@wix/origami-transforms 0.1.3 → 0.1.5
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wix/origami-transforms",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"description": "Babel and PostCSS checks and transforms for Wix origami page files.",
|
|
5
5
|
"main": "./src/index.js",
|
|
6
6
|
"files": [
|
|
@@ -54,5 +54,5 @@
|
|
|
54
54
|
},
|
|
55
55
|
"type": "module",
|
|
56
56
|
"types": "./dist/index.d.ts",
|
|
57
|
-
"falconPackageHash": "
|
|
57
|
+
"falconPackageHash": "ca2361f449d0870ec5720dae8f71767a7dadabb976f2ed36c1481607"
|
|
58
58
|
}
|
package/src/cssPlugins/fonts.js
CHANGED
|
@@ -1,28 +1,18 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
// The loading: a family is only a name until a `@font-face` rule says where its files are. For every Wix font a
|
|
10
|
-
// font token, `font` or `font-family` declaration names, the `@font-face` rules a live Wix site writes for it are
|
|
11
|
-
// appended to the stylesheet. They point at Wix's CDN, so no font file is downloaded into the site or its build;
|
|
12
|
-
// the browser fetches only the files of the fonts, weights and scripts a page uses. A family with no font faces,
|
|
13
|
-
// like a system font, adds nothing. The rules exist only in the served CSS, never in the site's own files.
|
|
1
|
+
// Loads the fonts the stylesheet names. A family is only a name until a `@font-face` rule says where its files are.
|
|
2
|
+
// For every Wix font a font token (`--wst-heading-1-font: normal normal 700 --spx(88)/1em benzin`), `font` or
|
|
3
|
+
// `font-family` declaration names, the `@font-face` rules a live Wix site writes for it are appended to the
|
|
4
|
+
// stylesheet. They point at Wix's CDN, so no font file is downloaded into the site or its build; the browser fetches
|
|
5
|
+
// only the files of the fonts, weights and scripts a page uses. A family with no font faces, like a system font, adds
|
|
6
|
+
// nothing. The rules exist only in the served CSS, never in the site's own files. Whether a token names exactly one
|
|
7
|
+
// Wix font id is checked by the lint (@wix/origami-lint's theme-font-ids rule), not here.
|
|
14
8
|
|
|
15
|
-
import {
|
|
16
|
-
import { fontFaceCss, fontFaces, fonts } from '@wix/origami-fonts'
|
|
9
|
+
import { fontFaceCss, fontFaces } from '@wix/origami-fonts'
|
|
17
10
|
import postcss from 'postcss'
|
|
18
|
-
import { LayoutError } from '../transform/layoutError.js'
|
|
19
11
|
|
|
20
|
-
const FONT_TOKEN = /^--wst-[\w-]+-font$/
|
|
21
12
|
const FONT_DECLARATION = /^(?:--wst-[\w-]+-font|font|font-family)$/
|
|
22
13
|
// The size in a `font` shorthand, with its optional line height: the family follows it. The number's quantifiers
|
|
23
14
|
// never overlap, so a long run of digits that is not a size fails in linear time.
|
|
24
15
|
const SIZE = /^(?:--spx\(.*\)|calc\(.*\)|(?:\d+(?:\.\d*)?|\.\d+)(?:px|em|rem|%|vw|vh|pt)?)(?:\/\S+)?$/i
|
|
25
|
-
const FONT_IDS = new Set(fonts.filter(font => font.permissions !== 'legacy').map(font => font.id))
|
|
26
16
|
|
|
27
17
|
/** A value split on top-level whitespace, so `--spx(16)/1.3em` stays one token. */
|
|
28
18
|
const tokens = value => {
|
|
@@ -59,54 +49,11 @@ const fontIdsOf = declaration => {
|
|
|
59
49
|
return family.split(',').map(name => name.trim().replace(/^(['"])(.*)\1$/, '$2').toLowerCase())
|
|
60
50
|
}
|
|
61
51
|
|
|
62
|
-
/** ` (theme.css:12)`: the carrier the declaration was written in, which the bundler doesn't name. */
|
|
63
|
-
const where = declaration => {
|
|
64
|
-
const file = declaration.source?.input.file
|
|
65
|
-
const line = declaration.source?.start?.line
|
|
66
|
-
return file ? ` (${basename(file)}${line ? `:${line}` : ''})` : ''
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* Where `source` starts, as LayoutError's location, leaving out what it doesn't know.
|
|
71
|
-
* @param {import('postcss').Declaration['source']} source
|
|
72
|
-
*/
|
|
73
|
-
const locationOf = source => {
|
|
74
|
-
/** @type {{ file?: string, line?: number, column?: number }} */
|
|
75
|
-
const location = {}
|
|
76
|
-
if (source?.input.file !== undefined) location.file = source.input.file
|
|
77
|
-
if (source?.start !== undefined) {
|
|
78
|
-
location.line = source.start.line
|
|
79
|
-
location.column = source.start.column
|
|
80
|
-
}
|
|
81
|
-
return location
|
|
82
|
-
}
|
|
83
|
-
|
|
84
52
|
/** @type {import('../transform/types.js').CssTransformPlugin} */
|
|
85
53
|
export const fontsPlugin = {
|
|
86
54
|
name: 'fonts',
|
|
87
55
|
// Reads the declarations as authored, before spx rewrites the sizes the family follows.
|
|
88
56
|
order: 5,
|
|
89
|
-
validate(root) {
|
|
90
|
-
/** @type {import('postcss').Declaration[]} */
|
|
91
|
-
const declarations = []
|
|
92
|
-
root.walkDecls(FONT_TOKEN, declaration => {
|
|
93
|
-
declarations.push(declaration)
|
|
94
|
-
})
|
|
95
|
-
const violations = []
|
|
96
|
-
let first
|
|
97
|
-
for (const declaration of declarations) {
|
|
98
|
-
const family = familyOf(declaration.value)
|
|
99
|
-
if (family === undefined || FONT_IDS.has(family)) continue
|
|
100
|
-
first ??= declaration.source
|
|
101
|
-
violations.push(
|
|
102
|
-
`${declaration.prop}${where(declaration)} must name exactly one Wix font id from the catalog; found ` +
|
|
103
|
-
`${family}. Run \`origami search-font --font <name>\` for the id.`
|
|
104
|
-
)
|
|
105
|
-
}
|
|
106
|
-
if (violations.length) {
|
|
107
|
-
throw new LayoutError(violations, locationOf(first))
|
|
108
|
-
}
|
|
109
|
-
},
|
|
110
57
|
transform(root) {
|
|
111
58
|
const ids = new Set()
|
|
112
59
|
root.walkDecls(FONT_DECLARATION, declaration => {
|
package/src/cssPlugins/index.js
CHANGED
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
// layout routes declarations to wrappers and SPX converts calls using the browser's active settings. stack-children
|
|
9
9
|
// only checks, and runs between mixins and layout: it needs the mixins' declarations and the stack rules as authored,
|
|
10
10
|
// before layout compiles them away. presets runs after mixins too, so a `--preset` a mixin body carries is moved
|
|
11
|
-
// like an authored one. fonts
|
|
12
|
-
//
|
|
11
|
+
// like an authored one. fonts appends the `@font-face` rules that load the Wix fonts the stylesheet names from Wix's
|
|
12
|
+
// CDN.
|
|
13
13
|
//
|
|
14
14
|
// `@layer` needs no plugin: cascade layers have been in every browser since March 2022.
|
|
15
15
|
|
|
@@ -7,7 +7,7 @@ scrolling and clipping. The content wrapper arranges the children.
|
|
|
7
7
|
In site-owned `layout.css`, `@origami-target` says which wrapper a style belongs to:
|
|
8
8
|
|
|
9
9
|
```css
|
|
10
|
-
|
|
10
|
+
.container {
|
|
11
11
|
--container-layout-type: FlexContainerLayout;
|
|
12
12
|
|
|
13
13
|
@origami-target internal-container-content-wrapper {
|
|
@@ -68,7 +68,7 @@ check and collect the target nodes from the updated stylesheet.
|
|
|
68
68
|
- `compiler.js` builds wrapper selectors, adds base styles and moves declarations.
|
|
69
69
|
|
|
70
70
|
Targets must come from site-owned `layout.css` and belong to a single component ID
|
|
71
|
-
rule
|
|
71
|
+
rule, written as `.compId` or `#compId`. Unsupported targets or properties fail with an error rather than being ignored.
|
|
72
72
|
|
|
73
73
|
This plugin generates CSS; the runtime supplies the wrapper elements. SPX values
|
|
74
74
|
are converted afterward by the SPX plugin.
|
|
@@ -41,7 +41,7 @@ export const compileContainers = (root, context) => {
|
|
|
41
41
|
for (const owner of rules) {
|
|
42
42
|
const { contentClass, overflowClass } = buildContainerClasses(owner.selector.slice(1))
|
|
43
43
|
// In @scope, an unqualified selector cannot select the scoping root. DM emits
|
|
44
|
-
//
|
|
44
|
+
// the owner selector there too; :where(:scope) includes that root without adding specificity.
|
|
45
45
|
let selector = owner.selector
|
|
46
46
|
for (let ancestor = owner.parent; ancestor && ancestor.type !== 'root'; ancestor = ancestor.parent) {
|
|
47
47
|
if (ancestor.type === 'atrule' && ancestor.name === 'scope') {
|
|
@@ -22,7 +22,12 @@ export const parseTargets = (root, context) => {
|
|
|
22
22
|
const name = target.params.trim()
|
|
23
23
|
if (!Object.hasOwn(targets, name)) throw target.error(`Unknown @origami-target ${name}`)
|
|
24
24
|
const owner = target.parent
|
|
25
|
-
|
|
25
|
+
// DM writes component rules as .compId; #compId is still accepted.
|
|
26
|
+
if (
|
|
27
|
+
owner?.type !== 'rule' ||
|
|
28
|
+
!['.', '#'].includes(owner.selector[0]) ||
|
|
29
|
+
!isValidContainerId(owner.selector.slice(1))
|
|
30
|
+
) {
|
|
26
31
|
throw target.error('@origami-target requires a single component ID rule')
|
|
27
32
|
}
|
|
28
33
|
for (let ancestor = owner.parent; ancestor && ancestor.type !== 'root'; ancestor = ancestor.parent) {
|