Skip to content
This repository was archived by the owner on Sep 6, 2021. It is now read-only.
Closed
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
54 changes: 53 additions & 1 deletion src/language/CSSUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
*/


/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */
/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50, regexp: true */
/*global define, $, CodeMirror, _parseRuleList: true */

// JSLint Note: _parseRuleList() is cyclical dependency, not a global function.
Expand Down Expand Up @@ -1115,10 +1115,62 @@ define(function (require, exports, module) {
return _stripAtRules(selector);
}

// removes css comments from the content
function _removeComments(_content) {
return _content.replace(/\/\*(?:(?!\*\/)[\s\S])*\*\//g, '');
}

// removes strings from the content
function _removeStrings(_content) {
return _content.replace(/[^\\]\"(.*)[^\\]\"|[^\\]\'(.*)[^\\]\'+/g, '');
}

/**
* Reduces the style sheet by removing comments and strings
* so that the content can be parsed using a regular expression
* @param {!String} content to reduce
* @return {String} reduced content

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lowercase for all primitive types.

*/
function reduceStyleSheetForRegExParsing(content) {
return _removeStrings(_removeComments(content));
}

/**
* Extracts all named flow instances
* @param {!String} text to extract from

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, should be lowercase.

* @return {?Array.<string>} array of unique flow names
*/
function extractAllNamedFlows(text) {
var namedFlowRegEx = /(?:flow\-(into|from)\:[ \t\n\r]*)([a-z0-9_\-]+)(?:[ \t\n\r]*;)/gi,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why [ \t\n\r] instead of \s?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I use regexpal.com to build my regular expressions and test them and \s wasn't working there for some reason. I made the change in brackets and it did work so I committed the change.

@RaymondLim This branch has been deleted and the pullreques is closed but I did address your JSDoc comments and the whitespace regex change in the pull request #4890

result = [],
names = {},
thisMatch;

// Reduce the content so that matches
// inside strings and comments are ignored
text = reduceStyleSheetForRegExParsing(text);

// Find the first match
thisMatch = namedFlowRegEx.exec(text);

// Iterate over the matches and add them to result
while (thisMatch) {
var thisName = thisMatch[2];
if (!names.hasOwnProperty(thisName)) {
names[thisName] = result.push(thisName);
}
thisMatch = namedFlowRegEx.exec(text);
}

return result;
}

exports._findAllMatchingSelectorsInText = _findAllMatchingSelectorsInText; // For testing only
exports.findMatchingRules = findMatchingRules;
exports.extractAllSelectors = extractAllSelectors;
exports.extractAllNamedFlows = extractAllNamedFlows;
exports.findSelectorAtDocumentPos = findSelectorAtDocumentPos;
exports.reduceStyleSheetForRegExParsing = reduceStyleSheetForRegExParsing;

exports.SELECTOR = SELECTOR;
exports.PROP_NAME = PROP_NAME;
Expand Down
77 changes: 77 additions & 0 deletions test/spec/CSSUtils-test-files/regions.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/* basic tests */
article.content {
flow-into: main;
}

section.layout > div {
flow-from: main;
}


#jeff.content {
flow-into: jeff;
}

#jeff.layout > div {
flow-from: jeff;
}

/* exclude matches inside comments tests */

/*
p.content {
flow-into: carter;
}

p.layout > div {
flow-from: carter;
}
*/

/* exclude matches inside strings tests */

div {
content: "/* p.content { flow-into: carter; } p.layout > div { flow-from: carter; } */";
}


div {
content: "html.content { flow-into: dexter; } html.layout > div { flow-from: dexter; }";
}


/*
div.content {
content: "flow-into: martin;";
}

div.layout > div {
content: "flow-from: martin;";
}
*/

/* multi-line property tests */

#randy.content {
flow-into:
randy
;
}

#randy.layout > div {
flow-from: randy;
}

/* test to exclude duplicates */
#yin.content {
flow-into: jeff;
}

#yin.layout > div {
flow-from: jeff;
}

/* flow-from only tests */
#raymond.layout > div {
flow-from: lim;
}
19 changes: 18 additions & 1 deletion test/spec/CSSUtils-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ define(function (require, exports, module) {
offsetsCssFileEntry = new NativeFileSystem.FileEntry(testPath + "/offsets.css"),
bootstrapCssFileEntry = new NativeFileSystem.FileEntry(testPath + "/bootstrap.css"),
escapesCssFileEntry = new NativeFileSystem.FileEntry(testPath + "/escaped-identifiers.css"),
embeddedHtmlFileEntry = new NativeFileSystem.FileEntry(testPath + "/embedded.html");
embeddedHtmlFileEntry = new NativeFileSystem.FileEntry(testPath + "/embedded.html"),
cssRegionsFileEntry = new NativeFileSystem.FileEntry(testPath + "/regions.css");

var contextTestCss = require("text!spec/CSSUtils-test-files/contexts.css"),
selectorPositionsTestCss = require("text!spec/CSSUtils-test-files/selector-positions.css");
Expand Down Expand Up @@ -1922,4 +1923,20 @@ define(function (require, exports, module) {
});
});
});

describe("CSS Regions", function () {
beforeEach(function () {
init(this, cssRegionsFileEntry);
});

it("should find named flows", function () {
var namedFlows = CSSUtils.extractAllNamedFlows(this.fileContent);
expect(namedFlows.length).toBe(4);
expect(namedFlows[0]).toBe("main");
expect(namedFlows[1]).toBe("jeff");
expect(namedFlows[2]).toBe("randy");
expect(namedFlows[3]).toBe("lim");
});

});
});