forked from phcode-dev/staging.phcode.dev
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathHTMLUtils.js
More file actions
1 lines (1 loc) · 8.22 KB
/
HTMLUtils.js
File metadata and controls
1 lines (1 loc) · 8.22 KB
1
define(function(require,exports,module){var CodeMirror=require("thirdparty/CodeMirror/lib/codemirror"),TokenUtils=require("utils/TokenUtils");const TAG_NAME="tagName",CLOSING_TAG="closingTag",ATTR_NAME="attr.name",ATTR_VALUE="attr.value";var tagPrefixedRegExp=/^tag/;function _extractAttrVal(ctx){var attrValue=ctx.token.string,startChar=attrValue.charAt(0),endChar=attrValue.charAt(attrValue.length-1),offset=TokenUtils.offsetInToken(ctx),foundEqualSign=!1;if(attrValue.length>1&&("'"===startChar||'"'===startChar)&&endChar===startChar&&!(foundEqualSign=null!==attrValue.match(/\=\s*['"]$/)))return{val:attrValue=attrValue.substring(1,attrValue.length-1),offset:offset=offset-1>attrValue.length?attrValue.length:offset-1,quoteChar:startChar,hasEndQuote:!0};if(foundEqualSign){var spaceIndex=attrValue.indexOf(" "),bracketIndex=attrValue.indexOf(">"),upToIndex=-1!==spaceIndex&&spaceIndex<bracketIndex?spaceIndex:bracketIndex;attrValue=attrValue.substring(0,upToIndex>offset?upToIndex:offset)}else offset>0&&("'"===startChar||'"'===startChar)&&(attrValue=attrValue.substring(0,offset));return"'"===(startChar=attrValue.charAt(0))||'"'===startChar?(attrValue=attrValue.substring(1),offset--):(startChar="",">"===endChar&&(attrValue="",offset=0)),{val:attrValue,offset:offset,quoteChar:startChar,hasEndQuote:!1}}function _extractTagName(ctx){var mode=ctx.editor.getMode(),innerModeData=CodeMirror.innerMode(mode,ctx.token.state);return"tag bracket"===ctx.token.type?innerModeData.state.tagName:innerModeData.state.tagName||ctx.token.string}function getTagAttributes(editor,pos){var attrs=[],backwardCtx=TokenUtils.getInitialContext(editor._codeMirror,pos),forwardCtx=$.extend({},backwardCtx);if("html"===editor.getModeForSelection()&&backwardCtx.token&&!tagPrefixedRegExp.test(backwardCtx.token.type)){for(;TokenUtils.movePrevToken(backwardCtx)&&!tagPrefixedRegExp.test(backwardCtx.token.type)&&("error"!==backwardCtx.token.type||0!==backwardCtx.token.string.indexOf("<"));)"attribute"===backwardCtx.token.type&&attrs.push(backwardCtx.token.string);for(;TokenUtils.moveNextToken(forwardCtx)&&!tagPrefixedRegExp.test(forwardCtx.token.type);)if("attribute"===forwardCtx.token.type){if(0===forwardCtx.token.string.indexOf("<"))break;attrs.push(forwardCtx.token.string)}else if("error"===forwardCtx.token.type){if(0===forwardCtx.token.string.indexOf("<")||0===forwardCtx.token.string.indexOf(">"))break;/\S/.test(forwardCtx.token.string)&&-1===forwardCtx.token.string.indexOf('"')&&-1===forwardCtx.token.string.indexOf("'")&&-1===forwardCtx.token.string.indexOf("=")&&attrs.push(forwardCtx.token.string)}}return attrs}function createTagInfo(tokenType,offset,tagName,attrName,attrValue,valueAssigned,quoteChar,hasEndQuote){return{tagName:tagName||"",attr:{name:attrName||"",value:attrValue||"",valueAssigned:valueAssigned||!1,quoteChar:quoteChar||"",hasEndQuote:hasEndQuote||!1},position:{tokenType:tokenType||"",offset:offset||0}}}function _getTagInfoStartingFromAttrValue(ctx){var attrInfo=_extractAttrVal(ctx),attrVal=attrInfo.val,offset=attrInfo.offset,quoteChar=attrInfo.quoteChar,hasEndQuote=attrInfo.hasEndQuote,strLength=ctx.token.string.length;if(("string"===ctx.token.type||"error"===ctx.token.type)&&ctx.pos.ch===ctx.token.end&&strLength>1){var firstChar=ctx.token.string[0],lastChar;if(firstChar===ctx.token.string[strLength-1]&&("'"===firstChar||'"'===firstChar))return createTagInfo()}for(;TokenUtils.moveSkippingWhitespace(TokenUtils.movePrevToken,ctx)&&"string"===ctx.token.type;);if(TokenUtils.moveSkippingWhitespace(TokenUtils.moveNextToken,ctx),!TokenUtils.moveSkippingWhitespace(TokenUtils.movePrevToken,ctx)||"="!==ctx.token.string)return createTagInfo();if(!TokenUtils.moveSkippingWhitespace(TokenUtils.movePrevToken,ctx)||"attribute"!==ctx.token.type)return createTagInfo();var attrName=ctx.token.string,tagName=_extractTagName(ctx);return createTagInfo(ATTR_VALUE,offset,tagName,attrName,attrVal,!0,quoteChar,hasEndQuote)}function _getTagInfoStartingFromAttrName(ctx,isPriorAttr){if(!1===isPriorAttr&&"attribute"!==ctx.token.type)return createTagInfo();var tagName=_extractTagName(ctx),attrName=ctx.token.string,offset=TokenUtils.offsetInToken(ctx);if(!TokenUtils.moveSkippingWhitespace(TokenUtils.moveNextToken,ctx)||"="!==ctx.token.string)return isPriorAttr&&(!ctx.token.type||ctx.token.type&&"attribute"!==ctx.token.type&&-1===ctx.token.type.indexOf("error")&&-1!==ctx.token.string.indexOf("<"))?createTagInfo():createTagInfo(ATTR_NAME,offset,tagName,attrName);if(!TokenUtils.moveSkippingWhitespace(TokenUtils.moveNextToken,ctx))return createTagInfo(ATTR_NAME,offset,tagName,attrName);var attrInfo=_extractAttrVal(ctx),attrVal=attrInfo.val,quoteChar=attrInfo.quoteChar,hasEndQuote=attrInfo.hasEndQuote;return createTagInfo(ATTR_NAME,offset,tagName,attrName,attrVal,!0,quoteChar,hasEndQuote)}function getTagInfo(editor,constPos,isHtmlMode){var pos=$.extend({},constPos),ctx=TokenUtils.getInitialContext(editor._codeMirror,pos),offset=TokenUtils.offsetInToken(ctx),tagInfo,tokenType;if(!isHtmlMode&&"html"!==editor.getModeForSelection())return createTagInfo();if(ctx.token.string.length>0&&!/\S/.test(ctx.token.string)){var testPos={ch:ctx.pos.ch+1,line:ctx.pos.line},testToken=editor._codeMirror.getTokenAt(testPos,!0);if(testToken.string.length>0&&/\S/.test(testToken.string)&&">"!==testToken.string.charAt(0))if(ctx.token=testToken,tagPrefixedRegExp.test(ctx.token.type)){if("<"===ctx.token.string.charAt(0))return createTagInfo()}else{if("attribute"===ctx.token.type)return _getTagInfoStartingFromAttrName(ctx,!1);if("="===ctx.token.string)return createTagInfo()}else{if(!TokenUtils.movePrevToken(ctx))return createTagInfo();if("comment"===ctx.token.type)return createTagInfo();if(!tagPrefixedRegExp.test(ctx.token.type)&&"="!==ctx.token.string)return tagInfo=_getTagInfoStartingFromAttrValue(ctx),"comment"===ctx.token.type||tagPrefixedRegExp.test(ctx.token.type)&&(">"===ctx.token.string||"/>"===ctx.token.string||"</"===ctx.token.string)?createTagInfo():(tagInfo.tagName||(tagInfo=_getTagInfoStartingFromAttrName(ctx,!0)),tagInfo.tagName?createTagInfo(ATTR_NAME,0,tagInfo.tagName):createTagInfo());tokenType=ATTR_NAME,offset=0}}if(tagPrefixedRegExp.test(ctx.token.type)){if("tag bracket"!==ctx.token.type){if(TokenUtils.movePrevToken(ctx)&&!/\S/.test(ctx.token.string))return createTagInfo();"tag bracket"===ctx.token.type&&"</"===ctx.token.string&&(tokenType=CLOSING_TAG),TokenUtils.moveNextToken(ctx)}if(">"===ctx.token.string||"/>"===ctx.token.string)return createTagInfo();if("="!==ctx.token.string&&null===ctx.token.string.match(/^["']/))return tokenType||(tokenType=TAG_NAME,"tag bracket"===ctx.token.type&&("</"===ctx.token.string?(tokenType=CLOSING_TAG,offset-=2):offset=0,0===offset&&TokenUtils.moveNextToken(ctx))),createTagInfo(tokenType,offset,_extractTagName(ctx))}if("="===ctx.token.string){if(!TokenUtils.moveSkippingWhitespace(TokenUtils.movePrevToken,ctx)||"attribute"!==ctx.token.type)return createTagInfo();tokenType=ATTR_VALUE,offset=0}return"attribute"===ctx.token.type?(tagInfo=_getTagInfoStartingFromAttrName(ctx,!1)).attr.quoteChar?offset=constPos.ch-ctx.pos.ch:tokenType===ATTR_VALUE&&constPos.ch+1<ctx.pos.ch&&(tagInfo.attr.value=""):tagInfo=_getTagInfoStartingFromAttrValue(ctx),tokenType&&tagInfo.tagName&&(tagInfo.position.tokenType=tokenType,tagInfo.position.offset=offset),tagInfo}function findBlocks(editor,modeName){for(var ctx=TokenUtils.getInitialContext(editor._codeMirror,{line:0,ch:0}),blocks=[],currentBlock=null,inBlock=!1,outerMode=editor._codeMirror.getMode(),tokenModeName,previousMode;TokenUtils.moveNextToken(ctx,!1);)tokenModeName=CodeMirror.innerMode(outerMode,ctx.token.state).mode.name,inBlock?(currentBlock.end||(currentBlock.end=currentBlock.start),tokenModeName===previousMode?(currentBlock.text=editor.document.getRange(currentBlock.start,currentBlock.end),inBlock=!1):currentBlock.end={line:ctx.pos.line,ch:ctx.pos.ch}):tokenModeName===modeName?(currentBlock={start:{line:ctx.pos.line,ch:ctx.pos.ch}},blocks.push(currentBlock),inBlock=!0):previousMode=tokenModeName;return blocks}function findStyleBlocks(editor){return findBlocks(editor,"css")}exports.TAG_NAME=TAG_NAME,exports.CLOSING_TAG=CLOSING_TAG,exports.ATTR_NAME=ATTR_NAME,exports.ATTR_VALUE=ATTR_VALUE,exports.getTagInfo=getTagInfo,exports.getTagAttributes=getTagAttributes,exports.createTagInfo=createTagInfo,exports.findStyleBlocks=findStyleBlocks,exports.findBlocks=findBlocks});