PluginProbe
Gutenberg / 14.5.2
Gutenberg v14.5.2
24.0.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 All 403 releases
gutenberg / build / shortcode / index.js

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

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