@lexical/code 0.1.20 → 0.1.21
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/LexicalCode.dev.js +78 -40
- package/LexicalCode.js.flow +3 -0
- package/LexicalCode.prod.js +18 -17
- package/package.json +3 -3
package/LexicalCode.dev.js
CHANGED
|
@@ -91,6 +91,7 @@ function $createCodeHighlightNode(text, highlightType) {
|
|
|
91
91
|
function $isCodeHighlightNode(node) {
|
|
92
92
|
return node instanceof CodeHighlightNode;
|
|
93
93
|
}
|
|
94
|
+
const LANGUAGE_DATA_ATTRIBUTE = 'data-highlight-language';
|
|
94
95
|
class CodeNode extends lexical.ElementNode {
|
|
95
96
|
static getType() {
|
|
96
97
|
return 'code';
|
|
@@ -110,14 +111,31 @@ class CodeNode extends lexical.ElementNode {
|
|
|
110
111
|
const element = document.createElement('code');
|
|
111
112
|
utils.addClassNamesToElement(element, config.theme.code);
|
|
112
113
|
element.setAttribute('spellcheck', 'false');
|
|
114
|
+
const language = this.getLanguage();
|
|
115
|
+
|
|
116
|
+
if (language) {
|
|
117
|
+
element.setAttribute(LANGUAGE_DATA_ATTRIBUTE, language);
|
|
118
|
+
}
|
|
119
|
+
|
|
113
120
|
return element;
|
|
114
121
|
}
|
|
115
122
|
|
|
116
123
|
updateDOM(prevNode, dom) {
|
|
124
|
+
const language = this.__language;
|
|
125
|
+
const prevLanguage = prevNode.__language;
|
|
126
|
+
|
|
127
|
+
if (language) {
|
|
128
|
+
if (language !== prevLanguage) {
|
|
129
|
+
dom.setAttribute(LANGUAGE_DATA_ATTRIBUTE, language);
|
|
130
|
+
}
|
|
131
|
+
} else if (prevLanguage) {
|
|
132
|
+
dom.removeAttribute(LANGUAGE_DATA_ATTRIBUTE);
|
|
133
|
+
}
|
|
134
|
+
|
|
117
135
|
return false;
|
|
118
136
|
}
|
|
119
137
|
|
|
120
|
-
static
|
|
138
|
+
static importDOM() {
|
|
121
139
|
return {
|
|
122
140
|
div: node => ({
|
|
123
141
|
conversion: convertDivElement,
|
|
@@ -358,58 +376,66 @@ function textNodeTransform(node, editor) {
|
|
|
358
376
|
const parentNode = node.getParent();
|
|
359
377
|
|
|
360
378
|
if ($isCodeNode(parentNode)) {
|
|
361
|
-
codeNodeTransform(parentNode
|
|
379
|
+
codeNodeTransform(parentNode);
|
|
362
380
|
} else if ($isCodeHighlightNode(node)) {
|
|
363
381
|
// When code block converted into paragraph or other element
|
|
364
382
|
// code highlight nodes converted back to normal text
|
|
365
383
|
node.replace(lexical.$createTextNode(node.__text));
|
|
366
384
|
}
|
|
367
|
-
}
|
|
368
|
-
// will not affect code block content itself.
|
|
369
|
-
//
|
|
370
|
-
// Using extra flag (`isHighlighting`) since both CodeNode and CodeHighlightNode
|
|
371
|
-
// trasnforms might be called at the same time (e.g. new CodeHighlight node inserted) and
|
|
372
|
-
// in both cases we'll rerun whole reformatting over CodeNode, which is redundant.
|
|
373
|
-
// Especially when pasting code into CodeBlock.
|
|
374
|
-
|
|
385
|
+
}
|
|
375
386
|
|
|
376
|
-
|
|
387
|
+
function updateCodeGutter(node, editor) {
|
|
388
|
+
const codeElement = editor.getElementByKey(node.getKey());
|
|
377
389
|
|
|
378
|
-
|
|
379
|
-
if (isHighlighting) {
|
|
390
|
+
if (codeElement === null) {
|
|
380
391
|
return;
|
|
381
392
|
}
|
|
382
393
|
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
394
|
+
const children = node.getChildren();
|
|
395
|
+
const childrenLength = children.length; // $FlowFixMe: internal field
|
|
396
|
+
|
|
397
|
+
if (childrenLength === codeElement.__cachedChildrenLength) {
|
|
398
|
+
// Avoid updating the attribute if the children length hasn't changed.
|
|
399
|
+
return;
|
|
400
|
+
} // $FlowFixMe: internal field
|
|
401
|
+
|
|
402
|
+
|
|
403
|
+
codeElement.__cachedChildrenLength = childrenLength;
|
|
404
|
+
let gutter = '1';
|
|
405
|
+
let count = 1;
|
|
406
|
+
|
|
407
|
+
for (let i = 0; i < childrenLength; i++) {
|
|
408
|
+
if (lexical.$isLineBreakNode(children[i])) {
|
|
409
|
+
gutter += '\n' + ++count;
|
|
388
410
|
}
|
|
411
|
+
}
|
|
389
412
|
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
const tokens = Prism.tokenize(code, Prism.languages[node.getLanguage() || ''] || Prism.languages[DEFAULT_CODE_LANGUAGE]);
|
|
393
|
-
const highlightNodes = getHighlightNodes(tokens);
|
|
394
|
-
const diffRange = getDiffRange(node.getChildren(), highlightNodes);
|
|
395
|
-
const {
|
|
396
|
-
from,
|
|
397
|
-
to,
|
|
398
|
-
nodesForReplacement
|
|
399
|
-
} = diffRange;
|
|
413
|
+
codeElement.setAttribute('data-gutter', gutter);
|
|
414
|
+
}
|
|
400
415
|
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
416
|
+
function codeNodeTransform(node, editor) {
|
|
417
|
+
// When new code block inserted it might not have language selected
|
|
418
|
+
if (node.getLanguage() === undefined) {
|
|
419
|
+
node.setLanguage(DEFAULT_CODE_LANGUAGE);
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
updateAndRetainSelection(node, () => {
|
|
423
|
+
const code = node.getTextContent();
|
|
424
|
+
const tokens = Prism.tokenize(code, Prism.languages[node.getLanguage() || ''] || Prism.languages[DEFAULT_CODE_LANGUAGE]);
|
|
425
|
+
const highlightNodes = getHighlightNodes(tokens);
|
|
426
|
+
const diffRange = getDiffRange(node.getChildren(), highlightNodes);
|
|
427
|
+
const {
|
|
428
|
+
from,
|
|
429
|
+
to,
|
|
430
|
+
nodesForReplacement
|
|
431
|
+
} = diffRange;
|
|
432
|
+
|
|
433
|
+
if (from !== to || nodesForReplacement.length) {
|
|
434
|
+
node.splice(from, to - from, nodesForReplacement);
|
|
435
|
+
return true;
|
|
436
|
+
}
|
|
405
437
|
|
|
406
|
-
|
|
407
|
-
});
|
|
408
|
-
}, {
|
|
409
|
-
onUpdate: () => {
|
|
410
|
-
isHighlighting = false;
|
|
411
|
-
},
|
|
412
|
-
skipTransforms: true
|
|
438
|
+
return false;
|
|
413
439
|
});
|
|
414
440
|
}
|
|
415
441
|
|
|
@@ -699,7 +725,19 @@ function registerCodeHighlighting(editor) {
|
|
|
699
725
|
throw new Error('CodeHighlightPlugin: CodeNode or CodeHighlightNode not registered on editor');
|
|
700
726
|
}
|
|
701
727
|
|
|
702
|
-
return utils.mergeRegister(editor.
|
|
728
|
+
return utils.mergeRegister(editor.registerMutationListener(CodeNode, mutations => {
|
|
729
|
+
editor.update(() => {
|
|
730
|
+
for (const [key, type] of mutations) {
|
|
731
|
+
if (type !== 'destroyed') {
|
|
732
|
+
const node = lexical.$getNodeByKey(key);
|
|
733
|
+
|
|
734
|
+
if (node !== null) {
|
|
735
|
+
updateCodeGutter(node, editor);
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
});
|
|
740
|
+
}), editor.registerNodeTransform(CodeNode, node => codeNodeTransform(node)), editor.registerNodeTransform(lexical.TextNode, node => textNodeTransform(node)), editor.registerNodeTransform(CodeHighlightNode, node => textNodeTransform(node)), editor.registerCommand(lexical.INDENT_CONTENT_COMMAND, payload => handleMultilineIndent(lexical.INDENT_CONTENT_COMMAND), 1), editor.registerCommand(lexical.OUTDENT_CONTENT_COMMAND, payload => handleMultilineIndent(lexical.OUTDENT_CONTENT_COMMAND), 1), editor.registerCommand(lexical.KEY_ARROW_UP_COMMAND, payload => handleShiftLines(lexical.KEY_ARROW_UP_COMMAND, payload), 1), editor.registerCommand(lexical.KEY_ARROW_DOWN_COMMAND, payload => handleShiftLines(lexical.KEY_ARROW_DOWN_COMMAND, payload), 1));
|
|
703
741
|
}
|
|
704
742
|
|
|
705
743
|
exports.$createCodeHighlightNode = $createCodeHighlightNode;
|
package/LexicalCode.js.flow
CHANGED
|
@@ -14,6 +14,7 @@ import type {
|
|
|
14
14
|
ParagraphNode,
|
|
15
15
|
RangeSelection,
|
|
16
16
|
EditorThemeClasses,
|
|
17
|
+
LexicalEditor,
|
|
17
18
|
} from 'lexical';
|
|
18
19
|
|
|
19
20
|
import {ElementNode} from 'lexical';
|
|
@@ -72,3 +73,5 @@ declare export function $createCodeHighlightNode(
|
|
|
72
73
|
declare export function $isCodeHighlightNode(
|
|
73
74
|
node: ?LexicalNode,
|
|
74
75
|
): boolean %checks(node instanceof CodeHighlightNode);
|
|
76
|
+
|
|
77
|
+
declare export function registerCodeHighlighting(editor: LexicalEditor): () => void;
|
package/LexicalCode.prod.js
CHANGED
|
@@ -5,21 +5,22 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
var e=require("prismjs/components/prism-core");require("prismjs/components/prism-clike");require("prismjs/components/prism-javascript");require("prismjs/components/prism-markup");require("prismjs/components/prism-markdown");require("prismjs/components/prism-c");require("prismjs/components/prism-css");require("prismjs/components/prism-objectivec");require("prismjs/components/prism-sql");require("prismjs/components/prism-python");require("prismjs/components/prism-rust");require("prismjs/components/prism-swift");
|
|
8
|
-
var
|
|
9
|
-
class
|
|
10
|
-
function
|
|
11
|
-
class
|
|
12
|
-
{conversion:E,priority:4}:b&&C(b)?{conversion:F,priority:4}:null},tr:a=>(a=a.closest("table"))&&C(a)?{conversion:F,priority:4}:null}}insertNewAfter(a){var b=this.getChildren(),c=b.length;if(2<=c&&"\n"===b[c-1].getTextContent()&&"\n"===b[c-2].getTextContent()&&a.isCollapsed()&&
|
|
13
|
-
1;if(0<c)return c=d.substring(0,c),c=
|
|
14
|
-
function G(a){let b=null;const c=a.getPreviousSiblings();for(c.push(a);0<c.length&&(a=c.pop(),
|
|
15
|
-
function D(){return{node:H()}}function F(){return{node:null}}function E(a){return{after:b=>{a.parentNode&&a.parentNode.nextSibling&&b.push(
|
|
16
|
-
function
|
|
17
|
-
(a.
|
|
18
|
-
function
|
|
19
|
-
function
|
|
20
|
-
function
|
|
21
|
-
function
|
|
22
|
-
b
|
|
8
|
+
var n=require("@lexical/utils"),r=require("lexical");
|
|
9
|
+
class t extends r.TextNode{constructor(a,b,c){super(a,c);this.__highlightType=b}static getType(){return"code-highlight"}static clone(a){return new t(a.__text,a.__highlightType||void 0,a.__key)}createDOM(a){const b=super.createDOM(a);a=u(a.theme,this.__highlightType);n.addClassNamesToElement(b,a);return b}updateDOM(a,b,c){const d=super.updateDOM(a,b,c);a=u(c.theme,a.__highlightType);c=u(c.theme,this.__highlightType);a!==c&&(a&&n.removeClassNamesFromElement(b,a),c&&n.addClassNamesToElement(b,c));return d}setFormat(){return this.getWritable()}}
|
|
10
|
+
function u(a,b){return b&&a&&a.codeHighlight&&a.codeHighlight[b]}function w(a,b){return new t(a,b)}function x(a){return a instanceof t}
|
|
11
|
+
class y extends r.ElementNode{static getType(){return"code"}static clone(a){return new y(a.__language,a.__key)}constructor(a,b){super(b);this.__language=a}createDOM(a){const b=document.createElement("code");n.addClassNamesToElement(b,a.theme.code);b.setAttribute("spellcheck","false");(a=this.getLanguage())&&b.setAttribute("data-highlight-language",a);return b}updateDOM(a,b){const c=this.__language;a=a.__language;c?c!==a&&b.setAttribute("data-highlight-language",c):a&&b.removeAttribute("data-highlight-language");
|
|
12
|
+
return!1}static importDOM(){return{div:()=>({conversion:A,priority:1}),pre:()=>({conversion:B,priority:0}),table:a=>C(a)?{conversion:D,priority:4}:null,td:a=>{const b=a.closest("table");return a.classList.contains("js-file-line")?{conversion:E,priority:4}:b&&C(b)?{conversion:F,priority:4}:null},tr:a=>(a=a.closest("table"))&&C(a)?{conversion:F,priority:4}:null}}insertNewAfter(a){var b=this.getChildren(),c=b.length;if(2<=c&&"\n"===b[c-1].getTextContent()&&"\n"===b[c-2].getTextContent()&&a.isCollapsed()&&
|
|
13
|
+
a.anchor.key===this.__key&&a.anchor.offset===c)return b[c-1].remove(),b[c-2].remove(),a=r.$createParagraphNode(),this.insertAfter(a),a;b=a.anchor.getNode();var d=G(b);if(null!=d){c=0;for(d=d.getTextContent();c<d.length&&/[\t ]/.test(d[c]);)c+=1;if(0<c)return c=d.substring(0,c),c=w(c),b.insertAfter(c),a.insertNodes([r.$createLineBreakNode()]),c.select(),c}return null}canInsertTab(){return!0}collapseAtStart(){const a=r.$createParagraphNode();this.getChildren().forEach(b=>a.append(b));this.replace(a);
|
|
14
|
+
return!0}setLanguage(a){this.getWritable().__language=a}getLanguage(){return this.getLatest().__language}}function H(a){return new y(a)}function I(a){return a instanceof y}function G(a){let b=null;const c=a.getPreviousSiblings();for(c.push(a);0<c.length&&(a=c.pop(),x(a)&&(b=a),!r.$isLineBreakNode(a)););return b}function J(a){let b=null;const c=a.getNextSiblings();for(c.unshift(a);0<c.length&&(a=c.shift(),x(a)&&(b=a),!r.$isLineBreakNode(a)););return b}function B(){return{node:H()}}
|
|
15
|
+
function A(a){return{after:b=>{const c=a.parentNode;null!=c&&a!==c.lastChild&&b.push(r.$createLineBreakNode());return b},node:null!==a.style.fontFamily.match("monospace")?H():null}}function D(){return{node:H()}}function F(){return{node:null}}function E(a){return{after:b=>{a.parentNode&&a.parentNode.nextSibling&&b.push(r.$createLineBreakNode());return b},node:null}}function C(a){return a.classList.contains("js-file-line-container")}
|
|
16
|
+
function K(a){const b=a.getParent();I(b)?L(b):x(a)&&a.replace(r.$createTextNode(a.__text))}
|
|
17
|
+
function L(a){void 0===a.getLanguage()&&a.setLanguage("javascript");M(a,()=>{var b=a.getTextContent();b=e.tokenize(b,e.languages[a.getLanguage()||""]||e.languages.javascript);b=O(b);var c=a.getChildren();let d=0;for(;d<c.length&&P(c[d],b[d]);)d++;var h=c.length;const k=b.length,l=Math.min(h,k)-d;let f=0;for(;f<l;)if(f++,!P(c[h-f],b[k-f])){f--;break}c=d;h-=f;b=b.slice(d,k-f);const {from:m,to:g,nodesForReplacement:p}={from:c,nodesForReplacement:b,to:h};return m!==g||p.length?(a.splice(m,g-m,p),!0):
|
|
18
|
+
!1})}function O(a){const b=[];a.forEach(c=>{if("string"===typeof c){c=c.split("\n");for(var d=0;d<c.length;d++){const h=c[d];h.length&&b.push(w(h));d<c.length-1&&b.push(r.$createLineBreakNode())}}else({content:d}=c),"string"===typeof d?b.push(w(d,c.type)):1===d.length&&"string"===typeof d[0]?b.push(w(d[0],c.type)):b.push(...O(d))});return b}
|
|
19
|
+
function M(a,b){var c=r.$getSelection();if(r.$isRangeSelection(c)&&c.anchor){c=c.anchor;var d=c.offset,h="element"===c.type&&r.$isLineBreakNode(a.getChildAtIndex(c.offset-1)),k=0;if(!h){const l=c.getNode();k=d+l.getPreviousSiblings().reduce((f,m)=>f+(r.$isLineBreakNode(m)?0:m.getTextContentSize()),0)}b()&&(h?c.getNode().select(d,d):a.getChildren().some(l=>{if(r.$isTextNode(l)){const f=l.getTextContentSize();if(f>=k)return l.select(k,k),!0;k-=f}return!1}))}}
|
|
20
|
+
function P(a,b){return x(a)&&x(b)?a.__text===b.__text&&a.__highlightType===b.__highlightType:r.$isLineBreakNode(a)&&r.$isLineBreakNode(b)?!0:!1}function Q(a){var b=r.$getSelection();if(!r.$isRangeSelection(b)||b.isCollapsed())return!1;b=b.getNodes();for(var c=0;c<b.length;c++){var d=b[c];if(!x(d)&&!r.$isLineBreakNode(d))return!1}c=G(b[0]);null!=c&&R(c,a);for(c=1;c<b.length;c++)d=b[c],r.$isLineBreakNode(b[c-1])&&x(d)&&R(d,a);return!0}
|
|
21
|
+
function R(a,b){const c=a.getTextContent();b===r.INDENT_CONTENT_COMMAND?0<c.length&&/\s/.test(c[0])?a.setTextContent("\t"+c):(b=w("\t"),a.insertBefore(b)):0===c.indexOf("\t")&&(1===c.length?a.remove():a.setTextContent(c.substring(1)))}
|
|
22
|
+
function S(a,b){const c=r.$getSelection();if(!b.altKey||!r.$isRangeSelection(c))return!1;const {anchor:d,focus:h}=c,k=d.offset,l=h.offset,f=d.getNode(),m=h.getNode();if(!x(f)||!x(m))return!1;var g=G(f),p=J(m);if(null==g||null==p)return!1;const z=g.getNodesBetween(p);for(let q=0;q<z.length;q++){const N=z[q];if(!x(N)&&!r.$isLineBreakNode(N))return!1}b.preventDefault();b.stopPropagation();g=(b=a===r.KEY_ARROW_UP_COMMAND)?g.getPreviousSibling():p.getNextSibling();if(!r.$isLineBreakNode(g))return!0;p=
|
|
23
|
+
b?g.getPreviousSibling():g.getNextSibling();if(null==p)return!0;b=b?G(p):J(p);let v=null!=b?b:p;g.remove();z.forEach(q=>q.remove());a===r.KEY_ARROW_UP_COMMAND?(z.forEach(q=>v.insertBefore(q)),v.insertBefore(g)):(v.insertAfter(g),v=g,z.forEach(q=>{v.insertAfter(q);v=q}));c.setTextNodeRange(f,k,m,l);return!0}exports.$createCodeHighlightNode=w;exports.$createCodeNode=H;exports.$isCodeHighlightNode=x;exports.$isCodeNode=I;exports.CodeHighlightNode=t;exports.CodeNode=y;
|
|
23
24
|
exports.getCodeLanguages=()=>Object.keys(e.languages).filter(a=>"function"!==typeof e.languages[a]).sort();exports.getDefaultCodeLanguage=()=>"javascript";exports.getFirstCodeHighlightNodeOfLine=G;exports.getLastCodeHighlightNodeOfLine=J;
|
|
24
|
-
exports.registerCodeHighlighting=function(a){if(!a.hasNodes([
|
|
25
|
-
|
|
25
|
+
exports.registerCodeHighlighting=function(a){if(!a.hasNodes([y,t]))throw Error("CodeHighlightPlugin: CodeNode or CodeHighlightNode not registered on editor");return n.mergeRegister(a.registerMutationListener(y,b=>{a.update(()=>{for(const [h,k]of b)if("destroyed"!==k){var c=r.$getNodeByKey(h);if(null!==c)a:{var d=c;c=a.getElementByKey(d.getKey());if(null===c)break a;d=d.getChildren();const l=d.length;if(l===c.__cachedChildrenLength)break a;c.__cachedChildrenLength=l;let f="1",m=1;for(let g=0;g<l;g++)r.$isLineBreakNode(d[g])&&
|
|
26
|
+
(f+="\n"+ ++m);c.setAttribute("data-gutter",f)}}})}),a.registerNodeTransform(y,b=>L(b)),a.registerNodeTransform(r.TextNode,b=>K(b)),a.registerNodeTransform(t,b=>K(b)),a.registerCommand(r.INDENT_CONTENT_COMMAND,()=>Q(r.INDENT_CONTENT_COMMAND),1),a.registerCommand(r.OUTDENT_CONTENT_COMMAND,()=>Q(r.OUTDENT_CONTENT_COMMAND),1),a.registerCommand(r.KEY_ARROW_UP_COMMAND,b=>S(r.KEY_ARROW_UP_COMMAND,b),1),a.registerCommand(r.KEY_ARROW_DOWN_COMMAND,b=>S(r.KEY_ARROW_DOWN_COMMAND,b),1))};
|
package/package.json
CHANGED
|
@@ -8,13 +8,13 @@
|
|
|
8
8
|
"code"
|
|
9
9
|
],
|
|
10
10
|
"license": "MIT",
|
|
11
|
-
"version": "0.1.
|
|
11
|
+
"version": "0.1.21",
|
|
12
12
|
"main": "LexicalCode.js",
|
|
13
13
|
"peerDependencies": {
|
|
14
|
-
"lexical": "0.1.
|
|
14
|
+
"lexical": "0.1.21"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@lexical/utils": "0.1.
|
|
17
|
+
"@lexical/utils": "0.1.21",
|
|
18
18
|
"prismjs": "^1.25.0"
|
|
19
19
|
},
|
|
20
20
|
"repository": {
|