@portabletext/plugin-paste-link 3.0.27 → 4.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -2,6 +2,7 @@ import { c } from "react/compiler-runtime";
2
2
  import { useEditor } from "@portabletext/editor";
3
3
  import { defineBehavior, raise } from "@portabletext/editor/behaviors";
4
4
  import * as selectors from "@portabletext/editor/selectors";
5
+ import { getPathSubSchema } from "@portabletext/editor/traversal";
5
6
  import { useEffect } from "react";
6
7
  function looksLikeUrl(text) {
7
8
  try {
@@ -50,15 +51,15 @@ function createPasteLinkBehaviors(config) {
50
51
  const {
51
52
  snapshot,
52
53
  event
53
- } = guardParams;
54
- if (selectors.isSelectionCollapsed(snapshot))
54
+ } = guardParams, selectionCollapsed = selectors.isSelectionCollapsed(snapshot), focusBlock = selectors.getFocusBlock(snapshot);
55
+ if (selectionCollapsed || !focusBlock)
55
56
  return !1;
56
57
  const text = event.originEvent.dataTransfer.getData("text/plain"), href = looksLikeUrl(text) ? text : void 0;
57
58
  if (!href)
58
59
  return !1;
59
60
  const result = config.link({
60
61
  context: {
61
- schema: snapshot.context.schema,
62
+ schema: getPathSubSchema(snapshot, focusBlock.path),
62
63
  keyGenerator: snapshot.context.keyGenerator
63
64
  },
64
65
  value: {
@@ -100,9 +101,9 @@ function createPasteLinkBehaviors(config) {
100
101
  const text = event.originEvent.dataTransfer.getData("text/plain"), href = looksLikeUrl(text) ? text : void 0;
101
102
  if (!href)
102
103
  return !1;
103
- const result = config.link({
104
+ const subSchema = getPathSubSchema(snapshot, focusTextBlock.path), result = config.link({
104
105
  context: {
105
- schema: snapshot.context.schema,
106
+ schema: subSchema,
106
107
  keyGenerator: snapshot.context.keyGenerator
107
108
  },
108
109
  value: {
@@ -115,7 +116,7 @@ function createPasteLinkBehaviors(config) {
115
116
  _type,
116
117
  _key,
117
118
  ...value
118
- } = result, markState = selectors.getMarkState(snapshot), decoratorNames = snapshot.context.schema.decorators.map((decorator) => decorator.name), activeDecorators = (markState?.marks ?? []).filter((mark) => decoratorNames.includes(mark)), markDefKey = _key ?? snapshot.context.keyGenerator(), markDef = {
119
+ } = result, markState = selectors.getMarkState(snapshot), decoratorNames = subSchema.decorators.map((decorator) => decorator.name), activeDecorators = (markState?.marks ?? []).filter((mark) => decoratorNames.includes(mark)), markDefKey = _key ?? snapshot.context.keyGenerator(), markDef = {
119
120
  _type,
120
121
  _key: markDefKey,
121
122
  ...value
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/looks-like-url.ts","../src/plugin.paste-link.tsx"],"sourcesContent":["export function looksLikeUrl(text: string) {\n try {\n const url = new URL(text)\n return sensibleProtocols.includes(url.protocol)\n } catch {\n return false\n }\n}\n\nconst sensibleProtocols = ['http:', 'https:', 'mailto:', 'tel:']\n","import type {EditorContext} from '@portabletext/editor'\nimport {useEditor} from '@portabletext/editor'\nimport {\n defineBehavior,\n raise,\n type BehaviorGuard,\n type NativeBehaviorEvent,\n} from '@portabletext/editor/behaviors'\nimport * as selectors from '@portabletext/editor/selectors'\nimport {useEffect} from 'react'\nimport {looksLikeUrl} from './looks-like-url'\n\n/**\n * Guard function that controls when the paste link behavior runs.\n * Return `false` to skip the behavior and fall through to default paste handling.\n * @public\n */\nexport type PasteLinkGuard = BehaviorGuard<\n Extract<NativeBehaviorEvent, {type: 'clipboard.paste'}>,\n true\n>\n\n/**\n * Context provided to link matchers.\n * @public\n */\nexport type LinkMatcherContext = Pick<EditorContext, 'schema' | 'keyGenerator'>\n\n/**\n * Value provided to link matchers.\n * @public\n */\nexport type LinkMatcherValue = {href: string}\n\n/**\n * Object returned by link matchers.\n * @public\n */\nexport type LinkMatcherResult = {\n _type: string\n _key?: string\n [other: string]: unknown\n}\n\n/**\n * Function that converts a pasted URL into a link annotation.\n * Return `undefined` to skip handling.\n * @public\n */\nexport type LinkMatcher = (params: {\n context: LinkMatcherContext\n value: LinkMatcherValue\n}) => LinkMatcherResult | undefined\n\n/**\n * @public\n */\nexport type PasteLinkPluginProps = {\n guard?: PasteLinkGuard\n link?: LinkMatcher\n}\n\nconst defaultLinkMatcher: LinkMatcher = ({context, value}) => {\n const schemaType = context.schema.annotations.find(\n (annotation) => annotation.name === 'link',\n )\n const hrefField = schemaType?.fields.find(\n (field) => field.name === 'href' && field.type === 'string',\n )\n\n if (!schemaType || !hrefField) {\n return undefined\n }\n\n return {\n _type: schemaType.name,\n [hrefField.name]: value.href,\n }\n}\n\n/**\n * Plugin that handles pasting URLs in the editor.\n *\n * When text is selected and a URL is pasted, adds a link annotation to the selection.\n * When the caret is collapsed (no selection) and a URL is pasted, inserts the URL as text with a link annotation.\n *\n * @public\n */\nexport function PasteLinkPlugin({\n guard,\n link = defaultLinkMatcher,\n}: PasteLinkPluginProps) {\n const editor = useEditor()\n\n useEffect(() => {\n const behaviors = createPasteLinkBehaviors({guard, link})\n const unregisterBehaviors = behaviors.map((behavior) =>\n editor.registerBehavior({behavior}),\n )\n\n return () => {\n for (const unregisterBehavior of unregisterBehaviors) {\n unregisterBehavior()\n }\n }\n }, [editor, guard, link])\n\n return null\n}\n\nfunction createPasteLinkBehaviors(\n config: Required<Pick<PasteLinkPluginProps, 'link'>> &\n Pick<PasteLinkPluginProps, 'guard'>,\n) {\n /**\n * When text is selected and a URL is pasted, add a link annotation to the\n * selection. If the selection already has a link annotation, the core\n * `preventOverlappingAnnotations` behavior will remove it first.\n */\n const pasteLinkOnSelection = defineBehavior({\n on: 'clipboard.paste',\n guard: (guardParams) => {\n if (config.guard && config.guard(guardParams) === false) {\n return false\n }\n\n const {snapshot, event} = guardParams\n const selectionCollapsed = selectors.isSelectionCollapsed(snapshot)\n\n if (selectionCollapsed) {\n return false\n }\n\n const text = event.originEvent.dataTransfer.getData('text/plain')\n const href = looksLikeUrl(text) ? text : undefined\n\n if (!href) {\n return false\n }\n\n const result = config.link({\n context: {\n schema: snapshot.context.schema,\n keyGenerator: snapshot.context.keyGenerator,\n },\n value: {href},\n })\n\n if (!result) {\n return false\n }\n\n const {_type, _key, ...value} = result\n\n return {annotation: {name: _type, _key, value}}\n },\n actions: [\n (_, {annotation}) => [\n raise({\n type: 'annotation.add',\n annotation,\n }),\n ],\n ],\n })\n\n /**\n * When the caret is collapsed (no selection) and a URL is pasted, insert the\n * URL as text with a link annotation. Existing decorators (bold, italic,\n * etc.) are preserved.\n */\n const pasteLinkAtCaret = defineBehavior({\n on: 'clipboard.paste',\n guard: (guardParams) => {\n if (config.guard && config.guard(guardParams) === false) {\n return false\n }\n\n const {snapshot, event} = guardParams\n const focusTextBlock = selectors.getFocusTextBlock(snapshot)\n const selectionCollapsed = selectors.isSelectionCollapsed(snapshot)\n\n if (!focusTextBlock || !selectionCollapsed) {\n return false\n }\n\n const text = event.originEvent.dataTransfer.getData('text/plain')\n const href = looksLikeUrl(text) ? text : undefined\n\n if (!href) {\n return false\n }\n\n const result = config.link({\n context: {\n schema: snapshot.context.schema,\n keyGenerator: snapshot.context.keyGenerator,\n },\n value: {href},\n })\n\n if (!result) {\n return false\n }\n\n const {_type, _key, ...value} = result\n\n const markState = selectors.getMarkState(snapshot)\n const decoratorNames = snapshot.context.schema.decorators.map(\n (decorator) => decorator.name,\n )\n const activeDecorators = (markState?.marks ?? []).filter((mark) =>\n decoratorNames.includes(mark),\n )\n\n const markDefKey = _key ?? snapshot.context.keyGenerator()\n const markDef = {\n _type,\n _key: markDefKey,\n ...value,\n }\n\n return {\n focusTextBlock,\n markDef,\n markDefKey,\n href,\n activeDecorators,\n }\n },\n actions: [\n (\n {snapshot},\n {focusTextBlock, markDef, markDefKey, href, activeDecorators},\n ) => [\n raise({\n type: 'block.set',\n at: focusTextBlock.path,\n props: {\n markDefs: [...(focusTextBlock.node.markDefs ?? []), markDef],\n },\n }),\n raise({\n type: 'insert.child',\n child: {\n _type: snapshot.context.schema.span.name,\n text: href,\n marks: [...activeDecorators, markDefKey],\n },\n }),\n ],\n ],\n })\n\n return [pasteLinkOnSelection, pasteLinkAtCaret]\n}\n"],"names":["looksLikeUrl","text","url","URL","sensibleProtocols","includes","protocol","defaultLinkMatcher","context","value","schemaType","schema","annotations","find","annotation","name","hrefField","fields","field","type","_type","href","PasteLinkPlugin","t0","$","_c","guard","link","t1","undefined","editor","useEditor","t2","t3","unregisterBehaviors","createPasteLinkBehaviors","map","behavior","registerBehavior","unregisterBehavior","useEffect","config","pasteLinkOnSelection","defineBehavior","on","guardParams","snapshot","event","selectors","isSelectionCollapsed","originEvent","dataTransfer","getData","result","keyGenerator","_key","actions","_","raise","pasteLinkAtCaret","focusTextBlock","getFocusTextBlock","selectionCollapsed","markState","getMarkState","decoratorNames","decorators","decorator","activeDecorators","marks","filter","mark","markDefKey","markDef","at","path","props","markDefs","node","child","span"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/looks-like-url.ts","../src/plugin.paste-link.tsx"],"sourcesContent":["export function looksLikeUrl(text: string) {\n try {\n const url = new URL(text)\n return sensibleProtocols.includes(url.protocol)\n } catch {\n return false\n }\n}\n\nconst sensibleProtocols = ['http:', 'https:', 'mailto:', 'tel:']\n","import type {EditorContext} from '@portabletext/editor'\nimport {useEditor} from '@portabletext/editor'\nimport {\n defineBehavior,\n raise,\n type BehaviorGuard,\n type NativeBehaviorEvent,\n} from '@portabletext/editor/behaviors'\nimport * as selectors from '@portabletext/editor/selectors'\nimport {getPathSubSchema} from '@portabletext/editor/traversal'\nimport {useEffect} from 'react'\nimport {looksLikeUrl} from './looks-like-url'\n\n/**\n * Guard function that controls when the paste link behavior runs.\n * Return `false` to skip the behavior and fall through to default paste handling.\n * @public\n */\nexport type PasteLinkGuard = BehaviorGuard<\n Extract<NativeBehaviorEvent, {type: 'clipboard.paste'}>,\n true\n>\n\n/**\n * Context provided to link matchers.\n * @public\n */\nexport type LinkMatcherContext = Pick<EditorContext, 'schema' | 'keyGenerator'>\n\n/**\n * Value provided to link matchers.\n * @public\n */\nexport type LinkMatcherValue = {href: string}\n\n/**\n * Object returned by link matchers.\n * @public\n */\nexport type LinkMatcherResult = {\n _type: string\n _key?: string\n [other: string]: unknown\n}\n\n/**\n * Function that converts a pasted URL into a link annotation.\n * Return `undefined` to skip handling.\n * @public\n */\nexport type LinkMatcher = (params: {\n context: LinkMatcherContext\n value: LinkMatcherValue\n}) => LinkMatcherResult | undefined\n\n/**\n * @public\n */\nexport type PasteLinkPluginProps = {\n guard?: PasteLinkGuard\n link?: LinkMatcher\n}\n\nconst defaultLinkMatcher: LinkMatcher = ({context, value}) => {\n const schemaType = context.schema.annotations.find(\n (annotation) => annotation.name === 'link',\n )\n const hrefField = schemaType?.fields.find(\n (field) => field.name === 'href' && field.type === 'string',\n )\n\n if (!schemaType || !hrefField) {\n return undefined\n }\n\n return {\n _type: schemaType.name,\n [hrefField.name]: value.href,\n }\n}\n\n/**\n * Plugin that handles pasting URLs in the editor.\n *\n * When text is selected and a URL is pasted, adds a link annotation to the selection.\n * When the caret is collapsed (no selection) and a URL is pasted, inserts the URL as text with a link annotation.\n *\n * @public\n */\nexport function PasteLinkPlugin({\n guard,\n link = defaultLinkMatcher,\n}: PasteLinkPluginProps) {\n const editor = useEditor()\n\n useEffect(() => {\n const behaviors = createPasteLinkBehaviors({guard, link})\n const unregisterBehaviors = behaviors.map((behavior) =>\n editor.registerBehavior({behavior}),\n )\n\n return () => {\n for (const unregisterBehavior of unregisterBehaviors) {\n unregisterBehavior()\n }\n }\n }, [editor, guard, link])\n\n return null\n}\n\nfunction createPasteLinkBehaviors(\n config: Required<Pick<PasteLinkPluginProps, 'link'>> &\n Pick<PasteLinkPluginProps, 'guard'>,\n) {\n /**\n * When text is selected and a URL is pasted, add a link annotation to the\n * selection. If the selection already has a link annotation, the core\n * `preventOverlappingAnnotations` behavior will remove it first.\n */\n const pasteLinkOnSelection = defineBehavior({\n on: 'clipboard.paste',\n guard: (guardParams) => {\n if (config.guard && config.guard(guardParams) === false) {\n return false\n }\n\n const {snapshot, event} = guardParams\n const selectionCollapsed = selectors.isSelectionCollapsed(snapshot)\n const focusBlock = selectors.getFocusBlock(snapshot)\n\n if (selectionCollapsed || !focusBlock) {\n return false\n }\n\n const text = event.originEvent.dataTransfer.getData('text/plain')\n const href = looksLikeUrl(text) ? text : undefined\n\n if (!href) {\n return false\n }\n\n const result = config.link({\n context: {\n schema: getPathSubSchema(snapshot, focusBlock.path),\n keyGenerator: snapshot.context.keyGenerator,\n },\n value: {href},\n })\n\n if (!result) {\n return false\n }\n\n const {_type, _key, ...value} = result\n\n return {annotation: {name: _type, _key, value}}\n },\n actions: [\n (_, {annotation}) => [\n raise({\n type: 'annotation.add',\n annotation,\n }),\n ],\n ],\n })\n\n /**\n * When the caret is collapsed (no selection) and a URL is pasted, insert the\n * URL as text with a link annotation. Existing decorators (bold, italic,\n * etc.) are preserved.\n */\n const pasteLinkAtCaret = defineBehavior({\n on: 'clipboard.paste',\n guard: (guardParams) => {\n if (config.guard && config.guard(guardParams) === false) {\n return false\n }\n\n const {snapshot, event} = guardParams\n const focusTextBlock = selectors.getFocusTextBlock(snapshot)\n const selectionCollapsed = selectors.isSelectionCollapsed(snapshot)\n\n if (!focusTextBlock || !selectionCollapsed) {\n return false\n }\n\n const text = event.originEvent.dataTransfer.getData('text/plain')\n const href = looksLikeUrl(text) ? text : undefined\n\n if (!href) {\n return false\n }\n\n const subSchema = getPathSubSchema(snapshot, focusTextBlock.path)\n const result = config.link({\n context: {\n schema: subSchema,\n keyGenerator: snapshot.context.keyGenerator,\n },\n value: {href},\n })\n\n if (!result) {\n return false\n }\n\n const {_type, _key, ...value} = result\n\n const markState = selectors.getMarkState(snapshot)\n const decoratorNames = subSchema.decorators.map(\n (decorator) => decorator.name,\n )\n const activeDecorators = (markState?.marks ?? []).filter((mark) =>\n decoratorNames.includes(mark),\n )\n\n const markDefKey = _key ?? snapshot.context.keyGenerator()\n const markDef = {\n _type,\n _key: markDefKey,\n ...value,\n }\n\n return {\n focusTextBlock,\n markDef,\n markDefKey,\n href,\n activeDecorators,\n }\n },\n actions: [\n (\n {snapshot},\n {focusTextBlock, markDef, markDefKey, href, activeDecorators},\n ) => [\n raise({\n type: 'block.set',\n at: focusTextBlock.path,\n props: {\n markDefs: [...(focusTextBlock.node.markDefs ?? []), markDef],\n },\n }),\n raise({\n type: 'insert.child',\n child: {\n _type: snapshot.context.schema.span.name,\n text: href,\n marks: [...activeDecorators, markDefKey],\n },\n }),\n ],\n ],\n })\n\n return [pasteLinkOnSelection, pasteLinkAtCaret]\n}\n"],"names":["looksLikeUrl","text","url","URL","sensibleProtocols","includes","protocol","defaultLinkMatcher","context","value","schemaType","schema","annotations","find","annotation","name","hrefField","fields","field","type","_type","href","PasteLinkPlugin","t0","$","_c","guard","link","t1","undefined","editor","useEditor","t2","t3","unregisterBehaviors","createPasteLinkBehaviors","map","behavior","registerBehavior","unregisterBehavior","useEffect","config","pasteLinkOnSelection","defineBehavior","on","guardParams","snapshot","event","selectionCollapsed","selectors","isSelectionCollapsed","focusBlock","getFocusBlock","originEvent","dataTransfer","getData","result","getPathSubSchema","path","keyGenerator","_key","actions","_","raise","pasteLinkAtCaret","focusTextBlock","getFocusTextBlock","subSchema","markState","getMarkState","decoratorNames","decorators","decorator","activeDecorators","marks","filter","mark","markDefKey","markDef","at","props","markDefs","node","child","span"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@portabletext/plugin-paste-link",
3
- "version": "3.0.27",
3
+ "version": "4.0.1",
4
4
  "description": "Allows pasting links in the Portable Text Editor",
5
5
  "keywords": [
6
6
  "portabletext",
@@ -34,23 +34,23 @@
34
34
  ],
35
35
  "devDependencies": {
36
36
  "@sanity/tsconfig": "^2.1.0",
37
- "@types/react": "^19.2.7",
38
- "@vitejs/plugin-react": "^5.1.1",
39
- "@vitest/browser": "^4.1.0",
40
- "@vitest/browser-playwright": "^4.1.0",
37
+ "@types/react": "^19.2.14",
38
+ "@vitejs/plugin-react": "^5.2.0",
39
+ "@vitest/browser": "^4.1.4",
40
+ "@vitest/browser-playwright": "^4.1.4",
41
41
  "babel-plugin-react-compiler": "^1.0.0",
42
42
  "eslint": "^9.39.1",
43
- "eslint-plugin-react-hooks": "^7.0.1",
44
- "react": "^19.2.3",
43
+ "eslint-plugin-react-hooks": "^7.1.1",
44
+ "react": "^19.2.5",
45
45
  "typescript": "5.9.3",
46
46
  "typescript-eslint": "^8.48.0",
47
- "vitest": "^4.1.0",
48
- "@portabletext/editor": "^6.6.4",
49
- "racejar": "2.0.5"
47
+ "vitest": "^4.1.4",
48
+ "@portabletext/editor": "^7.0.1",
49
+ "racejar": "2.0.6"
50
50
  },
51
51
  "peerDependencies": {
52
52
  "react": "^19.2",
53
- "@portabletext/editor": "^6.6.4"
53
+ "@portabletext/editor": "^7.0.1"
54
54
  },
55
55
  "engines": {
56
56
  "node": ">=20.19 <22 || >=22.12"