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

Commit 31dee88

Browse files
committed
Merge pull request #7390 from adobe/rlim/range-in-css-info
Return the css property value range in getInfoAtPos() api.
2 parents 377b4e2 + 99dbf8c commit 31dee88

3 files changed

Lines changed: 274 additions & 36 deletions

File tree

src/language/CSSUtils.js

Lines changed: 70 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ define(function (require, exports, module) {
4040
EditorManager = require("editor/EditorManager"),
4141
HTMLUtils = require("language/HTMLUtils"),
4242
ProjectManager = require("project/ProjectManager"),
43-
TokenUtils = require("utils/TokenUtils");
43+
TokenUtils = require("utils/TokenUtils"),
44+
_ = require("thirdparty/lodash");
4445

4546
// Constants
4647
var SELECTOR = "selector",
@@ -128,20 +129,25 @@ define(function (require, exports, module) {
128129
* @param {Array.<string>=} values An array of property values
129130
* @param {boolean=} isNewItem If this is true, then the value in index refers to the index at which a new item
130131
* is going to be inserted and should not be used for accessing an existing value in values array.
132+
* @param {{start: {line: number, ch: number},
133+
* end: {line: number, ch: number}}=} range A range object with a start position and an end position
131134
* @return {{context: string,
132135
* offset: number,
133136
* name: string,
134137
* index: number,
135138
* values: Array.<string>,
136-
* isNewItem: boolean}} A CSS context info object.
139+
* isNewItem: boolean,
140+
* range: {start: {line: number, ch: number},
141+
* end: {line: number, ch: number}}}} A CSS context info object.
137142
*/
138-
function createInfo(context, offset, name, index, values, isNewItem) {
143+
function createInfo(context, offset, name, index, values, isNewItem, range) {
139144
var ruleInfo = { context: context || "",
140145
offset: offset || 0,
141146
name: name || "",
142147
index: -1,
143148
values: [],
144-
isNewItem: (isNewItem) ? true : false };
149+
isNewItem: (isNewItem === true),
150+
range: range };
145151

146152
if (context === PROP_VALUE || context === SELECTOR || context === IMPORT_URL) {
147153
ruleInfo.index = index;
@@ -165,7 +171,9 @@ define(function (require, exports, module) {
165171
* name: string,
166172
* index: number,
167173
* values: Array.<string>,
168-
* isNewItem: boolean}} A CSS context info object.
174+
* isNewItem: boolean,
175+
* range: {start: {line: number, ch: number},
176+
* end: {line: number, ch: number}}}} A CSS context info object.
169177
*/
170178
function _getPropNameInfo(ctx) {
171179
var propName = "",
@@ -335,6 +343,43 @@ define(function (require, exports, module) {
335343
return propValues;
336344
}
337345

346+
/**
347+
* @private
348+
* Return a range object with a start position and an end position after
349+
* skipping any whitespaces and all separators used before and after a
350+
* valid property value.
351+
*
352+
* @param {editor:{CodeMirror}, pos:{ch:{string}, line:{number}}, token:{object}} startCtx context
353+
* @param {editor:{CodeMirror}, pos:{ch:{string}, line:{number}}, token:{object}} endCtx context
354+
* @return {{start: {line: number, ch: number},
355+
* end: {line: number, ch: number}}} A range object.
356+
*/
357+
function _getRangeForPropValue(startCtx, endCtx) {
358+
var range = { "start": {},
359+
"end": {} };
360+
361+
// Skip the ":" and any leading whitespace
362+
while (TokenUtils.moveNextToken(startCtx)) {
363+
if (startCtx.token.string.trim()) {
364+
break;
365+
}
366+
}
367+
368+
// Skip the trailing whitespace and property separators.
369+
while (endCtx.token.string === ";" || endCtx.token.string === "}" ||
370+
!endCtx.token.string.trim()) {
371+
TokenUtils.movePrevToken(endCtx);
372+
}
373+
374+
range.start = _.clone(startCtx.pos);
375+
range.start.ch = startCtx.token.start;
376+
377+
range.end = _.clone(endCtx.pos);
378+
range.end.ch = endCtx.token.end;
379+
380+
return range;
381+
}
382+
338383
/**
339384
* @private
340385
* Returns a context info object for the current CSS style rule
@@ -345,7 +390,9 @@ define(function (require, exports, module) {
345390
* name: string,
346391
* index: number,
347392
* values: Array.<string>,
348-
* isNewItem: boolean}} A CSS context info object.
393+
* isNewItem: boolean,
394+
* range: {start: {line: number, ch: number},
395+
* end: {line: number, ch: number}}}} A CSS context info object.
349396
*/
350397
function _getRuleInfoStartingFromPropValue(ctx, editor) {
351398
var propNamePos = $.extend({}, ctx.pos),
@@ -361,7 +408,8 @@ define(function (require, exports, module) {
361408
canAddNewOne = false,
362409
testPos = {ch: ctx.pos.ch + 1, line: ctx.pos.line},
363410
testToken = editor._codeMirror.getTokenAt(testPos, true),
364-
propName;
411+
propName,
412+
range;
365413

366414
// Get property name first. If we don't have a valid property name, then
367415
// return a default rule info.
@@ -413,13 +461,21 @@ define(function (require, exports, module) {
413461
forwardCtx = TokenUtils.getInitialContext(editor._codeMirror, forwardPos);
414462
propValues = propValues.concat(_getSucceedingPropValues(forwardCtx, lastValue));
415463

464+
if (propValues.length) {
465+
range = _getRangeForPropValue(backwardCtx, forwardCtx);
466+
} else {
467+
// No property value, so just return the cursor pos as range
468+
range = { "start": _.clone(ctx.pos),
469+
"end": _.clone(ctx.pos) };
470+
}
471+
416472
// If current index is more than the propValues size, then the cursor is
417473
// at the end of the existing property values and is ready for adding another one.
418474
if (index === propValues.length) {
419475
canAddNewOne = true;
420476
}
421477

422-
return createInfo(PROP_VALUE, offset, propName, index, propValues, canAddNewOne);
478+
return createInfo(PROP_VALUE, offset, propName, index, propValues, canAddNewOne, range);
423479
}
424480

425481
/**
@@ -432,7 +488,9 @@ define(function (require, exports, module) {
432488
* name: string,
433489
* index: number,
434490
* values: Array.<string>,
435-
* isNewItem: boolean}} A CSS context info object.
491+
* isNewItem: boolean,
492+
* range: {start: {line: number, ch: number},
493+
* end: {line: number, ch: number}}}} A CSS context info object.
436494
*/
437495
function _getImportUrlInfo(ctx, editor) {
438496
var propNamePos = $.extend({}, ctx.pos),
@@ -501,7 +559,9 @@ define(function (require, exports, module) {
501559
* name: string,
502560
* index: number,
503561
* values: Array.<string>,
504-
* isNewItem: boolean}} A CSS context info object.
562+
* isNewItem: boolean,
563+
* range: {start: {line: number, ch: number},
564+
* end: {line: number, ch: number}}}} A CSS context info object.
505565
*/
506566
function getInfoAtPos(editor, constPos) {
507567
// We're going to be changing pos a lot, but we don't want to mess up
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/* */
2+
3+
.foo {
4+
shape-inside: circle(0
5+
at
6+
0 0
7+
);
8+
9+
shape-inside: circle (0px
10+
at
11+
0px
12+
13+
0px
14+
);
15+
16+
shape-inside: polygon(0 0,
17+
100px
18+
19+
0,
20+
100px 100px
21+
22+
23+
);
24+
25+
26+
shape-inside:
27+
polygon(
28+
29+
30+
nonzero,
31+
0 0,
32+
100px
33+
0,
34+
100px
35+
36+
100px
37+
);
38+
}
39+
40+
41+
42+
@keyframes colorize {
43+
0% {
44+
-webkit-filter: grayscale(100%);
45+
}
46+
100% {
47+
-webkit-filter:
48+
49+
50+
grayscale
51+
( 0 % )
52+
53+
;
54+
}
55+
}

0 commit comments

Comments
 (0)