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

Commit ea16d5c

Browse files
committed
Merge pull request #7545 from adobe/rlim/update-codemirror
Rewrite some logic in getTagInfo and getTagAttributes apis for CodeMirror updates in xml mode.
2 parents e337d24 + ecdca2c commit ea16d5c

3 files changed

Lines changed: 54 additions & 25 deletions

File tree

src/language/CSSUtils.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1202,7 +1202,7 @@ define(function (require, exports, module) {
12021202
}
12031203

12041204
// Stop once we've reached a <style ...> tag
1205-
if (ctx.token.string === "<style") {
1205+
if (ctx.token.string === "style" && ctx.token.type === "tag") {
12061206
// Remove everything up to end-of-tag from selector
12071207
var eotIndex = selector.indexOf(">");
12081208
if (eotIndex !== -1) {

src/language/HTMLUtils.js

Lines changed: 52 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,15 @@ define(function (require, exports, module) {
3131
var CodeMirror = require("thirdparty/CodeMirror2/lib/codemirror"),
3232
TokenUtils = require("utils/TokenUtils");
3333

34-
//constants
34+
// Constants
3535
var TAG_NAME = "tagName",
3636
CLOSING_TAG = "closingTag",
3737
ATTR_NAME = "attr.name",
3838
ATTR_VALUE = "attr.value";
3939

40+
// Regular expression for token types with "tag" prefixed
41+
var tagPrefixedRegExp = /^tag/;
42+
4043
/**
4144
* @private
4245
* Sometimes as attr values are getting typed, if the quotes aren't balanced yet
@@ -114,7 +117,13 @@ define(function (require, exports, module) {
114117
var mode = ctx.editor.getMode(),
115118
innerModeData = CodeMirror.innerMode(mode, ctx.token.state);
116119

117-
return innerModeData.state.tagName;
120+
if (ctx.token.type === "tag bracket") {
121+
return innerModeData.state.tagName;
122+
}
123+
124+
// If the ctx is inside the tag name of an end tag, innerModeData.state.tagName is
125+
// undefined. So return token string as the tag name.
126+
return innerModeData.state.tagName || ctx.token.string;
118127
}
119128

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

131140
if (editor.getModeForSelection() === "html") {
132-
if (backwardCtx.token && backwardCtx.token.type !== "tag") {
133-
while (TokenUtils.movePrevToken(backwardCtx) && backwardCtx.token.type !== "tag") {
141+
if (backwardCtx.token && !tagPrefixedRegExp.test(backwardCtx.token.type)) {
142+
while (TokenUtils.movePrevToken(backwardCtx) && !tagPrefixedRegExp.test(backwardCtx.token.type)) {
134143
if (backwardCtx.token.type === "error" && backwardCtx.token.string.indexOf("<") === 0) {
135144
break;
136145
}
@@ -139,7 +148,7 @@ define(function (require, exports, module) {
139148
}
140149
}
141150

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

313-
// check if this is inside a style block.
322+
// Check if this is inside a style block.
314323
if (editor.getModeForSelection() !== "html") {
315324
return createTagInfo();
316325
}
317326

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

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

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

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

373383
// Check to see if this is the closing of a tag (either the start or end)
374384
// or a comment tag.
375385
if (ctx.token.type === "comment" ||
376-
(ctx.token.type === "tag" &&
386+
(tagPrefixedRegExp.test(ctx.token.type) &&
377387
(ctx.token.string === ">" || ctx.token.string === "/>" ||
378-
(ctx.token.string.charAt(0) === "<" && ctx.token.string.charAt(1) === "/")))) {
388+
ctx.token.string === "</"))) {
379389
return createTagInfo();
380390
}
381391

@@ -398,28 +408,47 @@ define(function (require, exports, module) {
398408
}
399409
}
400410

401-
if (ctx.token.type === "tag" ||
402-
(ctx.token.type && ctx.token.type.indexOf("error") !== -1)) {
403-
// Check if the user just typed a white space after "<" that made an existing tag invalid.
404-
if (ctx.token.string.match(/^<\s+/) && offset !== 1) {
405-
return createTagInfo();
411+
if (tagPrefixedRegExp.test(ctx.token.type)) {
412+
if (ctx.token.type !== "tag bracket") {
413+
// Check if the user just typed a white space after "<" that made an existing tag invalid.
414+
if (TokenUtils.movePrevToken(ctx) && !/\S/.test(ctx.token.string)) {
415+
return createTagInfo();
416+
}
417+
418+
// Check to see if this is a closing tag
419+
if (ctx.token.type === "tag bracket" && ctx.token.string === "</") {
420+
tokenType = CLOSING_TAG;
421+
}
422+
423+
// Restore the original ctx by moving back to next context since we call
424+
// movePrevToken above to detect "<" or "</".
425+
TokenUtils.moveNextToken(ctx);
406426
}
407427

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

413-
// Check to see if this is a closing tag
414-
if (ctx.token.string.charAt(0) === "<" && ctx.token.string.charAt(1) === "/") {
415-
return createTagInfo(CLOSING_TAG, offset - 2, ctx.token.string.slice(2));
416-
}
417-
418433
// Make sure the cursor is not after an equal sign or a quote before we report the context as a tag.
419434
if (ctx.token.string !== "=" && ctx.token.string.match(/^["']/) === null) {
420435
if (!tokenType) {
421436
tokenType = TAG_NAME;
422-
offset--; //need to take off 1 for the leading "<"
437+
if (ctx.token.type === "tag bracket") {
438+
// Check to see if this is a closing tag
439+
if (ctx.token.string === "</") {
440+
tokenType = CLOSING_TAG;
441+
offset -= 2;
442+
} else {
443+
offset = 0;
444+
}
445+
// If the cursor is right after the "<" or "</", then
446+
// move context to next one so that _extractTagName
447+
// call below can get the tag name if there is one.
448+
if (offset === 0) {
449+
TokenUtils.moveNextToken(ctx);
450+
}
451+
}
423452
}
424453

425454
// We're actually in the tag, just return that as we have no relevant

src/thirdparty/CodeMirror2

0 commit comments

Comments
 (0)