diff --git a/src/language/CSSUtils.js b/src/language/CSSUtils.js index 38f6cda6e73..399efd5e09e 100644 --- a/src/language/CSSUtils.js +++ b/src/language/CSSUtils.js @@ -516,10 +516,10 @@ define(function (require, exports, module) { return true; } - function _parseSelector() { + function _parseSelector(start) { currentSelector = ""; - selectorStartChar = stream.start; + selectorStartChar = start; selectorStartLine = line; // Everything until the next ',' or '{' is part of the current selector @@ -548,15 +548,18 @@ define(function (require, exports, module) { } currentSelector = currentSelector.trim(); + var startChar = (selectorGroupStartLine === -1) ? selectorStartChar : selectorStartChar + 1; + var selectorStart = (stream.string.indexOf(currentSelector, selectorStartChar) !== -1) ? stream.string.indexOf(currentSelector, selectorStartChar - currentSelector.length) : startChar; + if (currentSelector !== "") { selectors.push({selector: currentSelector, ruleStartLine: ruleStartLine, ruleStartChar: ruleStartChar, selectorStartLine: selectorStartLine, - selectorStartChar: selectorStartChar, + selectorStartChar: selectorStart, declListEndLine: -1, selectorEndLine: line, - selectorEndChar: stream.start - 1, // stream.start points to the first char of the non-selector token + selectorEndChar: selectorStart + currentSelector.length, selectorGroupStartLine: selectorGroupStartLine, selectorGroupStartChar: selectorGroupStartChar }); @@ -566,16 +569,15 @@ define(function (require, exports, module) { } function _parseSelectorList() { - - selectorGroupStartLine = line; + selectorGroupStartLine = (stream.string.indexOf(",") !== -1) ? line : -1; selectorGroupStartChar = stream.start; - _parseSelector(); + _parseSelector(stream.start); while (token === ",") { if (!_nextTokenSkippingComments()) { break; } - _parseSelector(); + _parseSelector(stream.start); } } @@ -1027,7 +1029,7 @@ define(function (require, exports, module) { exports.getInfoAtPos = getInfoAtPos; - // The createInfo is reallyonly for the unit tests so they can make the same + // The createInfo is really only for the unit tests so they can make the same // structure to compare results with. exports.createInfo = createInfo; }); diff --git a/test/spec/CSSUtils-test-files/selector-positions.css b/test/spec/CSSUtils-test-files/selector-positions.css new file mode 100644 index 00000000000..78ea9c13193 --- /dev/null +++ b/test/spec/CSSUtils-test-files/selector-positions.css @@ -0,0 +1,32 @@ +div { + color: "green"; +} + +div{ + color: "green"; +} + +div +{ + color: "green"; +} +/* spaces */ + div +{ + color: "green"; +} +/* tab */ + div +{ + color: "green"; +} + +h3, h2, h1 +{ + color: "yellow"; +} + + h3, h2, h1 +{ + color: "yellow"; +} \ No newline at end of file diff --git a/test/spec/CSSUtils-test.js b/test/spec/CSSUtils-test.js index 9af149ff31e..1b31dc230e1 100644 --- a/test/spec/CSSUtils-test.js +++ b/test/spec/CSSUtils-test.js @@ -27,21 +27,22 @@ define(function (require, exports, module) { 'use strict'; - var NativeFileSystem = require("file/NativeFileSystem").NativeFileSystem, - Async = require("utils/Async"), - FileUtils = require("file/FileUtils"), - CSSUtils = require("language/CSSUtils"), - SpecRunnerUtils = require("spec/SpecRunnerUtils"); + var NativeFileSystem = require("file/NativeFileSystem").NativeFileSystem, + Async = require("utils/Async"), + FileUtils = require("file/FileUtils"), + CSSUtils = require("language/CSSUtils"), + SpecRunnerUtils = require("spec/SpecRunnerUtils"); - var testPath = SpecRunnerUtils.getTestPath("/spec/CSSUtils-test-files"), - simpleCssFileEntry = new NativeFileSystem.FileEntry(testPath + "/simple.css"), - universalCssFileEntry = new NativeFileSystem.FileEntry(testPath + "/universal.css"), - groupsFileEntry = new NativeFileSystem.FileEntry(testPath + "/groups.css"), - offsetsCssFileEntry = new NativeFileSystem.FileEntry(testPath + "/offsets.css"), - bootstrapCssFileEntry = new NativeFileSystem.FileEntry(testPath + "/bootstrap.css"), - escapesCssFileEntry = new NativeFileSystem.FileEntry(testPath + "/escaped-identifiers.css"); + var testPath = SpecRunnerUtils.getTestPath("/spec/CSSUtils-test-files"), + simpleCssFileEntry = new NativeFileSystem.FileEntry(testPath + "/simple.css"), + universalCssFileEntry = new NativeFileSystem.FileEntry(testPath + "/universal.css"), + groupsFileEntry = new NativeFileSystem.FileEntry(testPath + "/groups.css"), + offsetsCssFileEntry = new NativeFileSystem.FileEntry(testPath + "/offsets.css"), + bootstrapCssFileEntry = new NativeFileSystem.FileEntry(testPath + "/bootstrap.css"), + escapesCssFileEntry = new NativeFileSystem.FileEntry(testPath + "/escaped-identifiers.css"); - var contextTestCss = require("text!spec/CSSUtils-test-files/contexts.css"); + var contextTestCss = require("text!spec/CSSUtils-test-files/contexts.css"), + selectorPositionsTestCss = require("text!spec/CSSUtils-test-files/selector-positions.css"); /** * Verifies whether one of the results returned by CSSUtils._findAllMatchingSelectorsInText() @@ -511,6 +512,53 @@ define(function (require, exports, module) { }); + describe("find correct positions of selectors", function () { + var selectors; + + selectors = CSSUtils.extractAllSelectors(selectorPositionsTestCss); + + it("should find selector positions when whitespace between selector and '{'", function () { + expect([selectors[0].selectorStartChar, selectors[0].selectorEndChar]).toEqual([0, 3]); + }); + + it("should find selector positions when no whitespace between selector and '{'", function () { + expect([selectors[1].selectorStartChar, selectors[1].selectorEndChar]).toEqual([0, 3]); + }); + + it("should find selector positions when '{' on the next line", function () { + expect([selectors[2].selectorStartChar, selectors[2].selectorEndChar]).toEqual([0, 3]); + }); + + it("should find selector positions when '{' on the next line and selector is indented", function () { + expect([selectors[3].selectorStartChar, selectors[3].selectorEndChar]).toEqual([4, 7]); + }); + + it("should find selector positions when '{' on the next line and selector is indented with tabs", function () { + expect([selectors[4].selectorStartChar, selectors[4].selectorEndChar]).toEqual([1, 4]); + }); + + it("should find selector positions in a selector group when '{' on the next line", function () { + var expected = [0, 2, 4, 6, 8, 10], + result = [ + selectors[5].selectorStartChar, selectors[5].selectorEndChar, + selectors[6].selectorStartChar, selectors[6].selectorEndChar, + selectors[7].selectorStartChar, selectors[7].selectorEndChar + ]; + + expect(result).toEqual(expected); + }); + + it("should find selector positions in a selector group when '{' on the next line and selector group is indented", function () { + var expected = [4, 6, 8, 10, 12, 14], + result = [ + selectors[8].selectorStartChar, selectors[8].selectorEndChar, + selectors[9].selectorStartChar, selectors[9].selectorEndChar, + selectors[10].selectorStartChar, selectors[10].selectorEndChar + ]; + + expect(result).toEqual(expected); + }); + }); }); // describe("CSSUtils")