| 1 |
"use strict"; |
| 2 |
var wp; |
| 3 |
(wp ||= {}).richText = (() => { |
| 4 |
var __create = Object.create; |
| 5 |
var __defProp = Object.defineProperty; |
| 6 |
var __getOwnPropDesc = Object.getOwnPropertyDescriptor; |
| 7 |
var __getOwnPropNames = Object.getOwnPropertyNames; |
| 8 |
var __getProtoOf = Object.getPrototypeOf; |
| 9 |
var __hasOwnProp = Object.prototype.hasOwnProperty; |
| 10 |
var __commonJS = (cb, mod) => function __require() { |
| 11 |
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; |
| 12 |
}; |
| 13 |
var __export = (target, all) => { |
| 14 |
for (var name in all) |
| 15 |
__defProp(target, name, { get: all[name], enumerable: true }); |
| 16 |
}; |
| 17 |
var __copyProps = (to, from, except, desc) => { |
| 18 |
if (from && typeof from === "object" || typeof from === "function") { |
| 19 |
for (let key of __getOwnPropNames(from)) |
| 20 |
if (!__hasOwnProp.call(to, key) && key !== except) |
| 21 |
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); |
| 22 |
} |
| 23 |
return to; |
| 24 |
}; |
| 25 |
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( |
| 26 |
// If the importer is in node compatibility mode or this is not an ESM |
| 27 |
// file that has been converted to a CommonJS file using a Babel- |
| 28 |
// compatible transform (i.e. "__esModule" has not been set), then set |
| 29 |
// "default" to the CommonJS "module.exports" for node compatibility. |
| 30 |
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, |
| 31 |
mod |
| 32 |
)); |
| 33 |
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); |
| 34 |
|
| 35 |
// package-external:@wordpress/data |
| 36 |
var require_data = __commonJS({ |
| 37 |
"package-external:@wordpress/data"(exports, module) { |
| 38 |
module.exports = window.wp.data; |
| 39 |
} |
| 40 |
}); |
| 41 |
|
| 42 |
// package-external:@wordpress/escape-html |
| 43 |
var require_escape_html = __commonJS({ |
| 44 |
"package-external:@wordpress/escape-html"(exports, module) { |
| 45 |
module.exports = window.wp.escapeHtml; |
| 46 |
} |
| 47 |
}); |
| 48 |
|
| 49 |
// package-external:@wordpress/a11y |
| 50 |
var require_a11y = __commonJS({ |
| 51 |
"package-external:@wordpress/a11y"(exports, module) { |
| 52 |
module.exports = window.wp.a11y; |
| 53 |
} |
| 54 |
}); |
| 55 |
|
| 56 |
// package-external:@wordpress/i18n |
| 57 |
var require_i18n = __commonJS({ |
| 58 |
"package-external:@wordpress/i18n"(exports, module) { |
| 59 |
module.exports = window.wp.i18n; |
| 60 |
} |
| 61 |
}); |
| 62 |
|
| 63 |
// package-external:@wordpress/private-apis |
| 64 |
var require_private_apis = __commonJS({ |
| 65 |
"package-external:@wordpress/private-apis"(exports, module) { |
| 66 |
module.exports = window.wp.privateApis; |
| 67 |
} |
| 68 |
}); |
| 69 |
|
| 70 |
// package-external:@wordpress/element |
| 71 |
var require_element = __commonJS({ |
| 72 |
"package-external:@wordpress/element"(exports, module) { |
| 73 |
module.exports = window.wp.element; |
| 74 |
} |
| 75 |
}); |
| 76 |
|
| 77 |
// package-external:@wordpress/compose |
| 78 |
var require_compose = __commonJS({ |
| 79 |
"package-external:@wordpress/compose"(exports, module) { |
| 80 |
module.exports = window.wp.compose; |
| 81 |
} |
| 82 |
}); |
| 83 |
|
| 84 |
// package-external:@wordpress/deprecated |
| 85 |
var require_deprecated = __commonJS({ |
| 86 |
"package-external:@wordpress/deprecated"(exports, module) { |
| 87 |
module.exports = window.wp.deprecated; |
| 88 |
} |
| 89 |
}); |
| 90 |
|
| 91 |
// package-external:@wordpress/keycodes |
| 92 |
var require_keycodes = __commonJS({ |
| 93 |
"package-external:@wordpress/keycodes"(exports, module) { |
| 94 |
module.exports = window.wp.keycodes; |
| 95 |
} |
| 96 |
}); |
| 97 |
|
| 98 |
// package-external:@wordpress/dom |
| 99 |
var require_dom = __commonJS({ |
| 100 |
"package-external:@wordpress/dom"(exports, module) { |
| 101 |
module.exports = window.wp.dom; |
| 102 |
} |
| 103 |
}); |
| 104 |
|
| 105 |
// packages/rich-text/build-module/index.mjs |
| 106 |
var index_exports = {}; |
| 107 |
__export(index_exports, { |
| 108 |
RichTextData: () => RichTextData, |
| 109 |
__experimentalRichText: () => __experimentalRichText, |
| 110 |
__unstableCreateElement: () => createElement, |
| 111 |
__unstableToDom: () => toDom, |
| 112 |
__unstableUseRichText: () => useDeprecatedRichText, |
| 113 |
applyFormat: () => applyFormat, |
| 114 |
concat: () => concat, |
| 115 |
create: () => create, |
| 116 |
getActiveFormat: () => getActiveFormat, |
| 117 |
getActiveFormats: () => getActiveFormats, |
| 118 |
getActiveObject: () => getActiveObject, |
| 119 |
getTextContent: () => getTextContent, |
| 120 |
insert: () => insert, |
| 121 |
insertObject: () => insertObject, |
| 122 |
isCollapsed: () => isCollapsed, |
| 123 |
isEmpty: () => isEmpty, |
| 124 |
join: () => join, |
| 125 |
privateApis: () => privateApis, |
| 126 |
registerFormatType: () => registerFormatType, |
| 127 |
remove: () => remove2, |
| 128 |
removeFormat: () => removeFormat, |
| 129 |
replace: () => replace2, |
| 130 |
slice: () => slice, |
| 131 |
split: () => split, |
| 132 |
store: () => store, |
| 133 |
toHTMLString: () => toHTMLString, |
| 134 |
toggleFormat: () => toggleFormat, |
| 135 |
unregisterFormatType: () => unregisterFormatType, |
| 136 |
useAnchor: () => useAnchor, |
| 137 |
useAnchorRef: () => useAnchorRef |
| 138 |
}); |
| 139 |
|
| 140 |
// packages/rich-text/build-module/store/index.mjs |
| 141 |
var import_data3 = __toESM(require_data(), 1); |
| 142 |
|
| 143 |
// packages/rich-text/build-module/store/reducer.mjs |
| 144 |
var import_data = __toESM(require_data(), 1); |
| 145 |
function formatTypes(state = {}, action) { |
| 146 |
switch (action.type) { |
| 147 |
case "ADD_FORMAT_TYPES": |
| 148 |
return { |
| 149 |
...state, |
| 150 |
// Key format types by their name. |
| 151 |
...action.formatTypes.reduce( |
| 152 |
(newFormatTypes, type) => ({ |
| 153 |
...newFormatTypes, |
| 154 |
[type.name]: type |
| 155 |
}), |
| 156 |
{} |
| 157 |
) |
| 158 |
}; |
| 159 |
case "REMOVE_FORMAT_TYPES": |
| 160 |
return Object.fromEntries( |
| 161 |
Object.entries(state).filter( |
| 162 |
([key]) => !action.names.includes(key) |
| 163 |
) |
| 164 |
); |
| 165 |
} |
| 166 |
return state; |
| 167 |
} |
| 168 |
var reducer_default = (0, import_data.combineReducers)({ formatTypes }); |
| 169 |
|
| 170 |
// packages/rich-text/build-module/store/selectors.mjs |
| 171 |
var selectors_exports = {}; |
| 172 |
__export(selectors_exports, { |
| 173 |
getFormatType: () => getFormatType, |
| 174 |
getFormatTypeForBareElement: () => getFormatTypeForBareElement, |
| 175 |
getFormatTypeForClassName: () => getFormatTypeForClassName, |
| 176 |
getFormatTypes: () => getFormatTypes |
| 177 |
}); |
| 178 |
var import_data2 = __toESM(require_data(), 1); |
| 179 |
var getFormatTypes = (0, import_data2.createSelector)( |
| 180 |
(state) => Object.values(state.formatTypes), |
| 181 |
(state) => [state.formatTypes] |
| 182 |
); |
| 183 |
function getFormatType(state, name) { |
| 184 |
return state.formatTypes[name]; |
| 185 |
} |
| 186 |
function getFormatTypeForBareElement(state, bareElementTagName) { |
| 187 |
const formatTypes2 = getFormatTypes(state); |
| 188 |
return formatTypes2.find(({ className, tagName }) => { |
| 189 |
return className === null && bareElementTagName === tagName; |
| 190 |
}) || formatTypes2.find(({ className, tagName }) => { |
| 191 |
return className === null && "*" === tagName; |
| 192 |
}); |
| 193 |
} |
| 194 |
function getFormatTypeForClassName(state, elementClassName) { |
| 195 |
return getFormatTypes(state).find(({ className }) => { |
| 196 |
if (className === null) { |
| 197 |
return false; |
| 198 |
} |
| 199 |
return ` ${elementClassName} `.indexOf(` ${className} `) >= 0; |
| 200 |
}); |
| 201 |
} |
| 202 |
|
| 203 |
// packages/rich-text/build-module/store/actions.mjs |
| 204 |
var actions_exports = {}; |
| 205 |
__export(actions_exports, { |
| 206 |
addFormatTypes: () => addFormatTypes, |
| 207 |
removeFormatTypes: () => removeFormatTypes |
| 208 |
}); |
| 209 |
function addFormatTypes(formatTypes2) { |
| 210 |
return { |
| 211 |
type: "ADD_FORMAT_TYPES", |
| 212 |
formatTypes: Array.isArray(formatTypes2) ? formatTypes2 : [formatTypes2] |
| 213 |
}; |
| 214 |
} |
| 215 |
function removeFormatTypes(names) { |
| 216 |
return { |
| 217 |
type: "REMOVE_FORMAT_TYPES", |
| 218 |
names: Array.isArray(names) ? names : [names] |
| 219 |
}; |
| 220 |
} |
| 221 |
|
| 222 |
// packages/rich-text/build-module/store/index.mjs |
| 223 |
var STORE_NAME = "core/rich-text"; |
| 224 |
var store = (0, import_data3.createReduxStore)(STORE_NAME, { |
| 225 |
reducer: reducer_default, |
| 226 |
selectors: selectors_exports, |
| 227 |
actions: actions_exports |
| 228 |
}); |
| 229 |
(0, import_data3.register)(store); |
| 230 |
|
| 231 |
// packages/rich-text/build-module/is-format-equal.mjs |
| 232 |
function isFormatEqual(format1, format2) { |
| 233 |
if (format1 === format2) { |
| 234 |
return true; |
| 235 |
} |
| 236 |
if (!format1 || !format2) { |
| 237 |
return false; |
| 238 |
} |
| 239 |
if (format1.type !== format2.type) { |
| 240 |
return false; |
| 241 |
} |
| 242 |
const attributes1 = format1.attributes; |
| 243 |
const attributes2 = format2.attributes; |
| 244 |
if (attributes1 === attributes2) { |
| 245 |
return true; |
| 246 |
} |
| 247 |
if (!attributes1 || !attributes2) { |
| 248 |
return false; |
| 249 |
} |
| 250 |
const keys1 = Object.keys(attributes1); |
| 251 |
const keys2 = Object.keys(attributes2); |
| 252 |
if (keys1.length !== keys2.length) { |
| 253 |
return false; |
| 254 |
} |
| 255 |
const length = keys1.length; |
| 256 |
for (let i2 = 0; i2 < length; i2++) { |
| 257 |
const name = keys1[i2]; |
| 258 |
if (attributes1[name] !== attributes2[name]) { |
| 259 |
return false; |
| 260 |
} |
| 261 |
} |
| 262 |
return true; |
| 263 |
} |
| 264 |
|
| 265 |
// packages/rich-text/build-module/normalise-formats.mjs |
| 266 |
function normaliseFormats(value) { |
| 267 |
const newFormats = value.formats.slice(); |
| 268 |
newFormats.forEach((formatsAtIndex, index) => { |
| 269 |
const formatsAtPreviousIndex = newFormats[index - 1]; |
| 270 |
if (formatsAtPreviousIndex) { |
| 271 |
const newFormatsAtIndex = formatsAtIndex.slice(); |
| 272 |
newFormatsAtIndex.forEach((format, formatIndex) => { |
| 273 |
const previousFormat = formatsAtPreviousIndex[formatIndex]; |
| 274 |
if (isFormatEqual(format, previousFormat)) { |
| 275 |
newFormatsAtIndex[formatIndex] = previousFormat; |
| 276 |
} |
| 277 |
}); |
| 278 |
newFormats[index] = newFormatsAtIndex; |
| 279 |
} |
| 280 |
}); |
| 281 |
return { |
| 282 |
...value, |
| 283 |
formats: newFormats |
| 284 |
}; |
| 285 |
} |
| 286 |
|
| 287 |
// packages/rich-text/build-module/apply-format.mjs |
| 288 |
function replace(array, index, value) { |
| 289 |
array = array.slice(); |
| 290 |
array[index] = value; |
| 291 |
return array; |
| 292 |
} |
| 293 |
function applyFormat(value, format, startIndex = value.start, endIndex = value.end) { |
| 294 |
const { formats, activeFormats } = value; |
| 295 |
const newFormats = formats.slice(); |
| 296 |
if (startIndex === endIndex) { |
| 297 |
const startFormat = newFormats[startIndex]?.find( |
| 298 |
({ type }) => type === format.type |
| 299 |
); |
| 300 |
if (startFormat) { |
| 301 |
const index = newFormats[startIndex].indexOf(startFormat); |
| 302 |
while (newFormats[startIndex] && newFormats[startIndex][index] === startFormat) { |
| 303 |
newFormats[startIndex] = replace( |
| 304 |
newFormats[startIndex], |
| 305 |
index, |
| 306 |
format |
| 307 |
); |
| 308 |
startIndex--; |
| 309 |
} |
| 310 |
endIndex++; |
| 311 |
while (newFormats[endIndex] && newFormats[endIndex][index] === startFormat) { |
| 312 |
newFormats[endIndex] = replace( |
| 313 |
newFormats[endIndex], |
| 314 |
index, |
| 315 |
format |
| 316 |
); |
| 317 |
endIndex++; |
| 318 |
} |
| 319 |
} |
| 320 |
} else { |
| 321 |
let position = Infinity; |
| 322 |
for (let index = startIndex; index < endIndex; index++) { |
| 323 |
if (newFormats[index]) { |
| 324 |
newFormats[index] = newFormats[index].filter( |
| 325 |
({ type }) => type !== format.type |
| 326 |
); |
| 327 |
const length = newFormats[index].length; |
| 328 |
if (length < position) { |
| 329 |
position = length; |
| 330 |
} |
| 331 |
} else { |
| 332 |
newFormats[index] = []; |
| 333 |
position = 0; |
| 334 |
} |
| 335 |
} |
| 336 |
for (let index = startIndex; index < endIndex; index++) { |
| 337 |
newFormats[index].splice(position, 0, format); |
| 338 |
} |
| 339 |
} |
| 340 |
return normaliseFormats({ |
| 341 |
...value, |
| 342 |
formats: newFormats, |
| 343 |
// Always revise active formats. This serves as a placeholder for new |
| 344 |
// inputs with the format so new input appears with the format applied, |
| 345 |
// and ensures a format of the same type uses the latest values. |
| 346 |
activeFormats: [ |
| 347 |
...activeFormats?.filter( |
| 348 |
({ type }) => type !== format.type |
| 349 |
) || [], |
| 350 |
format |
| 351 |
] |
| 352 |
}); |
| 353 |
} |
| 354 |
|
| 355 |
// packages/rich-text/build-module/create.mjs |
| 356 |
var import_data5 = __toESM(require_data(), 1); |
| 357 |
|
| 358 |
// packages/rich-text/build-module/create-element.mjs |
| 359 |
function createElement({ implementation }, html) { |
| 360 |
if (!createElement.body) { |
| 361 |
createElement.body = implementation.createHTMLDocument("").body; |
| 362 |
} |
| 363 |
createElement.body.innerHTML = html; |
| 364 |
return createElement.body; |
| 365 |
} |
| 366 |
|
| 367 |
// packages/rich-text/build-module/special-characters.mjs |
| 368 |
var OBJECT_REPLACEMENT_CHARACTER = "\uFFFC"; |
| 369 |
var ZWNBSP = "\uFEFF"; |
| 370 |
|
| 371 |
// packages/rich-text/build-module/to-html-string.mjs |
| 372 |
var import_escape_html = __toESM(require_escape_html(), 1); |
| 373 |
|
| 374 |
// packages/rich-text/build-module/get-active-formats.mjs |
| 375 |
function getActiveFormats(value, EMPTY_ACTIVE_FORMATS3 = []) { |
| 376 |
const { formats, start, end, activeFormats } = value; |
| 377 |
if (start === void 0) { |
| 378 |
return EMPTY_ACTIVE_FORMATS3; |
| 379 |
} |
| 380 |
if (start === end) { |
| 381 |
if (activeFormats) { |
| 382 |
return activeFormats; |
| 383 |
} |
| 384 |
const formatsBefore = formats[start - 1] || EMPTY_ACTIVE_FORMATS3; |
| 385 |
const formatsAfter = formats[start] || EMPTY_ACTIVE_FORMATS3; |
| 386 |
if (formatsBefore.length < formatsAfter.length) { |
| 387 |
return formatsBefore; |
| 388 |
} |
| 389 |
return formatsAfter; |
| 390 |
} |
| 391 |
if (!formats[start]) { |
| 392 |
return EMPTY_ACTIVE_FORMATS3; |
| 393 |
} |
| 394 |
const selectedFormats = formats.slice(start, end); |
| 395 |
const _activeFormats = [...selectedFormats[0]]; |
| 396 |
let i2 = selectedFormats.length; |
| 397 |
while (i2--) { |
| 398 |
const formatsAtIndex = selectedFormats[i2]; |
| 399 |
if (!formatsAtIndex) { |
| 400 |
return EMPTY_ACTIVE_FORMATS3; |
| 401 |
} |
| 402 |
let ii = _activeFormats.length; |
| 403 |
while (ii--) { |
| 404 |
const format = _activeFormats[ii]; |
| 405 |
if (!formatsAtIndex.find( |
| 406 |
(_format) => isFormatEqual(format, _format) |
| 407 |
)) { |
| 408 |
_activeFormats.splice(ii, 1); |
| 409 |
} |
| 410 |
} |
| 411 |
if (_activeFormats.length === 0) { |
| 412 |
return EMPTY_ACTIVE_FORMATS3; |
| 413 |
} |
| 414 |
} |
| 415 |
return _activeFormats || EMPTY_ACTIVE_FORMATS3; |
| 416 |
} |
| 417 |
|
| 418 |
// packages/rich-text/build-module/get-format-type.mjs |
| 419 |
var import_data4 = __toESM(require_data(), 1); |
| 420 |
function getFormatType2(name) { |
| 421 |
return (0, import_data4.select)(store).getFormatType(name); |
| 422 |
} |
| 423 |
|
| 424 |
// packages/rich-text/build-module/to-tree.mjs |
| 425 |
function restoreOnAttributes(attributes, isEditableTree) { |
| 426 |
if (isEditableTree) { |
| 427 |
return attributes; |
| 428 |
} |
| 429 |
const newAttributes = {}; |
| 430 |
for (const key in attributes) { |
| 431 |
let newKey = key; |
| 432 |
if (key.startsWith("data-disable-rich-text-")) { |
| 433 |
newKey = key.slice("data-disable-rich-text-".length); |
| 434 |
} |
| 435 |
newAttributes[newKey] = attributes[key]; |
| 436 |
} |
| 437 |
return newAttributes; |
| 438 |
} |
| 439 |
function fromFormat({ |
| 440 |
type, |
| 441 |
tagName, |
| 442 |
attributes, |
| 443 |
unregisteredAttributes, |
| 444 |
object, |
| 445 |
boundaryClass, |
| 446 |
isEditableTree |
| 447 |
}) { |
| 448 |
const formatType = getFormatType2(type); |
| 449 |
let elementAttributes = {}; |
| 450 |
if (boundaryClass && isEditableTree) { |
| 451 |
elementAttributes["data-rich-text-format-boundary"] = "true"; |
| 452 |
} |
| 453 |
if (!formatType) { |
| 454 |
if (attributes) { |
| 455 |
elementAttributes = { ...attributes, ...elementAttributes }; |
| 456 |
} |
| 457 |
return { |
| 458 |
type, |
| 459 |
attributes: restoreOnAttributes( |
| 460 |
elementAttributes, |
| 461 |
isEditableTree |
| 462 |
), |
| 463 |
object |
| 464 |
}; |
| 465 |
} |
| 466 |
elementAttributes = { ...unregisteredAttributes, ...elementAttributes }; |
| 467 |
for (const name in attributes) { |
| 468 |
const key = formatType.attributes ? formatType.attributes[name] : false; |
| 469 |
if (key) { |
| 470 |
elementAttributes[key] = attributes[name]; |
| 471 |
} else { |
| 472 |
elementAttributes[name] = attributes[name]; |
| 473 |
} |
| 474 |
} |
| 475 |
if (formatType.className) { |
| 476 |
if (elementAttributes.class) { |
| 477 |
elementAttributes.class = `${formatType.className} ${elementAttributes.class}`; |
| 478 |
} else { |
| 479 |
elementAttributes.class = formatType.className; |
| 480 |
} |
| 481 |
} |
| 482 |
return { |
| 483 |
type: tagName || formatType.tagName, |
| 484 |
object: formatType.object, |
| 485 |
attributes: restoreOnAttributes(elementAttributes, isEditableTree) |
| 486 |
}; |
| 487 |
} |
| 488 |
function isEqualUntil(a2, b2, index) { |
| 489 |
do { |
| 490 |
if (a2[index] !== b2[index]) { |
| 491 |
return false; |
| 492 |
} |
| 493 |
} while (index--); |
| 494 |
return true; |
| 495 |
} |
| 496 |
function toTree({ |
| 497 |
value, |
| 498 |
preserveWhiteSpace, |
| 499 |
createEmpty: createEmpty2, |
| 500 |
append: append3, |
| 501 |
getLastChild: getLastChild3, |
| 502 |
getParent: getParent3, |
| 503 |
isText: isText3, |
| 504 |
getText: getText3, |
| 505 |
remove: remove4, |
| 506 |
appendText: appendText3, |
| 507 |
onStartIndex, |
| 508 |
onEndIndex, |
| 509 |
isEditableTree, |
| 510 |
placeholder |
| 511 |
}) { |
| 512 |
const { formats, replacements, text, start, end } = value; |
| 513 |
const formatsLength = formats.length + 1; |
| 514 |
const tree = createEmpty2(); |
| 515 |
const activeFormats = getActiveFormats(value); |
| 516 |
const deepestActiveFormat = activeFormats[activeFormats.length - 1]; |
| 517 |
let lastCharacterFormats; |
| 518 |
let lastCharacter; |
| 519 |
append3(tree, ""); |
| 520 |
for (let i2 = 0; i2 < formatsLength; i2++) { |
| 521 |
const character = text.charAt(i2); |
| 522 |
const shouldInsertPadding = isEditableTree && // Pad the line if the line is empty. |
| 523 |
(!lastCharacter || // Pad the line if the previous character is a line break, otherwise |
| 524 |
// the line break won't be visible. |
| 525 |
lastCharacter === "\n"); |
| 526 |
const characterFormats = formats[i2]; |
| 527 |
let pointer = getLastChild3(tree); |
| 528 |
if (characterFormats) { |
| 529 |
characterFormats.forEach((format, formatIndex) => { |
| 530 |
if (pointer && lastCharacterFormats && // Reuse the last element if all formats remain the same. |
| 531 |
isEqualUntil( |
| 532 |
characterFormats, |
| 533 |
lastCharacterFormats, |
| 534 |
formatIndex |
| 535 |
)) { |
| 536 |
pointer = getLastChild3(pointer); |
| 537 |
return; |
| 538 |
} |
| 539 |
const { type, tagName, attributes, unregisteredAttributes } = format; |
| 540 |
const boundaryClass = isEditableTree && format === deepestActiveFormat; |
| 541 |
const parent = getParent3(pointer); |
| 542 |
const newNode = append3( |
| 543 |
parent, |
| 544 |
fromFormat({ |
| 545 |
type, |
| 546 |
tagName, |
| 547 |
attributes, |
| 548 |
unregisteredAttributes, |
| 549 |
boundaryClass, |
| 550 |
isEditableTree |
| 551 |
}) |
| 552 |
); |
| 553 |
if (isText3(pointer) && getText3(pointer).length === 0) { |
| 554 |
remove4(pointer); |
| 555 |
} |
| 556 |
pointer = append3(newNode, ""); |
| 557 |
}); |
| 558 |
} |
| 559 |
if (i2 === 0) { |
| 560 |
if (onStartIndex && start === 0) { |
| 561 |
onStartIndex(tree, pointer); |
| 562 |
} |
| 563 |
if (onEndIndex && end === 0) { |
| 564 |
onEndIndex(tree, pointer); |
| 565 |
} |
| 566 |
} |
| 567 |
if (character === OBJECT_REPLACEMENT_CHARACTER) { |
| 568 |
const replacement = replacements[i2]; |
| 569 |
if (!replacement) { |
| 570 |
continue; |
| 571 |
} |
| 572 |
const { type, attributes, innerHTML } = replacement; |
| 573 |
const formatType = getFormatType2(type); |
| 574 |
if (isEditableTree && type === "#comment") { |
| 575 |
pointer = append3(getParent3(pointer), { |
| 576 |
type: "span", |
| 577 |
attributes: { |
| 578 |
contenteditable: "false", |
| 579 |
"data-rich-text-comment": attributes["data-rich-text-comment"] |
| 580 |
} |
| 581 |
}); |
| 582 |
append3( |
| 583 |
append3(pointer, { type: "span" }), |
| 584 |
attributes["data-rich-text-comment"].trim() |
| 585 |
); |
| 586 |
} else if (!isEditableTree && type === "script") { |
| 587 |
pointer = append3( |
| 588 |
getParent3(pointer), |
| 589 |
fromFormat({ |
| 590 |
type: "script", |
| 591 |
isEditableTree |
| 592 |
}) |
| 593 |
); |
| 594 |
append3(pointer, { |
| 595 |
html: decodeURIComponent( |
| 596 |
attributes["data-rich-text-script"] |
| 597 |
) |
| 598 |
}); |
| 599 |
} else if (formatType?.contentEditable === false) { |
| 600 |
if (innerHTML || isEditableTree) { |
| 601 |
pointer = getParent3(pointer); |
| 602 |
if (isEditableTree) { |
| 603 |
const attrs = { |
| 604 |
contenteditable: "false", |
| 605 |
"data-rich-text-bogus": true |
| 606 |
}; |
| 607 |
if (start === i2 && end === i2 + 1) { |
| 608 |
attrs["data-rich-text-format-boundary"] = true; |
| 609 |
} |
| 610 |
pointer = append3(pointer, { |
| 611 |
type: "span", |
| 612 |
attributes: attrs |
| 613 |
}); |
| 614 |
if (isEditableTree && i2 + 1 === text.length) { |
| 615 |
append3(getParent3(pointer), ZWNBSP); |
| 616 |
} |
| 617 |
} |
| 618 |
pointer = append3( |
| 619 |
pointer, |
| 620 |
fromFormat({ |
| 621 |
...replacement, |
| 622 |
isEditableTree |
| 623 |
}) |
| 624 |
); |
| 625 |
if (innerHTML) { |
| 626 |
append3(pointer, { |
| 627 |
html: innerHTML |
| 628 |
}); |
| 629 |
} |
| 630 |
} |
| 631 |
} else { |
| 632 |
pointer = append3( |
| 633 |
getParent3(pointer), |
| 634 |
fromFormat({ |
| 635 |
...replacement, |
| 636 |
object: true, |
| 637 |
isEditableTree |
| 638 |
}) |
| 639 |
); |
| 640 |
} |
| 641 |
pointer = append3(getParent3(pointer), ""); |
| 642 |
} else if (!preserveWhiteSpace && character === "\n") { |
| 643 |
pointer = append3(getParent3(pointer), { |
| 644 |
type: "br", |
| 645 |
attributes: isEditableTree ? { |
| 646 |
"data-rich-text-line-break": "true" |
| 647 |
} : void 0, |
| 648 |
object: true |
| 649 |
}); |
| 650 |
pointer = append3(getParent3(pointer), ""); |
| 651 |
} else if (!isText3(pointer)) { |
| 652 |
pointer = append3(getParent3(pointer), character); |
| 653 |
} else { |
| 654 |
appendText3(pointer, character); |
| 655 |
} |
| 656 |
if (onStartIndex && start === i2 + 1) { |
| 657 |
onStartIndex(tree, pointer); |
| 658 |
} |
| 659 |
if (onEndIndex && end === i2 + 1) { |
| 660 |
onEndIndex(tree, pointer); |
| 661 |
} |
| 662 |
if (shouldInsertPadding && i2 === text.length) { |
| 663 |
append3(getParent3(pointer), ZWNBSP); |
| 664 |
if (placeholder && text.length === 0) { |
| 665 |
append3(getParent3(pointer), { |
| 666 |
type: "span", |
| 667 |
attributes: { |
| 668 |
"data-rich-text-placeholder": placeholder, |
| 669 |
// Necessary to prevent the placeholder from catching |
| 670 |
// selection and being editable. |
| 671 |
style: "pointer-events:none;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;" |
| 672 |
} |
| 673 |
}); |
| 674 |
} |
| 675 |
} |
| 676 |
lastCharacterFormats = characterFormats; |
| 677 |
lastCharacter = character; |
| 678 |
} |
| 679 |
return tree; |
| 680 |
} |
| 681 |
|
| 682 |
// packages/rich-text/build-module/to-html-string.mjs |
| 683 |
function toHTMLString({ value, preserveWhiteSpace }) { |
| 684 |
const tree = toTree({ |
| 685 |
value, |
| 686 |
preserveWhiteSpace, |
| 687 |
createEmpty, |
| 688 |
append, |
| 689 |
getLastChild, |
| 690 |
getParent, |
| 691 |
isText, |
| 692 |
getText, |
| 693 |
remove, |
| 694 |
appendText |
| 695 |
}); |
| 696 |
return createChildrenHTML(tree.children); |
| 697 |
} |
| 698 |
function createEmpty() { |
| 699 |
return {}; |
| 700 |
} |
| 701 |
function getLastChild({ children }) { |
| 702 |
return children && children[children.length - 1]; |
| 703 |
} |
| 704 |
function append(parent, object) { |
| 705 |
if (typeof object === "string") { |
| 706 |
object = { text: object }; |
| 707 |
} |
| 708 |
object.parent = parent; |
| 709 |
parent.children = parent.children || []; |
| 710 |
parent.children.push(object); |
| 711 |
return object; |
| 712 |
} |
| 713 |
function appendText(object, text) { |
| 714 |
object.text += text; |
| 715 |
} |
| 716 |
function getParent({ parent }) { |
| 717 |
return parent; |
| 718 |
} |
| 719 |
function isText({ text }) { |
| 720 |
return typeof text === "string"; |
| 721 |
} |
| 722 |
function getText({ text }) { |
| 723 |
return text; |
| 724 |
} |
| 725 |
function remove(object) { |
| 726 |
const index = object.parent.children.indexOf(object); |
| 727 |
if (index !== -1) { |
| 728 |
object.parent.children.splice(index, 1); |
| 729 |
} |
| 730 |
return object; |
| 731 |
} |
| 732 |
function createElementHTML({ type, attributes, object, children }) { |
| 733 |
if (type === "#comment") { |
| 734 |
return `<!--${attributes["data-rich-text-comment"]}-->`; |
| 735 |
} |
| 736 |
let attributeString = ""; |
| 737 |
for (const key in attributes) { |
| 738 |
if (!(0, import_escape_html.isValidAttributeName)(key)) { |
| 739 |
continue; |
| 740 |
} |
| 741 |
attributeString += ` ${key}="${(0, import_escape_html.escapeAttribute)( |
| 742 |
attributes[key] |
| 743 |
)}"`; |
| 744 |
} |
| 745 |
if (object) { |
| 746 |
return `<${type}${attributeString}>`; |
| 747 |
} |
| 748 |
return `<${type}${attributeString}>${createChildrenHTML( |
| 749 |
children |
| 750 |
)}</${type}>`; |
| 751 |
} |
| 752 |
function createChildrenHTML(children = []) { |
| 753 |
return children.map((child) => { |
| 754 |
if (child.html !== void 0) { |
| 755 |
return child.html; |
| 756 |
} |
| 757 |
return child.text === void 0 ? createElementHTML(child) : (0, import_escape_html.escapeEditableHTML)(child.text); |
| 758 |
}).join(""); |
| 759 |
} |
| 760 |
|
| 761 |
// packages/rich-text/build-module/get-text-content.mjs |
| 762 |
function getTextContent({ text }) { |
| 763 |
return text.replace(OBJECT_REPLACEMENT_CHARACTER, ""); |
| 764 |
} |
| 765 |
|
| 766 |
// packages/rich-text/build-module/create.mjs |
| 767 |
function createEmptyValue() { |
| 768 |
return { |
| 769 |
formats: [], |
| 770 |
replacements: [], |
| 771 |
text: "" |
| 772 |
}; |
| 773 |
} |
| 774 |
function toFormat({ tagName, attributes }) { |
| 775 |
let formatType; |
| 776 |
if (attributes && attributes.class) { |
| 777 |
formatType = (0, import_data5.select)(store).getFormatTypeForClassName( |
| 778 |
attributes.class |
| 779 |
); |
| 780 |
if (formatType) { |
| 781 |
attributes.class = ` ${attributes.class} `.replace(` ${formatType.className} `, " ").trim(); |
| 782 |
if (!attributes.class) { |
| 783 |
delete attributes.class; |
| 784 |
} |
| 785 |
} |
| 786 |
} |
| 787 |
if (!formatType) { |
| 788 |
formatType = (0, import_data5.select)(store).getFormatTypeForBareElement(tagName); |
| 789 |
} |
| 790 |
if (!formatType) { |
| 791 |
return attributes ? { type: tagName, attributes } : { type: tagName }; |
| 792 |
} |
| 793 |
if (formatType.__experimentalCreatePrepareEditableTree && !formatType.__experimentalCreateOnChangeEditableValue) { |
| 794 |
return null; |
| 795 |
} |
| 796 |
if (!attributes) { |
| 797 |
return { formatType, type: formatType.name, tagName }; |
| 798 |
} |
| 799 |
const registeredAttributes = {}; |
| 800 |
const unregisteredAttributes = {}; |
| 801 |
const _attributes = { ...attributes }; |
| 802 |
for (const key in formatType.attributes) { |
| 803 |
const name = formatType.attributes[key]; |
| 804 |
registeredAttributes[key] = _attributes[name]; |
| 805 |
delete _attributes[name]; |
| 806 |
if (typeof registeredAttributes[key] === "undefined") { |
| 807 |
delete registeredAttributes[key]; |
| 808 |
} |
| 809 |
} |
| 810 |
for (const name in _attributes) { |
| 811 |
unregisteredAttributes[name] = attributes[name]; |
| 812 |
} |
| 813 |
if (formatType.contentEditable === false) { |
| 814 |
delete unregisteredAttributes.contenteditable; |
| 815 |
} |
| 816 |
return { |
| 817 |
formatType, |
| 818 |
type: formatType.name, |
| 819 |
tagName, |
| 820 |
attributes: registeredAttributes, |
| 821 |
unregisteredAttributes |
| 822 |
}; |
| 823 |
} |
| 824 |
var RichTextData = class _RichTextData { |
| 825 |
#value; |
| 826 |
static empty() { |
| 827 |
return new _RichTextData(); |
| 828 |
} |
| 829 |
static fromPlainText(text) { |
| 830 |
return new _RichTextData(create({ text })); |
| 831 |
} |
| 832 |
static fromHTMLString(html) { |
| 833 |
return new _RichTextData(create({ html })); |
| 834 |
} |
| 835 |
/** |
| 836 |
* Create a RichTextData instance from an HTML element. |
| 837 |
* |
| 838 |
* @param {HTMLElement} htmlElement The HTML element to create the instance from. |
| 839 |
* @param {{preserveWhiteSpace?: boolean}} options Options. |
| 840 |
* @return {RichTextData} The RichTextData instance. |
| 841 |
*/ |
| 842 |
static fromHTMLElement(htmlElement, options = {}) { |
| 843 |
const { preserveWhiteSpace = false } = options; |
| 844 |
const element = preserveWhiteSpace ? htmlElement : collapseWhiteSpace(htmlElement); |
| 845 |
const richTextData = new _RichTextData(create({ element })); |
| 846 |
Object.defineProperty(richTextData, "originalHTML", { |
| 847 |
value: htmlElement.innerHTML |
| 848 |
}); |
| 849 |
return richTextData; |
| 850 |
} |
| 851 |
constructor(init = createEmptyValue()) { |
| 852 |
this.#value = init; |
| 853 |
} |
| 854 |
toPlainText() { |
| 855 |
return getTextContent(this.#value); |
| 856 |
} |
| 857 |
// We could expose `toHTMLElement` at some point as well, but we'd only use |
| 858 |
// it internally. |
| 859 |
/** |
| 860 |
* Convert the rich text value to an HTML string. |
| 861 |
* |
| 862 |
* @param {{preserveWhiteSpace?: boolean}} options Options. |
| 863 |
* @return {string} The HTML string. |
| 864 |
*/ |
| 865 |
toHTMLString({ preserveWhiteSpace } = {}) { |
| 866 |
return this.originalHTML || toHTMLString({ value: this.#value, preserveWhiteSpace }); |
| 867 |
} |
| 868 |
valueOf() { |
| 869 |
return this.toHTMLString(); |
| 870 |
} |
| 871 |
toString() { |
| 872 |
return this.toHTMLString(); |
| 873 |
} |
| 874 |
toJSON() { |
| 875 |
return this.toHTMLString(); |
| 876 |
} |
| 877 |
get length() { |
| 878 |
return this.text.length; |
| 879 |
} |
| 880 |
get formats() { |
| 881 |
return this.#value.formats; |
| 882 |
} |
| 883 |
get replacements() { |
| 884 |
return this.#value.replacements; |
| 885 |
} |
| 886 |
get text() { |
| 887 |
return this.#value.text; |
| 888 |
} |
| 889 |
}; |
| 890 |
for (const name of Object.getOwnPropertyNames(String.prototype)) { |
| 891 |
if (RichTextData.prototype.hasOwnProperty(name)) { |
| 892 |
continue; |
| 893 |
} |
| 894 |
Object.defineProperty(RichTextData.prototype, name, { |
| 895 |
value(...args) { |
| 896 |
return this.toHTMLString()[name](...args); |
| 897 |
} |
| 898 |
}); |
| 899 |
} |
| 900 |
function create({ |
| 901 |
element, |
| 902 |
text, |
| 903 |
html, |
| 904 |
range, |
| 905 |
__unstableIsEditableTree: isEditableTree |
| 906 |
} = {}) { |
| 907 |
if (html instanceof RichTextData) { |
| 908 |
return { |
| 909 |
text: html.text, |
| 910 |
formats: html.formats, |
| 911 |
replacements: html.replacements |
| 912 |
}; |
| 913 |
} |
| 914 |
if (typeof text === "string" && text.length > 0) { |
| 915 |
return { |
| 916 |
formats: Array(text.length), |
| 917 |
replacements: Array(text.length), |
| 918 |
text |
| 919 |
}; |
| 920 |
} |
| 921 |
if (typeof html === "string" && html.length > 0) { |
| 922 |
element = createElement(document, html); |
| 923 |
} |
| 924 |
if (typeof element !== "object") { |
| 925 |
return createEmptyValue(); |
| 926 |
} |
| 927 |
return createFromElement({ |
| 928 |
element, |
| 929 |
range, |
| 930 |
isEditableTree |
| 931 |
}); |
| 932 |
} |
| 933 |
function accumulateSelection(accumulator, node, range, value) { |
| 934 |
if (!range) { |
| 935 |
return; |
| 936 |
} |
| 937 |
const { parentNode } = node; |
| 938 |
const { startContainer, startOffset, endContainer, endOffset } = range; |
| 939 |
const currentLength = accumulator.text.length; |
| 940 |
if (value.start !== void 0) { |
| 941 |
accumulator.start = currentLength + value.start; |
| 942 |
} else if (node === startContainer && node.nodeType === node.TEXT_NODE) { |
| 943 |
accumulator.start = currentLength + startOffset; |
| 944 |
} else if (parentNode === startContainer && node === startContainer.childNodes[startOffset]) { |
| 945 |
accumulator.start = currentLength; |
| 946 |
} else if (parentNode === startContainer && node === startContainer.childNodes[startOffset - 1]) { |
| 947 |
accumulator.start = currentLength + value.text.length; |
| 948 |
} else if (node === startContainer) { |
| 949 |
accumulator.start = currentLength; |
| 950 |
} |
| 951 |
if (value.end !== void 0) { |
| 952 |
accumulator.end = currentLength + value.end; |
| 953 |
} else if (node === endContainer && node.nodeType === node.TEXT_NODE) { |
| 954 |
accumulator.end = currentLength + endOffset; |
| 955 |
} else if (parentNode === endContainer && node === endContainer.childNodes[endOffset - 1]) { |
| 956 |
accumulator.end = currentLength + value.text.length; |
| 957 |
} else if (parentNode === endContainer && node === endContainer.childNodes[endOffset]) { |
| 958 |
accumulator.end = currentLength; |
| 959 |
} else if (node === endContainer) { |
| 960 |
accumulator.end = currentLength + endOffset; |
| 961 |
} |
| 962 |
} |
| 963 |
function filterRange(node, range, filter) { |
| 964 |
if (!range) { |
| 965 |
return; |
| 966 |
} |
| 967 |
const { startContainer, endContainer } = range; |
| 968 |
let { startOffset, endOffset } = range; |
| 969 |
if (node === startContainer) { |
| 970 |
startOffset = filter(node.nodeValue.slice(0, startOffset)).length; |
| 971 |
} |
| 972 |
if (node === endContainer) { |
| 973 |
endOffset = filter(node.nodeValue.slice(0, endOffset)).length; |
| 974 |
} |
| 975 |
return { startContainer, startOffset, endContainer, endOffset }; |
| 976 |
} |
| 977 |
function collapseWhiteSpace(element, isRoot = true, hasPrecedingSpace = false, hasTrailingSpace = false) { |
| 978 |
const clone = element.cloneNode(true); |
| 979 |
clone.normalize(); |
| 980 |
Array.from(clone.childNodes).forEach((node, i2, nodes) => { |
| 981 |
if (node.nodeType === node.TEXT_NODE) { |
| 982 |
let newNodeValue = node.nodeValue; |
| 983 |
if (/[\n\t\r\f]/.test(newNodeValue)) { |
| 984 |
newNodeValue = newNodeValue.replace(/[\n\t\r\f]+/g, " "); |
| 985 |
} |
| 986 |
if (newNodeValue.indexOf(" ") !== -1) { |
| 987 |
newNodeValue = newNodeValue.replace(/ {2,}/g, " "); |
| 988 |
} |
| 989 |
if (i2 === 0 && newNodeValue.startsWith(" ") && (isRoot || hasPrecedingSpace)) { |
| 990 |
newNodeValue = newNodeValue.slice(1); |
| 991 |
} |
| 992 |
if (i2 === nodes.length - 1 && newNodeValue.endsWith(" ") && (isRoot || hasTrailingSpace)) { |
| 993 |
newNodeValue = newNodeValue.slice(0, -1); |
| 994 |
} |
| 995 |
node.nodeValue = newNodeValue; |
| 996 |
} else if (node.nodeType === node.ELEMENT_NODE) { |
| 997 |
const { previousSibling, nextSibling } = node; |
| 998 |
const prevHasSpace = previousSibling?.textContent.endsWith(" "); |
| 999 |
const nextHasSpace = nextSibling?.textContent.startsWith(" "); |
| 1000 |
node.replaceWith( |
| 1001 |
collapseWhiteSpace( |
| 1002 |
node, |
| 1003 |
false, |
| 1004 |
previousSibling ? prevHasSpace : isRoot || hasPrecedingSpace, |
| 1005 |
nextSibling ? nextHasSpace : isRoot || hasTrailingSpace |
| 1006 |
) |
| 1007 |
); |
| 1008 |
} |
| 1009 |
}); |
| 1010 |
return clone; |
| 1011 |
} |
| 1012 |
var CARRIAGE_RETURN = "\r"; |
| 1013 |
function removeReservedCharacters(string) { |
| 1014 |
return string.replace( |
| 1015 |
new RegExp( |
| 1016 |
`[${ZWNBSP}${OBJECT_REPLACEMENT_CHARACTER}${CARRIAGE_RETURN}]`, |
| 1017 |
"gu" |
| 1018 |
), |
| 1019 |
"" |
| 1020 |
); |
| 1021 |
} |
| 1022 |
function createFromElement({ element, range, isEditableTree }) { |
| 1023 |
const accumulator = createEmptyValue(); |
| 1024 |
if (!element) { |
| 1025 |
return accumulator; |
| 1026 |
} |
| 1027 |
if (!element.hasChildNodes()) { |
| 1028 |
accumulateSelection(accumulator, element, range, createEmptyValue()); |
| 1029 |
return accumulator; |
| 1030 |
} |
| 1031 |
const length = element.childNodes.length; |
| 1032 |
for (let index = 0; index < length; index++) { |
| 1033 |
const node = element.childNodes[index]; |
| 1034 |
const tagName = node.nodeName.toLowerCase(); |
| 1035 |
if (node.nodeType === node.TEXT_NODE) { |
| 1036 |
const text = removeReservedCharacters(node.nodeValue); |
| 1037 |
range = filterRange(node, range, removeReservedCharacters); |
| 1038 |
accumulateSelection(accumulator, node, range, { text }); |
| 1039 |
accumulator.formats.length += text.length; |
| 1040 |
accumulator.replacements.length += text.length; |
| 1041 |
accumulator.text += text; |
| 1042 |
continue; |
| 1043 |
} |
| 1044 |
if (node.nodeType === node.COMMENT_NODE || node.nodeType === node.ELEMENT_NODE && node.tagName === "SPAN" && node.hasAttribute("data-rich-text-comment")) { |
| 1045 |
const value2 = { |
| 1046 |
formats: [,], |
| 1047 |
replacements: [ |
| 1048 |
{ |
| 1049 |
type: "#comment", |
| 1050 |
attributes: { |
| 1051 |
"data-rich-text-comment": node.nodeType === node.COMMENT_NODE ? node.nodeValue : node.getAttribute( |
| 1052 |
"data-rich-text-comment" |
| 1053 |
) |
| 1054 |
} |
| 1055 |
} |
| 1056 |
], |
| 1057 |
text: OBJECT_REPLACEMENT_CHARACTER |
| 1058 |
}; |
| 1059 |
accumulateSelection(accumulator, node, range, value2); |
| 1060 |
mergePair(accumulator, value2); |
| 1061 |
continue; |
| 1062 |
} |
| 1063 |
if (node.nodeType !== node.ELEMENT_NODE) { |
| 1064 |
continue; |
| 1065 |
} |
| 1066 |
if (isEditableTree && // Ignore any line breaks that are not inserted by us. |
| 1067 |
tagName === "br" && !node.getAttribute("data-rich-text-line-break")) { |
| 1068 |
accumulateSelection(accumulator, node, range, createEmptyValue()); |
| 1069 |
continue; |
| 1070 |
} |
| 1071 |
if (tagName === "script") { |
| 1072 |
const value2 = { |
| 1073 |
formats: [,], |
| 1074 |
replacements: [ |
| 1075 |
{ |
| 1076 |
type: tagName, |
| 1077 |
attributes: { |
| 1078 |
"data-rich-text-script": node.getAttribute("data-rich-text-script") || encodeURIComponent(node.innerHTML) |
| 1079 |
} |
| 1080 |
} |
| 1081 |
], |
| 1082 |
text: OBJECT_REPLACEMENT_CHARACTER |
| 1083 |
}; |
| 1084 |
accumulateSelection(accumulator, node, range, value2); |
| 1085 |
mergePair(accumulator, value2); |
| 1086 |
continue; |
| 1087 |
} |
| 1088 |
if (tagName === "br") { |
| 1089 |
accumulateSelection(accumulator, node, range, createEmptyValue()); |
| 1090 |
mergePair(accumulator, create({ text: "\n" })); |
| 1091 |
continue; |
| 1092 |
} |
| 1093 |
const format = toFormat({ |
| 1094 |
tagName, |
| 1095 |
attributes: getAttributes({ element: node }) |
| 1096 |
}); |
| 1097 |
if (format?.formatType?.contentEditable === false) { |
| 1098 |
delete format.formatType; |
| 1099 |
accumulateSelection(accumulator, node, range, createEmptyValue()); |
| 1100 |
mergePair(accumulator, { |
| 1101 |
formats: [,], |
| 1102 |
replacements: [ |
| 1103 |
{ |
| 1104 |
...format, |
| 1105 |
innerHTML: node.innerHTML |
| 1106 |
} |
| 1107 |
], |
| 1108 |
text: OBJECT_REPLACEMENT_CHARACTER |
| 1109 |
}); |
| 1110 |
continue; |
| 1111 |
} |
| 1112 |
if (format) { |
| 1113 |
delete format.formatType; |
| 1114 |
} |
| 1115 |
const value = createFromElement({ |
| 1116 |
element: node, |
| 1117 |
range, |
| 1118 |
isEditableTree |
| 1119 |
}); |
| 1120 |
accumulateSelection(accumulator, node, range, value); |
| 1121 |
if (!format || node.getAttribute("data-rich-text-placeholder") || node.getAttribute("data-rich-text-bogus")) { |
| 1122 |
mergePair(accumulator, value); |
| 1123 |
} else if (value.text.length === 0) { |
| 1124 |
if (format.attributes) { |
| 1125 |
mergePair(accumulator, { |
| 1126 |
formats: [,], |
| 1127 |
replacements: [format], |
| 1128 |
text: OBJECT_REPLACEMENT_CHARACTER |
| 1129 |
}); |
| 1130 |
} |
| 1131 |
} else { |
| 1132 |
let mergeFormats2 = function(formats) { |
| 1133 |
if (mergeFormats2.formats === formats) { |
| 1134 |
return mergeFormats2.newFormats; |
| 1135 |
} |
| 1136 |
const newFormats = formats ? [format, ...formats] : [format]; |
| 1137 |
mergeFormats2.formats = formats; |
| 1138 |
mergeFormats2.newFormats = newFormats; |
| 1139 |
return newFormats; |
| 1140 |
}; |
| 1141 |
var mergeFormats = mergeFormats2; |
| 1142 |
mergeFormats2.newFormats = [format]; |
| 1143 |
mergePair(accumulator, { |
| 1144 |
...value, |
| 1145 |
formats: Array.from(value.formats, mergeFormats2) |
| 1146 |
}); |
| 1147 |
} |
| 1148 |
} |
| 1149 |
return accumulator; |
| 1150 |
} |
| 1151 |
function getAttributes({ element }) { |
| 1152 |
if (!element.hasAttributes()) { |
| 1153 |
return; |
| 1154 |
} |
| 1155 |
const length = element.attributes.length; |
| 1156 |
let accumulator; |
| 1157 |
for (let i2 = 0; i2 < length; i2++) { |
| 1158 |
const { name, value } = element.attributes[i2]; |
| 1159 |
if (name.indexOf("data-rich-text-") === 0) { |
| 1160 |
continue; |
| 1161 |
} |
| 1162 |
const safeName = /^on/i.test(name) ? "data-disable-rich-text-" + name : name; |
| 1163 |
accumulator = accumulator || {}; |
| 1164 |
accumulator[safeName] = value; |
| 1165 |
} |
| 1166 |
return accumulator; |
| 1167 |
} |
| 1168 |
|
| 1169 |
// packages/rich-text/build-module/concat.mjs |
| 1170 |
function mergePair(a2, b2) { |
| 1171 |
a2.formats = a2.formats.concat(b2.formats); |
| 1172 |
a2.replacements = a2.replacements.concat(b2.replacements); |
| 1173 |
a2.text += b2.text; |
| 1174 |
return a2; |
| 1175 |
} |
| 1176 |
function concat(...values) { |
| 1177 |
return normaliseFormats(values.reduce(mergePair, create())); |
| 1178 |
} |
| 1179 |
|
| 1180 |
// packages/rich-text/build-module/get-active-format.mjs |
| 1181 |
function getActiveFormat(value, formatType) { |
| 1182 |
return getActiveFormats(value).find( |
| 1183 |
({ type }) => type === formatType |
| 1184 |
); |
| 1185 |
} |
| 1186 |
|
| 1187 |
// packages/rich-text/build-module/get-active-object.mjs |
| 1188 |
function getActiveObject({ start, end, replacements, text }) { |
| 1189 |
if (start + 1 !== end || text[start] !== OBJECT_REPLACEMENT_CHARACTER) { |
| 1190 |
return; |
| 1191 |
} |
| 1192 |
return replacements[start]; |
| 1193 |
} |
| 1194 |
|
| 1195 |
// packages/rich-text/build-module/is-collapsed.mjs |
| 1196 |
function isCollapsed({ |
| 1197 |
start, |
| 1198 |
end |
| 1199 |
}) { |
| 1200 |
if (start === void 0 || end === void 0) { |
| 1201 |
return; |
| 1202 |
} |
| 1203 |
return start === end; |
| 1204 |
} |
| 1205 |
|
| 1206 |
// packages/rich-text/build-module/is-empty.mjs |
| 1207 |
function isEmpty({ text }) { |
| 1208 |
return text.length === 0; |
| 1209 |
} |
| 1210 |
|
| 1211 |
// packages/rich-text/build-module/join.mjs |
| 1212 |
function join(values, separator = "") { |
| 1213 |
if (typeof separator === "string") { |
| 1214 |
separator = create({ text: separator }); |
| 1215 |
} |
| 1216 |
return normaliseFormats( |
| 1217 |
values.reduce((accumulator, { formats, replacements, text }) => ({ |
| 1218 |
formats: accumulator.formats.concat(separator.formats, formats), |
| 1219 |
replacements: accumulator.replacements.concat( |
| 1220 |
separator.replacements, |
| 1221 |
replacements |
| 1222 |
), |
| 1223 |
text: accumulator.text + separator.text + text |
| 1224 |
})) |
| 1225 |
); |
| 1226 |
} |
| 1227 |
|
| 1228 |
// packages/rich-text/build-module/register-format-type.mjs |
| 1229 |
var import_data6 = __toESM(require_data(), 1); |
| 1230 |
function registerFormatType(name, settings) { |
| 1231 |
settings = { |
| 1232 |
name, |
| 1233 |
...settings |
| 1234 |
}; |
| 1235 |
if (typeof settings.name !== "string") { |
| 1236 |
window.console.error("Format names must be strings."); |
| 1237 |
return; |
| 1238 |
} |
| 1239 |
if (!/^[a-z][a-z0-9-]*\/[a-z][a-z0-9-]*$/.test(settings.name)) { |
| 1240 |
window.console.error( |
| 1241 |
"Format names must contain a namespace prefix, include only lowercase alphanumeric characters or dashes, and start with a letter. Example: my-plugin/my-custom-format" |
| 1242 |
); |
| 1243 |
return; |
| 1244 |
} |
| 1245 |
if ((0, import_data6.select)(store).getFormatType(settings.name)) { |
| 1246 |
window.console.error( |
| 1247 |
'Format "' + settings.name + '" is already registered.' |
| 1248 |
); |
| 1249 |
return; |
| 1250 |
} |
| 1251 |
if (typeof settings.tagName !== "string" || settings.tagName === "") { |
| 1252 |
window.console.error("Format tag names must be a string."); |
| 1253 |
return; |
| 1254 |
} |
| 1255 |
if ((typeof settings.className !== "string" || settings.className === "") && settings.className !== null) { |
| 1256 |
window.console.error( |
| 1257 |
"Format class names must be a string, or null to handle bare elements." |
| 1258 |
); |
| 1259 |
return; |
| 1260 |
} |
| 1261 |
if (!/^[_a-zA-Z]+[a-zA-Z0-9_-]*$/.test(settings.className)) { |
| 1262 |
window.console.error( |
| 1263 |
"A class name must begin with a letter, followed by any number of hyphens, underscores, letters, or numbers." |
| 1264 |
); |
| 1265 |
return; |
| 1266 |
} |
| 1267 |
if (settings.className === null) { |
| 1268 |
const formatTypeForBareElement = (0, import_data6.select)( |
| 1269 |
store |
| 1270 |
).getFormatTypeForBareElement(settings.tagName); |
| 1271 |
if (formatTypeForBareElement && formatTypeForBareElement.name !== "core/unknown") { |
| 1272 |
window.console.error( |
| 1273 |
`Format "${formatTypeForBareElement.name}" is already registered to handle bare tag name "${settings.tagName}".` |
| 1274 |
); |
| 1275 |
return; |
| 1276 |
} |
| 1277 |
} else { |
| 1278 |
const formatTypeForClassName = (0, import_data6.select)( |
| 1279 |
store |
| 1280 |
).getFormatTypeForClassName(settings.className); |
| 1281 |
if (formatTypeForClassName) { |
| 1282 |
window.console.error( |
| 1283 |
`Format "${formatTypeForClassName.name}" is already registered to handle class name "${settings.className}".` |
| 1284 |
); |
| 1285 |
return; |
| 1286 |
} |
| 1287 |
} |
| 1288 |
if (!("title" in settings) || settings.title === "") { |
| 1289 |
window.console.error( |
| 1290 |
'The format "' + settings.name + '" must have a title.' |
| 1291 |
); |
| 1292 |
return; |
| 1293 |
} |
| 1294 |
if ("keywords" in settings && settings.keywords.length > 3) { |
| 1295 |
window.console.error( |
| 1296 |
'The format "' + settings.name + '" can have a maximum of 3 keywords.' |
| 1297 |
); |
| 1298 |
return; |
| 1299 |
} |
| 1300 |
if (typeof settings.title !== "string") { |
| 1301 |
window.console.error("Format titles must be strings."); |
| 1302 |
return; |
| 1303 |
} |
| 1304 |
(0, import_data6.dispatch)(store).addFormatTypes(settings); |
| 1305 |
return settings; |
| 1306 |
} |
| 1307 |
|
| 1308 |
// packages/rich-text/build-module/remove-format.mjs |
| 1309 |
function removeFormat(value, formatType, startIndex = value.start, endIndex = value.end) { |
| 1310 |
const { formats, activeFormats } = value; |
| 1311 |
const newFormats = formats.slice(); |
| 1312 |
if (startIndex === endIndex) { |
| 1313 |
const format = newFormats[startIndex]?.find( |
| 1314 |
({ type }) => type === formatType |
| 1315 |
); |
| 1316 |
if (format) { |
| 1317 |
while (newFormats[startIndex]?.find( |
| 1318 |
(newFormat) => newFormat === format |
| 1319 |
)) { |
| 1320 |
filterFormats(newFormats, startIndex, formatType); |
| 1321 |
startIndex--; |
| 1322 |
} |
| 1323 |
endIndex++; |
| 1324 |
while (newFormats[endIndex]?.find( |
| 1325 |
(newFormat) => newFormat === format |
| 1326 |
)) { |
| 1327 |
filterFormats(newFormats, endIndex, formatType); |
| 1328 |
endIndex++; |
| 1329 |
} |
| 1330 |
} |
| 1331 |
} else { |
| 1332 |
for (let i2 = startIndex; i2 < endIndex; i2++) { |
| 1333 |
if (newFormats[i2]) { |
| 1334 |
filterFormats(newFormats, i2, formatType); |
| 1335 |
} |
| 1336 |
} |
| 1337 |
} |
| 1338 |
return normaliseFormats({ |
| 1339 |
...value, |
| 1340 |
formats: newFormats, |
| 1341 |
activeFormats: activeFormats?.filter(({ type }) => type !== formatType) || [] |
| 1342 |
}); |
| 1343 |
} |
| 1344 |
function filterFormats(formats, index, formatType) { |
| 1345 |
const newFormats = formats[index].filter( |
| 1346 |
({ type }) => type !== formatType |
| 1347 |
); |
| 1348 |
if (newFormats.length) { |
| 1349 |
formats[index] = newFormats; |
| 1350 |
} else { |
| 1351 |
delete formats[index]; |
| 1352 |
} |
| 1353 |
} |
| 1354 |
|
| 1355 |
// packages/rich-text/build-module/insert.mjs |
| 1356 |
function insert(value, valueToInsert, startIndex = value.start, endIndex = value.end) { |
| 1357 |
const { formats, replacements, text } = value; |
| 1358 |
if (typeof valueToInsert === "string") { |
| 1359 |
valueToInsert = create({ text: valueToInsert }); |
| 1360 |
} |
| 1361 |
const index = startIndex + valueToInsert.text.length; |
| 1362 |
return normaliseFormats({ |
| 1363 |
formats: formats.slice(0, startIndex).concat(valueToInsert.formats, formats.slice(endIndex)), |
| 1364 |
replacements: replacements.slice(0, startIndex).concat( |
| 1365 |
valueToInsert.replacements, |
| 1366 |
replacements.slice(endIndex) |
| 1367 |
), |
| 1368 |
text: text.slice(0, startIndex) + valueToInsert.text + text.slice(endIndex), |
| 1369 |
start: index, |
| 1370 |
end: index |
| 1371 |
}); |
| 1372 |
} |
| 1373 |
|
| 1374 |
// packages/rich-text/build-module/remove.mjs |
| 1375 |
function remove2(value, startIndex, endIndex) { |
| 1376 |
return insert(value, create(), startIndex, endIndex); |
| 1377 |
} |
| 1378 |
|
| 1379 |
// packages/rich-text/build-module/replace.mjs |
| 1380 |
function replace2({ formats, replacements, text, start, end }, pattern, replacement) { |
| 1381 |
text = text.replace(pattern, (match, ...rest) => { |
| 1382 |
const offset = rest[rest.length - 2]; |
| 1383 |
let newText = replacement; |
| 1384 |
let newFormats; |
| 1385 |
let newReplacements; |
| 1386 |
if (typeof newText === "function") { |
| 1387 |
newText = replacement(match, ...rest); |
| 1388 |
} |
| 1389 |
if (typeof newText === "object") { |
| 1390 |
newFormats = newText.formats; |
| 1391 |
newReplacements = newText.replacements; |
| 1392 |
newText = newText.text; |
| 1393 |
} else { |
| 1394 |
newFormats = Array(newText.length); |
| 1395 |
newReplacements = Array(newText.length); |
| 1396 |
if (formats[offset]) { |
| 1397 |
newFormats = newFormats.fill(formats[offset]); |
| 1398 |
} |
| 1399 |
} |
| 1400 |
formats = formats.slice(0, offset).concat(newFormats, formats.slice(offset + match.length)); |
| 1401 |
replacements = replacements.slice(0, offset).concat( |
| 1402 |
newReplacements, |
| 1403 |
replacements.slice(offset + match.length) |
| 1404 |
); |
| 1405 |
if (start) { |
| 1406 |
start = end = offset + newText.length; |
| 1407 |
} |
| 1408 |
return newText; |
| 1409 |
}); |
| 1410 |
return normaliseFormats({ formats, replacements, text, start, end }); |
| 1411 |
} |
| 1412 |
|
| 1413 |
// packages/rich-text/build-module/insert-object.mjs |
| 1414 |
function insertObject(value, formatToInsert, startIndex, endIndex) { |
| 1415 |
const valueToInsert = { |
| 1416 |
formats: [,], |
| 1417 |
replacements: [formatToInsert], |
| 1418 |
text: OBJECT_REPLACEMENT_CHARACTER |
| 1419 |
}; |
| 1420 |
return insert(value, valueToInsert, startIndex, endIndex); |
| 1421 |
} |
| 1422 |
|
| 1423 |
// packages/rich-text/build-module/slice.mjs |
| 1424 |
function slice(value, startIndex = value.start, endIndex = value.end) { |
| 1425 |
const { formats, replacements, text } = value; |
| 1426 |
if (startIndex === void 0 || endIndex === void 0) { |
| 1427 |
return { ...value }; |
| 1428 |
} |
| 1429 |
return { |
| 1430 |
formats: formats.slice(startIndex, endIndex), |
| 1431 |
replacements: replacements.slice(startIndex, endIndex), |
| 1432 |
text: text.slice(startIndex, endIndex) |
| 1433 |
}; |
| 1434 |
} |
| 1435 |
|
| 1436 |
// packages/rich-text/build-module/split.mjs |
| 1437 |
function split({ formats, replacements, text, start, end }, string) { |
| 1438 |
if (typeof string !== "string") { |
| 1439 |
return splitAtSelection(...arguments); |
| 1440 |
} |
| 1441 |
let nextStart = 0; |
| 1442 |
return text.split(string).map((substring) => { |
| 1443 |
const startIndex = nextStart; |
| 1444 |
const value = { |
| 1445 |
formats: formats.slice(startIndex, startIndex + substring.length), |
| 1446 |
replacements: replacements.slice( |
| 1447 |
startIndex, |
| 1448 |
startIndex + substring.length |
| 1449 |
), |
| 1450 |
text: substring |
| 1451 |
}; |
| 1452 |
nextStart += string.length + substring.length; |
| 1453 |
if (start !== void 0 && end !== void 0) { |
| 1454 |
if (start >= startIndex && start < nextStart) { |
| 1455 |
value.start = start - startIndex; |
| 1456 |
} else if (start < startIndex && end > startIndex) { |
| 1457 |
value.start = 0; |
| 1458 |
} |
| 1459 |
if (end >= startIndex && end < nextStart) { |
| 1460 |
value.end = end - startIndex; |
| 1461 |
} else if (start < nextStart && end > nextStart) { |
| 1462 |
value.end = substring.length; |
| 1463 |
} |
| 1464 |
} |
| 1465 |
return value; |
| 1466 |
}); |
| 1467 |
} |
| 1468 |
function splitAtSelection({ formats, replacements, text, start, end }, startIndex = start, endIndex = end) { |
| 1469 |
if (start === void 0 || end === void 0) { |
| 1470 |
return; |
| 1471 |
} |
| 1472 |
const before = { |
| 1473 |
formats: formats.slice(0, startIndex), |
| 1474 |
replacements: replacements.slice(0, startIndex), |
| 1475 |
text: text.slice(0, startIndex) |
| 1476 |
}; |
| 1477 |
const after = { |
| 1478 |
formats: formats.slice(endIndex), |
| 1479 |
replacements: replacements.slice(endIndex), |
| 1480 |
text: text.slice(endIndex), |
| 1481 |
start: 0, |
| 1482 |
end: 0 |
| 1483 |
}; |
| 1484 |
return [before, after]; |
| 1485 |
} |
| 1486 |
|
| 1487 |
// packages/rich-text/build-module/is-range-equal.mjs |
| 1488 |
function isRangeEqual(a2, b2) { |
| 1489 |
return a2 === b2 || a2 && b2 && a2.startContainer === b2.startContainer && a2.startOffset === b2.startOffset && a2.endContainer === b2.endContainer && a2.endOffset === b2.endOffset; |
| 1490 |
} |
| 1491 |
|
| 1492 |
// packages/rich-text/build-module/to-dom.mjs |
| 1493 |
var MATHML_NAMESPACE = "http://www.w3.org/1998/Math/MathML"; |
| 1494 |
function createPathToNode(node, rootNode, path) { |
| 1495 |
const parentNode = node.parentNode; |
| 1496 |
let i2 = 0; |
| 1497 |
while (node = node.previousSibling) { |
| 1498 |
i2++; |
| 1499 |
} |
| 1500 |
path = [i2, ...path]; |
| 1501 |
if (parentNode !== rootNode) { |
| 1502 |
path = createPathToNode(parentNode, rootNode, path); |
| 1503 |
} |
| 1504 |
return path; |
| 1505 |
} |
| 1506 |
function getNodeByPath(node, path) { |
| 1507 |
path = [...path]; |
| 1508 |
while (node && path.length > 1) { |
| 1509 |
node = node.childNodes[path.shift()]; |
| 1510 |
} |
| 1511 |
return { |
| 1512 |
node, |
| 1513 |
offset: path[0] |
| 1514 |
}; |
| 1515 |
} |
| 1516 |
function append2(element, child) { |
| 1517 |
if (child.html !== void 0) { |
| 1518 |
return element.innerHTML += child.html; |
| 1519 |
} |
| 1520 |
if (typeof child === "string") { |
| 1521 |
child = element.ownerDocument.createTextNode(child); |
| 1522 |
} |
| 1523 |
const { type, attributes } = child; |
| 1524 |
if (type) { |
| 1525 |
if (type === "#comment") { |
| 1526 |
child = element.ownerDocument.createComment( |
| 1527 |
attributes["data-rich-text-comment"] |
| 1528 |
); |
| 1529 |
} else { |
| 1530 |
const parentNamespace = element.namespaceURI; |
| 1531 |
if (type === "math") { |
| 1532 |
child = element.ownerDocument.createElementNS( |
| 1533 |
MATHML_NAMESPACE, |
| 1534 |
type |
| 1535 |
); |
| 1536 |
} else if (parentNamespace === MATHML_NAMESPACE) { |
| 1537 |
if (element.tagName === "MTEXT") { |
| 1538 |
child = element.ownerDocument.createElement(type); |
| 1539 |
} else { |
| 1540 |
child = element.ownerDocument.createElementNS( |
| 1541 |
MATHML_NAMESPACE, |
| 1542 |
type |
| 1543 |
); |
| 1544 |
} |
| 1545 |
} else { |
| 1546 |
child = element.ownerDocument.createElement(type); |
| 1547 |
} |
| 1548 |
for (const key in attributes) { |
| 1549 |
child.setAttribute(key, attributes[key]); |
| 1550 |
} |
| 1551 |
} |
| 1552 |
} |
| 1553 |
return element.appendChild(child); |
| 1554 |
} |
| 1555 |
function appendText2(node, text) { |
| 1556 |
node.appendData(text); |
| 1557 |
} |
| 1558 |
function getLastChild2({ lastChild }) { |
| 1559 |
return lastChild; |
| 1560 |
} |
| 1561 |
function getParent2({ parentNode }) { |
| 1562 |
return parentNode; |
| 1563 |
} |
| 1564 |
function isText2(node) { |
| 1565 |
return node.nodeType === node.TEXT_NODE; |
| 1566 |
} |
| 1567 |
function getText2({ nodeValue }) { |
| 1568 |
return nodeValue; |
| 1569 |
} |
| 1570 |
function remove3(node) { |
| 1571 |
return node.parentNode.removeChild(node); |
| 1572 |
} |
| 1573 |
function toDom({ |
| 1574 |
value, |
| 1575 |
prepareEditableTree, |
| 1576 |
isEditableTree = true, |
| 1577 |
placeholder, |
| 1578 |
doc = document |
| 1579 |
}) { |
| 1580 |
let startPath = []; |
| 1581 |
let endPath = []; |
| 1582 |
if (prepareEditableTree) { |
| 1583 |
value = { |
| 1584 |
...value, |
| 1585 |
formats: prepareEditableTree(value) |
| 1586 |
}; |
| 1587 |
} |
| 1588 |
const createEmpty2 = () => createElement(doc, ""); |
| 1589 |
const tree = toTree({ |
| 1590 |
value, |
| 1591 |
createEmpty: createEmpty2, |
| 1592 |
append: append2, |
| 1593 |
getLastChild: getLastChild2, |
| 1594 |
getParent: getParent2, |
| 1595 |
isText: isText2, |
| 1596 |
getText: getText2, |
| 1597 |
remove: remove3, |
| 1598 |
appendText: appendText2, |
| 1599 |
onStartIndex(body, pointer) { |
| 1600 |
startPath = createPathToNode(pointer, body, [ |
| 1601 |
pointer.nodeValue.length |
| 1602 |
]); |
| 1603 |
}, |
| 1604 |
onEndIndex(body, pointer) { |
| 1605 |
endPath = createPathToNode(pointer, body, [ |
| 1606 |
pointer.nodeValue.length |
| 1607 |
]); |
| 1608 |
}, |
| 1609 |
isEditableTree, |
| 1610 |
placeholder |
| 1611 |
}); |
| 1612 |
return { |
| 1613 |
body: tree, |
| 1614 |
selection: { startPath, endPath } |
| 1615 |
}; |
| 1616 |
} |
| 1617 |
function apply({ |
| 1618 |
value, |
| 1619 |
current, |
| 1620 |
prepareEditableTree, |
| 1621 |
__unstableDomOnly, |
| 1622 |
placeholder |
| 1623 |
}) { |
| 1624 |
const { body, selection } = toDom({ |
| 1625 |
value, |
| 1626 |
prepareEditableTree, |
| 1627 |
placeholder, |
| 1628 |
doc: current.ownerDocument |
| 1629 |
}); |
| 1630 |
applyValue(body, current); |
| 1631 |
if (value.start !== void 0 && !__unstableDomOnly) { |
| 1632 |
applySelection(selection, current); |
| 1633 |
} |
| 1634 |
} |
| 1635 |
function applyValue(future, current) { |
| 1636 |
let i2 = 0; |
| 1637 |
let futureChild; |
| 1638 |
while (futureChild = future.firstChild) { |
| 1639 |
const currentChild = current.childNodes[i2]; |
| 1640 |
if (!currentChild) { |
| 1641 |
current.appendChild(futureChild); |
| 1642 |
} else if (!currentChild.isEqualNode(futureChild)) { |
| 1643 |
if (currentChild.nodeName !== futureChild.nodeName || currentChild.nodeType === currentChild.TEXT_NODE && currentChild.data !== futureChild.data) { |
| 1644 |
current.replaceChild(futureChild, currentChild); |
| 1645 |
} else { |
| 1646 |
const currentAttributes = currentChild.attributes; |
| 1647 |
const futureAttributes = futureChild.attributes; |
| 1648 |
if (currentAttributes) { |
| 1649 |
let ii = currentAttributes.length; |
| 1650 |
while (ii--) { |
| 1651 |
const { name } = currentAttributes[ii]; |
| 1652 |
if (!futureChild.getAttribute(name)) { |
| 1653 |
currentChild.removeAttribute(name); |
| 1654 |
} |
| 1655 |
} |
| 1656 |
} |
| 1657 |
if (futureAttributes) { |
| 1658 |
for (let ii = 0; ii < futureAttributes.length; ii++) { |
| 1659 |
const { name, value } = futureAttributes[ii]; |
| 1660 |
if (currentChild.getAttribute(name) !== value) { |
| 1661 |
currentChild.setAttribute(name, value); |
| 1662 |
} |
| 1663 |
} |
| 1664 |
} |
| 1665 |
applyValue(futureChild, currentChild); |
| 1666 |
future.removeChild(futureChild); |
| 1667 |
} |
| 1668 |
} else { |
| 1669 |
future.removeChild(futureChild); |
| 1670 |
} |
| 1671 |
i2++; |
| 1672 |
} |
| 1673 |
while (current.childNodes[i2]) { |
| 1674 |
current.removeChild(current.childNodes[i2]); |
| 1675 |
} |
| 1676 |
} |
| 1677 |
function applySelection({ startPath, endPath }, current) { |
| 1678 |
const { node: startContainer, offset: startOffset } = getNodeByPath( |
| 1679 |
current, |
| 1680 |
startPath |
| 1681 |
); |
| 1682 |
const { node: endContainer, offset: endOffset } = getNodeByPath( |
| 1683 |
current, |
| 1684 |
endPath |
| 1685 |
); |
| 1686 |
const { ownerDocument } = current; |
| 1687 |
const { defaultView } = ownerDocument; |
| 1688 |
const selection = defaultView.getSelection(); |
| 1689 |
const range = ownerDocument.createRange(); |
| 1690 |
range.setStart(startContainer, startOffset); |
| 1691 |
range.setEnd(endContainer, endOffset); |
| 1692 |
const { activeElement } = ownerDocument; |
| 1693 |
if (selection.rangeCount > 0) { |
| 1694 |
if (isRangeEqual(range, selection.getRangeAt(0))) { |
| 1695 |
return; |
| 1696 |
} |
| 1697 |
selection.removeAllRanges(); |
| 1698 |
} |
| 1699 |
selection.addRange(range); |
| 1700 |
if (activeElement !== ownerDocument.activeElement) { |
| 1701 |
if (activeElement instanceof defaultView.HTMLElement) { |
| 1702 |
activeElement.focus(); |
| 1703 |
} |
| 1704 |
} |
| 1705 |
} |
| 1706 |
|
| 1707 |
// packages/rich-text/build-module/toggle-format.mjs |
| 1708 |
var import_a11y = __toESM(require_a11y(), 1); |
| 1709 |
var import_i18n = __toESM(require_i18n(), 1); |
| 1710 |
function toggleFormat(value, format) { |
| 1711 |
if (getActiveFormat(value, format.type)) { |
| 1712 |
if (format.title) { |
| 1713 |
(0, import_a11y.speak)((0, import_i18n.sprintf)((0, import_i18n.__)("%s removed."), format.title), "assertive"); |
| 1714 |
} |
| 1715 |
return removeFormat(value, format.type); |
| 1716 |
} |
| 1717 |
if (format.title) { |
| 1718 |
(0, import_a11y.speak)((0, import_i18n.sprintf)((0, import_i18n.__)("%s applied."), format.title), "assertive"); |
| 1719 |
} |
| 1720 |
return applyFormat(value, format); |
| 1721 |
} |
| 1722 |
|
| 1723 |
// packages/rich-text/build-module/unregister-format-type.mjs |
| 1724 |
var import_data7 = __toESM(require_data(), 1); |
| 1725 |
function unregisterFormatType(name) { |
| 1726 |
const oldFormat = (0, import_data7.select)(store).getFormatType(name); |
| 1727 |
if (!oldFormat) { |
| 1728 |
window.console.error(`Format ${name} is not registered.`); |
| 1729 |
return; |
| 1730 |
} |
| 1731 |
(0, import_data7.dispatch)(store).removeFormatTypes(name); |
| 1732 |
return oldFormat; |
| 1733 |
} |
| 1734 |
|
| 1735 |
// packages/rich-text/build-module/lock-unlock.mjs |
| 1736 |
var import_private_apis = __toESM(require_private_apis(), 1); |
| 1737 |
var { lock, unlock } = (0, import_private_apis.__dangerousOptInToUnstableAPIsOnlyForCoreModules)( |
| 1738 |
"I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.", |
| 1739 |
"@wordpress/rich-text" |
| 1740 |
); |
| 1741 |
|
| 1742 |
// packages/rich-text/build-module/hook/index.mjs |
| 1743 |
var import_element5 = __toESM(require_element(), 1); |
| 1744 |
var import_compose9 = __toESM(require_compose(), 1); |
| 1745 |
var import_data9 = __toESM(require_data(), 1); |
| 1746 |
var import_deprecated = __toESM(require_deprecated(), 1); |
| 1747 |
|
| 1748 |
// packages/rich-text/build-module/hook/use-default-style.mjs |
| 1749 |
var import_element = __toESM(require_element(), 1); |
| 1750 |
var whiteSpace = "pre-wrap"; |
| 1751 |
function useDefaultStyle() { |
| 1752 |
return (0, import_element.useCallback)((element) => { |
| 1753 |
if (!element) { |
| 1754 |
return; |
| 1755 |
} |
| 1756 |
element.style.whiteSpace = element.style.whiteSpace || whiteSpace; |
| 1757 |
}, []); |
| 1758 |
} |
| 1759 |
|
| 1760 |
// node_modules/colord/index.mjs |
| 1761 |
var r = { grad: 0.9, turn: 360, rad: 360 / (2 * Math.PI) }; |
| 1762 |
var t = function(r2) { |
| 1763 |
return "string" == typeof r2 ? r2.length > 0 : "number" == typeof r2; |
| 1764 |
}; |
| 1765 |
var n = function(r2, t2, n2) { |
| 1766 |
return void 0 === t2 && (t2 = 0), void 0 === n2 && (n2 = Math.pow(10, t2)), Math.round(n2 * r2) / n2 + 0; |
| 1767 |
}; |
| 1768 |
var e = function(r2, t2, n2) { |
| 1769 |
return void 0 === t2 && (t2 = 0), void 0 === n2 && (n2 = 1), r2 > n2 ? n2 : r2 > t2 ? r2 : t2; |
| 1770 |
}; |
| 1771 |
var u = function(r2) { |
| 1772 |
return (r2 = isFinite(r2) ? r2 % 360 : 0) > 0 ? r2 : r2 + 360; |
| 1773 |
}; |
| 1774 |
var a = function(r2) { |
| 1775 |
return { r: e(r2.r, 0, 255), g: e(r2.g, 0, 255), b: e(r2.b, 0, 255), a: e(r2.a) }; |
| 1776 |
}; |
| 1777 |
var o = function(r2) { |
| 1778 |
return { r: n(r2.r), g: n(r2.g), b: n(r2.b), a: n(r2.a, 3) }; |
| 1779 |
}; |
| 1780 |
var i = /^#([0-9a-f]{3,8})$/i; |
| 1781 |
var s = function(r2) { |
| 1782 |
var t2 = r2.toString(16); |
| 1783 |
return t2.length < 2 ? "0" + t2 : t2; |
| 1784 |
}; |
| 1785 |
var h = function(r2) { |
| 1786 |
var t2 = r2.r, n2 = r2.g, e2 = r2.b, u2 = r2.a, a2 = Math.max(t2, n2, e2), o2 = a2 - Math.min(t2, n2, e2), i2 = o2 ? a2 === t2 ? (n2 - e2) / o2 : a2 === n2 ? 2 + (e2 - t2) / o2 : 4 + (t2 - n2) / o2 : 0; |
| 1787 |
return { h: 60 * (i2 < 0 ? i2 + 6 : i2), s: a2 ? o2 / a2 * 100 : 0, v: a2 / 255 * 100, a: u2 }; |
| 1788 |
}; |
| 1789 |
var b = function(r2) { |
| 1790 |
var t2 = r2.h, n2 = r2.s, e2 = r2.v, u2 = r2.a; |
| 1791 |
t2 = t2 / 360 * 6, n2 /= 100, e2 /= 100; |
| 1792 |
var a2 = Math.floor(t2), o2 = e2 * (1 - n2), i2 = e2 * (1 - (t2 - a2) * n2), s2 = e2 * (1 - (1 - t2 + a2) * n2), h2 = a2 % 6; |
| 1793 |
return { r: 255 * [e2, i2, o2, o2, s2, e2][h2], g: 255 * [s2, e2, e2, i2, o2, o2][h2], b: 255 * [o2, o2, s2, e2, e2, i2][h2], a: u2 }; |
| 1794 |
}; |
| 1795 |
var g = function(r2) { |
| 1796 |
return { h: u(r2.h), s: e(r2.s, 0, 100), l: e(r2.l, 0, 100), a: e(r2.a) }; |
| 1797 |
}; |
| 1798 |
var d = function(r2) { |
| 1799 |
return { h: n(r2.h), s: n(r2.s), l: n(r2.l), a: n(r2.a, 3) }; |
| 1800 |
}; |
| 1801 |
var f = function(r2) { |
| 1802 |
return b((n2 = (t2 = r2).s, { h: t2.h, s: (n2 *= ((e2 = t2.l) < 50 ? e2 : 100 - e2) / 100) > 0 ? 2 * n2 / (e2 + n2) * 100 : 0, v: e2 + n2, a: t2.a })); |
| 1803 |
var t2, n2, e2; |
| 1804 |
}; |
| 1805 |
var c = function(r2) { |
| 1806 |
return { h: (t2 = h(r2)).h, s: (u2 = (200 - (n2 = t2.s)) * (e2 = t2.v) / 100) > 0 && u2 < 200 ? n2 * e2 / 100 / (u2 <= 100 ? u2 : 200 - u2) * 100 : 0, l: u2 / 2, a: t2.a }; |
| 1807 |
var t2, n2, e2, u2; |
| 1808 |
}; |
| 1809 |
var l = /^hsla?\(\s*([+-]?\d*\.?\d+)(deg|rad|grad|turn)?\s*,\s*([+-]?\d*\.?\d+)%\s*,\s*([+-]?\d*\.?\d+)%\s*(?:,\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i; |
| 1810 |
var p = /^hsla?\(\s*([+-]?\d*\.?\d+)(deg|rad|grad|turn)?\s+([+-]?\d*\.?\d+)%\s+([+-]?\d*\.?\d+)%\s*(?:\/\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i; |
| 1811 |
var v = /^rgba?\(\s*([+-]?\d*\.?\d+)(%)?\s*,\s*([+-]?\d*\.?\d+)(%)?\s*,\s*([+-]?\d*\.?\d+)(%)?\s*(?:,\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i; |
| 1812 |
var m = /^rgba?\(\s*([+-]?\d*\.?\d+)(%)?\s+([+-]?\d*\.?\d+)(%)?\s+([+-]?\d*\.?\d+)(%)?\s*(?:\/\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i; |
| 1813 |
var y = { string: [[function(r2) { |
| 1814 |
var t2 = i.exec(r2); |
| 1815 |
return t2 ? (r2 = t2[1]).length <= 4 ? { r: parseInt(r2[0] + r2[0], 16), g: parseInt(r2[1] + r2[1], 16), b: parseInt(r2[2] + r2[2], 16), a: 4 === r2.length ? n(parseInt(r2[3] + r2[3], 16) / 255, 2) : 1 } : 6 === r2.length || 8 === r2.length ? { r: parseInt(r2.substr(0, 2), 16), g: parseInt(r2.substr(2, 2), 16), b: parseInt(r2.substr(4, 2), 16), a: 8 === r2.length ? n(parseInt(r2.substr(6, 2), 16) / 255, 2) : 1 } : null : null; |
| 1816 |
}, "hex"], [function(r2) { |
| 1817 |
var t2 = v.exec(r2) || m.exec(r2); |
| 1818 |
return t2 ? t2[2] !== t2[4] || t2[4] !== t2[6] ? null : a({ r: Number(t2[1]) / (t2[2] ? 100 / 255 : 1), g: Number(t2[3]) / (t2[4] ? 100 / 255 : 1), b: Number(t2[5]) / (t2[6] ? 100 / 255 : 1), a: void 0 === t2[7] ? 1 : Number(t2[7]) / (t2[8] ? 100 : 1) }) : null; |
| 1819 |
}, "rgb"], [function(t2) { |
| 1820 |
var n2 = l.exec(t2) || p.exec(t2); |
| 1821 |
if (!n2) return null; |
| 1822 |
var e2, u2, a2 = g({ h: (e2 = n2[1], u2 = n2[2], void 0 === u2 && (u2 = "deg"), Number(e2) * (r[u2] || 1)), s: Number(n2[3]), l: Number(n2[4]), a: void 0 === n2[5] ? 1 : Number(n2[5]) / (n2[6] ? 100 : 1) }); |
| 1823 |
return f(a2); |
| 1824 |
}, "hsl"]], object: [[function(r2) { |
| 1825 |
var n2 = r2.r, e2 = r2.g, u2 = r2.b, o2 = r2.a, i2 = void 0 === o2 ? 1 : o2; |
| 1826 |
return t(n2) && t(e2) && t(u2) ? a({ r: Number(n2), g: Number(e2), b: Number(u2), a: Number(i2) }) : null; |
| 1827 |
}, "rgb"], [function(r2) { |
| 1828 |
var n2 = r2.h, e2 = r2.s, u2 = r2.l, a2 = r2.a, o2 = void 0 === a2 ? 1 : a2; |
| 1829 |
if (!t(n2) || !t(e2) || !t(u2)) return null; |
| 1830 |
var i2 = g({ h: Number(n2), s: Number(e2), l: Number(u2), a: Number(o2) }); |
| 1831 |
return f(i2); |
| 1832 |
}, "hsl"], [function(r2) { |
| 1833 |
var n2 = r2.h, a2 = r2.s, o2 = r2.v, i2 = r2.a, s2 = void 0 === i2 ? 1 : i2; |
| 1834 |
if (!t(n2) || !t(a2) || !t(o2)) return null; |
| 1835 |
var h2 = (function(r3) { |
| 1836 |
return { h: u(r3.h), s: e(r3.s, 0, 100), v: e(r3.v, 0, 100), a: e(r3.a) }; |
| 1837 |
})({ h: Number(n2), s: Number(a2), v: Number(o2), a: Number(s2) }); |
| 1838 |
return b(h2); |
| 1839 |
}, "hsv"]] }; |
| 1840 |
var N = function(r2, t2) { |
| 1841 |
for (var n2 = 0; n2 < t2.length; n2++) { |
| 1842 |
var e2 = t2[n2][0](r2); |
| 1843 |
if (e2) return [e2, t2[n2][1]]; |
| 1844 |
} |
| 1845 |
return [null, void 0]; |
| 1846 |
}; |
| 1847 |
var x = function(r2) { |
| 1848 |
return "string" == typeof r2 ? N(r2.trim(), y.string) : "object" == typeof r2 && null !== r2 ? N(r2, y.object) : [null, void 0]; |
| 1849 |
}; |
| 1850 |
var M = function(r2, t2) { |
| 1851 |
var n2 = c(r2); |
| 1852 |
return { h: n2.h, s: e(n2.s + 100 * t2, 0, 100), l: n2.l, a: n2.a }; |
| 1853 |
}; |
| 1854 |
var H = function(r2) { |
| 1855 |
return (299 * r2.r + 587 * r2.g + 114 * r2.b) / 1e3 / 255; |
| 1856 |
}; |
| 1857 |
var $ = function(r2, t2) { |
| 1858 |
var n2 = c(r2); |
| 1859 |
return { h: n2.h, s: n2.s, l: e(n2.l + 100 * t2, 0, 100), a: n2.a }; |
| 1860 |
}; |
| 1861 |
var j = (function() { |
| 1862 |
function r2(r3) { |
| 1863 |
this.parsed = x(r3)[0], this.rgba = this.parsed || { r: 0, g: 0, b: 0, a: 1 }; |
| 1864 |
} |
| 1865 |
return r2.prototype.isValid = function() { |
| 1866 |
return null !== this.parsed; |
| 1867 |
}, r2.prototype.brightness = function() { |
| 1868 |
return n(H(this.rgba), 2); |
| 1869 |
}, r2.prototype.isDark = function() { |
| 1870 |
return H(this.rgba) < 0.5; |
| 1871 |
}, r2.prototype.isLight = function() { |
| 1872 |
return H(this.rgba) >= 0.5; |
| 1873 |
}, r2.prototype.toHex = function() { |
| 1874 |
return r3 = o(this.rgba), t2 = r3.r, e2 = r3.g, u2 = r3.b, i2 = (a2 = r3.a) < 1 ? s(n(255 * a2)) : "", "#" + s(t2) + s(e2) + s(u2) + i2; |
| 1875 |
var r3, t2, e2, u2, a2, i2; |
| 1876 |
}, r2.prototype.toRgb = function() { |
| 1877 |
return o(this.rgba); |
| 1878 |
}, r2.prototype.toRgbString = function() { |
| 1879 |
return r3 = o(this.rgba), t2 = r3.r, n2 = r3.g, e2 = r3.b, (u2 = r3.a) < 1 ? "rgba(" + t2 + ", " + n2 + ", " + e2 + ", " + u2 + ")" : "rgb(" + t2 + ", " + n2 + ", " + e2 + ")"; |
| 1880 |
var r3, t2, n2, e2, u2; |
| 1881 |
}, r2.prototype.toHsl = function() { |
| 1882 |
return d(c(this.rgba)); |
| 1883 |
}, r2.prototype.toHslString = function() { |
| 1884 |
return r3 = d(c(this.rgba)), t2 = r3.h, n2 = r3.s, e2 = r3.l, (u2 = r3.a) < 1 ? "hsla(" + t2 + ", " + n2 + "%, " + e2 + "%, " + u2 + ")" : "hsl(" + t2 + ", " + n2 + "%, " + e2 + "%)"; |
| 1885 |
var r3, t2, n2, e2, u2; |
| 1886 |
}, r2.prototype.toHsv = function() { |
| 1887 |
return r3 = h(this.rgba), { h: n(r3.h), s: n(r3.s), v: n(r3.v), a: n(r3.a, 3) }; |
| 1888 |
var r3; |
| 1889 |
}, r2.prototype.invert = function() { |
| 1890 |
return w({ r: 255 - (r3 = this.rgba).r, g: 255 - r3.g, b: 255 - r3.b, a: r3.a }); |
| 1891 |
var r3; |
| 1892 |
}, r2.prototype.saturate = function(r3) { |
| 1893 |
return void 0 === r3 && (r3 = 0.1), w(M(this.rgba, r3)); |
| 1894 |
}, r2.prototype.desaturate = function(r3) { |
| 1895 |
return void 0 === r3 && (r3 = 0.1), w(M(this.rgba, -r3)); |
| 1896 |
}, r2.prototype.grayscale = function() { |
| 1897 |
return w(M(this.rgba, -1)); |
| 1898 |
}, r2.prototype.lighten = function(r3) { |
| 1899 |
return void 0 === r3 && (r3 = 0.1), w($(this.rgba, r3)); |
| 1900 |
}, r2.prototype.darken = function(r3) { |
| 1901 |
return void 0 === r3 && (r3 = 0.1), w($(this.rgba, -r3)); |
| 1902 |
}, r2.prototype.rotate = function(r3) { |
| 1903 |
return void 0 === r3 && (r3 = 15), this.hue(this.hue() + r3); |
| 1904 |
}, r2.prototype.alpha = function(r3) { |
| 1905 |
return "number" == typeof r3 ? w({ r: (t2 = this.rgba).r, g: t2.g, b: t2.b, a: r3 }) : n(this.rgba.a, 3); |
| 1906 |
var t2; |
| 1907 |
}, r2.prototype.hue = function(r3) { |
| 1908 |
var t2 = c(this.rgba); |
| 1909 |
return "number" == typeof r3 ? w({ h: r3, s: t2.s, l: t2.l, a: t2.a }) : n(t2.h); |
| 1910 |
}, r2.prototype.isEqual = function(r3) { |
| 1911 |
return this.toHex() === w(r3).toHex(); |
| 1912 |
}, r2; |
| 1913 |
})(); |
| 1914 |
var w = function(r2) { |
| 1915 |
return r2 instanceof j ? r2 : new j(r2); |
| 1916 |
}; |
| 1917 |
|
| 1918 |
// packages/rich-text/build-module/hook/use-boundary-style.mjs |
| 1919 |
var import_element2 = __toESM(require_element(), 1); |
| 1920 |
function useBoundaryStyle({ record }) { |
| 1921 |
const ref = (0, import_element2.useRef)(); |
| 1922 |
const { activeFormats = [], replacements, start } = record.current; |
| 1923 |
const activeReplacement = replacements[start]; |
| 1924 |
(0, import_element2.useEffect)(() => { |
| 1925 |
if ((!activeFormats || !activeFormats.length) && !activeReplacement) { |
| 1926 |
return; |
| 1927 |
} |
| 1928 |
const boundarySelector = "*[data-rich-text-format-boundary]"; |
| 1929 |
const element = ref.current.querySelector(boundarySelector); |
| 1930 |
if (!element) { |
| 1931 |
return; |
| 1932 |
} |
| 1933 |
const { ownerDocument } = element; |
| 1934 |
const { defaultView } = ownerDocument; |
| 1935 |
const computedStyle = defaultView.getComputedStyle(element); |
| 1936 |
const newColor = w(computedStyle.color).alpha(0.2).toRgbString(); |
| 1937 |
const selector = `.rich-text:focus ${boundarySelector}`; |
| 1938 |
const rule = `background-color: ${newColor}`; |
| 1939 |
const style = `${selector} {${rule}}`; |
| 1940 |
const globalStyleId = "rich-text-boundary-style"; |
| 1941 |
let globalStyle = ownerDocument.getElementById(globalStyleId); |
| 1942 |
if (!globalStyle) { |
| 1943 |
globalStyle = ownerDocument.createElement("style"); |
| 1944 |
globalStyle.id = globalStyleId; |
| 1945 |
ownerDocument.head.appendChild(globalStyle); |
| 1946 |
} |
| 1947 |
if (globalStyle.innerHTML !== style) { |
| 1948 |
globalStyle.innerHTML = style; |
| 1949 |
} |
| 1950 |
}, [activeFormats, activeReplacement]); |
| 1951 |
return ref; |
| 1952 |
} |
| 1953 |
|
| 1954 |
// packages/rich-text/build-module/hook/event-listeners/index.mjs |
| 1955 |
var import_element3 = __toESM(require_element(), 1); |
| 1956 |
var import_compose8 = __toESM(require_compose(), 1); |
| 1957 |
|
| 1958 |
// packages/rich-text/build-module/hook/event-listeners/copy-handler.mjs |
| 1959 |
var import_compose = __toESM(require_compose(), 1); |
| 1960 |
var { subscribeDelegatedListener } = unlock(import_compose.privateApis); |
| 1961 |
var copy_handler_default = (props) => (element) => { |
| 1962 |
function onCopy(event) { |
| 1963 |
const { record } = props.current; |
| 1964 |
const { ownerDocument } = element; |
| 1965 |
if (isCollapsed(record.current) || !element.contains(ownerDocument.activeElement)) { |
| 1966 |
return; |
| 1967 |
} |
| 1968 |
const selectedRecord = slice(record.current); |
| 1969 |
const plainText = getTextContent(selectedRecord); |
| 1970 |
const html = toHTMLString({ value: selectedRecord }); |
| 1971 |
event.clipboardData.setData("text/plain", plainText); |
| 1972 |
event.clipboardData.setData("text/html", html); |
| 1973 |
event.clipboardData.setData("rich-text", "true"); |
| 1974 |
event.preventDefault(); |
| 1975 |
if (event.type === "cut") { |
| 1976 |
ownerDocument.execCommand("delete"); |
| 1977 |
} |
| 1978 |
} |
| 1979 |
const { defaultView } = element.ownerDocument; |
| 1980 |
const unsubscribeCopy = subscribeDelegatedListener( |
| 1981 |
defaultView, |
| 1982 |
"copy", |
| 1983 |
onCopy |
| 1984 |
); |
| 1985 |
const unsubscribeCut = subscribeDelegatedListener( |
| 1986 |
defaultView, |
| 1987 |
"cut", |
| 1988 |
onCopy |
| 1989 |
); |
| 1990 |
return () => { |
| 1991 |
unsubscribeCopy(); |
| 1992 |
unsubscribeCut(); |
| 1993 |
}; |
| 1994 |
}; |
| 1995 |
|
| 1996 |
// packages/rich-text/build-module/hook/event-listeners/select-object.mjs |
| 1997 |
var import_compose2 = __toESM(require_compose(), 1); |
| 1998 |
var { subscribeDelegatedListener: subscribeDelegatedListener2 } = unlock(import_compose2.privateApis); |
| 1999 |
var select_object_default = () => (element) => { |
| 2000 |
function onClick(event) { |
| 2001 |
const { target } = event; |
| 2002 |
if (target === element || target.textContent && target.isContentEditable) { |
| 2003 |
return; |
| 2004 |
} |
| 2005 |
const { ownerDocument } = target; |
| 2006 |
const { defaultView } = ownerDocument; |
| 2007 |
const selection = defaultView.getSelection(); |
| 2008 |
if (selection.containsNode(target)) { |
| 2009 |
return; |
| 2010 |
} |
| 2011 |
const range = ownerDocument.createRange(); |
| 2012 |
const nodeToSelect = target.isContentEditable ? target : target.closest("[contenteditable]"); |
| 2013 |
range.selectNode(nodeToSelect); |
| 2014 |
selection.removeAllRanges(); |
| 2015 |
selection.addRange(range); |
| 2016 |
event.preventDefault(); |
| 2017 |
} |
| 2018 |
function onFocusIn(event) { |
| 2019 |
if (event.relatedTarget && !element.contains(event.relatedTarget) && event.relatedTarget.tagName === "A") { |
| 2020 |
onClick(event); |
| 2021 |
} |
| 2022 |
} |
| 2023 |
const unsubscribeClick = subscribeDelegatedListener2( |
| 2024 |
element, |
| 2025 |
"click", |
| 2026 |
onClick |
| 2027 |
); |
| 2028 |
const unsubscribeFocusIn = subscribeDelegatedListener2( |
| 2029 |
element, |
| 2030 |
"focusin", |
| 2031 |
onFocusIn |
| 2032 |
); |
| 2033 |
return () => { |
| 2034 |
unsubscribeClick(); |
| 2035 |
unsubscribeFocusIn(); |
| 2036 |
}; |
| 2037 |
}; |
| 2038 |
|
| 2039 |
// packages/rich-text/build-module/hook/event-listeners/format-boundaries.mjs |
| 2040 |
var import_keycodes = __toESM(require_keycodes(), 1); |
| 2041 |
var import_compose3 = __toESM(require_compose(), 1); |
| 2042 |
var { subscribeDelegatedListener: subscribeDelegatedListener3 } = unlock(import_compose3.privateApis); |
| 2043 |
var EMPTY_ACTIVE_FORMATS = []; |
| 2044 |
var format_boundaries_default = (props) => (element) => { |
| 2045 |
function onKeyDown(event) { |
| 2046 |
const { keyCode, shiftKey, altKey, metaKey, ctrlKey } = event; |
| 2047 |
if ( |
| 2048 |
// Only override left and right keys without modifiers pressed. |
| 2049 |
shiftKey || altKey || metaKey || ctrlKey || keyCode !== import_keycodes.LEFT && keyCode !== import_keycodes.RIGHT |
| 2050 |
) { |
| 2051 |
return; |
| 2052 |
} |
| 2053 |
const { record, applyRecord, forceRender } = props.current; |
| 2054 |
const { |
| 2055 |
text, |
| 2056 |
formats, |
| 2057 |
start, |
| 2058 |
end, |
| 2059 |
activeFormats: currentActiveFormats = [] |
| 2060 |
} = record.current; |
| 2061 |
const collapsed = isCollapsed(record.current); |
| 2062 |
const { defaultView } = element.ownerDocument; |
| 2063 |
const { direction } = defaultView.getComputedStyle(element); |
| 2064 |
const reverseKey = direction === "rtl" ? import_keycodes.RIGHT : import_keycodes.LEFT; |
| 2065 |
const isReverse = event.keyCode === reverseKey; |
| 2066 |
if (collapsed && currentActiveFormats.length === 0) { |
| 2067 |
if (start === 0 && isReverse) { |
| 2068 |
return; |
| 2069 |
} |
| 2070 |
if (end === text.length && !isReverse) { |
| 2071 |
return; |
| 2072 |
} |
| 2073 |
} |
| 2074 |
if (!collapsed) { |
| 2075 |
return; |
| 2076 |
} |
| 2077 |
const formatsBefore = formats[start - 1] || EMPTY_ACTIVE_FORMATS; |
| 2078 |
const formatsAfter = formats[start] || EMPTY_ACTIVE_FORMATS; |
| 2079 |
const destination = isReverse ? formatsBefore : formatsAfter; |
| 2080 |
const isIncreasing = currentActiveFormats.every( |
| 2081 |
(format, index) => format === destination[index] |
| 2082 |
); |
| 2083 |
let newActiveFormatsLength = currentActiveFormats.length; |
| 2084 |
if (!isIncreasing) { |
| 2085 |
newActiveFormatsLength--; |
| 2086 |
} else if (newActiveFormatsLength < destination.length) { |
| 2087 |
newActiveFormatsLength++; |
| 2088 |
} |
| 2089 |
if (newActiveFormatsLength === currentActiveFormats.length) { |
| 2090 |
record.current._newActiveFormats = destination; |
| 2091 |
return; |
| 2092 |
} |
| 2093 |
event.preventDefault(); |
| 2094 |
const origin = isReverse ? formatsAfter : formatsBefore; |
| 2095 |
const source = isIncreasing ? destination : origin; |
| 2096 |
const newActiveFormats = source.slice(0, newActiveFormatsLength); |
| 2097 |
const newValue = { |
| 2098 |
...record.current, |
| 2099 |
activeFormats: newActiveFormats |
| 2100 |
}; |
| 2101 |
record.current = newValue; |
| 2102 |
applyRecord(newValue); |
| 2103 |
forceRender(); |
| 2104 |
} |
| 2105 |
return subscribeDelegatedListener3(element, "keydown", onKeyDown, true); |
| 2106 |
}; |
| 2107 |
|
| 2108 |
// packages/rich-text/build-module/hook/event-listeners/delete.mjs |
| 2109 |
var import_keycodes2 = __toESM(require_keycodes(), 1); |
| 2110 |
var import_compose4 = __toESM(require_compose(), 1); |
| 2111 |
var { subscribeDelegatedListener: subscribeDelegatedListener4 } = unlock(import_compose4.privateApis); |
| 2112 |
var delete_default = (props) => (element) => { |
| 2113 |
function onKeyDown(event) { |
| 2114 |
const { keyCode } = event; |
| 2115 |
if (event.defaultPrevented) { |
| 2116 |
return; |
| 2117 |
} |
| 2118 |
if (keyCode !== import_keycodes2.DELETE && keyCode !== import_keycodes2.BACKSPACE) { |
| 2119 |
return; |
| 2120 |
} |
| 2121 |
const { createRecord, handleChange } = props.current; |
| 2122 |
const currentValue = createRecord(); |
| 2123 |
const { start, end, text } = currentValue; |
| 2124 |
if (start === 0 && end !== 0 && end === text.length) { |
| 2125 |
handleChange(remove2(currentValue)); |
| 2126 |
event.preventDefault(); |
| 2127 |
} |
| 2128 |
} |
| 2129 |
return subscribeDelegatedListener4(element, "keydown", onKeyDown); |
| 2130 |
}; |
| 2131 |
|
| 2132 |
// packages/rich-text/build-module/hook/event-listeners/input-and-selection.mjs |
| 2133 |
var import_compose5 = __toESM(require_compose(), 1); |
| 2134 |
|
| 2135 |
// packages/rich-text/build-module/update-formats.mjs |
| 2136 |
function updateFormats({ value, start, end, formats }) { |
| 2137 |
const min = Math.min(start, end); |
| 2138 |
const max = Math.max(start, end); |
| 2139 |
const formatsBefore = value.formats[min - 1] || []; |
| 2140 |
const formatsAfter = value.formats[max] || []; |
| 2141 |
value.activeFormats = formats.map((format, index) => { |
| 2142 |
if (formatsBefore[index]) { |
| 2143 |
if (isFormatEqual(format, formatsBefore[index])) { |
| 2144 |
return formatsBefore[index]; |
| 2145 |
} |
| 2146 |
} else if (formatsAfter[index]) { |
| 2147 |
if (isFormatEqual(format, formatsAfter[index])) { |
| 2148 |
return formatsAfter[index]; |
| 2149 |
} |
| 2150 |
} |
| 2151 |
return format; |
| 2152 |
}); |
| 2153 |
while (--end >= start) { |
| 2154 |
if (value.activeFormats.length > 0) { |
| 2155 |
value.formats[end] = value.activeFormats; |
| 2156 |
} else { |
| 2157 |
delete value.formats[end]; |
| 2158 |
} |
| 2159 |
} |
| 2160 |
return value; |
| 2161 |
} |
| 2162 |
|
| 2163 |
// packages/rich-text/build-module/hook/event-listeners/input-and-selection.mjs |
| 2164 |
var { subscribeDelegatedListener: subscribeDelegatedListener5 } = unlock(import_compose5.privateApis); |
| 2165 |
var INSERTION_INPUT_TYPES_TO_IGNORE = /* @__PURE__ */ new Set([ |
| 2166 |
"insertParagraph", |
| 2167 |
"insertOrderedList", |
| 2168 |
"insertUnorderedList", |
| 2169 |
"insertHorizontalRule", |
| 2170 |
"insertLink" |
| 2171 |
]); |
| 2172 |
var EMPTY_ACTIVE_FORMATS2 = []; |
| 2173 |
var PLACEHOLDER_ATTR_NAME = "data-rich-text-placeholder"; |
| 2174 |
function fixPlaceholderSelection(defaultView) { |
| 2175 |
const selection = defaultView.getSelection(); |
| 2176 |
const { anchorNode, anchorOffset } = selection; |
| 2177 |
if (anchorNode.nodeType !== anchorNode.ELEMENT_NODE) { |
| 2178 |
return; |
| 2179 |
} |
| 2180 |
const targetNode = anchorNode.childNodes[anchorOffset]; |
| 2181 |
if (!targetNode || targetNode.nodeType !== targetNode.ELEMENT_NODE || !targetNode.hasAttribute(PLACEHOLDER_ATTR_NAME)) { |
| 2182 |
return; |
| 2183 |
} |
| 2184 |
selection.collapseToStart(); |
| 2185 |
} |
| 2186 |
var input_and_selection_default = (props) => (element) => { |
| 2187 |
const { ownerDocument } = element; |
| 2188 |
const { defaultView } = ownerDocument; |
| 2189 |
let isComposing = false; |
| 2190 |
function onInput(event) { |
| 2191 |
if (isComposing) { |
| 2192 |
return; |
| 2193 |
} |
| 2194 |
let inputType; |
| 2195 |
if (event) { |
| 2196 |
inputType = event.inputType; |
| 2197 |
} |
| 2198 |
const { record, applyRecord, createRecord, handleChange } = props.current; |
| 2199 |
if (inputType && (inputType.indexOf("format") === 0 || INSERTION_INPUT_TYPES_TO_IGNORE.has(inputType))) { |
| 2200 |
applyRecord(record.current); |
| 2201 |
return; |
| 2202 |
} |
| 2203 |
const currentValue = createRecord(); |
| 2204 |
const { start, activeFormats: oldActiveFormats = [] } = record.current; |
| 2205 |
const clearFormats = !isCollapsed(record.current) && currentValue.start <= start; |
| 2206 |
const change = updateFormats({ |
| 2207 |
value: currentValue, |
| 2208 |
start, |
| 2209 |
end: currentValue.start, |
| 2210 |
formats: clearFormats ? [] : oldActiveFormats |
| 2211 |
}); |
| 2212 |
handleChange(change); |
| 2213 |
} |
| 2214 |
function handleSelectionChange() { |
| 2215 |
const { record, applyRecord, createRecord, onSelectionChange } = props.current; |
| 2216 |
if (element.contentEditable !== "true") { |
| 2217 |
return; |
| 2218 |
} |
| 2219 |
if (ownerDocument.activeElement !== element) { |
| 2220 |
ownerDocument.removeEventListener( |
| 2221 |
"selectionchange", |
| 2222 |
handleSelectionChange |
| 2223 |
); |
| 2224 |
return; |
| 2225 |
} |
| 2226 |
if (isComposing) { |
| 2227 |
return; |
| 2228 |
} |
| 2229 |
const { start, end, text } = createRecord(); |
| 2230 |
const oldRecord = record.current; |
| 2231 |
if (text !== oldRecord.text) { |
| 2232 |
onInput(); |
| 2233 |
return; |
| 2234 |
} |
| 2235 |
if (start === oldRecord.start && end === oldRecord.end) { |
| 2236 |
if (oldRecord.text.length === 0 && start === 0) { |
| 2237 |
fixPlaceholderSelection(defaultView); |
| 2238 |
} |
| 2239 |
return; |
| 2240 |
} |
| 2241 |
const newValue = { |
| 2242 |
...oldRecord, |
| 2243 |
start, |
| 2244 |
end, |
| 2245 |
// _newActiveFormats may be set on arrow key navigation to control |
| 2246 |
// the right boundary position. If undefined, getActiveFormats will |
| 2247 |
// give the active formats according to the browser. |
| 2248 |
activeFormats: oldRecord._newActiveFormats, |
| 2249 |
_newActiveFormats: void 0 |
| 2250 |
}; |
| 2251 |
const newActiveFormats = getActiveFormats( |
| 2252 |
newValue, |
| 2253 |
EMPTY_ACTIVE_FORMATS2 |
| 2254 |
); |
| 2255 |
newValue.activeFormats = newActiveFormats; |
| 2256 |
record.current = newValue; |
| 2257 |
applyRecord(newValue, { domOnly: true }); |
| 2258 |
onSelectionChange(start, end); |
| 2259 |
} |
| 2260 |
function onCompositionStart() { |
| 2261 |
isComposing = true; |
| 2262 |
ownerDocument.removeEventListener( |
| 2263 |
"selectionchange", |
| 2264 |
handleSelectionChange |
| 2265 |
); |
| 2266 |
element.querySelector(`[${PLACEHOLDER_ATTR_NAME}]`)?.remove(); |
| 2267 |
} |
| 2268 |
function onCompositionEnd() { |
| 2269 |
isComposing = false; |
| 2270 |
onInput({ inputType: "insertText" }); |
| 2271 |
ownerDocument.addEventListener( |
| 2272 |
"selectionchange", |
| 2273 |
handleSelectionChange |
| 2274 |
); |
| 2275 |
} |
| 2276 |
function onFocus(event) { |
| 2277 |
if (event.target !== element) { |
| 2278 |
return; |
| 2279 |
} |
| 2280 |
if (element.contentEditable !== "true") { |
| 2281 |
return; |
| 2282 |
} |
| 2283 |
const { record, isSelected, onSelectionChange, applyRecord } = props.current; |
| 2284 |
if (element.parentElement.closest('[contenteditable="true"]')) { |
| 2285 |
return; |
| 2286 |
} |
| 2287 |
if (!isSelected) { |
| 2288 |
const index = void 0; |
| 2289 |
record.current = { |
| 2290 |
...record.current, |
| 2291 |
start: index, |
| 2292 |
end: index, |
| 2293 |
activeFormats: EMPTY_ACTIVE_FORMATS2 |
| 2294 |
}; |
| 2295 |
} else { |
| 2296 |
applyRecord(record.current, { domOnly: true }); |
| 2297 |
} |
| 2298 |
onSelectionChange(record.current.start, record.current.end); |
| 2299 |
window.queueMicrotask(handleSelectionChange); |
| 2300 |
ownerDocument.addEventListener( |
| 2301 |
"selectionchange", |
| 2302 |
handleSelectionChange |
| 2303 |
); |
| 2304 |
} |
| 2305 |
const unsubscribeInput = subscribeDelegatedListener5( |
| 2306 |
element, |
| 2307 |
"input", |
| 2308 |
onInput, |
| 2309 |
true |
| 2310 |
); |
| 2311 |
const unsubscribeCompositionStart = subscribeDelegatedListener5( |
| 2312 |
element, |
| 2313 |
"compositionstart", |
| 2314 |
onCompositionStart |
| 2315 |
); |
| 2316 |
const unsubscribeCompositionEnd = subscribeDelegatedListener5( |
| 2317 |
element, |
| 2318 |
"compositionend", |
| 2319 |
onCompositionEnd, |
| 2320 |
true |
| 2321 |
); |
| 2322 |
const unsubscribeFocus = subscribeDelegatedListener5( |
| 2323 |
element, |
| 2324 |
"focusin", |
| 2325 |
onFocus |
| 2326 |
); |
| 2327 |
return () => { |
| 2328 |
unsubscribeInput(); |
| 2329 |
unsubscribeCompositionStart(); |
| 2330 |
unsubscribeCompositionEnd(); |
| 2331 |
unsubscribeFocus(); |
| 2332 |
}; |
| 2333 |
}; |
| 2334 |
|
| 2335 |
// packages/rich-text/build-module/hook/event-listeners/selection-change-compat.mjs |
| 2336 |
var import_compose6 = __toESM(require_compose(), 1); |
| 2337 |
var { subscribeDelegatedListener: subscribeDelegatedListener6 } = unlock(import_compose6.privateApis); |
| 2338 |
var selection_change_compat_default = () => (element) => { |
| 2339 |
const { ownerDocument } = element; |
| 2340 |
const { defaultView } = ownerDocument; |
| 2341 |
const selection = defaultView?.getSelection(); |
| 2342 |
let range; |
| 2343 |
function getRange() { |
| 2344 |
return selection.rangeCount ? selection.getRangeAt(0) : null; |
| 2345 |
} |
| 2346 |
function onDown(event) { |
| 2347 |
const type = event.type === "keydown" ? "keyup" : "pointerup"; |
| 2348 |
function onCancel() { |
| 2349 |
ownerDocument.removeEventListener(type, onUp); |
| 2350 |
ownerDocument.removeEventListener("selectionchange", onCancel); |
| 2351 |
ownerDocument.removeEventListener("input", onCancel); |
| 2352 |
} |
| 2353 |
function onUp() { |
| 2354 |
onCancel(); |
| 2355 |
if (isRangeEqual(range, getRange())) { |
| 2356 |
return; |
| 2357 |
} |
| 2358 |
ownerDocument.dispatchEvent(new Event("selectionchange")); |
| 2359 |
} |
| 2360 |
ownerDocument.addEventListener(type, onUp); |
| 2361 |
ownerDocument.addEventListener("selectionchange", onCancel); |
| 2362 |
ownerDocument.addEventListener("input", onCancel); |
| 2363 |
range = getRange(); |
| 2364 |
} |
| 2365 |
const unsubscribePointerDown = subscribeDelegatedListener6( |
| 2366 |
element, |
| 2367 |
"pointerdown", |
| 2368 |
onDown |
| 2369 |
); |
| 2370 |
const unsubscribeKeyDown = subscribeDelegatedListener6( |
| 2371 |
element, |
| 2372 |
"keydown", |
| 2373 |
onDown |
| 2374 |
); |
| 2375 |
return () => { |
| 2376 |
unsubscribePointerDown(); |
| 2377 |
unsubscribeKeyDown(); |
| 2378 |
}; |
| 2379 |
}; |
| 2380 |
|
| 2381 |
// packages/rich-text/build-module/hook/event-listeners/prevent-focus-capture.mjs |
| 2382 |
var import_compose7 = __toESM(require_compose(), 1); |
| 2383 |
var { subscribeDelegatedListener: subscribeDelegatedListener7 } = unlock(import_compose7.privateApis); |
| 2384 |
function preventFocusCapture() { |
| 2385 |
return (element) => { |
| 2386 |
const { ownerDocument } = element; |
| 2387 |
const { defaultView } = ownerDocument; |
| 2388 |
let value = null; |
| 2389 |
function onPointerDown(event) { |
| 2390 |
if (event.defaultPrevented) { |
| 2391 |
return; |
| 2392 |
} |
| 2393 |
if (event.target === element) { |
| 2394 |
return; |
| 2395 |
} |
| 2396 |
if (!event.target.contains(element)) { |
| 2397 |
return; |
| 2398 |
} |
| 2399 |
value = element.getAttribute("contenteditable"); |
| 2400 |
element.setAttribute("contenteditable", "false"); |
| 2401 |
defaultView.getSelection().removeAllRanges(); |
| 2402 |
} |
| 2403 |
function onPointerUp() { |
| 2404 |
if (value !== null) { |
| 2405 |
element.setAttribute("contenteditable", value); |
| 2406 |
value = null; |
| 2407 |
} |
| 2408 |
} |
| 2409 |
const unsubscribePointerDown = subscribeDelegatedListener7( |
| 2410 |
defaultView, |
| 2411 |
"pointerdown", |
| 2412 |
onPointerDown |
| 2413 |
); |
| 2414 |
const unsubscribePointerUp = subscribeDelegatedListener7( |
| 2415 |
defaultView, |
| 2416 |
"pointerup", |
| 2417 |
onPointerUp |
| 2418 |
); |
| 2419 |
return () => { |
| 2420 |
unsubscribePointerDown(); |
| 2421 |
unsubscribePointerUp(); |
| 2422 |
}; |
| 2423 |
}; |
| 2424 |
} |
| 2425 |
|
| 2426 |
// packages/rich-text/build-module/hook/event-listeners/index.mjs |
| 2427 |
var allEventListeners = [ |
| 2428 |
copy_handler_default, |
| 2429 |
select_object_default, |
| 2430 |
format_boundaries_default, |
| 2431 |
delete_default, |
| 2432 |
input_and_selection_default, |
| 2433 |
selection_change_compat_default, |
| 2434 |
preventFocusCapture |
| 2435 |
]; |
| 2436 |
function useEventListeners(props) { |
| 2437 |
const propsRef = (0, import_element3.useRef)(props); |
| 2438 |
(0, import_element3.useInsertionEffect)(() => { |
| 2439 |
propsRef.current = props; |
| 2440 |
}); |
| 2441 |
const refEffects = (0, import_element3.useMemo)( |
| 2442 |
() => allEventListeners.map((refEffect) => refEffect(propsRef)), |
| 2443 |
[propsRef] |
| 2444 |
); |
| 2445 |
return (0, import_compose8.useRefEffect)( |
| 2446 |
(element) => { |
| 2447 |
const cleanups = refEffects.map((effect) => effect(element)); |
| 2448 |
return () => { |
| 2449 |
cleanups.forEach((cleanup) => cleanup()); |
| 2450 |
}; |
| 2451 |
}, |
| 2452 |
[refEffects] |
| 2453 |
); |
| 2454 |
} |
| 2455 |
|
| 2456 |
// packages/rich-text/build-module/hook/use-format-types.mjs |
| 2457 |
var import_element4 = __toESM(require_element(), 1); |
| 2458 |
var import_data8 = __toESM(require_data(), 1); |
| 2459 |
function formatTypesSelector(select5) { |
| 2460 |
return select5(store).getFormatTypes(); |
| 2461 |
} |
| 2462 |
var interactiveContentTags = /* @__PURE__ */ new Set([ |
| 2463 |
"a", |
| 2464 |
"audio", |
| 2465 |
"button", |
| 2466 |
"details", |
| 2467 |
"embed", |
| 2468 |
"iframe", |
| 2469 |
"input", |
| 2470 |
"label", |
| 2471 |
"select", |
| 2472 |
"textarea", |
| 2473 |
"video" |
| 2474 |
]); |
| 2475 |
function prefixSelectKeys(selected, prefix) { |
| 2476 |
if (typeof selected !== "object") { |
| 2477 |
return { [prefix]: selected }; |
| 2478 |
} |
| 2479 |
return Object.fromEntries( |
| 2480 |
Object.entries(selected).map(([key, value]) => [ |
| 2481 |
`${prefix}.${key}`, |
| 2482 |
value |
| 2483 |
]) |
| 2484 |
); |
| 2485 |
} |
| 2486 |
function getPrefixedSelectKeys(selected, prefix) { |
| 2487 |
if (selected[prefix]) { |
| 2488 |
return selected[prefix]; |
| 2489 |
} |
| 2490 |
return Object.keys(selected).filter((key) => key.startsWith(prefix + ".")).reduce((accumulator, key) => { |
| 2491 |
accumulator[key.slice(prefix.length + 1)] = selected[key]; |
| 2492 |
return accumulator; |
| 2493 |
}, {}); |
| 2494 |
} |
| 2495 |
function useFormatTypes({ |
| 2496 |
allowedFormats, |
| 2497 |
withoutInteractiveFormatting, |
| 2498 |
__unstableFormatTypeHandlerContext |
| 2499 |
}) { |
| 2500 |
const allFormatTypes = (0, import_data8.useSelect)(formatTypesSelector, []); |
| 2501 |
const formatTypes2 = (0, import_element4.useMemo)(() => { |
| 2502 |
return allFormatTypes.filter(({ name, interactive, tagName }) => { |
| 2503 |
if (allowedFormats && !allowedFormats.includes(name)) { |
| 2504 |
return false; |
| 2505 |
} |
| 2506 |
if (withoutInteractiveFormatting && (interactive || interactiveContentTags.has(tagName))) { |
| 2507 |
return false; |
| 2508 |
} |
| 2509 |
return true; |
| 2510 |
}); |
| 2511 |
}, [allFormatTypes, allowedFormats, withoutInteractiveFormatting]); |
| 2512 |
const keyedSelected = (0, import_data8.useSelect)( |
| 2513 |
(select5) => formatTypes2.reduce((accumulator, type) => { |
| 2514 |
if (!type.__experimentalGetPropsForEditableTreePreparation || !__unstableFormatTypeHandlerContext) { |
| 2515 |
return accumulator; |
| 2516 |
} |
| 2517 |
return { |
| 2518 |
...accumulator, |
| 2519 |
...prefixSelectKeys( |
| 2520 |
type.__experimentalGetPropsForEditableTreePreparation( |
| 2521 |
select5, |
| 2522 |
__unstableFormatTypeHandlerContext |
| 2523 |
), |
| 2524 |
type.name |
| 2525 |
) |
| 2526 |
}; |
| 2527 |
}, {}), |
| 2528 |
[formatTypes2, __unstableFormatTypeHandlerContext] |
| 2529 |
); |
| 2530 |
const dispatch3 = (0, import_data8.useDispatch)(); |
| 2531 |
const prepareHandlers = []; |
| 2532 |
const valueHandlers = []; |
| 2533 |
const changeHandlers = []; |
| 2534 |
const dependencies = []; |
| 2535 |
for (const key in keyedSelected) { |
| 2536 |
dependencies.push(keyedSelected[key]); |
| 2537 |
} |
| 2538 |
formatTypes2.forEach((type) => { |
| 2539 |
if (type.__experimentalCreatePrepareEditableTree && __unstableFormatTypeHandlerContext) { |
| 2540 |
const handler = type.__experimentalCreatePrepareEditableTree( |
| 2541 |
getPrefixedSelectKeys(keyedSelected, type.name), |
| 2542 |
__unstableFormatTypeHandlerContext |
| 2543 |
); |
| 2544 |
if (type.__experimentalCreateOnChangeEditableValue) { |
| 2545 |
valueHandlers.push(handler); |
| 2546 |
} else { |
| 2547 |
prepareHandlers.push(handler); |
| 2548 |
} |
| 2549 |
} |
| 2550 |
if (type.__experimentalCreateOnChangeEditableValue && __unstableFormatTypeHandlerContext) { |
| 2551 |
let dispatchers = {}; |
| 2552 |
if (type.__experimentalGetPropsForEditableTreeChangeHandler) { |
| 2553 |
dispatchers = type.__experimentalGetPropsForEditableTreeChangeHandler( |
| 2554 |
dispatch3, |
| 2555 |
__unstableFormatTypeHandlerContext |
| 2556 |
); |
| 2557 |
} |
| 2558 |
const selected = getPrefixedSelectKeys(keyedSelected, type.name); |
| 2559 |
changeHandlers.push( |
| 2560 |
type.__experimentalCreateOnChangeEditableValue( |
| 2561 |
{ |
| 2562 |
...typeof selected === "object" ? selected : {}, |
| 2563 |
...dispatchers |
| 2564 |
}, |
| 2565 |
__unstableFormatTypeHandlerContext |
| 2566 |
) |
| 2567 |
); |
| 2568 |
} |
| 2569 |
}); |
| 2570 |
return { |
| 2571 |
formatTypes: formatTypes2, |
| 2572 |
prepareHandlers, |
| 2573 |
valueHandlers, |
| 2574 |
changeHandlers, |
| 2575 |
dependencies |
| 2576 |
}; |
| 2577 |
} |
| 2578 |
|
| 2579 |
// packages/rich-text/build-module/hook/index.mjs |
| 2580 |
function useRichTextBase({ |
| 2581 |
value = "", |
| 2582 |
selectionStart, |
| 2583 |
selectionEnd, |
| 2584 |
placeholder, |
| 2585 |
onSelectionChange, |
| 2586 |
preserveWhiteSpace, |
| 2587 |
onChange, |
| 2588 |
__unstableDisableFormats: disableFormats, |
| 2589 |
__unstableIsSelected: isSelected, |
| 2590 |
__unstableDependencies = [], |
| 2591 |
__unstableAfterParse, |
| 2592 |
__unstableBeforeSerialize, |
| 2593 |
__unstableAddInvisibleFormats |
| 2594 |
}) { |
| 2595 |
const registry = (0, import_data9.useRegistry)(); |
| 2596 |
const [, forceRender] = (0, import_element5.useReducer)(() => ({})); |
| 2597 |
const ref = (0, import_element5.useRef)(); |
| 2598 |
function createRecord() { |
| 2599 |
const { |
| 2600 |
ownerDocument: { defaultView } |
| 2601 |
} = ref.current; |
| 2602 |
const selection = defaultView.getSelection(); |
| 2603 |
const range = selection.rangeCount > 0 ? selection.getRangeAt(0) : null; |
| 2604 |
return create({ |
| 2605 |
element: ref.current, |
| 2606 |
range, |
| 2607 |
__unstableIsEditableTree: true |
| 2608 |
}); |
| 2609 |
} |
| 2610 |
function applyRecord(newRecord, { domOnly } = {}) { |
| 2611 |
apply({ |
| 2612 |
value: newRecord, |
| 2613 |
current: ref.current, |
| 2614 |
prepareEditableTree: __unstableAddInvisibleFormats, |
| 2615 |
__unstableDomOnly: domOnly, |
| 2616 |
placeholder |
| 2617 |
}); |
| 2618 |
} |
| 2619 |
const _valueRef = (0, import_element5.useRef)(value); |
| 2620 |
const recordRef = (0, import_element5.useRef)(); |
| 2621 |
function setRecordFromProps() { |
| 2622 |
const activeFormats = recordRef.current?.activeFormats; |
| 2623 |
_valueRef.current = value; |
| 2624 |
recordRef.current = value; |
| 2625 |
if (!(value instanceof RichTextData)) { |
| 2626 |
recordRef.current = value ? RichTextData.fromHTMLString(value, { preserveWhiteSpace }) : RichTextData.empty(); |
| 2627 |
} |
| 2628 |
recordRef.current = { |
| 2629 |
text: recordRef.current.text, |
| 2630 |
formats: recordRef.current.formats, |
| 2631 |
replacements: recordRef.current.replacements, |
| 2632 |
activeFormats |
| 2633 |
}; |
| 2634 |
if (disableFormats) { |
| 2635 |
recordRef.current.formats = Array(value.length); |
| 2636 |
recordRef.current.replacements = Array(value.length); |
| 2637 |
} |
| 2638 |
if (__unstableAfterParse) { |
| 2639 |
recordRef.current.formats = __unstableAfterParse( |
| 2640 |
recordRef.current |
| 2641 |
); |
| 2642 |
} |
| 2643 |
recordRef.current.start = selectionStart; |
| 2644 |
recordRef.current.end = selectionEnd; |
| 2645 |
} |
| 2646 |
const hadSelectionUpdateRef = (0, import_element5.useRef)(false); |
| 2647 |
if (!recordRef.current) { |
| 2648 |
hadSelectionUpdateRef.current = isSelected; |
| 2649 |
setRecordFromProps(); |
| 2650 |
} else if (selectionStart !== recordRef.current.start || selectionEnd !== recordRef.current.end) { |
| 2651 |
hadSelectionUpdateRef.current = isSelected; |
| 2652 |
recordRef.current = { |
| 2653 |
...recordRef.current, |
| 2654 |
start: selectionStart, |
| 2655 |
end: selectionEnd, |
| 2656 |
activeFormats: void 0 |
| 2657 |
}; |
| 2658 |
} |
| 2659 |
function handleChange(newRecord) { |
| 2660 |
recordRef.current = newRecord; |
| 2661 |
applyRecord(newRecord); |
| 2662 |
if (disableFormats) { |
| 2663 |
_valueRef.current = newRecord.text; |
| 2664 |
} else { |
| 2665 |
const newFormats = __unstableBeforeSerialize ? __unstableBeforeSerialize(newRecord) : newRecord.formats; |
| 2666 |
newRecord = { ...newRecord, formats: newFormats }; |
| 2667 |
if (typeof value === "string") { |
| 2668 |
_valueRef.current = toHTMLString({ |
| 2669 |
value: newRecord, |
| 2670 |
preserveWhiteSpace |
| 2671 |
}); |
| 2672 |
} else { |
| 2673 |
_valueRef.current = new RichTextData(newRecord); |
| 2674 |
} |
| 2675 |
} |
| 2676 |
const { start, end, formats, text } = recordRef.current; |
| 2677 |
registry.batch(() => { |
| 2678 |
onSelectionChange(start, end); |
| 2679 |
onChange(_valueRef.current, { |
| 2680 |
__unstableFormats: formats, |
| 2681 |
__unstableText: text |
| 2682 |
}); |
| 2683 |
}); |
| 2684 |
forceRender(); |
| 2685 |
} |
| 2686 |
function applyFromProps() { |
| 2687 |
const previousValue = _valueRef.current; |
| 2688 |
setRecordFromProps(); |
| 2689 |
const contentLengthChanged = previousValue && typeof previousValue === "string" && typeof value === "string" && previousValue.length !== value.length; |
| 2690 |
const hasFocus = ref.current?.contains( |
| 2691 |
ref.current.ownerDocument.activeElement |
| 2692 |
); |
| 2693 |
const skipSelection = contentLengthChanged && !hasFocus; |
| 2694 |
applyRecord(recordRef.current, { domOnly: skipSelection }); |
| 2695 |
} |
| 2696 |
const didMountRef = (0, import_element5.useRef)(false); |
| 2697 |
(0, import_element5.useLayoutEffect)(() => { |
| 2698 |
if (didMountRef.current && value !== _valueRef.current) { |
| 2699 |
applyFromProps(); |
| 2700 |
forceRender(); |
| 2701 |
} |
| 2702 |
}, [value]); |
| 2703 |
(0, import_element5.useLayoutEffect)(() => { |
| 2704 |
if (!hadSelectionUpdateRef.current) { |
| 2705 |
return; |
| 2706 |
} |
| 2707 |
if (ref.current.ownerDocument.activeElement !== ref.current) { |
| 2708 |
ref.current.focus(); |
| 2709 |
} |
| 2710 |
applyRecord(recordRef.current); |
| 2711 |
hadSelectionUpdateRef.current = false; |
| 2712 |
}, [hadSelectionUpdateRef.current]); |
| 2713 |
const mergedRefs = (0, import_compose9.useMergeRefs)([ |
| 2714 |
ref, |
| 2715 |
useDefaultStyle(), |
| 2716 |
useBoundaryStyle({ record: recordRef }), |
| 2717 |
useEventListeners({ |
| 2718 |
record: recordRef, |
| 2719 |
handleChange, |
| 2720 |
applyRecord, |
| 2721 |
createRecord, |
| 2722 |
isSelected, |
| 2723 |
onSelectionChange, |
| 2724 |
forceRender |
| 2725 |
}), |
| 2726 |
(0, import_compose9.useRefEffect)(() => { |
| 2727 |
applyFromProps(); |
| 2728 |
didMountRef.current = true; |
| 2729 |
}, [placeholder, ...__unstableDependencies]) |
| 2730 |
]); |
| 2731 |
return { |
| 2732 |
value: recordRef.current, |
| 2733 |
// A function to get the most recent value so event handlers in |
| 2734 |
// useRichText implementations have access to it. For example when |
| 2735 |
// listening to input events, we internally update the state, but this |
| 2736 |
// state is not yet available to the input event handler because React |
| 2737 |
// may re-render asynchronously. |
| 2738 |
getValue: () => recordRef.current, |
| 2739 |
onChange: handleChange, |
| 2740 |
ref: mergedRefs |
| 2741 |
}; |
| 2742 |
} |
| 2743 |
function useRichText({ |
| 2744 |
allowedFormats, |
| 2745 |
withoutInteractiveFormatting, |
| 2746 |
onChange, |
| 2747 |
__unstableDependencies = [], |
| 2748 |
__unstableFormatTypeHandlerContext, |
| 2749 |
...props |
| 2750 |
}) { |
| 2751 |
const { |
| 2752 |
formatTypes: formatTypes2, |
| 2753 |
prepareHandlers, |
| 2754 |
valueHandlers, |
| 2755 |
changeHandlers, |
| 2756 |
dependencies |
| 2757 |
} = useFormatTypes({ |
| 2758 |
allowedFormats, |
| 2759 |
withoutInteractiveFormatting, |
| 2760 |
__unstableFormatTypeHandlerContext |
| 2761 |
}); |
| 2762 |
function addEditorOnlyFormats(record) { |
| 2763 |
return valueHandlers.reduce( |
| 2764 |
(accumulator, fn) => fn(accumulator, record.text), |
| 2765 |
record.formats |
| 2766 |
); |
| 2767 |
} |
| 2768 |
function removeEditorOnlyFormats(record) { |
| 2769 |
formatTypes2.forEach((formatType) => { |
| 2770 |
if (formatType.__experimentalCreatePrepareEditableTree) { |
| 2771 |
record = removeFormat( |
| 2772 |
record, |
| 2773 |
formatType.name, |
| 2774 |
0, |
| 2775 |
record.text.length |
| 2776 |
); |
| 2777 |
} |
| 2778 |
}); |
| 2779 |
return record.formats; |
| 2780 |
} |
| 2781 |
function addInvisibleFormats(record) { |
| 2782 |
return prepareHandlers.reduce( |
| 2783 |
(accumulator, fn) => fn(accumulator, record.text), |
| 2784 |
record.formats |
| 2785 |
); |
| 2786 |
} |
| 2787 |
const result = useRichTextBase({ |
| 2788 |
...props, |
| 2789 |
onChange(value, { __unstableFormats, __unstableText }) { |
| 2790 |
onChange(value, { __unstableFormats, __unstableText }); |
| 2791 |
Object.values(changeHandlers).forEach((changeHandler) => { |
| 2792 |
changeHandler(__unstableFormats, __unstableText); |
| 2793 |
}); |
| 2794 |
}, |
| 2795 |
__unstableDependencies: [...dependencies, ...__unstableDependencies], |
| 2796 |
__unstableAfterParse: addEditorOnlyFormats, |
| 2797 |
__unstableBeforeSerialize: removeEditorOnlyFormats, |
| 2798 |
__unstableAddInvisibleFormats: addInvisibleFormats |
| 2799 |
}); |
| 2800 |
return { ...result, formatTypes: formatTypes2 }; |
| 2801 |
} |
| 2802 |
function useDeprecatedRichText(props) { |
| 2803 |
(0, import_deprecated.default)("`__unstableUseRichText` hook", { |
| 2804 |
since: "7.0" |
| 2805 |
}); |
| 2806 |
return useRichTextBase(props); |
| 2807 |
} |
| 2808 |
|
| 2809 |
// packages/rich-text/build-module/private-apis.mjs |
| 2810 |
var privateApis = {}; |
| 2811 |
lock(privateApis, { |
| 2812 |
useRichText |
| 2813 |
}); |
| 2814 |
|
| 2815 |
// packages/rich-text/build-module/hook/use-anchor-ref.mjs |
| 2816 |
var import_element6 = __toESM(require_element(), 1); |
| 2817 |
var import_deprecated2 = __toESM(require_deprecated(), 1); |
| 2818 |
function useAnchorRef({ ref, value, settings = {} }) { |
| 2819 |
(0, import_deprecated2.default)("`useAnchorRef` hook", { |
| 2820 |
since: "6.1", |
| 2821 |
alternative: "`useAnchor` hook" |
| 2822 |
}); |
| 2823 |
const { tagName, className, name } = settings; |
| 2824 |
const activeFormat = name ? getActiveFormat(value, name) : void 0; |
| 2825 |
return (0, import_element6.useMemo)(() => { |
| 2826 |
if (!ref.current) { |
| 2827 |
return; |
| 2828 |
} |
| 2829 |
const { |
| 2830 |
ownerDocument: { defaultView } |
| 2831 |
} = ref.current; |
| 2832 |
const selection = defaultView.getSelection(); |
| 2833 |
if (!selection.rangeCount) { |
| 2834 |
return; |
| 2835 |
} |
| 2836 |
const range = selection.getRangeAt(0); |
| 2837 |
if (!activeFormat) { |
| 2838 |
return range; |
| 2839 |
} |
| 2840 |
let element = range.startContainer; |
| 2841 |
element = element.nextElementSibling || element; |
| 2842 |
while (element.nodeType !== element.ELEMENT_NODE) { |
| 2843 |
element = element.parentNode; |
| 2844 |
} |
| 2845 |
return element.closest( |
| 2846 |
tagName + (className ? "." + className : "") |
| 2847 |
); |
| 2848 |
}, [activeFormat, value.start, value.end, tagName, className]); |
| 2849 |
} |
| 2850 |
|
| 2851 |
// packages/rich-text/build-module/hook/use-anchor.mjs |
| 2852 |
var import_compose10 = __toESM(require_compose(), 1); |
| 2853 |
var import_element7 = __toESM(require_element(), 1); |
| 2854 |
var import_dom = __toESM(require_dom(), 1); |
| 2855 |
function getFormatElement(range, editableContentElement, tagName, className) { |
| 2856 |
let element = range.startContainer; |
| 2857 |
if (element.nodeType === element.TEXT_NODE && element instanceof window.Text && range.startOffset === element.length && element.nextSibling) { |
| 2858 |
element = element.nextSibling; |
| 2859 |
while (element.firstChild) { |
| 2860 |
element = element.firstChild; |
| 2861 |
} |
| 2862 |
} |
| 2863 |
if (element.nodeType !== element.ELEMENT_NODE) { |
| 2864 |
if (!element.parentElement) { |
| 2865 |
return; |
| 2866 |
} |
| 2867 |
element = element.parentElement; |
| 2868 |
} |
| 2869 |
if (element === editableContentElement) { |
| 2870 |
return; |
| 2871 |
} |
| 2872 |
if (!editableContentElement.contains(element)) { |
| 2873 |
return; |
| 2874 |
} |
| 2875 |
const selector = tagName + (className ? "." + className : ""); |
| 2876 |
if (!selector) { |
| 2877 |
return; |
| 2878 |
} |
| 2879 |
if (!(element instanceof window.HTMLElement)) { |
| 2880 |
return; |
| 2881 |
} |
| 2882 |
let closestElement = element; |
| 2883 |
while (closestElement && closestElement !== editableContentElement) { |
| 2884 |
if (closestElement.matches(selector)) { |
| 2885 |
return closestElement; |
| 2886 |
} |
| 2887 |
closestElement = closestElement.parentElement; |
| 2888 |
} |
| 2889 |
return void 0; |
| 2890 |
} |
| 2891 |
function createVirtualAnchorElement(range, editableContentElement) { |
| 2892 |
return { |
| 2893 |
contextElement: editableContentElement, |
| 2894 |
getBoundingClientRect() { |
| 2895 |
if (editableContentElement.contains(range.startContainer)) { |
| 2896 |
return (0, import_dom.getRectangleFromRange)(range) ?? range.getBoundingClientRect(); |
| 2897 |
} |
| 2898 |
return editableContentElement.getBoundingClientRect(); |
| 2899 |
} |
| 2900 |
}; |
| 2901 |
} |
| 2902 |
function getAnchor(editableContentElement, tagName, className) { |
| 2903 |
if (!editableContentElement) { |
| 2904 |
return; |
| 2905 |
} |
| 2906 |
const { ownerDocument } = editableContentElement; |
| 2907 |
const { defaultView } = ownerDocument; |
| 2908 |
const selection = defaultView?.getSelection(); |
| 2909 |
if (!selection) { |
| 2910 |
return; |
| 2911 |
} |
| 2912 |
if (!selection.rangeCount) { |
| 2913 |
return; |
| 2914 |
} |
| 2915 |
const range = selection.getRangeAt(0); |
| 2916 |
if (!range || !range.startContainer) { |
| 2917 |
return; |
| 2918 |
} |
| 2919 |
if (!tagName && !className) { |
| 2920 |
return createVirtualAnchorElement(range, editableContentElement); |
| 2921 |
} |
| 2922 |
return getFormatElement(range, editableContentElement, tagName, className) ?? createVirtualAnchorElement(range, editableContentElement); |
| 2923 |
} |
| 2924 |
var DEFAULT_SETTINGS = { |
| 2925 |
tagName: "", |
| 2926 |
className: "" |
| 2927 |
}; |
| 2928 |
function useAnchor({ |
| 2929 |
editableContentElement, |
| 2930 |
settings |
| 2931 |
}) { |
| 2932 |
const { tagName, className } = settings ?? DEFAULT_SETTINGS; |
| 2933 |
const isActive = !!(settings && "isActive" in settings && settings.isActive); |
| 2934 |
const [anchor, setAnchor] = (0, import_element7.useState)( |
| 2935 |
() => getAnchor(editableContentElement, tagName, className ?? "") |
| 2936 |
); |
| 2937 |
const wasActive = (0, import_compose10.usePrevious)(isActive); |
| 2938 |
(0, import_element7.useLayoutEffect)(() => { |
| 2939 |
if (!editableContentElement) { |
| 2940 |
return; |
| 2941 |
} |
| 2942 |
function callback() { |
| 2943 |
setAnchor( |
| 2944 |
getAnchor(editableContentElement, tagName, className ?? "") |
| 2945 |
); |
| 2946 |
} |
| 2947 |
function attach() { |
| 2948 |
ownerDocument.addEventListener("selectionchange", callback); |
| 2949 |
} |
| 2950 |
function detach() { |
| 2951 |
ownerDocument.removeEventListener("selectionchange", callback); |
| 2952 |
} |
| 2953 |
const { ownerDocument } = editableContentElement; |
| 2954 |
if (editableContentElement === ownerDocument.activeElement || // When a link is created, we need to attach the popover to the newly created anchor. |
| 2955 |
!wasActive && isActive || // Sometimes we're _removing_ an active anchor, such as the inline color popover. |
| 2956 |
// When we add the color, it switches from a virtual anchor to a `<mark>` element. |
| 2957 |
// When we _remove_ the color, it switches from a `<mark>` element to a virtual anchor. |
| 2958 |
wasActive && !isActive) { |
| 2959 |
setAnchor( |
| 2960 |
getAnchor(editableContentElement, tagName, className ?? "") |
| 2961 |
); |
| 2962 |
attach(); |
| 2963 |
} |
| 2964 |
editableContentElement.addEventListener("focusin", attach); |
| 2965 |
editableContentElement.addEventListener("focusout", detach); |
| 2966 |
return () => { |
| 2967 |
detach(); |
| 2968 |
editableContentElement.removeEventListener("focusin", attach); |
| 2969 |
editableContentElement.removeEventListener("focusout", detach); |
| 2970 |
}; |
| 2971 |
}, [editableContentElement, tagName, className, isActive, wasActive]); |
| 2972 |
return anchor; |
| 2973 |
} |
| 2974 |
|
| 2975 |
// packages/rich-text/build-module/index.mjs |
| 2976 |
function __experimentalRichText() { |
| 2977 |
} |
| 2978 |
return __toCommonJS(index_exports); |
| 2979 |
})(); |
| 2980 |
if(wp.richText&&typeof wp.richText==='object'){wp.richText=Object.assign({},wp.richText);} |
| 2981 |
//# sourceMappingURL=index.js.map |
| 2982 |
|