Skip to content
This repository was archived by the owner on Sep 6, 2021. It is now read-only.
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
3 changes: 2 additions & 1 deletion src/extensions/default/CSSCodeHints/unittests.js
Original file line number Diff line number Diff line change
Expand Up @@ -527,7 +527,8 @@ define(function (require, exports, module) {
verifyAllValues(hintList, ["always", "auto", "avoid", "avoid-column", "avoid-page", "avoid-region", "column", "left", "page", "region", "right"]);
});

it("should list 4 value-name hints for vendor prefixed region-* properties", function () {
// TODO: Need to add vendor prefixed properties for CSS code hint provider.
xit("should list 4 value-name hints for vendor prefixed region-* properties", function () {
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.

Any reason not to do this now?

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.

It involves not only code changes in CSS hint provider extension, but also creating json files or entries for specific vendor properties. Not a quick and easy task for this sprint. And it is this user story https://trello.com/c/82j3IeJn/702-css-vendor-prefixifier that we need to schedule time for.

testEditor.setCursorPos({ line: 7, ch: 16 }); // after -ms-region
var hintList = expectHints(CSSCodeHints.cssPropHintProvider);
verifyAttrHints(hintList, "region-break-after"); // first hint should be region-break-after
Expand Down
90 changes: 68 additions & 22 deletions src/language/CSSUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,66 @@ define(function (require, exports, module) {
return ruleInfo;
}

/**
* @private
* Scan backwards to check for any prefix if the current context is property name.
* If the current context is in a prefix (either 'meta' or '-'), then scan forwards
* to collect the entire property name. Return the name of the property in the CSS
* context info object if there is one that seems to be valid. Return an empty context
* info when we find an invalid one.
*
* @param {editor:{CodeMirror}, pos:{ch:{string}, line:{number}}, token:{object}} ctx context
* @return {{context: string,
* offset: number,
* name: string,
* index: number,
* values: Array.<string>,
* isNewItem: boolean}} A CSS context info object.
*/
function _getPropNameInfo(ctx) {
var propName = "",
offset = TokenUtils.offsetInToken(ctx),
tokenString = ctx.token.string,
excludedCharacters = [";", "{", "}"];

if (ctx.token.type === "property" || ctx.token.type === "property error" ||
ctx.token.type === "tag") {
propName = tokenString;
if (TokenUtils.movePrevToken(ctx) && ctx.token.string.trim() !== "" &&
excludedCharacters.indexOf(ctx.token.string) === -1) {
propName = ctx.token.string + tokenString;
offset += ctx.token.string.length;
}
} else if (ctx.token.type === "meta" || tokenString === "-") {
propName = tokenString;
if (TokenUtils.moveNextToken(ctx) &&
(ctx.token.type === "property" || ctx.token.type === "property error" ||
ctx.token.type === "tag")) {
propName += ctx.token.string;
}
} else if (tokenString.trim() !== "" && excludedCharacters.indexOf(tokenString) === -1) {
// We're not inside the property name context.
return createInfo();
} else {
var testPos = {ch: ctx.pos.ch + 1, line: ctx.pos.line},
testToken = ctx.editor.getTokenAt(testPos, true);

if (testToken.type === "property" || testToken.type === "property error" ||
testToken.type === "tag") {
propName = testToken.string;
offset = 0;
}
}

// If we're in the property name context but not in an existing property name,
// then reset offset to zero.
if (propName === "") {
offset = 0;
}

return createInfo(PROP_NAME, offset, propName);
}

/**
* @private
* Scans backwards from the current context and returns the name of the property if there is
Expand All @@ -159,7 +219,8 @@ define(function (require, exports, module) {
* @return {string} the property name of the current rule.
*/
function _getPropNameStartingFromPropValue(ctx) {
var ctxClone = $.extend({}, ctx);
var ctxClone = $.extend({}, ctx),
propName = "";
do {
// If we're no longer in the property value before seeing a colon, then we don't
// have a valid property name. Just return an empty string.
Expand All @@ -170,10 +231,13 @@ define(function (require, exports, module) {

if (ctxClone.token.string === ":" && TokenUtils.moveSkippingWhitespace(TokenUtils.movePrevToken, ctxClone) &&
(ctxClone.token.type === "property" || ctxClone.token.type === "property error")) {
return ctxClone.token.string;
propName = ctxClone.token.string;
if (TokenUtils.movePrevToken(ctxClone) && ctxClone.token.type === "meta") {
propName = ctxClone.token.string + propName;
}
}

return "";
return propName;
}

/**
Expand Down Expand Up @@ -454,25 +518,7 @@ define(function (require, exports, module) {
}

if (_isInPropName(ctx)) {
if (ctx.token.type === "property" || ctx.token.type === "property error" || ctx.token.type === "tag") {
propName = ctx.token.string;
} else {
var testPos = {ch: ctx.pos.ch + 1, line: ctx.pos.line},
testToken = editor._codeMirror.getTokenAt(testPos, true);

if (testToken.type === "property" || testToken.type === "property error" || testToken.type === "tag") {
propName = testToken.string;
offset = 0;
}
}

// If we're in property name context but not in an existing property name,
// then reset offset to zero.
if (propName === "") {
offset = 0;
}

return createInfo(PROP_NAME, offset, propName);
return _getPropNameInfo(ctx, editor);
}

if (_isInPropValue(ctx)) {
Expand Down