An optional message to welcome customers and explain how to shop with you. If text is entered here it will be displayed in a home tab when customers first arrive at your shopfront.
// Creates a convenience function to save verbose repeated calls to tests functions
functiond(a){returnfunction(b,c){for(vard=c.length;d--;)if(!a(b,c[d]))return!1;return!0}}functione(a){returna&&A(a,z)&&C(a,y)}functionf(a){returnb(a,"body")?a.body:a.getElementsByTagName("body")[0]}functiong(b){typeofconsole!=v&&a(console,"log")&&console.log(b)}functionh(a,b){F&&b?alert(a):g(a)}functioni(a){H.initialized=!0,H.supported=!1,h("Rangy is not supported in this environment. Reason: "+a,H.config.alertOnFail)}functionj(a){h("Rangy warning: "+a,H.config.alertOnWarn)}functionk(a){returna.message||a.description||String(a)}
// Initialization
functionl(){if(F&&!H.initialized){varb,c=!1,d=!1;
// First, perform basic feature tests
a(document,"createRange")&&(b=document.createRange(),A(b,x)&&C(b,w)&&(c=!0));varh=f(document);if(!h||"body"!=h.nodeName.toLowerCase())returnvoidi("No body element found");if(h&&a(h,"createTextRange")&&(b=h.createTextRange(),e(b)&&(d=!0)),!c&&!d)returnvoidi("Neither Range nor TextRange are available");H.initialized=!0,H.features={implementsDomRange:c,implementsTextRange:d};
for(varn=0,o=K.length;n<o;++n)try{K[n](H)}catch(a){l="Rangy init listener threw an exception. Continuing. Detail: "+k(a),g(l)}}}functionm(a,b,c){c&&(a+=" in module "+c.name),H.warn("DEPRECATED: "+a+" is deprecated. Please use "+b+" instead.")}functionn(a,b,c,d){a[b]=function(){returnm(b,c,d),a[c].apply(a,G.toArray(arguments))}}functiono(a){a=a||window,l();
// Notify listeners
for(varb=0,c=L.length;b<c;++b)L[b](a)}functionp(a,b,c){this.name=a,this.dependencies=b,this.initialized=!1,this.supported=!1,this.initializer=c}functionq(a,b,c){vard=newp(a,b,function(b){if(!b.initialized){b.initialized=!0;try{c(H,b),b.supported=!0}catch(b){vard="Module '"+a+"' failed to load: "+k(b);g(d),b.stack&&g(b.stack)}}});returnE[a]=d,d}/*----------------------------------------------------------------------------------------------------------------*/
// Ensure rangy.rangePrototype and rangy.selectionPrototype are available immediately
// Special case for toString, which does not show up in for...in loops in IE <= 8
returnb.hasOwnProperty("toString")&&(a.toString=b.toString),a},G.createOptions=function(a,b){varc={};returnI(c,b),a&&I(c,a),c}):i("hasOwnProperty not supported"),
// Test whether we're in a browser and bail out if not
F||i("Rangy can only run in a browser"),
// Test whether Array.prototype.slice can be relied on for NodeLists and use an alternative toArray() if not
// Very simple event handler wrapper function that doesn't attempt to solve issues such as "this" handling or
// normalization of event properties
varJ;F&&(a(document,"addEventListener")?J=function(a,b,c){a.addEventListener(b,c,!1)}:a(document,"attachEvent")?J=function(a,b,c){a.attachEvent("on"+b,c)}:i("Document does not have required addEventListener or attachEvent method"),G.addListener=J);varK=[];G.deprecationNotice=m,G.createAliasForDeprecatedMethod=n,
// Allow external scripts to initialize this library in case it's loaded after the document has loaded
H.init=l,
// Execute listener immediately if already initialized
H.addInitListener=function(a){H.initialized?a(H):K.push(a)};varL=[];H.addShimListener=function(a){L.push(a)},F&&(H.shim=H.createMissingNativeApi=o,n(H,"createMissingNativeApi","shim")),p.prototype={init:function(){for(vara,b,c=this.dependencies||[],d=0,e=c.length;d<e;++d){if(b=c[d],a=E[b],!(a&&ainstanceofp))thrownewError("required module '"+b+"' not found");if(a.init(),!a.supported)thrownewError("required module '"+b+"' not supported")}
// Now run initializer
this.initializer(this)},fail:function(a){throwthis.initialized=!0,this.supported=!1,newError(a)},warn:function(a){H.warn("Module "+this.name+": "+a)},deprecationNotice:function(a,b){H.warn("DEPRECATED: "+a+" in module "+this.name+" is deprecated. Please use "+b+" instead")},createError:function(a){returnnewError("Error in Rangy "+this.name+" module: "+a)}},H.createModule=function(a){
// Allow 2 or 3 arguments (second argument is an optional array of dependencies)
// Handle case where position was inside the portion of node after the split point
f.node==a&&f.offset>b?(f.node=d,f.offset-=b):f.node==a.parentNode&&f.offset>e(a)&&++f.offset;returnd}functiono(a){if(9==a.nodeType)returna;if(typeofa.ownerDocument!=F)returna.ownerDocument;if(typeofa.document!=F)returna.document;if(a.parentNode)returno(a.parentNode);throwb.createError("getDocument: no document found for node")}functionp(a){varc=o(a);if(typeofc.defaultView!=F)returnc.defaultView;if(typeofc.parentWindow!=F)returnc.parentWindow;throwb.createError("Cannot get a window object for node")}functionq(a){if(typeofa.contentDocument!=F)returna.contentDocument;if(typeofa.contentWindow!=F)returna.contentWindow.document;throwb.createError("getIframeDocument: No Document object found for iframe element")}functionr(a){if(typeofa.contentWindow!=F)returna.contentWindow;if(typeofa.contentDocument!=F)returna.contentDocument.defaultView;throwb.createError("getIframeWindow: No Window object found for iframe element")}
// This looks bad. Is it worth it?
functions(a){returna&&G.isHostMethod(a,"setTimeout")&&G.isHostObject(a,"document")}functiont(a,b,c){vard;if(a?G.isHostProperty(a,"nodeType")?d=1==a.nodeType&&"iframe"==a.tagName.toLowerCase()?q(a):o(a):s(a)&&(d=a.document):d=document,!d)throwb.createError(c+"(): Parameter must be a Window object or DOM node");returnd}functionu(a){for(varb;b=a.parentNode;)a=b;returna}functionv(a,c,d,f){
// See http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-Comparing
varh,i,k,l,m;if(a==d)
// Case 1: nodes are the same
returnc===f?0:c<f?-1:1;if(h=j(d,a,!0))
// Case 2: node C (container B or an ancestor) is a child node of A
returnc<=e(h)?-1:1;if(h=j(a,d,!0))
// Case 3: node C (container A or an ancestor) is a child node of B
returne(h)<f?-1:1;if(i=g(a,d),!i)thrownewError("comparePoints error: nodes have no common ancestor");if(
// Case 4: containers are siblings or descendants of siblings
k=a===i?i:j(a,i,!0),l=d===i?i:j(d,i,!0),k===l)
// This shouldn't be possible
throwb.createError("comparePoints got to case 4 and childA and childB are the same!");for(m=i.firstChild;m;){if(m===k)return-1;if(m===l)return1;m=m.nextSibling}}functionw(a){varb;try{returnb=a.parentNode,!1}catch(a){return!0}}/*----------------------------------------------------------------------------------------------------------------*/
functionx(a){if(!a)return"[No node]";if(L&&w(a))return"[Broken node]";if(k(a))return'"'+a.data+'"';if(1==a.nodeType){varb=a.id?' id="'+a.id+'"':"";return"<"+a.nodeName+b+">[index:"+e(a)+",length:"+a.childNodes.length+"]["+(a.innerHTML||"[innerHTML not supported]").slice(0,25)+"]"}returna.nodeName}functiony(a){for(varb,c=o(a).createDocumentFragment();b=a.firstChild;)c.appendChild(b);returnc}functionz(a,b,c){vard=H(a),e=a.createElement("div");e.contentEditable=""+!!c,b&&(e.innerHTML=b);
// Insert the test element at the start of the body to prevent scrolling to the bottom in iOS (issue #292)
G.areHostMethods(document,["createDocumentFragment","createElement","createTextNode"])||b.fail("document missing a Node creation method"),G.isHostMethod(document,"getElementsByTagName")||b.fail("document missing getElementsByTagName method");varI=document.createElement("div");G.areHostMethods(I,["insertBefore","appendChild","cloneNode"]||!G.areHostObjects(I,["previousSibling","nextSibling","childNodes","parentNode"]))||b.fail("Incomplete Element implementation"),
// innerHTML is required for Range's createContextualFragment method
G.isHostProperty(I,"innerHTML")||b.fail("Element is missing innerHTML property");varJ=document.createTextNode("test");G.areHostMethods(J,["splitText","deleteData","insertData","appendData","cloneNode"]||!G.areHostObjects(I,["previousSibling","nextSibling","childNodes","parentNode"])||!G.areHostProperties(J,["data"]))||b.fail("Incomplete Text Node implementation");/*----------------------------------------------------------------------------------------------------------------*/
// Removed use of indexOf because of a bizarre bug in Opera that is thrown in one of the Acid3 tests. I haven't been
// able to replicate it outside of the test. The bug is that indexOf returns -1 when called on an Array that
// contains just the document as a single element and the value searched for is the document.
varK=/*Array.prototype.indexOf ?
function(arr, val) {
return arr.indexOf(val) > -1;
}:*/
function(a,b){for(varc=a.length;c--;)if(a[c]===b)return!0;return!1},L=!1;!function(){varb=document.createElement("b");b.innerHTML="1";varc=b.firstChild;b.innerHTML="<br />",L=w(c),a.features.crashyTextNodes=L}();varM;typeofwindow.getComputedStyle!=F?M=function(a,b){returnp(a).getComputedStyle(a,null)[b]}:typeofdocument.documentElement.currentStyle!=F?M=function(a,b){returna.currentStyle?a.currentStyle[b]:""}:b.fail("No means of obtaining computed style properties found"),B.prototype={_current:null,hasNext:function(){return!!this._next},next:function(){vara,b,c=this._current=this._next;if(this._current)if(a=c.firstChild)this._next=a;else{for(b=null;c!==this.root&&!(b=c.nextSibling);)c=c.parentNode;this._next=b}returnthis._current},detach:function(){this._current=this._next=this.root=null}},D.prototype={equals:function(a){return!!a&&this.node===a.node&&this.offset==a.offset},inspect:function(){return"[DomPosition("+x(this.node)+":"+this.offset+")]"},toString:function(){returnthis.inspect()}},E.prototype={INDEX_SIZE_ERR:1,HIERARCHY_REQUEST_ERR:3,WRONG_DOCUMENT_ERR:4,NO_MODIFICATION_ALLOWED_ERR:7,NOT_FOUND_ERR:8,NOT_SUPPORTED_ERR:9,INVALID_STATE_ERR:11,INVALID_NODE_TYPE_ERR:24},E.prototype.toString=function(){returnthis.message},a.dom={arrayContains:K,isHtmlNamespace:c,parentElement:d,getNodeIndex:e,getNodeLength:f,getCommonAncestor:g,isAncestorOf:h,isOrIsAncestorOf:i,getClosestAncestorIn:j,isCharacterDataNode:k,isTextOrCommentNode:l,insertAfter:m,splitDataNode:n,getDocument:o,getWindow:p,getIframeWindow:r,getIframeDocument:q,getBody:H,isWindow:s,getContentDocument:t,getRootContainer:u,comparePoints:v,isBrokenNode:w,inspectNode:x,getComputedStyleProperty:M,createTestElement:z,removeNode:A,fragmentFromNodeChildren:y,createIterator:C,DomPosition:D},a.DOMException=E}),/*----------------------------------------------------------------------------------------------------------------*/
// RangeIterator code partially borrows from IERange by Tim Ryan (http://github.com/timcameronryan/IERange)
functionp(a,b){if(this.range=a,this.clonePartiallySelectedTextNodes=b,!a.collapsed){this.sc=a.startContainer,this.so=a.startOffset,this.ec=a.endContainer,this.eo=a.endOffset;varc=a.commonAncestorContainer;this.sc===this.ec&&N(this.sc)?(this.isSingleCharacterDataNode=!0,this._first=this._last=this._next=this.sc):(this._first=this._next=this.sc!==c||N(this.sc)?T(this.sc,c,!0):this.sc.childNodes[this.so],this._last=this.ec!==c||N(this.ec)?T(this.ec,c,!0):this.ec.childNodes[this.eo-1])}}functionq(a){returnfunction(b,c){for(vard,e=c?b:b.parentNode;e;){if(d=e.nodeType,V(a,d))returne;e=e.parentNode}returnnull}}functionr(a,b){if(ea(a,b))thrownewM("INVALID_NODE_TYPE_ERR")}functions(a,b){if(!V(b,a.nodeType))thrownewM("INVALID_NODE_TYPE_ERR")}functiont(a,b){if(b<0||b>(N(a)?a.length:a.childNodes.length))thrownewM("INDEX_SIZE_ERR")}functionu(a,b){if(ca(a,!0)!==ca(b,!0))thrownewM("WRONG_DOCUMENT_ERR")}functionv(a){if(da(a,!0))thrownewM("NO_MODIFICATION_ALLOWED_ERR")}functionw(a,b){if(!a)thrownewM(b)}functionx(a,b){returnb<=(N(a)?a.length:a.childNodes.length)}functiony(a){return!!a.startContainer&&!!a.endContainer&&!(X&&(J.isBrokenNode(a.startContainer)||J.isBrokenNode(a.endContainer)))&&W(a.startContainer)==W(a.endContainer)&&x(a.startContainer,a.startOffset)&&x(a.endContainer,a.endOffset)}functionz(a){if(!y(a))thrownewError("Range error: Range is not valid. This usually happens after DOM mutation. Range: ("+a.inspect()+")")}functionA(a,b){z(a);varc=a.startContainer,d=a.startOffset,e=a.endContainer,f=a.endOffset,g=c===e;N(e)&&f>0&&f<e.length&&S(e,f,b),N(c)&&d>0&&d<c.length&&(c=S(c,d,b),g?(f-=d,e=c):e==c.parentNode&&f>=O(c)&&f++,d=0),a.setStartAndEnd(c,d,e,f)}functionB(a){z(a);varb=a.commonAncestorContainer.parentNode.cloneNode(!1);returnb.appendChild(a.cloneContents()),b.innerHTML}functionC(a){a.START_TO_START=ja,a.START_TO_END=ka,a.END_TO_END=la,a.END_TO_START=ma,a.NODE_BEFORE=na,a.NODE_AFTER=oa,a.NODE_BEFORE_AND_AFTER=pa,a.NODE_INSIDE=qa}functionD(a){C(a),C(a.prototype)}functionE(a,b){returnfunction(){z(this);varc,d,e=this.startContainer,f=this.startOffset,h=this.commonAncestorContainer,i=newp(this,!0);e!==h&&(c=T(e,h,!0),d=g(c),e=d.node,f=d.offset),
// The methods below are non-standard and invented by me.
// Sharing a boundary start-to-end or end-to-start does not count as intersection.
intersectsRange:function(a){returni(this,a,!1)},
// Sharing a boundary start-to-end or end-to-start does count as intersection.
intersectsOrTouchesRange:function(a){returni(this,a,!0)},intersection:function(a){if(this.intersectsRange(a)){varb=R(this.startContainer,this.startOffset,a.startContainer,a.startOffset),c=R(this.endContainer,this.endOffset,a.endContainer,a.endOffset),d=this.cloneRange();returnb==-1&&d.setStart(a.startContainer,a.startOffset),1==c&&d.setEnd(a.endContainer,a.endOffset),d}returnnull},union:function(a){if(this.intersectsOrTouchesRange(a)){varb=this.cloneRange();returnR(a.startContainer,a.startOffset,this.startContainer,this.startOffset)==-1&&b.setStart(a.startContainer,a.startOffset),1==R(a.endContainer,a.endOffset,this.endContainer,this.endOffset)&&b.setEnd(a.endContainer,a.endOffset),b}thrownewM("Ranges do not intersect")},containsNode:function(a,b){returnb?this.intersectsNode(a,!1):this.compareNode(a)==qa},containsNodeContents:function(a){returnthis.comparePoint(a,0)>=0&&this.comparePoint(a,U(a))<=0},containsRange:function(a){varb=this.intersection(a);returnnull!==b&&a.equals(b)},containsNodeText:function(a){varb=this.cloneRange();b.selectNode(a);varc=b.getNodes([3]);if(c.length>0){b.setStart(c[0],0);vard=c.pop();returnb.setEnd(d,d.length),this.containsRange(b)}returnthis.containsNodeContents(a)},getNodes:function(a,b){returnz(this),n(this,a,b)},getDocument:function(){returnd(this)},collapseBefore:function(a){this.setEndBefore(a),this.collapse(!1)},collapseAfter:function(a){this.setStartAfter(a),this.collapse(!0)},getBookmark:function(b){varc=d(this),e=a.createRange(c);b=b||J.getBody(c),e.selectNodeContents(b);varf=this.intersection(e),g=0,h=0;returnf&&(e.setEnd(f.startContainer,f.startOffset),g=e.toString().length,h=g+f.toString().length),{start:g,end:h,containerNode:b}},moveToBookmark:function(a){varb=a.containerNode,c=0;this.setStart(b,0),this.collapse(!0);for(vard,e,f,g,h=[b],i=!1,j=!1;!j&&(d=h.pop());)if(3==d.nodeType)e=c+d.length,!i&&a.start>=c&&a.start<=e&&(this.setStart(d,a.start-c),i=!0),i&&a.end>=c&&a.end<=e&&(this.setEnd(d,a.end-c),j=!0),c=e;elsefor(g=d.childNodes,f=g.length;f--;)h.push(g[f])},getName:function(){return"DomRange"},equals:function(a){returnI.rangesEqual(this,a)},isValid:function(){returny(this)},inspect:function(){returno(this)},detach:function(){}}),F(I,H),K.extend(I,{rangeProperties:ia,RangeIterator:p,copyComparisonConstants:D,createPrototypeRange:F,inspect:o,toHtml:B,getRangeDocument:d,rangesEqual:function(a,b){returna.startContainer===b.startContainer&&a.startOffset===b.startOffset&&a.endContainer===b.endContainer&&a.endOffset===b.endOffset}}),a.DomRange=I}),/*----------------------------------------------------------------------------------------------------------------*/
// Wrappers for the browser's native DOM Range and/or TextRange implementation
// Always set both boundaries for the benefit of IE9 (see issue 35)
(f||g||h)&&(a.setEnd(d,e),a.setStart(b,c))}vark,l,m=h.rangeProperties;c=function(a){if(!a)throwb.createError("WrappedRange: Range must be specified");this.nativeRange=a,d(this)},h.createPrototypeRange(c,g),k=c.prototype,k.selectNode=function(a){this.nativeRange.selectNode(a),d(this)},k.cloneContents=function(){returnthis.nativeRange.cloneContents()},
// Due to a long-standing Firefox bug that I have not been able to find a reliable way to detect,
// insertNode() is never delegated to the native range.
// Utility function to support direction parameters in the API that may be a string ("backward", "backwards",
// "forward" or "forwards") or a Boolean (true for backwards).
functionc(a){return"string"==typeofa?/^backward(s)?$/i.test(a):!!a}functiond(a,c){if(a){if(C.isWindow(a))returna;if(ainstanceofr)returna.win;vard=C.getContentDocument(a,b,c);returnC.getWindow(d)}returnwindow}functione(a){returnd(a,"getWinSelection").getSelection()}functionf(a){returnd(a,"getDocSelection").document.selection}functiong(a){varb=!1;returna.anchorNode&&(b=1==C.comparePoints(a.anchorNode,a.anchorOffset,a.focusNode,a.focusOffset)),b}functionh(a,b,c){vard=c?"end":"start",e=c?"start":"end";a.anchorNode=b[d+"Container"],a.anchorOffset=b[d+"Offset"],a.focusNode=b[e+"Container"],a.focusOffset=b[e+"Offset"]}functioni(a){varb=a.nativeSelection;a.anchorNode=b.anchorNode,a.anchorOffset=b.anchorOffset,a.focusNode=b.focusNode,a.focusOffset=b.focusOffset}functionj(a){a.anchorNode=a.focusNode=null,a.anchorOffset=a.focusOffset=0,a.rangeCount=0,a.isCollapsed=!0,a._ranges.length=0}functionk(b){varc;returnbinstanceofF?(c=a.createNativeRange(b.getDocument()),c.setEnd(b.endContainer,b.endOffset),c.setStart(b.startContainer,b.startOffset)):binstanceofG?c=b.nativeRange:J.implementsDomRange&&binstanceofC.getWindow(b.startContainer).Range&&(c=b),c}functionl(a){if(!a.length||1!=a[0].nodeType)return!1;for(varb=1,c=a.length;b<c;++b)if(!C.isAncestorOf(a[0],a[b]))return!1;return!0}functionm(a){varc=a.getNodes();if(!l(c))throwb.createError("getSingleElementFromRange: range "+a.inspect()+" did not consist of a single element");returnc[0]}
// Simple, quick test which only needs to distinguish between a TextRange and a ControlRange
// This case (where the selection type is "Control" and calling createRange() on the selection returns
// a TextRange) can happen in IE 9. It happens, for example, when all elements in the selected
// ControlRange have been removed from the ControlRange and removed from the document.
o(b,c);else{b.rangeCount=c.length;for(vard,e=L(c.item(0)),f=0;f<b.rangeCount;++f)d=a.createRange(e),d.selectNode(c.item(f)),b._ranges.push(d);b.isCollapsed=1==b.rangeCount&&b._ranges[0].collapsed,h(b,b._ranges[b.rangeCount-1],!1)}}}functionq(a,c){for(vard=a.docSelection.createRange(),e=m(c),f=L(d.item(0)),g=M(f).createControlRange(),h=0,i=d.length;h<i;++h)g.add(d.item(h));try{g.add(e)}catch(a){throwb.createError("addRange(): Element within the specified Range could not be added to control selection (does it have layout?)")}g.select(),
// Update the wrapped selection based on what's now in the native selection
p(a)}functionr(a,b,c){this.nativeSelection=a,this.docSelection=b,this._ranges=[],this.win=c,this.refresh()}functions(a){a.win=a.anchorNode=a.focusNode=a._ranges=null,a.rangeCount=a.anchorOffset=a.focusOffset=0,a.detached=!0}functiont(a,b){for(varc,d,e=ba.length;e--;)if(c=ba[e],d=c.selection,"deleteAll"==b)s(d);elseif(c.win==a)return"delete"==b?(ba.splice(e,1),!0):d;return"deleteAll"==b&&(ba.length=0),null}functionu(a,c){for(vard,e=L(c[0].startContainer),f=M(e).createControlRange(),g=0,h=c.length;g<h;++g){d=m(c[g]);try{f.add(d)}catch(a){throwb.createError("setRanges(): Element within one of the specified Ranges could not be added to control selection (does it have layout?)")}}f.select(),
// Update the wrapped selection based on what's now in the native selection
// Check whether the selection TextRange is actually contained within the correct document
return"None"!=c.type||L(c.createRange().parentElement())==b};else{if(!O)returnb.fail("Neither document.selection or window.getSelection() detected."),!1;y=e,a.isSelectionValid=function(){return!0}}a.getNativeSelection=y;varR=y();
// In Firefox, the selection is null in an iframe with display: none. See issue #138.
if(!R)returnb.fail("Native selection was null (possibly issue 138?)"),!1;varS=a.createNativeRange(document),T=M(document),U=D.areHostProperties(R,["anchorNode","focusNode","anchorOffset","focusOffset"]);J.selectionHasAnchorAndFocus=U;
// Test for existence of native selection extend() method
C.removeNode(i),b.removeAllRanges(),h=0;h<c;++h)0==h&&f?Z?Z(b,e[h]):(a.warn("Rangy initialization: original selection was backwards but selection has been restored forwards because the browser does not support Selection.extend"),b.addRange(e[h])):b.addRange(e[h])}}(),J.selectionSupportsMultipleRanges=X,J.collapsedNonEditableSelectionsSupported=Y;
// The range was not added successfully. The simplest thing is to refresh
this.refresh()}}:da.addRange=function(a,b){c(b)&&V?ea(this,a):(this.nativeSelection.addRange(k(a)),this.refresh())},da.setRanges=function(a){if(_&&P&&a.length>1)u(this,a);else{this.removeAllRanges();for(varb=0,c=a.length;b<c;++b)this.addRange(a[b])}}}else{if(!(E(R,"empty")&&E(S,"select")&&_&&Q))returnb.fail("No means of selecting a Range or TextRange was found"),!1;da.removeAllRanges=function(){
// Clone the range to preserve selection-range independence. See issue 80.
returnthis._ranges[a].cloneRange()};varfa;if(Q)fa=function(b){varc;a.isSelectionValid(b.win)?c=b.docSelection.createRange():(c=M(b.win.document).createTextRange(),c.collapse(!0)),b.docSelection.type==K?p(b):n(c)?o(b,c):j(b)};elseif(E(R,"getRangeAt")&&typeofR.rangeCount==B)fa=function(b){if(_&&P&&b.docSelection.type==K)p(b);elseif(b._ranges.length=b.rangeCount=b.nativeSelection.rangeCount,b.rangeCount){for(varc=0,d=b.rangeCount;c<d;++c)b._ranges[c]=newa.WrappedRange(b.nativeSelection.getRangeAt(c));h(b,b._ranges[b.rangeCount-1],ha(b.nativeSelection)),b.isCollapsed=z(b)}elsej(b)};else{if(!U||typeofR.isCollapsed!=A||typeofS.collapsed!=A||!J.implementsDomRange)returnb.fail("No means of obtaining a Range or TextRange from the user's selection was found"),!1;fa=function(a){varb,c=a.nativeSelection;c.anchorNode?(b=aa(c,0),a._ranges=[b],a.rangeCount=1,i(a),a.isCollapsed=z(a)):j(a)}}da.refresh=function(a){varb=a?this._ranges.slice(0):null,c=this.anchorNode,d=this.anchorOffset;if(fa(this),a){
// Check the range count first
vare=b.length;if(e!=this._ranges.length)return!0;
// Now check the direction. Checking the anchor position is the same is enough since we're checking all the
// Add select() method to Range prototype. Any existing selection will be removed.
a.rangePrototype.select=function(a){ca(this.getDocument()).setSingleRange(this,a)},da.changeEachRange=function(a){varb=[],c=this.isBackward();this.eachRange(function(c){a(c),b.push(c)}),this.removeAllRanges(),c&&1==b.length?this.addRange(b[0],"backward"):this.setRanges(b)},da.containsNode=function(a,b){returnthis.eachRange(function(c){returnc.containsNode(a,b)},!0)||!1},da.getBookmark=function(a){return{backward:this.isBackward(),rangeBookmarks:this.callMethodOnEachRange("getBookmark",[a])}},da.moveToBookmark=function(b){for(varc,d,e=[],f=0;c=b.rangeBookmarks[f++];)d=a.createRange(this.win),d.moveToBookmark(c),e.push(d);b.backward?this.setSingleRange(e[0],"backward"):this.setRanges(e)},da.saveRanges=function(){return{backward:this.isBackward(),ranges:this.callMethodOnEachRange("cloneRange")}},da.restoreRanges=function(a){this.removeAllRanges();for(varb,c=0;b=a.ranges[c];++c)this.addRange(b,a.backward&&0==c)},da.toHtml=function(){vara=[];returnthis.eachRange(function(b){a.push(F.toHtml(b))}),a.join("")},J.implementsTextRange&&(da.getNativeTextRange=function(){varc;if(c=this.docSelection){vard=c.createRange();if(n(d))returnd;throwb.createError("getNativeTextRange: selection is a control selection")}if(this.rangeCount>0)returna.WrappedTextRange.rangeToTextRange(this.getRangeAt(0));throwb.createError("getNativeTextRange: selection contains no range")}),da.getName=function(){return"WrappedSelection"},da.inspect=function(){returnx(this)},da.detach=function(){t(this.win,"delete"),s(this)},r.detachAll=function(){t(null,"deleteAll")},r.inspect=x,r.isDirectionBackward=c,a.Selection=r,a.selectionPrototype=da,a.addShimListener(function(a){"undefined"==typeofa.getSelection&&(a.getSelection=function(){returnca(a)}),a=null})});/*----------------------------------------------------------------------------------------------------------------*/
// Create the marker element containing a single invisible character using DOM methods and insert it
returnf.collapse(b),c=e.createElement("span"),c.id=d,c.style.lineHeight="0",c.style.display="none",c.className="rangySelectionBoundary",c.appendChild(e.createTextNode(r)),f.insertNode(c),c}functione(a,d,e,f){varg=c(e,a);g?(d[f?"setStartBefore":"setEndBefore"](g),p(g)):b.warn("Marker element has been removed. Cannot restore selection.")}functionf(a,b){returnb.compareBoundaryPoints(a.START_TO_START,a)}functiong(b,c){vare,f,g=a.DomRange.getRangeDocument(b),h=b.toString(),i=q(c);returnb.collapsed?(f=d(b,!1),{document:g,markerId:f.id,collapsed:!0}):(f=d(b,!1),e=d(b,!0),{document:g,startMarkerId:e.id,endMarkerId:f.id,collapsed:!1,backward:i,toString:function(){return"original text: '"+h+"', new text: '"+b.toString()+"'"}})}functionh(d,f){varg=d.document;"undefined"==typeoff&&(f=!0);varh=a.createRange(g);if(d.collapsed){vari=c(d.markerId,g);if(i){i.style.display="inline";varj=i.previousSibling;
// Workaround for issue 17
j&&3==j.nodeType?(p(i),h.collapseToPoint(j,j.length)):(h.collapseBefore(i),p(i))}elseb.warn("Marker element has been removed. Cannot restore selection.")}elsee(g,h,d.startMarkerId,!0),e(g,h,d.endMarkerId,!1);returnf&&h.normalizeBoundaries(),h}functioni(b,d){vare,h,i=[],j=q(d);
// Order the ranges by position within the DOM, latest first, cloning the array to leave the original untouched
// Now that all the markers are in place and DOM manipulation over, adjust each range's boundaries to lie
// between its markers
for(k=l-1;k>=0;--k)e=b[k],h=a.DomRange.getRangeDocument(e),e.collapsed?e.collapseAfter(c(i[k].markerId,h)):(e.setEndBefore(c(i[k].endMarkerId,h)),e.setStartAfter(c(i[k].startMarkerId,h)));returni}functionj(c){if(!a.isSelectionValid(c))returnb.warn("Cannot save selection. This usually happens when the selection is collapsed and the selection document has lost focus."),null;vard=a.getSelection(c),e=d.getAllRanges(),f=1==e.length&&d.isBackward(),g=i(e,f);
// no ending tag found --- this piece should be encoded as an entity.
j+="<",a=a.substring(1)));g&&(f=a.indexOf("<"),j+=f<0?a:a.substring(0,f),a=f<0?"":a.substring(f),c.chars&&c.chars(h(j)))}if(a==l)throwm("badparse","The sanitizer was unable to parse the following block of html: {0}",a);l=a}
// Clean up any remaining tags
e()}/**
* decodes all entities into regular string
* @param value
* @returns {string} A string with decoded entities.
*/
functionh(a){if(!a)return"";
// Note: IE8 does not preserve spaces at the start/end of innerHTML
// so we must capture them and reattach them afterward
varb=N.exec(a),c=b[1],d=b[3],e=b[2];
// innerText depends on styling as it doesn't display hidden elements.
// Therefore, it's better to use textContent not to cause unnecessary
// reflows. However, IE<9 don't support textContent so the innerText
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.