@wordpress/block-library 8.12.6 → 8.14.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.
Files changed (305) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/build/archives/index.js +5 -1
  3. package/build/archives/index.js.map +1 -1
  4. package/build/audio/index.js +5 -1
  5. package/build/audio/index.js.map +1 -1
  6. package/build/block/edit.native.js +2 -2
  7. package/build/block/edit.native.js.map +1 -1
  8. package/build/categories/index.js +5 -1
  9. package/build/categories/index.js.map +1 -1
  10. package/build/code/index.js +5 -1
  11. package/build/code/index.js.map +1 -1
  12. package/build/column/index.js +1 -0
  13. package/build/column/index.js.map +1 -1
  14. package/build/comments/index.js +1 -0
  15. package/build/comments/index.js.map +1 -1
  16. package/build/cover/edit/inspector-controls.js +2 -1
  17. package/build/cover/edit/inspector-controls.js.map +1 -1
  18. package/build/cover/index.js +1 -0
  19. package/build/cover/index.js.map +1 -1
  20. package/build/details/index.js +5 -1
  21. package/build/details/index.js.map +1 -1
  22. package/build/embed/util.js +9 -8
  23. package/build/embed/util.js.map +1 -1
  24. package/build/file/index.js +2 -1
  25. package/build/file/index.js.map +1 -1
  26. package/build/file/view.js +15 -1
  27. package/build/file/view.js.map +1 -1
  28. package/build/gallery/index.js +3 -1
  29. package/build/gallery/index.js.map +1 -1
  30. package/build/group/index.js +1 -0
  31. package/build/group/index.js.map +1 -1
  32. package/build/heading/index.js +5 -1
  33. package/build/heading/index.js.map +1 -1
  34. package/build/heading/transforms.js +5 -1
  35. package/build/heading/transforms.js.map +1 -1
  36. package/build/image/deprecated.js +453 -175
  37. package/build/image/deprecated.js.map +1 -1
  38. package/build/image/image.js +1 -1
  39. package/build/image/image.js.map +1 -1
  40. package/build/image/save.js +3 -1
  41. package/build/image/save.js.map +1 -1
  42. package/build/image/{interactivity.js → view-interactivity.js} +86 -44
  43. package/build/image/view-interactivity.js.map +1 -0
  44. package/build/index.js +12 -3
  45. package/build/index.js.map +1 -1
  46. package/build/list/index.js +5 -1
  47. package/build/list/index.js.map +1 -1
  48. package/build/list-item/utils.js +6 -1
  49. package/build/list-item/utils.js.map +1 -1
  50. package/build/media-text/index.js +1 -0
  51. package/build/media-text/index.js.map +1 -1
  52. package/build/missing/edit.js +22 -8
  53. package/build/missing/edit.js.map +1 -1
  54. package/build/navigation/index.js +3 -2
  55. package/build/navigation/index.js.map +1 -1
  56. package/build/navigation/view.js +174 -50
  57. package/build/navigation/view.js.map +1 -1
  58. package/build/page-list/convert-to-links-modal.js +3 -3
  59. package/build/page-list/convert-to-links-modal.js.map +1 -1
  60. package/build/page-list/edit.js +34 -39
  61. package/build/page-list/edit.js.map +1 -1
  62. package/build/page-list/use-convert-to-navigation-links.js +2 -15
  63. package/build/page-list/use-convert-to-navigation-links.js.map +1 -1
  64. package/build/paragraph/index.js +1 -0
  65. package/build/paragraph/index.js.map +1 -1
  66. package/build/paragraph/transforms.js +1 -0
  67. package/build/paragraph/transforms.js.map +1 -1
  68. package/build/post-comments-form/index.js +1 -0
  69. package/build/post-comments-form/index.js.map +1 -1
  70. package/build/post-navigation-link/index.js +1 -0
  71. package/build/post-navigation-link/index.js.map +1 -1
  72. package/build/post-time-to-read/index.js +5 -1
  73. package/build/post-time-to-read/index.js.map +1 -1
  74. package/build/quote/index.js +1 -0
  75. package/build/quote/index.js.map +1 -1
  76. package/build/site-logo/index.js +5 -1
  77. package/build/site-logo/index.js.map +1 -1
  78. package/build/site-tagline/index.js +5 -1
  79. package/build/site-tagline/index.js.map +1 -1
  80. package/build/site-title/index.js +5 -1
  81. package/build/site-title/index.js.map +1 -1
  82. package/build/social-links/index.js +3 -1
  83. package/build/social-links/index.js.map +1 -1
  84. package/build/table/index.js +5 -1
  85. package/build/table/index.js.map +1 -1
  86. package/build/term-description/index.js +1 -0
  87. package/build/term-description/index.js.map +1 -1
  88. package/build/verse/index.js +5 -1
  89. package/build/verse/index.js.map +1 -1
  90. package/build/video/deprecated.js +5 -1
  91. package/build/video/deprecated.js.map +1 -1
  92. package/build/video/index.js +5 -1
  93. package/build/video/index.js.map +1 -1
  94. package/build-module/archives/index.js +5 -1
  95. package/build-module/archives/index.js.map +1 -1
  96. package/build-module/audio/index.js +5 -1
  97. package/build-module/audio/index.js.map +1 -1
  98. package/build-module/block/edit.native.js +2 -2
  99. package/build-module/block/edit.native.js.map +1 -1
  100. package/build-module/categories/index.js +5 -1
  101. package/build-module/categories/index.js.map +1 -1
  102. package/build-module/code/index.js +5 -1
  103. package/build-module/code/index.js.map +1 -1
  104. package/build-module/column/index.js +1 -0
  105. package/build-module/column/index.js.map +1 -1
  106. package/build-module/comments/index.js +1 -0
  107. package/build-module/comments/index.js.map +1 -1
  108. package/build-module/cover/edit/inspector-controls.js +2 -1
  109. package/build-module/cover/edit/inspector-controls.js.map +1 -1
  110. package/build-module/cover/index.js +1 -0
  111. package/build-module/cover/index.js.map +1 -1
  112. package/build-module/details/index.js +5 -1
  113. package/build-module/details/index.js.map +1 -1
  114. package/build-module/embed/util.js +6 -6
  115. package/build-module/embed/util.js.map +1 -1
  116. package/build-module/file/index.js +2 -1
  117. package/build-module/file/index.js.map +1 -1
  118. package/build-module/file/view.js +15 -2
  119. package/build-module/file/view.js.map +1 -1
  120. package/build-module/gallery/index.js +3 -1
  121. package/build-module/gallery/index.js.map +1 -1
  122. package/build-module/group/index.js +1 -0
  123. package/build-module/group/index.js.map +1 -1
  124. package/build-module/heading/index.js +5 -1
  125. package/build-module/heading/index.js.map +1 -1
  126. package/build-module/heading/transforms.js +5 -1
  127. package/build-module/heading/transforms.js.map +1 -1
  128. package/build-module/image/deprecated.js +454 -176
  129. package/build-module/image/deprecated.js.map +1 -1
  130. package/build-module/image/image.js +1 -1
  131. package/build-module/image/image.js.map +1 -1
  132. package/build-module/image/save.js +3 -1
  133. package/build-module/image/save.js.map +1 -1
  134. package/build-module/image/{interactivity.js → view-interactivity.js} +86 -44
  135. package/build-module/image/view-interactivity.js.map +1 -0
  136. package/build-module/index.js +12 -3
  137. package/build-module/index.js.map +1 -1
  138. package/build-module/list/index.js +5 -1
  139. package/build-module/list/index.js.map +1 -1
  140. package/build-module/list-item/utils.js +6 -1
  141. package/build-module/list-item/utils.js.map +1 -1
  142. package/build-module/media-text/index.js +1 -0
  143. package/build-module/media-text/index.js.map +1 -1
  144. package/build-module/missing/edit.js +22 -8
  145. package/build-module/missing/edit.js.map +1 -1
  146. package/build-module/navigation/index.js +3 -2
  147. package/build-module/navigation/index.js.map +1 -1
  148. package/build-module/navigation/view.js +173 -50
  149. package/build-module/navigation/view.js.map +1 -1
  150. package/build-module/page-list/convert-to-links-modal.js +3 -3
  151. package/build-module/page-list/convert-to-links-modal.js.map +1 -1
  152. package/build-module/page-list/edit.js +34 -39
  153. package/build-module/page-list/edit.js.map +1 -1
  154. package/build-module/page-list/use-convert-to-navigation-links.js +3 -16
  155. package/build-module/page-list/use-convert-to-navigation-links.js.map +1 -1
  156. package/build-module/paragraph/index.js +1 -0
  157. package/build-module/paragraph/index.js.map +1 -1
  158. package/build-module/paragraph/transforms.js +1 -0
  159. package/build-module/paragraph/transforms.js.map +1 -1
  160. package/build-module/post-comments-form/index.js +1 -0
  161. package/build-module/post-comments-form/index.js.map +1 -1
  162. package/build-module/post-navigation-link/index.js +1 -0
  163. package/build-module/post-navigation-link/index.js.map +1 -1
  164. package/build-module/post-time-to-read/index.js +5 -1
  165. package/build-module/post-time-to-read/index.js.map +1 -1
  166. package/build-module/quote/index.js +1 -0
  167. package/build-module/quote/index.js.map +1 -1
  168. package/build-module/site-logo/index.js +5 -1
  169. package/build-module/site-logo/index.js.map +1 -1
  170. package/build-module/site-tagline/index.js +5 -1
  171. package/build-module/site-tagline/index.js.map +1 -1
  172. package/build-module/site-title/index.js +5 -1
  173. package/build-module/site-title/index.js.map +1 -1
  174. package/build-module/social-links/index.js +3 -1
  175. package/build-module/social-links/index.js.map +1 -1
  176. package/build-module/table/index.js +5 -1
  177. package/build-module/table/index.js.map +1 -1
  178. package/build-module/term-description/index.js +1 -0
  179. package/build-module/term-description/index.js.map +1 -1
  180. package/build-module/verse/index.js +5 -1
  181. package/build-module/verse/index.js.map +1 -1
  182. package/build-module/video/deprecated.js +5 -1
  183. package/build-module/video/deprecated.js.map +1 -1
  184. package/build-module/video/index.js +5 -1
  185. package/build-module/video/index.js.map +1 -1
  186. package/build-style/image/style-rtl.css +16 -2
  187. package/build-style/image/style.css +16 -2
  188. package/build-style/style-rtl.css +16 -2
  189. package/build-style/style.css +16 -2
  190. package/package.json +33 -38
  191. package/src/archives/block.json +5 -1
  192. package/src/audio/block.json +5 -1
  193. package/src/block/edit.native.js +2 -2
  194. package/src/block/test/edit.native.js +4 -4
  195. package/src/categories/block.json +5 -1
  196. package/src/code/block.json +5 -1
  197. package/src/column/block.json +1 -0
  198. package/src/comments/block.json +1 -0
  199. package/src/cover/block.json +1 -0
  200. package/src/cover/edit/inspector-controls.js +1 -0
  201. package/src/details/block.json +5 -1
  202. package/src/embed/util.js +4 -6
  203. package/src/file/block.json +2 -1
  204. package/src/file/index.php +0 -17
  205. package/src/file/view.js +14 -5
  206. package/src/gallery/block.json +3 -1
  207. package/src/group/block.json +1 -0
  208. package/src/heading/block.json +5 -1
  209. package/src/heading/test/index.native.js +18 -0
  210. package/src/image/deprecated.js +597 -320
  211. package/src/image/image.js +2 -1
  212. package/src/image/save.js +2 -0
  213. package/src/image/style.scss +15 -2
  214. package/src/image/{interactivity.js → view-interactivity.js} +99 -50
  215. package/src/index.js +18 -1
  216. package/src/list/block.json +5 -1
  217. package/src/media-text/block.json +1 -0
  218. package/src/missing/edit.js +31 -11
  219. package/src/navigation/block.json +3 -2
  220. package/src/navigation/index.php +15 -20
  221. package/src/navigation/view.js +189 -67
  222. package/src/navigation-submenu/index.php +0 -10
  223. package/src/page-list/convert-to-links-modal.js +3 -3
  224. package/src/page-list/edit.js +65 -62
  225. package/src/page-list/use-convert-to-navigation-links.js +3 -20
  226. package/src/paragraph/block.json +1 -0
  227. package/src/post-comments-form/block.json +1 -0
  228. package/src/post-navigation-link/block.json +1 -0
  229. package/src/post-time-to-read/block.json +5 -1
  230. package/src/quote/block.json +1 -0
  231. package/src/site-logo/block.json +5 -1
  232. package/src/site-tagline/block.json +5 -1
  233. package/src/site-title/block.json +5 -1
  234. package/src/social-links/block.json +3 -1
  235. package/src/table/block.json +5 -1
  236. package/src/term-description/block.json +1 -0
  237. package/src/verse/block.json +5 -1
  238. package/src/video/block.json +5 -1
  239. package/build/file/interactivity.js +0 -19
  240. package/build/file/interactivity.js.map +0 -1
  241. package/build/heading/heading-level-icon.js +0 -61
  242. package/build/heading/heading-level-icon.js.map +0 -1
  243. package/build/image/interactivity.js.map +0 -1
  244. package/build/navigation/interactivity.js +0 -167
  245. package/build/navigation/interactivity.js.map +0 -1
  246. package/build/navigation/view-modal.js +0 -64
  247. package/build/navigation/view-modal.js.map +0 -1
  248. package/build/utils/interactivity/constants.js +0 -9
  249. package/build/utils/interactivity/constants.js.map +0 -1
  250. package/build/utils/interactivity/directives.js +0 -222
  251. package/build/utils/interactivity/directives.js.map +0 -1
  252. package/build/utils/interactivity/hooks.js +0 -159
  253. package/build/utils/interactivity/hooks.js.map +0 -1
  254. package/build/utils/interactivity/hydration.js +0 -34
  255. package/build/utils/interactivity/hydration.js.map +0 -1
  256. package/build/utils/interactivity/index.js +0 -32
  257. package/build/utils/interactivity/index.js.map +0 -1
  258. package/build/utils/interactivity/portals.js +0 -108
  259. package/build/utils/interactivity/portals.js.map +0 -1
  260. package/build/utils/interactivity/store.js +0 -66
  261. package/build/utils/interactivity/store.js.map +0 -1
  262. package/build/utils/interactivity/utils.js +0 -87
  263. package/build/utils/interactivity/utils.js.map +0 -1
  264. package/build/utils/interactivity/vdom.js +0 -119
  265. package/build/utils/interactivity/vdom.js.map +0 -1
  266. package/build-module/file/interactivity.js +0 -15
  267. package/build-module/file/interactivity.js.map +0 -1
  268. package/build-module/heading/heading-level-icon.js +0 -53
  269. package/build-module/heading/heading-level-icon.js.map +0 -1
  270. package/build-module/image/interactivity.js.map +0 -1
  271. package/build-module/navigation/interactivity.js +0 -164
  272. package/build-module/navigation/interactivity.js.map +0 -1
  273. package/build-module/navigation/view-modal.js +0 -58
  274. package/build-module/navigation/view-modal.js.map +0 -1
  275. package/build-module/utils/interactivity/constants.js +0 -2
  276. package/build-module/utils/interactivity/constants.js.map +0 -1
  277. package/build-module/utils/interactivity/directives.js +0 -209
  278. package/build-module/utils/interactivity/directives.js.map +0 -1
  279. package/build-module/utils/interactivity/hooks.js +0 -145
  280. package/build-module/utils/interactivity/hooks.js.map +0 -1
  281. package/build-module/utils/interactivity/hydration.js +0 -21
  282. package/build-module/utils/interactivity/hydration.js.map +0 -1
  283. package/build-module/utils/interactivity/index.js +0 -15
  284. package/build-module/utils/interactivity/index.js.map +0 -1
  285. package/build-module/utils/interactivity/portals.js +0 -100
  286. package/build-module/utils/interactivity/portals.js.map +0 -1
  287. package/build-module/utils/interactivity/store.js +0 -55
  288. package/build-module/utils/interactivity/store.js.map +0 -1
  289. package/build-module/utils/interactivity/utils.js +0 -75
  290. package/build-module/utils/interactivity/utils.js.map +0 -1
  291. package/build-module/utils/interactivity/vdom.js +0 -107
  292. package/build-module/utils/interactivity/vdom.js.map +0 -1
  293. package/src/file/interactivity.js +0 -15
  294. package/src/heading/heading-level-icon.js +0 -48
  295. package/src/navigation/interactivity.js +0 -169
  296. package/src/navigation/view-modal.js +0 -78
  297. package/src/utils/interactivity/constants.js +0 -1
  298. package/src/utils/interactivity/directives.js +0 -200
  299. package/src/utils/interactivity/hooks.js +0 -145
  300. package/src/utils/interactivity/hydration.js +0 -22
  301. package/src/utils/interactivity/index.js +0 -15
  302. package/src/utils/interactivity/portals.js +0 -98
  303. package/src/utils/interactivity/store.js +0 -45
  304. package/src/utils/interactivity/utils.js +0 -66
  305. package/src/utils/interactivity/vdom.js +0 -111
@@ -1,200 +0,0 @@
1
- /**
2
- * External dependencies
3
- */
4
- import { useContext, useMemo, useEffect } from 'preact/hooks';
5
- import { deepSignal, peek } from 'deepsignal';
6
- /**
7
- * Internal dependencies
8
- */
9
- import { createPortal } from './portals.js';
10
-
11
- /**
12
- * Internal dependencies
13
- */
14
- import { useSignalEffect } from './utils';
15
- import { directive } from './hooks';
16
-
17
- const isObject = ( item ) =>
18
- item && typeof item === 'object' && ! Array.isArray( item );
19
-
20
- const mergeDeepSignals = ( target, source ) => {
21
- for ( const k in source ) {
22
- if ( typeof peek( target, k ) === 'undefined' ) {
23
- target[ `$${ k }` ] = source[ `$${ k }` ];
24
- } else if (
25
- isObject( peek( target, k ) ) &&
26
- isObject( peek( source, k ) )
27
- ) {
28
- mergeDeepSignals(
29
- target[ `$${ k }` ].peek(),
30
- source[ `$${ k }` ].peek()
31
- );
32
- }
33
- }
34
- };
35
-
36
- export default () => {
37
- // data-wp-context
38
- directive(
39
- 'context',
40
- ( {
41
- directives: {
42
- context: { default: context },
43
- },
44
- props: { children },
45
- context: inherited,
46
- } ) => {
47
- const { Provider } = inherited;
48
- const inheritedValue = useContext( inherited );
49
- const value = useMemo( () => {
50
- const localValue = deepSignal( context );
51
- mergeDeepSignals( localValue, inheritedValue );
52
- return localValue;
53
- }, [ context, inheritedValue ] );
54
-
55
- return <Provider value={ value }>{ children }</Provider>;
56
- },
57
- { priority: 5 }
58
- );
59
-
60
- // data-wp-body
61
- directive( 'body', ( { props: { children }, context: inherited } ) => {
62
- const { Provider } = inherited;
63
- const inheritedValue = useContext( inherited );
64
- return createPortal(
65
- <Provider value={ inheritedValue }>{ children }</Provider>,
66
- document.body
67
- );
68
- } );
69
-
70
- // data-wp-effect--[name]
71
- directive( 'effect', ( { directives: { effect }, context, evaluate } ) => {
72
- const contextValue = useContext( context );
73
- Object.values( effect ).forEach( ( path ) => {
74
- useSignalEffect( () => {
75
- return evaluate( path, { context: contextValue } );
76
- } );
77
- } );
78
- } );
79
-
80
- // data-wp-init--[name]
81
- directive( 'init', ( { directives: { init }, context, evaluate } ) => {
82
- const contextValue = useContext( context );
83
- Object.values( init ).forEach( ( path ) => {
84
- useEffect( () => {
85
- return evaluate( path, { context: contextValue } );
86
- }, [] );
87
- } );
88
- } );
89
-
90
- // data-wp-on--[event]
91
- directive( 'on', ( { directives: { on }, element, evaluate, context } ) => {
92
- const contextValue = useContext( context );
93
- Object.entries( on ).forEach( ( [ name, path ] ) => {
94
- element.props[ `on${ name }` ] = ( event ) => {
95
- evaluate( path, { event, context: contextValue } );
96
- };
97
- } );
98
- } );
99
-
100
- // data-wp-class--[classname]
101
- directive(
102
- 'class',
103
- ( {
104
- directives: { class: className },
105
- element,
106
- evaluate,
107
- context,
108
- } ) => {
109
- const contextValue = useContext( context );
110
- Object.keys( className )
111
- .filter( ( n ) => n !== 'default' )
112
- .forEach( ( name ) => {
113
- const result = evaluate( className[ name ], {
114
- className: name,
115
- context: contextValue,
116
- } );
117
- const currentClass = element.props.class || '';
118
- const classFinder = new RegExp(
119
- `(^|\\s)${ name }(\\s|$)`,
120
- 'g'
121
- );
122
- if ( ! result )
123
- element.props.class = currentClass
124
- .replace( classFinder, ' ' )
125
- .trim();
126
- else if ( ! classFinder.test( currentClass ) )
127
- element.props.class = currentClass
128
- ? `${ currentClass } ${ name }`
129
- : name;
130
-
131
- useEffect( () => {
132
- // This seems necessary because Preact doesn't change the class
133
- // names on the hydration, so we have to do it manually. It doesn't
134
- // need deps because it only needs to do it the first time.
135
- if ( ! result ) {
136
- element.ref.current.classList.remove( name );
137
- } else {
138
- element.ref.current.classList.add( name );
139
- }
140
- }, [] );
141
- } );
142
- }
143
- );
144
-
145
- // data-wp-bind--[attribute]
146
- directive(
147
- 'bind',
148
- ( { directives: { bind }, element, context, evaluate } ) => {
149
- const contextValue = useContext( context );
150
- Object.entries( bind )
151
- .filter( ( n ) => n !== 'default' )
152
- .forEach( ( [ attribute, path ] ) => {
153
- const result = evaluate( path, {
154
- context: contextValue,
155
- } );
156
- element.props[ attribute ] = result;
157
-
158
- // This seems necessary because Preact doesn't change the attributes
159
- // on the hydration, so we have to do it manually. It doesn't need
160
- // deps because it only needs to do it the first time.
161
- useEffect( () => {
162
- // aria- and data- attributes have no boolean representation.
163
- // A `false` value is different from the attribute not being
164
- // present, so we can't remove it.
165
- // We follow Preact's logic: https://github.com/preactjs/preact/blob/ea49f7a0f9d1ff2c98c0bdd66aa0cbc583055246/src/diff/props.js#L131C24-L136
166
- if ( result === false && attribute[ 4 ] !== '-' ) {
167
- element.ref.current.removeAttribute( attribute );
168
- } else {
169
- element.ref.current.setAttribute(
170
- attribute,
171
- result === true && attribute[ 4 ] !== '-'
172
- ? ''
173
- : result
174
- );
175
- }
176
- }, [] );
177
- } );
178
- }
179
- );
180
-
181
- // data-wp-ignore
182
- directive(
183
- 'ignore',
184
- ( {
185
- element: {
186
- type: Type,
187
- props: { innerHTML, ...rest },
188
- },
189
- } ) => {
190
- // Preserve the initial inner HTML.
191
- const cached = useMemo( () => innerHTML, [] );
192
- return (
193
- <Type
194
- dangerouslySetInnerHTML={ { __html: cached } }
195
- { ...rest }
196
- />
197
- );
198
- }
199
- );
200
- };
@@ -1,145 +0,0 @@
1
- /**
2
- * External dependencies
3
- */
4
- import { h, options, createContext, cloneElement } from 'preact';
5
- import { useRef, useMemo } from 'preact/hooks';
6
- /**
7
- * Internal dependencies
8
- */
9
- import { rawStore as store } from './store';
10
-
11
- // Main context.
12
- const context = createContext( {} );
13
-
14
- // WordPress Directives.
15
- const directiveMap = {};
16
- const directivePriorities = {};
17
- export const directive = ( name, cb, { priority = 10 } = {} ) => {
18
- directiveMap[ name ] = cb;
19
- directivePriorities[ name ] = priority;
20
- };
21
-
22
- // Resolve the path to some property of the store object.
23
- const resolve = ( path, ctx ) => {
24
- let current = { ...store, context: ctx };
25
- path.split( '.' ).forEach( ( p ) => ( current = current[ p ] ) );
26
- return current;
27
- };
28
-
29
- // Generate the evaluate function.
30
- const getEvaluate =
31
- ( { ref } = {} ) =>
32
- ( path, extraArgs = {} ) => {
33
- // If path starts with !, remove it and save a flag.
34
- const hasNegationOperator =
35
- path[ 0 ] === '!' && !! ( path = path.slice( 1 ) );
36
- const value = resolve( path, extraArgs.context );
37
- const returnValue =
38
- typeof value === 'function'
39
- ? value( {
40
- ref: ref.current,
41
- ...store,
42
- ...extraArgs,
43
- } )
44
- : value;
45
- return hasNegationOperator ? ! returnValue : returnValue;
46
- };
47
-
48
- // Separate directives by priority. The resulting array contains objects
49
- // of directives grouped by same priority, and sorted in ascending order.
50
- const usePriorityLevels = ( directives ) =>
51
- useMemo( () => {
52
- const byPriority = Object.entries( directives ).reduce(
53
- ( acc, [ name, values ] ) => {
54
- const priority = directivePriorities[ name ];
55
- if ( ! acc[ priority ] ) acc[ priority ] = {};
56
- acc[ priority ][ name ] = values;
57
-
58
- return acc;
59
- },
60
- {}
61
- );
62
-
63
- return Object.entries( byPriority )
64
- .sort( ( [ p1 ], [ p2 ] ) => p1 - p2 )
65
- .map( ( [ , obj ] ) => obj );
66
- }, [ directives ] );
67
-
68
- // Directive wrapper.
69
- const Directive = ( { type, directives, props: originalProps } ) => {
70
- const ref = useRef( null );
71
- const element = h( type, { ...originalProps, ref } );
72
- const evaluate = useMemo( () => getEvaluate( { ref } ), [] );
73
-
74
- // Add wrappers recursively for each priority level.
75
- const byPriorityLevel = usePriorityLevels( directives );
76
- return (
77
- <RecursivePriorityLevel
78
- directives={ byPriorityLevel }
79
- element={ element }
80
- evaluate={ evaluate }
81
- originalProps={ originalProps }
82
- />
83
- );
84
- };
85
-
86
- // Priority level wrapper.
87
- const RecursivePriorityLevel = ( {
88
- directives: [ directives, ...rest ],
89
- element,
90
- evaluate,
91
- originalProps,
92
- } ) => {
93
- // This element needs to be a fresh copy so we are not modifying an already
94
- // rendered element with Preact's internal properties initialized. This
95
- // prevents an error with changes in `element.props.children` not being
96
- // reflected in `element.__k`.
97
- element = cloneElement( element );
98
-
99
- // Recursively render the wrapper for the next priority level.
100
- //
101
- // Note that, even though we're instantiating a vnode with a
102
- // `RecursivePriorityLevel` here, its render function will not be executed
103
- // just yet. Actually, it will be delayed until the current render function
104
- // has finished. That ensures directives in the current priorty level have
105
- // run (and thus modified the passed `element`) before the next level.
106
- const children =
107
- rest.length > 0 ? (
108
- <RecursivePriorityLevel
109
- directives={ rest }
110
- element={ element }
111
- evaluate={ evaluate }
112
- originalProps={ originalProps }
113
- />
114
- ) : (
115
- element
116
- );
117
-
118
- const props = { ...originalProps, children };
119
- const directiveArgs = { directives, props, element, context, evaluate };
120
-
121
- for ( const d in directives ) {
122
- const wrapper = directiveMap[ d ]?.( directiveArgs );
123
- if ( wrapper !== undefined ) props.children = wrapper;
124
- }
125
-
126
- return props.children;
127
- };
128
-
129
- // Preact Options Hook called each time a vnode is created.
130
- const old = options.vnode;
131
- options.vnode = ( vnode ) => {
132
- if ( vnode.props.__directives ) {
133
- const props = vnode.props;
134
- const directives = props.__directives;
135
- delete props.__directives;
136
- vnode.props = {
137
- type: vnode.type,
138
- directives,
139
- props,
140
- };
141
- vnode.type = Directive;
142
- }
143
-
144
- if ( old ) old( vnode );
145
- };
@@ -1,22 +0,0 @@
1
- /**
2
- * External dependencies
3
- */
4
- import { hydrate } from 'preact';
5
- /**
6
- * Internal dependencies
7
- */
8
- import { toVdom, hydratedIslands } from './vdom';
9
- import { createRootFragment } from './utils';
10
- import { directivePrefix } from './constants';
11
-
12
- export const init = async () => {
13
- document
14
- .querySelectorAll( `[data-${ directivePrefix }-interactive]` )
15
- .forEach( ( node ) => {
16
- if ( ! hydratedIslands.has( node ) ) {
17
- const fragment = createRootFragment( node.parentNode, node );
18
- const vdom = toVdom( node );
19
- hydrate( vdom, fragment );
20
- }
21
- } );
22
- };
@@ -1,15 +0,0 @@
1
- /**
2
- * Internal dependencies
3
- */
4
- import registerDirectives from './directives';
5
- import { init } from './hydration';
6
- export { store } from './store';
7
-
8
- /**
9
- * Initialize the Interactivity API.
10
- */
11
- registerDirectives();
12
-
13
- document.addEventListener( 'DOMContentLoaded', async () => {
14
- await init();
15
- } );
@@ -1,98 +0,0 @@
1
- /**
2
- * External dependencies
3
- */
4
- import { createElement, render } from 'preact';
5
-
6
- /**
7
- * @param {import('../../src/index').RenderableProps<{ context: any }>} props
8
- */
9
- function ContextProvider( props ) {
10
- this.getChildContext = () => props.context;
11
- return props.children;
12
- }
13
-
14
- /**
15
- * Portal component
16
- *
17
- * @this {import('./internal').Component}
18
- * @param {object | null | undefined} props
19
- *
20
- * TODO: use createRoot() instead of fake root
21
- */
22
- function Portal( props ) {
23
- const _this = this;
24
- const container = props._container;
25
-
26
- _this.componentWillUnmount = function () {
27
- render( null, _this._temp );
28
- _this._temp = null;
29
- _this._container = null;
30
- };
31
-
32
- // When we change container we should clear our old container and
33
- // indicate a new mount.
34
- if ( _this._container && _this._container !== container ) {
35
- _this.componentWillUnmount();
36
- }
37
-
38
- // When props.vnode is undefined/false/null we are dealing with some kind of
39
- // conditional vnode. This should not trigger a render.
40
- if ( props._vnode ) {
41
- if ( ! _this._temp ) {
42
- _this._container = container;
43
-
44
- // Create a fake DOM parent node that manages a subset of `container`'s children:
45
- _this._temp = {
46
- nodeType: 1,
47
- parentNode: container,
48
- childNodes: [],
49
- appendChild( child ) {
50
- this.childNodes.push( child );
51
- _this._container.appendChild( child );
52
- },
53
- insertBefore( child ) {
54
- this.childNodes.push( child );
55
- _this._container.appendChild( child );
56
- },
57
- removeChild( child ) {
58
- this.childNodes.splice(
59
- // eslint-disable-next-line no-bitwise
60
- this.childNodes.indexOf( child ) >>> 1,
61
- 1
62
- );
63
- _this._container.removeChild( child );
64
- },
65
- };
66
- }
67
-
68
- // Render our wrapping element into temp.
69
- render(
70
- createElement(
71
- ContextProvider,
72
- { context: _this.context },
73
- props._vnode
74
- ),
75
- _this._temp
76
- );
77
- }
78
- // When we come from a conditional render, on a mounted
79
- // portal we should clear the DOM.
80
- else if ( _this._temp ) {
81
- _this.componentWillUnmount();
82
- }
83
- }
84
-
85
- /**
86
- * Create a `Portal` to continue rendering the vnode tree at a different DOM node
87
- *
88
- * @param {import('./internal').VNode} vnode The vnode to render
89
- * @param {import('./internal').PreactElement} container The DOM node to continue rendering in to.
90
- */
91
- export function createPortal( vnode, container ) {
92
- const el = createElement( Portal, {
93
- _vnode: vnode,
94
- _container: container,
95
- } );
96
- el.containerInfo = container;
97
- return el;
98
- }
@@ -1,45 +0,0 @@
1
- /**
2
- * External dependencies
3
- */
4
- import { deepSignal } from 'deepsignal';
5
-
6
- const isObject = ( item ) =>
7
- item && typeof item === 'object' && ! Array.isArray( item );
8
-
9
- const deepMerge = ( target, source ) => {
10
- if ( isObject( target ) && isObject( source ) ) {
11
- for ( const key in source ) {
12
- if ( isObject( source[ key ] ) ) {
13
- if ( ! target[ key ] ) Object.assign( target, { [ key ]: {} } );
14
- deepMerge( target[ key ], source[ key ] );
15
- } else {
16
- Object.assign( target, { [ key ]: source[ key ] } );
17
- }
18
- }
19
- }
20
- };
21
-
22
- const getSerializedState = () => {
23
- // TODO: change the store tag ID for a better one.
24
- const storeTag = document.querySelector(
25
- `script[type="application/json"]#store`
26
- );
27
- if ( ! storeTag ) return {};
28
- try {
29
- const { state } = JSON.parse( storeTag.textContent );
30
- if ( isObject( state ) ) return state;
31
- throw Error( 'Parsed state is not an object' );
32
- } catch ( e ) {
33
- // eslint-disable-next-line no-console
34
- console.log( e );
35
- }
36
- return {};
37
- };
38
-
39
- const rawState = getSerializedState();
40
- export const rawStore = { state: deepSignal( rawState ) };
41
-
42
- export const store = ( { state, ...block } ) => {
43
- deepMerge( rawStore, block );
44
- deepMerge( rawState, state );
45
- };
@@ -1,66 +0,0 @@
1
- /**
2
- * External dependencies
3
- */
4
- import { useRef, useEffect } from 'preact/hooks';
5
- import { effect } from '@preact/signals';
6
-
7
- function afterNextFrame( callback ) {
8
- const done = () => {
9
- window.cancelAnimationFrame( raf );
10
- setTimeout( callback );
11
- };
12
- const raf = window.requestAnimationFrame( done );
13
- }
14
-
15
- // Using the mangled properties:
16
- // this.c: this._callback
17
- // this.x: this._compute
18
- // https://github.com/preactjs/signals/blob/main/mangle.json
19
- function createFlusher( compute, notify ) {
20
- let flush;
21
- const dispose = effect( function () {
22
- flush = this.c.bind( this );
23
- this.x = compute;
24
- this.c = notify;
25
- return compute();
26
- } );
27
- return { flush, dispose };
28
- }
29
-
30
- // Version of `useSignalEffect` with a `useEffect`-like execution. This hook
31
- // implementation comes from this PR:
32
- // https://github.com/preactjs/signals/pull/290.
33
- //
34
- // We need to include it here in this repo until the mentioned PR is merged.
35
- export function useSignalEffect( cb ) {
36
- const callback = useRef( cb );
37
- callback.current = cb;
38
-
39
- useEffect( () => {
40
- const execute = () => callback.current();
41
- const notify = () => afterNextFrame( eff.flush );
42
- const eff = createFlusher( execute, notify );
43
- return eff.dispose;
44
- }, [] );
45
- }
46
-
47
- // For wrapperless hydration.
48
- // See https://gist.github.com/developit/f4c67a2ede71dc2fab7f357f39cff28c
49
- export const createRootFragment = ( parent, replaceNode ) => {
50
- replaceNode = [].concat( replaceNode );
51
- const s = replaceNode[ replaceNode.length - 1 ].nextSibling;
52
- function insert( c, r ) {
53
- parent.insertBefore( c, r || s );
54
- }
55
- return ( parent.__k = {
56
- nodeType: 1,
57
- parentNode: parent,
58
- firstChild: replaceNode[ 0 ],
59
- childNodes: replaceNode,
60
- insertBefore: insert,
61
- appendChild: insert,
62
- removeChild( c ) {
63
- parent.removeChild( c );
64
- },
65
- } );
66
- };
@@ -1,111 +0,0 @@
1
- /**
2
- * External dependencies
3
- */
4
- import { h } from 'preact';
5
- /**
6
- * Internal dependencies
7
- */
8
- import { directivePrefix as p } from './constants';
9
-
10
- const ignoreAttr = `data-${ p }-ignore`;
11
- const islandAttr = `data-${ p }-interactive`;
12
- const fullPrefix = `data-${ p }-`;
13
-
14
- // Regular expression for directive parsing.
15
- const directiveParser = new RegExp(
16
- `^data-${ p }-` + // ${p} must be a prefix string, like 'wp'.
17
- // Match alphanumeric characters including hyphen-separated
18
- // segments. It excludes underscore intentionally to prevent confusion.
19
- // E.g., "custom-directive".
20
- '([a-z0-9]+(?:-[a-z0-9]+)*)' +
21
- // (Optional) Match '--' followed by any alphanumeric charachters. It
22
- // excludes underscore intentionally to prevent confusion, but it can
23
- // contain multiple hyphens. E.g., "--custom-prefix--with-more-info".
24
- '(?:--([a-z0-9][a-z0-9-]+))?$',
25
- 'i' // Case insensitive.
26
- );
27
-
28
- export const hydratedIslands = new WeakSet();
29
-
30
- // Recursive function that transforms a DOM tree into vDOM.
31
- export function toVdom( root ) {
32
- const treeWalker = document.createTreeWalker(
33
- root,
34
- 205 // ELEMENT + TEXT + COMMENT + CDATA_SECTION + PROCESSING_INSTRUCTION
35
- );
36
-
37
- function walk( node ) {
38
- const { attributes, nodeType } = node;
39
-
40
- if ( nodeType === 3 ) return [ node.data ];
41
- if ( nodeType === 4 ) {
42
- const next = treeWalker.nextSibling();
43
- node.replaceWith( new window.Text( node.nodeValue ) );
44
- return [ node.nodeValue, next ];
45
- }
46
- if ( nodeType === 8 || nodeType === 7 ) {
47
- const next = treeWalker.nextSibling();
48
- node.remove();
49
- return [ null, next ];
50
- }
51
-
52
- const props = {};
53
- const children = [];
54
- const directives = {};
55
- let hasDirectives = false;
56
- let ignore = false;
57
- let island = false;
58
-
59
- for ( let i = 0; i < attributes.length; i++ ) {
60
- const n = attributes[ i ].name;
61
- if (
62
- n[ fullPrefix.length ] &&
63
- n.slice( 0, fullPrefix.length ) === fullPrefix
64
- ) {
65
- if ( n === ignoreAttr ) {
66
- ignore = true;
67
- } else if ( n === islandAttr ) {
68
- island = true;
69
- } else {
70
- hasDirectives = true;
71
- let val = attributes[ i ].value;
72
- try {
73
- val = JSON.parse( val );
74
- } catch ( e ) {}
75
- const [ , prefix, suffix ] = directiveParser.exec( n );
76
- directives[ prefix ] = directives[ prefix ] || {};
77
- directives[ prefix ][ suffix || 'default' ] = val;
78
- }
79
- } else if ( n === 'ref' ) {
80
- continue;
81
- }
82
- props[ n ] = attributes[ i ].value;
83
- }
84
-
85
- if ( ignore && ! island )
86
- return [
87
- h( node.localName, {
88
- ...props,
89
- innerHTML: node.innerHTML,
90
- __directives: { ignore: true },
91
- } ),
92
- ];
93
- if ( island ) hydratedIslands.add( node );
94
-
95
- if ( hasDirectives ) props.__directives = directives;
96
-
97
- let child = treeWalker.firstChild();
98
- if ( child ) {
99
- while ( child ) {
100
- const [ vnode, nextChild ] = walk( child );
101
- if ( vnode ) children.push( vnode );
102
- child = nextChild || treeWalker.nextSibling();
103
- }
104
- treeWalker.parentNode();
105
- }
106
-
107
- return [ h( node.localName, props, children ) ];
108
- }
109
-
110
- return walk( treeWalker.currentNode );
111
- }