@wordpress/core-data
Version:
Access to and manipulation of core WordPress entities.
119 lines (113 loc) • 3.71 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.updateFootnotesFromMeta = updateFootnotesFromMeta;
var _richText = require("@wordpress/rich-text");
var _getFootnotesOrder = _interopRequireDefault(require("./get-footnotes-order"));
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
let oldFootnotes = {};
function updateFootnotesFromMeta(blocks, meta) {
const output = {
blocks
};
if (!meta) {
return output;
}
// If meta.footnotes is empty, it means the meta is not registered.
if (meta.footnotes === undefined) {
return output;
}
const newOrder = (0, _getFootnotesOrder.default)(blocks);
const footnotes = meta.footnotes ? JSON.parse(meta.footnotes) : [];
const currentOrder = footnotes.map(fn => fn.id);
if (currentOrder.join('') === newOrder.join('')) {
return output;
}
const newFootnotes = newOrder.map(fnId => footnotes.find(fn => fn.id === fnId) || oldFootnotes[fnId] || {
id: fnId,
content: ''
});
function updateAttributes(attributes) {
// Only attempt to update attributes, if attributes is an object.
if (!attributes || Array.isArray(attributes) || typeof attributes !== 'object') {
return attributes;
}
attributes = {
...attributes
};
for (const key in attributes) {
const value = attributes[key];
if (Array.isArray(value)) {
attributes[key] = value.map(updateAttributes);
continue;
}
// To do, remove support for string values?
if (typeof value !== 'string' && !(value instanceof _richText.RichTextData)) {
continue;
}
const richTextValue = typeof value === 'string' ? _richText.RichTextData.fromHTMLString(value) : new _richText.RichTextData(value);
let hasFootnotes = false;
richTextValue.replacements.forEach(replacement => {
if (replacement.type === 'core/footnote') {
const id = replacement.attributes['data-fn'];
const index = newOrder.indexOf(id);
// The innerHTML contains the count wrapped in a link.
const countValue = (0, _richText.create)({
html: replacement.innerHTML
});
countValue.text = String(index + 1);
countValue.formats = Array.from({
length: countValue.text.length
}, () => countValue.formats[0]);
countValue.replacements = Array.from({
length: countValue.text.length
}, () => countValue.replacements[0]);
replacement.innerHTML = (0, _richText.toHTMLString)({
value: countValue
});
hasFootnotes = true;
}
});
if (hasFootnotes) {
attributes[key] = typeof value === 'string' ? richTextValue.toHTMLString() : richTextValue;
}
}
return attributes;
}
function updateBlocksAttributes(__blocks) {
return __blocks.map(block => {
return {
...block,
attributes: updateAttributes(block.attributes),
innerBlocks: updateBlocksAttributes(block.innerBlocks)
};
});
}
// We need to go through all block attributes deeply and update the
// footnote anchor numbering (textContent) to match the new order.
const newBlocks = updateBlocksAttributes(blocks);
oldFootnotes = {
...oldFootnotes,
...footnotes.reduce((acc, fn) => {
if (!newOrder.includes(fn.id)) {
acc[fn.id] = fn;
}
return acc;
}, {})
};
return {
meta: {
...meta,
footnotes: JSON.stringify(newFootnotes)
},
blocks: newBlocks
};
}
//# sourceMappingURL=index.js.map