/**
 * Class Applier module for Rangy.
 * Adds, removes and toggles classes on Ranges and Selections
 *
 * Part of Rangy, a cross-browser JavaScript range and selection library
 * http://code.google.com/p/rangy/
 *
 * Depends on Rangy core.
 *
 * Copyright 2013, Tim Down
 * Licensed under the MIT license.
 * Version: 1.3alpha.804
 * Build date: 8 December 2013
 */
rangy.createModule("ClassApplier",["WrappedSelection"],function(a,b){function g(a,b){for(var c in a)if(a.hasOwnProperty(c)&&b(c,a[c])===!1)return!1;return!0}function h(a){return a.replace(/^\s\s*/,"").replace(/\s\s*$/,"")}function i(a,b){return a.className&&(new RegExp("(?:^|\\s)"+b+"(?:\\s|$)")).test(a.className)}function j(a,b){a.className?i(a,b)||(a.className+=" "+b):a.className=b}function l(a){return a.split(/\s+/).sort().join(" ")}function m(a){return l(a.className)}function n(a,b){return m(a)==m(b)}function o(a,b,c,d,e){var f=a.node,g=a.offset,h=f,i=g;f==d&&g>e&&++i,f==b&&(g==c||g==c+1)&&(h=d,i+=e-c),f==b&&g>c+1&&--i,a.node=h,a.offset=i}function p(a,b,c){a.node==b&&a.offset>c&&--a.offset}function q(a,b,d,e){d==-1&&(d=b.childNodes.length);var f=a.parentNode,g=c.getNodeIndex(a);for(var h=0,i;i=e[h++];)o(i,f,g,b,d);b.childNodes.length==d?b.appendChild(a):b.insertBefore(a,b.childNodes[d])}function r(a,b){var d=a.parentNode,e=c.getNodeIndex(a);for(var f=0,g;g=b[f++];)p(g,d,e);a.parentNode.removeChild(a)}function s(a,b,c,d,e){var f,g=[];while(f=a.firstChild)q(f,b,c++,e),g.push(f);return d&&a.parentNode.removeChild(a),g}function t(a,b){return s(a,a.parentNode,c.getNodeIndex(a),!0,b)}function u(a,b){var c=a.cloneRange();c.selectNodeContents(b);var d=c.intersection(a),e=d?d.toString():"";return c.detach(),e!=""}function v(a){var b=a.getNodes([3]),c=0,d;while((d=b[c])&&!u(a,d))++c;var e=b.length-1;while((d=b[e])&&!u(a,d))--e;return b.slice(c,e+1)}function w(a,b){if(a.attributes.length!=b.attributes.length)return!1;for(var c=0,d=a.attributes.length,e,f,g;c<d;++c){e=a.attributes[c],g=e.name;if(g!="class"){f=b.attributes.getNamedItem(g);if(e===null!=(f===null))return!1;if(e.specified!=f.specified)return!1;if(e.specified&&e.nodeValue!==f.nodeValue)return!1}}return!0}function x(a,b){for(var c=0,d=a.attributes.length,f;c<d;++c){f=a.attributes[c].name;if((!b||!e(b,f))&&a.attributes[c].specified&&f!="class")return!0}return!1}function y(a,b){return g(b,function(b,c){if(typeof c=="object"){if(!y(a[b],c))return!1}else if(a[b]!==c)return!1}),!0}function B(a){var b;return a&&a.nodeType==1&&((b=a.parentNode)&&b.nodeType==9&&b.designMode=="on"||A(a)&&!A(a.parentNode))}function C(a){return(A(a)||a.nodeType!=1&&A(a.parentNode))&&!B(a)}function E(a){return a&&a.nodeType==1&&!D.test(z(a,"display"))}function G(a){if(a.data.length==0)return!0;if(F.test(a.data))return!1;var b=z(a.parentNode,"whiteSpace");switch(b){case"pre":case"pre-wrap":case"-moz-pre-wrap":return!1;case"pre-line":if(/[\r\n]/.test(a.data))return!1}return E(a.previousSibling)||E(a.nextSibling)}function H(a){var b=[],c,e;for(c=0;e=a[c++];)b.push(new d(e.startContainer,e.startOffset),new d(e.endContainer,e.endOffset));return b}function I(a,b){for(var c=0,d,e,f,g=a.length;c<g;++c)d=a[c],e=b[c*2],f=b[c*2+1],d.setStartAndEnd(e.node,e.offset,f.node,f.offset)}function J(a,b){return c.isCharacterDataNode(a)?b==0?!!a.previousSibling:b==a.length?!!a.nextSibling:!0:b>0&&b<a.childNodes.length}function K(a,d,e,f){var g,h,i=e==0;if(c.isAncestorOf(d,a))return a;if(c.isCharacterDataNode(d)){var j=c.getNodeIndex(d);if(e==0)e=j;else{if(e!=d.length)throw b.createError("splitNodeAt() should not be called with offset in the middle of a data node ("+e+" in "+d.data);e=j+1}d=d.parentNode}if(J(d,e)){g=d.cloneNode(!1),h=d.parentNode,g.id&&g.removeAttribute("id");var k,l=0;while(k=d.childNodes[e])q(k,g,l++,f);return q(g,h,c.getNodeIndex(d)+1,f),d==a?g:K(a,h,c.getNodeIndex(g),f)}if(a!=d){g=d.parentNode;var m=c.getNodeIndex(d);return i||m++,K(a,g,m,f)}return a}function L(a,b){return a.tagName==b.tagName&&n(a,b)&&w(a,b)&&z(a,"display")=="inline"&&z(b,"display")=="inline"}function M(a){var b=a?"nextSibling":"previousSibling";return function(c,d){var e=c.parentNode,f=c[b];if(f){if(f&&f.nodeType==3)return f}else if(d){f=e[b];if(f&&f.nodeType==1&&L(e,f)){var g=f[a?"firstChild":"lastChild"];if(g&&g.nodeType==3)return g}}return null}}function P(a){this.isElementMerge=a.nodeType==1,this.textNodes=[];var b=this.isElementMerge?a.lastChild:a;b&&(this.textNodes[0]=b)}function S(a,b,c){var d,e,f,i,j=this;j.cssClass=a;var k=null,l={};if(typeof b=="object"&&b!==null){c=b.tagNames,k=b.elementProperties,l=b.elementAttributes;for(e=0;i=Q[e++];)b.hasOwnProperty(i)&&(j[i]=b[i]);d=b.normalize}else d=b;j.normalize=typeof d=="undefined"?!0:d,j.attrExceptions=[];var m=document.createElement(j.elementTagName);j.elementProperties=j.copyPropertiesToElement(k,m,!0),g(l,function(a){j.attrExceptions.push(a)}),j.elementAttributes=l,j.elementSortedClassName=j.elementProperties.hasOwnProperty("className")?j.elementProperties.className:a,j.applyToAnyTagName=!1;var n=typeof c;if(n=="string")c=="*"?j.applyToAnyTagName=!0:j.tagNames=h(c.toLowerCase()).split(/\s*,\s*/);else if(n=="object"&&typeof c.length=="number"){j.tagNames=[];for(e=0,f=c.length;e<f;++e)c[e]=="*"?j.applyToAnyTagName=!0:j.tagNames.push(c[e].toLowerCase())}else j.tagNames=[j.elementTagName]}function T(a,b,c){return new S(a,b,c)}var c=a.dom,d=c.DomPosition,e=c.arrayContains,f="span",k=function(){function a(a,b,c){return b&&c?" ":""}return function(b,c){b.className&&(b.className=b.className.replace(new RegExp("(^|\\s)"+c+"(\\s|$)"),a))}}(),z=c.getComputedStyleProperty,A=function(){var a=document.createElement("div");return typeof a.isContentEditable=="boolean"?function(a){return a&&a.nodeType==1&&a.isContentEditable}:function(a){return!a||a.nodeType!=1||a.contentEditable=="false"?!1:a.contentEditable=="true"||A(a.parentNode)}}(),D=/^inline(-block|-table)?$/i,F=/[^\r\n\t\f \u200B]/,N=M(!1),O=M(!0);P.prototype={doMerge:function(a){var b=this.textNodes,c=b[0];if(b.length>1){var d=[],e=0,f,g;for(var h=0,i=b.length,j,k;h<i;++h){f=b[h],g=f.parentNode;if(h>0){g.removeChild(f),g.hasChildNodes()||g.parentNode.removeChild(g);if(a)for(j=0;k=a[j++];)k.node==f&&(k.node=c,k.offset+=e)}d[h]=f.data,e+=f.data.length}c.data=d.join("")}return c.data},getLength:function(){var a=this.textNodes.length,b=0;while(a--)b+=this.textNodes[a].length;return b},toString:function(){var a=[];for(var b=0,c=this.textNodes.length;b<c;++b)a[b]="'"+this.textNodes[b].data+"'";return"[Merge("+a.join(",")+")]"}};var Q=["elementTagName","ignoreWhiteSpace","applyToEditableOnly","useExistingElements","removeEmptyElements","onElementCreate"],R={};S.prototype={elementTagName:f,elementProperties:{},elementAttributes:{},ignoreWhiteSpace:!0,applyToEditableOnly:!1,useExistingElements:!0,removeEmptyElements:!0,onElementCreate:null,copyPropertiesToElement:function(a,b,c){var d,e,f={},g,h,i,k;for(var m in a)if(a.hasOwnProperty(m)){h=a[m],i=b[m];if(m=="className")j(b,h),j(b,this.cssClass),b[m]=l(b[m]),c&&(f[m]=b[m]);else if(m=="style"){e=i,c&&(f[m]=g={});for(d in a[m])e[d]=h[d],c&&(g[d]=e[d]);this.attrExceptions.push(m)}else b[m]=h,c&&(f[m]=b[m],k=R.hasOwnProperty(m)?R[m]:m,this.attrExceptions.push(k))}return c?f:""},copyAttributesToElement:function(a,b){for(var c in a)a.hasOwnProperty(c)&&b.setAttribute(c,a[c])},hasClass:function(a){return a.nodeType==1&&e(this.tagNames,a.tagName.toLowerCase())&&i(a,this.cssClass)},getSelfOrAncestorWithClass:function(a){while(a){if(this.hasClass(a))return a;a=a.parentNode}return null},isModifiable:function(a){return!this.applyToEditableOnly||C(a)},isIgnorableWhiteSpaceNode:function(a){return this.ignoreWhiteSpace&&a&&a.nodeType==3&&G(a)},postApply:function(a,b,c,d){var e=a[0],f=a[a.length-1],g=[],h,i=e,j=f,k=0,l=f.length,m,n;for(var o=0,p=a.length;o<p;++o)m=a[o],n=N(m,!d),n?(h||(h=new P(n),g.push(h)),h.textNodes.push(m),m===e&&(i=h.textNodes[0],k=i.length),m===f&&(j=h.textNodes[0],l=h.getLength())):h=null;var q=O(f,!d);q&&(h||(h=new P(f),g.push(h)),h.textNodes.push(q));if(g.length){for(o=0,p=g.length;o<p;++o)g[o].doMerge(c);b.setStartAndEnd(i,k,j,l)}},createContainer:function(a){var b=a.createElement(this.elementTagName);return this.copyPropertiesToElement(this.elementProperties,b,!1),this.copyAttributesToElement(this.elementAttributes,b),j(b,this.cssClass),this.onElementCreate&&this.onElementCreate(b,this),b},applyToTextNode:function(a,b){var d=a.parentNode;if(d.childNodes.length==1&&this.useExistingElements&&e(this.tagNames,d.tagName.toLowerCase())&&y(d,this.elementProperties))j(d,this.cssClass);else{var f=this.createContainer(c.getDocument(a));a.parentNode.insertBefore(f,a),f.appendChild(a)}},isRemovable:function(a){return a.tagName.toLowerCase()==this.elementTagName&&m(a)==this.elementSortedClassName&&y(a,this.elementProperties)&&!x(a,this.attrExceptions)&&this.isModifiable(a)},isEmptyContainer:function(a){var b=a.childNodes.length;return a.nodeType==1&&this.isRemovable(a)&&(b==0||b==1&&this.isEmptyContainer(a.firstChild))},removeEmptyContainers:function(a){var b=this,c=a.getNodes([1],function(a){return b.isEmptyContainer(a)}),d=[a],e=H(d);for(var f=0,g;g=c[f++];)r(g,e);I(d,e)},undoToTextNode:function(a,b,c,d){if(!b.containsNode(c)){var e=b.cloneRange();e.selectNode(c),e.isPointInRange(b.endContainer,b.endOffset)&&(K(c,b.endContainer,b.endOffset,d),b.setEndAfter(c)),e.isPointInRange(b.startContainer,b.startOffset)&&(c=K(c,b.startContainer,b.startOffset,d))}this.isRemovable(c)?t(c,d):k(c,this.cssClass)},applyToRange:function(a,b){b=b||[];var c=H(b||[]);a.splitBoundariesPreservingPositions(c),this.removeEmptyElements&&this.removeEmptyContainers(a);var d=v(a);if(d.length){for(var e=0,f;f=d[e++];)!this.isIgnorableWhiteSpaceNode(f)&&!this.getSelfOrAncestorWithClass(f)&&this.isModifiable(f)&&this.applyToTextNode(f,c);f=d[d.length-1],a.setStartAndEnd(d[0],0,f,f.length),this.normalize&&this.postApply(d,a,c,!1),I(b,c)}},applyToRanges:function(a){var b=a.length;while(b--)this.applyToRange(a[b],a);return a},applyToSelection:function(b){var c=a.getSelection(b);c.setRanges(this.applyToRanges(c.getAllRanges()))},undoToRange:function(a,b){b=b||[];var c=H(b);a.splitBoundariesPreservingPositions(c),this.removeEmptyElements&&this.removeEmptyContainers(a,c);var d=v(a),e,f,g=d[d.length-1];if(d.length){for(var h=0,i=d.length;h<i;++h)e=d[h],f=this.getSelfOrAncestorWithClass(e),f&&this.isModifiable(e)&&this.undoToTextNode(e,a,f,c),a.setStartAndEnd(d[0],0,g,g.length);this.normalize&&this.postApply(d,a,c,!0),I(b,c)}},undoToRanges:function(a){var b=a.length;while(b--)this.undoToRange(a[b],a);return a},undoToSelection:function(b){var c=a.getSelection(b),d=a.getSelection(b).getAllRanges();this.undoToRanges(d),c.setRanges(d)},isAppliedToRange:function(a){if(a.collapsed||a.toString()=="")return!!this.getSelfOrAncestorWithClass(a.commonAncestorContainer);var b=a.getNodes([3]);if(b.length)for(var c=0,d;d=b[c++];)if(!this.isIgnorableWhiteSpaceNode(d)&&u(a,d)&&this.isModifiable(d)&&!this.getSelfOrAncestorWithClass(d))return!1;return!0},isAppliedToRanges:function(a){var b=a.length;if(b==0)return!1;while(b--)if(!this.isAppliedToRange(a[b]))return!1;return!0},isAppliedToSelection:function(b){var c=a.getSelection(b);return this.isAppliedToRanges(c.getAllRanges())},toggleRange:function(a){this.isAppliedToRange(a)?this.undoToRange(a):this.applyToRange(a)},toggleSelection:function(a){this.isAppliedToSelection(a)?this.undoToSelection(a):this.applyToSelection(a)},getElementsWithClassIntersectingRange:function(a){var b=[],c=this;return a.getNodes([3],function(a){var d=c.getSelfOrAncestorWithClass(a);d&&!e(b,d)&&b.push(d)}),b},detach:function(){}},S.util={hasClass:i,addClass:j,removeClass:k,hasSameClasses:n,replaceWithOwnChildren:t,elementsHaveSameNonClassAttributes:w,elementHasNonClassAttributes:x,splitNodeAt:K,isEditableElement:A,isEditingHost:B,isEditable:C},a.CssClassApplier=a.ClassApplier=S,a.createCssClassApplier=a.createClassApplier=T});