@@ -53,44 +53,6 @@ define(function (require, exports, module) {
5353 description : Strings . DESCRIPTION_CSS_COLOR_PREVIEW
5454 } ) ;
5555
56- /**
57- * Responsible to get all the colors and their respective line numbers.
58- *
59- * @param {Editor } editor
60- * @return {Array.<Object> } an array of objects with all the line nos and,
61- * the colors to be added on those lines
62- */
63- function _getAllColorsAndLineNums ( editor ) {
64-
65- const nLen = editor . lineCount ( ) ;
66- const aColors = [ ] ;
67-
68- // match colors and push into an array
69- for ( let i = 0 ; i < nLen ; i ++ ) {
70- let lineText = editor . getLine ( i ) ;
71-
72- if ( ( lineText . indexOf ( '/*' ) !== - 1 ) || ( lineText . indexOf ( '*/' ) !== - 1 ) ) {
73- continue ;
74- } else {
75- let regx = / : [ ^ ; ] * ; / g;
76-
77- lineText = lineText . match ( regx ) ;
78- if ( lineText ) {
79- let tempColors = lineText [ 0 ] . match ( COLOR_REGEX ) ;
80- // Support up to 4 colors
81- if ( tempColors && tempColors . length > 0 ) {
82- let colors = tempColors . slice ( 0 , 4 ) ;
83- aColors . push ( {
84- lineNumber : i ,
85- colorValues : colors
86- } ) ;
87- }
88- }
89- }
90- }
91-
92- return aColors ;
93- }
9456
9557 /**
9658 * Gets all the colors that are to be displayed
@@ -151,15 +113,21 @@ define(function (require, exports, module) {
151113
152114 /**
153115 * To display the color marks on the gutter
116+ *
154117 * @param {activeEditor } editor
155118 * @param {Array.<object> } _results An array of objects which stores
156119 * all the line numbers and the colors to be displayed on that line.
120+ * @param {Boolean } update marks whether this function is called when some lines
121+ * are updated or when the whole file is re-updated. Defaults to false.
157122 */
158- function showGutters ( editor , _results ) {
159- // TODO we should show the gutter in those languages only if a color is present in that file.
123+ function showGutters ( editor , _results , update = false ) {
160124 if ( editor && enabled ) {
161125 const cm = editor . _codeMirror ;
162- editor . clearGutter ( GUTTER_NAME ) ; // clear color markers
126+ // if the file is updated we don't need to clear the gutter
127+ // as it will clear all the existing markers.
128+ if ( ! update ) {
129+ editor . clearGutter ( GUTTER_NAME ) ; // clear color markers
130+ }
163131 _addDummyGutterMarkerIfNotExist ( editor , editor . getCursorPos ( ) . line ) ;
164132
165133 // Only add markers if enabled
@@ -289,11 +257,134 @@ define(function (require, exports, module) {
289257 }
290258 }
291259
260+ /**
261+ * Detects valid colors in a given line of text
262+ *
263+ * @param {Editor } editor - The editor instance
264+ * @param {number } lineNumber - The line number to check
265+ * @return {Array<{color: string, index: number}> } An array of valid color values with their indices
266+ */
267+ function detectValidColorsInLine ( editor , lineNumber ) {
268+ const lineText = editor . getLine ( lineNumber ) ;
269+
270+ // to make sure that code doesn't break when lineText is null.
271+ if ( ! lineText ) {
272+ return [ ] ;
273+ }
274+
275+ const valueRegex = / : [ ^ ; ] * ; / g;
276+ const validColors = [ ] ;
277+
278+ // Find all property value sections in the line
279+ const lineMatches = [ ...lineText . matchAll ( valueRegex ) ] ;
280+
281+ for ( const lineMatch of lineMatches ) {
282+ // Find colors within each property value
283+ const colorMatches = [ ...lineMatch [ 0 ] . matchAll ( COLOR_REGEX ) ] ;
284+
285+ colorMatches . forEach ( colorMatch => {
286+ const colorIndex = lineMatch . index + colorMatch . index ;
287+
288+ // Check if the color is within a comment
289+ const token = editor . getToken ( { line : lineNumber , ch : colorIndex } , true ) ;
290+
291+ // If the token is not a comment, add the color
292+ if ( token . type !== "comment" ) {
293+ validColors . push ( {
294+ color : colorMatch [ 0 ] ,
295+ index : colorIndex
296+ } ) ;
297+ }
298+ } ) ;
299+ }
300+
301+ // Return up to 4 colors
302+ return validColors . slice ( 0 , 4 ) . map ( item => item . color ) ;
303+ }
304+
305+ /**
306+ * Responsible to get all the colors and their respective line numbers.
307+ *
308+ * @param {Editor } editor
309+ * @return {Array.<Object> } an array of objects with all the line nos and,
310+ * the colors to be added on those lines
311+ */
312+ function _getAllColorsAndLineNums ( editor ) {
313+ const nLen = editor . lineCount ( ) ;
314+ const aColors = [ ] ;
315+
316+ // Match colors and push into an array
317+ for ( let i = 0 ; i < nLen ; i ++ ) {
318+ const colors = detectValidColorsInLine ( editor , i ) ;
319+
320+ // If valid colors found, add to the results
321+ if ( colors . length > 0 ) {
322+ aColors . push ( {
323+ lineNumber : i ,
324+ colorValues : colors
325+ } ) ;
326+ }
327+ }
328+
329+ return aColors ;
330+ }
331+
332+
333+ /**
334+ * Responsible to update the color marks only on the modified lines
335+ *
336+ * @param {Editor } editor the editor instance
337+ * @param {Number } fromLineNumber modification start from line number
338+ * @param {Number } toLineNumber modification upto line number
339+ * @return {Array.<Object> } an array of objects with all the line nos and,
340+ * the colors to be added on those lines
341+ */
342+ function updateColorMarks ( editor , fromLineNumber , toLineNumber ) {
343+ const aColors = [ ] ;
344+
345+ // Match colors and push into an array for modified lines
346+ for ( let i = fromLineNumber ; i <= toLineNumber ; i ++ ) {
347+ const colors = detectValidColorsInLine ( editor , i ) ;
348+
349+ // If no valid colors, clear the gutter marker
350+ if ( colors . length === 0 ) {
351+ editor . setGutterMarker ( i , GUTTER_NAME , "" ) ;
352+ } else {
353+ aColors . push ( {
354+ lineNumber : i ,
355+ colorValues : colors
356+ } ) ;
357+ }
358+ }
359+
360+ return aColors ;
361+ }
362+
363+
292364 /**
293365 * Function that gets triggered when any change occurs on the editor
366+ *
367+ * @param {Editor } instance the codemirror instance
368+ * @param {Object } changeObj an object that has properties regarding the line changed and type of change
294369 */
295- function onChanged ( ) {
296- showColorMarks ( ) ;
370+ function onChanged ( instance , changeObj ) {
371+
372+ const editor = EditorManager . getActiveEditor ( ) ;
373+
374+ // for insertion and deletion, update the changed lines
375+ if ( changeObj . origin === '+input' || changeObj . origin === '+delete' ) {
376+ // make sure that the required properties exist and in the form they are expected to be
377+ if ( changeObj . from . line && changeObj . to . line && changeObj . from . line <= changeObj . to . line ) {
378+ const aColors = updateColorMarks ( editor , changeObj . from . line , changeObj . to . line ) ;
379+ showGutters ( editor , aColors , true ) ;
380+ } else {
381+ showColorMarks ( ) ;
382+ }
383+
384+ } else { // for any complex operation like, cut, paste etc, we re-update the whole file
385+ showColorMarks ( ) ;
386+ }
387+
297388 }
298389
299390 // init after appReady
0 commit comments