@lblod/ember-rdfa-editor 13.3.0 → 13.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -28,7 +28,7 @@ export default class EmbeddedEditor extends Component<Signature> {
28
28
  innerView: SayView | null;
29
29
  contentWrapper: Element | null;
30
30
  editorId: string;
31
- get outerView(): SayView;
31
+ get outerView(): import("prosemirror-view").EditorView | SayView;
32
32
  get node(): import("prosemirror-model").Node;
33
33
  get schema(): import("prosemirror-model").Schema<any, any>;
34
34
  get pos(): number | undefined;
@@ -23,11 +23,11 @@ export type DocumentRange = {
23
23
  export default class SayView extends EditorView {
24
24
  isSayView: boolean;
25
25
  state: EditorState;
26
- parent?: SayView;
26
+ parent?: EditorView;
27
27
  domParser: ProseParser;
28
28
  constructor(place: Node | ((editor: HTMLElement) => void) | {
29
29
  mount: HTMLElement;
30
- } | null, props: DirectEditorProps, parent?: SayView);
30
+ } | null, props: DirectEditorProps, parent?: EditorView);
31
31
  /**
32
32
  * Replaces the state (and current document) with a parsed version of the provided `html` string.
33
33
  * This method creates a new `doc` node and parses it correctly based on the provided html.
@@ -1 +1,73 @@
1
- export * from 'prosemirror-history';
1
+ import type { Transaction, EditorState, Plugin, Command } from 'prosemirror-state';
2
+ /**
3
+ Set a flag on the given transaction that will prevent further steps
4
+ from being appended to an existing history event (so that they
5
+ require a separate undo command to undo).
6
+ */
7
+ declare const closeHistory: (tr: Transaction) => Transaction;
8
+ interface HistoryOptions {
9
+ /**
10
+ The amount of history events that are collected before the
11
+ oldest events are discarded. Defaults to 100.
12
+ */
13
+ depth?: number;
14
+ /**
15
+ The delay between changes after which a new group should be
16
+ started. Defaults to 500 (milliseconds). Note that when changes
17
+ aren't adjacent, a new group is always started.
18
+ */
19
+ newGroupDelay?: number;
20
+ }
21
+ /**
22
+ Returns a plugin that enables the undo history for an editor. The
23
+ plugin will track undo and redo stacks, which can be used with the
24
+ [`undo`](https://prosemirror.net/docs/ref/#history.undo) and [`redo`](https://prosemirror.net/docs/ref/#history.redo) commands.
25
+
26
+ You can set an `"addToHistory"` [metadata
27
+ property](https://prosemirror.net/docs/ref/#state.Transaction.setMeta) of `false` on a transaction
28
+ to prevent it from being rolled back by undo.
29
+ */
30
+ declare const history: (config?: HistoryOptions) => Plugin;
31
+ /**
32
+ A command function that undoes the last change, if any.
33
+ */
34
+ declare const undo: Command;
35
+ /**
36
+ A command function that redoes the last undone change, if any.
37
+ */
38
+ declare const redo: Command;
39
+ /**
40
+ A command function that undoes the last change. Don't scroll the
41
+ selection into view.
42
+ */
43
+ declare const undoNoScroll: Command;
44
+ /**
45
+ A command function that redoes the last undone change. Don't
46
+ scroll the selection into view.
47
+ */
48
+ declare const redoNoScroll: Command;
49
+ /**
50
+ The amount of undoable events available in a given state.
51
+ */
52
+ declare const undoDepth: (state: EditorState) => any;
53
+ /**
54
+ The amount of redoable events available in a given editor state.
55
+ */
56
+ declare const redoDepth: (state: EditorState) => any;
57
+ /**
58
+ Returns true if the given transaction was generated by the history
59
+ plugin.
60
+ */
61
+ declare const isHistoryTransaction: (tr: Transaction) => boolean;
62
+ /**
63
+ Returns the unique ID of the current history for a given editor state.
64
+ This can for example be used to compare against a saved state, to
65
+ determine if there are changes since then.
66
+ */
67
+ declare const getHistoryStateId: (state: EditorState) => string | undefined;
68
+ /**
69
+ Whether the unique IDs of the history for the given editor state matches
70
+ the passed ID.
71
+ */
72
+ declare const matchesTaggedHistory: (state: EditorState, id: string) => boolean;
73
+ export { closeHistory, getHistoryStateId, history, isHistoryTransaction, matchesTaggedHistory, redo, redoDepth, redoNoScroll, undo, undoDepth, undoNoScroll, };
@@ -12,6 +12,9 @@ export type LinkParser = (input?: string) => LinkParserResult;
12
12
  type DefaultLinkParserOptions = {
13
13
  defaultCountryCode?: CountryCode;
14
14
  supportedProtocols?: string[];
15
+ customProtocolValidatorMapping?: ProtocolValidatorMapping;
15
16
  };
16
- export declare const defaultLinkParser: ({ defaultCountryCode, supportedProtocols, }?: DefaultLinkParserOptions) => LinkParser;
17
+ export declare const defaultLinkParser: ({ defaultCountryCode, supportedProtocols, customProtocolValidatorMapping, }?: DefaultLinkParserOptions) => LinkParser;
18
+ type URLValidator = (url: URL) => boolean;
19
+ type ProtocolValidatorMapping = Record<string, URLValidator>;
17
20
  export {};
@@ -8,13 +8,13 @@
8
8
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
9
9
  */
10
10
  import type { AttributeSpec, DOMOutputSpec, TagParseRule, Node as PNode, Attrs } from 'prosemirror-model';
11
- import { type DecorationSource, type NodeView } from 'prosemirror-view';
11
+ import { type EditorView, type DecorationSource, type NodeView } from 'prosemirror-view';
12
12
  import Component from '@ember/component';
13
13
  import type { ComponentLike } from '@glint/template';
14
14
  import SayController from '#root/core/say-controller.ts';
15
15
  import type SayNodeSpec from '#root/core/say-node-spec.ts';
16
16
  import type { NodeSerializer } from '#root/core/say-serializer.ts';
17
- import type SayView from '#root/core/say-view.ts';
17
+ import type SayView from '#root/core/say-view.js';
18
18
  export interface EmberInlineComponent extends Component, EmberNodeArgs {
19
19
  appendTo(selector: string | Element): this;
20
20
  }
@@ -33,7 +33,7 @@ export interface EmberNodeArgs {
33
33
  */
34
34
  selectNode: () => void;
35
35
  controller: SayController;
36
- view: SayView;
36
+ view: SayView | EditorView;
37
37
  selected: boolean;
38
38
  contentDecorations?: DecorationSource;
39
39
  }
@@ -129,7 +129,7 @@ export type EmberNodeConfig = {
129
129
  * Generate the {@link SayNodeSpec} for the {@link EmberNodeView} with the passed config
130
130
  */
131
131
  export declare function createEmberNodeSpec(config: EmberNodeConfig): SayNodeSpec;
132
- export type SayNodeViewConstructor = (node: PNode, view: SayView, getPos: () => number | undefined) => NodeView;
132
+ export type SayNodeViewConstructor = (node: PNode, view: EditorView, getPos: () => number | undefined) => NodeView;
133
133
  /**
134
134
  * Creates a constructor for EmberNodeViews according to the passed config
135
135
  * @see {@link EmberNodeView}
@@ -4,7 +4,7 @@ import { action } from '@ember/object';
4
4
  import { service } from '@ember/service';
5
5
  import Component from '@glimmer/component';
6
6
  import { v4 } from 'uuid';
7
- import { r as redo, u as undo } from '../../index-CxRqg5Kr.js';
7
+ import { redo, undo } from '../../plugins/history/index.js';
8
8
  import { isSome, unwrap } from '../../utils/_private/option.js';
9
9
  import { lastKeyPressedPluginKey } from '../../plugins/last-key-pressed/index.js';
10
10
  import { EditorState, NodeSelection, Selection, TextSelection } from 'prosemirror-state';
@@ -88,6 +88,7 @@ class Link extends Component {
88
88
  return `say-pill ${this.linkParserResult.isSuccessful || this.isNewLink ? '' : 'say-pill--error'}`;
89
89
  }
90
90
  onClick(event) {
91
+ this.hideTooltip = false;
91
92
  if (event.ctrlKey || event.metaKey) {
92
93
  window.open(this.href);
93
94
  }
@@ -1 +1 @@
1
- {"version":3,"file":"link.js","sources":["../../../src/components/ember-node/link.gts"],"sourcesContent":["import leaveOnEnterKey from '#root/modifiers/leave-on-enter-key.ts';\nimport { action } from '@ember/object';\nimport Component from '@glimmer/component';\nimport type { EmberNodeArgs } from '#root/utils/ember-node.ts';\nimport { Velcro } from 'ember-velcro';\nimport { hash } from '@ember/helper';\nimport EmbeddedEditor from './embedded-editor.gts';\nimport { on } from '@ember/modifier';\nimport t from 'ember-intl/helpers/t';\nimport Pill from '#root/components/pill.gts';\nimport LinkEditor from '../plugins/link/_private/link-editor.gts';\nimport {\n defaultLinkParser,\n type LinkParser,\n} from '#root/plugins/link/parser.ts';\nimport { cached, tracked } from '@glimmer/tracking';\nimport { service } from '@ember/service';\nimport type IntlService from 'ember-intl/services/intl';\nimport { CircleXIcon } from '@appuniversum/ember-appuniversum/components/icons/circle-x';\n\nexport default class Link extends Component<EmberNodeArgs> {\n @service declare intl: IntlService;\n @tracked hideTooltip = false;\n\n get isNewLink() {\n return this.link && (this.link.node.attrs['isNew'] as boolean);\n }\n\n selectionChangeHandler = (selected: boolean) => {\n this.hideTooltip = false;\n if (!selected && this.isNewLink) {\n this.args.updateAttribute('isNew', false, true);\n }\n };\n\n get href() {\n return this.args.node.attrs['href'] as string;\n }\n\n get link() {\n const pos = this.args.getPos();\n if (!pos) {\n return;\n }\n return {\n node: this.args.node,\n pos,\n };\n }\n\n get linkParser() {\n return (\n (this.node.attrs['linkParser'] as LinkParser | null) ??\n defaultLinkParser()\n );\n }\n\n @cached\n get linkParserResult() {\n return this.linkParser(this.href);\n }\n\n get linkTitle() {\n if (this.linkParserResult.isSuccessful) {\n return this.intl.t('ember-rdfa-editor.link.ctrlClickDescription');\n } else {\n return this.linkParserResult.errors[0];\n }\n }\n\n get linkIcon() {\n if (this.linkParserResult.isSuccessful || this.isNewLink) {\n return;\n } else {\n return CircleXIcon;\n }\n }\n\n get controller() {\n return this.args.controller;\n }\n\n get node() {\n return this.args.node;\n }\n\n get selected() {\n return this.args.selected;\n }\n\n get interactive() {\n return this.node.attrs['interactive'] as boolean;\n }\n\n get class() {\n return `say-pill ${this.linkParserResult.isSuccessful || this.isNewLink ? '' : 'say-pill--error'}`;\n }\n\n @action\n onClick(event: PointerEvent) {\n if (event.ctrlKey || event.metaKey) {\n window.open(this.href);\n }\n }\n\n get shouldShowTooltip() {\n return this.interactive && this.link && this.selected && !this.hideTooltip;\n }\n\n onKeyUp = (event: KeyboardEvent) => {\n if (event.key === 'Escape' || event.key === 'Enter') {\n this.hideTooltip = true;\n } else {\n this.hideTooltip = false;\n }\n };\n\n <template>\n <Velcro\n @placement=\"bottom-start\"\n @offsetOptions={{hash mainAxis=3}}\n @strategy=\"fixed\"\n as |velcro|\n >\n <Pill\n {{on \"keyup\" this.onKeyUp}}\n class={{this.class}}\n @skin=\"link\"\n @icon={{this.linkIcon}}\n title={{this.linkTitle}}\n aria-describedby=\"link-tooltip\"\n {{velcro.hook}}\n {{on \"click\" this.onClick}}\n >\n <EmbeddedEditor\n @controller={{@controller}}\n @node={{@node}}\n @view={{@view}}\n @getPos={{@getPos}}\n @onSelected={{this.selectionChangeHandler}}\n @selected={{@selected}}\n @placeholder={{t \"ember-rdfa-editor.link.placeholder.text\"}}\n @contentDecorations={{@contentDecorations}}\n @updateAttribute={{@updateAttribute}}\n @selectNode={{@selectNode}}\n {{leaveOnEnterKey @controller @getPos}}\n />\n </Pill>\n {{#if this.shouldShowTooltip}}\n <LinkEditor\n {{on \"keyup\" this.onKeyUp}}\n @controller={{@controller}}\n {{! @glint-expect-error }}\n @link={{this.link}}\n @linkParser={{this.linkParser}}\n {{velcro.loop}}\n />\n {{/if}}\n </Velcro>\n </template>\n}\n"],"names":["Link","Component","g","prototype","service","i","tracked","isNewLink","link","node","attrs","selectionChangeHandler","selected","hideTooltip","args","updateAttribute","href","pos","getPos","linkParser","defaultLinkParser","linkParserResult","n","cached","linkTitle","isSuccessful","intl","t","errors","linkIcon","CircleXIcon","controller","interactive","class","onClick","event","ctrlKey","metaKey","window","open","action","shouldShowTooltip","onKeyUp","key","setComponentTemplate","precompileTemplate","strictMode","scope","Velcro","hash","Pill","on","EmbeddedEditor","leaveOnEnterKey","LinkEditor"],"mappings":"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"}
1
+ {"version":3,"file":"link.js","sources":["../../../src/components/ember-node/link.gts"],"sourcesContent":["import leaveOnEnterKey from '#root/modifiers/leave-on-enter-key.ts';\nimport { action } from '@ember/object';\nimport Component from '@glimmer/component';\nimport type { EmberNodeArgs } from '#root/utils/ember-node.ts';\nimport { Velcro } from 'ember-velcro';\nimport { hash } from '@ember/helper';\nimport EmbeddedEditor from './embedded-editor.gts';\nimport { on } from '@ember/modifier';\nimport t from 'ember-intl/helpers/t';\nimport Pill from '#root/components/pill.gts';\nimport LinkEditor from '../plugins/link/_private/link-editor.gts';\nimport {\n defaultLinkParser,\n type LinkParser,\n} from '#root/plugins/link/parser.ts';\nimport { cached, tracked } from '@glimmer/tracking';\nimport { service } from '@ember/service';\nimport type IntlService from 'ember-intl/services/intl';\nimport { CircleXIcon } from '@appuniversum/ember-appuniversum/components/icons/circle-x';\n\nexport default class Link extends Component<EmberNodeArgs> {\n @service declare intl: IntlService;\n @tracked hideTooltip = false;\n\n get isNewLink() {\n return this.link && (this.link.node.attrs['isNew'] as boolean);\n }\n\n selectionChangeHandler = (selected: boolean) => {\n this.hideTooltip = false;\n if (!selected && this.isNewLink) {\n this.args.updateAttribute('isNew', false, true);\n }\n };\n\n get href() {\n return this.args.node.attrs['href'] as string;\n }\n\n get link() {\n const pos = this.args.getPos();\n if (!pos) {\n return;\n }\n return {\n node: this.args.node,\n pos,\n };\n }\n\n get linkParser() {\n return (\n (this.node.attrs['linkParser'] as LinkParser | null) ??\n defaultLinkParser()\n );\n }\n\n @cached\n get linkParserResult() {\n return this.linkParser(this.href);\n }\n\n get linkTitle() {\n if (this.linkParserResult.isSuccessful) {\n return this.intl.t('ember-rdfa-editor.link.ctrlClickDescription');\n } else {\n return this.linkParserResult.errors[0];\n }\n }\n\n get linkIcon() {\n if (this.linkParserResult.isSuccessful || this.isNewLink) {\n return;\n } else {\n return CircleXIcon;\n }\n }\n\n get controller() {\n return this.args.controller;\n }\n\n get node() {\n return this.args.node;\n }\n\n get selected() {\n return this.args.selected;\n }\n\n get interactive() {\n return this.node.attrs['interactive'] as boolean;\n }\n\n get class() {\n return `say-pill ${this.linkParserResult.isSuccessful || this.isNewLink ? '' : 'say-pill--error'}`;\n }\n\n @action\n onClick(event: PointerEvent) {\n this.hideTooltip = false;\n if (event.ctrlKey || event.metaKey) {\n window.open(this.href);\n }\n }\n\n get shouldShowTooltip() {\n return this.interactive && this.link && this.selected && !this.hideTooltip;\n }\n\n onKeyUp = (event: KeyboardEvent) => {\n if (event.key === 'Escape' || event.key === 'Enter') {\n this.hideTooltip = true;\n } else {\n this.hideTooltip = false;\n }\n };\n\n <template>\n <Velcro\n @placement=\"bottom-start\"\n @offsetOptions={{hash mainAxis=3}}\n @strategy=\"fixed\"\n as |velcro|\n >\n <Pill\n {{on \"keyup\" this.onKeyUp}}\n class={{this.class}}\n @skin=\"link\"\n @icon={{this.linkIcon}}\n title={{this.linkTitle}}\n aria-describedby=\"link-tooltip\"\n {{velcro.hook}}\n {{on \"click\" this.onClick}}\n >\n <EmbeddedEditor\n @controller={{@controller}}\n @node={{@node}}\n @view={{@view}}\n @getPos={{@getPos}}\n @onSelected={{this.selectionChangeHandler}}\n @selected={{@selected}}\n @placeholder={{t \"ember-rdfa-editor.link.placeholder.text\"}}\n @contentDecorations={{@contentDecorations}}\n @updateAttribute={{@updateAttribute}}\n @selectNode={{@selectNode}}\n {{leaveOnEnterKey @controller @getPos}}\n />\n </Pill>\n {{#if this.shouldShowTooltip}}\n <LinkEditor\n {{on \"keyup\" this.onKeyUp}}\n @controller={{@controller}}\n {{! @glint-expect-error }}\n @link={{this.link}}\n @linkParser={{this.linkParser}}\n {{velcro.loop}}\n />\n {{/if}}\n </Velcro>\n </template>\n}\n"],"names":["Link","Component","g","prototype","service","i","tracked","isNewLink","link","node","attrs","selectionChangeHandler","selected","hideTooltip","args","updateAttribute","href","pos","getPos","linkParser","defaultLinkParser","linkParserResult","n","cached","linkTitle","isSuccessful","intl","t","errors","linkIcon","CircleXIcon","controller","interactive","class","onClick","event","ctrlKey","metaKey","window","open","action","shouldShowTooltip","onKeyUp","key","setComponentTemplate","precompileTemplate","strictMode","scope","Velcro","hash","Pill","on","EmbeddedEditor","leaveOnEnterKey","LinkEditor"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { action } from '@ember/object';
2
2
  import Component from '@glimmer/component';
3
- import { r as redo } from '../../../index-CxRqg5Kr.js';
3
+ import { redo } from '../../../plugins/history/index.js';
4
4
  import '../../../core/say-controller.js';
5
5
  import { RedoIcon } from '@appuniversum/ember-appuniversum/components/icons/redo';
6
6
  import { precompileTemplate } from '@ember/template-compilation';
@@ -1,6 +1,6 @@
1
1
  import { action } from '@ember/object';
2
2
  import Component from '@glimmer/component';
3
- import { u as undo } from '../../../index-CxRqg5Kr.js';
3
+ import { undo } from '../../../plugins/history/index.js';
4
4
  import '../../../core/say-controller.js';
5
5
  import { UndoIcon } from '@appuniversum/ember-appuniversum/components/icons/undo';
6
6
  import { precompileTemplate } from '@ember/template-compilation';
@@ -1 +1 @@
1
- {"version":3,"file":"say-view.js","sources":["../../src/core/say-view.ts"],"sourcesContent":["import { AllSelection, EditorState, Selection } from 'prosemirror-state';\nimport { type DirectEditorProps, EditorView } from 'prosemirror-view';\nimport { tracked } from '@glimmer/tracking';\nimport { htmlToDoc, htmlToFragment } from '../utils/_private/html-utils.ts';\nimport { SetDocAttributesStep } from '../utils/steps.ts';\nimport { ProseParser } from '#root/prosemirror-aliases.ts';\nimport { DOMSerializer } from 'prosemirror-model';\n\nexport interface SetHtmlOptions {\n shouldFocus?: boolean;\n range?: DocumentRange;\n /**\n * Do not clean, only sanitize the input. This leaves empty elements and proprietary tags intact,\n * so is only suitable for HTML produced by the editor or otherwise known to be understood by it.\n * Defaults to false.\n */\n doNotClean?: boolean;\n /**\n * Whether the initial state should be considered as a 'dirty' state e.g. if this is a new\n * document that has not yet been saved.\n */\n startsDirty?: boolean;\n}\nexport type DocumentRange = {\n from: number;\n to: number;\n};\n\nexport default class SayView extends EditorView {\n isSayView = true;\n @tracked declare state: EditorState;\n @tracked parent?: SayView;\n domParser: ProseParser;\n\n constructor(\n place:\n | Node\n | ((editor: HTMLElement) => void)\n | {\n mount: HTMLElement;\n }\n | null,\n props: DirectEditorProps,\n parent?: SayView,\n ) {\n super(place, props);\n this.domParser =\n props.domParser ?? ProseParser.fromSchema(this.state.schema);\n this.parent = parent;\n }\n\n /**\n * Replaces the state (and current document) with a parsed version of the provided `html` string.\n * This method creates a new `doc` node and parses it correctly based on the provided html.\n * Note: plugin state is preserved but a new transaction setting the new content will be\n * dispatched.\n */\n setHtmlContent(content: string, options: SetHtmlOptions = {}) {\n const { shouldFocus = true, doNotClean } = options;\n if (shouldFocus) {\n this.focus();\n }\n const { range } = options;\n const tr = this.state.tr;\n if (range) {\n const fragment = htmlToFragment(content, {\n parser: this.domParser,\n editorView: this,\n doNotClean,\n });\n tr.replaceRange(range.from, range.to, fragment);\n } else {\n const doc = htmlToDoc(content, {\n schema: this.state.schema,\n parser: this.domParser,\n editorView: this,\n doNotClean,\n });\n tr.step(new SetDocAttributesStep(doc.attrs));\n tr.replaceWith(0, tr.doc.nodeSize - 2, doc);\n tr.setSelection(Selection.atEnd(tr.doc));\n }\n this.dispatch(tr);\n }\n\n get htmlContent(): string {\n const serializer =\n this.props.clipboardSerializer ??\n DOMSerializer.fromSchema(this.state.schema);\n const div = document.createElement('div');\n const doc = serializer.serializeNode(this.state.doc, undefined);\n div.appendChild(doc);\n return div.innerHTML;\n }\n\n updateState(state: EditorState): void {\n super.updateState(state);\n const { selection } = state;\n this.dom.classList.toggle(\n 'say-selection-all',\n selection instanceof AllSelection,\n );\n }\n}\n"],"names":["SayView","EditorView","isSayView","g","prototype","tracked","i","domParser","constructor","place","props","parent","ProseParser","fromSchema","state","schema","setHtmlContent","content","options","shouldFocus","doNotClean","focus","range","tr","fragment","htmlToFragment","parser","editorView","replaceRange","from","to","doc","htmlToDoc","step","SetDocAttributesStep","attrs","replaceWith","nodeSize","setSelection","Selection","atEnd","dispatch","htmlContent","serializer","clipboardSerializer","DOMSerializer","div","document","createElement","serializeNode","undefined","appendChild","innerHTML","updateState","selection","dom","classList","toggle","AllSelection"],"mappings":"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"}
1
+ {"version":3,"file":"say-view.js","sources":["../../src/core/say-view.ts"],"sourcesContent":["import { AllSelection, EditorState, Selection } from 'prosemirror-state';\nimport { type DirectEditorProps, EditorView } from 'prosemirror-view';\nimport { tracked } from '@glimmer/tracking';\nimport { htmlToDoc, htmlToFragment } from '../utils/_private/html-utils.ts';\nimport { SetDocAttributesStep } from '../utils/steps.ts';\nimport { ProseParser } from '#root/prosemirror-aliases.ts';\nimport { DOMSerializer } from 'prosemirror-model';\n\nexport interface SetHtmlOptions {\n shouldFocus?: boolean;\n range?: DocumentRange;\n /**\n * Do not clean, only sanitize the input. This leaves empty elements and proprietary tags intact,\n * so is only suitable for HTML produced by the editor or otherwise known to be understood by it.\n * Defaults to false.\n */\n doNotClean?: boolean;\n /**\n * Whether the initial state should be considered as a 'dirty' state e.g. if this is a new\n * document that has not yet been saved.\n */\n startsDirty?: boolean;\n}\nexport type DocumentRange = {\n from: number;\n to: number;\n};\n\nexport default class SayView extends EditorView {\n isSayView = true;\n @tracked declare state: EditorState;\n @tracked parent?: EditorView;\n domParser: ProseParser;\n\n constructor(\n place:\n | Node\n | ((editor: HTMLElement) => void)\n | {\n mount: HTMLElement;\n }\n | null,\n props: DirectEditorProps,\n parent?: EditorView,\n ) {\n super(place, props);\n this.domParser =\n props.domParser ?? ProseParser.fromSchema(this.state.schema);\n this.parent = parent;\n }\n\n /**\n * Replaces the state (and current document) with a parsed version of the provided `html` string.\n * This method creates a new `doc` node and parses it correctly based on the provided html.\n * Note: plugin state is preserved but a new transaction setting the new content will be\n * dispatched.\n */\n setHtmlContent(content: string, options: SetHtmlOptions = {}) {\n const { shouldFocus = true, doNotClean } = options;\n if (shouldFocus) {\n this.focus();\n }\n const { range } = options;\n const tr = this.state.tr;\n if (range) {\n const fragment = htmlToFragment(content, {\n parser: this.domParser,\n editorView: this,\n doNotClean,\n });\n tr.replaceRange(range.from, range.to, fragment);\n } else {\n const doc = htmlToDoc(content, {\n schema: this.state.schema,\n parser: this.domParser,\n editorView: this,\n doNotClean,\n });\n tr.step(new SetDocAttributesStep(doc.attrs));\n tr.replaceWith(0, tr.doc.nodeSize - 2, doc);\n tr.setSelection(Selection.atEnd(tr.doc));\n }\n this.dispatch(tr);\n }\n\n get htmlContent(): string {\n const serializer =\n this.props.clipboardSerializer ??\n DOMSerializer.fromSchema(this.state.schema);\n const div = document.createElement('div');\n const doc = serializer.serializeNode(this.state.doc, undefined);\n div.appendChild(doc);\n return div.innerHTML;\n }\n\n updateState(state: EditorState): void {\n super.updateState(state);\n const { selection } = state;\n this.dom.classList.toggle(\n 'say-selection-all',\n selection instanceof AllSelection,\n );\n }\n}\n"],"names":["SayView","EditorView","isSayView","g","prototype","tracked","i","domParser","constructor","place","props","parent","ProseParser","fromSchema","state","schema","setHtmlContent","content","options","shouldFocus","doNotClean","focus","range","tr","fragment","htmlToFragment","parser","editorView","replaceRange","from","to","doc","htmlToDoc","step","SetDocAttributesStep","attrs","replaceWith","nodeSize","setSelection","Selection","atEnd","dispatch","htmlContent","serializer","clipboardSerializer","DOMSerializer","div","document","createElement","serializeNode","undefined","appendChild","innerHTML","updateState","selection","dom","classList","toggle","AllSelection"],"mappings":"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"}
@@ -1,2 +1,66 @@
1
- export { c as closeHistory, g as getHistoryStateId, h as history, i as isHistoryTransaction, m as matchesTaggedHistory, r as redo, a as redoDepth, b as redoNoScroll, u as undo, d as undoDepth, e as undoNoScroll } from '../../index-CxRqg5Kr.js';
1
+ import { r as redo$1, u as undo$1, c as closeHistory$1, g as getHistoryStateId$1, h as history$1, i as isHistoryTransaction$1, m as matchesTaggedHistory$1, a as redoDepth$1, b as redoNoScroll$1, d as undoDepth$1, e as undoNoScroll$1 } from '../../index-CxRqg5Kr.js';
2
+
3
+ /* eslint-disable @typescript-eslint/no-explicit-any */
4
+
5
+
6
+ /**
7
+ Set a flag on the given transaction that will prevent further steps
8
+ from being appended to an existing history event (so that they
9
+ require a separate undo command to undo).
10
+ */
11
+ const closeHistory = closeHistory$1;
12
+ /**
13
+ Returns a plugin that enables the undo history for an editor. The
14
+ plugin will track undo and redo stacks, which can be used with the
15
+ [`undo`](https://prosemirror.net/docs/ref/#history.undo) and [`redo`](https://prosemirror.net/docs/ref/#history.redo) commands.
16
+
17
+ You can set an `"addToHistory"` [metadata
18
+ property](https://prosemirror.net/docs/ref/#state.Transaction.setMeta) of `false` on a transaction
19
+ to prevent it from being rolled back by undo.
20
+ */
21
+ const history = history$1;
22
+ /**
23
+ A command function that undoes the last change, if any.
24
+ */
25
+ const undo = undo$1;
26
+ /**
27
+ A command function that redoes the last undone change, if any.
28
+ */
29
+ const redo = redo$1;
30
+ /**
31
+ A command function that undoes the last change. Don't scroll the
32
+ selection into view.
33
+ */
34
+ const undoNoScroll = undoNoScroll$1;
35
+ /**
36
+ A command function that redoes the last undone change. Don't
37
+ scroll the selection into view.
38
+ */
39
+ const redoNoScroll = redoNoScroll$1;
40
+ /**
41
+ The amount of undoable events available in a given state.
42
+ */
43
+ const undoDepth = undoDepth$1;
44
+ /**
45
+ The amount of redoable events available in a given editor state.
46
+ */
47
+ const redoDepth = redoDepth$1;
48
+ /**
49
+ Returns true if the given transaction was generated by the history
50
+ plugin.
51
+ */
52
+ const isHistoryTransaction = isHistoryTransaction$1;
53
+ /**
54
+ Returns the unique ID of the current history for a given editor state.
55
+ This can for example be used to compare against a saved state, to
56
+ determine if there are changes since then.
57
+ */
58
+ const getHistoryStateId = getHistoryStateId$1;
59
+ /**
60
+ Whether the unique IDs of the history for the given editor state matches
61
+ the passed ID.
62
+ */
63
+ const matchesTaggedHistory = matchesTaggedHistory$1;
64
+
65
+ export { closeHistory, getHistoryStateId, history, isHistoryTransaction, matchesTaggedHistory, redo, redoDepth, redoNoScroll, undo, undoDepth, undoNoScroll };
2
66
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
1
+ {"version":3,"file":"index.js","sources":["../../../src/plugins/history/index.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport type {\n Transaction,\n EditorState,\n Plugin,\n Command,\n} from 'prosemirror-state';\nimport * as pmh from 'prosemirror-history';\n\n/**\nSet a flag on the given transaction that will prevent further steps\nfrom being appended to an existing history event (so that they\nrequire a separate undo command to undo).\n*/\nconst closeHistory: (tr: Transaction) => Transaction = pmh.closeHistory;\ninterface HistoryOptions {\n /**\n The amount of history events that are collected before the\n oldest events are discarded. Defaults to 100.\n */\n depth?: number;\n /**\n The delay between changes after which a new group should be\n started. Defaults to 500 (milliseconds). Note that when changes\n aren't adjacent, a new group is always started.\n */\n newGroupDelay?: number;\n}\n/**\nReturns a plugin that enables the undo history for an editor. The\nplugin will track undo and redo stacks, which can be used with the\n[`undo`](https://prosemirror.net/docs/ref/#history.undo) and [`redo`](https://prosemirror.net/docs/ref/#history.redo) commands.\n\nYou can set an `\"addToHistory\"` [metadata\nproperty](https://prosemirror.net/docs/ref/#state.Transaction.setMeta) of `false` on a transaction\nto prevent it from being rolled back by undo.\n*/\nconst history: (config?: HistoryOptions) => Plugin = pmh.history;\n/**\nA command function that undoes the last change, if any.\n*/\nconst undo: Command = pmh.undo;\n/**\nA command function that redoes the last undone change, if any.\n*/\nconst redo: Command = pmh.redo;\n/**\nA command function that undoes the last change. Don't scroll the\nselection into view.\n*/\nconst undoNoScroll: Command = pmh.undoNoScroll;\n/**\nA command function that redoes the last undone change. Don't\nscroll the selection into view.\n*/\nconst redoNoScroll: Command = pmh.redoNoScroll;\n/**\nThe amount of undoable events available in a given state.\n*/\nconst undoDepth: (state: EditorState) => any = pmh.undoDepth;\n/**\nThe amount of redoable events available in a given editor state.\n*/\nconst redoDepth: (state: EditorState) => any = pmh.redoDepth;\n/**\nReturns true if the given transaction was generated by the history\nplugin.\n*/\nconst isHistoryTransaction: (tr: Transaction) => boolean =\n pmh.isHistoryTransaction;\n/**\nReturns the unique ID of the current history for a given editor state.\nThis can for example be used to compare against a saved state, to\ndetermine if there are changes since then.\n*/\nconst getHistoryStateId: (state: EditorState) => string | undefined =\n pmh.getHistoryStateId;\n/**\nWhether the unique IDs of the history for the given editor state matches\nthe passed ID.\n*/\nconst matchesTaggedHistory: (state: EditorState, id: string) => boolean =\n pmh.matchesTaggedHistory;\n\nexport {\n closeHistory,\n getHistoryStateId,\n history,\n isHistoryTransaction,\n matchesTaggedHistory,\n redo,\n redoDepth,\n redoNoScroll,\n undo,\n undoDepth,\n undoNoScroll,\n};\n"],"names":["closeHistory","pmh","history","undo","redo","undoNoScroll","redoNoScroll","undoDepth","redoDepth","isHistoryTransaction","getHistoryStateId","matchesTaggedHistory"],"mappings":";;AAAA;;;AASA;AACA;AACA;AACA;AACA;AACA,MAAMA,YAA8C,GAAGC;AAcvD;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAMC,OAA4C,GAAGD;AACrD;AACA;AACA;AACA,MAAME,IAAa,GAAGF;AACtB;AACA;AACA;AACA,MAAMG,IAAa,GAAGH;AACtB;AACA;AACA;AACA;AACA,MAAMI,YAAqB,GAAGJ;AAC9B;AACA;AACA;AACA;AACA,MAAMK,YAAqB,GAAGL;AAC9B;AACA;AACA;AACA,MAAMM,SAAsC,GAAGN;AAC/C;AACA;AACA;AACA,MAAMO,SAAsC,GAAGP;AAC/C;AACA;AACA;AACA;AACA,MAAMQ,oBAAkD,GACtDR;AACF;AACA;AACA;AACA;AACA;AACA,MAAMS,iBAA6D,GACjET;AACF;AACA;AACA;AACA;AACA,MAAMU,oBAAiE,GACrEV;;;;"}
@@ -1,43 +1,42 @@
1
1
  import { test, find } from 'linkifyjs';
2
- import parsePhoneNumber from 'libphonenumber-js';
2
+ import parsePhoneNumber, { isValidPhoneNumber } from 'libphonenumber-js';
3
+ import isEmail from 'validator/lib/isEmail';
4
+ import isURL from 'validator/lib/isURL';
3
5
 
6
+ const INVALID_LINK_RESULT = {
7
+ isSuccessful: false,
8
+ errors: ['De ingegeven URL/link is niet geldig']
9
+ };
4
10
  const defaultLinkParser = ({
5
11
  defaultCountryCode = 'BE',
6
- supportedProtocols = ['http:', 'https:', 'mailto:', 'tel:', 'sms:']
12
+ supportedProtocols = ['http:', 'https:', 'mailto:', 'tel:', 'sms:'],
13
+ customProtocolValidatorMapping
7
14
  } = {}) => {
8
15
  return input => {
9
- const link = input?.trim();
10
- if (!link) {
16
+ const trimmedInput = input?.trim();
17
+ if (!trimmedInput) {
11
18
  return {
12
19
  isSuccessful: false,
13
20
  errors: ['URL mag niet leeg zijn']
14
21
  };
15
22
  }
16
- let href;
17
- if (test(link)) {
18
- href = find(link)[0].href;
19
- }
23
+
24
+ /**
25
+ * First step: parsing/detection of link
26
+ * `linkifyjs` and `libphonenumber-js` will check if the input text has the form of a link, and will add a protocol if necessary
27
+ * Note: e.g. `mailto:test` or `http://test` will be seen as valid by this step, so a second validation step is also necessary
28
+ */
29
+ const href = detectLink(trimmedInput, defaultCountryCode);
20
30
  if (!href) {
21
- const phoneNumber = parsePhoneNumber(link, defaultCountryCode);
22
- if (phoneNumber) {
23
- const phoneNumberUri = phoneNumber.getURI();
24
- const value = link.startsWith('sms:') ?
25
- // libphonenumber-js transforms sms: automatically to tel:, so revert this transform if necessary
26
- phoneNumberUri.replace('tel:', 'sms:') : phoneNumberUri;
27
- href = value;
28
- }
31
+ return INVALID_LINK_RESULT;
29
32
  }
30
- if (!href) {
31
- return {
32
- isSuccessful: false,
33
- errors: ['De ingegeven URL/link is niet geldig']
34
- };
35
- }
36
- if (!hasSupportedProtocol(href, supportedProtocols)) {
37
- return {
38
- isSuccessful: false,
39
- errors: ['de ingegeven URL/link is niet toegestaan']
40
- };
33
+
34
+ /**
35
+ * Second step: link validation
36
+ * Using `isURL`/`isEmail`/custom validators from the validator.js library, we check if the produced href is valid
37
+ */
38
+ if (!isValidHref(href, supportedProtocols, customProtocolValidatorMapping)) {
39
+ return INVALID_LINK_RESULT;
41
40
  }
42
41
  return {
43
42
  isSuccessful: true,
@@ -45,10 +44,43 @@ const defaultLinkParser = ({
45
44
  };
46
45
  };
47
46
  };
48
- const hasSupportedProtocol = (href, supportedProtocols) => {
47
+ const detectLink = (input, defaultCountryCode) => {
48
+ if (test(input)) {
49
+ const matches = find(input);
50
+ return matches[0].href;
51
+ }
52
+ const phoneNumber = parsePhoneNumber(input, defaultCountryCode);
53
+ if (phoneNumber) {
54
+ const phoneUri = phoneNumber.getURI();
55
+ return input.startsWith('sms:') ? phoneUri.replace('tel:', 'sms:') : phoneUri;
56
+ }
57
+ return;
58
+ };
59
+ const BUILT_IN_VALIDATORS = {
60
+ 'mailto:': url => isEmail(url.pathname),
61
+ 'tel:': url => isValidPhoneNumber(url.pathname),
62
+ 'sms:': url => isValidPhoneNumber(url.pathname),
63
+ 'http:': url => isURL(url.href, {
64
+ require_protocol: true,
65
+ require_tld: true
66
+ }),
67
+ 'https:': url => isURL(url.href, {
68
+ require_protocol: true,
69
+ require_tld: true
70
+ })
71
+ };
72
+ const isValidHref = (href, supportedProtocols, customProtocolValidatorMapping) => {
49
73
  try {
50
- const protocol = new URL(href).protocol;
51
- return supportedProtocols.includes(protocol);
74
+ const url = new URL(href);
75
+ if (!supportedProtocols.includes(url.protocol)) {
76
+ return false;
77
+ }
78
+ const protocolValidatorMapping = {
79
+ ...BUILT_IN_VALIDATORS,
80
+ ...(customProtocolValidatorMapping ?? {})
81
+ };
82
+ const validationFn = protocolValidatorMapping[url.protocol];
83
+ return validationFn ? validationFn(url) : true;
52
84
  } catch {
53
85
  return false;
54
86
  }
@@ -1 +1 @@
1
- {"version":3,"file":"parser.js","sources":["../../../src/plugins/link/parser.ts"],"sourcesContent":["import { find as linkifyFind, test as linkifyTest } from 'linkifyjs';\nimport parsePhoneNumber, { type CountryCode } from 'libphonenumber-js';\n\nexport type LinkParserResult =\n | {\n isSuccessful: true;\n value: string;\n errors?: never;\n }\n | {\n isSuccessful: false;\n value?: never;\n errors: [string, ...string[]];\n };\nexport type LinkParser = (input?: string) => LinkParserResult;\n\ntype DefaultLinkParserOptions = {\n defaultCountryCode?: CountryCode;\n supportedProtocols?: string[];\n};\n\nexport const defaultLinkParser = ({\n defaultCountryCode = 'BE',\n supportedProtocols = ['http:', 'https:', 'mailto:', 'tel:', 'sms:'],\n}: DefaultLinkParserOptions = {}): LinkParser => {\n return (input?: string) => {\n const link = input?.trim();\n if (!link) {\n return { isSuccessful: false, errors: ['URL mag niet leeg zijn'] };\n }\n\n let href: string | undefined;\n\n if (linkifyTest(link)) {\n href = linkifyFind(link)[0].href;\n }\n\n if (!href) {\n const phoneNumber = parsePhoneNumber(link, defaultCountryCode);\n if (phoneNumber) {\n const phoneNumberUri = phoneNumber.getURI();\n const value = link.startsWith('sms:')\n ? // libphonenumber-js transforms sms: automatically to tel:, so revert this transform if necessary\n phoneNumberUri.replace('tel:', 'sms:')\n : phoneNumberUri;\n href = value;\n }\n }\n if (!href) {\n return {\n isSuccessful: false,\n errors: ['De ingegeven URL/link is niet geldig'],\n };\n }\n\n if (!hasSupportedProtocol(href, supportedProtocols)) {\n return {\n isSuccessful: false,\n errors: ['de ingegeven URL/link is niet toegestaan'],\n };\n }\n\n return {\n isSuccessful: true,\n value: href,\n };\n };\n};\n\nconst hasSupportedProtocol = (href: string, supportedProtocols: string[]) => {\n try {\n const protocol = new URL(href).protocol;\n return supportedProtocols.includes(protocol);\n } catch {\n return false;\n }\n};\n"],"names":["defaultLinkParser","defaultCountryCode","supportedProtocols","input","link","trim","isSuccessful","errors","href","linkifyTest","linkifyFind","phoneNumber","parsePhoneNumber","phoneNumberUri","getURI","value","startsWith","replace","hasSupportedProtocol","protocol","URL","includes"],"mappings":";;;AAqBO,MAAMA,iBAAiB,GAAGA,CAAC;AAChCC,EAAAA,kBAAkB,GAAG,IAAI;EACzBC,kBAAkB,GAAG,CAAC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM;AAC1C,CAAC,GAAG,EAAE,KAAiB;AAC/C,EAAA,OAAQC,KAAc,IAAK;AACzB,IAAA,MAAMC,IAAI,GAAGD,KAAK,EAAEE,IAAI,EAAE;IAC1B,IAAI,CAACD,IAAI,EAAE;MACT,OAAO;AAAEE,QAAAA,YAAY,EAAE,KAAK;QAAEC,MAAM,EAAE,CAAC,wBAAwB;OAAG;AACpE,IAAA;AAEA,IAAA,IAAIC,IAAwB;AAE5B,IAAA,IAAIC,IAAW,CAACL,IAAI,CAAC,EAAE;MACrBI,IAAI,GAAGE,IAAW,CAACN,IAAI,CAAC,CAAC,CAAC,CAAC,CAACI,IAAI;AAClC,IAAA;IAEA,IAAI,CAACA,IAAI,EAAE;AACT,MAAA,MAAMG,WAAW,GAAGC,gBAAgB,CAACR,IAAI,EAAEH,kBAAkB,CAAC;AAC9D,MAAA,IAAIU,WAAW,EAAE;AACf,QAAA,MAAME,cAAc,GAAGF,WAAW,CAACG,MAAM,EAAE;AAC3C,QAAA,MAAMC,KAAK,GAAGX,IAAI,CAACY,UAAU,CAAC,MAAM,CAAC;AACjC;QACAH,cAAc,CAACI,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,GACtCJ,cAAc;AAClBL,QAAAA,IAAI,GAAGO,KAAK;AACd,MAAA;AACF,IAAA;IACA,IAAI,CAACP,IAAI,EAAE;MACT,OAAO;AACLF,QAAAA,YAAY,EAAE,KAAK;QACnBC,MAAM,EAAE,CAAC,sCAAsC;OAChD;AACH,IAAA;AAEA,IAAA,IAAI,CAACW,oBAAoB,CAACV,IAAI,EAAEN,kBAAkB,CAAC,EAAE;MACnD,OAAO;AACLI,QAAAA,YAAY,EAAE,KAAK;QACnBC,MAAM,EAAE,CAAC,0CAA0C;OACpD;AACH,IAAA;IAEA,OAAO;AACLD,MAAAA,YAAY,EAAE,IAAI;AAClBS,MAAAA,KAAK,EAAEP;KACR;EACH,CAAC;AACH;AAEA,MAAMU,oBAAoB,GAAGA,CAACV,IAAY,EAAEN,kBAA4B,KAAK;EAC3E,IAAI;IACF,MAAMiB,QAAQ,GAAG,IAAIC,GAAG,CAACZ,IAAI,CAAC,CAACW,QAAQ;AACvC,IAAA,OAAOjB,kBAAkB,CAACmB,QAAQ,CAACF,QAAQ,CAAC;AAC9C,EAAA,CAAC,CAAC,MAAM;AACN,IAAA,OAAO,KAAK;AACd,EAAA;AACF,CAAC;;;;"}
1
+ {"version":3,"file":"parser.js","sources":["../../../src/plugins/link/parser.ts"],"sourcesContent":["import { find as linkifyFind, test as linkifyTest } from 'linkifyjs';\nimport parsePhoneNumber, {\n isValidPhoneNumber,\n type CountryCode,\n} from 'libphonenumber-js';\nimport isEmail from 'validator/lib/isEmail';\nimport isURL from 'validator/lib/isURL';\n\nexport type LinkParserResult =\n | {\n isSuccessful: true;\n value: string;\n errors?: never;\n }\n | {\n isSuccessful: false;\n value?: never;\n errors: [string, ...string[]];\n };\nexport type LinkParser = (input?: string) => LinkParserResult;\n\ntype DefaultLinkParserOptions = {\n defaultCountryCode?: CountryCode;\n supportedProtocols?: string[];\n customProtocolValidatorMapping?: ProtocolValidatorMapping;\n};\n\nconst INVALID_LINK_RESULT: LinkParserResult = {\n isSuccessful: false,\n errors: ['De ingegeven URL/link is niet geldig'],\n};\n\nexport const defaultLinkParser = ({\n defaultCountryCode = 'BE',\n supportedProtocols = ['http:', 'https:', 'mailto:', 'tel:', 'sms:'],\n customProtocolValidatorMapping,\n}: DefaultLinkParserOptions = {}): LinkParser => {\n return (input?: string) => {\n const trimmedInput = input?.trim();\n if (!trimmedInput) {\n return { isSuccessful: false, errors: ['URL mag niet leeg zijn'] };\n }\n\n /**\n * First step: parsing/detection of link\n * `linkifyjs` and `libphonenumber-js` will check if the input text has the form of a link, and will add a protocol if necessary\n * Note: e.g. `mailto:test` or `http://test` will be seen as valid by this step, so a second validation step is also necessary\n */\n const href = detectLink(trimmedInput, defaultCountryCode);\n\n if (!href) {\n return INVALID_LINK_RESULT;\n }\n\n /**\n * Second step: link validation\n * Using `isURL`/`isEmail`/custom validators from the validator.js library, we check if the produced href is valid\n */\n if (\n !isValidHref(href, supportedProtocols, customProtocolValidatorMapping)\n ) {\n return INVALID_LINK_RESULT;\n }\n\n return {\n isSuccessful: true,\n value: href,\n };\n };\n};\n\nconst detectLink = (\n input: string,\n defaultCountryCode: CountryCode,\n): string | undefined => {\n if (linkifyTest(input)) {\n const matches = linkifyFind(input);\n return matches[0].href;\n }\n\n const phoneNumber = parsePhoneNumber(input, defaultCountryCode);\n if (phoneNumber) {\n const phoneUri = phoneNumber.getURI();\n return input.startsWith('sms:')\n ? phoneUri.replace('tel:', 'sms:')\n : phoneUri;\n }\n\n return;\n};\n\ntype URLValidator = (url: URL) => boolean;\n\ntype ProtocolValidatorMapping = Record<string, URLValidator>;\n\nconst BUILT_IN_VALIDATORS: ProtocolValidatorMapping = {\n 'mailto:': (url) => isEmail(url.pathname),\n 'tel:': (url) => isValidPhoneNumber(url.pathname),\n 'sms:': (url) => isValidPhoneNumber(url.pathname),\n 'http:': (url) =>\n isURL(url.href, { require_protocol: true, require_tld: true }),\n 'https:': (url) =>\n isURL(url.href, { require_protocol: true, require_tld: true }),\n};\n\nconst isValidHref = (\n href: string,\n supportedProtocols: string[],\n customProtocolValidatorMapping?: ProtocolValidatorMapping,\n) => {\n try {\n const url = new URL(href);\n if (!supportedProtocols.includes(url.protocol)) {\n return false;\n }\n const protocolValidatorMapping = {\n ...BUILT_IN_VALIDATORS,\n ...(customProtocolValidatorMapping ?? {}),\n };\n const validationFn = protocolValidatorMapping[url.protocol];\n return validationFn ? validationFn(url) : true;\n } catch {\n return false;\n }\n};\n"],"names":["INVALID_LINK_RESULT","isSuccessful","errors","defaultLinkParser","defaultCountryCode","supportedProtocols","customProtocolValidatorMapping","input","trimmedInput","trim","href","detectLink","isValidHref","value","linkifyTest","matches","linkifyFind","phoneNumber","parsePhoneNumber","phoneUri","getURI","startsWith","replace","BUILT_IN_VALIDATORS","url","isEmail","pathname","isValidPhoneNumber","isURL","require_protocol","require_tld","URL","includes","protocol","protocolValidatorMapping","validationFn"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ember-node.js","sources":["../../../src/utils/_private/ember-node.ts"],"sourcesContent":["/**\n * Contains code from https://github.com/ueberdosis/tiptap/blob/d61a621186470ce286e2cecf8206837a1eec7338/packages/core/src/NodeView.ts#L195\n *\n * MIT License\n * Copyright (c) 2023, Tiptap GmbH\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n/**\n\n */\n\nimport { hbs, type TemplateFactory } from 'ember-cli-htmlbars';\nimport type {\n AttributeSpec,\n DOMOutputSpec,\n TagParseRule,\n Node as PNode,\n Attrs,\n} from 'prosemirror-model';\nimport {\n Decoration,\n type DecorationSource,\n type NodeView,\n} from 'prosemirror-view';\nimport { v4 as uuidv4 } from 'uuid';\n// eslint-disable-next-line ember/no-classic-components\nimport Component from '@ember/component';\nimport type Owner from '@ember/owner';\nimport type { ComponentLike } from '@glint/template';\nimport SayController from '#root/core/say-controller.ts';\nimport type SayNodeSpec from '#root/core/say-node-spec.ts';\nimport type { NodeSerializer } from '#root/core/say-serializer.ts';\nimport type SayView from '#root/core/say-view.ts';\nimport { NodeSelection } from 'prosemirror-state';\n\nexport interface EmberInlineComponent extends Component, EmberNodeArgs {\n appendTo(selector: string | Element): this;\n}\n\nexport interface EmberNodeArgs {\n getPos: () => number | undefined;\n node: PNode;\n /**\n * Util method to help with keeping state in `attrs` of the node.\n * Instead of a tracked property, you'll often use the following logic to keep state inside the node:\n * `get someText() { return this.args.node.attrs.someText; }`\n * `set someText(value) { return this.args.updateAttribute('someText', value); }`\n */\n updateAttribute: (\n attr: string,\n value: unknown,\n ignoreHistory?: boolean,\n ) => void;\n /**\n * Util method which selects the node within the editor\n */\n selectNode: () => void;\n controller: SayController;\n view: SayView;\n selected: boolean;\n contentDecorations?: DecorationSource;\n}\n\nfunction emberComponent(\n owner: Owner,\n name: string,\n inline: boolean,\n template: TemplateFactory,\n props: EmberNodeArgs & {\n atom: boolean;\n component: ComponentLike<{ Args: EmberNodeArgs }>;\n contentDOM?: HTMLElement;\n },\n): { node: HTMLElement; component: EmberInlineComponent } {\n // const instance = window.__APPLICATION;\n const componentName = `${name}-${uuidv4()}`;\n owner.register(\n `component:${componentName}`,\n // eslint-disable-next-line ember/no-classic-classes\n Component.extend({\n layout: template,\n tagName: '',\n ...props,\n }),\n );\n const component = owner.lookup(\n `component:${componentName}`,\n ) as EmberInlineComponent;\n const node = document.createElement(inline ? 'span' : 'div');\n node.classList.add('ember-node');\n component.appendTo(node);\n return { node, component };\n}\n\n/**\n * An EmberNode is a node with a custom Node View defined by an ember template.\n * First define your EmberNodeConfig, which should contain the information for:\n *\n * Afterwards use `createEmberNodeSpec(config)` and `createEmberNodeView(config)` to insert them in the schema.\n *\n * Special notes for EmberNode components:\n * - Prosemirror nodes are immutable by design. Any change to a node will create a new node that is loaded in.\n * - A rerender is avoided as much as possible here\n * - An ember component might still rerender because of other reasons (-> not yet known which reasons and if they exist)\n * - This means EmberNode components might lose their state at any time. *Don't save state in components properties*. @tracked properties will most likely not work as wanted.\n * - Keep state in `attrs` of the node.\n * Instead of a tracked property, you'll often use the following logic to keep state inside the node:\n * `get someText() { return this.args.node.attrs.someText; }`\n * `set someText(value) { return this.args.updateAttribute('someText', value); }`\n *\n * - when defining an ember-node using these utility functions, nested contenteditable attributes should be prevented.\n * Ember nodes which can contain editable content should never be `contenteditable: false` as a whole,\n * but only the parts which are `contenteditable: false` should be marked as so.\n * E.g.: It's preferred to write:\n *\n * ```\n * <div>\n * <header contenteditable=\"false\">\n * <p>header</p>\n * </header>\n * <content>\n * {{yield}}\n * </content>\n * </div>\n * ```\n * instead of\n * ```\n * <div contenteditable=\"false\">\n * <header>\n * <p>header</p>\n * </header>\n * <content contenteditable=\"true\">\n * {{yield}}\n * </content>\n * </div>\n * ```\n */\nclass EmberNodeView implements NodeView {\n node: PNode;\n dom: Element;\n contentDOM?: HTMLElement;\n emberComponent: EmberInlineComponent;\n template: TemplateFactory;\n config: EmberNodeConfig;\n\n constructor(\n controller: SayController,\n emberNodeConfig: EmberNodeConfig,\n pNode: PNode,\n view: SayView,\n getPos: () => number | undefined,\n ) {\n // when a node gets updated, `update()` is called.\n // We set the new node here and pass it to the component to render it.\n this.config = emberNodeConfig;\n const { name, component: componentClass, atom, inline } = emberNodeConfig;\n\n this.template = hbs`<this.component\n @getPos={{this.getPos}}\n @node={{this.node}}\n @updateAttribute={{this.updateAttribute}}\n @controller={{this.controller}}\n @view={{this.view}}\n @selected={{this.selected}}\n @contentDecorations={{this.contentDecorations}}\n @selectNode={{this.selectNode}}\n >\n {{#unless this.atom}}\n {{! @glint-expect-error: not typesafe yet }}\n <EmberNode::Slot @contentDOM={{this.contentDOM}}/>\n {{/unless}}\n </this.component>`;\n this.node = pNode;\n this.contentDOM = !atom\n ? document.createElement(inline ? 'span' : 'div', {})\n : undefined;\n // Note `this.contentDOM` needs an attribute to prevent chromium-based browsers from deleting it when it is empty/only has empty children.\n if (this.contentDOM) {\n this.contentDOM.dataset['emberNodeContent'] = 'true';\n }\n const { node, component } = emberComponent(\n controller.owner,\n name,\n inline,\n this.template,\n {\n getPos,\n node: pNode,\n updateAttribute: (attr, value, ignoreHistory) => {\n const pos = getPos();\n if (pos !== undefined) {\n const transaction = view.state.tr;\n if (ignoreHistory) {\n transaction.setMeta('addToHistory', false);\n }\n transaction.setNodeAttribute(pos, attr, value);\n view.dispatch(transaction);\n }\n },\n selectNode: () => {\n const pos = getPos();\n if (pos !== undefined) {\n const tr = controller.activeEditorState.tr;\n tr.setSelection(\n NodeSelection.create(controller.activeEditorState.doc, pos),\n );\n controller.activeEditorView.dispatch(tr);\n }\n },\n controller,\n contentDOM: this.contentDOM,\n component: componentClass,\n atom,\n view,\n selected: false,\n },\n );\n this.dom = node;\n if (this.config.domClassNames) {\n this.dom.classList.add(...this.config.domClassNames);\n }\n if (this.config.contentDomClassNames && this.contentDOM) {\n this.contentDOM.classList.add(...this.config.contentDomClassNames);\n }\n\n this.emberComponent = component;\n }\n\n update(\n node: PNode,\n _decorations: readonly Decoration[],\n innerDecorations: DecorationSource,\n ) {\n if (node.type !== this.node.type) return false;\n this.node = node;\n this.emberComponent.set('node', node);\n this.emberComponent.set('contentDecorations', innerDecorations);\n return true;\n }\n\n selectNode() {\n this.dom.classList.add('ProseMirror-selectednode');\n this.emberComponent.set('selected', true);\n }\n\n deselectNode() {\n this.dom.classList.remove('ProseMirror-selectednode');\n this.emberComponent.set('selected', false);\n }\n\n destroy() {\n this.emberComponent.destroy();\n }\n\n /**\n * Based on https://github.com/ueberdosis/tiptap/blob/d61a621186470ce286e2cecf8206837a1eec7338/packages/core/src/NodeView.ts#LL99C6-L99C6\n */\n stopEvent(event: Event) {\n if (!this.dom) {\n return false;\n }\n\n if (this.config.stopEvent) {\n const configStop = this.config.stopEvent(event);\n if (configStop !== null) {\n return configStop;\n }\n }\n\n // A dragstart event can come from non-content DOM and be valid, so don't stop it\n // Stopping the event results in the rendered HTML being used for the drag event, rather than\n // the serialized HTML, so breaks drag-drop for many EmberNodes\n if (\n ['dragstart', 'dragend', 'drop', 'dragover', 'dragenter'].includes(\n event.type,\n )\n ) {\n return false;\n }\n\n const target = event.target as HTMLElement;\n const isInElement =\n this.dom.contains(target) && !this.contentDOM?.contains(target);\n\n return isInElement;\n }\n\n /**\n * Taken from https://github.com/ueberdosis/tiptap/blob/d61a621186470ce286e2cecf8206837a1eec7338/packages/core/src/NodeView.ts#L195\n */\n ignoreMutation(\n mutation: MutationRecord | { type: 'selection'; target: Element },\n ) {\n if (!this.dom || !this.contentDOM) {\n return true;\n }\n if (this.config.ignoreMutation) {\n return this.config.ignoreMutation(mutation);\n }\n\n // a leaf/atom node is like a black box for ProseMirror\n // and should be fully handled by the node view\n if (this.node.isLeaf || this.node.isAtom) {\n return true;\n }\n\n // ProseMirror should handle any selections\n if (mutation.type === 'selection') {\n return false;\n }\n\n // we will allow mutation contentDOM with attributes\n // so we can for example adding classes within our node view\n if (this.contentDOM === mutation.target && mutation.type === 'attributes') {\n return true;\n }\n\n // ProseMirror should handle any changes within contentDOM\n if (this.contentDOM.contains(mutation.target)) {\n return false;\n }\n\n return true;\n }\n}\n\ninterface AtomConfig {\n /** Is an atom if is not a leaf node */\n atom: true;\n /**\n * ProseMissor content expression\n * @see {@link https://prosemirror.net/docs/guide/#schema.content_expressions|ProseMirror schema guide}\n */\n content?: string;\n}\ninterface NonAtomConfig {\n /** Is an atom if is not a leaf node */\n atom: false;\n /**\n * ProseMissor content expression\n * @see {@link https://prosemirror.net/docs/guide/#schema.content_expressions|ProseMirror schema guide}\n */\n content: string;\n}\n\n// Maybe this should be split so that a different one exists for each of the 2 functions which takes\n// it as an argument\nexport type EmberNodeConfig = {\n name: string;\n /** ember component to render as a Node View */\n component: ComponentLike<{ Args: EmberNodeArgs }>;\n inline: boolean;\n /** ProseMirror 'group' property for the created node */\n group: string;\n draggable?: boolean;\n /** @see {@link https://prosemirror.net/docs/ref/#model.NodeSpec.defining} */\n defining?: boolean;\n /**\n * @deprecated\n */\n recreateUri?: boolean;\n /**\n * @deprecated\n */\n uriAttributes?: [string];\n /** Generate a new URI when pasting the node? */\n recreateUriFunction?: (attrs: Attrs) => Attrs;\n /** A map of attributes to assign to this node */\n attrs?: {\n [name: string]: AttributeSpec & {\n editable?: boolean;\n serialize?: (node: PNode) => string;\n parse?: (element: HTMLElement) => unknown;\n };\n };\n /** @see {@link https://prosemirror.net/docs/ref/#model.NodeSpec.parseDOM} */\n parseDOM?: readonly TagParseRule[];\n /** @see {@link https://prosemirror.net/docs/ref/#model.NodeSpec.toDOM} */\n toDOM?: (node: PNode) => DOMOutputSpec;\n /**\n * Allows creating a serialized version based on the node itself\n * @see {@link SayNodeSpec}\n */\n serialize?: NodeSerializer;\n /**\n * Prevents the editor view from handling events which are inside the ember-node but not inside it's editable content.\n * By default this will stop events which occur inside the ember-node but not inside it's content.\n * Returning a boolean will stop or not stop an event, returning null will hand over to the default logic.\n * Only override the default logic if you know what you are doing.\n * @param event The event to check\n */\n stopEvent?: (event: Event) => boolean | null;\n domClassNames?: string[];\n contentDomClassNames?: string[];\n /**\n * Determines whether a DOM mutation should be ignored by prosemirror.\n * Use this to avoid rerendering a component for every change.\n * DOM mutations occuring inside the ember-node which are not inside it's editable content are ignored.\n * Selections are always handled by prosemirror.\n * Already has a default implementation. Only override if you know what you are doing.\n * @param mutation\n * @returns whether to ignore the mutation\n */\n ignoreMutation?: (\n mutation: MutationRecord | { type: 'selection'; target: Element },\n ) => boolean;\n /** Do we need to workaround cursor problems on Firefox */\n needsFFKludge?: boolean;\n /** Do we need to workaround cursor problems on Chrome */\n needsChromeCursorFix?: boolean;\n} & (AtomConfig | NonAtomConfig) & {\n /** This is so we can use custom node config specs */\n [key: string]: unknown;\n };\n\n/**\n * Generate the {@link SayNodeSpec} for the {@link EmberNodeView} with the passed config\n */\nexport function createEmberNodeSpec(config: EmberNodeConfig): SayNodeSpec {\n const {\n name,\n inline,\n group,\n content,\n atom,\n draggable,\n defining,\n recreateUri,\n uriAttributes,\n recreateUriFunction,\n attrs,\n parseDOM,\n toDOM,\n serialize,\n ...passthrough\n } = config;\n return {\n inline,\n atom,\n group,\n content,\n recreateUri,\n uriAttributes,\n recreateUriFunction,\n attrs,\n draggable,\n defining,\n parseDOM: parseDOM ?? [\n {\n tag: inline ? 'span' : 'div',\n getAttrs(node: string | HTMLElement) {\n if (typeof node === 'string') {\n return false;\n }\n if (node.dataset['emberNode'] === name) {\n const result: Record<string, unknown> = {};\n if (attrs) {\n for (const [attributeName, attributeSpec] of Object.entries(\n attrs,\n )) {\n if (attributeSpec.parse) {\n result[attributeName] = attributeSpec.parse(node);\n }\n }\n }\n\n return result;\n }\n return false;\n },\n },\n ],\n toDOM:\n toDOM ??\n ((node: PNode) => {\n const serializedAttributes: Record<string, string> = {\n 'data-ember-node': name,\n };\n if (attrs) {\n for (const [attributeName, attributeSpec] of Object.entries(attrs)) {\n if (attributeSpec.serialize) {\n serializedAttributes[attributeName] =\n attributeSpec.serialize(node);\n }\n }\n }\n return [\n inline ? 'span' : 'div',\n serializedAttributes,\n ...(atom\n ? []\n : [[inline ? 'span' : 'div', { 'data-slot': 'true' }, 0]]),\n ];\n }),\n serialize,\n ...passthrough,\n };\n}\n\nexport type SayNodeViewConstructor = (\n node: PNode,\n view: SayView,\n getPos: () => number | undefined,\n) => NodeView;\n/**\n * Creates a constructor for EmberNodeViews according to the passed config\n * @see {@link EmberNodeView}\n */\nexport function createEmberNodeView(config: EmberNodeConfig) {\n return function (controller: SayController): SayNodeViewConstructor {\n return function (node, view: SayView, getPos) {\n return new EmberNodeView(controller, config, node, view, getPos);\n };\n };\n}\n"],"names":["emberComponent","owner","name","inline","template","props","componentName","uuidv4","register","Component","extend","layout","tagName","component","lookup","node","document","createElement","classList","add","appendTo","EmberNodeView","dom","contentDOM","config","constructor","controller","emberNodeConfig","pNode","view","getPos","componentClass","atom","hbs","undefined","dataset","updateAttribute","attr","value","ignoreHistory","pos","transaction","state","tr","setMeta","setNodeAttribute","dispatch","selectNode","activeEditorState","setSelection","NodeSelection","create","doc","activeEditorView","selected","domClassNames","contentDomClassNames","update","_decorations","innerDecorations","type","set","deselectNode","remove","destroy","stopEvent","event","configStop","includes","target","isInElement","contains","ignoreMutation","mutation","isLeaf","isAtom","createEmberNodeSpec","group","content","draggable","defining","recreateUri","uriAttributes","recreateUriFunction","attrs","parseDOM","toDOM","serialize","passthrough","tag","getAttrs","result","attributeName","attributeSpec","Object","entries","parse","serializedAttributes","createEmberNodeView"],"mappings":"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"}
1
+ {"version":3,"file":"ember-node.js","sources":["../../../src/utils/_private/ember-node.ts"],"sourcesContent":["/**\n * Contains code from https://github.com/ueberdosis/tiptap/blob/d61a621186470ce286e2cecf8206837a1eec7338/packages/core/src/NodeView.ts#L195\n *\n * MIT License\n * Copyright (c) 2023, Tiptap GmbH\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n/**\n\n */\n\nimport { hbs, type TemplateFactory } from 'ember-cli-htmlbars';\nimport type {\n AttributeSpec,\n DOMOutputSpec,\n TagParseRule,\n Node as PNode,\n Attrs,\n} from 'prosemirror-model';\nimport {\n Decoration,\n type EditorView,\n type DecorationSource,\n type NodeView,\n} from 'prosemirror-view';\nimport { v4 as uuidv4 } from 'uuid';\n// eslint-disable-next-line ember/no-classic-components\nimport Component from '@ember/component';\nimport type Owner from '@ember/owner';\nimport type { ComponentLike } from '@glint/template';\nimport SayController from '#root/core/say-controller.ts';\nimport type SayNodeSpec from '#root/core/say-node-spec.ts';\nimport type { NodeSerializer } from '#root/core/say-serializer.ts';\nimport type SayView from '#root/core/say-view.js';\nimport { NodeSelection } from 'prosemirror-state';\n\nexport interface EmberInlineComponent extends Component, EmberNodeArgs {\n appendTo(selector: string | Element): this;\n}\n\nexport interface EmberNodeArgs {\n getPos: () => number | undefined;\n node: PNode;\n /**\n * Util method to help with keeping state in `attrs` of the node.\n * Instead of a tracked property, you'll often use the following logic to keep state inside the node:\n * `get someText() { return this.args.node.attrs.someText; }`\n * `set someText(value) { return this.args.updateAttribute('someText', value); }`\n */\n updateAttribute: (\n attr: string,\n value: unknown,\n ignoreHistory?: boolean,\n ) => void;\n /**\n * Util method which selects the node within the editor\n */\n selectNode: () => void;\n controller: SayController;\n view: SayView | EditorView;\n selected: boolean;\n contentDecorations?: DecorationSource;\n}\n\nfunction emberComponent(\n owner: Owner,\n name: string,\n inline: boolean,\n template: TemplateFactory,\n props: EmberNodeArgs & {\n atom: boolean;\n component: ComponentLike<{ Args: EmberNodeArgs }>;\n contentDOM?: HTMLElement;\n },\n): { node: HTMLElement; component: EmberInlineComponent } {\n // const instance = window.__APPLICATION;\n const componentName = `${name}-${uuidv4()}`;\n owner.register(\n `component:${componentName}`,\n // eslint-disable-next-line ember/no-classic-classes\n Component.extend({\n layout: template,\n tagName: '',\n ...props,\n }),\n );\n const component = owner.lookup(\n `component:${componentName}`,\n ) as EmberInlineComponent;\n const node = document.createElement(inline ? 'span' : 'div');\n node.classList.add('ember-node');\n component.appendTo(node);\n return { node, component };\n}\n\n/**\n * An EmberNode is a node with a custom Node View defined by an ember template.\n * First define your EmberNodeConfig, which should contain the information for:\n *\n * Afterwards use `createEmberNodeSpec(config)` and `createEmberNodeView(config)` to insert them in the schema.\n *\n * Special notes for EmberNode components:\n * - Prosemirror nodes are immutable by design. Any change to a node will create a new node that is loaded in.\n * - A rerender is avoided as much as possible here\n * - An ember component might still rerender because of other reasons (-> not yet known which reasons and if they exist)\n * - This means EmberNode components might lose their state at any time. *Don't save state in components properties*. @tracked properties will most likely not work as wanted.\n * - Keep state in `attrs` of the node.\n * Instead of a tracked property, you'll often use the following logic to keep state inside the node:\n * `get someText() { return this.args.node.attrs.someText; }`\n * `set someText(value) { return this.args.updateAttribute('someText', value); }`\n *\n * - when defining an ember-node using these utility functions, nested contenteditable attributes should be prevented.\n * Ember nodes which can contain editable content should never be `contenteditable: false` as a whole,\n * but only the parts which are `contenteditable: false` should be marked as so.\n * E.g.: It's preferred to write:\n *\n * ```\n * <div>\n * <header contenteditable=\"false\">\n * <p>header</p>\n * </header>\n * <content>\n * {{yield}}\n * </content>\n * </div>\n * ```\n * instead of\n * ```\n * <div contenteditable=\"false\">\n * <header>\n * <p>header</p>\n * </header>\n * <content contenteditable=\"true\">\n * {{yield}}\n * </content>\n * </div>\n * ```\n */\nclass EmberNodeView implements NodeView {\n node: PNode;\n dom: Element;\n contentDOM?: HTMLElement;\n emberComponent: EmberInlineComponent;\n template: TemplateFactory;\n config: EmberNodeConfig;\n\n constructor(\n controller: SayController,\n emberNodeConfig: EmberNodeConfig,\n pNode: PNode,\n view: EditorView,\n getPos: () => number | undefined,\n ) {\n // when a node gets updated, `update()` is called.\n // We set the new node here and pass it to the component to render it.\n this.config = emberNodeConfig;\n const { name, component: componentClass, atom, inline } = emberNodeConfig;\n\n this.template = hbs`<this.component\n @getPos={{this.getPos}}\n @node={{this.node}}\n @updateAttribute={{this.updateAttribute}}\n @controller={{this.controller}}\n @view={{this.view}}\n @selected={{this.selected}}\n @contentDecorations={{this.contentDecorations}}\n @selectNode={{this.selectNode}}\n >\n {{#unless this.atom}}\n {{! @glint-expect-error: not typesafe yet }}\n <EmberNode::Slot @contentDOM={{this.contentDOM}}/>\n {{/unless}}\n </this.component>`;\n this.node = pNode;\n this.contentDOM = !atom\n ? document.createElement(inline ? 'span' : 'div', {})\n : undefined;\n // Note `this.contentDOM` needs an attribute to prevent chromium-based browsers from deleting it when it is empty/only has empty children.\n if (this.contentDOM) {\n this.contentDOM.dataset['emberNodeContent'] = 'true';\n }\n const { node, component } = emberComponent(\n controller.owner,\n name,\n inline,\n this.template,\n {\n getPos,\n node: pNode,\n updateAttribute: (attr, value, ignoreHistory) => {\n const pos = getPos();\n if (pos !== undefined) {\n const transaction = view.state.tr;\n if (ignoreHistory) {\n transaction.setMeta('addToHistory', false);\n }\n transaction.setNodeAttribute(pos, attr, value);\n view.dispatch(transaction);\n }\n },\n selectNode: () => {\n const pos = getPos();\n if (pos !== undefined) {\n const tr = controller.activeEditorState.tr;\n tr.setSelection(\n NodeSelection.create(controller.activeEditorState.doc, pos),\n );\n controller.activeEditorView.dispatch(tr);\n }\n },\n controller,\n contentDOM: this.contentDOM,\n component: componentClass,\n atom,\n view,\n selected: false,\n },\n );\n this.dom = node;\n if (this.config.domClassNames) {\n this.dom.classList.add(...this.config.domClassNames);\n }\n if (this.config.contentDomClassNames && this.contentDOM) {\n this.contentDOM.classList.add(...this.config.contentDomClassNames);\n }\n\n this.emberComponent = component;\n }\n\n update(\n node: PNode,\n _decorations: readonly Decoration[],\n innerDecorations: DecorationSource,\n ) {\n if (node.type !== this.node.type) return false;\n this.node = node;\n this.emberComponent.set('node', node);\n this.emberComponent.set('contentDecorations', innerDecorations);\n return true;\n }\n\n selectNode() {\n this.dom.classList.add('ProseMirror-selectednode');\n this.emberComponent.set('selected', true);\n }\n\n deselectNode() {\n this.dom.classList.remove('ProseMirror-selectednode');\n this.emberComponent.set('selected', false);\n }\n\n destroy() {\n this.emberComponent.destroy();\n }\n\n /**\n * Based on https://github.com/ueberdosis/tiptap/blob/d61a621186470ce286e2cecf8206837a1eec7338/packages/core/src/NodeView.ts#LL99C6-L99C6\n */\n stopEvent(event: Event) {\n if (!this.dom) {\n return false;\n }\n\n if (this.config.stopEvent) {\n const configStop = this.config.stopEvent(event);\n if (configStop !== null) {\n return configStop;\n }\n }\n\n // A dragstart event can come from non-content DOM and be valid, so don't stop it\n // Stopping the event results in the rendered HTML being used for the drag event, rather than\n // the serialized HTML, so breaks drag-drop for many EmberNodes\n if (\n ['dragstart', 'dragend', 'drop', 'dragover', 'dragenter'].includes(\n event.type,\n )\n ) {\n return false;\n }\n\n const target = event.target as HTMLElement;\n const isInElement =\n this.dom.contains(target) && !this.contentDOM?.contains(target);\n\n return isInElement;\n }\n\n /**\n * Taken from https://github.com/ueberdosis/tiptap/blob/d61a621186470ce286e2cecf8206837a1eec7338/packages/core/src/NodeView.ts#L195\n */\n ignoreMutation(\n mutation: MutationRecord | { type: 'selection'; target: Element },\n ) {\n if (!this.dom || !this.contentDOM) {\n return true;\n }\n if (this.config.ignoreMutation) {\n return this.config.ignoreMutation(mutation);\n }\n\n // a leaf/atom node is like a black box for ProseMirror\n // and should be fully handled by the node view\n if (this.node.isLeaf || this.node.isAtom) {\n return true;\n }\n\n // ProseMirror should handle any selections\n if (mutation.type === 'selection') {\n return false;\n }\n\n // we will allow mutation contentDOM with attributes\n // so we can for example adding classes within our node view\n if (this.contentDOM === mutation.target && mutation.type === 'attributes') {\n return true;\n }\n\n // ProseMirror should handle any changes within contentDOM\n if (this.contentDOM.contains(mutation.target)) {\n return false;\n }\n\n return true;\n }\n}\n\ninterface AtomConfig {\n /** Is an atom if is not a leaf node */\n atom: true;\n /**\n * ProseMissor content expression\n * @see {@link https://prosemirror.net/docs/guide/#schema.content_expressions|ProseMirror schema guide}\n */\n content?: string;\n}\ninterface NonAtomConfig {\n /** Is an atom if is not a leaf node */\n atom: false;\n /**\n * ProseMissor content expression\n * @see {@link https://prosemirror.net/docs/guide/#schema.content_expressions|ProseMirror schema guide}\n */\n content: string;\n}\n\n// Maybe this should be split so that a different one exists for each of the 2 functions which takes\n// it as an argument\nexport type EmberNodeConfig = {\n name: string;\n /** ember component to render as a Node View */\n component: ComponentLike<{ Args: EmberNodeArgs }>;\n inline: boolean;\n /** ProseMirror 'group' property for the created node */\n group: string;\n draggable?: boolean;\n /** @see {@link https://prosemirror.net/docs/ref/#model.NodeSpec.defining} */\n defining?: boolean;\n /**\n * @deprecated\n */\n recreateUri?: boolean;\n /**\n * @deprecated\n */\n uriAttributes?: [string];\n /** Generate a new URI when pasting the node? */\n recreateUriFunction?: (attrs: Attrs) => Attrs;\n /** A map of attributes to assign to this node */\n attrs?: {\n [name: string]: AttributeSpec & {\n editable?: boolean;\n serialize?: (node: PNode) => string;\n parse?: (element: HTMLElement) => unknown;\n };\n };\n /** @see {@link https://prosemirror.net/docs/ref/#model.NodeSpec.parseDOM} */\n parseDOM?: readonly TagParseRule[];\n /** @see {@link https://prosemirror.net/docs/ref/#model.NodeSpec.toDOM} */\n toDOM?: (node: PNode) => DOMOutputSpec;\n /**\n * Allows creating a serialized version based on the node itself\n * @see {@link SayNodeSpec}\n */\n serialize?: NodeSerializer;\n /**\n * Prevents the editor view from handling events which are inside the ember-node but not inside it's editable content.\n * By default this will stop events which occur inside the ember-node but not inside it's content.\n * Returning a boolean will stop or not stop an event, returning null will hand over to the default logic.\n * Only override the default logic if you know what you are doing.\n * @param event The event to check\n */\n stopEvent?: (event: Event) => boolean | null;\n domClassNames?: string[];\n contentDomClassNames?: string[];\n /**\n * Determines whether a DOM mutation should be ignored by prosemirror.\n * Use this to avoid rerendering a component for every change.\n * DOM mutations occuring inside the ember-node which are not inside it's editable content are ignored.\n * Selections are always handled by prosemirror.\n * Already has a default implementation. Only override if you know what you are doing.\n * @param mutation\n * @returns whether to ignore the mutation\n */\n ignoreMutation?: (\n mutation: MutationRecord | { type: 'selection'; target: Element },\n ) => boolean;\n /** Do we need to workaround cursor problems on Firefox */\n needsFFKludge?: boolean;\n /** Do we need to workaround cursor problems on Chrome */\n needsChromeCursorFix?: boolean;\n} & (AtomConfig | NonAtomConfig) & {\n /** This is so we can use custom node config specs */\n [key: string]: unknown;\n };\n\n/**\n * Generate the {@link SayNodeSpec} for the {@link EmberNodeView} with the passed config\n */\nexport function createEmberNodeSpec(config: EmberNodeConfig): SayNodeSpec {\n const {\n name,\n inline,\n group,\n content,\n atom,\n draggable,\n defining,\n recreateUri,\n uriAttributes,\n recreateUriFunction,\n attrs,\n parseDOM,\n toDOM,\n serialize,\n ...passthrough\n } = config;\n return {\n inline,\n atom,\n group,\n content,\n recreateUri,\n uriAttributes,\n recreateUriFunction,\n attrs,\n draggable,\n defining,\n parseDOM: parseDOM ?? [\n {\n tag: inline ? 'span' : 'div',\n getAttrs(node: string | HTMLElement) {\n if (typeof node === 'string') {\n return false;\n }\n if (node.dataset['emberNode'] === name) {\n const result: Record<string, unknown> = {};\n if (attrs) {\n for (const [attributeName, attributeSpec] of Object.entries(\n attrs,\n )) {\n if (attributeSpec.parse) {\n result[attributeName] = attributeSpec.parse(node);\n }\n }\n }\n\n return result;\n }\n return false;\n },\n },\n ],\n toDOM:\n toDOM ??\n ((node: PNode) => {\n const serializedAttributes: Record<string, string> = {\n 'data-ember-node': name,\n };\n if (attrs) {\n for (const [attributeName, attributeSpec] of Object.entries(attrs)) {\n if (attributeSpec.serialize) {\n serializedAttributes[attributeName] =\n attributeSpec.serialize(node);\n }\n }\n }\n return [\n inline ? 'span' : 'div',\n serializedAttributes,\n ...(atom\n ? []\n : [[inline ? 'span' : 'div', { 'data-slot': 'true' }, 0]]),\n ];\n }),\n serialize,\n ...passthrough,\n };\n}\n\nexport type SayNodeViewConstructor = (\n node: PNode,\n view: EditorView,\n getPos: () => number | undefined,\n) => NodeView;\n/**\n * Creates a constructor for EmberNodeViews according to the passed config\n * @see {@link EmberNodeView}\n */\nexport function createEmberNodeView(config: EmberNodeConfig) {\n return function (controller: SayController): SayNodeViewConstructor {\n return function (node, view: EditorView, getPos) {\n return new EmberNodeView(controller, config, node, view, getPos);\n };\n };\n}\n"],"names":["emberComponent","owner","name","inline","template","props","componentName","uuidv4","register","Component","extend","layout","tagName","component","lookup","node","document","createElement","classList","add","appendTo","EmberNodeView","dom","contentDOM","config","constructor","controller","emberNodeConfig","pNode","view","getPos","componentClass","atom","hbs","undefined","dataset","updateAttribute","attr","value","ignoreHistory","pos","transaction","state","tr","setMeta","setNodeAttribute","dispatch","selectNode","activeEditorState","setSelection","NodeSelection","create","doc","activeEditorView","selected","domClassNames","contentDomClassNames","update","_decorations","innerDecorations","type","set","deselectNode","remove","destroy","stopEvent","event","configStop","includes","target","isInElement","contains","ignoreMutation","mutation","isLeaf","isAtom","createEmberNodeSpec","group","content","draggable","defining","recreateUri","uriAttributes","recreateUriFunction","attrs","parseDOM","toDOM","serialize","passthrough","tag","getAttrs","result","attributeName","attributeSpec","Object","entries","parse","serializedAttributes","createEmberNodeView"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lblod/ember-rdfa-editor",
3
- "version": "13.3.0",
3
+ "version": "13.3.1",
4
4
  "description": "Ember addon wrapping an RDFa editor with a public API",
5
5
  "keywords": [
6
6
  "ember-addon"
@@ -259,11 +259,12 @@
259
259
  "relative-to-absolute-iri": "^1.0.7",
260
260
  "stream-browserify": "^3.0.0",
261
261
  "tracked-toolbox": "^2.2.0",
262
+ "typedoc": "^0.28.17",
262
263
  "uuid": "^9.0.1",
264
+ "validator": "^13.15.26",
263
265
  "yup": "^1.7.1"
264
266
  },
265
267
  "devDependencies": {
266
- "prosemirror-history": "./vendored-deps/prosemirror-history-1.5.0.tgz",
267
268
  "@appuniversum/ember-appuniversum": "^3.15.1",
268
269
  "@babel/core": "^7.28.6",
269
270
  "@babel/eslint-parser": "^7.28.6",
@@ -284,6 +285,7 @@
284
285
  "@types/debug": "^4.1.12",
285
286
  "@types/js-beautify": "^1.14.3",
286
287
  "@types/uuid": "^9.0.8",
288
+ "@types/validator": "^13.15.10",
287
289
  "autoprefixer": "^10.4.23",
288
290
  "babel-plugin-ember-template-compilation": "^2.4.1",
289
291
  "concurrently": "^9.2.1",
@@ -306,6 +308,7 @@
306
308
  "postcss": "^8.5.6",
307
309
  "prettier": "^3.8.0",
308
310
  "prettier-plugin-ember-template-tag": "^2.1.2",
311
+ "prosemirror-history": "file:./vendored-deps/prosemirror-history-1.5.0.tgz",
309
312
  "prosemirror-test-builder": "^1.1.1",
310
313
  "rollup": "^4.52.2",
311
314
  "rollup-plugin-copy": "^3.5.0",
@@ -435,6 +438,11 @@
435
438
  "./modifiers/leave-with-arrow-keys.js": "./dist/_app_/modifiers/leave-with-arrow-keys.js"
436
439
  }
437
440
  },
441
+ "typedocOptions": {
442
+ "tsconfig": "tsconfig.typedoc.json",
443
+ "out": "docs",
444
+ "readme": "./README.md"
445
+ },
438
446
  "scripts": {
439
447
  "build": "rollup --config",
440
448
  "format": "prettier . --cache --write",
@@ -447,6 +455,7 @@
447
455
  "lint:js:fix": "eslint . --fix",
448
456
  "lint:types": "ember-tsc --noEmit",
449
457
  "start": "rollup --config --watch",
450
- "test": "echo 'A v2 addon does not have tests, run tests in test-app'"
458
+ "test": "echo 'A v2 addon does not have tests, run tests in test-app'",
459
+ "doc:generate": "pnpm typedoc"
451
460
  }
452
461
  }