Skip to content
This repository has been archived by the owner on Sep 6, 2021. It is now read-only.

Rewrite some logic in getTagInfo and getTagAttributes apis for CodeMirror updates in xml mode. #7545

Merged
merged 4 commits into from
Apr 17, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/language/CSSUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -1202,7 +1202,7 @@ define(function (require, exports, module) {
}

// Stop once we've reached a <style ...> tag
if (ctx.token.string === "<style") {
if (ctx.token.string === "style" && ctx.token.type === "tag") {
// Remove everything up to end-of-tag from selector
var eotIndex = selector.indexOf(">");
if (eotIndex !== -1) {
Expand Down
75 changes: 52 additions & 23 deletions src/language/HTMLUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,15 @@ define(function (require, exports, module) {
var CodeMirror = require("thirdparty/CodeMirror2/lib/codemirror"),
TokenUtils = require("utils/TokenUtils");

//constants
// Constants
var TAG_NAME = "tagName",
CLOSING_TAG = "closingTag",
ATTR_NAME = "attr.name",
ATTR_VALUE = "attr.value";

// Regular expression for token types with "tag" prefixed
var tagPrefixedRegExp = /^tag/;

/**
* @private
* Sometimes as attr values are getting typed, if the quotes aren't balanced yet
Expand Down Expand Up @@ -114,7 +117,13 @@ define(function (require, exports, module) {
var mode = ctx.editor.getMode(),
innerModeData = CodeMirror.innerMode(mode, ctx.token.state);

return innerModeData.state.tagName;
if (ctx.token.type === "tag bracket") {
return innerModeData.state.tagName;
}

// If the ctx is inside the tag name of an end tag, innerModeData.state.tagName is
// undefined. So return token string as the tag name.
return innerModeData.state.tagName || ctx.token.string;
}

/**
Expand All @@ -129,8 +138,8 @@ define(function (require, exports, module) {
forwardCtx = $.extend({}, backwardCtx);

if (editor.getModeForSelection() === "html") {
if (backwardCtx.token && backwardCtx.token.type !== "tag") {
while (TokenUtils.movePrevToken(backwardCtx) && backwardCtx.token.type !== "tag") {
if (backwardCtx.token && !tagPrefixedRegExp.test(backwardCtx.token.type)) {
while (TokenUtils.movePrevToken(backwardCtx) && !tagPrefixedRegExp.test(backwardCtx.token.type)) {
if (backwardCtx.token.type === "error" && backwardCtx.token.string.indexOf("<") === 0) {
break;
}
Expand All @@ -139,7 +148,7 @@ define(function (require, exports, module) {
}
}

while (TokenUtils.moveNextToken(forwardCtx) && forwardCtx.token.type !== "tag") {
while (TokenUtils.moveNextToken(forwardCtx) && !tagPrefixedRegExp.test(forwardCtx.token.type)) {
if (forwardCtx.token.type === "attribute") {
// If the current tag is not closed, codemirror may return the next opening
// tag as an attribute. Stop the search loop in that case.
Expand Down Expand Up @@ -310,12 +319,12 @@ define(function (require, exports, module) {
tagInfo,
tokenType;

// check if this is inside a style block.
// Check if this is inside a style block.
if (editor.getModeForSelection() !== "html") {
return createTagInfo();
}

//check and see where we are in the tag
// Check and see where we are in the tag
if (ctx.token.string.length > 0 && !/\S/.test(ctx.token.string)) {

// token at (i.e. before) pos is whitespace, so test token at next pos
Expand All @@ -331,8 +340,9 @@ define(function (require, exports, module) {
// pos has whitespace before it and non-whitespace after it, so use token after
ctx.token = testToken;

if (ctx.token.type === "tag" ||
(ctx.token.type && ctx.token.type.indexOf("error") !== -1)) {
// Check whether the token type is one of the types prefixed with "tag"
// (e.g. "tag", "tag error", "tag brackets")
if (tagPrefixedRegExp.test(ctx.token.type)) {
// Check to see if the cursor is just before a "<" but not in any tag.
if (ctx.token.string.charAt(0) === "<") {
return createTagInfo();
Expand Down Expand Up @@ -365,17 +375,17 @@ define(function (require, exports, module) {

if (ctx.token.type === "comment") {
return createTagInfo();
} else if (ctx.token.type !== "tag" && ctx.token.string !== "=") {
} else if (!tagPrefixedRegExp.test(ctx.token.type) && ctx.token.string !== "=") {
// If it wasn't the tag name, assume it was an attr value
// Also we don't handle the "=" here.
tagInfo = _getTagInfoStartingFromAttrValue(ctx);

// Check to see if this is the closing of a tag (either the start or end)
// or a comment tag.
if (ctx.token.type === "comment" ||
(ctx.token.type === "tag" &&
(tagPrefixedRegExp.test(ctx.token.type) &&
(ctx.token.string === ">" || ctx.token.string === "/>" ||
(ctx.token.string.charAt(0) === "<" && ctx.token.string.charAt(1) === "/")))) {
ctx.token.string === "</"))) {
return createTagInfo();
}

Expand All @@ -398,28 +408,47 @@ define(function (require, exports, module) {
}
}

if (ctx.token.type === "tag" ||
(ctx.token.type && ctx.token.type.indexOf("error") !== -1)) {
// Check if the user just typed a white space after "<" that made an existing tag invalid.
if (ctx.token.string.match(/^<\s+/) && offset !== 1) {
return createTagInfo();
if (tagPrefixedRegExp.test(ctx.token.type)) {
if (ctx.token.type !== "tag bracket") {
// Check if the user just typed a white space after "<" that made an existing tag invalid.
if (TokenUtils.movePrevToken(ctx) && !/\S/.test(ctx.token.string)) {
return createTagInfo();
}

// Check to see if this is a closing tag
if (ctx.token.type === "tag bracket" && ctx.token.string === "</") {
tokenType = CLOSING_TAG;
}

// Restore the original ctx by moving back to next context since we call
// movePrevToken above to detect "<" or "</".
TokenUtils.moveNextToken(ctx);
}

// Check to see if this is the closing of a start tag or a self closing tag
if (ctx.token.string === ">" || ctx.token.string === "/>") {
return createTagInfo();
}

// Check to see if this is a closing tag
if (ctx.token.string.charAt(0) === "<" && ctx.token.string.charAt(1) === "/") {
return createTagInfo(CLOSING_TAG, offset - 2, ctx.token.string.slice(2));
}

// Make sure the cursor is not after an equal sign or a quote before we report the context as a tag.
if (ctx.token.string !== "=" && ctx.token.string.match(/^["']/) === null) {
if (!tokenType) {
tokenType = TAG_NAME;
offset--; //need to take off 1 for the leading "<"
if (ctx.token.type === "tag bracket") {
// Check to see if this is a closing tag
if (ctx.token.string === "</") {
tokenType = CLOSING_TAG;
offset -= 2;
} else {
offset = 0;
}
// If the cursor is right after the "<" or "</", then
// move context to next one so that _extractTagName
// call below can get the tag name if there is one.
if (offset === 0) {
TokenUtils.moveNextToken(ctx);
}
}
}

// We're actually in the tag, just return that as we have no relevant
Expand Down
2 changes: 1 addition & 1 deletion src/thirdparty/CodeMirror2