-
Notifications
You must be signed in to change notification settings - Fork 103
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
740 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; |
Oops, something went wrong.