From 1a41c2da17fa96331227883b45f68e696edcf8b9 Mon Sep 17 00:00:00 2001 From: Anthony Blackshaw Date: Sat, 29 Oct 2016 11:17:00 +0100 Subject: [PATCH] Added support for ambiguous ampersands --- build/html-string.js | 40 ++++++++++- build/html-string.min.js | 4 +- npm-debug.log | 112 +++++++++++++++++++++++++++++++ package.json | 2 +- spec/html-string-spec.js | 12 +++- src/spec/html-string-spec.coffee | 7 ++ src/strings.coffee | 33 ++++++++- 7 files changed, 202 insertions(+), 8 deletions(-) create mode 100644 npm-debug.log diff --git a/build/html-string.js b/build/html-string.js index bdd8170..60fa187 100644 --- a/build/html-string.js +++ b/build/html-string.js @@ -875,6 +875,7 @@ }); this.fsm.addTransition('<', CHAR_OR_ENTITY_OR_TAG, OPENNING_OR_CLOSING_TAG); this.fsm.addTransition('&', CHAR_OR_ENTITY_OR_TAG, ENTITY); + this.fsm.addTransition('END', CHAR_OR_ENTITY_OR_TAG, null); this.fsm.addTransitions(ENTITY_CHARS, ENTITY, null, function(c) { return this.entity += c; }); @@ -882,6 +883,27 @@ this._pushChar("&" + this.entity + ";"); return this.entity = ''; }); + this.fsm.addTransitionAny(ENTITY, CHAR_OR_ENTITY_OR_TAG, function(c) { + var _i, _len, _ref; + this._pushChar('&'); + _ref = this.entity.split(''); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + c = _ref[_i]; + this._pushChar(c); + } + this.entity = ''; + return this._back(); + }); + this.fsm.addTransition('END', ENTITY, null, function() { + var c, _i, _len, _ref; + this._pushChar('&'); + _ref = this.entity.split(''); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + c = _ref[_i]; + this._pushChar(c); + } + return this.entity = ''; + }); this.fsm.addTransitions([' ', '\n'], OPENNING_OR_CLOSING_TAG); this.fsm.addTransitions(ALPHA_CHARS, OPENNING_OR_CLOSING_TAG, OPENING_TAG, function() { return this._back(); @@ -979,7 +1001,7 @@ this.fsm.addTransitions(ENTITY_CHARS, ATTR_ENTITY_NO_DELIM, null, function(c) { return this.entity += c; }); - this.fsm.addTransitions(ENTITY_CHARS, ATTR_ENTITY_SINGLE_DELIM, function(c) { + this.fsm.addTransitions(ENTITY_CHARS, ATTR_ENTITY_SINGLE_DELIM, null, function(c) { return this.entity += c; }); this.fsm.addTransitions(ENTITY_CHARS, ATTR_ENTITY_DOUBLE_DELIM, null, function(c) { @@ -997,6 +1019,21 @@ this.attributeValue += "&" + this.entity + ";"; return this.entity = ''; }); + this.fsm.addTransitionAny(ATTR_ENTITY_NO_DELIM, ATTR_VALUE_NO_DELIM, function(c) { + this.attributeValue += '&' + this.entity; + this.entity = ''; + return this._back(); + }); + this.fsm.addTransitionAny(ATTR_ENTITY_SINGLE_DELIM, ATTR_VALUE_SINGLE_DELIM, function(c) { + this.attributeValue += '&' + this.entity; + this.entity = ''; + return this._back(); + }); + this.fsm.addTransitionAny(ATTR_ENTITY_DOUBLE_DELIM, ATTR_VALUE_DOUBLE_DELIM, function(c) { + this.attributeValue += '&' + this.entity; + this.entity = ''; + return this._back(); + }); } _Parser.prototype._back = function() { @@ -1074,6 +1111,7 @@ } this.head++; } + this.fsm.process('END'); return this.string; }; diff --git a/build/html-string.min.js b/build/html-string.min.js index 23a0820..7efc391 100644 --- a/build/html-string.min.js +++ b/build/html-string.min.js @@ -1,2 +1,2 @@ -/*! HTMLString v1.0.5 by Anthony Blackshaw (https://github.com/anthonyjb) */ -(function(){var FSM,exports;FSM={},FSM.Machine=function(){function Machine(context){this.context=context,this._stateTransitions={},this._stateTransitionsAny={},this._defaultTransition=null,this._initialState=null,this._currentState=null}return Machine.prototype.addTransition=function(action,state,nextState,callback){return nextState||(nextState=state),this._stateTransitions[[action,state]]=[nextState,callback]},Machine.prototype.addTransitions=function(actions,state,nextState,callback){var action,_i,_len,_results;for(nextState||(nextState=state),_results=[],_i=0,_len=actions.length;_len>_i;_i++)action=actions[_i],_results.push(this.addTransition(action,state,nextState,callback));return _results},Machine.prototype.addTransitionAny=function(state,nextState,callback){return nextState||(nextState=state),this._stateTransitionsAny[state]=[nextState,callback]},Machine.prototype.setDefaultTransition=function(state,callback){return this._defaultTransition=[state,callback]},Machine.prototype.getTransition=function(action,state){if(this._stateTransitions[[action,state]])return this._stateTransitions[[action,state]];if(this._stateTransitionsAny[state])return this._stateTransitionsAny[state];if(this._defaultTransition)return this._defaultTransition;throw new Error("Transition is undefined: ("+action+", "+state+")")},Machine.prototype.getCurrentState=function(){return this._currentState},Machine.prototype.setInitialState=function(state){return this._initialState=state,this._currentState?void 0:this.reset()},Machine.prototype.reset=function(){return this._currentState=this._initialState},Machine.prototype.process=function(action){var result;return result=this.getTransition(action,this._currentState),result[1]&&result[1].call(this.context||(this.context=this),action),this._currentState=result[0]},Machine}(),"undefined"!=typeof window&&(window.FSM=FSM),"undefined"!=typeof module&&module.exports&&(exports=module.exports=FSM)}).call(this),function(){var ALPHA_CHARS,ALPHA_NUMERIC_CHARS,ATTR_DELIM,ATTR_ENTITY_DOUBLE_DELIM,ATTR_ENTITY_NO_DELIM,ATTR_ENTITY_SINGLE_DELIM,ATTR_NAME,ATTR_NAME_CHARS,ATTR_NAME_FIND_VALUE,ATTR_OR_TAG_END,ATTR_VALUE_DOUBLE_DELIM,ATTR_VALUE_NO_DELIM,ATTR_VALUE_SINGLE_DELIM,CHAR_OR_ENTITY_OR_TAG,CLOSING_TAG,ENTITY,ENTITY_CHARS,HTMLString,OPENING_TAG,OPENNING_OR_CLOSING_TAG,TAG_NAME_CHARS,TAG_NAME_CLOSING,TAG_NAME_MUST_CLOSE,TAG_NAME_OPENING,TAG_OPENING_SELF_CLOSING,exports,_Parser,__slice=[].slice,__indexOf=[].indexOf||function(item){for(var i=0,l=this.length;l>i;i++)if(i in this&&this[i]===item)return i;return-1};HTMLString={},"undefined"!=typeof window&&(window.HTMLString=HTMLString),"undefined"!=typeof module&&module.exports&&(exports=module.exports=HTMLString),HTMLString.String=function(){function String(html,preserveWhitespace){null==preserveWhitespace&&(preserveWhitespace=!1),this._preserveWhitespace=preserveWhitespace,html?(null===HTMLString.String._parser&&(HTMLString.String._parser=new _Parser),this.characters=HTMLString.String._parser.parse(html,this._preserveWhitespace).characters):this.characters=[]}return String._parser=null,String.prototype.isWhitespace=function(){var c,_i,_len,_ref;for(_ref=this.characters,_i=0,_len=_ref.length;_len>_i;_i++)if(c=_ref[_i],!c.isWhitespace())return!1;return!0},String.prototype.length=function(){return this.characters.length},String.prototype.preserveWhitespace=function(){return this._preserveWhitespace},String.prototype.capitalize=function(){var c,newString;return newString=this.copy(),newString.length()&&(c=newString.characters[0]._c.toUpperCase(),newString.characters[0]._c=c),newString},String.prototype.charAt=function(index){return this.characters[index].copy()},String.prototype.concat=function(){var c,indexChar,inheritFormat,inheritedTags,newString,string,strings,tail,_i,_j,_k,_l,_len,_len1,_len2,_ref,_ref1;for(strings=2<=arguments.length?__slice.call(arguments,0,_i=arguments.length-1):(_i=0,[]),inheritFormat=arguments[_i++],"undefined"!=typeof inheritFormat&&"boolean"!=typeof inheritFormat&&(strings.push(inheritFormat),inheritFormat=!0),newString=this.copy(),_j=0,_len=strings.length;_len>_j;_j++)if(string=strings[_j],0!==string.length){if(tail=string,"string"==typeof string&&(tail=new HTMLString.String(string,this._preserveWhitespace)),inheritFormat&&newString.length())for(indexChar=newString.charAt(newString.length()-1),inheritedTags=indexChar.tags(),indexChar.isTag()&&inheritedTags.shift(),"string"!=typeof string&&(tail=tail.copy()),_ref=tail.characters,_k=0,_len1=_ref.length;_len1>_k;_k++)c=_ref[_k],c.addTags.apply(c,inheritedTags);for(_ref1=tail.characters,_l=0,_len2=_ref1.length;_len2>_l;_l++)c=_ref1[_l],newString.characters.push(c)}return newString},String.prototype.contains=function(substring){var c,found,from,i,_i,_len,_ref;if("string"==typeof substring)return this.text().indexOf(substring)>-1;for(from=0;from<=this.length()-substring.length();){for(found=!0,_ref=substring.characters,i=_i=0,_len=_ref.length;_len>_i;i=++_i)if(c=_ref[i],!c.eq(this.characters[i+from])){found=!1;break}if(found)return!0;from++}return!1},String.prototype.endsWith=function(substring){var c,characters,i,_i,_len,_ref;if("string"==typeof substring)return""===substring||this.text().slice(-substring.length)===substring;for(characters=this.characters.slice().reverse(),_ref=substring.characters.slice().reverse(),i=_i=0,_len=_ref.length;_len>_i;i=++_i)if(c=_ref[i],!c.eq(characters[i]))return!1;return!0},String.prototype.format=function(){var c,from,i,newString,tags,to,_i;for(from=arguments[0],to=arguments[1],tags=3<=arguments.length?__slice.call(arguments,2):[],0>to&&(to=this.length()+to+1),0>from&&(from=this.length()+from),newString=this.copy(),i=_i=from;to>=from?to>_i:_i>to;i=to>=from?++_i:--_i)c=newString.characters[i],c.addTags.apply(c,tags);return newString},String.prototype.hasTags=function(){var c,found,strict,tags,_i,_j,_len,_ref;for(tags=2<=arguments.length?__slice.call(arguments,0,_i=arguments.length-1):(_i=0,[]),strict=arguments[_i++],"undefined"!=typeof strict&&"boolean"!=typeof strict&&(tags.push(strict),strict=!1),found=!1,_ref=this.characters,_j=0,_len=_ref.length;_len>_j;_j++)if(c=_ref[_j],c.hasTags.apply(c,tags))found=!0;else if(strict)return!1;return found},String.prototype.html=function(){var c,closingTag,closingTags,head,html,openHeads,openTag,openTags,tag,_i,_j,_k,_l,_len,_len1,_len2,_len3,_len4,_m,_ref,_ref1,_ref2,_ref3;for(html="",openTags=[],openHeads=[],closingTags=[],_ref=this.characters,_i=0,_len=_ref.length;_len>_i;_i++){for(c=_ref[_i],closingTags=[],_ref1=openTags.slice().reverse(),_j=0,_len1=_ref1.length;_len1>_j;_j++)if(openTag=_ref1[_j],closingTags.push(openTag),!c.hasTags(openTag)){for(_k=0,_len2=closingTags.length;_len2>_k;_k++)closingTag=closingTags[_k],html+=closingTag.tail(),openTags.pop(),openHeads.pop();closingTags=[]}for(_ref2=c._tags,_l=0,_len3=_ref2.length;_len3>_l;_l++)tag=_ref2[_l],-1===openHeads.indexOf(tag.head())&&(tag.selfClosing()||(head=tag.head(),html+=head,openTags.push(tag),openHeads.push(head)));c._tags.length>0&&c._tags[0].selfClosing()&&(html+=c._tags[0].head()),html+=c.c()}for(_ref3=openTags.reverse(),_m=0,_len4=_ref3.length;_len4>_m;_m++)tag=_ref3[_m],html+=tag.tail();return html},String.prototype.indexOf=function(substring,from){var c,found,i,_i,_len,_ref;if(null==from&&(from=0),0>from&&(from=0),"string"==typeof substring)return this.text().indexOf(substring,from);for(;from<=this.length()-substring.length();){for(found=!0,_ref=substring.characters,i=_i=0,_len=_ref.length;_len>_i;i=++_i)if(c=_ref[i],!c.eq(this.characters[i+from])){found=!1;break}if(found)return from;from++}return-1},String.prototype.insert=function(index,substring,inheritFormat){var c,head,indexChar,inheritedTags,middle,newString,tail,_i,_j,_k,_len,_len1,_len2,_ref,_ref1,_ref2;if(null==inheritFormat&&(inheritFormat=!0),head=this.slice(0,index),tail=this.slice(index),0>index&&(index=this.length()+index),middle=substring,"string"==typeof substring&&(middle=new HTMLString.String(substring,this._preserveWhitespace)),inheritFormat&&index>0)for(indexChar=this.charAt(index-1),inheritedTags=indexChar.tags(),indexChar.isTag()&&inheritedTags.shift(),"string"!=typeof substring&&(middle=middle.copy()),_ref=middle.characters,_i=0,_len=_ref.length;_len>_i;_i++)c=_ref[_i],c.addTags.apply(c,inheritedTags);for(newString=head,_ref1=middle.characters,_j=0,_len1=_ref1.length;_len1>_j;_j++)c=_ref1[_j],newString.characters.push(c);for(_ref2=tail.characters,_k=0,_len2=_ref2.length;_len2>_k;_k++)c=_ref2[_k],newString.characters.push(c);return newString},String.prototype.lastIndexOf=function(substring,from){var c,characters,found,i,skip,_i,_j,_len,_len1;if(null==from&&(from=0),0>from&&(from=0),characters=this.characters.slice(from).reverse(),from=0,"string"==typeof substring){if(!this.contains(substring))return-1;for(substring=substring.split("").reverse();from<=characters.length-substring.length;){for(found=!0,skip=0,i=_i=0,_len=substring.length;_len>_i;i=++_i)if(c=substring[i],characters[i+from].isTag()&&(skip+=1),c!==characters[skip+i+from].c()){found=!1;break}if(found)return from;from++}return-1}for(substring=substring.characters.slice().reverse();from<=characters.length-substring.length;){for(found=!0,i=_j=0,_len1=substring.length;_len1>_j;i=++_j)if(c=substring[i],!c.eq(characters[i+from])){found=!1;break}if(found)return from;from++}return-1},String.prototype.optimize=function(){var c,closingTag,closingTags,head,lastC,len,openHeads,openTag,openTags,runLength,runLengthSort,runLengths,run_length,t,tag,_i,_j,_k,_l,_len,_len1,_len2,_len3,_len4,_len5,_len6,_m,_n,_o,_ref,_ref1,_ref2,_ref3,_ref4,_ref5,_results;for(openTags=[],openHeads=[],lastC=null,_ref=this.characters.slice().reverse(),_i=0,_len=_ref.length;_len>_i;_i++){for(c=_ref[_i],c._runLengthMap={},c._runLengthMapSize=0,closingTags=[],_ref1=openTags.slice().reverse(),_j=0,_len1=_ref1.length;_len1>_j;_j++)if(openTag=_ref1[_j],closingTags.push(openTag),!c.hasTags(openTag)){for(_k=0,_len2=closingTags.length;_len2>_k;_k++)closingTag=closingTags[_k],openTags.pop(),openHeads.pop();closingTags=[]}for(_ref2=c._tags,_l=0,_len3=_ref2.length;_len3>_l;_l++)tag=_ref2[_l],-1===openHeads.indexOf(tag.head())&&(tag.selfClosing()||(openTags.push(tag),openHeads.push(tag.head())));for(_m=0,_len4=openTags.length;_len4>_m;_m++)tag=openTags[_m],head=tag.head(),lastC?(c._runLengthMap[head]||(c._runLengthMap[head]=[tag,0]),run_length=0,lastC._runLengthMap[head]&&(run_length=lastC._runLengthMap[head][1]),c._runLengthMap[head][1]=run_length+1):c._runLengthMap[head]=[tag,1];lastC=c}for(runLengthSort=function(a,b){return b[1]-a[1]},_ref3=this.characters,_results=[],_n=0,_len5=_ref3.length;_len5>_n;_n++)if(c=_ref3[_n],len=c._tags.length,!(len>0&&c._tags[0].selfClosing()&&3>len||2>len)){runLengths=[],_ref4=c._runLengthMap;for(tag in _ref4)runLength=_ref4[tag],runLengths.push(runLength);for(runLengths.sort(runLengthSort),_ref5=c._tags.slice(),_o=0,_len6=_ref5.length;_len6>_o;_o++)tag=_ref5[_o],tag.selfClosing()||c.removeTags(tag);_results.push(c.addTags.apply(c,function(){var _len7,_p,_results1;for(_results1=[],_p=0,_len7=runLengths.length;_len7>_p;_p++)t=runLengths[_p],_results1.push(t[0]);return _results1}()))}return _results},String.prototype.slice=function(from,to){var c,newString;return newString=new HTMLString.String("",this._preserveWhitespace),newString.characters=function(){var _i,_len,_ref,_results;for(_ref=this.characters.slice(from,to),_results=[],_i=0,_len=_ref.length;_len>_i;_i++)c=_ref[_i],_results.push(c.copy());return _results}.call(this),newString},String.prototype.split=function(separator,limit){var count,end,i,index,indexes,lastIndex,start,substrings,_i,_ref;for(null==separator&&(separator=""),null==limit&&(limit=0),lastIndex=0,count=0,indexes=[0];;){if(limit>0&&count>limit)break;if(index=this.indexOf(separator,lastIndex),-1===index)break;indexes.push(index),lastIndex=index+1}for(indexes.push(this.length()),substrings=[],i=_i=0,_ref=indexes.length-2;_ref>=0?_ref>=_i:_i>=_ref;i=_ref>=0?++_i:--_i)start=indexes[i],i>0&&(start+=1),end=indexes[i+1],substrings.push(this.slice(start,end));return substrings},String.prototype.startsWith=function(substring){var c,i,_i,_len,_ref;if("string"==typeof substring)return this.text().slice(0,substring.length)===substring;for(_ref=substring.characters,i=_i=0,_len=_ref.length;_len>_i;i=++_i)if(c=_ref[i],!c.eq(this.characters[i]))return!1;return!0},String.prototype.substr=function(from,length){return 0>=length?new HTMLString.String("",this._preserveWhitespace):(0>from&&(from=this.length()+from),void 0===length&&(length=this.length()-from),this.slice(from,from+length))},String.prototype.substring=function(from,to){return void 0===to&&(to=this.length()),this.slice(from,to)},String.prototype.text=function(){var c,text,_i,_len,_ref;for(text="",_ref=this.characters,_i=0,_len=_ref.length;_len>_i;_i++)c=_ref[_i],c.isTag()?c.isTag("br")&&(text+="\n"):text+=(" "!==c.c(),c.c());return this.constructor.decode(text)},String.prototype.toLowerCase=function(){var c,newString,_i,_len,_ref;for(newString=this.copy(),_ref=newString.characters,_i=0,_len=_ref.length;_len>_i;_i++)c=_ref[_i],1===c._c.length&&(c._c=c._c.toLowerCase());return newString},String.prototype.toUpperCase=function(){var c,newString,_i,_len,_ref;for(newString=this.copy(),_ref=newString.characters,_i=0,_len=_ref.length;_len>_i;_i++)c=_ref[_i],1===c._c.length&&(c._c=c._c.toUpperCase());return newString},String.prototype.trim=function(){var c,from,newString,to,_i,_j,_len,_len1,_ref,_ref1;for(_ref=this.characters,from=_i=0,_len=_ref.length;_len>_i&&(c=_ref[from],c.isWhitespace());from=++_i);for(_ref1=this.characters.slice().reverse(),to=_j=0,_len1=_ref1.length;_len1>_j&&(c=_ref1[to],c.isWhitespace());to=++_j);return to=this.length()-to-1,newString=new HTMLString.String("",this._preserveWhitespace),newString.characters=function(){var _k,_len2,_ref2,_results;for(_ref2=this.characters.slice(from,+to+1||9e9),_results=[],_k=0,_len2=_ref2.length;_len2>_k;_k++)c=_ref2[_k],_results.push(c.copy());return _results}.call(this),newString},String.prototype.trimLeft=function(){var c,from,newString,to,_i,_len,_ref;for(to=this.length()-1,_ref=this.characters,from=_i=0,_len=_ref.length;_len>_i&&(c=_ref[from],c.isWhitespace());from=++_i);return newString=new HTMLString.String("",this._preserveWhitespace),newString.characters=function(){var _j,_len1,_ref1,_results;for(_ref1=this.characters.slice(from,+to+1||9e9),_results=[],_j=0,_len1=_ref1.length;_len1>_j;_j++)c=_ref1[_j],_results.push(c.copy());return _results}.call(this),newString},String.prototype.trimRight=function(){var c,from,newString,to,_i,_len,_ref;for(from=0,_ref=this.characters.slice().reverse(),to=_i=0,_len=_ref.length;_len>_i&&(c=_ref[to],c.isWhitespace());to=++_i);return to=this.length()-to-1,newString=new HTMLString.String("",this._preserveWhitespace),newString.characters=function(){var _j,_len1,_ref1,_results;for(_ref1=this.characters.slice(from,+to+1||9e9),_results=[],_j=0,_len1=_ref1.length;_len1>_j;_j++)c=_ref1[_j],_results.push(c.copy());return _results}.call(this),newString},String.prototype.unformat=function(){var c,from,i,newString,tags,to,_i;for(from=arguments[0],to=arguments[1],tags=3<=arguments.length?__slice.call(arguments,2):[],0>to&&(to=this.length()+to+1),0>from&&(from=this.length()+from),newString=this.copy(),i=_i=from;to>=from?to>_i:_i>to;i=to>=from?++_i:--_i)c=newString.characters[i],c.removeTags.apply(c,tags);return newString},String.prototype.copy=function(){var c,stringCopy;return stringCopy=new HTMLString.String("",this._preserveWhitespace),stringCopy.characters=function(){var _i,_len,_ref,_results;for(_ref=this.characters,_results=[],_i=0,_len=_ref.length;_len>_i;_i++)c=_ref[_i],_results.push(c.copy());return _results}.call(this),stringCopy},String.decode=function(string){var textarea;return textarea=document.createElement("textarea"),textarea.innerHTML=string,textarea.textContent},String.encode=function(string){var textarea;return textarea=document.createElement("textarea"),textarea.textContent=string,textarea.innerHTML},String.join=function(separator,strings){var joined,s,_i,_len;for(joined=strings.shift(),_i=0,_len=strings.length;_len>_i;_i++)s=strings[_i],joined=joined.concat(separator,s);return joined},String}(),ALPHA_CHARS="AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz-_$".split(""),ALPHA_NUMERIC_CHARS=ALPHA_CHARS.concat("1234567890".split("")),ATTR_NAME_CHARS=ALPHA_NUMERIC_CHARS.concat([":"]),ENTITY_CHARS=ALPHA_NUMERIC_CHARS.concat(["#"]),TAG_NAME_CHARS=ALPHA_NUMERIC_CHARS.concat([":"]),CHAR_OR_ENTITY_OR_TAG=1,ENTITY=2,OPENNING_OR_CLOSING_TAG=3,OPENING_TAG=4,CLOSING_TAG=5,TAG_NAME_OPENING=6,TAG_NAME_CLOSING=7,TAG_OPENING_SELF_CLOSING=8,TAG_NAME_MUST_CLOSE=9,ATTR_OR_TAG_END=10,ATTR_NAME=11,ATTR_NAME_FIND_VALUE=12,ATTR_DELIM=13,ATTR_VALUE_SINGLE_DELIM=14,ATTR_VALUE_DOUBLE_DELIM=15,ATTR_VALUE_NO_DELIM=16,ATTR_ENTITY_NO_DELIM=17,ATTR_ENTITY_SINGLE_DELIM=18,ATTR_ENTITY_DOUBLE_DELIM=19,_Parser=function(){function _Parser(){this.fsm=new FSM.Machine(this),this.fsm.setInitialState(CHAR_OR_ENTITY_OR_TAG),this.fsm.addTransitionAny(CHAR_OR_ENTITY_OR_TAG,null,function(c){return this._pushChar(c)}),this.fsm.addTransition("<",CHAR_OR_ENTITY_OR_TAG,OPENNING_OR_CLOSING_TAG),this.fsm.addTransition("&",CHAR_OR_ENTITY_OR_TAG,ENTITY),this.fsm.addTransitions(ENTITY_CHARS,ENTITY,null,function(c){return this.entity+=c}),this.fsm.addTransition(";",ENTITY,CHAR_OR_ENTITY_OR_TAG,function(){return this._pushChar("&"+this.entity+";"),this.entity=""}),this.fsm.addTransitions([" ","\n"],OPENNING_OR_CLOSING_TAG),this.fsm.addTransitions(ALPHA_CHARS,OPENNING_OR_CLOSING_TAG,OPENING_TAG,function(){return this._back()}),this.fsm.addTransition("/",OPENNING_OR_CLOSING_TAG,CLOSING_TAG),this.fsm.addTransitions([" ","\n"],OPENING_TAG),this.fsm.addTransitions(ALPHA_CHARS,OPENING_TAG,TAG_NAME_OPENING,function(){return this._back()}),this.fsm.addTransitions([" ","\n"],CLOSING_TAG),this.fsm.addTransitions(ALPHA_CHARS,CLOSING_TAG,TAG_NAME_CLOSING,function(){return this._back()}),this.fsm.addTransitions(TAG_NAME_CHARS,TAG_NAME_OPENING,null,function(c){return this.tagName+=c}),this.fsm.addTransitions([" ","\n"],TAG_NAME_OPENING,ATTR_OR_TAG_END),this.fsm.addTransition("/",TAG_NAME_OPENING,TAG_OPENING_SELF_CLOSING,function(){return this.selfClosing=!0}),this.fsm.addTransition(">",TAG_NAME_OPENING,CHAR_OR_ENTITY_OR_TAG,function(){return this._pushTag()}),this.fsm.addTransitions([" ","\n"],TAG_OPENING_SELF_CLOSING),this.fsm.addTransition(">",TAG_OPENING_SELF_CLOSING,CHAR_OR_ENTITY_OR_TAG,function(){return this._pushTag()}),this.fsm.addTransitions([" ","\n"],ATTR_OR_TAG_END),this.fsm.addTransition("/",ATTR_OR_TAG_END,TAG_OPENING_SELF_CLOSING,function(){return this.selfClosing=!0}),this.fsm.addTransition(">",ATTR_OR_TAG_END,CHAR_OR_ENTITY_OR_TAG,function(){return this._pushTag()}),this.fsm.addTransitions(ALPHA_CHARS,ATTR_OR_TAG_END,ATTR_NAME,function(){return this._back()}),this.fsm.addTransitions(TAG_NAME_CHARS,TAG_NAME_CLOSING,null,function(c){return this.tagName+=c}),this.fsm.addTransitions([" ","\n"],TAG_NAME_CLOSING,TAG_NAME_MUST_CLOSE),this.fsm.addTransition(">",TAG_NAME_CLOSING,CHAR_OR_ENTITY_OR_TAG,function(){return this._popTag()}),this.fsm.addTransitions([" ","\n"],TAG_NAME_MUST_CLOSE),this.fsm.addTransition(">",TAG_NAME_MUST_CLOSE,CHAR_OR_ENTITY_OR_TAG,function(){return this._popTag()}),this.fsm.addTransitions(ATTR_NAME_CHARS,ATTR_NAME,null,function(c){return this.attributeName+=c}),this.fsm.addTransitions([" ","\n"],ATTR_NAME,ATTR_NAME_FIND_VALUE),this.fsm.addTransition("=",ATTR_NAME,ATTR_DELIM),this.fsm.addTransitions([" ","\n"],ATTR_NAME_FIND_VALUE),this.fsm.addTransition("=",ATTR_NAME_FIND_VALUE,ATTR_DELIM),this.fsm.addTransitions(">",ATTR_NAME,ATTR_OR_TAG_END,function(){return this._pushAttribute(),this._back()}),this.fsm.addTransitionAny(ATTR_NAME_FIND_VALUE,ATTR_OR_TAG_END,function(){return this._pushAttribute(),this._back()}),this.fsm.addTransitions([" ","\n"],ATTR_DELIM),this.fsm.addTransition("'",ATTR_DELIM,ATTR_VALUE_SINGLE_DELIM),this.fsm.addTransition('"',ATTR_DELIM,ATTR_VALUE_DOUBLE_DELIM),this.fsm.addTransitions(ALPHA_NUMERIC_CHARS.concat(["&"],ATTR_DELIM,ATTR_VALUE_NO_DELIM,function(){return this._back()})),this.fsm.addTransition(" ",ATTR_VALUE_NO_DELIM,ATTR_OR_TAG_END,function(){return this._pushAttribute()}),this.fsm.addTransitions(["/",">"],ATTR_VALUE_NO_DELIM,ATTR_OR_TAG_END,function(){return this._back(),this._pushAttribute()}),this.fsm.addTransition("&",ATTR_VALUE_NO_DELIM,ATTR_ENTITY_NO_DELIM),this.fsm.addTransitionAny(ATTR_VALUE_NO_DELIM,null,function(c){return this.attributeValue+=c}),this.fsm.addTransition("'",ATTR_VALUE_SINGLE_DELIM,ATTR_OR_TAG_END,function(){return this._pushAttribute()}),this.fsm.addTransition("&",ATTR_VALUE_SINGLE_DELIM,ATTR_ENTITY_SINGLE_DELIM),this.fsm.addTransitionAny(ATTR_VALUE_SINGLE_DELIM,null,function(c){return this.attributeValue+=c}),this.fsm.addTransition('"',ATTR_VALUE_DOUBLE_DELIM,ATTR_OR_TAG_END,function(){return this._pushAttribute()}),this.fsm.addTransition("&",ATTR_VALUE_DOUBLE_DELIM,ATTR_ENTITY_DOUBLE_DELIM),this.fsm.addTransitionAny(ATTR_VALUE_DOUBLE_DELIM,null,function(c){return this.attributeValue+=c}),this.fsm.addTransitions(ENTITY_CHARS,ATTR_ENTITY_NO_DELIM,null,function(c){return this.entity+=c}),this.fsm.addTransitions(ENTITY_CHARS,ATTR_ENTITY_SINGLE_DELIM,function(c){return this.entity+=c}),this.fsm.addTransitions(ENTITY_CHARS,ATTR_ENTITY_DOUBLE_DELIM,null,function(c){return this.entity+=c}),this.fsm.addTransition(";",ATTR_ENTITY_NO_DELIM,ATTR_VALUE_NO_DELIM,function(){return this.attributeValue+="&"+this.entity+";",this.entity=""}),this.fsm.addTransition(";",ATTR_ENTITY_SINGLE_DELIM,ATTR_VALUE_SINGLE_DELIM,function(){return this.attributeValue+="&"+this.entity+";",this.entity=""}),this.fsm.addTransition(";",ATTR_ENTITY_DOUBLE_DELIM,ATTR_VALUE_DOUBLE_DELIM,function(){return this.attributeValue+="&"+this.entity+";",this.entity=""})}return _Parser.prototype._back=function(){return this.head--},_Parser.prototype._pushAttribute=function(){return this.attributes[this.attributeName]=this.attributeValue,this.attributeName="",this.attributeValue=""},_Parser.prototype._pushChar=function(c){var character,lastCharacter;return character=new HTMLString.Character(c,this.tags),this._preserveWhitespace?void this.string.characters.push(character):!this.string.length()||character.isTag()||character.isEntity()||!character.isWhitespace()||(lastCharacter=this.string.characters[this.string.length()-1],!lastCharacter.isWhitespace()||lastCharacter.isTag()||lastCharacter.isEntity())?this.string.characters.push(character):void 0},_Parser.prototype._pushTag=function(){var tag,_ref;return tag=new HTMLString.Tag(this.tagName,this.attributes),this.tags.push(tag),tag.selfClosing()&&(this._pushChar(""),this.tags.pop(),!this.selfClosed&&(_ref=this.tagName,__indexOf.call(HTMLString.Tag.SELF_CLOSING,_ref)>=0)&&this.fsm.reset()),this.tagName="",this.selfClosed=!1,this.attributes={}},_Parser.prototype._popTag=function(){for(var character,tag;;)if(tag=this.tags.pop(),this.string.length()&&(character=this.string.characters[this.string.length()-1],character.isTag()||character.isEntity()||!character.isWhitespace()||character.removeTags(tag)),tag.name()===this.tagName.toLowerCase())break;return this.tagName=""},_Parser.prototype.parse=function(html,preserveWhitespace){var character,error;for(this._preserveWhitespace=preserveWhitespace,this.reset(),html=this.preprocess(html),this.fsm.parser=this;this.head> "+error)}this.head++}return this.string},_Parser.prototype.preprocess=function(html){return html=html.replace(/\r\n/g,"\n").replace(/\r/g,"\n"),html=html.replace(//g,""),this._preserveWhitespace||(html=html.replace(/\s+/g," ")),html},_Parser.prototype.reset=function(){return this.fsm.reset(),this.head=0,this.string=new HTMLString.String,this.entity="",this.tags=[],this.tagName="",this.selfClosing=!1,this.attributes={},this.attributeName="",this.attributeValue=""},_Parser}(),HTMLString.Tag=function(){function Tag(name,attributes){var k,v;this._name=name.toLowerCase(),this._selfClosing=HTMLString.Tag.SELF_CLOSING[this._name]===!0,this._head=null,this._attributes={};for(k in attributes)v=attributes[k],this._attributes[k]=v}return Tag.SELF_CLOSING={area:!0,base:!0,br:!0,hr:!0,img:!0,input:!0,"link meta":!0,wbr:!0},Tag.prototype.head=function(){var components,k,v,_ref;if(!this._head){components=[],_ref=this._attributes;for(k in _ref)v=_ref[k],components.push(v?""+k+'="'+v+'"':""+k);components.sort(),components.unshift(this._name),this._head="<"+components.join(" ")+">"}return this._head},Tag.prototype.name=function(){return this._name},Tag.prototype.selfClosing=function(){return this._selfClosing},Tag.prototype.tail=function(){return this._selfClosing?"":""},Tag.prototype.attr=function(name,value){return void 0===value?this._attributes[name]:(this._attributes[name]=value,this._head=null)},Tag.prototype.removeAttr=function(name){return void 0!==this._attributes[name]?(delete this._attributes[name],this._head=null):void 0},Tag.prototype.copy=function(){return new HTMLString.Tag(this._name,this._attributes)},Tag}(),HTMLString.Character=function(){function Character(c,tags){this._c=c,c.length>1&&(this._c=c.toLowerCase()),this._tags=[],this.addTags.apply(this,tags)}return Character.prototype.c=function(){return this._c},Character.prototype.isEntity=function(){return this._c.length>1},Character.prototype.isTag=function(tagName){return 0!==this._tags.length&&this._tags[0].selfClosing()?tagName&&this._tags[0].name()!==tagName?!1:!0:!1},Character.prototype.isWhitespace=function(){var _ref;return" "===(_ref=this._c)||"\n"===_ref||" "===_ref||this.isTag("br")},Character.prototype.tags=function(){var t;return function(){var _i,_len,_ref,_results;for(_ref=this._tags,_results=[],_i=0,_len=_ref.length;_len>_i;_i++)t=_ref[_i],_results.push(t.copy());return _results}.call(this)},Character.prototype.addTags=function(){var tag,tags,_i,_len,_results;for(tags=1<=arguments.length?__slice.call(arguments,0):[],_results=[],_i=0,_len=tags.length;_len>_i;_i++)tag=tags[_i],Array.isArray(tag)||(tag.selfClosing()?this.isTag()||this._tags.unshift(tag.copy()):_results.push(this._tags.push(tag.copy())));return _results},Character.prototype.eq=function(c){var tag,tags,_i,_j,_len,_len1,_ref,_ref1;if(this.c()!==c.c())return!1;if(this._tags.length!==c._tags.length)return!1;for(tags={},_ref=this._tags,_i=0,_len=_ref.length;_len>_i;_i++)tag=_ref[_i],tags[tag.head()]=!0;for(_ref1=c._tags,_j=0,_len1=_ref1.length;_len1>_j;_j++)if(tag=_ref1[_j],!tags[tag.head()])return!1;return!0},Character.prototype.hasTags=function(){var tag,tagHeads,tagNames,tags,_i,_j,_len,_len1,_ref;for(tags=1<=arguments.length?__slice.call(arguments,0):[],tagNames={},tagHeads={},_ref=this._tags,_i=0,_len=_ref.length;_len>_i;_i++)tag=_ref[_i],tagNames[tag.name()]=!0,tagHeads[tag.head()]=!0;for(_j=0,_len1=tags.length;_len1>_j;_j++)if(tag=tags[_j],"string"==typeof tag){if(void 0===tagNames[tag])return!1}else if(void 0===tagHeads[tag.head()])return!1;return!0},Character.prototype.removeTags=function(){var heads,names,newTags,tag,tags,_i,_len;if(tags=1<=arguments.length?__slice.call(arguments,0):[],0===tags.length)return void(this._tags=[]);for(names={},heads={},_i=0,_len=tags.length;_len>_i;_i++)tag=tags[_i],"string"==typeof tag?names[tag]=tag:heads[tag.head()]=tag;return newTags=[],this._tags=this._tags.filter(function(tag){return heads[tag.head()]||names[tag.name()]?void 0:tag})},Character.prototype.copy=function(){var t;return new HTMLString.Character(this._c,function(){var _i,_len,_ref,_results;for(_ref=this._tags,_results=[],_i=0,_len=_ref.length;_len>_i;_i++)t=_ref[_i],_results.push(t.copy());return _results}.call(this))},Character}()}.call(this); \ No newline at end of file +/*! HTMLString v1.0.6 by Anthony Blackshaw (https://github.com/anthonyjb) */ +(function(){var FSM,exports;FSM={},FSM.Machine=function(){function Machine(context){this.context=context,this._stateTransitions={},this._stateTransitionsAny={},this._defaultTransition=null,this._initialState=null,this._currentState=null}return Machine.prototype.addTransition=function(action,state,nextState,callback){return nextState||(nextState=state),this._stateTransitions[[action,state]]=[nextState,callback]},Machine.prototype.addTransitions=function(actions,state,nextState,callback){var action,_i,_len,_results;for(nextState||(nextState=state),_results=[],_i=0,_len=actions.length;_len>_i;_i++)action=actions[_i],_results.push(this.addTransition(action,state,nextState,callback));return _results},Machine.prototype.addTransitionAny=function(state,nextState,callback){return nextState||(nextState=state),this._stateTransitionsAny[state]=[nextState,callback]},Machine.prototype.setDefaultTransition=function(state,callback){return this._defaultTransition=[state,callback]},Machine.prototype.getTransition=function(action,state){if(this._stateTransitions[[action,state]])return this._stateTransitions[[action,state]];if(this._stateTransitionsAny[state])return this._stateTransitionsAny[state];if(this._defaultTransition)return this._defaultTransition;throw new Error("Transition is undefined: ("+action+", "+state+")")},Machine.prototype.getCurrentState=function(){return this._currentState},Machine.prototype.setInitialState=function(state){return this._initialState=state,this._currentState?void 0:this.reset()},Machine.prototype.reset=function(){return this._currentState=this._initialState},Machine.prototype.process=function(action){var result;return result=this.getTransition(action,this._currentState),result[1]&&result[1].call(this.context||(this.context=this),action),this._currentState=result[0]},Machine}(),"undefined"!=typeof window&&(window.FSM=FSM),"undefined"!=typeof module&&module.exports&&(exports=module.exports=FSM)}).call(this),function(){var ALPHA_CHARS,ALPHA_NUMERIC_CHARS,ATTR_DELIM,ATTR_ENTITY_DOUBLE_DELIM,ATTR_ENTITY_NO_DELIM,ATTR_ENTITY_SINGLE_DELIM,ATTR_NAME,ATTR_NAME_CHARS,ATTR_NAME_FIND_VALUE,ATTR_OR_TAG_END,ATTR_VALUE_DOUBLE_DELIM,ATTR_VALUE_NO_DELIM,ATTR_VALUE_SINGLE_DELIM,CHAR_OR_ENTITY_OR_TAG,CLOSING_TAG,ENTITY,ENTITY_CHARS,HTMLString,OPENING_TAG,OPENNING_OR_CLOSING_TAG,TAG_NAME_CHARS,TAG_NAME_CLOSING,TAG_NAME_MUST_CLOSE,TAG_NAME_OPENING,TAG_OPENING_SELF_CLOSING,exports,_Parser,__slice=[].slice,__indexOf=[].indexOf||function(item){for(var i=0,l=this.length;l>i;i++)if(i in this&&this[i]===item)return i;return-1};HTMLString={},"undefined"!=typeof window&&(window.HTMLString=HTMLString),"undefined"!=typeof module&&module.exports&&(exports=module.exports=HTMLString),HTMLString.String=function(){function String(html,preserveWhitespace){null==preserveWhitespace&&(preserveWhitespace=!1),this._preserveWhitespace=preserveWhitespace,html?(null===HTMLString.String._parser&&(HTMLString.String._parser=new _Parser),this.characters=HTMLString.String._parser.parse(html,this._preserveWhitespace).characters):this.characters=[]}return String._parser=null,String.prototype.isWhitespace=function(){var c,_i,_len,_ref;for(_ref=this.characters,_i=0,_len=_ref.length;_len>_i;_i++)if(c=_ref[_i],!c.isWhitespace())return!1;return!0},String.prototype.length=function(){return this.characters.length},String.prototype.preserveWhitespace=function(){return this._preserveWhitespace},String.prototype.capitalize=function(){var c,newString;return newString=this.copy(),newString.length()&&(c=newString.characters[0]._c.toUpperCase(),newString.characters[0]._c=c),newString},String.prototype.charAt=function(index){return this.characters[index].copy()},String.prototype.concat=function(){var c,indexChar,inheritFormat,inheritedTags,newString,string,strings,tail,_i,_j,_k,_l,_len,_len1,_len2,_ref,_ref1;for(strings=2<=arguments.length?__slice.call(arguments,0,_i=arguments.length-1):(_i=0,[]),inheritFormat=arguments[_i++],"undefined"!=typeof inheritFormat&&"boolean"!=typeof inheritFormat&&(strings.push(inheritFormat),inheritFormat=!0),newString=this.copy(),_j=0,_len=strings.length;_len>_j;_j++)if(string=strings[_j],0!==string.length){if(tail=string,"string"==typeof string&&(tail=new HTMLString.String(string,this._preserveWhitespace)),inheritFormat&&newString.length())for(indexChar=newString.charAt(newString.length()-1),inheritedTags=indexChar.tags(),indexChar.isTag()&&inheritedTags.shift(),"string"!=typeof string&&(tail=tail.copy()),_ref=tail.characters,_k=0,_len1=_ref.length;_len1>_k;_k++)c=_ref[_k],c.addTags.apply(c,inheritedTags);for(_ref1=tail.characters,_l=0,_len2=_ref1.length;_len2>_l;_l++)c=_ref1[_l],newString.characters.push(c)}return newString},String.prototype.contains=function(substring){var c,found,from,i,_i,_len,_ref;if("string"==typeof substring)return this.text().indexOf(substring)>-1;for(from=0;from<=this.length()-substring.length();){for(found=!0,_ref=substring.characters,i=_i=0,_len=_ref.length;_len>_i;i=++_i)if(c=_ref[i],!c.eq(this.characters[i+from])){found=!1;break}if(found)return!0;from++}return!1},String.prototype.endsWith=function(substring){var c,characters,i,_i,_len,_ref;if("string"==typeof substring)return""===substring||this.text().slice(-substring.length)===substring;for(characters=this.characters.slice().reverse(),_ref=substring.characters.slice().reverse(),i=_i=0,_len=_ref.length;_len>_i;i=++_i)if(c=_ref[i],!c.eq(characters[i]))return!1;return!0},String.prototype.format=function(){var c,from,i,newString,tags,to,_i;for(from=arguments[0],to=arguments[1],tags=3<=arguments.length?__slice.call(arguments,2):[],0>to&&(to=this.length()+to+1),0>from&&(from=this.length()+from),newString=this.copy(),i=_i=from;to>=from?to>_i:_i>to;i=to>=from?++_i:--_i)c=newString.characters[i],c.addTags.apply(c,tags);return newString},String.prototype.hasTags=function(){var c,found,strict,tags,_i,_j,_len,_ref;for(tags=2<=arguments.length?__slice.call(arguments,0,_i=arguments.length-1):(_i=0,[]),strict=arguments[_i++],"undefined"!=typeof strict&&"boolean"!=typeof strict&&(tags.push(strict),strict=!1),found=!1,_ref=this.characters,_j=0,_len=_ref.length;_len>_j;_j++)if(c=_ref[_j],c.hasTags.apply(c,tags))found=!0;else if(strict)return!1;return found},String.prototype.html=function(){var c,closingTag,closingTags,head,html,openHeads,openTag,openTags,tag,_i,_j,_k,_l,_len,_len1,_len2,_len3,_len4,_m,_ref,_ref1,_ref2,_ref3;for(html="",openTags=[],openHeads=[],closingTags=[],_ref=this.characters,_i=0,_len=_ref.length;_len>_i;_i++){for(c=_ref[_i],closingTags=[],_ref1=openTags.slice().reverse(),_j=0,_len1=_ref1.length;_len1>_j;_j++)if(openTag=_ref1[_j],closingTags.push(openTag),!c.hasTags(openTag)){for(_k=0,_len2=closingTags.length;_len2>_k;_k++)closingTag=closingTags[_k],html+=closingTag.tail(),openTags.pop(),openHeads.pop();closingTags=[]}for(_ref2=c._tags,_l=0,_len3=_ref2.length;_len3>_l;_l++)tag=_ref2[_l],-1===openHeads.indexOf(tag.head())&&(tag.selfClosing()||(head=tag.head(),html+=head,openTags.push(tag),openHeads.push(head)));c._tags.length>0&&c._tags[0].selfClosing()&&(html+=c._tags[0].head()),html+=c.c()}for(_ref3=openTags.reverse(),_m=0,_len4=_ref3.length;_len4>_m;_m++)tag=_ref3[_m],html+=tag.tail();return html},String.prototype.indexOf=function(substring,from){var c,found,i,_i,_len,_ref;if(null==from&&(from=0),0>from&&(from=0),"string"==typeof substring)return this.text().indexOf(substring,from);for(;from<=this.length()-substring.length();){for(found=!0,_ref=substring.characters,i=_i=0,_len=_ref.length;_len>_i;i=++_i)if(c=_ref[i],!c.eq(this.characters[i+from])){found=!1;break}if(found)return from;from++}return-1},String.prototype.insert=function(index,substring,inheritFormat){var c,head,indexChar,inheritedTags,middle,newString,tail,_i,_j,_k,_len,_len1,_len2,_ref,_ref1,_ref2;if(null==inheritFormat&&(inheritFormat=!0),head=this.slice(0,index),tail=this.slice(index),0>index&&(index=this.length()+index),middle=substring,"string"==typeof substring&&(middle=new HTMLString.String(substring,this._preserveWhitespace)),inheritFormat&&index>0)for(indexChar=this.charAt(index-1),inheritedTags=indexChar.tags(),indexChar.isTag()&&inheritedTags.shift(),"string"!=typeof substring&&(middle=middle.copy()),_ref=middle.characters,_i=0,_len=_ref.length;_len>_i;_i++)c=_ref[_i],c.addTags.apply(c,inheritedTags);for(newString=head,_ref1=middle.characters,_j=0,_len1=_ref1.length;_len1>_j;_j++)c=_ref1[_j],newString.characters.push(c);for(_ref2=tail.characters,_k=0,_len2=_ref2.length;_len2>_k;_k++)c=_ref2[_k],newString.characters.push(c);return newString},String.prototype.lastIndexOf=function(substring,from){var c,characters,found,i,skip,_i,_j,_len,_len1;if(null==from&&(from=0),0>from&&(from=0),characters=this.characters.slice(from).reverse(),from=0,"string"==typeof substring){if(!this.contains(substring))return-1;for(substring=substring.split("").reverse();from<=characters.length-substring.length;){for(found=!0,skip=0,i=_i=0,_len=substring.length;_len>_i;i=++_i)if(c=substring[i],characters[i+from].isTag()&&(skip+=1),c!==characters[skip+i+from].c()){found=!1;break}if(found)return from;from++}return-1}for(substring=substring.characters.slice().reverse();from<=characters.length-substring.length;){for(found=!0,i=_j=0,_len1=substring.length;_len1>_j;i=++_j)if(c=substring[i],!c.eq(characters[i+from])){found=!1;break}if(found)return from;from++}return-1},String.prototype.optimize=function(){var c,closingTag,closingTags,head,lastC,len,openHeads,openTag,openTags,runLength,runLengthSort,runLengths,run_length,t,tag,_i,_j,_k,_l,_len,_len1,_len2,_len3,_len4,_len5,_len6,_m,_n,_o,_ref,_ref1,_ref2,_ref3,_ref4,_ref5,_results;for(openTags=[],openHeads=[],lastC=null,_ref=this.characters.slice().reverse(),_i=0,_len=_ref.length;_len>_i;_i++){for(c=_ref[_i],c._runLengthMap={},c._runLengthMapSize=0,closingTags=[],_ref1=openTags.slice().reverse(),_j=0,_len1=_ref1.length;_len1>_j;_j++)if(openTag=_ref1[_j],closingTags.push(openTag),!c.hasTags(openTag)){for(_k=0,_len2=closingTags.length;_len2>_k;_k++)closingTag=closingTags[_k],openTags.pop(),openHeads.pop();closingTags=[]}for(_ref2=c._tags,_l=0,_len3=_ref2.length;_len3>_l;_l++)tag=_ref2[_l],-1===openHeads.indexOf(tag.head())&&(tag.selfClosing()||(openTags.push(tag),openHeads.push(tag.head())));for(_m=0,_len4=openTags.length;_len4>_m;_m++)tag=openTags[_m],head=tag.head(),lastC?(c._runLengthMap[head]||(c._runLengthMap[head]=[tag,0]),run_length=0,lastC._runLengthMap[head]&&(run_length=lastC._runLengthMap[head][1]),c._runLengthMap[head][1]=run_length+1):c._runLengthMap[head]=[tag,1];lastC=c}for(runLengthSort=function(a,b){return b[1]-a[1]},_ref3=this.characters,_results=[],_n=0,_len5=_ref3.length;_len5>_n;_n++)if(c=_ref3[_n],len=c._tags.length,!(len>0&&c._tags[0].selfClosing()&&3>len||2>len)){runLengths=[],_ref4=c._runLengthMap;for(tag in _ref4)runLength=_ref4[tag],runLengths.push(runLength);for(runLengths.sort(runLengthSort),_ref5=c._tags.slice(),_o=0,_len6=_ref5.length;_len6>_o;_o++)tag=_ref5[_o],tag.selfClosing()||c.removeTags(tag);_results.push(c.addTags.apply(c,function(){var _len7,_p,_results1;for(_results1=[],_p=0,_len7=runLengths.length;_len7>_p;_p++)t=runLengths[_p],_results1.push(t[0]);return _results1}()))}return _results},String.prototype.slice=function(from,to){var c,newString;return newString=new HTMLString.String("",this._preserveWhitespace),newString.characters=function(){var _i,_len,_ref,_results;for(_ref=this.characters.slice(from,to),_results=[],_i=0,_len=_ref.length;_len>_i;_i++)c=_ref[_i],_results.push(c.copy());return _results}.call(this),newString},String.prototype.split=function(separator,limit){var count,end,i,index,indexes,lastIndex,start,substrings,_i,_ref;for(null==separator&&(separator=""),null==limit&&(limit=0),lastIndex=0,count=0,indexes=[0];;){if(limit>0&&count>limit)break;if(index=this.indexOf(separator,lastIndex),-1===index)break;indexes.push(index),lastIndex=index+1}for(indexes.push(this.length()),substrings=[],i=_i=0,_ref=indexes.length-2;_ref>=0?_ref>=_i:_i>=_ref;i=_ref>=0?++_i:--_i)start=indexes[i],i>0&&(start+=1),end=indexes[i+1],substrings.push(this.slice(start,end));return substrings},String.prototype.startsWith=function(substring){var c,i,_i,_len,_ref;if("string"==typeof substring)return this.text().slice(0,substring.length)===substring;for(_ref=substring.characters,i=_i=0,_len=_ref.length;_len>_i;i=++_i)if(c=_ref[i],!c.eq(this.characters[i]))return!1;return!0},String.prototype.substr=function(from,length){return 0>=length?new HTMLString.String("",this._preserveWhitespace):(0>from&&(from=this.length()+from),void 0===length&&(length=this.length()-from),this.slice(from,from+length))},String.prototype.substring=function(from,to){return void 0===to&&(to=this.length()),this.slice(from,to)},String.prototype.text=function(){var c,text,_i,_len,_ref;for(text="",_ref=this.characters,_i=0,_len=_ref.length;_len>_i;_i++)c=_ref[_i],c.isTag()?c.isTag("br")&&(text+="\n"):text+=(" "!==c.c(),c.c());return this.constructor.decode(text)},String.prototype.toLowerCase=function(){var c,newString,_i,_len,_ref;for(newString=this.copy(),_ref=newString.characters,_i=0,_len=_ref.length;_len>_i;_i++)c=_ref[_i],1===c._c.length&&(c._c=c._c.toLowerCase());return newString},String.prototype.toUpperCase=function(){var c,newString,_i,_len,_ref;for(newString=this.copy(),_ref=newString.characters,_i=0,_len=_ref.length;_len>_i;_i++)c=_ref[_i],1===c._c.length&&(c._c=c._c.toUpperCase());return newString},String.prototype.trim=function(){var c,from,newString,to,_i,_j,_len,_len1,_ref,_ref1;for(_ref=this.characters,from=_i=0,_len=_ref.length;_len>_i&&(c=_ref[from],c.isWhitespace());from=++_i);for(_ref1=this.characters.slice().reverse(),to=_j=0,_len1=_ref1.length;_len1>_j&&(c=_ref1[to],c.isWhitespace());to=++_j);return to=this.length()-to-1,newString=new HTMLString.String("",this._preserveWhitespace),newString.characters=function(){var _k,_len2,_ref2,_results;for(_ref2=this.characters.slice(from,+to+1||9e9),_results=[],_k=0,_len2=_ref2.length;_len2>_k;_k++)c=_ref2[_k],_results.push(c.copy());return _results}.call(this),newString},String.prototype.trimLeft=function(){var c,from,newString,to,_i,_len,_ref;for(to=this.length()-1,_ref=this.characters,from=_i=0,_len=_ref.length;_len>_i&&(c=_ref[from],c.isWhitespace());from=++_i);return newString=new HTMLString.String("",this._preserveWhitespace),newString.characters=function(){var _j,_len1,_ref1,_results;for(_ref1=this.characters.slice(from,+to+1||9e9),_results=[],_j=0,_len1=_ref1.length;_len1>_j;_j++)c=_ref1[_j],_results.push(c.copy());return _results}.call(this),newString},String.prototype.trimRight=function(){var c,from,newString,to,_i,_len,_ref;for(from=0,_ref=this.characters.slice().reverse(),to=_i=0,_len=_ref.length;_len>_i&&(c=_ref[to],c.isWhitespace());to=++_i);return to=this.length()-to-1,newString=new HTMLString.String("",this._preserveWhitespace),newString.characters=function(){var _j,_len1,_ref1,_results;for(_ref1=this.characters.slice(from,+to+1||9e9),_results=[],_j=0,_len1=_ref1.length;_len1>_j;_j++)c=_ref1[_j],_results.push(c.copy());return _results}.call(this),newString},String.prototype.unformat=function(){var c,from,i,newString,tags,to,_i;for(from=arguments[0],to=arguments[1],tags=3<=arguments.length?__slice.call(arguments,2):[],0>to&&(to=this.length()+to+1),0>from&&(from=this.length()+from),newString=this.copy(),i=_i=from;to>=from?to>_i:_i>to;i=to>=from?++_i:--_i)c=newString.characters[i],c.removeTags.apply(c,tags);return newString},String.prototype.copy=function(){var c,stringCopy;return stringCopy=new HTMLString.String("",this._preserveWhitespace),stringCopy.characters=function(){var _i,_len,_ref,_results;for(_ref=this.characters,_results=[],_i=0,_len=_ref.length;_len>_i;_i++)c=_ref[_i],_results.push(c.copy());return _results}.call(this),stringCopy},String.decode=function(string){var textarea;return textarea=document.createElement("textarea"),textarea.innerHTML=string,textarea.textContent},String.encode=function(string){var textarea;return textarea=document.createElement("textarea"),textarea.textContent=string,textarea.innerHTML},String.join=function(separator,strings){var joined,s,_i,_len;for(joined=strings.shift(),_i=0,_len=strings.length;_len>_i;_i++)s=strings[_i],joined=joined.concat(separator,s);return joined},String}(),ALPHA_CHARS="AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz-_$".split(""),ALPHA_NUMERIC_CHARS=ALPHA_CHARS.concat("1234567890".split("")),ATTR_NAME_CHARS=ALPHA_NUMERIC_CHARS.concat([":"]),ENTITY_CHARS=ALPHA_NUMERIC_CHARS.concat(["#"]),TAG_NAME_CHARS=ALPHA_NUMERIC_CHARS.concat([":"]),CHAR_OR_ENTITY_OR_TAG=1,ENTITY=2,OPENNING_OR_CLOSING_TAG=3,OPENING_TAG=4,CLOSING_TAG=5,TAG_NAME_OPENING=6,TAG_NAME_CLOSING=7,TAG_OPENING_SELF_CLOSING=8,TAG_NAME_MUST_CLOSE=9,ATTR_OR_TAG_END=10,ATTR_NAME=11,ATTR_NAME_FIND_VALUE=12,ATTR_DELIM=13,ATTR_VALUE_SINGLE_DELIM=14,ATTR_VALUE_DOUBLE_DELIM=15,ATTR_VALUE_NO_DELIM=16,ATTR_ENTITY_NO_DELIM=17,ATTR_ENTITY_SINGLE_DELIM=18,ATTR_ENTITY_DOUBLE_DELIM=19,_Parser=function(){function _Parser(){this.fsm=new FSM.Machine(this),this.fsm.setInitialState(CHAR_OR_ENTITY_OR_TAG),this.fsm.addTransitionAny(CHAR_OR_ENTITY_OR_TAG,null,function(c){return this._pushChar(c)}),this.fsm.addTransition("<",CHAR_OR_ENTITY_OR_TAG,OPENNING_OR_CLOSING_TAG),this.fsm.addTransition("&",CHAR_OR_ENTITY_OR_TAG,ENTITY),this.fsm.addTransition("END",CHAR_OR_ENTITY_OR_TAG,null),this.fsm.addTransitions(ENTITY_CHARS,ENTITY,null,function(c){return this.entity+=c}),this.fsm.addTransition(";",ENTITY,CHAR_OR_ENTITY_OR_TAG,function(){return this._pushChar("&"+this.entity+";"),this.entity=""}),this.fsm.addTransitionAny(ENTITY,CHAR_OR_ENTITY_OR_TAG,function(c){var _i,_len,_ref;for(this._pushChar("&"),_ref=this.entity.split(""),_i=0,_len=_ref.length;_len>_i;_i++)c=_ref[_i],this._pushChar(c);return this.entity="",this._back()}),this.fsm.addTransition("END",ENTITY,null,function(){var c,_i,_len,_ref;for(this._pushChar("&"),_ref=this.entity.split(""),_i=0,_len=_ref.length;_len>_i;_i++)c=_ref[_i],this._pushChar(c);return this.entity=""}),this.fsm.addTransitions([" ","\n"],OPENNING_OR_CLOSING_TAG),this.fsm.addTransitions(ALPHA_CHARS,OPENNING_OR_CLOSING_TAG,OPENING_TAG,function(){return this._back()}),this.fsm.addTransition("/",OPENNING_OR_CLOSING_TAG,CLOSING_TAG),this.fsm.addTransitions([" ","\n"],OPENING_TAG),this.fsm.addTransitions(ALPHA_CHARS,OPENING_TAG,TAG_NAME_OPENING,function(){return this._back()}),this.fsm.addTransitions([" ","\n"],CLOSING_TAG),this.fsm.addTransitions(ALPHA_CHARS,CLOSING_TAG,TAG_NAME_CLOSING,function(){return this._back()}),this.fsm.addTransitions(TAG_NAME_CHARS,TAG_NAME_OPENING,null,function(c){return this.tagName+=c}),this.fsm.addTransitions([" ","\n"],TAG_NAME_OPENING,ATTR_OR_TAG_END),this.fsm.addTransition("/",TAG_NAME_OPENING,TAG_OPENING_SELF_CLOSING,function(){return this.selfClosing=!0}),this.fsm.addTransition(">",TAG_NAME_OPENING,CHAR_OR_ENTITY_OR_TAG,function(){return this._pushTag()}),this.fsm.addTransitions([" ","\n"],TAG_OPENING_SELF_CLOSING),this.fsm.addTransition(">",TAG_OPENING_SELF_CLOSING,CHAR_OR_ENTITY_OR_TAG,function(){return this._pushTag()}),this.fsm.addTransitions([" ","\n"],ATTR_OR_TAG_END),this.fsm.addTransition("/",ATTR_OR_TAG_END,TAG_OPENING_SELF_CLOSING,function(){return this.selfClosing=!0}),this.fsm.addTransition(">",ATTR_OR_TAG_END,CHAR_OR_ENTITY_OR_TAG,function(){return this._pushTag()}),this.fsm.addTransitions(ALPHA_CHARS,ATTR_OR_TAG_END,ATTR_NAME,function(){return this._back()}),this.fsm.addTransitions(TAG_NAME_CHARS,TAG_NAME_CLOSING,null,function(c){return this.tagName+=c}),this.fsm.addTransitions([" ","\n"],TAG_NAME_CLOSING,TAG_NAME_MUST_CLOSE),this.fsm.addTransition(">",TAG_NAME_CLOSING,CHAR_OR_ENTITY_OR_TAG,function(){return this._popTag()}),this.fsm.addTransitions([" ","\n"],TAG_NAME_MUST_CLOSE),this.fsm.addTransition(">",TAG_NAME_MUST_CLOSE,CHAR_OR_ENTITY_OR_TAG,function(){return this._popTag()}),this.fsm.addTransitions(ATTR_NAME_CHARS,ATTR_NAME,null,function(c){return this.attributeName+=c}),this.fsm.addTransitions([" ","\n"],ATTR_NAME,ATTR_NAME_FIND_VALUE),this.fsm.addTransition("=",ATTR_NAME,ATTR_DELIM),this.fsm.addTransitions([" ","\n"],ATTR_NAME_FIND_VALUE),this.fsm.addTransition("=",ATTR_NAME_FIND_VALUE,ATTR_DELIM),this.fsm.addTransitions(">",ATTR_NAME,ATTR_OR_TAG_END,function(){return this._pushAttribute(),this._back()}),this.fsm.addTransitionAny(ATTR_NAME_FIND_VALUE,ATTR_OR_TAG_END,function(){return this._pushAttribute(),this._back()}),this.fsm.addTransitions([" ","\n"],ATTR_DELIM),this.fsm.addTransition("'",ATTR_DELIM,ATTR_VALUE_SINGLE_DELIM),this.fsm.addTransition('"',ATTR_DELIM,ATTR_VALUE_DOUBLE_DELIM),this.fsm.addTransitions(ALPHA_NUMERIC_CHARS.concat(["&"],ATTR_DELIM,ATTR_VALUE_NO_DELIM,function(){return this._back()})),this.fsm.addTransition(" ",ATTR_VALUE_NO_DELIM,ATTR_OR_TAG_END,function(){return this._pushAttribute()}),this.fsm.addTransitions(["/",">"],ATTR_VALUE_NO_DELIM,ATTR_OR_TAG_END,function(){return this._back(),this._pushAttribute()}),this.fsm.addTransition("&",ATTR_VALUE_NO_DELIM,ATTR_ENTITY_NO_DELIM),this.fsm.addTransitionAny(ATTR_VALUE_NO_DELIM,null,function(c){return this.attributeValue+=c}),this.fsm.addTransition("'",ATTR_VALUE_SINGLE_DELIM,ATTR_OR_TAG_END,function(){return this._pushAttribute()}),this.fsm.addTransition("&",ATTR_VALUE_SINGLE_DELIM,ATTR_ENTITY_SINGLE_DELIM),this.fsm.addTransitionAny(ATTR_VALUE_SINGLE_DELIM,null,function(c){return this.attributeValue+=c}),this.fsm.addTransition('"',ATTR_VALUE_DOUBLE_DELIM,ATTR_OR_TAG_END,function(){return this._pushAttribute()}),this.fsm.addTransition("&",ATTR_VALUE_DOUBLE_DELIM,ATTR_ENTITY_DOUBLE_DELIM),this.fsm.addTransitionAny(ATTR_VALUE_DOUBLE_DELIM,null,function(c){return this.attributeValue+=c}),this.fsm.addTransitions(ENTITY_CHARS,ATTR_ENTITY_NO_DELIM,null,function(c){return this.entity+=c}),this.fsm.addTransitions(ENTITY_CHARS,ATTR_ENTITY_SINGLE_DELIM,null,function(c){return this.entity+=c}),this.fsm.addTransitions(ENTITY_CHARS,ATTR_ENTITY_DOUBLE_DELIM,null,function(c){return this.entity+=c}),this.fsm.addTransition(";",ATTR_ENTITY_NO_DELIM,ATTR_VALUE_NO_DELIM,function(){return this.attributeValue+="&"+this.entity+";",this.entity=""}),this.fsm.addTransition(";",ATTR_ENTITY_SINGLE_DELIM,ATTR_VALUE_SINGLE_DELIM,function(){return this.attributeValue+="&"+this.entity+";",this.entity=""}),this.fsm.addTransition(";",ATTR_ENTITY_DOUBLE_DELIM,ATTR_VALUE_DOUBLE_DELIM,function(){return this.attributeValue+="&"+this.entity+";",this.entity=""}),this.fsm.addTransitionAny(ATTR_ENTITY_NO_DELIM,ATTR_VALUE_NO_DELIM,function(){return this.attributeValue+="&"+this.entity,this.entity="",this._back()}),this.fsm.addTransitionAny(ATTR_ENTITY_SINGLE_DELIM,ATTR_VALUE_SINGLE_DELIM,function(){return this.attributeValue+="&"+this.entity,this.entity="",this._back()}),this.fsm.addTransitionAny(ATTR_ENTITY_DOUBLE_DELIM,ATTR_VALUE_DOUBLE_DELIM,function(){return this.attributeValue+="&"+this.entity,this.entity="",this._back()})}return _Parser.prototype._back=function(){return this.head--},_Parser.prototype._pushAttribute=function(){return this.attributes[this.attributeName]=this.attributeValue,this.attributeName="",this.attributeValue=""},_Parser.prototype._pushChar=function(c){var character,lastCharacter;return character=new HTMLString.Character(c,this.tags),this._preserveWhitespace?void this.string.characters.push(character):!this.string.length()||character.isTag()||character.isEntity()||!character.isWhitespace()||(lastCharacter=this.string.characters[this.string.length()-1],!lastCharacter.isWhitespace()||lastCharacter.isTag()||lastCharacter.isEntity())?this.string.characters.push(character):void 0},_Parser.prototype._pushTag=function(){var tag,_ref;return tag=new HTMLString.Tag(this.tagName,this.attributes),this.tags.push(tag),tag.selfClosing()&&(this._pushChar(""),this.tags.pop(),!this.selfClosed&&(_ref=this.tagName,__indexOf.call(HTMLString.Tag.SELF_CLOSING,_ref)>=0)&&this.fsm.reset()),this.tagName="",this.selfClosed=!1,this.attributes={}},_Parser.prototype._popTag=function(){for(var character,tag;;)if(tag=this.tags.pop(),this.string.length()&&(character=this.string.characters[this.string.length()-1],character.isTag()||character.isEntity()||!character.isWhitespace()||character.removeTags(tag)),tag.name()===this.tagName.toLowerCase())break;return this.tagName=""},_Parser.prototype.parse=function(html,preserveWhitespace){var character,error;for(this._preserveWhitespace=preserveWhitespace,this.reset(),html=this.preprocess(html),this.fsm.parser=this;this.head> "+error)}this.head++}return this.fsm.process("END"),this.string},_Parser.prototype.preprocess=function(html){return html=html.replace(/\r\n/g,"\n").replace(/\r/g,"\n"),html=html.replace(//g,""),this._preserveWhitespace||(html=html.replace(/\s+/g," ")),html},_Parser.prototype.reset=function(){return this.fsm.reset(),this.head=0,this.string=new HTMLString.String,this.entity="",this.tags=[],this.tagName="",this.selfClosing=!1,this.attributes={},this.attributeName="",this.attributeValue=""},_Parser}(),HTMLString.Tag=function(){function Tag(name,attributes){var k,v;this._name=name.toLowerCase(),this._selfClosing=HTMLString.Tag.SELF_CLOSING[this._name]===!0,this._head=null,this._attributes={};for(k in attributes)v=attributes[k],this._attributes[k]=v}return Tag.SELF_CLOSING={area:!0,base:!0,br:!0,hr:!0,img:!0,input:!0,"link meta":!0,wbr:!0},Tag.prototype.head=function(){var components,k,v,_ref;if(!this._head){components=[],_ref=this._attributes;for(k in _ref)v=_ref[k],components.push(v?""+k+'="'+v+'"':""+k);components.sort(),components.unshift(this._name),this._head="<"+components.join(" ")+">"}return this._head},Tag.prototype.name=function(){return this._name},Tag.prototype.selfClosing=function(){return this._selfClosing},Tag.prototype.tail=function(){return this._selfClosing?"":""},Tag.prototype.attr=function(name,value){return void 0===value?this._attributes[name]:(this._attributes[name]=value,this._head=null)},Tag.prototype.removeAttr=function(name){return void 0!==this._attributes[name]?(delete this._attributes[name],this._head=null):void 0},Tag.prototype.copy=function(){return new HTMLString.Tag(this._name,this._attributes)},Tag}(),HTMLString.Character=function(){function Character(c,tags){this._c=c,c.length>1&&(this._c=c.toLowerCase()),this._tags=[],this.addTags.apply(this,tags)}return Character.prototype.c=function(){return this._c},Character.prototype.isEntity=function(){return this._c.length>1},Character.prototype.isTag=function(tagName){return 0!==this._tags.length&&this._tags[0].selfClosing()?tagName&&this._tags[0].name()!==tagName?!1:!0:!1},Character.prototype.isWhitespace=function(){var _ref;return" "===(_ref=this._c)||"\n"===_ref||" "===_ref||this.isTag("br")},Character.prototype.tags=function(){var t;return function(){var _i,_len,_ref,_results;for(_ref=this._tags,_results=[],_i=0,_len=_ref.length;_len>_i;_i++)t=_ref[_i],_results.push(t.copy());return _results}.call(this)},Character.prototype.addTags=function(){var tag,tags,_i,_len,_results;for(tags=1<=arguments.length?__slice.call(arguments,0):[],_results=[],_i=0,_len=tags.length;_len>_i;_i++)tag=tags[_i],Array.isArray(tag)||(tag.selfClosing()?this.isTag()||this._tags.unshift(tag.copy()):_results.push(this._tags.push(tag.copy())));return _results},Character.prototype.eq=function(c){var tag,tags,_i,_j,_len,_len1,_ref,_ref1;if(this.c()!==c.c())return!1;if(this._tags.length!==c._tags.length)return!1;for(tags={},_ref=this._tags,_i=0,_len=_ref.length;_len>_i;_i++)tag=_ref[_i],tags[tag.head()]=!0;for(_ref1=c._tags,_j=0,_len1=_ref1.length;_len1>_j;_j++)if(tag=_ref1[_j],!tags[tag.head()])return!1;return!0},Character.prototype.hasTags=function(){var tag,tagHeads,tagNames,tags,_i,_j,_len,_len1,_ref;for(tags=1<=arguments.length?__slice.call(arguments,0):[],tagNames={},tagHeads={},_ref=this._tags,_i=0,_len=_ref.length;_len>_i;_i++)tag=_ref[_i],tagNames[tag.name()]=!0,tagHeads[tag.head()]=!0;for(_j=0,_len1=tags.length;_len1>_j;_j++)if(tag=tags[_j],"string"==typeof tag){if(void 0===tagNames[tag])return!1}else if(void 0===tagHeads[tag.head()])return!1;return!0},Character.prototype.removeTags=function(){var heads,names,newTags,tag,tags,_i,_len;if(tags=1<=arguments.length?__slice.call(arguments,0):[],0===tags.length)return void(this._tags=[]);for(names={},heads={},_i=0,_len=tags.length;_len>_i;_i++)tag=tags[_i],"string"==typeof tag?names[tag]=tag:heads[tag.head()]=tag;return newTags=[],this._tags=this._tags.filter(function(tag){return heads[tag.head()]||names[tag.name()]?void 0:tag})},Character.prototype.copy=function(){var t;return new HTMLString.Character(this._c,function(){var _i,_len,_ref,_results;for(_ref=this._tags,_results=[],_i=0,_len=_ref.length;_len>_i;_i++)t=_ref[_i],_results.push(t.copy());return _results}.call(this))},Character}()}.call(this); \ No newline at end of file diff --git a/npm-debug.log b/npm-debug.log new file mode 100644 index 0000000..3b48fb4 --- /dev/null +++ b/npm-debug.log @@ -0,0 +1,112 @@ +0 info it worked if it ends with ok +1 verbose cli [ '/usr/local/bin/node', '/usr/local/bin/npm', 'publish' ] +2 info using npm@1.4.28 +3 info using node@v0.10.33 +4 verbose publish [ '.' ] +5 verbose cache add [ '.', null ] +6 verbose cache add name=undefined spec="." args=[".",null] +7 verbose parsed url { protocol: null, +7 verbose parsed url slashes: null, +7 verbose parsed url auth: null, +7 verbose parsed url host: null, +7 verbose parsed url port: null, +7 verbose parsed url hostname: null, +7 verbose parsed url hash: null, +7 verbose parsed url search: null, +7 verbose parsed url query: null, +7 verbose parsed url pathname: '.', +7 verbose parsed url path: '.', +7 verbose parsed url href: '.' } +8 silly lockFile 3a52ce78- . +9 verbose lock . /home/anthony/.npm/3a52ce78-.lock +10 verbose tar pack [ '/home/anthony/.npm/HTMLString/1.0.6/package.tgz', '.' ] +11 verbose tarball /home/anthony/.npm/HTMLString/1.0.6/package.tgz +12 verbose folder . +13 info prepublish HTMLString@1.0.6 +14 silly lockFile 1f1177db-tar tar://. +15 verbose lock tar://. /home/anthony/.npm/1f1177db-tar.lock +16 silly lockFile 423837ce-npm-HTMLString-1-0-6-package-tgz tar:///home/anthony/.npm/HTMLString/1.0.6/package.tgz +17 verbose lock tar:///home/anthony/.npm/HTMLString/1.0.6/package.tgz /home/anthony/.npm/423837ce-npm-HTMLString-1-0-6-package-tgz.lock +18 silly lockFile 1f1177db-tar tar://. +19 silly lockFile 1f1177db-tar tar://. +20 silly lockFile 423837ce-npm-HTMLString-1-0-6-package-tgz tar:///home/anthony/.npm/HTMLString/1.0.6/package.tgz +21 silly lockFile 423837ce-npm-HTMLString-1-0-6-package-tgz tar:///home/anthony/.npm/HTMLString/1.0.6/package.tgz +22 silly lockFile b99c44c8-ony-npm-HTMLString-1-0-6-package /home/anthony/.npm/HTMLString/1.0.6/package +23 verbose lock /home/anthony/.npm/HTMLString/1.0.6/package /home/anthony/.npm/b99c44c8-ony-npm-HTMLString-1-0-6-package.lock +24 silly lockFile b99c44c8-ony-npm-HTMLString-1-0-6-package /home/anthony/.npm/HTMLString/1.0.6/package +25 silly lockFile b99c44c8-ony-npm-HTMLString-1-0-6-package /home/anthony/.npm/HTMLString/1.0.6/package +26 silly lockFile 3a52ce78- . +27 silly lockFile 3a52ce78- . +28 silly publish { name: 'HTMLString', +28 silly publish description: 'An HTML parser written in JavaScript that\'s probably not what you\'re looking for.', +28 silly publish version: '1.0.6', +28 silly publish keywords: [ 'html', 'parser' ], +28 silly publish author: +28 silly publish { name: 'Anthony Blackshaw', +28 silly publish email: 'ant@getme.co.uk', +28 silly publish url: 'https://github.com/anthonyjb' }, +28 silly publish main: 'build/html-string.js', +28 silly publish devDependencies: +28 silly publish { grunt: '~0.4.5', +28 silly publish 'grunt-contrib-clean': '^0.6.0', +28 silly publish 'grunt-contrib-coffee': '^0.11.1', +28 silly publish 'grunt-contrib-concat': '^0.5.0', +28 silly publish 'grunt-contrib-jasmine': '^0.9.2', +28 silly publish 'grunt-contrib-uglify': '^0.5.1', +28 silly publish 'grunt-contrib-watch': '^0.6.1' }, +28 silly publish scripts: { test: 'grunt jasmine --verbose' }, +28 silly publish repository: +28 silly publish { type: 'git', +28 silly publish url: 'https://github.com/GetmeUK/HTMLString.git' }, +28 silly publish license: 'MIT', +28 silly publish readme: '# HTMLString\n\n[![Build Status](https://travis-ci.org/GetmeUK/HTMLString.svg?branch=master)](https://travis-ci.org/GetmeUK/HTMLString)\n\n> An HTML parser written in JavaScript that\'s probably not what you\'re looking for.\n\n## Install\n\n**Using bower**\n\n```\nbower install --save HTMLString\n```\n\n**Using npm**\n\n```\nnpm install --save HTMLString\n```\n\n## Building\nTo build the library you\'ll need to use Grunt. First install the required node modules ([grunt-cli](http://gruntjs.com/getting-started) must be installed):\n```\ngit clone https://github.com/GetmeUK/HTMLString.git\ncd HTMLString\nnpm install\n```\n\nThen run `grunt build` to build the project.\n\n## Testing\nTo test the library you\'ll need to use Jasmine. First install Jasmine:\n```\ngit clone https://github.com/pivotal/jasmine.git\nmkdir HTMLString/jasmine\nmv jasmine/dist/jasmine-standalone-2.0.3.zip HTMLString/jasmine\ncd HTMLString/jasmine\nunzip jasmine-standalone-2.0.3.zip\n```\n\nThen open `HTMLString/SpecRunner.html` in a browser to run the tests.\n\nAlternatively you can use `grunt jasmine` to run the tests from the command line.\n\n## Documentation\nFull documentation is available at http://getcontenttools.com/api/html-string\n\n## Browser support\n- Chrome\n- Firefox\n- IE9+\n', +28 silly publish readmeFilename: 'README.md', +28 silly publish gitHead: '8ca1028b8f00c0ae20e25887e57999c7eb6fb03b', +28 silly publish bugs: { url: 'https://github.com/GetmeUK/HTMLString/issues' }, +28 silly publish homepage: 'https://github.com/GetmeUK/HTMLString', +28 silly publish _id: 'HTMLString@1.0.6', +28 silly publish _shasum: '0dbd2b90ad9ff5634d21f366ecbf9c4954477425', +28 silly publish _from: '.' } +29 verbose request where is /HTMLString +30 verbose request registry https://registry.npmjs.org/ +31 verbose request id 9915c72d0522b64e +32 verbose url raw /HTMLString +33 verbose url resolving [ 'https://registry.npmjs.org/', './HTMLString' ] +34 verbose url resolved https://registry.npmjs.org/HTMLString +35 verbose request where is https://registry.npmjs.org/HTMLString +36 info trying registry request attempt 1 at 21:57:55 +37 http PUT https://registry.npmjs.org/HTMLString +38 http 401 https://registry.npmjs.org/HTMLString +39 verbose headers { 'content-type': 'application/json', +39 verbose headers 'cache-control': 'max-age=300', +39 verbose headers 'content-length': '42', +39 verbose headers 'accept-ranges': 'bytes', +39 verbose headers date: 'Sun, 23 Oct 2016 20:57:49 GMT', +39 verbose headers via: '1.1 varnish', +39 verbose headers connection: 'keep-alive', +39 verbose headers 'x-served-by': 'cache-lcy1130-LCY', +39 verbose headers 'x-cache': 'MISS', +39 verbose headers 'x-cache-hits': '0', +39 verbose headers 'x-timer': 'S1477256268.696056,VS0,VE1166', +39 verbose headers vary: 'Accept-Encoding' } +40 error publish Failed PUT 401 +41 error Error: Could not authenticate getmeuk : HTMLString +41 error at RegClient. (/usr/local/lib/node_modules/npm/node_modules/npm-registry-client/lib/request.js:308:14) +41 error at Request._callback (/usr/local/lib/node_modules/npm/node_modules/npm-registry-client/lib/request.js:246:65) +41 error at Request.self.callback (/usr/local/lib/node_modules/npm/node_modules/request/request.js:236:22) +41 error at Request.emit (events.js:98:17) +41 error at Request. (/usr/local/lib/node_modules/npm/node_modules/request/request.js:1142:14) +41 error at Request.emit (events.js:117:20) +41 error at IncomingMessage. (/usr/local/lib/node_modules/npm/node_modules/request/request.js:1096:12) +41 error at IncomingMessage.emit (events.js:117:20) +41 error at _stream_readable.js:943:16 +41 error at process._tickCallback (node.js:419:13) +42 error If you need help, you may report this *entire* log, +42 error including the npm and node versions, at: +42 error +43 error System Linux 3.13.0-100-generic +44 error command "/usr/local/bin/node" "/usr/local/bin/npm" "publish" +45 error cwd /home/anthony/Desktop/Work/Public/CoffeeScript/github/HTMLString +46 error node -v v0.10.33 +47 error npm -v 1.4.28 +48 verbose exit [ 1, true ] diff --git a/package.json b/package.json index dfb02e4..5536d10 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "HTMLString", "description": "An HTML parser written in JavaScript that's probably not what you're looking for.", - "version": "1.0.6", + "version": "1.0.7", "keywords": [ "html", "parser" diff --git a/spec/html-string-spec.js b/spec/html-string-spec.js index 783b473..95f6eb8 100644 --- a/spec/html-string-spec.js +++ b/spec/html-string-spec.js @@ -8,7 +8,8 @@ Turing: 'Machines take me by
surprise with great frequency.
', Wozniak: 'all the best people in life seem to like LINUX.', WozniakNamespaced: 'all the best people in life seem to like LINUX.', - WozniakWhitespace: 'all the best people in life seem to like LINUX.' + WozniakWhitespace: 'all the best people in life seem to like LINUX.', + AmbiguousAmpersand: '& &amp &foo && && &end' }; describe('HTMLString.String()', function() { @@ -22,12 +23,17 @@ string = new HTMLString.String(quotes.WozniakWhitespace, true); return expect(string.text()).toBe(quotes.WozniakWhitespace); }); - return it('should parse and render a string (HTML)', function() { + it('should parse and render a string (HTML)', function() { var string; string = new HTMLString.String(quotes.Turing); expect(string.html()).toBe(quotes.Turing); string = new HTMLString.String(quotes.WozniakNamespaced); - expect(string.html()).toBe(quotes.WozniakNamespaced); + return expect(string.html()).toBe(quotes.WozniakNamespaced); + }); + return it('should parse and render a string (HTML with ambiguous ampersands)', function() { + var string; + string = new HTMLString.String(quotes.AmbiguousAmpersand); + expect(string.html()).toBe(quotes.AmbiguousAmpersand); return console.log(string.html()); }); }); diff --git a/src/spec/html-string-spec.coffee b/src/spec/html-string-spec.coffee index 14c8ff7..6f5b7b6 100644 --- a/src/spec/html-string-spec.coffee +++ b/src/spec/html-string-spec.coffee @@ -21,6 +21,9 @@ all the best people in life seem to like LINUX. WozniakWhitespace: ''' all the best people in life seem to like LINUX. ''' + AmbiguousAmpersand: ''' +& &amp &foo && && &end + ''' } describe 'HTMLString.String()', () -> @@ -41,6 +44,10 @@ describe 'HTMLString.String()', () -> string = new HTMLString.String(quotes.WozniakNamespaced) expect(string.html()).toBe quotes.WozniakNamespaced + it 'should parse and render a string (HTML with ambiguous ampersands)', () -> + string = new HTMLString.String(quotes.AmbiguousAmpersand) + expect(string.html()).toBe quotes.AmbiguousAmpersand + console.log string.html() diff --git a/src/strings.coffee b/src/strings.coffee index ee33630..f5eb783 100644 --- a/src/strings.coffee +++ b/src/strings.coffee @@ -659,6 +659,7 @@ class _Parser @fsm.addTransition '<', CHAR_OR_ENTITY_OR_TAG, OPENNING_OR_CLOSING_TAG @fsm.addTransition '&', CHAR_OR_ENTITY_OR_TAG, ENTITY + @fsm.addTransition 'END', CHAR_OR_ENTITY_OR_TAG, null # Entity @fsm.addTransitions ENTITY_CHARS, ENTITY, null, (c) -> @@ -668,6 +669,19 @@ class _Parser @_pushChar("&#{ @entity };") @entity = '' + @fsm.addTransitionAny ENTITY, CHAR_OR_ENTITY_OR_TAG, (c) -> + @_pushChar('&') + for c in @entity.split('') + @_pushChar(c) + @entity = '' + @_back() + + @fsm.addTransition 'END', ENTITY, null, () -> + @_pushChar('&') + for c in @entity.split('') + @_pushChar(c) + @entity = '' + # Opening or closing Tag @fsm.addTransitions [' ', '\n'], OPENNING_OR_CLOSING_TAG @fsm.addTransitions ALPHA_CHARS, OPENNING_OR_CLOSING_TAG, OPENING_TAG, () -> @@ -779,7 +793,7 @@ class _Parser @fsm.addTransitions ENTITY_CHARS, ATTR_ENTITY_NO_DELIM, null, (c) -> @entity += c - @fsm.addTransitions ENTITY_CHARS, ATTR_ENTITY_SINGLE_DELIM, (c) -> + @fsm.addTransitions ENTITY_CHARS, ATTR_ENTITY_SINGLE_DELIM, null, (c) -> @entity += c @fsm.addTransitions ENTITY_CHARS, ATTR_ENTITY_DOUBLE_DELIM, null, (c) -> @@ -797,6 +811,21 @@ class _Parser @attributeValue += "&#{ @entity };" @entity = '' + @fsm.addTransitionAny ATTR_ENTITY_NO_DELIM, ATTR_VALUE_NO_DELIM, (c) -> + @attributeValue += '&' + @entity + @entity = '' + @_back() + + @fsm.addTransitionAny ATTR_ENTITY_SINGLE_DELIM, ATTR_VALUE_SINGLE_DELIM, (c) -> + @attributeValue += '&' + @entity + @entity = '' + @_back() + + @fsm.addTransitionAny ATTR_ENTITY_DOUBLE_DELIM, ATTR_VALUE_DOUBLE_DELIM, (c) -> + @attributeValue += '&' + @entity + @entity = '' + @_back() + # Parsing methods _back: () -> @@ -896,6 +925,8 @@ class _Parser @head++ + @fsm.process('END') + return @string preprocess: (html) ->