@portabletext/editor 1.18.1 → 1.18.2

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.
@@ -348,6 +348,25 @@ function createEmojiPickerMachine() {
348
348
  }
349
349
  });
350
350
  }
351
+ function looksLikeUrl(text) {
352
+ let looksLikeUrl2 = !1;
353
+ try {
354
+ try {
355
+ const url = new URL(text);
356
+ if (!sensibleProtocols.includes(url.protocol))
357
+ return !1;
358
+ looksLikeUrl2 = url.hostname.length > 0 ? url.hostname.includes(".") : !0;
359
+ } catch {
360
+ const url = new URL(`https://${text}`);
361
+ if (!sensibleProtocols.includes(url.protocol))
362
+ return !1;
363
+ looksLikeUrl2 = url.hostname.length > 0 ? url.hostname.includes(".") : !0;
364
+ }
365
+ } catch {
366
+ }
367
+ return looksLikeUrl2;
368
+ }
369
+ const sensibleProtocols = ["http:", "https:", "mailto:", "tel:"];
351
370
  function createLinkBehaviors(config) {
352
371
  const pasteLinkOnSelection = behavior_core.defineBehavior({
353
372
  on: "paste",
@@ -405,14 +424,6 @@ function createLinkBehaviors(config) {
405
424
  });
406
425
  return [pasteLinkOnSelection, pasteLinkAtCaret];
407
426
  }
408
- function looksLikeUrl(text) {
409
- let looksLikeUrl2 = !1;
410
- try {
411
- new URL(text), looksLikeUrl2 = !0;
412
- } catch {
413
- }
414
- return looksLikeUrl2;
415
- }
416
427
  function createMarkdownBehaviors(config) {
417
428
  const automaticBlockquoteOnSpace = behavior_core.defineBehavior({
418
429
  on: "insert.text",
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../../src/behaviors/behavior.code-editor.ts","../../src/behaviors/behavior.emoji-picker.ts","../../src/behaviors/behavior.links.ts","../../src/behaviors/behavior.markdown.ts"],"sourcesContent":["import * as selectors from '../selectors'\nimport {isHotkey} from '../utils/is-hotkey'\nimport {defineBehavior} from './behavior.types'\n\n/**\n * @beta\n */\nexport type CodeEditorBehaviorsConfig = {\n moveBlockUpShortcut: string\n moveBlockDownShortcut: string\n}\n\n/**\n * @beta\n */\nexport function createCodeEditorBehaviors(config: CodeEditorBehaviorsConfig) {\n return [\n defineBehavior({\n on: 'key.down',\n guard: ({context, event}) => {\n const isMoveUpShortcut = isHotkey(\n config.moveBlockUpShortcut,\n event.keyboardEvent,\n )\n const firstBlock = selectors.getFirstBlock({context})\n const selectedBlocks = selectors.getSelectedBlocks({context})\n const blocksAbove =\n firstBlock?.node._key !== selectedBlocks[0]?.node._key\n\n if (!isMoveUpShortcut || !blocksAbove) {\n return false\n }\n\n return {paths: selectedBlocks.map((block) => block.path)}\n },\n actions: [\n (_, {paths}) =>\n paths.map((at) => ({\n type: 'move.block up',\n at,\n })),\n ],\n }),\n defineBehavior({\n on: 'key.down',\n guard: ({context, event}) => {\n const isMoveDownShortcut = isHotkey(\n config.moveBlockDownShortcut,\n event.keyboardEvent,\n )\n const lastBlock = selectors.getLastBlock({context})\n const selectedBlocks = selectors.getSelectedBlocks({context})\n const blocksBelow =\n lastBlock?.node._key !==\n selectedBlocks[selectedBlocks.length - 1]?.node._key\n\n if (!isMoveDownShortcut || !blocksBelow) {\n return false\n }\n\n return {paths: selectedBlocks.map((block) => block.path).reverse()}\n },\n actions: [\n (_, {paths}) =>\n paths.map((at) => ({\n type: 'move.block down',\n at,\n })),\n ],\n }),\n ]\n}\n","import {assertEvent, assign, createActor, setup} from 'xstate'\nimport * as selectors from '../selectors'\nimport {isHotkey} from '../utils/is-hotkey'\nimport {defineBehavior} from './behavior.types'\n\nconst emojiCharRegEx = /^[a-zA-Z-_0-9]{1}$/\nconst incompleteEmojiRegEx = /:([a-zA-Z-_0-9]+)$/\nconst emojiRegEx = /:([a-zA-Z-_0-9]+):$/\n\n/**\n * @beta\n */\nexport type EmojiPickerBehaviorsConfig<TEmojiMatch> = {\n /**\n * Match emojis by keyword.\n */\n matchEmojis: ({keyword}: {keyword: string}) => Array<TEmojiMatch>\n onMatchesChanged: ({matches}: {matches: Array<TEmojiMatch>}) => void\n onSelectedIndexChanged: ({selectedIndex}: {selectedIndex: number}) => void\n /**\n * Parse an emoji match to a string that will be inserted into the editor.\n */\n parseMatch: ({match}: {match: TEmojiMatch}) => string | undefined\n}\n\n/**\n * @beta\n */\nexport function createEmojiPickerBehaviors<TEmojiMatch>(\n config: EmojiPickerBehaviorsConfig<TEmojiMatch>,\n) {\n const emojiPickerActor = createActor(createEmojiPickerMachine<TEmojiMatch>())\n emojiPickerActor.start()\n emojiPickerActor.subscribe((state) => {\n config.onMatchesChanged({matches: state.context.matches})\n config.onSelectedIndexChanged({selectedIndex: state.context.selectedIndex})\n })\n\n return [\n defineBehavior({\n on: 'insert.text',\n guard: ({context, event}) => {\n if (event.text === ':') {\n return false\n }\n\n const isEmojiChar = emojiCharRegEx.test(event.text)\n\n if (!isEmojiChar) {\n return {emojis: []}\n }\n\n const focusBlock = selectors.getFocusTextBlock({context})\n const textBefore = selectors.getBlockTextBefore({context})\n const emojiKeyword = `${textBefore}${event.text}`.match(\n incompleteEmojiRegEx,\n )?.[1]\n\n if (!focusBlock || emojiKeyword === undefined) {\n return {emojis: []}\n }\n\n const emojis = config.matchEmojis({keyword: emojiKeyword})\n\n return {emojis}\n },\n actions: [\n (_, params) => [\n {\n type: 'effect',\n effect: () => {\n emojiPickerActor.send({\n type: 'emojis found',\n matches: params.emojis,\n })\n },\n },\n ],\n ],\n }),\n defineBehavior({\n on: 'insert.text',\n guard: ({context, event}) => {\n const isColon = event.text === ':'\n\n if (!isColon) {\n return false\n }\n\n const matches = emojiPickerActor.getSnapshot().context.matches\n const selectedIndex =\n emojiPickerActor.getSnapshot().context.selectedIndex\n const emoji = matches[selectedIndex]\n ? config.parseMatch({match: matches[selectedIndex]})\n : undefined\n\n const focusBlock = selectors.getFocusTextBlock({context})\n const textBefore = selectors.getBlockTextBefore({context})\n const emojiKeyword = `${textBefore}:`.match(emojiRegEx)?.[1]\n\n if (!focusBlock || emojiKeyword === undefined) {\n return false\n }\n\n const emojiStringLength = emojiKeyword.length + 2\n\n if (emoji) {\n return {\n focusBlock,\n emoji,\n emojiStringLength,\n textBeforeLength: textBefore.length + 1,\n }\n }\n\n return false\n },\n actions: [\n () => [\n {\n type: 'insert.text',\n text: ':',\n },\n ],\n (_, params) => [\n {\n type: 'effect',\n effect: () => {\n emojiPickerActor.send({type: 'select'})\n },\n },\n {\n type: 'delete.text',\n anchor: {\n path: params.focusBlock.path,\n offset: params.textBeforeLength - params.emojiStringLength,\n },\n focus: {\n path: params.focusBlock.path,\n offset: params.textBeforeLength,\n },\n },\n {\n type: 'insert.text',\n text: params.emoji,\n },\n ],\n ],\n }),\n defineBehavior({\n on: 'key.down',\n guard: ({context, event}) => {\n const matches = emojiPickerActor.getSnapshot().context.matches\n\n if (matches.length === 0) {\n return false\n }\n\n const isShift = isHotkey('Shift', event.keyboardEvent)\n const isColon = event.keyboardEvent.key === ':'\n const isEmojiChar = emojiCharRegEx.test(event.keyboardEvent.key)\n\n if (isShift || isColon || isEmojiChar) {\n return false\n }\n\n const isArrowDown = isHotkey('ArrowDown', event.keyboardEvent)\n const isArrowUp = isHotkey('ArrowUp', event.keyboardEvent)\n const isEnter = isHotkey('Enter', event.keyboardEvent)\n const isTab = isHotkey('Tab', event.keyboardEvent)\n\n if (isEnter || isTab) {\n const selectedIndex =\n emojiPickerActor.getSnapshot().context.selectedIndex\n\n const emoji = matches[selectedIndex]\n ? config.parseMatch({match: matches[selectedIndex]})\n : undefined\n\n if (!emoji) {\n return false\n }\n\n const focusBlock = selectors.getFocusTextBlock({context})\n const textBefore = selectors.getBlockTextBefore({context})\n const emojiKeyword = textBefore.match(incompleteEmojiRegEx)?.[1]\n\n if (!focusBlock || emojiKeyword === undefined) {\n return false\n }\n\n const emojiStringLength = emojiKeyword.length + 1\n\n if (emoji) {\n return {\n action: 'select' as const,\n focusBlock,\n emoji,\n emojiStringLength,\n textBeforeLength: textBefore.length,\n }\n }\n\n return false\n }\n\n if (isArrowDown && matches.length > 0) {\n return {action: 'navigate down' as const}\n }\n\n if (isArrowUp && matches.length > 0) {\n return {action: 'navigate up' as const}\n }\n\n return {action: 'reset' as const}\n },\n actions: [\n (_, params) => {\n if (params.action === 'select') {\n return [\n {\n type: 'effect',\n effect: () => {\n emojiPickerActor.send({type: 'select'})\n },\n },\n {\n type: 'delete.text',\n anchor: {\n path: params.focusBlock.path,\n offset: params.textBeforeLength - params.emojiStringLength,\n },\n focus: {\n path: params.focusBlock.path,\n offset: params.textBeforeLength,\n },\n },\n {\n type: 'insert.text',\n text: params.emoji,\n },\n ]\n }\n\n if (params.action === 'navigate up') {\n return [\n // If we are navigating then we want to hijack the key event and\n // turn it into a noop.\n {\n type: 'noop',\n },\n {\n type: 'effect',\n effect: () => {\n emojiPickerActor.send({type: 'navigate up'})\n },\n },\n ]\n }\n\n if (params.action === 'navigate down') {\n return [\n // If we are navigating then we want to hijack the key event and\n // turn it into a noop.\n {\n type: 'noop',\n },\n {\n type: 'effect',\n effect: () => {\n emojiPickerActor.send({type: 'navigate down'})\n },\n },\n ]\n }\n\n return [\n {\n type: 'effect',\n effect: () => {\n emojiPickerActor.send({type: 'reset'})\n },\n },\n ]\n },\n ],\n }),\n defineBehavior({\n on: 'delete.backward',\n guard: ({context, event}) => {\n if (event.unit !== 'character') {\n return false\n }\n\n const matches = emojiPickerActor.getSnapshot().context.matches\n\n if (matches.length === 0) {\n return false\n }\n\n const focusBlock = selectors.getFocusTextBlock({context})\n const textBefore = selectors.getBlockTextBefore({context})\n const emojiKeyword = textBefore\n .slice(0, textBefore.length - 1)\n .match(incompleteEmojiRegEx)?.[1]\n\n if (!focusBlock || emojiKeyword === undefined) {\n return {emojis: []}\n }\n\n const emojis = config.matchEmojis({keyword: emojiKeyword})\n\n return {emojis}\n },\n actions: [\n (_, params) => [\n {\n type: 'effect',\n effect: () => {\n emojiPickerActor.send({\n type: 'emojis found',\n matches: params.emojis,\n })\n },\n },\n ],\n ],\n }),\n ]\n}\n\nfunction createEmojiPickerMachine<TEmojiSearchResult>() {\n return setup({\n types: {\n context: {} as {\n matches: Array<TEmojiSearchResult>\n selectedIndex: number\n },\n events: {} as\n | {\n type: 'emojis found'\n matches: Array<TEmojiSearchResult>\n }\n | {\n type: 'navigate down' | 'navigate up' | 'select' | 'reset'\n },\n },\n actions: {\n 'assign matches': assign({\n matches: ({event}) => {\n assertEvent(event, 'emojis found')\n return event.matches\n },\n }),\n 'reset matches': assign({\n matches: [],\n }),\n 'reset selected index': assign({\n selectedIndex: 0,\n }),\n 'increment selected index': assign({\n selectedIndex: ({context}) => {\n if (context.selectedIndex === context.matches.length - 1) {\n return 0\n }\n return context.selectedIndex + 1\n },\n }),\n 'decrement selected index': assign({\n selectedIndex: ({context}) => {\n if (context.selectedIndex === 0) {\n return context.matches.length - 1\n }\n return context.selectedIndex - 1\n },\n }),\n },\n guards: {\n 'no matches': ({context}) => context.matches.length === 0,\n },\n }).createMachine({\n id: 'emoji picker',\n context: {\n matches: [],\n selectedIndex: 0,\n },\n initial: 'idle',\n states: {\n 'idle': {\n on: {\n 'emojis found': {\n actions: 'assign matches',\n target: 'showing matches',\n },\n },\n },\n 'showing matches': {\n always: {\n guard: 'no matches',\n target: 'idle',\n },\n exit: ['reset selected index'],\n on: {\n 'emojis found': {\n actions: 'assign matches',\n },\n 'navigate down': {\n actions: 'increment selected index',\n },\n 'navigate up': {\n actions: 'decrement selected index',\n },\n 'reset': {\n target: 'idle',\n actions: ['reset selected index', 'reset matches'],\n },\n 'select': {\n target: 'idle',\n actions: ['reset selected index', 'reset matches'],\n },\n },\n },\n },\n })\n}\n","import type {EditorSchema} from '../editor/define-schema'\nimport * as selectors from '../selectors'\nimport {defineBehavior} from './behavior.types'\n\n/**\n * @beta\n */\nexport type LinkBehaviorsConfig = {\n linkAnnotation?: (context: {\n schema: EditorSchema\n url: string\n }) => {name: string; value: {[prop: string]: unknown}} | undefined\n}\n\n/**\n * @beta\n */\nexport function createLinkBehaviors(config: LinkBehaviorsConfig) {\n const pasteLinkOnSelection = defineBehavior({\n on: 'paste',\n guard: ({context, event}) => {\n const selectionCollapsed = selectors.isSelectionCollapsed({context})\n const text = event.data.getData('text/plain')\n const url = looksLikeUrl(text) ? text : undefined\n const annotation =\n url !== undefined\n ? config.linkAnnotation?.({url, schema: context.schema})\n : undefined\n\n if (annotation && !selectionCollapsed) {\n return {annotation}\n }\n\n return false\n },\n actions: [\n (_, {annotation}) => [\n {\n type: 'annotation.add',\n annotation,\n },\n ],\n ],\n })\n const pasteLinkAtCaret = defineBehavior({\n on: 'paste',\n guard: ({context, event}) => {\n const focusSpan = selectors.getFocusSpan({context})\n const selectionCollapsed = selectors.isSelectionCollapsed({context})\n\n if (!focusSpan || !selectionCollapsed) {\n return false\n }\n\n const text = event.data.getData('text/plain')\n const url = looksLikeUrl(text) ? text : undefined\n const annotation =\n url !== undefined\n ? config.linkAnnotation?.({url, schema: context.schema})\n : undefined\n\n if (url && annotation && selectionCollapsed) {\n return {focusSpan, annotation, url}\n }\n\n return false\n },\n actions: [\n (_, {annotation, url}) => [\n {\n type: 'insert.span',\n text: url,\n annotations: [annotation],\n },\n ],\n ],\n })\n\n const linkBehaviors = [pasteLinkOnSelection, pasteLinkAtCaret]\n\n return linkBehaviors\n}\n\nfunction looksLikeUrl(text: string) {\n let looksLikeUrl = false\n try {\n new URL(text)\n looksLikeUrl = true\n } catch {}\n return looksLikeUrl\n}\n","import {isPortableTextTextBlock} from '@sanity/types'\nimport type {EditorSchema} from '../editor/define-schema'\nimport {getTextBlockText} from '../editor/utils/utils'\nimport {spanSelectionPointToBlockOffset} from '../editor/utils/utils.block-offset'\nimport * as selectors from '../selectors'\nimport {getBlockTextBefore} from '../selectors/selector.get-text-before'\nimport {defineBehavior} from './behavior.types'\n\n/**\n * @beta\n */\nexport type MarkdownBehaviorsConfig = {\n horizontalRuleObject?: (context: {\n schema: EditorSchema\n }) => {name: string; value?: {[prop: string]: unknown}} | undefined\n defaultStyle?: (context: {schema: EditorSchema}) => string | undefined\n headingStyle?: (context: {\n schema: EditorSchema\n level: number\n }) => string | undefined\n blockquoteStyle?: (context: {schema: EditorSchema}) => string | undefined\n unorderedListStyle?: (context: {schema: EditorSchema}) => string | undefined\n orderedListStyle?: (context: {schema: EditorSchema}) => string | undefined\n}\n\n/**\n * @beta\n */\nexport function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {\n const automaticBlockquoteOnSpace = defineBehavior({\n on: 'insert.text',\n guard: ({context, event}) => {\n const isSpace = event.text === ' '\n\n if (!isSpace) {\n return false\n }\n\n const selectionCollapsed = selectors.isSelectionCollapsed({context})\n const focusTextBlock = selectors.getFocusTextBlock({context})\n const focusSpan = selectors.getFocusSpan({context})\n\n if (!selectionCollapsed || !focusTextBlock || !focusSpan) {\n return false\n }\n\n const blockOffset = spanSelectionPointToBlockOffset({\n value: context.value,\n selectionPoint: {\n path: [\n {_key: focusTextBlock.node._key},\n 'children',\n {_key: focusSpan.node._key},\n ],\n offset: context.selection?.focus.offset ?? 0,\n },\n })\n\n if (!blockOffset) {\n return false\n }\n\n const blockText = getTextBlockText(focusTextBlock.node)\n const caretAtTheEndOfQuote = blockOffset.offset === 1\n const looksLikeMarkdownQuote = /^>/.test(blockText)\n const blockquoteStyle = config.blockquoteStyle?.(context)\n\n if (\n caretAtTheEndOfQuote &&\n looksLikeMarkdownQuote &&\n blockquoteStyle !== undefined\n ) {\n return {focusTextBlock, style: blockquoteStyle}\n }\n\n return false\n },\n actions: [\n () => [\n {\n type: 'insert.text',\n text: ' ',\n },\n ],\n (_, {focusTextBlock, style}) => [\n {\n type: 'text block.unset',\n props: ['listItem', 'level'],\n at: focusTextBlock.path,\n },\n {\n type: 'text block.set',\n style,\n at: focusTextBlock.path,\n },\n {\n type: 'delete.text',\n anchor: {\n path: focusTextBlock.path,\n offset: 0,\n },\n focus: {\n path: focusTextBlock.path,\n offset: 2,\n },\n },\n ],\n ],\n })\n const automaticHr = defineBehavior({\n on: 'insert.text',\n guard: ({context, event}) => {\n const hrCharacter =\n event.text === '-'\n ? '-'\n : event.text === '*'\n ? '*'\n : event.text === '_'\n ? '_'\n : undefined\n\n if (hrCharacter === undefined) {\n return false\n }\n\n const hrObject = config.horizontalRuleObject?.(context)\n const focusBlock = selectors.getFocusTextBlock({context})\n const selectionCollapsed = selectors.isSelectionCollapsed({context})\n\n if (!hrObject || !focusBlock || !selectionCollapsed) {\n return false\n }\n\n const textBefore = getBlockTextBefore({context})\n const hrBlockOffsets = {\n anchor: {\n path: focusBlock.path,\n offset: 0,\n },\n focus: {\n path: focusBlock.path,\n offset: 3,\n },\n }\n\n if (textBefore === `${hrCharacter}${hrCharacter}`) {\n return {hrObject, focusBlock, hrCharacter, hrBlockOffsets}\n }\n\n return false\n },\n actions: [\n (_, {hrCharacter}) => [\n {\n type: 'insert.text',\n text: hrCharacter,\n },\n ],\n (_, {hrObject, hrBlockOffsets}) => [\n {\n type: 'insert.block object',\n placement: 'before',\n blockObject: hrObject,\n },\n {\n type: 'delete.text',\n ...hrBlockOffsets,\n },\n ],\n ],\n })\n const automaticHrOnPaste = defineBehavior({\n on: 'paste',\n guard: ({context, event}) => {\n const text = event.data.getData('text/plain')\n const hrRegExp = /^(---)$|(___)$|(\\*\\*\\*)$/gm\n const hrCharacters = text.match(hrRegExp)?.[0]\n const hrObject = config.horizontalRuleObject?.(context)\n const focusBlock = selectors.getFocusBlock({context})\n\n if (!hrCharacters || !hrObject || !focusBlock) {\n return false\n }\n\n return {hrCharacters, hrObject, focusBlock}\n },\n actions: [\n (_, {hrCharacters}) => [\n {\n type: 'insert.text',\n text: hrCharacters,\n },\n ],\n (_, {hrObject, focusBlock}) =>\n isPortableTextTextBlock(focusBlock.node)\n ? [\n {\n type: 'insert.text block',\n textBlock: {children: focusBlock.node.children},\n placement: 'after',\n },\n {\n type: 'insert.block object',\n blockObject: hrObject,\n placement: 'after',\n },\n {type: 'delete.block', blockPath: focusBlock.path},\n ]\n : [\n {\n type: 'insert.block object',\n blockObject: hrObject,\n placement: 'after',\n },\n ],\n ],\n })\n const automaticHeadingOnSpace = defineBehavior({\n on: 'insert.text',\n guard: ({context, event}) => {\n const isSpace = event.text === ' '\n\n if (!isSpace) {\n return false\n }\n\n const selectionCollapsed = selectors.isSelectionCollapsed({context})\n const focusTextBlock = selectors.getFocusTextBlock({context})\n const focusSpan = selectors.getFocusSpan({context})\n\n if (!selectionCollapsed || !focusTextBlock || !focusSpan) {\n return false\n }\n\n const blockOffset = spanSelectionPointToBlockOffset({\n value: context.value,\n selectionPoint: {\n path: [\n {_key: focusTextBlock.node._key},\n 'children',\n {_key: focusSpan.node._key},\n ],\n offset: context.selection?.focus.offset ?? 0,\n },\n })\n\n if (!blockOffset) {\n return false\n }\n\n const blockText = getTextBlockText(focusTextBlock.node)\n const markdownHeadingSearch = /^#+/.exec(blockText)\n const level = markdownHeadingSearch\n ? markdownHeadingSearch[0].length\n : undefined\n const caretAtTheEndOfHeading = blockOffset.offset === level\n\n if (!caretAtTheEndOfHeading) {\n return false\n }\n\n const style =\n level !== undefined\n ? config.headingStyle?.({schema: context.schema, level})\n : undefined\n\n if (level !== undefined && style !== undefined) {\n return {\n focusTextBlock,\n style: style,\n level,\n }\n }\n\n return false\n },\n actions: [\n ({event}) => [event],\n (_, {focusTextBlock, style, level}) => [\n {\n type: 'text block.unset',\n props: ['listItem', 'level'],\n at: focusTextBlock.path,\n },\n {\n type: 'text block.set',\n style,\n at: focusTextBlock.path,\n },\n {\n type: 'delete.text',\n anchor: {\n path: focusTextBlock.path,\n offset: 0,\n },\n focus: {\n path: focusTextBlock.path,\n offset: level + 1,\n },\n },\n ],\n ],\n })\n const clearStyleOnBackspace = defineBehavior({\n on: 'delete.backward',\n guard: ({context}) => {\n const selectionCollapsed = selectors.isSelectionCollapsed({context})\n const focusTextBlock = selectors.getFocusTextBlock({context})\n const focusSpan = selectors.getFocusSpan({context})\n\n if (!selectionCollapsed || !focusTextBlock || !focusSpan) {\n return false\n }\n\n const atTheBeginningOfBLock =\n focusTextBlock.node.children[0]._key === focusSpan.node._key &&\n context.selection?.focus.offset === 0\n\n const defaultStyle = config.defaultStyle?.(context)\n\n if (\n atTheBeginningOfBLock &&\n defaultStyle &&\n focusTextBlock.node.style !== defaultStyle\n ) {\n return {defaultStyle, focusTextBlock}\n }\n\n return false\n },\n actions: [\n (_, {defaultStyle, focusTextBlock}) => [\n {\n type: 'text block.set',\n style: defaultStyle,\n at: focusTextBlock.path,\n },\n ],\n ],\n })\n const automaticListOnSpace = defineBehavior({\n on: 'insert.text',\n guard: ({context, event}) => {\n const isSpace = event.text === ' '\n\n if (!isSpace) {\n return false\n }\n\n const selectionCollapsed = selectors.isSelectionCollapsed({context})\n const focusTextBlock = selectors.getFocusTextBlock({context})\n const focusSpan = selectors.getFocusSpan({context})\n\n if (!selectionCollapsed || !focusTextBlock || !focusSpan) {\n return false\n }\n\n const blockOffset = spanSelectionPointToBlockOffset({\n value: context.value,\n selectionPoint: {\n path: [\n {_key: focusTextBlock.node._key},\n 'children',\n {_key: focusSpan.node._key},\n ],\n offset: context.selection?.focus.offset ?? 0,\n },\n })\n\n if (!blockOffset) {\n return false\n }\n\n const blockText = getTextBlockText(focusTextBlock.node)\n const defaultStyle = config.defaultStyle?.(context)\n const looksLikeUnorderedList = /^(-|\\*)/.test(blockText)\n const unorderedListStyle = config.unorderedListStyle?.(context)\n const caretAtTheEndOfUnorderedList = blockOffset.offset === 1\n\n if (\n defaultStyle &&\n caretAtTheEndOfUnorderedList &&\n looksLikeUnorderedList &&\n unorderedListStyle !== undefined\n ) {\n return {\n focusTextBlock,\n listItem: unorderedListStyle,\n listItemLength: 1,\n style: defaultStyle,\n }\n }\n\n const looksLikeOrderedList = /^1\\./.test(blockText)\n const orderedListStyle = config.orderedListStyle?.(context)\n const caretAtTheEndOfOrderedList = blockOffset.offset === 2\n\n if (\n defaultStyle &&\n caretAtTheEndOfOrderedList &&\n looksLikeOrderedList &&\n orderedListStyle !== undefined\n ) {\n return {\n focusTextBlock,\n listItem: orderedListStyle,\n listItemLength: 2,\n style: defaultStyle,\n }\n }\n\n return false\n },\n actions: [\n ({event}) => [event],\n (_, {focusTextBlock, style, listItem, listItemLength}) => [\n {\n type: 'text block.set',\n listItem,\n level: 1,\n style,\n at: focusTextBlock.path,\n },\n {\n type: 'delete.text',\n anchor: {\n path: focusTextBlock.path,\n offset: 0,\n },\n focus: {\n path: focusTextBlock.path,\n offset: listItemLength + 1,\n },\n },\n ],\n ],\n })\n\n const markdownBehaviors = [\n automaticBlockquoteOnSpace,\n automaticHeadingOnSpace,\n automaticHr,\n automaticHrOnPaste,\n clearStyleOnBackspace,\n automaticListOnSpace,\n ]\n\n return markdownBehaviors\n}\n"],"names":["createCodeEditorBehaviors","config","defineBehavior","on","guard","context","event","isMoveUpShortcut","isHotkey","moveBlockUpShortcut","keyboardEvent","firstBlock","selectors","selectedBlocks","blocksAbove","node","_key","paths","map","block","path","actions","_","at","type","isMoveDownShortcut","moveBlockDownShortcut","lastBlock","blocksBelow","length","reverse","emojiCharRegEx","incompleteEmojiRegEx","emojiRegEx","createEmojiPickerBehaviors","emojiPickerActor","createActor","createEmojiPickerMachine","start","subscribe","state","onMatchesChanged","matches","onSelectedIndexChanged","selectedIndex","text","test","emojis","focusBlock","emojiKeyword","match","undefined","matchEmojis","keyword","params","effect","send","getSnapshot","emoji","parseMatch","textBefore","emojiStringLength","textBeforeLength","anchor","offset","focus","isShift","isColon","key","isEmojiChar","isArrowDown","isArrowUp","isEnter","isTab","action","unit","slice","setup","types","events","assign","assertEvent","guards","no matches","createMachine","id","initial","states","target","always","exit","createLinkBehaviors","pasteLinkOnSelection","selectionCollapsed","data","getData","url","looksLikeUrl","annotation","linkAnnotation","schema","pasteLinkAtCaret","focusSpan","annotations","URL","createMarkdownBehaviors","automaticBlockquoteOnSpace","focusTextBlock","blockOffset","spanSelectionPointToBlockOffset","value","selectionPoint","selection","blockText","getTextBlockText","caretAtTheEndOfQuote","looksLikeMarkdownQuote","blockquoteStyle","style","props","automaticHr","hrCharacter","hrObject","horizontalRuleObject","getBlockTextBefore","hrBlockOffsets","placement","blockObject","automaticHrOnPaste","hrRegExp","hrCharacters","isPortableTextTextBlock","textBlock","children","blockPath","automaticHeadingOnSpace","markdownHeadingSearch","exec","level","headingStyle","clearStyleOnBackspace","atTheBeginningOfBLock","defaultStyle","automaticListOnSpace","looksLikeUnorderedList","unorderedListStyle","caretAtTheEndOfUnorderedList","listItem","listItemLength","looksLikeOrderedList","orderedListStyle","caretAtTheEndOfOrderedList"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","sources":["../../src/behaviors/behavior.code-editor.ts","../../src/behaviors/behavior.emoji-picker.ts","../../src/utils/looks-like-url.ts","../../src/behaviors/behavior.links.ts","../../src/behaviors/behavior.markdown.ts"],"sourcesContent":["import * as selectors from '../selectors'\nimport {isHotkey} from '../utils/is-hotkey'\nimport {defineBehavior} from './behavior.types'\n\n/**\n * @beta\n */\nexport type CodeEditorBehaviorsConfig = {\n moveBlockUpShortcut: string\n moveBlockDownShortcut: string\n}\n\n/**\n * @beta\n */\nexport function createCodeEditorBehaviors(config: CodeEditorBehaviorsConfig) {\n return [\n defineBehavior({\n on: 'key.down',\n guard: ({context, event}) => {\n const isMoveUpShortcut = isHotkey(\n config.moveBlockUpShortcut,\n event.keyboardEvent,\n )\n const firstBlock = selectors.getFirstBlock({context})\n const selectedBlocks = selectors.getSelectedBlocks({context})\n const blocksAbove =\n firstBlock?.node._key !== selectedBlocks[0]?.node._key\n\n if (!isMoveUpShortcut || !blocksAbove) {\n return false\n }\n\n return {paths: selectedBlocks.map((block) => block.path)}\n },\n actions: [\n (_, {paths}) =>\n paths.map((at) => ({\n type: 'move.block up',\n at,\n })),\n ],\n }),\n defineBehavior({\n on: 'key.down',\n guard: ({context, event}) => {\n const isMoveDownShortcut = isHotkey(\n config.moveBlockDownShortcut,\n event.keyboardEvent,\n )\n const lastBlock = selectors.getLastBlock({context})\n const selectedBlocks = selectors.getSelectedBlocks({context})\n const blocksBelow =\n lastBlock?.node._key !==\n selectedBlocks[selectedBlocks.length - 1]?.node._key\n\n if (!isMoveDownShortcut || !blocksBelow) {\n return false\n }\n\n return {paths: selectedBlocks.map((block) => block.path).reverse()}\n },\n actions: [\n (_, {paths}) =>\n paths.map((at) => ({\n type: 'move.block down',\n at,\n })),\n ],\n }),\n ]\n}\n","import {assertEvent, assign, createActor, setup} from 'xstate'\nimport * as selectors from '../selectors'\nimport {isHotkey} from '../utils/is-hotkey'\nimport {defineBehavior} from './behavior.types'\n\nconst emojiCharRegEx = /^[a-zA-Z-_0-9]{1}$/\nconst incompleteEmojiRegEx = /:([a-zA-Z-_0-9]+)$/\nconst emojiRegEx = /:([a-zA-Z-_0-9]+):$/\n\n/**\n * @beta\n */\nexport type EmojiPickerBehaviorsConfig<TEmojiMatch> = {\n /**\n * Match emojis by keyword.\n */\n matchEmojis: ({keyword}: {keyword: string}) => Array<TEmojiMatch>\n onMatchesChanged: ({matches}: {matches: Array<TEmojiMatch>}) => void\n onSelectedIndexChanged: ({selectedIndex}: {selectedIndex: number}) => void\n /**\n * Parse an emoji match to a string that will be inserted into the editor.\n */\n parseMatch: ({match}: {match: TEmojiMatch}) => string | undefined\n}\n\n/**\n * @beta\n */\nexport function createEmojiPickerBehaviors<TEmojiMatch>(\n config: EmojiPickerBehaviorsConfig<TEmojiMatch>,\n) {\n const emojiPickerActor = createActor(createEmojiPickerMachine<TEmojiMatch>())\n emojiPickerActor.start()\n emojiPickerActor.subscribe((state) => {\n config.onMatchesChanged({matches: state.context.matches})\n config.onSelectedIndexChanged({selectedIndex: state.context.selectedIndex})\n })\n\n return [\n defineBehavior({\n on: 'insert.text',\n guard: ({context, event}) => {\n if (event.text === ':') {\n return false\n }\n\n const isEmojiChar = emojiCharRegEx.test(event.text)\n\n if (!isEmojiChar) {\n return {emojis: []}\n }\n\n const focusBlock = selectors.getFocusTextBlock({context})\n const textBefore = selectors.getBlockTextBefore({context})\n const emojiKeyword = `${textBefore}${event.text}`.match(\n incompleteEmojiRegEx,\n )?.[1]\n\n if (!focusBlock || emojiKeyword === undefined) {\n return {emojis: []}\n }\n\n const emojis = config.matchEmojis({keyword: emojiKeyword})\n\n return {emojis}\n },\n actions: [\n (_, params) => [\n {\n type: 'effect',\n effect: () => {\n emojiPickerActor.send({\n type: 'emojis found',\n matches: params.emojis,\n })\n },\n },\n ],\n ],\n }),\n defineBehavior({\n on: 'insert.text',\n guard: ({context, event}) => {\n const isColon = event.text === ':'\n\n if (!isColon) {\n return false\n }\n\n const matches = emojiPickerActor.getSnapshot().context.matches\n const selectedIndex =\n emojiPickerActor.getSnapshot().context.selectedIndex\n const emoji = matches[selectedIndex]\n ? config.parseMatch({match: matches[selectedIndex]})\n : undefined\n\n const focusBlock = selectors.getFocusTextBlock({context})\n const textBefore = selectors.getBlockTextBefore({context})\n const emojiKeyword = `${textBefore}:`.match(emojiRegEx)?.[1]\n\n if (!focusBlock || emojiKeyword === undefined) {\n return false\n }\n\n const emojiStringLength = emojiKeyword.length + 2\n\n if (emoji) {\n return {\n focusBlock,\n emoji,\n emojiStringLength,\n textBeforeLength: textBefore.length + 1,\n }\n }\n\n return false\n },\n actions: [\n () => [\n {\n type: 'insert.text',\n text: ':',\n },\n ],\n (_, params) => [\n {\n type: 'effect',\n effect: () => {\n emojiPickerActor.send({type: 'select'})\n },\n },\n {\n type: 'delete.text',\n anchor: {\n path: params.focusBlock.path,\n offset: params.textBeforeLength - params.emojiStringLength,\n },\n focus: {\n path: params.focusBlock.path,\n offset: params.textBeforeLength,\n },\n },\n {\n type: 'insert.text',\n text: params.emoji,\n },\n ],\n ],\n }),\n defineBehavior({\n on: 'key.down',\n guard: ({context, event}) => {\n const matches = emojiPickerActor.getSnapshot().context.matches\n\n if (matches.length === 0) {\n return false\n }\n\n const isShift = isHotkey('Shift', event.keyboardEvent)\n const isColon = event.keyboardEvent.key === ':'\n const isEmojiChar = emojiCharRegEx.test(event.keyboardEvent.key)\n\n if (isShift || isColon || isEmojiChar) {\n return false\n }\n\n const isArrowDown = isHotkey('ArrowDown', event.keyboardEvent)\n const isArrowUp = isHotkey('ArrowUp', event.keyboardEvent)\n const isEnter = isHotkey('Enter', event.keyboardEvent)\n const isTab = isHotkey('Tab', event.keyboardEvent)\n\n if (isEnter || isTab) {\n const selectedIndex =\n emojiPickerActor.getSnapshot().context.selectedIndex\n\n const emoji = matches[selectedIndex]\n ? config.parseMatch({match: matches[selectedIndex]})\n : undefined\n\n if (!emoji) {\n return false\n }\n\n const focusBlock = selectors.getFocusTextBlock({context})\n const textBefore = selectors.getBlockTextBefore({context})\n const emojiKeyword = textBefore.match(incompleteEmojiRegEx)?.[1]\n\n if (!focusBlock || emojiKeyword === undefined) {\n return false\n }\n\n const emojiStringLength = emojiKeyword.length + 1\n\n if (emoji) {\n return {\n action: 'select' as const,\n focusBlock,\n emoji,\n emojiStringLength,\n textBeforeLength: textBefore.length,\n }\n }\n\n return false\n }\n\n if (isArrowDown && matches.length > 0) {\n return {action: 'navigate down' as const}\n }\n\n if (isArrowUp && matches.length > 0) {\n return {action: 'navigate up' as const}\n }\n\n return {action: 'reset' as const}\n },\n actions: [\n (_, params) => {\n if (params.action === 'select') {\n return [\n {\n type: 'effect',\n effect: () => {\n emojiPickerActor.send({type: 'select'})\n },\n },\n {\n type: 'delete.text',\n anchor: {\n path: params.focusBlock.path,\n offset: params.textBeforeLength - params.emojiStringLength,\n },\n focus: {\n path: params.focusBlock.path,\n offset: params.textBeforeLength,\n },\n },\n {\n type: 'insert.text',\n text: params.emoji,\n },\n ]\n }\n\n if (params.action === 'navigate up') {\n return [\n // If we are navigating then we want to hijack the key event and\n // turn it into a noop.\n {\n type: 'noop',\n },\n {\n type: 'effect',\n effect: () => {\n emojiPickerActor.send({type: 'navigate up'})\n },\n },\n ]\n }\n\n if (params.action === 'navigate down') {\n return [\n // If we are navigating then we want to hijack the key event and\n // turn it into a noop.\n {\n type: 'noop',\n },\n {\n type: 'effect',\n effect: () => {\n emojiPickerActor.send({type: 'navigate down'})\n },\n },\n ]\n }\n\n return [\n {\n type: 'effect',\n effect: () => {\n emojiPickerActor.send({type: 'reset'})\n },\n },\n ]\n },\n ],\n }),\n defineBehavior({\n on: 'delete.backward',\n guard: ({context, event}) => {\n if (event.unit !== 'character') {\n return false\n }\n\n const matches = emojiPickerActor.getSnapshot().context.matches\n\n if (matches.length === 0) {\n return false\n }\n\n const focusBlock = selectors.getFocusTextBlock({context})\n const textBefore = selectors.getBlockTextBefore({context})\n const emojiKeyword = textBefore\n .slice(0, textBefore.length - 1)\n .match(incompleteEmojiRegEx)?.[1]\n\n if (!focusBlock || emojiKeyword === undefined) {\n return {emojis: []}\n }\n\n const emojis = config.matchEmojis({keyword: emojiKeyword})\n\n return {emojis}\n },\n actions: [\n (_, params) => [\n {\n type: 'effect',\n effect: () => {\n emojiPickerActor.send({\n type: 'emojis found',\n matches: params.emojis,\n })\n },\n },\n ],\n ],\n }),\n ]\n}\n\nfunction createEmojiPickerMachine<TEmojiSearchResult>() {\n return setup({\n types: {\n context: {} as {\n matches: Array<TEmojiSearchResult>\n selectedIndex: number\n },\n events: {} as\n | {\n type: 'emojis found'\n matches: Array<TEmojiSearchResult>\n }\n | {\n type: 'navigate down' | 'navigate up' | 'select' | 'reset'\n },\n },\n actions: {\n 'assign matches': assign({\n matches: ({event}) => {\n assertEvent(event, 'emojis found')\n return event.matches\n },\n }),\n 'reset matches': assign({\n matches: [],\n }),\n 'reset selected index': assign({\n selectedIndex: 0,\n }),\n 'increment selected index': assign({\n selectedIndex: ({context}) => {\n if (context.selectedIndex === context.matches.length - 1) {\n return 0\n }\n return context.selectedIndex + 1\n },\n }),\n 'decrement selected index': assign({\n selectedIndex: ({context}) => {\n if (context.selectedIndex === 0) {\n return context.matches.length - 1\n }\n return context.selectedIndex - 1\n },\n }),\n },\n guards: {\n 'no matches': ({context}) => context.matches.length === 0,\n },\n }).createMachine({\n id: 'emoji picker',\n context: {\n matches: [],\n selectedIndex: 0,\n },\n initial: 'idle',\n states: {\n 'idle': {\n on: {\n 'emojis found': {\n actions: 'assign matches',\n target: 'showing matches',\n },\n },\n },\n 'showing matches': {\n always: {\n guard: 'no matches',\n target: 'idle',\n },\n exit: ['reset selected index'],\n on: {\n 'emojis found': {\n actions: 'assign matches',\n },\n 'navigate down': {\n actions: 'increment selected index',\n },\n 'navigate up': {\n actions: 'decrement selected index',\n },\n 'reset': {\n target: 'idle',\n actions: ['reset selected index', 'reset matches'],\n },\n 'select': {\n target: 'idle',\n actions: ['reset selected index', 'reset matches'],\n },\n },\n },\n },\n })\n}\n","export function looksLikeUrl(text: string) {\n let looksLikeUrl = false\n try {\n try {\n const url = new URL(text)\n\n if (!sensibleProtocols.includes(url.protocol)) {\n return false\n }\n\n const probablyHasTld =\n url.hostname.length > 0 ? url.hostname.includes('.') : true\n\n looksLikeUrl = probablyHasTld\n } catch {\n const url = new URL(`https://${text}`)\n\n if (!sensibleProtocols.includes(url.protocol)) {\n return false\n }\n\n const probablyHasTld =\n url.hostname.length > 0 ? url.hostname.includes('.') : true\n\n looksLikeUrl = probablyHasTld\n }\n } catch {}\n return looksLikeUrl\n}\n\nconst sensibleProtocols = ['http:', 'https:', 'mailto:', 'tel:']\n","import type {EditorSchema} from '../editor/define-schema'\nimport * as selectors from '../selectors'\nimport {looksLikeUrl} from '../utils/looks-like-url'\nimport {defineBehavior} from './behavior.types'\n\n/**\n * @beta\n */\nexport type LinkBehaviorsConfig = {\n linkAnnotation?: (context: {\n schema: EditorSchema\n url: string\n }) => {name: string; value: {[prop: string]: unknown}} | undefined\n}\n\n/**\n * @beta\n */\nexport function createLinkBehaviors(config: LinkBehaviorsConfig) {\n const pasteLinkOnSelection = defineBehavior({\n on: 'paste',\n guard: ({context, event}) => {\n const selectionCollapsed = selectors.isSelectionCollapsed({context})\n const text = event.data.getData('text/plain')\n const url = looksLikeUrl(text) ? text : undefined\n const annotation =\n url !== undefined\n ? config.linkAnnotation?.({url, schema: context.schema})\n : undefined\n\n if (annotation && !selectionCollapsed) {\n return {annotation}\n }\n\n return false\n },\n actions: [\n (_, {annotation}) => [\n {\n type: 'annotation.add',\n annotation,\n },\n ],\n ],\n })\n const pasteLinkAtCaret = defineBehavior({\n on: 'paste',\n guard: ({context, event}) => {\n const focusSpan = selectors.getFocusSpan({context})\n const selectionCollapsed = selectors.isSelectionCollapsed({context})\n\n if (!focusSpan || !selectionCollapsed) {\n return false\n }\n\n const text = event.data.getData('text/plain')\n const url = looksLikeUrl(text) ? text : undefined\n const annotation =\n url !== undefined\n ? config.linkAnnotation?.({url, schema: context.schema})\n : undefined\n\n if (url && annotation && selectionCollapsed) {\n return {focusSpan, annotation, url}\n }\n\n return false\n },\n actions: [\n (_, {annotation, url}) => [\n {\n type: 'insert.span',\n text: url,\n annotations: [annotation],\n },\n ],\n ],\n })\n\n const linkBehaviors = [pasteLinkOnSelection, pasteLinkAtCaret]\n\n return linkBehaviors\n}\n","import {isPortableTextTextBlock} from '@sanity/types'\nimport type {EditorSchema} from '../editor/define-schema'\nimport {getTextBlockText} from '../editor/utils/utils'\nimport {spanSelectionPointToBlockOffset} from '../editor/utils/utils.block-offset'\nimport * as selectors from '../selectors'\nimport {getBlockTextBefore} from '../selectors/selector.get-text-before'\nimport {defineBehavior} from './behavior.types'\n\n/**\n * @beta\n */\nexport type MarkdownBehaviorsConfig = {\n horizontalRuleObject?: (context: {\n schema: EditorSchema\n }) => {name: string; value?: {[prop: string]: unknown}} | undefined\n defaultStyle?: (context: {schema: EditorSchema}) => string | undefined\n headingStyle?: (context: {\n schema: EditorSchema\n level: number\n }) => string | undefined\n blockquoteStyle?: (context: {schema: EditorSchema}) => string | undefined\n unorderedListStyle?: (context: {schema: EditorSchema}) => string | undefined\n orderedListStyle?: (context: {schema: EditorSchema}) => string | undefined\n}\n\n/**\n * @beta\n */\nexport function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {\n const automaticBlockquoteOnSpace = defineBehavior({\n on: 'insert.text',\n guard: ({context, event}) => {\n const isSpace = event.text === ' '\n\n if (!isSpace) {\n return false\n }\n\n const selectionCollapsed = selectors.isSelectionCollapsed({context})\n const focusTextBlock = selectors.getFocusTextBlock({context})\n const focusSpan = selectors.getFocusSpan({context})\n\n if (!selectionCollapsed || !focusTextBlock || !focusSpan) {\n return false\n }\n\n const blockOffset = spanSelectionPointToBlockOffset({\n value: context.value,\n selectionPoint: {\n path: [\n {_key: focusTextBlock.node._key},\n 'children',\n {_key: focusSpan.node._key},\n ],\n offset: context.selection?.focus.offset ?? 0,\n },\n })\n\n if (!blockOffset) {\n return false\n }\n\n const blockText = getTextBlockText(focusTextBlock.node)\n const caretAtTheEndOfQuote = blockOffset.offset === 1\n const looksLikeMarkdownQuote = /^>/.test(blockText)\n const blockquoteStyle = config.blockquoteStyle?.(context)\n\n if (\n caretAtTheEndOfQuote &&\n looksLikeMarkdownQuote &&\n blockquoteStyle !== undefined\n ) {\n return {focusTextBlock, style: blockquoteStyle}\n }\n\n return false\n },\n actions: [\n () => [\n {\n type: 'insert.text',\n text: ' ',\n },\n ],\n (_, {focusTextBlock, style}) => [\n {\n type: 'text block.unset',\n props: ['listItem', 'level'],\n at: focusTextBlock.path,\n },\n {\n type: 'text block.set',\n style,\n at: focusTextBlock.path,\n },\n {\n type: 'delete.text',\n anchor: {\n path: focusTextBlock.path,\n offset: 0,\n },\n focus: {\n path: focusTextBlock.path,\n offset: 2,\n },\n },\n ],\n ],\n })\n const automaticHr = defineBehavior({\n on: 'insert.text',\n guard: ({context, event}) => {\n const hrCharacter =\n event.text === '-'\n ? '-'\n : event.text === '*'\n ? '*'\n : event.text === '_'\n ? '_'\n : undefined\n\n if (hrCharacter === undefined) {\n return false\n }\n\n const hrObject = config.horizontalRuleObject?.(context)\n const focusBlock = selectors.getFocusTextBlock({context})\n const selectionCollapsed = selectors.isSelectionCollapsed({context})\n\n if (!hrObject || !focusBlock || !selectionCollapsed) {\n return false\n }\n\n const textBefore = getBlockTextBefore({context})\n const hrBlockOffsets = {\n anchor: {\n path: focusBlock.path,\n offset: 0,\n },\n focus: {\n path: focusBlock.path,\n offset: 3,\n },\n }\n\n if (textBefore === `${hrCharacter}${hrCharacter}`) {\n return {hrObject, focusBlock, hrCharacter, hrBlockOffsets}\n }\n\n return false\n },\n actions: [\n (_, {hrCharacter}) => [\n {\n type: 'insert.text',\n text: hrCharacter,\n },\n ],\n (_, {hrObject, hrBlockOffsets}) => [\n {\n type: 'insert.block object',\n placement: 'before',\n blockObject: hrObject,\n },\n {\n type: 'delete.text',\n ...hrBlockOffsets,\n },\n ],\n ],\n })\n const automaticHrOnPaste = defineBehavior({\n on: 'paste',\n guard: ({context, event}) => {\n const text = event.data.getData('text/plain')\n const hrRegExp = /^(---)$|(___)$|(\\*\\*\\*)$/gm\n const hrCharacters = text.match(hrRegExp)?.[0]\n const hrObject = config.horizontalRuleObject?.(context)\n const focusBlock = selectors.getFocusBlock({context})\n\n if (!hrCharacters || !hrObject || !focusBlock) {\n return false\n }\n\n return {hrCharacters, hrObject, focusBlock}\n },\n actions: [\n (_, {hrCharacters}) => [\n {\n type: 'insert.text',\n text: hrCharacters,\n },\n ],\n (_, {hrObject, focusBlock}) =>\n isPortableTextTextBlock(focusBlock.node)\n ? [\n {\n type: 'insert.text block',\n textBlock: {children: focusBlock.node.children},\n placement: 'after',\n },\n {\n type: 'insert.block object',\n blockObject: hrObject,\n placement: 'after',\n },\n {type: 'delete.block', blockPath: focusBlock.path},\n ]\n : [\n {\n type: 'insert.block object',\n blockObject: hrObject,\n placement: 'after',\n },\n ],\n ],\n })\n const automaticHeadingOnSpace = defineBehavior({\n on: 'insert.text',\n guard: ({context, event}) => {\n const isSpace = event.text === ' '\n\n if (!isSpace) {\n return false\n }\n\n const selectionCollapsed = selectors.isSelectionCollapsed({context})\n const focusTextBlock = selectors.getFocusTextBlock({context})\n const focusSpan = selectors.getFocusSpan({context})\n\n if (!selectionCollapsed || !focusTextBlock || !focusSpan) {\n return false\n }\n\n const blockOffset = spanSelectionPointToBlockOffset({\n value: context.value,\n selectionPoint: {\n path: [\n {_key: focusTextBlock.node._key},\n 'children',\n {_key: focusSpan.node._key},\n ],\n offset: context.selection?.focus.offset ?? 0,\n },\n })\n\n if (!blockOffset) {\n return false\n }\n\n const blockText = getTextBlockText(focusTextBlock.node)\n const markdownHeadingSearch = /^#+/.exec(blockText)\n const level = markdownHeadingSearch\n ? markdownHeadingSearch[0].length\n : undefined\n const caretAtTheEndOfHeading = blockOffset.offset === level\n\n if (!caretAtTheEndOfHeading) {\n return false\n }\n\n const style =\n level !== undefined\n ? config.headingStyle?.({schema: context.schema, level})\n : undefined\n\n if (level !== undefined && style !== undefined) {\n return {\n focusTextBlock,\n style: style,\n level,\n }\n }\n\n return false\n },\n actions: [\n ({event}) => [event],\n (_, {focusTextBlock, style, level}) => [\n {\n type: 'text block.unset',\n props: ['listItem', 'level'],\n at: focusTextBlock.path,\n },\n {\n type: 'text block.set',\n style,\n at: focusTextBlock.path,\n },\n {\n type: 'delete.text',\n anchor: {\n path: focusTextBlock.path,\n offset: 0,\n },\n focus: {\n path: focusTextBlock.path,\n offset: level + 1,\n },\n },\n ],\n ],\n })\n const clearStyleOnBackspace = defineBehavior({\n on: 'delete.backward',\n guard: ({context}) => {\n const selectionCollapsed = selectors.isSelectionCollapsed({context})\n const focusTextBlock = selectors.getFocusTextBlock({context})\n const focusSpan = selectors.getFocusSpan({context})\n\n if (!selectionCollapsed || !focusTextBlock || !focusSpan) {\n return false\n }\n\n const atTheBeginningOfBLock =\n focusTextBlock.node.children[0]._key === focusSpan.node._key &&\n context.selection?.focus.offset === 0\n\n const defaultStyle = config.defaultStyle?.(context)\n\n if (\n atTheBeginningOfBLock &&\n defaultStyle &&\n focusTextBlock.node.style !== defaultStyle\n ) {\n return {defaultStyle, focusTextBlock}\n }\n\n return false\n },\n actions: [\n (_, {defaultStyle, focusTextBlock}) => [\n {\n type: 'text block.set',\n style: defaultStyle,\n at: focusTextBlock.path,\n },\n ],\n ],\n })\n const automaticListOnSpace = defineBehavior({\n on: 'insert.text',\n guard: ({context, event}) => {\n const isSpace = event.text === ' '\n\n if (!isSpace) {\n return false\n }\n\n const selectionCollapsed = selectors.isSelectionCollapsed({context})\n const focusTextBlock = selectors.getFocusTextBlock({context})\n const focusSpan = selectors.getFocusSpan({context})\n\n if (!selectionCollapsed || !focusTextBlock || !focusSpan) {\n return false\n }\n\n const blockOffset = spanSelectionPointToBlockOffset({\n value: context.value,\n selectionPoint: {\n path: [\n {_key: focusTextBlock.node._key},\n 'children',\n {_key: focusSpan.node._key},\n ],\n offset: context.selection?.focus.offset ?? 0,\n },\n })\n\n if (!blockOffset) {\n return false\n }\n\n const blockText = getTextBlockText(focusTextBlock.node)\n const defaultStyle = config.defaultStyle?.(context)\n const looksLikeUnorderedList = /^(-|\\*)/.test(blockText)\n const unorderedListStyle = config.unorderedListStyle?.(context)\n const caretAtTheEndOfUnorderedList = blockOffset.offset === 1\n\n if (\n defaultStyle &&\n caretAtTheEndOfUnorderedList &&\n looksLikeUnorderedList &&\n unorderedListStyle !== undefined\n ) {\n return {\n focusTextBlock,\n listItem: unorderedListStyle,\n listItemLength: 1,\n style: defaultStyle,\n }\n }\n\n const looksLikeOrderedList = /^1\\./.test(blockText)\n const orderedListStyle = config.orderedListStyle?.(context)\n const caretAtTheEndOfOrderedList = blockOffset.offset === 2\n\n if (\n defaultStyle &&\n caretAtTheEndOfOrderedList &&\n looksLikeOrderedList &&\n orderedListStyle !== undefined\n ) {\n return {\n focusTextBlock,\n listItem: orderedListStyle,\n listItemLength: 2,\n style: defaultStyle,\n }\n }\n\n return false\n },\n actions: [\n ({event}) => [event],\n (_, {focusTextBlock, style, listItem, listItemLength}) => [\n {\n type: 'text block.set',\n listItem,\n level: 1,\n style,\n at: focusTextBlock.path,\n },\n {\n type: 'delete.text',\n anchor: {\n path: focusTextBlock.path,\n offset: 0,\n },\n focus: {\n path: focusTextBlock.path,\n offset: listItemLength + 1,\n },\n },\n ],\n ],\n })\n\n const markdownBehaviors = [\n automaticBlockquoteOnSpace,\n automaticHeadingOnSpace,\n automaticHr,\n automaticHrOnPaste,\n clearStyleOnBackspace,\n automaticListOnSpace,\n ]\n\n return markdownBehaviors\n}\n"],"names":["createCodeEditorBehaviors","config","defineBehavior","on","guard","context","event","isMoveUpShortcut","isHotkey","moveBlockUpShortcut","keyboardEvent","firstBlock","selectors","selectedBlocks","blocksAbove","node","_key","paths","map","block","path","actions","_","at","type","isMoveDownShortcut","moveBlockDownShortcut","lastBlock","blocksBelow","length","reverse","emojiCharRegEx","incompleteEmojiRegEx","emojiRegEx","createEmojiPickerBehaviors","emojiPickerActor","createActor","createEmojiPickerMachine","start","subscribe","state","onMatchesChanged","matches","onSelectedIndexChanged","selectedIndex","text","test","emojis","focusBlock","emojiKeyword","match","undefined","matchEmojis","keyword","params","effect","send","getSnapshot","emoji","parseMatch","textBefore","emojiStringLength","textBeforeLength","anchor","offset","focus","isShift","isColon","key","isEmojiChar","isArrowDown","isArrowUp","isEnter","isTab","action","unit","slice","setup","types","events","assign","assertEvent","guards","no matches","createMachine","id","initial","states","target","always","exit","looksLikeUrl","url","URL","sensibleProtocols","includes","protocol","hostname","createLinkBehaviors","pasteLinkOnSelection","selectionCollapsed","data","getData","annotation","linkAnnotation","schema","pasteLinkAtCaret","focusSpan","annotations","createMarkdownBehaviors","automaticBlockquoteOnSpace","focusTextBlock","blockOffset","spanSelectionPointToBlockOffset","value","selectionPoint","selection","blockText","getTextBlockText","caretAtTheEndOfQuote","looksLikeMarkdownQuote","blockquoteStyle","style","props","automaticHr","hrCharacter","hrObject","horizontalRuleObject","getBlockTextBefore","hrBlockOffsets","placement","blockObject","automaticHrOnPaste","hrRegExp","hrCharacters","isPortableTextTextBlock","textBlock","children","blockPath","automaticHeadingOnSpace","markdownHeadingSearch","exec","level","headingStyle","clearStyleOnBackspace","atTheBeginningOfBLock","defaultStyle","automaticListOnSpace","looksLikeUnorderedList","unorderedListStyle","caretAtTheEndOfUnorderedList","listItem","listItemLength","looksLikeOrderedList","orderedListStyle","caretAtTheEndOfOrderedList"],"mappings":"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"}
@@ -351,6 +351,25 @@ function createEmojiPickerMachine() {
351
351
  }
352
352
  });
353
353
  }
354
+ function looksLikeUrl(text) {
355
+ let looksLikeUrl2 = !1;
356
+ try {
357
+ try {
358
+ const url = new URL(text);
359
+ if (!sensibleProtocols.includes(url.protocol))
360
+ return !1;
361
+ looksLikeUrl2 = url.hostname.length > 0 ? url.hostname.includes(".") : !0;
362
+ } catch {
363
+ const url = new URL(`https://${text}`);
364
+ if (!sensibleProtocols.includes(url.protocol))
365
+ return !1;
366
+ looksLikeUrl2 = url.hostname.length > 0 ? url.hostname.includes(".") : !0;
367
+ }
368
+ } catch {
369
+ }
370
+ return looksLikeUrl2;
371
+ }
372
+ const sensibleProtocols = ["http:", "https:", "mailto:", "tel:"];
354
373
  function createLinkBehaviors(config) {
355
374
  const pasteLinkOnSelection = defineBehavior({
356
375
  on: "paste",
@@ -408,14 +427,6 @@ function createLinkBehaviors(config) {
408
427
  });
409
428
  return [pasteLinkOnSelection, pasteLinkAtCaret];
410
429
  }
411
- function looksLikeUrl(text) {
412
- let looksLikeUrl2 = !1;
413
- try {
414
- new URL(text), looksLikeUrl2 = !0;
415
- } catch {
416
- }
417
- return looksLikeUrl2;
418
- }
419
430
  function createMarkdownBehaviors(config) {
420
431
  const automaticBlockquoteOnSpace = defineBehavior({
421
432
  on: "insert.text",
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/behaviors/behavior.code-editor.ts","../../src/behaviors/behavior.emoji-picker.ts","../../src/behaviors/behavior.links.ts","../../src/behaviors/behavior.markdown.ts"],"sourcesContent":["import * as selectors from '../selectors'\nimport {isHotkey} from '../utils/is-hotkey'\nimport {defineBehavior} from './behavior.types'\n\n/**\n * @beta\n */\nexport type CodeEditorBehaviorsConfig = {\n moveBlockUpShortcut: string\n moveBlockDownShortcut: string\n}\n\n/**\n * @beta\n */\nexport function createCodeEditorBehaviors(config: CodeEditorBehaviorsConfig) {\n return [\n defineBehavior({\n on: 'key.down',\n guard: ({context, event}) => {\n const isMoveUpShortcut = isHotkey(\n config.moveBlockUpShortcut,\n event.keyboardEvent,\n )\n const firstBlock = selectors.getFirstBlock({context})\n const selectedBlocks = selectors.getSelectedBlocks({context})\n const blocksAbove =\n firstBlock?.node._key !== selectedBlocks[0]?.node._key\n\n if (!isMoveUpShortcut || !blocksAbove) {\n return false\n }\n\n return {paths: selectedBlocks.map((block) => block.path)}\n },\n actions: [\n (_, {paths}) =>\n paths.map((at) => ({\n type: 'move.block up',\n at,\n })),\n ],\n }),\n defineBehavior({\n on: 'key.down',\n guard: ({context, event}) => {\n const isMoveDownShortcut = isHotkey(\n config.moveBlockDownShortcut,\n event.keyboardEvent,\n )\n const lastBlock = selectors.getLastBlock({context})\n const selectedBlocks = selectors.getSelectedBlocks({context})\n const blocksBelow =\n lastBlock?.node._key !==\n selectedBlocks[selectedBlocks.length - 1]?.node._key\n\n if (!isMoveDownShortcut || !blocksBelow) {\n return false\n }\n\n return {paths: selectedBlocks.map((block) => block.path).reverse()}\n },\n actions: [\n (_, {paths}) =>\n paths.map((at) => ({\n type: 'move.block down',\n at,\n })),\n ],\n }),\n ]\n}\n","import {assertEvent, assign, createActor, setup} from 'xstate'\nimport * as selectors from '../selectors'\nimport {isHotkey} from '../utils/is-hotkey'\nimport {defineBehavior} from './behavior.types'\n\nconst emojiCharRegEx = /^[a-zA-Z-_0-9]{1}$/\nconst incompleteEmojiRegEx = /:([a-zA-Z-_0-9]+)$/\nconst emojiRegEx = /:([a-zA-Z-_0-9]+):$/\n\n/**\n * @beta\n */\nexport type EmojiPickerBehaviorsConfig<TEmojiMatch> = {\n /**\n * Match emojis by keyword.\n */\n matchEmojis: ({keyword}: {keyword: string}) => Array<TEmojiMatch>\n onMatchesChanged: ({matches}: {matches: Array<TEmojiMatch>}) => void\n onSelectedIndexChanged: ({selectedIndex}: {selectedIndex: number}) => void\n /**\n * Parse an emoji match to a string that will be inserted into the editor.\n */\n parseMatch: ({match}: {match: TEmojiMatch}) => string | undefined\n}\n\n/**\n * @beta\n */\nexport function createEmojiPickerBehaviors<TEmojiMatch>(\n config: EmojiPickerBehaviorsConfig<TEmojiMatch>,\n) {\n const emojiPickerActor = createActor(createEmojiPickerMachine<TEmojiMatch>())\n emojiPickerActor.start()\n emojiPickerActor.subscribe((state) => {\n config.onMatchesChanged({matches: state.context.matches})\n config.onSelectedIndexChanged({selectedIndex: state.context.selectedIndex})\n })\n\n return [\n defineBehavior({\n on: 'insert.text',\n guard: ({context, event}) => {\n if (event.text === ':') {\n return false\n }\n\n const isEmojiChar = emojiCharRegEx.test(event.text)\n\n if (!isEmojiChar) {\n return {emojis: []}\n }\n\n const focusBlock = selectors.getFocusTextBlock({context})\n const textBefore = selectors.getBlockTextBefore({context})\n const emojiKeyword = `${textBefore}${event.text}`.match(\n incompleteEmojiRegEx,\n )?.[1]\n\n if (!focusBlock || emojiKeyword === undefined) {\n return {emojis: []}\n }\n\n const emojis = config.matchEmojis({keyword: emojiKeyword})\n\n return {emojis}\n },\n actions: [\n (_, params) => [\n {\n type: 'effect',\n effect: () => {\n emojiPickerActor.send({\n type: 'emojis found',\n matches: params.emojis,\n })\n },\n },\n ],\n ],\n }),\n defineBehavior({\n on: 'insert.text',\n guard: ({context, event}) => {\n const isColon = event.text === ':'\n\n if (!isColon) {\n return false\n }\n\n const matches = emojiPickerActor.getSnapshot().context.matches\n const selectedIndex =\n emojiPickerActor.getSnapshot().context.selectedIndex\n const emoji = matches[selectedIndex]\n ? config.parseMatch({match: matches[selectedIndex]})\n : undefined\n\n const focusBlock = selectors.getFocusTextBlock({context})\n const textBefore = selectors.getBlockTextBefore({context})\n const emojiKeyword = `${textBefore}:`.match(emojiRegEx)?.[1]\n\n if (!focusBlock || emojiKeyword === undefined) {\n return false\n }\n\n const emojiStringLength = emojiKeyword.length + 2\n\n if (emoji) {\n return {\n focusBlock,\n emoji,\n emojiStringLength,\n textBeforeLength: textBefore.length + 1,\n }\n }\n\n return false\n },\n actions: [\n () => [\n {\n type: 'insert.text',\n text: ':',\n },\n ],\n (_, params) => [\n {\n type: 'effect',\n effect: () => {\n emojiPickerActor.send({type: 'select'})\n },\n },\n {\n type: 'delete.text',\n anchor: {\n path: params.focusBlock.path,\n offset: params.textBeforeLength - params.emojiStringLength,\n },\n focus: {\n path: params.focusBlock.path,\n offset: params.textBeforeLength,\n },\n },\n {\n type: 'insert.text',\n text: params.emoji,\n },\n ],\n ],\n }),\n defineBehavior({\n on: 'key.down',\n guard: ({context, event}) => {\n const matches = emojiPickerActor.getSnapshot().context.matches\n\n if (matches.length === 0) {\n return false\n }\n\n const isShift = isHotkey('Shift', event.keyboardEvent)\n const isColon = event.keyboardEvent.key === ':'\n const isEmojiChar = emojiCharRegEx.test(event.keyboardEvent.key)\n\n if (isShift || isColon || isEmojiChar) {\n return false\n }\n\n const isArrowDown = isHotkey('ArrowDown', event.keyboardEvent)\n const isArrowUp = isHotkey('ArrowUp', event.keyboardEvent)\n const isEnter = isHotkey('Enter', event.keyboardEvent)\n const isTab = isHotkey('Tab', event.keyboardEvent)\n\n if (isEnter || isTab) {\n const selectedIndex =\n emojiPickerActor.getSnapshot().context.selectedIndex\n\n const emoji = matches[selectedIndex]\n ? config.parseMatch({match: matches[selectedIndex]})\n : undefined\n\n if (!emoji) {\n return false\n }\n\n const focusBlock = selectors.getFocusTextBlock({context})\n const textBefore = selectors.getBlockTextBefore({context})\n const emojiKeyword = textBefore.match(incompleteEmojiRegEx)?.[1]\n\n if (!focusBlock || emojiKeyword === undefined) {\n return false\n }\n\n const emojiStringLength = emojiKeyword.length + 1\n\n if (emoji) {\n return {\n action: 'select' as const,\n focusBlock,\n emoji,\n emojiStringLength,\n textBeforeLength: textBefore.length,\n }\n }\n\n return false\n }\n\n if (isArrowDown && matches.length > 0) {\n return {action: 'navigate down' as const}\n }\n\n if (isArrowUp && matches.length > 0) {\n return {action: 'navigate up' as const}\n }\n\n return {action: 'reset' as const}\n },\n actions: [\n (_, params) => {\n if (params.action === 'select') {\n return [\n {\n type: 'effect',\n effect: () => {\n emojiPickerActor.send({type: 'select'})\n },\n },\n {\n type: 'delete.text',\n anchor: {\n path: params.focusBlock.path,\n offset: params.textBeforeLength - params.emojiStringLength,\n },\n focus: {\n path: params.focusBlock.path,\n offset: params.textBeforeLength,\n },\n },\n {\n type: 'insert.text',\n text: params.emoji,\n },\n ]\n }\n\n if (params.action === 'navigate up') {\n return [\n // If we are navigating then we want to hijack the key event and\n // turn it into a noop.\n {\n type: 'noop',\n },\n {\n type: 'effect',\n effect: () => {\n emojiPickerActor.send({type: 'navigate up'})\n },\n },\n ]\n }\n\n if (params.action === 'navigate down') {\n return [\n // If we are navigating then we want to hijack the key event and\n // turn it into a noop.\n {\n type: 'noop',\n },\n {\n type: 'effect',\n effect: () => {\n emojiPickerActor.send({type: 'navigate down'})\n },\n },\n ]\n }\n\n return [\n {\n type: 'effect',\n effect: () => {\n emojiPickerActor.send({type: 'reset'})\n },\n },\n ]\n },\n ],\n }),\n defineBehavior({\n on: 'delete.backward',\n guard: ({context, event}) => {\n if (event.unit !== 'character') {\n return false\n }\n\n const matches = emojiPickerActor.getSnapshot().context.matches\n\n if (matches.length === 0) {\n return false\n }\n\n const focusBlock = selectors.getFocusTextBlock({context})\n const textBefore = selectors.getBlockTextBefore({context})\n const emojiKeyword = textBefore\n .slice(0, textBefore.length - 1)\n .match(incompleteEmojiRegEx)?.[1]\n\n if (!focusBlock || emojiKeyword === undefined) {\n return {emojis: []}\n }\n\n const emojis = config.matchEmojis({keyword: emojiKeyword})\n\n return {emojis}\n },\n actions: [\n (_, params) => [\n {\n type: 'effect',\n effect: () => {\n emojiPickerActor.send({\n type: 'emojis found',\n matches: params.emojis,\n })\n },\n },\n ],\n ],\n }),\n ]\n}\n\nfunction createEmojiPickerMachine<TEmojiSearchResult>() {\n return setup({\n types: {\n context: {} as {\n matches: Array<TEmojiSearchResult>\n selectedIndex: number\n },\n events: {} as\n | {\n type: 'emojis found'\n matches: Array<TEmojiSearchResult>\n }\n | {\n type: 'navigate down' | 'navigate up' | 'select' | 'reset'\n },\n },\n actions: {\n 'assign matches': assign({\n matches: ({event}) => {\n assertEvent(event, 'emojis found')\n return event.matches\n },\n }),\n 'reset matches': assign({\n matches: [],\n }),\n 'reset selected index': assign({\n selectedIndex: 0,\n }),\n 'increment selected index': assign({\n selectedIndex: ({context}) => {\n if (context.selectedIndex === context.matches.length - 1) {\n return 0\n }\n return context.selectedIndex + 1\n },\n }),\n 'decrement selected index': assign({\n selectedIndex: ({context}) => {\n if (context.selectedIndex === 0) {\n return context.matches.length - 1\n }\n return context.selectedIndex - 1\n },\n }),\n },\n guards: {\n 'no matches': ({context}) => context.matches.length === 0,\n },\n }).createMachine({\n id: 'emoji picker',\n context: {\n matches: [],\n selectedIndex: 0,\n },\n initial: 'idle',\n states: {\n 'idle': {\n on: {\n 'emojis found': {\n actions: 'assign matches',\n target: 'showing matches',\n },\n },\n },\n 'showing matches': {\n always: {\n guard: 'no matches',\n target: 'idle',\n },\n exit: ['reset selected index'],\n on: {\n 'emojis found': {\n actions: 'assign matches',\n },\n 'navigate down': {\n actions: 'increment selected index',\n },\n 'navigate up': {\n actions: 'decrement selected index',\n },\n 'reset': {\n target: 'idle',\n actions: ['reset selected index', 'reset matches'],\n },\n 'select': {\n target: 'idle',\n actions: ['reset selected index', 'reset matches'],\n },\n },\n },\n },\n })\n}\n","import type {EditorSchema} from '../editor/define-schema'\nimport * as selectors from '../selectors'\nimport {defineBehavior} from './behavior.types'\n\n/**\n * @beta\n */\nexport type LinkBehaviorsConfig = {\n linkAnnotation?: (context: {\n schema: EditorSchema\n url: string\n }) => {name: string; value: {[prop: string]: unknown}} | undefined\n}\n\n/**\n * @beta\n */\nexport function createLinkBehaviors(config: LinkBehaviorsConfig) {\n const pasteLinkOnSelection = defineBehavior({\n on: 'paste',\n guard: ({context, event}) => {\n const selectionCollapsed = selectors.isSelectionCollapsed({context})\n const text = event.data.getData('text/plain')\n const url = looksLikeUrl(text) ? text : undefined\n const annotation =\n url !== undefined\n ? config.linkAnnotation?.({url, schema: context.schema})\n : undefined\n\n if (annotation && !selectionCollapsed) {\n return {annotation}\n }\n\n return false\n },\n actions: [\n (_, {annotation}) => [\n {\n type: 'annotation.add',\n annotation,\n },\n ],\n ],\n })\n const pasteLinkAtCaret = defineBehavior({\n on: 'paste',\n guard: ({context, event}) => {\n const focusSpan = selectors.getFocusSpan({context})\n const selectionCollapsed = selectors.isSelectionCollapsed({context})\n\n if (!focusSpan || !selectionCollapsed) {\n return false\n }\n\n const text = event.data.getData('text/plain')\n const url = looksLikeUrl(text) ? text : undefined\n const annotation =\n url !== undefined\n ? config.linkAnnotation?.({url, schema: context.schema})\n : undefined\n\n if (url && annotation && selectionCollapsed) {\n return {focusSpan, annotation, url}\n }\n\n return false\n },\n actions: [\n (_, {annotation, url}) => [\n {\n type: 'insert.span',\n text: url,\n annotations: [annotation],\n },\n ],\n ],\n })\n\n const linkBehaviors = [pasteLinkOnSelection, pasteLinkAtCaret]\n\n return linkBehaviors\n}\n\nfunction looksLikeUrl(text: string) {\n let looksLikeUrl = false\n try {\n new URL(text)\n looksLikeUrl = true\n } catch {}\n return looksLikeUrl\n}\n","import {isPortableTextTextBlock} from '@sanity/types'\nimport type {EditorSchema} from '../editor/define-schema'\nimport {getTextBlockText} from '../editor/utils/utils'\nimport {spanSelectionPointToBlockOffset} from '../editor/utils/utils.block-offset'\nimport * as selectors from '../selectors'\nimport {getBlockTextBefore} from '../selectors/selector.get-text-before'\nimport {defineBehavior} from './behavior.types'\n\n/**\n * @beta\n */\nexport type MarkdownBehaviorsConfig = {\n horizontalRuleObject?: (context: {\n schema: EditorSchema\n }) => {name: string; value?: {[prop: string]: unknown}} | undefined\n defaultStyle?: (context: {schema: EditorSchema}) => string | undefined\n headingStyle?: (context: {\n schema: EditorSchema\n level: number\n }) => string | undefined\n blockquoteStyle?: (context: {schema: EditorSchema}) => string | undefined\n unorderedListStyle?: (context: {schema: EditorSchema}) => string | undefined\n orderedListStyle?: (context: {schema: EditorSchema}) => string | undefined\n}\n\n/**\n * @beta\n */\nexport function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {\n const automaticBlockquoteOnSpace = defineBehavior({\n on: 'insert.text',\n guard: ({context, event}) => {\n const isSpace = event.text === ' '\n\n if (!isSpace) {\n return false\n }\n\n const selectionCollapsed = selectors.isSelectionCollapsed({context})\n const focusTextBlock = selectors.getFocusTextBlock({context})\n const focusSpan = selectors.getFocusSpan({context})\n\n if (!selectionCollapsed || !focusTextBlock || !focusSpan) {\n return false\n }\n\n const blockOffset = spanSelectionPointToBlockOffset({\n value: context.value,\n selectionPoint: {\n path: [\n {_key: focusTextBlock.node._key},\n 'children',\n {_key: focusSpan.node._key},\n ],\n offset: context.selection?.focus.offset ?? 0,\n },\n })\n\n if (!blockOffset) {\n return false\n }\n\n const blockText = getTextBlockText(focusTextBlock.node)\n const caretAtTheEndOfQuote = blockOffset.offset === 1\n const looksLikeMarkdownQuote = /^>/.test(blockText)\n const blockquoteStyle = config.blockquoteStyle?.(context)\n\n if (\n caretAtTheEndOfQuote &&\n looksLikeMarkdownQuote &&\n blockquoteStyle !== undefined\n ) {\n return {focusTextBlock, style: blockquoteStyle}\n }\n\n return false\n },\n actions: [\n () => [\n {\n type: 'insert.text',\n text: ' ',\n },\n ],\n (_, {focusTextBlock, style}) => [\n {\n type: 'text block.unset',\n props: ['listItem', 'level'],\n at: focusTextBlock.path,\n },\n {\n type: 'text block.set',\n style,\n at: focusTextBlock.path,\n },\n {\n type: 'delete.text',\n anchor: {\n path: focusTextBlock.path,\n offset: 0,\n },\n focus: {\n path: focusTextBlock.path,\n offset: 2,\n },\n },\n ],\n ],\n })\n const automaticHr = defineBehavior({\n on: 'insert.text',\n guard: ({context, event}) => {\n const hrCharacter =\n event.text === '-'\n ? '-'\n : event.text === '*'\n ? '*'\n : event.text === '_'\n ? '_'\n : undefined\n\n if (hrCharacter === undefined) {\n return false\n }\n\n const hrObject = config.horizontalRuleObject?.(context)\n const focusBlock = selectors.getFocusTextBlock({context})\n const selectionCollapsed = selectors.isSelectionCollapsed({context})\n\n if (!hrObject || !focusBlock || !selectionCollapsed) {\n return false\n }\n\n const textBefore = getBlockTextBefore({context})\n const hrBlockOffsets = {\n anchor: {\n path: focusBlock.path,\n offset: 0,\n },\n focus: {\n path: focusBlock.path,\n offset: 3,\n },\n }\n\n if (textBefore === `${hrCharacter}${hrCharacter}`) {\n return {hrObject, focusBlock, hrCharacter, hrBlockOffsets}\n }\n\n return false\n },\n actions: [\n (_, {hrCharacter}) => [\n {\n type: 'insert.text',\n text: hrCharacter,\n },\n ],\n (_, {hrObject, hrBlockOffsets}) => [\n {\n type: 'insert.block object',\n placement: 'before',\n blockObject: hrObject,\n },\n {\n type: 'delete.text',\n ...hrBlockOffsets,\n },\n ],\n ],\n })\n const automaticHrOnPaste = defineBehavior({\n on: 'paste',\n guard: ({context, event}) => {\n const text = event.data.getData('text/plain')\n const hrRegExp = /^(---)$|(___)$|(\\*\\*\\*)$/gm\n const hrCharacters = text.match(hrRegExp)?.[0]\n const hrObject = config.horizontalRuleObject?.(context)\n const focusBlock = selectors.getFocusBlock({context})\n\n if (!hrCharacters || !hrObject || !focusBlock) {\n return false\n }\n\n return {hrCharacters, hrObject, focusBlock}\n },\n actions: [\n (_, {hrCharacters}) => [\n {\n type: 'insert.text',\n text: hrCharacters,\n },\n ],\n (_, {hrObject, focusBlock}) =>\n isPortableTextTextBlock(focusBlock.node)\n ? [\n {\n type: 'insert.text block',\n textBlock: {children: focusBlock.node.children},\n placement: 'after',\n },\n {\n type: 'insert.block object',\n blockObject: hrObject,\n placement: 'after',\n },\n {type: 'delete.block', blockPath: focusBlock.path},\n ]\n : [\n {\n type: 'insert.block object',\n blockObject: hrObject,\n placement: 'after',\n },\n ],\n ],\n })\n const automaticHeadingOnSpace = defineBehavior({\n on: 'insert.text',\n guard: ({context, event}) => {\n const isSpace = event.text === ' '\n\n if (!isSpace) {\n return false\n }\n\n const selectionCollapsed = selectors.isSelectionCollapsed({context})\n const focusTextBlock = selectors.getFocusTextBlock({context})\n const focusSpan = selectors.getFocusSpan({context})\n\n if (!selectionCollapsed || !focusTextBlock || !focusSpan) {\n return false\n }\n\n const blockOffset = spanSelectionPointToBlockOffset({\n value: context.value,\n selectionPoint: {\n path: [\n {_key: focusTextBlock.node._key},\n 'children',\n {_key: focusSpan.node._key},\n ],\n offset: context.selection?.focus.offset ?? 0,\n },\n })\n\n if (!blockOffset) {\n return false\n }\n\n const blockText = getTextBlockText(focusTextBlock.node)\n const markdownHeadingSearch = /^#+/.exec(blockText)\n const level = markdownHeadingSearch\n ? markdownHeadingSearch[0].length\n : undefined\n const caretAtTheEndOfHeading = blockOffset.offset === level\n\n if (!caretAtTheEndOfHeading) {\n return false\n }\n\n const style =\n level !== undefined\n ? config.headingStyle?.({schema: context.schema, level})\n : undefined\n\n if (level !== undefined && style !== undefined) {\n return {\n focusTextBlock,\n style: style,\n level,\n }\n }\n\n return false\n },\n actions: [\n ({event}) => [event],\n (_, {focusTextBlock, style, level}) => [\n {\n type: 'text block.unset',\n props: ['listItem', 'level'],\n at: focusTextBlock.path,\n },\n {\n type: 'text block.set',\n style,\n at: focusTextBlock.path,\n },\n {\n type: 'delete.text',\n anchor: {\n path: focusTextBlock.path,\n offset: 0,\n },\n focus: {\n path: focusTextBlock.path,\n offset: level + 1,\n },\n },\n ],\n ],\n })\n const clearStyleOnBackspace = defineBehavior({\n on: 'delete.backward',\n guard: ({context}) => {\n const selectionCollapsed = selectors.isSelectionCollapsed({context})\n const focusTextBlock = selectors.getFocusTextBlock({context})\n const focusSpan = selectors.getFocusSpan({context})\n\n if (!selectionCollapsed || !focusTextBlock || !focusSpan) {\n return false\n }\n\n const atTheBeginningOfBLock =\n focusTextBlock.node.children[0]._key === focusSpan.node._key &&\n context.selection?.focus.offset === 0\n\n const defaultStyle = config.defaultStyle?.(context)\n\n if (\n atTheBeginningOfBLock &&\n defaultStyle &&\n focusTextBlock.node.style !== defaultStyle\n ) {\n return {defaultStyle, focusTextBlock}\n }\n\n return false\n },\n actions: [\n (_, {defaultStyle, focusTextBlock}) => [\n {\n type: 'text block.set',\n style: defaultStyle,\n at: focusTextBlock.path,\n },\n ],\n ],\n })\n const automaticListOnSpace = defineBehavior({\n on: 'insert.text',\n guard: ({context, event}) => {\n const isSpace = event.text === ' '\n\n if (!isSpace) {\n return false\n }\n\n const selectionCollapsed = selectors.isSelectionCollapsed({context})\n const focusTextBlock = selectors.getFocusTextBlock({context})\n const focusSpan = selectors.getFocusSpan({context})\n\n if (!selectionCollapsed || !focusTextBlock || !focusSpan) {\n return false\n }\n\n const blockOffset = spanSelectionPointToBlockOffset({\n value: context.value,\n selectionPoint: {\n path: [\n {_key: focusTextBlock.node._key},\n 'children',\n {_key: focusSpan.node._key},\n ],\n offset: context.selection?.focus.offset ?? 0,\n },\n })\n\n if (!blockOffset) {\n return false\n }\n\n const blockText = getTextBlockText(focusTextBlock.node)\n const defaultStyle = config.defaultStyle?.(context)\n const looksLikeUnorderedList = /^(-|\\*)/.test(blockText)\n const unorderedListStyle = config.unorderedListStyle?.(context)\n const caretAtTheEndOfUnorderedList = blockOffset.offset === 1\n\n if (\n defaultStyle &&\n caretAtTheEndOfUnorderedList &&\n looksLikeUnorderedList &&\n unorderedListStyle !== undefined\n ) {\n return {\n focusTextBlock,\n listItem: unorderedListStyle,\n listItemLength: 1,\n style: defaultStyle,\n }\n }\n\n const looksLikeOrderedList = /^1\\./.test(blockText)\n const orderedListStyle = config.orderedListStyle?.(context)\n const caretAtTheEndOfOrderedList = blockOffset.offset === 2\n\n if (\n defaultStyle &&\n caretAtTheEndOfOrderedList &&\n looksLikeOrderedList &&\n orderedListStyle !== undefined\n ) {\n return {\n focusTextBlock,\n listItem: orderedListStyle,\n listItemLength: 2,\n style: defaultStyle,\n }\n }\n\n return false\n },\n actions: [\n ({event}) => [event],\n (_, {focusTextBlock, style, listItem, listItemLength}) => [\n {\n type: 'text block.set',\n listItem,\n level: 1,\n style,\n at: focusTextBlock.path,\n },\n {\n type: 'delete.text',\n anchor: {\n path: focusTextBlock.path,\n offset: 0,\n },\n focus: {\n path: focusTextBlock.path,\n offset: listItemLength + 1,\n },\n },\n ],\n ],\n })\n\n const markdownBehaviors = [\n automaticBlockquoteOnSpace,\n automaticHeadingOnSpace,\n automaticHr,\n automaticHrOnPaste,\n clearStyleOnBackspace,\n automaticListOnSpace,\n ]\n\n return markdownBehaviors\n}\n"],"names":["createCodeEditorBehaviors","config","defineBehavior","on","guard","context","event","isMoveUpShortcut","isHotkey","moveBlockUpShortcut","keyboardEvent","firstBlock","selectors","selectedBlocks","blocksAbove","node","_key","paths","map","block","path","actions","_","at","type","isMoveDownShortcut","moveBlockDownShortcut","lastBlock","blocksBelow","length","reverse","emojiCharRegEx","incompleteEmojiRegEx","emojiRegEx","createEmojiPickerBehaviors","emojiPickerActor","createActor","createEmojiPickerMachine","start","subscribe","state","onMatchesChanged","matches","onSelectedIndexChanged","selectedIndex","text","test","emojis","focusBlock","emojiKeyword","match","undefined","matchEmojis","keyword","params","effect","send","getSnapshot","emoji","parseMatch","textBefore","emojiStringLength","textBeforeLength","anchor","offset","focus","isShift","isColon","key","isEmojiChar","isArrowDown","isArrowUp","isEnter","isTab","action","unit","slice","setup","types","events","assign","assertEvent","guards","no matches","createMachine","id","initial","states","target","always","exit","createLinkBehaviors","pasteLinkOnSelection","selectionCollapsed","data","getData","url","looksLikeUrl","annotation","linkAnnotation","schema","pasteLinkAtCaret","focusSpan","annotations","URL","createMarkdownBehaviors","automaticBlockquoteOnSpace","focusTextBlock","blockOffset","spanSelectionPointToBlockOffset","value","selectionPoint","selection","blockText","getTextBlockText","caretAtTheEndOfQuote","looksLikeMarkdownQuote","blockquoteStyle","style","props","automaticHr","hrCharacter","hrObject","horizontalRuleObject","getBlockTextBefore","hrBlockOffsets","placement","blockObject","automaticHrOnPaste","hrRegExp","hrCharacters","isPortableTextTextBlock","textBlock","children","blockPath","automaticHeadingOnSpace","markdownHeadingSearch","exec","level","headingStyle","clearStyleOnBackspace","atTheBeginningOfBLock","defaultStyle","automaticListOnSpace","looksLikeUnorderedList","unorderedListStyle","caretAtTheEndOfUnorderedList","listItem","listItemLength","looksLikeOrderedList","orderedListStyle","caretAtTheEndOfOrderedList"],"mappings":";;;;;;AAeO,SAASA,0BAA0BC,QAAmC;AAC3E,SAAO,CACLC,eAAe;AAAA,IACbC,IAAI;AAAA,IACJC,OAAOA,CAAC;AAAA,MAACC;AAAAA,MAASC;AAAAA,IAAAA,MAAW;AACrBC,YAAAA,mBAAmBC,SACvBP,OAAOQ,qBACPH,MAAMI,aACR,GACMC,aAAaC,cAAwB;AAAA,QAACP;AAAAA,MAAAA,CAAQ,GAC9CQ,iBAAiBD,kBAA4B;AAAA,QAACP;AAAAA,MAAAA,CAAQ,GACtDS,cACJH,YAAYI,KAAKC,SAASH,eAAe,CAAC,GAAGE,KAAKC;AAEpD,aAAI,CAACT,oBAAoB,CAACO,cACjB,KAGF;AAAA,QAACG,OAAOJ,eAAeK,IAAKC,CAAAA,UAAUA,MAAMC,IAAI;AAAA,MAAC;AAAA,IAC1D;AAAA,IACAC,SAAS,CACP,CAACC,GAAG;AAAA,MAACL;AAAAA,IAAAA,MACHA,MAAMC,IAAKK,CAAQ,QAAA;AAAA,MACjBC,MAAM;AAAA,MACND;AAAAA,IAAAA,EACA,CAAC;AAAA,EAER,CAAA,GACDrB,eAAe;AAAA,IACbC,IAAI;AAAA,IACJC,OAAOA,CAAC;AAAA,MAACC;AAAAA,MAASC;AAAAA,IAAAA,MAAW;AACrBmB,YAAAA,qBAAqBjB,SACzBP,OAAOyB,uBACPpB,MAAMI,aACR,GACMiB,YAAYf,aAAuB;AAAA,QAACP;AAAAA,MAAAA,CAAQ,GAC5CQ,iBAAiBD,kBAA4B;AAAA,QAACP;AAAAA,MAAQ,CAAA,GACtDuB,cACJD,WAAWZ,KAAKC,SAChBH,eAAeA,eAAegB,SAAS,CAAC,GAAGd,KAAKC;AAElD,aAAI,CAACS,sBAAsB,CAACG,cACnB,KAGF;AAAA,QAACX,OAAOJ,eAAeK,IAAKC,WAAUA,MAAMC,IAAI,EAAEU,QAAQ;AAAA,MAAC;AAAA,IACpE;AAAA,IACAT,SAAS,CACP,CAACC,GAAG;AAAA,MAACL;AAAAA,IAAAA,MACHA,MAAMC,IAAKK,CAAQ,QAAA;AAAA,MACjBC,MAAM;AAAA,MACND;AAAAA,IAAAA,EACA,CAAC;AAAA,EAAA,CAER,CAAC;AAEN;AClEA,MAAMQ,iBAAiB,sBACjBC,uBAAuB,sBACvBC,aAAa;AAqBZ,SAASC,2BACdjC,QACA;AACMkC,QAAAA,mBAAmBC,YAAYC,0BAAuC;AAC5EF,SAAAA,iBAAiBG,MAAM,GACvBH,iBAAiBI,UAAWC,CAAU,UAAA;AACpCvC,WAAOwC,iBAAiB;AAAA,MAACC,SAASF,MAAMnC,QAAQqC;AAAAA,IAAAA,CAAQ,GACxDzC,OAAO0C,uBAAuB;AAAA,MAACC,eAAeJ,MAAMnC,QAAQuC;AAAAA,IAAAA,CAAc;AAAA,EAAA,CAC3E,GAEM,CACL1C,eAAe;AAAA,IACbC,IAAI;AAAA,IACJC,OAAOA,CAAC;AAAA,MAACC;AAAAA,MAASC;AAAAA,IAAAA,MAAW;AAC3B,UAAIA,MAAMuC,SAAS;AACV,eAAA;AAKT,UAAI,CAFgBd,eAAee,KAAKxC,MAAMuC,IAAI;AAGzC,eAAA;AAAA,UAACE,QAAQ,CAAA;AAAA,QAAE;AAGdC,YAAAA,aAAapC,kBAA4B;AAAA,QAACP;AAAAA,MAAAA,CAAQ,GAElD4C,eAAe,GADFrC,mBAA6B;AAAA,QAACP;AAAAA,MAAAA,CAAQ,CACvB,GAAGC,MAAMuC,IAAI,GAAGK,MAChDlB,oBACF,IAAI,CAAC;AAED,aAAA,CAACgB,cAAcC,iBAAiBE,SAC3B;AAAA,QAACJ,QAAQ,CAAA;AAAA,MAAA,IAKX;AAAA,QAACA,QAFO9C,OAAOmD,YAAY;AAAA,UAACC,SAASJ;AAAAA,QAAa,CAAA;AAAA,MAE3C;AAAA,IAChB;AAAA,IACA5B,SAAS,CACP,CAACC,GAAGgC,WAAW,CACb;AAAA,MACE9B,MAAM;AAAA,MACN+B,QAAQA,MAAM;AACZpB,yBAAiBqB,KAAK;AAAA,UACpBhC,MAAM;AAAA,UACNkB,SAASY,OAAOP;AAAAA,QAAAA,CACjB;AAAA,MAAA;AAAA,IACH,CACD,CACF;AAAA,EAEJ,CAAA,GACD7C,eAAe;AAAA,IACbC,IAAI;AAAA,IACJC,OAAOA,CAAC;AAAA,MAACC;AAAAA,MAASC;AAAAA,IAAAA,MAAW;AAGvB,UAFYA,MAAMuC,SAAS;AAGtB,eAAA;AAGT,YAAMH,UAAUP,iBAAiBsB,YAAAA,EAAcpD,QAAQqC,SACjDE,gBACJT,iBAAiBsB,YAAY,EAAEpD,QAAQuC,eACnCc,QAAQhB,QAAQE,aAAa,IAC/B3C,OAAO0D,WAAW;AAAA,QAACT,OAAOR,QAAQE,aAAa;AAAA,MAAE,CAAA,IACjDO,QAEEH,aAAapC,kBAA4B;AAAA,QAACP;AAAAA,MAAAA,CAAQ,GAClDuD,aAAahD,mBAA6B;AAAA,QAACP;AAAAA,MAAAA,CAAQ,GACnD4C,eAAe,GAAGW,UAAU,IAAIV,MAAMjB,UAAU,IAAI,CAAC;AAEvD,UAAA,CAACe,cAAcC,iBAAiBE;AAC3B,eAAA;AAGHU,YAAAA,oBAAoBZ,aAAapB,SAAS;AAEhD,aAAI6B,QACK;AAAA,QACLV;AAAAA,QACAU;AAAAA,QACAG;AAAAA,QACAC,kBAAkBF,WAAW/B,SAAS;AAAA,MAInC,IAAA;AAAA,IACT;AAAA,IACAR,SAAS,CACP,MAAM,CACJ;AAAA,MACEG,MAAM;AAAA,MACNqB,MAAM;AAAA,IAAA,CACP,GAEH,CAACvB,GAAGgC,WAAW,CACb;AAAA,MACE9B,MAAM;AAAA,MACN+B,QAAQA,MAAM;AACZpB,yBAAiBqB,KAAK;AAAA,UAAChC,MAAM;AAAA,QAAA,CAAS;AAAA,MAAA;AAAA,IACxC,GAEF;AAAA,MACEA,MAAM;AAAA,MACNuC,QAAQ;AAAA,QACN3C,MAAMkC,OAAON,WAAW5B;AAAAA,QACxB4C,QAAQV,OAAOQ,mBAAmBR,OAAOO;AAAAA,MAC3C;AAAA,MACAI,OAAO;AAAA,QACL7C,MAAMkC,OAAON,WAAW5B;AAAAA,QACxB4C,QAAQV,OAAOQ;AAAAA,MAAAA;AAAAA,IACjB,GAEF;AAAA,MACEtC,MAAM;AAAA,MACNqB,MAAMS,OAAOI;AAAAA,IAAAA,CACd,CACF;AAAA,EAEJ,CAAA,GACDxD,eAAe;AAAA,IACbC,IAAI;AAAA,IACJC,OAAOA,CAAC;AAAA,MAACC;AAAAA,MAASC;AAAAA,IAAAA,MAAW;AAC3B,YAAMoC,UAAUP,iBAAiBsB,YAAY,EAAEpD,QAAQqC;AAEvD,UAAIA,QAAQb,WAAW;AACd,eAAA;AAGT,YAAMqC,UAAU1D,SAAS,SAASF,MAAMI,aAAa,GAC/CyD,UAAU7D,MAAMI,cAAc0D,QAAQ,KACtCC,cAActC,eAAee,KAAKxC,MAAMI,cAAc0D,GAAG;AAE/D,UAAIF,WAAWC,WAAWE;AACjB,eAAA;AAGHC,YAAAA,cAAc9D,SAAS,aAAaF,MAAMI,aAAa,GACvD6D,YAAY/D,SAAS,WAAWF,MAAMI,aAAa,GACnD8D,UAAUhE,SAAS,SAASF,MAAMI,aAAa,GAC/C+D,QAAQjE,SAAS,OAAOF,MAAMI,aAAa;AAEjD,UAAI8D,WAAWC,OAAO;AACd7B,cAAAA,gBACJT,iBAAiBsB,YAAAA,EAAcpD,QAAQuC,eAEnCc,QAAQhB,QAAQE,aAAa,IAC/B3C,OAAO0D,WAAW;AAAA,UAACT,OAAOR,QAAQE,aAAa;AAAA,QAAE,CAAA,IACjDO;AAEJ,YAAI,CAACO;AACI,iBAAA;AAGHV,cAAAA,aAAapC,kBAA4B;AAAA,UAACP;AAAAA,QAAAA,CAAQ,GAClDuD,aAAahD,mBAA6B;AAAA,UAACP;AAAAA,QAAAA,CAAQ,GACnD4C,eAAeW,WAAWV,MAAMlB,oBAAoB,IAAI,CAAC;AAE3D,YAAA,CAACgB,cAAcC,iBAAiBE;AAC3B,iBAAA;AAGHU,cAAAA,oBAAoBZ,aAAapB,SAAS;AAEhD,eAAI6B,QACK;AAAA,UACLgB,QAAQ;AAAA,UACR1B;AAAAA,UACAU;AAAAA,UACAG;AAAAA,UACAC,kBAAkBF,WAAW/B;AAAAA,QAI1B,IAAA;AAAA,MAAA;AAGLyC,aAAAA,eAAe5B,QAAQb,SAAS,IAC3B;AAAA,QAAC6C,QAAQ;AAAA,MAGdH,IAAAA,aAAa7B,QAAQb,SAAS,IACzB;AAAA,QAAC6C,QAAQ;AAAA,MAAA,IAGX;AAAA,QAACA,QAAQ;AAAA,MAAgB;AAAA,IAClC;AAAA,IACArD,SAAS,CACP,CAACC,GAAGgC,WACEA,OAAOoB,WAAW,WACb,CACL;AAAA,MACElD,MAAM;AAAA,MACN+B,QAAQA,MAAM;AACZpB,yBAAiBqB,KAAK;AAAA,UAAChC,MAAM;AAAA,QAAA,CAAS;AAAA,MAAA;AAAA,IACxC,GAEF;AAAA,MACEA,MAAM;AAAA,MACNuC,QAAQ;AAAA,QACN3C,MAAMkC,OAAON,WAAW5B;AAAAA,QACxB4C,QAAQV,OAAOQ,mBAAmBR,OAAOO;AAAAA,MAC3C;AAAA,MACAI,OAAO;AAAA,QACL7C,MAAMkC,OAAON,WAAW5B;AAAAA,QACxB4C,QAAQV,OAAOQ;AAAAA,MAAAA;AAAAA,IACjB,GAEF;AAAA,MACEtC,MAAM;AAAA,MACNqB,MAAMS,OAAOI;AAAAA,IAAAA,CACd,IAIDJ,OAAOoB,WAAW,gBACb;AAAA;AAAA;AAAA,MAGL;AAAA,QACElD,MAAM;AAAA,MACR;AAAA,MACA;AAAA,QACEA,MAAM;AAAA,QACN+B,QAAQA,MAAM;AACZpB,2BAAiBqB,KAAK;AAAA,YAAChC,MAAM;AAAA,UAAA,CAAc;AAAA,QAAA;AAAA,MAC7C;AAAA,IACF,IAIA8B,OAAOoB,WAAW,kBACb;AAAA;AAAA;AAAA,MAGL;AAAA,QACElD,MAAM;AAAA,MACR;AAAA,MACA;AAAA,QACEA,MAAM;AAAA,QACN+B,QAAQA,MAAM;AACZpB,2BAAiBqB,KAAK;AAAA,YAAChC,MAAM;AAAA,UAAA,CAAgB;AAAA,QAAA;AAAA,MAC/C;AAAA,IACF,IAIG,CACL;AAAA,MACEA,MAAM;AAAA,MACN+B,QAAQA,MAAM;AACZpB,yBAAiBqB,KAAK;AAAA,UAAChC,MAAM;AAAA,QAAA,CAAQ;AAAA,MAAA;AAAA,IACvC,CACD,CAEJ;AAAA,EAEJ,CAAA,GACDtB,eAAe;AAAA,IACbC,IAAI;AAAA,IACJC,OAAOA,CAAC;AAAA,MAACC;AAAAA,MAASC;AAAAA,IAAAA,MAAW;AACvBA,UAAAA,MAAMqE,SAAS,eAIHxC,iBAAiBsB,cAAcpD,QAAQqC,QAE3Cb,WAAW;AACd,eAAA;AAGHmB,YAAAA,aAAapC,kBAA4B;AAAA,QAACP;AAAAA,MAAAA,CAAQ,GAClDuD,aAAahD,mBAA6B;AAAA,QAACP;AAAAA,MAAQ,CAAA,GACnD4C,eAAeW,WAClBgB,MAAM,GAAGhB,WAAW/B,SAAS,CAAC,EAC9BqB,MAAMlB,oBAAoB,IAAI,CAAC;AAE9B,aAAA,CAACgB,cAAcC,iBAAiBE,SAC3B;AAAA,QAACJ,QAAQ,CAAA;AAAA,MAAA,IAKX;AAAA,QAACA,QAFO9C,OAAOmD,YAAY;AAAA,UAACC,SAASJ;AAAAA,QAAa,CAAA;AAAA,MAE3C;AAAA,IAChB;AAAA,IACA5B,SAAS,CACP,CAACC,GAAGgC,WAAW,CACb;AAAA,MACE9B,MAAM;AAAA,MACN+B,QAAQA,MAAM;AACZpB,yBAAiBqB,KAAK;AAAA,UACpBhC,MAAM;AAAA,UACNkB,SAASY,OAAOP;AAAAA,QAAAA,CACjB;AAAA,MAAA;AAAA,IACH,CACD,CACF;AAAA,EAAA,CAEJ,CAAC;AAEN;AAEA,SAASV,2BAA+C;AACtD,SAAOwC,MAAM;AAAA,IACXC,OAAO;AAAA,MACLzE,SAAS,CAAC;AAAA,MAIV0E,QAAQ,CAAA;AAAA,IAQV;AAAA,IACA1D,SAAS;AAAA,MACP,kBAAkB2D,OAAO;AAAA,QACvBtC,SAASA,CAAC;AAAA,UAACpC;AAAAA,QACT2E,OAAAA,YAAY3E,OAAO,cAAc,GAC1BA,MAAMoC;AAAAA,MAAAA,CAEhB;AAAA,MACD,iBAAiBsC,OAAO;AAAA,QACtBtC,SAAS,CAAA;AAAA,MAAA,CACV;AAAA,MACD,wBAAwBsC,OAAO;AAAA,QAC7BpC,eAAe;AAAA,MAAA,CAChB;AAAA,MACD,4BAA4BoC,OAAO;AAAA,QACjCpC,eAAeA,CAAC;AAAA,UAACvC;AAAAA,QAAAA,MACXA,QAAQuC,kBAAkBvC,QAAQqC,QAAQb,SAAS,IAC9C,IAEFxB,QAAQuC,gBAAgB;AAAA,MAAA,CAElC;AAAA,MACD,4BAA4BoC,OAAO;AAAA,QACjCpC,eAAeA,CAAC;AAAA,UAACvC;AAAAA,QAAAA,MACXA,QAAQuC,kBAAkB,IACrBvC,QAAQqC,QAAQb,SAAS,IAE3BxB,QAAQuC,gBAAgB;AAAA,MAElC,CAAA;AAAA,IACH;AAAA,IACAsC,QAAQ;AAAA,MACN,cAAcC,CAAC;AAAA,QAAC9E;AAAAA,MAAAA,MAAaA,QAAQqC,QAAQb,WAAW;AAAA,IAAA;AAAA,EAE3D,CAAA,EAAEuD,cAAc;AAAA,IACfC,IAAI;AAAA,IACJhF,SAAS;AAAA,MACPqC,SAAS,CAAE;AAAA,MACXE,eAAe;AAAA,IACjB;AAAA,IACA0C,SAAS;AAAA,IACTC,QAAQ;AAAA,MACN,MAAQ;AAAA,QACNpF,IAAI;AAAA,UACF,gBAAgB;AAAA,YACdkB,SAAS;AAAA,YACTmE,QAAQ;AAAA,UAAA;AAAA,QACV;AAAA,MAEJ;AAAA,MACA,mBAAmB;AAAA,QACjBC,QAAQ;AAAA,UACNrF,OAAO;AAAA,UACPoF,QAAQ;AAAA,QACV;AAAA,QACAE,MAAM,CAAC,sBAAsB;AAAA,QAC7BvF,IAAI;AAAA,UACF,gBAAgB;AAAA,YACdkB,SAAS;AAAA,UACX;AAAA,UACA,iBAAiB;AAAA,YACfA,SAAS;AAAA,UACX;AAAA,UACA,eAAe;AAAA,YACbA,SAAS;AAAA,UACX;AAAA,UACA,OAAS;AAAA,YACPmE,QAAQ;AAAA,YACRnE,SAAS,CAAC,wBAAwB,eAAe;AAAA,UACnD;AAAA,UACA,QAAU;AAAA,YACRmE,QAAQ;AAAA,YACRnE,SAAS,CAAC,wBAAwB,eAAe;AAAA,UAAA;AAAA,QACnD;AAAA,MACF;AAAA,IACF;AAAA,EACF,CACD;AACH;ACvZO,SAASsE,oBAAoB1F,QAA6B;AAC/D,QAAM2F,uBAAuB1F,eAAe;AAAA,IAC1CC,IAAI;AAAA,IACJC,OAAOA,CAAC;AAAA,MAACC;AAAAA,MAASC;AAAAA,IAAAA,MAAW;AACrBuF,YAAAA,qBAAqBjF,qBAA+B;AAAA,QAACP;AAAAA,MAAAA,CAAQ,GAC7DwC,OAAOvC,MAAMwF,KAAKC,QAAQ,YAAY,GACtCC,MAAMC,aAAapD,IAAI,IAAIA,OAAOM,QAClC+C,aACJF,QAAQ7C,SACJlD,OAAOkG,iBAAiB;AAAA,QAACH;AAAAA,QAAKI,QAAQ/F,QAAQ+F;AAAAA,MAAO,CAAA,IACrDjD;AAEF+C,aAAAA,cAAc,CAACL,qBACV;AAAA,QAACK;AAAAA,MAGH,IAAA;AAAA,IACT;AAAA,IACA7E,SAAS,CACP,CAACC,GAAG;AAAA,MAAC4E;AAAAA,IAAAA,MAAgB,CACnB;AAAA,MACE1E,MAAM;AAAA,MACN0E;AAAAA,IAAAA,CACD,CACF;AAAA,EAAA,CAEJ,GACKG,mBAAmBnG,eAAe;AAAA,IACtCC,IAAI;AAAA,IACJC,OAAOA,CAAC;AAAA,MAACC;AAAAA,MAASC;AAAAA,IAAAA,MAAW;AACrBgG,YAAAA,YAAY1F,aAAuB;AAAA,QAACP;AAAAA,MAAAA,CAAQ,GAC5CwF,qBAAqBjF,qBAA+B;AAAA,QAACP;AAAAA,MAAAA,CAAQ;AAE/D,UAAA,CAACiG,aAAa,CAACT;AACV,eAAA;AAGT,YAAMhD,OAAOvC,MAAMwF,KAAKC,QAAQ,YAAY,GACtCC,MAAMC,aAAapD,IAAI,IAAIA,OAAOM,QAClC+C,aACJF,QAAQ7C,SACJlD,OAAOkG,iBAAiB;AAAA,QAACH;AAAAA,QAAKI,QAAQ/F,QAAQ+F;AAAAA,MAAO,CAAA,IACrDjD;AAEF6C,aAAAA,OAAOE,cAAcL,qBAChB;AAAA,QAACS;AAAAA,QAAWJ;AAAAA,QAAYF;AAAAA,MAG1B,IAAA;AAAA,IACT;AAAA,IACA3E,SAAS,CACP,CAACC,GAAG;AAAA,MAAC4E;AAAAA,MAAYF;AAAAA,IAAAA,MAAS,CACxB;AAAA,MACExE,MAAM;AAAA,MACNqB,MAAMmD;AAAAA,MACNO,aAAa,CAACL,UAAU;AAAA,IAAA,CACzB,CACF;AAAA,EAAA,CAEJ;AAEqB,SAAA,CAACN,sBAAsBS,gBAAgB;AAG/D;AAEA,SAASJ,aAAapD,MAAc;AAClC,MAAIoD,gBAAe;AACf,MAAA;AACEO,QAAAA,IAAI3D,IAAI,GACZoD,gBAAe;AAAA,EAAA,QACT;AAAA,EAAA;AACDA,SAAAA;AACT;AC9DO,SAASQ,wBAAwBxG,QAAiC;AACvE,QAAMyG,6BAA6BxG,eAAe;AAAA,IAChDC,IAAI;AAAA,IACJC,OAAOA,CAAC;AAAA,MAACC;AAAAA,MAASC;AAAAA,IAAAA,MAAW;AAGvB,UAFYA,MAAMuC,SAAS;AAGtB,eAAA;AAGHgD,YAAAA,qBAAqBjF,qBAA+B;AAAA,QAACP;AAAAA,MAAAA,CAAQ,GAC7DsG,iBAAiB/F,kBAA4B;AAAA,QAACP;AAAAA,MAAAA,CAAQ,GACtDiG,YAAY1F,aAAuB;AAAA,QAACP;AAAAA,MAAAA,CAAQ;AAElD,UAAI,CAACwF,sBAAsB,CAACc,kBAAkB,CAACL;AACtC,eAAA;AAGT,YAAMM,cAAcC,gCAAgC;AAAA,QAClDC,OAAOzG,QAAQyG;AAAAA,QACfC,gBAAgB;AAAA,UACd3F,MAAM,CACJ;AAAA,YAACJ,MAAM2F,eAAe5F,KAAKC;AAAAA,aAC3B,YACA;AAAA,YAACA,MAAMsF,UAAUvF,KAAKC;AAAAA,UAAAA,CAAK;AAAA,UAE7BgD,QAAQ3D,QAAQ2G,WAAW/C,MAAMD,UAAU;AAAA,QAAA;AAAA,MAC7C,CACD;AAED,UAAI,CAAC4C;AACI,eAAA;AAGT,YAAMK,YAAYC,iBAAiBP,eAAe5F,IAAI,GAChDoG,uBAAuBP,YAAY5C,WAAW,GAC9CoD,yBAAyB,KAAKtE,KAAKmE,SAAS,GAC5CI,kBAAkBpH,OAAOoH,kBAAkBhH,OAAO;AAGtD8G,aAAAA,wBACAC,0BACAC,oBAAoBlE,SAEb;AAAA,QAACwD;AAAAA,QAAgBW,OAAOD;AAAAA,MAG1B,IAAA;AAAA,IACT;AAAA,IACAhG,SAAS,CACP,MAAM,CACJ;AAAA,MACEG,MAAM;AAAA,MACNqB,MAAM;AAAA,IAAA,CACP,GAEH,CAACvB,GAAG;AAAA,MAACqF;AAAAA,MAAgBW;AAAAA,IAAAA,MAAW,CAC9B;AAAA,MACE9F,MAAM;AAAA,MACN+F,OAAO,CAAC,YAAY,OAAO;AAAA,MAC3BhG,IAAIoF,eAAevF;AAAAA,IAAAA,GAErB;AAAA,MACEI,MAAM;AAAA,MACN8F;AAAAA,MACA/F,IAAIoF,eAAevF;AAAAA,IAAAA,GAErB;AAAA,MACEI,MAAM;AAAA,MACNuC,QAAQ;AAAA,QACN3C,MAAMuF,eAAevF;AAAAA,QACrB4C,QAAQ;AAAA,MACV;AAAA,MACAC,OAAO;AAAA,QACL7C,MAAMuF,eAAevF;AAAAA,QACrB4C,QAAQ;AAAA,MAAA;AAAA,IACV,CACD,CACF;AAAA,EAAA,CAEJ,GACKwD,cAActH,eAAe;AAAA,IACjCC,IAAI;AAAA,IACJC,OAAOA,CAAC;AAAA,MAACC;AAAAA,MAASC;AAAAA,IAAAA,MAAW;AAC3B,YAAMmH,cACJnH,MAAMuC,SAAS,MACX,MACAvC,MAAMuC,SAAS,MACb,MACAvC,MAAMuC,SAAS,MACb,MACAM;AAEV,UAAIsE,gBAAgBtE;AACX,eAAA;AAGT,YAAMuE,WAAWzH,OAAO0H,uBAAuBtH,OAAO,GAChD2C,aAAapC,kBAA4B;AAAA,QAACP;AAAAA,MAAAA,CAAQ,GAClDwF,qBAAqBjF,qBAA+B;AAAA,QAACP;AAAAA,MAAAA,CAAQ;AAEnE,UAAI,CAACqH,YAAY,CAAC1E,cAAc,CAAC6C;AACxB,eAAA;AAGT,YAAMjC,aAAagE,mBAAmB;AAAA,QAACvH;AAAAA,MAAQ,CAAA,GACzCwH,iBAAiB;AAAA,QACrB9D,QAAQ;AAAA,UACN3C,MAAM4B,WAAW5B;AAAAA,UACjB4C,QAAQ;AAAA,QACV;AAAA,QACAC,OAAO;AAAA,UACL7C,MAAM4B,WAAW5B;AAAAA,UACjB4C,QAAQ;AAAA,QAAA;AAAA,MAEZ;AAEA,aAAIJ,eAAe,GAAG6D,WAAW,GAAGA,WAAW,KACtC;AAAA,QAACC;AAAAA,QAAU1E;AAAAA,QAAYyE;AAAAA,QAAaI;AAAAA,MAGtC,IAAA;AAAA,IACT;AAAA,IACAxG,SAAS,CACP,CAACC,GAAG;AAAA,MAACmG;AAAAA,IAAAA,MAAiB,CACpB;AAAA,MACEjG,MAAM;AAAA,MACNqB,MAAM4E;AAAAA,IAAAA,CACP,GAEH,CAACnG,GAAG;AAAA,MAACoG;AAAAA,MAAUG;AAAAA,IAAAA,MAAoB,CACjC;AAAA,MACErG,MAAM;AAAA,MACNsG,WAAW;AAAA,MACXC,aAAaL;AAAAA,IAAAA,GAEf;AAAA,MACElG,MAAM;AAAA,MACN,GAAGqG;AAAAA,IAAAA,CACJ,CACF;AAAA,EAAA,CAEJ,GACKG,qBAAqB9H,eAAe;AAAA,IACxCC,IAAI;AAAA,IACJC,OAAOA,CAAC;AAAA,MAACC;AAAAA,MAASC;AAAAA,IAAAA,MAAW;AACrBuC,YAAAA,OAAOvC,MAAMwF,KAAKC,QAAQ,YAAY,GACtCkC,WAAW,8BACXC,eAAerF,KAAKK,MAAM+E,QAAQ,IAAI,CAAC,GACvCP,WAAWzH,OAAO0H,uBAAuBtH,OAAO,GAChD2C,aAAapC,cAAwB;AAAA,QAACP;AAAAA,MAAAA,CAAQ;AAEpD,aAAI,CAAC6H,gBAAgB,CAACR,YAAY,CAAC1E,aAC1B,KAGF;AAAA,QAACkF;AAAAA,QAAcR;AAAAA,QAAU1E;AAAAA,MAAU;AAAA,IAC5C;AAAA,IACA3B,SAAS,CACP,CAACC,GAAG;AAAA,MAAC4G;AAAAA,IAAAA,MAAkB,CACrB;AAAA,MACE1G,MAAM;AAAA,MACNqB,MAAMqF;AAAAA,IAAAA,CACP,GAEH,CAAC5G,GAAG;AAAA,MAACoG;AAAAA,MAAU1E;AAAAA,IACbmF,MAAAA,wBAAwBnF,WAAWjC,IAAI,IACnC,CACE;AAAA,MACES,MAAM;AAAA,MACN4G,WAAW;AAAA,QAACC,UAAUrF,WAAWjC,KAAKsH;AAAAA,MAAQ;AAAA,MAC9CP,WAAW;AAAA,IAAA,GAEb;AAAA,MACEtG,MAAM;AAAA,MACNuG,aAAaL;AAAAA,MACbI,WAAW;AAAA,IAAA,GAEb;AAAA,MAACtG,MAAM;AAAA,MAAgB8G,WAAWtF,WAAW5B;AAAAA,IAAK,CAAA,IAEpD,CACE;AAAA,MACEI,MAAM;AAAA,MACNuG,aAAaL;AAAAA,MACbI,WAAW;AAAA,IAAA,CACZ,CACF;AAAA,EAAA,CAEV,GACKS,0BAA0BrI,eAAe;AAAA,IAC7CC,IAAI;AAAA,IACJC,OAAOA,CAAC;AAAA,MAACC;AAAAA,MAASC;AAAAA,IAAAA,MAAW;AAGvB,UAFYA,MAAMuC,SAAS;AAGtB,eAAA;AAGHgD,YAAAA,qBAAqBjF,qBAA+B;AAAA,QAACP;AAAAA,MAAAA,CAAQ,GAC7DsG,iBAAiB/F,kBAA4B;AAAA,QAACP;AAAAA,MAAAA,CAAQ,GACtDiG,YAAY1F,aAAuB;AAAA,QAACP;AAAAA,MAAAA,CAAQ;AAElD,UAAI,CAACwF,sBAAsB,CAACc,kBAAkB,CAACL;AACtC,eAAA;AAGT,YAAMM,cAAcC,gCAAgC;AAAA,QAClDC,OAAOzG,QAAQyG;AAAAA,QACfC,gBAAgB;AAAA,UACd3F,MAAM,CACJ;AAAA,YAACJ,MAAM2F,eAAe5F,KAAKC;AAAAA,aAC3B,YACA;AAAA,YAACA,MAAMsF,UAAUvF,KAAKC;AAAAA,UAAAA,CAAK;AAAA,UAE7BgD,QAAQ3D,QAAQ2G,WAAW/C,MAAMD,UAAU;AAAA,QAAA;AAAA,MAC7C,CACD;AAED,UAAI,CAAC4C;AACI,eAAA;AAGT,YAAMK,YAAYC,iBAAiBP,eAAe5F,IAAI,GAChDyH,wBAAwB,MAAMC,KAAKxB,SAAS,GAC5CyB,QAAQF,wBACVA,sBAAsB,CAAC,EAAE3G,SACzBsB;AAGA,UAF2ByD,YAAY5C,WAAW0E;AAG7C,eAAA;AAGT,YAAMpB,QACJoB,UAAUvF,SACNlD,OAAO0I,eAAe;AAAA,QAACvC,QAAQ/F,QAAQ+F;AAAAA,QAAQsC;AAAAA,MAAM,CAAA,IACrDvF;AAEFuF,aAAAA,UAAUvF,UAAamE,UAAUnE,SAC5B;AAAA,QACLwD;AAAAA,QACAW;AAAAA,QACAoB;AAAAA,MAIG,IAAA;AAAA,IACT;AAAA,IACArH,SAAS,CACP,CAAC;AAAA,MAACf;AAAAA,IAAAA,MAAW,CAACA,KAAK,GACnB,CAACgB,GAAG;AAAA,MAACqF;AAAAA,MAAgBW;AAAAA,MAAOoB;AAAAA,IAAAA,MAAW,CACrC;AAAA,MACElH,MAAM;AAAA,MACN+F,OAAO,CAAC,YAAY,OAAO;AAAA,MAC3BhG,IAAIoF,eAAevF;AAAAA,IAAAA,GAErB;AAAA,MACEI,MAAM;AAAA,MACN8F;AAAAA,MACA/F,IAAIoF,eAAevF;AAAAA,IAAAA,GAErB;AAAA,MACEI,MAAM;AAAA,MACNuC,QAAQ;AAAA,QACN3C,MAAMuF,eAAevF;AAAAA,QACrB4C,QAAQ;AAAA,MACV;AAAA,MACAC,OAAO;AAAA,QACL7C,MAAMuF,eAAevF;AAAAA,QACrB4C,QAAQ0E,QAAQ;AAAA,MAAA;AAAA,IAClB,CACD,CACF;AAAA,EAAA,CAEJ,GACKE,wBAAwB1I,eAAe;AAAA,IAC3CC,IAAI;AAAA,IACJC,OAAOA,CAAC;AAAA,MAACC;AAAAA,IAAAA,MAAa;AACdwF,YAAAA,qBAAqBjF,qBAA+B;AAAA,QAACP;AAAAA,MAAAA,CAAQ,GAC7DsG,iBAAiB/F,kBAA4B;AAAA,QAACP;AAAAA,MAAAA,CAAQ,GACtDiG,YAAY1F,aAAuB;AAAA,QAACP;AAAAA,MAAAA,CAAQ;AAElD,UAAI,CAACwF,sBAAsB,CAACc,kBAAkB,CAACL;AACtC,eAAA;AAGT,YAAMuC,wBACJlC,eAAe5F,KAAKsH,SAAS,CAAC,EAAErH,SAASsF,UAAUvF,KAAKC,QACxDX,QAAQ2G,WAAW/C,MAAMD,WAAW,GAEhC8E,eAAe7I,OAAO6I,eAAezI,OAAO;AAElD,aACEwI,yBACAC,gBACAnC,eAAe5F,KAAKuG,UAAUwB,eAEvB;AAAA,QAACA;AAAAA,QAAcnC;AAAAA,MAGjB,IAAA;AAAA,IACT;AAAA,IACAtF,SAAS,CACP,CAACC,GAAG;AAAA,MAACwH;AAAAA,MAAcnC;AAAAA,IAAAA,MAAoB,CACrC;AAAA,MACEnF,MAAM;AAAA,MACN8F,OAAOwB;AAAAA,MACPvH,IAAIoF,eAAevF;AAAAA,IAAAA,CACpB,CACF;AAAA,EAAA,CAEJ,GACK2H,uBAAuB7I,eAAe;AAAA,IAC1CC,IAAI;AAAA,IACJC,OAAOA,CAAC;AAAA,MAACC;AAAAA,MAASC;AAAAA,IAAAA,MAAW;AAGvB,UAFYA,MAAMuC,SAAS;AAGtB,eAAA;AAGHgD,YAAAA,qBAAqBjF,qBAA+B;AAAA,QAACP;AAAAA,MAAAA,CAAQ,GAC7DsG,iBAAiB/F,kBAA4B;AAAA,QAACP;AAAAA,MAAAA,CAAQ,GACtDiG,YAAY1F,aAAuB;AAAA,QAACP;AAAAA,MAAAA,CAAQ;AAElD,UAAI,CAACwF,sBAAsB,CAACc,kBAAkB,CAACL;AACtC,eAAA;AAGT,YAAMM,cAAcC,gCAAgC;AAAA,QAClDC,OAAOzG,QAAQyG;AAAAA,QACfC,gBAAgB;AAAA,UACd3F,MAAM,CACJ;AAAA,YAACJ,MAAM2F,eAAe5F,KAAKC;AAAAA,aAC3B,YACA;AAAA,YAACA,MAAMsF,UAAUvF,KAAKC;AAAAA,UAAAA,CAAK;AAAA,UAE7BgD,QAAQ3D,QAAQ2G,WAAW/C,MAAMD,UAAU;AAAA,QAAA;AAAA,MAC7C,CACD;AAED,UAAI,CAAC4C;AACI,eAAA;AAGHK,YAAAA,YAAYC,iBAAiBP,eAAe5F,IAAI,GAChD+H,eAAe7I,OAAO6I,eAAezI,OAAO,GAC5C2I,yBAAyB,UAAUlG,KAAKmE,SAAS,GACjDgC,qBAAqBhJ,OAAOgJ,qBAAqB5I,OAAO,GACxD6I,+BAA+BtC,YAAY5C,WAAW;AAG1D8E,UAAAA,gBACAI,gCACAF,0BACAC,uBAAuB9F;AAEhB,eAAA;AAAA,UACLwD;AAAAA,UACAwC,UAAUF;AAAAA,UACVG,gBAAgB;AAAA,UAChB9B,OAAOwB;AAAAA,QACT;AAGF,YAAMO,uBAAuB,OAAOvG,KAAKmE,SAAS,GAC5CqC,mBAAmBrJ,OAAOqJ,mBAAmBjJ,OAAO,GACpDkJ,6BAA6B3C,YAAY5C,WAAW;AAE1D,aACE8E,gBACAS,8BACAF,wBACAC,qBAAqBnG,SAEd;AAAA,QACLwD;AAAAA,QACAwC,UAAUG;AAAAA,QACVF,gBAAgB;AAAA,QAChB9B,OAAOwB;AAAAA,MAIJ,IAAA;AAAA,IACT;AAAA,IACAzH,SAAS,CACP,CAAC;AAAA,MAACf;AAAAA,IAAAA,MAAW,CAACA,KAAK,GACnB,CAACgB,GAAG;AAAA,MAACqF;AAAAA,MAAgBW;AAAAA,MAAO6B;AAAAA,MAAUC;AAAAA,IAAAA,MAAoB,CACxD;AAAA,MACE5H,MAAM;AAAA,MACN2H;AAAAA,MACAT,OAAO;AAAA,MACPpB;AAAAA,MACA/F,IAAIoF,eAAevF;AAAAA,IAAAA,GAErB;AAAA,MACEI,MAAM;AAAA,MACNuC,QAAQ;AAAA,QACN3C,MAAMuF,eAAevF;AAAAA,QACrB4C,QAAQ;AAAA,MACV;AAAA,MACAC,OAAO;AAAA,QACL7C,MAAMuF,eAAevF;AAAAA,QACrB4C,QAAQoF,iBAAiB;AAAA,MAAA;AAAA,IAC3B,CACD,CACF;AAAA,EAAA,CAEJ;AAWD,SAT0B,CACxB1C,4BACA6B,yBACAf,aACAQ,oBACAY,uBACAG,oBAAoB;AAIxB;"}
1
+ {"version":3,"file":"index.js","sources":["../../src/behaviors/behavior.code-editor.ts","../../src/behaviors/behavior.emoji-picker.ts","../../src/utils/looks-like-url.ts","../../src/behaviors/behavior.links.ts","../../src/behaviors/behavior.markdown.ts"],"sourcesContent":["import * as selectors from '../selectors'\nimport {isHotkey} from '../utils/is-hotkey'\nimport {defineBehavior} from './behavior.types'\n\n/**\n * @beta\n */\nexport type CodeEditorBehaviorsConfig = {\n moveBlockUpShortcut: string\n moveBlockDownShortcut: string\n}\n\n/**\n * @beta\n */\nexport function createCodeEditorBehaviors(config: CodeEditorBehaviorsConfig) {\n return [\n defineBehavior({\n on: 'key.down',\n guard: ({context, event}) => {\n const isMoveUpShortcut = isHotkey(\n config.moveBlockUpShortcut,\n event.keyboardEvent,\n )\n const firstBlock = selectors.getFirstBlock({context})\n const selectedBlocks = selectors.getSelectedBlocks({context})\n const blocksAbove =\n firstBlock?.node._key !== selectedBlocks[0]?.node._key\n\n if (!isMoveUpShortcut || !blocksAbove) {\n return false\n }\n\n return {paths: selectedBlocks.map((block) => block.path)}\n },\n actions: [\n (_, {paths}) =>\n paths.map((at) => ({\n type: 'move.block up',\n at,\n })),\n ],\n }),\n defineBehavior({\n on: 'key.down',\n guard: ({context, event}) => {\n const isMoveDownShortcut = isHotkey(\n config.moveBlockDownShortcut,\n event.keyboardEvent,\n )\n const lastBlock = selectors.getLastBlock({context})\n const selectedBlocks = selectors.getSelectedBlocks({context})\n const blocksBelow =\n lastBlock?.node._key !==\n selectedBlocks[selectedBlocks.length - 1]?.node._key\n\n if (!isMoveDownShortcut || !blocksBelow) {\n return false\n }\n\n return {paths: selectedBlocks.map((block) => block.path).reverse()}\n },\n actions: [\n (_, {paths}) =>\n paths.map((at) => ({\n type: 'move.block down',\n at,\n })),\n ],\n }),\n ]\n}\n","import {assertEvent, assign, createActor, setup} from 'xstate'\nimport * as selectors from '../selectors'\nimport {isHotkey} from '../utils/is-hotkey'\nimport {defineBehavior} from './behavior.types'\n\nconst emojiCharRegEx = /^[a-zA-Z-_0-9]{1}$/\nconst incompleteEmojiRegEx = /:([a-zA-Z-_0-9]+)$/\nconst emojiRegEx = /:([a-zA-Z-_0-9]+):$/\n\n/**\n * @beta\n */\nexport type EmojiPickerBehaviorsConfig<TEmojiMatch> = {\n /**\n * Match emojis by keyword.\n */\n matchEmojis: ({keyword}: {keyword: string}) => Array<TEmojiMatch>\n onMatchesChanged: ({matches}: {matches: Array<TEmojiMatch>}) => void\n onSelectedIndexChanged: ({selectedIndex}: {selectedIndex: number}) => void\n /**\n * Parse an emoji match to a string that will be inserted into the editor.\n */\n parseMatch: ({match}: {match: TEmojiMatch}) => string | undefined\n}\n\n/**\n * @beta\n */\nexport function createEmojiPickerBehaviors<TEmojiMatch>(\n config: EmojiPickerBehaviorsConfig<TEmojiMatch>,\n) {\n const emojiPickerActor = createActor(createEmojiPickerMachine<TEmojiMatch>())\n emojiPickerActor.start()\n emojiPickerActor.subscribe((state) => {\n config.onMatchesChanged({matches: state.context.matches})\n config.onSelectedIndexChanged({selectedIndex: state.context.selectedIndex})\n })\n\n return [\n defineBehavior({\n on: 'insert.text',\n guard: ({context, event}) => {\n if (event.text === ':') {\n return false\n }\n\n const isEmojiChar = emojiCharRegEx.test(event.text)\n\n if (!isEmojiChar) {\n return {emojis: []}\n }\n\n const focusBlock = selectors.getFocusTextBlock({context})\n const textBefore = selectors.getBlockTextBefore({context})\n const emojiKeyword = `${textBefore}${event.text}`.match(\n incompleteEmojiRegEx,\n )?.[1]\n\n if (!focusBlock || emojiKeyword === undefined) {\n return {emojis: []}\n }\n\n const emojis = config.matchEmojis({keyword: emojiKeyword})\n\n return {emojis}\n },\n actions: [\n (_, params) => [\n {\n type: 'effect',\n effect: () => {\n emojiPickerActor.send({\n type: 'emojis found',\n matches: params.emojis,\n })\n },\n },\n ],\n ],\n }),\n defineBehavior({\n on: 'insert.text',\n guard: ({context, event}) => {\n const isColon = event.text === ':'\n\n if (!isColon) {\n return false\n }\n\n const matches = emojiPickerActor.getSnapshot().context.matches\n const selectedIndex =\n emojiPickerActor.getSnapshot().context.selectedIndex\n const emoji = matches[selectedIndex]\n ? config.parseMatch({match: matches[selectedIndex]})\n : undefined\n\n const focusBlock = selectors.getFocusTextBlock({context})\n const textBefore = selectors.getBlockTextBefore({context})\n const emojiKeyword = `${textBefore}:`.match(emojiRegEx)?.[1]\n\n if (!focusBlock || emojiKeyword === undefined) {\n return false\n }\n\n const emojiStringLength = emojiKeyword.length + 2\n\n if (emoji) {\n return {\n focusBlock,\n emoji,\n emojiStringLength,\n textBeforeLength: textBefore.length + 1,\n }\n }\n\n return false\n },\n actions: [\n () => [\n {\n type: 'insert.text',\n text: ':',\n },\n ],\n (_, params) => [\n {\n type: 'effect',\n effect: () => {\n emojiPickerActor.send({type: 'select'})\n },\n },\n {\n type: 'delete.text',\n anchor: {\n path: params.focusBlock.path,\n offset: params.textBeforeLength - params.emojiStringLength,\n },\n focus: {\n path: params.focusBlock.path,\n offset: params.textBeforeLength,\n },\n },\n {\n type: 'insert.text',\n text: params.emoji,\n },\n ],\n ],\n }),\n defineBehavior({\n on: 'key.down',\n guard: ({context, event}) => {\n const matches = emojiPickerActor.getSnapshot().context.matches\n\n if (matches.length === 0) {\n return false\n }\n\n const isShift = isHotkey('Shift', event.keyboardEvent)\n const isColon = event.keyboardEvent.key === ':'\n const isEmojiChar = emojiCharRegEx.test(event.keyboardEvent.key)\n\n if (isShift || isColon || isEmojiChar) {\n return false\n }\n\n const isArrowDown = isHotkey('ArrowDown', event.keyboardEvent)\n const isArrowUp = isHotkey('ArrowUp', event.keyboardEvent)\n const isEnter = isHotkey('Enter', event.keyboardEvent)\n const isTab = isHotkey('Tab', event.keyboardEvent)\n\n if (isEnter || isTab) {\n const selectedIndex =\n emojiPickerActor.getSnapshot().context.selectedIndex\n\n const emoji = matches[selectedIndex]\n ? config.parseMatch({match: matches[selectedIndex]})\n : undefined\n\n if (!emoji) {\n return false\n }\n\n const focusBlock = selectors.getFocusTextBlock({context})\n const textBefore = selectors.getBlockTextBefore({context})\n const emojiKeyword = textBefore.match(incompleteEmojiRegEx)?.[1]\n\n if (!focusBlock || emojiKeyword === undefined) {\n return false\n }\n\n const emojiStringLength = emojiKeyword.length + 1\n\n if (emoji) {\n return {\n action: 'select' as const,\n focusBlock,\n emoji,\n emojiStringLength,\n textBeforeLength: textBefore.length,\n }\n }\n\n return false\n }\n\n if (isArrowDown && matches.length > 0) {\n return {action: 'navigate down' as const}\n }\n\n if (isArrowUp && matches.length > 0) {\n return {action: 'navigate up' as const}\n }\n\n return {action: 'reset' as const}\n },\n actions: [\n (_, params) => {\n if (params.action === 'select') {\n return [\n {\n type: 'effect',\n effect: () => {\n emojiPickerActor.send({type: 'select'})\n },\n },\n {\n type: 'delete.text',\n anchor: {\n path: params.focusBlock.path,\n offset: params.textBeforeLength - params.emojiStringLength,\n },\n focus: {\n path: params.focusBlock.path,\n offset: params.textBeforeLength,\n },\n },\n {\n type: 'insert.text',\n text: params.emoji,\n },\n ]\n }\n\n if (params.action === 'navigate up') {\n return [\n // If we are navigating then we want to hijack the key event and\n // turn it into a noop.\n {\n type: 'noop',\n },\n {\n type: 'effect',\n effect: () => {\n emojiPickerActor.send({type: 'navigate up'})\n },\n },\n ]\n }\n\n if (params.action === 'navigate down') {\n return [\n // If we are navigating then we want to hijack the key event and\n // turn it into a noop.\n {\n type: 'noop',\n },\n {\n type: 'effect',\n effect: () => {\n emojiPickerActor.send({type: 'navigate down'})\n },\n },\n ]\n }\n\n return [\n {\n type: 'effect',\n effect: () => {\n emojiPickerActor.send({type: 'reset'})\n },\n },\n ]\n },\n ],\n }),\n defineBehavior({\n on: 'delete.backward',\n guard: ({context, event}) => {\n if (event.unit !== 'character') {\n return false\n }\n\n const matches = emojiPickerActor.getSnapshot().context.matches\n\n if (matches.length === 0) {\n return false\n }\n\n const focusBlock = selectors.getFocusTextBlock({context})\n const textBefore = selectors.getBlockTextBefore({context})\n const emojiKeyword = textBefore\n .slice(0, textBefore.length - 1)\n .match(incompleteEmojiRegEx)?.[1]\n\n if (!focusBlock || emojiKeyword === undefined) {\n return {emojis: []}\n }\n\n const emojis = config.matchEmojis({keyword: emojiKeyword})\n\n return {emojis}\n },\n actions: [\n (_, params) => [\n {\n type: 'effect',\n effect: () => {\n emojiPickerActor.send({\n type: 'emojis found',\n matches: params.emojis,\n })\n },\n },\n ],\n ],\n }),\n ]\n}\n\nfunction createEmojiPickerMachine<TEmojiSearchResult>() {\n return setup({\n types: {\n context: {} as {\n matches: Array<TEmojiSearchResult>\n selectedIndex: number\n },\n events: {} as\n | {\n type: 'emojis found'\n matches: Array<TEmojiSearchResult>\n }\n | {\n type: 'navigate down' | 'navigate up' | 'select' | 'reset'\n },\n },\n actions: {\n 'assign matches': assign({\n matches: ({event}) => {\n assertEvent(event, 'emojis found')\n return event.matches\n },\n }),\n 'reset matches': assign({\n matches: [],\n }),\n 'reset selected index': assign({\n selectedIndex: 0,\n }),\n 'increment selected index': assign({\n selectedIndex: ({context}) => {\n if (context.selectedIndex === context.matches.length - 1) {\n return 0\n }\n return context.selectedIndex + 1\n },\n }),\n 'decrement selected index': assign({\n selectedIndex: ({context}) => {\n if (context.selectedIndex === 0) {\n return context.matches.length - 1\n }\n return context.selectedIndex - 1\n },\n }),\n },\n guards: {\n 'no matches': ({context}) => context.matches.length === 0,\n },\n }).createMachine({\n id: 'emoji picker',\n context: {\n matches: [],\n selectedIndex: 0,\n },\n initial: 'idle',\n states: {\n 'idle': {\n on: {\n 'emojis found': {\n actions: 'assign matches',\n target: 'showing matches',\n },\n },\n },\n 'showing matches': {\n always: {\n guard: 'no matches',\n target: 'idle',\n },\n exit: ['reset selected index'],\n on: {\n 'emojis found': {\n actions: 'assign matches',\n },\n 'navigate down': {\n actions: 'increment selected index',\n },\n 'navigate up': {\n actions: 'decrement selected index',\n },\n 'reset': {\n target: 'idle',\n actions: ['reset selected index', 'reset matches'],\n },\n 'select': {\n target: 'idle',\n actions: ['reset selected index', 'reset matches'],\n },\n },\n },\n },\n })\n}\n","export function looksLikeUrl(text: string) {\n let looksLikeUrl = false\n try {\n try {\n const url = new URL(text)\n\n if (!sensibleProtocols.includes(url.protocol)) {\n return false\n }\n\n const probablyHasTld =\n url.hostname.length > 0 ? url.hostname.includes('.') : true\n\n looksLikeUrl = probablyHasTld\n } catch {\n const url = new URL(`https://${text}`)\n\n if (!sensibleProtocols.includes(url.protocol)) {\n return false\n }\n\n const probablyHasTld =\n url.hostname.length > 0 ? url.hostname.includes('.') : true\n\n looksLikeUrl = probablyHasTld\n }\n } catch {}\n return looksLikeUrl\n}\n\nconst sensibleProtocols = ['http:', 'https:', 'mailto:', 'tel:']\n","import type {EditorSchema} from '../editor/define-schema'\nimport * as selectors from '../selectors'\nimport {looksLikeUrl} from '../utils/looks-like-url'\nimport {defineBehavior} from './behavior.types'\n\n/**\n * @beta\n */\nexport type LinkBehaviorsConfig = {\n linkAnnotation?: (context: {\n schema: EditorSchema\n url: string\n }) => {name: string; value: {[prop: string]: unknown}} | undefined\n}\n\n/**\n * @beta\n */\nexport function createLinkBehaviors(config: LinkBehaviorsConfig) {\n const pasteLinkOnSelection = defineBehavior({\n on: 'paste',\n guard: ({context, event}) => {\n const selectionCollapsed = selectors.isSelectionCollapsed({context})\n const text = event.data.getData('text/plain')\n const url = looksLikeUrl(text) ? text : undefined\n const annotation =\n url !== undefined\n ? config.linkAnnotation?.({url, schema: context.schema})\n : undefined\n\n if (annotation && !selectionCollapsed) {\n return {annotation}\n }\n\n return false\n },\n actions: [\n (_, {annotation}) => [\n {\n type: 'annotation.add',\n annotation,\n },\n ],\n ],\n })\n const pasteLinkAtCaret = defineBehavior({\n on: 'paste',\n guard: ({context, event}) => {\n const focusSpan = selectors.getFocusSpan({context})\n const selectionCollapsed = selectors.isSelectionCollapsed({context})\n\n if (!focusSpan || !selectionCollapsed) {\n return false\n }\n\n const text = event.data.getData('text/plain')\n const url = looksLikeUrl(text) ? text : undefined\n const annotation =\n url !== undefined\n ? config.linkAnnotation?.({url, schema: context.schema})\n : undefined\n\n if (url && annotation && selectionCollapsed) {\n return {focusSpan, annotation, url}\n }\n\n return false\n },\n actions: [\n (_, {annotation, url}) => [\n {\n type: 'insert.span',\n text: url,\n annotations: [annotation],\n },\n ],\n ],\n })\n\n const linkBehaviors = [pasteLinkOnSelection, pasteLinkAtCaret]\n\n return linkBehaviors\n}\n","import {isPortableTextTextBlock} from '@sanity/types'\nimport type {EditorSchema} from '../editor/define-schema'\nimport {getTextBlockText} from '../editor/utils/utils'\nimport {spanSelectionPointToBlockOffset} from '../editor/utils/utils.block-offset'\nimport * as selectors from '../selectors'\nimport {getBlockTextBefore} from '../selectors/selector.get-text-before'\nimport {defineBehavior} from './behavior.types'\n\n/**\n * @beta\n */\nexport type MarkdownBehaviorsConfig = {\n horizontalRuleObject?: (context: {\n schema: EditorSchema\n }) => {name: string; value?: {[prop: string]: unknown}} | undefined\n defaultStyle?: (context: {schema: EditorSchema}) => string | undefined\n headingStyle?: (context: {\n schema: EditorSchema\n level: number\n }) => string | undefined\n blockquoteStyle?: (context: {schema: EditorSchema}) => string | undefined\n unorderedListStyle?: (context: {schema: EditorSchema}) => string | undefined\n orderedListStyle?: (context: {schema: EditorSchema}) => string | undefined\n}\n\n/**\n * @beta\n */\nexport function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {\n const automaticBlockquoteOnSpace = defineBehavior({\n on: 'insert.text',\n guard: ({context, event}) => {\n const isSpace = event.text === ' '\n\n if (!isSpace) {\n return false\n }\n\n const selectionCollapsed = selectors.isSelectionCollapsed({context})\n const focusTextBlock = selectors.getFocusTextBlock({context})\n const focusSpan = selectors.getFocusSpan({context})\n\n if (!selectionCollapsed || !focusTextBlock || !focusSpan) {\n return false\n }\n\n const blockOffset = spanSelectionPointToBlockOffset({\n value: context.value,\n selectionPoint: {\n path: [\n {_key: focusTextBlock.node._key},\n 'children',\n {_key: focusSpan.node._key},\n ],\n offset: context.selection?.focus.offset ?? 0,\n },\n })\n\n if (!blockOffset) {\n return false\n }\n\n const blockText = getTextBlockText(focusTextBlock.node)\n const caretAtTheEndOfQuote = blockOffset.offset === 1\n const looksLikeMarkdownQuote = /^>/.test(blockText)\n const blockquoteStyle = config.blockquoteStyle?.(context)\n\n if (\n caretAtTheEndOfQuote &&\n looksLikeMarkdownQuote &&\n blockquoteStyle !== undefined\n ) {\n return {focusTextBlock, style: blockquoteStyle}\n }\n\n return false\n },\n actions: [\n () => [\n {\n type: 'insert.text',\n text: ' ',\n },\n ],\n (_, {focusTextBlock, style}) => [\n {\n type: 'text block.unset',\n props: ['listItem', 'level'],\n at: focusTextBlock.path,\n },\n {\n type: 'text block.set',\n style,\n at: focusTextBlock.path,\n },\n {\n type: 'delete.text',\n anchor: {\n path: focusTextBlock.path,\n offset: 0,\n },\n focus: {\n path: focusTextBlock.path,\n offset: 2,\n },\n },\n ],\n ],\n })\n const automaticHr = defineBehavior({\n on: 'insert.text',\n guard: ({context, event}) => {\n const hrCharacter =\n event.text === '-'\n ? '-'\n : event.text === '*'\n ? '*'\n : event.text === '_'\n ? '_'\n : undefined\n\n if (hrCharacter === undefined) {\n return false\n }\n\n const hrObject = config.horizontalRuleObject?.(context)\n const focusBlock = selectors.getFocusTextBlock({context})\n const selectionCollapsed = selectors.isSelectionCollapsed({context})\n\n if (!hrObject || !focusBlock || !selectionCollapsed) {\n return false\n }\n\n const textBefore = getBlockTextBefore({context})\n const hrBlockOffsets = {\n anchor: {\n path: focusBlock.path,\n offset: 0,\n },\n focus: {\n path: focusBlock.path,\n offset: 3,\n },\n }\n\n if (textBefore === `${hrCharacter}${hrCharacter}`) {\n return {hrObject, focusBlock, hrCharacter, hrBlockOffsets}\n }\n\n return false\n },\n actions: [\n (_, {hrCharacter}) => [\n {\n type: 'insert.text',\n text: hrCharacter,\n },\n ],\n (_, {hrObject, hrBlockOffsets}) => [\n {\n type: 'insert.block object',\n placement: 'before',\n blockObject: hrObject,\n },\n {\n type: 'delete.text',\n ...hrBlockOffsets,\n },\n ],\n ],\n })\n const automaticHrOnPaste = defineBehavior({\n on: 'paste',\n guard: ({context, event}) => {\n const text = event.data.getData('text/plain')\n const hrRegExp = /^(---)$|(___)$|(\\*\\*\\*)$/gm\n const hrCharacters = text.match(hrRegExp)?.[0]\n const hrObject = config.horizontalRuleObject?.(context)\n const focusBlock = selectors.getFocusBlock({context})\n\n if (!hrCharacters || !hrObject || !focusBlock) {\n return false\n }\n\n return {hrCharacters, hrObject, focusBlock}\n },\n actions: [\n (_, {hrCharacters}) => [\n {\n type: 'insert.text',\n text: hrCharacters,\n },\n ],\n (_, {hrObject, focusBlock}) =>\n isPortableTextTextBlock(focusBlock.node)\n ? [\n {\n type: 'insert.text block',\n textBlock: {children: focusBlock.node.children},\n placement: 'after',\n },\n {\n type: 'insert.block object',\n blockObject: hrObject,\n placement: 'after',\n },\n {type: 'delete.block', blockPath: focusBlock.path},\n ]\n : [\n {\n type: 'insert.block object',\n blockObject: hrObject,\n placement: 'after',\n },\n ],\n ],\n })\n const automaticHeadingOnSpace = defineBehavior({\n on: 'insert.text',\n guard: ({context, event}) => {\n const isSpace = event.text === ' '\n\n if (!isSpace) {\n return false\n }\n\n const selectionCollapsed = selectors.isSelectionCollapsed({context})\n const focusTextBlock = selectors.getFocusTextBlock({context})\n const focusSpan = selectors.getFocusSpan({context})\n\n if (!selectionCollapsed || !focusTextBlock || !focusSpan) {\n return false\n }\n\n const blockOffset = spanSelectionPointToBlockOffset({\n value: context.value,\n selectionPoint: {\n path: [\n {_key: focusTextBlock.node._key},\n 'children',\n {_key: focusSpan.node._key},\n ],\n offset: context.selection?.focus.offset ?? 0,\n },\n })\n\n if (!blockOffset) {\n return false\n }\n\n const blockText = getTextBlockText(focusTextBlock.node)\n const markdownHeadingSearch = /^#+/.exec(blockText)\n const level = markdownHeadingSearch\n ? markdownHeadingSearch[0].length\n : undefined\n const caretAtTheEndOfHeading = blockOffset.offset === level\n\n if (!caretAtTheEndOfHeading) {\n return false\n }\n\n const style =\n level !== undefined\n ? config.headingStyle?.({schema: context.schema, level})\n : undefined\n\n if (level !== undefined && style !== undefined) {\n return {\n focusTextBlock,\n style: style,\n level,\n }\n }\n\n return false\n },\n actions: [\n ({event}) => [event],\n (_, {focusTextBlock, style, level}) => [\n {\n type: 'text block.unset',\n props: ['listItem', 'level'],\n at: focusTextBlock.path,\n },\n {\n type: 'text block.set',\n style,\n at: focusTextBlock.path,\n },\n {\n type: 'delete.text',\n anchor: {\n path: focusTextBlock.path,\n offset: 0,\n },\n focus: {\n path: focusTextBlock.path,\n offset: level + 1,\n },\n },\n ],\n ],\n })\n const clearStyleOnBackspace = defineBehavior({\n on: 'delete.backward',\n guard: ({context}) => {\n const selectionCollapsed = selectors.isSelectionCollapsed({context})\n const focusTextBlock = selectors.getFocusTextBlock({context})\n const focusSpan = selectors.getFocusSpan({context})\n\n if (!selectionCollapsed || !focusTextBlock || !focusSpan) {\n return false\n }\n\n const atTheBeginningOfBLock =\n focusTextBlock.node.children[0]._key === focusSpan.node._key &&\n context.selection?.focus.offset === 0\n\n const defaultStyle = config.defaultStyle?.(context)\n\n if (\n atTheBeginningOfBLock &&\n defaultStyle &&\n focusTextBlock.node.style !== defaultStyle\n ) {\n return {defaultStyle, focusTextBlock}\n }\n\n return false\n },\n actions: [\n (_, {defaultStyle, focusTextBlock}) => [\n {\n type: 'text block.set',\n style: defaultStyle,\n at: focusTextBlock.path,\n },\n ],\n ],\n })\n const automaticListOnSpace = defineBehavior({\n on: 'insert.text',\n guard: ({context, event}) => {\n const isSpace = event.text === ' '\n\n if (!isSpace) {\n return false\n }\n\n const selectionCollapsed = selectors.isSelectionCollapsed({context})\n const focusTextBlock = selectors.getFocusTextBlock({context})\n const focusSpan = selectors.getFocusSpan({context})\n\n if (!selectionCollapsed || !focusTextBlock || !focusSpan) {\n return false\n }\n\n const blockOffset = spanSelectionPointToBlockOffset({\n value: context.value,\n selectionPoint: {\n path: [\n {_key: focusTextBlock.node._key},\n 'children',\n {_key: focusSpan.node._key},\n ],\n offset: context.selection?.focus.offset ?? 0,\n },\n })\n\n if (!blockOffset) {\n return false\n }\n\n const blockText = getTextBlockText(focusTextBlock.node)\n const defaultStyle = config.defaultStyle?.(context)\n const looksLikeUnorderedList = /^(-|\\*)/.test(blockText)\n const unorderedListStyle = config.unorderedListStyle?.(context)\n const caretAtTheEndOfUnorderedList = blockOffset.offset === 1\n\n if (\n defaultStyle &&\n caretAtTheEndOfUnorderedList &&\n looksLikeUnorderedList &&\n unorderedListStyle !== undefined\n ) {\n return {\n focusTextBlock,\n listItem: unorderedListStyle,\n listItemLength: 1,\n style: defaultStyle,\n }\n }\n\n const looksLikeOrderedList = /^1\\./.test(blockText)\n const orderedListStyle = config.orderedListStyle?.(context)\n const caretAtTheEndOfOrderedList = blockOffset.offset === 2\n\n if (\n defaultStyle &&\n caretAtTheEndOfOrderedList &&\n looksLikeOrderedList &&\n orderedListStyle !== undefined\n ) {\n return {\n focusTextBlock,\n listItem: orderedListStyle,\n listItemLength: 2,\n style: defaultStyle,\n }\n }\n\n return false\n },\n actions: [\n ({event}) => [event],\n (_, {focusTextBlock, style, listItem, listItemLength}) => [\n {\n type: 'text block.set',\n listItem,\n level: 1,\n style,\n at: focusTextBlock.path,\n },\n {\n type: 'delete.text',\n anchor: {\n path: focusTextBlock.path,\n offset: 0,\n },\n focus: {\n path: focusTextBlock.path,\n offset: listItemLength + 1,\n },\n },\n ],\n ],\n })\n\n const markdownBehaviors = [\n automaticBlockquoteOnSpace,\n automaticHeadingOnSpace,\n automaticHr,\n automaticHrOnPaste,\n clearStyleOnBackspace,\n automaticListOnSpace,\n ]\n\n return markdownBehaviors\n}\n"],"names":["createCodeEditorBehaviors","config","defineBehavior","on","guard","context","event","isMoveUpShortcut","isHotkey","moveBlockUpShortcut","keyboardEvent","firstBlock","selectors","selectedBlocks","blocksAbove","node","_key","paths","map","block","path","actions","_","at","type","isMoveDownShortcut","moveBlockDownShortcut","lastBlock","blocksBelow","length","reverse","emojiCharRegEx","incompleteEmojiRegEx","emojiRegEx","createEmojiPickerBehaviors","emojiPickerActor","createActor","createEmojiPickerMachine","start","subscribe","state","onMatchesChanged","matches","onSelectedIndexChanged","selectedIndex","text","test","emojis","focusBlock","emojiKeyword","match","undefined","matchEmojis","keyword","params","effect","send","getSnapshot","emoji","parseMatch","textBefore","emojiStringLength","textBeforeLength","anchor","offset","focus","isShift","isColon","key","isEmojiChar","isArrowDown","isArrowUp","isEnter","isTab","action","unit","slice","setup","types","events","assign","assertEvent","guards","no matches","createMachine","id","initial","states","target","always","exit","looksLikeUrl","url","URL","sensibleProtocols","includes","protocol","hostname","createLinkBehaviors","pasteLinkOnSelection","selectionCollapsed","data","getData","annotation","linkAnnotation","schema","pasteLinkAtCaret","focusSpan","annotations","createMarkdownBehaviors","automaticBlockquoteOnSpace","focusTextBlock","blockOffset","spanSelectionPointToBlockOffset","value","selectionPoint","selection","blockText","getTextBlockText","caretAtTheEndOfQuote","looksLikeMarkdownQuote","blockquoteStyle","style","props","automaticHr","hrCharacter","hrObject","horizontalRuleObject","getBlockTextBefore","hrBlockOffsets","placement","blockObject","automaticHrOnPaste","hrRegExp","hrCharacters","isPortableTextTextBlock","textBlock","children","blockPath","automaticHeadingOnSpace","markdownHeadingSearch","exec","level","headingStyle","clearStyleOnBackspace","atTheBeginningOfBLock","defaultStyle","automaticListOnSpace","looksLikeUnorderedList","unorderedListStyle","caretAtTheEndOfUnorderedList","listItem","listItemLength","looksLikeOrderedList","orderedListStyle","caretAtTheEndOfOrderedList"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@portabletext/editor",
3
- "version": "1.18.1",
3
+ "version": "1.18.2",
4
4
  "description": "Portable Text Editor made in React",
5
5
  "keywords": [
6
6
  "sanity",
@@ -1,5 +1,6 @@
1
1
  import type {EditorSchema} from '../editor/define-schema'
2
2
  import * as selectors from '../selectors'
3
+ import {looksLikeUrl} from '../utils/looks-like-url'
3
4
  import {defineBehavior} from './behavior.types'
4
5
 
5
6
  /**
@@ -80,12 +81,3 @@ export function createLinkBehaviors(config: LinkBehaviorsConfig) {
80
81
 
81
82
  return linkBehaviors
82
83
  }
83
-
84
- function looksLikeUrl(text: string) {
85
- let looksLikeUrl = false
86
- try {
87
- new URL(text)
88
- looksLikeUrl = true
89
- } catch {}
90
- return looksLikeUrl
91
- }
@@ -0,0 +1,13 @@
1
+ import {expect, test} from 'vitest'
2
+ import {looksLikeUrl} from './looks-like-url'
3
+
4
+ test(looksLikeUrl.name, () => {
5
+ expect(looksLikeUrl('https://example.com')).toBe(true)
6
+ expect(looksLikeUrl('http://example.com')).toBe(true)
7
+ expect(looksLikeUrl('example.com')).toBe(true)
8
+ expect(looksLikeUrl('mailto:foo@example.com')).toBe(true)
9
+ expect(looksLikeUrl('tel:+123456789')).toBe(true)
10
+ expect(looksLikeUrl('http://example')).toBe(false)
11
+ expect(looksLikeUrl('http:example')).toBe(false)
12
+ expect(looksLikeUrl('a:b')).toBe(false)
13
+ })
@@ -0,0 +1,31 @@
1
+ export function looksLikeUrl(text: string) {
2
+ let looksLikeUrl = false
3
+ try {
4
+ try {
5
+ const url = new URL(text)
6
+
7
+ if (!sensibleProtocols.includes(url.protocol)) {
8
+ return false
9
+ }
10
+
11
+ const probablyHasTld =
12
+ url.hostname.length > 0 ? url.hostname.includes('.') : true
13
+
14
+ looksLikeUrl = probablyHasTld
15
+ } catch {
16
+ const url = new URL(`https://${text}`)
17
+
18
+ if (!sensibleProtocols.includes(url.protocol)) {
19
+ return false
20
+ }
21
+
22
+ const probablyHasTld =
23
+ url.hostname.length > 0 ? url.hostname.includes('.') : true
24
+
25
+ looksLikeUrl = probablyHasTld
26
+ }
27
+ } catch {}
28
+ return looksLikeUrl
29
+ }
30
+
31
+ const sensibleProtocols = ['http:', 'https:', 'mailto:', 'tel:']