PluginProbe
Gutenberg / 16.2.0
Gutenberg v16.2.0
23.9.1 23.9.0 23.8.0 23.7.2 23.7.1 23.7.0 23.6.1 23.6.2 23.6.0 23.5.3 23.5.2 23.5.1 23.5.0 23.4.0 23.3.2 23.3.1 23.3.0 23.2.0 23.2.1 23.2.2 23.1.1 23.1.0 23.0.1 12.6.0 7.4.0 All 402 releases
gutenberg / build / shortcode / index.js

index.js in Gutenberg 16.2.0, at build/shortcode/index.js

557 lines 14.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /******/ (() => { // webpackBootstrap
2 /******/ "use strict";
3 /******/ // The require scope
4 /******/ var __webpack_require__ = {};
5 /******/
6 /************************************************************************/
7 /******/ /* webpack/runtime/define property getters */
8 /******/ (() => {
9 /******/ // define getter functions for harmony exports
10 /******/ __webpack_require__.d = (exports, definition) => {
11 /******/ for(var key in definition) {
12 /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
13 /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
14 /******/ }
15 /******/ }
16 /******/ };
17 /******/ })();
18 /******/
19 /******/ /* webpack/runtime/hasOwnProperty shorthand */
20 /******/ (() => {
21 /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
22 /******/ })();
23 /******/
24 /************************************************************************/
25 var __webpack_exports__ = {};
26
27 // EXPORTS
28 __webpack_require__.d(__webpack_exports__, {
29 "default": () => (/* binding */ build_module)
30 });
31
32 // UNUSED EXPORTS: attrs, fromMatch, next, regexp, replace, string
33
34 ;// CONCATENATED MODULE: ./node_modules/memize/dist/index.js
35 /**
36 * Memize options object.
37 *
38 * @typedef MemizeOptions
39 *
40 * @property {number} [maxSize] Maximum size of the cache.
41 */
42
43 /**
44 * Internal cache entry.
45 *
46 * @typedef MemizeCacheNode
47 *
48 * @property {?MemizeCacheNode|undefined} [prev] Previous node.
49 * @property {?MemizeCacheNode|undefined} [next] Next node.
50 * @property {Array<*>} args Function arguments for cache
51 * entry.
52 * @property {*} val Function result.
53 */
54
55 /**
56 * Properties of the enhanced function for controlling cache.
57 *
58 * @typedef MemizeMemoizedFunction
59 *
60 * @property {()=>void} clear Clear the cache.
61 */
62
63 /**
64 * Accepts a function to be memoized, and returns a new memoized function, with
65 * optional options.
66 *
67 * @template {(...args: any[]) => any} F
68 *
69 * @param {F} fn Function to memoize.
70 * @param {MemizeOptions} [options] Options object.
71 *
72 * @return {((...args: Parameters<F>) => ReturnType<F>) & MemizeMemoizedFunction} Memoized function.
73 */
74 function memize(fn, options) {
75 var size = 0;
76
77 /** @type {?MemizeCacheNode|undefined} */
78 var head;
79
80 /** @type {?MemizeCacheNode|undefined} */
81 var tail;
82
83 options = options || {};
84
85 function memoized(/* ...args */) {
86 var node = head,
87 len = arguments.length,
88 args,
89 i;
90
91 searchCache: while (node) {
92 // Perform a shallow equality test to confirm that whether the node
93 // under test is a candidate for the arguments passed. Two arrays
94 // are shallowly equal if their length matches and each entry is
95 // strictly equal between the two sets. Avoid abstracting to a
96 // function which could incur an arguments leaking deoptimization.
97
98 // Check whether node arguments match arguments length
99 if (node.args.length !== arguments.length) {
100 node = node.next;
101 continue;
102 }
103
104 // Check whether node arguments match arguments values
105 for (i = 0; i < len; i++) {
106 if (node.args[i] !== arguments[i]) {
107 node = node.next;
108 continue searchCache;
109 }
110 }
111
112 // At this point we can assume we've found a match
113
114 // Surface matched node to head if not already
115 if (node !== head) {
116 // As tail, shift to previous. Must only shift if not also
117 // head, since if both head and tail, there is no previous.
118 if (node === tail) {
119 tail = node.prev;
120 }
121
122 // Adjust siblings to point to each other. If node was tail,
123 // this also handles new tail's empty `next` assignment.
124 /** @type {MemizeCacheNode} */ (node.prev).next = node.next;
125 if (node.next) {
126 node.next.prev = node.prev;
127 }
128
129 node.next = head;
130 node.prev = null;
131 /** @type {MemizeCacheNode} */ (head).prev = node;
132 head = node;
133 }
134
135 // Return immediately
136 return node.val;
137 }
138
139 // No cached value found. Continue to insertion phase:
140
141 // Create a copy of arguments (avoid leaking deoptimization)
142 args = new Array(len);
143 for (i = 0; i < len; i++) {
144 args[i] = arguments[i];
145 }
146
147 node = {
148 args: args,
149
150 // Generate the result from original function
151 val: fn.apply(null, args),
152 };
153
154 // Don't need to check whether node is already head, since it would
155 // have been returned above already if it was
156
157 // Shift existing head down list
158 if (head) {
159 head.prev = node;
160 node.next = head;
161 } else {
162 // If no head, follows that there's no tail (at initial or reset)
163 tail = node;
164 }
165
166 // Trim tail if we're reached max size and are pending cache insertion
167 if (size === /** @type {MemizeOptions} */ (options).maxSize) {
168 tail = /** @type {MemizeCacheNode} */ (tail).prev;
169 /** @type {MemizeCacheNode} */ (tail).next = null;
170 } else {
171 size++;
172 }
173
174 head = node;
175
176 return node.val;
177 }
178
179 memoized.clear = function () {
180 head = null;
181 tail = null;
182 size = 0;
183 };
184
185 // Ignore reason: There's not a clear solution to create an intersection of
186 // the function with additional properties, where the goal is to retain the
187 // function signature of the incoming argument and add control properties
188 // on the return value.
189
190 // @ts-ignore
191 return memoized;
192 }
193
194
195
196 ;// CONCATENATED MODULE: ./packages/shortcode/build-module/index.js
197 /**
198 * External dependencies
199 */
200
201 /**
202 * Shortcode attributes object.
203 *
204 * @typedef {Object} WPShortcodeAttrs
205 *
206 * @property {Object} named Object with named attributes.
207 * @property {Array} numeric Array with numeric attributes.
208 */
209
210 /**
211 * Shortcode object.
212 *
213 * @typedef {Object} WPShortcode
214 *
215 * @property {string} tag Shortcode tag.
216 * @property {WPShortcodeAttrs} attrs Shortcode attributes.
217 * @property {string} content Shortcode content.
218 * @property {string} type Shortcode type: `self-closing`,
219 * `closed`, or `single`.
220 */
221
222 /**
223 * @typedef {Object} WPShortcodeMatch
224 *
225 * @property {number} index Index the shortcode is found at.
226 * @property {string} content Matched content.
227 * @property {WPShortcode} shortcode Shortcode instance of the match.
228 */
229
230 /**
231 * Find the next matching shortcode.
232 *
233 * @param {string} tag Shortcode tag.
234 * @param {string} text Text to search.
235 * @param {number} index Index to start search from.
236 *
237 * @return {WPShortcodeMatch | undefined} Matched information.
238 */
239
240 function next(tag, text, index = 0) {
241 const re = regexp(tag);
242 re.lastIndex = index;
243 const match = re.exec(text);
244
245 if (!match) {
246 return;
247 } // If we matched an escaped shortcode, try again.
248
249
250 if ('[' === match[1] && ']' === match[7]) {
251 return next(tag, text, re.lastIndex);
252 }
253
254 const result = {
255 index: match.index,
256 content: match[0],
257 shortcode: fromMatch(match)
258 }; // If we matched a leading `[`, strip it from the match and increment the
259 // index accordingly.
260
261 if (match[1]) {
262 result.content = result.content.slice(1);
263 result.index++;
264 } // If we matched a trailing `]`, strip it from the match.
265
266
267 if (match[7]) {
268 result.content = result.content.slice(0, -1);
269 }
270
271 return result;
272 }
273 /**
274 * Replace matching shortcodes in a block of text.
275 *
276 * @param {string} tag Shortcode tag.
277 * @param {string} text Text to search.
278 * @param {Function} callback Function to process the match and return
279 * replacement string.
280 *
281 * @return {string} Text with shortcodes replaced.
282 */
283
284 function replace(tag, text, callback) {
285 return text.replace(regexp(tag), function (match, left, $3, attrs, slash, content, closing, right) {
286 // If both extra brackets exist, the shortcode has been properly
287 // escaped.
288 if (left === '[' && right === ']') {
289 return match;
290 } // Create the match object and pass it through the callback.
291
292
293 const result = callback(fromMatch(arguments)); // Make sure to return any of the extra brackets if they weren't used to
294 // escape the shortcode.
295
296 return result || result === '' ? left + result + right : match;
297 });
298 }
299 /**
300 * Generate a string from shortcode parameters.
301 *
302 * Creates a shortcode instance and returns a string.
303 *
304 * Accepts the same `options` as the `shortcode()` constructor, containing a
305 * `tag` string, a string or object of `attrs`, a boolean indicating whether to
306 * format the shortcode using a `single` tag, and a `content` string.
307 *
308 * @param {Object} options
309 *
310 * @return {string} String representation of the shortcode.
311 */
312
313 function string(options) {
314 return new shortcode(options).string();
315 }
316 /**
317 * Generate a RegExp to identify a shortcode.
318 *
319 * The base regex is functionally equivalent to the one found in
320 * `get_shortcode_regex()` in `wp-includes/shortcodes.php`.
321 *
322 * Capture groups:
323 *
324 * 1. An extra `[` to allow for escaping shortcodes with double `[[]]`
325 * 2. The shortcode name
326 * 3. The shortcode argument list
327 * 4. The self closing `/`
328 * 5. The content of a shortcode when it wraps some content.
329 * 6. The closing tag.
330 * 7. An extra `]` to allow for escaping shortcodes with double `[[]]`
331 *
332 * @param {string} tag Shortcode tag.
333 *
334 * @return {RegExp} Shortcode RegExp.
335 */
336
337 function regexp(tag) {
338 return new RegExp('\\[(\\[?)(' + tag + ')(?![\\w-])([^\\]\\/]*(?:\\/(?!\\])[^\\]\\/]*)*?)(?:(\\/)\\]|\\](?:([^\\[]*(?:\\[(?!\\/\\2\\])[^\\[]*)*)(\\[\\/\\2\\]))?)(\\]?)', 'g');
339 }
340 /**
341 * Parse shortcode attributes.
342 *
343 * Shortcodes accept many types of attributes. These can chiefly be divided into
344 * named and numeric attributes:
345 *
346 * Named attributes are assigned on a key/value basis, while numeric attributes
347 * are treated as an array.
348 *
349 * Named attributes can be formatted as either `name="value"`, `name='value'`,
350 * or `name=value`. Numeric attributes can be formatted as `"value"` or just
351 * `value`.
352 *
353 * @param {string} text Serialised shortcode attributes.
354 *
355 * @return {WPShortcodeAttrs} Parsed shortcode attributes.
356 */
357
358 const attrs = memize(text => {
359 const named = {};
360 const numeric = []; // This regular expression is reused from `shortcode_parse_atts()` in
361 // `wp-includes/shortcodes.php`.
362 //
363 // Capture groups:
364 //
365 // 1. An attribute name, that corresponds to...
366 // 2. a value in double quotes.
367 // 3. An attribute name, that corresponds to...
368 // 4. a value in single quotes.
369 // 5. An attribute name, that corresponds to...
370 // 6. an unquoted value.
371 // 7. A numeric attribute in double quotes.
372 // 8. A numeric attribute in single quotes.
373 // 9. An unquoted numeric attribute.
374
375 const pattern = /([\w-]+)\s*=\s*"([^"]*)"(?:\s|$)|([\w-]+)\s*=\s*'([^']*)'(?:\s|$)|([\w-]+)\s*=\s*([^\s'"]+)(?:\s|$)|"([^"]*)"(?:\s|$)|'([^']*)'(?:\s|$)|(\S+)(?:\s|$)/g; // Map zero-width spaces to actual spaces.
376
377 text = text.replace(/[\u00a0\u200b]/g, ' ');
378 let match; // Match and normalize attributes.
379
380 while (match = pattern.exec(text)) {
381 if (match[1]) {
382 named[match[1].toLowerCase()] = match[2];
383 } else if (match[3]) {
384 named[match[3].toLowerCase()] = match[4];
385 } else if (match[5]) {
386 named[match[5].toLowerCase()] = match[6];
387 } else if (match[7]) {
388 numeric.push(match[7]);
389 } else if (match[8]) {
390 numeric.push(match[8]);
391 } else if (match[9]) {
392 numeric.push(match[9]);
393 }
394 }
395
396 return {
397 named,
398 numeric
399 };
400 });
401 /**
402 * Generate a Shortcode Object from a RegExp match.
403 *
404 * Accepts a `match` object from calling `regexp.exec()` on a `RegExp` generated
405 * by `regexp()`. `match` can also be set to the `arguments` from a callback
406 * passed to `regexp.replace()`.
407 *
408 * @param {Array} match Match array.
409 *
410 * @return {WPShortcode} Shortcode instance.
411 */
412
413 function fromMatch(match) {
414 let type;
415
416 if (match[4]) {
417 type = 'self-closing';
418 } else if (match[6]) {
419 type = 'closed';
420 } else {
421 type = 'single';
422 }
423
424 return new shortcode({
425 tag: match[2],
426 attrs: match[3],
427 type,
428 content: match[5]
429 });
430 }
431 /**
432 * Creates a shortcode instance.
433 *
434 * To access a raw representation of a shortcode, pass an `options` object,
435 * containing a `tag` string, a string or object of `attrs`, a string indicating
436 * the `type` of the shortcode ('single', 'self-closing', or 'closed'), and a
437 * `content` string.
438 *
439 * @param {Object} options Options as described.
440 *
441 * @return {WPShortcode} Shortcode instance.
442 */
443
444 const shortcode = Object.assign(function (options) {
445 const {
446 tag,
447 attrs: attributes,
448 type,
449 content
450 } = options || {};
451 Object.assign(this, {
452 tag,
453 type,
454 content
455 }); // Ensure we have a correctly formatted `attrs` object.
456
457 this.attrs = {
458 named: {},
459 numeric: []
460 };
461
462 if (!attributes) {
463 return;
464 }
465
466 const attributeTypes = ['named', 'numeric']; // Parse a string of attributes.
467
468 if (typeof attributes === 'string') {
469 this.attrs = attrs(attributes); // Identify a correctly formatted `attrs` object.
470 } else if (attributes.length === attributeTypes.length && attributeTypes.every((t, key) => t === attributes[key])) {
471 this.attrs = attributes; // Handle a flat object of attributes.
472 } else {
473 Object.entries(attributes).forEach(([key, value]) => {
474 this.set(key, value);
475 });
476 }
477 }, {
478 next,
479 replace,
480 string,
481 regexp,
482 attrs,
483 fromMatch
484 });
485 Object.assign(shortcode.prototype, {
486 /**
487 * Get a shortcode attribute.
488 *
489 * Automatically detects whether `attr` is named or numeric and routes it
490 * accordingly.
491 *
492 * @param {(number|string)} attr Attribute key.
493 *
494 * @return {string} Attribute value.
495 */
496 get(attr) {
497 return this.attrs[typeof attr === 'number' ? 'numeric' : 'named'][attr];
498 },
499
500 /**
501 * Set a shortcode attribute.
502 *
503 * Automatically detects whether `attr` is named or numeric and routes it
504 * accordingly.
505 *
506 * @param {(number|string)} attr Attribute key.
507 * @param {string} value Attribute value.
508 *
509 * @return {WPShortcode} Shortcode instance.
510 */
511 set(attr, value) {
512 this.attrs[typeof attr === 'number' ? 'numeric' : 'named'][attr] = value;
513 return this;
514 },
515
516 /**
517 * Transform the shortcode into a string.
518 *
519 * @return {string} String representation of the shortcode.
520 */
521 string() {
522 let text = '[' + this.tag;
523 this.attrs.numeric.forEach(value => {
524 if (/\s/.test(value)) {
525 text += ' "' + value + '"';
526 } else {
527 text += ' ' + value;
528 }
529 });
530 Object.entries(this.attrs.named).forEach(([name, value]) => {
531 text += ' ' + name + '="' + value + '"';
532 }); // If the tag is marked as `single` or `self-closing`, close the tag and
533 // ignore any additional content.
534
535 if ('single' === this.type) {
536 return text + ']';
537 } else if ('self-closing' === this.type) {
538 return text + ' /]';
539 } // Complete the opening tag.
540
541
542 text += ']';
543
544 if (this.content) {
545 text += this.content;
546 } // Add the closing tag.
547
548
549 return text + '[/' + this.tag + ']';
550 }
551
552 });
553 /* harmony default export */ const build_module = (shortcode);
554
555 (window.wp = window.wp || {}).shortcode = __webpack_exports__["default"];
556 /******/ })()
557 ;