@@ -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
0 commit comments