From d587f366f16a493a6fd23f644512714ee911eb3c Mon Sep 17 00:00:00 2001 From: Chema Date: Fri, 30 Nov 2012 01:54:53 +0100 Subject: [PATCH 1/7] Basic attribute discovery and hinting filter --- src/extensions/default/HTMLCodeHints/main.js | 24 ++++++++--- src/language/HTMLUtils.js | 45 +++++++++++++++++++- 2 files changed, 60 insertions(+), 9 deletions(-) diff --git a/src/extensions/default/HTMLCodeHints/main.js b/src/extensions/default/HTMLCodeHints/main.js index e88c229cb03..82afae0ff90 100644 --- a/src/extensions/default/HTMLCodeHints/main.js +++ b/src/extensions/default/HTMLCodeHints/main.js @@ -172,6 +172,8 @@ define(function (require, exports, module) { endQuote = "", shouldReplace = true; + var tagInfo2 = HTMLUtils.getTagInfo(editor, {ch: 1, line: cursor.line}); + if (tokenType === HTMLUtils.ATTR_NAME) { charCount = tagInfo.attr.name.length; // Append an equal sign and two double quotes if the current attr is not an empty attr @@ -248,7 +250,7 @@ define(function (require, exports, module) { var tagInfo = HTMLUtils.getTagInfo(editor, cursor), query = {queryStr: null}, tokenType = tagInfo.position.tokenType; - + if (tokenType === HTMLUtils.ATTR_NAME || tokenType === HTMLUtils.ATTR_VALUE) { query.tag = tagInfo.tagName; @@ -267,7 +269,7 @@ define(function (require, exports, module) { query.attrName = tagInfo.attr.name; } - // TODO: get existing attributes for the current tag and add them to query.usedAttr + query.usedAttr = HTMLUtils.getTagAttributes(editor, cursor); } return query; @@ -422,9 +424,11 @@ define(function (require, exports, module) { if (query.tag && query.queryStr !== null) { var tagName = query.tag, + self = this, attrName = query.attrName, filter = query.queryStr, unfiltered = [], + filtered = [], sortFunc = null; this.closeOnSelect = true; @@ -452,13 +456,19 @@ define(function (require, exports, module) { } } else if (tags && tags[tagName] && tags[tagName].attributes) { unfiltered = tags[tagName].attributes.concat(this.globalAttributes); - - // TODO: exclude existing attributes from unfiltered array + filtered = $.grep(unfiltered, function (attr, i) { + if ($.inArray(attr, query.usedAttr) >= 0) { + console.log(attr); + console.log(query.usedAttr); + console.log($.inArray(attr, query.usedAttr)); + } + return ($.inArray(attr, query.usedAttr) < 0); + }); } - - if (unfiltered.length) { + + if (filtered.length) { console.assert(!result.length); - result = $.map(unfiltered, function (item) { + result = $.map(filtered, function (item) { if (item.indexOf(filter) === 0) { return item; } diff --git a/src/language/HTMLUtils.js b/src/language/HTMLUtils.js index c5cda6e26a0..d0f9149f12c 100644 --- a/src/language/HTMLUtils.js +++ b/src/language/HTMLUtils.js @@ -112,6 +112,46 @@ define(function (require, exports, module) { return null; } + /** + * + * @param {CodeMirror} editor + * @param {ch:{string}, line:{number}} pos + * @return {Array.} + */ + function getTagAttributes(editor, pos) { + var attrs = [], + backwardCtx = TokenUtils.getInitialContext(editor._codeMirror, pos), + forwardCtx = $.extend({}, backwardCtx); + + if (backwardCtx.token) { + while (backwardCtx.token.className !== "tag") { + console.log(backwardCtx.token.className, backwardCtx.token.string); + if (backwardCtx.token.className === "attribute") { + attrs.push(backwardCtx.token.string); + } + TokenUtils.movePrevToken(backwardCtx); + } + + TokenUtils.moveNextToken(forwardCtx); + while (forwardCtx.token.className !== "tag") { + console.log(forwardCtx.token.className, forwardCtx.token.string); + if (forwardCtx.token.className === "attribute") { + attrs.push(forwardCtx.token.string); + } else if (forwardCtx.token.className === "error") { + if (forwardCtx.token.string.trim() !== "" && + forwardCtx.token.string.indexOf("\"") === -1 && + forwardCtx.token.string.indexOf("'") === -1 && + forwardCtx.token.string.indexOf("=") === -1) { + attrs.push(forwardCtx.token.string); + } + } + TokenUtils.moveNextToken(forwardCtx); + } + } + + return attrs; + } + /** * Creates a tagInfo object and assures all the values are entered or are empty strings * @param {string=} tokenType what is getting edited and should be hinted @@ -251,7 +291,7 @@ define(function (require, exports, module) { offset = TokenUtils.offsetInToken(ctx), tagInfo, tokenType; - + // check if this is inside a style block. if (editor.getModeForSelection() !== "html") { return createTagInfo(); @@ -398,7 +438,7 @@ define(function (require, exports, module) { tagInfo.position.tokenType = tokenType; tagInfo.position.offset = offset; } - + return tagInfo; } @@ -450,6 +490,7 @@ define(function (require, exports, module) { exports.ATTR_VALUE = ATTR_VALUE; exports.getTagInfo = getTagInfo; + exports.getTagAttributes = getTagAttributes; //The createTagInfo is really only for the unit tests so they can make the same structure to //compare results with exports.createTagInfo = createTagInfo; From 7335f946ff491a388cc92ee6fe75812bbbbf19be Mon Sep 17 00:00:00 2001 From: Chema Date: Sat, 1 Dec 2012 14:13:43 +0100 Subject: [PATCH 2/7] Fixes and cleanup --- src/extensions/default/HTMLCodeHints/main.js | 12 +---- src/language/HTMLUtils.js | 49 ++++++++++---------- 2 files changed, 26 insertions(+), 35 deletions(-) diff --git a/src/extensions/default/HTMLCodeHints/main.js b/src/extensions/default/HTMLCodeHints/main.js index 82afae0ff90..693549b7988 100644 --- a/src/extensions/default/HTMLCodeHints/main.js +++ b/src/extensions/default/HTMLCodeHints/main.js @@ -172,8 +172,6 @@ define(function (require, exports, module) { endQuote = "", shouldReplace = true; - var tagInfo2 = HTMLUtils.getTagInfo(editor, {ch: 1, line: cursor.line}); - if (tokenType === HTMLUtils.ATTR_NAME) { charCount = tagInfo.attr.name.length; // Append an equal sign and two double quotes if the current attr is not an empty attr @@ -250,7 +248,7 @@ define(function (require, exports, module) { var tagInfo = HTMLUtils.getTagInfo(editor, cursor), query = {queryStr: null}, tokenType = tagInfo.position.tokenType; - + if (tokenType === HTMLUtils.ATTR_NAME || tokenType === HTMLUtils.ATTR_VALUE) { query.tag = tagInfo.tagName; @@ -424,7 +422,6 @@ define(function (require, exports, module) { if (query.tag && query.queryStr !== null) { var tagName = query.tag, - self = this, attrName = query.attrName, filter = query.queryStr, unfiltered = [], @@ -457,12 +454,7 @@ define(function (require, exports, module) { } else if (tags && tags[tagName] && tags[tagName].attributes) { unfiltered = tags[tagName].attributes.concat(this.globalAttributes); filtered = $.grep(unfiltered, function (attr, i) { - if ($.inArray(attr, query.usedAttr) >= 0) { - console.log(attr); - console.log(query.usedAttr); - console.log($.inArray(attr, query.usedAttr)); - } - return ($.inArray(attr, query.usedAttr) < 0); + return $.inArray(attr, query.usedAttr) < 0; }); } diff --git a/src/language/HTMLUtils.js b/src/language/HTMLUtils.js index d0f9149f12c..e70cd2f55b6 100644 --- a/src/language/HTMLUtils.js +++ b/src/language/HTMLUtils.js @@ -113,39 +113,38 @@ define(function (require, exports, module) { } /** - * - * @param {CodeMirror} editor - * @param {ch:{string}, line:{number}} pos - * @return {Array.} + * Compiles a list of used attributes for a given tag + * @param {CodeMirror} editor An instance of a CodeMirror editor + * @param {ch:{string}, line:{number}} pos A CodeMirror position + * @return {Array.} A list of the used attributes inside the current tag */ function getTagAttributes(editor, pos) { var attrs = [], backwardCtx = TokenUtils.getInitialContext(editor._codeMirror, pos), forwardCtx = $.extend({}, backwardCtx); - if (backwardCtx.token) { - while (backwardCtx.token.className !== "tag") { - console.log(backwardCtx.token.className, backwardCtx.token.string); - if (backwardCtx.token.className === "attribute") { - attrs.push(backwardCtx.token.string); + if (editor.getModeForSelection() === "html") { + if (backwardCtx.token) { + while (TokenUtils.movePrevToken(backwardCtx) && backwardCtx.token.className !== "tag") { + if (backwardCtx.token.className === "attribute") { + attrs.push(backwardCtx.token.string); + } } - TokenUtils.movePrevToken(backwardCtx); - } - - TokenUtils.moveNextToken(forwardCtx); - while (forwardCtx.token.className !== "tag") { - console.log(forwardCtx.token.className, forwardCtx.token.string); - if (forwardCtx.token.className === "attribute") { - attrs.push(forwardCtx.token.string); - } else if (forwardCtx.token.className === "error") { - if (forwardCtx.token.string.trim() !== "" && - forwardCtx.token.string.indexOf("\"") === -1 && - forwardCtx.token.string.indexOf("'") === -1 && - forwardCtx.token.string.indexOf("=") === -1) { + + while (TokenUtils.moveNextToken(forwardCtx) && forwardCtx.token.className !== "tag") { + if (forwardCtx.token.className === "attribute") { attrs.push(forwardCtx.token.string); + } else if (forwardCtx.token.className === "error") { + // If we type the first letter of the next attribute, it comes as an error + // token. We need to double check for possible invalidated attributes. + if (forwardCtx.token.string.trim() !== "" && + forwardCtx.token.string.indexOf("\"") === -1 && + forwardCtx.token.string.indexOf("'") === -1 && + forwardCtx.token.string.indexOf("=") === -1) { + attrs.push(forwardCtx.token.string); + } } } - TokenUtils.moveNextToken(forwardCtx); } } @@ -291,7 +290,7 @@ define(function (require, exports, module) { offset = TokenUtils.offsetInToken(ctx), tagInfo, tokenType; - + // check if this is inside a style block. if (editor.getModeForSelection() !== "html") { return createTagInfo(); @@ -438,7 +437,7 @@ define(function (require, exports, module) { tagInfo.position.tokenType = tokenType; tagInfo.position.offset = offset; } - + return tagInfo; } From 0aae4e68c2b34ed140d110af9fa1e43896a93b4f Mon Sep 17 00:00:00 2001 From: Chema Date: Sat, 1 Dec 2012 14:13:23 +0100 Subject: [PATCH 3/7] Basic tests --- test/spec/CodeHintUtils-test.js | 86 +++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/test/spec/CodeHintUtils-test.js b/test/spec/CodeHintUtils-test.js index 0761717e090..61f5fe8b34a 100644 --- a/test/spec/CodeHintUtils-test.js +++ b/test/spec/CodeHintUtils-test.js @@ -246,6 +246,92 @@ define(function (require, exports, module) { var tag = HTMLUtils.getTagInfo(myEditor, pos); expect(tag).toEqual(HTMLUtils.createTagInfo()); }); + + it("should not find attributes in an empty editor", function () { + var pos = {"ch": 0, "line": 0}; + var attrs = HTMLUtils.getTagAttributes(myEditor, pos); + expect(attrs).toEqual([]); + }); + + it("should not find attributes before the tag is opened", function () { + var pos = {"ch": 0, "line": 0}; + setContentAndUpdatePos(pos, + ['', '', '
'], + '', '

test

', + [ '
', '', '']); + var attrs = HTMLUtils.getTagAttributes(myEditor, pos); + expect(attrs).toEqual([]); + }); + + it("should not find attributes if there isn't a valid tag", function () { + var pos = {"ch": 0, "line": 0}; + setContentAndUpdatePos(pos, + ['', '', '
'], + '<', ' id="pid" class="pclass" lang="plang" align="palign" title="">test

', + [ '
', '', '']); + var attrs = HTMLUtils.getTagAttributes(myEditor, pos); + expect(attrs).toEqual([]); + }); + + it("should not find attributes after the tag is closed", function () { + var pos = {"ch": 0, "line": 0}; + setContentAndUpdatePos(pos, + ['', '', '
'], + '

test

', '', + [ '
', '', '']); + var attrs = HTMLUtils.getTagAttributes(myEditor, pos); + expect(attrs).toEqual([]); + }); + + it("should find all the tag attributes immediately after the tag", function () { + var pos = {"ch": 0, "line": 0}; + setContentAndUpdatePos(pos, + ['', '', '
'], + '

test

', + [ '
', '', '']); + var attrs = HTMLUtils.getTagAttributes(myEditor, pos); + expect(attrs.sort()).toEqual(["id", "class", "lang", "align", "title"].sort()); + }); + + it("should find all the tag attributes before closing the tag", function () { + var pos = {"ch": 0, "line": 0}; + setContentAndUpdatePos(pos, + ['', '', '
'], + '

test

', + [ '
', '', '']); + var attrs = HTMLUtils.getTagAttributes(myEditor, pos); + expect(attrs.sort()).toEqual(["id", "class", "lang", "align", "title"].sort()); + }); + + it("should find all the tag attributes backward and forward", function () { + var pos = {"ch": 0, "line": 0}; + setContentAndUpdatePos(pos, + ['', '', '
'], + '

test

', + [ '
', '', '']); + var attrs = HTMLUtils.getTagAttributes(myEditor, pos); + expect(attrs.sort()).toEqual(["id", "class", "lang", "align", "title"].sort()); + }); + + it("should find valid attributes marked as errors by the tokenizer", function () { + var pos = {"ch": 0, "line": 0}; + setContentAndUpdatePos(pos, + ['', '', '
'], + '

test

', + [ '
', '', '']); + var attrs = HTMLUtils.getTagAttributes(myEditor, pos); + expect(attrs.sort()).toEqual(["id", "class", "lang", "align", "title"].sort()); + }); + + it("should not find attributes in nested tags", function () { + var pos = {"ch": 0, "line": 0}; + setContentAndUpdatePos(pos, + ['', '', '
'], + '

', + [ '
', '', '']); + var attrs = HTMLUtils.getTagAttributes(myEditor, pos); + expect(attrs.sort()).toEqual(["id", "class", "lang", "align", "title"].sort()); + }); }); }); }); From 3306701b700214dadf7d2f5dfcb64325a07b4632 Mon Sep 17 00:00:00 2001 From: Chema Date: Sun, 2 Dec 2012 12:03:15 +0100 Subject: [PATCH 4/7] Fixed empty array for attributes options --- src/extensions/default/HTMLCodeHints/main.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/extensions/default/HTMLCodeHints/main.js b/src/extensions/default/HTMLCodeHints/main.js index 693549b7988..9adcd4288ea 100644 --- a/src/extensions/default/HTMLCodeHints/main.js +++ b/src/extensions/default/HTMLCodeHints/main.js @@ -425,7 +425,7 @@ define(function (require, exports, module) { attrName = query.attrName, filter = query.queryStr, unfiltered = [], - filtered = [], + hints = [], sortFunc = null; this.closeOnSelect = true; @@ -441,26 +441,26 @@ define(function (require, exports, module) { if (attrInfo) { if (attrInfo.type === "boolean") { - unfiltered = ["false", "true"]; + hints = ["false", "true"]; } else if (attrInfo.type === "url") { // Default behavior for url hints is do not close on select. this.closeOnSelect = false; - unfiltered = this._getUrlList(query); + hints = this._getUrlList(query); sortFunc = StringUtils.urlSort; } else if (attrInfo.attribOption) { - unfiltered = attrInfo.attribOption; + hints = attrInfo.attribOption; } } } else if (tags && tags[tagName] && tags[tagName].attributes) { unfiltered = tags[tagName].attributes.concat(this.globalAttributes); - filtered = $.grep(unfiltered, function (attr, i) { + hints = $.grep(unfiltered, function (attr, i) { return $.inArray(attr, query.usedAttr) < 0; }); } - if (filtered.length) { + if (hints.length) { console.assert(!result.length); - result = $.map(filtered, function (item) { + result = $.map(hints, function (item) { if (item.indexOf(filter) === 0) { return item; } From 07be3750dc0261924efd5c5de44017bcb6131f56 Mon Sep 17 00:00:00 2001 From: Chema Date: Wed, 5 Dec 2012 19:59:00 +0100 Subject: [PATCH 5/7] Inverted sage of quotes --- test/spec/CodeHintUtils-test.js | 142 ++++++++++++++++---------------- 1 file changed, 71 insertions(+), 71 deletions(-) diff --git a/test/spec/CodeHintUtils-test.js b/test/spec/CodeHintUtils-test.js index 61f5fe8b34a..8ac68f38fe0 100644 --- a/test/spec/CodeHintUtils-test.js +++ b/test/spec/CodeHintUtils-test.js @@ -82,41 +82,41 @@ define(function (require, exports, module) { it("should find an attribute as a tag is getting typed", function () { var pos = {"ch": 0, "line": 0}; setContentAndUpdatePos(pos, - ['', ''], - '

", ""], + "

', '', '

'], - '

", "", "

"], + "

', '', '

'], - '

", "", '

'], + "

', ''], - '

tricky="', '

', - [ '', '']); + ["", ""], + "

tricky='", "

", + [ "", ""]); var tag = HTMLUtils.getTagInfo(myEditor, pos); expect(tag).toEqual(HTMLUtils.createTagInfo()); @@ -125,52 +125,52 @@ define(function (require, exports, module) { it("should find the attribute value if present", function () { var pos = {"ch": 0, "line": 0}; setContentAndUpdatePos(pos, - ['', ''], - '

', - [ '', '']); + ["", ""], + "

", + [ "", ""]); var tag = HTMLUtils.getTagInfo(myEditor, pos); - expect(tag).toEqual(HTMLUtils.createTagInfo(HTMLUtils.ATTR_VALUE, 3, "p", "class", "foo", true, '"', true)); + expect(tag).toEqual(HTMLUtils.createTagInfo(HTMLUtils.ATTR_VALUE, 3, "p", "class", "foo", true, "'", true)); }); it("should find the full attribute as an existing value is changed", function () { var pos = {"ch": 0, "line": 0}; setContentAndUpdatePos(pos, - ['', ''], - '

', - [ '', '']); + ["", ""], + "

", + [ "", ""]); var tag = HTMLUtils.getTagInfo(myEditor, pos); - expect(tag).toEqual(HTMLUtils.createTagInfo(HTMLUtils.ATTR_VALUE, 3, "p", "class", "foo bar", true, '"', true)); + expect(tag).toEqual(HTMLUtils.createTagInfo(HTMLUtils.ATTR_VALUE, 3, "p", "class", "foo bar", true, "'", true)); }); it("should find the attribute value even when there is space around the =", function () { var pos = {"ch": 0, "line": 0}; setContentAndUpdatePos(pos, - ['', ''], - '

', - [ '', '']); + ["", ""], + "

", + [ "", ""]); var tag = HTMLUtils.getTagInfo(myEditor, pos); - expect(tag).toEqual(HTMLUtils.createTagInfo(HTMLUtils.ATTR_VALUE, 3, "p", "class", "foo", true, '"', true)); + expect(tag).toEqual(HTMLUtils.createTagInfo(HTMLUtils.ATTR_VALUE, 3, "p", "class", "foo", true, "'", true)); }); it("should find the attribute value when the IP is after the =", function () { var pos = {"ch": 0, "line": 0}; setContentAndUpdatePos(pos, - ['', ''], - '

', - [ '', '']); + ["", ""], + "

", + [ "", ""]); var tag = HTMLUtils.getTagInfo(myEditor, pos); - expect(tag).toEqual(HTMLUtils.createTagInfo(HTMLUtils.ATTR_VALUE, -1, "p", "class", "foo", true, '"', true)); + expect(tag).toEqual(HTMLUtils.createTagInfo(HTMLUtils.ATTR_VALUE, -1, "p", "class", "foo", true, "'", true)); }); it("should find the tagname as it's typed", function () { var pos = {"ch": 0, "line": 0}; setContentAndUpdatePos(pos, - ['', ''], - '", ""], + "', ''], - '

test

<'); + ["", ""], + "

test

<"); var tag = HTMLUtils.getTagInfo(myEditor, pos); expect(tag).toEqual(HTMLUtils.createTagInfo(HTMLUtils.TAG_NAME)); @@ -189,8 +189,8 @@ define(function (require, exports, module) { it("should find the tagname of the current tag if two tags are right next to each other", function () { var pos = {"ch": 0, "line": 0}; setContentAndUpdatePos(pos, - ['', ''], - '
", ""], + "
', ''], - '
  • ", ""], + "
  • ', ''], - '
    ", ""], + "
    ', ''], - '
    '); + ["", ""], + "
    "); var tag = HTMLUtils.getTagInfo(myEditor, pos); expect(tag).toEqual(HTMLUtils.createTagInfo()); @@ -229,9 +229,9 @@ define(function (require, exports, module) { it("should not hint anything after a closing tag", function () { var pos = {"ch": 0, "line": 0}; setContentAndUpdatePos(pos, - ['', ''], - '
    ', '
    ', - ['', '']); + ["", ""], + "
    ", "
    ", + ["", ""]); var tag = HTMLUtils.getTagInfo(myEditor, pos); expect(tag).toEqual(HTMLUtils.createTagInfo()); @@ -240,8 +240,8 @@ define(function (require, exports, module) { it("should not hint anything inside a closing tag", function () { var pos = {"ch": 0, "line": 0}; setContentAndUpdatePos(pos, - ['', '', '
    '], - ''); + ["", "", "
    "], + ""); var tag = HTMLUtils.getTagInfo(myEditor, pos); expect(tag).toEqual(HTMLUtils.createTagInfo()); @@ -256,9 +256,9 @@ define(function (require, exports, module) { it("should not find attributes before the tag is opened", function () { var pos = {"ch": 0, "line": 0}; setContentAndUpdatePos(pos, - ['', '', '
    '], - '', '

    test

    ', - [ '
    ', '', '']); + ["", "", "
    "], + "", "

    test

    ", + [ "
    ", "", ""]); var attrs = HTMLUtils.getTagAttributes(myEditor, pos); expect(attrs).toEqual([]); }); @@ -266,9 +266,9 @@ define(function (require, exports, module) { it("should not find attributes if there isn't a valid tag", function () { var pos = {"ch": 0, "line": 0}; setContentAndUpdatePos(pos, - ['', '', '
    '], - '<', ' id="pid" class="pclass" lang="plang" align="palign" title="">test

    ', - [ '
    ', '', '']); + ["", "", "
    "], + "<", " id='pid' class='pclass' lang='plang' align='palign' title='ptitle'>test

    ", + [ "
    ", "", ""]); var attrs = HTMLUtils.getTagAttributes(myEditor, pos); expect(attrs).toEqual([]); }); @@ -276,9 +276,9 @@ define(function (require, exports, module) { it("should not find attributes after the tag is closed", function () { var pos = {"ch": 0, "line": 0}; setContentAndUpdatePos(pos, - ['', '', '
    '], - '

    test

    ', '', - [ '
    ', '', '']); + ["", "", '
    '], + "

    test

    ", "", + [ "
    ", "", ""]); var attrs = HTMLUtils.getTagAttributes(myEditor, pos); expect(attrs).toEqual([]); }); @@ -286,9 +286,9 @@ define(function (require, exports, module) { it("should find all the tag attributes immediately after the tag", function () { var pos = {"ch": 0, "line": 0}; setContentAndUpdatePos(pos, - ['', '', '
    '], - '

    test

    ', - [ '
    ', '', '']); + ["", "", '
    '], + "

    test

    ", + [ "
    ", "", ""]); var attrs = HTMLUtils.getTagAttributes(myEditor, pos); expect(attrs.sort()).toEqual(["id", "class", "lang", "align", "title"].sort()); }); @@ -296,9 +296,9 @@ define(function (require, exports, module) { it("should find all the tag attributes before closing the tag", function () { var pos = {"ch": 0, "line": 0}; setContentAndUpdatePos(pos, - ['', '', '
    '], - '

    test

    ', - [ '
    ', '', '']); + ["", "", '
    '], + "

    test

    ", + [ "
    ", "", ""]); var attrs = HTMLUtils.getTagAttributes(myEditor, pos); expect(attrs.sort()).toEqual(["id", "class", "lang", "align", "title"].sort()); }); @@ -306,9 +306,9 @@ define(function (require, exports, module) { it("should find all the tag attributes backward and forward", function () { var pos = {"ch": 0, "line": 0}; setContentAndUpdatePos(pos, - ['', '', '
    '], - '

    test

    ', - [ '
    ', '', '']); + ["", "", '
    '], + "

    test

    ", + [ "
    ", "", ""]); var attrs = HTMLUtils.getTagAttributes(myEditor, pos); expect(attrs.sort()).toEqual(["id", "class", "lang", "align", "title"].sort()); }); @@ -316,9 +316,9 @@ define(function (require, exports, module) { it("should find valid attributes marked as errors by the tokenizer", function () { var pos = {"ch": 0, "line": 0}; setContentAndUpdatePos(pos, - ['', '', '
    '], - '

    test

    ', - [ '
    ', '', '']); + ["", "", '
    '], + "

    test

    ", + [ "
    ", "", ""]); var attrs = HTMLUtils.getTagAttributes(myEditor, pos); expect(attrs.sort()).toEqual(["id", "class", "lang", "align", "title"].sort()); }); @@ -326,9 +326,9 @@ define(function (require, exports, module) { it("should not find attributes in nested tags", function () { var pos = {"ch": 0, "line": 0}; setContentAndUpdatePos(pos, - ['', '', '
    '], - '

    ', - [ '
    ', '', '']); + ["", "", '
    '], + "

    ", + [ "
    ", "", ""]); var attrs = HTMLUtils.getTagAttributes(myEditor, pos); expect(attrs.sort()).toEqual(["id", "class", "lang", "align", "title"].sort()); }); From 844c5fe3098ec70817b5a9f75a81bc679ed44319 Mon Sep 17 00:00:00 2001 From: Chema Date: Thu, 6 Dec 2012 11:45:50 +0100 Subject: [PATCH 6/7] Update test for hints after close tag --- src/language/HTMLUtils.js | 2 +- test/spec/CodeHintUtils-test.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/language/HTMLUtils.js b/src/language/HTMLUtils.js index e70cd2f55b6..86af2454d6b 100644 --- a/src/language/HTMLUtils.js +++ b/src/language/HTMLUtils.js @@ -124,7 +124,7 @@ define(function (require, exports, module) { forwardCtx = $.extend({}, backwardCtx); if (editor.getModeForSelection() === "html") { - if (backwardCtx.token) { + if (backwardCtx.token && backwardCtx.token.className !== "tag") { while (TokenUtils.movePrevToken(backwardCtx) && backwardCtx.token.className !== "tag") { if (backwardCtx.token.className === "attribute") { attrs.push(backwardCtx.token.string); diff --git a/test/spec/CodeHintUtils-test.js b/test/spec/CodeHintUtils-test.js index 8ac68f38fe0..d653730de00 100644 --- a/test/spec/CodeHintUtils-test.js +++ b/test/spec/CodeHintUtils-test.js @@ -277,7 +277,7 @@ define(function (require, exports, module) { var pos = {"ch": 0, "line": 0}; setContentAndUpdatePos(pos, ["", "", '
    '], - "

    test

    ", "", + "

    ", "test

    ", [ "
    ", "", ""]); var attrs = HTMLUtils.getTagAttributes(myEditor, pos); expect(attrs).toEqual([]); From c48b3ad145863a456f5325f454145624263ba066 Mon Sep 17 00:00:00 2001 From: Chema Date: Thu, 6 Dec 2012 11:50:55 +0100 Subject: [PATCH 7/7] Fixed last missing single quotes --- test/spec/CodeHintUtils-test.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/test/spec/CodeHintUtils-test.js b/test/spec/CodeHintUtils-test.js index d653730de00..8bd154728f7 100644 --- a/test/spec/CodeHintUtils-test.js +++ b/test/spec/CodeHintUtils-test.js @@ -103,7 +103,7 @@ define(function (require, exports, module) { it("should find an attribute as the value is typed", function () { var pos = {"ch": 0, "line": 0}; setContentAndUpdatePos(pos, - ["", "", '
    '], + ["", "", "
    "], "

    '], + ["", "", "

    "], "

    ", "test

    ", [ "
    ", "", ""]); var attrs = HTMLUtils.getTagAttributes(myEditor, pos); @@ -286,7 +286,7 @@ define(function (require, exports, module) { it("should find all the tag attributes immediately after the tag", function () { var pos = {"ch": 0, "line": 0}; setContentAndUpdatePos(pos, - ["", "", '
    '], + ["", "", "
    "], "

    test

    ", [ "
    ", "", ""]); var attrs = HTMLUtils.getTagAttributes(myEditor, pos); @@ -296,7 +296,7 @@ define(function (require, exports, module) { it("should find all the tag attributes before closing the tag", function () { var pos = {"ch": 0, "line": 0}; setContentAndUpdatePos(pos, - ["", "", '
    '], + ["", "", "
    "], "

    test

    ", [ "
    ", "", ""]); var attrs = HTMLUtils.getTagAttributes(myEditor, pos); @@ -306,7 +306,7 @@ define(function (require, exports, module) { it("should find all the tag attributes backward and forward", function () { var pos = {"ch": 0, "line": 0}; setContentAndUpdatePos(pos, - ["", "", '
    '], + ["", "", "
    "], "

    test

    ", [ "
    ", "", ""]); var attrs = HTMLUtils.getTagAttributes(myEditor, pos); @@ -316,7 +316,7 @@ define(function (require, exports, module) { it("should find valid attributes marked as errors by the tokenizer", function () { var pos = {"ch": 0, "line": 0}; setContentAndUpdatePos(pos, - ["", "", '
    '], + ["", "", "
    "], "

    test

    ", [ "
    ", "", ""]); var attrs = HTMLUtils.getTagAttributes(myEditor, pos); @@ -326,7 +326,7 @@ define(function (require, exports, module) { it("should not find attributes in nested tags", function () { var pos = {"ch": 0, "line": 0}; setContentAndUpdatePos(pos, - ["", "", '
    '], + ["", "", "
    "], "

    ", [ "
    ", "", ""]); var attrs = HTMLUtils.getTagAttributes(myEditor, pos);