├── .editorconfig ├── .eslintignore ├── .eslintrc ├── .githooks ├── logger.mjs ├── post-checkout │ ├── post-checkout-check-node-version.mjs │ └── post-checkout-check-npm-install-status.mjs └── semver.js ├── .gitignore ├── .nvmrc ├── .vscode └── settings.json ├── FIXME.md ├── LICENSE ├── PRIVACY-POLICY.md ├── README.md ├── TODO.md ├── copy-files-from-to.cjson ├── documents ├── extension-flowcharts │ └── login-flow.drawio.xml ├── extension-media │ └── screenshots │ │ ├── archived │ │ └── screenshot-wikipedia.jpg │ │ ├── screenshot-wikipedia.md │ │ └── screenshot-wikipedia.png └── extension-stores │ └── chrome │ └── product-description.txt ├── extension-dist └── .gitignore ├── extension ├── README-FOR-EXTENSION-REVIEWERS.md ├── _locales │ └── en │ │ └── messages.json ├── alert.html ├── alert.js ├── background-magicss.html ├── background-magicss.js ├── commonAppUtils │ ├── detectEnvironment.js │ ├── instanceAndFeatures.js │ ├── theWin.js │ └── updateConfigFromRemoteForNextLoad.js ├── constants.js ├── external-editor-base.js ├── external-editor.css ├── external-editor.html ├── icons │ ├── archived │ │ ├── icon-128.png │ │ ├── icon-16.png │ │ ├── icon-24.png │ │ ├── icon-256.png │ │ ├── icon-256.svg │ │ ├── icon-32.png │ │ ├── icon-40.png │ │ ├── icon-48.png │ │ ├── icon-64.png │ │ ├── icon-dark-scheme-128.png │ │ ├── icon-dark-scheme-16.png │ │ ├── icon-dark-scheme-24.png │ │ ├── icon-dark-scheme-256.png │ │ ├── icon-dark-scheme-32.png │ │ ├── icon-dark-scheme-40.png │ │ ├── icon-dark-scheme-48.png │ │ └── icon-dark-scheme-64.png │ ├── generate-icons.sh │ ├── icon-128.png │ ├── icon-16.png │ ├── icon-24.png │ ├── icon-256.png │ ├── icon-256.svg │ ├── icon-32.png │ ├── icon-40.png │ ├── icon-48.png │ └── icon-64.png ├── manifest-chrome.json ├── manifest-edge.json ├── manifest-firefox.json ├── manifest-generator.mjs ├── manifest-kiwi.json ├── manifest-opera.json ├── manifest-puppeteer.json ├── manifest.json ├── options.html ├── scripts │ ├── 3rdparty-custom-fixes │ │ ├── codemirror │ │ │ ├── addons │ │ │ │ └── lint │ │ │ │ │ └── tooltip.css │ │ │ ├── codemirror-as-global.js │ │ │ └── magicss-codemirror.css │ │ ├── csslint │ │ │ └── ignore-some-rules.js │ │ ├── csspretty │ │ │ └── pre-csspretty.js │ │ ├── jquery │ │ │ └── jquery-as-global.js │ │ └── socket.io │ │ │ └── socket.io-as-global.js │ ├── 3rdparty │ │ ├── .editorconfig │ │ ├── amplify-store.js │ │ ├── amplify-store.js.source.txt │ │ ├── basic-less-with-sourcemap-support.browserified.js │ │ ├── basic-less-with-sourcemap-support.browserified.js.source.description.txt │ │ ├── basic-less-with-sourcemap-support.browserified.js.source.txt │ │ ├── codemirror │ │ │ ├── addons │ │ │ │ ├── colorpicker │ │ │ │ │ ├── colorpicker.css │ │ │ │ │ ├── colorpicker.css.source.txt │ │ │ │ │ ├── colorpicker.js │ │ │ │ │ ├── colorpicker.js.source.txt │ │ │ │ │ ├── colorview.js │ │ │ │ │ ├── colorview.js.source.txt │ │ │ │ │ ├── colorview_customized.js │ │ │ │ │ └── colorview_customized.js.source.txt │ │ │ │ ├── comment │ │ │ │ │ ├── comment.js │ │ │ │ │ └── comment.js.source.txt │ │ │ │ ├── display │ │ │ │ │ ├── placeholder.js │ │ │ │ │ └── placeholder.js.source.txt │ │ │ │ ├── edit │ │ │ │ │ ├── closebrackets.js │ │ │ │ │ ├── closebrackets.js.source.txt │ │ │ │ │ ├── matchbrackets.js │ │ │ │ │ └── matchbrackets.js.source.txt │ │ │ │ ├── emmet │ │ │ │ │ ├── emmet-codemirror-plugin.js │ │ │ │ │ └── emmet-codemirror-plugin.js.source.txt │ │ │ │ ├── hint │ │ │ │ │ ├── css-hint.js │ │ │ │ │ ├── css-hint.js.source.txt │ │ │ │ │ ├── css-hint_customized.js │ │ │ │ │ ├── css-hint_customized.js.source.txt │ │ │ │ │ ├── show-hint.css │ │ │ │ │ ├── show-hint.css.source.txt │ │ │ │ │ ├── show-hint.js │ │ │ │ │ ├── show-hint.js.source.txt │ │ │ │ │ ├── show-hint_customized.js │ │ │ │ │ └── show-hint_customized.js.source.txt │ │ │ │ ├── lint │ │ │ │ │ ├── css-lint.js │ │ │ │ │ ├── css-lint.js.source.txt │ │ │ │ │ ├── css-lint_customized.js │ │ │ │ │ ├── css-lint_customized.js.source.txt │ │ │ │ │ ├── lint.css │ │ │ │ │ ├── lint.css.source.txt │ │ │ │ │ ├── lint.js │ │ │ │ │ └── lint.js.source.txt │ │ │ │ ├── search │ │ │ │ │ ├── searchcursor.js │ │ │ │ │ └── searchcursor.js.source.txt │ │ │ │ └── selection │ │ │ │ │ ├── active-line.js │ │ │ │ │ └── active-line.js.source.txt │ │ │ ├── codemirror.css │ │ │ ├── codemirror.css.source.txt │ │ │ ├── codemirror.js │ │ │ ├── codemirror.js.source.txt │ │ │ ├── keymap │ │ │ │ ├── sublime.js │ │ │ │ └── sublime.js.source.txt │ │ │ ├── mode │ │ │ │ ├── css.js │ │ │ │ └── css.js.source.txt │ │ │ └── theme │ │ │ │ ├── ambiance.css │ │ │ │ └── ambiance.css.source.txt │ │ ├── css.escape.js │ │ ├── css.escape.js.source.txt │ │ ├── csslint │ │ │ ├── csslint.js │ │ │ └── csslint.js.source.txt │ │ ├── csspretty │ │ │ ├── csspretty.js │ │ │ └── csspretty.js.source.txt │ │ ├── jquery-ui.css │ │ ├── jquery-ui.css.source.txt │ │ ├── jquery-ui.js │ │ ├── jquery-ui.js.source.txt │ │ ├── jquery-ui_customized.css │ │ ├── jquery-ui_customized.css.source.txt │ │ ├── jquery.js │ │ ├── jquery.js.source.txt │ │ ├── jquery.ui-touch-punch_customized.js.source.txt │ │ ├── jquery.ui.touch-punch.js │ │ ├── jquery.ui.touch-punch.js.source.txt │ │ ├── jquery.ui.touch-punch_customized.js │ │ ├── magicsuggest │ │ │ ├── magicsuggest.css │ │ │ ├── magicsuggest.css.source.txt │ │ │ ├── magicsuggest.js │ │ │ └── magicsuggest.js.source.txt │ │ ├── sass │ │ │ ├── sass.sync.min.js │ │ │ └── sass.sync.min.js.source.txt │ │ ├── socket.io │ │ │ ├── socket.io.slim.dev.js │ │ │ ├── socket.io.slim.dev.js.source.txt │ │ │ ├── socket.io.slim.js │ │ │ └── socket.io.slim.js.source.txt │ │ ├── source-map.js │ │ ├── source-map.js.source.txt │ │ ├── toastr │ │ │ ├── toastr.css │ │ │ ├── toastr.css.source.txt │ │ │ ├── toastr.js │ │ │ ├── toastr.js.source.txt │ │ │ ├── toastr_customized.js │ │ │ └── toastr_customized.js.source.txt │ │ └── tooltipster │ │ │ ├── jquery.tooltipster.js │ │ │ ├── jquery.tooltipster.js.source.txt │ │ │ ├── tooltipster-scrollableTip.js │ │ │ ├── tooltipster-scrollableTip.js.source.txt │ │ │ ├── tooltipster.css │ │ │ └── tooltipster.css.source.txt │ ├── actions.js │ ├── appUtils │ │ ├── getUuid.js │ │ ├── isFeatureEnabled.js │ │ ├── mainFnMetricsHandler.js │ │ ├── metricsUrlGenerator.js │ │ ├── myWin.js │ │ └── nativeAlert.js │ ├── appVersion.js │ ├── background-magicss-include.js │ ├── background-operations.js │ ├── chrome-extension-lib │ │ └── ext-lib.js │ ├── load-editor.js │ ├── load-reapply.js │ ├── loading-magic-css.js │ ├── magicss │ │ ├── editor │ │ │ ├── editor-standalone-example.js │ │ │ ├── editor.css │ │ │ └── editor.js │ │ ├── generate-selector.js │ │ ├── magicss.css │ │ ├── magicss.js │ │ └── metrics │ │ │ └── sendMessageForMetrics.js │ ├── migrate-storage.js │ ├── platformInfoOs-android.js │ ├── platformInfoOs-non-android.js │ ├── reapply-css.js │ ├── utils.js │ └── utils │ │ ├── StyleTag.js │ │ ├── alertNote.js │ │ ├── basisNumberFromUuid.js │ │ ├── beautifyCss.js │ │ ├── chromeStorage.js │ │ ├── confirmDialog.css │ │ ├── confirmDialog.js │ │ ├── delayFunctionUntilTestFunction.js │ │ ├── i18n.js │ │ ├── isValidUuidV4.js │ │ ├── lessToCss.js │ │ ├── loadScript.js │ │ ├── minifyCss.js │ │ ├── postMessageWithReturnAsync.js │ │ ├── randomUUID.js │ │ ├── removeComments.js │ │ ├── sassToCss.js │ │ └── waterfall.js ├── src │ ├── actions.js │ ├── appUtils │ │ ├── flagDevMode.js │ │ ├── readyStateConstants.js │ │ ├── requestUserViaConsoleToReportUnexpectedError.js │ │ └── siteOrigin.js │ ├── command-palette │ │ ├── command-palette.js │ │ └── getCommands.js │ ├── common-styles │ │ └── common-styles.css │ ├── dialogs │ │ └── searchIcons │ │ │ ├── searchIcons.css │ │ │ ├── searchIcons.js │ │ │ ├── searchIconsConfiguration.css │ │ │ ├── searchIconsConfiguration.js │ │ │ ├── searchUi.css │ │ │ └── searchUi.js │ ├── lib │ │ └── ResponsiveDialog │ │ │ └── ResponsiveDialog.js │ ├── main.js │ ├── node_modules │ │ ├── AfterDelay │ │ │ └── AfterDelay.js │ │ ├── GenericAccordion │ │ │ └── GenericAccordion.js │ │ ├── Loading │ │ │ ├── Loading.css │ │ │ └── Loading.js │ │ ├── constants │ │ │ └── readyStates.js │ │ └── reducers │ │ │ └── actionTypes.js │ ├── options │ │ ├── Main │ │ │ ├── Form │ │ │ │ ├── Form.css │ │ │ │ ├── Form.js │ │ │ │ ├── FormEntries │ │ │ │ │ ├── Autocomplete.js │ │ │ │ │ ├── CodeEditorTheme.js │ │ │ │ │ ├── DefaultMode.js │ │ │ │ │ ├── ExperimentalOptions.js │ │ │ │ │ ├── FontSize.js │ │ │ │ │ ├── Indentation.js │ │ │ │ │ ├── LoadForIframe.js │ │ │ │ │ ├── NotificationsForPin.js │ │ │ │ │ └── Storage.js │ │ │ │ └── helpers.js │ │ │ ├── Main.css │ │ │ ├── Main.js │ │ │ ├── MainTabs.js │ │ │ ├── Tabs │ │ │ │ ├── TabAccount.js │ │ │ │ ├── TabAccount │ │ │ │ │ ├── RegistrationOptions.css │ │ │ │ │ └── RegistrationOptions.js │ │ │ │ ├── TabHelp.css │ │ │ │ ├── TabHelp.js │ │ │ │ └── TabOptions.js │ │ │ └── commonStyles.css │ │ ├── helpers │ │ │ └── helpers.js │ │ ├── options.js │ │ ├── optionsSetup.js │ │ ├── optionsZustandStore.js │ │ └── styles-reset.css │ ├── rootReducer │ │ ├── appReducer │ │ │ ├── appReducer.js │ │ │ ├── commandPaletteReducer │ │ │ │ └── commandPaletteReducer.js │ │ │ └── searchIconsReducer │ │ │ │ └── searchIconsReducer.js │ │ └── rootReducer.js │ └── store.js ├── ui-images │ ├── ban.svg │ ├── ban_edited-white.svg │ ├── ban_edited-yellow.svg │ ├── ban_edited.svg │ ├── close-x_edited-yellow.svg │ ├── close-x_edited.svg │ ├── compress.svg │ ├── copy.svg │ ├── hash.svg │ ├── hash_edited.svg │ ├── icon-login_edited.svg │ ├── icon-plus-yellow_edited.svg │ ├── icon-plus.svg │ ├── icon-settings.svg │ ├── icon-shiny-check-green.svg │ ├── icon-smile.svg │ ├── line-wrap.svg │ ├── line-wrap_edited.svg │ ├── link-external.svg │ ├── link-external_edited-yellow.svg │ ├── link-internal_edited-yellow.svg │ ├── logo-chrome-grayscale.svg │ ├── logo-chrome-grayscale_edited.svg │ ├── logo-chrome-web-store.png │ ├── logo-chrome-web-store.svg │ ├── logo-chrome.svg │ ├── logo-extension-mirror-image.png │ ├── logo-facebook.svg │ ├── logo-facebook_edited.svg │ ├── logo-firefox_edited.png │ ├── logo-github.png │ ├── logo-github_edited.png │ ├── logo-google-chrome.svg │ ├── logo-microsoft-edge-chromium.svg │ ├── logo-microsoft-edge-chromium_edited.svg │ ├── logo-microsoft-edge.svg │ ├── logo-microsoft-edge_edited.svg │ ├── logo-microsoft.svg │ ├── logo-mozilla-add-ons-store.svg │ ├── logo-mozilla-add-ons-store_edited-black.svg │ ├── logo-mozilla-add-ons-store_edited.svg │ ├── logo-mozilla-addons_edited.png │ ├── logo-opera.svg │ ├── logo-thenounproject.svg │ ├── logo-twitter-black.png │ ├── mail.svg │ ├── mail_edited.svg │ ├── pin.svg │ ├── pin_edited.svg │ ├── plus.svg │ ├── plus_edited.svg │ ├── point-and-click.svg │ ├── point-and-click_edited-yellow.svg │ ├── point-and-click_edited.svg │ ├── reload.svg │ ├── reload_edited-yellow.svg │ ├── reload_edited.svg │ ├── settings-server.svg │ ├── settings-server_edited.svg │ ├── settings.svg │ ├── smiley.svg │ ├── sources.txt │ ├── triple-dots.svg │ ├── triple-dots_edited.svg │ ├── unordered-list.svg │ ├── unordered-list_edited.svg │ ├── warning-circle.svg │ ├── warning-circle_edited.svg │ ├── warning.svg │ ├── watch.svg │ ├── watch_edited-yellow.svg │ └── watch_edited.svg └── webpack │ ├── utils │ └── notify-completion-status.js │ └── webpack.config.js ├── extras-for-edge-extension-package └── logos │ ├── icon-150.png │ ├── icon-44.png │ └── icon-50.png ├── live-css ├── .gitignore ├── .npmignore ├── .nvmrc ├── README.md ├── default.live-css.config.js ├── index.js ├── live-css.html ├── nodemon.json ├── package-lock.json ├── package.json ├── scripts │ └── ensure-no-npm-links.sh └── test │ ├── example.css │ ├── index.html │ ├── sample-html │ ├── sample.css │ ├── sample.html │ └── sample2.css │ └── subfolder │ ├── deep-subfolder │ ├── example │ │ ├── .css │ │ ├── .file-name-starting-with-dot.css │ │ ├── .gitignore │ │ ├── css-file-with-invalid-sub-resource-integrity.css │ │ ├── css-file-with-unexpected-extension.mystyles │ │ ├── css-file-without-any-extension │ │ ├── dummy-folder │ │ │ └── file-with-same-name-existing-at-two-different-paths.css │ │ ├── example.html │ │ ├── example2.css │ │ ├── file-not-used.css │ │ ├── file-placed-at-same-level-as-html-file-accessed-with-relative-path.css │ │ ├── file-which-gets-linked-twice.css │ │ ├── file-with-same-name-existing-at-two-different-paths.css │ │ ├── file-with-unicode-character-á.css │ │ ├── file-with-unicode-character-ë.css │ │ ├── node_modules.css │ │ ├── node_modules │ │ │ └── file-placed-in-a-folder-disabled-from-watch-by-default.css │ │ └── styles.css │ └── file-placed-one-level-up-than-html-file-accessed-with-relative-path.css │ └── file-placed-two-levels-up-than-html-file-accessed-with-relative-path.css ├── notes-for-developers.md ├── package-lock.json ├── package.json ├── scripts ├── .gitignore ├── all-is-well.sh ├── build-and-release │ └── prepare-version │ │ └── prepare-version.sh ├── ensure-no-npm-links.sh ├── housekeeping │ └── update-package-lock-json.sh ├── package-lock.json ├── package.json ├── recipes │ └── get-latest-reviews.mjs └── version-consistency-check.js ├── testing-zone ├── child-css.css ├── index.html └── parent-css.css ├── tests ├── .gitignore ├── package-lock.json ├── package.json ├── screenshots-in-multiple-browsers.test.mjs ├── screenshots-in-single-browser.test.mjs ├── screenshots │ ├── .gitignore │ ├── about-to-search-for-arrow-icon-snap.png │ ├── all │ │ └── .gitignore │ ├── command-palette-search-icon-snap.png │ ├── command-palette-snap.png │ ├── focused-input-search-icons-ui-snap.png │ ├── hundred-search-results-and-one-result-selected-snap.png │ ├── joyride-for-search-icons-snap.png │ ├── magic-css-loaded-snap.png │ ├── opened-and-focused-search-icons-configuration-2-snap.png │ ├── opened-and-focused-search-icons-configuration-snap.png │ ├── opened-search-icons-configuration-2-snap.png │ ├── opened-search-icons-configuration-snap.png │ ├── page-1-search-results-for-arrow-icon-snap.png │ ├── search-for-arrow-icon-with-erroneous-configuration-snap.png │ └── search-icons-ui-snap.png └── secrets │ ├── .gitignore │ └── sample-secrets.js ├── utils └── notifications │ ├── icons │ ├── error.png │ ├── info.png │ ├── sources.txt │ └── warning.png │ └── notifications.js └── zip-extension.mjs /.editorconfig: -------------------------------------------------------------------------------- 1 | # This file is provided by the package "node-editorconfig": 2 | # https://github.com/webextensions/node-editorconfig 3 | # https://www.npmjs.com/package/node-editorconfig 4 | # 5 | # References: 6 | # http://editorconfig.org/ (Official Site) 7 | # http://editorconfig.org/#download (Plugins) 8 | # http://davidensinger.com/2013/07/why-i-use-editorconfig/ (Reference) 9 | # https://github.com/eslint/eslint/blob/master/.editorconfig (Sample file) 10 | 11 | # No .editorconfig files above the root directory 12 | root = true 13 | 14 | [*] 15 | charset = utf-8 16 | end_of_line = lf 17 | indent_size = 4 18 | indent_style = space 19 | insert_final_newline = true 20 | trim_trailing_whitespace = true 21 | 22 | [{.nvmrc,*.svg}] 23 | insert_final_newline = false 24 | 25 | [Makefile] 26 | indent_style = tab 27 | 28 | [{package.json,package-lock.json,bower.json,nodemon.json,.babelrc,.travis.yml}] 29 | indent_size = 2 30 | 31 | [{*.markdown,*.md,*.mdown,*.mkd,*.mkdn,*.text}] # https://superuser.com/questions/249436/file-extension-for-markdown-files/285878#285878 32 | trim_trailing_whitespace = false # https://stackoverflow.com/editing-help#linebreaks 33 | 34 | [node_modules/**] 35 | charset = unset 36 | end_of_line = unset 37 | indent_size = unset 38 | indent_style = unset 39 | insert_final_newline = false 40 | trim_trailing_whitespace = false 41 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | # http://eslint.org/docs/user-guide/configuring.html#ignoring-files-and-directories 2 | 3 | # node_modules folders 4 | # -------------------- 5 | 6 | # https://github.com/eslint/eslint/blob/v8.38.0/lib/config/default-config.js#L51 7 | # `!**/node_modules/*` is ignored by default 8 | # Since we are creating handwritten code in some non-npm based node_modules folders (to utilize the module resolution 9 | # algorithm for custom code), we are disabling that ESLint ignore rule to add paths to those folders immediately after 10 | # this. If we don't do this, then we may have to do a weird workaround to enable ESLint for those custom code 11 | # in node_modules paths, like: https://github.com/eslint/eslint/issues/5728#issuecomment-246430604 12 | !**/node_modules/* 13 | 14 | /node_modules/ 15 | /live-css/node_modules/ 16 | /tests/node_modules/ 17 | /scripts/node_modules/ 18 | 19 | # 3rd party code 20 | # -------------- 21 | 22 | extension/scripts/3rdparty/ 23 | 24 | # Generated files 25 | # --------------- 26 | 27 | extension-dist/ 28 | 29 | extension-chrome/ 30 | extension-edge/ 31 | extension-firefox/ 32 | extension-kiwi/ 33 | extension-opera/ 34 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | // http://eslint.org/docs/user-guide/configuring.html 3 | // https://gist.github.com/cletusw/e01a85e399ab563b1236 4 | "env": { 5 | "es2021": true, // https://eslint.org/docs/user-guide/configuring/language-options#specifying-environments 6 | // This automatically sets the ecmaVersion parser option (parserOptions) to 12 7 | "browser": true, 8 | "node": true 9 | }, 10 | 11 | "parserOptions": { 12 | "sourceType": "module", 13 | "ecmaFeatures": { 14 | "jsx": true 15 | } 16 | }, 17 | 18 | "extends": [ 19 | "eslint:recommended", 20 | "plugin:react/recommended" 21 | ], 22 | "plugins": [ 23 | "import" 24 | ], 25 | 26 | // https://eslint.org/docs/latest/use/configure/configuration-files#adding-shared-settings 27 | "settings": { 28 | "react": { 29 | // https://github.com/jsx-eslint/eslint-plugin-react#configuration-legacy-eslintrc 30 | "version": "detect" 31 | } 32 | }, 33 | 34 | "rules": { 35 | "import/no-unresolved": [ 36 | "error", 37 | { 38 | "commonjs": true, 39 | "amd": true 40 | } 41 | ], 42 | // https://eslint.org/docs/latest/rules/no-restricted-globals 43 | "no-restricted-globals": [ 44 | "error", 45 | { 46 | "name": "event", 47 | "message": "Use local parameter instead." 48 | } 49 | ], 50 | "indent": ["error", 4, { "SwitchCase": 1, "ignoreComments": true }], 51 | "linebreak-style": ["error", "unix"], 52 | "semi": ["error", "always"], 53 | // http://eslint.org/docs/rules/quotes 54 | "quotes": "off", 55 | "no-console": "off", 56 | "no-debugger": "off", 57 | "no-shadow": "off" 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /.githooks/logger.mjs: -------------------------------------------------------------------------------- 1 | var chalk; 2 | try { 3 | chalk = (await import('chalk')).default; 4 | } catch (e) { 5 | // do nothing 6 | } 7 | 8 | var boxen; 9 | try { 10 | boxen = (await import('boxen')).default; 11 | } catch (e) { 12 | // do nothing 13 | } 14 | 15 | var stripAnsi; 16 | try { 17 | stripAnsi = (await import('strip-ansi')).default; 18 | } catch (e) { 19 | // do nothing 20 | } 21 | 22 | var logger = { 23 | chalkProxy: function (fnName, msg) { 24 | if (chalk && chalk[fnName]) { 25 | return chalk[fnName](msg); 26 | } else { 27 | return msg; 28 | } 29 | }, 30 | stripAnsi: function (msg) { 31 | if (stripAnsi) { 32 | return stripAnsi(msg); 33 | } else { 34 | return msg; 35 | } 36 | }, 37 | boxen: function (msg, options) { 38 | if (boxen) { 39 | return boxen(msg, options); 40 | } else { 41 | return msg; 42 | } 43 | }, 44 | log: function (msg) { 45 | console.log(msg); 46 | }, 47 | info: function (msg) { 48 | if (chalk) { 49 | msg = chalk.blue(msg); 50 | } 51 | console.log(msg); 52 | }, 53 | warn: function (msg) { 54 | if (chalk) { 55 | msg = chalk.yellow(msg); 56 | } 57 | console.log(msg); 58 | }, 59 | error: function (msg) { 60 | if (chalk) { 61 | msg = chalk.red(msg); 62 | } 63 | console.log(msg); 64 | }, 65 | success: function (msg) { 66 | if (chalk) { 67 | msg = chalk.green(msg); 68 | } 69 | console.log(msg); 70 | } 71 | }; 72 | 73 | export default logger; 74 | -------------------------------------------------------------------------------- /.githooks/post-checkout/post-checkout-check-node-version.mjs: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | // This Git hook finds mismatches between Node version in use and the .nvmrc file and informs the user 4 | 5 | import fs from 'fs'; 6 | import path from 'path'; 7 | 8 | import logger from '../logger.mjs'; 9 | 10 | const __dirname = path.dirname(import.meta.url).replace('file://', ''); 11 | 12 | var nodeVersion = process.versions.node; 13 | try { 14 | var dotNvmrcPath = path.resolve(__dirname, '../../.nvmrc'), 15 | dotNvmrcContents = fs.readFileSync(dotNvmrcPath, 'utf8'); 16 | if(dotNvmrcContents !== nodeVersion) { 17 | logger.log(''); 18 | logger.success(' ✓ .nvmrc suggests: Node JS ' + dotNvmrcContents); 19 | logger.warn(' ✗ You currently use: Node JS ' + nodeVersion); 20 | logger.warn('\nYou might want to run:'); 21 | logger.warn(' $ nvm use\n'); 22 | } 23 | } catch (e) { 24 | logger.warn('\nWarning: Unable to read the .nvmrc file\n'); 25 | } 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Zipped extension files and directories 2 | extension-chrome.zip 3 | extension-chrome/ 4 | extension-edge.zip 5 | extension-edge/ 6 | extension-firefox.zip 7 | extension-firefox/ 8 | extension-kiwi.zip 9 | extension-kiwi/ 10 | extension-opera.zip 11 | extension-opera/ 12 | 13 | # Packaged extension files 14 | *.crx 15 | *.pem 16 | 17 | # Temporary files and directories 18 | tmp 19 | temp 20 | 21 | # Root level "node_modules" directory 22 | # Ensure that "node_modules/" is not enabled elsewhere in this file if we want to allow custom node_modules at sub-level 23 | /node_modules/ 24 | 25 | # Logs 26 | logs 27 | *.log 28 | npm-debug.log* 29 | 30 | # Runtime data 31 | pids 32 | *.pid 33 | *.seed 34 | 35 | # Directory for instrumented libs generated by jscoverage/JSCover 36 | lib-cov 37 | 38 | # Coverage directory used by tools like istanbul 39 | coverage 40 | 41 | # nyc test coverage 42 | .nyc_output 43 | 44 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 45 | .grunt 46 | 47 | # node-waf configuration 48 | .lock-wscript 49 | 50 | # Compiled binary addons (http://nodejs.org/api/addons.html) 51 | build/Release 52 | 53 | # Dependency directories 54 | jspm_packages 55 | 56 | # Optional npm cache directory 57 | .npm 58 | 59 | # Optional REPL history 60 | .node_repl_history 61 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | live-css/.nvmrc -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | // When "search.useIgnoreFiles" is set to false, the search-in-files functionality does not take 3 | // .gitignore into consideration for exclusion 4 | "search.useIgnoreFiles": true, 5 | 6 | // https://github.com/wk-j/vscode-save-and-run#sample-config 7 | "saveAndRun": { 8 | "commands": [ 9 | { 10 | "match": "./extension/manifest-generator.mjs", 11 | "cmd": "./extension/manifest-generator.mjs", 12 | "useShortcut": false, 13 | "silent": true 14 | } 15 | ] 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /FIXME.md: -------------------------------------------------------------------------------- 1 | In `extension/scripts/utils.js`, there is a hacky comment added which says: 2 | 3 | 'This string is added to the end of this file to handle a weird bug/behavior for Firefox. Without this, if "reapply styles automatically" feature is activated, then it would not work and an error would occur in the background script. Reference: https://stackoverflow.com/questions/44567525/inject-scripts-error-script-returned-non-structured-clonable-data-on-firefox-ex/56597154#56597154'; 4 | 5 | Check the behavior before / after the ongoing `import` based refactoring. 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 webextensions 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /PRIVACY-POLICY.md: -------------------------------------------------------------------------------- 1 | # Privacy Policy 2 | This browser extension, "Magic CSS" (also known as "MagiCSS", "Live editor for CSS and LESS", "Live editor for CSS, Less & Sass") may use the following forms of storage: 3 | - localStorage 4 | - sessionStorage 5 | - cookies 6 | - browser storage local 7 | - browser storage sync 8 | 9 | #### Notes 10 | * The data stored in the above mentioned forms is used only for the extension's functionalities, i.e., extension's settings and the data generated by the user by using this extension. 11 | * No personally identifiable data is stored by this extension. 12 | * The stored data is not recorded/shared anywhere online by the extension. 13 | * If the user has setup "browser storage sync" in their browser, then some of the stored data would be accessible across user's own browser instances as per the way their browser works. 14 | * The stored data is not used/shared anywhere outside the purposes of this extension. 15 | 16 | In case you have any further queries, you may get more information or contact us via https://github.com/webextensions/live-css-editor :-) 17 | -------------------------------------------------------------------------------- /documents/extension-media/screenshots/archived/screenshot-wikipedia.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/live-css-editor/f2d3df6709ec8bd6662bbb58a6bc89a4c4377975/documents/extension-media/screenshots/archived/screenshot-wikipedia.jpg -------------------------------------------------------------------------------- /documents/extension-media/screenshots/screenshot-wikipedia.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/live-css-editor/f2d3df6709ec8bd6662bbb58a6bc89a4c4377975/documents/extension-media/screenshots/screenshot-wikipedia.png -------------------------------------------------------------------------------- /extension-dist/.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore all files 2 | 3 | # With extension 4 | *.* 5 | 6 | # Without extension 7 | # It also helps in graying out the folders in the code editor's explorer having Git integration (eg: VS Code) 8 | * 9 | 10 | # Don't ignore the .gitignore file 11 | !.gitignore 12 | -------------------------------------------------------------------------------- /extension/_locales/en/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "Extension_Description": { 3 | "message": "Live preview of CSS/Less/Sass code changes. Auto-save file, autocomplete, Less/Sass to CSS, beautify, CSS reloader, lint, ..." 4 | }, 5 | "Extension_Name": { 6 | "message": "Live editor for CSS, Less & Sass - Magic CSS" 7 | }, 8 | "Include_CanRunOnOtherPages": { 9 | "message": "You can run it on other websites and web pages." 10 | }, 11 | "Include_GrantPermisssions": { 12 | "message": "And grant permissions by enabling \"Allow access to file URLs\" for this extension" 13 | }, 14 | "Include_MagicssDoesNotOperateOnSomeTabs": { 15 | "message": "For security reasons, Magic CSS does not run on:" 16 | }, 17 | "Include_RequiresYourPermission": { 18 | "message": "It requires your permission to execute on:" 19 | }, 20 | "Include_ToExecuteMagicssEditor": { 21 | "message": "To execute Live editor for CSS, Less & Sass (Magic CSS) on:" 22 | }, 23 | "Include_UnableToStart": { 24 | "message": "Unable to start" 25 | }, 26 | "Include_YouNeedToGoTo": { 27 | "message": "You need to go to:" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /extension/alert.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Live editor for CSS, Less & Sass - Magic CSS 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /extension/alert.js: -------------------------------------------------------------------------------- 1 | // Read query parameter `message` and alert it 2 | // This is used to show notification from background page 3 | 4 | const url = new URL(location.href); 5 | const message = url.searchParams.get('message'); 6 | if (message) { 7 | alert(message); 8 | } 9 | -------------------------------------------------------------------------------- /extension/background-magicss.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Live editor for CSS, Less & Sass - Magic CSS 8 | 9 | 16 | 17 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | Live editor for CSS, Less & Sass - Magic CSS 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /extension/background-magicss.js: -------------------------------------------------------------------------------- 1 | import './scripts/actions.js'; 2 | import './scripts/background-magicss-include.js'; 3 | import './scripts/background-operations.js'; 4 | -------------------------------------------------------------------------------- /extension/commonAppUtils/detectEnvironment.js: -------------------------------------------------------------------------------- 1 | /* global chrome */ 2 | 3 | let flagRunningInKiwiExtensionLikeEnvironment = null; 4 | const runningInKiwiExtensionLikeEnvironment = function () { 5 | if (flagRunningInKiwiExtensionLikeEnvironment !== null) { 6 | return flagRunningInKiwiExtensionLikeEnvironment; 7 | } 8 | 9 | // An error shouldn't occur. This try...catch block is just for extra safety. 10 | try { 11 | const manifest = chrome.runtime.getManifest(); 12 | if (manifest.name.indexOf('Kiwi Browser') !== -1) { 13 | flagRunningInKiwiExtensionLikeEnvironment = true; 14 | } else { 15 | flagRunningInKiwiExtensionLikeEnvironment = false; 16 | } 17 | } catch (e) { 18 | flagRunningInKiwiExtensionLikeEnvironment = false; 19 | } 20 | 21 | return flagRunningInKiwiExtensionLikeEnvironment; 22 | }; 23 | 24 | export { 25 | runningInKiwiExtensionLikeEnvironment 26 | }; 27 | -------------------------------------------------------------------------------- /extension/commonAppUtils/theWin.js: -------------------------------------------------------------------------------- 1 | let theWin; 2 | 3 | if (typeof window !== 'undefined') { 4 | theWin = window; 5 | } else { 6 | theWin = {}; 7 | } 8 | 9 | export { theWin }; 10 | 11 | /* 12 | const theWin = {}; 13 | 14 | export { theWin }; 15 | */ 16 | -------------------------------------------------------------------------------- /extension/commonAppUtils/updateConfigFromRemoteForNextLoad.js: -------------------------------------------------------------------------------- 1 | import { updateConfigFromRemoteForNextLoad } from './instanceAndFeatures.js'; 2 | 3 | (async () => { 4 | await updateConfigFromRemoteForNextLoad(); 5 | })(); 6 | -------------------------------------------------------------------------------- /extension/constants.js: -------------------------------------------------------------------------------- 1 | // TODO: Share constants across files (like magicss.js, editor.js and options.js) (probably keep them in a separate file as global variables) 2 | 3 | export const 4 | USER_PREFERENCE_AUTOCOMPLETE_SELECTORS = 'autocomplete-css-selectors', 5 | USER_PREFERENCE_AUTOCOMPLETE_CSS_PROPERTIES_AND_VALUES = 'autocomplete-css-properties-and-values', 6 | USER_PREFERENCE_ALL_FRAMES = 'all-frames', 7 | USER_PREFERENCE_SHOW_REAPPLYING_STYLES_NOTIFICATION = 'show-reapplying-styles-notification', 8 | USER_PREFERENCE_SHOW_REAPPLYING_STYLES_NOTIFICATION_AT = 'show-reapplying-styles-notification-at', 9 | USER_PREFERENCE_USE_CUSTOM_FONT_SIZE = 'use-custom-font-size', 10 | USER_PREFERENCE_FONT_SIZE_IN_PX = 'font-size-in-px', 11 | USER_PREFERENCE_STORAGE_MODE = 'storage-mode', 12 | USER_PREFERENCE_THEME = 'theme', 13 | USER_PREFERENCE_HIDE_ON_PAGE_MOUSEOUT = 'hide-on-page-mouseout', 14 | USER_PREFERENCE_USE_SASS_SYNTAX = 'use-sass-syntax'; 15 | -------------------------------------------------------------------------------- /extension/external-editor-base.js: -------------------------------------------------------------------------------- 1 | import { myWin } from './scripts/appUtils/myWin.js'; 2 | 3 | (function () { 4 | try { 5 | const 6 | urlParams = new URLSearchParams(window.location.search), 7 | tabTitle = urlParams.get('tabTitle'); 8 | if (tabTitle) { 9 | document.title = 'Magic CSS: ' + tabTitle; 10 | } else { 11 | document.title = 'Magic CSS'; 12 | } 13 | } catch (e) { 14 | // do nothing 15 | } 16 | 17 | myWin.flagEditorInExternalWindow = true; 18 | myWin.treatAsNormalWebpage = true; 19 | })(); 20 | -------------------------------------------------------------------------------- /extension/external-editor.css: -------------------------------------------------------------------------------- 1 | .full-screen-editor { 2 | background-color: #294a75; 3 | } 4 | 5 | .full-screen-editor #MagiCSS-bookmarklet { 6 | border-radius: 0 !important; 7 | 8 | left: 0 !important; 9 | top: 0 !important; 10 | } 11 | -------------------------------------------------------------------------------- /extension/external-editor.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Live editor for CSS, Less & Sass - Magic CSS 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /extension/icons/archived/icon-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/live-css-editor/f2d3df6709ec8bd6662bbb58a6bc89a4c4377975/extension/icons/archived/icon-128.png -------------------------------------------------------------------------------- /extension/icons/archived/icon-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/live-css-editor/f2d3df6709ec8bd6662bbb58a6bc89a4c4377975/extension/icons/archived/icon-16.png -------------------------------------------------------------------------------- /extension/icons/archived/icon-24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/live-css-editor/f2d3df6709ec8bd6662bbb58a6bc89a4c4377975/extension/icons/archived/icon-24.png -------------------------------------------------------------------------------- /extension/icons/archived/icon-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/live-css-editor/f2d3df6709ec8bd6662bbb58a6bc89a4c4377975/extension/icons/archived/icon-256.png -------------------------------------------------------------------------------- /extension/icons/archived/icon-256.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /extension/icons/archived/icon-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/live-css-editor/f2d3df6709ec8bd6662bbb58a6bc89a4c4377975/extension/icons/archived/icon-32.png -------------------------------------------------------------------------------- /extension/icons/archived/icon-40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/live-css-editor/f2d3df6709ec8bd6662bbb58a6bc89a4c4377975/extension/icons/archived/icon-40.png -------------------------------------------------------------------------------- /extension/icons/archived/icon-48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/live-css-editor/f2d3df6709ec8bd6662bbb58a6bc89a4c4377975/extension/icons/archived/icon-48.png -------------------------------------------------------------------------------- /extension/icons/archived/icon-64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/live-css-editor/f2d3df6709ec8bd6662bbb58a6bc89a4c4377975/extension/icons/archived/icon-64.png -------------------------------------------------------------------------------- /extension/icons/archived/icon-dark-scheme-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/live-css-editor/f2d3df6709ec8bd6662bbb58a6bc89a4c4377975/extension/icons/archived/icon-dark-scheme-128.png -------------------------------------------------------------------------------- /extension/icons/archived/icon-dark-scheme-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/live-css-editor/f2d3df6709ec8bd6662bbb58a6bc89a4c4377975/extension/icons/archived/icon-dark-scheme-16.png -------------------------------------------------------------------------------- /extension/icons/archived/icon-dark-scheme-24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/live-css-editor/f2d3df6709ec8bd6662bbb58a6bc89a4c4377975/extension/icons/archived/icon-dark-scheme-24.png -------------------------------------------------------------------------------- /extension/icons/archived/icon-dark-scheme-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/live-css-editor/f2d3df6709ec8bd6662bbb58a6bc89a4c4377975/extension/icons/archived/icon-dark-scheme-256.png -------------------------------------------------------------------------------- /extension/icons/archived/icon-dark-scheme-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/live-css-editor/f2d3df6709ec8bd6662bbb58a6bc89a4c4377975/extension/icons/archived/icon-dark-scheme-32.png -------------------------------------------------------------------------------- /extension/icons/archived/icon-dark-scheme-40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/live-css-editor/f2d3df6709ec8bd6662bbb58a6bc89a4c4377975/extension/icons/archived/icon-dark-scheme-40.png -------------------------------------------------------------------------------- /extension/icons/archived/icon-dark-scheme-48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/live-css-editor/f2d3df6709ec8bd6662bbb58a6bc89a4c4377975/extension/icons/archived/icon-dark-scheme-48.png -------------------------------------------------------------------------------- /extension/icons/archived/icon-dark-scheme-64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/live-css-editor/f2d3df6709ec8bd6662bbb58a6bc89a4c4377975/extension/icons/archived/icon-dark-scheme-64.png -------------------------------------------------------------------------------- /extension/icons/generate-icons.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -x 4 | 5 | cd "$(dirname "$0")" 6 | 7 | # https://stackoverflow.com/questions/9853325/how-to-convert-a-svg-to-a-png-with-imagemagick/14174624#14174624 8 | 9 | # Inkscape v1.0+ 10 | # inkscape -w 256 -h 256 icon-256.svg -o icon-256.png 11 | 12 | # Inkscape older than v1.0 13 | inkscape -z -w 256 -h 256 icon-256.svg -e icon-256.png 14 | inkscape -z -w 128 -h 128 icon-256.svg -e icon-128.png 15 | inkscape -z -w 64 -h 64 icon-256.svg -e icon-64.png 16 | inkscape -z -w 48 -h 48 icon-256.svg -e icon-48.png 17 | inkscape -z -w 40 -h 40 icon-256.svg -e icon-40.png 18 | inkscape -z -w 32 -h 32 icon-256.svg -e icon-32.png 19 | inkscape -z -w 24 -h 24 icon-256.svg -e icon-24.png 20 | inkscape -z -w 16 -h 16 icon-256.svg -e icon-16.png 21 | -------------------------------------------------------------------------------- /extension/icons/icon-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/live-css-editor/f2d3df6709ec8bd6662bbb58a6bc89a4c4377975/extension/icons/icon-128.png -------------------------------------------------------------------------------- /extension/icons/icon-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/live-css-editor/f2d3df6709ec8bd6662bbb58a6bc89a4c4377975/extension/icons/icon-16.png -------------------------------------------------------------------------------- /extension/icons/icon-24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/live-css-editor/f2d3df6709ec8bd6662bbb58a6bc89a4c4377975/extension/icons/icon-24.png -------------------------------------------------------------------------------- /extension/icons/icon-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/live-css-editor/f2d3df6709ec8bd6662bbb58a6bc89a4c4377975/extension/icons/icon-256.png -------------------------------------------------------------------------------- /extension/icons/icon-256.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /extension/icons/icon-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/live-css-editor/f2d3df6709ec8bd6662bbb58a6bc89a4c4377975/extension/icons/icon-32.png -------------------------------------------------------------------------------- /extension/icons/icon-40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/live-css-editor/f2d3df6709ec8bd6662bbb58a6bc89a4c4377975/extension/icons/icon-40.png -------------------------------------------------------------------------------- /extension/icons/icon-48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/live-css-editor/f2d3df6709ec8bd6662bbb58a6bc89a4c4377975/extension/icons/icon-48.png -------------------------------------------------------------------------------- /extension/icons/icon-64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/live-css-editor/f2d3df6709ec8bd6662bbb58a6bc89a4c4377975/extension/icons/icon-64.png -------------------------------------------------------------------------------- /extension/manifest-chrome.json: -------------------------------------------------------------------------------- 1 | { 2 | "action": { 3 | "default_icon": { 4 | "16": "icons/icon-16.png", 5 | "24": "icons/icon-24.png", 6 | "32": "icons/icon-32.png", 7 | "40": "icons/icon-40.png", 8 | "48": "icons/icon-48.png", 9 | "128": "icons/icon-128.png", 10 | "256": "icons/icon-256.png" 11 | }, 12 | "default_title": "Launch Magic CSS editor for this page" 13 | }, 14 | "author": "Priyank Parashar", 15 | "background": { 16 | "service_worker": "dist/background-magicss/background-magicss.bundle.js" 17 | }, 18 | "commands": { 19 | "_execute_action": { 20 | "suggested_key": { 21 | "default": "Alt+Shift+C" 22 | } 23 | } 24 | }, 25 | "content_security_policy": { 26 | "extension_pages": "script-src 'self'; object-src 'self'" 27 | }, 28 | "default_locale": "en", 29 | "description": "__MSG_Extension_Description__", 30 | "homepage_url": "https://github.com/webextensions/live-css-editor", 31 | "icons": { 32 | "16": "icons/icon-16.png", 33 | "24": "icons/icon-24.png", 34 | "32": "icons/icon-32.png", 35 | "40": "icons/icon-40.png", 36 | "48": "icons/icon-48.png", 37 | "128": "icons/icon-128.png", 38 | "256": "icons/icon-256.png" 39 | }, 40 | "manifest_version": 3, 41 | "minimum_chrome_version": "102", 42 | "name": "__MSG_Extension_Name__", 43 | "offline_enabled": true, 44 | "optional_host_permissions": [ 45 | "*://*/*" 46 | ], 47 | "optional_permissions": [ 48 | "webNavigation" 49 | ], 50 | "options_ui": { 51 | "open_in_tab": true, 52 | "page": "options.html" 53 | }, 54 | "permissions": [ 55 | "activeTab", 56 | "storage", 57 | "unlimitedStorage", 58 | "scripting", 59 | "offscreen" 60 | ], 61 | "version": "8.22.5" 62 | } 63 | -------------------------------------------------------------------------------- /extension/manifest-edge.json: -------------------------------------------------------------------------------- 1 | { 2 | "action": { 3 | "default_icon": { 4 | "16": "icons/icon-16.png", 5 | "24": "icons/icon-24.png", 6 | "32": "icons/icon-32.png", 7 | "40": "icons/icon-40.png", 8 | "48": "icons/icon-48.png", 9 | "128": "icons/icon-128.png", 10 | "256": "icons/icon-256.png" 11 | }, 12 | "default_title": "Launch Magic CSS editor for this page" 13 | }, 14 | "author": "Priyank Parashar", 15 | "background": { 16 | "service_worker": "dist/background-magicss/background-magicss.bundle.js" 17 | }, 18 | "commands": { 19 | "_execute_action": { 20 | "suggested_key": { 21 | "default": "Alt+Shift+C" 22 | } 23 | } 24 | }, 25 | "content_security_policy": { 26 | "extension_pages": "script-src 'self'; object-src 'self'" 27 | }, 28 | "default_locale": "en", 29 | "description": "__MSG_Extension_Description__", 30 | "homepage_url": "https://github.com/webextensions/live-css-editor", 31 | "icons": { 32 | "16": "icons/icon-16.png", 33 | "24": "icons/icon-24.png", 34 | "32": "icons/icon-32.png", 35 | "40": "icons/icon-40.png", 36 | "48": "icons/icon-48.png", 37 | "128": "icons/icon-128.png", 38 | "256": "icons/icon-256.png" 39 | }, 40 | "manifest_version": 3, 41 | "name": "__MSG_Extension_Name__", 42 | "offline_enabled": true, 43 | "optional_host_permissions": [ 44 | "*://*/*" 45 | ], 46 | "optional_permissions": [ 47 | "webNavigation" 48 | ], 49 | "options_ui": { 50 | "open_in_tab": true, 51 | "page": "options.html" 52 | }, 53 | "permissions": [ 54 | "activeTab", 55 | "storage", 56 | "unlimitedStorage", 57 | "scripting", 58 | "offscreen" 59 | ], 60 | "version": "8.22.5" 61 | } 62 | -------------------------------------------------------------------------------- /extension/manifest-firefox.json: -------------------------------------------------------------------------------- 1 | { 2 | "action": { 3 | "default_icon": { 4 | "16": "icons/icon-16.png", 5 | "24": "icons/icon-24.png", 6 | "32": "icons/icon-32.png", 7 | "40": "icons/icon-40.png", 8 | "48": "icons/icon-48.png", 9 | "128": "icons/icon-128.png", 10 | "256": "icons/icon-256.png" 11 | }, 12 | "default_title": "Launch Magic CSS editor for this page" 13 | }, 14 | "applications": { 15 | "gecko": { 16 | "id": "{a42eb16c-2fab-4c06-b1f3-5f15adebb0e3}", 17 | "strict_min_version": "48.0" 18 | } 19 | }, 20 | "author": "Priyank Parashar", 21 | "background": { 22 | "service_worker": "dist/background-magicss/background-magicss.bundle.js" 23 | }, 24 | "commands": { 25 | "_execute_action": { 26 | "suggested_key": { 27 | "default": "Alt+Shift+C" 28 | } 29 | } 30 | }, 31 | "content_security_policy": { 32 | "extension_pages": "script-src 'self'; object-src 'self'" 33 | }, 34 | "default_locale": "en", 35 | "description": "__MSG_Extension_Description__", 36 | "homepage_url": "https://github.com/webextensions/live-css-editor", 37 | "icons": { 38 | "16": "icons/icon-16.png", 39 | "24": "icons/icon-24.png", 40 | "32": "icons/icon-32.png", 41 | "40": "icons/icon-40.png", 42 | "48": "icons/icon-48.png", 43 | "128": "icons/icon-128.png", 44 | "256": "icons/icon-256.png" 45 | }, 46 | "manifest_version": 3, 47 | "name": "__MSG_Extension_Name__", 48 | "optional_host_permissions": [ 49 | "*://*/*" 50 | ], 51 | "optional_permissions": [], 52 | "options_ui": { 53 | "open_in_tab": true, 54 | "page": "options.html" 55 | }, 56 | "permissions": [ 57 | "activeTab", 58 | "storage", 59 | "unlimitedStorage", 60 | "scripting", 61 | "offscreen", 62 | "webNavigation" 63 | ], 64 | "version": "8.22.5" 65 | } 66 | -------------------------------------------------------------------------------- /extension/manifest-kiwi.json: -------------------------------------------------------------------------------- 1 | { 2 | "action": { 3 | "default_icon": { 4 | "16": "icons/icon-16.png", 5 | "24": "icons/icon-24.png", 6 | "32": "icons/icon-32.png", 7 | "40": "icons/icon-40.png", 8 | "48": "icons/icon-48.png", 9 | "128": "icons/icon-128.png", 10 | "256": "icons/icon-256.png" 11 | }, 12 | "default_title": "Launch Magic CSS editor for this page" 13 | }, 14 | "author": "Priyank Parashar", 15 | "background": { 16 | "service_worker": "dist/background-magicss/background-magicss.bundle.js" 17 | }, 18 | "commands": { 19 | "_execute_action": { 20 | "suggested_key": { 21 | "default": "Alt+Shift+C" 22 | } 23 | } 24 | }, 25 | "content_security_policy": { 26 | "extension_pages": "script-src 'self'; object-src 'self'" 27 | }, 28 | "default_locale": "en", 29 | "description": "__MSG_Extension_Description__", 30 | "homepage_url": "https://github.com/webextensions/live-css-editor", 31 | "host_permissions": [ 32 | "*://*/*" 33 | ], 34 | "icons": { 35 | "16": "icons/icon-16.png", 36 | "24": "icons/icon-24.png", 37 | "32": "icons/icon-32.png", 38 | "40": "icons/icon-40.png", 39 | "48": "icons/icon-48.png", 40 | "128": "icons/icon-128.png", 41 | "256": "icons/icon-256.png" 42 | }, 43 | "manifest_version": 3, 44 | "name": "__MSG_Extension_Name__ for Kiwi Browser", 45 | "offline_enabled": true, 46 | "optional_permissions": [], 47 | "options_ui": { 48 | "open_in_tab": true, 49 | "page": "options.html" 50 | }, 51 | "permissions": [ 52 | "activeTab", 53 | "storage", 54 | "unlimitedStorage", 55 | "scripting", 56 | "offscreen", 57 | "webNavigation" 58 | ], 59 | "version": "8.22.5" 60 | } 61 | -------------------------------------------------------------------------------- /extension/manifest-opera.json: -------------------------------------------------------------------------------- 1 | { 2 | "action": { 3 | "default_icon": { 4 | "16": "icons/icon-16.png", 5 | "24": "icons/icon-24.png", 6 | "32": "icons/icon-32.png", 7 | "40": "icons/icon-40.png", 8 | "48": "icons/icon-48.png", 9 | "128": "icons/icon-128.png", 10 | "256": "icons/icon-256.png" 11 | }, 12 | "default_title": "Launch Magic CSS editor for this page" 13 | }, 14 | "author": "Priyank Parashar", 15 | "background": { 16 | "service_worker": "dist/background-magicss/background-magicss.bundle.js" 17 | }, 18 | "commands": { 19 | "_execute_action": { 20 | "suggested_key": { 21 | "default": "Alt+Shift+C" 22 | } 23 | } 24 | }, 25 | "content_security_policy": { 26 | "extension_pages": "script-src 'self'; object-src 'self'" 27 | }, 28 | "default_locale": "en", 29 | "description": "__MSG_Extension_Description__", 30 | "homepage_url": "https://github.com/webextensions/live-css-editor", 31 | "icons": { 32 | "16": "icons/icon-16.png", 33 | "24": "icons/icon-24.png", 34 | "32": "icons/icon-32.png", 35 | "40": "icons/icon-40.png", 36 | "48": "icons/icon-48.png", 37 | "128": "icons/icon-128.png", 38 | "256": "icons/icon-256.png" 39 | }, 40 | "manifest_version": 3, 41 | "name": "__MSG_Extension_Name__", 42 | "offline_enabled": true, 43 | "optional_host_permissions": [ 44 | "*://*/*" 45 | ], 46 | "optional_permissions": [ 47 | "webNavigation" 48 | ], 49 | "options_ui": { 50 | "open_in_tab": true, 51 | "page": "options.html" 52 | }, 53 | "permissions": [ 54 | "activeTab", 55 | "storage", 56 | "unlimitedStorage", 57 | "scripting", 58 | "offscreen" 59 | ], 60 | "version": "8.22.5" 61 | } 62 | -------------------------------------------------------------------------------- /extension/manifest-puppeteer.json: -------------------------------------------------------------------------------- 1 | { 2 | "__custom__": { 3 | "hideRateUsHeaderIcon": true 4 | }, 5 | "action": { 6 | "default_icon": { 7 | "16": "icons/icon-16.png", 8 | "24": "icons/icon-24.png", 9 | "32": "icons/icon-32.png", 10 | "40": "icons/icon-40.png", 11 | "48": "icons/icon-48.png", 12 | "128": "icons/icon-128.png", 13 | "256": "icons/icon-256.png" 14 | }, 15 | "default_title": "Launch Magic CSS editor for this page" 16 | }, 17 | "author": "Priyank Parashar", 18 | "background": { 19 | "service_worker": "dist/background-magicss/background-magicss.bundle.js" 20 | }, 21 | "commands": { 22 | "_execute_action": { 23 | "suggested_key": { 24 | "default": "Alt+Shift+C" 25 | } 26 | } 27 | }, 28 | "default_locale": "en", 29 | "description": "__MSG_Extension_Description__", 30 | "homepage_url": "https://github.com/webextensions/live-css-editor", 31 | "icons": { 32 | "16": "icons/icon-16.png", 33 | "24": "icons/icon-24.png", 34 | "32": "icons/icon-32.png", 35 | "40": "icons/icon-40.png", 36 | "48": "icons/icon-48.png", 37 | "128": "icons/icon-128.png", 38 | "256": "icons/icon-256.png" 39 | }, 40 | "manifest_version": 3, 41 | "name": "__MSG_Extension_Name__", 42 | "offline_enabled": true, 43 | "optional_host_permissions": [ 44 | "*://*/*" 45 | ], 46 | "optional_permissions": [ 47 | "webNavigation" 48 | ], 49 | "options_ui": { 50 | "open_in_tab": true, 51 | "page": "options.html" 52 | }, 53 | "permissions": [ 54 | "activeTab", 55 | "storage", 56 | "unlimitedStorage", 57 | "scripting", 58 | "offscreen" 59 | ], 60 | "version": "8.22.5" 61 | } 62 | -------------------------------------------------------------------------------- /extension/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "action": { 3 | "default_icon": { 4 | "16": "icons/icon-16.png", 5 | "24": "icons/icon-24.png", 6 | "32": "icons/icon-32.png", 7 | "40": "icons/icon-40.png", 8 | "48": "icons/icon-48.png", 9 | "128": "icons/icon-128.png", 10 | "256": "icons/icon-256.png" 11 | }, 12 | "default_title": "Launch Magic CSS editor for this page" 13 | }, 14 | "author": "Priyank Parashar", 15 | "background": { 16 | "service_worker": "dist/background-magicss/background-magicss.bundle.js" 17 | }, 18 | "commands": { 19 | "_execute_action": { 20 | "suggested_key": { 21 | "default": "Alt+Shift+C" 22 | } 23 | } 24 | }, 25 | "content_security_policy": { 26 | "extension_pages": "script-src 'self'; object-src 'self'" 27 | }, 28 | "default_locale": "en", 29 | "description": "__MSG_Extension_Description__", 30 | "homepage_url": "https://github.com/webextensions/live-css-editor", 31 | "icons": { 32 | "16": "icons/icon-16.png", 33 | "24": "icons/icon-24.png", 34 | "32": "icons/icon-32.png", 35 | "40": "icons/icon-40.png", 36 | "48": "icons/icon-48.png", 37 | "128": "icons/icon-128.png", 38 | "256": "icons/icon-256.png" 39 | }, 40 | "manifest_version": 3, 41 | "minimum_chrome_version": "102", 42 | "name": "__MSG_Extension_Name__", 43 | "offline_enabled": true, 44 | "optional_host_permissions": [ 45 | "*://*/*" 46 | ], 47 | "optional_permissions": [ 48 | "webNavigation" 49 | ], 50 | "options_ui": { 51 | "open_in_tab": true, 52 | "page": "options.html" 53 | }, 54 | "permissions": [ 55 | "activeTab", 56 | "storage", 57 | "unlimitedStorage", 58 | "scripting", 59 | "offscreen" 60 | ], 61 | "version": "8.22.5" 62 | } 63 | -------------------------------------------------------------------------------- /extension/options.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Live editor for CSS, Less & Sass - Magic CSS 8 | 9 | 83 | 84 | 85 | 86 |
87 | 88 | 89 | 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /extension/scripts/3rdparty-custom-fixes/codemirror/addons/lint/tooltip.css: -------------------------------------------------------------------------------- 1 | /* Increased CSS specificity by including "html" in the CSS selector to override site-specific CSS for https://github.com/webextensions/live-css-editor */ 2 | html .CodeMirror-lint-tooltip { 3 | z-index: 2147483600; 4 | } 5 | -------------------------------------------------------------------------------- /extension/scripts/3rdparty-custom-fixes/codemirror/codemirror-as-global.js: -------------------------------------------------------------------------------- 1 | import CodeMirror from '../../3rdparty/codemirror/codemirror.js'; 2 | 3 | window.CodeMirror = CodeMirror; 4 | -------------------------------------------------------------------------------- /extension/scripts/3rdparty-custom-fixes/codemirror/magicss-codemirror.css: -------------------------------------------------------------------------------- 1 | html:not(.full-screen-editor) #MagiCSS-bookmarklet .CodeMirror-hscrollbar { 2 | right: 15px !important; 3 | } 4 | html:not(.full-screen-editor) #MagiCSS-bookmarklet .CodeMirror-vscrollbar { 5 | bottom: 0px !important; 6 | margin-bottom: 15px; 7 | padding-right: 15px; 8 | } 9 | 10 | html:not(.full-screen-editor) #MagiCSS-bookmarklet .codemirror-hscrollbar { 11 | overflow-x: auto; 12 | } 13 | html:not(.full-screen-editor) #MagiCSS-bookmarklet .codemirror-vscrollbar { 14 | overflow-y: auto; 15 | } 16 | 17 | #MagiCSS-bookmarklet { 18 | width: auto; 19 | } 20 | 21 | #MagiCSS-bookmarklet .CodeMirror-activeline-background { 22 | background: rgba(128, 128, 128, 0.15); 23 | } 24 | 25 | html .CodeMirror-hints { 26 | z-index: 2147483600; 27 | } 28 | 29 | .full-screen-editor .CodeMirror-hints { 30 | /* 31 | Overriding: 32 | .CodeMirror-hints { max-height: 20em; } 33 | Details: 34 | To avoid scrollbar going beyond the window size. 35 | Applicable when the window size is particularly small. 36 | Without this, in full-screen-editor (external editor window), these hints may lead to scrollbar in page overall. 37 | */ 38 | max-height: min(40vh, 20em); 39 | 40 | /* Useful in avoiding full page horizontal scrollbar when editor is open in external window and the autocomplete 41 | suggestions list is too wide */ 42 | max-width: 90vw; 43 | } 44 | -------------------------------------------------------------------------------- /extension/scripts/3rdparty-custom-fixes/csslint/ignore-some-rules.js: -------------------------------------------------------------------------------- 1 | /* global CSSLint */ 2 | 3 | (function () { 4 | var originalRules = CSSLint.getRules(), 5 | rulesToIgnore = [ 6 | 'box-model', 7 | 'adjoining-classes', 8 | 'box-sizing', 9 | 'compatible-vendor-prefixes', 10 | 'gradients', 11 | 'fallback-colors', 12 | 'bulletproof-font-face', 13 | 'regex-selectors', 14 | 'overqualified-elements', 15 | 'shorthand', 16 | 'duplicate-background-images', 17 | 'floats', 18 | 'font-sizes', 19 | 'ids', 20 | 'order-alphabetical' 21 | ], 22 | newRules = originalRules.filter(function (rule) { 23 | if (rulesToIgnore.indexOf(rule.id) >= 0) { 24 | return false; 25 | } 26 | return true; 27 | }); 28 | 29 | CSSLint.clearRules(); 30 | newRules.forEach(function (rule) { 31 | CSSLint.addRule(rule); 32 | }); 33 | }()); 34 | -------------------------------------------------------------------------------- /extension/scripts/3rdparty-custom-fixes/csspretty/pre-csspretty.js: -------------------------------------------------------------------------------- 1 | /*eslint-disable no-unused-vars */ 2 | var global = {}; 3 | /*eslint-enable no-unused-vars */ 4 | -------------------------------------------------------------------------------- /extension/scripts/3rdparty-custom-fixes/jquery/jquery-as-global.js: -------------------------------------------------------------------------------- 1 | import * as jQuery from '../../3rdparty/jquery.js'; 2 | 3 | window.jQuery = jQuery; 4 | window.$ = jQuery; 5 | -------------------------------------------------------------------------------- /extension/scripts/3rdparty-custom-fixes/socket.io/socket.io-as-global.js: -------------------------------------------------------------------------------- 1 | // import { io } from '../../3rdparty/socket.io/socket.io.slim.js'; 2 | import { io } from '../../3rdparty/socket.io/socket.io.slim.dev.js'; 3 | 4 | window.io = io; 5 | -------------------------------------------------------------------------------- /extension/scripts/3rdparty/.editorconfig: -------------------------------------------------------------------------------- 1 | # References: 2 | # http://editorconfig.org/ (Official Site) 3 | # http://editorconfig.org/#download (Plugins) 4 | # http://davidensinger.com/2013/07/why-i-use-editorconfig/ (Reference) 5 | # https://github.com/eslint/eslint/blob/master/.editorconfig (Sample file) 6 | 7 | [*] 8 | charset = unset 9 | end_of_line = unset 10 | indent_size = unset 11 | indent_style = unset 12 | insert_final_newline = false 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /extension/scripts/3rdparty/amplify-store.js.source.txt: -------------------------------------------------------------------------------- 1 | https://raw.githubusercontent.com/mikehostetler/amplify/1.1.2/src/store.js -------------------------------------------------------------------------------- /extension/scripts/3rdparty/basic-less-with-sourcemap-support.browserified.js.source.txt: -------------------------------------------------------------------------------- 1 | https://raw.githubusercontent.com/webextensions/less.js/1bf6a495a11dee77bb0f773149ff6261a4718c4d/packages/less/dist/basic-less-with-sourcemap-support.browserified.js -------------------------------------------------------------------------------- /extension/scripts/3rdparty/codemirror/addons/colorpicker/colorpicker.css.source.txt: -------------------------------------------------------------------------------- 1 | https://raw.githubusercontent.com/easylogic/codemirror-colorpicker/v1.0.10/addon/colorpicker/colorpicker.css -------------------------------------------------------------------------------- /extension/scripts/3rdparty/codemirror/addons/colorpicker/colorpicker.js.source.txt: -------------------------------------------------------------------------------- 1 | https://raw.githubusercontent.com/easylogic/codemirror-colorpicker/v1.0.10/addon/colorpicker/colorpicker.js -------------------------------------------------------------------------------- /extension/scripts/3rdparty/codemirror/addons/colorpicker/colorview.js.source.txt: -------------------------------------------------------------------------------- 1 | https://raw.githubusercontent.com/easylogic/codemirror-colorpicker/v1.0.10/addon/colorpicker/colorview.js -------------------------------------------------------------------------------- /extension/scripts/3rdparty/codemirror/addons/colorpicker/colorview_customized.js.source.txt: -------------------------------------------------------------------------------- 1 | Slightly customized version of ./colorview.js -------------------------------------------------------------------------------- /extension/scripts/3rdparty/codemirror/addons/comment/comment.js.source.txt: -------------------------------------------------------------------------------- 1 | https://raw.githubusercontent.com/codemirror/CodeMirror/5.34.0/addon/comment/comment.js -------------------------------------------------------------------------------- /extension/scripts/3rdparty/codemirror/addons/display/placeholder.js.source.txt: -------------------------------------------------------------------------------- 1 | https://raw.githubusercontent.com/codemirror/CodeMirror/5.34.0/addon/display/placeholder.js -------------------------------------------------------------------------------- /extension/scripts/3rdparty/codemirror/addons/edit/closebrackets.js.source.txt: -------------------------------------------------------------------------------- 1 | https://raw.githubusercontent.com/codemirror/CodeMirror/5.34.0/addon/edit/closebrackets.js -------------------------------------------------------------------------------- /extension/scripts/3rdparty/codemirror/addons/edit/matchbrackets.js.source.txt: -------------------------------------------------------------------------------- 1 | https://raw.githubusercontent.com/codemirror/CodeMirror/5.34.0/addon/edit/matchbrackets.js -------------------------------------------------------------------------------- /extension/scripts/3rdparty/codemirror/addons/emmet/emmet-codemirror-plugin.js.source.txt: -------------------------------------------------------------------------------- 1 | node_modules/emmetio-codemirror-plugin-webextensions/dist/emmet-codemirror-plugin.js 2 | 3 | Note: Removed "sourceMappingURL" -------------------------------------------------------------------------------- /extension/scripts/3rdparty/codemirror/addons/hint/css-hint.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror"), require("../../mode/css/css")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror", "../../mode/css/css"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | var pseudoClasses = {link: 1, visited: 1, active: 1, hover: 1, focus: 1, 15 | "first-letter": 1, "first-line": 1, "first-child": 1, 16 | before: 1, after: 1, lang: 1}; 17 | 18 | CodeMirror.registerHelper("hint", "css", function(cm) { 19 | var cur = cm.getCursor(), token = cm.getTokenAt(cur); 20 | var inner = CodeMirror.innerMode(cm.getMode(), token.state); 21 | if (inner.mode.name != "css") return; 22 | 23 | if (token.type == "keyword" && "!important".indexOf(token.string) == 0) 24 | return {list: ["!important"], from: CodeMirror.Pos(cur.line, token.start), 25 | to: CodeMirror.Pos(cur.line, token.end)}; 26 | 27 | var start = token.start, end = cur.ch, word = token.string.slice(0, end - start); 28 | if (/[^\w$_-]/.test(word)) { 29 | word = ""; start = end = cur.ch; 30 | } 31 | 32 | var spec = CodeMirror.resolveMode("text/css"); 33 | 34 | var result = []; 35 | function add(keywords) { 36 | for (var name in keywords) 37 | if (!word || name.lastIndexOf(word, 0) == 0) 38 | result.push(name); 39 | } 40 | 41 | var st = inner.state.state; 42 | if (st == "pseudo" || token.type == "variable-3") { 43 | add(pseudoClasses); 44 | } else if (st == "block" || st == "maybeprop") { 45 | add(spec.propertyKeywords); 46 | } else if (st == "prop" || st == "parens" || st == "at" || st == "params") { 47 | add(spec.valueKeywords); 48 | add(spec.colorKeywords); 49 | } else if (st == "media" || st == "media_parens") { 50 | add(spec.mediaTypes); 51 | add(spec.mediaFeatures); 52 | } 53 | 54 | if (result.length) return { 55 | list: result, 56 | from: CodeMirror.Pos(cur.line, start), 57 | to: CodeMirror.Pos(cur.line, end) 58 | }; 59 | }); 60 | }); 61 | -------------------------------------------------------------------------------- /extension/scripts/3rdparty/codemirror/addons/hint/css-hint.js.source.txt: -------------------------------------------------------------------------------- 1 | https://raw.githubusercontent.com/codemirror/CodeMirror/5.34.0/addon/hint/css-hint.js -------------------------------------------------------------------------------- /extension/scripts/3rdparty/codemirror/addons/hint/css-hint_customized.js.source.txt: -------------------------------------------------------------------------------- 1 | Slightly customized version of ./css-hint.js -------------------------------------------------------------------------------- /extension/scripts/3rdparty/codemirror/addons/hint/show-hint.css: -------------------------------------------------------------------------------- 1 | .CodeMirror-hints { 2 | position: absolute; 3 | z-index: 10; 4 | overflow: hidden; 5 | list-style: none; 6 | 7 | margin: 0; 8 | padding: 2px; 9 | 10 | -webkit-box-shadow: 2px 3px 5px rgba(0,0,0,.2); 11 | -moz-box-shadow: 2px 3px 5px rgba(0,0,0,.2); 12 | box-shadow: 2px 3px 5px rgba(0,0,0,.2); 13 | border-radius: 3px; 14 | border: 1px solid silver; 15 | 16 | background: white; 17 | font-size: 90%; 18 | font-family: monospace; 19 | 20 | max-height: 20em; 21 | overflow-y: auto; 22 | } 23 | 24 | .CodeMirror-hint { 25 | margin: 0; 26 | padding: 0 4px; 27 | border-radius: 2px; 28 | white-space: pre; 29 | color: black; 30 | cursor: pointer; 31 | } 32 | 33 | li.CodeMirror-hint-active { 34 | background: #08f; 35 | color: white; 36 | } 37 | -------------------------------------------------------------------------------- /extension/scripts/3rdparty/codemirror/addons/hint/show-hint.css.source.txt: -------------------------------------------------------------------------------- 1 | https://raw.githubusercontent.com/codemirror/CodeMirror/5.34.0/addon/hint/show-hint.css -------------------------------------------------------------------------------- /extension/scripts/3rdparty/codemirror/addons/hint/show-hint.js.source.txt: -------------------------------------------------------------------------------- 1 | https://raw.githubusercontent.com/codemirror/CodeMirror/5.34.0/addon/hint/show-hint.js -------------------------------------------------------------------------------- /extension/scripts/3rdparty/codemirror/addons/hint/show-hint_customized.js.source.txt: -------------------------------------------------------------------------------- 1 | Slightly customized version of ./show-hint.js -------------------------------------------------------------------------------- /extension/scripts/3rdparty/codemirror/addons/lint/css-lint.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | // Depends on csslint.js from https://github.com/stubbornella/csslint 5 | 6 | // declare global: CSSLint 7 | 8 | (function(mod) { 9 | if (typeof exports == "object" && typeof module == "object") // CommonJS 10 | mod(require("../../lib/codemirror")); 11 | else if (typeof define == "function" && define.amd) // AMD 12 | define(["../../lib/codemirror"], mod); 13 | else // Plain browser env 14 | mod(CodeMirror); 15 | })(function(CodeMirror) { 16 | "use strict"; 17 | 18 | CodeMirror.registerHelper("lint", "css", function(text, options) { 19 | var found = []; 20 | if (!window.CSSLint) { 21 | if (window.console) { 22 | window.console.error("Error: window.CSSLint not defined, CodeMirror CSS linting cannot run."); 23 | } 24 | return found; 25 | } 26 | var results = CSSLint.verify(text, options), messages = results.messages, message = null; 27 | for ( var i = 0; i < messages.length; i++) { 28 | message = messages[i]; 29 | var startLine = message.line -1, endLine = message.line -1, startCol = message.col -1, endCol = message.col; 30 | found.push({ 31 | from: CodeMirror.Pos(startLine, startCol), 32 | to: CodeMirror.Pos(endLine, endCol), 33 | message: message.message, 34 | severity : message.type 35 | }); 36 | } 37 | return found; 38 | }); 39 | 40 | }); 41 | -------------------------------------------------------------------------------- /extension/scripts/3rdparty/codemirror/addons/lint/css-lint.js.source.txt: -------------------------------------------------------------------------------- 1 | https://raw.githubusercontent.com/codemirror/CodeMirror/5.34.0/addon/lint/css-lint.js -------------------------------------------------------------------------------- /extension/scripts/3rdparty/codemirror/addons/lint/css-lint_customized.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | // Depends on csslint.js from https://github.com/stubbornella/csslint 5 | 6 | // declare global: CSSLint 7 | 8 | (function(mod) { 9 | // if (typeof exports == "object" && typeof module == "object") // CommonJS 10 | // mod(require("../../lib/codemirror")); 11 | // else if (typeof define == "function" && define.amd) // AMD 12 | // define(["../../lib/codemirror"], mod); 13 | // else // Plain browser env 14 | mod(CodeMirror); 15 | })(function(CodeMirror) { 16 | "use strict"; 17 | 18 | CodeMirror.registerHelper("lint", "css", function(text, options) { 19 | var found = []; 20 | // if (!window.CSSLint) { 21 | if (typeof CSSLint === 'undefined') { // In Firefox WebExtension, "window.CSSLint" is not available, while "CSSLint" is available 22 | // Firefox WebExtensions behave slightly differently for global variables declared-using-"var" vs declared-using-"window." 23 | // References: 24 | // https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Content_scripts 25 | // https://developer.mozilla.org/en-US/docs/Mozilla/Tech/Xray_vision 26 | if (window.console) { 27 | window.console.error("Error: window.CSSLint not defined, CodeMirror CSS linting cannot run."); 28 | } 29 | return found; 30 | } 31 | var results = CSSLint.verify(text, options), messages = results.messages, message = null; 32 | for ( var i = 0; i < messages.length; i++) { 33 | message = messages[i]; 34 | var startLine = message.line -1, endLine = message.line -1, startCol = message.col -1, endCol = message.col; 35 | found.push({ 36 | from: CodeMirror.Pos(startLine, startCol), 37 | to: CodeMirror.Pos(endLine, endCol), 38 | message: message.message, 39 | severity : message.type 40 | }); 41 | } 42 | return found; 43 | }); 44 | 45 | }); 46 | -------------------------------------------------------------------------------- /extension/scripts/3rdparty/codemirror/addons/lint/css-lint_customized.js.source.txt: -------------------------------------------------------------------------------- 1 | Slightly customized version of ./css-lint.js -------------------------------------------------------------------------------- /extension/scripts/3rdparty/codemirror/addons/lint/lint.css.source.txt: -------------------------------------------------------------------------------- 1 | https://raw.githubusercontent.com/codemirror/CodeMirror/5.34.0/addon/lint/lint.css -------------------------------------------------------------------------------- /extension/scripts/3rdparty/codemirror/addons/lint/lint.js.source.txt: -------------------------------------------------------------------------------- 1 | https://raw.githubusercontent.com/codemirror/CodeMirror/5.34.0/addon/lint/lint.js -------------------------------------------------------------------------------- /extension/scripts/3rdparty/codemirror/addons/search/searchcursor.js.source.txt: -------------------------------------------------------------------------------- 1 | https://raw.githubusercontent.com/codemirror/CodeMirror/5.34.0/addon/search/searchcursor.js -------------------------------------------------------------------------------- /extension/scripts/3rdparty/codemirror/addons/selection/active-line.js.source.txt: -------------------------------------------------------------------------------- 1 | https://raw.githubusercontent.com/codemirror/CodeMirror/5.34.0/addon/selection/active-line.js -------------------------------------------------------------------------------- /extension/scripts/3rdparty/codemirror/codemirror.css.source.txt: -------------------------------------------------------------------------------- 1 | node_modules/codemirror/lib/codemirror.css -------------------------------------------------------------------------------- /extension/scripts/3rdparty/codemirror/codemirror.js.source.txt: -------------------------------------------------------------------------------- 1 | node_modules/codemirror/lib/codemirror.js -------------------------------------------------------------------------------- /extension/scripts/3rdparty/codemirror/keymap/sublime.js.source.txt: -------------------------------------------------------------------------------- 1 | https://raw.githubusercontent.com/codemirror/CodeMirror/5.34.0/keymap/sublime.js -------------------------------------------------------------------------------- /extension/scripts/3rdparty/codemirror/mode/css.js.source.txt: -------------------------------------------------------------------------------- 1 | https://raw.githubusercontent.com/codemirror/CodeMirror/5.34.0/mode/css/css.js -------------------------------------------------------------------------------- /extension/scripts/3rdparty/codemirror/theme/ambiance.css.source.txt: -------------------------------------------------------------------------------- 1 | node_modules/codemirror/theme/ambiance.css -------------------------------------------------------------------------------- /extension/scripts/3rdparty/css.escape.js.source.txt: -------------------------------------------------------------------------------- 1 | https://raw.githubusercontent.com/mathiasbynens/CSS.escape/v1.5.1/css.escape.js -------------------------------------------------------------------------------- /extension/scripts/3rdparty/csslint/csslint.js.source.txt: -------------------------------------------------------------------------------- 1 | https://raw.githubusercontent.com/CSSLint/csslint/v1.0.5/dist/csslint.js -------------------------------------------------------------------------------- /extension/scripts/3rdparty/csspretty/csspretty.js.source.txt: -------------------------------------------------------------------------------- 1 | https://raw.githubusercontent.com/prettydiff/prettydiff/v1.16.28/lib/csspretty.js -------------------------------------------------------------------------------- /extension/scripts/3rdparty/jquery-ui.css.source.txt: -------------------------------------------------------------------------------- 1 | Steps to generate jquery-ui.js 2 | ============================== 3 | 4 | - Go to https://jqueryui.com/download/ 5 | - Under "Version", select "1.12.1 (Stable, for jQuery1.7+)" 6 | - Under "Components", uncheck "Toggle All". This deselects all other packages below that. 7 | - Under "Interactions", check "Draggable" and "Resizable". This would automatically select a few other packages. 8 | - Under "Theme", select "UI lightness" 9 | - Under "CSS Scope", type "#MagiCSS-bookmarklet" (without double-quotes) 10 | - Click on "Download" 11 | - This would download a file called "jquery-ui-1.12.1.custom.zip" 12 | - Extract "jquery-ui-1.12.1.custom.zip" 13 | - Use "jquery-ui.css" from the extracted folder 14 | -------------------------------------------------------------------------------- /extension/scripts/3rdparty/jquery-ui.js.source.txt: -------------------------------------------------------------------------------- 1 | Steps to generate jquery-ui.js 2 | ============================== 3 | 4 | - Go to https://jqueryui.com/download/ 5 | - Under "Version", select "1.12.1 (Stable, for jQuery1.7+)" 6 | - Under "Components", uncheck "Toggle All". This deselects all other packages below that. 7 | - Under "Interactions", check "Draggable" and "Resizable". This would automatically select a few other packages. 8 | - Under "Theme", select "UI lightness" 9 | - Under "CSS Scope", type "#MagiCSS-bookmarklet" (without double-quotes) 10 | - Click on "Download" 11 | - This would download a file called "jquery-ui-1.12.1.custom.zip" 12 | - Extract "jquery-ui-1.12.1.custom.zip" 13 | - Use "jquery-ui.js" from the extracted folder 14 | -------------------------------------------------------------------------------- /extension/scripts/3rdparty/jquery-ui_customized.css.source.txt: -------------------------------------------------------------------------------- 1 | Slightly customized version of ./jquery-ui.css -------------------------------------------------------------------------------- /extension/scripts/3rdparty/jquery.js.source.txt: -------------------------------------------------------------------------------- 1 | https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js -------------------------------------------------------------------------------- /extension/scripts/3rdparty/jquery.ui-touch-punch_customized.js.source.txt: -------------------------------------------------------------------------------- 1 | Slightly customized version of ./jquery.ui-touch-punch.js -------------------------------------------------------------------------------- /extension/scripts/3rdparty/jquery.ui.touch-punch.js.source.txt: -------------------------------------------------------------------------------- 1 | https://raw.githubusercontent.com/furf/jquery-ui-touch-punch/8f7559b6e65cdc3ee3648d5fe76d38c653f87ff5/jquery.ui.touch-punch.js -------------------------------------------------------------------------------- /extension/scripts/3rdparty/magicsuggest/magicsuggest.css.source.txt: -------------------------------------------------------------------------------- 1 | https://raw.githubusercontent.com/nicolasbize/magicsuggest/2.1.4/magicsuggest.css -------------------------------------------------------------------------------- /extension/scripts/3rdparty/magicsuggest/magicsuggest.js.source.txt: -------------------------------------------------------------------------------- 1 | https://raw.githubusercontent.com/nicolasbize/magicsuggest/2.1.4/magicsuggest.js -------------------------------------------------------------------------------- /extension/scripts/3rdparty/sass/sass.sync.min.js.source.txt: -------------------------------------------------------------------------------- 1 | https://raw.githubusercontent.com/medialize/sass.js/0.11.1/dist/sass.sync.js -------------------------------------------------------------------------------- /extension/scripts/3rdparty/socket.io/socket.io.slim.dev.js.source.txt: -------------------------------------------------------------------------------- 1 | node_modules/socket.io-client/dist/socket.io.slim.dev.js 2 | 3 | Note: Removed "sourceMappingURL" -------------------------------------------------------------------------------- /extension/scripts/3rdparty/socket.io/socket.io.slim.js.source.txt: -------------------------------------------------------------------------------- 1 | node_modules/socket.io-client/dist/socket.io.slim.js 2 | 3 | Note: Removed "sourceMappingURL" -------------------------------------------------------------------------------- /extension/scripts/3rdparty/source-map.js.source.txt: -------------------------------------------------------------------------------- 1 | https://raw.githubusercontent.com/mozilla/source-map/0.6.1/dist/source-map.debug.js 2 | 3 | Note: Removed "sourceMappingURL" -------------------------------------------------------------------------------- /extension/scripts/3rdparty/toastr/toastr.css.source.txt: -------------------------------------------------------------------------------- 1 | node_modules/toastr/build/toastr.css -------------------------------------------------------------------------------- /extension/scripts/3rdparty/toastr/toastr.js.source.txt: -------------------------------------------------------------------------------- 1 | node_modules/toastr/toastr.js -------------------------------------------------------------------------------- /extension/scripts/3rdparty/toastr/toastr_customized.js.source.txt: -------------------------------------------------------------------------------- 1 | Slightly customized version of ./toastr.js -------------------------------------------------------------------------------- /extension/scripts/3rdparty/tooltipster/jquery.tooltipster.js.source.txt: -------------------------------------------------------------------------------- 1 | https://raw.githubusercontent.com/iamceege/tooltipster/4.2.8/dist/js/tooltipster.bundle.js -------------------------------------------------------------------------------- /extension/scripts/3rdparty/tooltipster/tooltipster-scrollableTip.js.source.txt: -------------------------------------------------------------------------------- 1 | https://raw.githubusercontent.com/louisameline/tooltipster-scrollableTip/1.0.0/tooltipster-scrollableTip.js -------------------------------------------------------------------------------- /extension/scripts/3rdparty/tooltipster/tooltipster.css.source.txt: -------------------------------------------------------------------------------- 1 | https://raw.githubusercontent.com/iamceege/tooltipster/4.2.8/dist/css/tooltipster.bundle.css -------------------------------------------------------------------------------- /extension/scripts/appUtils/getUuid.js: -------------------------------------------------------------------------------- 1 | import { chromeStorageLocalGet } from '../utils/chromeStorage.js'; 2 | 3 | const INSTANCE_UUID = 'instance-uuid'; 4 | 5 | const timeout = function (ms) { 6 | return new Promise(resolve => setTimeout(resolve, ms)); 7 | }; 8 | 9 | const getUuid = async function () { 10 | let uuid; 11 | 12 | for (let i = 0; i < 5; i++) { 13 | uuid = await chromeStorageLocalGet(INSTANCE_UUID); 14 | if (uuid) { 15 | break; 16 | } 17 | await timeout(1000); 18 | } 19 | 20 | if (uuid) { 21 | return [null, uuid]; 22 | } else { 23 | const errToReport = new Error(`Unable to fetch the ${INSTANCE_UUID}`); 24 | console.error(errToReport); 25 | return [errToReport]; 26 | } 27 | }; 28 | 29 | export { getUuid }; 30 | -------------------------------------------------------------------------------- /extension/scripts/appUtils/isFeatureEnabled.js: -------------------------------------------------------------------------------- 1 | import { chromeStorageLocalGet } from '../utils/chromeStorage.js'; 2 | import { basisNumberFromUuid } from '../utils/basisNumberFromUuid.js'; 3 | 4 | const INSTANCE_UUID = 'instance-uuid'; 5 | 6 | const isFeatureEnabled = async function (enabledOrConditions) { 7 | let flag = false; 8 | 9 | const instanceUuid = await chromeStorageLocalGet(INSTANCE_UUID); 10 | const basisNumber = basisNumberFromUuid(instanceUuid); 11 | 12 | if (enabledOrConditions === true) { 13 | flag = true; 14 | } else if (Array.isArray(enabledOrConditions)) { 15 | const conditions = enabledOrConditions; 16 | for (const condition of conditions) { 17 | if (Array.isArray(condition)) { 18 | const [from, to] = condition; 19 | if (from <= basisNumber && basisNumber <= to) { 20 | flag = true; 21 | break; 22 | } 23 | } else if (typeof condition === 'string') { 24 | if (instanceUuid.indexOf(condition) >= 0) { 25 | flag = true; 26 | break; 27 | } 28 | } 29 | } 30 | } 31 | 32 | return flag; 33 | }; 34 | 35 | export { isFeatureEnabled }; 36 | -------------------------------------------------------------------------------- /extension/scripts/appUtils/metricsUrlGenerator.js: -------------------------------------------------------------------------------- 1 | const metricsUrlGenerator = async function ({ remoteConfig, event, details, uninstallPathOnServer }) { 2 | if (uninstallPathOnServer) { 3 | const url = uninstallPathOnServer + '?uuid=' + details.uuid; 4 | return url; 5 | } else { 6 | const detailsParam = JSON.stringify(details); 7 | const parameters = { 8 | v: '1.0.0', 9 | appId: 'magic-css', 10 | event, 11 | details: detailsParam 12 | }; 13 | const queryString = new URLSearchParams(parameters).toString(); 14 | 15 | // The code would reach here only when the config is loaded from remote 16 | const metricsApiServer = remoteConfig.config.metricsApi.server; 17 | const metricsApiCollectionPath = remoteConfig.config.metricsApi.collectionPath; 18 | 19 | const url = metricsApiServer + metricsApiCollectionPath + '?' + queryString; 20 | return url; 21 | } 22 | }; 23 | 24 | export { metricsUrlGenerator }; 25 | -------------------------------------------------------------------------------- /extension/scripts/appUtils/myWin.js: -------------------------------------------------------------------------------- 1 | import { theWin } from '../../commonAppUtils/theWin.js'; 2 | 3 | const myWin = theWin; 4 | 5 | export { myWin }; 6 | -------------------------------------------------------------------------------- /extension/scripts/appUtils/nativeAlert.js: -------------------------------------------------------------------------------- 1 | /* global chrome */ 2 | 3 | export const nativeAlert = async (message) => { 4 | await chrome.offscreen.createDocument({ 5 | url: ( 6 | chrome.runtime.getURL('alert.html') + 7 | '?message=' + encodeURIComponent(message) 8 | ), 9 | reasons: ['DISPLAY_MEDIA'], 10 | justification: 'show an alert that extension does not work on various special pages' 11 | }); 12 | await chrome.offscreen.closeDocument(); 13 | }; 14 | -------------------------------------------------------------------------------- /extension/scripts/appVersion.js: -------------------------------------------------------------------------------- 1 | // Just a block 2 | { 3 | const magicCssVersion = '8.22.5'; 4 | if (typeof window === 'undefined') { 5 | module.exports = { 6 | version: magicCssVersion 7 | }; 8 | } else { 9 | window.magicCssVersion = magicCssVersion; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /extension/scripts/load-reapply.js: -------------------------------------------------------------------------------- 1 | import './reapply-css.js'; 2 | -------------------------------------------------------------------------------- /extension/scripts/loading-magic-css.js: -------------------------------------------------------------------------------- 1 | import { alertNote } from './utils/alertNote.js'; 2 | 3 | alertNote('Loading Magic CSS ... Please wait :-)', 10000); 4 | -------------------------------------------------------------------------------- /extension/scripts/magicss/editor/editor-standalone-example.js: -------------------------------------------------------------------------------- 1 | import { delayFunctionUntilTestFunction } from '../../../scripts/utils/delayFunctionUntilTestFunction.js'; 2 | 3 | // Here goes the functional code 4 | (async function(){ 5 | if (window.editor) { 6 | console.log('Editor window is already there.'); 7 | return; 8 | } 9 | 10 | // for HTML frameset pages, this value would be 'FRAMESET' 11 | // chrome.tabs.executeScript uses allFrames: true, to run inside all frames 12 | // TODO: Check if it is still the same for chrome.tabs.scripting 13 | if (document.body.tagName !== 'BODY') { 14 | return; 15 | } 16 | 17 | // Just a block 18 | { 19 | await delayFunctionUntilTestFunction({ 20 | tryLimit: 100, 21 | waitFor: 500, 22 | fnTest: function () { 23 | if ( 24 | typeof window.Editor === 'function' 25 | && window.Editor.usable 26 | ) { 27 | return true; 28 | } 29 | return false; 30 | }, 31 | fnFirstFailure: function () { 32 | // do nothing 33 | }, 34 | fnFailure: function () { 35 | // do nothing 36 | }, 37 | fnSuccess: async function () { 38 | var id = 'Editor'; 39 | var options = { 40 | id: id, 41 | 42 | title: '
Editor
', 43 | placeholder: 'Write your text here...', 44 | syntaxHighlightingLanguage: 'text/x-less', 45 | 46 | bgColor: '68,88,174,0.7', 47 | 48 | events: {} 49 | }; 50 | 51 | window.editor = new window.Editor(options); 52 | await window.editor.create(); 53 | } 54 | }); 55 | } 56 | }()); 57 | -------------------------------------------------------------------------------- /extension/scripts/magicss/metrics/sendMessageForMetrics.js: -------------------------------------------------------------------------------- 1 | /* global chrome */ 2 | 3 | /* 4 | For example: 5 | sendEventMessageForMetrics({ 6 | name: 'openGetIcon', 7 | spot: 'commandPalette' 8 | }); 9 | */ 10 | const sendEventMessageForMetrics = function (payload) { 11 | try { 12 | if (payload) { 13 | if ( 14 | typeof payload.metricsTarget === 'undefined' || 15 | payload.metricsTarget === 'mixpanel' 16 | ) { 17 | // eslint-disable-next-line no-unused-vars 18 | const { metricsTarget, ...evt } = payload; 19 | chrome.runtime.sendMessage({ 20 | type: 'mixpanel', 21 | subType: 'event', 22 | payload: evt 23 | }); 24 | } 25 | } 26 | } catch (e) { 27 | // do nothing 28 | } 29 | }; 30 | window.sendEventMessageForMetrics = sendEventMessageForMetrics; 31 | 32 | export { sendEventMessageForMetrics }; 33 | -------------------------------------------------------------------------------- /extension/scripts/platformInfoOs-android.js: -------------------------------------------------------------------------------- 1 | window.platformInfoOs = 'android'; 2 | -------------------------------------------------------------------------------- /extension/scripts/platformInfoOs-non-android.js: -------------------------------------------------------------------------------- 1 | window.platformInfoOs = 'non-android'; 2 | -------------------------------------------------------------------------------- /extension/scripts/utils.js: -------------------------------------------------------------------------------- 1 | /* global jQuery */ 2 | 3 | 'use strict'; 4 | 5 | var utils = window.utils || {}; 6 | 7 | if (!utils.defined) { 8 | utils.defined = true; 9 | 10 | utils.attachPublishSubscribe = function (attachToObject) { 11 | var o = jQuery({}); 12 | jQuery.each({ 13 | trigger: 'publish', 14 | on: 'subscribe', 15 | off: 'unsubscribe' 16 | }, function (key, val) { 17 | attachToObject[val] = function () { 18 | o[key].apply(o, arguments); 19 | }; 20 | }); 21 | }; 22 | } 23 | 24 | if (!utils.attachPublishSubscribeDone) { 25 | if (typeof jQuery !== 'undefined') { 26 | utils.attachPublishSubscribeDone = true; 27 | utils.attachPublishSubscribe(jQuery); 28 | } 29 | } 30 | 31 | // // The following line has been commented out temporarily. See: FIXME.md 32 | // 'This string is added to the end of this file to handle a weird bug/behavior for Firefox. Without this, if "reapply styles automatically" feature is activated, then it would not work and an error would occur in the background script. Reference: https://stackoverflow.com/questions/44567525/inject-scripts-error-script-returned-non-structured-clonable-data-on-firefox-ex/56597154#56597154'; 33 | 34 | export { utils }; 35 | -------------------------------------------------------------------------------- /extension/scripts/utils/basisNumberFromUuid.js: -------------------------------------------------------------------------------- 1 | const basisNumberFromUuid = function (uuid) { 2 | const uuidWithoutHyphen = uuid.replace(/-/g, ''); 3 | let basisString = BigInt(`0x${uuidWithoutHyphen}`).toString(); 4 | basisString = basisString.slice(basisString.length - 4); 5 | const basisNumber = parseInt(basisString) + 1; 6 | return basisNumber; 7 | }; 8 | 9 | export { basisNumberFromUuid }; 10 | -------------------------------------------------------------------------------- /extension/scripts/utils/beautifyCss.js: -------------------------------------------------------------------------------- 1 | import { csspretty } from 'helpmate-css/dist/format/csspretty.js'; 2 | 3 | const beautifyCss = function (cssCode, options) { 4 | var useTabs = options.useTabs, 5 | useSpaceCount = options.useSpaceCount; 6 | 7 | var inchar, 8 | insize; 9 | 10 | if (useTabs) { 11 | inchar = '\t'; 12 | insize = 1; 13 | } else { 14 | inchar = ' '; 15 | insize = useSpaceCount || 4; 16 | } 17 | 18 | return csspretty({ 19 | mode: 'beautify', /* Doing beautify twice, otherwise it doesn't beautify code like the following one in single go: 20 | .box-shadow(@style,@alpha: 50%) when (isnumber(@alpha)){.box-shadow(@style, rgba(0, 0, 0, @alpha))} */ 21 | insize: insize, 22 | inchar: inchar, 23 | source: csspretty({ 24 | mode: 'beautify', 25 | insize: insize, 26 | inchar: inchar, 27 | source: cssCode 28 | }) 29 | }); 30 | 31 | // Alternatively, use cssbeautify library: 32 | // return cssbeautify( 33 | // cssCode, 34 | // { 35 | // indent: ' ', 36 | // autosemicolon: true 37 | // } 38 | // ); 39 | }; 40 | 41 | export { beautifyCss }; 42 | -------------------------------------------------------------------------------- /extension/scripts/utils/chromeStorage.js: -------------------------------------------------------------------------------- 1 | /* global chrome */ 2 | 3 | export const chromeStorageGet = function (storageObject, prop) { 4 | return new Promise(function (resolve, reject) { // eslint-disable-line no-unused-vars 5 | storageObject.get(prop, function (values) { 6 | if (prop === null) { 7 | resolve(values); 8 | } else { 9 | resolve(values[prop]); 10 | } 11 | }); 12 | }); 13 | }; 14 | export const chromeStorageSet = function (storageObject, prop, value) { 15 | return new Promise(function (resolve, reject) { // eslint-disable-line no-unused-vars 16 | storageObject.set( 17 | { 18 | [prop]: value 19 | }, 20 | function () { 21 | resolve(); 22 | } 23 | ); 24 | }); 25 | }; 26 | export const chromeStorageRemove = function (storageObject, prop) { 27 | return new Promise(function (resolve, reject) { // eslint-disable-line no-unused-vars 28 | storageObject.remove(prop, function () { 29 | resolve(); 30 | }); 31 | }); 32 | }; 33 | 34 | export const chromeStorageLocalGet = async function (prop) { 35 | const value = await chromeStorageGet(chrome.storage.local, prop); 36 | return value; 37 | }; 38 | export const chromeStorageLocalSet = async function (prop, value) { 39 | await chromeStorageSet(chrome.storage.local, prop, value); 40 | }; 41 | export const chromeStorageLocalRemove = async function (prop, value) { 42 | await chromeStorageRemove(chrome.storage.local, prop, value); 43 | }; 44 | 45 | export const chromeStorageSyncGet = async function (prop) { 46 | const value = await chromeStorageGet(chrome.storage.sync, prop); 47 | return value; 48 | }; 49 | export const chromeStorageSyncSet = async function (prop, value) { 50 | await chromeStorageSet(chrome.storage.sync, prop, value); 51 | }; 52 | export const chromeStorageSyncRemove = async function (prop, value) { 53 | await chromeStorageRemove(chrome.storage.sync, prop, value); 54 | }; 55 | -------------------------------------------------------------------------------- /extension/scripts/utils/confirmDialog.css: -------------------------------------------------------------------------------- 1 | .magicCssConfirmDialog::backdrop { 2 | background-color: rgba(0, 0, 0, 0.66); 3 | } 4 | 5 | .magicCssConfirmDialog button { 6 | font-size: 14px !important; 7 | font-family: sans-serif !important; 8 | cursor: pointer; 9 | padding: 4px 10px !important; 10 | } 11 | 12 | #magicCssConfirmDialogButtonOk, 13 | #magicCssConfirmDialogButtonCancel { 14 | min-width: 130px; 15 | height: 40px; 16 | padding: 5px 10px; 17 | font-weight: bold; 18 | cursor: pointer; 19 | transition: all 0.3s ease; 20 | position: relative; 21 | display: inline-block; 22 | outline: none; 23 | border-radius: 20px; 24 | } 25 | 26 | #magicCssConfirmDialogButtonOk { 27 | border: 2px solid #1565c0; 28 | background-color: #1565c0; 29 | color: #fff; 30 | } 31 | #magicCssConfirmDialogButtonOk:hover { 32 | background-color: #0535a0; 33 | border-color: #0535a0; 34 | } 35 | 36 | #magicCssConfirmDialogButtonCancel { 37 | border: 2px solid #1565c0; 38 | background-color: #fff; 39 | color: #1565c0; 40 | } 41 | #magicCssConfirmDialogButtonCancel:hover { 42 | background-color: #0535a0; 43 | border-color: #0535a0; 44 | color: #fff; 45 | } 46 | -------------------------------------------------------------------------------- /extension/scripts/utils/confirmDialog.js: -------------------------------------------------------------------------------- 1 | import './confirmDialog.css'; 2 | const confirmDialog = function (message) { 3 | return new Promise((resolve) => { 4 | const dialog = document.createElement('dialog'); 5 | dialog.className = 'magicCssConfirmDialog'; 6 | dialog.style.padding = '10px 20px'; 7 | dialog.style.margin = 'auto'; // Required for some cases where style `* { margin: 0 }` is set 8 | dialog.innerHTML = ` 9 |
10 |
11 | ${message} 12 |
13 |
14 |
15 | 18 |
19 |
20 | 23 |
24 |
25 |
26 | `; 27 | dialog.addEventListener('click', (evt) => { 28 | if (evt.target.id === 'magicCssConfirmDialogButtonOk') { 29 | resolve(true); 30 | dialog.close(); 31 | dialog.remove(); 32 | } else if ( 33 | evt.target.id === 'magicCssConfirmDialogButtonCancel' || 34 | evt.target === dialog 35 | ) { 36 | resolve(false); 37 | dialog.close(); 38 | dialog.remove(); 39 | } 40 | }); 41 | document.body.appendChild(dialog); 42 | dialog.showModal(); 43 | }); 44 | }; 45 | 46 | export { confirmDialog }; 47 | -------------------------------------------------------------------------------- /extension/scripts/utils/delayFunctionUntilTestFunction.js: -------------------------------------------------------------------------------- 1 | const delayFunctionUntilTestFunction = async function(config) { 2 | var fnSuccess = config.fnSuccess, 3 | fnTest = config.fnTest, 4 | fnFirstFailure = config.fnFirstFailure, 5 | fnEachFailure = config.fnEachFailure, 6 | fnFailure = config.fnFailure, 7 | tryLimit = typeof config.tryLimit === 'undefined' ? 120 : config.tryLimit; 8 | 9 | config['tryLimit-Running-Cycle-Number'] = typeof config['tryLimit-Running-Cycle-Number'] === 'undefined' ? 0 : config['tryLimit-Running-Cycle-Number']+1; 10 | 11 | var tryLimitRunningCycleNumber = config['tryLimit-Running-Cycle-Number'], 12 | waitFor = config.waitFor || 750; 13 | 14 | if(fnTest()) { 15 | return (await fnSuccess()) === false ? false : true; 16 | } else { 17 | if(tryLimitRunningCycleNumber === 0 && typeof fnFirstFailure === 'function') { 18 | fnFirstFailure(); 19 | } 20 | 21 | if(typeof fnEachFailure === 'function') { 22 | fnEachFailure(); 23 | } 24 | 25 | if(tryLimitRunningCycleNumber < (tryLimit-1)) { 26 | window.setTimeout((async function(){ 27 | await delayFunctionUntilTestFunction(config); 28 | }),waitFor); 29 | } else { 30 | if (typeof fnFailure === 'function') { 31 | fnFailure(); 32 | } 33 | } 34 | return false; 35 | } 36 | }; 37 | 38 | export { delayFunctionUntilTestFunction }; 39 | -------------------------------------------------------------------------------- /extension/scripts/utils/i18n.js: -------------------------------------------------------------------------------- 1 | /* global chrome */ 2 | 3 | const TR = function (key, defaultValue) { 4 | if ( 5 | typeof chrome !== 'undefined' && 6 | chrome?.i18n?.getMessage 7 | ) { 8 | return chrome.i18n.getMessage(key); 9 | } else { 10 | if (defaultValue) { 11 | return defaultValue; 12 | } else { 13 | console.warn('No default value available for key: ' + key); 14 | return ''; 15 | } 16 | } 17 | }; 18 | 19 | export { TR }; 20 | -------------------------------------------------------------------------------- /extension/scripts/utils/isValidUuidV4.js: -------------------------------------------------------------------------------- 1 | const isValidUuidV4 = function (str) { 2 | const v4Regex = /^[0-9a-f]{8}-[0-9a-f]{4}-[4][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i; 3 | if (v4Regex.test(str)) { 4 | return true; 5 | } else { 6 | return false; 7 | } 8 | }; 9 | 10 | export { isValidUuidV4 }; 11 | -------------------------------------------------------------------------------- /extension/scripts/utils/lessToCss.js: -------------------------------------------------------------------------------- 1 | /* global less */ 2 | 3 | const lessToCss = function (lessCode, cb) { 4 | less.default.render( 5 | lessCode, 6 | function (err, output) { 7 | if (err) { 8 | cb(err); 9 | } else { 10 | var cssCode = output.css; 11 | cb(null, cssCode); 12 | } 13 | } 14 | ); 15 | 16 | // With older versions of less: 17 | // less.Parser().parse(lessCode, function (err, tree) { 18 | // if (err) { 19 | // cb(err); 20 | // } else { 21 | // var cssCode = tree.toCSS(); 22 | // cb(null, cssCode); 23 | // } 24 | // }); 25 | }; 26 | 27 | export { lessToCss }; 28 | -------------------------------------------------------------------------------- /extension/scripts/utils/loadScript.js: -------------------------------------------------------------------------------- 1 | // NOTE: This file is not being used as of now. It is being kept here for future reference. 2 | 3 | /* 4 | * Load a script 5 | * 6 | * @param {Object|string} cfg Configuration object or Path of the JS source 7 | * @param {Document} [cfg.doc=document] Which "document" object to use 8 | * @param {String} [cfg.parent='body'] Which tag to append to (the "parent" tag value would be used if that element is available) 9 | * @param {String} cfg.src Path of the JS source 10 | * @param {Boolean} [cfg.freshCopy=true] Load a fresh JS source 11 | */ 12 | const loadScript = function (cfg) { 13 | var doc = cfg.doc || document, 14 | parent = (function () { 15 | var parent = cfg.parent || 'body'; 16 | if (parent === 'html') { 17 | return 'documentElement'; 18 | } else if (parent === 'head') { 19 | return 'head'; 20 | } else { 21 | return 'body'; 22 | } 23 | }()), 24 | parentEl = doc[parent] || doc['body'] || doc['head'] || doc['documentElement'], 25 | src = (cfg.src || cfg), 26 | freshCopy = (cfg.freshCopy === false) ? false : true, 27 | script = doc.createElement('script'); 28 | script.src = src + (freshCopy ? '' : ('?' + Math.random())); 29 | parentEl.appendChild(script); 30 | }; 31 | 32 | export { loadScript }; 33 | -------------------------------------------------------------------------------- /extension/scripts/utils/minifyCss.js: -------------------------------------------------------------------------------- 1 | import { csspretty } from 'helpmate-css/dist/format/csspretty.js'; 2 | 3 | const minifyCss = function (cssCode) { 4 | return csspretty({ 5 | mode: 'minify', 6 | source: cssCode 7 | }); 8 | 9 | // Alternatively, use Yahoo's CSS Min library: 10 | // return YAHOO.compressor.cssmin(cssCode); 11 | }; 12 | 13 | export { minifyCss }; 14 | -------------------------------------------------------------------------------- /extension/scripts/utils/postMessageWithReturnAsync.js: -------------------------------------------------------------------------------- 1 | import { randomUUID } from './randomUUID.js'; 2 | 3 | const originMatchesTargetOrigin = function (origin, targetOrigin) { 4 | if ( 5 | targetOrigin === '*' || 6 | origin === targetOrigin 7 | ) { 8 | return true; 9 | } else { 10 | return false; 11 | } 12 | }; 13 | 14 | const postMessageWithReturnAsync = function (targetWindow, data, targetOrigin) { 15 | return new Promise((resolve) => { 16 | const uuid = randomUUID(); 17 | 18 | const fn = (evt) => { 19 | if ( 20 | !( 21 | originMatchesTargetOrigin(evt.origin, targetOrigin) 22 | ) 23 | ) { 24 | return; 25 | } else { 26 | if (evt.data && typeof evt.data === 'object') { 27 | if (evt.data.originalData?.uuid === uuid) { 28 | window.removeEventListener('message', fn); 29 | resolve({ 30 | origin: evt.origin, 31 | data: { 32 | uuid: evt.data.uuid, 33 | flagProxy: evt.data.flagProxy, 34 | originalData: evt.data.originalData 35 | } 36 | }); 37 | } 38 | } 39 | } 40 | }; 41 | window.addEventListener('message', fn); 42 | 43 | targetWindow.postMessage( 44 | { 45 | uuid, 46 | flagProxy: true, 47 | originalData: data 48 | }, 49 | targetOrigin 50 | ); 51 | }); 52 | }; 53 | 54 | export { postMessageWithReturnAsync }; 55 | -------------------------------------------------------------------------------- /extension/scripts/utils/randomUUID.js: -------------------------------------------------------------------------------- 1 | const randomUUID = function () { 2 | let uuid; 3 | if (typeof crypto.randomUUID === 'function') { 4 | uuid = crypto.randomUUID(); 5 | } else { 6 | // https://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid/2117523#2117523 7 | uuid = ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c => 8 | (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16) 9 | ); 10 | } 11 | return uuid; 12 | }; 13 | 14 | export { randomUUID }; 15 | -------------------------------------------------------------------------------- /extension/scripts/utils/removeComments.js: -------------------------------------------------------------------------------- 1 | // NOTE: This file is not being used as of now. It is being kept here for future reference. 2 | 3 | // http://james.padolsey.com/javascript/javascript-comment-removal-revisted/ 4 | const removeComments = function (str) { 5 | var uid = '_' + (+new Date()), 6 | primatives = [], 7 | primIndex = 0; 8 | 9 | return ( 10 | str 11 | /* Remove strings */ 12 | .replace(/(['"])(\\\1|.)+?\1/g, function(match){ 13 | primatives[primIndex] = match; 14 | return (uid + '') + primIndex++; 15 | }) 16 | 17 | /* Remove Regexes */ 18 | .replace(/([^/])(\/(?!\*|\/)(\\\/|.)+?\/[gim]{0,3})/g, function(match, $1, $2){ 19 | primatives[primIndex] = $2; 20 | return $1 + (uid + '') + primIndex++; 21 | }) 22 | 23 | /* 24 | - Remove single-line comments that contain would-be multi-line delimiters 25 | E.g. // Comment /* <-- 26 | - Remove multi-line comments that contain would be single-line delimiters 27 | E.g. /* // <-- 28 | */ 29 | .replace(/\/\/.*?\/?\*.+?(?=\n|\r|$)|\/\*[\s\S]*?\/\/[\s\S]*?\*\//g, '') 30 | 31 | /* 32 | Remove single and multi-line comments, 33 | no consideration of inner-contents 34 | */ 35 | .replace(/\/\/.+?(?=\n|\r|$)|\/\*[\s\S]+?\*\//g, '') 36 | 37 | /* 38 | Remove multi-line comments that have a replaced ending (string/regex) 39 | Greedy, so no inner strings/regexes will stop it. 40 | */ 41 | .replace(RegExp('\\/\\*[\\s\\S]+' + uid + '\\d+', 'g'), '') 42 | 43 | /* Bring back strings & regexes */ 44 | .replace(RegExp(uid + '(\\d+)', 'g'), function(match, n){ 45 | return primatives[n]; 46 | }) 47 | ); 48 | }; 49 | 50 | export { removeComments }; 51 | -------------------------------------------------------------------------------- /extension/scripts/utils/sassToCss.js: -------------------------------------------------------------------------------- 1 | /* global Sass */ 2 | 3 | const sassToCss = function (sassCode, options, cb) { 4 | Sass.compile(sassCode, options, function (output) { 5 | if (output.message) { 6 | cb(output); 7 | } else { 8 | var cssCode = output.text; 9 | cb(null, cssCode); 10 | } 11 | }); 12 | }; 13 | 14 | export { sassToCss }; 15 | -------------------------------------------------------------------------------- /extension/scripts/utils/waterfall.js: -------------------------------------------------------------------------------- 1 | // https://github.com/hydiak/a-sync-waterfall/blob/master/index.js 2 | // MIT license (by Elan Shanker). 3 | 4 | var executeSync = function() { 5 | var args = Array.prototype.slice.call(arguments); 6 | if (typeof args[0] === 'function') { 7 | args[0].apply(null, args.splice(1)); 8 | } 9 | }; 10 | 11 | var executeAsync = function(fn) { 12 | if (typeof setImmediate === 'function') { 13 | setImmediate(fn); 14 | } else if (typeof process !== 'undefined' && process.nextTick) { 15 | process.nextTick(fn); 16 | } else { 17 | setTimeout(fn, 0); 18 | } 19 | }; 20 | 21 | var makeIterator = function(tasks) { 22 | var makeCallback = function(index) { 23 | var fn = function() { 24 | if (tasks.length) { 25 | tasks[index].apply(null, arguments); 26 | } 27 | return fn.next(); 28 | }; 29 | fn.next = function() { 30 | return (index < tasks.length - 1) ? makeCallback(index + 1) : null; 31 | }; 32 | return fn; 33 | }; 34 | return makeCallback(0); 35 | }; 36 | 37 | var _isArray = Array.isArray || function(maybeArray) { 38 | return Object.prototype.toString.call(maybeArray) === '[object Array]'; 39 | }; 40 | 41 | var waterfall = function(tasks, callback, forceAsync) { 42 | var nextTick = forceAsync ? executeAsync : executeSync; 43 | callback = callback || function() {}; 44 | if (!_isArray(tasks)) { 45 | var err = new Error('First argument to waterfall must be an array of functions'); 46 | return callback(err); 47 | } 48 | if (!tasks.length) { 49 | return callback(); 50 | } 51 | var wrapIterator = function(iterator) { 52 | return function(err) { 53 | if (err) { 54 | callback.apply(null, arguments); 55 | callback = function() {}; 56 | } else { 57 | var args = Array.prototype.slice.call(arguments, 1); 58 | var next = iterator.next(); 59 | if (next) { 60 | args.push(wrapIterator(next)); 61 | } else { 62 | args.push(callback); 63 | } 64 | nextTick(function() { 65 | iterator.apply(null, args); 66 | }); 67 | } 68 | }; 69 | }; 70 | wrapIterator(makeIterator(tasks))(); 71 | }; 72 | 73 | export { waterfall }; 74 | -------------------------------------------------------------------------------- /extension/src/actions.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { connect } from 'react-redux'; 4 | 5 | import { CommandPalette } from './command-palette/command-palette.js'; 6 | 7 | import { 8 | APP_$_CLOSE_COMMAND_PALETTE 9 | } from 'reducers/actionTypes.js'; 10 | 11 | function mapStateToProps(state) { 12 | return { 13 | open: state.app.commandPalette.open 14 | }; 15 | } 16 | 17 | const Actions = function (props) { 18 | return ( 19 |
20 | 28 |
29 | ); 30 | }; 31 | Actions.propTypes = { 32 | open: PropTypes.bool, 33 | dispatch: PropTypes.func 34 | }; 35 | 36 | const _Actions = connect(mapStateToProps)(Actions); 37 | 38 | export { _Actions as Actions }; 39 | -------------------------------------------------------------------------------- /extension/src/appUtils/flagDevMode.js: -------------------------------------------------------------------------------- 1 | /* global chrome */ 2 | 3 | import { requestUserViaConsoleToReportUnexpectedError } from './requestUserViaConsoleToReportUnexpectedError.js'; 4 | 5 | export const flagDevMode = (function () { 6 | let flag = false; 7 | try { 8 | // TODO: Verify that this works well across browsers 9 | // https://stackoverflow.com/questions/12830649/check-if-chrome-extension-installed-in-unpacked-mode/20227975#20227975 10 | flag = (!('update_url' in chrome.runtime.getManifest())); 11 | } catch (e) { 12 | requestUserViaConsoleToReportUnexpectedError(e); 13 | } 14 | return flag; 15 | })(); 16 | -------------------------------------------------------------------------------- /extension/src/appUtils/readyStateConstants.js: -------------------------------------------------------------------------------- 1 | export const 2 | READYSTATE = 'READYSTATE', 3 | UNINITIALIZED = 'UNINITIALIZED', 4 | LOADING = 'LOADING', 5 | LOADED = 'LOADED', 6 | ERROR = 'ERROR'; 7 | -------------------------------------------------------------------------------- /extension/src/appUtils/requestUserViaConsoleToReportUnexpectedError.js: -------------------------------------------------------------------------------- 1 | // Use this for the cases where the code should never reach in imaginable scenarios. 2 | export const requestUserViaConsoleToReportUnexpectedError = function (e) { 3 | console.error(e); 4 | console.error([ 5 | 'An unexpected error was encountered by Magic CSS.', 6 | 'Kindly report this issue at:', 7 | ' https://github.com/webextensions/live-css-editor/issues' 8 | ].join('\n')); 9 | }; 10 | -------------------------------------------------------------------------------- /extension/src/appUtils/siteOrigin.js: -------------------------------------------------------------------------------- 1 | import { flagDevMode } from './flagDevMode.js'; 2 | 3 | let originToUse = 'https://www.webextensions.org'; 4 | if (flagDevMode) { 5 | originToUse = 'https://local.webextensions.org:4430'; 6 | } 7 | 8 | export const siteOrigin = originToUse; 9 | -------------------------------------------------------------------------------- /extension/src/common-styles/common-styles.css: -------------------------------------------------------------------------------- 1 | .magicss-material-ui-dialog { 2 | -z-index: 2147483646 !important; 3 | z-index: 2147483647 !important; 4 | } 5 | 6 | /* Begin: Generic (not targeting specific components via CSS selector) fixes */ 7 | 8 | .magicss-material-ui-dialog { 9 | font-size: 16px; /* https://code.visualstudio.com/ */ 10 | } 11 | 12 | .magicss-material-ui-dialog :global(.MuiInputBase-input) { 13 | color: rgba(0, 0, 0, 0.87); /* https://visualstudio.microsoft.com/ */ 14 | } 15 | 16 | /* End: Generic (not targeting specific components via CSS selector) fixes */ 17 | -------------------------------------------------------------------------------- /extension/src/dialogs/searchIcons/searchIconsConfiguration.css: -------------------------------------------------------------------------------- 1 | .SearchIconsConfiguration { 2 | } 3 | 4 | .magicss-dialog-search-icons { 5 | } 6 | -------------------------------------------------------------------------------- /extension/src/main.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { createRoot } from 'react-dom/client'; 3 | 4 | import { Provider } from 'react-redux'; 5 | 6 | import { Actions } from './actions.js'; 7 | 8 | import { SearchIcons } from './dialogs/searchIcons/searchIcons.js'; 9 | import { SearchIconsConfiguration } from './dialogs/searchIcons/searchIconsConfiguration.js'; 10 | 11 | import { store } from './store.js'; 12 | 13 | const Main = function () { 14 | return ( 15 |
16 | 17 | 18 | 19 | 20 | 21 |
22 | ); 23 | }; 24 | 25 | window.reactMain = function () { 26 | // https://reactjs.org/blog/2022/03/08/react-18-upgrade-guide.html 27 | const container = document.getElementsByClassName('magicss-command-palette-root')[0]; 28 | const root = createRoot(container); // createRoot(container!) if you use TypeScript 29 | 30 | root.render(
); 31 | }; 32 | 33 | window.reactMain(); 34 | -------------------------------------------------------------------------------- /extension/src/node_modules/AfterDelay/AfterDelay.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | const AfterDelay = function ({ children, delay }) { 5 | const [showChildren, setShowChildren] = useState(false); 6 | useEffect(() => { 7 | const timeout = setTimeout(() => { 8 | setShowChildren(true); 9 | }, delay || 0); 10 | return () => { 11 | clearTimeout(timeout); 12 | }; 13 | }, []); 14 | if (showChildren) { 15 | return children; 16 | } else { 17 | return null; 18 | } 19 | }; 20 | AfterDelay.propTypes = { 21 | children: PropTypes.node, 22 | delay: PropTypes.number 23 | }; 24 | 25 | export { AfterDelay }; 26 | -------------------------------------------------------------------------------- /extension/src/node_modules/Loading/Loading.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | import './Loading.css'; 5 | 6 | const Loading = function ({ type, style, theme }) { 7 | if (type === 'line-scale') { 8 | return ( 9 |
10 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | ); 29 | } else { 30 | return ( 31 |
32 | ... 33 |
34 | ); 35 | } 36 | }; 37 | Loading.propTypes = { 38 | type: PropTypes.string, 39 | style: PropTypes.object, 40 | theme: PropTypes.string 41 | }; 42 | 43 | export { Loading }; 44 | -------------------------------------------------------------------------------- /extension/src/node_modules/constants/readyStates.js: -------------------------------------------------------------------------------- 1 | export const 2 | READYSTATE = 'READYSTATE', 3 | STATUSCODE = 'STATUSCODE', 4 | UNINITIALIZED = 'UNINITIALIZED', 5 | LOADING = 'LOADING', 6 | LOADED = 'LOADED', 7 | ERROR = 'ERROR'; 8 | -------------------------------------------------------------------------------- /extension/src/node_modules/reducers/actionTypes.js: -------------------------------------------------------------------------------- 1 | export const APP_$_CLOSE_COMMAND_PALETTE = 'APP_$_CLOSE_COMMAND_PALETTE'; 2 | export const APP_$_CLOSE_SEARCH_ICONS = 'APP_$_CLOSE_SEARCH_ICONS'; 3 | export const APP_$_CLOSE_SEARCH_ICONS_CONFIGURATION = 'APP_$_CLOSE_SEARCH_ICONS_CONFIGURATION'; 4 | export const APP_$_OPEN_COMMAND_PALETTE = 'APP_$_OPEN_COMMAND_PALETTE'; 5 | export const APP_$_OPEN_SEARCH_ICONS = 'APP_$_OPEN_SEARCH_ICONS'; 6 | export const APP_$_OPEN_SEARCH_ICONS_CONFIGURATION = 'APP_$_OPEN_SEARCH_ICONS_CONFIGURATION'; 7 | export const APP_$_SEARCH_ICONS_CONFIGURATION_SET_ACCESS_KEY = 'APP_$_SEARCH_ICONS_CONFIGURATION_SET_ACCESS_KEY'; 8 | export const APP_$_SEARCH_ICONS_CONFIGURATION_SET_SECRET = 'APP_$_SEARCH_ICONS_CONFIGURATION_SET_SECRET'; 9 | -------------------------------------------------------------------------------- /extension/src/options/Main/Form/Form.css: -------------------------------------------------------------------------------- 1 | .Form { 2 | } 3 | 4 | .inputSection:not(:first-child) { 5 | margin-top: 10px; 6 | } 7 | 8 | .accordionSummary { 9 | margin-left: 10px; 10 | } 11 | -------------------------------------------------------------------------------- /extension/src/options/Main/Form/FormEntries/LoadForIframe.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from 'react'; 2 | import { 3 | chromeStorageForExtensionData, 4 | notifyUser 5 | } from '../helpers.js'; 6 | 7 | import { USER_PREFERENCE_ALL_FRAMES } from '../../../../../constants.js'; 8 | 9 | const LoadForIframe = function () { 10 | const [allFrames, setAllFrames] = useState(''); 11 | 12 | useEffect(() => { 13 | chromeStorageForExtensionData.get(USER_PREFERENCE_ALL_FRAMES, function (values) { 14 | let valueToSet = 'no'; 15 | if (values && values[USER_PREFERENCE_ALL_FRAMES] === 'yes') { 16 | valueToSet = 'yes'; 17 | } 18 | setAllFrames(valueToSet); 19 | }); 20 | }, []); 21 | 22 | const handleAllFramesChange = function (evt) { 23 | let valueToSet = 'no'; 24 | if (evt.target.checked) { 25 | valueToSet = 'yes'; 26 | } 27 | setAllFrames(valueToSet); 28 | chromeStorageForExtensionData.set({ [USER_PREFERENCE_ALL_FRAMES]: valueToSet }); 29 | notifyUser(); 30 | }; 31 | return ( 32 |
33 |
34 |
35 | 49 |
50 |
51 |
52 | ); 53 | }; 54 | 55 | export { LoadForIframe }; 56 | -------------------------------------------------------------------------------- /extension/src/options/Main/Form/helpers.js: -------------------------------------------------------------------------------- 1 | /* global chrome */ 2 | 3 | import { getBrowser } from 'helpmate/dist/browser/getBrowser.js'; 4 | import { alertNote } from '../../../../scripts/utils/alertNote.js'; 5 | 6 | const chromeStorageForExtensionData = chrome.storage.sync || chrome.storage.local; 7 | 8 | const notifyUser = function () { 9 | alertNote('Your change would apply next time onwards :-)', 2500); 10 | }; 11 | 12 | const isSassUiAllowed = (function () { 13 | let flagAllowSassUi = null; 14 | return async function () { 15 | if (flagAllowSassUi === null) { 16 | const browserDetails = await getBrowser(); 17 | if (browserDetails.name === 'firefox') { 18 | flagAllowSassUi = false; 19 | } else { 20 | flagAllowSassUi = true; 21 | } 22 | } 23 | return flagAllowSassUi; 24 | }; 25 | })(); 26 | 27 | export { 28 | chromeStorageForExtensionData, 29 | notifyUser, 30 | isSassUiAllowed 31 | }; 32 | -------------------------------------------------------------------------------- /extension/src/options/Main/Main.css: -------------------------------------------------------------------------------- 1 | .Main { 2 | } 3 | 4 | .baseBlock { 5 | width: 410px; 6 | margin: 0 auto; 7 | padding: 20px; 8 | } 9 | @media screen and (min-width: 640px) { 10 | .baseBlock { 11 | width: 570px; 12 | } 13 | } 14 | @media screen and (min-width: 768px) { 15 | .baseBlock { 16 | width: 698px; 17 | } 18 | } 19 | @media screen and (min-width: 1024px) { 20 | .baseBlock { 21 | width: 954px; 22 | } 23 | } 24 | 25 | .MainUiWrapper { 26 | border-radius: 5px; 27 | box-shadow: 2px 4px 10px 0 rgb(0 0 0 / 25%); 28 | padding: 40px; 29 | 30 | display: flex; 31 | } 32 | -------------------------------------------------------------------------------- /extension/src/options/Main/Tabs/TabAccount.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | import React from 'react'; 4 | 5 | import { RegistrationOptions } from './TabAccount/RegistrationOptions.js'; 6 | 7 | 8 | const TabAccount = function () { 9 | return ( 10 |
11 | 12 |
13 | ); 14 | }; 15 | 16 | export { TabAccount }; 17 | -------------------------------------------------------------------------------- /extension/src/options/Main/Tabs/TabAccount/RegistrationOptions.css: -------------------------------------------------------------------------------- 1 | .RegistrationOptions { 2 | } 3 | 4 | .subscriptionFeatureEntry { 5 | } 6 | 7 | .block { 8 | padding: 40px 40px; 9 | border: 1px solid #b7b7b7; 10 | } 11 | 12 | .blockHeader { 13 | display: flex; 14 | justify-content: center; 15 | font-size: 28px; 16 | } 17 | 18 | .blockMessage { 19 | font-size: 14px; 20 | } 21 | 22 | .blockList { 23 | font-size: 14px; 24 | } 25 | 26 | .blockButton { 27 | margin-top: 30px; 28 | display: flex; 29 | justify-content: center; 30 | } 31 | 32 | /* https://weekendprojects.dev/posts/creating-jumping-dots-css-animation-with-examples/ */ 33 | .dotTyping { 34 | position: relative; 35 | left: -9999px; 36 | width: 10px; 37 | height: 10px; 38 | border-radius: 5px; 39 | background-color: #152c4a; 40 | color: #152c4a; 41 | box-shadow: 9984px 0 0 0 #152c4a, 9999px 0 0 0 #152c4a, 10014px 0 0 0 #152c4a; 42 | animation: dot-typing 1.5s infinite linear; 43 | } 44 | @keyframes dot-typing { 45 | 0% { 46 | box-shadow: 9984px 0 0 0 #152c4a, 9999px 0 0 0 #152c4a, 10014px 0 0 0 #152c4a; 47 | } 48 | 49 | 16.667% { 50 | box-shadow: 9984px -10px 0 0 #152c4a, 9999px 0 0 0 #152c4a, 10014px 0 0 0 #152c4a; 51 | } 52 | 53 | 33.333% { 54 | box-shadow: 9984px 0 0 0 #152c4a, 9999px 0 0 0 #152c4a, 10014px 0 0 0 #152c4a; 55 | } 56 | 57 | 50% { 58 | box-shadow: 9984px 0 0 0 #152c4a, 9999px -10px 0 0 #152c4a, 10014px 0 0 0 #152c4a; 59 | } 60 | 61 | 66.667% { 62 | box-shadow: 9984px 0 0 0 #152c4a, 9999px 0 0 0 #152c4a, 10014px 0 0 0 #152c4a; 63 | } 64 | 65 | 83.333% { 66 | box-shadow: 9984px 0 0 0 #152c4a, 9999px 0 0 0 #152c4a, 10014px -10px 0 0 #152c4a; 67 | } 68 | 69 | 100% { 70 | box-shadow: 9984px 0 0 0 #152c4a, 9999px 0 0 0 #152c4a, 10014px 0 0 0 #152c4a; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /extension/src/options/Main/Tabs/TabHelp.css: -------------------------------------------------------------------------------- 1 | .TabHelp { 2 | } 3 | 4 | .faqItem:not(:first-child) { 5 | margin-top: 10px; 6 | } 7 | 8 | .TabHelp ul { 9 | list-style-type: disc; 10 | } 11 | -------------------------------------------------------------------------------- /extension/src/options/Main/Tabs/TabOptions.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import { Form } from '../Form/Form.js'; 4 | 5 | const TabOptions = function () { 6 | return ( 7 |
8 |
9 |
10 | ); 11 | }; 12 | 13 | export { TabOptions }; 14 | -------------------------------------------------------------------------------- /extension/src/options/Main/commonStyles.css: -------------------------------------------------------------------------------- 1 | .gridDesktop2ColumnsMobile1Column { 2 | display: grid; 3 | grid-template-columns: 1fr; 4 | } 5 | 6 | @media screen and (min-width: 1024px) { 7 | .gridDesktop2ColumnsMobile1Column { 8 | grid-template-columns: 1fr 1fr; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /extension/src/options/helpers/helpers.js: -------------------------------------------------------------------------------- 1 | /* global chrome */ 2 | 3 | import { alertNote } from '../../../scripts/utils/alertNote.js'; 4 | 5 | // TODO: DUPLICATE: Move this to a common file (Used elsewhere with name "flagDevMode") 6 | const FLAG_DEV_MODE = (function () { 7 | let flag = false; 8 | try { 9 | const manifest = chrome.runtime.getManifest(); 10 | // TODO: Verify that this works well across browsers 11 | // https://stackoverflow.com/questions/12830649/check-if-chrome-extension-installed-in-unpacked-mode/20227975#20227975 12 | flag = (!('update_url' in manifest)); 13 | } catch (e) { 14 | // do nothing 15 | } 16 | return flag; 17 | })(); 18 | 19 | const chromeStorageForExtensionData = chrome.storage.sync || chrome.storage.local; 20 | 21 | const notifyUser = function () { 22 | alertNote('Your change would apply next time onwards :-)', 2500); 23 | }; 24 | 25 | export { 26 | FLAG_DEV_MODE, 27 | chromeStorageForExtensionData, 28 | notifyUser 29 | }; 30 | -------------------------------------------------------------------------------- /extension/src/options/options.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable react/jsx-no-target-blank */ 2 | 3 | import React from 'react'; 4 | import { createRoot } from 'react-dom/client'; 5 | 6 | import './optionsSetup.js'; 7 | 8 | import { Main } from './Main/Main.js'; 9 | 10 | import './styles-reset.css'; 11 | 12 | const renderReactApp = function () { 13 | // https://reactjs.org/blog/2022/03/08/react-18-upgrade-guide.html 14 | const container = document.getElementById('root'); 15 | const root = createRoot(container); // createRoot(container!) if you use TypeScript 16 | 17 | root.render(
); 18 | }; 19 | 20 | renderReactApp(); 21 | -------------------------------------------------------------------------------- /extension/src/options/optionsZustandStore.js: -------------------------------------------------------------------------------- 1 | /* global chrome */ 2 | 3 | import { create } from 'zustand'; 4 | 5 | import { 6 | READYSTATE, 7 | UNINITIALIZED, 8 | LOADED 9 | } from '../appUtils/readyStateConstants.js'; 10 | 11 | const useDialogsStore = create((set) => ({ 12 | flagShowConnectViaDialog: false, 13 | 14 | setFlagShowConnectViaDialog: (flagShowConnectViaDialog) => { 15 | set({ flagShowConnectViaDialog }); 16 | } 17 | })); 18 | 19 | const useAuthStore = create((set, get) => ({ // eslint-disable-line no-unused-vars 20 | [READYSTATE]: UNINITIALIZED, 21 | value: null, 22 | 23 | isLoggedIn: () => { 24 | const auth = get(); 25 | 26 | const authReadyState = auth[READYSTATE]; 27 | const authValue = auth.value; 28 | 29 | const flagLoggedIn = !!( 30 | authReadyState === LOADED && 31 | authValue && 32 | authValue.accountUuid && 33 | authValue.validUntil && 34 | (authValue.validUntil > Date.now()) 35 | ); 36 | 37 | return flagLoggedIn; 38 | }, 39 | logout: () => { 40 | set({ 41 | [READYSTATE]: LOADED, 42 | value: null 43 | }); 44 | }, 45 | loginWithAuthValue: (authValue) => { 46 | set({ 47 | [READYSTATE]: LOADED, 48 | value: authValue 49 | }); 50 | }, 51 | refresh: async () => { 52 | const authValue = await new Promise((resolve, reject) => { // eslint-disable-line no-unused-vars 53 | chrome.storage.local.get(['authValue'], (result) => { 54 | resolve(result.authValue || null); 55 | }); 56 | }); 57 | set({ 58 | [READYSTATE]: LOADED, 59 | value: authValue || null 60 | }); 61 | } 62 | })); 63 | (async () => { 64 | const auth = useAuthStore.getState(); 65 | await auth.refresh(); 66 | })(); 67 | 68 | export { 69 | useDialogsStore, 70 | useAuthStore 71 | }; 72 | -------------------------------------------------------------------------------- /extension/src/rootReducer/appReducer/appReducer.js: -------------------------------------------------------------------------------- 1 | const initialAppState = {}; 2 | 3 | import { searchIconsReducer } from './searchIconsReducer/searchIconsReducer.js'; 4 | import { commandPaletteReducer } from './commandPaletteReducer/commandPaletteReducer.js'; 5 | 6 | const appReducer = (draft = initialAppState, action) => { 7 | // const { 8 | // type, 9 | // payload 10 | // } = action; 11 | 12 | draft.app.commandPalette = commandPaletteReducer(draft.app.commandPalette, action); 13 | draft.app.searchIcons = searchIconsReducer(draft.app.searchIcons, action); 14 | 15 | return draft; 16 | }; 17 | 18 | export { appReducer }; 19 | -------------------------------------------------------------------------------- /extension/src/rootReducer/appReducer/commandPaletteReducer/commandPaletteReducer.js: -------------------------------------------------------------------------------- 1 | import { 2 | APP_$_OPEN_COMMAND_PALETTE, 3 | APP_$_CLOSE_COMMAND_PALETTE 4 | } from 'reducers/actionTypes.js'; 5 | 6 | const commandPaletteInitialState = {}; 7 | 8 | const commandPaletteReducer = (draft = commandPaletteInitialState, action) => { 9 | const { 10 | type, 11 | payload // eslint-disable-line no-unused-vars 12 | } = action; 13 | 14 | switch (type) { 15 | case APP_$_OPEN_COMMAND_PALETTE: 16 | draft.open = true; 17 | break; 18 | case APP_$_CLOSE_COMMAND_PALETTE: 19 | draft.open = false; 20 | break; 21 | } 22 | 23 | return draft; 24 | }; 25 | 26 | export { commandPaletteReducer }; 27 | -------------------------------------------------------------------------------- /extension/src/rootReducer/rootReducer.js: -------------------------------------------------------------------------------- 1 | import { produce } from 'immer'; 2 | 3 | import { appReducer } from './appReducer/appReducer.js'; 4 | 5 | const rootInitialState = { 6 | app: {} 7 | }; 8 | const rootReducer = function (state = rootInitialState, action) { 9 | return ( 10 | produce(state, function (draft) { 11 | return appReducer(draft, action); 12 | }) 13 | ); 14 | }; 15 | 16 | export { rootReducer }; 17 | -------------------------------------------------------------------------------- /extension/src/store.js: -------------------------------------------------------------------------------- 1 | import { createStore } from 'redux'; 2 | 3 | import { rootReducer } from './rootReducer/rootReducer.js'; 4 | 5 | const store = createStore(rootReducer); 6 | 7 | window.redux_store = store; 8 | 9 | export { store }; 10 | -------------------------------------------------------------------------------- /extension/ui-images/ban.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /extension/ui-images/ban_edited-white.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /extension/ui-images/ban_edited-yellow.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /extension/ui-images/ban_edited.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /extension/ui-images/close-x_edited-yellow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /extension/ui-images/close-x_edited.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /extension/ui-images/compress.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /extension/ui-images/copy.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /extension/ui-images/hash.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /extension/ui-images/hash_edited.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /extension/ui-images/icon-login_edited.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /extension/ui-images/icon-plus-yellow_edited.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /extension/ui-images/icon-plus.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /extension/ui-images/icon-settings.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /extension/ui-images/icon-shiny-check-green.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /extension/ui-images/icon-smile.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /extension/ui-images/line-wrap.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /extension/ui-images/line-wrap_edited.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /extension/ui-images/link-external.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /extension/ui-images/link-external_edited-yellow.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /extension/ui-images/link-internal_edited-yellow.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /extension/ui-images/logo-chrome-grayscale.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /extension/ui-images/logo-chrome-grayscale_edited.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | background 5 | 6 | 7 | 8 | Layer 1 9 | 10 | 11 | -------------------------------------------------------------------------------- /extension/ui-images/logo-chrome-web-store.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/live-css-editor/f2d3df6709ec8bd6662bbb58a6bc89a4c4377975/extension/ui-images/logo-chrome-web-store.png -------------------------------------------------------------------------------- /extension/ui-images/logo-chrome.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /extension/ui-images/logo-extension-mirror-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/live-css-editor/f2d3df6709ec8bd6662bbb58a6bc89a4c4377975/extension/ui-images/logo-extension-mirror-image.png -------------------------------------------------------------------------------- /extension/ui-images/logo-facebook.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 10 | 13 | 14 | -------------------------------------------------------------------------------- /extension/ui-images/logo-facebook_edited.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 10 | 13 | 14 | -------------------------------------------------------------------------------- /extension/ui-images/logo-firefox_edited.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/live-css-editor/f2d3df6709ec8bd6662bbb58a6bc89a4c4377975/extension/ui-images/logo-firefox_edited.png -------------------------------------------------------------------------------- /extension/ui-images/logo-github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/live-css-editor/f2d3df6709ec8bd6662bbb58a6bc89a4c4377975/extension/ui-images/logo-github.png -------------------------------------------------------------------------------- /extension/ui-images/logo-github_edited.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/live-css-editor/f2d3df6709ec8bd6662bbb58a6bc89a4c4377975/extension/ui-images/logo-github_edited.png -------------------------------------------------------------------------------- /extension/ui-images/logo-google-chrome.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /extension/ui-images/logo-microsoft-edge.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /extension/ui-images/logo-microsoft-edge_edited.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /extension/ui-images/logo-microsoft.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /extension/ui-images/logo-mozilla-add-ons-store.svg: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /extension/ui-images/logo-mozilla-add-ons-store_edited-black.svg: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /extension/ui-images/logo-mozilla-add-ons-store_edited.svg: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /extension/ui-images/logo-mozilla-addons_edited.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/live-css-editor/f2d3df6709ec8bd6662bbb58a6bc89a4c4377975/extension/ui-images/logo-mozilla-addons_edited.png -------------------------------------------------------------------------------- /extension/ui-images/logo-opera.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /extension/ui-images/logo-thenounproject.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | Created by potrace 1.11, written by Peter Selinger 2001-2013 9 | 10 | 12 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /extension/ui-images/logo-twitter-black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/live-css-editor/f2d3df6709ec8bd6662bbb58a6bc89a4c4377975/extension/ui-images/logo-twitter-black.png -------------------------------------------------------------------------------- /extension/ui-images/mail.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /extension/ui-images/mail_edited.svg: -------------------------------------------------------------------------------- 1 | Layer 1 4 | -------------------------------------------------------------------------------- /extension/ui-images/pin.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /extension/ui-images/pin_edited.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /extension/ui-images/plus.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /extension/ui-images/plus_edited.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /extension/ui-images/point-and-click.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /extension/ui-images/point-and-click_edited-yellow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /extension/ui-images/point-and-click_edited.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /extension/ui-images/reload.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /extension/ui-images/reload_edited-yellow.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /extension/ui-images/reload_edited.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /extension/ui-images/settings-server.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /extension/ui-images/settings-server_edited.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /extension/ui-images/settings.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /extension/ui-images/smiley.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /extension/ui-images/triple-dots.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /extension/ui-images/triple-dots_edited.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /extension/ui-images/unordered-list.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /extension/ui-images/unordered-list_edited.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /extension/ui-images/warning-circle.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /extension/ui-images/warning-circle_edited.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /extension/ui-images/warning.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /extension/ui-images/watch.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /extension/ui-images/watch_edited-yellow.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /extension/ui-images/watch_edited.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /extension/webpack/utils/notify-completion-status.js: -------------------------------------------------------------------------------- 1 | const 2 | notifier = require('../../../utils/notifications/notifications.js'); 3 | 4 | const notifyCompletionStatus = (stats) => { 5 | const jsonStats = stats.toJson(); 6 | 7 | let overallStatus = 'info'; 8 | 9 | let statusMsg = ''; 10 | const whitespaceChar = ' '; // A normal space character is trimmed in notifications. This character (U+2000) is not trimmed in notification. 11 | if (stats.hasErrors()) { 12 | statusMsg += `${whitespaceChar}\nWebpack build failed.`; 13 | } else { 14 | statusMsg += `${whitespaceChar}\nWebpack build completed.`; 15 | } 16 | 17 | if (stats.hasErrors()) { 18 | overallStatus = 'error'; 19 | 20 | if (jsonStats.errors.length) { 21 | statusMsg += `\n${whitespaceChar}\n${jsonStats.errors.length} error(s) occurred.`; 22 | } else { 23 | statusMsg += `\n${whitespaceChar}\nSome error(s) occurred. Analyze webpack stats of compilation.children for further details.`; 24 | } 25 | } 26 | if (stats.hasWarnings()) { 27 | overallStatus = 'warn'; 28 | 29 | if (jsonStats.warnings.length) { 30 | statusMsg += `\n${whitespaceChar}\n${jsonStats.warnings.length} warning(s) occurred.`; 31 | } else { 32 | statusMsg += `\n${whitespaceChar}\nSome warning(s) occurred. Analyze webpack stats of compilation.children for further details.`; 33 | } 34 | } 35 | 36 | const currentTime = (function () { 37 | const d = new Date(); 38 | 39 | return ( 40 | new Date( 41 | d.getTime() - 42 | d.getTimezoneOffset() * 60 * 1000 43 | ) 44 | ).toISOString().substring(11, 19); 45 | }()); 46 | const title = `${require('../../../package.json').name} @ ${currentTime} (in ${stats.endTime - stats.startTime}ms)`; 47 | 48 | if (overallStatus === 'error') { 49 | notifier.error(title, statusMsg); 50 | } else if (overallStatus === 'warn') { 51 | notifier.warn(title, statusMsg); 52 | } else { 53 | notifier.info(title, statusMsg); 54 | } 55 | }; 56 | 57 | module.exports = notifyCompletionStatus; 58 | -------------------------------------------------------------------------------- /extras-for-edge-extension-package/logos/icon-150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/live-css-editor/f2d3df6709ec8bd6662bbb58a6bc89a4c4377975/extras-for-edge-extension-package/logos/icon-150.png -------------------------------------------------------------------------------- /extras-for-edge-extension-package/logos/icon-44.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/live-css-editor/f2d3df6709ec8bd6662bbb58a6bc89a4c4377975/extras-for-edge-extension-package/logos/icon-44.png -------------------------------------------------------------------------------- /extras-for-edge-extension-package/logos/icon-50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/live-css-editor/f2d3df6709ec8bd6662bbb58a6bc89a4c4377975/extras-for-edge-extension-package/logos/icon-50.png -------------------------------------------------------------------------------- /live-css/.gitignore: -------------------------------------------------------------------------------- 1 | # Local config files used for debugging 2 | .live-css.config.js 3 | .live-css.config*(*).js 4 | 5 | # Files generated by "$ npm pack" 6 | webextensions-live-css-*.tgz 7 | 8 | # Logs 9 | logs 10 | *.log 11 | npm-debug.log* 12 | 13 | # Runtime data 14 | pids 15 | *.pid 16 | *.seed 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | 24 | # nyc test coverage 25 | .nyc_output 26 | 27 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 28 | .grunt 29 | 30 | # node-waf configuration 31 | .lock-wscript 32 | 33 | # Compiled binary addons (http://nodejs.org/api/addons.html) 34 | build/Release 35 | 36 | # Dependency directories 37 | node_modules 38 | jspm_packages 39 | 40 | # Optional npm cache directory 41 | .npm 42 | 43 | # Optional REPL history 44 | .node_repl_history 45 | -------------------------------------------------------------------------------- /live-css/.npmignore: -------------------------------------------------------------------------------- 1 | scripts/ 2 | test/ 3 | .nvmrc 4 | nodemon.json 5 | 6 | # Files generated by "$ npm install" 7 | node_modules/ 8 | 9 | # Local config files used for debugging 10 | .live-css.config.js 11 | .live-css.config*(*).js 12 | 13 | # Files generated by "$ npm pack" 14 | webextensions-live-css-*.tgz 15 | -------------------------------------------------------------------------------- /live-css/.nvmrc: -------------------------------------------------------------------------------- 1 | 20.16.0 -------------------------------------------------------------------------------- /live-css/live-css.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 16 | 17 | 18 | 19 |
20 |
21 |
22 | live-css server is running :-) 23 |
24 | 25 |
26 | 27 | 32 | 33 |
34 | 35 | 40 | 41 |
42 | 43 | 50 |
51 |
52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /live-css/nodemon.json: -------------------------------------------------------------------------------- 1 | { 2 | "verbose": true, 3 | "watch": [ 4 | "index.js", 5 | "default.live-css.config.js", 6 | ".live-css.config.js" 7 | ], 8 | "ext": "js json cjson", 9 | "ignore": [ 10 | ".git", 11 | "node_modules", 12 | "test", 13 | "temp" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /live-css/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@webextensions/live-css", 3 | "version": "8.22.5", 4 | "description": "live-css is a Node JS based development server for use with the browser extension \"Live editor for CSS, Less & Sass - Magic CSS\" for Chrome/Edge/Firefox/Opera", 5 | "repository": "https://github.com/webextensions/live-css-editor.git", 6 | "homepage": "https://webextensions.org/", 7 | "main": "index.js", 8 | "bin": { 9 | "live-css": "./index.js" 10 | }, 11 | "scripts": { 12 | "start": "node index.js", 13 | "nodemon": " nodemon ./index.js", 14 | "nodemon:debug": "nodemon ./index.js -- --debug", 15 | "test": "echo \"Warning: no test specified\"" 16 | }, 17 | "dependencies": { 18 | "anymatch": "^3.1.3", 19 | "body-parser": "^1.20.2", 20 | "boxen": "=5.1.2", 21 | "chokidar-webextensions": "^2.0.4", 22 | "express": "^4.19.2", 23 | "find-free-port": "^2.0.0", 24 | "local-ip-addresses-and-hostnames": "=0.2.0", 25 | "nocache": "^4.0.0", 26 | "note-down": "=1.0.2", 27 | "socket.io": "^2.5.0", 28 | "tiny-emitter": "^2.1.0", 29 | "unused-filename": "=2.1.0", 30 | "update-notifier": "=5.1.0", 31 | "yargs": "^17.7.2" 32 | }, 33 | "devDependencies": { 34 | "nodemon": "^3.1.0" 35 | }, 36 | "keywords": [ 37 | "add-on", 38 | "addon", 39 | "apply", 40 | "browser", 41 | "changes", 42 | "chrome", 43 | "chromium", 44 | "css", 45 | "development", 46 | "edge", 47 | "editor", 48 | "extension", 49 | "files", 50 | "firefox", 51 | "google", 52 | "less", 53 | "live", 54 | "magic", 55 | "magicss", 56 | "microsoft", 57 | "mozilla", 58 | "opera", 59 | "refresh", 60 | "reload", 61 | "sass", 62 | "server", 63 | "watch", 64 | "webextension" 65 | ], 66 | "author": "Priyank Parashar", 67 | "license": "MIT" 68 | } 69 | -------------------------------------------------------------------------------- /live-css/scripts/ensure-no-npm-links.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd "$(dirname "$0")" 4 | 5 | # Colors: 6 | # http://stackoverflow.com/questions/5412761/using-colors-with-printf/5413029#5413029 7 | # http://stackoverflow.com/questions/4332478/read-the-current-text-color-in-a-xterm/4332530#4332530 8 | NORMAL=$(tput sgr0) 9 | RED=$(tput setaf 1) 10 | GREEN=$(tput setaf 2) 11 | YELLOW=$(tput setaf 3) 12 | BLUE=$(tput setaf 4) 13 | 14 | printf "\n${BLUE}Checking for npm-linked packages:${NORMAL}" 15 | if [[ $(ls -al ../node_modules | grep ^l | wc -l) == "0" ]]; then 16 | printf "${GREEN} Folder node_modules/ is free of npm-linked packages\n\n" 17 | exit 0 18 | else 19 | echo "${RED} npm linked package(s) found${NORMAL}" 20 | printf "${YELLOW}Warning: Get rid of npm-linked packages (they are generally used for debugging purposes)${NORMAL}" 21 | 22 | printf "\n${YELLOW}\n# List the npm-linked packages${NORMAL}\n" 23 | echo "${BLUE}$ ls -l ../node_modules | grep ^l${NORMAL}" 24 | ls -l ../node_modules | grep ^l 25 | echo "" 26 | exit 1 27 | fi 28 | -------------------------------------------------------------------------------- /live-css/test/example.css: -------------------------------------------------------------------------------- 1 | .example-inside-test-folder { 2 | font-weight: bold; 3 | } 4 | -------------------------------------------------------------------------------- /live-css/test/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Socket.IO chat 5 | 15 | 16 | 17 |
    18 | 19 | 20 | 21 | 22 | 23 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /live-css/test/sample-html/sample.css: -------------------------------------------------------------------------------- 1 | body > div span { 2 | font-size: 20px; 3 | -text-decoration: underline; 4 | } 5 | 6 | -------------------------------------------------------------------------------- /live-css/test/sample-html/sample.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
    16 | hello 17 | 18 |
    19 | .test123 20 |
    21 |
    22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /live-css/test/sample-html/sample2.css: -------------------------------------------------------------------------------- 1 | .test123 { 2 | font-weight: bold; 3 | } 4 | -------------------------------------------------------------------------------- /live-css/test/subfolder/deep-subfolder/example/.css: -------------------------------------------------------------------------------- 1 | .file-name-is-dot-css-style1 { 2 | margin-left: 140px; 3 | } 4 | -------------------------------------------------------------------------------- /live-css/test/subfolder/deep-subfolder/example/.file-name-starting-with-dot.css: -------------------------------------------------------------------------------- 1 | .file-name-starting-with-dot-style1 { 2 | margin-left: 150px; 3 | } 4 | -------------------------------------------------------------------------------- /live-css/test/subfolder/deep-subfolder/example/.gitignore: -------------------------------------------------------------------------------- 1 | !node_modules/ 2 | -------------------------------------------------------------------------------- /live-css/test/subfolder/deep-subfolder/example/css-file-with-invalid-sub-resource-integrity.css: -------------------------------------------------------------------------------- 1 | .css-file-with-invalid-sub-resource-integrity-style1 { 2 | margin-left: 50px; 3 | } 4 | -------------------------------------------------------------------------------- /live-css/test/subfolder/deep-subfolder/example/css-file-with-unexpected-extension.mystyles: -------------------------------------------------------------------------------- 1 | .css-file-with-unexpected-extension-style1 { 2 | margin-left: 240px; 3 | } 4 | -------------------------------------------------------------------------------- /live-css/test/subfolder/deep-subfolder/example/css-file-without-any-extension: -------------------------------------------------------------------------------- 1 | .css-file-without-any-extension-style1 { 2 | margin-left: 220px; 3 | } 4 | -------------------------------------------------------------------------------- /live-css/test/subfolder/deep-subfolder/example/dummy-folder/file-with-same-name-existing-at-two-different-paths.css: -------------------------------------------------------------------------------- 1 | .file-with-same-name-existing-at-two-different-paths-style2 { 2 | margin-left: 260px; 3 | } 4 | -------------------------------------------------------------------------------- /live-css/test/subfolder/deep-subfolder/example/example2.css: -------------------------------------------------------------------------------- 1 | .example2-style1 { 2 | margin-left: 40px; 3 | } 4 | -------------------------------------------------------------------------------- /live-css/test/subfolder/deep-subfolder/example/file-not-used.css: -------------------------------------------------------------------------------- 1 | /* This file is not referenced */ 2 | -------------------------------------------------------------------------------- /live-css/test/subfolder/deep-subfolder/example/file-placed-at-same-level-as-html-file-accessed-with-relative-path.css: -------------------------------------------------------------------------------- 1 | .file-placed-at-same-level-as-html-file-accessed-with-relative-path-style1 { 2 | margin-left: 60px; 3 | } 4 | -------------------------------------------------------------------------------- /live-css/test/subfolder/deep-subfolder/example/file-which-gets-linked-twice.css: -------------------------------------------------------------------------------- 1 | .file-which-gets-linked-twice-style1 { 2 | margin-left: 30px; 3 | } 4 | -------------------------------------------------------------------------------- /live-css/test/subfolder/deep-subfolder/example/file-with-same-name-existing-at-two-different-paths.css: -------------------------------------------------------------------------------- 1 | .file-with-same-name-existing-at-two-different-paths-style1 { 2 | margin-left: 240px; 3 | } 4 | -------------------------------------------------------------------------------- /live-css/test/subfolder/deep-subfolder/example/file-with-unicode-character-á.css: -------------------------------------------------------------------------------- 1 | .file-with-unicode-character-á-style1 { 2 | margin-left: 180px; 3 | } 4 | -------------------------------------------------------------------------------- /live-css/test/subfolder/deep-subfolder/example/file-with-unicode-character-ë.css: -------------------------------------------------------------------------------- 1 | .file-with-unicode-character-ë-style1 { 2 | margin-left: 200px; 3 | } 4 | -------------------------------------------------------------------------------- /live-css/test/subfolder/deep-subfolder/example/node_modules.css: -------------------------------------------------------------------------------- 1 | .node_modules-style1 { 2 | margin-left: 160px; 3 | } 4 | -------------------------------------------------------------------------------- /live-css/test/subfolder/deep-subfolder/example/node_modules/file-placed-in-a-folder-disabled-from-watch-by-default.css: -------------------------------------------------------------------------------- 1 | .file-placed-in-a-folder-disabled-from-watch-by-default-style1 { 2 | margin-left: 80px; 3 | } 4 | -------------------------------------------------------------------------------- /live-css/test/subfolder/deep-subfolder/example/styles.css: -------------------------------------------------------------------------------- 1 | .styles-style1 { 2 | margin-left: 20px; 3 | } 4 | -------------------------------------------------------------------------------- /live-css/test/subfolder/deep-subfolder/file-placed-one-level-up-than-html-file-accessed-with-relative-path.css: -------------------------------------------------------------------------------- 1 | .file-placed-one-level-up-than-html-file-accessed-with-relative-path-style1 { 2 | margin-left: 100px; 3 | } 4 | -------------------------------------------------------------------------------- /live-css/test/subfolder/file-placed-two-levels-up-than-html-file-accessed-with-relative-path.css: -------------------------------------------------------------------------------- 1 | .file-placed-two-levels-up-than-html-file-accessed-with-relative-path-style1 { 2 | margin-left: 120px; 3 | } 4 | -------------------------------------------------------------------------------- /notes-for-developers.md: -------------------------------------------------------------------------------- 1 | # How to load the extension in development mode 2 | 3 | ## For Chrome / Chromium / Edge / Kiwi / Opera 4 | 5 | - Load the unpacked extension via ```manifest.json``` from the ```extension/``` folder 6 | 7 | ## For Firefox 8 | 9 | - Temporarily, copy ```extension/manifest-firefox.json``` to ```extension/manifest.json``` 10 | - Load the unpacked extension via ```manifest.json``` from the ```extension/``` folder 11 | - Once you are done, before committing any changes, revert ```extension/manifest.json``` to its original state 12 | 13 | 14 | ## For Android Firefox 15 | 16 | - Connect the Android device to desktop via USB 17 | - Enable USB debugger in the Android device and Android Firefox 18 | - Go to ```about:debugging``` in the desktop Firefox 19 | - ```$ npm install --global web-ext``` 20 | - ```$ web-ext run --target=firefox-android``` # This would list the available devices 21 | - ```$ web-ext run --target=firefox-android --android-device=``` 22 | For example: ```$ web-ext run --target=firefox-android --android-device=A1B2C3D4E5F``` 23 | -------------------------------------------------------------------------------- /scripts/.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules/ 2 | -------------------------------------------------------------------------------- /scripts/all-is-well.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Colors: 4 | # http://stackoverflow.com/questions/5412761/using-colors-with-printf/5413029#5413029 5 | # http://stackoverflow.com/questions/4332478/read-the-current-text-color-in-a-xterm/4332530#4332530 6 | NORMAL=$(tput sgr0) 7 | RED=$(tput setaf 1) 8 | GREEN=$(tput setaf 2) 9 | YELLOW=$(tput setaf 3) 10 | BLUE=$(tput setaf 4) 11 | 12 | cd "$(dirname "$0")" 13 | 14 | printf "\n${BLUE}$ ./ensure-no-npm-links.sh${NORMAL}\n" 15 | ./ensure-no-npm-links.sh 16 | exitCodeNoNpmLinks=$? 17 | 18 | printf "\n${BLUE}$ ../live-css/scripts/ensure-no-npm-links.sh${NORMAL}\n" 19 | ../live-css/scripts/ensure-no-npm-links.sh 20 | exitCodeNoNpmLinksInLiveCss=$? 21 | 22 | printf "\n${BLUE}$ ./version-consistency-check.js${NORMAL}\n" 23 | ./version-consistency-check.js 24 | exitCodeVersionConsistency=$? 25 | 26 | cd .. 27 | 28 | printf "\n${BLUE}$ npm run lint${NORMAL}\n" 29 | npm run lint 30 | exitCodeLint=$? 31 | 32 | if [ "$exitCodeNoNpmLinks" == "0" ] && [ "$exitCodeNoNpmLinksInLiveCss" == "0" ] && [ "$exitCodeVersionConsistency" == "0" ] && [ "$exitCodeLint" == "0" ]; then 33 | printf "\n${GREEN}Success: All is well :-) ${NORMAL}\n" 34 | exit 0 35 | else 36 | if [ "$exitCodeNoNpmLinks" != "0" ]; then 37 | printf "\n${YELLOW}Warning: Get rid of npm linked packages in node_modules (they are generally used for debugging/development purposes)${NORMAL}" 38 | fi 39 | if [ "$exitCodeNoNpmLinksInLiveCss" != "0" ]; then 40 | printf "\n${YELLOW}Warning: Get rid of npm linked packages in live-css/node_modules (they are generally used for debugging/development purposes)${NORMAL}" 41 | fi 42 | if [ "$exitCodeVersionConsistency" != "0" ]; then 43 | printf "\n${RED}Error: Failure in code version consistency${NORMAL}" 44 | fi 45 | if [ "$exitCodeLint" != "0" ]; then 46 | printf "\n${RED}Error: Failure in code linting${NORMAL}" 47 | fi 48 | printf "\n" 49 | exit 1 50 | fi 51 | -------------------------------------------------------------------------------- /scripts/ensure-no-npm-links.sh: -------------------------------------------------------------------------------- 1 | ../live-css/scripts/ensure-no-npm-links.sh -------------------------------------------------------------------------------- /scripts/housekeeping/update-package-lock-json.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd "$(dirname "$0")" # Change directory to the folder containing this file 4 | cd ../.. # Change directory to project's root folder 5 | 6 | # Colors: 7 | # http://stackoverflow.com/questions/5412761/using-colors-with-printf/5413029#5413029 8 | # http://stackoverflow.com/questions/4332478/read-the-current-text-color-in-a-xterm/4332530#4332530 9 | NORMAL=$(tput sgr0) 10 | YELLOW=$(tput setaf 3) 11 | BLUE=$(tput setaf 4) 12 | 13 | printf "\n${YELLOW}About to clean up node_modules directory (will be reinstalled automatically):${NORMAL}" 14 | printf " 5" ; sleep 1 15 | printf " 4" ; sleep 1 16 | printf " 3" ; sleep 1 17 | printf " 2" ; sleep 1 18 | printf " 1" ; sleep 1 19 | printf " Start" 20 | 21 | printf "\n${BLUE}$ rm -rf node_modules${NORMAL}\n" 22 | rm -rf node_modules 23 | printf "\n${BLUE}$ rm -f package-lock.json${NORMAL}\n" 24 | rm -f package-lock.json 25 | 26 | # Repeat the same steps for the "live-css" folder 27 | printf "\n${BLUE}$ cd live-css${NORMAL}\n" 28 | cd live-css 29 | printf "\n${BLUE}$ rm -rf node_modules${NORMAL}\n" 30 | rm -rf node_modules 31 | printf "\n${BLUE}$ rm -f package-lock.json${NORMAL}\n" 32 | rm -f package-lock.json 33 | 34 | # Install inside the "live-css" directory first 35 | printf "\n${BLUE}$ npm install${NORMAL}\n" 36 | npm install 37 | 38 | # Install inside the root directory later 39 | printf "\n${BLUE}$ cd ..${NORMAL}\n" 40 | cd .. 41 | printf "\n${BLUE}$ npm install${NORMAL}\n" 42 | npm install 43 | -------------------------------------------------------------------------------- /scripts/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "scripts", 3 | "version": "0.0.1", 4 | "devDependencies": { 5 | "axios": "^1.3.4", 6 | "chalk": "^5.2.0", 7 | "word-wrap": "^1.2.3" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /testing-zone/child-css.css: -------------------------------------------------------------------------------- 1 | body p { 2 | color: red; 3 | } 4 | 5 | body all { 6 | color: red; 7 | } 8 | 9 | div p { 10 | 11 | } 12 | 13 | html div { 14 | color: maroon; 15 | } 16 | 17 | html div p { 18 | color: blue; 19 | } 20 | -------------------------------------------------------------------------------- /testing-zone/parent-css.css: -------------------------------------------------------------------------------- 1 | @import "child-css.css"; 2 | 3 | body a { 4 | -color: green; 5 | } 6 | 7 | body p { 8 | color: pink; 9 | } 10 | body p { 11 | color: blue; 12 | } 13 | body p { 14 | color: maroon; 15 | } 16 | 17 | body all { 18 | color: red; 19 | } 20 | -------------------------------------------------------------------------------- /tests/.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules/ 2 | -------------------------------------------------------------------------------- /tests/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "live-css-editor-tests", 3 | "version": "8.22.5", 4 | "scripts": { 5 | "test": " cp ../extension-dist/manifest-puppeteer.json ../extension-dist/manifest.json ; mocha *.test.mjs ; cp ../extension-dist/manifest-chrome.json ../extension-dist/manifest.json", 6 | "test:inspect": "cp ../extension-dist/manifest-puppeteer.json ../extension-dist/manifest.json ; node --inspect-brk ./node_modules/.bin/mocha *.test.mjs ; cp ../extension-dist/manifest-chrome.json ../extension-dist/manifest.json" 7 | }, 8 | "devDependencies": { 9 | "expect": "^27.5.1", 10 | "expect-mocha-image-snapshot": "^3.0.8", 11 | "mocha": "^10.2.0", 12 | "puppeteer": "^19.8.0" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /tests/screenshots/.gitignore: -------------------------------------------------------------------------------- 1 | /diffs/__diff_output__/ 2 | /diffs/__diff_output__*/ 3 | -------------------------------------------------------------------------------- /tests/screenshots/about-to-search-for-arrow-icon-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/live-css-editor/f2d3df6709ec8bd6662bbb58a6bc89a4c4377975/tests/screenshots/about-to-search-for-arrow-icon-snap.png -------------------------------------------------------------------------------- /tests/screenshots/all/.gitignore: -------------------------------------------------------------------------------- 1 | *.* 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /tests/screenshots/command-palette-search-icon-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/live-css-editor/f2d3df6709ec8bd6662bbb58a6bc89a4c4377975/tests/screenshots/command-palette-search-icon-snap.png -------------------------------------------------------------------------------- /tests/screenshots/command-palette-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/live-css-editor/f2d3df6709ec8bd6662bbb58a6bc89a4c4377975/tests/screenshots/command-palette-snap.png -------------------------------------------------------------------------------- /tests/screenshots/focused-input-search-icons-ui-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/live-css-editor/f2d3df6709ec8bd6662bbb58a6bc89a4c4377975/tests/screenshots/focused-input-search-icons-ui-snap.png -------------------------------------------------------------------------------- /tests/screenshots/hundred-search-results-and-one-result-selected-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/live-css-editor/f2d3df6709ec8bd6662bbb58a6bc89a4c4377975/tests/screenshots/hundred-search-results-and-one-result-selected-snap.png -------------------------------------------------------------------------------- /tests/screenshots/joyride-for-search-icons-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/live-css-editor/f2d3df6709ec8bd6662bbb58a6bc89a4c4377975/tests/screenshots/joyride-for-search-icons-snap.png -------------------------------------------------------------------------------- /tests/screenshots/magic-css-loaded-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/live-css-editor/f2d3df6709ec8bd6662bbb58a6bc89a4c4377975/tests/screenshots/magic-css-loaded-snap.png -------------------------------------------------------------------------------- /tests/screenshots/opened-and-focused-search-icons-configuration-2-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/live-css-editor/f2d3df6709ec8bd6662bbb58a6bc89a4c4377975/tests/screenshots/opened-and-focused-search-icons-configuration-2-snap.png -------------------------------------------------------------------------------- /tests/screenshots/opened-and-focused-search-icons-configuration-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/live-css-editor/f2d3df6709ec8bd6662bbb58a6bc89a4c4377975/tests/screenshots/opened-and-focused-search-icons-configuration-snap.png -------------------------------------------------------------------------------- /tests/screenshots/opened-search-icons-configuration-2-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/live-css-editor/f2d3df6709ec8bd6662bbb58a6bc89a4c4377975/tests/screenshots/opened-search-icons-configuration-2-snap.png -------------------------------------------------------------------------------- /tests/screenshots/opened-search-icons-configuration-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/live-css-editor/f2d3df6709ec8bd6662bbb58a6bc89a4c4377975/tests/screenshots/opened-search-icons-configuration-snap.png -------------------------------------------------------------------------------- /tests/screenshots/page-1-search-results-for-arrow-icon-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/live-css-editor/f2d3df6709ec8bd6662bbb58a6bc89a4c4377975/tests/screenshots/page-1-search-results-for-arrow-icon-snap.png -------------------------------------------------------------------------------- /tests/screenshots/search-for-arrow-icon-with-erroneous-configuration-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/live-css-editor/f2d3df6709ec8bd6662bbb58a6bc89a4c4377975/tests/screenshots/search-for-arrow-icon-with-erroneous-configuration-snap.png -------------------------------------------------------------------------------- /tests/screenshots/search-icons-ui-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/live-css-editor/f2d3df6709ec8bd6662bbb58a6bc89a4c4377975/tests/screenshots/search-icons-ui-snap.png -------------------------------------------------------------------------------- /tests/secrets/.gitignore: -------------------------------------------------------------------------------- 1 | *.* 2 | !.gitignore 3 | !sample-secrets.js 4 | -------------------------------------------------------------------------------- /tests/secrets/sample-secrets.js: -------------------------------------------------------------------------------- 1 | /* Copy the format of this file (./sample-secrets.js) with appropriate changes in secret values and save that at ./secrets.js */ 2 | 3 | const secrets = { 4 | nounProjectApiIncorrectAccessKeyAndSecret: { 5 | accessKey: '12345678901234567890123456789012', 6 | secret: '12345678901234567890123456789012' 7 | }, 8 | nounProjectApiCorrectAccessKeyIncorrectSecret: { 9 | accessKey: '', 10 | secret: '12345678901234567890123456789012' 11 | }, 12 | nounProjectApi: { 13 | accessKey: '', 14 | secret: '' 15 | } 16 | }; 17 | 18 | module.exports = secrets; 19 | -------------------------------------------------------------------------------- /utils/notifications/icons/error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/live-css-editor/f2d3df6709ec8bd6662bbb58a6bc89a4c4377975/utils/notifications/icons/error.png -------------------------------------------------------------------------------- /utils/notifications/icons/info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/live-css-editor/f2d3df6709ec8bd6662bbb58a6bc89a4c4377975/utils/notifications/icons/info.png -------------------------------------------------------------------------------- /utils/notifications/icons/sources.txt: -------------------------------------------------------------------------------- 1 | error.png 2 | https://www.iconfinder.com/icons/282471/cross_delete_remove_icon 3 | https://www.iconfinder.com/icons/282471/download/png/256 4 | 5 | info.png 6 | https://www.iconfinder.com/icons/1398911/check_correct_mark_success_tick_valid_yes_icon 7 | https://www.iconfinder.com/icons/1398911/download/png/256 8 | 9 | warning.png 10 | https://www.iconfinder.com/icons/183416/download/png/256 11 | https://www.iconfinder.com/icons/183416/warning_icon 12 | -------------------------------------------------------------------------------- /utils/notifications/icons/warning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webextensions/live-css-editor/f2d3df6709ec8bd6662bbb58a6bc89a4c4377975/utils/notifications/icons/warning.png -------------------------------------------------------------------------------- /utils/notifications/notifications.js: -------------------------------------------------------------------------------- 1 | const path = require('node:path'); 2 | 3 | let notifier; 4 | try { 5 | notifier = require('node-notifier'); 6 | } catch (e) { 7 | console.log( 8 | 'Could not load module "node-notifier".' + 9 | '\nWe need to run "$ npm install node-notifier" to be able to see desktop notifications.' + 10 | '\n' 11 | ); 12 | } 13 | 14 | let muteNotifications = false; 15 | 16 | const notify = function (options) { 17 | if (!muteNotifications) { 18 | if (notifier) { 19 | notifier.notify(options); 20 | } 21 | } 22 | }; 23 | 24 | module.exports = { 25 | info: function (title, message) { 26 | notify({ 27 | title, 28 | message, 29 | icon: path.join(__dirname, 'icons', 'info.png') 30 | }); 31 | }, 32 | warn: function (title, message) { 33 | notify({ 34 | title, 35 | message, 36 | icon: path.join(__dirname, 'icons', 'warn.png') 37 | }); 38 | }, 39 | error: function (title, message) { 40 | notify({ 41 | title, 42 | message, 43 | icon: path.join(__dirname, 'icons', 'error.png') 44 | }); 45 | }, 46 | mute: function (flag) { 47 | muteNotifications = flag; 48 | } 49 | }; 50 | --------------------------------------------------------------------------------