@@ -33190,13 +33190,16 @@ define("extensionsIntegrated/CSSColorPreview/main", function (require, exports,
3319033190 // Extension variables.
3319133191 const COLOR_REGEX = ColorUtils.COLOR_REGEX, // used to match color
3319233192 GUTTER_NAME = "CodeMirror-colorGutter",
33193+ DUMMY_GUTTER_CLASS = "CodeMirror-colorGutter-none",
33194+ SINGLE_COLOR_PREVIEW_CLASS = "ico-cssColorPreview",
33195+ MULTI_COLOR_PREVIEW_CLASS = "ico-multiple-cssColorPreview",
3319333196 COLOR_PREVIEW_GUTTER_PRIORITY = 200,
3319433197 COLOR_LANGUAGES= ["css", "scss", "less", "sass", "stylus", "html", "svg", "jsx", "tsx",
3319533198 "php", "ejs", "erb_html", "pug"];
3319633199
3319733200
3319833201 // For preferences settings, to toggle this feature on/off
33199- const PREFERENCES_CSS_COLOR_PREVIEW = "CSSColorPreview ";
33202+ const PREFERENCES_CSS_COLOR_PREVIEW = "colorPreview ";
3320033203 let enabled = true; // by default:- on
3320133204
3320233205 PreferencesManager.definePreference(PREFERENCES_CSS_COLOR_PREVIEW, "boolean", enabled, {
@@ -33264,81 +33267,82 @@ define("extensionsIntegrated/CSSColorPreview/main", function (require, exports,
3326433267 /**
3326533268 * To display the color marks on the gutter
3326633269 *
33267- * @param {activeEditor } editor
33270+ * @param {Editor } editor
3326833271 * @param {Array.<object>} _results An array of objects which stores
3326933272 * all the line numbers and the colors to be displayed on that line.
3327033273 * @param {Boolean} update marks whether this function is called when some lines
3327133274 * are updated or when the whole file is re-updated. Defaults to false.
3327233275 */
3327333276 function showGutters(editor, _results, update = false) {
3327433277 if (editor && enabled) {
33275- // if the file is updated we don't need to clear the gutter
33276- // as it will clear all the existing markers.
33277- if(!update) {
33278- editor.clearGutter(GUTTER_NAME); // clear color markers
33279- }
33280- _addDummyGutterMarkerIfNotExist(editor, editor.getCursorPos().line);
33278+ editor.operation(()=>{
33279+ // if the file is updated we don't need to clear the gutter
33280+ // as it will clear all the existing markers.
33281+ if(!update) {
33282+ editor.clearGutter(GUTTER_NAME); // clear color markers
33283+ }
33284+ _addDummyGutterMarkerIfNotExist(editor, editor.getCursorPos().line);
33285+
33286+ // Only add markers if enabled
33287+ if (enabled) {
33288+ const colorGutters = _.sortBy(_results, "lineNumber");
33289+
33290+ colorGutters.forEach(function (obj) {
33291+ let $marker;
33292+ if (obj.colorValues.length === 1) {
33293+ // Single color preview
33294+ $marker = $("<i>")
33295+ .addClass(SINGLE_COLOR_PREVIEW_CLASS)
33296+ .css('background-color', obj.colorValues[0]);
33297+
33298+ editor.setGutterMarker(obj.lineNumber, GUTTER_NAME, $marker[0]);
33299+ $marker.click((event)=>{
33300+ event.preventDefault();
33301+ event.stopPropagation();
33302+ _colorIconClicked(editor, obj.lineNumber, obj.colorValues[0]);
33303+ });
33304+ } else {
33305+ // Multiple colors preview
33306+ $marker = $("<div>").addClass(MULTI_COLOR_PREVIEW_CLASS);
33307+
33308+ // Positions for up to 4 colors in grid
33309+ const positions = [
33310+ { top: 0, left: 0 },
33311+ { top: 0, right: 0 },
33312+ { bottom: 0, right: 0 },
33313+ { bottom: 0, left: 0 }
33314+ ];
3328133315
33282- // Only add markers if enabled
33283- if (enabled) {
33284- const colorGutters = _.sortBy(_results, "lineNumber");
33285-
33286- colorGutters.forEach(function (obj) {
33287- let $marker;
33288- if (obj.colorValues.length === 1) {
33289- // Single color preview
33290- $marker = $("<i>")
33291- .addClass("ico-cssColorPreview")
33292- .css('background-color', obj.colorValues[0]);
33293-
33294- editor.setGutterMarker(obj.lineNumber, GUTTER_NAME, $marker[0]);
33295- $marker.click((event)=>{
33296- event.preventDefault();
33297- event.stopPropagation();
33298- _colorIconClicked(editor, obj.lineNumber, obj.colorValues[0]);
33299- });
33300- } else {
33301- // Multiple colors preview
33302- $marker = $("<div>").addClass("ico-multiple-cssColorPreview");
33303-
33304- // Positions for up to 4 colors in grid
33305- const positions = [
33306- { top: 0, left: 0 },
33307- { top: 0, right: 0 },
33308- { bottom: 0, right: 0 },
33309- { bottom: 0, left: 0 }
33310- ];
33311-
33312- obj.colorValues.forEach((color, index) => {
33313- if (index < 4) {
33314- const $colorBox = $("<div>")
33315- .addClass("color-box")
33316- .css({
33317- 'background-color': color,
33318- ...positions[index]
33316+ obj.colorValues.forEach((color, index) => {
33317+ if (index < 4) {
33318+ const $colorBox = $("<div>")
33319+ .addClass("color-box")
33320+ .css({
33321+ 'background-color': color,
33322+ ...positions[index]
33323+ });
33324+ $colorBox.click((event)=>{
33325+ event.preventDefault();
33326+ event.stopPropagation();
33327+ _colorIconClicked(editor, obj.lineNumber, color);
3331933328 });
33320- $colorBox.click((event)=>{
33321- event.preventDefault();
33322- event.stopPropagation();
33323- _colorIconClicked(editor, obj.lineNumber, color);
33324- });
33325- $marker.append($colorBox);
33326- }
33327- });
33328-
33329- editor.setGutterMarker(obj.lineNumber, GUTTER_NAME, $marker[0]);
33330- }
33331- });
33332- }
33329+ $marker.append($colorBox);
33330+ }
33331+ });
3333333332
33333+ editor.setGutterMarker(obj.lineNumber, GUTTER_NAME, $marker[0]);
33334+ }
33335+ });
33336+ }
33337+ });
3333433338 }
3333533339 }
3333633340
3333733341 function _addDummyGutterMarkerIfNotExist(editor, line) {
3333833342 let marker = editor.getGutterMarker(line, GUTTER_NAME);
3333933343 if(!marker){
3334033344 let $marker = $('<div>')
33341- .addClass(GUTTER_NAME );
33345+ .addClass(DUMMY_GUTTER_CLASS );
3334233346 editor.setGutterMarker(line, GUTTER_NAME, $marker[0]);
3334333347 }
3334433348 }
@@ -33396,6 +33400,35 @@ define("extensionsIntegrated/CSSColorPreview/main", function (require, exports,
3339633400 }
3339733401 }
3339833402
33403+ const STYLE_PARSE_LANGUAGES = {
33404+ php: true,
33405+ jsx: true,
33406+ tsx: true
33407+ };
33408+ function _isInStyleAttr(editor, token) {
33409+ while(token.type === "string") {
33410+ const currentToken = token;
33411+ token = editor.getPreviousToken({line: token.line, ch: token.start}, true);
33412+ if(currentToken.line === token.line &&
33413+ currentToken.start === token.start && currentToken.end === token.end) {
33414+ // reached start of file
33415+ break;
33416+ }
33417+ }
33418+ return token.type === "attribute" && token.string === "style";
33419+ }
33420+
33421+ function _shouldProcessToken(editor, token, pos) {
33422+ const languageID = editor.document.getLanguage().getId();
33423+ if(languageID === "html") {
33424+ return editor.getLanguageForPosition(pos).getId() === "css";
33425+ } else if (STYLE_PARSE_LANGUAGES[languageID]) {
33426+ // unfortunately the codemirror mode doesn't support css detection in attributes in php files right now
33427+ return token.type !== "comment" && _isInStyleAttr(editor, token);
33428+ }
33429+ return token.type !== "comment";
33430+ }
33431+
3339933432 /**
3340033433 * Detects valid colors in a given line of text
3340133434 *
@@ -33411,7 +33444,7 @@ define("extensionsIntegrated/CSSColorPreview/main", function (require, exports,
3341133444 return [];
3341233445 }
3341333446
33414- const valueRegex = /:[^;]*;/g;
33447+ const valueRegex = /:[^;]*;? /g; // the last semi colon is optional.
3341533448 const validColors = [];
3341633449
3341733450 // Find all property value sections in the line
@@ -33428,7 +33461,7 @@ define("extensionsIntegrated/CSSColorPreview/main", function (require, exports,
3342833461 const token = editor.getToken({ line: lineNumber, ch: colorIndex }, true);
3342933462
3343033463 // If the token is not a comment, add the color
33431- if (token.type !== "comment" ) {
33464+ if (_shouldProcessToken(editor, token, { line: lineNumber, ch: colorIndex }) ) {
3343233465 validColors.push({
3343333466 color: colorMatch[0],
3343433467 index: colorIndex
@@ -33503,27 +33536,33 @@ define("extensionsIntegrated/CSSColorPreview/main", function (require, exports,
3350333536 /**
3350433537 * Function that gets triggered when any change occurs on the editor
3350533538 *
33506- * @param {Editor} instance the codemirror instance
33507- * @param {Object} changeObj an object that has properties regarding the line changed and type of change
33539+ * @param _evt unused event detail
33540+ * @param {Editor} instance the editor instance
33541+ * @param {Object} changeList an object that has properties regarding the line changed and type of change
3350833542 */
33509- function onChanged(instance, changeObj) {
33510-
33511- const editor = EditorManager.getActiveEditor();
33512-
33543+ function onChanged(_evt, instance, changeList) {
3351333544 // for insertion and deletion, update the changed lines
33514- if(changeObj.origin === '+input' || changeObj.origin === '+delete') {
33515- // make sure that the required properties exist and in the form they are expected to be
33545+ if(!changeList || !changeList.length) {
33546+ return;
33547+ }
33548+ const changeObj = changeList[0];
33549+ if(changeList.length === 1 && changeObj.origin === '+input' || changeObj.origin === '+delete') {
33550+ // we only do the diff updates on single key type input/delete and not bulk changes
33551+ // somehow the performance degrades if we do the diff logic on large blocks.
3351633552 if(changeObj.from.line && changeObj.to.line && changeObj.from.line <= changeObj.to.line) {
33517- const aColors = updateColorMarks(editor, changeObj.from.line, changeObj.to.line);
33518- showGutters(editor, aColors, true);
33553+ let toLine = changeObj.to.line;
33554+ if(changeObj.text && changeObj.text.length) {
33555+ toLine = changeObj.from.line + changeObj.text.length;
33556+ }
33557+ const aColors = updateColorMarks(instance, changeObj.from.line, Math.max(changeObj.to.line, toLine));
33558+ showGutters(instance, aColors, true);
3351933559 } else {
3352033560 showColorMarks();
3352133561 }
3352233562
3352333563 } else { // for any complex operation like, cut, paste etc, we re-update the whole file
3352433564 showColorMarks();
3352533565 }
33526-
3352733566 }
3352833567
3352933568 // init after appReady
0 commit comments