diff --git a/cli/plasmo/src/type.ts b/cli/plasmo/src/type.ts index db7f8b0a7..dafa40d66 100644 --- a/cli/plasmo/src/type.ts +++ b/cli/plasmo/src/type.ts @@ -68,7 +68,12 @@ export type PlasmoMountShadowHost = ( export type PlasmoGetShadowHostId = Getter -export type PlasmoGetStyle = Getter +export type PlasmoGetStyle = Getter< + HTMLStyleElement, + PlasmoCSUIAnchor & { sfcStyleContent?: string } +> + +export type PlasmoGetSfcStyleContent = Getter /** * @return a cleanup unwatch function that will be run when unmounted @@ -113,6 +118,7 @@ export type PlasmoCSUIWatch = (props: { export type PlasmoCSUI = { default: any getStyle: PlasmoGetStyle + getSfcStyleContent: PlasmoGetSfcStyleContent getShadowHostId: PlasmoGetShadowHostId getOverlayAnchor: PlasmoGetOverlayAnchor diff --git a/cli/plasmo/templates/static/common/csui.ts b/cli/plasmo/templates/static/common/csui.ts index 7b4c051a9..a910b9cce 100644 --- a/cli/plasmo/templates/static/common/csui.ts +++ b/cli/plasmo/templates/static/common/csui.ts @@ -32,7 +32,11 @@ async function injectAnchor( mountState?: PlasmoCSUIMountState ) { if (typeof Mount.getStyle === "function") { - shadowRoot.prepend(await Mount.getStyle(anchor)) + const sfcStyleContent = + typeof Mount.getSfcStyleContent === "function" + ? await Mount.getSfcStyleContent() + : "" + shadowRoot.prepend(await Mount.getStyle({ ...anchor, sfcStyleContent })) } if (typeof Mount.getShadowHostId === "function") { diff --git a/cli/plasmo/templates/static/vue3/content-script-ui-mount.ts b/cli/plasmo/templates/static/vue3/content-script-ui-mount.ts index aeba6ecc1..e4d5afde1 100644 --- a/cli/plasmo/templates/static/vue3/content-script-ui-mount.ts +++ b/cli/plasmo/templates/static/vue3/content-script-ui-mount.ts @@ -10,6 +10,10 @@ import { createApp } from "vue" // @ts-ignore import RawMount from "__plasmo_mount_content_script__" +// prettier-sort-ignore +// @ts-ignore +import SfcStyleContent from "style-raw:__plasmo_mount_content_script__" + import type { PlasmoCSUI, PlasmoCSUIAnchor, @@ -17,7 +21,19 @@ import type { } from "~type" // Escape parcel's static analyzer -const Mount = RawMount.plasmo as PlasmoCSUI +const Mount = (RawMount.plasmo || {}) as PlasmoCSUI + +if (typeof SfcStyleContent === "string") { + Mount.getSfcStyleContent = () => SfcStyleContent + + if (typeof Mount.getStyle !== "function") { + Mount.getStyle = ({ sfcStyleContent }) => { + const element = document.createElement("style") + element.textContent = sfcStyleContent + return element + } + } +} const observer = createAnchorObserver(Mount) diff --git a/core/parcel-config/index.json b/core/parcel-config/index.json index a7c274a44..afc2b6d68 100644 --- a/core/parcel-config/index.json +++ b/core/parcel-config/index.json @@ -42,6 +42,7 @@ "template:*.vue": ["@plasmohq/parcel-transformer-vue"], "script:*.vue": ["@plasmohq/parcel-transformer-vue"], "style:*.vue": ["@plasmohq/parcel-transformer-vue"], + "style-raw:*.vue": ["@plasmohq/parcel-transformer-vue"], "custom:*.vue": ["@plasmohq/parcel-transformer-vue"], "*.svelte": ["@plasmohq/parcel-transformer-svelte"], diff --git a/core/parcel-transformer-vue/src/index.ts b/core/parcel-transformer-vue/src/index.ts index c30732b0d..e71b985d1 100644 --- a/core/parcel-transformer-vue/src/index.ts +++ b/core/parcel-transformer-vue/src/index.ts @@ -338,7 +338,8 @@ async function processPipeline({ return [scriptAsset] } - case "style": { + case "style": + case "style-raw": { let cssModules = {} let assets = await Promise.all( styles.map(async (style, i) => { @@ -408,11 +409,12 @@ async function processPipeline({ return styleAsset }) ) - if (Object.keys(cssModules).length !== 0) { - assets.push({ - type: "js", - uniqueKey: asset.id + "-cssModules", - content: ` + if (asset.pipeline == "style") { + if (Object.keys(cssModules).length !== 0) { + assets.push({ + type: "js", + uniqueKey: asset.id + "-cssModules", + content: ` import {render} from 'template:./${basePath}'; let cssModules = ${JSON.stringify(cssModules)}; ${ @@ -425,9 +427,22 @@ async function processPipeline({ : "" } export default cssModules;` - }) + }) + } + return assets + } else if (asset.pipeline == "style-raw") { + const styleRawString = assets.map((a) => a.content).join("\n") + return [ + { + type: "js", + uniqueKey: asset.id + "-cssRawString", + content: ` +const styleRawString = \`${styleRawString}\` +export default styleRawString + ` + } + ] } - return assets } case "custom": { let toCall = []