@remirror/core
Version:
Where your quest to create a world class editing experience begins.
1,332 lines (1,318 loc) • 201 kB
JavaScript
"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __getProtoOf = Object.getPrototypeOf;
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 __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key2 of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key2) && key2 !== except)
__defProp(to, key2, { get: () => from[key2], enumerable: !(desc = __getOwnPropDesc(from, key2)) || desc.enumerable });
}
return to;
};
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
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/index.ts
var src_exports = {};
__export(src_exports, {
AttributesExtension: () => AttributesExtension,
CommandsExtension: () => CommandsExtension,
DEFAULT_SHORTCUTS: () => DEFAULT_SHORTCUTS,
DecorationsExtension: () => DecorationsExtension,
DelayedCommand: () => DelayedCommand,
DocChangedExtension: () => DocChangedExtension,
Framework: () => Framework,
GOOGLE_DOC_SHORTCUTS: () => GOOGLE_DOC_SHORTCUTS,
HelpersExtension: () => HelpersExtension,
InputRulesExtension: () => InputRulesExtension,
KeymapExtension: () => KeymapExtension,
MarkExtension: () => MarkExtension,
MetaExtension: () => MetaExtension,
NodeExtension: () => NodeExtension,
NodeViewsExtension: () => NodeViewsExtension,
PasteRulesExtension: () => PasteRulesExtension,
PlainExtension: () => PlainExtension,
PluginsExtension: () => PluginsExtension,
RemirrorManager: () => RemirrorManager,
SchemaExtension: () => SchemaExtension,
SuggestExtension: () => SuggestExtension,
TagsExtension: () => TagsExtension,
UploadExtension: () => UploadExtension,
builtinPreset: () => builtinPreset,
command: () => command,
delayedCommand: () => delayedCommand,
extension: () => extension,
findUploadPlaceholderPayload: () => findUploadPlaceholderPayload,
findUploadPlaceholderPos: () => findUploadPlaceholderPos,
hasUploadingFile: () => hasUploadingFile,
helper: () => helper,
insertText: () => insertText,
isDelayedValue: () => isDelayedValue,
isExtension: () => isExtension,
isExtensionConstructor: () => isExtensionConstructor,
isExtensionTag: () => isExtensionTag,
isMarkExtension: () => isMarkExtension,
isNodeExtension: () => isNodeExtension,
isPlainExtension: () => isPlainExtension,
isRemirrorManager: () => isRemirrorManager,
keyBinding: () => keyBinding,
keyboardShortcuts: () => keyboardShortcuts,
legacyCommand: () => legacyCommand,
legacyHelper: () => legacyHelper,
legacyKeyBinding: () => legacyKeyBinding,
mutateDefaultExtensionOptions: () => mutateDefaultExtensionOptions,
setUploadPlaceholderAction: () => setUploadPlaceholderAction,
toggleMark: () => toggleMark,
uploadFile: () => uploadFile
});
module.exports = __toCommonJS(src_exports);
// src/builtins/attributes-extension.ts
var import_core_helpers5 = require("@remirror/core-helpers");
// src/extension/extension.ts
var import_core_constants3 = require("@remirror/core-constants");
var import_core_helpers3 = require("@remirror/core-helpers");
var import_core_utils2 = require("@remirror/core-utils");
// src/extension/base-class.ts
var import_core_constants2 = require("@remirror/core-constants");
var import_core_helpers2 = require("@remirror/core-helpers");
var import_core_utils = require("@remirror/core-utils");
// src/helpers.ts
var import_core_constants = require("@remirror/core-constants");
var import_core_helpers = require("@remirror/core-helpers");
function defaultEquals(valueA, valueB) {
return valueA === valueB;
}
function getChangedOptions(props) {
const { previousOptions, update, equals = defaultEquals } = props;
const next = (0, import_core_helpers.freeze)(__spreadValues(__spreadValues({}, previousOptions), update));
const changes = (0, import_core_helpers.object)();
const optionKeys = (0, import_core_helpers.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 = (0, import_core_helpers.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: (0, import_core_helpers.freeze)(changes), options: next, pickChanged };
}
var codeLabelMap = {
[import_core_constants.ErrorConstant.DUPLICATE_HELPER_NAMES]: "helper method",
[import_core_constants.ErrorConstant.DUPLICATE_COMMAND_NAMES]: "command method"
};
function throwIfNameNotUnique(props) {
const { name, set, code } = props;
const label = codeLabelMap[code];
(0, import_core_helpers.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 = (0, import_core_helpers2.object)();
this.populateMappedHandlers();
this._options = this._initialOptions = (0, import_core_helpers2.deepMerge)(
defaultOptions2,
this.constructor.defaultOptions,
options != null ? options : (0, import_core_helpers2.object)(),
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 (0, import_core_helpers2.keys)(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 (import_core_utils.environment.isProduction) {
return;
}
const invalid = [];
for (const key2 of (0, import_core_helpers2.keys)(update)) {
if (this._dynamicKeys.includes(key2)) {
continue;
}
invalid.push(key2);
}
(0, import_core_helpers2.invariant)((0, import_core_helpers2.isEmptyArray)(invalid), {
code: import_core_constants2.ErrorConstant.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 (0, import_core_helpers2.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 = (0, import_core_helpers2.object)();
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 = import_core_constants2.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] = (0, import_core_helpers2.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 : import_core_helpers2.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 && ((0, import_core_helpers2.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.
((0, import_core_helpers2.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 = (0, import_core_helpers3.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((0, import_core_helpers3.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() {
(0, import_core_helpers3.invariant)(this._store, {
code: import_core_constants3.ErrorConstant.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 (0, import_core_helpers3.freeze)(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);
(0, import_core_helpers3.invariant)(extension2, {
code: import_core_constants3.ErrorConstant.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", import_core_constants3.ExtensionPriority.Default);
var PlainExtension = class extends Extension {
/** @internal */
static get [import_core_constants3.__INTERNAL_REMIRROR_IDENTIFIER_KEY__]() {
return import_core_constants3.RemirrorIdentifier.PlainExtensionConstructor;
}
/** @internal */
get [import_core_constants3.__INTERNAL_REMIRROR_IDENTIFIER_KEY__]() {
return import_core_constants3.RemirrorIdentifier.PlainExtension;
}
};
var MarkExtension = class extends Extension {
/** @internal */
static get [import_core_constants3.__INTERNAL_REMIRROR_IDENTIFIER_KEY__]() {
return import_core_constants3.RemirrorIdentifier.MarkExtensionConstructor;
}
/** @internal */
get [import_core_constants3.__INTERNAL_REMIRROR_IDENTIFIER_KEY__]() {
return import_core_constants3.RemirrorIdentifier.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 (0, import_core_helpers3.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 [import_core_constants3.__INTERNAL_REMIRROR_IDENTIFIER_KEY__]() {
return import_core_constants3.RemirrorIdentifier.NodeExtensionConstructor;
}
/** @internal */
get [import_core_constants3.__INTERNAL_REMIRROR_IDENTIFIER_KEY__]() {
return import_core_constants3.RemirrorIdentifier.NodeExtension;
}
/**
* Provides access to the node type from the schema.
*/
get type() {
return (0, import_core_helpers3.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 (0, import_core_utils2.isRemirrorType)(value) && (0, import_core_utils2.isIdentifierOfType)(value, [
import_core_constants3.RemirrorIdentifier.PlainExtension,
import_core_constants3.RemirrorIdentifier.MarkExtension,
import_core_constants3.RemirrorIdentifier.NodeExtension
]);
}
function isExtensionConstructor(value) {
return (0, import_core_utils2.isRemirrorType)(value) && (0, import_core_utils2.isIdentifierOfType)(value, [
import_core_constants3.RemirrorIdentifier.PlainExtensionConstructor,
import_core_constants3.RemirrorIdentifier.MarkExtensionConstructor,
import_core_constants3.RemirrorIdentifier.NodeExtensionConstructor
]);
}
function isPlainExtension(value) {
return (0, import_core_utils2.isRemirrorType)(value) && (0, import_core_utils2.isIdentifierOfType)(value, import_core_constants3.RemirrorIdentifier.PlainExtension);
}
function isNodeExtension(value) {
return (0, import_core_utils2.isRemirrorType)(value) && (0, import_core_utils2.isIdentifierOfType)(value, import_core_constants3.RemirrorIdentifier.NodeExtension);
}
function isMarkExtension(value) {
return (0, import_core_utils2.isRemirrorType)(value) && (0, import_core_utils2.isIdentifierOfType)(value, import_core_constants3.RemirrorIdentifier.MarkExtension);
}
// src/extension/extension-decorator.ts
var import_core_helpers4 = require("@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 = (0, import_core_helpers4.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 (0, import_core_helpers4.Cast)(Constructor);
};
}
// src/builtins/attributes-extension.ts
var AttributesExtension = class extends PlainExtension {
constructor() {
super(...arguments);
__publicField(this, "attributeList", []);
__publicField(this, "attributeObject", (0, import_core_helpers5.object)());
__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 = (0, import_core_helpers5.object)();
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: (0, import_core_helpers5.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: (0, import_core_helpers5.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
var import_core_helpers18 = require("@remirror/core-helpers");
// src/builtins/commands-extension.ts
var import_core_constants5 = require("@remirror/core-constants");
var import_core_helpers7 = require("@remirror/core-helpers");
var import_core_utils4 = require("@remirror/core-utils");
var import_messages = require("@remirror/messages");
var import_model = require("@remirror/pm/model");
var import_state = require("@remirror/pm/state");
// src/commands.ts
var import_core_constants4 = require("@remirror/core-constants");
var import_core_helpers6 = require("@remirror/core-helpers");
var import_core_utils3 = require("@remirror/core-utils");
var import_commands = require("@remirror/pm/commands");
function isDelayedValue(value) {
return (0, import_core_helpers6.isFunction)(value) || (0, import_core_helpers6.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 = (0, import_core_helpers6.isFunction)(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 = (0, import_core_helpers6.isString)(type) ? state.schema.marks[type] : type;
(0, import_core_helpers6.invariant)(markType, {
code: import_core_constants4.ErrorConstant.SCHEMA,
message: "Mark type: ".concat(type, " does not exist on the current schema.")
});
if (range || selection) {
const { from, to } = (0, import_core_utils3.getTextSelection)((_a12 = selection != null ? selection : range) != null ? _a12 : tr.selection, tr.doc);
(0, import_core_utils3.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 (0, import_core_utils3.convertCommand)((0, import_commands.toggleMark)(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 = (0, import_core_utils3.getTextSelection)(selectionPoint != null ? selectionPoint : tr.selection, tr.doc);
const $cursor = (0, import_core_utils3.getCursor)(selection);
const markType = (0, import_core_helpers6.isString)(type) ? state.schema.marks[type] : type;
(0, import_core_helpers6.invariant)(markType, {
code: import_core_constants4.ErrorConstant.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 = (0, import_core_helpers6.assertGet)(tr.steps, tr.steps.length - 1).getMap().map(to);
for (const [markName, attributes] of (0, import_core_helpers6.entries)(marks)) {
tr.addMark(from, end, (0, import_core_helpers6.assertGet)(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: import_core_constants5.ExtensionPriority.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(import_messages.CoreMessages.SELECT_ALL_DESCRIPTION),
label: ({ t }) => t(import_messages.CoreMessages.SELECT_ALL_LABEL),
shortcut: import_core_constants5.NamedShortcut.SelectAll
})], _copy_dec = [command({
description: ({ t }) => t(import_messages.CoreMessages.COPY_DESCRIPTION),
label: ({ t }) => t(import_messages.CoreMessages.COPY_LABEL),
shortcut: import_core_constants5.NamedShortcut.Copy,
icon: "fileCopyLine"
})], _paste_dec = [command({
description: ({ t }) => t(import_messages.CoreMessages.PASTE_DESCRIPTION),
label: ({ t }) => t(import_messages.CoreMessages.PASTE_LABEL),
shortcut: import_core_constants5.NamedShortcut.Paste,
icon: "clipboardLine"
})], _cut_dec = [command({
description: ({ t }) => t(import_messages.CoreMessages.CUT_DESCRIPTION),
label: ({ t }) => t(import_messages.CoreMessages.CUT_LABEL),
shortcut: import_core_constants5.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: (0, import_core_helpers7.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 = !(0, import_core_helpers7.isEmptyArray)(this._transaction.steps);
if (!isValid)