@remirror/core
Version:
Where your quest to create a world class editing experience begins.
1,440 lines (1,427 loc) • 189 kB
JavaScript
var __create = Object.create;
var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __knownSymbol = (name, symbol) => (symbol = Symbol[name]) ? symbol : Symbol.for("Symbol." + name);
var __typeError = (msg) => {
throw TypeError(msg);
};
var __defNormalProp = (obj, key2, value) => key2 in obj ? __defProp(obj, key2, { enumerable: true, configurable: true, writable: true, value }) : obj[key2] = value;
var __spreadValues = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp.call(b, prop))
__defNormalProp(a, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp(a, prop, b[prop]);
}
return a;
};
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
var __objRest = (source, exclude) => {
var target = {};
for (var prop in source)
if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
target[prop] = source[prop];
if (source != null && __getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(source)) {
if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
target[prop] = source[prop];
}
return target;
};
var __decoratorStart = (base) => {
var _a12;
return [, , , __create((_a12 = base == null ? void 0 : base[__knownSymbol("metadata")]) != null ? _a12 : null)];
};
var __decoratorStrings = ["class", "method", "getter", "setter", "accessor", "field", "value", "get", "set"];
var __expectFn = (fn) => fn !== void 0 && typeof fn !== "function" ? __typeError("Function expected") : fn;
var __decoratorContext = (kind, name, done, metadata, fns) => ({ kind: __decoratorStrings[kind], name, metadata, addInitializer: (fn) => done._ ? __typeError("Already initialized") : fns.push(__expectFn(fn || null)) });
var __decoratorMetadata = (array, target) => __defNormalProp(target, __knownSymbol("metadata"), array[3]);
var __runInitializers = (array, flags, self, value) => {
for (var i = 0, fns = array[flags >> 1], n = fns && fns.length; i < n; i++) flags & 1 ? fns[i].call(self) : value = fns[i].call(self, value);
return value;
};
var __decorateElement = (array, flags, name, decorators, target, extra) => {
var fn, it, done, ctx, access, k = flags & 7, s = !!(flags & 8), p = !!(flags & 16);
var j = k > 3 ? array.length + 1 : k ? s ? 1 : 2 : 0, key2 = __decoratorStrings[k + 5];
var initializers = k > 3 && (array[j - 1] = []), extraInitializers = array[j] || (array[j] = []);
var desc = k && (!p && !s && (target = target.prototype), k < 5 && (k > 3 || !p) && __getOwnPropDesc(k < 4 ? target : { get [name]() {
return __privateGet(this, extra);
}, set [name](x) {
return __privateSet(this, extra, x);
} }, name));
k ? p && k < 4 && __name(extra, (k > 2 ? "set " : k > 1 ? "get " : "") + name) : __name(target, name);
for (var i = decorators.length - 1; i >= 0; i--) {
ctx = __decoratorContext(k, name, done = {}, array[3], extraInitializers);
if (k) {
ctx.static = s, ctx.private = p, access = ctx.access = { has: p ? (x) => __privateIn(target, x) : (x) => name in x };
if (k ^ 3) access.get = p ? (x) => (k ^ 1 ? __privateGet : __privateMethod)(x, target, k ^ 4 ? extra : desc.get) : (x) => x[name];
if (k > 2) access.set = p ? (x, y) => __privateSet(x, target, y, k ^ 4 ? extra : desc.set) : (x, y) => x[name] = y;
}
it = (0, decorators[i])(k ? k < 4 ? p ? extra : desc[key2] : k > 4 ? void 0 : { get: desc.get, set: desc.set } : target, ctx), done._ = 1;
if (k ^ 4 || it === void 0) __expectFn(it) && (k > 4 ? initializers.unshift(it) : k ? p ? extra = it : desc[key2] = it : target = it);
else if (typeof it !== "object" || it === null) __typeError("Object expected");
else __expectFn(fn = it.get) && (desc.get = fn), __expectFn(fn = it.set) && (desc.set = fn), __expectFn(fn = it.init) && initializers.unshift(fn);
}
return k || __decoratorMetadata(array, target), desc && __defProp(target, name, desc), p ? k ^ 4 ? extra : desc : target;
};
var __publicField = (obj, key2, value) => __defNormalProp(obj, typeof key2 !== "symbol" ? key2 + "" : key2, value);
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
var __privateIn = (member, obj) => Object(obj) !== obj ? __typeError('Cannot use the "in" operator on this value') : member.has(obj);
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
// src/builtins/attributes-extension.ts
import { cx, object as object3 } from "@remirror/core-helpers";
// src/extension/extension.ts
import {
__INTERNAL_REMIRROR_IDENTIFIER_KEY__ as __INTERNAL_REMIRROR_IDENTIFIER_KEY__2,
ErrorConstant as ErrorConstant3,
ExtensionPriority as ExtensionPriority2,
RemirrorIdentifier as RemirrorIdentifier2
} from "@remirror/core-constants";
import { assertGet, freeze as freeze2, invariant as invariant3, pascalCase, uniqueBy } from "@remirror/core-helpers";
import { isIdentifierOfType, isRemirrorType } from "@remirror/core-utils";
// src/extension/base-class.ts
import {
ErrorConstant as ErrorConstant2,
ExtensionPriority
} from "@remirror/core-constants";
import {
deepMerge,
invariant as invariant2,
isEmptyArray,
isFunction,
keys as keys2,
noop,
object as object2,
omit,
sort
} from "@remirror/core-helpers";
import { environment } from "@remirror/core-utils";
// src/helpers.ts
import { ErrorConstant } from "@remirror/core-constants";
import { freeze, invariant, keys, object } from "@remirror/core-helpers";
function defaultEquals(valueA, valueB) {
return valueA === valueB;
}
function getChangedOptions(props) {
const { previousOptions, update, equals = defaultEquals } = props;
const next = freeze(__spreadValues(__spreadValues({}, previousOptions), update));
const changes = object();
const optionKeys = keys(previousOptions);
for (const key2 of optionKeys) {
const previousValue = previousOptions[key2];
const value = next[key2];
if (equals(previousValue, value)) {
changes[key2] = { changed: false };
continue;
}
changes[key2] = { changed: true, previousValue, value };
}
const pickChanged = (keys3) => {
const picked = object();
for (const key2 of keys3) {
const item = changes[key2];
if (item == null ? void 0 : item.changed) {
picked[key2] = item.value;
}
}
return picked;
};
return { changes: freeze(changes), options: next, pickChanged };
}
var codeLabelMap = {
[ErrorConstant.DUPLICATE_HELPER_NAMES]: "helper method",
[ErrorConstant.DUPLICATE_COMMAND_NAMES]: "command method"
};
function throwIfNameNotUnique(props) {
const { name, set, code } = props;
const label = codeLabelMap[code];
invariant(!set.has(name), {
code,
message: "There is a naming conflict for the name: ".concat(name, " used in this '").concat(label, "'. Please rename or remove from the editor to avoid runtime errors.")
});
set.add(name);
}
// src/extension/base-class.ts
var IGNORE = "__IGNORE__";
var GENERAL_OPTIONS = "__ALL__";
var BaseClass = class {
constructor(defaultOptions2, ...[options]) {
/**
* This is not for external use. It is purely here for TypeScript inference of
* the generic `Options` type parameter.
*
* @internal
*/
__publicField(this, "~O", {});
/**
* The initial options at creation (used to reset).
*/
__publicField(this, "_initialOptions");
/**
* All the dynamic keys supported by this extension.
*/
__publicField(this, "_dynamicKeys");
/**
* Private instance of the extension options.
*/
__publicField(this, "_options");
/**
* The mapped function handlers.
*/
__publicField(this, "_mappedHandlers");
/**
* Override this method if you want to set custom handlers on your extension.
*
* This must return a dispose function.
*/
__publicField(this, "onAddCustomHandler");
this._mappedHandlers = object2();
this.populateMappedHandlers();
this._options = this._initialOptions = deepMerge(
defaultOptions2,
this.constructor.defaultOptions,
options != null ? options : object2(),
this.createDefaultHandlerOptions()
);
this._dynamicKeys = this.getDynamicKeys();
this.init();
}
/**
* The options for this extension.
*
* @remarks
*
* Options are composed of Static, Dynamic, Handlers and ObjectHandlers.
*
* - `Static` - set at instantiation by the constructor.
* - `Dynamic` - optionally set at instantiation by the constructor and also
* set during the runtime.
* - `Handlers` - can only be set during the runtime.
* - `ObjectHandlers` - Can only be set during the runtime of the extension.
*/
get options() {
return this._options;
}
/**
* Get the dynamic keys for this extension.
*/
get dynamicKeys() {
return this._dynamicKeys;
}
/**
* The options that this instance was created with, merged with all the
* default options.
*/
get initialOptions() {
return this._initialOptions;
}
/**
* This method is called by the extension constructor. It is not strictly a
* lifecycle method since at this point the manager has not yet been
* instantiated.
*
* @remarks
*
* It should be used instead of overriding the constructor which is strongly
* advised against.
*
* There are some limitations when using this method.
*
* - Accessing `this.store` will throw an error since the manager hasn't been
* created and it hasn't yet been attached to the extensions.
* - `this.type` in `NodeExtension` and `MarkExtension` will also throw an
* error since the schema hasn't been created yet.
*
* You should use this to setup any instance properties with the options
* provided to the extension.
*/
init() {
}
/**
* Get the dynamic keys for this extension.
*/
getDynamicKeys() {
const dynamicKeys = [];
const { customHandlerKeys, handlerKeys, staticKeys } = this.constructor;
for (const key2 of keys2(this._options)) {
if (staticKeys.includes(key2) || handlerKeys.includes(key2) || customHandlerKeys.includes(key2)) {
continue;
}
dynamicKeys.push(key2);
}
return dynamicKeys;
}
/**
* Throw an error if non dynamic keys are updated.
*/
ensureAllKeysAreDynamic(update) {
if (environment.isProduction) {
return;
}
const invalid = [];
for (const key2 of keys2(update)) {
if (this._dynamicKeys.includes(key2)) {
continue;
}
invalid.push(key2);
}
invariant2(isEmptyArray(invalid), {
code: ErrorConstant2.INVALID_SET_EXTENSION_OPTIONS,
message: "Invalid properties passed into the 'setOptions()' method: ".concat(JSON.stringify(
invalid
), ".")
});
}
/**
* Update the properties with the provided partial value when changed.
*/
setOptions(update) {
var _a12;
const previousOptions = this.getDynamicOptions();
this.ensureAllKeysAreDynamic(update);
const { changes, options, pickChanged } = getChangedOptions({
previousOptions,
update
});
this.updateDynamicOptions(options);
(_a12 = this.onSetOptions) == null ? void 0 : _a12.call(this, {
reason: "set",
changes,
options,
pickChanged,
initialOptions: this._initialOptions
});
}
/**
* Reset the extension properties to their default values.
*
* @nonVirtual
*/
resetOptions() {
var _a12;
const previousOptions = this.getDynamicOptions();
const { changes, options, pickChanged } = getChangedOptions({
previousOptions,
update: this._initialOptions
});
this.updateDynamicOptions(options);
(_a12 = this.onSetOptions) == null ? void 0 : _a12.call(this, {
reason: "reset",
options,
changes,
pickChanged,
initialOptions: this._initialOptions
});
}
/**
* Update the private options.
*/
getDynamicOptions() {
return omit(this._options, [
...this.constructor.customHandlerKeys,
...this.constructor.handlerKeys
]);
}
/**
* Update the dynamic options.
*/
updateDynamicOptions(options) {
this._options = __spreadValues(__spreadValues({}, this._options), options);
}
/**
* Set up the mapped handlers object with default values (an empty array);
*/
populateMappedHandlers() {
for (const key2 of this.constructor.handlerKeys) {
this._mappedHandlers[key2] = [];
}
}
/**
* This is currently fudged together, I'm not sure it will work.
*/
createDefaultHandlerOptions() {
const methods = object2();
for (const key2 of this.constructor.handlerKeys) {
methods[key2] = (...args) => {
var _a12;
const { handlerKeyOptions } = this.constructor;
const reducer = (_a12 = handlerKeyOptions[key2]) == null ? void 0 : _a12.reducer;
let returnValue = reducer == null ? void 0 : reducer.getDefault(...args);
for (const [, handler] of this._mappedHandlers[key2]) {
const value = handler(...args);
returnValue = reducer ? reducer.accumulator(returnValue, value, ...args) : value;
if (shouldReturnEarly(handlerKeyOptions, returnValue, key2)) {
return returnValue;
}
}
return returnValue;
};
}
return methods;
}
/**
* Add a handler to the event handlers so that it is called along with all the
* other handler methods.
*
* This is helpful for integrating react hooks which can be used in multiple
* places. The original problem with fixed properties is that you can only
* assign to a method once and it overwrites any other methods. This pattern
* for adding handlers allows for multiple usages of the same handler in the
* most relevant part of the code.
*
* More to come on this pattern.
*
* @nonVirtual
*/
addHandler(key2, method, priority = ExtensionPriority.Default) {
this._mappedHandlers[key2].push([priority, method]);
this.sortHandlers(key2);
return () => this._mappedHandlers[key2] = this._mappedHandlers[key2].filter(
([, handler]) => handler !== method
);
}
/**
* Determines if handlers exist for the given key.
*
* Checking the existence of a handler property directly gives wrong results.
* `this.options.onHandlerName` is always truthy because it is a reference to
* the wrapper function that calls each handler.
*
* ```ts
*
* // GOOD ✅
* if (!this.hasHandlers('onHandlerName')) {
* return;
* }
*
* // BAD ❌
* if (!this.options.onHandlerName) {
* return;
* }
* ```
*
* @param key The handler to test
*/
hasHandlers(key2) {
var _a12;
return ((_a12 = this._mappedHandlers[key2]) != null ? _a12 : []).length > 0;
}
sortHandlers(key2) {
this._mappedHandlers[key2] = sort(
this._mappedHandlers[key2],
// Sort from highest binding to the lowest.
([a], [z]) => z - a
);
}
/**
* A method that can be used to add a custom handler. It is up to the
* extension creator to manage the handlers and dispose methods.
*/
addCustomHandler(key2, value) {
var _a12, _b;
return (_b = (_a12 = this.onAddCustomHandler) == null ? void 0 : _a12.call(this, { [key2]: value })) != null ? _b : noop;
}
};
/**
* The default options for this extension.
*
* TODO see if this can be cast to something other than any and allow
* composition.
*/
__publicField(BaseClass, "defaultOptions", {});
/**
* The static keys for this class.
*/
__publicField(BaseClass, "staticKeys", []);
/**
* The event handler keys.
*/
__publicField(BaseClass, "handlerKeys", []);
/**
* Customize the way the handler should behave.
*/
__publicField(BaseClass, "handlerKeyOptions", {});
/**
* The custom keys.
*/
__publicField(BaseClass, "customHandlerKeys", []);
function shouldReturnEarly(handlerKeyOptions, returnValue, handlerKey) {
const { [GENERAL_OPTIONS]: generalOptions } = handlerKeyOptions;
const handlerOptions = handlerKeyOptions[handlerKey];
if (!generalOptions && !handlerOptions) {
return false;
}
if (handlerOptions && // Only proceed if the value should not be ignored.
handlerOptions.earlyReturnValue !== IGNORE && (isFunction(handlerOptions.earlyReturnValue) ? handlerOptions.earlyReturnValue(returnValue) === true : returnValue === handlerOptions.earlyReturnValue)) {
return true;
}
if (generalOptions && // Only proceed if they are not ignored.
generalOptions.earlyReturnValue !== IGNORE && // Check whether the `earlyReturnValue` is a predicate check.
(isFunction(generalOptions.earlyReturnValue) ? (
// If it is a predicate and when called with the current
// `returnValue` the value is `true` then we should return
// early.
generalOptions.earlyReturnValue(returnValue) === true
) : (
// Check the actual return value.
returnValue === generalOptions.earlyReturnValue
))) {
return true;
}
return false;
}
// src/extension/extension.ts
var Extension = class extends BaseClass {
constructor(...args) {
super(defaultOptions, ...args);
/**
* Allows for the `RemirrorManager` or `Preset`'s to override the priority of
* an extension.
*/
__publicField(this, "priorityOverride");
/**
* Private list of extension stored within this [[`Preset`]].
*/
__publicField(this, "_extensions");
/**
* An extension mapping of the extensions and their constructors.
*/
__publicField(this, "extensionMap");
/**
* This store is can be modified by the extension manager with and lifecycle
* extension methods.
*
* Different properties are added at different times so it's important to
* check the documentation for each property to know what phase is being
* added.
*/
__publicField(this, "_store");
/**
* Not for usage. This is purely for types to make it easier to infer
* available sub extension types.
*
* @internal
*/
__publicField(this, "~E", {});
this._extensions = uniqueBy(
this.createExtensions(),
// Ensure that all the provided extensions are unique.
(extension2) => extension2.constructor
);
this.extensionMap = /* @__PURE__ */ new Map();
for (const extension2 of this._extensions) {
this.extensionMap.set(extension2.constructor, extension2);
}
}
/**
* The priority level for this instance of the extension. A higher value
* corresponds to a higher priority extension
*/
get priority() {
var _a12, _b;
return (_b = (_a12 = this.priorityOverride) != null ? _a12 : this.options.priority) != null ? _b : this.constructor.defaultPriority;
}
/**
* The name that the constructor should have, which doesn't get mangled in
* production.
*/
get constructorName() {
return "".concat(pascalCase(this.name), "Extension");
}
/**
* The store is a shared object that's internal to each extension. It includes
* often used items like the `view` and `schema` that are added by the
* extension manager and also the lifecycle extension methods.
*
* **NOTE** - The store is not available until the manager has been created
* and received the extension. As a result trying to access the store during
* `init` and `constructor` will result in a runtime error.
*
* Some properties of the store are available at different phases. You should
* check the inline documentation to know when a certain property is useable
* in your extension.
*/
get store() {
invariant3(this._store, {
code: ErrorConstant3.MANAGER_PHASE_ERROR,
message: "An error occurred while attempting to access the 'extension.store' when the Manager has not yet set created the lifecycle methods."
});
return freeze2(this._store, { requireKeys: true });
}
/**
* The list of extensions added to the editor by this `Preset`.
*/
get extensions() {
return this._extensions;
}
/**
* When there are duplicate extensions used within the editor the extension
* manager will call this method and make sure all extension holders are using
* the same instance of the `ExtensionConstructor`.
*
* @internal
*/
replaceChildExtension(constructor, extension2) {
if (!this.extensionMap.has(constructor)) {
return;
}
this.extensionMap.set(constructor, extension2);
this._extensions = this.extensions.map(
(currentExtension) => extension2.constructor === constructor ? extension2 : currentExtension
);
}
/**
* Create the extensions which will be consumed by the preset. Override this
* if you would like to make your extension a parent to other (holder)
* extensions which don't make sense existing outside of the context of this
* extension.
*
* @remarks
*
* Since this method is called in the constructor it should always be created
* as an instance method and not a property. Properties aren't available for
* the call to the parent class.
*
* ```ts
* class HolderExtension extends PlainExtension {
* get name() {
* return 'holder'
* }
*
* // GOOD ✅
* createExtensions() {
* return [];
* }
*
* // BAD ❌
* createExtensions = () => {
* return [];
* }
* }
* ```
*/
createExtensions() {
return [];
}
/**
* Get an extension from this holder extension by providing the desired
* `Constructor`.
*
* @param Constructor - the extension constructor to find in the editor.
*
* @remarks
*
* This method will throw an error if the constructor doesn't exist within the
* extension created by this extension.
*
* It can be used to forward options and attach handlers to the children
* extensions. It is the spiritual replacement of the `Preset` extension.
*
* ```ts
* import { PlainExtension, OnSetOptionsProps } from 'remirror';
*
* interface ParentOptions { weight?: string }
*
* class ParentExtension extends PlainExtension<ParentOptions> {
* get name() {
* return 'parent' as const;
* }
*
* createExtensions() {
* return [new BoldExtension()]
* }
*
* onSetOptions(options: OnSetOptionsProps<ParentOptions>): void {
* if (options.changes.weight.changed) {
* // Update the value of the provided extension.
* this.getExtension(BoldExtension).setOption({ weight: options.changes.weight.value });
* }
* }
* }
* ```
*/
getExtension(Constructor) {
const extension2 = this.extensionMap.get(Constructor);
invariant3(extension2, {
code: ErrorConstant3.INVALID_GET_EXTENSION,
message: "'".concat(Constructor.name, "' does not exist within the preset: '").concat(this.name, "'")
});
return extension2;
}
/**
* Check if the type of this extension's constructor matches the type of the
* provided constructor.
*/
isOfType(Constructor) {
return this.constructor === Constructor;
}
/**
* Pass a reference to the globally shared `ExtensionStore` for this
* extension.
*
* @remarks
*
* The extension store allows extensions to access important variables without
* complicating their creator methods.
*
* ```ts
* import { PlainExtension } from 'remirror';
*
* class Awesome extends PlainExtension {
* customMethod() {
* if (this.store.view.hasFocus()) {
* log('dance dance dance');
* }
* }
* }
* ```
*
* This should only be called by the `RemirrorManager`.
*
* @internal
* @nonVirtual
*/
setStore(store) {
if (this._store) {
return;
}
this._store = store;
}
/**
* Clone an extension.
*/
clone(...args) {
return new this.constructor(...args);
}
/**
* Set the priority override for this extension. This is used in the
* `RemirrorManager` in order to override the priority of an extension.
*
* If you set the first parameter to `undefined` it will remove the priority
* override.
*
* @internal
*/
setPriority(priority) {
this.priorityOverride = priority;
}
};
/**
* The default priority for this family of extensions.
*/
__publicField(Extension, "defaultPriority", ExtensionPriority2.Default);
var PlainExtension = class extends Extension {
/** @internal */
static get [__INTERNAL_REMIRROR_IDENTIFIER_KEY__2]() {
return RemirrorIdentifier2.PlainExtensionConstructor;
}
/** @internal */
get [__INTERNAL_REMIRROR_IDENTIFIER_KEY__2]() {
return RemirrorIdentifier2.PlainExtension;
}
};
var MarkExtension = class extends Extension {
/** @internal */
static get [__INTERNAL_REMIRROR_IDENTIFIER_KEY__2]() {
return RemirrorIdentifier2.MarkExtensionConstructor;
}
/** @internal */
get [__INTERNAL_REMIRROR_IDENTIFIER_KEY__2]() {
return RemirrorIdentifier2.MarkExtension;
}
/**
* Provides access to the mark type from the schema.
*
* @remarks
*
* The type is available as soon as the schema is created by the
* `SchemaExtension` which has the priority `Highest`. It should be safe to
* access in any of the lifecycle methods.
*/
get type() {
return assertGet(this.store.schema.marks, this.name);
}
constructor(...args) {
super(...args);
}
};
/**
* Whether to disable extra attributes for this extension.
*/
__publicField(MarkExtension, "disableExtraAttributes", false);
var NodeExtension = class extends Extension {
static get [__INTERNAL_REMIRROR_IDENTIFIER_KEY__2]() {
return RemirrorIdentifier2.NodeExtensionConstructor;
}
/** @internal */
get [__INTERNAL_REMIRROR_IDENTIFIER_KEY__2]() {
return RemirrorIdentifier2.NodeExtension;
}
/**
* Provides access to the node type from the schema.
*/
get type() {
return assertGet(this.store.schema.nodes, this.name);
}
constructor(...args) {
super(...args);
}
};
/**
* Whether to disable extra attributes for this extension.
*/
__publicField(NodeExtension, "disableExtraAttributes", false);
var defaultOptions = {
priority: void 0,
extraAttributes: {},
disableExtraAttributes: false,
exclude: {}
};
function mutateDefaultExtensionOptions(mutatorMethod) {
mutatorMethod(defaultOptions);
}
function isExtension(value) {
return isRemirrorType(value) && isIdentifierOfType(value, [
RemirrorIdentifier2.PlainExtension,
RemirrorIdentifier2.MarkExtension,
RemirrorIdentifier2.NodeExtension
]);
}
function isExtensionConstructor(value) {
return isRemirrorType(value) && isIdentifierOfType(value, [
RemirrorIdentifier2.PlainExtensionConstructor,
RemirrorIdentifier2.MarkExtensionConstructor,
RemirrorIdentifier2.NodeExtensionConstructor
]);
}
function isPlainExtension(value) {
return isRemirrorType(value) && isIdentifierOfType(value, RemirrorIdentifier2.PlainExtension);
}
function isNodeExtension(value) {
return isRemirrorType(value) && isIdentifierOfType(value, RemirrorIdentifier2.NodeExtension);
}
function isMarkExtension(value) {
return isRemirrorType(value) && isIdentifierOfType(value, RemirrorIdentifier2.MarkExtension);
}
// src/extension/extension-decorator.ts
import { Cast } from "@remirror/core-helpers";
function extension(options) {
return (ReadonlyConstructor, context) => {
if (context && context.kind !== "class") {
throw new Error("The extension decorator can only be used on a class.");
}
const _a12 = options, {
defaultOptions: defaultOptions2,
customHandlerKeys,
handlerKeys,
staticKeys,
defaultPriority,
handlerKeyOptions
} = _a12, rest = __objRest(_a12, [
"defaultOptions",
"customHandlerKeys",
"handlerKeys",
"staticKeys",
"defaultPriority",
"handlerKeyOptions"
]);
const Constructor = Cast(ReadonlyConstructor);
if (defaultOptions2) {
Constructor.defaultOptions = defaultOptions2;
}
if (defaultPriority) {
Constructor.defaultPriority = defaultPriority;
}
if (handlerKeyOptions) {
Constructor.handlerKeyOptions = handlerKeyOptions;
}
Constructor.staticKeys = staticKeys != null ? staticKeys : [];
Constructor.handlerKeys = handlerKeys != null ? handlerKeys : [];
Constructor.customHandlerKeys = customHandlerKeys != null ? customHandlerKeys : [];
for (const [key2, value] of Object.entries(rest)) {
if (Constructor[key2]) {
continue;
}
Constructor[key2] = value;
}
return Cast(Constructor);
};
}
// src/builtins/attributes-extension.ts
var AttributesExtension = class extends PlainExtension {
constructor() {
super(...arguments);
__publicField(this, "attributeList", []);
__publicField(this, "attributeObject", object3());
__publicField(this, "updateAttributes", (triggerUpdate = true) => {
this.transformAttributes();
if (triggerUpdate) {
this.store.commands.forceUpdate("attributes");
}
});
}
get name() {
return "attributes";
}
/**
* Create the attributes object on initialization.
*
* @internal
*/
onCreate() {
this.transformAttributes();
this.store.setExtensionStore("updateAttributes", this.updateAttributes);
}
transformAttributes() {
var _a12, _b, _c, _d;
this.attributeObject = object3();
if ((_a12 = this.store.managerSettings.exclude) == null ? void 0 : _a12.attributes) {
this.store.setStoreKey("attributes", this.attributeObject);
return;
}
this.attributeList = [];
for (const extension2 of this.store.extensions) {
if ((_b = extension2.options.exclude) == null ? void 0 : _b.attributes) {
continue;
}
const createdAttributes = (_c = extension2.createAttributes) == null ? void 0 : _c.call(extension2);
const attributes = __spreadProps(__spreadValues({}, createdAttributes), {
class: cx(...(_d = extension2.classNames) != null ? _d : [], createdAttributes == null ? void 0 : createdAttributes.class)
});
this.attributeList.unshift(attributes);
}
for (const attributes of this.attributeList) {
this.attributeObject = __spreadProps(__spreadValues(__spreadValues({}, this.attributeObject), attributes), {
class: cx(this.attributeObject.class, attributes.class)
});
}
this.store.setStoreKey("attributes", this.attributeObject);
}
};
// src/builtins/builtin-decorators.ts
function helper(options = {}) {
return (method, context) => {
const methodName = context.name;
if (typeof methodName !== "string") {
throw new TypeError("Invalid method name provided");
}
context.addInitializer(function() {
var _a12;
const ExtensionClass = this;
((_a12 = ExtensionClass.decoratedHelpers) != null ? _a12 : ExtensionClass.decoratedHelpers = {})[methodName] = options;
});
return method;
};
}
function legacyHelper(options = {}) {
return (target, propertyKey, _descriptor) => {
var _a12;
((_a12 = target.decoratedHelpers) != null ? _a12 : target.decoratedHelpers = {})[propertyKey] = options;
};
}
function command(options = {}) {
return (method, context) => {
const methodName = context.name;
if (typeof methodName !== "string") {
throw new TypeError("Invalid method name provided");
}
context.addInitializer(function() {
var _a12;
const ExtensionClass = this;
((_a12 = ExtensionClass.decoratedCommands) != null ? _a12 : ExtensionClass.decoratedCommands = {})[methodName] = options;
});
return method;
};
}
function legacyCommand(options = {}) {
return (target, propertyKey, _descriptor) => {
var _a12;
((_a12 = target.decoratedCommands) != null ? _a12 : target.decoratedCommands = {})[propertyKey] = options;
};
}
function keyBinding(options) {
return (method, context) => {
const methodName = context.name;
if (typeof methodName !== "string") {
throw new TypeError("Invalid method name provided");
}
context.addInitializer(function() {
var _a12;
const ExtensionClass = this;
((_a12 = ExtensionClass.decoratedKeybindings) != null ? _a12 : ExtensionClass.decoratedKeybindings = {})[methodName] = options;
});
return method;
};
}
function legacyKeyBinding(options) {
return (target, propertyKey, _descriptor) => {
var _a12;
((_a12 = target.decoratedKeybindings) != null ? _a12 : target.decoratedKeybindings = {})[propertyKey] = options;
};
}
// src/builtins/builtin-preset.ts
import { pick } from "@remirror/core-helpers";
// src/builtins/commands-extension.ts
import { ErrorConstant as ErrorConstant5, ExtensionPriority as ExtensionPriority3, NamedShortcut } from "@remirror/core-constants";
import {
entries as entries2,
invariant as invariant5,
isEmptyArray as isEmptyArray2,
isEmptyObject,
isString as isString2,
object as object4,
uniqueArray
} from "@remirror/core-helpers";
import {
environment as environment2,
getMarkRange,
getTextSelection as getTextSelection2,
htmlToProsemirrorNode,
isEmptyBlockNode,
isProsemirrorFragment,
isProsemirrorNode,
isTextSelection,
removeMark,
replaceText,
setBlockType,
toggleBlockItem,
toggleWrap,
wrapIn
} from "@remirror/core-utils";
import { CoreMessages as Messages } from "@remirror/messages";
import { Mark } from "@remirror/pm/model";
import { TextSelection } from "@remirror/pm/state";
// src/commands.ts
import { ErrorConstant as ErrorConstant4 } from "@remirror/core-constants";
import {
assertGet as assertGet2,
entries,
invariant as invariant4,
isFunction as isFunction2,
isPromise,
isString
} from "@remirror/core-helpers";
import { convertCommand, getCursor, getTextSelection, isMarkActive } from "@remirror/core-utils";
import { toggleMark as originalToggleMark } from "@remirror/pm/commands";
function isDelayedValue(value) {
return isFunction2(value) || isPromise(value);
}
function delayedCommand({
immediate,
promise,
onDone,
onFail
}) {
return (props) => {
const { view } = props;
if ((immediate == null ? void 0 : immediate(props)) === false) {
return false;
}
if (!view) {
return true;
}
const deferred = isFunction2(promise) ? promise() : promise;
deferred.then((value) => {
onDone({ state: view.state, tr: view.state.tr, dispatch: view.dispatch, view, value });
}).catch(() => {
onFail == null ? void 0 : onFail({ state: view.state, tr: view.state.tr, dispatch: view.dispatch, view });
});
return true;
};
}
var DelayedCommand = class {
constructor(promiseCreator) {
this.promiseCreator = promiseCreator;
__publicField(this, "failureHandlers", []);
__publicField(this, "successHandlers", []);
__publicField(this, "validateHandlers", []);
/**
* Generate the `remirror` command.
*/
__publicField(this, "generateCommand", () => (props) => {
let isValid = true;
const { view, tr, dispatch } = props;
if (!view) {
return false;
}
for (const handler of this.validateHandlers) {
if (!handler(__spreadProps(__spreadValues({}, props), { dispatch: () => {
} }))) {
isValid = false;
break;
}
}
if (!dispatch || !isValid) {
return isValid;
}
const deferred = this.promiseCreator(props);
deferred.then((value) => {
this.runHandlers(this.successHandlers, {
value,
state: view.state,
tr: view.state.tr,
dispatch: view.dispatch,
view
});
}).catch((error) => {
this.runHandlers(this.failureHandlers, {
error,
state: view.state,
tr: view.state.tr,
dispatch: view.dispatch,
view
});
});
dispatch(tr);
return true;
});
}
/**
* The commands that will immediately be run and used to evaluate whether to
* proceed.
*/
validate(handler, method = "push") {
this.validateHandlers[method](handler);
return this;
}
/**
* Add a success callback to the handler.
*/
success(handler, method = "push") {
this.successHandlers[method](handler);
return this;
}
/**
* Add a failure callback to the handler.
*/
failure(handler, method = "push") {
this.failureHandlers[method](handler);
return this;
}
runHandlers(handlers, param) {
var _a12;
for (const handler of handlers) {
if (!handler(__spreadProps(__spreadValues({}, param), { dispatch: () => {
} }))) {
break;
}
}
(_a12 = param.dispatch) == null ? void 0 : _a12.call(param, param.tr);
}
};
function toggleMark(props) {
const { type, attrs, range, selection } = props;
return (props2) => {
var _a12;
const { dispatch, tr, state } = props2;
const markType = isString(type) ? state.schema.marks[type] : type;
invariant4(markType, {
code: ErrorConstant4.SCHEMA,
message: "Mark type: ".concat(type, " does not exist on the current schema.")
});
if (range || selection) {
const { from, to } = getTextSelection((_a12 = selection != null ? selection : range) != null ? _a12 : tr.selection, tr.doc);
isMarkActive(__spreadValues({ trState: tr, type }, range)) ? dispatch == null ? void 0 : dispatch(tr.removeMark(from, to, markType)) : dispatch == null ? void 0 : dispatch(tr.addMark(from, to, markType.create(attrs)));
return true;
}
return convertCommand(originalToggleMark(markType, attrs))(props2);
};
}
function markApplies(type, doc, ranges) {
for (const { $from, $to } of ranges) {
let markIsAllowed = $from.depth === 0 ? doc.type.allowsMarkType(type) : false;
doc.nodesBetween($from.pos, $to.pos, (node) => {
if (markIsAllowed) {
return false;
}
markIsAllowed = node.inlineContent && node.type.allowsMarkType(type);
return;
});
if (markIsAllowed) {
return true;
}
}
return false;
}
function applyMark(type, attrs, selectionPoint) {
return ({ tr, dispatch, state }) => {
const selection = getTextSelection(selectionPoint != null ? selectionPoint : tr.selection, tr.doc);
const $cursor = getCursor(selection);
const markType = isString(type) ? state.schema.marks[type] : type;
invariant4(markType, {
code: ErrorConstant4.SCHEMA,
message: "Mark type: ".concat(type, " does not exist on the current schema.")
});
if (selection.empty && !$cursor || !markApplies(markType, tr.doc, selection.ranges)) {
return false;
}
if (!dispatch) {
return true;
}
if ($cursor) {
tr.removeStoredMark(markType);
if (attrs) {
tr.addStoredMark(markType.create(attrs));
}
dispatch(tr);
return true;
}
let containsMark = false;
for (const { $from, $to } of selection.ranges) {
if (containsMark) {
break;
}
containsMark = tr.doc.rangeHasMark($from.pos, $to.pos, markType);
}
for (const { $from, $to } of selection.ranges) {
if (containsMark) {
tr.removeMark($from.pos, $to.pos, markType);
}
if (attrs) {
tr.addMark($from.pos, $to.pos, markType.create(attrs));
}
}
dispatch(tr);
return true;
};
}
function insertText(text, options = {}) {
return ({ tr, dispatch, state }) => {
const schema = state.schema;
const selection = tr.selection;
const { from = selection.from, to = from != null ? from : selection.to, marks = {} } = options;
if (!dispatch) {
return true;
}
tr.insertText(text, from, to);
const end = assertGet2(tr.steps, tr.steps.length - 1).getMap().map(to);
for (const [markName, attributes] of entries(marks)) {
tr.addMark(from, end, assertGet2(schema.marks, markName).create(attributes));
}
dispatch(tr);
return true;
};
}
// src/builtins/commands-extension.ts
var _getCommandProp_dec, _getCommandOptions_dec, _getAllCommandOptions_dec, _replaceText_dec, _cut_dec, _paste_dec, _copy_dec, _selectAll_dec, _setMeta_dec, _removeMark_dec, _toggleMark_dec, _applyMark_dec, _wrapInNode_dec, _toggleBlockNodeItem_dec, _toggleWrappingNode_dec, _setBlockNodeType_dec, _blur_dec, _focus_dec, _insertNode_dec, _insertNewLine_dec, _emptySelection_dec, _resetContent_dec, _setContent_dec, _updateNodeAttributes_dec, _forceUpdate_dec, _emptyUpdate_dec, _delete_dec, _selectMark_dec, _selectText_dec, _insertText_dec, _customDispatch_dec, _a, _CommandsExtension_decorators, _init;
_CommandsExtension_decorators = [extension({
defaultPriority: ExtensionPriority3.Highest,
defaultOptions: { trackerClassName: "remirror-tracker-position", trackerNodeName: "span" },
staticKeys: ["trackerClassName", "trackerNodeName"]
})];
var CommandsExtension = class extends (_a = PlainExtension, _customDispatch_dec = [command()], _insertText_dec = [command()], _selectText_dec = [command()], _selectMark_dec = [command()], _delete_dec = [command()], _emptyUpdate_dec = [command()], _forceUpdate_dec = [command()], _updateNodeAttributes_dec = [command()], _setContent_dec = [command()], _resetContent_dec = [command()], _emptySelection_dec = [command()], _insertNewLine_dec = [command()], _insertNode_dec = [command()], _focus_dec = [command()], _blur_dec = [command()], _setBlockNodeType_dec = [command()], _toggleWrappingNode_dec = [command()], _toggleBlockNodeItem_dec = [command()], _wrapInNode_dec = [command()], _applyMark_dec = [command()], _toggleMark_dec = [command()], _removeMark_dec = [command()], _setMeta_dec = [command()], _selectAll_dec = [command({
description: ({ t }) => t(Messages.SELECT_ALL_DESCRIPTION),
label: ({ t }) => t(Messages.SELECT_ALL_LABEL),
shortcut: NamedShortcut.SelectAll
})], _copy_dec = [command({
description: ({ t }) => t(Messages.COPY_DESCRIPTION),
label: ({ t }) => t(Messages.COPY_LABEL),
shortcut: NamedShortcut.Copy,
icon: "fileCopyLine"
})], _paste_dec = [command({
description: ({ t }) => t(Messages.PASTE_DESCRIPTION),
label: ({ t }) => t(Messages.PASTE_LABEL),
shortcut: NamedShortcut.Paste,
icon: "clipboardLine"
})], _cut_dec = [command({
description: ({ t }) => t(Messages.CUT_DESCRIPTION),
label: ({ t }) => t(Messages.CUT_LABEL),
shortcut: NamedShortcut.Cut,
icon: "scissorsFill"
})], _replaceText_dec = [command()], _getAllCommandOptions_dec = [helper()], _getCommandOptions_dec = [helper()], _getCommandProp_dec = [helper()], _a) {
constructor() {
super(...arguments);
__runInitializers(_init, 5, this);
/**
* This is the holder for the shared transaction which is shared by commands
* in order to support chaining.
*
* @internal
*/
__publicField(this, "_transaction");
/**
* Track the decorated command data.
*/
__publicField(this, "decorated", /* @__PURE__ */ new Map());
/**
* A helper for forcing through updates in the view layer. The view layer can
* check for the meta data of the transaction with
* `manager.store.getForcedUpdate(tr)`. If that has a value then it should use
* the unique symbol to update the key.
*/
__publicField(this, "forceUpdateTransaction", (tr, ...keys3) => {
const { forcedUpdates } = this.getCommandMeta(tr);
this.setCommandMeta(tr, { forcedUpdates: uniqueArray([...forcedUpdates, ...keys3]) });
return tr;
});
}
get name() {
return "commands";
}
/**
* The current transaction which allows for making commands chainable.
*
* It is shared by all the commands helpers and can even be used in the
* [[`KeymapExtension`]].
*
* @internal
*/
get transaction() {
const state = this.store.getState();
if (!this._transaction) {
this._transaction = state.tr;
}
const isValid = this._transaction.before.eq(state.doc);
const hasSteps = !isEmptyArray2(this._transaction.steps);
if (!isValid) {
const tr = state.tr;
if (hasSteps) {
for (const step of this._transaction.steps) {
tr.step(step);
}
}
this._transaction = tr;
}
return this._transaction;
}
onCreate() {
this.store.setStoreKey("getForcedUpdates", this.getForcedUpdates.bind(this));
}
/**
* Attach commands once the view is attached.
*/
onView(view) {
var _a12, _b, _c;
const { extensions, helpers } = this.store;
const commands = object4();
const names = /* @__PURE__ */ new Set();
let allDecoratedCommands = object4();
const chain = (tr) => {
var _a13;
const customChain = object4();
const getTr = () => tr != null ? tr : this.transaction;
let commandChain = [];
const getChain = () => commandChain;
for (const [name, command2] of Object.entries(commands)) {
if ((_a13 = allDecoratedCommands[name]) == null ? void 0 : _a13.disableChaining) {
continue;
}
customChain[name] = this.chainedFactory({
chain: customChain,
command: command2.original,
getTr,
getChain
});
}
const dispatch = (transaction) => {
invariant5(transaction === getTr(), {
message: "Chaining currently only supports `CommandFunction` methods which do not use the `state.tr` property. Instead you should use the provided `tr` property."
});
};
customChain.run = (options = {}) => {
const commands2 = commandChain;
commandChain = [];
for (const cmd of commands2) {
if (!cmd(dispatch) && options.exitEarly) {
return;
}
}
view.dispatch(getTr());
};
customChain.tr = () => {
const commands2 = commandChain;
commandChain = [];
for (const cmd of commands2) {
cmd(dispatch);
}
return getTr();
};
customChain.enabled = () => {
for (const cmd of commandChain) {
if (!cmd()) {
return false;
}
}
return true;
};
customChain.new = (tr2) => {
return chain(tr2);
};
return customChain;
};
for (const extension2 of extensions) {
const extensionCommands = (_b = (_a12 = extension2.createCommands) == null ? void 0 : _a12.call(extension2)) != null ? _b : {};
const decoratedCommands = (_c = extension2.decoratedCommands) != null ? _c : {};
const active = {};
allDecoratedCommands = __spreadProps(__spreadValues({}, allDecoratedCommands), { decoratedCommands });
for (const [commandName, options] of Object.entries(decoratedCommands)) {
const shortcut = isString2(options.shortcut) && options.shortcut.startsWith("_|") ? { shortcut: helpers.getNamedShortcut(options.shortcut, extension2.options) } : void 0;
this.updateDecorated(commandName, __spreadValues(__spreadProps(__spreadValues({}, options), { name: extension2.name }), shortcut));
extensionCommands[commandName] = extension2[commandName].bind(extension2);
if (options.active) {
active[commandName] = () => {
var _a13, _b2;
return (_b2 = (_a13 = options.active) == null ? void 0 : _a13.call(options, extension2.options, this.store)) != null ? _b2 : false;
};
}
}
if (isEmptyObject(extensionCommands)) {
continue;
}
this.addCommands({ active, names, commands, extensionCommands });
}
const chainProperty = chain();
for (const [key2, command2] of Object.entries(chainProperty)) {
chain[key2] = command2;
}
this.store.setStoreKey("commands", commands);
this.store.setStoreKey("chain", chain);
this.store.setExtensionStore("commands", commands);
this.store.setExtensionStore("chain", chain);
}
/**
* Update the cached transaction whenever the state is updated.
*/
onStateUpdate({ state }) {
this._transaction = state.tr;
}
/**
* Create a plugin that solely exists to track forced updates via the
* generated plugin key.
*/
createPlugin() {
return {};
}
customDispatch(command2) {
return command2;
}
insertText(text, options = {}) {
if (isString2(text)) {
return insertText(text, options);
}
return this.store.createPlaceholderCommand({
promise: text,
placeholder: { type: "inline" },
onSuccess: (value, range, props) => this.insertText(value, __spreadValues(__spreadValues({}, options), range))(props)
}).generateCommand();
}
selectText(selection, options = {}) {
return ({ tr, dispatch }) => {
const textSelection = getTextSelection2(selection, tr.doc);
const selectionUnchanged = tr.selection.anchor === textSelection.anchor && tr.selection.head === textSelection.head;
if (selectionUnchanged && !options.forceUpdate) {
return false;
}
dispatch == null ? void 0 : dispatch(tr.setSelection(textSelection));
r