diff --git a/.gitignore b/.gitignore index 0b03d95f2fc0..8a58530a4bcc 100644 --- a/.gitignore +++ b/.gitignore @@ -200,7 +200,7 @@ config/external/icu4x # Ignore Storybook generated files browser/components/storybook/node_modules/ browser/components/storybook/storybook-static/ -browser/components/storybook/.storybook/rewrites.js +browser/components/storybook/.storybook/chrome-map.js browser/components/storybook/custom-elements.json # Ignore jscodeshift installed by mach esmify on windows diff --git a/.hgignore b/.hgignore index 5f8f5c96720e..f3b1e406eb54 100644 --- a/.hgignore +++ b/.hgignore @@ -273,7 +273,7 @@ gfx/wr/target/ # Ignore Storybook generated files ^browser/components/storybook/node_modules/ ^browser/components/storybook/storybook-static/ -^browser/components/storybook/.storybook/rewrites.js +^browser/components/storybook/.storybook/chrome-map.js ^browser/components/storybook/custom-elements.json # Ignore jscodeshift installed by mach esmify on windows diff --git a/browser/components/storybook/.storybook/main.js b/browser/components/storybook/.storybook/main.js index 47802e23cbbf..64dbb2419222 100644 --- a/browser/components/storybook/.storybook/main.js +++ b/browser/components/storybook/.storybook/main.js @@ -4,10 +4,33 @@ /* eslint-env node */ const path = require("path"); +const webpack = require("webpack"); + +const [prefixMap, aliasMap, sourceMap] = require("./chrome-map.js"); + const projectRoot = path.resolve(__dirname, "../../../../"); -// ./mach environment --format json -// topobjdir should be the build location +function rewriteChromeUri(uri) { + if (uri in aliasMap) { + return rewriteChromeUri(aliasMap[uri]); + } + for (let [prefix, [bundlePath]] of Object.entries(prefixMap)) { + if (uri.startsWith(prefix)) { + if (!bundlePath.endsWith("/")) { + bundlePath += "/"; + } + let relativePath = uri.slice(prefix.length); + let objdirPath = bundlePath + relativePath; + for (let [_objdirPath, [filePath]] of Object.entries(sourceMap)) { + if (_objdirPath == objdirPath) { + // We're just hoping this is the actual path =\ + return filePath; + } + } + } + } + return ""; +} module.exports = { stories: [ @@ -62,16 +85,18 @@ module.exports = { config.resolve.alias["lit-html/directive-helpers.js"] = "lit.all.mjs"; config.resolve.alias["lit-html"] = "lit.all.mjs"; + config.plugins.push( + // Rewrite chrome:// URI imports to file system paths. + new webpack.NormalModuleReplacementPlugin(/^chrome:\/\//, resource => { + resource.request = rewriteChromeUri(resource.request); + }) + ); + config.module.rules.push({ test: /\.ftl$/, type: "asset/source", }); - config.module.rules.push({ - test: /\.mjs/, - loader: path.resolve(__dirname, "./chrome-uri-loader.js"), - }); - // We're adding a rule for files matching this pattern in order to support // writing docs only stories in plain markdown. const MD_STORY_REGEX = /(stories|story)\.md$/; diff --git a/browser/components/storybook/mach_commands.py b/browser/components/storybook/mach_commands.py index 4963b5d1753b..b81794719e0d 100644 --- a/browser/components/storybook/mach_commands.py +++ b/browser/components/storybook/mach_commands.py @@ -2,12 +2,8 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -import json -import os - import mozpack.path as mozpath from mach.decorators import Command, SubCommand -from mozpack.manifests import InstallManifest @Command( @@ -43,84 +39,16 @@ def storybook_launch(command_context): def build_storybook_manifest(command_context): + print("Build ChromeMap backend") + run_mach(command_context, "build-backend", backend=["ChromeMap"]) config_environment = command_context.config_environment - # The InstallManifest object will have mappings of JAR entries to paths on disk. - unified_manifest = InstallManifest( - mozpath.join(config_environment.topobjdir, "faster", "unified_install_dist_bin") - ) - paths = {} - - for dest, entry in unified_manifest._dests.items(): - # dest in the JAR path - # entry can be many things, but we care about the [1, file_path] form - # 1 essentially means this is a file - if ( - entry[0] == 1 - and (dest.endswith(".js") or dest.endswith(".mjs")) - and ( - dest.startswith("chrome/toolkit/") or dest.startswith("browser/chrome/") - ) - ): - try: - # Try to map the dest to a chrome URI. This could fail for some weird cases that - # don't seem like they're worth handling. - chrome_uri = _parse_dest_to_chrome_uri(dest) - # Since we run through mach we're relative to the project root here. - paths[chrome_uri] = os.path.relpath(entry[1]) - except Exception as e: - # Log the files that failed, this could get noisy but the list is short for now. - print('Error rewriting to chrome:// URI "{}" [{}]'.format(dest, e)) - pass - - with open("browser/components/storybook/.storybook/rewrites.js", "w") as f: - f.write("module.exports = ") - json.dump(paths, f, indent=2) - - -def _parse_dest_to_chrome_uri(dest): - """Turn a jar destination into a chrome:// URI. Will raise an error on unknown input.""" - - global_start = dest.find("global/") - content_start = dest.find("content/") - skin_classic_browser = "skin/classic/browser/" - browser_skin_start = dest.find(skin_classic_browser) - package, provider, path = "", "", "" - - if global_start != -1: - # e.g. chrome/toolkit/content/global/vendor/lit.all.mjs - # chrome://global/content/vendor/lit.all.mjs - # If the jar location has global in it, then: - # * the package is global, - # * the portion after global should be the path, - # * the provider is in the path somewhere (we want skin or content). - package = "global" - provider = "skin" if "/skin/" in dest else "content" - path = dest[global_start + len("global/") :] - elif content_start != -1: - # e.g. browser/chrome/browser/content/browser/aboutDialog.js - # chrome://browser/content/aboutDialog.js - # e.g. chrome/toolkit/content/mozapps/extensions/shortcuts.js - # chrome://mozapps/content/extensions/shortcuts.js - # If the jar location has content/ in it, then: - # * starting from "content/" split on slashes and, - # * the provider is "content", - # * the package is the next part, - # * the path is the remainder. - provider, package, path = dest[content_start:].split("/", 2) - elif browser_skin_start != -1: - # e.g. browser/chrome/browser/skin/classic/browser/browser.css - # chrome://browser/skin/browser.css - # If the jar location has skin/classic/browser/ in it, then: - # * the package is browser, - # * the provider is skin, - # * the path is what remains after sking/classic/browser. - package = "browser" - provider = "skin" - path = dest[browser_skin_start + len(skin_classic_browser) :] - - return "chrome://{package}/{provider}/{path}".format( - package=package, provider=provider, path=path - ) + storybook_chrome_map_path = "browser/components/storybook/.storybook/chrome-map.js" + chrome_map_path = mozpath.join(config_environment.topobjdir, "chrome-map.json") + with open(chrome_map_path, "r") as chrome_map_f: + with open(storybook_chrome_map_path, "w") as storybook_chrome_map_f: + storybook_chrome_map_f.write("module.exports = ") + storybook_chrome_map_f.write(chrome_map_f.read()) + storybook_chrome_map_f.write(";") def run_mach(command_context, cmd, **kwargs):