From 1b0612b5a5ed33a2f1931e4aa08cb2d54ec8585c Mon Sep 17 00:00:00 2001 From: nightwing Date: Wed, 17 Aug 2022 00:25:08 +0400 Subject: [PATCH] fix: better way to extract css for csp environments --- Makefile.dryice.js | 122 ++++++++++++++++++-------------------- src/autocomplete/popup.js | 98 +++++++++++++++--------------- src/ext/code_lens.js | 46 +++++++------- src/ext/error_marker.js | 68 ++++++++++----------- src/ext/prompt.js | 18 +++--- src/incremental_search.js | 30 +++++----- src/keyboard/emacs.js | 51 ++++++++-------- src/keyboard/vim.js | 68 ++++++++++----------- src/snippets.js | 16 ++--- 9 files changed, 254 insertions(+), 263 deletions(-) diff --git a/Makefile.dryice.js b/Makefile.dryice.js index 0fff46ffe57..46823a45f42 100755 --- a/Makefile.dryice.js +++ b/Makefile.dryice.js @@ -90,11 +90,6 @@ function main(args) { return updateModes(); } - if (args.indexOf("--reuse") === -1) { - console.log("updating files in lib/ace"); - generateAmdModules(); - } - var type = "minimal"; args = args.map(function(x) { if (x[0] == "-" && x[1] != "-") @@ -112,6 +107,16 @@ function main(args) { if (args.indexOf("--h") != -1 || args.indexOf("-h") != -1 || args.indexOf("--help") != -1) { return showHelp(); } + + if (type == "css") { + return extractCss(); + } + + if (args.indexOf("--reuse") === -1) { + console.log("updating files in lib/ace"); + generateAmdModules(); + } + if (type == "minimal") { buildAce({ compress: args.indexOf("--m") != -1, @@ -139,6 +144,7 @@ function showHelp(type) { console.log(" demo Runs demo build of Ace"); console.log(" full all of above"); console.log(" highlighter "); + console.log(" css extract css files"); console.log("args:"); console.log(" --target ./path path to build folder"); console.log("flags:"); @@ -510,7 +516,7 @@ function buildAce(options, callback) { return; } else { cssUpdated = true; - extractCss(options, function() { + extractCss(function() { if (callback) return callback(); console.log("Finished building " + getTargetDir(options)); @@ -520,39 +526,54 @@ function buildAce(options, callback) { } var cssUpdated = false; -function extractCss(options, callback) { - var dir = BUILD_DIR + "/src" + (options.noconflict ? "-noconflict" : ""); - var filenames = fs.readdirSync(dir); - var css = ""; +function extractCss(callback) { var images = {}; - var usedCss = {}; - filenames.forEach(function(filename) { - var stat = fs.statSync(dir + "/" + filename); - if (stat.isDirectory()) return; - var value = fs.readFileSync(dir + "/" + filename, "utf8"); - - var cssImports = detectCssImports(value); - - if (/theme-/.test(filename)) { - var name = filename.replace(/^theme-|\.js$/g, ""); - var themeCss = ""; - for (var i in cssImports) { - themeCss += cssImports[i]; - } - themeCss = extractImages(themeCss, name, ".."); - build.writeToFile({code: themeCss}, { - outputFolder: BUILD_DIR + "/css/theme", - outputFile: name + ".css" - }, function() {}); - } else if (cssImports) { - css += "\n/*" + filename + "*/"; - for (var i in cssImports) { - if (usedCss[cssImports[i]]) continue; - usedCss[cssImports[i]] = true; - css += "\n" + cssImports[i]; - } + var cssImports = {}; + var fileName = ""; + + var extensions = jsFileList("src/ext"); + var keybinding = jsFileList("src/keyboard"); + var themes = jsFileList("src/theme"); + var dom = require("./src/lib/dom"); + var index = 0; + dom.importCssString = function(value, id) { + if (!id) id = fileName + (index++); + cssImports[id] = value; + }; + var loadFile = function(path) { + fileName = path; + require(path); + }; + themes.forEach(function(name) { + cssImports = {}; + loadFile("./src/theme/" + name); + delete require.cache[require.resolve("./src/theme/" + name)]; + + var themeCss = ""; + for (var i in cssImports) { + themeCss += cssImports[i]; } + themeCss = extractImages(themeCss, name, ".."); + build.writeToFile({code: themeCss}, { + outputFolder: BUILD_DIR + "/css/theme", + outputFile: name + ".css" + }, function() {}); + }); + + cssImports = {}; + loadFile("./src/ace"); + extensions.forEach(function(name) { + loadFile("./src/ext/" + name); + }); + keybinding.forEach(function(name) { + loadFile("./src/keyboard/" + name); }); + + var css = ""; + for (var i in cssImports) { + css += "\n/*" + i + "*/"; + css += "\n" + cssImports[i]; + } css = extractImages(css, "main", ".").replace(/^\s*/gm, ""); build.writeToFile({code: css}, { @@ -560,36 +581,9 @@ function extractCss(options, callback) { outputFile: "ace.css" }, function() { saveImages(); - callback(); + callback && callback(); }); - function detectCssImports(code) { - code = code.replace(/^\s*\/\/.+|^\s*\/\*[\s\S]*?\*\//gm, ""); - - var stringRegex = /^("(?:[^"\\]|\\[\d\D])*"|'(?:[^'\\]|\\[\d\D])*'|)/; - var importCssRegex = /\.importCssString\(\s*(?:([^,)"']+)|["'])/g; - - var match; - var cssImports; - while (match = importCssRegex.exec(code)) { - if (match[1]) { - var locationRegex = new RegExp("[^.]" + match[1] + /\s*=\s*['"]/.source); - match = locationRegex.exec(code); - if (!match) continue; - } - var index = match.index + match[0].length - 1; - if (cssImports && cssImports[index]) continue; - var cssString = stringRegex.exec(code.slice(index))[0]; - if (!cssString) continue; - if (!cssImports) cssImports = {}; - cssImports[index] = cssString.slice(1, -1).replace(/\\(.|\n)/g, function(_, ch) { - if (ch == "n") return ""; - return ch; - }); - } - return cssImports; - } - function extractImages(css, name, directory) { var imageCounter = 0; return css.replace( diff --git a/src/autocomplete/popup.js b/src/autocomplete/popup.js index 819bc350f58..ed48d279c3a 100644 --- a/src/autocomplete/popup.js +++ b/src/autocomplete/popup.js @@ -298,55 +298,55 @@ var AcePopup = function(parentNode) { return popup; }; -dom.importCssString("\ -.ace_editor.ace_autocomplete .ace_marker-layer .ace_active-line {\ - background-color: #CAD6FA;\ - z-index: 1;\ -}\ -.ace_dark.ace_editor.ace_autocomplete .ace_marker-layer .ace_active-line {\ - background-color: #3a674e;\ -}\ -.ace_editor.ace_autocomplete .ace_line-hover {\ - border: 1px solid #abbffe;\ - margin-top: -1px;\ - background: rgba(233,233,253,0.4);\ - position: absolute;\ - z-index: 2;\ -}\ -.ace_dark.ace_editor.ace_autocomplete .ace_line-hover {\ - border: 1px solid rgba(109, 150, 13, 0.8);\ - background: rgba(58, 103, 78, 0.62);\ -}\ -.ace_completion-meta {\ - opacity: 0.5;\ - margin: 0.9em;\ -}\ -.ace_completion-message {\ - color: blue;\ -}\ -.ace_editor.ace_autocomplete .ace_completion-highlight{\ - color: #2d69c7;\ -}\ -.ace_dark.ace_editor.ace_autocomplete .ace_completion-highlight{\ - color: #93ca12;\ -}\ -.ace_editor.ace_autocomplete {\ - width: 300px;\ - z-index: 200000;\ - border: 1px lightgray solid;\ - position: fixed;\ - box-shadow: 2px 3px 5px rgba(0,0,0,.2);\ - line-height: 1.4;\ - background: #fefefe;\ - color: #111;\ -}\ -.ace_dark.ace_editor.ace_autocomplete {\ - border: 1px #484747 solid;\ - box-shadow: 2px 3px 5px rgba(0, 0, 0, 0.51);\ - line-height: 1.4;\ - background: #25282c;\ - color: #c1c1c1;\ -}", "autocompletion.css", false); +dom.importCssString(` +.ace_editor.ace_autocomplete .ace_marker-layer .ace_active-line { + background-color: #CAD6FA; + z-index: 1; +} +.ace_dark.ace_editor.ace_autocomplete .ace_marker-layer .ace_active-line { + background-color: #3a674e; +} +.ace_editor.ace_autocomplete .ace_line-hover { + border: 1px solid #abbffe; + margin-top: -1px; + background: rgba(233,233,253,0.4); + position: absolute; + z-index: 2; +} +.ace_dark.ace_editor.ace_autocomplete .ace_line-hover { + border: 1px solid rgba(109, 150, 13, 0.8); + background: rgba(58, 103, 78, 0.62); +} +.ace_completion-meta { + opacity: 0.5; + margin: 0.9em; +} +.ace_completion-message { + color: blue; +} +.ace_editor.ace_autocomplete .ace_completion-highlight{ + color: #2d69c7; +} +.ace_dark.ace_editor.ace_autocomplete .ace_completion-highlight{ + color: #93ca12; +} +.ace_editor.ace_autocomplete { + width: 300px; + z-index: 200000; + border: 1px lightgray solid; + position: fixed; + box-shadow: 2px 3px 5px rgba(0,0,0,.2); + line-height: 1.4; + background: #fefefe; + color: #111; +} +.ace_dark.ace_editor.ace_autocomplete { + border: 1px #484747 solid; + box-shadow: 2px 3px 5px rgba(0, 0, 0, 0.51); + line-height: 1.4; + background: #25282c; + color: #c1c1c1; +}`, "autocompletion.css", false); exports.AcePopup = AcePopup; exports.$singleLineEditor = $singleLineEditor; diff --git a/src/ext/code_lens.js b/src/ext/code_lens.js index 82ba969cd95..74947ff56e6 100644 --- a/src/ext/code_lens.js +++ b/src/ext/code_lens.js @@ -209,26 +209,26 @@ require("../config").defineOptions(Editor.prototype, "editor", { } }); -dom.importCssString("\ -.ace_codeLens {\ - position: absolute;\ - color: #aaa;\ - font-size: 88%;\ - background: inherit;\ - width: 100%;\ - display: flex;\ - align-items: flex-end;\ - pointer-events: none;\ -}\ -.ace_codeLens > a {\ - cursor: pointer;\ - pointer-events: auto;\ -}\ -.ace_codeLens > a:hover {\ - color: #0000ff;\ - text-decoration: underline;\ -}\ -.ace_dark > .ace_codeLens > a:hover {\ - color: #4e94ce;\ -}\ -", "codelense.css", false); +dom.importCssString(` +.ace_codeLens { + position: absolute; + color: #aaa; + font-size: 88%; + background: inherit; + width: 100%; + display: flex; + align-items: flex-end; + pointer-events: none; +} +.ace_codeLens > a { + cursor: pointer; + pointer-events: auto; +} +.ace_codeLens > a:hover { + color: #0000ff; + text-decoration: underline; +} +.ace_dark > .ace_codeLens > a:hover { + color: #4e94ce; +} +`, "codelense.css", false); diff --git a/src/ext/error_marker.js b/src/ext/error_marker.js index e2c4447fb68..318e650e969 100644 --- a/src/ext/error_marker.js +++ b/src/ext/error_marker.js @@ -148,37 +148,37 @@ exports.showErrorMarker = function(editor, dir) { }; -dom.importCssString("\ - .error_widget_wrapper {\ - background: inherit;\ - color: inherit;\ - border:none\ - }\ - .error_widget {\ - border-top: solid 2px;\ - border-bottom: solid 2px;\ - margin: 5px 0;\ - padding: 10px 40px;\ - white-space: pre-wrap;\ - }\ - .error_widget.ace_error, .error_widget_arrow.ace_error{\ - border-color: #ff5a5a\ - }\ - .error_widget.ace_warning, .error_widget_arrow.ace_warning{\ - border-color: #F1D817\ - }\ - .error_widget.ace_info, .error_widget_arrow.ace_info{\ - border-color: #5a5a5a\ - }\ - .error_widget.ace_ok, .error_widget_arrow.ace_ok{\ - border-color: #5aaa5a\ - }\ - .error_widget_arrow {\ - position: absolute;\ - border: solid 5px;\ - border-top-color: transparent!important;\ - border-right-color: transparent!important;\ - border-left-color: transparent!important;\ - top: -5px;\ - }\ -", "error_marker.css", false); +dom.importCssString(` + .error_widget_wrapper { + background: inherit; + color: inherit; + border:none + } + .error_widget { + border-top: solid 2px; + border-bottom: solid 2px; + margin: 5px 0; + padding: 10px 40px; + white-space: pre-wrap; + } + .error_widget.ace_error, .error_widget_arrow.ace_error{ + border-color: #ff5a5a + } + .error_widget.ace_warning, .error_widget_arrow.ace_warning{ + border-color: #F1D817 + } + .error_widget.ace_info, .error_widget_arrow.ace_info{ + border-color: #5a5a5a + } + .error_widget.ace_ok, .error_widget_arrow.ace_ok{ + border-color: #5aaa5a + } + .error_widget_arrow { + position: absolute; + border: solid 5px; + border-top-color: transparent!important; + border-right-color: transparent!important; + border-left-color: transparent!important; + top: -5px; + } +`, "error_marker.css", false); diff --git a/src/ext/prompt.js b/src/ext/prompt.js index b1c197fd40e..4d93bdef5e4 100644 --- a/src/ext/prompt.js +++ b/src/ext/prompt.js @@ -469,15 +469,15 @@ prompt.modes = function(editor, callback) { }); }; -dom.importCssString(".ace_prompt_container {\ - max-width: 600px;\ - width: 100%;\ - margin: 20px auto;\ - padding: 3px;\ - background: white;\ - border-radius: 2px;\ - box-shadow: 0px 2px 3px 0px #555;\ -}", "promtp.css", false); +dom.importCssString(`.ace_prompt_container { + max-width: 600px; + width: 100%; + margin: 20px auto; + padding: 3px; + background: white; + border-radius: 2px; + box-shadow: 0px 2px 3px 0px #555; +}`, "promtp.css", false); exports.prompt = prompt; diff --git a/src/incremental_search.js b/src/incremental_search.js index bed3aee1ab7..569e983f46c 100644 --- a/src/incremental_search.js +++ b/src/incremental_search.js @@ -237,21 +237,21 @@ exports.IncrementalSearch = IncrementalSearch; **/ var dom = require('./lib/dom'); -dom.importCssString("\ -.ace_marker-layer .ace_isearch-result {\ - position: absolute;\ - z-index: 6;\ - box-sizing: border-box;\ -}\ -div.ace_isearch-result {\ - border-radius: 4px;\ - background-color: rgba(255, 200, 0, 0.5);\ - box-shadow: 0 0 4px rgb(255, 200, 0);\ -}\ -.ace_dark div.ace_isearch-result {\ - background-color: rgb(100, 110, 160);\ - box-shadow: 0 0 4px rgb(80, 90, 140);\ -}", "incremental-search-highlighting", false); +dom.importCssString(` +.ace_marker-layer .ace_isearch-result { + position: absolute; + z-index: 6; + box-sizing: border-box; +} +div.ace_isearch-result { + border-radius: 4px; + background-color: rgba(255, 200, 0, 0.5); + box-shadow: 0 0 4px rgb(255, 200, 0); +} +.ace_dark div.ace_isearch-result { + background-color: rgb(100, 110, 160); + box-shadow: 0 0 4px rgb(80, 90, 140); +}`, "incremental-search-highlighting", false); // support for default keyboard handler var commands = require("./commands/command_manager"); diff --git a/src/keyboard/emacs.js b/src/keyboard/emacs.js index 748737074ef..d0c4de24d19 100644 --- a/src/keyboard/emacs.js +++ b/src/keyboard/emacs.js @@ -11,37 +11,34 @@ exports.handler = new HashHandler(); exports.handler.isEmacs = true; exports.handler.$id = "ace/keyboard/emacs"; -var initialized = false; + +dom.importCssString(` +.emacs-mode .ace_cursor{ + border: 1px rgba(50,250,50,0.8) solid!important; + box-sizing: border-box!important; + background-color: rgba(0,250,0,0.9); + opacity: 0.5; +} +.emacs-mode .ace_hidden-cursors .ace_cursor{ + opacity: 1; + background-color: transparent; +} +.emacs-mode .ace_overwrite-cursors .ace_cursor { + opacity: 1; + background-color: transparent; + border-width: 0 0 2px 2px !important; +} +.emacs-mode .ace_text-layer { + z-index: 4 +} +.emacs-mode .ace_cursor-layer { + z-index: 2 +}`, 'emacsMode' +); var $formerLongWords; var $formerLineStart; exports.handler.attach = function(editor) { - if (!initialized) { - initialized = true; - dom.importCssString('\ - .emacs-mode .ace_cursor{\ - border: 1px rgba(50,250,50,0.8) solid!important;\ - box-sizing: border-box!important;\ - background-color: rgba(0,250,0,0.9);\ - opacity: 0.5;\ - }\ - .emacs-mode .ace_hidden-cursors .ace_cursor{\ - opacity: 1;\ - background-color: transparent;\ - }\ - .emacs-mode .ace_overwrite-cursors .ace_cursor {\ - opacity: 1;\ - background-color: transparent;\ - border-width: 0 0 2px 2px !important;\ - }\ - .emacs-mode .ace_text-layer {\ - z-index: 4\ - }\ - .emacs-mode .ace_cursor-layer {\ - z-index: 2\ - }', 'emacsMode' - ); - } // in emacs, gotowordleft/right should not count a space as a word.. $formerLongWords = editor.session.$selectLongWords; editor.session.$selectLongWords = true; diff --git a/src/keyboard/vim.js b/src/keyboard/vim.js index e49d69a6dd4..5360c8d55a0 100644 --- a/src/keyboard/vim.js +++ b/src/keyboard/vim.js @@ -740,40 +740,40 @@ CodeMirror.defineExtension = function(name, fn) { CodeMirror.prototype[name] = fn; }; -dom.importCssString(".normal-mode .ace_cursor{\ - border: none;\ - background-color: rgba(255,0,0,0.5);\ -}\ -.normal-mode .ace_hidden-cursors .ace_cursor{\ - background-color: transparent;\ - border: 1px solid red;\ - opacity: 0.7\ -}\ -.ace_dialog {\ - position: absolute;\ - left: 0; right: 0;\ - background: inherit;\ - z-index: 15;\ - padding: .1em .8em;\ - overflow: hidden;\ - color: inherit;\ -}\ -.ace_dialog-top {\ - border-bottom: 1px solid #444;\ - top: 0;\ -}\ -.ace_dialog-bottom {\ - border-top: 1px solid #444;\ - bottom: 0;\ -}\ -.ace_dialog input {\ - border: none;\ - outline: none;\ - background: transparent;\ - width: 20em;\ - color: inherit;\ - font-family: monospace;\ -}", "vimMode", false); +dom.importCssString(`.normal-mode .ace_cursor{ + border: none; + background-color: rgba(255,0,0,0.5); +} +.normal-mode .ace_hidden-cursors .ace_cursor{ + background-color: transparent; + border: 1px solid red; + opacity: 0.7 +} +.ace_dialog { + position: absolute; + left: 0; right: 0; + background: inherit; + z-index: 15; + padding: .1em .8em; + overflow: hidden; + color: inherit; +} +.ace_dialog-top { + border-bottom: 1px solid #444; + top: 0; +} +.ace_dialog-bottom { + border-top: 1px solid #444; + bottom: 0; +} +.ace_dialog input { + border: none; + outline: none; + background: transparent; + width: 20em; + color: inherit; + font-family: monospace; +}`, "vimMode", false); (function() { function dialogDiv(cm, template, bottom) { var wrap = cm.ace.container; diff --git a/src/snippets.js b/src/snippets.js index 9a72272994d..d54e3ead65c 100644 --- a/src/snippets.js +++ b/src/snippets.js @@ -997,14 +997,14 @@ var moveRelative = function(point, start) { }; -dom.importCssString("\ -.ace_snippet-marker {\ - -moz-box-sizing: border-box;\ - box-sizing: border-box;\ - background: rgba(194, 193, 208, 0.09);\ - border: 1px dotted rgba(211, 208, 235, 0.62);\ - position: absolute;\ -}", "snippets.css", false); +dom.importCssString(` +.ace_snippet-marker { + -moz-box-sizing: border-box; + box-sizing: border-box; + background: rgba(194, 193, 208, 0.09); + border: 1px dotted rgba(211, 208, 235, 0.62); + position: absolute; +}`, "snippets.css", false); exports.snippetManager = new SnippetManager();