@wordpress/global-styles-engine 1.15.2-next.v.202606191442.0 → 1.16.0
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/build/core/merge.cjs +22 -17
- package/build/core/merge.cjs.map +2 -2
- package/build/core/render.cjs +16 -8
- package/build/core/render.cjs.map +2 -2
- package/build/settings/get-style.cjs +17 -1
- package/build/settings/get-style.cjs.map +2 -2
- package/build/settings/set-style.cjs +2 -1
- package/build/settings/set-style.cjs.map +2 -2
- package/build/style-state-back-compat.cjs +94 -0
- package/build/style-state-back-compat.cjs.map +7 -0
- package/build-module/core/merge.mjs +22 -17
- package/build-module/core/merge.mjs.map +2 -2
- package/build-module/core/render.mjs +16 -8
- package/build-module/core/render.mjs.map +2 -2
- package/build-module/settings/get-style.mjs +17 -1
- package/build-module/settings/get-style.mjs.map +2 -2
- package/build-module/settings/set-style.mjs +2 -1
- package/build-module/settings/set-style.mjs.map +2 -2
- package/build-module/style-state-back-compat.mjs +68 -0
- package/build-module/style-state-back-compat.mjs.map +7 -0
- package/build-types/core/merge.d.ts.map +1 -1
- package/build-types/core/render.d.ts.map +1 -1
- package/build-types/settings/get-style.d.ts.map +1 -1
- package/build-types/settings/set-style.d.ts.map +1 -1
- package/build-types/style-state-back-compat.d.ts +28 -0
- package/build-types/style-state-back-compat.d.ts.map +1 -0
- package/package.json +6 -6
- package/src/core/merge.ts +25 -19
- package/src/core/render.tsx +18 -8
- package/src/settings/get-style.ts +23 -1
- package/src/settings/set-style.ts +2 -1
- package/src/style-state-back-compat.ts +137 -0
- package/src/test/render.test.ts +47 -8
- package/src/test/style-state-back-compat.test.ts +170 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/style-state-back-compat.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Internal dependencies\n */\nimport type { GlobalStylesConfig } from './types';\n\n/**\n * Temporary aliases for persisted style state keys shipped before breakpoint\n * states used the `@` prefix and custom states used the `-` prefix.\n *\n * Gutenberg plugin back compat for data saved before state keys were prefixed.\n * Guarded by `IS_GUTENBERG_PLUGIN` so synced Core package code does not apply it.\n */\nconst LEGACY_STYLE_STATE_ALIASES: Record< string, string > = {\n\t'@mobile': 'mobile',\n\t'@tablet': 'tablet',\n\t'-current': '@current',\n};\n\n/* eslint-disable @wordpress/wp-global-usage */\ndeclare global {\n\tvar IS_GUTENBERG_PLUGIN: boolean | undefined;\n}\n/* eslint-enable @wordpress/wp-global-usage */\n\n/**\n * Returns whether a value is a non-array object.\n *\n * @param value Value to check.\n * @return Whether the value is a non-array object.\n */\nfunction isObjectRecord( value: unknown ): value is Record< string, any > {\n\treturn !! value && typeof value === 'object' && ! Array.isArray( value );\n}\n\n/**\n * Normalizes legacy persisted style state aliases within a style node.\n *\n * For example, `{ mobile: { color: ... } }` becomes\n * `{ '@mobile': { color: ... } }`, and `{ '@current': { color: ... } }`\n * becomes `{ '-current': { color: ... } }`.\n *\n * @param node Style node or nested value.\n * @return Normalized style node or original value.\n */\nfunction normalizeStyleStateNode( node: any ): any {\n\tif ( ! isObjectRecord( node ) ) {\n\t\treturn node;\n\t}\n\n\tlet normalized = node;\n\n\t// Normalize legacy keys at the current style node before walking children.\n\tObject.entries( LEGACY_STYLE_STATE_ALIASES ).forEach(\n\t\t( [ state, legacyState ] ) => {\n\t\t\tif ( Object.hasOwn( node, legacyState ) ) {\n\t\t\t\t// Clone lazily before mutating this node.\n\t\t\t\tif ( normalized === node ) {\n\t\t\t\t\tnormalized = { ...node };\n\t\t\t\t}\n\t\t\t\tif ( ! Object.hasOwn( node, state ) ) {\n\t\t\t\t\tnormalized[ state ] = node[ legacyState ];\n\t\t\t\t}\n\t\t\t\tdelete normalized[ legacyState ];\n\t\t\t}\n\t\t}\n\t);\n\n\t// Recurse into nested style nodes, such as blocks, elements, and variations.\n\tObject.entries( normalized ).forEach( ( [ key, value ] ) => {\n\t\tif ( ! isObjectRecord( value ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst normalizedValue = normalizeStyleStateNode( value );\n\t\tif ( normalizedValue !== value ) {\n\t\t\t// Clone lazily before mutating this node.\n\t\t\tif ( normalized === node ) {\n\t\t\t\tnormalized = { ...node };\n\t\t\t}\n\t\t\tnormalized[ key ] = normalizedValue;\n\t\t}\n\t} );\n\n\treturn normalized;\n}\n\n/**\n * Normalizes legacy persisted style state aliases in a global styles config.\n *\n * For example, `styles.blocks['core/button'].mobile` becomes\n * `styles.blocks['core/button']['@mobile']`.\n *\n * @param globalStyles Global styles config to normalize.\n * @return Global styles config with canonical style state keys.\n */\nexport function normalizeStyleStateAliases(\n\tglobalStyles: GlobalStylesConfig\n): GlobalStylesConfig {\n\tif ( ! globalThis.IS_GUTENBERG_PLUGIN ) {\n\t\treturn globalStyles;\n\t}\n\n\tif ( ! globalStyles?.styles ) {\n\t\treturn globalStyles;\n\t}\n\n\tconst styles = normalizeStyleStateNode( globalStyles.styles );\n\treturn styles === globalStyles.styles\n\t\t? globalStyles\n\t\t: { ...globalStyles, styles };\n}\n\n/**\n * Returns the legacy equivalent of a canonical style state path.\n *\n * For example, `styles.blocks.core/button.@mobile.color.text` maps to\n * `styles.blocks.core/button.mobile.color.text`.\n *\n * @param path Canonical dot-separated object path.\n * @return Legacy path when one differs, otherwise undefined.\n */\nexport function getLegacyStyleStatePath( path: string ): string | undefined {\n\tif ( ! globalThis.IS_GUTENBERG_PLUGIN ) {\n\t\treturn undefined;\n\t}\n\n\tconst pathParts = path.split( '.' );\n\tconst legacyPathParts = pathParts.map(\n\t\t( part ) => LEGACY_STYLE_STATE_ALIASES[ part ] ?? part\n\t);\n\n\treturn legacyPathParts.some(\n\t\t( part, index ) => part !== pathParts[ index ]\n\t)\n\t\t? legacyPathParts.join( '.' )\n\t\t: undefined;\n}\n"],
|
|
5
|
+
"mappings": ";AAYA,IAAM,6BAAuD;AAAA,EAC5D,WAAW;AAAA,EACX,WAAW;AAAA,EACX,YAAY;AACb;AAcA,SAAS,eAAgB,OAAiD;AACzE,SAAO,CAAC,CAAE,SAAS,OAAO,UAAU,YAAY,CAAE,MAAM,QAAS,KAAM;AACxE;AAYA,SAAS,wBAAyB,MAAiB;AAClD,MAAK,CAAE,eAAgB,IAAK,GAAI;AAC/B,WAAO;AAAA,EACR;AAEA,MAAI,aAAa;AAGjB,SAAO,QAAS,0BAA2B,EAAE;AAAA,IAC5C,CAAE,CAAE,OAAO,WAAY,MAAO;AAC7B,UAAK,OAAO,OAAQ,MAAM,WAAY,GAAI;AAEzC,YAAK,eAAe,MAAO;AAC1B,uBAAa,EAAE,GAAG,KAAK;AAAA,QACxB;AACA,YAAK,CAAE,OAAO,OAAQ,MAAM,KAAM,GAAI;AACrC,qBAAY,KAAM,IAAI,KAAM,WAAY;AAAA,QACzC;AACA,eAAO,WAAY,WAAY;AAAA,MAChC;AAAA,IACD;AAAA,EACD;AAGA,SAAO,QAAS,UAAW,EAAE,QAAS,CAAE,CAAE,KAAK,KAAM,MAAO;AAC3D,QAAK,CAAE,eAAgB,KAAM,GAAI;AAChC;AAAA,IACD;AAEA,UAAM,kBAAkB,wBAAyB,KAAM;AACvD,QAAK,oBAAoB,OAAQ;AAEhC,UAAK,eAAe,MAAO;AAC1B,qBAAa,EAAE,GAAG,KAAK;AAAA,MACxB;AACA,iBAAY,GAAI,IAAI;AAAA,IACrB;AAAA,EACD,CAAE;AAEF,SAAO;AACR;AAWO,SAAS,2BACf,cACqB;AACrB,MAAK,CAAE,WAAW,qBAAsB;AACvC,WAAO;AAAA,EACR;AAEA,MAAK,CAAE,cAAc,QAAS;AAC7B,WAAO;AAAA,EACR;AAEA,QAAM,SAAS,wBAAyB,aAAa,MAAO;AAC5D,SAAO,WAAW,aAAa,SAC5B,eACA,EAAE,GAAG,cAAc,OAAO;AAC9B;AAWO,SAAS,wBAAyB,MAAmC;AAC3E,MAAK,CAAE,WAAW,qBAAsB;AACvC,WAAO;AAAA,EACR;AAEA,QAAM,YAAY,KAAK,MAAO,GAAI;AAClC,QAAM,kBAAkB,UAAU;AAAA,IACjC,CAAE,SAAU,2BAA4B,IAAK,KAAK;AAAA,EACnD;AAEA,SAAO,gBAAgB;AAAA,IACtB,CAAE,MAAM,UAAW,SAAS,UAAW,KAAM;AAAA,EAC9C,IACG,gBAAgB,KAAM,GAAI,IAC1B;AACJ;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"merge.d.ts","sourceRoot":"","sources":["../../src/core/merge.ts"],"names":[],"mappings":"AAOA;;GAEG;AACH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"merge.d.ts","sourceRoot":"","sources":["../../src/core/merge.ts"],"names":[],"mappings":"AAOA;;GAEG;AACH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAGnD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAChC,IAAI,EAAE,kBAAkB,EACxB,IAAI,EAAE,kBAAkB,GACtB,kBAAkB,CAyBpB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/core/render.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AA2BnD,OAAO,KAAK,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/core/render.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AA2BnD,OAAO,KAAK,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AA8CvE;;GAEG;AACH,UAAU,gBAAgB;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,KAAK,CAAE;QACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,KAAK,CAAC,EAAE,MAAM,CAAE,MAAM,EAAE,GAAG,CAAE,CAAC;KAC9B,CAAE,CAAC;IACJ,UAAU,CAAC,EAAE,KAAK,CAAE;QACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,KAAK,CAAC,EAAE,MAAM,CAAE,MAAM,EAAE,GAAG,CAAE,CAAC;KAC9B,CAAE,CAAC;CACJ;AA6BD,MAAM,MAAM,cAAc,GAAG,MAAM,CAClC,MAAM,EACN;IACC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,gBAAgB,CAAC,EACd,MAAM,GACN,MAAM,CAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAAE,MAAM,EAAE,MAAM,CAAE,CAAE,CAAC;IACvD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uBAAuB,CAAC,EAAE,MAAM,CAAE,MAAM,EAAE,MAAM,CAAE,CAAC;CACnD,CACD,CAAC;AA4bF;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CACpC,WAAW,GAAE,GAAQ,EACrB,QAAQ,GAAE,MAAW,EACrB,mBAAmB,CAAC,EAAE,OAAO,EAC7B,IAAI,GAAE,GAAQ,EACd,kBAAkB,GAAE,OAAe,GACjC,MAAM,EAAE,CAqJV;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAAE,EAChC,iBAAsC,EACtC,KAAK,EACL,QAAQ,EACR,kBAAkB,EAClB,qBAAqB,EACrB,gBAAgB,EAChB,EAAE;IACF,iBAAiB,CAAC,EAAE,MAAM,CAAE,MAAM,EAAE,gBAAgB,CAAE,CAAC;IACvD,KAAK,CAAC,EAAE,kBAAkB,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC1B,GAAI,MAAM,CA0HV;AAkJD,eAAO,MAAM,kBAAkB,SACxB,kBAAkB,kBACR,MAAM,GAAG,cAAc,KACrC,GAAG,EA4QL,CAAC;AAEF,eAAO,MAAM,oBAAoB,SAC1B,kBAAkB,kBACR,MAAM,GAAG,cAAc,KACrC,GAAG,EAgEL,CAAC;AAgFF,eAAO,MAAM,wBAAwB,SAC9B,kBAAkB,kBACR,cAAc,KAC5B,MAuDF,CAAC;AA6JF,eAAO,MAAM,iBAAiB,SACvB,kBAAkB,kBACR,MAAM,GAAG,cAAc,uBAClB,OAAO,0BACJ,OAAO,wBACV,OAAO,uBACR,OAAO,iBACb,MAAM,CAAE,MAAM,EAAE,OAAO,CAAE,KACrC,MA6IF,CAAC;AAEF,wBAAgB,kBAAkB,CACjC,IAAI,EAAE,kBAAkB,EACxB,cAAc,EAAE,cAAc,GAC5B,MAAM,EAAE,CAKV;AA0BD,eAAO,MAAM,iBAAiB,eACjB,SAAS,EAAE,wBACD,MAAM,mBAkE5B,CAAC;AAwCF,wBAAgB,iBAAiB,CAAE,GAAG,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,UAuDpE;AAED,MAAM,WAAW,yBAAyB;IACzC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,cAAc,CAAC,EAAE,CAAE,SAAS,EAAE,MAAM,KAAM,GAAG,EAAE,CAAC;IAChD,YAAY,CAAC,EAAE,MAAM,CAAE,MAAM,EAAE,OAAO,CAAE,CAAC;CACzC;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CACnC,MAAM,GAAE,kBAAkB,GAAG,SAAc,EAC3C,UAAU,GAAE,GAAG,EAAO,EACtB,OAAO,GAAE,yBAA8B,GACrC,CAAE,GAAG,EAAE,EAAE,GAAG,CAAE,CAuFhB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-style.d.ts","sourceRoot":"","sources":["../../src/settings/get-style.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,kBAAkB,EAAmB,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"get-style.d.ts","sourceRoot":"","sources":["../../src/settings/get-style.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,kBAAkB,EAAmB,MAAM,UAAU,CAAC;AAGpE,wBAAgB,QAAQ,CAAE,CAAC,GAAG,GAAG,EAChC,YAAY,CAAC,EAAE,kBAAkB,EACjC,IAAI,CAAC,EAAE,MAAM,EACb,SAAS,CAAC,EAAE,MAAM,EAClB,kBAAkB,UAAO,GACvB,CAAC,GAAG,SAAS,CAqCf"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"set-style.d.ts","sourceRoot":"","sources":["../../src/settings/set-style.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"set-style.d.ts","sourceRoot":"","sources":["../../src/settings/set-style.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAGnD,wBAAgB,QAAQ,CAAE,CAAC,GAAG,GAAG,EAChC,YAAY,EAAE,kBAAkB,EAChC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,CAAC,GAAG,SAAS,EACvB,SAAS,CAAC,EAAE,MAAM,GAChB,kBAAkB,CAWpB"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal dependencies
|
|
3
|
+
*/
|
|
4
|
+
import type { GlobalStylesConfig } from './types';
|
|
5
|
+
declare global {
|
|
6
|
+
var IS_GUTENBERG_PLUGIN: boolean | undefined;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Normalizes legacy persisted style state aliases in a global styles config.
|
|
10
|
+
*
|
|
11
|
+
* For example, `styles.blocks['core/button'].mobile` becomes
|
|
12
|
+
* `styles.blocks['core/button']['@mobile']`.
|
|
13
|
+
*
|
|
14
|
+
* @param globalStyles Global styles config to normalize.
|
|
15
|
+
* @return Global styles config with canonical style state keys.
|
|
16
|
+
*/
|
|
17
|
+
export declare function normalizeStyleStateAliases(globalStyles: GlobalStylesConfig): GlobalStylesConfig;
|
|
18
|
+
/**
|
|
19
|
+
* Returns the legacy equivalent of a canonical style state path.
|
|
20
|
+
*
|
|
21
|
+
* For example, `styles.blocks.core/button.@mobile.color.text` maps to
|
|
22
|
+
* `styles.blocks.core/button.mobile.color.text`.
|
|
23
|
+
*
|
|
24
|
+
* @param path Canonical dot-separated object path.
|
|
25
|
+
* @return Legacy path when one differs, otherwise undefined.
|
|
26
|
+
*/
|
|
27
|
+
export declare function getLegacyStyleStatePath(path: string): string | undefined;
|
|
28
|
+
//# sourceMappingURL=style-state-back-compat.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"style-state-back-compat.d.ts","sourceRoot":"","sources":["../src/style-state-back-compat.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAgBlD,OAAO,CAAC,MAAM,CAAC,CAAC;IACf,IAAI,mBAAmB,EAAE,OAAO,GAAG,SAAS,CAAC;CAC7C;AAiED;;;;;;;;GAQG;AACH,wBAAgB,0BAA0B,CACzC,YAAY,EAAE,kBAAkB,GAC9B,kBAAkB,CAapB;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CAAE,IAAI,EAAE,MAAM,GAAI,MAAM,GAAG,SAAS,CAe1E"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wordpress/global-styles-engine",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.16.0",
|
|
4
4
|
"description": "Pure CSS generation engine for WordPress global styles.",
|
|
5
5
|
"author": "The WordPress Contributors",
|
|
6
6
|
"license": "GPL-2.0-or-later",
|
|
@@ -42,10 +42,10 @@
|
|
|
42
42
|
"types": "build-types/index.d.ts",
|
|
43
43
|
"sideEffects": false,
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@wordpress/blocks": "^15.
|
|
46
|
-
"@wordpress/data": "^10.
|
|
47
|
-
"@wordpress/i18n": "^6.
|
|
48
|
-
"@wordpress/style-engine": "^2.49.
|
|
45
|
+
"@wordpress/blocks": "^15.22.0",
|
|
46
|
+
"@wordpress/data": "^10.49.0",
|
|
47
|
+
"@wordpress/i18n": "^6.22.0",
|
|
48
|
+
"@wordpress/style-engine": "^2.49.0",
|
|
49
49
|
"colord": "^2.9.3",
|
|
50
50
|
"deepmerge": "^4.3.1",
|
|
51
51
|
"fast-deep-equal": "^3.1.3",
|
|
@@ -59,5 +59,5 @@
|
|
|
59
59
|
"publishConfig": {
|
|
60
60
|
"access": "public"
|
|
61
61
|
},
|
|
62
|
-
"gitHead": "
|
|
62
|
+
"gitHead": "0e7112a4f4fde4ea15bd9060489b8f6fe11eb6ca"
|
|
63
63
|
}
|
package/src/core/merge.ts
CHANGED
|
@@ -9,6 +9,7 @@ import { isPlainObject } from 'is-plain-object';
|
|
|
9
9
|
* Internal dependencies
|
|
10
10
|
*/
|
|
11
11
|
import type { GlobalStylesConfig } from '../types';
|
|
12
|
+
import { normalizeStyleStateAliases } from '../style-state-back-compat';
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
15
|
* Merges base and user global styles configurations
|
|
@@ -21,23 +22,28 @@ export function mergeGlobalStyles(
|
|
|
21
22
|
base: GlobalStylesConfig,
|
|
22
23
|
user: GlobalStylesConfig
|
|
23
24
|
): GlobalStylesConfig {
|
|
24
|
-
return deepmerge(
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
25
|
+
return deepmerge(
|
|
26
|
+
normalizeStyleStateAliases( base ),
|
|
27
|
+
normalizeStyleStateAliases( user ),
|
|
28
|
+
{
|
|
29
|
+
/*
|
|
30
|
+
* We only pass as arrays the presets,
|
|
31
|
+
* in which case we want the new array of values
|
|
32
|
+
* to override the old array (no merging).
|
|
33
|
+
*/
|
|
34
|
+
isMergeableObject: isPlainObject,
|
|
35
|
+
/*
|
|
36
|
+
* Exceptions to the above rule.
|
|
37
|
+
* Background images should be replaced, not merged,
|
|
38
|
+
* as they themselves are specific object definitions for the style.
|
|
39
|
+
*/
|
|
40
|
+
customMerge: ( key ) => {
|
|
41
|
+
if ( key === 'backgroundImage' ) {
|
|
42
|
+
return ( baseConfig, userConfig ) =>
|
|
43
|
+
userConfig ?? baseConfig;
|
|
44
|
+
}
|
|
45
|
+
return undefined;
|
|
46
|
+
},
|
|
47
|
+
}
|
|
48
|
+
);
|
|
43
49
|
}
|
package/src/core/render.tsx
CHANGED
|
@@ -36,6 +36,7 @@ import { LAYOUT_DEFINITIONS } from '../utils/layout';
|
|
|
36
36
|
import { getValueFromObjectPath, setImmutably } from '../utils/object';
|
|
37
37
|
import { getSetting } from '../settings/get-setting';
|
|
38
38
|
import type { GlobalStylesConfig, GlobalStylesStyles } from '../types';
|
|
39
|
+
import { normalizeStyleStateAliases } from '../style-state-back-compat';
|
|
39
40
|
|
|
40
41
|
// =============================================================================
|
|
41
42
|
// LOCAL TYPE DEFINITIONS
|
|
@@ -232,8 +233,8 @@ const VALID_ELEMENT_PSEUDO_SELECTORS: Record< string, string[] > = {
|
|
|
232
233
|
* Keep in sync with WP_Theme_JSON_Gutenberg::RESPONSIVE_BREAKPOINTS.
|
|
233
234
|
*/
|
|
234
235
|
const RESPONSIVE_BREAKPOINTS: Record< string, string > = {
|
|
235
|
-
mobile: '@media (width <= 480px)',
|
|
236
|
-
tablet: '@media (480px < width <= 782px)',
|
|
236
|
+
'@mobile': '@media (width <= 480px)',
|
|
237
|
+
'@tablet': '@media (480px < width <= 782px)',
|
|
237
238
|
};
|
|
238
239
|
|
|
239
240
|
/**
|
|
@@ -1699,10 +1700,18 @@ export const transformToStyles = (
|
|
|
1699
1700
|
variationStyles: false,
|
|
1700
1701
|
...styleOptions,
|
|
1701
1702
|
};
|
|
1702
|
-
const
|
|
1703
|
-
const
|
|
1704
|
-
|
|
1705
|
-
|
|
1703
|
+
const normalizedTree = normalizeStyleStateAliases( tree );
|
|
1704
|
+
const nodesWithStyles = getNodesWithStyles(
|
|
1705
|
+
normalizedTree,
|
|
1706
|
+
blockSelectors
|
|
1707
|
+
);
|
|
1708
|
+
const nodesWithSettings = getNodesWithSettings(
|
|
1709
|
+
normalizedTree,
|
|
1710
|
+
blockSelectors
|
|
1711
|
+
);
|
|
1712
|
+
const useRootPaddingAlign =
|
|
1713
|
+
normalizedTree?.settings?.useRootPaddingAwareAlignments;
|
|
1714
|
+
const { contentSize, wideSize } = normalizedTree?.settings?.layout || {};
|
|
1706
1715
|
const hasBodyStyles =
|
|
1707
1716
|
options.marginReset || options.rootPadding || options.layoutStyles;
|
|
1708
1717
|
|
|
@@ -1762,7 +1771,7 @@ export const transformToStyles = (
|
|
|
1762
1771
|
...responsiveNodes.flatMap( getPseudoStyleNodes ),
|
|
1763
1772
|
].forEach( ( expandedNode ) => {
|
|
1764
1773
|
ruleset += renderStylesNode( expandedNode, {
|
|
1765
|
-
tree,
|
|
1774
|
+
tree: normalizedTree,
|
|
1766
1775
|
useRootPaddingAlign,
|
|
1767
1776
|
disableLayoutStyles,
|
|
1768
1777
|
hasBlockGapSupport,
|
|
@@ -1789,7 +1798,8 @@ export const transformToStyles = (
|
|
|
1789
1798
|
if ( options.blockGap && hasBlockGapSupport ) {
|
|
1790
1799
|
// Use fallback of `0.5em` just in case, however if there is blockGap support, there should nearly always be a real value.
|
|
1791
1800
|
const gapValue =
|
|
1792
|
-
getGapCSSValue(
|
|
1801
|
+
getGapCSSValue( normalizedTree?.styles?.spacing?.blockGap ) ||
|
|
1802
|
+
'0.5em';
|
|
1793
1803
|
ruleset =
|
|
1794
1804
|
ruleset +
|
|
1795
1805
|
`:root :where(.wp-site-blocks) > * { margin-block-start: ${ gapValue }; margin-block-end: 0; }`;
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import { getValueFromObjectPath } from '../utils/object';
|
|
5
5
|
import { getValueFromVariable } from '../utils/common';
|
|
6
6
|
import type { GlobalStylesConfig, UnresolvedValue } from '../types';
|
|
7
|
+
import { getLegacyStyleStatePath } from '../style-state-back-compat';
|
|
7
8
|
|
|
8
9
|
export function getStyle< T = any >(
|
|
9
10
|
globalStyles?: GlobalStylesConfig,
|
|
@@ -19,9 +20,30 @@ export function getStyle< T = any >(
|
|
|
19
20
|
return undefined;
|
|
20
21
|
}
|
|
21
22
|
|
|
22
|
-
|
|
23
|
+
let rawResult = getValueFromObjectPath( globalStyles, finalPath ) as
|
|
23
24
|
| string
|
|
24
25
|
| UnresolvedValue;
|
|
26
|
+
const legacyPath = getLegacyStyleStatePath( finalPath );
|
|
27
|
+
if ( rawResult === undefined && legacyPath ) {
|
|
28
|
+
let hasCanonicalPath = true;
|
|
29
|
+
let currentValue: any = globalStyles;
|
|
30
|
+
for ( const pathPart of finalPath.split( '.' ) ) {
|
|
31
|
+
if (
|
|
32
|
+
! currentValue ||
|
|
33
|
+
typeof currentValue !== 'object' ||
|
|
34
|
+
! Object.hasOwn( currentValue, pathPart )
|
|
35
|
+
) {
|
|
36
|
+
hasCanonicalPath = false;
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
currentValue = currentValue[ pathPart ];
|
|
40
|
+
}
|
|
41
|
+
if ( ! hasCanonicalPath ) {
|
|
42
|
+
rawResult = getValueFromObjectPath( globalStyles, legacyPath ) as
|
|
43
|
+
| string
|
|
44
|
+
| UnresolvedValue;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
25
47
|
const result = shouldDecodeEncode
|
|
26
48
|
? getValueFromVariable( globalStyles, blockName, rawResult )
|
|
27
49
|
: rawResult;
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { setImmutably } from '../utils/object';
|
|
5
5
|
import type { GlobalStylesConfig } from '../types';
|
|
6
|
+
import { normalizeStyleStateAliases } from '../style-state-back-compat';
|
|
6
7
|
|
|
7
8
|
export function setStyle< T = any >(
|
|
8
9
|
globalStyles: GlobalStylesConfig,
|
|
@@ -16,7 +17,7 @@ export function setStyle< T = any >(
|
|
|
16
17
|
: `styles.blocks.${ blockName }${ appendedPath }`;
|
|
17
18
|
|
|
18
19
|
return setImmutably(
|
|
19
|
-
globalStyles,
|
|
20
|
+
normalizeStyleStateAliases( globalStyles ),
|
|
20
21
|
finalPath.split( '.' ),
|
|
21
22
|
newValue
|
|
22
23
|
) as GlobalStylesConfig;
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal dependencies
|
|
3
|
+
*/
|
|
4
|
+
import type { GlobalStylesConfig } from './types';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Temporary aliases for persisted style state keys shipped before breakpoint
|
|
8
|
+
* states used the `@` prefix and custom states used the `-` prefix.
|
|
9
|
+
*
|
|
10
|
+
* Gutenberg plugin back compat for data saved before state keys were prefixed.
|
|
11
|
+
* Guarded by `IS_GUTENBERG_PLUGIN` so synced Core package code does not apply it.
|
|
12
|
+
*/
|
|
13
|
+
const LEGACY_STYLE_STATE_ALIASES: Record< string, string > = {
|
|
14
|
+
'@mobile': 'mobile',
|
|
15
|
+
'@tablet': 'tablet',
|
|
16
|
+
'-current': '@current',
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
/* eslint-disable @wordpress/wp-global-usage */
|
|
20
|
+
declare global {
|
|
21
|
+
var IS_GUTENBERG_PLUGIN: boolean | undefined;
|
|
22
|
+
}
|
|
23
|
+
/* eslint-enable @wordpress/wp-global-usage */
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Returns whether a value is a non-array object.
|
|
27
|
+
*
|
|
28
|
+
* @param value Value to check.
|
|
29
|
+
* @return Whether the value is a non-array object.
|
|
30
|
+
*/
|
|
31
|
+
function isObjectRecord( value: unknown ): value is Record< string, any > {
|
|
32
|
+
return !! value && typeof value === 'object' && ! Array.isArray( value );
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Normalizes legacy persisted style state aliases within a style node.
|
|
37
|
+
*
|
|
38
|
+
* For example, `{ mobile: { color: ... } }` becomes
|
|
39
|
+
* `{ '@mobile': { color: ... } }`, and `{ '@current': { color: ... } }`
|
|
40
|
+
* becomes `{ '-current': { color: ... } }`.
|
|
41
|
+
*
|
|
42
|
+
* @param node Style node or nested value.
|
|
43
|
+
* @return Normalized style node or original value.
|
|
44
|
+
*/
|
|
45
|
+
function normalizeStyleStateNode( node: any ): any {
|
|
46
|
+
if ( ! isObjectRecord( node ) ) {
|
|
47
|
+
return node;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
let normalized = node;
|
|
51
|
+
|
|
52
|
+
// Normalize legacy keys at the current style node before walking children.
|
|
53
|
+
Object.entries( LEGACY_STYLE_STATE_ALIASES ).forEach(
|
|
54
|
+
( [ state, legacyState ] ) => {
|
|
55
|
+
if ( Object.hasOwn( node, legacyState ) ) {
|
|
56
|
+
// Clone lazily before mutating this node.
|
|
57
|
+
if ( normalized === node ) {
|
|
58
|
+
normalized = { ...node };
|
|
59
|
+
}
|
|
60
|
+
if ( ! Object.hasOwn( node, state ) ) {
|
|
61
|
+
normalized[ state ] = node[ legacyState ];
|
|
62
|
+
}
|
|
63
|
+
delete normalized[ legacyState ];
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
// Recurse into nested style nodes, such as blocks, elements, and variations.
|
|
69
|
+
Object.entries( normalized ).forEach( ( [ key, value ] ) => {
|
|
70
|
+
if ( ! isObjectRecord( value ) ) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const normalizedValue = normalizeStyleStateNode( value );
|
|
75
|
+
if ( normalizedValue !== value ) {
|
|
76
|
+
// Clone lazily before mutating this node.
|
|
77
|
+
if ( normalized === node ) {
|
|
78
|
+
normalized = { ...node };
|
|
79
|
+
}
|
|
80
|
+
normalized[ key ] = normalizedValue;
|
|
81
|
+
}
|
|
82
|
+
} );
|
|
83
|
+
|
|
84
|
+
return normalized;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Normalizes legacy persisted style state aliases in a global styles config.
|
|
89
|
+
*
|
|
90
|
+
* For example, `styles.blocks['core/button'].mobile` becomes
|
|
91
|
+
* `styles.blocks['core/button']['@mobile']`.
|
|
92
|
+
*
|
|
93
|
+
* @param globalStyles Global styles config to normalize.
|
|
94
|
+
* @return Global styles config with canonical style state keys.
|
|
95
|
+
*/
|
|
96
|
+
export function normalizeStyleStateAliases(
|
|
97
|
+
globalStyles: GlobalStylesConfig
|
|
98
|
+
): GlobalStylesConfig {
|
|
99
|
+
if ( ! globalThis.IS_GUTENBERG_PLUGIN ) {
|
|
100
|
+
return globalStyles;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if ( ! globalStyles?.styles ) {
|
|
104
|
+
return globalStyles;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const styles = normalizeStyleStateNode( globalStyles.styles );
|
|
108
|
+
return styles === globalStyles.styles
|
|
109
|
+
? globalStyles
|
|
110
|
+
: { ...globalStyles, styles };
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Returns the legacy equivalent of a canonical style state path.
|
|
115
|
+
*
|
|
116
|
+
* For example, `styles.blocks.core/button.@mobile.color.text` maps to
|
|
117
|
+
* `styles.blocks.core/button.mobile.color.text`.
|
|
118
|
+
*
|
|
119
|
+
* @param path Canonical dot-separated object path.
|
|
120
|
+
* @return Legacy path when one differs, otherwise undefined.
|
|
121
|
+
*/
|
|
122
|
+
export function getLegacyStyleStatePath( path: string ): string | undefined {
|
|
123
|
+
if ( ! globalThis.IS_GUTENBERG_PLUGIN ) {
|
|
124
|
+
return undefined;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const pathParts = path.split( '.' );
|
|
128
|
+
const legacyPathParts = pathParts.map(
|
|
129
|
+
( part ) => LEGACY_STYLE_STATE_ALIASES[ part ] ?? part
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
return legacyPathParts.some(
|
|
133
|
+
( part, index ) => part !== pathParts[ index ]
|
|
134
|
+
)
|
|
135
|
+
? legacyPathParts.join( '.' )
|
|
136
|
+
: undefined;
|
|
137
|
+
}
|
package/src/test/render.test.ts
CHANGED
|
@@ -682,7 +682,7 @@ describe( 'global styles renderer', () => {
|
|
|
682
682
|
text: 'blue',
|
|
683
683
|
},
|
|
684
684
|
},
|
|
685
|
-
mobile: {
|
|
685
|
+
'@mobile': {
|
|
686
686
|
color: {
|
|
687
687
|
text: 'green',
|
|
688
688
|
},
|
|
@@ -790,7 +790,7 @@ describe( 'global styles renderer', () => {
|
|
|
790
790
|
text: 'blue',
|
|
791
791
|
},
|
|
792
792
|
},
|
|
793
|
-
mobile: {
|
|
793
|
+
'@mobile': {
|
|
794
794
|
color: {
|
|
795
795
|
text: 'red',
|
|
796
796
|
},
|
|
@@ -832,7 +832,7 @@ describe( 'global styles renderer', () => {
|
|
|
832
832
|
text: 'blue',
|
|
833
833
|
},
|
|
834
834
|
},
|
|
835
|
-
mobile: {
|
|
835
|
+
'@mobile': {
|
|
836
836
|
color: {
|
|
837
837
|
text: 'green',
|
|
838
838
|
},
|
|
@@ -945,7 +945,7 @@ describe( 'global styles renderer', () => {
|
|
|
945
945
|
width: '20rem',
|
|
946
946
|
},
|
|
947
947
|
},
|
|
948
|
-
tablet: {
|
|
948
|
+
'@tablet': {
|
|
949
949
|
color: {
|
|
950
950
|
text: 'red',
|
|
951
951
|
},
|
|
@@ -1002,6 +1002,45 @@ describe( 'global styles renderer', () => {
|
|
|
1002
1002
|
} );
|
|
1003
1003
|
|
|
1004
1004
|
it( 'handles responsive block styles', () => {
|
|
1005
|
+
const tree = {
|
|
1006
|
+
styles: {
|
|
1007
|
+
blocks: {
|
|
1008
|
+
'core/button': {
|
|
1009
|
+
color: {
|
|
1010
|
+
text: 'red',
|
|
1011
|
+
},
|
|
1012
|
+
'@mobile': {
|
|
1013
|
+
color: {
|
|
1014
|
+
text: 'blue',
|
|
1015
|
+
},
|
|
1016
|
+
},
|
|
1017
|
+
},
|
|
1018
|
+
},
|
|
1019
|
+
},
|
|
1020
|
+
} as unknown as GlobalStylesConfig;
|
|
1021
|
+
|
|
1022
|
+
const blockSelectors = {
|
|
1023
|
+
'core/button': {
|
|
1024
|
+
selector: '.wp-block-button',
|
|
1025
|
+
},
|
|
1026
|
+
};
|
|
1027
|
+
|
|
1028
|
+
const result = transformToStyles(
|
|
1029
|
+
Object.freeze( tree ),
|
|
1030
|
+
blockSelectors,
|
|
1031
|
+
false,
|
|
1032
|
+
false,
|
|
1033
|
+
true,
|
|
1034
|
+
true,
|
|
1035
|
+
minimalStyleOptions
|
|
1036
|
+
);
|
|
1037
|
+
|
|
1038
|
+
expect( result ).toEqual(
|
|
1039
|
+
':root :where(.wp-block-button){color: red;}@media (width <= 480px){:root :where(.wp-block-button){color: blue;}}'
|
|
1040
|
+
);
|
|
1041
|
+
} );
|
|
1042
|
+
|
|
1043
|
+
it( 'handles legacy responsive block styles', () => {
|
|
1005
1044
|
const tree = {
|
|
1006
1045
|
styles: {
|
|
1007
1046
|
blocks: {
|
|
@@ -1050,7 +1089,7 @@ describe( 'global styles renderer', () => {
|
|
|
1050
1089
|
text: 'blue',
|
|
1051
1090
|
},
|
|
1052
1091
|
},
|
|
1053
|
-
mobile: {
|
|
1092
|
+
'@mobile': {
|
|
1054
1093
|
color: {
|
|
1055
1094
|
text: 'red',
|
|
1056
1095
|
},
|
|
@@ -1095,7 +1134,7 @@ describe( 'global styles renderer', () => {
|
|
|
1095
1134
|
dimensions: {
|
|
1096
1135
|
width: '25%',
|
|
1097
1136
|
},
|
|
1098
|
-
mobile: {
|
|
1137
|
+
'@mobile': {
|
|
1099
1138
|
dimensions: {
|
|
1100
1139
|
width: '50%',
|
|
1101
1140
|
},
|
|
@@ -1140,7 +1179,7 @@ describe( 'global styles renderer', () => {
|
|
|
1140
1179
|
color: {
|
|
1141
1180
|
text: 'blue',
|
|
1142
1181
|
},
|
|
1143
|
-
mobile: {
|
|
1182
|
+
'@mobile': {
|
|
1144
1183
|
color: {
|
|
1145
1184
|
text: 'red',
|
|
1146
1185
|
},
|
|
@@ -1180,7 +1219,7 @@ describe( 'global styles renderer', () => {
|
|
|
1180
1219
|
color: {
|
|
1181
1220
|
text: 'green',
|
|
1182
1221
|
},
|
|
1183
|
-
mobile: {
|
|
1222
|
+
'@mobile': {
|
|
1184
1223
|
color: {
|
|
1185
1224
|
text: 'yellow',
|
|
1186
1225
|
},
|