diff --git a/package.json b/package.json index 32c4461db..2bd80880b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sub-store-front-end", - "version": "2.14.206", + "version": "2.14.207", "private": true, "scripts": { "dev": "vite --host", @@ -24,7 +24,6 @@ "@lezer/javascript": "^1.4.13", "@nutui/nutui": "^3.3.8", "@replit/codemirror-indentation-markers": "^6.5.0", - "@uiw/codemirror-extensions-hyper-link": "^4.21.21", "@vueuse/core": "^8.9.2", "@vueuse/integrations": "^8.9.2", "axios": "^0.27.2", diff --git a/src/views/editCode/cmView.vue b/src/views/editCode/cmView.vue index 44007fd4f..998bab240 100644 --- a/src/views/editCode/cmView.vue +++ b/src/views/editCode/cmView.vue @@ -65,7 +65,7 @@ import { } from "@codemirror/commands"; import { closeBrackets, autocompletion } from "@codemirror/autocomplete"; import { Compartment, EditorState } from "@codemirror/state"; -import { hyperLink } from "@uiw/codemirror-extensions-hyper-link"; +import { hyperLink } from "@/views/editCode/link"; import { indentationMarkers } from "@replit/codemirror-indentation-markers"; import useV3Clipboard from "vue-clipboard3"; import copyimg from "@/views/editCode/svg/copy.svg"; diff --git a/src/views/editCode/link/README.md b/src/views/editCode/link/README.md new file mode 100644 index 000000000..3d0efc28a --- /dev/null +++ b/src/views/editCode/link/README.md @@ -0,0 +1,123 @@ + + +# Hyper link Extensions + + + +[![Buy me a coffee](https://img.shields.io/badge/Buy%20me%20a%20coffee-048754?logo=buymeacoffee)](https://jaywcjlove.github.io/#/sponsor) +[![npm version](https://img.shields.io/npm/v/@uiw/codemirror-extensions-hyper-link.svg)](https://www.npmjs.com/package/@uiw/codemirror-extensions-hyper-link) + +Hyper link Extensions for CodeMirror6. + +## Install + +```bash +npm install @uiw/codemirror-extensions-hyper-link --save +``` + +```jsx +import { hyperLink, hyperLinkExtension, hyperLinkStyle } from '@uiw/codemirror-extensions-hyper-link'; +``` + +## Usage + +```jsx +import CodeMirror from '@uiw/react-codemirror'; +import { hyperLink } from '@uiw/codemirror-extensions-hyper-link'; + +const code = `https://uiwjs.github.io/react-codemirror`; + +function App() { + return ; +} +export default App; +``` + +```js +import { EditorView } from '@codemirror/view'; +import { EditorState } from '@codemirror/state'; +import { hyperLink } from '@uiw/codemirror-extensions-hyper-link'; + +const code = `https://uiwjs.github.io/react-codemirror`; + +const state = EditorState.create({ + doc: code, + extensions: [hyperLink], +}); + +const view = new EditorView({ + parent: document.querySelector('#editor'), + state, +}); +``` + +Custom match content + +```tsx +import { EditorView } from '@codemirror/view'; +import { EditorState } from '@codemirror/state'; +import { hyperLinkExtension, hyperLinkStyle } from '@uiw/codemirror-extensions-hyper-link'; + +const code = `Hyper Link\n====`; + +export const hyperLink: Extension = [ + hyperLinkExtension({ + regexp: /Hyper/gi, + match: { Hyper: 'https://google.com' }, + handle: (value, input, from, to) => { + if (value === 'Hyper') return 'https://google.com'; + return value; + }, + }), + hyperLinkStyle, +]; + +const state = EditorState.create({ + doc: code, + extensions: [hyperLink], +}); + +const view = new EditorView({ + parent: document.querySelector('#editor'), + state, +}); +``` + +## API + +```ts +import { ViewPlugin, DecorationSet, MatchDecorator, ViewUpdate } from '@codemirror/view'; +import { Extension } from '@codemirror/state'; +export interface HyperLinkState { + at: number; + url: string; + anchor: HyperLinkExtensionOptions['anchor']; +} +export type HyperLinkExtensionOptions = { + regexp?: RegExp; + match?: Record; + handle?: (value: string, input: string, from: number, to: number) => string; + anchor?: (dom: HTMLAnchorElement) => HTMLAnchorElement; +}; +export declare function hyperLinkExtension({ regexp, match, handle, anchor }?: HyperLinkExtensionOptions): ViewPlugin<{ + decorator?: MatchDecorator | undefined; + decorations: DecorationSet; + update(update: ViewUpdate): void; +}>; +export declare const hyperLinkStyle: Extension; +export declare const hyperLink: Extension; +``` + +## Contributors + +As always, thanks to our amazing contributors! + + + + + +Made with [github-action-contributors](https://github.com/jaywcjlove/github-action-contributors). + +## License + +Licensed under the MIT License. diff --git a/src/views/editCode/link/cjs/index.d.ts b/src/views/editCode/link/cjs/index.d.ts new file mode 100644 index 000000000..c36baf995 --- /dev/null +++ b/src/views/editCode/link/cjs/index.d.ts @@ -0,0 +1,20 @@ +import { ViewPlugin, DecorationSet, MatchDecorator, ViewUpdate } from '@codemirror/view'; +import { Extension } from '@codemirror/state'; +export interface HyperLinkState { + at: number; + url: string; + anchor: HyperLinkExtensionOptions['anchor']; +} +export type HyperLinkExtensionOptions = { + regexp?: RegExp; + match?: Record; + handle?: (value: string, input: string, from: number, to: number) => string; + anchor?: (dom: HTMLAnchorElement) => HTMLAnchorElement; +}; +export declare function hyperLinkExtension({ regexp, match, handle, anchor }?: HyperLinkExtensionOptions): ViewPlugin<{ + decorator?: MatchDecorator | undefined; + decorations: DecorationSet; + update(update: ViewUpdate): void; +}>; +export declare const hyperLinkStyle: Extension; +export declare const hyperLink: Extension; diff --git a/src/views/editCode/link/cjs/index.js b/src/views/editCode/link/cjs/index.js new file mode 100644 index 000000000..c8d3f9f9d --- /dev/null +++ b/src/views/editCode/link/cjs/index.js @@ -0,0 +1,144 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault")["default"]; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.hyperLink = void 0; +exports.hyperLinkExtension = hyperLinkExtension; +exports.hyperLinkStyle = void 0; +var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); +var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); +var _callSuper2 = _interopRequireDefault(require("@babel/runtime/helpers/callSuper")); +var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); +var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); +var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); +var _view = require("@codemirror/view"); +var pathStr = ""; +var defaultRegexp = /\b((?:https?|ftp):\/\/[^\s/$.?#,].[^\s,]*)\b/gi; +var HyperLinkIcon = /*#__PURE__*/function (_WidgetType) { + (0, _inherits2["default"])(HyperLinkIcon, _WidgetType); + function HyperLinkIcon(state) { + var _this; + (0, _classCallCheck2["default"])(this, HyperLinkIcon); + _this = (0, _callSuper2["default"])(this, HyperLinkIcon); + (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "state", void 0); + _this.state = state; + return _this; + } + (0, _createClass2["default"])(HyperLinkIcon, [{ + key: "eq", + value: function eq(other) { + return this.state.url === other.state.url && this.state.at === other.state.at; + } + }, { + key: "toDOM", + value: function toDOM() { + var wrapper = document.createElement('a'); + wrapper.href = this.state.url; + wrapper.target = '_blank'; + wrapper.innerHTML = pathStr; + wrapper.className = 'cm-hyper-link-icon'; + wrapper.rel = 'nofollow'; + var anchor = this.state.anchor && this.state.anchor(wrapper); + return anchor || wrapper; + } + }]); + return HyperLinkIcon; +}(_view.WidgetType); +function hyperLinkDecorations(view, anchor) { + var widgets = []; + var doc = view.state.doc; + var match; + while ((match = defaultRegexp.exec(doc.toString())) !== null) { + var _from = match.index; + var _to = _from + match[0].length; + var widget = _view.Decoration.widget({ + widget: new HyperLinkIcon({ + at: _to, + url: match[0], + anchor: anchor + }), + side: 1 + }); + widgets.push(widget.range(_to)); + } + return _view.Decoration.set(widgets); +} +var linkDecorator = function linkDecorator(regexp, matchData, matchFn, anchor) { + return new _view.MatchDecorator({ + regexp: regexp || defaultRegexp, + decorate: function decorate(add, from, to, match, view) { + var url = match[0]; + var urlStr = matchFn && typeof matchFn === 'function' ? matchFn(url, match.input, from, to) : url; + if (matchData && matchData[url]) { + urlStr = matchData[url]; + } + var start = to, + end = to; + var linkIcon = new HyperLinkIcon({ + at: start, + url: urlStr, + anchor: anchor + }); + add(from, to, _view.Decoration.mark({ + "class": 'cm-hyper-link-underline' + })); + add(start, end, _view.Decoration.widget({ + widget: linkIcon, + side: 1 + })); + } + }); +}; +function hyperLinkExtension() { + var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, + regexp = _ref.regexp, + match = _ref.match, + handle = _ref.handle, + anchor = _ref.anchor; + return _view.ViewPlugin.fromClass( /*#__PURE__*/function () { + function HyperLinkView(view) { + (0, _classCallCheck2["default"])(this, HyperLinkView); + (0, _defineProperty2["default"])(this, "decorator", void 0); + (0, _defineProperty2["default"])(this, "decorations", void 0); + if (regexp) { + this.decorator = linkDecorator(regexp, match, handle, anchor); + this.decorations = this.decorator.createDeco(view); + } else { + this.decorations = hyperLinkDecorations(view, anchor); + } + } + (0, _createClass2["default"])(HyperLinkView, [{ + key: "update", + value: function update(_update) { + if (_update.docChanged || _update.viewportChanged) { + if (regexp && this.decorator) { + this.decorations = this.decorator.updateDeco(_update, this.decorations); + } else { + this.decorations = hyperLinkDecorations(_update.view, anchor); + } + } + } + }]); + return HyperLinkView; + }(), { + decorations: function decorations(v) { + return v.decorations; + } + }); +} +var hyperLinkStyle = exports.hyperLinkStyle = _view.EditorView.baseTheme({ + '.cm-hyper-link-icon': { + display: 'inline-block', + verticalAlign: 'middle', + marginLeft: '0.2ch' + }, + '.cm-hyper-link-icon svg': { + display: 'block' + }, + '.cm-hyper-link-underline': { + textDecoration: 'underline' + } +}); +var hyperLink = exports.hyperLink = [hyperLinkExtension(), hyperLinkStyle]; \ No newline at end of file diff --git a/src/views/editCode/link/esm/index.d.ts b/src/views/editCode/link/esm/index.d.ts new file mode 100644 index 000000000..c36baf995 --- /dev/null +++ b/src/views/editCode/link/esm/index.d.ts @@ -0,0 +1,20 @@ +import { ViewPlugin, DecorationSet, MatchDecorator, ViewUpdate } from '@codemirror/view'; +import { Extension } from '@codemirror/state'; +export interface HyperLinkState { + at: number; + url: string; + anchor: HyperLinkExtensionOptions['anchor']; +} +export type HyperLinkExtensionOptions = { + regexp?: RegExp; + match?: Record; + handle?: (value: string, input: string, from: number, to: number) => string; + anchor?: (dom: HTMLAnchorElement) => HTMLAnchorElement; +}; +export declare function hyperLinkExtension({ regexp, match, handle, anchor }?: HyperLinkExtensionOptions): ViewPlugin<{ + decorator?: MatchDecorator | undefined; + decorations: DecorationSet; + update(update: ViewUpdate): void; +}>; +export declare const hyperLinkStyle: Extension; +export declare const hyperLink: Extension; diff --git a/src/views/editCode/link/esm/index.js b/src/views/editCode/link/esm/index.js new file mode 100644 index 000000000..78db0975e --- /dev/null +++ b/src/views/editCode/link/esm/index.js @@ -0,0 +1,111 @@ +import { ViewPlugin, EditorView, Decoration, MatchDecorator, WidgetType } from '@codemirror/view'; +var pathStr = ""; +var defaultRegexp = /\b((?:https?|ftp):\/\/[^\s/$.?#,].[^\s,]*)\b/gi; +class HyperLinkIcon extends WidgetType { + constructor(state) { + super(); + this.state = void 0; + this.state = state; + } + eq(other) { + return this.state.url === other.state.url && this.state.at === other.state.at; + } + toDOM() { + var wrapper = document.createElement('a'); + wrapper.href = this.state.url; + wrapper.target = '_blank'; + wrapper.innerHTML = pathStr; + wrapper.className = 'cm-hyper-link-icon'; + wrapper.rel = 'nofollow'; + var anchor = this.state.anchor && this.state.anchor(wrapper); + return anchor || wrapper; + } +} +function hyperLinkDecorations(view, anchor) { + var widgets = []; + var doc = view.state.doc; + var match; + while ((match = defaultRegexp.exec(doc.toString())) !== null) { + var _from = match.index; + var _to = _from + match[0].length; + var widget = Decoration.widget({ + widget: new HyperLinkIcon({ + at: _to, + url: match[0], + anchor + }), + side: 1 + }); + widgets.push(widget.range(_to)); + } + return Decoration.set(widgets); +} +var linkDecorator = (regexp, matchData, matchFn, anchor) => new MatchDecorator({ + regexp: regexp || defaultRegexp, + decorate: (add, from, to, match, view) => { + var url = match[0]; + var urlStr = matchFn && typeof matchFn === 'function' ? matchFn(url, match.input, from, to) : url; + if (matchData && matchData[url]) { + urlStr = matchData[url]; + } + var start = to, + end = to; + var linkIcon = new HyperLinkIcon({ + at: start, + url: urlStr, + anchor + }); + add(from, to, Decoration.mark({ + class: 'cm-hyper-link-underline' + })); + add(start, end, Decoration.widget({ + widget: linkIcon, + side: 1 + })); + } +}); +export function hyperLinkExtension(_temp) { + var { + regexp, + match, + handle, + anchor + } = _temp === void 0 ? {} : _temp; + return ViewPlugin.fromClass(class HyperLinkView { + constructor(view) { + this.decorator = void 0; + this.decorations = void 0; + if (regexp) { + this.decorator = linkDecorator(regexp, match, handle, anchor); + this.decorations = this.decorator.createDeco(view); + } else { + this.decorations = hyperLinkDecorations(view, anchor); + } + } + update(update) { + if (update.docChanged || update.viewportChanged) { + if (regexp && this.decorator) { + this.decorations = this.decorator.updateDeco(update, this.decorations); + } else { + this.decorations = hyperLinkDecorations(update.view, anchor); + } + } + } + }, { + decorations: v => v.decorations + }); +} +export var hyperLinkStyle = EditorView.baseTheme({ + '.cm-hyper-link-icon': { + display: 'inline-block', + verticalAlign: 'middle', + marginLeft: '0.2ch' + }, + '.cm-hyper-link-icon svg': { + display: 'block' + }, + '.cm-hyper-link-underline': { + textDecoration: 'underline' + } +}); +export var hyperLink = [hyperLinkExtension(), hyperLinkStyle]; \ No newline at end of file diff --git a/src/views/editCode/link/index.ts b/src/views/editCode/link/index.ts new file mode 100644 index 000000000..b60799416 --- /dev/null +++ b/src/views/editCode/link/index.ts @@ -0,0 +1,136 @@ +import { + ViewPlugin, + EditorView, + Decoration, + DecorationSet, + MatchDecorator, + WidgetType, + ViewUpdate, +} from '@codemirror/view'; +import { Extension, Range } from '@codemirror/state'; + +const pathStr = ``; +const defaultRegexp = /\b((?:https?|ftp):\/\/[^\s/$.?#,].[^\s,]*)\b/gi; + +export interface HyperLinkState { + at: number; + url: string; + anchor: HyperLinkExtensionOptions['anchor']; +} + +class HyperLinkIcon extends WidgetType { + private readonly state: HyperLinkState; + constructor(state: HyperLinkState) { + super(); + this.state = state; + } + eq(other: HyperLinkIcon) { + return this.state.url === other.state.url && this.state.at === other.state.at; + } + toDOM() { + const wrapper = document.createElement('a'); + wrapper.href = this.state.url; + wrapper.target = '_blank'; + wrapper.innerHTML = pathStr; + wrapper.className = 'cm-hyper-link-icon'; + wrapper.rel = 'nofollow'; + const anchor = this.state.anchor && this.state.anchor(wrapper); + return anchor || wrapper; + } +} + +function hyperLinkDecorations(view: EditorView, anchor?: HyperLinkExtensionOptions['anchor']) { + const widgets: Array> = []; + const doc = view.state.doc; + let match; + + while ((match = defaultRegexp.exec(doc.toString())) !== null) { + const from = match.index; + const to = from + match[0].length; + const widget = Decoration.widget({ + widget: new HyperLinkIcon({ + at: to, + url: match[0], + anchor, + }), + side: 1, + }); + widgets.push(widget.range(to)); + } + + return Decoration.set(widgets); +} + +const linkDecorator = ( + regexp?: RegExp, + matchData?: Record, + matchFn?: (str: string, input: string, from: number, to: number) => string, + anchor?: HyperLinkExtensionOptions['anchor'], +) => + new MatchDecorator({ + regexp: regexp || defaultRegexp, + decorate: (add, from, to, match, view) => { + const url = match[0]; + let urlStr = matchFn && typeof matchFn === 'function' ? matchFn(url, match.input, from, to) : url; + if (matchData && matchData[url]) { + urlStr = matchData[url]; + } + const start = to, + end = to; + const linkIcon = new HyperLinkIcon({ at: start, url: urlStr, anchor }); + add(from, to, Decoration.mark({ class: 'cm-hyper-link-underline' })); + add(start, end, Decoration.widget({ widget: linkIcon, side: 1 })); + }, + }); + +export type HyperLinkExtensionOptions = { + regexp?: RegExp; + match?: Record; + handle?: (value: string, input: string, from: number, to: number) => string; + anchor?: (dom: HTMLAnchorElement) => HTMLAnchorElement; +}; + +export function hyperLinkExtension({ regexp, match, handle, anchor }: HyperLinkExtensionOptions = {}) { + return ViewPlugin.fromClass( + class HyperLinkView { + decorator?: MatchDecorator; + decorations: DecorationSet; + constructor(view: EditorView) { + if (regexp) { + this.decorator = linkDecorator(regexp, match, handle, anchor); + this.decorations = this.decorator.createDeco(view); + } else { + this.decorations = hyperLinkDecorations(view, anchor); + } + } + update(update: ViewUpdate) { + if (update.docChanged || update.viewportChanged) { + if (regexp && this.decorator) { + this.decorations = this.decorator.updateDeco(update, this.decorations); + } else { + this.decorations = hyperLinkDecorations(update.view, anchor); + } + } + } + }, + { + decorations: (v) => v.decorations, + }, + ); +} + +export const hyperLinkStyle = EditorView.baseTheme({ + '.cm-hyper-link-icon': { + display: 'inline-block', + verticalAlign: 'middle', + marginLeft: '0.2ch', + }, + '.cm-hyper-link-icon svg': { + display: 'block', + }, + '.cm-hyper-link-underline': { + textDecoration: 'underline', + }, +}); + +export const hyperLink: Extension = [hyperLinkExtension(), hyperLinkStyle]; diff --git a/src/views/editCode/link/package.json b/src/views/editCode/link/package.json new file mode 100644 index 000000000..8ae14834d --- /dev/null +++ b/src/views/editCode/link/package.json @@ -0,0 +1,48 @@ +{ + "name": "@uiw/codemirror-extensions-hyper-link", + "version": "4.21.24", + "description": "Hyper link Extensions for CodeMirror6.", + "homepage": "https://uiwjs.github.io/react-codemirror/#/extensions/hyper-link", + "funding": "https://jaywcjlove.github.io/#/sponsor", + "author": "kenny wong ", + "license": "MIT", + "main": "./cjs/index.js", + "module": "./esm/index.js", + "scripts": { + "watch": "tsbb watch src/*.ts --use-babel", + "build": "tsbb build src/*.ts --use-babel" + }, + "repository": { + "type": "git", + "url": "https://github.com/uiwjs/react-codemirror.git" + }, + "files": [ + "src", + "esm", + "cjs" + ], + "peerDependencies": { + "@codemirror/state": ">=6.0.0", + "@codemirror/view": ">=6.0.0" + }, + "devDependencies": { + "@codemirror/state": "^6.1.0", + "@codemirror/view": "^6.0.0" + }, + "keywords": [ + "codemirror", + "codemirror6", + "link", + "url", + "hyper-link", + "extensions", + "ide", + "code" + ], + "jest": { + "coverageReporters": [ + "lcov", + "json-summary" + ] + } +} diff --git a/src/views/editCode/link/src/index.ts b/src/views/editCode/link/src/index.ts new file mode 100644 index 000000000..b60799416 --- /dev/null +++ b/src/views/editCode/link/src/index.ts @@ -0,0 +1,136 @@ +import { + ViewPlugin, + EditorView, + Decoration, + DecorationSet, + MatchDecorator, + WidgetType, + ViewUpdate, +} from '@codemirror/view'; +import { Extension, Range } from '@codemirror/state'; + +const pathStr = ``; +const defaultRegexp = /\b((?:https?|ftp):\/\/[^\s/$.?#,].[^\s,]*)\b/gi; + +export interface HyperLinkState { + at: number; + url: string; + anchor: HyperLinkExtensionOptions['anchor']; +} + +class HyperLinkIcon extends WidgetType { + private readonly state: HyperLinkState; + constructor(state: HyperLinkState) { + super(); + this.state = state; + } + eq(other: HyperLinkIcon) { + return this.state.url === other.state.url && this.state.at === other.state.at; + } + toDOM() { + const wrapper = document.createElement('a'); + wrapper.href = this.state.url; + wrapper.target = '_blank'; + wrapper.innerHTML = pathStr; + wrapper.className = 'cm-hyper-link-icon'; + wrapper.rel = 'nofollow'; + const anchor = this.state.anchor && this.state.anchor(wrapper); + return anchor || wrapper; + } +} + +function hyperLinkDecorations(view: EditorView, anchor?: HyperLinkExtensionOptions['anchor']) { + const widgets: Array> = []; + const doc = view.state.doc; + let match; + + while ((match = defaultRegexp.exec(doc.toString())) !== null) { + const from = match.index; + const to = from + match[0].length; + const widget = Decoration.widget({ + widget: new HyperLinkIcon({ + at: to, + url: match[0], + anchor, + }), + side: 1, + }); + widgets.push(widget.range(to)); + } + + return Decoration.set(widgets); +} + +const linkDecorator = ( + regexp?: RegExp, + matchData?: Record, + matchFn?: (str: string, input: string, from: number, to: number) => string, + anchor?: HyperLinkExtensionOptions['anchor'], +) => + new MatchDecorator({ + regexp: regexp || defaultRegexp, + decorate: (add, from, to, match, view) => { + const url = match[0]; + let urlStr = matchFn && typeof matchFn === 'function' ? matchFn(url, match.input, from, to) : url; + if (matchData && matchData[url]) { + urlStr = matchData[url]; + } + const start = to, + end = to; + const linkIcon = new HyperLinkIcon({ at: start, url: urlStr, anchor }); + add(from, to, Decoration.mark({ class: 'cm-hyper-link-underline' })); + add(start, end, Decoration.widget({ widget: linkIcon, side: 1 })); + }, + }); + +export type HyperLinkExtensionOptions = { + regexp?: RegExp; + match?: Record; + handle?: (value: string, input: string, from: number, to: number) => string; + anchor?: (dom: HTMLAnchorElement) => HTMLAnchorElement; +}; + +export function hyperLinkExtension({ regexp, match, handle, anchor }: HyperLinkExtensionOptions = {}) { + return ViewPlugin.fromClass( + class HyperLinkView { + decorator?: MatchDecorator; + decorations: DecorationSet; + constructor(view: EditorView) { + if (regexp) { + this.decorator = linkDecorator(regexp, match, handle, anchor); + this.decorations = this.decorator.createDeco(view); + } else { + this.decorations = hyperLinkDecorations(view, anchor); + } + } + update(update: ViewUpdate) { + if (update.docChanged || update.viewportChanged) { + if (regexp && this.decorator) { + this.decorations = this.decorator.updateDeco(update, this.decorations); + } else { + this.decorations = hyperLinkDecorations(update.view, anchor); + } + } + } + }, + { + decorations: (v) => v.decorations, + }, + ); +} + +export const hyperLinkStyle = EditorView.baseTheme({ + '.cm-hyper-link-icon': { + display: 'inline-block', + verticalAlign: 'middle', + marginLeft: '0.2ch', + }, + '.cm-hyper-link-icon svg': { + display: 'block', + }, + '.cm-hyper-link-underline': { + textDecoration: 'underline', + }, +}); + +export const hyperLink: Extension = [hyperLinkExtension(), hyperLinkStyle];