-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathmain.js
More file actions
1 lines (1 loc) · 8.35 KB
/
main.js
File metadata and controls
1 lines (1 loc) · 8.35 KB
1
define(function(require,exports,module){const _=require("thirdparty/lodash"),EditorManager=require("editor/EditorManager"),ColorUtils=require("utils/ColorUtils"),AppInit=require("utils/AppInit"),Editor=require("editor/Editor").Editor,PreferencesManager=require("preferences/PreferencesManager"),MainViewManager=require("view/MainViewManager"),Commands=require("command/Commands"),CommandManager=require("command/CommandManager"),Strings=require("strings"),COLOR_REGEX=ColorUtils.COLOR_REGEX,GUTTER_NAME="CodeMirror-colorGutter",DUMMY_GUTTER_CLASS="CodeMirror-colorGutter-none",SINGLE_COLOR_PREVIEW_CLASS="ico-cssColorPreview",MULTI_COLOR_PREVIEW_CLASS="ico-multiple-cssColorPreview",COLOR_MARK_NAME="colorMarker",COLOR_PREVIEW_GUTTER_PRIORITY=200,COLOR_LANGUAGES=["css","scss","less","sass","stylus","html","svg","jsx","tsx","php","ejs","erb_html","pug"],SVG_REGEX=/(:[^;]*;?|(?:fill|stroke|stop-color|flood-color|lighting-color|background-color|border-color|from|to)\s*=\s*(['"]?)[^'";]*\2)/g,CSS_REGEX=/:[^;]*;?/g,PREFERENCES_CSS_COLOR_PREVIEW="colorPreview";let enabled=!0;function showColorMarks(){if(!enabled)return;const editor=EditorManager.getActiveEditor();editor&&editor.isGutterActive(GUTTER_NAME)&&showGutters(editor,_getAllColorsAndLineNums(editor))}function addColorMarksToAllEditors(){const allActiveEditors=MainViewManager.getAllViewedEditors();allActiveEditors.forEach(activeEditor=>{const currEditor=activeEditor.editor;if(currEditor){const aColors=_getAllColorsAndLineNums(currEditor);showGutters(currEditor,aColors)}})}function _colorIconClicked(editor,lineNumber,colorValue){const lineText=editor.getLine(lineNumber),colorIndex=lineText.indexOf(colorValue),currentPos=editor.getCursorPos(!1,"start");currentPos.line===lineNumber&¤tPos.ch===colorIndex||(editor.setCursorPos(lineNumber,colorIndex),editor.focus()),setTimeout(()=>{CommandManager.execute(Commands.TOGGLE_QUICK_EDIT)},50)}function showGutters(editor,_results,update=!1){editor&&enabled&&editor.operation(()=>{if(update||editor.clearGutter(GUTTER_NAME),_addDummyGutterMarkerIfNotExist(editor,editor.getCursorPos().line),enabled){const colorGutters=_.sortBy(_results,"lineNumber");colorGutters.forEach(function(obj){let lineHandle,$marker;if(1===obj.colorValues.length)$marker=$("<i>").addClass(SINGLE_COLOR_PREVIEW_CLASS).css("background-color",obj.colorValues[0].color),lineHandle=editor.setGutterMarker(obj.lineNumber,GUTTER_NAME,$marker[0]),$marker.click(event=>{event.preventDefault(),event.stopPropagation(),_colorIconClicked(editor,lineHandle.lineNo(),obj.colorValues[0].color)});else{$marker=$("<div>").addClass(MULTI_COLOR_PREVIEW_CLASS),lineHandle=editor.setGutterMarker(obj.lineNumber,GUTTER_NAME,$marker[0]);const positions=[{top:0,left:0},{top:0,right:0},{bottom:0,right:0},{bottom:0,left:0}];obj.colorValues.forEach((color,index)=>{if(index<4){const $colorBox=$("<div>").addClass("color-box").css({"background-color":color.color,...positions[index]});$colorBox.click(event=>{event.preventDefault(),event.stopPropagation(),_colorIconClicked(editor,lineHandle.lineNo(),color.color)}),$marker.append($colorBox)}})}$marker.mouseenter(event=>{event.preventDefault(),event.stopPropagation(),_applyInlineColor(editor,lineHandle.lineNo())}),$marker.mouseleave(event=>{event.preventDefault(),event.stopPropagation(),editor.clearAllMarks(COLOR_MARK_NAME)})})}})}function _addDummyGutterMarkerIfNotExist(editor,line){let marker;if(!editor.getGutterMarker(line,GUTTER_NAME)){let $marker=$("<div>").addClass(DUMMY_GUTTER_CLASS);editor.setGutterMarker(line,GUTTER_NAME,$marker[0])}}function _cursorActivity(_evt,editor){editor.hasSelection()||(_addDummyGutterMarkerIfNotExist(editor,editor.getCursorPos().line),editor._currentlyColorMarkedLine&&(editor.clearAllMarks(COLOR_MARK_NAME),editor._currentlyColorMarkedLine=null))}function registerHandlers(){EditorManager.off("activeEditorChange",onChanged),EditorManager.on("activeEditorChange",function(event,newEditor,oldEditor){newEditor&&newEditor.isGutterActive(GUTTER_NAME)&&(newEditor.off("cursorActivity.colorPreview"),newEditor.on("cursorActivity.colorPreview",_cursorActivity),oldEditor&&oldEditor.off("change",onChanged),newEditor.off("change",onChanged),newEditor.on("change",onChanged),showColorMarks(),_cursorActivity(null,newEditor))});const activeEditor=EditorManager.getActiveEditor();activeEditor&&(activeEditor.off("change",onChanged),activeEditor.on("change",onChanged),activeEditor.off("cursorActivity.colorPreview"),activeEditor.on("cursorActivity.colorPreview",_cursorActivity),showColorMarks(),_cursorActivity(null,activeEditor))}function _colorMark(editor,from,to,color){editor.markText(COLOR_MARK_NAME,from,to,{css:`\n --bg-color-mark: ${color};\n background: var(--bg-color-mark);\n color: lch(from var(--bg-color-mark) calc((50 - l) * infinity) 0 0);\n `})}function _applyInlineColor(editor,line){editor._currentlyColorMarkedLine=line,editor.clearAllMarks(COLOR_MARK_NAME);const colors=detectValidColorsInLine(editor,line);for(let color of colors)_colorMark(editor,{line:line,ch:color.index},{line:line,ch:color.index+color.color.length},color.color)}function preferenceChanged(){const value=PreferencesManager.get(PREFERENCES_CSS_COLOR_PREVIEW);enabled=value,value?(Editor.registerGutter(GUTTER_NAME,COLOR_PREVIEW_GUTTER_PRIORITY,COLOR_LANGUAGES),addColorMarksToAllEditors()):Editor.unregisterGutter(GUTTER_NAME)}PreferencesManager.definePreference(PREFERENCES_CSS_COLOR_PREVIEW,"boolean",enabled,{description:Strings.DESCRIPTION_CSS_COLOR_PREVIEW});const STYLE_PARSE_LANGUAGES={php:!0,jsx:!0,tsx:!0};function _isInStyleAttr(editor,token){for(;"string"===token.type;){const currentToken=token;if(token=editor.getPreviousToken({line:token.line,ch:token.start},!0),currentToken.line===token.line&¤tToken.start===token.start&¤tToken.end===token.end)break}return"attribute"===token.type&&"style"===token.string}function _shouldProcessToken(editor,token,pos){const languageID=editor.document.getLanguage().getId();return"html"===languageID?"css"===editor.getLanguageForPosition(pos).getId():STYLE_PARSE_LANGUAGES[languageID]?"comment"!==token.type&&_isInStyleAttr(editor,token):"comment"!==token.type}function isAlphanumeric(char){return/^[a-z0-9-@$]$/i.test(char)}function _isColor(segment,colorInSegment,colorIndex){const previousChar=0===colorIndex?"":segment.charAt(colorIndex-1),endIndex=colorIndex+colorInSegment.length,nextChar=endIndex===segment.length?"":segment.charAt(endIndex);return!isAlphanumeric(previousChar)&&!isAlphanumeric(nextChar)}function detectValidColorsInLine(editor,lineNumber){const lineText=editor.getLine(lineNumber),languageID=editor.document.getLanguage().getId();if(!lineText||lineText.length>1e3)return[];const valueRegex="svg"===languageID?SVG_REGEX:CSS_REGEX,validColors=[],lineMatches=[...lineText.matchAll(valueRegex)];for(const lineMatch of lineMatches){const colorMatches=[...lineMatch[0].matchAll(COLOR_REGEX)];colorMatches.forEach(colorMatch=>{const colorIndex=lineMatch.index+colorMatch.index;if(!_isColor(lineMatch[0],colorMatch[0],colorMatch.index))return;const token=editor.getToken({line:lineNumber,ch:colorIndex},!0);_shouldProcessToken(editor,token,{line:lineNumber,ch:colorIndex})&&validColors.push({color:colorMatch[0],index:colorIndex})})}return validColors}function _getAllColorsAndLineNums(editor){const nLen=editor.lineCount(),aColors=[];for(let i=0;i<nLen;i++){const colors=detectValidColorsInLine(editor,i);colors.length>0&&aColors.push({lineNumber:i,colorValues:colors})}return aColors}function updateColorMarks(editor,fromLineNumber,toLineNumber){const aColors=[];for(let i=fromLineNumber;i<=toLineNumber;i++){const colors=detectValidColorsInLine(editor,i);0===colors.length?editor.setGutterMarker(i,GUTTER_NAME,""):aColors.push({lineNumber:i,colorValues:colors})}return aColors}function onChanged(_evt,instance,changeList){if(!changeList||!changeList.length)return;const changeObj=changeList[0];if(1===changeList.length&&"+input"===changeObj.origin||"+delete"===changeObj.origin)if(changeObj.from.line&&changeObj.to.line&&changeObj.from.line<=changeObj.to.line){let toLine=changeObj.to.line;changeObj.text&&changeObj.text.length&&(toLine=changeObj.from.line+changeObj.text.length);const aColors=updateColorMarks(instance,changeObj.from.line,Math.max(changeObj.to.line,toLine));showGutters(instance,aColors,!0)}else showColorMarks();else showColorMarks()}AppInit.appReady(function(){PreferencesManager.on("change",PREFERENCES_CSS_COLOR_PREVIEW,preferenceChanged),preferenceChanged(),registerHandlers()})});