TextUtils.js 5.8 KB

12345678910111213141516171819202122232425262728
  1. const Utils={isStopChar:function(char){return(char>' '&&char<'0')||(char>'9'&&char<'A')||(char>'Z'&&char<'_')||(char>'_'&&char<'a')||(char>'z'&&char<='~');},isWordChar:function(char){return!TextUtils.TextUtils.isStopChar(char)&&!TextUtils.TextUtils.isSpaceChar(char);},isSpaceChar:function(char){return TextUtils.TextUtils._SpaceCharRegex.test(char);},isWord:function(word){for(let i=0;i<word.length;++i){if(!TextUtils.TextUtils.isWordChar(word.charAt(i))){return false;}}
  2. return true;},isOpeningBraceChar:function(char){return char==='('||char==='{';},isClosingBraceChar:function(char){return char===')'||char==='}';},isBraceChar:function(char){return TextUtils.TextUtils.isOpeningBraceChar(char)||TextUtils.TextUtils.isClosingBraceChar(char);},textToWords:function(text,isWordChar,wordCallback){let startWord=-1;for(let i=0;i<text.length;++i){if(!isWordChar(text.charAt(i))){if(startWord!==-1){wordCallback(text.substring(startWord,i));}
  3. startWord=-1;}else if(startWord===-1){startWord=i;}}
  4. if(startWord!==-1){wordCallback(text.substring(startWord));}},lineIndent:function(line){let indentation=0;while(indentation<line.length&&TextUtils.TextUtils.isSpaceChar(line.charAt(indentation))){++indentation;}
  5. return line.substr(0,indentation);},isUpperCase:function(text){return text===text.toUpperCase();},isLowerCase:function(text){return text===text.toLowerCase();},splitStringByRegexes(text,regexes){const matches=[];const globalRegexes=[];for(let i=0;i<regexes.length;i++){const regex=regexes[i];if(!regex.global){globalRegexes.push(new RegExp(regex.source,regex.flags?regex.flags+'g':'g'));}else{globalRegexes.push(regex);}}
  6. doSplit(text,0,0);return matches;function doSplit(text,regexIndex,startIndex){if(regexIndex>=globalRegexes.length){matches.push({value:text,position:startIndex,regexIndex:-1,captureGroups:[]});return;}
  7. const regex=globalRegexes[regexIndex];let currentIndex=0;let result;regex.lastIndex=0;while((result=regex.exec(text))!==null){const stringBeforeMatch=text.substring(currentIndex,result.index);if(stringBeforeMatch){doSplit(stringBeforeMatch,regexIndex+1,startIndex+currentIndex);}
  8. const match=result[0];matches.push({value:match,position:startIndex+result.index,regexIndex:regexIndex,captureGroups:result.slice(1)});currentIndex=result.index+match.length;}
  9. const stringAfterMatches=text.substring(currentIndex);if(stringAfterMatches){doSplit(stringAfterMatches,regexIndex+1,startIndex+currentIndex);}}}};export default Utils;export class FilterParser{constructor(keys){this._keys=keys;}
  10. static cloneFilter(filter){return{key:filter.key,text:filter.text,regex:filter.regex,negative:filter.negative};}
  11. parse(query){const splitResult=TextUtils.TextUtils.splitStringByRegexes(query,[TextUtils.TextUtils._keyValueFilterRegex,TextUtils.TextUtils._regexFilterRegex,TextUtils.TextUtils._textFilterRegex]);const filters=[];for(let i=0;i<splitResult.length;i++){const regexIndex=splitResult[i].regexIndex;if(regexIndex===-1){continue;}
  12. const result=splitResult[i].captureGroups;if(regexIndex===0){if(this._keys.indexOf((result[1]))!==-1){filters.push({key:result[1],text:result[2],negative:!!result[0]});}else{filters.push({text:result[1]+':'+result[2],negative:!!result[0]});}}else if(regexIndex===1){try{filters.push({regex:new RegExp(result[1],'i'),negative:!!result[0]});}catch(e){filters.push({text:'/'+result[1]+'/',negative:!!result[0]});}}else if(regexIndex===2){filters.push({text:result[1],negative:!!result[0]});}}
  13. return filters;}}
  14. Utils._keyValueFilterRegex=/(?:^|\s)(\-)?([\w\-]+):([^\s]+)/;Utils._regexFilterRegex=/(?:^|\s)(\-)?\/([^\s]+)\//;Utils._textFilterRegex=/(?:^|\s)(\-)?([^\s]+)/;Utils._SpaceCharRegex=/\s/;Utils.Indent={TwoSpaces:' ',FourSpaces:' ',EightSpaces:' ',TabCharacter:'\t'};export class BalancedJSONTokenizer{constructor(callback,findMultiple){this._callback=callback;this._index=0;this._balance=0;this._buffer='';this._findMultiple=findMultiple||false;this._closingDoubleQuoteRegex=/[^\\](?:\\\\)*"/g;}
  15. write(chunk){this._buffer+=chunk;const lastIndex=this._buffer.length;const buffer=this._buffer;let index;for(index=this._index;index<lastIndex;++index){const character=buffer[index];if(character==='"'){this._closingDoubleQuoteRegex.lastIndex=index;if(!this._closingDoubleQuoteRegex.test(buffer)){break;}
  16. index=this._closingDoubleQuoteRegex.lastIndex-1;}else if(character==='{'){++this._balance;}else if(character==='}'){--this._balance;if(this._balance<0){this._reportBalanced();return false;}
  17. if(!this._balance){this._lastBalancedIndex=index+1;if(!this._findMultiple){break;}}}else if(character===']'&&!this._balance){this._reportBalanced();return false;}}
  18. this._index=index;this._reportBalanced();return true;}
  19. _reportBalanced(){if(!this._lastBalancedIndex){return;}
  20. this._callback(this._buffer.slice(0,this._lastBalancedIndex));this._buffer=this._buffer.slice(this._lastBalancedIndex);this._index-=this._lastBalancedIndex;this._lastBalancedIndex=0;}
  21. remainder(){return this._buffer;}}
  22. export class TokenizerFactory{createTokenizer(mimeType){}}
  23. export function isMinified(text){const kMaxNonMinifiedLength=500;let linesToCheck=10;let lastPosition=0;do{let eolIndex=text.indexOf('\n',lastPosition);if(eolIndex<0){eolIndex=text.length;}
  24. if(eolIndex-lastPosition>kMaxNonMinifiedLength&&text.substr(lastPosition,3)!=='//#'){return true;}
  25. lastPosition=eolIndex+1;}while(--linesToCheck>=0&&lastPosition<text.length);linesToCheck=10;lastPosition=text.length;do{let eolIndex=text.lastIndexOf('\n',lastPosition);if(eolIndex<0){eolIndex=0;}
  26. if(lastPosition-eolIndex>kMaxNonMinifiedLength&&text.substr(lastPosition,3)!=='//#'){return true;}
  27. lastPosition=eolIndex-1;}while(--linesToCheck>=0&&lastPosition>0);return false;}
  28. self.TextUtils=self.TextUtils||{};TextUtils=TextUtils||{};TextUtils.TextUtils=Utils;TextUtils.FilterParser=FilterParser;TextUtils.BalancedJSONTokenizer=BalancedJSONTokenizer;TextUtils.TokenizerFactory=TokenizerFactory;TextUtils.isMinified=isMinified;TextUtils.FilterParser.ParsedFilter;