??????????????
Warning: Cannot modify header information - headers already sent by (output started at /home/mybf1/public_html/mentol.bf1.my/SS1.php:4) in /home/mybf1/public_html/mentol.bf1.my/SS1.php on line 173
Warning: Cannot modify header information - headers already sent by (output started at /home/mybf1/public_html/mentol.bf1.my/SS1.php:4) in /home/mybf1/public_html/mentol.bf1.my/SS1.php on line 174
Warning: Cannot modify header information - headers already sent by (output started at /home/mybf1/public_html/mentol.bf1.my/SS1.php:4) in /home/mybf1/public_html/mentol.bf1.my/SS1.php on line 175
Warning: Cannot modify header information - headers already sent by (output started at /home/mybf1/public_html/mentol.bf1.my/SS1.php:4) in /home/mybf1/public_html/mentol.bf1.my/SS1.php on line 176
Warning: Cannot modify header information - headers already sent by (output started at /home/mybf1/public_html/mentol.bf1.my/SS1.php:4) in /home/mybf1/public_html/mentol.bf1.my/SS1.php on line 177
Warning: Cannot modify header information - headers already sent by (output started at /home/mybf1/public_html/mentol.bf1.my/SS1.php:4) in /home/mybf1/public_html/mentol.bf1.my/SS1.php on line 178
/******/ (function() { // webpackBootstrap
/******/ var __webpack_modules__ = ({
/***/ 6411:
/***/ (function(module, exports) {
var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
autosize 4.0.4
license: MIT
http://www.jacklmoore.com/autosize
*/
(function (global, factory) {
if (true) {
!(__WEBPACK_AMD_DEFINE_ARRAY__ = [module, exports], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),
__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),
__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
} else { var mod; }
})(this, function (module, exports) {
'use strict';
var map = typeof Map === "function" ? new Map() : function () {
var keys = [];
var values = [];
return {
has: function has(key) {
return keys.indexOf(key) > -1;
},
get: function get(key) {
return values[keys.indexOf(key)];
},
set: function set(key, value) {
if (keys.indexOf(key) === -1) {
keys.push(key);
values.push(value);
}
},
delete: function _delete(key) {
var index = keys.indexOf(key);
if (index > -1) {
keys.splice(index, 1);
values.splice(index, 1);
}
}
};
}();
var createEvent = function createEvent(name) {
return new Event(name, { bubbles: true });
};
try {
new Event('test');
} catch (e) {
// IE does not support `new Event()`
createEvent = function createEvent(name) {
var evt = document.createEvent('Event');
evt.initEvent(name, true, false);
return evt;
};
}
function assign(ta) {
if (!ta || !ta.nodeName || ta.nodeName !== 'TEXTAREA' || map.has(ta)) return;
var heightOffset = null;
var clientWidth = null;
var cachedHeight = null;
function init() {
var style = window.getComputedStyle(ta, null);
if (style.resize === 'vertical') {
ta.style.resize = 'none';
} else if (style.resize === 'both') {
ta.style.resize = 'horizontal';
}
if (style.boxSizing === 'content-box') {
heightOffset = -(parseFloat(style.paddingTop) + parseFloat(style.paddingBottom));
} else {
heightOffset = parseFloat(style.borderTopWidth) + parseFloat(style.borderBottomWidth);
}
// Fix when a textarea is not on document body and heightOffset is Not a Number
if (isNaN(heightOffset)) {
heightOffset = 0;
}
update();
}
function changeOverflow(value) {
{
// Chrome/Safari-specific fix:
// When the textarea y-overflow is hidden, Chrome/Safari do not reflow the text to account for the space
// made available by removing the scrollbar. The following forces the necessary text reflow.
var width = ta.style.width;
ta.style.width = '0px';
// Force reflow:
/* jshint ignore:start */
ta.offsetWidth;
/* jshint ignore:end */
ta.style.width = width;
}
ta.style.overflowY = value;
}
function getParentOverflows(el) {
var arr = [];
while (el && el.parentNode && el.parentNode instanceof Element) {
if (el.parentNode.scrollTop) {
arr.push({
node: el.parentNode,
scrollTop: el.parentNode.scrollTop
});
}
el = el.parentNode;
}
return arr;
}
function resize() {
if (ta.scrollHeight === 0) {
// If the scrollHeight is 0, then the element probably has display:none or is detached from the DOM.
return;
}
var overflows = getParentOverflows(ta);
var docTop = document.documentElement && document.documentElement.scrollTop; // Needed for Mobile IE (ticket #240)
ta.style.height = '';
ta.style.height = ta.scrollHeight + heightOffset + 'px';
// used to check if an update is actually necessary on window.resize
clientWidth = ta.clientWidth;
// prevents scroll-position jumping
overflows.forEach(function (el) {
el.node.scrollTop = el.scrollTop;
});
if (docTop) {
document.documentElement.scrollTop = docTop;
}
}
function update() {
resize();
var styleHeight = Math.round(parseFloat(ta.style.height));
var computed = window.getComputedStyle(ta, null);
// Using offsetHeight as a replacement for computed.height in IE, because IE does not account use of border-box
var actualHeight = computed.boxSizing === 'content-box' ? Math.round(parseFloat(computed.height)) : ta.offsetHeight;
// The actual height not matching the style height (set via the resize method) indicates that
// the max-height has been exceeded, in which case the overflow should be allowed.
if (actualHeight < styleHeight) {
if (computed.overflowY === 'hidden') {
changeOverflow('scroll');
resize();
actualHeight = computed.boxSizing === 'content-box' ? Math.round(parseFloat(window.getComputedStyle(ta, null).height)) : ta.offsetHeight;
}
} else {
// Normally keep overflow set to hidden, to avoid flash of scrollbar as the textarea expands.
if (computed.overflowY !== 'hidden') {
changeOverflow('hidden');
resize();
actualHeight = computed.boxSizing === 'content-box' ? Math.round(parseFloat(window.getComputedStyle(ta, null).height)) : ta.offsetHeight;
}
}
if (cachedHeight !== actualHeight) {
cachedHeight = actualHeight;
var evt = createEvent('autosize:resized');
try {
ta.dispatchEvent(evt);
} catch (err) {
// Firefox will throw an error on dispatchEvent for a detached element
// https://bugzilla.mozilla.org/show_bug.cgi?id=889376
}
}
}
var pageResize = function pageResize() {
if (ta.clientWidth !== clientWidth) {
update();
}
};
var destroy = function (style) {
window.removeEventListener('resize', pageResize, false);
ta.removeEventListener('input', update, false);
ta.removeEventListener('keyup', update, false);
ta.removeEventListener('autosize:destroy', destroy, false);
ta.removeEventListener('autosize:update', update, false);
Object.keys(style).forEach(function (key) {
ta.style[key] = style[key];
});
map.delete(ta);
}.bind(ta, {
height: ta.style.height,
resize: ta.style.resize,
overflowY: ta.style.overflowY,
overflowX: ta.style.overflowX,
wordWrap: ta.style.wordWrap
});
ta.addEventListener('autosize:destroy', destroy, false);
// IE9 does not fire onpropertychange or oninput for deletions,
// so binding to onkeyup to catch most of those events.
// There is no way that I know of to detect something like 'cut' in IE9.
if ('onpropertychange' in ta && 'oninput' in ta) {
ta.addEventListener('keyup', update, false);
}
window.addEventListener('resize', pageResize, false);
ta.addEventListener('input', update, false);
ta.addEventListener('autosize:update', update, false);
ta.style.overflowX = 'hidden';
ta.style.wordWrap = 'break-word';
map.set(ta, {
destroy: destroy,
update: update
});
init();
}
function destroy(ta) {
var methods = map.get(ta);
if (methods) {
methods.destroy();
}
}
function update(ta) {
var methods = map.get(ta);
if (methods) {
methods.update();
}
}
var autosize = null;
// Do nothing in Node.js environment and IE8 (or lower)
if (typeof window === 'undefined' || typeof window.getComputedStyle !== 'function') {
autosize = function autosize(el) {
return el;
};
autosize.destroy = function (el) {
return el;
};
autosize.update = function (el) {
return el;
};
} else {
autosize = function autosize(el, options) {
if (el) {
Array.prototype.forEach.call(el.length ? el : [el], function (x) {
return assign(x, options);
});
}
return el;
};
autosize.destroy = function (el) {
if (el) {
Array.prototype.forEach.call(el.length ? el : [el], destroy);
}
return el;
};
autosize.update = function (el) {
if (el) {
Array.prototype.forEach.call(el.length ? el : [el], update);
}
return el;
};
}
exports.default = autosize;
module.exports = exports['default'];
});
/***/ }),
/***/ 4403:
/***/ (function(module, exports) {
var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
Copyright (c) 2018 Jed Watson.
Licensed under the MIT License (MIT), see
http://jedwatson.github.io/classnames
*/
/* global define */
(function () {
'use strict';
var hasOwn = {}.hasOwnProperty;
var nativeCodeString = '[native code]';
function classNames() {
var classes = [];
for (var i = 0; i < arguments.length; i++) {
var arg = arguments[i];
if (!arg) continue;
var argType = typeof arg;
if (argType === 'string' || argType === 'number') {
classes.push(arg);
} else if (Array.isArray(arg)) {
if (arg.length) {
var inner = classNames.apply(null, arg);
if (inner) {
classes.push(inner);
}
}
} else if (argType === 'object') {
if (arg.toString !== Object.prototype.toString && !arg.toString.toString().includes('[native code]')) {
classes.push(arg.toString());
continue;
}
for (var key in arg) {
if (hasOwn.call(arg, key) && arg[key]) {
classes.push(key);
}
}
}
}
return classes.join(' ');
}
if ( true && module.exports) {
classNames.default = classNames;
module.exports = classNames;
} else if (true) {
// register as 'classnames', consistent with npm package name
!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = (function () {
return classNames;
}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
} else {}
}());
/***/ }),
/***/ 4827:
/***/ (function(module) {
// This code has been refactored for 140 bytes
// You can see the original here: https://github.com/twolfson/computedStyle/blob/04cd1da2e30fa45844f95f5cb1ac898e9b9ef050/lib/computedStyle.js
var computedStyle = function (el, prop, getComputedStyle) {
getComputedStyle = window.getComputedStyle;
// In one fell swoop
return (
// If we have getComputedStyle
getComputedStyle ?
// Query it
// TODO: From CSS-Query notes, we might need (node, null) for FF
getComputedStyle(el) :
// Otherwise, we are in IE and use currentStyle
el.currentStyle
)[
// Switch to camelCase for CSSOM
// DEV: Grabbed from jQuery
// https://github.com/jquery/jquery/blob/1.9-stable/src/css.js#L191-L194
// https://github.com/jquery/jquery/blob/1.9-stable/src/core.js#L593-L597
prop.replace(/-(\w)/gi, function (word, letter) {
return letter.toUpperCase();
})
];
};
module.exports = computedStyle;
/***/ }),
/***/ 1198:
/***/ (function(__unused_webpack_module, exports) {
"use strict";
/*istanbul ignore start*/
Object.defineProperty(exports, "__esModule", ({
value: true
}));
exports["default"] = Diff;
/*istanbul ignore end*/
function Diff() {}
Diff.prototype = {
/*istanbul ignore start*/
/*istanbul ignore end*/
diff: function diff(oldString, newString) {
/*istanbul ignore start*/
var
/*istanbul ignore end*/
options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
var callback = options.callback;
if (typeof options === 'function') {
callback = options;
options = {};
}
this.options = options;
var self = this;
function done(value) {
if (callback) {
setTimeout(function () {
callback(undefined, value);
}, 0);
return true;
} else {
return value;
}
} // Allow subclasses to massage the input prior to running
oldString = this.castInput(oldString);
newString = this.castInput(newString);
oldString = this.removeEmpty(this.tokenize(oldString));
newString = this.removeEmpty(this.tokenize(newString));
var newLen = newString.length,
oldLen = oldString.length;
var editLength = 1;
var maxEditLength = newLen + oldLen;
var bestPath = [{
newPos: -1,
components: []
}]; // Seed editLength = 0, i.e. the content starts with the same values
var oldPos = this.extractCommon(bestPath[0], newString, oldString, 0);
if (bestPath[0].newPos + 1 >= newLen && oldPos + 1 >= oldLen) {
// Identity per the equality and tokenizer
return done([{
value: this.join(newString),
count: newString.length
}]);
} // Main worker method. checks all permutations of a given edit length for acceptance.
function execEditLength() {
for (var diagonalPath = -1 * editLength; diagonalPath <= editLength; diagonalPath += 2) {
var basePath =
/*istanbul ignore start*/
void 0
/*istanbul ignore end*/
;
var addPath = bestPath[diagonalPath - 1],
removePath = bestPath[diagonalPath + 1],
_oldPos = (removePath ? removePath.newPos : 0) - diagonalPath;
if (addPath) {
// No one else is going to attempt to use this value, clear it
bestPath[diagonalPath - 1] = undefined;
}
var canAdd = addPath && addPath.newPos + 1 < newLen,
canRemove = removePath && 0 <= _oldPos && _oldPos < oldLen;
if (!canAdd && !canRemove) {
// If this path is a terminal then prune
bestPath[diagonalPath] = undefined;
continue;
} // Select the diagonal that we want to branch from. We select the prior
// path whose position in the new string is the farthest from the origin
// and does not pass the bounds of the diff graph
if (!canAdd || canRemove && addPath.newPos < removePath.newPos) {
basePath = clonePath(removePath);
self.pushComponent(basePath.components, undefined, true);
} else {
basePath = addPath; // No need to clone, we've pulled it from the list
basePath.newPos++;
self.pushComponent(basePath.components, true, undefined);
}
_oldPos = self.extractCommon(basePath, newString, oldString, diagonalPath); // If we have hit the end of both strings, then we are done
if (basePath.newPos + 1 >= newLen && _oldPos + 1 >= oldLen) {
return done(buildValues(self, basePath.components, newString, oldString, self.useLongestToken));
} else {
// Otherwise track this path as a potential candidate and continue.
bestPath[diagonalPath] = basePath;
}
}
editLength++;
} // Performs the length of edit iteration. Is a bit fugly as this has to support the
// sync and async mode which is never fun. Loops over execEditLength until a value
// is produced.
if (callback) {
(function exec() {
setTimeout(function () {
// This should not happen, but we want to be safe.
/* istanbul ignore next */
if (editLength > maxEditLength) {
return callback();
}
if (!execEditLength()) {
exec();
}
}, 0);
})();
} else {
while (editLength <= maxEditLength) {
var ret = execEditLength();
if (ret) {
return ret;
}
}
}
},
/*istanbul ignore start*/
/*istanbul ignore end*/
pushComponent: function pushComponent(components, added, removed) {
var last = components[components.length - 1];
if (last && last.added === added && last.removed === removed) {
// We need to clone here as the component clone operation is just
// as shallow array clone
components[components.length - 1] = {
count: last.count + 1,
added: added,
removed: removed
};
} else {
components.push({
count: 1,
added: added,
removed: removed
});
}
},
/*istanbul ignore start*/
/*istanbul ignore end*/
extractCommon: function extractCommon(basePath, newString, oldString, diagonalPath) {
var newLen = newString.length,
oldLen = oldString.length,
newPos = basePath.newPos,
oldPos = newPos - diagonalPath,
commonCount = 0;
while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(newString[newPos + 1], oldString[oldPos + 1])) {
newPos++;
oldPos++;
commonCount++;
}
if (commonCount) {
basePath.components.push({
count: commonCount
});
}
basePath.newPos = newPos;
return oldPos;
},
/*istanbul ignore start*/
/*istanbul ignore end*/
equals: function equals(left, right) {
if (this.options.comparator) {
return this.options.comparator(left, right);
} else {
return left === right || this.options.ignoreCase && left.toLowerCase() === right.toLowerCase();
}
},
/*istanbul ignore start*/
/*istanbul ignore end*/
removeEmpty: function removeEmpty(array) {
var ret = [];
for (var i = 0; i < array.length; i++) {
if (array[i]) {
ret.push(array[i]);
}
}
return ret;
},
/*istanbul ignore start*/
/*istanbul ignore end*/
castInput: function castInput(value) {
return value;
},
/*istanbul ignore start*/
/*istanbul ignore end*/
tokenize: function tokenize(value) {
return value.split('');
},
/*istanbul ignore start*/
/*istanbul ignore end*/
join: function join(chars) {
return chars.join('');
}
};
function buildValues(diff, components, newString, oldString, useLongestToken) {
var componentPos = 0,
componentLen = components.length,
newPos = 0,
oldPos = 0;
for (; componentPos < componentLen; componentPos++) {
var component = components[componentPos];
if (!component.removed) {
if (!component.added && useLongestToken) {
var value = newString.slice(newPos, newPos + component.count);
value = value.map(function (value, i) {
var oldValue = oldString[oldPos + i];
return oldValue.length > value.length ? oldValue : value;
});
component.value = diff.join(value);
} else {
component.value = diff.join(newString.slice(newPos, newPos + component.count));
}
newPos += component.count; // Common case
if (!component.added) {
oldPos += component.count;
}
} else {
component.value = diff.join(oldString.slice(oldPos, oldPos + component.count));
oldPos += component.count; // Reverse add and remove so removes are output first to match common convention
// The diffing algorithm is tied to add then remove output and this is the simplest
// route to get the desired output with minimal overhead.
if (componentPos && components[componentPos - 1].added) {
var tmp = components[componentPos - 1];
components[componentPos - 1] = components[componentPos];
components[componentPos] = tmp;
}
}
} // Special case handle for when one terminal is ignored (i.e. whitespace).
// For this case we merge the terminal into the prior string and drop the change.
// This is only available for string mode.
var lastComponent = components[componentLen - 1];
if (componentLen > 1 && typeof lastComponent.value === 'string' && (lastComponent.added || lastComponent.removed) && diff.equals('', lastComponent.value)) {
components[componentLen - 2].value += lastComponent.value;
components.pop();
}
return components;
}
function clonePath(path) {
return {
newPos: path.newPos,
components: path.components.slice(0)
};
}
/***/ }),
/***/ 1973:
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
"use strict";
var __webpack_unused_export__;
/*istanbul ignore start*/
__webpack_unused_export__ = ({
value: true
});
exports.Kx = diffChars;
__webpack_unused_export__ = void 0;
/*istanbul ignore end*/
var
/*istanbul ignore start*/
_base = _interopRequireDefault(__webpack_require__(1198))
/*istanbul ignore end*/
;
/*istanbul ignore start*/ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/*istanbul ignore end*/
var characterDiff = new
/*istanbul ignore start*/
_base
/*istanbul ignore end*/
.
/*istanbul ignore start*/
default
/*istanbul ignore end*/
();
/*istanbul ignore start*/
__webpack_unused_export__ = characterDiff;
/*istanbul ignore end*/
function diffChars(oldStr, newStr, options) {
return characterDiff.diff(oldStr, newStr, options);
}
/***/ }),
/***/ 1345:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {
"use strict";
var util = __webpack_require__(5022);
function scrollIntoView(elem, container, config) {
config = config || {};
// document 归一化到 window
if (container.nodeType === 9) {
container = util.getWindow(container);
}
var allowHorizontalScroll = config.allowHorizontalScroll;
var onlyScrollIfNeeded = config.onlyScrollIfNeeded;
var alignWithTop = config.alignWithTop;
var alignWithLeft = config.alignWithLeft;
var offsetTop = config.offsetTop || 0;
var offsetLeft = config.offsetLeft || 0;
var offsetBottom = config.offsetBottom || 0;
var offsetRight = config.offsetRight || 0;
allowHorizontalScroll = allowHorizontalScroll === undefined ? true : allowHorizontalScroll;
var isWin = util.isWindow(container);
var elemOffset = util.offset(elem);
var eh = util.outerHeight(elem);
var ew = util.outerWidth(elem);
var containerOffset = undefined;
var ch = undefined;
var cw = undefined;
var containerScroll = undefined;
var diffTop = undefined;
var diffBottom = undefined;
var win = undefined;
var winScroll = undefined;
var ww = undefined;
var wh = undefined;
if (isWin) {
win = container;
wh = util.height(win);
ww = util.width(win);
winScroll = {
left: util.scrollLeft(win),
top: util.scrollTop(win)
};
// elem 相对 container 可视视窗的距离
diffTop = {
left: elemOffset.left - winScroll.left - offsetLeft,
top: elemOffset.top - winScroll.top - offsetTop
};
diffBottom = {
left: elemOffset.left + ew - (winScroll.left + ww) + offsetRight,
top: elemOffset.top + eh - (winScroll.top + wh) + offsetBottom
};
containerScroll = winScroll;
} else {
containerOffset = util.offset(container);
ch = container.clientHeight;
cw = container.clientWidth;
containerScroll = {
left: container.scrollLeft,
top: container.scrollTop
};
// elem 相对 container 可视视窗的距离
// 注意边框, offset 是边框到根节点
diffTop = {
left: elemOffset.left - (containerOffset.left + (parseFloat(util.css(container, 'borderLeftWidth')) || 0)) - offsetLeft,
top: elemOffset.top - (containerOffset.top + (parseFloat(util.css(container, 'borderTopWidth')) || 0)) - offsetTop
};
diffBottom = {
left: elemOffset.left + ew - (containerOffset.left + cw + (parseFloat(util.css(container, 'borderRightWidth')) || 0)) + offsetRight,
top: elemOffset.top + eh - (containerOffset.top + ch + (parseFloat(util.css(container, 'borderBottomWidth')) || 0)) + offsetBottom
};
}
if (diffTop.top < 0 || diffBottom.top > 0) {
// 强制向上
if (alignWithTop === true) {
util.scrollTop(container, containerScroll.top + diffTop.top);
} else if (alignWithTop === false) {
util.scrollTop(container, containerScroll.top + diffBottom.top);
} else {
// 自动调整
if (diffTop.top < 0) {
util.scrollTop(container, containerScroll.top + diffTop.top);
} else {
util.scrollTop(container, containerScroll.top + diffBottom.top);
}
}
} else {
if (!onlyScrollIfNeeded) {
alignWithTop = alignWithTop === undefined ? true : !!alignWithTop;
if (alignWithTop) {
util.scrollTop(container, containerScroll.top + diffTop.top);
} else {
util.scrollTop(container, containerScroll.top + diffBottom.top);
}
}
}
if (allowHorizontalScroll) {
if (diffTop.left < 0 || diffBottom.left > 0) {
// 强制向上
if (alignWithLeft === true) {
util.scrollLeft(container, containerScroll.left + diffTop.left);
} else if (alignWithLeft === false) {
util.scrollLeft(container, containerScroll.left + diffBottom.left);
} else {
// 自动调整
if (diffTop.left < 0) {
util.scrollLeft(container, containerScroll.left + diffTop.left);
} else {
util.scrollLeft(container, containerScroll.left + diffBottom.left);
}
}
} else {
if (!onlyScrollIfNeeded) {
alignWithLeft = alignWithLeft === undefined ? true : !!alignWithLeft;
if (alignWithLeft) {
util.scrollLeft(container, containerScroll.left + diffTop.left);
} else {
util.scrollLeft(container, containerScroll.left + diffBottom.left);
}
}
}
}
}
module.exports = scrollIntoView;
/***/ }),
/***/ 5425:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {
"use strict";
module.exports = __webpack_require__(1345);
/***/ }),
/***/ 5022:
/***/ (function(module) {
"use strict";
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };
var RE_NUM = /[\-+]?(?:\d*\.|)\d+(?:[eE][\-+]?\d+|)/.source;
function getClientPosition(elem) {
var box = undefined;
var x = undefined;
var y = undefined;
var doc = elem.ownerDocument;
var body = doc.body;
var docElem = doc && doc.documentElement;
// 根据 GBS 最新数据,A-Grade Browsers 都已支持 getBoundingClientRect 方法,不用再考虑传统的实现方式
box = elem.getBoundingClientRect();
// 注:jQuery 还考虑减去 docElem.clientLeft/clientTop
// 但测试发现,这样反而会导致当 html 和 body 有边距/边框样式时,获取的值不正确
// 此外,ie6 会忽略 html 的 margin 值,幸运地是没有谁会去设置 html 的 margin
x = box.left;
y = box.top;
// In IE, most of the time, 2 extra pixels are added to the top and left
// due to the implicit 2-pixel inset border. In IE6/7 quirks mode and
// IE6 standards mode, this border can be overridden by setting the
// document element's border to zero -- thus, we cannot rely on the
// offset always being 2 pixels.
// In quirks mode, the offset can be determined by querying the body's
// clientLeft/clientTop, but in standards mode, it is found by querying
// the document element's clientLeft/clientTop. Since we already called
// getClientBoundingRect we have already forced a reflow, so it is not
// too expensive just to query them all.
// ie 下应该减去窗口的边框吧,毕竟默认 absolute 都是相对窗口定位的
// 窗口边框标准是设 documentElement ,quirks 时设置 body
// 最好禁止在 body 和 html 上边框 ,但 ie < 9 html 默认有 2px ,减去
// 但是非 ie 不可能设置窗口边框,body html 也不是窗口 ,ie 可以通过 html,body 设置
// 标准 ie 下 docElem.clientTop 就是 border-top
// ie7 html 即窗口边框改变不了。永远为 2
// 但标准 firefox/chrome/ie9 下 docElem.clientTop 是窗口边框,即使设了 border-top 也为 0
x -= docElem.clientLeft || body.clientLeft || 0;
y -= docElem.clientTop || body.clientTop || 0;
return {
left: x,
top: y
};
}
function getScroll(w, top) {
var ret = w['page' + (top ? 'Y' : 'X') + 'Offset'];
var method = 'scroll' + (top ? 'Top' : 'Left');
if (typeof ret !== 'number') {
var d = w.document;
// ie6,7,8 standard mode
ret = d.documentElement[method];
if (typeof ret !== 'number') {
// quirks mode
ret = d.body[method];
}
}
return ret;
}
function getScrollLeft(w) {
return getScroll(w);
}
function getScrollTop(w) {
return getScroll(w, true);
}
function getOffset(el) {
var pos = getClientPosition(el);
var doc = el.ownerDocument;
var w = doc.defaultView || doc.parentWindow;
pos.left += getScrollLeft(w);
pos.top += getScrollTop(w);
return pos;
}
function _getComputedStyle(elem, name, computedStyle_) {
var val = '';
var d = elem.ownerDocument;
var computedStyle = computedStyle_ || d.defaultView.getComputedStyle(elem, null);
// https://github.com/kissyteam/kissy/issues/61
if (computedStyle) {
val = computedStyle.getPropertyValue(name) || computedStyle[name];
}
return val;
}
var _RE_NUM_NO_PX = new RegExp('^(' + RE_NUM + ')(?!px)[a-z%]+$', 'i');
var RE_POS = /^(top|right|bottom|left)$/;
var CURRENT_STYLE = 'currentStyle';
var RUNTIME_STYLE = 'runtimeStyle';
var LEFT = 'left';
var PX = 'px';
function _getComputedStyleIE(elem, name) {
// currentStyle maybe null
// http://msdn.microsoft.com/en-us/library/ms535231.aspx
var ret = elem[CURRENT_STYLE] && elem[CURRENT_STYLE][name];
// 当 width/height 设置为百分比时,通过 pixelLeft 方式转换的 width/height 值
// 一开始就处理了! CUSTOM_STYLE.height,CUSTOM_STYLE.width ,cssHook 解决@2011-08-19
// 在 ie 下不对,需要直接用 offset 方式
// borderWidth 等值也有问题,但考虑到 borderWidth 设为百分比的概率很小,这里就不考虑了
// From the awesome hack by Dean Edwards
// http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
// If we're not dealing with a regular pixel number
// but a number that has a weird ending, we need to convert it to pixels
// exclude left right for relativity
if (_RE_NUM_NO_PX.test(ret) && !RE_POS.test(name)) {
// Remember the original values
var style = elem.style;
var left = style[LEFT];
var rsLeft = elem[RUNTIME_STYLE][LEFT];
// prevent flashing of content
elem[RUNTIME_STYLE][LEFT] = elem[CURRENT_STYLE][LEFT];
// Put in the new values to get a computed value out
style[LEFT] = name === 'fontSize' ? '1em' : ret || 0;
ret = style.pixelLeft + PX;
// Revert the changed values
style[LEFT] = left;
elem[RUNTIME_STYLE][LEFT] = rsLeft;
}
return ret === '' ? 'auto' : ret;
}
var getComputedStyleX = undefined;
if (typeof window !== 'undefined') {
getComputedStyleX = window.getComputedStyle ? _getComputedStyle : _getComputedStyleIE;
}
function each(arr, fn) {
for (var i = 0; i < arr.length; i++) {
fn(arr[i]);
}
}
function isBorderBoxFn(elem) {
return getComputedStyleX(elem, 'boxSizing') === 'border-box';
}
var BOX_MODELS = ['margin', 'border', 'padding'];
var CONTENT_INDEX = -1;
var PADDING_INDEX = 2;
var BORDER_INDEX = 1;
var MARGIN_INDEX = 0;
function swap(elem, options, callback) {
var old = {};
var style = elem.style;
var name = undefined;
// Remember the old values, and insert the new ones
for (name in options) {
if (options.hasOwnProperty(name)) {
old[name] = style[name];
style[name] = options[name];
}
}
callback.call(elem);
// Revert the old values
for (name in options) {
if (options.hasOwnProperty(name)) {
style[name] = old[name];
}
}
}
function getPBMWidth(elem, props, which) {
var value = 0;
var prop = undefined;
var j = undefined;
var i = undefined;
for (j = 0; j < props.length; j++) {
prop = props[j];
if (prop) {
for (i = 0; i < which.length; i++) {
var cssProp = undefined;
if (prop === 'border') {
cssProp = prop + which[i] + 'Width';
} else {
cssProp = prop + which[i];
}
value += parseFloat(getComputedStyleX(elem, cssProp)) || 0;
}
}
}
return value;
}
/**
* A crude way of determining if an object is a window
* @member util
*/
function isWindow(obj) {
// must use == for ie8
/* eslint eqeqeq:0 */
return obj != null && obj == obj.window;
}
var domUtils = {};
each(['Width', 'Height'], function (name) {
domUtils['doc' + name] = function (refWin) {
var d = refWin.document;
return Math.max(
// firefox chrome documentElement.scrollHeight< body.scrollHeight
// ie standard mode : documentElement.scrollHeight> body.scrollHeight
d.documentElement['scroll' + name],
// quirks : documentElement.scrollHeight 最大等于可视窗口多一点?
d.body['scroll' + name], domUtils['viewport' + name](d));
};
domUtils['viewport' + name] = function (win) {
// pc browser includes scrollbar in window.innerWidth
var prop = 'client' + name;
var doc = win.document;
var body = doc.body;
var documentElement = doc.documentElement;
var documentElementProp = documentElement[prop];
// 标准模式取 documentElement
// backcompat 取 body
return doc.compatMode === 'CSS1Compat' && documentElementProp || body && body[prop] || documentElementProp;
};
});
/*
得到元素的大小信息
@param elem
@param name
@param {String} [extra] 'padding' : (css width) + padding
'border' : (css width) + padding + border
'margin' : (css width) + padding + border + margin
*/
function getWH(elem, name, extra) {
if (isWindow(elem)) {
return name === 'width' ? domUtils.viewportWidth(elem) : domUtils.viewportHeight(elem);
} else if (elem.nodeType === 9) {
return name === 'width' ? domUtils.docWidth(elem) : domUtils.docHeight(elem);
}
var which = name === 'width' ? ['Left', 'Right'] : ['Top', 'Bottom'];
var borderBoxValue = name === 'width' ? elem.offsetWidth : elem.offsetHeight;
var computedStyle = getComputedStyleX(elem);
var isBorderBox = isBorderBoxFn(elem, computedStyle);
var cssBoxValue = 0;
if (borderBoxValue == null || borderBoxValue <= 0) {
borderBoxValue = undefined;
// Fall back to computed then un computed css if necessary
cssBoxValue = getComputedStyleX(elem, name);
if (cssBoxValue == null || Number(cssBoxValue) < 0) {
cssBoxValue = elem.style[name] || 0;
}
// Normalize '', auto, and prepare for extra
cssBoxValue = parseFloat(cssBoxValue) || 0;
}
if (extra === undefined) {
extra = isBorderBox ? BORDER_INDEX : CONTENT_INDEX;
}
var borderBoxValueOrIsBorderBox = borderBoxValue !== undefined || isBorderBox;
var val = borderBoxValue || cssBoxValue;
if (extra === CONTENT_INDEX) {
if (borderBoxValueOrIsBorderBox) {
return val - getPBMWidth(elem, ['border', 'padding'], which, computedStyle);
}
return cssBoxValue;
}
if (borderBoxValueOrIsBorderBox) {
var padding = extra === PADDING_INDEX ? -getPBMWidth(elem, ['border'], which, computedStyle) : getPBMWidth(elem, ['margin'], which, computedStyle);
return val + (extra === BORDER_INDEX ? 0 : padding);
}
return cssBoxValue + getPBMWidth(elem, BOX_MODELS.slice(extra), which, computedStyle);
}
var cssShow = {
position: 'absolute',
visibility: 'hidden',
display: 'block'
};
// fix #119 : https://github.com/kissyteam/kissy/issues/119
function getWHIgnoreDisplay(elem) {
var val = undefined;
var args = arguments;
// in case elem is window
// elem.offsetWidth === undefined
if (elem.offsetWidth !== 0) {
val = getWH.apply(undefined, args);
} else {
swap(elem, cssShow, function () {
val = getWH.apply(undefined, args);
});
}
return val;
}
function css(el, name, v) {
var value = v;
if ((typeof name === 'undefined' ? 'undefined' : _typeof(name)) === 'object') {
for (var i in name) {
if (name.hasOwnProperty(i)) {
css(el, i, name[i]);
}
}
return undefined;
}
if (typeof value !== 'undefined') {
if (typeof value === 'number') {
value += 'px';
}
el.style[name] = value;
return undefined;
}
return getComputedStyleX(el, name);
}
each(['width', 'height'], function (name) {
var first = name.charAt(0).toUpperCase() + name.slice(1);
domUtils['outer' + first] = function (el, includeMargin) {
return el && getWHIgnoreDisplay(el, name, includeMargin ? MARGIN_INDEX : BORDER_INDEX);
};
var which = name === 'width' ? ['Left', 'Right'] : ['Top', 'Bottom'];
domUtils[name] = function (elem, val) {
if (val !== undefined) {
if (elem) {
var computedStyle = getComputedStyleX(elem);
var isBorderBox = isBorderBoxFn(elem);
if (isBorderBox) {
val += getPBMWidth(elem, ['padding', 'border'], which, computedStyle);
}
return css(elem, name, val);
}
return undefined;
}
return elem && getWHIgnoreDisplay(elem, name, CONTENT_INDEX);
};
});
// 设置 elem 相对 elem.ownerDocument 的坐标
function setOffset(elem, offset) {
// set position first, in-case top/left are set even on static elem
if (css(elem, 'position') === 'static') {
elem.style.position = 'relative';
}
var old = getOffset(elem);
var ret = {};
var current = undefined;
var key = undefined;
for (key in offset) {
if (offset.hasOwnProperty(key)) {
current = parseFloat(css(elem, key)) || 0;
ret[key] = current + offset[key] - old[key];
}
}
css(elem, ret);
}
module.exports = _extends({
getWindow: function getWindow(node) {
var doc = node.ownerDocument || node;
return doc.defaultView || doc.parentWindow;
},
offset: function offset(el, value) {
if (typeof value !== 'undefined') {
setOffset(el, value);
} else {
return getOffset(el);
}
},
isWindow: isWindow,
each: each,
css: css,
clone: function clone(obj) {
var ret = {};
for (var i in obj) {
if (obj.hasOwnProperty(i)) {
ret[i] = obj[i];
}
}
var overflow = obj.overflow;
if (overflow) {
for (var i in obj) {
if (obj.hasOwnProperty(i)) {
ret.overflow[i] = obj.overflow[i];
}
}
}
return ret;
},
scrollLeft: function scrollLeft(w, v) {
if (isWindow(w)) {
if (v === undefined) {
return getScrollLeft(w);
}
window.scrollTo(v, getScrollTop(w));
} else {
if (v === undefined) {
return w.scrollLeft;
}
w.scrollLeft = v;
}
},
scrollTop: function scrollTop(w, v) {
if (isWindow(w)) {
if (v === undefined) {
return getScrollTop(w);
}
window.scrollTo(getScrollLeft(w), v);
} else {
if (v === undefined) {
return w.scrollTop;
}
w.scrollTop = v;
}
},
viewportWidth: 0,
viewportHeight: 0
}, domUtils);
/***/ }),
/***/ 5619:
/***/ (function(module) {
"use strict";
// do not edit .js files directly - edit src/index.jst
var envHasBigInt64Array = typeof BigInt64Array !== 'undefined';
module.exports = function equal(a, b) {
if (a === b) return true;
if (a && b && typeof a == 'object' && typeof b == 'object') {
if (a.constructor !== b.constructor) return false;
var length, i, keys;
if (Array.isArray(a)) {
length = a.length;
if (length != b.length) return false;
for (i = length; i-- !== 0;)
if (!equal(a[i], b[i])) return false;
return true;
}
if ((a instanceof Map) && (b instanceof Map)) {
if (a.size !== b.size) return false;
for (i of a.entries())
if (!b.has(i[0])) return false;
for (i of a.entries())
if (!equal(i[1], b.get(i[0]))) return false;
return true;
}
if ((a instanceof Set) && (b instanceof Set)) {
if (a.size !== b.size) return false;
for (i of a.entries())
if (!b.has(i[0])) return false;
return true;
}
if (ArrayBuffer.isView(a) && ArrayBuffer.isView(b)) {
length = a.length;
if (length != b.length) return false;
for (i = length; i-- !== 0;)
if (a[i] !== b[i]) return false;
return true;
}
if (a.constructor === RegExp) return a.source === b.source && a.flags === b.flags;
if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf();
if (a.toString !== Object.prototype.toString) return a.toString() === b.toString();
keys = Object.keys(a);
length = keys.length;
if (length !== Object.keys(b).length) return false;
for (i = length; i-- !== 0;)
if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false;
for (i = length; i-- !== 0;) {
var key = keys[i];
if (!equal(a[key], b[key])) return false;
}
return true;
}
// true if both NaN, false otherwise
return a!==a && b!==b;
};
/***/ }),
/***/ 8575:
/***/ (function(module) {
if (typeof Object.create === 'function') {
// implementation from standard node.js 'util' module
module.exports = function inherits(ctor, superCtor) {
if (superCtor) {
ctor.super_ = superCtor
ctor.prototype = Object.create(superCtor.prototype, {
constructor: {
value: ctor,
enumerable: false,
writable: true,
configurable: true
}
})
}
};
} else {
// old school shim for old browsers
module.exports = function inherits(ctor, superCtor) {
if (superCtor) {
ctor.super_ = superCtor
var TempCtor = function () {}
TempCtor.prototype = superCtor.prototype
ctor.prototype = new TempCtor()
ctor.prototype.constructor = ctor
}
}
}
/***/ }),
/***/ 9894:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {
// Load in dependencies
var computedStyle = __webpack_require__(4827);
/**
* Calculate the `line-height` of a given node
* @param {HTMLElement} node Element to calculate line height of. Must be in the DOM.
* @returns {Number} `line-height` of the element in pixels
*/
function lineHeight(node) {
// Grab the line-height via style
var lnHeightStr = computedStyle(node, 'line-height');
var lnHeight = parseFloat(lnHeightStr, 10);
// If the lineHeight did not contain a unit (i.e. it was numeric), convert it to ems (e.g. '2.3' === '2.3em')
if (lnHeightStr === lnHeight + '') {
// Save the old lineHeight style and update the em unit to the element
var _lnHeightStyle = node.style.lineHeight;
node.style.lineHeight = lnHeightStr + 'em';
// Calculate the em based height
lnHeightStr = computedStyle(node, 'line-height');
lnHeight = parseFloat(lnHeightStr, 10);
// Revert the lineHeight style
if (_lnHeightStyle) {
node.style.lineHeight = _lnHeightStyle;
} else {
delete node.style.lineHeight;
}
}
// If the lineHeight is in `pt`, convert it to pixels (4px for 3pt)
// DEV: `em` units are converted to `pt` in IE6
// Conversion ratio from https://developer.mozilla.org/en-US/docs/Web/CSS/length
if (lnHeightStr.indexOf('pt') !== -1) {
lnHeight *= 4;
lnHeight /= 3;
// Otherwise, if the lineHeight is in `mm`, convert it to pixels (96px for 25.4mm)
} else if (lnHeightStr.indexOf('mm') !== -1) {
lnHeight *= 96;
lnHeight /= 25.4;
// Otherwise, if the lineHeight is in `cm`, convert it to pixels (96px for 2.54cm)
} else if (lnHeightStr.indexOf('cm') !== -1) {
lnHeight *= 96;
lnHeight /= 2.54;
// Otherwise, if the lineHeight is in `in`, convert it to pixels (96px for 1in)
} else if (lnHeightStr.indexOf('in') !== -1) {
lnHeight *= 96;
// Otherwise, if the lineHeight is in `pc`, convert it to pixels (12pt for 1pc)
} else if (lnHeightStr.indexOf('pc') !== -1) {
lnHeight *= 16;
}
// Continue our computation
lnHeight = Math.round(lnHeight);
// If the line-height is "normal", calculate by font-size
if (lnHeightStr === 'normal') {
// Create a temporary node
var nodeName = node.nodeName;
var _node = document.createElement(nodeName);
_node.innerHTML = ' ';
// If we have a text area, reset it to only 1 row
// https://github.com/twolfson/line-height/issues/4
if (nodeName.toUpperCase() === 'TEXTAREA') {
_node.setAttribute('rows', '1');
}
// Set the font-size of the element
var fontSizeStr = computedStyle(node, 'font-size');
_node.style.fontSize = fontSizeStr;
// Remove default padding/border which can affect offset height
// https://github.com/twolfson/line-height/issues/4
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetHeight
_node.style.padding = '0px';
_node.style.border = '0px';
// Append it to the body
var body = document.body;
body.appendChild(_node);
// Assume the line height of the element is the height
var height = _node.offsetHeight;
lnHeight = height;
// Remove our child from the DOM
body.removeChild(_node);
}
// Return the calculated height
return lnHeight;
}
// Export lineHeight
module.exports = lineHeight;
/***/ }),
/***/ 7970:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {
module.exports = __webpack_require__(195);
/***/ }),
/***/ 3110:
/***/ (function(module) {
"use strict";
/**
* Copyright (c) 2015, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule ExecutionEnvironment
*/
/*jslint evil: true */
var canUseDOM = !!(
typeof window !== 'undefined' &&
window.document &&
window.document.createElement
);
/**
* Simple, lightweight module assisting with the detection and context of
* Worker. Helps avoid circular dependencies and allows code to reason about
* whether or not they are in a Worker, even if they never include the main
* `ReactWorker` dependency.
*/
var ExecutionEnvironment = {
canUseDOM: canUseDOM,
canUseWorkers: typeof Worker !== 'undefined',
canUseEventListeners:
canUseDOM && !!(window.addEventListener || window.attachEvent),
canUseViewport: canUseDOM && !!window.screen,
isInWorker: !canUseDOM // For now, this is true - might change in the future.
};
module.exports = ExecutionEnvironment;
/***/ }),
/***/ 3812:
/***/ (function(module) {
/**
* Copyright 2004-present Facebook. All Rights Reserved.
*
* @providesModule UserAgent_DEPRECATED
*/
/**
* Provides entirely client-side User Agent and OS detection. You should prefer
* the non-deprecated UserAgent module when possible, which exposes our
* authoritative server-side PHP-based detection to the client.
*
* Usage is straightforward:
*
* if (UserAgent_DEPRECATED.ie()) {
* // IE
* }
*
* You can also do version checks:
*
* if (UserAgent_DEPRECATED.ie() >= 7) {
* // IE7 or better
* }
*
* The browser functions will return NaN if the browser does not match, so
* you can also do version compares the other way:
*
* if (UserAgent_DEPRECATED.ie() < 7) {
* // IE6 or worse
* }
*
* Note that the version is a float and may include a minor version number,
* so you should always use range operators to perform comparisons, not
* strict equality.
*
* **Note:** You should **strongly** prefer capability detection to browser
* version detection where it's reasonable:
*
* http://www.quirksmode.org/js/support.html
*
* Further, we have a large number of mature wrapper functions and classes
* which abstract away many browser irregularities. Check the documentation,
* grep for things, or ask on javascript@lists.facebook.com before writing yet
* another copy of "event || window.event".
*
*/
var _populated = false;
// Browsers
var _ie, _firefox, _opera, _webkit, _chrome;
// Actual IE browser for compatibility mode
var _ie_real_version;
// Platforms
var _osx, _windows, _linux, _android;
// Architectures
var _win64;
// Devices
var _iphone, _ipad, _native;
var _mobile;
function _populate() {
if (_populated) {
return;
}
_populated = true;
// To work around buggy JS libraries that can't handle multi-digit
// version numbers, Opera 10's user agent string claims it's Opera
// 9, then later includes a Version/X.Y field:
//
// Opera/9.80 (foo) Presto/2.2.15 Version/10.10
var uas = navigator.userAgent;
var agent = /(?:MSIE.(\d+\.\d+))|(?:(?:Firefox|GranParadiso|Iceweasel).(\d+\.\d+))|(?:Opera(?:.+Version.|.)(\d+\.\d+))|(?:AppleWebKit.(\d+(?:\.\d+)?))|(?:Trident\/\d+\.\d+.*rv:(\d+\.\d+))/.exec(uas);
var os = /(Mac OS X)|(Windows)|(Linux)/.exec(uas);
_iphone = /\b(iPhone|iP[ao]d)/.exec(uas);
_ipad = /\b(iP[ao]d)/.exec(uas);
_android = /Android/i.exec(uas);
_native = /FBAN\/\w+;/i.exec(uas);
_mobile = /Mobile/i.exec(uas);
// Note that the IE team blog would have you believe you should be checking
// for 'Win64; x64'. But MSDN then reveals that you can actually be coming
// from either x64 or ia64; so ultimately, you should just check for Win64
// as in indicator of whether you're in 64-bit IE. 32-bit IE on 64-bit
// Windows will send 'WOW64' instead.
_win64 = !!(/Win64/.exec(uas));
if (agent) {
_ie = agent[1] ? parseFloat(agent[1]) : (
agent[5] ? parseFloat(agent[5]) : NaN);
// IE compatibility mode
if (_ie && document && document.documentMode) {
_ie = document.documentMode;
}
// grab the "true" ie version from the trident token if available
var trident = /(?:Trident\/(\d+.\d+))/.exec(uas);
_ie_real_version = trident ? parseFloat(trident[1]) + 4 : _ie;
_firefox = agent[2] ? parseFloat(agent[2]) : NaN;
_opera = agent[3] ? parseFloat(agent[3]) : NaN;
_webkit = agent[4] ? parseFloat(agent[4]) : NaN;
if (_webkit) {
// We do not add the regexp to the above test, because it will always
// match 'safari' only since 'AppleWebKit' appears before 'Chrome' in
// the userAgent string.
agent = /(?:Chrome\/(\d+\.\d+))/.exec(uas);
_chrome = agent && agent[1] ? parseFloat(agent[1]) : NaN;
} else {
_chrome = NaN;
}
} else {
_ie = _firefox = _opera = _chrome = _webkit = NaN;
}
if (os) {
if (os[1]) {
// Detect OS X version. If no version number matches, set _osx to true.
// Version examples: 10, 10_6_1, 10.7
// Parses version number as a float, taking only first two sets of
// digits. If only one set of digits is found, returns just the major
// version number.
var ver = /(?:Mac OS X (\d+(?:[._]\d+)?))/.exec(uas);
_osx = ver ? parseFloat(ver[1].replace('_', '.')) : true;
} else {
_osx = false;
}
_windows = !!os[2];
_linux = !!os[3];
} else {
_osx = _windows = _linux = false;
}
}
var UserAgent_DEPRECATED = {
/**
* Check if the UA is Internet Explorer.
*
*
* @return float|NaN Version number (if match) or NaN.
*/
ie: function() {
return _populate() || _ie;
},
/**
* Check if we're in Internet Explorer compatibility mode.
*
* @return bool true if in compatibility mode, false if
* not compatibility mode or not ie
*/
ieCompatibilityMode: function() {
return _populate() || (_ie_real_version > _ie);
},
/**
* Whether the browser is 64-bit IE. Really, this is kind of weak sauce; we
* only need this because Skype can't handle 64-bit IE yet. We need to remove
* this when we don't need it -- tracked by #601957.
*/
ie64: function() {
return UserAgent_DEPRECATED.ie() && _win64;
},
/**
* Check if the UA is Firefox.
*
*
* @return float|NaN Version number (if match) or NaN.
*/
firefox: function() {
return _populate() || _firefox;
},
/**
* Check if the UA is Opera.
*
*
* @return float|NaN Version number (if match) or NaN.
*/
opera: function() {
return _populate() || _opera;
},
/**
* Check if the UA is WebKit.
*
*
* @return float|NaN Version number (if match) or NaN.
*/
webkit: function() {
return _populate() || _webkit;
},
/**
* For Push
* WILL BE REMOVED VERY SOON. Use UserAgent_DEPRECATED.webkit
*/
safari: function() {
return UserAgent_DEPRECATED.webkit();
},
/**
* Check if the UA is a Chrome browser.
*
*
* @return float|NaN Version number (if match) or NaN.
*/
chrome : function() {
return _populate() || _chrome;
},
/**
* Check if the user is running Windows.
*
* @return bool `true' if the user's OS is Windows.
*/
windows: function() {
return _populate() || _windows;
},
/**
* Check if the user is running Mac OS X.
*
* @return float|bool Returns a float if a version number is detected,
* otherwise true/false.
*/
osx: function() {
return _populate() || _osx;
},
/**
* Check if the user is running Linux.
*
* @return bool `true' if the user's OS is some flavor of Linux.
*/
linux: function() {
return _populate() || _linux;
},
/**
* Check if the user is running on an iPhone or iPod platform.
*
* @return bool `true' if the user is running some flavor of the
* iPhone OS.
*/
iphone: function() {
return _populate() || _iphone;
},
mobile: function() {
return _populate() || (_iphone || _ipad || _android || _mobile);
},
nativeApp: function() {
// webviews inside of the native apps
return _populate() || _native;
},
android: function() {
return _populate() || _android;
},
ipad: function() {
return _populate() || _ipad;
}
};
module.exports = UserAgent_DEPRECATED;
/***/ }),
/***/ 7939:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {
"use strict";
/**
* Copyright 2013-2015, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule isEventSupported
*/
var ExecutionEnvironment = __webpack_require__(3110);
var useHasFeature;
if (ExecutionEnvironment.canUseDOM) {
useHasFeature =
document.implementation &&
document.implementation.hasFeature &&
// always returns true in newer browsers as per the standard.
// @see http://dom.spec.whatwg.org/#dom-domimplementation-hasfeature
document.implementation.hasFeature('', '') !== true;
}
/**
* Checks if an event is supported in the current execution environment.
*
* NOTE: This will not work correctly for non-generic events such as `change`,
* `reset`, `load`, `error`, and `select`.
*
* Borrows from Modernizr.
*
* @param {string} eventNameSuffix Event name, e.g. "click".
* @param {?boolean} capture Check if the capture phase is supported.
* @return {boolean} True if the event is supported.
* @internal
* @license Modernizr 3.0.0pre (Custom Build) | MIT
*/
function isEventSupported(eventNameSuffix, capture) {
if (!ExecutionEnvironment.canUseDOM ||
capture && !('addEventListener' in document)) {
return false;
}
var eventName = 'on' + eventNameSuffix;
var isSupported = eventName in document;
if (!isSupported) {
var element = document.createElement('div');
element.setAttribute(eventName, 'return;');
isSupported = typeof element[eventName] === 'function';
}
if (!isSupported && useHasFeature && eventNameSuffix === 'wheel') {
// This is the only way to test support for the `wheel` event in IE9+.
isSupported = document.implementation.hasFeature('Events.wheel', '3.0');
}
return isSupported;
}
module.exports = isEventSupported;
/***/ }),
/***/ 195:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2015, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule normalizeWheel
* @typechecks
*/
var UserAgent_DEPRECATED = __webpack_require__(3812);
var isEventSupported = __webpack_require__(7939);
// Reasonable defaults
var PIXEL_STEP = 10;
var LINE_HEIGHT = 40;
var PAGE_HEIGHT = 800;
/**
* Mouse wheel (and 2-finger trackpad) support on the web sucks. It is
* complicated, thus this doc is long and (hopefully) detailed enough to answer
* your questions.
*
* If you need to react to the mouse wheel in a predictable way, this code is
* like your bestest friend. * hugs *
*
* As of today, there are 4 DOM event types you can listen to:
*
* 'wheel' -- Chrome(31+), FF(17+), IE(9+)
* 'mousewheel' -- Chrome, IE(6+), Opera, Safari
* 'MozMousePixelScroll' -- FF(3.5 only!) (2010-2013) -- don't bother!
* 'DOMMouseScroll' -- FF(0.9.7+) since 2003
*
* So what to do? The is the best:
*
* normalizeWheel.getEventType();
*
* In your event callback, use this code to get sane interpretation of the
* deltas. This code will return an object with properties:
*
* spinX -- normalized spin speed (use for zoom) - x plane
* spinY -- " - y plane
* pixelX -- normalized distance (to pixels) - x plane
* pixelY -- " - y plane
*
* Wheel values are provided by the browser assuming you are using the wheel to
* scroll a web page by a number of lines or pixels (or pages). Values can vary
* significantly on different platforms and browsers, forgetting that you can
* scroll at different speeds. Some devices (like trackpads) emit more events
* at smaller increments with fine granularity, and some emit massive jumps with
* linear speed or acceleration.
*
* This code does its best to normalize the deltas for you:
*
* - spin is trying to normalize how far the wheel was spun (or trackpad
* dragged). This is super useful for zoom support where you want to
* throw away the chunky scroll steps on the PC and make those equal to
* the slow and smooth tiny steps on the Mac. Key data: This code tries to
* resolve a single slow step on a wheel to 1.
*
* - pixel is normalizing the desired scroll delta in pixel units. You'll
* get the crazy differences between browsers, but at least it'll be in
* pixels!
*
* - positive value indicates scrolling DOWN/RIGHT, negative UP/LEFT. This
* should translate to positive value zooming IN, negative zooming OUT.
* This matches the newer 'wheel' event.
*
* Why are there spinX, spinY (or pixels)?
*
* - spinX is a 2-finger side drag on the trackpad, and a shift + wheel turn
* with a mouse. It results in side-scrolling in the browser by default.
*
* - spinY is what you expect -- it's the classic axis of a mouse wheel.
*
* - I dropped spinZ/pixelZ. It is supported by the DOM 3 'wheel' event and
* probably is by browsers in conjunction with fancy 3D controllers .. but
* you know.
*
* Implementation info:
*
* Examples of 'wheel' event if you scroll slowly (down) by one step with an
* average mouse:
*
* OS X + Chrome (mouse) - 4 pixel delta (wheelDelta -120)
* OS X + Safari (mouse) - N/A pixel delta (wheelDelta -12)
* OS X + Firefox (mouse) - 0.1 line delta (wheelDelta N/A)
* Win8 + Chrome (mouse) - 100 pixel delta (wheelDelta -120)
* Win8 + Firefox (mouse) - 3 line delta (wheelDelta -120)
*
* On the trackpad:
*
* OS X + Chrome (trackpad) - 2 pixel delta (wheelDelta -6)
* OS X + Firefox (trackpad) - 1 pixel delta (wheelDelta N/A)
*
* On other/older browsers.. it's more complicated as there can be multiple and
* also missing delta values.
*
* The 'wheel' event is more standard:
*
* http://www.w3.org/TR/DOM-Level-3-Events/#events-wheelevents
*
* The basics is that it includes a unit, deltaMode (pixels, lines, pages), and
* deltaX, deltaY and deltaZ. Some browsers provide other values to maintain
* backward compatibility with older events. Those other values help us
* better normalize spin speed. Example of what the browsers provide:
*
* | event.wheelDelta | event.detail
* ------------------+------------------+--------------
* Safari v5/OS X | -120 | 0
* Safari v5/Win7 | -120 | 0
* Chrome v17/OS X | -120 | 0
* Chrome v17/Win7 | -120 | 0
* IE9/Win7 | -120 | undefined
* Firefox v4/OS X | undefined | 1
* Firefox v4/Win7 | undefined | 3
*
*/
function normalizeWheel(/*object*/ event) /*object*/ {
var sX = 0, sY = 0, // spinX, spinY
pX = 0, pY = 0; // pixelX, pixelY
// Legacy
if ('detail' in event) { sY = event.detail; }
if ('wheelDelta' in event) { sY = -event.wheelDelta / 120; }
if ('wheelDeltaY' in event) { sY = -event.wheelDeltaY / 120; }
if ('wheelDeltaX' in event) { sX = -event.wheelDeltaX / 120; }
// side scrolling on FF with DOMMouseScroll
if ( 'axis' in event && event.axis === event.HORIZONTAL_AXIS ) {
sX = sY;
sY = 0;
}
pX = sX * PIXEL_STEP;
pY = sY * PIXEL_STEP;
if ('deltaY' in event) { pY = event.deltaY; }
if ('deltaX' in event) { pX = event.deltaX; }
if ((pX || pY) && event.deltaMode) {
if (event.deltaMode == 1) { // delta in LINE units
pX *= LINE_HEIGHT;
pY *= LINE_HEIGHT;
} else { // delta in PAGE units
pX *= PAGE_HEIGHT;
pY *= PAGE_HEIGHT;
}
}
// Fall-back if spin cannot be determined
if (pX && !sX) { sX = (pX < 1) ? -1 : 1; }
if (pY && !sY) { sY = (pY < 1) ? -1 : 1; }
return { spinX : sX,
spinY : sY,
pixelX : pX,
pixelY : pY };
}
/**
* The best combination if you prefer spinX + spinY normalization. It favors
* the older DOMMouseScroll for Firefox, as FF does not include wheelDelta with
* 'wheel' event, making spin speed determination impossible.
*/
normalizeWheel.getEventType = function() /*string*/ {
return (UserAgent_DEPRECATED.firefox())
? 'DOMMouseScroll'
: (isEventSupported('wheel'))
? 'wheel'
: 'mousewheel';
};
module.exports = normalizeWheel;
/***/ }),
/***/ 5372:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
var ReactPropTypesSecret = __webpack_require__(9567);
function emptyFunction() {}
function emptyFunctionWithReset() {}
emptyFunctionWithReset.resetWarningCache = emptyFunction;
module.exports = function() {
function shim(props, propName, componentName, location, propFullName, secret) {
if (secret === ReactPropTypesSecret) {
// It is still safe when called from React.
return;
}
var err = new Error(
'Calling PropTypes validators directly is not supported by the `prop-types` package. ' +
'Use PropTypes.checkPropTypes() to call them. ' +
'Read more at http://fb.me/use-check-prop-types'
);
err.name = 'Invariant Violation';
throw err;
};
shim.isRequired = shim;
function getShim() {
return shim;
};
// Important!
// Keep this list in sync with production version in `./factoryWithTypeCheckers.js`.
var ReactPropTypes = {
array: shim,
bigint: shim,
bool: shim,
func: shim,
number: shim,
object: shim,
string: shim,
symbol: shim,
any: shim,
arrayOf: getShim,
element: shim,
elementType: shim,
instanceOf: getShim,
node: shim,
objectOf: getShim,
oneOf: getShim,
oneOfType: getShim,
shape: getShim,
exact: getShim,
checkPropTypes: emptyFunctionWithReset,
resetWarningCache: emptyFunction
};
ReactPropTypes.PropTypes = ReactPropTypes;
return ReactPropTypes;
};
/***/ }),
/***/ 2652:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
if (false) { var throwOnDirectAccess, ReactIs; } else {
// By explicitly using `prop-types` you are opting into new production behavior.
// http://fb.me/prop-types-in-prod
module.exports = __webpack_require__(5372)();
}
/***/ }),
/***/ 9567:
/***/ (function(module) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
var ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED';
module.exports = ReactPropTypesSecret;
/***/ }),
/***/ 5438:
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __assign = (this && this.__assign) || Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0)
t[p[i]] = s[p[i]];
return t;
};
exports.__esModule = true;
var React = __webpack_require__(9196);
var PropTypes = __webpack_require__(2652);
var autosize = __webpack_require__(6411);
var _getLineHeight = __webpack_require__(9894);
var getLineHeight = _getLineHeight;
var RESIZED = "autosize:resized";
/**
* A light replacement for built-in textarea component
* which automaticaly adjusts its height to match the content
*/
var TextareaAutosizeClass = /** @class */ (function (_super) {
__extends(TextareaAutosizeClass, _super);
function TextareaAutosizeClass() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.state = {
lineHeight: null
};
_this.textarea = null;
_this.onResize = function (e) {
if (_this.props.onResize) {
_this.props.onResize(e);
}
};
_this.updateLineHeight = function () {
if (_this.textarea) {
_this.setState({
lineHeight: getLineHeight(_this.textarea)
});
}
};
_this.onChange = function (e) {
var onChange = _this.props.onChange;
_this.currentValue = e.currentTarget.value;
onChange && onChange(e);
};
return _this;
}
TextareaAutosizeClass.prototype.componentDidMount = function () {
var _this = this;
var _a = this.props, maxRows = _a.maxRows, async = _a.async;
if (typeof maxRows === "number") {
this.updateLineHeight();
}
if (typeof maxRows === "number" || async) {
/*
the defer is needed to:
- force "autosize" to activate the scrollbar when this.props.maxRows is passed
- support StyledComponents (see #71)
*/
setTimeout(function () { return _this.textarea && autosize(_this.textarea); });
}
else {
this.textarea && autosize(this.textarea);
}
if (this.textarea) {
this.textarea.addEventListener(RESIZED, this.onResize);
}
};
TextareaAutosizeClass.prototype.componentWillUnmount = function () {
if (this.textarea) {
this.textarea.removeEventListener(RESIZED, this.onResize);
autosize.destroy(this.textarea);
}
};
TextareaAutosizeClass.prototype.render = function () {
var _this = this;
var _a = this, _b = _a.props, onResize = _b.onResize, maxRows = _b.maxRows, onChange = _b.onChange, style = _b.style, innerRef = _b.innerRef, children = _b.children, props = __rest(_b, ["onResize", "maxRows", "onChange", "style", "innerRef", "children"]), lineHeight = _a.state.lineHeight;
var maxHeight = maxRows && lineHeight ? lineHeight * maxRows : null;
return (React.createElement("textarea", __assign({}, props, { onChange: this.onChange, style: maxHeight ? __assign({}, style, { maxHeight: maxHeight }) : style, ref: function (element) {
_this.textarea = element;
if (typeof _this.props.innerRef === 'function') {
_this.props.innerRef(element);
}
else if (_this.props.innerRef) {
_this.props.innerRef.current = element;
}
} }), children));
};
TextareaAutosizeClass.prototype.componentDidUpdate = function () {
this.textarea && autosize.update(this.textarea);
};
TextareaAutosizeClass.defaultProps = {
rows: 1,
async: false
};
TextareaAutosizeClass.propTypes = {
rows: PropTypes.number,
maxRows: PropTypes.number,
onResize: PropTypes.func,
innerRef: PropTypes.any,
async: PropTypes.bool
};
return TextareaAutosizeClass;
}(React.Component));
exports.TextareaAutosize = React.forwardRef(function (props, ref) {
return React.createElement(TextareaAutosizeClass, __assign({}, props, { innerRef: ref }));
});
/***/ }),
/***/ 773:
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
"use strict";
var __webpack_unused_export__;
__webpack_unused_export__ = true;
var TextareaAutosize_1 = __webpack_require__(5438);
exports.Z = TextareaAutosize_1.TextareaAutosize;
/***/ }),
/***/ 4793:
/***/ (function(module) {
var characterMap = {
"À": "A",
"Á": "A",
"Â": "A",
"Ã": "A",
"Ä": "A",
"Å": "A",
"Ấ": "A",
"Ắ": "A",
"Ẳ": "A",
"Ẵ": "A",
"Ặ": "A",
"Æ": "AE",
"Ầ": "A",
"Ằ": "A",
"Ȃ": "A",
"Ả": "A",
"Ạ": "A",
"Ẩ": "A",
"Ẫ": "A",
"Ậ": "A",
"Ç": "C",
"Ḉ": "C",
"È": "E",
"É": "E",
"Ê": "E",
"Ë": "E",
"Ế": "E",
"Ḗ": "E",
"Ề": "E",
"Ḕ": "E",
"Ḝ": "E",
"Ȇ": "E",
"Ẻ": "E",
"Ẽ": "E",
"Ẹ": "E",
"Ể": "E",
"Ễ": "E",
"Ệ": "E",
"Ì": "I",
"Í": "I",
"Î": "I",
"Ï": "I",
"Ḯ": "I",
"Ȋ": "I",
"Ỉ": "I",
"Ị": "I",
"Ð": "D",
"Ñ": "N",
"Ò": "O",
"Ó": "O",
"Ô": "O",
"Õ": "O",
"Ö": "O",
"Ø": "O",
"Ố": "O",
"Ṍ": "O",
"Ṓ": "O",
"Ȏ": "O",
"Ỏ": "O",
"Ọ": "O",
"Ổ": "O",
"Ỗ": "O",
"Ộ": "O",
"Ờ": "O",
"Ở": "O",
"Ỡ": "O",
"Ớ": "O",
"Ợ": "O",
"Ù": "U",
"Ú": "U",
"Û": "U",
"Ü": "U",
"Ủ": "U",
"Ụ": "U",
"Ử": "U",
"Ữ": "U",
"Ự": "U",
"Ý": "Y",
"à": "a",
"á": "a",
"â": "a",
"ã": "a",
"ä": "a",
"å": "a",
"ấ": "a",
"ắ": "a",
"ẳ": "a",
"ẵ": "a",
"ặ": "a",
"æ": "ae",
"ầ": "a",
"ằ": "a",
"ȃ": "a",
"ả": "a",
"ạ": "a",
"ẩ": "a",
"ẫ": "a",
"ậ": "a",
"ç": "c",
"ḉ": "c",
"è": "e",
"é": "e",
"ê": "e",
"ë": "e",
"ế": "e",
"ḗ": "e",
"ề": "e",
"ḕ": "e",
"ḝ": "e",
"ȇ": "e",
"ẻ": "e",
"ẽ": "e",
"ẹ": "e",
"ể": "e",
"ễ": "e",
"ệ": "e",
"ì": "i",
"í": "i",
"î": "i",
"ï": "i",
"ḯ": "i",
"ȋ": "i",
"ỉ": "i",
"ị": "i",
"ð": "d",
"ñ": "n",
"ò": "o",
"ó": "o",
"ô": "o",
"õ": "o",
"ö": "o",
"ø": "o",
"ố": "o",
"ṍ": "o",
"ṓ": "o",
"ȏ": "o",
"ỏ": "o",
"ọ": "o",
"ổ": "o",
"ỗ": "o",
"ộ": "o",
"ờ": "o",
"ở": "o",
"ỡ": "o",
"ớ": "o",
"ợ": "o",
"ù": "u",
"ú": "u",
"û": "u",
"ü": "u",
"ủ": "u",
"ụ": "u",
"ử": "u",
"ữ": "u",
"ự": "u",
"ý": "y",
"ÿ": "y",
"Ā": "A",
"ā": "a",
"Ă": "A",
"ă": "a",
"Ą": "A",
"ą": "a",
"Ć": "C",
"ć": "c",
"Ĉ": "C",
"ĉ": "c",
"Ċ": "C",
"ċ": "c",
"Č": "C",
"č": "c",
"C̆": "C",
"c̆": "c",
"Ď": "D",
"ď": "d",
"Đ": "D",
"đ": "d",
"Ē": "E",
"ē": "e",
"Ĕ": "E",
"ĕ": "e",
"Ė": "E",
"ė": "e",
"Ę": "E",
"ę": "e",
"Ě": "E",
"ě": "e",
"Ĝ": "G",
"Ǵ": "G",
"ĝ": "g",
"ǵ": "g",
"Ğ": "G",
"ğ": "g",
"Ġ": "G",
"ġ": "g",
"Ģ": "G",
"ģ": "g",
"Ĥ": "H",
"ĥ": "h",
"Ħ": "H",
"ħ": "h",
"Ḫ": "H",
"ḫ": "h",
"Ĩ": "I",
"ĩ": "i",
"Ī": "I",
"ī": "i",
"Ĭ": "I",
"ĭ": "i",
"Į": "I",
"į": "i",
"İ": "I",
"ı": "i",
"IJ": "IJ",
"ij": "ij",
"Ĵ": "J",
"ĵ": "j",
"Ķ": "K",
"ķ": "k",
"Ḱ": "K",
"ḱ": "k",
"K̆": "K",
"k̆": "k",
"Ĺ": "L",
"ĺ": "l",
"Ļ": "L",
"ļ": "l",
"Ľ": "L",
"ľ": "l",
"Ŀ": "L",
"ŀ": "l",
"Ł": "l",
"ł": "l",
"Ḿ": "M",
"ḿ": "m",
"M̆": "M",
"m̆": "m",
"Ń": "N",
"ń": "n",
"Ņ": "N",
"ņ": "n",
"Ň": "N",
"ň": "n",
"ʼn": "n",
"N̆": "N",
"n̆": "n",
"Ō": "O",
"ō": "o",
"Ŏ": "O",
"ŏ": "o",
"Ő": "O",
"ő": "o",
"Œ": "OE",
"œ": "oe",
"P̆": "P",
"p̆": "p",
"Ŕ": "R",
"ŕ": "r",
"Ŗ": "R",
"ŗ": "r",
"Ř": "R",
"ř": "r",
"R̆": "R",
"r̆": "r",
"Ȓ": "R",
"ȓ": "r",
"Ś": "S",
"ś": "s",
"Ŝ": "S",
"ŝ": "s",
"Ş": "S",
"Ș": "S",
"ș": "s",
"ş": "s",
"Š": "S",
"š": "s",
"Ţ": "T",
"ţ": "t",
"ț": "t",
"Ț": "T",
"Ť": "T",
"ť": "t",
"Ŧ": "T",
"ŧ": "t",
"T̆": "T",
"t̆": "t",
"Ũ": "U",
"ũ": "u",
"Ū": "U",
"ū": "u",
"Ŭ": "U",
"ŭ": "u",
"Ů": "U",
"ů": "u",
"Ű": "U",
"ű": "u",
"Ų": "U",
"ų": "u",
"Ȗ": "U",
"ȗ": "u",
"V̆": "V",
"v̆": "v",
"Ŵ": "W",
"ŵ": "w",
"Ẃ": "W",
"ẃ": "w",
"X̆": "X",
"x̆": "x",
"Ŷ": "Y",
"ŷ": "y",
"Ÿ": "Y",
"Y̆": "Y",
"y̆": "y",
"Ź": "Z",
"ź": "z",
"Ż": "Z",
"ż": "z",
"Ž": "Z",
"ž": "z",
"ſ": "s",
"ƒ": "f",
"Ơ": "O",
"ơ": "o",
"Ư": "U",
"ư": "u",
"Ǎ": "A",
"ǎ": "a",
"Ǐ": "I",
"ǐ": "i",
"Ǒ": "O",
"ǒ": "o",
"Ǔ": "U",
"ǔ": "u",
"Ǖ": "U",
"ǖ": "u",
"Ǘ": "U",
"ǘ": "u",
"Ǚ": "U",
"ǚ": "u",
"Ǜ": "U",
"ǜ": "u",
"Ứ": "U",
"ứ": "u",
"Ṹ": "U",
"ṹ": "u",
"Ǻ": "A",
"ǻ": "a",
"Ǽ": "AE",
"ǽ": "ae",
"Ǿ": "O",
"ǿ": "o",
"Þ": "TH",
"þ": "th",
"Ṕ": "P",
"ṕ": "p",
"Ṥ": "S",
"ṥ": "s",
"X́": "X",
"x́": "x",
"Ѓ": "Г",
"ѓ": "г",
"Ќ": "К",
"ќ": "к",
"A̋": "A",
"a̋": "a",
"E̋": "E",
"e̋": "e",
"I̋": "I",
"i̋": "i",
"Ǹ": "N",
"ǹ": "n",
"Ồ": "O",
"ồ": "o",
"Ṑ": "O",
"ṑ": "o",
"Ừ": "U",
"ừ": "u",
"Ẁ": "W",
"ẁ": "w",
"Ỳ": "Y",
"ỳ": "y",
"Ȁ": "A",
"ȁ": "a",
"Ȅ": "E",
"ȅ": "e",
"Ȉ": "I",
"ȉ": "i",
"Ȍ": "O",
"ȍ": "o",
"Ȑ": "R",
"ȑ": "r",
"Ȕ": "U",
"ȕ": "u",
"B̌": "B",
"b̌": "b",
"Č̣": "C",
"č̣": "c",
"Ê̌": "E",
"ê̌": "e",
"F̌": "F",
"f̌": "f",
"Ǧ": "G",
"ǧ": "g",
"Ȟ": "H",
"ȟ": "h",
"J̌": "J",
"ǰ": "j",
"Ǩ": "K",
"ǩ": "k",
"M̌": "M",
"m̌": "m",
"P̌": "P",
"p̌": "p",
"Q̌": "Q",
"q̌": "q",
"Ř̩": "R",
"ř̩": "r",
"Ṧ": "S",
"ṧ": "s",
"V̌": "V",
"v̌": "v",
"W̌": "W",
"w̌": "w",
"X̌": "X",
"x̌": "x",
"Y̌": "Y",
"y̌": "y",
"A̧": "A",
"a̧": "a",
"B̧": "B",
"b̧": "b",
"Ḑ": "D",
"ḑ": "d",
"Ȩ": "E",
"ȩ": "e",
"Ɛ̧": "E",
"ɛ̧": "e",
"Ḩ": "H",
"ḩ": "h",
"I̧": "I",
"i̧": "i",
"Ɨ̧": "I",
"ɨ̧": "i",
"M̧": "M",
"m̧": "m",
"O̧": "O",
"o̧": "o",
"Q̧": "Q",
"q̧": "q",
"U̧": "U",
"u̧": "u",
"X̧": "X",
"x̧": "x",
"Z̧": "Z",
"z̧": "z",
"й":"и",
"Й":"И",
"ё":"е",
"Ё":"Е",
};
var chars = Object.keys(characterMap).join('|');
var allAccents = new RegExp(chars, 'g');
var firstAccent = new RegExp(chars, '');
function matcher(match) {
return characterMap[match];
}
var removeAccents = function(string) {
return string.replace(allAccents, matcher);
};
var hasAccents = function(string) {
return !!string.match(firstAccent);
};
module.exports = removeAccents;
module.exports.has = hasAccents;
module.exports.remove = removeAccents;
/***/ }),
/***/ 3124:
/***/ (function(module) {
"use strict";
// TODO: use call-bind, is-date, is-regex, is-string, is-boolean-object, is-number-object
function toS(obj) { return Object.prototype.toString.call(obj); }
function isDate(obj) { return toS(obj) === '[object Date]'; }
function isRegExp(obj) { return toS(obj) === '[object RegExp]'; }
function isError(obj) { return toS(obj) === '[object Error]'; }
function isBoolean(obj) { return toS(obj) === '[object Boolean]'; }
function isNumber(obj) { return toS(obj) === '[object Number]'; }
function isString(obj) { return toS(obj) === '[object String]'; }
// TODO: use isarray
var isArray = Array.isArray || function isArray(xs) {
return Object.prototype.toString.call(xs) === '[object Array]';
};
// TODO: use for-each?
function forEach(xs, fn) {
if (xs.forEach) { return xs.forEach(fn); }
for (var i = 0; i < xs.length; i++) {
fn(xs[i], i, xs);
}
return void undefined;
}
// TODO: use object-keys
var objectKeys = Object.keys || function keys(obj) {
var res = [];
for (var key in obj) { res.push(key); } // eslint-disable-line no-restricted-syntax
return res;
};
// TODO: use object.hasown
var hasOwnProperty = Object.prototype.hasOwnProperty || function (obj, key) {
return key in obj;
};
function copy(src) {
if (typeof src === 'object' && src !== null) {
var dst;
if (isArray(src)) {
dst = [];
} else if (isDate(src)) {
dst = new Date(src.getTime ? src.getTime() : src);
} else if (isRegExp(src)) {
dst = new RegExp(src);
} else if (isError(src)) {
dst = { message: src.message };
} else if (isBoolean(src) || isNumber(src) || isString(src)) {
dst = Object(src);
} else if (Object.create && Object.getPrototypeOf) {
dst = Object.create(Object.getPrototypeOf(src));
} else if (src.constructor === Object) {
dst = {};
} else {
var proto = (src.constructor && src.constructor.prototype)
|| src.__proto__
|| {};
var T = function T() {}; // eslint-disable-line func-style, func-name-matching
T.prototype = proto;
dst = new T();
}
forEach(objectKeys(src), function (key) {
dst[key] = src[key];
});
return dst;
}
return src;
}
function walk(root, cb, immutable) {
var path = [];
var parents = [];
var alive = true;
return (function walker(node_) {
var node = immutable ? copy(node_) : node_;
var modifiers = {};
var keepGoing = true;
var state = {
node: node,
node_: node_,
path: [].concat(path),
parent: parents[parents.length - 1],
parents: parents,
key: path[path.length - 1],
isRoot: path.length === 0,
level: path.length,
circular: null,
update: function (x, stopHere) {
if (!state.isRoot) {
state.parent.node[state.key] = x;
}
state.node = x;
if (stopHere) { keepGoing = false; }
},
delete: function (stopHere) {
delete state.parent.node[state.key];
if (stopHere) { keepGoing = false; }
},
remove: function (stopHere) {
if (isArray(state.parent.node)) {
state.parent.node.splice(state.key, 1);
} else {
delete state.parent.node[state.key];
}
if (stopHere) { keepGoing = false; }
},
keys: null,
before: function (f) { modifiers.before = f; },
after: function (f) { modifiers.after = f; },
pre: function (f) { modifiers.pre = f; },
post: function (f) { modifiers.post = f; },
stop: function () { alive = false; },
block: function () { keepGoing = false; },
};
if (!alive) { return state; }
function updateState() {
if (typeof state.node === 'object' && state.node !== null) {
if (!state.keys || state.node_ !== state.node) {
state.keys = objectKeys(state.node);
}
state.isLeaf = state.keys.length === 0;
for (var i = 0; i < parents.length; i++) {
if (parents[i].node_ === node_) {
state.circular = parents[i];
break; // eslint-disable-line no-restricted-syntax
}
}
} else {
state.isLeaf = true;
state.keys = null;
}
state.notLeaf = !state.isLeaf;
state.notRoot = !state.isRoot;
}
updateState();
// use return values to update if defined
var ret = cb.call(state, state.node);
if (ret !== undefined && state.update) { state.update(ret); }
if (modifiers.before) { modifiers.before.call(state, state.node); }
if (!keepGoing) { return state; }
if (
typeof state.node === 'object'
&& state.node !== null
&& !state.circular
) {
parents.push(state);
updateState();
forEach(state.keys, function (key, i) {
path.push(key);
if (modifiers.pre) { modifiers.pre.call(state, state.node[key], key); }
var child = walker(state.node[key]);
if (immutable && hasOwnProperty.call(state.node, key)) {
state.node[key] = child.node;
}
child.isLast = i === state.keys.length - 1;
child.isFirst = i === 0;
if (modifiers.post) { modifiers.post.call(state, child); }
path.pop();
});
parents.pop();
}
if (modifiers.after) { modifiers.after.call(state, state.node); }
return state;
}(root)).node;
}
function Traverse(obj) {
this.value = obj;
}
Traverse.prototype.get = function (ps) {
var node = this.value;
for (var i = 0; i < ps.length; i++) {
var key = ps[i];
if (!node || !hasOwnProperty.call(node, key)) {
return void undefined;
}
node = node[key];
}
return node;
};
Traverse.prototype.has = function (ps) {
var node = this.value;
for (var i = 0; i < ps.length; i++) {
var key = ps[i];
if (!node || !hasOwnProperty.call(node, key)) {
return false;
}
node = node[key];
}
return true;
};
Traverse.prototype.set = function (ps, value) {
var node = this.value;
for (var i = 0; i < ps.length - 1; i++) {
var key = ps[i];
if (!hasOwnProperty.call(node, key)) { node[key] = {}; }
node = node[key];
}
node[ps[i]] = value;
return value;
};
Traverse.prototype.map = function (cb) {
return walk(this.value, cb, true);
};
Traverse.prototype.forEach = function (cb) {
this.value = walk(this.value, cb, false);
return this.value;
};
Traverse.prototype.reduce = function (cb, init) {
var skip = arguments.length === 1;
var acc = skip ? this.value : init;
this.forEach(function (x) {
if (!this.isRoot || !skip) {
acc = cb.call(this, acc, x);
}
});
return acc;
};
Traverse.prototype.paths = function () {
var acc = [];
this.forEach(function () {
acc.push(this.path);
});
return acc;
};
Traverse.prototype.nodes = function () {
var acc = [];
this.forEach(function () {
acc.push(this.node);
});
return acc;
};
Traverse.prototype.clone = function () {
var parents = [];
var nodes = [];
return (function clone(src) {
for (var i = 0; i < parents.length; i++) {
if (parents[i] === src) {
return nodes[i];
}
}
if (typeof src === 'object' && src !== null) {
var dst = copy(src);
parents.push(src);
nodes.push(dst);
forEach(objectKeys(src), function (key) {
dst[key] = clone(src[key]);
});
parents.pop();
nodes.pop();
return dst;
}
return src;
}(this.value));
};
function traverse(obj) {
return new Traverse(obj);
}
// TODO: replace with object.assign?
forEach(objectKeys(Traverse.prototype), function (key) {
traverse[key] = function (obj) {
var args = [].slice.call(arguments, 1);
var t = new Traverse(obj);
return t[key].apply(t, args);
};
});
module.exports = traverse;
/***/ }),
/***/ 9196:
/***/ (function(module) {
"use strict";
module.exports = window["React"];
/***/ })
/******/ });
/************************************************************************/
/******/ // The module cache
/******/ var __webpack_module_cache__ = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ var cachedModule = __webpack_module_cache__[moduleId];
/******/ if (cachedModule !== undefined) {
/******/ return cachedModule.exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = __webpack_module_cache__[moduleId] = {
/******/ // no module.id needed
/******/ // no module.loaded needed
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/************************************************************************/
/******/ /* webpack/runtime/compat get default export */
/******/ !function() {
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function() { return module['default']; } :
/******/ function() { return module; };
/******/ __webpack_require__.d(getter, { a: getter });
/******/ return getter;
/******/ };
/******/ }();
/******/
/******/ /* webpack/runtime/define property getters */
/******/ !function() {
/******/ // define getter functions for harmony exports
/******/ __webpack_require__.d = function(exports, definition) {
/******/ for(var key in definition) {
/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
/******/ }
/******/ }
/******/ };
/******/ }();
/******/
/******/ /* webpack/runtime/hasOwnProperty shorthand */
/******/ !function() {
/******/ __webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }
/******/ }();
/******/
/******/ /* webpack/runtime/make namespace object */
/******/ !function() {
/******/ // define __esModule on exports
/******/ __webpack_require__.r = function(exports) {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/ }();
/******/
/************************************************************************/
var __webpack_exports__ = {};
// This entry need to be wrapped in an IIFE because it need to be in strict mode.
!function() {
"use strict";
// ESM COMPAT FLAG
__webpack_require__.r(__webpack_exports__);
// EXPORTS
__webpack_require__.d(__webpack_exports__, {
AlignmentControl: function() { return /* reexport */ AlignmentControl; },
AlignmentToolbar: function() { return /* reexport */ AlignmentToolbar; },
Autocomplete: function() { return /* reexport */ autocomplete; },
BlockAlignmentControl: function() { return /* reexport */ BlockAlignmentControl; },
BlockAlignmentToolbar: function() { return /* reexport */ BlockAlignmentToolbar; },
BlockBreadcrumb: function() { return /* reexport */ block_breadcrumb; },
BlockCanvas: function() { return /* reexport */ block_canvas; },
BlockColorsStyleSelector: function() { return /* reexport */ color_style_selector; },
BlockContextProvider: function() { return /* reexport */ BlockContextProvider; },
BlockControls: function() { return /* reexport */ block_controls; },
BlockEdit: function() { return /* reexport */ BlockEdit; },
BlockEditorKeyboardShortcuts: function() { return /* reexport */ keyboard_shortcuts; },
BlockEditorProvider: function() { return /* reexport */ provider; },
BlockFormatControls: function() { return /* reexport */ BlockFormatControls; },
BlockIcon: function() { return /* reexport */ block_icon; },
BlockInspector: function() { return /* reexport */ block_inspector; },
BlockList: function() { return /* reexport */ BlockList; },
BlockMover: function() { return /* reexport */ block_mover; },
BlockNavigationDropdown: function() { return /* reexport */ dropdown; },
BlockPreview: function() { return /* reexport */ block_preview; },
BlockSelectionClearer: function() { return /* reexport */ BlockSelectionClearer; },
BlockSettingsMenu: function() { return /* reexport */ block_settings_menu; },
BlockSettingsMenuControls: function() { return /* reexport */ block_settings_menu_controls; },
BlockStyles: function() { return /* reexport */ block_styles; },
BlockTitle: function() { return /* reexport */ BlockTitle; },
BlockToolbar: function() { return /* reexport */ block_toolbar; },
BlockTools: function() { return /* reexport */ BlockTools; },
BlockVerticalAlignmentControl: function() { return /* reexport */ BlockVerticalAlignmentControl; },
BlockVerticalAlignmentToolbar: function() { return /* reexport */ BlockVerticalAlignmentToolbar; },
ButtonBlockAppender: function() { return /* reexport */ button_block_appender; },
ButtonBlockerAppender: function() { return /* reexport */ ButtonBlockerAppender; },
ColorPalette: function() { return /* reexport */ color_palette; },
ColorPaletteControl: function() { return /* reexport */ ColorPaletteControl; },
ContrastChecker: function() { return /* reexport */ contrast_checker; },
CopyHandler: function() { return /* reexport */ copy_handler; },
DefaultBlockAppender: function() { return /* reexport */ default_block_appender; },
FontSizePicker: function() { return /* reexport */ font_size_picker; },
HeadingLevelDropdown: function() { return /* reexport */ HeadingLevelDropdown; },
HeightControl: function() { return /* reexport */ HeightControl; },
InnerBlocks: function() { return /* reexport */ inner_blocks; },
Inserter: function() { return /* reexport */ inserter; },
InspectorAdvancedControls: function() { return /* reexport */ InspectorAdvancedControls; },
InspectorControls: function() { return /* reexport */ inspector_controls; },
JustifyContentControl: function() { return /* reexport */ JustifyContentControl; },
JustifyToolbar: function() { return /* reexport */ JustifyToolbar; },
LineHeightControl: function() { return /* reexport */ line_height_control; },
MediaPlaceholder: function() { return /* reexport */ media_placeholder; },
MediaReplaceFlow: function() { return /* reexport */ media_replace_flow; },
MediaUpload: function() { return /* reexport */ media_upload; },
MediaUploadCheck: function() { return /* reexport */ check; },
MultiSelectScrollIntoView: function() { return /* reexport */ MultiSelectScrollIntoView; },
NavigableToolbar: function() { return /* reexport */ navigable_toolbar; },
ObserveTyping: function() { return /* reexport */ observe_typing; },
PanelColorSettings: function() { return /* reexport */ panel_color_settings; },
PlainText: function() { return /* reexport */ plain_text; },
ReusableBlocksRenameHint: function() { return /* reexport */ ReusableBlocksRenameHint; },
RichText: function() { return /* reexport */ rich_text; },
RichTextShortcut: function() { return /* reexport */ RichTextShortcut; },
RichTextToolbarButton: function() { return /* reexport */ RichTextToolbarButton; },
SETTINGS_DEFAULTS: function() { return /* reexport */ SETTINGS_DEFAULTS; },
SkipToSelectedBlock: function() { return /* reexport */ skip_to_selected_block; },
ToolSelector: function() { return /* reexport */ tool_selector; },
Typewriter: function() { return /* reexport */ typewriter; },
URLInput: function() { return /* reexport */ url_input; },
URLInputButton: function() { return /* reexport */ url_input_button; },
URLPopover: function() { return /* reexport */ url_popover; },
Warning: function() { return /* reexport */ warning; },
WritingFlow: function() { return /* reexport */ writing_flow; },
__experimentalBlockAlignmentMatrixControl: function() { return /* reexport */ block_alignment_matrix_control; },
__experimentalBlockFullHeightAligmentControl: function() { return /* reexport */ block_full_height_alignment_control; },
__experimentalBlockPatternSetup: function() { return /* reexport */ block_pattern_setup; },
__experimentalBlockPatternsList: function() { return /* reexport */ block_patterns_list; },
__experimentalBlockVariationPicker: function() { return /* reexport */ block_variation_picker; },
__experimentalBlockVariationTransforms: function() { return /* reexport */ block_variation_transforms; },
__experimentalBorderRadiusControl: function() { return /* reexport */ BorderRadiusControl; },
__experimentalColorGradientControl: function() { return /* reexport */ control; },
__experimentalColorGradientSettingsDropdown: function() { return /* reexport */ ColorGradientSettingsDropdown; },
__experimentalDateFormatPicker: function() { return /* reexport */ DateFormatPicker; },
__experimentalDuotoneControl: function() { return /* reexport */ duotone_control; },
__experimentalFontAppearanceControl: function() { return /* reexport */ FontAppearanceControl; },
__experimentalFontFamilyControl: function() { return /* reexport */ FontFamilyControl; },
__experimentalGetBorderClassesAndStyles: function() { return /* reexport */ getBorderClassesAndStyles; },
__experimentalGetColorClassesAndStyles: function() { return /* reexport */ getColorClassesAndStyles; },
__experimentalGetElementClassName: function() { return /* reexport */ __experimentalGetElementClassName; },
__experimentalGetGapCSSValue: function() { return /* reexport */ getGapCSSValue; },
__experimentalGetGradientClass: function() { return /* reexport */ __experimentalGetGradientClass; },
__experimentalGetGradientObjectByGradientValue: function() { return /* reexport */ __experimentalGetGradientObjectByGradientValue; },
__experimentalGetMatchingVariation: function() { return /* reexport */ __experimentalGetMatchingVariation; },
__experimentalGetSpacingClassesAndStyles: function() { return /* reexport */ getSpacingClassesAndStyles; },
__experimentalImageEditor: function() { return /* reexport */ ImageEditor; },
__experimentalImageSizeControl: function() { return /* reexport */ ImageSizeControl; },
__experimentalImageURLInputUI: function() { return /* reexport */ ImageURLInputUI; },
__experimentalInspectorPopoverHeader: function() { return /* reexport */ InspectorPopoverHeader; },
__experimentalLetterSpacingControl: function() { return /* reexport */ LetterSpacingControl; },
__experimentalLibrary: function() { return /* reexport */ library; },
__experimentalLinkControl: function() { return /* reexport */ link_control; },
__experimentalLinkControlSearchInput: function() { return /* reexport */ search_input; },
__experimentalLinkControlSearchItem: function() { return /* reexport */ search_item; },
__experimentalLinkControlSearchResults: function() { return /* reexport */ LinkControlSearchResults; },
__experimentalListView: function() { return /* reexport */ components_list_view; },
__experimentalPanelColorGradientSettings: function() { return /* reexport */ panel_color_gradient_settings; },
__experimentalPreviewOptions: function() { return /* reexport */ PreviewOptions; },
__experimentalPublishDateTimePicker: function() { return /* reexport */ publish_date_time_picker; },
__experimentalRecursionProvider: function() { return /* reexport */ RecursionProvider; },
__experimentalResponsiveBlockControl: function() { return /* reexport */ responsive_block_control; },
__experimentalSpacingSizesControl: function() { return /* reexport */ SpacingSizesControl; },
__experimentalTextDecorationControl: function() { return /* reexport */ TextDecorationControl; },
__experimentalTextTransformControl: function() { return /* reexport */ TextTransformControl; },
__experimentalUnitControl: function() { return /* reexport */ UnitControl; },
__experimentalUseBlockOverlayActive: function() { return /* reexport */ useBlockOverlayActive; },
__experimentalUseBlockPreview: function() { return /* reexport */ useBlockPreview; },
__experimentalUseBorderProps: function() { return /* reexport */ useBorderProps; },
__experimentalUseColorProps: function() { return /* reexport */ useColorProps; },
__experimentalUseCustomSides: function() { return /* reexport */ useCustomSides; },
__experimentalUseGradient: function() { return /* reexport */ __experimentalUseGradient; },
__experimentalUseHasRecursion: function() { return /* reexport */ useHasRecursion; },
__experimentalUseMultipleOriginColorsAndGradients: function() { return /* reexport */ useMultipleOriginColorsAndGradients; },
__experimentalUseResizeCanvas: function() { return /* reexport */ useResizeCanvas; },
__experimentalWritingModeControl: function() { return /* reexport */ WritingModeControl; },
__unstableBlockNameContext: function() { return /* reexport */ block_name_context; },
__unstableBlockSettingsMenuFirstItem: function() { return /* reexport */ block_settings_menu_first_item; },
__unstableBlockToolbarLastItem: function() { return /* reexport */ block_toolbar_last_item; },
__unstableEditorStyles: function() { return /* reexport */ EditorStyles; },
__unstableIframe: function() { return /* reexport */ iframe; },
__unstableInserterMenuExtension: function() { return /* reexport */ inserter_menu_extension; },
__unstableRichTextInputEvent: function() { return /* reexport */ __unstableRichTextInputEvent; },
__unstableUseBlockSelectionClearer: function() { return /* reexport */ useBlockSelectionClearer; },
__unstableUseClipboardHandler: function() { return /* reexport */ useClipboardHandler; },
__unstableUseMouseMoveTypingReset: function() { return /* reexport */ useMouseMoveTypingReset; },
__unstableUseTypewriter: function() { return /* reexport */ useTypewriter; },
__unstableUseTypingObserver: function() { return /* reexport */ useTypingObserver; },
createCustomColorsHOC: function() { return /* reexport */ createCustomColorsHOC; },
getColorClassName: function() { return /* reexport */ getColorClassName; },
getColorObjectByAttributeValues: function() { return /* reexport */ getColorObjectByAttributeValues; },
getColorObjectByColorValue: function() { return /* reexport */ getColorObjectByColorValue; },
getComputedFluidTypographyValue: function() { return /* reexport */ getComputedFluidTypographyValue; },
getCustomValueFromPreset: function() { return /* reexport */ getCustomValueFromPreset; },
getFontSize: function() { return /* reexport */ utils_getFontSize; },
getFontSizeClass: function() { return /* reexport */ getFontSizeClass; },
getFontSizeObjectByValue: function() { return /* reexport */ utils_getFontSizeObjectByValue; },
getGradientSlugByValue: function() { return /* reexport */ getGradientSlugByValue; },
getGradientValueBySlug: function() { return /* reexport */ getGradientValueBySlug; },
getPxFromCssUnit: function() { return /* reexport */ parse_css_unit_to_px; },
getSpacingPresetCssVar: function() { return /* reexport */ getSpacingPresetCssVar; },
getTypographyClassesAndStyles: function() { return /* reexport */ getTypographyClassesAndStyles; },
isValueSpacingPreset: function() { return /* reexport */ isValueSpacingPreset; },
privateApis: function() { return /* reexport */ privateApis; },
store: function() { return /* reexport */ store; },
storeConfig: function() { return /* reexport */ storeConfig; },
transformStyles: function() { return /* reexport */ transform_styles; },
useBlockCommands: function() { return /* reexport */ useBlockCommands; },
useBlockDisplayInformation: function() { return /* reexport */ useBlockDisplayInformation; },
useBlockEditContext: function() { return /* reexport */ useBlockEditContext; },
useBlockEditingMode: function() { return /* reexport */ useBlockEditingMode; },
useBlockProps: function() { return /* reexport */ useBlockProps; },
useCachedTruthy: function() { return /* reexport */ useCachedTruthy; },
useInnerBlocksProps: function() { return /* reexport */ useInnerBlocksProps; },
useSetting: function() { return /* reexport */ use_setting_useSetting; },
withColorContext: function() { return /* reexport */ with_color_context; },
withColors: function() { return /* reexport */ withColors; },
withFontSizes: function() { return /* reexport */ with_font_sizes; }
});
// NAMESPACE OBJECT: ./node_modules/@wordpress/block-editor/build-module/store/selectors.js
var selectors_namespaceObject = {};
__webpack_require__.r(selectors_namespaceObject);
__webpack_require__.d(selectors_namespaceObject, {
__experimentalGetActiveBlockIdByBlockNames: function() { return __experimentalGetActiveBlockIdByBlockNames; },
__experimentalGetAllowedBlocks: function() { return __experimentalGetAllowedBlocks; },
__experimentalGetAllowedPatterns: function() { return __experimentalGetAllowedPatterns; },
__experimentalGetBlockListSettingsForBlocks: function() { return __experimentalGetBlockListSettingsForBlocks; },
__experimentalGetDirectInsertBlock: function() { return __experimentalGetDirectInsertBlock; },
__experimentalGetGlobalBlocksByName: function() { return __experimentalGetGlobalBlocksByName; },
__experimentalGetLastBlockAttributeChanges: function() { return __experimentalGetLastBlockAttributeChanges; },
__experimentalGetParsedPattern: function() { return __experimentalGetParsedPattern; },
__experimentalGetPatternTransformItems: function() { return __experimentalGetPatternTransformItems; },
__experimentalGetPatternsByBlockTypes: function() { return __experimentalGetPatternsByBlockTypes; },
__experimentalGetReusableBlockTitle: function() { return __experimentalGetReusableBlockTitle; },
__experimentalUserPatternCategories: function() { return __experimentalUserPatternCategories; },
__unstableGetBlockWithoutInnerBlocks: function() { return __unstableGetBlockWithoutInnerBlocks; },
__unstableGetClientIdWithClientIdsTree: function() { return __unstableGetClientIdWithClientIdsTree; },
__unstableGetClientIdsTree: function() { return __unstableGetClientIdsTree; },
__unstableGetContentLockingParent: function() { return __unstableGetContentLockingParent; },
__unstableGetEditorMode: function() { return __unstableGetEditorMode; },
__unstableGetSelectedBlocksWithPartialSelection: function() { return __unstableGetSelectedBlocksWithPartialSelection; },
__unstableGetTemporarilyEditingAsBlocks: function() { return __unstableGetTemporarilyEditingAsBlocks; },
__unstableGetVisibleBlocks: function() { return __unstableGetVisibleBlocks; },
__unstableHasActiveBlockOverlayActive: function() { return __unstableHasActiveBlockOverlayActive; },
__unstableIsFullySelected: function() { return __unstableIsFullySelected; },
__unstableIsLastBlockChangeIgnored: function() { return __unstableIsLastBlockChangeIgnored; },
__unstableIsSelectionCollapsed: function() { return __unstableIsSelectionCollapsed; },
__unstableIsSelectionMergeable: function() { return __unstableIsSelectionMergeable; },
__unstableIsWithinBlockOverlay: function() { return __unstableIsWithinBlockOverlay; },
__unstableSelectionHasUnmergeableBlock: function() { return __unstableSelectionHasUnmergeableBlock; },
areInnerBlocksControlled: function() { return areInnerBlocksControlled; },
canEditBlock: function() { return canEditBlock; },
canInsertBlockType: function() { return canInsertBlockType; },
canInsertBlocks: function() { return canInsertBlocks; },
canLockBlockType: function() { return canLockBlockType; },
canMoveBlock: function() { return canMoveBlock; },
canMoveBlocks: function() { return canMoveBlocks; },
canRemoveBlock: function() { return canRemoveBlock; },
canRemoveBlocks: function() { return canRemoveBlocks; },
didAutomaticChange: function() { return didAutomaticChange; },
getAdjacentBlockClientId: function() { return getAdjacentBlockClientId; },
getAllowedBlocks: function() { return getAllowedBlocks; },
getBlock: function() { return getBlock; },
getBlockAttributes: function() { return getBlockAttributes; },
getBlockCount: function() { return getBlockCount; },
getBlockEditingMode: function() { return getBlockEditingMode; },
getBlockHierarchyRootClientId: function() { return getBlockHierarchyRootClientId; },
getBlockIndex: function() { return getBlockIndex; },
getBlockInsertionPoint: function() { return getBlockInsertionPoint; },
getBlockListSettings: function() { return getBlockListSettings; },
getBlockMode: function() { return getBlockMode; },
getBlockName: function() { return getBlockName; },
getBlockNamesByClientId: function() { return getBlockNamesByClientId; },
getBlockOrder: function() { return getBlockOrder; },
getBlockParents: function() { return getBlockParents; },
getBlockParentsByBlockName: function() { return getBlockParentsByBlockName; },
getBlockRootClientId: function() { return getBlockRootClientId; },
getBlockSelectionEnd: function() { return getBlockSelectionEnd; },
getBlockSelectionStart: function() { return getBlockSelectionStart; },
getBlockTransformItems: function() { return getBlockTransformItems; },
getBlocks: function() { return getBlocks; },
getBlocksByClientId: function() { return getBlocksByClientId; },
getClientIdsOfDescendants: function() { return getClientIdsOfDescendants; },
getClientIdsWithDescendants: function() { return getClientIdsWithDescendants; },
getDirectInsertBlock: function() { return getDirectInsertBlock; },
getDraggedBlockClientIds: function() { return getDraggedBlockClientIds; },
getFirstMultiSelectedBlockClientId: function() { return getFirstMultiSelectedBlockClientId; },
getGlobalBlockCount: function() { return getGlobalBlockCount; },
getInserterItems: function() { return getInserterItems; },
getLastMultiSelectedBlockClientId: function() { return getLastMultiSelectedBlockClientId; },
getLowestCommonAncestorWithSelectedBlock: function() { return getLowestCommonAncestorWithSelectedBlock; },
getMultiSelectedBlockClientIds: function() { return getMultiSelectedBlockClientIds; },
getMultiSelectedBlocks: function() { return getMultiSelectedBlocks; },
getMultiSelectedBlocksEndClientId: function() { return getMultiSelectedBlocksEndClientId; },
getMultiSelectedBlocksStartClientId: function() { return getMultiSelectedBlocksStartClientId; },
getNextBlockClientId: function() { return getNextBlockClientId; },
getPatternsByBlockTypes: function() { return getPatternsByBlockTypes; },
getPreviousBlockClientId: function() { return getPreviousBlockClientId; },
getSelectedBlock: function() { return getSelectedBlock; },
getSelectedBlockClientId: function() { return getSelectedBlockClientId; },
getSelectedBlockClientIds: function() { return getSelectedBlockClientIds; },
getSelectedBlockCount: function() { return getSelectedBlockCount; },
getSelectedBlocksInitialCaretPosition: function() { return getSelectedBlocksInitialCaretPosition; },
getSelectionEnd: function() { return getSelectionEnd; },
getSelectionStart: function() { return getSelectionStart; },
getSettings: function() { return getSettings; },
getTemplate: function() { return getTemplate; },
getTemplateLock: function() { return getTemplateLock; },
hasBlockMovingClientId: function() { return selectors_hasBlockMovingClientId; },
hasDraggedInnerBlock: function() { return hasDraggedInnerBlock; },
hasInserterItems: function() { return hasInserterItems; },
hasMultiSelection: function() { return hasMultiSelection; },
hasSelectedBlock: function() { return hasSelectedBlock; },
hasSelectedInnerBlock: function() { return hasSelectedInnerBlock; },
isAncestorBeingDragged: function() { return isAncestorBeingDragged; },
isAncestorMultiSelected: function() { return isAncestorMultiSelected; },
isBlockBeingDragged: function() { return isBlockBeingDragged; },
isBlockHighlighted: function() { return isBlockHighlighted; },
isBlockInsertionPointVisible: function() { return isBlockInsertionPointVisible; },
isBlockMultiSelected: function() { return isBlockMultiSelected; },
isBlockSelected: function() { return isBlockSelected; },
isBlockValid: function() { return isBlockValid; },
isBlockVisible: function() { return isBlockVisible; },
isBlockWithinSelection: function() { return isBlockWithinSelection; },
isCaretWithinFormattedText: function() { return isCaretWithinFormattedText; },
isDraggingBlocks: function() { return isDraggingBlocks; },
isFirstMultiSelectedBlock: function() { return isFirstMultiSelectedBlock; },
isGroupable: function() { return isGroupable; },
isLastBlockChangePersistent: function() { return isLastBlockChangePersistent; },
isMultiSelecting: function() { return selectors_isMultiSelecting; },
isNavigationMode: function() { return isNavigationMode; },
isSelectionEnabled: function() { return selectors_isSelectionEnabled; },
isTyping: function() { return selectors_isTyping; },
isUngroupable: function() { return isUngroupable; },
isValidTemplate: function() { return isValidTemplate; },
wasBlockJustInserted: function() { return wasBlockJustInserted; }
});
// NAMESPACE OBJECT: ./node_modules/@wordpress/block-editor/build-module/store/private-actions.js
var private_actions_namespaceObject = {};
__webpack_require__.r(private_actions_namespaceObject);
__webpack_require__.d(private_actions_namespaceObject, {
__experimentalUpdateSettings: function() { return __experimentalUpdateSettings; },
clearBlockRemovalPrompt: function() { return clearBlockRemovalPrompt; },
deleteStyleOverride: function() { return deleteStyleOverride; },
ensureDefaultBlock: function() { return ensureDefaultBlock; },
hideBlockInterface: function() { return hideBlockInterface; },
privateRemoveBlocks: function() { return privateRemoveBlocks; },
setBlockRemovalRules: function() { return setBlockRemovalRules; },
setOpenedBlockSettingsMenu: function() { return setOpenedBlockSettingsMenu; },
setStyleOverride: function() { return setStyleOverride; },
showBlockInterface: function() { return showBlockInterface; }
});
// NAMESPACE OBJECT: ./node_modules/@wordpress/block-editor/build-module/store/private-selectors.js
var private_selectors_namespaceObject = {};
__webpack_require__.r(private_selectors_namespaceObject);
__webpack_require__.d(private_selectors_namespaceObject, {
getBlockRemovalRules: function() { return getBlockRemovalRules; },
getEnabledBlockParents: function() { return getEnabledBlockParents; },
getEnabledClientIdsTree: function() { return getEnabledClientIdsTree; },
getInserterMediaCategories: function() { return getInserterMediaCategories; },
getLastInsertedBlocksClientIds: function() { return getLastInsertedBlocksClientIds; },
getOpenedBlockSettingsMenu: function() { return getOpenedBlockSettingsMenu; },
getRegisteredInserterMediaCategories: function() { return getRegisteredInserterMediaCategories; },
getRemovalPromptData: function() { return getRemovalPromptData; },
getStyleOverrides: function() { return getStyleOverrides; },
isBlockInterfaceHidden: function() { return private_selectors_isBlockInterfaceHidden; },
isBlockSubtreeDisabled: function() { return isBlockSubtreeDisabled; }
});
// NAMESPACE OBJECT: ./node_modules/@wordpress/block-editor/build-module/store/actions.js
var actions_namespaceObject = {};
__webpack_require__.r(actions_namespaceObject);
__webpack_require__.d(actions_namespaceObject, {
__unstableDeleteSelection: function() { return __unstableDeleteSelection; },
__unstableExpandSelection: function() { return __unstableExpandSelection; },
__unstableMarkAutomaticChange: function() { return __unstableMarkAutomaticChange; },
__unstableMarkLastChangeAsPersistent: function() { return __unstableMarkLastChangeAsPersistent; },
__unstableMarkNextChangeAsNotPersistent: function() { return __unstableMarkNextChangeAsNotPersistent; },
__unstableSaveReusableBlock: function() { return __unstableSaveReusableBlock; },
__unstableSetEditorMode: function() { return __unstableSetEditorMode; },
__unstableSetTemporarilyEditingAsBlocks: function() { return __unstableSetTemporarilyEditingAsBlocks; },
__unstableSplitSelection: function() { return __unstableSplitSelection; },
clearSelectedBlock: function() { return clearSelectedBlock; },
duplicateBlocks: function() { return duplicateBlocks; },
enterFormattedText: function() { return enterFormattedText; },
exitFormattedText: function() { return exitFormattedText; },
flashBlock: function() { return flashBlock; },
hideInsertionPoint: function() { return hideInsertionPoint; },
insertAfterBlock: function() { return insertAfterBlock; },
insertBeforeBlock: function() { return insertBeforeBlock; },
insertBlock: function() { return insertBlock; },
insertBlocks: function() { return insertBlocks; },
insertDefaultBlock: function() { return insertDefaultBlock; },
mergeBlocks: function() { return mergeBlocks; },
moveBlockToPosition: function() { return moveBlockToPosition; },
moveBlocksDown: function() { return moveBlocksDown; },
moveBlocksToPosition: function() { return moveBlocksToPosition; },
moveBlocksUp: function() { return moveBlocksUp; },
multiSelect: function() { return multiSelect; },
receiveBlocks: function() { return receiveBlocks; },
registerInserterMediaCategory: function() { return registerInserterMediaCategory; },
removeBlock: function() { return removeBlock; },
removeBlocks: function() { return removeBlocks; },
replaceBlock: function() { return replaceBlock; },
replaceBlocks: function() { return replaceBlocks; },
replaceInnerBlocks: function() { return replaceInnerBlocks; },
resetBlocks: function() { return resetBlocks; },
resetSelection: function() { return resetSelection; },
selectBlock: function() { return selectBlock; },
selectNextBlock: function() { return selectNextBlock; },
selectPreviousBlock: function() { return selectPreviousBlock; },
selectionChange: function() { return selectionChange; },
setBlockEditingMode: function() { return setBlockEditingMode; },
setBlockMovingClientId: function() { return setBlockMovingClientId; },
setBlockVisibility: function() { return setBlockVisibility; },
setHasControlledInnerBlocks: function() { return setHasControlledInnerBlocks; },
setNavigationMode: function() { return setNavigationMode; },
setTemplateValidity: function() { return setTemplateValidity; },
showInsertionPoint: function() { return showInsertionPoint; },
startDraggingBlocks: function() { return startDraggingBlocks; },
startMultiSelect: function() { return startMultiSelect; },
startTyping: function() { return startTyping; },
stopDraggingBlocks: function() { return stopDraggingBlocks; },
stopMultiSelect: function() { return stopMultiSelect; },
stopTyping: function() { return stopTyping; },
synchronizeTemplate: function() { return synchronizeTemplate; },
toggleBlockHighlight: function() { return toggleBlockHighlight; },
toggleBlockMode: function() { return toggleBlockMode; },
toggleSelection: function() { return toggleSelection; },
unsetBlockEditingMode: function() { return unsetBlockEditingMode; },
updateBlock: function() { return updateBlock; },
updateBlockAttributes: function() { return updateBlockAttributes; },
updateBlockListSettings: function() { return updateBlockListSettings; },
updateSettings: function() { return updateSettings; },
validateBlocksToTemplate: function() { return validateBlocksToTemplate; }
});
// NAMESPACE OBJECT: ./node_modules/@wordpress/block-editor/build-module/components/global-styles/index.js
var global_styles_namespaceObject = {};
__webpack_require__.r(global_styles_namespaceObject);
__webpack_require__.d(global_styles_namespaceObject, {
AdvancedPanel: function() { return AdvancedPanel; },
BorderPanel: function() { return BorderPanel; },
ColorPanel: function() { return ColorPanel; },
DimensionsPanel: function() { return DimensionsPanel; },
EffectsPanel: function() { return EffectsPanel; },
FiltersPanel: function() { return FiltersPanel; },
GlobalStylesContext: function() { return GlobalStylesContext; },
ImageSettingsPanel: function() { return ImageSettingsPanel; },
TypographyPanel: function() { return TypographyPanel; },
areGlobalStyleConfigsEqual: function() { return areGlobalStyleConfigsEqual; },
getBlockCSSSelector: function() { return getBlockCSSSelector; },
getLayoutStyles: function() { return getLayoutStyles; },
useGlobalSetting: function() { return useGlobalSetting; },
useGlobalStyle: function() { return useGlobalStyle; },
useGlobalStylesOutput: function() { return useGlobalStylesOutput; },
useGlobalStylesOutputWithConfig: function() { return useGlobalStylesOutputWithConfig; },
useGlobalStylesReset: function() { return useGlobalStylesReset; },
useHasBorderPanel: function() { return useHasBorderPanel; },
useHasColorPanel: function() { return useHasColorPanel; },
useHasDimensionsPanel: function() { return useHasDimensionsPanel; },
useHasEffectsPanel: function() { return useHasEffectsPanel; },
useHasFiltersPanel: function() { return useHasFiltersPanel; },
useHasImageSettingsPanel: function() { return useHasImageSettingsPanel; },
useHasTypographyPanel: function() { return useHasTypographyPanel; },
useSettingsForBlockElement: function() { return useSettingsForBlockElement; }
});
;// CONCATENATED MODULE: external ["wp","blocks"]
var external_wp_blocks_namespaceObject = window["wp"]["blocks"];
;// CONCATENATED MODULE: external ["wp","hooks"]
var external_wp_hooks_namespaceObject = window["wp"]["hooks"];
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/hooks/compat.js
/**
* WordPress dependencies
*/
function migrateLightBlockWrapper(settings) {
const {
apiVersion = 1
} = settings;
if (apiVersion < 2 && (0,external_wp_blocks_namespaceObject.hasBlockSupport)(settings, 'lightBlockWrapper', false)) {
settings.apiVersion = 2;
}
return settings;
}
(0,external_wp_hooks_namespaceObject.addFilter)('blocks.registerBlockType', 'core/compat/migrateLightBlockWrapper', migrateLightBlockWrapper);
;// CONCATENATED MODULE: external ["wp","element"]
var external_wp_element_namespaceObject = window["wp"]["element"];
// EXTERNAL MODULE: ./node_modules/classnames/index.js
var classnames = __webpack_require__(4403);
var classnames_default = /*#__PURE__*/__webpack_require__.n(classnames);
;// CONCATENATED MODULE: external ["wp","compose"]
var external_wp_compose_namespaceObject = window["wp"]["compose"];
;// CONCATENATED MODULE: external ["wp","components"]
var external_wp_components_namespaceObject = window["wp"]["components"];
;// CONCATENATED MODULE: external ["wp","data"]
var external_wp_data_namespaceObject = window["wp"]["data"];
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-controls/groups.js
/**
* WordPress dependencies
*/
const BlockControlsDefault = (0,external_wp_components_namespaceObject.createSlotFill)('BlockControls');
const BlockControlsBlock = (0,external_wp_components_namespaceObject.createSlotFill)('BlockControlsBlock');
const BlockControlsInline = (0,external_wp_components_namespaceObject.createSlotFill)('BlockFormatControls');
const BlockControlsOther = (0,external_wp_components_namespaceObject.createSlotFill)('BlockControlsOther');
const BlockControlsParent = (0,external_wp_components_namespaceObject.createSlotFill)('BlockControlsParent');
const groups = {
default: BlockControlsDefault,
block: BlockControlsBlock,
inline: BlockControlsInline,
other: BlockControlsOther,
parent: BlockControlsParent
};
/* harmony default export */ var block_controls_groups = (groups);
// EXTERNAL MODULE: ./node_modules/fast-deep-equal/es6/index.js
var es6 = __webpack_require__(5619);
var es6_default = /*#__PURE__*/__webpack_require__.n(es6);
;// CONCATENATED MODULE: external ["wp","i18n"]
var external_wp_i18n_namespaceObject = window["wp"]["i18n"];
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/store/defaults.js
/**
* WordPress dependencies
*/
const PREFERENCES_DEFAULTS = {
insertUsage: {}
};
/**
* The default editor settings
*
* @typedef {Object} SETTINGS_DEFAULT
* @property {boolean} alignWide Enable/Disable Wide/Full Alignments
* @property {boolean} supportsLayout Enable/disable layouts support in container blocks.
* @property {boolean} imageEditing Image Editing settings set to false to disable.
* @property {Array} imageSizes Available image sizes
* @property {number} maxWidth Max width to constraint resizing
* @property {boolean|Array} allowedBlockTypes Allowed block types
* @property {boolean} hasFixedToolbar Whether or not the editor toolbar is fixed
* @property {boolean} distractionFree Whether or not the editor UI is distraction free
* @property {boolean} focusMode Whether the focus mode is enabled or not
* @property {Array} styles Editor Styles
* @property {boolean} keepCaretInsideBlock Whether caret should move between blocks in edit mode
* @property {string} bodyPlaceholder Empty post placeholder
* @property {string} titlePlaceholder Empty title placeholder
* @property {boolean} canLockBlocks Whether the user can manage Block Lock state
* @property {boolean} codeEditingEnabled Whether or not the user can switch to the code editor
* @property {boolean} generateAnchors Enable/Disable auto anchor generation for Heading blocks
* @property {boolean} enableOpenverseMediaCategory Enable/Disable the Openverse media category in the inserter.
* @property {boolean} clearBlockSelection Whether the block editor should clear selection on mousedown when a block is not clicked.
* @property {boolean} __experimentalCanUserUseUnfilteredHTML Whether the user should be able to use unfiltered HTML or the HTML should be filtered e.g., to remove elements considered insecure like iframes.
* @property {boolean} __experimentalBlockDirectory Whether the user has enabled the Block Directory
* @property {Array} __experimentalBlockPatterns Array of objects representing the block patterns
* @property {Array} __experimentalBlockPatternCategories Array of objects representing the block pattern categories
* @property {boolean} __unstableGalleryWithImageBlocks Whether the user has enabled the refactored gallery block which uses InnerBlocks
*/
const SETTINGS_DEFAULTS = {
alignWide: false,
supportsLayout: true,
// colors setting is not used anymore now defaults are passed from theme.json on the server and core has its own defaults.
// The setting is only kept for backward compatibility purposes.
colors: [{
name: (0,external_wp_i18n_namespaceObject.__)('Black'),
slug: 'black',
color: '#000000'
}, {
name: (0,external_wp_i18n_namespaceObject.__)('Cyan bluish gray'),
slug: 'cyan-bluish-gray',
color: '#abb8c3'
}, {
name: (0,external_wp_i18n_namespaceObject.__)('White'),
slug: 'white',
color: '#ffffff'
}, {
name: (0,external_wp_i18n_namespaceObject.__)('Pale pink'),
slug: 'pale-pink',
color: '#f78da7'
}, {
name: (0,external_wp_i18n_namespaceObject.__)('Vivid red'),
slug: 'vivid-red',
color: '#cf2e2e'
}, {
name: (0,external_wp_i18n_namespaceObject.__)('Luminous vivid orange'),
slug: 'luminous-vivid-orange',
color: '#ff6900'
}, {
name: (0,external_wp_i18n_namespaceObject.__)('Luminous vivid amber'),
slug: 'luminous-vivid-amber',
color: '#fcb900'
}, {
name: (0,external_wp_i18n_namespaceObject.__)('Light green cyan'),
slug: 'light-green-cyan',
color: '#7bdcb5'
}, {
name: (0,external_wp_i18n_namespaceObject.__)('Vivid green cyan'),
slug: 'vivid-green-cyan',
color: '#00d084'
}, {
name: (0,external_wp_i18n_namespaceObject.__)('Pale cyan blue'),
slug: 'pale-cyan-blue',
color: '#8ed1fc'
}, {
name: (0,external_wp_i18n_namespaceObject.__)('Vivid cyan blue'),
slug: 'vivid-cyan-blue',
color: '#0693e3'
}, {
name: (0,external_wp_i18n_namespaceObject.__)('Vivid purple'),
slug: 'vivid-purple',
color: '#9b51e0'
}],
// fontSizes setting is not used anymore now defaults are passed from theme.json on the server and core has its own defaults.
// The setting is only kept for backward compatibility purposes.
fontSizes: [{
name: (0,external_wp_i18n_namespaceObject._x)('Small', 'font size name'),
size: 13,
slug: 'small'
}, {
name: (0,external_wp_i18n_namespaceObject._x)('Normal', 'font size name'),
size: 16,
slug: 'normal'
}, {
name: (0,external_wp_i18n_namespaceObject._x)('Medium', 'font size name'),
size: 20,
slug: 'medium'
}, {
name: (0,external_wp_i18n_namespaceObject._x)('Large', 'font size name'),
size: 36,
slug: 'large'
}, {
name: (0,external_wp_i18n_namespaceObject._x)('Huge', 'font size name'),
size: 42,
slug: 'huge'
}],
// Image default size slug.
imageDefaultSize: 'large',
imageSizes: [{
slug: 'thumbnail',
name: (0,external_wp_i18n_namespaceObject.__)('Thumbnail')
}, {
slug: 'medium',
name: (0,external_wp_i18n_namespaceObject.__)('Medium')
}, {
slug: 'large',
name: (0,external_wp_i18n_namespaceObject.__)('Large')
}, {
slug: 'full',
name: (0,external_wp_i18n_namespaceObject.__)('Full Size')
}],
// Allow plugin to disable Image Editor if need be.
imageEditing: true,
// This is current max width of the block inner area
// It's used to constraint image resizing and this value could be overridden later by themes
maxWidth: 580,
// Allowed block types for the editor, defaulting to true (all supported).
allowedBlockTypes: true,
// Maximum upload size in bytes allowed for the site.
maxUploadFileSize: 0,
// List of allowed mime types and file extensions.
allowedMimeTypes: null,
// Allows to disable block locking interface.
canLockBlocks: true,
// Allows to disable Openverse media category in the inserter.
enableOpenverseMediaCategory: true,
clearBlockSelection: true,
__experimentalCanUserUseUnfilteredHTML: false,
__experimentalBlockDirectory: false,
__mobileEnablePageTemplates: false,
__experimentalBlockPatterns: [],
__experimentalBlockPatternCategories: [],
__unstableGalleryWithImageBlocks: false,
__unstableIsPreviewMode: false,
// These settings will be completely revamped in the future.
// The goal is to evolve this into an API which will instruct
// the block inspector to animate transitions between what it
// displays based on the relationship between the selected block
// and its parent, and only enable it if the parent is controlling
// its children blocks.
blockInspectorAnimation: {
animationParent: 'core/navigation',
'core/navigation': {
enterDirection: 'leftToRight'
},
'core/navigation-submenu': {
enterDirection: 'rightToLeft'
},
'core/navigation-link': {
enterDirection: 'rightToLeft'
},
'core/search': {
enterDirection: 'rightToLeft'
},
'core/social-links': {
enterDirection: 'rightToLeft'
},
'core/page-list': {
enterDirection: 'rightToLeft'
},
'core/spacer': {
enterDirection: 'rightToLeft'
},
'core/home-link': {
enterDirection: 'rightToLeft'
},
'core/site-title': {
enterDirection: 'rightToLeft'
},
'core/site-logo': {
enterDirection: 'rightToLeft'
}
},
generateAnchors: false,
// gradients setting is not used anymore now defaults are passed from theme.json on the server and core has its own defaults.
// The setting is only kept for backward compatibility purposes.
gradients: [{
name: (0,external_wp_i18n_namespaceObject.__)('Vivid cyan blue to vivid purple'),
gradient: 'linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%)',
slug: 'vivid-cyan-blue-to-vivid-purple'
}, {
name: (0,external_wp_i18n_namespaceObject.__)('Light green cyan to vivid green cyan'),
gradient: 'linear-gradient(135deg,rgb(122,220,180) 0%,rgb(0,208,130) 100%)',
slug: 'light-green-cyan-to-vivid-green-cyan'
}, {
name: (0,external_wp_i18n_namespaceObject.__)('Luminous vivid amber to luminous vivid orange'),
gradient: 'linear-gradient(135deg,rgba(252,185,0,1) 0%,rgba(255,105,0,1) 100%)',
slug: 'luminous-vivid-amber-to-luminous-vivid-orange'
}, {
name: (0,external_wp_i18n_namespaceObject.__)('Luminous vivid orange to vivid red'),
gradient: 'linear-gradient(135deg,rgba(255,105,0,1) 0%,rgb(207,46,46) 100%)',
slug: 'luminous-vivid-orange-to-vivid-red'
}, {
name: (0,external_wp_i18n_namespaceObject.__)('Very light gray to cyan bluish gray'),
gradient: 'linear-gradient(135deg,rgb(238,238,238) 0%,rgb(169,184,195) 100%)',
slug: 'very-light-gray-to-cyan-bluish-gray'
}, {
name: (0,external_wp_i18n_namespaceObject.__)('Cool to warm spectrum'),
gradient: 'linear-gradient(135deg,rgb(74,234,220) 0%,rgb(151,120,209) 20%,rgb(207,42,186) 40%,rgb(238,44,130) 60%,rgb(251,105,98) 80%,rgb(254,248,76) 100%)',
slug: 'cool-to-warm-spectrum'
}, {
name: (0,external_wp_i18n_namespaceObject.__)('Blush light purple'),
gradient: 'linear-gradient(135deg,rgb(255,206,236) 0%,rgb(152,150,240) 100%)',
slug: 'blush-light-purple'
}, {
name: (0,external_wp_i18n_namespaceObject.__)('Blush bordeaux'),
gradient: 'linear-gradient(135deg,rgb(254,205,165) 0%,rgb(254,45,45) 50%,rgb(107,0,62) 100%)',
slug: 'blush-bordeaux'
}, {
name: (0,external_wp_i18n_namespaceObject.__)('Luminous dusk'),
gradient: 'linear-gradient(135deg,rgb(255,203,112) 0%,rgb(199,81,192) 50%,rgb(65,88,208) 100%)',
slug: 'luminous-dusk'
}, {
name: (0,external_wp_i18n_namespaceObject.__)('Pale ocean'),
gradient: 'linear-gradient(135deg,rgb(255,245,203) 0%,rgb(182,227,212) 50%,rgb(51,167,181) 100%)',
slug: 'pale-ocean'
}, {
name: (0,external_wp_i18n_namespaceObject.__)('Electric grass'),
gradient: 'linear-gradient(135deg,rgb(202,248,128) 0%,rgb(113,206,126) 100%)',
slug: 'electric-grass'
}, {
name: (0,external_wp_i18n_namespaceObject.__)('Midnight'),
gradient: 'linear-gradient(135deg,rgb(2,3,129) 0%,rgb(40,116,252) 100%)',
slug: 'midnight'
}],
__unstableResolvedAssets: {
styles: [],
scripts: []
}
};
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/store/array.js
/**
* Insert one or multiple elements into a given position of an array.
*
* @param {Array} array Source array.
* @param {*} elements Elements to insert.
* @param {number} index Insert Position.
*
* @return {Array} Result.
*/
function insertAt(array, elements, index) {
return [...array.slice(0, index), ...(Array.isArray(elements) ? elements : [elements]), ...array.slice(index)];
}
/**
* Moves an element in an array.
*
* @param {Array} array Source array.
* @param {number} from Source index.
* @param {number} to Destination index.
* @param {number} count Number of elements to move.
*
* @return {Array} Result.
*/
function moveTo(array, from, to, count = 1) {
const withoutMovedElements = [...array];
withoutMovedElements.splice(from, count);
return insertAt(withoutMovedElements, array.slice(from, from + count), to);
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/store/reducer.js
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const identity = x => x;
/**
* Given an array of blocks, returns an object where each key is a nesting
* context, the value of which is an array of block client IDs existing within
* that nesting context.
*
* @param {Array} blocks Blocks to map.
* @param {?string} rootClientId Assumed root client ID.
*
* @return {Object} Block order map object.
*/
function mapBlockOrder(blocks, rootClientId = '') {
const result = new Map();
const current = [];
result.set(rootClientId, current);
blocks.forEach(block => {
const {
clientId,
innerBlocks
} = block;
current.push(clientId);
mapBlockOrder(innerBlocks, clientId).forEach((order, subClientId) => {
result.set(subClientId, order);
});
});
return result;
}
/**
* Given an array of blocks, returns an object where each key contains
* the clientId of the block and the value is the parent of the block.
*
* @param {Array} blocks Blocks to map.
* @param {?string} rootClientId Assumed root client ID.
*
* @return {Object} Block order map object.
*/
function mapBlockParents(blocks, rootClientId = '') {
const result = [];
const stack = [[rootClientId, blocks]];
while (stack.length) {
const [parent, currentBlocks] = stack.shift();
currentBlocks.forEach(({
innerBlocks,
...block
}) => {
result.push([block.clientId, parent]);
if (innerBlocks?.length) {
stack.push([block.clientId, innerBlocks]);
}
});
}
return result;
}
/**
* Helper method to iterate through all blocks, recursing into inner blocks,
* applying a transformation function to each one.
* Returns a flattened object with the transformed blocks.
*
* @param {Array} blocks Blocks to flatten.
* @param {Function} transform Transforming function to be applied to each block.
*
* @return {Array} Flattened object.
*/
function flattenBlocks(blocks, transform = identity) {
const result = [];
const stack = [...blocks];
while (stack.length) {
const {
innerBlocks,
...block
} = stack.shift();
stack.push(...innerBlocks);
result.push([block.clientId, transform(block)]);
}
return result;
}
function getFlattenedClientIds(blocks) {
const result = {};
const stack = [...blocks];
while (stack.length) {
const {
innerBlocks,
...block
} = stack.shift();
stack.push(...innerBlocks);
result[block.clientId] = true;
}
return result;
}
/**
* Given an array of blocks, returns an object containing all blocks, without
* attributes, recursing into inner blocks. Keys correspond to the block client
* ID, the value of which is the attributes object.
*
* @param {Array} blocks Blocks to flatten.
*
* @return {Array} Flattened block attributes object.
*/
function getFlattenedBlocksWithoutAttributes(blocks) {
return flattenBlocks(blocks, block => {
const {
attributes,
...restBlock
} = block;
return restBlock;
});
}
/**
* Given an array of blocks, returns an object containing all block attributes,
* recursing into inner blocks. Keys correspond to the block client ID, the
* value of which is the attributes object.
*
* @param {Array} blocks Blocks to flatten.
*
* @return {Array} Flattened block attributes object.
*/
function getFlattenedBlockAttributes(blocks) {
return flattenBlocks(blocks, block => block.attributes);
}
/**
* Returns true if the two object arguments have the same keys, or false
* otherwise.
*
* @param {Object} a First object.
* @param {Object} b Second object.
*
* @return {boolean} Whether the two objects have the same keys.
*/
function hasSameKeys(a, b) {
return es6_default()(Object.keys(a), Object.keys(b));
}
/**
* Returns true if, given the currently dispatching action and the previously
* dispatched action, the two actions are updating the same block attribute, or
* false otherwise.
*
* @param {Object} action Currently dispatching action.
* @param {Object} lastAction Previously dispatched action.
*
* @return {boolean} Whether actions are updating the same block attribute.
*/
function isUpdatingSameBlockAttribute(action, lastAction) {
return action.type === 'UPDATE_BLOCK_ATTRIBUTES' && lastAction !== undefined && lastAction.type === 'UPDATE_BLOCK_ATTRIBUTES' && es6_default()(action.clientIds, lastAction.clientIds) && hasSameKeys(action.attributes, lastAction.attributes);
}
function updateBlockTreeForBlocks(state, blocks) {
const treeToUpdate = state.tree;
const stack = [...blocks];
const flattenedBlocks = [...blocks];
while (stack.length) {
const block = stack.shift();
stack.push(...block.innerBlocks);
flattenedBlocks.push(...block.innerBlocks);
}
// Create objects before mutating them, that way it's always defined.
for (const block of flattenedBlocks) {
treeToUpdate.set(block.clientId, {});
}
for (const block of flattenedBlocks) {
treeToUpdate.set(block.clientId, Object.assign(treeToUpdate.get(block.clientId), {
...state.byClientId.get(block.clientId),
attributes: state.attributes.get(block.clientId),
innerBlocks: block.innerBlocks.map(subBlock => treeToUpdate.get(subBlock.clientId))
}));
}
}
function updateParentInnerBlocksInTree(state, updatedClientIds, updateChildrenOfUpdatedClientIds = false) {
const treeToUpdate = state.tree;
const uncontrolledParents = new Set([]);
const controlledParents = new Set();
for (const clientId of updatedClientIds) {
let current = updateChildrenOfUpdatedClientIds ? clientId : state.parents.get(clientId);
do {
if (state.controlledInnerBlocks[current]) {
// Should stop on controlled blocks.
// If we reach a controlled parent, break out of the loop.
controlledParents.add(current);
break;
} else {
// Else continue traversing up through parents.
uncontrolledParents.add(current);
current = state.parents.get(current);
}
} while (current !== undefined);
}
// To make sure the order of assignments doesn't matter,
// we first create empty objects and mutates the inner blocks later.
for (const clientId of uncontrolledParents) {
treeToUpdate.set(clientId, {
...treeToUpdate.get(clientId)
});
}
for (const clientId of uncontrolledParents) {
treeToUpdate.get(clientId).innerBlocks = (state.order.get(clientId) || []).map(subClientId => treeToUpdate.get(subClientId));
}
// Controlled parent blocks, need a dedicated key for their inner blocks
// to be used when doing getBlocks( controlledBlockClientId ).
for (const clientId of controlledParents) {
treeToUpdate.set('controlled||' + clientId, {
innerBlocks: (state.order.get(clientId) || []).map(subClientId => treeToUpdate.get(subClientId))
});
}
}
/**
* Higher-order reducer intended to compute full block objects key for each block in the post.
* This is a denormalization to optimize the performance of the getBlock selectors and avoid
* recomputing the block objects and avoid heavy memoization.
*
* @param {Function} reducer Original reducer function.
*
* @return {Function} Enhanced reducer function.
*/
const withBlockTree = reducer => (state = {}, action) => {
const newState = reducer(state, action);
if (newState === state) {
return state;
}
newState.tree = state.tree ? state.tree : new Map();
switch (action.type) {
case 'RECEIVE_BLOCKS':
case 'INSERT_BLOCKS':
{
newState.tree = new Map(newState.tree);
updateBlockTreeForBlocks(newState, action.blocks);
updateParentInnerBlocksInTree(newState, action.rootClientId ? [action.rootClientId] : [''], true);
break;
}
case 'UPDATE_BLOCK':
newState.tree = new Map(newState.tree);
newState.tree.set(action.clientId, {
...newState.tree.get(action.clientId),
...newState.byClientId.get(action.clientId),
attributes: newState.attributes.get(action.clientId)
});
updateParentInnerBlocksInTree(newState, [action.clientId], false);
break;
case 'UPDATE_BLOCK_ATTRIBUTES':
{
newState.tree = new Map(newState.tree);
action.clientIds.forEach(clientId => {
newState.tree.set(clientId, {
...newState.tree.get(clientId),
attributes: newState.attributes.get(clientId)
});
});
updateParentInnerBlocksInTree(newState, action.clientIds, false);
break;
}
case 'REPLACE_BLOCKS_AUGMENTED_WITH_CHILDREN':
{
const inserterClientIds = getFlattenedClientIds(action.blocks);
newState.tree = new Map(newState.tree);
action.replacedClientIds.concat(
// Controlled inner blocks are only removed
// if the block doesn't move to another position
// otherwise their content will be lost.
action.replacedClientIds.filter(clientId => !inserterClientIds[clientId]).map(clientId => 'controlled||' + clientId)).forEach(key => {
newState.tree.delete(key);
});
updateBlockTreeForBlocks(newState, action.blocks);
updateParentInnerBlocksInTree(newState, action.blocks.map(b => b.clientId), false);
// If there are no replaced blocks, it means we're removing blocks so we need to update their parent.
const parentsOfRemovedBlocks = [];
for (const clientId of action.clientIds) {
if (state.parents.get(clientId) !== undefined && (state.parents.get(clientId) === '' || newState.byClientId.get(state.parents.get(clientId)))) {
parentsOfRemovedBlocks.push(state.parents.get(clientId));
}
}
updateParentInnerBlocksInTree(newState, parentsOfRemovedBlocks, true);
break;
}
case 'REMOVE_BLOCKS_AUGMENTED_WITH_CHILDREN':
const parentsOfRemovedBlocks = [];
for (const clientId of action.clientIds) {
if (state.parents.get(clientId) !== undefined && (state.parents.get(clientId) === '' || newState.byClientId.get(state.parents.get(clientId)))) {
parentsOfRemovedBlocks.push(state.parents.get(clientId));
}
}
newState.tree = new Map(newState.tree);
action.removedClientIds.concat(action.removedClientIds.map(clientId => 'controlled||' + clientId)).forEach(key => {
newState.tree.delete(key);
});
updateParentInnerBlocksInTree(newState, parentsOfRemovedBlocks, true);
break;
case 'MOVE_BLOCKS_TO_POSITION':
{
const updatedBlockUids = [];
if (action.fromRootClientId) {
updatedBlockUids.push(action.fromRootClientId);
} else {
updatedBlockUids.push('');
}
if (action.toRootClientId) {
updatedBlockUids.push(action.toRootClientId);
}
newState.tree = new Map(newState.tree);
updateParentInnerBlocksInTree(newState, updatedBlockUids, true);
break;
}
case 'MOVE_BLOCKS_UP':
case 'MOVE_BLOCKS_DOWN':
{
const updatedBlockUids = [action.rootClientId ? action.rootClientId : ''];
newState.tree = new Map(newState.tree);
updateParentInnerBlocksInTree(newState, updatedBlockUids, true);
break;
}
case 'SAVE_REUSABLE_BLOCK_SUCCESS':
{
const updatedBlockUids = [];
newState.attributes.forEach((attributes, clientId) => {
if (newState.byClientId.get(clientId).name === 'core/block' && attributes.ref === action.updatedId) {
updatedBlockUids.push(clientId);
}
});
newState.tree = new Map(newState.tree);
updatedBlockUids.forEach(clientId => {
newState.tree.set(clientId, {
...newState.byClientId.get(clientId),
attributes: newState.attributes.get(clientId),
innerBlocks: newState.tree.get(clientId).innerBlocks
});
});
updateParentInnerBlocksInTree(newState, updatedBlockUids, false);
}
}
return newState;
};
/**
* Higher-order reducer intended to augment the blocks reducer, assigning an
* `isPersistentChange` property value corresponding to whether a change in
* state can be considered as persistent. All changes are considered persistent
* except when updating the same block attribute as in the previous action.
*
* @param {Function} reducer Original reducer function.
*
* @return {Function} Enhanced reducer function.
*/
function withPersistentBlockChange(reducer) {
let lastAction;
let markNextChangeAsNotPersistent = false;
return (state, action) => {
let nextState = reducer(state, action);
const isExplicitPersistentChange = action.type === 'MARK_LAST_CHANGE_AS_PERSISTENT' || markNextChangeAsNotPersistent;
// Defer to previous state value (or default) unless changing or
// explicitly marking as persistent.
if (state === nextState && !isExplicitPersistentChange) {
var _state$isPersistentCh;
markNextChangeAsNotPersistent = action.type === 'MARK_NEXT_CHANGE_AS_NOT_PERSISTENT';
const nextIsPersistentChange = (_state$isPersistentCh = state?.isPersistentChange) !== null && _state$isPersistentCh !== void 0 ? _state$isPersistentCh : true;
if (state.isPersistentChange === nextIsPersistentChange) {
return state;
}
return {
...nextState,
isPersistentChange: nextIsPersistentChange
};
}
nextState = {
...nextState,
isPersistentChange: isExplicitPersistentChange ? !markNextChangeAsNotPersistent : !isUpdatingSameBlockAttribute(action, lastAction)
};
// In comparing against the previous action, consider only those which
// would have qualified as one which would have been ignored or not
// have resulted in a changed state.
lastAction = action;
markNextChangeAsNotPersistent = action.type === 'MARK_NEXT_CHANGE_AS_NOT_PERSISTENT';
return nextState;
};
}
/**
* Higher-order reducer intended to augment the blocks reducer, assigning an
* `isIgnoredChange` property value corresponding to whether a change in state
* can be considered as ignored. A change is considered ignored when the result
* of an action not incurred by direct user interaction.
*
* @param {Function} reducer Original reducer function.
*
* @return {Function} Enhanced reducer function.
*/
function withIgnoredBlockChange(reducer) {
/**
* Set of action types for which a blocks state change should be ignored.
*
* @type {Set}
*/
const IGNORED_ACTION_TYPES = new Set(['RECEIVE_BLOCKS']);
return (state, action) => {
const nextState = reducer(state, action);
if (nextState !== state) {
nextState.isIgnoredChange = IGNORED_ACTION_TYPES.has(action.type);
}
return nextState;
};
}
/**
* Higher-order reducer targeting the combined blocks reducer, augmenting
* block client IDs in remove action to include cascade of inner blocks.
*
* @param {Function} reducer Original reducer function.
*
* @return {Function} Enhanced reducer function.
*/
const withInnerBlocksRemoveCascade = reducer => (state, action) => {
// Gets all children which need to be removed.
const getAllChildren = clientIds => {
let result = clientIds;
for (let i = 0; i < result.length; i++) {
if (!state.order.get(result[i]) || action.keepControlledInnerBlocks && action.keepControlledInnerBlocks[result[i]]) {
continue;
}
if (result === clientIds) {
result = [...result];
}
result.push(...state.order.get(result[i]));
}
return result;
};
if (state) {
switch (action.type) {
case 'REMOVE_BLOCKS':
action = {
...action,
type: 'REMOVE_BLOCKS_AUGMENTED_WITH_CHILDREN',
removedClientIds: getAllChildren(action.clientIds)
};
break;
case 'REPLACE_BLOCKS':
action = {
...action,
type: 'REPLACE_BLOCKS_AUGMENTED_WITH_CHILDREN',
replacedClientIds: getAllChildren(action.clientIds)
};
break;
}
}
return reducer(state, action);
};
/**
* Higher-order reducer which targets the combined blocks reducer and handles
* the `RESET_BLOCKS` action. When dispatched, this action will replace all
* blocks that exist in the post, leaving blocks that exist only in state (e.g.
* reusable blocks and blocks controlled by inner blocks controllers) alone.
*
* @param {Function} reducer Original reducer function.
*
* @return {Function} Enhanced reducer function.
*/
const withBlockReset = reducer => (state, action) => {
if (action.type === 'RESET_BLOCKS') {
const newState = {
...state,
byClientId: new Map(getFlattenedBlocksWithoutAttributes(action.blocks)),
attributes: new Map(getFlattenedBlockAttributes(action.blocks)),
order: mapBlockOrder(action.blocks),
parents: new Map(mapBlockParents(action.blocks)),
controlledInnerBlocks: {}
};
newState.tree = new Map(state?.tree);
updateBlockTreeForBlocks(newState, action.blocks);
newState.tree.set('', {
innerBlocks: action.blocks.map(subBlock => newState.tree.get(subBlock.clientId))
});
return newState;
}
return reducer(state, action);
};
/**
* Higher-order reducer which targets the combined blocks reducer and handles
* the `REPLACE_INNER_BLOCKS` action. When dispatched, this action the state
* should become equivalent to the execution of a `REMOVE_BLOCKS` action
* containing all the child's of the root block followed by the execution of
* `INSERT_BLOCKS` with the new blocks.
*
* @param {Function} reducer Original reducer function.
*
* @return {Function} Enhanced reducer function.
*/
const withReplaceInnerBlocks = reducer => (state, action) => {
if (action.type !== 'REPLACE_INNER_BLOCKS') {
return reducer(state, action);
}
// Finds every nested inner block controller. We must check the action blocks
// and not just the block parent state because some inner block controllers
// should be deleted if specified, whereas others should not be deleted. If
// a controlled should not be deleted, then we need to avoid deleting its
// inner blocks from the block state because its inner blocks will not be
// attached to the block in the action.
const nestedControllers = {};
if (Object.keys(state.controlledInnerBlocks).length) {
const stack = [...action.blocks];
while (stack.length) {
const {
innerBlocks,
...block
} = stack.shift();
stack.push(...innerBlocks);
if (!!state.controlledInnerBlocks[block.clientId]) {
nestedControllers[block.clientId] = true;
}
}
}
// The `keepControlledInnerBlocks` prop will keep the inner blocks of the
// marked block in the block state so that they can be reattached to the
// marked block when we re-insert everything a few lines below.
let stateAfterBlocksRemoval = state;
if (state.order.get(action.rootClientId)) {
stateAfterBlocksRemoval = reducer(stateAfterBlocksRemoval, {
type: 'REMOVE_BLOCKS',
keepControlledInnerBlocks: nestedControllers,
clientIds: state.order.get(action.rootClientId)
});
}
let stateAfterInsert = stateAfterBlocksRemoval;
if (action.blocks.length) {
stateAfterInsert = reducer(stateAfterInsert, {
...action,
type: 'INSERT_BLOCKS',
index: 0
});
// We need to re-attach the controlled inner blocks to the blocks tree and
// preserve their block order. Otherwise, an inner block controller's blocks
// will be deleted entirely from its entity.
const stateAfterInsertOrder = new Map(stateAfterInsert.order);
Object.keys(nestedControllers).forEach(key => {
if (state.order.get(key)) {
stateAfterInsertOrder.set(key, state.order.get(key));
}
});
stateAfterInsert.order = stateAfterInsertOrder;
stateAfterInsert.tree = new Map(stateAfterInsert.tree);
Object.keys(nestedControllers).forEach(_key => {
const key = `controlled||${_key}`;
if (state.tree.has(key)) {
stateAfterInsert.tree.set(key, state.tree.get(key));
}
});
}
return stateAfterInsert;
};
/**
* Higher-order reducer which targets the combined blocks reducer and handles
* the `SAVE_REUSABLE_BLOCK_SUCCESS` action. This action can't be handled by
* regular reducers and needs a higher-order reducer since it needs access to
* both `byClientId` and `attributes` simultaneously.
*
* @param {Function} reducer Original reducer function.
*
* @return {Function} Enhanced reducer function.
*/
const withSaveReusableBlock = reducer => (state, action) => {
if (state && action.type === 'SAVE_REUSABLE_BLOCK_SUCCESS') {
const {
id,
updatedId
} = action;
// If a temporary reusable block is saved, we swap the temporary id with the final one.
if (id === updatedId) {
return state;
}
state = {
...state
};
state.attributes = new Map(state.attributes);
state.attributes.forEach((attributes, clientId) => {
const {
name
} = state.byClientId.get(clientId);
if (name === 'core/block' && attributes.ref === id) {
state.attributes.set(clientId, {
...attributes,
ref: updatedId
});
}
});
}
return reducer(state, action);
};
/**
* Higher-order reducer which removes blocks from state when switching parent block controlled state.
*
* @param {Function} reducer Original reducer function.
*
* @return {Function} Enhanced reducer function.
*/
const withResetControlledBlocks = reducer => (state, action) => {
if (action.type === 'SET_HAS_CONTROLLED_INNER_BLOCKS') {
// when switching a block from controlled to uncontrolled or inverse,
// we need to remove its content first.
const tempState = reducer(state, {
type: 'REPLACE_INNER_BLOCKS',
rootClientId: action.clientId,
blocks: []
});
return reducer(tempState, action);
}
return reducer(state, action);
};
/**
* Reducer returning the blocks state.
*
* @param {Object} state Current state.
* @param {Object} action Dispatched action.
*
* @return {Object} Updated state.
*/
const blocks = (0,external_wp_compose_namespaceObject.pipe)(external_wp_data_namespaceObject.combineReducers, withSaveReusableBlock,
// Needs to be before withBlockCache.
withBlockTree,
// Needs to be before withInnerBlocksRemoveCascade.
withInnerBlocksRemoveCascade, withReplaceInnerBlocks,
// Needs to be after withInnerBlocksRemoveCascade.
withBlockReset, withPersistentBlockChange, withIgnoredBlockChange, withResetControlledBlocks)({
// The state is using a Map instead of a plain object for performance reasons.
// You can run the "./test/performance.js" unit test to check the impact
// code changes can have on this reducer.
byClientId(state = new Map(), action) {
switch (action.type) {
case 'RECEIVE_BLOCKS':
case 'INSERT_BLOCKS':
{
const newState = new Map(state);
getFlattenedBlocksWithoutAttributes(action.blocks).forEach(([key, value]) => {
newState.set(key, value);
});
return newState;
}
case 'UPDATE_BLOCK':
{
// Ignore updates if block isn't known.
if (!state.has(action.clientId)) {
return state;
}
// Do nothing if only attributes change.
const {
attributes,
...changes
} = action.updates;
if (Object.values(changes).length === 0) {
return state;
}
const newState = new Map(state);
newState.set(action.clientId, {
...state.get(action.clientId),
...changes
});
return newState;
}
case 'REPLACE_BLOCKS_AUGMENTED_WITH_CHILDREN':
{
if (!action.blocks) {
return state;
}
const newState = new Map(state);
action.replacedClientIds.forEach(clientId => {
newState.delete(clientId);
});
getFlattenedBlocksWithoutAttributes(action.blocks).forEach(([key, value]) => {
newState.set(key, value);
});
return newState;
}
case 'REMOVE_BLOCKS_AUGMENTED_WITH_CHILDREN':
{
const newState = new Map(state);
action.removedClientIds.forEach(clientId => {
newState.delete(clientId);
});
return newState;
}
}
return state;
},
// The state is using a Map instead of a plain object for performance reasons.
// You can run the "./test/performance.js" unit test to check the impact
// code changes can have on this reducer.
attributes(state = new Map(), action) {
switch (action.type) {
case 'RECEIVE_BLOCKS':
case 'INSERT_BLOCKS':
{
const newState = new Map(state);
getFlattenedBlockAttributes(action.blocks).forEach(([key, value]) => {
newState.set(key, value);
});
return newState;
}
case 'UPDATE_BLOCK':
{
// Ignore updates if block isn't known or there are no attribute changes.
if (!state.get(action.clientId) || !action.updates.attributes) {
return state;
}
const newState = new Map(state);
newState.set(action.clientId, {
...state.get(action.clientId),
...action.updates.attributes
});
return newState;
}
case 'UPDATE_BLOCK_ATTRIBUTES':
{
// Avoid a state change if none of the block IDs are known.
if (action.clientIds.every(id => !state.get(id))) {
return state;
}
let hasChange = false;
const newState = new Map(state);
for (const clientId of action.clientIds) {
var _action$attributes;
const updatedAttributeEntries = Object.entries(action.uniqueByBlock ? action.attributes[clientId] : (_action$attributes = action.attributes) !== null && _action$attributes !== void 0 ? _action$attributes : {});
if (updatedAttributeEntries.length === 0) {
continue;
}
let hasUpdatedAttributes = false;
const existingAttributes = state.get(clientId);
const newAttributes = {};
updatedAttributeEntries.forEach(([key, value]) => {
if (existingAttributes[key] !== value) {
hasUpdatedAttributes = true;
newAttributes[key] = value;
}
});
hasChange = hasChange || hasUpdatedAttributes;
if (hasUpdatedAttributes) {
newState.set(clientId, {
...existingAttributes,
...newAttributes
});
}
}
return hasChange ? newState : state;
}
case 'REPLACE_BLOCKS_AUGMENTED_WITH_CHILDREN':
{
if (!action.blocks) {
return state;
}
const newState = new Map(state);
action.replacedClientIds.forEach(clientId => {
newState.delete(clientId);
});
getFlattenedBlockAttributes(action.blocks).forEach(([key, value]) => {
newState.set(key, value);
});
return newState;
}
case 'REMOVE_BLOCKS_AUGMENTED_WITH_CHILDREN':
{
const newState = new Map(state);
action.removedClientIds.forEach(clientId => {
newState.delete(clientId);
});
return newState;
}
}
return state;
},
// The state is using a Map instead of a plain object for performance reasons.
// You can run the "./test/performance.js" unit test to check the impact
// code changes can have on this reducer.
order(state = new Map(), action) {
switch (action.type) {
case 'RECEIVE_BLOCKS':
{
var _state$get;
const blockOrder = mapBlockOrder(action.blocks);
const newState = new Map(state);
blockOrder.forEach((order, clientId) => {
if (clientId !== '') {
newState.set(clientId, order);
}
});
newState.set('', ((_state$get = state.get('')) !== null && _state$get !== void 0 ? _state$get : []).concat(blockOrder['']));
return newState;
}
case 'INSERT_BLOCKS':
{
const {
rootClientId = ''
} = action;
const subState = state.get(rootClientId) || [];
const mappedBlocks = mapBlockOrder(action.blocks, rootClientId);
const {
index = subState.length
} = action;
const newState = new Map(state);
mappedBlocks.forEach((order, clientId) => {
newState.set(clientId, order);
});
newState.set(rootClientId, insertAt(subState, mappedBlocks.get(rootClientId), index));
return newState;
}
case 'MOVE_BLOCKS_TO_POSITION':
{
var _state$get$filter;
const {
fromRootClientId = '',
toRootClientId = '',
clientIds
} = action;
const {
index = state.get(toRootClientId).length
} = action;
// Moving inside the same parent block.
if (fromRootClientId === toRootClientId) {
const subState = state.get(toRootClientId);
const fromIndex = subState.indexOf(clientIds[0]);
const newState = new Map(state);
newState.set(toRootClientId, moveTo(state.get(toRootClientId), fromIndex, index, clientIds.length));
return newState;
}
// Moving from a parent block to another.
const newState = new Map(state);
newState.set(fromRootClientId, (_state$get$filter = state.get(fromRootClientId)?.filter(id => !clientIds.includes(id))) !== null && _state$get$filter !== void 0 ? _state$get$filter : []);
newState.set(toRootClientId, insertAt(state.get(toRootClientId), clientIds, index));
return newState;
}
case 'MOVE_BLOCKS_UP':
{
const {
clientIds,
rootClientId = ''
} = action;
const firstClientId = clientIds[0];
const subState = state.get(rootClientId);
if (!subState.length || firstClientId === subState[0]) {
return state;
}
const firstIndex = subState.indexOf(firstClientId);
const newState = new Map(state);
newState.set(rootClientId, moveTo(subState, firstIndex, firstIndex - 1, clientIds.length));
return newState;
}
case 'MOVE_BLOCKS_DOWN':
{
const {
clientIds,
rootClientId = ''
} = action;
const firstClientId = clientIds[0];
const lastClientId = clientIds[clientIds.length - 1];
const subState = state.get(rootClientId);
if (!subState.length || lastClientId === subState[subState.length - 1]) {
return state;
}
const firstIndex = subState.indexOf(firstClientId);
const newState = new Map(state);
newState.set(rootClientId, moveTo(subState, firstIndex, firstIndex + 1, clientIds.length));
return newState;
}
case 'REPLACE_BLOCKS_AUGMENTED_WITH_CHILDREN':
{
const {
clientIds
} = action;
if (!action.blocks) {
return state;
}
const mappedBlocks = mapBlockOrder(action.blocks);
const newState = new Map(state);
action.replacedClientIds.forEach(clientId => {
newState.delete(clientId);
});
mappedBlocks.forEach((order, clientId) => {
if (clientId !== '') {
newState.set(clientId, order);
}
});
newState.forEach((order, clientId) => {
const newSubOrder = Object.values(order).reduce((result, subClientId) => {
if (subClientId === clientIds[0]) {
return [...result, ...mappedBlocks.get('')];
}
if (clientIds.indexOf(subClientId) === -1) {
result.push(subClientId);
}
return result;
}, []);
newState.set(clientId, newSubOrder);
});
return newState;
}
case 'REMOVE_BLOCKS_AUGMENTED_WITH_CHILDREN':
{
const newState = new Map(state);
// Remove inner block ordering for removed blocks.
action.removedClientIds.forEach(clientId => {
newState.delete(clientId);
});
newState.forEach((order, clientId) => {
var _order$filter;
const newSubOrder = (_order$filter = order?.filter(id => !action.removedClientIds.includes(id))) !== null && _order$filter !== void 0 ? _order$filter : [];
if (newSubOrder.length !== order.length) {
newState.set(clientId, newSubOrder);
}
});
return newState;
}
}
return state;
},
// While technically redundant data as the inverse of `order`, it serves as
// an optimization for the selectors which derive the ancestry of a block.
parents(state = new Map(), action) {
switch (action.type) {
case 'RECEIVE_BLOCKS':
{
const newState = new Map(state);
mapBlockParents(action.blocks).forEach(([key, value]) => {
newState.set(key, value);
});
return newState;
}
case 'INSERT_BLOCKS':
{
const newState = new Map(state);
mapBlockParents(action.blocks, action.rootClientId || '').forEach(([key, value]) => {
newState.set(key, value);
});
return newState;
}
case 'MOVE_BLOCKS_TO_POSITION':
{
const newState = new Map(state);
action.clientIds.forEach(id => {
newState.set(id, action.toRootClientId || '');
});
return newState;
}
case 'REPLACE_BLOCKS_AUGMENTED_WITH_CHILDREN':
{
const newState = new Map(state);
action.replacedClientIds.forEach(clientId => {
newState.delete(clientId);
});
mapBlockParents(action.blocks, state.get(action.clientIds[0])).forEach(([key, value]) => {
newState.set(key, value);
});
return newState;
}
case 'REMOVE_BLOCKS_AUGMENTED_WITH_CHILDREN':
{
const newState = new Map(state);
action.removedClientIds.forEach(clientId => {
newState.delete(clientId);
});
return newState;
}
}
return state;
},
controlledInnerBlocks(state = {}, {
type,
clientId,
hasControlledInnerBlocks
}) {
if (type === 'SET_HAS_CONTROLLED_INNER_BLOCKS') {
return {
...state,
[clientId]: hasControlledInnerBlocks
};
}
return state;
}
});
/**
* Reducer returning visibility status of block interface.
*
* @param {boolean} state Current state.
* @param {Object} action Dispatched action.
*
* @return {boolean} Updated state.
*/
function isBlockInterfaceHidden(state = false, action) {
switch (action.type) {
case 'HIDE_BLOCK_INTERFACE':
return true;
case 'SHOW_BLOCK_INTERFACE':
return false;
}
return state;
}
/**
* Reducer returning typing state.
*
* @param {boolean} state Current state.
* @param {Object} action Dispatched action.
*
* @return {boolean} Updated state.
*/
function isTyping(state = false, action) {
switch (action.type) {
case 'START_TYPING':
return true;
case 'STOP_TYPING':
return false;
}
return state;
}
/**
* Reducer returning dragged block client id.
*
* @param {string[]} state Current state.
* @param {Object} action Dispatched action.
*
* @return {string[]} Updated state.
*/
function draggedBlocks(state = [], action) {
switch (action.type) {
case 'START_DRAGGING_BLOCKS':
return action.clientIds;
case 'STOP_DRAGGING_BLOCKS':
return [];
}
return state;
}
/**
* Reducer tracking the visible blocks.
*
* @param {Record} state Current state.
* @param {Object} action Dispatched action.
*
* @return {Record} Block visibility.
*/
function blockVisibility(state = {}, action) {
if (action.type === 'SET_BLOCK_VISIBILITY') {
return {
...state,
...action.updates
};
}
return state;
}
/**
* Internal helper reducer for selectionStart and selectionEnd. Can hold a block
* selection, represented by an object with property clientId.
*
* @param {Object} state Current state.
* @param {Object} action Dispatched action.
*
* @return {Object} Updated state.
*/
function selectionHelper(state = {}, action) {
switch (action.type) {
case 'CLEAR_SELECTED_BLOCK':
{
if (state.clientId) {
return {};
}
return state;
}
case 'SELECT_BLOCK':
if (action.clientId === state.clientId) {
return state;
}
return {
clientId: action.clientId
};
case 'REPLACE_INNER_BLOCKS':
case 'INSERT_BLOCKS':
{
if (!action.updateSelection || !action.blocks.length) {
return state;
}
return {
clientId: action.blocks[0].clientId
};
}
case 'REMOVE_BLOCKS':
if (!action.clientIds || !action.clientIds.length || action.clientIds.indexOf(state.clientId) === -1) {
return state;
}
return {};
case 'REPLACE_BLOCKS':
{
if (action.clientIds.indexOf(state.clientId) === -1) {
return state;
}
const blockToSelect = action.blocks[action.indexToSelect] || action.blocks[action.blocks.length - 1];
if (!blockToSelect) {
return {};
}
if (blockToSelect.clientId === state.clientId) {
return state;
}
return {
clientId: blockToSelect.clientId
};
}
}
return state;
}
/**
* Reducer returning the selection state.
*
* @param {boolean} state Current state.
* @param {Object} action Dispatched action.
*
* @return {boolean} Updated state.
*/
function selection(state = {}, action) {
switch (action.type) {
case 'SELECTION_CHANGE':
if (action.clientId) {
return {
selectionStart: {
clientId: action.clientId,
attributeKey: action.attributeKey,
offset: action.startOffset
},
selectionEnd: {
clientId: action.clientId,
attributeKey: action.attributeKey,
offset: action.endOffset
}
};
}
return {
selectionStart: action.start || state.selectionStart,
selectionEnd: action.end || state.selectionEnd
};
case 'RESET_SELECTION':
const {
selectionStart,
selectionEnd
} = action;
return {
selectionStart,
selectionEnd
};
case 'MULTI_SELECT':
const {
start,
end
} = action;
if (start === state.selectionStart?.clientId && end === state.selectionEnd?.clientId) {
return state;
}
return {
selectionStart: {
clientId: start
},
selectionEnd: {
clientId: end
}
};
case 'RESET_BLOCKS':
const startClientId = state?.selectionStart?.clientId;
const endClientId = state?.selectionEnd?.clientId;
// Do nothing if there's no selected block.
if (!startClientId && !endClientId) {
return state;
}
// If the start of the selection won't exist after reset, remove selection.
if (!action.blocks.some(block => block.clientId === startClientId)) {
return {
selectionStart: {},
selectionEnd: {}
};
}
// If the end of the selection won't exist after reset, collapse selection.
if (!action.blocks.some(block => block.clientId === endClientId)) {
return {
...state,
selectionEnd: state.selectionStart
};
}
}
const selectionStart = selectionHelper(state.selectionStart, action);
const selectionEnd = selectionHelper(state.selectionEnd, action);
if (selectionStart === state.selectionStart && selectionEnd === state.selectionEnd) {
return state;
}
return {
selectionStart,
selectionEnd
};
}
/**
* Reducer returning whether the user is multi-selecting.
*
* @param {boolean} state Current state.
* @param {Object} action Dispatched action.
*
* @return {boolean} Updated state.
*/
function isMultiSelecting(state = false, action) {
switch (action.type) {
case 'START_MULTI_SELECT':
return true;
case 'STOP_MULTI_SELECT':
return false;
}
return state;
}
/**
* Reducer returning whether selection is enabled.
*
* @param {boolean} state Current state.
* @param {Object} action Dispatched action.
*
* @return {boolean} Updated state.
*/
function isSelectionEnabled(state = true, action) {
switch (action.type) {
case 'TOGGLE_SELECTION':
return action.isSelectionEnabled;
}
return state;
}
/**
* Reducer returning the data needed to display a prompt when certain blocks
* are removed, or `false` if no such prompt is requested.
*
* @param {boolean} state Current state.
* @param {Object} action Dispatched action.
*
* @return {Object|false} Data for removal prompt display, if any.
*/
function removalPromptData(state = false, action) {
switch (action.type) {
case 'DISPLAY_BLOCK_REMOVAL_PROMPT':
const {
clientIds,
selectPrevious,
blockNamesForPrompt
} = action;
return {
clientIds,
selectPrevious,
blockNamesForPrompt
};
case 'CLEAR_BLOCK_REMOVAL_PROMPT':
return false;
}
return state;
}
/**
* Reducer returning any rules that a block editor may provide in order to
* prevent a user from accidentally removing certain blocks. These rules are
* then used to display a confirmation prompt to the user. For instance, in the
* Site Editor, the Query Loop block is important enough to warrant such
* confirmation.
*
* The data is a record whose keys are block types (e.g. 'core/query') and
* whose values are the explanation to be shown to users (e.g. 'Query Loop
* displays a list of posts or pages.').
*
* @param {boolean} state Current state.
* @param {Object} action Dispatched action.
*
* @return {Record} Updated state.
*/
function blockRemovalRules(state = false, action) {
switch (action.type) {
case 'SET_BLOCK_REMOVAL_RULES':
return action.rules;
}
return state;
}
/**
* Reducer returning the initial block selection.
*
* Currently this in only used to restore the selection after block deletion and
* pasting new content.This reducer should eventually be removed in favour of setting
* selection directly.
*
* @param {boolean} state Current state.
* @param {Object} action Dispatched action.
*
* @return {number|null} Initial position: 0, -1 or null.
*/
function initialPosition(state = null, action) {
if (action.type === 'REPLACE_BLOCKS' && action.initialPosition !== undefined) {
return action.initialPosition;
} else if (['MULTI_SELECT', 'SELECT_BLOCK', 'RESET_SELECTION', 'INSERT_BLOCKS', 'REPLACE_INNER_BLOCKS'].includes(action.type)) {
return action.initialPosition;
}
return state;
}
function blocksMode(state = {}, action) {
if (action.type === 'TOGGLE_BLOCK_MODE') {
const {
clientId
} = action;
return {
...state,
[clientId]: state[clientId] && state[clientId] === 'html' ? 'visual' : 'html'
};
}
return state;
}
/**
* Reducer returning the block insertion point visibility, either null if there
* is not an explicit insertion point assigned, or an object of its `index` and
* `rootClientId`.
*
* @param {Object} state Current state.
* @param {Object} action Dispatched action.
*
* @return {Object} Updated state.
*/
function insertionPoint(state = null, action) {
switch (action.type) {
case 'SHOW_INSERTION_POINT':
{
const {
rootClientId,
index,
__unstableWithInserter,
operation
} = action;
const nextState = {
rootClientId,
index,
__unstableWithInserter,
operation
};
// Bail out updates if the states are the same.
return es6_default()(state, nextState) ? state : nextState;
}
case 'HIDE_INSERTION_POINT':
return null;
}
return state;
}
/**
* Reducer returning whether the post blocks match the defined template or not.
*
* @param {Object} state Current state.
* @param {Object} action Dispatched action.
*
* @return {boolean} Updated state.
*/
function template(state = {
isValid: true
}, action) {
switch (action.type) {
case 'SET_TEMPLATE_VALIDITY':
return {
...state,
isValid: action.isValid
};
}
return state;
}
/**
* Reducer returning the editor setting.
*
* @param {Object} state Current state.
* @param {Object} action Dispatched action.
*
* @return {Object} Updated state.
*/
function settings(state = SETTINGS_DEFAULTS, action) {
switch (action.type) {
case 'UPDATE_SETTINGS':
if (action.reset) {
return {
...SETTINGS_DEFAULTS,
...action.settings
};
}
return {
...state,
...action.settings
};
}
return state;
}
/**
* Reducer returning the user preferences.
*
* @param {Object} state Current state.
* @param {Object} action Dispatched action.
*
* @return {string} Updated state.
*/
function preferences(state = PREFERENCES_DEFAULTS, action) {
switch (action.type) {
case 'INSERT_BLOCKS':
case 'REPLACE_BLOCKS':
return action.blocks.reduce((prevState, block) => {
const {
attributes,
name: blockName
} = block;
let id = blockName;
// If a block variation match is found change the name to be the same with the
// one that is used for block variations in the Inserter (`getItemFromVariation`).
const match = (0,external_wp_data_namespaceObject.select)(external_wp_blocks_namespaceObject.store).getActiveBlockVariation(blockName, attributes);
if (match?.name) {
id += '/' + match.name;
}
if (blockName === 'core/block') {
id += '/' + attributes.ref;
}
return {
...prevState,
insertUsage: {
...prevState.insertUsage,
[id]: {
time: action.time,
count: prevState.insertUsage[id] ? prevState.insertUsage[id].count + 1 : 1
}
}
};
}, state);
}
return state;
}
/**
* Reducer returning an object where each key is a block client ID, its value
* representing the settings for its nested blocks.
*
* @param {Object} state Current state.
* @param {Object} action Dispatched action.
*
* @return {Object} Updated state.
*/
const blockListSettings = (state = {}, action) => {
switch (action.type) {
// Even if the replaced blocks have the same client ID, our logic
// should correct the state.
case 'REPLACE_BLOCKS':
case 'REMOVE_BLOCKS':
{
return Object.fromEntries(Object.entries(state).filter(([id]) => !action.clientIds.includes(id)));
}
case 'UPDATE_BLOCK_LIST_SETTINGS':
{
const {
clientId
} = action;
if (!action.settings) {
if (state.hasOwnProperty(clientId)) {
const {
[clientId]: removedBlock,
...restBlocks
} = state;
return restBlocks;
}
return state;
}
if (es6_default()(state[clientId], action.settings)) {
return state;
}
return {
...state,
[clientId]: action.settings
};
}
}
return state;
};
/**
* Reducer returning which mode is enabled.
*
* @param {string} state Current state.
* @param {Object} action Dispatched action.
*
* @return {string} Updated state.
*/
function editorMode(state = 'edit', action) {
// Let inserting block in navigation mode always trigger Edit mode.
if (action.type === 'INSERT_BLOCKS' && state === 'navigation') {
return 'edit';
}
if (action.type === 'SET_EDITOR_MODE') {
return action.mode;
}
return state;
}
/**
* Reducer returning whether the block moving mode is enabled or not.
*
* @param {string|null} state Current state.
* @param {Object} action Dispatched action.
*
* @return {string|null} Updated state.
*/
function hasBlockMovingClientId(state = null, action) {
if (action.type === 'SET_BLOCK_MOVING_MODE') {
return action.hasBlockMovingClientId;
}
if (action.type === 'SET_EDITOR_MODE') {
return null;
}
return state;
}
/**
* Reducer return an updated state representing the most recent block attribute
* update. The state is structured as an object where the keys represent the
* client IDs of blocks, the values a subset of attributes from the most recent
* block update. The state is always reset to null if the last action is
* anything other than an attributes update.
*
* @param {Object} state Current state.
* @param {Object} action Action object.
*
* @return {[string,Object]} Updated state.
*/
function lastBlockAttributesChange(state = null, action) {
switch (action.type) {
case 'UPDATE_BLOCK':
if (!action.updates.attributes) {
break;
}
return {
[action.clientId]: action.updates.attributes
};
case 'UPDATE_BLOCK_ATTRIBUTES':
return action.clientIds.reduce((accumulator, id) => ({
...accumulator,
[id]: action.uniqueByBlock ? action.attributes[id] : action.attributes
}), {});
}
return state;
}
/**
* Reducer returning current highlighted block.
*
* @param {boolean} state Current highlighted block.
* @param {Object} action Dispatched action.
*
* @return {string} Updated state.
*/
function highlightedBlock(state, action) {
switch (action.type) {
case 'TOGGLE_BLOCK_HIGHLIGHT':
const {
clientId,
isHighlighted
} = action;
if (isHighlighted) {
return clientId;
} else if (state === clientId) {
return null;
}
return state;
case 'SELECT_BLOCK':
if (action.clientId !== state) {
return null;
}
}
return state;
}
/**
* Reducer returning the block insertion event list state.
*
* @param {Object} state Current state.
* @param {Object} action Dispatched action.
*
* @return {Object} Updated state.
*/
function lastBlockInserted(state = {}, action) {
switch (action.type) {
case 'INSERT_BLOCKS':
case 'REPLACE_BLOCKS':
if (!action.blocks.length) {
return state;
}
const clientIds = action.blocks.map(block => {
return block.clientId;
});
const source = action.meta?.source;
return {
clientIds,
source
};
case 'RESET_BLOCKS':
return {};
}
return state;
}
/**
* Reducer returning the block that is eding temporarily edited as blocks.
*
* @param {Object} state Current state.
* @param {Object} action Dispatched action.
*
* @return {Object} Updated state.
*/
function temporarilyEditingAsBlocks(state = '', action) {
if (action.type === 'SET_TEMPORARILY_EDITING_AS_BLOCKS') {
return action.temporarilyEditingAsBlocks;
}
return state;
}
/**
* Reducer returning a map of block client IDs to block editing modes.
*
* @param {Map} state Current state.
* @param {Object} action Dispatched action.
*
* @return {Map} Updated state.
*/
function blockEditingModes(state = new Map(), action) {
switch (action.type) {
case 'SET_BLOCK_EDITING_MODE':
return new Map(state).set(action.clientId, action.mode);
case 'UNSET_BLOCK_EDITING_MODE':
{
const newState = new Map(state);
newState.delete(action.clientId);
return newState;
}
case 'RESET_BLOCKS':
{
return state.has('') ? new Map().set('', state.get('')) : state;
}
}
return state;
}
/**
* Reducer returning the clientId of the block settings menu that is currently open.
*
* @param {string|null} state Current state.
* @param {Object} action Dispatched action.
*
* @return {string|null} Updated state.
*/
function openedBlockSettingsMenu(state = null, action) {
if ('SET_OPENED_BLOCK_SETTINGS_MENU' === action.type) {
var _action$clientId;
return (_action$clientId = action?.clientId) !== null && _action$clientId !== void 0 ? _action$clientId : null;
}
return state;
}
/**
* Reducer returning a map of style IDs to style overrides.
*
* @param {Map} state Current state.
* @param {Object} action Dispatched action.
*
* @return {Map} Updated state.
*/
function styleOverrides(state = new Map(), action) {
switch (action.type) {
case 'SET_STYLE_OVERRIDE':
return new Map(state).set(action.id, action.style);
case 'DELETE_STYLE_OVERRIDE':
{
const newState = new Map(state);
newState.delete(action.id);
return newState;
}
}
return state;
}
/**
* Reducer returning a map of the registered inserter media categories.
*
* @param {Array} state Current state.
* @param {Object} action Dispatched action.
*
* @return {Array} Updated state.
*/
function registeredInserterMediaCategories(state = [], action) {
switch (action.type) {
case 'REGISTER_INSERTER_MEDIA_CATEGORY':
return [...state, action.category];
}
return state;
}
const combinedReducers = (0,external_wp_data_namespaceObject.combineReducers)({
blocks,
isTyping,
isBlockInterfaceHidden,
draggedBlocks,
selection,
isMultiSelecting,
isSelectionEnabled,
initialPosition,
blocksMode,
blockListSettings,
insertionPoint,
template,
settings,
preferences,
lastBlockAttributesChange,
editorMode,
hasBlockMovingClientId,
highlightedBlock,
lastBlockInserted,
temporarilyEditingAsBlocks,
blockVisibility,
blockEditingModes,
styleOverrides,
removalPromptData,
blockRemovalRules,
openedBlockSettingsMenu,
registeredInserterMediaCategories
});
function withAutomaticChangeReset(reducer) {
return (state, action) => {
const nextState = reducer(state, action);
if (!state) {
return nextState;
}
// Take over the last value without creating a new reference.
nextState.automaticChangeStatus = state.automaticChangeStatus;
if (action.type === 'MARK_AUTOMATIC_CHANGE') {
return {
...nextState,
automaticChangeStatus: 'pending'
};
}
if (action.type === 'MARK_AUTOMATIC_CHANGE_FINAL' && state.automaticChangeStatus === 'pending') {
return {
...nextState,
automaticChangeStatus: 'final'
};
}
// If there's a change that doesn't affect blocks or selection, maintain
// the current status.
if (nextState.blocks === state.blocks && nextState.selection === state.selection) {
return nextState;
}
// As long as the state is not final, ignore any selection changes.
if (nextState.automaticChangeStatus !== 'final' && nextState.selection !== state.selection) {
return nextState;
}
// Reset the status if blocks change or selection changes (when status is final).
return {
...nextState,
automaticChangeStatus: undefined
};
};
}
/* harmony default export */ var reducer = (withAutomaticChangeReset(combinedReducers));
;// CONCATENATED MODULE: ./node_modules/rememo/rememo.js
/** @typedef {(...args: any[]) => *[]} GetDependants */
/** @typedef {() => void} Clear */
/**
* @typedef {{
* getDependants: GetDependants,
* clear: Clear
* }} EnhancedSelector
*/
/**
* Internal cache entry.
*
* @typedef CacheNode
*
* @property {?CacheNode|undefined} [prev] Previous node.
* @property {?CacheNode|undefined} [next] Next node.
* @property {*[]} args Function arguments for cache entry.
* @property {*} val Function result.
*/
/**
* @typedef Cache
*
* @property {Clear} clear Function to clear cache.
* @property {boolean} [isUniqueByDependants] Whether dependants are valid in
* considering cache uniqueness. A cache is unique if dependents are all arrays
* or objects.
* @property {CacheNode?} [head] Cache head.
* @property {*[]} [lastDependants] Dependants from previous invocation.
*/
/**
* Arbitrary value used as key for referencing cache object in WeakMap tree.
*
* @type {{}}
*/
var LEAF_KEY = {};
/**
* Returns the first argument as the sole entry in an array.
*
* @template T
*
* @param {T} value Value to return.
*
* @return {[T]} Value returned as entry in array.
*/
function arrayOf(value) {
return [value];
}
/**
* Returns true if the value passed is object-like, or false otherwise. A value
* is object-like if it can support property assignment, e.g. object or array.
*
* @param {*} value Value to test.
*
* @return {boolean} Whether value is object-like.
*/
function isObjectLike(value) {
return !!value && 'object' === typeof value;
}
/**
* Creates and returns a new cache object.
*
* @return {Cache} Cache object.
*/
function createCache() {
/** @type {Cache} */
var cache = {
clear: function () {
cache.head = null;
},
};
return cache;
}
/**
* Returns true if entries within the two arrays are strictly equal by
* reference from a starting index.
*
* @param {*[]} a First array.
* @param {*[]} b Second array.
* @param {number} fromIndex Index from which to start comparison.
*
* @return {boolean} Whether arrays are shallowly equal.
*/
function isShallowEqual(a, b, fromIndex) {
var i;
if (a.length !== b.length) {
return false;
}
for (i = fromIndex; i < a.length; i++) {
if (a[i] !== b[i]) {
return false;
}
}
return true;
}
/**
* Returns a memoized selector function. The getDependants function argument is
* called before the memoized selector and is expected to return an immutable
* reference or array of references on which the selector depends for computing
* its own return value. The memoize cache is preserved only as long as those
* dependant references remain the same. If getDependants returns a different
* reference(s), the cache is cleared and the selector value regenerated.
*
* @template {(...args: *[]) => *} S
*
* @param {S} selector Selector function.
* @param {GetDependants=} getDependants Dependant getter returning an array of
* references used in cache bust consideration.
*/
/* harmony default export */ function rememo(selector, getDependants) {
/** @type {WeakMap<*,*>} */
var rootCache;
/** @type {GetDependants} */
var normalizedGetDependants = getDependants ? getDependants : arrayOf;
/**
* Returns the cache for a given dependants array. When possible, a WeakMap
* will be used to create a unique cache for each set of dependants. This
* is feasible due to the nature of WeakMap in allowing garbage collection
* to occur on entries where the key object is no longer referenced. Since
* WeakMap requires the key to be an object, this is only possible when the
* dependant is object-like. The root cache is created as a hierarchy where
* each top-level key is the first entry in a dependants set, the value a
* WeakMap where each key is the next dependant, and so on. This continues
* so long as the dependants are object-like. If no dependants are object-
* like, then the cache is shared across all invocations.
*
* @see isObjectLike
*
* @param {*[]} dependants Selector dependants.
*
* @return {Cache} Cache object.
*/
function getCache(dependants) {
var caches = rootCache,
isUniqueByDependants = true,
i,
dependant,
map,
cache;
for (i = 0; i < dependants.length; i++) {
dependant = dependants[i];
// Can only compose WeakMap from object-like key.
if (!isObjectLike(dependant)) {
isUniqueByDependants = false;
break;
}
// Does current segment of cache already have a WeakMap?
if (caches.has(dependant)) {
// Traverse into nested WeakMap.
caches = caches.get(dependant);
} else {
// Create, set, and traverse into a new one.
map = new WeakMap();
caches.set(dependant, map);
caches = map;
}
}
// We use an arbitrary (but consistent) object as key for the last item
// in the WeakMap to serve as our running cache.
if (!caches.has(LEAF_KEY)) {
cache = createCache();
cache.isUniqueByDependants = isUniqueByDependants;
caches.set(LEAF_KEY, cache);
}
return caches.get(LEAF_KEY);
}
/**
* Resets root memoization cache.
*/
function clear() {
rootCache = new WeakMap();
}
/* eslint-disable jsdoc/check-param-names */
/**
* The augmented selector call, considering first whether dependants have
* changed before passing it to underlying memoize function.
*
* @param {*} source Source object for derivation.
* @param {...*} extraArgs Additional arguments to pass to selector.
*
* @return {*} Selector result.
*/
/* eslint-enable jsdoc/check-param-names */
function callSelector(/* source, ...extraArgs */) {
var len = arguments.length,
cache,
node,
i,
args,
dependants;
// Create copy of arguments (avoid leaking deoptimization).
args = new Array(len);
for (i = 0; i < len; i++) {
args[i] = arguments[i];
}
dependants = normalizedGetDependants.apply(null, args);
cache = getCache(dependants);
// If not guaranteed uniqueness by dependants (primitive type), shallow
// compare against last dependants and, if references have changed,
// destroy cache to recalculate result.
if (!cache.isUniqueByDependants) {
if (
cache.lastDependants &&
!isShallowEqual(dependants, cache.lastDependants, 0)
) {
cache.clear();
}
cache.lastDependants = dependants;
}
node = cache.head;
while (node) {
// Check whether node arguments match arguments
if (!isShallowEqual(node.args, args, 1)) {
node = node.next;
continue;
}
// At this point we can assume we've found a match
// Surface matched node to head if not already
if (node !== cache.head) {
// Adjust siblings to point to each other.
/** @type {CacheNode} */ (node.prev).next = node.next;
if (node.next) {
node.next.prev = node.prev;
}
node.next = cache.head;
node.prev = null;
/** @type {CacheNode} */ (cache.head).prev = node;
cache.head = node;
}
// Return immediately
return node.val;
}
// No cached value found. Continue to insertion phase:
node = /** @type {CacheNode} */ ({
// Generate the result from original function
val: selector.apply(null, args),
});
// Avoid including the source object in the cache.
args[0] = null;
node.args = args;
// Don't need to check whether node is already head, since it would
// have been returned above already if it was
// Shift existing head down list
if (cache.head) {
cache.head.prev = node;
node.next = cache.head;
}
cache.head = node;
return node.val;
}
callSelector.getDependants = normalizedGetDependants;
callSelector.clear = clear;
clear();
return /** @type {S & EnhancedSelector} */ (callSelector);
}
;// CONCATENATED MODULE: external ["wp","primitives"]
var external_wp_primitives_namespaceObject = window["wp"]["primitives"];
;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/symbol.js
/**
* WordPress dependencies
*/
const symbol = (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.SVG, {
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 24 24"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.Path, {
d: "M21.3 10.8l-5.6-5.6c-.7-.7-1.8-.7-2.5 0l-5.6 5.6c-.7.7-.7 1.8 0 2.5l5.6 5.6c.3.3.8.5 1.2.5s.9-.2 1.2-.5l5.6-5.6c.8-.7.8-1.9.1-2.5zm-1 1.4l-5.6 5.6c-.1.1-.3.1-.4 0l-5.6-5.6c-.1-.1-.1-.3 0-.4l5.6-5.6s.1-.1.2-.1.1 0 .2.1l5.6 5.6c.1.1.1.3 0 .4zm-16.6-.4L10 5.5l-1-1-6.3 6.3c-.7.7-.7 1.8 0 2.5L9 19.5l1.1-1.1-6.3-6.3c-.2 0-.2-.2-.1-.3z"
}));
/* harmony default export */ var library_symbol = (symbol);
;// CONCATENATED MODULE: external ["wp","richText"]
var external_wp_richText_namespaceObject = window["wp"]["richText"];
;// CONCATENATED MODULE: external ["wp","deprecated"]
var external_wp_deprecated_namespaceObject = window["wp"]["deprecated"];
var external_wp_deprecated_default = /*#__PURE__*/__webpack_require__.n(external_wp_deprecated_namespaceObject);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/store/utils.js
/**
* Helper function that maps attribute definition properties to the
* ones used by RichText utils like `create, toHTMLString, etc..`.
*
* @param {Object} attributeDefinition A block's attribute definition object.
* @return {Object} The mapped object.
*/
function mapRichTextSettings(attributeDefinition) {
const {
__unstablePreserveWhiteSpace: preserveWhiteSpace
} = attributeDefinition;
return {
preserveWhiteSpace
};
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/utils/sorting.js
/**
* Recursive stable sorting comparator function.
*
* @param {string|Function} field Field to sort by.
* @param {Array} items Items to sort.
* @param {string} order Order, 'asc' or 'desc'.
* @return {Function} Comparison function to be used in a `.sort()`.
*/
const comparator = (field, items, order) => {
return (a, b) => {
let cmpA, cmpB;
if (typeof field === 'function') {
cmpA = field(a);
cmpB = field(b);
} else {
cmpA = a[field];
cmpB = b[field];
}
if (cmpA > cmpB) {
return order === 'asc' ? 1 : -1;
} else if (cmpB > cmpA) {
return order === 'asc' ? -1 : 1;
}
const orderA = items.findIndex(item => item === a);
const orderB = items.findIndex(item => item === b);
// Stable sort: maintaining original array order
if (orderA > orderB) {
return 1;
} else if (orderB > orderA) {
return -1;
}
return 0;
};
};
/**
* Order items by a certain key.
* Supports decorator functions that allow complex picking of a comparison field.
* Sorts in ascending order by default, but supports descending as well.
* Stable sort - maintains original order of equal items.
*
* @param {Array} items Items to order.
* @param {string|Function} field Field to order by.
* @param {string} order Sorting order, `asc` or `desc`.
* @return {Array} Sorted items.
*/
function orderBy(items, field, order = 'asc') {
return items.concat().sort(comparator(field, items, order));
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/store/selectors.js
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
/**
* A block selection object.
*
* @typedef {Object} WPBlockSelection
*
* @property {string} clientId A block client ID.
* @property {string} attributeKey A block attribute key.
* @property {number} offset An attribute value offset, based on the rich
* text value. See `wp.richText.create`.
*/
// Module constants.
const MILLISECONDS_PER_HOUR = 3600 * 1000;
const MILLISECONDS_PER_DAY = 24 * 3600 * 1000;
const MILLISECONDS_PER_WEEK = 7 * 24 * 3600 * 1000;
/**
* Shared reference to an empty array for cases where it is important to avoid
* returning a new array reference on every invocation, as in a connected or
* other pure component which performs `shouldComponentUpdate` check on props.
* This should be used as a last resort, since the normalized data should be
* maintained by the reducer result in state.
*
* @type {Array}
*/
const EMPTY_ARRAY = [];
/**
* Shared reference to an empty Set for cases where it is important to avoid
* returning a new Set reference on every invocation, as in a connected or
* other pure component which performs `shouldComponentUpdate` check on props.
* This should be used as a last resort, since the normalized data should be
* maintained by the reducer result in state.
*
* @type {Set}
*/
const EMPTY_SET = new Set();
/**
* Returns a block's name given its client ID, or null if no block exists with
* the client ID.
*
* @param {Object} state Editor state.
* @param {string} clientId Block client ID.
*
* @return {string} Block name.
*/
function getBlockName(state, clientId) {
const block = state.blocks.byClientId.get(clientId);
const socialLinkName = 'core/social-link';
if (external_wp_element_namespaceObject.Platform.OS !== 'web' && block?.name === socialLinkName) {
const attributes = state.blocks.attributes.get(clientId);
const {
service
} = attributes !== null && attributes !== void 0 ? attributes : {};
return service ? `${socialLinkName}-${service}` : socialLinkName;
}
return block ? block.name : null;
}
/**
* Returns whether a block is valid or not.
*
* @param {Object} state Editor state.
* @param {string} clientId Block client ID.
*
* @return {boolean} Is Valid.
*/
function isBlockValid(state, clientId) {
const block = state.blocks.byClientId.get(clientId);
return !!block && block.isValid;
}
/**
* Returns a block's attributes given its client ID, or null if no block exists with
* the client ID.
*
* @param {Object} state Editor state.
* @param {string} clientId Block client ID.
*
* @return {Object?} Block attributes.
*/
function getBlockAttributes(state, clientId) {
const block = state.blocks.byClientId.get(clientId);
if (!block) {
return null;
}
return state.blocks.attributes.get(clientId);
}
/**
* Returns a block given its client ID. This is a parsed copy of the block,
* containing its `blockName`, `clientId`, and current `attributes` state. This
* is not the block's registration settings, which must be retrieved from the
* blocks module registration store.
*
* getBlock recurses through its inner blocks until all its children blocks have
* been retrieved. Note that getBlock will not return the child inner blocks of
* an inner block controller. This is because an inner block controller syncs
* itself with its own entity, and should therefore not be included with the
* blocks of a different entity. For example, say you call `getBlocks( TP )` to
* get the blocks of a template part. If another template part is a child of TP,
* then the nested template part's child blocks will not be returned. This way,
* the template block itself is considered part of the parent, but the children
* are not.
*
* @param {Object} state Editor state.
* @param {string} clientId Block client ID.
*
* @return {Object} Parsed block object.
*/
function getBlock(state, clientId) {
if (!state.blocks.byClientId.has(clientId)) {
return null;
}
return state.blocks.tree.get(clientId);
}
const __unstableGetBlockWithoutInnerBlocks = rememo((state, clientId) => {
if (!state.blocks.byClientId.has(clientId)) {
return null;
}
return {
...state.blocks.byClientId.get(clientId),
attributes: getBlockAttributes(state, clientId)
};
}, (state, clientId) => [state.blocks.byClientId.get(clientId), state.blocks.attributes.get(clientId)]);
/**
* Returns all block objects for the current post being edited as an array in
* the order they appear in the post. Note that this will exclude child blocks
* of nested inner block controllers.
*
* @param {Object} state Editor state.
* @param {?string} rootClientId Optional root client ID of block list.
*
* @return {Object[]} Post blocks.
*/
function getBlocks(state, rootClientId) {
const treeKey = !rootClientId || !areInnerBlocksControlled(state, rootClientId) ? rootClientId || '' : 'controlled||' + rootClientId;
return state.blocks.tree.get(treeKey)?.innerBlocks || EMPTY_ARRAY;
}
/**
* Returns a stripped down block object containing only its client ID,
* and its inner blocks' client IDs.
*
* @deprecated
*
* @param {Object} state Editor state.
* @param {string} clientId Client ID of the block to get.
*
* @return {Object} Client IDs of the post blocks.
*/
const __unstableGetClientIdWithClientIdsTree = rememo((state, clientId) => {
external_wp_deprecated_default()("wp.data.select( 'core/block-editor' ).__unstableGetClientIdWithClientIdsTree", {
since: '6.3',
version: '6.5'
});
return {
clientId,
innerBlocks: __unstableGetClientIdsTree(state, clientId)
};
}, state => [state.blocks.order]);
/**
* Returns the block tree represented in the block-editor store from the
* given root, consisting of stripped down block objects containing only
* their client IDs, and their inner blocks' client IDs.
*
* @deprecated
*
* @param {Object} state Editor state.
* @param {?string} rootClientId Optional root client ID of block list.
*
* @return {Object[]} Client IDs of the post blocks.
*/
const __unstableGetClientIdsTree = rememo((state, rootClientId = '') => {
external_wp_deprecated_default()("wp.data.select( 'core/block-editor' ).__unstableGetClientIdsTree", {
since: '6.3',
version: '6.5'
});
return getBlockOrder(state, rootClientId).map(clientId => __unstableGetClientIdWithClientIdsTree(state, clientId));
}, state => [state.blocks.order]);
/**
* Returns an array containing the clientIds of all descendants of the blocks
* given. Returned ids are ordered first by the order of the ids given, then
* by the order that they appear in the editor.
*
* @param {Object} state Global application state.
* @param {string|string[]} clientIds Client ID(s) for which descendant blocks are to be returned.
*
* @return {Array} Client IDs of descendants.
*/
const getClientIdsOfDescendants = rememo((state, clientIds) => {
const givenIds = Array.isArray(clientIds) ? clientIds : [clientIds];
const collectedIds = [];
for (const givenId of givenIds) {
for (const descendantId of getBlockOrder(state, givenId)) {
collectedIds.push(descendantId, ...getClientIdsOfDescendants(state, descendantId));
}
}
return collectedIds;
}, state => [state.blocks.order]);
/**
* Returns an array containing the clientIds of the top-level blocks and
* their descendants of any depth (for nested blocks). Ids are returned
* in the same order that they appear in the editor.
*
* @param {Object} state Global application state.
*
* @return {Array} ids of top-level and descendant blocks.
*/
const getClientIdsWithDescendants = rememo(state => {
const collectedIds = [];
for (const topLevelId of getBlockOrder(state)) {
collectedIds.push(topLevelId, ...getClientIdsOfDescendants(state, topLevelId));
}
return collectedIds;
}, state => [state.blocks.order]);
/**
* Returns the total number of blocks, or the total number of blocks with a specific name in a post.
* The number returned includes nested blocks.
*
* @param {Object} state Global application state.
* @param {?string} blockName Optional block name, if specified only blocks of that type will be counted.
*
* @return {number} Number of blocks in the post, or number of blocks with name equal to blockName.
*/
const getGlobalBlockCount = rememo((state, blockName) => {
const clientIds = getClientIdsWithDescendants(state);
if (!blockName) {
return clientIds.length;
}
return clientIds.reduce((accumulator, clientId) => {
const block = state.blocks.byClientId.get(clientId);
return block.name === blockName ? accumulator + 1 : accumulator;
}, 0);
}, state => [state.blocks.order, state.blocks.byClientId]);
/**
* Returns all global blocks that match a blockName. Results include nested blocks.
*
* @param {Object} state Global application state.
* @param {?string} blockName Optional block name, if not specified, returns an empty array.
*
* @return {Array} Array of clientIds of blocks with name equal to blockName.
*/
const __experimentalGetGlobalBlocksByName = rememo((state, blockName) => {
if (!blockName) {
return EMPTY_ARRAY;
}
const blockNames = Array.isArray(blockName) ? blockName : [blockName];
const clientIds = getClientIdsWithDescendants(state);
const foundBlocks = clientIds.filter(clientId => {
const block = state.blocks.byClientId.get(clientId);
return blockNames.includes(block.name);
});
return foundBlocks.length > 0 ? foundBlocks : EMPTY_ARRAY;
}, state => [state.blocks.order, state.blocks.byClientId]);
/**
* Given an array of block client IDs, returns the corresponding array of block
* objects.
*
* @param {Object} state Editor state.
* @param {string[]} clientIds Client IDs for which blocks are to be returned.
*
* @return {WPBlock[]} Block objects.
*/
const getBlocksByClientId = rememo((state, clientIds) => (Array.isArray(clientIds) ? clientIds : [clientIds]).map(clientId => getBlock(state, clientId)), (state, clientIds) => (Array.isArray(clientIds) ? clientIds : [clientIds]).map(clientId => state.blocks.tree.get(clientId)));
/**
* Given an array of block client IDs, returns the corresponding array of block
* names.
*
* @param {Object} state Editor state.
* @param {string[]} clientIds Client IDs for which block names are to be returned.
*
* @return {string[]} Block names.
*/
const getBlockNamesByClientId = rememo((state, clientIds) => getBlocksByClientId(state, clientIds).filter(Boolean).map(block => block.name), (state, clientIds) => getBlocksByClientId(state, clientIds));
/**
* Returns the number of blocks currently present in the post.
*
* @param {Object} state Editor state.
* @param {?string} rootClientId Optional root client ID of block list.
*
* @return {number} Number of blocks in the post.
*/
function getBlockCount(state, rootClientId) {
return getBlockOrder(state, rootClientId).length;
}
/**
* Returns the current selection start block client ID, attribute key and text
* offset.
*
* @param {Object} state Block editor state.
*
* @return {WPBlockSelection} Selection start information.
*/
function getSelectionStart(state) {
return state.selection.selectionStart;
}
/**
* Returns the current selection end block client ID, attribute key and text
* offset.
*
* @param {Object} state Block editor state.
*
* @return {WPBlockSelection} Selection end information.
*/
function getSelectionEnd(state) {
return state.selection.selectionEnd;
}
/**
* Returns the current block selection start. This value may be null, and it
* may represent either a singular block selection or multi-selection start.
* A selection is singular if its start and end match.
*
* @param {Object} state Global application state.
*
* @return {?string} Client ID of block selection start.
*/
function getBlockSelectionStart(state) {
return state.selection.selectionStart.clientId;
}
/**
* Returns the current block selection end. This value may be null, and it
* may represent either a singular block selection or multi-selection end.
* A selection is singular if its start and end match.
*
* @param {Object} state Global application state.
*
* @return {?string} Client ID of block selection end.
*/
function getBlockSelectionEnd(state) {
return state.selection.selectionEnd.clientId;
}
/**
* Returns the number of blocks currently selected in the post.
*
* @param {Object} state Global application state.
*
* @return {number} Number of blocks selected in the post.
*/
function getSelectedBlockCount(state) {
const multiSelectedBlockCount = getMultiSelectedBlockClientIds(state).length;
if (multiSelectedBlockCount) {
return multiSelectedBlockCount;
}
return state.selection.selectionStart.clientId ? 1 : 0;
}
/**
* Returns true if there is a single selected block, or false otherwise.
*
* @param {Object} state Editor state.
*
* @return {boolean} Whether a single block is selected.
*/
function hasSelectedBlock(state) {
const {
selectionStart,
selectionEnd
} = state.selection;
return !!selectionStart.clientId && selectionStart.clientId === selectionEnd.clientId;
}
/**
* Returns the currently selected block client ID, or null if there is no
* selected block.
*
* @param {Object} state Editor state.
*
* @return {?string} Selected block client ID.
*/
function getSelectedBlockClientId(state) {
const {
selectionStart,
selectionEnd
} = state.selection;
const {
clientId
} = selectionStart;
if (!clientId || clientId !== selectionEnd.clientId) {
return null;
}
return clientId;
}
/**
* Returns the currently selected block, or null if there is no selected block.
*
* @param {Object} state Global application state.
*
* @return {?Object} Selected block.
*/
function getSelectedBlock(state) {
const clientId = getSelectedBlockClientId(state);
return clientId ? getBlock(state, clientId) : null;
}
/**
* Given a block client ID, returns the root block from which the block is
* nested, an empty string for top-level blocks, or null if the block does not
* exist.
*
* @param {Object} state Editor state.
* @param {string} clientId Block from which to find root client ID.
*
* @return {?string} Root client ID, if exists
*/
function getBlockRootClientId(state, clientId) {
return state.blocks.parents.has(clientId) ? state.blocks.parents.get(clientId) : null;
}
/**
* Given a block client ID, returns the list of all its parents from top to bottom.
*
* @param {Object} state Editor state.
* @param {string} clientId Block from which to find root client ID.
* @param {boolean} ascending Order results from bottom to top (true) or top to bottom (false).
*
* @return {Array} ClientIDs of the parent blocks.
*/
const getBlockParents = rememo((state, clientId, ascending = false) => {
const parents = [];
let current = clientId;
while (!!state.blocks.parents.get(current)) {
current = state.blocks.parents.get(current);
parents.push(current);
}
if (!parents.length) {
return EMPTY_ARRAY;
}
return ascending ? parents : parents.reverse();
}, state => [state.blocks.parents]);
/**
* Given a block client ID and a block name, returns the list of all its parents
* from top to bottom, filtered by the given name(s). For example, if passed
* 'core/group' as the blockName, it will only return parents which are group
* blocks. If passed `[ 'core/group', 'core/cover']`, as the blockName, it will
* return parents which are group blocks and parents which are cover blocks.
*
* @param {Object} state Editor state.
* @param {string} clientId Block from which to find root client ID.
* @param {string|string[]} blockName Block name(s) to filter.
* @param {boolean} ascending Order results from bottom to top (true) or top to bottom (false).
*
* @return {Array} ClientIDs of the parent blocks.
*/
const getBlockParentsByBlockName = rememo((state, clientId, blockName, ascending = false) => {
const parents = getBlockParents(state, clientId, ascending);
const hasName = Array.isArray(blockName) ? name => blockName.includes(name) : name => blockName === name;
return parents.filter(id => hasName(getBlockName(state, id)));
}, state => [state.blocks.parents]);
/**
* Given a block client ID, returns the root of the hierarchy from which the block is nested, return the block itself for root level blocks.
*
* @param {Object} state Editor state.
* @param {string} clientId Block from which to find root client ID.
*
* @return {string} Root client ID
*/
function getBlockHierarchyRootClientId(state, clientId) {
let current = clientId;
let parent;
do {
parent = current;
current = state.blocks.parents.get(current);
} while (current);
return parent;
}
/**
* Given a block client ID, returns the lowest common ancestor with selected client ID.
*
* @param {Object} state Editor state.
* @param {string} clientId Block from which to find common ancestor client ID.
*
* @return {string} Common ancestor client ID or undefined
*/
function getLowestCommonAncestorWithSelectedBlock(state, clientId) {
const selectedId = getSelectedBlockClientId(state);
const clientParents = [...getBlockParents(state, clientId), clientId];
const selectedParents = [...getBlockParents(state, selectedId), selectedId];
let lowestCommonAncestor;
const maxDepth = Math.min(clientParents.length, selectedParents.length);
for (let index = 0; index < maxDepth; index++) {
if (clientParents[index] === selectedParents[index]) {
lowestCommonAncestor = clientParents[index];
} else {
break;
}
}
return lowestCommonAncestor;
}
/**
* Returns the client ID of the block adjacent one at the given reference
* startClientId and modifier directionality. Defaults start startClientId to
* the selected block, and direction as next block. Returns null if there is no
* adjacent block.
*
* @param {Object} state Editor state.
* @param {?string} startClientId Optional client ID of block from which to
* search.
* @param {?number} modifier Directionality multiplier (1 next, -1
* previous).
*
* @return {?string} Return the client ID of the block, or null if none exists.
*/
function getAdjacentBlockClientId(state, startClientId, modifier = 1) {
// Default to selected block.
if (startClientId === undefined) {
startClientId = getSelectedBlockClientId(state);
}
// Try multi-selection starting at extent based on modifier.
if (startClientId === undefined) {
if (modifier < 0) {
startClientId = getFirstMultiSelectedBlockClientId(state);
} else {
startClientId = getLastMultiSelectedBlockClientId(state);
}
}
// Validate working start client ID.
if (!startClientId) {
return null;
}
// Retrieve start block root client ID, being careful to allow the falsey
// empty string top-level root by explicitly testing against null.
const rootClientId = getBlockRootClientId(state, startClientId);
if (rootClientId === null) {
return null;
}
const {
order
} = state.blocks;
const orderSet = order.get(rootClientId);
const index = orderSet.indexOf(startClientId);
const nextIndex = index + 1 * modifier;
// Block was first in set and we're attempting to get previous.
if (nextIndex < 0) {
return null;
}
// Block was last in set and we're attempting to get next.
if (nextIndex === orderSet.length) {
return null;
}
// Assume incremented index is within the set.
return orderSet[nextIndex];
}
/**
* Returns the previous block's client ID from the given reference start ID.
* Defaults start to the selected block. Returns null if there is no previous
* block.
*
* @param {Object} state Editor state.
* @param {?string} startClientId Optional client ID of block from which to
* search.
*
* @return {?string} Adjacent block's client ID, or null if none exists.
*/
function getPreviousBlockClientId(state, startClientId) {
return getAdjacentBlockClientId(state, startClientId, -1);
}
/**
* Returns the next block's client ID from the given reference start ID.
* Defaults start to the selected block. Returns null if there is no next
* block.
*
* @param {Object} state Editor state.
* @param {?string} startClientId Optional client ID of block from which to
* search.
*
* @return {?string} Adjacent block's client ID, or null if none exists.
*/
function getNextBlockClientId(state, startClientId) {
return getAdjacentBlockClientId(state, startClientId, 1);
}
/* eslint-disable jsdoc/valid-types */
/**
* Returns the initial caret position for the selected block.
* This position is to used to position the caret properly when the selected block changes.
* If the current block is not a RichText, having initial position set to 0 means "focus block"
*
* @param {Object} state Global application state.
*
* @return {0|-1|null} Initial position.
*/
function getSelectedBlocksInitialCaretPosition(state) {
/* eslint-enable jsdoc/valid-types */
return state.initialPosition;
}
/**
* Returns the current selection set of block client IDs (multiselection or single selection).
*
* @param {Object} state Editor state.
*
* @return {Array} Multi-selected block client IDs.
*/
const getSelectedBlockClientIds = rememo(state => {
const {
selectionStart,
selectionEnd
} = state.selection;
if (!selectionStart.clientId || !selectionEnd.clientId) {
return EMPTY_ARRAY;
}
if (selectionStart.clientId === selectionEnd.clientId) {
return [selectionStart.clientId];
}
// Retrieve root client ID to aid in retrieving relevant nested block
// order, being careful to allow the falsey empty string top-level root
// by explicitly testing against null.
const rootClientId = getBlockRootClientId(state, selectionStart.clientId);
if (rootClientId === null) {
return EMPTY_ARRAY;
}
const blockOrder = getBlockOrder(state, rootClientId);
const startIndex = blockOrder.indexOf(selectionStart.clientId);
const endIndex = blockOrder.indexOf(selectionEnd.clientId);
if (startIndex > endIndex) {
return blockOrder.slice(endIndex, startIndex + 1);
}
return blockOrder.slice(startIndex, endIndex + 1);
}, state => [state.blocks.order, state.selection.selectionStart.clientId, state.selection.selectionEnd.clientId]);
/**
* Returns the current multi-selection set of block client IDs, or an empty
* array if there is no multi-selection.
*
* @param {Object} state Editor state.
*
* @return {Array} Multi-selected block client IDs.
*/
function getMultiSelectedBlockClientIds(state) {
const {
selectionStart,
selectionEnd
} = state.selection;
if (selectionStart.clientId === selectionEnd.clientId) {
return EMPTY_ARRAY;
}
return getSelectedBlockClientIds(state);
}
/**
* Returns the current multi-selection set of blocks, or an empty array if
* there is no multi-selection.
*
* @param {Object} state Editor state.
*
* @return {Array} Multi-selected block objects.
*/
const getMultiSelectedBlocks = rememo(state => {
const multiSelectedBlockClientIds = getMultiSelectedBlockClientIds(state);
if (!multiSelectedBlockClientIds.length) {
return EMPTY_ARRAY;
}
return multiSelectedBlockClientIds.map(clientId => getBlock(state, clientId));
}, state => [...getSelectedBlockClientIds.getDependants(state), state.blocks.byClientId, state.blocks.order, state.blocks.attributes]);
/**
* Returns the client ID of the first block in the multi-selection set, or null
* if there is no multi-selection.
*
* @param {Object} state Editor state.
*
* @return {?string} First block client ID in the multi-selection set.
*/
function getFirstMultiSelectedBlockClientId(state) {
return getMultiSelectedBlockClientIds(state)[0] || null;
}
/**
* Returns the client ID of the last block in the multi-selection set, or null
* if there is no multi-selection.
*
* @param {Object} state Editor state.
*
* @return {?string} Last block client ID in the multi-selection set.
*/
function getLastMultiSelectedBlockClientId(state) {
const selectedClientIds = getMultiSelectedBlockClientIds(state);
return selectedClientIds[selectedClientIds.length - 1] || null;
}
/**
* Returns true if a multi-selection exists, and the block corresponding to the
* specified client ID is the first block of the multi-selection set, or false
* otherwise.
*
* @param {Object} state Editor state.
* @param {string} clientId Block client ID.
*
* @return {boolean} Whether block is first in multi-selection.
*/
function isFirstMultiSelectedBlock(state, clientId) {
return getFirstMultiSelectedBlockClientId(state) === clientId;
}
/**
* Returns true if the client ID occurs within the block multi-selection, or
* false otherwise.
*
* @param {Object} state Editor state.
* @param {string} clientId Block client ID.
*
* @return {boolean} Whether block is in multi-selection set.
*/
function isBlockMultiSelected(state, clientId) {
return getMultiSelectedBlockClientIds(state).indexOf(clientId) !== -1;
}
/**
* Returns true if an ancestor of the block is multi-selected, or false
* otherwise.
*
* @param {Object} state Editor state.
* @param {string} clientId Block client ID.
*
* @return {boolean} Whether an ancestor of the block is in multi-selection
* set.
*/
const isAncestorMultiSelected = rememo((state, clientId) => {
let ancestorClientId = clientId;
let isMultiSelected = false;
while (ancestorClientId && !isMultiSelected) {
ancestorClientId = getBlockRootClientId(state, ancestorClientId);
isMultiSelected = isBlockMultiSelected(state, ancestorClientId);
}
return isMultiSelected;
}, state => [state.blocks.order, state.selection.selectionStart.clientId, state.selection.selectionEnd.clientId]);
/**
* Returns the client ID of the block which begins the multi-selection set, or
* null if there is no multi-selection.
*
* This is not necessarily the first client ID in the selection.
*
* @see getFirstMultiSelectedBlockClientId
*
* @param {Object} state Editor state.
*
* @return {?string} Client ID of block beginning multi-selection.
*/
function getMultiSelectedBlocksStartClientId(state) {
const {
selectionStart,
selectionEnd
} = state.selection;
if (selectionStart.clientId === selectionEnd.clientId) {
return null;
}
return selectionStart.clientId || null;
}
/**
* Returns the client ID of the block which ends the multi-selection set, or
* null if there is no multi-selection.
*
* This is not necessarily the last client ID in the selection.
*
* @see getLastMultiSelectedBlockClientId
*
* @param {Object} state Editor state.
*
* @return {?string} Client ID of block ending multi-selection.
*/
function getMultiSelectedBlocksEndClientId(state) {
const {
selectionStart,
selectionEnd
} = state.selection;
if (selectionStart.clientId === selectionEnd.clientId) {
return null;
}
return selectionEnd.clientId || null;
}
/**
* Returns true if the selection is not partial.
*
* @param {Object} state Editor state.
*
* @return {boolean} Whether the selection is mergeable.
*/
function __unstableIsFullySelected(state) {
const selectionAnchor = getSelectionStart(state);
const selectionFocus = getSelectionEnd(state);
return !selectionAnchor.attributeKey && !selectionFocus.attributeKey && typeof selectionAnchor.offset === 'undefined' && typeof selectionFocus.offset === 'undefined';
}
/**
* Returns true if the selection is collapsed.
*
* @param {Object} state Editor state.
*
* @return {boolean} Whether the selection is collapsed.
*/
function __unstableIsSelectionCollapsed(state) {
const selectionAnchor = getSelectionStart(state);
const selectionFocus = getSelectionEnd(state);
return !!selectionAnchor && !!selectionFocus && selectionAnchor.clientId === selectionFocus.clientId && selectionAnchor.attributeKey === selectionFocus.attributeKey && selectionAnchor.offset === selectionFocus.offset;
}
function __unstableSelectionHasUnmergeableBlock(state) {
return getSelectedBlockClientIds(state).some(clientId => {
const blockName = getBlockName(state, clientId);
const blockType = (0,external_wp_blocks_namespaceObject.getBlockType)(blockName);
return !blockType.merge;
});
}
/**
* Check whether the selection is mergeable.
*
* @param {Object} state Editor state.
* @param {boolean} isForward Whether to merge forwards.
*
* @return {boolean} Whether the selection is mergeable.
*/
function __unstableIsSelectionMergeable(state, isForward) {
const selectionAnchor = getSelectionStart(state);
const selectionFocus = getSelectionEnd(state);
// It's not mergeable if the start and end are within the same block.
if (selectionAnchor.clientId === selectionFocus.clientId) return false;
// It's not mergeable if there's no rich text selection.
if (!selectionAnchor.attributeKey || !selectionFocus.attributeKey || typeof selectionAnchor.offset === 'undefined' || typeof selectionFocus.offset === 'undefined') return false;
const anchorRootClientId = getBlockRootClientId(state, selectionAnchor.clientId);
const focusRootClientId = getBlockRootClientId(state, selectionFocus.clientId);
// It's not mergeable if the selection doesn't start and end in the same
// block list. Maybe in the future it should be allowed.
if (anchorRootClientId !== focusRootClientId) {
return false;
}
const blockOrder = getBlockOrder(state, anchorRootClientId);
const anchorIndex = blockOrder.indexOf(selectionAnchor.clientId);
const focusIndex = blockOrder.indexOf(selectionFocus.clientId);
// Reassign selection start and end based on order.
let selectionStart, selectionEnd;
if (anchorIndex > focusIndex) {
selectionStart = selectionFocus;
selectionEnd = selectionAnchor;
} else {
selectionStart = selectionAnchor;
selectionEnd = selectionFocus;
}
const targetBlockClientId = isForward ? selectionEnd.clientId : selectionStart.clientId;
const blockToMergeClientId = isForward ? selectionStart.clientId : selectionEnd.clientId;
const targetBlockName = getBlockName(state, targetBlockClientId);
const targetBlockType = (0,external_wp_blocks_namespaceObject.getBlockType)(targetBlockName);
if (!targetBlockType.merge) return false;
const blockToMerge = getBlock(state, blockToMergeClientId);
// It's mergeable if the blocks are of the same type.
if (blockToMerge.name === targetBlockName) return true;
// If the blocks are of a different type, try to transform the block being
// merged into the same type of block.
const blocksToMerge = (0,external_wp_blocks_namespaceObject.switchToBlockType)(blockToMerge, targetBlockName);
return blocksToMerge && blocksToMerge.length;
}
/**
* Get partial selected blocks with their content updated
* based on the selection.
*
* @param {Object} state Editor state.
*
* @return {Object[]} Updated partial selected blocks.
*/
const __unstableGetSelectedBlocksWithPartialSelection = state => {
const selectionAnchor = getSelectionStart(state);
const selectionFocus = getSelectionEnd(state);
if (selectionAnchor.clientId === selectionFocus.clientId) {
return EMPTY_ARRAY;
}
// Can't split if the selection is not set.
if (!selectionAnchor.attributeKey || !selectionFocus.attributeKey || typeof selectionAnchor.offset === 'undefined' || typeof selectionFocus.offset === 'undefined') {
return EMPTY_ARRAY;
}
const anchorRootClientId = getBlockRootClientId(state, selectionAnchor.clientId);
const focusRootClientId = getBlockRootClientId(state, selectionFocus.clientId);
// It's not splittable if the selection doesn't start and end in the same
// block list. Maybe in the future it should be allowed.
if (anchorRootClientId !== focusRootClientId) {
return EMPTY_ARRAY;
}
const blockOrder = getBlockOrder(state, anchorRootClientId);
const anchorIndex = blockOrder.indexOf(selectionAnchor.clientId);
const focusIndex = blockOrder.indexOf(selectionFocus.clientId);
// Reassign selection start and end based on order.
const [selectionStart, selectionEnd] = anchorIndex > focusIndex ? [selectionFocus, selectionAnchor] : [selectionAnchor, selectionFocus];
const blockA = getBlock(state, selectionStart.clientId);
const blockAType = (0,external_wp_blocks_namespaceObject.getBlockType)(blockA.name);
const blockB = getBlock(state, selectionEnd.clientId);
const blockBType = (0,external_wp_blocks_namespaceObject.getBlockType)(blockB.name);
const htmlA = blockA.attributes[selectionStart.attributeKey];
const htmlB = blockB.attributes[selectionEnd.attributeKey];
const attributeDefinitionA = blockAType.attributes[selectionStart.attributeKey];
const attributeDefinitionB = blockBType.attributes[selectionEnd.attributeKey];
let valueA = (0,external_wp_richText_namespaceObject.create)({
html: htmlA,
...mapRichTextSettings(attributeDefinitionA)
});
let valueB = (0,external_wp_richText_namespaceObject.create)({
html: htmlB,
...mapRichTextSettings(attributeDefinitionB)
});
valueA = (0,external_wp_richText_namespaceObject.remove)(valueA, 0, selectionStart.offset);
valueB = (0,external_wp_richText_namespaceObject.remove)(valueB, selectionEnd.offset, valueB.text.length);
return [{
...blockA,
attributes: {
...blockA.attributes,
[selectionStart.attributeKey]: (0,external_wp_richText_namespaceObject.toHTMLString)({
value: valueA,
...mapRichTextSettings(attributeDefinitionA)
})
}
}, {
...blockB,
attributes: {
...blockB.attributes,
[selectionEnd.attributeKey]: (0,external_wp_richText_namespaceObject.toHTMLString)({
value: valueB,
...mapRichTextSettings(attributeDefinitionB)
})
}
}];
};
/**
* Returns an array containing all block client IDs in the editor in the order
* they appear. Optionally accepts a root client ID of the block list for which
* the order should be returned, defaulting to the top-level block order.
*
* @param {Object} state Editor state.
* @param {?string} rootClientId Optional root client ID of block list.
*
* @return {Array} Ordered client IDs of editor blocks.
*/
function getBlockOrder(state, rootClientId) {
return state.blocks.order.get(rootClientId || '') || EMPTY_ARRAY;
}
/**
* Returns the index at which the block corresponding to the specified client
* ID occurs within the block order, or `-1` if the block does not exist.
*
* @param {Object} state Editor state.
* @param {string} clientId Block client ID.
*
* @return {number} Index at which block exists in order.
*/
function getBlockIndex(state, clientId) {
const rootClientId = getBlockRootClientId(state, clientId);
return getBlockOrder(state, rootClientId).indexOf(clientId);
}
/**
* Returns true if the block corresponding to the specified client ID is
* currently selected and no multi-selection exists, or false otherwise.
*
* @param {Object} state Editor state.
* @param {string} clientId Block client ID.
*
* @return {boolean} Whether block is selected and multi-selection exists.
*/
function isBlockSelected(state, clientId) {
const {
selectionStart,
selectionEnd
} = state.selection;
if (selectionStart.clientId !== selectionEnd.clientId) {
return false;
}
return selectionStart.clientId === clientId;
}
/**
* Returns true if one of the block's inner blocks is selected.
*
* @param {Object} state Editor state.
* @param {string} clientId Block client ID.
* @param {boolean} deep Perform a deep check.
*
* @return {boolean} Whether the block has an inner block selected
*/
function hasSelectedInnerBlock(state, clientId, deep = false) {
return getBlockOrder(state, clientId).some(innerClientId => isBlockSelected(state, innerClientId) || isBlockMultiSelected(state, innerClientId) || deep && hasSelectedInnerBlock(state, innerClientId, deep));
}
/**
* Returns true if one of the block's inner blocks is dragged.
*
* @param {Object} state Editor state.
* @param {string} clientId Block client ID.
* @param {boolean} deep Perform a deep check.
*
* @return {boolean} Whether the block has an inner block dragged
*/
function hasDraggedInnerBlock(state, clientId, deep = false) {
return getBlockOrder(state, clientId).some(innerClientId => isBlockBeingDragged(state, innerClientId) || deep && hasDraggedInnerBlock(state, innerClientId, deep));
}
/**
* Returns true if the block corresponding to the specified client ID is
* currently selected but isn't the last of the selected blocks. Here "last"
* refers to the block sequence in the document, _not_ the sequence of
* multi-selection, which is why `state.selectionEnd` isn't used.
*
* @param {Object} state Editor state.
* @param {string} clientId Block client ID.
*
* @return {boolean} Whether block is selected and not the last in the
* selection.
*/
function isBlockWithinSelection(state, clientId) {
if (!clientId) {
return false;
}
const clientIds = getMultiSelectedBlockClientIds(state);
const index = clientIds.indexOf(clientId);
return index > -1 && index < clientIds.length - 1;
}
/**
* Returns true if a multi-selection has been made, or false otherwise.
*
* @param {Object} state Editor state.
*
* @return {boolean} Whether multi-selection has been made.
*/
function hasMultiSelection(state) {
const {
selectionStart,
selectionEnd
} = state.selection;
return selectionStart.clientId !== selectionEnd.clientId;
}
/**
* Whether in the process of multi-selecting or not. This flag is only true
* while the multi-selection is being selected (by mouse move), and is false
* once the multi-selection has been settled.
*
* @see hasMultiSelection
*
* @param {Object} state Global application state.
*
* @return {boolean} True if multi-selecting, false if not.
*/
function selectors_isMultiSelecting(state) {
return state.isMultiSelecting;
}
/**
* Selector that returns if multi-selection is enabled or not.
*
* @param {Object} state Global application state.
*
* @return {boolean} True if it should be possible to multi-select blocks, false if multi-selection is disabled.
*/
function selectors_isSelectionEnabled(state) {
return state.isSelectionEnabled;
}
/**
* Returns the block's editing mode, defaulting to "visual" if not explicitly
* assigned.
*
* @param {Object} state Editor state.
* @param {string} clientId Block client ID.
*
* @return {Object} Block editing mode.
*/
function getBlockMode(state, clientId) {
return state.blocksMode[clientId] || 'visual';
}
/**
* Returns true if the user is typing, or false otherwise.
*
* @param {Object} state Global application state.
*
* @return {boolean} Whether user is typing.
*/
function selectors_isTyping(state) {
return state.isTyping;
}
/**
* Returns true if the user is dragging blocks, or false otherwise.
*
* @param {Object} state Global application state.
*
* @return {boolean} Whether user is dragging blocks.
*/
function isDraggingBlocks(state) {
return !!state.draggedBlocks.length;
}
/**
* Returns the client ids of any blocks being directly dragged.
*
* This does not include children of a parent being dragged.
*
* @param {Object} state Global application state.
*
* @return {string[]} Array of dragged block client ids.
*/
function getDraggedBlockClientIds(state) {
return state.draggedBlocks;
}
/**
* Returns whether the block is being dragged.
*
* Only returns true if the block is being directly dragged,
* not if the block is a child of a parent being dragged.
* See `isAncestorBeingDragged` for child blocks.
*
* @param {Object} state Global application state.
* @param {string} clientId Client id for block to check.
*
* @return {boolean} Whether the block is being dragged.
*/
function isBlockBeingDragged(state, clientId) {
return state.draggedBlocks.includes(clientId);
}
/**
* Returns whether a parent/ancestor of the block is being dragged.
*
* @param {Object} state Global application state.
* @param {string} clientId Client id for block to check.
*
* @return {boolean} Whether the block's ancestor is being dragged.
*/
function isAncestorBeingDragged(state, clientId) {
// Return early if no blocks are being dragged rather than
// the more expensive check for parents.
if (!isDraggingBlocks(state)) {
return false;
}
const parents = getBlockParents(state, clientId);
return parents.some(parentClientId => isBlockBeingDragged(state, parentClientId));
}
/**
* Returns true if the caret is within formatted text, or false otherwise.
*
* @deprecated
*
* @return {boolean} Whether the caret is within formatted text.
*/
function isCaretWithinFormattedText() {
external_wp_deprecated_default()('wp.data.select( "core/block-editor" ).isCaretWithinFormattedText', {
since: '6.1',
version: '6.3'
});
return false;
}
/**
* Returns the insertion point, the index at which the new inserted block would
* be placed. Defaults to the last index.
*
* @param {Object} state Editor state.
*
* @return {Object} Insertion point object with `rootClientId`, `index`.
*/
const getBlockInsertionPoint = rememo(state => {
let rootClientId, index;
const {
insertionPoint,
selection: {
selectionEnd
}
} = state;
if (insertionPoint !== null) {
return insertionPoint;
}
const {
clientId
} = selectionEnd;
if (clientId) {
rootClientId = getBlockRootClientId(state, clientId) || undefined;
index = getBlockIndex(state, selectionEnd.clientId) + 1;
} else {
index = getBlockOrder(state).length;
}
return {
rootClientId,
index
};
}, state => [state.insertionPoint, state.selection.selectionEnd.clientId, state.blocks.parents, state.blocks.order]);
/**
* Returns true if we should show the block insertion point.
*
* @param {Object} state Global application state.
*
* @return {?boolean} Whether the insertion point is visible or not.
*/
function isBlockInsertionPointVisible(state) {
return state.insertionPoint !== null;
}
/**
* Returns whether the blocks matches the template or not.
*
* @param {boolean} state
* @return {?boolean} Whether the template is valid or not.
*/
function isValidTemplate(state) {
return state.template.isValid;
}
/**
* Returns the defined block template
*
* @param {boolean} state
*
* @return {?Array} Block Template.
*/
function getTemplate(state) {
return state.settings.template;
}
/**
* Returns the defined block template lock. Optionally accepts a root block
* client ID as context, otherwise defaulting to the global context.
*
* @param {Object} state Editor state.
* @param {?string} rootClientId Optional block root client ID.
*
* @return {string|false} Block Template Lock
*/
function getTemplateLock(state, rootClientId) {
var _getBlockListSettings;
if (!rootClientId) {
var _state$settings$templ;
return (_state$settings$templ = state.settings.templateLock) !== null && _state$settings$templ !== void 0 ? _state$settings$templ : false;
}
return (_getBlockListSettings = getBlockListSettings(state, rootClientId)?.templateLock) !== null && _getBlockListSettings !== void 0 ? _getBlockListSettings : false;
}
const checkAllowList = (list, item, defaultResult = null) => {
if (typeof list === 'boolean') {
return list;
}
if (Array.isArray(list)) {
// TODO: when there is a canonical way to detect that we are editing a post
// the following check should be changed to something like:
// if ( list.includes( 'core/post-content' ) && getEditorMode() === 'post-content' && item === null )
if (list.includes('core/post-content') && item === null) {
return true;
}
return list.includes(item);
}
return defaultResult;
};
/**
* Determines if the given block type is allowed to be inserted into the block list.
* This function is not exported and not memoized because using a memoized selector
* inside another memoized selector is just a waste of time.
*
* @param {Object} state Editor state.
* @param {string|Object} blockName The block type object, e.g., the response
* from the block directory; or a string name of
* an installed block type, e.g.' core/paragraph'.
* @param {?string} rootClientId Optional root client ID of block list.
*
* @return {boolean} Whether the given block type is allowed to be inserted.
*/
const canInsertBlockTypeUnmemoized = (state, blockName, rootClientId = null) => {
let blockType;
if (blockName && 'object' === typeof blockName) {
blockType = blockName;
blockName = blockType.name;
} else {
blockType = (0,external_wp_blocks_namespaceObject.getBlockType)(blockName);
}
if (!blockType) {
return false;
}
const {
allowedBlockTypes
} = getSettings(state);
const isBlockAllowedInEditor = checkAllowList(allowedBlockTypes, blockName, true);
if (!isBlockAllowedInEditor) {
return false;
}
const isLocked = !!getTemplateLock(state, rootClientId);
if (isLocked) {
return false;
}
if (getBlockEditingMode(state, rootClientId !== null && rootClientId !== void 0 ? rootClientId : '') === 'disabled') {
return false;
}
const parentBlockListSettings = getBlockListSettings(state, rootClientId);
// The parent block doesn't have settings indicating it doesn't support
// inner blocks, return false.
if (rootClientId && parentBlockListSettings === undefined) {
return false;
}
const parentAllowedBlocks = parentBlockListSettings?.allowedBlocks;
const hasParentAllowedBlock = checkAllowList(parentAllowedBlocks, blockName);
const blockAllowedParentBlocks = blockType.parent;
const parentName = getBlockName(state, rootClientId);
const hasBlockAllowedParent = checkAllowList(blockAllowedParentBlocks, parentName);
let hasBlockAllowedAncestor = true;
const blockAllowedAncestorBlocks = blockType.ancestor;
if (blockAllowedAncestorBlocks) {
const ancestors = [rootClientId, ...getBlockParents(state, rootClientId)];
hasBlockAllowedAncestor = ancestors.some(ancestorClientId => checkAllowList(blockAllowedAncestorBlocks, getBlockName(state, ancestorClientId)));
}
const canInsert = hasBlockAllowedAncestor && (hasParentAllowedBlock === null && hasBlockAllowedParent === null || hasParentAllowedBlock === true || hasBlockAllowedParent === true);
if (!canInsert) {
return canInsert;
}
/**
* This filter is an ad-hoc solution to prevent adding template parts inside post content.
* Conceptually, having a filter inside a selector is bad pattern so this code will be
* replaced by a declarative API that doesn't the following drawbacks:
*
* Filters are not reactive: Upon switching between "template mode" and non "template mode",
* the filter and selector won't necessarily be executed again. For now, it doesn't matter much
* because you can't switch between the two modes while the inserter stays open.
*
* Filters are global: Once they're defined, they will affect all editor instances and all registries.
* An ideal API would only affect specific editor instances.
*/
return (0,external_wp_hooks_namespaceObject.applyFilters)('blockEditor.__unstableCanInsertBlockType', canInsert, blockType, rootClientId, {
// Pass bound selectors of the current registry. If we're in a nested
// context, the data will differ from the one selected from the root
// registry.
getBlock: getBlock.bind(null, state),
getBlockParentsByBlockName: getBlockParentsByBlockName.bind(null, state)
});
};
/**
* Determines if the given block type is allowed to be inserted into the block list.
*
* @param {Object} state Editor state.
* @param {string} blockName The name of the block type, e.g.' core/paragraph'.
* @param {?string} rootClientId Optional root client ID of block list.
*
* @return {boolean} Whether the given block type is allowed to be inserted.
*/
const canInsertBlockType = rememo(canInsertBlockTypeUnmemoized, (state, blockName, rootClientId) => [state.blockListSettings[rootClientId], state.blocks.byClientId.get(rootClientId), state.settings.allowedBlockTypes, state.settings.templateLock, state.blockEditingModes]);
/**
* Determines if the given blocks are allowed to be inserted into the block
* list.
*
* @param {Object} state Editor state.
* @param {string} clientIds The block client IDs to be inserted.
* @param {?string} rootClientId Optional root client ID of block list.
*
* @return {boolean} Whether the given blocks are allowed to be inserted.
*/
function canInsertBlocks(state, clientIds, rootClientId = null) {
return clientIds.every(id => canInsertBlockType(state, getBlockName(state, id), rootClientId));
}
/**
* Determines if the given block is allowed to be deleted.
*
* @param {Object} state Editor state.
* @param {string} clientId The block client Id.
* @param {?string} rootClientId Optional root client ID of block list.
*
* @return {boolean} Whether the given block is allowed to be removed.
*/
function canRemoveBlock(state, clientId, rootClientId = null) {
const attributes = getBlockAttributes(state, clientId);
if (attributes === null) {
return true;
}
if (attributes.lock?.remove !== undefined) {
return !attributes.lock.remove;
}
if (getTemplateLock(state, rootClientId)) {
return false;
}
return getBlockEditingMode(state, rootClientId) !== 'disabled';
}
/**
* Determines if the given blocks are allowed to be removed.
*
* @param {Object} state Editor state.
* @param {string} clientIds The block client IDs to be removed.
* @param {?string} rootClientId Optional root client ID of block list.
*
* @return {boolean} Whether the given blocks are allowed to be removed.
*/
function canRemoveBlocks(state, clientIds, rootClientId = null) {
return clientIds.every(clientId => canRemoveBlock(state, clientId, rootClientId));
}
/**
* Determines if the given block is allowed to be moved.
*
* @param {Object} state Editor state.
* @param {string} clientId The block client Id.
* @param {?string} rootClientId Optional root client ID of block list.
*
* @return {boolean | undefined} Whether the given block is allowed to be moved.
*/
function canMoveBlock(state, clientId, rootClientId = null) {
const attributes = getBlockAttributes(state, clientId);
if (attributes === null) {
return true;
}
if (attributes.lock?.move !== undefined) {
return !attributes.lock.move;
}
if (getTemplateLock(state, rootClientId) === 'all') {
return false;
}
return getBlockEditingMode(state, rootClientId) !== 'disabled';
}
/**
* Determines if the given blocks are allowed to be moved.
*
* @param {Object} state Editor state.
* @param {string} clientIds The block client IDs to be moved.
* @param {?string} rootClientId Optional root client ID of block list.
*
* @return {boolean} Whether the given blocks are allowed to be moved.
*/
function canMoveBlocks(state, clientIds, rootClientId = null) {
return clientIds.every(clientId => canMoveBlock(state, clientId, rootClientId));
}
/**
* Determines if the given block is allowed to be edited.
*
* @param {Object} state Editor state.
* @param {string} clientId The block client Id.
*
* @return {boolean} Whether the given block is allowed to be edited.
*/
function canEditBlock(state, clientId) {
const attributes = getBlockAttributes(state, clientId);
if (attributes === null) {
return true;
}
const {
lock
} = attributes;
// When the edit is true, we cannot edit the block.
return !lock?.edit;
}
/**
* Determines if the given block type can be locked/unlocked by a user.
*
* @param {Object} state Editor state.
* @param {(string|Object)} nameOrType Block name or type object.
*
* @return {boolean} Whether a given block type can be locked/unlocked.
*/
function canLockBlockType(state, nameOrType) {
if (!(0,external_wp_blocks_namespaceObject.hasBlockSupport)(nameOrType, 'lock', true)) {
return false;
}
// Use block editor settings as the default value.
return !!state.settings?.canLockBlocks;
}
/**
* Returns information about how recently and frequently a block has been inserted.
*
* @param {Object} state Global application state.
* @param {string} id A string which identifies the insert, e.g. 'core/block/12'
*
* @return {?{ time: number, count: number }} An object containing `time` which is when the last
* insert occurred as a UNIX epoch, and `count` which is
* the number of inserts that have occurred.
*/
function getInsertUsage(state, id) {
var _state$preferences$in;
return (_state$preferences$in = state.preferences.insertUsage?.[id]) !== null && _state$preferences$in !== void 0 ? _state$preferences$in : null;
}
/**
* Returns whether we can show a block type in the inserter
*
* @param {Object} state Global State
* @param {Object} blockType BlockType
* @param {?string} rootClientId Optional root client ID of block list.
*
* @return {boolean} Whether the given block type is allowed to be shown in the inserter.
*/
const canIncludeBlockTypeInInserter = (state, blockType, rootClientId) => {
if (!(0,external_wp_blocks_namespaceObject.hasBlockSupport)(blockType, 'inserter', true)) {
return false;
}
return canInsertBlockTypeUnmemoized(state, blockType.name, rootClientId);
};
/**
* Return a function to be used to tranform a block variation to an inserter item
*
* @param {Object} state Global State
* @param {Object} item Denormalized inserter item
* @return {Function} Function to transform a block variation to inserter item
*/
const getItemFromVariation = (state, item) => variation => {
const variationId = `${item.id}/${variation.name}`;
const {
time,
count = 0
} = getInsertUsage(state, variationId) || {};
return {
...item,
id: variationId,
icon: variation.icon || item.icon,
title: variation.title || item.title,
description: variation.description || item.description,
category: variation.category || item.category,
// If `example` is explicitly undefined for the variation, the preview will not be shown.
example: variation.hasOwnProperty('example') ? variation.example : item.example,
initialAttributes: {
...item.initialAttributes,
...variation.attributes
},
innerBlocks: variation.innerBlocks,
keywords: variation.keywords || item.keywords,
frecency: calculateFrecency(time, count)
};
};
/**
* Returns the calculated frecency.
*
* 'frecency' is a heuristic (https://en.wikipedia.org/wiki/Frecency)
* that combines block usage frequenty and recency.
*
* @param {number} time When the last insert occurred as a UNIX epoch
* @param {number} count The number of inserts that have occurred.
*
* @return {number} The calculated frecency.
*/
const calculateFrecency = (time, count) => {
if (!time) {
return count;
}
// The selector is cached, which means Date.now() is the last time that the
// relevant state changed. This suits our needs.
const duration = Date.now() - time;
switch (true) {
case duration < MILLISECONDS_PER_HOUR:
return count * 4;
case duration < MILLISECONDS_PER_DAY:
return count * 2;
case duration < MILLISECONDS_PER_WEEK:
return count / 2;
default:
return count / 4;
}
};
/**
* Returns a function that accepts a block type and builds an item to be shown
* in a specific context. It's used for building items for Inserter and available
* block Transfroms list.
*
* @param {Object} state Editor state.
* @param {Object} options Options object for handling the building of a block type.
* @param {string} options.buildScope The scope for which the item is going to be used.
* @return {Function} Function returns an item to be shown in a specific context (Inserter|Transforms list).
*/
const buildBlockTypeItem = (state, {
buildScope = 'inserter'
}) => blockType => {
const id = blockType.name;
let isDisabled = false;
if (!(0,external_wp_blocks_namespaceObject.hasBlockSupport)(blockType.name, 'multiple', true)) {
isDisabled = getBlocksByClientId(state, getClientIdsWithDescendants(state)).some(({
name
}) => name === blockType.name);
}
const {
time,
count = 0
} = getInsertUsage(state, id) || {};
const blockItemBase = {
id,
name: blockType.name,
title: blockType.title,
icon: blockType.icon,
isDisabled,
frecency: calculateFrecency(time, count)
};
if (buildScope === 'transform') return blockItemBase;
const inserterVariations = (0,external_wp_blocks_namespaceObject.getBlockVariations)(blockType.name, 'inserter');
return {
...blockItemBase,
initialAttributes: {},
description: blockType.description,
category: blockType.category,
keywords: blockType.keywords,
variations: inserterVariations,
example: blockType.example,
utility: 1 // Deprecated.
};
};
/**
* Determines the items that appear in the inserter. Includes both static
* items (e.g. a regular block type) and dynamic items (e.g. a reusable block).
*
* Each item object contains what's necessary to display a button in the
* inserter and handle its selection.
*
* The 'frecency' property is a heuristic (https://en.wikipedia.org/wiki/Frecency)
* that combines block usage frequenty and recency.
*
* Items are returned ordered descendingly by their 'utility' and 'frecency'.
*
* @param {Object} state Editor state.
* @param {?string} rootClientId Optional root client ID of block list.
*
* @return {WPEditorInserterItem[]} Items that appear in inserter.
*
* @typedef {Object} WPEditorInserterItem
* @property {string} id Unique identifier for the item.
* @property {string} name The type of block to create.
* @property {Object} initialAttributes Attributes to pass to the newly created block.
* @property {string} title Title of the item, as it appears in the inserter.
* @property {string} icon Dashicon for the item, as it appears in the inserter.
* @property {string} category Block category that the item is associated with.
* @property {string[]} keywords Keywords that can be searched to find this item.
* @property {boolean} isDisabled Whether or not the user should be prevented from inserting
* this item.
* @property {number} frecency Heuristic that combines frequency and recency.
*/
const getInserterItems = rememo((state, rootClientId = null) => {
const buildReusableBlockInserterItem = reusableBlock => {
const icon = !reusableBlock.wp_pattern_sync_status ? {
src: library_symbol,
foreground: 'var(--wp-block-synced-color)'
} : library_symbol;
const id = `core/block/${reusableBlock.id}`;
const {
time,
count = 0
} = getInsertUsage(state, id) || {};
const frecency = calculateFrecency(time, count);
return {
id,
name: 'core/block',
initialAttributes: {
ref: reusableBlock.id
},
title: reusableBlock.title?.raw,
icon,
category: 'reusable',
keywords: ['reusable'],
isDisabled: false,
utility: 1,
// Deprecated.
frecency,
content: reusableBlock.content.raw,
syncStatus: reusableBlock.wp_pattern_sync_status
};
};
const syncedPatternInserterItems = canInsertBlockTypeUnmemoized(state, 'core/block', rootClientId) ? getReusableBlocks(state).map(buildReusableBlockInserterItem) : [];
const buildBlockTypeInserterItem = buildBlockTypeItem(state, {
buildScope: 'inserter'
});
const blockTypeInserterItems = (0,external_wp_blocks_namespaceObject.getBlockTypes)().filter(blockType => canIncludeBlockTypeInInserter(state, blockType, rootClientId)).map(buildBlockTypeInserterItem);
const items = blockTypeInserterItems.reduce((accumulator, item) => {
const {
variations = []
} = item;
// Exclude any block type item that is to be replaced by a default variation.
if (!variations.some(({
isDefault
}) => isDefault)) {
accumulator.push(item);
}
if (variations.length) {
const variationMapper = getItemFromVariation(state, item);
accumulator.push(...variations.map(variationMapper));
}
return accumulator;
}, []);
// Ensure core blocks are prioritized in the returned results,
// because third party blocks can be registered earlier than
// the core blocks (usually by using the `init` action),
// thus affecting the display order.
// We don't sort reusable blocks as they are handled differently.
const groupByType = (blocks, block) => {
const {
core,
noncore
} = blocks;
const type = block.name.startsWith('core/') ? core : noncore;
type.push(block);
return blocks;
};
const {
core: coreItems,
noncore: nonCoreItems
} = items.reduce(groupByType, {
core: [],
noncore: []
});
const sortedBlockTypes = [...coreItems, ...nonCoreItems];
return [...sortedBlockTypes, ...syncedPatternInserterItems];
}, (state, rootClientId) => [state.blockListSettings[rootClientId], state.blocks.byClientId, state.blocks.order, state.preferences.insertUsage, state.settings.allowedBlockTypes, state.settings.templateLock, getReusableBlocks(state), (0,external_wp_blocks_namespaceObject.getBlockTypes)()]);
/**
* Determines the items that appear in the available block transforms list.
*
* Each item object contains what's necessary to display a menu item in the
* transform list and handle its selection.
*
* The 'frecency' property is a heuristic (https://en.wikipedia.org/wiki/Frecency)
* that combines block usage frequenty and recency.
*
* Items are returned ordered descendingly by their 'frecency'.
*
* @param {Object} state Editor state.
* @param {Object|Object[]} blocks Block object or array objects.
* @param {?string} rootClientId Optional root client ID of block list.
*
* @return {WPEditorTransformItem[]} Items that appear in inserter.
*
* @typedef {Object} WPEditorTransformItem
* @property {string} id Unique identifier for the item.
* @property {string} name The type of block to create.
* @property {string} title Title of the item, as it appears in the inserter.
* @property {string} icon Dashicon for the item, as it appears in the inserter.
* @property {boolean} isDisabled Whether or not the user should be prevented from inserting
* this item.
* @property {number} frecency Heuristic that combines frequency and recency.
*/
const getBlockTransformItems = rememo((state, blocks, rootClientId = null) => {
const normalizedBlocks = Array.isArray(blocks) ? blocks : [blocks];
const buildBlockTypeTransformItem = buildBlockTypeItem(state, {
buildScope: 'transform'
});
const blockTypeTransformItems = (0,external_wp_blocks_namespaceObject.getBlockTypes)().filter(blockType => canIncludeBlockTypeInInserter(state, blockType, rootClientId)).map(buildBlockTypeTransformItem);
const itemsByName = Object.fromEntries(Object.entries(blockTypeTransformItems).map(([, value]) => [value.name, value]));
const possibleTransforms = (0,external_wp_blocks_namespaceObject.getPossibleBlockTransformations)(normalizedBlocks).reduce((accumulator, block) => {
if (itemsByName[block?.name]) {
accumulator.push(itemsByName[block.name]);
}
return accumulator;
}, []);
return orderBy(possibleTransforms, block => itemsByName[block.name].frecency, 'desc');
}, (state, blocks, rootClientId) => [state.blockListSettings[rootClientId], state.blocks.byClientId, state.preferences.insertUsage, state.settings.allowedBlockTypes, state.settings.templateLock, (0,external_wp_blocks_namespaceObject.getBlockTypes)()]);
/**
* Determines whether there are items to show in the inserter.
*
* @param {Object} state Editor state.
* @param {?string} rootClientId Optional root client ID of block list.
*
* @return {boolean} Items that appear in inserter.
*/
const hasInserterItems = rememo((state, rootClientId = null) => {
const hasBlockType = (0,external_wp_blocks_namespaceObject.getBlockTypes)().some(blockType => canIncludeBlockTypeInInserter(state, blockType, rootClientId));
if (hasBlockType) {
return true;
}
const hasReusableBlock = canInsertBlockTypeUnmemoized(state, 'core/block', rootClientId) && getReusableBlocks(state).length > 0;
return hasReusableBlock;
}, (state, rootClientId) => [state.blockListSettings[rootClientId], state.blocks.byClientId, state.settings.allowedBlockTypes, state.settings.templateLock, getReusableBlocks(state), (0,external_wp_blocks_namespaceObject.getBlockTypes)()]);
/**
* Returns the list of allowed inserter blocks for inner blocks children.
*
* @param {Object} state Editor state.
* @param {?string} rootClientId Optional root client ID of block list.
*
* @return {Array?} The list of allowed block types.
*/
const getAllowedBlocks = rememo((state, rootClientId = null) => {
if (!rootClientId) {
return;
}
const blockTypes = (0,external_wp_blocks_namespaceObject.getBlockTypes)().filter(blockType => canIncludeBlockTypeInInserter(state, blockType, rootClientId));
const hasReusableBlock = canInsertBlockTypeUnmemoized(state, 'core/block', rootClientId) && getReusableBlocks(state).length > 0;
return [...blockTypes, ...(hasReusableBlock ? ['core/block'] : [])];
}, (state, rootClientId) => [state.blockListSettings[rootClientId], state.blocks.byClientId, state.settings.allowedBlockTypes, state.settings.templateLock, getReusableBlocks(state), (0,external_wp_blocks_namespaceObject.getBlockTypes)()]);
const __experimentalGetAllowedBlocks = rememo((state, rootClientId = null) => {
external_wp_deprecated_default()('wp.data.select( "core/block-editor" ).__experimentalGetAllowedBlocks', {
alternative: 'wp.data.select( "core/block-editor" ).getAllowedBlocks',
since: '6.2',
version: '6.4'
});
return getAllowedBlocks(state, rootClientId);
}, (state, rootClientId) => [...getAllowedBlocks.getDependants(state, rootClientId)]);
/**
* Returns the block to be directly inserted by the block appender.
*
* @param {Object} state Editor state.
* @param {?string} rootClientId Optional root client ID of block list.
*
* @return {?WPDirectInsertBlock} The block type to be directly inserted.
*
* @typedef {Object} WPDirectInsertBlock
* @property {string} name The type of block.
* @property {?Object} attributes Attributes to pass to the newly created block.
* @property {?Array} attributesToCopy Attributes to be copied from adjecent blocks when inserted.
*/
const getDirectInsertBlock = rememo((state, rootClientId = null) => {
if (!rootClientId) {
return;
}
const defaultBlock = state.blockListSettings[rootClientId]?.defaultBlock;
const directInsert = state.blockListSettings[rootClientId]?.directInsert;
if (!defaultBlock || !directInsert) {
return;
}
if (typeof directInsert === 'function') {
return directInsert(getBlock(state, rootClientId)) ? defaultBlock : null;
}
return defaultBlock;
}, (state, rootClientId) => [state.blockListSettings[rootClientId], state.blocks.tree.get(rootClientId)]);
const __experimentalGetDirectInsertBlock = rememo((state, rootClientId = null) => {
external_wp_deprecated_default()('wp.data.select( "core/block-editor" ).__experimentalGetDirectInsertBlock', {
alternative: 'wp.data.select( "core/block-editor" ).getDirectInsertBlock',
since: '6.3',
version: '6.4'
});
return getDirectInsertBlock(state, rootClientId);
}, (state, rootClientId) => [state.blockListSettings[rootClientId], state.blocks.tree.get(rootClientId)]);
const checkAllowListRecursive = (blocks, allowedBlockTypes) => {
if (typeof allowedBlockTypes === 'boolean') {
return allowedBlockTypes;
}
const blocksQueue = [...blocks];
while (blocksQueue.length > 0) {
const block = blocksQueue.shift();
const isAllowed = checkAllowList(allowedBlockTypes, block.name || block.blockName, true);
if (!isAllowed) {
return false;
}
block.innerBlocks?.forEach(innerBlock => {
blocksQueue.push(innerBlock);
});
}
return true;
};
function getUserPatterns(state) {
var _state$settings$__exp, _state$settings$__exp2;
const userPatterns = (_state$settings$__exp = state?.settings?.__experimentalReusableBlocks) !== null && _state$settings$__exp !== void 0 ? _state$settings$__exp : EMPTY_ARRAY;
const userPatternCategories = (_state$settings$__exp2 = state?.settings?.__experimentalUserPatternCategories) !== null && _state$settings$__exp2 !== void 0 ? _state$settings$__exp2 : [];
const categories = new Map();
userPatternCategories.forEach(userCategory => categories.set(userCategory.id, userCategory));
return userPatterns.map(userPattern => {
return {
name: `core/block/${userPattern.id}`,
id: userPattern.id,
type: 'user',
title: userPattern.title.raw,
categories: userPattern.wp_pattern_category.map(catId => categories && categories.get(catId) ? categories.get(catId).slug : catId),
content: userPattern.content.raw,
syncStatus: userPattern.wp_pattern_sync_status
};
});
}
const __experimentalUserPatternCategories = rememo(state => {
return state?.settings?.__experimentalUserPatternCategories;
}, state => [state.settings.__experimentalUserPatternCategories]);
const __experimentalGetParsedPattern = rememo((state, patternName) => {
const patterns = state.settings.__experimentalBlockPatterns;
const userPatterns = getUserPatterns(state);
const pattern = [...patterns, ...userPatterns].find(({
name
}) => name === patternName);
if (!pattern) {
return null;
}
return {
...pattern,
blocks: (0,external_wp_blocks_namespaceObject.parse)(pattern.content, {
__unstableSkipMigrationLogs: true
})
};
}, state => [state.settings.__experimentalBlockPatterns, state.settings.__experimentalReusableBlocks, state?.settings?.__experimentalUserPatternCategories]);
const getAllAllowedPatterns = rememo(state => {
const patterns = state.settings.__experimentalBlockPatterns;
const userPatterns = getUserPatterns(state);
const {
allowedBlockTypes
} = getSettings(state);
const parsedPatterns = [...userPatterns, ...patterns].filter(({
inserter = true
}) => !!inserter).map(({
name
}) => __experimentalGetParsedPattern(state, name));
const allowedPatterns = parsedPatterns.filter(({
blocks
}) => checkAllowListRecursive(blocks, allowedBlockTypes));
return allowedPatterns;
}, state => [state.settings.__experimentalBlockPatterns, state.settings.__experimentalReusableBlocks, state.settings.allowedBlockTypes, state?.settings?.__experimentalUserPatternCategories]);
/**
* Returns the list of allowed patterns for inner blocks children.
*
* @param {Object} state Editor state.
* @param {?string} rootClientId Optional target root client ID.
*
* @return {Array?} The list of allowed patterns.
*/
const __experimentalGetAllowedPatterns = rememo((state, rootClientId = null) => {
const availableParsedPatterns = getAllAllowedPatterns(state);
const patternsAllowed = availableParsedPatterns.filter(({
blocks
}) => blocks.every(({
name
}) => canInsertBlockType(state, name, rootClientId)));
return patternsAllowed;
}, (state, rootClientId) => [state.settings.__experimentalBlockPatterns, state.settings.__experimentalReusableBlocks, state.settings.allowedBlockTypes, state.settings.templateLock, state.blockListSettings[rootClientId], state.blocks.byClientId.get(rootClientId)]);
/**
* Returns the list of patterns based on their declared `blockTypes`
* and a block's name.
* Patterns can use `blockTypes` to integrate in work flows like
* suggesting appropriate patterns in a Placeholder state(during insertion)
* or blocks transformations.
*
* @param {Object} state Editor state.
* @param {string|string[]} blockNames Block's name or array of block names to find matching pattens.
* @param {?string} rootClientId Optional target root client ID.
*
* @return {Array} The list of matched block patterns based on declared `blockTypes` and block name.
*/
const getPatternsByBlockTypes = rememo((state, blockNames, rootClientId = null) => {
if (!blockNames) return EMPTY_ARRAY;
const patterns = __experimentalGetAllowedPatterns(state, rootClientId);
const normalizedBlockNames = Array.isArray(blockNames) ? blockNames : [blockNames];
const filteredPatterns = patterns.filter(pattern => pattern?.blockTypes?.some?.(blockName => normalizedBlockNames.includes(blockName)));
if (filteredPatterns.length === 0) {
return EMPTY_ARRAY;
}
return filteredPatterns;
}, (state, blockNames, rootClientId) => [...__experimentalGetAllowedPatterns.getDependants(state, rootClientId)]);
const __experimentalGetPatternsByBlockTypes = rememo((state, blockNames, rootClientId = null) => {
external_wp_deprecated_default()('wp.data.select( "core/block-editor" ).__experimentalGetPatternsByBlockTypes', {
alternative: 'wp.data.select( "core/block-editor" ).getPatternsByBlockTypes',
since: '6.2',
version: '6.4'
});
return getPatternsByBlockTypes(state, blockNames, rootClientId);
}, (state, blockNames, rootClientId) => [...__experimentalGetAllowedPatterns.getDependants(state, rootClientId)]);
/**
* Determines the items that appear in the available pattern transforms list.
*
* For now we only handle blocks without InnerBlocks and take into account
* the `__experimentalRole` property of blocks' attributes for the transformation.
*
* We return the first set of possible eligible block patterns,
* by checking the `blockTypes` property. We still have to recurse through
* block pattern's blocks and try to find matches from the selected blocks.
* Now this happens in the consumer to avoid heavy operations in the selector.
*
* @param {Object} state Editor state.
* @param {Object[]} blocks The selected blocks.
* @param {?string} rootClientId Optional root client ID of block list.
*
* @return {WPBlockPattern[]} Items that are eligible for a pattern transformation.
*/
const __experimentalGetPatternTransformItems = rememo((state, blocks, rootClientId = null) => {
if (!blocks) return EMPTY_ARRAY;
/**
* For now we only handle blocks without InnerBlocks and take into account
* the `__experimentalRole` property of blocks' attributes for the transformation.
* Note that the blocks have been retrieved through `getBlock`, which doesn't
* return the inner blocks of an inner block controller, so we still need
* to check for this case too.
*/
if (blocks.some(({
clientId,
innerBlocks
}) => innerBlocks.length || areInnerBlocksControlled(state, clientId))) {
return EMPTY_ARRAY;
}
// Create a Set of the selected block names that is used in patterns filtering.
const selectedBlockNames = Array.from(new Set(blocks.map(({
name
}) => name)));
/**
* Here we will return first set of possible eligible block patterns,
* by checking the `blockTypes` property. We still have to recurse through
* block pattern's blocks and try to find matches from the selected blocks.
* Now this happens in the consumer to avoid heavy operations in the selector.
*/
return getPatternsByBlockTypes(state, selectedBlockNames, rootClientId);
}, (state, blocks, rootClientId) => [...getPatternsByBlockTypes.getDependants(state, rootClientId)]);
/**
* Returns the Block List settings of a block, if any exist.
*
* @param {Object} state Editor state.
* @param {?string} clientId Block client ID.
*
* @return {?Object} Block settings of the block if set.
*/
function getBlockListSettings(state, clientId) {
return state.blockListSettings[clientId];
}
/**
* Returns the editor settings.
*
* @param {Object} state Editor state.
*
* @return {Object} The editor settings object.
*/
function getSettings(state) {
return state.settings;
}
/**
* Returns true if the most recent block change is be considered persistent, or
* false otherwise. A persistent change is one committed by BlockEditorProvider
* via its `onChange` callback, in addition to `onInput`.
*
* @param {Object} state Block editor state.
*
* @return {boolean} Whether the most recent block change was persistent.
*/
function isLastBlockChangePersistent(state) {
return state.blocks.isPersistentChange;
}
/**
* Returns the block list settings for an array of blocks, if any exist.
*
* @param {Object} state Editor state.
* @param {Array} clientIds Block client IDs.
*
* @return {Object} An object where the keys are client ids and the values are
* a block list setting object.
*/
const __experimentalGetBlockListSettingsForBlocks = rememo((state, clientIds = []) => {
return clientIds.reduce((blockListSettingsForBlocks, clientId) => {
if (!state.blockListSettings[clientId]) {
return blockListSettingsForBlocks;
}
return {
...blockListSettingsForBlocks,
[clientId]: state.blockListSettings[clientId]
};
}, {});
}, state => [state.blockListSettings]);
/**
* Returns the title of a given reusable block
*
* @param {Object} state Global application state.
* @param {number|string} ref The shared block's ID.
*
* @return {string} The reusable block saved title.
*/
const __experimentalGetReusableBlockTitle = rememo((state, ref) => {
const reusableBlock = getReusableBlocks(state).find(block => block.id === ref);
if (!reusableBlock) {
return null;
}
return reusableBlock.title?.raw;
}, state => [getReusableBlocks(state)]);
/**
* Returns true if the most recent block change is be considered ignored, or
* false otherwise. An ignored change is one not to be committed by
* BlockEditorProvider, neither via `onChange` nor `onInput`.
*
* @param {Object} state Block editor state.
*
* @return {boolean} Whether the most recent block change was ignored.
*/
function __unstableIsLastBlockChangeIgnored(state) {
// TODO: Removal Plan: Changes incurred by RECEIVE_BLOCKS should not be
// ignored if in-fact they result in a change in blocks state. The current
// need to ignore changes not a result of user interaction should be
// accounted for in the refactoring of reusable blocks as occurring within
// their own separate block editor / state (#7119).
return state.blocks.isIgnoredChange;
}
/**
* Returns the block attributes changed as a result of the last dispatched
* action.
*
* @param {Object} state Block editor state.
*
* @return {Object} Subsets of block attributes changed, keyed
* by block client ID.
*/
function __experimentalGetLastBlockAttributeChanges(state) {
return state.lastBlockAttributesChange;
}
/**
* Returns the available reusable blocks
*
* @param {Object} state Global application state.
*
* @return {Array} Reusable blocks
*/
function getReusableBlocks(state) {
var _state$settings$__exp3;
return (_state$settings$__exp3 = state?.settings?.__experimentalReusableBlocks) !== null && _state$settings$__exp3 !== void 0 ? _state$settings$__exp3 : EMPTY_ARRAY;
}
/**
* Returns whether the navigation mode is enabled.
*
* @param {Object} state Editor state.
*
* @return {boolean} Is navigation mode enabled.
*/
function isNavigationMode(state) {
return state.editorMode === 'navigation';
}
/**
* Returns the current editor mode.
*
* @param {Object} state Editor state.
*
* @return {string} the editor mode.
*/
function __unstableGetEditorMode(state) {
return state.editorMode;
}
/**
* Returns whether block moving mode is enabled.
*
* @param {Object} state Editor state.
*
* @return {string} Client Id of moving block.
*/
function selectors_hasBlockMovingClientId(state) {
return state.hasBlockMovingClientId;
}
/**
* Returns true if the last change was an automatic change, false otherwise.
*
* @param {Object} state Global application state.
*
* @return {boolean} Whether the last change was automatic.
*/
function didAutomaticChange(state) {
return !!state.automaticChangeStatus;
}
/**
* Returns true if the current highlighted block matches the block clientId.
*
* @param {Object} state Global application state.
* @param {string} clientId The block to check.
*
* @return {boolean} Whether the block is currently highlighted.
*/
function isBlockHighlighted(state, clientId) {
return state.highlightedBlock === clientId;
}
/**
* Checks if a given block has controlled inner blocks.
*
* @param {Object} state Global application state.
* @param {string} clientId The block to check.
*
* @return {boolean} True if the block has controlled inner blocks.
*/
function areInnerBlocksControlled(state, clientId) {
return !!state.blocks.controlledInnerBlocks[clientId];
}
/**
* Returns the clientId for the first 'active' block of a given array of block names.
* A block is 'active' if it (or a child) is the selected block.
* Returns the first match moving up the DOM from the selected block.
*
* @param {Object} state Global application state.
* @param {string[]} validBlocksNames The names of block types to check for.
*
* @return {string} The matching block's clientId.
*/
const __experimentalGetActiveBlockIdByBlockNames = rememo((state, validBlockNames) => {
if (!validBlockNames.length) {
return null;
}
// Check if selected block is a valid entity area.
const selectedBlockClientId = getSelectedBlockClientId(state);
if (validBlockNames.includes(getBlockName(state, selectedBlockClientId))) {
return selectedBlockClientId;
}
// Check if first selected block is a child of a valid entity area.
const multiSelectedBlockClientIds = getMultiSelectedBlockClientIds(state);
const entityAreaParents = getBlockParentsByBlockName(state, selectedBlockClientId || multiSelectedBlockClientIds[0], validBlockNames);
if (entityAreaParents) {
// Last parent closest/most interior.
return entityAreaParents[entityAreaParents.length - 1];
}
return null;
}, (state, validBlockNames) => [state.selection.selectionStart.clientId, state.selection.selectionEnd.clientId, validBlockNames]);
/**
* Tells if the block with the passed clientId was just inserted.
*
* @param {Object} state Global application state.
* @param {Object} clientId Client Id of the block.
* @param {?string} source Optional insertion source of the block.
* @return {boolean} True if the block matches the last block inserted from the specified source.
*/
function wasBlockJustInserted(state, clientId, source) {
const {
lastBlockInserted
} = state;
return lastBlockInserted.clientIds?.includes(clientId) && lastBlockInserted.source === source;
}
/**
* Tells if the block is visible on the canvas or not.
*
* @param {Object} state Global application state.
* @param {Object} clientId Client Id of the block.
* @return {boolean} True if the block is visible.
*/
function isBlockVisible(state, clientId) {
var _state$blockVisibilit;
return (_state$blockVisibilit = state.blockVisibility?.[clientId]) !== null && _state$blockVisibilit !== void 0 ? _state$blockVisibilit : true;
}
/**
* Returns the list of all hidden blocks.
*
* @param {Object} state Global application state.
* @return {[string]} List of hidden blocks.
*/
const __unstableGetVisibleBlocks = rememo(state => {
const visibleBlocks = new Set(Object.keys(state.blockVisibility).filter(key => state.blockVisibility[key]));
if (visibleBlocks.size === 0) {
return EMPTY_SET;
}
return visibleBlocks;
}, state => [state.blockVisibility]);
/**
* DO-NOT-USE in production.
* This selector is created for internal/experimental only usage and may be
* removed anytime without any warning, causing breakage on any plugin or theme invoking it.
*/
const __unstableGetContentLockingParent = rememo((state, clientId) => {
let current = clientId;
let result;
while (state.blocks.parents.has(current)) {
current = state.blocks.parents.get(current);
if (current && getTemplateLock(state, current) === 'contentOnly') {
result = current;
}
}
return result;
}, state => [state.blocks.parents, state.blockListSettings]);
/**
* DO-NOT-USE in production.
* This selector is created for internal/experimental only usage and may be
* removed anytime without any warning, causing breakage on any plugin or theme invoking it.
*
* @param {Object} state Global application state.
*/
function __unstableGetTemporarilyEditingAsBlocks(state) {
return state.temporarilyEditingAsBlocks;
}
function __unstableHasActiveBlockOverlayActive(state, clientId) {
// Prevent overlay on blocks with a non-default editing mode. If the mdoe is
// 'disabled' then the overlay is redundant since the block can't be
// selected. If the mode is 'contentOnly' then the overlay is redundant
// since there will be no controls to interact with once selected.
if (getBlockEditingMode(state, clientId) !== 'default') {
return false;
}
// If the block editing is locked, the block overlay is always active.
if (!canEditBlock(state, clientId)) {
return true;
}
const editorMode = __unstableGetEditorMode(state);
// In zoom-out mode, the block overlay is always active for top level blocks.
if (editorMode === 'zoom-out' && clientId && !getBlockRootClientId(state, clientId)) {
return true;
}
// In navigation mode, the block overlay is active when the block is not
// selected (and doesn't contain a selected child). The same behavior is
// also enabled in all modes for blocks that have controlled children
// (reusable block, template part, navigation), unless explicitly disabled
// with `supports.__experimentalDisableBlockOverlay`.
const blockSupportDisable = (0,external_wp_blocks_namespaceObject.hasBlockSupport)(getBlockName(state, clientId), '__experimentalDisableBlockOverlay', false);
const shouldEnableIfUnselected = editorMode === 'navigation' || (blockSupportDisable ? false : areInnerBlocksControlled(state, clientId));
return shouldEnableIfUnselected && !isBlockSelected(state, clientId) && !hasSelectedInnerBlock(state, clientId, true);
}
function __unstableIsWithinBlockOverlay(state, clientId) {
let parent = state.blocks.parents.get(clientId);
while (!!parent) {
if (__unstableHasActiveBlockOverlayActive(state, parent)) {
return true;
}
parent = state.blocks.parents.get(parent);
}
return false;
}
/**
* @typedef {import('../components/block-editing-mode').BlockEditingMode} BlockEditingMode
*/
/**
* Returns the block editing mode for a given block.
*
* The mode can be one of three options:
*
* - `'disabled'`: Prevents editing the block entirely, i.e. it cannot be
* selected.
* - `'contentOnly'`: Hides all non-content UI, e.g. auxiliary controls in the
* toolbar, the block movers, block settings.
* - `'default'`: Allows editing the block as normal.
*
* Blocks can set a mode using the `useBlockEditingMode` hook.
*
* The mode is inherited by all of the block's inner blocks, unless they have
* their own mode.
*
* A template lock can also set a mode. If the template lock is `'contentOnly'`,
* the block's mode is overridden to `'contentOnly'` if the block has a content
* role attribute, or `'disabled'` otherwise.
*
* @see useBlockEditingMode
*
* @param {Object} state Global application state.
* @param {string} clientId The block client ID, or `''` for the root container.
*
* @return {BlockEditingMode} The block editing mode. One of `'disabled'`,
* `'contentOnly'`, or `'default'`.
*/
const getBlockEditingMode = (0,external_wp_data_namespaceObject.createRegistrySelector)(select => (state, clientId = '') => {
if (state.blockEditingModes.has(clientId)) {
return state.blockEditingModes.get(clientId);
}
if (!clientId) {
return 'default';
}
const rootClientId = getBlockRootClientId(state, clientId);
const templateLock = getTemplateLock(state, rootClientId);
if (templateLock === 'contentOnly') {
const name = getBlockName(state, clientId);
const isContent = select(external_wp_blocks_namespaceObject.store).__experimentalHasContentRoleAttribute(name);
return isContent ? 'contentOnly' : 'disabled';
}
const parentMode = getBlockEditingMode(state, rootClientId);
return parentMode === 'contentOnly' ? 'default' : parentMode;
});
/**
* Indicates if a block is ungroupable.
* A block is ungroupable if it is a single grouping block with inner blocks.
* If a block has an `ungroup` transform, it is also ungroupable, without the
* requirement of being the default grouping block.
* Additionally a block can only be ungrouped if it has inner blocks and can
* be removed.
*
* @param {Object} state Global application state.
* @param {string} clientId Client Id of the block. If not passed the selected block's client id will be used.
* @return {boolean} True if the block is ungroupable.
*/
const isUngroupable = (0,external_wp_data_namespaceObject.createRegistrySelector)(select => (state, clientId = '') => {
const _clientId = clientId || getSelectedBlockClientId(state);
if (!_clientId) {
return false;
}
const {
getGroupingBlockName
} = select(external_wp_blocks_namespaceObject.store);
const block = getBlock(state, _clientId);
const groupingBlockName = getGroupingBlockName();
const _isUngroupable = block && (block.name === groupingBlockName || (0,external_wp_blocks_namespaceObject.getBlockType)(block.name)?.transforms?.ungroup) && !!block.innerBlocks.length;
return _isUngroupable && canRemoveBlock(state, _clientId);
});
/**
* Indicates if the provided blocks(by client ids) are groupable.
* We need to have at least one block, have a grouping block name set and
* be able to remove these blocks.
*
* @param {Object} state Global application state.
* @param {string[]} clientIds Block client ids. If not passed the selected blocks client ids will be used.
* @return {boolean} True if the blocks are groupable.
*/
const isGroupable = (0,external_wp_data_namespaceObject.createRegistrySelector)(select => (state, clientIds = EMPTY_ARRAY) => {
const {
getGroupingBlockName
} = select(external_wp_blocks_namespaceObject.store);
const groupingBlockName = getGroupingBlockName();
const _clientIds = clientIds?.length ? clientIds : getSelectedBlockClientIds(state);
const rootClientId = _clientIds?.length ? getBlockRootClientId(state, _clientIds[0]) : undefined;
const groupingBlockAvailable = canInsertBlockType(state, groupingBlockName, rootClientId);
const _isGroupable = groupingBlockAvailable && _clientIds.length;
return _isGroupable && canRemoveBlocks(state, _clientIds, rootClientId);
});
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/store/private-actions.js
/**
* WordPress dependencies
*/
const castArray = maybeArray => Array.isArray(maybeArray) ? maybeArray : [maybeArray];
/**
* A list of private/experimental block editor settings that
* should not become a part of the WordPress public API.
* BlockEditorProvider will remove these settings from the
* settings object it receives.
*
* @see https://github.com/WordPress/gutenberg/pull/46131
*/
const privateSettings = ['inserterMediaCategories', 'blockInspectorAnimation'];
/**
* Action that updates the block editor settings and
* conditionally preserves the experimental ones.
*
* @param {Object} settings Updated settings
* @param {Object} options Options object.
* @param {boolean} options.stripExperimentalSettings Whether to strip experimental settings.
* @param {boolean} options.reset Whether to reset the settings.
* @return {Object} Action object
*/
function __experimentalUpdateSettings(settings, {
stripExperimentalSettings = false,
reset = false
} = {}) {
let cleanSettings = settings;
// There are no plugins in the mobile apps, so there is no
// need to strip the experimental settings:
if (stripExperimentalSettings && external_wp_element_namespaceObject.Platform.OS === 'web') {
cleanSettings = {};
for (const key in settings) {
if (!privateSettings.includes(key)) {
cleanSettings[key] = settings[key];
}
}
}
return {
type: 'UPDATE_SETTINGS',
settings: cleanSettings,
reset
};
}
/**
* Hides the block interface (eg. toolbar, outline, etc.)
*
* @return {Object} Action object.
*/
function hideBlockInterface() {
return {
type: 'HIDE_BLOCK_INTERFACE'
};
}
/**
* Shows the block interface (eg. toolbar, outline, etc.)
*
* @return {Object} Action object.
*/
function showBlockInterface() {
return {
type: 'SHOW_BLOCK_INTERFACE'
};
}
/**
* Yields action objects used in signalling that the blocks corresponding to
* the set of specified client IDs are to be removed.
*
* Compared to `removeBlocks`, this private interface exposes an additional
* parameter; see `forceRemove`.
*
* @param {string|string[]} clientIds Client IDs of blocks to remove.
* @param {boolean} selectPrevious True if the previous block
* or the immediate parent
* (if no previous block exists)
* should be selected
* when a block is removed.
* @param {boolean} forceRemove Whether to force the operation,
* bypassing any checks for certain
* block types.
*/
const privateRemoveBlocks = (clientIds, selectPrevious = true, forceRemove = false) => ({
select,
dispatch,
registry
}) => {
if (!clientIds || !clientIds.length) {
return;
}
clientIds = castArray(clientIds);
const rootClientId = select.getBlockRootClientId(clientIds[0]);
const canRemoveBlocks = select.canRemoveBlocks(clientIds, rootClientId);
if (!canRemoveBlocks) {
return;
}
// In certain editing contexts, we'd like to prevent accidental removal
// of important blocks. For example, in the site editor, the Query Loop
// block is deemed important. In such cases, we'll ask the user for
// confirmation that they intended to remove such block(s). However,
// the editor instance is responsible for presenting those confirmation
// prompts to the user. Any instance opting into removal prompts must
// register using `setBlockRemovalRules()`.
//
// @see https://github.com/WordPress/gutenberg/pull/51145
const rules = !forceRemove && select.getBlockRemovalRules();
if (rules) {
const blockNamesForPrompt = new Set();
// Given a list of client IDs of blocks that the user intended to
// remove, perform a tree search (BFS) to find all block names
// corresponding to "important" blocks, i.e. blocks that require a
// removal prompt.
const queue = [...clientIds];
while (queue.length) {
const clientId = queue.shift();
const blockName = select.getBlockName(clientId);
if (rules[blockName]) {
blockNamesForPrompt.add(blockName);
}
const innerBlocks = select.getBlockOrder(clientId);
queue.push(...innerBlocks);
}
// If any such blocks were found, trigger the removal prompt and
// skip any other steps (thus postponing actual removal).
if (blockNamesForPrompt.size) {
dispatch(displayBlockRemovalPrompt(clientIds, selectPrevious, Array.from(blockNamesForPrompt)));
return;
}
}
if (selectPrevious) {
dispatch.selectPreviousBlock(clientIds[0], selectPrevious);
}
// We're batching these two actions because an extra `undo/redo` step can
// be created, based on whether we insert a default block or not.
registry.batch(() => {
dispatch({
type: 'REMOVE_BLOCKS',
clientIds
});
// To avoid a focus loss when removing the last block, assure there is
// always a default block if the last of the blocks have been removed.
dispatch(ensureDefaultBlock());
});
};
/**
* Action which will insert a default block insert action if there
* are no other blocks at the root of the editor. This action should be used
* in actions which may result in no blocks remaining in the editor (removal,
* replacement, etc).
*/
const ensureDefaultBlock = () => ({
select,
dispatch
}) => {
// To avoid a focus loss when removing the last block, assure there is
// always a default block if the last of the blocks have been removed.
const count = select.getBlockCount();
if (count > 0) {
return;
}
// If there's an custom appender, don't insert default block.
// We have to remember to manually move the focus elsewhere to
// prevent it from being lost though.
const {
__unstableHasCustomAppender
} = select.getSettings();
if (__unstableHasCustomAppender) {
return;
}
dispatch.insertDefaultBlock();
};
/**
* Returns an action object used in signalling that a block removal prompt must
* be displayed.
*
* Contrast with `setBlockRemovalRules`.
*
* @param {string|string[]} clientIds Client IDs of blocks to remove.
* @param {boolean} selectPrevious True if the previous block
* or the immediate parent
* (if no previous block exists)
* should be selected
* when a block is removed.
* @param {string[]} blockNamesForPrompt Names of the blocks that
* triggered the need for
* confirmation before removal.
*
* @return {Object} Action object.
*/
function displayBlockRemovalPrompt(clientIds, selectPrevious, blockNamesForPrompt) {
return {
type: 'DISPLAY_BLOCK_REMOVAL_PROMPT',
clientIds,
selectPrevious,
blockNamesForPrompt
};
}
/**
* Returns an action object used in signalling that a block removal prompt must
* be cleared, either be cause the user has confirmed or canceled the request
* for removal.
*
* @return {Object} Action object.
*/
function clearBlockRemovalPrompt() {
return {
type: 'CLEAR_BLOCK_REMOVAL_PROMPT'
};
}
/**
* Returns an action object used to set up any rules that a block editor may
* provide in order to prevent a user from accidentally removing certain
* blocks. These rules are then used to display a confirmation prompt to the
* user. For instance, in the Site Editor, the Query Loop block is important
* enough to warrant such confirmation.
*
* IMPORTANT: Registering rules implicitly signals to the `privateRemoveBlocks`
* action that the editor will be responsible for displaying block removal
* prompts and confirming deletions. This action is meant to be used by
* component `BlockRemovalWarningModal` only.
*
* The data is a record whose keys are block types (e.g. 'core/query') and
* whose values are the explanation to be shown to users (e.g. 'Query Loop
* displays a list of posts or pages.').
*
* Contrast with `displayBlockRemovalPrompt`.
*
* @param {Record|false} rules Block removal rules.
* @return {Object} Action object.
*/
function setBlockRemovalRules(rules = false) {
return {
type: 'SET_BLOCK_REMOVAL_RULES',
rules
};
}
/**
* Sets the client ID of the block settings menu that is currently open.
*
* @param {?string} clientId The block client ID.
* @return {Object} Action object.
*/
function setOpenedBlockSettingsMenu(clientId) {
return {
type: 'SET_OPENED_BLOCK_SETTINGS_MENU',
clientId
};
}
function setStyleOverride(id, style) {
return {
type: 'SET_STYLE_OVERRIDE',
id,
style
};
}
function deleteStyleOverride(id) {
return {
type: 'DELETE_STYLE_OVERRIDE',
id
};
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/store/private-selectors.js
/**
* External dependencies
*/
/**
* Internal dependencies
*/
/**
* Returns true if the block interface is hidden, or false otherwise.
*
* @param {Object} state Global application state.
*
* @return {boolean} Whether the block toolbar is hidden.
*/
function private_selectors_isBlockInterfaceHidden(state) {
return state.isBlockInterfaceHidden;
}
/**
* Gets the client ids of the last inserted blocks.
*
* @param {Object} state Global application state.
* @return {Array|undefined} Client Ids of the last inserted block(s).
*/
function getLastInsertedBlocksClientIds(state) {
return state?.lastBlockInserted?.clientIds;
}
/**
* Returns true if the block with the given client ID and all of its descendants
* have an editing mode of 'disabled', or false otherwise.
*
* @param {Object} state Global application state.
* @param {string} clientId The block client ID.
*
* @return {boolean} Whether the block and its descendants are disabled.
*/
const isBlockSubtreeDisabled = rememo((state, clientId) => {
const isChildSubtreeDisabled = childClientId => {
return getBlockEditingMode(state, childClientId) === 'disabled' && getBlockOrder(state, childClientId).every(isChildSubtreeDisabled);
};
return getBlockEditingMode(state, clientId) === 'disabled' && getBlockOrder(state, clientId).every(isChildSubtreeDisabled);
}, state => [state.blocks.parents, state.blocks.order, state.blockEditingModes, state.blockListSettings]);
/**
* Returns a tree of block objects with only clientID and innerBlocks set.
* Blocks with a 'disabled' editing mode are not included.
*
* @param {Object} state Global application state.
* @param {?string} rootClientId Optional root client ID of block list.
*
* @return {Object[]} Tree of block objects with only clientID and innerBlocks set.
*/
const getEnabledClientIdsTree = rememo((state, rootClientId = '') => {
return getBlockOrder(state, rootClientId).flatMap(clientId => {
if (getBlockEditingMode(state, clientId) !== 'disabled') {
return [{
clientId,
innerBlocks: getEnabledClientIdsTree(state, clientId)
}];
}
return getEnabledClientIdsTree(state, clientId);
});
}, state => [state.blocks.order, state.blockEditingModes, state.settings.templateLock, state.blockListSettings]);
/**
* Returns a list of a given block's ancestors, from top to bottom. Blocks with
* a 'disabled' editing mode are excluded.
*
* @see getBlockParents
*
* @param {Object} state Global application state.
* @param {string} clientId The block client ID.
* @param {boolean} ascending Order results from bottom to top (true) or top
* to bottom (false).
*/
const getEnabledBlockParents = rememo((state, clientId, ascending = false) => {
return getBlockParents(state, clientId, ascending).filter(parent => getBlockEditingMode(state, parent) !== 'disabled');
}, state => [state.blocks.parents, state.blockEditingModes, state.settings.templateLock, state.blockListSettings]);
/**
* Selector that returns the data needed to display a prompt when certain
* blocks are removed, or `false` if no such prompt is requested.
*
* @param {Object} state Global application state.
*
* @return {Object|false} Data for removal prompt display, if any.
*/
function getRemovalPromptData(state) {
return state.removalPromptData;
}
/**
* Returns true if removal prompt exists, or false otherwise.
*
* @param {Object} state Global application state.
*
* @return {boolean} Whether removal prompt exists.
*/
function getBlockRemovalRules(state) {
return state.blockRemovalRules;
}
/**
* Returns the client ID of the block settings menu that is currently open.
*
* @param {Object} state Global application state.
* @return {string|null} The client ID of the block menu that is currently open.
*/
function getOpenedBlockSettingsMenu(state) {
return state.openedBlockSettingsMenu;
}
/**
* Returns all style overrides, intended to be merged with global editor styles.
*
* @param {Object} state Global application state.
*
* @return {Map} A map of style IDs to style overrides.
*/
function getStyleOverrides(state) {
return state.styleOverrides;
}
/** @typedef {import('./actions').InserterMediaCategory} InserterMediaCategory */
/**
* Returns the registered inserter media categories through the public API.
*
* @param {Object} state Editor state.
*
* @return {InserterMediaCategory[]} Inserter media categories.
*/
function getRegisteredInserterMediaCategories(state) {
return state.registeredInserterMediaCategories;
}
/**
* Returns an array containing the allowed inserter media categories.
* It merges the registered media categories from extenders with the
* core ones. It also takes into account the allowed `mime_types`, which
* can be altered by `upload_mimes` filter and restrict some of them.
*
* @param {Object} state Global application state.
*
* @return {InserterMediaCategory[]} Client IDs of descendants.
*/
const getInserterMediaCategories = rememo(state => {
const {
settings: {
inserterMediaCategories,
allowedMimeTypes,
enableOpenverseMediaCategory
},
registeredInserterMediaCategories
} = state;
// The allowed `mime_types` can be altered by `upload_mimes` filter and restrict
// some of them. In this case we shouldn't add the category to the available media
// categories list in the inserter.
if (!inserterMediaCategories && !registeredInserterMediaCategories.length || !allowedMimeTypes) {
return;
}
const coreInserterMediaCategoriesNames = inserterMediaCategories?.map(({
name
}) => name) || [];
const mergedCategories = [...(inserterMediaCategories || []), ...(registeredInserterMediaCategories || []).filter(({
name
}) => !coreInserterMediaCategoriesNames.includes(name))];
return mergedCategories.filter(category => {
// Check if Openverse category is enabled.
if (!enableOpenverseMediaCategory && category.name === 'openverse') {
return false;
}
return Object.values(allowedMimeTypes).some(mimeType => mimeType.startsWith(`${category.mediaType}/`));
});
}, state => [state.settings.inserterMediaCategories, state.settings.allowedMimeTypes, state.settings.enableOpenverseMediaCategory, state.registeredInserterMediaCategories]);
;// CONCATENATED MODULE: external ["wp","a11y"]
var external_wp_a11y_namespaceObject = window["wp"]["a11y"];
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/utils/selection.js
/**
* A robust way to retain selection position through various
* transforms is to insert a special character at the position and
* then recover it.
*/
const START_OF_SELECTED_AREA = '\u0086';
/**
* Retrieve the block attribute that contains the selection position.
*
* @param {Object} blockAttributes Block attributes.
* @return {string|void} The name of the block attribute that was previously selected.
*/
function retrieveSelectedAttribute(blockAttributes) {
if (!blockAttributes) {
return;
}
return Object.keys(blockAttributes).find(name => {
const value = blockAttributes[name];
return typeof value === 'string' && value.indexOf(START_OF_SELECTED_AREA) !== -1;
});
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/store/actions.js
/* eslint no-console: [ 'error', { allow: [ 'error', 'warn' ] } ] */
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
/** @typedef {import('../components/use-on-block-drop/types').WPDropOperation} WPDropOperation */
const actions_castArray = maybeArray => Array.isArray(maybeArray) ? maybeArray : [maybeArray];
/**
* Action that resets blocks state to the specified array of blocks, taking precedence
* over any other content reflected as an edit in state.
*
* @param {Array} blocks Array of blocks.
*/
const resetBlocks = blocks => ({
dispatch
}) => {
dispatch({
type: 'RESET_BLOCKS',
blocks
});
dispatch(validateBlocksToTemplate(blocks));
};
/**
* Block validity is a function of blocks state (at the point of a
* reset) and the template setting. As a compromise to its placement
* across distinct parts of state, it is implemented here as a side
* effect of the block reset action.
*
* @param {Array} blocks Array of blocks.
*/
const validateBlocksToTemplate = blocks => ({
select,
dispatch
}) => {
const template = select.getTemplate();
const templateLock = select.getTemplateLock();
// Unlocked templates are considered always valid because they act
// as default values only.
const isBlocksValidToTemplate = !template || templateLock !== 'all' || (0,external_wp_blocks_namespaceObject.doBlocksMatchTemplate)(blocks, template);
// Update if validity has changed.
const isValidTemplate = select.isValidTemplate();
if (isBlocksValidToTemplate !== isValidTemplate) {
dispatch.setTemplateValidity(isBlocksValidToTemplate);
return isBlocksValidToTemplate;
}
};
/**
* A block selection object.
*
* @typedef {Object} WPBlockSelection
*
* @property {string} clientId A block client ID.
* @property {string} attributeKey A block attribute key.
* @property {number} offset An attribute value offset, based on the rich
* text value. See `wp.richText.create`.
*/
/**
* A selection object.
*
* @typedef {Object} WPSelection
*
* @property {WPBlockSelection} start The selection start.
* @property {WPBlockSelection} end The selection end.
*/
/* eslint-disable jsdoc/valid-types */
/**
* Returns an action object used in signalling that selection state should be
* reset to the specified selection.
*
* @param {WPBlockSelection} selectionStart The selection start.
* @param {WPBlockSelection} selectionEnd The selection end.
* @param {0|-1|null} initialPosition Initial block position.
*
* @return {Object} Action object.
*/
function resetSelection(selectionStart, selectionEnd, initialPosition) {
/* eslint-enable jsdoc/valid-types */
return {
type: 'RESET_SELECTION',
selectionStart,
selectionEnd,
initialPosition
};
}
/**
* Returns an action object used in signalling that blocks have been received.
* Unlike resetBlocks, these should be appended to the existing known set, not
* replacing.
*
* @deprecated
*
* @param {Object[]} blocks Array of block objects.
*
* @return {Object} Action object.
*/
function receiveBlocks(blocks) {
external_wp_deprecated_default()('wp.data.dispatch( "core/block-editor" ).receiveBlocks', {
since: '5.9',
alternative: 'resetBlocks or insertBlocks'
});
return {
type: 'RECEIVE_BLOCKS',
blocks
};
}
/**
* Action that updates attributes of multiple blocks with the specified client IDs.
*
* @param {string|string[]} clientIds Block client IDs.
* @param {Object} attributes Block attributes to be merged. Should be keyed by clientIds if
* uniqueByBlock is true.
* @param {boolean} uniqueByBlock true if each block in clientIds array has a unique set of attributes
* @return {Object} Action object.
*/
function updateBlockAttributes(clientIds, attributes, uniqueByBlock = false) {
return {
type: 'UPDATE_BLOCK_ATTRIBUTES',
clientIds: actions_castArray(clientIds),
attributes,
uniqueByBlock
};
}
/**
* Action that updates the block with the specified client ID.
*
* @param {string} clientId Block client ID.
* @param {Object} updates Block attributes to be merged.
*
* @return {Object} Action object.
*/
function updateBlock(clientId, updates) {
return {
type: 'UPDATE_BLOCK',
clientId,
updates
};
}
/* eslint-disable jsdoc/valid-types */
/**
* Returns an action object used in signalling that the block with the
* specified client ID has been selected, optionally accepting a position
* value reflecting its selection directionality. An initialPosition of -1
* reflects a reverse selection.
*
* @param {string} clientId Block client ID.
* @param {0|-1|null} initialPosition Optional initial position. Pass as -1 to
* reflect reverse selection.
*
* @return {Object} Action object.
*/
function selectBlock(clientId, initialPosition = 0) {
/* eslint-enable jsdoc/valid-types */
return {
type: 'SELECT_BLOCK',
initialPosition,
clientId
};
}
/**
* Yields action objects used in signalling that the block preceding the given
* clientId (or optionally, its first parent from bottom to top)
* should be selected.
*
* @param {string} clientId Block client ID.
* @param {boolean} fallbackToParent If true, select the first parent if there is no previous block.
*/
const selectPreviousBlock = (clientId, fallbackToParent = false) => ({
select,
dispatch
}) => {
const previousBlockClientId = select.getPreviousBlockClientId(clientId);
if (previousBlockClientId) {
dispatch.selectBlock(previousBlockClientId, -1);
} else if (fallbackToParent) {
const firstParentClientId = select.getBlockRootClientId(clientId);
if (firstParentClientId) {
dispatch.selectBlock(firstParentClientId, -1);
}
}
};
/**
* Yields action objects used in signalling that the block following the given
* clientId should be selected.
*
* @param {string} clientId Block client ID.
*/
const selectNextBlock = clientId => ({
select,
dispatch
}) => {
const nextBlockClientId = select.getNextBlockClientId(clientId);
if (nextBlockClientId) {
dispatch.selectBlock(nextBlockClientId);
}
};
/**
* Action that starts block multi-selection.
*
* @return {Object} Action object.
*/
function startMultiSelect() {
return {
type: 'START_MULTI_SELECT'
};
}
/**
* Action that stops block multi-selection.
*
* @return {Object} Action object.
*/
function stopMultiSelect() {
return {
type: 'STOP_MULTI_SELECT'
};
}
/**
* Action that changes block multi-selection.
*
* @param {string} start First block of the multi selection.
* @param {string} end Last block of the multiselection.
* @param {number|null} __experimentalInitialPosition Optional initial position. Pass as null to skip focus within editor canvas.
*/
const multiSelect = (start, end, __experimentalInitialPosition = 0) => ({
select,
dispatch
}) => {
const startBlockRootClientId = select.getBlockRootClientId(start);
const endBlockRootClientId = select.getBlockRootClientId(end);
// Only allow block multi-selections at the same level.
if (startBlockRootClientId !== endBlockRootClientId) {
return;
}
dispatch({
type: 'MULTI_SELECT',
start,
end,
initialPosition: __experimentalInitialPosition
});
const blockCount = select.getSelectedBlockCount();
(0,external_wp_a11y_namespaceObject.speak)((0,external_wp_i18n_namespaceObject.sprintf)( /* translators: %s: number of selected blocks */
(0,external_wp_i18n_namespaceObject._n)('%s block selected.', '%s blocks selected.', blockCount), blockCount), 'assertive');
};
/**
* Action that clears the block selection.
*
* @return {Object} Action object.
*/
function clearSelectedBlock() {
return {
type: 'CLEAR_SELECTED_BLOCK'
};
}
/**
* Action that enables or disables block selection.
*
* @param {boolean} [isSelectionEnabled=true] Whether block selection should
* be enabled.
*
* @return {Object} Action object.
*/
function toggleSelection(isSelectionEnabled = true) {
return {
type: 'TOGGLE_SELECTION',
isSelectionEnabled
};
}
function getBlocksWithDefaultStylesApplied(blocks, blockEditorSettings) {
var _blockEditorSettings$;
const preferredStyleVariations = (_blockEditorSettings$ = blockEditorSettings?.__experimentalPreferredStyleVariations?.value) !== null && _blockEditorSettings$ !== void 0 ? _blockEditorSettings$ : {};
return blocks.map(block => {
const blockName = block.name;
if (!(0,external_wp_blocks_namespaceObject.hasBlockSupport)(blockName, 'defaultStylePicker', true)) {
return block;
}
if (!preferredStyleVariations[blockName]) {
return block;
}
const className = block.attributes?.className;
if (className?.includes('is-style-')) {
return block;
}
const {
attributes = {}
} = block;
const blockStyle = preferredStyleVariations[blockName];
return {
...block,
attributes: {
...attributes,
className: `${className || ''} is-style-${blockStyle}`.trim()
}
};
});
}
/* eslint-disable jsdoc/valid-types */
/**
* Action that replaces given blocks with one or more replacement blocks.
*
* @param {(string|string[])} clientIds Block client ID(s) to replace.
* @param {(Object|Object[])} blocks Replacement block(s).
* @param {number} indexToSelect Index of replacement block to select.
* @param {0|-1|null} initialPosition Index of caret after in the selected block after the operation.
* @param {?Object} meta Optional Meta values to be passed to the action object.
*
* @return {Object} Action object.
*/
const replaceBlocks = (clientIds, blocks, indexToSelect, initialPosition = 0, meta) => ({
select,
dispatch,
registry
}) => {
/* eslint-enable jsdoc/valid-types */
clientIds = actions_castArray(clientIds);
blocks = getBlocksWithDefaultStylesApplied(actions_castArray(blocks), select.getSettings());
const rootClientId = select.getBlockRootClientId(clientIds[0]);
// Replace is valid if the new blocks can be inserted in the root block.
for (let index = 0; index < blocks.length; index++) {
const block = blocks[index];
const canInsertBlock = select.canInsertBlockType(block.name, rootClientId);
if (!canInsertBlock) {
return;
}
}
// We're batching these two actions because an extra `undo/redo` step can
// be created, based on whether we insert a default block or not.
registry.batch(() => {
dispatch({
type: 'REPLACE_BLOCKS',
clientIds,
blocks,
time: Date.now(),
indexToSelect,
initialPosition,
meta
});
// To avoid a focus loss when removing the last block, assure there is
// always a default block if the last of the blocks have been removed.
dispatch.ensureDefaultBlock();
});
};
/**
* Action that replaces a single block with one or more replacement blocks.
*
* @param {(string|string[])} clientId Block client ID to replace.
* @param {(Object|Object[])} block Replacement block(s).
*
* @return {Object} Action object.
*/
function replaceBlock(clientId, block) {
return replaceBlocks(clientId, block);
}
/**
* Higher-order action creator which, given the action type to dispatch creates
* an action creator for managing block movement.
*
* @param {string} type Action type to dispatch.
*
* @return {Function} Action creator.
*/
const createOnMove = type => (clientIds, rootClientId) => ({
select,
dispatch
}) => {
// If one of the blocks is locked or the parent is locked, we cannot move any block.
const canMoveBlocks = select.canMoveBlocks(clientIds, rootClientId);
if (!canMoveBlocks) {
return;
}
dispatch({
type,
clientIds: actions_castArray(clientIds),
rootClientId
});
};
const moveBlocksDown = createOnMove('MOVE_BLOCKS_DOWN');
const moveBlocksUp = createOnMove('MOVE_BLOCKS_UP');
/**
* Action that moves given blocks to a new position.
*
* @param {?string} clientIds The client IDs of the blocks.
* @param {?string} fromRootClientId Root client ID source.
* @param {?string} toRootClientId Root client ID destination.
* @param {number} index The index to move the blocks to.
*/
const moveBlocksToPosition = (clientIds, fromRootClientId = '', toRootClientId = '', index) => ({
select,
dispatch
}) => {
const canMoveBlocks = select.canMoveBlocks(clientIds, fromRootClientId);
// If one of the blocks is locked or the parent is locked, we cannot move any block.
if (!canMoveBlocks) {
return;
}
// If moving inside the same root block the move is always possible.
if (fromRootClientId !== toRootClientId) {
const canRemoveBlocks = select.canRemoveBlocks(clientIds, fromRootClientId);
// If we're moving to another block, it means we're deleting blocks from
// the original block, so we need to check if removing is possible.
if (!canRemoveBlocks) {
return;
}
const canInsertBlocks = select.canInsertBlocks(clientIds, toRootClientId);
// If moving to other parent block, the move is possible if we can insert a block of the same type inside the new parent block.
if (!canInsertBlocks) {
return;
}
}
dispatch({
type: 'MOVE_BLOCKS_TO_POSITION',
fromRootClientId,
toRootClientId,
clientIds,
index
});
};
/**
* Action that moves given block to a new position.
*
* @param {?string} clientId The client ID of the block.
* @param {?string} fromRootClientId Root client ID source.
* @param {?string} toRootClientId Root client ID destination.
* @param {number} index The index to move the block to.
*/
function moveBlockToPosition(clientId, fromRootClientId = '', toRootClientId = '', index) {
return moveBlocksToPosition([clientId], fromRootClientId, toRootClientId, index);
}
/**
* Action that inserts a single block, optionally at a specific index respective a root block list.
*
* Only allowed blocks are inserted. The action may fail silently for blocks that are not allowed or if
* a templateLock is active on the block list.
*
* @param {Object} block Block object to insert.
* @param {?number} index Index at which block should be inserted.
* @param {?string} rootClientId Optional root client ID of block list on which to insert.
* @param {?boolean} updateSelection If true block selection will be updated. If false, block selection will not change. Defaults to true.
* @param {?Object} meta Optional Meta values to be passed to the action object.
*
* @return {Object} Action object.
*/
function insertBlock(block, index, rootClientId, updateSelection, meta) {
return insertBlocks([block], index, rootClientId, updateSelection, 0, meta);
}
/* eslint-disable jsdoc/valid-types */
/**
* Action that inserts an array of blocks, optionally at a specific index respective a root block list.
*
* Only allowed blocks are inserted. The action may fail silently for blocks that are not allowed or if
* a templateLock is active on the block list.
*
* @param {Object[]} blocks Block objects to insert.
* @param {?number} index Index at which block should be inserted.
* @param {?string} rootClientId Optional root client ID of block list on which to insert.
* @param {?boolean} updateSelection If true block selection will be updated. If false, block selection will not change. Defaults to true.
* @param {0|-1|null} initialPosition Initial focus position. Setting it to null prevent focusing the inserted block.
* @param {?Object} meta Optional Meta values to be passed to the action object.
*
* @return {Object} Action object.
*/
const insertBlocks = (blocks, index, rootClientId, updateSelection = true, initialPosition = 0, meta) => ({
select,
dispatch
}) => {
/* eslint-enable jsdoc/valid-types */
if (initialPosition !== null && typeof initialPosition === 'object') {
meta = initialPosition;
initialPosition = 0;
external_wp_deprecated_default()("meta argument in wp.data.dispatch('core/block-editor')", {
since: '5.8',
hint: 'The meta argument is now the 6th argument of the function'
});
}
blocks = getBlocksWithDefaultStylesApplied(actions_castArray(blocks), select.getSettings());
const allowedBlocks = [];
for (const block of blocks) {
const isValid = select.canInsertBlockType(block.name, rootClientId);
if (isValid) {
allowedBlocks.push(block);
}
}
if (allowedBlocks.length) {
dispatch({
type: 'INSERT_BLOCKS',
blocks: allowedBlocks,
index,
rootClientId,
time: Date.now(),
updateSelection,
initialPosition: updateSelection ? initialPosition : null,
meta
});
}
};
/**
* Action that shows the insertion point.
*
* @param {?string} rootClientId Optional root client ID of block list on
* which to insert.
* @param {?number} index Index at which block should be inserted.
* @param {?Object} __unstableOptions Additional options.
* @property {boolean} __unstableWithInserter Whether or not to show an inserter button.
* @property {WPDropOperation} operation The operation to perform when applied,
* either 'insert' or 'replace' for now.
*
* @return {Object} Action object.
*/
function showInsertionPoint(rootClientId, index, __unstableOptions = {}) {
const {
__unstableWithInserter,
operation
} = __unstableOptions;
return {
type: 'SHOW_INSERTION_POINT',
rootClientId,
index,
__unstableWithInserter,
operation
};
}
/**
* Action that hides the insertion point.
*/
const hideInsertionPoint = () => ({
select,
dispatch
}) => {
if (!select.isBlockInsertionPointVisible()) {
return;
}
dispatch({
type: 'HIDE_INSERTION_POINT'
});
};
/**
* Action that resets the template validity.
*
* @param {boolean} isValid template validity flag.
*
* @return {Object} Action object.
*/
function setTemplateValidity(isValid) {
return {
type: 'SET_TEMPLATE_VALIDITY',
isValid
};
}
/**
* Action that synchronizes the template with the list of blocks.
*
* @return {Object} Action object.
*/
const synchronizeTemplate = () => ({
select,
dispatch
}) => {
dispatch({
type: 'SYNCHRONIZE_TEMPLATE'
});
const blocks = select.getBlocks();
const template = select.getTemplate();
const updatedBlockList = (0,external_wp_blocks_namespaceObject.synchronizeBlocksWithTemplate)(blocks, template);
dispatch.resetBlocks(updatedBlockList);
};
/**
* Delete the current selection.
*
* @param {boolean} isForward
*/
const __unstableDeleteSelection = isForward => ({
registry,
select,
dispatch
}) => {
const selectionAnchor = select.getSelectionStart();
const selectionFocus = select.getSelectionEnd();
if (selectionAnchor.clientId === selectionFocus.clientId) return;
// It's not mergeable if there's no rich text selection.
if (!selectionAnchor.attributeKey || !selectionFocus.attributeKey || typeof selectionAnchor.offset === 'undefined' || typeof selectionFocus.offset === 'undefined') return false;
const anchorRootClientId = select.getBlockRootClientId(selectionAnchor.clientId);
const focusRootClientId = select.getBlockRootClientId(selectionFocus.clientId);
// It's not mergeable if the selection doesn't start and end in the same
// block list. Maybe in the future it should be allowed.
if (anchorRootClientId !== focusRootClientId) {
return;
}
const blockOrder = select.getBlockOrder(anchorRootClientId);
const anchorIndex = blockOrder.indexOf(selectionAnchor.clientId);
const focusIndex = blockOrder.indexOf(selectionFocus.clientId);
// Reassign selection start and end based on order.
let selectionStart, selectionEnd;
if (anchorIndex > focusIndex) {
selectionStart = selectionFocus;
selectionEnd = selectionAnchor;
} else {
selectionStart = selectionAnchor;
selectionEnd = selectionFocus;
}
const targetSelection = isForward ? selectionEnd : selectionStart;
const targetBlock = select.getBlock(targetSelection.clientId);
const targetBlockType = (0,external_wp_blocks_namespaceObject.getBlockType)(targetBlock.name);
if (!targetBlockType.merge) {
return;
}
const selectionA = selectionStart;
const selectionB = selectionEnd;
const blockA = select.getBlock(selectionA.clientId);
const blockAType = (0,external_wp_blocks_namespaceObject.getBlockType)(blockA.name);
const blockB = select.getBlock(selectionB.clientId);
const blockBType = (0,external_wp_blocks_namespaceObject.getBlockType)(blockB.name);
const htmlA = blockA.attributes[selectionA.attributeKey];
const htmlB = blockB.attributes[selectionB.attributeKey];
const attributeDefinitionA = blockAType.attributes[selectionA.attributeKey];
const attributeDefinitionB = blockBType.attributes[selectionB.attributeKey];
let valueA = (0,external_wp_richText_namespaceObject.create)({
html: htmlA,
...mapRichTextSettings(attributeDefinitionA)
});
let valueB = (0,external_wp_richText_namespaceObject.create)({
html: htmlB,
...mapRichTextSettings(attributeDefinitionB)
});
valueA = (0,external_wp_richText_namespaceObject.remove)(valueA, selectionA.offset, valueA.text.length);
valueB = (0,external_wp_richText_namespaceObject.insert)(valueB, START_OF_SELECTED_AREA, 0, selectionB.offset);
// Clone the blocks so we don't manipulate the original.
const cloneA = (0,external_wp_blocks_namespaceObject.cloneBlock)(blockA, {
[selectionA.attributeKey]: (0,external_wp_richText_namespaceObject.toHTMLString)({
value: valueA,
...mapRichTextSettings(attributeDefinitionA)
})
});
const cloneB = (0,external_wp_blocks_namespaceObject.cloneBlock)(blockB, {
[selectionB.attributeKey]: (0,external_wp_richText_namespaceObject.toHTMLString)({
value: valueB,
...mapRichTextSettings(attributeDefinitionB)
})
});
const followingBlock = isForward ? cloneA : cloneB;
// We can only merge blocks with similar types
// thus, we transform the block to merge first
const blocksWithTheSameType = blockA.name === blockB.name ? [followingBlock] : (0,external_wp_blocks_namespaceObject.switchToBlockType)(followingBlock, targetBlockType.name);
// If the block types can not match, do nothing
if (!blocksWithTheSameType || !blocksWithTheSameType.length) {
return;
}
let updatedAttributes;
if (isForward) {
const blockToMerge = blocksWithTheSameType.pop();
updatedAttributes = targetBlockType.merge(blockToMerge.attributes, cloneB.attributes);
} else {
const blockToMerge = blocksWithTheSameType.shift();
updatedAttributes = targetBlockType.merge(cloneA.attributes, blockToMerge.attributes);
}
const newAttributeKey = retrieveSelectedAttribute(updatedAttributes);
const convertedHtml = updatedAttributes[newAttributeKey];
const convertedValue = (0,external_wp_richText_namespaceObject.create)({
html: convertedHtml,
...mapRichTextSettings(targetBlockType.attributes[newAttributeKey])
});
const newOffset = convertedValue.text.indexOf(START_OF_SELECTED_AREA);
const newValue = (0,external_wp_richText_namespaceObject.remove)(convertedValue, newOffset, newOffset + 1);
const newHtml = (0,external_wp_richText_namespaceObject.toHTMLString)({
value: newValue,
...mapRichTextSettings(targetBlockType.attributes[newAttributeKey])
});
updatedAttributes[newAttributeKey] = newHtml;
const selectedBlockClientIds = select.getSelectedBlockClientIds();
const replacement = [...(isForward ? blocksWithTheSameType : []), {
// Preserve the original client ID.
...targetBlock,
attributes: {
...targetBlock.attributes,
...updatedAttributes
}
}, ...(isForward ? [] : blocksWithTheSameType)];
registry.batch(() => {
dispatch.selectionChange(targetBlock.clientId, newAttributeKey, newOffset, newOffset);
dispatch.replaceBlocks(selectedBlockClientIds, replacement, 0,
// If we don't pass the `indexToSelect` it will default to the last block.
select.getSelectedBlocksInitialCaretPosition());
});
};
/**
* Split the current selection.
*/
const __unstableSplitSelection = () => ({
select,
dispatch
}) => {
const selectionAnchor = select.getSelectionStart();
const selectionFocus = select.getSelectionEnd();
if (selectionAnchor.clientId === selectionFocus.clientId) return;
// Can't split if the selection is not set.
if (!selectionAnchor.attributeKey || !selectionFocus.attributeKey || typeof selectionAnchor.offset === 'undefined' || typeof selectionFocus.offset === 'undefined') return;
const anchorRootClientId = select.getBlockRootClientId(selectionAnchor.clientId);
const focusRootClientId = select.getBlockRootClientId(selectionFocus.clientId);
// It's not splittable if the selection doesn't start and end in the same
// block list. Maybe in the future it should be allowed.
if (anchorRootClientId !== focusRootClientId) {
return;
}
const blockOrder = select.getBlockOrder(anchorRootClientId);
const anchorIndex = blockOrder.indexOf(selectionAnchor.clientId);
const focusIndex = blockOrder.indexOf(selectionFocus.clientId);
// Reassign selection start and end based on order.
let selectionStart, selectionEnd;
if (anchorIndex > focusIndex) {
selectionStart = selectionFocus;
selectionEnd = selectionAnchor;
} else {
selectionStart = selectionAnchor;
selectionEnd = selectionFocus;
}
const selectionA = selectionStart;
const selectionB = selectionEnd;
const blockA = select.getBlock(selectionA.clientId);
const blockAType = (0,external_wp_blocks_namespaceObject.getBlockType)(blockA.name);
const blockB = select.getBlock(selectionB.clientId);
const blockBType = (0,external_wp_blocks_namespaceObject.getBlockType)(blockB.name);
const htmlA = blockA.attributes[selectionA.attributeKey];
const htmlB = blockB.attributes[selectionB.attributeKey];
const attributeDefinitionA = blockAType.attributes[selectionA.attributeKey];
const attributeDefinitionB = blockBType.attributes[selectionB.attributeKey];
let valueA = (0,external_wp_richText_namespaceObject.create)({
html: htmlA,
...mapRichTextSettings(attributeDefinitionA)
});
let valueB = (0,external_wp_richText_namespaceObject.create)({
html: htmlB,
...mapRichTextSettings(attributeDefinitionB)
});
valueA = (0,external_wp_richText_namespaceObject.remove)(valueA, selectionA.offset, valueA.text.length);
valueB = (0,external_wp_richText_namespaceObject.remove)(valueB, 0, selectionB.offset);
dispatch.replaceBlocks(select.getSelectedBlockClientIds(), [{
// Preserve the original client ID.
...blockA,
attributes: {
...blockA.attributes,
[selectionA.attributeKey]: (0,external_wp_richText_namespaceObject.toHTMLString)({
value: valueA,
...mapRichTextSettings(attributeDefinitionA)
})
}
}, {
// Preserve the original client ID.
...blockB,
attributes: {
...blockB.attributes,
[selectionB.attributeKey]: (0,external_wp_richText_namespaceObject.toHTMLString)({
value: valueB,
...mapRichTextSettings(attributeDefinitionB)
})
}
}]);
};
/**
* Expand the selection to cover the entire blocks, removing partial selection.
*/
const __unstableExpandSelection = () => ({
select,
dispatch
}) => {
const selectionAnchor = select.getSelectionStart();
const selectionFocus = select.getSelectionEnd();
dispatch.selectionChange({
start: {
clientId: selectionAnchor.clientId
},
end: {
clientId: selectionFocus.clientId
}
});
};
/**
* Action that merges two blocks.
*
* @param {string} firstBlockClientId Client ID of the first block to merge.
* @param {string} secondBlockClientId Client ID of the second block to merge.
*/
const mergeBlocks = (firstBlockClientId, secondBlockClientId) => ({
registry,
select,
dispatch
}) => {
const blocks = [firstBlockClientId, secondBlockClientId];
dispatch({
type: 'MERGE_BLOCKS',
blocks
});
const [clientIdA, clientIdB] = blocks;
const blockA = select.getBlock(clientIdA);
const blockAType = (0,external_wp_blocks_namespaceObject.getBlockType)(blockA.name);
if (!blockAType) return;
if (!blockAType.merge && !(0,external_wp_blocks_namespaceObject.getBlockSupport)(blockA.name, '__experimentalOnMerge')) {
dispatch.selectBlock(blockA.clientId);
return;
}
const blockB = select.getBlock(clientIdB);
if (!blockAType.merge) {
// If there's no merge function defined, attempt merging inner
// blocks.
const blocksWithTheSameType = (0,external_wp_blocks_namespaceObject.switchToBlockType)(blockB, blockAType.name);
// Only focus the previous block if it's not mergeable.
if (blocksWithTheSameType?.length !== 1) {
dispatch.selectBlock(blockA.clientId);
return;
}
const [blockWithSameType] = blocksWithTheSameType;
if (blockWithSameType.innerBlocks.length < 1) {
dispatch.selectBlock(blockA.clientId);
return;
}
registry.batch(() => {
dispatch.insertBlocks(blockWithSameType.innerBlocks, undefined, clientIdA);
dispatch.removeBlock(clientIdB);
dispatch.selectBlock(blockWithSameType.innerBlocks[0].clientId);
// Attempt to merge the next block if it's the same type and
// same attributes. This is useful when merging a paragraph into
// a list, and the next block is also a list. If we don't merge,
// it looks like one list, but it's actually two lists. The same
// applies to other blocks such as a group with the same
// attributes.
const nextBlockClientId = select.getNextBlockClientId(clientIdA);
if (nextBlockClientId && select.getBlockName(clientIdA) === select.getBlockName(nextBlockClientId)) {
const rootAttributes = select.getBlockAttributes(clientIdA);
const previousRootAttributes = select.getBlockAttributes(nextBlockClientId);
if (Object.keys(rootAttributes).every(key => rootAttributes[key] === previousRootAttributes[key])) {
dispatch.moveBlocksToPosition(select.getBlockOrder(nextBlockClientId), nextBlockClientId, clientIdA);
dispatch.removeBlock(nextBlockClientId, false);
}
}
});
return;
}
const blockBType = (0,external_wp_blocks_namespaceObject.getBlockType)(blockB.name);
const {
clientId,
attributeKey,
offset
} = select.getSelectionStart();
const selectedBlockType = clientId === clientIdA ? blockAType : blockBType;
const attributeDefinition = selectedBlockType.attributes[attributeKey];
const canRestoreTextSelection = (clientId === clientIdA || clientId === clientIdB) && attributeKey !== undefined && offset !== undefined &&
// We cannot restore text selection if the RichText identifier
// is not a defined block attribute key. This can be the case if the
// fallback intance ID is used to store selection (and no RichText
// identifier is set), or when the identifier is wrong.
!!attributeDefinition;
if (!attributeDefinition) {
if (typeof attributeKey === 'number') {
window.console.error(`RichText needs an identifier prop that is the block attribute key of the attribute it controls. Its type is expected to be a string, but was ${typeof attributeKey}`);
} else {
window.console.error('The RichText identifier prop does not match any attributes defined by the block.');
}
}
// Clone the blocks so we don't insert the character in a "live" block.
const cloneA = (0,external_wp_blocks_namespaceObject.cloneBlock)(blockA);
const cloneB = (0,external_wp_blocks_namespaceObject.cloneBlock)(blockB);
if (canRestoreTextSelection) {
const selectedBlock = clientId === clientIdA ? cloneA : cloneB;
const html = selectedBlock.attributes[attributeKey];
const value = (0,external_wp_richText_namespaceObject.insert)((0,external_wp_richText_namespaceObject.create)({
html,
...mapRichTextSettings(attributeDefinition)
}), START_OF_SELECTED_AREA, offset, offset);
selectedBlock.attributes[attributeKey] = (0,external_wp_richText_namespaceObject.toHTMLString)({
value,
...mapRichTextSettings(attributeDefinition)
});
}
// We can only merge blocks with similar types
// thus, we transform the block to merge first.
const blocksWithTheSameType = blockA.name === blockB.name ? [cloneB] : (0,external_wp_blocks_namespaceObject.switchToBlockType)(cloneB, blockA.name);
// If the block types can not match, do nothing.
if (!blocksWithTheSameType || !blocksWithTheSameType.length) {
return;
}
// Calling the merge to update the attributes and remove the block to be merged.
const updatedAttributes = blockAType.merge(cloneA.attributes, blocksWithTheSameType[0].attributes);
if (canRestoreTextSelection) {
const newAttributeKey = retrieveSelectedAttribute(updatedAttributes);
const convertedHtml = updatedAttributes[newAttributeKey];
const convertedValue = (0,external_wp_richText_namespaceObject.create)({
html: convertedHtml,
...mapRichTextSettings(blockAType.attributes[newAttributeKey])
});
const newOffset = convertedValue.text.indexOf(START_OF_SELECTED_AREA);
const newValue = (0,external_wp_richText_namespaceObject.remove)(convertedValue, newOffset, newOffset + 1);
const newHtml = (0,external_wp_richText_namespaceObject.toHTMLString)({
value: newValue,
...mapRichTextSettings(blockAType.attributes[newAttributeKey])
});
updatedAttributes[newAttributeKey] = newHtml;
dispatch.selectionChange(blockA.clientId, newAttributeKey, newOffset, newOffset);
}
dispatch.replaceBlocks([blockA.clientId, blockB.clientId], [{
...blockA,
attributes: {
...blockA.attributes,
...updatedAttributes
}
}, ...blocksWithTheSameType.slice(1)], 0 // If we don't pass the `indexToSelect` it will default to the last block.
);
};
/**
* Yields action objects used in signalling that the blocks corresponding to
* the set of specified client IDs are to be removed.
*
* @param {string|string[]} clientIds Client IDs of blocks to remove.
* @param {boolean} selectPrevious True if the previous block
* or the immediate parent
* (if no previous block exists)
* should be selected
* when a block is removed.
*/
const removeBlocks = (clientIds, selectPrevious = true) => privateRemoveBlocks(clientIds, selectPrevious);
/**
* Returns an action object used in signalling that the block with the
* specified client ID is to be removed.
*
* @param {string} clientId Client ID of block to remove.
* @param {boolean} selectPrevious True if the previous block should be
* selected when a block is removed.
*
* @return {Object} Action object.
*/
function removeBlock(clientId, selectPrevious) {
return removeBlocks([clientId], selectPrevious);
}
/* eslint-disable jsdoc/valid-types */
/**
* Returns an action object used in signalling that the inner blocks with the
* specified client ID should be replaced.
*
* @param {string} rootClientId Client ID of the block whose InnerBlocks will re replaced.
* @param {Object[]} blocks Block objects to insert as new InnerBlocks
* @param {?boolean} updateSelection If true block selection will be updated. If false, block selection will not change. Defaults to false.
* @param {0|-1|null} initialPosition Initial block position.
* @return {Object} Action object.
*/
function replaceInnerBlocks(rootClientId, blocks, updateSelection = false, initialPosition = 0) {
/* eslint-enable jsdoc/valid-types */
return {
type: 'REPLACE_INNER_BLOCKS',
rootClientId,
blocks,
updateSelection,
initialPosition: updateSelection ? initialPosition : null,
time: Date.now()
};
}
/**
* Returns an action object used to toggle the block editing mode between
* visual and HTML modes.
*
* @param {string} clientId Block client ID.
*
* @return {Object} Action object.
*/
function toggleBlockMode(clientId) {
return {
type: 'TOGGLE_BLOCK_MODE',
clientId
};
}
/**
* Returns an action object used in signalling that the user has begun to type.
*
* @return {Object} Action object.
*/
function startTyping() {
return {
type: 'START_TYPING'
};
}
/**
* Returns an action object used in signalling that the user has stopped typing.
*
* @return {Object} Action object.
*/
function stopTyping() {
return {
type: 'STOP_TYPING'
};
}
/**
* Returns an action object used in signalling that the user has begun to drag blocks.
*
* @param {string[]} clientIds An array of client ids being dragged
*
* @return {Object} Action object.
*/
function startDraggingBlocks(clientIds = []) {
return {
type: 'START_DRAGGING_BLOCKS',
clientIds
};
}
/**
* Returns an action object used in signalling that the user has stopped dragging blocks.
*
* @return {Object} Action object.
*/
function stopDraggingBlocks() {
return {
type: 'STOP_DRAGGING_BLOCKS'
};
}
/**
* Returns an action object used in signalling that the caret has entered formatted text.
*
* @deprecated
*
* @return {Object} Action object.
*/
function enterFormattedText() {
external_wp_deprecated_default()('wp.data.dispatch( "core/block-editor" ).enterFormattedText', {
since: '6.1',
version: '6.3'
});
return {
type: 'DO_NOTHING'
};
}
/**
* Returns an action object used in signalling that the user caret has exited formatted text.
*
* @deprecated
*
* @return {Object} Action object.
*/
function exitFormattedText() {
external_wp_deprecated_default()('wp.data.dispatch( "core/block-editor" ).exitFormattedText', {
since: '6.1',
version: '6.3'
});
return {
type: 'DO_NOTHING'
};
}
/**
* Action that changes the position of the user caret.
*
* @param {string|WPSelection} clientId The selected block client ID.
* @param {string} attributeKey The selected block attribute key.
* @param {number} startOffset The start offset.
* @param {number} endOffset The end offset.
*
* @return {Object} Action object.
*/
function selectionChange(clientId, attributeKey, startOffset, endOffset) {
if (typeof clientId === 'string') {
return {
type: 'SELECTION_CHANGE',
clientId,
attributeKey,
startOffset,
endOffset
};
}
return {
type: 'SELECTION_CHANGE',
...clientId
};
}
/**
* Action that adds a new block of the default type to the block list.
*
* @param {?Object} attributes Optional attributes of the block to assign.
* @param {?string} rootClientId Optional root client ID of block list on which
* to append.
* @param {?number} index Optional index where to insert the default block.
*/
const insertDefaultBlock = (attributes, rootClientId, index) => ({
dispatch
}) => {
// Abort if there is no default block type (if it has been unregistered).
const defaultBlockName = (0,external_wp_blocks_namespaceObject.getDefaultBlockName)();
if (!defaultBlockName) {
return;
}
const block = (0,external_wp_blocks_namespaceObject.createBlock)(defaultBlockName, attributes);
return dispatch.insertBlock(block, index, rootClientId);
};
/**
* Action that changes the nested settings of a given block.
*
* @param {string} clientId Client ID of the block whose nested setting are
* being received.
* @param {Object} settings Object with the new settings for the nested block.
*
* @return {Object} Action object
*/
function updateBlockListSettings(clientId, settings) {
return {
type: 'UPDATE_BLOCK_LIST_SETTINGS',
clientId,
settings
};
}
/**
* Action that updates the block editor settings.
*
* @param {Object} settings Updated settings
*
* @return {Object} Action object
*/
function updateSettings(settings) {
return __experimentalUpdateSettings(settings, {
stripExperimentalSettings: true
});
}
/**
* Action that signals that a temporary reusable block has been saved
* in order to switch its temporary id with the real id.
*
* @param {string} id Reusable block's id.
* @param {string} updatedId Updated block's id.
*
* @return {Object} Action object.
*/
function __unstableSaveReusableBlock(id, updatedId) {
return {
type: 'SAVE_REUSABLE_BLOCK_SUCCESS',
id,
updatedId
};
}
/**
* Action that marks the last block change explicitly as persistent.
*
* @return {Object} Action object.
*/
function __unstableMarkLastChangeAsPersistent() {
return {
type: 'MARK_LAST_CHANGE_AS_PERSISTENT'
};
}
/**
* Action that signals that the next block change should be marked explicitly as not persistent.
*
* @return {Object} Action object.
*/
function __unstableMarkNextChangeAsNotPersistent() {
return {
type: 'MARK_NEXT_CHANGE_AS_NOT_PERSISTENT'
};
}
/**
* Action that marks the last block change as an automatic change, meaning it was not
* performed by the user, and can be undone using the `Escape` and `Backspace` keys.
* This action must be called after the change was made, and any actions that are a
* consequence of it, so it is recommended to be called at the next idle period to ensure all
* selection changes have been recorded.
*/
const __unstableMarkAutomaticChange = () => ({
dispatch
}) => {
dispatch({
type: 'MARK_AUTOMATIC_CHANGE'
});
const {
requestIdleCallback = cb => setTimeout(cb, 100)
} = window;
requestIdleCallback(() => {
dispatch({
type: 'MARK_AUTOMATIC_CHANGE_FINAL'
});
});
};
/**
* Action that enables or disables the navigation mode.
*
* @param {boolean} isNavigationMode Enable/Disable navigation mode.
*/
const setNavigationMode = (isNavigationMode = true) => ({
dispatch
}) => {
dispatch.__unstableSetEditorMode(isNavigationMode ? 'navigation' : 'edit');
};
/**
* Action that sets the editor mode
*
* @param {string} mode Editor mode
*/
const __unstableSetEditorMode = mode => ({
dispatch,
select
}) => {
// When switching to zoom-out mode, we need to select the root block
if (mode === 'zoom-out') {
const firstSelectedClientId = select.getBlockSelectionStart();
if (firstSelectedClientId) {
dispatch.selectBlock(select.getBlockHierarchyRootClientId(firstSelectedClientId));
}
}
dispatch({
type: 'SET_EDITOR_MODE',
mode
});
if (mode === 'navigation') {
(0,external_wp_a11y_namespaceObject.speak)((0,external_wp_i18n_namespaceObject.__)('You are currently in navigation mode. Navigate blocks using the Tab key and Arrow keys. Use Left and Right Arrow keys to move between nesting levels. To exit navigation mode and edit the selected block, press Enter.'));
} else if (mode === 'edit') {
(0,external_wp_a11y_namespaceObject.speak)((0,external_wp_i18n_namespaceObject.__)('You are currently in edit mode. To return to the navigation mode, press Escape.'));
} else if (mode === 'zoom-out') {
(0,external_wp_a11y_namespaceObject.speak)((0,external_wp_i18n_namespaceObject.__)('You are currently in zoom-out mode.'));
}
};
/**
* Action that enables or disables the block moving mode.
*
* @param {string|null} hasBlockMovingClientId Enable/Disable block moving mode.
*/
const setBlockMovingClientId = (hasBlockMovingClientId = null) => ({
dispatch
}) => {
dispatch({
type: 'SET_BLOCK_MOVING_MODE',
hasBlockMovingClientId
});
if (hasBlockMovingClientId) {
(0,external_wp_a11y_namespaceObject.speak)((0,external_wp_i18n_namespaceObject.__)('Use the Tab key and Arrow keys to choose new block location. Use Left and Right Arrow keys to move between nesting levels. Once location is selected press Enter or Space to move the block.'));
}
};
/**
* Action that duplicates a list of blocks.
*
* @param {string[]} clientIds
* @param {boolean} updateSelection
*/
const duplicateBlocks = (clientIds, updateSelection = true) => ({
select,
dispatch
}) => {
if (!clientIds || !clientIds.length) {
return;
}
// Return early if blocks don't exist.
const blocks = select.getBlocksByClientId(clientIds);
if (blocks.some(block => !block)) {
return;
}
// Return early if blocks don't support multiple usage.
const blockNames = blocks.map(block => block.name);
if (blockNames.some(blockName => !(0,external_wp_blocks_namespaceObject.hasBlockSupport)(blockName, 'multiple', true))) {
return;
}
const rootClientId = select.getBlockRootClientId(clientIds[0]);
const clientIdsArray = actions_castArray(clientIds);
const lastSelectedIndex = select.getBlockIndex(clientIdsArray[clientIdsArray.length - 1]);
const clonedBlocks = blocks.map(block => (0,external_wp_blocks_namespaceObject.__experimentalCloneSanitizedBlock)(block));
dispatch.insertBlocks(clonedBlocks, lastSelectedIndex + 1, rootClientId, updateSelection);
if (clonedBlocks.length > 1 && updateSelection) {
dispatch.multiSelect(clonedBlocks[0].clientId, clonedBlocks[clonedBlocks.length - 1].clientId);
}
return clonedBlocks.map(block => block.clientId);
};
/**
* Action that inserts an empty block before a given block.
*
* @param {string} clientId
*/
const insertBeforeBlock = clientId => ({
select,
dispatch
}) => {
if (!clientId) {
return;
}
const rootClientId = select.getBlockRootClientId(clientId);
const isLocked = select.getTemplateLock(rootClientId);
if (isLocked) {
return;
}
const firstSelectedIndex = select.getBlockIndex(clientId);
return dispatch.insertDefaultBlock({}, rootClientId, firstSelectedIndex);
};
/**
* Action that inserts an empty block after a given block.
*
* @param {string} clientId
*/
const insertAfterBlock = clientId => ({
select,
dispatch
}) => {
if (!clientId) {
return;
}
const rootClientId = select.getBlockRootClientId(clientId);
const isLocked = select.getTemplateLock(rootClientId);
if (isLocked) {
return;
}
const firstSelectedIndex = select.getBlockIndex(clientId);
return dispatch.insertDefaultBlock({}, rootClientId, firstSelectedIndex + 1);
};
/**
* Action that toggles the highlighted block state.
*
* @param {string} clientId The block's clientId.
* @param {boolean} isHighlighted The highlight state.
*/
function toggleBlockHighlight(clientId, isHighlighted) {
return {
type: 'TOGGLE_BLOCK_HIGHLIGHT',
clientId,
isHighlighted
};
}
/**
* Action that "flashes" the block with a given `clientId` by rhythmically highlighting it.
*
* @param {string} clientId Target block client ID.
*/
const flashBlock = clientId => async ({
dispatch
}) => {
dispatch(toggleBlockHighlight(clientId, true));
await new Promise(resolve => setTimeout(resolve, 150));
dispatch(toggleBlockHighlight(clientId, false));
};
/**
* Action that sets whether a block has controlled inner blocks.
*
* @param {string} clientId The block's clientId.
* @param {boolean} hasControlledInnerBlocks True if the block's inner blocks are controlled.
*/
function setHasControlledInnerBlocks(clientId, hasControlledInnerBlocks) {
return {
type: 'SET_HAS_CONTROLLED_INNER_BLOCKS',
hasControlledInnerBlocks,
clientId
};
}
/**
* Action that sets whether given blocks are visible on the canvas.
*
* @param {Record} updates For each block's clientId, its new visibility setting.
*/
function setBlockVisibility(updates) {
return {
type: 'SET_BLOCK_VISIBILITY',
updates
};
}
/**
* Action that sets whether a block is being temporaritly edited as blocks.
*
* DO-NOT-USE in production.
* This action is created for internal/experimental only usage and may be
* removed anytime without any warning, causing breakage on any plugin or theme invoking it.
*
* @param {?string} temporarilyEditingAsBlocks The block's clientId being temporaritly edited as blocks.
*/
function __unstableSetTemporarilyEditingAsBlocks(temporarilyEditingAsBlocks) {
return {
type: 'SET_TEMPORARILY_EDITING_AS_BLOCKS',
temporarilyEditingAsBlocks
};
}
/**
* Interface for inserter media requests.
*
* @typedef {Object} InserterMediaRequest
* @property {number} per_page How many items to fetch per page.
* @property {string} search The search term to use for filtering the results.
*/
/**
* Interface for inserter media responses. Any media resource should
* map their response to this interface, in order to create the core
* WordPress media blocks (image, video, audio).
*
* @typedef {Object} InserterMediaItem
* @property {string} title The title of the media item.
* @property {string} url The source url of the media item.
* @property {string} [previewUrl] The preview source url of the media item to display in the media list.
* @property {number} [id] The WordPress id of the media item.
* @property {number|string} [sourceId] The id of the media item from external source.
* @property {string} [alt] The alt text of the media item.
* @property {string} [caption] The caption of the media item.
*/
/**
* Registers a new inserter media category. Once registered, the media category is
* available in the inserter's media tab.
*
* The following interfaces are used:
*
* _Type Definition_
*
* - _InserterMediaRequest_ `Object`: Interface for inserter media requests.
*
* _Properties_
*
* - _per_page_ `number`: How many items to fetch per page.
* - _search_ `string`: The search term to use for filtering the results.
*
* _Type Definition_
*
* - _InserterMediaItem_ `Object`: Interface for inserter media responses. Any media resource should
* map their response to this interface, in order to create the core
* WordPress media blocks (image, video, audio).
*
* _Properties_
*
* - _title_ `string`: The title of the media item.
* - _url_ `string: The source url of the media item.
* - _previewUrl_ `[string]`: The preview source url of the media item to display in the media list.
* - _id_ `[number]`: The WordPress id of the media item.
* - _sourceId_ `[number|string]`: The id of the media item from external source.
* - _alt_ `[string]`: The alt text of the media item.
* - _caption_ `[string]`: The caption of the media item.
*
* @param {InserterMediaCategory} category The inserter media category to register.
*
* @example
* ```js
*
* wp.data.dispatch('core/block-editor').registerInserterMediaCategory( {
* name: 'openverse',
* labels: {
* name: 'Openverse',
* search_items: 'Search Openverse',
* },
* mediaType: 'image',
* async fetch( query = {} ) {
* const defaultArgs = {
* mature: false,
* excluded_source: 'flickr,inaturalist,wikimedia',
* license: 'pdm,cc0',
* };
* const finalQuery = { ...query, ...defaultArgs };
* // Sometimes you might need to map the supported request params according to `InserterMediaRequest`.
* // interface. In this example the `search` query param is named `q`.
* const mapFromInserterMediaRequest = {
* per_page: 'page_size',
* search: 'q',
* };
* const url = new URL( 'https://api.openverse.engineering/v1/images/' );
* Object.entries( finalQuery ).forEach( ( [ key, value ] ) => {
* const queryKey = mapFromInserterMediaRequest[ key ] || key;
* url.searchParams.set( queryKey, value );
* } );
* const response = await window.fetch( url, {
* headers: {
* 'User-Agent': 'WordPress/inserter-media-fetch',
* },
* } );
* const jsonResponse = await response.json();
* const results = jsonResponse.results;
* return results.map( ( result ) => ( {
* ...result,
* // If your response result includes an `id` prop that you want to access later, it should
* // be mapped to `InserterMediaItem`'s `sourceId` prop. This can be useful if you provide
* // a report URL getter.
* // Additionally you should always clear the `id` value of your response results because
* // it is used to identify WordPress media items.
* sourceId: result.id,
* id: undefined,
* caption: result.caption,
* previewUrl: result.thumbnail,
* } ) );
* },
* getReportUrl: ( { sourceId } ) =>
* `https://wordpress.org/openverse/image/${ sourceId }/report/`,
* isExternalResource: true,
* } );
* ```
*
* @typedef {Object} InserterMediaCategory Interface for inserter media category.
* @property {string} name The name of the media category, that should be unique among all media categories.
* @property {Object} labels Labels for the media category.
* @property {string} labels.name General name of the media category. It's used in the inserter media items list.
* @property {string} [labels.search_items='Search'] Label for searching items. Default is ‘Search Posts’ / ‘Search Pages’.
* @property {('image'|'audio'|'video')} mediaType The media type of the media category.
* @property {(InserterMediaRequest) => Promise} fetch The function to fetch media items for the category.
* @property {(InserterMediaItem) => string} [getReportUrl] If the media category supports reporting media items, this function should return
* the report url for the media item. It accepts the `InserterMediaItem` as an argument.
* @property {boolean} [isExternalResource] If the media category is an external resource, this should be set to true.
* This is used to avoid making a request to the external resource when the user
*/
const registerInserterMediaCategory = category => ({
select,
dispatch
}) => {
if (!category || typeof category !== 'object') {
console.error('Category should be an `InserterMediaCategory` object.');
return;
}
if (!category.name) {
console.error('Category should have a `name` that should be unique among all media categories.');
return;
}
if (!category.labels?.name) {
console.error('Category should have a `labels.name`.');
return;
}
if (!['image', 'audio', 'video'].includes(category.mediaType)) {
console.error('Category should have `mediaType` property that is one of `image|audio|video`.');
return;
}
if (!category.fetch || typeof category.fetch !== 'function') {
console.error('Category should have a `fetch` function defined with the following signature `(InserterMediaRequest) => Promise`.');
return;
}
const registeredInserterMediaCategories = select.getRegisteredInserterMediaCategories();
if (registeredInserterMediaCategories.some(({
name
}) => name === category.name)) {
console.error(`A category is already registered with the same name: "${category.name}".`);
return;
}
if (registeredInserterMediaCategories.some(({
labels: {
name
} = {}
}) => name === category.labels?.name)) {
console.error(`A category is already registered with the same labels.name: "${category.labels.name}".`);
return;
}
// `inserterMediaCategories` is a private block editor setting, which means it cannot
// be updated through the public `updateSettings` action. We preserve this setting as
// private, so extenders can only add new inserter media categories and don't have any
// control over the core media categories.
dispatch({
type: 'REGISTER_INSERTER_MEDIA_CATEGORY',
category: {
...category,
isExternalResource: true
}
});
};
/**
* @typedef {import('../components/block-editing-mode').BlockEditingMode} BlockEditingMode
*/
/**
* Sets the block editing mode for a given block.
*
* @see useBlockEditingMode
*
* @param {string} clientId The block client ID, or `''` for the root container.
* @param {BlockEditingMode} mode The block editing mode. One of `'disabled'`,
* `'contentOnly'`, or `'default'`.
*
* @return {Object} Action object.
*/
function setBlockEditingMode(clientId = '', mode) {
return {
type: 'SET_BLOCK_EDITING_MODE',
clientId,
mode
};
}
/**
* Clears the block editing mode for a given block.
*
* @see useBlockEditingMode
*
* @param {string} clientId The block client ID, or `''` for the root container.
*
* @return {Object} Action object.
*/
function unsetBlockEditingMode(clientId = '') {
return {
type: 'UNSET_BLOCK_EDITING_MODE',
clientId
};
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/store/constants.js
const STORE_NAME = 'core/block-editor';
;// CONCATENATED MODULE: external ["wp","privateApis"]
var external_wp_privateApis_namespaceObject = window["wp"]["privateApis"];
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/lock-unlock.js
/**
* WordPress dependencies
*/
const {
lock,
unlock
} = (0,external_wp_privateApis_namespaceObject.__dangerousOptInToUnstableAPIsOnlyForCoreModules)('I know using unstable features means my theme or plugin will inevitably break in the next version of WordPress.', '@wordpress/block-editor');
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/store/index.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
/**
* Block editor data store configuration.
*
* @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/data/README.md#registerStore
*/
const storeConfig = {
reducer: reducer,
selectors: selectors_namespaceObject,
actions: actions_namespaceObject
};
/**
* Store definition for the block editor namespace.
*
* @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/data/README.md#createReduxStore
*/
const store = (0,external_wp_data_namespaceObject.createReduxStore)(STORE_NAME, {
...storeConfig,
persist: ['preferences']
});
// We will be able to use the `register` function once we switch
// the "preferences" persistence to use the new preferences package.
const registeredStore = (0,external_wp_data_namespaceObject.registerStore)(STORE_NAME, {
...storeConfig,
persist: ['preferences']
});
unlock(registeredStore).registerPrivateActions(private_actions_namespaceObject);
unlock(registeredStore).registerPrivateSelectors(private_selectors_namespaceObject);
// TODO: Remove once we switch to the `register` function (see above).
//
// Until then, private functions also need to be attached to the original
// `store` descriptor in order to avoid unit tests failing, which could happen
// when tests create new registries in which they register stores.
//
// @see https://github.com/WordPress/gutenberg/pull/51145#discussion_r1239999590
unlock(store).registerPrivateActions(private_actions_namespaceObject);
unlock(store).registerPrivateSelectors(private_selectors_namespaceObject);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-edit/context.js
/**
* WordPress dependencies
*/
const DEFAULT_BLOCK_EDIT_CONTEXT = {
name: '',
isSelected: false
};
const Context = (0,external_wp_element_namespaceObject.createContext)(DEFAULT_BLOCK_EDIT_CONTEXT);
const {
Provider
} = Context;
/**
* A hook that returns the block edit context.
*
* @return {Object} Block edit context
*/
function useBlockEditContext() {
return (0,external_wp_element_namespaceObject.useContext)(Context);
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/use-display-block-controls/index.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
function useDisplayBlockControls() {
const {
isSelected,
clientId,
name
} = useBlockEditContext();
return (0,external_wp_data_namespaceObject.useSelect)(select => {
if (isSelected) {
return true;
}
const {
getBlockName,
isFirstMultiSelectedBlock,
getMultiSelectedBlockClientIds
} = select(store);
if (isFirstMultiSelectedBlock(clientId)) {
return getMultiSelectedBlockClientIds().every(id => getBlockName(id) === name);
}
return false;
}, [clientId, isSelected, name]);
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-controls/hook.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
function useBlockControlsFill(group, shareWithChildBlocks) {
const isDisplayed = useDisplayBlockControls();
const {
clientId
} = useBlockEditContext();
const isParentDisplayed = (0,external_wp_data_namespaceObject.useSelect)(select => {
const {
getBlockName,
hasSelectedInnerBlock
} = select(store);
const {
hasBlockSupport
} = select(external_wp_blocks_namespaceObject.store);
return shareWithChildBlocks && hasBlockSupport(getBlockName(clientId), '__experimentalExposeControlsToChildren', false) && hasSelectedInnerBlock(clientId);
}, [shareWithChildBlocks, clientId]);
if (isDisplayed) {
return block_controls_groups[group]?.Fill;
}
if (isParentDisplayed) {
return block_controls_groups.parent.Fill;
}
return null;
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-controls/fill.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
function BlockControlsFill({
group = 'default',
controls,
children,
__experimentalShareWithChildBlocks = false
}) {
const Fill = useBlockControlsFill(group, __experimentalShareWithChildBlocks);
if (!Fill) {
return null;
}
const innerMarkup = (0,external_wp_element_namespaceObject.createElement)(external_wp_element_namespaceObject.Fragment, null, group === 'default' && (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.ToolbarGroup, {
controls: controls
}), children);
return (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__experimentalStyleProvider, {
document: document
}, (0,external_wp_element_namespaceObject.createElement)(Fill, null, fillProps => {
// `fillProps.forwardedContext` is an array of context provider entries, provided by slot,
// that should wrap the fill markup.
const {
forwardedContext = []
} = fillProps;
return forwardedContext.reduce((inner, [Provider, props]) => (0,external_wp_element_namespaceObject.createElement)(Provider, {
...props
}, inner), innerMarkup);
}));
}
;// CONCATENATED MODULE: external ["wp","warning"]
var external_wp_warning_namespaceObject = window["wp"]["warning"];
var external_wp_warning_default = /*#__PURE__*/__webpack_require__.n(external_wp_warning_namespaceObject);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-controls/slot.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const {
ComponentsContext
} = unlock(external_wp_components_namespaceObject.privateApis);
function BlockControlsSlot({
group = 'default',
...props
}) {
const toolbarState = (0,external_wp_element_namespaceObject.useContext)(external_wp_components_namespaceObject.__experimentalToolbarContext);
const contextState = (0,external_wp_element_namespaceObject.useContext)(ComponentsContext);
const fillProps = (0,external_wp_element_namespaceObject.useMemo)(() => ({
forwardedContext: [[external_wp_components_namespaceObject.__experimentalToolbarContext.Provider, {
value: toolbarState
}], [ComponentsContext.Provider, {
value: contextState
}]]
}), [toolbarState, contextState]);
const Slot = block_controls_groups[group]?.Slot;
const fills = (0,external_wp_components_namespaceObject.__experimentalUseSlotFills)(Slot?.__unstableName);
if (!Slot) {
true ? external_wp_warning_default()(`Unknown BlockControls group "${group}" provided.`) : 0;
return null;
}
if (!fills?.length) {
return null;
}
const slot = (0,external_wp_element_namespaceObject.createElement)(Slot, {
...props,
bubblesVirtually: true,
fillProps: fillProps
});
if (group === 'default') {
return slot;
}
return (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.ToolbarGroup, null, slot);
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-controls/index.js
/**
* Internal dependencies
*/
const BlockControls = BlockControlsFill;
BlockControls.Slot = BlockControlsSlot;
// This is just here for backward compatibility.
const BlockFormatControls = props => {
return (0,external_wp_element_namespaceObject.createElement)(BlockControlsFill, {
group: "inline",
...props
});
};
BlockFormatControls.Slot = props => {
return (0,external_wp_element_namespaceObject.createElement)(BlockControlsSlot, {
group: "inline",
...props
});
};
/* harmony default export */ var block_controls = (BlockControls);
;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/justify-left.js
/**
* WordPress dependencies
*/
const justifyLeft = (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.SVG, {
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 24 24"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.Path, {
d: "M9 9v6h11V9H9zM4 20h1.5V4H4v16z"
}));
/* harmony default export */ var justify_left = (justifyLeft);
;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/justify-center.js
/**
* WordPress dependencies
*/
const justifyCenter = (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.SVG, {
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 24 24"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.Path, {
d: "M12.5 15v5H11v-5H4V9h7V4h1.5v5h7v6h-7Z"
}));
/* harmony default export */ var justify_center = (justifyCenter);
;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/justify-right.js
/**
* WordPress dependencies
*/
const justifyRight = (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.SVG, {
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 24 24"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.Path, {
d: "M4 15h11V9H4v6zM18.5 4v16H20V4h-1.5z"
}));
/* harmony default export */ var justify_right = (justifyRight);
;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/justify-space-between.js
/**
* WordPress dependencies
*/
const justifySpaceBetween = (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.SVG, {
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 24 24"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.Path, {
d: "M9 15h6V9H9v6zm-5 5h1.5V4H4v16zM18.5 4v16H20V4h-1.5z"
}));
/* harmony default export */ var justify_space_between = (justifySpaceBetween);
;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/justify-stretch.js
/**
* WordPress dependencies
*/
const justifyStretch = (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.SVG, {
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 24 24"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.Path, {
d: "M4 4H5.5V20H4V4ZM7 10L17 10V14L7 14V10ZM20 4H18.5V20H20V4Z"
}));
/* harmony default export */ var justify_stretch = (justifyStretch);
;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/arrow-right.js
/**
* WordPress dependencies
*/
const arrowRight = (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.SVG, {
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 24 24"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.Path, {
d: "m14.5 6.5-1 1 3.7 3.7H4v1.6h13.2l-3.7 3.7 1 1 5.6-5.5z"
}));
/* harmony default export */ var arrow_right = (arrowRight);
;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/arrow-down.js
/**
* WordPress dependencies
*/
const arrowDown = (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.SVG, {
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 24 24"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.Path, {
d: "m16.5 13.5-3.7 3.7V4h-1.5v13.2l-3.8-3.7-1 1 5.5 5.6 5.5-5.6z"
}));
/* harmony default export */ var arrow_down = (arrowDown);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/layouts/definitions.js
// Layout definitions keyed by layout type.
// Provides a common definition of slugs, classnames, base styles, and spacing styles for each layout type.
// If making changes or additions to layout definitions, be sure to update the corresponding PHP definitions in
// `block-supports/layout.php` so that the server-side and client-side definitions match.
const LAYOUT_DEFINITIONS = {
default: {
name: 'default',
slug: 'flow',
className: 'is-layout-flow',
baseStyles: [{
selector: ' > .alignleft',
rules: {
float: 'left',
'margin-inline-start': '0',
'margin-inline-end': '2em'
}
}, {
selector: ' > .alignright',
rules: {
float: 'right',
'margin-inline-start': '2em',
'margin-inline-end': '0'
}
}, {
selector: ' > .aligncenter',
rules: {
'margin-left': 'auto !important',
'margin-right': 'auto !important'
}
}],
spacingStyles: [{
selector: ' > :first-child:first-child',
rules: {
'margin-block-start': '0'
}
}, {
selector: ' > :last-child:last-child',
rules: {
'margin-block-end': '0'
}
}, {
selector: ' > *',
rules: {
'margin-block-start': null,
'margin-block-end': '0'
}
}]
},
constrained: {
name: 'constrained',
slug: 'constrained',
className: 'is-layout-constrained',
baseStyles: [{
selector: ' > .alignleft',
rules: {
float: 'left',
'margin-inline-start': '0',
'margin-inline-end': '2em'
}
}, {
selector: ' > .alignright',
rules: {
float: 'right',
'margin-inline-start': '2em',
'margin-inline-end': '0'
}
}, {
selector: ' > .aligncenter',
rules: {
'margin-left': 'auto !important',
'margin-right': 'auto !important'
}
}, {
selector: ' > :where(:not(.alignleft):not(.alignright):not(.alignfull))',
rules: {
'max-width': 'var(--wp--style--global--content-size)',
'margin-left': 'auto !important',
'margin-right': 'auto !important'
}
}, {
selector: ' > .alignwide',
rules: {
'max-width': 'var(--wp--style--global--wide-size)'
}
}],
spacingStyles: [{
selector: ' > :first-child:first-child',
rules: {
'margin-block-start': '0'
}
}, {
selector: ' > :last-child:last-child',
rules: {
'margin-block-end': '0'
}
}, {
selector: ' > *',
rules: {
'margin-block-start': null,
'margin-block-end': '0'
}
}]
},
flex: {
name: 'flex',
slug: 'flex',
className: 'is-layout-flex',
displayMode: 'flex',
baseStyles: [{
selector: '',
rules: {
'flex-wrap': 'wrap',
'align-items': 'center'
}
}, {
selector: ' > *',
rules: {
margin: '0'
}
}],
spacingStyles: [{
selector: '',
rules: {
gap: null
}
}]
},
grid: {
name: 'grid',
slug: 'grid',
className: 'is-layout-grid',
displayMode: 'grid',
baseStyles: [{
selector: ' > *',
rules: {
margin: '0'
}
}],
spacingStyles: [{
selector: '',
rules: {
gap: null
}
}]
}
};
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/layouts/utils.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
/**
* Utility to generate the proper CSS selector for layout styles.
*
* @param {string} selectors CSS selector, also supports multiple comma-separated selectors.
* @param {string} append The string to append.
*
* @return {string} - CSS selector.
*/
function appendSelectors(selectors, append = '') {
// Ideally we shouldn't need the `.editor-styles-wrapper` increased specificity here
// The problem though is that we have a `.editor-styles-wrapper p { margin: reset; }` style
// it's used to reset the default margin added by wp-admin to paragraphs
// so we need this to be higher speficity otherwise, it won't be applied to paragraphs inside containers
// When the post editor is fully iframed, this extra classname could be removed.
return selectors.split(',').map(subselector => `.editor-styles-wrapper ${subselector}${append ? ` ${append}` : ''}`).join(',');
}
/**
* Get generated blockGap CSS rules based on layout definitions provided in theme.json
* Falsy values in the layout definition's spacingStyles rules will be swapped out
* with the provided `blockGapValue`.
*
* @param {string} selector The CSS selector to target for the generated rules.
* @param {Object} layoutDefinitions Layout definitions object.
* @param {string} layoutType The layout type (e.g. `default` or `flex`).
* @param {string} blockGapValue The current blockGap value to be applied.
* @return {string} The generated CSS rules.
*/
function getBlockGapCSS(selector, layoutDefinitions = LAYOUT_DEFINITIONS, layoutType, blockGapValue) {
let output = '';
if (layoutDefinitions?.[layoutType]?.spacingStyles?.length && blockGapValue) {
layoutDefinitions[layoutType].spacingStyles.forEach(gapStyle => {
output += `${appendSelectors(selector, gapStyle.selector.trim())} { `;
output += Object.entries(gapStyle.rules).map(([cssProperty, value]) => `${cssProperty}: ${value ? value : blockGapValue}`).join('; ');
output += '; }';
});
}
return output;
}
/**
* Helper method to assign contextual info to clarify
* alignment settings.
*
* Besides checking if `contentSize` and `wideSize` have a
* value, we now show this information only if their values
* are not a `css var`. This needs to change when parsing
* css variables land.
*
* @see https://github.com/WordPress/gutenberg/pull/34710#issuecomment-918000752
*
* @param {Object} layout The layout object.
* @return {Object} An object with contextual info per alignment.
*/
function getAlignmentsInfo(layout) {
const {
contentSize,
wideSize,
type = 'default'
} = layout;
const alignmentInfo = {};
const sizeRegex = /^(?!0)\d+(px|em|rem|vw|vh|%)?$/i;
if (sizeRegex.test(contentSize) && type === 'constrained') {
// translators: %s: container size (i.e. 600px etc)
alignmentInfo.none = (0,external_wp_i18n_namespaceObject.sprintf)((0,external_wp_i18n_namespaceObject.__)('Max %s wide'), contentSize);
}
if (sizeRegex.test(wideSize)) {
// translators: %s: container size (i.e. 600px etc)
alignmentInfo.wide = (0,external_wp_i18n_namespaceObject.sprintf)((0,external_wp_i18n_namespaceObject.__)('Max %s wide'), wideSize);
}
return alignmentInfo;
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/sides-all.js
/**
* WordPress dependencies
*/
const sidesAll = (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.SVG, {
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 24 24"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.Path, {
d: "m7.5 6h9v-1.5h-9zm0 13.5h9v-1.5h-9zm-3-3h1.5v-9h-1.5zm13.5-9v9h1.5v-9z"
}));
/* harmony default export */ var sides_all = (sidesAll);
;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/sides-horizontal.js
/**
* WordPress dependencies
*/
const sidesHorizontal = (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.SVG, {
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 24 24"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.Path, {
d: "m7.5 6h9v-1.5h-9zm0 13.5h9v-1.5h-9zm-3-3h1.5v-9h-1.5zm13.5-9v9h1.5v-9z",
style: {
opacity: 0.25
}
}), (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.Path, {
d: "m4.5 7.5v9h1.5v-9z"
}), (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.Path, {
d: "m18 7.5v9h1.5v-9z"
}));
/* harmony default export */ var sides_horizontal = (sidesHorizontal);
;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/sides-vertical.js
/**
* WordPress dependencies
*/
const sidesVertical = (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.SVG, {
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 24 24"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.Path, {
d: "m7.5 6h9v-1.5h-9zm0 13.5h9v-1.5h-9zm-3-3h1.5v-9h-1.5zm13.5-9v9h1.5v-9z",
style: {
opacity: 0.25
}
}), (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.Path, {
d: "m7.5 6h9v-1.5h-9z"
}), (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.Path, {
d: "m7.5 19.5h9v-1.5h-9z"
}));
/* harmony default export */ var sides_vertical = (sidesVertical);
;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/sides-top.js
/**
* WordPress dependencies
*/
const sidesTop = (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.SVG, {
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 24 24"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.Path, {
d: "m7.5 6h9v-1.5h-9zm0 13.5h9v-1.5h-9zm-3-3h1.5v-9h-1.5zm13.5-9v9h1.5v-9z",
style: {
opacity: 0.25
}
}), (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.Path, {
d: "m16.5 6h-9v-1.5h9z"
}));
/* harmony default export */ var sides_top = (sidesTop);
;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/sides-right.js
/**
* WordPress dependencies
*/
const sidesRight = (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.SVG, {
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 24 24"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.Path, {
d: "m7.5 6h9v-1.5h-9zm0 13.5h9v-1.5h-9zm-3-3h1.5v-9h-1.5zm13.5-9v9h1.5v-9z",
style: {
opacity: 0.25
}
}), (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.Path, {
d: "m18 16.5v-9h1.5v9z"
}));
/* harmony default export */ var sides_right = (sidesRight);
;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/sides-bottom.js
/**
* WordPress dependencies
*/
const sidesBottom = (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.SVG, {
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 24 24"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.Path, {
d: "m7.5 6h9v-1.5h-9zm0 13.5h9v-1.5h-9zm-3-3h1.5v-9h-1.5zm13.5-9v9h1.5v-9z",
style: {
opacity: 0.25
}
}), (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.Path, {
d: "m16.5 19.5h-9v-1.5h9z",
style: {
fill: '#1e1e1e'
}
}));
/* harmony default export */ var sides_bottom = (sidesBottom);
;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/sides-left.js
/**
* WordPress dependencies
*/
const sidesLeft = (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.SVG, {
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 24 24"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.Path, {
d: "m7.5 6h9v-1.5h-9zm0 13.5h9v-1.5h-9zm-3-3h1.5v-9h-1.5zm13.5-9v9h1.5v-9z",
style: {
opacity: 0.25
}
}), (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.Path, {
d: "m4.5 16.5v-9h1.5v9z"
}));
/* harmony default export */ var sides_left = (sidesLeft);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/spacing-sizes-control/utils.js
/**
* WordPress dependencies
*/
const ALL_SIDES = ['top', 'right', 'bottom', 'left'];
const DEFAULT_VALUES = {
top: undefined,
right: undefined,
bottom: undefined,
left: undefined
};
const ICONS = {
custom: sides_all,
axial: sides_all,
horizontal: sides_horizontal,
vertical: sides_vertical,
top: sides_top,
right: sides_right,
bottom: sides_bottom,
left: sides_left
};
const LABELS = {
default: (0,external_wp_i18n_namespaceObject.__)('Spacing control'),
top: (0,external_wp_i18n_namespaceObject.__)('Top'),
bottom: (0,external_wp_i18n_namespaceObject.__)('Bottom'),
left: (0,external_wp_i18n_namespaceObject.__)('Left'),
right: (0,external_wp_i18n_namespaceObject.__)('Right'),
mixed: (0,external_wp_i18n_namespaceObject.__)('Mixed'),
vertical: (0,external_wp_i18n_namespaceObject.__)('Vertical'),
horizontal: (0,external_wp_i18n_namespaceObject.__)('Horizontal'),
axial: (0,external_wp_i18n_namespaceObject.__)('Horizontal & vertical'),
custom: (0,external_wp_i18n_namespaceObject.__)('Custom')
};
const VIEWS = {
axial: 'axial',
top: 'top',
right: 'right',
bottom: 'bottom',
left: 'left',
custom: 'custom'
};
/**
* Checks is given value is a spacing preset.
*
* @param {string} value Value to check
*
* @return {boolean} Return true if value is string in format var:preset|spacing|.
*/
function isValueSpacingPreset(value) {
if (!value?.includes) {
return false;
}
return value === '0' || value.includes('var:preset|spacing|');
}
/**
* Converts a spacing preset into a custom value.
*
* @param {string} value Value to convert
* @param {Array} spacingSizes Array of the current spacing preset objects
*
* @return {string} Mapping of the spacing preset to its equivalent custom value.
*/
function getCustomValueFromPreset(value, spacingSizes) {
if (!isValueSpacingPreset(value)) {
return value;
}
const slug = getSpacingPresetSlug(value);
const spacingSize = spacingSizes.find(size => String(size.slug) === slug);
return spacingSize?.size;
}
/**
* Converts a custom value to preset value if one can be found.
*
* Returns value as-is if no match is found.
*
* @param {string} value Value to convert
* @param {Array} spacingSizes Array of the current spacing preset objects
*
* @return {string} The preset value if it can be found.
*/
function getPresetValueFromCustomValue(value, spacingSizes) {
// Return value as-is if it is undefined or is already a preset, or '0';
if (!value || isValueSpacingPreset(value) || value === '0') {
return value;
}
const spacingMatch = spacingSizes.find(size => String(size.size) === String(value));
if (spacingMatch?.slug) {
return `var:preset|spacing|${spacingMatch.slug}`;
}
return value;
}
/**
* Converts a spacing preset into a custom value.
*
* @param {string} value Value to convert.
*
* @return {string | undefined} CSS var string for given spacing preset value.
*/
function getSpacingPresetCssVar(value) {
if (!value) {
return;
}
const slug = value.match(/var:preset\|spacing\|(.+)/);
if (!slug) {
return value;
}
return `var(--wp--preset--spacing--${slug[1]})`;
}
/**
* Returns the slug section of the given spacing preset string.
*
* @param {string} value Value to extract slug from.
*
* @return {string|undefined} The int value of the slug from given spacing preset.
*/
function getSpacingPresetSlug(value) {
if (!value) {
return;
}
if (value === '0' || value === 'default') {
return value;
}
const slug = value.match(/var:preset\|spacing\|(.+)/);
return slug ? slug[1] : undefined;
}
/**
* Converts spacing preset value into a Range component value .
*
* @param {string} presetValue Value to convert to Range value.
* @param {Array} spacingSizes Array of current spacing preset value objects.
*
* @return {number} The int value for use in Range control.
*/
function getSliderValueFromPreset(presetValue, spacingSizes) {
if (presetValue === undefined) {
return 0;
}
const slug = parseFloat(presetValue, 10) === 0 ? '0' : getSpacingPresetSlug(presetValue);
const sliderValue = spacingSizes.findIndex(spacingSize => {
return String(spacingSize.slug) === slug;
});
// Returning NaN rather than undefined as undefined makes range control thumb sit in center
return sliderValue !== -1 ? sliderValue : NaN;
}
/**
* Gets an items with the most occurrence within an array
* https://stackoverflow.com/a/20762713
*
* @param {Array} arr Array of items to check.
* @return {any} The item with the most occurrences.
*/
function mode(arr) {
return arr.sort((a, b) => arr.filter(v => v === a).length - arr.filter(v => v === b).length).pop();
}
/**
* Gets the 'all' input value from values data.
*
* @param {Object} values Box spacing values
*
* @return {string} The most common value from all sides of box.
*/
function getAllRawValue(values = {}) {
return mode(Object.values(values));
}
/**
* Checks to determine if values are mixed.
*
* @param {Object} values Box values.
* @param {Array} sides Sides that values relate to.
*
* @return {boolean} Whether values are mixed.
*/
function isValuesMixed(values = {}, sides = ALL_SIDES) {
return Object.values(values).length >= 1 && Object.values(values).length < sides.length || new Set(Object.values(values)).size > 1;
}
/**
* Checks to determine if values are defined.
*
* @param {Object} values Box values.
*
* @return {boolean} Whether values are defined.
*/
function isValuesDefined(values) {
if (values === undefined || values === null) {
return false;
}
return Object.values(values).filter(value => !!value).length > 0;
}
/**
* Determines whether a particular axis has support. If no axis is
* specified, this function checks if either axis is supported.
*
* @param {Array} sides Supported sides.
* @param {string} axis Which axis to check.
*
* @return {boolean} Whether there is support for the specified axis or both axes.
*/
function hasAxisSupport(sides, axis) {
if (!sides || !sides.length) {
return false;
}
const hasHorizontalSupport = sides.includes('horizontal') || sides.includes('left') && sides.includes('right');
const hasVerticalSupport = sides.includes('vertical') || sides.includes('top') && sides.includes('bottom');
if (axis === 'horizontal') {
return hasHorizontalSupport;
}
if (axis === 'vertical') {
return hasVerticalSupport;
}
return hasHorizontalSupport || hasVerticalSupport;
}
/**
* Determines which menu options should be included in the SidePicker.
*
* @param {Array} sides Supported sides.
*
* @return {Object} Menu options with each option containing label & icon.
*/
function getSupportedMenuItems(sides) {
if (!sides || !sides.length) {
return {};
}
const menuItems = {};
// Determine the primary "side" menu options.
const hasHorizontalSupport = hasAxisSupport(sides, 'horizontal');
const hasVerticalSupport = hasAxisSupport(sides, 'vertical');
if (hasHorizontalSupport && hasVerticalSupport) {
menuItems.axial = {
label: LABELS.axial,
icon: ICONS.axial
};
} else if (hasHorizontalSupport) {
menuItems.axial = {
label: LABELS.horizontal,
icon: ICONS.horizontal
};
} else if (hasVerticalSupport) {
menuItems.axial = {
label: LABELS.vertical,
icon: ICONS.vertical
};
}
// Track whether we have any individual sides so we can omit the custom
// option if required.
let numberOfIndividualSides = 0;
ALL_SIDES.forEach(side => {
if (sides.includes(side)) {
numberOfIndividualSides += 1;
menuItems[side] = {
label: LABELS[side],
icon: ICONS[side]
};
}
});
// Add custom item if there are enough sides to warrant a separated view.
if (numberOfIndividualSides > 1) {
menuItems.custom = {
label: LABELS.custom,
icon: ICONS.custom
};
}
return menuItems;
}
/**
* Checks if the supported sides are balanced for each axis.
* - Horizontal - both left and right sides are supported.
* - Vertical - both top and bottom are supported.
*
* @param {Array} sides The supported sides which may be axes as well.
*
* @return {boolean} Whether or not the supported sides are balanced.
*/
function hasBalancedSidesSupport(sides = []) {
const counts = {
top: 0,
right: 0,
bottom: 0,
left: 0
};
sides.forEach(side => counts[side] += 1);
return (counts.top + counts.bottom) % 2 === 0 && (counts.left + counts.right) % 2 === 0;
}
/**
* Determines which view the SpacingSizesControl should default to on its
* first render; Axial, Custom, or Single side.
*
* @param {Object} values Current side values.
* @param {Array} sides Supported sides.
*
* @return {string} View to display.
*/
function getInitialView(values = {}, sides) {
const {
top,
right,
bottom,
left
} = values;
const sideValues = [top, right, bottom, left].filter(Boolean);
// Axial ( Horizontal & vertical ).
// - Has axial side support
// - Has axial side values which match
// - Has no values and the supported sides are balanced
const hasMatchingAxialValues = top === bottom && left === right && (!!top || !!left);
const hasNoValuesAndBalancedSides = !sideValues.length && hasBalancedSidesSupport(sides);
if (hasAxisSupport(sides) && (hasMatchingAxialValues || hasNoValuesAndBalancedSides)) {
return VIEWS.axial;
}
// Single side.
// - Ensure the side returned is the first side that has a value.
if (sideValues.length === 1) {
let side;
Object.entries(values).some(([key, value]) => {
side = key;
return value !== undefined;
});
return side;
}
// Only single side supported and no value defined.
if (sides?.length === 1 && !sideValues.length) {
return sides[0];
}
// Default to the Custom (separated sides) view.
return VIEWS.custom;
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/hooks/gap.js
/**
* Internal dependencies
*/
/**
* Returns a BoxControl object value from a given blockGap style value.
* The string check is for backwards compatibility before Gutenberg supported
* split gap values (row and column) and the value was a string n + unit.
*
* @param {string? | Object?} blockGapValue A block gap string or axial object value, e.g., '10px' or { top: '10px', left: '10px'}.
* @return {Object|null} A value to pass to the BoxControl component.
*/
function getGapBoxControlValueFromStyle(blockGapValue) {
if (!blockGapValue) {
return null;
}
const isValueString = typeof blockGapValue === 'string';
return {
top: isValueString ? blockGapValue : blockGapValue?.top,
left: isValueString ? blockGapValue : blockGapValue?.left
};
}
/**
* Returns a CSS value for the `gap` property from a given blockGap style.
*
* @param {string? | Object?} blockGapValue A block gap string or axial object value, e.g., '10px' or { top: '10px', left: '10px'}.
* @param {string?} defaultValue A default gap value.
* @return {string|null} The concatenated gap value (row and column).
*/
function getGapCSSValue(blockGapValue, defaultValue = '0') {
const blockGapBoxControlValue = getGapBoxControlValueFromStyle(blockGapValue);
if (!blockGapBoxControlValue) {
return null;
}
const row = getSpacingPresetCssVar(blockGapBoxControlValue?.top) || defaultValue;
const column = getSpacingPresetCssVar(blockGapBoxControlValue?.left) || defaultValue;
return row === column ? row : `${row} ${column}`;
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-vertical-alignment-control/icons.js
/**
* WordPress dependencies
*/
const alignBottom = (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.SVG, {
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 24 24"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.Path, {
d: "M15 4H9v11h6V4zM4 18.5V20h16v-1.5H4z"
}));
const alignCenter = (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.SVG, {
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 24 24"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.Path, {
d: "M20 11h-5V4H9v7H4v1.5h5V20h6v-7.5h5z"
}));
const alignTop = (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.SVG, {
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 24 24"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.Path, {
d: "M9 20h6V9H9v11zM4 4v1.5h16V4H4z"
}));
const alignStretch = (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.SVG, {
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 24 24"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.Path, {
d: "M4 4L20 4L20 5.5L4 5.5L4 4ZM10 7L14 7L14 17L10 17L10 7ZM20 18.5L4 18.5L4 20L20 20L20 18.5Z"
}));
const spaceBetween = (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.SVG, {
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 24 24"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.Path, {
d: "M7 4H17V8L7 8V4ZM7 16L17 16V20L7 20V16ZM20 11.25H4V12.75H20V11.25Z"
}));
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-vertical-alignment-control/ui.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const BLOCK_ALIGNMENTS_CONTROLS = {
top: {
icon: alignTop,
title: (0,external_wp_i18n_namespaceObject._x)('Align top', 'Block vertical alignment setting')
},
center: {
icon: alignCenter,
title: (0,external_wp_i18n_namespaceObject._x)('Align middle', 'Block vertical alignment setting')
},
bottom: {
icon: alignBottom,
title: (0,external_wp_i18n_namespaceObject._x)('Align bottom', 'Block vertical alignment setting')
},
stretch: {
icon: alignStretch,
title: (0,external_wp_i18n_namespaceObject._x)('Stretch to fill', 'Block vertical alignment setting')
},
'space-between': {
icon: spaceBetween,
title: (0,external_wp_i18n_namespaceObject._x)('Space between', 'Block vertical alignment setting')
}
};
const DEFAULT_CONTROLS = ['top', 'center', 'bottom'];
const DEFAULT_CONTROL = 'top';
function BlockVerticalAlignmentUI({
value,
onChange,
controls = DEFAULT_CONTROLS,
isCollapsed = true,
isToolbar
}) {
function applyOrUnset(align) {
return () => onChange(value === align ? undefined : align);
}
const activeAlignment = BLOCK_ALIGNMENTS_CONTROLS[value];
const defaultAlignmentControl = BLOCK_ALIGNMENTS_CONTROLS[DEFAULT_CONTROL];
const UIComponent = isToolbar ? external_wp_components_namespaceObject.ToolbarGroup : external_wp_components_namespaceObject.ToolbarDropdownMenu;
const extraProps = isToolbar ? {
isCollapsed
} : {};
return (0,external_wp_element_namespaceObject.createElement)(UIComponent, {
icon: activeAlignment ? activeAlignment.icon : defaultAlignmentControl.icon,
label: (0,external_wp_i18n_namespaceObject._x)('Change vertical alignment', 'Block vertical alignment setting label'),
controls: controls.map(control => {
return {
...BLOCK_ALIGNMENTS_CONTROLS[control],
isActive: value === control,
role: isCollapsed ? 'menuitemradio' : undefined,
onClick: applyOrUnset(control)
};
}),
...extraProps
});
}
/**
* @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/block-vertical-alignment-toolbar/README.md
*/
/* harmony default export */ var ui = (BlockVerticalAlignmentUI);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-vertical-alignment-control/index.js
/**
* Internal dependencies
*/
const BlockVerticalAlignmentControl = props => {
return (0,external_wp_element_namespaceObject.createElement)(ui, {
...props,
isToolbar: false
});
};
const BlockVerticalAlignmentToolbar = props => {
return (0,external_wp_element_namespaceObject.createElement)(ui, {
...props,
isToolbar: true
});
};
/**
* @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/block-vertical-alignment-control/README.md
*/
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/justify-content-control/ui.js
/**
* WordPress dependencies
*/
const icons = {
left: justify_left,
center: justify_center,
right: justify_right,
'space-between': justify_space_between,
stretch: justify_stretch
};
function JustifyContentUI({
allowedControls = ['left', 'center', 'right', 'space-between'],
isCollapsed = true,
onChange,
value,
popoverProps,
isToolbar
}) {
// If the control is already selected we want a click
// again on the control to deselect the item, so we
// call onChange( undefined )
const handleClick = next => {
if (next === value) {
onChange(undefined);
} else {
onChange(next);
}
};
const icon = value ? icons[value] : icons.left;
const allControls = [{
name: 'left',
icon: justify_left,
title: (0,external_wp_i18n_namespaceObject.__)('Justify items left'),
isActive: 'left' === value,
onClick: () => handleClick('left')
}, {
name: 'center',
icon: justify_center,
title: (0,external_wp_i18n_namespaceObject.__)('Justify items center'),
isActive: 'center' === value,
onClick: () => handleClick('center')
}, {
name: 'right',
icon: justify_right,
title: (0,external_wp_i18n_namespaceObject.__)('Justify items right'),
isActive: 'right' === value,
onClick: () => handleClick('right')
}, {
name: 'space-between',
icon: justify_space_between,
title: (0,external_wp_i18n_namespaceObject.__)('Space between items'),
isActive: 'space-between' === value,
onClick: () => handleClick('space-between')
}, {
name: 'stretch',
icon: justify_stretch,
title: (0,external_wp_i18n_namespaceObject.__)('Stretch items'),
isActive: 'stretch' === value,
onClick: () => handleClick('stretch')
}];
const UIComponent = isToolbar ? external_wp_components_namespaceObject.ToolbarGroup : external_wp_components_namespaceObject.ToolbarDropdownMenu;
const extraProps = isToolbar ? {
isCollapsed
} : {};
return (0,external_wp_element_namespaceObject.createElement)(UIComponent, {
icon: icon,
popoverProps: popoverProps,
label: (0,external_wp_i18n_namespaceObject.__)('Change items justification'),
controls: allControls.filter(elem => allowedControls.includes(elem.name)),
...extraProps
});
}
/* harmony default export */ var justify_content_control_ui = (JustifyContentUI);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/justify-content-control/index.js
/**
* Internal dependencies
*/
const JustifyContentControl = props => {
return (0,external_wp_element_namespaceObject.createElement)(justify_content_control_ui, {
...props,
isToolbar: false
});
};
const JustifyToolbar = props => {
return (0,external_wp_element_namespaceObject.createElement)(justify_content_control_ui, {
...props,
isToolbar: true
});
};
/**
* @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/justify-content-control/README.md
*/
;// CONCATENATED MODULE: ./node_modules/tslib/tslib.es6.mjs
/******************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
/* global Reflect, Promise, SuppressedError, Symbol */
var extendStatics = function(d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
function __extends(d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
}
var __assign = function() {
__assign = Object.assign || function __assign(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
}
return t;
}
return __assign.apply(this, arguments);
}
function __rest(s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
}
function __decorate(decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
}
function __param(paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
}
function __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
var _, done = false;
for (var i = decorators.length - 1; i >= 0; i--) {
var context = {};
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
if (kind === "accessor") {
if (result === void 0) continue;
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
if (_ = accept(result.get)) descriptor.get = _;
if (_ = accept(result.set)) descriptor.set = _;
if (_ = accept(result.init)) initializers.unshift(_);
}
else if (_ = accept(result)) {
if (kind === "field") initializers.unshift(_);
else descriptor[key] = _;
}
}
if (target) Object.defineProperty(target, contextIn.name, descriptor);
done = true;
};
function __runInitializers(thisArg, initializers, value) {
var useValue = arguments.length > 2;
for (var i = 0; i < initializers.length; i++) {
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
}
return useValue ? value : void 0;
};
function __propKey(x) {
return typeof x === "symbol" ? x : "".concat(x);
};
function __setFunctionName(f, name, prefix) {
if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : "";
return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name });
};
function __metadata(metadataKey, metadataValue) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
}
function __awaiter(thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
}
function __generator(thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (g && (g = 0, op[0] && (_ = 0)), _) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
}
var __createBinding = Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
});
function __exportStar(m, o) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);
}
function __values(o) {
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
if (m) return m.call(o);
if (o && typeof o.length === "number") return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
}
function __read(o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
}
/** @deprecated */
function __spread() {
for (var ar = [], i = 0; i < arguments.length; i++)
ar = ar.concat(__read(arguments[i]));
return ar;
}
/** @deprecated */
function __spreadArrays() {
for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
for (var r = Array(s), k = 0, i = 0; i < il; i++)
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
r[k] = a[j];
return r;
}
function __spreadArray(to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
}
function __await(v) {
return this instanceof __await ? (this.v = v, this) : new __await(v);
}
function __asyncGenerator(thisArg, _arguments, generator) {
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
var g = generator.apply(thisArg, _arguments || []), i, q = [];
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }
function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
function fulfill(value) { resume("next", value); }
function reject(value) { resume("throw", value); }
function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
}
function __asyncDelegator(o) {
var i, p;
return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; }
}
function __asyncValues(o) {
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
var m = o[Symbol.asyncIterator], i;
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
}
function __makeTemplateObject(cooked, raw) {
if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
return cooked;
};
var __setModuleDefault = Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
};
function __importStar(mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
}
function __importDefault(mod) {
return (mod && mod.__esModule) ? mod : { default: mod };
}
function __classPrivateFieldGet(receiver, state, kind, f) {
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
}
function __classPrivateFieldSet(receiver, state, value, kind, f) {
if (kind === "m") throw new TypeError("Private method is not writable");
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
}
function __classPrivateFieldIn(state, receiver) {
if (receiver === null || (typeof receiver !== "object" && typeof receiver !== "function")) throw new TypeError("Cannot use 'in' operator on non-object");
return typeof state === "function" ? receiver === state : state.has(receiver);
}
function __addDisposableResource(env, value, async) {
if (value !== null && value !== void 0) {
if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
var dispose;
if (async) {
if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
dispose = value[Symbol.asyncDispose];
}
if (dispose === void 0) {
if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
dispose = value[Symbol.dispose];
}
if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
env.stack.push({ value: value, dispose: dispose, async: async });
}
else if (async) {
env.stack.push({ async: true });
}
return value;
}
var _SuppressedError = typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
var e = new Error(message);
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
};
function __disposeResources(env) {
function fail(e) {
env.error = env.hasError ? new _SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
env.hasError = true;
}
function next() {
while (env.stack.length) {
var rec = env.stack.pop();
try {
var result = rec.dispose && rec.dispose.call(rec.value);
if (rec.async) return Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
}
catch (e) {
fail(e);
}
}
if (env.hasError) throw env.error;
}
return next();
}
/* harmony default export */ var tslib_es6 = ({
__extends,
__assign,
__rest,
__decorate,
__param,
__metadata,
__awaiter,
__generator,
__createBinding,
__exportStar,
__values,
__read,
__spread,
__spreadArrays,
__spreadArray,
__await,
__asyncGenerator,
__asyncDelegator,
__asyncValues,
__makeTemplateObject,
__importStar,
__importDefault,
__classPrivateFieldGet,
__classPrivateFieldSet,
__classPrivateFieldIn,
__addDisposableResource,
__disposeResources,
});
;// CONCATENATED MODULE: ./node_modules/lower-case/dist.es2015/index.js
/**
* Source: ftp://ftp.unicode.org/Public/UCD/latest/ucd/SpecialCasing.txt
*/
var SUPPORTED_LOCALE = {
tr: {
regexp: /\u0130|\u0049|\u0049\u0307/g,
map: {
İ: "\u0069",
I: "\u0131",
İ: "\u0069",
},
},
az: {
regexp: /\u0130/g,
map: {
İ: "\u0069",
I: "\u0131",
İ: "\u0069",
},
},
lt: {
regexp: /\u0049|\u004A|\u012E|\u00CC|\u00CD|\u0128/g,
map: {
I: "\u0069\u0307",
J: "\u006A\u0307",
Į: "\u012F\u0307",
Ì: "\u0069\u0307\u0300",
Í: "\u0069\u0307\u0301",
Ĩ: "\u0069\u0307\u0303",
},
},
};
/**
* Localized lower case.
*/
function localeLowerCase(str, locale) {
var lang = SUPPORTED_LOCALE[locale.toLowerCase()];
if (lang)
return lowerCase(str.replace(lang.regexp, function (m) { return lang.map[m]; }));
return lowerCase(str);
}
/**
* Lower case as a function.
*/
function lowerCase(str) {
return str.toLowerCase();
}
;// CONCATENATED MODULE: ./node_modules/no-case/dist.es2015/index.js
// Support camel case ("camelCase" -> "camel Case" and "CAMELCase" -> "CAMEL Case").
var DEFAULT_SPLIT_REGEXP = [/([a-z0-9])([A-Z])/g, /([A-Z])([A-Z][a-z])/g];
// Remove all non-word characters.
var DEFAULT_STRIP_REGEXP = /[^A-Z0-9]+/gi;
/**
* Normalize the string into something other libraries can manipulate easier.
*/
function noCase(input, options) {
if (options === void 0) { options = {}; }
var _a = options.splitRegexp, splitRegexp = _a === void 0 ? DEFAULT_SPLIT_REGEXP : _a, _b = options.stripRegexp, stripRegexp = _b === void 0 ? DEFAULT_STRIP_REGEXP : _b, _c = options.transform, transform = _c === void 0 ? lowerCase : _c, _d = options.delimiter, delimiter = _d === void 0 ? " " : _d;
var result = dist_es2015_replace(dist_es2015_replace(input, splitRegexp, "$1\0$2"), stripRegexp, "\0");
var start = 0;
var end = result.length;
// Trim the delimiter from around the output string.
while (result.charAt(start) === "\0")
start++;
while (result.charAt(end - 1) === "\0")
end--;
// Transform each token independently.
return result.slice(start, end).split("\0").map(transform).join(delimiter);
}
/**
* Replace `re` in the input string with the replacement value.
*/
function dist_es2015_replace(input, re, value) {
if (re instanceof RegExp)
return input.replace(re, value);
return re.reduce(function (input, re) { return input.replace(re, value); }, input);
}
;// CONCATENATED MODULE: ./node_modules/dot-case/dist.es2015/index.js
function dotCase(input, options) {
if (options === void 0) { options = {}; }
return noCase(input, __assign({ delimiter: "." }, options));
}
;// CONCATENATED MODULE: ./node_modules/param-case/dist.es2015/index.js
function paramCase(input, options) {
if (options === void 0) { options = {}; }
return dotCase(input, __assign({ delimiter: "-" }, options));
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/utils/object.js
/**
* External dependencies
*/
/**
* Converts a path to an array of its fragments.
* Supports strings, numbers and arrays:
*
* 'foo' => [ 'foo' ]
* 2 => [ '2' ]
* [ 'foo', 'bar' ] => [ 'foo', 'bar' ]
*
* @param {string|number|Array} path Path
* @return {Array} Normalized path.
*/
function normalizePath(path) {
if (Array.isArray(path)) {
return path;
} else if (typeof path === 'number') {
return [path.toString()];
}
return [path];
}
/**
* Converts any string to kebab case.
* Backwards compatible with Lodash's `_.kebabCase()`.
* Backwards compatible with `_wp_to_kebab_case()`.
*
* @see https://lodash.com/docs/4.17.15#kebabCase
* @see https://developer.wordpress.org/reference/functions/_wp_to_kebab_case/
*
* @param {string} str String to convert.
* @return {string} Kebab-cased string
*/
function kebabCase(str) {
let input = str;
if (typeof str !== 'string') {
var _str$toString;
input = (_str$toString = str?.toString?.()) !== null && _str$toString !== void 0 ? _str$toString : '';
}
// See https://github.com/lodash/lodash/blob/b185fcee26b2133bd071f4aaca14b455c2ed1008/lodash.js#L4970
input = input.replace(/['\u2019]/, '');
return paramCase(input, {
splitRegexp: [/(?!(?:1ST|2ND|3RD|[4-9]TH)(?![a-z]))([a-z0-9])([A-Z])/g,
// fooBar => foo-bar, 3Bar => 3-bar
/(?!(?:1st|2nd|3rd|[4-9]th)(?![a-z]))([0-9])([a-z])/g,
// 3bar => 3-bar
/([A-Za-z])([0-9])/g,
// Foo3 => foo-3, foo3 => foo-3
/([A-Z])([A-Z][a-z])/g // FOOBar => foo-bar
]
});
}
/**
* Clones an object.
* Arrays are also cloned as arrays.
* Non-object values are returned unchanged.
*
* @param {*} object Object to clone.
* @return {*} Cloned object, or original literal non-object value.
*/
function cloneObject(object) {
if (Array.isArray(object)) {
return object.map(cloneObject);
}
if (object && typeof object === 'object') {
return {
...Object.fromEntries(Object.entries(object).map(([key, value]) => [key, cloneObject(value)]))
};
}
return object;
}
/**
* Immutably sets a value inside an object. Like `lodash#set`, but returning a
* new object. Treats nullish initial values as empty objects. Clones any
* nested objects. Supports arrays, too.
*
* @param {Object} object Object to set a value in.
* @param {number|string|Array} path Path in the object to modify.
* @param {*} value New value to set.
* @return {Object} Cloned object with the new value set.
*/
function setImmutably(object, path, value) {
const normalizedPath = normalizePath(path);
const newObject = object ? cloneObject(object) : {};
normalizedPath.reduce((acc, key, i) => {
if (acc[key] === undefined) {
if (Number.isInteger(path[i + 1])) {
acc[key] = [];
} else {
acc[key] = {};
}
}
if (i === normalizedPath.length - 1) {
acc[key] = value;
}
return acc[key];
}, newObject);
return newObject;
}
/**
* Helper util to return a value from a certain path of the object.
* Path is specified as either:
* - a string of properties, separated by dots, for example: "x.y".
* - an array of properties, for example `[ 'x', 'y' ]`.
* You can also specify a default value in case the result is nullish.
*
* @param {Object} object Input object.
* @param {string|Array} path Path to the object property.
* @param {*} defaultValue Default value if the value at the specified path is nullish.
* @return {*} Value of the object property at the specified path.
*/
const getValueFromObjectPath = (object, path, defaultValue) => {
var _value;
const normalizedPath = Array.isArray(path) ? path : path.split('.');
let value = object;
normalizedPath.forEach(fieldName => {
value = value?.[fieldName];
});
return (_value = value) !== null && _value !== void 0 ? _value : defaultValue;
};
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/use-setting/index.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const blockedPaths = ['color', 'border', 'dimensions', 'typography', 'spacing'];
const deprecatedFlags = {
'color.palette': settings => settings.colors,
'color.gradients': settings => settings.gradients,
'color.custom': settings => settings.disableCustomColors === undefined ? undefined : !settings.disableCustomColors,
'color.customGradient': settings => settings.disableCustomGradients === undefined ? undefined : !settings.disableCustomGradients,
'typography.fontSizes': settings => settings.fontSizes,
'typography.customFontSize': settings => settings.disableCustomFontSizes === undefined ? undefined : !settings.disableCustomFontSizes,
'typography.lineHeight': settings => settings.enableCustomLineHeight,
'spacing.units': settings => {
if (settings.enableCustomUnits === undefined) {
return;
}
if (settings.enableCustomUnits === true) {
return ['px', 'em', 'rem', 'vh', 'vw', '%'];
}
return settings.enableCustomUnits;
},
'spacing.padding': settings => settings.enableCustomSpacing
};
const prefixedFlags = {
/*
* These were only available in the plugin
* and can be removed when the minimum WordPress version
* for the plugin is 5.9.
*/
'border.customColor': 'border.color',
'border.customStyle': 'border.style',
'border.customWidth': 'border.width',
'typography.customFontStyle': 'typography.fontStyle',
'typography.customFontWeight': 'typography.fontWeight',
'typography.customLetterSpacing': 'typography.letterSpacing',
'typography.customTextDecorations': 'typography.textDecoration',
'typography.customTextTransforms': 'typography.textTransform',
/*
* These were part of WordPress 5.8 and we need to keep them.
*/
'border.customRadius': 'border.radius',
'spacing.customMargin': 'spacing.margin',
'spacing.customPadding': 'spacing.padding',
'typography.customLineHeight': 'typography.lineHeight'
};
/**
* Remove `custom` prefixes for flags that did not land in 5.8.
*
* This provides continued support for `custom` prefixed properties. It will
* be removed once third party devs have had sufficient time to update themes,
* plugins, etc.
*
* @see https://github.com/WordPress/gutenberg/pull/34485
*
* @param {string} path Path to desired value in settings.
* @return {string} The value for defined setting.
*/
const removeCustomPrefixes = path => {
return prefixedFlags[path] || path;
};
/**
* Hook that retrieves the given setting for the block instance in use.
*
* It looks up the settings first in the block instance hierarchy.
* If none is found, it'll look it up in the block editor store.
*
* @param {string} path The path to the setting.
* @return {any} Returns the value defined for the setting.
* @example
* ```js
* const isEnabled = useSetting( 'typography.dropCap' );
* ```
*/
function use_setting_useSetting(path) {
const {
name: blockName,
clientId
} = useBlockEditContext();
return (0,external_wp_data_namespaceObject.useSelect)(select => {
if (blockedPaths.includes(path)) {
// eslint-disable-next-line no-console
console.warn('Top level useSetting paths are disabled. Please use a subpath to query the information needed.');
return undefined;
}
// 0. Allow third parties to filter the block's settings at runtime.
let result = (0,external_wp_hooks_namespaceObject.applyFilters)('blockEditor.useSetting.before', undefined, path, clientId, blockName);
if (undefined !== result) {
return result;
}
const normalizedPath = removeCustomPrefixes(path);
// 1. Take settings from the block instance or its ancestors.
// Start from the current block and work our way up the ancestors.
const candidates = [clientId, ...select(store).getBlockParents(clientId, /* ascending */true)];
for (const candidateClientId of candidates) {
const candidateBlockName = select(store).getBlockName(candidateClientId);
if ((0,external_wp_blocks_namespaceObject.hasBlockSupport)(candidateBlockName, '__experimentalSettings', false)) {
var _getValueFromObjectPa;
const candidateAtts = select(store).getBlockAttributes(candidateClientId);
result = (_getValueFromObjectPa = getValueFromObjectPath(candidateAtts, `settings.blocks.${blockName}.${normalizedPath}`)) !== null && _getValueFromObjectPa !== void 0 ? _getValueFromObjectPa : getValueFromObjectPath(candidateAtts, `settings.${normalizedPath}`);
if (result !== undefined) {
// Stop the search for more distant ancestors and move on.
break;
}
}
}
// 2. Fall back to the settings from the block editor store (__experimentalFeatures).
const settings = select(store).getSettings();
if (result === undefined) {
var _getValueFromObjectPa2;
const defaultsPath = `__experimentalFeatures.${normalizedPath}`;
const blockPath = `__experimentalFeatures.blocks.${blockName}.${normalizedPath}`;
result = (_getValueFromObjectPa2 = getValueFromObjectPath(settings, blockPath)) !== null && _getValueFromObjectPa2 !== void 0 ? _getValueFromObjectPa2 : getValueFromObjectPath(settings, defaultsPath);
}
// Return if the setting was found in either the block instance or the store.
if (result !== undefined) {
if (external_wp_blocks_namespaceObject.__EXPERIMENTAL_PATHS_WITH_MERGE[normalizedPath]) {
var _ref, _result$custom;
return (_ref = (_result$custom = result.custom) !== null && _result$custom !== void 0 ? _result$custom : result.theme) !== null && _ref !== void 0 ? _ref : result.default;
}
return result;
}
// 3. Otherwise, use deprecated settings.
const deprecatedSettingsValue = deprecatedFlags[normalizedPath] ? deprecatedFlags[normalizedPath](settings) : undefined;
if (deprecatedSettingsValue !== undefined) {
return deprecatedSettingsValue;
}
// 4. Fallback for typography.dropCap:
// This is only necessary to support typography.dropCap.
// when __experimentalFeatures are not present (core without plugin).
// To remove when __experimentalFeatures are ported to core.
return normalizedPath === 'typography.dropCap' ? true : undefined;
}, [blockName, clientId, path]);
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/font-sizes/fluid-utils.js
/**
* The fluid utilities must match the backend equivalent.
* See: gutenberg_get_typography_font_size_value() in lib/block-supports/typography.php
* ---------------------------------------------------------------
*/
// Defaults.
const DEFAULT_MAXIMUM_VIEWPORT_WIDTH = '1600px';
const DEFAULT_MINIMUM_VIEWPORT_WIDTH = '320px';
const DEFAULT_SCALE_FACTOR = 1;
const DEFAULT_MINIMUM_FONT_SIZE_FACTOR_MIN = 0.25;
const DEFAULT_MINIMUM_FONT_SIZE_FACTOR_MAX = 0.75;
const DEFAULT_MINIMUM_FONT_SIZE_LIMIT = '14px';
/**
* Computes a fluid font-size value that uses clamp(). A minimum and maximum
* font size OR a single font size can be specified.
*
* If a single font size is specified, it is scaled up and down using a logarithmic scale.
*
* @example
* ```js
* // Calculate fluid font-size value from a minimum and maximum value.
* const fontSize = getComputedFluidTypographyValue( {
* minimumFontSize: '20px',
* maximumFontSize: '45px'
* } );
* // Calculate fluid font-size value from a single font size.
* const fontSize = getComputedFluidTypographyValue( {
* fontSize: '30px',
* } );
* ```
*
* @param {Object} args
* @param {?string} args.minimumViewportWidth Minimum viewport size from which type will have fluidity. Optional if fontSize is specified.
* @param {?string} args.maximumViewportWidth Maximum size up to which type will have fluidity. Optional if fontSize is specified.
* @param {string|number} [args.fontSize] Size to derive maximumFontSize and minimumFontSize from, if necessary. Optional if minimumFontSize and maximumFontSize are specified.
* @param {?string} args.maximumFontSize Maximum font size for any clamp() calculation. Optional.
* @param {?string} args.minimumFontSize Minimum font size for any clamp() calculation. Optional.
* @param {?number} args.scaleFactor A scale factor to determine how fast a font scales within boundaries. Optional.
* @param {?string} args.minimumFontSizeLimit The smallest a calculated font size may be. Optional.
*
* @return {string|null} A font-size value using clamp().
*/
function getComputedFluidTypographyValue({
minimumFontSize,
maximumFontSize,
fontSize,
minimumViewportWidth = DEFAULT_MINIMUM_VIEWPORT_WIDTH,
maximumViewportWidth = DEFAULT_MAXIMUM_VIEWPORT_WIDTH,
scaleFactor = DEFAULT_SCALE_FACTOR,
minimumFontSizeLimit
}) {
// Validate incoming settings and set defaults.
minimumFontSizeLimit = !!getTypographyValueAndUnit(minimumFontSizeLimit) ? minimumFontSizeLimit : DEFAULT_MINIMUM_FONT_SIZE_LIMIT;
/*
* Calculates missing minimumFontSize and maximumFontSize from
* defaultFontSize if provided.
*/
if (fontSize) {
// Parses default font size.
const fontSizeParsed = getTypographyValueAndUnit(fontSize);
// Protect against invalid units.
if (!fontSizeParsed?.unit) {
return null;
}
// Parses the minimum font size limit, so we can perform checks using it.
const minimumFontSizeLimitParsed = getTypographyValueAndUnit(minimumFontSizeLimit, {
coerceTo: fontSizeParsed.unit
});
// Don't enforce minimum font size if a font size has explicitly set a min and max value.
if (!!minimumFontSizeLimitParsed?.value && !minimumFontSize && !maximumFontSize) {
/*
* If a minimum size was not passed to this function
* and the user-defined font size is lower than $minimum_font_size_limit,
* do not calculate a fluid value.
*/
if (fontSizeParsed?.value <= minimumFontSizeLimitParsed?.value) {
return null;
}
}
// If no fluid max font size is available use the incoming value.
if (!maximumFontSize) {
maximumFontSize = `${fontSizeParsed.value}${fontSizeParsed.unit}`;
}
/*
* If no minimumFontSize is provided, create one using
* the given font size multiplied by the min font size scale factor.
*/
if (!minimumFontSize) {
const fontSizeValueInPx = fontSizeParsed.unit === 'px' ? fontSizeParsed.value : fontSizeParsed.value * 16;
/*
* The scale factor is a multiplier that affects how quickly the curve will move towards the minimum,
* that is, how quickly the size factor reaches 0 given increasing font size values.
* For a - b * log2(), lower values of b will make the curve move towards the minimum faster.
* The scale factor is constrained between min and max values.
*/
const minimumFontSizeFactor = Math.min(Math.max(1 - 0.075 * Math.log2(fontSizeValueInPx), DEFAULT_MINIMUM_FONT_SIZE_FACTOR_MIN), DEFAULT_MINIMUM_FONT_SIZE_FACTOR_MAX);
// Calculates the minimum font size.
const calculatedMinimumFontSize = roundToPrecision(fontSizeParsed.value * minimumFontSizeFactor, 3);
// Only use calculated min font size if it's > $minimum_font_size_limit value.
if (!!minimumFontSizeLimitParsed?.value && calculatedMinimumFontSize < minimumFontSizeLimitParsed?.value) {
minimumFontSize = `${minimumFontSizeLimitParsed.value}${minimumFontSizeLimitParsed.unit}`;
} else {
minimumFontSize = `${calculatedMinimumFontSize}${fontSizeParsed.unit}`;
}
}
}
// Grab the minimum font size and normalize it in order to use the value for calculations.
const minimumFontSizeParsed = getTypographyValueAndUnit(minimumFontSize);
// We get a 'preferred' unit to keep units consistent when calculating,
// otherwise the result will not be accurate.
const fontSizeUnit = minimumFontSizeParsed?.unit || 'rem';
// Grabs the maximum font size and normalize it in order to use the value for calculations.
const maximumFontSizeParsed = getTypographyValueAndUnit(maximumFontSize, {
coerceTo: fontSizeUnit
});
// Checks for mandatory min and max sizes, and protects against unsupported units.
if (!minimumFontSizeParsed || !maximumFontSizeParsed) {
return null;
}
// Uses rem for accessible fluid target font scaling.
const minimumFontSizeRem = getTypographyValueAndUnit(minimumFontSize, {
coerceTo: 'rem'
});
// Viewport widths defined for fluid typography. Normalize units
const maximumViewportWidthParsed = getTypographyValueAndUnit(maximumViewportWidth, {
coerceTo: fontSizeUnit
});
const minimumViewportWidthParsed = getTypographyValueAndUnit(minimumViewportWidth, {
coerceTo: fontSizeUnit
});
// Protect against unsupported units.
if (!maximumViewportWidthParsed || !minimumViewportWidthParsed || !minimumFontSizeRem) {
return null;
}
// Build CSS rule.
// Borrowed from https://websemantics.uk/tools/responsive-font-calculator/.
const minViewportWidthOffsetValue = roundToPrecision(minimumViewportWidthParsed.value / 100, 3);
const viewportWidthOffset = roundToPrecision(minViewportWidthOffsetValue, 3) + fontSizeUnit;
const linearFactor = 100 * ((maximumFontSizeParsed.value - minimumFontSizeParsed.value) / (maximumViewportWidthParsed.value - minimumViewportWidthParsed.value));
const linearFactorScaled = roundToPrecision((linearFactor || 1) * scaleFactor, 3);
const fluidTargetFontSize = `${minimumFontSizeRem.value}${minimumFontSizeRem.unit} + ((1vw - ${viewportWidthOffset}) * ${linearFactorScaled})`;
return `clamp(${minimumFontSize}, ${fluidTargetFontSize}, ${maximumFontSize})`;
}
/**
* Internal method that checks a string for a unit and value and returns an array consisting of `'value'` and `'unit'`, e.g., [ '42', 'rem' ].
* A raw font size of `value + unit` is expected. If the value is an integer, it will convert to `value + 'px'`.
*
* @param {string|number} rawValue Raw size value from theme.json.
* @param {Object|undefined} options Calculation options.
*
* @return {{ unit: string, value: number }|null} An object consisting of `'value'` and `'unit'` properties.
*/
function getTypographyValueAndUnit(rawValue, options = {}) {
if (typeof rawValue !== 'string' && typeof rawValue !== 'number') {
return null;
}
// Converts numeric values to pixel values by default.
if (isFinite(rawValue)) {
rawValue = `${rawValue}px`;
}
const {
coerceTo,
rootSizeValue,
acceptableUnits
} = {
coerceTo: '',
// Default browser font size. Later we could inject some JS to compute this `getComputedStyle( document.querySelector( "html" ) ).fontSize`.
rootSizeValue: 16,
acceptableUnits: ['rem', 'px', 'em'],
...options
};
const acceptableUnitsGroup = acceptableUnits?.join('|');
const regexUnits = new RegExp(`^(\\d*\\.?\\d+)(${acceptableUnitsGroup}){1,1}$`);
const matches = rawValue.match(regexUnits);
// We need a number value and a unit.
if (!matches || matches.length < 3) {
return null;
}
let [, value, unit] = matches;
let returnValue = parseFloat(value);
if ('px' === coerceTo && ('em' === unit || 'rem' === unit)) {
returnValue = returnValue * rootSizeValue;
unit = coerceTo;
}
if ('px' === unit && ('em' === coerceTo || 'rem' === coerceTo)) {
returnValue = returnValue / rootSizeValue;
unit = coerceTo;
}
/*
* No calculation is required if swapping between em and rem yet,
* since we assume a root size value. Later we might like to differentiate between
* :root font size (rem) and parent element font size (em) relativity.
*/
if (('em' === coerceTo || 'rem' === coerceTo) && ('em' === unit || 'rem' === unit)) {
unit = coerceTo;
}
return {
value: roundToPrecision(returnValue, 3),
unit
};
}
/**
* Returns a value rounded to defined precision.
* Returns `undefined` if the value is not a valid finite number.
*
* @param {number} value Raw value.
* @param {number} digits The number of digits to appear after the decimal point
*
* @return {number|undefined} Value rounded to standard precision.
*/
function roundToPrecision(value, digits = 3) {
const base = Math.pow(10, digits);
return Number.isFinite(value) ? parseFloat(Math.round(value * base) / base) : undefined;
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/global-styles/typography-utils.js
/**
* The fluid utilities must match the backend equivalent.
* See: gutenberg_get_typography_font_size_value() in lib/block-supports/typography.php
* ---------------------------------------------------------------
*/
/**
* Internal dependencies
*/
/**
* @typedef {Object} FluidPreset
* @property {string|undefined} max A maximum font size value.
* @property {?string|undefined} min A minimum font size value.
*/
/**
* @typedef {Object} Preset
* @property {?string|?number} size A default font size.
* @property {string} name A font size name, displayed in the UI.
* @property {string} slug A font size slug
* @property {boolean|FluidPreset|undefined} fluid Specifies the minimum and maximum font size value of a fluid font size.
*/
/**
* @typedef {Object} TypographySettings
* @property {?string} minViewportWidth Minimum viewport size from which type will have fluidity. Optional if size is specified.
* @property {?string} maxViewportWidth Maximum size up to which type will have fluidity. Optional if size is specified.
* @property {?number} scaleFactor A scale factor to determine how fast a font scales within boundaries. Optional.
* @property {?number} minFontSizeFactor How much to scale defaultFontSize by to derive minimumFontSize. Optional.
* @property {?string} minFontSize The smallest a calculated font size may be. Optional.
*/
/**
* Returns a font-size value based on a given font-size preset.
* Takes into account fluid typography parameters and attempts to return a css formula depending on available, valid values.
*
* @param {Preset} preset
* @param {Object} typographyOptions
* @param {boolean|TypographySettings} typographyOptions.fluid Whether fluid typography is enabled, and, optionally, fluid font size options.
*
* @return {string|*} A font-size value or the value of preset.size.
*/
function getTypographyFontSizeValue(preset, typographyOptions) {
const {
size: defaultSize
} = preset;
if (!isFluidTypographyEnabled(typographyOptions)) {
return defaultSize;
}
/*
* Checks whether a font size has explicitly bypassed fluid calculations.
* Also catches falsy values and 0/'0'.
* Fluid calculations cannot be performed on `0`.
*/
if (!defaultSize || '0' === defaultSize || false === preset?.fluid) {
return defaultSize;
}
const fluidTypographySettings = typeof typographyOptions?.fluid === 'object' ? typographyOptions?.fluid : {};
const fluidFontSizeValue = getComputedFluidTypographyValue({
minimumFontSize: preset?.fluid?.min,
maximumFontSize: preset?.fluid?.max,
fontSize: defaultSize,
minimumFontSizeLimit: fluidTypographySettings?.minFontSize,
maximumViewportWidth: fluidTypographySettings?.maxViewportWidth,
minimumViewportWidth: fluidTypographySettings?.minViewportWidth
});
if (!!fluidFontSizeValue) {
return fluidFontSizeValue;
}
return defaultSize;
}
function isFluidTypographyEnabled(typographySettings) {
const fluidSettings = typographySettings?.fluid;
return true === fluidSettings || fluidSettings && typeof fluidSettings === 'object' && Object.keys(fluidSettings).length > 0;
}
/**
* Returns fluid typography settings from theme.json setting object.
*
* @param {Object} settings Theme.json settings
* @param {Object} settings.typography Theme.json typography settings
* @param {Object} settings.layout Theme.json layout settings
* @return {TypographySettings} Fluid typography settings
*/
function getFluidTypographyOptionsFromSettings(settings) {
const typographySettings = settings?.typography;
const layoutSettings = settings?.layout;
const defaultMaxViewportWidth = getTypographyValueAndUnit(layoutSettings?.wideSize) ? layoutSettings?.wideSize : null;
return isFluidTypographyEnabled(typographySettings) && defaultMaxViewportWidth ? {
fluid: {
maxViewportWidth: defaultMaxViewportWidth,
...typographySettings.fluid
}
} : {
fluid: typographySettings?.fluid
};
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/global-styles/utils.js
/**
* External dependencies
*/
/**
* Internal dependencies
*/
/* Supporting data. */
const ROOT_BLOCK_NAME = 'root';
const ROOT_BLOCK_SELECTOR = 'body';
const ROOT_BLOCK_SUPPORTS = (/* unused pure expression or super */ null && (['background', 'backgroundColor', 'color', 'linkColor', 'captionColor', 'buttonColor', 'headingColor', 'fontFamily', 'fontSize', 'fontStyle', 'fontWeight', 'lineHeight', 'textDecoration', 'textTransform', 'padding']));
const PRESET_METADATA = [{
path: ['color', 'palette'],
valueKey: 'color',
cssVarInfix: 'color',
classes: [{
classSuffix: 'color',
propertyName: 'color'
}, {
classSuffix: 'background-color',
propertyName: 'background-color'
}, {
classSuffix: 'border-color',
propertyName: 'border-color'
}]
}, {
path: ['color', 'gradients'],
valueKey: 'gradient',
cssVarInfix: 'gradient',
classes: [{
classSuffix: 'gradient-background',
propertyName: 'background'
}]
}, {
path: ['color', 'duotone'],
valueKey: 'colors',
cssVarInfix: 'duotone',
valueFunc: ({
slug
}) => `url( '#wp-duotone-${slug}' )`,
classes: []
}, {
path: ['shadow', 'presets'],
valueKey: 'shadow',
cssVarInfix: 'shadow',
classes: []
}, {
path: ['typography', 'fontSizes'],
valueFunc: (preset, settings) => getTypographyFontSizeValue(preset, getFluidTypographyOptionsFromSettings(settings)),
valueKey: 'size',
cssVarInfix: 'font-size',
classes: [{
classSuffix: 'font-size',
propertyName: 'font-size'
}]
}, {
path: ['typography', 'fontFamilies'],
valueKey: 'fontFamily',
cssVarInfix: 'font-family',
classes: [{
classSuffix: 'font-family',
propertyName: 'font-family'
}]
}, {
path: ['spacing', 'spacingSizes'],
valueKey: 'size',
cssVarInfix: 'spacing',
valueFunc: ({
size
}) => size,
classes: []
}];
const STYLE_PATH_TO_CSS_VAR_INFIX = {
'color.background': 'color',
'color.text': 'color',
'filter.duotone': 'duotone',
'elements.link.color.text': 'color',
'elements.link.:hover.color.text': 'color',
'elements.link.typography.fontFamily': 'font-family',
'elements.link.typography.fontSize': 'font-size',
'elements.button.color.text': 'color',
'elements.button.color.background': 'color',
'elements.caption.color.text': 'color',
'elements.button.typography.fontFamily': 'font-family',
'elements.button.typography.fontSize': 'font-size',
'elements.heading.color': 'color',
'elements.heading.color.background': 'color',
'elements.heading.typography.fontFamily': 'font-family',
'elements.heading.gradient': 'gradient',
'elements.heading.color.gradient': 'gradient',
'elements.h1.color': 'color',
'elements.h1.color.background': 'color',
'elements.h1.typography.fontFamily': 'font-family',
'elements.h1.color.gradient': 'gradient',
'elements.h2.color': 'color',
'elements.h2.color.background': 'color',
'elements.h2.typography.fontFamily': 'font-family',
'elements.h2.color.gradient': 'gradient',
'elements.h3.color': 'color',
'elements.h3.color.background': 'color',
'elements.h3.typography.fontFamily': 'font-family',
'elements.h3.color.gradient': 'gradient',
'elements.h4.color': 'color',
'elements.h4.color.background': 'color',
'elements.h4.typography.fontFamily': 'font-family',
'elements.h4.color.gradient': 'gradient',
'elements.h5.color': 'color',
'elements.h5.color.background': 'color',
'elements.h5.typography.fontFamily': 'font-family',
'elements.h5.color.gradient': 'gradient',
'elements.h6.color': 'color',
'elements.h6.color.background': 'color',
'elements.h6.typography.fontFamily': 'font-family',
'elements.h6.color.gradient': 'gradient',
'color.gradient': 'gradient',
shadow: 'shadow',
'typography.fontSize': 'font-size',
'typography.fontFamily': 'font-family'
};
// A static list of block attributes that store global style preset slugs.
const STYLE_PATH_TO_PRESET_BLOCK_ATTRIBUTE = {
'color.background': 'backgroundColor',
'color.text': 'textColor',
'color.gradient': 'gradient',
'typography.fontSize': 'fontSize',
'typography.fontFamily': 'fontFamily'
};
function findInPresetsBy(features, blockName, presetPath, presetProperty, presetValueValue) {
// Block presets take priority above root level presets.
const orderedPresetsByOrigin = [getValueFromObjectPath(features, ['blocks', blockName, ...presetPath]), getValueFromObjectPath(features, presetPath)];
for (const presetByOrigin of orderedPresetsByOrigin) {
if (presetByOrigin) {
// Preset origins ordered by priority.
const origins = ['custom', 'theme', 'default'];
for (const origin of origins) {
const presets = presetByOrigin[origin];
if (presets) {
const presetObject = presets.find(preset => preset[presetProperty] === presetValueValue);
if (presetObject) {
if (presetProperty === 'slug') {
return presetObject;
}
// If there is a highest priority preset with the same slug but different value the preset we found was overwritten and should be ignored.
const highestPresetObjectWithSameSlug = findInPresetsBy(features, blockName, presetPath, 'slug', presetObject.slug);
if (highestPresetObjectWithSameSlug[presetProperty] === presetObject[presetProperty]) {
return presetObject;
}
return undefined;
}
}
}
}
}
}
function getPresetVariableFromValue(features, blockName, variableStylePath, presetPropertyValue) {
if (!presetPropertyValue) {
return presetPropertyValue;
}
const cssVarInfix = STYLE_PATH_TO_CSS_VAR_INFIX[variableStylePath];
const metadata = PRESET_METADATA.find(data => data.cssVarInfix === cssVarInfix);
if (!metadata) {
// The property doesn't have preset data
// so the value should be returned as it is.
return presetPropertyValue;
}
const {
valueKey,
path
} = metadata;
const presetObject = findInPresetsBy(features, blockName, path, valueKey, presetPropertyValue);
if (!presetObject) {
// Value wasn't found in the presets,
// so it must be a custom value.
return presetPropertyValue;
}
return `var:preset|${cssVarInfix}|${presetObject.slug}`;
}
function getValueFromPresetVariable(features, blockName, variable, [presetType, slug]) {
const metadata = PRESET_METADATA.find(data => data.cssVarInfix === presetType);
if (!metadata) {
return variable;
}
const presetObject = findInPresetsBy(features.settings, blockName, metadata.path, 'slug', slug);
if (presetObject) {
const {
valueKey
} = metadata;
const result = presetObject[valueKey];
return getValueFromVariable(features, blockName, result);
}
return variable;
}
function getValueFromCustomVariable(features, blockName, variable, path) {
var _getValueFromObjectPa;
const result = (_getValueFromObjectPa = getValueFromObjectPath(features.settings, ['blocks', blockName, 'custom', ...path])) !== null && _getValueFromObjectPa !== void 0 ? _getValueFromObjectPa : getValueFromObjectPath(features.settings, ['custom', ...path]);
if (!result) {
return variable;
}
// A variable may reference another variable so we need recursion until we find the value.
return getValueFromVariable(features, blockName, result);
}
/**
* Attempts to fetch the value of a theme.json CSS variable.
*
* @param {Object} features GlobalStylesContext config, e.g., user, base or merged. Represents the theme.json tree.
* @param {string} blockName The name of a block as represented in the styles property. E.g., 'root' for root-level, and 'core/${blockName}' for blocks.
* @param {string|*} variable An incoming style value. A CSS var value is expected, but it could be any value.
* @return {string|*|{ref}} The value of the CSS var, if found. If not found, the passed variable argument.
*/
function getValueFromVariable(features, blockName, variable) {
if (!variable || typeof variable !== 'string') {
if (variable?.ref && typeof variable?.ref === 'string') {
const refPath = variable.ref.split('.');
variable = getValueFromObjectPath(features, refPath);
// Presence of another ref indicates a reference to another dynamic value.
// Pointing to another dynamic value is not supported.
if (!variable || !!variable?.ref) {
return variable;
}
} else {
return variable;
}
}
const USER_VALUE_PREFIX = 'var:';
const THEME_VALUE_PREFIX = 'var(--wp--';
const THEME_VALUE_SUFFIX = ')';
let parsedVar;
if (variable.startsWith(USER_VALUE_PREFIX)) {
parsedVar = variable.slice(USER_VALUE_PREFIX.length).split('|');
} else if (variable.startsWith(THEME_VALUE_PREFIX) && variable.endsWith(THEME_VALUE_SUFFIX)) {
parsedVar = variable.slice(THEME_VALUE_PREFIX.length, -THEME_VALUE_SUFFIX.length).split('--');
} else {
// We don't know how to parse the value: either is raw of uses complex CSS such as `calc(1px * var(--wp--variable) )`
return variable;
}
const [type, ...path] = parsedVar;
if (type === 'preset') {
return getValueFromPresetVariable(features, blockName, variable, path);
}
if (type === 'custom') {
return getValueFromCustomVariable(features, blockName, variable, path);
}
return variable;
}
/**
* Function that scopes a selector with another one. This works a bit like
* SCSS nesting except the `&` operator isn't supported.
*
* @example
* ```js
* const scope = '.a, .b .c';
* const selector = '> .x, .y';
* const merged = scopeSelector( scope, selector );
* // merged is '.a > .x, .a .y, .b .c > .x, .b .c .y'
* ```
*
* @param {string} scope Selector to scope to.
* @param {string} selector Original selector.
*
* @return {string} Scoped selector.
*/
function scopeSelector(scope, selector) {
const scopes = scope.split(',');
const selectors = selector.split(',');
const selectorsScoped = [];
scopes.forEach(outer => {
selectors.forEach(inner => {
selectorsScoped.push(`${outer.trim()} ${inner.trim()}`);
});
});
return selectorsScoped.join(', ');
}
/**
* Appends a sub-selector to an existing one.
*
* Given the compounded `selector` "h1, h2, h3"
* and the `toAppend` selector ".some-class" the result will be
* "h1.some-class, h2.some-class, h3.some-class".
*
* @param {string} selector Original selector.
* @param {string} toAppend Selector to append.
*
* @return {string} The new selector.
*/
function appendToSelector(selector, toAppend) {
if (!selector.includes(',')) {
return selector + toAppend;
}
const selectors = selector.split(',');
const newSelectors = selectors.map(sel => sel + toAppend);
return newSelectors.join(',');
}
/**
* Compares global style variations according to their styles and settings properties.
*
* @example
* ```js
* const globalStyles = { styles: { typography: { fontSize: '10px' } }, settings: {} };
* const variation = { styles: { typography: { fontSize: '10000px' } }, settings: {} };
* const isEqual = areGlobalStyleConfigsEqual( globalStyles, variation );
* // false
* ```
*
* @param {Object} original A global styles object.
* @param {Object} variation A global styles object.
*
* @return {boolean} Whether `original` and `variation` match.
*/
function areGlobalStyleConfigsEqual(original, variation) {
if (typeof original !== 'object' || typeof variation !== 'object') {
return original === variation;
}
return es6_default()(original?.styles, variation?.styles) && es6_default()(original?.settings, variation?.settings);
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/global-styles/context.js
/**
* WordPress dependencies
*/
const DEFAULT_GLOBAL_STYLES_CONTEXT = {
user: {},
base: {},
merged: {},
setUserConfig: () => {}
};
const GlobalStylesContext = (0,external_wp_element_namespaceObject.createContext)(DEFAULT_GLOBAL_STYLES_CONTEXT);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/global-styles/hooks.js
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const EMPTY_CONFIG = {
settings: {},
styles: {}
};
const VALID_SETTINGS = ['appearanceTools', 'useRootPaddingAwareAlignments', 'border.color', 'border.radius', 'border.style', 'border.width', 'shadow.presets', 'shadow.defaultPresets', 'color.background', 'color.button', 'color.caption', 'color.custom', 'color.customDuotone', 'color.customGradient', 'color.defaultDuotone', 'color.defaultGradients', 'color.defaultPalette', 'color.duotone', 'color.gradients', 'color.heading', 'color.link', 'color.palette', 'color.text', 'custom', 'dimensions.minHeight', 'layout.contentSize', 'layout.definitions', 'layout.wideSize', 'lightbox.enabled', 'lightbox.allowEditing', 'position.fixed', 'position.sticky', 'spacing.customSpacingSize', 'spacing.spacingSizes', 'spacing.spacingScale', 'spacing.blockGap', 'spacing.margin', 'spacing.padding', 'spacing.units', 'typography.fluid', 'typography.customFontSize', 'typography.dropCap', 'typography.fontFamilies', 'typography.fontSizes', 'typography.fontStyle', 'typography.fontWeight', 'typography.letterSpacing', 'typography.lineHeight', 'typography.textColumns', 'typography.textDecoration', 'typography.textTransform', 'typography.writingMode'];
const useGlobalStylesReset = () => {
const {
user: config,
setUserConfig
} = (0,external_wp_element_namespaceObject.useContext)(GlobalStylesContext);
const canReset = !!config && !es6_default()(config, EMPTY_CONFIG);
return [canReset, (0,external_wp_element_namespaceObject.useCallback)(() => setUserConfig(() => EMPTY_CONFIG), [setUserConfig])];
};
function useGlobalSetting(propertyPath, blockName, source = 'all') {
const {
setUserConfig,
...configs
} = (0,external_wp_element_namespaceObject.useContext)(GlobalStylesContext);
const appendedBlockPath = blockName ? '.blocks.' + blockName : '';
const appendedPropertyPath = propertyPath ? '.' + propertyPath : '';
const contextualPath = `settings${appendedBlockPath}${appendedPropertyPath}`;
const globalPath = `settings${appendedPropertyPath}`;
const sourceKey = source === 'all' ? 'merged' : source;
const settingValue = (0,external_wp_element_namespaceObject.useMemo)(() => {
const configToUse = configs[sourceKey];
if (!configToUse) {
throw 'Unsupported source';
}
if (propertyPath) {
var _getValueFromObjectPa;
return (_getValueFromObjectPa = getValueFromObjectPath(configToUse, contextualPath)) !== null && _getValueFromObjectPa !== void 0 ? _getValueFromObjectPa : getValueFromObjectPath(configToUse, globalPath);
}
let result = {};
VALID_SETTINGS.forEach(setting => {
var _getValueFromObjectPa2;
const value = (_getValueFromObjectPa2 = getValueFromObjectPath(configToUse, `settings${appendedBlockPath}.${setting}`)) !== null && _getValueFromObjectPa2 !== void 0 ? _getValueFromObjectPa2 : getValueFromObjectPath(configToUse, `settings.${setting}`);
if (value !== undefined) {
result = setImmutably(result, setting.split('.'), value);
}
});
return result;
}, [configs, sourceKey, propertyPath, contextualPath, globalPath, appendedBlockPath]);
const setSetting = newValue => {
setUserConfig(currentConfig => setImmutably(currentConfig, contextualPath.split('.'), newValue));
};
return [settingValue, setSetting];
}
function useGlobalStyle(path, blockName, source = 'all', {
shouldDecodeEncode = true
} = {}) {
const {
merged: mergedConfig,
base: baseConfig,
user: userConfig,
setUserConfig
} = (0,external_wp_element_namespaceObject.useContext)(GlobalStylesContext);
const appendedPath = path ? '.' + path : '';
const finalPath = !blockName ? `styles${appendedPath}` : `styles.blocks.${blockName}${appendedPath}`;
const setStyle = newValue => {
setUserConfig(currentConfig => setImmutably(currentConfig, finalPath.split('.'), shouldDecodeEncode ? getPresetVariableFromValue(mergedConfig.settings, blockName, path, newValue) : newValue));
};
let rawResult, result;
switch (source) {
case 'all':
rawResult = getValueFromObjectPath(mergedConfig, finalPath);
result = shouldDecodeEncode ? getValueFromVariable(mergedConfig, blockName, rawResult) : rawResult;
break;
case 'user':
rawResult = getValueFromObjectPath(userConfig, finalPath);
result = shouldDecodeEncode ? getValueFromVariable(mergedConfig, blockName, rawResult) : rawResult;
break;
case 'base':
rawResult = getValueFromObjectPath(baseConfig, finalPath);
result = shouldDecodeEncode ? getValueFromVariable(baseConfig, blockName, rawResult) : rawResult;
break;
default:
throw 'Unsupported source';
}
return [result, setStyle];
}
/**
* React hook that overrides a global settings object with block and element specific settings.
*
* @param {Object} parentSettings Settings object.
* @param {blockName?} blockName Block name.
* @param {element?} element Element name.
*
* @return {Object} Merge of settings and supports.
*/
function useSettingsForBlockElement(parentSettings, blockName, element) {
const {
supportedStyles,
supports
} = (0,external_wp_data_namespaceObject.useSelect)(select => {
return {
supportedStyles: unlock(select(external_wp_blocks_namespaceObject.store)).getSupportedStyles(blockName, element),
supports: select(external_wp_blocks_namespaceObject.store).getBlockType(blockName)?.supports
};
}, [blockName, element]);
return (0,external_wp_element_namespaceObject.useMemo)(() => {
const updatedSettings = {
...parentSettings
};
if (!supportedStyles.includes('fontSize')) {
updatedSettings.typography = {
...updatedSettings.typography,
fontSizes: {},
customFontSize: false
};
}
if (!supportedStyles.includes('fontFamily')) {
updatedSettings.typography = {
...updatedSettings.typography,
fontFamilies: {}
};
}
updatedSettings.color = {
...updatedSettings.color,
text: updatedSettings.color?.text && supportedStyles.includes('color'),
background: updatedSettings.color?.background && (supportedStyles.includes('background') || supportedStyles.includes('backgroundColor')),
button: updatedSettings.color?.button && supportedStyles.includes('buttonColor'),
heading: updatedSettings.color?.heading && supportedStyles.includes('headingColor'),
link: updatedSettings.color?.link && supportedStyles.includes('linkColor'),
caption: updatedSettings.color?.caption && supportedStyles.includes('captionColor')
};
// Some blocks can enable background colors but disable gradients.
if (!supportedStyles.includes('background')) {
updatedSettings.color.gradients = [];
updatedSettings.color.customGradient = false;
}
// If filters are not supported by the block/element, disable duotone.
if (!supportedStyles.includes('filter')) {
updatedSettings.color.defaultDuotone = false;
updatedSettings.color.customDuotone = false;
}
['lineHeight', 'fontStyle', 'fontWeight', 'letterSpacing', 'textTransform', 'textDecoration', 'writingMode'].forEach(key => {
if (!supportedStyles.includes(key)) {
updatedSettings.typography = {
...updatedSettings.typography,
[key]: false
};
}
});
// The column-count style is named text column to reduce confusion with
// the columns block and manage expectations from the support.
// See: https://github.com/WordPress/gutenberg/pull/33587
if (!supportedStyles.includes('columnCount')) {
updatedSettings.typography = {
...updatedSettings.typography,
textColumns: false
};
}
['contentSize', 'wideSize'].forEach(key => {
if (!supportedStyles.includes(key)) {
updatedSettings.layout = {
...updatedSettings.layout,
[key]: false
};
}
});
['padding', 'margin', 'blockGap'].forEach(key => {
if (!supportedStyles.includes(key)) {
updatedSettings.spacing = {
...updatedSettings.spacing,
[key]: false
};
}
const sides = Array.isArray(supports?.spacing?.[key]) ? supports?.spacing?.[key] : supports?.spacing?.[key]?.sides;
// Check if spacing type is supported before adding sides.
if (sides?.length && updatedSettings.spacing?.[key]) {
updatedSettings.spacing = {
...updatedSettings.spacing,
[key]: {
...updatedSettings.spacing?.[key],
sides
}
};
}
});
if (!supportedStyles.includes('minHeight')) {
updatedSettings.dimensions = {
...updatedSettings.dimensions,
minHeight: false
};
}
['radius', 'color', 'style', 'width'].forEach(key => {
if (!supportedStyles.includes('border' + key.charAt(0).toUpperCase() + key.slice(1))) {
updatedSettings.border = {
...updatedSettings.border,
[key]: false
};
}
});
updatedSettings.shadow = supportedStyles.includes('shadow') ? updatedSettings.shadow : false;
return updatedSettings;
}, [parentSettings, supportedStyles, supports]);
}
function useColorsPerOrigin(settings) {
const customColors = settings?.color?.palette?.custom;
const themeColors = settings?.color?.palette?.theme;
const defaultColors = settings?.color?.palette?.default;
const shouldDisplayDefaultColors = settings?.color?.defaultPalette;
return (0,external_wp_element_namespaceObject.useMemo)(() => {
const result = [];
if (themeColors && themeColors.length) {
result.push({
name: (0,external_wp_i18n_namespaceObject._x)('Theme', 'Indicates this palette comes from the theme.'),
colors: themeColors
});
}
if (shouldDisplayDefaultColors && defaultColors && defaultColors.length) {
result.push({
name: (0,external_wp_i18n_namespaceObject._x)('Default', 'Indicates this palette comes from WordPress.'),
colors: defaultColors
});
}
if (customColors && customColors.length) {
result.push({
name: (0,external_wp_i18n_namespaceObject._x)('Custom', 'Indicates this palette is created by the user.'),
colors: customColors
});
}
return result;
}, [customColors, themeColors, defaultColors, shouldDisplayDefaultColors]);
}
function useGradientsPerOrigin(settings) {
const customGradients = settings?.color?.gradients?.custom;
const themeGradients = settings?.color?.gradients?.theme;
const defaultGradients = settings?.color?.gradients?.default;
const shouldDisplayDefaultGradients = settings?.color?.defaultGradients;
return (0,external_wp_element_namespaceObject.useMemo)(() => {
const result = [];
if (themeGradients && themeGradients.length) {
result.push({
name: (0,external_wp_i18n_namespaceObject._x)('Theme', 'Indicates this palette comes from the theme.'),
gradients: themeGradients
});
}
if (shouldDisplayDefaultGradients && defaultGradients && defaultGradients.length) {
result.push({
name: (0,external_wp_i18n_namespaceObject._x)('Default', 'Indicates this palette comes from WordPress.'),
gradients: defaultGradients
});
}
if (customGradients && customGradients.length) {
result.push({
name: (0,external_wp_i18n_namespaceObject._x)('Custom', 'Indicates this palette is created by the user.'),
gradients: customGradients
});
}
return result;
}, [customGradients, themeGradients, defaultGradients, shouldDisplayDefaultGradients]);
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/hooks/utils.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
/**
* Removed falsy values from nested object.
*
* @param {*} object
* @return {*} Object cleaned from falsy values
*/
const utils_cleanEmptyObject = object => {
if (object === null || typeof object !== 'object' || Array.isArray(object)) {
return object;
}
const cleanedNestedObjects = Object.entries(object).map(([key, value]) => [key, utils_cleanEmptyObject(value)]).filter(([, value]) => value !== undefined);
return !cleanedNestedObjects.length ? undefined : Object.fromEntries(cleanedNestedObjects);
};
function transformStyles(activeSupports, migrationPaths, result, source, index, results) {
// If there are no active supports return early.
if (Object.values(activeSupports !== null && activeSupports !== void 0 ? activeSupports : {}).every(isActive => !isActive)) {
return result;
}
// If the condition verifies we are probably in the presence of a wrapping transform
// e.g: nesting paragraphs in a group or columns and in that case the styles should not be transformed.
if (results.length === 1 && result.innerBlocks.length === source.length) {
return result;
}
// For cases where we have a transform from one block to multiple blocks
// or multiple blocks to one block we apply the styles of the first source block
// to the result(s).
let referenceBlockAttributes = source[0]?.attributes;
// If we are in presence of transform between more than one block in the source
// that has more than one block in the result
// we apply the styles on source N to the result N,
// if source N does not exists we do nothing.
if (results.length > 1 && source.length > 1) {
if (source[index]) {
referenceBlockAttributes = source[index]?.attributes;
} else {
return result;
}
}
let returnBlock = result;
Object.entries(activeSupports).forEach(([support, isActive]) => {
if (isActive) {
migrationPaths[support].forEach(path => {
const styleValue = getValueFromObjectPath(referenceBlockAttributes, path);
if (styleValue) {
returnBlock = {
...returnBlock,
attributes: setImmutably(returnBlock.attributes, path, styleValue)
};
}
});
}
});
return returnBlock;
}
/**
* Check whether serialization of specific block support feature or set should
* be skipped.
*
* @param {string|Object} blockType Block name or block type object.
* @param {string} featureSet Name of block support feature set.
* @param {string} feature Name of the individual feature to check.
*
* @return {boolean} Whether serialization should occur.
*/
function shouldSkipSerialization(blockType, featureSet, feature) {
const support = (0,external_wp_blocks_namespaceObject.getBlockSupport)(blockType, featureSet);
const skipSerialization = support?.__experimentalSkipSerialization;
if (Array.isArray(skipSerialization)) {
return skipSerialization.includes(feature);
}
return skipSerialization;
}
/**
* Based on the block and its context, returns an object of all the block settings.
* This object can be passed as a prop to all the Styles UI components
* (TypographyPanel, DimensionsPanel...).
*
* @param {string} name Block name.
* @param {*} parentLayout Parent layout.
*
* @return {Object} Settings object.
*/
function useBlockSettings(name, parentLayout) {
const fontFamilies = use_setting_useSetting('typography.fontFamilies');
const fontSizes = use_setting_useSetting('typography.fontSizes');
const customFontSize = use_setting_useSetting('typography.customFontSize');
const fontStyle = use_setting_useSetting('typography.fontStyle');
const fontWeight = use_setting_useSetting('typography.fontWeight');
const lineHeight = use_setting_useSetting('typography.lineHeight');
const textColumns = use_setting_useSetting('typography.textColumns');
const textDecoration = use_setting_useSetting('typography.textDecoration');
const writingMode = use_setting_useSetting('typography.writingMode');
const textTransform = use_setting_useSetting('typography.textTransform');
const letterSpacing = use_setting_useSetting('typography.letterSpacing');
const padding = use_setting_useSetting('spacing.padding');
const margin = use_setting_useSetting('spacing.margin');
const blockGap = use_setting_useSetting('spacing.blockGap');
const spacingSizes = use_setting_useSetting('spacing.spacingSizes');
const units = use_setting_useSetting('spacing.units');
const minHeight = use_setting_useSetting('dimensions.minHeight');
const layout = use_setting_useSetting('layout');
const borderColor = use_setting_useSetting('border.color');
const borderRadius = use_setting_useSetting('border.radius');
const borderStyle = use_setting_useSetting('border.style');
const borderWidth = use_setting_useSetting('border.width');
const customColorsEnabled = use_setting_useSetting('color.custom');
const customColors = use_setting_useSetting('color.palette.custom');
const customDuotone = use_setting_useSetting('color.customDuotone');
const themeColors = use_setting_useSetting('color.palette.theme');
const defaultColors = use_setting_useSetting('color.palette.default');
const defaultPalette = use_setting_useSetting('color.defaultPalette');
const defaultDuotone = use_setting_useSetting('color.defaultDuotone');
const userDuotonePalette = use_setting_useSetting('color.duotone.custom');
const themeDuotonePalette = use_setting_useSetting('color.duotone.theme');
const defaultDuotonePalette = use_setting_useSetting('color.duotone.default');
const userGradientPalette = use_setting_useSetting('color.gradients.custom');
const themeGradientPalette = use_setting_useSetting('color.gradients.theme');
const defaultGradientPalette = use_setting_useSetting('color.gradients.default');
const defaultGradients = use_setting_useSetting('color.defaultGradients');
const areCustomGradientsEnabled = use_setting_useSetting('color.customGradient');
const isBackgroundEnabled = use_setting_useSetting('color.background');
const isLinkEnabled = use_setting_useSetting('color.link');
const isTextEnabled = use_setting_useSetting('color.text');
const isHeadingEnabled = use_setting_useSetting('color.heading');
const isButtonEnabled = use_setting_useSetting('color.button');
const rawSettings = (0,external_wp_element_namespaceObject.useMemo)(() => {
return {
color: {
palette: {
custom: customColors,
theme: themeColors,
default: defaultColors
},
gradients: {
custom: userGradientPalette,
theme: themeGradientPalette,
default: defaultGradientPalette
},
duotone: {
custom: userDuotonePalette,
theme: themeDuotonePalette,
default: defaultDuotonePalette
},
defaultGradients,
defaultPalette,
defaultDuotone,
custom: customColorsEnabled,
customGradient: areCustomGradientsEnabled,
customDuotone,
background: isBackgroundEnabled,
link: isLinkEnabled,
heading: isHeadingEnabled,
button: isButtonEnabled,
text: isTextEnabled
},
typography: {
fontFamilies: {
custom: fontFamilies
},
fontSizes: {
custom: fontSizes
},
customFontSize,
fontStyle,
fontWeight,
lineHeight,
textColumns,
textDecoration,
textTransform,
letterSpacing,
writingMode
},
spacing: {
spacingSizes: {
custom: spacingSizes
},
padding,
margin,
blockGap,
units
},
border: {
color: borderColor,
radius: borderRadius,
style: borderStyle,
width: borderWidth
},
dimensions: {
minHeight
},
layout,
parentLayout
};
}, [fontFamilies, fontSizes, customFontSize, fontStyle, fontWeight, lineHeight, textColumns, textDecoration, textTransform, letterSpacing, writingMode, padding, margin, blockGap, spacingSizes, units, minHeight, layout, parentLayout, borderColor, borderRadius, borderStyle, borderWidth, customColorsEnabled, customColors, customDuotone, themeColors, defaultColors, defaultPalette, defaultDuotone, userDuotonePalette, themeDuotonePalette, defaultDuotonePalette, userGradientPalette, themeGradientPalette, defaultGradientPalette, defaultGradients, areCustomGradientsEnabled, isBackgroundEnabled, isLinkEnabled, isTextEnabled, isHeadingEnabled, isButtonEnabled]);
return useSettingsForBlockElement(rawSettings, name);
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/layouts/flex.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
// Used with the default, horizontal flex orientation.
const justifyContentMap = {
left: 'flex-start',
right: 'flex-end',
center: 'center',
'space-between': 'space-between'
};
// Used with the vertical (column) flex orientation.
const alignItemsMap = {
left: 'flex-start',
right: 'flex-end',
center: 'center',
stretch: 'stretch'
};
const verticalAlignmentMap = {
top: 'flex-start',
center: 'center',
bottom: 'flex-end',
stretch: 'stretch',
'space-between': 'space-between'
};
const flexWrapOptions = ['wrap', 'nowrap'];
/* harmony default export */ var flex = ({
name: 'flex',
label: (0,external_wp_i18n_namespaceObject.__)('Flex'),
inspectorControls: function FlexLayoutInspectorControls({
layout = {},
onChange,
layoutBlockSupport = {}
}) {
const {
allowOrientation = true
} = layoutBlockSupport;
return (0,external_wp_element_namespaceObject.createElement)(external_wp_element_namespaceObject.Fragment, null, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.Flex, null, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.FlexItem, null, (0,external_wp_element_namespaceObject.createElement)(FlexLayoutJustifyContentControl, {
layout: layout,
onChange: onChange
})), (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.FlexItem, null, allowOrientation && (0,external_wp_element_namespaceObject.createElement)(OrientationControl, {
layout: layout,
onChange: onChange
}))), (0,external_wp_element_namespaceObject.createElement)(FlexWrapControl, {
layout: layout,
onChange: onChange
}));
},
toolBarControls: function FlexLayoutToolbarControls({
layout = {},
onChange,
layoutBlockSupport
}) {
if (layoutBlockSupport?.allowSwitching) {
return null;
}
const {
allowVerticalAlignment = true
} = layoutBlockSupport;
return (0,external_wp_element_namespaceObject.createElement)(block_controls, {
group: "block",
__experimentalShareWithChildBlocks: true
}, (0,external_wp_element_namespaceObject.createElement)(FlexLayoutJustifyContentControl, {
layout: layout,
onChange: onChange,
isToolbar: true
}), allowVerticalAlignment && (0,external_wp_element_namespaceObject.createElement)(FlexLayoutVerticalAlignmentControl, {
layout: layout,
onChange: onChange,
isToolbar: true
}));
},
getLayoutStyle: function getLayoutStyle({
selector,
layout,
style,
blockName,
hasBlockGapSupport,
layoutDefinitions = LAYOUT_DEFINITIONS
}) {
const {
orientation = 'horizontal'
} = layout;
// If a block's block.json skips serialization for spacing or spacing.blockGap,
// don't apply the user-defined value to the styles.
const blockGapValue = style?.spacing?.blockGap && !shouldSkipSerialization(blockName, 'spacing', 'blockGap') ? getGapCSSValue(style?.spacing?.blockGap, '0.5em') : undefined;
const justifyContent = justifyContentMap[layout.justifyContent];
const flexWrap = flexWrapOptions.includes(layout.flexWrap) ? layout.flexWrap : 'wrap';
const verticalAlignment = verticalAlignmentMap[layout.verticalAlignment];
const alignItems = alignItemsMap[layout.justifyContent] || alignItemsMap.left;
let output = '';
const rules = [];
if (flexWrap && flexWrap !== 'wrap') {
rules.push(`flex-wrap: ${flexWrap}`);
}
if (orientation === 'horizontal') {
if (verticalAlignment) {
rules.push(`align-items: ${verticalAlignment}`);
}
if (justifyContent) {
rules.push(`justify-content: ${justifyContent}`);
}
} else {
if (verticalAlignment) {
rules.push(`justify-content: ${verticalAlignment}`);
}
rules.push('flex-direction: column');
rules.push(`align-items: ${alignItems}`);
}
if (rules.length) {
output = `${appendSelectors(selector)} {
${rules.join('; ')};
}`;
}
// Output blockGap styles based on rules contained in layout definitions in theme.json.
if (hasBlockGapSupport && blockGapValue) {
output += getBlockGapCSS(selector, layoutDefinitions, 'flex', blockGapValue);
}
return output;
},
getOrientation(layout) {
const {
orientation = 'horizontal'
} = layout;
return orientation;
},
getAlignments() {
return [];
}
});
function FlexLayoutVerticalAlignmentControl({
layout,
onChange,
isToolbar = false
}) {
const {
orientation = 'horizontal'
} = layout;
const defaultVerticalAlignment = orientation === 'horizontal' ? verticalAlignmentMap.center : verticalAlignmentMap.top;
const {
verticalAlignment = defaultVerticalAlignment
} = layout;
const onVerticalAlignmentChange = value => {
onChange({
...layout,
verticalAlignment: value
});
};
if (isToolbar) {
return (0,external_wp_element_namespaceObject.createElement)(BlockVerticalAlignmentControl, {
onChange: onVerticalAlignmentChange,
value: verticalAlignment,
controls: orientation === 'horizontal' ? ['top', 'center', 'bottom', 'stretch'] : ['top', 'center', 'bottom', 'space-between']
});
}
const verticalAlignmentOptions = [{
value: 'flex-start',
label: (0,external_wp_i18n_namespaceObject.__)('Align items top')
}, {
value: 'center',
label: (0,external_wp_i18n_namespaceObject.__)('Align items center')
}, {
value: 'flex-end',
label: (0,external_wp_i18n_namespaceObject.__)('Align items bottom')
}];
return (0,external_wp_element_namespaceObject.createElement)("fieldset", {
className: "block-editor-hooks__flex-layout-vertical-alignment-control"
}, (0,external_wp_element_namespaceObject.createElement)("legend", null, (0,external_wp_i18n_namespaceObject.__)('Vertical alignment')), (0,external_wp_element_namespaceObject.createElement)("div", null, verticalAlignmentOptions.map((value, icon, label) => {
return (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.Button, {
key: value,
label: label,
icon: icon,
isPressed: verticalAlignment === value,
onClick: () => onVerticalAlignmentChange(value)
});
})));
}
const POPOVER_PROPS = {
placement: 'bottom-start'
};
function FlexLayoutJustifyContentControl({
layout,
onChange,
isToolbar = false
}) {
const {
justifyContent = 'left',
orientation = 'horizontal'
} = layout;
const onJustificationChange = value => {
onChange({
...layout,
justifyContent: value
});
};
const allowedControls = ['left', 'center', 'right'];
if (orientation === 'horizontal') {
allowedControls.push('space-between');
} else {
allowedControls.push('stretch');
}
if (isToolbar) {
return (0,external_wp_element_namespaceObject.createElement)(JustifyContentControl, {
allowedControls: allowedControls,
value: justifyContent,
onChange: onJustificationChange,
popoverProps: POPOVER_PROPS
});
}
const justificationOptions = [{
value: 'left',
icon: justify_left,
label: (0,external_wp_i18n_namespaceObject.__)('Justify items left')
}, {
value: 'center',
icon: justify_center,
label: (0,external_wp_i18n_namespaceObject.__)('Justify items center')
}, {
value: 'right',
icon: justify_right,
label: (0,external_wp_i18n_namespaceObject.__)('Justify items right')
}];
if (orientation === 'horizontal') {
justificationOptions.push({
value: 'space-between',
icon: justify_space_between,
label: (0,external_wp_i18n_namespaceObject.__)('Space between items')
});
} else {
justificationOptions.push({
value: 'stretch',
icon: justify_stretch,
label: (0,external_wp_i18n_namespaceObject.__)('Stretch items')
});
}
return (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__experimentalToggleGroupControl, {
__nextHasNoMarginBottom: true,
label: (0,external_wp_i18n_namespaceObject.__)('Justification'),
value: justifyContent,
onChange: onJustificationChange,
className: "block-editor-hooks__flex-layout-justification-controls"
}, justificationOptions.map(({
value,
icon,
label
}) => {
return (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__experimentalToggleGroupControlOptionIcon, {
key: value,
value: value,
icon: icon,
label: label
});
}));
}
function FlexWrapControl({
layout,
onChange
}) {
const {
flexWrap = 'wrap'
} = layout;
return (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.ToggleControl, {
__nextHasNoMarginBottom: true,
label: (0,external_wp_i18n_namespaceObject.__)('Allow to wrap to multiple lines'),
onChange: value => {
onChange({
...layout,
flexWrap: value ? 'wrap' : 'nowrap'
});
},
checked: flexWrap === 'wrap'
});
}
function OrientationControl({
layout,
onChange
}) {
const {
orientation = 'horizontal',
verticalAlignment,
justifyContent
} = layout;
return (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__experimentalToggleGroupControl, {
__nextHasNoMarginBottom: true,
className: "block-editor-hooks__flex-layout-orientation-controls",
label: (0,external_wp_i18n_namespaceObject.__)('Orientation'),
value: orientation,
onChange: value => {
// Make sure the vertical alignment and justification are compatible with the new orientation.
let newVerticalAlignment = verticalAlignment;
let newJustification = justifyContent;
if (value === 'horizontal') {
if (verticalAlignment === 'space-between') {
newVerticalAlignment = 'center';
}
if (justifyContent === 'stretch') {
newJustification = 'left';
}
} else {
if (verticalAlignment === 'stretch') {
newVerticalAlignment = 'top';
}
if (justifyContent === 'space-between') {
newJustification = 'left';
}
}
return onChange({
...layout,
orientation: value,
verticalAlignment: newVerticalAlignment,
justifyContent: newJustification
});
}
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__experimentalToggleGroupControlOptionIcon, {
icon: arrow_right,
value: 'horizontal',
label: (0,external_wp_i18n_namespaceObject.__)('Horizontal')
}), (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__experimentalToggleGroupControlOptionIcon, {
icon: arrow_down,
value: 'vertical',
label: (0,external_wp_i18n_namespaceObject.__)('Vertical')
}));
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/layouts/flow.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
/* harmony default export */ var flow = ({
name: 'default',
label: (0,external_wp_i18n_namespaceObject.__)('Flow'),
inspectorControls: function DefaultLayoutInspectorControls() {
return null;
},
toolBarControls: function DefaultLayoutToolbarControls() {
return null;
},
getLayoutStyle: function getLayoutStyle({
selector,
style,
blockName,
hasBlockGapSupport,
layoutDefinitions = LAYOUT_DEFINITIONS
}) {
const blockGapStyleValue = getGapCSSValue(style?.spacing?.blockGap);
// If a block's block.json skips serialization for spacing or
// spacing.blockGap, don't apply the user-defined value to the styles.
let blockGapValue = '';
if (!shouldSkipSerialization(blockName, 'spacing', 'blockGap')) {
// If an object is provided only use the 'top' value for this kind of gap.
if (blockGapStyleValue?.top) {
blockGapValue = getGapCSSValue(blockGapStyleValue?.top);
} else if (typeof blockGapStyleValue === 'string') {
blockGapValue = getGapCSSValue(blockGapStyleValue);
}
}
let output = '';
// Output blockGap styles based on rules contained in layout definitions in theme.json.
if (hasBlockGapSupport && blockGapValue) {
output += getBlockGapCSS(selector, layoutDefinitions, 'default', blockGapValue);
}
return output;
},
getOrientation() {
return 'vertical';
},
getAlignments(layout, isBlockBasedTheme) {
const alignmentInfo = getAlignmentsInfo(layout);
if (layout.alignments !== undefined) {
if (!layout.alignments.includes('none')) {
layout.alignments.unshift('none');
}
return layout.alignments.map(alignment => ({
name: alignment,
info: alignmentInfo[alignment]
}));
}
const alignments = [{
name: 'left'
}, {
name: 'center'
}, {
name: 'right'
}];
// This is for backwards compatibility with hybrid themes.
if (!isBlockBasedTheme) {
const {
contentSize,
wideSize
} = layout;
if (contentSize) {
alignments.unshift({
name: 'full'
});
}
if (wideSize) {
alignments.unshift({
name: 'wide',
info: alignmentInfo.wide
});
}
}
alignments.unshift({
name: 'none',
info: alignmentInfo.none
});
return alignments;
}
});
;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/icon/index.js
/**
* WordPress dependencies
*/
/** @typedef {{icon: JSX.Element, size?: number} & import('@wordpress/primitives').SVGProps} IconProps */
/**
* Return an SVG icon.
*
* @param {IconProps} props icon is the SVG component to render
* size is a number specifiying the icon size in pixels
* Other props will be passed to wrapped SVG component
* @param {import('react').ForwardedRef} ref The forwarded ref to the SVG element.
*
* @return {JSX.Element} Icon component
*/
function Icon({
icon,
size = 24,
...props
}, ref) {
return (0,external_wp_element_namespaceObject.cloneElement)(icon, {
width: size,
height: size,
...props,
ref
});
}
/* harmony default export */ var build_module_icon = ((0,external_wp_element_namespaceObject.forwardRef)(Icon));
;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/position-center.js
/**
* WordPress dependencies
*/
const positionCenter = (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.SVG, {
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 24 24"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.Path, {
d: "M19 5.5H5V4h14v1.5ZM19 20H5v-1.5h14V20ZM7 9h10v6H7V9Z"
}));
/* harmony default export */ var position_center = (positionCenter);
;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/stretch-wide.js
/**
* WordPress dependencies
*/
const stretchWide = (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.SVG, {
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 24 24"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.Path, {
d: "M16 5.5H8V4h8v1.5ZM16 20H8v-1.5h8V20ZM5 9h14v6H5V9Z"
}));
/* harmony default export */ var stretch_wide = (stretchWide);
;// CONCATENATED MODULE: external ["wp","styleEngine"]
var external_wp_styleEngine_namespaceObject = window["wp"]["styleEngine"];
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/layouts/constrained.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
/* harmony default export */ var constrained = ({
name: 'constrained',
label: (0,external_wp_i18n_namespaceObject.__)('Constrained'),
inspectorControls: function DefaultLayoutInspectorControls({
layout,
onChange,
layoutBlockSupport = {}
}) {
const {
wideSize,
contentSize,
justifyContent = 'center'
} = layout;
const {
allowJustification = true
} = layoutBlockSupport;
const onJustificationChange = value => {
onChange({
...layout,
justifyContent: value
});
};
const justificationOptions = [{
value: 'left',
icon: justify_left,
label: (0,external_wp_i18n_namespaceObject.__)('Justify items left')
}, {
value: 'center',
icon: justify_center,
label: (0,external_wp_i18n_namespaceObject.__)('Justify items center')
}, {
value: 'right',
icon: justify_right,
label: (0,external_wp_i18n_namespaceObject.__)('Justify items right')
}];
const units = (0,external_wp_components_namespaceObject.__experimentalUseCustomUnits)({
availableUnits: use_setting_useSetting('spacing.units') || ['%', 'px', 'em', 'rem', 'vw']
});
return (0,external_wp_element_namespaceObject.createElement)(external_wp_element_namespaceObject.Fragment, null, (0,external_wp_element_namespaceObject.createElement)("div", {
className: "block-editor-hooks__layout-controls"
}, (0,external_wp_element_namespaceObject.createElement)("div", {
className: "block-editor-hooks__layout-controls-unit"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__experimentalUnitControl, {
className: "block-editor-hooks__layout-controls-unit-input",
label: (0,external_wp_i18n_namespaceObject.__)('Content'),
labelPosition: "top",
__unstableInputWidth: "80px",
value: contentSize || wideSize || '',
onChange: nextWidth => {
nextWidth = 0 > parseFloat(nextWidth) ? '0' : nextWidth;
onChange({
...layout,
contentSize: nextWidth
});
},
units: units
}), (0,external_wp_element_namespaceObject.createElement)(build_module_icon, {
icon: position_center
})), (0,external_wp_element_namespaceObject.createElement)("div", {
className: "block-editor-hooks__layout-controls-unit"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__experimentalUnitControl, {
className: "block-editor-hooks__layout-controls-unit-input",
label: (0,external_wp_i18n_namespaceObject.__)('Wide'),
labelPosition: "top",
__unstableInputWidth: "80px",
value: wideSize || contentSize || '',
onChange: nextWidth => {
nextWidth = 0 > parseFloat(nextWidth) ? '0' : nextWidth;
onChange({
...layout,
wideSize: nextWidth
});
},
units: units
}), (0,external_wp_element_namespaceObject.createElement)(build_module_icon, {
icon: stretch_wide
}))), (0,external_wp_element_namespaceObject.createElement)("p", {
className: "block-editor-hooks__layout-controls-helptext"
}, (0,external_wp_i18n_namespaceObject.__)('Customize the width for all elements that are assigned to the center or wide columns.')), allowJustification && (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__experimentalToggleGroupControl, {
__nextHasNoMarginBottom: true,
label: (0,external_wp_i18n_namespaceObject.__)('Justification'),
value: justifyContent,
onChange: onJustificationChange
}, justificationOptions.map(({
value,
icon,
label
}) => {
return (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__experimentalToggleGroupControlOptionIcon, {
key: value,
value: value,
icon: icon,
label: label
});
})));
},
toolBarControls: function DefaultLayoutToolbarControls() {
return null;
},
getLayoutStyle: function getLayoutStyle({
selector,
layout = {},
style,
blockName,
hasBlockGapSupport,
layoutDefinitions = LAYOUT_DEFINITIONS
}) {
const {
contentSize,
wideSize,
justifyContent
} = layout;
const blockGapStyleValue = getGapCSSValue(style?.spacing?.blockGap);
// If a block's block.json skips serialization for spacing or
// spacing.blockGap, don't apply the user-defined value to the styles.
let blockGapValue = '';
if (!shouldSkipSerialization(blockName, 'spacing', 'blockGap')) {
// If an object is provided only use the 'top' value for this kind of gap.
if (blockGapStyleValue?.top) {
blockGapValue = getGapCSSValue(blockGapStyleValue?.top);
} else if (typeof blockGapStyleValue === 'string') {
blockGapValue = getGapCSSValue(blockGapStyleValue);
}
}
const marginLeft = justifyContent === 'left' ? '0 !important' : 'auto !important';
const marginRight = justifyContent === 'right' ? '0 !important' : 'auto !important';
let output = !!contentSize || !!wideSize ? `
${appendSelectors(selector, '> :where(:not(.alignleft):not(.alignright):not(.alignfull))')} {
max-width: ${contentSize !== null && contentSize !== void 0 ? contentSize : wideSize};
margin-left: ${marginLeft};
margin-right: ${marginRight};
}
${appendSelectors(selector, '> .alignwide')} {
max-width: ${wideSize !== null && wideSize !== void 0 ? wideSize : contentSize};
}
${appendSelectors(selector, '> .alignfull')} {
max-width: none;
}
` : '';
if (justifyContent === 'left') {
output += `${appendSelectors(selector, '> :where(:not(.alignleft):not(.alignright):not(.alignfull))')}
{ margin-left: ${marginLeft}; }`;
} else if (justifyContent === 'right') {
output += `${appendSelectors(selector, '> :where(:not(.alignleft):not(.alignright):not(.alignfull))')}
{ margin-right: ${marginRight}; }`;
}
// If there is custom padding, add negative margins for alignfull blocks.
if (style?.spacing?.padding) {
// The style object might be storing a preset so we need to make sure we get a usable value.
const paddingValues = (0,external_wp_styleEngine_namespaceObject.getCSSRules)(style);
paddingValues.forEach(rule => {
if (rule.key === 'paddingRight') {
output += `
${appendSelectors(selector, '> .alignfull')} {
margin-right: calc(${rule.value} * -1);
}
`;
} else if (rule.key === 'paddingLeft') {
output += `
${appendSelectors(selector, '> .alignfull')} {
margin-left: calc(${rule.value} * -1);
}
`;
}
});
}
// Output blockGap styles based on rules contained in layout definitions in theme.json.
if (hasBlockGapSupport && blockGapValue) {
output += getBlockGapCSS(selector, layoutDefinitions, 'constrained', blockGapValue);
}
return output;
},
getOrientation() {
return 'vertical';
},
getAlignments(layout) {
const alignmentInfo = getAlignmentsInfo(layout);
if (layout.alignments !== undefined) {
if (!layout.alignments.includes('none')) {
layout.alignments.unshift('none');
}
return layout.alignments.map(alignment => ({
name: alignment,
info: alignmentInfo[alignment]
}));
}
const {
contentSize,
wideSize
} = layout;
const alignments = [{
name: 'left'
}, {
name: 'center'
}, {
name: 'right'
}];
if (contentSize) {
alignments.unshift({
name: 'full'
});
}
if (wideSize) {
alignments.unshift({
name: 'wide',
info: alignmentInfo.wide
});
}
alignments.unshift({
name: 'none',
info: alignmentInfo.none
});
return alignments;
}
});
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/layouts/grid.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const RANGE_CONTROL_MAX_VALUES = {
px: 600,
'%': 100,
vw: 100,
vh: 100,
em: 38,
rem: 38
};
/* harmony default export */ var grid = ({
name: 'grid',
label: (0,external_wp_i18n_namespaceObject.__)('Grid'),
inspectorControls: function GridLayoutInspectorControls({
layout = {},
onChange
}) {
return layout?.columnCount ? (0,external_wp_element_namespaceObject.createElement)(GridLayoutColumnsControl, {
layout: layout,
onChange: onChange
}) : (0,external_wp_element_namespaceObject.createElement)(GridLayoutMinimumWidthControl, {
layout: layout,
onChange: onChange
});
},
toolBarControls: function DefaultLayoutToolbarControls() {
return null;
},
getLayoutStyle: function getLayoutStyle({
selector,
layout,
style,
blockName,
hasBlockGapSupport,
layoutDefinitions = LAYOUT_DEFINITIONS
}) {
const {
minimumColumnWidth = '12rem',
columnCount = null
} = layout;
// If a block's block.json skips serialization for spacing or spacing.blockGap,
// don't apply the user-defined value to the styles.
const blockGapValue = style?.spacing?.blockGap && !shouldSkipSerialization(blockName, 'spacing', 'blockGap') ? getGapCSSValue(style?.spacing?.blockGap, '0.5em') : undefined;
let output = '';
const rules = [];
if (columnCount) {
rules.push(`grid-template-columns: repeat(${columnCount}, minmax(0, 1fr))`);
} else if (minimumColumnWidth) {
rules.push(`grid-template-columns: repeat(auto-fill, minmax(min(${minimumColumnWidth}, 100%), 1fr))`);
}
if (rules.length) {
// Reason to disable: the extra line breaks added by prettier mess with the unit tests.
// eslint-disable-next-line prettier/prettier
output = `${appendSelectors(selector)} { ${rules.join('; ')}; }`;
}
// Output blockGap styles based on rules contained in layout definitions in theme.json.
if (hasBlockGapSupport && blockGapValue) {
output += getBlockGapCSS(selector, layoutDefinitions, 'grid', blockGapValue);
}
return output;
},
getOrientation() {
return 'horizontal';
},
getAlignments() {
return [];
}
});
// Enables setting minimum width of grid items.
function GridLayoutMinimumWidthControl({
layout,
onChange
}) {
const {
minimumColumnWidth: value = '12rem'
} = layout;
const [quantity, unit] = (0,external_wp_components_namespaceObject.__experimentalParseQuantityAndUnitFromRawValue)(value);
const handleSliderChange = next => {
onChange({
...layout,
minimumColumnWidth: [next, unit].join('')
});
};
// Mostly copied from HeightControl.
const handleUnitChange = newUnit => {
// Attempt to smooth over differences between currentUnit and newUnit.
// This should slightly improve the experience of switching between unit types.
let newValue;
if (['em', 'rem'].includes(newUnit) && unit === 'px') {
// Convert pixel value to an approximate of the new unit, assuming a root size of 16px.
newValue = (quantity / 16).toFixed(2) + newUnit;
} else if (['em', 'rem'].includes(unit) && newUnit === 'px') {
// Convert to pixel value assuming a root size of 16px.
newValue = Math.round(quantity * 16) + newUnit;
} else if (['vh', 'vw', '%'].includes(newUnit) && quantity > 100) {
// When converting to `vh`, `vw`, or `%` units, cap the new value at 100.
newValue = 100 + newUnit;
}
onChange({
...layout,
minimumColumnWidth: newValue
});
};
return (0,external_wp_element_namespaceObject.createElement)("fieldset", null, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.BaseControl.VisualLabel, {
as: "legend"
}, (0,external_wp_i18n_namespaceObject.__)('Minimum column width')), (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.Flex, {
gap: 4
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.FlexItem, {
isBlock: true
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__experimentalUnitControl, {
size: '__unstable-large',
onChange: newValue => {
onChange({
...layout,
minimumColumnWidth: newValue
});
},
onUnitChange: handleUnitChange,
value: value,
min: 0
})), (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.FlexItem, {
isBlock: true
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.RangeControl, {
onChange: handleSliderChange,
value: quantity,
min: 0,
max: RANGE_CONTROL_MAX_VALUES[unit] || 600,
withInputField: false
}))));
}
// Enables setting number of grid columns
function GridLayoutColumnsControl({
layout,
onChange
}) {
const {
columnCount = 3
} = layout;
return (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.RangeControl, {
label: (0,external_wp_i18n_namespaceObject.__)('Columns'),
value: columnCount,
onChange: value => onChange({
...layout,
columnCount: value
}),
min: 1,
max: 6
});
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/layouts/index.js
/**
* Internal dependencies
*/
const layoutTypes = [flow, flex, constrained, grid];
/**
* Retrieves a layout type by name.
*
* @param {string} name - The name of the layout type.
* @return {Object} Layout type.
*/
function getLayoutType(name = 'default') {
return layoutTypes.find(layoutType => layoutType.name === name);
}
/**
* Retrieves the available layout types.
*
* @return {Array} Layout types.
*/
function getLayoutTypes() {
return layoutTypes;
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-list/layout.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const defaultLayout = {
type: 'default'
};
const Layout = (0,external_wp_element_namespaceObject.createContext)(defaultLayout);
/**
* Allows to define the layout.
*/
const LayoutProvider = Layout.Provider;
/**
* React hook used to retrieve the layout config.
*/
function useLayout() {
return (0,external_wp_element_namespaceObject.useContext)(Layout);
}
function LayoutStyle({
layout = {},
css,
...props
}) {
const layoutType = getLayoutType(layout.type);
const blockGapSupport = use_setting_useSetting('spacing.blockGap');
const hasBlockGapSupport = blockGapSupport !== null;
if (layoutType) {
if (css) {
return (0,external_wp_element_namespaceObject.createElement)("style", null, css);
}
const layoutStyle = layoutType.getLayoutStyle?.({
hasBlockGapSupport,
layout,
...props
});
if (layoutStyle) {
return (0,external_wp_element_namespaceObject.createElement)("style", null, layoutStyle);
}
}
return null;
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-alignment-control/use-available-alignments.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const use_available_alignments_EMPTY_ARRAY = [];
const use_available_alignments_DEFAULT_CONTROLS = ['none', 'left', 'center', 'right', 'wide', 'full'];
const WIDE_CONTROLS = ['wide', 'full'];
function useAvailableAlignments(controls = use_available_alignments_DEFAULT_CONTROLS) {
// Always add the `none` option if not exists.
if (!controls.includes('none')) {
controls = ['none', ...controls];
}
const {
wideControlsEnabled = false,
themeSupportsLayout,
isBlockBasedTheme
} = (0,external_wp_data_namespaceObject.useSelect)(select => {
const {
getSettings
} = select(store);
const settings = getSettings();
return {
wideControlsEnabled: settings.alignWide,
themeSupportsLayout: settings.supportsLayout,
isBlockBasedTheme: settings.__unstableIsBlockBasedTheme
};
}, []);
const layout = useLayout();
const layoutType = getLayoutType(layout?.type);
const layoutAlignments = layoutType.getAlignments(layout, isBlockBasedTheme);
if (themeSupportsLayout) {
const alignments = layoutAlignments.filter(({
name: alignmentName
}) => controls.includes(alignmentName));
// While we treat `none` as an alignment, we shouldn't return it if no
// other alignments exist.
if (alignments.length === 1 && alignments[0].name === 'none') {
return use_available_alignments_EMPTY_ARRAY;
}
return alignments;
}
// Starting here, it's the fallback for themes not supporting the layout config.
if (layoutType.name !== 'default' && layoutType.name !== 'constrained') {
return use_available_alignments_EMPTY_ARRAY;
}
const {
alignments: availableAlignments = use_available_alignments_DEFAULT_CONTROLS
} = layout;
const enabledControls = controls.filter(control => (layout.alignments ||
// Ignore the global wideAlignment check if the layout explicitely defines alignments.
wideControlsEnabled || !WIDE_CONTROLS.includes(control)) && availableAlignments.includes(control)).map(enabledControl => ({
name: enabledControl
}));
// While we treat `none` as an alignment, we shouldn't return it if no
// other alignments exist.
if (enabledControls.length === 1 && enabledControls[0].name === 'none') {
return use_available_alignments_EMPTY_ARRAY;
}
return enabledControls;
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/align-none.js
/**
* WordPress dependencies
*/
const alignNone = (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.SVG, {
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 24 24"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.Path, {
d: "M19 5.5H5V4h14v1.5ZM19 20H5v-1.5h14V20ZM5 9h14v6H5V9Z"
}));
/* harmony default export */ var align_none = (alignNone);
;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/position-left.js
/**
* WordPress dependencies
*/
const positionLeft = (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.SVG, {
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 24 24"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.Path, {
d: "M5 5.5h8V4H5v1.5ZM5 20h8v-1.5H5V20ZM19 9H5v6h14V9Z"
}));
/* harmony default export */ var position_left = (positionLeft);
;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/position-right.js
/**
* WordPress dependencies
*/
const positionRight = (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.SVG, {
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 24 24"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.Path, {
d: "M19 5.5h-8V4h8v1.5ZM19 20h-8v-1.5h8V20ZM5 9h14v6H5V9Z"
}));
/* harmony default export */ var position_right = (positionRight);
;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/stretch-full-width.js
/**
* WordPress dependencies
*/
const stretchFullWidth = (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.SVG, {
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 24 24"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.Path, {
d: "M5 4h14v11H5V4Zm11 16H8v-1.5h8V20Z"
}));
/* harmony default export */ var stretch_full_width = (stretchFullWidth);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-alignment-control/constants.js
/**
* WordPress dependencies
*/
const constants_BLOCK_ALIGNMENTS_CONTROLS = {
none: {
icon: align_none,
title: (0,external_wp_i18n_namespaceObject._x)('None', 'Alignment option')
},
left: {
icon: position_left,
title: (0,external_wp_i18n_namespaceObject.__)('Align left')
},
center: {
icon: position_center,
title: (0,external_wp_i18n_namespaceObject.__)('Align center')
},
right: {
icon: position_right,
title: (0,external_wp_i18n_namespaceObject.__)('Align right')
},
wide: {
icon: stretch_wide,
title: (0,external_wp_i18n_namespaceObject.__)('Wide width')
},
full: {
icon: stretch_full_width,
title: (0,external_wp_i18n_namespaceObject.__)('Full width')
}
};
const constants_DEFAULT_CONTROL = 'none';
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-alignment-control/ui.js
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
function BlockAlignmentUI({
value,
onChange,
controls,
isToolbar,
isCollapsed = true
}) {
const enabledControls = useAvailableAlignments(controls);
const hasEnabledControls = !!enabledControls.length;
if (!hasEnabledControls) {
return null;
}
function onChangeAlignment(align) {
onChange([value, 'none'].includes(align) ? undefined : align);
}
const activeAlignmentControl = constants_BLOCK_ALIGNMENTS_CONTROLS[value];
const defaultAlignmentControl = constants_BLOCK_ALIGNMENTS_CONTROLS[constants_DEFAULT_CONTROL];
const UIComponent = isToolbar ? external_wp_components_namespaceObject.ToolbarGroup : external_wp_components_namespaceObject.ToolbarDropdownMenu;
const commonProps = {
icon: activeAlignmentControl ? activeAlignmentControl.icon : defaultAlignmentControl.icon,
label: (0,external_wp_i18n_namespaceObject.__)('Align')
};
const extraProps = isToolbar ? {
isCollapsed,
controls: enabledControls.map(({
name: controlName
}) => {
return {
...constants_BLOCK_ALIGNMENTS_CONTROLS[controlName],
isActive: value === controlName || !value && controlName === 'none',
role: isCollapsed ? 'menuitemradio' : undefined,
onClick: () => onChangeAlignment(controlName)
};
})
} : {
toggleProps: {
describedBy: (0,external_wp_i18n_namespaceObject.__)('Change alignment')
},
children: ({
onClose
}) => {
return (0,external_wp_element_namespaceObject.createElement)(external_wp_element_namespaceObject.Fragment, null, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.MenuGroup, {
className: "block-editor-block-alignment-control__menu-group"
}, enabledControls.map(({
name: controlName,
info
}) => {
const {
icon,
title
} = constants_BLOCK_ALIGNMENTS_CONTROLS[controlName];
// If no value is provided, mark as selected the `none` option.
const isSelected = controlName === value || !value && controlName === 'none';
return (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.MenuItem, {
key: controlName,
icon: icon,
iconPosition: "left",
className: classnames_default()('components-dropdown-menu__menu-item', {
'is-active': isSelected
}),
isSelected: isSelected,
onClick: () => {
onChangeAlignment(controlName);
onClose();
},
role: "menuitemradio",
info: info
}, title);
})));
}
};
return (0,external_wp_element_namespaceObject.createElement)(UIComponent, {
...commonProps,
...extraProps
});
}
/* harmony default export */ var block_alignment_control_ui = (BlockAlignmentUI);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-alignment-control/index.js
/**
* Internal dependencies
*/
const BlockAlignmentControl = props => {
return (0,external_wp_element_namespaceObject.createElement)(block_alignment_control_ui, {
...props,
isToolbar: false
});
};
const BlockAlignmentToolbar = props => {
return (0,external_wp_element_namespaceObject.createElement)(block_alignment_control_ui, {
...props,
isToolbar: true
});
};
/**
* @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/block-alignment-control/README.md
*/
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-list/block-list-block-context.js
/**
* WordPress dependencies
*/
const BlockListBlockContext = (0,external_wp_element_namespaceObject.createContext)(null);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-editing-mode/index.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
/**
* @typedef {'disabled'|'contentOnly'|'default'} BlockEditingMode
*/
/**
* Allows a block to restrict the user interface that is displayed for editing
* that block and its inner blocks.
*
* @example
* ```js
* function MyBlock( { attributes, setAttributes } ) {
* useBlockEditingMode( 'disabled' );
* return ;
* }
* ```
*
* `mode` can be one of three options:
*
* - `'disabled'`: Prevents editing the block entirely, i.e. it cannot be
* selected.
* - `'contentOnly'`: Hides all non-content UI, e.g. auxiliary controls in the
* toolbar, the block movers, block settings.
* - `'default'`: Allows editing the block as normal.
*
* The mode is inherited by all of the block's inner blocks, unless they have
* their own mode.
*
* If called outside of a block context, the mode is applied to all blocks.
*
* @param {?BlockEditingMode} mode The editing mode to apply. If undefined, the
* current editing mode is not changed.
*
* @return {BlockEditingMode} The current editing mode.
*/
function useBlockEditingMode(mode) {
var _useContext;
const {
clientId = ''
} = (_useContext = (0,external_wp_element_namespaceObject.useContext)(BlockListBlockContext)) !== null && _useContext !== void 0 ? _useContext : {};
const blockEditingMode = (0,external_wp_data_namespaceObject.useSelect)(select => select(store).getBlockEditingMode(clientId), [clientId]);
const {
setBlockEditingMode,
unsetBlockEditingMode
} = (0,external_wp_data_namespaceObject.useDispatch)(store);
(0,external_wp_element_namespaceObject.useEffect)(() => {
if (mode) {
setBlockEditingMode(clientId, mode);
}
return () => {
if (mode) {
unsetBlockEditingMode(clientId);
}
};
}, [clientId, mode, setBlockEditingMode, unsetBlockEditingMode]);
return blockEditingMode;
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/hooks/align.js
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
/**
* An array which includes all possible valid alignments,
* used to validate if an alignment is valid or not.
*
* @constant
* @type {string[]}
*/
const ALL_ALIGNMENTS = ['left', 'center', 'right', 'wide', 'full'];
/**
* An array which includes all wide alignments.
* In order for this alignments to be valid they need to be supported by the block,
* and by the theme.
*
* @constant
* @type {string[]}
*/
const WIDE_ALIGNMENTS = ['wide', 'full'];
/**
* Returns the valid alignments.
* Takes into consideration the aligns supported by a block, if the block supports wide controls or not and if theme supports wide controls or not.
* Exported just for testing purposes, not exported outside the module.
*
* @param {?boolean|string[]} blockAlign Aligns supported by the block.
* @param {?boolean} hasWideBlockSupport True if block supports wide alignments. And False otherwise.
* @param {?boolean} hasWideEnabled True if theme supports wide alignments. And False otherwise.
*
* @return {string[]} Valid alignments.
*/
function getValidAlignments(blockAlign, hasWideBlockSupport = true, hasWideEnabled = true) {
let validAlignments;
if (Array.isArray(blockAlign)) {
validAlignments = ALL_ALIGNMENTS.filter(value => blockAlign.includes(value));
} else if (blockAlign === true) {
// `true` includes all alignments...
validAlignments = [...ALL_ALIGNMENTS];
} else {
validAlignments = [];
}
if (!hasWideEnabled || blockAlign === true && !hasWideBlockSupport) {
return validAlignments.filter(alignment => !WIDE_ALIGNMENTS.includes(alignment));
}
return validAlignments;
}
/**
* Filters registered block settings, extending attributes to include `align`.
*
* @param {Object} settings Original block settings.
*
* @return {Object} Filtered block settings.
*/
function addAttribute(settings) {
var _settings$attributes$;
// Allow blocks to specify their own attribute definition with default values if needed.
if ('type' in ((_settings$attributes$ = settings.attributes?.align) !== null && _settings$attributes$ !== void 0 ? _settings$attributes$ : {})) {
return settings;
}
if ((0,external_wp_blocks_namespaceObject.hasBlockSupport)(settings, 'align')) {
// Gracefully handle if settings.attributes is undefined.
settings.attributes = {
...settings.attributes,
align: {
type: 'string',
// Allow for '' since it is used by updateAlignment function
// in withToolbarControls for special cases with defined default values.
enum: [...ALL_ALIGNMENTS, '']
}
};
}
return settings;
}
/**
* Override the default edit UI to include new toolbar controls for block
* alignment, if block defines support.
*
* @param {Function} BlockEdit Original component.
*
* @return {Function} Wrapped component.
*/
const withToolbarControls = (0,external_wp_compose_namespaceObject.createHigherOrderComponent)(BlockEdit => props => {
const blockEdit = (0,external_wp_element_namespaceObject.createElement)(BlockEdit, {
key: "edit",
...props
});
const {
name: blockName
} = props;
// Compute the block valid alignments by taking into account,
// if the theme supports wide alignments or not and the layout's
// availble alignments. We do that for conditionally rendering
// Slot.
const blockAllowedAlignments = getValidAlignments((0,external_wp_blocks_namespaceObject.getBlockSupport)(blockName, 'align'), (0,external_wp_blocks_namespaceObject.hasBlockSupport)(blockName, 'alignWide', true));
const validAlignments = useAvailableAlignments(blockAllowedAlignments).map(({
name
}) => name);
const blockEditingMode = useBlockEditingMode();
if (!validAlignments.length || blockEditingMode !== 'default') {
return blockEdit;
}
const updateAlignment = nextAlign => {
if (!nextAlign) {
const blockType = (0,external_wp_blocks_namespaceObject.getBlockType)(props.name);
const blockDefaultAlign = blockType?.attributes?.align?.default;
if (blockDefaultAlign) {
nextAlign = '';
}
}
props.setAttributes({
align: nextAlign
});
};
return (0,external_wp_element_namespaceObject.createElement)(external_wp_element_namespaceObject.Fragment, null, (0,external_wp_element_namespaceObject.createElement)(block_controls, {
group: "block",
__experimentalShareWithChildBlocks: true
}, (0,external_wp_element_namespaceObject.createElement)(BlockAlignmentControl, {
value: props.attributes.align,
onChange: updateAlignment,
controls: validAlignments
})), blockEdit);
}, 'withToolbarControls');
/**
* Override the default block element to add alignment wrapper props.
*
* @param {Function} BlockListBlock Original component.
*
* @return {Function} Wrapped component.
*/
const withDataAlign = (0,external_wp_compose_namespaceObject.createHigherOrderComponent)(BlockListBlock => props => {
const {
name,
attributes
} = props;
const {
align
} = attributes;
const blockAllowedAlignments = getValidAlignments((0,external_wp_blocks_namespaceObject.getBlockSupport)(name, 'align'), (0,external_wp_blocks_namespaceObject.hasBlockSupport)(name, 'alignWide', true));
const validAlignments = useAvailableAlignments(blockAllowedAlignments);
// If an alignment is not assigned, there's no need to go through the
// effort to validate or assign its value.
if (align === undefined) {
return (0,external_wp_element_namespaceObject.createElement)(BlockListBlock, {
...props
});
}
let wrapperProps = props.wrapperProps;
if (validAlignments.some(alignment => alignment.name === align)) {
wrapperProps = {
...wrapperProps,
'data-align': align
};
}
return (0,external_wp_element_namespaceObject.createElement)(BlockListBlock, {
...props,
wrapperProps: wrapperProps
});
}, 'withDataAlign');
/**
* Override props assigned to save component to inject alignment class name if
* block supports it.
*
* @param {Object} props Additional props applied to save element.
* @param {Object} blockType Block type.
* @param {Object} attributes Block attributes.
*
* @return {Object} Filtered props applied to save element.
*/
function addAssignedAlign(props, blockType, attributes) {
const {
align
} = attributes;
const blockAlign = (0,external_wp_blocks_namespaceObject.getBlockSupport)(blockType, 'align');
const hasWideBlockSupport = (0,external_wp_blocks_namespaceObject.hasBlockSupport)(blockType, 'alignWide', true);
// Compute valid alignments without taking into account if
// the theme supports wide alignments or not.
// This way changing themes does not impact the block save.
const isAlignValid = getValidAlignments(blockAlign, hasWideBlockSupport).includes(align);
if (isAlignValid) {
props.className = classnames_default()(`align${align}`, props.className);
}
return props;
}
(0,external_wp_hooks_namespaceObject.addFilter)('blocks.registerBlockType', 'core/align/addAttribute', addAttribute);
(0,external_wp_hooks_namespaceObject.addFilter)('editor.BlockListBlock', 'core/editor/align/with-data-align', withDataAlign);
(0,external_wp_hooks_namespaceObject.addFilter)('editor.BlockEdit', 'core/editor/align/with-toolbar-controls', withToolbarControls);
(0,external_wp_hooks_namespaceObject.addFilter)('blocks.getSaveContent.extraProps', 'core/align/addAssignedAlign', addAssignedAlign);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/hooks/lock.js
/**
* WordPress dependencies
*/
/**
* Filters registered block settings, extending attributes to include `lock`.
*
* @param {Object} settings Original block settings.
*
* @return {Object} Filtered block settings.
*/
function lock_addAttribute(settings) {
var _settings$attributes$;
// Allow blocks to specify their own attribute definition with default values if needed.
if ('type' in ((_settings$attributes$ = settings.attributes?.lock) !== null && _settings$attributes$ !== void 0 ? _settings$attributes$ : {})) {
return settings;
}
// Gracefully handle if settings.attributes is undefined.
settings.attributes = {
...settings.attributes,
lock: {
type: 'object'
}
};
return settings;
}
(0,external_wp_hooks_namespaceObject.addFilter)('blocks.registerBlockType', 'core/lock/addAttribute', lock_addAttribute);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inspector-controls/groups.js
/**
* WordPress dependencies
*/
const InspectorControlsDefault = (0,external_wp_components_namespaceObject.createSlotFill)('InspectorControls');
const InspectorControlsAdvanced = (0,external_wp_components_namespaceObject.createSlotFill)('InspectorAdvancedControls');
const InspectorControlsBackground = (0,external_wp_components_namespaceObject.createSlotFill)('InspectorControlsBackground');
const InspectorControlsBorder = (0,external_wp_components_namespaceObject.createSlotFill)('InspectorControlsBorder');
const InspectorControlsColor = (0,external_wp_components_namespaceObject.createSlotFill)('InspectorControlsColor');
const InspectorControlsFilter = (0,external_wp_components_namespaceObject.createSlotFill)('InspectorControlsFilter');
const InspectorControlsDimensions = (0,external_wp_components_namespaceObject.createSlotFill)('InspectorControlsDimensions');
const InspectorControlsPosition = (0,external_wp_components_namespaceObject.createSlotFill)('InspectorControlsPosition');
const InspectorControlsTypography = (0,external_wp_components_namespaceObject.createSlotFill)('InspectorControlsTypography');
const InspectorControlsListView = (0,external_wp_components_namespaceObject.createSlotFill)('InspectorControlsListView');
const InspectorControlsStyles = (0,external_wp_components_namespaceObject.createSlotFill)('InspectorControlsStyles');
const groups_groups = {
default: InspectorControlsDefault,
advanced: InspectorControlsAdvanced,
background: InspectorControlsBackground,
border: InspectorControlsBorder,
color: InspectorControlsColor,
dimensions: InspectorControlsDimensions,
filter: InspectorControlsFilter,
list: InspectorControlsListView,
position: InspectorControlsPosition,
settings: InspectorControlsDefault,
// Alias for default.
styles: InspectorControlsStyles,
typography: InspectorControlsTypography
};
/* harmony default export */ var inspector_controls_groups = (groups_groups);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inspector-controls/fill.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
function InspectorControlsFill({
children,
group = 'default',
__experimentalGroup,
resetAllFilter
}) {
if (__experimentalGroup) {
external_wp_deprecated_default()('`__experimentalGroup` property in `InspectorControlsFill`', {
since: '6.2',
version: '6.4',
alternative: '`group`'
});
group = __experimentalGroup;
}
const isDisplayed = useDisplayBlockControls();
const Fill = inspector_controls_groups[group]?.Fill;
if (!Fill) {
true ? external_wp_warning_default()(`Unknown InspectorControls group "${group}" provided.`) : 0;
return null;
}
if (!isDisplayed) {
return null;
}
return (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__experimentalStyleProvider, {
document: document
}, (0,external_wp_element_namespaceObject.createElement)(Fill, null, fillProps => {
return (0,external_wp_element_namespaceObject.createElement)(ToolsPanelInspectorControl, {
fillProps: fillProps,
children: children,
resetAllFilter: resetAllFilter
});
}));
}
function RegisterResetAll({
resetAllFilter,
children
}) {
const {
registerResetAllFilter,
deregisterResetAllFilter
} = (0,external_wp_element_namespaceObject.useContext)(external_wp_components_namespaceObject.__experimentalToolsPanelContext);
(0,external_wp_element_namespaceObject.useEffect)(() => {
if (resetAllFilter && registerResetAllFilter && deregisterResetAllFilter) {
registerResetAllFilter(resetAllFilter);
return () => {
deregisterResetAllFilter(resetAllFilter);
};
}
}, [resetAllFilter, registerResetAllFilter, deregisterResetAllFilter]);
return children;
}
function ToolsPanelInspectorControl({
children,
resetAllFilter,
fillProps
}) {
// `fillProps.forwardedContext` is an array of context provider entries, provided by slot,
// that should wrap the fill markup.
const {
forwardedContext = []
} = fillProps;
// Children passed to InspectorControlsFill will not have
// access to any React Context whose Provider is part of
// the InspectorControlsSlot tree. So we re-create the
// Provider in this subtree.
const innerMarkup = (0,external_wp_element_namespaceObject.createElement)(RegisterResetAll, {
resetAllFilter: resetAllFilter
}, children);
return forwardedContext.reduce((inner, [Provider, props]) => (0,external_wp_element_namespaceObject.createElement)(Provider, {
...props
}, inner), innerMarkup);
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inspector-controls/block-support-tools-panel.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
function BlockSupportToolsPanel({
children,
group,
label
}) {
const {
updateBlockAttributes
} = (0,external_wp_data_namespaceObject.useDispatch)(store);
const {
getBlockAttributes,
getMultiSelectedBlockClientIds,
getSelectedBlockClientId,
hasMultiSelection
} = (0,external_wp_data_namespaceObject.useSelect)(store);
const panelId = getSelectedBlockClientId();
const resetAll = (0,external_wp_element_namespaceObject.useCallback)((resetFilters = []) => {
const newAttributes = {};
const clientIds = hasMultiSelection() ? getMultiSelectedBlockClientIds() : [panelId];
clientIds.forEach(clientId => {
const {
style
} = getBlockAttributes(clientId);
let newBlockAttributes = {
style
};
resetFilters.forEach(resetFilter => {
newBlockAttributes = {
...newBlockAttributes,
...resetFilter(newBlockAttributes)
};
});
// Enforce a cleaned style object.
newBlockAttributes = {
...newBlockAttributes,
style: utils_cleanEmptyObject(newBlockAttributes.style)
};
newAttributes[clientId] = newBlockAttributes;
});
updateBlockAttributes(clientIds, newAttributes, true);
}, [getBlockAttributes, getMultiSelectedBlockClientIds, hasMultiSelection, panelId, updateBlockAttributes]);
return (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__experimentalToolsPanel, {
className: `${group}-block-support-panel`,
label: label,
resetAll: resetAll,
key: panelId,
panelId: panelId,
hasInnerWrapper: true,
shouldRenderPlaceholderItems: true // Required to maintain fills ordering.
,
__experimentalFirstVisibleItemClass: "first",
__experimentalLastVisibleItemClass: "last"
}, children);
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inspector-controls/block-support-slot-container.js
/**
* WordPress dependencies
*/
function BlockSupportSlotContainer({
Slot,
fillProps,
...props
}) {
// Add the toolspanel context provider and value to existing fill props
const toolsPanelContext = (0,external_wp_element_namespaceObject.useContext)(external_wp_components_namespaceObject.__experimentalToolsPanelContext);
const computedFillProps = (0,external_wp_element_namespaceObject.useMemo)(() => {
var _fillProps$forwardedC;
return {
...(fillProps !== null && fillProps !== void 0 ? fillProps : {}),
forwardedContext: [...((_fillProps$forwardedC = fillProps?.forwardedContext) !== null && _fillProps$forwardedC !== void 0 ? _fillProps$forwardedC : []), [external_wp_components_namespaceObject.__experimentalToolsPanelContext.Provider, {
value: toolsPanelContext
}]]
};
}, [toolsPanelContext, fillProps]);
return (0,external_wp_element_namespaceObject.createElement)(Slot, {
...props,
fillProps: computedFillProps,
bubblesVirtually: true
});
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inspector-controls/slot.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
function InspectorControlsSlot({
__experimentalGroup,
group = 'default',
label,
fillProps,
...props
}) {
if (__experimentalGroup) {
external_wp_deprecated_default()('`__experimentalGroup` property in `InspectorControlsSlot`', {
since: '6.2',
version: '6.4',
alternative: '`group`'
});
group = __experimentalGroup;
}
const Slot = inspector_controls_groups[group]?.Slot;
const fills = (0,external_wp_components_namespaceObject.__experimentalUseSlotFills)(Slot?.__unstableName);
const motionContextValue = (0,external_wp_element_namespaceObject.useContext)(external_wp_components_namespaceObject.__unstableMotionContext);
const computedFillProps = (0,external_wp_element_namespaceObject.useMemo)(() => {
var _fillProps$forwardedC;
return {
...(fillProps !== null && fillProps !== void 0 ? fillProps : {}),
forwardedContext: [...((_fillProps$forwardedC = fillProps?.forwardedContext) !== null && _fillProps$forwardedC !== void 0 ? _fillProps$forwardedC : []), [external_wp_components_namespaceObject.__unstableMotionContext.Provider, {
value: motionContextValue
}]]
};
}, [motionContextValue, fillProps]);
if (!Slot) {
true ? external_wp_warning_default()(`Unknown InspectorControls group "${group}" provided.`) : 0;
return null;
}
if (!fills?.length) {
return null;
}
if (label) {
return (0,external_wp_element_namespaceObject.createElement)(BlockSupportToolsPanel, {
group: group,
label: label
}, (0,external_wp_element_namespaceObject.createElement)(BlockSupportSlotContainer, {
...props,
fillProps: computedFillProps,
Slot: Slot
}));
}
return (0,external_wp_element_namespaceObject.createElement)(Slot, {
...props,
fillProps: computedFillProps,
bubblesVirtually: true
});
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inspector-controls/index.js
/**
* Internal dependencies
*/
const InspectorControls = InspectorControlsFill;
InspectorControls.Slot = InspectorControlsSlot;
// This is just here for backward compatibility.
const InspectorAdvancedControls = props => {
return (0,external_wp_element_namespaceObject.createElement)(InspectorControlsFill, {
...props,
group: "advanced"
});
};
InspectorAdvancedControls.Slot = props => {
return (0,external_wp_element_namespaceObject.createElement)(InspectorControlsSlot, {
...props,
group: "advanced"
});
};
InspectorAdvancedControls.slotName = 'InspectorAdvancedControls';
/**
* @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/inspector-controls/README.md
*/
/* harmony default export */ var inspector_controls = (InspectorControls);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/hooks/anchor.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
/**
* Regular expression matching invalid anchor characters for replacement.
*
* @type {RegExp}
*/
const ANCHOR_REGEX = /[\s#]/g;
const ANCHOR_SCHEMA = {
type: 'string',
source: 'attribute',
attribute: 'id',
selector: '*'
};
/**
* Filters registered block settings, extending attributes with anchor using ID
* of the first node.
*
* @param {Object} settings Original block settings.
*
* @return {Object} Filtered block settings.
*/
function anchor_addAttribute(settings) {
var _settings$attributes$;
// Allow blocks to specify their own attribute definition with default values if needed.
if ('type' in ((_settings$attributes$ = settings.attributes?.anchor) !== null && _settings$attributes$ !== void 0 ? _settings$attributes$ : {})) {
return settings;
}
if ((0,external_wp_blocks_namespaceObject.hasBlockSupport)(settings, 'anchor')) {
// Gracefully handle if settings.attributes is undefined.
settings.attributes = {
...settings.attributes,
anchor: ANCHOR_SCHEMA
};
}
return settings;
}
/**
* Override the default edit UI to include a new block inspector control for
* assigning the anchor ID, if block supports anchor.
*
* @param {WPComponent} BlockEdit Original component.
*
* @return {WPComponent} Wrapped component.
*/
const withInspectorControl = (0,external_wp_compose_namespaceObject.createHigherOrderComponent)(BlockEdit => {
return props => {
const hasAnchor = (0,external_wp_blocks_namespaceObject.hasBlockSupport)(props.name, 'anchor');
const blockEditingMode = useBlockEditingMode();
if (hasAnchor && props.isSelected) {
const isWeb = external_wp_element_namespaceObject.Platform.OS === 'web';
const textControl = (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.TextControl, {
__nextHasNoMarginBottom: true,
className: "html-anchor-control",
label: (0,external_wp_i18n_namespaceObject.__)('HTML anchor'),
help: (0,external_wp_element_namespaceObject.createElement)(external_wp_element_namespaceObject.Fragment, null, (0,external_wp_i18n_namespaceObject.__)('Enter a word or two — without spaces — to make a unique web address just for this block, called an “anchor.” Then, you’ll be able to link directly to this section of your page.'), isWeb && (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.ExternalLink, {
href: (0,external_wp_i18n_namespaceObject.__)('https://wordpress.org/documentation/article/page-jumps/')
}, (0,external_wp_i18n_namespaceObject.__)('Learn more about anchors'))),
value: props.attributes.anchor || '',
placeholder: !isWeb ? (0,external_wp_i18n_namespaceObject.__)('Add an anchor') : null,
onChange: nextValue => {
nextValue = nextValue.replace(ANCHOR_REGEX, '-');
props.setAttributes({
anchor: nextValue
});
},
autoCapitalize: "none",
autoComplete: "off"
});
return (0,external_wp_element_namespaceObject.createElement)(external_wp_element_namespaceObject.Fragment, null, (0,external_wp_element_namespaceObject.createElement)(BlockEdit, {
...props
}), isWeb && blockEditingMode === 'default' && (0,external_wp_element_namespaceObject.createElement)(inspector_controls, {
group: "advanced"
}, textControl), !isWeb && props.name === 'core/heading' && (0,external_wp_element_namespaceObject.createElement)(inspector_controls, null, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.PanelBody, {
title: (0,external_wp_i18n_namespaceObject.__)('Heading settings')
}, textControl)));
}
return (0,external_wp_element_namespaceObject.createElement)(BlockEdit, {
...props
});
};
}, 'withInspectorControl');
/**
* Override props assigned to save component to inject anchor ID, if block
* supports anchor. This is only applied if the block's save result is an
* element and not a markup string.
*
* @param {Object} extraProps Additional props applied to save element.
* @param {Object} blockType Block type.
* @param {Object} attributes Current block attributes.
*
* @return {Object} Filtered props applied to save element.
*/
function addSaveProps(extraProps, blockType, attributes) {
if ((0,external_wp_blocks_namespaceObject.hasBlockSupport)(blockType, 'anchor')) {
extraProps.id = attributes.anchor === '' ? null : attributes.anchor;
}
return extraProps;
}
(0,external_wp_hooks_namespaceObject.addFilter)('blocks.registerBlockType', 'core/anchor/attribute', anchor_addAttribute);
(0,external_wp_hooks_namespaceObject.addFilter)('editor.BlockEdit', 'core/editor/anchor/with-inspector-control', withInspectorControl);
(0,external_wp_hooks_namespaceObject.addFilter)('blocks.getSaveContent.extraProps', 'core/anchor/save-props', addSaveProps);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/hooks/aria-label.js
/**
* WordPress dependencies
*/
const ARIA_LABEL_SCHEMA = {
type: 'string',
source: 'attribute',
attribute: 'aria-label',
selector: '*'
};
/**
* Filters registered block settings, extending attributes with ariaLabel using aria-label
* of the first node.
*
* @param {Object} settings Original block settings.
*
* @return {Object} Filtered block settings.
*/
function aria_label_addAttribute(settings) {
// Allow blocks to specify their own attribute definition with default values if needed.
if (settings?.attributes?.ariaLabel?.type) {
return settings;
}
if ((0,external_wp_blocks_namespaceObject.hasBlockSupport)(settings, 'ariaLabel')) {
// Gracefully handle if settings.attributes is undefined.
settings.attributes = {
...settings.attributes,
ariaLabel: ARIA_LABEL_SCHEMA
};
}
return settings;
}
/**
* Override props assigned to save component to inject aria-label, if block
* supports ariaLabel. This is only applied if the block's save result is an
* element and not a markup string.
*
* @param {Object} extraProps Additional props applied to save element.
* @param {Object} blockType Block type.
* @param {Object} attributes Current block attributes.
*
* @return {Object} Filtered props applied to save element.
*/
function aria_label_addSaveProps(extraProps, blockType, attributes) {
if ((0,external_wp_blocks_namespaceObject.hasBlockSupport)(blockType, 'ariaLabel')) {
extraProps['aria-label'] = attributes.ariaLabel === '' ? null : attributes.ariaLabel;
}
return extraProps;
}
(0,external_wp_hooks_namespaceObject.addFilter)('blocks.registerBlockType', 'core/ariaLabel/attribute', aria_label_addAttribute);
(0,external_wp_hooks_namespaceObject.addFilter)('blocks.getSaveContent.extraProps', 'core/ariaLabel/save-props', aria_label_addSaveProps);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/hooks/custom-class-name.js
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
/**
* Filters registered block settings, extending attributes to include `className`.
*
* @param {Object} settings Original block settings.
*
* @return {Object} Filtered block settings.
*/
function custom_class_name_addAttribute(settings) {
if ((0,external_wp_blocks_namespaceObject.hasBlockSupport)(settings, 'customClassName', true)) {
// Gracefully handle if settings.attributes is undefined.
settings.attributes = {
...settings.attributes,
className: {
type: 'string'
}
};
}
return settings;
}
/**
* Override the default edit UI to include a new block inspector control for
* assigning the custom class name, if block supports custom class name.
* The control is displayed within the Advanced panel in the block inspector.
*
* @param {WPComponent} BlockEdit Original component.
*
* @return {WPComponent} Wrapped component.
*/
const custom_class_name_withInspectorControl = (0,external_wp_compose_namespaceObject.createHigherOrderComponent)(BlockEdit => {
return props => {
const blockEditingMode = useBlockEditingMode();
const hasCustomClassName = (0,external_wp_blocks_namespaceObject.hasBlockSupport)(props.name, 'customClassName', true);
if (hasCustomClassName && props.isSelected) {
return (0,external_wp_element_namespaceObject.createElement)(external_wp_element_namespaceObject.Fragment, null, (0,external_wp_element_namespaceObject.createElement)(BlockEdit, {
...props
}), blockEditingMode === 'default' && (0,external_wp_element_namespaceObject.createElement)(inspector_controls, {
group: "advanced"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.TextControl, {
__nextHasNoMarginBottom: true,
autoComplete: "off",
label: (0,external_wp_i18n_namespaceObject.__)('Additional CSS class(es)'),
value: props.attributes.className || '',
onChange: nextValue => {
props.setAttributes({
className: nextValue !== '' ? nextValue : undefined
});
},
help: (0,external_wp_i18n_namespaceObject.__)('Separate multiple classes with spaces.')
})));
}
return (0,external_wp_element_namespaceObject.createElement)(BlockEdit, {
...props
});
};
}, 'withInspectorControl');
/**
* Override props assigned to save component to inject the className, if block
* supports customClassName. This is only applied if the block's save result is an
* element and not a markup string.
*
* @param {Object} extraProps Additional props applied to save element.
* @param {Object} blockType Block type.
* @param {Object} attributes Current block attributes.
*
* @return {Object} Filtered props applied to save element.
*/
function custom_class_name_addSaveProps(extraProps, blockType, attributes) {
if ((0,external_wp_blocks_namespaceObject.hasBlockSupport)(blockType, 'customClassName', true) && attributes.className) {
extraProps.className = classnames_default()(extraProps.className, attributes.className);
}
return extraProps;
}
function addTransforms(result, source, index, results) {
if (!(0,external_wp_blocks_namespaceObject.hasBlockSupport)(result.name, 'customClassName', true)) {
return result;
}
// If the condition verifies we are probably in the presence of a wrapping transform
// e.g: nesting paragraphs in a group or columns and in that case the class should not be kept.
if (results.length === 1 && result.innerBlocks.length === source.length) {
return result;
}
// If we are transforming one block to multiple blocks or multiple blocks to one block,
// we ignore the class during the transform.
if (results.length === 1 && source.length > 1 || results.length > 1 && source.length === 1) {
return result;
}
// If we are in presence of transform between one or more block in the source
// that have one or more blocks in the result
// we apply the class on source N to the result N,
// if source N does not exists we do nothing.
if (source[index]) {
const originClassName = source[index]?.attributes.className;
if (originClassName) {
return {
...result,
attributes: {
...result.attributes,
className: originClassName
}
};
}
}
return result;
}
(0,external_wp_hooks_namespaceObject.addFilter)('blocks.registerBlockType', 'core/custom-class-name/attribute', custom_class_name_addAttribute);
(0,external_wp_hooks_namespaceObject.addFilter)('editor.BlockEdit', 'core/editor/custom-class-name/with-inspector-control', custom_class_name_withInspectorControl);
(0,external_wp_hooks_namespaceObject.addFilter)('blocks.getSaveContent.extraProps', 'core/custom-class-name/save-props', custom_class_name_addSaveProps);
(0,external_wp_hooks_namespaceObject.addFilter)('blocks.switchToBlockType.transformedBlock', 'core/color/addTransforms', addTransforms);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/hooks/generated-class-name.js
/**
* WordPress dependencies
*/
/**
* Override props assigned to save component to inject generated className if
* block supports it. This is only applied if the block's save result is an
* element and not a markup string.
*
* @param {Object} extraProps Additional props applied to save element.
* @param {Object} blockType Block type.
*
* @return {Object} Filtered props applied to save element.
*/
function addGeneratedClassName(extraProps, blockType) {
// Adding the generated className.
if ((0,external_wp_blocks_namespaceObject.hasBlockSupport)(blockType, 'className', true)) {
if (typeof extraProps.className === 'string') {
// We have some extra classes and want to add the default classname
// We use uniq to prevent duplicate classnames.
extraProps.className = [...new Set([(0,external_wp_blocks_namespaceObject.getBlockDefaultClassName)(blockType.name), ...extraProps.className.split(' ')])].join(' ').trim();
} else {
// There is no string in the className variable,
// so we just dump the default name in there.
extraProps.className = (0,external_wp_blocks_namespaceObject.getBlockDefaultClassName)(blockType.name);
}
}
return extraProps;
}
(0,external_wp_hooks_namespaceObject.addFilter)('blocks.getSaveContent.extraProps', 'core/generated-class-name/save-props', addGeneratedClassName);
;// CONCATENATED MODULE: external ["wp","dom"]
var external_wp_dom_namespaceObject = window["wp"]["dom"];
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-context/index.js
/**
* WordPress dependencies
*/
/** @typedef {import('react').ReactNode} ReactNode */
/**
* @typedef BlockContextProviderProps
*
* @property {Record} value Context value to merge with current
* value.
* @property {ReactNode} children Component children.
*/
/** @type {import('react').Context>} */
const block_context_Context = (0,external_wp_element_namespaceObject.createContext)({});
/**
* Component which merges passed value with current consumed block context.
*
* @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/block-context/README.md
*
* @param {BlockContextProviderProps} props
*/
function BlockContextProvider({
value,
children
}) {
const context = (0,external_wp_element_namespaceObject.useContext)(block_context_Context);
const nextValue = (0,external_wp_element_namespaceObject.useMemo)(() => ({
...context,
...value
}), [context, value]);
return (0,external_wp_element_namespaceObject.createElement)(block_context_Context.Provider, {
value: nextValue,
children: children
});
}
/* harmony default export */ var block_context = (block_context_Context);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-edit/edit.js
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
/**
* Default value used for blocks which do not define their own context needs,
* used to guarantee that a block's `context` prop will always be an object. It
* is assigned as a constant since it is always expected to be an empty object,
* and in order to avoid unnecessary React reconciliations of a changing object.
*
* @type {{}}
*/
const DEFAULT_BLOCK_CONTEXT = {};
const Edit = props => {
const {
name
} = props;
const blockType = (0,external_wp_blocks_namespaceObject.getBlockType)(name);
if (!blockType) {
return null;
}
// `edit` and `save` are functions or components describing the markup
// with which a block is displayed. If `blockType` is valid, assign
// them preferentially as the render value for the block.
const Component = blockType.edit || blockType.save;
return (0,external_wp_element_namespaceObject.createElement)(Component, {
...props
});
};
const EditWithFilters = (0,external_wp_components_namespaceObject.withFilters)('editor.BlockEdit')(Edit);
const EditWithGeneratedProps = props => {
const {
attributes = {},
name
} = props;
const blockType = (0,external_wp_blocks_namespaceObject.getBlockType)(name);
const blockContext = (0,external_wp_element_namespaceObject.useContext)(block_context);
// Assign context values using the block type's declared context needs.
const context = (0,external_wp_element_namespaceObject.useMemo)(() => {
return blockType && blockType.usesContext ? Object.fromEntries(Object.entries(blockContext).filter(([key]) => blockType.usesContext.includes(key))) : DEFAULT_BLOCK_CONTEXT;
}, [blockType, blockContext]);
if (!blockType) {
return null;
}
if (blockType.apiVersion > 1) {
return (0,external_wp_element_namespaceObject.createElement)(EditWithFilters, {
...props,
context: context
});
}
// Generate a class name for the block's editable form.
const generatedClassName = (0,external_wp_blocks_namespaceObject.hasBlockSupport)(blockType, 'className', true) ? (0,external_wp_blocks_namespaceObject.getBlockDefaultClassName)(name) : null;
const className = classnames_default()(generatedClassName, attributes.className, props.className);
return (0,external_wp_element_namespaceObject.createElement)(EditWithFilters, {
...props,
context: context,
className: className
});
};
/* harmony default export */ var edit = (EditWithGeneratedProps);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-edit/index.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
/**
* The `useBlockEditContext` hook provides information about the block this hook is being used in.
* It returns an object with the `name`, `isSelected` state, and the `clientId` of the block.
* It is useful if you want to create custom hooks that need access to the current blocks clientId
* but don't want to rely on the data getting passed in as a parameter.
*
* @return {Object} Block edit context
*/
function BlockEdit(props) {
const {
name,
isSelected,
clientId,
attributes = {},
__unstableLayoutClassNames
} = props;
const {
layout = null
} = attributes;
const layoutSupport = (0,external_wp_blocks_namespaceObject.hasBlockSupport)(name, 'layout', false) || (0,external_wp_blocks_namespaceObject.hasBlockSupport)(name, '__experimentalLayout', false);
const context = {
name,
isSelected,
clientId,
layout: layoutSupport ? layout : null,
__unstableLayoutClassNames
};
return (0,external_wp_element_namespaceObject.createElement)(Provider
// It is important to return the same object if props haven't
// changed to avoid unnecessary rerenders.
// See https://reactjs.org/docs/context.html#caveats.
, {
value: (0,external_wp_element_namespaceObject.useMemo)(() => context, Object.values(context))
}, (0,external_wp_element_namespaceObject.createElement)(edit, {
...props
}));
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/more-vertical.js
/**
* WordPress dependencies
*/
const moreVertical = (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.SVG, {
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 24 24"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.Path, {
d: "M13 19h-2v-2h2v2zm0-6h-2v-2h2v2zm0-6h-2V5h2v2z"
}));
/* harmony default export */ var more_vertical = (moreVertical);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/warning/index.js
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
function Warning({
className,
actions,
children,
secondaryActions
}) {
return (0,external_wp_element_namespaceObject.createElement)("div", {
style: {
display: 'contents',
all: 'initial'
}
}, (0,external_wp_element_namespaceObject.createElement)("div", {
className: classnames_default()(className, 'block-editor-warning')
}, (0,external_wp_element_namespaceObject.createElement)("div", {
className: "block-editor-warning__contents"
}, (0,external_wp_element_namespaceObject.createElement)("p", {
className: "block-editor-warning__message"
}, children), (external_wp_element_namespaceObject.Children.count(actions) > 0 || secondaryActions) && (0,external_wp_element_namespaceObject.createElement)("div", {
className: "block-editor-warning__actions"
}, external_wp_element_namespaceObject.Children.count(actions) > 0 && external_wp_element_namespaceObject.Children.map(actions, (action, i) => (0,external_wp_element_namespaceObject.createElement)("span", {
key: i,
className: "block-editor-warning__action"
}, action)), secondaryActions && (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.DropdownMenu, {
className: "block-editor-warning__secondary",
icon: more_vertical,
label: (0,external_wp_i18n_namespaceObject.__)('More options'),
popoverProps: {
position: 'bottom left',
className: 'block-editor-warning__dropdown'
},
noIcons: true
}, () => (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.MenuGroup, null, secondaryActions.map((item, pos) => (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.MenuItem, {
onClick: item.onClick,
key: pos
}, item.title))))))));
}
/**
* @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/warning/README.md
*/
/* harmony default export */ var warning = (Warning);
// EXTERNAL MODULE: ./node_modules/diff/lib/diff/character.js
var character = __webpack_require__(1973);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-compare/block-view.js
/**
* WordPress dependencies
*/
function BlockView({
title,
rawContent,
renderedContent,
action,
actionText,
className
}) {
return (0,external_wp_element_namespaceObject.createElement)("div", {
className: className
}, (0,external_wp_element_namespaceObject.createElement)("div", {
className: "block-editor-block-compare__content"
}, (0,external_wp_element_namespaceObject.createElement)("h2", {
className: "block-editor-block-compare__heading"
}, title), (0,external_wp_element_namespaceObject.createElement)("div", {
className: "block-editor-block-compare__html"
}, rawContent), (0,external_wp_element_namespaceObject.createElement)("div", {
className: "block-editor-block-compare__preview edit-post-visual-editor"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_element_namespaceObject.RawHTML, null, (0,external_wp_dom_namespaceObject.safeHTML)(renderedContent)))), (0,external_wp_element_namespaceObject.createElement)("div", {
className: "block-editor-block-compare__action"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.Button, {
variant: "secondary",
tabIndex: "0",
onClick: action
}, actionText)));
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-compare/index.js
/**
* External dependencies
*/
// diff doesn't tree-shake correctly, so we import from the individual
// module here, to avoid including too much of the library
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
function BlockCompare({
block,
onKeep,
onConvert,
convertor,
convertButtonText
}) {
function getDifference(originalContent, newContent) {
const difference = (0,character/* diffChars */.Kx)(originalContent, newContent);
return difference.map((item, pos) => {
const classes = classnames_default()({
'block-editor-block-compare__added': item.added,
'block-editor-block-compare__removed': item.removed
});
return (0,external_wp_element_namespaceObject.createElement)("span", {
key: pos,
className: classes
}, item.value);
});
}
function getConvertedContent(convertedBlock) {
// The convertor may return an array of items or a single item.
const newBlocks = Array.isArray(convertedBlock) ? convertedBlock : [convertedBlock];
// Get converted block details.
const newContent = newBlocks.map(item => (0,external_wp_blocks_namespaceObject.getSaveContent)(item.name, item.attributes, item.innerBlocks));
return newContent.join('');
}
const converted = getConvertedContent(convertor(block));
const difference = getDifference(block.originalContent, converted);
return (0,external_wp_element_namespaceObject.createElement)("div", {
className: "block-editor-block-compare__wrapper"
}, (0,external_wp_element_namespaceObject.createElement)(BlockView, {
title: (0,external_wp_i18n_namespaceObject.__)('Current'),
className: "block-editor-block-compare__current",
action: onKeep,
actionText: (0,external_wp_i18n_namespaceObject.__)('Convert to HTML'),
rawContent: block.originalContent,
renderedContent: block.originalContent
}), (0,external_wp_element_namespaceObject.createElement)(BlockView, {
title: (0,external_wp_i18n_namespaceObject.__)('After Conversion'),
className: "block-editor-block-compare__converted",
action: onConvert,
actionText: convertButtonText,
rawContent: difference,
renderedContent: converted
}));
}
/* harmony default export */ var block_compare = (BlockCompare);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-list/block-invalid-warning.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const blockToBlocks = block => (0,external_wp_blocks_namespaceObject.rawHandler)({
HTML: block.originalContent
});
function BlockInvalidWarning({
clientId
}) {
const {
block,
canInsertHTMLBlock,
canInsertClassicBlock
} = (0,external_wp_data_namespaceObject.useSelect)(select => {
const {
canInsertBlockType,
getBlock,
getBlockRootClientId
} = select(store);
const rootClientId = getBlockRootClientId(clientId);
return {
block: getBlock(clientId),
canInsertHTMLBlock: canInsertBlockType('core/html', rootClientId),
canInsertClassicBlock: canInsertBlockType('core/freeform', rootClientId)
};
}, [clientId]);
const {
replaceBlock
} = (0,external_wp_data_namespaceObject.useDispatch)(store);
const [compare, setCompare] = (0,external_wp_element_namespaceObject.useState)(false);
const onCompareClose = (0,external_wp_element_namespaceObject.useCallback)(() => setCompare(false), []);
const convert = (0,external_wp_element_namespaceObject.useMemo)(() => ({
toClassic() {
const classicBlock = (0,external_wp_blocks_namespaceObject.createBlock)('core/freeform', {
content: block.originalContent
});
return replaceBlock(block.clientId, classicBlock);
},
toHTML() {
const htmlBlock = (0,external_wp_blocks_namespaceObject.createBlock)('core/html', {
content: block.originalContent
});
return replaceBlock(block.clientId, htmlBlock);
},
toBlocks() {
const newBlocks = blockToBlocks(block);
return replaceBlock(block.clientId, newBlocks);
},
toRecoveredBlock() {
const recoveredBlock = (0,external_wp_blocks_namespaceObject.createBlock)(block.name, block.attributes, block.innerBlocks);
return replaceBlock(block.clientId, recoveredBlock);
}
}), [block, replaceBlock]);
const secondaryActions = (0,external_wp_element_namespaceObject.useMemo)(() => [{
// translators: Button to fix block content
title: (0,external_wp_i18n_namespaceObject._x)('Resolve', 'imperative verb'),
onClick: () => setCompare(true)
}, canInsertHTMLBlock && {
title: (0,external_wp_i18n_namespaceObject.__)('Convert to HTML'),
onClick: convert.toHTML
}, canInsertClassicBlock && {
title: (0,external_wp_i18n_namespaceObject.__)('Convert to Classic Block'),
onClick: convert.toClassic
}].filter(Boolean), [canInsertHTMLBlock, canInsertClassicBlock, convert]);
return (0,external_wp_element_namespaceObject.createElement)(external_wp_element_namespaceObject.Fragment, null, (0,external_wp_element_namespaceObject.createElement)(warning, {
actions: [(0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.Button, {
key: "recover",
onClick: convert.toRecoveredBlock,
variant: "primary"
}, (0,external_wp_i18n_namespaceObject.__)('Attempt Block Recovery'))],
secondaryActions: secondaryActions
}, (0,external_wp_i18n_namespaceObject.__)('This block contains unexpected or invalid content.')), compare && (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.Modal, {
title:
// translators: Dialog title to fix block content
(0,external_wp_i18n_namespaceObject.__)('Resolve Block'),
onRequestClose: onCompareClose,
className: "block-editor-block-compare"
}, (0,external_wp_element_namespaceObject.createElement)(block_compare, {
block: block,
onKeep: convert.toHTML,
onConvert: convert.toBlocks,
convertor: blockToBlocks,
convertButtonText: (0,external_wp_i18n_namespaceObject.__)('Convert to Blocks')
})));
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-list/block-crash-warning.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const block_crash_warning_warning = (0,external_wp_element_namespaceObject.createElement)(warning, {
className: "block-editor-block-list__block-crash-warning"
}, (0,external_wp_i18n_namespaceObject.__)('This block has encountered an error and cannot be previewed.'));
/* harmony default export */ var block_crash_warning = (() => block_crash_warning_warning);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-list/block-crash-boundary.js
/**
* WordPress dependencies
*/
class BlockCrashBoundary extends external_wp_element_namespaceObject.Component {
constructor() {
super(...arguments);
this.state = {
hasError: false
};
}
componentDidCatch() {
this.setState({
hasError: true
});
}
render() {
if (this.state.hasError) {
return this.props.fallback;
}
return this.props.children;
}
}
/* harmony default export */ var block_crash_boundary = (BlockCrashBoundary);
// EXTERNAL MODULE: ./node_modules/react-autosize-textarea/lib/index.js
var lib = __webpack_require__(773);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-list/block-html.js
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
function BlockHTML({
clientId
}) {
const [html, setHtml] = (0,external_wp_element_namespaceObject.useState)('');
const block = (0,external_wp_data_namespaceObject.useSelect)(select => select(store).getBlock(clientId), [clientId]);
const {
updateBlock
} = (0,external_wp_data_namespaceObject.useDispatch)(store);
const onChange = () => {
const blockType = (0,external_wp_blocks_namespaceObject.getBlockType)(block.name);
if (!blockType) {
return;
}
const attributes = (0,external_wp_blocks_namespaceObject.getBlockAttributes)(blockType, html, block.attributes);
// If html is empty we reset the block to the default HTML and mark it as valid to avoid triggering an error
const content = html ? html : (0,external_wp_blocks_namespaceObject.getSaveContent)(blockType, attributes);
const [isValid] = html ? (0,external_wp_blocks_namespaceObject.validateBlock)({
...block,
attributes,
originalContent: content
}) : [true];
updateBlock(clientId, {
attributes,
originalContent: content,
isValid
});
// Ensure the state is updated if we reset so it displays the default content.
if (!html) {
setHtml(content);
}
};
(0,external_wp_element_namespaceObject.useEffect)(() => {
setHtml((0,external_wp_blocks_namespaceObject.getBlockContent)(block));
}, [block]);
return (0,external_wp_element_namespaceObject.createElement)(lib/* default */.Z, {
className: "block-editor-block-list__block-html-textarea",
value: html,
onBlur: onChange,
onChange: event => setHtml(event.target.value)
});
}
/* harmony default export */ var block_html = (BlockHTML);
;// CONCATENATED MODULE: ./node_modules/@react-spring/rafz/dist/esm/index.js
var f=l(),esm_n=e=>c(e,f),m=l();esm_n.write=e=>c(e,m);var d=l();esm_n.onStart=e=>c(e,d);var h=l();esm_n.onFrame=e=>c(e,h);var p=l();esm_n.onFinish=e=>c(e,p);var i=[];esm_n.setTimeout=(e,t)=>{let a=esm_n.now()+t,o=()=>{let F=i.findIndex(z=>z.cancel==o);~F&&i.splice(F,1),u-=~F?1:0},s={time:a,handler:e,cancel:o};return i.splice(w(a),0,s),u+=1,v(),s};var w=e=>~(~i.findIndex(t=>t.time>e)||~i.length);esm_n.cancel=e=>{d.delete(e),h.delete(e),p.delete(e),f.delete(e),m.delete(e)};esm_n.sync=e=>{T=!0,esm_n.batchedUpdates(e),T=!1};esm_n.throttle=e=>{let t;function a(){try{e(...t)}finally{t=null}}function o(...s){t=s,esm_n.onStart(a)}return o.handler=e,o.cancel=()=>{d.delete(a),t=null},o};var y=typeof window<"u"?window.requestAnimationFrame:()=>{};esm_n.use=e=>y=e;esm_n.now=typeof performance<"u"?()=>performance.now():Date.now;esm_n.batchedUpdates=e=>e();esm_n.catch=console.error;esm_n.frameLoop="always";esm_n.advance=()=>{esm_n.frameLoop!=="demand"?console.warn("Cannot call the manual advancement of rafz whilst frameLoop is not set as demand"):x()};var r=-1,u=0,T=!1;function c(e,t){T?(t.delete(e),e(0)):(t.add(e),v())}function v(){r<0&&(r=0,esm_n.frameLoop!=="demand"&&y(b))}function R(){r=-1}function b(){~r&&(y(b),esm_n.batchedUpdates(x))}function x(){let e=r;r=esm_n.now();let t=w(r);if(t&&(Q(i.splice(0,t),a=>a.handler()),u-=t),!u){R();return}d.flush(),f.flush(e?Math.min(64,r-e):16.667),h.flush(),m.flush(),p.flush()}function l(){let e=new Set,t=e;return{add(a){u+=t==e&&!e.has(a)?1:0,e.add(a)},delete(a){return u-=t==e&&e.has(a)?1:0,e.delete(a)},flush(a){t.size&&(e=new Set,u-=t.size,Q(t,o=>o(a)&&e.add(o)),u+=e.size,t=e)}}}function Q(e,t){e.forEach(a=>{try{t(a)}catch(o){esm_n.catch(o)}})}var S={count(){return u},isRunning(){return r>=0},clear(){r=-1,i=[],d=l(),f=l(),h=l(),m=l(),p=l(),u=0}};
// EXTERNAL MODULE: external "React"
var external_React_ = __webpack_require__(9196);
var external_React_default = /*#__PURE__*/__webpack_require__.n(external_React_);
;// CONCATENATED MODULE: ./node_modules/@react-spring/shared/dist/esm/index.js
var ze=Object.defineProperty;var Le=(e,t)=>{for(var r in t)ze(e,r,{get:t[r],enumerable:!0})};var esm_p={};Le(esm_p,{assign:()=>U,colors:()=>esm_c,createStringInterpolator:()=>k,skipAnimation:()=>ee,to:()=>J,willAdvance:()=>esm_S});function Y(){}var mt=(e,t,r)=>Object.defineProperty(e,t,{value:r,writable:!0,configurable:!0}),esm_l={arr:Array.isArray,obj:e=>!!e&&e.constructor.name==="Object",fun:e=>typeof e=="function",str:e=>typeof e=="string",num:e=>typeof e=="number",und:e=>e===void 0};function bt(e,t){if(esm_l.arr(e)){if(!esm_l.arr(t)||e.length!==t.length)return!1;for(let r=0;re.forEach(t);function xt(e,t,r){if(esm_l.arr(e)){for(let n=0;nesm_l.und(e)?[]:esm_l.arr(e)?e:[e];function Pe(e,t){if(e.size){let r=Array.from(e);e.clear(),Ve(r,t)}}var yt=(e,...t)=>Pe(e,r=>r(...t)),esm_h=()=>typeof window>"u"||!window.navigator||/ServerSideRendering|^Deno\//.test(window.navigator.userAgent);var k,J,esm_c=null,ee=!1,esm_S=Y,U=e=>{e.to&&(J=e.to),e.now&&(esm_n.now=e.now),e.colors!==void 0&&(esm_c=e.colors),e.skipAnimation!=null&&(ee=e.skipAnimation),e.createStringInterpolator&&(k=e.createStringInterpolator),e.requestAnimationFrame&&esm_n.use(e.requestAnimationFrame),e.batchedUpdates&&(esm_n.batchedUpdates=e.batchedUpdates),e.willAdvance&&(esm_S=e.willAdvance),e.frameLoop&&(esm_n.frameLoop=e.frameLoop)};var E=new Set,esm_u=[],H=[],A=0,qe={get idle(){return!E.size&&!esm_u.length},start(e){A>e.priority?(E.add(e),esm_n.onStart($e)):(te(e),esm_n(B))},advance:B,sort(e){if(A)esm_n.onFrame(()=>qe.sort(e));else{let t=esm_u.indexOf(e);~t&&(esm_u.splice(t,1),re(e))}},clear(){esm_u=[],E.clear()}};function $e(){E.forEach(te),E.clear(),esm_n(B)}function te(e){esm_u.includes(e)||re(e)}function re(e){esm_u.splice(Ge(esm_u,t=>t.priority>e.priority),0,e)}function B(e){let t=H;for(let r=0;r0}function Ge(e,t){let r=e.findIndex(t);return r<0?e.length:r}var ne=(e,t,r)=>Math.min(Math.max(r,e),t);var It={transparent:0,aliceblue:4042850303,antiquewhite:4209760255,aqua:16777215,aquamarine:2147472639,azure:4043309055,beige:4126530815,bisque:4293182719,black:255,blanchedalmond:4293643775,blue:65535,blueviolet:2318131967,brown:2771004159,burlywood:3736635391,burntsienna:3934150143,cadetblue:1604231423,chartreuse:2147418367,chocolate:3530104575,coral:4286533887,cornflowerblue:1687547391,cornsilk:4294499583,crimson:3692313855,cyan:16777215,darkblue:35839,darkcyan:9145343,darkgoldenrod:3095792639,darkgray:2846468607,darkgreen:6553855,darkgrey:2846468607,darkkhaki:3182914559,darkmagenta:2332068863,darkolivegreen:1433087999,darkorange:4287365375,darkorchid:2570243327,darkred:2332033279,darksalmon:3918953215,darkseagreen:2411499519,darkslateblue:1211993087,darkslategray:793726975,darkslategrey:793726975,darkturquoise:13554175,darkviolet:2483082239,deeppink:4279538687,deepskyblue:12582911,dimgray:1768516095,dimgrey:1768516095,dodgerblue:512819199,firebrick:2988581631,floralwhite:4294635775,forestgreen:579543807,fuchsia:4278255615,gainsboro:3705462015,ghostwhite:4177068031,gold:4292280575,goldenrod:3668254975,gray:2155905279,green:8388863,greenyellow:2919182335,grey:2155905279,honeydew:4043305215,hotpink:4285117695,indianred:3445382399,indigo:1258324735,ivory:4294963455,khaki:4041641215,lavender:3873897215,lavenderblush:4293981695,lawngreen:2096890111,lemonchiffon:4294626815,lightblue:2916673279,lightcoral:4034953471,lightcyan:3774873599,lightgoldenrodyellow:4210742015,lightgray:3553874943,lightgreen:2431553791,lightgrey:3553874943,lightpink:4290167295,lightsalmon:4288707327,lightseagreen:548580095,lightskyblue:2278488831,lightslategray:2005441023,lightslategrey:2005441023,lightsteelblue:2965692159,lightyellow:4294959359,lime:16711935,limegreen:852308735,linen:4210091775,magenta:4278255615,maroon:2147483903,mediumaquamarine:1724754687,mediumblue:52735,mediumorchid:3126187007,mediumpurple:2473647103,mediumseagreen:1018393087,mediumslateblue:2070474495,mediumspringgreen:16423679,mediumturquoise:1221709055,mediumvioletred:3340076543,midnightblue:421097727,mintcream:4127193855,mistyrose:4293190143,moccasin:4293178879,navajowhite:4292783615,navy:33023,oldlace:4260751103,olive:2155872511,olivedrab:1804477439,orange:4289003775,orangered:4282712319,orchid:3664828159,palegoldenrod:4008225535,palegreen:2566625535,paleturquoise:2951671551,palevioletred:3681588223,papayawhip:4293907967,peachpuff:4292524543,peru:3448061951,pink:4290825215,plum:3718307327,powderblue:2967529215,purple:2147516671,rebeccapurple:1714657791,red:4278190335,rosybrown:3163525119,royalblue:1097458175,saddlebrown:2336560127,salmon:4202722047,sandybrown:4104413439,seagreen:780883967,seashell:4294307583,sienna:2689740287,silver:3233857791,skyblue:2278484991,slateblue:1784335871,slategray:1887473919,slategrey:1887473919,snow:4294638335,springgreen:16744447,steelblue:1182971135,tan:3535047935,teal:8421631,thistle:3636451583,tomato:4284696575,turquoise:1088475391,violet:4001558271,wheat:4125012991,white:4294967295,whitesmoke:4126537215,yellow:4294902015,yellowgreen:2597139199};var esm_d="[-+]?\\d*\\.?\\d+",M=esm_d+"%";function C(...e){return"\\(\\s*("+e.join(")\\s*,\\s*(")+")\\s*\\)"}var oe=new RegExp("rgb"+C(esm_d,esm_d,esm_d)),fe=new RegExp("rgba"+C(esm_d,esm_d,esm_d,esm_d)),ae=new RegExp("hsl"+C(esm_d,M,M)),ie=new RegExp("hsla"+C(esm_d,M,M,esm_d)),se=/^#([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,ue=/^#([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,le=/^#([0-9a-fA-F]{6})$/,ce=/^#([0-9a-fA-F]{8})$/;function be(e){let t;return typeof e=="number"?e>>>0===e&&e>=0&&e<=4294967295?e:null:(t=le.exec(e))?parseInt(t[1]+"ff",16)>>>0:esm_c&&esm_c[e]!==void 0?esm_c[e]:(t=oe.exec(e))?(esm_y(t[1])<<24|esm_y(t[2])<<16|esm_y(t[3])<<8|255)>>>0:(t=fe.exec(e))?(esm_y(t[1])<<24|esm_y(t[2])<<16|esm_y(t[3])<<8|me(t[4]))>>>0:(t=se.exec(e))?parseInt(t[1]+t[1]+t[2]+t[2]+t[3]+t[3]+"ff",16)>>>0:(t=ce.exec(e))?parseInt(t[1],16)>>>0:(t=ue.exec(e))?parseInt(t[1]+t[1]+t[2]+t[2]+t[3]+t[3]+t[4]+t[4],16)>>>0:(t=ae.exec(e))?(de(pe(t[1]),z(t[2]),z(t[3]))|255)>>>0:(t=ie.exec(e))?(de(pe(t[1]),z(t[2]),z(t[3]))|me(t[4]))>>>0:null}function esm_j(e,t,r){return r<0&&(r+=1),r>1&&(r-=1),r<1/6?e+(t-e)*6*r:r<1/2?t:r<2/3?e+(t-e)*(2/3-r)*6:e}function de(e,t,r){let n=r<.5?r*(1+t):r+t-r*t,f=2*r-n,o=esm_j(f,n,e+1/3),i=esm_j(f,n,e),s=esm_j(f,n,e-1/3);return Math.round(o*255)<<24|Math.round(i*255)<<16|Math.round(s*255)<<8}function esm_y(e){let t=parseInt(e,10);return t<0?0:t>255?255:t}function pe(e){return(parseFloat(e)%360+360)%360/360}function me(e){let t=parseFloat(e);return t<0?0:t>1?255:Math.round(t*255)}function z(e){let t=parseFloat(e);return t<0?0:t>100?1:t/100}function D(e){let t=be(e);if(t===null)return e;t=t||0;let r=(t&4278190080)>>>24,n=(t&16711680)>>>16,f=(t&65280)>>>8,o=(t&255)/255;return`rgba(${r}, ${n}, ${f}, ${o})`}var W=(e,t,r)=>{if(esm_l.fun(e))return e;if(esm_l.arr(e))return W({range:e,output:t,extrapolate:r});if(esm_l.str(e.output[0]))return k(e);let n=e,f=n.output,o=n.range||[0,1],i=n.extrapolateLeft||n.extrapolate||"extend",s=n.extrapolateRight||n.extrapolate||"extend",x=n.easing||(a=>a);return a=>{let F=He(a,o);return Ue(a,o[F],o[F+1],f[F],f[F+1],x,i,s,n.map)}};function Ue(e,t,r,n,f,o,i,s,x){let a=x?x(e):e;if(ar){if(s==="identity")return a;s==="clamp"&&(a=r)}return n===f?n:t===r?e<=t?n:f:(t===-1/0?a=-a:r===1/0?a=a-t:a=(a-t)/(r-t),a=o(a),n===-1/0?a=-a:f===1/0?a=a+n:a=a*(f-n)+n,a)}function He(e,t){for(var r=1;r=e);++r);return r-1}var Be=(e,t="end")=>r=>{r=t==="end"?Math.min(r,.999):Math.max(r,.001);let n=r*e,f=t==="end"?Math.floor(n):Math.ceil(n);return ne(0,1,f/e)},P=1.70158,L=P*1.525,xe=P+1,he=2*Math.PI/3,ye=2*Math.PI/4.5,V=e=>e<1/2.75?7.5625*e*e:e<2/2.75?7.5625*(e-=1.5/2.75)*e+.75:e<2.5/2.75?7.5625*(e-=2.25/2.75)*e+.9375:7.5625*(e-=2.625/2.75)*e+.984375,Lt={linear:e=>e,easeInQuad:e=>e*e,easeOutQuad:e=>1-(1-e)*(1-e),easeInOutQuad:e=>e<.5?2*e*e:1-Math.pow(-2*e+2,2)/2,easeInCubic:e=>e*e*e,easeOutCubic:e=>1-Math.pow(1-e,3),easeInOutCubic:e=>e<.5?4*e*e*e:1-Math.pow(-2*e+2,3)/2,easeInQuart:e=>e*e*e*e,easeOutQuart:e=>1-Math.pow(1-e,4),easeInOutQuart:e=>e<.5?8*e*e*e*e:1-Math.pow(-2*e+2,4)/2,easeInQuint:e=>e*e*e*e*e,easeOutQuint:e=>1-Math.pow(1-e,5),easeInOutQuint:e=>e<.5?16*e*e*e*e*e:1-Math.pow(-2*e+2,5)/2,easeInSine:e=>1-Math.cos(e*Math.PI/2),easeOutSine:e=>Math.sin(e*Math.PI/2),easeInOutSine:e=>-(Math.cos(Math.PI*e)-1)/2,easeInExpo:e=>e===0?0:Math.pow(2,10*e-10),easeOutExpo:e=>e===1?1:1-Math.pow(2,-10*e),easeInOutExpo:e=>e===0?0:e===1?1:e<.5?Math.pow(2,20*e-10)/2:(2-Math.pow(2,-20*e+10))/2,easeInCirc:e=>1-Math.sqrt(1-Math.pow(e,2)),easeOutCirc:e=>Math.sqrt(1-Math.pow(e-1,2)),easeInOutCirc:e=>e<.5?(1-Math.sqrt(1-Math.pow(2*e,2)))/2:(Math.sqrt(1-Math.pow(-2*e+2,2))+1)/2,easeInBack:e=>xe*e*e*e-P*e*e,easeOutBack:e=>1+xe*Math.pow(e-1,3)+P*Math.pow(e-1,2),easeInOutBack:e=>e<.5?Math.pow(2*e,2)*((L+1)*2*e-L)/2:(Math.pow(2*e-2,2)*((L+1)*(e*2-2)+L)+2)/2,easeInElastic:e=>e===0?0:e===1?1:-Math.pow(2,10*e-10)*Math.sin((e*10-10.75)*he),easeOutElastic:e=>e===0?0:e===1?1:Math.pow(2,-10*e)*Math.sin((e*10-.75)*he)+1,easeInOutElastic:e=>e===0?0:e===1?1:e<.5?-(Math.pow(2,20*e-10)*Math.sin((20*e-11.125)*ye))/2:Math.pow(2,-20*e+10)*Math.sin((20*e-11.125)*ye)/2+1,easeInBounce:e=>1-V(1-e),easeOutBounce:V,easeInOutBounce:e=>e<.5?(1-V(1-2*e))/2:(1+V(2*e-1))/2,steps:Be};var g=Symbol.for("FluidValue.get"),esm_m=Symbol.for("FluidValue.observers");var Pt=e=>Boolean(e&&e[g]),ve=e=>e&&e[g]?e[g]():e,esm_qt=e=>e[esm_m]||null;function je(e,t){e.eventObserved?e.eventObserved(t):e(t)}function $t(e,t){let r=e[esm_m];r&&r.forEach(n=>{je(n,t)})}var esm_ge=class{[g];[esm_m];constructor(t){if(!t&&!(t=this.get))throw Error("Unknown getter");De(this,t)}},De=(e,t)=>Ee(e,g,t);function Gt(e,t){if(e[g]){let r=e[esm_m];r||Ee(e,esm_m,r=new Set),r.has(t)||(r.add(t),e.observerAdded&&e.observerAdded(r.size,t))}return t}function Qt(e,t){let r=e[esm_m];if(r&&r.has(t)){let n=r.size-1;n?r.delete(t):e[esm_m]=null,e.observerRemoved&&e.observerRemoved(n,t)}}var Ee=(e,t,r)=>Object.defineProperty(e,t,{value:r,writable:!0,configurable:!0});var O=/[+\-]?(?:0|[1-9]\d*)(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,esm_Oe=/(#(?:[0-9a-f]{2}){2,4}|(#[0-9a-f]{3})|(rgb|hsl)a?\((-?\d+%?[,\s]+){2,3}\s*[\d\.]+%?\))/gi,K=new RegExp(`(${O.source})(%|[a-z]+)`,"i"),we=/rgba\(([0-9\.-]+), ([0-9\.-]+), ([0-9\.-]+), ([0-9\.-]+)\)/gi,esm_b=/var\((--[a-zA-Z0-9-_]+),? ?([a-zA-Z0-9 ()%#.,-]+)?\)/;var N=e=>{let[t,r]=We(e);if(!t||esm_h())return e;let n=window.getComputedStyle(document.documentElement).getPropertyValue(t);if(n)return n.trim();if(r&&r.startsWith("--")){let f=window.getComputedStyle(document.documentElement).getPropertyValue(r);return f||e}else{if(r&&esm_b.test(r))return N(r);if(r)return r}return e},We=e=>{let t=esm_b.exec(e);if(!t)return[,];let[,r,n]=t;return[r,n]};var _,Ke=(e,t,r,n,f)=>`rgba(${Math.round(t)}, ${Math.round(r)}, ${Math.round(n)}, ${f})`,Xt=e=>{_||(_=esm_c?new RegExp(`(${Object.keys(esm_c).join("|")})(?!\\w)`,"g"):/^\b$/);let t=e.output.map(o=>ve(o).replace(esm_b,N).replace(esm_Oe,D).replace(_,D)),r=t.map(o=>o.match(O).map(Number)),f=r[0].map((o,i)=>r.map(s=>{if(!(i in s))throw Error('The arity of each "output" value must be equal');return s[i]})).map(o=>W({...e,output:o}));return o=>{let i=!K.test(t[0])&&t.find(x=>K.test(x))?.replace(O,""),s=0;return t[0].replace(O,()=>`${f[s++](o)}${i||""}`).replace(we,Ke)}};var Z="react-spring: ",Te=e=>{let t=e,r=!1;if(typeof t!="function")throw new TypeError(`${Z}once requires a function parameter`);return(...n)=>{r||(t(...n),r=!0)}},Ne=Te(console.warn);function Jt(){Ne(`${Z}The "interpolate" function is deprecated in v9 (use "to" instead)`)}var _e=Te(console.warn);function er(){_e(`${Z}Directly calling start instead of using the api object is deprecated in v9 (use ".start" instead), this will be removed in later 0.X.0 versions`)}function esm_or(e){return esm_l.str(e)&&(e[0]=="#"||/\d/.test(e)||!esm_h()&&esm_b.test(e)||e in(esm_c||{}))}var esm_v,q=new WeakMap,Ze=e=>e.forEach(({target:t,contentRect:r})=>q.get(t)?.forEach(n=>n(r)));function Fe(e,t){esm_v||typeof ResizeObserver<"u"&&(esm_v=new ResizeObserver(Ze));let r=q.get(t);return r||(r=new Set,q.set(t,r)),r.add(e),esm_v&&esm_v.observe(t),()=>{let n=q.get(t);!n||(n.delete(e),!n.size&&esm_v&&esm_v.unobserve(t))}}var $=new Set,esm_w,Xe=()=>{let e=()=>{$.forEach(t=>t({width:window.innerWidth,height:window.innerHeight}))};return window.addEventListener("resize",e),()=>{window.removeEventListener("resize",e)}},Ie=e=>($.add(e),esm_w||(esm_w=Xe()),()=>{$.delete(e),!$.size&&esm_w&&(esm_w(),esm_w=void 0)});var ke=(e,{container:t=document.documentElement}={})=>t===document.documentElement?Ie(e):Fe(e,t);var Se=(e,t,r)=>t-e===0?1:(r-e)/(t-e);var Ye={x:{length:"Width",position:"Left"},y:{length:"Height",position:"Top"}},esm_G=class{callback;container;info;constructor(t,r){this.callback=t,this.container=r,this.info={time:0,x:this.createAxis(),y:this.createAxis()}}createAxis=()=>({current:0,progress:0,scrollLength:0});updateAxis=t=>{let r=this.info[t],{length:n,position:f}=Ye[t];r.current=this.container[`scroll${f}`],r.scrollLength=this.container["scroll"+n]-this.container["client"+n],r.progress=Se(0,r.scrollLength,r.current)};update=()=>{this.updateAxis("x"),this.updateAxis("y")};sendEvent=()=>{this.callback(this.info)};advance=()=>{this.update(),this.sendEvent()}};var esm_T=new WeakMap,Ae=new WeakMap,X=new WeakMap,Me=e=>e===document.documentElement?window:e,yr=(e,{container:t=document.documentElement}={})=>{let r=X.get(t);r||(r=new Set,X.set(t,r));let n=new esm_G(e,t);if(r.add(n),!esm_T.has(t)){let o=()=>(r?.forEach(s=>s.advance()),!0);esm_T.set(t,o);let i=Me(t);window.addEventListener("resize",o,{passive:!0}),t!==document.documentElement&&Ae.set(t,ke(o,{container:t})),i.addEventListener("scroll",o,{passive:!0})}let f=esm_T.get(t);return Re(f),()=>{Re.cancel(f);let o=X.get(t);if(!o||(o.delete(n),o.size))return;let i=esm_T.get(t);esm_T.delete(t),i&&(Me(t).removeEventListener("scroll",i),window.removeEventListener("resize",i),Ae.get(t)?.())}};function Er(e){let t=Je(null);return t.current===null&&(t.current=e()),t.current}var esm_Q=esm_h()?external_React_.useEffect:external_React_.useLayoutEffect;var Ce=()=>{let e=(0,external_React_.useRef)(!1);return esm_Q(()=>(e.current=!0,()=>{e.current=!1}),[]),e};function Mr(){let e=(0,external_React_.useState)()[1],t=Ce();return()=>{t.current&&e(Math.random())}}function Lr(e,t){let[r]=(0,external_React_.useState)(()=>({inputs:t,result:e()})),n=(0,external_React_.useRef)(),f=n.current,o=f;return o?Boolean(t&&o.inputs&&it(t,o.inputs))||(o={inputs:t,result:e()}):o=r,(0,external_React_.useEffect)(()=>{n.current=o,f==r&&(r.inputs=r.result=void 0)},[o]),o.result}function it(e,t){if(e.length!==t.length)return!1;for(let r=0;r(0,external_React_.useEffect)(e,ut),ut=[];function Ur(e){let t=(0,external_React_.useRef)();return (0,external_React_.useEffect)(()=>{t.current=e}),t.current}var Wr=()=>{let[e,t]=dt(null);return esm_Q(()=>{let r=window.matchMedia("(prefers-reduced-motion)"),n=f=>{t(f.matches),U({skipAnimation:f.matches})};return n(r),r.addEventListener("change",n),()=>{r.removeEventListener("change",n)}},[]),e};
;// CONCATENATED MODULE: ./node_modules/@react-spring/animated/dist/esm/index.js
var dist_esm_h=Symbol.for("Animated:node"),dist_esm_v=e=>!!e&&e[dist_esm_h]===e,esm_k=e=>e&&e[dist_esm_h],esm_D=(e,t)=>mt(e,dist_esm_h,t),F=e=>e&&e[dist_esm_h]&&e[dist_esm_h].getPayload(),dist_esm_c=class{payload;constructor(){esm_D(this,this)}getPayload(){return this.payload||[]}};var dist_esm_l=class extends dist_esm_c{constructor(r){super();this._value=r;esm_l.num(this._value)&&(this.lastPosition=this._value)}done=!0;elapsedTime;lastPosition;lastVelocity;v0;durationProgress=0;static create(r){return new dist_esm_l(r)}getPayload(){return[this]}getValue(){return this._value}setValue(r,n){return esm_l.num(r)&&(this.lastPosition=r,n&&(r=Math.round(r/n)*n,this.done&&(this.lastPosition=r))),this._value===r?!1:(this._value=r,!0)}reset(){let{done:r}=this;this.done=!1,esm_l.num(this._value)&&(this.elapsedTime=0,this.durationProgress=0,this.lastPosition=this._value,r&&(this.lastVelocity=null),this.v0=null)}};var dist_esm_d=class extends dist_esm_l{_string=null;_toString;constructor(t){super(0),this._toString=W({output:[t,t]})}static create(t){return new dist_esm_d(t)}getValue(){let t=this._string;return t??(this._string=this._toString(this._value))}setValue(t){if(esm_l.str(t)){if(t==this._string)return!1;this._string=t,this._value=1}else if(super.setValue(t))this._string=null;else return!1;return!0}reset(t){t&&(this._toString=W({output:[this.getValue(),t]})),this._value=0,super.reset()}};var esm_f={dependencies:null};var dist_esm_u=class extends dist_esm_c{constructor(r){super();this.source=r;this.setValue(r)}getValue(r){let n={};return xt(this.source,(a,i)=>{dist_esm_v(a)?n[i]=a.getValue(r):Pt(a)?n[i]=ve(a):r||(n[i]=a)}),n}setValue(r){this.source=r,this.payload=this._makePayload(r)}reset(){this.payload&&Ve(this.payload,r=>r.reset())}_makePayload(r){if(r){let n=new Set;return xt(r,this._addToPayload,n),Array.from(n)}}_addToPayload(r){esm_f.dependencies&&Pt(r)&&esm_f.dependencies.add(r);let n=F(r);n&&Ve(n,a=>this.add(a))}};var dist_esm_y=class extends dist_esm_u{constructor(t){super(t)}static create(t){return new dist_esm_y(t)}getValue(){return this.source.map(t=>t.getValue())}setValue(t){let r=this.getPayload();return t.length==r.length?r.map((n,a)=>n.setValue(t[a])).some(Boolean):(super.setValue(t.map(esm_z)),!0)}};function esm_z(e){return(esm_or(e)?dist_esm_d:dist_esm_l).create(e)}function esm_Le(e){let t=esm_k(e);return t?t.constructor:esm_l.arr(e)?dist_esm_y:esm_or(e)?dist_esm_d:dist_esm_l}var esm_x=(e,t)=>{let r=!esm_l.fun(e)||e.prototype&&e.prototype.isReactComponent;return (0,external_React_.forwardRef)((n,a)=>{let i=(0,external_React_.useRef)(null),o=r&&(0,external_React_.useCallback)(s=>{i.current=esm_ae(a,s)},[a]),[m,T]=esm_ne(n,t),W=Mr(),P=()=>{let s=i.current;if(r&&!s)return;(s?t.applyAnimatedValues(s,m.getValue(!0)):!1)===!1&&W()},_=new dist_esm_b(P,T),p=(0,external_React_.useRef)();esm_Q(()=>(p.current=_,Ve(T,s=>Gt(s,_)),()=>{p.current&&(Ve(p.current.deps,s=>Qt(s,p.current)),esm_n.cancel(p.current.update))})),(0,external_React_.useEffect)(P,[]),$r(()=>()=>{let s=p.current;Ve(s.deps,S=>Qt(S,s))});let $=t.getComponentProps(m.getValue());return external_React_.createElement(e,{...$,ref:o})})},dist_esm_b=class{constructor(t,r){this.update=t;this.deps=r}eventObserved(t){t.type=="change"&&esm_n.write(this.update)}};function esm_ne(e,t){let r=new Set;return esm_f.dependencies=r,e.style&&(e={...e,style:t.createAnimatedStyle(e.style)}),e=new dist_esm_u(e),esm_f.dependencies=null,[e,r]}function esm_ae(e,t){return e&&(esm_l.fun(e)?e(t):e.current=t),t}var dist_esm_j=Symbol.for("AnimatedComponent"),esm_Ke=(e,{applyAnimatedValues:t=()=>!1,createAnimatedStyle:r=a=>new dist_esm_u(a),getComponentProps:n=a=>a}={})=>{let a={applyAnimatedValues:t,createAnimatedStyle:r,getComponentProps:n},i=o=>{let m=I(o)||"Anonymous";return esm_l.str(o)?o=i[o]||(i[o]=esm_x(o,a)):o=o[dist_esm_j]||(o[dist_esm_j]=esm_x(o,a)),o.displayName=`Animated(${m})`,o};return xt(e,(o,m)=>{esm_l.arr(e)&&(m=I(o)),i[m]=i(o)}),{animated:i}},I=e=>esm_l.str(e)?e:e&&esm_l.str(e.displayName)?e.displayName:esm_l.fun(e)&&e.name||null;
;// CONCATENATED MODULE: ./node_modules/@react-spring/core/dist/esm/index.js
function esm_I(t,...e){return esm_l.fun(t)?t(...e):t}var esm_te=(t,e)=>t===!0||!!(e&&t&&(esm_l.fun(t)?t(e):ht(t).includes(e))),et=(t,e)=>esm_l.obj(t)?e&&t[e]:t;var esm_ke=(t,e)=>t.default===!0?t[e]:t.default?t.default[e]:void 0,nn=t=>t,dist_esm_ne=(t,e=nn)=>{let n=rn;t.default&&t.default!==!0&&(t=t.default,n=Object.keys(t));let r={};for(let o of n){let s=e(t[o],o);esm_l.und(s)||(r[o]=s)}return r},rn=["config","onProps","onStart","onChange","onPause","onResume","onRest"],on={config:1,from:1,to:1,ref:1,loop:1,reset:1,pause:1,cancel:1,reverse:1,immediate:1,default:1,delay:1,onProps:1,onStart:1,onChange:1,onPause:1,onResume:1,onRest:1,onResolve:1,items:1,trail:1,sort:1,expires:1,initial:1,enter:1,update:1,leave:1,children:1,onDestroyed:1,keys:1,callId:1,parentId:1};function sn(t){let e={},n=0;if(xt(t,(r,o)=>{on[o]||(e[o]=r,n++)}),n)return e}function esm_de(t){let e=sn(t);if(e){let n={to:e};return xt(t,(r,o)=>o in e||(n[o]=r)),n}return{...t}}function esm_me(t){return t=ve(t),esm_l.arr(t)?t.map(esm_me):esm_or(t)?esm_p.createStringInterpolator({range:[0,1],output:[t,t]})(1):t}function esm_Ue(t){for(let e in t)return!0;return!1}function esm_Ee(t){return esm_l.fun(t)||esm_l.arr(t)&&esm_l.obj(t[0])}function esm_xe(t,e){t.ref?.delete(t),e?.delete(t)}function esm_he(t,e){e&&t.ref!==e&&(t.ref?.delete(t),e.add(t),t.ref=e)}function wr(t,e,n=1e3){an(()=>{if(e){let r=0;ge(t,(o,s)=>{let a=o.current;if(a.length){let i=n*e[s];isNaN(i)?i=r:r=i,ge(a,u=>{ge(u.queue,p=>{let f=p.delay;p.delay=d=>i+esm_I(f||0,d)})}),o.start()}})}else{let r=Promise.resolve();ge(t,o=>{let s=o.current;if(s.length){let a=s.map(i=>{let u=i.queue;return i.queue=[],u});r=r.then(()=>(ge(s,(i,u)=>ge(a[u]||[],p=>i.queue.push(p))),Promise.all(o.start())))}})}})}var esm_mt={default:{tension:170,friction:26},gentle:{tension:120,friction:14},wobbly:{tension:180,friction:12},stiff:{tension:210,friction:20},slow:{tension:280,friction:60},molasses:{tension:280,friction:120}};var tt={...esm_mt.default,mass:1,damping:1,easing:Lt.linear,clamp:!1},esm_we=class{tension;friction;frequency;damping;mass;velocity=0;restVelocity;precision;progress;duration;easing;clamp;bounce;decay;round;constructor(){Object.assign(this,tt)}};function gt(t,e,n){n&&(n={...n},esm_ht(n,e),e={...n,...e}),esm_ht(t,e),Object.assign(t,e);for(let a in tt)t[a]==null&&(t[a]=tt[a]);let{mass:r,frequency:o,damping:s}=t;return esm_l.und(o)||(o<.01&&(o=.01),s<0&&(s=0),t.tension=Math.pow(2*Math.PI/o,2)*r,t.friction=4*Math.PI*s*r/o),t}function esm_ht(t,e){if(!esm_l.und(e.decay))t.duration=void 0;else{let n=!esm_l.und(e.tension)||!esm_l.und(e.friction);(n||!esm_l.und(e.frequency)||!esm_l.und(e.damping)||!esm_l.und(e.mass))&&(t.duration=void 0,t.decay=void 0),n&&(t.frequency=void 0)}}var esm_yt=[],dist_esm_Le=class{changed=!1;values=esm_yt;toValues=null;fromValues=esm_yt;to;from;config=new esm_we;immediate=!1};function esm_Me(t,{key:e,props:n,defaultProps:r,state:o,actions:s}){return new Promise((a,i)=>{let u,p,f=esm_te(n.cancel??r?.cancel,e);if(f)b();else{esm_l.und(n.pause)||(o.paused=esm_te(n.pause,e));let c=r?.pause;c!==!0&&(c=o.paused||esm_te(c,e)),u=esm_I(n.delay||0,e),c?(o.resumeQueue.add(m),s.pause()):(s.resume(),m())}function d(){o.resumeQueue.add(m),o.timeouts.delete(p),p.cancel(),u=p.time-esm_n.now()}function m(){u>0&&!esm_p.skipAnimation?(o.delayed=!0,p=esm_n.setTimeout(b,u),o.pauseQueue.add(d),o.timeouts.add(p)):b()}function b(){o.delayed&&(o.delayed=!1),o.pauseQueue.delete(d),o.timeouts.delete(p),t<=(o.cancelId||0)&&(f=!0);try{s.start({...n,callId:t,cancel:f},a)}catch(c){i(c)}}})}var esm_be=(t,e)=>e.length==1?e[0]:e.some(n=>n.cancelled)?esm_q(t.get()):e.every(n=>n.noop)?nt(t.get()):esm_E(t.get(),e.every(n=>n.finished)),nt=t=>({value:t,noop:!0,finished:!0,cancelled:!1}),esm_E=(t,e,n=!1)=>({value:t,finished:e,cancelled:n}),esm_q=t=>({value:t,cancelled:!0,finished:!1});function esm_De(t,e,n,r){let{callId:o,parentId:s,onRest:a}=e,{asyncTo:i,promise:u}=n;return!s&&t===i&&!e.reset?u:n.promise=(async()=>{n.asyncId=o,n.asyncTo=t;let p=dist_esm_ne(e,(l,h)=>h==="onRest"?void 0:l),f,d,m=new Promise((l,h)=>(f=l,d=h)),b=l=>{let h=o<=(n.cancelId||0)&&esm_q(r)||o!==n.asyncId&&esm_E(r,!1);if(h)throw l.result=h,d(l),l},c=(l,h)=>{let g=new esm_Ae,x=new esm_Ne;return(async()=>{if(esm_p.skipAnimation)throw esm_oe(n),x.result=esm_E(r,!1),d(x),x;b(g);let S=esm_l.obj(l)?{...l}:{...h,to:l};S.parentId=o,xt(p,(V,_)=>{esm_l.und(S[_])&&(S[_]=V)});let A=await r.start(S);return b(g),n.paused&&await new Promise(V=>{n.resumeQueue.add(V)}),A})()},P;if(esm_p.skipAnimation)return esm_oe(n),esm_E(r,!1);try{let l;esm_l.arr(t)?l=(async h=>{for(let g of h)await c(g)})(t):l=Promise.resolve(t(c,r.stop.bind(r))),await Promise.all([l.then(f),m]),P=esm_E(r.get(),!0,!1)}catch(l){if(l instanceof esm_Ae)P=l.result;else if(l instanceof esm_Ne)P=l.result;else throw l}finally{o==n.asyncId&&(n.asyncId=s,n.asyncTo=s?i:void 0,n.promise=s?u:void 0)}return esm_l.fun(a)&&esm_n.batchedUpdates(()=>{a(P,r,r.item)}),P})()}function esm_oe(t,e){Pe(t.timeouts,n=>n.cancel()),t.pauseQueue.clear(),t.resumeQueue.clear(),t.asyncId=t.asyncTo=t.promise=void 0,e&&(t.cancelId=e)}var esm_Ae=class extends Error{result;constructor(){super("An async animation has been interrupted. You see this error because you forgot to use `await` or `.catch(...)` on its returned promise.")}},esm_Ne=class extends Error{result;constructor(){super("SkipAnimationSignal")}};var esm_Re=t=>t instanceof esm_X,Sn=1,esm_X=class extends esm_ge{id=Sn++;_priority=0;get priority(){return this._priority}set priority(e){this._priority!=e&&(this._priority=e,this._onPriorityChange(e))}get(){let e=esm_k(this);return e&&e.getValue()}to(...e){return esm_p.to(this,e)}interpolate(...e){return Jt(),esm_p.to(this,e)}toJSON(){return this.get()}observerAdded(e){e==1&&this._attach()}observerRemoved(e){e==0&&this._detach()}_attach(){}_detach(){}_onChange(e,n=!1){$t(this,{type:"change",parent:this,value:e,idle:n})}_onPriorityChange(e){this.idle||qe.sort(this),$t(this,{type:"priority",parent:this,priority:e})}};var esm_se=Symbol.for("SpringPhase"),esm_bt=1,rt=2,ot=4,esm_qe=t=>(t[esm_se]&esm_bt)>0,dist_esm_Q=t=>(t[esm_se]&rt)>0,esm_ye=t=>(t[esm_se]&ot)>0,st=(t,e)=>e?t[esm_se]|=rt|esm_bt:t[esm_se]&=~rt,esm_it=(t,e)=>e?t[esm_se]|=ot:t[esm_se]&=~ot;var esm_ue=class extends esm_X{key;animation=new dist_esm_Le;queue;defaultProps={};_state={paused:!1,delayed:!1,pauseQueue:new Set,resumeQueue:new Set,timeouts:new Set};_pendingCalls=new Set;_lastCallId=0;_lastToId=0;_memoizedDuration=0;constructor(e,n){if(super(),!esm_l.und(e)||!esm_l.und(n)){let r=esm_l.obj(e)?{...e}:{...n,from:e};esm_l.und(r.default)&&(r.default=!0),this.start(r)}}get idle(){return!(dist_esm_Q(this)||this._state.asyncTo)||esm_ye(this)}get goal(){return ve(this.animation.to)}get velocity(){let e=esm_k(this);return e instanceof dist_esm_l?e.lastVelocity||0:e.getPayload().map(n=>n.lastVelocity||0)}get hasAnimated(){return esm_qe(this)}get isAnimating(){return dist_esm_Q(this)}get isPaused(){return esm_ye(this)}get isDelayed(){return this._state.delayed}advance(e){let n=!0,r=!1,o=this.animation,{config:s,toValues:a}=o,i=F(o.to);!i&&Pt(o.to)&&(a=ht(ve(o.to))),o.values.forEach((f,d)=>{if(f.done)return;let m=f.constructor==dist_esm_d?1:i?i[d].lastPosition:a[d],b=o.immediate,c=m;if(!b){if(c=f.lastPosition,s.tension<=0){f.done=!0;return}let P=f.elapsedTime+=e,l=o.fromValues[d],h=f.v0!=null?f.v0:f.v0=esm_l.arr(s.velocity)?s.velocity[d]:s.velocity,g,x=s.precision||(l==m?.005:Math.min(1,Math.abs(m-l)*.001));if(esm_l.und(s.duration))if(s.decay){let S=s.decay===!0?.998:s.decay,A=Math.exp(-(1-S)*P);c=l+h/(1-S)*(1-A),b=Math.abs(f.lastPosition-c)<=x,g=h*A}else{g=f.lastVelocity==null?h:f.lastVelocity;let S=s.restVelocity||x/10,A=s.clamp?0:s.bounce,V=!esm_l.und(A),_=l==m?f.v0>0:lS,!(!v&&(b=Math.abs(m-c)<=x,b)));++L){V&&(w=c==m||c>m==_,w&&(g=-g*A,c=m));let N=-s.tension*1e-6*(c-m),y=-s.friction*.001*g,T=(N+y)/s.mass;g=g+T*C,c=c+g*C}}else{let S=1;s.duration>0&&(this._memoizedDuration!==s.duration&&(this._memoizedDuration=s.duration,f.durationProgress>0&&(f.elapsedTime=s.duration*f.durationProgress,P=f.elapsedTime+=e)),S=(s.progress||0)+P/this._memoizedDuration,S=S>1?1:S<0?0:S,f.durationProgress=S),c=l+s.easing(S)*(m-l),g=(c-f.lastPosition)/e,b=S==1}f.lastVelocity=g,Number.isNaN(c)&&(console.warn("Got NaN while animating:",this),b=!0)}i&&!i[d].done&&(b=!1),b?f.done=!0:n=!1,f.setValue(c,s.round)&&(r=!0)});let u=esm_k(this),p=u.getValue();if(n){let f=ve(o.to);(p!==f||r)&&!s.decay?(u.setValue(f),this._onChange(f)):r&&s.decay&&this._onChange(p),this._stop()}else r&&this._onChange(p)}set(e){return esm_n.batchedUpdates(()=>{this._stop(),this._focus(e),this._set(e)}),this}pause(){this._update({pause:!0})}resume(){this._update({pause:!1})}finish(){if(dist_esm_Q(this)){let{to:e,config:n}=this.animation;esm_n.batchedUpdates(()=>{this._onStart(),n.decay||this._set(e,!1),this._stop()})}return this}update(e){return(this.queue||(this.queue=[])).push(e),this}start(e,n){let r;return esm_l.und(e)?(r=this.queue||[],this.queue=[]):r=[esm_l.obj(e)?e:{...n,to:e}],Promise.all(r.map(o=>this._update(o))).then(o=>esm_be(this,o))}stop(e){let{to:n}=this.animation;return this._focus(this.get()),esm_oe(this._state,e&&this._lastCallId),esm_n.batchedUpdates(()=>this._stop(n,e)),this}reset(){this._update({reset:!0})}eventObserved(e){e.type=="change"?this._start():e.type=="priority"&&(this.priority=e.priority+1)}_prepareNode(e){let n=this.key||"",{to:r,from:o}=e;r=esm_l.obj(r)?r[n]:r,(r==null||esm_Ee(r))&&(r=void 0),o=esm_l.obj(o)?o[n]:o,o==null&&(o=void 0);let s={to:r,from:o};return esm_qe(this)||(e.reverse&&([r,o]=[o,r]),o=ve(o),esm_l.und(o)?esm_k(this)||this._set(r):this._set(o)),s}_update({...e},n){let{key:r,defaultProps:o}=this;e.default&&Object.assign(o,dist_esm_ne(e,(i,u)=>/^on/.test(u)?et(i,r):i)),_t(this,e,"onProps"),esm_Ie(this,"onProps",e,this);let s=this._prepareNode(e);if(Object.isFrozen(this))throw Error("Cannot animate a `SpringValue` object that is frozen. Did you forget to pass your component to `animated(...)` before animating its props?");let a=this._state;return esm_Me(++this._lastCallId,{key:r,props:e,defaultProps:o,state:a,actions:{pause:()=>{esm_ye(this)||(esm_it(this,!0),yt(a.pauseQueue),esm_Ie(this,"onPause",esm_E(this,esm_Ce(this,this.animation.to)),this))},resume:()=>{esm_ye(this)&&(esm_it(this,!1),dist_esm_Q(this)&&this._resume(),yt(a.resumeQueue),esm_Ie(this,"onResume",esm_E(this,esm_Ce(this,this.animation.to)),this))},start:this._merge.bind(this,s)}}).then(i=>{if(e.loop&&i.finished&&!(n&&i.noop)){let u=at(e);if(u)return this._update(u,!0)}return i})}_merge(e,n,r){if(n.cancel)return this.stop(!0),r(esm_q(this));let o=!esm_l.und(e.to),s=!esm_l.und(e.from);if(o||s)if(n.callId>this._lastToId)this._lastToId=n.callId;else return r(esm_q(this));let{key:a,defaultProps:i,animation:u}=this,{to:p,from:f}=u,{to:d=p,from:m=f}=e;s&&!o&&(!n.default||esm_l.und(d))&&(d=m),n.reverse&&([d,m]=[m,d]);let b=!bt(m,f);b&&(u.from=m),m=ve(m);let c=!bt(d,p);c&&this._focus(d);let P=esm_Ee(n.to),{config:l}=u,{decay:h,velocity:g}=l;(o||s)&&(l.velocity=0),n.config&&!P&>(l,esm_I(n.config,a),n.config!==i.config?esm_I(i.config,a):void 0);let x=esm_k(this);if(!x||esm_l.und(d))return r(esm_E(this,!0));let S=esm_l.und(n.reset)?s&&!n.default:!esm_l.und(m)&&esm_te(n.reset,a),A=S?m:this.get(),V=esm_me(d),_=esm_l.num(V)||esm_l.arr(V)||esm_or(V),v=!P&&(!_||esm_te(i.immediate||n.immediate,a));if(c){let L=esm_Le(d);if(L!==x.constructor)if(v)x=this._set(V);else throw Error(`Cannot animate between ${x.constructor.name} and ${L.name}, as the "to" prop suggests`)}let w=x.constructor,C=Pt(d),$=!1;if(!C){let L=S||!esm_qe(this)&&b;(c||L)&&($=bt(esm_me(A),V),C=!$),(!bt(u.immediate,v)&&!v||!bt(l.decay,h)||!bt(l.velocity,g))&&(C=!0)}if($&&dist_esm_Q(this)&&(u.changed&&!S?C=!0:C||this._stop(p)),!P&&((C||Pt(p))&&(u.values=x.getPayload(),u.toValues=Pt(d)?null:w==dist_esm_d?[1]:ht(V)),u.immediate!=v&&(u.immediate=v,!v&&!S&&this._set(p)),C)){let{onRest:L}=u;Ve(_n,y=>_t(this,n,y));let N=esm_E(this,esm_Ce(this,p));yt(this._pendingCalls,N),this._pendingCalls.add(r),u.changed&&esm_n.batchedUpdates(()=>{u.changed=!S,L?.(N,this),S?esm_I(i.onRest,N):u.onStart?.(N,this)})}S&&this._set(A),P?r(esm_De(n.to,n,this._state,this)):C?this._start():dist_esm_Q(this)&&!c?this._pendingCalls.add(r):r(nt(A))}_focus(e){let n=this.animation;e!==n.to&&(esm_qt(this)&&this._detach(),n.to=e,esm_qt(this)&&this._attach())}_attach(){let e=0,{to:n}=this.animation;Pt(n)&&(Gt(n,this),esm_Re(n)&&(e=n.priority+1)),this.priority=e}_detach(){let{to:e}=this.animation;Pt(e)&&Qt(e,this)}_set(e,n=!0){let r=ve(e);if(!esm_l.und(r)){let o=esm_k(this);if(!o||!bt(r,o.getValue())){let s=esm_Le(r);!o||o.constructor!=s?esm_D(this,s.create(r)):o.setValue(r),o&&esm_n.batchedUpdates(()=>{this._onChange(r,n)})}}return esm_k(this)}_onStart(){let e=this.animation;e.changed||(e.changed=!0,esm_Ie(this,"onStart",esm_E(this,esm_Ce(this,e.to)),this))}_onChange(e,n){n||(this._onStart(),esm_I(this.animation.onChange,e,this)),esm_I(this.defaultProps.onChange,e,this),super._onChange(e,n)}_start(){let e=this.animation;esm_k(this).reset(ve(e.to)),e.immediate||(e.fromValues=e.values.map(n=>n.lastPosition)),dist_esm_Q(this)||(st(this,!0),esm_ye(this)||this._resume())}_resume(){esm_p.skipAnimation?this.finish():qe.start(this)}_stop(e,n){if(dist_esm_Q(this)){st(this,!1);let r=this.animation;Ve(r.values,s=>{s.done=!0}),r.toValues&&(r.onChange=r.onPause=r.onResume=void 0),$t(this,{type:"idle",parent:this});let o=n?esm_q(this.get()):esm_E(this.get(),esm_Ce(this,e??r.to));yt(this._pendingCalls,o),r.changed&&(r.changed=!1,esm_Ie(this,"onRest",o,this))}}};function esm_Ce(t,e){let n=esm_me(e),r=esm_me(t.get());return bt(r,n)}function at(t,e=t.loop,n=t.to){let r=esm_I(e);if(r){let o=r!==!0&&esm_de(r),s=(o||t).reverse,a=!o||o.reset;return esm_Pe({...t,loop:e,default:!1,pause:void 0,to:!s||esm_Ee(n)?n:void 0,from:a?t.from:void 0,reset:a,...o})}}function esm_Pe(t){let{to:e,from:n}=t=esm_de(t),r=new Set;return esm_l.obj(e)&&Vt(e,r),esm_l.obj(n)&&Vt(n,r),t.keys=r.size?Array.from(r):null,t}function Ot(t){let e=esm_Pe(t);return esm_l.und(e.default)&&(e.default=dist_esm_ne(e)),e}function Vt(t,e){xt(t,(n,r)=>n!=null&&e.add(r))}var _n=["onStart","onRest","onChange","onPause","onResume"];function _t(t,e,n){t.animation[n]=e[n]!==esm_ke(e,n)?et(e[n],t.key):void 0}function esm_Ie(t,e,...n){t.animation[e]?.(...n),t.defaultProps[e]?.(...n)}var Fn=["onStart","onChange","onRest"],kn=1,esm_le=class{id=kn++;springs={};queue=[];ref;_flush;_initialProps;_lastAsyncId=0;_active=new Set;_changed=new Set;_started=!1;_item;_state={paused:!1,pauseQueue:new Set,resumeQueue:new Set,timeouts:new Set};_events={onStart:new Map,onChange:new Map,onRest:new Map};constructor(e,n){this._onFrame=this._onFrame.bind(this),n&&(this._flush=n),e&&this.start({default:!0,...e})}get idle(){return!this._state.asyncTo&&Object.values(this.springs).every(e=>e.idle&&!e.isDelayed&&!e.isPaused)}get item(){return this._item}set item(e){this._item=e}get(){let e={};return this.each((n,r)=>e[r]=n.get()),e}set(e){for(let n in e){let r=e[n];esm_l.und(r)||this.springs[n].set(r)}}update(e){return e&&this.queue.push(esm_Pe(e)),this}start(e){let{queue:n}=this;return e?n=ht(e).map(esm_Pe):this.queue=[],this._flush?this._flush(this,n):(jt(this,n),esm_ze(this,n))}stop(e,n){if(e!==!!e&&(n=e),n){let r=this.springs;Ve(ht(n),o=>r[o].stop(!!e))}else esm_oe(this._state,this._lastAsyncId),this.each(r=>r.stop(!!e));return this}pause(e){if(esm_l.und(e))this.start({pause:!0});else{let n=this.springs;Ve(ht(e),r=>n[r].pause())}return this}resume(e){if(esm_l.und(e))this.start({pause:!1});else{let n=this.springs;Ve(ht(e),r=>n[r].resume())}return this}each(e){xt(this.springs,e)}_onFrame(){let{onStart:e,onChange:n,onRest:r}=this._events,o=this._active.size>0,s=this._changed.size>0;(o&&!this._started||s&&!this._started)&&(this._started=!0,Pe(e,([u,p])=>{p.value=this.get(),u(p,this,this._item)}));let a=!o&&this._started,i=s||a&&r.size?this.get():null;s&&n.size&&Pe(n,([u,p])=>{p.value=i,u(p,this,this._item)}),a&&(this._started=!1,Pe(r,([u,p])=>{p.value=i,u(p,this,this._item)}))}eventObserved(e){if(e.type=="change")this._changed.add(e.parent),e.idle||this._active.add(e.parent);else if(e.type=="idle")this._active.delete(e.parent);else return;esm_n.onFrame(this._onFrame)}};function esm_ze(t,e){return Promise.all(e.map(n=>wt(t,n))).then(n=>esm_be(t,n))}async function wt(t,e,n){let{keys:r,to:o,from:s,loop:a,onRest:i,onResolve:u}=e,p=esm_l.obj(e.default)&&e.default;a&&(e.loop=!1),o===!1&&(e.to=null),s===!1&&(e.from=null);let f=esm_l.arr(o)||esm_l.fun(o)?o:void 0;f?(e.to=void 0,e.onRest=void 0,p&&(p.onRest=void 0)):Ve(Fn,P=>{let l=e[P];if(esm_l.fun(l)){let h=t._events[P];e[P]=({finished:g,cancelled:x})=>{let S=h.get(l);S?(g||(S.finished=!1),x&&(S.cancelled=!0)):h.set(l,{value:null,finished:g||!1,cancelled:x||!1})},p&&(p[P]=e[P])}});let d=t._state;e.pause===!d.paused?(d.paused=e.pause,yt(e.pause?d.pauseQueue:d.resumeQueue)):d.paused&&(e.pause=!0);let m=(r||Object.keys(t.springs)).map(P=>t.springs[P].start(e)),b=e.cancel===!0||esm_ke(e,"cancel")===!0;(f||b&&d.asyncId)&&m.push(esm_Me(++t._lastAsyncId,{props:e,state:d,actions:{pause:Y,resume:Y,start(P,l){b?(esm_oe(d,t._lastAsyncId),l(esm_q(t))):(P.onRest=i,l(esm_De(f,P,d,t)))}}})),d.paused&&await new Promise(P=>{d.resumeQueue.add(P)});let c=esm_be(t,await Promise.all(m));if(a&&c.finished&&!(n&&c.noop)){let P=at(e,a,o);if(P)return jt(t,[P]),wt(t,P,!0)}return u&&esm_n.batchedUpdates(()=>u(c,t,t.item)),c}function esm_e(t,e){let n={...t.springs};return e&&Ve(ht(e),r=>{esm_l.und(r.keys)&&(r=esm_Pe(r)),esm_l.obj(r.to)||(r={...r,to:void 0}),Mt(n,r,o=>esm_Lt(o))}),pt(t,n),n}function pt(t,e){xt(e,(n,r)=>{t.springs[r]||(t.springs[r]=n,Gt(n,t))})}function esm_Lt(t,e){let n=new esm_ue;return n.key=t,e&&Gt(n,e),n}function Mt(t,e,n){e.keys&&Ve(e.keys,r=>{(t[r]||(t[r]=n(r)))._prepareNode(e)})}function jt(t,e){Ve(e,n=>{Mt(t.springs,n,r=>esm_Lt(r,t))})}var esm_H=({children:t,...e})=>{let n=(0,external_React_.useContext)(esm_Ge),r=e.pause||!!n.pause,o=e.immediate||!!n.immediate;e=Lr(()=>({pause:r,immediate:o}),[r,o]);let{Provider:s}=esm_Ge;return external_React_.createElement(s,{value:e},t)},esm_Ge=wn(esm_H,{});esm_H.Provider=esm_Ge.Provider;esm_H.Consumer=esm_Ge.Consumer;function wn(t,e){return Object.assign(t,external_React_.createContext(e)),t.Provider._context=t,t.Consumer._context=t,t}var esm_fe=()=>{let t=[],e=function(r){er();let o=[];return Ve(t,(s,a)=>{if(esm_l.und(r))o.push(s.start());else{let i=n(r,s,a);i&&o.push(s.start(i))}}),o};e.current=t,e.add=function(r){t.includes(r)||t.push(r)},e.delete=function(r){let o=t.indexOf(r);~o&&t.splice(o,1)},e.pause=function(){return Ve(t,r=>r.pause(...arguments)),this},e.resume=function(){return Ve(t,r=>r.resume(...arguments)),this},e.set=function(r){Ve(t,(o,s)=>{let a=esm_l.fun(r)?r(s,o):r;a&&o.set(a)})},e.start=function(r){let o=[];return Ve(t,(s,a)=>{if(esm_l.und(r))o.push(s.start());else{let i=this._getProps(r,s,a);i&&o.push(s.start(i))}}),o},e.stop=function(){return Ve(t,r=>r.stop(...arguments)),this},e.update=function(r){return Ve(t,(o,s)=>o.update(this._getProps(r,o,s))),this};let n=function(r,o,s){return esm_l.fun(r)?r(s,o):r};return e._getProps=n,e};function esm_He(t,e,n){let r=esm_l.fun(e)&&e;r&&!n&&(n=[]);let o=(0,external_React_.useMemo)(()=>r||arguments.length==3?esm_fe():void 0,[]),s=(0,external_React_.useRef)(0),a=Mr(),i=(0,external_React_.useMemo)(()=>({ctrls:[],queue:[],flush(h,g){let x=esm_e(h,g);return s.current>0&&!i.queue.length&&!Object.keys(x).some(A=>!h.springs[A])?esm_ze(h,g):new Promise(A=>{pt(h,x),i.queue.push(()=>{A(esm_ze(h,g))}),a()})}}),[]),u=(0,external_React_.useRef)([...i.ctrls]),p=[],f=Ur(t)||0;(0,external_React_.useMemo)(()=>{Ve(u.current.slice(t,f),h=>{esm_xe(h,o),h.stop(!0)}),u.current.length=t,d(f,t)},[t]),(0,external_React_.useMemo)(()=>{d(0,Math.min(f,t))},n);function d(h,g){for(let x=h;xesm_e(h,p[g])),b=(0,external_React_.useContext)(esm_H),c=Ur(b),P=b!==c&&esm_Ue(b);esm_Q(()=>{s.current++,i.ctrls=u.current;let{queue:h}=i;h.length&&(i.queue=[],Ve(h,g=>g())),Ve(u.current,(g,x)=>{o?.add(g),P&&g.start({default:b});let S=p[x];S&&(esm_he(g,S.ref),g.ref?g.queue.push(S):g.start(S))})}),$r(()=>()=>{Ve(i.ctrls,h=>h.stop(!0))});let l=m.map(h=>({...h}));return o?[l,o]:l}function esm_J(t,e){let n=esm_l.fun(t),[[r],o]=esm_He(1,n?t:[t],n?e||[]:e);return n||arguments.length==2?[r,o]:r}var Gn=()=>esm_fe(),Xo=()=>zn(Gn)[0];var Wo=(t,e)=>{let n=Bn(()=>new esm_ue(t,e));return Kn(()=>()=>{n.stop()}),n};function esm_Qt(t,e,n){let r=qt.fun(e)&&e;r&&!n&&(n=[]);let o=!0,s,a=esm_He(t,(i,u)=>{let p=r?r(i,u):e;return s=p.ref,o=o&&p.reverse,p},n||[{}]);if(Yn(()=>{Xn(a[1].current,(i,u)=>{let p=a[1].current[u+(o?1:-1)];if(esm_he(i,s),i.ref){p&&i.update({to:p.springs});return}p?i.start({to:p.springs}):i.start()})},n),r||arguments.length==3){let i=s??a[1];return i._getProps=(u,p,f)=>{let d=qt.fun(u)?u(f,p):u;if(d){let m=i.current[f+(d.reverse?1:-1)];return m&&(d.to=m.springs),d}},a}return a[0]}function esm_Gt(t,e,n){let r=G.fun(e)&&e,{reset:o,sort:s,trail:a=0,expires:i=!0,exitBeforeEnter:u=!1,onDestroyed:p,ref:f,config:d}=r?r():e,m=Jn(()=>r||arguments.length==3?esm_fe():void 0,[]),b=zt(t),c=[],P=lt(null),l=o?null:P.current;Je(()=>{P.current=c}),$n(()=>(j(c,y=>{m?.add(y.ctrl),y.ctrl.ref=m}),()=>{j(P.current,y=>{y.expired&&clearTimeout(y.expirationId),esm_xe(y.ctrl,m),y.ctrl.stop(!0)})}));let h=tr(b,r?r():e,l),g=o&&P.current||[];Je(()=>j(g,({ctrl:y,item:T,key:F})=>{esm_xe(y,m),esm_I(p,T,F)}));let x=[];if(l&&j(l,(y,T)=>{y.expired?(clearTimeout(y.expirationId),g.push(y)):(T=x[T]=h.indexOf(y.key),~T&&(c[T]=y))}),j(b,(y,T)=>{c[T]||(c[T]={key:h[T],item:y,phase:"mount",ctrl:new esm_le},c[T].ctrl.item=y)}),x.length){let y=-1,{leave:T}=r?r():e;j(x,(F,k)=>{let O=l[k];~F?(y=c.indexOf(O),c[y]={...O,item:b[F]}):T&&c.splice(++y,0,O)})}G.fun(s)&&c.sort((y,T)=>s(y.item,T.item));let S=-a,A=Wn(),V=dist_esm_ne(e),_=new Map,v=lt(new Map),w=lt(!1);j(c,(y,T)=>{let F=y.key,k=y.phase,O=r?r():e,U,D,Jt=esm_I(O.delay||0,F);if(k=="mount")U=O.enter,D="enter";else{let M=h.indexOf(F)<0;if(k!="leave")if(M)U=O.leave,D="leave";else if(U=O.update)D="update";else return;else if(!M)U=O.enter,D="enter";else return}if(U=esm_I(U,y.item,T),U=G.obj(U)?esm_de(U):{to:U},!U.config){let M=d||V.config;U.config=esm_I(M,y.item,T,D)}S+=a;let Z={...V,delay:Jt+S,ref:f,immediate:O.immediate,reset:!1,...U};if(D=="enter"&&G.und(Z.from)){let M=r?r():e,Te=G.und(M.initial)||l?M.from:M.initial;Z.from=esm_I(Te,y.item,T)}let{onResolve:Wt}=Z;Z.onResolve=M=>{esm_I(Wt,M);let Te=P.current,B=Te.find(Fe=>Fe.key===F);if(!!B&&!(M.cancelled&&B.phase!="update")&&B.ctrl.idle){let Fe=Te.every(ee=>ee.ctrl.idle);if(B.phase=="leave"){let ee=esm_I(i,B.item);if(ee!==!1){let Ze=ee===!0?0:ee;if(B.expired=!0,!Fe&&Ze>0){Ze<=2147483647&&(B.expirationId=setTimeout(A,Ze));return}}}Fe&&Te.some(ee=>ee.expired)&&(v.current.delete(B),u&&(w.current=!0),A())}};let ft=esm_e(y.ctrl,Z);D==="leave"&&u?v.current.set(y,{phase:D,springs:ft,payload:Z}):_.set(y,{phase:D,springs:ft,payload:Z})});let C=Hn(esm_H),$=Zn(C),L=C!==$&&esm_Ue(C);Je(()=>{L&&j(c,y=>{y.ctrl.start({default:C})})},[C]),j(_,(y,T)=>{if(v.current.size){let F=c.findIndex(k=>k.key===T.key);c.splice(F,1)}}),Je(()=>{j(v.current.size?v.current:_,({phase:y,payload:T},F)=>{let{ctrl:k}=F;F.phase=y,m?.add(k),L&&y=="enter"&&k.start({default:C}),T&&(esm_he(k,T.ref),(k.ref||m)&&!w.current?k.update(T):(k.start(T),w.current&&(w.current=!1)))})},o?void 0:n);let N=y=>Oe.createElement(Oe.Fragment,null,c.map((T,F)=>{let{springs:k}=_.get(T)||T.ctrl,O=y({...k},T.item,T,F);return O&&O.type?Oe.createElement(O.type,{...O.props,key:G.str(T.key)||G.num(T.key)?T.key:T.ctrl.id,ref:O.ref}):O}));return m?[N,m]:N}var esm_er=1;function tr(t,{key:e,keys:n=e},r){if(n===null){let o=new Set;return t.map(s=>{let a=r&&r.find(i=>i.item===s&&i.phase!=="leave"&&!o.has(i));return a?(o.add(a),a.key):esm_er++})}return G.und(n)?t:G.fun(n)?t.map(n):zt(n)}var hs=({container:t,...e}={})=>{let[n,r]=esm_J(()=>({scrollX:0,scrollY:0,scrollXProgress:0,scrollYProgress:0,...e}),[]);return or(()=>{let o=rr(({x:s,y:a})=>{r.start({scrollX:s.current,scrollXProgress:s.progress,scrollY:a.current,scrollYProgress:a.progress})},{container:t?.current||void 0});return()=>{nr(Object.values(n),s=>s.stop()),o()}},[]),n};var Ps=({container:t,...e})=>{let[n,r]=esm_J(()=>({width:0,height:0,...e}),[]);return ar(()=>{let o=sr(({width:s,height:a})=>{r.start({width:s,height:a,immediate:n.width.get()===0||n.height.get()===0})},{container:t?.current||void 0});return()=>{ir(Object.values(n),s=>s.stop()),o()}},[]),n};var cr={any:0,all:1};function Cs(t,e){let[n,r]=pr(!1),o=ur(),s=Bt.fun(t)&&t,a=s?s():{},{to:i={},from:u={},...p}=a,f=s?e:t,[d,m]=esm_J(()=>({from:u,...p}),[]);return lr(()=>{let b=o.current,{root:c,once:P,amount:l="any",...h}=f??{};if(!b||P&&n||typeof IntersectionObserver>"u")return;let g=new WeakMap,x=()=>(i&&m.start(i),r(!0),P?void 0:()=>{u&&m.start(u),r(!1)}),S=V=>{V.forEach(_=>{let v=g.get(_.target);if(_.isIntersecting!==Boolean(v))if(_.isIntersecting){let w=x();Bt.fun(w)?g.set(_.target,w):A.unobserve(_.target)}else v&&(v(),g.delete(_.target))})},A=new IntersectionObserver(S,{root:c&&c.current||void 0,threshold:typeof l=="number"||Array.isArray(l)?l:cr[l],...h});return A.observe(b),()=>A.unobserve(b)},[f]),s?[o,d]:[o,n]}function qs({children:t,...e}){return t(esm_J(e))}function Bs({items:t,children:e,...n}){let r=esm_Qt(t.length,n);return t.map((o,s)=>{let a=e(o,s);return fr.fun(a)?a(r[s]):a})}function Ys({items:t,children:e,...n}){return esm_Gt(t,n)(e)}var esm_W=class extends esm_X{constructor(n,r){super();this.source=n;this.calc=W(...r);let o=this._get(),s=esm_Le(o);esm_D(this,s.create(o))}key;idle=!0;calc;_active=new Set;advance(n){let r=this._get(),o=this.get();bt(r,o)||(esm_k(this).setValue(r),this._onChange(r,this.idle)),!this.idle&&Yt(this._active)&&ct(this)}_get(){let n=esm_l.arr(this.source)?this.source.map(ve):ht(ve(this.source));return this.calc(...n)}_start(){this.idle&&!Yt(this._active)&&(this.idle=!1,Ve(F(this),n=>{n.done=!1}),esm_p.skipAnimation?(esm_n.batchedUpdates(()=>this.advance()),ct(this)):qe.start(this))}_attach(){let n=1;Ve(ht(this.source),r=>{Pt(r)&&Gt(r,this),esm_Re(r)&&(r.idle||this._active.add(r),n=Math.max(n,r.priority+1))}),this.priority=n,this._start()}_detach(){Ve(ht(this.source),n=>{Pt(n)&&Qt(n,this)}),this._active.clear(),ct(this)}eventObserved(n){n.type=="change"?n.idle?this.advance():(this._active.add(n.parent),this._start()):n.type=="idle"?this._active.delete(n.parent):n.type=="priority"&&(this.priority=ht(this.source).reduce((r,o)=>Math.max(r,(esm_Re(o)?o.priority:0)+1),0))}};function vr(t){return t.idle!==!1}function Yt(t){return!t.size||Array.from(t).every(vr)}function ct(t){t.idle||(t.idle=!0,Ve(F(t),e=>{e.done=!0}),$t(t,{type:"idle",parent:t}))}var esm_ui=(t,...e)=>new esm_W(t,e),pi=(t,...e)=>(Cr(),new esm_W(t,e));esm_p.assign({createStringInterpolator:Xt,to:(t,e)=>new esm_W(t,e)});var di=qe.advance;
;// CONCATENATED MODULE: external "ReactDOM"
var external_ReactDOM_namespaceObject = window["ReactDOM"];
;// CONCATENATED MODULE: ./node_modules/@react-spring/web/dist/esm/index.js
var dist_esm_k=/^--/;function dist_esm_I(t,e){return e==null||typeof e=="boolean"||e===""?"":typeof e=="number"&&e!==0&&!dist_esm_k.test(t)&&!(web_dist_esm_c.hasOwnProperty(t)&&web_dist_esm_c[t])?e+"px":(""+e).trim()}var web_dist_esm_v={};function esm_V(t,e){if(!t.nodeType||!t.setAttribute)return!1;let r=t.nodeName==="filter"||t.parentNode&&t.parentNode.nodeName==="filter",{style:i,children:s,scrollTop:u,scrollLeft:l,viewBox:a,...n}=e,d=Object.values(n),m=Object.keys(n).map(o=>r||t.hasAttribute(o)?o:web_dist_esm_v[o]||(web_dist_esm_v[o]=o.replace(/([A-Z])/g,p=>"-"+p.toLowerCase())));s!==void 0&&(t.textContent=s);for(let o in i)if(i.hasOwnProperty(o)){let p=dist_esm_I(o,i[o]);dist_esm_k.test(o)?t.style.setProperty(o,p):t.style[o]=p}m.forEach((o,p)=>{t.setAttribute(o,d[p])}),u!==void 0&&(t.scrollTop=u),l!==void 0&&(t.scrollLeft=l),a!==void 0&&t.setAttribute("viewBox",a)}var web_dist_esm_c={animationIterationCount:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},esm_F=(t,e)=>t+e.charAt(0).toUpperCase()+e.substring(1),esm_L=["Webkit","Ms","Moz","O"];web_dist_esm_c=Object.keys(web_dist_esm_c).reduce((t,e)=>(esm_L.forEach(r=>t[esm_F(r,e)]=t[e]),t),web_dist_esm_c);var esm_=/^(matrix|translate|scale|rotate|skew)/,esm_$=/^(translate)/,dist_esm_G=/^(rotate|skew)/,web_dist_esm_y=(t,e)=>esm_l.num(t)&&t!==0?t+e:t,web_dist_esm_h=(t,e)=>esm_l.arr(t)?t.every(r=>web_dist_esm_h(r,e)):esm_l.num(t)?t===e:parseFloat(t)===e,esm_g=class extends dist_esm_u{constructor({x:e,y:r,z:i,...s}){let u=[],l=[];(e||r||i)&&(u.push([e||0,r||0,i||0]),l.push(a=>[`translate3d(${a.map(n=>web_dist_esm_y(n,"px")).join(",")})`,web_dist_esm_h(a,0)])),xt(s,(a,n)=>{if(n==="transform")u.push([a||""]),l.push(d=>[d,d===""]);else if(esm_.test(n)){if(delete s[n],esm_l.und(a))return;let d=esm_$.test(n)?"px":dist_esm_G.test(n)?"deg":"";u.push(ht(a)),l.push(n==="rotate3d"?([m,o,p,O])=>[`rotate3d(${m},${o},${p},${web_dist_esm_y(O,d)})`,web_dist_esm_h(O,0)]:m=>[`${n}(${m.map(o=>web_dist_esm_y(o,d)).join(",")})`,web_dist_esm_h(m,n.startsWith("scale")?1:0)])}}),u.length&&(s.transform=new dist_esm_x(u,l)),super(s)}},dist_esm_x=class extends esm_ge{constructor(r,i){super();this.inputs=r;this.transforms=i}_value=null;get(){return this._value||(this._value=this._get())}_get(){let r="",i=!0;return Ve(this.inputs,(s,u)=>{let l=ve(s[0]),[a,n]=this.transforms[u](esm_l.arr(l)?l:s.map(ve));r+=" "+a,i=i&&n}),i?"none":r}observerAdded(r){r==1&&Ve(this.inputs,i=>Ve(i,s=>Pt(s)&&Gt(s,this)))}observerRemoved(r){r==0&&Ve(this.inputs,i=>Ve(i,s=>Pt(s)&&Qt(s,this)))}eventObserved(r){r.type=="change"&&(this._value=null),$t(this,r)}};var esm_C=["a","abbr","address","area","article","aside","audio","b","base","bdi","bdo","big","blockquote","body","br","button","canvas","caption","cite","code","col","colgroup","data","datalist","dd","del","details","dfn","dialog","div","dl","dt","em","embed","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","iframe","img","input","ins","kbd","keygen","label","legend","li","link","main","map","mark","menu","menuitem","meta","meter","nav","noscript","object","ol","optgroup","option","output","p","param","picture","pre","progress","q","rp","rt","ruby","s","samp","script","section","select","small","source","span","strong","style","sub","summary","sup","table","tbody","td","textarea","tfoot","th","thead","time","title","tr","track","u","ul","var","video","wbr","circle","clipPath","defs","ellipse","foreignObject","g","image","line","linearGradient","mask","path","pattern","polygon","polyline","radialGradient","rect","stop","svg","text","tspan"];esm_p.assign({batchedUpdates:external_ReactDOM_namespaceObject.unstable_batchedUpdates,createStringInterpolator:Xt,colors:It});var dist_esm_q=esm_Ke(esm_C,{applyAnimatedValues:esm_V,createAnimatedStyle:t=>new esm_g(t),getComponentProps:({scrollTop:t,scrollLeft:e,...r})=>r}),dist_esm_it=dist_esm_q.animated;
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/use-moving-animation/index.js
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
/**
* Simple reducer used to increment a counter.
*
* @param {number} state Previous counter value.
* @return {number} New state value.
*/
const counterReducer = state => state + 1;
const getAbsolutePosition = element => {
return {
top: element.offsetTop,
left: element.offsetLeft
};
};
/**
* Hook used to compute the styles required to move a div into a new position.
*
* The way this animation works is the following:
* - It first renders the element as if there was no animation.
* - It takes a snapshot of the position of the block to use it
* as a destination point for the animation.
* - It restores the element to the previous position using a CSS transform
* - It uses the "resetAnimation" flag to reset the animation
* from the beginning in order to animate to the new destination point.
*
* @param {Object} $1 Options
* @param {boolean} $1.isSelected Whether it's the current block or not.
* @param {boolean} $1.adjustScrolling Adjust the scroll position to the current block.
* @param {boolean} $1.enableAnimation Enable/Disable animation.
* @param {*} $1.triggerAnimationOnChange Variable used to trigger the animation if it changes.
*/
function useMovingAnimation({
isSelected,
adjustScrolling,
enableAnimation,
triggerAnimationOnChange
}) {
const ref = (0,external_wp_element_namespaceObject.useRef)();
const prefersReducedMotion = (0,external_wp_compose_namespaceObject.useReducedMotion)() || !enableAnimation;
const [triggeredAnimation, triggerAnimation] = (0,external_wp_element_namespaceObject.useReducer)(counterReducer, 0);
const [finishedAnimation, endAnimation] = (0,external_wp_element_namespaceObject.useReducer)(counterReducer, 0);
const [transform, setTransform] = (0,external_wp_element_namespaceObject.useState)({
x: 0,
y: 0
});
const previous = (0,external_wp_element_namespaceObject.useMemo)(() => ref.current ? getAbsolutePosition(ref.current) : null, [triggerAnimationOnChange]);
// Calculate the previous position of the block relative to the viewport and
// return a function to maintain that position by scrolling.
const preserveScrollPosition = (0,external_wp_element_namespaceObject.useMemo)(() => {
if (!adjustScrolling || !ref.current) {
return () => {};
}
const scrollContainer = (0,external_wp_dom_namespaceObject.getScrollContainer)(ref.current);
if (!scrollContainer) {
return () => {};
}
const prevRect = ref.current.getBoundingClientRect();
return () => {
const blockRect = ref.current.getBoundingClientRect();
const diff = blockRect.top - prevRect.top;
if (diff) {
scrollContainer.scrollTop += diff;
}
};
}, [triggerAnimationOnChange, adjustScrolling]);
(0,external_wp_element_namespaceObject.useLayoutEffect)(() => {
if (triggeredAnimation) {
endAnimation();
}
}, [triggeredAnimation]);
(0,external_wp_element_namespaceObject.useLayoutEffect)(() => {
if (!previous) {
return;
}
if (prefersReducedMotion) {
// If the animation is disabled and the scroll needs to be adjusted,
// just move directly to the final scroll position.
preserveScrollPosition();
return;
}
ref.current.style.transform = undefined;
const destination = getAbsolutePosition(ref.current);
triggerAnimation();
setTransform({
x: Math.round(previous.left - destination.left),
y: Math.round(previous.top - destination.top)
});
}, [triggerAnimationOnChange]);
function onChange({
value
}) {
if (!ref.current) {
return;
}
let {
x,
y
} = value;
x = Math.round(x);
y = Math.round(y);
const finishedMoving = x === 0 && y === 0;
ref.current.style.transformOrigin = 'center center';
ref.current.style.transform = finishedMoving ? undefined : `translate3d(${x}px,${y}px,0)`;
ref.current.style.zIndex = isSelected ? '1' : '';
preserveScrollPosition();
}
esm_J({
from: {
x: transform.x,
y: transform.y
},
to: {
x: 0,
y: 0
},
reset: triggeredAnimation !== finishedAnimation,
config: {
mass: 5,
tension: 2000,
friction: 200
},
immediate: prefersReducedMotion,
onChange
});
return ref;
}
/* harmony default export */ var use_moving_animation = (useMovingAnimation);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/utils/dom.js
const BLOCK_SELECTOR = '.block-editor-block-list__block';
const APPENDER_SELECTOR = '.block-list-appender';
const BLOCK_APPENDER_CLASS = '.block-editor-button-block-appender';
/**
* Returns true if two elements are contained within the same block.
*
* @param {Element} a First element.
* @param {Element} b Second element.
*
* @return {boolean} Whether elements are in the same block.
*/
function isInSameBlock(a, b) {
return a.closest(BLOCK_SELECTOR) === b.closest(BLOCK_SELECTOR);
}
/**
* Returns true if an element is considered part of the block and not its inner
* blocks or appender.
*
* @param {Element} blockElement Block container element.
* @param {Element} element Element.
*
* @return {boolean} Whether an element is considered part of the block and not
* its inner blocks or appender.
*/
function isInsideRootBlock(blockElement, element) {
const parentBlock = element.closest([BLOCK_SELECTOR, APPENDER_SELECTOR, BLOCK_APPENDER_CLASS].join(','));
return parentBlock === blockElement;
}
/**
* Finds the block client ID given any DOM node inside the block.
*
* @param {Node?} node DOM node.
*
* @return {string|undefined} Client ID or undefined if the node is not part of
* a block.
*/
function getBlockClientId(node) {
while (node && node.nodeType !== node.ELEMENT_NODE) {
node = node.parentNode;
}
if (!node) {
return;
}
const elementNode = /** @type {Element} */node;
const blockNode = elementNode.closest(BLOCK_SELECTOR);
if (!blockNode) {
return;
}
return blockNode.id.slice('block-'.length);
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-list/use-block-props/use-focus-first-element.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
/** @typedef {import('@wordpress/element').RefObject} RefObject */
/**
* Returns the initial position if the block needs to be focussed, `undefined`
* otherwise. The initial position is either 0 (start) or -1 (end).
*
* @param {string} clientId Block client ID.
*
* @return {number} The initial position, either 0 (start) or -1 (end).
*/
function useInitialPosition(clientId) {
return (0,external_wp_data_namespaceObject.useSelect)(select => {
const {
getSelectedBlocksInitialCaretPosition,
__unstableGetEditorMode,
isBlockSelected
} = select(store);
if (!isBlockSelected(clientId)) {
return;
}
if (__unstableGetEditorMode() !== 'edit') {
return;
}
// If there's no initial position, return 0 to focus the start.
return getSelectedBlocksInitialCaretPosition();
}, [clientId]);
}
/**
* Transitions focus to the block or inner tabbable when the block becomes
* selected and an initial position is set.
*
* @param {string} clientId Block client ID.
*
* @return {RefObject} React ref with the block element.
*/
function useFocusFirstElement(clientId) {
const ref = (0,external_wp_element_namespaceObject.useRef)();
const initialPosition = useInitialPosition(clientId);
const {
isBlockSelected,
isMultiSelecting
} = (0,external_wp_data_namespaceObject.useSelect)(store);
(0,external_wp_element_namespaceObject.useEffect)(() => {
// Check if the block is still selected at the time this effect runs.
if (!isBlockSelected(clientId) || isMultiSelecting()) {
return;
}
if (initialPosition === undefined || initialPosition === null) {
return;
}
if (!ref.current) {
return;
}
const {
ownerDocument
} = ref.current;
// Do not focus the block if it already contains the active element.
if (isInsideRootBlock(ref.current, ownerDocument.activeElement)) {
return;
}
// Find all tabbables within node.
const textInputs = external_wp_dom_namespaceObject.focus.tabbable.find(ref.current).filter(node => (0,external_wp_dom_namespaceObject.isTextField)(node));
// If reversed (e.g. merge via backspace), use the last in the set of
// tabbables.
const isReverse = -1 === initialPosition;
const target = textInputs[isReverse ? textInputs.length - 1 : 0] || ref.current;
if (!isInsideRootBlock(ref.current, target)) {
ref.current.focus();
return;
}
// Check to see if element is focussable before a generic caret insert.
if (!ref.current.getAttribute('contenteditable')) {
const focusElement = external_wp_dom_namespaceObject.focus.tabbable.findNext(ref.current);
// Make sure focusElement is valid, contained in the same block, and a form field.
if (focusElement && isInsideRootBlock(ref.current, focusElement) && (0,external_wp_dom_namespaceObject.isFormElement)(focusElement)) {
focusElement.focus();
return;
}
}
(0,external_wp_dom_namespaceObject.placeCaretAtHorizontalEdge)(target, isReverse);
}, [initialPosition, clientId]);
return ref;
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-list/use-block-props/use-is-hovered.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
function listener(event) {
if (event.defaultPrevented) {
return;
}
const action = event.type === 'mouseover' ? 'add' : 'remove';
event.preventDefault();
event.currentTarget.classList[action]('is-hovered');
}
/**
* Adds `is-hovered` class when the block is hovered and in navigation or
* outline mode.
*/
function useIsHovered() {
const isEnabled = (0,external_wp_data_namespaceObject.useSelect)(select => {
const {
getSettings
} = select(store);
return getSettings().outlineMode;
}, []);
return (0,external_wp_compose_namespaceObject.useRefEffect)(node => {
if (isEnabled) {
node.addEventListener('mouseout', listener);
node.addEventListener('mouseover', listener);
return () => {
node.removeEventListener('mouseout', listener);
node.removeEventListener('mouseover', listener);
// Remove class in case it lingers.
node.classList.remove('is-hovered');
};
}
}, [isEnabled]);
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-list/use-block-props/use-block-class-names.js
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
/**
* Returns the class names used for the different states of the block.
*
* @param {string} clientId The block client ID.
*
* @return {string} The class names.
*/
function useBlockClassNames(clientId) {
return (0,external_wp_data_namespaceObject.useSelect)(select => {
const {
isBlockBeingDragged,
isBlockHighlighted,
isBlockSelected,
isBlockMultiSelected,
getBlockName,
getSettings,
hasSelectedInnerBlock,
isTyping,
__unstableIsFullySelected,
__unstableSelectionHasUnmergeableBlock
} = select(store);
const {
outlineMode
} = getSettings();
const isDragging = isBlockBeingDragged(clientId);
const isSelected = isBlockSelected(clientId);
const name = getBlockName(clientId);
const checkDeep = true;
// "ancestor" is the more appropriate label due to "deep" check.
const isAncestorOfSelectedBlock = hasSelectedInnerBlock(clientId, checkDeep);
const isMultiSelected = isBlockMultiSelected(clientId);
return classnames_default()({
'is-selected': isSelected,
'is-highlighted': isBlockHighlighted(clientId),
'is-multi-selected': isMultiSelected,
'is-partially-selected': isMultiSelected && !__unstableIsFullySelected() && !__unstableSelectionHasUnmergeableBlock(),
'is-reusable': (0,external_wp_blocks_namespaceObject.isReusableBlock)((0,external_wp_blocks_namespaceObject.getBlockType)(name)),
'is-dragging': isDragging,
'has-child-selected': isAncestorOfSelectedBlock,
'remove-outline': isSelected && outlineMode && isTyping()
});
}, [clientId]);
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-list/use-block-props/use-block-default-class-name.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
/**
* Returns the default class name if the block is a light block and it supports
* `className`.
*
* @param {string} clientId The block client ID.
*
* @return {string} The class name, e.g. `wp-block-paragraph`.
*/
function useBlockDefaultClassName(clientId) {
return (0,external_wp_data_namespaceObject.useSelect)(select => {
const name = select(store).getBlockName(clientId);
const blockType = (0,external_wp_blocks_namespaceObject.getBlockType)(name);
const hasLightBlockWrapper = blockType?.apiVersion > 1;
if (!hasLightBlockWrapper) {
return;
}
return (0,external_wp_blocks_namespaceObject.getBlockDefaultClassName)(name);
}, [clientId]);
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-list/use-block-props/use-block-custom-class-name.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
/**
* Returns the custom class name if the block is a light block.
*
* @param {string} clientId The block client ID.
*
* @return {string} The custom class name.
*/
function useBlockCustomClassName(clientId) {
// It's good for this to be a separate selector because it will be executed
// on every attribute change, while the other selectors are not re-evaluated
// as much.
return (0,external_wp_data_namespaceObject.useSelect)(select => {
const {
getBlockName,
getBlockAttributes
} = select(store);
const attributes = getBlockAttributes(clientId);
if (!attributes?.className) {
return;
}
const blockType = (0,external_wp_blocks_namespaceObject.getBlockType)(getBlockName(clientId));
const hasLightBlockWrapper = blockType?.apiVersion > 1;
if (!hasLightBlockWrapper) {
return;
}
return attributes.className;
}, [clientId]);
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-list/use-block-props/use-block-moving-mode-class-names.js
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
/**
* Returns the class names used for block moving mode.
*
* @param {string} clientId The block client ID to insert above.
*
* @return {string} The class names.
*/
function useBlockMovingModeClassNames(clientId) {
return (0,external_wp_data_namespaceObject.useSelect)(select => {
const {
hasBlockMovingClientId,
canInsertBlockType,
getBlockName,
getBlockRootClientId,
isBlockSelected
} = select(store);
// The classes are only relevant for the selected block. Avoid
// re-rendering all blocks!
if (!isBlockSelected(clientId)) {
return;
}
const movingClientId = hasBlockMovingClientId();
if (!movingClientId) {
return;
}
return classnames_default()('is-block-moving-mode', {
'can-insert-moving-block': canInsertBlockType(getBlockName(movingClientId), getBlockRootClientId(clientId))
});
}, [clientId]);
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-list/use-block-props/use-focus-handler.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
/**
* Selects the block if it receives focus.
*
* @param {string} clientId Block client ID.
*/
function useFocusHandler(clientId) {
const {
isBlockSelected
} = (0,external_wp_data_namespaceObject.useSelect)(store);
const {
selectBlock,
selectionChange
} = (0,external_wp_data_namespaceObject.useDispatch)(store);
return (0,external_wp_compose_namespaceObject.useRefEffect)(node => {
/**
* Marks the block as selected when focused and not already
* selected. This specifically handles the case where block does not
* set focus on its own (via `setFocus`), typically if there is no
* focusable input in the block.
*
* @param {FocusEvent} event Focus event.
*/
function onFocus(event) {
// When the whole editor is editable, let writing flow handle
// selection.
if (node.parentElement.closest('[contenteditable="true"]')) {
return;
}
// Check synchronously because a non-selected block might be
// getting data through `useSelect` asynchronously.
if (isBlockSelected(clientId)) {
// Potentially change selection away from rich text.
if (!event.target.isContentEditable) {
selectionChange(clientId);
}
return;
}
// If an inner block is focussed, that block is resposible for
// setting the selected block.
if (!isInsideRootBlock(node, event.target)) {
return;
}
selectBlock(clientId);
}
node.addEventListener('focusin', onFocus);
return () => {
node.removeEventListener('focusin', onFocus);
};
}, [isBlockSelected, selectBlock]);
}
;// CONCATENATED MODULE: external ["wp","keycodes"]
var external_wp_keycodes_namespaceObject = window["wp"]["keycodes"];
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-list/use-block-props/use-selected-block-event-handlers.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
/**
* Adds block behaviour:
* - Removes the block on BACKSPACE.
* - Inserts a default block on ENTER.
* - Disables dragging of block contents.
*
* @param {string} clientId Block client ID.
*/
function useEventHandlers(clientId) {
const isSelected = (0,external_wp_data_namespaceObject.useSelect)(select => select(store).isBlockSelected(clientId), [clientId]);
const {
getBlockRootClientId,
getBlockIndex
} = (0,external_wp_data_namespaceObject.useSelect)(store);
const {
insertDefaultBlock,
removeBlock
} = (0,external_wp_data_namespaceObject.useDispatch)(store);
return (0,external_wp_compose_namespaceObject.useRefEffect)(node => {
if (!isSelected) {
return;
}
/**
* Interprets keydown event intent to remove or insert after block if
* key event occurs on wrapper node. This can occur when the block has
* no text fields of its own, particularly after initial insertion, to
* allow for easy deletion and continuous writing flow to add additional
* content.
*
* @param {KeyboardEvent} event Keydown event.
*/
function onKeyDown(event) {
const {
keyCode,
target
} = event;
if (keyCode !== external_wp_keycodes_namespaceObject.ENTER && keyCode !== external_wp_keycodes_namespaceObject.BACKSPACE && keyCode !== external_wp_keycodes_namespaceObject.DELETE) {
return;
}
if (target !== node || (0,external_wp_dom_namespaceObject.isTextField)(target)) {
return;
}
event.preventDefault();
if (keyCode === external_wp_keycodes_namespaceObject.ENTER) {
insertDefaultBlock({}, getBlockRootClientId(clientId), getBlockIndex(clientId) + 1);
} else {
removeBlock(clientId);
}
}
/**
* Prevents default dragging behavior within a block. To do: we must
* handle this in the future and clean up the drag target.
*
* @param {DragEvent} event Drag event.
*/
function onDragStart(event) {
event.preventDefault();
}
node.addEventListener('keydown', onKeyDown);
node.addEventListener('dragstart', onDragStart);
return () => {
node.removeEventListener('keydown', onKeyDown);
node.removeEventListener('dragstart', onDragStart);
};
}, [clientId, isSelected, getBlockRootClientId, getBlockIndex, insertDefaultBlock, removeBlock]);
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-list/use-block-props/use-nav-mode-exit.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
/**
* Allows navigation mode to be exited by clicking in the selected block.
*
* @param {string} clientId Block client ID.
*/
function useNavModeExit(clientId) {
const {
isNavigationMode,
isBlockSelected
} = (0,external_wp_data_namespaceObject.useSelect)(store);
const {
setNavigationMode,
selectBlock
} = (0,external_wp_data_namespaceObject.useDispatch)(store);
return (0,external_wp_compose_namespaceObject.useRefEffect)(node => {
function onMouseDown(event) {
// Don't select a block if it's already handled by a child
// block.
if (isNavigationMode() && !event.defaultPrevented) {
// Prevent focus from moving to the block.
event.preventDefault();
// When clicking on a selected block, exit navigation mode.
if (isBlockSelected(clientId)) {
setNavigationMode(false);
} else {
selectBlock(clientId);
}
}
}
node.addEventListener('mousedown', onMouseDown);
return () => {
node.removeEventListener('mousedown', onMouseDown);
};
}, [clientId, isNavigationMode, isBlockSelected, setNavigationMode]);
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/provider/block-refs-provider.js
/**
* WordPress dependencies
*/
const BlockRefs = (0,external_wp_element_namespaceObject.createContext)({
refs: new Map(),
callbacks: new Map()
});
function BlockRefsProvider({
children
}) {
const value = (0,external_wp_element_namespaceObject.useMemo)(() => ({
refs: new Map(),
callbacks: new Map()
}), []);
return (0,external_wp_element_namespaceObject.createElement)(BlockRefs.Provider, {
value: value
}, children);
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-list/use-block-props/use-block-refs.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
/** @typedef {import('@wordpress/element').RefCallback} RefCallback */
/** @typedef {import('@wordpress/element').RefObject} RefObject */
/**
* Provides a ref to the BlockRefs context.
*
* @param {string} clientId The client ID of the element ref.
*
* @return {RefCallback} Ref callback.
*/
function useBlockRefProvider(clientId) {
const {
refs,
callbacks
} = (0,external_wp_element_namespaceObject.useContext)(BlockRefs);
const ref = (0,external_wp_element_namespaceObject.useRef)();
(0,external_wp_element_namespaceObject.useLayoutEffect)(() => {
refs.set(ref, clientId);
return () => {
refs.delete(ref);
};
}, [clientId]);
return (0,external_wp_compose_namespaceObject.useRefEffect)(element => {
// Update the ref in the provider.
ref.current = element;
// Call any update functions.
callbacks.forEach((id, setElement) => {
if (clientId === id) {
setElement(element);
}
});
}, [clientId]);
}
/**
* Gets a ref pointing to the current block element. Continues to return a
* stable ref even if the block client ID changes.
*
* @param {string} clientId The client ID to get a ref for.
*
* @return {RefObject} A ref containing the element.
*/
function useBlockRef(clientId) {
const {
refs
} = (0,external_wp_element_namespaceObject.useContext)(BlockRefs);
const freshClientId = (0,external_wp_element_namespaceObject.useRef)();
freshClientId.current = clientId;
// Always return an object, even if no ref exists for a given client ID, so
// that `current` works at a later point.
return (0,external_wp_element_namespaceObject.useMemo)(() => ({
get current() {
let element = null;
// Multiple refs may be created for a single block. Find the
// first that has an element set.
for (const [ref, id] of refs.entries()) {
if (id === freshClientId.current && ref.current) {
element = ref.current;
}
}
return element;
}
}), []);
}
/**
* Return the element for a given client ID. Updates whenever the element
* changes, becomes available, or disappears.
*
* @param {string} clientId The client ID to an element for.
*
* @return {Element|null} The block's wrapper element.
*/
function useBlockElement(clientId) {
const {
callbacks
} = (0,external_wp_element_namespaceObject.useContext)(BlockRefs);
const ref = useBlockRef(clientId);
const [element, setElement] = (0,external_wp_element_namespaceObject.useState)(null);
(0,external_wp_element_namespaceObject.useLayoutEffect)(() => {
if (!clientId) {
return;
}
callbacks.set(setElement, clientId);
return () => {
callbacks.delete(setElement);
};
}, [clientId]);
return ref.current || element;
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-list/use-block-props/use-intersection-observer.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
function useIntersectionObserver() {
const observer = (0,external_wp_element_namespaceObject.useContext)(block_list_IntersectionObserver);
return (0,external_wp_compose_namespaceObject.useRefEffect)(node => {
if (observer) {
observer.observe(node);
return () => {
observer.unobserve(node);
};
}
}, [observer]);
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-content-overlay/index.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
function useBlockOverlayActive(clientId) {
return (0,external_wp_data_namespaceObject.useSelect)(select => {
const {
__unstableHasActiveBlockOverlayActive
} = select(store);
return __unstableHasActiveBlockOverlayActive(clientId);
}, [clientId]);
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-list/use-block-props/index.js
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
/**
* If the block count exceeds the threshold, we disable the reordering animation
* to avoid laginess.
*/
const BLOCK_ANIMATION_THRESHOLD = 200;
/**
* This hook is used to lightly mark an element as a block element. The element
* should be the outermost element of a block. Call this hook and pass the
* returned props to the element to mark as a block. If you define a ref for the
* element, it is important to pass the ref to this hook, which the hook in turn
* will pass to the component through the props it returns. Optionally, you can
* also pass any other props through this hook, and they will be merged and
* returned.
*
* Use of this hook on the outermost element of a block is required if using API >= v2.
*
* @example
* ```js
* import { useBlockProps } from '@wordpress/block-editor';
*
* export default function Edit() {
*
* const blockProps = useBlockProps(
* className: 'my-custom-class',
* style: {
* color: '#222222',
* backgroundColor: '#eeeeee'
* }
* )
*
* return (
*
*
*
* )
* }
*
* ```
*
*
* @param {Object} props Optional. Props to pass to the element. Must contain
* the ref if one is defined.
* @param {Object} options Options for internal use only.
* @param {boolean} options.__unstableIsHtml
*
* @return {Object} Props to pass to the element to mark as a block.
*/
function useBlockProps(props = {}, {
__unstableIsHtml
} = {}) {
const {
clientId,
className,
wrapperProps = {},
isAligned
} = (0,external_wp_element_namespaceObject.useContext)(BlockListBlockContext);
const {
index,
mode,
name,
blockApiVersion,
blockTitle,
isPartOfSelection,
adjustScrolling,
enableAnimation,
isSubtreeDisabled
} = (0,external_wp_data_namespaceObject.useSelect)(select => {
const {
getBlockAttributes,
getBlockIndex,
getBlockMode,
getBlockName,
isTyping,
getGlobalBlockCount,
isBlockSelected,
isBlockMultiSelected,
isAncestorMultiSelected,
isFirstMultiSelectedBlock,
isBlockSubtreeDisabled
} = unlock(select(store));
const {
getActiveBlockVariation
} = select(external_wp_blocks_namespaceObject.store);
const isSelected = isBlockSelected(clientId);
const isPartOfMultiSelection = isBlockMultiSelected(clientId) || isAncestorMultiSelected(clientId);
const blockName = getBlockName(clientId);
const blockType = (0,external_wp_blocks_namespaceObject.getBlockType)(blockName);
const attributes = getBlockAttributes(clientId);
const match = getActiveBlockVariation(blockName, attributes);
return {
index: getBlockIndex(clientId),
mode: getBlockMode(clientId),
name: blockName,
blockApiVersion: blockType?.apiVersion || 1,
blockTitle: match?.title || blockType?.title,
isPartOfSelection: isSelected || isPartOfMultiSelection,
adjustScrolling: isSelected || isFirstMultiSelectedBlock(clientId),
enableAnimation: !isTyping() && getGlobalBlockCount() <= BLOCK_ANIMATION_THRESHOLD,
isSubtreeDisabled: isBlockSubtreeDisabled(clientId)
};
}, [clientId]);
const hasOverlay = useBlockOverlayActive(clientId);
// translators: %s: Type of block (i.e. Text, Image etc)
const blockLabel = (0,external_wp_i18n_namespaceObject.sprintf)((0,external_wp_i18n_namespaceObject.__)('Block: %s'), blockTitle);
const htmlSuffix = mode === 'html' && !__unstableIsHtml ? '-visual' : '';
const mergedRefs = (0,external_wp_compose_namespaceObject.useMergeRefs)([props.ref, useFocusFirstElement(clientId), useBlockRefProvider(clientId), useFocusHandler(clientId), useEventHandlers(clientId), useNavModeExit(clientId), useIsHovered(), useIntersectionObserver(), use_moving_animation({
isSelected: isPartOfSelection,
adjustScrolling,
enableAnimation,
triggerAnimationOnChange: index
}), (0,external_wp_compose_namespaceObject.useDisabled)({
isDisabled: !hasOverlay
})]);
const blockEditContext = useBlockEditContext();
// Ensures it warns only inside the `edit` implementation for the block.
if (blockApiVersion < 2 && clientId === blockEditContext.clientId) {
true ? external_wp_warning_default()(`Block type "${name}" must support API version 2 or higher to work correctly with "useBlockProps" method.`) : 0;
}
return {
tabIndex: 0,
...wrapperProps,
...props,
ref: mergedRefs,
id: `block-${clientId}${htmlSuffix}`,
role: 'document',
'aria-label': blockLabel,
'data-block': clientId,
'data-type': name,
'data-title': blockTitle,
inert: isSubtreeDisabled ? 'true' : undefined,
className: classnames_default()(
// The wp-block className is important for editor styles.
classnames_default()('block-editor-block-list__block', {
'wp-block': !isAligned,
'has-block-overlay': hasOverlay
}), className, props.className, wrapperProps.className, useBlockClassNames(clientId), useBlockDefaultClassName(clientId), useBlockCustomClassName(clientId), useBlockMovingModeClassNames(clientId)),
style: {
...wrapperProps.style,
...props.style
}
};
}
/**
* Call within a save function to get the props for the block wrapper.
*
* @param {Object} props Optional. Props to pass to the element.
*/
useBlockProps.save = external_wp_blocks_namespaceObject.__unstableGetBlockProps;
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-list/block.js
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
/**
* Merges wrapper props with special handling for classNames and styles.
*
* @param {Object} propsA
* @param {Object} propsB
*
* @return {Object} Merged props.
*/
function mergeWrapperProps(propsA, propsB) {
const newProps = {
...propsA,
...propsB
};
if (propsA?.className && propsB?.className) {
newProps.className = classnames_default()(propsA.className, propsB.className);
}
if (propsA?.style && propsB?.style) {
newProps.style = {
...propsA.style,
...propsB.style
};
}
return newProps;
}
function Block({
children,
isHtml,
...props
}) {
return (0,external_wp_element_namespaceObject.createElement)("div", {
...useBlockProps(props, {
__unstableIsHtml: isHtml
})
}, children);
}
function BlockListBlock({
block: {
__unstableBlockSource
},
mode,
isLocked,
canRemove,
clientId,
isSelected,
isSelectionEnabled,
className,
__unstableLayoutClassNames: layoutClassNames,
name,
isValid,
attributes,
wrapperProps,
setAttributes,
onReplace,
onInsertBlocksAfter,
onMerge,
toggleSelection
}) {
var _wrapperProps;
const {
themeSupportsLayout,
isTemporarilyEditingAsBlocks,
blockEditingMode
} = (0,external_wp_data_namespaceObject.useSelect)(select => {
const {
getSettings,
__unstableGetTemporarilyEditingAsBlocks,
getBlockEditingMode
} = select(store);
return {
themeSupportsLayout: getSettings().supportsLayout,
isTemporarilyEditingAsBlocks: __unstableGetTemporarilyEditingAsBlocks() === clientId,
blockEditingMode: getBlockEditingMode(clientId)
};
}, [clientId]);
const {
removeBlock
} = (0,external_wp_data_namespaceObject.useDispatch)(store);
const onRemove = (0,external_wp_element_namespaceObject.useCallback)(() => removeBlock(clientId), [clientId]);
const parentLayout = useLayout() || {};
// We wrap the BlockEdit component in a div that hides it when editing in
// HTML mode. This allows us to render all of the ancillary pieces
// (InspectorControls, etc.) which are inside `BlockEdit` but not
// `BlockHTML`, even in HTML mode.
let blockEdit = (0,external_wp_element_namespaceObject.createElement)(BlockEdit, {
name: name,
isSelected: isSelected,
attributes: attributes,
setAttributes: setAttributes,
insertBlocksAfter: isLocked ? undefined : onInsertBlocksAfter,
onReplace: canRemove ? onReplace : undefined,
onRemove: canRemove ? onRemove : undefined,
mergeBlocks: canRemove ? onMerge : undefined,
clientId: clientId,
isSelectionEnabled: isSelectionEnabled,
toggleSelection: toggleSelection,
__unstableLayoutClassNames: layoutClassNames,
__unstableParentLayout: Object.keys(parentLayout).length ? parentLayout : undefined
});
const blockType = (0,external_wp_blocks_namespaceObject.getBlockType)(name);
if (blockEditingMode === 'disabled') {
wrapperProps = {
...wrapperProps,
tabIndex: -1
};
}
// Determine whether the block has props to apply to the wrapper.
if (blockType?.getEditWrapperProps) {
wrapperProps = mergeWrapperProps(wrapperProps, blockType.getEditWrapperProps(attributes));
}
const isAligned = wrapperProps && !!wrapperProps['data-align'] && !themeSupportsLayout;
// For aligned blocks, provide a wrapper element so the block can be
// positioned relative to the block column.
// This is only kept for classic themes that don't support layout
// Historically we used to rely on extra divs and data-align to
// provide the alignments styles in the editor.
// Due to the differences between frontend and backend, we migrated
// to the layout feature, and we're now aligning the markup of frontend
// and backend.
if (isAligned) {
blockEdit = (0,external_wp_element_namespaceObject.createElement)("div", {
className: "wp-block",
"data-align": wrapperProps['data-align']
}, blockEdit);
}
let block;
if (!isValid) {
const saveContent = __unstableBlockSource ? (0,external_wp_blocks_namespaceObject.serializeRawBlock)(__unstableBlockSource) : (0,external_wp_blocks_namespaceObject.getSaveContent)(blockType, attributes);
block = (0,external_wp_element_namespaceObject.createElement)(Block, {
className: "has-warning"
}, (0,external_wp_element_namespaceObject.createElement)(BlockInvalidWarning, {
clientId: clientId
}), (0,external_wp_element_namespaceObject.createElement)(external_wp_element_namespaceObject.RawHTML, null, (0,external_wp_dom_namespaceObject.safeHTML)(saveContent)));
} else if (mode === 'html') {
// Render blockEdit so the inspector controls don't disappear.
// See #8969.
block = (0,external_wp_element_namespaceObject.createElement)(external_wp_element_namespaceObject.Fragment, null, (0,external_wp_element_namespaceObject.createElement)("div", {
style: {
display: 'none'
}
}, blockEdit), (0,external_wp_element_namespaceObject.createElement)(Block, {
isHtml: true
}, (0,external_wp_element_namespaceObject.createElement)(block_html, {
clientId: clientId
})));
} else if (blockType?.apiVersion > 1) {
block = blockEdit;
} else {
block = (0,external_wp_element_namespaceObject.createElement)(Block, {
...wrapperProps
}, blockEdit);
}
const {
'data-align': dataAlign,
...restWrapperProps
} = (_wrapperProps = wrapperProps) !== null && _wrapperProps !== void 0 ? _wrapperProps : {};
const value = {
clientId,
className: classnames_default()({
'is-editing-disabled': blockEditingMode === 'disabled',
'is-content-locked-temporarily-editing-as-blocks': isTemporarilyEditingAsBlocks
}, dataAlign && themeSupportsLayout && `align${dataAlign}`, className),
wrapperProps: restWrapperProps,
isAligned
};
const memoizedValue = (0,external_wp_element_namespaceObject.useMemo)(() => value, Object.values(value));
return (0,external_wp_element_namespaceObject.createElement)(BlockListBlockContext.Provider, {
value: memoizedValue
}, (0,external_wp_element_namespaceObject.createElement)(block_crash_boundary, {
fallback: (0,external_wp_element_namespaceObject.createElement)(Block, {
className: "has-warning"
}, (0,external_wp_element_namespaceObject.createElement)(block_crash_warning, null))
}, block));
}
const applyWithSelect = (0,external_wp_data_namespaceObject.withSelect)((select, {
clientId,
rootClientId
}) => {
const {
isBlockSelected,
getBlockMode,
isSelectionEnabled,
getTemplateLock,
__unstableGetBlockWithoutInnerBlocks,
canRemoveBlock,
canMoveBlock
} = select(store);
const block = __unstableGetBlockWithoutInnerBlocks(clientId);
const isSelected = isBlockSelected(clientId);
const templateLock = getTemplateLock(rootClientId);
const canRemove = canRemoveBlock(clientId, rootClientId);
const canMove = canMoveBlock(clientId, rootClientId);
// The fallback to `{}` is a temporary fix.
// This function should never be called when a block is not present in
// the state. It happens now because the order in withSelect rendering
// is not correct.
const {
name,
attributes,
isValid
} = block || {};
// Do not add new properties here, use `useSelect` instead to avoid
// leaking new props to the public API (editor.BlockListBlock filter).
return {
mode: getBlockMode(clientId),
isSelectionEnabled: isSelectionEnabled(),
isLocked: !!templateLock,
canRemove,
canMove,
// Users of the editor.BlockListBlock filter used to be able to
// access the block prop.
// Ideally these blocks would rely on the clientId prop only.
// This is kept for backward compatibility reasons.
block,
name,
attributes,
isValid,
isSelected
};
});
const applyWithDispatch = (0,external_wp_data_namespaceObject.withDispatch)((dispatch, ownProps, registry) => {
const {
updateBlockAttributes,
insertBlocks,
mergeBlocks,
replaceBlocks,
toggleSelection,
__unstableMarkLastChangeAsPersistent,
moveBlocksToPosition,
removeBlock
} = dispatch(store);
// Do not add new properties here, use `useDispatch` instead to avoid
// leaking new props to the public API (editor.BlockListBlock filter).
return {
setAttributes(newAttributes) {
const {
getMultiSelectedBlockClientIds
} = registry.select(store);
const multiSelectedBlockClientIds = getMultiSelectedBlockClientIds();
const {
clientId
} = ownProps;
const clientIds = multiSelectedBlockClientIds.length ? multiSelectedBlockClientIds : [clientId];
updateBlockAttributes(clientIds, newAttributes);
},
onInsertBlocks(blocks, index) {
const {
rootClientId
} = ownProps;
insertBlocks(blocks, index, rootClientId);
},
onInsertBlocksAfter(blocks) {
const {
clientId,
rootClientId
} = ownProps;
const {
getBlockIndex
} = registry.select(store);
const index = getBlockIndex(clientId);
insertBlocks(blocks, index + 1, rootClientId);
},
onMerge(forward) {
const {
clientId,
rootClientId
} = ownProps;
const {
getPreviousBlockClientId,
getNextBlockClientId,
getBlock,
getBlockAttributes,
getBlockName,
getBlockOrder,
getBlockIndex,
getBlockRootClientId,
canInsertBlockType
} = registry.select(store);
/**
* Moves the block with clientId up one level. If the block type
* cannot be inserted at the new location, it will be attempted to
* convert to the default block type.
*
* @param {string} _clientId The block to move.
* @param {boolean} changeSelection Whether to change the selection
* to the moved block.
*/
function moveFirstItemUp(_clientId, changeSelection = true) {
const targetRootClientId = getBlockRootClientId(_clientId);
const blockOrder = getBlockOrder(_clientId);
const [firstClientId] = blockOrder;
if (blockOrder.length === 1 && (0,external_wp_blocks_namespaceObject.isUnmodifiedBlock)(getBlock(firstClientId))) {
removeBlock(_clientId);
} else {
registry.batch(() => {
if (canInsertBlockType(getBlockName(firstClientId), targetRootClientId)) {
moveBlocksToPosition([firstClientId], _clientId, targetRootClientId, getBlockIndex(_clientId));
} else {
const replacement = (0,external_wp_blocks_namespaceObject.switchToBlockType)(getBlock(firstClientId), (0,external_wp_blocks_namespaceObject.getDefaultBlockName)());
if (replacement && replacement.length) {
insertBlocks(replacement, getBlockIndex(_clientId), targetRootClientId, changeSelection);
removeBlock(firstClientId, false);
}
}
if (!getBlockOrder(_clientId).length && (0,external_wp_blocks_namespaceObject.isUnmodifiedBlock)(getBlock(_clientId))) {
removeBlock(_clientId, false);
}
});
}
}
// For `Delete` or forward merge, we should do the exact same thing
// as `Backspace`, but from the other block.
if (forward) {
if (rootClientId) {
const nextRootClientId = getNextBlockClientId(rootClientId);
if (nextRootClientId) {
// If there is a block that follows with the same parent
// block name and the same attributes, merge the inner
// blocks.
if (getBlockName(rootClientId) === getBlockName(nextRootClientId)) {
const rootAttributes = getBlockAttributes(rootClientId);
const previousRootAttributes = getBlockAttributes(nextRootClientId);
if (Object.keys(rootAttributes).every(key => rootAttributes[key] === previousRootAttributes[key])) {
registry.batch(() => {
moveBlocksToPosition(getBlockOrder(nextRootClientId), nextRootClientId, rootClientId);
removeBlock(nextRootClientId, false);
});
return;
}
} else {
mergeBlocks(rootClientId, nextRootClientId);
return;
}
}
}
const nextBlockClientId = getNextBlockClientId(clientId);
if (!nextBlockClientId) {
return;
}
if (getBlockOrder(nextBlockClientId).length) {
moveFirstItemUp(nextBlockClientId, false);
} else {
mergeBlocks(clientId, nextBlockClientId);
}
} else {
const previousBlockClientId = getPreviousBlockClientId(clientId);
if (previousBlockClientId) {
mergeBlocks(previousBlockClientId, clientId);
} else if (rootClientId) {
const previousRootClientId = getPreviousBlockClientId(rootClientId);
// If there is a preceding block with the same parent block
// name and the same attributes, merge the inner blocks.
if (previousRootClientId && getBlockName(rootClientId) === getBlockName(previousRootClientId)) {
const rootAttributes = getBlockAttributes(rootClientId);
const previousRootAttributes = getBlockAttributes(previousRootClientId);
if (Object.keys(rootAttributes).every(key => rootAttributes[key] === previousRootAttributes[key])) {
registry.batch(() => {
moveBlocksToPosition(getBlockOrder(rootClientId), rootClientId, previousRootClientId);
removeBlock(rootClientId, false);
});
return;
}
}
moveFirstItemUp(rootClientId);
}
}
},
onReplace(blocks, indexToSelect, initialPosition) {
if (blocks.length && !(0,external_wp_blocks_namespaceObject.isUnmodifiedDefaultBlock)(blocks[blocks.length - 1])) {
__unstableMarkLastChangeAsPersistent();
}
//Unsynced patterns are nested in an array so we need to flatten them.
const replacementBlocks = blocks?.length === 1 && Array.isArray(blocks[0]) ? blocks[0] : blocks;
replaceBlocks([ownProps.clientId], replacementBlocks, indexToSelect, initialPosition);
},
toggleSelection(selectionEnabled) {
toggleSelection(selectionEnabled);
}
};
});
/* harmony default export */ var block = ((0,external_wp_compose_namespaceObject.compose)(external_wp_compose_namespaceObject.pure, applyWithSelect, applyWithDispatch,
// Block is sometimes not mounted at the right time, causing it be undefined
// see issue for more info
// https://github.com/WordPress/gutenberg/issues/17013
(0,external_wp_compose_namespaceObject.ifCondition)(({
block
}) => !!block), (0,external_wp_components_namespaceObject.withFilters)('editor.BlockListBlock'))(BlockListBlock));
;// CONCATENATED MODULE: external ["wp","htmlEntities"]
var external_wp_htmlEntities_namespaceObject = window["wp"]["htmlEntities"];
;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/plus.js
/**
* WordPress dependencies
*/
const plus = (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.SVG, {
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 24 24"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.Path, {
d: "M18 11.2h-5.2V6h-1.6v5.2H6v1.6h5.2V18h1.6v-5.2H18z"
}));
/* harmony default export */ var library_plus = (plus);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/tips.js
/**
* WordPress dependencies
*/
const globalTips = [(0,external_wp_element_namespaceObject.createInterpolateElement)((0,external_wp_i18n_namespaceObject.__)('While writing, you can press / to quickly insert new blocks.'), {
kbd: (0,external_wp_element_namespaceObject.createElement)("kbd", null)
}), (0,external_wp_element_namespaceObject.createInterpolateElement)((0,external_wp_i18n_namespaceObject.__)('Indent a list by pressing space at the beginning of a line.'), {
kbd: (0,external_wp_element_namespaceObject.createElement)("kbd", null)
}), (0,external_wp_element_namespaceObject.createInterpolateElement)((0,external_wp_i18n_namespaceObject.__)('Outdent a list by pressing backspace at the beginning of a line.'), {
kbd: (0,external_wp_element_namespaceObject.createElement)("kbd", null)
}), (0,external_wp_i18n_namespaceObject.__)('Drag files into the editor to automatically insert media blocks.'), (0,external_wp_i18n_namespaceObject.__)("Change a block's type by pressing the block icon on the toolbar.")];
function Tips() {
const [randomIndex] = (0,external_wp_element_namespaceObject.useState)(
// Disable Reason: I'm not generating an HTML id.
// eslint-disable-next-line no-restricted-syntax
Math.floor(Math.random() * globalTips.length));
return (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.Tip, null, globalTips[randomIndex]);
}
/* harmony default export */ var tips = (Tips);
;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/chevron-right.js
/**
* WordPress dependencies
*/
const chevronRight = (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.SVG, {
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 24 24"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.Path, {
d: "M10.6 6L9.4 7l4.6 5-4.6 5 1.2 1 5.4-6z"
}));
/* harmony default export */ var chevron_right = (chevronRight);
;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/chevron-left.js
/**
* WordPress dependencies
*/
const chevronLeft = (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.SVG, {
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 24 24"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.Path, {
d: "M14.6 7l-1.2-1L8 12l5.4 6 1.2-1-4.6-5z"
}));
/* harmony default export */ var chevron_left = (chevronLeft);
;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/block-default.js
/**
* WordPress dependencies
*/
const blockDefault = (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.SVG, {
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 24 24"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.Path, {
d: "M19 8h-1V6h-5v2h-2V6H6v2H5c-1.1 0-2 .9-2 2v8c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2v-8c0-1.1-.9-2-2-2zm.5 10c0 .3-.2.5-.5.5H5c-.3 0-.5-.2-.5-.5v-8c0-.3.2-.5.5-.5h14c.3 0 .5.2.5.5v8z"
}));
/* harmony default export */ var block_default = (blockDefault);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-icon/index.js
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
function BlockIcon({
icon,
showColors = false,
className,
context
}) {
if (icon?.src === 'block-default') {
icon = {
src: block_default
};
}
const renderedIcon = (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.Icon, {
icon: icon && icon.src ? icon.src : icon,
context: context
});
const style = showColors ? {
backgroundColor: icon && icon.background,
color: icon && icon.foreground
} : {};
return (0,external_wp_element_namespaceObject.createElement)("span", {
style: style,
className: classnames_default()('block-editor-block-icon', className, {
'has-colors': showColors
})
}, renderedIcon);
}
/**
* @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/block-icon/README.md
*/
/* harmony default export */ var block_icon = ((0,external_wp_element_namespaceObject.memo)(BlockIcon));
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-card/index.js
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
function BlockCard({
title,
icon,
description,
blockType,
className
}) {
if (blockType) {
external_wp_deprecated_default()('`blockType` property in `BlockCard component`', {
since: '5.7',
alternative: '`title, icon and description` properties'
});
({
title,
icon,
description
} = blockType);
}
const {
parentNavBlockClientId
} = (0,external_wp_data_namespaceObject.useSelect)(select => {
const {
getSelectedBlockClientId,
getBlockParentsByBlockName
} = select(store);
const _selectedBlockClientId = getSelectedBlockClientId();
return {
parentNavBlockClientId: getBlockParentsByBlockName(_selectedBlockClientId, 'core/navigation', true)[0]
};
}, []);
const {
selectBlock
} = (0,external_wp_data_namespaceObject.useDispatch)(store);
return (0,external_wp_element_namespaceObject.createElement)("div", {
className: classnames_default()('block-editor-block-card', className)
}, parentNavBlockClientId &&
// This is only used by the Navigation block for now. It's not ideal having Navigation block specific code here.
(0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.Button, {
onClick: () => selectBlock(parentNavBlockClientId),
label: (0,external_wp_i18n_namespaceObject.__)('Go to parent Navigation block'),
style:
// TODO: This style override is also used in ToolsPanelHeader.
// It should be supported out-of-the-box by Button.
{
minWidth: 24,
padding: 0
},
icon: (0,external_wp_i18n_namespaceObject.isRTL)() ? chevron_right : chevron_left,
isSmall: true
}), (0,external_wp_element_namespaceObject.createElement)(block_icon, {
icon: icon,
showColors: true
}), (0,external_wp_element_namespaceObject.createElement)("div", {
className: "block-editor-block-card__content"
}, (0,external_wp_element_namespaceObject.createElement)("h2", {
className: "block-editor-block-card__title"
}, title), (0,external_wp_element_namespaceObject.createElement)("span", {
className: "block-editor-block-card__description"
}, description)));
}
/* harmony default export */ var block_card = (BlockCard);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/provider/with-registry-provider.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const withRegistryProvider = (0,external_wp_compose_namespaceObject.createHigherOrderComponent)(WrappedComponent => {
return (0,external_wp_data_namespaceObject.withRegistry)(({
useSubRegistry = true,
registry,
...props
}) => {
if (!useSubRegistry) {
return (0,external_wp_element_namespaceObject.createElement)(WrappedComponent, {
registry: registry,
...props
});
}
const [subRegistry, setSubRegistry] = (0,external_wp_element_namespaceObject.useState)(null);
(0,external_wp_element_namespaceObject.useEffect)(() => {
const newRegistry = (0,external_wp_data_namespaceObject.createRegistry)({}, registry);
newRegistry.registerStore(STORE_NAME, storeConfig);
setSubRegistry(newRegistry);
}, [registry]);
if (!subRegistry) {
return null;
}
return (0,external_wp_element_namespaceObject.createElement)(external_wp_data_namespaceObject.RegistryProvider, {
value: subRegistry
}, (0,external_wp_element_namespaceObject.createElement)(WrappedComponent, {
registry: subRegistry,
...props
}));
});
}, 'withRegistryProvider');
/* harmony default export */ var with_registry_provider = (withRegistryProvider);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/provider/use-block-sync.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const noop = () => {};
/**
* A function to call when the block value has been updated in the block-editor
* store.
*
* @callback onBlockUpdate
* @param {Object[]} blocks The updated blocks.
* @param {Object} options The updated block options, such as selectionStart
* and selectionEnd.
*/
/**
* useBlockSync is a side effect which handles bidirectional sync between the
* block-editor store and a controlling data source which provides blocks. This
* is most commonly used by the BlockEditorProvider to synchronize the contents
* of the block-editor store with the root entity, like a post.
*
* Another example would be the template part block, which provides blocks from
* a separate entity data source than a root entity. This hook syncs edits to
* the template part in the block editor back to the entity and vice-versa.
*
* Here are some of its basic functions:
* - Initalizes the block-editor store for the given clientID to the blocks
* given via props.
* - Adds incoming changes (like undo) to the block-editor store.
* - Adds outgoing changes (like editing content) to the controlling entity,
* determining if a change should be considered persistent or not.
* - Handles edge cases and race conditions which occur in those operations.
* - Ignores changes which happen to other entities (like nested inner block
* controllers.
* - Passes selection state from the block-editor store to the controlling entity.
*
* @param {Object} props Props for the block sync hook
* @param {string} props.clientId The client ID of the inner block controller.
* If none is passed, then it is assumed to be a
* root controller rather than an inner block
* controller.
* @param {Object[]} props.value The control value for the blocks. This value
* is used to initalize the block-editor store
* and for resetting the blocks to incoming
* changes like undo.
* @param {Object} props.selection The selection state responsible to restore the selection on undo/redo.
* @param {onBlockUpdate} props.onChange Function to call when a persistent
* change has been made in the block-editor blocks
* for the given clientId. For example, after
* this function is called, an entity is marked
* dirty because it has changes to save.
* @param {onBlockUpdate} props.onInput Function to call when a non-persistent
* change has been made in the block-editor blocks
* for the given clientId. When this is called,
* controlling sources do not become dirty.
*/
function useBlockSync({
clientId = null,
value: controlledBlocks,
selection: controlledSelection,
onChange = noop,
onInput = noop
}) {
const registry = (0,external_wp_data_namespaceObject.useRegistry)();
const {
resetBlocks,
resetSelection,
replaceInnerBlocks,
selectBlock,
setHasControlledInnerBlocks,
__unstableMarkNextChangeAsNotPersistent
} = registry.dispatch(store);
const {
hasSelectedBlock,
getBlockName,
getBlocks,
getSelectionStart,
getSelectionEnd,
getBlock
} = registry.select(store);
const isControlled = (0,external_wp_data_namespaceObject.useSelect)(select => {
return !clientId || select(store).areInnerBlocksControlled(clientId);
}, [clientId]);
const pendingChanges = (0,external_wp_element_namespaceObject.useRef)({
incoming: null,
outgoing: []
});
const subscribed = (0,external_wp_element_namespaceObject.useRef)(false);
const setControlledBlocks = () => {
if (!controlledBlocks) {
return;
}
// We don't need to persist this change because we only replace
// controlled inner blocks when the change was caused by an entity,
// and so it would already be persisted.
__unstableMarkNextChangeAsNotPersistent();
if (clientId) {
// It is important to batch here because otherwise,
// as soon as `setHasControlledInnerBlocks` is called
// the effect to restore might be triggered
// before the actual blocks get set properly in state.
registry.batch(() => {
setHasControlledInnerBlocks(clientId, true);
const storeBlocks = controlledBlocks.map(block => (0,external_wp_blocks_namespaceObject.cloneBlock)(block));
if (subscribed.current) {
pendingChanges.current.incoming = storeBlocks;
}
__unstableMarkNextChangeAsNotPersistent();
replaceInnerBlocks(clientId, storeBlocks);
});
} else {
if (subscribed.current) {
pendingChanges.current.incoming = controlledBlocks;
}
resetBlocks(controlledBlocks);
}
};
// Clean up the changes made by setControlledBlocks() when the component
// containing useBlockSync() unmounts.
const unsetControlledBlocks = () => {
__unstableMarkNextChangeAsNotPersistent();
if (clientId) {
setHasControlledInnerBlocks(clientId, false);
__unstableMarkNextChangeAsNotPersistent();
replaceInnerBlocks(clientId, []);
} else {
resetBlocks([]);
}
};
// Add a subscription to the block-editor registry to detect when changes
// have been made. This lets us inform the data source of changes. This
// is an effect so that the subscriber can run synchronously without
// waiting for React renders for changes.
const onInputRef = (0,external_wp_element_namespaceObject.useRef)(onInput);
const onChangeRef = (0,external_wp_element_namespaceObject.useRef)(onChange);
(0,external_wp_element_namespaceObject.useEffect)(() => {
onInputRef.current = onInput;
onChangeRef.current = onChange;
}, [onInput, onChange]);
// Determine if blocks need to be reset when they change.
(0,external_wp_element_namespaceObject.useEffect)(() => {
if (pendingChanges.current.outgoing.includes(controlledBlocks)) {
// Skip block reset if the value matches expected outbound sync
// triggered by this component by a preceding change detection.
// Only skip if the value matches expectation, since a reset should
// still occur if the value is modified (not equal by reference),
// to allow that the consumer may apply modifications to reflect
// back on the editor.
if (pendingChanges.current.outgoing[pendingChanges.current.outgoing.length - 1] === controlledBlocks) {
pendingChanges.current.outgoing = [];
}
} else if (getBlocks(clientId) !== controlledBlocks) {
// Reset changing value in all other cases than the sync described
// above. Since this can be reached in an update following an out-
// bound sync, unset the outbound value to avoid considering it in
// subsequent renders.
pendingChanges.current.outgoing = [];
const hadSelecton = hasSelectedBlock();
const selectionAnchor = getSelectionStart();
const selectionFocus = getSelectionEnd();
setControlledBlocks();
if (controlledSelection) {
resetSelection(controlledSelection.selectionStart, controlledSelection.selectionEnd, controlledSelection.initialPosition);
} else {
const selectionStillExists = getBlock(selectionAnchor.clientId);
if (hadSelecton && !selectionStillExists) {
selectBlock(clientId);
} else {
resetSelection(selectionAnchor, selectionFocus);
}
}
}
}, [controlledBlocks, clientId]);
(0,external_wp_element_namespaceObject.useEffect)(() => {
// When the block becomes uncontrolled, it means its inner state has been reset
// we need to take the blocks again from the external value property.
if (!isControlled) {
pendingChanges.current.outgoing = [];
setControlledBlocks();
}
}, [isControlled]);
(0,external_wp_element_namespaceObject.useEffect)(() => {
const {
getSelectedBlocksInitialCaretPosition,
isLastBlockChangePersistent,
__unstableIsLastBlockChangeIgnored,
areInnerBlocksControlled
} = registry.select(store);
let blocks = getBlocks(clientId);
let isPersistent = isLastBlockChangePersistent();
let previousAreBlocksDifferent = false;
subscribed.current = true;
const unsubscribe = registry.subscribe(() => {
// Sometimes, when changing block lists, lingering subscriptions
// might trigger before they are cleaned up. If the block for which
// the subscription runs is no longer in the store, this would clear
// its parent entity's block list. To avoid this, we bail out if
// the subscription is triggering for a block (`clientId !== null`)
// and its block name can't be found because it's not on the list.
// (`getBlockName( clientId ) === null`).
if (clientId !== null && getBlockName(clientId) === null) return;
// When RESET_BLOCKS on parent blocks get called, the controlled blocks
// can reset to uncontrolled, in these situations, it means we need to populate
// the blocks again from the external blocks (the value property here)
// and we should stop triggering onChange
const isStillControlled = !clientId || areInnerBlocksControlled(clientId);
if (!isStillControlled) {
return;
}
const newIsPersistent = isLastBlockChangePersistent();
const newBlocks = getBlocks(clientId);
const areBlocksDifferent = newBlocks !== blocks;
blocks = newBlocks;
if (areBlocksDifferent && (pendingChanges.current.incoming || __unstableIsLastBlockChangeIgnored())) {
pendingChanges.current.incoming = null;
isPersistent = newIsPersistent;
return;
}
// Since we often dispatch an action to mark the previous action as
// persistent, we need to make sure that the blocks changed on the
// previous action before committing the change.
const didPersistenceChange = previousAreBlocksDifferent && !areBlocksDifferent && newIsPersistent && !isPersistent;
if (areBlocksDifferent || didPersistenceChange) {
isPersistent = newIsPersistent;
// We know that onChange/onInput will update controlledBlocks.
// We need to be aware that it was caused by an outgoing change
// so that we do not treat it as an incoming change later on,
// which would cause a block reset.
pendingChanges.current.outgoing.push(blocks);
// Inform the controlling entity that changes have been made to
// the block-editor store they should be aware about.
const updateParent = isPersistent ? onChangeRef.current : onInputRef.current;
updateParent(blocks, {
selection: {
selectionStart: getSelectionStart(),
selectionEnd: getSelectionEnd(),
initialPosition: getSelectedBlocksInitialCaretPosition()
}
});
}
previousAreBlocksDifferent = areBlocksDifferent;
});
return () => {
subscribed.current = false;
unsubscribe();
};
}, [registry, clientId]);
(0,external_wp_element_namespaceObject.useEffect)(() => {
return () => {
unsetControlledBlocks();
};
}, []);
}
;// CONCATENATED MODULE: external ["wp","keyboardShortcuts"]
var external_wp_keyboardShortcuts_namespaceObject = window["wp"]["keyboardShortcuts"];
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/keyboard-shortcuts/index.js
/**
* WordPress dependencies
*/
function KeyboardShortcuts() {
return null;
}
function KeyboardShortcutsRegister() {
// Registering the shortcuts.
const {
registerShortcut
} = (0,external_wp_data_namespaceObject.useDispatch)(external_wp_keyboardShortcuts_namespaceObject.store);
(0,external_wp_element_namespaceObject.useEffect)(() => {
registerShortcut({
name: 'core/block-editor/duplicate',
category: 'block',
description: (0,external_wp_i18n_namespaceObject.__)('Duplicate the selected block(s).'),
keyCombination: {
modifier: 'primaryShift',
character: 'd'
}
});
registerShortcut({
name: 'core/block-editor/remove',
category: 'block',
description: (0,external_wp_i18n_namespaceObject.__)('Remove the selected block(s).'),
keyCombination: {
modifier: 'access',
character: 'z'
}
});
registerShortcut({
name: 'core/block-editor/insert-before',
category: 'block',
description: (0,external_wp_i18n_namespaceObject.__)('Insert a new block before the selected block(s).'),
keyCombination: {
modifier: 'primaryAlt',
character: 't'
}
});
registerShortcut({
name: 'core/block-editor/insert-after',
category: 'block',
description: (0,external_wp_i18n_namespaceObject.__)('Insert a new block after the selected block(s).'),
keyCombination: {
modifier: 'primaryAlt',
character: 'y'
}
});
registerShortcut({
name: 'core/block-editor/delete-multi-selection',
category: 'block',
description: (0,external_wp_i18n_namespaceObject.__)('Delete selection.'),
keyCombination: {
character: 'del'
},
aliases: [{
character: 'backspace'
}]
});
registerShortcut({
name: 'core/block-editor/select-all',
category: 'selection',
description: (0,external_wp_i18n_namespaceObject.__)('Select all text when typing. Press again to select all blocks.'),
keyCombination: {
modifier: 'primary',
character: 'a'
}
});
registerShortcut({
name: 'core/block-editor/unselect',
category: 'selection',
description: (0,external_wp_i18n_namespaceObject.__)('Clear selection.'),
keyCombination: {
character: 'escape'
}
});
registerShortcut({
name: 'core/block-editor/multi-text-selection',
category: 'selection',
description: (0,external_wp_i18n_namespaceObject.__)('Select text across multiple blocks.'),
keyCombination: {
modifier: 'shift',
character: 'arrow'
}
});
registerShortcut({
name: 'core/block-editor/focus-toolbar',
category: 'global',
description: (0,external_wp_i18n_namespaceObject.__)('Navigate to the nearest toolbar.'),
keyCombination: {
modifier: 'alt',
character: 'F10'
}
});
registerShortcut({
name: 'core/block-editor/move-up',
category: 'block',
description: (0,external_wp_i18n_namespaceObject.__)('Move the selected block(s) up.'),
keyCombination: {
modifier: 'secondary',
character: 't'
}
});
registerShortcut({
name: 'core/block-editor/move-down',
category: 'block',
description: (0,external_wp_i18n_namespaceObject.__)('Move the selected block(s) down.'),
keyCombination: {
modifier: 'secondary',
character: 'y'
}
});
}, [registerShortcut]);
return null;
}
KeyboardShortcuts.Register = KeyboardShortcutsRegister;
/* harmony default export */ var keyboard_shortcuts = (KeyboardShortcuts);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/provider/index.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
/** @typedef {import('@wordpress/data').WPDataRegistry} WPDataRegistry */
const ExperimentalBlockEditorProvider = with_registry_provider(props => {
const {
children,
settings,
stripExperimentalSettings = false
} = props;
const {
__experimentalUpdateSettings
} = unlock((0,external_wp_data_namespaceObject.useDispatch)(store));
(0,external_wp_element_namespaceObject.useEffect)(() => {
__experimentalUpdateSettings({
...settings,
__internalIsInitialized: true
}, {
stripExperimentalSettings,
reset: true
});
}, [settings, stripExperimentalSettings, __experimentalUpdateSettings]);
// Syncs the entity provider with changes in the block-editor store.
useBlockSync(props);
return (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.SlotFillProvider, {
passthrough: true
}, (0,external_wp_element_namespaceObject.createElement)(keyboard_shortcuts.Register, null), (0,external_wp_element_namespaceObject.createElement)(BlockRefsProvider, null, children));
});
const BlockEditorProvider = props => {
return (0,external_wp_element_namespaceObject.createElement)(ExperimentalBlockEditorProvider, {
...props,
stripExperimentalSettings: true
}, props.children);
};
/* harmony default export */ var provider = (BlockEditorProvider);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-selection-clearer/index.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
/**
* Pass the returned ref callback to an element that should clear block
* selection. Selection will only be cleared if the element is clicked directly,
* not if a child element is clicked.
*
* @return {import('react').RefCallback} Ref callback.
*/
function useBlockSelectionClearer() {
const {
getSettings,
hasSelectedBlock,
hasMultiSelection
} = (0,external_wp_data_namespaceObject.useSelect)(store);
const {
clearSelectedBlock
} = (0,external_wp_data_namespaceObject.useDispatch)(store);
const {
clearBlockSelection: isEnabled
} = getSettings();
return (0,external_wp_compose_namespaceObject.useRefEffect)(node => {
if (!isEnabled) {
return;
}
function onMouseDown(event) {
if (!hasSelectedBlock() && !hasMultiSelection()) {
return;
}
// Only handle clicks on the element, not the children.
if (event.target !== node) {
return;
}
clearSelectedBlock();
}
node.addEventListener('mousedown', onMouseDown);
return () => {
node.removeEventListener('mousedown', onMouseDown);
};
}, [hasSelectedBlock, hasMultiSelection, clearSelectedBlock, isEnabled]);
}
function BlockSelectionClearer(props) {
return (0,external_wp_element_namespaceObject.createElement)("div", {
ref: useBlockSelectionClearer(),
...props
});
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/writing-flow/use-multi-selection.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
function selector(select) {
const {
isMultiSelecting,
getMultiSelectedBlockClientIds,
hasMultiSelection,
getSelectedBlockClientId,
getSelectedBlocksInitialCaretPosition,
__unstableIsFullySelected
} = select(store);
return {
isMultiSelecting: isMultiSelecting(),
multiSelectedBlockClientIds: getMultiSelectedBlockClientIds(),
hasMultiSelection: hasMultiSelection(),
selectedBlockClientId: getSelectedBlockClientId(),
initialPosition: getSelectedBlocksInitialCaretPosition(),
isFullSelection: __unstableIsFullySelected()
};
}
function useMultiSelection() {
const {
initialPosition,
isMultiSelecting,
multiSelectedBlockClientIds,
hasMultiSelection,
selectedBlockClientId,
isFullSelection
} = (0,external_wp_data_namespaceObject.useSelect)(selector, []);
/**
* When the component updates, and there is multi selection, we need to
* select the entire block contents.
*/
return (0,external_wp_compose_namespaceObject.useRefEffect)(node => {
const {
ownerDocument
} = node;
const {
defaultView
} = ownerDocument;
// Allow initialPosition to bypass focus behavior. This is useful
// for the list view or other areas where we don't want to transfer
// focus to the editor canvas.
if (initialPosition === undefined || initialPosition === null) {
return;
}
if (!hasMultiSelection || isMultiSelecting) {
return;
}
const {
length
} = multiSelectedBlockClientIds;
if (length < 2) {
return;
}
if (!isFullSelection) {
return;
}
// Allow cross contentEditable selection by temporarily making
// all content editable. We can't rely on using the store and
// React because re-rending happens too slowly. We need to be
// able to select across instances immediately.
node.contentEditable = true;
// For some browsers, like Safari, it is important that focus
// happens BEFORE selection removal.
node.focus();
defaultView.getSelection().removeAllRanges();
}, [hasMultiSelection, isMultiSelecting, multiSelectedBlockClientIds, selectedBlockClientId, initialPosition, isFullSelection]);
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/writing-flow/use-tab-nav.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
function useTabNav() {
const container = (0,external_wp_element_namespaceObject.useRef)();
const focusCaptureBeforeRef = (0,external_wp_element_namespaceObject.useRef)();
const focusCaptureAfterRef = (0,external_wp_element_namespaceObject.useRef)();
const lastFocus = (0,external_wp_element_namespaceObject.useRef)();
const {
hasMultiSelection,
getSelectedBlockClientId,
getBlockCount
} = (0,external_wp_data_namespaceObject.useSelect)(store);
const {
setNavigationMode
} = (0,external_wp_data_namespaceObject.useDispatch)(store);
const isNavigationMode = (0,external_wp_data_namespaceObject.useSelect)(select => select(store).isNavigationMode(), []);
// Don't allow tabbing to this element in Navigation mode.
const focusCaptureTabIndex = !isNavigationMode ? '0' : undefined;
// Reference that holds the a flag for enabling or disabling
// capturing on the focus capture elements.
const noCapture = (0,external_wp_element_namespaceObject.useRef)();
function onFocusCapture(event) {
// Do not capture incoming focus if set by us in WritingFlow.
if (noCapture.current) {
noCapture.current = null;
} else if (hasMultiSelection()) {
container.current.focus();
} else if (getSelectedBlockClientId()) {
lastFocus.current.focus();
} else {
setNavigationMode(true);
const canvasElement = container.current.ownerDocument === event.target.ownerDocument ? container.current : container.current.ownerDocument.defaultView.frameElement;
const isBefore =
// eslint-disable-next-line no-bitwise
event.target.compareDocumentPosition(canvasElement) & event.target.DOCUMENT_POSITION_FOLLOWING;
const tabbables = external_wp_dom_namespaceObject.focus.tabbable.find(container.current);
if (tabbables.length) {
const next = isBefore ? tabbables[0] : tabbables[tabbables.length - 1];
next.focus();
}
}
}
const before = (0,external_wp_element_namespaceObject.createElement)("div", {
ref: focusCaptureBeforeRef,
tabIndex: focusCaptureTabIndex,
onFocus: onFocusCapture
});
const after = (0,external_wp_element_namespaceObject.createElement)("div", {
ref: focusCaptureAfterRef,
tabIndex: focusCaptureTabIndex,
onFocus: onFocusCapture
});
const ref = (0,external_wp_compose_namespaceObject.useRefEffect)(node => {
function onKeyDown(event) {
if (event.defaultPrevented) {
return;
}
if (event.keyCode === external_wp_keycodes_namespaceObject.ESCAPE && !hasMultiSelection()) {
event.preventDefault();
setNavigationMode(true);
return;
}
// In Edit mode, Tab should focus the first tabbable element after
// the content, which is normally the sidebar (with block controls)
// and Shift+Tab should focus the first tabbable element before the
// content, which is normally the block toolbar.
// Arrow keys can be used, and Tab and arrow keys can be used in
// Navigation mode (press Esc), to navigate through blocks.
if (event.keyCode !== external_wp_keycodes_namespaceObject.TAB) {
return;
}
const isShift = event.shiftKey;
const direction = isShift ? 'findPrevious' : 'findNext';
if (!hasMultiSelection() && !getSelectedBlockClientId()) {
// Preserve the behaviour of entering navigation mode when
// tabbing into the content without a block selection.
// `onFocusCapture` already did this previously, but we need to
// do it again here because after clearing block selection,
// focus land on the writing flow container and pressing Tab
// will no longer send focus through the focus capture element.
if (event.target === node) setNavigationMode(true);
return;
}
const nextTabbable = external_wp_dom_namespaceObject.focus.tabbable[direction](event.target);
// We want to constrain the tabbing to the block and its child blocks.
// If the preceding form element is within a different block,
// such as two sibling image blocks in the placeholder state,
// we want shift + tab from the first form element to move to the image
// block toolbar and not the previous image block's form element.
const currentBlock = event.target.closest('[data-block]');
const isElementPartOfSelectedBlock = currentBlock && nextTabbable && (isInSameBlock(currentBlock, nextTabbable) || isInsideRootBlock(currentBlock, nextTabbable));
// Allow tabbing from the block wrapper to a form element,
// and between form elements rendered in a block and its child blocks,
// such as inside a placeholder. Form elements are generally
// meant to be UI rather than part of the content. Ideally
// these are not rendered in the content and perhaps in the
// future they can be rendered in an iframe or shadow DOM.
if ((0,external_wp_dom_namespaceObject.isFormElement)(nextTabbable) && isElementPartOfSelectedBlock) {
return;
}
const next = isShift ? focusCaptureBeforeRef : focusCaptureAfterRef;
// Disable focus capturing on the focus capture element, so it
// doesn't refocus this block and so it allows default behaviour
// (moving focus to the next tabbable element).
noCapture.current = true;
// Focusing the focus capture element, which is located above and
// below the editor, should not scroll the page all the way up or
// down.
next.current.focus({
preventScroll: true
});
}
function onFocusOut(event) {
lastFocus.current = event.target;
const {
ownerDocument
} = node;
// If focus disappears due to there being no blocks, move focus to
// the writing flow wrapper.
if (!event.relatedTarget && ownerDocument.activeElement === ownerDocument.body && getBlockCount() === 0) {
node.focus();
}
}
// When tabbing back to an element in block list, this event handler prevents scrolling if the
// focus capture divs (before/after) are outside of the viewport. (For example shift+tab back to a paragraph
// when focus is on a sidebar element. This prevents the scrollable writing area from jumping either to the
// top or bottom of the document.
//
// Note that it isn't possible to disable scrolling in the onFocus event. We need to intercept this
// earlier in the keypress handler, and call focus( { preventScroll: true } ) instead.
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLOrForeignElement/focus#parameters
function preventScrollOnTab(event) {
if (event.keyCode !== external_wp_keycodes_namespaceObject.TAB) {
return;
}
if (event.target?.getAttribute('role') === 'region') {
return;
}
if (container.current === event.target) {
return;
}
const isShift = event.shiftKey;
const direction = isShift ? 'findPrevious' : 'findNext';
const target = external_wp_dom_namespaceObject.focus.tabbable[direction](event.target);
// Only do something when the next tabbable is a focus capture div (before/after)
if (target === focusCaptureBeforeRef.current || target === focusCaptureAfterRef.current) {
event.preventDefault();
target.focus({
preventScroll: true
});
}
}
const {
ownerDocument
} = node;
const {
defaultView
} = ownerDocument;
defaultView.addEventListener('keydown', preventScrollOnTab);
node.addEventListener('keydown', onKeyDown);
node.addEventListener('focusout', onFocusOut);
return () => {
defaultView.removeEventListener('keydown', preventScrollOnTab);
node.removeEventListener('keydown', onKeyDown);
node.removeEventListener('focusout', onFocusOut);
};
}, []);
const mergedRefs = (0,external_wp_compose_namespaceObject.useMergeRefs)([container, ref]);
return [before, mergedRefs, after];
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/writing-flow/use-arrow-nav.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
/**
* Returns true if the element should consider edge navigation upon a keyboard
* event of the given directional key code, or false otherwise.
*
* @param {Element} element HTML element to test.
* @param {number} keyCode KeyboardEvent keyCode to test.
* @param {boolean} hasModifier Whether a modifier is pressed.
*
* @return {boolean} Whether element should consider edge navigation.
*/
function isNavigationCandidate(element, keyCode, hasModifier) {
const isVertical = keyCode === external_wp_keycodes_namespaceObject.UP || keyCode === external_wp_keycodes_namespaceObject.DOWN;
const {
tagName
} = element;
const elementType = element.getAttribute('type');
// Native inputs should not navigate vertically, unless they are simple types that don't need up/down arrow keys.
if (isVertical && !hasModifier) {
if (tagName === 'INPUT') {
const verticalInputTypes = ['date', 'datetime-local', 'month', 'number', 'range', 'time', 'week'];
return !verticalInputTypes.includes(elementType);
}
return true;
}
// Native inputs should not navigate horizontally, unless they are simple types that don't need left/right arrow keys.
if (tagName === 'INPUT') {
const simpleInputTypes = ['button', 'checkbox', 'number', 'color', 'file', 'image', 'radio', 'reset', 'submit'];
return simpleInputTypes.includes(elementType);
}
// Native textareas should not navigate horizontally.
return tagName !== 'TEXTAREA';
}
/**
* Returns the optimal tab target from the given focused element in the desired
* direction. A preference is made toward text fields, falling back to the block
* focus stop if no other candidates exist for the block.
*
* @param {Element} target Currently focused text field.
* @param {boolean} isReverse True if considering as the first field.
* @param {Element} containerElement Element containing all blocks.
* @param {boolean} onlyVertical Whether to only consider tabbable elements
* that are visually above or under the
* target.
*
* @return {?Element} Optimal tab target, if one exists.
*/
function getClosestTabbable(target, isReverse, containerElement, onlyVertical) {
// Since the current focus target is not guaranteed to be a text field, find
// all focusables. Tabbability is considered later.
let focusableNodes = external_wp_dom_namespaceObject.focus.focusable.find(containerElement);
if (isReverse) {
focusableNodes.reverse();
}
// Consider as candidates those focusables after the current target. It's
// assumed this can only be reached if the target is focusable (on its
// keydown event), so no need to verify it exists in the set.
focusableNodes = focusableNodes.slice(focusableNodes.indexOf(target) + 1);
let targetRect;
if (onlyVertical) {
targetRect = target.getBoundingClientRect();
}
function isTabCandidate(node) {
// Skip if there's only one child that is content editable (and thus a
// better candidate).
if (node.children.length === 1 && isInSameBlock(node, node.firstElementChild) && node.firstElementChild.getAttribute('contenteditable') === 'true') {
return;
}
// Not a candidate if the node is not tabbable.
if (!external_wp_dom_namespaceObject.focus.tabbable.isTabbableIndex(node)) {
return false;
}
// Skip focusable elements such as links within content editable nodes.
if (node.isContentEditable && node.contentEditable !== 'true') {
return false;
}
if (onlyVertical) {
const nodeRect = node.getBoundingClientRect();
if (nodeRect.left >= targetRect.right || nodeRect.right <= targetRect.left) {
return false;
}
}
return true;
}
return focusableNodes.find(isTabCandidate);
}
function useArrowNav() {
const {
getMultiSelectedBlocksStartClientId,
getMultiSelectedBlocksEndClientId,
getSettings,
hasMultiSelection,
__unstableIsFullySelected
} = (0,external_wp_data_namespaceObject.useSelect)(store);
const {
selectBlock
} = (0,external_wp_data_namespaceObject.useDispatch)(store);
return (0,external_wp_compose_namespaceObject.useRefEffect)(node => {
// Here a DOMRect is stored while moving the caret vertically so
// vertical position of the start position can be restored. This is to
// recreate browser behaviour across blocks.
let verticalRect;
function onMouseDown() {
verticalRect = null;
}
function isClosestTabbableABlock(target, isReverse) {
const closestTabbable = getClosestTabbable(target, isReverse, node);
return closestTabbable && getBlockClientId(closestTabbable);
}
function onKeyDown(event) {
// Abort if navigation has already been handled (e.g. RichText
// inline boundaries).
if (event.defaultPrevented) {
return;
}
const {
keyCode,
target,
shiftKey,
ctrlKey,
altKey,
metaKey
} = event;
const isUp = keyCode === external_wp_keycodes_namespaceObject.UP;
const isDown = keyCode === external_wp_keycodes_namespaceObject.DOWN;
const isLeft = keyCode === external_wp_keycodes_namespaceObject.LEFT;
const isRight = keyCode === external_wp_keycodes_namespaceObject.RIGHT;
const isReverse = isUp || isLeft;
const isHorizontal = isLeft || isRight;
const isVertical = isUp || isDown;
const isNav = isHorizontal || isVertical;
const hasModifier = shiftKey || ctrlKey || altKey || metaKey;
const isNavEdge = isVertical ? external_wp_dom_namespaceObject.isVerticalEdge : external_wp_dom_namespaceObject.isHorizontalEdge;
const {
ownerDocument
} = node;
const {
defaultView
} = ownerDocument;
if (!isNav) {
return;
}
// If there is a multi-selection, the arrow keys should collapse the
// selection to the start or end of the selection.
if (hasMultiSelection()) {
if (shiftKey) {
return;
}
// Only handle if we have a full selection (not a native partial
// selection).
if (!__unstableIsFullySelected()) {
return;
}
event.preventDefault();
if (isReverse) {
selectBlock(getMultiSelectedBlocksStartClientId());
} else {
selectBlock(getMultiSelectedBlocksEndClientId(), -1);
}
return;
}
// Abort if our current target is not a candidate for navigation
// (e.g. preserve native input behaviors).
if (!isNavigationCandidate(target, keyCode, hasModifier)) {
return;
}
// When presing any key other than up or down, the initial vertical
// position must ALWAYS be reset. The vertical position is saved so
// it can be restored as well as possible on sebsequent vertical
// arrow key presses. It may not always be possible to restore the
// exact same position (such as at an empty line), so it wouldn't be
// good to compute the position right before any vertical arrow key
// press.
if (!isVertical) {
verticalRect = null;
} else if (!verticalRect) {
verticalRect = (0,external_wp_dom_namespaceObject.computeCaretRect)(defaultView);
}
// In the case of RTL scripts, right means previous and left means
// next, which is the exact reverse of LTR.
const isReverseDir = (0,external_wp_dom_namespaceObject.isRTL)(target) ? !isReverse : isReverse;
const {
keepCaretInsideBlock
} = getSettings();
if (shiftKey) {
if (isClosestTabbableABlock(target, isReverse) && isNavEdge(target, isReverse)) {
node.contentEditable = true;
// Firefox doesn't automatically move focus.
node.focus();
}
} else if (isVertical && (0,external_wp_dom_namespaceObject.isVerticalEdge)(target, isReverse) && (
// When Alt is pressed, only intercept if the caret is also at
// the horizontal edge.
altKey ? (0,external_wp_dom_namespaceObject.isHorizontalEdge)(target, isReverseDir) : true) && !keepCaretInsideBlock) {
const closestTabbable = getClosestTabbable(target, isReverse, node, true);
if (closestTabbable) {
(0,external_wp_dom_namespaceObject.placeCaretAtVerticalEdge)(closestTabbable,
// When Alt is pressed, place the caret at the furthest
// horizontal edge and the furthest vertical edge.
altKey ? !isReverse : isReverse, altKey ? undefined : verticalRect);
event.preventDefault();
}
} else if (isHorizontal && defaultView.getSelection().isCollapsed && (0,external_wp_dom_namespaceObject.isHorizontalEdge)(target, isReverseDir) && !keepCaretInsideBlock) {
const closestTabbable = getClosestTabbable(target, isReverseDir, node);
(0,external_wp_dom_namespaceObject.placeCaretAtHorizontalEdge)(closestTabbable, isReverse);
event.preventDefault();
}
}
node.addEventListener('mousedown', onMouseDown);
node.addEventListener('keydown', onKeyDown);
return () => {
node.removeEventListener('mousedown', onMouseDown);
node.removeEventListener('keydown', onKeyDown);
};
}, []);
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/writing-flow/use-select-all.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
function useSelectAll() {
const {
getBlockOrder,
getSelectedBlockClientIds,
getBlockRootClientId
} = (0,external_wp_data_namespaceObject.useSelect)(store);
const {
multiSelect,
selectBlock
} = (0,external_wp_data_namespaceObject.useDispatch)(store);
const isMatch = (0,external_wp_keyboardShortcuts_namespaceObject.__unstableUseShortcutEventMatch)();
return (0,external_wp_compose_namespaceObject.useRefEffect)(node => {
function onKeyDown(event) {
if (!isMatch('core/block-editor/select-all', event)) {
return;
}
const selectedClientIds = getSelectedBlockClientIds();
if (selectedClientIds.length < 2 && !(0,external_wp_dom_namespaceObject.isEntirelySelected)(event.target)) {
return;
}
event.preventDefault();
const [firstSelectedClientId] = selectedClientIds;
const rootClientId = getBlockRootClientId(firstSelectedClientId);
const blockClientIds = getBlockOrder(rootClientId);
// If we have selected all sibling nested blocks, try selecting up a
// level. See: https://github.com/WordPress/gutenberg/pull/31859/
if (selectedClientIds.length === blockClientIds.length) {
if (rootClientId) {
node.ownerDocument.defaultView.getSelection().removeAllRanges();
selectBlock(rootClientId);
}
return;
}
multiSelect(blockClientIds[0], blockClientIds[blockClientIds.length - 1]);
}
node.addEventListener('keydown', onKeyDown);
return () => {
node.removeEventListener('keydown', onKeyDown);
};
}, []);
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/writing-flow/use-drag-selection.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
/**
* Sets the `contenteditable` wrapper element to `value`.
*
* @param {HTMLElement} node Block element.
* @param {boolean} value `contentEditable` value (true or false)
*/
function setContentEditableWrapper(node, value) {
node.contentEditable = value;
// Firefox doesn't automatically move focus.
if (value) node.focus();
}
/**
* Sets a multi-selection based on the native selection across blocks.
*/
function useDragSelection() {
const {
startMultiSelect,
stopMultiSelect
} = (0,external_wp_data_namespaceObject.useDispatch)(store);
const {
isSelectionEnabled,
hasMultiSelection,
isDraggingBlocks
} = (0,external_wp_data_namespaceObject.useSelect)(store);
return (0,external_wp_compose_namespaceObject.useRefEffect)(node => {
const {
ownerDocument
} = node;
const {
defaultView
} = ownerDocument;
let anchorElement;
let rafId;
function onMouseUp() {
stopMultiSelect();
// Equivalent to attaching the listener once.
defaultView.removeEventListener('mouseup', onMouseUp);
// The browser selection won't have updated yet at this point,
// so wait until the next animation frame to get the browser
// selection.
rafId = defaultView.requestAnimationFrame(() => {
if (hasMultiSelection()) {
return;
}
// If the selection is complete (on mouse up), and no
// multiple blocks have been selected, set focus back to the
// anchor element. if the anchor element contains the
// selection. Additionally, the contentEditable wrapper can
// now be disabled again.
setContentEditableWrapper(node, false);
const selection = defaultView.getSelection();
if (selection.rangeCount) {
const {
commonAncestorContainer
} = selection.getRangeAt(0);
if (anchorElement.contains(commonAncestorContainer)) {
anchorElement.focus();
}
}
});
}
function onMouseLeave({
buttons,
target
}) {
// Avoid triggering a multi-selection if the user is already
// dragging blocks.
if (isDraggingBlocks()) {
return;
}
// The primary button must be pressed to initiate selection.
// See https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/buttons
if (buttons !== 1) {
return;
}
// Check the attribute, not the contentEditable attribute. All
// child elements of the content editable wrapper are editable
// and return true for this property. We only want to start
// multi selecting when the mouse leaves the wrapper.
if (target.getAttribute('contenteditable') !== 'true') {
return;
}
if (!isSelectionEnabled()) {
return;
}
// Do not rely on the active element because it may change after
// the mouse leaves for the first time. See
// https://github.com/WordPress/gutenberg/issues/48747.
anchorElement = target;
startMultiSelect();
// `onSelectionStart` is called after `mousedown` and
// `mouseleave` (from a block). The selection ends when
// `mouseup` happens anywhere in the window.
defaultView.addEventListener('mouseup', onMouseUp);
// Allow cross contentEditable selection by temporarily making
// all content editable. We can't rely on using the store and
// React because re-rending happens too slowly. We need to be
// able to select across instances immediately.
setContentEditableWrapper(node, true);
}
node.addEventListener('mouseout', onMouseLeave);
return () => {
node.removeEventListener('mouseout', onMouseLeave);
defaultView.removeEventListener('mouseup', onMouseUp);
defaultView.cancelAnimationFrame(rafId);
};
}, [startMultiSelect, stopMultiSelect, isSelectionEnabled, hasMultiSelection]);
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/writing-flow/use-selection-observer.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
/**
* Extract the selection start node from the selection. When the anchor node is
* not a text node, the selection offset is the index of a child node.
*
* @param {Selection} selection The selection.
*
* @return {Element} The selection start node.
*/
function extractSelectionStartNode(selection) {
const {
anchorNode,
anchorOffset
} = selection;
if (anchorNode.nodeType === anchorNode.TEXT_NODE) {
return anchorNode;
}
if (anchorOffset === 0) {
return anchorNode;
}
return anchorNode.childNodes[anchorOffset - 1];
}
/**
* Extract the selection end node from the selection. When the focus node is not
* a text node, the selection offset is the index of a child node. The selection
* reaches up to but excluding that child node.
*
* @param {Selection} selection The selection.
*
* @return {Element} The selection start node.
*/
function extractSelectionEndNode(selection) {
const {
focusNode,
focusOffset
} = selection;
if (focusNode.nodeType === focusNode.TEXT_NODE) {
return focusNode;
}
if (focusOffset === focusNode.childNodes.length) {
return focusNode;
}
return focusNode.childNodes[focusOffset];
}
function findDepth(a, b) {
let depth = 0;
while (a[depth] === b[depth]) {
depth++;
}
return depth;
}
/**
* Sets the `contenteditable` wrapper element to `value`.
*
* @param {HTMLElement} node Block element.
* @param {boolean} value `contentEditable` value (true or false)
*/
function use_selection_observer_setContentEditableWrapper(node, value) {
// Since we are calling this on every selection change, check if the value
// needs to be updated first because it trigger the browser to recalculate
// style.
if (node.contentEditable !== String(value)) node.contentEditable = value;
// Firefox doesn't automatically move focus.
if (value) node.focus();
}
/**
* Sets a multi-selection based on the native selection across blocks.
*/
function useSelectionObserver() {
const {
multiSelect,
selectBlock,
selectionChange
} = (0,external_wp_data_namespaceObject.useDispatch)(store);
const {
getBlockParents,
getBlockSelectionStart
} = (0,external_wp_data_namespaceObject.useSelect)(store);
return (0,external_wp_compose_namespaceObject.useRefEffect)(node => {
const {
ownerDocument
} = node;
const {
defaultView
} = ownerDocument;
function onSelectionChange(event) {
const selection = defaultView.getSelection();
if (!selection.rangeCount) {
return;
}
// If selection is collapsed and we haven't used `shift+click`,
// end multi selection and disable the contentEditable wrapper.
// We have to check about `shift+click` case because elements
// that don't support text selection might be involved, and we might
// update the clientIds to multi-select blocks.
// For now we check if the event is a `mouse` event.
const isClickShift = event.shiftKey && event.type === 'mouseup';
if (selection.isCollapsed && !isClickShift) {
use_selection_observer_setContentEditableWrapper(node, false);
return;
}
let startClientId = getBlockClientId(extractSelectionStartNode(selection));
let endClientId = getBlockClientId(extractSelectionEndNode(selection));
// If the selection has changed and we had pressed `shift+click`,
// we need to check if in an element that doesn't support
// text selection has been clicked.
if (isClickShift) {
const selectedClientId = getBlockSelectionStart();
const clickedClientId = getBlockClientId(event.target);
// `endClientId` is not defined if we end the selection by clicking a non-selectable block.
// We need to check if there was already a selection with a non-selectable focusNode.
const focusNodeIsNonSelectable = clickedClientId !== endClientId;
if (startClientId === endClientId && selection.isCollapsed || !endClientId || focusNodeIsNonSelectable) {
endClientId = clickedClientId;
}
// Handle the case when we have a non-selectable block
// selected and click another one.
if (startClientId !== selectedClientId) {
startClientId = selectedClientId;
}
}
// If the selection did not involve a block, return.
if (startClientId === undefined && endClientId === undefined) {
use_selection_observer_setContentEditableWrapper(node, false);
return;
}
const isSingularSelection = startClientId === endClientId;
if (isSingularSelection) {
selectBlock(startClientId);
} else {
const startPath = [...getBlockParents(startClientId), startClientId];
const endPath = [...getBlockParents(endClientId), endClientId];
const depth = findDepth(startPath, endPath);
multiSelect(startPath[depth], endPath[depth]);
}
}
function addListeners() {
ownerDocument.addEventListener('selectionchange', onSelectionChange);
defaultView.addEventListener('mouseup', onSelectionChange);
}
function removeListeners() {
ownerDocument.removeEventListener('selectionchange', onSelectionChange);
defaultView.removeEventListener('mouseup', onSelectionChange);
}
function resetListeners() {
removeListeners();
addListeners();
}
addListeners();
// We must allow rich text to set selection first. This ensures that
// our `selectionchange` listener is always reset to be called after
// the rich text one.
node.addEventListener('focusin', resetListeners);
return () => {
removeListeners();
node.removeEventListener('focusin', resetListeners);
};
}, [multiSelect, selectBlock, selectionChange, getBlockParents]);
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/writing-flow/use-click-selection.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
function useClickSelection() {
const {
selectBlock
} = (0,external_wp_data_namespaceObject.useDispatch)(store);
const {
isSelectionEnabled,
getBlockSelectionStart,
hasMultiSelection
} = (0,external_wp_data_namespaceObject.useSelect)(store);
return (0,external_wp_compose_namespaceObject.useRefEffect)(node => {
function onMouseDown(event) {
// The main button.
// https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/button
if (!isSelectionEnabled() || event.button !== 0) {
return;
}
const startClientId = getBlockSelectionStart();
const clickedClientId = getBlockClientId(event.target);
if (event.shiftKey) {
if (startClientId !== clickedClientId) {
node.contentEditable = true;
// Firefox doesn't automatically move focus.
node.focus();
}
} else if (hasMultiSelection()) {
// Allow user to escape out of a multi-selection to a
// singular selection of a block via click. This is handled
// here since focus handling excludes blocks when there is
// multiselection, as focus can be incurred by starting a
// multiselection (focus moved to first block's multi-
// controls).
selectBlock(clickedClientId);
}
}
node.addEventListener('mousedown', onMouseDown);
return () => {
node.removeEventListener('mousedown', onMouseDown);
};
}, [selectBlock, isSelectionEnabled, getBlockSelectionStart, hasMultiSelection]);
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/writing-flow/use-input.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
/**
* Handles input for selections across blocks.
*/
function useInput() {
const {
__unstableIsFullySelected,
getSelectedBlockClientIds,
__unstableIsSelectionMergeable,
hasMultiSelection
} = (0,external_wp_data_namespaceObject.useSelect)(store);
const {
replaceBlocks,
__unstableSplitSelection,
removeBlocks,
__unstableDeleteSelection,
__unstableExpandSelection
} = (0,external_wp_data_namespaceObject.useDispatch)(store);
return (0,external_wp_compose_namespaceObject.useRefEffect)(node => {
function onBeforeInput(event) {
// If writing flow is editable, NEVER allow the browser to alter the
// DOM. This will cause React errors (and the DOM should only be
// altered in a controlled fashion).
if (node.contentEditable === 'true') {
event.preventDefault();
}
}
function onKeyDown(event) {
if (event.defaultPrevented) {
return;
}
if (!hasMultiSelection()) {
return;
}
if (event.keyCode === external_wp_keycodes_namespaceObject.ENTER) {
node.contentEditable = false;
event.preventDefault();
if (__unstableIsFullySelected()) {
replaceBlocks(getSelectedBlockClientIds(), (0,external_wp_blocks_namespaceObject.createBlock)((0,external_wp_blocks_namespaceObject.getDefaultBlockName)()));
} else {
__unstableSplitSelection();
}
} else if (event.keyCode === external_wp_keycodes_namespaceObject.BACKSPACE || event.keyCode === external_wp_keycodes_namespaceObject.DELETE) {
node.contentEditable = false;
event.preventDefault();
if (__unstableIsFullySelected()) {
removeBlocks(getSelectedBlockClientIds());
} else if (__unstableIsSelectionMergeable()) {
__unstableDeleteSelection(event.keyCode === external_wp_keycodes_namespaceObject.DELETE);
} else {
__unstableExpandSelection();
}
} else if (
// If key.length is longer than 1, it's a control key that doesn't
// input anything.
event.key.length === 1 && !(event.metaKey || event.ctrlKey)) {
node.contentEditable = false;
if (__unstableIsSelectionMergeable()) {
__unstableDeleteSelection(event.keyCode === external_wp_keycodes_namespaceObject.DELETE);
} else {
event.preventDefault();
// Safari does not stop default behaviour with either
// event.preventDefault() or node.contentEditable = false, so
// remove the selection to stop browser manipulation.
node.ownerDocument.defaultView.getSelection().removeAllRanges();
}
}
}
function onCompositionStart(event) {
if (!hasMultiSelection()) {
return;
}
node.contentEditable = false;
if (__unstableIsSelectionMergeable()) {
__unstableDeleteSelection();
} else {
event.preventDefault();
// Safari does not stop default behaviour with either
// event.preventDefault() or node.contentEditable = false, so
// remove the selection to stop browser manipulation.
node.ownerDocument.defaultView.getSelection().removeAllRanges();
}
}
node.addEventListener('beforeinput', onBeforeInput);
node.addEventListener('keydown', onKeyDown);
node.addEventListener('compositionstart', onCompositionStart);
return () => {
node.removeEventListener('beforeinput', onBeforeInput);
node.removeEventListener('keydown', onKeyDown);
node.removeEventListener('compositionstart', onCompositionStart);
};
}, []);
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/writing-flow/index.js
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
function useWritingFlow() {
const [before, ref, after] = useTabNav();
const hasMultiSelection = (0,external_wp_data_namespaceObject.useSelect)(select => select(store).hasMultiSelection(), []);
return [before, (0,external_wp_compose_namespaceObject.useMergeRefs)([ref, useInput(), useDragSelection(), useSelectionObserver(), useClickSelection(), useMultiSelection(), useSelectAll(), useArrowNav(), (0,external_wp_compose_namespaceObject.useRefEffect)(node => {
node.tabIndex = 0;
node.contentEditable = hasMultiSelection;
if (!hasMultiSelection) {
return;
}
node.classList.add('has-multi-selection');
node.setAttribute('aria-label', (0,external_wp_i18n_namespaceObject.__)('Multiple selected blocks'));
return () => {
node.classList.remove('has-multi-selection');
node.removeAttribute('aria-label');
};
}, [hasMultiSelection])]), after];
}
function WritingFlow({
children,
...props
}, forwardedRef) {
const [before, ref, after] = useWritingFlow();
return (0,external_wp_element_namespaceObject.createElement)(external_wp_element_namespaceObject.Fragment, null, before, (0,external_wp_element_namespaceObject.createElement)("div", {
...props,
ref: (0,external_wp_compose_namespaceObject.useMergeRefs)([ref, forwardedRef]),
className: classnames_default()(props.className, 'block-editor-writing-flow')
}, children), after);
}
/**
* Handles selection and navigation across blocks. This component should be
* wrapped around BlockList.
*
* @param {Object} props Component properties.
* @param {WPElement} props.children Children to be rendered.
*/
/* harmony default export */ var writing_flow = ((0,external_wp_element_namespaceObject.forwardRef)(WritingFlow));
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/iframe/use-compatibility-styles.js
/**
* WordPress dependencies
*/
/**
* Returns a list of stylesheets that target the editor canvas. A stylesheet is
* considered targetting the editor a canvas if it contains the
* `editor-styles-wrapper`, `wp-block`, or `wp-block-*` class selectors.
*
* Ideally, this hook should be removed in the future and styles should be added
* explicitly as editor styles.
*/
function useCompatibilityStyles() {
// Only memoize the result once on load, since these stylesheets should not
// change.
return (0,external_wp_element_namespaceObject.useMemo)(() => {
// Search the document for stylesheets targetting the editor canvas.
return Array.from(document.styleSheets).reduce((accumulator, styleSheet) => {
try {
// May fail for external styles.
// eslint-disable-next-line no-unused-expressions
styleSheet.cssRules;
} catch (e) {
return accumulator;
}
const {
ownerNode,
cssRules
} = styleSheet;
// Stylesheet is added by another stylesheet. See
// https://developer.mozilla.org/en-US/docs/Web/API/StyleSheet/ownerNode#notes.
if (ownerNode === null) {
return accumulator;
}
if (!cssRules) {
return accumulator;
}
// Don't try to add the reset styles, which were removed as a dependency
// from `edit-blocks` for the iframe since we don't need to reset admin
// styles.
if (ownerNode.id === 'wp-reset-editor-styles-css') {
return accumulator;
}
// Don't try to add styles without ID. Styles enqueued via the WP dependency system will always have IDs.
if (!ownerNode.id) {
return accumulator;
}
function matchFromRules(_cssRules) {
return Array.from(_cssRules).find(({
selectorText,
conditionText,
cssRules: __cssRules
}) => {
// If the rule is conditional then it will not have selector text.
// Recurse into child CSS ruleset to determine selector eligibility.
if (conditionText) {
return matchFromRules(__cssRules);
}
return selectorText && (selectorText.includes('.editor-styles-wrapper') || selectorText.includes('.wp-block'));
});
}
if (matchFromRules(cssRules)) {
const isInline = ownerNode.tagName === 'STYLE';
if (isInline) {
// If the current target is inline,
// it could be a dependency of an existing stylesheet.
// Look for that dependency and add it BEFORE the current target.
const mainStylesCssId = ownerNode.id.replace('-inline-css', '-css');
const mainStylesElement = document.getElementById(mainStylesCssId);
if (mainStylesElement) {
accumulator.push(mainStylesElement.cloneNode(true));
}
}
accumulator.push(ownerNode.cloneNode(true));
if (!isInline) {
// If the current target is not inline,
// we still look for inline styles that could be relevant for the current target.
// If they exist, add them AFTER the current target.
const inlineStylesCssId = ownerNode.id.replace('-css', '-inline-css');
const inlineStylesElement = document.getElementById(inlineStylesCssId);
if (inlineStylesElement) {
accumulator.push(inlineStylesElement.cloneNode(true));
}
}
}
return accumulator;
}, []);
}, []);
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/iframe/index.js
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
function bubbleEvent(event, Constructor, frame) {
const init = {};
for (const key in event) {
init[key] = event[key];
}
// Check if the event is a MouseEvent generated within the iframe.
// If so, adjust the coordinates to be relative to the position of
// the iframe. This ensures that components such as Draggable
// receive coordinates relative to the window, instead of relative
// to the iframe. Without this, the Draggable event handler would
// result in components "jumping" position as soon as the user
// drags over the iframe.
if (event instanceof frame.contentDocument.defaultView.MouseEvent) {
const rect = frame.getBoundingClientRect();
init.clientX += rect.left;
init.clientY += rect.top;
}
const newEvent = new Constructor(event.type, init);
if (init.defaultPrevented) {
newEvent.preventDefault();
}
const cancelled = !frame.dispatchEvent(newEvent);
if (cancelled) {
event.preventDefault();
}
}
/**
* Bubbles some event types (keydown, keypress, and dragover) to parent document
* document to ensure that the keyboard shortcuts and drag and drop work.
*
* Ideally, we should remove event bubbling in the future. Keyboard shortcuts
* should be context dependent, e.g. actions on blocks like Cmd+A should not
* work globally outside the block editor.
*
* @param {Document} iframeDocument Document to attach listeners to.
*/
function useBubbleEvents(iframeDocument) {
return (0,external_wp_compose_namespaceObject.useRefEffect)(body => {
const {
defaultView
} = iframeDocument;
if (!defaultView) {
return;
}
const {
frameElement
} = defaultView;
const eventTypes = ['dragover', 'mousemove'];
const handlers = {};
for (const name of eventTypes) {
handlers[name] = event => {
const prototype = Object.getPrototypeOf(event);
const constructorName = prototype.constructor.name;
const Constructor = window[constructorName];
bubbleEvent(event, Constructor, frameElement);
};
body.addEventListener(name, handlers[name]);
}
return () => {
for (const name of eventTypes) {
body.removeEventListener(name, handlers[name]);
}
};
});
}
function Iframe({
contentRef,
children,
tabIndex = 0,
scale = 1,
frameSize = 0,
expand = false,
readonly,
forwardedRef: ref,
...props
}) {
const {
resolvedAssets,
isPreviewMode
} = (0,external_wp_data_namespaceObject.useSelect)(select => {
const settings = select(store).getSettings();
return {
resolvedAssets: settings.__unstableResolvedAssets,
isPreviewMode: settings.__unstableIsPreviewMode
};
}, []);
const {
styles = '',
scripts = ''
} = resolvedAssets;
const [iframeDocument, setIframeDocument] = (0,external_wp_element_namespaceObject.useState)();
const [bodyClasses, setBodyClasses] = (0,external_wp_element_namespaceObject.useState)([]);
const compatStyles = useCompatibilityStyles();
const clearerRef = useBlockSelectionClearer();
const [before, writingFlowRef, after] = useWritingFlow();
const [contentResizeListener, {
height: contentHeight
}] = (0,external_wp_compose_namespaceObject.useResizeObserver)();
const setRef = (0,external_wp_compose_namespaceObject.useRefEffect)(node => {
node._load = () => {
setIframeDocument(node.contentDocument);
};
let iFrameDocument;
// Prevent the default browser action for files dropped outside of dropzones.
function preventFileDropDefault(event) {
event.preventDefault();
}
function onLoad() {
const {
contentDocument,
ownerDocument
} = node;
const {
documentElement
} = contentDocument;
iFrameDocument = contentDocument;
clearerRef(documentElement);
// Ideally ALL classes that are added through get_body_class should
// be added in the editor too, which we'll somehow have to get from
// the server in the future (which will run the PHP filters).
setBodyClasses(Array.from(ownerDocument.body.classList).filter(name => name.startsWith('admin-color-') || name.startsWith('post-type-') || name === 'wp-embed-responsive'));
contentDocument.dir = ownerDocument.dir;
for (const compatStyle of compatStyles) {
if (contentDocument.getElementById(compatStyle.id)) {
continue;
}
contentDocument.head.appendChild(compatStyle.cloneNode(true));
if (!isPreviewMode) {
// eslint-disable-next-line no-console
console.warn(`${compatStyle.id} was added to the iframe incorrectly. Please use block.json or enqueue_block_assets to add styles to the iframe.`, compatStyle);
}
}
iFrameDocument.addEventListener('dragover', preventFileDropDefault, false);
iFrameDocument.addEventListener('drop', preventFileDropDefault, false);
}
node.addEventListener('load', onLoad);
return () => {
delete node._load;
node.removeEventListener('load', onLoad);
iFrameDocument?.removeEventListener('dragover', preventFileDropDefault);
iFrameDocument?.removeEventListener('drop', preventFileDropDefault);
};
}, []);
const disabledRef = (0,external_wp_compose_namespaceObject.useDisabled)({
isDisabled: !readonly
});
const bodyRef = (0,external_wp_compose_namespaceObject.useMergeRefs)([useBubbleEvents(iframeDocument), contentRef, clearerRef, writingFlowRef, disabledRef]);
// Correct doctype is required to enable rendering in standards
// mode. Also preload the styles to avoid a flash of unstyled
// content.
const html = `
${styles}
${scripts}
`;
const [src, cleanup] = (0,external_wp_element_namespaceObject.useMemo)(() => {
const _src = URL.createObjectURL(new window.Blob([html], {
type: 'text/html'
}));
return [_src, () => URL.revokeObjectURL(_src)];
}, [html]);
(0,external_wp_element_namespaceObject.useEffect)(() => cleanup, [cleanup]);
// We need to counter the margin created by scaling the iframe. If the scale
// is e.g. 0.45, then the top + bottom margin is 0.55 (1 - scale). Just the
// top or bottom margin is 0.55 / 2 ((1 - scale) / 2).
const marginFromScaling = contentHeight * (1 - scale) / 2;
return (0,external_wp_element_namespaceObject.createElement)(external_wp_element_namespaceObject.Fragment, null, tabIndex >= 0 && before, (0,external_wp_element_namespaceObject.createElement)("iframe", {
...props,
style: {
border: 0,
...props.style,
height: expand ? contentHeight : props.style?.height,
marginTop: scale !== 1 ? -marginFromScaling + frameSize : props.style?.marginTop,
marginBottom: scale !== 1 ? -marginFromScaling + frameSize : props.style?.marginBottom,
transform: scale !== 1 ? `scale( ${scale} )` : props.style?.transform,
transition: 'all .3s'
},
ref: (0,external_wp_compose_namespaceObject.useMergeRefs)([ref, setRef]),
tabIndex: tabIndex
// Correct doctype is required to enable rendering in standards
// mode. Also preload the styles to avoid a flash of unstyled
// content.
,
src: src,
title: (0,external_wp_i18n_namespaceObject.__)('Editor canvas'),
onKeyDown: event => {
// If the event originates from inside the iframe, it means
// it bubbled through the portal, but only with React
// events. We need to to bubble native events as well,
// though by doing so we also trigger another React event,
// so we need to stop the propagation of this event to avoid
// duplication.
if (event.currentTarget.ownerDocument !== event.target.ownerDocument) {
event.stopPropagation();
bubbleEvent(event, window.KeyboardEvent, event.currentTarget);
}
}
}, iframeDocument && (0,external_wp_element_namespaceObject.createPortal)(
// We want to prevent React events from bubbling throught the iframe
// we bubble these manually.
/* eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions */
(0,external_wp_element_namespaceObject.createElement)("body", {
ref: bodyRef,
className: classnames_default()('block-editor-iframe__body', 'editor-styles-wrapper', ...bodyClasses)
}, contentResizeListener, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__experimentalStyleProvider, {
document: iframeDocument
}, children)), iframeDocument.documentElement)), tabIndex >= 0 && after);
}
function IframeIfReady(props, ref) {
const isInitialised = (0,external_wp_data_namespaceObject.useSelect)(select => select(store).getSettings().__internalIsInitialized, []);
// We shouldn't render the iframe until the editor settings are initialised.
// The initial settings are needed to get the styles for the srcDoc, which
// cannot be changed after the iframe is mounted. srcDoc is used to to set
// the initial iframe HTML, which is required to avoid a flash of unstyled
// content.
if (!isInitialised) {
return null;
}
return (0,external_wp_element_namespaceObject.createElement)(Iframe, {
...props,
forwardedRef: ref
});
}
/* harmony default export */ var iframe = ((0,external_wp_element_namespaceObject.forwardRef)(IframeIfReady));
;// CONCATENATED MODULE: ./node_modules/colord/index.mjs
var colord_r={grad:.9,turn:360,rad:360/(2*Math.PI)},t=function(r){return"string"==typeof r?r.length>0:"number"==typeof r},n=function(r,t,n){return void 0===t&&(t=0),void 0===n&&(n=Math.pow(10,t)),Math.round(n*r)/n+0},e=function(r,t,n){return void 0===t&&(t=0),void 0===n&&(n=1),r>n?n:r>t?r:t},colord_u=function(r){return(r=isFinite(r)?r%360:0)>0?r:r+360},a=function(r){return{r:e(r.r,0,255),g:e(r.g,0,255),b:e(r.b,0,255),a:e(r.a)}},o=function(r){return{r:n(r.r),g:n(r.g),b:n(r.b),a:n(r.a,3)}},colord_i=/^#([0-9a-f]{3,8})$/i,s=function(r){var t=r.toString(16);return t.length<2?"0"+t:t},colord_h=function(r){var t=r.r,n=r.g,e=r.b,u=r.a,a=Math.max(t,n,e),o=a-Math.min(t,n,e),i=o?a===t?(n-e)/o:a===n?2+(e-t)/o:4+(t-n)/o:0;return{h:60*(i<0?i+6:i),s:a?o/a*100:0,v:a/255*100,a:u}},colord_b=function(r){var t=r.h,n=r.s,e=r.v,u=r.a;t=t/360*6,n/=100,e/=100;var a=Math.floor(t),o=e*(1-n),i=e*(1-(t-a)*n),s=e*(1-(1-t+a)*n),h=a%6;return{r:255*[e,i,o,o,s,e][h],g:255*[s,e,e,i,o,o][h],b:255*[o,o,s,e,e,i][h],a:u}},colord_g=function(r){return{h:colord_u(r.h),s:e(r.s,0,100),l:e(r.l,0,100),a:e(r.a)}},colord_d=function(r){return{h:n(r.h),s:n(r.s),l:n(r.l),a:n(r.a,3)}},colord_f=function(r){return colord_b((n=(t=r).s,{h:t.h,s:(n*=((e=t.l)<50?e:100-e)/100)>0?2*n/(e+n)*100:0,v:e+n,a:t.a}));var t,n,e},colord_c=function(r){return{h:(t=colord_h(r)).h,s:(u=(200-(n=t.s))*(e=t.v)/100)>0&&u<200?n*e/100/(u<=100?u:200-u)*100:0,l:u/2,a:t.a};var t,n,e,u},colord_l=/^hsla?\(\s*([+-]?\d*\.?\d+)(deg|rad|grad|turn)?\s*,\s*([+-]?\d*\.?\d+)%\s*,\s*([+-]?\d*\.?\d+)%\s*(?:,\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i,colord_p=/^hsla?\(\s*([+-]?\d*\.?\d+)(deg|rad|grad|turn)?\s+([+-]?\d*\.?\d+)%\s+([+-]?\d*\.?\d+)%\s*(?:\/\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i,colord_v=/^rgba?\(\s*([+-]?\d*\.?\d+)(%)?\s*,\s*([+-]?\d*\.?\d+)(%)?\s*,\s*([+-]?\d*\.?\d+)(%)?\s*(?:,\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i,colord_m=/^rgba?\(\s*([+-]?\d*\.?\d+)(%)?\s+([+-]?\d*\.?\d+)(%)?\s+([+-]?\d*\.?\d+)(%)?\s*(?:\/\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i,colord_y={string:[[function(r){var t=colord_i.exec(r);return t?(r=t[1]).length<=4?{r:parseInt(r[0]+r[0],16),g:parseInt(r[1]+r[1],16),b:parseInt(r[2]+r[2],16),a:4===r.length?n(parseInt(r[3]+r[3],16)/255,2):1}:6===r.length||8===r.length?{r:parseInt(r.substr(0,2),16),g:parseInt(r.substr(2,2),16),b:parseInt(r.substr(4,2),16),a:8===r.length?n(parseInt(r.substr(6,2),16)/255,2):1}:null:null},"hex"],[function(r){var t=colord_v.exec(r)||colord_m.exec(r);return t?t[2]!==t[4]||t[4]!==t[6]?null:a({r:Number(t[1])/(t[2]?100/255:1),g:Number(t[3])/(t[4]?100/255:1),b:Number(t[5])/(t[6]?100/255:1),a:void 0===t[7]?1:Number(t[7])/(t[8]?100:1)}):null},"rgb"],[function(t){var n=colord_l.exec(t)||colord_p.exec(t);if(!n)return null;var e,u,a=colord_g({h:(e=n[1],u=n[2],void 0===u&&(u="deg"),Number(e)*(colord_r[u]||1)),s:Number(n[3]),l:Number(n[4]),a:void 0===n[5]?1:Number(n[5])/(n[6]?100:1)});return colord_f(a)},"hsl"]],object:[[function(r){var n=r.r,e=r.g,u=r.b,o=r.a,i=void 0===o?1:o;return t(n)&&t(e)&&t(u)?a({r:Number(n),g:Number(e),b:Number(u),a:Number(i)}):null},"rgb"],[function(r){var n=r.h,e=r.s,u=r.l,a=r.a,o=void 0===a?1:a;if(!t(n)||!t(e)||!t(u))return null;var i=colord_g({h:Number(n),s:Number(e),l:Number(u),a:Number(o)});return colord_f(i)},"hsl"],[function(r){var n=r.h,a=r.s,o=r.v,i=r.a,s=void 0===i?1:i;if(!t(n)||!t(a)||!t(o))return null;var h=function(r){return{h:colord_u(r.h),s:e(r.s,0,100),v:e(r.v,0,100),a:e(r.a)}}({h:Number(n),s:Number(a),v:Number(o),a:Number(s)});return colord_b(h)},"hsv"]]},colord_N=function(r,t){for(var n=0;n=.5},r.prototype.toHex=function(){return r=o(this.rgba),t=r.r,e=r.g,u=r.b,i=(a=r.a)<1?s(n(255*a)):"","#"+s(t)+s(e)+s(u)+i;var r,t,e,u,a,i},r.prototype.toRgb=function(){return o(this.rgba)},r.prototype.toRgbString=function(){return r=o(this.rgba),t=r.r,n=r.g,e=r.b,(u=r.a)<1?"rgba("+t+", "+n+", "+e+", "+u+")":"rgb("+t+", "+n+", "+e+")";var r,t,n,e,u},r.prototype.toHsl=function(){return colord_d(colord_c(this.rgba))},r.prototype.toHslString=function(){return r=colord_d(colord_c(this.rgba)),t=r.h,n=r.s,e=r.l,(u=r.a)<1?"hsla("+t+", "+n+"%, "+e+"%, "+u+")":"hsl("+t+", "+n+"%, "+e+"%)";var r,t,n,e,u},r.prototype.toHsv=function(){return r=colord_h(this.rgba),{h:n(r.h),s:n(r.s),v:n(r.v),a:n(r.a,3)};var r},r.prototype.invert=function(){return colord_w({r:255-(r=this.rgba).r,g:255-r.g,b:255-r.b,a:r.a});var r},r.prototype.saturate=function(r){return void 0===r&&(r=.1),colord_w(colord_M(this.rgba,r))},r.prototype.desaturate=function(r){return void 0===r&&(r=.1),colord_w(colord_M(this.rgba,-r))},r.prototype.grayscale=function(){return colord_w(colord_M(this.rgba,-1))},r.prototype.lighten=function(r){return void 0===r&&(r=.1),colord_w(colord_$(this.rgba,r))},r.prototype.darken=function(r){return void 0===r&&(r=.1),colord_w(colord_$(this.rgba,-r))},r.prototype.rotate=function(r){return void 0===r&&(r=15),this.hue(this.hue()+r)},r.prototype.alpha=function(r){return"number"==typeof r?colord_w({r:(t=this.rgba).r,g:t.g,b:t.b,a:r}):n(this.rgba.a,3);var t},r.prototype.hue=function(r){var t=colord_c(this.rgba);return"number"==typeof r?colord_w({h:r,s:t.s,l:t.l,a:t.a}):n(t.h)},r.prototype.isEqual=function(r){return this.toHex()===colord_w(r).toHex()},r}(),colord_w=function(r){return r instanceof colord_j?r:new colord_j(r)},colord_S=[],colord_k=function(r){r.forEach(function(r){colord_S.indexOf(r)<0&&(r(colord_j,colord_y),colord_S.push(r))})},colord_E=function(){return new colord_j({r:255*Math.random(),g:255*Math.random(),b:255*Math.random()})};
;// CONCATENATED MODULE: ./node_modules/colord/plugins/names.mjs
/* harmony default export */ function names(e,f){var a={white:"#ffffff",bisque:"#ffe4c4",blue:"#0000ff",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",antiquewhite:"#faebd7",aqua:"#00ffff",azure:"#f0ffff",whitesmoke:"#f5f5f5",papayawhip:"#ffefd5",plum:"#dda0dd",blanchedalmond:"#ffebcd",black:"#000000",gold:"#ffd700",goldenrod:"#daa520",gainsboro:"#dcdcdc",cornsilk:"#fff8dc",cornflowerblue:"#6495ed",burlywood:"#deb887",aquamarine:"#7fffd4",beige:"#f5f5dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkkhaki:"#bdb76b",darkgray:"#a9a9a9",darkgreen:"#006400",darkgrey:"#a9a9a9",peachpuff:"#ffdab9",darkmagenta:"#8b008b",darkred:"#8b0000",darkorchid:"#9932cc",darkorange:"#ff8c00",darkslateblue:"#483d8b",gray:"#808080",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",deeppink:"#ff1493",deepskyblue:"#00bfff",wheat:"#f5deb3",firebrick:"#b22222",floralwhite:"#fffaf0",ghostwhite:"#f8f8ff",darkviolet:"#9400d3",magenta:"#ff00ff",green:"#008000",dodgerblue:"#1e90ff",grey:"#808080",honeydew:"#f0fff0",hotpink:"#ff69b4",blueviolet:"#8a2be2",forestgreen:"#228b22",lawngreen:"#7cfc00",indianred:"#cd5c5c",indigo:"#4b0082",fuchsia:"#ff00ff",brown:"#a52a2a",maroon:"#800000",mediumblue:"#0000cd",lightcoral:"#f08080",darkturquoise:"#00ced1",lightcyan:"#e0ffff",ivory:"#fffff0",lightyellow:"#ffffe0",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",linen:"#faf0e6",mediumaquamarine:"#66cdaa",lemonchiffon:"#fffacd",lime:"#00ff00",khaki:"#f0e68c",mediumseagreen:"#3cb371",limegreen:"#32cd32",mediumspringgreen:"#00fa9a",lightskyblue:"#87cefa",lightblue:"#add8e6",midnightblue:"#191970",lightpink:"#ffb6c1",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",mintcream:"#f5fffa",lightslategray:"#778899",lightslategrey:"#778899",navajowhite:"#ffdead",navy:"#000080",mediumvioletred:"#c71585",powderblue:"#b0e0e6",palegoldenrod:"#eee8aa",oldlace:"#fdf5e6",paleturquoise:"#afeeee",mediumturquoise:"#48d1cc",mediumorchid:"#ba55d3",rebeccapurple:"#663399",lightsteelblue:"#b0c4de",mediumslateblue:"#7b68ee",thistle:"#d8bfd8",tan:"#d2b48c",orchid:"#da70d6",mediumpurple:"#9370db",purple:"#800080",pink:"#ffc0cb",skyblue:"#87ceeb",springgreen:"#00ff7f",palegreen:"#98fb98",red:"#ff0000",yellow:"#ffff00",slateblue:"#6a5acd",lavenderblush:"#fff0f5",peru:"#cd853f",palevioletred:"#db7093",violet:"#ee82ee",teal:"#008080",slategray:"#708090",slategrey:"#708090",aliceblue:"#f0f8ff",darkseagreen:"#8fbc8f",darkolivegreen:"#556b2f",greenyellow:"#adff2f",seagreen:"#2e8b57",seashell:"#fff5ee",tomato:"#ff6347",silver:"#c0c0c0",sienna:"#a0522d",lavender:"#e6e6fa",lightgreen:"#90ee90",orange:"#ffa500",orangered:"#ff4500",steelblue:"#4682b4",royalblue:"#4169e1",turquoise:"#40e0d0",yellowgreen:"#9acd32",salmon:"#fa8072",saddlebrown:"#8b4513",sandybrown:"#f4a460",rosybrown:"#bc8f8f",darksalmon:"#e9967a",lightgoldenrodyellow:"#fafad2",snow:"#fffafa",lightgrey:"#d3d3d3",lightgray:"#d3d3d3",dimgray:"#696969",dimgrey:"#696969",olivedrab:"#6b8e23",olive:"#808000"},r={};for(var d in a)r[a[d]]=d;var l={};e.prototype.toName=function(f){if(!(this.rgba.a||this.rgba.r||this.rgba.g||this.rgba.b))return"transparent";var d,i,n=r[this.toHex()];if(n)return n;if(null==f?void 0:f.closest){var o=this.toRgb(),t=1/0,b="black";if(!l.length)for(var c in a)l[c]=new e(a[c]).toRgb();for(var g in a){var u=(d=o,i=l[g],Math.pow(d.r-i.r,2)+Math.pow(d.g-i.g,2)+Math.pow(d.b-i.b,2));ud?(u+.05)/(d+.05):(d+.05)/(u+.05),void 0===(a=2)&&(a=0),void 0===i&&(i=Math.pow(10,a)),Math.floor(i*n)/i+0},o.prototype.isReadable=function(o,t){return void 0===o&&(o="#FFF"),void 0===t&&(t={}),this.contrast(o)>=(e=void 0===(i=(r=t).size)?"normal":i,"AAA"===(a=void 0===(n=r.level)?"AA":n)&&"normal"===e?7:"AA"===a&&"large"===e?3:4.5);var r,n,a,i,e}}
// EXTERNAL MODULE: ./node_modules/traverse/index.js
var traverse = __webpack_require__(3124);
var traverse_default = /*#__PURE__*/__webpack_require__.n(traverse);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/utils/transform-styles/ast/parse.js
/* eslint-disable @wordpress/no-unused-vars-before-return */
// Adapted from https://github.com/reworkcss/css
// because we needed to remove source map support.
// http://www.w3.org/TR/CSS21/grammar.htm
// https://github.com/visionmedia/css-parse/pull/49#issuecomment-30088027
const commentre = /\/\*[^*]*\*+([^/*][^*]*\*+)*\//g;
/* harmony default export */ function parse(css, options) {
options = options || {};
/**
* Positional.
*/
let lineno = 1;
let column = 1;
/**
* Update lineno and column based on `str`.
*/
function updatePosition(str) {
const lines = str.match(/\n/g);
if (lines) {
lineno += lines.length;
}
const i = str.lastIndexOf('\n');
// eslint-disable-next-line no-bitwise
column = ~i ? str.length - i : column + str.length;
}
/**
* Mark position and patch `node.position`.
*/
function position() {
const start = {
line: lineno,
column
};
return function (node) {
node.position = new Position(start);
whitespace();
return node;
};
}
/**
* Store position information for a node
*/
function Position(start) {
this.start = start;
this.end = {
line: lineno,
column
};
this.source = options.source;
}
/**
* Non-enumerable source string
*/
Position.prototype.content = css;
/**
* Error `msg`.
*/
const errorsList = [];
function error(msg) {
const err = new Error(options.source + ':' + lineno + ':' + column + ': ' + msg);
err.reason = msg;
err.filename = options.source;
err.line = lineno;
err.column = column;
err.source = css;
if (options.silent) {
errorsList.push(err);
} else {
throw err;
}
}
/**
* Parse stylesheet.
*/
function stylesheet() {
const rulesList = rules();
return {
type: 'stylesheet',
stylesheet: {
source: options.source,
rules: rulesList,
parsingErrors: errorsList
}
};
}
/**
* Opening brace.
*/
function open() {
return match(/^{\s*/);
}
/**
* Closing brace.
*/
function close() {
return match(/^}/);
}
/**
* Parse ruleset.
*/
function rules() {
let node;
const accumulator = [];
whitespace();
comments(accumulator);
while (css.length && css.charAt(0) !== '}' && (node = atrule() || rule())) {
if (node !== false) {
accumulator.push(node);
comments(accumulator);
}
}
return accumulator;
}
/**
* Match `re` and return captures.
*/
function match(re) {
const m = re.exec(css);
if (!m) {
return;
}
const str = m[0];
updatePosition(str);
css = css.slice(str.length);
return m;
}
/**
* Parse whitespace.
*/
function whitespace() {
match(/^\s*/);
}
/**
* Parse comments;
*/
function comments(accumulator) {
let c;
accumulator = accumulator || [];
// eslint-disable-next-line no-cond-assign
while (c = comment()) {
if (c !== false) {
accumulator.push(c);
}
}
return accumulator;
}
/**
* Parse comment.
*/
function comment() {
const pos = position();
if ('/' !== css.charAt(0) || '*' !== css.charAt(1)) {
return;
}
let i = 2;
while ('' !== css.charAt(i) && ('*' !== css.charAt(i) || '/' !== css.charAt(i + 1))) {
++i;
}
i += 2;
if ('' === css.charAt(i - 1)) {
return error('End of comment missing');
}
const str = css.slice(2, i - 2);
column += 2;
updatePosition(str);
css = css.slice(i);
column += 2;
return pos({
type: 'comment',
comment: str
});
}
/**
* Parse selector.
*/
function selector() {
const m = match(/^([^{]+)/);
if (!m) {
return;
}
// FIXME: Remove all comments from selectors http://ostermiller.org/findcomment.html
return trim(m[0]).replace(/\/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*\/+/g, '').replace(/"(?:\\"|[^"])*"|'(?:\\'|[^'])*'/g, function (matched) {
return matched.replace(/,/g, '\u200C');
}).split(/\s*(?![^(]*\)),\s*/).map(function (s) {
return s.replace(/\u200C/g, ',');
});
}
/**
* Parse declaration.
*/
function declaration() {
const pos = position();
// prop.
let prop = match(/^(\*?[-#\/\*\\\w]+(\[[0-9a-z_-]+\])?)\s*/);
if (!prop) {
return;
}
prop = trim(prop[0]);
// :
if (!match(/^:\s*/)) {
return error("property missing ':'");
}
// val.
const val = match(/^((?:'(?:\\'|.)*?'|"(?:\\"|.)*?"|\([^\)]*?\)|[^};])+)/);
const ret = pos({
type: 'declaration',
property: prop.replace(commentre, ''),
value: val ? trim(val[0]).replace(commentre, '') : ''
});
// ;
match(/^[;\s]*/);
return ret;
}
/**
* Parse declarations.
*/
function declarations() {
const decls = [];
if (!open()) {
return error("missing '{'");
}
comments(decls);
// declarations.
let decl;
// eslint-disable-next-line no-cond-assign
while (decl = declaration()) {
if (decl !== false) {
decls.push(decl);
comments(decls);
}
}
if (!close()) {
return error("missing '}'");
}
return decls;
}
/**
* Parse keyframe.
*/
function keyframe() {
let m;
const vals = [];
const pos = position();
// eslint-disable-next-line no-cond-assign
while (m = match(/^((\d+\.\d+|\.\d+|\d+)%?|[a-z]+)\s*/)) {
vals.push(m[1]);
match(/^,\s*/);
}
if (!vals.length) {
return;
}
return pos({
type: 'keyframe',
values: vals,
declarations: declarations()
});
}
/**
* Parse keyframes.
*/
function atkeyframes() {
const pos = position();
let m = match(/^@([-\w]+)?keyframes\s*/);
if (!m) {
return;
}
const vendor = m[1];
// identifier
m = match(/^([-\w]+)\s*/);
if (!m) {
return error('@keyframes missing name');
}
const name = m[1];
if (!open()) {
return error("@keyframes missing '{'");
}
let frame;
let frames = comments();
// eslint-disable-next-line no-cond-assign
while (frame = keyframe()) {
frames.push(frame);
frames = frames.concat(comments());
}
if (!close()) {
return error("@keyframes missing '}'");
}
return pos({
type: 'keyframes',
name,
vendor,
keyframes: frames
});
}
/**
* Parse supports.
*/
function atsupports() {
const pos = position();
const m = match(/^@supports *([^{]+)/);
if (!m) {
return;
}
const supports = trim(m[1]);
if (!open()) {
return error("@supports missing '{'");
}
const style = comments().concat(rules());
if (!close()) {
return error("@supports missing '}'");
}
return pos({
type: 'supports',
supports,
rules: style
});
}
/**
* Parse host.
*/
function athost() {
const pos = position();
const m = match(/^@host\s*/);
if (!m) {
return;
}
if (!open()) {
return error("@host missing '{'");
}
const style = comments().concat(rules());
if (!close()) {
return error("@host missing '}'");
}
return pos({
type: 'host',
rules: style
});
}
/**
* Parse media.
*/
function atmedia() {
const pos = position();
const m = match(/^@media *([^{]+)/);
if (!m) {
return;
}
const media = trim(m[1]);
if (!open()) {
return error("@media missing '{'");
}
const style = comments().concat(rules());
if (!close()) {
return error("@media missing '}'");
}
return pos({
type: 'media',
media,
rules: style
});
}
/**
* Parse container.
*/
function atcontainer() {
const pos = position();
const m = match(/^@container *([^{]+)/);
if (!m) {
return;
}
const container = trim(m[1]);
if (!open()) {
return error("@container missing '{'");
}
const style = comments().concat(rules());
if (!close()) {
return error("@container missing '}'");
}
return pos({
type: 'container',
container,
rules: style
});
}
/**
* Parse custom-media.
*/
function atcustommedia() {
const pos = position();
const m = match(/^@custom-media\s+(--[^\s]+)\s*([^{;]+);/);
if (!m) {
return;
}
return pos({
type: 'custom-media',
name: trim(m[1]),
media: trim(m[2])
});
}
/**
* Parse paged media.
*/
function atpage() {
const pos = position();
const m = match(/^@page */);
if (!m) {
return;
}
const sel = selector() || [];
if (!open()) {
return error("@page missing '{'");
}
let decls = comments();
// declarations.
let decl;
// eslint-disable-next-line no-cond-assign
while (decl = declaration()) {
decls.push(decl);
decls = decls.concat(comments());
}
if (!close()) {
return error("@page missing '}'");
}
return pos({
type: 'page',
selectors: sel,
declarations: decls
});
}
/**
* Parse document.
*/
function atdocument() {
const pos = position();
const m = match(/^@([-\w]+)?document *([^{]+)/);
if (!m) {
return;
}
const vendor = trim(m[1]);
const doc = trim(m[2]);
if (!open()) {
return error("@document missing '{'");
}
const style = comments().concat(rules());
if (!close()) {
return error("@document missing '}'");
}
return pos({
type: 'document',
document: doc,
vendor,
rules: style
});
}
/**
* Parse font-face.
*/
function atfontface() {
const pos = position();
const m = match(/^@font-face\s*/);
if (!m) {
return;
}
if (!open()) {
return error("@font-face missing '{'");
}
let decls = comments();
// declarations.
let decl;
// eslint-disable-next-line no-cond-assign
while (decl = declaration()) {
decls.push(decl);
decls = decls.concat(comments());
}
if (!close()) {
return error("@font-face missing '}'");
}
return pos({
type: 'font-face',
declarations: decls
});
}
/**
* Parse import
*/
const atimport = _compileAtrule('import');
/**
* Parse charset
*/
const atcharset = _compileAtrule('charset');
/**
* Parse namespace
*/
const atnamespace = _compileAtrule('namespace');
/**
* Parse non-block at-rules
*/
function _compileAtrule(name) {
const re = new RegExp('^@' + name + '\\s*([^;]+);');
return function () {
const pos = position();
const m = match(re);
if (!m) {
return;
}
const ret = {
type: name
};
ret[name] = m[1].trim();
return pos(ret);
};
}
/**
* Parse at rule.
*/
function atrule() {
if (css[0] !== '@') {
return;
}
return atkeyframes() || atmedia() || atcontainer() || atcustommedia() || atsupports() || atimport() || atcharset() || atnamespace() || atdocument() || atpage() || athost() || atfontface();
}
/**
* Parse rule.
*/
function rule() {
const pos = position();
const sel = selector();
if (!sel) {
return error('selector missing');
}
comments();
return pos({
type: 'rule',
selectors: sel,
declarations: declarations()
});
}
return addParent(stylesheet());
}
/**
* Trim `str`.
*/
function trim(str) {
return str ? str.replace(/^\s+|\s+$/g, '') : '';
}
/**
* Adds non-enumerable parent node reference to each node.
*/
function addParent(obj, parent) {
const isNode = obj && typeof obj.type === 'string';
const childParent = isNode ? obj : parent;
for (const k in obj) {
const value = obj[k];
if (Array.isArray(value)) {
value.forEach(function (v) {
addParent(v, childParent);
});
} else if (value && typeof value === 'object') {
addParent(value, childParent);
}
}
if (isNode) {
Object.defineProperty(obj, 'parent', {
configurable: true,
writable: true,
enumerable: false,
value: parent || null
});
}
return obj;
}
/* eslint-enable @wordpress/no-unused-vars-before-return */
// EXTERNAL MODULE: ./node_modules/inherits/inherits_browser.js
var inherits_browser = __webpack_require__(8575);
var inherits_browser_default = /*#__PURE__*/__webpack_require__.n(inherits_browser);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/utils/transform-styles/ast/stringify/compiler.js
// Adapted from https://github.com/reworkcss/css
// because we needed to remove source map support.
/**
* Expose `Compiler`.
*/
/* harmony default export */ var compiler = (Compiler);
/**
* Initialize a compiler.
*/
function Compiler(opts) {
this.options = opts || {};
}
/**
* Emit `str`
*/
Compiler.prototype.emit = function (str) {
return str;
};
/**
* Visit `node`.
*/
Compiler.prototype.visit = function (node) {
return this[node.type](node);
};
/**
* Map visit over array of `nodes`, optionally using a `delim`
*/
Compiler.prototype.mapVisit = function (nodes, delim) {
let buf = '';
delim = delim || '';
for (let i = 0, length = nodes.length; i < length; i++) {
buf += this.visit(nodes[i]);
if (delim && i < length - 1) {
buf += this.emit(delim);
}
}
return buf;
};
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/utils/transform-styles/ast/stringify/compress.js
// Adapted from https://github.com/reworkcss/css
// because we needed to remove source map support.
/**
* External dependencies
*/
/**
* Internal dependencies
*/
/**
* Expose compiler.
*/
/* harmony default export */ var compress = (compress_Compiler);
/**
* Initialize a new `Compiler`.
*/
function compress_Compiler(options) {
compiler.call(this, options);
}
/**
* Inherit from `Base.prototype`.
*/
inherits_browser_default()(compress_Compiler, compiler);
/**
* Compile `node`.
*/
compress_Compiler.prototype.compile = function (node) {
return node.stylesheet.rules.map(this.visit, this).join('');
};
/**
* Visit comment node.
*/
compress_Compiler.prototype.comment = function (node) {
return this.emit('', node.position);
};
/**
* Visit import node.
*/
compress_Compiler.prototype.import = function (node) {
return this.emit('@import ' + node.import + ';', node.position);
};
/**
* Visit media node.
*/
compress_Compiler.prototype.media = function (node) {
return this.emit('@media ' + node.media, node.position) + this.emit('{') + this.mapVisit(node.rules) + this.emit('}');
};
/**
* Visit container node.
*/
compress_Compiler.prototype.container = function (node) {
return this.emit('@container ' + node.container, node.position) + this.emit('{') + this.mapVisit(node.rules) + this.emit('}');
};
/**
* Visit document node.
*/
compress_Compiler.prototype.document = function (node) {
const doc = '@' + (node.vendor || '') + 'document ' + node.document;
return this.emit(doc, node.position) + this.emit('{') + this.mapVisit(node.rules) + this.emit('}');
};
/**
* Visit charset node.
*/
compress_Compiler.prototype.charset = function (node) {
return this.emit('@charset ' + node.charset + ';', node.position);
};
/**
* Visit namespace node.
*/
compress_Compiler.prototype.namespace = function (node) {
return this.emit('@namespace ' + node.namespace + ';', node.position);
};
/**
* Visit supports node.
*/
compress_Compiler.prototype.supports = function (node) {
return this.emit('@supports ' + node.supports, node.position) + this.emit('{') + this.mapVisit(node.rules) + this.emit('}');
};
/**
* Visit keyframes node.
*/
compress_Compiler.prototype.keyframes = function (node) {
return this.emit('@' + (node.vendor || '') + 'keyframes ' + node.name, node.position) + this.emit('{') + this.mapVisit(node.keyframes) + this.emit('}');
};
/**
* Visit keyframe node.
*/
compress_Compiler.prototype.keyframe = function (node) {
const decls = node.declarations;
return this.emit(node.values.join(','), node.position) + this.emit('{') + this.mapVisit(decls) + this.emit('}');
};
/**
* Visit page node.
*/
compress_Compiler.prototype.page = function (node) {
const sel = node.selectors.length ? node.selectors.join(', ') : '';
return this.emit('@page ' + sel, node.position) + this.emit('{') + this.mapVisit(node.declarations) + this.emit('}');
};
/**
* Visit font-face node.
*/
compress_Compiler.prototype['font-face'] = function (node) {
return this.emit('@font-face', node.position) + this.emit('{') + this.mapVisit(node.declarations) + this.emit('}');
};
/**
* Visit host node.
*/
compress_Compiler.prototype.host = function (node) {
return this.emit('@host', node.position) + this.emit('{') + this.mapVisit(node.rules) + this.emit('}');
};
/**
* Visit custom-media node.
*/
compress_Compiler.prototype['custom-media'] = function (node) {
return this.emit('@custom-media ' + node.name + ' ' + node.media + ';', node.position);
};
/**
* Visit rule node.
*/
compress_Compiler.prototype.rule = function (node) {
const decls = node.declarations;
if (!decls.length) {
return '';
}
return this.emit(node.selectors.join(','), node.position) + this.emit('{') + this.mapVisit(decls) + this.emit('}');
};
/**
* Visit declaration node.
*/
compress_Compiler.prototype.declaration = function (node) {
return this.emit(node.property + ':' + node.value, node.position) + this.emit(';');
};
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/utils/transform-styles/ast/stringify/identity.js
/* eslint-disable @wordpress/no-unused-vars-before-return */
// Adapted from https://github.com/reworkcss/css
// because we needed to remove source map support.
/**
* External dependencies
*/
/**
* Internal dependencies
*/
/**
* Expose compiler.
*/
/* harmony default export */ var stringify_identity = (identity_Compiler);
/**
* Initialize a new `Compiler`.
*/
function identity_Compiler(options) {
options = options || {};
compiler.call(this, options);
this.indentation = options.indent;
}
/**
* Inherit from `Base.prototype`.
*/
inherits_browser_default()(identity_Compiler, compiler);
/**
* Compile `node`.
*/
identity_Compiler.prototype.compile = function (node) {
return this.stylesheet(node);
};
/**
* Visit stylesheet node.
*/
identity_Compiler.prototype.stylesheet = function (node) {
return this.mapVisit(node.stylesheet.rules, '\n\n');
};
/**
* Visit comment node.
*/
identity_Compiler.prototype.comment = function (node) {
return this.emit(this.indent() + '/*' + node.comment + '*/', node.position);
};
/**
* Visit import node.
*/
identity_Compiler.prototype.import = function (node) {
return this.emit('@import ' + node.import + ';', node.position);
};
/**
* Visit media node.
*/
identity_Compiler.prototype.media = function (node) {
return this.emit('@media ' + node.media, node.position) + this.emit(' {\n' + this.indent(1)) + this.mapVisit(node.rules, '\n\n') + this.emit(this.indent(-1) + '\n}');
};
/**
* Visit container node.
*/
identity_Compiler.prototype.container = function (node) {
return this.emit('@container ' + node.container, node.position) + this.emit(' {\n' + this.indent(1)) + this.mapVisit(node.rules, '\n\n') + this.emit(this.indent(-1) + '\n}');
};
/**
* Visit document node.
*/
identity_Compiler.prototype.document = function (node) {
const doc = '@' + (node.vendor || '') + 'document ' + node.document;
return this.emit(doc, node.position) + this.emit(' ' + ' {\n' + this.indent(1)) + this.mapVisit(node.rules, '\n\n') + this.emit(this.indent(-1) + '\n}');
};
/**
* Visit charset node.
*/
identity_Compiler.prototype.charset = function (node) {
return this.emit('@charset ' + node.charset + ';', node.position);
};
/**
* Visit namespace node.
*/
identity_Compiler.prototype.namespace = function (node) {
return this.emit('@namespace ' + node.namespace + ';', node.position);
};
/**
* Visit supports node.
*/
identity_Compiler.prototype.supports = function (node) {
return this.emit('@supports ' + node.supports, node.position) + this.emit(' {\n' + this.indent(1)) + this.mapVisit(node.rules, '\n\n') + this.emit(this.indent(-1) + '\n}');
};
/**
* Visit keyframes node.
*/
identity_Compiler.prototype.keyframes = function (node) {
return this.emit('@' + (node.vendor || '') + 'keyframes ' + node.name, node.position) + this.emit(' {\n' + this.indent(1)) + this.mapVisit(node.keyframes, '\n') + this.emit(this.indent(-1) + '}');
};
/**
* Visit keyframe node.
*/
identity_Compiler.prototype.keyframe = function (node) {
const decls = node.declarations;
return this.emit(this.indent()) + this.emit(node.values.join(', '), node.position) + this.emit(' {\n' + this.indent(1)) + this.mapVisit(decls, '\n') + this.emit(this.indent(-1) + '\n' + this.indent() + '}\n');
};
/**
* Visit page node.
*/
identity_Compiler.prototype.page = function (node) {
const sel = node.selectors.length ? node.selectors.join(', ') + ' ' : '';
return this.emit('@page ' + sel, node.position) + this.emit('{\n') + this.emit(this.indent(1)) + this.mapVisit(node.declarations, '\n') + this.emit(this.indent(-1)) + this.emit('\n}');
};
/**
* Visit font-face node.
*/
identity_Compiler.prototype['font-face'] = function (node) {
return this.emit('@font-face ', node.position) + this.emit('{\n') + this.emit(this.indent(1)) + this.mapVisit(node.declarations, '\n') + this.emit(this.indent(-1)) + this.emit('\n}');
};
/**
* Visit host node.
*/
identity_Compiler.prototype.host = function (node) {
return this.emit('@host', node.position) + this.emit(' {\n' + this.indent(1)) + this.mapVisit(node.rules, '\n\n') + this.emit(this.indent(-1) + '\n}');
};
/**
* Visit custom-media node.
*/
identity_Compiler.prototype['custom-media'] = function (node) {
return this.emit('@custom-media ' + node.name + ' ' + node.media + ';', node.position);
};
/**
* Visit rule node.
*/
identity_Compiler.prototype.rule = function (node) {
const indent = this.indent();
const decls = node.declarations;
if (!decls.length) {
return '';
}
return this.emit(node.selectors.map(function (s) {
return indent + s;
}).join(',\n'), node.position) + this.emit(' {\n') + this.emit(this.indent(1)) + this.mapVisit(decls, '\n') + this.emit(this.indent(-1)) + this.emit('\n' + this.indent() + '}');
};
/**
* Visit declaration node.
*/
identity_Compiler.prototype.declaration = function (node) {
return this.emit(this.indent()) + this.emit(node.property + ': ' + node.value, node.position) + this.emit(';');
};
/**
* Increase, decrease or return current indentation.
*/
identity_Compiler.prototype.indent = function (level) {
this.level = this.level || 1;
if (null !== level) {
this.level += level;
return '';
}
return Array(this.level).join(this.indentation || ' ');
};
/* eslint-enable @wordpress/no-unused-vars-before-return */
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/utils/transform-styles/ast/stringify/index.js
// Adapted from https://github.com/reworkcss/css
// because we needed to remove source map support.
/**
* Internal dependencies
*/
/**
* Stringfy the given AST `node`.
*
* Options:
*
* - `compress` space-optimized output
* - `sourcemap` return an object with `.code` and `.map`
*
* @param {Object} node
* @param {Object} [options]
* @return {string}
*/
/* harmony default export */ function stringify(node, options) {
options = options || {};
const compiler = options.compress ? new compress(options) : new stringify_identity(options);
const code = compiler.compile(node);
return code;
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/utils/transform-styles/traverse.js
/**
* External dependencies
*/
/**
* Internal dependencies
*/
function traverseCSS(css, callback) {
try {
const parsed = parse(css);
const updated = traverse_default().map(parsed, function (node) {
if (!node) {
return node;
}
const updatedNode = callback(node);
return this.update(updatedNode);
});
return stringify(updated);
} catch (err) {
// eslint-disable-next-line no-console
console.warn('Error while traversing the CSS: ' + err);
return null;
}
}
/* harmony default export */ var transform_styles_traverse = (traverseCSS);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/utils/transform-styles/transforms/url-rewrite.js
/**
* Return `true` if the given path is http/https.
*
* @param {string} filePath path
*
* @return {boolean} is remote path.
*/
function isRemotePath(filePath) {
return /^(?:https?:)?\/\//.test(filePath);
}
/**
* Return `true` if the given filePath is an absolute url.
*
* @param {string} filePath path
*
* @return {boolean} is absolute path.
*/
function isAbsolutePath(filePath) {
return /^\/(?!\/)/.test(filePath);
}
/**
* Whether or not the url should be inluded.
*
* @param {Object} meta url meta info
*
* @return {boolean} is valid.
*/
function isValidURL(meta) {
// Ignore hashes or data uris.
if (meta.value.indexOf('data:') === 0 || meta.value.indexOf('#') === 0) {
return false;
}
if (isAbsolutePath(meta.value)) {
return false;
}
// Do not handle the http/https urls if `includeRemote` is false.
if (isRemotePath(meta.value)) {
return false;
}
return true;
}
/**
* Get the absolute path of the url, relative to the basePath
*
* @param {string} str the url
* @param {string} baseURL base URL
*
* @return {string} the full path to the file
*/
function getResourcePath(str, baseURL) {
return new URL(str, baseURL).toString();
}
/**
* Process the single `url()` pattern
*
* @param {string} baseURL the base URL for relative URLs.
*
* @return {Promise} the Promise.
*/
function processURL(baseURL) {
return meta => ({
...meta,
newUrl: 'url(' + meta.before + meta.quote + getResourcePath(meta.value, baseURL) + meta.quote + meta.after + ')'
});
}
/**
* Get all `url()`s, and return the meta info
*
* @param {string} value decl.value.
*
* @return {Array} the urls.
*/
function getURLs(value) {
const reg = /url\((\s*)(['"]?)(.+?)\2(\s*)\)/g;
let match;
const URLs = [];
while ((match = reg.exec(value)) !== null) {
const meta = {
source: match[0],
before: match[1],
quote: match[2],
value: match[3],
after: match[4]
};
if (isValidURL(meta)) {
URLs.push(meta);
}
}
return URLs;
}
/**
* Replace the raw value's `url()` segment to the new value
*
* @param {string} raw the raw value.
* @param {Array} URLs the URLs to replace.
*
* @return {string} the new value.
*/
function replaceURLs(raw, URLs) {
URLs.forEach(item => {
raw = raw.replace(item.source, item.newUrl);
});
return raw;
}
const rewrite = rootURL => node => {
if (node.type === 'declaration') {
const updatedURLs = getURLs(node.value).map(processURL(rootURL));
return {
...node,
value: replaceURLs(node.value, updatedURLs)
};
}
return node;
};
/* harmony default export */ var url_rewrite = (rewrite);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/utils/transform-styles/transforms/wrap.js
/**
* @constant string IS_ROOT_TAG Regex to check if the selector is a root tag selector.
*/
const IS_ROOT_TAG = /^(body|html|:root).*$/;
/**
* Creates a callback to modify selectors so they only apply within a certain
* namespace.
*
* @param {string} namespace Namespace to prefix selectors with.
* @param {string[]} ignore Selectors to not prefix.
*
* @return {(node: Object) => Object} Callback to wrap selectors.
*/
const wrap = (namespace, ignore = []) => node => {
/**
* Updates selector if necessary.
*
* @param {string} selector Selector to modify.
*
* @return {string} Updated selector.
*/
const updateSelector = selector => {
if (ignore.includes(selector.trim())) {
return selector;
}
// Skip the update when a selector already has a namespace + space (" ").
if (selector.trim().startsWith(`${namespace} `)) {
return selector;
}
// Anything other than a root tag is always prefixed.
{
if (!selector.match(IS_ROOT_TAG)) {
return namespace + ' ' + selector;
}
}
// HTML and Body elements cannot be contained within our container so lets extract their styles.
return selector.replace(/^(body|html|:root)/, namespace);
};
if (node.type === 'rule') {
return {
...node,
selectors: node.selectors.map(updateSelector)
};
}
return node;
};
/* harmony default export */ var transforms_wrap = (wrap);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/utils/transform-styles/index.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
/**
* Applies a series of CSS rule transforms to wrap selectors inside a given class and/or rewrite URLs depending on the parameters passed.
*
* @param {Object|Array} styles CSS rules.
* @param {string} wrapperClassName Wrapper Class Name.
* @return {Array} converted rules.
*/
const transform_styles_transformStyles = (styles, wrapperClassName = '') => {
return Object.values(styles !== null && styles !== void 0 ? styles : []).map(({
css,
baseURL
}) => {
const transforms = [];
if (wrapperClassName) {
transforms.push(transforms_wrap(wrapperClassName));
}
if (baseURL) {
transforms.push(url_rewrite(baseURL));
}
if (transforms.length) {
return transform_styles_traverse(css, (0,external_wp_compose_namespaceObject.compose)(transforms));
}
return css;
});
};
/* harmony default export */ var transform_styles = (transform_styles_transformStyles);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/editor-styles/index.js
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
colord_k([names, a11y]);
function useDarkThemeBodyClassName(styles, scope) {
return (0,external_wp_element_namespaceObject.useCallback)(node => {
if (!node) {
return;
}
const {
ownerDocument
} = node;
const {
defaultView,
body
} = ownerDocument;
const canvas = scope ? ownerDocument.querySelector(scope) : body;
let backgroundColor;
if (!canvas) {
// The real .editor-styles-wrapper element might not exist in the
// DOM, so calculate the background color by creating a fake
// wrapper.
const tempCanvas = ownerDocument.createElement('div');
tempCanvas.classList.add('editor-styles-wrapper');
body.appendChild(tempCanvas);
backgroundColor = defaultView?.getComputedStyle(tempCanvas, null).getPropertyValue('background-color');
body.removeChild(tempCanvas);
} else {
backgroundColor = defaultView?.getComputedStyle(canvas, null).getPropertyValue('background-color');
}
const colordBackgroundColor = colord_w(backgroundColor);
// If background is transparent, it should be treated as light color.
if (colordBackgroundColor.luminance() > 0.5 || colordBackgroundColor.alpha() === 0) {
body.classList.remove('is-dark-theme');
} else {
body.classList.add('is-dark-theme');
}
}, [styles, scope]);
}
function EditorStyles({
styles,
scope
}) {
const overrides = (0,external_wp_data_namespaceObject.useSelect)(select => unlock(select(store)).getStyleOverrides(), []);
const [transformedStyles, transformedSvgs] = (0,external_wp_element_namespaceObject.useMemo)(() => {
const _styles = Object.values(styles !== null && styles !== void 0 ? styles : []);
for (const [id, override] of overrides) {
const index = _styles.findIndex(({
id: _id
}) => id === _id);
const overrideWithId = {
...override,
id
};
if (index === -1) {
_styles.push(overrideWithId);
} else {
_styles[index] = overrideWithId;
}
}
return [transform_styles(_styles.filter(style => style?.css), scope), _styles.filter(style => style.__unstableType === 'svgs').map(style => style.assets).join('')];
}, [styles, overrides, scope]);
return (0,external_wp_element_namespaceObject.createElement)(external_wp_element_namespaceObject.Fragment, null, (0,external_wp_element_namespaceObject.createElement)("style", {
ref: useDarkThemeBodyClassName(transformedStyles, scope)
}), transformedStyles.map((css, index) => (0,external_wp_element_namespaceObject.createElement)("style", {
key: index
}, css)), (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.SVG, {
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 0 0",
width: "0",
height: "0",
role: "none",
style: {
visibility: 'hidden',
position: 'absolute',
left: '-9999px',
overflow: 'hidden'
},
dangerouslySetInnerHTML: {
__html: transformedSvgs
}
}));
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-preview/auto.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
// This is used to avoid rendering the block list if the sizes change.
let MemoizedBlockList;
const MAX_HEIGHT = 2000;
function ScaledBlockPreview({
viewportWidth,
containerWidth,
minHeight,
additionalStyles = []
}) {
if (!viewportWidth) {
viewportWidth = containerWidth;
}
const [contentResizeListener, {
height: contentHeight
}] = (0,external_wp_compose_namespaceObject.useResizeObserver)();
const {
styles
} = (0,external_wp_data_namespaceObject.useSelect)(select => {
const settings = select(store).getSettings();
return {
styles: settings.styles
};
}, []);
// Avoid scrollbars for pattern previews.
const editorStyles = (0,external_wp_element_namespaceObject.useMemo)(() => {
if (styles) {
return [...styles, {
css: 'body{height:auto;overflow:hidden;border:none;padding:0;}',
__unstableType: 'presets'
}, ...additionalStyles];
}
return styles;
}, [styles, additionalStyles]);
// Initialize on render instead of module top level, to avoid circular dependency issues.
MemoizedBlockList = MemoizedBlockList || (0,external_wp_compose_namespaceObject.pure)(BlockList);
const scale = containerWidth / viewportWidth;
const aspectRatio = contentHeight ? containerWidth / (contentHeight * scale) : 0;
return (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.Disabled, {
className: "block-editor-block-preview__content",
style: {
transform: `scale(${scale})`,
// Using width + aspect-ratio instead of height here triggers browsers' native
// handling of scrollbar's visibility. It prevents the flickering issue seen
// in https://github.com/WordPress/gutenberg/issues/52027.
// See https://github.com/WordPress/gutenberg/pull/52921 for more info.
aspectRatio,
maxHeight: contentHeight > MAX_HEIGHT ? MAX_HEIGHT * scale : undefined,
minHeight
}
}, (0,external_wp_element_namespaceObject.createElement)(iframe, {
contentRef: (0,external_wp_compose_namespaceObject.useRefEffect)(bodyElement => {
const {
ownerDocument: {
documentElement
}
} = bodyElement;
documentElement.classList.add('block-editor-block-preview__content-iframe');
documentElement.style.position = 'absolute';
documentElement.style.width = '100%';
// Necessary for contentResizeListener to work.
bodyElement.style.boxSizing = 'border-box';
bodyElement.style.position = 'absolute';
bodyElement.style.width = '100%';
}, []),
"aria-hidden": true,
tabIndex: -1,
style: {
position: 'absolute',
width: viewportWidth,
height: contentHeight,
pointerEvents: 'none',
// This is a catch-all max-height for patterns.
// See: https://github.com/WordPress/gutenberg/pull/38175.
maxHeight: MAX_HEIGHT,
minHeight: scale !== 0 && scale < 1 && minHeight ? minHeight / scale : minHeight
}
}, (0,external_wp_element_namespaceObject.createElement)(EditorStyles, {
styles: editorStyles
}), contentResizeListener, (0,external_wp_element_namespaceObject.createElement)(MemoizedBlockList, {
renderAppender: false
})));
}
function AutoBlockPreview(props) {
const [containerResizeListener, {
width: containerWidth
}] = (0,external_wp_compose_namespaceObject.useResizeObserver)();
return (0,external_wp_element_namespaceObject.createElement)(external_wp_element_namespaceObject.Fragment, null, (0,external_wp_element_namespaceObject.createElement)("div", {
style: {
position: 'relative',
width: '100%',
height: 0
}
}, containerResizeListener), (0,external_wp_element_namespaceObject.createElement)("div", {
className: "block-editor-block-preview__container"
}, !!containerWidth && (0,external_wp_element_namespaceObject.createElement)(ScaledBlockPreview, {
...props,
containerWidth: containerWidth
})));
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-preview/index.js
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
function BlockPreview({
blocks,
viewportWidth = 1200,
minHeight,
additionalStyles = [],
// Deprecated props:
__experimentalMinHeight,
__experimentalPadding
}) {
if (__experimentalMinHeight) {
minHeight = __experimentalMinHeight;
external_wp_deprecated_default()('The __experimentalMinHeight prop', {
since: '6.2',
version: '6.4',
alternative: 'minHeight'
});
}
if (__experimentalPadding) {
additionalStyles = [...additionalStyles, {
css: `body { padding: ${__experimentalPadding}px; }`
}];
external_wp_deprecated_default()('The __experimentalPadding prop of BlockPreview', {
since: '6.2',
version: '6.4',
alternative: 'additionalStyles'
});
}
const originalSettings = (0,external_wp_data_namespaceObject.useSelect)(select => select(store).getSettings(), []);
const settings = (0,external_wp_element_namespaceObject.useMemo)(() => ({
...originalSettings,
__unstableIsPreviewMode: true
}), [originalSettings]);
const renderedBlocks = (0,external_wp_element_namespaceObject.useMemo)(() => Array.isArray(blocks) ? blocks : [blocks], [blocks]);
if (!blocks || blocks.length === 0) {
return null;
}
return (0,external_wp_element_namespaceObject.createElement)(ExperimentalBlockEditorProvider, {
value: renderedBlocks,
settings: settings
}, (0,external_wp_element_namespaceObject.createElement)(AutoBlockPreview, {
viewportWidth: viewportWidth,
minHeight: minHeight,
additionalStyles: additionalStyles
}));
}
/**
* BlockPreview renders a preview of a block or array of blocks.
*
* @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/block-preview/README.md
*
* @param {Object} preview options for how the preview should be shown
* @param {Array|Object} preview.blocks A block instance (object) or an array of blocks to be previewed.
* @param {number} preview.viewportWidth Width of the preview container in pixels. Controls at what size the blocks will be rendered inside the preview. Default: 700.
*
* @return {WPComponent} The component to be rendered.
*/
/* harmony default export */ var block_preview = ((0,external_wp_element_namespaceObject.memo)(BlockPreview));
/**
* This hook is used to lightly mark an element as a block preview wrapper
* element. Call this hook and pass the returned props to the element to mark as
* a block preview wrapper, automatically rendering inner blocks as children. If
* you define a ref for the element, it is important to pass the ref to this
* hook, which the hook in turn will pass to the component through the props it
* returns. Optionally, you can also pass any other props through this hook, and
* they will be merged and returned.
*
* @param {Object} options Preview options.
* @param {WPBlock[]} options.blocks Block objects.
* @param {Object} options.props Optional. Props to pass to the element. Must contain
* the ref if one is defined.
* @param {Object} options.layout Layout settings to be used in the preview.
*/
function useBlockPreview({
blocks,
props = {},
layout
}) {
const originalSettings = (0,external_wp_data_namespaceObject.useSelect)(select => select(store).getSettings(), []);
const settings = (0,external_wp_element_namespaceObject.useMemo)(() => ({
...originalSettings,
styles: undefined,
// Clear styles included by the parent settings, as they are already output by the parent's EditorStyles.
__unstableIsPreviewMode: true
}), [originalSettings]);
const disabledRef = (0,external_wp_compose_namespaceObject.useDisabled)();
const ref = (0,external_wp_compose_namespaceObject.useMergeRefs)([props.ref, disabledRef]);
const renderedBlocks = (0,external_wp_element_namespaceObject.useMemo)(() => Array.isArray(blocks) ? blocks : [blocks], [blocks]);
const children = (0,external_wp_element_namespaceObject.createElement)(ExperimentalBlockEditorProvider, {
value: renderedBlocks,
settings: settings
}, (0,external_wp_element_namespaceObject.createElement)(EditorStyles, null), (0,external_wp_element_namespaceObject.createElement)(BlockListItems, {
renderAppender: false,
layout: layout
}));
return {
...props,
ref,
className: classnames_default()(props.className, 'block-editor-block-preview__live-content', 'components-disabled'),
children: blocks?.length ? children : null
};
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/preview-panel.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
function InserterPreviewPanel({
item
}) {
var _example$viewportWidt;
const {
name,
title,
icon,
description,
initialAttributes,
example
} = item;
const isReusable = (0,external_wp_blocks_namespaceObject.isReusableBlock)(item);
const blocks = (0,external_wp_element_namespaceObject.useMemo)(() => {
if (!example) {
return (0,external_wp_blocks_namespaceObject.createBlock)(name, initialAttributes);
}
return (0,external_wp_blocks_namespaceObject.getBlockFromExample)(name, {
attributes: {
...example.attributes,
...initialAttributes
},
innerBlocks: example.innerBlocks
});
}, [name, example, initialAttributes]);
return (0,external_wp_element_namespaceObject.createElement)("div", {
className: "block-editor-inserter__preview-container"
}, (0,external_wp_element_namespaceObject.createElement)("div", {
className: "block-editor-inserter__preview"
}, isReusable || example ? (0,external_wp_element_namespaceObject.createElement)("div", {
className: "block-editor-inserter__preview-content"
}, (0,external_wp_element_namespaceObject.createElement)(block_preview, {
blocks: blocks,
viewportWidth: (_example$viewportWidt = example?.viewportWidth) !== null && _example$viewportWidt !== void 0 ? _example$viewportWidt : 500,
additionalStyles: [{
css: 'body { padding: 16px; }'
}]
})) : (0,external_wp_element_namespaceObject.createElement)("div", {
className: "block-editor-inserter__preview-content-missing"
}, (0,external_wp_i18n_namespaceObject.__)('No Preview Available.'))), !isReusable && (0,external_wp_element_namespaceObject.createElement)(block_card, {
title: title,
icon: icon,
description: description
}));
}
/* harmony default export */ var preview_panel = (InserterPreviewPanel);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter-listbox/context.js
/**
* WordPress dependencies
*/
const InserterListboxContext = (0,external_wp_element_namespaceObject.createContext)();
/* harmony default export */ var context = (InserterListboxContext);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter-listbox/item.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
function InserterListboxItem({
isFirst,
as: Component,
children,
...props
}, ref) {
const state = (0,external_wp_element_namespaceObject.useContext)(context);
return (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__unstableCompositeItem, {
ref: ref,
state: state,
role: "option"
// Use the CompositeItem `focusable` prop over Button's
// isFocusable. The latter was shown to cause an issue
// with tab order in the inserter list.
,
focusable: true,
...props
}, htmlProps => {
const propsWithTabIndex = {
...htmlProps,
tabIndex: isFirst ? 0 : htmlProps.tabIndex
};
if (Component) {
return (0,external_wp_element_namespaceObject.createElement)(Component, {
...propsWithTabIndex
}, children);
}
if (typeof children === 'function') {
return children(propsWithTabIndex);
}
return (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.Button, {
...propsWithTabIndex
}, children);
});
}
/* harmony default export */ var inserter_listbox_item = ((0,external_wp_element_namespaceObject.forwardRef)(InserterListboxItem));
;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/drag-handle.js
/**
* WordPress dependencies
*/
const dragHandle = (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.SVG, {
width: "24",
height: "24",
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 24 24"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.Path, {
d: "M8 7h2V5H8v2zm0 6h2v-2H8v2zm0 6h2v-2H8v2zm6-14v2h2V5h-2zm0 8h2v-2h-2v2zm0 6h2v-2h-2v2z"
}));
/* harmony default export */ var drag_handle = (dragHandle);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-draggable/draggable-chip.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
function BlockDraggableChip({
count,
icon,
isPattern
}) {
const patternLabel = isPattern && (0,external_wp_i18n_namespaceObject.__)('Pattern');
return (0,external_wp_element_namespaceObject.createElement)("div", {
className: "block-editor-block-draggable-chip-wrapper"
}, (0,external_wp_element_namespaceObject.createElement)("div", {
className: "block-editor-block-draggable-chip",
"data-testid": "block-draggable-chip"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.Flex, {
justify: "center",
className: "block-editor-block-draggable-chip__content"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.FlexItem, null, icon ? (0,external_wp_element_namespaceObject.createElement)(block_icon, {
icon: icon
}) : patternLabel || (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: %d: Number of blocks. */
(0,external_wp_i18n_namespaceObject._n)('%d block', '%d blocks', count), count)), (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.FlexItem, null, (0,external_wp_element_namespaceObject.createElement)(block_icon, {
icon: drag_handle
})))));
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter-draggable-blocks/index.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const InserterDraggableBlocks = ({
isEnabled,
blocks,
icon,
children,
isPattern
}) => {
const transferData = {
type: 'inserter',
blocks
};
const blockTypeIcon = (0,external_wp_data_namespaceObject.useSelect)(select => {
const {
getBlockType
} = select(external_wp_blocks_namespaceObject.store);
return blocks.length === 1 && getBlockType(blocks[0].name)?.icon;
}, [blocks]);
return (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.Draggable, {
__experimentalTransferDataType: "wp-blocks",
transferData: transferData,
onDragStart: event => {
event.dataTransfer.setData('text/html', (0,external_wp_blocks_namespaceObject.serialize)(blocks));
},
__experimentalDragComponent: (0,external_wp_element_namespaceObject.createElement)(BlockDraggableChip, {
count: blocks.length,
icon: icon || !isPattern && blockTypeIcon,
isPattern: isPattern
})
}, ({
onDraggableStart,
onDraggableEnd
}) => {
return children({
draggable: isEnabled,
onDragStart: isEnabled ? onDraggableStart : undefined,
onDragEnd: isEnabled ? onDraggableEnd : undefined
});
});
};
/* harmony default export */ var inserter_draggable_blocks = (InserterDraggableBlocks);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter-list-item/index.js
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
function InserterListItem({
className,
isFirst,
item,
onSelect,
onHover,
isDraggable,
...props
}) {
const isDragging = (0,external_wp_element_namespaceObject.useRef)(false);
const itemIconStyle = item.icon ? {
backgroundColor: item.icon.background,
color: item.icon.foreground
} : {};
const blocks = (0,external_wp_element_namespaceObject.useMemo)(() => {
return [(0,external_wp_blocks_namespaceObject.createBlock)(item.name, item.initialAttributes, (0,external_wp_blocks_namespaceObject.createBlocksFromInnerBlocksTemplate)(item.innerBlocks))];
}, [item.name, item.initialAttributes, item.initialAttributes]);
const isSynced = (0,external_wp_blocks_namespaceObject.isReusableBlock)(item) && item.syncStatus !== 'unsynced' || (0,external_wp_blocks_namespaceObject.isTemplatePart)(item);
return (0,external_wp_element_namespaceObject.createElement)(inserter_draggable_blocks, {
isEnabled: isDraggable && !item.disabled,
blocks: blocks,
icon: item.icon
}, ({
draggable,
onDragStart,
onDragEnd
}) => (0,external_wp_element_namespaceObject.createElement)("div", {
className: classnames_default()('block-editor-block-types-list__list-item', {
'is-synced': isSynced
}),
draggable: draggable,
onDragStart: event => {
isDragging.current = true;
if (onDragStart) {
onHover(null);
onDragStart(event);
}
},
onDragEnd: event => {
isDragging.current = false;
if (onDragEnd) {
onDragEnd(event);
}
}
}, (0,external_wp_element_namespaceObject.createElement)(inserter_listbox_item, {
isFirst: isFirst,
className: classnames_default()('block-editor-block-types-list__item', className),
disabled: item.isDisabled,
onClick: event => {
event.preventDefault();
onSelect(item, (0,external_wp_keycodes_namespaceObject.isAppleOS)() ? event.metaKey : event.ctrlKey);
onHover(null);
},
onKeyDown: event => {
const {
keyCode
} = event;
if (keyCode === external_wp_keycodes_namespaceObject.ENTER) {
event.preventDefault();
onSelect(item, (0,external_wp_keycodes_namespaceObject.isAppleOS)() ? event.metaKey : event.ctrlKey);
onHover(null);
}
},
onMouseEnter: () => {
if (isDragging.current) {
return;
}
onHover(item);
},
onMouseLeave: () => onHover(null),
...props
}, (0,external_wp_element_namespaceObject.createElement)("span", {
className: "block-editor-block-types-list__item-icon",
style: itemIconStyle
}, (0,external_wp_element_namespaceObject.createElement)(block_icon, {
icon: item.icon,
showColors: true
})), (0,external_wp_element_namespaceObject.createElement)("span", {
className: "block-editor-block-types-list__item-title"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__experimentalTruncate, {
numberOfLines: 3
}, item.title)))));
}
/* harmony default export */ var inserter_list_item = ((0,external_wp_element_namespaceObject.memo)(InserterListItem));
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter-listbox/group.js
/**
* WordPress dependencies
*/
function InserterListboxGroup(props, ref) {
const [shouldSpeak, setShouldSpeak] = (0,external_wp_element_namespaceObject.useState)(false);
(0,external_wp_element_namespaceObject.useEffect)(() => {
if (shouldSpeak) {
(0,external_wp_a11y_namespaceObject.speak)((0,external_wp_i18n_namespaceObject.__)('Use left and right arrow keys to move through blocks'));
}
}, [shouldSpeak]);
return (0,external_wp_element_namespaceObject.createElement)("div", {
ref: ref,
role: "listbox",
"aria-orientation": "horizontal",
onFocus: () => {
setShouldSpeak(true);
},
onBlur: event => {
const focusingOutsideGroup = !event.currentTarget.contains(event.relatedTarget);
if (focusingOutsideGroup) {
setShouldSpeak(false);
}
},
...props
});
}
/* harmony default export */ var group = ((0,external_wp_element_namespaceObject.forwardRef)(InserterListboxGroup));
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter-listbox/row.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
function InserterListboxRow(props, ref) {
const state = (0,external_wp_element_namespaceObject.useContext)(context);
return (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__unstableCompositeGroup, {
state: state,
role: "presentation",
ref: ref,
...props
});
}
/* harmony default export */ var inserter_listbox_row = ((0,external_wp_element_namespaceObject.forwardRef)(InserterListboxRow));
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-types-list/index.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
function chunk(array, size) {
const chunks = [];
for (let i = 0, j = array.length; i < j; i += size) {
chunks.push(array.slice(i, i + size));
}
return chunks;
}
function BlockTypesList({
items = [],
onSelect,
onHover = () => {},
children,
label,
isDraggable = true
}) {
return (0,external_wp_element_namespaceObject.createElement)(group, {
className: "block-editor-block-types-list",
"aria-label": label
}, chunk(items, 3).map((row, i) => (0,external_wp_element_namespaceObject.createElement)(inserter_listbox_row, {
key: i
}, row.map((item, j) => (0,external_wp_element_namespaceObject.createElement)(inserter_list_item, {
key: item.id,
item: item,
className: (0,external_wp_blocks_namespaceObject.getBlockMenuDefaultClassName)(item.id),
onSelect: onSelect,
onHover: onHover,
isDraggable: isDraggable && !item.isDisabled,
isFirst: i === 0 && j === 0
})))), children);
}
/* harmony default export */ var block_types_list = (BlockTypesList);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/panel.js
/**
* WordPress dependencies
*/
function InserterPanel({
title,
icon,
children
}) {
return (0,external_wp_element_namespaceObject.createElement)(external_wp_element_namespaceObject.Fragment, null, (0,external_wp_element_namespaceObject.createElement)("div", {
className: "block-editor-inserter__panel-header"
}, (0,external_wp_element_namespaceObject.createElement)("h2", {
className: "block-editor-inserter__panel-title"
}, title), (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.Icon, {
icon: icon
})), (0,external_wp_element_namespaceObject.createElement)("div", {
className: "block-editor-inserter__panel-content"
}, children));
}
/* harmony default export */ var panel = (InserterPanel);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/hooks/use-block-types-state.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
/**
* Retrieves the block types inserter state.
*
* @param {string=} rootClientId Insertion's root client ID.
* @param {Function} onInsert function called when inserter a list of blocks.
* @return {Array} Returns the block types state. (block types, categories, collections, onSelect handler)
*/
const useBlockTypesState = (rootClientId, onInsert) => {
const {
categories,
collections,
items
} = (0,external_wp_data_namespaceObject.useSelect)(select => {
const {
getInserterItems
} = select(store);
const {
getCategories,
getCollections
} = select(external_wp_blocks_namespaceObject.store);
return {
categories: getCategories(),
collections: getCollections(),
items: getInserterItems(rootClientId)
};
}, [rootClientId]);
const onSelectItem = (0,external_wp_element_namespaceObject.useCallback)(({
name,
initialAttributes,
innerBlocks,
syncStatus,
content
}, shouldFocusBlock) => {
const insertedBlock = syncStatus === 'unsynced' ? (0,external_wp_blocks_namespaceObject.parse)(content, {
__unstableSkipMigrationLogs: true
}) : (0,external_wp_blocks_namespaceObject.createBlock)(name, initialAttributes, (0,external_wp_blocks_namespaceObject.createBlocksFromInnerBlocksTemplate)(innerBlocks));
onInsert(insertedBlock, undefined, shouldFocusBlock);
}, [onInsert]);
return [items, categories, collections, onSelectItem];
};
/* harmony default export */ var use_block_types_state = (useBlockTypesState);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter-listbox/index.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
function InserterListbox({
children
}) {
const compositeState = (0,external_wp_components_namespaceObject.__unstableUseCompositeState)({
shift: true,
wrap: 'horizontal'
});
return (0,external_wp_element_namespaceObject.createElement)(context.Provider, {
value: compositeState
}, children);
}
/* harmony default export */ var inserter_listbox = (InserterListbox);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/block-types-tab.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const getBlockNamespace = item => item.name.split('/')[0];
const MAX_SUGGESTED_ITEMS = 6;
/**
* Shared reference to an empty array for cases where it is important to avoid
* returning a new array reference on every invocation and rerendering the component.
*
* @type {Array}
*/
const block_types_tab_EMPTY_ARRAY = [];
function BlockTypesTab({
rootClientId,
onInsert,
onHover,
showMostUsedBlocks
}) {
const [items, categories, collections, onSelectItem] = use_block_types_state(rootClientId, onInsert);
const suggestedItems = (0,external_wp_element_namespaceObject.useMemo)(() => {
return orderBy(items, 'frecency', 'desc').slice(0, MAX_SUGGESTED_ITEMS);
}, [items]);
const uncategorizedItems = (0,external_wp_element_namespaceObject.useMemo)(() => {
return items.filter(item => !item.category);
}, [items]);
const itemsPerCategory = (0,external_wp_element_namespaceObject.useMemo)(() => {
return (0,external_wp_compose_namespaceObject.pipe)(itemList => itemList.filter(item => item.category && item.category !== 'reusable'), itemList => itemList.reduce((acc, item) => {
const {
category
} = item;
if (!acc[category]) {
acc[category] = [];
}
acc[category].push(item);
return acc;
}, {}))(items);
}, [items]);
const itemsPerCollection = (0,external_wp_element_namespaceObject.useMemo)(() => {
// Create a new Object to avoid mutating collection.
const result = {
...collections
};
Object.keys(collections).forEach(namespace => {
result[namespace] = items.filter(item => getBlockNamespace(item) === namespace);
if (result[namespace].length === 0) {
delete result[namespace];
}
});
return result;
}, [items, collections]);
// Hide block preview on unmount.
(0,external_wp_element_namespaceObject.useEffect)(() => () => onHover(null), []);
/**
* The inserter contains a big number of blocks and opening it is a costful operation.
* The rendering is the most costful part of it, in order to improve the responsiveness
* of the "opening" action, these lazy lists allow us to render the inserter category per category,
* once all the categories are rendered, we start rendering the collections and the uncategorized block types.
*/
const currentlyRenderedCategories = (0,external_wp_compose_namespaceObject.useAsyncList)(categories);
const didRenderAllCategories = categories.length === currentlyRenderedCategories.length;
// Async List requires an array.
const collectionEntries = (0,external_wp_element_namespaceObject.useMemo)(() => {
return Object.entries(collections);
}, [collections]);
const currentlyRenderedCollections = (0,external_wp_compose_namespaceObject.useAsyncList)(didRenderAllCategories ? collectionEntries : block_types_tab_EMPTY_ARRAY);
return (0,external_wp_element_namespaceObject.createElement)(inserter_listbox, null, (0,external_wp_element_namespaceObject.createElement)("div", null, showMostUsedBlocks && !!suggestedItems.length && (0,external_wp_element_namespaceObject.createElement)(panel, {
title: (0,external_wp_i18n_namespaceObject._x)('Most used', 'blocks')
}, (0,external_wp_element_namespaceObject.createElement)(block_types_list, {
items: suggestedItems,
onSelect: onSelectItem,
onHover: onHover,
label: (0,external_wp_i18n_namespaceObject._x)('Most used', 'blocks')
})), currentlyRenderedCategories.map(category => {
const categoryItems = itemsPerCategory[category.slug];
if (!categoryItems || !categoryItems.length) {
return null;
}
return (0,external_wp_element_namespaceObject.createElement)(panel, {
key: category.slug,
title: category.title,
icon: category.icon
}, (0,external_wp_element_namespaceObject.createElement)(block_types_list, {
items: categoryItems,
onSelect: onSelectItem,
onHover: onHover,
label: category.title
}));
}), didRenderAllCategories && uncategorizedItems.length > 0 && (0,external_wp_element_namespaceObject.createElement)(panel, {
className: "block-editor-inserter__uncategorized-blocks-panel",
title: (0,external_wp_i18n_namespaceObject.__)('Uncategorized')
}, (0,external_wp_element_namespaceObject.createElement)(block_types_list, {
items: uncategorizedItems,
onSelect: onSelectItem,
onHover: onHover,
label: (0,external_wp_i18n_namespaceObject.__)('Uncategorized')
})), currentlyRenderedCollections.map(([namespace, collection]) => {
const collectionItems = itemsPerCollection[namespace];
if (!collectionItems || !collectionItems.length) {
return null;
}
return (0,external_wp_element_namespaceObject.createElement)(panel, {
key: namespace,
title: collection.title,
icon: collection.icon
}, (0,external_wp_element_namespaceObject.createElement)(block_types_list, {
items: collectionItems,
onSelect: onSelectItem,
onHover: onHover,
label: collection.title
}));
})));
}
/* harmony default export */ var block_types_tab = (BlockTypesTab);
;// CONCATENATED MODULE: external ["wp","notices"]
var external_wp_notices_namespaceObject = window["wp"]["notices"];
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/hooks/use-patterns-state.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
/**
* Retrieves the block patterns inserter state.
*
* @param {Function} onInsert function called when inserter a list of blocks.
* @param {string=} rootClientId Insertion's root client ID.
*
* @return {Array} Returns the patterns state. (patterns, categories, onSelect handler)
*/
const usePatternsState = (onInsert, rootClientId) => {
const {
patternCategories,
patterns,
userPatternCategories
} = (0,external_wp_data_namespaceObject.useSelect)(select => {
const {
__experimentalGetAllowedPatterns,
getSettings
} = select(store);
const {
__experimentalUserPatternCategories,
__experimentalBlockPatternCategories
} = getSettings();
return {
patterns: __experimentalGetAllowedPatterns(rootClientId),
userPatternCategories: __experimentalUserPatternCategories,
patternCategories: __experimentalBlockPatternCategories
};
}, [rootClientId]);
const allCategories = (0,external_wp_element_namespaceObject.useMemo)(() => {
const categories = [...patternCategories];
userPatternCategories?.forEach(userCategory => {
if (!categories.find(existingCategory => existingCategory.name === userCategory.name)) {
categories.push(userCategory);
}
});
return categories;
}, [patternCategories, userPatternCategories]);
const {
createSuccessNotice
} = (0,external_wp_data_namespaceObject.useDispatch)(external_wp_notices_namespaceObject.store);
const onClickPattern = (0,external_wp_element_namespaceObject.useCallback)((pattern, blocks) => {
const patternBlocks = pattern.id && pattern.syncStatus !== 'unsynced' ? [(0,external_wp_blocks_namespaceObject.createBlock)('core/block', {
ref: pattern.id
})] : blocks;
onInsert((patternBlocks !== null && patternBlocks !== void 0 ? patternBlocks : []).map(block => (0,external_wp_blocks_namespaceObject.cloneBlock)(block)), pattern.name);
createSuccessNotice((0,external_wp_i18n_namespaceObject.sprintf)( /* translators: %s: block pattern title. */
(0,external_wp_i18n_namespaceObject.__)('Block pattern "%s" inserted.'), pattern.title), {
type: 'snackbar',
id: 'block-pattern-inserted-notice'
});
}, [createSuccessNotice, onInsert]);
return [patterns, allCategories, onClickPattern];
};
/* harmony default export */ var use_patterns_state = (usePatternsState);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-patterns-paging/index.js
/**
* WordPress dependencies
*/
function Pagination({
currentPage,
numPages,
changePage,
totalItems
}) {
return (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__experimentalVStack, {
className: "block-editor-patterns__grid-pagination-wrapper"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__experimentalText, {
variant: "muted"
},
// translators: %s: Total number of patterns.
(0,external_wp_i18n_namespaceObject.sprintf)(
// translators: %s: Total number of patterns.
(0,external_wp_i18n_namespaceObject._n)('%s item', '%s items', totalItems), totalItems)), numPages > 1 && (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__experimentalHStack, {
expanded: false,
spacing: 3,
justify: "flex-start",
className: "block-editor-patterns__grid-pagination"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__experimentalHStack, {
expanded: false,
spacing: 1,
className: "block-editor-patterns__grid-pagination-previous"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.Button, {
variant: "tertiary",
onClick: () => changePage(1),
disabled: currentPage === 1,
"aria-label": (0,external_wp_i18n_namespaceObject.__)('First page')
}, (0,external_wp_element_namespaceObject.createElement)("span", null, "\xAB")), (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.Button, {
variant: "tertiary",
onClick: () => changePage(currentPage - 1),
disabled: currentPage === 1,
"aria-label": (0,external_wp_i18n_namespaceObject.__)('Previous page')
}, (0,external_wp_element_namespaceObject.createElement)("span", null, "\u2039"))), (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__experimentalText, {
variant: "muted"
}, (0,external_wp_i18n_namespaceObject.sprintf)(
// translators: %1$s: Current page number, %2$s: Total number of pages.
(0,external_wp_i18n_namespaceObject._x)('%1$s of %2$s', 'paging'), currentPage, numPages)), (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__experimentalHStack, {
expanded: false,
spacing: 1,
className: "block-editor-patterns__grid-pagination-next"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.Button, {
variant: "tertiary",
onClick: () => changePage(currentPage + 1),
disabled: currentPage === numPages,
"aria-label": (0,external_wp_i18n_namespaceObject.__)('Next page')
}, (0,external_wp_element_namespaceObject.createElement)("span", null, "\u203A")), (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.Button, {
variant: "tertiary",
onClick: () => changePage(numPages),
disabled: currentPage === numPages,
"aria-label": (0,external_wp_i18n_namespaceObject.__)('Last page'),
size: "default"
}, (0,external_wp_element_namespaceObject.createElement)("span", null, "\xBB")))));
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-patterns-list/index.js
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const WithToolTip = ({
showTooltip,
title,
children
}) => {
if (showTooltip) {
return (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.Tooltip, {
text: title
}, children);
}
return (0,external_wp_element_namespaceObject.createElement)(external_wp_element_namespaceObject.Fragment, null, children);
};
function BlockPattern({
isDraggable,
pattern,
onClick,
onHover,
composite,
showTooltip
}) {
const [isDragging, setIsDragging] = (0,external_wp_element_namespaceObject.useState)(false);
const {
blocks,
viewportWidth
} = pattern;
const instanceId = (0,external_wp_compose_namespaceObject.useInstanceId)(BlockPattern);
const descriptionId = `block-editor-block-patterns-list__item-description-${instanceId}`;
return (0,external_wp_element_namespaceObject.createElement)(inserter_draggable_blocks, {
isEnabled: isDraggable,
blocks: blocks,
isPattern: !!pattern
}, ({
draggable,
onDragStart,
onDragEnd
}) => (0,external_wp_element_namespaceObject.createElement)("div", {
className: "block-editor-block-patterns-list__list-item",
draggable: draggable,
onDragStart: event => {
setIsDragging(true);
if (onDragStart) {
onHover?.(null);
onDragStart(event);
}
},
onDragEnd: event => {
setIsDragging(false);
if (onDragEnd) {
onDragEnd(event);
}
}
}, (0,external_wp_element_namespaceObject.createElement)(WithToolTip, {
showTooltip: showTooltip && !pattern.type === 'user',
title: pattern.title
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__unstableCompositeItem, {
role: "option",
as: "div",
...composite,
className: classnames_default()('block-editor-block-patterns-list__item', {
'block-editor-block-patterns-list__list-item-synced': pattern.type === 'user' && !pattern.syncStatus
}),
onClick: () => {
onClick(pattern, blocks);
onHover?.(null);
},
onMouseEnter: () => {
if (isDragging) {
return;
}
onHover?.(pattern);
},
onMouseLeave: () => onHover?.(null),
"aria-label": pattern.title,
"aria-describedby": pattern.description ? descriptionId : undefined
}, (0,external_wp_element_namespaceObject.createElement)(block_preview, {
blocks: blocks,
viewportWidth: viewportWidth
}), (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__experimentalHStack, {
className: "block-editor-patterns__pattern-details"
}, pattern.type === 'user' && !pattern.syncStatus && (0,external_wp_element_namespaceObject.createElement)("div", {
className: "block-editor-patterns__pattern-icon-wrapper"
}, (0,external_wp_element_namespaceObject.createElement)(build_module_icon, {
className: "block-editor-patterns__pattern-icon",
icon: library_symbol
})), (!showTooltip || pattern.type === 'user') && (0,external_wp_element_namespaceObject.createElement)("div", {
className: "block-editor-block-patterns-list__item-title"
}, pattern.title)), !!pattern.description && (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.VisuallyHidden, {
id: descriptionId
}, pattern.description)))));
}
function BlockPatternPlaceholder() {
return (0,external_wp_element_namespaceObject.createElement)("div", {
className: "block-editor-block-patterns-list__item is-placeholder"
});
}
function BlockPatternList({
isDraggable,
blockPatterns,
shownPatterns,
onHover,
onClickPattern,
orientation,
label = (0,external_wp_i18n_namespaceObject.__)('Block patterns'),
showTitlesAsTooltip,
pagingProps
}, ref) {
const composite = (0,external_wp_components_namespaceObject.__unstableUseCompositeState)({
orientation
});
return (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__unstableComposite, {
...composite,
role: "listbox",
className: "block-editor-block-patterns-list",
"aria-label": label,
ref: ref
}, blockPatterns.map(pattern => {
const isShown = shownPatterns.includes(pattern);
return isShown ? (0,external_wp_element_namespaceObject.createElement)(BlockPattern, {
key: pattern.name,
pattern: pattern,
onClick: onClickPattern,
onHover: onHover,
isDraggable: isDraggable,
composite: composite,
showTooltip: showTitlesAsTooltip
}) : (0,external_wp_element_namespaceObject.createElement)(BlockPatternPlaceholder, {
key: pattern.name
});
}), pagingProps && (0,external_wp_element_namespaceObject.createElement)(Pagination, {
...pagingProps
}));
}
/* harmony default export */ var block_patterns_list = ((0,external_wp_element_namespaceObject.forwardRef)(BlockPatternList));
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/block-patterns-explorer/sidebar.js
/**
* WordPress dependencies
*/
function PatternCategoriesList({
selectedCategory,
patternCategories,
onClickCategory
}) {
const baseClassName = 'block-editor-block-patterns-explorer__sidebar';
return (0,external_wp_element_namespaceObject.createElement)("div", {
className: `${baseClassName}__categories-list`
}, patternCategories.map(({
name,
label
}) => {
return (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.Button, {
key: name,
label: label,
className: `${baseClassName}__categories-list__item`,
isPressed: selectedCategory === name,
onClick: () => {
onClickCategory(name);
}
}, label);
}));
}
function PatternsExplorerSearch({
searchValue,
setSearchValue
}) {
const baseClassName = 'block-editor-block-patterns-explorer__search';
return (0,external_wp_element_namespaceObject.createElement)("div", {
className: baseClassName
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.SearchControl, {
__nextHasNoMarginBottom: true,
onChange: setSearchValue,
value: searchValue,
label: (0,external_wp_i18n_namespaceObject.__)('Search for patterns'),
placeholder: (0,external_wp_i18n_namespaceObject.__)('Search')
}));
}
function PatternExplorerSidebar({
selectedCategory,
patternCategories,
onClickCategory,
searchValue,
setSearchValue
}) {
const baseClassName = 'block-editor-block-patterns-explorer__sidebar';
return (0,external_wp_element_namespaceObject.createElement)("div", {
className: baseClassName
}, (0,external_wp_element_namespaceObject.createElement)(PatternsExplorerSearch, {
searchValue: searchValue,
setSearchValue: setSearchValue
}), !searchValue && (0,external_wp_element_namespaceObject.createElement)(PatternCategoriesList, {
selectedCategory: selectedCategory,
patternCategories: patternCategories,
onClickCategory: onClickCategory
}));
}
/* harmony default export */ var sidebar = (PatternExplorerSidebar);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/hooks/use-insertion-point.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
/**
* @typedef WPInserterConfig
*
* @property {string=} rootClientId If set, insertion will be into the
* block with this ID.
* @property {number=} insertionIndex If set, insertion will be into this
* explicit position.
* @property {string=} clientId If set, insertion will be after the
* block with this ID.
* @property {boolean=} isAppender Whether the inserter is an appender
* or not.
* @property {Function=} onSelect Called after insertion.
*/
/**
* Returns the insertion point state given the inserter config.
*
* @param {WPInserterConfig} config Inserter Config.
* @return {Array} Insertion Point State (rootClientID, onInsertBlocks and onToggle).
*/
function useInsertionPoint({
rootClientId = '',
insertionIndex,
clientId,
isAppender,
onSelect,
shouldFocusBlock = true,
selectBlockOnInsert = true
}) {
const {
getSelectedBlock
} = (0,external_wp_data_namespaceObject.useSelect)(store);
const {
destinationRootClientId,
destinationIndex
} = (0,external_wp_data_namespaceObject.useSelect)(select => {
const {
getSelectedBlockClientId,
getBlockRootClientId,
getBlockIndex,
getBlockOrder
} = select(store);
const selectedBlockClientId = getSelectedBlockClientId();
let _destinationRootClientId = rootClientId;
let _destinationIndex;
if (insertionIndex !== undefined) {
// Insert into a specific index.
_destinationIndex = insertionIndex;
} else if (clientId) {
// Insert after a specific client ID.
_destinationIndex = getBlockIndex(clientId);
} else if (!isAppender && selectedBlockClientId) {
_destinationRootClientId = getBlockRootClientId(selectedBlockClientId);
_destinationIndex = getBlockIndex(selectedBlockClientId) + 1;
} else {
// Insert at the end of the list.
_destinationIndex = getBlockOrder(_destinationRootClientId).length;
}
return {
destinationRootClientId: _destinationRootClientId,
destinationIndex: _destinationIndex
};
}, [rootClientId, insertionIndex, clientId, isAppender]);
const {
replaceBlocks,
insertBlocks,
showInsertionPoint,
hideInsertionPoint
} = (0,external_wp_data_namespaceObject.useDispatch)(store);
const onInsertBlocks = (0,external_wp_element_namespaceObject.useCallback)((blocks, meta, shouldForceFocusBlock = false) => {
const selectedBlock = getSelectedBlock();
if (!isAppender && selectedBlock && (0,external_wp_blocks_namespaceObject.isUnmodifiedDefaultBlock)(selectedBlock)) {
replaceBlocks(selectedBlock.clientId, blocks, null, shouldFocusBlock || shouldForceFocusBlock ? 0 : null, meta);
} else {
insertBlocks(blocks, destinationIndex, destinationRootClientId, selectBlockOnInsert, shouldFocusBlock || shouldForceFocusBlock ? 0 : null, meta);
}
const blockLength = Array.isArray(blocks) ? blocks.length : 1;
const message = (0,external_wp_i18n_namespaceObject.sprintf)(
// translators: %d: the name of the block that has been added
(0,external_wp_i18n_namespaceObject._n)('%d block added.', '%d blocks added.', blockLength), blockLength);
(0,external_wp_a11y_namespaceObject.speak)(message);
if (onSelect) {
onSelect(blocks);
}
}, [isAppender, getSelectedBlock, replaceBlocks, insertBlocks, destinationRootClientId, destinationIndex, onSelect, shouldFocusBlock, selectBlockOnInsert]);
const onToggleInsertionPoint = (0,external_wp_element_namespaceObject.useCallback)(show => {
if (show) {
showInsertionPoint(destinationRootClientId, destinationIndex);
} else {
hideInsertionPoint();
}
}, [showInsertionPoint, hideInsertionPoint, destinationRootClientId, destinationIndex]);
return [destinationRootClientId, onInsertBlocks, onToggleInsertionPoint];
}
/* harmony default export */ var use_insertion_point = (useInsertionPoint);
// EXTERNAL MODULE: ./node_modules/remove-accents/index.js
var remove_accents = __webpack_require__(4793);
var remove_accents_default = /*#__PURE__*/__webpack_require__.n(remove_accents);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/search-items.js
/**
* External dependencies
*/
// Default search helpers.
const defaultGetName = item => item.name || '';
const defaultGetTitle = item => item.title;
const defaultGetDescription = item => item.description || '';
const defaultGetKeywords = item => item.keywords || [];
const defaultGetCategory = item => item.category;
const defaultGetCollection = () => null;
/**
* Extracts words from an input string.
*
* @param {string} input The input string.
*
* @return {Array} Words, extracted from the input string.
*/
function extractWords(input = '') {
return noCase(input, {
splitRegexp: [/([\p{Ll}\p{Lo}\p{N}])([\p{Lu}\p{Lt}])/gu,
// One lowercase or digit, followed by one uppercase.
/([\p{Lu}\p{Lt}])([\p{Lu}\p{Lt}][\p{Ll}\p{Lo}])/gu // One uppercase followed by one uppercase and one lowercase.
],
stripRegexp: /(\p{C}|\p{P}|\p{S})+/giu // Anything that's not a punctuation, symbol or control/format character.
}).split(' ').filter(Boolean);
}
/**
* Sanitizes the search input string.
*
* @param {string} input The search input to normalize.
*
* @return {string} The normalized search input.
*/
function normalizeSearchInput(input = '') {
// Disregard diacritics.
// Input: "média"
input = remove_accents_default()(input);
// Accommodate leading slash, matching autocomplete expectations.
// Input: "/media"
input = input.replace(/^\//, '');
// Lowercase.
// Input: "MEDIA"
input = input.toLowerCase();
return input;
}
/**
* Converts the search term into a list of normalized terms.
*
* @param {string} input The search term to normalize.
*
* @return {string[]} The normalized list of search terms.
*/
const getNormalizedSearchTerms = (input = '') => {
return extractWords(normalizeSearchInput(input));
};
const removeMatchingTerms = (unmatchedTerms, unprocessedTerms) => {
return unmatchedTerms.filter(term => !getNormalizedSearchTerms(unprocessedTerms).some(unprocessedTerm => unprocessedTerm.includes(term)));
};
const searchBlockItems = (items, categories, collections, searchInput) => {
const normalizedSearchTerms = getNormalizedSearchTerms(searchInput);
if (normalizedSearchTerms.length === 0) {
return items;
}
const config = {
getCategory: item => categories.find(({
slug
}) => slug === item.category)?.title,
getCollection: item => collections[item.name.split('/')[0]]?.title
};
return searchItems(items, searchInput, config);
};
/**
* Filters an item list given a search term.
*
* @param {Array} items Item list
* @param {string} searchInput Search input.
* @param {Object} config Search Config.
*
* @return {Array} Filtered item list.
*/
const searchItems = (items = [], searchInput = '', config = {}) => {
const normalizedSearchTerms = getNormalizedSearchTerms(searchInput);
if (normalizedSearchTerms.length === 0) {
return items;
}
const rankedItems = items.map(item => {
return [item, getItemSearchRank(item, searchInput, config)];
}).filter(([, rank]) => rank > 0);
rankedItems.sort(([, rank1], [, rank2]) => rank2 - rank1);
return rankedItems.map(([item]) => item);
};
/**
* Get the search rank for a given item and a specific search term.
* The better the match, the higher the rank.
* If the rank equals 0, it should be excluded from the results.
*
* @param {Object} item Item to filter.
* @param {string} searchTerm Search term.
* @param {Object} config Search Config.
*
* @return {number} Search Rank.
*/
function getItemSearchRank(item, searchTerm, config = {}) {
const {
getName = defaultGetName,
getTitle = defaultGetTitle,
getDescription = defaultGetDescription,
getKeywords = defaultGetKeywords,
getCategory = defaultGetCategory,
getCollection = defaultGetCollection
} = config;
const name = getName(item);
const title = getTitle(item);
const description = getDescription(item);
const keywords = getKeywords(item);
const category = getCategory(item);
const collection = getCollection(item);
const normalizedSearchInput = normalizeSearchInput(searchTerm);
const normalizedTitle = normalizeSearchInput(title);
let rank = 0;
// Prefers exact matches
// Then prefers if the beginning of the title matches the search term
// name, keywords, categories, collection, variations match come later.
if (normalizedSearchInput === normalizedTitle) {
rank += 30;
} else if (normalizedTitle.startsWith(normalizedSearchInput)) {
rank += 20;
} else {
const terms = [name, title, description, ...keywords, category, collection].join(' ');
const normalizedSearchTerms = extractWords(normalizedSearchInput);
const unmatchedTerms = removeMatchingTerms(normalizedSearchTerms, terms);
if (unmatchedTerms.length === 0) {
rank += 10;
}
}
// Give a better rank to "core" namespaced items.
if (rank !== 0 && name.startsWith('core/')) {
const isCoreBlockVariation = name !== item.id;
// Give a bit better rank to "core" blocks over "core" block variations.
rank += isCoreBlockVariation ? 1 : 2;
}
return rank;
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/hooks/use-patterns-paging.js
/**
* WordPress dependencies
*/
const PAGE_SIZE = 20;
const INITIAL_INSERTER_RESULTS = 5;
/**
* Supplies values needed to page the patterns list client side.
*
* @param {Array} currentCategoryPatterns An array of the current patterns to display.
* @param {string} currentCategory The currently selected category.
* @param {Object} scrollContainerRef Ref of container to to find scroll container for when moving between pages.
* @param {string} currentFilter The currently search filter.
*
* @return {Object} Returns the relevant paging values. (totalItems, categoryPatternsList, numPages, changePage, currentPage)
*/
function usePatternsPaging(currentCategoryPatterns, currentCategory, scrollContainerRef, currentFilter = '') {
const [currentPage, setCurrentPage] = (0,external_wp_element_namespaceObject.useState)(1);
const previousCategory = (0,external_wp_compose_namespaceObject.usePrevious)(currentCategory);
const previousFilter = (0,external_wp_compose_namespaceObject.usePrevious)(currentFilter);
if ((previousCategory !== currentCategory || previousFilter !== currentFilter) && currentPage !== 1) {
setCurrentPage(1);
}
const totalItems = currentCategoryPatterns.length;
const pageIndex = currentPage - 1;
const categoryPatterns = (0,external_wp_element_namespaceObject.useMemo)(() => {
return currentCategoryPatterns.slice(pageIndex * PAGE_SIZE, pageIndex * PAGE_SIZE + PAGE_SIZE);
}, [pageIndex, currentCategoryPatterns]);
const categoryPatternsAsyncList = (0,external_wp_compose_namespaceObject.useAsyncList)(categoryPatterns, {
step: INITIAL_INSERTER_RESULTS
});
const numPages = Math.ceil(currentCategoryPatterns.length / PAGE_SIZE);
const changePage = page => {
const scrollContainer = (0,external_wp_dom_namespaceObject.getScrollContainer)(scrollContainerRef?.current);
scrollContainer?.scrollTo(0, 0);
setCurrentPage(page);
};
(0,external_wp_element_namespaceObject.useEffect)(function scrollToTopOnCategoryChange() {
const scrollContainer = (0,external_wp_dom_namespaceObject.getScrollContainer)(scrollContainerRef?.current);
scrollContainer?.scrollTo(0, 0);
}, [currentCategory, scrollContainerRef]);
return {
totalItems,
categoryPatterns,
categoryPatternsAsyncList,
numPages,
changePage,
currentPage
};
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/block-patterns-explorer/patterns-list.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
function PatternsListHeader({
filterValue,
filteredBlockPatternsLength
}) {
if (!filterValue) {
return null;
}
return (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__experimentalHeading, {
level: 2,
lineHeight: '48px',
className: "block-editor-block-patterns-explorer__search-results-count"
}, (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: %d: number of patterns. */
(0,external_wp_i18n_namespaceObject._n)('%d pattern found', '%d patterns found', filteredBlockPatternsLength), filteredBlockPatternsLength));
}
function PatternList({
searchValue,
selectedCategory,
patternCategories
}) {
const container = (0,external_wp_element_namespaceObject.useRef)();
const debouncedSpeak = (0,external_wp_compose_namespaceObject.useDebounce)(external_wp_a11y_namespaceObject.speak, 500);
const [destinationRootClientId, onInsertBlocks] = use_insertion_point({
shouldFocusBlock: true
});
const [patterns,, onClickPattern] = use_patterns_state(onInsertBlocks, destinationRootClientId);
const registeredPatternCategories = (0,external_wp_element_namespaceObject.useMemo)(() => patternCategories.map(patternCategory => patternCategory.name), [patternCategories]);
const filteredBlockPatterns = (0,external_wp_element_namespaceObject.useMemo)(() => {
const filteredPatterns = patterns.filter(pattern => {
if (selectedCategory === allPatternsCategory.name) {
return true;
}
if (selectedCategory === myPatternsCategory.name && pattern.id) {
return true;
}
if (selectedCategory === 'uncategorized') {
const hasKnownCategory = pattern.categories.some(category => registeredPatternCategories.includes(category));
return !pattern.categories?.length || !hasKnownCategory;
}
return pattern.categories?.includes(selectedCategory);
});
if (!searchValue) {
return filteredPatterns;
}
return searchItems(filteredPatterns, searchValue);
}, [searchValue, patterns, selectedCategory, registeredPatternCategories]);
// Announce search results on change.
(0,external_wp_element_namespaceObject.useEffect)(() => {
if (!searchValue) {
return;
}
const count = filteredBlockPatterns.length;
const resultsFoundMessage = (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: %d: number of results. */
(0,external_wp_i18n_namespaceObject._n)('%d result found.', '%d results found.', count), count);
debouncedSpeak(resultsFoundMessage);
}, [searchValue, debouncedSpeak, filteredBlockPatterns.length]);
const pagingProps = usePatternsPaging(filteredBlockPatterns, selectedCategory, container);
// Reset page when search value changes.
const [previousSearchValue, setPreviousSearchValue] = (0,external_wp_element_namespaceObject.useState)(searchValue);
if (searchValue !== previousSearchValue) {
setPreviousSearchValue(searchValue);
pagingProps.changePage(1);
}
const hasItems = !!filteredBlockPatterns?.length;
return (0,external_wp_element_namespaceObject.createElement)("div", {
className: "block-editor-block-patterns-explorer__list",
ref: container
}, (0,external_wp_element_namespaceObject.createElement)(PatternsListHeader, {
filterValue: searchValue,
filteredBlockPatternsLength: filteredBlockPatterns.length
}), (0,external_wp_element_namespaceObject.createElement)(inserter_listbox, null, hasItems && (0,external_wp_element_namespaceObject.createElement)(external_wp_element_namespaceObject.Fragment, null, (0,external_wp_element_namespaceObject.createElement)(block_patterns_list, {
shownPatterns: pagingProps.categoryPatternsAsyncList,
blockPatterns: pagingProps.categoryPatterns,
onClickPattern: onClickPattern,
isDraggable: false
}), (0,external_wp_element_namespaceObject.createElement)(Pagination, {
...pagingProps
}))));
}
/* harmony default export */ var patterns_list = (PatternList);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/block-patterns-explorer/explorer.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
function PatternsExplorer({
initialCategory,
rootClientId
}) {
const [searchValue, setSearchValue] = (0,external_wp_element_namespaceObject.useState)('');
const [patternSourceFilter, setPatternSourceFilter] = (0,external_wp_element_namespaceObject.useState)('all');
const [selectedCategory, setSelectedCategory] = (0,external_wp_element_namespaceObject.useState)(initialCategory?.name);
const patternCategories = usePatternsCategories(rootClientId, patternSourceFilter);
return (0,external_wp_element_namespaceObject.createElement)("div", {
className: "block-editor-block-patterns-explorer"
}, (0,external_wp_element_namespaceObject.createElement)(sidebar, {
selectedCategory: selectedCategory,
patternCategories: patternCategories,
onClickCategory: setSelectedCategory,
searchValue: searchValue,
setSearchValue: setSearchValue,
patternSourceFilter: patternSourceFilter,
setPatternSourceFilter: setPatternSourceFilter
}), (0,external_wp_element_namespaceObject.createElement)(patterns_list, {
searchValue: searchValue,
selectedCategory: selectedCategory,
patternCategories: patternCategories,
patternSourceFilter: patternSourceFilter
}));
}
function PatternsExplorerModal({
onModalClose,
...restProps
}) {
return (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.Modal, {
title: (0,external_wp_i18n_namespaceObject.__)('Patterns'),
onRequestClose: onModalClose,
isFullScreen: true
}, (0,external_wp_element_namespaceObject.createElement)(PatternsExplorer, {
...restProps
}));
}
/* harmony default export */ var explorer = (PatternsExplorerModal);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/mobile-tab-navigation.js
/**
* WordPress dependencies
*/
function ScreenHeader({
title
}) {
return (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__experimentalVStack, {
spacing: 0
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__experimentalView, null, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__experimentalSpacer, {
marginBottom: 0,
paddingX: 4,
paddingY: 3
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__experimentalHStack, {
spacing: 2
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__experimentalNavigatorBackButton, {
style:
// TODO: This style override is also used in ToolsPanelHeader.
// It should be supported out-of-the-box by Button.
{
minWidth: 24,
padding: 0
},
icon: (0,external_wp_i18n_namespaceObject.isRTL)() ? chevron_right : chevron_left,
isSmall: true,
"aria-label": (0,external_wp_i18n_namespaceObject.__)('Navigate to the previous view')
}), (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__experimentalSpacer, null, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__experimentalHeading, {
level: 5
}, title))))));
}
function MobileTabNavigation({
categories,
children
}) {
return (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__experimentalNavigatorProvider, {
initialPath: "/",
className: "block-editor-inserter__mobile-tab-navigation"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__experimentalNavigatorScreen, {
path: "/"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__experimentalItemGroup, null, categories.map(category => (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__experimentalNavigatorButton, {
key: category.name,
path: `/category/${category.name}`,
as: external_wp_components_namespaceObject.__experimentalItem,
isAction: true
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__experimentalHStack, null, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.FlexBlock, null, category.label), (0,external_wp_element_namespaceObject.createElement)(build_module_icon, {
icon: (0,external_wp_i18n_namespaceObject.isRTL)() ? chevron_left : chevron_right
})))))), categories.map(category => (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__experimentalNavigatorScreen, {
key: category.name,
path: `/category/${category.name}`
}, (0,external_wp_element_namespaceObject.createElement)(ScreenHeader, {
title: (0,external_wp_i18n_namespaceObject.__)('Back')
}), children(category))));
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/block-patterns-filter.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const PATTERN_TYPES = {
all: 'all',
synced: 'synced',
unsynced: 'unsynced',
user: 'user',
theme: 'theme',
directory: 'directory'
};
const SYNC_TYPES = {
all: 'all',
full: 'fully',
unsynced: 'unsynced'
};
const getShouldDisableSyncFilter = sourceFilter => sourceFilter !== PATTERN_TYPES.all && sourceFilter !== PATTERN_TYPES.user;
const getShouldDisableNonUserSources = category => {
return category.name === myPatternsCategory.name;
};
function BlockPatternsSyncFilter({
setPatternSyncFilter,
setPatternSourceFilter,
patternSyncFilter,
patternSourceFilter,
scrollContainerRef,
category
}) {
// If the category is `myPatterns` then we need to set the source filter to `user`, but
// we do this by deriving from props rather than calling setPatternSourceFilter otherwise
// the user may be confused when switching to another category if the haven't explicity set
// this filter themselves.
const currentPatternSourceFilter = category.name === myPatternsCategory.name ? PATTERN_TYPES.user : patternSourceFilter;
// We need to disable the sync filter option if the source filter is not 'all' or 'user'
// otherwise applying them will just result in no patterns being shown.
const shouldDisableSyncFilter = getShouldDisableSyncFilter(currentPatternSourceFilter);
// We also need to disable the directory and theme source filter options if the category
// is `myPatterns` otherwise applying them will also just result in no patterns being shown.
const shouldDisableNonUserSources = getShouldDisableNonUserSources(category);
const patternSyncMenuOptions = (0,external_wp_element_namespaceObject.useMemo)(() => [{
value: SYNC_TYPES.all,
label: (0,external_wp_i18n_namespaceObject._x)('All', 'Option that shows all patterns')
}, {
value: SYNC_TYPES.full,
label: (0,external_wp_i18n_namespaceObject._x)('Synced', 'Option that shows all synchronized patterns'),
disabled: shouldDisableSyncFilter
}, {
value: SYNC_TYPES.unsynced,
label: (0,external_wp_i18n_namespaceObject._x)('Not synced', 'Option that shows all patterns that are not synchronized'),
disabled: shouldDisableSyncFilter
}], [shouldDisableSyncFilter]);
const patternSourceMenuOptions = (0,external_wp_element_namespaceObject.useMemo)(() => [{
value: PATTERN_TYPES.all,
label: (0,external_wp_i18n_namespaceObject.__)('All'),
disabled: shouldDisableNonUserSources
}, {
value: PATTERN_TYPES.directory,
label: (0,external_wp_i18n_namespaceObject.__)('Pattern Directory'),
disabled: shouldDisableNonUserSources
}, {
value: PATTERN_TYPES.theme,
label: (0,external_wp_i18n_namespaceObject.__)('Theme & Plugins'),
disabled: shouldDisableNonUserSources
}, {
value: PATTERN_TYPES.user,
label: (0,external_wp_i18n_namespaceObject.__)('User')
}], [shouldDisableNonUserSources]);
function handleSetSourceFilterChange(newSourceFilter) {
setPatternSourceFilter(newSourceFilter);
if (getShouldDisableSyncFilter(newSourceFilter)) {
setPatternSyncFilter(SYNC_TYPES.all);
}
}
return (0,external_wp_element_namespaceObject.createElement)(external_wp_element_namespaceObject.Fragment, null, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.DropdownMenu, {
popoverProps: {
placement: 'right-end'
},
label: "Filter patterns",
icon: (0,external_wp_element_namespaceObject.createElement)(build_module_icon, {
icon: (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.SVG, {
width: "24",
height: "24",
viewBox: "0 0 24 24",
fill: "none",
xmlns: "http://www.w3.org/2000/svg"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.Path, {
d: "M10 17.5H14V16H10V17.5ZM6 6V7.5H18V6H6ZM8 12.5H16V11H8V12.5Z",
fill: "#1E1E1E"
}))
})
}, () => (0,external_wp_element_namespaceObject.createElement)(external_wp_element_namespaceObject.Fragment, null, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.MenuGroup, {
label: (0,external_wp_i18n_namespaceObject.__)('Source')
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.MenuItemsChoice, {
choices: patternSourceMenuOptions,
onSelect: value => {
handleSetSourceFilterChange(value);
scrollContainerRef.current?.scrollTo(0, 0);
},
value: currentPatternSourceFilter
})), (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.MenuGroup, {
label: (0,external_wp_i18n_namespaceObject.__)('Type')
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.MenuItemsChoice, {
choices: patternSyncMenuOptions,
onSelect: value => {
setPatternSyncFilter(value);
scrollContainerRef.current?.scrollTo(0, 0);
},
value: patternSyncFilter
})), (0,external_wp_element_namespaceObject.createElement)("div", {
className: "block-editor-tool-selector__help"
}, (0,external_wp_element_namespaceObject.createInterpolateElement)((0,external_wp_i18n_namespaceObject.__)('Patterns are available from the WordPress.org Pattern Directory, bundled in the active theme, or created by users on this site. Only patterns created on this site can be synced.'), {
Link: (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.ExternalLink, {
href: (0,external_wp_i18n_namespaceObject.__)('https://wordpress.org/patterns/')
})
})))));
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/block-patterns-tab.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const block_patterns_tab_noop = () => {};
const allPatternsCategory = {
name: 'allPatterns',
label: (0,external_wp_i18n_namespaceObject.__)('All patterns')
};
const myPatternsCategory = {
name: 'myPatterns',
label: (0,external_wp_i18n_namespaceObject.__)('My patterns')
};
function isPatternFiltered(pattern, sourceFilter, syncFilter) {
const isUserPattern = pattern.name.startsWith('core/block');
const isDirectoryPattern = pattern.source === 'core' || pattern.source?.startsWith('pattern-directory');
// If theme source selected, filter out user created patterns and those from
// the core patterns directory.
if (sourceFilter === PATTERN_TYPES.theme && (isUserPattern || isDirectoryPattern)) {
return true;
}
// If the directory source is selected, filter out user created patterns
// and those bundled with the theme.
if (sourceFilter === PATTERN_TYPES.directory && (isUserPattern || !isDirectoryPattern)) {
return true;
}
// If user source selected, filter out theme patterns. Any pattern without
// an id wasn't created by a user.
if (sourceFilter === PATTERN_TYPES.user && !pattern.id) {
return true;
}
// Filter by sync status.
if (syncFilter === SYNC_TYPES.full && pattern.syncStatus !== '') {
return true;
}
if (syncFilter === SYNC_TYPES.unsynced && pattern.syncStatus !== 'unsynced' && isUserPattern) {
return true;
}
return false;
}
function usePatternsCategories(rootClientId, sourceFilter = 'all') {
const [patterns, allCategories] = use_patterns_state(undefined, rootClientId);
const filteredPatterns = (0,external_wp_element_namespaceObject.useMemo)(() => sourceFilter === 'all' ? patterns : patterns.filter(pattern => !isPatternFiltered(pattern, sourceFilter)), [sourceFilter, patterns]);
const hasRegisteredCategory = (0,external_wp_element_namespaceObject.useCallback)(pattern => {
if (!pattern.categories || !pattern.categories.length) {
return false;
}
return pattern.categories.some(cat => allCategories.some(category => category.name === cat));
}, [allCategories]);
// Remove any empty categories.
const populatedCategories = (0,external_wp_element_namespaceObject.useMemo)(() => {
const categories = allCategories.filter(category => filteredPatterns.some(pattern => pattern.categories?.includes(category.name))).sort((a, b) => a.label.localeCompare(b.label));
if (filteredPatterns.some(pattern => !hasRegisteredCategory(pattern)) && !categories.find(category => category.name === 'uncategorized')) {
categories.push({
name: 'uncategorized',
label: (0,external_wp_i18n_namespaceObject._x)('Uncategorized')
});
}
if (filteredPatterns.some(pattern => pattern.id)) {
categories.unshift(myPatternsCategory);
}
if (filteredPatterns.length > 0) {
categories.unshift({
name: allPatternsCategory.name,
label: allPatternsCategory.label
});
}
(0,external_wp_a11y_namespaceObject.speak)((0,external_wp_i18n_namespaceObject.sprintf)( /* translators: %d: number of categories . */
(0,external_wp_i18n_namespaceObject._n)('%d category button displayed.', '%d category buttons displayed.', categories.length), categories.length));
return categories;
}, [allCategories, filteredPatterns, hasRegisteredCategory]);
return populatedCategories;
}
function BlockPatternsCategoryDialog({
rootClientId,
onInsert,
onHover,
category,
showTitlesAsTooltip,
patternFilter
}) {
const container = (0,external_wp_element_namespaceObject.useRef)();
(0,external_wp_element_namespaceObject.useEffect)(() => {
const timeout = setTimeout(() => {
const [firstTabbable] = external_wp_dom_namespaceObject.focus.tabbable.find(container.current);
firstTabbable?.focus();
});
return () => clearTimeout(timeout);
}, [category]);
return (0,external_wp_element_namespaceObject.createElement)("div", {
ref: container,
className: "block-editor-inserter__patterns-category-dialog"
}, (0,external_wp_element_namespaceObject.createElement)(BlockPatternsCategoryPanel, {
key: category.name,
rootClientId: rootClientId,
onInsert: onInsert,
onHover: onHover,
category: category,
showTitlesAsTooltip: showTitlesAsTooltip,
patternFilter: patternFilter
}));
}
function BlockPatternsCategoryPanel({
rootClientId,
onInsert,
onHover = block_patterns_tab_noop,
category,
showTitlesAsTooltip
}) {
const [allPatterns,, onClickPattern] = use_patterns_state(onInsert, rootClientId);
const [patternSyncFilter, setPatternSyncFilter] = (0,external_wp_element_namespaceObject.useState)('all');
const [patternSourceFilter, setPatternSourceFilter] = (0,external_wp_element_namespaceObject.useState)('all');
const availableCategories = usePatternsCategories(rootClientId, patternSourceFilter);
const scrollContainerRef = (0,external_wp_element_namespaceObject.useRef)();
const currentCategoryPatterns = (0,external_wp_element_namespaceObject.useMemo)(() => allPatterns.filter(pattern => {
var _pattern$categories$f;
if (isPatternFiltered(pattern, patternSourceFilter, patternSyncFilter)) {
return false;
}
if (category.name === allPatternsCategory.name) {
return true;
}
if (category.name === myPatternsCategory.name && pattern.id) {
return true;
}
if (category.name !== 'uncategorized') {
return pattern.categories?.includes(category.name);
}
// The uncategorized category should show all the patterns without any category
// or with no available category.
const availablePatternCategories = (_pattern$categories$f = pattern.categories?.filter(cat => availableCategories.find(availableCategory => availableCategory.name === cat))) !== null && _pattern$categories$f !== void 0 ? _pattern$categories$f : [];
return availablePatternCategories.length === 0;
}), [allPatterns, availableCategories, category.name, patternSourceFilter, patternSyncFilter]);
const pagingProps = usePatternsPaging(currentCategoryPatterns, category, scrollContainerRef);
const {
changePage
} = pagingProps;
// Hide block pattern preview on unmount.
// eslint-disable-next-line react-hooks/exhaustive-deps
(0,external_wp_element_namespaceObject.useEffect)(() => () => onHover(null), []);
const onSetPatternSyncFilter = (0,external_wp_element_namespaceObject.useCallback)(value => {
setPatternSyncFilter(value);
changePage(1);
}, [setPatternSyncFilter, changePage]);
const onSetPatternSourceFilter = (0,external_wp_element_namespaceObject.useCallback)(value => {
setPatternSourceFilter(value);
changePage(1);
}, [setPatternSourceFilter, changePage]);
return (0,external_wp_element_namespaceObject.createElement)("div", {
className: "block-editor-inserter__patterns-category-panel"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__experimentalVStack, {
spacing: 2,
className: "block-editor-inserter__patterns-category-panel-header"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__experimentalHStack, null, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.FlexBlock, null, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__experimentalHeading, {
level: 4,
as: "div"
}, category.label)), (0,external_wp_element_namespaceObject.createElement)(BlockPatternsSyncFilter, {
patternSyncFilter: patternSyncFilter,
patternSourceFilter: patternSourceFilter,
setPatternSyncFilter: onSetPatternSyncFilter,
setPatternSourceFilter: onSetPatternSourceFilter,
scrollContainerRef: scrollContainerRef,
category: category
})), !currentCategoryPatterns.length && (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__experimentalText, {
variant: "muted",
className: "block-editor-inserter__patterns-category-no-results"
}, (0,external_wp_i18n_namespaceObject.__)('No results found'))), currentCategoryPatterns.length > 0 && (0,external_wp_element_namespaceObject.createElement)(block_patterns_list, {
ref: scrollContainerRef,
shownPatterns: pagingProps.categoryPatternsAsyncList,
blockPatterns: pagingProps.categoryPatterns,
onClickPattern: onClickPattern,
onHover: onHover,
label: category.label,
orientation: "vertical",
category: category.name,
isDraggable: true,
showTitlesAsTooltip: showTitlesAsTooltip,
patternFilter: patternSourceFilter,
pagingProps: pagingProps
}));
}
function BlockPatternsTabs({
onSelectCategory,
selectedCategory,
onInsert,
rootClientId
}) {
const [showPatternsExplorer, setShowPatternsExplorer] = (0,external_wp_element_namespaceObject.useState)(false);
const categories = usePatternsCategories(rootClientId);
const initialCategory = selectedCategory || categories[0];
const isMobile = (0,external_wp_compose_namespaceObject.useViewportMatch)('medium', '<');
return (0,external_wp_element_namespaceObject.createElement)(external_wp_element_namespaceObject.Fragment, null, !isMobile && (0,external_wp_element_namespaceObject.createElement)("div", {
className: "block-editor-inserter__block-patterns-tabs-container"
}, (0,external_wp_element_namespaceObject.createElement)("nav", {
"aria-label": (0,external_wp_i18n_namespaceObject.__)('Block pattern categories'),
className: "block-editor-inserter__block-patterns-tabs"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__experimentalItemGroup, {
role: "list"
}, categories.map(category => (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__experimentalItem, {
role: "listitem",
key: category.name,
onClick: () => onSelectCategory(category),
className: category === selectedCategory ? 'block-editor-inserter__patterns-category block-editor-inserter__patterns-selected-category' : 'block-editor-inserter__patterns-category',
"aria-label": category.label,
"aria-current": category === selectedCategory ? 'true' : undefined
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__experimentalHStack, null, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.FlexBlock, null, category.label), (0,external_wp_element_namespaceObject.createElement)(build_module_icon, {
icon: (0,external_wp_i18n_namespaceObject.isRTL)() ? chevron_left : chevron_right
})))), (0,external_wp_element_namespaceObject.createElement)("div", {
role: "listitem"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.Button, {
className: "block-editor-inserter__patterns-explore-button",
onClick: () => setShowPatternsExplorer(true),
variant: "secondary"
}, (0,external_wp_i18n_namespaceObject.__)('Explore all patterns')))))), isMobile && (0,external_wp_element_namespaceObject.createElement)(MobileTabNavigation, {
categories: categories
}, category => (0,external_wp_element_namespaceObject.createElement)(BlockPatternsCategoryPanel, {
key: category.name,
onInsert: onInsert,
rootClientId: rootClientId,
category: category,
showTitlesAsTooltip: false
})), showPatternsExplorer && (0,external_wp_element_namespaceObject.createElement)(explorer, {
initialCategory: initialCategory,
patternCategories: categories,
onModalClose: () => setShowPatternsExplorer(false),
rootClientId: rootClientId
}));
}
/* harmony default export */ var block_patterns_tab = (BlockPatternsTabs);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/media-tab/hooks.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
/** @typedef {import('../../../store/actions').InserterMediaRequest} InserterMediaRequest */
/** @typedef {import('../../../store/actions').InserterMediaItem} InserterMediaItem */
/**
* Fetches media items based on the provided category.
* Each media category is responsible for providing a `fetch` function.
*
* @param {Object} category The media category to fetch results for.
* @param {InserterMediaRequest} query The query args to use for the request.
* @return {InserterMediaItem[]} The media results.
*/
function useMediaResults(category, query = {}) {
const [mediaList, setMediaList] = (0,external_wp_element_namespaceObject.useState)();
const [isLoading, setIsLoading] = (0,external_wp_element_namespaceObject.useState)(false);
// We need to keep track of the last request made because
// multiple request can be fired without knowing the order
// of resolution, and we need to ensure we are showing
// the results of the last request.
// In the future we could use AbortController to cancel previous
// requests, but we don't for now as it involves adding support
// for this to `core-data` package.
const lastRequest = (0,external_wp_element_namespaceObject.useRef)();
(0,external_wp_element_namespaceObject.useEffect)(() => {
(async () => {
const key = JSON.stringify({
category: category.name,
...query
});
lastRequest.current = key;
setIsLoading(true);
setMediaList([]); // Empty the previous results.
const _media = await category.fetch?.(query);
if (key === lastRequest.current) {
setMediaList(_media);
setIsLoading(false);
}
})();
}, [category.name, ...Object.values(query)]);
return {
mediaList,
isLoading
};
}
function useMediaCategories(rootClientId) {
const [categories, setCategories] = (0,external_wp_element_namespaceObject.useState)([]);
const inserterMediaCategories = (0,external_wp_data_namespaceObject.useSelect)(select => unlock(select(store)).getInserterMediaCategories(), []);
const {
canInsertImage,
canInsertVideo,
canInsertAudio
} = (0,external_wp_data_namespaceObject.useSelect)(select => {
const {
canInsertBlockType
} = select(store);
return {
canInsertImage: canInsertBlockType('core/image', rootClientId),
canInsertVideo: canInsertBlockType('core/video', rootClientId),
canInsertAudio: canInsertBlockType('core/audio', rootClientId)
};
}, [rootClientId]);
(0,external_wp_element_namespaceObject.useEffect)(() => {
(async () => {
const _categories = [];
// If `inserterMediaCategories` is not defined in
// block editor settings, do not show any media categories.
if (!inserterMediaCategories) {
return;
}
// Loop through categories to check if they have at least one media item.
const categoriesHaveMedia = new Map(await Promise.all(inserterMediaCategories.map(async category => {
// Some sources are external and we don't need to make a request.
if (category.isExternalResource) {
return [category.name, true];
}
let results = [];
try {
results = await category.fetch({
per_page: 1
});
} catch (e) {
// If the request fails, we shallow the error and just don't show
// the category, in order to not break the media tab.
}
return [category.name, !!results.length];
})));
// We need to filter out categories that don't have any media items or
// whose corresponding block type is not allowed to be inserted, based
// on the category's `mediaType`.
const canInsertMediaType = {
image: canInsertImage,
video: canInsertVideo,
audio: canInsertAudio
};
inserterMediaCategories.forEach(category => {
if (canInsertMediaType[category.mediaType] && categoriesHaveMedia.get(category.name)) {
_categories.push(category);
}
});
if (!!_categories.length) {
setCategories(_categories);
}
})();
}, [canInsertImage, canInsertVideo, canInsertAudio, inserterMediaCategories]);
return categories;
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/external.js
/**
* WordPress dependencies
*/
const external = (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.SVG, {
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 24 24"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.Path, {
d: "M19.5 4.5h-7V6h4.44l-5.97 5.97 1.06 1.06L18 7.06v4.44h1.5v-7Zm-13 1a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-3H17v3a.5.5 0 0 1-.5.5h-10a.5.5 0 0 1-.5-.5v-10a.5.5 0 0 1 .5-.5h3V5.5h-3Z"
}));
/* harmony default export */ var library_external = (external);
;// CONCATENATED MODULE: external ["wp","blob"]
var external_wp_blob_namespaceObject = window["wp"]["blob"];
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/media-tab/utils.js
/**
* WordPress dependencies
*/
const mediaTypeTag = {
image: 'img',
video: 'video',
audio: 'audio'
};
/** @typedef {import('./hooks').InserterMediaItem} InserterMediaItem */
/**
* Creates a block and a preview element from a media object.
*
* @param {InserterMediaItem} media The media object to create the block from.
* @param {('image'|'audio'|'video')} mediaType The media type to create the block for.
* @return {[WPBlock, JSX.Element]} An array containing the block and the preview element.
*/
function getBlockAndPreviewFromMedia(media, mediaType) {
// Add the common attributes between the different media types.
const attributes = {
id: media.id || undefined,
caption: media.caption || undefined
};
const mediaSrc = media.url;
const alt = media.alt || undefined;
if (mediaType === 'image') {
attributes.url = mediaSrc;
attributes.alt = alt;
} else if (['video', 'audio'].includes(mediaType)) {
attributes.src = mediaSrc;
}
const PreviewTag = mediaTypeTag[mediaType];
const preview = (0,external_wp_element_namespaceObject.createElement)(PreviewTag, {
src: media.previewUrl || mediaSrc,
alt: alt,
controls: mediaType === 'audio' ? true : undefined,
inert: "true",
onError: ({
currentTarget
}) => {
// Fall back to the media source if the preview cannot be loaded.
if (currentTarget.src === media.previewUrl) {
currentTarget.src = mediaSrc;
}
}
});
return [(0,external_wp_blocks_namespaceObject.createBlock)(`core/${mediaType}`, attributes), preview];
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/media-tab/media-preview.js
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const ALLOWED_MEDIA_TYPES = ['image'];
const MAXIMUM_TITLE_LENGTH = 25;
const MEDIA_OPTIONS_POPOVER_PROPS = {
position: 'bottom left',
className: 'block-editor-inserter__media-list__item-preview-options__popover'
};
function MediaPreviewOptions({
category,
media
}) {
if (!category.getReportUrl) {
return null;
}
const reportUrl = category.getReportUrl(media);
return (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.DropdownMenu, {
className: "block-editor-inserter__media-list__item-preview-options",
label: (0,external_wp_i18n_namespaceObject.__)('Options'),
popoverProps: MEDIA_OPTIONS_POPOVER_PROPS,
icon: more_vertical
}, () => (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.MenuGroup, null, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.MenuItem, {
onClick: () => window.open(reportUrl, '_blank').focus(),
icon: library_external
}, (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: %s: The media type to report e.g: "image", "video", "audio" */
(0,external_wp_i18n_namespaceObject.__)('Report %s'), category.mediaType))));
}
function InsertExternalImageModal({
onClose,
onSubmit
}) {
return (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.Modal, {
title: (0,external_wp_i18n_namespaceObject.__)('Insert external image'),
onRequestClose: onClose,
className: "block-editor-inserter-media-tab-media-preview-inserter-external-image-modal"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__experimentalVStack, {
spacing: 3
}, (0,external_wp_element_namespaceObject.createElement)("p", null, (0,external_wp_i18n_namespaceObject.__)('This image cannot be uploaded to your Media Library, but it can still be inserted as an external image.')), (0,external_wp_element_namespaceObject.createElement)("p", null, (0,external_wp_i18n_namespaceObject.__)('External images can be removed by the external provider without warning and could even have legal compliance issues related to privacy legislation.'))), (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.Flex, {
className: "block-editor-block-lock-modal__actions",
justify: "flex-end",
expanded: false
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.FlexItem, null, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.Button, {
variant: "tertiary",
onClick: onClose
}, (0,external_wp_i18n_namespaceObject.__)('Cancel'))), (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.FlexItem, null, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.Button, {
variant: "primary",
onClick: onSubmit
}, (0,external_wp_i18n_namespaceObject.__)('Insert')))));
}
function MediaPreview({
media,
onClick,
composite,
category
}) {
const [showExternalUploadModal, setShowExternalUploadModal] = (0,external_wp_element_namespaceObject.useState)(false);
const [isHovered, setIsHovered] = (0,external_wp_element_namespaceObject.useState)(false);
const [isInserting, setIsInserting] = (0,external_wp_element_namespaceObject.useState)(false);
const [block, preview] = (0,external_wp_element_namespaceObject.useMemo)(() => getBlockAndPreviewFromMedia(media, category.mediaType), [media, category.mediaType]);
const {
createErrorNotice,
createSuccessNotice
} = (0,external_wp_data_namespaceObject.useDispatch)(external_wp_notices_namespaceObject.store);
const mediaUpload = (0,external_wp_data_namespaceObject.useSelect)(select => select(store).getSettings().mediaUpload, []);
const onMediaInsert = (0,external_wp_element_namespaceObject.useCallback)(previewBlock => {
// Prevent multiple uploads when we're in the process of inserting.
if (isInserting) {
return;
}
const clonedBlock = (0,external_wp_blocks_namespaceObject.cloneBlock)(previewBlock);
const {
id,
url,
caption
} = clonedBlock.attributes;
// Media item already exists in library, so just insert it.
if (!!id) {
onClick(clonedBlock);
return;
}
setIsInserting(true);
// Media item does not exist in library, so try to upload it.
// Fist fetch the image data. This may fail if the image host
// doesn't allow CORS with the domain.
// If this happens, we insert the image block using the external
// URL and let the user know about the possible implications.
window.fetch(url).then(response => response.blob()).then(blob => {
mediaUpload({
filesList: [blob],
additionalData: {
caption
},
onFileChange([img]) {
if ((0,external_wp_blob_namespaceObject.isBlobURL)(img.url)) {
return;
}
onClick({
...clonedBlock,
attributes: {
...clonedBlock.attributes,
id: img.id,
url: img.url
}
});
createSuccessNotice((0,external_wp_i18n_namespaceObject.__)('Image uploaded and inserted.'), {
type: 'snackbar'
});
setIsInserting(false);
},
allowedTypes: ALLOWED_MEDIA_TYPES,
onError(message) {
createErrorNotice(message, {
type: 'snackbar'
});
setIsInserting(false);
}
});
}).catch(() => {
setShowExternalUploadModal(true);
setIsInserting(false);
});
}, [isInserting, onClick, mediaUpload, createErrorNotice, createSuccessNotice]);
const title = media.title?.rendered || media.title;
let truncatedTitle;
if (title.length > MAXIMUM_TITLE_LENGTH) {
const omission = '...';
truncatedTitle = title.slice(0, MAXIMUM_TITLE_LENGTH - omission.length) + omission;
}
const onMouseEnter = (0,external_wp_element_namespaceObject.useCallback)(() => setIsHovered(true), []);
const onMouseLeave = (0,external_wp_element_namespaceObject.useCallback)(() => setIsHovered(false), []);
return (0,external_wp_element_namespaceObject.createElement)(external_wp_element_namespaceObject.Fragment, null, (0,external_wp_element_namespaceObject.createElement)(inserter_draggable_blocks, {
isEnabled: true,
blocks: [block]
}, ({
draggable,
onDragStart,
onDragEnd
}) => (0,external_wp_element_namespaceObject.createElement)("div", {
className: classnames_default()('block-editor-inserter__media-list__list-item', {
'is-hovered': isHovered
}),
draggable: draggable,
onDragStart: onDragStart,
onDragEnd: onDragEnd
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.Tooltip, {
text: truncatedTitle || title
}, (0,external_wp_element_namespaceObject.createElement)("div", {
onMouseEnter: onMouseEnter,
onMouseLeave: onMouseLeave
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__unstableCompositeItem, {
role: "option",
as: "div",
...composite,
className: "block-editor-inserter__media-list__item",
onClick: () => onMediaInsert(block),
"aria-label": title
}, (0,external_wp_element_namespaceObject.createElement)("div", {
className: "block-editor-inserter__media-list__item-preview"
}, preview, isInserting && (0,external_wp_element_namespaceObject.createElement)("div", {
className: "block-editor-inserter__media-list__item-preview-spinner"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.Spinner, null)))), !isInserting && (0,external_wp_element_namespaceObject.createElement)(MediaPreviewOptions, {
category: category,
media: media
}))))), showExternalUploadModal && (0,external_wp_element_namespaceObject.createElement)(InsertExternalImageModal, {
onClose: () => setShowExternalUploadModal(false),
onSubmit: () => {
onClick((0,external_wp_blocks_namespaceObject.cloneBlock)(block));
createSuccessNotice((0,external_wp_i18n_namespaceObject.__)('Image inserted.'), {
type: 'snackbar'
});
setShowExternalUploadModal(false);
}
}));
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/media-tab/media-list.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
function MediaList({
mediaList,
category,
onClick,
label = (0,external_wp_i18n_namespaceObject.__)('Media List')
}) {
const composite = (0,external_wp_components_namespaceObject.__unstableUseCompositeState)();
return (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__unstableComposite, {
...composite,
role: "listbox",
className: "block-editor-inserter__media-list",
"aria-label": label
}, mediaList.map((media, index) => (0,external_wp_element_namespaceObject.createElement)(MediaPreview, {
key: media.id || media.sourceId || index,
media: media,
category: category,
onClick: onClick,
composite: composite
})));
}
/* harmony default export */ var media_list = (MediaList);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/hooks/use-debounced-input.js
/**
* WordPress dependencies
*/
function useDebouncedInput(defaultValue = '') {
const [input, setInput] = (0,external_wp_element_namespaceObject.useState)(defaultValue);
const [debouncedInput, setDebouncedState] = (0,external_wp_element_namespaceObject.useState)(defaultValue);
const setDebouncedInput = (0,external_wp_compose_namespaceObject.useDebounce)(setDebouncedState, 250);
(0,external_wp_element_namespaceObject.useEffect)(() => {
setDebouncedInput(input);
}, [input]);
return [input, setInput, debouncedInput];
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/no-results.js
/**
* WordPress dependencies
*/
function InserterNoResults() {
return (0,external_wp_element_namespaceObject.createElement)("div", {
className: "block-editor-inserter__no-results"
}, (0,external_wp_element_namespaceObject.createElement)(build_module_icon, {
className: "block-editor-inserter__no-results-icon",
icon: block_default
}), (0,external_wp_element_namespaceObject.createElement)("p", null, (0,external_wp_i18n_namespaceObject.__)('No results found.')));
}
/* harmony default export */ var no_results = (InserterNoResults);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/media-tab/media-panel.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const INITIAL_MEDIA_ITEMS_PER_PAGE = 10;
function MediaCategoryDialog({
rootClientId,
onInsert,
category
}) {
const container = (0,external_wp_element_namespaceObject.useRef)();
(0,external_wp_element_namespaceObject.useEffect)(() => {
const timeout = setTimeout(() => {
const [firstTabbable] = external_wp_dom_namespaceObject.focus.tabbable.find(container.current);
firstTabbable?.focus();
});
return () => clearTimeout(timeout);
}, [category]);
return (0,external_wp_element_namespaceObject.createElement)("div", {
ref: container,
className: "block-editor-inserter__media-dialog"
}, (0,external_wp_element_namespaceObject.createElement)(MediaCategoryPanel, {
rootClientId: rootClientId,
onInsert: onInsert,
category: category
}));
}
function MediaCategoryPanel({
rootClientId,
onInsert,
category
}) {
const [search, setSearch, debouncedSearch] = useDebouncedInput();
const {
mediaList,
isLoading
} = useMediaResults(category, {
per_page: !!debouncedSearch ? 20 : INITIAL_MEDIA_ITEMS_PER_PAGE,
search: debouncedSearch
});
const baseCssClass = 'block-editor-inserter__media-panel';
const searchLabel = category.labels.search_items || (0,external_wp_i18n_namespaceObject.__)('Search');
return (0,external_wp_element_namespaceObject.createElement)("div", {
className: baseCssClass
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.SearchControl, {
className: `${baseCssClass}-search`,
onChange: setSearch,
value: search,
label: searchLabel,
placeholder: searchLabel
}), isLoading && (0,external_wp_element_namespaceObject.createElement)("div", {
className: `${baseCssClass}-spinner`
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.Spinner, null)), !isLoading && !mediaList?.length && (0,external_wp_element_namespaceObject.createElement)(no_results, null), !isLoading && !!mediaList?.length && (0,external_wp_element_namespaceObject.createElement)(media_list, {
rootClientId: rootClientId,
onClick: onInsert,
mediaList: mediaList,
category: category
}));
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/media-upload/check.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
function MediaUploadCheck({
fallback = null,
children
}) {
const hasUploadPermissions = (0,external_wp_data_namespaceObject.useSelect)(select => {
const {
getSettings
} = select(store);
return !!getSettings().mediaUpload;
}, []);
return hasUploadPermissions ? children : fallback;
}
/**
* @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/media-upload/README.md
*/
/* harmony default export */ var check = (MediaUploadCheck);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/media-upload/index.js
/**
* WordPress dependencies
*/
/**
* This is a placeholder for the media upload component necessary to make it possible to provide
* an integration with the core blocks that handle media files. By default it renders nothing but
* it provides a way to have it overridden with the `editor.MediaUpload` filter.
*
* @return {WPComponent} The component to be rendered.
*/
const MediaUpload = () => null;
/**
* @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/media-upload/README.md
*/
/* harmony default export */ var media_upload = ((0,external_wp_components_namespaceObject.withFilters)('editor.MediaUpload')(MediaUpload));
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/media-tab/media-tab.js
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const media_tab_ALLOWED_MEDIA_TYPES = ['image', 'video', 'audio'];
function MediaTab({
rootClientId,
selectedCategory,
onSelectCategory,
onInsert
}) {
const mediaCategories = useMediaCategories(rootClientId);
const isMobile = (0,external_wp_compose_namespaceObject.useViewportMatch)('medium', '<');
const baseCssClass = 'block-editor-inserter__media-tabs';
const onSelectMedia = (0,external_wp_element_namespaceObject.useCallback)(media => {
if (!media?.url) {
return;
}
const [block] = getBlockAndPreviewFromMedia(media, media.type);
onInsert(block);
}, [onInsert]);
const mobileMediaCategories = (0,external_wp_element_namespaceObject.useMemo)(() => mediaCategories.map(mediaCategory => ({
...mediaCategory,
label: mediaCategory.labels.name
})), [mediaCategories]);
return (0,external_wp_element_namespaceObject.createElement)(external_wp_element_namespaceObject.Fragment, null, !isMobile && (0,external_wp_element_namespaceObject.createElement)("div", {
className: `${baseCssClass}-container`
}, (0,external_wp_element_namespaceObject.createElement)("nav", {
"aria-label": (0,external_wp_i18n_namespaceObject.__)('Media categories')
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__experimentalItemGroup, {
role: "list",
className: baseCssClass
}, mediaCategories.map(mediaCategory => (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__experimentalItem, {
role: "listitem",
key: mediaCategory.name,
onClick: () => onSelectCategory(mediaCategory),
className: classnames_default()(`${baseCssClass}__media-category`, {
'is-selected': selectedCategory === mediaCategory
}),
"aria-label": mediaCategory.labels.name,
"aria-current": mediaCategory === selectedCategory ? 'true' : undefined
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__experimentalHStack, null, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.FlexBlock, null, mediaCategory.labels.name), (0,external_wp_element_namespaceObject.createElement)(build_module_icon, {
icon: (0,external_wp_i18n_namespaceObject.isRTL)() ? chevron_left : chevron_right
})))), (0,external_wp_element_namespaceObject.createElement)("div", {
role: "listitem"
}, (0,external_wp_element_namespaceObject.createElement)(check, null, (0,external_wp_element_namespaceObject.createElement)(media_upload, {
multiple: false,
onSelect: onSelectMedia,
allowedTypes: media_tab_ALLOWED_MEDIA_TYPES,
render: ({
open
}) => (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.Button, {
onClick: event => {
// Safari doesn't emit a focus event on button elements when
// clicked and we need to manually focus the button here.
// The reason is that core's Media Library modal explicitly triggers a
// focus event and therefore a `blur` event is triggered on a different
// element, which doesn't contain the `data-unstable-ignore-focus-outside-for-relatedtarget`
// attribute making the Inserter dialog to close.
event.target.focus();
open();
},
className: "block-editor-inserter__media-library-button",
variant: "secondary",
"data-unstable-ignore-focus-outside-for-relatedtarget": ".media-modal"
}, (0,external_wp_i18n_namespaceObject.__)('Open Media Library'))
})))))), isMobile && (0,external_wp_element_namespaceObject.createElement)(MobileTabNavigation, {
categories: mobileMediaCategories
}, category => (0,external_wp_element_namespaceObject.createElement)(MediaCategoryPanel, {
onInsert: onInsert,
rootClientId: rootClientId,
category: category
})));
}
/* harmony default export */ var media_tab = (MediaTab);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter-menu-extension/index.js
/**
* WordPress dependencies
*/
const {
Fill: __unstableInserterMenuExtension,
Slot
} = (0,external_wp_components_namespaceObject.createSlotFill)('__unstableInserterMenuExtension');
__unstableInserterMenuExtension.Slot = Slot;
/* harmony default export */ var inserter_menu_extension = (__unstableInserterMenuExtension);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/utils/order-inserter-block-items.js
/** @typedef {import('../store/selectors').WPEditorInserterItem} WPEditorInserterItem */
/**
* Helper function to order inserter block items according to a provided array of prioritized blocks.
*
* @param {WPEditorInserterItem[]} items The array of editor inserter block items to be sorted.
* @param {string[]} priority The array of block names to be prioritized.
* @return {WPEditorInserterItem[]} The sorted array of editor inserter block items.
*/
const orderInserterBlockItems = (items, priority) => {
if (!priority) {
return items;
}
items.sort(({
id: aName
}, {
id: bName
}) => {
// Sort block items according to `priority`.
let aIndex = priority.indexOf(aName);
let bIndex = priority.indexOf(bName);
// All other block items should come after that.
if (aIndex < 0) aIndex = priority.length;
if (bIndex < 0) bIndex = priority.length;
return aIndex - bIndex;
});
return items;
};
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/search-results.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const search_results_INITIAL_INSERTER_RESULTS = 9;
/**
* Shared reference to an empty array for cases where it is important to avoid
* returning a new array reference on every invocation and rerendering the component.
*
* @type {Array}
*/
const search_results_EMPTY_ARRAY = [];
function InserterSearchResults({
filterValue,
onSelect,
onHover,
onHoverPattern,
rootClientId,
clientId,
isAppender,
__experimentalInsertionIndex,
maxBlockPatterns,
maxBlockTypes,
showBlockDirectory = false,
isDraggable = true,
shouldFocusBlock = true,
prioritizePatterns,
selectBlockOnInsert
}) {
const debouncedSpeak = (0,external_wp_compose_namespaceObject.useDebounce)(external_wp_a11y_namespaceObject.speak, 500);
const {
prioritizedBlocks
} = (0,external_wp_data_namespaceObject.useSelect)(select => {
const blockListSettings = select(store).getBlockListSettings(rootClientId);
return {
prioritizedBlocks: blockListSettings?.prioritizedInserterBlocks || search_results_EMPTY_ARRAY
};
}, [rootClientId]);
const [destinationRootClientId, onInsertBlocks] = use_insertion_point({
onSelect,
rootClientId,
clientId,
isAppender,
insertionIndex: __experimentalInsertionIndex,
shouldFocusBlock,
selectBlockOnInsert
});
const [blockTypes, blockTypeCategories, blockTypeCollections, onSelectBlockType] = use_block_types_state(destinationRootClientId, onInsertBlocks);
const [patterns,, onClickPattern] = use_patterns_state(onInsertBlocks, destinationRootClientId);
const filteredBlockPatterns = (0,external_wp_element_namespaceObject.useMemo)(() => {
if (maxBlockPatterns === 0) {
return [];
}
const results = searchItems(patterns, filterValue);
return maxBlockPatterns !== undefined ? results.slice(0, maxBlockPatterns) : results;
}, [filterValue, patterns, maxBlockPatterns]);
let maxBlockTypesToShow = maxBlockTypes;
if (prioritizePatterns && filteredBlockPatterns.length > 2) {
maxBlockTypesToShow = 0;
}
const filteredBlockTypes = (0,external_wp_element_namespaceObject.useMemo)(() => {
if (maxBlockTypesToShow === 0) {
return [];
}
const nonPatternBlockTypes = blockTypes.filter(blockType => blockType.name !== 'core/block');
let orderedItems = orderBy(nonPatternBlockTypes, 'frecency', 'desc');
if (!filterValue && prioritizedBlocks.length) {
orderedItems = orderInserterBlockItems(orderedItems, prioritizedBlocks);
}
const results = searchBlockItems(orderedItems, blockTypeCategories, blockTypeCollections, filterValue);
return maxBlockTypesToShow !== undefined ? results.slice(0, maxBlockTypesToShow) : results;
}, [filterValue, blockTypes, blockTypeCategories, blockTypeCollections, maxBlockTypesToShow, prioritizedBlocks]);
// Announce search results on change.
(0,external_wp_element_namespaceObject.useEffect)(() => {
if (!filterValue) {
return;
}
const count = filteredBlockTypes.length + filteredBlockPatterns.length;
const resultsFoundMessage = (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: %d: number of results. */
(0,external_wp_i18n_namespaceObject._n)('%d result found.', '%d results found.', count), count);
debouncedSpeak(resultsFoundMessage);
}, [filterValue, debouncedSpeak, filteredBlockTypes, filteredBlockPatterns]);
const currentShownBlockTypes = (0,external_wp_compose_namespaceObject.useAsyncList)(filteredBlockTypes, {
step: search_results_INITIAL_INSERTER_RESULTS
});
const currentShownPatterns = (0,external_wp_compose_namespaceObject.useAsyncList)(currentShownBlockTypes.length === filteredBlockTypes.length ? filteredBlockPatterns : search_results_EMPTY_ARRAY);
const hasItems = filteredBlockTypes.length > 0 || filteredBlockPatterns.length > 0;
const blocksUI = !!filteredBlockTypes.length && (0,external_wp_element_namespaceObject.createElement)(panel, {
title: (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.VisuallyHidden, null, (0,external_wp_i18n_namespaceObject.__)('Blocks'))
}, (0,external_wp_element_namespaceObject.createElement)(block_types_list, {
items: currentShownBlockTypes,
onSelect: onSelectBlockType,
onHover: onHover,
label: (0,external_wp_i18n_namespaceObject.__)('Blocks'),
isDraggable: isDraggable
}));
const patternsUI = !!filteredBlockPatterns.length && (0,external_wp_element_namespaceObject.createElement)(panel, {
title: (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.VisuallyHidden, null, (0,external_wp_i18n_namespaceObject.__)('Block patterns'))
}, (0,external_wp_element_namespaceObject.createElement)("div", {
className: "block-editor-inserter__quick-inserter-patterns"
}, (0,external_wp_element_namespaceObject.createElement)(block_patterns_list, {
shownPatterns: currentShownPatterns,
blockPatterns: filteredBlockPatterns,
onClickPattern: onClickPattern,
onHover: onHoverPattern,
isDraggable: isDraggable
})));
return (0,external_wp_element_namespaceObject.createElement)(inserter_listbox, null, !showBlockDirectory && !hasItems && (0,external_wp_element_namespaceObject.createElement)(no_results, null), prioritizePatterns ? patternsUI : blocksUI, !!filteredBlockTypes.length && !!filteredBlockPatterns.length && (0,external_wp_element_namespaceObject.createElement)("div", {
className: "block-editor-inserter__quick-inserter-separator"
}), prioritizePatterns ? blocksUI : patternsUI, showBlockDirectory && (0,external_wp_element_namespaceObject.createElement)(inserter_menu_extension.Slot, {
fillProps: {
onSelect: onSelectBlockType,
onHover,
filterValue,
hasItems,
rootClientId: destinationRootClientId
}
}, fills => {
if (fills.length) {
return fills;
}
if (!hasItems) {
return (0,external_wp_element_namespaceObject.createElement)(no_results, null);
}
return null;
}));
}
/* harmony default export */ var search_results = (InserterSearchResults);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/tabs.js
/**
* WordPress dependencies
*/
const blocksTab = {
name: 'blocks',
/* translators: Blocks tab title in the block inserter. */
title: (0,external_wp_i18n_namespaceObject.__)('Blocks')
};
const patternsTab = {
name: 'patterns',
/* translators: Theme and Directory Patterns tab title in the block inserter. */
title: (0,external_wp_i18n_namespaceObject.__)('Patterns')
};
const mediaTab = {
name: 'media',
/* translators: Media tab title in the block inserter. */
title: (0,external_wp_i18n_namespaceObject.__)('Media')
};
function InserterTabs({
children,
showPatterns = false,
showMedia = false,
onSelect,
prioritizePatterns
}) {
const tabs = (0,external_wp_element_namespaceObject.useMemo)(() => {
const tempTabs = [];
if (prioritizePatterns && showPatterns) {
tempTabs.push(patternsTab);
}
tempTabs.push(blocksTab);
if (!prioritizePatterns && showPatterns) {
tempTabs.push(patternsTab);
}
if (showMedia) {
tempTabs.push(mediaTab);
}
return tempTabs;
}, [prioritizePatterns, showPatterns, showMedia]);
return (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.TabPanel, {
className: "block-editor-inserter__tabs",
tabs: tabs,
onSelect: onSelect
}, children);
}
/* harmony default export */ var tabs = (InserterTabs);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/menu.js
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
function InserterMenu({
rootClientId,
clientId,
isAppender,
__experimentalInsertionIndex,
onSelect,
showInserterHelpPanel,
showMostUsedBlocks,
__experimentalFilterValue = '',
shouldFocusBlock = true,
prioritizePatterns
}, ref) {
const [filterValue, setFilterValue, delayedFilterValue] = useDebouncedInput(__experimentalFilterValue);
const [hoveredItem, setHoveredItem] = (0,external_wp_element_namespaceObject.useState)(null);
const [selectedPatternCategory, setSelectedPatternCategory] = (0,external_wp_element_namespaceObject.useState)(null);
const [patternFilter, setPatternFilter] = (0,external_wp_element_namespaceObject.useState)('all');
const [selectedMediaCategory, setSelectedMediaCategory] = (0,external_wp_element_namespaceObject.useState)(null);
const [selectedTab, setSelectedTab] = (0,external_wp_element_namespaceObject.useState)(null);
const [destinationRootClientId, onInsertBlocks, onToggleInsertionPoint] = use_insertion_point({
rootClientId,
clientId,
isAppender,
insertionIndex: __experimentalInsertionIndex,
shouldFocusBlock
});
const {
showPatterns,
inserterItems
} = (0,external_wp_data_namespaceObject.useSelect)(select => {
const {
__experimentalGetAllowedPatterns,
getInserterItems
} = select(store);
return {
showPatterns: !!__experimentalGetAllowedPatterns(destinationRootClientId).length,
inserterItems: getInserterItems(destinationRootClientId)
};
}, [destinationRootClientId]);
const hasReusableBlocks = (0,external_wp_element_namespaceObject.useMemo)(() => {
return inserterItems.some(({
category
}) => category === 'reusable');
}, [inserterItems]);
const mediaCategories = useMediaCategories(destinationRootClientId);
const showMedia = !!mediaCategories.length;
const onInsert = (0,external_wp_element_namespaceObject.useCallback)((blocks, meta, shouldForceFocusBlock) => {
onInsertBlocks(blocks, meta, shouldForceFocusBlock);
onSelect();
}, [onInsertBlocks, onSelect]);
const onInsertPattern = (0,external_wp_element_namespaceObject.useCallback)((blocks, patternName) => {
onInsertBlocks(blocks, {
patternName
});
onSelect();
}, [onInsertBlocks, onSelect]);
const onHover = (0,external_wp_element_namespaceObject.useCallback)(item => {
onToggleInsertionPoint(!!item);
setHoveredItem(item);
}, [onToggleInsertionPoint, setHoveredItem]);
const onHoverPattern = (0,external_wp_element_namespaceObject.useCallback)(item => {
onToggleInsertionPoint(!!item);
}, [onToggleInsertionPoint]);
const onClickPatternCategory = (0,external_wp_element_namespaceObject.useCallback)((patternCategory, filter) => {
setSelectedPatternCategory(patternCategory);
setPatternFilter(filter);
}, [setSelectedPatternCategory]);
const blocksTab = (0,external_wp_element_namespaceObject.useMemo)(() => (0,external_wp_element_namespaceObject.createElement)(external_wp_element_namespaceObject.Fragment, null, (0,external_wp_element_namespaceObject.createElement)("div", {
className: "block-editor-inserter__block-list"
}, (0,external_wp_element_namespaceObject.createElement)(block_types_tab, {
rootClientId: destinationRootClientId,
onInsert: onInsert,
onHover: onHover,
showMostUsedBlocks: showMostUsedBlocks
})), showInserterHelpPanel && (0,external_wp_element_namespaceObject.createElement)("div", {
className: "block-editor-inserter__tips"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.VisuallyHidden, {
as: "h2"
}, (0,external_wp_i18n_namespaceObject.__)('A tip for using the block editor')), (0,external_wp_element_namespaceObject.createElement)(tips, null))), [destinationRootClientId, onInsert, onHover, showMostUsedBlocks, showInserterHelpPanel]);
const patternsTab = (0,external_wp_element_namespaceObject.useMemo)(() => (0,external_wp_element_namespaceObject.createElement)(block_patterns_tab, {
rootClientId: destinationRootClientId,
onInsert: onInsertPattern,
onSelectCategory: onClickPatternCategory,
selectedCategory: selectedPatternCategory
}), [destinationRootClientId, onInsertPattern, onClickPatternCategory, selectedPatternCategory]);
const mediaTab = (0,external_wp_element_namespaceObject.useMemo)(() => (0,external_wp_element_namespaceObject.createElement)(media_tab, {
rootClientId: destinationRootClientId,
selectedCategory: selectedMediaCategory,
onSelectCategory: setSelectedMediaCategory,
onInsert: onInsert
}), [destinationRootClientId, onInsert, selectedMediaCategory, setSelectedMediaCategory]);
const getCurrentTab = (0,external_wp_element_namespaceObject.useCallback)(tab => {
if (tab.name === 'blocks') {
return blocksTab;
} else if (tab.name === 'patterns') {
return patternsTab;
} else if (tab.name === 'media') {
return mediaTab;
}
}, [blocksTab, patternsTab, mediaTab]);
const searchRef = (0,external_wp_element_namespaceObject.useRef)();
(0,external_wp_element_namespaceObject.useImperativeHandle)(ref, () => ({
focusSearch: () => {
searchRef.current.focus();
}
}));
const showPatternPanel = selectedTab === 'patterns' && !delayedFilterValue && selectedPatternCategory;
const showAsTabs = !delayedFilterValue && (showPatterns || hasReusableBlocks || showMedia);
const showMediaPanel = selectedTab === 'media' && !delayedFilterValue && selectedMediaCategory;
const handleSetSelectedTab = value => {
// If no longer on patterns tab remove the category setting.
if (value !== 'patterns') {
setSelectedPatternCategory(null);
}
setSelectedTab(value);
};
return (0,external_wp_element_namespaceObject.createElement)("div", {
className: "block-editor-inserter__menu"
}, (0,external_wp_element_namespaceObject.createElement)("div", {
className: classnames_default()('block-editor-inserter__main-area', {
'show-as-tabs': showAsTabs
})
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.SearchControl, {
__nextHasNoMarginBottom: true,
className: "block-editor-inserter__search",
onChange: value => {
if (hoveredItem) setHoveredItem(null);
setFilterValue(value);
},
value: filterValue,
label: (0,external_wp_i18n_namespaceObject.__)('Search for blocks and patterns'),
placeholder: (0,external_wp_i18n_namespaceObject.__)('Search'),
ref: searchRef
}), !!delayedFilterValue && (0,external_wp_element_namespaceObject.createElement)("div", {
className: "block-editor-inserter__no-tab-container"
}, (0,external_wp_element_namespaceObject.createElement)(search_results, {
filterValue: delayedFilterValue,
onSelect: onSelect,
onHover: onHover,
onHoverPattern: onHoverPattern,
rootClientId: rootClientId,
clientId: clientId,
isAppender: isAppender,
__experimentalInsertionIndex: __experimentalInsertionIndex,
showBlockDirectory: true,
shouldFocusBlock: shouldFocusBlock
})), showAsTabs && (0,external_wp_element_namespaceObject.createElement)(tabs, {
showPatterns: showPatterns,
showReusableBlocks: hasReusableBlocks,
showMedia: showMedia,
prioritizePatterns: prioritizePatterns,
onSelect: handleSetSelectedTab
}, getCurrentTab), !delayedFilterValue && !showAsTabs && (0,external_wp_element_namespaceObject.createElement)("div", {
className: "block-editor-inserter__no-tab-container"
}, blocksTab)), showMediaPanel && (0,external_wp_element_namespaceObject.createElement)(MediaCategoryDialog, {
rootClientId: destinationRootClientId,
onInsert: onInsert,
category: selectedMediaCategory
}), showInserterHelpPanel && hoveredItem && (0,external_wp_element_namespaceObject.createElement)(preview_panel, {
item: hoveredItem
}), showPatternPanel && (0,external_wp_element_namespaceObject.createElement)(BlockPatternsCategoryDialog, {
rootClientId: destinationRootClientId,
onInsert: onInsertPattern,
onHover: onHoverPattern,
category: selectedPatternCategory,
patternFilter: patternFilter,
showTitlesAsTooltip: true
}));
}
/* harmony default export */ var menu = ((0,external_wp_element_namespaceObject.forwardRef)(InserterMenu));
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/quick-inserter.js
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const SEARCH_THRESHOLD = 6;
const SHOWN_BLOCK_TYPES = 6;
const SHOWN_BLOCK_PATTERNS = 2;
const SHOWN_BLOCK_PATTERNS_WITH_PRIORITIZATION = 4;
function QuickInserter({
onSelect,
rootClientId,
clientId,
isAppender,
prioritizePatterns,
selectBlockOnInsert
}) {
const [filterValue, setFilterValue] = (0,external_wp_element_namespaceObject.useState)('');
const [destinationRootClientId, onInsertBlocks] = use_insertion_point({
onSelect,
rootClientId,
clientId,
isAppender,
selectBlockOnInsert
});
const [blockTypes] = use_block_types_state(destinationRootClientId, onInsertBlocks);
const [patterns] = use_patterns_state(onInsertBlocks, destinationRootClientId);
const {
setInserterIsOpened,
insertionIndex
} = (0,external_wp_data_namespaceObject.useSelect)(select => {
const {
getSettings,
getBlockIndex,
getBlockCount
} = select(store);
const settings = getSettings();
const index = getBlockIndex(clientId);
const blockCount = getBlockCount();
return {
setInserterIsOpened: settings.__experimentalSetIsInserterOpened,
insertionIndex: index === -1 ? blockCount : index
};
}, [clientId]);
const showPatterns = patterns.length && (!!filterValue || prioritizePatterns);
const showSearch = showPatterns && patterns.length > SEARCH_THRESHOLD || blockTypes.length > SEARCH_THRESHOLD;
(0,external_wp_element_namespaceObject.useEffect)(() => {
if (setInserterIsOpened) {
setInserterIsOpened(false);
}
}, [setInserterIsOpened]);
// When clicking Browse All select the appropriate block so as
// the insertion point can work as expected.
const onBrowseAll = () => {
setInserterIsOpened({
rootClientId,
insertionIndex,
filterValue
});
};
let maxBlockPatterns = 0;
if (showPatterns) {
maxBlockPatterns = prioritizePatterns ? SHOWN_BLOCK_PATTERNS_WITH_PRIORITIZATION : SHOWN_BLOCK_PATTERNS;
}
return (0,external_wp_element_namespaceObject.createElement)("div", {
className: classnames_default()('block-editor-inserter__quick-inserter', {
'has-search': showSearch,
'has-expand': setInserterIsOpened
})
}, showSearch && (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.SearchControl, {
__nextHasNoMarginBottom: true,
className: "block-editor-inserter__search",
value: filterValue,
onChange: value => {
setFilterValue(value);
},
label: (0,external_wp_i18n_namespaceObject.__)('Search for blocks and patterns'),
placeholder: (0,external_wp_i18n_namespaceObject.__)('Search')
}), (0,external_wp_element_namespaceObject.createElement)("div", {
className: "block-editor-inserter__quick-inserter-results"
}, (0,external_wp_element_namespaceObject.createElement)(search_results, {
filterValue: filterValue,
onSelect: onSelect,
rootClientId: rootClientId,
clientId: clientId,
isAppender: isAppender,
maxBlockPatterns: maxBlockPatterns,
maxBlockTypes: SHOWN_BLOCK_TYPES,
isDraggable: false,
prioritizePatterns: prioritizePatterns,
selectBlockOnInsert: selectBlockOnInsert
})), setInserterIsOpened && (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.Button, {
className: "block-editor-inserter__quick-inserter-expand",
onClick: onBrowseAll,
"aria-label": (0,external_wp_i18n_namespaceObject.__)('Browse all. This will open the main inserter panel in the editor toolbar.')
}, (0,external_wp_i18n_namespaceObject.__)('Browse all')));
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inserter/index.js
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const defaultRenderToggle = ({
onToggle,
disabled,
isOpen,
blockTitle,
hasSingleBlockType,
toggleProps = {},
prioritizePatterns
}) => {
const {
as: Wrapper = external_wp_components_namespaceObject.Button,
label: labelProp,
onClick,
...rest
} = toggleProps;
let label = labelProp;
if (!label && hasSingleBlockType) {
label = (0,external_wp_i18n_namespaceObject.sprintf)(
// translators: %s: the name of the block when there is only one
(0,external_wp_i18n_namespaceObject._x)('Add %s', 'directly add the only allowed block'), blockTitle);
} else if (!label && prioritizePatterns) {
label = (0,external_wp_i18n_namespaceObject.__)('Add pattern');
} else if (!label) {
label = (0,external_wp_i18n_namespaceObject._x)('Add block', 'Generic label for block inserter button');
}
// Handle both onClick functions from the toggle and the parent component.
function handleClick(event) {
if (onToggle) {
onToggle(event);
}
if (onClick) {
onClick(event);
}
}
return (0,external_wp_element_namespaceObject.createElement)(Wrapper, {
icon: library_plus,
label: label,
tooltipPosition: "bottom",
onClick: handleClick,
className: "block-editor-inserter__toggle",
"aria-haspopup": !hasSingleBlockType ? 'true' : false,
"aria-expanded": !hasSingleBlockType ? isOpen : false,
disabled: disabled,
...rest
});
};
class PrivateInserter extends external_wp_element_namespaceObject.Component {
constructor() {
super(...arguments);
this.onToggle = this.onToggle.bind(this);
this.renderToggle = this.renderToggle.bind(this);
this.renderContent = this.renderContent.bind(this);
}
onToggle(isOpen) {
const {
onToggle
} = this.props;
// Surface toggle callback to parent component.
if (onToggle) {
onToggle(isOpen);
}
}
/**
* Render callback to display Dropdown toggle element.
*
* @param {Object} options
* @param {Function} options.onToggle Callback to invoke when toggle is
* pressed.
* @param {boolean} options.isOpen Whether dropdown is currently open.
*
* @return {WPElement} Dropdown toggle element.
*/
renderToggle({
onToggle,
isOpen
}) {
const {
disabled,
blockTitle,
hasSingleBlockType,
directInsertBlock,
toggleProps,
hasItems,
renderToggle = defaultRenderToggle,
prioritizePatterns
} = this.props;
return renderToggle({
onToggle,
isOpen,
disabled: disabled || !hasItems,
blockTitle,
hasSingleBlockType,
directInsertBlock,
toggleProps,
prioritizePatterns
});
}
/**
* Render callback to display Dropdown content element.
*
* @param {Object} options
* @param {Function} options.onClose Callback to invoke when dropdown is
* closed.
*
* @return {WPElement} Dropdown content element.
*/
renderContent({
onClose
}) {
const {
rootClientId,
clientId,
isAppender,
showInserterHelpPanel,
// This prop is experimental to give some time for the quick inserter to mature
// Feel free to make them stable after a few releases.
__experimentalIsQuick: isQuick,
prioritizePatterns,
onSelectOrClose,
selectBlockOnInsert
} = this.props;
if (isQuick) {
return (0,external_wp_element_namespaceObject.createElement)(QuickInserter, {
onSelect: blocks => {
const firstBlock = Array.isArray(blocks) && blocks?.length ? blocks[0] : blocks;
if (onSelectOrClose && typeof onSelectOrClose === 'function') {
onSelectOrClose(firstBlock);
}
onClose();
},
rootClientId: rootClientId,
clientId: clientId,
isAppender: isAppender,
prioritizePatterns: prioritizePatterns,
selectBlockOnInsert: selectBlockOnInsert
});
}
return (0,external_wp_element_namespaceObject.createElement)(menu, {
onSelect: () => {
onClose();
},
rootClientId: rootClientId,
clientId: clientId,
isAppender: isAppender,
showInserterHelpPanel: showInserterHelpPanel,
prioritizePatterns: prioritizePatterns
});
}
render() {
const {
position,
hasSingleBlockType,
directInsertBlock,
insertOnlyAllowedBlock,
__experimentalIsQuick: isQuick,
onSelectOrClose
} = this.props;
if (hasSingleBlockType || directInsertBlock) {
return this.renderToggle({
onToggle: insertOnlyAllowedBlock
});
}
return (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.Dropdown, {
className: "block-editor-inserter",
contentClassName: classnames_default()('block-editor-inserter__popover', {
'is-quick': isQuick
}),
popoverProps: {
position,
shift: true
},
onToggle: this.onToggle,
expandOnMobile: true,
headerTitle: (0,external_wp_i18n_namespaceObject.__)('Add a block'),
renderToggle: this.renderToggle,
renderContent: this.renderContent,
onClose: onSelectOrClose
});
}
}
const ComposedPrivateInserter = (0,external_wp_compose_namespaceObject.compose)([(0,external_wp_data_namespaceObject.withSelect)((select, {
clientId,
rootClientId,
shouldDirectInsert = true
}) => {
const {
getBlockRootClientId,
hasInserterItems,
getAllowedBlocks,
getDirectInsertBlock,
getSettings
} = select(store);
const {
getBlockVariations
} = select(external_wp_blocks_namespaceObject.store);
rootClientId = rootClientId || getBlockRootClientId(clientId) || undefined;
const allowedBlocks = getAllowedBlocks(rootClientId);
const directInsertBlock = shouldDirectInsert && getDirectInsertBlock(rootClientId);
const settings = getSettings();
const hasSingleBlockType = allowedBlocks?.length === 1 && getBlockVariations(allowedBlocks[0].name, 'inserter')?.length === 0;
let allowedBlockType = false;
if (hasSingleBlockType) {
allowedBlockType = allowedBlocks[0];
}
return {
hasItems: hasInserterItems(rootClientId),
hasSingleBlockType,
blockTitle: allowedBlockType ? allowedBlockType.title : '',
allowedBlockType,
directInsertBlock,
rootClientId,
prioritizePatterns: settings.__experimentalPreferPatternsOnRoot && !rootClientId
};
}), (0,external_wp_data_namespaceObject.withDispatch)((dispatch, ownProps, {
select
}) => {
return {
insertOnlyAllowedBlock() {
const {
rootClientId,
clientId,
isAppender,
hasSingleBlockType,
allowedBlockType,
directInsertBlock,
onSelectOrClose,
selectBlockOnInsert
} = ownProps;
if (!hasSingleBlockType && !directInsertBlock) {
return;
}
function getAdjacentBlockAttributes(attributesToCopy) {
const {
getBlock,
getPreviousBlockClientId
} = select(store);
if (!attributesToCopy || !clientId && !rootClientId) {
return {};
}
const result = {};
let adjacentAttributes = {};
// If there is no clientId, then attempt to get attributes
// from the last block within innerBlocks of the root block.
if (!clientId) {
const parentBlock = getBlock(rootClientId);
if (parentBlock?.innerBlocks?.length) {
const lastInnerBlock = parentBlock.innerBlocks[parentBlock.innerBlocks.length - 1];
if (directInsertBlock && directInsertBlock?.name === lastInnerBlock.name) {
adjacentAttributes = lastInnerBlock.attributes;
}
}
} else {
// Otherwise, attempt to get attributes from the
// previous block relative to the current clientId.
const currentBlock = getBlock(clientId);
const previousBlock = getBlock(getPreviousBlockClientId(clientId));
if (currentBlock?.name === previousBlock?.name) {
adjacentAttributes = previousBlock?.attributes || {};
}
}
// Copy over only those attributes flagged to be copied.
attributesToCopy.forEach(attribute => {
if (adjacentAttributes.hasOwnProperty(attribute)) {
result[attribute] = adjacentAttributes[attribute];
}
});
return result;
}
function getInsertionIndex() {
const {
getBlockIndex,
getBlockSelectionEnd,
getBlockOrder,
getBlockRootClientId
} = select(store);
// If the clientId is defined, we insert at the position of the block.
if (clientId) {
return getBlockIndex(clientId);
}
// If there a selected block, we insert after the selected block.
const end = getBlockSelectionEnd();
if (!isAppender && end && getBlockRootClientId(end) === rootClientId) {
return getBlockIndex(end) + 1;
}
// Otherwise, we insert at the end of the current rootClientId.
return getBlockOrder(rootClientId).length;
}
const {
insertBlock
} = dispatch(store);
let blockToInsert;
// Attempt to augment the directInsertBlock with attributes from an adjacent block.
// This ensures styling from nearby blocks is preserved in the newly inserted block.
// See: https://github.com/WordPress/gutenberg/issues/37904
if (directInsertBlock) {
const newAttributes = getAdjacentBlockAttributes(directInsertBlock.attributesToCopy);
blockToInsert = (0,external_wp_blocks_namespaceObject.createBlock)(directInsertBlock.name, {
...(directInsertBlock.attributes || {}),
...newAttributes
});
} else {
blockToInsert = (0,external_wp_blocks_namespaceObject.createBlock)(allowedBlockType.name);
}
insertBlock(blockToInsert, getInsertionIndex(), rootClientId, selectBlockOnInsert);
if (onSelectOrClose) {
onSelectOrClose({
clientId: blockToInsert?.clientId
});
}
const message = (0,external_wp_i18n_namespaceObject.sprintf)(
// translators: %s: the name of the block that has been added
(0,external_wp_i18n_namespaceObject.__)('%s block added'), allowedBlockType.title);
(0,external_wp_a11y_namespaceObject.speak)(message);
}
};
}),
// The global inserter should always be visible, we are using ( ! isAppender && ! rootClientId && ! clientId ) as
// a way to detect the global Inserter.
(0,external_wp_compose_namespaceObject.ifCondition)(({
hasItems,
isAppender,
rootClientId,
clientId
}) => hasItems || !isAppender && !rootClientId && !clientId)])(PrivateInserter);
const Inserter = (0,external_wp_element_namespaceObject.forwardRef)((props, ref) => {
return (0,external_wp_element_namespaceObject.createElement)(ComposedPrivateInserter, {
ref: ref,
...props
});
});
/* harmony default export */ var inserter = (Inserter);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/default-block-appender/index.js
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
/**
* Zero width non-breaking space, used as padding for the paragraph when it is
* empty.
*/
const ZWNBSP = '\ufeff';
function DefaultBlockAppender({
isLocked,
onAppend,
showPrompt,
placeholder,
rootClientId
}) {
if (isLocked) {
return null;
}
const value = (0,external_wp_htmlEntities_namespaceObject.decodeEntities)(placeholder) || (0,external_wp_i18n_namespaceObject.__)('Type / to choose a block');
return (0,external_wp_element_namespaceObject.createElement)("div", {
"data-root-client-id": rootClientId || '',
className: classnames_default()('block-editor-default-block-appender', {
'has-visible-prompt': showPrompt
})
}, (0,external_wp_element_namespaceObject.createElement)("p", {
tabIndex: "0"
// We want this element to be styled as a paragraph by themes.
// eslint-disable-next-line jsx-a11y/no-noninteractive-element-to-interactive-role
,
role: "button",
"aria-label": (0,external_wp_i18n_namespaceObject.__)('Add default block')
// A wrapping container for this one already has the wp-block className.
,
className: "block-editor-default-block-appender__content",
onKeyDown: event => {
if (external_wp_keycodes_namespaceObject.ENTER === event.keyCode || external_wp_keycodes_namespaceObject.SPACE === event.keyCode) {
onAppend();
}
},
onClick: () => onAppend(),
onFocus: () => {
if (showPrompt) {
onAppend();
}
}
}, showPrompt ? value : ZWNBSP), (0,external_wp_element_namespaceObject.createElement)(inserter, {
rootClientId: rootClientId,
position: "bottom right",
isAppender: true,
__experimentalIsQuick: true
}));
}
/* harmony default export */ var default_block_appender = ((0,external_wp_compose_namespaceObject.compose)((0,external_wp_data_namespaceObject.withSelect)((select, ownProps) => {
const {
getBlockCount,
getSettings,
getTemplateLock
} = select(store);
const isEmpty = !getBlockCount(ownProps.rootClientId);
const {
bodyPlaceholder
} = getSettings();
return {
showPrompt: isEmpty,
isLocked: !!getTemplateLock(ownProps.rootClientId),
placeholder: bodyPlaceholder
};
}), (0,external_wp_data_namespaceObject.withDispatch)((dispatch, ownProps) => {
const {
insertDefaultBlock,
startTyping
} = dispatch(store);
return {
onAppend() {
const {
rootClientId
} = ownProps;
insertDefaultBlock(undefined, rootClientId);
startTyping();
}
};
}))(DefaultBlockAppender));
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/button-block-appender/index.js
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
function ButtonBlockAppender({
rootClientId,
className,
onFocus,
tabIndex
}, ref) {
return (0,external_wp_element_namespaceObject.createElement)(inserter, {
position: "bottom center",
rootClientId: rootClientId,
__experimentalIsQuick: true,
renderToggle: ({
onToggle,
disabled,
isOpen,
blockTitle,
hasSingleBlockType
}) => {
let label;
if (hasSingleBlockType) {
label = (0,external_wp_i18n_namespaceObject.sprintf)(
// translators: %s: the name of the block when there is only one
(0,external_wp_i18n_namespaceObject._x)('Add %s', 'directly add the only allowed block'), blockTitle);
} else {
label = (0,external_wp_i18n_namespaceObject._x)('Add block', 'Generic label for block inserter button');
}
const isToggleButton = !hasSingleBlockType;
let inserterButton = (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.Button, {
ref: ref,
onFocus: onFocus,
tabIndex: tabIndex,
className: classnames_default()(className, 'block-editor-button-block-appender'),
onClick: onToggle,
"aria-haspopup": isToggleButton ? 'true' : undefined,
"aria-expanded": isToggleButton ? isOpen : undefined,
disabled: disabled,
label: label
}, !hasSingleBlockType && (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.VisuallyHidden, {
as: "span"
}, label), (0,external_wp_element_namespaceObject.createElement)(build_module_icon, {
icon: library_plus
}));
if (isToggleButton || hasSingleBlockType) {
inserterButton = (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.Tooltip, {
text: label
}, inserterButton);
}
return inserterButton;
},
isAppender: true
});
}
/**
* Use `ButtonBlockAppender` instead.
*
* @deprecated
*/
const ButtonBlockerAppender = (0,external_wp_element_namespaceObject.forwardRef)((props, ref) => {
external_wp_deprecated_default()(`wp.blockEditor.ButtonBlockerAppender`, {
alternative: 'wp.blockEditor.ButtonBlockAppender',
since: '5.9'
});
return ButtonBlockAppender(props, ref);
});
/**
* @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/button-block-appender/README.md
*/
/* harmony default export */ var button_block_appender = ((0,external_wp_element_namespaceObject.forwardRef)(ButtonBlockAppender));
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-list-appender/index.js
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
function DefaultAppender({
rootClientId
}) {
const canInsertDefaultBlock = (0,external_wp_data_namespaceObject.useSelect)(select => select(store).canInsertBlockType((0,external_wp_blocks_namespaceObject.getDefaultBlockName)(), rootClientId));
if (canInsertDefaultBlock) {
// Render the default block appender if the context supports use
// of the default appender.
return (0,external_wp_element_namespaceObject.createElement)(default_block_appender, {
rootClientId: rootClientId
});
}
// Fallback in case the default block can't be inserted.
return (0,external_wp_element_namespaceObject.createElement)(button_block_appender, {
rootClientId: rootClientId,
className: "block-list-appender__toggle"
});
}
function useAppender(rootClientId, CustomAppender) {
const isVisible = (0,external_wp_data_namespaceObject.useSelect)(select => {
const {
getTemplateLock,
getSelectedBlockClientId,
__unstableGetEditorMode,
getBlockEditingMode
} = select(store);
if (CustomAppender === false) {
return false;
}
if (!CustomAppender) {
const selectedBlockClientId = getSelectedBlockClientId();
const isParentSelected = rootClientId === selectedBlockClientId || !rootClientId && !selectedBlockClientId;
if (!isParentSelected) {
return false;
}
}
if (getTemplateLock(rootClientId) || getBlockEditingMode(rootClientId) === 'disabled' || __unstableGetEditorMode() === 'zoom-out') {
return false;
}
return true;
}, [rootClientId, CustomAppender]);
if (!isVisible) {
return null;
}
return CustomAppender ? (0,external_wp_element_namespaceObject.createElement)(CustomAppender, null) : (0,external_wp_element_namespaceObject.createElement)(DefaultAppender, {
rootClientId: rootClientId
});
}
function BlockListAppender({
rootClientId,
renderAppender,
className,
tagName: TagName = 'div'
}) {
const appender = useAppender(rootClientId, renderAppender);
const isDragOver = (0,external_wp_data_namespaceObject.useSelect)(select => {
const {
getBlockInsertionPoint,
isBlockInsertionPointVisible,
getBlockCount
} = select(store);
const insertionPoint = getBlockInsertionPoint();
// Ideally we should also check for `isDragging` but currently it
// requires a lot more setup. We can revisit this once we refactor
// the DnD utility hooks.
return isBlockInsertionPointVisible() && rootClientId === insertionPoint?.rootClientId && getBlockCount(rootClientId) === 0;
}, [rootClientId]);
if (!appender) {
return null;
}
return (0,external_wp_element_namespaceObject.createElement)(TagName
// A `tabIndex` is used on the wrapping `div` element in order to
// force a focus event to occur when an appender `button` element
// is clicked. In some browsers (Firefox, Safari), button clicks do
// not emit a focus event, which could cause this event to propagate
// unexpectedly. The `tabIndex` ensures that the interaction is
// captured as a focus, without also adding an extra tab stop.
//
// See: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#Clicking_and_focus
, {
tabIndex: -1,
className: classnames_default()('block-list-appender wp-block', className, {
'is-drag-over': isDragOver
})
// Needed in case the whole editor is content editable (for multi
// selection). It fixes an edge case where ArrowDown and ArrowRight
// should collapse the selection to the end of that selection and
// not into the appender.
,
contentEditable: false
// The appender exists to let you add the first Paragraph before
// any is inserted. To that end, this appender should visually be
// presented as a block. That means theme CSS should style it as if
// it were an empty paragraph block. That means a `wp-block` class to
// ensure the width is correct, and a [data-block] attribute to ensure
// the correct margin is applied, especially for classic themes which
// have commonly targeted that attribute for margins.
,
"data-block": true
}, appender);
}
/* harmony default export */ var block_list_appender = (BlockListAppender);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-popover/use-popover-scroll.js
/**
* WordPress dependencies
*/
/**
* Allow scrolling "through" popovers over the canvas. This is only called for
* as long as the pointer is over a popover. Do not use React events because it
* will bubble through portals.
*
* @param {Object} scrollableRef
*/
function usePopoverScroll(scrollableRef) {
return (0,external_wp_compose_namespaceObject.useRefEffect)(node => {
if (!scrollableRef) {
return;
}
function onWheel(event) {
const {
deltaX,
deltaY
} = event;
scrollableRef.current.scrollBy(deltaX, deltaY);
}
// Tell the browser that we do not call event.preventDefault
// See https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#improving_scrolling_performance_with_passive_listeners
const options = {
passive: true
};
node.addEventListener('wheel', onWheel, options);
return () => {
node.removeEventListener('wheel', onWheel, options);
};
}, [scrollableRef]);
}
/* harmony default export */ var use_popover_scroll = (usePopoverScroll);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-popover/inbetween.js
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const MAX_POPOVER_RECOMPUTE_COUNTER = Number.MAX_SAFE_INTEGER;
const InsertionPointOpenRef = (0,external_wp_element_namespaceObject.createContext)();
function BlockPopoverInbetween({
previousClientId,
nextClientId,
children,
__unstablePopoverSlot,
__unstableContentRef,
...props
}) {
// This is a temporary hack to get the inbetween inserter to recompute properly.
const [popoverRecomputeCounter, forcePopoverRecompute] = (0,external_wp_element_namespaceObject.useReducer)(
// Module is there to make sure that the counter doesn't overflow.
s => (s + 1) % MAX_POPOVER_RECOMPUTE_COUNTER, 0);
const {
orientation,
rootClientId,
isVisible
} = (0,external_wp_data_namespaceObject.useSelect)(select => {
const {
getBlockListSettings,
getBlockRootClientId,
isBlockVisible
} = select(store);
const _rootClientId = getBlockRootClientId(previousClientId !== null && previousClientId !== void 0 ? previousClientId : nextClientId);
return {
orientation: getBlockListSettings(_rootClientId)?.orientation || 'vertical',
rootClientId: _rootClientId,
isVisible: isBlockVisible(previousClientId) && isBlockVisible(nextClientId)
};
}, [previousClientId, nextClientId]);
const previousElement = useBlockElement(previousClientId);
const nextElement = useBlockElement(nextClientId);
const isVertical = orientation === 'vertical';
const popoverAnchor = (0,external_wp_element_namespaceObject.useMemo)(() => {
if (
// popoverRecomputeCounter is by definition always equal or greater than 0.
// This check is only there to satisfy the correctness of the
// exhaustive-deps rule for the `useMemo` hook.
popoverRecomputeCounter < 0 || !previousElement && !nextElement || !isVisible) {
return undefined;
}
const contextElement = previousElement || nextElement;
return {
contextElement,
getBoundingClientRect() {
const previousRect = previousElement ? previousElement.getBoundingClientRect() : null;
const nextRect = nextElement ? nextElement.getBoundingClientRect() : null;
let left = 0;
let top = 0;
let width = 0;
let height = 0;
if (isVertical) {
// vertical
top = previousRect ? previousRect.bottom : nextRect.top;
width = previousRect ? previousRect.width : nextRect.width;
height = nextRect && previousRect ? nextRect.top - previousRect.bottom : 0;
left = previousRect ? previousRect.left : nextRect.left;
} else {
top = previousRect ? previousRect.top : nextRect.top;
height = previousRect ? previousRect.height : nextRect.height;
if ((0,external_wp_i18n_namespaceObject.isRTL)()) {
// non vertical, rtl
left = nextRect ? nextRect.right : previousRect.left;
width = previousRect && nextRect ? previousRect.left - nextRect.right : 0;
} else {
// non vertical, ltr
left = previousRect ? previousRect.right : nextRect.left;
width = previousRect && nextRect ? nextRect.left - previousRect.right : 0;
}
}
return new window.DOMRect(left, top, width, height);
}
};
}, [previousElement, nextElement, popoverRecomputeCounter, isVertical, isVisible]);
const popoverScrollRef = use_popover_scroll(__unstableContentRef);
// This is only needed for a smooth transition when moving blocks.
// When blocks are moved up/down, their position can be set by
// updating the `transform` property manually (i.e. without using CSS
// transitions or animations). The animation, which can also scroll the block
// editor, can sometimes cause the position of the Popover to get out of sync.
// A MutationObserver is therefore used to make sure that changes to the
// selectedElement's attribute (i.e. `transform`) can be tracked and used to
// trigger the Popover to rerender.
(0,external_wp_element_namespaceObject.useLayoutEffect)(() => {
if (!previousElement) {
return;
}
const observer = new window.MutationObserver(forcePopoverRecompute);
observer.observe(previousElement, {
attributes: true
});
return () => {
observer.disconnect();
};
}, [previousElement]);
(0,external_wp_element_namespaceObject.useLayoutEffect)(() => {
if (!nextElement) {
return;
}
const observer = new window.MutationObserver(forcePopoverRecompute);
observer.observe(nextElement, {
attributes: true
});
return () => {
observer.disconnect();
};
}, [nextElement]);
(0,external_wp_element_namespaceObject.useLayoutEffect)(() => {
if (!previousElement) {
return;
}
previousElement.ownerDocument.defaultView.addEventListener('resize', forcePopoverRecompute);
return () => {
previousElement.ownerDocument.defaultView?.removeEventListener('resize', forcePopoverRecompute);
};
}, [previousElement]);
// If there's either a previous or a next element, show the inbetween popover.
// Note that drag and drop uses the inbetween popover to show the drop indicator
// before the first block and after the last block.
if (!previousElement && !nextElement || !isVisible) {
return null;
}
/* eslint-disable jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events */
// While ideally it would be enough to capture the
// bubbling focus event from the Inserter, due to the
// characteristics of click focusing of `button`s in
// Firefox and Safari, it is not reliable.
//
// See: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#Clicking_and_focus
return (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.Popover, {
ref: popoverScrollRef,
animate: false,
anchor: popoverAnchor,
focusOnMount: false
// Render in the old slot if needed for backward compatibility,
// otherwise render in place (not in the default popover slot).
,
__unstableSlotName: __unstablePopoverSlot,
inline: !__unstablePopoverSlot
// Forces a remount of the popover when its position changes
// This makes sure the popover doesn't animate from its previous position.
,
key: nextClientId + '--' + rootClientId,
...props,
className: classnames_default()('block-editor-block-popover', 'block-editor-block-popover__inbetween', props.className),
resize: false,
flip: false,
placement: "overlay",
variant: "unstyled"
}, (0,external_wp_element_namespaceObject.createElement)("div", {
className: "block-editor-block-popover__inbetween-container"
}, children));
/* eslint-enable jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events */
}
/* harmony default export */ var inbetween = (BlockPopoverInbetween);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-popover/index.js
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const block_popover_MAX_POPOVER_RECOMPUTE_COUNTER = Number.MAX_SAFE_INTEGER;
function BlockPopover({
clientId,
bottomClientId,
children,
__unstableRefreshSize,
__unstableCoverTarget = false,
__unstablePopoverSlot,
__unstableContentRef,
shift = true,
...props
}, ref) {
const selectedElement = useBlockElement(clientId);
const lastSelectedElement = useBlockElement(bottomClientId !== null && bottomClientId !== void 0 ? bottomClientId : clientId);
const mergedRefs = (0,external_wp_compose_namespaceObject.useMergeRefs)([ref, use_popover_scroll(__unstableContentRef)]);
const [popoverDimensionsRecomputeCounter, forceRecomputePopoverDimensions] = (0,external_wp_element_namespaceObject.useReducer)(
// Module is there to make sure that the counter doesn't overflow.
s => (s + 1) % block_popover_MAX_POPOVER_RECOMPUTE_COUNTER, 0);
// When blocks are moved up/down, they are animated to their new position by
// updating the `transform` property manually (i.e. without using CSS
// transitions or animations). The animation, which can also scroll the block
// editor, can sometimes cause the position of the Popover to get out of sync.
// A MutationObserver is therefore used to make sure that changes to the
// selectedElement's attribute (i.e. `transform`) can be tracked and used to
// trigger the Popover to rerender.
(0,external_wp_element_namespaceObject.useLayoutEffect)(() => {
if (!selectedElement) {
return;
}
const observer = new window.MutationObserver(forceRecomputePopoverDimensions);
observer.observe(selectedElement, {
attributes: true
});
return () => {
observer.disconnect();
};
}, [selectedElement]);
const style = (0,external_wp_element_namespaceObject.useMemo)(() => {
if (
// popoverDimensionsRecomputeCounter is by definition always equal or greater
// than 0. This check is only there to satisfy the correctness of the
// exhaustive-deps rule for the `useMemo` hook.
popoverDimensionsRecomputeCounter < 0 || !selectedElement || lastSelectedElement !== selectedElement) {
return {};
}
return {
position: 'absolute',
width: selectedElement.offsetWidth,
height: selectedElement.offsetHeight
};
}, [selectedElement, lastSelectedElement, __unstableRefreshSize, popoverDimensionsRecomputeCounter]);
const popoverAnchor = (0,external_wp_element_namespaceObject.useMemo)(() => {
if (
// popoverDimensionsRecomputeCounter is by definition always equal or greater
// than 0. This check is only there to satisfy the correctness of the
// exhaustive-deps rule for the `useMemo` hook.
popoverDimensionsRecomputeCounter < 0 || !selectedElement || bottomClientId && !lastSelectedElement) {
return undefined;
}
return {
getBoundingClientRect() {
var _lastSelectedBCR$left, _lastSelectedBCR$top, _lastSelectedBCR$righ, _lastSelectedBCR$bott;
const selectedBCR = selectedElement.getBoundingClientRect();
const lastSelectedBCR = lastSelectedElement?.getBoundingClientRect();
// Get the biggest rectangle that encompasses completely the currently
// selected element and the last selected element:
// - for top/left coordinates, use the smaller numbers
// - for the bottom/right coordinates, use the largest numbers
const left = Math.min(selectedBCR.left, (_lastSelectedBCR$left = lastSelectedBCR?.left) !== null && _lastSelectedBCR$left !== void 0 ? _lastSelectedBCR$left : Infinity);
const top = Math.min(selectedBCR.top, (_lastSelectedBCR$top = lastSelectedBCR?.top) !== null && _lastSelectedBCR$top !== void 0 ? _lastSelectedBCR$top : Infinity);
const right = Math.max(selectedBCR.right, (_lastSelectedBCR$righ = lastSelectedBCR.right) !== null && _lastSelectedBCR$righ !== void 0 ? _lastSelectedBCR$righ : -Infinity);
const bottom = Math.max(selectedBCR.bottom, (_lastSelectedBCR$bott = lastSelectedBCR.bottom) !== null && _lastSelectedBCR$bott !== void 0 ? _lastSelectedBCR$bott : -Infinity);
const width = right - left;
const height = bottom - top;
return new window.DOMRect(left, top, width, height);
},
contextElement: selectedElement
};
}, [bottomClientId, lastSelectedElement, selectedElement, popoverDimensionsRecomputeCounter]);
if (!selectedElement || bottomClientId && !lastSelectedElement) {
return null;
}
return (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.Popover, {
ref: mergedRefs,
animate: false,
focusOnMount: false,
anchor: popoverAnchor
// Render in the old slot if needed for backward compatibility,
// otherwise render in place (not in the default popover slot).
,
__unstableSlotName: __unstablePopoverSlot,
inline: !__unstablePopoverSlot,
placement: "top-start",
resize: false,
flip: false,
shift: shift,
...props,
className: classnames_default()('block-editor-block-popover', props.className),
variant: "unstyled"
}, __unstableCoverTarget && (0,external_wp_element_namespaceObject.createElement)("div", {
style: style
}, children), !__unstableCoverTarget && children);
}
/* harmony default export */ var block_popover = ((0,external_wp_element_namespaceObject.forwardRef)(BlockPopover));
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-popover/drop-zone.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const animateVariants = {
hide: {
opacity: 0,
scaleY: 0.75
},
show: {
opacity: 1,
scaleY: 1
},
exit: {
opacity: 0,
scaleY: 0.9
}
};
function BlockDropZonePopover({
__unstablePopoverSlot,
__unstableContentRef
}) {
const {
clientId
} = (0,external_wp_data_namespaceObject.useSelect)(select => {
const {
getBlockOrder,
getBlockInsertionPoint
} = select(store);
const insertionPoint = getBlockInsertionPoint();
const order = getBlockOrder(insertionPoint.rootClientId);
if (!order.length) {
return {};
}
return {
clientId: order[insertionPoint.index]
};
}, []);
const reducedMotion = (0,external_wp_compose_namespaceObject.useReducedMotion)();
return (0,external_wp_element_namespaceObject.createElement)(block_popover, {
clientId: clientId,
__unstableCoverTarget: true,
__unstablePopoverSlot: __unstablePopoverSlot,
__unstableContentRef: __unstableContentRef,
className: "block-editor-block-popover__drop-zone"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__unstableMotion.div, {
"data-testid": "block-popover-drop-zone",
initial: reducedMotion ? animateVariants.show : animateVariants.hide,
animate: animateVariants.show,
exit: reducedMotion ? animateVariants.show : animateVariants.exit,
className: "block-editor-block-popover__drop-zone-foreground"
}));
}
/* harmony default export */ var drop_zone = (BlockDropZonePopover);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-tools/insertion-point.js
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const insertion_point_InsertionPointOpenRef = (0,external_wp_element_namespaceObject.createContext)();
function InbetweenInsertionPointPopover({
__unstablePopoverSlot,
__unstableContentRef
}) {
const {
selectBlock,
hideInsertionPoint
} = (0,external_wp_data_namespaceObject.useDispatch)(store);
const openRef = (0,external_wp_element_namespaceObject.useContext)(insertion_point_InsertionPointOpenRef);
const ref = (0,external_wp_element_namespaceObject.useRef)();
const {
orientation,
previousClientId,
nextClientId,
rootClientId,
isInserterShown,
isDistractionFree,
isNavigationMode
} = (0,external_wp_data_namespaceObject.useSelect)(select => {
const {
getBlockOrder,
getBlockListSettings,
getBlockInsertionPoint,
isBlockBeingDragged,
getPreviousBlockClientId,
getNextBlockClientId,
getSettings,
isNavigationMode: _isNavigationMode
} = select(store);
const insertionPoint = getBlockInsertionPoint();
const order = getBlockOrder(insertionPoint.rootClientId);
if (!order.length) {
return {};
}
let _previousClientId = order[insertionPoint.index - 1];
let _nextClientId = order[insertionPoint.index];
while (isBlockBeingDragged(_previousClientId)) {
_previousClientId = getPreviousBlockClientId(_previousClientId);
}
while (isBlockBeingDragged(_nextClientId)) {
_nextClientId = getNextBlockClientId(_nextClientId);
}
const settings = getSettings();
return {
previousClientId: _previousClientId,
nextClientId: _nextClientId,
orientation: getBlockListSettings(insertionPoint.rootClientId)?.orientation || 'vertical',
rootClientId: insertionPoint.rootClientId,
isNavigationMode: _isNavigationMode(),
isDistractionFree: settings.isDistractionFree,
isInserterShown: insertionPoint?.__unstableWithInserter
};
}, []);
const disableMotion = (0,external_wp_compose_namespaceObject.useReducedMotion)();
function onClick(event) {
if (event.target === ref.current && nextClientId) {
selectBlock(nextClientId, -1);
}
}
function maybeHideInserterPoint(event) {
// Only hide the inserter if it's triggered on the wrapper,
// and the inserter is not open.
if (event.target === ref.current && !openRef.current) {
hideInsertionPoint();
}
}
function onFocus(event) {
// Only handle click on the wrapper specifically, and not an event
// bubbled from the inserter itself.
if (event.target !== ref.current) {
openRef.current = true;
}
}
const lineVariants = {
// Initial position starts from the center and invisible.
start: {
opacity: 0,
scale: 0
},
// The line expands to fill the container. If the inserter is visible it
// is delayed so it appears orchestrated.
rest: {
opacity: 1,
scale: 1,
transition: {
delay: isInserterShown ? 0.5 : 0,
type: 'tween'
}
},
hover: {
opacity: 1,
scale: 1,
transition: {
delay: 0.5,
type: 'tween'
}
}
};
const inserterVariants = {
start: {
scale: disableMotion ? 1 : 0
},
rest: {
scale: 1,
transition: {
delay: 0.4,
type: 'tween'
}
}
};
if (isDistractionFree && !isNavigationMode) {
return null;
}
const className = classnames_default()('block-editor-block-list__insertion-point', 'is-' + orientation);
return (0,external_wp_element_namespaceObject.createElement)(inbetween, {
previousClientId: previousClientId,
nextClientId: nextClientId,
__unstablePopoverSlot: __unstablePopoverSlot,
__unstableContentRef: __unstableContentRef
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__unstableMotion.div, {
layout: !disableMotion,
initial: disableMotion ? 'rest' : 'start',
animate: "rest",
whileHover: "hover",
whileTap: "pressed",
exit: "start",
ref: ref,
tabIndex: -1,
onClick: onClick,
onFocus: onFocus,
className: classnames_default()(className, {
'is-with-inserter': isInserterShown
}),
onHoverEnd: maybeHideInserterPoint
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__unstableMotion.div, {
variants: lineVariants,
className: "block-editor-block-list__insertion-point-indicator",
"data-testid": "block-list-insertion-point-indicator"
}), isInserterShown && (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.__unstableMotion.div, {
variants: inserterVariants,
className: classnames_default()('block-editor-block-list__insertion-point-inserter')
}, (0,external_wp_element_namespaceObject.createElement)(inserter, {
position: "bottom center",
clientId: nextClientId,
rootClientId: rootClientId,
__experimentalIsQuick: true,
onToggle: isOpen => {
openRef.current = isOpen;
},
onSelectOrClose: () => {
openRef.current = false;
}
}))));
}
function InsertionPoint(props) {
const {
insertionPoint,
isVisible,
isBlockListEmpty
} = (0,external_wp_data_namespaceObject.useSelect)(select => {
const {
getBlockInsertionPoint,
isBlockInsertionPointVisible,
getBlockCount
} = select(store);
const blockInsertionPoint = getBlockInsertionPoint();
return {
insertionPoint: blockInsertionPoint,
isVisible: isBlockInsertionPointVisible(),
isBlockListEmpty: getBlockCount(blockInsertionPoint?.rootClientId) === 0
};
}, []);
if (!isVisible ||
// Don't render the insertion point if the block list is empty.
// The insertion point will be represented by the appender instead.
isBlockListEmpty) {
return null;
}
/**
* Render a popover that overlays the block when the desired operation is to replace it.
* Otherwise, render a popover in between blocks for the indication of inserting between them.
*/
return insertionPoint.operation === 'replace' ? (0,external_wp_element_namespaceObject.createElement)(drop_zone
// Force remount to trigger the animation.
, {
key: `${insertionPoint.rootClientId}-${insertionPoint.index}`,
...props
}) : (0,external_wp_element_namespaceObject.createElement)(InbetweenInsertionPointPopover, {
...props
});
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-list/use-in-between-inserter.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
function useInBetweenInserter() {
const openRef = (0,external_wp_element_namespaceObject.useContext)(insertion_point_InsertionPointOpenRef);
const isInBetweenInserterDisabled = (0,external_wp_data_namespaceObject.useSelect)(select => select(store).getSettings().isDistractionFree || select(store).__unstableGetEditorMode() === 'zoom-out', []);
const {
getBlockListSettings,
getBlockIndex,
isMultiSelecting,
getSelectedBlockClientIds,
getTemplateLock,
__unstableIsWithinBlockOverlay,
getBlockEditingMode
} = (0,external_wp_data_namespaceObject.useSelect)(store);
const {
showInsertionPoint,
hideInsertionPoint
} = (0,external_wp_data_namespaceObject.useDispatch)(store);
return (0,external_wp_compose_namespaceObject.useRefEffect)(node => {
if (isInBetweenInserterDisabled) {
return;
}
function onMouseMove(event) {
if (openRef.current) {
return;
}
// Ignore text nodes sometimes detected in FireFox.
if (event.target.nodeType === event.target.TEXT_NODE) {
return;
}
if (isMultiSelecting()) {
return;
}
if (!event.target.classList.contains('block-editor-block-list__layout')) {
hideInsertionPoint();
return;
}
let rootClientId;
if (!event.target.classList.contains('is-root-container')) {
const blockElement = !!event.target.getAttribute('data-block') ? event.target : event.target.closest('[data-block]');
rootClientId = blockElement.getAttribute('data-block');
}
if (getTemplateLock(rootClientId) || getBlockEditingMode(rootClientId) === 'disabled') {
return;
}
const orientation = getBlockListSettings(rootClientId)?.orientation || 'vertical';
const offsetTop = event.clientY;
const offsetLeft = event.clientX;
const children = Array.from(event.target.children);
let element = children.find(blockEl => {
const blockElRect = blockEl.getBoundingClientRect();
return blockEl.classList.contains('wp-block') && orientation === 'vertical' && blockElRect.top > offsetTop || blockEl.classList.contains('wp-block') && orientation === 'horizontal' && ((0,external_wp_i18n_namespaceObject.isRTL)() ? blockElRect.right < offsetLeft : blockElRect.left > offsetLeft);
});
if (!element) {
hideInsertionPoint();
return;
}
// The block may be in an alignment wrapper, so check the first direct
// child if the element has no ID.
if (!element.id) {
element = element.firstElementChild;
if (!element) {
hideInsertionPoint();
return;
}
}
// Don't show the insertion point if a parent block has an "overlay"
// See https://github.com/WordPress/gutenberg/pull/34012#pullrequestreview-727762337
const clientId = element.id.slice('block-'.length);
if (!clientId || __unstableIsWithinBlockOverlay(clientId)) {
return;
}
// Don't show the inserter when hovering above (conflicts with
// block toolbar) or inside selected block(s).
if (getSelectedBlockClientIds().includes(clientId)) {
return;
}
const elementRect = element.getBoundingClientRect();
if (orientation === 'horizontal' && (event.clientY > elementRect.bottom || event.clientY < elementRect.top) || orientation === 'vertical' && (event.clientX > elementRect.right || event.clientX < elementRect.left)) {
hideInsertionPoint();
return;
}
const index = getBlockIndex(clientId);
// Don't show the in-between inserter before the first block in
// the list (preserves the original behaviour).
if (index === 0) {
hideInsertionPoint();
return;
}
showInsertionPoint(rootClientId, index, {
__unstableWithInserter: true
});
}
node.addEventListener('mousemove', onMouseMove);
return () => {
node.removeEventListener('mousemove', onMouseMove);
};
}, [openRef, getBlockListSettings, getBlockIndex, isMultiSelecting, showInsertionPoint, hideInsertionPoint, getSelectedBlockClientIds, isInBetweenInserterDisabled]);
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inner-blocks/with-client-id.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const withClientId = (0,external_wp_compose_namespaceObject.createHigherOrderComponent)(WrappedComponent => props => {
const {
clientId
} = useBlockEditContext();
return (0,external_wp_element_namespaceObject.createElement)(WrappedComponent, {
...props,
clientId: clientId
});
}, 'withClientId');
/* harmony default export */ var with_client_id = (withClientId);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inner-blocks/button-block-appender.js
/**
* External dependencies
*/
/**
* Internal dependencies
*/
const button_block_appender_ButtonBlockAppender = ({
clientId,
showSeparator,
isFloating,
onAddBlock,
isToggle
}) => {
return (0,external_wp_element_namespaceObject.createElement)(button_block_appender, {
className: classnames_default()({
'block-list-appender__toggle': isToggle
}),
rootClientId: clientId,
showSeparator: showSeparator,
isFloating: isFloating,
onAddBlock: onAddBlock
});
};
/* harmony default export */ var inner_blocks_button_block_appender = (with_client_id(button_block_appender_ButtonBlockAppender));
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inner-blocks/default-block-appender.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const default_block_appender_DefaultBlockAppender = ({
clientId
}) => {
return (0,external_wp_element_namespaceObject.createElement)(default_block_appender, {
rootClientId: clientId
});
};
/* harmony default export */ var inner_blocks_default_block_appender = ((0,external_wp_compose_namespaceObject.compose)([with_client_id, (0,external_wp_data_namespaceObject.withSelect)((select, {
clientId
}) => {
const {
getBlockOrder
} = select(store);
const blockClientIds = getBlockOrder(clientId);
return {
lastBlockClientId: blockClientIds[blockClientIds.length - 1]
};
})])(default_block_appender_DefaultBlockAppender));
;// CONCATENATED MODULE: external ["wp","isShallowEqual"]
var external_wp_isShallowEqual_namespaceObject = window["wp"]["isShallowEqual"];
var external_wp_isShallowEqual_default = /*#__PURE__*/__webpack_require__.n(external_wp_isShallowEqual_namespaceObject);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inner-blocks/use-nested-settings-update.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
/** @typedef {import('../../selectors').WPDirectInsertBlock } WPDirectInsertBlock */
const pendingSettingsUpdates = new WeakMap();
function useShallowMemo(value) {
const [prevValue, setPrevValue] = (0,external_wp_element_namespaceObject.useState)(value);
if (!external_wp_isShallowEqual_default()(prevValue, value)) {
setPrevValue(value);
}
return prevValue;
}
/**
* This hook is a side effect which updates the block-editor store when changes
* happen to inner block settings. The given props are transformed into a
* settings object, and if that is different from the current settings object in
* the block-editor store, then the store is updated with the new settings which
* came from props.
*
* @param {string} clientId The client ID of the block to update.
* @param {string[]} allowedBlocks An array of block names which are permitted
* in inner blocks.
* @param {string[]} prioritizedInserterBlocks Block names and/or block variations to be prioritized in the inserter, in the format {blockName}/{variationName}.
* @param {?WPDirectInsertBlock} defaultBlock The default block to insert: [ blockName, { blockAttributes } ].
* @param {?Function|boolean} directInsert If a default block should be inserted directly by the appender.
*
* @param {?WPDirectInsertBlock} __experimentalDefaultBlock A deprecated prop for the default block to insert: [ blockName, { blockAttributes } ]. Use `defaultBlock` instead.
*
* @param {?Function|boolean} __experimentalDirectInsert A deprecated prop for whether a default block should be inserted directly by the appender. Use `directInsert` instead.
*
* @param {string} [templateLock] The template lock specified for the inner
* blocks component. (e.g. "all")
* @param {boolean} captureToolbars Whether or children toolbars should be shown
* in the inner blocks component rather than on
* the child block.
* @param {string} orientation The direction in which the block
* should face.
* @param {Object} layout The layout object for the block container.
*/
function useNestedSettingsUpdate(clientId, allowedBlocks, prioritizedInserterBlocks, defaultBlock, directInsert, __experimentalDefaultBlock, __experimentalDirectInsert, templateLock, captureToolbars, orientation, layout) {
const {
updateBlockListSettings
} = (0,external_wp_data_namespaceObject.useDispatch)(store);
const registry = (0,external_wp_data_namespaceObject.useRegistry)();
const {
parentLock
} = (0,external_wp_data_namespaceObject.useSelect)(select => {
const rootClientId = select(store).getBlockRootClientId(clientId);
return {
parentLock: select(store).getTemplateLock(rootClientId)
};
}, [clientId]);
// Implementors often pass a new array on every render,
// and the contents of the arrays are just strings, so the entire array
// can be passed as dependencies but We need to include the length of the array,
// otherwise if the arrays change length but the first elements are equal the comparison,
// does not works as expected.
const _allowedBlocks = useShallowMemo(allowedBlocks);
const _prioritizedInserterBlocks = (0,external_wp_element_namespaceObject.useMemo)(() => prioritizedInserterBlocks,
// eslint-disable-next-line react-hooks/exhaustive-deps
prioritizedInserterBlocks);
const _templateLock = templateLock === undefined || parentLock === 'contentOnly' ? parentLock : templateLock;
(0,external_wp_element_namespaceObject.useLayoutEffect)(() => {
const newSettings = {
allowedBlocks: _allowedBlocks,
prioritizedInserterBlocks: _prioritizedInserterBlocks,
templateLock: _templateLock
};
// These values are not defined for RN, so only include them if they
// are defined.
if (captureToolbars !== undefined) {
newSettings.__experimentalCaptureToolbars = captureToolbars;
}
// Orientation depends on layout,
// ideally the separate orientation prop should be deprecated.
if (orientation !== undefined) {
newSettings.orientation = orientation;
} else {
const layoutType = getLayoutType(layout?.type);
newSettings.orientation = layoutType.getOrientation(layout);
}
if (__experimentalDefaultBlock !== undefined) {
external_wp_deprecated_default()('__experimentalDefaultBlock', {
alternative: 'defaultBlock',
since: '6.3',
version: '6.4'
});
newSettings.defaultBlock = __experimentalDefaultBlock;
}
if (defaultBlock !== undefined) {
newSettings.defaultBlock = defaultBlock;
}
if (__experimentalDirectInsert !== undefined) {
external_wp_deprecated_default()('__experimentalDirectInsert', {
alternative: 'directInsert',
since: '6.3',
version: '6.4'
});
newSettings.directInsert = __experimentalDirectInsert;
}
if (directInsert !== undefined) {
newSettings.directInsert = directInsert;
}
// Batch updates to block list settings to avoid triggering cascading renders
// for each container block included in a tree and optimize initial render.
// To avoid triggering updateBlockListSettings for each container block
// causing X re-renderings for X container blocks,
// we batch all the updatedBlockListSettings in a single "data" batch
// which results in a single re-render.
if (!pendingSettingsUpdates.get(registry)) {
pendingSettingsUpdates.set(registry, []);
}
pendingSettingsUpdates.get(registry).push([clientId, newSettings]);
window.queueMicrotask(() => {
if (pendingSettingsUpdates.get(registry)?.length) {
registry.batch(() => {
pendingSettingsUpdates.get(registry).forEach(args => {
updateBlockListSettings(...args);
});
pendingSettingsUpdates.set(registry, []);
});
}
});
}, [clientId, _allowedBlocks, _prioritizedInserterBlocks, _templateLock, defaultBlock, directInsert, __experimentalDefaultBlock, __experimentalDirectInsert, captureToolbars, orientation, updateBlockListSettings, layout, registry]);
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inner-blocks/use-inner-block-template-sync.js
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
/**
* This hook makes sure that a block's inner blocks stay in sync with the given
* block "template". The template is a block hierarchy to which inner blocks must
* conform. If the blocks get "out of sync" with the template and the template
* is meant to be locked (e.g. templateLock = "all" or templateLock = "contentOnly"),
* then we replace the inner blocks with the correct value after synchronizing it with the template.
*
* @param {string} clientId The block client ID.
* @param {Object} template The template to match.
* @param {string} templateLock The template lock state for the inner blocks. For
* example, if the template lock is set to "all",
* then the inner blocks will stay in sync with the
* template. If not defined or set to false, then
* the inner blocks will not be synchronized with
* the given template.
* @param {boolean} templateInsertUpdatesSelection Whether or not to update the
* block-editor selection state when inner blocks
* are replaced after template synchronization.
*/
function useInnerBlockTemplateSync(clientId, template, templateLock, templateInsertUpdatesSelection) {
const {
getBlocks,
getSelectedBlocksInitialCaretPosition,
isBlockSelected
} = (0,external_wp_data_namespaceObject.useSelect)(store);
const {
replaceInnerBlocks,
__unstableMarkNextChangeAsNotPersistent
} = (0,external_wp_data_namespaceObject.useDispatch)(store);
const {
innerBlocks
} = (0,external_wp_data_namespaceObject.useSelect)(select => ({
innerBlocks: select(store).getBlocks(clientId)
}), [clientId]);
// Maintain a reference to the previous value so we can do a deep equality check.
const existingTemplate = (0,external_wp_element_namespaceObject.useRef)(null);
(0,external_wp_element_namespaceObject.useLayoutEffect)(() => {
let isCancelled = false;
// There's an implicit dependency between useInnerBlockTemplateSync and useNestedSettingsUpdate
// The former needs to happen after the latter and since the latter is using microtasks to batch updates (performance optimization),
// we need to schedule this one in a microtask as well.
// Example: If you remove queueMicrotask here, ctrl + click to insert quote block won't close the inserter.
window.queueMicrotask(() => {
if (isCancelled) {
return;
}
// Only synchronize innerBlocks with template if innerBlocks are empty
// or a locking "all" or "contentOnly" exists directly on the block.
const currentInnerBlocks = getBlocks(clientId);
const shouldApplyTemplate = currentInnerBlocks.length === 0 || templateLock === 'all' || templateLock === 'contentOnly';
const hasTemplateChanged = !es6_default()(template, existingTemplate.current);
if (!shouldApplyTemplate || !hasTemplateChanged) {
return;
}
existingTemplate.current = template;
const nextBlocks = (0,external_wp_blocks_namespaceObject.synchronizeBlocksWithTemplate)(currentInnerBlocks, template);
if (!es6_default()(nextBlocks, currentInnerBlocks)) {
__unstableMarkNextChangeAsNotPersistent();
replaceInnerBlocks(clientId, nextBlocks, currentInnerBlocks.length === 0 && templateInsertUpdatesSelection && nextBlocks.length !== 0 && isBlockSelected(clientId),
// This ensures the "initialPosition" doesn't change when applying the template
// If we're supposed to focus the block, we'll focus the first inner block
// otherwise, we won't apply any auto-focus.
// This ensures for instance that the focus stays in the inserter when inserting the "buttons" block.
getSelectedBlocksInitialCaretPosition());
}
});
return () => {
isCancelled = true;
};
}, [innerBlocks, template, templateLock, clientId]);
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inner-blocks/use-block-context.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
/**
* Returns a context object for a given block.
*
* @param {string} clientId The block client ID.
*
* @return {Record} Context value.
*/
function useBlockContext(clientId) {
return (0,external_wp_data_namespaceObject.useSelect)(select => {
const block = select(store).getBlock(clientId);
if (!block) {
return undefined;
}
const blockType = select(external_wp_blocks_namespaceObject.store).getBlockType(block.name);
if (!blockType) {
return undefined;
}
if (Object.keys(blockType.providesContext).length === 0) {
return undefined;
}
return Object.fromEntries(Object.entries(blockType.providesContext).map(([contextName, attributeName]) => [contextName, block.attributes[attributeName]]));
}, [clientId]);
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/use-on-block-drop/index.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
/** @typedef {import('@wordpress/element').WPSyntheticEvent} WPSyntheticEvent */
/** @typedef {import('./types').WPDropOperation} WPDropOperation */
/**
* Retrieve the data for a block drop event.
*
* @param {WPSyntheticEvent} event The drop event.
*
* @return {Object} An object with block drag and drop data.
*/
function parseDropEvent(event) {
let result = {
srcRootClientId: null,
srcClientIds: null,
srcIndex: null,
type: null,
blocks: null
};
if (!event.dataTransfer) {
return result;
}
try {
result = Object.assign(result, JSON.parse(event.dataTransfer.getData('wp-blocks')));
} catch (err) {
return result;
}
return result;
}
/**
* A function that returns an event handler function for block drop events.
*
* @param {string} targetRootClientId The root client id where the block(s) will be inserted.
* @param {number} targetBlockIndex The index where the block(s) will be inserted.
* @param {Function} getBlockIndex A function that gets the index of a block.
* @param {Function} getClientIdsOfDescendants A function that gets the client ids of descendant blocks.
* @param {Function} moveBlocks A function that moves blocks.
* @param {Function} insertOrReplaceBlocks A function that inserts or replaces blocks.
* @param {Function} clearSelectedBlock A function that clears block selection.
* @return {Function} The event handler for a block drop event.
*/
function onBlockDrop(targetRootClientId, targetBlockIndex, getBlockIndex, getClientIdsOfDescendants, moveBlocks, insertOrReplaceBlocks, clearSelectedBlock) {
return event => {
const {
srcRootClientId: sourceRootClientId,
srcClientIds: sourceClientIds,
type: dropType,
blocks
} = parseDropEvent(event);
// If the user is inserting a block.
if (dropType === 'inserter') {
clearSelectedBlock();
const blocksToInsert = blocks.map(block => (0,external_wp_blocks_namespaceObject.cloneBlock)(block));
insertOrReplaceBlocks(blocksToInsert, true, null);
}
// If the user is moving a block.
if (dropType === 'block') {
const sourceBlockIndex = getBlockIndex(sourceClientIds[0]);
// If the user is dropping to the same position, return early.
if (sourceRootClientId === targetRootClientId && sourceBlockIndex === targetBlockIndex) {
return;
}
// If the user is attempting to drop a block within its own
// nested blocks, return early as this would create infinite
// recursion.
if (sourceClientIds.includes(targetRootClientId) || getClientIdsOfDescendants(sourceClientIds).some(id => id === targetRootClientId)) {
return;
}
const isAtSameLevel = sourceRootClientId === targetRootClientId;
const draggedBlockCount = sourceClientIds.length;
// If the block is kept at the same level and moved downwards,
// subtract to take into account that the blocks being dragged
// were removed from the block list above the insertion point.
const insertIndex = isAtSameLevel && sourceBlockIndex < targetBlockIndex ? targetBlockIndex - draggedBlockCount : targetBlockIndex;
moveBlocks(sourceClientIds, sourceRootClientId, insertIndex);
}
};
}
/**
* A function that returns an event handler function for block-related file drop events.
*
* @param {string} targetRootClientId The root client id where the block(s) will be inserted.
* @param {number} targetBlockIndex The index where the block(s) will be inserted.
* @param {boolean} hasUploadPermissions Whether the user has upload permissions.
* @param {Function} updateBlockAttributes A function that updates a block's attributes.
* @param {Function} canInsertBlockType A function that returns checks whether a block type can be inserted.
* @param {Function} insertOrReplaceBlocks A function that inserts or replaces blocks.
*
* @return {Function} The event handler for a block-related file drop event.
*/
function onFilesDrop(targetRootClientId, targetBlockIndex, hasUploadPermissions, updateBlockAttributes, canInsertBlockType, insertOrReplaceBlocks) {
return files => {
if (!hasUploadPermissions) {
return;
}
const transformation = (0,external_wp_blocks_namespaceObject.findTransform)((0,external_wp_blocks_namespaceObject.getBlockTransforms)('from'), transform => transform.type === 'files' && canInsertBlockType(transform.blockName, targetRootClientId) && transform.isMatch(files));
if (transformation) {
const blocks = transformation.transform(files, updateBlockAttributes);
insertOrReplaceBlocks(blocks);
}
};
}
/**
* A function that returns an event handler function for block-related HTML drop events.
*
* @param {string} targetRootClientId The root client id where the block(s) will be inserted.
* @param {number} targetBlockIndex The index where the block(s) will be inserted.
* @param {Function} insertOrReplaceBlocks A function that inserts or replaces blocks.
*
* @return {Function} The event handler for a block-related HTML drop event.
*/
function onHTMLDrop(targetRootClientId, targetBlockIndex, insertOrReplaceBlocks) {
return HTML => {
const blocks = (0,external_wp_blocks_namespaceObject.pasteHandler)({
HTML,
mode: 'BLOCKS'
});
if (blocks.length) {
insertOrReplaceBlocks(blocks);
}
};
}
/**
* A React hook for handling block drop events.
*
* @param {string} targetRootClientId The root client id where the block(s) will be inserted.
* @param {number} targetBlockIndex The index where the block(s) will be inserted.
* @param {Object} options The optional options.
* @param {WPDropOperation} [options.operation] The type of operation to perform on drop. Could be `insert` or `replace` for now.
*
* @return {Function} A function to be passed to the onDrop handler.
*/
function useOnBlockDrop(targetRootClientId, targetBlockIndex, options = {}) {
const {
operation = 'insert'
} = options;
const hasUploadPermissions = (0,external_wp_data_namespaceObject.useSelect)(select => select(store).getSettings().mediaUpload, []);
const {
canInsertBlockType,
getBlockIndex,
getClientIdsOfDescendants,
getBlockOrder,
getBlocksByClientId
} = (0,external_wp_data_namespaceObject.useSelect)(store);
const {
insertBlocks,
moveBlocksToPosition,
updateBlockAttributes,
clearSelectedBlock,
replaceBlocks,
removeBlocks
} = (0,external_wp_data_namespaceObject.useDispatch)(store);
const registry = (0,external_wp_data_namespaceObject.useRegistry)();
const insertOrReplaceBlocks = (0,external_wp_element_namespaceObject.useCallback)((blocks, updateSelection = true, initialPosition = 0) => {
if (operation === 'replace') {
const clientIds = getBlockOrder(targetRootClientId);
const clientId = clientIds[targetBlockIndex];
replaceBlocks(clientId, blocks, undefined, initialPosition);
} else {
insertBlocks(blocks, targetBlockIndex, targetRootClientId, updateSelection, initialPosition);
}
}, [operation, getBlockOrder, insertBlocks, replaceBlocks, targetBlockIndex, targetRootClientId]);
const moveBlocks = (0,external_wp_element_namespaceObject.useCallback)((sourceClientIds, sourceRootClientId, insertIndex) => {
if (operation === 'replace') {
const sourceBlocks = getBlocksByClientId(sourceClientIds);
const targetBlockClientIds = getBlockOrder(targetRootClientId);
const targetBlockClientId = targetBlockClientIds[targetBlockIndex];
registry.batch(() => {
// Remove the source blocks.
removeBlocks(sourceClientIds, false);
// Replace the target block with the source blocks.
replaceBlocks(targetBlockClientId, sourceBlocks, undefined, 0);
});
} else {
moveBlocksToPosition(sourceClientIds, sourceRootClientId, targetRootClientId, insertIndex);
}
}, [operation, getBlockOrder, getBlocksByClientId, insertBlocks, moveBlocksToPosition, removeBlocks, targetBlockIndex, targetRootClientId]);
const _onDrop = onBlockDrop(targetRootClientId, targetBlockIndex, getBlockIndex, getClientIdsOfDescendants, moveBlocks, insertOrReplaceBlocks, clearSelectedBlock);
const _onFilesDrop = onFilesDrop(targetRootClientId, targetBlockIndex, hasUploadPermissions, updateBlockAttributes, canInsertBlockType, insertOrReplaceBlocks);
const _onHTMLDrop = onHTMLDrop(targetRootClientId, targetBlockIndex, insertOrReplaceBlocks);
return event => {
const files = (0,external_wp_dom_namespaceObject.getFilesFromDataTransfer)(event.dataTransfer);
const html = event.dataTransfer.getData('text/html');
/**
* From Windows Chrome 96, the `event.dataTransfer` returns both file object and HTML.
* The order of the checks is important to recognise the HTML drop.
*/
if (html) {
_onHTMLDrop(html);
} else if (files.length) {
_onFilesDrop(files);
} else {
_onDrop(event);
}
};
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/utils/math.js
/**
* A string representing the name of an edge.
*
* @typedef {'top'|'right'|'bottom'|'left'} WPEdgeName
*/
/**
* @typedef {Object} WPPoint
* @property {number} x The horizontal position.
* @property {number} y The vertical position.
*/
/**
* Given a point, a DOMRect and the name of an edge, returns the distance to
* that edge of the rect.
*
* This function works for edges that are horizontal or vertical (e.g. not
* rotated), the following terms are used so that the function works in both
* orientations:
*
* - Forward, meaning the axis running horizontally when an edge is vertical
* and vertically when an edge is horizontal.
* - Lateral, meaning the axis running vertically when an edge is vertical
* and horizontally when an edge is horizontal.
*
* @param {WPPoint} point The point to measure distance from.
* @param {DOMRect} rect A DOM Rect containing edge positions.
* @param {WPEdgeName} edge The edge to measure to.
*/
function getDistanceFromPointToEdge(point, rect, edge) {
const isHorizontal = edge === 'top' || edge === 'bottom';
const {
x,
y
} = point;
const pointLateralPosition = isHorizontal ? x : y;
const pointForwardPosition = isHorizontal ? y : x;
const edgeStart = isHorizontal ? rect.left : rect.top;
const edgeEnd = isHorizontal ? rect.right : rect.bottom;
const edgeForwardPosition = rect[edge];
// Measure the straight line distance to the edge of the rect, when the
// point is adjacent to the edge.
// Else, if the point is positioned diagonally to the edge of the rect,
// measure diagonally to the nearest corner that the edge meets.
let edgeLateralPosition;
if (pointLateralPosition >= edgeStart && pointLateralPosition <= edgeEnd) {
edgeLateralPosition = pointLateralPosition;
} else if (pointLateralPosition < edgeEnd) {
edgeLateralPosition = edgeStart;
} else {
edgeLateralPosition = edgeEnd;
}
return Math.sqrt((pointLateralPosition - edgeLateralPosition) ** 2 + (pointForwardPosition - edgeForwardPosition) ** 2);
}
/**
* Given a point, a DOMRect and a list of allowed edges returns the name of and
* distance to the nearest edge.
*
* @param {WPPoint} point The point to measure distance from.
* @param {DOMRect} rect A DOM Rect containing edge positions.
* @param {WPEdgeName[]} allowedEdges A list of the edges included in the
* calculation. Defaults to all edges.
*
* @return {[number, string]} An array where the first value is the distance
* and a second is the edge name.
*/
function getDistanceToNearestEdge(point, rect, allowedEdges = ['top', 'bottom', 'left', 'right']) {
let candidateDistance;
let candidateEdge;
allowedEdges.forEach(edge => {
const distance = getDistanceFromPointToEdge(point, rect, edge);
if (candidateDistance === undefined || distance < candidateDistance) {
candidateDistance = distance;
candidateEdge = edge;
}
});
return [candidateDistance, candidateEdge];
}
/**
* Is the point contained by the rectangle.
*
* @param {WPPoint} point The point.
* @param {DOMRect} rect The rectangle.
*
* @return {boolean} True if the point is contained by the rectangle, false otherwise.
*/
function isPointContainedByRect(point, rect) {
return rect.left <= point.x && rect.right >= point.x && rect.top <= point.y && rect.bottom >= point.y;
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/use-block-drop-zone/index.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
/** @typedef {import('../../utils/math').WPPoint} WPPoint */
/** @typedef {import('../use-on-block-drop/types').WPDropOperation} WPDropOperation */
/**
* The orientation of a block list.
*
* @typedef {'horizontal'|'vertical'|undefined} WPBlockListOrientation
*/
/**
* The insert position when dropping a block.
*
* @typedef {'before'|'after'} WPInsertPosition
*/
/**
* @typedef {Object} WPBlockData
* @property {boolean} isUnmodifiedDefaultBlock Is the block unmodified default block.
* @property {() => DOMRect} getBoundingClientRect Get the bounding client rect of the block.
* @property {number} blockIndex The index of the block.
*/
/**
* Get the drop target position from a given drop point and the orientation.
*
* @param {WPBlockData[]} blocksData The block data list.
* @param {WPPoint} position The position of the item being dragged.
* @param {WPBlockListOrientation} orientation The orientation of the block list.
* @return {[number, WPDropOperation]} The drop target position.
*/
function getDropTargetPosition(blocksData, position, orientation = 'vertical') {
const allowedEdges = orientation === 'horizontal' ? ['left', 'right'] : ['top', 'bottom'];
const isRightToLeft = (0,external_wp_i18n_namespaceObject.isRTL)();
let nearestIndex = 0;
let insertPosition = 'before';
let minDistance = Infinity;
blocksData.forEach(({
isUnmodifiedDefaultBlock,
getBoundingClientRect,
blockIndex
}) => {
const rect = getBoundingClientRect();
let [distance, edge] = getDistanceToNearestEdge(position, rect, allowedEdges);
// Prioritize the element if the point is inside of an unmodified default block.
if (isUnmodifiedDefaultBlock && isPointContainedByRect(position, rect)) {
distance = 0;
}
if (distance < minDistance) {
// Where the dropped block will be inserted on the nearest block.
insertPosition = edge === 'bottom' || !isRightToLeft && edge === 'right' || isRightToLeft && edge === 'left' ? 'after' : 'before';
// Update the currently known best candidate.
minDistance = distance;
nearestIndex = blockIndex;
}
});
const adjacentIndex = nearestIndex + (insertPosition === 'after' ? 1 : -1);
const isNearestBlockUnmodifiedDefaultBlock = !!blocksData[nearestIndex]?.isUnmodifiedDefaultBlock;
const isAdjacentBlockUnmodifiedDefaultBlock = !!blocksData[adjacentIndex]?.isUnmodifiedDefaultBlock;
// If both blocks are not unmodified default blocks then just insert between them.
if (!isNearestBlockUnmodifiedDefaultBlock && !isAdjacentBlockUnmodifiedDefaultBlock) {
// If the user is dropping to the trailing edge of the block
// add 1 to the index to represent dragging after.
const insertionIndex = insertPosition === 'after' ? nearestIndex + 1 : nearestIndex;
return [insertionIndex, 'insert'];
}
// Otherwise, replace the nearest unmodified default block.
return [isNearestBlockUnmodifiedDefaultBlock ? nearestIndex : adjacentIndex, 'replace'];
}
/**
* @typedef {Object} WPBlockDropZoneConfig
* @property {string} rootClientId The root client id for the block list.
*/
/**
* A React hook that can be used to make a block list handle drag and drop.
*
* @param {WPBlockDropZoneConfig} dropZoneConfig configuration data for the drop zone.
*/
function useBlockDropZone({
// An undefined value represents a top-level block. Default to an empty
// string for this so that `targetRootClientId` can be easily compared to
// values returned by the `getRootBlockClientId` selector, which also uses
// an empty string to represent top-level blocks.
rootClientId: targetRootClientId = ''
} = {}) {
const registry = (0,external_wp_data_namespaceObject.useRegistry)();
const [dropTarget, setDropTarget] = (0,external_wp_element_namespaceObject.useState)({
index: null,
operation: 'insert'
});
const isDisabled = (0,external_wp_data_namespaceObject.useSelect)(select => {
const {
__unstableIsWithinBlockOverlay,
__unstableHasActiveBlockOverlayActive,
getBlockEditingMode
} = select(store);
const blockEditingMode = getBlockEditingMode(targetRootClientId);
return blockEditingMode !== 'default' || __unstableHasActiveBlockOverlayActive(targetRootClientId) || __unstableIsWithinBlockOverlay(targetRootClientId);
}, [targetRootClientId]);
const {
getBlockListSettings,
getBlocks,
getBlockIndex
} = (0,external_wp_data_namespaceObject.useSelect)(store);
const {
showInsertionPoint,
hideInsertionPoint
} = (0,external_wp_data_namespaceObject.useDispatch)(store);
const onBlockDrop = useOnBlockDrop(targetRootClientId, dropTarget.index, {
operation: dropTarget.operation
});
const throttled = (0,external_wp_compose_namespaceObject.useThrottle)((0,external_wp_element_namespaceObject.useCallback)((event, ownerDocument) => {
const blocks = getBlocks(targetRootClientId);
// The block list is empty, don't show the insertion point but still allow dropping.
if (blocks.length === 0) {
registry.batch(() => {
setDropTarget({
index: 0,
operation: 'insert'
});
showInsertionPoint(targetRootClientId, 0, {
operation: 'insert'
});
});
return;
}
const blocksData = blocks.map(block => {
const clientId = block.clientId;
return {
isUnmodifiedDefaultBlock: (0,external_wp_blocks_namespaceObject.isUnmodifiedDefaultBlock)(block),
getBoundingClientRect: () => ownerDocument.getElementById(`block-${clientId}`).getBoundingClientRect(),
blockIndex: getBlockIndex(clientId)
};
});
const [targetIndex, operation] = getDropTargetPosition(blocksData, {
x: event.clientX,
y: event.clientY
}, getBlockListSettings(targetRootClientId)?.orientation);
registry.batch(() => {
setDropTarget({
index: targetIndex,
operation
});
showInsertionPoint(targetRootClientId, targetIndex, {
operation
});
});
}, [getBlocks, targetRootClientId, getBlockListSettings, registry, showInsertionPoint, getBlockIndex]), 200);
return (0,external_wp_compose_namespaceObject.__experimentalUseDropZone)({
isDisabled,
onDrop: onBlockDrop,
onDragOver(event) {
// `currentTarget` is only available while the event is being
// handled, so get it now and pass it to the thottled function.
// https://developer.mozilla.org/en-US/docs/Web/API/Event/currentTarget
throttled(event, event.currentTarget.ownerDocument);
},
onDragLeave() {
throttled.cancel();
hideInsertionPoint();
},
onDragEnd() {
throttled.cancel();
hideInsertionPoint();
}
});
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/inner-blocks/index.js
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const EMPTY_OBJECT = {};
/**
* InnerBlocks is a component which allows a single block to have multiple blocks
* as children. The UncontrolledInnerBlocks component is used whenever the inner
* blocks are not controlled by another entity. In other words, it is normally
* used for inner blocks in the post editor
*
* @param {Object} props The component props.
*/
function UncontrolledInnerBlocks(props) {
const {
clientId,
allowedBlocks,
prioritizedInserterBlocks,
defaultBlock,
directInsert,
__experimentalDefaultBlock,
__experimentalDirectInsert,
template,
templateLock,
wrapperRef,
templateInsertUpdatesSelection,
__experimentalCaptureToolbars: captureToolbars,
__experimentalAppenderTagName,
renderAppender,
orientation,
placeholder,
layout
} = props;
useNestedSettingsUpdate(clientId, allowedBlocks, prioritizedInserterBlocks, defaultBlock, directInsert, __experimentalDefaultBlock, __experimentalDirectInsert, templateLock, captureToolbars, orientation, layout);
useInnerBlockTemplateSync(clientId, template, templateLock, templateInsertUpdatesSelection);
const context = useBlockContext(clientId);
const name = (0,external_wp_data_namespaceObject.useSelect)(select => {
return select(store).getBlock(clientId)?.name;
}, [clientId]);
const defaultLayoutBlockSupport = (0,external_wp_blocks_namespaceObject.getBlockSupport)(name, 'layout') || (0,external_wp_blocks_namespaceObject.getBlockSupport)(name, '__experimentalLayout') || EMPTY_OBJECT;
const {
allowSizingOnChildren = false
} = defaultLayoutBlockSupport;
const defaultLayout = use_setting_useSetting('layout') || EMPTY_OBJECT;
const usedLayout = layout || defaultLayoutBlockSupport;
const memoedLayout = (0,external_wp_element_namespaceObject.useMemo)(() => ({
// Default layout will know about any content/wide size defined by the theme.
...defaultLayout,
...usedLayout,
...(allowSizingOnChildren && {
allowSizingOnChildren: true
})
}), [defaultLayout, usedLayout, allowSizingOnChildren]);
// This component needs to always be synchronous as it's the one changing
// the async mode depending on the block selection.
return (0,external_wp_element_namespaceObject.createElement)(BlockContextProvider, {
value: context
}, (0,external_wp_element_namespaceObject.createElement)(BlockListItems, {
rootClientId: clientId,
renderAppender: renderAppender,
__experimentalAppenderTagName: __experimentalAppenderTagName,
layout: memoedLayout,
wrapperRef: wrapperRef,
placeholder: placeholder
}));
}
/**
* The controlled inner blocks component wraps the uncontrolled inner blocks
* component with the blockSync hook. This keeps the innerBlocks of the block in
* the block-editor store in sync with the blocks of the controlling entity. An
* example of an inner block controller is a template part block, which provides
* its own blocks from the template part entity data source.
*
* @param {Object} props The component props.
*/
function ControlledInnerBlocks(props) {
useBlockSync(props);
return (0,external_wp_element_namespaceObject.createElement)(UncontrolledInnerBlocks, {
...props
});
}
const ForwardedInnerBlocks = (0,external_wp_element_namespaceObject.forwardRef)((props, ref) => {
const innerBlocksProps = useInnerBlocksProps({
ref
}, props);
return (0,external_wp_element_namespaceObject.createElement)("div", {
className: "block-editor-inner-blocks"
}, (0,external_wp_element_namespaceObject.createElement)("div", {
...innerBlocksProps
}));
});
/**
* This hook is used to lightly mark an element as an inner blocks wrapper
* element. Call this hook and pass the returned props to the element to mark as
* an inner blocks wrapper, automatically rendering inner blocks as children. If
* you define a ref for the element, it is important to pass the ref to this
* hook, which the hook in turn will pass to the component through the props it
* returns. Optionally, you can also pass any other props through this hook, and
* they will be merged and returned.
*
* @param {Object} props Optional. Props to pass to the element. Must contain
* the ref if one is defined.
* @param {Object} options Optional. Inner blocks options.
*
* @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/inner-blocks/README.md
*/
function useInnerBlocksProps(props = {}, options = {}) {
const {
__unstableDisableLayoutClassNames,
__unstableDisableDropZone
} = options;
const {
clientId,
layout = null,
__unstableLayoutClassNames: layoutClassNames = ''
} = useBlockEditContext();
const isSmallScreen = (0,external_wp_compose_namespaceObject.useViewportMatch)('medium', '<');
const {
__experimentalCaptureToolbars,
hasOverlay
} = (0,external_wp_data_namespaceObject.useSelect)(select => {
if (!clientId) {
return {};
}
const {
getBlockName,
isBlockSelected,
hasSelectedInnerBlock,
__unstableGetEditorMode
} = select(store);
const blockName = getBlockName(clientId);
const enableClickThrough = __unstableGetEditorMode() === 'navigation' || isSmallScreen;
return {
__experimentalCaptureToolbars: select(external_wp_blocks_namespaceObject.store).hasBlockSupport(blockName, '__experimentalExposeControlsToChildren', false),
hasOverlay: blockName !== 'core/template' && !isBlockSelected(clientId) && !hasSelectedInnerBlock(clientId, true) && enableClickThrough
};
}, [clientId, isSmallScreen]);
const blockDropZoneRef = useBlockDropZone({
rootClientId: clientId
});
const ref = (0,external_wp_compose_namespaceObject.useMergeRefs)([props.ref, __unstableDisableDropZone ? null : blockDropZoneRef]);
const innerBlocksProps = {
__experimentalCaptureToolbars,
layout,
...options
};
const InnerBlocks = innerBlocksProps.value && innerBlocksProps.onChange ? ControlledInnerBlocks : UncontrolledInnerBlocks;
return {
...props,
ref,
className: classnames_default()(props.className, 'block-editor-block-list__layout', __unstableDisableLayoutClassNames ? '' : layoutClassNames, {
'has-overlay': hasOverlay
}),
children: clientId ? (0,external_wp_element_namespaceObject.createElement)(InnerBlocks, {
...innerBlocksProps,
clientId: clientId
}) : (0,external_wp_element_namespaceObject.createElement)(BlockListItems, {
...options
})
};
}
useInnerBlocksProps.save = external_wp_blocks_namespaceObject.__unstableGetInnerBlocksProps;
// Expose default appender placeholders as components.
ForwardedInnerBlocks.DefaultBlockAppender = inner_blocks_default_block_appender;
ForwardedInnerBlocks.ButtonBlockAppender = inner_blocks_button_block_appender;
ForwardedInnerBlocks.Content = () => useInnerBlocksProps.save().children;
/**
* @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/inner-blocks/README.md
*/
/* harmony default export */ var inner_blocks = (ForwardedInnerBlocks);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/observe-typing/index.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
/**
* Set of key codes upon which typing is to be initiated on a keydown event.
*
* @type {Set}
*/
const KEY_DOWN_ELIGIBLE_KEY_CODES = new Set([external_wp_keycodes_namespaceObject.UP, external_wp_keycodes_namespaceObject.RIGHT, external_wp_keycodes_namespaceObject.DOWN, external_wp_keycodes_namespaceObject.LEFT, external_wp_keycodes_namespaceObject.ENTER, external_wp_keycodes_namespaceObject.BACKSPACE]);
/**
* Returns true if a given keydown event can be inferred as intent to start
* typing, or false otherwise. A keydown is considered eligible if it is a
* text navigation without shift active.
*
* @param {KeyboardEvent} event Keydown event to test.
*
* @return {boolean} Whether event is eligible to start typing.
*/
function isKeyDownEligibleForStartTyping(event) {
const {
keyCode,
shiftKey
} = event;
return !shiftKey && KEY_DOWN_ELIGIBLE_KEY_CODES.has(keyCode);
}
/**
* Removes the `isTyping` flag when the mouse moves in the document of the given
* element.
*/
function useMouseMoveTypingReset() {
const isTyping = (0,external_wp_data_namespaceObject.useSelect)(select => select(store).isTyping(), []);
const {
stopTyping
} = (0,external_wp_data_namespaceObject.useDispatch)(store);
return (0,external_wp_compose_namespaceObject.useRefEffect)(node => {
if (!isTyping) {
return;
}
const {
ownerDocument
} = node;
let lastClientX;
let lastClientY;
/**
* On mouse move, unset typing flag if user has moved cursor.
*
* @param {MouseEvent} event Mousemove event.
*/
function stopTypingOnMouseMove(event) {
const {
clientX,
clientY
} = event;
// We need to check that the mouse really moved because Safari
// triggers mousemove events when shift or ctrl are pressed.
if (lastClientX && lastClientY && (lastClientX !== clientX || lastClientY !== clientY)) {
stopTyping();
}
lastClientX = clientX;
lastClientY = clientY;
}
ownerDocument.addEventListener('mousemove', stopTypingOnMouseMove);
return () => {
ownerDocument.removeEventListener('mousemove', stopTypingOnMouseMove);
};
}, [isTyping, stopTyping]);
}
/**
* Sets and removes the `isTyping` flag based on user actions:
*
* - Sets the flag if the user types within the given element.
* - Removes the flag when the user selects some text, focusses a non-text
* field, presses ESC or TAB, or moves the mouse in the document.
*/
function useTypingObserver() {
const {
isTyping,
hasInlineToolbar
} = (0,external_wp_data_namespaceObject.useSelect)(select => {
const {
isTyping: _isTyping,
getSettings
} = select(store);
return {
isTyping: _isTyping(),
hasInlineToolbar: getSettings().hasInlineToolbar
};
}, []);
const {
startTyping,
stopTyping
} = (0,external_wp_data_namespaceObject.useDispatch)(store);
const ref1 = useMouseMoveTypingReset();
const ref2 = (0,external_wp_compose_namespaceObject.useRefEffect)(node => {
const {
ownerDocument
} = node;
const {
defaultView
} = ownerDocument;
const selection = defaultView.getSelection();
// Listeners to stop typing should only be added when typing.
// Listeners to start typing should only be added when not typing.
if (isTyping) {
let timerId;
/**
* Stops typing when focus transitions to a non-text field element.
*
* @param {FocusEvent} event Focus event.
*/
function stopTypingOnNonTextField(event) {
const {
target
} = event;
// Since focus to a non-text field via arrow key will trigger
// before the keydown event, wait until after current stack
// before evaluating whether typing is to be stopped. Otherwise,
// typing will re-start.
timerId = defaultView.setTimeout(() => {
if (!(0,external_wp_dom_namespaceObject.isTextField)(target)) {
stopTyping();
}
});
}
/**
* Unsets typing flag if user presses Escape while typing flag is
* active.
*
* @param {KeyboardEvent} event Keypress or keydown event to
* interpret.
*/
function stopTypingOnEscapeKey(event) {
const {
keyCode
} = event;
if (keyCode === external_wp_keycodes_namespaceObject.ESCAPE || keyCode === external_wp_keycodes_namespaceObject.TAB) {
stopTyping();
}
}
/**
* On selection change, unset typing flag if user has made an
* uncollapsed (shift) selection.
*/
function stopTypingOnSelectionUncollapse() {
if (!selection.isCollapsed) {
stopTyping();
}
}
node.addEventListener('focus', stopTypingOnNonTextField);
node.addEventListener('keydown', stopTypingOnEscapeKey);
if (!hasInlineToolbar) {
ownerDocument.addEventListener('selectionchange', stopTypingOnSelectionUncollapse);
}
return () => {
defaultView.clearTimeout(timerId);
node.removeEventListener('focus', stopTypingOnNonTextField);
node.removeEventListener('keydown', stopTypingOnEscapeKey);
ownerDocument.removeEventListener('selectionchange', stopTypingOnSelectionUncollapse);
};
}
/**
* Handles a keypress or keydown event to infer intention to start
* typing.
*
* @param {KeyboardEvent} event Keypress or keydown event to interpret.
*/
function startTypingInTextField(event) {
const {
type,
target
} = event;
// Abort early if already typing, or key press is incurred outside a
// text field (e.g. arrow-ing through toolbar buttons).
// Ignore typing if outside the current DOM container
if (!(0,external_wp_dom_namespaceObject.isTextField)(target) || !node.contains(target)) {
return;
}
// Special-case keydown because certain keys do not emit a keypress
// event. Conversely avoid keydown as the canonical event since
// there are many keydown which are explicitly not targeted for
// typing.
if (type === 'keydown' && !isKeyDownEligibleForStartTyping(event)) {
return;
}
startTyping();
}
node.addEventListener('keypress', startTypingInTextField);
node.addEventListener('keydown', startTypingInTextField);
return () => {
node.removeEventListener('keypress', startTypingInTextField);
node.removeEventListener('keydown', startTypingInTextField);
};
}, [isTyping, hasInlineToolbar, startTyping, stopTyping]);
return (0,external_wp_compose_namespaceObject.useMergeRefs)([ref1, ref2]);
}
function ObserveTyping({
children
}) {
return (0,external_wp_element_namespaceObject.createElement)("div", {
ref: useTypingObserver()
}, children);
}
/**
* @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/observe-typing/README.md
*/
/* harmony default export */ var observe_typing = (ObserveTyping);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-list/index.js
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const elementContext = (0,external_wp_element_namespaceObject.createContext)();
const block_list_IntersectionObserver = (0,external_wp_element_namespaceObject.createContext)();
const pendingBlockVisibilityUpdatesPerRegistry = new WeakMap();
function Root({
className,
...settings
}) {
const [element, setElement] = (0,external_wp_element_namespaceObject.useState)();
const isLargeViewport = (0,external_wp_compose_namespaceObject.useViewportMatch)('medium');
const {
isOutlineMode,
isFocusMode,
editorMode
} = (0,external_wp_data_namespaceObject.useSelect)(select => {
const {
getSettings,
__unstableGetEditorMode
} = select(store);
const {
outlineMode,
focusMode
} = getSettings();
return {
isOutlineMode: outlineMode,
isFocusMode: focusMode,
editorMode: __unstableGetEditorMode()
};
}, []);
const registry = (0,external_wp_data_namespaceObject.useRegistry)();
const {
setBlockVisibility
} = (0,external_wp_data_namespaceObject.useDispatch)(store);
const delayedBlockVisibilityUpdates = (0,external_wp_compose_namespaceObject.useDebounce)((0,external_wp_element_namespaceObject.useCallback)(() => {
const updates = {};
pendingBlockVisibilityUpdatesPerRegistry.get(registry).forEach(([id, isIntersecting]) => {
updates[id] = isIntersecting;
});
setBlockVisibility(updates);
}, [registry]), 300, {
trailing: true
});
const intersectionObserver = (0,external_wp_element_namespaceObject.useMemo)(() => {
const {
IntersectionObserver: Observer
} = window;
if (!Observer) {
return;
}
return new Observer(entries => {
if (!pendingBlockVisibilityUpdatesPerRegistry.get(registry)) {
pendingBlockVisibilityUpdatesPerRegistry.set(registry, []);
}
for (const entry of entries) {
const clientId = entry.target.getAttribute('data-block');
pendingBlockVisibilityUpdatesPerRegistry.get(registry).push([clientId, entry.isIntersecting]);
}
delayedBlockVisibilityUpdates();
});
}, []);
const innerBlocksProps = useInnerBlocksProps({
ref: (0,external_wp_compose_namespaceObject.useMergeRefs)([useBlockSelectionClearer(), useInBetweenInserter(), useTypingObserver()]),
className: classnames_default()('is-root-container', className, {
'is-outline-mode': isOutlineMode,
'is-focus-mode': isFocusMode && isLargeViewport,
'is-navigate-mode': editorMode === 'navigation'
})
}, settings);
return (0,external_wp_element_namespaceObject.createElement)(elementContext.Provider, {
value: element
}, (0,external_wp_element_namespaceObject.createElement)(block_list_IntersectionObserver.Provider, {
value: intersectionObserver
}, (0,external_wp_element_namespaceObject.createElement)("div", {
...innerBlocksProps
}), (0,external_wp_element_namespaceObject.createElement)("div", {
ref: setElement
})));
}
function BlockList(settings) {
return (0,external_wp_element_namespaceObject.createElement)(Provider, {
value: DEFAULT_BLOCK_EDIT_CONTEXT
}, (0,external_wp_element_namespaceObject.createElement)(Root, {
...settings
}));
}
BlockList.__unstableElementContext = elementContext;
function Items({
placeholder,
rootClientId,
renderAppender,
__experimentalAppenderTagName,
layout = defaultLayout
}) {
const {
order,
selectedBlocks,
visibleBlocks
} = (0,external_wp_data_namespaceObject.useSelect)(select => {
const {
getBlockOrder,
getSelectedBlockClientIds,
__unstableGetVisibleBlocks
} = select(store);
return {
order: getBlockOrder(rootClientId),
selectedBlocks: getSelectedBlockClientIds(),
visibleBlocks: __unstableGetVisibleBlocks()
};
}, [rootClientId]);
return (0,external_wp_element_namespaceObject.createElement)(LayoutProvider, {
value: layout
}, order.map(clientId => (0,external_wp_element_namespaceObject.createElement)(external_wp_data_namespaceObject.AsyncModeProvider, {
key: clientId,
value:
// Only provide data asynchronously if the block is
// not visible and not selected.
!visibleBlocks.has(clientId) && !selectedBlocks.includes(clientId)
}, (0,external_wp_element_namespaceObject.createElement)(block, {
rootClientId: rootClientId,
clientId: clientId
}))), order.length < 1 && placeholder, (0,external_wp_element_namespaceObject.createElement)(block_list_appender, {
tagName: __experimentalAppenderTagName,
rootClientId: rootClientId,
renderAppender: renderAppender
}));
}
function BlockListItems(props) {
// This component needs to always be synchronous as it's the one changing
// the async mode depending on the block selection.
return (0,external_wp_element_namespaceObject.createElement)(external_wp_data_namespaceObject.AsyncModeProvider, {
value: false
}, (0,external_wp_element_namespaceObject.createElement)(Items, {
...props
}));
}
;// CONCATENATED MODULE: external ["wp","url"]
var external_wp_url_namespaceObject = window["wp"]["url"];
;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/media.js
/**
* WordPress dependencies
*/
const media = (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.SVG, {
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 24 24"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.Path, {
d: "m7 6.5 4 2.5-4 2.5z"
}), (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.Path, {
fillRule: "evenodd",
clipRule: "evenodd",
d: "m5 3c-1.10457 0-2 .89543-2 2v14c0 1.1046.89543 2 2 2h14c1.1046 0 2-.8954 2-2v-14c0-1.10457-.8954-2-2-2zm14 1.5h-14c-.27614 0-.5.22386-.5.5v10.7072l3.62953-2.6465c.25108-.1831.58905-.1924.84981-.0234l2.92666 1.8969 3.5712-3.4719c.2911-.2831.7545-.2831 1.0456 0l2.9772 2.8945v-9.3568c0-.27614-.2239-.5-.5-.5zm-14.5 14.5v-1.4364l4.09643-2.987 2.99567 1.9417c.2936.1903.6798.1523.9307-.0917l3.4772-3.3806 3.4772 3.3806.0228-.0234v2.5968c0 .2761-.2239.5-.5.5h-14c-.27614 0-.5-.2239-.5-.5z"
}));
/* harmony default export */ var library_media = (media);
;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/upload.js
/**
* WordPress dependencies
*/
const upload = (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.SVG, {
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 24 24"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.Path, {
d: "M18.5 15v3.5H13V6.7l4.5 4.1 1-1.1-6.2-5.8-5.8 5.8 1 1.1 4-4v11.7h-6V15H4v5h16v-5z"
}));
/* harmony default export */ var library_upload = (upload);
;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/post-featured-image.js
/**
* WordPress dependencies
*/
const postFeaturedImage = (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.SVG, {
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 24 24"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.Path, {
d: "M19 3H5c-.6 0-1 .4-1 1v7c0 .5.4 1 1 1h14c.5 0 1-.4 1-1V4c0-.6-.4-1-1-1zM5.5 10.5v-.4l1.8-1.3 1.3.8c.3.2.7.2.9-.1L11 8.1l2.4 2.4H5.5zm13 0h-2.9l-4-4c-.3-.3-.8-.3-1.1 0L8.9 8l-1.2-.8c-.3-.2-.6-.2-.9 0l-1.3 1V4.5h13v6zM4 20h9v-1.5H4V20zm0-4h16v-1.5H4V16z"
}));
/* harmony default export */ var post_featured_image = (postFeaturedImage);
;// CONCATENATED MODULE: external ["wp","preferences"]
var external_wp_preferences_namespaceObject = window["wp"]["preferences"];
;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/keyboard-return.js
/**
* WordPress dependencies
*/
const keyboardReturn = (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.SVG, {
xmlns: "http://www.w3.org/2000/svg",
viewBox: "-2 -2 24 24"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.Path, {
d: "M6.734 16.106l2.176-2.38-1.093-1.028-3.846 4.158 3.846 4.157 1.093-1.027-2.176-2.38h2.811c1.125 0 2.25.03 3.374 0 1.428-.001 3.362-.25 4.963-1.277 1.66-1.065 2.868-2.906 2.868-5.859 0-2.479-1.327-4.896-3.65-5.93-1.82-.813-3.044-.8-4.806-.788l-.567.002v1.5c.184 0 .368 0 .553-.002 1.82-.007 2.704-.014 4.21.657 1.854.827 2.76 2.657 2.76 4.561 0 2.472-.973 3.824-2.178 4.596-1.258.807-2.864 1.04-4.163 1.04h-.02c-1.115.03-2.229 0-3.344 0H6.734z"
}));
/* harmony default export */ var keyboard_return = (keyboardReturn);
;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/chevron-left-small.js
/**
* WordPress dependencies
*/
const chevronLeftSmall = (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.SVG, {
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 24 24"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.Path, {
d: "m13.1 16-3.4-4 3.4-4 1.1 1-2.6 3 2.6 3-1.1 1z"
}));
/* harmony default export */ var chevron_left_small = (chevronLeftSmall);
;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/chevron-right-small.js
/**
* WordPress dependencies
*/
const chevronRightSmall = (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.SVG, {
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 24 24"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.Path, {
d: "M10.8622 8.04053L14.2805 12.0286L10.8622 16.0167L9.72327 15.0405L12.3049 12.0286L9.72327 9.01672L10.8622 8.04053Z"
}));
/* harmony default export */ var chevron_right_small = (chevronRightSmall);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/link-control/settings-drawer.js
/**
* WordPress dependencies
*/
function LinkSettingsDrawer({
children,
settingsOpen,
setSettingsOpen
}) {
const prefersReducedMotion = (0,external_wp_compose_namespaceObject.useReducedMotion)();
const MaybeAnimatePresence = prefersReducedMotion ? external_wp_element_namespaceObject.Fragment : external_wp_components_namespaceObject.__unstableAnimatePresence;
const MaybeMotionDiv = prefersReducedMotion ? 'div' : external_wp_components_namespaceObject.__unstableMotion.div;
const id = (0,external_wp_compose_namespaceObject.useInstanceId)(LinkSettingsDrawer);
const settingsDrawerId = `link-control-settings-drawer-${id}`;
return (0,external_wp_element_namespaceObject.createElement)(external_wp_element_namespaceObject.Fragment, null, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.Button, {
className: "block-editor-link-control__drawer-toggle",
"aria-expanded": settingsOpen,
onClick: () => setSettingsOpen(!settingsOpen),
icon: (0,external_wp_i18n_namespaceObject.isRTL)() ? chevron_left_small : chevron_right_small,
"aria-controls": settingsDrawerId
}, (0,external_wp_i18n_namespaceObject._x)('Advanced', 'Additional link settings')), (0,external_wp_element_namespaceObject.createElement)(MaybeAnimatePresence, null, settingsOpen && (0,external_wp_element_namespaceObject.createElement)(MaybeMotionDiv, {
className: "block-editor-link-control__drawer",
hidden: !settingsOpen,
id: settingsDrawerId,
initial: "collapsed",
animate: "open",
exit: "collapsed",
variants: {
open: {
opacity: 1,
height: 'auto'
},
collapsed: {
opacity: 0,
height: 0
}
},
transition: {
duration: 0.1
}
}, (0,external_wp_element_namespaceObject.createElement)("div", {
className: "block-editor-link-control__drawer-inner"
}, children))));
}
/* harmony default export */ var settings_drawer = (LinkSettingsDrawer);
// EXTERNAL MODULE: ./node_modules/dom-scroll-into-view/lib/index.js
var dom_scroll_into_view_lib = __webpack_require__(5425);
var lib_default = /*#__PURE__*/__webpack_require__.n(dom_scroll_into_view_lib);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/url-input/index.js
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
/**
* Whether the argument is a function.
*
* @param {*} maybeFunc The argument to check.
* @return {boolean} True if the argument is a function, false otherwise.
*/
function isFunction(maybeFunc) {
return typeof maybeFunc === 'function';
}
class URLInput extends external_wp_element_namespaceObject.Component {
constructor(props) {
super(props);
this.onChange = this.onChange.bind(this);
this.onFocus = this.onFocus.bind(this);
this.onKeyDown = this.onKeyDown.bind(this);
this.selectLink = this.selectLink.bind(this);
this.handleOnClick = this.handleOnClick.bind(this);
this.bindSuggestionNode = this.bindSuggestionNode.bind(this);
this.autocompleteRef = props.autocompleteRef || (0,external_wp_element_namespaceObject.createRef)();
this.inputRef = (0,external_wp_element_namespaceObject.createRef)();
this.updateSuggestions = (0,external_wp_compose_namespaceObject.debounce)(this.updateSuggestions.bind(this), 200);
this.suggestionNodes = [];
this.suggestionsRequest = null;
this.state = {
suggestions: [],
showSuggestions: false,
isUpdatingSuggestions: false,
suggestionsValue: null,
selectedSuggestion: null,
suggestionsListboxId: '',
suggestionOptionIdPrefix: ''
};
}
componentDidUpdate(prevProps) {
const {
showSuggestions,
selectedSuggestion
} = this.state;
const {
value,
__experimentalShowInitialSuggestions = false
} = this.props;
// Only have to worry about scrolling selected suggestion into view
// when already expanded.
if (showSuggestions && selectedSuggestion !== null && this.suggestionNodes[selectedSuggestion] && !this.scrollingIntoView) {
this.scrollingIntoView = true;
lib_default()(this.suggestionNodes[selectedSuggestion], this.autocompleteRef.current, {
onlyScrollIfNeeded: true
});
this.props.setTimeout(() => {
this.scrollingIntoView = false;
}, 100);
}
// Update suggestions when the value changes.
if (prevProps.value !== value && !this.props.disableSuggestions && !this.state.isUpdatingSuggestions) {
if (value?.length) {
// If the new value is not empty we need to update with suggestions for it.
this.updateSuggestions(value);
} else if (__experimentalShowInitialSuggestions) {
// If the new value is empty and we can show initial suggestions, then show initial suggestions.
this.updateSuggestions();
}
}
}
componentDidMount() {
if (this.shouldShowInitialSuggestions()) {
this.updateSuggestions();
}
}
componentWillUnmount() {
this.suggestionsRequest?.cancel?.();
this.suggestionsRequest = null;
}
bindSuggestionNode(index) {
return ref => {
this.suggestionNodes[index] = ref;
};
}
shouldShowInitialSuggestions() {
const {
__experimentalShowInitialSuggestions = false,
value
} = this.props;
return __experimentalShowInitialSuggestions && !(value && value.length);
}
updateSuggestions(value = '') {
const {
__experimentalFetchLinkSuggestions: fetchLinkSuggestions,
__experimentalHandleURLSuggestions: handleURLSuggestions
} = this.props;
if (!fetchLinkSuggestions) {
return;
}
// Initial suggestions may only show if there is no value
// (note: this includes whitespace).
const isInitialSuggestions = !value?.length;
// Trim only now we've determined whether or not it originally had a "length"
// (even if that value was all whitespace).
value = value.trim();
// Allow a suggestions request if:
// - there are at least 2 characters in the search input (except manual searches where
// search input length is not required to trigger a fetch)
// - this is a direct entry (eg: a URL)
if (!isInitialSuggestions && (value.length < 2 || !handleURLSuggestions && (0,external_wp_url_namespaceObject.isURL)(value))) {
this.suggestionsRequest?.cancel?.();
this.suggestionsRequest = null;
this.setState({
suggestions: [],
showSuggestions: false,
suggestionsValue: value,
selectedSuggestion: null,
loading: false
});
return;
}
this.setState({
isUpdatingSuggestions: true,
selectedSuggestion: null,
loading: true
});
const request = fetchLinkSuggestions(value, {
isInitialSuggestions
});
request.then(suggestions => {
// A fetch Promise doesn't have an abort option. It's mimicked by
// comparing the request reference in on the instance, which is
// reset or deleted on subsequent requests or unmounting.
if (this.suggestionsRequest !== request) {
return;
}
this.setState({
suggestions,
isUpdatingSuggestions: false,
suggestionsValue: value,
loading: false,
showSuggestions: !!suggestions.length
});
if (!!suggestions.length) {
this.props.debouncedSpeak((0,external_wp_i18n_namespaceObject.sprintf)( /* translators: %s: number of results. */
(0,external_wp_i18n_namespaceObject._n)('%d result found, use up and down arrow keys to navigate.', '%d results found, use up and down arrow keys to navigate.', suggestions.length), suggestions.length), 'assertive');
} else {
this.props.debouncedSpeak((0,external_wp_i18n_namespaceObject.__)('No results.'), 'assertive');
}
}).catch(() => {
if (this.suggestionsRequest !== request) {
return;
}
this.setState({
isUpdatingSuggestions: false,
loading: false
});
});
// Note that this assignment is handled *before* the async search request
// as a Promise always resolves on the next tick of the event loop.
this.suggestionsRequest = request;
}
onChange(event) {
this.props.onChange(event.target.value);
}
onFocus() {
const {
suggestions
} = this.state;
const {
disableSuggestions,
value
} = this.props;
// When opening the link editor, if there's a value present, we want to load the suggestions pane with the results for this input search value
// Don't re-run the suggestions on focus if there are already suggestions present (prevents searching again when tabbing between the input and buttons)
if (value && !disableSuggestions && !this.state.isUpdatingSuggestions && !(suggestions && suggestions.length)) {
// Ensure the suggestions are updated with the current input value.
this.updateSuggestions(value);
}
}
onKeyDown(event) {
this.props.onKeyDown?.(event);
const {
showSuggestions,
selectedSuggestion,
suggestions,
loading
} = this.state;
// If the suggestions are not shown or loading, we shouldn't handle the arrow keys
// We shouldn't preventDefault to allow block arrow keys navigation.
if (!showSuggestions || !suggestions.length || loading) {
// In the Windows version of Firefox the up and down arrows don't move the caret
// within an input field like they do for Mac Firefox/Chrome/Safari. This causes
// a form of focus trapping that is disruptive to the user experience. This disruption
// only happens if the caret is not in the first or last position in the text input.
// See: https://github.com/WordPress/gutenberg/issues/5693#issuecomment-436684747
switch (event.keyCode) {
// When UP is pressed, if the caret is at the start of the text, move it to the 0
// position.
case external_wp_keycodes_namespaceObject.UP:
{
if (0 !== event.target.selectionStart) {
event.preventDefault();
// Set the input caret to position 0.
event.target.setSelectionRange(0, 0);
}
break;
}
// When DOWN is pressed, if the caret is not at the end of the text, move it to the
// last position.
case external_wp_keycodes_namespaceObject.DOWN:
{
if (this.props.value.length !== event.target.selectionStart) {
event.preventDefault();
// Set the input caret to the last position.
event.target.setSelectionRange(this.props.value.length, this.props.value.length);
}
break;
}
// Submitting while loading should trigger onSubmit.
case external_wp_keycodes_namespaceObject.ENTER:
{
if (this.props.onSubmit) {
event.preventDefault();
this.props.onSubmit(null, event);
}
break;
}
}
return;
}
const suggestion = this.state.suggestions[this.state.selectedSuggestion];
switch (event.keyCode) {
case external_wp_keycodes_namespaceObject.UP:
{
event.preventDefault();
const previousIndex = !selectedSuggestion ? suggestions.length - 1 : selectedSuggestion - 1;
this.setState({
selectedSuggestion: previousIndex
});
break;
}
case external_wp_keycodes_namespaceObject.DOWN:
{
event.preventDefault();
const nextIndex = selectedSuggestion === null || selectedSuggestion === suggestions.length - 1 ? 0 : selectedSuggestion + 1;
this.setState({
selectedSuggestion: nextIndex
});
break;
}
case external_wp_keycodes_namespaceObject.TAB:
{
if (this.state.selectedSuggestion !== null) {
this.selectLink(suggestion);
// Announce a link has been selected when tabbing away from the input field.
this.props.speak((0,external_wp_i18n_namespaceObject.__)('Link selected.'));
}
break;
}
case external_wp_keycodes_namespaceObject.ENTER:
{
event.preventDefault();
if (this.state.selectedSuggestion !== null) {
this.selectLink(suggestion);
if (this.props.onSubmit) {
this.props.onSubmit(suggestion, event);
}
} else if (this.props.onSubmit) {
this.props.onSubmit(null, event);
}
break;
}
}
}
selectLink(suggestion) {
this.props.onChange(suggestion.url, suggestion);
this.setState({
selectedSuggestion: null,
showSuggestions: false
});
}
handleOnClick(suggestion) {
this.selectLink(suggestion);
// Move focus to the input field when a link suggestion is clicked.
this.inputRef.current.focus();
}
static getDerivedStateFromProps({
value,
instanceId,
disableSuggestions,
__experimentalShowInitialSuggestions = false
}, {
showSuggestions
}) {
let shouldShowSuggestions = showSuggestions;
const hasValue = value && value.length;
if (!__experimentalShowInitialSuggestions && !hasValue) {
shouldShowSuggestions = false;
}
if (disableSuggestions === true) {
shouldShowSuggestions = false;
}
return {
showSuggestions: shouldShowSuggestions,
suggestionsListboxId: `block-editor-url-input-suggestions-${instanceId}`,
suggestionOptionIdPrefix: `block-editor-url-input-suggestion-${instanceId}`
};
}
render() {
return (0,external_wp_element_namespaceObject.createElement)(external_wp_element_namespaceObject.Fragment, null, this.renderControl(), this.renderSuggestions());
}
renderControl() {
const {
/** Start opting into the new margin-free styles that will become the default in a future version. */
__nextHasNoMarginBottom = false,
label = null,
className,
isFullWidth,
instanceId,
placeholder = (0,external_wp_i18n_namespaceObject.__)('Paste URL or type to search'),
__experimentalRenderControl: renderControl,
value = '',
hideLabelFromVision = false
} = this.props;
const {
loading,
showSuggestions,
selectedSuggestion,
suggestionsListboxId,
suggestionOptionIdPrefix
} = this.state;
const inputId = `url-input-control-${instanceId}`;
const controlProps = {
id: inputId,
// Passes attribute to label for the for attribute
label,
className: classnames_default()('block-editor-url-input', className, {
'is-full-width': isFullWidth
}),
hideLabelFromVision
};
const inputProps = {
id: inputId,
value,
required: true,
className: 'block-editor-url-input__input',
type: 'text',
onChange: this.onChange,
onFocus: this.onFocus,
placeholder,
onKeyDown: this.onKeyDown,
role: 'combobox',
'aria-label': label ? undefined : (0,external_wp_i18n_namespaceObject.__)('URL'),
// Ensure input always has an accessible label
'aria-expanded': showSuggestions,
'aria-autocomplete': 'list',
'aria-owns': suggestionsListboxId,
'aria-activedescendant': selectedSuggestion !== null ? `${suggestionOptionIdPrefix}-${selectedSuggestion}` : undefined,
ref: this.inputRef
};
if (renderControl) {
return renderControl(controlProps, inputProps, loading);
}
if (!__nextHasNoMarginBottom) {
external_wp_deprecated_default()('Bottom margin styles for wp.blockEditor.URLInput', {
since: '6.2',
version: '6.5',
hint: 'Set the `__nextHasNoMarginBottom` prop to true to start opting into the new styles, which will become the default in a future version'
});
}
return (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.BaseControl, {
__nextHasNoMarginBottom: __nextHasNoMarginBottom,
...controlProps
}, (0,external_wp_element_namespaceObject.createElement)("input", {
...inputProps
}), loading && (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.Spinner, null));
}
renderSuggestions() {
const {
className,
__experimentalRenderSuggestions: renderSuggestions
} = this.props;
const {
showSuggestions,
suggestions,
suggestionsValue,
selectedSuggestion,
suggestionsListboxId,
suggestionOptionIdPrefix,
loading
} = this.state;
if (!showSuggestions || suggestions.length === 0) {
return null;
}
const suggestionsListProps = {
id: suggestionsListboxId,
ref: this.autocompleteRef,
role: 'listbox'
};
const buildSuggestionItemProps = (suggestion, index) => {
return {
role: 'option',
tabIndex: '-1',
id: `${suggestionOptionIdPrefix}-${index}`,
ref: this.bindSuggestionNode(index),
'aria-selected': index === selectedSuggestion ? true : undefined
};
};
if (isFunction(renderSuggestions)) {
return renderSuggestions({
suggestions,
selectedSuggestion,
suggestionsListProps,
buildSuggestionItemProps,
isLoading: loading,
handleSuggestionClick: this.handleOnClick,
isInitialSuggestions: !suggestionsValue?.length,
currentInputValue: suggestionsValue
});
}
return (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.Popover, {
placement: "bottom",
focusOnMount: false
}, (0,external_wp_element_namespaceObject.createElement)("div", {
...suggestionsListProps,
className: classnames_default()('block-editor-url-input__suggestions', `${className}__suggestions`)
}, suggestions.map((suggestion, index) => (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.Button, {
...buildSuggestionItemProps(suggestion, index),
key: suggestion.id,
className: classnames_default()('block-editor-url-input__suggestion', {
'is-selected': index === selectedSuggestion
}),
onClick: () => this.handleOnClick(suggestion)
}, suggestion.title))));
}
}
/**
* @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/url-input/README.md
*/
/* harmony default export */ var url_input = ((0,external_wp_compose_namespaceObject.compose)(external_wp_compose_namespaceObject.withSafeTimeout, external_wp_components_namespaceObject.withSpokenMessages, external_wp_compose_namespaceObject.withInstanceId, (0,external_wp_data_namespaceObject.withSelect)((select, props) => {
// If a link suggestions handler is already provided then
// bail.
if (isFunction(props.__experimentalFetchLinkSuggestions)) {
return;
}
const {
getSettings
} = select(store);
return {
__experimentalFetchLinkSuggestions: getSettings().__experimentalFetchLinkSuggestions
};
}))(URLInput));
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/link-control/search-create-button.js
/**
* WordPress dependencies
*/
const LinkControlSearchCreate = ({
searchTerm,
onClick,
itemProps,
buttonText
}) => {
if (!searchTerm) {
return null;
}
let text;
if (buttonText) {
text = typeof buttonText === 'function' ? buttonText(searchTerm) : buttonText;
} else {
text = (0,external_wp_element_namespaceObject.createInterpolateElement)((0,external_wp_i18n_namespaceObject.sprintf)( /* translators: %s: search term. */
(0,external_wp_i18n_namespaceObject.__)('Create: %s'), searchTerm), {
mark: (0,external_wp_element_namespaceObject.createElement)("mark", null)
});
}
return (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.MenuItem, {
...itemProps,
iconPosition: "left",
icon: library_plus,
className: "block-editor-link-control__search-item",
onClick: onClick
}, text);
};
/* harmony default export */ var search_create_button = (LinkControlSearchCreate);
;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/post-list.js
/**
* WordPress dependencies
*/
const postList = (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.SVG, {
viewBox: "0 0 24 24",
xmlns: "http://www.w3.org/2000/svg"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.Path, {
d: "M18 4H6c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm.5 14c0 .3-.2.5-.5.5H6c-.3 0-.5-.2-.5-.5V6c0-.3.2-.5.5-.5h12c.3 0 .5.2.5.5v12zM7 11h2V9H7v2zm0 4h2v-2H7v2zm3-4h7V9h-7v2zm0 4h7v-2h-7v2z"
}));
/* harmony default export */ var post_list = (postList);
;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/page.js
/**
* WordPress dependencies
*/
const page = (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.SVG, {
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 24 24"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.Path, {
d: "M7 5.5h10a.5.5 0 01.5.5v12a.5.5 0 01-.5.5H7a.5.5 0 01-.5-.5V6a.5.5 0 01.5-.5zM17 4H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V6a2 2 0 00-2-2zm-1 3.75H8v1.5h8v-1.5zM8 11h8v1.5H8V11zm6 3.25H8v1.5h6v-1.5z"
}));
/* harmony default export */ var library_page = (page);
;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/tag.js
/**
* WordPress dependencies
*/
const tag = (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.SVG, {
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 24 24"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.Path, {
d: "M20.1 11.2l-6.7-6.7c-.1-.1-.3-.2-.5-.2H5c-.4-.1-.8.3-.8.7v7.8c0 .2.1.4.2.5l6.7 6.7c.2.2.5.4.7.5s.6.2.9.2c.3 0 .6-.1.9-.2.3-.1.5-.3.8-.5l5.6-5.6c.4-.4.7-1 .7-1.6.1-.6-.2-1.2-.6-1.6zM19 13.4L13.4 19c-.1.1-.2.1-.3.2-.2.1-.4.1-.6 0-.1 0-.2-.1-.3-.2l-6.5-6.5V5.8h6.8l6.5 6.5c.2.2.2.4.2.6 0 .1 0 .3-.2.5zM9 8c-.6 0-1 .4-1 1s.4 1 1 1 1-.4 1-1-.4-1-1-1z"
}));
/* harmony default export */ var library_tag = (tag);
;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/category.js
/**
* WordPress dependencies
*/
const category = (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.SVG, {
viewBox: "0 0 24 24",
xmlns: "http://www.w3.org/2000/svg"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.Path, {
d: "M6 5.5h3a.5.5 0 01.5.5v3a.5.5 0 01-.5.5H6a.5.5 0 01-.5-.5V6a.5.5 0 01.5-.5zM4 6a2 2 0 012-2h3a2 2 0 012 2v3a2 2 0 01-2 2H6a2 2 0 01-2-2V6zm11-.5h3a.5.5 0 01.5.5v3a.5.5 0 01-.5.5h-3a.5.5 0 01-.5-.5V6a.5.5 0 01.5-.5zM13 6a2 2 0 012-2h3a2 2 0 012 2v3a2 2 0 01-2 2h-3a2 2 0 01-2-2V6zm5 8.5h-3a.5.5 0 00-.5.5v3a.5.5 0 00.5.5h3a.5.5 0 00.5-.5v-3a.5.5 0 00-.5-.5zM15 13a2 2 0 00-2 2v3a2 2 0 002 2h3a2 2 0 002-2v-3a2 2 0 00-2-2h-3zm-9 1.5h3a.5.5 0 01.5.5v3a.5.5 0 01-.5.5H6a.5.5 0 01-.5-.5v-3a.5.5 0 01.5-.5zM4 15a2 2 0 012-2h3a2 2 0 012 2v3a2 2 0 01-2 2H6a2 2 0 01-2-2v-3z",
fillRule: "evenodd",
clipRule: "evenodd"
}));
/* harmony default export */ var library_category = (category);
;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/file.js
/**
* WordPress dependencies
*/
const file = (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.SVG, {
viewBox: "0 0 24 24",
xmlns: "http://www.w3.org/2000/svg"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.Path, {
d: "M19 6.2h-5.9l-.6-1.1c-.3-.7-1-1.1-1.8-1.1H5c-1.1 0-2 .9-2 2v11.8c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V8.2c0-1.1-.9-2-2-2zm.5 11.6c0 .3-.2.5-.5.5H5c-.3 0-.5-.2-.5-.5V6c0-.3.2-.5.5-.5h5.8c.2 0 .4.1.4.3l1 2H19c.3 0 .5.2.5.5v9.5z"
}));
/* harmony default export */ var library_file = (file);
;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/globe.js
/**
* WordPress dependencies
*/
const globe = (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.SVG, {
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 24 24"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.Path, {
d: "M12 3.3c-4.8 0-8.8 3.9-8.8 8.8 0 4.8 3.9 8.8 8.8 8.8 4.8 0 8.8-3.9 8.8-8.8s-4-8.8-8.8-8.8zm6.5 5.5h-2.6C15.4 7.3 14.8 6 14 5c2 .6 3.6 2 4.5 3.8zm.7 3.2c0 .6-.1 1.2-.2 1.8h-2.9c.1-.6.1-1.2.1-1.8s-.1-1.2-.1-1.8H19c.2.6.2 1.2.2 1.8zM12 18.7c-1-.7-1.8-1.9-2.3-3.5h4.6c-.5 1.6-1.3 2.9-2.3 3.5zm-2.6-4.9c-.1-.6-.1-1.1-.1-1.8 0-.6.1-1.2.1-1.8h5.2c.1.6.1 1.1.1 1.8s-.1 1.2-.1 1.8H9.4zM4.8 12c0-.6.1-1.2.2-1.8h2.9c-.1.6-.1 1.2-.1 1.8 0 .6.1 1.2.1 1.8H5c-.2-.6-.2-1.2-.2-1.8zM12 5.3c1 .7 1.8 1.9 2.3 3.5H9.7c.5-1.6 1.3-2.9 2.3-3.5zM10 5c-.8 1-1.4 2.3-1.8 3.8H5.5C6.4 7 8 5.6 10 5zM5.5 15.3h2.6c.4 1.5 1 2.8 1.8 3.7-1.8-.6-3.5-2-4.4-3.7zM14 19c.8-1 1.4-2.2 1.8-3.7h2.6C17.6 17 16 18.4 14 19z"
}));
/* harmony default export */ var library_globe = (globe);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/link-control/search-item.js
/**
* WordPress dependencies
*/
const ICONS_MAP = {
post: post_list,
page: library_page,
post_tag: library_tag,
category: library_category,
attachment: library_file
};
function SearchItemIcon({
isURL,
suggestion
}) {
let icon = null;
if (isURL) {
icon = library_globe;
} else if (suggestion.type in ICONS_MAP) {
icon = ICONS_MAP[suggestion.type];
}
if (icon) {
return (0,external_wp_element_namespaceObject.createElement)(build_module_icon, {
className: "block-editor-link-control__search-item-icon",
icon: icon
});
}
return null;
}
/**
* Adds a leading slash to a url if it doesn't already have one.
* @param {string} url the url to add a leading slash to.
* @return {string} the url with a leading slash.
*/
function addLeadingSlash(url) {
const trimmedURL = url?.trim();
if (!trimmedURL?.length) return url;
return url?.replace(/^\/?/, '/');
}
function removeTrailingSlash(url) {
const trimmedURL = url?.trim();
if (!trimmedURL?.length) return url;
return url?.replace(/\/$/, '');
}
const partialRight = (fn, ...partialArgs) => (...args) => fn(...args, ...partialArgs);
const defaultTo = d => v => {
return v === null || v === undefined || v !== v ? d : v;
};
/**
* Prepares a URL for display in the UI.
* - decodes the URL.
* - filters it (removes protocol, www, etc.).
* - truncates it if necessary.
* - adds a leading slash.
* @param {string} url the url.
* @return {string} the processed url to display.
*/
function getURLForDisplay(url) {
if (!url) return url;
return (0,external_wp_compose_namespaceObject.pipe)(external_wp_url_namespaceObject.safeDecodeURI, external_wp_url_namespaceObject.getPath, defaultTo(''), partialRight(external_wp_url_namespaceObject.filterURLForDisplay, 24), removeTrailingSlash, addLeadingSlash)(url);
}
const LinkControlSearchItem = ({
itemProps,
suggestion,
searchTerm,
onClick,
isURL = false,
shouldShowType = false
}) => {
const info = isURL ? (0,external_wp_i18n_namespaceObject.__)('Press ENTER to add this link') : getURLForDisplay(suggestion.url);
return (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.MenuItem, {
...itemProps,
info: info,
iconPosition: "left",
icon: (0,external_wp_element_namespaceObject.createElement)(SearchItemIcon, {
suggestion: suggestion,
isURL: isURL
}),
onClick: onClick,
shortcut: shouldShowType && getVisualTypeName(suggestion),
className: "block-editor-link-control__search-item"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.TextHighlight
// The component expects a plain text string.
, {
text: (0,external_wp_dom_namespaceObject.__unstableStripHTML)(suggestion.title),
highlight: searchTerm
}));
};
function getVisualTypeName(suggestion) {
if (suggestion.isFrontPage) {
return 'front page';
}
// Rename 'post_tag' to 'tag'. Ideally, the API would return the localised CPT or taxonomy label.
return suggestion.type === 'post_tag' ? 'tag' : suggestion.type;
}
/* harmony default export */ var search_item = (LinkControlSearchItem);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/link-control/constants.js
/**
* WordPress dependencies
*/
// Used as a unique identifier for the "Create" option within search results.
// Used to help distinguish the "Create" suggestion within the search results in
// order to handle it as a unique case.
const CREATE_TYPE = '__CREATE__';
const TEL_TYPE = 'tel';
const URL_TYPE = 'link';
const MAILTO_TYPE = 'mailto';
const INTERNAL_TYPE = 'internal';
const LINK_ENTRY_TYPES = [URL_TYPE, MAILTO_TYPE, TEL_TYPE, INTERNAL_TYPE];
const DEFAULT_LINK_SETTINGS = [{
id: 'opensInNewTab',
title: (0,external_wp_i18n_namespaceObject.__)('Open in new tab')
}];
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/link-control/search-results.js
/**
* WordPress dependencies
*/
/**
* External dependencies
*/
/**
* Internal dependencies
*/
function LinkControlSearchResults({
instanceId,
withCreateSuggestion,
currentInputValue,
handleSuggestionClick,
suggestionsListProps,
buildSuggestionItemProps,
suggestions,
selectedSuggestion,
isLoading,
isInitialSuggestions,
createSuggestionButtonText,
suggestionsQuery
}) {
const resultsListClasses = classnames_default()('block-editor-link-control__search-results', {
'is-loading': isLoading
});
const isSingleDirectEntryResult = suggestions.length === 1 && LINK_ENTRY_TYPES.includes(suggestions[0].type);
const shouldShowCreateSuggestion = withCreateSuggestion && !isSingleDirectEntryResult && !isInitialSuggestions;
// If the query has a specified type, then we can skip showing them in the result. See #24839.
const shouldShowSuggestionsTypes = !suggestionsQuery?.type;
// According to guidelines aria-label should be added if the label
// itself is not visible.
// See: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/listbox_role
const searchResultsLabelId = `block-editor-link-control-search-results-label-${instanceId}`;
const labelText = isInitialSuggestions ? (0,external_wp_i18n_namespaceObject.__)('Suggestions') : (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: %s: search term. */
(0,external_wp_i18n_namespaceObject.__)('Search results for "%s"'), currentInputValue);
const searchResultsLabel = (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.VisuallyHidden, {
id: searchResultsLabelId
}, labelText);
return (0,external_wp_element_namespaceObject.createElement)("div", {
className: "block-editor-link-control__search-results-wrapper"
}, searchResultsLabel, (0,external_wp_element_namespaceObject.createElement)("div", {
...suggestionsListProps,
className: resultsListClasses,
"aria-labelledby": searchResultsLabelId
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.MenuGroup, null, suggestions.map((suggestion, index) => {
if (shouldShowCreateSuggestion && CREATE_TYPE === suggestion.type) {
return (0,external_wp_element_namespaceObject.createElement)(search_create_button, {
searchTerm: currentInputValue,
buttonText: createSuggestionButtonText,
onClick: () => handleSuggestionClick(suggestion)
// Intentionally only using `type` here as
// the constant is enough to uniquely
// identify the single "CREATE" suggestion.
,
key: suggestion.type,
itemProps: buildSuggestionItemProps(suggestion, index),
isSelected: index === selectedSuggestion
});
}
// If we're not handling "Create" suggestions above then
// we don't want them in the main results so exit early.
if (CREATE_TYPE === suggestion.type) {
return null;
}
return (0,external_wp_element_namespaceObject.createElement)(search_item, {
key: `${suggestion.id}-${suggestion.type}`,
itemProps: buildSuggestionItemProps(suggestion, index),
suggestion: suggestion,
index: index,
onClick: () => {
handleSuggestionClick(suggestion);
},
isSelected: index === selectedSuggestion,
isURL: LINK_ENTRY_TYPES.includes(suggestion.type),
searchTerm: currentInputValue,
shouldShowType: shouldShowSuggestionsTypes,
isFrontPage: suggestion?.isFrontPage
});
}))));
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/link-control/is-url-like.js
/**
* WordPress dependencies
*/
/**
* Determines whether a given value could be a URL. Note this does not
* guarantee the value is a URL only that it looks like it might be one. For
* example, just because a string has `www.` in it doesn't make it a URL,
* but it does make it highly likely that it will be so in the context of
* creating a link it makes sense to treat it like one.
*
* @param {string} val the candidate for being URL-like (or not).
*
* @return {boolean} whether or not the value is potentially a URL.
*/
function isURLLike(val) {
const hasSpaces = val.includes(' ');
if (hasSpaces) {
return false;
}
const protocol = (0,external_wp_url_namespaceObject.getProtocol)(val);
const protocolIsValid = (0,external_wp_url_namespaceObject.isValidProtocol)(protocol);
const mayBeTLD = hasPossibleTLD(val);
const isWWW = val?.startsWith('www.');
const isInternal = val?.startsWith('#') && (0,external_wp_url_namespaceObject.isValidFragment)(val);
return protocolIsValid || isWWW || isInternal || mayBeTLD;
}
/**
* Checks if a given URL has a valid Top-Level Domain (TLD).
*
* @param {string} url - The URL to check.
* @param {number} maxLength - The maximum length of the TLD.
* @return {boolean} Returns true if the URL has a valid TLD, false otherwise.
*/
function hasPossibleTLD(url, maxLength = 6) {
// Clean the URL by removing anything after the first occurrence of "?" or "#".
const cleanedURL = url.split(/[?#]/)[0];
// Regular expression explanation:
// - (?<=\S) : Positive lookbehind assertion to ensure there is at least one non-whitespace character before the TLD
// - \. : Matches a literal dot (.)
// - [a-zA-Z_]{2,maxLength} : Matches 2 to maxLength letters or underscores, representing the TLD
// - (?:\/|$) : Non-capturing group that matches either a forward slash (/) or the end of the string
const regex = new RegExp(`(?<=\\S)\\.(?:[a-zA-Z_]{2,${maxLength}})(?:\\/|$)`);
return regex.test(cleanedURL);
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/link-control/use-search-handler.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const handleNoop = () => Promise.resolve([]);
const handleDirectEntry = val => {
let type = URL_TYPE;
const protocol = (0,external_wp_url_namespaceObject.getProtocol)(val) || '';
if (protocol.includes('mailto')) {
type = MAILTO_TYPE;
}
if (protocol.includes('tel')) {
type = TEL_TYPE;
}
if (val?.startsWith('#')) {
type = INTERNAL_TYPE;
}
return Promise.resolve([{
id: val,
title: val,
url: type === 'URL' ? (0,external_wp_url_namespaceObject.prependHTTP)(val) : val,
type
}]);
};
const handleEntitySearch = async (val, suggestionsQuery, fetchSearchSuggestions, withCreateSuggestion, pageOnFront) => {
const {
isInitialSuggestions
} = suggestionsQuery;
const results = await fetchSearchSuggestions(val, suggestionsQuery);
// Identify front page and update type to match.
results.map(result => {
if (Number(result.id) === pageOnFront) {
result.isFrontPage = true;
return result;
}
return result;
});
// If displaying initial suggestions just return plain results.
if (isInitialSuggestions) {
return results;
}
// Here we append a faux suggestion to represent a "CREATE" option. This
// is detected in the rendering of the search results and handled as a
// special case. This is currently necessary because the suggestions
// dropdown will only appear if there are valid suggestions and
// therefore unless the create option is a suggestion it will not
// display in scenarios where there are no results returned from the
// API. In addition promoting CREATE to a first class suggestion affords
// the a11y benefits afforded by `URLInput` to all suggestions (eg:
// keyboard handling, ARIA roles...etc).
//
// Note also that the value of the `title` and `url` properties must correspond
// to the text value of the ``. This is because `title` is used
// when creating the suggestion. Similarly `url` is used when using keyboard to select
// the suggestion (the