@wix/origami-transforms 0.1.40 → 0.1.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cssPlugins/svg.d.ts +1 -0
- package/dist/cssPlugins/{wixVectorUrls.d.ts → wixUrls.d.ts} +1 -1
- package/package.json +3 -2
- package/src/cssPlugins/index.js +4 -4
- package/src/cssPlugins/shapeDividers.js +1 -1
- package/src/cssPlugins/svg.js +11 -0
- package/src/cssPlugins/wixUrls.js +90 -0
- package/src/cssPlugins/wixVectorUrls.js +0 -43
package/dist/cssPlugins/svg.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** @typedef {typeof checks[number]} Check */
|
|
2
2
|
/** @type {import('../transform/types.js').CssTransformPlugin<Check>} */
|
|
3
|
-
export const
|
|
3
|
+
export const wixUrlsPlugin: import("../transform/types.js").CssTransformPlugin<Check>;
|
|
4
4
|
export type Check = (typeof checks)[number];
|
|
5
5
|
declare const checks: readonly [];
|
|
6
6
|
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wix/origami-transforms",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.41",
|
|
4
4
|
"description": "Babel and PostCSS checks and transforms for Wix origami page files.",
|
|
5
5
|
"main": "./src/index.js",
|
|
6
6
|
"files": [
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
"@babel/core": "^7.26.0",
|
|
20
20
|
"@babel/parser": "^7.25.0",
|
|
21
21
|
"@babel/types": "^7.25.2",
|
|
22
|
+
"@wix/sdk": "^1.21.13",
|
|
22
23
|
"@wix/origami-fonts": "1.0.4",
|
|
23
24
|
"@wix/origami-system-components": "1.10.10",
|
|
24
25
|
"postcss": "^8.5.3",
|
|
@@ -75,5 +76,5 @@
|
|
|
75
76
|
},
|
|
76
77
|
"type": "module",
|
|
77
78
|
"types": "./dist/index.d.ts",
|
|
78
|
-
"falconPackageHash": "
|
|
79
|
+
"falconPackageHash": "573fa6b0fb741a4bb27078f673fa0895c486a65ee23b26a1cf1127e8"
|
|
79
80
|
}
|
package/src/cssPlugins/index.js
CHANGED
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
// and layout move declarations out of the instance's rule. fonts appends the `@font-face` rules that load the Wix fonts
|
|
13
13
|
// the stylesheet names from Wix's CDN.
|
|
14
14
|
// component-position runs after mixins, so a position a mixin body sets is kept, and before layout compiles the rules.
|
|
15
|
-
// shape-dividers and wix-
|
|
16
|
-
//
|
|
15
|
+
// shape-dividers and wix-urls run last: they load the SVGs a stylesheet names from Wix's CDN in `prepare`, and write
|
|
16
|
+
// them in as data URIs; wix-urls links a regular image a `wix:image` url names from Wix's media service, resized.
|
|
17
17
|
//
|
|
18
18
|
// `@layer` needs no plugin: cascade layers have been in every browser since March 2022.
|
|
19
19
|
|
|
@@ -28,7 +28,7 @@ import { layoutPlugin } from './layout/index.js'
|
|
|
28
28
|
import { spxPlugin } from './spx/index.js'
|
|
29
29
|
import { spxThemeVariablesPlugin } from './spxThemeVariables/index.js'
|
|
30
30
|
import { stackChildrenPlugin } from './stackChildren.js'
|
|
31
|
-
import {
|
|
31
|
+
import { wixUrlsPlugin } from './wixUrls.js'
|
|
32
32
|
|
|
33
33
|
/** @type {readonly import('../transform/types.js').CssTransformPlugin<string>[]} */
|
|
34
34
|
export const cssPlugins = Object.freeze([
|
|
@@ -43,5 +43,5 @@ export const cssPlugins = Object.freeze([
|
|
|
43
43
|
spxThemeVariablesPlugin,
|
|
44
44
|
spxPlugin,
|
|
45
45
|
shapeDividersPlugin,
|
|
46
|
-
|
|
46
|
+
wixUrlsPlugin,
|
|
47
47
|
])
|
|
@@ -108,7 +108,7 @@ const checks = /** @type {const} */ ([])
|
|
|
108
108
|
export const shapeDividersPlugin = {
|
|
109
109
|
checks,
|
|
110
110
|
name: 'shape-dividers',
|
|
111
|
-
// Last, with wix-
|
|
111
|
+
// Last, with wix-urls: it only adds rules, which no other plugin needs to see, and it reads only `--height` as
|
|
112
112
|
// `var(--height)`, so spx converts that var's `--spx()` where it is declared.
|
|
113
113
|
order: 25,
|
|
114
114
|
prepare(root) {
|
package/src/cssPlugins/svg.js
CHANGED
|
@@ -88,3 +88,14 @@ export const svgDataUrl = svg => {
|
|
|
88
88
|
.replace(URL_SYMBOLS, encodeURIComponent)
|
|
89
89
|
return `url("data:image/svg+xml,${escaped}")`
|
|
90
90
|
}
|
|
91
|
+
|
|
92
|
+
const SIZE = /\s(?:width|height)="[^"]*"/g
|
|
93
|
+
|
|
94
|
+
/** The SVG drawn at `width` × `height` pixels, its drawing box stretched to that size: what a cursor image, which a
|
|
95
|
+
* browser draws at the image's own size, needs. */
|
|
96
|
+
export const sizeSvg = (svg, width, height) => {
|
|
97
|
+
const scaled = scaleSvg(svg, svgInfo(svg), 'none')
|
|
98
|
+
const tag = scaled.match(SVG_TAG)?.[0]
|
|
99
|
+
if (tag === undefined) return scaled
|
|
100
|
+
return scaled.replace(tag, tag.replace(SIZE, '').replace(/<svg/, `<svg width="${width}" height="${height}"`))
|
|
101
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
// Rewrites the urls a value names with Wix's own url schemes, which no browser can load:
|
|
2
|
+
//
|
|
3
|
+
// - `url(wix:vector://v1/<id>.svg)`: vector art, Image's `--maskImage` for one. A live Wix site writes it as a data
|
|
4
|
+
// URI of the SVG stretched to its drawing's box (Thunderbolt's `replaceWixUrl` and `createSvgCssVar`); this writes
|
|
5
|
+
// the same data URI in its place.
|
|
6
|
+
// - `url("wix:image://v1/<id>/<name>#originWidth=<w>&originHeight=<h>")`: an image at the size it's displayed at, a
|
|
7
|
+
// component's `cursor` for one (css-codec/style/cursor.ts). A browser draws a cursor at the image's pixel size, so
|
|
8
|
+
// the image is requested at that size: a regular image resized by Wix's media service, through @wix/sdk's media
|
|
9
|
+
// helpers, an SVG shape inlined as a data URI with that width and height (the media service doesn't resize an SVG).
|
|
10
|
+
//
|
|
11
|
+
// Only the url is rewritten: a cursor's hotspot and `auto` fallback stay as written. So does a url that can't be
|
|
12
|
+
// rewritten, with a warning. And only the CSS this stage renders is rewritten, never the stored bundle: an https
|
|
13
|
+
// cursor in style.css would be read back as plain CSS, not as the component's cursor.
|
|
14
|
+
|
|
15
|
+
import { getImageUrl, getScaledToFillImageUrl } from '@wix/sdk/media'
|
|
16
|
+
import { loadedSvg, loadSvgs, scaleSvg, sizeSvg, svgDataUrl, svgInfo } from './svg.js'
|
|
17
|
+
|
|
18
|
+
// A quoted url runs to its closing quote: a file name encoded with encodeURIComponent keeps `(`, `)` and `'`.
|
|
19
|
+
const WIX_URL = /url\(\s*(['"]?)(wix:(vector|image):\/\/v1\/(.+?))\1\s*\)/gi
|
|
20
|
+
const HAS_WIX_URL = /wix:(?:vector|image):\/\//i
|
|
21
|
+
|
|
22
|
+
const isSvg = id => id.endsWith('.svg')
|
|
23
|
+
|
|
24
|
+
/** Every wix url in the stylesheet: its scheme, its path after `v1/`, and the url itself. */
|
|
25
|
+
const wixUrls = root => {
|
|
26
|
+
const urls = []
|
|
27
|
+
root.walkDecls(declaration => {
|
|
28
|
+
for (const [, , wixUrl, scheme, path] of declaration.value.matchAll(WIX_URL)) urls.push({ scheme: scheme.toLowerCase(), path, wixUrl })
|
|
29
|
+
})
|
|
30
|
+
return urls
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** The ids of the SVGs the stylesheet's wix urls name. */
|
|
34
|
+
const svgIdsIn = root => {
|
|
35
|
+
const ids = new Set()
|
|
36
|
+
for (const { scheme, path, wixUrl } of wixUrls(root)) {
|
|
37
|
+
if (scheme === 'vector') ids.add(path)
|
|
38
|
+
else {
|
|
39
|
+
const { id, width, height } = getImageUrl(wixUrl)
|
|
40
|
+
if (isSvg(id) && width && height) ids.add(id)
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return ids
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** The `wix:vector` url `id` as a data URI, or `url` as written when its SVG isn't loaded. */
|
|
47
|
+
const vectorUrl = (url, id, declaration, context) => {
|
|
48
|
+
const svg = loadedSvg(id)
|
|
49
|
+
if (svg === undefined) {
|
|
50
|
+
context.warn?.(declaration, `Couldn't load the SVG ${id} from Wix's CDN, so ${url} stays as written`, 'svg_not_loaded')
|
|
51
|
+
return url
|
|
52
|
+
}
|
|
53
|
+
return svgDataUrl(scaleSvg(svg, svgInfo(svg), 'none'))
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** The `wix:image` url `wixUrl` as a loadable url at its size, or `url` as written when it can't be. */
|
|
57
|
+
const imageUrl = (url, wixUrl, declaration, context) => {
|
|
58
|
+
const { id, width, height } = getImageUrl(wixUrl)
|
|
59
|
+
if (!width || !height) {
|
|
60
|
+
context.warn?.(declaration, `The image ${id} has no size: ${url} doesn't end in #originWidth=<w>&originHeight=<h>, so it stays as written`)
|
|
61
|
+
return url
|
|
62
|
+
}
|
|
63
|
+
if (!isSvg(id)) return `url("${getScaledToFillImageUrl(wixUrl, width, height, {})}")`
|
|
64
|
+
const svg = loadedSvg(id)
|
|
65
|
+
if (svg === undefined) {
|
|
66
|
+
context.warn?.(declaration, `Couldn't load the SVG ${id} from Wix's CDN, so ${url} stays as written`, 'svg_not_loaded')
|
|
67
|
+
return url
|
|
68
|
+
}
|
|
69
|
+
return svgDataUrl(sizeSvg(svg, width, height))
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const checks = /** @type {const} */ ([])
|
|
73
|
+
/** @typedef {typeof checks[number]} Check */
|
|
74
|
+
|
|
75
|
+
/** @type {import('../transform/types.js').CssTransformPlugin<Check>} */
|
|
76
|
+
export const wixUrlsPlugin = {
|
|
77
|
+
checks,
|
|
78
|
+
name: 'wix-urls',
|
|
79
|
+
// Last, so a url a mixin or preset copies elsewhere is rewritten wherever it ends up.
|
|
80
|
+
order: 25,
|
|
81
|
+
prepare: root => loadSvgs(svgIdsIn(root)),
|
|
82
|
+
transform(root, context) {
|
|
83
|
+
root.walkDecls(declaration => {
|
|
84
|
+
if (!HAS_WIX_URL.test(declaration.value)) return
|
|
85
|
+
declaration.value = declaration.value.replace(WIX_URL, (url, _quote, wixUrl, scheme, path) =>
|
|
86
|
+
scheme.toLowerCase() === 'vector' ? vectorUrl(url, path, declaration, context) : imageUrl(url, wixUrl, declaration, context)
|
|
87
|
+
)
|
|
88
|
+
})
|
|
89
|
+
},
|
|
90
|
+
}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
// Inlines the vector art a value names with Wix's own url scheme, `url(wix:vector://v1/<id>.svg)`, which no browser
|
|
2
|
-
// can load: Image's `--maskImage`, for one. A live Wix site writes it as a data URI of the SVG stretched to its
|
|
3
|
-
// drawing's box (Thunderbolt's `replaceWixUrl` and `createSvgCssVar`); this writes the same data URI in its place.
|
|
4
|
-
// An SVG that can't be loaded stays as written, with a warning.
|
|
5
|
-
|
|
6
|
-
import { loadedSvg, loadSvgs, scaleSvg, svgDataUrl, svgInfo } from './svg.js'
|
|
7
|
-
|
|
8
|
-
const WIX_VECTOR_URL = /url\(\s*(['"]?)wix:vector:\/\/v1\/([^'")\s]+)\1\s*\)/gi
|
|
9
|
-
const HAS_WIX_VECTOR_URL = /wix:vector:\/\//i
|
|
10
|
-
|
|
11
|
-
/** The ids every `wix:vector` url in the stylesheet names. */
|
|
12
|
-
const idsIn = root => {
|
|
13
|
-
const ids = new Set()
|
|
14
|
-
root.walkDecls(declaration => {
|
|
15
|
-
for (const [, , id] of declaration.value.matchAll(WIX_VECTOR_URL)) ids.add(id)
|
|
16
|
-
})
|
|
17
|
-
return ids
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const checks = /** @type {const} */ ([])
|
|
21
|
-
/** @typedef {typeof checks[number]} Check */
|
|
22
|
-
|
|
23
|
-
/** @type {import('../transform/types.js').CssTransformPlugin<Check>} */
|
|
24
|
-
export const wixVectorUrlsPlugin = {
|
|
25
|
-
checks,
|
|
26
|
-
name: 'wix-vector-urls',
|
|
27
|
-
// Last, so a url a mixin or preset copies elsewhere is inlined wherever it ends up.
|
|
28
|
-
order: 25,
|
|
29
|
-
prepare: root => loadSvgs(idsIn(root)),
|
|
30
|
-
transform(root, context) {
|
|
31
|
-
root.walkDecls(declaration => {
|
|
32
|
-
if (!HAS_WIX_VECTOR_URL.test(declaration.value)) return
|
|
33
|
-
declaration.value = declaration.value.replace(WIX_VECTOR_URL, (url, _quote, id) => {
|
|
34
|
-
const svg = loadedSvg(id)
|
|
35
|
-
if (svg === undefined) {
|
|
36
|
-
context.warn?.(declaration, `Couldn't load the SVG ${id} from Wix's CDN, so ${url} stays as written`, 'svg_not_loaded')
|
|
37
|
-
return url
|
|
38
|
-
}
|
|
39
|
-
return svgDataUrl(scaleSvg(svg, svgInfo(svg), 'none'))
|
|
40
|
-
})
|
|
41
|
-
})
|
|
42
|
-
},
|
|
43
|
-
}
|