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

Commit 27ed6e1

Browse files
committed
Merge pull request #7373 from adobe/rlim/prop-name-issues
Handle prefixed property names and nested selector in getInfoAtPos().
2 parents bcddd42 + 2656997 commit 27ed6e1

2 files changed

Lines changed: 70 additions & 23 deletions

File tree

src/extensions/default/CSSCodeHints/unittests.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -527,7 +527,8 @@ define(function (require, exports, module) {
527527
verifyAllValues(hintList, ["always", "auto", "avoid", "avoid-column", "avoid-page", "avoid-region", "column", "left", "page", "region", "right"]);
528528
});
529529

530-
it("should list 4 value-name hints for vendor prefixed region-* properties", function () {
530+
// TODO: Need to add vendor prefixed properties for CSS code hint provider.
531+
xit("should list 4 value-name hints for vendor prefixed region-* properties", function () {
531532
testEditor.setCursorPos({ line: 7, ch: 16 }); // after -ms-region
532533
var hintList = expectHints(CSSCodeHints.cssPropHintProvider);
533534
verifyAttrHints(hintList, "region-break-after"); // first hint should be region-break-after

src/language/CSSUtils.js

Lines changed: 68 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,66 @@ define(function (require, exports, module) {
151151
return ruleInfo;
152152
}
153153

154+
/**
155+
* @private
156+
* Scan backwards to check for any prefix if the current context is property name.
157+
* If the current context is in a prefix (either 'meta' or '-'), then scan forwards
158+
* to collect the entire property name. Return the name of the property in the CSS
159+
* context info object if there is one that seems to be valid. Return an empty context
160+
* info when we find an invalid one.
161+
*
162+
* @param {editor:{CodeMirror}, pos:{ch:{string}, line:{number}}, token:{object}} ctx context
163+
* @return {{context: string,
164+
* offset: number,
165+
* name: string,
166+
* index: number,
167+
* values: Array.<string>,
168+
* isNewItem: boolean}} A CSS context info object.
169+
*/
170+
function _getPropNameInfo(ctx) {
171+
var propName = "",
172+
offset = TokenUtils.offsetInToken(ctx),
173+
tokenString = ctx.token.string,
174+
excludedCharacters = [";", "{", "}"];
175+
176+
if (ctx.token.type === "property" || ctx.token.type === "property error" ||
177+
ctx.token.type === "tag") {
178+
propName = tokenString;
179+
if (TokenUtils.movePrevToken(ctx) && ctx.token.string.trim() !== "" &&
180+
excludedCharacters.indexOf(ctx.token.string) === -1) {
181+
propName = ctx.token.string + tokenString;
182+
offset += ctx.token.string.length;
183+
}
184+
} else if (ctx.token.type === "meta" || tokenString === "-") {
185+
propName = tokenString;
186+
if (TokenUtils.moveNextToken(ctx) &&
187+
(ctx.token.type === "property" || ctx.token.type === "property error" ||
188+
ctx.token.type === "tag")) {
189+
propName += ctx.token.string;
190+
}
191+
} else if (tokenString.trim() !== "" && excludedCharacters.indexOf(tokenString) === -1) {
192+
// We're not inside the property name context.
193+
return createInfo();
194+
} else {
195+
var testPos = {ch: ctx.pos.ch + 1, line: ctx.pos.line},
196+
testToken = ctx.editor.getTokenAt(testPos, true);
197+
198+
if (testToken.type === "property" || testToken.type === "property error" ||
199+
testToken.type === "tag") {
200+
propName = testToken.string;
201+
offset = 0;
202+
}
203+
}
204+
205+
// If we're in the property name context but not in an existing property name,
206+
// then reset offset to zero.
207+
if (propName === "") {
208+
offset = 0;
209+
}
210+
211+
return createInfo(PROP_NAME, offset, propName);
212+
}
213+
154214
/**
155215
* @private
156216
* Scans backwards from the current context and returns the name of the property if there is
@@ -159,7 +219,8 @@ define(function (require, exports, module) {
159219
* @return {string} the property name of the current rule.
160220
*/
161221
function _getPropNameStartingFromPropValue(ctx) {
162-
var ctxClone = $.extend({}, ctx);
222+
var ctxClone = $.extend({}, ctx),
223+
propName = "";
163224
do {
164225
// If we're no longer in the property value before seeing a colon, then we don't
165226
// have a valid property name. Just return an empty string.
@@ -170,10 +231,13 @@ define(function (require, exports, module) {
170231

171232
if (ctxClone.token.string === ":" && TokenUtils.moveSkippingWhitespace(TokenUtils.movePrevToken, ctxClone) &&
172233
(ctxClone.token.type === "property" || ctxClone.token.type === "property error")) {
173-
return ctxClone.token.string;
234+
propName = ctxClone.token.string;
235+
if (TokenUtils.movePrevToken(ctxClone) && ctxClone.token.type === "meta") {
236+
propName = ctxClone.token.string + propName;
237+
}
174238
}
175239

176-
return "";
240+
return propName;
177241
}
178242

179243
/**
@@ -454,25 +518,7 @@ define(function (require, exports, module) {
454518
}
455519

456520
if (_isInPropName(ctx)) {
457-
if (ctx.token.type === "property" || ctx.token.type === "property error" || ctx.token.type === "tag") {
458-
propName = ctx.token.string;
459-
} else {
460-
var testPos = {ch: ctx.pos.ch + 1, line: ctx.pos.line},
461-
testToken = editor._codeMirror.getTokenAt(testPos, true);
462-
463-
if (testToken.type === "property" || testToken.type === "property error" || testToken.type === "tag") {
464-
propName = testToken.string;
465-
offset = 0;
466-
}
467-
}
468-
469-
// If we're in property name context but not in an existing property name,
470-
// then reset offset to zero.
471-
if (propName === "") {
472-
offset = 0;
473-
}
474-
475-
return createInfo(PROP_NAME, offset, propName);
521+
return _getPropNameInfo(ctx, editor);
476522
}
477523

478524
if (_isInPropValue(ctx)) {

0 commit comments

Comments
 (0)