Skip to content

Commit

Permalink
优化 cmCode 超链接 🔗
Browse files Browse the repository at this point in the history
  • Loading branch information
Keywos committed Mar 21, 2024
1 parent 4d7143a commit fae58df
Show file tree
Hide file tree
Showing 10 changed files with 740 additions and 3 deletions.
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "sub-store-front-end",
"version": "2.14.206",
"version": "2.14.207",
"private": true,
"scripts": {
"dev": "vite --host",
Expand All @@ -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",
Expand Down
2 changes: 1 addition & 1 deletion src/views/editCode/cmView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down
123 changes: 123 additions & 0 deletions src/views/editCode/link/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
<!--rehype:ignore:start-->

# Hyper link Extensions

<!--rehype:ignore:end-->

[![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 <CodeMirror value={code} height="200px" extensions={[hyperLink]} />;
}
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<string, string>;
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!

<a href="https://github.com/uiwjs/react-codemirror/graphs/contributors">
<img src="https://uiwjs.github.io/react-codemirror/CONTRIBUTORS.svg" />
</a>

Made with [github-action-contributors](https://github.com/jaywcjlove/github-action-contributors).

## License

Licensed under the MIT License.
20 changes: 20 additions & 0 deletions src/views/editCode/link/cjs/index.d.ts
Original file line number Diff line number Diff line change
@@ -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<string, string>;
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;
144 changes: 144 additions & 0 deletions src/views/editCode/link/cjs/index.js
Original file line number Diff line number Diff line change
@@ -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 = "<svg viewBox=\"0 0 1024 1024\" width=\"16\" height=\"16\" fill=\"currentColor\"><path d=\"M607.934444 417.856853c-6.179746-6.1777-12.766768-11.746532-19.554358-16.910135l-0.01228 0.011256c-6.986111-6.719028-16.47216-10.857279-26.930349-10.857279-21.464871 0-38.864146 17.400299-38.864146 38.864146 0 9.497305 3.411703 18.196431 9.071609 24.947182l-0.001023 0c0.001023 0.001023 0.00307 0.00307 0.005117 0.004093 2.718925 3.242857 5.953595 6.03853 9.585309 8.251941 3.664459 3.021823 7.261381 5.997598 10.624988 9.361205l3.203972 3.204995c40.279379 40.229237 28.254507 109.539812-12.024871 149.820214L371.157763 796.383956c-40.278355 40.229237-105.761766 40.229237-146.042167 0l-3.229554-3.231601c-40.281425-40.278355-40.281425-105.809861 0-145.991002l75.93546-75.909877c9.742898-7.733125 15.997346-19.668968 15.997346-33.072233 0-23.312962-18.898419-42.211381-42.211381-42.211381-8.797363 0-16.963347 2.693342-23.725354 7.297197-0.021489-0.045025-0.044002-0.088004-0.066515-0.134053l-0.809435 0.757247c-2.989077 2.148943-5.691629 4.669346-8.025791 7.510044l-78.913281 73.841775c-74.178443 74.229608-74.178443 195.632609 0 269.758863l3.203972 3.202948c74.178443 74.127278 195.529255 74.127278 269.707698 0l171.829484-171.880649c74.076112-74.17435 80.357166-191.184297 6.282077-265.311575L607.934444 417.856853z\"></path><path d=\"M855.61957 165.804257l-3.203972-3.203972c-74.17742-74.178443-195.528232-74.178443-269.706675 0L410.87944 334.479911c-74.178443 74.178443-78.263481 181.296089-4.085038 255.522628l3.152806 3.104711c3.368724 3.367701 6.865361 6.54302 10.434653 9.588379 2.583848 2.885723 5.618974 5.355985 8.992815 7.309476 0.025583 0.020466 0.052189 0.041956 0.077771 0.062422l0.011256-0.010233c5.377474 3.092431 11.608386 4.870938 18.257829 4.870938 20.263509 0 36.68962-16.428158 36.68962-36.68962 0-5.719258-1.309832-11.132548-3.645017-15.95846l0 0c-4.850471-10.891048-13.930267-17.521049-20.210297-23.802102l-3.15383-3.102664c-40.278355-40.278355-24.982998-98.79612 15.295358-139.074476l171.930791-171.830507c40.179095-40.280402 105.685018-40.280402 145.965419 0l3.206018 3.152806c40.279379 40.281425 40.279379 105.838513 0 146.06775l-75.686796 75.737962c-10.296507 7.628748-16.97358 19.865443-16.97358 33.662681 0 23.12365 18.745946 41.87062 41.87062 41.87062 8.048303 0 15.563464-2.275833 21.944801-6.211469 0.048095 0.081864 0.093121 0.157589 0.141216 0.240477l1.173732-1.083681c3.616364-2.421142 6.828522-5.393847 9.529027-8.792247l79.766718-73.603345C929.798013 361.334535 929.798013 239.981676 855.61957 165.804257z\"></path></svg>";
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];
20 changes: 20 additions & 0 deletions src/views/editCode/link/esm/index.d.ts
Original file line number Diff line number Diff line change
@@ -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<string, string>;
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;
Loading

0 comments on commit fae58df

Please sign in to comment.