From f3e44e83a31ff06e34d3d3cc3dc9fc4c58ea7830 Mon Sep 17 00:00:00 2001 From: "zhangsheng.93" Date: Wed, 5 Jul 2023 17:30:45 +0000 Subject: [PATCH 1/5] fix: first open document, cherryMarkdown not have theme --- controllers/DocumentController.go | 4 ++++ static/prismjs/prismjs.css | 1 - 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/controllers/DocumentController.go b/controllers/DocumentController.go index f874224b..4483ddca 100644 --- a/controllers/DocumentController.go +++ b/controllers/DocumentController.go @@ -68,6 +68,10 @@ func (c *DocumentController) Index() { c.Data["Description"] = utils.AutoSummary(doc.Release, 120) c.Data["FoldSetting"] = "first" + if bookResult.Editor == EditorCherryMarkdown { + c.Data["MarkdownTheme"] = doc.MarkdownTheme + } + if bookResult.IsDisplayComment { // 获取评论、分页 comments, count, _ := models.NewComment().QueryCommentByDocumentId(doc.DocumentId, 1, conf.PageSize, c.Member) diff --git a/static/prismjs/prismjs.css b/static/prismjs/prismjs.css index 190d5f5f..2eebfac6 100644 --- a/static/prismjs/prismjs.css +++ b/static/prismjs/prismjs.css @@ -103,7 +103,6 @@ pre[class*=language-] { .token.operator, .token.url { color: #9a6e3a; - background: hsla(0, 0%, 100%, .5) } .token.atrule, From a6aa70037838427324a0c6e77cc02a64cdb6cb20 Mon Sep 17 00:00:00 2001 From: zhangsheng <244212647@qq.com> Date: Tue, 15 Aug 2023 17:39:38 +0800 Subject: [PATCH 2/5] fix: modify prismjs style and improve image clarity --- static/cherry/drawio-demo.js | 2 +- static/prismjs/prismjs.css | 103 +++++++++++++++++++++-------------- 2 files changed, 62 insertions(+), 43 deletions(-) diff --git a/static/cherry/drawio-demo.js b/static/cherry/drawio-demo.js index 8e0c0453..f4b4ea1e 100644 --- a/static/cherry/drawio-demo.js +++ b/static/cherry/drawio-demo.js @@ -53,7 +53,7 @@ function addPostMessageListener(graphEditor) { case 'getData': editorUIInstance.editor.graph.stopEditing(); var xmlData = mxUtils.getXml(editorUIInstance.editor.getGraphXml()); - editorUIInstance.exportImage(1, "#ffffff", true, null, true, 50, null, "png", function (base64, filename) { + editorUIInstance.exportImage(10, "#ffffff", true, null, true, 50, null, "png", function (base64, filename) { window.parent.postMessage({ mceAction: 'getData:success', eventName: 'getData:success', diff --git a/static/prismjs/prismjs.css b/static/prismjs/prismjs.css index 2eebfac6..383e21a8 100644 --- a/static/prismjs/prismjs.css +++ b/static/prismjs/prismjs.css @@ -1,10 +1,9 @@ -/* PrismJS 1.28.0 -https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript+bash+dart+go+java+kotlin+latex+markup-templating+matlab+mongodb+php+python+ruby+rust+sql+swift+systemd+typoscript+yaml&plugins=line-numbers+toolbar+copy-to-clipboard */ +/* PrismJS 1.29.0 +https://prismjs.com/download.html#themes=prism-tomorrow&languages=markup+css+clike+javascript */ code[class*=language-], pre[class*=language-] { - color: #f90505; + color: #ccc; background: 0 0; - text-shadow: 0 1px #fff; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; font-size: 1em; text-align: left; @@ -22,6 +21,12 @@ pre[class*=language-] { hyphens: none } +pre[class*=language-] { + padding: 1em; + margin: .5em 0; + overflow: auto +} + code[class*=language-] ::-moz-selection, code[class*=language-]::-moz-selection, pre[class*=language-] ::-moz-selection, @@ -46,15 +51,9 @@ pre[class*=language-]::selection { } } -pre[class*=language-] { - padding: 1em; - margin: .5em 0; - overflow: auto -} - :not(pre)>code[class*=language-], pre[class*=language-] { - background: #f5f2f0 + background: #2d2d2d } :not(pre)>code[class*=language-] { @@ -63,46 +62,79 @@ pre[class*=language-] { white-space: normal } +.token.block-comment, .token.cdata, .token.comment, .token.doctype, .token.prolog { - color: #708090 + color: #999 } .token.punctuation { - color: #999 + color: #ccc } -.token.namespace { - opacity: .7 +.token.attr-name, +.token.deleted, +.token.namespace, +.token.tag { + color: #e2777a +} + +.token.function-name { + color: #6196cc } .token.boolean, +.token.function, +.token.number { + color: #f08d49 +} + +.token.class-name, .token.constant, -.token.deleted, -.token.number, .token.property, -.token.symbol, -.token.tag { - color: #905 +.token.symbol { + color: #f8c555 } -.token.attr-name, +.token.atrule, .token.builtin, +.token.important, +.token.keyword, +.token.selector { + color: #cc99cd +} + +.token.attr-value, .token.char, -.token.inserted, -.token.selector, -.token.string { - color: #690 +.token.regex, +.token.string, +.token.variable { + color: #7ec699 } -.language-css .token.string, -.style .token.string, .token.entity, .token.operator, .token.url { - color: #9a6e3a; + color: #67cdcc +} + +.token.bold, +.token.important { + font-weight: 700 +} + +.token.italic { + font-style: italic +} + +.token.entity { + cursor: help +} + +.token.inserted { + color: green } .token.atrule, @@ -122,19 +154,6 @@ pre[class*=language-] { color: #e90 } -.token.bold, -.token.important { - font-weight: 700 -} - -.token.italic { - font-style: italic -} - -.token.entity { - cursor: help -} - pre[class*=language-].line-numbers { position: relative; padding-left: 3.8em !important; @@ -240,4 +259,4 @@ div.code-toolbar>.toolbar>.toolbar-item>span:hover { .cherry div.code-toolbar>.toolbar>.toolbar-item>button:focus, div.code-toolbar>.toolbar>.toolbar-item>button:hover { color: #1fa9e0be !important; -} \ No newline at end of file +} From 3695521f2206a266282834b3e34ed6b25cb2e807 Mon Sep 17 00:00:00 2001 From: "zhangsheng.93" Date: Tue, 15 Aug 2023 09:46:27 +0000 Subject: [PATCH 3/5] update cherry-markdown --- static/cherry/cherry-markdown.css | 2048 +- static/cherry/cherry-markdown.js | 168196 ++++++++++--------- static/cherry/cherry-markdown.min.js | 2 +- static/cherry/temp/cherry-markdown.js.map | 1 + 4 files changed, 88088 insertions(+), 82159 deletions(-) create mode 100644 static/cherry/temp/cherry-markdown.js.map diff --git a/static/cherry/cherry-markdown.css b/static/cherry/cherry-markdown.css index 994021c3..5f596f64 100644 --- a/static/cherry/cherry-markdown.css +++ b/static/cherry/cherry-markdown.css @@ -1,24 +1,19 @@ @charset "UTF-8"; - .cherry *::-webkit-scrollbar { height: 7px; width: 7px; background: transparent; } - .cherry *::-webkit-scrollbar:hover { background: rgba(128, 128, 128, 0.1); } - .cherry *::-webkit-scrollbar-thumb { background: #d3d7da; -webkit-border-radius: 6px; } - .cherry *::-webkit-scrollbar-thumb:hover { background: rgba(0, 0, 0, 0.6); } - .cherry *::-webkit-scrollbar-corner { background: transparent; } @@ -30,7 +25,6 @@ font-weight: normal; font-style: normal; } - .ch-icon:before { display: inline-block; font-family: "ch-icon"; @@ -368,13 +362,28 @@ content: "\ea6b"; } +.ch-icon-justify:before { + content: "\ea6c"; +} + +.ch-icon-justifyCenter:before { + content: "\ea6d"; +} + +.ch-icon-justifyLeft:before { + content: "\ea6e"; +} + +.ch-icon-justifyRight:before { + content: "\ea6f"; +} + .cherry-markdown { word-break: break-all; /* Specify class=linenums on a pre to get line numbering */ /* Inline code */ /* 数学表达式展示 */ } - .cherry-markdown h1, .cherry-markdown h2, .cherry-markdown h3, @@ -392,7 +401,6 @@ line-height: 1.1; color: inherit; } - .cherry-markdown h1 small, .cherry-markdown h2 small, .cherry-markdown h3 small, @@ -421,14 +429,12 @@ line-height: 1; color: #999; } - .cherry-markdown h1, .cherry-markdown h2, .cherry-markdown h3 { margin-top: 30px; margin-bottom: 16px; } - .cherry-markdown h1 small, .cherry-markdown h2 small, .cherry-markdown h3 small, @@ -437,14 +443,12 @@ .cherry-markdown h3 .small { font-size: 65%; } - .cherry-markdown h4, .cherry-markdown h5, .cherry-markdown h6 { margin-top: 12px; margin-bottom: 12px; } - .cherry-markdown h4 small, .cherry-markdown h5 small, .cherry-markdown h6 small, @@ -453,70 +457,57 @@ .cherry-markdown h6 .small { font-size: 75%; } - .cherry-markdown h1, .cherry-markdown .h1 { font-size: 2em; } - .cherry-markdown h2, .cherry-markdown .h2 { font-size: 1.5em; } - .cherry-markdown h3, .cherry-markdown .h3 { font-size: 1.25em; } - .cherry-markdown h4, .cherry-markdown .h4 { font-size: 1em; } - .cherry-markdown h5, .cherry-markdown .h5 { font-size: 0.875em; } - .cherry-markdown h6, .cherry-markdown .h6 { font-size: 0.85em; } - .cherry-markdown b, .cherry-markdown strong { font-weight: bold; } - .cherry-markdown ul, .cherry-markdown ol { padding-left: 24px; margin-bottom: 16px; } - .cherry-markdown ul ul, .cherry-markdown ul ol, .cherry-markdown ol ul, .cherry-markdown ol ol { margin-bottom: 0; } - .cherry-markdown ul li, .cherry-markdown ol li { list-style: inherit; } - .cherry-markdown ul li p, .cherry-markdown ol li p { margin: 0; } - .cherry-markdown div ul, .cherry-markdown div ol { margin-bottom: 0; } - .cherry-markdown hr { height: 0; border: 0; @@ -525,77 +516,62 @@ box-sizing: content-box; overflow: visible; } - .cherry-markdown table { border-collapse: collapse; } - .cherry-markdown table th, .cherry-markdown table td { border: 1px solid #dfe6ee; padding: 0.2em 0.4em; min-width: 100px; } - .cherry-markdown table th { background-color: #eee; } - .cherry-markdown .link-quote { color: #3582fb; } - .cherry-markdown a { color: #3582fb; position: relative; text-decoration: none; } - .cherry-markdown a[target=_blank] { padding: 0 2px; } - .cherry-markdown a[target=_blank]::after { content: "\ea10"; font-size: 12px; font-family: "ch-icon"; margin: 0 2px; } - .cherry-markdown a:hover { color: #056bad; } - .cherry-markdown em { font-style: italic; } - .cherry-markdown sup { vertical-align: super; } - .cherry-markdown sub { vertical-align: sub; } - .cherry-markdown figure { overflow-x: auto; } - .cherry-markdown blockquote { color: #6d6e6f; padding: 10px 15px; border-left: 10px solid #D6DBDF; background: rgba(102, 128, 153, 0.05); } - .cherry-markdown p, .cherry-markdown pre, .cherry-markdown blockquote, .cherry-markdown table { margin: 0 0 16px; } - .cherry-markdown pre { padding: 16px; overflow: auto; @@ -604,7 +580,6 @@ background-color: #f6f8fa; border-radius: 6px; } - .cherry-markdown .prettyprint { min-width: 500px; display: inline-block; @@ -612,25 +587,20 @@ font-family: Menlo, "Bitstream Vera Sans Mono", "DejaVu Sans Mono", Monaco, Consolas, monospace; border: 0 !important; } - .cherry-markdown .pln { color: #dfe6ee; } - .cherry-markdown .str { color: #ffaf21; } - .cherry-markdown .kwd { color: #f85353; } - .cherry-markdown ol.linenums { margin-top: 0; margin-bottom: 0; color: #969896; } - .cherry-markdown li.L0, .cherry-markdown li.L1, .cherry-markdown li.L2, @@ -645,7 +615,6 @@ background-color: #00212b; list-style-type: decimal; } - @media screen { .cherry-markdown .cherry-markdown { /* comment */ @@ -661,56 +630,43 @@ /* variable name */ /* function name */ } - .cherry-markdown .cherry-markdown .com { color: #969896; } - .cherry-markdown .cherry-markdown .typ { color: #81a2be; } - .cherry-markdown .cherry-markdown .lit { color: #de935f; } - .cherry-markdown .cherry-markdown .pun { color: #c5c8c6; } - .cherry-markdown .cherry-markdown .opn { color: #c5c8c6; } - .cherry-markdown .cherry-markdown .clo { color: #c5c8c6; } - .cherry-markdown .cherry-markdown .tag { color: #cc6666; } - .cherry-markdown .cherry-markdown .atn { color: #de935f; } - .cherry-markdown .cherry-markdown .atv { color: #8abeb7; } - .cherry-markdown .cherry-markdown .dec { color: #de935f; } - .cherry-markdown .cherry-markdown .var { color: #cc6666; } - .cherry-markdown .cherry-markdown .fun { color: #81a2be; } } - .cherry-markdown div[data-type=codeBlock] { display: inline-block; width: 100%; @@ -720,52 +676,43 @@ font-size: 14px; overflow-x: auto; } - -.cherry-markdown div[data-type=codeBlock]>pre { +.cherry-markdown div[data-type=codeBlock] > pre { margin: 0; } - -.cherry-markdown div[data-type=codeBlock]>pre code[class*=language-] { +.cherry-markdown div[data-type=codeBlock] > pre code[class*=language-] { counter-reset: line; } - -.cherry-markdown div[data-type=codeBlock]>pre code[class*=language-].wrap { +.cherry-markdown div[data-type=codeBlock] > pre code[class*=language-].wrap { white-space: pre-wrap; } - -.cherry-markdown div[data-type=codeBlock]>pre code[class*=language-] .code-line { +.cherry-markdown div[data-type=codeBlock] > pre code[class*=language-] .code-line { display: inline-block; position: relative; padding-left: 3em; height: 1.3em; line-height: 2em; } - -.cherry-markdown div[data-type=codeBlock]>pre code[class*=language-] .code-line:before { +.cherry-markdown div[data-type=codeBlock] > pre code[class*=language-] .code-line:before { counter-increment: line; content: counter(line); margin-right: 1em; position: absolute; left: 0; } - -.cherry-markdown div[data-type=codeBlock]>pre code[class*=language-] .code-line:last-child { +.cherry-markdown div[data-type=codeBlock] > pre code[class*=language-] .code-line:last-child { margin-bottom: 0; } - -.cherry-markdown :not(pre)>code { +.cherry-markdown :not(pre) > code { padding: 0.1em; border-radius: 0.3em; white-space: normal; color: #f85353; background-color: #e5e5e5; } - -[data-inline-code-theme=black] .cherry-markdown :not(pre)>code { +[data-inline-code-theme=black] .cherry-markdown :not(pre) > code { color: #3f4a56; background-color: #e5e5e5; } - .cherry-markdown a.anchor:before { content: "§"; text-decoration: none; @@ -776,45 +723,36 @@ text-align: center; margin-left: -15px; } - .cherry-markdown .toc { margin-bottom: 16px; padding-left: 0; } - .cherry-markdown .toc .toc-title { font-size: 24px; margin-bottom: 5px; } - .cherry-markdown .toc .toc-li { border-bottom: 1px ridge #dfe6ee; list-style: none; } - .cherry-markdown .toc .toc-li a { text-decoration: none; color: #3f4a56; } - .cherry-markdown .toc .toc-li a:hover { color: #056bad; } - .cherry-markdown .check-list-item { list-style: none; } - .cherry-markdown .check-list-item .ch-icon { margin: 0 6px 0 -20px; } - .cherry-markdown .footnote:not(a) { padding-top: 20px; border-top: 1px solid #dfe6ee; margin-top: 50px; } - .cherry-markdown .footnote:not(a) .footnote-title { font-size: 20px; margin-top: -38px; @@ -822,29 +760,24 @@ width: 60px; margin-bottom: 16px; } - .cherry-markdown .footnote:not(a) .one-footnote { color: #6d6e6f; margin-bottom: 16px; border-bottom: 1px dotted #dfe6ee; } - .cherry-markdown .cherry-table-container { max-width: 100%; overflow-x: auto; } - .cherry-markdown .cherry-table-container .cherry-table th, .cherry-markdown .cherry-table-container .cherry-table td { border: 1px solid #dfe6ee; padding: 0.2em 0.4em; min-width: 100px; } - .cherry-markdown .cherry-table-container .cherry-table th { white-space: nowrap; } - .cherry-markdown mjx-assistive-mml { position: absolute; top: 0; @@ -853,11 +786,9 @@ padding: 1px 0 0 0; border: 0; } - .cherry-markdown.head-num { counter-reset: level1; } - .cherry-markdown.head-num h1 .anchor:before, .cherry-markdown.head-num h2 .anchor:before, .cherry-markdown.head-num h3 .anchor:before, @@ -869,52 +800,41 @@ vertical-align: inherit; padding-right: 10px; } - .cherry-markdown.head-num h1 { counter-reset: level2; } - .cherry-markdown.head-num h2 { counter-reset: level3; } - .cherry-markdown.head-num h3 { counter-reset: level4; } - .cherry-markdown.head-num h4 { counter-reset: level5; } - .cherry-markdown.head-num h5 { counter-reset: level6; } - .cherry-markdown.head-num h1 .anchor:before { counter-increment: level1; content: counter(level1) ". "; } - .cherry-markdown.head-num h2 .anchor:before { counter-increment: level2; content: counter(level1) "." counter(level2) " "; } - .cherry-markdown.head-num h3 .anchor:before { counter-increment: level3; content: counter(level1) "." counter(level2) "." counter(level3) " "; } - .cherry-markdown.head-num h4 .anchor:before { counter-increment: level4; content: counter(level1) "." counter(level2) "." counter(level3) "." counter(level4) " "; } - .cherry-markdown.head-num h5 .anchor:before { counter-increment: level5; content: counter(level1) "." counter(level2) "." counter(level3) "." counter(level4) "." counter(level5) " "; } - .cherry-markdown.head-num h6 .anchor:before { counter-increment: level6; content: counter(level1) "." counter(level2) "." counter(level3) "." counter(level4) "." counter(level5) "." counter(level6) " "; @@ -931,7 +851,6 @@ div[data-type=codeBlock] { /* Code blocks */ /* Inline code */ } - div[data-type=codeBlock] code[class*=language-], div[data-type=codeBlock] pre[class*=language-] { color: #ccc; @@ -952,24 +871,20 @@ div[data-type=codeBlock] pre[class*=language-] { -ms-hyphens: none; hyphens: none; } - div[data-type=codeBlock] pre[class*=language-] { padding: 1em; margin: 0.5em 0; overflow: auto; } - -div[data-type=codeBlock] :not(pre)>code[class*=language-], +div[data-type=codeBlock] :not(pre) > code[class*=language-], div[data-type=codeBlock] pre[class*=language-] { background: #2d2d2d; } - -div[data-type=codeBlock] :not(pre)>code[class*=language-] { +div[data-type=codeBlock] :not(pre) > code[class*=language-] { padding: 0.1em; border-radius: 0.3em; white-space: normal; } - div[data-type=codeBlock] .token.comment, div[data-type=codeBlock] .token.block-comment, div[data-type=codeBlock] .token.prolog, @@ -977,35 +892,29 @@ div[data-type=codeBlock] .token.doctype, div[data-type=codeBlock] .token.cdata { color: #999; } - div[data-type=codeBlock] .token.punctuation { color: #ccc; } - div[data-type=codeBlock] .token.tag, div[data-type=codeBlock] .token.attr-name, div[data-type=codeBlock] .token.namespace, div[data-type=codeBlock] .token.deleted { color: #e2777a; } - div[data-type=codeBlock] .token.function-name { color: #6196cc; } - div[data-type=codeBlock] .token.boolean, div[data-type=codeBlock] .token.number, div[data-type=codeBlock] .token.function { color: #f08d49; } - div[data-type=codeBlock] .token.property, div[data-type=codeBlock] .token.class-name, div[data-type=codeBlock] .token.constant, div[data-type=codeBlock] .token.symbol { color: #f8c555; } - div[data-type=codeBlock] .token.selector, div[data-type=codeBlock] .token.important, div[data-type=codeBlock] .token.atrule, @@ -1013,7 +922,6 @@ div[data-type=codeBlock] .token.keyword, div[data-type=codeBlock] .token.builtin { color: #cc99cd; } - div[data-type=codeBlock] .token.string, div[data-type=codeBlock] .token.char, div[data-type=codeBlock] .token.attr-value, @@ -1021,30 +929,24 @@ div[data-type=codeBlock] .token.regex, div[data-type=codeBlock] .token.variable { color: #7ec699; } - div[data-type=codeBlock] .token.operator, div[data-type=codeBlock] .token.entity, div[data-type=codeBlock] .token.url { color: #67cdcc; } - div[data-type=codeBlock] .token.important, div[data-type=codeBlock] .token.bold { font-weight: bold; } - div[data-type=codeBlock] .token.italic { font-style: italic; } - div[data-type=codeBlock] .token.entity { cursor: help; } - div[data-type=codeBlock] .token.inserted { color: green; } - [data-code-block-theme=default] div[data-type=codeBlock] { /* PrismJS 1.23.0 https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript+abap+abnf+actionscript+ada+agda+al+antlr4+apacheconf+apex+apl+applescript+aql+arduino+arff+asciidoc+aspnet+asm6502+autohotkey+autoit+bash+basic+batch+bbcode+birb+bison+bnf+brainfuck+brightscript+bro+bsl+c+csharp+cpp+cfscript+chaiscript+cil+clojure+cmake+cobol+coffeescript+concurnas+csp+coq+crystal+css-extras+csv+cypher+d+dart+dataweave+dax+dhall+diff+django+dns-zone-file+docker+dot+ebnf+editorconfig+eiffel+ejs+elixir+elm+etlua+erb+erlang+excel-formula+fsharp+factor+false+firestore-security-rules+flow+fortran+ftl+gml+gcode+gdscript+gedcom+gherkin+git+glsl+go+graphql+groovy+haml+handlebars+haskell+haxe+hcl+hlsl+http+hpkp+hsts+ichigojam+icon+icu-message-format+idris+ignore+inform7+ini+io+j+java+javadoc+javadoclike+javastacktrace+jexl+jolie+jq+jsdoc+js-extras+json+json5+jsonp+jsstacktrace+js-templates+julia+keyman+kotlin+kumir+latex+latte+less+lilypond+liquid+lisp+livescript+llvm+log+lolcode+lua+makefile+markdown+markup-templating+matlab+mel+mizar+mongodb+monkey+moonscript+n1ql+n4js+nand2tetris-hdl+naniscript+nasm+neon+nevod+nginx+nim+nix+nsis+objectivec+ocaml+opencl+openqasm+oz+parigp+parser+pascal+pascaligo+psl+pcaxis+peoplecode+perl+php+phpdoc+php-extras+plsql+powerquery+powershell+processing+prolog+promql+properties+protobuf+pug+puppet+pure+purebasic+purescript+python+qsharp+q+qml+qore+r+racket+jsx+tsx+reason+regex+rego+renpy+rest+rip+roboconf+robotframework+ruby+rust+sas+sass+scss+scala+scheme+shell-session+smali+smalltalk+smarty+sml+solidity+solution-file+soy+sparql+splunk-spl+sqf+sql+squirrel+stan+iecst+stylus+swift+t4-templating+t4-cs+t4-vb+tap+tcl+tt2+textile+toml+turtle+twig+typescript+typoscript+unrealscript+uri+v+vala+vbnet+velocity+verilog+vhdl+vim+visual-basic+warpscript+wasm+wiki+wolfram+xeora+xml-doc+xojo+xquery+yaml+yang+zig */ @@ -1056,7 +958,6 @@ div[data-type=codeBlock] .token.inserted { /* Code blocks */ /* Inline code */ } - [data-code-block-theme=default] div[data-type=codeBlock] code[class*=language-], [data-code-block-theme=default] div[data-type=codeBlock] pre[class*=language-] { color: black; @@ -1078,63 +979,48 @@ div[data-type=codeBlock] .token.inserted { -ms-hyphens: none; hyphens: none; } - -[data-code-block-theme=default] div[data-type=codeBlock] pre[class*=language-]::-moz-selection, -[data-code-block-theme=default] div[data-type=codeBlock] pre[class*=language-] ::-moz-selection, -[data-code-block-theme=default] div[data-type=codeBlock] code[class*=language-]::-moz-selection, -[data-code-block-theme=default] div[data-type=codeBlock] code[class*=language-] ::-moz-selection { +[data-code-block-theme=default] div[data-type=codeBlock] pre[class*=language-]::-moz-selection, [data-code-block-theme=default] div[data-type=codeBlock] pre[class*=language-] ::-moz-selection, +[data-code-block-theme=default] div[data-type=codeBlock] code[class*=language-]::-moz-selection, [data-code-block-theme=default] div[data-type=codeBlock] code[class*=language-] ::-moz-selection { text-shadow: none; background: #b3d4fc; } - -[data-code-block-theme=default] div[data-type=codeBlock] pre[class*=language-]::selection, -[data-code-block-theme=default] div[data-type=codeBlock] pre[class*=language-] ::selection, -[data-code-block-theme=default] div[data-type=codeBlock] code[class*=language-]::selection, -[data-code-block-theme=default] div[data-type=codeBlock] code[class*=language-] ::selection { +[data-code-block-theme=default] div[data-type=codeBlock] pre[class*=language-]::selection, [data-code-block-theme=default] div[data-type=codeBlock] pre[class*=language-] ::selection, +[data-code-block-theme=default] div[data-type=codeBlock] code[class*=language-]::selection, [data-code-block-theme=default] div[data-type=codeBlock] code[class*=language-] ::selection { text-shadow: none; background: #b3d4fc; } - @media print { - [data-code-block-theme=default] div[data-type=codeBlock] code[class*=language-], - [data-code-block-theme=default] div[data-type=codeBlock] pre[class*=language-] { +[data-code-block-theme=default] div[data-type=codeBlock] pre[class*=language-] { text-shadow: none; } } - [data-code-block-theme=default] div[data-type=codeBlock] pre[class*=language-] { padding: 1em; margin: 0.5em 0; overflow: auto; } - -[data-code-block-theme=default] div[data-type=codeBlock] :not(pre)>code[class*=language-], +[data-code-block-theme=default] div[data-type=codeBlock] :not(pre) > code[class*=language-], [data-code-block-theme=default] div[data-type=codeBlock] pre[class*=language-] { background: #f5f2f0; } - -[data-code-block-theme=default] div[data-type=codeBlock] :not(pre)>code[class*=language-] { +[data-code-block-theme=default] div[data-type=codeBlock] :not(pre) > code[class*=language-] { padding: 0.1em; border-radius: 0.3em; white-space: normal; } - [data-code-block-theme=default] div[data-type=codeBlock] .token.comment, [data-code-block-theme=default] div[data-type=codeBlock] .token.prolog, [data-code-block-theme=default] div[data-type=codeBlock] .token.doctype, [data-code-block-theme=default] div[data-type=codeBlock] .token.cdata { color: slategray; } - [data-code-block-theme=default] div[data-type=codeBlock] .token.punctuation { color: #999; } - [data-code-block-theme=default] div[data-type=codeBlock] .token.namespace { opacity: 0.7; } - [data-code-block-theme=default] div[data-type=codeBlock] .token.property, [data-code-block-theme=default] div[data-type=codeBlock] .token.tag, [data-code-block-theme=default] div[data-type=codeBlock] .token.boolean, @@ -1144,7 +1030,6 @@ div[data-type=codeBlock] .token.inserted { [data-code-block-theme=default] div[data-type=codeBlock] .token.deleted { color: #905; } - [data-code-block-theme=default] div[data-type=codeBlock] .token.selector, [data-code-block-theme=default] div[data-type=codeBlock] .token.attr-name, [data-code-block-theme=default] div[data-type=codeBlock] .token.string, @@ -1153,7 +1038,6 @@ div[data-type=codeBlock] .token.inserted { [data-code-block-theme=default] div[data-type=codeBlock] .token.inserted { color: #690; } - [data-code-block-theme=default] div[data-type=codeBlock] .token.operator, [data-code-block-theme=default] div[data-type=codeBlock] .token.entity, [data-code-block-theme=default] div[data-type=codeBlock] .token.url, @@ -1163,37 +1047,30 @@ div[data-type=codeBlock] .token.inserted { /* This background color was intended by the author of this theme. */ background: hsla(0deg, 0%, 100%, 0.5); } - [data-code-block-theme=default] div[data-type=codeBlock] .token.atrule, [data-code-block-theme=default] div[data-type=codeBlock] .token.attr-value, [data-code-block-theme=default] div[data-type=codeBlock] .token.keyword { color: #07a; } - [data-code-block-theme=default] div[data-type=codeBlock] .token.function, [data-code-block-theme=default] div[data-type=codeBlock] .token.class-name { color: #DD4A68; } - [data-code-block-theme=default] div[data-type=codeBlock] .token.regex, [data-code-block-theme=default] div[data-type=codeBlock] .token.important, [data-code-block-theme=default] div[data-type=codeBlock] .token.variable { color: #e90; } - [data-code-block-theme=default] div[data-type=codeBlock] .token.important, [data-code-block-theme=default] div[data-type=codeBlock] .token.bold { font-weight: bold; } - [data-code-block-theme=default] div[data-type=codeBlock] .token.italic { font-style: italic; } - [data-code-block-theme=default] div[data-type=codeBlock] .token.entity { cursor: help; } - [data-code-block-theme=dark] div[data-type=codeBlock] { /* PrismJS 1.23.0 https://prismjs.com/download.html#themes=prism-dark&languages=markup+css+clike+javascript+abap+abnf+actionscript+ada+agda+al+antlr4+apacheconf+apex+apl+applescript+aql+arduino+arff+asciidoc+aspnet+asm6502+autohotkey+autoit+bash+basic+batch+bbcode+birb+bison+bnf+brainfuck+brightscript+bro+bsl+c+csharp+cpp+cfscript+chaiscript+cil+clojure+cmake+cobol+coffeescript+concurnas+csp+coq+crystal+css-extras+csv+cypher+d+dart+dataweave+dax+dhall+diff+django+dns-zone-file+docker+dot+ebnf+editorconfig+eiffel+ejs+elixir+elm+etlua+erb+erlang+excel-formula+fsharp+factor+false+firestore-security-rules+flow+fortran+ftl+gml+gcode+gdscript+gedcom+gherkin+git+glsl+go+graphql+groovy+haml+handlebars+haskell+haxe+hcl+hlsl+http+hpkp+hsts+ichigojam+icon+icu-message-format+ignore+inform7+ini+io+j+java+javadoc+javadoclike+javastacktrace+jexl+jolie+jq+jsdoc+js-extras+json+json5+jsonp+jsstacktrace+js-templates+julia+keyman+kotlin+kumir+latte+less+lilypond+liquid+lisp+livescript+llvm+log+lolcode+lua+makefile+markdown+markup-templating+matlab+mel+mizar+mongodb+monkey+moonscript+n1ql+n4js+nand2tetris-hdl+naniscript+nasm+neon+nevod+nginx+nim+nix+nsis+objectivec+ocaml+opencl+openqasm+oz+parigp+parser+pascal+pascaligo+psl+pcaxis+peoplecode+perl+php+phpdoc+php-extras+plsql+powerquery+powershell+processing+prolog+promql+properties+protobuf+pug+puppet+pure+purebasic+purescript+python+qsharp+q+qml+qore+r+racket+jsx+tsx+reason+regex+rego+renpy+rest+rip+roboconf+robotframework+ruby+rust+sas+sass+scss+scala+scheme+shell-session+smali+smalltalk+smarty+sml+solidity+solution-file+soy+sparql+splunk-spl+sqf+sql+squirrel+stan+iecst+stylus+swift+t4-templating+t4-cs+t4-vb+tap+tcl+tt2+textile+toml+turtle+twig+typescript+typoscript+unrealscript+uri+v+vala+vbnet+velocity+verilog+vhdl+vim+visual-basic+warpscript+wasm+wiki+wolfram+xeora+xml-doc+xojo+xquery+yaml+yang+zig */ @@ -1205,7 +1082,6 @@ div[data-type=codeBlock] .token.inserted { /* Code blocks */ /* Inline code */ } - [data-code-block-theme=dark] div[data-type=codeBlock] code[class*=language-], [data-code-block-theme=dark] div[data-type=codeBlock] pre[class*=language-] { color: white; @@ -1227,20 +1103,16 @@ div[data-type=codeBlock] .token.inserted { -ms-hyphens: none; hyphens: none; } - @media print { - [data-code-block-theme=dark] div[data-type=codeBlock] code[class*=language-], - [data-code-block-theme=dark] div[data-type=codeBlock] pre[class*=language-] { +[data-code-block-theme=dark] div[data-type=codeBlock] pre[class*=language-] { text-shadow: none; } } - [data-code-block-theme=dark] div[data-type=codeBlock] pre[class*=language-], -[data-code-block-theme=dark] div[data-type=codeBlock] :not(pre)>code[class*=language-] { +[data-code-block-theme=dark] div[data-type=codeBlock] :not(pre) > code[class*=language-] { background: hsl(30deg, 20%, 25%); } - [data-code-block-theme=dark] div[data-type=codeBlock] pre[class*=language-] { padding: 1em; margin: 0.5em 0; @@ -1249,30 +1121,25 @@ div[data-type=codeBlock] .token.inserted { border-radius: 0.5em; box-shadow: 1px 1px 0.5em black inset; } - -[data-code-block-theme=dark] div[data-type=codeBlock] :not(pre)>code[class*=language-] { +[data-code-block-theme=dark] div[data-type=codeBlock] :not(pre) > code[class*=language-] { padding: 0.15em 0.2em 0.05em; border-radius: 0.3em; border: 0.13em solid hsl(30deg, 20%, 40%); box-shadow: 1px 1px 0.3em -0.1em black inset; white-space: normal; } - [data-code-block-theme=dark] div[data-type=codeBlock] .token.comment, [data-code-block-theme=dark] div[data-type=codeBlock] .token.prolog, [data-code-block-theme=dark] div[data-type=codeBlock] .token.doctype, [data-code-block-theme=dark] div[data-type=codeBlock] .token.cdata { color: hsl(30deg, 20%, 50%); } - [data-code-block-theme=dark] div[data-type=codeBlock] .token.punctuation { opacity: 0.7; } - [data-code-block-theme=dark] div[data-type=codeBlock] .token.namespace { opacity: 0.7; } - [data-code-block-theme=dark] div[data-type=codeBlock] .token.property, [data-code-block-theme=dark] div[data-type=codeBlock] .token.tag, [data-code-block-theme=dark] div[data-type=codeBlock] .token.boolean, @@ -1281,7 +1148,6 @@ div[data-type=codeBlock] .token.inserted { [data-code-block-theme=dark] div[data-type=codeBlock] .token.symbol { color: hsl(350deg, 40%, 70%); } - [data-code-block-theme=dark] div[data-type=codeBlock] .token.selector, [data-code-block-theme=dark] div[data-type=codeBlock] .token.attr-name, [data-code-block-theme=dark] div[data-type=codeBlock] .token.string, @@ -1290,7 +1156,6 @@ div[data-type=codeBlock] .token.inserted { [data-code-block-theme=dark] div[data-type=codeBlock] .token.inserted { color: hsl(75deg, 70%, 60%); } - [data-code-block-theme=dark] div[data-type=codeBlock] .token.operator, [data-code-block-theme=dark] div[data-type=codeBlock] .token.entity, [data-code-block-theme=dark] div[data-type=codeBlock] .token.url, @@ -1299,35 +1164,28 @@ div[data-type=codeBlock] .token.inserted { [data-code-block-theme=dark] div[data-type=codeBlock] .token.variable { color: hsl(40deg, 90%, 60%); } - [data-code-block-theme=dark] div[data-type=codeBlock] .token.atrule, [data-code-block-theme=dark] div[data-type=codeBlock] .token.attr-value, [data-code-block-theme=dark] div[data-type=codeBlock] .token.keyword { color: hsl(350deg, 40%, 70%); } - [data-code-block-theme=dark] div[data-type=codeBlock] .token.regex, [data-code-block-theme=dark] div[data-type=codeBlock] .token.important { color: #e90; } - [data-code-block-theme=dark] div[data-type=codeBlock] .token.important, [data-code-block-theme=dark] div[data-type=codeBlock] .token.bold { font-weight: bold; } - [data-code-block-theme=dark] div[data-type=codeBlock] .token.italic { font-style: italic; } - [data-code-block-theme=dark] div[data-type=codeBlock] .token.entity { cursor: help; } - [data-code-block-theme=dark] div[data-type=codeBlock] .token.deleted { color: red; } - [data-code-block-theme=funky] div[data-type=codeBlock] { /* PrismJS 1.23.0 https://prismjs.com/download.html#themes=prism-funky&languages=markup+css+clike+javascript+abap+abnf+actionscript+ada+agda+al+antlr4+apacheconf+apex+apl+applescript+aql+arduino+arff+asciidoc+aspnet+asm6502+autohotkey+autoit+bash+basic+batch+bbcode+birb+bison+bnf+brainfuck+brightscript+bro+bsl+c+csharp+cpp+cfscript+chaiscript+cil+clojure+cmake+cobol+coffeescript+concurnas+csp+coq+crystal+css-extras+csv+cypher+d+dart+dataweave+dax+dhall+diff+django+dns-zone-file+docker+dot+ebnf+editorconfig+eiffel+ejs+elixir+elm+etlua+erb+erlang+excel-formula+fsharp+factor+false+firestore-security-rules+flow+fortran+ftl+gml+gcode+gdscript+gedcom+gherkin+git+glsl+go+graphql+groovy+haml+handlebars+haskell+haxe+hcl+hlsl+http+hpkp+hsts+ichigojam+icon+icu-message-format+ignore+inform7+ini+io+j+java+javadoc+javadoclike+javastacktrace+jexl+jolie+jq+jsdoc+js-extras+json+json5+jsonp+jsstacktrace+js-templates+julia+keyman+kotlin+kumir+latte+less+lilypond+liquid+lisp+livescript+llvm+log+lolcode+lua+makefile+markdown+markup-templating+matlab+mel+mizar+mongodb+monkey+moonscript+n1ql+n4js+nand2tetris-hdl+naniscript+nasm+neon+nevod+nginx+nim+nix+nsis+objectivec+ocaml+opencl+openqasm+oz+parigp+parser+pascal+pascaligo+psl+pcaxis+peoplecode+perl+php+phpdoc+php-extras+plsql+powerquery+powershell+processing+prolog+promql+properties+protobuf+pug+puppet+pure+purebasic+purescript+python+qsharp+q+qml+qore+r+racket+jsx+tsx+reason+regex+rego+renpy+rest+rip+roboconf+robotframework+ruby+rust+sas+sass+scss+scala+scheme+shell-session+smali+smalltalk+smarty+sml+solidity+solution-file+soy+sparql+splunk-spl+sqf+sql+squirrel+stan+iecst+stylus+swift+t4-templating+t4-cs+t4-vb+tap+tcl+tt2+textile+toml+turtle+twig+typescript+typoscript+unrealscript+uri+v+vala+vbnet+velocity+verilog+vhdl+vim+visual-basic+warpscript+wasm+wiki+wolfram+xeora+xml-doc+xojo+xquery+yaml+yang+zig */ @@ -1340,7 +1198,6 @@ div[data-type=codeBlock] .token.inserted { /* Inline code */ /* Plugin styles: Diff Highlight */ } - [data-code-block-theme=funky] div[data-type=codeBlock] code[class*=language-], [data-code-block-theme=funky] div[data-type=codeBlock] pre[class*=language-] { font-family: Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace; @@ -1359,7 +1216,6 @@ div[data-type=codeBlock] .token.inserted { -ms-hyphens: none; hyphens: none; } - [data-code-block-theme=funky] div[data-type=codeBlock] pre[class*=language-] { padding: 0.4em 0.8em; margin: 0.5em 0; @@ -1367,35 +1223,29 @@ div[data-type=codeBlock] .token.inserted { background: url('data:image/svg+xml;charset=utf-8,%0D%0A%0D%0A%0D%0A<%2Fsvg>'); background-size: 1em 1em; } - [data-code-block-theme=funky] div[data-type=codeBlock] code[class*=language-] { background: black; color: white; box-shadow: -0.3em 0 0 0.3em black, 0.3em 0 0 0.3em black; } - -[data-code-block-theme=funky] div[data-type=codeBlock] :not(pre)>code[class*=language-] { +[data-code-block-theme=funky] div[data-type=codeBlock] :not(pre) > code[class*=language-] { padding: 0.2em; border-radius: 0.3em; box-shadow: none; white-space: normal; } - [data-code-block-theme=funky] div[data-type=codeBlock] .token.comment, [data-code-block-theme=funky] div[data-type=codeBlock] .token.prolog, [data-code-block-theme=funky] div[data-type=codeBlock] .token.doctype, [data-code-block-theme=funky] div[data-type=codeBlock] .token.cdata { color: #aaa; } - [data-code-block-theme=funky] div[data-type=codeBlock] .token.punctuation { color: #999; } - [data-code-block-theme=funky] div[data-type=codeBlock] .token.namespace { opacity: 0.7; } - [data-code-block-theme=funky] div[data-type=codeBlock] .token.property, [data-code-block-theme=funky] div[data-type=codeBlock] .token.tag, [data-code-block-theme=funky] div[data-type=codeBlock] .token.boolean, @@ -1404,7 +1254,6 @@ div[data-type=codeBlock] .token.inserted { [data-code-block-theme=funky] div[data-type=codeBlock] .token.symbol { color: #0cf; } - [data-code-block-theme=funky] div[data-type=codeBlock] .token.selector, [data-code-block-theme=funky] div[data-type=codeBlock] .token.attr-name, [data-code-block-theme=funky] div[data-type=codeBlock] .token.string, @@ -1412,7 +1261,6 @@ div[data-type=codeBlock] .token.inserted { [data-code-block-theme=funky] div[data-type=codeBlock] .token.builtin { color: yellow; } - [data-code-block-theme=funky] div[data-type=codeBlock] .token.operator, [data-code-block-theme=funky] div[data-type=codeBlock] .token.entity, [data-code-block-theme=funky] div[data-type=codeBlock] .token.url, @@ -1421,47 +1269,38 @@ div[data-type=codeBlock] .token.inserted { [data-code-block-theme=funky] div[data-type=codeBlock] .token.inserted { color: yellowgreen; } - [data-code-block-theme=funky] div[data-type=codeBlock] .token.atrule, [data-code-block-theme=funky] div[data-type=codeBlock] .token.attr-value, [data-code-block-theme=funky] div[data-type=codeBlock] .token.keyword { color: deeppink; } - [data-code-block-theme=funky] div[data-type=codeBlock] .token.regex, [data-code-block-theme=funky] div[data-type=codeBlock] .token.important { color: orange; } - [data-code-block-theme=funky] div[data-type=codeBlock] .token.important, [data-code-block-theme=funky] div[data-type=codeBlock] .token.bold { font-weight: bold; } - [data-code-block-theme=funky] div[data-type=codeBlock] .token.italic { font-style: italic; } - [data-code-block-theme=funky] div[data-type=codeBlock] .token.entity { cursor: help; } - [data-code-block-theme=funky] div[data-type=codeBlock] .token.deleted { color: red; } - -[data-code-block-theme=funky] div[data-type=codeBlock] pre.diff-highlight.diff-highlight>code .token.deleted:not(.prefix), -[data-code-block-theme=funky] div[data-type=codeBlock] pre>code.diff-highlight.diff-highlight .token.deleted:not(.prefix) { +[data-code-block-theme=funky] div[data-type=codeBlock] pre.diff-highlight.diff-highlight > code .token.deleted:not(.prefix), +[data-code-block-theme=funky] div[data-type=codeBlock] pre > code.diff-highlight.diff-highlight .token.deleted:not(.prefix) { background-color: rgba(255, 0, 0, 0.3); display: inline; } - -[data-code-block-theme=funky] div[data-type=codeBlock] pre.diff-highlight.diff-highlight>code .token.inserted:not(.prefix), -[data-code-block-theme=funky] div[data-type=codeBlock] pre>code.diff-highlight.diff-highlight .token.inserted:not(.prefix) { +[data-code-block-theme=funky] div[data-type=codeBlock] pre.diff-highlight.diff-highlight > code .token.inserted:not(.prefix), +[data-code-block-theme=funky] div[data-type=codeBlock] pre > code.diff-highlight.diff-highlight .token.inserted:not(.prefix) { background-color: rgba(0, 255, 128, 0.3); display: inline; } - [data-code-block-theme=okaidia] div[data-type=codeBlock] { /* PrismJS 1.23.0 https://prismjs.com/download.html#themes=prism-okaidia&languages=markup+css+clike+javascript+abap+abnf+actionscript+ada+agda+al+antlr4+apacheconf+apex+apl+applescript+aql+arduino+arff+asciidoc+aspnet+asm6502+autohotkey+autoit+bash+basic+batch+bbcode+birb+bison+bnf+brainfuck+brightscript+bro+bsl+c+csharp+cpp+cfscript+chaiscript+cil+clojure+cmake+cobol+coffeescript+concurnas+csp+coq+crystal+css-extras+csv+cypher+d+dart+dataweave+dax+dhall+diff+django+dns-zone-file+docker+dot+ebnf+editorconfig+eiffel+ejs+elixir+elm+etlua+erb+erlang+excel-formula+fsharp+factor+false+firestore-security-rules+flow+fortran+ftl+gml+gcode+gdscript+gedcom+gherkin+git+glsl+go+graphql+groovy+haml+handlebars+haskell+haxe+hcl+hlsl+http+hpkp+hsts+ichigojam+icon+icu-message-format+ignore+inform7+ini+io+j+java+javadoc+javadoclike+javastacktrace+jexl+jolie+jq+jsdoc+js-extras+json+json5+jsonp+jsstacktrace+js-templates+julia+keyman+kotlin+kumir+latte+less+lilypond+liquid+lisp+livescript+llvm+log+lolcode+lua+makefile+markdown+markup-templating+matlab+mel+mizar+mongodb+monkey+moonscript+n1ql+n4js+nand2tetris-hdl+naniscript+nasm+neon+nevod+nginx+nim+nix+nsis+objectivec+ocaml+opencl+openqasm+oz+parigp+parser+pascal+pascaligo+psl+pcaxis+peoplecode+perl+php+phpdoc+php-extras+plsql+powerquery+powershell+processing+prolog+promql+properties+protobuf+pug+puppet+pure+purebasic+purescript+python+qsharp+q+qml+qore+r+racket+jsx+tsx+reason+regex+rego+renpy+rest+rip+roboconf+robotframework+ruby+rust+sas+sass+scss+scala+scheme+shell-session+smali+smalltalk+smarty+sml+solidity+solution-file+soy+sparql+splunk-spl+sqf+sql+squirrel+stan+iecst+stylus+swift+t4-templating+t4-cs+t4-vb+tap+tcl+tt2+textile+toml+turtle+twig+typescript+typoscript+unrealscript+uri+v+vala+vbnet+velocity+verilog+vhdl+vim+visual-basic+warpscript+wasm+wiki+wolfram+xeora+xml-doc+xojo+xquery+yaml+yang+zig */ @@ -1473,7 +1312,6 @@ div[data-type=codeBlock] .token.inserted { /* Code blocks */ /* Inline code */ } - [data-code-block-theme=okaidia] div[data-type=codeBlock] code[class*=language-], [data-code-block-theme=okaidia] div[data-type=codeBlock] pre[class*=language-] { color: #f8f8f2; @@ -1495,40 +1333,33 @@ div[data-type=codeBlock] .token.inserted { -ms-hyphens: none; hyphens: none; } - [data-code-block-theme=okaidia] div[data-type=codeBlock] pre[class*=language-] { padding: 1em; margin: 0.5em 0; overflow: auto; border-radius: 0.3em; } - -[data-code-block-theme=okaidia] div[data-type=codeBlock] :not(pre)>code[class*=language-], +[data-code-block-theme=okaidia] div[data-type=codeBlock] :not(pre) > code[class*=language-], [data-code-block-theme=okaidia] div[data-type=codeBlock] pre[class*=language-] { background: #272822; } - -[data-code-block-theme=okaidia] div[data-type=codeBlock] :not(pre)>code[class*=language-] { +[data-code-block-theme=okaidia] div[data-type=codeBlock] :not(pre) > code[class*=language-] { padding: 0.1em; border-radius: 0.3em; white-space: normal; } - [data-code-block-theme=okaidia] div[data-type=codeBlock] .token.comment, [data-code-block-theme=okaidia] div[data-type=codeBlock] .token.prolog, [data-code-block-theme=okaidia] div[data-type=codeBlock] .token.doctype, [data-code-block-theme=okaidia] div[data-type=codeBlock] .token.cdata { color: #8292a2; } - [data-code-block-theme=okaidia] div[data-type=codeBlock] .token.punctuation { color: #f8f8f2; } - [data-code-block-theme=okaidia] div[data-type=codeBlock] .token.namespace { opacity: 0.7; } - [data-code-block-theme=okaidia] div[data-type=codeBlock] .token.property, [data-code-block-theme=okaidia] div[data-type=codeBlock] .token.tag, [data-code-block-theme=okaidia] div[data-type=codeBlock] .token.constant, @@ -1536,12 +1367,10 @@ div[data-type=codeBlock] .token.inserted { [data-code-block-theme=okaidia] div[data-type=codeBlock] .token.deleted { color: #f92672; } - [data-code-block-theme=okaidia] div[data-type=codeBlock] .token.boolean, [data-code-block-theme=okaidia] div[data-type=codeBlock] .token.number { color: #ae81ff; } - [data-code-block-theme=okaidia] div[data-type=codeBlock] .token.selector, [data-code-block-theme=okaidia] div[data-type=codeBlock] .token.attr-name, [data-code-block-theme=okaidia] div[data-type=codeBlock] .token.string, @@ -1550,7 +1379,6 @@ div[data-type=codeBlock] .token.inserted { [data-code-block-theme=okaidia] div[data-type=codeBlock] .token.inserted { color: #a6e22e; } - [data-code-block-theme=okaidia] div[data-type=codeBlock] .token.operator, [data-code-block-theme=okaidia] div[data-type=codeBlock] .token.entity, [data-code-block-theme=okaidia] div[data-type=codeBlock] .token.url, @@ -1559,36 +1387,29 @@ div[data-type=codeBlock] .token.inserted { [data-code-block-theme=okaidia] div[data-type=codeBlock] .token.variable { color: #f8f8f2; } - [data-code-block-theme=okaidia] div[data-type=codeBlock] .token.atrule, [data-code-block-theme=okaidia] div[data-type=codeBlock] .token.attr-value, [data-code-block-theme=okaidia] div[data-type=codeBlock] .token.function, [data-code-block-theme=okaidia] div[data-type=codeBlock] .token.class-name { color: #e6db74; } - [data-code-block-theme=okaidia] div[data-type=codeBlock] .token.keyword { color: #66d9ef; } - [data-code-block-theme=okaidia] div[data-type=codeBlock] .token.regex, [data-code-block-theme=okaidia] div[data-type=codeBlock] .token.important { color: #fd971f; } - [data-code-block-theme=okaidia] div[data-type=codeBlock] .token.important, [data-code-block-theme=okaidia] div[data-type=codeBlock] .token.bold { font-weight: bold; } - [data-code-block-theme=okaidia] div[data-type=codeBlock] .token.italic { font-style: italic; } - [data-code-block-theme=okaidia] div[data-type=codeBlock] .token.entity { cursor: help; } - [data-code-block-theme=twilight] div[data-type=codeBlock] { /* PrismJS 1.23.0 https://prismjs.com/download.html#themes=prism-twilight&languages=markup+css+clike+javascript+abap+abnf+actionscript+ada+agda+al+antlr4+apacheconf+apex+apl+applescript+aql+arduino+arff+asciidoc+aspnet+asm6502+autohotkey+autoit+bash+basic+batch+bbcode+birb+bison+bnf+brainfuck+brightscript+bro+bsl+c+csharp+cpp+cfscript+chaiscript+cil+clojure+cmake+cobol+coffeescript+concurnas+csp+coq+crystal+css-extras+csv+cypher+d+dart+dataweave+dax+dhall+diff+django+dns-zone-file+docker+dot+ebnf+editorconfig+eiffel+ejs+elixir+elm+etlua+erb+erlang+excel-formula+fsharp+factor+false+firestore-security-rules+flow+fortran+ftl+gml+gcode+gdscript+gedcom+gherkin+git+glsl+go+graphql+groovy+haml+handlebars+haskell+haxe+hcl+hlsl+http+hpkp+hsts+ichigojam+icon+icu-message-format+idris+ignore+inform7+ini+io+j+java+javadoc+javadoclike+javastacktrace+jexl+jolie+jq+jsdoc+js-extras+json+json5+jsonp+jsstacktrace+js-templates+julia+keyman+kotlin+kumir+latex+latte+less+lilypond+liquid+lisp+livescript+llvm+log+lolcode+lua+makefile+markdown+markup-templating+matlab+mel+mizar+mongodb+monkey+moonscript+n1ql+n4js+nand2tetris-hdl+naniscript+nasm+neon+nevod+nginx+nim+nix+nsis+objectivec+ocaml+opencl+openqasm+oz+parigp+parser+pascal+pascaligo+psl+pcaxis+peoplecode+perl+php+phpdoc+php-extras+plsql+powerquery+powershell+processing+prolog+promql+properties+protobuf+pug+puppet+pure+purebasic+purescript+python+qsharp+q+qml+qore+r+racket+jsx+tsx+reason+regex+rego+renpy+rest+rip+roboconf+robotframework+ruby+rust+sas+sass+scss+scala+scheme+shell-session+smali+smalltalk+smarty+sml+solidity+solution-file+soy+sparql+splunk-spl+sqf+sql+squirrel+stan+iecst+stylus+swift+t4-templating+t4-cs+t4-vb+tap+tcl+tt2+textile+toml+turtle+twig+typescript+typoscript+unrealscript+uri+v+vala+vbnet+velocity+verilog+vhdl+vim+visual-basic+warpscript+wasm+wiki+wolfram+xeora+xml-doc+xojo+xquery+yaml+yang+zig */ @@ -1603,7 +1424,6 @@ div[data-type=codeBlock] .token.inserted { /* Markup */ /* Make the tokens sit above the line highlight so the colours don't look faded. */ } - [data-code-block-theme=twilight] div[data-type=codeBlock] code[class*=language-], [data-code-block-theme=twilight] div[data-type=codeBlock] pre[class*=language-] { color: white; @@ -1625,96 +1445,69 @@ div[data-type=codeBlock] .token.inserted { -ms-hyphens: none; hyphens: none; } - [data-code-block-theme=twilight] div[data-type=codeBlock] pre[class*=language-], -[data-code-block-theme=twilight] div[data-type=codeBlock] :not(pre)>code[class*=language-] { - background: hsl(0deg, 0%, 8%); - /* #141414 */ +[data-code-block-theme=twilight] div[data-type=codeBlock] :not(pre) > code[class*=language-] { + background: hsl(0deg, 0%, 8%); /* #141414 */ } - [data-code-block-theme=twilight] div[data-type=codeBlock] pre[class*=language-] { border-radius: 0.5em; - border: 0.3em solid hsl(0deg, 0%, 33%); - /* #282A2B */ + border: 0.3em solid hsl(0deg, 0%, 33%); /* #282A2B */ box-shadow: 1px 1px 0.5em black inset; margin: 0.5em 0; overflow: auto; padding: 1em; } - [data-code-block-theme=twilight] div[data-type=codeBlock] pre[class*=language-]::-moz-selection { /* Firefox */ - background: hsl(200deg, 4%, 16%); - /* #282A2B */ + background: hsl(200deg, 4%, 16%); /* #282A2B */ } - [data-code-block-theme=twilight] div[data-type=codeBlock] pre[class*=language-]::selection { /* Safari */ - background: hsl(200deg, 4%, 16%); - /* #282A2B */ + background: hsl(200deg, 4%, 16%); /* #282A2B */ } - -[data-code-block-theme=twilight] div[data-type=codeBlock] pre[class*=language-]::-moz-selection, -[data-code-block-theme=twilight] div[data-type=codeBlock] pre[class*=language-] ::-moz-selection, -[data-code-block-theme=twilight] div[data-type=codeBlock] code[class*=language-]::-moz-selection, -[data-code-block-theme=twilight] div[data-type=codeBlock] code[class*=language-] ::-moz-selection { +[data-code-block-theme=twilight] div[data-type=codeBlock] pre[class*=language-]::-moz-selection, [data-code-block-theme=twilight] div[data-type=codeBlock] pre[class*=language-] ::-moz-selection, +[data-code-block-theme=twilight] div[data-type=codeBlock] code[class*=language-]::-moz-selection, [data-code-block-theme=twilight] div[data-type=codeBlock] code[class*=language-] ::-moz-selection { text-shadow: none; - background: hsla(0deg, 0%, 93%, 0.15); - /* #EDEDED */ + background: hsla(0deg, 0%, 93%, 0.15); /* #EDEDED */ } - -[data-code-block-theme=twilight] div[data-type=codeBlock] pre[class*=language-]::selection, -[data-code-block-theme=twilight] div[data-type=codeBlock] pre[class*=language-] ::selection, -[data-code-block-theme=twilight] div[data-type=codeBlock] code[class*=language-]::selection, -[data-code-block-theme=twilight] div[data-type=codeBlock] code[class*=language-] ::selection { +[data-code-block-theme=twilight] div[data-type=codeBlock] pre[class*=language-]::selection, [data-code-block-theme=twilight] div[data-type=codeBlock] pre[class*=language-] ::selection, +[data-code-block-theme=twilight] div[data-type=codeBlock] code[class*=language-]::selection, [data-code-block-theme=twilight] div[data-type=codeBlock] code[class*=language-] ::selection { text-shadow: none; - background: hsla(0deg, 0%, 93%, 0.15); - /* #EDEDED */ + background: hsla(0deg, 0%, 93%, 0.15); /* #EDEDED */ } - -[data-code-block-theme=twilight] div[data-type=codeBlock] :not(pre)>code[class*=language-] { +[data-code-block-theme=twilight] div[data-type=codeBlock] :not(pre) > code[class*=language-] { border-radius: 0.3em; - border: 0.13em solid hsl(0deg, 0%, 33%); - /* #545454 */ + border: 0.13em solid hsl(0deg, 0%, 33%); /* #545454 */ box-shadow: 1px 1px 0.3em -0.1em black inset; padding: 0.15em 0.2em 0.05em; white-space: normal; } - [data-code-block-theme=twilight] div[data-type=codeBlock] .token.comment, [data-code-block-theme=twilight] div[data-type=codeBlock] .token.prolog, [data-code-block-theme=twilight] div[data-type=codeBlock] .token.doctype, [data-code-block-theme=twilight] div[data-type=codeBlock] .token.cdata { - color: hsl(0deg, 0%, 47%); - /* #777777 */ + color: hsl(0deg, 0%, 47%); /* #777777 */ } - [data-code-block-theme=twilight] div[data-type=codeBlock] .token.punctuation { opacity: 0.7; } - [data-code-block-theme=twilight] div[data-type=codeBlock] .token.namespace { opacity: 0.7; } - [data-code-block-theme=twilight] div[data-type=codeBlock] .token.tag, [data-code-block-theme=twilight] div[data-type=codeBlock] .token.boolean, [data-code-block-theme=twilight] div[data-type=codeBlock] .token.number, [data-code-block-theme=twilight] div[data-type=codeBlock] .token.deleted { - color: hsl(14deg, 58%, 55%); - /* #CF6A4C */ + color: hsl(14deg, 58%, 55%); /* #CF6A4C */ } - [data-code-block-theme=twilight] div[data-type=codeBlock] .token.keyword, [data-code-block-theme=twilight] div[data-type=codeBlock] .token.property, [data-code-block-theme=twilight] div[data-type=codeBlock] .token.selector, [data-code-block-theme=twilight] div[data-type=codeBlock] .token.constant, [data-code-block-theme=twilight] div[data-type=codeBlock] .token.symbol, [data-code-block-theme=twilight] div[data-type=codeBlock] .token.builtin { - color: hsl(53deg, 89%, 79%); - /* #F9EE98 */ + color: hsl(53deg, 89%, 79%); /* #F9EE98 */ } - [data-code-block-theme=twilight] div[data-type=codeBlock] .token.attr-name, [data-code-block-theme=twilight] div[data-type=codeBlock] .token.attr-value, [data-code-block-theme=twilight] div[data-type=codeBlock] .token.string, @@ -1726,64 +1519,46 @@ div[data-type=codeBlock] .token.inserted { [data-code-block-theme=twilight] div[data-type=codeBlock] .style .token.string, [data-code-block-theme=twilight] div[data-type=codeBlock] .token.variable, [data-code-block-theme=twilight] div[data-type=codeBlock] .token.inserted { - color: hsl(76deg, 21%, 52%); - /* #8F9D6A */ + color: hsl(76deg, 21%, 52%); /* #8F9D6A */ } - [data-code-block-theme=twilight] div[data-type=codeBlock] .token.atrule { - color: hsl(218deg, 22%, 55%); - /* #7587A6 */ + color: hsl(218deg, 22%, 55%); /* #7587A6 */ } - [data-code-block-theme=twilight] div[data-type=codeBlock] .token.regex, [data-code-block-theme=twilight] div[data-type=codeBlock] .token.important { - color: hsl(42deg, 75%, 65%); - /* #E9C062 */ + color: hsl(42deg, 75%, 65%); /* #E9C062 */ } - [data-code-block-theme=twilight] div[data-type=codeBlock] .token.important, [data-code-block-theme=twilight] div[data-type=codeBlock] .token.bold { font-weight: bold; } - [data-code-block-theme=twilight] div[data-type=codeBlock] .token.italic { font-style: italic; } - [data-code-block-theme=twilight] div[data-type=codeBlock] .token.entity { cursor: help; } - [data-code-block-theme=twilight] div[data-type=codeBlock] pre[data-line] { padding: 1em 0 1em 3em; position: relative; } - [data-code-block-theme=twilight] div[data-type=codeBlock] .language-markup .token.tag, [data-code-block-theme=twilight] div[data-type=codeBlock] .language-markup .token.attr-name, [data-code-block-theme=twilight] div[data-type=codeBlock] .language-markup .token.punctuation { - color: hsl(33deg, 33%, 52%); - /* #AC885B */ + color: hsl(33deg, 33%, 52%); /* #AC885B */ } - [data-code-block-theme=twilight] div[data-type=codeBlock] .token { position: relative; z-index: 1; } - [data-code-block-theme=twilight] div[data-type=codeBlock] .line-highlight { - background: hsla(0deg, 0%, 33%, 0.25); - /* #545454 */ - background: linear-gradient(to right, hsla(0deg, 0%, 33%, 0.1) 70%, hsla(0deg, 0%, 33%, 0)); - /* #545454 */ - border-bottom: 1px dashed hsl(0deg, 0%, 33%); - /* #545454 */ - border-top: 1px dashed hsl(0deg, 0%, 33%); - /* #545454 */ + background: hsla(0deg, 0%, 33%, 0.25); /* #545454 */ + background: linear-gradient(to right, hsla(0deg, 0%, 33%, 0.1) 70%, hsla(0deg, 0%, 33%, 0)); /* #545454 */ + border-bottom: 1px dashed hsl(0deg, 0%, 33%); /* #545454 */ + border-top: 1px dashed hsl(0deg, 0%, 33%); /* #545454 */ left: 0; line-height: inherit; - margin-top: 0.75em; - /* Same as .prism’s padding-top */ + margin-top: 0.75em; /* Same as .prism’s padding-top */ padding: inherit 0; pointer-events: none; position: absolute; @@ -1791,15 +1566,12 @@ div[data-type=codeBlock] .token.inserted { white-space: pre; z-index: 0; } - [data-code-block-theme=twilight] div[data-type=codeBlock] .line-highlight:before, [data-code-block-theme=twilight] div[data-type=codeBlock] .line-highlight[data-end]:after { - background-color: hsl(215deg, 15%, 59%); - /* #8794A6 */ + background-color: hsl(215deg, 15%, 59%); /* #8794A6 */ border-radius: 999px; box-shadow: 0 1px white; - color: hsl(24deg, 20%, 95%); - /* #F5F2F0 */ + color: hsl(24deg, 20%, 95%); /* #F5F2F0 */ content: attr(data-start); font: bold 65%/1.5 sans-serif; left: 0.6em; @@ -1811,13 +1583,11 @@ div[data-type=codeBlock] .token.inserted { top: 0.4em; vertical-align: 0.3em; } - [data-code-block-theme=twilight] div[data-type=codeBlock] .line-highlight[data-end]:after { bottom: 0.4em; content: attr(data-end); top: auto; } - [data-code-block-theme=coy] div[data-type=codeBlock] { /* PrismJS 1.23.0 https://prismjs.com/download.html#themes=prism-coy&languages=markup+css+clike+javascript+abap+abnf+actionscript+ada+agda+al+antlr4+apacheconf+apex+apl+applescript+aql+arduino+arff+asciidoc+aspnet+asm6502+autohotkey+autoit+bash+basic+batch+bbcode+birb+bison+bnf+brainfuck+brightscript+bro+bsl+c+csharp+cpp+cfscript+chaiscript+cil+clojure+cmake+cobol+coffeescript+concurnas+csp+coq+crystal+css-extras+csv+cypher+d+dart+dataweave+dax+dhall+diff+django+dns-zone-file+docker+dot+ebnf+editorconfig+eiffel+ejs+elixir+elm+etlua+erb+erlang+excel-formula+fsharp+factor+false+firestore-security-rules+flow+fortran+ftl+gml+gcode+gdscript+gedcom+gherkin+git+glsl+go+graphql+groovy+haml+handlebars+haskell+haxe+hcl+hlsl+http+hpkp+hsts+ichigojam+icon+icu-message-format+idris+ignore+inform7+ini+io+j+java+javadoc+javadoclike+javastacktrace+jexl+jolie+jq+jsdoc+js-extras+json+json5+jsonp+jsstacktrace+js-templates+julia+keyman+kotlin+kumir+latex+latte+less+lilypond+liquid+lisp+livescript+llvm+log+lolcode+lua+makefile+markdown+markup-templating+matlab+mel+mizar+mongodb+monkey+moonscript+n1ql+n4js+nand2tetris-hdl+naniscript+nasm+neon+nevod+nginx+nim+nix+nsis+objectivec+ocaml+opencl+openqasm+oz+parigp+parser+pascal+pascaligo+psl+pcaxis+peoplecode+perl+php+phpdoc+php-extras+plsql+powerquery+powershell+processing+prolog+promql+properties+protobuf+pug+puppet+pure+purebasic+purescript+python+qsharp+q+qml+qore+r+racket+jsx+tsx+reason+regex+rego+renpy+rest+rip+roboconf+robotframework+ruby+rust+sas+sass+scss+scala+scheme+shell-session+smali+smalltalk+smarty+sml+solidity+solution-file+soy+sparql+splunk-spl+sqf+sql+squirrel+stan+iecst+stylus+swift+t4-templating+t4-cs+t4-vb+tap+tcl+tt2+textile+toml+turtle+twig+typescript+typoscript+unrealscript+uri+v+vala+vbnet+velocity+verilog+vhdl+vim+visual-basic+warpscript+wasm+wiki+wolfram+xeora+xml-doc+xojo+xquery+yaml+yang+zig */ @@ -1832,7 +1602,6 @@ div[data-type=codeBlock] .token.inserted { /* Plugin styles: Line Numbers */ /* Plugin styles: Line Highlight */ } - [data-code-block-theme=coy] div[data-type=codeBlock] code[class*=language-], [data-code-block-theme=coy] div[data-type=codeBlock] pre[class*=language-] { color: black; @@ -1853,15 +1622,13 @@ div[data-type=codeBlock] .token.inserted { -ms-hyphens: none; hyphens: none; } - [data-code-block-theme=coy] div[data-type=codeBlock] pre[class*=language-] { position: relative; margin: 0.5em 0; overflow-y: hidden; padding: 0; } - -[data-code-block-theme=coy] div[data-type=codeBlock] pre[class*=language-]>code { +[data-code-block-theme=coy] div[data-type=codeBlock] pre[class*=language-] > code { position: relative; border-left: 10px solid #358ccb; box-shadow: -1px 0px 0px 0px #358ccb, 0px 0px 0px 1px #dfdfdf; @@ -1871,15 +1638,13 @@ div[data-type=codeBlock] .token.inserted { background-origin: content-box; background-attachment: local; } - [data-code-block-theme=coy] div[data-type=codeBlock] code[class*=language-] { max-height: inherit; height: inherit; padding: 0 1em; display: block; } - -[data-code-block-theme=coy] div[data-type=codeBlock] :not(pre)>code[class*=language-], +[data-code-block-theme=coy] div[data-type=codeBlock] :not(pre) > code[class*=language-], [data-code-block-theme=coy] div[data-type=codeBlock] pre[class*=language-] { background-color: #fdfdfd; -webkit-box-sizing: border-box; @@ -1887,8 +1652,7 @@ div[data-type=codeBlock] .token.inserted { box-sizing: border-box; margin-bottom: 1em; } - -[data-code-block-theme=coy] div[data-type=codeBlock] :not(pre)>code[class*=language-] { +[data-code-block-theme=coy] div[data-type=codeBlock] :not(pre) > code[class*=language-] { position: relative; padding: 0.2em; border-radius: 0.3em; @@ -1897,7 +1661,6 @@ div[data-type=codeBlock] .token.inserted { display: inline; white-space: normal; } - [data-code-block-theme=coy] div[data-type=codeBlock] pre[class*=language-]:before, [data-code-block-theme=coy] div[data-type=codeBlock] pre[class*=language-]:after { content: ""; @@ -1916,7 +1679,6 @@ div[data-type=codeBlock] .token.inserted { -o-transform: rotate(-2deg); transform: rotate(-2deg); } - [data-code-block-theme=coy] div[data-type=codeBlock] pre[class*=language-]:after { right: 0.75em; left: auto; @@ -1926,7 +1688,6 @@ div[data-type=codeBlock] .token.inserted { -o-transform: rotate(2deg); transform: rotate(2deg); } - [data-code-block-theme=coy] div[data-type=codeBlock] .token.comment, [data-code-block-theme=coy] div[data-type=codeBlock] .token.block-comment, [data-code-block-theme=coy] div[data-type=codeBlock] .token.prolog, @@ -1934,11 +1695,9 @@ div[data-type=codeBlock] .token.inserted { [data-code-block-theme=coy] div[data-type=codeBlock] .token.cdata { color: #7D8B99; } - [data-code-block-theme=coy] div[data-type=codeBlock] .token.punctuation { color: #5F6364; } - [data-code-block-theme=coy] div[data-type=codeBlock] .token.property, [data-code-block-theme=coy] div[data-type=codeBlock] .token.tag, [data-code-block-theme=coy] div[data-type=codeBlock] .token.boolean, @@ -1949,7 +1708,6 @@ div[data-type=codeBlock] .token.inserted { [data-code-block-theme=coy] div[data-type=codeBlock] .token.deleted { color: #c92c2c; } - [data-code-block-theme=coy] div[data-type=codeBlock] .token.selector, [data-code-block-theme=coy] div[data-type=codeBlock] .token.attr-name, [data-code-block-theme=coy] div[data-type=codeBlock] .token.string, @@ -1959,7 +1717,6 @@ div[data-type=codeBlock] .token.inserted { [data-code-block-theme=coy] div[data-type=codeBlock] .token.inserted { color: #2f9c0a; } - [data-code-block-theme=coy] div[data-type=codeBlock] .token.operator, [data-code-block-theme=coy] div[data-type=codeBlock] .token.entity, [data-code-block-theme=coy] div[data-type=codeBlock] .token.url, @@ -1967,81 +1724,64 @@ div[data-type=codeBlock] .token.inserted { color: #a67f59; background: rgba(255, 255, 255, 0.5); } - [data-code-block-theme=coy] div[data-type=codeBlock] .token.atrule, [data-code-block-theme=coy] div[data-type=codeBlock] .token.attr-value, [data-code-block-theme=coy] div[data-type=codeBlock] .token.keyword, [data-code-block-theme=coy] div[data-type=codeBlock] .token.class-name { color: #1990b8; } - [data-code-block-theme=coy] div[data-type=codeBlock] .token.regex, [data-code-block-theme=coy] div[data-type=codeBlock] .token.important { color: #e90; } - [data-code-block-theme=coy] div[data-type=codeBlock] .language-css .token.string, [data-code-block-theme=coy] div[data-type=codeBlock] .style .token.string { color: #a67f59; background: rgba(255, 255, 255, 0.5); } - [data-code-block-theme=coy] div[data-type=codeBlock] .token.important { font-weight: normal; } - [data-code-block-theme=coy] div[data-type=codeBlock] .token.bold { font-weight: bold; } - [data-code-block-theme=coy] div[data-type=codeBlock] .token.italic { font-style: italic; } - [data-code-block-theme=coy] div[data-type=codeBlock] .token.entity { cursor: help; } - [data-code-block-theme=coy] div[data-type=codeBlock] .token.namespace { opacity: 0.7; } - @media screen and (max-width: 767px) { - [data-code-block-theme=coy] div[data-type=codeBlock] pre[class*=language-]:before, - [data-code-block-theme=coy] div[data-type=codeBlock] pre[class*=language-]:after { +[data-code-block-theme=coy] div[data-type=codeBlock] pre[class*=language-]:after { bottom: 14px; box-shadow: none; } } - [data-code-block-theme=coy] div[data-type=codeBlock] pre[class*=language-].line-numbers.line-numbers { padding-left: 0; } - [data-code-block-theme=coy] div[data-type=codeBlock] pre[class*=language-].line-numbers.line-numbers code { padding-left: 3.8em; } - [data-code-block-theme=coy] div[data-type=codeBlock] pre[class*=language-].line-numbers.line-numbers .line-numbers-rows { left: 0; } - [data-code-block-theme=coy] div[data-type=codeBlock] pre[class*=language-][data-line] { padding-top: 0; padding-bottom: 0; padding-left: 0; } - [data-code-block-theme=coy] div[data-type=codeBlock] pre[data-line] code { position: relative; padding-left: 4em; } - [data-code-block-theme=coy] div[data-type=codeBlock] pre .line-highlight { margin-top: 0; } - [data-code-block-theme=solarized-light] div[data-type=codeBlock] { /* PrismJS 1.23.0 https://prismjs.com/download.html#themes=prism-solarizedlight&languages=markup+css+clike+javascript */ @@ -2076,11 +1816,9 @@ div[data-type=codeBlock] .token.inserted { /* Code blocks */ /* Inline code */ } - [data-code-block-theme=solarized-light] div[data-type=codeBlock] code[class*=language-], [data-code-block-theme=solarized-light] div[data-type=codeBlock] pre[class*=language-] { - color: #657b83; - /* base00 */ + color: #657b83; /* base00 */ font-family: Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace; font-size: 1em; text-align: left; @@ -2097,58 +1835,40 @@ div[data-type=codeBlock] .token.inserted { -ms-hyphens: none; hyphens: none; } - -[data-code-block-theme=solarized-light] div[data-type=codeBlock] pre[class*=language-]::-moz-selection, -[data-code-block-theme=solarized-light] div[data-type=codeBlock] pre[class*=language-] ::-moz-selection, -[data-code-block-theme=solarized-light] div[data-type=codeBlock] code[class*=language-]::-moz-selection, -[data-code-block-theme=solarized-light] div[data-type=codeBlock] code[class*=language-] ::-moz-selection { - background: #073642; - /* base02 */ +[data-code-block-theme=solarized-light] div[data-type=codeBlock] pre[class*=language-]::-moz-selection, [data-code-block-theme=solarized-light] div[data-type=codeBlock] pre[class*=language-] ::-moz-selection, +[data-code-block-theme=solarized-light] div[data-type=codeBlock] code[class*=language-]::-moz-selection, [data-code-block-theme=solarized-light] div[data-type=codeBlock] code[class*=language-] ::-moz-selection { + background: #073642; /* base02 */ } - -[data-code-block-theme=solarized-light] div[data-type=codeBlock] pre[class*=language-]::selection, -[data-code-block-theme=solarized-light] div[data-type=codeBlock] pre[class*=language-] ::selection, -[data-code-block-theme=solarized-light] div[data-type=codeBlock] code[class*=language-]::selection, -[data-code-block-theme=solarized-light] div[data-type=codeBlock] code[class*=language-] ::selection { - background: #073642; - /* base02 */ +[data-code-block-theme=solarized-light] div[data-type=codeBlock] pre[class*=language-]::selection, [data-code-block-theme=solarized-light] div[data-type=codeBlock] pre[class*=language-] ::selection, +[data-code-block-theme=solarized-light] div[data-type=codeBlock] code[class*=language-]::selection, [data-code-block-theme=solarized-light] div[data-type=codeBlock] code[class*=language-] ::selection { + background: #073642; /* base02 */ } - [data-code-block-theme=solarized-light] div[data-type=codeBlock] pre[class*=language-] { padding: 1em; margin: 0.5em 0; overflow: auto; border-radius: 0.3em; } - -[data-code-block-theme=solarized-light] div[data-type=codeBlock] :not(pre)>code[class*=language-], +[data-code-block-theme=solarized-light] div[data-type=codeBlock] :not(pre) > code[class*=language-], [data-code-block-theme=solarized-light] div[data-type=codeBlock] pre[class*=language-] { - background-color: #fdf6e3; - /* base3 */ + background-color: #fdf6e3; /* base3 */ } - -[data-code-block-theme=solarized-light] div[data-type=codeBlock] :not(pre)>code[class*=language-] { +[data-code-block-theme=solarized-light] div[data-type=codeBlock] :not(pre) > code[class*=language-] { padding: 0.1em; border-radius: 0.3em; } - [data-code-block-theme=solarized-light] div[data-type=codeBlock] .token.comment, [data-code-block-theme=solarized-light] div[data-type=codeBlock] .token.prolog, [data-code-block-theme=solarized-light] div[data-type=codeBlock] .token.doctype, [data-code-block-theme=solarized-light] div[data-type=codeBlock] .token.cdata { - color: #93a1a1; - /* base1 */ + color: #93a1a1; /* base1 */ } - [data-code-block-theme=solarized-light] div[data-type=codeBlock] .token.punctuation { - color: #586e75; - /* base01 */ + color: #586e75; /* base01 */ } - [data-code-block-theme=solarized-light] div[data-type=codeBlock] .token.namespace { opacity: 0.7; } - [data-code-block-theme=solarized-light] div[data-type=codeBlock] .token.property, [data-code-block-theme=solarized-light] div[data-type=codeBlock] .token.tag, [data-code-block-theme=solarized-light] div[data-type=codeBlock] .token.boolean, @@ -2156,10 +1876,8 @@ div[data-type=codeBlock] .token.inserted { [data-code-block-theme=solarized-light] div[data-type=codeBlock] .token.constant, [data-code-block-theme=solarized-light] div[data-type=codeBlock] .token.symbol, [data-code-block-theme=solarized-light] div[data-type=codeBlock] .token.deleted { - color: #268bd2; - /* blue */ + color: #268bd2; /* blue */ } - [data-code-block-theme=solarized-light] div[data-type=codeBlock] .token.selector, [data-code-block-theme=solarized-light] div[data-type=codeBlock] .token.attr-name, [data-code-block-theme=solarized-light] div[data-type=codeBlock] .token.string, @@ -2167,46 +1885,33 @@ div[data-type=codeBlock] .token.inserted { [data-code-block-theme=solarized-light] div[data-type=codeBlock] .token.builtin, [data-code-block-theme=solarized-light] div[data-type=codeBlock] .token.url, [data-code-block-theme=solarized-light] div[data-type=codeBlock] .token.inserted { - color: #2aa198; - /* cyan */ + color: #2aa198; /* cyan */ } - [data-code-block-theme=solarized-light] div[data-type=codeBlock] .token.entity { - color: #657b83; - /* base00 */ - background: #eee8d5; - /* base2 */ + color: #657b83; /* base00 */ + background: #eee8d5; /* base2 */ } - [data-code-block-theme=solarized-light] div[data-type=codeBlock] .token.atrule, [data-code-block-theme=solarized-light] div[data-type=codeBlock] .token.attr-value, [data-code-block-theme=solarized-light] div[data-type=codeBlock] .token.keyword { - color: #859900; - /* green */ + color: #859900; /* green */ } - [data-code-block-theme=solarized-light] div[data-type=codeBlock] .token.function, [data-code-block-theme=solarized-light] div[data-type=codeBlock] .token.class-name { - color: #b58900; - /* yellow */ + color: #b58900; /* yellow */ } - [data-code-block-theme=solarized-light] div[data-type=codeBlock] .token.regex, [data-code-block-theme=solarized-light] div[data-type=codeBlock] .token.important, [data-code-block-theme=solarized-light] div[data-type=codeBlock] .token.variable { - color: #cb4b16; - /* orange */ + color: #cb4b16; /* orange */ } - [data-code-block-theme=solarized-light] div[data-type=codeBlock] .token.important, [data-code-block-theme=solarized-light] div[data-type=codeBlock] .token.bold { font-weight: bold; } - [data-code-block-theme=solarized-light] div[data-type=codeBlock] .token.italic { font-style: italic; } - [data-code-block-theme=solarized-light] div[data-type=codeBlock] .token.entity { cursor: help; } @@ -2217,7 +1922,6 @@ div[data-type=codeBlock] .token.inserted { overflow: hidden; margin-bottom: 10px; } - .cherry-detail details summary { user-select: none; padding: 5px 10px; @@ -2225,7 +1929,6 @@ div[data-type=codeBlock] .token.inserted { color: #FFF; border-radius: 8px; } - .cherry-detail details .cherry-detail-body { padding: 15px 25px 0 25px; } @@ -2234,106 +1937,95 @@ div[data-type=codeBlock] .token.inserted { border-radius: 8px; overflow: hidden; } - .cherry-detail__multiple details { margin-bottom: 1px; border-radius: 0; border: none; } - .cherry-detail__multiple details summary { border-radius: 0; } +.cherry-text-align__center table { + margin-left: auto; + margin-right: auto; +} + +.cherry-text-align__right table { + margin-left: auto; +} + .cherry-panel { margin: 10px 0; overflow: hidden; border-radius: 8px; box-sizing: border-box; - border: 1px solid; + border: 0.5px solid; } - .cherry-panel .cherry-panel--title { color: #fff; padding: 5px 20px; } - .cherry-panel .cherry-panel--title.cherry-panel--title__not-empty::before { font-family: "ch-icon"; margin: 0 12px 0 -6px; vertical-align: bottom; } - .cherry-panel .cherry-panel--body { padding: 5px 20px; } .cherry-panel__primary { - background-color: #fff5eb; - border-color: #fed4a4; + background-color: #cfe2ff; color: #0a58ca; } - .cherry-panel__primary .cherry-panel--title { - background-color: #f7cf22; + background-color: #0d6dfe; } - .cherry-panel__primary .cherry-panel--title.cherry-panel--title__not-empty::before { content: "\ea6a"; } .cherry-panel__info { - background-color: #ebfeff; - border-color: #a4a5fe; + background-color: #cff4fc; color: #087990; } - .cherry-panel__info .cherry-panel--title { - background-color: #22d6f7; + background-color: #099cba; } - .cherry-panel__info .cherry-panel--title.cherry-panel--title__not-empty::before { content: "\ea69"; } .cherry-panel__warning { - background-color: #f1ebff; - border-color: #fea4d7; + background-color: #fff3cd; color: #997404; } - .cherry-panel__warning .cherry-panel--title { - background-color: #8e22f7; + background-color: #b38806; } - .cherry-panel__warning .cherry-panel--title.cherry-panel--title__not-empty::before { content: "\ea6b"; } .cherry-panel__danger { - background-color: #f4dfdf; - border-color: #b9fea4; + background-color: #f8d7da; color: #b02a37; } - .cherry-panel__danger .cherry-panel--title { - background-color: #ff5959; + background-color: #dc3545; } - .cherry-panel__danger .cherry-panel--title.cherry-panel--title__not-empty::before { content: "\ea68"; } .cherry-panel__success { - background-color: #d6f8de; - border-color: #a4a8fe; + background-color: #d1e7dd; color: #146c43; } - .cherry-panel__success .cherry-panel--title { - background-color: #4be561; + background-color: #198754; } - .cherry-panel__success .cherry-panel--title.cherry-panel--title__not-empty::before { content: "\ea67"; } @@ -2343,12 +2035,9 @@ div[data-type=codeBlock] .token.inserted { -webkit-user-select: none; user-select: none; } - .cherry .cherry-previewer img { transition: all 0.1s; - max-width: 100%; } - .cherry .cherry-previewer-img-size-hander { position: absolute; box-shadow: 0 1px 4px 0 rgba(20, 81, 154, 0.5); @@ -2356,7 +2045,6 @@ div[data-type=codeBlock] .token.inserted { box-sizing: content-box; pointer-events: none; } - .cherry .cherry-previewer-img-size-hander .cherry-previewer-img-size-hander__points { position: absolute; height: 10px; @@ -2370,7 +2058,6 @@ div[data-type=codeBlock] .token.inserted { box-shadow: 0px 2px 2px 0px rgba(20, 81, 154, 0.5); pointer-events: all; } - .cherry .cherry-previewer-img-size-hander .cherry-previewer-img-size-hander__background { background-repeat: no-repeat; background-size: 100% 100%; @@ -2378,43 +2065,33 @@ div[data-type=codeBlock] .token.inserted { width: 100%; height: 100%; } - .cherry .cherry-previewer-img-size-hander .cherry-previewer-img-size-hander__points-leftTop { cursor: nw-resize; } - .cherry .cherry-previewer-img-size-hander .cherry-previewer-img-size-hander__points-rightTop { cursor: sw-resize; } - .cherry .cherry-previewer-img-size-hander .cherry-previewer-img-size-hander__points-leftBottom { cursor: sw-resize; } - .cherry .cherry-previewer-img-size-hander .cherry-previewer-img-size-hander__points-rightBottom { cursor: nw-resize; } - .cherry .cherry-previewer-img-size-hander .cherry-previewer-img-size-hander__points-middleTop { cursor: n-resize; } - .cherry .cherry-previewer-img-size-hander .cherry-previewer-img-size-hander__points-middleBottom { cursor: n-resize; } - .cherry .cherry-previewer-img-size-hander .cherry-previewer-img-size-hander__points-leftMiddle { cursor: e-resize; } - .cherry .cherry-previewer-img-size-hander .cherry-previewer-img-size-hander__points-rightMiddle { cursor: e-resize; } - .cherry .cherry-previewer-table-content-hander .cherry-previewer-table-content-hander__input { position: absolute; } - .cherry .cherry-previewer-table-content-hander .cherry-previewer-table-content-hander__input textarea { width: 100%; height: 100%; @@ -2424,34 +2101,53 @@ div[data-type=codeBlock] .token.inserted { outline: 1px solid #3582fb; word-break: break-all; } - +.cherry .cherry-previewer-table-hover-handler { + position: absolute; + pointer-events: none; + z-index: 999; +} +.cherry .cherry-previewer-table-hover-handler-container { + position: relative; + height: 100%; + padding: 0; + margin: 0; + list-style-type: none; +} +.cherry .cherry-previewer-table-hover-handler__symbol { + pointer-events: auto; + display: flex; + justify-content: center; + position: absolute; + color: #3582fb; + width: 12px; + height: 12px; + line-height: 12px; + border: 1px solid rgba(53, 130, 251, 0); + background-color: rgba(255, 255, 255, 0); + cursor: pointer; + transition: all 0.3s; +} +.cherry .cherry-previewer-table-hover-handler__symbol:hover { + background-color: rgba(53, 130, 251, 0.5333333333); + color: #FFF; +} .cherry .cherry-highlight-line { - background-color: #ffffcc; + background-color: rgba(255, 255, 204, 0.5333333333); } @media print { - - img, - figure, - pre, - table { + img, figure, pre, table { page-break-inside: avoid; } - .cherry-previewer { width: 100% !important; max-height: none; border-left: none !important; } - - .cherry-toolbar, - .cherry-sidebar, - .cherry-editor, - .cherry-drag { + .cherry-toolbar, .cherry-sidebar, .cherry-editor, .cherry-drag { display: none !important; } } - .cherry { display: flex; flex-flow: row wrap; @@ -2461,28 +2157,39 @@ div[data-type=codeBlock] .token.inserted { min-height: 100px; position: relative; } - .cherry .cherry-editor, .cherry .cherry-previewer { max-height: calc(100% - 48px); min-height: calc(100% - 48px); } - .cherry .CodeMirror { height: 100%; } - .cherry.cherry--no-toolbar .cherry-toolbar, .cherry.cherry--no-toolbar .cherry-sidebar { height: 0; display: none; } - .cherry.cherry--no-toolbar .cherry-editor, .cherry.cherry--no-toolbar .cherry-previewer { max-height: 100%; min-height: 100%; } +.cherry div[data-type=codeBlock]:hover { + position: relative; +} +.cherry div[data-type=codeBlock]:hover .cherry-code-preview-lang-select { + display: block !important; + position: absolute; + transform: translate(2px, 50%); +} +.cherry .cherry-preview--full div[data-type=codeBlock]:hover { + position: unset; +} +.cherry .cherry-preview--full div[data-type=codeBlock]:hover .cherry-code-preview-lang-select { + display: none !important; + position: unset; +} .cherry { font-family: "Helvetica Neue", Arial, "Hiragino Sans GB", "STHeiti", "Microsoft YaHei", "WenQuanYi Micro Hei", sans-serif; @@ -2492,15 +2199,12 @@ div[data-type=codeBlock] .token.inserted { background: #f8fafb; box-shadow: 0 0 10px rgba(128, 145, 165, 0.2); } - .cherry .ch-icon { vertical-align: middle; } - .cherry .clearfix { zoom: 1; } - .cherry .clearfix:after { content: "."; display: block; @@ -2510,16 +2214,14 @@ div[data-type=codeBlock] .token.inserted { overflow: hidden; font-size: 0; } - .cherry.fullscreen { position: fixed; top: 0; left: 0; right: 0; bottom: 0; - z-index: 1000; + z-index: 99; } - .cherry .no-select { -webkit-touch-callout: none; -webkit-user-select: none; @@ -2528,7 +2230,6 @@ div[data-type=codeBlock] .token.inserted { -ms-user-select: none; user-select: none; } - .cherry .cherry-insert-table-menu { display: block; position: fixed; @@ -2541,20 +2242,16 @@ div[data-type=codeBlock] .token.inserted { width: auto; height: auto; } - .cherry .cherry-insert-table-menu-item { padding: 7px; border: 1px solid #dfe6ee; } - .cherry .cherry-insert-table-menu-item.active { background-color: #ebf3ff; } - .cherry[data-toolbar-theme=dark] .cherry-insert-table-menu-item { border-color: rgba(255, 255, 255, 0.2); } - .cherry[data-toolbar-theme=dark] .cherry-insert-table-menu-item.active { background-color: #d7e6fe; } @@ -2566,9 +2263,8 @@ div[data-type=codeBlock] .token.inserted { background: #fff; box-shadow: 0 5px 15px -5px rgba(0, 0, 0, 0.5); margin-left: -60px; - z-index: 8; + z-index: 11; } - .cherry-dropdown-item { width: 100%; padding: 0 15px; @@ -2581,25 +2277,20 @@ div[data-type=codeBlock] .token.inserted { cursor: pointer; box-sizing: border-box; } - .cherry-dropdown-item:hover { background: #ebf3ff; color: #5d9bfc; } - .cherry-dropdown-item .ch-icon { margin-right: 10px; } - [data-toolbar-theme=dark] .cherry-dropdown { background: #20304b; } - [data-toolbar-theme=dark] .cherry-dropdown .cherry-dropdown-item { background: transparent; color: #d7e6fe; } - [data-toolbar-theme=dark] .cherry-dropdown .cherry-dropdown-item:hover { background: rgba(255, 255, 255, 0.1); color: #fff; @@ -2608,9 +2299,9 @@ div[data-type=codeBlock] .token.inserted { .cherry-toolbar { position: relative; display: flex; - align-items: center; + justify-content: space-between; padding: 0 20px; - height: 35px; + height: 48px; font-size: 14px; line-height: 2.8; flex-basis: 100%; @@ -2621,30 +2312,58 @@ div[data-type=codeBlock] .token.inserted { background: white; overflow: hidden; } - +.cherry-toolbar .icon-loading.loading { + display: inline-block; + width: 8px; + height: 8px; +} +.cherry-toolbar .icon-loading.loading:after { + content: " "; + display: block; + width: 8px; + height: 8px; + margin-left: 2px; + margin-top: -2px; + border-radius: 50%; + border: 2px solid #000; + border-color: #000 transparent #000 transparent; + animation: loading 1.2s linear infinite; +} [data-toolbar-theme=dark] .cherry-toolbar { background: #20304b; box-shadow: 0 0 10px rgba(128, 145, 165, 0.2); } - [data-toolbar-theme=dark] .cherry-toolbar .cherry-toolbar-button { color: #d7e6fe; background: transparent; } - [data-toolbar-theme=dark] .cherry-toolbar .cherry-toolbar-button:hover { color: #fff; background: rgba(255, 255, 255, 0.1); } - +.cherry-toolbar .toolbar-left, +.cherry-toolbar .toolbar-right { + display: flex; + align-items: center; + height: 48px; + overflow: hidden; +} +.cherry-toolbar .toolbar-left { + flex: 0 0 auto; + margin-right: 20px; +} +.cherry-toolbar .toolbar-right { + flex: 0 1 auto; + flex-direction: row-reverse; + margin-left: 10px; + box-sizing: border-box; +} .cherry-toolbar.preview-only .cherry-toolbar-button { display: none; } - .cherry-toolbar.preview-only .cherry-toolbar-switchPreview { display: inline; } - .cherry-toolbar-button { float: left; padding: 0 12px; @@ -2657,12 +2376,10 @@ div[data-type=codeBlock] .token.inserted { cursor: pointer; font-style: normal; } - .cherry-toolbar-button:hover { color: #5d9bfc; background: #ebf3ff; } - .cherry-toolbar-button.cherry-toolbar-split { font-size: 0; height: 50%; @@ -2675,7 +2392,6 @@ div[data-type=codeBlock] .token.inserted { overflow: hidden; opacity: 0.5; } - .cherry-toolbar-button.disabled { color: #ccc; } @@ -2689,26 +2405,22 @@ div[data-type=codeBlock] .token.inserted { position: absolute; top: 48px; right: 7px; - z-index: 0; + z-index: 11; bottom: 0; overflow: hidden; } - .cherry-sidebar .cherry-toolbar-button { height: 30px; padding: 3px 12px 0 6px; } - .cherry-sidebar .cherry-toolbar-button:hover { background: transparent; } - .cherry-sidebar .cherry-toolbar-button .icon-loading.loading { display: inline-block; width: 8px; height: 8px; } - .cherry-sidebar .cherry-toolbar-button .icon-loading.loading:after { content: " "; display: block; @@ -2721,12 +2433,10 @@ div[data-type=codeBlock] .token.inserted { border-color: #000 transparent #000 transparent; animation: loading 1.2s linear infinite; } - @keyframes loading { 0% { transform: rotate(0deg); } - 100% { transform: rotate(360deg); } @@ -2747,12 +2457,10 @@ div[data-type=codeBlock] .token.inserted { border-radius: 3px; z-index: 8; } - .cherry-bubble.cherry-bubble--centered { left: 50%; transform: translateX(-50%); } - .cherry-bubble .cherry-bubble-top, .cherry-bubble .cherry-bubble-bottom { position: absolute; @@ -2763,19 +2471,16 @@ div[data-type=codeBlock] .token.inserted { border-left: 8px solid rgba(0, 0, 0, 0); border-right: 8px solid rgba(0, 0, 0, 0); } - .cherry-bubble .cherry-bubble-top { top: 0; transform: translateY(-100%); border-bottom: 8px solid #fff; } - .cherry-bubble .cherry-bubble-bottom { bottom: 0; transform: translateY(100%); border-top: 8px solid #fff; } - .cherry-bubble .cherry-toolbar-button { display: inline-flex; align-items: center; @@ -2784,40 +2489,32 @@ div[data-type=codeBlock] .token.inserted { cursor: pointer; user-select: none; } - .cherry-bubble .cherry-toolbar-button:hover { border-color: #dfe6ee; background-color: rgba(89, 128, 166, 0.05); } - .cherry-bubble .cherry-toolbar-button.cherry-toolbar-split { height: 65%; min-height: 22.75px; } - [data-toolbar-theme=dark] .cherry-bubble { border-color: #20304b; background: #20304b; } - [data-toolbar-theme=dark] .cherry-bubble .cherry-toolbar-button { color: #d7e6fe; background: transparent; } - [data-toolbar-theme=dark] .cherry-bubble .cherry-toolbar-button:hover { color: #fff; background: rgba(255, 255, 255, 0.1); } - [data-toolbar-theme=dark] .cherry-bubble .cherry-bubble-top { border-bottom-color: #20304b; } - [data-toolbar-theme=dark] .cherry-bubble .cherry-bubble-bottom { border-top-color: #20304b; } - [data-toolbar-theme=dark] .cherry-bubble .cherry-toolbar-button:hover { border-color: #20304b; } @@ -2835,7 +2532,6 @@ div[data-type=codeBlock] .token.inserted { border-radius: 2px; transition: all 0.3s; } - .cherry-switch-paste .cherry-toolbar-button { display: inline-flex; align-items: center; @@ -2843,51 +2539,39 @@ div[data-type=codeBlock] .token.inserted { width: 80px; text-align: center; } - .cherry-switch-paste .cherry-toolbar-button:hover { border-color: transparent; } - .cherry-switch-paste[data-type=text] .cherry-text-btn { color: #3f4a56; } - .cherry-switch-paste[data-type=text] .cherry-md-btn { color: #5d9bfc; } - .cherry-switch-paste[data-type=md] .cherry-md-btn { color: #3f4a56; } - .cherry-switch-paste[data-type=md] .cherry-text-btn { color: #5d9bfc; } - .cherry-switch-paste[data-type=md] .switch-btn--bg { left: 50%; } - [data-toolbar-theme=dark] .cherry-switch-paste .switch-btn--bg { background-color: #fff; } - [data-toolbar-theme=dark] .cherry-switch-paste[data-type=text] .cherry-text-btn { color: #d7e6fe; } - [data-toolbar-theme=dark] .cherry-switch-paste[data-type=text] .cherry-md-btn { color: #fff; } - [data-toolbar-theme=dark] .cherry-switch-paste[data-type=md] .cherry-md-btn { color: #d7e6fe; } - [data-toolbar-theme=dark] .cherry-switch-paste[data-type=md] .cherry-text-btn { color: #fff; } - [data-toolbar-theme=dark] .cherry-switch-paste[data-type=md] .switch-btn--bg { left: 50%; } @@ -2906,7 +2590,6 @@ div[data-type=codeBlock] .token.inserted { -ms-user-select: none; user-select: none; } - .cherry-floatmenu .cherry-toolbar-button { float: left; padding: 0 9px; @@ -2922,7 +2605,6 @@ div[data-type=codeBlock] .token.inserted { cursor: pointer; font-style: normal; } - .cherry-floatmenu .cherry-toolbar-button.cherry-toolbar-split { border-left: 1px solid #dfe6ee; width: 0; @@ -2930,16 +2612,13 @@ div[data-type=codeBlock] .token.inserted { overflow: hidden; height: 25px; } - .cherry-floatmenu .cherry-toolbar-button .ch-icon { color: #aaa; font-size: 12px; } - .cherry-floatmenu .cherry-toolbar-button:hover { background: rgba(0, 0, 0, 0.05); } - .cherry-floatmenu .cherry-toolbar-button:hover .ch-icon { color: #3f4a56; } @@ -2952,30 +2631,55 @@ div[data-type=codeBlock] .token.inserted { box-sizing: border-box; overflow: hidden; } - .cherry-editor.cherry-editor--full { width: 100%; padding-right: 0; } - .cherry-editor.cherry-editor--hidden { display: none; } - +.cherry-editor-writing-style--focus::before { + content: ""; + display: block; + width: 100%; + position: absolute; + top: 0; + background: linear-gradient(to bottom, rgba(0, 0, 0, 0.0235294118), rgba(0, 0, 0, 0.2)); + pointer-events: none; + z-index: 11; +} +.cherry-editor-writing-style--focus::after { + content: ""; + display: block; + width: 100%; + position: absolute; + bottom: 0; + background: linear-gradient(to top, rgba(0, 0, 0, 0.0235294118), rgba(0, 0, 0, 0.2)); + pointer-events: none; + z-index: 11; +} +.cherry-editor-writing-style--typewriter .CodeMirror-lines { + position: relative; +} +.cherry-editor-writing-style--typewriter .CodeMirror-lines::before { + content: ""; + display: block; +} +.cherry-editor-writing-style--typewriter .CodeMirror-lines::after { + content: ""; + display: block; +} .cherry-editor .CodeMirror { font-family: "Helvetica Neue", Arial, "Hiragino Sans GB", "STHeiti", "Microsoft YaHei", "WenQuanYi Micro Hei", sans-serif; background: #f8fafb; color: #3f4a56; } - .cherry-editor .CodeMirror textarea { font-size: 27px; } - .cherry-editor .CodeMirror-lines { padding: 15px 34px; } - .cherry-editor .CodeMirror-lines .drawio, .cherry-editor .CodeMirror-lines .base64 { display: inline-block; @@ -2987,49 +2691,39 @@ div[data-type=codeBlock] .token.inserted { color: darkmagenta !important; font-size: 12px !important; } - .cherry-editor .cm-s-default .cm-header { color: #3f4a56; } - .cherry-editor .cm-s-default .cm-string { color: #3f4a56; } - .cherry-editor .cm-s-default .cm-comment { color: #3582fb; font-family: "Menlo", "Liberation Mono", "Consolas", "DejaVu Sans Mono", "Ubuntu Mono", "Courier New", "andale mono", "lucida console", monospace; font-size: 0.9em; } - .cherry-editor .cm-s-default .cm-whitespace, .cherry-editor .cm-tab { font-family: "Menlo", "Liberation Mono", "Consolas", "DejaVu Sans Mono", "Ubuntu Mono", "Courier New", "andale mono", "lucida console", monospace; font-size: 0.9em; } - .cherry-editor .cm-s-default .cm-quote { color: #3582fb; } - .cherry-editor .cm-s-default .cm-link { color: #3582fb; } - .cherry-editor .cm-s-default .cm-url { background: #d7e6fe; font-family: "Menlo", "Liberation Mono", "Consolas", "DejaVu Sans Mono", "Ubuntu Mono", "Courier New", "andale mono", "lucida console", monospace; font-size: 0.9em; } - .cherry-editor .cm-s-default .cm-variable-2 { color: #3f4a56; } - .cherry-editor .cm-s-default .cm-variable-3 { color: #3f4a56; } - .cherry-editor .cm-s-default .cm-keyword { color: #3f4a56; } @@ -3041,13 +2735,11 @@ div[data-type=codeBlock] .token.inserted { z-index: 12; background: transparent; } - .cherry-drag.cherry-drag--show { width: 5px; display: block; background: #dfe6ee; } - .cherry-drag.cherry-drag--hidden { display: none; } @@ -3058,7 +2750,6 @@ div[data-type=codeBlock] .token.inserted { display: none; background: rgba(0, 0, 0, 0.2); } - .cherry-editor-mask.cherry-editor-mask--show { display: block; } @@ -3069,7 +2760,6 @@ div[data-type=codeBlock] .token.inserted { display: none; background: rgba(0, 0, 0, 0.4); } - .cherry-previewer-mask.cherry-previewer-mask--show { display: block; } @@ -3082,8 +2772,8 @@ div[data-type=codeBlock] .token.inserted { background-color: #f8fafb; min-height: auto; overflow-y: auto; + -webkit-print-color-adjust: exact; } - .cherry-previewer .cherry-mobile-previewer-content { width: 375px; height: 100%; @@ -3093,36 +2783,28 @@ div[data-type=codeBlock] .token.inserted { box-shadow: 0 0 60px rgba(0, 0, 0, 0.1); box-sizing: border-box; } - .cherry-previewer.cherry-previewer--hidden { width: 0; display: none; } - .cherry-previewer.cherry-previewer--full { width: 100%; } - .cherry-previewer .cherry-list__upper-roman { list-style: upper-roman; } - .cherry-previewer .cherry-list__lower-greek { list-style: lower-greek; } - .cherry-previewer .cherry-list__cjk-ideographic { list-style: cjk-ideographic; } - .cherry-previewer .cherry-list__circle { list-style: circle; } - .cherry-previewer .cherry-list__square { list-style: square; } - .cherry-previewer div[data-type=codeBlock]:hover .cherry-copy-code-block { display: block !important; position: relative; @@ -3140,14 +2822,9 @@ div[data-type=codeBlock] .token.inserted { transition: all 0.3s; z-index: 2; } - -[data-code-block-theme=default] .cherry-previewer div[data-type=codeBlock]:hover .cherry-copy-code-block, -[data-code-block-theme=funky] .cherry-previewer div[data-type=codeBlock]:hover .cherry-copy-code-block, -[data-code-block-theme=solarized-light] .cherry-previewer div[data-type=codeBlock]:hover .cherry-copy-code-block, -[data-code-block-theme=coy] .cherry-previewer div[data-type=codeBlock]:hover .cherry-copy-code-block { +[data-code-block-theme=default] .cherry-previewer div[data-type=codeBlock]:hover .cherry-copy-code-block, [data-code-block-theme=funky] .cherry-previewer div[data-type=codeBlock]:hover .cherry-copy-code-block, [data-code-block-theme=solarized-light] .cherry-previewer div[data-type=codeBlock]:hover .cherry-copy-code-block, [data-code-block-theme=coy] .cherry-previewer div[data-type=codeBlock]:hover .cherry-copy-code-block { background-color: #3582fb; } - .cherry-previewer div[data-type=codeBlock]:hover .cherry-copy-code-block:hover { color: #3582fb; background-color: #eee; @@ -3163,29 +2840,24 @@ div[data-type=codeBlock] .token.inserted { background: #fff; box-shadow: 0 0 10px rgba(128, 145, 165, 0.2); } - .cherry-color-wrap h3 { font-size: 12px; margin: 0px; font-weight: 400; } - [data-toolbar-theme=dark] .cherry-color-wrap h3 { color: #d7e6fe; } - .cherry-color-wrap .cherry-color-text { float: left; width: 128px; margin: 0 8px 0 5px; } - .cherry-color-wrap .cherry-color-bg { float: left; width: 128px; margin-right: 5px; } - .cherry-color-wrap .cherry-color-item { float: left; width: 14px; @@ -3193,7 +2865,6 @@ div[data-type=codeBlock] .token.inserted { border: 1px solid #fff; cursor: pointer; } - .cherry-color-wrap .cherry-color-item:hover { border: 1px solid #000; } @@ -3208,12 +2879,10 @@ div[data-type=codeBlock] .token.inserted { left: 0; top: 0; background: #fff; - border: 1px solid #ccc; border-radius: 2px; - max-height: 200px; + max-height: 500px; box-shadow: 0 2px 8px 1px rgba(0, 0, 0, 0.2); } - .cherry-suggester-panel .cherry-suggester-panel__item { border: none; white-space: nowrap; @@ -3223,12 +2892,16 @@ div[data-type=codeBlock] .token.inserted { display: block; cursor: pointer; } - .cherry-suggester-panel .cherry-suggester-panel__item.cherry-suggester-panel__item--selected { background-color: #f2f2f5; text-decoration: none; color: #eb7350; } +.cherry-suggester-panel .cherry-suggester-panel__item > i { + display: inline-block; + transform: translateY(2px); + margin-right: 8px; +} .cherry-suggestion { background-color: #ebf3ff; @@ -3245,24 +2918,19 @@ div[data-type=codeBlock] .token.inserted { /** 选中文字时弹出的按钮 */ /** 光标focus到空行时联想出的按钮 */ } - .cherry.theme__default .cherry-dropdown { /** 选择颜色的按钮 */ } - .cherry.theme__default .cherry-dropdown .cherry-dropdown-item { /** 图标 */ } - .cherry.theme__default .cherry-dropdown.cherry-color-wrap .cherry-color-text { /** 色盘的标题 */ /** 色盘里的每一个色块 */ } - .cherry.theme__default .cherry-bubble { /** 粘贴HTML内容时弹出的选择按钮 */ } - /** 预览区域样式 */ .cherry-markdown.theme__default { /** 行内代码 */ @@ -3278,45 +2946,31 @@ div[data-type=codeBlock] .token.inserted { /** 段落公式 */ /** 目录 */ } - -.cherry-markdown.theme__default h1, -.cherry-markdown.theme__default h2, -.cherry-markdown.theme__default h3, -.cherry-markdown.theme__default h4, -.cherry-markdown.theme__default h5, -.cherry-markdown.theme__default h6 { +.cherry-markdown.theme__default h1, .cherry-markdown.theme__default h2, .cherry-markdown.theme__default h3, .cherry-markdown.theme__default h4, .cherry-markdown.theme__default h5, .cherry-markdown.theme__default h6 { /** 标题前面的锚点或序号 */ } - .cherry-markdown.theme__default ul { /** checklist 模式,未勾选时 */ /** checklist 模式,勾选时 */ } - .cherry-markdown.theme__default ul.cherry-list__upper-roman { list-style: upper-roman; } - .cherry-markdown.theme__default ul.cherry-list__lower-greek { list-style: lower-greek; } - .cherry-markdown.theme__default ul.cherry-list__cjk-ideographic { list-style: cjk-ideographic; } - .cherry-markdown.theme__default ul.cherry-list__circle { list-style: circle; } - .cherry-markdown.theme__default ul.cherry-list__square { list-style: square; } - .cherry-markdown.theme__default ruby { /** 上部的拼音 */ } - /** 色值可以参考:https://yeun.github.io/open-color/ */ /** 工具栏样式 */ /** 编辑区域样式 */ @@ -3328,133 +2982,84 @@ div[data-type=codeBlock] .token.inserted { /** 二级菜单 */ /** 选中文字时弹出的按钮 */ } - -.cherry.theme__dark .cherry-toolbar, -.cherry.theme__dark .cherry-floatmenu, -.cherry.theme__dark .cherry-bubble, -.cherry.theme__dark .cherry-sidebar { +.cherry.theme__dark .cherry-toolbar, .cherry.theme__dark .cherry-floatmenu, .cherry.theme__dark .cherry-bubble, .cherry.theme__dark .cherry-sidebar { background: rgb(60, 60, 60); border-color: rgb(60, 60, 60); } - -.cherry.theme__dark .cherry-toolbar .cherry-toolbar-button, -.cherry.theme__dark .cherry-floatmenu .cherry-toolbar-button, -.cherry.theme__dark .cherry-bubble .cherry-toolbar-button, -.cherry.theme__dark .cherry-sidebar .cherry-toolbar-button { +.cherry.theme__dark .cherry-toolbar .cherry-toolbar-button, .cherry.theme__dark .cherry-floatmenu .cherry-toolbar-button, .cherry.theme__dark .cherry-bubble .cherry-toolbar-button, .cherry.theme__dark .cherry-sidebar .cherry-toolbar-button { color: #d7e6fe; } - -.cherry.theme__dark .cherry-toolbar .cherry-toolbar-button:hover, -.cherry.theme__dark .cherry-floatmenu .cherry-toolbar-button:hover, -.cherry.theme__dark .cherry-bubble .cherry-toolbar-button:hover, -.cherry.theme__dark .cherry-sidebar .cherry-toolbar-button:hover { +.cherry.theme__dark .cherry-toolbar .cherry-toolbar-button:hover, .cherry.theme__dark .cherry-floatmenu .cherry-toolbar-button:hover, .cherry.theme__dark .cherry-bubble .cherry-toolbar-button:hover, .cherry.theme__dark .cherry-sidebar .cherry-toolbar-button:hover { background-color: rgb(69, 70, 70); color: rgb(255, 255, 255) !important; border-color: rgb(60, 60, 60); } - -.cherry.theme__dark .cherry-toolbar .cherry-toolbar-button:hover i, -.cherry.theme__dark .cherry-floatmenu .cherry-toolbar-button:hover i, -.cherry.theme__dark .cherry-bubble .cherry-toolbar-button:hover i, -.cherry.theme__dark .cherry-sidebar .cherry-toolbar-button:hover i { +.cherry.theme__dark .cherry-toolbar .cherry-toolbar-button:hover i, .cherry.theme__dark .cherry-floatmenu .cherry-toolbar-button:hover i, .cherry.theme__dark .cherry-bubble .cherry-toolbar-button:hover i, .cherry.theme__dark .cherry-sidebar .cherry-toolbar-button:hover i { color: rgb(255, 255, 255) !important; } - .cherry.theme__dark .cherry-dropdown { background: rgb(60, 60, 60); /** 选择颜色的按钮 */ } - .cherry.theme__dark .cherry-dropdown .cherry-dropdown-item { color: #d7e6fe; } - .cherry.theme__dark .cherry-dropdown .cherry-dropdown-item:hover { background-color: rgb(69, 70, 70); color: rgb(255, 255, 255); } - .cherry.theme__dark .cherry-dropdown.cherry-color-wrap { /** 色盘的标题 */ /** 色盘里的每一个色块 */ } - .cherry.theme__dark .cherry-dropdown.cherry-color-wrap h3 { color: #d7e6fe; } - .cherry.theme__dark .cherry-dropdown.cherry-color-wrap .cherry-color-item { border-color: rgb(69, 70, 70); } - .cherry.theme__dark .cherry-dropdown.cherry-color-wrap .cherry-color-item:hover { border-color: rgb(247, 133, 83); } - .cherry.theme__dark .cherry-bubble { /** 粘贴HTML内容时弹出的选择按钮 */ } - .cherry.theme__dark .cherry-bubble .cherry-bubble-bottom { border-top-color: rgb(60, 60, 60); } - .cherry.theme__dark .cherry-editor { background-color: rgb(37, 37, 38); } - .cherry.theme__dark .cherry-editor .CodeMirror { background-color: rgb(37, 37, 38); } - .cherry.theme__dark .cherry-editor .CodeMirror .CodeMirror-cursor { border-left: 1px solid rgb(255, 255, 255); } - -.cherry.theme__dark .cherry-editor .CodeMirror .CodeMirror-scroll span, -.cherry.theme__dark .cherry-editor .CodeMirror .CodeMirror-scroll .cm-variable-2, -.cherry.theme__dark .cherry-editor .CodeMirror .CodeMirror-scroll .cm-string, -.cherry.theme__dark .cherry-editor .CodeMirror .CodeMirror-scroll .cm-strong, -.cherry.theme__dark .cherry-editor .CodeMirror .CodeMirror-scroll .cm-em, -.cherry.theme__dark .cherry-editor .CodeMirror .CodeMirror-scroll .cm-meta { +.cherry.theme__dark .cherry-editor .CodeMirror .CodeMirror-scroll span, .cherry.theme__dark .cherry-editor .CodeMirror .CodeMirror-scroll .cm-variable-2, .cherry.theme__dark .cherry-editor .CodeMirror .CodeMirror-scroll .cm-string, .cherry.theme__dark .cherry-editor .CodeMirror .CodeMirror-scroll .cm-strong, .cherry.theme__dark .cherry-editor .CodeMirror .CodeMirror-scroll .cm-em, .cherry.theme__dark .cherry-editor .CodeMirror .CodeMirror-scroll .cm-meta { color: rgb(200, 200, 200); } - -.cherry.theme__dark .cherry-editor .CodeMirror .CodeMirror-scroll .cm-image-marker, -.cherry.theme__dark .cherry-editor .CodeMirror .CodeMirror-scroll .cm-quote, -.cherry.theme__dark .cherry-editor .CodeMirror .CodeMirror-scroll .cm-header { +.cherry.theme__dark .cherry-editor .CodeMirror .CodeMirror-scroll .cm-image-marker, .cherry.theme__dark .cherry-editor .CodeMirror .CodeMirror-scroll .cm-quote, .cherry.theme__dark .cherry-editor .CodeMirror .CodeMirror-scroll .cm-header { color: rgb(247, 133, 83); } - .cherry.theme__dark .cherry-editor .CodeMirror .CodeMirror-scroll .cm-url { background-color: rgb(0, 0, 0); } - -.cherry.theme__dark .cherry-editor .CodeMirror .CodeMirror-scroll .cm-comment, -.cherry.theme__dark .cherry-editor .CodeMirror .CodeMirror-scroll .cm-url { +.cherry.theme__dark .cherry-editor .CodeMirror .CodeMirror-scroll .cm-comment, .cherry.theme__dark .cherry-editor .CodeMirror .CodeMirror-scroll .cm-url { color: rgb(255, 203, 107); } - .cherry.theme__dark .cherry-editor .CodeMirror .CodeMirror-selected { background-color: rgb(69, 70, 70); } - .cherry.theme__dark .cherry-sidebar { box-shadow: 0 0 10px rgba(128, 145, 165, 0.2); } - .cherry.theme__dark .cherry-previewer { background-color: rgb(51, 51, 51); } - -.manual-article.theme__dark { - background-color: rgb(51, 51, 51) !important; -} - .cherry.theme__dark .cherry-previewer .cherry-mobile-previewer-content { background-color: rgb(37, 37, 38); } - .cherry.theme__dark .cherry-previewer-table-content-hander .cherry-previewer-table-content-hander__input textarea { background-color: rgb(37, 37, 38); color: rgb(200, 200, 200); @@ -3464,6 +3069,7 @@ div[data-type=codeBlock] .token.inserted { /** 预览区域样式 */ .cherry-markdown.theme__dark { color: rgb(200, 200, 200); + background-color: rgb(51, 51, 51); /** 行内代码 */ /** * 代码块 @@ -3477,161 +3083,114 @@ div[data-type=codeBlock] .token.inserted { /** 段落公式 */ /** 目录 */ } - -.cherry-markdown.theme__dark h1, -.cherry-markdown.theme__dark h2, -.cherry-markdown.theme__dark h3, -.cherry-markdown.theme__dark h4, -.cherry-markdown.theme__dark h5 { +.cherry-markdown.theme__dark h1, .cherry-markdown.theme__dark h2, .cherry-markdown.theme__dark h3, .cherry-markdown.theme__dark h4, .cherry-markdown.theme__dark h5 { color: rgb(247, 133, 83); } - -.cherry-markdown.theme__dark h1, -.cherry-markdown.theme__dark h2, -.cherry-markdown.theme__dark h3, -.cherry-markdown.theme__dark h4, -.cherry-markdown.theme__dark h5, -.cherry-markdown.theme__dark h6 { +.cherry-markdown.theme__dark h1, .cherry-markdown.theme__dark h2, .cherry-markdown.theme__dark h3, .cherry-markdown.theme__dark h4, .cherry-markdown.theme__dark h5, .cherry-markdown.theme__dark h6 { /** 标题前面的锚点或序号 */ } - .cherry-markdown.theme__dark ul { /** checklist 模式,未勾选时 */ /** checklist 模式,勾选时 */ } - .cherry-markdown.theme__dark ul.cherry-list__upper-roman { list-style: upper-roman; } - .cherry-markdown.theme__dark ul.cherry-list__lower-greek { list-style: lower-greek; } - .cherry-markdown.theme__dark ul.cherry-list__cjk-ideographic { list-style: cjk-ideographic; } - .cherry-markdown.theme__dark ul.cherry-list__circle { list-style: circle; } - .cherry-markdown.theme__dark ul.cherry-list__square { list-style: square; } - .cherry-markdown.theme__dark blockquote { color: rgb(200, 200, 200); } - .cherry-markdown.theme__dark a { text-decoration: none; color: rgb(255, 203, 107); } - .cherry-markdown.theme__dark a:hover { color: rgb(247, 133, 83); } - .cherry-markdown.theme__dark hr { border-color: rgb(105, 105, 105); } - -.cherry-markdown.theme__dark p code, -.cherry-markdown.theme__dark li code { +.cherry-markdown.theme__dark p code, .cherry-markdown.theme__dark li code { background-color: rgb(0, 0, 0); color: rgb(255, 203, 107); border: 1px solid rgb(105, 105, 105); } - -.cherry-markdown.theme__dark table, -.cherry-markdown.theme__dark .cherry-table { +.cherry-markdown.theme__dark table, .cherry-markdown.theme__dark .cherry-table { color: rgb(200, 200, 200); } - -.cherry-markdown.theme__dark table th, -.cherry-markdown.theme__dark .cherry-table th { +.cherry-markdown.theme__dark table th, .cherry-markdown.theme__dark .cherry-table th { background-color: rgb(0, 0, 0); } - -.cherry-markdown.theme__dark table tr, -.cherry-markdown.theme__dark table th, -.cherry-markdown.theme__dark table td, -.cherry-markdown.theme__dark .cherry-table tr, -.cherry-markdown.theme__dark .cherry-table th, -.cherry-markdown.theme__dark .cherry-table td { +.cherry-markdown.theme__dark table tr, .cherry-markdown.theme__dark table th, .cherry-markdown.theme__dark table td, .cherry-markdown.theme__dark .cherry-table tr, .cherry-markdown.theme__dark .cherry-table th, .cherry-markdown.theme__dark .cherry-table td { border-color: rgb(105, 105, 105); } - .cherry-markdown.theme__dark ruby { /** 上部的拼音 */ } - .cherry-markdown.theme__dark .footnote { border-color: rgb(105, 105, 105); } - .cherry-markdown.theme__dark .footnote .footnote-title { background-color: rgb(0, 0, 0); } - .cherry-markdown.theme__dark .footnote .one-footnote { color: rgb(200, 200, 200); border-color: rgb(105, 105, 105); } - .cherry-markdown.theme__dark .footnote .one-footnote a.footnote-ref { padding: 5px; } - .cherry-markdown.theme__dark .toc { border: 1px solid rgb(105, 105, 105); margin-top: 15px; margin-bottom: 15px; margin-right: 15px; } - .cherry-markdown.theme__dark .toc .toc-title { padding: 15px; margin-bottom: 15px; border-bottom: 1px solid rgb(105, 105, 105); } - .cherry-markdown.theme__dark .toc .toc-li { border: none; padding: 0 20px; } - .cherry-markdown.theme__dark .toc .toc-li a { color: rgb(200, 200, 200); } - .cherry-markdown.theme__dark .toc .toc-li a:hover { color: rgb(247, 133, 83); } - -.cherry-markdown.theme__dark figure svg path, -.cherry-markdown.theme__dark figure svg rect, -.cherry-markdown.theme__dark figure svg line { +.cherry-markdown.theme__dark figure svg path, .cherry-markdown.theme__dark figure svg rect, .cherry-markdown.theme__dark figure svg line { stroke: rgb(255, 203, 107) !important; } - .cherry-markdown.theme__dark figure svg text { fill: rgb(250, 160, 0) !important; stroke: none !important; } - .cherry-markdown.theme__dark figure svg tspan { fill: rgb(250, 160, 0) !important; } - .cherry-markdown.theme__dark figure svg circle { fill: rgb(236, 236, 255) !important; } - .cherry-markdown.theme__dark figure svg circle.state-start { fill: rgb(250, 160, 0) !important; } +.cherry-markdown.theme__dark .cherry-highlight-line { + background-color: #151422; +} /** 色值可以参考:https://yeun.github.io/open-color/ */ /** 工具栏样式 */ @@ -3644,133 +3203,84 @@ div[data-type=codeBlock] .token.inserted { /** 二级菜单 */ /** 选中文字时弹出的按钮 */ } - -.cherry.theme__light .cherry-toolbar, -.cherry.theme__light .cherry-floatmenu, -.cherry.theme__light .cherry-bubble, -.cherry.theme__light .cherry-sidebar { +.cherry.theme__light .cherry-toolbar, .cherry.theme__light .cherry-floatmenu, .cherry.theme__light .cherry-bubble, .cherry.theme__light .cherry-sidebar { background: white; border-color: white; } - -.cherry.theme__light .cherry-toolbar .cherry-toolbar-button, -.cherry.theme__light .cherry-floatmenu .cherry-toolbar-button, -.cherry.theme__light .cherry-bubble .cherry-toolbar-button, -.cherry.theme__light .cherry-sidebar .cherry-toolbar-button { +.cherry.theme__light .cherry-toolbar .cherry-toolbar-button, .cherry.theme__light .cherry-floatmenu .cherry-toolbar-button, .cherry.theme__light .cherry-bubble .cherry-toolbar-button, .cherry.theme__light .cherry-sidebar .cherry-toolbar-button { color: #3f4a56; } - -.cherry.theme__light .cherry-toolbar .cherry-toolbar-button:hover, -.cherry.theme__light .cherry-floatmenu .cherry-toolbar-button:hover, -.cherry.theme__light .cherry-bubble .cherry-toolbar-button:hover, -.cherry.theme__light .cherry-sidebar .cherry-toolbar-button:hover { +.cherry.theme__light .cherry-toolbar .cherry-toolbar-button:hover, .cherry.theme__light .cherry-floatmenu .cherry-toolbar-button:hover, .cherry.theme__light .cherry-bubble .cherry-toolbar-button:hover, .cherry.theme__light .cherry-sidebar .cherry-toolbar-button:hover { background-color: #ebf3ff; color: #5d9bfc !important; border-color: white; } - -.cherry.theme__light .cherry-toolbar .cherry-toolbar-button:hover i, -.cherry.theme__light .cherry-floatmenu .cherry-toolbar-button:hover i, -.cherry.theme__light .cherry-bubble .cherry-toolbar-button:hover i, -.cherry.theme__light .cherry-sidebar .cherry-toolbar-button:hover i { +.cherry.theme__light .cherry-toolbar .cherry-toolbar-button:hover i, .cherry.theme__light .cherry-floatmenu .cherry-toolbar-button:hover i, .cherry.theme__light .cherry-bubble .cherry-toolbar-button:hover i, .cherry.theme__light .cherry-sidebar .cherry-toolbar-button:hover i { color: #5d9bfc !important; } - .cherry.theme__light .cherry-dropdown { background: white; /** 选择颜色的按钮 */ } - .cherry.theme__light .cherry-dropdown .cherry-dropdown-item { color: #3f4a56; } - .cherry.theme__light .cherry-dropdown .cherry-dropdown-item:hover { background-color: #ebf3ff; color: #5d9bfc; } - .cherry.theme__light .cherry-dropdown.cherry-color-wrap { /** 色盘的标题 */ /** 色盘里的每一个色块 */ } - .cherry.theme__light .cherry-dropdown.cherry-color-wrap h3 { color: #3f4a56; } - .cherry.theme__light .cherry-dropdown.cherry-color-wrap .cherry-color-item { border-color: #ebf3ff; } - .cherry.theme__light .cherry-dropdown.cherry-color-wrap .cherry-color-item:hover { border-color: rgb(247, 133, 83); } - .cherry.theme__light .cherry-bubble { /** 粘贴HTML内容时弹出的选择按钮 */ } - .cherry.theme__light .cherry-bubble .cherry-bubble-bottom { border-top-color: white; } - .cherry.theme__light .cherry-editor { background-color: rgb(255, 255, 255); } - .cherry.theme__light .cherry-editor .CodeMirror { background-color: rgb(255, 255, 255); } - .cherry.theme__light .cherry-editor .CodeMirror .CodeMirror-cursor { border-left: 1px solid rgb(0, 0, 0); } - -.cherry.theme__light .cherry-editor .CodeMirror .CodeMirror-scroll span, -.cherry.theme__light .cherry-editor .CodeMirror .CodeMirror-scroll .cm-variable-2, -.cherry.theme__light .cherry-editor .CodeMirror .CodeMirror-scroll .cm-string, -.cherry.theme__light .cherry-editor .CodeMirror .CodeMirror-scroll .cm-strong, -.cherry.theme__light .cherry-editor .CodeMirror .CodeMirror-scroll .cm-em, -.cherry.theme__light .cherry-editor .CodeMirror .CodeMirror-scroll .cm-meta { +.cherry.theme__light .cherry-editor .CodeMirror .CodeMirror-scroll span, .cherry.theme__light .cherry-editor .CodeMirror .CodeMirror-scroll .cm-variable-2, .cherry.theme__light .cherry-editor .CodeMirror .CodeMirror-scroll .cm-string, .cherry.theme__light .cherry-editor .CodeMirror .CodeMirror-scroll .cm-strong, .cherry.theme__light .cherry-editor .CodeMirror .CodeMirror-scroll .cm-em, .cherry.theme__light .cherry-editor .CodeMirror .CodeMirror-scroll .cm-meta { color: rgb(63, 74, 86); } - -.cherry.theme__light .cherry-editor .CodeMirror .CodeMirror-scroll .cm-image-marker, -.cherry.theme__light .cherry-editor .CodeMirror .CodeMirror-scroll .cm-quote, -.cherry.theme__light .cherry-editor .CodeMirror .CodeMirror-scroll .cm-header { +.cherry.theme__light .cherry-editor .CodeMirror .CodeMirror-scroll .cm-image-marker, .cherry.theme__light .cherry-editor .CodeMirror .CodeMirror-scroll .cm-quote, .cherry.theme__light .cherry-editor .CodeMirror .CodeMirror-scroll .cm-header { color: rgb(34, 139, 230); } - .cherry.theme__light .cherry-editor .CodeMirror .CodeMirror-scroll .cm-url { background-color: rgb(215, 230, 254); } - -.cherry.theme__light .cherry-editor .CodeMirror .CodeMirror-scroll .cm-comment, -.cherry.theme__light .cherry-editor .CodeMirror .CodeMirror-scroll .cm-url { +.cherry.theme__light .cherry-editor .CodeMirror .CodeMirror-scroll .cm-comment, .cherry.theme__light .cherry-editor .CodeMirror .CodeMirror-scroll .cm-url { color: rgb(77, 171, 247); } - .cherry.theme__light .cherry-editor .CodeMirror .CodeMirror-selected { background-color: #ebf3ff; } - .cherry.theme__light .cherry-sidebar { box-shadow: 0 0 10px rgba(128, 145, 165, 0.2); } - .cherry.theme__light .cherry-previewer { background-color: rgb(255, 255, 255); } - -.manual-article.theme__light { - background-color: rgb(255, 255, 255) !important; -} - .cherry.theme__light .cherry-previewer .cherry-mobile-previewer-content { background-color: rgb(255, 255, 255); } - .cherry.theme__light .cherry-previewer-table-content-hander .cherry-previewer-table-content-hander__input textarea { background-color: rgb(255, 255, 255); color: rgb(63, 74, 86); @@ -3780,6 +3290,7 @@ div[data-type=codeBlock] .token.inserted { /** 预览区域样式 */ .cherry-markdown.theme__light { color: rgb(63, 74, 86); + background-color: rgb(255, 255, 255); /** 行内代码 */ /** * 代码块 @@ -3793,116 +3304,77 @@ div[data-type=codeBlock] .token.inserted { /** 段落公式 */ /** 目录 */ } - -.cherry-markdown.theme__light h1, -.cherry-markdown.theme__light h2, -.cherry-markdown.theme__light h3, -.cherry-markdown.theme__light h4, -.cherry-markdown.theme__light h5 { +.cherry-markdown.theme__light h1, .cherry-markdown.theme__light h2, .cherry-markdown.theme__light h3, .cherry-markdown.theme__light h4, .cherry-markdown.theme__light h5 { color: rgb(34, 139, 230); } - -.cherry-markdown.theme__light h1, -.cherry-markdown.theme__light h2, -.cherry-markdown.theme__light h3, -.cherry-markdown.theme__light h4, -.cherry-markdown.theme__light h5, -.cherry-markdown.theme__light h6 { +.cherry-markdown.theme__light h1, .cherry-markdown.theme__light h2, .cherry-markdown.theme__light h3, .cherry-markdown.theme__light h4, .cherry-markdown.theme__light h5, .cherry-markdown.theme__light h6 { /** 标题前面的锚点或序号 */ } - .cherry-markdown.theme__light ul { /** checklist 模式,未勾选时 */ /** checklist 模式,勾选时 */ } - .cherry-markdown.theme__light ul.cherry-list__upper-roman { list-style: upper-roman; } - .cherry-markdown.theme__light ul.cherry-list__lower-greek { list-style: lower-greek; } - .cherry-markdown.theme__light ul.cherry-list__cjk-ideographic { list-style: cjk-ideographic; } - .cherry-markdown.theme__light ul.cherry-list__circle { list-style: circle; } - .cherry-markdown.theme__light ul.cherry-list__square { list-style: square; } - .cherry-markdown.theme__light blockquote { color: rgb(63, 74, 86); background-color: rgb(231, 245, 255); border-color: rgb(25, 113, 194); } - .cherry-markdown.theme__light a { text-decoration: none; color: rgb(77, 171, 247); } - .cherry-markdown.theme__light a:hover { text-decoration: underline; color: rgb(34, 139, 230); } - .cherry-markdown.theme__light hr { border-color: rgb(25, 113, 194); } - -.cherry-markdown.theme__light p code, -.cherry-markdown.theme__light li code { +.cherry-markdown.theme__light p code, .cherry-markdown.theme__light li code { background-color: rgb(215, 230, 254); color: rgb(77, 171, 247); border: 1px solid rgb(25, 113, 194); } - -.cherry-markdown.theme__light table, -.cherry-markdown.theme__light .cherry-table { +.cherry-markdown.theme__light table, .cherry-markdown.theme__light .cherry-table { color: rgb(63, 74, 86); } - -.cherry-markdown.theme__light table th, -.cherry-markdown.theme__light .cherry-table th { +.cherry-markdown.theme__light table th, .cherry-markdown.theme__light .cherry-table th { background-color: rgb(215, 230, 254); } - -.cherry-markdown.theme__light table tr, -.cherry-markdown.theme__light table th, -.cherry-markdown.theme__light table td, -.cherry-markdown.theme__light .cherry-table tr, -.cherry-markdown.theme__light .cherry-table th, -.cherry-markdown.theme__light .cherry-table td { +.cherry-markdown.theme__light table tr, .cherry-markdown.theme__light table th, .cherry-markdown.theme__light table td, .cherry-markdown.theme__light .cherry-table tr, .cherry-markdown.theme__light .cherry-table th, .cherry-markdown.theme__light .cherry-table td { border-color: rgb(25, 113, 194); } - .cherry-markdown.theme__light ruby { /** 上部的拼音 */ } - .cherry-markdown.theme__light .footnote { border-color: rgb(25, 113, 194); } - .cherry-markdown.theme__light .footnote .footnote-title { background-color: rgb(215, 230, 254); } - .cherry-markdown.theme__light .footnote .one-footnote { color: rgb(63, 74, 86); border-color: rgb(25, 113, 194); } - .cherry-markdown.theme__light .footnote .one-footnote a.footnote-ref { padding: 5px; } - /** 色值可以参考:https://yeun.github.io/open-color/ */ /** 工具栏样式 */ /** 编辑区域样式 */ @@ -3914,140 +3386,87 @@ div[data-type=codeBlock] .token.inserted { /** 二级菜单 */ /** 选中文字时弹出的按钮 */ } - -.cherry.theme__green .cherry-toolbar, -.cherry.theme__green .cherry-floatmenu, -.cherry.theme__green .cherry-bubble, -.cherry.theme__green .cherry-sidebar { +.cherry.theme__green .cherry-toolbar, .cherry.theme__green .cherry-floatmenu, .cherry.theme__green .cherry-bubble, .cherry.theme__green .cherry-sidebar { background: #FFF; border-color: #FFF; } - -.cherry.theme__green .cherry-toolbar .cherry-toolbar-button, -.cherry.theme__green .cherry-floatmenu .cherry-toolbar-button, -.cherry.theme__green .cherry-bubble .cherry-toolbar-button, -.cherry.theme__green .cherry-sidebar .cherry-toolbar-button { +.cherry.theme__green .cherry-toolbar .cherry-toolbar-button, .cherry.theme__green .cherry-floatmenu .cherry-toolbar-button, .cherry.theme__green .cherry-bubble .cherry-toolbar-button, .cherry.theme__green .cherry-sidebar .cherry-toolbar-button { color: #2b8a3e; } - -.cherry.theme__green .cherry-toolbar .cherry-toolbar-button i, -.cherry.theme__green .cherry-floatmenu .cherry-toolbar-button i, -.cherry.theme__green .cherry-bubble .cherry-toolbar-button i, -.cherry.theme__green .cherry-sidebar .cherry-toolbar-button i { +.cherry.theme__green .cherry-toolbar .cherry-toolbar-button i, .cherry.theme__green .cherry-floatmenu .cherry-toolbar-button i, .cherry.theme__green .cherry-bubble .cherry-toolbar-button i, .cherry.theme__green .cherry-sidebar .cherry-toolbar-button i { color: #2b8a3e; } - -.cherry.theme__green .cherry-toolbar .cherry-toolbar-button:hover, -.cherry.theme__green .cherry-floatmenu .cherry-toolbar-button:hover, -.cherry.theme__green .cherry-bubble .cherry-toolbar-button:hover, -.cherry.theme__green .cherry-sidebar .cherry-toolbar-button:hover { +.cherry.theme__green .cherry-toolbar .cherry-toolbar-button:hover, .cherry.theme__green .cherry-floatmenu .cherry-toolbar-button:hover, .cherry.theme__green .cherry-bubble .cherry-toolbar-button:hover, .cherry.theme__green .cherry-sidebar .cherry-toolbar-button:hover { background-color: #51cf66; color: #ebfbee !important; border-color: #FFF; } - -.cherry.theme__green .cherry-toolbar .cherry-toolbar-button:hover i, -.cherry.theme__green .cherry-floatmenu .cherry-toolbar-button:hover i, -.cherry.theme__green .cherry-bubble .cherry-toolbar-button:hover i, -.cherry.theme__green .cherry-sidebar .cherry-toolbar-button:hover i { +.cherry.theme__green .cherry-toolbar .cherry-toolbar-button:hover i, .cherry.theme__green .cherry-floatmenu .cherry-toolbar-button:hover i, .cherry.theme__green .cherry-bubble .cherry-toolbar-button:hover i, .cherry.theme__green .cherry-sidebar .cherry-toolbar-button:hover i { color: #ebfbee !important; } - .cherry.theme__green .cherry-dropdown { background: #FFF; /** 选择颜色的按钮 */ } - .cherry.theme__green .cherry-dropdown .cherry-dropdown-item { color: #2b8a3e; } - .cherry.theme__green .cherry-dropdown .cherry-dropdown-item:hover { background-color: #51cf66; color: #ebfbee; } - .cherry.theme__green .cherry-dropdown.cherry-color-wrap { /** 色盘的标题 */ /** 色盘里的每一个色块 */ } - .cherry.theme__green .cherry-dropdown.cherry-color-wrap h3 { color: #2b8a3e; } - .cherry.theme__green .cherry-dropdown.cherry-color-wrap .cherry-color-item { border-color: #51cf66; } - .cherry.theme__green .cherry-dropdown.cherry-color-wrap .cherry-color-item:hover { border-color: #2b8a3e; } - .cherry.theme__green .cherry-bubble { /** 粘贴HTML内容时弹出的选择按钮 */ } - .cherry.theme__green .cherry-bubble .cherry-bubble-bottom { border-top-color: #FFF; } - .cherry.theme__green .cherry-editor { background-color: #FFF; } - .cherry.theme__green .cherry-editor .CodeMirror { background-color: #FFF; } - .cherry.theme__green .cherry-editor .CodeMirror .CodeMirror-cursor { border-left: 1px solid #2b8a3e; } - -.cherry.theme__green .cherry-editor .CodeMirror .CodeMirror-scroll span, -.cherry.theme__green .cherry-editor .CodeMirror .CodeMirror-scroll .cm-variable-2, -.cherry.theme__green .cherry-editor .CodeMirror .CodeMirror-scroll .cm-string, -.cherry.theme__green .cherry-editor .CodeMirror .CodeMirror-scroll .cm-strong, -.cherry.theme__green .cherry-editor .CodeMirror .CodeMirror-scroll .cm-em, -.cherry.theme__green .cherry-editor .CodeMirror .CodeMirror-scroll .cm-meta { +.cherry.theme__green .cherry-editor .CodeMirror .CodeMirror-scroll span, .cherry.theme__green .cherry-editor .CodeMirror .CodeMirror-scroll .cm-variable-2, .cherry.theme__green .cherry-editor .CodeMirror .CodeMirror-scroll .cm-string, .cherry.theme__green .cherry-editor .CodeMirror .CodeMirror-scroll .cm-strong, .cherry.theme__green .cherry-editor .CodeMirror .CodeMirror-scroll .cm-em, .cherry.theme__green .cherry-editor .CodeMirror .CodeMirror-scroll .cm-meta { color: #2b8a3e; } - -.cherry.theme__green .cherry-editor .CodeMirror .CodeMirror-scroll .cm-image-marker, -.cherry.theme__green .cherry-editor .CodeMirror .CodeMirror-scroll .cm-quote, -.cherry.theme__green .cherry-editor .CodeMirror .CodeMirror-scroll .cm-header { +.cherry.theme__green .cherry-editor .CodeMirror .CodeMirror-scroll .cm-image-marker, .cherry.theme__green .cherry-editor .CodeMirror .CodeMirror-scroll .cm-quote, .cherry.theme__green .cherry-editor .CodeMirror .CodeMirror-scroll .cm-header { color: #37b24d; } - .cherry.theme__green .cherry-editor .CodeMirror .CodeMirror-scroll .cm-url { background-color: #ebfbee; } - -.cherry.theme__green .cherry-editor .CodeMirror .CodeMirror-scroll .cm-comment, -.cherry.theme__green .cherry-editor .CodeMirror .CodeMirror-scroll .cm-url { +.cherry.theme__green .cherry-editor .CodeMirror .CodeMirror-scroll .cm-comment, .cherry.theme__green .cherry-editor .CodeMirror .CodeMirror-scroll .cm-url { color: #40c057; } - .cherry.theme__green .cherry-editor .CodeMirror .CodeMirror-selected { background-color: #b2f2bb; } - .cherry.theme__green .cherry-sidebar { box-shadow: 0 0 10px rgba(128, 145, 165, 0.2); } - .cherry.theme__green .cherry-previewer { background-color: #ebfbee; } - -.manual-article.theme__green { - background-color: #ebfbee !important; -} - .cherry.theme__green .cherry-previewer .cherry-mobile-previewer-content { background-color: #FFF; } - .cherry.theme__green .cherry-previewer-table-content-hander .cherry-previewer-table-content-hander__input textarea { background-color: #FFF; color: #2b8a3e; @@ -4057,6 +3476,7 @@ div[data-type=codeBlock] .token.inserted { /** 预览区域样式 */ .cherry-markdown.theme__green { color: #2b8a3e; + background-color: #ebfbee; /** 行内代码 */ /** * 代码块 @@ -4070,124 +3490,84 @@ div[data-type=codeBlock] .token.inserted { /** 段落公式 */ /** 目录 */ } - -.cherry-markdown.theme__green h1, -.cherry-markdown.theme__green h2, -.cherry-markdown.theme__green h3, -.cherry-markdown.theme__green h4, -.cherry-markdown.theme__green h5 { +.cherry-markdown.theme__green h1, .cherry-markdown.theme__green h2, .cherry-markdown.theme__green h3, .cherry-markdown.theme__green h4, .cherry-markdown.theme__green h5 { color: #37b24d; text-align: center; margin-bottom: 35px; } - -.cherry-markdown.theme__green h1, -.cherry-markdown.theme__green h2, -.cherry-markdown.theme__green h3, -.cherry-markdown.theme__green h4, -.cherry-markdown.theme__green h5, -.cherry-markdown.theme__green h6 { +.cherry-markdown.theme__green h1, .cherry-markdown.theme__green h2, .cherry-markdown.theme__green h3, .cherry-markdown.theme__green h4, .cherry-markdown.theme__green h5, .cherry-markdown.theme__green h6 { /** 标题前面的锚点或序号 */ } - .cherry-markdown.theme__green ul { /** checklist 模式,未勾选时 */ /** checklist 模式,勾选时 */ } - .cherry-markdown.theme__green ul.cherry-list__upper-roman { list-style: upper-roman; } - .cherry-markdown.theme__green ul.cherry-list__lower-greek { list-style: lower-greek; } - .cherry-markdown.theme__green ul.cherry-list__cjk-ideographic { list-style: cjk-ideographic; } - .cherry-markdown.theme__green ul.cherry-list__circle { list-style: circle; } - .cherry-markdown.theme__green ul.cherry-list__square { list-style: square; } - .cherry-markdown.theme__green blockquote { color: #2b8a3e; background-color: #d3f9d8; border-color: #2f9e44; } - .cherry-markdown.theme__green a { text-decoration: none; color: #40c057; } - .cherry-markdown.theme__green a:hover { text-decoration: underline; color: #37b24d; } - .cherry-markdown.theme__green hr { border-color: #2f9e44; } - -.cherry-markdown.theme__green p code, -.cherry-markdown.theme__green li code { +.cherry-markdown.theme__green p code, .cherry-markdown.theme__green li code { background-color: #d3f9d8; color: #40c057; border: 1px solid #2f9e44; } - -.cherry-markdown.theme__green table, -.cherry-markdown.theme__green .cherry-table { +.cherry-markdown.theme__green table, .cherry-markdown.theme__green .cherry-table { color: #2b8a3e; } - -.cherry-markdown.theme__green table th, -.cherry-markdown.theme__green .cherry-table th { +.cherry-markdown.theme__green table th, .cherry-markdown.theme__green .cherry-table th { background-color: #d3f9d8; } - -.cherry-markdown.theme__green table tr, -.cherry-markdown.theme__green table th, -.cherry-markdown.theme__green table td, -.cherry-markdown.theme__green .cherry-table tr, -.cherry-markdown.theme__green .cherry-table th, -.cherry-markdown.theme__green .cherry-table td { +.cherry-markdown.theme__green table tr, .cherry-markdown.theme__green table th, .cherry-markdown.theme__green table td, .cherry-markdown.theme__green .cherry-table tr, .cherry-markdown.theme__green .cherry-table th, .cherry-markdown.theme__green .cherry-table td { border-color: #2f9e44; } - .cherry-markdown.theme__green ruby { /** 上部的拼音 */ } - .cherry-markdown.theme__green .footnote { border-color: #2f9e44; } - .cherry-markdown.theme__green .footnote .footnote-title { background-color: #d3f9d8; } - .cherry-markdown.theme__green .footnote .one-footnote { color: #2b8a3e; border-color: #2f9e44; } - .cherry-markdown.theme__green .footnote .one-footnote a.footnote-ref { padding: 5px; } - .cherry-markdown.theme__green .toc { border-bottom: 1px solid #2f9e44; padding-bottom: 15px; margin-bottom: 30px; } - .cherry-markdown.theme__green .toc .toc-title { text-align: center; padding-bottom: 15px; @@ -4195,15 +3575,12 @@ div[data-type=codeBlock] .token.inserted { margin-bottom: 15px; border-bottom: 1px solid #2f9e44; } - .cherry-markdown.theme__green .toc .toc-li { border: none; } - .cherry-markdown.theme__green .toc .toc-li a { color: #2b8a3e; } - .cherry-markdown.theme__green .toc .toc-li a:hover { color: #37b24d; } @@ -4219,140 +3596,87 @@ div[data-type=codeBlock] .token.inserted { /** 二级菜单 */ /** 选中文字时弹出的按钮 */ } - -.cherry.theme__red .cherry-toolbar, -.cherry.theme__red .cherry-floatmenu, -.cherry.theme__red .cherry-bubble, -.cherry.theme__red .cherry-sidebar { +.cherry.theme__red .cherry-toolbar, .cherry.theme__red .cherry-floatmenu, .cherry.theme__red .cherry-bubble, .cherry.theme__red .cherry-sidebar { background: #ffdeeb; border-color: #ffdeeb; } - -.cherry.theme__red .cherry-toolbar .cherry-toolbar-button, -.cherry.theme__red .cherry-floatmenu .cherry-toolbar-button, -.cherry.theme__red .cherry-bubble .cherry-toolbar-button, -.cherry.theme__red .cherry-sidebar .cherry-toolbar-button { +.cherry.theme__red .cherry-toolbar .cherry-toolbar-button, .cherry.theme__red .cherry-floatmenu .cherry-toolbar-button, .cherry.theme__red .cherry-bubble .cherry-toolbar-button, .cherry.theme__red .cherry-sidebar .cherry-toolbar-button { color: #c2255c; } - -.cherry.theme__red .cherry-toolbar .cherry-toolbar-button i, -.cherry.theme__red .cherry-floatmenu .cherry-toolbar-button i, -.cherry.theme__red .cherry-bubble .cherry-toolbar-button i, -.cherry.theme__red .cherry-sidebar .cherry-toolbar-button i { +.cherry.theme__red .cherry-toolbar .cherry-toolbar-button i, .cherry.theme__red .cherry-floatmenu .cherry-toolbar-button i, .cherry.theme__red .cherry-bubble .cherry-toolbar-button i, .cherry.theme__red .cherry-sidebar .cherry-toolbar-button i { color: #c2255c; } - -.cherry.theme__red .cherry-toolbar .cherry-toolbar-button:hover, -.cherry.theme__red .cherry-floatmenu .cherry-toolbar-button:hover, -.cherry.theme__red .cherry-bubble .cherry-toolbar-button:hover, -.cherry.theme__red .cherry-sidebar .cherry-toolbar-button:hover { +.cherry.theme__red .cherry-toolbar .cherry-toolbar-button:hover, .cherry.theme__red .cherry-floatmenu .cherry-toolbar-button:hover, .cherry.theme__red .cherry-bubble .cherry-toolbar-button:hover, .cherry.theme__red .cherry-sidebar .cherry-toolbar-button:hover { background-color: #f06595; color: #fff0f6 !important; border-color: #ffdeeb; } - -.cherry.theme__red .cherry-toolbar .cherry-toolbar-button:hover i, -.cherry.theme__red .cherry-floatmenu .cherry-toolbar-button:hover i, -.cherry.theme__red .cherry-bubble .cherry-toolbar-button:hover i, -.cherry.theme__red .cherry-sidebar .cherry-toolbar-button:hover i { +.cherry.theme__red .cherry-toolbar .cherry-toolbar-button:hover i, .cherry.theme__red .cherry-floatmenu .cherry-toolbar-button:hover i, .cherry.theme__red .cherry-bubble .cherry-toolbar-button:hover i, .cherry.theme__red .cherry-sidebar .cherry-toolbar-button:hover i { color: #fff0f6 !important; } - .cherry.theme__red .cherry-dropdown { background: #ffdeeb; /** 选择颜色的按钮 */ } - .cherry.theme__red .cherry-dropdown .cherry-dropdown-item { color: #c2255c; } - .cherry.theme__red .cherry-dropdown .cherry-dropdown-item:hover { background-color: #f06595; color: #fff0f6; } - .cherry.theme__red .cherry-dropdown.cherry-color-wrap { /** 色盘的标题 */ /** 色盘里的每一个色块 */ } - .cherry.theme__red .cherry-dropdown.cherry-color-wrap h3 { color: #c2255c; } - .cherry.theme__red .cherry-dropdown.cherry-color-wrap .cherry-color-item { border-color: #f06595; } - .cherry.theme__red .cherry-dropdown.cherry-color-wrap .cherry-color-item:hover { border-color: #a61e4d; } - .cherry.theme__red .cherry-bubble { /** 粘贴HTML内容时弹出的选择按钮 */ } - .cherry.theme__red .cherry-bubble .cherry-bubble-bottom { border-top-color: #ffdeeb; } - .cherry.theme__red .cherry-editor { background-color: #fff0f6; } - .cherry.theme__red .cherry-editor .CodeMirror { background-color: #fff0f6; } - .cherry.theme__red .cherry-editor .CodeMirror .CodeMirror-cursor { border-left: 1px solid #a61e4d; } - -.cherry.theme__red .cherry-editor .CodeMirror .CodeMirror-scroll span, -.cherry.theme__red .cherry-editor .CodeMirror .CodeMirror-scroll .cm-variable-2, -.cherry.theme__red .cherry-editor .CodeMirror .CodeMirror-scroll .cm-string, -.cherry.theme__red .cherry-editor .CodeMirror .CodeMirror-scroll .cm-strong, -.cherry.theme__red .cherry-editor .CodeMirror .CodeMirror-scroll .cm-em, -.cherry.theme__red .cherry-editor .CodeMirror .CodeMirror-scroll .cm-meta { +.cherry.theme__red .cherry-editor .CodeMirror .CodeMirror-scroll span, .cherry.theme__red .cherry-editor .CodeMirror .CodeMirror-scroll .cm-variable-2, .cherry.theme__red .cherry-editor .CodeMirror .CodeMirror-scroll .cm-string, .cherry.theme__red .cherry-editor .CodeMirror .CodeMirror-scroll .cm-strong, .cherry.theme__red .cherry-editor .CodeMirror .CodeMirror-scroll .cm-em, .cherry.theme__red .cherry-editor .CodeMirror .CodeMirror-scroll .cm-meta { color: #a61e4d; } - -.cherry.theme__red .cherry-editor .CodeMirror .CodeMirror-scroll .cm-image-marker, -.cherry.theme__red .cherry-editor .CodeMirror .CodeMirror-scroll .cm-quote, -.cherry.theme__red .cherry-editor .CodeMirror .CodeMirror-scroll .cm-header { +.cherry.theme__red .cherry-editor .CodeMirror .CodeMirror-scroll .cm-image-marker, .cherry.theme__red .cherry-editor .CodeMirror .CodeMirror-scroll .cm-quote, .cherry.theme__red .cherry-editor .CodeMirror .CodeMirror-scroll .cm-header { color: #d6336c; } - .cherry.theme__red .cherry-editor .CodeMirror .CodeMirror-scroll .cm-url { background-color: #ffdeeb; } - -.cherry.theme__red .cherry-editor .CodeMirror .CodeMirror-scroll .cm-comment, -.cherry.theme__red .cherry-editor .CodeMirror .CodeMirror-scroll .cm-url { +.cherry.theme__red .cherry-editor .CodeMirror .CodeMirror-scroll .cm-comment, .cherry.theme__red .cherry-editor .CodeMirror .CodeMirror-scroll .cm-url { color: #f06595; } - .cherry.theme__red .cherry-editor .CodeMirror .CodeMirror-selected { background-color: #fcc2d7; } - .cherry.theme__red .cherry-sidebar { box-shadow: 0 0 10px #fcc2d7; } - .cherry.theme__red .cherry-previewer { background-color: #fff0f6; } - -.manual-article.theme__red { - background-color: #fff0f6 !important; -} - .cherry.theme__red .cherry-previewer .cherry-mobile-previewer-content { background-color: #fff0f6; } - .cherry.theme__red .cherry-previewer-table-content-hander .cherry-previewer-table-content-hander__input textarea { background-color: #fff0f6; color: #a61e4d; @@ -4362,6 +3686,7 @@ div[data-type=codeBlock] .token.inserted { /** 预览区域样式 */ .cherry-markdown.theme__red { color: #a61e4d; + background-color: #fff0f6; /** 行内代码 */ /** * 代码块 @@ -4375,126 +3700,86 @@ div[data-type=codeBlock] .token.inserted { /** 段落公式 */ /** 目录 */ } - -.cherry-markdown.theme__red h1, -.cherry-markdown.theme__red h2, -.cherry-markdown.theme__red h3, -.cherry-markdown.theme__red h4, -.cherry-markdown.theme__red h5 { +.cherry-markdown.theme__red h1, .cherry-markdown.theme__red h2, .cherry-markdown.theme__red h3, .cherry-markdown.theme__red h4, .cherry-markdown.theme__red h5 { color: #d6336c; text-align: center; border-bottom: 1px dashed #c2255c; padding-bottom: 15px; margin-bottom: 25px; } - -.cherry-markdown.theme__red h1, -.cherry-markdown.theme__red h2, -.cherry-markdown.theme__red h3, -.cherry-markdown.theme__red h4, -.cherry-markdown.theme__red h5, -.cherry-markdown.theme__red h6 { +.cherry-markdown.theme__red h1, .cherry-markdown.theme__red h2, .cherry-markdown.theme__red h3, .cherry-markdown.theme__red h4, .cherry-markdown.theme__red h5, .cherry-markdown.theme__red h6 { /** 标题前面的锚点或序号 */ } - .cherry-markdown.theme__red ul { /** checklist 模式,未勾选时 */ /** checklist 模式,勾选时 */ } - .cherry-markdown.theme__red ul.cherry-list__upper-roman { list-style: upper-roman; } - .cherry-markdown.theme__red ul.cherry-list__lower-greek { list-style: lower-greek; } - .cherry-markdown.theme__red ul.cherry-list__cjk-ideographic { list-style: cjk-ideographic; } - .cherry-markdown.theme__red ul.cherry-list__circle { list-style: circle; } - .cherry-markdown.theme__red ul.cherry-list__square { list-style: square; } - .cherry-markdown.theme__red blockquote { color: #a61e4d; background-color: #ffdeeb; border-color: #c2255c; } - .cherry-markdown.theme__red a { text-decoration: none; color: #f06595; } - .cherry-markdown.theme__red a:hover { text-decoration: underline; color: #d6336c; } - .cherry-markdown.theme__red hr { border-color: #c2255c; } - -.cherry-markdown.theme__red p code, -.cherry-markdown.theme__red li code { +.cherry-markdown.theme__red p code, .cherry-markdown.theme__red li code { background-color: #ffdeeb; color: #f06595; border: 1px solid #c2255c; } - -.cherry-markdown.theme__red table, -.cherry-markdown.theme__red .cherry-table { +.cherry-markdown.theme__red table, .cherry-markdown.theme__red .cherry-table { color: #a61e4d; } - -.cherry-markdown.theme__red table th, -.cherry-markdown.theme__red .cherry-table th { +.cherry-markdown.theme__red table th, .cherry-markdown.theme__red .cherry-table th { background-color: #ffdeeb; } - -.cherry-markdown.theme__red table tr, -.cherry-markdown.theme__red table th, -.cherry-markdown.theme__red table td, -.cherry-markdown.theme__red .cherry-table tr, -.cherry-markdown.theme__red .cherry-table th, -.cherry-markdown.theme__red .cherry-table td { +.cherry-markdown.theme__red table tr, .cherry-markdown.theme__red table th, .cherry-markdown.theme__red table td, .cherry-markdown.theme__red .cherry-table tr, .cherry-markdown.theme__red .cherry-table th, .cherry-markdown.theme__red .cherry-table td { border-color: #c2255c; } - .cherry-markdown.theme__red ruby { /** 上部的拼音 */ } - .cherry-markdown.theme__red .footnote { border-color: #c2255c; } - .cherry-markdown.theme__red .footnote .footnote-title { background-color: #ffdeeb; } - .cherry-markdown.theme__red .footnote .one-footnote { color: #a61e4d; border-color: #c2255c; } - .cherry-markdown.theme__red .footnote .one-footnote a.footnote-ref { padding: 5px; } - .cherry-markdown.theme__red .toc { border-bottom: 1px solid #c2255c; padding-bottom: 15px; margin-bottom: 30px; } - .cherry-markdown.theme__red .toc .toc-title { text-align: center; padding-bottom: 15px; @@ -4502,49 +3787,464 @@ div[data-type=codeBlock] .token.inserted { margin-bottom: 15px; border-bottom: 1px solid #c2255c; } - .cherry-markdown.theme__red .toc .toc-li { border: none; } - .cherry-markdown.theme__red .toc .toc-li a { color: #a61e4d; } - .cherry-markdown.theme__red .toc .toc-li a:hover { color: #d6336c; } -/* BASICS */ -.CodeMirror { - /* Set height, width, borders, and global font properties here */ - font-family: monospace; - height: 300px; - color: black; - direction: ltr; +/** 工具栏样式 */ +/** 编辑区域样式 */ +/** 预览区域样式 */ +/** markdown样式 */ +/** 编辑器样式 */ +.cherry.theme__violet { + /** 顶部按钮, 选中文字时弹出的按钮, 光标focus到空行时联想出的按钮, 侧边栏按钮 */ + /** 二级菜单 */ + /** 选中文字时弹出的按钮 */ + /** 光标focus到空行时联想出的按钮 */ } - -/* PADDING */ -.CodeMirror-lines { - padding: 4px 0; - /* Vertical padding around content */ +.cherry.theme__violet .cherry-toolbar, .cherry.theme__violet .cherry-floatmenu, .cherry.theme__violet .cherry-bubble, .cherry.theme__violet .cherry-sidebar { + background: #FFF; + border-color: #FFF; } - -.CodeMirror pre.CodeMirror-line, -.CodeMirror pre.CodeMirror-line-like { - padding: 0 4px; - /* Horizontal padding of content */ +.cherry.theme__violet .cherry-toolbar .cherry-toolbar-button, .cherry.theme__violet .cherry-floatmenu .cherry-toolbar-button, .cherry.theme__violet .cherry-bubble .cherry-toolbar-button, .cherry.theme__violet .cherry-sidebar .cherry-toolbar-button { + color: #5f3dc4; } - -.CodeMirror-scrollbar-filler, -.CodeMirror-gutter-filler { - background-color: white; - /* The little square between H and V scrollbars */ +.cherry.theme__violet .cherry-toolbar .cherry-toolbar-button i, .cherry.theme__violet .cherry-floatmenu .cherry-toolbar-button i, .cherry.theme__violet .cherry-bubble .cherry-toolbar-button i, .cherry.theme__violet .cherry-sidebar .cherry-toolbar-button i { + color: #5f3dc4; } - -/* GUTTER */ -.CodeMirror-gutters { - border-right: 1px solid #ddd; +.cherry.theme__violet .cherry-toolbar .cherry-toolbar-button:hover, .cherry.theme__violet .cherry-floatmenu .cherry-toolbar-button:hover, .cherry.theme__violet .cherry-bubble .cherry-toolbar-button:hover, .cherry.theme__violet .cherry-sidebar .cherry-toolbar-button:hover { + background-color: #845ef7; + color: #f3f0ff !important; + border-color: #FFF; +} +.cherry.theme__violet .cherry-toolbar .cherry-toolbar-button:hover i, .cherry.theme__violet .cherry-floatmenu .cherry-toolbar-button:hover i, .cherry.theme__violet .cherry-bubble .cherry-toolbar-button:hover i, .cherry.theme__violet .cherry-sidebar .cherry-toolbar-button:hover i { + color: #f3f0ff !important; +} +.cherry.theme__violet .cherry-dropdown { + background: #FFF; + /** 选择颜色的按钮 */ +} +.cherry.theme__violet .cherry-dropdown .cherry-dropdown-item { + color: #5f3dc4; +} +.cherry.theme__violet .cherry-dropdown .cherry-dropdown-item:hover { + background-color: #845ef7; + color: #f3f0ff; +} +.cherry.theme__violet .cherry-dropdown.cherry-color-wrap { + /** 色盘的标题 */ + /** 色盘里的每一个色块 */ +} +.cherry.theme__violet .cherry-dropdown.cherry-color-wrap h3 { + color: #5f3dc4; +} +.cherry.theme__violet .cherry-dropdown.cherry-color-wrap .cherry-color-item { + border-color: #845ef7; +} +.cherry.theme__violet .cherry-dropdown.cherry-color-wrap .cherry-color-item:hover { + border-color: #5f3dc4; +} +.cherry.theme__violet .cherry-bubble { + /** 粘贴HTML内容时弹出的选择按钮 */ +} +.cherry.theme__violet .cherry-bubble .cherry-bubble-bottom { + border-top-color: #FFF; +} +.cherry.theme__violet .cherry-editor { + background-color: #FFF; +} +.cherry.theme__violet .cherry-editor .CodeMirror { + background-color: #FFF; +} +.cherry.theme__violet .cherry-editor .CodeMirror .CodeMirror-cursor { + border-left: 1px solid #5f3dc4; +} +.cherry.theme__violet .cherry-editor .CodeMirror .CodeMirror-scroll span, .cherry.theme__violet .cherry-editor .CodeMirror .CodeMirror-scroll .cm-variable-2, .cherry.theme__violet .cherry-editor .CodeMirror .CodeMirror-scroll .cm-string, .cherry.theme__violet .cherry-editor .CodeMirror .CodeMirror-scroll .cm-strong, .cherry.theme__violet .cherry-editor .CodeMirror .CodeMirror-scroll .cm-em, .cherry.theme__violet .cherry-editor .CodeMirror .CodeMirror-scroll .cm-meta { + color: #5f3dc4; +} +.cherry.theme__violet .cherry-editor .CodeMirror .CodeMirror-scroll .cm-image-marker, .cherry.theme__violet .cherry-editor .CodeMirror .CodeMirror-scroll .cm-quote, .cherry.theme__violet .cherry-editor .CodeMirror .CodeMirror-scroll .cm-header { + color: #7048e8; +} +.cherry.theme__violet .cherry-editor .CodeMirror .CodeMirror-scroll .cm-url { + background-color: #f3f0ff; +} +.cherry.theme__violet .cherry-editor .CodeMirror .CodeMirror-scroll .cm-comment, .cherry.theme__violet .cherry-editor .CodeMirror .CodeMirror-scroll .cm-url { + color: #7950f2; +} +.cherry.theme__violet .cherry-editor .CodeMirror .CodeMirror-selected { + background-color: #d0bfff; +} +.cherry.theme__violet .cherry-sidebar { + box-shadow: 0 0 10px rgba(128, 145, 165, 0.2); +} +.cherry.theme__violet .cherry-previewer { + background-color: #FFF; +} +.cherry.theme__violet .cherry-previewer .cherry-mobile-previewer-content { + background-color: #FFF; +} +.cherry.theme__violet .cherry-previewer-table-content-hander .cherry-previewer-table-content-hander__input textarea { + background-color: #FFF; + color: #5f3dc4; + outline-color: #7048e8; +} + +/** 预览区域样式 */ +.cherry-markdown.theme__violet { + color: #5f3dc4; + background-color: #FFF; + /** 行内代码 */ + /** + * 代码块 + */ + /** + * 表格 + */ + /** 可以理解为上下结构的音标,下部是文字,上部是对应的拼音 */ + /** 脚注 */ + /** 行间公式 */ + /** 段落公式 */ + /** 目录 */ +} +.cherry-markdown.theme__violet h1, .cherry-markdown.theme__violet h2, .cherry-markdown.theme__violet h3, .cherry-markdown.theme__violet h4, .cherry-markdown.theme__violet h5 { + color: #7048e8; + text-align: center; + margin-bottom: 35px; +} +.cherry-markdown.theme__violet h1, .cherry-markdown.theme__violet h2, .cherry-markdown.theme__violet h3, .cherry-markdown.theme__violet h4, .cherry-markdown.theme__violet h5, .cherry-markdown.theme__violet h6 { + /** 标题前面的锚点或序号 */ +} +.cherry-markdown.theme__violet ul { + /** checklist 模式,未勾选时 */ + /** checklist 模式,勾选时 */ +} +.cherry-markdown.theme__violet ul.cherry-list__upper-roman { + list-style: upper-roman; +} +.cherry-markdown.theme__violet ul.cherry-list__lower-greek { + list-style: lower-greek; +} +.cherry-markdown.theme__violet ul.cherry-list__cjk-ideographic { + list-style: cjk-ideographic; +} +.cherry-markdown.theme__violet ul.cherry-list__circle { + list-style: circle; +} +.cherry-markdown.theme__violet ul.cherry-list__square { + list-style: square; +} +.cherry-markdown.theme__violet blockquote { + color: #5f3dc4; + background-color: #e5dbff; + border-color: #6741d9; +} +.cherry-markdown.theme__violet a { + text-decoration: none; + color: #7950f2; +} +.cherry-markdown.theme__violet a:hover { + text-decoration: underline; + color: #7048e8; +} +.cherry-markdown.theme__violet hr { + border-color: #6741d9; +} +.cherry-markdown.theme__violet p code, .cherry-markdown.theme__violet li code { + background-color: #e5dbff; + color: #7950f2; + border: 1px solid #6741d9; +} +.cherry-markdown.theme__violet table, .cherry-markdown.theme__violet .cherry-table { + color: #5f3dc4; +} +.cherry-markdown.theme__violet table th, .cherry-markdown.theme__violet .cherry-table th { + background-color: #e5dbff; +} +.cherry-markdown.theme__violet table tr, .cherry-markdown.theme__violet table th, .cherry-markdown.theme__violet table td, .cherry-markdown.theme__violet .cherry-table tr, .cherry-markdown.theme__violet .cherry-table th, .cherry-markdown.theme__violet .cherry-table td { + border-color: #6741d9; +} +.cherry-markdown.theme__violet ruby { + /** 上部的拼音 */ +} +.cherry-markdown.theme__violet .footnote { + border-color: #6741d9; +} +.cherry-markdown.theme__violet .footnote .footnote-title { + background-color: #e5dbff; +} +.cherry-markdown.theme__violet .footnote .one-footnote { + color: #5f3dc4; + border-color: #6741d9; +} +.cherry-markdown.theme__violet .footnote .one-footnote a.footnote-ref { + padding: 5px; +} +.cherry-markdown.theme__violet .toc { + border-bottom: 1px solid #6741d9; + padding-bottom: 15px; + margin-bottom: 30px; +} +.cherry-markdown.theme__violet .toc .toc-title { + text-align: center; + padding-bottom: 15px; + margin-top: 30px; + margin-bottom: 15px; + border-bottom: 1px solid #6741d9; +} +.cherry-markdown.theme__violet .toc .toc-li { + border: none; +} +.cherry-markdown.theme__violet .toc .toc-li a { + color: #5f3dc4; +} +.cherry-markdown.theme__violet .toc .toc-li a:hover { + color: #7048e8; +} + +/** 色值可以参考:https://yeun.github.io/open-color/ */ +/** 工具栏样式 */ +/** 编辑区域样式 */ +/** 预览区域样式 */ +/** markdown样式 */ +/** 编辑器样式 */ +.cherry.theme__blue { + /** 顶部按钮, 选中文字时弹出的按钮, 光标focus到空行时联想出的按钮, 侧边栏按钮 */ + /** 二级菜单 */ + /** 选中文字时弹出的按钮 */ +} +.cherry.theme__blue .cherry-toolbar, .cherry.theme__blue .cherry-floatmenu, .cherry.theme__blue .cherry-bubble, .cherry.theme__blue .cherry-sidebar { + background: #e5dbff; + border-color: #e5dbff; +} +.cherry.theme__blue .cherry-toolbar .cherry-toolbar-button, .cherry.theme__blue .cherry-floatmenu .cherry-toolbar-button, .cherry.theme__blue .cherry-bubble .cherry-toolbar-button, .cherry.theme__blue .cherry-sidebar .cherry-toolbar-button { + color: #3b5bdb; +} +.cherry.theme__blue .cherry-toolbar .cherry-toolbar-button i, .cherry.theme__blue .cherry-floatmenu .cherry-toolbar-button i, .cherry.theme__blue .cherry-bubble .cherry-toolbar-button i, .cherry.theme__blue .cherry-sidebar .cherry-toolbar-button i { + color: #3b5bdb; +} +.cherry.theme__blue .cherry-toolbar .cherry-toolbar-button:hover, .cherry.theme__blue .cherry-floatmenu .cherry-toolbar-button:hover, .cherry.theme__blue .cherry-bubble .cherry-toolbar-button:hover, .cherry.theme__blue .cherry-sidebar .cherry-toolbar-button:hover { + background-color: #845ef7; + color: #edf2ff !important; + border-color: #e5dbff; +} +.cherry.theme__blue .cherry-toolbar .cherry-toolbar-button:hover i, .cherry.theme__blue .cherry-floatmenu .cherry-toolbar-button:hover i, .cherry.theme__blue .cherry-bubble .cherry-toolbar-button:hover i, .cherry.theme__blue .cherry-sidebar .cherry-toolbar-button:hover i { + color: #edf2ff !important; +} +.cherry.theme__blue .cherry-dropdown { + background: #e5dbff; + /** 选择颜色的按钮 */ +} +.cherry.theme__blue .cherry-dropdown .cherry-dropdown-item { + color: #3b5bdb; +} +.cherry.theme__blue .cherry-dropdown .cherry-dropdown-item:hover { + background-color: #845ef7; + color: #edf2ff; +} +.cherry.theme__blue .cherry-dropdown.cherry-color-wrap { + /** 色盘的标题 */ + /** 色盘里的每一个色块 */ +} +.cherry.theme__blue .cherry-dropdown.cherry-color-wrap h3 { + color: #3b5bdb; +} +.cherry.theme__blue .cherry-dropdown.cherry-color-wrap .cherry-color-item { + border-color: #845ef7; +} +.cherry.theme__blue .cherry-dropdown.cherry-color-wrap .cherry-color-item:hover { + border-color: #364fc7; +} +.cherry.theme__blue .cherry-bubble { + /** 粘贴HTML内容时弹出的选择按钮 */ +} +.cherry.theme__blue .cherry-bubble .cherry-bubble-bottom { + border-top-color: #e5dbff; +} +.cherry.theme__blue .cherry-editor { + background-color: #f3f0ff; +} +.cherry.theme__blue .cherry-editor .CodeMirror { + background-color: #f3f0ff; +} +.cherry.theme__blue .cherry-editor .CodeMirror .CodeMirror-cursor { + border-left: 1px solid #364fc7; +} +.cherry.theme__blue .cherry-editor .CodeMirror .CodeMirror-scroll span, .cherry.theme__blue .cherry-editor .CodeMirror .CodeMirror-scroll .cm-variable-2, .cherry.theme__blue .cherry-editor .CodeMirror .CodeMirror-scroll .cm-string, .cherry.theme__blue .cherry-editor .CodeMirror .CodeMirror-scroll .cm-strong, .cherry.theme__blue .cherry-editor .CodeMirror .CodeMirror-scroll .cm-em, .cherry.theme__blue .cherry-editor .CodeMirror .CodeMirror-scroll .cm-meta { + color: #364fc7; +} +.cherry.theme__blue .cherry-editor .CodeMirror .CodeMirror-scroll .cm-image-marker, .cherry.theme__blue .cherry-editor .CodeMirror .CodeMirror-scroll .cm-quote, .cherry.theme__blue .cherry-editor .CodeMirror .CodeMirror-scroll .cm-header { + color: #4263eb; +} +.cherry.theme__blue .cherry-editor .CodeMirror .CodeMirror-scroll .cm-url { + background-color: #e5dbff; +} +.cherry.theme__blue .cherry-editor .CodeMirror .CodeMirror-scroll .cm-comment, .cherry.theme__blue .cherry-editor .CodeMirror .CodeMirror-scroll .cm-url { + color: #5c7cfa; +} +.cherry.theme__blue .cherry-editor .CodeMirror .CodeMirror-selected { + background-color: #d0bfff; +} +.cherry.theme__blue .cherry-sidebar { + box-shadow: 0 0 10px #bac8ff; +} +.cherry.theme__blue .cherry-previewer { + background-color: #f3f0ff; +} +.cherry.theme__blue .cherry-previewer .cherry-mobile-previewer-content { + background-color: #f3f0ff; +} +.cherry.theme__blue .cherry-previewer-table-content-hander .cherry-previewer-table-content-hander__input textarea { + background-color: #f3f0ff; + color: #364fc7; + outline-color: #4263eb; +} + +/** 预览区域样式 */ +.cherry-markdown.theme__blue { + color: #364fc7; + background-color: #f3f0ff; + /** 行内代码 */ + /** + * 代码块 + */ + /** + * 表格 + */ + /** 可以理解为上下结构的音标,下部是文字,上部是对应的拼音 */ + /** 脚注 */ + /** 行间公式 */ + /** 段落公式 */ + /** 目录 */ +} +.cherry-markdown.theme__blue h1, .cherry-markdown.theme__blue h2, .cherry-markdown.theme__blue h3, .cherry-markdown.theme__blue h4, .cherry-markdown.theme__blue h5 { + color: #4263eb; + text-align: center; + border-bottom: 1px dashed #3b5bdb; + padding-bottom: 15px; + margin-bottom: 25px; +} +.cherry-markdown.theme__blue h1, .cherry-markdown.theme__blue h2, .cherry-markdown.theme__blue h3, .cherry-markdown.theme__blue h4, .cherry-markdown.theme__blue h5, .cherry-markdown.theme__blue h6 { + /** 标题前面的锚点或序号 */ +} +.cherry-markdown.theme__blue ul { + /** checklist 模式,未勾选时 */ + /** checklist 模式,勾选时 */ +} +.cherry-markdown.theme__blue ul.cherry-list__upper-roman { + list-style: upper-roman; +} +.cherry-markdown.theme__blue ul.cherry-list__lower-greek { + list-style: lower-greek; +} +.cherry-markdown.theme__blue ul.cherry-list__cjk-ideographic { + list-style: cjk-ideographic; +} +.cherry-markdown.theme__blue ul.cherry-list__circle { + list-style: circle; +} +.cherry-markdown.theme__blue ul.cherry-list__square { + list-style: square; +} +.cherry-markdown.theme__blue blockquote { + color: #364fc7; + background-color: #e5dbff; + border-color: #3b5bdb; +} +.cherry-markdown.theme__blue a { + text-decoration: none; + color: #5c7cfa; +} +.cherry-markdown.theme__blue a:hover { + text-decoration: underline; + color: #4263eb; +} +.cherry-markdown.theme__blue hr { + border-color: #3b5bdb; +} +.cherry-markdown.theme__blue p code, .cherry-markdown.theme__blue li code { + background-color: #e5dbff; + color: #5c7cfa; + border: 1px solid #3b5bdb; +} +.cherry-markdown.theme__blue table, .cherry-markdown.theme__blue .cherry-table { + color: #364fc7; +} +.cherry-markdown.theme__blue table th, .cherry-markdown.theme__blue .cherry-table th { + background-color: #e5dbff; +} +.cherry-markdown.theme__blue table tr, .cherry-markdown.theme__blue table th, .cherry-markdown.theme__blue table td, .cherry-markdown.theme__blue .cherry-table tr, .cherry-markdown.theme__blue .cherry-table th, .cherry-markdown.theme__blue .cherry-table td { + border-color: #3b5bdb; +} +.cherry-markdown.theme__blue ruby { + /** 上部的拼音 */ +} +.cherry-markdown.theme__blue .footnote { + border-color: #3b5bdb; +} +.cherry-markdown.theme__blue .footnote .footnote-title { + background-color: #e5dbff; +} +.cherry-markdown.theme__blue .footnote .one-footnote { + color: #364fc7; + border-color: #3b5bdb; +} +.cherry-markdown.theme__blue .footnote .one-footnote a.footnote-ref { + padding: 5px; +} +.cherry-markdown.theme__blue .toc { + border-bottom: 1px solid #3b5bdb; + padding-bottom: 15px; + margin-bottom: 30px; +} +.cherry-markdown.theme__blue .toc .toc-title { + text-align: center; + padding-bottom: 15px; + margin-top: 30px; + margin-bottom: 15px; + border-bottom: 1px solid #3b5bdb; +} +.cherry-markdown.theme__blue .toc .toc-li { + border: none; +} +.cherry-markdown.theme__blue .toc .toc-li a { + color: #364fc7; +} +.cherry-markdown.theme__blue .toc .toc-li a:hover { + color: #4263eb; +} + +/* BASICS */ +.CodeMirror { + /* Set height, width, borders, and global font properties here */ + font-family: monospace; + height: 300px; + color: black; + direction: ltr; +} + +/* PADDING */ +.CodeMirror-lines { + padding: 4px 0; /* Vertical padding around content */ +} + +.CodeMirror pre.CodeMirror-line, +.CodeMirror pre.CodeMirror-line-like { + padding: 0 4px; /* Horizontal padding of content */ +} + +.CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler { + background-color: white; /* The little square between H and V scrollbars */ +} + +/* GUTTER */ +.CodeMirror-gutters { + border-right: 1px solid #ddd; background-color: #f7f7f7; white-space: nowrap; } @@ -4608,19 +4308,16 @@ div[data-type=codeBlock] .token.inserted { background-color: transparent; } } - @-webkit-keyframes blink { 50% { background-color: transparent; } } - @keyframes blink { 50% { background-color: transparent; } } - /* Can style cursor different in overwrite (non-insert) mode */ .cm-tab { display: inline-block; @@ -4660,8 +4357,7 @@ div[data-type=codeBlock] .token.inserted { color: #292; } -.cm-header, -.cm-strong { +.cm-header, .cm-strong { font-weight: bold; } @@ -4697,8 +4393,7 @@ div[data-type=codeBlock] .token.inserted { color: #05a; } -.cm-s-default .cm-variable-3, -.cm-s-default .cm-type { +.cm-s-default .cm-variable-3, .cm-s-default .cm-type { color: #085; } @@ -4785,16 +4480,14 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket { } .CodeMirror-scroll { - overflow: scroll !important; - /* Things will break if this is overridden */ + overflow: scroll !important; /* Things will break if this is overridden */ /* 50px is the magic margin used to hide the element's real scrollbars */ /* See overflow: hidden in .CodeMirror */ margin-bottom: -50px; margin-right: -50px; padding-bottom: 50px; height: 100%; - outline: none; - /* Prevent dragging from highlighting the element */ + outline: none; /* Prevent dragging from highlighting the element */ position: relative; } @@ -4806,10 +4499,7 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket { /* The fake, visible scrollbars. Used to force redraw during scrolling before actual scrolling happens, thus preventing shaking and flickering artifacts. */ -.CodeMirror-vscrollbar, -.CodeMirror-hscrollbar, -.CodeMirror-scrollbar-filler, -.CodeMirror-gutter-filler { +.CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler { position: absolute; z-index: 6; display: none; @@ -4886,8 +4576,7 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket { .CodeMirror-lines { cursor: text; - min-height: 1px; - /* prevents collapsing before first draw */ + min-height: 1px; /* prevents collapsing before first draw */ } .CodeMirror pre.CodeMirror-line, @@ -4932,8 +4621,7 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket { .CodeMirror-linewidget { position: relative; z-index: 2; - padding: 0.1px; - /* Force widget margins to stay inside of the container */ + padding: 0.1px; /* Force widget margins to stay inside of the container */ } .CodeMirror-rtl pre { @@ -4997,15 +4685,11 @@ div.CodeMirror-dragcursors { cursor: crosshair; } -.CodeMirror-line::selection, -.CodeMirror-line>span::selection, -.CodeMirror-line>span>span::selection { +.CodeMirror-line::selection, .CodeMirror-line > span::selection, .CodeMirror-line > span > span::selection { background: #d7d4f0; } -.CodeMirror-line::-moz-selection, -.CodeMirror-line>span::-moz-selection, -.CodeMirror-line>span>span::-moz-selection { +.CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; } @@ -5020,13 +4704,11 @@ div.CodeMirror-dragcursors { } @media print { - /* Hide the cursor when printing */ .CodeMirror div.CodeMirror-cursors { visibility: hidden; } } - /* See issue #2901 */ .cm-tab-wrap-hack:after { content: ""; @@ -5035,224 +4717,4 @@ div.CodeMirror-dragcursors { /* Help users use markselection to safely style text background */ span.CodeMirror-selectedtext { background: none; -} - -iframe.cherry-dialog-iframe { - width: 100%; - height: 100%; -} - -.manual-article.cherry { - height: auto !important; -} - -.cherry img { - max-width: 100%; -} - -.tooltipped { - position: relative -} - -.tooltipped:after { - position: absolute; - z-index: 1000000; - display: none; - padding: 5px 8px; - font: normal normal 11px/1.5 Helvetica, arial, nimbussansl, liberationsans, freesans, clean, sans-serif, "Segoe UI Emoji", "Segoe UI Symbol"; - color: #fff; - text-align: center; - text-decoration: none; - text-shadow: none; - text-transform: none; - letter-spacing: normal; - word-wrap: break-word; - white-space: pre; - pointer-events: none; - content: attr(aria-label); - background: rgba(0, 0, 0, .8); - border-radius: 3px; - -webkit-font-smoothing: subpixel-antialiased -} - -.tooltipped:before { - position: absolute; - z-index: 1000001; - display: none; - width: 0; - height: 0; - color: rgba(0, 0, 0, .8); - pointer-events: none; - content: ""; - border: 5px solid transparent -} - -.tooltipped:hover:before, -.tooltipped:hover:after, -.tooltipped:active:before, -.tooltipped:active:after, -.tooltipped:focus:before, -.tooltipped:focus:after { - display: inline-block; - text-decoration: none -} - -.tooltipped-multiline:hover:after, -.tooltipped-multiline:active:after, -.tooltipped-multiline:focus:after { - display: table-cell -} - -.tooltipped-s:after, -.tooltipped-se:after, -.tooltipped-sw:after { - top: 100%; - right: 50%; - margin-top: 5px -} - -.tooltipped-s:before, -.tooltipped-se:before, -.tooltipped-sw:before { - top: auto; - right: 50%; - bottom: -5px; - margin-right: -5px; - border-bottom-color: rgba(0, 0, 0, .8) -} - -.tooltipped-se:after { - right: auto; - left: 50%; - margin-left: -15px -} - -.tooltipped-sw:after { - margin-right: -15px -} - -.tooltipped-n:after, -.tooltipped-ne:after, -.tooltipped-nw:after { - right: 50%; - bottom: 100%; - margin-bottom: 5px -} - -.tooltipped-n:before, -.tooltipped-ne:before, -.tooltipped-nw:before { - top: -5px; - right: 50%; - bottom: auto; - margin-right: -5px; - border-top-color: rgba(0, 0, 0, .8) -} - -.tooltipped-ne:after { - right: auto; - left: 50%; - margin-left: -15px -} - -.tooltipped-nw:after { - margin-right: -15px -} - -.tooltipped-s:after, -.tooltipped-n:after { - -webkit-transform: translateX(50%); - -ms-transform: translateX(50%); - transform: translateX(50%) -} - -.tooltipped-w:after { - right: 100%; - bottom: 50%; - margin-right: 5px; - -webkit-transform: translateY(50%); - -ms-transform: translateY(50%); - transform: translateY(50%) -} - -.tooltipped-w:before { - top: 50%; - bottom: 50%; - left: -5px; - margin-top: -5px; - border-left-color: rgba(0, 0, 0, .8) -} - -.tooltipped-e:after { - bottom: 50%; - left: 100%; - margin-left: 5px; - -webkit-transform: translateY(50%); - -ms-transform: translateY(50%); - transform: translateY(50%) -} - -.tooltipped-e:before { - top: 50%; - right: -5px; - bottom: 50%; - margin-top: -5px; - border-right-color: rgba(0, 0, 0, .8) -} - -.tooltipped-multiline:after { - width: -webkit-max-content; - width: -moz-max-content; - width: max-content; - max-width: 250px; - word-break: break-word; - word-wrap: normal; - white-space: pre-line; - border-collapse: separate -} - -.tooltipped-multiline.tooltipped-s:after, -.tooltipped-multiline.tooltipped-n:after { - right: auto; - left: 50%; - -webkit-transform: translateX(-50%); - -ms-transform: translateX(-50%); - transform: translateX(-50%) -} - -.tooltipped-multiline.tooltipped-w:after, -.tooltipped-multiline.tooltipped-e:after { - right: 100% -} - -/*styles related to snippet copy to clipboard, borrowed from https://clipboardjs.com/assets/styles/main.css*/ -.clippy { - margin-top: -3px; - position: relative; - top: 3px -} - -.codebtn[disabled] .clippy { - opacity: .3 -} - -.snippet { - position: relative; - overflow: visible -} - -.snippet .codebtn { - -webkit-transition: opacity .3s ease-in-out; - -o-transition: opacity .3s ease-in-out; - transition: opacity .3s ease-in-out; - opacity: 0; - padding: 6px 6px; - position: absolute; - right: 6px; - top: 13px -} - -.snippet:hover .codebtn, -.snippet .codebtn:focus { - opacity: 1 } \ No newline at end of file diff --git a/static/cherry/cherry-markdown.js b/static/cherry/cherry-markdown.js index 25c5a089..bb04746c 100644 --- a/static/cherry/cherry-markdown.js +++ b/static/cherry/cherry-markdown.js @@ -1,13 +1,12 @@ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : - typeof define === 'function' && define.amd ? define(['exports'], factory) : - (global = global || self, factory(global.Cherry = {})); -}(this, (function (exports) { - 'use strict'; + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (global = global || self, factory(global.Cherry = {})); +}(this, (function (exports) { 'use strict'; var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; - function unwrapExports(x) { + function unwrapExports (x) { return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; } @@ -15,38 +14,38 @@ return module = { exports: {} }, fn(module, module.exports), module.exports; } - function getCjsExportFromNamespace(n) { + function getCjsExportFromNamespace (n) { return n && n['default'] || n; } var check = function (it) { - return it && it.Math == Math && it; + return it && it.Math == Math && it; }; // https://github.com/zloirock/core-js/issues/86#issuecomment-115759028 var global_1 = - // eslint-disable-next-line es-x/no-global-this -- safe - check(typeof globalThis == 'object' && globalThis) || - check(typeof window == 'object' && window) || - // eslint-disable-next-line no-restricted-globals -- safe - check(typeof self == 'object' && self) || - check(typeof commonjsGlobal == 'object' && commonjsGlobal) || - // eslint-disable-next-line no-new-func -- fallback - (function () { return this; })() || Function('return this')(); + // eslint-disable-next-line es-x/no-global-this -- safe + check(typeof globalThis == 'object' && globalThis) || + check(typeof window == 'object' && window) || + // eslint-disable-next-line no-restricted-globals -- safe + check(typeof self == 'object' && self) || + check(typeof commonjsGlobal == 'object' && commonjsGlobal) || + // eslint-disable-next-line no-new-func -- fallback + (function () { return this; })() || Function('return this')(); var fails = function (exec) { - try { - return !!exec(); - } catch (error) { - return true; - } + try { + return !!exec(); + } catch (error) { + return true; + } }; var functionBindNative = !fails(function () { - // eslint-disable-next-line es-x/no-function-prototype-bind -- safe - var test = (function () { /* empty */ }).bind(); - // eslint-disable-next-line no-prototype-builtins -- safe - return typeof test != 'function' || test.hasOwnProperty('prototype'); + // eslint-disable-next-line es-x/no-function-prototype-bind -- safe + var test = (function () { /* empty */ }).bind(); + // eslint-disable-next-line no-prototype-builtins -- safe + return typeof test != 'function' || test.hasOwnProperty('prototype'); }); var FunctionPrototype = Function.prototype; @@ -55,7 +54,7 @@ // eslint-disable-next-line es-x/no-reflect -- safe var functionApply = typeof Reflect == 'object' && Reflect.apply || (functionBindNative ? call.bind(apply) : function () { - return call.apply(apply, arguments); + return call.apply(apply, arguments); }); var FunctionPrototype$1 = Function.prototype; @@ -64,29 +63,29 @@ var uncurryThis = functionBindNative && bind.bind(call$1, call$1); var functionUncurryThis = functionBindNative ? function (fn) { - return fn && uncurryThis(fn); + return fn && uncurryThis(fn); } : function (fn) { - return fn && function () { - return call$1.apply(fn, arguments); - }; + return fn && function () { + return call$1.apply(fn, arguments); + }; }; // `IsCallable` abstract operation // https://tc39.es/ecma262/#sec-iscallable var isCallable = function (argument) { - return typeof argument == 'function'; + return typeof argument == 'function'; }; // Detect IE8's incomplete defineProperty implementation var descriptors = !fails(function () { - // eslint-disable-next-line es-x/no-object-defineproperty -- required for testing - return Object.defineProperty({}, 1, { get: function () { return 7; } })[1] != 7; + // eslint-disable-next-line es-x/no-object-defineproperty -- required for testing + return Object.defineProperty({}, 1, { get: function () { return 7; } })[1] != 7; }); var call$2 = Function.prototype.call; var functionCall = functionBindNative ? call$2.bind(call$2) : function () { - return call$2.apply(call$2, arguments); + return call$2.apply(call$2, arguments); }; var $propertyIsEnumerable = {}.propertyIsEnumerable; @@ -99,8 +98,8 @@ // `Object.prototype.propertyIsEnumerable` method implementation // https://tc39.es/ecma262/#sec-object.prototype.propertyisenumerable var f = NASHORN_BUG ? function propertyIsEnumerable(V) { - var descriptor = getOwnPropertyDescriptor(this, V); - return !!descriptor && descriptor.enumerable; + var descriptor = getOwnPropertyDescriptor(this, V); + return !!descriptor && descriptor.enumerable; } : $propertyIsEnumerable; var objectPropertyIsEnumerable = { @@ -108,19 +107,19 @@ }; var createPropertyDescriptor = function (bitmap, value) { - return { - enumerable: !(bitmap & 1), - configurable: !(bitmap & 2), - writable: !(bitmap & 4), - value: value - }; + return { + enumerable: !(bitmap & 1), + configurable: !(bitmap & 2), + writable: !(bitmap & 4), + value: value + }; }; var toString = functionUncurryThis({}.toString); var stringSlice = functionUncurryThis(''.slice); var classofRaw = function (it) { - return stringSlice(toString(it), 8, -1); + return stringSlice(toString(it), 8, -1); }; var Object$1 = global_1.Object; @@ -128,11 +127,11 @@ // fallback for non-array-like ES3 and non-enumerable old V8 strings var indexedObject = fails(function () { - // throws an error in rhino, see https://github.com/mozilla/rhino/issues/346 - // eslint-disable-next-line no-prototype-builtins -- safe - return !Object$1('z').propertyIsEnumerable(0); + // throws an error in rhino, see https://github.com/mozilla/rhino/issues/346 + // eslint-disable-next-line no-prototype-builtins -- safe + return !Object$1('z').propertyIsEnumerable(0); }) ? function (it) { - return classofRaw(it) == 'String' ? split(it, '') : Object$1(it); + return classofRaw(it) == 'String' ? split(it, '') : Object$1(it); } : Object$1; var TypeError$1 = global_1.TypeError; @@ -140,8 +139,8 @@ // `RequireObjectCoercible` abstract operation // https://tc39.es/ecma262/#sec-requireobjectcoercible var requireObjectCoercible = function (it) { - if (it == undefined) throw TypeError$1("Can't call method on " + it); - return it; + if (it == undefined) throw TypeError$1("Can't call method on " + it); + return it; }; // toObject with fallback for non-array-like ES3 strings @@ -149,22 +148,22 @@ var toIndexedObject = function (it) { - return indexedObject(requireObjectCoercible(it)); + return indexedObject(requireObjectCoercible(it)); }; var isObject = function (it) { - return typeof it == 'object' ? it !== null : isCallable(it); + return typeof it == 'object' ? it !== null : isCallable(it); }; var path = {}; var aFunction = function (variable) { - return isCallable(variable) ? variable : undefined; + return isCallable(variable) ? variable : undefined; }; var getBuiltIn = function (namespace, method) { - return arguments.length < 2 ? aFunction(path[namespace]) || aFunction(global_1[namespace]) - : path[namespace] && path[namespace][method] || global_1[namespace] && global_1[namespace][method]; + return arguments.length < 2 ? aFunction(path[namespace]) || aFunction(global_1[namespace]) + : path[namespace] && path[namespace][method] || global_1[namespace] && global_1[namespace][method]; }; var objectIsPrototypeOf = functionUncurryThis({}.isPrototypeOf); @@ -178,20 +177,20 @@ var match, version; if (v8) { - match = v8.split('.'); - // in old Chrome, versions of V8 isn't V8 = Chrome / 10 - // but their correct versions are not interesting for us - version = match[0] > 0 && match[0] < 4 ? 1 : +(match[0] + match[1]); + match = v8.split('.'); + // in old Chrome, versions of V8 isn't V8 = Chrome / 10 + // but their correct versions are not interesting for us + version = match[0] > 0 && match[0] < 4 ? 1 : +(match[0] + match[1]); } // BrowserFS NodeJS `process` polyfill incorrectly set `.v8` to `0.0` // so check `userAgent` even if `.v8` exists, but 0 if (!version && engineUserAgent) { - match = engineUserAgent.match(/Edge\/(\d+)/); - if (!match || match[1] >= 74) { - match = engineUserAgent.match(/Chrome\/(\d+)/); - if (match) version = +match[1]; - } + match = engineUserAgent.match(/Edge\/(\d+)/); + if (!match || match[1] >= 74) { + match = engineUserAgent.match(/Chrome\/(\d+)/); + if (match) version = +match[1]; + } } var engineV8Version = version; @@ -202,53 +201,53 @@ // eslint-disable-next-line es-x/no-object-getownpropertysymbols -- required for testing var nativeSymbol = !!Object.getOwnPropertySymbols && !fails(function () { - var symbol = Symbol(); - // Chrome 38 Symbol has incorrect toString conversion - // `get-own-property-symbols` polyfill symbols converted to object are not Symbol instances - return !String(symbol) || !(Object(symbol) instanceof Symbol) || - // Chrome 38-40 symbols are not inherited from DOM collections prototypes to instances - !Symbol.sham && engineV8Version && engineV8Version < 41; + var symbol = Symbol(); + // Chrome 38 Symbol has incorrect toString conversion + // `get-own-property-symbols` polyfill symbols converted to object are not Symbol instances + return !String(symbol) || !(Object(symbol) instanceof Symbol) || + // Chrome 38-40 symbols are not inherited from DOM collections prototypes to instances + !Symbol.sham && engineV8Version && engineV8Version < 41; }); /* eslint-disable es-x/no-symbol -- required for testing */ var useSymbolAsUid = nativeSymbol - && !Symbol.sham - && typeof Symbol.iterator == 'symbol'; + && !Symbol.sham + && typeof Symbol.iterator == 'symbol'; var Object$2 = global_1.Object; var isSymbol = useSymbolAsUid ? function (it) { - return typeof it == 'symbol'; + return typeof it == 'symbol'; } : function (it) { - var $Symbol = getBuiltIn('Symbol'); - return isCallable($Symbol) && objectIsPrototypeOf($Symbol.prototype, Object$2(it)); + var $Symbol = getBuiltIn('Symbol'); + return isCallable($Symbol) && objectIsPrototypeOf($Symbol.prototype, Object$2(it)); }; var String$1 = global_1.String; var tryToString = function (argument) { - try { - return String$1(argument); - } catch (error) { - return 'Object'; - } + try { + return String$1(argument); + } catch (error) { + return 'Object'; + } }; var TypeError$2 = global_1.TypeError; // `Assert: IsCallable(argument) is true` var aCallable = function (argument) { - if (isCallable(argument)) return argument; - throw TypeError$2(tryToString(argument) + ' is not a function'); + if (isCallable(argument)) return argument; + throw TypeError$2(tryToString(argument) + ' is not a function'); }; // `GetMethod` abstract operation // https://tc39.es/ecma262/#sec-getmethod var getMethod = function (V, P) { - var func = V[P]; - return func == null ? undefined : aCallable(func); + var func = V[P]; + return func == null ? undefined : aCallable(func); }; var TypeError$3 = global_1.TypeError; @@ -256,11 +255,11 @@ // `OrdinaryToPrimitive` abstract operation // https://tc39.es/ecma262/#sec-ordinarytoprimitive var ordinaryToPrimitive = function (input, pref) { - var fn, val; - if (pref === 'string' && isCallable(fn = input.toString) && !isObject(val = functionCall(fn, input))) return val; - if (isCallable(fn = input.valueOf) && !isObject(val = functionCall(fn, input))) return val; - if (pref !== 'string' && isCallable(fn = input.toString) && !isObject(val = functionCall(fn, input))) return val; - throw TypeError$3("Can't convert object to primitive value"); + var fn, val; + if (pref === 'string' && isCallable(fn = input.toString) && !isObject(val = functionCall(fn, input))) return val; + if (isCallable(fn = input.valueOf) && !isObject(val = functionCall(fn, input))) return val; + if (pref !== 'string' && isCallable(fn = input.toString) && !isObject(val = functionCall(fn, input))) return val; + throw TypeError$3("Can't convert object to primitive value"); }; var isPure = true; @@ -269,11 +268,11 @@ var defineProperty = Object.defineProperty; var defineGlobalProperty = function (key, value) { - try { - defineProperty(global_1, key, { value: value, configurable: true, writable: true }); - } catch (error) { - global_1[key] = value; - } return value; + try { + defineProperty(global_1, key, { value: value, configurable: true, writable: true }); + } catch (error) { + global_1[key] = value; + } return value; }; var SHARED = '__core-js_shared__'; @@ -282,15 +281,15 @@ var sharedStore = store; var shared = createCommonjsModule(function (module) { - (module.exports = function (key, value) { - return sharedStore[key] || (sharedStore[key] = value !== undefined ? value : {}); - })('versions', []).push({ - version: '3.22.6', - mode: 'pure', - copyright: '© 2014-2022 Denis Pushkarev (zloirock.ru)', - license: 'https://github.com/zloirock/core-js/blob/v3.22.6/LICENSE', - source: 'https://github.com/zloirock/core-js' - }); + (module.exports = function (key, value) { + return sharedStore[key] || (sharedStore[key] = value !== undefined ? value : {}); + })('versions', []).push({ + version: '3.22.6', + mode: 'pure' , + copyright: '© 2014-2022 Denis Pushkarev (zloirock.ru)', + license: 'https://github.com/zloirock/core-js/blob/v3.22.6/LICENSE', + source: 'https://github.com/zloirock/core-js' + }); }); var Object$3 = global_1.Object; @@ -298,7 +297,7 @@ // `ToObject` abstract operation // https://tc39.es/ecma262/#sec-toobject var toObject = function (argument) { - return Object$3(requireObjectCoercible(argument)); + return Object$3(requireObjectCoercible(argument)); }; var hasOwnProperty = functionUncurryThis({}.hasOwnProperty); @@ -307,7 +306,7 @@ // https://tc39.es/ecma262/#sec-hasownproperty // eslint-disable-next-line es-x/no-object-hasown -- safe var hasOwnProperty_1 = Object.hasOwn || function hasOwn(it, key) { - return hasOwnProperty(toObject(it), key); + return hasOwnProperty(toObject(it), key); }; var id = 0; @@ -315,7 +314,7 @@ var toString$1 = functionUncurryThis(1.0.toString); var uid = function (key) { - return 'Symbol(' + (key === undefined ? '' : key) + ')_' + toString$1(++id + postfix, 36); + return 'Symbol(' + (key === undefined ? '' : key) + ')_' + toString$1(++id + postfix, 36); }; var WellKnownSymbolsStore = shared('wks'); @@ -324,16 +323,16 @@ var createWellKnownSymbol = useSymbolAsUid ? Symbol$1 : Symbol$1 && Symbol$1.withoutSetter || uid; var wellKnownSymbol = function (name) { - if (!hasOwnProperty_1(WellKnownSymbolsStore, name) || !(nativeSymbol || typeof WellKnownSymbolsStore[name] == 'string')) { - var description = 'Symbol.' + name; - if (nativeSymbol && hasOwnProperty_1(Symbol$1, name)) { - WellKnownSymbolsStore[name] = Symbol$1[name]; - } else if (useSymbolAsUid && symbolFor) { - WellKnownSymbolsStore[name] = symbolFor(description); - } else { - WellKnownSymbolsStore[name] = createWellKnownSymbol(description); - } - } return WellKnownSymbolsStore[name]; + if (!hasOwnProperty_1(WellKnownSymbolsStore, name) || !(nativeSymbol || typeof WellKnownSymbolsStore[name] == 'string')) { + var description = 'Symbol.' + name; + if (nativeSymbol && hasOwnProperty_1(Symbol$1, name)) { + WellKnownSymbolsStore[name] = Symbol$1[name]; + } else if (useSymbolAsUid && symbolFor) { + WellKnownSymbolsStore[name] = symbolFor(description); + } else { + WellKnownSymbolsStore[name] = createWellKnownSymbol(description); + } + } return WellKnownSymbolsStore[name]; }; var TypeError$4 = global_1.TypeError; @@ -342,24 +341,24 @@ // `ToPrimitive` abstract operation // https://tc39.es/ecma262/#sec-toprimitive var toPrimitive = function (input, pref) { - if (!isObject(input) || isSymbol(input)) return input; - var exoticToPrim = getMethod(input, TO_PRIMITIVE); - var result; - if (exoticToPrim) { - if (pref === undefined) pref = 'default'; - result = functionCall(exoticToPrim, input, pref); - if (!isObject(result) || isSymbol(result)) return result; - throw TypeError$4("Can't convert object to primitive value"); - } - if (pref === undefined) pref = 'number'; - return ordinaryToPrimitive(input, pref); + if (!isObject(input) || isSymbol(input)) return input; + var exoticToPrim = getMethod(input, TO_PRIMITIVE); + var result; + if (exoticToPrim) { + if (pref === undefined) pref = 'default'; + result = functionCall(exoticToPrim, input, pref); + if (!isObject(result) || isSymbol(result)) return result; + throw TypeError$4("Can't convert object to primitive value"); + } + if (pref === undefined) pref = 'number'; + return ordinaryToPrimitive(input, pref); }; // `ToPropertyKey` abstract operation // https://tc39.es/ecma262/#sec-topropertykey var toPropertyKey = function (argument) { - var key = toPrimitive(argument, 'string'); - return isSymbol(key) ? key : key + ''; + var key = toPrimitive(argument, 'string'); + return isSymbol(key) ? key : key + ''; }; var document$1 = global_1.document; @@ -367,15 +366,15 @@ var EXISTS = isObject(document$1) && isObject(document$1.createElement); var documentCreateElement = function (it) { - return EXISTS ? document$1.createElement(it) : {}; + return EXISTS ? document$1.createElement(it) : {}; }; // Thanks to IE8 for its funny defineProperty var ie8DomDefine = !descriptors && !fails(function () { - // eslint-disable-next-line es-x/no-object-defineproperty -- required for testing - return Object.defineProperty(documentCreateElement('div'), 'a', { - get: function () { return 7; } - }).a != 7; + // eslint-disable-next-line es-x/no-object-defineproperty -- required for testing + return Object.defineProperty(documentCreateElement('div'), 'a', { + get: function () { return 7; } + }).a != 7; }); // eslint-disable-next-line es-x/no-object-getownpropertydescriptor -- safe @@ -384,12 +383,12 @@ // `Object.getOwnPropertyDescriptor` method // https://tc39.es/ecma262/#sec-object.getownpropertydescriptor var f$1 = descriptors ? $getOwnPropertyDescriptor : function getOwnPropertyDescriptor(O, P) { - O = toIndexedObject(O); - P = toPropertyKey(P); - if (ie8DomDefine) try { - return $getOwnPropertyDescriptor(O, P); - } catch (error) { /* empty */ } - if (hasOwnProperty_1(O, P)) return createPropertyDescriptor(!functionCall(objectPropertyIsEnumerable.f, O, P), O[P]); + O = toIndexedObject(O); + P = toPropertyKey(P); + if (ie8DomDefine) try { + return $getOwnPropertyDescriptor(O, P); + } catch (error) { /* empty */ } + if (hasOwnProperty_1(O, P)) return createPropertyDescriptor(!functionCall(objectPropertyIsEnumerable.f, O, P), O[P]); }; var objectGetOwnPropertyDescriptor = { @@ -399,15 +398,15 @@ var replacement = /#|\.prototype\./; var isForced = function (feature, detection) { - var value = data[normalize(feature)]; - return value == POLYFILL ? true - : value == NATIVE ? false - : isCallable(detection) ? fails(detection) - : !!detection; + var value = data[normalize(feature)]; + return value == POLYFILL ? true + : value == NATIVE ? false + : isCallable(detection) ? fails(detection) + : !!detection; }; var normalize = isForced.normalize = function (string) { - return String(string).replace(replacement, '.').toLowerCase(); + return String(string).replace(replacement, '.').toLowerCase(); }; var data = isForced.data = {}; @@ -420,20 +419,20 @@ // optional / simple context binding var functionBindContext = function (fn, that) { - aCallable(fn); - return that === undefined ? fn : functionBindNative ? bind$1(fn, that) : function (/* ...args */) { - return fn.apply(that, arguments); - }; + aCallable(fn); + return that === undefined ? fn : functionBindNative ? bind$1(fn, that) : function (/* ...args */) { + return fn.apply(that, arguments); + }; }; // V8 ~ Chrome 36- // https://bugs.chromium.org/p/v8/issues/detail?id=3334 var v8PrototypeDefineBug = descriptors && fails(function () { - // eslint-disable-next-line es-x/no-object-defineproperty -- required for testing - return Object.defineProperty(function () { /* empty */ }, 'prototype', { - value: 42, - writable: false - }).prototype != 42; + // eslint-disable-next-line es-x/no-object-defineproperty -- required for testing + return Object.defineProperty(function () { /* empty */ }, 'prototype', { + value: 42, + writable: false + }).prototype != 42; }); var String$2 = global_1.String; @@ -441,8 +440,8 @@ // `Assert: Type(argument) is Object` var anObject = function (argument) { - if (isObject(argument)) return argument; - throw TypeError$5(String$2(argument) + ' is not an object'); + if (isObject(argument)) return argument; + throw TypeError$5(String$2(argument) + ' is not an object'); }; var TypeError$6 = global_1.TypeError; @@ -457,30 +456,30 @@ // `Object.defineProperty` method // https://tc39.es/ecma262/#sec-object.defineproperty var f$2 = descriptors ? v8PrototypeDefineBug ? function defineProperty(O, P, Attributes) { - anObject(O); - P = toPropertyKey(P); - anObject(Attributes); - if (typeof O === 'function' && P === 'prototype' && 'value' in Attributes && WRITABLE in Attributes && !Attributes[WRITABLE]) { - var current = $getOwnPropertyDescriptor$1(O, P); - if (current && current[WRITABLE]) { - O[P] = Attributes.value; - Attributes = { - configurable: CONFIGURABLE in Attributes ? Attributes[CONFIGURABLE] : current[CONFIGURABLE], - enumerable: ENUMERABLE in Attributes ? Attributes[ENUMERABLE] : current[ENUMERABLE], - writable: false - }; - } - } return $defineProperty(O, P, Attributes); + anObject(O); + P = toPropertyKey(P); + anObject(Attributes); + if (typeof O === 'function' && P === 'prototype' && 'value' in Attributes && WRITABLE in Attributes && !Attributes[WRITABLE]) { + var current = $getOwnPropertyDescriptor$1(O, P); + if (current && current[WRITABLE]) { + O[P] = Attributes.value; + Attributes = { + configurable: CONFIGURABLE in Attributes ? Attributes[CONFIGURABLE] : current[CONFIGURABLE], + enumerable: ENUMERABLE in Attributes ? Attributes[ENUMERABLE] : current[ENUMERABLE], + writable: false + }; + } + } return $defineProperty(O, P, Attributes); } : $defineProperty : function defineProperty(O, P, Attributes) { - anObject(O); - P = toPropertyKey(P); - anObject(Attributes); - if (ie8DomDefine) try { - return $defineProperty(O, P, Attributes); - } catch (error) { /* empty */ } - if ('get' in Attributes || 'set' in Attributes) throw TypeError$6('Accessors not supported'); - if ('value' in Attributes) O[P] = Attributes.value; - return O; + anObject(O); + P = toPropertyKey(P); + anObject(Attributes); + if (ie8DomDefine) try { + return $defineProperty(O, P, Attributes); + } catch (error) { /* empty */ } + if ('get' in Attributes || 'set' in Attributes) throw TypeError$6('Accessors not supported'); + if ('value' in Attributes) O[P] = Attributes.value; + return O; }; var objectDefineProperty = { @@ -488,10 +487,10 @@ }; var createNonEnumerableProperty = descriptors ? function (object, key, value) { - return objectDefineProperty.f(object, key, createPropertyDescriptor(1, value)); + return objectDefineProperty.f(object, key, createPropertyDescriptor(1, value)); } : function (object, key, value) { - object[key] = value; - return object; + object[key] = value; + return object; }; var getOwnPropertyDescriptor$1 = objectGetOwnPropertyDescriptor.f; @@ -502,17 +501,17 @@ var wrapConstructor = function (NativeConstructor) { - var Wrapper = function (a, b, c) { - if (this instanceof Wrapper) { - switch (arguments.length) { - case 0: return new NativeConstructor(); - case 1: return new NativeConstructor(a); - case 2: return new NativeConstructor(a, b); - } return new NativeConstructor(a, b, c); - } return functionApply(NativeConstructor, this, arguments); - }; - Wrapper.prototype = NativeConstructor.prototype; - return Wrapper; + var Wrapper = function (a, b, c) { + if (this instanceof Wrapper) { + switch (arguments.length) { + case 0: return new NativeConstructor(); + case 1: return new NativeConstructor(a); + case 2: return new NativeConstructor(a, b); + } return new NativeConstructor(a, b, c); + } return functionApply(NativeConstructor, this, arguments); + }; + Wrapper.prototype = NativeConstructor.prototype; + return Wrapper; }; /* @@ -531,65 +530,65 @@ options.name - the .name of the function if it does not match the key */ var _export = function (options, source) { - var TARGET = options.target; - var GLOBAL = options.global; - var STATIC = options.stat; - var PROTO = options.proto; - - var nativeSource = GLOBAL ? global_1 : STATIC ? global_1[TARGET] : (global_1[TARGET] || {}).prototype; - - var target = GLOBAL ? path : path[TARGET] || createNonEnumerableProperty(path, TARGET, {})[TARGET]; - var targetPrototype = target.prototype; - - var FORCED, USE_NATIVE, VIRTUAL_PROTOTYPE; - var key, sourceProperty, targetProperty, nativeProperty, resultProperty, descriptor; - - for (key in source) { - FORCED = isForced_1(GLOBAL ? key : TARGET + (STATIC ? '.' : '#') + key, options.forced); - // contains in native - USE_NATIVE = !FORCED && nativeSource && hasOwnProperty_1(nativeSource, key); - - targetProperty = target[key]; - - if (USE_NATIVE) if (options.dontCallGetSet) { - descriptor = getOwnPropertyDescriptor$1(nativeSource, key); - nativeProperty = descriptor && descriptor.value; - } else nativeProperty = nativeSource[key]; - - // export native or implementation - sourceProperty = (USE_NATIVE && nativeProperty) ? nativeProperty : source[key]; - - if (USE_NATIVE && typeof targetProperty == typeof sourceProperty) continue; - - // bind timers to global for call from export context - if (options.bind && USE_NATIVE) resultProperty = functionBindContext(sourceProperty, global_1); - // wrap global constructors for prevent changs in this version - else if (options.wrap && USE_NATIVE) resultProperty = wrapConstructor(sourceProperty); - // make static versions for prototype methods - else if (PROTO && isCallable(sourceProperty)) resultProperty = functionUncurryThis(sourceProperty); - // default case - else resultProperty = sourceProperty; - - // add a flag to not completely full polyfills - if (options.sham || (sourceProperty && sourceProperty.sham) || (targetProperty && targetProperty.sham)) { - createNonEnumerableProperty(resultProperty, 'sham', true); - } - - createNonEnumerableProperty(target, key, resultProperty); - - if (PROTO) { - VIRTUAL_PROTOTYPE = TARGET + 'Prototype'; - if (!hasOwnProperty_1(path, VIRTUAL_PROTOTYPE)) { - createNonEnumerableProperty(path, VIRTUAL_PROTOTYPE, {}); - } - // export virtual prototype methods - createNonEnumerableProperty(path[VIRTUAL_PROTOTYPE], key, sourceProperty); - // export real prototype methods - if (options.real && targetPrototype && !targetPrototype[key]) { - createNonEnumerableProperty(targetPrototype, key, sourceProperty); - } - } - } + var TARGET = options.target; + var GLOBAL = options.global; + var STATIC = options.stat; + var PROTO = options.proto; + + var nativeSource = GLOBAL ? global_1 : STATIC ? global_1[TARGET] : (global_1[TARGET] || {}).prototype; + + var target = GLOBAL ? path : path[TARGET] || createNonEnumerableProperty(path, TARGET, {})[TARGET]; + var targetPrototype = target.prototype; + + var FORCED, USE_NATIVE, VIRTUAL_PROTOTYPE; + var key, sourceProperty, targetProperty, nativeProperty, resultProperty, descriptor; + + for (key in source) { + FORCED = isForced_1(GLOBAL ? key : TARGET + (STATIC ? '.' : '#') + key, options.forced); + // contains in native + USE_NATIVE = !FORCED && nativeSource && hasOwnProperty_1(nativeSource, key); + + targetProperty = target[key]; + + if (USE_NATIVE) if (options.dontCallGetSet) { + descriptor = getOwnPropertyDescriptor$1(nativeSource, key); + nativeProperty = descriptor && descriptor.value; + } else nativeProperty = nativeSource[key]; + + // export native or implementation + sourceProperty = (USE_NATIVE && nativeProperty) ? nativeProperty : source[key]; + + if (USE_NATIVE && typeof targetProperty == typeof sourceProperty) continue; + + // bind timers to global for call from export context + if (options.bind && USE_NATIVE) resultProperty = functionBindContext(sourceProperty, global_1); + // wrap global constructors for prevent changs in this version + else if (options.wrap && USE_NATIVE) resultProperty = wrapConstructor(sourceProperty); + // make static versions for prototype methods + else if (PROTO && isCallable(sourceProperty)) resultProperty = functionUncurryThis(sourceProperty); + // default case + else resultProperty = sourceProperty; + + // add a flag to not completely full polyfills + if (options.sham || (sourceProperty && sourceProperty.sham) || (targetProperty && targetProperty.sham)) { + createNonEnumerableProperty(resultProperty, 'sham', true); + } + + createNonEnumerableProperty(target, key, resultProperty); + + if (PROTO) { + VIRTUAL_PROTOTYPE = TARGET + 'Prototype'; + if (!hasOwnProperty_1(path, VIRTUAL_PROTOTYPE)) { + createNonEnumerableProperty(path, VIRTUAL_PROTOTYPE, {}); + } + // export virtual prototype methods + createNonEnumerableProperty(path[VIRTUAL_PROTOTYPE], key, sourceProperty); + // export real prototype methods + if (options.real && targetPrototype && !targetPrototype[key]) { + createNonEnumerableProperty(targetPrototype, key, sourceProperty); + } + } + } }; var arraySlice = functionUncurryThis([].slice); @@ -600,24 +599,24 @@ var factories = {}; var construct = function (C, argsLength, args) { - if (!hasOwnProperty_1(factories, argsLength)) { - for (var list = [], i = 0; i < argsLength; i++) list[i] = 'a[' + i + ']'; - factories[argsLength] = Function$1('C,a', 'return new C(' + join(list, ',') + ')'); - } return factories[argsLength](C, args); + if (!hasOwnProperty_1(factories, argsLength)) { + for (var list = [], i = 0; i < argsLength; i++) list[i] = 'a[' + i + ']'; + factories[argsLength] = Function$1('C,a', 'return new C(' + join(list, ',') + ')'); + } return factories[argsLength](C, args); }; // `Function.prototype.bind` method implementation // https://tc39.es/ecma262/#sec-function.prototype.bind var functionBind = functionBindNative ? Function$1.bind : function bind(that /* , ...args */) { - var F = aCallable(this); - var Prototype = F.prototype; - var partArgs = arraySlice(arguments, 1); - var boundFunction = function bound(/* args... */) { - var args = concat(partArgs, arraySlice(arguments)); - return this instanceof boundFunction ? construct(F, args.length, args) : F.apply(that, args); - }; - if (isObject(Prototype)) boundFunction.prototype = Prototype; - return boundFunction; + var F = aCallable(this); + var Prototype = F.prototype; + var partArgs = arraySlice(arguments, 1); + var boundFunction = function bound(/* args... */) { + var args = concat(partArgs, arraySlice(arguments)); + return this instanceof boundFunction ? construct(F, args.length, args) : F.apply(that, args); + }; + if (isObject(Prototype)) boundFunction.prototype = Prototype; + return boundFunction; }; var TO_STRING_TAG = wellKnownSymbol('toStringTag'); @@ -635,30 +634,30 @@ // fallback for IE11 Script Access Denied error var tryGet = function (it, key) { - try { - return it[key]; - } catch (error) { /* empty */ } + try { + return it[key]; + } catch (error) { /* empty */ } }; // getting tag from ES6+ `Object.prototype.toString` var classof = toStringTagSupport ? classofRaw : function (it) { - var O, tag, result; - return it === undefined ? 'Undefined' : it === null ? 'Null' - // @@toStringTag case - : typeof (tag = tryGet(O = Object$4(it), TO_STRING_TAG$1)) == 'string' ? tag - // builtinTag case - : CORRECT_ARGUMENTS ? classofRaw(O) - // ES3 arguments fallback - : (result = classofRaw(O)) == 'Object' && isCallable(O.callee) ? 'Arguments' : result; + var O, tag, result; + return it === undefined ? 'Undefined' : it === null ? 'Null' + // @@toStringTag case + : typeof (tag = tryGet(O = Object$4(it), TO_STRING_TAG$1)) == 'string' ? tag + // builtinTag case + : CORRECT_ARGUMENTS ? classofRaw(O) + // ES3 arguments fallback + : (result = classofRaw(O)) == 'Object' && isCallable(O.callee) ? 'Arguments' : result; }; var functionToString = functionUncurryThis(Function.toString); // this helper broken in `core-js@3.4.1-3.4.4`, so we can't use `shared` helper if (!isCallable(sharedStore.inspectSource)) { - sharedStore.inspectSource = function (it) { - return functionToString(it); - }; + sharedStore.inspectSource = function (it) { + return functionToString(it); + }; } var inspectSource = sharedStore.inspectSource; @@ -671,30 +670,30 @@ var INCORRECT_TO_STRING = !constructorRegExp.exec(noop); var isConstructorModern = function isConstructor(argument) { - if (!isCallable(argument)) return false; - try { - construct$1(noop, empty, argument); - return true; - } catch (error) { - return false; - } + if (!isCallable(argument)) return false; + try { + construct$1(noop, empty, argument); + return true; + } catch (error) { + return false; + } }; var isConstructorLegacy = function isConstructor(argument) { - if (!isCallable(argument)) return false; - switch (classof(argument)) { - case 'AsyncFunction': - case 'GeneratorFunction': - case 'AsyncGeneratorFunction': return false; - } - try { - // we can't check .prototype since constructors produced by .bind haven't it - // `Function#toString` throws on some built-it function in some legacy engines - // (for example, `DOMQuad` and similar in FF41-) - return INCORRECT_TO_STRING || !!exec(constructorRegExp, inspectSource(argument)); - } catch (error) { - return true; - } + if (!isCallable(argument)) return false; + switch (classof(argument)) { + case 'AsyncFunction': + case 'GeneratorFunction': + case 'AsyncGeneratorFunction': return false; + } + try { + // we can't check .prototype since constructors produced by .bind haven't it + // `Function#toString` throws on some built-it function in some legacy engines + // (for example, `DOMQuad` and similar in FF41-) + return INCORRECT_TO_STRING || !!exec(constructorRegExp, inspectSource(argument)); + } catch (error) { + return true; + } }; isConstructorLegacy.sham = true; @@ -702,19 +701,19 @@ // `IsConstructor` abstract operation // https://tc39.es/ecma262/#sec-isconstructor var isConstructor = !construct$1 || fails(function () { - var called; - return isConstructorModern(isConstructorModern.call) - || !isConstructorModern(Object) - || !isConstructorModern(function () { called = true; }) - || called; + var called; + return isConstructorModern(isConstructorModern.call) + || !isConstructorModern(Object) + || !isConstructorModern(function () { called = true; }) + || called; }) ? isConstructorLegacy : isConstructorModern; var TypeError$7 = global_1.TypeError; // `Assert: IsConstructor(argument) is true` var aConstructor = function (argument) { - if (isConstructor(argument)) return argument; - throw TypeError$7(tryToString(argument) + ' is not a constructor'); + if (isConstructor(argument)) return argument; + throw TypeError$7(tryToString(argument) + ' is not a constructor'); }; var ceil = Math.ceil; @@ -724,16 +723,16 @@ // https://tc39.es/ecma262/#sec-math.trunc // eslint-disable-next-line es-x/no-math-trunc -- safe var mathTrunc = Math.trunc || function trunc(x) { - var n = +x; - return (n > 0 ? floor : ceil)(n); + var n = +x; + return (n > 0 ? floor : ceil)(n); }; // `ToIntegerOrInfinity` abstract operation // https://tc39.es/ecma262/#sec-tointegerorinfinity var toIntegerOrInfinity = function (argument) { - var number = +argument; - // eslint-disable-next-line no-self-compare -- NaN check - return number !== number || number === 0 ? 0 : mathTrunc(number); + var number = +argument; + // eslint-disable-next-line no-self-compare -- NaN check + return number !== number || number === 0 ? 0 : mathTrunc(number); }; var max = Math.max; @@ -743,8 +742,8 @@ // Let integer be ? ToInteger(index). // If integer < 0, let result be max((length + integer), 0); else let result be min(integer, length). var toAbsoluteIndex = function (index, length) { - var integer = toIntegerOrInfinity(index); - return integer < 0 ? max(integer + length, 0) : min(integer, length); + var integer = toIntegerOrInfinity(index); + return integer < 0 ? max(integer + length, 0) : min(integer, length); }; var min$1 = Math.min; @@ -752,42 +751,42 @@ // `ToLength` abstract operation // https://tc39.es/ecma262/#sec-tolength var toLength = function (argument) { - return argument > 0 ? min$1(toIntegerOrInfinity(argument), 0x1FFFFFFFFFFFFF) : 0; // 2 ** 53 - 1 == 9007199254740991 + return argument > 0 ? min$1(toIntegerOrInfinity(argument), 0x1FFFFFFFFFFFFF) : 0; // 2 ** 53 - 1 == 9007199254740991 }; // `LengthOfArrayLike` abstract operation // https://tc39.es/ecma262/#sec-lengthofarraylike var lengthOfArrayLike = function (obj) { - return toLength(obj.length); + return toLength(obj.length); }; // `Array.prototype.{ indexOf, includes }` methods implementation var createMethod = function (IS_INCLUDES) { - return function ($this, el, fromIndex) { - var O = toIndexedObject($this); - var length = lengthOfArrayLike(O); - var index = toAbsoluteIndex(fromIndex, length); - var value; - // Array#includes uses SameValueZero equality algorithm - // eslint-disable-next-line no-self-compare -- NaN check - if (IS_INCLUDES && el != el) while (length > index) { - value = O[index++]; - // eslint-disable-next-line no-self-compare -- NaN check - if (value != value) return true; - // Array#indexOf ignores holes, Array#includes - not - } else for (; length > index; index++) { - if ((IS_INCLUDES || index in O) && O[index] === el) return IS_INCLUDES || index || 0; - } return !IS_INCLUDES && -1; - }; + return function ($this, el, fromIndex) { + var O = toIndexedObject($this); + var length = lengthOfArrayLike(O); + var index = toAbsoluteIndex(fromIndex, length); + var value; + // Array#includes uses SameValueZero equality algorithm + // eslint-disable-next-line no-self-compare -- NaN check + if (IS_INCLUDES && el != el) while (length > index) { + value = O[index++]; + // eslint-disable-next-line no-self-compare -- NaN check + if (value != value) return true; + // Array#indexOf ignores holes, Array#includes - not + } else for (;length > index; index++) { + if ((IS_INCLUDES || index in O) && O[index] === el) return IS_INCLUDES || index || 0; + } return !IS_INCLUDES && -1; + }; }; var arrayIncludes = { - // `Array.prototype.includes` method - // https://tc39.es/ecma262/#sec-array.prototype.includes - includes: createMethod(true), - // `Array.prototype.indexOf` method - // https://tc39.es/ecma262/#sec-array.prototype.indexof - indexOf: createMethod(false) + // `Array.prototype.includes` method + // https://tc39.es/ecma262/#sec-array.prototype.includes + includes: createMethod(true), + // `Array.prototype.indexOf` method + // https://tc39.es/ecma262/#sec-array.prototype.indexof + indexOf: createMethod(false) }; var hiddenKeys = {}; @@ -798,48 +797,48 @@ var push = functionUncurryThis([].push); var objectKeysInternal = function (object, names) { - var O = toIndexedObject(object); - var i = 0; - var result = []; - var key; - for (key in O) !hasOwnProperty_1(hiddenKeys, key) && hasOwnProperty_1(O, key) && push(result, key); - // Don't enum bug & hidden keys - while (names.length > i) if (hasOwnProperty_1(O, key = names[i++])) { - ~indexOf(result, key) || push(result, key); - } - return result; + var O = toIndexedObject(object); + var i = 0; + var result = []; + var key; + for (key in O) !hasOwnProperty_1(hiddenKeys, key) && hasOwnProperty_1(O, key) && push(result, key); + // Don't enum bug & hidden keys + while (names.length > i) if (hasOwnProperty_1(O, key = names[i++])) { + ~indexOf(result, key) || push(result, key); + } + return result; }; // IE8- don't enum bug keys var enumBugKeys = [ - 'constructor', - 'hasOwnProperty', - 'isPrototypeOf', - 'propertyIsEnumerable', - 'toLocaleString', - 'toString', - 'valueOf' + 'constructor', + 'hasOwnProperty', + 'isPrototypeOf', + 'propertyIsEnumerable', + 'toLocaleString', + 'toString', + 'valueOf' ]; // `Object.keys` method // https://tc39.es/ecma262/#sec-object.keys // eslint-disable-next-line es-x/no-object-keys -- safe var objectKeys = Object.keys || function keys(O) { - return objectKeysInternal(O, enumBugKeys); + return objectKeysInternal(O, enumBugKeys); }; // `Object.defineProperties` method // https://tc39.es/ecma262/#sec-object.defineproperties // eslint-disable-next-line es-x/no-object-defineproperties -- safe var f$3 = descriptors && !v8PrototypeDefineBug ? Object.defineProperties : function defineProperties(O, Properties) { - anObject(O); - var props = toIndexedObject(Properties); - var keys = objectKeys(Properties); - var length = keys.length; - var index = 0; - var key; - while (length > index) objectDefineProperty.f(O, key = keys[index++], props[key]); - return O; + anObject(O); + var props = toIndexedObject(Properties); + var keys = objectKeys(Properties); + var length = keys.length; + var index = 0; + var key; + while (length > index) objectDefineProperty.f(O, key = keys[index++], props[key]); + return O; }; var objectDefineProperties = { @@ -851,7 +850,7 @@ var keys = shared('keys'); var sharedKey = function (key) { - return keys[key] || (keys[key] = uid(key)); + return keys[key] || (keys[key] = uid(key)); }; /* global ActiveXObject -- old IE, WSH */ @@ -872,33 +871,33 @@ var EmptyConstructor = function () { /* empty */ }; var scriptTag = function (content) { - return LT + SCRIPT + GT + content + LT + '/' + SCRIPT + GT; + return LT + SCRIPT + GT + content + LT + '/' + SCRIPT + GT; }; // Create object with fake `null` prototype: use ActiveX Object with cleared prototype var NullProtoObjectViaActiveX = function (activeXDocument) { - activeXDocument.write(scriptTag('')); - activeXDocument.close(); - var temp = activeXDocument.parentWindow.Object; - activeXDocument = null; // avoid memory leak - return temp; + activeXDocument.write(scriptTag('')); + activeXDocument.close(); + var temp = activeXDocument.parentWindow.Object; + activeXDocument = null; // avoid memory leak + return temp; }; // Create object with fake `null` prototype: use iframe Object with cleared prototype var NullProtoObjectViaIFrame = function () { - // Thrash, waste and sodomy: IE GC bug - var iframe = documentCreateElement('iframe'); - var JS = 'java' + SCRIPT + ':'; - var iframeDocument; - iframe.style.display = 'none'; - html.appendChild(iframe); - // https://github.com/zloirock/core-js/issues/475 - iframe.src = String(JS); - iframeDocument = iframe.contentWindow.document; - iframeDocument.open(); - iframeDocument.write(scriptTag('document.F=Object')); - iframeDocument.close(); - return iframeDocument.F; + // Thrash, waste and sodomy: IE GC bug + var iframe = documentCreateElement('iframe'); + var JS = 'java' + SCRIPT + ':'; + var iframeDocument; + iframe.style.display = 'none'; + html.appendChild(iframe); + // https://github.com/zloirock/core-js/issues/475 + iframe.src = String(JS); + iframeDocument = iframe.contentWindow.document; + iframeDocument.open(); + iframeDocument.write(scriptTag('document.F=Object')); + iframeDocument.close(); + return iframeDocument.F; }; // Check for document.domain and active x support @@ -908,17 +907,17 @@ // avoid IE GC bug var activeXDocument; var NullProtoObject = function () { - try { - activeXDocument = new ActiveXObject('htmlfile'); - } catch (error) { /* ignore */ } - NullProtoObject = typeof document != 'undefined' - ? document.domain && activeXDocument - ? NullProtoObjectViaActiveX(activeXDocument) // old IE - : NullProtoObjectViaIFrame() - : NullProtoObjectViaActiveX(activeXDocument); // WSH - var length = enumBugKeys.length; - while (length--) delete NullProtoObject[PROTOTYPE][enumBugKeys[length]]; - return NullProtoObject(); + try { + activeXDocument = new ActiveXObject('htmlfile'); + } catch (error) { /* ignore */ } + NullProtoObject = typeof document != 'undefined' + ? document.domain && activeXDocument + ? NullProtoObjectViaActiveX(activeXDocument) // old IE + : NullProtoObjectViaIFrame() + : NullProtoObjectViaActiveX(activeXDocument); // WSH + var length = enumBugKeys.length; + while (length--) delete NullProtoObject[PROTOTYPE][enumBugKeys[length]]; + return NullProtoObject(); }; hiddenKeys[IE_PROTO] = true; @@ -927,15 +926,15 @@ // https://tc39.es/ecma262/#sec-object.create // eslint-disable-next-line es-x/no-object-create -- safe var objectCreate = Object.create || function create(O, Properties) { - var result; - if (O !== null) { - EmptyConstructor[PROTOTYPE] = anObject(O); - result = new EmptyConstructor(); - EmptyConstructor[PROTOTYPE] = null; - // add "__proto__" for Object.getPrototypeOf polyfill - result[IE_PROTO] = O; - } else result = NullProtoObject(); - return Properties === undefined ? result : objectDefineProperties.f(result, Properties); + var result; + if (O !== null) { + EmptyConstructor[PROTOTYPE] = anObject(O); + result = new EmptyConstructor(); + EmptyConstructor[PROTOTYPE] = null; + // add "__proto__" for Object.getPrototypeOf polyfill + result[IE_PROTO] = O; + } else result = NullProtoObject(); + return Properties === undefined ? result : objectDefineProperties.f(result, Properties); }; var nativeConstruct = getBuiltIn('Reflect', 'construct'); @@ -947,42 +946,42 @@ // MS Edge supports only 2 arguments and argumentsList argument is optional // FF Nightly sets third argument as `new.target`, but does not create `this` from it var NEW_TARGET_BUG = fails(function () { - function F() { /* empty */ } - return !(nativeConstruct(function () { /* empty */ }, [], F) instanceof F); + function F() { /* empty */ } + return !(nativeConstruct(function () { /* empty */ }, [], F) instanceof F); }); var ARGS_BUG = !fails(function () { - nativeConstruct(function () { /* empty */ }); + nativeConstruct(function () { /* empty */ }); }); var FORCED = NEW_TARGET_BUG || ARGS_BUG; _export({ target: 'Reflect', stat: true, forced: FORCED, sham: FORCED }, { - construct: function construct(Target, args /* , newTarget */) { - aConstructor(Target); - anObject(args); - var newTarget = arguments.length < 3 ? Target : aConstructor(arguments[2]); - if (ARGS_BUG && !NEW_TARGET_BUG) return nativeConstruct(Target, args, newTarget); - if (Target == newTarget) { - // w/o altered newTarget, optimization for 0-4 arguments - switch (args.length) { - case 0: return new Target(); - case 1: return new Target(args[0]); - case 2: return new Target(args[0], args[1]); - case 3: return new Target(args[0], args[1], args[2]); - case 4: return new Target(args[0], args[1], args[2], args[3]); - } - // w/o altered newTarget, lot of arguments case - var $args = [null]; - functionApply(push$1, $args, args); - return new (functionApply(functionBind, Target, $args))(); - } - // with altered newTarget, not support built-in constructors - var proto = newTarget.prototype; - var instance = objectCreate(isObject(proto) ? proto : ObjectPrototype); - var result = functionApply(Target, instance, args); - return isObject(result) ? result : instance; - } + construct: function construct(Target, args /* , newTarget */) { + aConstructor(Target); + anObject(args); + var newTarget = arguments.length < 3 ? Target : aConstructor(arguments[2]); + if (ARGS_BUG && !NEW_TARGET_BUG) return nativeConstruct(Target, args, newTarget); + if (Target == newTarget) { + // w/o altered newTarget, optimization for 0-4 arguments + switch (args.length) { + case 0: return new Target(); + case 1: return new Target(args[0]); + case 2: return new Target(args[0], args[1]); + case 3: return new Target(args[0], args[1], args[2]); + case 4: return new Target(args[0], args[1], args[2], args[3]); + } + // w/o altered newTarget, lot of arguments case + var $args = [null]; + functionApply(push$1, $args, args); + return new (functionApply(functionBind, Target, $args))(); + } + // with altered newTarget, not support built-in constructors + var proto = newTarget.prototype; + var instance = objectCreate(isObject(proto) ? proto : ObjectPrototype); + var result = functionApply(Target, instance, args); + return isObject(result) ? result : instance; + } }); var construct$2 = path.Reflect.construct; @@ -996,9 +995,9 @@ // `Object.keys` method // https://tc39.es/ecma262/#sec-object.keys _export({ target: 'Object', stat: true, forced: FAILS_ON_PRIMITIVES }, { - keys: function keys(it) { - return objectKeys(toObject(it)); - } + keys: function keys(it) { + return objectKeys(toObject(it)); + } }); var keys$1 = path.Object.keys; @@ -1010,8 +1009,8 @@ var String$3 = global_1.String; var toString_1 = function (argument) { - if (classof(argument) === 'Symbol') throw TypeError('Cannot convert a Symbol value to a string'); - return String$3(argument); + if (classof(argument) === 'Symbol') throw TypeError('Cannot convert a Symbol value to a string'); + return String$3(argument); }; var hiddenKeys$1 = enumBugKeys.concat('length', 'prototype'); @@ -1020,7 +1019,7 @@ // https://tc39.es/ecma262/#sec-object.getownpropertynames // eslint-disable-next-line es-x/no-object-getownpropertynames -- safe var f$4 = Object.getOwnPropertyNames || function getOwnPropertyNames(O) { - return objectKeysInternal(O, hiddenKeys$1); + return objectKeysInternal(O, hiddenKeys$1); }; var objectGetOwnPropertyNames = { @@ -1028,22 +1027,22 @@ }; var createProperty = function (object, key, value) { - var propertyKey = toPropertyKey(key); - if (propertyKey in object) objectDefineProperty.f(object, propertyKey, createPropertyDescriptor(0, value)); - else object[propertyKey] = value; + var propertyKey = toPropertyKey(key); + if (propertyKey in object) objectDefineProperty.f(object, propertyKey, createPropertyDescriptor(0, value)); + else object[propertyKey] = value; }; var Array$1 = global_1.Array; var max$1 = Math.max; var arraySliceSimple = function (O, start, end) { - var length = lengthOfArrayLike(O); - var k = toAbsoluteIndex(start, length); - var fin = toAbsoluteIndex(end === undefined ? length : end, length); - var result = Array$1(max$1(fin - k, 0)); - for (var n = 0; k < fin; k++, n++) createProperty(result, n, O[k]); - result.length = n; - return result; + var length = lengthOfArrayLike(O); + var k = toAbsoluteIndex(start, length); + var fin = toAbsoluteIndex(end === undefined ? length : end, length); + var result = Array$1(max$1(fin - k, 0)); + for (var n = 0; k < fin; k++, n++) createProperty(result, n, O[k]); + result.length = n; + return result; }; /* eslint-disable es-x/no-object-getownpropertynames -- safe */ @@ -1053,21 +1052,21 @@ var windowNames = typeof window == 'object' && window && Object.getOwnPropertyNames - ? Object.getOwnPropertyNames(window) : []; + ? Object.getOwnPropertyNames(window) : []; var getWindowNames = function (it) { - try { - return $getOwnPropertyNames(it); - } catch (error) { - return arraySliceSimple(windowNames); - } + try { + return $getOwnPropertyNames(it); + } catch (error) { + return arraySliceSimple(windowNames); + } }; // fallback for IE11 buggy Object.getOwnPropertyNames with iframe and window var f$5 = function getOwnPropertyNames(it) { - return windowNames && classofRaw(it) == 'Window' - ? getWindowNames(it) - : $getOwnPropertyNames(toIndexedObject(it)); + return windowNames && classofRaw(it) == 'Window' + ? getWindowNames(it) + : $getOwnPropertyNames(toIndexedObject(it)); }; var objectGetOwnPropertyNamesExternal = { @@ -1082,9 +1081,9 @@ }; var defineBuiltIn = function (target, key, value, options) { - if (options && options.enumerable) target[key] = value; - else createNonEnumerableProperty(target, key, value); - return target; + if (options && options.enumerable) target[key] = value; + else createNonEnumerableProperty(target, key, value); + return target; }; var f$7 = wellKnownSymbol; @@ -1096,32 +1095,32 @@ var defineProperty$1 = objectDefineProperty.f; var defineWellKnownSymbol = function (NAME) { - var Symbol = path.Symbol || (path.Symbol = {}); - if (!hasOwnProperty_1(Symbol, NAME)) defineProperty$1(Symbol, NAME, { - value: wellKnownSymbolWrapped.f(NAME) - }); + var Symbol = path.Symbol || (path.Symbol = {}); + if (!hasOwnProperty_1(Symbol, NAME)) defineProperty$1(Symbol, NAME, { + value: wellKnownSymbolWrapped.f(NAME) + }); }; var symbolDefineToPrimitive = function () { - var Symbol = getBuiltIn('Symbol'); - var SymbolPrototype = Symbol && Symbol.prototype; - var valueOf = SymbolPrototype && SymbolPrototype.valueOf; - var TO_PRIMITIVE = wellKnownSymbol('toPrimitive'); - - if (SymbolPrototype && !SymbolPrototype[TO_PRIMITIVE]) { - // `Symbol.prototype[@@toPrimitive]` method - // https://tc39.es/ecma262/#sec-symbol.prototype-@@toprimitive - // eslint-disable-next-line no-unused-vars -- required for .length - defineBuiltIn(SymbolPrototype, TO_PRIMITIVE, function (hint) { - return functionCall(valueOf, this); - }, { arity: 1 }); - } + var Symbol = getBuiltIn('Symbol'); + var SymbolPrototype = Symbol && Symbol.prototype; + var valueOf = SymbolPrototype && SymbolPrototype.valueOf; + var TO_PRIMITIVE = wellKnownSymbol('toPrimitive'); + + if (SymbolPrototype && !SymbolPrototype[TO_PRIMITIVE]) { + // `Symbol.prototype[@@toPrimitive]` method + // https://tc39.es/ecma262/#sec-symbol.prototype-@@toprimitive + // eslint-disable-next-line no-unused-vars -- required for .length + defineBuiltIn(SymbolPrototype, TO_PRIMITIVE, function (hint) { + return functionCall(valueOf, this); + }, { arity: 1 }); + } }; // `Object.prototype.toString` method implementation // https://tc39.es/ecma262/#sec-object.prototype.tostring var objectToString = toStringTagSupport ? {}.toString : function toString() { - return '[object ' + classof(this) + ']'; + return '[object ' + classof(this) + ']'; }; var defineProperty$2 = objectDefineProperty.f; @@ -1133,15 +1132,15 @@ var TO_STRING_TAG$2 = wellKnownSymbol('toStringTag'); var setToStringTag = function (it, TAG, STATIC, SET_METHOD) { - if (it) { - var target = STATIC ? it : it.prototype; - if (!hasOwnProperty_1(target, TO_STRING_TAG$2)) { - defineProperty$2(target, TO_STRING_TAG$2, { configurable: true, value: TAG }); - } - if (SET_METHOD && !toStringTagSupport) { - createNonEnumerableProperty(target, 'toString', objectToString); - } - } + if (it) { + var target = STATIC ? it : it.prototype; + if (!hasOwnProperty_1(target, TO_STRING_TAG$2)) { + defineProperty$2(target, TO_STRING_TAG$2, { configurable: true, value: TAG }); + } + if (SET_METHOD && !toStringTagSupport) { + createNonEnumerableProperty(target, 'toString', objectToString); + } + } }; var WeakMap = global_1.WeakMap; @@ -1154,65 +1153,65 @@ var set, get, has; var enforce = function (it) { - return has(it) ? get(it) : set(it, {}); + return has(it) ? get(it) : set(it, {}); }; var getterFor = function (TYPE) { - return function (it) { - var state; - if (!isObject(it) || (state = get(it)).type !== TYPE) { - throw TypeError$8('Incompatible receiver, ' + TYPE + ' required'); - } return state; - }; + return function (it) { + var state; + if (!isObject(it) || (state = get(it)).type !== TYPE) { + throw TypeError$8('Incompatible receiver, ' + TYPE + ' required'); + } return state; + }; }; if (nativeWeakMap || sharedStore.state) { - var store$1 = sharedStore.state || (sharedStore.state = new WeakMap$1()); - var wmget = functionUncurryThis(store$1.get); - var wmhas = functionUncurryThis(store$1.has); - var wmset = functionUncurryThis(store$1.set); - set = function (it, metadata) { - if (wmhas(store$1, it)) throw new TypeError$8(OBJECT_ALREADY_INITIALIZED); - metadata.facade = it; - wmset(store$1, it, metadata); - return metadata; - }; - get = function (it) { - return wmget(store$1, it) || {}; - }; - has = function (it) { - return wmhas(store$1, it); - }; + var store$1 = sharedStore.state || (sharedStore.state = new WeakMap$1()); + var wmget = functionUncurryThis(store$1.get); + var wmhas = functionUncurryThis(store$1.has); + var wmset = functionUncurryThis(store$1.set); + set = function (it, metadata) { + if (wmhas(store$1, it)) throw new TypeError$8(OBJECT_ALREADY_INITIALIZED); + metadata.facade = it; + wmset(store$1, it, metadata); + return metadata; + }; + get = function (it) { + return wmget(store$1, it) || {}; + }; + has = function (it) { + return wmhas(store$1, it); + }; } else { - var STATE = sharedKey('state'); - hiddenKeys[STATE] = true; - set = function (it, metadata) { - if (hasOwnProperty_1(it, STATE)) throw new TypeError$8(OBJECT_ALREADY_INITIALIZED); - metadata.facade = it; - createNonEnumerableProperty(it, STATE, metadata); - return metadata; - }; - get = function (it) { - return hasOwnProperty_1(it, STATE) ? it[STATE] : {}; - }; - has = function (it) { - return hasOwnProperty_1(it, STATE); - }; + var STATE = sharedKey('state'); + hiddenKeys[STATE] = true; + set = function (it, metadata) { + if (hasOwnProperty_1(it, STATE)) throw new TypeError$8(OBJECT_ALREADY_INITIALIZED); + metadata.facade = it; + createNonEnumerableProperty(it, STATE, metadata); + return metadata; + }; + get = function (it) { + return hasOwnProperty_1(it, STATE) ? it[STATE] : {}; + }; + has = function (it) { + return hasOwnProperty_1(it, STATE); + }; } var internalState = { - set: set, - get: get, - has: has, - enforce: enforce, - getterFor: getterFor + set: set, + get: get, + has: has, + enforce: enforce, + getterFor: getterFor }; // `IsArray` abstract operation // https://tc39.es/ecma262/#sec-isarray // eslint-disable-next-line es-x/no-array-isarray -- safe var isArray = Array.isArray || function isArray(argument) { - return classofRaw(argument) == 'Array'; + return classofRaw(argument) == 'Array'; }; var SPECIES = wellKnownSymbol('species'); @@ -1221,89 +1220,89 @@ // a part of `ArraySpeciesCreate` abstract operation // https://tc39.es/ecma262/#sec-arrayspeciescreate var arraySpeciesConstructor = function (originalArray) { - var C; - if (isArray(originalArray)) { - C = originalArray.constructor; - // cross-realm fallback - if (isConstructor(C) && (C === Array$2 || isArray(C.prototype))) C = undefined; - else if (isObject(C)) { - C = C[SPECIES]; - if (C === null) C = undefined; - } - } return C === undefined ? Array$2 : C; + var C; + if (isArray(originalArray)) { + C = originalArray.constructor; + // cross-realm fallback + if (isConstructor(C) && (C === Array$2 || isArray(C.prototype))) C = undefined; + else if (isObject(C)) { + C = C[SPECIES]; + if (C === null) C = undefined; + } + } return C === undefined ? Array$2 : C; }; // `ArraySpeciesCreate` abstract operation // https://tc39.es/ecma262/#sec-arrayspeciescreate var arraySpeciesCreate = function (originalArray, length) { - return new (arraySpeciesConstructor(originalArray))(length === 0 ? 0 : length); + return new (arraySpeciesConstructor(originalArray))(length === 0 ? 0 : length); }; var push$2 = functionUncurryThis([].push); // `Array.prototype.{ forEach, map, filter, some, every, find, findIndex, filterReject }` methods implementation var createMethod$1 = function (TYPE) { - var IS_MAP = TYPE == 1; - var IS_FILTER = TYPE == 2; - var IS_SOME = TYPE == 3; - var IS_EVERY = TYPE == 4; - var IS_FIND_INDEX = TYPE == 6; - var IS_FILTER_REJECT = TYPE == 7; - var NO_HOLES = TYPE == 5 || IS_FIND_INDEX; - return function ($this, callbackfn, that, specificCreate) { - var O = toObject($this); - var self = indexedObject(O); - var boundFunction = functionBindContext(callbackfn, that); - var length = lengthOfArrayLike(self); - var index = 0; - var create = specificCreate || arraySpeciesCreate; - var target = IS_MAP ? create($this, length) : IS_FILTER || IS_FILTER_REJECT ? create($this, 0) : undefined; - var value, result; - for (; length > index; index++) if (NO_HOLES || index in self) { - value = self[index]; - result = boundFunction(value, index, O); - if (TYPE) { - if (IS_MAP) target[index] = result; // map - else if (result) switch (TYPE) { - case 3: return true; // some - case 5: return value; // find - case 6: return index; // findIndex - case 2: push$2(target, value); // filter - } else switch (TYPE) { - case 4: return false; // every - case 7: push$2(target, value); // filterReject - } - } - } - return IS_FIND_INDEX ? -1 : IS_SOME || IS_EVERY ? IS_EVERY : target; - }; + var IS_MAP = TYPE == 1; + var IS_FILTER = TYPE == 2; + var IS_SOME = TYPE == 3; + var IS_EVERY = TYPE == 4; + var IS_FIND_INDEX = TYPE == 6; + var IS_FILTER_REJECT = TYPE == 7; + var NO_HOLES = TYPE == 5 || IS_FIND_INDEX; + return function ($this, callbackfn, that, specificCreate) { + var O = toObject($this); + var self = indexedObject(O); + var boundFunction = functionBindContext(callbackfn, that); + var length = lengthOfArrayLike(self); + var index = 0; + var create = specificCreate || arraySpeciesCreate; + var target = IS_MAP ? create($this, length) : IS_FILTER || IS_FILTER_REJECT ? create($this, 0) : undefined; + var value, result; + for (;length > index; index++) if (NO_HOLES || index in self) { + value = self[index]; + result = boundFunction(value, index, O); + if (TYPE) { + if (IS_MAP) target[index] = result; // map + else if (result) switch (TYPE) { + case 3: return true; // some + case 5: return value; // find + case 6: return index; // findIndex + case 2: push$2(target, value); // filter + } else switch (TYPE) { + case 4: return false; // every + case 7: push$2(target, value); // filterReject + } + } + } + return IS_FIND_INDEX ? -1 : IS_SOME || IS_EVERY ? IS_EVERY : target; + }; }; var arrayIteration = { - // `Array.prototype.forEach` method - // https://tc39.es/ecma262/#sec-array.prototype.foreach - forEach: createMethod$1(0), - // `Array.prototype.map` method - // https://tc39.es/ecma262/#sec-array.prototype.map - map: createMethod$1(1), - // `Array.prototype.filter` method - // https://tc39.es/ecma262/#sec-array.prototype.filter - filter: createMethod$1(2), - // `Array.prototype.some` method - // https://tc39.es/ecma262/#sec-array.prototype.some - some: createMethod$1(3), - // `Array.prototype.every` method - // https://tc39.es/ecma262/#sec-array.prototype.every - every: createMethod$1(4), - // `Array.prototype.find` method - // https://tc39.es/ecma262/#sec-array.prototype.find - find: createMethod$1(5), - // `Array.prototype.findIndex` method - // https://tc39.es/ecma262/#sec-array.prototype.findIndex - findIndex: createMethod$1(6), - // `Array.prototype.filterReject` method - // https://github.com/tc39/proposal-array-filtering - filterReject: createMethod$1(7) + // `Array.prototype.forEach` method + // https://tc39.es/ecma262/#sec-array.prototype.foreach + forEach: createMethod$1(0), + // `Array.prototype.map` method + // https://tc39.es/ecma262/#sec-array.prototype.map + map: createMethod$1(1), + // `Array.prototype.filter` method + // https://tc39.es/ecma262/#sec-array.prototype.filter + filter: createMethod$1(2), + // `Array.prototype.some` method + // https://tc39.es/ecma262/#sec-array.prototype.some + some: createMethod$1(3), + // `Array.prototype.every` method + // https://tc39.es/ecma262/#sec-array.prototype.every + every: createMethod$1(4), + // `Array.prototype.find` method + // https://tc39.es/ecma262/#sec-array.prototype.find + find: createMethod$1(5), + // `Array.prototype.findIndex` method + // https://tc39.es/ecma262/#sec-array.prototype.findIndex + findIndex: createMethod$1(6), + // `Array.prototype.filterReject` method + // https://github.com/tc39/proposal-array-filtering + filterReject: createMethod$1(7) }; var $forEach = arrayIteration.forEach; @@ -1335,179 +1334,179 @@ // fallback for old Android, https://code.google.com/p/v8/issues/detail?id=687 var setSymbolDescriptor = descriptors && fails(function () { - return objectCreate(nativeDefineProperty({}, 'a', { - get: function () { return nativeDefineProperty(this, 'a', { value: 7 }).a; } - })).a != 7; + return objectCreate(nativeDefineProperty({}, 'a', { + get: function () { return nativeDefineProperty(this, 'a', { value: 7 }).a; } + })).a != 7; }) ? function (O, P, Attributes) { - var ObjectPrototypeDescriptor = nativeGetOwnPropertyDescriptor(ObjectPrototype$1, P); - if (ObjectPrototypeDescriptor) delete ObjectPrototype$1[P]; - nativeDefineProperty(O, P, Attributes); - if (ObjectPrototypeDescriptor && O !== ObjectPrototype$1) { - nativeDefineProperty(ObjectPrototype$1, P, ObjectPrototypeDescriptor); - } + var ObjectPrototypeDescriptor = nativeGetOwnPropertyDescriptor(ObjectPrototype$1, P); + if (ObjectPrototypeDescriptor) delete ObjectPrototype$1[P]; + nativeDefineProperty(O, P, Attributes); + if (ObjectPrototypeDescriptor && O !== ObjectPrototype$1) { + nativeDefineProperty(ObjectPrototype$1, P, ObjectPrototypeDescriptor); + } } : nativeDefineProperty; var wrap = function (tag, description) { - var symbol = AllSymbols[tag] = objectCreate(SymbolPrototype); - setInternalState(symbol, { - type: SYMBOL, - tag: tag, - description: description - }); - if (!descriptors) symbol.description = description; - return symbol; + var symbol = AllSymbols[tag] = objectCreate(SymbolPrototype); + setInternalState(symbol, { + type: SYMBOL, + tag: tag, + description: description + }); + if (!descriptors) symbol.description = description; + return symbol; }; var $defineProperty$1 = function defineProperty(O, P, Attributes) { - if (O === ObjectPrototype$1) $defineProperty$1(ObjectPrototypeSymbols, P, Attributes); - anObject(O); - var key = toPropertyKey(P); - anObject(Attributes); - if (hasOwnProperty_1(AllSymbols, key)) { - if (!Attributes.enumerable) { - if (!hasOwnProperty_1(O, HIDDEN)) nativeDefineProperty(O, HIDDEN, createPropertyDescriptor(1, {})); - O[HIDDEN][key] = true; - } else { - if (hasOwnProperty_1(O, HIDDEN) && O[HIDDEN][key]) O[HIDDEN][key] = false; - Attributes = objectCreate(Attributes, { enumerable: createPropertyDescriptor(0, false) }); - } return setSymbolDescriptor(O, key, Attributes); - } return nativeDefineProperty(O, key, Attributes); + if (O === ObjectPrototype$1) $defineProperty$1(ObjectPrototypeSymbols, P, Attributes); + anObject(O); + var key = toPropertyKey(P); + anObject(Attributes); + if (hasOwnProperty_1(AllSymbols, key)) { + if (!Attributes.enumerable) { + if (!hasOwnProperty_1(O, HIDDEN)) nativeDefineProperty(O, HIDDEN, createPropertyDescriptor(1, {})); + O[HIDDEN][key] = true; + } else { + if (hasOwnProperty_1(O, HIDDEN) && O[HIDDEN][key]) O[HIDDEN][key] = false; + Attributes = objectCreate(Attributes, { enumerable: createPropertyDescriptor(0, false) }); + } return setSymbolDescriptor(O, key, Attributes); + } return nativeDefineProperty(O, key, Attributes); }; var $defineProperties = function defineProperties(O, Properties) { - anObject(O); - var properties = toIndexedObject(Properties); - var keys = objectKeys(properties).concat($getOwnPropertySymbols(properties)); - $forEach(keys, function (key) { - if (!descriptors || functionCall($propertyIsEnumerable$1, properties, key)) $defineProperty$1(O, key, properties[key]); - }); - return O; + anObject(O); + var properties = toIndexedObject(Properties); + var keys = objectKeys(properties).concat($getOwnPropertySymbols(properties)); + $forEach(keys, function (key) { + if (!descriptors || functionCall($propertyIsEnumerable$1, properties, key)) $defineProperty$1(O, key, properties[key]); + }); + return O; }; var $create = function create(O, Properties) { - return Properties === undefined ? objectCreate(O) : $defineProperties(objectCreate(O), Properties); + return Properties === undefined ? objectCreate(O) : $defineProperties(objectCreate(O), Properties); }; var $propertyIsEnumerable$1 = function propertyIsEnumerable(V) { - var P = toPropertyKey(V); - var enumerable = functionCall(nativePropertyIsEnumerable, this, P); - if (this === ObjectPrototype$1 && hasOwnProperty_1(AllSymbols, P) && !hasOwnProperty_1(ObjectPrototypeSymbols, P)) return false; - return enumerable || !hasOwnProperty_1(this, P) || !hasOwnProperty_1(AllSymbols, P) || hasOwnProperty_1(this, HIDDEN) && this[HIDDEN][P] - ? enumerable : true; + var P = toPropertyKey(V); + var enumerable = functionCall(nativePropertyIsEnumerable, this, P); + if (this === ObjectPrototype$1 && hasOwnProperty_1(AllSymbols, P) && !hasOwnProperty_1(ObjectPrototypeSymbols, P)) return false; + return enumerable || !hasOwnProperty_1(this, P) || !hasOwnProperty_1(AllSymbols, P) || hasOwnProperty_1(this, HIDDEN) && this[HIDDEN][P] + ? enumerable : true; }; var $getOwnPropertyDescriptor$2 = function getOwnPropertyDescriptor(O, P) { - var it = toIndexedObject(O); - var key = toPropertyKey(P); - if (it === ObjectPrototype$1 && hasOwnProperty_1(AllSymbols, key) && !hasOwnProperty_1(ObjectPrototypeSymbols, key)) return; - var descriptor = nativeGetOwnPropertyDescriptor(it, key); - if (descriptor && hasOwnProperty_1(AllSymbols, key) && !(hasOwnProperty_1(it, HIDDEN) && it[HIDDEN][key])) { - descriptor.enumerable = true; - } - return descriptor; + var it = toIndexedObject(O); + var key = toPropertyKey(P); + if (it === ObjectPrototype$1 && hasOwnProperty_1(AllSymbols, key) && !hasOwnProperty_1(ObjectPrototypeSymbols, key)) return; + var descriptor = nativeGetOwnPropertyDescriptor(it, key); + if (descriptor && hasOwnProperty_1(AllSymbols, key) && !(hasOwnProperty_1(it, HIDDEN) && it[HIDDEN][key])) { + descriptor.enumerable = true; + } + return descriptor; }; var $getOwnPropertyNames$1 = function getOwnPropertyNames(O) { - var names = nativeGetOwnPropertyNames(toIndexedObject(O)); - var result = []; - $forEach(names, function (key) { - if (!hasOwnProperty_1(AllSymbols, key) && !hasOwnProperty_1(hiddenKeys, key)) push$3(result, key); - }); - return result; + var names = nativeGetOwnPropertyNames(toIndexedObject(O)); + var result = []; + $forEach(names, function (key) { + if (!hasOwnProperty_1(AllSymbols, key) && !hasOwnProperty_1(hiddenKeys, key)) push$3(result, key); + }); + return result; }; var $getOwnPropertySymbols = function (O) { - var IS_OBJECT_PROTOTYPE = O === ObjectPrototype$1; - var names = nativeGetOwnPropertyNames(IS_OBJECT_PROTOTYPE ? ObjectPrototypeSymbols : toIndexedObject(O)); - var result = []; - $forEach(names, function (key) { - if (hasOwnProperty_1(AllSymbols, key) && (!IS_OBJECT_PROTOTYPE || hasOwnProperty_1(ObjectPrototype$1, key))) { - push$3(result, AllSymbols[key]); - } - }); - return result; + var IS_OBJECT_PROTOTYPE = O === ObjectPrototype$1; + var names = nativeGetOwnPropertyNames(IS_OBJECT_PROTOTYPE ? ObjectPrototypeSymbols : toIndexedObject(O)); + var result = []; + $forEach(names, function (key) { + if (hasOwnProperty_1(AllSymbols, key) && (!IS_OBJECT_PROTOTYPE || hasOwnProperty_1(ObjectPrototype$1, key))) { + push$3(result, AllSymbols[key]); + } + }); + return result; }; // `Symbol` constructor // https://tc39.es/ecma262/#sec-symbol-constructor if (!nativeSymbol) { - $Symbol = function Symbol() { - if (objectIsPrototypeOf(SymbolPrototype, this)) throw TypeError$9('Symbol is not a constructor'); - var description = !arguments.length || arguments[0] === undefined ? undefined : toString_1(arguments[0]); - var tag = uid(description); - var setter = function (value) { - if (this === ObjectPrototype$1) functionCall(setter, ObjectPrototypeSymbols, value); - if (hasOwnProperty_1(this, HIDDEN) && hasOwnProperty_1(this[HIDDEN], tag)) this[HIDDEN][tag] = false; - setSymbolDescriptor(this, tag, createPropertyDescriptor(1, value)); - }; - if (descriptors && USE_SETTER) setSymbolDescriptor(ObjectPrototype$1, tag, { configurable: true, set: setter }); - return wrap(tag, description); - }; - - SymbolPrototype = $Symbol[PROTOTYPE$1]; - - defineBuiltIn(SymbolPrototype, 'toString', function toString() { - return getInternalState(this).tag; - }); - - defineBuiltIn($Symbol, 'withoutSetter', function (description) { - return wrap(uid(description), description); - }); - - objectPropertyIsEnumerable.f = $propertyIsEnumerable$1; - objectDefineProperty.f = $defineProperty$1; - objectDefineProperties.f = $defineProperties; - objectGetOwnPropertyDescriptor.f = $getOwnPropertyDescriptor$2; - objectGetOwnPropertyNames.f = objectGetOwnPropertyNamesExternal.f = $getOwnPropertyNames$1; - objectGetOwnPropertySymbols.f = $getOwnPropertySymbols; - - wellKnownSymbolWrapped.f = function (name) { - return wrap(wellKnownSymbol(name), name); - }; - - if (descriptors) { - // https://github.com/tc39/proposal-Symbol-description - nativeDefineProperty(SymbolPrototype, 'description', { - configurable: true, - get: function description() { - return getInternalState(this).description; - } - }); - } + $Symbol = function Symbol() { + if (objectIsPrototypeOf(SymbolPrototype, this)) throw TypeError$9('Symbol is not a constructor'); + var description = !arguments.length || arguments[0] === undefined ? undefined : toString_1(arguments[0]); + var tag = uid(description); + var setter = function (value) { + if (this === ObjectPrototype$1) functionCall(setter, ObjectPrototypeSymbols, value); + if (hasOwnProperty_1(this, HIDDEN) && hasOwnProperty_1(this[HIDDEN], tag)) this[HIDDEN][tag] = false; + setSymbolDescriptor(this, tag, createPropertyDescriptor(1, value)); + }; + if (descriptors && USE_SETTER) setSymbolDescriptor(ObjectPrototype$1, tag, { configurable: true, set: setter }); + return wrap(tag, description); + }; + + SymbolPrototype = $Symbol[PROTOTYPE$1]; + + defineBuiltIn(SymbolPrototype, 'toString', function toString() { + return getInternalState(this).tag; + }); + + defineBuiltIn($Symbol, 'withoutSetter', function (description) { + return wrap(uid(description), description); + }); + + objectPropertyIsEnumerable.f = $propertyIsEnumerable$1; + objectDefineProperty.f = $defineProperty$1; + objectDefineProperties.f = $defineProperties; + objectGetOwnPropertyDescriptor.f = $getOwnPropertyDescriptor$2; + objectGetOwnPropertyNames.f = objectGetOwnPropertyNamesExternal.f = $getOwnPropertyNames$1; + objectGetOwnPropertySymbols.f = $getOwnPropertySymbols; + + wellKnownSymbolWrapped.f = function (name) { + return wrap(wellKnownSymbol(name), name); + }; + + if (descriptors) { + // https://github.com/tc39/proposal-Symbol-description + nativeDefineProperty(SymbolPrototype, 'description', { + configurable: true, + get: function description() { + return getInternalState(this).description; + } + }); + } } _export({ global: true, constructor: true, wrap: true, forced: !nativeSymbol, sham: !nativeSymbol }, { - Symbol: $Symbol + Symbol: $Symbol }); $forEach(objectKeys(WellKnownSymbolsStore$1), function (name) { - defineWellKnownSymbol(name); + defineWellKnownSymbol(name); }); _export({ target: SYMBOL, stat: true, forced: !nativeSymbol }, { - useSetter: function () { USE_SETTER = true; }, - useSimple: function () { USE_SETTER = false; } + useSetter: function () { USE_SETTER = true; }, + useSimple: function () { USE_SETTER = false; } }); _export({ target: 'Object', stat: true, forced: !nativeSymbol, sham: !descriptors }, { - // `Object.create` method - // https://tc39.es/ecma262/#sec-object.create - create: $create, - // `Object.defineProperty` method - // https://tc39.es/ecma262/#sec-object.defineproperty - defineProperty: $defineProperty$1, - // `Object.defineProperties` method - // https://tc39.es/ecma262/#sec-object.defineproperties - defineProperties: $defineProperties, - // `Object.getOwnPropertyDescriptor` method - // https://tc39.es/ecma262/#sec-object.getownpropertydescriptors - getOwnPropertyDescriptor: $getOwnPropertyDescriptor$2 + // `Object.create` method + // https://tc39.es/ecma262/#sec-object.create + create: $create, + // `Object.defineProperty` method + // https://tc39.es/ecma262/#sec-object.defineproperty + defineProperty: $defineProperty$1, + // `Object.defineProperties` method + // https://tc39.es/ecma262/#sec-object.defineproperties + defineProperties: $defineProperties, + // `Object.getOwnPropertyDescriptor` method + // https://tc39.es/ecma262/#sec-object.getownpropertydescriptors + getOwnPropertyDescriptor: $getOwnPropertyDescriptor$2 }); _export({ target: 'Object', stat: true, forced: !nativeSymbol }, { - // `Object.getOwnPropertyNames` method - // https://tc39.es/ecma262/#sec-object.getownpropertynames - getOwnPropertyNames: $getOwnPropertyNames$1 + // `Object.getOwnPropertyNames` method + // https://tc39.es/ecma262/#sec-object.getownpropertynames + getOwnPropertyNames: $getOwnPropertyNames$1 }); // `Symbol.prototype[@@toPrimitive]` method @@ -1529,14 +1528,14 @@ // `Symbol.for` method // https://tc39.es/ecma262/#sec-symbol.for _export({ target: 'Symbol', stat: true, forced: !nativeSymbolRegistry }, { - 'for': function (key) { - var string = toString_1(key); - if (hasOwnProperty_1(StringToSymbolRegistry, string)) return StringToSymbolRegistry[string]; - var symbol = getBuiltIn('Symbol')(string); - StringToSymbolRegistry[string] = symbol; - SymbolToStringRegistry[symbol] = string; - return symbol; - } + 'for': function (key) { + var string = toString_1(key); + if (hasOwnProperty_1(StringToSymbolRegistry, string)) return StringToSymbolRegistry[string]; + var symbol = getBuiltIn('Symbol')(string); + StringToSymbolRegistry[string] = symbol; + SymbolToStringRegistry[symbol] = string; + return symbol; + } }); var SymbolToStringRegistry$1 = shared('symbol-to-string-registry'); @@ -1544,10 +1543,10 @@ // `Symbol.keyFor` method // https://tc39.es/ecma262/#sec-symbol.keyfor _export({ target: 'Symbol', stat: true, forced: !nativeSymbolRegistry }, { - keyFor: function keyFor(sym) { - if (!isSymbol(sym)) throw TypeError(tryToString(sym) + ' is not a symbol'); - if (hasOwnProperty_1(SymbolToStringRegistry$1, sym)) return SymbolToStringRegistry$1[sym]; - } + keyFor: function keyFor(sym) { + if (!isSymbol(sym)) throw TypeError(tryToString(sym) + ' is not a symbol'); + if (hasOwnProperty_1(SymbolToStringRegistry$1, sym)) return SymbolToStringRegistry$1[sym]; + } }); var $stringify = getBuiltIn('JSON', 'stringify'); @@ -1562,52 +1561,52 @@ var hi = /^[\uDC00-\uDFFF]$/; var WRONG_SYMBOLS_CONVERSION = !nativeSymbol || fails(function () { - var symbol = getBuiltIn('Symbol')(); - // MS Edge converts symbol values to JSON as {} - return $stringify([symbol]) != '[null]' - // WebKit converts symbol values to JSON as null - || $stringify({ a: symbol }) != '{}' - // V8 throws on boxed symbols - || $stringify(Object(symbol)) != '{}'; + var symbol = getBuiltIn('Symbol')(); + // MS Edge converts symbol values to JSON as {} + return $stringify([symbol]) != '[null]' + // WebKit converts symbol values to JSON as null + || $stringify({ a: symbol }) != '{}' + // V8 throws on boxed symbols + || $stringify(Object(symbol)) != '{}'; }); // https://github.com/tc39/proposal-well-formed-stringify var ILL_FORMED_UNICODE = fails(function () { - return $stringify('\uDF06\uD834') !== '"\\udf06\\ud834"' - || $stringify('\uDEAD') !== '"\\udead"'; + return $stringify('\uDF06\uD834') !== '"\\udf06\\ud834"' + || $stringify('\uDEAD') !== '"\\udead"'; }); var stringifyWithSymbolsFix = function (it, replacer) { - var args = arraySlice(arguments); - var $replacer = replacer; - if (!isObject(replacer) && it === undefined || isSymbol(it)) return; // IE8 returns string on undefined - if (!isArray(replacer)) replacer = function (key, value) { - if (isCallable($replacer)) value = functionCall($replacer, this, key, value); - if (!isSymbol(value)) return value; - }; - args[1] = replacer; - return functionApply($stringify, null, args); + var args = arraySlice(arguments); + var $replacer = replacer; + if (!isObject(replacer) && it === undefined || isSymbol(it)) return; // IE8 returns string on undefined + if (!isArray(replacer)) replacer = function (key, value) { + if (isCallable($replacer)) value = functionCall($replacer, this, key, value); + if (!isSymbol(value)) return value; + }; + args[1] = replacer; + return functionApply($stringify, null, args); }; var fixIllFormed = function (match, offset, string) { - var prev = charAt(string, offset - 1); - var next = charAt(string, offset + 1); - if ((exec$1(low, match) && !exec$1(hi, next)) || (exec$1(hi, match) && !exec$1(low, prev))) { - return '\\u' + numberToString(charCodeAt(match, 0), 16); - } return match; + var prev = charAt(string, offset - 1); + var next = charAt(string, offset + 1); + if ((exec$1(low, match) && !exec$1(hi, next)) || (exec$1(hi, match) && !exec$1(low, prev))) { + return '\\u' + numberToString(charCodeAt(match, 0), 16); + } return match; }; if ($stringify) { - // `JSON.stringify` method - // https://tc39.es/ecma262/#sec-json.stringify - _export({ target: 'JSON', stat: true, arity: 3, forced: WRONG_SYMBOLS_CONVERSION || ILL_FORMED_UNICODE }, { - // eslint-disable-next-line no-unused-vars -- required for `.length` - stringify: function stringify(it, replacer, space) { - var args = arraySlice(arguments); - var result = functionApply(WRONG_SYMBOLS_CONVERSION ? stringifyWithSymbolsFix : $stringify, null, args); - return ILL_FORMED_UNICODE && typeof result == 'string' ? replace(result, tester, fixIllFormed) : result; - } - }); + // `JSON.stringify` method + // https://tc39.es/ecma262/#sec-json.stringify + _export({ target: 'JSON', stat: true, arity: 3, forced: WRONG_SYMBOLS_CONVERSION || ILL_FORMED_UNICODE }, { + // eslint-disable-next-line no-unused-vars -- required for `.length` + stringify: function stringify(it, replacer, space) { + var args = arraySlice(arguments); + var result = functionApply(WRONG_SYMBOLS_CONVERSION ? stringifyWithSymbolsFix : $stringify, null, args); + return ILL_FORMED_UNICODE && typeof result == 'string' ? replace(result, tester, fixIllFormed) : result; + } + }); } // V8 ~ Chrome 38 and 39 `Object.getOwnPropertySymbols` fails on primitives @@ -1617,10 +1616,10 @@ // `Object.getOwnPropertySymbols` method // https://tc39.es/ecma262/#sec-object.getownpropertysymbols _export({ target: 'Object', stat: true, forced: FORCED$1 }, { - getOwnPropertySymbols: function getOwnPropertySymbols(it) { - var $getOwnPropertySymbols = objectGetOwnPropertySymbols.f; - return $getOwnPropertySymbols ? $getOwnPropertySymbols(toObject(it)) : []; - } + getOwnPropertySymbols: function getOwnPropertySymbols(it) { + var $getOwnPropertySymbols = objectGetOwnPropertySymbols.f; + return $getOwnPropertySymbols ? $getOwnPropertySymbols(toObject(it)) : []; + } }); var getOwnPropertySymbols = path.Object.getOwnPropertySymbols; @@ -1632,17 +1631,17 @@ var SPECIES$1 = wellKnownSymbol('species'); var arrayMethodHasSpeciesSupport = function (METHOD_NAME) { - // We can't use this feature detection in V8 since it causes - // deoptimization and serious performance degradation - // https://github.com/zloirock/core-js/issues/677 - return engineV8Version >= 51 || !fails(function () { - var array = []; - var constructor = array.constructor = {}; - constructor[SPECIES$1] = function () { - return { foo: 1 }; - }; - return array[METHOD_NAME](Boolean).foo !== 1; - }); + // We can't use this feature detection in V8 since it causes + // deoptimization and serious performance degradation + // https://github.com/zloirock/core-js/issues/677 + return engineV8Version >= 51 || !fails(function () { + var array = []; + var constructor = array.constructor = {}; + constructor[SPECIES$1] = function () { + return { foo: 1 }; + }; + return array[METHOD_NAME](Boolean).foo !== 1; + }); }; var $filter = arrayIteration.filter; @@ -1654,13 +1653,13 @@ // https://tc39.es/ecma262/#sec-array.prototype.filter // with adding support of @@species _export({ target: 'Array', proto: true, forced: !HAS_SPECIES_SUPPORT }, { - filter: function filter(callbackfn /* , thisArg */) { - return $filter(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined); - } + filter: function filter(callbackfn /* , thisArg */) { + return $filter(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined); + } }); var entryVirtual = function (CONSTRUCTOR) { - return path[CONSTRUCTOR + 'Prototype']; + return path[CONSTRUCTOR + 'Prototype']; }; var filter = entryVirtual('Array').filter; @@ -1668,8 +1667,8 @@ var ArrayPrototype = Array.prototype; var filter$1 = function (it) { - var own = it.filter; - return it === ArrayPrototype || (objectIsPrototypeOf(ArrayPrototype, it) && own === ArrayPrototype.filter) ? filter : own; + var own = it.filter; + return it === ArrayPrototype || (objectIsPrototypeOf(ArrayPrototype, it) && own === ArrayPrototype.filter) ? filter : own; }; var filter$2 = filter$1; @@ -1685,19 +1684,19 @@ // `Object.getOwnPropertyDescriptor` method // https://tc39.es/ecma262/#sec-object.getownpropertydescriptor _export({ target: 'Object', stat: true, forced: FORCED$2, sham: !descriptors }, { - getOwnPropertyDescriptor: function getOwnPropertyDescriptor(it, key) { - return nativeGetOwnPropertyDescriptor$1(toIndexedObject(it), key); - } + getOwnPropertyDescriptor: function getOwnPropertyDescriptor(it, key) { + return nativeGetOwnPropertyDescriptor$1(toIndexedObject(it), key); + } }); var getOwnPropertyDescriptor_1 = createCommonjsModule(function (module) { - var Object = path.Object; + var Object = path.Object; - var getOwnPropertyDescriptor = module.exports = function getOwnPropertyDescriptor(it, key) { - return Object.getOwnPropertyDescriptor(it, key); - }; + var getOwnPropertyDescriptor = module.exports = function getOwnPropertyDescriptor(it, key) { + return Object.getOwnPropertyDescriptor(it, key); + }; - if (Object.getOwnPropertyDescriptor.sham) getOwnPropertyDescriptor.sham = true; + if (Object.getOwnPropertyDescriptor.sham) getOwnPropertyDescriptor.sham = true; }); var getOwnPropertyDescriptor$2 = getOwnPropertyDescriptor_1; @@ -1716,16 +1715,16 @@ var CONFIGURABLE$1 = EXISTS$1 && (!descriptors || (descriptors && getDescriptor(FunctionPrototype$2, 'name').configurable)); var functionName = { - EXISTS: EXISTS$1, - PROPER: PROPER, - CONFIGURABLE: CONFIGURABLE$1 + EXISTS: EXISTS$1, + PROPER: PROPER, + CONFIGURABLE: CONFIGURABLE$1 }; var correctPrototypeGetter = !fails(function () { - function F() { /* empty */ } - F.prototype.constructor = null; - // eslint-disable-next-line es-x/no-object-getprototypeof -- required for testing - return Object.getPrototypeOf(new F()) !== F.prototype; + function F() { /* empty */ } + F.prototype.constructor = null; + // eslint-disable-next-line es-x/no-object-getprototypeof -- required for testing + return Object.getPrototypeOf(new F()) !== F.prototype; }); var IE_PROTO$1 = sharedKey('IE_PROTO'); @@ -1735,12 +1734,12 @@ // `Object.getPrototypeOf` method // https://tc39.es/ecma262/#sec-object.getprototypeof var objectGetPrototypeOf = correctPrototypeGetter ? Object$5.getPrototypeOf : function (O) { - var object = toObject(O); - if (hasOwnProperty_1(object, IE_PROTO$1)) return object[IE_PROTO$1]; - var constructor = object.constructor; - if (isCallable(constructor) && object instanceof constructor) { - return constructor.prototype; - } return object instanceof Object$5 ? ObjectPrototype$2 : null; + var object = toObject(O); + if (hasOwnProperty_1(object, IE_PROTO$1)) return object[IE_PROTO$1]; + var constructor = object.constructor; + if (isCallable(constructor) && object instanceof constructor) { + return constructor.prototype; + } return object instanceof Object$5 ? ObjectPrototype$2 : null; }; var ITERATOR = wellKnownSymbol('iterator'); @@ -1752,19 +1751,19 @@ /* eslint-disable es-x/no-array-prototype-keys -- safe */ if ([].keys) { - arrayIterator = [].keys(); - // Safari 8 has buggy iterators w/o `next` - if (!('next' in arrayIterator)) BUGGY_SAFARI_ITERATORS = true; - else { - PrototypeOfArrayIteratorPrototype = objectGetPrototypeOf(objectGetPrototypeOf(arrayIterator)); - if (PrototypeOfArrayIteratorPrototype !== Object.prototype) IteratorPrototype = PrototypeOfArrayIteratorPrototype; - } + arrayIterator = [].keys(); + // Safari 8 has buggy iterators w/o `next` + if (!('next' in arrayIterator)) BUGGY_SAFARI_ITERATORS = true; + else { + PrototypeOfArrayIteratorPrototype = objectGetPrototypeOf(objectGetPrototypeOf(arrayIterator)); + if (PrototypeOfArrayIteratorPrototype !== Object.prototype) IteratorPrototype = PrototypeOfArrayIteratorPrototype; + } } var NEW_ITERATOR_PROTOTYPE = IteratorPrototype == undefined || fails(function () { - var test = {}; - // FF44- legacy iterators case - return IteratorPrototype[ITERATOR].call(test) !== test; + var test = {}; + // FF44- legacy iterators case + return IteratorPrototype[ITERATOR].call(test) !== test; }); if (NEW_ITERATOR_PROTOTYPE) IteratorPrototype = {}; @@ -1773,14 +1772,14 @@ // `%IteratorPrototype%[@@iterator]()` method // https://tc39.es/ecma262/#sec-%iteratorprototype%-@@iterator if (!isCallable(IteratorPrototype[ITERATOR])) { - defineBuiltIn(IteratorPrototype, ITERATOR, function () { - return this; - }); + defineBuiltIn(IteratorPrototype, ITERATOR, function () { + return this; + }); } var iteratorsCore = { - IteratorPrototype: IteratorPrototype, - BUGGY_SAFARI_ITERATORS: BUGGY_SAFARI_ITERATORS + IteratorPrototype: IteratorPrototype, + BUGGY_SAFARI_ITERATORS: BUGGY_SAFARI_ITERATORS }; var IteratorPrototype$1 = iteratorsCore.IteratorPrototype; @@ -1792,19 +1791,19 @@ var returnThis = function () { return this; }; var createIteratorConstructor = function (IteratorConstructor, NAME, next, ENUMERABLE_NEXT) { - var TO_STRING_TAG = NAME + ' Iterator'; - IteratorConstructor.prototype = objectCreate(IteratorPrototype$1, { next: createPropertyDescriptor(+!ENUMERABLE_NEXT, next) }); - setToStringTag(IteratorConstructor, TO_STRING_TAG, false, true); - iterators[TO_STRING_TAG] = returnThis; - return IteratorConstructor; + var TO_STRING_TAG = NAME + ' Iterator'; + IteratorConstructor.prototype = objectCreate(IteratorPrototype$1, { next: createPropertyDescriptor(+!ENUMERABLE_NEXT, next) }); + setToStringTag(IteratorConstructor, TO_STRING_TAG, false, true); + iterators[TO_STRING_TAG] = returnThis; + return IteratorConstructor; }; var String$4 = global_1.String; var TypeError$a = global_1.TypeError; var aPossiblePrototype = function (argument) { - if (typeof argument == 'object' || isCallable(argument)) return argument; - throw TypeError$a("Can't set " + String$4(argument) + ' as a prototype'); + if (typeof argument == 'object' || isCallable(argument)) return argument; + throw TypeError$a("Can't set " + String$4(argument) + ' as a prototype'); }; /* eslint-disable no-proto -- safe */ @@ -1817,22 +1816,22 @@ // Works with __proto__ only. Old v8 can't work with null proto objects. // eslint-disable-next-line es-x/no-object-setprototypeof -- safe var objectSetPrototypeOf = Object.setPrototypeOf || ('__proto__' in {} ? function () { - var CORRECT_SETTER = false; - var test = {}; - var setter; - try { - // eslint-disable-next-line es-x/no-object-getownpropertydescriptor -- safe - setter = functionUncurryThis(Object.getOwnPropertyDescriptor(Object.prototype, '__proto__').set); - setter(test, []); - CORRECT_SETTER = test instanceof Array; - } catch (error) { /* empty */ } - return function setPrototypeOf(O, proto) { - anObject(O); - aPossiblePrototype(proto); - if (CORRECT_SETTER) setter(O, proto); - else O.__proto__ = proto; - return O; - }; + var CORRECT_SETTER = false; + var test = {}; + var setter; + try { + // eslint-disable-next-line es-x/no-object-getownpropertydescriptor -- safe + setter = functionUncurryThis(Object.getOwnPropertyDescriptor(Object.prototype, '__proto__').set); + setter(test, []); + CORRECT_SETTER = test instanceof Array; + } catch (error) { /* empty */ } + return function setPrototypeOf(O, proto) { + anObject(O); + aPossiblePrototype(proto); + if (CORRECT_SETTER) setter(O, proto); + else O.__proto__ = proto; + return O; + }; }() : undefined); var PROPER_FUNCTION_NAME = functionName.PROPER; @@ -1845,67 +1844,67 @@ var returnThis$1 = function () { return this; }; var defineIterator = function (Iterable, NAME, IteratorConstructor, next, DEFAULT, IS_SET, FORCED) { - createIteratorConstructor(IteratorConstructor, NAME, next); - - var getIterationMethod = function (KIND) { - if (KIND === DEFAULT && defaultIterator) return defaultIterator; - if (!BUGGY_SAFARI_ITERATORS$1 && KIND in IterablePrototype) return IterablePrototype[KIND]; - switch (KIND) { - case KEYS: return function keys() { return new IteratorConstructor(this, KIND); }; - case VALUES: return function values() { return new IteratorConstructor(this, KIND); }; - case ENTRIES: return function entries() { return new IteratorConstructor(this, KIND); }; - } return function () { return new IteratorConstructor(this); }; - }; - - var TO_STRING_TAG = NAME + ' Iterator'; - var INCORRECT_VALUES_NAME = false; - var IterablePrototype = Iterable.prototype; - var nativeIterator = IterablePrototype[ITERATOR$1] - || IterablePrototype['@@iterator'] - || DEFAULT && IterablePrototype[DEFAULT]; - var defaultIterator = !BUGGY_SAFARI_ITERATORS$1 && nativeIterator || getIterationMethod(DEFAULT); - var anyNativeIterator = NAME == 'Array' ? IterablePrototype.entries || nativeIterator : nativeIterator; - var CurrentIteratorPrototype, methods, KEY; - - // fix native - if (anyNativeIterator) { - CurrentIteratorPrototype = objectGetPrototypeOf(anyNativeIterator.call(new Iterable())); - if (CurrentIteratorPrototype !== Object.prototype && CurrentIteratorPrototype.next) { - // Set @@toStringTag to native iterators - setToStringTag(CurrentIteratorPrototype, TO_STRING_TAG, true, true); - iterators[TO_STRING_TAG] = returnThis$1; - } - } - - // fix Array.prototype.{ values, @@iterator }.name in V8 / FF - if (PROPER_FUNCTION_NAME && DEFAULT == VALUES && nativeIterator && nativeIterator.name !== VALUES) { - { - INCORRECT_VALUES_NAME = true; - defaultIterator = function values() { return functionCall(nativeIterator, this); }; - } - } - - // export additional methods - if (DEFAULT) { - methods = { - values: getIterationMethod(VALUES), - keys: IS_SET ? defaultIterator : getIterationMethod(KEYS), - entries: getIterationMethod(ENTRIES) - }; - if (FORCED) for (KEY in methods) { - if (BUGGY_SAFARI_ITERATORS$1 || INCORRECT_VALUES_NAME || !(KEY in IterablePrototype)) { - defineBuiltIn(IterablePrototype, KEY, methods[KEY]); - } - } else _export({ target: NAME, proto: true, forced: BUGGY_SAFARI_ITERATORS$1 || INCORRECT_VALUES_NAME }, methods); - } - - // define iterator - if ((FORCED) && IterablePrototype[ITERATOR$1] !== defaultIterator) { - defineBuiltIn(IterablePrototype, ITERATOR$1, defaultIterator, { name: DEFAULT }); - } - iterators[NAME] = defaultIterator; - - return methods; + createIteratorConstructor(IteratorConstructor, NAME, next); + + var getIterationMethod = function (KIND) { + if (KIND === DEFAULT && defaultIterator) return defaultIterator; + if (!BUGGY_SAFARI_ITERATORS$1 && KIND in IterablePrototype) return IterablePrototype[KIND]; + switch (KIND) { + case KEYS: return function keys() { return new IteratorConstructor(this, KIND); }; + case VALUES: return function values() { return new IteratorConstructor(this, KIND); }; + case ENTRIES: return function entries() { return new IteratorConstructor(this, KIND); }; + } return function () { return new IteratorConstructor(this); }; + }; + + var TO_STRING_TAG = NAME + ' Iterator'; + var INCORRECT_VALUES_NAME = false; + var IterablePrototype = Iterable.prototype; + var nativeIterator = IterablePrototype[ITERATOR$1] + || IterablePrototype['@@iterator'] + || DEFAULT && IterablePrototype[DEFAULT]; + var defaultIterator = !BUGGY_SAFARI_ITERATORS$1 && nativeIterator || getIterationMethod(DEFAULT); + var anyNativeIterator = NAME == 'Array' ? IterablePrototype.entries || nativeIterator : nativeIterator; + var CurrentIteratorPrototype, methods, KEY; + + // fix native + if (anyNativeIterator) { + CurrentIteratorPrototype = objectGetPrototypeOf(anyNativeIterator.call(new Iterable())); + if (CurrentIteratorPrototype !== Object.prototype && CurrentIteratorPrototype.next) { + // Set @@toStringTag to native iterators + setToStringTag(CurrentIteratorPrototype, TO_STRING_TAG, true, true); + iterators[TO_STRING_TAG] = returnThis$1; + } + } + + // fix Array.prototype.{ values, @@iterator }.name in V8 / FF + if (PROPER_FUNCTION_NAME && DEFAULT == VALUES && nativeIterator && nativeIterator.name !== VALUES) { + { + INCORRECT_VALUES_NAME = true; + defaultIterator = function values() { return functionCall(nativeIterator, this); }; + } + } + + // export additional methods + if (DEFAULT) { + methods = { + values: getIterationMethod(VALUES), + keys: IS_SET ? defaultIterator : getIterationMethod(KEYS), + entries: getIterationMethod(ENTRIES) + }; + if (FORCED) for (KEY in methods) { + if (BUGGY_SAFARI_ITERATORS$1 || INCORRECT_VALUES_NAME || !(KEY in IterablePrototype)) { + defineBuiltIn(IterablePrototype, KEY, methods[KEY]); + } + } else _export({ target: NAME, proto: true, forced: BUGGY_SAFARI_ITERATORS$1 || INCORRECT_VALUES_NAME }, methods); + } + + // define iterator + if (( FORCED) && IterablePrototype[ITERATOR$1] !== defaultIterator) { + defineBuiltIn(IterablePrototype, ITERATOR$1, defaultIterator, { name: DEFAULT }); + } + iterators[NAME] = defaultIterator; + + return methods; }; var ARRAY_ITERATOR = 'Array Iterator'; @@ -1923,26 +1922,26 @@ // `CreateArrayIterator` internal method // https://tc39.es/ecma262/#sec-createarrayiterator var es_array_iterator = defineIterator(Array, 'Array', function (iterated, kind) { - setInternalState$1(this, { - type: ARRAY_ITERATOR, - target: toIndexedObject(iterated), // target - index: 0, // next index - kind: kind // kind - }); - // `%ArrayIteratorPrototype%.next` method - // https://tc39.es/ecma262/#sec-%arrayiteratorprototype%.next + setInternalState$1(this, { + type: ARRAY_ITERATOR, + target: toIndexedObject(iterated), // target + index: 0, // next index + kind: kind // kind + }); + // `%ArrayIteratorPrototype%.next` method + // https://tc39.es/ecma262/#sec-%arrayiteratorprototype%.next }, function () { - var state = getInternalState$1(this); - var target = state.target; - var kind = state.kind; - var index = state.index++; - if (!target || index >= target.length) { - state.target = undefined; - return { value: undefined, done: true }; - } - if (kind == 'keys') return { value: index, done: false }; - if (kind == 'values') return { value: target[index], done: false }; - return { value: [index, target[index]], done: false }; + var state = getInternalState$1(this); + var target = state.target; + var kind = state.kind; + var index = state.index++; + if (!target || index >= target.length) { + state.target = undefined; + return { value: undefined, done: true }; + } + if (kind == 'keys') return { value: index, done: false }; + if (kind == 'values') return { value: target[index], done: false }; + return { value: [index, target[index]], done: false }; }, 'values'); // argumentsList[@@iterator] is %ArrayProto_values% @@ -1953,56 +1952,56 @@ // iterable DOM collections // flag - `iterable` interface - 'entries', 'keys', 'values', 'forEach' methods var domIterables = { - CSSRuleList: 0, - CSSStyleDeclaration: 0, - CSSValueList: 0, - ClientRectList: 0, - DOMRectList: 0, - DOMStringList: 0, - DOMTokenList: 1, - DataTransferItemList: 0, - FileList: 0, - HTMLAllCollection: 0, - HTMLCollection: 0, - HTMLFormElement: 0, - HTMLSelectElement: 0, - MediaList: 0, - MimeTypeArray: 0, - NamedNodeMap: 0, - NodeList: 1, - PaintRequestList: 0, - Plugin: 0, - PluginArray: 0, - SVGLengthList: 0, - SVGNumberList: 0, - SVGPathSegList: 0, - SVGPointList: 0, - SVGStringList: 0, - SVGTransformList: 0, - SourceBufferList: 0, - StyleSheetList: 0, - TextTrackCueList: 0, - TextTrackList: 0, - TouchList: 0 + CSSRuleList: 0, + CSSStyleDeclaration: 0, + CSSValueList: 0, + ClientRectList: 0, + DOMRectList: 0, + DOMStringList: 0, + DOMTokenList: 1, + DataTransferItemList: 0, + FileList: 0, + HTMLAllCollection: 0, + HTMLCollection: 0, + HTMLFormElement: 0, + HTMLSelectElement: 0, + MediaList: 0, + MimeTypeArray: 0, + NamedNodeMap: 0, + NodeList: 1, + PaintRequestList: 0, + Plugin: 0, + PluginArray: 0, + SVGLengthList: 0, + SVGNumberList: 0, + SVGPathSegList: 0, + SVGPointList: 0, + SVGStringList: 0, + SVGTransformList: 0, + SourceBufferList: 0, + StyleSheetList: 0, + TextTrackCueList: 0, + TextTrackList: 0, + TouchList: 0 }; var TO_STRING_TAG$3 = wellKnownSymbol('toStringTag'); for (var COLLECTION_NAME in domIterables) { - var Collection = global_1[COLLECTION_NAME]; - var CollectionPrototype = Collection && Collection.prototype; - if (CollectionPrototype && classof(CollectionPrototype) !== TO_STRING_TAG$3) { - createNonEnumerableProperty(CollectionPrototype, TO_STRING_TAG$3, COLLECTION_NAME); - } - iterators[COLLECTION_NAME] = iterators.Array; + var Collection = global_1[COLLECTION_NAME]; + var CollectionPrototype = Collection && Collection.prototype; + if (CollectionPrototype && classof(CollectionPrototype) !== TO_STRING_TAG$3) { + createNonEnumerableProperty(CollectionPrototype, TO_STRING_TAG$3, COLLECTION_NAME); + } + iterators[COLLECTION_NAME] = iterators.Array; } var arrayMethodIsStrict = function (METHOD_NAME, argument) { - var method = [][METHOD_NAME]; - return !!method && fails(function () { - // eslint-disable-next-line no-useless-call -- required for testing - method.call(null, argument || function () { return 1; }, 1); - }); + var method = [][METHOD_NAME]; + return !!method && fails(function () { + // eslint-disable-next-line no-useless-call -- required for testing + method.call(null, argument || function () { return 1; }, 1); + }); }; var $forEach$1 = arrayIteration.forEach; @@ -2013,15 +2012,15 @@ // `Array.prototype.forEach` method implementation // https://tc39.es/ecma262/#sec-array.prototype.foreach var arrayForEach = !STRICT_METHOD ? function forEach(callbackfn /* , thisArg */) { - return $forEach$1(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined); - // eslint-disable-next-line es-x/no-array-prototype-foreach -- safe + return $forEach$1(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined); + // eslint-disable-next-line es-x/no-array-prototype-foreach -- safe } : [].forEach; // `Array.prototype.forEach` method // https://tc39.es/ecma262/#sec-array.prototype.foreach // eslint-disable-next-line es-x/no-array-prototype-foreach -- safe _export({ target: 'Array', proto: true, forced: [].forEach != arrayForEach }, { - forEach: arrayForEach + forEach: arrayForEach }); var forEach = entryVirtual('Array').forEach; @@ -2031,14 +2030,14 @@ var ArrayPrototype$1 = Array.prototype; var DOMIterables = { - DOMTokenList: true, - NodeList: true + DOMTokenList: true, + NodeList: true }; var forEach$2 = function (it) { - var own = it.forEach; - return it === ArrayPrototype$1 || (objectIsPrototypeOf(ArrayPrototype$1, it) && own === ArrayPrototype$1.forEach) - || hasOwnProperty_1(DOMIterables, classof(it)) ? forEach$1 : own; + var own = it.forEach; + return it === ArrayPrototype$1 || (objectIsPrototypeOf(ArrayPrototype$1, it) && own === ArrayPrototype$1.forEach) + || hasOwnProperty_1(DOMIterables, classof(it)) ? forEach$1 : own; }; var forEach$3 = forEach$2; @@ -2047,27 +2046,27 @@ // all object keys, includes non-enumerable and symbols var ownKeys = getBuiltIn('Reflect', 'ownKeys') || function ownKeys(it) { - var keys = objectGetOwnPropertyNames.f(anObject(it)); - var getOwnPropertySymbols = objectGetOwnPropertySymbols.f; - return getOwnPropertySymbols ? concat$1(keys, getOwnPropertySymbols(it)) : keys; + var keys = objectGetOwnPropertyNames.f(anObject(it)); + var getOwnPropertySymbols = objectGetOwnPropertySymbols.f; + return getOwnPropertySymbols ? concat$1(keys, getOwnPropertySymbols(it)) : keys; }; // `Object.getOwnPropertyDescriptors` method // https://tc39.es/ecma262/#sec-object.getownpropertydescriptors _export({ target: 'Object', stat: true, sham: !descriptors }, { - getOwnPropertyDescriptors: function getOwnPropertyDescriptors(object) { - var O = toIndexedObject(object); - var getOwnPropertyDescriptor = objectGetOwnPropertyDescriptor.f; - var keys = ownKeys(O); - var result = {}; - var index = 0; - var key, descriptor; - while (keys.length > index) { - descriptor = getOwnPropertyDescriptor(O, key = keys[index++]); - if (descriptor !== undefined) createProperty(result, key, descriptor); - } - return result; - } + getOwnPropertyDescriptors: function getOwnPropertyDescriptors(object) { + var O = toIndexedObject(object); + var getOwnPropertyDescriptor = objectGetOwnPropertyDescriptor.f; + var keys = ownKeys(O); + var result = {}; + var index = 0; + var key, descriptor; + while (keys.length > index) { + descriptor = getOwnPropertyDescriptor(O, key = keys[index++]); + if (descriptor !== undefined) createProperty(result, key, descriptor); + } + return result; + } }); var getOwnPropertyDescriptors = path.Object.getOwnPropertyDescriptors; @@ -2082,17 +2081,17 @@ // https://tc39.es/ecma262/#sec-object.defineproperties // eslint-disable-next-line es-x/no-object-defineproperties -- safe _export({ target: 'Object', stat: true, forced: Object.defineProperties !== defineProperties, sham: !descriptors }, { - defineProperties: defineProperties + defineProperties: defineProperties }); var defineProperties_1 = createCommonjsModule(function (module) { - var Object = path.Object; + var Object = path.Object; - var defineProperties = module.exports = function defineProperties(T, D) { - return Object.defineProperties(T, D); - }; + var defineProperties = module.exports = function defineProperties(T, D) { + return Object.defineProperties(T, D); + }; - if (Object.defineProperties.sham) defineProperties.sham = true; + if (Object.defineProperties.sham) defineProperties.sham = true; }); var defineProperties$1 = defineProperties_1; @@ -2105,17 +2104,17 @@ // https://tc39.es/ecma262/#sec-object.defineproperty // eslint-disable-next-line es-x/no-object-defineproperty -- safe _export({ target: 'Object', stat: true, forced: Object.defineProperty !== defineProperty$3, sham: !descriptors }, { - defineProperty: defineProperty$3 + defineProperty: defineProperty$3 }); var defineProperty_1 = createCommonjsModule(function (module) { - var Object = path.Object; + var Object = path.Object; - var defineProperty = module.exports = function defineProperty(it, key, desc) { - return Object.defineProperty(it, key, desc); - }; + var defineProperty = module.exports = function defineProperty(it, key, desc) { + return Object.defineProperty(it, key, desc); + }; - if (Object.defineProperty.sham) defineProperty.sham = true; + if (Object.defineProperty.sham) defineProperty.sham = true; }); var defineProperty$4 = defineProperty_1; @@ -2123,13 +2122,13 @@ var defineProperty$5 = defineProperty$4; var classCallCheck = createCommonjsModule(function (module) { - function _classCallCheck(instance, Constructor) { - if (!(instance instanceof Constructor)) { - throw new TypeError("Cannot call a class as a function"); - } - } + function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } + } - module.exports = _classCallCheck, module.exports.__esModule = true, module.exports["default"] = module.exports; + module.exports = _classCallCheck, module.exports.__esModule = true, module.exports["default"] = module.exports; }); var _classCallCheck = unwrapExports(classCallCheck); @@ -2143,43 +2142,43 @@ var defineProperty$9 = defineProperty$8; var createClass = createCommonjsModule(function (module) { - function _defineProperties(target, props) { - for (var i = 0; i < props.length; i++) { - var descriptor = props[i]; - descriptor.enumerable = descriptor.enumerable || false; - descriptor.configurable = true; - if ("value" in descriptor) descriptor.writable = true; - - defineProperty$9(target, descriptor.key, descriptor); - } - } + function _defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; - function _createClass(Constructor, protoProps, staticProps) { - if (protoProps) _defineProperties(Constructor.prototype, protoProps); - if (staticProps) _defineProperties(Constructor, staticProps); + defineProperty$9(target, descriptor.key, descriptor); + } + } - defineProperty$9(Constructor, "prototype", { - writable: false - }); + function _createClass(Constructor, protoProps, staticProps) { + if (protoProps) _defineProperties(Constructor.prototype, protoProps); + if (staticProps) _defineProperties(Constructor, staticProps); - return Constructor; - } + defineProperty$9(Constructor, "prototype", { + writable: false + }); - module.exports = _createClass, module.exports.__esModule = true, module.exports["default"] = module.exports; + return Constructor; + } + + module.exports = _createClass, module.exports.__esModule = true, module.exports["default"] = module.exports; }); var _createClass = unwrapExports(createClass); var assertThisInitialized = createCommonjsModule(function (module) { - function _assertThisInitialized(self) { - if (self === void 0) { - throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); - } + function _assertThisInitialized(self) { + if (self === void 0) { + throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); + } - return self; - } + return self; + } - module.exports = _assertThisInitialized, module.exports.__esModule = true, module.exports["default"] = module.exports; + module.exports = _assertThisInitialized, module.exports.__esModule = true, module.exports["default"] = module.exports; }); var _assertThisInitialized = unwrapExports(assertThisInitialized); @@ -2192,13 +2191,13 @@ // `Object.create` method // https://tc39.es/ecma262/#sec-object.create _export({ target: 'Object', stat: true, sham: !descriptors }, { - create: objectCreate + create: objectCreate }); var Object$6 = path.Object; var create = function create(P, D) { - return Object$6.create(P, D); + return Object$6.create(P, D); }; var create$1 = create; @@ -2214,7 +2213,7 @@ // `Object.setPrototypeOf` method // https://tc39.es/ecma262/#sec-object.setprototypeof _export({ target: 'Object', stat: true }, { - setPrototypeOf: objectSetPrototypeOf + setPrototypeOf: objectSetPrototypeOf }); var setPrototypeOf = path.Object.setPrototypeOf; @@ -2230,41 +2229,41 @@ var setPrototypeOf$5 = setPrototypeOf$4; var setPrototypeOf$6 = createCommonjsModule(function (module) { - function _setPrototypeOf(o, p) { - module.exports = _setPrototypeOf = setPrototypeOf$5 || function _setPrototypeOf(o, p) { - o.__proto__ = p; - return o; - }, module.exports.__esModule = true, module.exports["default"] = module.exports; - return _setPrototypeOf(o, p); - } + function _setPrototypeOf(o, p) { + module.exports = _setPrototypeOf = setPrototypeOf$5 || function _setPrototypeOf(o, p) { + o.__proto__ = p; + return o; + }, module.exports.__esModule = true, module.exports["default"] = module.exports; + return _setPrototypeOf(o, p); + } - module.exports = _setPrototypeOf, module.exports.__esModule = true, module.exports["default"] = module.exports; + module.exports = _setPrototypeOf, module.exports.__esModule = true, module.exports["default"] = module.exports; }); unwrapExports(setPrototypeOf$6); var inherits = createCommonjsModule(function (module) { - function _inherits(subClass, superClass) { - if (typeof superClass !== "function" && superClass !== null) { - throw new TypeError("Super expression must either be null or a function"); - } + function _inherits(subClass, superClass) { + if (typeof superClass !== "function" && superClass !== null) { + throw new TypeError("Super expression must either be null or a function"); + } - subClass.prototype = create$5(superClass && superClass.prototype, { - constructor: { - value: subClass, - writable: true, - configurable: true - } - }); + subClass.prototype = create$5(superClass && superClass.prototype, { + constructor: { + value: subClass, + writable: true, + configurable: true + } + }); - defineProperty$9(subClass, "prototype", { - writable: false - }); + defineProperty$9(subClass, "prototype", { + writable: false + }); - if (superClass) setPrototypeOf$6(subClass, superClass); - } + if (superClass) setPrototypeOf$6(subClass, superClass); + } - module.exports = _inherits, module.exports.__esModule = true, module.exports["default"] = module.exports; + module.exports = _inherits, module.exports.__esModule = true, module.exports["default"] = module.exports; }); var _inherits = unwrapExports(inherits); @@ -2278,17 +2277,17 @@ // deoptimization and serious performance degradation // https://github.com/zloirock/core-js/issues/679 var IS_CONCAT_SPREADABLE_SUPPORT = engineV8Version >= 51 || !fails(function () { - var array = []; - array[IS_CONCAT_SPREADABLE] = false; - return array.concat()[0] !== array; + var array = []; + array[IS_CONCAT_SPREADABLE] = false; + return array.concat()[0] !== array; }); var SPECIES_SUPPORT = arrayMethodHasSpeciesSupport('concat'); var isConcatSpreadable = function (O) { - if (!isObject(O)) return false; - var spreadable = O[IS_CONCAT_SPREADABLE]; - return spreadable !== undefined ? !!spreadable : isArray(O); + if (!isObject(O)) return false; + var spreadable = O[IS_CONCAT_SPREADABLE]; + return spreadable !== undefined ? !!spreadable : isArray(O); }; var FORCED$3 = !IS_CONCAT_SPREADABLE_SUPPORT || !SPECIES_SUPPORT; @@ -2297,26 +2296,26 @@ // https://tc39.es/ecma262/#sec-array.prototype.concat // with adding support of @@isConcatSpreadable and @@species _export({ target: 'Array', proto: true, arity: 1, forced: FORCED$3 }, { - // eslint-disable-next-line no-unused-vars -- required for `.length` - concat: function concat(arg) { - var O = toObject(this); - var A = arraySpeciesCreate(O, 0); - var n = 0; - var i, k, length, len, E; - for (i = -1, length = arguments.length; i < length; i++) { - E = i === -1 ? O : arguments[i]; - if (isConcatSpreadable(E)) { - len = lengthOfArrayLike(E); - if (n + len > MAX_SAFE_INTEGER) throw TypeError$b(MAXIMUM_ALLOWED_INDEX_EXCEEDED); - for (k = 0; k < len; k++, n++) if (k in E) createProperty(A, n, E[k]); - } else { - if (n >= MAX_SAFE_INTEGER) throw TypeError$b(MAXIMUM_ALLOWED_INDEX_EXCEEDED); - createProperty(A, n++, E); - } - } - A.length = n; - return A; - } + // eslint-disable-next-line no-unused-vars -- required for `.length` + concat: function concat(arg) { + var O = toObject(this); + var A = arraySpeciesCreate(O, 0); + var n = 0; + var i, k, length, len, E; + for (i = -1, length = arguments.length; i < length; i++) { + E = i === -1 ? O : arguments[i]; + if (isConcatSpreadable(E)) { + len = lengthOfArrayLike(E); + if (n + len > MAX_SAFE_INTEGER) throw TypeError$b(MAXIMUM_ALLOWED_INDEX_EXCEEDED); + for (k = 0; k < len; k++, n++) if (k in E) createProperty(A, n, E[k]); + } else { + if (n >= MAX_SAFE_INTEGER) throw TypeError$b(MAXIMUM_ALLOWED_INDEX_EXCEEDED); + createProperty(A, n++, E); + } + } + A.length = n; + return A; + } }); // `Symbol.asyncIterator` well-known symbol @@ -2437,31 +2436,31 @@ var stringSlice$1 = functionUncurryThis(''.slice); var createMethod$2 = function (CONVERT_TO_STRING) { - return function ($this, pos) { - var S = toString_1(requireObjectCoercible($this)); - var position = toIntegerOrInfinity(pos); - var size = S.length; - var first, second; - if (position < 0 || position >= size) return CONVERT_TO_STRING ? '' : undefined; - first = charCodeAt$1(S, position); - return first < 0xD800 || first > 0xDBFF || position + 1 === size - || (second = charCodeAt$1(S, position + 1)) < 0xDC00 || second > 0xDFFF - ? CONVERT_TO_STRING - ? charAt$1(S, position) - : first - : CONVERT_TO_STRING - ? stringSlice$1(S, position, position + 2) - : (first - 0xD800 << 10) + (second - 0xDC00) + 0x10000; - }; + return function ($this, pos) { + var S = toString_1(requireObjectCoercible($this)); + var position = toIntegerOrInfinity(pos); + var size = S.length; + var first, second; + if (position < 0 || position >= size) return CONVERT_TO_STRING ? '' : undefined; + first = charCodeAt$1(S, position); + return first < 0xD800 || first > 0xDBFF || position + 1 === size + || (second = charCodeAt$1(S, position + 1)) < 0xDC00 || second > 0xDFFF + ? CONVERT_TO_STRING + ? charAt$1(S, position) + : first + : CONVERT_TO_STRING + ? stringSlice$1(S, position, position + 2) + : (first - 0xD800 << 10) + (second - 0xDC00) + 0x10000; + }; }; var stringMultibyte = { - // `String.prototype.codePointAt` method - // https://tc39.es/ecma262/#sec-string.prototype.codepointat - codeAt: createMethod$2(false), - // `String.prototype.at` method - // https://github.com/mathiasbynens/String.prototype.at - charAt: createMethod$2(true) + // `String.prototype.codePointAt` method + // https://tc39.es/ecma262/#sec-string.prototype.codepointat + codeAt: createMethod$2(false), + // `String.prototype.at` method + // https://github.com/mathiasbynens/String.prototype.at + charAt: createMethod$2(true) }; var charAt$2 = stringMultibyte.charAt; @@ -2476,22 +2475,22 @@ // `String.prototype[@@iterator]` method // https://tc39.es/ecma262/#sec-string.prototype-@@iterator defineIterator(String, 'String', function (iterated) { - setInternalState$2(this, { - type: STRING_ITERATOR, - string: toString_1(iterated), - index: 0 - }); - // `%StringIteratorPrototype%.next` method - // https://tc39.es/ecma262/#sec-%stringiteratorprototype%.next + setInternalState$2(this, { + type: STRING_ITERATOR, + string: toString_1(iterated), + index: 0 + }); + // `%StringIteratorPrototype%.next` method + // https://tc39.es/ecma262/#sec-%stringiteratorprototype%.next }, function next() { - var state = getInternalState$2(this); - var string = state.string; - var index = state.index; - var point; - if (index >= string.length) return { value: undefined, done: true }; - point = charAt$2(string, index); - state.index += point.length; - return { value: point, done: false }; + var state = getInternalState$2(this); + var string = state.string; + var index = state.index; + var point; + if (index >= string.length) return { value: undefined, done: true }; + point = charAt$2(string, index); + state.index += point.length; + return { value: point, done: false }; }); var iterator = wellKnownSymbolWrapped.f('iterator'); @@ -2507,37 +2506,37 @@ var iterator$5 = iterator$4; var _typeof_1 = createCommonjsModule(function (module) { - function _typeof(obj) { - "@babel/helpers - typeof"; - - return (module.exports = _typeof = "function" == typeof symbol$5 && "symbol" == typeof iterator$5 ? function (obj) { - return typeof obj; - } : function (obj) { - return obj && "function" == typeof symbol$5 && obj.constructor === symbol$5 && obj !== symbol$5.prototype ? "symbol" : typeof obj; - }, module.exports.__esModule = true, module.exports["default"] = module.exports), _typeof(obj); - } + function _typeof(obj) { + "@babel/helpers - typeof"; + + return (module.exports = _typeof = "function" == typeof symbol$5 && "symbol" == typeof iterator$5 ? function (obj) { + return typeof obj; + } : function (obj) { + return obj && "function" == typeof symbol$5 && obj.constructor === symbol$5 && obj !== symbol$5.prototype ? "symbol" : typeof obj; + }, module.exports.__esModule = true, module.exports["default"] = module.exports), _typeof(obj); + } - module.exports = _typeof, module.exports.__esModule = true, module.exports["default"] = module.exports; + module.exports = _typeof, module.exports.__esModule = true, module.exports["default"] = module.exports; }); var _typeof = unwrapExports(_typeof_1); var possibleConstructorReturn = createCommonjsModule(function (module) { - var _typeof = _typeof_1["default"]; + var _typeof = _typeof_1["default"]; - function _possibleConstructorReturn(self, call) { - if (call && (_typeof(call) === "object" || typeof call === "function")) { - return call; - } else if (call !== void 0) { - throw new TypeError("Derived constructors may only return object or undefined"); - } + function _possibleConstructorReturn(self, call) { + if (call && (_typeof(call) === "object" || typeof call === "function")) { + return call; + } else if (call !== void 0) { + throw new TypeError("Derived constructors may only return object or undefined"); + } - return assertThisInitialized(self); - } + return assertThisInitialized(self); + } - module.exports = _possibleConstructorReturn, module.exports.__esModule = true, module.exports["default"] = module.exports; + module.exports = _possibleConstructorReturn, module.exports.__esModule = true, module.exports["default"] = module.exports; }); var _possibleConstructorReturn = unwrapExports(possibleConstructorReturn); @@ -2547,9 +2546,9 @@ // `Object.getPrototypeOf` method // https://tc39.es/ecma262/#sec-object.getprototypeof _export({ target: 'Object', stat: true, forced: FAILS_ON_PRIMITIVES$2, sham: !correctPrototypeGetter }, { - getPrototypeOf: function getPrototypeOf(it) { - return objectGetPrototypeOf(toObject(it)); - } + getPrototypeOf: function getPrototypeOf(it) { + return objectGetPrototypeOf(toObject(it)); + } }); var getPrototypeOf = path.Object.getPrototypeOf; @@ -2565,35 +2564,35 @@ var getPrototypeOf$5 = getPrototypeOf$4; var getPrototypeOf$6 = createCommonjsModule(function (module) { - function _getPrototypeOf(o) { - module.exports = _getPrototypeOf = setPrototypeOf$5 ? getPrototypeOf$5 : function _getPrototypeOf(o) { - return o.__proto__ || getPrototypeOf$5(o); - }, module.exports.__esModule = true, module.exports["default"] = module.exports; - return _getPrototypeOf(o); - } + function _getPrototypeOf(o) { + module.exports = _getPrototypeOf = setPrototypeOf$5 ? getPrototypeOf$5 : function _getPrototypeOf(o) { + return o.__proto__ || getPrototypeOf$5(o); + }, module.exports.__esModule = true, module.exports["default"] = module.exports; + return _getPrototypeOf(o); + } - module.exports = _getPrototypeOf, module.exports.__esModule = true, module.exports["default"] = module.exports; + module.exports = _getPrototypeOf, module.exports.__esModule = true, module.exports["default"] = module.exports; }); var _getPrototypeOf = unwrapExports(getPrototypeOf$6); var defineProperty$a = createCommonjsModule(function (module) { - function _defineProperty(obj, key, value) { - if (key in obj) { - defineProperty$9(obj, key, { - value: value, - enumerable: true, - configurable: true, - writable: true - }); - } else { - obj[key] = value; - } - - return obj; - } - - module.exports = _defineProperty, module.exports.__esModule = true, module.exports["default"] = module.exports; + function _defineProperty(obj, key, value) { + if (key in obj) { + defineProperty$9(obj, key, { + value: value, + enumerable: true, + configurable: true, + writable: true + }); + } else { + obj[key] = value; + } + + return obj; + } + + module.exports = _defineProperty, module.exports.__esModule = true, module.exports["default"] = module.exports; }); var _defineProperty = unwrapExports(defineProperty$a); @@ -2603,8 +2602,8 @@ var ArrayPrototype$2 = Array.prototype; var concat$3 = function (it) { - var own = it.concat; - return it === ArrayPrototype$2 || (objectIsPrototypeOf(ArrayPrototype$2, it) && own === ArrayPrototype$2.concat) ? concat$2 : own; + var own = it.concat; + return it === ArrayPrototype$2 || (objectIsPrototypeOf(ArrayPrototype$2, it) && own === ArrayPrototype$2.concat) ? concat$2 : own; }; var concat$4 = concat$3; @@ -2618,7 +2617,7 @@ // `Function.prototype.bind` method // https://tc39.es/ecma262/#sec-function.prototype.bind _export({ target: 'Function', proto: true, forced: Function.bind !== functionBind }, { - bind: functionBind + bind: functionBind }); var bind$2 = entryVirtual('Function').bind; @@ -2626,8 +2625,8 @@ var FunctionPrototype$3 = Function.prototype; var bind$3 = function (it) { - var own = it.bind; - return it === FunctionPrototype$3 || (objectIsPrototypeOf(FunctionPrototype$3, it) && own === FunctionPrototype$3.bind) ? bind$2 : own; + var own = it.bind; + return it === FunctionPrototype$3 || (objectIsPrototypeOf(FunctionPrototype$3, it) && own === FunctionPrototype$3.bind) ? bind$2 : own; }; var bind$4 = bind$3; @@ -2637,33 +2636,33 @@ var TypeError$c = global_1.TypeError; var validateArgumentsLength = function (passed, required) { - if (passed < required) throw TypeError$c('Not enough arguments'); - return passed; + if (passed < required) throw TypeError$c('Not enough arguments'); + return passed; }; var MSIE = /MSIE .\./.test(engineUserAgent); // <- dirty ie9- check var Function$2 = global_1.Function; var wrap$1 = function (scheduler) { - return MSIE ? function (handler, timeout /* , ...arguments */) { - var boundArgs = validateArgumentsLength(arguments.length, 1) > 2; - var fn = isCallable(handler) ? handler : Function$2(handler); - var args = boundArgs ? arraySlice(arguments, 2) : undefined; - return scheduler(boundArgs ? function () { - functionApply(fn, this, args); - } : fn, timeout); - } : scheduler; + return MSIE ? function (handler, timeout /* , ...arguments */) { + var boundArgs = validateArgumentsLength(arguments.length, 1) > 2; + var fn = isCallable(handler) ? handler : Function$2(handler); + var args = boundArgs ? arraySlice(arguments, 2) : undefined; + return scheduler(boundArgs ? function () { + functionApply(fn, this, args); + } : fn, timeout); + } : scheduler; }; // ie9- setTimeout & setInterval additional parameters fix // https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#timers var schedulersFix = { - // `setTimeout` method - // https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#dom-settimeout - setTimeout: wrap$1(global_1.setTimeout), - // `setInterval` method - // https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#dom-setinterval - setInterval: wrap$1(global_1.setInterval) + // `setTimeout` method + // https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#dom-settimeout + setTimeout: wrap$1(global_1.setTimeout), + // `setInterval` method + // https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#dom-setinterval + setInterval: wrap$1(global_1.setInterval) }; var setInterval$1 = schedulersFix.setInterval; @@ -2671,7 +2670,7 @@ // ie9- setInterval additional parameters fix // https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#dom-setinterval _export({ global: true, bind: true, forced: global_1.setInterval !== setInterval$1 }, { - setInterval: setInterval$1 + setInterval: setInterval$1 }); var setTimeout$1 = schedulersFix.setTimeout; @@ -2679,7 +2678,7 @@ // ie9- setTimeout additional parameters fix // https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#dom-settimeout _export({ global: true, bind: true, forced: global_1.setTimeout !== setTimeout$1 }, { - setTimeout: setTimeout$1 + setTimeout: setTimeout$1 }); var setTimeout$2 = path.setTimeout; @@ -2694,8 +2693,8 @@ * @memberOf ListCache */ function listCacheClear() { - this.__data__ = []; - this.size = 0; + this.__data__ = []; + this.size = 0; } var _listCacheClear = listCacheClear; @@ -2733,7 +2732,7 @@ * // => true */ function eq(value, other) { - return value === other || (value !== value && other !== other); + return value === other || (value !== value && other !== other); } var eq_1 = eq; @@ -2747,13 +2746,13 @@ * @returns {number} Returns the index of the matched value, else `-1`. */ function assocIndexOf(array, key) { - var length = array.length; - while (length--) { - if (eq_1(array[length][0], key)) { - return length; - } - } - return -1; + var length = array.length; + while (length--) { + if (eq_1(array[length][0], key)) { + return length; + } + } + return -1; } var _assocIndexOf = assocIndexOf; @@ -2774,20 +2773,20 @@ * @returns {boolean} Returns `true` if the entry was removed, else `false`. */ function listCacheDelete(key) { - var data = this.__data__, - index = _assocIndexOf(data, key); - - if (index < 0) { - return false; - } - var lastIndex = data.length - 1; - if (index == lastIndex) { - data.pop(); - } else { - splice.call(data, index, 1); - } - --this.size; - return true; + var data = this.__data__, + index = _assocIndexOf(data, key); + + if (index < 0) { + return false; + } + var lastIndex = data.length - 1; + if (index == lastIndex) { + data.pop(); + } else { + splice.call(data, index, 1); + } + --this.size; + return true; } var _listCacheDelete = listCacheDelete; @@ -2802,10 +2801,10 @@ * @returns {*} Returns the entry value. */ function listCacheGet(key) { - var data = this.__data__, - index = _assocIndexOf(data, key); + var data = this.__data__, + index = _assocIndexOf(data, key); - return index < 0 ? undefined : data[index][1]; + return index < 0 ? undefined : data[index][1]; } var _listCacheGet = listCacheGet; @@ -2820,7 +2819,7 @@ * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. */ function listCacheHas(key) { - return _assocIndexOf(this.__data__, key) > -1; + return _assocIndexOf(this.__data__, key) > -1; } var _listCacheHas = listCacheHas; @@ -2836,16 +2835,16 @@ * @returns {Object} Returns the list cache instance. */ function listCacheSet(key, value) { - var data = this.__data__, - index = _assocIndexOf(data, key); - - if (index < 0) { - ++this.size; - data.push([key, value]); - } else { - data[index][1] = value; - } - return this; + var data = this.__data__, + index = _assocIndexOf(data, key); + + if (index < 0) { + ++this.size; + data.push([key, value]); + } else { + data[index][1] = value; + } + return this; } var _listCacheSet = listCacheSet; @@ -2858,14 +2857,14 @@ * @param {Array} [entries] The key-value pairs to cache. */ function ListCache(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; + var index = -1, + length = entries == null ? 0 : entries.length; - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } } // Add methods to `ListCache`. @@ -2885,8 +2884,8 @@ * @memberOf Stack */ function stackClear() { - this.__data__ = new _ListCache; - this.size = 0; + this.__data__ = new _ListCache; + this.size = 0; } var _stackClear = stackClear; @@ -2901,11 +2900,11 @@ * @returns {boolean} Returns `true` if the entry was removed, else `false`. */ function stackDelete(key) { - var data = this.__data__, - result = data['delete'](key); + var data = this.__data__, + result = data['delete'](key); - this.size = data.size; - return result; + this.size = data.size; + return result; } var _stackDelete = stackDelete; @@ -2920,7 +2919,7 @@ * @returns {*} Returns the entry value. */ function stackGet(key) { - return this.__data__.get(key); + return this.__data__.get(key); } var _stackGet = stackGet; @@ -2935,7 +2934,7 @@ * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. */ function stackHas(key) { - return this.__data__.has(key); + return this.__data__.has(key); } var _stackHas = stackHas; @@ -2982,23 +2981,23 @@ * @returns {string} Returns the raw `toStringTag`. */ function getRawTag(value) { - var isOwn = hasOwnProperty$1.call(value, symToStringTag), - tag = value[symToStringTag]; - - try { - value[symToStringTag] = undefined; - var unmasked = true; - } catch (e) { } - - var result = nativeObjectToString.call(value); - if (unmasked) { - if (isOwn) { - value[symToStringTag] = tag; - } else { - delete value[symToStringTag]; - } - } - return result; + var isOwn = hasOwnProperty$1.call(value, symToStringTag), + tag = value[symToStringTag]; + + try { + value[symToStringTag] = undefined; + var unmasked = true; + } catch (e) {} + + var result = nativeObjectToString.call(value); + if (unmasked) { + if (isOwn) { + value[symToStringTag] = tag; + } else { + delete value[symToStringTag]; + } + } + return result; } var _getRawTag = getRawTag; @@ -3021,14 +3020,14 @@ * @returns {string} Returns the converted string. */ function objectToString$1(value) { - return nativeObjectToString$1.call(value); + return nativeObjectToString$1.call(value); } var _objectToString = objectToString$1; /** `Object#toString` result references. */ var nullTag = '[object Null]', - undefinedTag = '[object Undefined]'; + undefinedTag = '[object Undefined]'; /** Built-in value references. */ var symToStringTag$1 = _Symbol ? _Symbol.toStringTag : undefined; @@ -3041,12 +3040,12 @@ * @returns {string} Returns the `toStringTag`. */ function baseGetTag(value) { - if (value == null) { - return value === undefined ? undefinedTag : nullTag; - } - return (symToStringTag$1 && symToStringTag$1 in Object(value)) - ? _getRawTag(value) - : _objectToString(value); + if (value == null) { + return value === undefined ? undefinedTag : nullTag; + } + return (symToStringTag$1 && symToStringTag$1 in Object(value)) + ? _getRawTag(value) + : _objectToString(value); } var _baseGetTag = baseGetTag; @@ -3077,17 +3076,17 @@ * // => false */ function isObject$1(value) { - var type = typeof value; - return value != null && (type == 'object' || type == 'function'); + var type = typeof value; + return value != null && (type == 'object' || type == 'function'); } var isObject_1 = isObject$1; /** `Object#toString` result references. */ var asyncTag = '[object AsyncFunction]', - funcTag = '[object Function]', - genTag = '[object GeneratorFunction]', - proxyTag = '[object Proxy]'; + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + proxyTag = '[object Proxy]'; /** * Checks if `value` is classified as a `Function` object. @@ -3107,13 +3106,13 @@ * // => false */ function isFunction(value) { - if (!isObject_1(value)) { - return false; - } - // The use of `Object#toString` avoids issues with the `typeof` operator - // in Safari 9 which returns 'object' for typed arrays and other constructors. - var tag = _baseGetTag(value); - return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; + if (!isObject_1(value)) { + return false; + } + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 9 which returns 'object' for typed arrays and other constructors. + var tag = _baseGetTag(value); + return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; } var isFunction_1 = isFunction; @@ -3124,9 +3123,9 @@ var _coreJsData = coreJsData; /** Used to detect methods masquerading as native. */ - var maskSrcKey = (function () { - var uid = /[^.]+$/.exec(_coreJsData && _coreJsData.keys && _coreJsData.keys.IE_PROTO || ''); - return uid ? ('Symbol(src)_1.' + uid) : ''; + var maskSrcKey = (function() { + var uid = /[^.]+$/.exec(_coreJsData && _coreJsData.keys && _coreJsData.keys.IE_PROTO || ''); + return uid ? ('Symbol(src)_1.' + uid) : ''; }()); /** @@ -3137,7 +3136,7 @@ * @returns {boolean} Returns `true` if `func` is masked, else `false`. */ function isMasked(func) { - return !!maskSrcKey && (maskSrcKey in func); + return !!maskSrcKey && (maskSrcKey in func); } var _isMasked = isMasked; @@ -3156,15 +3155,15 @@ * @returns {string} Returns the source code. */ function toSource(func) { - if (func != null) { - try { - return funcToString.call(func); - } catch (e) { } - try { - return (func + ''); - } catch (e) { } - } - return ''; + if (func != null) { + try { + return funcToString.call(func); + } catch (e) {} + try { + return (func + ''); + } catch (e) {} + } + return ''; } var _toSource = toSource; @@ -3180,7 +3179,7 @@ /** Used for built-in method references. */ var funcProto$1 = Function.prototype, - objectProto$2 = Object.prototype; + objectProto$2 = Object.prototype; /** Used to resolve the decompiled source of functions. */ var funcToString$1 = funcProto$1.toString; @@ -3190,8 +3189,8 @@ /** Used to detect if a method is native. */ var reIsNative = RegExp('^' + - funcToString$1.call(hasOwnProperty$2).replace(reRegExpChar, '\\$&') - .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' + funcToString$1.call(hasOwnProperty$2).replace(reRegExpChar, '\\$&') + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' ); /** @@ -3203,11 +3202,11 @@ * else `false`. */ function baseIsNative(value) { - if (!isObject_1(value) || _isMasked(value)) { - return false; - } - var pattern = isFunction_1(value) ? reIsNative : reIsHostCtor; - return pattern.test(_toSource(value)); + if (!isObject_1(value) || _isMasked(value)) { + return false; + } + var pattern = isFunction_1(value) ? reIsNative : reIsHostCtor; + return pattern.test(_toSource(value)); } var _baseIsNative = baseIsNative; @@ -3221,7 +3220,7 @@ * @returns {*} Returns the property value. */ function getValue(object, key) { - return object == null ? undefined : object[key]; + return object == null ? undefined : object[key]; } var _getValue = getValue; @@ -3235,8 +3234,8 @@ * @returns {*} Returns the function if it's native, else `undefined`. */ function getNative(object, key) { - var value = _getValue(object, key); - return _baseIsNative(value) ? value : undefined; + var value = _getValue(object, key); + return _baseIsNative(value) ? value : undefined; } var _getNative = getNative; @@ -3259,8 +3258,8 @@ * @memberOf Hash */ function hashClear() { - this.__data__ = _nativeCreate ? _nativeCreate(null) : {}; - this.size = 0; + this.__data__ = _nativeCreate ? _nativeCreate(null) : {}; + this.size = 0; } var _hashClear = hashClear; @@ -3276,9 +3275,9 @@ * @returns {boolean} Returns `true` if the entry was removed, else `false`. */ function hashDelete(key) { - var result = this.has(key) && delete this.__data__[key]; - this.size -= result ? 1 : 0; - return result; + var result = this.has(key) && delete this.__data__[key]; + this.size -= result ? 1 : 0; + return result; } var _hashDelete = hashDelete; @@ -3302,12 +3301,12 @@ * @returns {*} Returns the entry value. */ function hashGet(key) { - var data = this.__data__; - if (_nativeCreate) { - var result = data[key]; - return result === HASH_UNDEFINED ? undefined : result; - } - return hasOwnProperty$3.call(data, key) ? data[key] : undefined; + var data = this.__data__; + if (_nativeCreate) { + var result = data[key]; + return result === HASH_UNDEFINED ? undefined : result; + } + return hasOwnProperty$3.call(data, key) ? data[key] : undefined; } var _hashGet = hashGet; @@ -3328,8 +3327,8 @@ * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. */ function hashHas(key) { - var data = this.__data__; - return _nativeCreate ? (data[key] !== undefined) : hasOwnProperty$4.call(data, key); + var data = this.__data__; + return _nativeCreate ? (data[key] !== undefined) : hasOwnProperty$4.call(data, key); } var _hashHas = hashHas; @@ -3348,10 +3347,10 @@ * @returns {Object} Returns the hash instance. */ function hashSet(key, value) { - var data = this.__data__; - this.size += this.has(key) ? 0 : 1; - data[key] = (_nativeCreate && value === undefined) ? HASH_UNDEFINED$1 : value; - return this; + var data = this.__data__; + this.size += this.has(key) ? 0 : 1; + data[key] = (_nativeCreate && value === undefined) ? HASH_UNDEFINED$1 : value; + return this; } var _hashSet = hashSet; @@ -3364,14 +3363,14 @@ * @param {Array} [entries] The key-value pairs to cache. */ function Hash(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; + var index = -1, + length = entries == null ? 0 : entries.length; - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } } // Add methods to `Hash`. @@ -3391,12 +3390,12 @@ * @memberOf MapCache */ function mapCacheClear() { - this.size = 0; - this.__data__ = { - 'hash': new _Hash, - 'map': new (_Map || _ListCache), - 'string': new _Hash - }; + this.size = 0; + this.__data__ = { + 'hash': new _Hash, + 'map': new (_Map || _ListCache), + 'string': new _Hash + }; } var _mapCacheClear = mapCacheClear; @@ -3409,10 +3408,10 @@ * @returns {boolean} Returns `true` if `value` is suitable, else `false`. */ function isKeyable(value) { - var type = typeof value; - return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') - ? (value !== '__proto__') - : (value === null); + var type = typeof value; + return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') + ? (value !== '__proto__') + : (value === null); } var _isKeyable = isKeyable; @@ -3426,10 +3425,10 @@ * @returns {*} Returns the map data. */ function getMapData(map, key) { - var data = map.__data__; - return _isKeyable(key) - ? data[typeof key == 'string' ? 'string' : 'hash'] - : data.map; + var data = map.__data__; + return _isKeyable(key) + ? data[typeof key == 'string' ? 'string' : 'hash'] + : data.map; } var _getMapData = getMapData; @@ -3444,9 +3443,9 @@ * @returns {boolean} Returns `true` if the entry was removed, else `false`. */ function mapCacheDelete(key) { - var result = _getMapData(this, key)['delete'](key); - this.size -= result ? 1 : 0; - return result; + var result = _getMapData(this, key)['delete'](key); + this.size -= result ? 1 : 0; + return result; } var _mapCacheDelete = mapCacheDelete; @@ -3461,7 +3460,7 @@ * @returns {*} Returns the entry value. */ function mapCacheGet(key) { - return _getMapData(this, key).get(key); + return _getMapData(this, key).get(key); } var _mapCacheGet = mapCacheGet; @@ -3476,7 +3475,7 @@ * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. */ function mapCacheHas(key) { - return _getMapData(this, key).has(key); + return _getMapData(this, key).has(key); } var _mapCacheHas = mapCacheHas; @@ -3492,12 +3491,12 @@ * @returns {Object} Returns the map cache instance. */ function mapCacheSet(key, value) { - var data = _getMapData(this, key), - size = data.size; + var data = _getMapData(this, key), + size = data.size; - data.set(key, value); - this.size += data.size == size ? 0 : 1; - return this; + data.set(key, value); + this.size += data.size == size ? 0 : 1; + return this; } var _mapCacheSet = mapCacheSet; @@ -3510,14 +3509,14 @@ * @param {Array} [entries] The key-value pairs to cache. */ function MapCache(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; + var index = -1, + length = entries == null ? 0 : entries.length; - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } } // Add methods to `MapCache`. @@ -3543,19 +3542,19 @@ * @returns {Object} Returns the stack cache instance. */ function stackSet(key, value) { - var data = this.__data__; - if (data instanceof _ListCache) { - var pairs = data.__data__; - if (!_Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) { - pairs.push([key, value]); - this.size = ++data.size; - return this; - } - data = this.__data__ = new _MapCache(pairs); - } - data.set(key, value); - this.size = data.size; - return this; + var data = this.__data__; + if (data instanceof _ListCache) { + var pairs = data.__data__; + if (!_Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) { + pairs.push([key, value]); + this.size = ++data.size; + return this; + } + data = this.__data__ = new _MapCache(pairs); + } + data.set(key, value); + this.size = data.size; + return this; } var _stackSet = stackSet; @@ -3568,8 +3567,8 @@ * @param {Array} [entries] The key-value pairs to cache. */ function Stack(entries) { - var data = this.__data__ = new _ListCache(entries); - this.size = data.size; + var data = this.__data__ = new _ListCache(entries); + this.size = data.size; } // Add methods to `Stack`. @@ -3581,12 +3580,12 @@ var _Stack = Stack; - var defineProperty$b = (function () { - try { - var func = _getNative(Object, 'defineProperty'); - func({}, '', {}); - return func; - } catch (e) { } + var defineProperty$b = (function() { + try { + var func = _getNative(Object, 'defineProperty'); + func({}, '', {}); + return func; + } catch (e) {} }()); var _defineProperty$1 = defineProperty$b; @@ -3601,16 +3600,16 @@ * @param {*} value The value to assign. */ function baseAssignValue(object, key, value) { - if (key == '__proto__' && _defineProperty$1) { - _defineProperty$1(object, key, { - 'configurable': true, - 'enumerable': true, - 'value': value, - 'writable': true - }); - } else { - object[key] = value; - } + if (key == '__proto__' && _defineProperty$1) { + _defineProperty$1(object, key, { + 'configurable': true, + 'enumerable': true, + 'value': value, + 'writable': true + }); + } else { + object[key] = value; + } } var _baseAssignValue = baseAssignValue; @@ -3625,10 +3624,10 @@ * @param {*} value The value to assign. */ function assignMergeValue(object, key, value) { - if ((value !== undefined && !eq_1(object[key], value)) || - (value === undefined && !(key in object))) { - _baseAssignValue(object, key, value); - } + if ((value !== undefined && !eq_1(object[key], value)) || + (value === undefined && !(key in object))) { + _baseAssignValue(object, key, value); + } } var _assignMergeValue = assignMergeValue; @@ -3641,20 +3640,20 @@ * @returns {Function} Returns the new base function. */ function createBaseFor(fromRight) { - return function (object, iteratee, keysFunc) { - var index = -1, - iterable = Object(object), - props = keysFunc(object), - length = props.length; - - while (length--) { - var key = props[fromRight ? length : ++index]; - if (iteratee(iterable[key], key, iterable) === false) { - break; - } - } - return object; - }; + return function(object, iteratee, keysFunc) { + var index = -1, + iterable = Object(object), + props = keysFunc(object), + length = props.length; + + while (length--) { + var key = props[fromRight ? length : ++index]; + if (iteratee(iterable[key], key, iterable) === false) { + break; + } + } + return object; + }; } var _createBaseFor = createBaseFor; @@ -3675,39 +3674,39 @@ var _baseFor = baseFor; var _cloneBuffer = createCommonjsModule(function (module, exports) { - /** Detect free variable `exports`. */ - var freeExports = exports && !exports.nodeType && exports; + /** Detect free variable `exports`. */ + var freeExports = exports && !exports.nodeType && exports; - /** Detect free variable `module`. */ - var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module; + /** Detect free variable `module`. */ + var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module; - /** Detect the popular CommonJS extension `module.exports`. */ - var moduleExports = freeModule && freeModule.exports === freeExports; + /** Detect the popular CommonJS extension `module.exports`. */ + var moduleExports = freeModule && freeModule.exports === freeExports; - /** Built-in value references. */ - var Buffer = moduleExports ? _root.Buffer : undefined, - allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined; + /** Built-in value references. */ + var Buffer = moduleExports ? _root.Buffer : undefined, + allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined; - /** - * Creates a clone of `buffer`. - * - * @private - * @param {Buffer} buffer The buffer to clone. - * @param {boolean} [isDeep] Specify a deep clone. - * @returns {Buffer} Returns the cloned buffer. - */ - function cloneBuffer(buffer, isDeep) { - if (isDeep) { - return buffer.slice(); - } - var length = buffer.length, - result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length); + /** + * Creates a clone of `buffer`. + * + * @private + * @param {Buffer} buffer The buffer to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Buffer} Returns the cloned buffer. + */ + function cloneBuffer(buffer, isDeep) { + if (isDeep) { + return buffer.slice(); + } + var length = buffer.length, + result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length); - buffer.copy(result); - return result; - } + buffer.copy(result); + return result; + } - module.exports = cloneBuffer; + module.exports = cloneBuffer; }); /** Built-in value references. */ @@ -3723,9 +3722,9 @@ * @returns {ArrayBuffer} Returns the cloned array buffer. */ function cloneArrayBuffer(arrayBuffer) { - var result = new arrayBuffer.constructor(arrayBuffer.byteLength); - new _Uint8Array(result).set(new _Uint8Array(arrayBuffer)); - return result; + var result = new arrayBuffer.constructor(arrayBuffer.byteLength); + new _Uint8Array(result).set(new _Uint8Array(arrayBuffer)); + return result; } var _cloneArrayBuffer = cloneArrayBuffer; @@ -3739,8 +3738,8 @@ * @returns {Object} Returns the cloned typed array. */ function cloneTypedArray(typedArray, isDeep) { - var buffer = isDeep ? _cloneArrayBuffer(typedArray.buffer) : typedArray.buffer; - return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length); + var buffer = isDeep ? _cloneArrayBuffer(typedArray.buffer) : typedArray.buffer; + return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length); } var _cloneTypedArray = cloneTypedArray; @@ -3754,14 +3753,14 @@ * @returns {Array} Returns `array`. */ function copyArray(source, array) { - var index = -1, - length = source.length; + var index = -1, + length = source.length; - array || (array = Array(length)); - while (++index < length) { - array[index] = source[index]; - } - return array; + array || (array = Array(length)); + while (++index < length) { + array[index] = source[index]; + } + return array; } var _copyArray = copyArray; @@ -3777,20 +3776,20 @@ * @param {Object} proto The object to inherit from. * @returns {Object} Returns the new object. */ - var baseCreate = (function () { - function object() { } - return function (proto) { - if (!isObject_1(proto)) { - return {}; - } - if (objectCreate$1) { - return objectCreate$1(proto); - } - object.prototype = proto; - var result = new object; - object.prototype = undefined; - return result; - }; + var baseCreate = (function() { + function object() {} + return function(proto) { + if (!isObject_1(proto)) { + return {}; + } + if (objectCreate$1) { + return objectCreate$1(proto); + } + object.prototype = proto; + var result = new object; + object.prototype = undefined; + return result; + }; }()); var _baseCreate = baseCreate; @@ -3804,9 +3803,9 @@ * @returns {Function} Returns the new function. */ function overArg(func, transform) { - return function (arg) { - return func(transform(arg)); - }; + return function(arg) { + return func(transform(arg)); + }; } var _overArg = overArg; @@ -3827,10 +3826,10 @@ * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. */ function isPrototype(value) { - var Ctor = value && value.constructor, - proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto$5; + var Ctor = value && value.constructor, + proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto$5; - return value === proto; + return value === proto; } var _isPrototype = isPrototype; @@ -3843,9 +3842,9 @@ * @returns {Object} Returns the initialized clone. */ function initCloneObject(object) { - return (typeof object.constructor == 'function' && !_isPrototype(object)) - ? _baseCreate(_getPrototype(object)) - : {}; + return (typeof object.constructor == 'function' && !_isPrototype(object)) + ? _baseCreate(_getPrototype(object)) + : {}; } var _initCloneObject = initCloneObject; @@ -3875,7 +3874,7 @@ * // => false */ function isObjectLike(value) { - return value != null && typeof value == 'object'; + return value != null && typeof value == 'object'; } var isObjectLike_1 = isObjectLike; @@ -3891,7 +3890,7 @@ * @returns {boolean} Returns `true` if `value` is an `arguments` object, */ function baseIsArguments(value) { - return isObjectLike_1(value) && _baseGetTag(value) == argsTag; + return isObjectLike_1(value) && _baseGetTag(value) == argsTag; } var _baseIsArguments = baseIsArguments; @@ -3923,9 +3922,9 @@ * _.isArguments([1, 2, 3]); * // => false */ - var isArguments = _baseIsArguments(function () { return arguments; }()) ? _baseIsArguments : function (value) { - return isObjectLike_1(value) && hasOwnProperty$5.call(value, 'callee') && - !propertyIsEnumerable.call(value, 'callee'); + var isArguments = _baseIsArguments(function() { return arguments; }()) ? _baseIsArguments : function(value) { + return isObjectLike_1(value) && hasOwnProperty$5.call(value, 'callee') && + !propertyIsEnumerable.call(value, 'callee'); }; var isArguments_1 = isArguments; @@ -3987,8 +3986,8 @@ * // => false */ function isLength(value) { - return typeof value == 'number' && - value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER$1; + return typeof value == 'number' && + value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER$1; } var isLength_1 = isLength; @@ -4019,7 +4018,7 @@ * // => false */ function isArrayLike(value) { - return value != null && isLength_1(value.length) && !isFunction_1(value); + return value != null && isLength_1(value.length) && !isFunction_1(value); } var isArrayLike_1 = isArrayLike; @@ -4050,7 +4049,7 @@ * // => false */ function isArrayLikeObject(value) { - return isObjectLike_1(value) && isArrayLike_1(value); + return isObjectLike_1(value) && isArrayLike_1(value); } var isArrayLikeObject_1 = isArrayLikeObject; @@ -4069,47 +4068,47 @@ * // => [false, false] */ function stubFalse() { - return false; + return false; } var stubFalse_1 = stubFalse; var isBuffer_1 = createCommonjsModule(function (module, exports) { - /** Detect free variable `exports`. */ - var freeExports = exports && !exports.nodeType && exports; + /** Detect free variable `exports`. */ + var freeExports = exports && !exports.nodeType && exports; - /** Detect free variable `module`. */ - var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module; + /** Detect free variable `module`. */ + var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module; - /** Detect the popular CommonJS extension `module.exports`. */ - var moduleExports = freeModule && freeModule.exports === freeExports; + /** Detect the popular CommonJS extension `module.exports`. */ + var moduleExports = freeModule && freeModule.exports === freeExports; - /** Built-in value references. */ - var Buffer = moduleExports ? _root.Buffer : undefined; + /** Built-in value references. */ + var Buffer = moduleExports ? _root.Buffer : undefined; - /* Built-in method references for those with the same name as other `lodash` methods. */ - var nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined; + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined; - /** - * Checks if `value` is a buffer. - * - * @static - * @memberOf _ - * @since 4.3.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. - * @example - * - * _.isBuffer(new Buffer(2)); - * // => true - * - * _.isBuffer(new Uint8Array(2)); - * // => false - */ - var isBuffer = nativeIsBuffer || stubFalse_1; + /** + * Checks if `value` is a buffer. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. + * @example + * + * _.isBuffer(new Buffer(2)); + * // => true + * + * _.isBuffer(new Uint8Array(2)); + * // => false + */ + var isBuffer = nativeIsBuffer || stubFalse_1; - module.exports = isBuffer; + module.exports = isBuffer; }); /** `Object#toString` result references. */ @@ -4117,7 +4116,7 @@ /** Used for built-in method references. */ var funcProto$2 = Function.prototype, - objectProto$7 = Object.prototype; + objectProto$7 = Object.prototype; /** Used to resolve the decompiled source of functions. */ var funcToString$2 = funcProto$2.toString; @@ -4157,62 +4156,62 @@ * // => true */ function isPlainObject(value) { - if (!isObjectLike_1(value) || _baseGetTag(value) != objectTag) { - return false; - } - var proto = _getPrototype(value); - if (proto === null) { - return true; - } - var Ctor = hasOwnProperty$6.call(proto, 'constructor') && proto.constructor; - return typeof Ctor == 'function' && Ctor instanceof Ctor && - funcToString$2.call(Ctor) == objectCtorString; + if (!isObjectLike_1(value) || _baseGetTag(value) != objectTag) { + return false; + } + var proto = _getPrototype(value); + if (proto === null) { + return true; + } + var Ctor = hasOwnProperty$6.call(proto, 'constructor') && proto.constructor; + return typeof Ctor == 'function' && Ctor instanceof Ctor && + funcToString$2.call(Ctor) == objectCtorString; } var isPlainObject_1 = isPlainObject; /** `Object#toString` result references. */ var argsTag$1 = '[object Arguments]', - arrayTag = '[object Array]', - boolTag = '[object Boolean]', - dateTag = '[object Date]', - errorTag = '[object Error]', - funcTag$1 = '[object Function]', - mapTag = '[object Map]', - numberTag = '[object Number]', - objectTag$1 = '[object Object]', - regexpTag = '[object RegExp]', - setTag = '[object Set]', - stringTag = '[object String]', - weakMapTag = '[object WeakMap]'; + arrayTag = '[object Array]', + boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag$1 = '[object Function]', + mapTag = '[object Map]', + numberTag = '[object Number]', + objectTag$1 = '[object Object]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + weakMapTag = '[object WeakMap]'; var arrayBufferTag = '[object ArrayBuffer]', - dataViewTag = '[object DataView]', - float32Tag = '[object Float32Array]', - float64Tag = '[object Float64Array]', - int8Tag = '[object Int8Array]', - int16Tag = '[object Int16Array]', - int32Tag = '[object Int32Array]', - uint8Tag = '[object Uint8Array]', - uint8ClampedTag = '[object Uint8ClampedArray]', - uint16Tag = '[object Uint16Array]', - uint32Tag = '[object Uint32Array]'; + dataViewTag = '[object DataView]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; /** Used to identify `toStringTag` values of typed arrays. */ var typedArrayTags = {}; typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = - typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = - typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = - typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = - typedArrayTags[uint32Tag] = true; + typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = + typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = + typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = + typedArrayTags[uint32Tag] = true; typedArrayTags[argsTag$1] = typedArrayTags[arrayTag] = - typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = - typedArrayTags[dataViewTag] = typedArrayTags[dateTag] = - typedArrayTags[errorTag] = typedArrayTags[funcTag$1] = - typedArrayTags[mapTag] = typedArrayTags[numberTag] = - typedArrayTags[objectTag$1] = typedArrayTags[regexpTag] = - typedArrayTags[setTag] = typedArrayTags[stringTag] = - typedArrayTags[weakMapTag] = false; + typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = + typedArrayTags[dataViewTag] = typedArrayTags[dateTag] = + typedArrayTags[errorTag] = typedArrayTags[funcTag$1] = + typedArrayTags[mapTag] = typedArrayTags[numberTag] = + typedArrayTags[objectTag$1] = typedArrayTags[regexpTag] = + typedArrayTags[setTag] = typedArrayTags[stringTag] = + typedArrayTags[weakMapTag] = false; /** * The base implementation of `_.isTypedArray` without Node.js optimizations. @@ -4222,8 +4221,8 @@ * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. */ function baseIsTypedArray(value) { - return isObjectLike_1(value) && - isLength_1(value.length) && !!typedArrayTags[_baseGetTag(value)]; + return isObjectLike_1(value) && + isLength_1(value.length) && !!typedArrayTags[_baseGetTag(value)]; } var _baseIsTypedArray = baseIsTypedArray; @@ -4236,42 +4235,42 @@ * @returns {Function} Returns the new capped function. */ function baseUnary(func) { - return function (value) { - return func(value); - }; + return function(value) { + return func(value); + }; } var _baseUnary = baseUnary; var _nodeUtil = createCommonjsModule(function (module, exports) { - /** Detect free variable `exports`. */ - var freeExports = exports && !exports.nodeType && exports; + /** Detect free variable `exports`. */ + var freeExports = exports && !exports.nodeType && exports; - /** Detect free variable `module`. */ - var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module; + /** Detect free variable `module`. */ + var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module; - /** Detect the popular CommonJS extension `module.exports`. */ - var moduleExports = freeModule && freeModule.exports === freeExports; + /** Detect the popular CommonJS extension `module.exports`. */ + var moduleExports = freeModule && freeModule.exports === freeExports; - /** Detect free variable `process` from Node.js. */ - var freeProcess = moduleExports && _freeGlobal.process; + /** Detect free variable `process` from Node.js. */ + var freeProcess = moduleExports && _freeGlobal.process; - /** Used to access faster Node.js helpers. */ - var nodeUtil = (function () { - try { - // Use `util.types` for Node.js 10+. - var types = freeModule && freeModule.require && freeModule.require('util').types; + /** Used to access faster Node.js helpers. */ + var nodeUtil = (function() { + try { + // Use `util.types` for Node.js 10+. + var types = freeModule && freeModule.require && freeModule.require('util').types; - if (types) { - return types; - } + if (types) { + return types; + } - // Legacy `process.binding('util')` for Node.js < 10. - return freeProcess && freeProcess.binding && freeProcess.binding('util'); - } catch (e) { } - }()); + // Legacy `process.binding('util')` for Node.js < 10. + return freeProcess && freeProcess.binding && freeProcess.binding('util'); + } catch (e) {} + }()); - module.exports = nodeUtil; + module.exports = nodeUtil; }); /* Node.js helper references. */ @@ -4307,15 +4306,15 @@ * @returns {*} Returns the property value. */ function safeGet(object, key) { - if (key === 'constructor' && typeof object[key] === 'function') { - return; - } + if (key === 'constructor' && typeof object[key] === 'function') { + return; + } - if (key == '__proto__') { - return; - } + if (key == '__proto__') { + return; + } - return object[key]; + return object[key]; } var _safeGet = safeGet; @@ -4337,11 +4336,11 @@ * @param {*} value The value to assign. */ function assignValue(object, key, value) { - var objValue = object[key]; - if (!(hasOwnProperty$7.call(object, key) && eq_1(objValue, value)) || - (value === undefined && !(key in object))) { - _baseAssignValue(object, key, value); - } + var objValue = object[key]; + if (!(hasOwnProperty$7.call(object, key) && eq_1(objValue, value)) || + (value === undefined && !(key in object))) { + _baseAssignValue(object, key, value); + } } var _assignValue = assignValue; @@ -4357,29 +4356,29 @@ * @returns {Object} Returns `object`. */ function copyObject(source, props, object, customizer) { - var isNew = !object; - object || (object = {}); + var isNew = !object; + object || (object = {}); - var index = -1, - length = props.length; + var index = -1, + length = props.length; - while (++index < length) { - var key = props[index]; + while (++index < length) { + var key = props[index]; - var newValue = customizer - ? customizer(object[key], source[key], key, object, source) - : undefined; + var newValue = customizer + ? customizer(object[key], source[key], key, object, source) + : undefined; - if (newValue === undefined) { - newValue = source[key]; - } - if (isNew) { - _baseAssignValue(object, key, newValue); - } else { - _assignValue(object, key, newValue); - } - } - return object; + if (newValue === undefined) { + newValue = source[key]; + } + if (isNew) { + _baseAssignValue(object, key, newValue); + } else { + _assignValue(object, key, newValue); + } + } + return object; } var _copyObject = copyObject; @@ -4394,13 +4393,13 @@ * @returns {Array} Returns the array of results. */ function baseTimes(n, iteratee) { - var index = -1, - result = Array(n); + var index = -1, + result = Array(n); - while (++index < n) { - result[index] = iteratee(index); - } - return result; + while (++index < n) { + result[index] = iteratee(index); + } + return result; } var _baseTimes = baseTimes; @@ -4420,13 +4419,13 @@ * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. */ function isIndex(value, length) { - var type = typeof value; - length = length == null ? MAX_SAFE_INTEGER$2 : length; + var type = typeof value; + length = length == null ? MAX_SAFE_INTEGER$2 : length; - return !!length && - (type == 'number' || - (type != 'symbol' && reIsUint.test(value))) && - (value > -1 && value % 1 == 0 && value < length); + return !!length && + (type == 'number' || + (type != 'symbol' && reIsUint.test(value))) && + (value > -1 && value % 1 == 0 && value < length); } var _isIndex = isIndex; @@ -4446,30 +4445,30 @@ * @returns {Array} Returns the array of property names. */ function arrayLikeKeys(value, inherited) { - var isArr = isArray_1(value), - isArg = !isArr && isArguments_1(value), - isBuff = !isArr && !isArg && isBuffer_1(value), - isType = !isArr && !isArg && !isBuff && isTypedArray_1(value), - skipIndexes = isArr || isArg || isBuff || isType, - result = skipIndexes ? _baseTimes(value.length, String) : [], - length = result.length; - - for (var key in value) { - if ((inherited || hasOwnProperty$8.call(value, key)) && - !(skipIndexes && ( - // Safari 9 has enumerable `arguments.length` in strict mode. - key == 'length' || - // Node.js 0.10 has enumerable non-index properties on buffers. - (isBuff && (key == 'offset' || key == 'parent')) || - // PhantomJS 2 has enumerable non-index properties on typed arrays. - (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) || - // Skip index properties. - _isIndex(key, length) - ))) { - result.push(key); - } - } - return result; + var isArr = isArray_1(value), + isArg = !isArr && isArguments_1(value), + isBuff = !isArr && !isArg && isBuffer_1(value), + isType = !isArr && !isArg && !isBuff && isTypedArray_1(value), + skipIndexes = isArr || isArg || isBuff || isType, + result = skipIndexes ? _baseTimes(value.length, String) : [], + length = result.length; + + for (var key in value) { + if ((inherited || hasOwnProperty$8.call(value, key)) && + !(skipIndexes && ( + // Safari 9 has enumerable `arguments.length` in strict mode. + key == 'length' || + // Node.js 0.10 has enumerable non-index properties on buffers. + (isBuff && (key == 'offset' || key == 'parent')) || + // PhantomJS 2 has enumerable non-index properties on typed arrays. + (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) || + // Skip index properties. + _isIndex(key, length) + ))) { + result.push(key); + } + } + return result; } var _arrayLikeKeys = arrayLikeKeys; @@ -4484,13 +4483,13 @@ * @returns {Array} Returns the array of property names. */ function nativeKeysIn(object) { - var result = []; - if (object != null) { - for (var key in Object(object)) { - result.push(key); - } - } - return result; + var result = []; + if (object != null) { + for (var key in Object(object)) { + result.push(key); + } + } + return result; } var _nativeKeysIn = nativeKeysIn; @@ -4509,18 +4508,18 @@ * @returns {Array} Returns the array of property names. */ function baseKeysIn(object) { - if (!isObject_1(object)) { - return _nativeKeysIn(object); - } - var isProto = _isPrototype(object), - result = []; + if (!isObject_1(object)) { + return _nativeKeysIn(object); + } + var isProto = _isPrototype(object), + result = []; - for (var key in object) { - if (!(key == 'constructor' && (isProto || !hasOwnProperty$9.call(object, key)))) { - result.push(key); - } - } - return result; + for (var key in object) { + if (!(key == 'constructor' && (isProto || !hasOwnProperty$9.call(object, key)))) { + result.push(key); + } + } + return result; } var _baseKeysIn = baseKeysIn; @@ -4549,7 +4548,7 @@ * // => ['a', 'b', 'c'] (iteration order is not guaranteed) */ function keysIn(object) { - return isArrayLike_1(object) ? _arrayLikeKeys(object, true) : _baseKeysIn(object); + return isArrayLike_1(object) ? _arrayLikeKeys(object, true) : _baseKeysIn(object); } var keysIn_1 = keysIn; @@ -4579,7 +4578,7 @@ * // => { 'a': 1, 'b': 2, 'c': 3 } */ function toPlainObject(value) { - return _copyObject(value, keysIn_1(value)); + return _copyObject(value, keysIn_1(value)); } var toPlainObject_1 = toPlainObject; @@ -4600,65 +4599,65 @@ * counterparts. */ function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) { - var objValue = _safeGet(object, key), - srcValue = _safeGet(source, key), - stacked = stack.get(srcValue); - - if (stacked) { - _assignMergeValue(object, key, stacked); - return; - } - var newValue = customizer - ? customizer(objValue, srcValue, (key + ''), object, source, stack) - : undefined; - - var isCommon = newValue === undefined; - - if (isCommon) { - var isArr = isArray_1(srcValue), - isBuff = !isArr && isBuffer_1(srcValue), - isTyped = !isArr && !isBuff && isTypedArray_1(srcValue); - - newValue = srcValue; - if (isArr || isBuff || isTyped) { - if (isArray_1(objValue)) { - newValue = objValue; - } - else if (isArrayLikeObject_1(objValue)) { - newValue = _copyArray(objValue); - } - else if (isBuff) { - isCommon = false; - newValue = _cloneBuffer(srcValue, true); - } - else if (isTyped) { - isCommon = false; - newValue = _cloneTypedArray(srcValue, true); - } - else { - newValue = []; - } - } - else if (isPlainObject_1(srcValue) || isArguments_1(srcValue)) { - newValue = objValue; - if (isArguments_1(objValue)) { - newValue = toPlainObject_1(objValue); - } - else if (!isObject_1(objValue) || isFunction_1(objValue)) { - newValue = _initCloneObject(srcValue); - } - } - else { - isCommon = false; - } - } - if (isCommon) { - // Recursively merge objects and arrays (susceptible to call stack limits). - stack.set(srcValue, newValue); - mergeFunc(newValue, srcValue, srcIndex, customizer, stack); - stack['delete'](srcValue); - } - _assignMergeValue(object, key, newValue); + var objValue = _safeGet(object, key), + srcValue = _safeGet(source, key), + stacked = stack.get(srcValue); + + if (stacked) { + _assignMergeValue(object, key, stacked); + return; + } + var newValue = customizer + ? customizer(objValue, srcValue, (key + ''), object, source, stack) + : undefined; + + var isCommon = newValue === undefined; + + if (isCommon) { + var isArr = isArray_1(srcValue), + isBuff = !isArr && isBuffer_1(srcValue), + isTyped = !isArr && !isBuff && isTypedArray_1(srcValue); + + newValue = srcValue; + if (isArr || isBuff || isTyped) { + if (isArray_1(objValue)) { + newValue = objValue; + } + else if (isArrayLikeObject_1(objValue)) { + newValue = _copyArray(objValue); + } + else if (isBuff) { + isCommon = false; + newValue = _cloneBuffer(srcValue, true); + } + else if (isTyped) { + isCommon = false; + newValue = _cloneTypedArray(srcValue, true); + } + else { + newValue = []; + } + } + else if (isPlainObject_1(srcValue) || isArguments_1(srcValue)) { + newValue = objValue; + if (isArguments_1(objValue)) { + newValue = toPlainObject_1(objValue); + } + else if (!isObject_1(objValue) || isFunction_1(objValue)) { + newValue = _initCloneObject(srcValue); + } + } + else { + isCommon = false; + } + } + if (isCommon) { + // Recursively merge objects and arrays (susceptible to call stack limits). + stack.set(srcValue, newValue); + mergeFunc(newValue, srcValue, srcIndex, customizer, stack); + stack['delete'](srcValue); + } + _assignMergeValue(object, key, newValue); } var _baseMergeDeep = baseMergeDeep; @@ -4675,25 +4674,25 @@ * counterparts. */ function baseMerge(object, source, srcIndex, customizer, stack) { - if (object === source) { - return; - } - _baseFor(source, function (srcValue, key) { - stack || (stack = new _Stack); - if (isObject_1(srcValue)) { - _baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack); - } - else { - var newValue = customizer - ? customizer(_safeGet(object, key), srcValue, (key + ''), object, source, stack) - : undefined; - - if (newValue === undefined) { - newValue = srcValue; - } - _assignMergeValue(object, key, newValue); - } - }, keysIn_1); + if (object === source) { + return; + } + _baseFor(source, function(srcValue, key) { + stack || (stack = new _Stack); + if (isObject_1(srcValue)) { + _baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack); + } + else { + var newValue = customizer + ? customizer(_safeGet(object, key), srcValue, (key + ''), object, source, stack) + : undefined; + + if (newValue === undefined) { + newValue = srcValue; + } + _assignMergeValue(object, key, newValue); + } + }, keysIn_1); } var _baseMerge = baseMerge; @@ -4715,7 +4714,7 @@ * // => true */ function identity(value) { - return value; + return value; } var identity_1 = identity; @@ -4731,13 +4730,13 @@ * @returns {*} Returns the result of `func`. */ function apply$1(func, thisArg, args) { - switch (args.length) { - case 0: return func.call(thisArg); - case 1: return func.call(thisArg, args[0]); - case 2: return func.call(thisArg, args[0], args[1]); - case 3: return func.call(thisArg, args[0], args[1], args[2]); - } - return func.apply(thisArg, args); + switch (args.length) { + case 0: return func.call(thisArg); + case 1: return func.call(thisArg, args[0]); + case 2: return func.call(thisArg, args[0], args[1]); + case 3: return func.call(thisArg, args[0], args[1], args[2]); + } + return func.apply(thisArg, args); } var _apply = apply$1; @@ -4755,24 +4754,24 @@ * @returns {Function} Returns the new function. */ function overRest(func, start, transform) { - start = nativeMax(start === undefined ? (func.length - 1) : start, 0); - return function () { - var args = arguments, - index = -1, - length = nativeMax(args.length - start, 0), - array = Array(length); - - while (++index < length) { - array[index] = args[start + index]; - } - index = -1; - var otherArgs = Array(start + 1); - while (++index < start) { - otherArgs[index] = args[index]; - } - otherArgs[start] = transform(array); - return _apply(func, this, otherArgs); - }; + start = nativeMax(start === undefined ? (func.length - 1) : start, 0); + return function() { + var args = arguments, + index = -1, + length = nativeMax(args.length - start, 0), + array = Array(length); + + while (++index < length) { + array[index] = args[start + index]; + } + index = -1; + var otherArgs = Array(start + 1); + while (++index < start) { + otherArgs[index] = args[index]; + } + otherArgs[start] = transform(array); + return _apply(func, this, otherArgs); + }; } var _overRest = overRest; @@ -4797,9 +4796,9 @@ * // => true */ function constant(value) { - return function () { - return value; - }; + return function() { + return value; + }; } var constant_1 = constant; @@ -4812,20 +4811,20 @@ * @param {Function} string The `toString` result. * @returns {Function} Returns `func`. */ - var baseSetToString = !_defineProperty$1 ? identity_1 : function (func, string) { - return _defineProperty$1(func, 'toString', { - 'configurable': true, - 'enumerable': false, - 'value': constant_1(string), - 'writable': true - }); + var baseSetToString = !_defineProperty$1 ? identity_1 : function(func, string) { + return _defineProperty$1(func, 'toString', { + 'configurable': true, + 'enumerable': false, + 'value': constant_1(string), + 'writable': true + }); }; var _baseSetToString = baseSetToString; /** Used to detect hot functions by number of calls within a span of milliseconds. */ var HOT_COUNT = 800, - HOT_SPAN = 16; + HOT_SPAN = 16; /* Built-in method references for those with the same name as other `lodash` methods. */ var nativeNow = Date.now; @@ -4840,23 +4839,23 @@ * @returns {Function} Returns the new shortable function. */ function shortOut(func) { - var count = 0, - lastCalled = 0; + var count = 0, + lastCalled = 0; - return function () { - var stamp = nativeNow(), - remaining = HOT_SPAN - (stamp - lastCalled); + return function() { + var stamp = nativeNow(), + remaining = HOT_SPAN - (stamp - lastCalled); - lastCalled = stamp; - if (remaining > 0) { - if (++count >= HOT_COUNT) { - return arguments[0]; - } - } else { - count = 0; - } - return func.apply(undefined, arguments); - }; + lastCalled = stamp; + if (remaining > 0) { + if (++count >= HOT_COUNT) { + return arguments[0]; + } + } else { + count = 0; + } + return func.apply(undefined, arguments); + }; } var _shortOut = shortOut; @@ -4882,7 +4881,7 @@ * @returns {Function} Returns the new function. */ function baseRest(func, start) { - return _setToString(_overRest(func, start, identity_1), func + ''); + return _setToString(_overRest(func, start, identity_1), func + ''); } var _baseRest = baseRest; @@ -4898,17 +4897,17 @@ * else `false`. */ function isIterateeCall(value, index, object) { - if (!isObject_1(object)) { - return false; - } - var type = typeof index; - if (type == 'number' - ? (isArrayLike_1(object) && _isIndex(index, object.length)) - : (type == 'string' && index in object) - ) { - return eq_1(object[index], value); - } - return false; + if (!isObject_1(object)) { + return false; + } + var type = typeof index; + if (type == 'number' + ? (isArrayLike_1(object) && _isIndex(index, object.length)) + : (type == 'string' && index in object) + ) { + return eq_1(object[index], value); + } + return false; } var _isIterateeCall = isIterateeCall; @@ -4921,29 +4920,29 @@ * @returns {Function} Returns the new assigner function. */ function createAssigner(assigner) { - return _baseRest(function (object, sources) { - var index = -1, - length = sources.length, - customizer = length > 1 ? sources[length - 1] : undefined, - guard = length > 2 ? sources[2] : undefined; - - customizer = (assigner.length > 3 && typeof customizer == 'function') - ? (length--, customizer) - : undefined; - - if (guard && _isIterateeCall(sources[0], sources[1], guard)) { - customizer = length < 3 ? undefined : customizer; - length = 1; - } - object = Object(object); - while (++index < length) { - var source = sources[index]; - if (source) { - assigner(object, source, index, customizer); - } - } - return object; - }); + return _baseRest(function(object, sources) { + var index = -1, + length = sources.length, + customizer = length > 1 ? sources[length - 1] : undefined, + guard = length > 2 ? sources[2] : undefined; + + customizer = (assigner.length > 3 && typeof customizer == 'function') + ? (length--, customizer) + : undefined; + + if (guard && _isIterateeCall(sources[0], sources[1], guard)) { + customizer = length < 3 ? undefined : customizer; + length = 1; + } + object = Object(object); + while (++index < length) { + var source = sources[index]; + if (source) { + assigner(object, source, index, customizer); + } + } + return object; + }); } var _createAssigner = createAssigner; @@ -4979,8 +4978,8 @@ * _.mergeWith(object, other, customizer); * // => { 'a': [1, 3], 'b': [2, 4] } */ - var mergeWith = _createAssigner(function (object, source, srcIndex, customizer) { - _baseMerge(object, source, srcIndex, customizer); + var mergeWith = _createAssigner(function(object, source, srcIndex, customizer) { + _baseMerge(object, source, srcIndex, customizer); }); var mergeWith_1 = mergeWith; @@ -5007,13 +5006,13 @@ // `Array.prototype.indexOf` method // https://tc39.es/ecma262/#sec-array.prototype.indexof _export({ target: 'Array', proto: true, forced: NEGATIVE_ZERO || !STRICT_METHOD$1 }, { - indexOf: function indexOf(searchElement /* , fromIndex = 0 */) { - var fromIndex = arguments.length > 1 ? arguments[1] : undefined; - return NEGATIVE_ZERO - // convert -0 to +0 - ? un$IndexOf(this, searchElement, fromIndex) || 0 - : $IndexOf(this, searchElement, fromIndex); - } + indexOf: function indexOf(searchElement /* , fromIndex = 0 */) { + var fromIndex = arguments.length > 1 ? arguments[1] : undefined; + return NEGATIVE_ZERO + // convert -0 to +0 + ? un$IndexOf(this, searchElement, fromIndex) || 0 + : $IndexOf(this, searchElement, fromIndex); + } }); var indexOf$1 = entryVirtual('Array').indexOf; @@ -5021,8 +5020,8 @@ var ArrayPrototype$3 = Array.prototype; var indexOf$2 = function (it) { - var own = it.indexOf; - return it === ArrayPrototype$3 || (objectIsPrototypeOf(ArrayPrototype$3, it) && own === ArrayPrototype$3.indexOf) ? indexOf$1 : own; + var own = it.indexOf; + return it === ArrayPrototype$3 || (objectIsPrototypeOf(ArrayPrototype$3, it) && own === ArrayPrototype$3.indexOf) ? indexOf$1 : own; }; var indexOf$3 = indexOf$2; @@ -5044,49 +5043,49 @@ var keys$7 = keys$6; var objectWithoutPropertiesLoose = createCommonjsModule(function (module) { - function _objectWithoutPropertiesLoose(source, excluded) { - if (source == null) return {}; - var target = {}; + function _objectWithoutPropertiesLoose(source, excluded) { + if (source == null) return {}; + var target = {}; - var sourceKeys = keys$7(source); + var sourceKeys = keys$7(source); - var key, i; + var key, i; - for (i = 0; i < sourceKeys.length; i++) { - key = sourceKeys[i]; - if (indexOf$7(excluded).call(excluded, key) >= 0) continue; - target[key] = source[key]; - } + for (i = 0; i < sourceKeys.length; i++) { + key = sourceKeys[i]; + if (indexOf$7(excluded).call(excluded, key) >= 0) continue; + target[key] = source[key]; + } - return target; - } + return target; + } - module.exports = _objectWithoutPropertiesLoose, module.exports.__esModule = true, module.exports["default"] = module.exports; + module.exports = _objectWithoutPropertiesLoose, module.exports.__esModule = true, module.exports["default"] = module.exports; }); unwrapExports(objectWithoutPropertiesLoose); var objectWithoutProperties = createCommonjsModule(function (module) { - function _objectWithoutProperties(source, excluded) { - if (source == null) return {}; - var target = objectWithoutPropertiesLoose(source, excluded); - var key, i; - - if (getOwnPropertySymbols$6) { - var sourceSymbolKeys = getOwnPropertySymbols$6(source); - - for (i = 0; i < sourceSymbolKeys.length; i++) { - key = sourceSymbolKeys[i]; - if (indexOf$7(excluded).call(excluded, key) >= 0) continue; - if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; - target[key] = source[key]; - } - } + function _objectWithoutProperties(source, excluded) { + if (source == null) return {}; + var target = objectWithoutPropertiesLoose(source, excluded); + var key, i; - return target; - } + if (getOwnPropertySymbols$6) { + var sourceSymbolKeys = getOwnPropertySymbols$6(source); - module.exports = _objectWithoutProperties, module.exports.__esModule = true, module.exports["default"] = module.exports; + for (i = 0; i < sourceSymbolKeys.length; i++) { + key = sourceSymbolKeys[i]; + if (indexOf$7(excluded).call(excluded, key) >= 0) continue; + if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; + target[key] = source[key]; + } + } + + return target; + } + + module.exports = _objectWithoutProperties, module.exports.__esModule = true, module.exports["default"] = module.exports; }); var _objectWithoutProperties = unwrapExports(objectWithoutProperties); @@ -5100,49 +5099,49 @@ // `Object.assign` method // https://tc39.es/ecma262/#sec-object.assign var objectAssign = !$assign || fails(function () { - // should have correct order of operations (Edge bug) - if (descriptors && $assign({ b: 1 }, $assign(defineProperty$c({}, 'a', { - enumerable: true, - get: function () { - defineProperty$c(this, 'b', { - value: 3, - enumerable: false - }); - } - }), { b: 2 })).b !== 1) return true; - // should work with symbols and should have deterministic property order (V8 bug) - var A = {}; - var B = {}; - // eslint-disable-next-line es-x/no-symbol -- safe - var symbol = Symbol(); - var alphabet = 'abcdefghijklmnopqrst'; - A[symbol] = 7; - alphabet.split('').forEach(function (chr) { B[chr] = chr; }); - return $assign({}, A)[symbol] != 7 || objectKeys($assign({}, B)).join('') != alphabet; + // should have correct order of operations (Edge bug) + if (descriptors && $assign({ b: 1 }, $assign(defineProperty$c({}, 'a', { + enumerable: true, + get: function () { + defineProperty$c(this, 'b', { + value: 3, + enumerable: false + }); + } + }), { b: 2 })).b !== 1) return true; + // should work with symbols and should have deterministic property order (V8 bug) + var A = {}; + var B = {}; + // eslint-disable-next-line es-x/no-symbol -- safe + var symbol = Symbol(); + var alphabet = 'abcdefghijklmnopqrst'; + A[symbol] = 7; + alphabet.split('').forEach(function (chr) { B[chr] = chr; }); + return $assign({}, A)[symbol] != 7 || objectKeys($assign({}, B)).join('') != alphabet; }) ? function assign(target, source) { // eslint-disable-line no-unused-vars -- required for `.length` - var T = toObject(target); - var argumentsLength = arguments.length; - var index = 1; - var getOwnPropertySymbols = objectGetOwnPropertySymbols.f; - var propertyIsEnumerable = objectPropertyIsEnumerable.f; - while (argumentsLength > index) { - var S = indexedObject(arguments[index++]); - var keys = getOwnPropertySymbols ? concat$6(objectKeys(S), getOwnPropertySymbols(S)) : objectKeys(S); - var length = keys.length; - var j = 0; - var key; - while (length > j) { - key = keys[j++]; - if (!descriptors || functionCall(propertyIsEnumerable, S, key)) T[key] = S[key]; - } - } return T; + var T = toObject(target); + var argumentsLength = arguments.length; + var index = 1; + var getOwnPropertySymbols = objectGetOwnPropertySymbols.f; + var propertyIsEnumerable = objectPropertyIsEnumerable.f; + while (argumentsLength > index) { + var S = indexedObject(arguments[index++]); + var keys = getOwnPropertySymbols ? concat$6(objectKeys(S), getOwnPropertySymbols(S)) : objectKeys(S); + var length = keys.length; + var j = 0; + var key; + while (length > j) { + key = keys[j++]; + if (!descriptors || functionCall(propertyIsEnumerable, S, key)) T[key] = S[key]; + } + } return T; } : $assign; // `Object.assign` method // https://tc39.es/ecma262/#sec-object.assign // eslint-disable-next-line es-x/no-object-assign -- required for testing _export({ target: 'Object', stat: true, arity: 2, forced: Object.assign !== objectAssign }, { - assign: objectAssign + assign: objectAssign }); var assign = path.Object.assign; @@ -5153,7 +5152,7 @@ // a string of all valid unicode whitespaces var whitespaces = '\u0009\u000A\u000B\u000C\u000D\u0020\u00A0\u1680\u2000\u2001\u2002' + - '\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF'; + '\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF'; var replace$1 = functionUncurryThis(''.replace); var whitespace = '[' + whitespaces + ']'; @@ -5162,24 +5161,24 @@ // `String.prototype.{ trim, trimStart, trimEnd, trimLeft, trimRight }` methods implementation var createMethod$3 = function (TYPE) { - return function ($this) { - var string = toString_1(requireObjectCoercible($this)); - if (TYPE & 1) string = replace$1(string, ltrim, ''); - if (TYPE & 2) string = replace$1(string, rtrim, ''); - return string; - }; + return function ($this) { + var string = toString_1(requireObjectCoercible($this)); + if (TYPE & 1) string = replace$1(string, ltrim, ''); + if (TYPE & 2) string = replace$1(string, rtrim, ''); + return string; + }; }; var stringTrim = { - // `String.prototype.{ trimLeft, trimStart }` methods - // https://tc39.es/ecma262/#sec-string.prototype.trimstart - start: createMethod$3(1), - // `String.prototype.{ trimRight, trimEnd }` methods - // https://tc39.es/ecma262/#sec-string.prototype.trimend - end: createMethod$3(2), - // `String.prototype.trim` method - // https://tc39.es/ecma262/#sec-string.prototype.trim - trim: createMethod$3(3) + // `String.prototype.{ trimLeft, trimStart }` methods + // https://tc39.es/ecma262/#sec-string.prototype.trimstart + start: createMethod$3(1), + // `String.prototype.{ trimRight, trimEnd }` methods + // https://tc39.es/ecma262/#sec-string.prototype.trimend + end: createMethod$3(2), + // `String.prototype.trim` method + // https://tc39.es/ecma262/#sec-string.prototype.trim + trim: createMethod$3(3) }; var PROPER_FUNCTION_NAME$1 = functionName.PROPER; @@ -5191,11 +5190,11 @@ // check that a method works with the correct list // of whitespaces and has a correct name var stringTrimForced = function (METHOD_NAME) { - return fails(function () { - return !!whitespaces[METHOD_NAME]() - || non[METHOD_NAME]() !== non - || (PROPER_FUNCTION_NAME$1 && whitespaces[METHOD_NAME].name !== METHOD_NAME); - }); + return fails(function () { + return !!whitespaces[METHOD_NAME]() + || non[METHOD_NAME]() !== non + || (PROPER_FUNCTION_NAME$1 && whitespaces[METHOD_NAME].name !== METHOD_NAME); + }); }; var $trim = stringTrim.trim; @@ -5204,9 +5203,9 @@ // `String.prototype.trim` method // https://tc39.es/ecma262/#sec-string.prototype.trim _export({ target: 'String', proto: true, forced: stringTrimForced('trim') }, { - trim: function trim() { - return $trim(this); - } + trim: function trim() { + return $trim(this); + } }); var trim = entryVirtual('String').trim; @@ -5214,17715 +5213,29267 @@ var StringPrototype = String.prototype; var trim$1 = function (it) { - var own = it.trim; - return typeof it == 'string' || it === StringPrototype - || (objectIsPrototypeOf(StringPrototype, it) && own === StringPrototype.trim) ? trim : own; + var own = it.trim; + return typeof it == 'string' || it === StringPrototype + || (objectIsPrototypeOf(StringPrototype, it) && own === StringPrototype.trim) ? trim : own; }; var trim$2 = trim$1; var trim$3 = trim$2; - var codemirror = createCommonjsModule(function (module, exports) { - // CodeMirror, copyright (c) by Marijn Haverbeke and others - // Distributed under an MIT license: https://codemirror.net/LICENSE - - // This is CodeMirror (https://codemirror.net), a code editor - // implemented in JavaScript on top of the browser's DOM. - // - // You can find some technical background for some of the code below - // at http://marijnhaverbeke.nl/blog/#cm-internals . - - (function (global, factory) { - module.exports = factory(); - }(commonjsGlobal, (function () { - // Kludges for bugs and behavior differences that can't be feature - // detected are enabled based on userAgent etc sniffing. - var userAgent = navigator.userAgent; - var platform = navigator.platform; - - var gecko = /gecko\/\d/i.test(userAgent); - var ie_upto10 = /MSIE \d/.test(userAgent); - var ie_11up = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(userAgent); - var edge = /Edge\/(\d+)/.exec(userAgent); - var ie = ie_upto10 || ie_11up || edge; - var ie_version = ie && (ie_upto10 ? document.documentMode || 6 : +(edge || ie_11up)[1]); - var webkit = !edge && /WebKit\//.test(userAgent); - var qtwebkit = webkit && /Qt\/\d+\.\d+/.test(userAgent); - var chrome = !edge && /Chrome\//.test(userAgent); - var presto = /Opera\//.test(userAgent); - var safari = /Apple Computer/.test(navigator.vendor); - var mac_geMountainLion = /Mac OS X 1\d\D([8-9]|\d\d)\D/.test(userAgent); - var phantom = /PhantomJS/.test(userAgent); - - var ios = !edge && /AppleWebKit/.test(userAgent) && /Mobile\/\w+/.test(userAgent); - var android = /Android/.test(userAgent); - // This is woefully incomplete. Suggestions for alternative methods welcome. - var mobile = ios || android || /webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(userAgent); - var mac = ios || /Mac/.test(platform); - var chromeOS = /\bCrOS\b/.test(userAgent); - var windows = /win/i.test(platform); - - var presto_version = presto && userAgent.match(/Version\/(\d*\.\d*)/); - if (presto_version) { presto_version = Number(presto_version[1]); } - if (presto_version && presto_version >= 15) { presto = false; webkit = true; } - // Some browsers use the wrong event properties to signal cmd/ctrl on OS X - var flipCtrlCmd = mac && (qtwebkit || presto && (presto_version == null || presto_version < 12.11)); - var captureRightClick = gecko || (ie && ie_version >= 9); - - function classTest(cls) { return new RegExp("(^|\\s)" + cls + "(?:$|\\s)\\s*") } - - var rmClass = function (node, cls) { - var current = node.className; - var match = classTest(cls).exec(current); - if (match) { - var after = current.slice(match.index + match[0].length); - node.className = current.slice(0, match.index) + (after ? match[1] + after : ""); - } - }; + var iteratorClose = function (iterator, kind, value) { + var innerResult, innerError; + anObject(iterator); + try { + innerResult = getMethod(iterator, 'return'); + if (!innerResult) { + if (kind === 'throw') throw value; + return value; + } + innerResult = functionCall(innerResult, iterator); + } catch (error) { + innerError = true; + innerResult = error; + } + if (kind === 'throw') throw value; + if (innerError) throw innerResult; + anObject(innerResult); + return value; + }; - function removeChildren(e) { - for (var count = e.childNodes.length; count > 0; --count) { e.removeChild(e.firstChild); } - return e - } + // call something on iterator step with safe closing on error + var callWithSafeIterationClosing = function (iterator, fn, value, ENTRIES) { + try { + return ENTRIES ? fn(anObject(value)[0], value[1]) : fn(value); + } catch (error) { + iteratorClose(iterator, 'throw', error); + } + }; - function removeChildrenAndAdd(parent, e) { - return removeChildren(parent).appendChild(e) - } + var ITERATOR$2 = wellKnownSymbol('iterator'); + var ArrayPrototype$4 = Array.prototype; - function elt(tag, content, className, style) { - var e = document.createElement(tag); - if (className) { e.className = className; } - if (style) { e.style.cssText = style; } - if (typeof content == "string") { e.appendChild(document.createTextNode(content)); } - else if (content) { for (var i = 0; i < content.length; ++i) { e.appendChild(content[i]); } } - return e - } - // wrapper for elt, which removes the elt from the accessibility tree - function eltP(tag, content, className, style) { - var e = elt(tag, content, className, style); - e.setAttribute("role", "presentation"); - return e - } + // check on default Array iterator + var isArrayIteratorMethod = function (it) { + return it !== undefined && (iterators.Array === it || ArrayPrototype$4[ITERATOR$2] === it); + }; - var range; - if (document.createRange) { - range = function (node, start, end, endNode) { - var r = document.createRange(); - r.setEnd(endNode || node, end); - r.setStart(node, start); - return r - }; - } - else { - range = function (node, start, end) { - var r = document.body.createTextRange(); - try { r.moveToElementText(node.parentNode); } - catch (e) { return r } - r.collapse(true); - r.moveEnd("character", end); - r.moveStart("character", start); - return r - }; - } + var ITERATOR$3 = wellKnownSymbol('iterator'); - function contains(parent, child) { - if (child.nodeType == 3) // Android browser always returns false when child is a textnode - { child = child.parentNode; } - if (parent.contains) { return parent.contains(child) } - do { - if (child.nodeType == 11) { child = child.host; } - if (child == parent) { return true } - } while (child = child.parentNode) - } + var getIteratorMethod = function (it) { + if (it != undefined) return getMethod(it, ITERATOR$3) + || getMethod(it, '@@iterator') + || iterators[classof(it)]; + }; - function activeElt() { - // IE and Edge may throw an "Unspecified Error" when accessing document.activeElement. - // IE < 10 will throw when accessed while the page is loading or in an iframe. - // IE > 9 and Edge will throw when accessed in an iframe if document.body is unavailable. - var activeElement; - try { - activeElement = document.activeElement; - } catch (e) { - activeElement = document.body || null; - } - while (activeElement && activeElement.shadowRoot && activeElement.shadowRoot.activeElement) { activeElement = activeElement.shadowRoot.activeElement; } - return activeElement - } + var TypeError$d = global_1.TypeError; - function addClass(node, cls) { - var current = node.className; - if (!classTest(cls).test(current)) { node.className += (current ? " " : "") + cls; } - } - function joinClasses(a, b) { - var as = a.split(" "); - for (var i = 0; i < as.length; i++) { if (as[i] && !classTest(as[i]).test(b)) { b += " " + as[i]; } } - return b - } + var getIterator = function (argument, usingIterator) { + var iteratorMethod = arguments.length < 2 ? getIteratorMethod(argument) : usingIterator; + if (aCallable(iteratorMethod)) return anObject(functionCall(iteratorMethod, argument)); + throw TypeError$d(tryToString(argument) + ' is not iterable'); + }; - var selectInput = function (node) { node.select(); }; - if (ios) // Mobile Safari apparently has a bug where select() is broken. - { selectInput = function (node) { node.selectionStart = 0; node.selectionEnd = node.value.length; }; } - else if (ie) // Suppress mysterious IE10 errors - { selectInput = function (node) { try { node.select(); } catch (_e) { } }; } + var Array$3 = global_1.Array; - function bind(f) { - var args = Array.prototype.slice.call(arguments, 1); - return function () { return f.apply(null, args) } - } + // `Array.from` method implementation + // https://tc39.es/ecma262/#sec-array.from + var arrayFrom = function from(arrayLike /* , mapfn = undefined, thisArg = undefined */) { + var O = toObject(arrayLike); + var IS_CONSTRUCTOR = isConstructor(this); + var argumentsLength = arguments.length; + var mapfn = argumentsLength > 1 ? arguments[1] : undefined; + var mapping = mapfn !== undefined; + if (mapping) mapfn = functionBindContext(mapfn, argumentsLength > 2 ? arguments[2] : undefined); + var iteratorMethod = getIteratorMethod(O); + var index = 0; + var length, result, step, iterator, next, value; + // if the target is not iterable or it's an array with the default iterator - use a simple case + if (iteratorMethod && !(this == Array$3 && isArrayIteratorMethod(iteratorMethod))) { + iterator = getIterator(O, iteratorMethod); + next = iterator.next; + result = IS_CONSTRUCTOR ? new this() : []; + for (;!(step = functionCall(next, iterator)).done; index++) { + value = mapping ? callWithSafeIterationClosing(iterator, mapfn, [step.value, index], true) : step.value; + createProperty(result, index, value); + } + } else { + length = lengthOfArrayLike(O); + result = IS_CONSTRUCTOR ? new this(length) : Array$3(length); + for (;length > index; index++) { + value = mapping ? mapfn(O[index], index) : O[index]; + createProperty(result, index, value); + } + } + result.length = index; + return result; + }; - function copyObj(obj, target, overwrite) { - if (!target) { target = {}; } - for (var prop in obj) { - if (obj.hasOwnProperty(prop) && (overwrite !== false || !target.hasOwnProperty(prop))) { target[prop] = obj[prop]; } - } - return target - } + var ITERATOR$4 = wellKnownSymbol('iterator'); + var SAFE_CLOSING = false; - // Counts the column offset in a string, taking tabs into account. - // Used mostly to find indentation. - function countColumn(string, end, tabSize, startIndex, startValue) { - if (end == null) { - end = string.search(/[^\s\u00a0]/); - if (end == -1) { end = string.length; } - } - for (var i = startIndex || 0, n = startValue || 0; ;) { - var nextTab = string.indexOf("\t", i); - if (nextTab < 0 || nextTab >= end) { return n + (end - i) } - n += nextTab - i; - n += tabSize - (n % tabSize); - i = nextTab + 1; - } - } + try { + var called = 0; + var iteratorWithReturn = { + next: function () { + return { done: !!called++ }; + }, + 'return': function () { + SAFE_CLOSING = true; + } + }; + iteratorWithReturn[ITERATOR$4] = function () { + return this; + }; + // eslint-disable-next-line es-x/no-array-from, no-throw-literal -- required for testing + Array.from(iteratorWithReturn, function () { throw 2; }); + } catch (error) { /* empty */ } - var Delayed = function () { - this.id = null; - this.f = null; - this.time = 0; - this.handler = bind(this.onTimeout, this); - }; - Delayed.prototype.onTimeout = function (self) { - self.id = 0; - if (self.time <= +new Date) { - self.f(); - } else { - setTimeout(self.handler, self.time - +new Date); - } - }; - Delayed.prototype.set = function (ms, f) { - this.f = f; - var time = +new Date + ms; - if (!this.id || time < this.time) { - clearTimeout(this.id); - this.id = setTimeout(this.handler, ms); - this.time = time; - } - }; + var checkCorrectnessOfIteration = function (exec, SKIP_CLOSING) { + if (!SKIP_CLOSING && !SAFE_CLOSING) return false; + var ITERATION_SUPPORT = false; + try { + var object = {}; + object[ITERATOR$4] = function () { + return { + next: function () { + return { done: ITERATION_SUPPORT = true }; + } + }; + }; + exec(object); + } catch (error) { /* empty */ } + return ITERATION_SUPPORT; + }; - function indexOf(array, elt) { - for (var i = 0; i < array.length; ++i) { if (array[i] == elt) { return i } } - return -1 - } + var INCORRECT_ITERATION = !checkCorrectnessOfIteration(function (iterable) { + // eslint-disable-next-line es-x/no-array-from -- required for testing + Array.from(iterable); + }); - // Number of pixels added to scroller and sizer to hide scrollbar - var scrollerGap = 50; - - // Returned or thrown by various protocols to signal 'I'm not - // handling this'. - var Pass = { toString: function () { return "CodeMirror.Pass" } }; - - // Reused option objects for setSelection & friends - var sel_dontScroll = { scroll: false }, sel_mouse = { origin: "*mouse" }, sel_move = { origin: "+move" }; - - // The inverse of countColumn -- find the offset that corresponds to - // a particular column. - function findColumn(string, goal, tabSize) { - for (var pos = 0, col = 0; ;) { - var nextTab = string.indexOf("\t", pos); - if (nextTab == -1) { nextTab = string.length; } - var skipped = nextTab - pos; - if (nextTab == string.length || col + skipped >= goal) { return pos + Math.min(skipped, goal - col) } - col += nextTab - pos; - col += tabSize - (col % tabSize); - pos = nextTab + 1; - if (col >= goal) { return pos } - } - } + // `Array.from` method + // https://tc39.es/ecma262/#sec-array.from + _export({ target: 'Array', stat: true, forced: INCORRECT_ITERATION }, { + from: arrayFrom + }); - var spaceStrs = [""]; - function spaceStr(n) { - while (spaceStrs.length <= n) { spaceStrs.push(lst(spaceStrs) + " "); } - return spaceStrs[n] - } + var from_1 = path.Array.from; - function lst(arr) { return arr[arr.length - 1] } + var from_1$1 = from_1; - function map(array, f) { - var out = []; - for (var i = 0; i < array.length; i++) { out[i] = f(array[i], i); } - return out - } + var from_1$2 = from_1$1; - function insertSorted(array, value, score) { - var pos = 0, priority = score(value); - while (pos < array.length && score(array[pos]) <= priority) { pos++; } - array.splice(pos, 0, value); - } + var MATCH = wellKnownSymbol('match'); - function nothing() { } + // `IsRegExp` abstract operation + // https://tc39.es/ecma262/#sec-isregexp + var isRegexp = function (it) { + var isRegExp; + return isObject(it) && ((isRegExp = it[MATCH]) !== undefined ? !!isRegExp : classofRaw(it) == 'RegExp'); + }; - function createObj(base, props) { - var inst; - if (Object.create) { - inst = Object.create(base); - } else { - nothing.prototype = base; - inst = new nothing(); - } - if (props) { copyObj(props, inst); } - return inst - } + var TypeError$e = global_1.TypeError; - var nonASCIISingleCaseWordChar = /[\u00df\u0587\u0590-\u05f4\u0600-\u06ff\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/; - function isWordCharBasic(ch) { - return /\w/.test(ch) || ch > "\x80" && - (ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch)) - } - function isWordChar(ch, helper) { - if (!helper) { return isWordCharBasic(ch) } - if (helper.source.indexOf("\\w") > -1 && isWordCharBasic(ch)) { return true } - return helper.test(ch) - } + var notARegexp = function (it) { + if (isRegexp(it)) { + throw TypeError$e("The method doesn't accept regular expressions"); + } return it; + }; - function isEmpty(obj) { - for (var n in obj) { if (obj.hasOwnProperty(n) && obj[n]) { return false } } - return true - } + var MATCH$1 = wellKnownSymbol('match'); - // Extending unicode characters. A series of a non-extending char + - // any number of extending chars is treated as a single unit as far - // as editing and measuring is concerned. This is not fully correct, - // since some scripts/fonts/browsers also treat other configurations - // of code points as a group. - var extendingChars = /[\u0300-\u036f\u0483-\u0489\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u065e\u0670\u06d6-\u06dc\u06de-\u06e4\u06e7\u06e8\u06ea-\u06ed\u0711\u0730-\u074a\u07a6-\u07b0\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0900-\u0902\u093c\u0941-\u0948\u094d\u0951-\u0955\u0962\u0963\u0981\u09bc\u09be\u09c1-\u09c4\u09cd\u09d7\u09e2\u09e3\u0a01\u0a02\u0a3c\u0a41\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a70\u0a71\u0a75\u0a81\u0a82\u0abc\u0ac1-\u0ac5\u0ac7\u0ac8\u0acd\u0ae2\u0ae3\u0b01\u0b3c\u0b3e\u0b3f\u0b41-\u0b44\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b82\u0bbe\u0bc0\u0bcd\u0bd7\u0c3e-\u0c40\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0cbc\u0cbf\u0cc2\u0cc6\u0ccc\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0d3e\u0d41-\u0d44\u0d4d\u0d57\u0d62\u0d63\u0dca\u0dcf\u0dd2-\u0dd4\u0dd6\u0ddf\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0f18\u0f19\u0f35\u0f37\u0f39\u0f71-\u0f7e\u0f80-\u0f84\u0f86\u0f87\u0f90-\u0f97\u0f99-\u0fbc\u0fc6\u102d-\u1030\u1032-\u1037\u1039\u103a\u103d\u103e\u1058\u1059\u105e-\u1060\u1071-\u1074\u1082\u1085\u1086\u108d\u109d\u135f\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b7-\u17bd\u17c6\u17c9-\u17d3\u17dd\u180b-\u180d\u18a9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193b\u1a17\u1a18\u1a56\u1a58-\u1a5e\u1a60\u1a62\u1a65-\u1a6c\u1a73-\u1a7c\u1a7f\u1b00-\u1b03\u1b34\u1b36-\u1b3a\u1b3c\u1b42\u1b6b-\u1b73\u1b80\u1b81\u1ba2-\u1ba5\u1ba8\u1ba9\u1c2c-\u1c33\u1c36\u1c37\u1cd0-\u1cd2\u1cd4-\u1ce0\u1ce2-\u1ce8\u1ced\u1dc0-\u1de6\u1dfd-\u1dff\u200c\u200d\u20d0-\u20f0\u2cef-\u2cf1\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua66f-\ua672\ua67c\ua67d\ua6f0\ua6f1\ua802\ua806\ua80b\ua825\ua826\ua8c4\ua8e0-\ua8f1\ua926-\ua92d\ua947-\ua951\ua980-\ua982\ua9b3\ua9b6-\ua9b9\ua9bc\uaa29-\uaa2e\uaa31\uaa32\uaa35\uaa36\uaa43\uaa4c\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uabe5\uabe8\uabed\udc00-\udfff\ufb1e\ufe00-\ufe0f\ufe20-\ufe26\uff9e\uff9f]/; - function isExtendingChar(ch) { return ch.charCodeAt(0) >= 768 && extendingChars.test(ch) } - - // Returns a number from the range [`0`; `str.length`] unless `pos` is outside that range. - function skipExtendingChars(str, pos, dir) { - while ((dir < 0 ? pos > 0 : pos < str.length) && isExtendingChar(str.charAt(pos))) { pos += dir; } - return pos - } + var correctIsRegexpLogic = function (METHOD_NAME) { + var regexp = /./; + try { + '/./'[METHOD_NAME](regexp); + } catch (error1) { + try { + regexp[MATCH$1] = false; + return '/./'[METHOD_NAME](regexp); + } catch (error2) { /* empty */ } + } return false; + }; - // Returns the value from the range [`from`; `to`] that satisfies - // `pred` and is closest to `from`. Assumes that at least `to` - // satisfies `pred`. Supports `from` being greater than `to`. - function findFirst(pred, from, to) { - // At any point we are certain `to` satisfies `pred`, don't know - // whether `from` does. - var dir = from > to ? -1 : 1; - for (; ;) { - if (from == to) { return from } - var midF = (from + to) / 2, mid = dir < 0 ? Math.ceil(midF) : Math.floor(midF); - if (mid == from) { return pred(mid) ? from : to } - if (pred(mid)) { to = mid; } - else { from = mid + dir; } - } - } + // eslint-disable-next-line es-x/no-string-prototype-startswith -- safe + var un$StartsWith = functionUncurryThis(''.startsWith); + var stringSlice$2 = functionUncurryThis(''.slice); + var min$2 = Math.min; - // BIDI HELPERS + var CORRECT_IS_REGEXP_LOGIC = correctIsRegexpLogic('startsWith'); - function iterateBidiSections(order, from, to, f) { - if (!order) { return f(from, to, "ltr", 0) } - var found = false; - for (var i = 0; i < order.length; ++i) { - var part = order[i]; - if (part.from < to && part.to > from || from == to && part.to == from) { - f(Math.max(part.from, from), Math.min(part.to, to), part.level == 1 ? "rtl" : "ltr", i); - found = true; - } - } - if (!found) { f(from, to, "ltr"); } - } + // `String.prototype.startsWith` method + // https://tc39.es/ecma262/#sec-string.prototype.startswith + _export({ target: 'String', proto: true, forced: !CORRECT_IS_REGEXP_LOGIC }, { + startsWith: function startsWith(searchString /* , position = 0 */) { + var that = toString_1(requireObjectCoercible(this)); + notARegexp(searchString); + var index = toLength(min$2(arguments.length > 1 ? arguments[1] : undefined, that.length)); + var search = toString_1(searchString); + return un$StartsWith + ? un$StartsWith(that, search, index) + : stringSlice$2(that, index, index + search.length) === search; + } + }); - var bidiOther = null; - function getBidiPartAt(order, ch, sticky) { - var found; - bidiOther = null; - for (var i = 0; i < order.length; ++i) { - var cur = order[i]; - if (cur.from < ch && cur.to > ch) { return i } - if (cur.to == ch) { - if (cur.from != cur.to && sticky == "before") { found = i; } - else { bidiOther = i; } - } - if (cur.from == ch) { - if (cur.from != cur.to && sticky != "before") { found = i; } - else { bidiOther = i; } - } - } - return found != null ? found : bidiOther - } + var startsWith = entryVirtual('String').startsWith; - // Bidirectional ordering algorithm - // See http://unicode.org/reports/tr9/tr9-13.html for the algorithm - // that this (partially) implements. - - // One-char codes used for character types: - // L (L): Left-to-Right - // R (R): Right-to-Left - // r (AL): Right-to-Left Arabic - // 1 (EN): European Number - // + (ES): European Number Separator - // % (ET): European Number Terminator - // n (AN): Arabic Number - // , (CS): Common Number Separator - // m (NSM): Non-Spacing Mark - // b (BN): Boundary Neutral - // s (B): Paragraph Separator - // t (S): Segment Separator - // w (WS): Whitespace - // N (ON): Other Neutrals - - // Returns null if characters are ordered as they appear - // (left-to-right), or an array of sections ({from, to, level} - // objects) in the order in which they occur visually. - var bidiOrdering = (function () { - // Character types for codepoints 0 to 0xff - var lowTypes = "bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLN"; - // Character types for codepoints 0x600 to 0x6f9 - var arabicTypes = "nnnnnnNNr%%r,rNNmmmmmmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmmmnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmnNmmmmmmrrmmNmmmmrr1111111111"; - function charType(code) { - if (code <= 0xf7) { return lowTypes.charAt(code) } - else if (0x590 <= code && code <= 0x5f4) { return "R" } - else if (0x600 <= code && code <= 0x6f9) { return arabicTypes.charAt(code - 0x600) } - else if (0x6ee <= code && code <= 0x8ac) { return "r" } - else if (0x2000 <= code && code <= 0x200b) { return "w" } - else if (code == 0x200c) { return "b" } - else { return "L" } - } + var StringPrototype$1 = String.prototype; - var bidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/; - var isNeutral = /[stwN]/, isStrong = /[LRr]/, countsAsLeft = /[Lb1n]/, countsAsNum = /[1n]/; + var startsWith$1 = function (it) { + var own = it.startsWith; + return typeof it == 'string' || it === StringPrototype$1 + || (objectIsPrototypeOf(StringPrototype$1, it) && own === StringPrototype$1.startsWith) ? startsWith : own; + }; - function BidiSpan(level, from, to) { - this.level = level; - this.from = from; this.to = to; - } + var startsWith$2 = startsWith$1; - return function (str, direction) { - var outerType = direction == "ltr" ? "L" : "R"; - - if (str.length == 0 || direction == "ltr" && !bidiRE.test(str)) { return false } - var len = str.length, types = []; - for (var i = 0; i < len; ++i) { types.push(charType(str.charCodeAt(i))); } - - // W1. Examine each non-spacing mark (NSM) in the level run, and - // change the type of the NSM to the type of the previous - // character. If the NSM is at the start of the level run, it will - // get the type of sor. - for (var i$1 = 0, prev = outerType; i$1 < len; ++i$1) { - var type = types[i$1]; - if (type == "m") { types[i$1] = prev; } - else { prev = type; } - } + var startsWith$3 = startsWith$2; - // W2. Search backwards from each instance of a European number - // until the first strong type (R, L, AL, or sor) is found. If an - // AL is found, change the type of the European number to Arabic - // number. - // W3. Change all ALs to R. - for (var i$2 = 0, cur = outerType; i$2 < len; ++i$2) { - var type$1 = types[i$2]; - if (type$1 == "1" && cur == "r") { types[i$2] = "n"; } - else if (isStrong.test(type$1)) { cur = type$1; if (type$1 == "r") { types[i$2] = "R"; } } - } + var $find = arrayIteration.find; - // W4. A single European separator between two European numbers - // changes to a European number. A single common separator between - // two numbers of the same type changes to that type. - for (var i$3 = 1, prev$1 = types[0]; i$3 < len - 1; ++i$3) { - var type$2 = types[i$3]; - if (type$2 == "+" && prev$1 == "1" && types[i$3 + 1] == "1") { types[i$3] = "1"; } - else if (type$2 == "," && prev$1 == types[i$3 + 1] && - (prev$1 == "1" || prev$1 == "n")) { types[i$3] = prev$1; } - prev$1 = type$2; - } - // W5. A sequence of European terminators adjacent to European - // numbers changes to all European numbers. - // W6. Otherwise, separators and terminators change to Other - // Neutral. - for (var i$4 = 0; i$4 < len; ++i$4) { - var type$3 = types[i$4]; - if (type$3 == ",") { types[i$4] = "N"; } - else if (type$3 == "%") { - var end = (void 0); - for (end = i$4 + 1; end < len && types[end] == "%"; ++end) { } - var replace = (i$4 && types[i$4 - 1] == "!") || (end < len && types[end] == "1") ? "1" : "N"; - for (var j = i$4; j < end; ++j) { types[j] = replace; } - i$4 = end - 1; - } - } + var FIND = 'find'; + var SKIPS_HOLES = true; - // W7. Search backwards from each instance of a European number - // until the first strong type (R, L, or sor) is found. If an L is - // found, then change the type of the European number to L. - for (var i$5 = 0, cur$1 = outerType; i$5 < len; ++i$5) { - var type$4 = types[i$5]; - if (cur$1 == "L" && type$4 == "1") { types[i$5] = "L"; } - else if (isStrong.test(type$4)) { cur$1 = type$4; } - } + // Shouldn't skip holes + if (FIND in []) Array(1)[FIND](function () { SKIPS_HOLES = false; }); - // N1. A sequence of neutrals takes the direction of the - // surrounding strong text if the text on both sides has the same - // direction. European and Arabic numbers act as if they were R in - // terms of their influence on neutrals. Start-of-level-run (sor) - // and end-of-level-run (eor) are used at level run boundaries. - // N2. Any remaining neutrals take the embedding direction. - for (var i$6 = 0; i$6 < len; ++i$6) { - if (isNeutral.test(types[i$6])) { - var end$1 = (void 0); - for (end$1 = i$6 + 1; end$1 < len && isNeutral.test(types[end$1]); ++end$1) { } - var before = (i$6 ? types[i$6 - 1] : outerType) == "L"; - var after = (end$1 < len ? types[end$1] : outerType) == "L"; - var replace$1 = before == after ? (before ? "L" : "R") : outerType; - for (var j$1 = i$6; j$1 < end$1; ++j$1) { types[j$1] = replace$1; } - i$6 = end$1 - 1; - } - } + // `Array.prototype.find` method + // https://tc39.es/ecma262/#sec-array.prototype.find + _export({ target: 'Array', proto: true, forced: SKIPS_HOLES }, { + find: function find(callbackfn /* , that = undefined */) { + return $find(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined); + } + }); - // Here we depart from the documented algorithm, in order to avoid - // building up an actual levels array. Since there are only three - // levels (0, 1, 2) in an implementation that doesn't take - // explicit embedding into account, we can build up the order on - // the fly, without following the level-based algorithm. - var order = [], m; - for (var i$7 = 0; i$7 < len;) { - if (countsAsLeft.test(types[i$7])) { - var start = i$7; - for (++i$7; i$7 < len && countsAsLeft.test(types[i$7]); ++i$7) { } - order.push(new BidiSpan(0, start, i$7)); - } else { - var pos = i$7, at = order.length, isRTL = direction == "rtl" ? 1 : 0; - for (++i$7; i$7 < len && types[i$7] != "L"; ++i$7) { } - for (var j$2 = pos; j$2 < i$7;) { - if (countsAsNum.test(types[j$2])) { - if (pos < j$2) { order.splice(at, 0, new BidiSpan(1, pos, j$2)); at += isRTL; } - var nstart = j$2; - for (++j$2; j$2 < i$7 && countsAsNum.test(types[j$2]); ++j$2) { } - order.splice(at, 0, new BidiSpan(2, nstart, j$2)); - at += isRTL; - pos = j$2; - } else { ++j$2; } - } - if (pos < i$7) { order.splice(at, 0, new BidiSpan(1, pos, i$7)); } - } - } - if (direction == "ltr") { - if (order[0].level == 1 && (m = str.match(/^\s+/))) { - order[0].from = m[0].length; - order.unshift(new BidiSpan(0, 0, m[0].length)); - } - if (lst(order).level == 1 && (m = str.match(/\s+$/))) { - lst(order).to -= m[0].length; - order.push(new BidiSpan(0, len - m[0].length, len)); - } - } + var find = entryVirtual('Array').find; - return direction == "rtl" ? order.reverse() : order - } - })(); - - // Get the bidi ordering for the given line (and cache it). Returns - // false for lines that are fully left-to-right, and an array of - // BidiSpan objects otherwise. - function getOrder(line, direction) { - var order = line.order; - if (order == null) { order = line.order = bidiOrdering(line.text, direction); } - return order - } + var ArrayPrototype$5 = Array.prototype; - // EVENT HANDLING + var find$1 = function (it) { + var own = it.find; + return it === ArrayPrototype$5 || (objectIsPrototypeOf(ArrayPrototype$5, it) && own === ArrayPrototype$5.find) ? find : own; + }; - // Lightweight event framework. on/off also work on DOM nodes, - // registering native DOM handlers. + var find$2 = find$1; - var noHandlers = []; + var find$3 = find$2; - var on = function (emitter, type, f) { - if (emitter.addEventListener) { - emitter.addEventListener(type, f, false); - } else if (emitter.attachEvent) { - emitter.attachEvent("on" + type, f); - } else { - var map = emitter._handlers || (emitter._handlers = {}); - map[type] = (map[type] || noHandlers).concat(f); - } - }; + var codemirror = createCommonjsModule(function (module, exports) { + // CodeMirror, copyright (c) by Marijn Haverbeke and others + // Distributed under an MIT license: https://codemirror.net/LICENSE + + // This is CodeMirror (https://codemirror.net), a code editor + // implemented in JavaScript on top of the browser's DOM. + // + // You can find some technical background for some of the code below + // at http://marijnhaverbeke.nl/blog/#cm-internals . + + (function (global, factory) { + module.exports = factory() ; + }(commonjsGlobal, (function () { + // Kludges for bugs and behavior differences that can't be feature + // detected are enabled based on userAgent etc sniffing. + var userAgent = navigator.userAgent; + var platform = navigator.platform; + + var gecko = /gecko\/\d/i.test(userAgent); + var ie_upto10 = /MSIE \d/.test(userAgent); + var ie_11up = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(userAgent); + var edge = /Edge\/(\d+)/.exec(userAgent); + var ie = ie_upto10 || ie_11up || edge; + var ie_version = ie && (ie_upto10 ? document.documentMode || 6 : +(edge || ie_11up)[1]); + var webkit = !edge && /WebKit\//.test(userAgent); + var qtwebkit = webkit && /Qt\/\d+\.\d+/.test(userAgent); + var chrome = !edge && /Chrome\//.test(userAgent); + var presto = /Opera\//.test(userAgent); + var safari = /Apple Computer/.test(navigator.vendor); + var mac_geMountainLion = /Mac OS X 1\d\D([8-9]|\d\d)\D/.test(userAgent); + var phantom = /PhantomJS/.test(userAgent); + + var ios = !edge && /AppleWebKit/.test(userAgent) && /Mobile\/\w+/.test(userAgent); + var android = /Android/.test(userAgent); + // This is woefully incomplete. Suggestions for alternative methods welcome. + var mobile = ios || android || /webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(userAgent); + var mac = ios || /Mac/.test(platform); + var chromeOS = /\bCrOS\b/.test(userAgent); + var windows = /win/i.test(platform); + + var presto_version = presto && userAgent.match(/Version\/(\d*\.\d*)/); + if (presto_version) { presto_version = Number(presto_version[1]); } + if (presto_version && presto_version >= 15) { presto = false; webkit = true; } + // Some browsers use the wrong event properties to signal cmd/ctrl on OS X + var flipCtrlCmd = mac && (qtwebkit || presto && (presto_version == null || presto_version < 12.11)); + var captureRightClick = gecko || (ie && ie_version >= 9); + + function classTest(cls) { return new RegExp("(^|\\s)" + cls + "(?:$|\\s)\\s*") } + + var rmClass = function(node, cls) { + var current = node.className; + var match = classTest(cls).exec(current); + if (match) { + var after = current.slice(match.index + match[0].length); + node.className = current.slice(0, match.index) + (after ? match[1] + after : ""); + } + }; + + function removeChildren(e) { + for (var count = e.childNodes.length; count > 0; --count) + { e.removeChild(e.firstChild); } + return e + } + + function removeChildrenAndAdd(parent, e) { + return removeChildren(parent).appendChild(e) + } + + function elt(tag, content, className, style) { + var e = document.createElement(tag); + if (className) { e.className = className; } + if (style) { e.style.cssText = style; } + if (typeof content == "string") { e.appendChild(document.createTextNode(content)); } + else if (content) { for (var i = 0; i < content.length; ++i) { e.appendChild(content[i]); } } + return e + } + // wrapper for elt, which removes the elt from the accessibility tree + function eltP(tag, content, className, style) { + var e = elt(tag, content, className, style); + e.setAttribute("role", "presentation"); + return e + } + + var range; + if (document.createRange) { range = function(node, start, end, endNode) { + var r = document.createRange(); + r.setEnd(endNode || node, end); + r.setStart(node, start); + return r + }; } + else { range = function(node, start, end) { + var r = document.body.createTextRange(); + try { r.moveToElementText(node.parentNode); } + catch(e) { return r } + r.collapse(true); + r.moveEnd("character", end); + r.moveStart("character", start); + return r + }; } + + function contains(parent, child) { + if (child.nodeType == 3) // Android browser always returns false when child is a textnode + { child = child.parentNode; } + if (parent.contains) + { return parent.contains(child) } + do { + if (child.nodeType == 11) { child = child.host; } + if (child == parent) { return true } + } while (child = child.parentNode) + } + + function activeElt() { + // IE and Edge may throw an "Unspecified Error" when accessing document.activeElement. + // IE < 10 will throw when accessed while the page is loading or in an iframe. + // IE > 9 and Edge will throw when accessed in an iframe if document.body is unavailable. + var activeElement; + try { + activeElement = document.activeElement; + } catch(e) { + activeElement = document.body || null; + } + while (activeElement && activeElement.shadowRoot && activeElement.shadowRoot.activeElement) + { activeElement = activeElement.shadowRoot.activeElement; } + return activeElement + } + + function addClass(node, cls) { + var current = node.className; + if (!classTest(cls).test(current)) { node.className += (current ? " " : "") + cls; } + } + function joinClasses(a, b) { + var as = a.split(" "); + for (var i = 0; i < as.length; i++) + { if (as[i] && !classTest(as[i]).test(b)) { b += " " + as[i]; } } + return b + } + + var selectInput = function(node) { node.select(); }; + if (ios) // Mobile Safari apparently has a bug where select() is broken. + { selectInput = function(node) { node.selectionStart = 0; node.selectionEnd = node.value.length; }; } + else if (ie) // Suppress mysterious IE10 errors + { selectInput = function(node) { try { node.select(); } catch(_e) {} }; } + + function bind(f) { + var args = Array.prototype.slice.call(arguments, 1); + return function(){return f.apply(null, args)} + } + + function copyObj(obj, target, overwrite) { + if (!target) { target = {}; } + for (var prop in obj) + { if (obj.hasOwnProperty(prop) && (overwrite !== false || !target.hasOwnProperty(prop))) + { target[prop] = obj[prop]; } } + return target + } + + // Counts the column offset in a string, taking tabs into account. + // Used mostly to find indentation. + function countColumn(string, end, tabSize, startIndex, startValue) { + if (end == null) { + end = string.search(/[^\s\u00a0]/); + if (end == -1) { end = string.length; } + } + for (var i = startIndex || 0, n = startValue || 0;;) { + var nextTab = string.indexOf("\t", i); + if (nextTab < 0 || nextTab >= end) + { return n + (end - i) } + n += nextTab - i; + n += tabSize - (n % tabSize); + i = nextTab + 1; + } + } + + var Delayed = function() { + this.id = null; + this.f = null; + this.time = 0; + this.handler = bind(this.onTimeout, this); + }; + Delayed.prototype.onTimeout = function (self) { + self.id = 0; + if (self.time <= +new Date) { + self.f(); + } else { + setTimeout(self.handler, self.time - +new Date); + } + }; + Delayed.prototype.set = function (ms, f) { + this.f = f; + var time = +new Date + ms; + if (!this.id || time < this.time) { + clearTimeout(this.id); + this.id = setTimeout(this.handler, ms); + this.time = time; + } + }; + + function indexOf(array, elt) { + for (var i = 0; i < array.length; ++i) + { if (array[i] == elt) { return i } } + return -1 + } + + // Number of pixels added to scroller and sizer to hide scrollbar + var scrollerGap = 50; + + // Returned or thrown by various protocols to signal 'I'm not + // handling this'. + var Pass = {toString: function(){return "CodeMirror.Pass"}}; + + // Reused option objects for setSelection & friends + var sel_dontScroll = {scroll: false}, sel_mouse = {origin: "*mouse"}, sel_move = {origin: "+move"}; + + // The inverse of countColumn -- find the offset that corresponds to + // a particular column. + function findColumn(string, goal, tabSize) { + for (var pos = 0, col = 0;;) { + var nextTab = string.indexOf("\t", pos); + if (nextTab == -1) { nextTab = string.length; } + var skipped = nextTab - pos; + if (nextTab == string.length || col + skipped >= goal) + { return pos + Math.min(skipped, goal - col) } + col += nextTab - pos; + col += tabSize - (col % tabSize); + pos = nextTab + 1; + if (col >= goal) { return pos } + } + } + + var spaceStrs = [""]; + function spaceStr(n) { + while (spaceStrs.length <= n) + { spaceStrs.push(lst(spaceStrs) + " "); } + return spaceStrs[n] + } + + function lst(arr) { return arr[arr.length-1] } + + function map(array, f) { + var out = []; + for (var i = 0; i < array.length; i++) { out[i] = f(array[i], i); } + return out + } + + function insertSorted(array, value, score) { + var pos = 0, priority = score(value); + while (pos < array.length && score(array[pos]) <= priority) { pos++; } + array.splice(pos, 0, value); + } + + function nothing() {} + + function createObj(base, props) { + var inst; + if (Object.create) { + inst = Object.create(base); + } else { + nothing.prototype = base; + inst = new nothing(); + } + if (props) { copyObj(props, inst); } + return inst + } + + var nonASCIISingleCaseWordChar = /[\u00df\u0587\u0590-\u05f4\u0600-\u06ff\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/; + function isWordCharBasic(ch) { + return /\w/.test(ch) || ch > "\x80" && + (ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch)) + } + function isWordChar(ch, helper) { + if (!helper) { return isWordCharBasic(ch) } + if (helper.source.indexOf("\\w") > -1 && isWordCharBasic(ch)) { return true } + return helper.test(ch) + } + + function isEmpty(obj) { + for (var n in obj) { if (obj.hasOwnProperty(n) && obj[n]) { return false } } + return true + } + + // Extending unicode characters. A series of a non-extending char + + // any number of extending chars is treated as a single unit as far + // as editing and measuring is concerned. This is not fully correct, + // since some scripts/fonts/browsers also treat other configurations + // of code points as a group. + var extendingChars = /[\u0300-\u036f\u0483-\u0489\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u065e\u0670\u06d6-\u06dc\u06de-\u06e4\u06e7\u06e8\u06ea-\u06ed\u0711\u0730-\u074a\u07a6-\u07b0\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0900-\u0902\u093c\u0941-\u0948\u094d\u0951-\u0955\u0962\u0963\u0981\u09bc\u09be\u09c1-\u09c4\u09cd\u09d7\u09e2\u09e3\u0a01\u0a02\u0a3c\u0a41\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a70\u0a71\u0a75\u0a81\u0a82\u0abc\u0ac1-\u0ac5\u0ac7\u0ac8\u0acd\u0ae2\u0ae3\u0b01\u0b3c\u0b3e\u0b3f\u0b41-\u0b44\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b82\u0bbe\u0bc0\u0bcd\u0bd7\u0c3e-\u0c40\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0cbc\u0cbf\u0cc2\u0cc6\u0ccc\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0d3e\u0d41-\u0d44\u0d4d\u0d57\u0d62\u0d63\u0dca\u0dcf\u0dd2-\u0dd4\u0dd6\u0ddf\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0f18\u0f19\u0f35\u0f37\u0f39\u0f71-\u0f7e\u0f80-\u0f84\u0f86\u0f87\u0f90-\u0f97\u0f99-\u0fbc\u0fc6\u102d-\u1030\u1032-\u1037\u1039\u103a\u103d\u103e\u1058\u1059\u105e-\u1060\u1071-\u1074\u1082\u1085\u1086\u108d\u109d\u135f\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b7-\u17bd\u17c6\u17c9-\u17d3\u17dd\u180b-\u180d\u18a9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193b\u1a17\u1a18\u1a56\u1a58-\u1a5e\u1a60\u1a62\u1a65-\u1a6c\u1a73-\u1a7c\u1a7f\u1b00-\u1b03\u1b34\u1b36-\u1b3a\u1b3c\u1b42\u1b6b-\u1b73\u1b80\u1b81\u1ba2-\u1ba5\u1ba8\u1ba9\u1c2c-\u1c33\u1c36\u1c37\u1cd0-\u1cd2\u1cd4-\u1ce0\u1ce2-\u1ce8\u1ced\u1dc0-\u1de6\u1dfd-\u1dff\u200c\u200d\u20d0-\u20f0\u2cef-\u2cf1\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua66f-\ua672\ua67c\ua67d\ua6f0\ua6f1\ua802\ua806\ua80b\ua825\ua826\ua8c4\ua8e0-\ua8f1\ua926-\ua92d\ua947-\ua951\ua980-\ua982\ua9b3\ua9b6-\ua9b9\ua9bc\uaa29-\uaa2e\uaa31\uaa32\uaa35\uaa36\uaa43\uaa4c\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uabe5\uabe8\uabed\udc00-\udfff\ufb1e\ufe00-\ufe0f\ufe20-\ufe26\uff9e\uff9f]/; + function isExtendingChar(ch) { return ch.charCodeAt(0) >= 768 && extendingChars.test(ch) } + + // Returns a number from the range [`0`; `str.length`] unless `pos` is outside that range. + function skipExtendingChars(str, pos, dir) { + while ((dir < 0 ? pos > 0 : pos < str.length) && isExtendingChar(str.charAt(pos))) { pos += dir; } + return pos + } + + // Returns the value from the range [`from`; `to`] that satisfies + // `pred` and is closest to `from`. Assumes that at least `to` + // satisfies `pred`. Supports `from` being greater than `to`. + function findFirst(pred, from, to) { + // At any point we are certain `to` satisfies `pred`, don't know + // whether `from` does. + var dir = from > to ? -1 : 1; + for (;;) { + if (from == to) { return from } + var midF = (from + to) / 2, mid = dir < 0 ? Math.ceil(midF) : Math.floor(midF); + if (mid == from) { return pred(mid) ? from : to } + if (pred(mid)) { to = mid; } + else { from = mid + dir; } + } + } + + // BIDI HELPERS + + function iterateBidiSections(order, from, to, f) { + if (!order) { return f(from, to, "ltr", 0) } + var found = false; + for (var i = 0; i < order.length; ++i) { + var part = order[i]; + if (part.from < to && part.to > from || from == to && part.to == from) { + f(Math.max(part.from, from), Math.min(part.to, to), part.level == 1 ? "rtl" : "ltr", i); + found = true; + } + } + if (!found) { f(from, to, "ltr"); } + } + + var bidiOther = null; + function getBidiPartAt(order, ch, sticky) { + var found; + bidiOther = null; + for (var i = 0; i < order.length; ++i) { + var cur = order[i]; + if (cur.from < ch && cur.to > ch) { return i } + if (cur.to == ch) { + if (cur.from != cur.to && sticky == "before") { found = i; } + else { bidiOther = i; } + } + if (cur.from == ch) { + if (cur.from != cur.to && sticky != "before") { found = i; } + else { bidiOther = i; } + } + } + return found != null ? found : bidiOther + } + + // Bidirectional ordering algorithm + // See http://unicode.org/reports/tr9/tr9-13.html for the algorithm + // that this (partially) implements. + + // One-char codes used for character types: + // L (L): Left-to-Right + // R (R): Right-to-Left + // r (AL): Right-to-Left Arabic + // 1 (EN): European Number + // + (ES): European Number Separator + // % (ET): European Number Terminator + // n (AN): Arabic Number + // , (CS): Common Number Separator + // m (NSM): Non-Spacing Mark + // b (BN): Boundary Neutral + // s (B): Paragraph Separator + // t (S): Segment Separator + // w (WS): Whitespace + // N (ON): Other Neutrals + + // Returns null if characters are ordered as they appear + // (left-to-right), or an array of sections ({from, to, level} + // objects) in the order in which they occur visually. + var bidiOrdering = (function() { + // Character types for codepoints 0 to 0xff + var lowTypes = "bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLN"; + // Character types for codepoints 0x600 to 0x6f9 + var arabicTypes = "nnnnnnNNr%%r,rNNmmmmmmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmmmnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmnNmmmmmmrrmmNmmmmrr1111111111"; + function charType(code) { + if (code <= 0xf7) { return lowTypes.charAt(code) } + else if (0x590 <= code && code <= 0x5f4) { return "R" } + else if (0x600 <= code && code <= 0x6f9) { return arabicTypes.charAt(code - 0x600) } + else if (0x6ee <= code && code <= 0x8ac) { return "r" } + else if (0x2000 <= code && code <= 0x200b) { return "w" } + else if (code == 0x200c) { return "b" } + else { return "L" } + } + + var bidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/; + var isNeutral = /[stwN]/, isStrong = /[LRr]/, countsAsLeft = /[Lb1n]/, countsAsNum = /[1n]/; + + function BidiSpan(level, from, to) { + this.level = level; + this.from = from; this.to = to; + } + + return function(str, direction) { + var outerType = direction == "ltr" ? "L" : "R"; + + if (str.length == 0 || direction == "ltr" && !bidiRE.test(str)) { return false } + var len = str.length, types = []; + for (var i = 0; i < len; ++i) + { types.push(charType(str.charCodeAt(i))); } + + // W1. Examine each non-spacing mark (NSM) in the level run, and + // change the type of the NSM to the type of the previous + // character. If the NSM is at the start of the level run, it will + // get the type of sor. + for (var i$1 = 0, prev = outerType; i$1 < len; ++i$1) { + var type = types[i$1]; + if (type == "m") { types[i$1] = prev; } + else { prev = type; } + } + + // W2. Search backwards from each instance of a European number + // until the first strong type (R, L, AL, or sor) is found. If an + // AL is found, change the type of the European number to Arabic + // number. + // W3. Change all ALs to R. + for (var i$2 = 0, cur = outerType; i$2 < len; ++i$2) { + var type$1 = types[i$2]; + if (type$1 == "1" && cur == "r") { types[i$2] = "n"; } + else if (isStrong.test(type$1)) { cur = type$1; if (type$1 == "r") { types[i$2] = "R"; } } + } + + // W4. A single European separator between two European numbers + // changes to a European number. A single common separator between + // two numbers of the same type changes to that type. + for (var i$3 = 1, prev$1 = types[0]; i$3 < len - 1; ++i$3) { + var type$2 = types[i$3]; + if (type$2 == "+" && prev$1 == "1" && types[i$3+1] == "1") { types[i$3] = "1"; } + else if (type$2 == "," && prev$1 == types[i$3+1] && + (prev$1 == "1" || prev$1 == "n")) { types[i$3] = prev$1; } + prev$1 = type$2; + } + + // W5. A sequence of European terminators adjacent to European + // numbers changes to all European numbers. + // W6. Otherwise, separators and terminators change to Other + // Neutral. + for (var i$4 = 0; i$4 < len; ++i$4) { + var type$3 = types[i$4]; + if (type$3 == ",") { types[i$4] = "N"; } + else if (type$3 == "%") { + var end = (void 0); + for (end = i$4 + 1; end < len && types[end] == "%"; ++end) {} + var replace = (i$4 && types[i$4-1] == "!") || (end < len && types[end] == "1") ? "1" : "N"; + for (var j = i$4; j < end; ++j) { types[j] = replace; } + i$4 = end - 1; + } + } + + // W7. Search backwards from each instance of a European number + // until the first strong type (R, L, or sor) is found. If an L is + // found, then change the type of the European number to L. + for (var i$5 = 0, cur$1 = outerType; i$5 < len; ++i$5) { + var type$4 = types[i$5]; + if (cur$1 == "L" && type$4 == "1") { types[i$5] = "L"; } + else if (isStrong.test(type$4)) { cur$1 = type$4; } + } + + // N1. A sequence of neutrals takes the direction of the + // surrounding strong text if the text on both sides has the same + // direction. European and Arabic numbers act as if they were R in + // terms of their influence on neutrals. Start-of-level-run (sor) + // and end-of-level-run (eor) are used at level run boundaries. + // N2. Any remaining neutrals take the embedding direction. + for (var i$6 = 0; i$6 < len; ++i$6) { + if (isNeutral.test(types[i$6])) { + var end$1 = (void 0); + for (end$1 = i$6 + 1; end$1 < len && isNeutral.test(types[end$1]); ++end$1) {} + var before = (i$6 ? types[i$6-1] : outerType) == "L"; + var after = (end$1 < len ? types[end$1] : outerType) == "L"; + var replace$1 = before == after ? (before ? "L" : "R") : outerType; + for (var j$1 = i$6; j$1 < end$1; ++j$1) { types[j$1] = replace$1; } + i$6 = end$1 - 1; + } + } + + // Here we depart from the documented algorithm, in order to avoid + // building up an actual levels array. Since there are only three + // levels (0, 1, 2) in an implementation that doesn't take + // explicit embedding into account, we can build up the order on + // the fly, without following the level-based algorithm. + var order = [], m; + for (var i$7 = 0; i$7 < len;) { + if (countsAsLeft.test(types[i$7])) { + var start = i$7; + for (++i$7; i$7 < len && countsAsLeft.test(types[i$7]); ++i$7) {} + order.push(new BidiSpan(0, start, i$7)); + } else { + var pos = i$7, at = order.length, isRTL = direction == "rtl" ? 1 : 0; + for (++i$7; i$7 < len && types[i$7] != "L"; ++i$7) {} + for (var j$2 = pos; j$2 < i$7;) { + if (countsAsNum.test(types[j$2])) { + if (pos < j$2) { order.splice(at, 0, new BidiSpan(1, pos, j$2)); at += isRTL; } + var nstart = j$2; + for (++j$2; j$2 < i$7 && countsAsNum.test(types[j$2]); ++j$2) {} + order.splice(at, 0, new BidiSpan(2, nstart, j$2)); + at += isRTL; + pos = j$2; + } else { ++j$2; } + } + if (pos < i$7) { order.splice(at, 0, new BidiSpan(1, pos, i$7)); } + } + } + if (direction == "ltr") { + if (order[0].level == 1 && (m = str.match(/^\s+/))) { + order[0].from = m[0].length; + order.unshift(new BidiSpan(0, 0, m[0].length)); + } + if (lst(order).level == 1 && (m = str.match(/\s+$/))) { + lst(order).to -= m[0].length; + order.push(new BidiSpan(0, len - m[0].length, len)); + } + } + + return direction == "rtl" ? order.reverse() : order + } + })(); + + // Get the bidi ordering for the given line (and cache it). Returns + // false for lines that are fully left-to-right, and an array of + // BidiSpan objects otherwise. + function getOrder(line, direction) { + var order = line.order; + if (order == null) { order = line.order = bidiOrdering(line.text, direction); } + return order + } + + // EVENT HANDLING + + // Lightweight event framework. on/off also work on DOM nodes, + // registering native DOM handlers. + + var noHandlers = []; + + var on = function(emitter, type, f) { + if (emitter.addEventListener) { + emitter.addEventListener(type, f, false); + } else if (emitter.attachEvent) { + emitter.attachEvent("on" + type, f); + } else { + var map = emitter._handlers || (emitter._handlers = {}); + map[type] = (map[type] || noHandlers).concat(f); + } + }; + + function getHandlers(emitter, type) { + return emitter._handlers && emitter._handlers[type] || noHandlers + } + + function off(emitter, type, f) { + if (emitter.removeEventListener) { + emitter.removeEventListener(type, f, false); + } else if (emitter.detachEvent) { + emitter.detachEvent("on" + type, f); + } else { + var map = emitter._handlers, arr = map && map[type]; + if (arr) { + var index = indexOf(arr, f); + if (index > -1) + { map[type] = arr.slice(0, index).concat(arr.slice(index + 1)); } + } + } + } + + function signal(emitter, type /*, values...*/) { + var handlers = getHandlers(emitter, type); + if (!handlers.length) { return } + var args = Array.prototype.slice.call(arguments, 2); + for (var i = 0; i < handlers.length; ++i) { handlers[i].apply(null, args); } + } + + // The DOM events that CodeMirror handles can be overridden by + // registering a (non-DOM) handler on the editor for the event name, + // and preventDefault-ing the event in that handler. + function signalDOMEvent(cm, e, override) { + if (typeof e == "string") + { e = {type: e, preventDefault: function() { this.defaultPrevented = true; }}; } + signal(cm, override || e.type, cm, e); + return e_defaultPrevented(e) || e.codemirrorIgnore + } + + function signalCursorActivity(cm) { + var arr = cm._handlers && cm._handlers.cursorActivity; + if (!arr) { return } + var set = cm.curOp.cursorActivityHandlers || (cm.curOp.cursorActivityHandlers = []); + for (var i = 0; i < arr.length; ++i) { if (indexOf(set, arr[i]) == -1) + { set.push(arr[i]); } } + } + + function hasHandler(emitter, type) { + return getHandlers(emitter, type).length > 0 + } + + // Add on and off methods to a constructor's prototype, to make + // registering events on such objects more convenient. + function eventMixin(ctor) { + ctor.prototype.on = function(type, f) {on(this, type, f);}; + ctor.prototype.off = function(type, f) {off(this, type, f);}; + } + + // Due to the fact that we still support jurassic IE versions, some + // compatibility wrappers are needed. + + function e_preventDefault(e) { + if (e.preventDefault) { e.preventDefault(); } + else { e.returnValue = false; } + } + function e_stopPropagation(e) { + if (e.stopPropagation) { e.stopPropagation(); } + else { e.cancelBubble = true; } + } + function e_defaultPrevented(e) { + return e.defaultPrevented != null ? e.defaultPrevented : e.returnValue == false + } + function e_stop(e) {e_preventDefault(e); e_stopPropagation(e);} + + function e_target(e) {return e.target || e.srcElement} + function e_button(e) { + var b = e.which; + if (b == null) { + if (e.button & 1) { b = 1; } + else if (e.button & 2) { b = 3; } + else if (e.button & 4) { b = 2; } + } + if (mac && e.ctrlKey && b == 1) { b = 3; } + return b + } + + // Detect drag-and-drop + var dragAndDrop = function() { + // There is *some* kind of drag-and-drop support in IE6-8, but I + // couldn't get it to work yet. + if (ie && ie_version < 9) { return false } + var div = elt('div'); + return "draggable" in div || "dragDrop" in div + }(); + + var zwspSupported; + function zeroWidthElement(measure) { + if (zwspSupported == null) { + var test = elt("span", "\u200b"); + removeChildrenAndAdd(measure, elt("span", [test, document.createTextNode("x")])); + if (measure.firstChild.offsetHeight != 0) + { zwspSupported = test.offsetWidth <= 1 && test.offsetHeight > 2 && !(ie && ie_version < 8); } + } + var node = zwspSupported ? elt("span", "\u200b") : + elt("span", "\u00a0", null, "display: inline-block; width: 1px; margin-right: -1px"); + node.setAttribute("cm-text", ""); + return node + } + + // Feature-detect IE's crummy client rect reporting for bidi text + var badBidiRects; + function hasBadBidiRects(measure) { + if (badBidiRects != null) { return badBidiRects } + var txt = removeChildrenAndAdd(measure, document.createTextNode("A\u062eA")); + var r0 = range(txt, 0, 1).getBoundingClientRect(); + var r1 = range(txt, 1, 2).getBoundingClientRect(); + removeChildren(measure); + if (!r0 || r0.left == r0.right) { return false } // Safari returns null in some cases (#2780) + return badBidiRects = (r1.right - r0.right < 3) + } + + // See if "".split is the broken IE version, if so, provide an + // alternative way to split lines. + var splitLinesAuto = "\n\nb".split(/\n/).length != 3 ? function (string) { + var pos = 0, result = [], l = string.length; + while (pos <= l) { + var nl = string.indexOf("\n", pos); + if (nl == -1) { nl = string.length; } + var line = string.slice(pos, string.charAt(nl - 1) == "\r" ? nl - 1 : nl); + var rt = line.indexOf("\r"); + if (rt != -1) { + result.push(line.slice(0, rt)); + pos += rt + 1; + } else { + result.push(line); + pos = nl + 1; + } + } + return result + } : function (string) { return string.split(/\r\n?|\n/); }; + + var hasSelection = window.getSelection ? function (te) { + try { return te.selectionStart != te.selectionEnd } + catch(e) { return false } + } : function (te) { + var range; + try {range = te.ownerDocument.selection.createRange();} + catch(e) {} + if (!range || range.parentElement() != te) { return false } + return range.compareEndPoints("StartToEnd", range) != 0 + }; + + var hasCopyEvent = (function () { + var e = elt("div"); + if ("oncopy" in e) { return true } + e.setAttribute("oncopy", "return;"); + return typeof e.oncopy == "function" + })(); + + var badZoomedRects = null; + function hasBadZoomedRects(measure) { + if (badZoomedRects != null) { return badZoomedRects } + var node = removeChildrenAndAdd(measure, elt("span", "x")); + var normal = node.getBoundingClientRect(); + var fromRange = range(node, 0, 1).getBoundingClientRect(); + return badZoomedRects = Math.abs(normal.left - fromRange.left) > 1 + } + + // Known modes, by name and by MIME + var modes = {}, mimeModes = {}; + + // Extra arguments are stored as the mode's dependencies, which is + // used by (legacy) mechanisms like loadmode.js to automatically + // load a mode. (Preferred mechanism is the require/define calls.) + function defineMode(name, mode) { + if (arguments.length > 2) + { mode.dependencies = Array.prototype.slice.call(arguments, 2); } + modes[name] = mode; + } + + function defineMIME(mime, spec) { + mimeModes[mime] = spec; + } + + // Given a MIME type, a {name, ...options} config object, or a name + // string, return a mode config object. + function resolveMode(spec) { + if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) { + spec = mimeModes[spec]; + } else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) { + var found = mimeModes[spec.name]; + if (typeof found == "string") { found = {name: found}; } + spec = createObj(found, spec); + spec.name = found.name; + } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+xml$/.test(spec)) { + return resolveMode("application/xml") + } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+json$/.test(spec)) { + return resolveMode("application/json") + } + if (typeof spec == "string") { return {name: spec} } + else { return spec || {name: "null"} } + } + + // Given a mode spec (anything that resolveMode accepts), find and + // initialize an actual mode object. + function getMode(options, spec) { + spec = resolveMode(spec); + var mfactory = modes[spec.name]; + if (!mfactory) { return getMode(options, "text/plain") } + var modeObj = mfactory(options, spec); + if (modeExtensions.hasOwnProperty(spec.name)) { + var exts = modeExtensions[spec.name]; + for (var prop in exts) { + if (!exts.hasOwnProperty(prop)) { continue } + if (modeObj.hasOwnProperty(prop)) { modeObj["_" + prop] = modeObj[prop]; } + modeObj[prop] = exts[prop]; + } + } + modeObj.name = spec.name; + if (spec.helperType) { modeObj.helperType = spec.helperType; } + if (spec.modeProps) { for (var prop$1 in spec.modeProps) + { modeObj[prop$1] = spec.modeProps[prop$1]; } } + + return modeObj + } + + // This can be used to attach properties to mode objects from + // outside the actual mode definition. + var modeExtensions = {}; + function extendMode(mode, properties) { + var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {}); + copyObj(properties, exts); + } + + function copyState(mode, state) { + if (state === true) { return state } + if (mode.copyState) { return mode.copyState(state) } + var nstate = {}; + for (var n in state) { + var val = state[n]; + if (val instanceof Array) { val = val.concat([]); } + nstate[n] = val; + } + return nstate + } + + // Given a mode and a state (for that mode), find the inner mode and + // state at the position that the state refers to. + function innerMode(mode, state) { + var info; + while (mode.innerMode) { + info = mode.innerMode(state); + if (!info || info.mode == mode) { break } + state = info.state; + mode = info.mode; + } + return info || {mode: mode, state: state} + } + + function startState(mode, a1, a2) { + return mode.startState ? mode.startState(a1, a2) : true + } + + // STRING STREAM + + // Fed to the mode parsers, provides helper functions to make + // parsers more succinct. + + var StringStream = function(string, tabSize, lineOracle) { + this.pos = this.start = 0; + this.string = string; + this.tabSize = tabSize || 8; + this.lastColumnPos = this.lastColumnValue = 0; + this.lineStart = 0; + this.lineOracle = lineOracle; + }; + + StringStream.prototype.eol = function () {return this.pos >= this.string.length}; + StringStream.prototype.sol = function () {return this.pos == this.lineStart}; + StringStream.prototype.peek = function () {return this.string.charAt(this.pos) || undefined}; + StringStream.prototype.next = function () { + if (this.pos < this.string.length) + { return this.string.charAt(this.pos++) } + }; + StringStream.prototype.eat = function (match) { + var ch = this.string.charAt(this.pos); + var ok; + if (typeof match == "string") { ok = ch == match; } + else { ok = ch && (match.test ? match.test(ch) : match(ch)); } + if (ok) {++this.pos; return ch} + }; + StringStream.prototype.eatWhile = function (match) { + var start = this.pos; + while (this.eat(match)){} + return this.pos > start + }; + StringStream.prototype.eatSpace = function () { + var start = this.pos; + while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) { ++this.pos; } + return this.pos > start + }; + StringStream.prototype.skipToEnd = function () {this.pos = this.string.length;}; + StringStream.prototype.skipTo = function (ch) { + var found = this.string.indexOf(ch, this.pos); + if (found > -1) {this.pos = found; return true} + }; + StringStream.prototype.backUp = function (n) {this.pos -= n;}; + StringStream.prototype.column = function () { + if (this.lastColumnPos < this.start) { + this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue); + this.lastColumnPos = this.start; + } + return this.lastColumnValue - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0) + }; + StringStream.prototype.indentation = function () { + return countColumn(this.string, null, this.tabSize) - + (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0) + }; + StringStream.prototype.match = function (pattern, consume, caseInsensitive) { + if (typeof pattern == "string") { + var cased = function (str) { return caseInsensitive ? str.toLowerCase() : str; }; + var substr = this.string.substr(this.pos, pattern.length); + if (cased(substr) == cased(pattern)) { + if (consume !== false) { this.pos += pattern.length; } + return true + } + } else { + var match = this.string.slice(this.pos).match(pattern); + if (match && match.index > 0) { return null } + if (match && consume !== false) { this.pos += match[0].length; } + return match + } + }; + StringStream.prototype.current = function (){return this.string.slice(this.start, this.pos)}; + StringStream.prototype.hideFirstChars = function (n, inner) { + this.lineStart += n; + try { return inner() } + finally { this.lineStart -= n; } + }; + StringStream.prototype.lookAhead = function (n) { + var oracle = this.lineOracle; + return oracle && oracle.lookAhead(n) + }; + StringStream.prototype.baseToken = function () { + var oracle = this.lineOracle; + return oracle && oracle.baseToken(this.pos) + }; + + // Find the line object corresponding to the given line number. + function getLine(doc, n) { + n -= doc.first; + if (n < 0 || n >= doc.size) { throw new Error("There is no line " + (n + doc.first) + " in the document.") } + var chunk = doc; + while (!chunk.lines) { + for (var i = 0;; ++i) { + var child = chunk.children[i], sz = child.chunkSize(); + if (n < sz) { chunk = child; break } + n -= sz; + } + } + return chunk.lines[n] + } + + // Get the part of a document between two positions, as an array of + // strings. + function getBetween(doc, start, end) { + var out = [], n = start.line; + doc.iter(start.line, end.line + 1, function (line) { + var text = line.text; + if (n == end.line) { text = text.slice(0, end.ch); } + if (n == start.line) { text = text.slice(start.ch); } + out.push(text); + ++n; + }); + return out + } + // Get the lines between from and to, as array of strings. + function getLines(doc, from, to) { + var out = []; + doc.iter(from, to, function (line) { out.push(line.text); }); // iter aborts when callback returns truthy value + return out + } + + // Update the height of a line, propagating the height change + // upwards to parent nodes. + function updateLineHeight(line, height) { + var diff = height - line.height; + if (diff) { for (var n = line; n; n = n.parent) { n.height += diff; } } + } + + // Given a line object, find its line number by walking up through + // its parent links. + function lineNo(line) { + if (line.parent == null) { return null } + var cur = line.parent, no = indexOf(cur.lines, line); + for (var chunk = cur.parent; chunk; cur = chunk, chunk = chunk.parent) { + for (var i = 0;; ++i) { + if (chunk.children[i] == cur) { break } + no += chunk.children[i].chunkSize(); + } + } + return no + cur.first + } + + // Find the line at the given vertical position, using the height + // information in the document tree. + function lineAtHeight(chunk, h) { + var n = chunk.first; + outer: do { + for (var i$1 = 0; i$1 < chunk.children.length; ++i$1) { + var child = chunk.children[i$1], ch = child.height; + if (h < ch) { chunk = child; continue outer } + h -= ch; + n += child.chunkSize(); + } + return n + } while (!chunk.lines) + var i = 0; + for (; i < chunk.lines.length; ++i) { + var line = chunk.lines[i], lh = line.height; + if (h < lh) { break } + h -= lh; + } + return n + i + } + + function isLine(doc, l) {return l >= doc.first && l < doc.first + doc.size} + + function lineNumberFor(options, i) { + return String(options.lineNumberFormatter(i + options.firstLineNumber)) + } + + // A Pos instance represents a position within the text. + function Pos(line, ch, sticky) { + if ( sticky === void 0 ) sticky = null; + + if (!(this instanceof Pos)) { return new Pos(line, ch, sticky) } + this.line = line; + this.ch = ch; + this.sticky = sticky; + } + + // Compare two positions, return 0 if they are the same, a negative + // number when a is less, and a positive number otherwise. + function cmp(a, b) { return a.line - b.line || a.ch - b.ch } + + function equalCursorPos(a, b) { return a.sticky == b.sticky && cmp(a, b) == 0 } + + function copyPos(x) {return Pos(x.line, x.ch)} + function maxPos(a, b) { return cmp(a, b) < 0 ? b : a } + function minPos(a, b) { return cmp(a, b) < 0 ? a : b } + + // Most of the external API clips given positions to make sure they + // actually exist within the document. + function clipLine(doc, n) {return Math.max(doc.first, Math.min(n, doc.first + doc.size - 1))} + function clipPos(doc, pos) { + if (pos.line < doc.first) { return Pos(doc.first, 0) } + var last = doc.first + doc.size - 1; + if (pos.line > last) { return Pos(last, getLine(doc, last).text.length) } + return clipToLen(pos, getLine(doc, pos.line).text.length) + } + function clipToLen(pos, linelen) { + var ch = pos.ch; + if (ch == null || ch > linelen) { return Pos(pos.line, linelen) } + else if (ch < 0) { return Pos(pos.line, 0) } + else { return pos } + } + function clipPosArray(doc, array) { + var out = []; + for (var i = 0; i < array.length; i++) { out[i] = clipPos(doc, array[i]); } + return out + } + + var SavedContext = function(state, lookAhead) { + this.state = state; + this.lookAhead = lookAhead; + }; + + var Context = function(doc, state, line, lookAhead) { + this.state = state; + this.doc = doc; + this.line = line; + this.maxLookAhead = lookAhead || 0; + this.baseTokens = null; + this.baseTokenPos = 1; + }; + + Context.prototype.lookAhead = function (n) { + var line = this.doc.getLine(this.line + n); + if (line != null && n > this.maxLookAhead) { this.maxLookAhead = n; } + return line + }; + + Context.prototype.baseToken = function (n) { + if (!this.baseTokens) { return null } + while (this.baseTokens[this.baseTokenPos] <= n) + { this.baseTokenPos += 2; } + var type = this.baseTokens[this.baseTokenPos + 1]; + return {type: type && type.replace(/( |^)overlay .*/, ""), + size: this.baseTokens[this.baseTokenPos] - n} + }; + + Context.prototype.nextLine = function () { + this.line++; + if (this.maxLookAhead > 0) { this.maxLookAhead--; } + }; + + Context.fromSaved = function (doc, saved, line) { + if (saved instanceof SavedContext) + { return new Context(doc, copyState(doc.mode, saved.state), line, saved.lookAhead) } + else + { return new Context(doc, copyState(doc.mode, saved), line) } + }; + + Context.prototype.save = function (copy) { + var state = copy !== false ? copyState(this.doc.mode, this.state) : this.state; + return this.maxLookAhead > 0 ? new SavedContext(state, this.maxLookAhead) : state + }; + + + // Compute a style array (an array starting with a mode generation + // -- for invalidation -- followed by pairs of end positions and + // style strings), which is used to highlight the tokens on the + // line. + function highlightLine(cm, line, context, forceToEnd) { + // A styles array always starts with a number identifying the + // mode/overlays that it is based on (for easy invalidation). + var st = [cm.state.modeGen], lineClasses = {}; + // Compute the base array of styles + runMode(cm, line.text, cm.doc.mode, context, function (end, style) { return st.push(end, style); }, + lineClasses, forceToEnd); + var state = context.state; + + // Run overlays, adjust style array. + var loop = function ( o ) { + context.baseTokens = st; + var overlay = cm.state.overlays[o], i = 1, at = 0; + context.state = true; + runMode(cm, line.text, overlay.mode, context, function (end, style) { + var start = i; + // Ensure there's a token end at the current position, and that i points at it + while (at < end) { + var i_end = st[i]; + if (i_end > end) + { st.splice(i, 1, end, st[i+1], i_end); } + i += 2; + at = Math.min(end, i_end); + } + if (!style) { return } + if (overlay.opaque) { + st.splice(start, i - start, end, "overlay " + style); + i = start + 2; + } else { + for (; start < i; start += 2) { + var cur = st[start+1]; + st[start+1] = (cur ? cur + " " : "") + "overlay " + style; + } + } + }, lineClasses); + context.state = state; + context.baseTokens = null; + context.baseTokenPos = 1; + }; + + for (var o = 0; o < cm.state.overlays.length; ++o) loop( o ); + + return {styles: st, classes: lineClasses.bgClass || lineClasses.textClass ? lineClasses : null} + } + + function getLineStyles(cm, line, updateFrontier) { + if (!line.styles || line.styles[0] != cm.state.modeGen) { + var context = getContextBefore(cm, lineNo(line)); + var resetState = line.text.length > cm.options.maxHighlightLength && copyState(cm.doc.mode, context.state); + var result = highlightLine(cm, line, context); + if (resetState) { context.state = resetState; } + line.stateAfter = context.save(!resetState); + line.styles = result.styles; + if (result.classes) { line.styleClasses = result.classes; } + else if (line.styleClasses) { line.styleClasses = null; } + if (updateFrontier === cm.doc.highlightFrontier) + { cm.doc.modeFrontier = Math.max(cm.doc.modeFrontier, ++cm.doc.highlightFrontier); } + } + return line.styles + } + + function getContextBefore(cm, n, precise) { + var doc = cm.doc, display = cm.display; + if (!doc.mode.startState) { return new Context(doc, true, n) } + var start = findStartLine(cm, n, precise); + var saved = start > doc.first && getLine(doc, start - 1).stateAfter; + var context = saved ? Context.fromSaved(doc, saved, start) : new Context(doc, startState(doc.mode), start); + + doc.iter(start, n, function (line) { + processLine(cm, line.text, context); + var pos = context.line; + line.stateAfter = pos == n - 1 || pos % 5 == 0 || pos >= display.viewFrom && pos < display.viewTo ? context.save() : null; + context.nextLine(); + }); + if (precise) { doc.modeFrontier = context.line; } + return context + } + + // Lightweight form of highlight -- proceed over this line and + // update state, but don't save a style array. Used for lines that + // aren't currently visible. + function processLine(cm, text, context, startAt) { + var mode = cm.doc.mode; + var stream = new StringStream(text, cm.options.tabSize, context); + stream.start = stream.pos = startAt || 0; + if (text == "") { callBlankLine(mode, context.state); } + while (!stream.eol()) { + readToken(mode, stream, context.state); + stream.start = stream.pos; + } + } + + function callBlankLine(mode, state) { + if (mode.blankLine) { return mode.blankLine(state) } + if (!mode.innerMode) { return } + var inner = innerMode(mode, state); + if (inner.mode.blankLine) { return inner.mode.blankLine(inner.state) } + } + + function readToken(mode, stream, state, inner) { + for (var i = 0; i < 10; i++) { + if (inner) { inner[0] = innerMode(mode, state).mode; } + var style = mode.token(stream, state); + if (stream.pos > stream.start) { return style } + } + throw new Error("Mode " + mode.name + " failed to advance stream.") + } + + var Token = function(stream, type, state) { + this.start = stream.start; this.end = stream.pos; + this.string = stream.current(); + this.type = type || null; + this.state = state; + }; + + // Utility for getTokenAt and getLineTokens + function takeToken(cm, pos, precise, asArray) { + var doc = cm.doc, mode = doc.mode, style; + pos = clipPos(doc, pos); + var line = getLine(doc, pos.line), context = getContextBefore(cm, pos.line, precise); + var stream = new StringStream(line.text, cm.options.tabSize, context), tokens; + if (asArray) { tokens = []; } + while ((asArray || stream.pos < pos.ch) && !stream.eol()) { + stream.start = stream.pos; + style = readToken(mode, stream, context.state); + if (asArray) { tokens.push(new Token(stream, style, copyState(doc.mode, context.state))); } + } + return asArray ? tokens : new Token(stream, style, context.state) + } + + function extractLineClasses(type, output) { + if (type) { for (;;) { + var lineClass = type.match(/(?:^|\s+)line-(background-)?(\S+)/); + if (!lineClass) { break } + type = type.slice(0, lineClass.index) + type.slice(lineClass.index + lineClass[0].length); + var prop = lineClass[1] ? "bgClass" : "textClass"; + if (output[prop] == null) + { output[prop] = lineClass[2]; } + else if (!(new RegExp("(?:^|\\s)" + lineClass[2] + "(?:$|\\s)")).test(output[prop])) + { output[prop] += " " + lineClass[2]; } + } } + return type + } + + // Run the given mode's parser over a line, calling f for each token. + function runMode(cm, text, mode, context, f, lineClasses, forceToEnd) { + var flattenSpans = mode.flattenSpans; + if (flattenSpans == null) { flattenSpans = cm.options.flattenSpans; } + var curStart = 0, curStyle = null; + var stream = new StringStream(text, cm.options.tabSize, context), style; + var inner = cm.options.addModeClass && [null]; + if (text == "") { extractLineClasses(callBlankLine(mode, context.state), lineClasses); } + while (!stream.eol()) { + if (stream.pos > cm.options.maxHighlightLength) { + flattenSpans = false; + if (forceToEnd) { processLine(cm, text, context, stream.pos); } + stream.pos = text.length; + style = null; + } else { + style = extractLineClasses(readToken(mode, stream, context.state, inner), lineClasses); + } + if (inner) { + var mName = inner[0].name; + if (mName) { style = "m-" + (style ? mName + " " + style : mName); } + } + if (!flattenSpans || curStyle != style) { + while (curStart < stream.start) { + curStart = Math.min(stream.start, curStart + 5000); + f(curStart, curStyle); + } + curStyle = style; + } + stream.start = stream.pos; + } + while (curStart < stream.pos) { + // Webkit seems to refuse to render text nodes longer than 57444 + // characters, and returns inaccurate measurements in nodes + // starting around 5000 chars. + var pos = Math.min(stream.pos, curStart + 5000); + f(pos, curStyle); + curStart = pos; + } + } + + // Finds the line to start with when starting a parse. Tries to + // find a line with a stateAfter, so that it can start with a + // valid state. If that fails, it returns the line with the + // smallest indentation, which tends to need the least context to + // parse correctly. + function findStartLine(cm, n, precise) { + var minindent, minline, doc = cm.doc; + var lim = precise ? -1 : n - (cm.doc.mode.innerMode ? 1000 : 100); + for (var search = n; search > lim; --search) { + if (search <= doc.first) { return doc.first } + var line = getLine(doc, search - 1), after = line.stateAfter; + if (after && (!precise || search + (after instanceof SavedContext ? after.lookAhead : 0) <= doc.modeFrontier)) + { return search } + var indented = countColumn(line.text, null, cm.options.tabSize); + if (minline == null || minindent > indented) { + minline = search - 1; + minindent = indented; + } + } + return minline + } + + function retreatFrontier(doc, n) { + doc.modeFrontier = Math.min(doc.modeFrontier, n); + if (doc.highlightFrontier < n - 10) { return } + var start = doc.first; + for (var line = n - 1; line > start; line--) { + var saved = getLine(doc, line).stateAfter; + // change is on 3 + // state on line 1 looked ahead 2 -- so saw 3 + // test 1 + 2 < 3 should cover this + if (saved && (!(saved instanceof SavedContext) || line + saved.lookAhead < n)) { + start = line + 1; + break + } + } + doc.highlightFrontier = Math.min(doc.highlightFrontier, start); + } + + // Optimize some code when these features are not used. + var sawReadOnlySpans = false, sawCollapsedSpans = false; + + function seeReadOnlySpans() { + sawReadOnlySpans = true; + } + + function seeCollapsedSpans() { + sawCollapsedSpans = true; + } + + // TEXTMARKER SPANS + + function MarkedSpan(marker, from, to) { + this.marker = marker; + this.from = from; this.to = to; + } + + // Search an array of spans for a span matching the given marker. + function getMarkedSpanFor(spans, marker) { + if (spans) { for (var i = 0; i < spans.length; ++i) { + var span = spans[i]; + if (span.marker == marker) { return span } + } } + } + // Remove a span from an array, returning undefined if no spans are + // left (we don't store arrays for lines without spans). + function removeMarkedSpan(spans, span) { + var r; + for (var i = 0; i < spans.length; ++i) + { if (spans[i] != span) { (r || (r = [])).push(spans[i]); } } + return r + } + // Add a span to a line. + function addMarkedSpan(line, span) { + line.markedSpans = line.markedSpans ? line.markedSpans.concat([span]) : [span]; + span.marker.attachLine(line); + } + + // Used for the algorithm that adjusts markers for a change in the + // document. These functions cut an array of spans at a given + // character position, returning an array of remaining chunks (or + // undefined if nothing remains). + function markedSpansBefore(old, startCh, isInsert) { + var nw; + if (old) { for (var i = 0; i < old.length; ++i) { + var span = old[i], marker = span.marker; + var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= startCh : span.from < startCh); + if (startsBefore || span.from == startCh && marker.type == "bookmark" && (!isInsert || !span.marker.insertLeft)) { + var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= startCh : span.to > startCh) + ;(nw || (nw = [])).push(new MarkedSpan(marker, span.from, endsAfter ? null : span.to)); + } + } } + return nw + } + function markedSpansAfter(old, endCh, isInsert) { + var nw; + if (old) { for (var i = 0; i < old.length; ++i) { + var span = old[i], marker = span.marker; + var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= endCh : span.to > endCh); + if (endsAfter || span.from == endCh && marker.type == "bookmark" && (!isInsert || span.marker.insertLeft)) { + var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= endCh : span.from < endCh) + ;(nw || (nw = [])).push(new MarkedSpan(marker, startsBefore ? null : span.from - endCh, + span.to == null ? null : span.to - endCh)); + } + } } + return nw + } + + // Given a change object, compute the new set of marker spans that + // cover the line in which the change took place. Removes spans + // entirely within the change, reconnects spans belonging to the + // same marker that appear on both sides of the change, and cuts off + // spans partially within the change. Returns an array of span + // arrays with one element for each line in (after) the change. + function stretchSpansOverChange(doc, change) { + if (change.full) { return null } + var oldFirst = isLine(doc, change.from.line) && getLine(doc, change.from.line).markedSpans; + var oldLast = isLine(doc, change.to.line) && getLine(doc, change.to.line).markedSpans; + if (!oldFirst && !oldLast) { return null } + + var startCh = change.from.ch, endCh = change.to.ch, isInsert = cmp(change.from, change.to) == 0; + // Get the spans that 'stick out' on both sides + var first = markedSpansBefore(oldFirst, startCh, isInsert); + var last = markedSpansAfter(oldLast, endCh, isInsert); + + // Next, merge those two ends + var sameLine = change.text.length == 1, offset = lst(change.text).length + (sameLine ? startCh : 0); + if (first) { + // Fix up .to properties of first + for (var i = 0; i < first.length; ++i) { + var span = first[i]; + if (span.to == null) { + var found = getMarkedSpanFor(last, span.marker); + if (!found) { span.to = startCh; } + else if (sameLine) { span.to = found.to == null ? null : found.to + offset; } + } + } + } + if (last) { + // Fix up .from in last (or move them into first in case of sameLine) + for (var i$1 = 0; i$1 < last.length; ++i$1) { + var span$1 = last[i$1]; + if (span$1.to != null) { span$1.to += offset; } + if (span$1.from == null) { + var found$1 = getMarkedSpanFor(first, span$1.marker); + if (!found$1) { + span$1.from = offset; + if (sameLine) { (first || (first = [])).push(span$1); } + } + } else { + span$1.from += offset; + if (sameLine) { (first || (first = [])).push(span$1); } + } + } + } + // Make sure we didn't create any zero-length spans + if (first) { first = clearEmptySpans(first); } + if (last && last != first) { last = clearEmptySpans(last); } + + var newMarkers = [first]; + if (!sameLine) { + // Fill gap with whole-line-spans + var gap = change.text.length - 2, gapMarkers; + if (gap > 0 && first) + { for (var i$2 = 0; i$2 < first.length; ++i$2) + { if (first[i$2].to == null) + { (gapMarkers || (gapMarkers = [])).push(new MarkedSpan(first[i$2].marker, null, null)); } } } + for (var i$3 = 0; i$3 < gap; ++i$3) + { newMarkers.push(gapMarkers); } + newMarkers.push(last); + } + return newMarkers + } + + // Remove spans that are empty and don't have a clearWhenEmpty + // option of false. + function clearEmptySpans(spans) { + for (var i = 0; i < spans.length; ++i) { + var span = spans[i]; + if (span.from != null && span.from == span.to && span.marker.clearWhenEmpty !== false) + { spans.splice(i--, 1); } + } + if (!spans.length) { return null } + return spans + } + + // Used to 'clip' out readOnly ranges when making a change. + function removeReadOnlyRanges(doc, from, to) { + var markers = null; + doc.iter(from.line, to.line + 1, function (line) { + if (line.markedSpans) { for (var i = 0; i < line.markedSpans.length; ++i) { + var mark = line.markedSpans[i].marker; + if (mark.readOnly && (!markers || indexOf(markers, mark) == -1)) + { (markers || (markers = [])).push(mark); } + } } + }); + if (!markers) { return null } + var parts = [{from: from, to: to}]; + for (var i = 0; i < markers.length; ++i) { + var mk = markers[i], m = mk.find(0); + for (var j = 0; j < parts.length; ++j) { + var p = parts[j]; + if (cmp(p.to, m.from) < 0 || cmp(p.from, m.to) > 0) { continue } + var newParts = [j, 1], dfrom = cmp(p.from, m.from), dto = cmp(p.to, m.to); + if (dfrom < 0 || !mk.inclusiveLeft && !dfrom) + { newParts.push({from: p.from, to: m.from}); } + if (dto > 0 || !mk.inclusiveRight && !dto) + { newParts.push({from: m.to, to: p.to}); } + parts.splice.apply(parts, newParts); + j += newParts.length - 3; + } + } + return parts + } + + // Connect or disconnect spans from a line. + function detachMarkedSpans(line) { + var spans = line.markedSpans; + if (!spans) { return } + for (var i = 0; i < spans.length; ++i) + { spans[i].marker.detachLine(line); } + line.markedSpans = null; + } + function attachMarkedSpans(line, spans) { + if (!spans) { return } + for (var i = 0; i < spans.length; ++i) + { spans[i].marker.attachLine(line); } + line.markedSpans = spans; + } + + // Helpers used when computing which overlapping collapsed span + // counts as the larger one. + function extraLeft(marker) { return marker.inclusiveLeft ? -1 : 0 } + function extraRight(marker) { return marker.inclusiveRight ? 1 : 0 } + + // Returns a number indicating which of two overlapping collapsed + // spans is larger (and thus includes the other). Falls back to + // comparing ids when the spans cover exactly the same range. + function compareCollapsedMarkers(a, b) { + var lenDiff = a.lines.length - b.lines.length; + if (lenDiff != 0) { return lenDiff } + var aPos = a.find(), bPos = b.find(); + var fromCmp = cmp(aPos.from, bPos.from) || extraLeft(a) - extraLeft(b); + if (fromCmp) { return -fromCmp } + var toCmp = cmp(aPos.to, bPos.to) || extraRight(a) - extraRight(b); + if (toCmp) { return toCmp } + return b.id - a.id + } + + // Find out whether a line ends or starts in a collapsed span. If + // so, return the marker for that span. + function collapsedSpanAtSide(line, start) { + var sps = sawCollapsedSpans && line.markedSpans, found; + if (sps) { for (var sp = (void 0), i = 0; i < sps.length; ++i) { + sp = sps[i]; + if (sp.marker.collapsed && (start ? sp.from : sp.to) == null && + (!found || compareCollapsedMarkers(found, sp.marker) < 0)) + { found = sp.marker; } + } } + return found + } + function collapsedSpanAtStart(line) { return collapsedSpanAtSide(line, true) } + function collapsedSpanAtEnd(line) { return collapsedSpanAtSide(line, false) } + + function collapsedSpanAround(line, ch) { + var sps = sawCollapsedSpans && line.markedSpans, found; + if (sps) { for (var i = 0; i < sps.length; ++i) { + var sp = sps[i]; + if (sp.marker.collapsed && (sp.from == null || sp.from < ch) && (sp.to == null || sp.to > ch) && + (!found || compareCollapsedMarkers(found, sp.marker) < 0)) { found = sp.marker; } + } } + return found + } + + // Test whether there exists a collapsed span that partially + // overlaps (covers the start or end, but not both) of a new span. + // Such overlap is not allowed. + function conflictingCollapsedRange(doc, lineNo, from, to, marker) { + var line = getLine(doc, lineNo); + var sps = sawCollapsedSpans && line.markedSpans; + if (sps) { for (var i = 0; i < sps.length; ++i) { + var sp = sps[i]; + if (!sp.marker.collapsed) { continue } + var found = sp.marker.find(0); + var fromCmp = cmp(found.from, from) || extraLeft(sp.marker) - extraLeft(marker); + var toCmp = cmp(found.to, to) || extraRight(sp.marker) - extraRight(marker); + if (fromCmp >= 0 && toCmp <= 0 || fromCmp <= 0 && toCmp >= 0) { continue } + if (fromCmp <= 0 && (sp.marker.inclusiveRight && marker.inclusiveLeft ? cmp(found.to, from) >= 0 : cmp(found.to, from) > 0) || + fromCmp >= 0 && (sp.marker.inclusiveRight && marker.inclusiveLeft ? cmp(found.from, to) <= 0 : cmp(found.from, to) < 0)) + { return true } + } } + } + + // A visual line is a line as drawn on the screen. Folding, for + // example, can cause multiple logical lines to appear on the same + // visual line. This finds the start of the visual line that the + // given line is part of (usually that is the line itself). + function visualLine(line) { + var merged; + while (merged = collapsedSpanAtStart(line)) + { line = merged.find(-1, true).line; } + return line + } + + function visualLineEnd(line) { + var merged; + while (merged = collapsedSpanAtEnd(line)) + { line = merged.find(1, true).line; } + return line + } + + // Returns an array of logical lines that continue the visual line + // started by the argument, or undefined if there are no such lines. + function visualLineContinued(line) { + var merged, lines; + while (merged = collapsedSpanAtEnd(line)) { + line = merged.find(1, true).line + ;(lines || (lines = [])).push(line); + } + return lines + } + + // Get the line number of the start of the visual line that the + // given line number is part of. + function visualLineNo(doc, lineN) { + var line = getLine(doc, lineN), vis = visualLine(line); + if (line == vis) { return lineN } + return lineNo(vis) + } + + // Get the line number of the start of the next visual line after + // the given line. + function visualLineEndNo(doc, lineN) { + if (lineN > doc.lastLine()) { return lineN } + var line = getLine(doc, lineN), merged; + if (!lineIsHidden(doc, line)) { return lineN } + while (merged = collapsedSpanAtEnd(line)) + { line = merged.find(1, true).line; } + return lineNo(line) + 1 + } + + // Compute whether a line is hidden. Lines count as hidden when they + // are part of a visual line that starts with another line, or when + // they are entirely covered by collapsed, non-widget span. + function lineIsHidden(doc, line) { + var sps = sawCollapsedSpans && line.markedSpans; + if (sps) { for (var sp = (void 0), i = 0; i < sps.length; ++i) { + sp = sps[i]; + if (!sp.marker.collapsed) { continue } + if (sp.from == null) { return true } + if (sp.marker.widgetNode) { continue } + if (sp.from == 0 && sp.marker.inclusiveLeft && lineIsHiddenInner(doc, line, sp)) + { return true } + } } + } + function lineIsHiddenInner(doc, line, span) { + if (span.to == null) { + var end = span.marker.find(1, true); + return lineIsHiddenInner(doc, end.line, getMarkedSpanFor(end.line.markedSpans, span.marker)) + } + if (span.marker.inclusiveRight && span.to == line.text.length) + { return true } + for (var sp = (void 0), i = 0; i < line.markedSpans.length; ++i) { + sp = line.markedSpans[i]; + if (sp.marker.collapsed && !sp.marker.widgetNode && sp.from == span.to && + (sp.to == null || sp.to != span.from) && + (sp.marker.inclusiveLeft || span.marker.inclusiveRight) && + lineIsHiddenInner(doc, line, sp)) { return true } + } + } + + // Find the height above the given line. + function heightAtLine(lineObj) { + lineObj = visualLine(lineObj); + + var h = 0, chunk = lineObj.parent; + for (var i = 0; i < chunk.lines.length; ++i) { + var line = chunk.lines[i]; + if (line == lineObj) { break } + else { h += line.height; } + } + for (var p = chunk.parent; p; chunk = p, p = chunk.parent) { + for (var i$1 = 0; i$1 < p.children.length; ++i$1) { + var cur = p.children[i$1]; + if (cur == chunk) { break } + else { h += cur.height; } + } + } + return h + } + + // Compute the character length of a line, taking into account + // collapsed ranges (see markText) that might hide parts, and join + // other lines onto it. + function lineLength(line) { + if (line.height == 0) { return 0 } + var len = line.text.length, merged, cur = line; + while (merged = collapsedSpanAtStart(cur)) { + var found = merged.find(0, true); + cur = found.from.line; + len += found.from.ch - found.to.ch; + } + cur = line; + while (merged = collapsedSpanAtEnd(cur)) { + var found$1 = merged.find(0, true); + len -= cur.text.length - found$1.from.ch; + cur = found$1.to.line; + len += cur.text.length - found$1.to.ch; + } + return len + } + + // Find the longest line in the document. + function findMaxLine(cm) { + var d = cm.display, doc = cm.doc; + d.maxLine = getLine(doc, doc.first); + d.maxLineLength = lineLength(d.maxLine); + d.maxLineChanged = true; + doc.iter(function (line) { + var len = lineLength(line); + if (len > d.maxLineLength) { + d.maxLineLength = len; + d.maxLine = line; + } + }); + } + + // LINE DATA STRUCTURE + + // Line objects. These hold state related to a line, including + // highlighting info (the styles array). + var Line = function(text, markedSpans, estimateHeight) { + this.text = text; + attachMarkedSpans(this, markedSpans); + this.height = estimateHeight ? estimateHeight(this) : 1; + }; + + Line.prototype.lineNo = function () { return lineNo(this) }; + eventMixin(Line); + + // Change the content (text, markers) of a line. Automatically + // invalidates cached information and tries to re-estimate the + // line's height. + function updateLine(line, text, markedSpans, estimateHeight) { + line.text = text; + if (line.stateAfter) { line.stateAfter = null; } + if (line.styles) { line.styles = null; } + if (line.order != null) { line.order = null; } + detachMarkedSpans(line); + attachMarkedSpans(line, markedSpans); + var estHeight = estimateHeight ? estimateHeight(line) : 1; + if (estHeight != line.height) { updateLineHeight(line, estHeight); } + } + + // Detach a line from the document tree and its markers. + function cleanUpLine(line) { + line.parent = null; + detachMarkedSpans(line); + } + + // Convert a style as returned by a mode (either null, or a string + // containing one or more styles) to a CSS style. This is cached, + // and also looks for line-wide styles. + var styleToClassCache = {}, styleToClassCacheWithMode = {}; + function interpretTokenStyle(style, options) { + if (!style || /^\s*$/.test(style)) { return null } + var cache = options.addModeClass ? styleToClassCacheWithMode : styleToClassCache; + return cache[style] || + (cache[style] = style.replace(/\S+/g, "cm-$&")) + } + + // Render the DOM representation of the text of a line. Also builds + // up a 'line map', which points at the DOM nodes that represent + // specific stretches of text, and is used by the measuring code. + // The returned object contains the DOM node, this map, and + // information about line-wide styles that were set by the mode. + function buildLineContent(cm, lineView) { + // The padding-right forces the element to have a 'border', which + // is needed on Webkit to be able to get line-level bounding + // rectangles for it (in measureChar). + var content = eltP("span", null, null, webkit ? "padding-right: .1px" : null); + var builder = {pre: eltP("pre", [content], "CodeMirror-line"), content: content, + col: 0, pos: 0, cm: cm, + trailingSpace: false, + splitSpaces: cm.getOption("lineWrapping")}; + lineView.measure = {}; + + // Iterate over the logical lines that make up this visual line. + for (var i = 0; i <= (lineView.rest ? lineView.rest.length : 0); i++) { + var line = i ? lineView.rest[i - 1] : lineView.line, order = (void 0); + builder.pos = 0; + builder.addToken = buildToken; + // Optionally wire in some hacks into the token-rendering + // algorithm, to deal with browser quirks. + if (hasBadBidiRects(cm.display.measure) && (order = getOrder(line, cm.doc.direction))) + { builder.addToken = buildTokenBadBidi(builder.addToken, order); } + builder.map = []; + var allowFrontierUpdate = lineView != cm.display.externalMeasured && lineNo(line); + insertLineContent(line, builder, getLineStyles(cm, line, allowFrontierUpdate)); + if (line.styleClasses) { + if (line.styleClasses.bgClass) + { builder.bgClass = joinClasses(line.styleClasses.bgClass, builder.bgClass || ""); } + if (line.styleClasses.textClass) + { builder.textClass = joinClasses(line.styleClasses.textClass, builder.textClass || ""); } + } + + // Ensure at least a single node is present, for measuring. + if (builder.map.length == 0) + { builder.map.push(0, 0, builder.content.appendChild(zeroWidthElement(cm.display.measure))); } + + // Store the map and a cache object for the current logical line + if (i == 0) { + lineView.measure.map = builder.map; + lineView.measure.cache = {}; + } else { + (lineView.measure.maps || (lineView.measure.maps = [])).push(builder.map) + ;(lineView.measure.caches || (lineView.measure.caches = [])).push({}); + } + } + + // See issue #2901 + if (webkit) { + var last = builder.content.lastChild; + if (/\bcm-tab\b/.test(last.className) || (last.querySelector && last.querySelector(".cm-tab"))) + { builder.content.className = "cm-tab-wrap-hack"; } + } + + signal(cm, "renderLine", cm, lineView.line, builder.pre); + if (builder.pre.className) + { builder.textClass = joinClasses(builder.pre.className, builder.textClass || ""); } + + return builder + } + + function defaultSpecialCharPlaceholder(ch) { + var token = elt("span", "\u2022", "cm-invalidchar"); + token.title = "\\u" + ch.charCodeAt(0).toString(16); + token.setAttribute("aria-label", token.title); + return token + } + + // Build up the DOM representation for a single token, and add it to + // the line map. Takes care to render special characters separately. + function buildToken(builder, text, style, startStyle, endStyle, css, attributes) { + if (!text) { return } + var displayText = builder.splitSpaces ? splitSpaces(text, builder.trailingSpace) : text; + var special = builder.cm.state.specialChars, mustWrap = false; + var content; + if (!special.test(text)) { + builder.col += text.length; + content = document.createTextNode(displayText); + builder.map.push(builder.pos, builder.pos + text.length, content); + if (ie && ie_version < 9) { mustWrap = true; } + builder.pos += text.length; + } else { + content = document.createDocumentFragment(); + var pos = 0; + while (true) { + special.lastIndex = pos; + var m = special.exec(text); + var skipped = m ? m.index - pos : text.length - pos; + if (skipped) { + var txt = document.createTextNode(displayText.slice(pos, pos + skipped)); + if (ie && ie_version < 9) { content.appendChild(elt("span", [txt])); } + else { content.appendChild(txt); } + builder.map.push(builder.pos, builder.pos + skipped, txt); + builder.col += skipped; + builder.pos += skipped; + } + if (!m) { break } + pos += skipped + 1; + var txt$1 = (void 0); + if (m[0] == "\t") { + var tabSize = builder.cm.options.tabSize, tabWidth = tabSize - builder.col % tabSize; + txt$1 = content.appendChild(elt("span", spaceStr(tabWidth), "cm-tab")); + txt$1.setAttribute("role", "presentation"); + txt$1.setAttribute("cm-text", "\t"); + builder.col += tabWidth; + } else if (m[0] == "\r" || m[0] == "\n") { + txt$1 = content.appendChild(elt("span", m[0] == "\r" ? "\u240d" : "\u2424", "cm-invalidchar")); + txt$1.setAttribute("cm-text", m[0]); + builder.col += 1; + } else { + txt$1 = builder.cm.options.specialCharPlaceholder(m[0]); + txt$1.setAttribute("cm-text", m[0]); + if (ie && ie_version < 9) { content.appendChild(elt("span", [txt$1])); } + else { content.appendChild(txt$1); } + builder.col += 1; + } + builder.map.push(builder.pos, builder.pos + 1, txt$1); + builder.pos++; + } + } + builder.trailingSpace = displayText.charCodeAt(text.length - 1) == 32; + if (style || startStyle || endStyle || mustWrap || css || attributes) { + var fullStyle = style || ""; + if (startStyle) { fullStyle += startStyle; } + if (endStyle) { fullStyle += endStyle; } + var token = elt("span", [content], fullStyle, css); + if (attributes) { + for (var attr in attributes) { if (attributes.hasOwnProperty(attr) && attr != "style" && attr != "class") + { token.setAttribute(attr, attributes[attr]); } } + } + return builder.content.appendChild(token) + } + builder.content.appendChild(content); + } + + // Change some spaces to NBSP to prevent the browser from collapsing + // trailing spaces at the end of a line when rendering text (issue #1362). + function splitSpaces(text, trailingBefore) { + if (text.length > 1 && !/ /.test(text)) { return text } + var spaceBefore = trailingBefore, result = ""; + for (var i = 0; i < text.length; i++) { + var ch = text.charAt(i); + if (ch == " " && spaceBefore && (i == text.length - 1 || text.charCodeAt(i + 1) == 32)) + { ch = "\u00a0"; } + result += ch; + spaceBefore = ch == " "; + } + return result + } + + // Work around nonsense dimensions being reported for stretches of + // right-to-left text. + function buildTokenBadBidi(inner, order) { + return function (builder, text, style, startStyle, endStyle, css, attributes) { + style = style ? style + " cm-force-border" : "cm-force-border"; + var start = builder.pos, end = start + text.length; + for (;;) { + // Find the part that overlaps with the start of this text + var part = (void 0); + for (var i = 0; i < order.length; i++) { + part = order[i]; + if (part.to > start && part.from <= start) { break } + } + if (part.to >= end) { return inner(builder, text, style, startStyle, endStyle, css, attributes) } + inner(builder, text.slice(0, part.to - start), style, startStyle, null, css, attributes); + startStyle = null; + text = text.slice(part.to - start); + start = part.to; + } + } + } + + function buildCollapsedSpan(builder, size, marker, ignoreWidget) { + var widget = !ignoreWidget && marker.widgetNode; + if (widget) { builder.map.push(builder.pos, builder.pos + size, widget); } + if (!ignoreWidget && builder.cm.display.input.needsContentAttribute) { + if (!widget) + { widget = builder.content.appendChild(document.createElement("span")); } + widget.setAttribute("cm-marker", marker.id); + } + if (widget) { + builder.cm.display.input.setUneditable(widget); + builder.content.appendChild(widget); + } + builder.pos += size; + builder.trailingSpace = false; + } + + // Outputs a number of spans to make up a line, taking highlighting + // and marked text into account. + function insertLineContent(line, builder, styles) { + var spans = line.markedSpans, allText = line.text, at = 0; + if (!spans) { + for (var i$1 = 1; i$1 < styles.length; i$1+=2) + { builder.addToken(builder, allText.slice(at, at = styles[i$1]), interpretTokenStyle(styles[i$1+1], builder.cm.options)); } + return + } + + var len = allText.length, pos = 0, i = 1, text = "", style, css; + var nextChange = 0, spanStyle, spanEndStyle, spanStartStyle, collapsed, attributes; + for (;;) { + if (nextChange == pos) { // Update current marker set + spanStyle = spanEndStyle = spanStartStyle = css = ""; + attributes = null; + collapsed = null; nextChange = Infinity; + var foundBookmarks = [], endStyles = (void 0); + for (var j = 0; j < spans.length; ++j) { + var sp = spans[j], m = sp.marker; + if (m.type == "bookmark" && sp.from == pos && m.widgetNode) { + foundBookmarks.push(m); + } else if (sp.from <= pos && (sp.to == null || sp.to > pos || m.collapsed && sp.to == pos && sp.from == pos)) { + if (sp.to != null && sp.to != pos && nextChange > sp.to) { + nextChange = sp.to; + spanEndStyle = ""; + } + if (m.className) { spanStyle += " " + m.className; } + if (m.css) { css = (css ? css + ";" : "") + m.css; } + if (m.startStyle && sp.from == pos) { spanStartStyle += " " + m.startStyle; } + if (m.endStyle && sp.to == nextChange) { (endStyles || (endStyles = [])).push(m.endStyle, sp.to); } + // support for the old title property + // https://github.com/codemirror/CodeMirror/pull/5673 + if (m.title) { (attributes || (attributes = {})).title = m.title; } + if (m.attributes) { + for (var attr in m.attributes) + { (attributes || (attributes = {}))[attr] = m.attributes[attr]; } + } + if (m.collapsed && (!collapsed || compareCollapsedMarkers(collapsed.marker, m) < 0)) + { collapsed = sp; } + } else if (sp.from > pos && nextChange > sp.from) { + nextChange = sp.from; + } + } + if (endStyles) { for (var j$1 = 0; j$1 < endStyles.length; j$1 += 2) + { if (endStyles[j$1 + 1] == nextChange) { spanEndStyle += " " + endStyles[j$1]; } } } + + if (!collapsed || collapsed.from == pos) { for (var j$2 = 0; j$2 < foundBookmarks.length; ++j$2) + { buildCollapsedSpan(builder, 0, foundBookmarks[j$2]); } } + if (collapsed && (collapsed.from || 0) == pos) { + buildCollapsedSpan(builder, (collapsed.to == null ? len + 1 : collapsed.to) - pos, + collapsed.marker, collapsed.from == null); + if (collapsed.to == null) { return } + if (collapsed.to == pos) { collapsed = false; } + } + } + if (pos >= len) { break } + + var upto = Math.min(len, nextChange); + while (true) { + if (text) { + var end = pos + text.length; + if (!collapsed) { + var tokenText = end > upto ? text.slice(0, upto - pos) : text; + builder.addToken(builder, tokenText, style ? style + spanStyle : spanStyle, + spanStartStyle, pos + tokenText.length == nextChange ? spanEndStyle : "", css, attributes); + } + if (end >= upto) {text = text.slice(upto - pos); pos = upto; break} + pos = end; + spanStartStyle = ""; + } + text = allText.slice(at, at = styles[i++]); + style = interpretTokenStyle(styles[i++], builder.cm.options); + } + } + } + + + // These objects are used to represent the visible (currently drawn) + // part of the document. A LineView may correspond to multiple + // logical lines, if those are connected by collapsed ranges. + function LineView(doc, line, lineN) { + // The starting line + this.line = line; + // Continuing lines, if any + this.rest = visualLineContinued(line); + // Number of logical lines in this visual line + this.size = this.rest ? lineNo(lst(this.rest)) - lineN + 1 : 1; + this.node = this.text = null; + this.hidden = lineIsHidden(doc, line); + } + + // Create a range of LineView objects for the given lines. + function buildViewArray(cm, from, to) { + var array = [], nextPos; + for (var pos = from; pos < to; pos = nextPos) { + var view = new LineView(cm.doc, getLine(cm.doc, pos), pos); + nextPos = pos + view.size; + array.push(view); + } + return array + } + + var operationGroup = null; + + function pushOperation(op) { + if (operationGroup) { + operationGroup.ops.push(op); + } else { + op.ownsGroup = operationGroup = { + ops: [op], + delayedCallbacks: [] + }; + } + } + + function fireCallbacksForOps(group) { + // Calls delayed callbacks and cursorActivity handlers until no + // new ones appear + var callbacks = group.delayedCallbacks, i = 0; + do { + for (; i < callbacks.length; i++) + { callbacks[i].call(null); } + for (var j = 0; j < group.ops.length; j++) { + var op = group.ops[j]; + if (op.cursorActivityHandlers) + { while (op.cursorActivityCalled < op.cursorActivityHandlers.length) + { op.cursorActivityHandlers[op.cursorActivityCalled++].call(null, op.cm); } } + } + } while (i < callbacks.length) + } + + function finishOperation(op, endCb) { + var group = op.ownsGroup; + if (!group) { return } + + try { fireCallbacksForOps(group); } + finally { + operationGroup = null; + endCb(group); + } + } + + var orphanDelayedCallbacks = null; + + // Often, we want to signal events at a point where we are in the + // middle of some work, but don't want the handler to start calling + // other methods on the editor, which might be in an inconsistent + // state or simply not expect any other events to happen. + // signalLater looks whether there are any handlers, and schedules + // them to be executed when the last operation ends, or, if no + // operation is active, when a timeout fires. + function signalLater(emitter, type /*, values...*/) { + var arr = getHandlers(emitter, type); + if (!arr.length) { return } + var args = Array.prototype.slice.call(arguments, 2), list; + if (operationGroup) { + list = operationGroup.delayedCallbacks; + } else if (orphanDelayedCallbacks) { + list = orphanDelayedCallbacks; + } else { + list = orphanDelayedCallbacks = []; + setTimeout(fireOrphanDelayed, 0); + } + var loop = function ( i ) { + list.push(function () { return arr[i].apply(null, args); }); + }; + + for (var i = 0; i < arr.length; ++i) + loop( i ); + } + + function fireOrphanDelayed() { + var delayed = orphanDelayedCallbacks; + orphanDelayedCallbacks = null; + for (var i = 0; i < delayed.length; ++i) { delayed[i](); } + } + + // When an aspect of a line changes, a string is added to + // lineView.changes. This updates the relevant part of the line's + // DOM structure. + function updateLineForChanges(cm, lineView, lineN, dims) { + for (var j = 0; j < lineView.changes.length; j++) { + var type = lineView.changes[j]; + if (type == "text") { updateLineText(cm, lineView); } + else if (type == "gutter") { updateLineGutter(cm, lineView, lineN, dims); } + else if (type == "class") { updateLineClasses(cm, lineView); } + else if (type == "widget") { updateLineWidgets(cm, lineView, dims); } + } + lineView.changes = null; + } + + // Lines with gutter elements, widgets or a background class need to + // be wrapped, and have the extra elements added to the wrapper div + function ensureLineWrapped(lineView) { + if (lineView.node == lineView.text) { + lineView.node = elt("div", null, null, "position: relative"); + if (lineView.text.parentNode) + { lineView.text.parentNode.replaceChild(lineView.node, lineView.text); } + lineView.node.appendChild(lineView.text); + if (ie && ie_version < 8) { lineView.node.style.zIndex = 2; } + } + return lineView.node + } + + function updateLineBackground(cm, lineView) { + var cls = lineView.bgClass ? lineView.bgClass + " " + (lineView.line.bgClass || "") : lineView.line.bgClass; + if (cls) { cls += " CodeMirror-linebackground"; } + if (lineView.background) { + if (cls) { lineView.background.className = cls; } + else { lineView.background.parentNode.removeChild(lineView.background); lineView.background = null; } + } else if (cls) { + var wrap = ensureLineWrapped(lineView); + lineView.background = wrap.insertBefore(elt("div", null, cls), wrap.firstChild); + cm.display.input.setUneditable(lineView.background); + } + } + + // Wrapper around buildLineContent which will reuse the structure + // in display.externalMeasured when possible. + function getLineContent(cm, lineView) { + var ext = cm.display.externalMeasured; + if (ext && ext.line == lineView.line) { + cm.display.externalMeasured = null; + lineView.measure = ext.measure; + return ext.built + } + return buildLineContent(cm, lineView) + } + + // Redraw the line's text. Interacts with the background and text + // classes because the mode may output tokens that influence these + // classes. + function updateLineText(cm, lineView) { + var cls = lineView.text.className; + var built = getLineContent(cm, lineView); + if (lineView.text == lineView.node) { lineView.node = built.pre; } + lineView.text.parentNode.replaceChild(built.pre, lineView.text); + lineView.text = built.pre; + if (built.bgClass != lineView.bgClass || built.textClass != lineView.textClass) { + lineView.bgClass = built.bgClass; + lineView.textClass = built.textClass; + updateLineClasses(cm, lineView); + } else if (cls) { + lineView.text.className = cls; + } + } + + function updateLineClasses(cm, lineView) { + updateLineBackground(cm, lineView); + if (lineView.line.wrapClass) + { ensureLineWrapped(lineView).className = lineView.line.wrapClass; } + else if (lineView.node != lineView.text) + { lineView.node.className = ""; } + var textClass = lineView.textClass ? lineView.textClass + " " + (lineView.line.textClass || "") : lineView.line.textClass; + lineView.text.className = textClass || ""; + } + + function updateLineGutter(cm, lineView, lineN, dims) { + if (lineView.gutter) { + lineView.node.removeChild(lineView.gutter); + lineView.gutter = null; + } + if (lineView.gutterBackground) { + lineView.node.removeChild(lineView.gutterBackground); + lineView.gutterBackground = null; + } + if (lineView.line.gutterClass) { + var wrap = ensureLineWrapped(lineView); + lineView.gutterBackground = elt("div", null, "CodeMirror-gutter-background " + lineView.line.gutterClass, + ("left: " + (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px; width: " + (dims.gutterTotalWidth) + "px")); + cm.display.input.setUneditable(lineView.gutterBackground); + wrap.insertBefore(lineView.gutterBackground, lineView.text); + } + var markers = lineView.line.gutterMarkers; + if (cm.options.lineNumbers || markers) { + var wrap$1 = ensureLineWrapped(lineView); + var gutterWrap = lineView.gutter = elt("div", null, "CodeMirror-gutter-wrapper", ("left: " + (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px")); + cm.display.input.setUneditable(gutterWrap); + wrap$1.insertBefore(gutterWrap, lineView.text); + if (lineView.line.gutterClass) + { gutterWrap.className += " " + lineView.line.gutterClass; } + if (cm.options.lineNumbers && (!markers || !markers["CodeMirror-linenumbers"])) + { lineView.lineNumber = gutterWrap.appendChild( + elt("div", lineNumberFor(cm.options, lineN), + "CodeMirror-linenumber CodeMirror-gutter-elt", + ("left: " + (dims.gutterLeft["CodeMirror-linenumbers"]) + "px; width: " + (cm.display.lineNumInnerWidth) + "px"))); } + if (markers) { for (var k = 0; k < cm.display.gutterSpecs.length; ++k) { + var id = cm.display.gutterSpecs[k].className, found = markers.hasOwnProperty(id) && markers[id]; + if (found) + { gutterWrap.appendChild(elt("div", [found], "CodeMirror-gutter-elt", + ("left: " + (dims.gutterLeft[id]) + "px; width: " + (dims.gutterWidth[id]) + "px"))); } + } } + } + } + + function updateLineWidgets(cm, lineView, dims) { + if (lineView.alignable) { lineView.alignable = null; } + var isWidget = classTest("CodeMirror-linewidget"); + for (var node = lineView.node.firstChild, next = (void 0); node; node = next) { + next = node.nextSibling; + if (isWidget.test(node.className)) { lineView.node.removeChild(node); } + } + insertLineWidgets(cm, lineView, dims); + } + + // Build a line's DOM representation from scratch + function buildLineElement(cm, lineView, lineN, dims) { + var built = getLineContent(cm, lineView); + lineView.text = lineView.node = built.pre; + if (built.bgClass) { lineView.bgClass = built.bgClass; } + if (built.textClass) { lineView.textClass = built.textClass; } + + updateLineClasses(cm, lineView); + updateLineGutter(cm, lineView, lineN, dims); + insertLineWidgets(cm, lineView, dims); + return lineView.node + } + + // A lineView may contain multiple logical lines (when merged by + // collapsed spans). The widgets for all of them need to be drawn. + function insertLineWidgets(cm, lineView, dims) { + insertLineWidgetsFor(cm, lineView.line, lineView, dims, true); + if (lineView.rest) { for (var i = 0; i < lineView.rest.length; i++) + { insertLineWidgetsFor(cm, lineView.rest[i], lineView, dims, false); } } + } + + function insertLineWidgetsFor(cm, line, lineView, dims, allowAbove) { + if (!line.widgets) { return } + var wrap = ensureLineWrapped(lineView); + for (var i = 0, ws = line.widgets; i < ws.length; ++i) { + var widget = ws[i], node = elt("div", [widget.node], "CodeMirror-linewidget" + (widget.className ? " " + widget.className : "")); + if (!widget.handleMouseEvents) { node.setAttribute("cm-ignore-events", "true"); } + positionLineWidget(widget, node, lineView, dims); + cm.display.input.setUneditable(node); + if (allowAbove && widget.above) + { wrap.insertBefore(node, lineView.gutter || lineView.text); } + else + { wrap.appendChild(node); } + signalLater(widget, "redraw"); + } + } + + function positionLineWidget(widget, node, lineView, dims) { + if (widget.noHScroll) { + (lineView.alignable || (lineView.alignable = [])).push(node); + var width = dims.wrapperWidth; + node.style.left = dims.fixedPos + "px"; + if (!widget.coverGutter) { + width -= dims.gutterTotalWidth; + node.style.paddingLeft = dims.gutterTotalWidth + "px"; + } + node.style.width = width + "px"; + } + if (widget.coverGutter) { + node.style.zIndex = 5; + node.style.position = "relative"; + if (!widget.noHScroll) { node.style.marginLeft = -dims.gutterTotalWidth + "px"; } + } + } + + function widgetHeight(widget) { + if (widget.height != null) { return widget.height } + var cm = widget.doc.cm; + if (!cm) { return 0 } + if (!contains(document.body, widget.node)) { + var parentStyle = "position: relative;"; + if (widget.coverGutter) + { parentStyle += "margin-left: -" + cm.display.gutters.offsetWidth + "px;"; } + if (widget.noHScroll) + { parentStyle += "width: " + cm.display.wrapper.clientWidth + "px;"; } + removeChildrenAndAdd(cm.display.measure, elt("div", [widget.node], null, parentStyle)); + } + return widget.height = widget.node.parentNode.offsetHeight + } + + // Return true when the given mouse event happened in a widget + function eventInWidget(display, e) { + for (var n = e_target(e); n != display.wrapper; n = n.parentNode) { + if (!n || (n.nodeType == 1 && n.getAttribute("cm-ignore-events") == "true") || + (n.parentNode == display.sizer && n != display.mover)) + { return true } + } + } + + // POSITION MEASUREMENT + + function paddingTop(display) {return display.lineSpace.offsetTop} + function paddingVert(display) {return display.mover.offsetHeight - display.lineSpace.offsetHeight} + function paddingH(display) { + if (display.cachedPaddingH) { return display.cachedPaddingH } + var e = removeChildrenAndAdd(display.measure, elt("pre", "x", "CodeMirror-line-like")); + var style = window.getComputedStyle ? window.getComputedStyle(e) : e.currentStyle; + var data = {left: parseInt(style.paddingLeft), right: parseInt(style.paddingRight)}; + if (!isNaN(data.left) && !isNaN(data.right)) { display.cachedPaddingH = data; } + return data + } + + function scrollGap(cm) { return scrollerGap - cm.display.nativeBarWidth } + function displayWidth(cm) { + return cm.display.scroller.clientWidth - scrollGap(cm) - cm.display.barWidth + } + function displayHeight(cm) { + return cm.display.scroller.clientHeight - scrollGap(cm) - cm.display.barHeight + } + + // Ensure the lineView.wrapping.heights array is populated. This is + // an array of bottom offsets for the lines that make up a drawn + // line. When lineWrapping is on, there might be more than one + // height. + function ensureLineHeights(cm, lineView, rect) { + var wrapping = cm.options.lineWrapping; + var curWidth = wrapping && displayWidth(cm); + if (!lineView.measure.heights || wrapping && lineView.measure.width != curWidth) { + var heights = lineView.measure.heights = []; + if (wrapping) { + lineView.measure.width = curWidth; + var rects = lineView.text.firstChild.getClientRects(); + for (var i = 0; i < rects.length - 1; i++) { + var cur = rects[i], next = rects[i + 1]; + if (Math.abs(cur.bottom - next.bottom) > 2) + { heights.push((cur.bottom + next.top) / 2 - rect.top); } + } + } + heights.push(rect.bottom - rect.top); + } + } + + // Find a line map (mapping character offsets to text nodes) and a + // measurement cache for the given line number. (A line view might + // contain multiple lines when collapsed ranges are present.) + function mapFromLineView(lineView, line, lineN) { + if (lineView.line == line) + { return {map: lineView.measure.map, cache: lineView.measure.cache} } + for (var i = 0; i < lineView.rest.length; i++) + { if (lineView.rest[i] == line) + { return {map: lineView.measure.maps[i], cache: lineView.measure.caches[i]} } } + for (var i$1 = 0; i$1 < lineView.rest.length; i$1++) + { if (lineNo(lineView.rest[i$1]) > lineN) + { return {map: lineView.measure.maps[i$1], cache: lineView.measure.caches[i$1], before: true} } } + } + + // Render a line into the hidden node display.externalMeasured. Used + // when measurement is needed for a line that's not in the viewport. + function updateExternalMeasurement(cm, line) { + line = visualLine(line); + var lineN = lineNo(line); + var view = cm.display.externalMeasured = new LineView(cm.doc, line, lineN); + view.lineN = lineN; + var built = view.built = buildLineContent(cm, view); + view.text = built.pre; + removeChildrenAndAdd(cm.display.lineMeasure, built.pre); + return view + } + + // Get a {top, bottom, left, right} box (in line-local coordinates) + // for a given character. + function measureChar(cm, line, ch, bias) { + return measureCharPrepared(cm, prepareMeasureForLine(cm, line), ch, bias) + } + + // Find a line view that corresponds to the given line number. + function findViewForLine(cm, lineN) { + if (lineN >= cm.display.viewFrom && lineN < cm.display.viewTo) + { return cm.display.view[findViewIndex(cm, lineN)] } + var ext = cm.display.externalMeasured; + if (ext && lineN >= ext.lineN && lineN < ext.lineN + ext.size) + { return ext } + } + + // Measurement can be split in two steps, the set-up work that + // applies to the whole line, and the measurement of the actual + // character. Functions like coordsChar, that need to do a lot of + // measurements in a row, can thus ensure that the set-up work is + // only done once. + function prepareMeasureForLine(cm, line) { + var lineN = lineNo(line); + var view = findViewForLine(cm, lineN); + if (view && !view.text) { + view = null; + } else if (view && view.changes) { + updateLineForChanges(cm, view, lineN, getDimensions(cm)); + cm.curOp.forceUpdate = true; + } + if (!view) + { view = updateExternalMeasurement(cm, line); } + + var info = mapFromLineView(view, line, lineN); + return { + line: line, view: view, rect: null, + map: info.map, cache: info.cache, before: info.before, + hasHeights: false + } + } + + // Given a prepared measurement object, measures the position of an + // actual character (or fetches it from the cache). + function measureCharPrepared(cm, prepared, ch, bias, varHeight) { + if (prepared.before) { ch = -1; } + var key = ch + (bias || ""), found; + if (prepared.cache.hasOwnProperty(key)) { + found = prepared.cache[key]; + } else { + if (!prepared.rect) + { prepared.rect = prepared.view.text.getBoundingClientRect(); } + if (!prepared.hasHeights) { + ensureLineHeights(cm, prepared.view, prepared.rect); + prepared.hasHeights = true; + } + found = measureCharInner(cm, prepared, ch, bias); + if (!found.bogus) { prepared.cache[key] = found; } + } + return {left: found.left, right: found.right, + top: varHeight ? found.rtop : found.top, + bottom: varHeight ? found.rbottom : found.bottom} + } + + var nullRect = {left: 0, right: 0, top: 0, bottom: 0}; + + function nodeAndOffsetInLineMap(map, ch, bias) { + var node, start, end, collapse, mStart, mEnd; + // First, search the line map for the text node corresponding to, + // or closest to, the target character. + for (var i = 0; i < map.length; i += 3) { + mStart = map[i]; + mEnd = map[i + 1]; + if (ch < mStart) { + start = 0; end = 1; + collapse = "left"; + } else if (ch < mEnd) { + start = ch - mStart; + end = start + 1; + } else if (i == map.length - 3 || ch == mEnd && map[i + 3] > ch) { + end = mEnd - mStart; + start = end - 1; + if (ch >= mEnd) { collapse = "right"; } + } + if (start != null) { + node = map[i + 2]; + if (mStart == mEnd && bias == (node.insertLeft ? "left" : "right")) + { collapse = bias; } + if (bias == "left" && start == 0) + { while (i && map[i - 2] == map[i - 3] && map[i - 1].insertLeft) { + node = map[(i -= 3) + 2]; + collapse = "left"; + } } + if (bias == "right" && start == mEnd - mStart) + { while (i < map.length - 3 && map[i + 3] == map[i + 4] && !map[i + 5].insertLeft) { + node = map[(i += 3) + 2]; + collapse = "right"; + } } + break + } + } + return {node: node, start: start, end: end, collapse: collapse, coverStart: mStart, coverEnd: mEnd} + } + + function getUsefulRect(rects, bias) { + var rect = nullRect; + if (bias == "left") { for (var i = 0; i < rects.length; i++) { + if ((rect = rects[i]).left != rect.right) { break } + } } else { for (var i$1 = rects.length - 1; i$1 >= 0; i$1--) { + if ((rect = rects[i$1]).left != rect.right) { break } + } } + return rect + } + + function measureCharInner(cm, prepared, ch, bias) { + var place = nodeAndOffsetInLineMap(prepared.map, ch, bias); + var node = place.node, start = place.start, end = place.end, collapse = place.collapse; + + var rect; + if (node.nodeType == 3) { // If it is a text node, use a range to retrieve the coordinates. + for (var i$1 = 0; i$1 < 4; i$1++) { // Retry a maximum of 4 times when nonsense rectangles are returned + while (start && isExtendingChar(prepared.line.text.charAt(place.coverStart + start))) { --start; } + while (place.coverStart + end < place.coverEnd && isExtendingChar(prepared.line.text.charAt(place.coverStart + end))) { ++end; } + if (ie && ie_version < 9 && start == 0 && end == place.coverEnd - place.coverStart) + { rect = node.parentNode.getBoundingClientRect(); } + else + { rect = getUsefulRect(range(node, start, end).getClientRects(), bias); } + if (rect.left || rect.right || start == 0) { break } + end = start; + start = start - 1; + collapse = "right"; + } + if (ie && ie_version < 11) { rect = maybeUpdateRectForZooming(cm.display.measure, rect); } + } else { // If it is a widget, simply get the box for the whole widget. + if (start > 0) { collapse = bias = "right"; } + var rects; + if (cm.options.lineWrapping && (rects = node.getClientRects()).length > 1) + { rect = rects[bias == "right" ? rects.length - 1 : 0]; } + else + { rect = node.getBoundingClientRect(); } + } + if (ie && ie_version < 9 && !start && (!rect || !rect.left && !rect.right)) { + var rSpan = node.parentNode.getClientRects()[0]; + if (rSpan) + { rect = {left: rSpan.left, right: rSpan.left + charWidth(cm.display), top: rSpan.top, bottom: rSpan.bottom}; } + else + { rect = nullRect; } + } + + var rtop = rect.top - prepared.rect.top, rbot = rect.bottom - prepared.rect.top; + var mid = (rtop + rbot) / 2; + var heights = prepared.view.measure.heights; + var i = 0; + for (; i < heights.length - 1; i++) + { if (mid < heights[i]) { break } } + var top = i ? heights[i - 1] : 0, bot = heights[i]; + var result = {left: (collapse == "right" ? rect.right : rect.left) - prepared.rect.left, + right: (collapse == "left" ? rect.left : rect.right) - prepared.rect.left, + top: top, bottom: bot}; + if (!rect.left && !rect.right) { result.bogus = true; } + if (!cm.options.singleCursorHeightPerLine) { result.rtop = rtop; result.rbottom = rbot; } + + return result + } + + // Work around problem with bounding client rects on ranges being + // returned incorrectly when zoomed on IE10 and below. + function maybeUpdateRectForZooming(measure, rect) { + if (!window.screen || screen.logicalXDPI == null || + screen.logicalXDPI == screen.deviceXDPI || !hasBadZoomedRects(measure)) + { return rect } + var scaleX = screen.logicalXDPI / screen.deviceXDPI; + var scaleY = screen.logicalYDPI / screen.deviceYDPI; + return {left: rect.left * scaleX, right: rect.right * scaleX, + top: rect.top * scaleY, bottom: rect.bottom * scaleY} + } + + function clearLineMeasurementCacheFor(lineView) { + if (lineView.measure) { + lineView.measure.cache = {}; + lineView.measure.heights = null; + if (lineView.rest) { for (var i = 0; i < lineView.rest.length; i++) + { lineView.measure.caches[i] = {}; } } + } + } + + function clearLineMeasurementCache(cm) { + cm.display.externalMeasure = null; + removeChildren(cm.display.lineMeasure); + for (var i = 0; i < cm.display.view.length; i++) + { clearLineMeasurementCacheFor(cm.display.view[i]); } + } + + function clearCaches(cm) { + clearLineMeasurementCache(cm); + cm.display.cachedCharWidth = cm.display.cachedTextHeight = cm.display.cachedPaddingH = null; + if (!cm.options.lineWrapping) { cm.display.maxLineChanged = true; } + cm.display.lineNumChars = null; + } + + function pageScrollX() { + // Work around https://bugs.chromium.org/p/chromium/issues/detail?id=489206 + // which causes page_Offset and bounding client rects to use + // different reference viewports and invalidate our calculations. + if (chrome && android) { return -(document.body.getBoundingClientRect().left - parseInt(getComputedStyle(document.body).marginLeft)) } + return window.pageXOffset || (document.documentElement || document.body).scrollLeft + } + function pageScrollY() { + if (chrome && android) { return -(document.body.getBoundingClientRect().top - parseInt(getComputedStyle(document.body).marginTop)) } + return window.pageYOffset || (document.documentElement || document.body).scrollTop + } + + function widgetTopHeight(lineObj) { + var height = 0; + if (lineObj.widgets) { for (var i = 0; i < lineObj.widgets.length; ++i) { if (lineObj.widgets[i].above) + { height += widgetHeight(lineObj.widgets[i]); } } } + return height + } + + // Converts a {top, bottom, left, right} box from line-local + // coordinates into another coordinate system. Context may be one of + // "line", "div" (display.lineDiv), "local"./null (editor), "window", + // or "page". + function intoCoordSystem(cm, lineObj, rect, context, includeWidgets) { + if (!includeWidgets) { + var height = widgetTopHeight(lineObj); + rect.top += height; rect.bottom += height; + } + if (context == "line") { return rect } + if (!context) { context = "local"; } + var yOff = heightAtLine(lineObj); + if (context == "local") { yOff += paddingTop(cm.display); } + else { yOff -= cm.display.viewOffset; } + if (context == "page" || context == "window") { + var lOff = cm.display.lineSpace.getBoundingClientRect(); + yOff += lOff.top + (context == "window" ? 0 : pageScrollY()); + var xOff = lOff.left + (context == "window" ? 0 : pageScrollX()); + rect.left += xOff; rect.right += xOff; + } + rect.top += yOff; rect.bottom += yOff; + return rect + } + + // Coverts a box from "div" coords to another coordinate system. + // Context may be "window", "page", "div", or "local"./null. + function fromCoordSystem(cm, coords, context) { + if (context == "div") { return coords } + var left = coords.left, top = coords.top; + // First move into "page" coordinate system + if (context == "page") { + left -= pageScrollX(); + top -= pageScrollY(); + } else if (context == "local" || !context) { + var localBox = cm.display.sizer.getBoundingClientRect(); + left += localBox.left; + top += localBox.top; + } + + var lineSpaceBox = cm.display.lineSpace.getBoundingClientRect(); + return {left: left - lineSpaceBox.left, top: top - lineSpaceBox.top} + } + + function charCoords(cm, pos, context, lineObj, bias) { + if (!lineObj) { lineObj = getLine(cm.doc, pos.line); } + return intoCoordSystem(cm, lineObj, measureChar(cm, lineObj, pos.ch, bias), context) + } + + // Returns a box for a given cursor position, which may have an + // 'other' property containing the position of the secondary cursor + // on a bidi boundary. + // A cursor Pos(line, char, "before") is on the same visual line as `char - 1` + // and after `char - 1` in writing order of `char - 1` + // A cursor Pos(line, char, "after") is on the same visual line as `char` + // and before `char` in writing order of `char` + // Examples (upper-case letters are RTL, lower-case are LTR): + // Pos(0, 1, ...) + // before after + // ab a|b a|b + // aB a|B aB| + // Ab |Ab A|b + // AB B|A B|A + // Every position after the last character on a line is considered to stick + // to the last character on the line. + function cursorCoords(cm, pos, context, lineObj, preparedMeasure, varHeight) { + lineObj = lineObj || getLine(cm.doc, pos.line); + if (!preparedMeasure) { preparedMeasure = prepareMeasureForLine(cm, lineObj); } + function get(ch, right) { + var m = measureCharPrepared(cm, preparedMeasure, ch, right ? "right" : "left", varHeight); + if (right) { m.left = m.right; } else { m.right = m.left; } + return intoCoordSystem(cm, lineObj, m, context) + } + var order = getOrder(lineObj, cm.doc.direction), ch = pos.ch, sticky = pos.sticky; + if (ch >= lineObj.text.length) { + ch = lineObj.text.length; + sticky = "before"; + } else if (ch <= 0) { + ch = 0; + sticky = "after"; + } + if (!order) { return get(sticky == "before" ? ch - 1 : ch, sticky == "before") } + + function getBidi(ch, partPos, invert) { + var part = order[partPos], right = part.level == 1; + return get(invert ? ch - 1 : ch, right != invert) + } + var partPos = getBidiPartAt(order, ch, sticky); + var other = bidiOther; + var val = getBidi(ch, partPos, sticky == "before"); + if (other != null) { val.other = getBidi(ch, other, sticky != "before"); } + return val + } + + // Used to cheaply estimate the coordinates for a position. Used for + // intermediate scroll updates. + function estimateCoords(cm, pos) { + var left = 0; + pos = clipPos(cm.doc, pos); + if (!cm.options.lineWrapping) { left = charWidth(cm.display) * pos.ch; } + var lineObj = getLine(cm.doc, pos.line); + var top = heightAtLine(lineObj) + paddingTop(cm.display); + return {left: left, right: left, top: top, bottom: top + lineObj.height} + } + + // Positions returned by coordsChar contain some extra information. + // xRel is the relative x position of the input coordinates compared + // to the found position (so xRel > 0 means the coordinates are to + // the right of the character position, for example). When outside + // is true, that means the coordinates lie outside the line's + // vertical range. + function PosWithInfo(line, ch, sticky, outside, xRel) { + var pos = Pos(line, ch, sticky); + pos.xRel = xRel; + if (outside) { pos.outside = outside; } + return pos + } + + // Compute the character position closest to the given coordinates. + // Input must be lineSpace-local ("div" coordinate system). + function coordsChar(cm, x, y) { + var doc = cm.doc; + y += cm.display.viewOffset; + if (y < 0) { return PosWithInfo(doc.first, 0, null, -1, -1) } + var lineN = lineAtHeight(doc, y), last = doc.first + doc.size - 1; + if (lineN > last) + { return PosWithInfo(doc.first + doc.size - 1, getLine(doc, last).text.length, null, 1, 1) } + if (x < 0) { x = 0; } + + var lineObj = getLine(doc, lineN); + for (;;) { + var found = coordsCharInner(cm, lineObj, lineN, x, y); + var collapsed = collapsedSpanAround(lineObj, found.ch + (found.xRel > 0 || found.outside > 0 ? 1 : 0)); + if (!collapsed) { return found } + var rangeEnd = collapsed.find(1); + if (rangeEnd.line == lineN) { return rangeEnd } + lineObj = getLine(doc, lineN = rangeEnd.line); + } + } + + function wrappedLineExtent(cm, lineObj, preparedMeasure, y) { + y -= widgetTopHeight(lineObj); + var end = lineObj.text.length; + var begin = findFirst(function (ch) { return measureCharPrepared(cm, preparedMeasure, ch - 1).bottom <= y; }, end, 0); + end = findFirst(function (ch) { return measureCharPrepared(cm, preparedMeasure, ch).top > y; }, begin, end); + return {begin: begin, end: end} + } + + function wrappedLineExtentChar(cm, lineObj, preparedMeasure, target) { + if (!preparedMeasure) { preparedMeasure = prepareMeasureForLine(cm, lineObj); } + var targetTop = intoCoordSystem(cm, lineObj, measureCharPrepared(cm, preparedMeasure, target), "line").top; + return wrappedLineExtent(cm, lineObj, preparedMeasure, targetTop) + } + + // Returns true if the given side of a box is after the given + // coordinates, in top-to-bottom, left-to-right order. + function boxIsAfter(box, x, y, left) { + return box.bottom <= y ? false : box.top > y ? true : (left ? box.left : box.right) > x + } + + function coordsCharInner(cm, lineObj, lineNo, x, y) { + // Move y into line-local coordinate space + y -= heightAtLine(lineObj); + var preparedMeasure = prepareMeasureForLine(cm, lineObj); + // When directly calling `measureCharPrepared`, we have to adjust + // for the widgets at this line. + var widgetHeight = widgetTopHeight(lineObj); + var begin = 0, end = lineObj.text.length, ltr = true; + + var order = getOrder(lineObj, cm.doc.direction); + // If the line isn't plain left-to-right text, first figure out + // which bidi section the coordinates fall into. + if (order) { + var part = (cm.options.lineWrapping ? coordsBidiPartWrapped : coordsBidiPart) + (cm, lineObj, lineNo, preparedMeasure, order, x, y); + ltr = part.level != 1; + // The awkward -1 offsets are needed because findFirst (called + // on these below) will treat its first bound as inclusive, + // second as exclusive, but we want to actually address the + // characters in the part's range + begin = ltr ? part.from : part.to - 1; + end = ltr ? part.to : part.from - 1; + } + + // A binary search to find the first character whose bounding box + // starts after the coordinates. If we run across any whose box wrap + // the coordinates, store that. + var chAround = null, boxAround = null; + var ch = findFirst(function (ch) { + var box = measureCharPrepared(cm, preparedMeasure, ch); + box.top += widgetHeight; box.bottom += widgetHeight; + if (!boxIsAfter(box, x, y, false)) { return false } + if (box.top <= y && box.left <= x) { + chAround = ch; + boxAround = box; + } + return true + }, begin, end); + + var baseX, sticky, outside = false; + // If a box around the coordinates was found, use that + if (boxAround) { + // Distinguish coordinates nearer to the left or right side of the box + var atLeft = x - boxAround.left < boxAround.right - x, atStart = atLeft == ltr; + ch = chAround + (atStart ? 0 : 1); + sticky = atStart ? "after" : "before"; + baseX = atLeft ? boxAround.left : boxAround.right; + } else { + // (Adjust for extended bound, if necessary.) + if (!ltr && (ch == end || ch == begin)) { ch++; } + // To determine which side to associate with, get the box to the + // left of the character and compare it's vertical position to the + // coordinates + sticky = ch == 0 ? "after" : ch == lineObj.text.length ? "before" : + (measureCharPrepared(cm, preparedMeasure, ch - (ltr ? 1 : 0)).bottom + widgetHeight <= y) == ltr ? + "after" : "before"; + // Now get accurate coordinates for this place, in order to get a + // base X position + var coords = cursorCoords(cm, Pos(lineNo, ch, sticky), "line", lineObj, preparedMeasure); + baseX = coords.left; + outside = y < coords.top ? -1 : y >= coords.bottom ? 1 : 0; + } + + ch = skipExtendingChars(lineObj.text, ch, 1); + return PosWithInfo(lineNo, ch, sticky, outside, x - baseX) + } + + function coordsBidiPart(cm, lineObj, lineNo, preparedMeasure, order, x, y) { + // Bidi parts are sorted left-to-right, and in a non-line-wrapping + // situation, we can take this ordering to correspond to the visual + // ordering. This finds the first part whose end is after the given + // coordinates. + var index = findFirst(function (i) { + var part = order[i], ltr = part.level != 1; + return boxIsAfter(cursorCoords(cm, Pos(lineNo, ltr ? part.to : part.from, ltr ? "before" : "after"), + "line", lineObj, preparedMeasure), x, y, true) + }, 0, order.length - 1); + var part = order[index]; + // If this isn't the first part, the part's start is also after + // the coordinates, and the coordinates aren't on the same line as + // that start, move one part back. + if (index > 0) { + var ltr = part.level != 1; + var start = cursorCoords(cm, Pos(lineNo, ltr ? part.from : part.to, ltr ? "after" : "before"), + "line", lineObj, preparedMeasure); + if (boxIsAfter(start, x, y, true) && start.top > y) + { part = order[index - 1]; } + } + return part + } + + function coordsBidiPartWrapped(cm, lineObj, _lineNo, preparedMeasure, order, x, y) { + // In a wrapped line, rtl text on wrapping boundaries can do things + // that don't correspond to the ordering in our `order` array at + // all, so a binary search doesn't work, and we want to return a + // part that only spans one line so that the binary search in + // coordsCharInner is safe. As such, we first find the extent of the + // wrapped line, and then do a flat search in which we discard any + // spans that aren't on the line. + var ref = wrappedLineExtent(cm, lineObj, preparedMeasure, y); + var begin = ref.begin; + var end = ref.end; + if (/\s/.test(lineObj.text.charAt(end - 1))) { end--; } + var part = null, closestDist = null; + for (var i = 0; i < order.length; i++) { + var p = order[i]; + if (p.from >= end || p.to <= begin) { continue } + var ltr = p.level != 1; + var endX = measureCharPrepared(cm, preparedMeasure, ltr ? Math.min(end, p.to) - 1 : Math.max(begin, p.from)).right; + // Weigh against spans ending before this, so that they are only + // picked if nothing ends after + var dist = endX < x ? x - endX + 1e9 : endX - x; + if (!part || closestDist > dist) { + part = p; + closestDist = dist; + } + } + if (!part) { part = order[order.length - 1]; } + // Clip the part to the wrapped line. + if (part.from < begin) { part = {from: begin, to: part.to, level: part.level}; } + if (part.to > end) { part = {from: part.from, to: end, level: part.level}; } + return part + } + + var measureText; + // Compute the default text height. + function textHeight(display) { + if (display.cachedTextHeight != null) { return display.cachedTextHeight } + if (measureText == null) { + measureText = elt("pre", null, "CodeMirror-line-like"); + // Measure a bunch of lines, for browsers that compute + // fractional heights. + for (var i = 0; i < 49; ++i) { + measureText.appendChild(document.createTextNode("x")); + measureText.appendChild(elt("br")); + } + measureText.appendChild(document.createTextNode("x")); + } + removeChildrenAndAdd(display.measure, measureText); + var height = measureText.offsetHeight / 50; + if (height > 3) { display.cachedTextHeight = height; } + removeChildren(display.measure); + return height || 1 + } + + // Compute the default character width. + function charWidth(display) { + if (display.cachedCharWidth != null) { return display.cachedCharWidth } + var anchor = elt("span", "xxxxxxxxxx"); + var pre = elt("pre", [anchor], "CodeMirror-line-like"); + removeChildrenAndAdd(display.measure, pre); + var rect = anchor.getBoundingClientRect(), width = (rect.right - rect.left) / 10; + if (width > 2) { display.cachedCharWidth = width; } + return width || 10 + } + + // Do a bulk-read of the DOM positions and sizes needed to draw the + // view, so that we don't interleave reading and writing to the DOM. + function getDimensions(cm) { + var d = cm.display, left = {}, width = {}; + var gutterLeft = d.gutters.clientLeft; + for (var n = d.gutters.firstChild, i = 0; n; n = n.nextSibling, ++i) { + var id = cm.display.gutterSpecs[i].className; + left[id] = n.offsetLeft + n.clientLeft + gutterLeft; + width[id] = n.clientWidth; + } + return {fixedPos: compensateForHScroll(d), + gutterTotalWidth: d.gutters.offsetWidth, + gutterLeft: left, + gutterWidth: width, + wrapperWidth: d.wrapper.clientWidth} + } + + // Computes display.scroller.scrollLeft + display.gutters.offsetWidth, + // but using getBoundingClientRect to get a sub-pixel-accurate + // result. + function compensateForHScroll(display) { + return display.scroller.getBoundingClientRect().left - display.sizer.getBoundingClientRect().left + } + + // Returns a function that estimates the height of a line, to use as + // first approximation until the line becomes visible (and is thus + // properly measurable). + function estimateHeight(cm) { + var th = textHeight(cm.display), wrapping = cm.options.lineWrapping; + var perLine = wrapping && Math.max(5, cm.display.scroller.clientWidth / charWidth(cm.display) - 3); + return function (line) { + if (lineIsHidden(cm.doc, line)) { return 0 } + + var widgetsHeight = 0; + if (line.widgets) { for (var i = 0; i < line.widgets.length; i++) { + if (line.widgets[i].height) { widgetsHeight += line.widgets[i].height; } + } } + + if (wrapping) + { return widgetsHeight + (Math.ceil(line.text.length / perLine) || 1) * th } + else + { return widgetsHeight + th } + } + } + + function estimateLineHeights(cm) { + var doc = cm.doc, est = estimateHeight(cm); + doc.iter(function (line) { + var estHeight = est(line); + if (estHeight != line.height) { updateLineHeight(line, estHeight); } + }); + } + + // Given a mouse event, find the corresponding position. If liberal + // is false, it checks whether a gutter or scrollbar was clicked, + // and returns null if it was. forRect is used by rectangular + // selections, and tries to estimate a character position even for + // coordinates beyond the right of the text. + function posFromMouse(cm, e, liberal, forRect) { + var display = cm.display; + if (!liberal && e_target(e).getAttribute("cm-not-content") == "true") { return null } + + var x, y, space = display.lineSpace.getBoundingClientRect(); + // Fails unpredictably on IE[67] when mouse is dragged around quickly. + try { x = e.clientX - space.left; y = e.clientY - space.top; } + catch (e$1) { return null } + var coords = coordsChar(cm, x, y), line; + if (forRect && coords.xRel > 0 && (line = getLine(cm.doc, coords.line).text).length == coords.ch) { + var colDiff = countColumn(line, line.length, cm.options.tabSize) - line.length; + coords = Pos(coords.line, Math.max(0, Math.round((x - paddingH(cm.display).left) / charWidth(cm.display)) - colDiff)); + } + return coords + } + + // Find the view element corresponding to a given line. Return null + // when the line isn't visible. + function findViewIndex(cm, n) { + if (n >= cm.display.viewTo) { return null } + n -= cm.display.viewFrom; + if (n < 0) { return null } + var view = cm.display.view; + for (var i = 0; i < view.length; i++) { + n -= view[i].size; + if (n < 0) { return i } + } + } + + // Updates the display.view data structure for a given change to the + // document. From and to are in pre-change coordinates. Lendiff is + // the amount of lines added or subtracted by the change. This is + // used for changes that span multiple lines, or change the way + // lines are divided into visual lines. regLineChange (below) + // registers single-line changes. + function regChange(cm, from, to, lendiff) { + if (from == null) { from = cm.doc.first; } + if (to == null) { to = cm.doc.first + cm.doc.size; } + if (!lendiff) { lendiff = 0; } + + var display = cm.display; + if (lendiff && to < display.viewTo && + (display.updateLineNumbers == null || display.updateLineNumbers > from)) + { display.updateLineNumbers = from; } + + cm.curOp.viewChanged = true; + + if (from >= display.viewTo) { // Change after + if (sawCollapsedSpans && visualLineNo(cm.doc, from) < display.viewTo) + { resetView(cm); } + } else if (to <= display.viewFrom) { // Change before + if (sawCollapsedSpans && visualLineEndNo(cm.doc, to + lendiff) > display.viewFrom) { + resetView(cm); + } else { + display.viewFrom += lendiff; + display.viewTo += lendiff; + } + } else if (from <= display.viewFrom && to >= display.viewTo) { // Full overlap + resetView(cm); + } else if (from <= display.viewFrom) { // Top overlap + var cut = viewCuttingPoint(cm, to, to + lendiff, 1); + if (cut) { + display.view = display.view.slice(cut.index); + display.viewFrom = cut.lineN; + display.viewTo += lendiff; + } else { + resetView(cm); + } + } else if (to >= display.viewTo) { // Bottom overlap + var cut$1 = viewCuttingPoint(cm, from, from, -1); + if (cut$1) { + display.view = display.view.slice(0, cut$1.index); + display.viewTo = cut$1.lineN; + } else { + resetView(cm); + } + } else { // Gap in the middle + var cutTop = viewCuttingPoint(cm, from, from, -1); + var cutBot = viewCuttingPoint(cm, to, to + lendiff, 1); + if (cutTop && cutBot) { + display.view = display.view.slice(0, cutTop.index) + .concat(buildViewArray(cm, cutTop.lineN, cutBot.lineN)) + .concat(display.view.slice(cutBot.index)); + display.viewTo += lendiff; + } else { + resetView(cm); + } + } + + var ext = display.externalMeasured; + if (ext) { + if (to < ext.lineN) + { ext.lineN += lendiff; } + else if (from < ext.lineN + ext.size) + { display.externalMeasured = null; } + } + } + + // Register a change to a single line. Type must be one of "text", + // "gutter", "class", "widget" + function regLineChange(cm, line, type) { + cm.curOp.viewChanged = true; + var display = cm.display, ext = cm.display.externalMeasured; + if (ext && line >= ext.lineN && line < ext.lineN + ext.size) + { display.externalMeasured = null; } + + if (line < display.viewFrom || line >= display.viewTo) { return } + var lineView = display.view[findViewIndex(cm, line)]; + if (lineView.node == null) { return } + var arr = lineView.changes || (lineView.changes = []); + if (indexOf(arr, type) == -1) { arr.push(type); } + } + + // Clear the view. + function resetView(cm) { + cm.display.viewFrom = cm.display.viewTo = cm.doc.first; + cm.display.view = []; + cm.display.viewOffset = 0; + } + + function viewCuttingPoint(cm, oldN, newN, dir) { + var index = findViewIndex(cm, oldN), diff, view = cm.display.view; + if (!sawCollapsedSpans || newN == cm.doc.first + cm.doc.size) + { return {index: index, lineN: newN} } + var n = cm.display.viewFrom; + for (var i = 0; i < index; i++) + { n += view[i].size; } + if (n != oldN) { + if (dir > 0) { + if (index == view.length - 1) { return null } + diff = (n + view[index].size) - oldN; + index++; + } else { + diff = n - oldN; + } + oldN += diff; newN += diff; + } + while (visualLineNo(cm.doc, newN) != newN) { + if (index == (dir < 0 ? 0 : view.length - 1)) { return null } + newN += dir * view[index - (dir < 0 ? 1 : 0)].size; + index += dir; + } + return {index: index, lineN: newN} + } + + // Force the view to cover a given range, adding empty view element + // or clipping off existing ones as needed. + function adjustView(cm, from, to) { + var display = cm.display, view = display.view; + if (view.length == 0 || from >= display.viewTo || to <= display.viewFrom) { + display.view = buildViewArray(cm, from, to); + display.viewFrom = from; + } else { + if (display.viewFrom > from) + { display.view = buildViewArray(cm, from, display.viewFrom).concat(display.view); } + else if (display.viewFrom < from) + { display.view = display.view.slice(findViewIndex(cm, from)); } + display.viewFrom = from; + if (display.viewTo < to) + { display.view = display.view.concat(buildViewArray(cm, display.viewTo, to)); } + else if (display.viewTo > to) + { display.view = display.view.slice(0, findViewIndex(cm, to)); } + } + display.viewTo = to; + } + + // Count the number of lines in the view whose DOM representation is + // out of date (or nonexistent). + function countDirtyView(cm) { + var view = cm.display.view, dirty = 0; + for (var i = 0; i < view.length; i++) { + var lineView = view[i]; + if (!lineView.hidden && (!lineView.node || lineView.changes)) { ++dirty; } + } + return dirty + } + + function updateSelection(cm) { + cm.display.input.showSelection(cm.display.input.prepareSelection()); + } + + function prepareSelection(cm, primary) { + if ( primary === void 0 ) primary = true; + + var doc = cm.doc, result = {}; + var curFragment = result.cursors = document.createDocumentFragment(); + var selFragment = result.selection = document.createDocumentFragment(); + + for (var i = 0; i < doc.sel.ranges.length; i++) { + if (!primary && i == doc.sel.primIndex) { continue } + var range = doc.sel.ranges[i]; + if (range.from().line >= cm.display.viewTo || range.to().line < cm.display.viewFrom) { continue } + var collapsed = range.empty(); + if (collapsed || cm.options.showCursorWhenSelecting) + { drawSelectionCursor(cm, range.head, curFragment); } + if (!collapsed) + { drawSelectionRange(cm, range, selFragment); } + } + return result + } + + // Draws a cursor for the given range + function drawSelectionCursor(cm, head, output) { + var pos = cursorCoords(cm, head, "div", null, null, !cm.options.singleCursorHeightPerLine); + + var cursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor")); + cursor.style.left = pos.left + "px"; + cursor.style.top = pos.top + "px"; + cursor.style.height = Math.max(0, pos.bottom - pos.top) * cm.options.cursorHeight + "px"; + + if (pos.other) { + // Secondary cursor, shown when on a 'jump' in bi-directional text + var otherCursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor CodeMirror-secondarycursor")); + otherCursor.style.display = ""; + otherCursor.style.left = pos.other.left + "px"; + otherCursor.style.top = pos.other.top + "px"; + otherCursor.style.height = (pos.other.bottom - pos.other.top) * .85 + "px"; + } + } + + function cmpCoords(a, b) { return a.top - b.top || a.left - b.left } + + // Draws the given range as a highlighted selection + function drawSelectionRange(cm, range, output) { + var display = cm.display, doc = cm.doc; + var fragment = document.createDocumentFragment(); + var padding = paddingH(cm.display), leftSide = padding.left; + var rightSide = Math.max(display.sizerWidth, displayWidth(cm) - display.sizer.offsetLeft) - padding.right; + var docLTR = doc.direction == "ltr"; + + function add(left, top, width, bottom) { + if (top < 0) { top = 0; } + top = Math.round(top); + bottom = Math.round(bottom); + fragment.appendChild(elt("div", null, "CodeMirror-selected", ("position: absolute; left: " + left + "px;\n top: " + top + "px; width: " + (width == null ? rightSide - left : width) + "px;\n height: " + (bottom - top) + "px"))); + } + + function drawForLine(line, fromArg, toArg) { + var lineObj = getLine(doc, line); + var lineLen = lineObj.text.length; + var start, end; + function coords(ch, bias) { + return charCoords(cm, Pos(line, ch), "div", lineObj, bias) + } + + function wrapX(pos, dir, side) { + var extent = wrappedLineExtentChar(cm, lineObj, null, pos); + var prop = (dir == "ltr") == (side == "after") ? "left" : "right"; + var ch = side == "after" ? extent.begin : extent.end - (/\s/.test(lineObj.text.charAt(extent.end - 1)) ? 2 : 1); + return coords(ch, prop)[prop] + } + + var order = getOrder(lineObj, doc.direction); + iterateBidiSections(order, fromArg || 0, toArg == null ? lineLen : toArg, function (from, to, dir, i) { + var ltr = dir == "ltr"; + var fromPos = coords(from, ltr ? "left" : "right"); + var toPos = coords(to - 1, ltr ? "right" : "left"); + + var openStart = fromArg == null && from == 0, openEnd = toArg == null && to == lineLen; + var first = i == 0, last = !order || i == order.length - 1; + if (toPos.top - fromPos.top <= 3) { // Single line + var openLeft = (docLTR ? openStart : openEnd) && first; + var openRight = (docLTR ? openEnd : openStart) && last; + var left = openLeft ? leftSide : (ltr ? fromPos : toPos).left; + var right = openRight ? rightSide : (ltr ? toPos : fromPos).right; + add(left, fromPos.top, right - left, fromPos.bottom); + } else { // Multiple lines + var topLeft, topRight, botLeft, botRight; + if (ltr) { + topLeft = docLTR && openStart && first ? leftSide : fromPos.left; + topRight = docLTR ? rightSide : wrapX(from, dir, "before"); + botLeft = docLTR ? leftSide : wrapX(to, dir, "after"); + botRight = docLTR && openEnd && last ? rightSide : toPos.right; + } else { + topLeft = !docLTR ? leftSide : wrapX(from, dir, "before"); + topRight = !docLTR && openStart && first ? rightSide : fromPos.right; + botLeft = !docLTR && openEnd && last ? leftSide : toPos.left; + botRight = !docLTR ? rightSide : wrapX(to, dir, "after"); + } + add(topLeft, fromPos.top, topRight - topLeft, fromPos.bottom); + if (fromPos.bottom < toPos.top) { add(leftSide, fromPos.bottom, null, toPos.top); } + add(botLeft, toPos.top, botRight - botLeft, toPos.bottom); + } + + if (!start || cmpCoords(fromPos, start) < 0) { start = fromPos; } + if (cmpCoords(toPos, start) < 0) { start = toPos; } + if (!end || cmpCoords(fromPos, end) < 0) { end = fromPos; } + if (cmpCoords(toPos, end) < 0) { end = toPos; } + }); + return {start: start, end: end} + } + + var sFrom = range.from(), sTo = range.to(); + if (sFrom.line == sTo.line) { + drawForLine(sFrom.line, sFrom.ch, sTo.ch); + } else { + var fromLine = getLine(doc, sFrom.line), toLine = getLine(doc, sTo.line); + var singleVLine = visualLine(fromLine) == visualLine(toLine); + var leftEnd = drawForLine(sFrom.line, sFrom.ch, singleVLine ? fromLine.text.length + 1 : null).end; + var rightStart = drawForLine(sTo.line, singleVLine ? 0 : null, sTo.ch).start; + if (singleVLine) { + if (leftEnd.top < rightStart.top - 2) { + add(leftEnd.right, leftEnd.top, null, leftEnd.bottom); + add(leftSide, rightStart.top, rightStart.left, rightStart.bottom); + } else { + add(leftEnd.right, leftEnd.top, rightStart.left - leftEnd.right, leftEnd.bottom); + } + } + if (leftEnd.bottom < rightStart.top) + { add(leftSide, leftEnd.bottom, null, rightStart.top); } + } + + output.appendChild(fragment); + } + + // Cursor-blinking + function restartBlink(cm) { + if (!cm.state.focused) { return } + var display = cm.display; + clearInterval(display.blinker); + var on = true; + display.cursorDiv.style.visibility = ""; + if (cm.options.cursorBlinkRate > 0) + { display.blinker = setInterval(function () { + if (!cm.hasFocus()) { onBlur(cm); } + display.cursorDiv.style.visibility = (on = !on) ? "" : "hidden"; + }, cm.options.cursorBlinkRate); } + else if (cm.options.cursorBlinkRate < 0) + { display.cursorDiv.style.visibility = "hidden"; } + } + + function ensureFocus(cm) { + if (!cm.state.focused) { cm.display.input.focus(); onFocus(cm); } + } + + function delayBlurEvent(cm) { + cm.state.delayingBlurEvent = true; + setTimeout(function () { if (cm.state.delayingBlurEvent) { + cm.state.delayingBlurEvent = false; + onBlur(cm); + } }, 100); + } + + function onFocus(cm, e) { + if (cm.state.delayingBlurEvent) { cm.state.delayingBlurEvent = false; } + + if (cm.options.readOnly == "nocursor") { return } + if (!cm.state.focused) { + signal(cm, "focus", cm, e); + cm.state.focused = true; + addClass(cm.display.wrapper, "CodeMirror-focused"); + // This test prevents this from firing when a context + // menu is closed (since the input reset would kill the + // select-all detection hack) + if (!cm.curOp && cm.display.selForContextMenu != cm.doc.sel) { + cm.display.input.reset(); + if (webkit) { setTimeout(function () { return cm.display.input.reset(true); }, 20); } // Issue #1730 + } + cm.display.input.receivedFocus(); + } + restartBlink(cm); + } + function onBlur(cm, e) { + if (cm.state.delayingBlurEvent) { return } + + if (cm.state.focused) { + signal(cm, "blur", cm, e); + cm.state.focused = false; + rmClass(cm.display.wrapper, "CodeMirror-focused"); + } + clearInterval(cm.display.blinker); + setTimeout(function () { if (!cm.state.focused) { cm.display.shift = false; } }, 150); + } + + // Read the actual heights of the rendered lines, and update their + // stored heights to match. + function updateHeightsInViewport(cm) { + var display = cm.display; + var prevBottom = display.lineDiv.offsetTop; + for (var i = 0; i < display.view.length; i++) { + var cur = display.view[i], wrapping = cm.options.lineWrapping; + var height = (void 0), width = 0; + if (cur.hidden) { continue } + if (ie && ie_version < 8) { + var bot = cur.node.offsetTop + cur.node.offsetHeight; + height = bot - prevBottom; + prevBottom = bot; + } else { + var box = cur.node.getBoundingClientRect(); + height = box.bottom - box.top; + // Check that lines don't extend past the right of the current + // editor width + if (!wrapping && cur.text.firstChild) + { width = cur.text.firstChild.getBoundingClientRect().right - box.left - 1; } + } + var diff = cur.line.height - height; + if (diff > .005 || diff < -.005) { + updateLineHeight(cur.line, height); + updateWidgetHeight(cur.line); + if (cur.rest) { for (var j = 0; j < cur.rest.length; j++) + { updateWidgetHeight(cur.rest[j]); } } + } + if (width > cm.display.sizerWidth) { + var chWidth = Math.ceil(width / charWidth(cm.display)); + if (chWidth > cm.display.maxLineLength) { + cm.display.maxLineLength = chWidth; + cm.display.maxLine = cur.line; + cm.display.maxLineChanged = true; + } + } + } + } + + // Read and store the height of line widgets associated with the + // given line. + function updateWidgetHeight(line) { + if (line.widgets) { for (var i = 0; i < line.widgets.length; ++i) { + var w = line.widgets[i], parent = w.node.parentNode; + if (parent) { w.height = parent.offsetHeight; } + } } + } + + // Compute the lines that are visible in a given viewport (defaults + // the the current scroll position). viewport may contain top, + // height, and ensure (see op.scrollToPos) properties. + function visibleLines(display, doc, viewport) { + var top = viewport && viewport.top != null ? Math.max(0, viewport.top) : display.scroller.scrollTop; + top = Math.floor(top - paddingTop(display)); + var bottom = viewport && viewport.bottom != null ? viewport.bottom : top + display.wrapper.clientHeight; + + var from = lineAtHeight(doc, top), to = lineAtHeight(doc, bottom); + // Ensure is a {from: {line, ch}, to: {line, ch}} object, and + // forces those lines into the viewport (if possible). + if (viewport && viewport.ensure) { + var ensureFrom = viewport.ensure.from.line, ensureTo = viewport.ensure.to.line; + if (ensureFrom < from) { + from = ensureFrom; + to = lineAtHeight(doc, heightAtLine(getLine(doc, ensureFrom)) + display.wrapper.clientHeight); + } else if (Math.min(ensureTo, doc.lastLine()) >= to) { + from = lineAtHeight(doc, heightAtLine(getLine(doc, ensureTo)) - display.wrapper.clientHeight); + to = ensureTo; + } + } + return {from: from, to: Math.max(to, from + 1)} + } + + // SCROLLING THINGS INTO VIEW + + // If an editor sits on the top or bottom of the window, partially + // scrolled out of view, this ensures that the cursor is visible. + function maybeScrollWindow(cm, rect) { + if (signalDOMEvent(cm, "scrollCursorIntoView")) { return } + + var display = cm.display, box = display.sizer.getBoundingClientRect(), doScroll = null; + if (rect.top + box.top < 0) { doScroll = true; } + else if (rect.bottom + box.top > (window.innerHeight || document.documentElement.clientHeight)) { doScroll = false; } + if (doScroll != null && !phantom) { + var scrollNode = elt("div", "\u200b", null, ("position: absolute;\n top: " + (rect.top - display.viewOffset - paddingTop(cm.display)) + "px;\n height: " + (rect.bottom - rect.top + scrollGap(cm) + display.barHeight) + "px;\n left: " + (rect.left) + "px; width: " + (Math.max(2, rect.right - rect.left)) + "px;")); + cm.display.lineSpace.appendChild(scrollNode); + scrollNode.scrollIntoView(doScroll); + cm.display.lineSpace.removeChild(scrollNode); + } + } + + // Scroll a given position into view (immediately), verifying that + // it actually became visible (as line heights are accurately + // measured, the position of something may 'drift' during drawing). + function scrollPosIntoView(cm, pos, end, margin) { + if (margin == null) { margin = 0; } + var rect; + if (!cm.options.lineWrapping && pos == end) { + // Set pos and end to the cursor positions around the character pos sticks to + // If pos.sticky == "before", that is around pos.ch - 1, otherwise around pos.ch + // If pos == Pos(_, 0, "before"), pos and end are unchanged + pos = pos.ch ? Pos(pos.line, pos.sticky == "before" ? pos.ch - 1 : pos.ch, "after") : pos; + end = pos.sticky == "before" ? Pos(pos.line, pos.ch + 1, "before") : pos; + } + for (var limit = 0; limit < 5; limit++) { + var changed = false; + var coords = cursorCoords(cm, pos); + var endCoords = !end || end == pos ? coords : cursorCoords(cm, end); + rect = {left: Math.min(coords.left, endCoords.left), + top: Math.min(coords.top, endCoords.top) - margin, + right: Math.max(coords.left, endCoords.left), + bottom: Math.max(coords.bottom, endCoords.bottom) + margin}; + var scrollPos = calculateScrollPos(cm, rect); + var startTop = cm.doc.scrollTop, startLeft = cm.doc.scrollLeft; + if (scrollPos.scrollTop != null) { + updateScrollTop(cm, scrollPos.scrollTop); + if (Math.abs(cm.doc.scrollTop - startTop) > 1) { changed = true; } + } + if (scrollPos.scrollLeft != null) { + setScrollLeft(cm, scrollPos.scrollLeft); + if (Math.abs(cm.doc.scrollLeft - startLeft) > 1) { changed = true; } + } + if (!changed) { break } + } + return rect + } + + // Scroll a given set of coordinates into view (immediately). + function scrollIntoView(cm, rect) { + var scrollPos = calculateScrollPos(cm, rect); + if (scrollPos.scrollTop != null) { updateScrollTop(cm, scrollPos.scrollTop); } + if (scrollPos.scrollLeft != null) { setScrollLeft(cm, scrollPos.scrollLeft); } + } + + // Calculate a new scroll position needed to scroll the given + // rectangle into view. Returns an object with scrollTop and + // scrollLeft properties. When these are undefined, the + // vertical/horizontal position does not need to be adjusted. + function calculateScrollPos(cm, rect) { + var display = cm.display, snapMargin = textHeight(cm.display); + if (rect.top < 0) { rect.top = 0; } + var screentop = cm.curOp && cm.curOp.scrollTop != null ? cm.curOp.scrollTop : display.scroller.scrollTop; + var screen = displayHeight(cm), result = {}; + if (rect.bottom - rect.top > screen) { rect.bottom = rect.top + screen; } + var docBottom = cm.doc.height + paddingVert(display); + var atTop = rect.top < snapMargin, atBottom = rect.bottom > docBottom - snapMargin; + if (rect.top < screentop) { + result.scrollTop = atTop ? 0 : rect.top; + } else if (rect.bottom > screentop + screen) { + var newTop = Math.min(rect.top, (atBottom ? docBottom : rect.bottom) - screen); + if (newTop != screentop) { result.scrollTop = newTop; } + } + + var gutterSpace = cm.options.fixedGutter ? 0 : display.gutters.offsetWidth; + var screenleft = cm.curOp && cm.curOp.scrollLeft != null ? cm.curOp.scrollLeft : display.scroller.scrollLeft - gutterSpace; + var screenw = displayWidth(cm) - display.gutters.offsetWidth; + var tooWide = rect.right - rect.left > screenw; + if (tooWide) { rect.right = rect.left + screenw; } + if (rect.left < 10) + { result.scrollLeft = 0; } + else if (rect.left < screenleft) + { result.scrollLeft = Math.max(0, rect.left + gutterSpace - (tooWide ? 0 : 10)); } + else if (rect.right > screenw + screenleft - 3) + { result.scrollLeft = rect.right + (tooWide ? 0 : 10) - screenw; } + return result + } + + // Store a relative adjustment to the scroll position in the current + // operation (to be applied when the operation finishes). + function addToScrollTop(cm, top) { + if (top == null) { return } + resolveScrollToPos(cm); + cm.curOp.scrollTop = (cm.curOp.scrollTop == null ? cm.doc.scrollTop : cm.curOp.scrollTop) + top; + } + + // Make sure that at the end of the operation the current cursor is + // shown. + function ensureCursorVisible(cm) { + resolveScrollToPos(cm); + var cur = cm.getCursor(); + cm.curOp.scrollToPos = {from: cur, to: cur, margin: cm.options.cursorScrollMargin}; + } + + function scrollToCoords(cm, x, y) { + if (x != null || y != null) { resolveScrollToPos(cm); } + if (x != null) { cm.curOp.scrollLeft = x; } + if (y != null) { cm.curOp.scrollTop = y; } + } + + function scrollToRange(cm, range) { + resolveScrollToPos(cm); + cm.curOp.scrollToPos = range; + } + + // When an operation has its scrollToPos property set, and another + // scroll action is applied before the end of the operation, this + // 'simulates' scrolling that position into view in a cheap way, so + // that the effect of intermediate scroll commands is not ignored. + function resolveScrollToPos(cm) { + var range = cm.curOp.scrollToPos; + if (range) { + cm.curOp.scrollToPos = null; + var from = estimateCoords(cm, range.from), to = estimateCoords(cm, range.to); + scrollToCoordsRange(cm, from, to, range.margin); + } + } + + function scrollToCoordsRange(cm, from, to, margin) { + var sPos = calculateScrollPos(cm, { + left: Math.min(from.left, to.left), + top: Math.min(from.top, to.top) - margin, + right: Math.max(from.right, to.right), + bottom: Math.max(from.bottom, to.bottom) + margin + }); + scrollToCoords(cm, sPos.scrollLeft, sPos.scrollTop); + } + + // Sync the scrollable area and scrollbars, ensure the viewport + // covers the visible area. + function updateScrollTop(cm, val) { + if (Math.abs(cm.doc.scrollTop - val) < 2) { return } + if (!gecko) { updateDisplaySimple(cm, {top: val}); } + setScrollTop(cm, val, true); + if (gecko) { updateDisplaySimple(cm); } + startWorker(cm, 100); + } + + function setScrollTop(cm, val, forceScroll) { + val = Math.max(0, Math.min(cm.display.scroller.scrollHeight - cm.display.scroller.clientHeight, val)); + if (cm.display.scroller.scrollTop == val && !forceScroll) { return } + cm.doc.scrollTop = val; + cm.display.scrollbars.setScrollTop(val); + if (cm.display.scroller.scrollTop != val) { cm.display.scroller.scrollTop = val; } + } + + // Sync scroller and scrollbar, ensure the gutter elements are + // aligned. + function setScrollLeft(cm, val, isScroller, forceScroll) { + val = Math.max(0, Math.min(val, cm.display.scroller.scrollWidth - cm.display.scroller.clientWidth)); + if ((isScroller ? val == cm.doc.scrollLeft : Math.abs(cm.doc.scrollLeft - val) < 2) && !forceScroll) { return } + cm.doc.scrollLeft = val; + alignHorizontally(cm); + if (cm.display.scroller.scrollLeft != val) { cm.display.scroller.scrollLeft = val; } + cm.display.scrollbars.setScrollLeft(val); + } + + // SCROLLBARS + + // Prepare DOM reads needed to update the scrollbars. Done in one + // shot to minimize update/measure roundtrips. + function measureForScrollbars(cm) { + var d = cm.display, gutterW = d.gutters.offsetWidth; + var docH = Math.round(cm.doc.height + paddingVert(cm.display)); + return { + clientHeight: d.scroller.clientHeight, + viewHeight: d.wrapper.clientHeight, + scrollWidth: d.scroller.scrollWidth, clientWidth: d.scroller.clientWidth, + viewWidth: d.wrapper.clientWidth, + barLeft: cm.options.fixedGutter ? gutterW : 0, + docHeight: docH, + scrollHeight: docH + scrollGap(cm) + d.barHeight, + nativeBarWidth: d.nativeBarWidth, + gutterWidth: gutterW + } + } + + var NativeScrollbars = function(place, scroll, cm) { + this.cm = cm; + var vert = this.vert = elt("div", [elt("div", null, null, "min-width: 1px")], "CodeMirror-vscrollbar"); + var horiz = this.horiz = elt("div", [elt("div", null, null, "height: 100%; min-height: 1px")], "CodeMirror-hscrollbar"); + vert.tabIndex = horiz.tabIndex = -1; + place(vert); place(horiz); + + on(vert, "scroll", function () { + if (vert.clientHeight) { scroll(vert.scrollTop, "vertical"); } + }); + on(horiz, "scroll", function () { + if (horiz.clientWidth) { scroll(horiz.scrollLeft, "horizontal"); } + }); + + this.checkedZeroWidth = false; + // Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8). + if (ie && ie_version < 8) { this.horiz.style.minHeight = this.vert.style.minWidth = "18px"; } + }; + + NativeScrollbars.prototype.update = function (measure) { + var needsH = measure.scrollWidth > measure.clientWidth + 1; + var needsV = measure.scrollHeight > measure.clientHeight + 1; + var sWidth = measure.nativeBarWidth; + + if (needsV) { + this.vert.style.display = "block"; + this.vert.style.bottom = needsH ? sWidth + "px" : "0"; + var totalHeight = measure.viewHeight - (needsH ? sWidth : 0); + // A bug in IE8 can cause this value to be negative, so guard it. + this.vert.firstChild.style.height = + Math.max(0, measure.scrollHeight - measure.clientHeight + totalHeight) + "px"; + } else { + this.vert.style.display = ""; + this.vert.firstChild.style.height = "0"; + } + + if (needsH) { + this.horiz.style.display = "block"; + this.horiz.style.right = needsV ? sWidth + "px" : "0"; + this.horiz.style.left = measure.barLeft + "px"; + var totalWidth = measure.viewWidth - measure.barLeft - (needsV ? sWidth : 0); + this.horiz.firstChild.style.width = + Math.max(0, measure.scrollWidth - measure.clientWidth + totalWidth) + "px"; + } else { + this.horiz.style.display = ""; + this.horiz.firstChild.style.width = "0"; + } + + if (!this.checkedZeroWidth && measure.clientHeight > 0) { + if (sWidth == 0) { this.zeroWidthHack(); } + this.checkedZeroWidth = true; + } + + return {right: needsV ? sWidth : 0, bottom: needsH ? sWidth : 0} + }; + + NativeScrollbars.prototype.setScrollLeft = function (pos) { + if (this.horiz.scrollLeft != pos) { this.horiz.scrollLeft = pos; } + if (this.disableHoriz) { this.enableZeroWidthBar(this.horiz, this.disableHoriz, "horiz"); } + }; + + NativeScrollbars.prototype.setScrollTop = function (pos) { + if (this.vert.scrollTop != pos) { this.vert.scrollTop = pos; } + if (this.disableVert) { this.enableZeroWidthBar(this.vert, this.disableVert, "vert"); } + }; + + NativeScrollbars.prototype.zeroWidthHack = function () { + var w = mac && !mac_geMountainLion ? "12px" : "18px"; + this.horiz.style.height = this.vert.style.width = w; + this.horiz.style.pointerEvents = this.vert.style.pointerEvents = "none"; + this.disableHoriz = new Delayed; + this.disableVert = new Delayed; + }; + + NativeScrollbars.prototype.enableZeroWidthBar = function (bar, delay, type) { + bar.style.pointerEvents = "auto"; + function maybeDisable() { + // To find out whether the scrollbar is still visible, we + // check whether the element under the pixel in the bottom + // right corner of the scrollbar box is the scrollbar box + // itself (when the bar is still visible) or its filler child + // (when the bar is hidden). If it is still visible, we keep + // it enabled, if it's hidden, we disable pointer events. + var box = bar.getBoundingClientRect(); + var elt = type == "vert" ? document.elementFromPoint(box.right - 1, (box.top + box.bottom) / 2) + : document.elementFromPoint((box.right + box.left) / 2, box.bottom - 1); + if (elt != bar) { bar.style.pointerEvents = "none"; } + else { delay.set(1000, maybeDisable); } + } + delay.set(1000, maybeDisable); + }; + + NativeScrollbars.prototype.clear = function () { + var parent = this.horiz.parentNode; + parent.removeChild(this.horiz); + parent.removeChild(this.vert); + }; + + var NullScrollbars = function () {}; + + NullScrollbars.prototype.update = function () { return {bottom: 0, right: 0} }; + NullScrollbars.prototype.setScrollLeft = function () {}; + NullScrollbars.prototype.setScrollTop = function () {}; + NullScrollbars.prototype.clear = function () {}; + + function updateScrollbars(cm, measure) { + if (!measure) { measure = measureForScrollbars(cm); } + var startWidth = cm.display.barWidth, startHeight = cm.display.barHeight; + updateScrollbarsInner(cm, measure); + for (var i = 0; i < 4 && startWidth != cm.display.barWidth || startHeight != cm.display.barHeight; i++) { + if (startWidth != cm.display.barWidth && cm.options.lineWrapping) + { updateHeightsInViewport(cm); } + updateScrollbarsInner(cm, measureForScrollbars(cm)); + startWidth = cm.display.barWidth; startHeight = cm.display.barHeight; + } + } + + // Re-synchronize the fake scrollbars with the actual size of the + // content. + function updateScrollbarsInner(cm, measure) { + var d = cm.display; + var sizes = d.scrollbars.update(measure); + + d.sizer.style.paddingRight = (d.barWidth = sizes.right) + "px"; + d.sizer.style.paddingBottom = (d.barHeight = sizes.bottom) + "px"; + d.heightForcer.style.borderBottom = sizes.bottom + "px solid transparent"; + + if (sizes.right && sizes.bottom) { + d.scrollbarFiller.style.display = "block"; + d.scrollbarFiller.style.height = sizes.bottom + "px"; + d.scrollbarFiller.style.width = sizes.right + "px"; + } else { d.scrollbarFiller.style.display = ""; } + if (sizes.bottom && cm.options.coverGutterNextToScrollbar && cm.options.fixedGutter) { + d.gutterFiller.style.display = "block"; + d.gutterFiller.style.height = sizes.bottom + "px"; + d.gutterFiller.style.width = measure.gutterWidth + "px"; + } else { d.gutterFiller.style.display = ""; } + } + + var scrollbarModel = {"native": NativeScrollbars, "null": NullScrollbars}; + + function initScrollbars(cm) { + if (cm.display.scrollbars) { + cm.display.scrollbars.clear(); + if (cm.display.scrollbars.addClass) + { rmClass(cm.display.wrapper, cm.display.scrollbars.addClass); } + } + + cm.display.scrollbars = new scrollbarModel[cm.options.scrollbarStyle](function (node) { + cm.display.wrapper.insertBefore(node, cm.display.scrollbarFiller); + // Prevent clicks in the scrollbars from killing focus + on(node, "mousedown", function () { + if (cm.state.focused) { setTimeout(function () { return cm.display.input.focus(); }, 0); } + }); + node.setAttribute("cm-not-content", "true"); + }, function (pos, axis) { + if (axis == "horizontal") { setScrollLeft(cm, pos); } + else { updateScrollTop(cm, pos); } + }, cm); + if (cm.display.scrollbars.addClass) + { addClass(cm.display.wrapper, cm.display.scrollbars.addClass); } + } + + // Operations are used to wrap a series of changes to the editor + // state in such a way that each change won't have to update the + // cursor and display (which would be awkward, slow, and + // error-prone). Instead, display updates are batched and then all + // combined and executed at once. + + var nextOpId = 0; + // Start a new operation. + function startOperation(cm) { + cm.curOp = { + cm: cm, + viewChanged: false, // Flag that indicates that lines might need to be redrawn + startHeight: cm.doc.height, // Used to detect need to update scrollbar + forceUpdate: false, // Used to force a redraw + updateInput: 0, // Whether to reset the input textarea + typing: false, // Whether this reset should be careful to leave existing text (for compositing) + changeObjs: null, // Accumulated changes, for firing change events + cursorActivityHandlers: null, // Set of handlers to fire cursorActivity on + cursorActivityCalled: 0, // Tracks which cursorActivity handlers have been called already + selectionChanged: false, // Whether the selection needs to be redrawn + updateMaxLine: false, // Set when the widest line needs to be determined anew + scrollLeft: null, scrollTop: null, // Intermediate scroll position, not pushed to DOM yet + scrollToPos: null, // Used to scroll to a specific position + focus: false, + id: ++nextOpId // Unique ID + }; + pushOperation(cm.curOp); + } + + // Finish an operation, updating the display and signalling delayed events + function endOperation(cm) { + var op = cm.curOp; + if (op) { finishOperation(op, function (group) { + for (var i = 0; i < group.ops.length; i++) + { group.ops[i].cm.curOp = null; } + endOperations(group); + }); } + } + + // The DOM updates done when an operation finishes are batched so + // that the minimum number of relayouts are required. + function endOperations(group) { + var ops = group.ops; + for (var i = 0; i < ops.length; i++) // Read DOM + { endOperation_R1(ops[i]); } + for (var i$1 = 0; i$1 < ops.length; i$1++) // Write DOM (maybe) + { endOperation_W1(ops[i$1]); } + for (var i$2 = 0; i$2 < ops.length; i$2++) // Read DOM + { endOperation_R2(ops[i$2]); } + for (var i$3 = 0; i$3 < ops.length; i$3++) // Write DOM (maybe) + { endOperation_W2(ops[i$3]); } + for (var i$4 = 0; i$4 < ops.length; i$4++) // Read DOM + { endOperation_finish(ops[i$4]); } + } + + function endOperation_R1(op) { + var cm = op.cm, display = cm.display; + maybeClipScrollbars(cm); + if (op.updateMaxLine) { findMaxLine(cm); } + + op.mustUpdate = op.viewChanged || op.forceUpdate || op.scrollTop != null || + op.scrollToPos && (op.scrollToPos.from.line < display.viewFrom || + op.scrollToPos.to.line >= display.viewTo) || + display.maxLineChanged && cm.options.lineWrapping; + op.update = op.mustUpdate && + new DisplayUpdate(cm, op.mustUpdate && {top: op.scrollTop, ensure: op.scrollToPos}, op.forceUpdate); + } + + function endOperation_W1(op) { + op.updatedDisplay = op.mustUpdate && updateDisplayIfNeeded(op.cm, op.update); + } + + function endOperation_R2(op) { + var cm = op.cm, display = cm.display; + if (op.updatedDisplay) { updateHeightsInViewport(cm); } + + op.barMeasure = measureForScrollbars(cm); + + // If the max line changed since it was last measured, measure it, + // and ensure the document's width matches it. + // updateDisplay_W2 will use these properties to do the actual resizing + if (display.maxLineChanged && !cm.options.lineWrapping) { + op.adjustWidthTo = measureChar(cm, display.maxLine, display.maxLine.text.length).left + 3; + cm.display.sizerWidth = op.adjustWidthTo; + op.barMeasure.scrollWidth = + Math.max(display.scroller.clientWidth, display.sizer.offsetLeft + op.adjustWidthTo + scrollGap(cm) + cm.display.barWidth); + op.maxScrollLeft = Math.max(0, display.sizer.offsetLeft + op.adjustWidthTo - displayWidth(cm)); + } + + if (op.updatedDisplay || op.selectionChanged) + { op.preparedSelection = display.input.prepareSelection(); } + } + + function endOperation_W2(op) { + var cm = op.cm; + + if (op.adjustWidthTo != null) { + cm.display.sizer.style.minWidth = op.adjustWidthTo + "px"; + if (op.maxScrollLeft < cm.doc.scrollLeft) + { setScrollLeft(cm, Math.min(cm.display.scroller.scrollLeft, op.maxScrollLeft), true); } + cm.display.maxLineChanged = false; + } + + var takeFocus = op.focus && op.focus == activeElt(); + if (op.preparedSelection) + { cm.display.input.showSelection(op.preparedSelection, takeFocus); } + if (op.updatedDisplay || op.startHeight != cm.doc.height) + { updateScrollbars(cm, op.barMeasure); } + if (op.updatedDisplay) + { setDocumentHeight(cm, op.barMeasure); } + + if (op.selectionChanged) { restartBlink(cm); } + + if (cm.state.focused && op.updateInput) + { cm.display.input.reset(op.typing); } + if (takeFocus) { ensureFocus(op.cm); } + } + + function endOperation_finish(op) { + var cm = op.cm, display = cm.display, doc = cm.doc; + + if (op.updatedDisplay) { postUpdateDisplay(cm, op.update); } + + // Abort mouse wheel delta measurement, when scrolling explicitly + if (display.wheelStartX != null && (op.scrollTop != null || op.scrollLeft != null || op.scrollToPos)) + { display.wheelStartX = display.wheelStartY = null; } + + // Propagate the scroll position to the actual DOM scroller + if (op.scrollTop != null) { setScrollTop(cm, op.scrollTop, op.forceScroll); } + + if (op.scrollLeft != null) { setScrollLeft(cm, op.scrollLeft, true, true); } + // If we need to scroll a specific position into view, do so. + if (op.scrollToPos) { + var rect = scrollPosIntoView(cm, clipPos(doc, op.scrollToPos.from), + clipPos(doc, op.scrollToPos.to), op.scrollToPos.margin); + maybeScrollWindow(cm, rect); + } + + // Fire events for markers that are hidden/unidden by editing or + // undoing + var hidden = op.maybeHiddenMarkers, unhidden = op.maybeUnhiddenMarkers; + if (hidden) { for (var i = 0; i < hidden.length; ++i) + { if (!hidden[i].lines.length) { signal(hidden[i], "hide"); } } } + if (unhidden) { for (var i$1 = 0; i$1 < unhidden.length; ++i$1) + { if (unhidden[i$1].lines.length) { signal(unhidden[i$1], "unhide"); } } } + + if (display.wrapper.offsetHeight) + { doc.scrollTop = cm.display.scroller.scrollTop; } + + // Fire change events, and delayed event handlers + if (op.changeObjs) + { signal(cm, "changes", cm, op.changeObjs); } + if (op.update) + { op.update.finish(); } + } + + // Run the given function in an operation + function runInOp(cm, f) { + if (cm.curOp) { return f() } + startOperation(cm); + try { return f() } + finally { endOperation(cm); } + } + // Wraps a function in an operation. Returns the wrapped function. + function operation(cm, f) { + return function() { + if (cm.curOp) { return f.apply(cm, arguments) } + startOperation(cm); + try { return f.apply(cm, arguments) } + finally { endOperation(cm); } + } + } + // Used to add methods to editor and doc instances, wrapping them in + // operations. + function methodOp(f) { + return function() { + if (this.curOp) { return f.apply(this, arguments) } + startOperation(this); + try { return f.apply(this, arguments) } + finally { endOperation(this); } + } + } + function docMethodOp(f) { + return function() { + var cm = this.cm; + if (!cm || cm.curOp) { return f.apply(this, arguments) } + startOperation(cm); + try { return f.apply(this, arguments) } + finally { endOperation(cm); } + } + } + + // HIGHLIGHT WORKER + + function startWorker(cm, time) { + if (cm.doc.highlightFrontier < cm.display.viewTo) + { cm.state.highlight.set(time, bind(highlightWorker, cm)); } + } + + function highlightWorker(cm) { + var doc = cm.doc; + if (doc.highlightFrontier >= cm.display.viewTo) { return } + var end = +new Date + cm.options.workTime; + var context = getContextBefore(cm, doc.highlightFrontier); + var changedLines = []; + + doc.iter(context.line, Math.min(doc.first + doc.size, cm.display.viewTo + 500), function (line) { + if (context.line >= cm.display.viewFrom) { // Visible + var oldStyles = line.styles; + var resetState = line.text.length > cm.options.maxHighlightLength ? copyState(doc.mode, context.state) : null; + var highlighted = highlightLine(cm, line, context, true); + if (resetState) { context.state = resetState; } + line.styles = highlighted.styles; + var oldCls = line.styleClasses, newCls = highlighted.classes; + if (newCls) { line.styleClasses = newCls; } + else if (oldCls) { line.styleClasses = null; } + var ischange = !oldStyles || oldStyles.length != line.styles.length || + oldCls != newCls && (!oldCls || !newCls || oldCls.bgClass != newCls.bgClass || oldCls.textClass != newCls.textClass); + for (var i = 0; !ischange && i < oldStyles.length; ++i) { ischange = oldStyles[i] != line.styles[i]; } + if (ischange) { changedLines.push(context.line); } + line.stateAfter = context.save(); + context.nextLine(); + } else { + if (line.text.length <= cm.options.maxHighlightLength) + { processLine(cm, line.text, context); } + line.stateAfter = context.line % 5 == 0 ? context.save() : null; + context.nextLine(); + } + if (+new Date > end) { + startWorker(cm, cm.options.workDelay); + return true + } + }); + doc.highlightFrontier = context.line; + doc.modeFrontier = Math.max(doc.modeFrontier, context.line); + if (changedLines.length) { runInOp(cm, function () { + for (var i = 0; i < changedLines.length; i++) + { regLineChange(cm, changedLines[i], "text"); } + }); } + } + + // DISPLAY DRAWING + + var DisplayUpdate = function(cm, viewport, force) { + var display = cm.display; + + this.viewport = viewport; + // Store some values that we'll need later (but don't want to force a relayout for) + this.visible = visibleLines(display, cm.doc, viewport); + this.editorIsHidden = !display.wrapper.offsetWidth; + this.wrapperHeight = display.wrapper.clientHeight; + this.wrapperWidth = display.wrapper.clientWidth; + this.oldDisplayWidth = displayWidth(cm); + this.force = force; + this.dims = getDimensions(cm); + this.events = []; + }; + + DisplayUpdate.prototype.signal = function (emitter, type) { + if (hasHandler(emitter, type)) + { this.events.push(arguments); } + }; + DisplayUpdate.prototype.finish = function () { + for (var i = 0; i < this.events.length; i++) + { signal.apply(null, this.events[i]); } + }; + + function maybeClipScrollbars(cm) { + var display = cm.display; + if (!display.scrollbarsClipped && display.scroller.offsetWidth) { + display.nativeBarWidth = display.scroller.offsetWidth - display.scroller.clientWidth; + display.heightForcer.style.height = scrollGap(cm) + "px"; + display.sizer.style.marginBottom = -display.nativeBarWidth + "px"; + display.sizer.style.borderRightWidth = scrollGap(cm) + "px"; + display.scrollbarsClipped = true; + } + } + + function selectionSnapshot(cm) { + if (cm.hasFocus()) { return null } + var active = activeElt(); + if (!active || !contains(cm.display.lineDiv, active)) { return null } + var result = {activeElt: active}; + if (window.getSelection) { + var sel = window.getSelection(); + if (sel.anchorNode && sel.extend && contains(cm.display.lineDiv, sel.anchorNode)) { + result.anchorNode = sel.anchorNode; + result.anchorOffset = sel.anchorOffset; + result.focusNode = sel.focusNode; + result.focusOffset = sel.focusOffset; + } + } + return result + } + + function restoreSelection(snapshot) { + if (!snapshot || !snapshot.activeElt || snapshot.activeElt == activeElt()) { return } + snapshot.activeElt.focus(); + if (!/^(INPUT|TEXTAREA)$/.test(snapshot.activeElt.nodeName) && + snapshot.anchorNode && contains(document.body, snapshot.anchorNode) && contains(document.body, snapshot.focusNode)) { + var sel = window.getSelection(), range = document.createRange(); + range.setEnd(snapshot.anchorNode, snapshot.anchorOffset); + range.collapse(false); + sel.removeAllRanges(); + sel.addRange(range); + sel.extend(snapshot.focusNode, snapshot.focusOffset); + } + } + + // Does the actual updating of the line display. Bails out + // (returning false) when there is nothing to be done and forced is + // false. + function updateDisplayIfNeeded(cm, update) { + var display = cm.display, doc = cm.doc; + + if (update.editorIsHidden) { + resetView(cm); + return false + } + + // Bail out if the visible area is already rendered and nothing changed. + if (!update.force && + update.visible.from >= display.viewFrom && update.visible.to <= display.viewTo && + (display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo) && + display.renderedView == display.view && countDirtyView(cm) == 0) + { return false } + + if (maybeUpdateLineNumberWidth(cm)) { + resetView(cm); + update.dims = getDimensions(cm); + } + + // Compute a suitable new viewport (from & to) + var end = doc.first + doc.size; + var from = Math.max(update.visible.from - cm.options.viewportMargin, doc.first); + var to = Math.min(end, update.visible.to + cm.options.viewportMargin); + if (display.viewFrom < from && from - display.viewFrom < 20) { from = Math.max(doc.first, display.viewFrom); } + if (display.viewTo > to && display.viewTo - to < 20) { to = Math.min(end, display.viewTo); } + if (sawCollapsedSpans) { + from = visualLineNo(cm.doc, from); + to = visualLineEndNo(cm.doc, to); + } + + var different = from != display.viewFrom || to != display.viewTo || + display.lastWrapHeight != update.wrapperHeight || display.lastWrapWidth != update.wrapperWidth; + adjustView(cm, from, to); + + display.viewOffset = heightAtLine(getLine(cm.doc, display.viewFrom)); + // Position the mover div to align with the current scroll position + cm.display.mover.style.top = display.viewOffset + "px"; + + var toUpdate = countDirtyView(cm); + if (!different && toUpdate == 0 && !update.force && display.renderedView == display.view && + (display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo)) + { return false } + + // For big changes, we hide the enclosing element during the + // update, since that speeds up the operations on most browsers. + var selSnapshot = selectionSnapshot(cm); + if (toUpdate > 4) { display.lineDiv.style.display = "none"; } + patchDisplay(cm, display.updateLineNumbers, update.dims); + if (toUpdate > 4) { display.lineDiv.style.display = ""; } + display.renderedView = display.view; + // There might have been a widget with a focused element that got + // hidden or updated, if so re-focus it. + restoreSelection(selSnapshot); + + // Prevent selection and cursors from interfering with the scroll + // width and height. + removeChildren(display.cursorDiv); + removeChildren(display.selectionDiv); + display.gutters.style.height = display.sizer.style.minHeight = 0; + + if (different) { + display.lastWrapHeight = update.wrapperHeight; + display.lastWrapWidth = update.wrapperWidth; + startWorker(cm, 400); + } + + display.updateLineNumbers = null; + + return true + } + + function postUpdateDisplay(cm, update) { + var viewport = update.viewport; + + for (var first = true;; first = false) { + if (!first || !cm.options.lineWrapping || update.oldDisplayWidth == displayWidth(cm)) { + // Clip forced viewport to actual scrollable area. + if (viewport && viewport.top != null) + { viewport = {top: Math.min(cm.doc.height + paddingVert(cm.display) - displayHeight(cm), viewport.top)}; } + // Updated line heights might result in the drawn area not + // actually covering the viewport. Keep looping until it does. + update.visible = visibleLines(cm.display, cm.doc, viewport); + if (update.visible.from >= cm.display.viewFrom && update.visible.to <= cm.display.viewTo) + { break } + } else if (first) { + update.visible = visibleLines(cm.display, cm.doc, viewport); + } + if (!updateDisplayIfNeeded(cm, update)) { break } + updateHeightsInViewport(cm); + var barMeasure = measureForScrollbars(cm); + updateSelection(cm); + updateScrollbars(cm, barMeasure); + setDocumentHeight(cm, barMeasure); + update.force = false; + } + + update.signal(cm, "update", cm); + if (cm.display.viewFrom != cm.display.reportedViewFrom || cm.display.viewTo != cm.display.reportedViewTo) { + update.signal(cm, "viewportChange", cm, cm.display.viewFrom, cm.display.viewTo); + cm.display.reportedViewFrom = cm.display.viewFrom; cm.display.reportedViewTo = cm.display.viewTo; + } + } + + function updateDisplaySimple(cm, viewport) { + var update = new DisplayUpdate(cm, viewport); + if (updateDisplayIfNeeded(cm, update)) { + updateHeightsInViewport(cm); + postUpdateDisplay(cm, update); + var barMeasure = measureForScrollbars(cm); + updateSelection(cm); + updateScrollbars(cm, barMeasure); + setDocumentHeight(cm, barMeasure); + update.finish(); + } + } + + // Sync the actual display DOM structure with display.view, removing + // nodes for lines that are no longer in view, and creating the ones + // that are not there yet, and updating the ones that are out of + // date. + function patchDisplay(cm, updateNumbersFrom, dims) { + var display = cm.display, lineNumbers = cm.options.lineNumbers; + var container = display.lineDiv, cur = container.firstChild; + + function rm(node) { + var next = node.nextSibling; + // Works around a throw-scroll bug in OS X Webkit + if (webkit && mac && cm.display.currentWheelTarget == node) + { node.style.display = "none"; } + else + { node.parentNode.removeChild(node); } + return next + } + + var view = display.view, lineN = display.viewFrom; + // Loop over the elements in the view, syncing cur (the DOM nodes + // in display.lineDiv) with the view as we go. + for (var i = 0; i < view.length; i++) { + var lineView = view[i]; + if (lineView.hidden) ; else if (!lineView.node || lineView.node.parentNode != container) { // Not drawn yet + var node = buildLineElement(cm, lineView, lineN, dims); + container.insertBefore(node, cur); + } else { // Already drawn + while (cur != lineView.node) { cur = rm(cur); } + var updateNumber = lineNumbers && updateNumbersFrom != null && + updateNumbersFrom <= lineN && lineView.lineNumber; + if (lineView.changes) { + if (indexOf(lineView.changes, "gutter") > -1) { updateNumber = false; } + updateLineForChanges(cm, lineView, lineN, dims); + } + if (updateNumber) { + removeChildren(lineView.lineNumber); + lineView.lineNumber.appendChild(document.createTextNode(lineNumberFor(cm.options, lineN))); + } + cur = lineView.node.nextSibling; + } + lineN += lineView.size; + } + while (cur) { cur = rm(cur); } + } + + function updateGutterSpace(display) { + var width = display.gutters.offsetWidth; + display.sizer.style.marginLeft = width + "px"; + } + + function setDocumentHeight(cm, measure) { + cm.display.sizer.style.minHeight = measure.docHeight + "px"; + cm.display.heightForcer.style.top = measure.docHeight + "px"; + cm.display.gutters.style.height = (measure.docHeight + cm.display.barHeight + scrollGap(cm)) + "px"; + } + + // Re-align line numbers and gutter marks to compensate for + // horizontal scrolling. + function alignHorizontally(cm) { + var display = cm.display, view = display.view; + if (!display.alignWidgets && (!display.gutters.firstChild || !cm.options.fixedGutter)) { return } + var comp = compensateForHScroll(display) - display.scroller.scrollLeft + cm.doc.scrollLeft; + var gutterW = display.gutters.offsetWidth, left = comp + "px"; + for (var i = 0; i < view.length; i++) { if (!view[i].hidden) { + if (cm.options.fixedGutter) { + if (view[i].gutter) + { view[i].gutter.style.left = left; } + if (view[i].gutterBackground) + { view[i].gutterBackground.style.left = left; } + } + var align = view[i].alignable; + if (align) { for (var j = 0; j < align.length; j++) + { align[j].style.left = left; } } + } } + if (cm.options.fixedGutter) + { display.gutters.style.left = (comp + gutterW) + "px"; } + } + + // Used to ensure that the line number gutter is still the right + // size for the current document size. Returns true when an update + // is needed. + function maybeUpdateLineNumberWidth(cm) { + if (!cm.options.lineNumbers) { return false } + var doc = cm.doc, last = lineNumberFor(cm.options, doc.first + doc.size - 1), display = cm.display; + if (last.length != display.lineNumChars) { + var test = display.measure.appendChild(elt("div", [elt("div", last)], + "CodeMirror-linenumber CodeMirror-gutter-elt")); + var innerW = test.firstChild.offsetWidth, padding = test.offsetWidth - innerW; + display.lineGutter.style.width = ""; + display.lineNumInnerWidth = Math.max(innerW, display.lineGutter.offsetWidth - padding) + 1; + display.lineNumWidth = display.lineNumInnerWidth + padding; + display.lineNumChars = display.lineNumInnerWidth ? last.length : -1; + display.lineGutter.style.width = display.lineNumWidth + "px"; + updateGutterSpace(cm.display); + return true + } + return false + } + + function getGutters(gutters, lineNumbers) { + var result = [], sawLineNumbers = false; + for (var i = 0; i < gutters.length; i++) { + var name = gutters[i], style = null; + if (typeof name != "string") { style = name.style; name = name.className; } + if (name == "CodeMirror-linenumbers") { + if (!lineNumbers) { continue } + else { sawLineNumbers = true; } + } + result.push({className: name, style: style}); + } + if (lineNumbers && !sawLineNumbers) { result.push({className: "CodeMirror-linenumbers", style: null}); } + return result + } + + // Rebuild the gutter elements, ensure the margin to the left of the + // code matches their width. + function renderGutters(display) { + var gutters = display.gutters, specs = display.gutterSpecs; + removeChildren(gutters); + display.lineGutter = null; + for (var i = 0; i < specs.length; ++i) { + var ref = specs[i]; + var className = ref.className; + var style = ref.style; + var gElt = gutters.appendChild(elt("div", null, "CodeMirror-gutter " + className)); + if (style) { gElt.style.cssText = style; } + if (className == "CodeMirror-linenumbers") { + display.lineGutter = gElt; + gElt.style.width = (display.lineNumWidth || 1) + "px"; + } + } + gutters.style.display = specs.length ? "" : "none"; + updateGutterSpace(display); + } + + function updateGutters(cm) { + renderGutters(cm.display); + regChange(cm); + alignHorizontally(cm); + } + + // The display handles the DOM integration, both for input reading + // and content drawing. It holds references to DOM nodes and + // display-related state. + + function Display(place, doc, input, options) { + var d = this; + this.input = input; + + // Covers bottom-right square when both scrollbars are present. + d.scrollbarFiller = elt("div", null, "CodeMirror-scrollbar-filler"); + d.scrollbarFiller.setAttribute("cm-not-content", "true"); + // Covers bottom of gutter when coverGutterNextToScrollbar is on + // and h scrollbar is present. + d.gutterFiller = elt("div", null, "CodeMirror-gutter-filler"); + d.gutterFiller.setAttribute("cm-not-content", "true"); + // Will contain the actual code, positioned to cover the viewport. + d.lineDiv = eltP("div", null, "CodeMirror-code"); + // Elements are added to these to represent selection and cursors. + d.selectionDiv = elt("div", null, null, "position: relative; z-index: 1"); + d.cursorDiv = elt("div", null, "CodeMirror-cursors"); + // A visibility: hidden element used to find the size of things. + d.measure = elt("div", null, "CodeMirror-measure"); + // When lines outside of the viewport are measured, they are drawn in this. + d.lineMeasure = elt("div", null, "CodeMirror-measure"); + // Wraps everything that needs to exist inside the vertically-padded coordinate system + d.lineSpace = eltP("div", [d.measure, d.lineMeasure, d.selectionDiv, d.cursorDiv, d.lineDiv], + null, "position: relative; outline: none"); + var lines = eltP("div", [d.lineSpace], "CodeMirror-lines"); + // Moved around its parent to cover visible view. + d.mover = elt("div", [lines], null, "position: relative"); + // Set to the height of the document, allowing scrolling. + d.sizer = elt("div", [d.mover], "CodeMirror-sizer"); + d.sizerWidth = null; + // Behavior of elts with overflow: auto and padding is + // inconsistent across browsers. This is used to ensure the + // scrollable area is big enough. + d.heightForcer = elt("div", null, null, "position: absolute; height: " + scrollerGap + "px; width: 1px;"); + // Will contain the gutters, if any. + d.gutters = elt("div", null, "CodeMirror-gutters"); + d.lineGutter = null; + // Actual scrollable element. + d.scroller = elt("div", [d.sizer, d.heightForcer, d.gutters], "CodeMirror-scroll"); + d.scroller.setAttribute("tabIndex", "-1"); + // The element in which the editor lives. + d.wrapper = elt("div", [d.scrollbarFiller, d.gutterFiller, d.scroller], "CodeMirror"); + + // Work around IE7 z-index bug (not perfect, hence IE7 not really being supported) + if (ie && ie_version < 8) { d.gutters.style.zIndex = -1; d.scroller.style.paddingRight = 0; } + if (!webkit && !(gecko && mobile)) { d.scroller.draggable = true; } + + if (place) { + if (place.appendChild) { place.appendChild(d.wrapper); } + else { place(d.wrapper); } + } + + // Current rendered range (may be bigger than the view window). + d.viewFrom = d.viewTo = doc.first; + d.reportedViewFrom = d.reportedViewTo = doc.first; + // Information about the rendered lines. + d.view = []; + d.renderedView = null; + // Holds info about a single rendered line when it was rendered + // for measurement, while not in view. + d.externalMeasured = null; + // Empty space (in pixels) above the view + d.viewOffset = 0; + d.lastWrapHeight = d.lastWrapWidth = 0; + d.updateLineNumbers = null; + + d.nativeBarWidth = d.barHeight = d.barWidth = 0; + d.scrollbarsClipped = false; + + // Used to only resize the line number gutter when necessary (when + // the amount of lines crosses a boundary that makes its width change) + d.lineNumWidth = d.lineNumInnerWidth = d.lineNumChars = null; + // Set to true when a non-horizontal-scrolling line widget is + // added. As an optimization, line widget aligning is skipped when + // this is false. + d.alignWidgets = false; + + d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null; + + // Tracks the maximum line length so that the horizontal scrollbar + // can be kept static when scrolling. + d.maxLine = null; + d.maxLineLength = 0; + d.maxLineChanged = false; + + // Used for measuring wheel scrolling granularity + d.wheelDX = d.wheelDY = d.wheelStartX = d.wheelStartY = null; + + // True when shift is held down. + d.shift = false; + + // Used to track whether anything happened since the context menu + // was opened. + d.selForContextMenu = null; + + d.activeTouch = null; + + d.gutterSpecs = getGutters(options.gutters, options.lineNumbers); + renderGutters(d); + + input.init(d); + } + + // Since the delta values reported on mouse wheel events are + // unstandardized between browsers and even browser versions, and + // generally horribly unpredictable, this code starts by measuring + // the scroll effect that the first few mouse wheel events have, + // and, from that, detects the way it can convert deltas to pixel + // offsets afterwards. + // + // The reason we want to know the amount a wheel event will scroll + // is that it gives us a chance to update the display before the + // actual scrolling happens, reducing flickering. + + var wheelSamples = 0, wheelPixelsPerUnit = null; + // Fill in a browser-detected starting value on browsers where we + // know one. These don't have to be accurate -- the result of them + // being wrong would just be a slight flicker on the first wheel + // scroll (if it is large enough). + if (ie) { wheelPixelsPerUnit = -.53; } + else if (gecko) { wheelPixelsPerUnit = 15; } + else if (chrome) { wheelPixelsPerUnit = -.7; } + else if (safari) { wheelPixelsPerUnit = -1/3; } + + function wheelEventDelta(e) { + var dx = e.wheelDeltaX, dy = e.wheelDeltaY; + if (dx == null && e.detail && e.axis == e.HORIZONTAL_AXIS) { dx = e.detail; } + if (dy == null && e.detail && e.axis == e.VERTICAL_AXIS) { dy = e.detail; } + else if (dy == null) { dy = e.wheelDelta; } + return {x: dx, y: dy} + } + function wheelEventPixels(e) { + var delta = wheelEventDelta(e); + delta.x *= wheelPixelsPerUnit; + delta.y *= wheelPixelsPerUnit; + return delta + } + + function onScrollWheel(cm, e) { + var delta = wheelEventDelta(e), dx = delta.x, dy = delta.y; + + var display = cm.display, scroll = display.scroller; + // Quit if there's nothing to scroll here + var canScrollX = scroll.scrollWidth > scroll.clientWidth; + var canScrollY = scroll.scrollHeight > scroll.clientHeight; + if (!(dx && canScrollX || dy && canScrollY)) { return } + + // Webkit browsers on OS X abort momentum scrolls when the target + // of the scroll event is removed from the scrollable element. + // This hack (see related code in patchDisplay) makes sure the + // element is kept around. + if (dy && mac && webkit) { + outer: for (var cur = e.target, view = display.view; cur != scroll; cur = cur.parentNode) { + for (var i = 0; i < view.length; i++) { + if (view[i].node == cur) { + cm.display.currentWheelTarget = cur; + break outer + } + } + } + } + + // On some browsers, horizontal scrolling will cause redraws to + // happen before the gutter has been realigned, causing it to + // wriggle around in a most unseemly way. When we have an + // estimated pixels/delta value, we just handle horizontal + // scrolling entirely here. It'll be slightly off from native, but + // better than glitching out. + if (dx && !gecko && !presto && wheelPixelsPerUnit != null) { + if (dy && canScrollY) + { updateScrollTop(cm, Math.max(0, scroll.scrollTop + dy * wheelPixelsPerUnit)); } + setScrollLeft(cm, Math.max(0, scroll.scrollLeft + dx * wheelPixelsPerUnit)); + // Only prevent default scrolling if vertical scrolling is + // actually possible. Otherwise, it causes vertical scroll + // jitter on OSX trackpads when deltaX is small and deltaY + // is large (issue #3579) + if (!dy || (dy && canScrollY)) + { e_preventDefault(e); } + display.wheelStartX = null; // Abort measurement, if in progress + return + } + + // 'Project' the visible viewport to cover the area that is being + // scrolled into view (if we know enough to estimate it). + if (dy && wheelPixelsPerUnit != null) { + var pixels = dy * wheelPixelsPerUnit; + var top = cm.doc.scrollTop, bot = top + display.wrapper.clientHeight; + if (pixels < 0) { top = Math.max(0, top + pixels - 50); } + else { bot = Math.min(cm.doc.height, bot + pixels + 50); } + updateDisplaySimple(cm, {top: top, bottom: bot}); + } + + if (wheelSamples < 20) { + if (display.wheelStartX == null) { + display.wheelStartX = scroll.scrollLeft; display.wheelStartY = scroll.scrollTop; + display.wheelDX = dx; display.wheelDY = dy; + setTimeout(function () { + if (display.wheelStartX == null) { return } + var movedX = scroll.scrollLeft - display.wheelStartX; + var movedY = scroll.scrollTop - display.wheelStartY; + var sample = (movedY && display.wheelDY && movedY / display.wheelDY) || + (movedX && display.wheelDX && movedX / display.wheelDX); + display.wheelStartX = display.wheelStartY = null; + if (!sample) { return } + wheelPixelsPerUnit = (wheelPixelsPerUnit * wheelSamples + sample) / (wheelSamples + 1); + ++wheelSamples; + }, 200); + } else { + display.wheelDX += dx; display.wheelDY += dy; + } + } + } + + // Selection objects are immutable. A new one is created every time + // the selection changes. A selection is one or more non-overlapping + // (and non-touching) ranges, sorted, and an integer that indicates + // which one is the primary selection (the one that's scrolled into + // view, that getCursor returns, etc). + var Selection = function(ranges, primIndex) { + this.ranges = ranges; + this.primIndex = primIndex; + }; + + Selection.prototype.primary = function () { return this.ranges[this.primIndex] }; + + Selection.prototype.equals = function (other) { + if (other == this) { return true } + if (other.primIndex != this.primIndex || other.ranges.length != this.ranges.length) { return false } + for (var i = 0; i < this.ranges.length; i++) { + var here = this.ranges[i], there = other.ranges[i]; + if (!equalCursorPos(here.anchor, there.anchor) || !equalCursorPos(here.head, there.head)) { return false } + } + return true + }; + + Selection.prototype.deepCopy = function () { + var out = []; + for (var i = 0; i < this.ranges.length; i++) + { out[i] = new Range(copyPos(this.ranges[i].anchor), copyPos(this.ranges[i].head)); } + return new Selection(out, this.primIndex) + }; + + Selection.prototype.somethingSelected = function () { + for (var i = 0; i < this.ranges.length; i++) + { if (!this.ranges[i].empty()) { return true } } + return false + }; + + Selection.prototype.contains = function (pos, end) { + if (!end) { end = pos; } + for (var i = 0; i < this.ranges.length; i++) { + var range = this.ranges[i]; + if (cmp(end, range.from()) >= 0 && cmp(pos, range.to()) <= 0) + { return i } + } + return -1 + }; + + var Range = function(anchor, head) { + this.anchor = anchor; this.head = head; + }; + + Range.prototype.from = function () { return minPos(this.anchor, this.head) }; + Range.prototype.to = function () { return maxPos(this.anchor, this.head) }; + Range.prototype.empty = function () { return this.head.line == this.anchor.line && this.head.ch == this.anchor.ch }; + + // Take an unsorted, potentially overlapping set of ranges, and + // build a selection out of it. 'Consumes' ranges array (modifying + // it). + function normalizeSelection(cm, ranges, primIndex) { + var mayTouch = cm && cm.options.selectionsMayTouch; + var prim = ranges[primIndex]; + ranges.sort(function (a, b) { return cmp(a.from(), b.from()); }); + primIndex = indexOf(ranges, prim); + for (var i = 1; i < ranges.length; i++) { + var cur = ranges[i], prev = ranges[i - 1]; + var diff = cmp(prev.to(), cur.from()); + if (mayTouch && !cur.empty() ? diff > 0 : diff >= 0) { + var from = minPos(prev.from(), cur.from()), to = maxPos(prev.to(), cur.to()); + var inv = prev.empty() ? cur.from() == cur.head : prev.from() == prev.head; + if (i <= primIndex) { --primIndex; } + ranges.splice(--i, 2, new Range(inv ? to : from, inv ? from : to)); + } + } + return new Selection(ranges, primIndex) + } + + function simpleSelection(anchor, head) { + return new Selection([new Range(anchor, head || anchor)], 0) + } + + // Compute the position of the end of a change (its 'to' property + // refers to the pre-change end). + function changeEnd(change) { + if (!change.text) { return change.to } + return Pos(change.from.line + change.text.length - 1, + lst(change.text).length + (change.text.length == 1 ? change.from.ch : 0)) + } + + // Adjust a position to refer to the post-change position of the + // same text, or the end of the change if the change covers it. + function adjustForChange(pos, change) { + if (cmp(pos, change.from) < 0) { return pos } + if (cmp(pos, change.to) <= 0) { return changeEnd(change) } + + var line = pos.line + change.text.length - (change.to.line - change.from.line) - 1, ch = pos.ch; + if (pos.line == change.to.line) { ch += changeEnd(change).ch - change.to.ch; } + return Pos(line, ch) + } + + function computeSelAfterChange(doc, change) { + var out = []; + for (var i = 0; i < doc.sel.ranges.length; i++) { + var range = doc.sel.ranges[i]; + out.push(new Range(adjustForChange(range.anchor, change), + adjustForChange(range.head, change))); + } + return normalizeSelection(doc.cm, out, doc.sel.primIndex) + } + + function offsetPos(pos, old, nw) { + if (pos.line == old.line) + { return Pos(nw.line, pos.ch - old.ch + nw.ch) } + else + { return Pos(nw.line + (pos.line - old.line), pos.ch) } + } + + // Used by replaceSelections to allow moving the selection to the + // start or around the replaced test. Hint may be "start" or "around". + function computeReplacedSel(doc, changes, hint) { + var out = []; + var oldPrev = Pos(doc.first, 0), newPrev = oldPrev; + for (var i = 0; i < changes.length; i++) { + var change = changes[i]; + var from = offsetPos(change.from, oldPrev, newPrev); + var to = offsetPos(changeEnd(change), oldPrev, newPrev); + oldPrev = change.to; + newPrev = to; + if (hint == "around") { + var range = doc.sel.ranges[i], inv = cmp(range.head, range.anchor) < 0; + out[i] = new Range(inv ? to : from, inv ? from : to); + } else { + out[i] = new Range(from, from); + } + } + return new Selection(out, doc.sel.primIndex) + } + + // Used to get the editor into a consistent state again when options change. + + function loadMode(cm) { + cm.doc.mode = getMode(cm.options, cm.doc.modeOption); + resetModeState(cm); + } + + function resetModeState(cm) { + cm.doc.iter(function (line) { + if (line.stateAfter) { line.stateAfter = null; } + if (line.styles) { line.styles = null; } + }); + cm.doc.modeFrontier = cm.doc.highlightFrontier = cm.doc.first; + startWorker(cm, 100); + cm.state.modeGen++; + if (cm.curOp) { regChange(cm); } + } + + // DOCUMENT DATA STRUCTURE + + // By default, updates that start and end at the beginning of a line + // are treated specially, in order to make the association of line + // widgets and marker elements with the text behave more intuitive. + function isWholeLineUpdate(doc, change) { + return change.from.ch == 0 && change.to.ch == 0 && lst(change.text) == "" && + (!doc.cm || doc.cm.options.wholeLineUpdateBefore) + } + + // Perform a change on the document data structure. + function updateDoc(doc, change, markedSpans, estimateHeight) { + function spansFor(n) {return markedSpans ? markedSpans[n] : null} + function update(line, text, spans) { + updateLine(line, text, spans, estimateHeight); + signalLater(line, "change", line, change); + } + function linesFor(start, end) { + var result = []; + for (var i = start; i < end; ++i) + { result.push(new Line(text[i], spansFor(i), estimateHeight)); } + return result + } + + var from = change.from, to = change.to, text = change.text; + var firstLine = getLine(doc, from.line), lastLine = getLine(doc, to.line); + var lastText = lst(text), lastSpans = spansFor(text.length - 1), nlines = to.line - from.line; + + // Adjust the line structure + if (change.full) { + doc.insert(0, linesFor(0, text.length)); + doc.remove(text.length, doc.size - text.length); + } else if (isWholeLineUpdate(doc, change)) { + // This is a whole-line replace. Treated specially to make + // sure line objects move the way they are supposed to. + var added = linesFor(0, text.length - 1); + update(lastLine, lastLine.text, lastSpans); + if (nlines) { doc.remove(from.line, nlines); } + if (added.length) { doc.insert(from.line, added); } + } else if (firstLine == lastLine) { + if (text.length == 1) { + update(firstLine, firstLine.text.slice(0, from.ch) + lastText + firstLine.text.slice(to.ch), lastSpans); + } else { + var added$1 = linesFor(1, text.length - 1); + added$1.push(new Line(lastText + firstLine.text.slice(to.ch), lastSpans, estimateHeight)); + update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0)); + doc.insert(from.line + 1, added$1); + } + } else if (text.length == 1) { + update(firstLine, firstLine.text.slice(0, from.ch) + text[0] + lastLine.text.slice(to.ch), spansFor(0)); + doc.remove(from.line + 1, nlines); + } else { + update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0)); + update(lastLine, lastText + lastLine.text.slice(to.ch), lastSpans); + var added$2 = linesFor(1, text.length - 1); + if (nlines > 1) { doc.remove(from.line + 1, nlines - 1); } + doc.insert(from.line + 1, added$2); + } + + signalLater(doc, "change", doc, change); + } + + // Call f for all linked documents. + function linkedDocs(doc, f, sharedHistOnly) { + function propagate(doc, skip, sharedHist) { + if (doc.linked) { for (var i = 0; i < doc.linked.length; ++i) { + var rel = doc.linked[i]; + if (rel.doc == skip) { continue } + var shared = sharedHist && rel.sharedHist; + if (sharedHistOnly && !shared) { continue } + f(rel.doc, shared); + propagate(rel.doc, doc, shared); + } } + } + propagate(doc, null, true); + } + + // Attach a document to an editor. + function attachDoc(cm, doc) { + if (doc.cm) { throw new Error("This document is already in use.") } + cm.doc = doc; + doc.cm = cm; + estimateLineHeights(cm); + loadMode(cm); + setDirectionClass(cm); + if (!cm.options.lineWrapping) { findMaxLine(cm); } + cm.options.mode = doc.modeOption; + regChange(cm); + } + + function setDirectionClass(cm) { + (cm.doc.direction == "rtl" ? addClass : rmClass)(cm.display.lineDiv, "CodeMirror-rtl"); + } + + function directionChanged(cm) { + runInOp(cm, function () { + setDirectionClass(cm); + regChange(cm); + }); + } + + function History(startGen) { + // Arrays of change events and selections. Doing something adds an + // event to done and clears undo. Undoing moves events from done + // to undone, redoing moves them in the other direction. + this.done = []; this.undone = []; + this.undoDepth = Infinity; + // Used to track when changes can be merged into a single undo + // event + this.lastModTime = this.lastSelTime = 0; + this.lastOp = this.lastSelOp = null; + this.lastOrigin = this.lastSelOrigin = null; + // Used by the isClean() method + this.generation = this.maxGeneration = startGen || 1; + } + + // Create a history change event from an updateDoc-style change + // object. + function historyChangeFromChange(doc, change) { + var histChange = {from: copyPos(change.from), to: changeEnd(change), text: getBetween(doc, change.from, change.to)}; + attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1); + linkedDocs(doc, function (doc) { return attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1); }, true); + return histChange + } + + // Pop all selection events off the end of a history array. Stop at + // a change event. + function clearSelectionEvents(array) { + while (array.length) { + var last = lst(array); + if (last.ranges) { array.pop(); } + else { break } + } + } + + // Find the top change event in the history. Pop off selection + // events that are in the way. + function lastChangeEvent(hist, force) { + if (force) { + clearSelectionEvents(hist.done); + return lst(hist.done) + } else if (hist.done.length && !lst(hist.done).ranges) { + return lst(hist.done) + } else if (hist.done.length > 1 && !hist.done[hist.done.length - 2].ranges) { + hist.done.pop(); + return lst(hist.done) + } + } + + // Register a change in the history. Merges changes that are within + // a single operation, or are close together with an origin that + // allows merging (starting with "+") into a single event. + function addChangeToHistory(doc, change, selAfter, opId) { + var hist = doc.history; + hist.undone.length = 0; + var time = +new Date, cur; + var last; + + if ((hist.lastOp == opId || + hist.lastOrigin == change.origin && change.origin && + ((change.origin.charAt(0) == "+" && hist.lastModTime > time - (doc.cm ? doc.cm.options.historyEventDelay : 500)) || + change.origin.charAt(0) == "*")) && + (cur = lastChangeEvent(hist, hist.lastOp == opId))) { + // Merge this change into the last event + last = lst(cur.changes); + if (cmp(change.from, change.to) == 0 && cmp(change.from, last.to) == 0) { + // Optimized case for simple insertion -- don't want to add + // new changesets for every character typed + last.to = changeEnd(change); + } else { + // Add new sub-event + cur.changes.push(historyChangeFromChange(doc, change)); + } + } else { + // Can not be merged, start a new event. + var before = lst(hist.done); + if (!before || !before.ranges) + { pushSelectionToHistory(doc.sel, hist.done); } + cur = {changes: [historyChangeFromChange(doc, change)], + generation: hist.generation}; + hist.done.push(cur); + while (hist.done.length > hist.undoDepth) { + hist.done.shift(); + if (!hist.done[0].ranges) { hist.done.shift(); } + } + } + hist.done.push(selAfter); + hist.generation = ++hist.maxGeneration; + hist.lastModTime = hist.lastSelTime = time; + hist.lastOp = hist.lastSelOp = opId; + hist.lastOrigin = hist.lastSelOrigin = change.origin; + + if (!last) { signal(doc, "historyAdded"); } + } + + function selectionEventCanBeMerged(doc, origin, prev, sel) { + var ch = origin.charAt(0); + return ch == "*" || + ch == "+" && + prev.ranges.length == sel.ranges.length && + prev.somethingSelected() == sel.somethingSelected() && + new Date - doc.history.lastSelTime <= (doc.cm ? doc.cm.options.historyEventDelay : 500) + } + + // Called whenever the selection changes, sets the new selection as + // the pending selection in the history, and pushes the old pending + // selection into the 'done' array when it was significantly + // different (in number of selected ranges, emptiness, or time). + function addSelectionToHistory(doc, sel, opId, options) { + var hist = doc.history, origin = options && options.origin; + + // A new event is started when the previous origin does not match + // the current, or the origins don't allow matching. Origins + // starting with * are always merged, those starting with + are + // merged when similar and close together in time. + if (opId == hist.lastSelOp || + (origin && hist.lastSelOrigin == origin && + (hist.lastModTime == hist.lastSelTime && hist.lastOrigin == origin || + selectionEventCanBeMerged(doc, origin, lst(hist.done), sel)))) + { hist.done[hist.done.length - 1] = sel; } + else + { pushSelectionToHistory(sel, hist.done); } + + hist.lastSelTime = +new Date; + hist.lastSelOrigin = origin; + hist.lastSelOp = opId; + if (options && options.clearRedo !== false) + { clearSelectionEvents(hist.undone); } + } + + function pushSelectionToHistory(sel, dest) { + var top = lst(dest); + if (!(top && top.ranges && top.equals(sel))) + { dest.push(sel); } + } + + // Used to store marked span information in the history. + function attachLocalSpans(doc, change, from, to) { + var existing = change["spans_" + doc.id], n = 0; + doc.iter(Math.max(doc.first, from), Math.min(doc.first + doc.size, to), function (line) { + if (line.markedSpans) + { (existing || (existing = change["spans_" + doc.id] = {}))[n] = line.markedSpans; } + ++n; + }); + } + + // When un/re-doing restores text containing marked spans, those + // that have been explicitly cleared should not be restored. + function removeClearedSpans(spans) { + if (!spans) { return null } + var out; + for (var i = 0; i < spans.length; ++i) { + if (spans[i].marker.explicitlyCleared) { if (!out) { out = spans.slice(0, i); } } + else if (out) { out.push(spans[i]); } + } + return !out ? spans : out.length ? out : null + } + + // Retrieve and filter the old marked spans stored in a change event. + function getOldSpans(doc, change) { + var found = change["spans_" + doc.id]; + if (!found) { return null } + var nw = []; + for (var i = 0; i < change.text.length; ++i) + { nw.push(removeClearedSpans(found[i])); } + return nw + } + + // Used for un/re-doing changes from the history. Combines the + // result of computing the existing spans with the set of spans that + // existed in the history (so that deleting around a span and then + // undoing brings back the span). + function mergeOldSpans(doc, change) { + var old = getOldSpans(doc, change); + var stretched = stretchSpansOverChange(doc, change); + if (!old) { return stretched } + if (!stretched) { return old } + + for (var i = 0; i < old.length; ++i) { + var oldCur = old[i], stretchCur = stretched[i]; + if (oldCur && stretchCur) { + spans: for (var j = 0; j < stretchCur.length; ++j) { + var span = stretchCur[j]; + for (var k = 0; k < oldCur.length; ++k) + { if (oldCur[k].marker == span.marker) { continue spans } } + oldCur.push(span); + } + } else if (stretchCur) { + old[i] = stretchCur; + } + } + return old + } + + // Used both to provide a JSON-safe object in .getHistory, and, when + // detaching a document, to split the history in two + function copyHistoryArray(events, newGroup, instantiateSel) { + var copy = []; + for (var i = 0; i < events.length; ++i) { + var event = events[i]; + if (event.ranges) { + copy.push(instantiateSel ? Selection.prototype.deepCopy.call(event) : event); + continue + } + var changes = event.changes, newChanges = []; + copy.push({changes: newChanges}); + for (var j = 0; j < changes.length; ++j) { + var change = changes[j], m = (void 0); + newChanges.push({from: change.from, to: change.to, text: change.text}); + if (newGroup) { for (var prop in change) { if (m = prop.match(/^spans_(\d+)$/)) { + if (indexOf(newGroup, Number(m[1])) > -1) { + lst(newChanges)[prop] = change[prop]; + delete change[prop]; + } + } } } + } + } + return copy + } + + // The 'scroll' parameter given to many of these indicated whether + // the new cursor position should be scrolled into view after + // modifying the selection. + + // If shift is held or the extend flag is set, extends a range to + // include a given position (and optionally a second position). + // Otherwise, simply returns the range between the given positions. + // Used for cursor motion and such. + function extendRange(range, head, other, extend) { + if (extend) { + var anchor = range.anchor; + if (other) { + var posBefore = cmp(head, anchor) < 0; + if (posBefore != (cmp(other, anchor) < 0)) { + anchor = head; + head = other; + } else if (posBefore != (cmp(head, other) < 0)) { + head = other; + } + } + return new Range(anchor, head) + } else { + return new Range(other || head, head) + } + } + + // Extend the primary selection range, discard the rest. + function extendSelection(doc, head, other, options, extend) { + if (extend == null) { extend = doc.cm && (doc.cm.display.shift || doc.extend); } + setSelection(doc, new Selection([extendRange(doc.sel.primary(), head, other, extend)], 0), options); + } + + // Extend all selections (pos is an array of selections with length + // equal the number of selections) + function extendSelections(doc, heads, options) { + var out = []; + var extend = doc.cm && (doc.cm.display.shift || doc.extend); + for (var i = 0; i < doc.sel.ranges.length; i++) + { out[i] = extendRange(doc.sel.ranges[i], heads[i], null, extend); } + var newSel = normalizeSelection(doc.cm, out, doc.sel.primIndex); + setSelection(doc, newSel, options); + } + + // Updates a single range in the selection. + function replaceOneSelection(doc, i, range, options) { + var ranges = doc.sel.ranges.slice(0); + ranges[i] = range; + setSelection(doc, normalizeSelection(doc.cm, ranges, doc.sel.primIndex), options); + } + + // Reset the selection to a single range. + function setSimpleSelection(doc, anchor, head, options) { + setSelection(doc, simpleSelection(anchor, head), options); + } + + // Give beforeSelectionChange handlers a change to influence a + // selection update. + function filterSelectionChange(doc, sel, options) { + var obj = { + ranges: sel.ranges, + update: function(ranges) { + this.ranges = []; + for (var i = 0; i < ranges.length; i++) + { this.ranges[i] = new Range(clipPos(doc, ranges[i].anchor), + clipPos(doc, ranges[i].head)); } + }, + origin: options && options.origin + }; + signal(doc, "beforeSelectionChange", doc, obj); + if (doc.cm) { signal(doc.cm, "beforeSelectionChange", doc.cm, obj); } + if (obj.ranges != sel.ranges) { return normalizeSelection(doc.cm, obj.ranges, obj.ranges.length - 1) } + else { return sel } + } + + function setSelectionReplaceHistory(doc, sel, options) { + var done = doc.history.done, last = lst(done); + if (last && last.ranges) { + done[done.length - 1] = sel; + setSelectionNoUndo(doc, sel, options); + } else { + setSelection(doc, sel, options); + } + } + + // Set a new selection. + function setSelection(doc, sel, options) { + setSelectionNoUndo(doc, sel, options); + addSelectionToHistory(doc, doc.sel, doc.cm ? doc.cm.curOp.id : NaN, options); + } + + function setSelectionNoUndo(doc, sel, options) { + if (hasHandler(doc, "beforeSelectionChange") || doc.cm && hasHandler(doc.cm, "beforeSelectionChange")) + { sel = filterSelectionChange(doc, sel, options); } + + var bias = options && options.bias || + (cmp(sel.primary().head, doc.sel.primary().head) < 0 ? -1 : 1); + setSelectionInner(doc, skipAtomicInSelection(doc, sel, bias, true)); + + if (!(options && options.scroll === false) && doc.cm) + { ensureCursorVisible(doc.cm); } + } + + function setSelectionInner(doc, sel) { + if (sel.equals(doc.sel)) { return } + + doc.sel = sel; + + if (doc.cm) { + doc.cm.curOp.updateInput = 1; + doc.cm.curOp.selectionChanged = true; + signalCursorActivity(doc.cm); + } + signalLater(doc, "cursorActivity", doc); + } + + // Verify that the selection does not partially select any atomic + // marked ranges. + function reCheckSelection(doc) { + setSelectionInner(doc, skipAtomicInSelection(doc, doc.sel, null, false)); + } + + // Return a selection that does not partially select any atomic + // ranges. + function skipAtomicInSelection(doc, sel, bias, mayClear) { + var out; + for (var i = 0; i < sel.ranges.length; i++) { + var range = sel.ranges[i]; + var old = sel.ranges.length == doc.sel.ranges.length && doc.sel.ranges[i]; + var newAnchor = skipAtomic(doc, range.anchor, old && old.anchor, bias, mayClear); + var newHead = skipAtomic(doc, range.head, old && old.head, bias, mayClear); + if (out || newAnchor != range.anchor || newHead != range.head) { + if (!out) { out = sel.ranges.slice(0, i); } + out[i] = new Range(newAnchor, newHead); + } + } + return out ? normalizeSelection(doc.cm, out, sel.primIndex) : sel + } + + function skipAtomicInner(doc, pos, oldPos, dir, mayClear) { + var line = getLine(doc, pos.line); + if (line.markedSpans) { for (var i = 0; i < line.markedSpans.length; ++i) { + var sp = line.markedSpans[i], m = sp.marker; + + // Determine if we should prevent the cursor being placed to the left/right of an atomic marker + // Historically this was determined using the inclusiveLeft/Right option, but the new way to control it + // is with selectLeft/Right + var preventCursorLeft = ("selectLeft" in m) ? !m.selectLeft : m.inclusiveLeft; + var preventCursorRight = ("selectRight" in m) ? !m.selectRight : m.inclusiveRight; + + if ((sp.from == null || (preventCursorLeft ? sp.from <= pos.ch : sp.from < pos.ch)) && + (sp.to == null || (preventCursorRight ? sp.to >= pos.ch : sp.to > pos.ch))) { + if (mayClear) { + signal(m, "beforeCursorEnter"); + if (m.explicitlyCleared) { + if (!line.markedSpans) { break } + else {--i; continue} + } + } + if (!m.atomic) { continue } + + if (oldPos) { + var near = m.find(dir < 0 ? 1 : -1), diff = (void 0); + if (dir < 0 ? preventCursorRight : preventCursorLeft) + { near = movePos(doc, near, -dir, near && near.line == pos.line ? line : null); } + if (near && near.line == pos.line && (diff = cmp(near, oldPos)) && (dir < 0 ? diff < 0 : diff > 0)) + { return skipAtomicInner(doc, near, pos, dir, mayClear) } + } + + var far = m.find(dir < 0 ? -1 : 1); + if (dir < 0 ? preventCursorLeft : preventCursorRight) + { far = movePos(doc, far, dir, far.line == pos.line ? line : null); } + return far ? skipAtomicInner(doc, far, pos, dir, mayClear) : null + } + } } + return pos + } + + // Ensure a given position is not inside an atomic range. + function skipAtomic(doc, pos, oldPos, bias, mayClear) { + var dir = bias || 1; + var found = skipAtomicInner(doc, pos, oldPos, dir, mayClear) || + (!mayClear && skipAtomicInner(doc, pos, oldPos, dir, true)) || + skipAtomicInner(doc, pos, oldPos, -dir, mayClear) || + (!mayClear && skipAtomicInner(doc, pos, oldPos, -dir, true)); + if (!found) { + doc.cantEdit = true; + return Pos(doc.first, 0) + } + return found + } + + function movePos(doc, pos, dir, line) { + if (dir < 0 && pos.ch == 0) { + if (pos.line > doc.first) { return clipPos(doc, Pos(pos.line - 1)) } + else { return null } + } else if (dir > 0 && pos.ch == (line || getLine(doc, pos.line)).text.length) { + if (pos.line < doc.first + doc.size - 1) { return Pos(pos.line + 1, 0) } + else { return null } + } else { + return new Pos(pos.line, pos.ch + dir) + } + } + + function selectAll(cm) { + cm.setSelection(Pos(cm.firstLine(), 0), Pos(cm.lastLine()), sel_dontScroll); + } + + // UPDATING + + // Allow "beforeChange" event handlers to influence a change + function filterChange(doc, change, update) { + var obj = { + canceled: false, + from: change.from, + to: change.to, + text: change.text, + origin: change.origin, + cancel: function () { return obj.canceled = true; } + }; + if (update) { obj.update = function (from, to, text, origin) { + if (from) { obj.from = clipPos(doc, from); } + if (to) { obj.to = clipPos(doc, to); } + if (text) { obj.text = text; } + if (origin !== undefined) { obj.origin = origin; } + }; } + signal(doc, "beforeChange", doc, obj); + if (doc.cm) { signal(doc.cm, "beforeChange", doc.cm, obj); } + + if (obj.canceled) { + if (doc.cm) { doc.cm.curOp.updateInput = 2; } + return null + } + return {from: obj.from, to: obj.to, text: obj.text, origin: obj.origin} + } + + // Apply a change to a document, and add it to the document's + // history, and propagating it to all linked documents. + function makeChange(doc, change, ignoreReadOnly) { + if (doc.cm) { + if (!doc.cm.curOp) { return operation(doc.cm, makeChange)(doc, change, ignoreReadOnly) } + if (doc.cm.state.suppressEdits) { return } + } + + if (hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange")) { + change = filterChange(doc, change, true); + if (!change) { return } + } + + // Possibly split or suppress the update based on the presence + // of read-only spans in its range. + var split = sawReadOnlySpans && !ignoreReadOnly && removeReadOnlyRanges(doc, change.from, change.to); + if (split) { + for (var i = split.length - 1; i >= 0; --i) + { makeChangeInner(doc, {from: split[i].from, to: split[i].to, text: i ? [""] : change.text, origin: change.origin}); } + } else { + makeChangeInner(doc, change); + } + } + + function makeChangeInner(doc, change) { + if (change.text.length == 1 && change.text[0] == "" && cmp(change.from, change.to) == 0) { return } + var selAfter = computeSelAfterChange(doc, change); + addChangeToHistory(doc, change, selAfter, doc.cm ? doc.cm.curOp.id : NaN); + + makeChangeSingleDoc(doc, change, selAfter, stretchSpansOverChange(doc, change)); + var rebased = []; + + linkedDocs(doc, function (doc, sharedHist) { + if (!sharedHist && indexOf(rebased, doc.history) == -1) { + rebaseHist(doc.history, change); + rebased.push(doc.history); + } + makeChangeSingleDoc(doc, change, null, stretchSpansOverChange(doc, change)); + }); + } + + // Revert a change stored in a document's history. + function makeChangeFromHistory(doc, type, allowSelectionOnly) { + var suppress = doc.cm && doc.cm.state.suppressEdits; + if (suppress && !allowSelectionOnly) { return } + + var hist = doc.history, event, selAfter = doc.sel; + var source = type == "undo" ? hist.done : hist.undone, dest = type == "undo" ? hist.undone : hist.done; + + // Verify that there is a useable event (so that ctrl-z won't + // needlessly clear selection events) + var i = 0; + for (; i < source.length; i++) { + event = source[i]; + if (allowSelectionOnly ? event.ranges && !event.equals(doc.sel) : !event.ranges) + { break } + } + if (i == source.length) { return } + hist.lastOrigin = hist.lastSelOrigin = null; + + for (;;) { + event = source.pop(); + if (event.ranges) { + pushSelectionToHistory(event, dest); + if (allowSelectionOnly && !event.equals(doc.sel)) { + setSelection(doc, event, {clearRedo: false}); + return + } + selAfter = event; + } else if (suppress) { + source.push(event); + return + } else { break } + } + + // Build up a reverse change object to add to the opposite history + // stack (redo when undoing, and vice versa). + var antiChanges = []; + pushSelectionToHistory(selAfter, dest); + dest.push({changes: antiChanges, generation: hist.generation}); + hist.generation = event.generation || ++hist.maxGeneration; + + var filter = hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange"); + + var loop = function ( i ) { + var change = event.changes[i]; + change.origin = type; + if (filter && !filterChange(doc, change, false)) { + source.length = 0; + return {} + } + + antiChanges.push(historyChangeFromChange(doc, change)); + + var after = i ? computeSelAfterChange(doc, change) : lst(source); + makeChangeSingleDoc(doc, change, after, mergeOldSpans(doc, change)); + if (!i && doc.cm) { doc.cm.scrollIntoView({from: change.from, to: changeEnd(change)}); } + var rebased = []; + + // Propagate to the linked documents + linkedDocs(doc, function (doc, sharedHist) { + if (!sharedHist && indexOf(rebased, doc.history) == -1) { + rebaseHist(doc.history, change); + rebased.push(doc.history); + } + makeChangeSingleDoc(doc, change, null, mergeOldSpans(doc, change)); + }); + }; + + for (var i$1 = event.changes.length - 1; i$1 >= 0; --i$1) { + var returned = loop( i$1 ); + + if ( returned ) return returned.v; + } + } + + // Sub-views need their line numbers shifted when text is added + // above or below them in the parent document. + function shiftDoc(doc, distance) { + if (distance == 0) { return } + doc.first += distance; + doc.sel = new Selection(map(doc.sel.ranges, function (range) { return new Range( + Pos(range.anchor.line + distance, range.anchor.ch), + Pos(range.head.line + distance, range.head.ch) + ); }), doc.sel.primIndex); + if (doc.cm) { + regChange(doc.cm, doc.first, doc.first - distance, distance); + for (var d = doc.cm.display, l = d.viewFrom; l < d.viewTo; l++) + { regLineChange(doc.cm, l, "gutter"); } + } + } + + // More lower-level change function, handling only a single document + // (not linked ones). + function makeChangeSingleDoc(doc, change, selAfter, spans) { + if (doc.cm && !doc.cm.curOp) + { return operation(doc.cm, makeChangeSingleDoc)(doc, change, selAfter, spans) } + + if (change.to.line < doc.first) { + shiftDoc(doc, change.text.length - 1 - (change.to.line - change.from.line)); + return + } + if (change.from.line > doc.lastLine()) { return } + + // Clip the change to the size of this doc + if (change.from.line < doc.first) { + var shift = change.text.length - 1 - (doc.first - change.from.line); + shiftDoc(doc, shift); + change = {from: Pos(doc.first, 0), to: Pos(change.to.line + shift, change.to.ch), + text: [lst(change.text)], origin: change.origin}; + } + var last = doc.lastLine(); + if (change.to.line > last) { + change = {from: change.from, to: Pos(last, getLine(doc, last).text.length), + text: [change.text[0]], origin: change.origin}; + } + + change.removed = getBetween(doc, change.from, change.to); + + if (!selAfter) { selAfter = computeSelAfterChange(doc, change); } + if (doc.cm) { makeChangeSingleDocInEditor(doc.cm, change, spans); } + else { updateDoc(doc, change, spans); } + setSelectionNoUndo(doc, selAfter, sel_dontScroll); + + if (doc.cantEdit && skipAtomic(doc, Pos(doc.firstLine(), 0))) + { doc.cantEdit = false; } + } + + // Handle the interaction of a change to a document with the editor + // that this document is part of. + function makeChangeSingleDocInEditor(cm, change, spans) { + var doc = cm.doc, display = cm.display, from = change.from, to = change.to; + + var recomputeMaxLength = false, checkWidthStart = from.line; + if (!cm.options.lineWrapping) { + checkWidthStart = lineNo(visualLine(getLine(doc, from.line))); + doc.iter(checkWidthStart, to.line + 1, function (line) { + if (line == display.maxLine) { + recomputeMaxLength = true; + return true + } + }); + } + + if (doc.sel.contains(change.from, change.to) > -1) + { signalCursorActivity(cm); } + + updateDoc(doc, change, spans, estimateHeight(cm)); + + if (!cm.options.lineWrapping) { + doc.iter(checkWidthStart, from.line + change.text.length, function (line) { + var len = lineLength(line); + if (len > display.maxLineLength) { + display.maxLine = line; + display.maxLineLength = len; + display.maxLineChanged = true; + recomputeMaxLength = false; + } + }); + if (recomputeMaxLength) { cm.curOp.updateMaxLine = true; } + } + + retreatFrontier(doc, from.line); + startWorker(cm, 400); + + var lendiff = change.text.length - (to.line - from.line) - 1; + // Remember that these lines changed, for updating the display + if (change.full) + { regChange(cm); } + else if (from.line == to.line && change.text.length == 1 && !isWholeLineUpdate(cm.doc, change)) + { regLineChange(cm, from.line, "text"); } + else + { regChange(cm, from.line, to.line + 1, lendiff); } + + var changesHandler = hasHandler(cm, "changes"), changeHandler = hasHandler(cm, "change"); + if (changeHandler || changesHandler) { + var obj = { + from: from, to: to, + text: change.text, + removed: change.removed, + origin: change.origin + }; + if (changeHandler) { signalLater(cm, "change", cm, obj); } + if (changesHandler) { (cm.curOp.changeObjs || (cm.curOp.changeObjs = [])).push(obj); } + } + cm.display.selForContextMenu = null; + } + + function replaceRange(doc, code, from, to, origin) { + var assign; + + if (!to) { to = from; } + if (cmp(to, from) < 0) { (assign = [to, from], from = assign[0], to = assign[1]); } + if (typeof code == "string") { code = doc.splitLines(code); } + makeChange(doc, {from: from, to: to, text: code, origin: origin}); + } + + // Rebasing/resetting history to deal with externally-sourced changes + + function rebaseHistSelSingle(pos, from, to, diff) { + if (to < pos.line) { + pos.line += diff; + } else if (from < pos.line) { + pos.line = from; + pos.ch = 0; + } + } + + // Tries to rebase an array of history events given a change in the + // document. If the change touches the same lines as the event, the + // event, and everything 'behind' it, is discarded. If the change is + // before the event, the event's positions are updated. Uses a + // copy-on-write scheme for the positions, to avoid having to + // reallocate them all on every rebase, but also avoid problems with + // shared position objects being unsafely updated. + function rebaseHistArray(array, from, to, diff) { + for (var i = 0; i < array.length; ++i) { + var sub = array[i], ok = true; + if (sub.ranges) { + if (!sub.copied) { sub = array[i] = sub.deepCopy(); sub.copied = true; } + for (var j = 0; j < sub.ranges.length; j++) { + rebaseHistSelSingle(sub.ranges[j].anchor, from, to, diff); + rebaseHistSelSingle(sub.ranges[j].head, from, to, diff); + } + continue + } + for (var j$1 = 0; j$1 < sub.changes.length; ++j$1) { + var cur = sub.changes[j$1]; + if (to < cur.from.line) { + cur.from = Pos(cur.from.line + diff, cur.from.ch); + cur.to = Pos(cur.to.line + diff, cur.to.ch); + } else if (from <= cur.to.line) { + ok = false; + break + } + } + if (!ok) { + array.splice(0, i + 1); + i = 0; + } + } + } + + function rebaseHist(hist, change) { + var from = change.from.line, to = change.to.line, diff = change.text.length - (to - from) - 1; + rebaseHistArray(hist.done, from, to, diff); + rebaseHistArray(hist.undone, from, to, diff); + } + + // Utility for applying a change to a line by handle or number, + // returning the number and optionally registering the line as + // changed. + function changeLine(doc, handle, changeType, op) { + var no = handle, line = handle; + if (typeof handle == "number") { line = getLine(doc, clipLine(doc, handle)); } + else { no = lineNo(handle); } + if (no == null) { return null } + if (op(line, no) && doc.cm) { regLineChange(doc.cm, no, changeType); } + return line + } + + // The document is represented as a BTree consisting of leaves, with + // chunk of lines in them, and branches, with up to ten leaves or + // other branch nodes below them. The top node is always a branch + // node, and is the document object itself (meaning it has + // additional methods and properties). + // + // All nodes have parent links. The tree is used both to go from + // line numbers to line objects, and to go from objects to numbers. + // It also indexes by height, and is used to convert between height + // and line object, and to find the total height of the document. + // + // See also http://marijnhaverbeke.nl/blog/codemirror-line-tree.html + + function LeafChunk(lines) { + this.lines = lines; + this.parent = null; + var height = 0; + for (var i = 0; i < lines.length; ++i) { + lines[i].parent = this; + height += lines[i].height; + } + this.height = height; + } + + LeafChunk.prototype = { + chunkSize: function() { return this.lines.length }, + + // Remove the n lines at offset 'at'. + removeInner: function(at, n) { + for (var i = at, e = at + n; i < e; ++i) { + var line = this.lines[i]; + this.height -= line.height; + cleanUpLine(line); + signalLater(line, "delete"); + } + this.lines.splice(at, n); + }, + + // Helper used to collapse a small branch into a single leaf. + collapse: function(lines) { + lines.push.apply(lines, this.lines); + }, + + // Insert the given array of lines at offset 'at', count them as + // having the given height. + insertInner: function(at, lines, height) { + this.height += height; + this.lines = this.lines.slice(0, at).concat(lines).concat(this.lines.slice(at)); + for (var i = 0; i < lines.length; ++i) { lines[i].parent = this; } + }, + + // Used to iterate over a part of the tree. + iterN: function(at, n, op) { + for (var e = at + n; at < e; ++at) + { if (op(this.lines[at])) { return true } } + } + }; + + function BranchChunk(children) { + this.children = children; + var size = 0, height = 0; + for (var i = 0; i < children.length; ++i) { + var ch = children[i]; + size += ch.chunkSize(); height += ch.height; + ch.parent = this; + } + this.size = size; + this.height = height; + this.parent = null; + } + + BranchChunk.prototype = { + chunkSize: function() { return this.size }, + + removeInner: function(at, n) { + this.size -= n; + for (var i = 0; i < this.children.length; ++i) { + var child = this.children[i], sz = child.chunkSize(); + if (at < sz) { + var rm = Math.min(n, sz - at), oldHeight = child.height; + child.removeInner(at, rm); + this.height -= oldHeight - child.height; + if (sz == rm) { this.children.splice(i--, 1); child.parent = null; } + if ((n -= rm) == 0) { break } + at = 0; + } else { at -= sz; } + } + // If the result is smaller than 25 lines, ensure that it is a + // single leaf node. + if (this.size - n < 25 && + (this.children.length > 1 || !(this.children[0] instanceof LeafChunk))) { + var lines = []; + this.collapse(lines); + this.children = [new LeafChunk(lines)]; + this.children[0].parent = this; + } + }, + + collapse: function(lines) { + for (var i = 0; i < this.children.length; ++i) { this.children[i].collapse(lines); } + }, + + insertInner: function(at, lines, height) { + this.size += lines.length; + this.height += height; + for (var i = 0; i < this.children.length; ++i) { + var child = this.children[i], sz = child.chunkSize(); + if (at <= sz) { + child.insertInner(at, lines, height); + if (child.lines && child.lines.length > 50) { + // To avoid memory thrashing when child.lines is huge (e.g. first view of a large file), it's never spliced. + // Instead, small slices are taken. They're taken in order because sequential memory accesses are fastest. + var remaining = child.lines.length % 25 + 25; + for (var pos = remaining; pos < child.lines.length;) { + var leaf = new LeafChunk(child.lines.slice(pos, pos += 25)); + child.height -= leaf.height; + this.children.splice(++i, 0, leaf); + leaf.parent = this; + } + child.lines = child.lines.slice(0, remaining); + this.maybeSpill(); + } + break + } + at -= sz; + } + }, + + // When a node has grown, check whether it should be split. + maybeSpill: function() { + if (this.children.length <= 10) { return } + var me = this; + do { + var spilled = me.children.splice(me.children.length - 5, 5); + var sibling = new BranchChunk(spilled); + if (!me.parent) { // Become the parent node + var copy = new BranchChunk(me.children); + copy.parent = me; + me.children = [copy, sibling]; + me = copy; + } else { + me.size -= sibling.size; + me.height -= sibling.height; + var myIndex = indexOf(me.parent.children, me); + me.parent.children.splice(myIndex + 1, 0, sibling); + } + sibling.parent = me.parent; + } while (me.children.length > 10) + me.parent.maybeSpill(); + }, + + iterN: function(at, n, op) { + for (var i = 0; i < this.children.length; ++i) { + var child = this.children[i], sz = child.chunkSize(); + if (at < sz) { + var used = Math.min(n, sz - at); + if (child.iterN(at, used, op)) { return true } + if ((n -= used) == 0) { break } + at = 0; + } else { at -= sz; } + } + } + }; + + // Line widgets are block elements displayed above or below a line. + + var LineWidget = function(doc, node, options) { + if (options) { for (var opt in options) { if (options.hasOwnProperty(opt)) + { this[opt] = options[opt]; } } } + this.doc = doc; + this.node = node; + }; + + LineWidget.prototype.clear = function () { + var cm = this.doc.cm, ws = this.line.widgets, line = this.line, no = lineNo(line); + if (no == null || !ws) { return } + for (var i = 0; i < ws.length; ++i) { if (ws[i] == this) { ws.splice(i--, 1); } } + if (!ws.length) { line.widgets = null; } + var height = widgetHeight(this); + updateLineHeight(line, Math.max(0, line.height - height)); + if (cm) { + runInOp(cm, function () { + adjustScrollWhenAboveVisible(cm, line, -height); + regLineChange(cm, no, "widget"); + }); + signalLater(cm, "lineWidgetCleared", cm, this, no); + } + }; + + LineWidget.prototype.changed = function () { + var this$1 = this; + + var oldH = this.height, cm = this.doc.cm, line = this.line; + this.height = null; + var diff = widgetHeight(this) - oldH; + if (!diff) { return } + if (!lineIsHidden(this.doc, line)) { updateLineHeight(line, line.height + diff); } + if (cm) { + runInOp(cm, function () { + cm.curOp.forceUpdate = true; + adjustScrollWhenAboveVisible(cm, line, diff); + signalLater(cm, "lineWidgetChanged", cm, this$1, lineNo(line)); + }); + } + }; + eventMixin(LineWidget); + + function adjustScrollWhenAboveVisible(cm, line, diff) { + if (heightAtLine(line) < ((cm.curOp && cm.curOp.scrollTop) || cm.doc.scrollTop)) + { addToScrollTop(cm, diff); } + } + + function addLineWidget(doc, handle, node, options) { + var widget = new LineWidget(doc, node, options); + var cm = doc.cm; + if (cm && widget.noHScroll) { cm.display.alignWidgets = true; } + changeLine(doc, handle, "widget", function (line) { + var widgets = line.widgets || (line.widgets = []); + if (widget.insertAt == null) { widgets.push(widget); } + else { widgets.splice(Math.min(widgets.length - 1, Math.max(0, widget.insertAt)), 0, widget); } + widget.line = line; + if (cm && !lineIsHidden(doc, line)) { + var aboveVisible = heightAtLine(line) < doc.scrollTop; + updateLineHeight(line, line.height + widgetHeight(widget)); + if (aboveVisible) { addToScrollTop(cm, widget.height); } + cm.curOp.forceUpdate = true; + } + return true + }); + if (cm) { signalLater(cm, "lineWidgetAdded", cm, widget, typeof handle == "number" ? handle : lineNo(handle)); } + return widget + } + + // TEXTMARKERS + + // Created with markText and setBookmark methods. A TextMarker is a + // handle that can be used to clear or find a marked position in the + // document. Line objects hold arrays (markedSpans) containing + // {from, to, marker} object pointing to such marker objects, and + // indicating that such a marker is present on that line. Multiple + // lines may point to the same marker when it spans across lines. + // The spans will have null for their from/to properties when the + // marker continues beyond the start/end of the line. Markers have + // links back to the lines they currently touch. + + // Collapsed markers have unique ids, in order to be able to order + // them, which is needed for uniquely determining an outer marker + // when they overlap (they may nest, but not partially overlap). + var nextMarkerId = 0; + + var TextMarker = function(doc, type) { + this.lines = []; + this.type = type; + this.doc = doc; + this.id = ++nextMarkerId; + }; + + // Clear the marker. + TextMarker.prototype.clear = function () { + if (this.explicitlyCleared) { return } + var cm = this.doc.cm, withOp = cm && !cm.curOp; + if (withOp) { startOperation(cm); } + if (hasHandler(this, "clear")) { + var found = this.find(); + if (found) { signalLater(this, "clear", found.from, found.to); } + } + var min = null, max = null; + for (var i = 0; i < this.lines.length; ++i) { + var line = this.lines[i]; + var span = getMarkedSpanFor(line.markedSpans, this); + if (cm && !this.collapsed) { regLineChange(cm, lineNo(line), "text"); } + else if (cm) { + if (span.to != null) { max = lineNo(line); } + if (span.from != null) { min = lineNo(line); } + } + line.markedSpans = removeMarkedSpan(line.markedSpans, span); + if (span.from == null && this.collapsed && !lineIsHidden(this.doc, line) && cm) + { updateLineHeight(line, textHeight(cm.display)); } + } + if (cm && this.collapsed && !cm.options.lineWrapping) { for (var i$1 = 0; i$1 < this.lines.length; ++i$1) { + var visual = visualLine(this.lines[i$1]), len = lineLength(visual); + if (len > cm.display.maxLineLength) { + cm.display.maxLine = visual; + cm.display.maxLineLength = len; + cm.display.maxLineChanged = true; + } + } } + + if (min != null && cm && this.collapsed) { regChange(cm, min, max + 1); } + this.lines.length = 0; + this.explicitlyCleared = true; + if (this.atomic && this.doc.cantEdit) { + this.doc.cantEdit = false; + if (cm) { reCheckSelection(cm.doc); } + } + if (cm) { signalLater(cm, "markerCleared", cm, this, min, max); } + if (withOp) { endOperation(cm); } + if (this.parent) { this.parent.clear(); } + }; + + // Find the position of the marker in the document. Returns a {from, + // to} object by default. Side can be passed to get a specific side + // -- 0 (both), -1 (left), or 1 (right). When lineObj is true, the + // Pos objects returned contain a line object, rather than a line + // number (used to prevent looking up the same line twice). + TextMarker.prototype.find = function (side, lineObj) { + if (side == null && this.type == "bookmark") { side = 1; } + var from, to; + for (var i = 0; i < this.lines.length; ++i) { + var line = this.lines[i]; + var span = getMarkedSpanFor(line.markedSpans, this); + if (span.from != null) { + from = Pos(lineObj ? line : lineNo(line), span.from); + if (side == -1) { return from } + } + if (span.to != null) { + to = Pos(lineObj ? line : lineNo(line), span.to); + if (side == 1) { return to } + } + } + return from && {from: from, to: to} + }; + + // Signals that the marker's widget changed, and surrounding layout + // should be recomputed. + TextMarker.prototype.changed = function () { + var this$1 = this; + + var pos = this.find(-1, true), widget = this, cm = this.doc.cm; + if (!pos || !cm) { return } + runInOp(cm, function () { + var line = pos.line, lineN = lineNo(pos.line); + var view = findViewForLine(cm, lineN); + if (view) { + clearLineMeasurementCacheFor(view); + cm.curOp.selectionChanged = cm.curOp.forceUpdate = true; + } + cm.curOp.updateMaxLine = true; + if (!lineIsHidden(widget.doc, line) && widget.height != null) { + var oldHeight = widget.height; + widget.height = null; + var dHeight = widgetHeight(widget) - oldHeight; + if (dHeight) + { updateLineHeight(line, line.height + dHeight); } + } + signalLater(cm, "markerChanged", cm, this$1); + }); + }; + + TextMarker.prototype.attachLine = function (line) { + if (!this.lines.length && this.doc.cm) { + var op = this.doc.cm.curOp; + if (!op.maybeHiddenMarkers || indexOf(op.maybeHiddenMarkers, this) == -1) + { (op.maybeUnhiddenMarkers || (op.maybeUnhiddenMarkers = [])).push(this); } + } + this.lines.push(line); + }; + + TextMarker.prototype.detachLine = function (line) { + this.lines.splice(indexOf(this.lines, line), 1); + if (!this.lines.length && this.doc.cm) { + var op = this.doc.cm.curOp + ;(op.maybeHiddenMarkers || (op.maybeHiddenMarkers = [])).push(this); + } + }; + eventMixin(TextMarker); + + // Create a marker, wire it up to the right lines, and + function markText(doc, from, to, options, type) { + // Shared markers (across linked documents) are handled separately + // (markTextShared will call out to this again, once per + // document). + if (options && options.shared) { return markTextShared(doc, from, to, options, type) } + // Ensure we are in an operation. + if (doc.cm && !doc.cm.curOp) { return operation(doc.cm, markText)(doc, from, to, options, type) } + + var marker = new TextMarker(doc, type), diff = cmp(from, to); + if (options) { copyObj(options, marker, false); } + // Don't connect empty markers unless clearWhenEmpty is false + if (diff > 0 || diff == 0 && marker.clearWhenEmpty !== false) + { return marker } + if (marker.replacedWith) { + // Showing up as a widget implies collapsed (widget replaces text) + marker.collapsed = true; + marker.widgetNode = eltP("span", [marker.replacedWith], "CodeMirror-widget"); + if (!options.handleMouseEvents) { marker.widgetNode.setAttribute("cm-ignore-events", "true"); } + if (options.insertLeft) { marker.widgetNode.insertLeft = true; } + } + if (marker.collapsed) { + if (conflictingCollapsedRange(doc, from.line, from, to, marker) || + from.line != to.line && conflictingCollapsedRange(doc, to.line, from, to, marker)) + { throw new Error("Inserting collapsed marker partially overlapping an existing one") } + seeCollapsedSpans(); + } + + if (marker.addToHistory) + { addChangeToHistory(doc, {from: from, to: to, origin: "markText"}, doc.sel, NaN); } + + var curLine = from.line, cm = doc.cm, updateMaxLine; + doc.iter(curLine, to.line + 1, function (line) { + if (cm && marker.collapsed && !cm.options.lineWrapping && visualLine(line) == cm.display.maxLine) + { updateMaxLine = true; } + if (marker.collapsed && curLine != from.line) { updateLineHeight(line, 0); } + addMarkedSpan(line, new MarkedSpan(marker, + curLine == from.line ? from.ch : null, + curLine == to.line ? to.ch : null)); + ++curLine; + }); + // lineIsHidden depends on the presence of the spans, so needs a second pass + if (marker.collapsed) { doc.iter(from.line, to.line + 1, function (line) { + if (lineIsHidden(doc, line)) { updateLineHeight(line, 0); } + }); } + + if (marker.clearOnEnter) { on(marker, "beforeCursorEnter", function () { return marker.clear(); }); } + + if (marker.readOnly) { + seeReadOnlySpans(); + if (doc.history.done.length || doc.history.undone.length) + { doc.clearHistory(); } + } + if (marker.collapsed) { + marker.id = ++nextMarkerId; + marker.atomic = true; + } + if (cm) { + // Sync editor state + if (updateMaxLine) { cm.curOp.updateMaxLine = true; } + if (marker.collapsed) + { regChange(cm, from.line, to.line + 1); } + else if (marker.className || marker.startStyle || marker.endStyle || marker.css || + marker.attributes || marker.title) + { for (var i = from.line; i <= to.line; i++) { regLineChange(cm, i, "text"); } } + if (marker.atomic) { reCheckSelection(cm.doc); } + signalLater(cm, "markerAdded", cm, marker); + } + return marker + } + + // SHARED TEXTMARKERS + + // A shared marker spans multiple linked documents. It is + // implemented as a meta-marker-object controlling multiple normal + // markers. + var SharedTextMarker = function(markers, primary) { + this.markers = markers; + this.primary = primary; + for (var i = 0; i < markers.length; ++i) + { markers[i].parent = this; } + }; + + SharedTextMarker.prototype.clear = function () { + if (this.explicitlyCleared) { return } + this.explicitlyCleared = true; + for (var i = 0; i < this.markers.length; ++i) + { this.markers[i].clear(); } + signalLater(this, "clear"); + }; + + SharedTextMarker.prototype.find = function (side, lineObj) { + return this.primary.find(side, lineObj) + }; + eventMixin(SharedTextMarker); + + function markTextShared(doc, from, to, options, type) { + options = copyObj(options); + options.shared = false; + var markers = [markText(doc, from, to, options, type)], primary = markers[0]; + var widget = options.widgetNode; + linkedDocs(doc, function (doc) { + if (widget) { options.widgetNode = widget.cloneNode(true); } + markers.push(markText(doc, clipPos(doc, from), clipPos(doc, to), options, type)); + for (var i = 0; i < doc.linked.length; ++i) + { if (doc.linked[i].isParent) { return } } + primary = lst(markers); + }); + return new SharedTextMarker(markers, primary) + } + + function findSharedMarkers(doc) { + return doc.findMarks(Pos(doc.first, 0), doc.clipPos(Pos(doc.lastLine())), function (m) { return m.parent; }) + } + + function copySharedMarkers(doc, markers) { + for (var i = 0; i < markers.length; i++) { + var marker = markers[i], pos = marker.find(); + var mFrom = doc.clipPos(pos.from), mTo = doc.clipPos(pos.to); + if (cmp(mFrom, mTo)) { + var subMark = markText(doc, mFrom, mTo, marker.primary, marker.primary.type); + marker.markers.push(subMark); + subMark.parent = marker; + } + } + } + + function detachSharedMarkers(markers) { + var loop = function ( i ) { + var marker = markers[i], linked = [marker.primary.doc]; + linkedDocs(marker.primary.doc, function (d) { return linked.push(d); }); + for (var j = 0; j < marker.markers.length; j++) { + var subMarker = marker.markers[j]; + if (indexOf(linked, subMarker.doc) == -1) { + subMarker.parent = null; + marker.markers.splice(j--, 1); + } + } + }; + + for (var i = 0; i < markers.length; i++) loop( i ); + } + + var nextDocId = 0; + var Doc = function(text, mode, firstLine, lineSep, direction) { + if (!(this instanceof Doc)) { return new Doc(text, mode, firstLine, lineSep, direction) } + if (firstLine == null) { firstLine = 0; } + + BranchChunk.call(this, [new LeafChunk([new Line("", null)])]); + this.first = firstLine; + this.scrollTop = this.scrollLeft = 0; + this.cantEdit = false; + this.cleanGeneration = 1; + this.modeFrontier = this.highlightFrontier = firstLine; + var start = Pos(firstLine, 0); + this.sel = simpleSelection(start); + this.history = new History(null); + this.id = ++nextDocId; + this.modeOption = mode; + this.lineSep = lineSep; + this.direction = (direction == "rtl") ? "rtl" : "ltr"; + this.extend = false; + + if (typeof text == "string") { text = this.splitLines(text); } + updateDoc(this, {from: start, to: start, text: text}); + setSelection(this, simpleSelection(start), sel_dontScroll); + }; + + Doc.prototype = createObj(BranchChunk.prototype, { + constructor: Doc, + // Iterate over the document. Supports two forms -- with only one + // argument, it calls that for each line in the document. With + // three, it iterates over the range given by the first two (with + // the second being non-inclusive). + iter: function(from, to, op) { + if (op) { this.iterN(from - this.first, to - from, op); } + else { this.iterN(this.first, this.first + this.size, from); } + }, + + // Non-public interface for adding and removing lines. + insert: function(at, lines) { + var height = 0; + for (var i = 0; i < lines.length; ++i) { height += lines[i].height; } + this.insertInner(at - this.first, lines, height); + }, + remove: function(at, n) { this.removeInner(at - this.first, n); }, + + // From here, the methods are part of the public interface. Most + // are also available from CodeMirror (editor) instances. + + getValue: function(lineSep) { + var lines = getLines(this, this.first, this.first + this.size); + if (lineSep === false) { return lines } + return lines.join(lineSep || this.lineSeparator()) + }, + setValue: docMethodOp(function(code) { + var top = Pos(this.first, 0), last = this.first + this.size - 1; + makeChange(this, {from: top, to: Pos(last, getLine(this, last).text.length), + text: this.splitLines(code), origin: "setValue", full: true}, true); + if (this.cm) { scrollToCoords(this.cm, 0, 0); } + setSelection(this, simpleSelection(top), sel_dontScroll); + }), + replaceRange: function(code, from, to, origin) { + from = clipPos(this, from); + to = to ? clipPos(this, to) : from; + replaceRange(this, code, from, to, origin); + }, + getRange: function(from, to, lineSep) { + var lines = getBetween(this, clipPos(this, from), clipPos(this, to)); + if (lineSep === false) { return lines } + return lines.join(lineSep || this.lineSeparator()) + }, + + getLine: function(line) {var l = this.getLineHandle(line); return l && l.text}, + + getLineHandle: function(line) {if (isLine(this, line)) { return getLine(this, line) }}, + getLineNumber: function(line) {return lineNo(line)}, + + getLineHandleVisualStart: function(line) { + if (typeof line == "number") { line = getLine(this, line); } + return visualLine(line) + }, + + lineCount: function() {return this.size}, + firstLine: function() {return this.first}, + lastLine: function() {return this.first + this.size - 1}, + + clipPos: function(pos) {return clipPos(this, pos)}, + + getCursor: function(start) { + var range = this.sel.primary(), pos; + if (start == null || start == "head") { pos = range.head; } + else if (start == "anchor") { pos = range.anchor; } + else if (start == "end" || start == "to" || start === false) { pos = range.to(); } + else { pos = range.from(); } + return pos + }, + listSelections: function() { return this.sel.ranges }, + somethingSelected: function() {return this.sel.somethingSelected()}, + + setCursor: docMethodOp(function(line, ch, options) { + setSimpleSelection(this, clipPos(this, typeof line == "number" ? Pos(line, ch || 0) : line), null, options); + }), + setSelection: docMethodOp(function(anchor, head, options) { + setSimpleSelection(this, clipPos(this, anchor), clipPos(this, head || anchor), options); + }), + extendSelection: docMethodOp(function(head, other, options) { + extendSelection(this, clipPos(this, head), other && clipPos(this, other), options); + }), + extendSelections: docMethodOp(function(heads, options) { + extendSelections(this, clipPosArray(this, heads), options); + }), + extendSelectionsBy: docMethodOp(function(f, options) { + var heads = map(this.sel.ranges, f); + extendSelections(this, clipPosArray(this, heads), options); + }), + setSelections: docMethodOp(function(ranges, primary, options) { + if (!ranges.length) { return } + var out = []; + for (var i = 0; i < ranges.length; i++) + { out[i] = new Range(clipPos(this, ranges[i].anchor), + clipPos(this, ranges[i].head)); } + if (primary == null) { primary = Math.min(ranges.length - 1, this.sel.primIndex); } + setSelection(this, normalizeSelection(this.cm, out, primary), options); + }), + addSelection: docMethodOp(function(anchor, head, options) { + var ranges = this.sel.ranges.slice(0); + ranges.push(new Range(clipPos(this, anchor), clipPos(this, head || anchor))); + setSelection(this, normalizeSelection(this.cm, ranges, ranges.length - 1), options); + }), + + getSelection: function(lineSep) { + var ranges = this.sel.ranges, lines; + for (var i = 0; i < ranges.length; i++) { + var sel = getBetween(this, ranges[i].from(), ranges[i].to()); + lines = lines ? lines.concat(sel) : sel; + } + if (lineSep === false) { return lines } + else { return lines.join(lineSep || this.lineSeparator()) } + }, + getSelections: function(lineSep) { + var parts = [], ranges = this.sel.ranges; + for (var i = 0; i < ranges.length; i++) { + var sel = getBetween(this, ranges[i].from(), ranges[i].to()); + if (lineSep !== false) { sel = sel.join(lineSep || this.lineSeparator()); } + parts[i] = sel; + } + return parts + }, + replaceSelection: function(code, collapse, origin) { + var dup = []; + for (var i = 0; i < this.sel.ranges.length; i++) + { dup[i] = code; } + this.replaceSelections(dup, collapse, origin || "+input"); + }, + replaceSelections: docMethodOp(function(code, collapse, origin) { + var changes = [], sel = this.sel; + for (var i = 0; i < sel.ranges.length; i++) { + var range = sel.ranges[i]; + changes[i] = {from: range.from(), to: range.to(), text: this.splitLines(code[i]), origin: origin}; + } + var newSel = collapse && collapse != "end" && computeReplacedSel(this, changes, collapse); + for (var i$1 = changes.length - 1; i$1 >= 0; i$1--) + { makeChange(this, changes[i$1]); } + if (newSel) { setSelectionReplaceHistory(this, newSel); } + else if (this.cm) { ensureCursorVisible(this.cm); } + }), + undo: docMethodOp(function() {makeChangeFromHistory(this, "undo");}), + redo: docMethodOp(function() {makeChangeFromHistory(this, "redo");}), + undoSelection: docMethodOp(function() {makeChangeFromHistory(this, "undo", true);}), + redoSelection: docMethodOp(function() {makeChangeFromHistory(this, "redo", true);}), + + setExtending: function(val) {this.extend = val;}, + getExtending: function() {return this.extend}, + + historySize: function() { + var hist = this.history, done = 0, undone = 0; + for (var i = 0; i < hist.done.length; i++) { if (!hist.done[i].ranges) { ++done; } } + for (var i$1 = 0; i$1 < hist.undone.length; i$1++) { if (!hist.undone[i$1].ranges) { ++undone; } } + return {undo: done, redo: undone} + }, + clearHistory: function() { + var this$1 = this; + + this.history = new History(this.history.maxGeneration); + linkedDocs(this, function (doc) { return doc.history = this$1.history; }, true); + }, + + markClean: function() { + this.cleanGeneration = this.changeGeneration(true); + }, + changeGeneration: function(forceSplit) { + if (forceSplit) + { this.history.lastOp = this.history.lastSelOp = this.history.lastOrigin = null; } + return this.history.generation + }, + isClean: function (gen) { + return this.history.generation == (gen || this.cleanGeneration) + }, + + getHistory: function() { + return {done: copyHistoryArray(this.history.done), + undone: copyHistoryArray(this.history.undone)} + }, + setHistory: function(histData) { + var hist = this.history = new History(this.history.maxGeneration); + hist.done = copyHistoryArray(histData.done.slice(0), null, true); + hist.undone = copyHistoryArray(histData.undone.slice(0), null, true); + }, + + setGutterMarker: docMethodOp(function(line, gutterID, value) { + return changeLine(this, line, "gutter", function (line) { + var markers = line.gutterMarkers || (line.gutterMarkers = {}); + markers[gutterID] = value; + if (!value && isEmpty(markers)) { line.gutterMarkers = null; } + return true + }) + }), + + clearGutter: docMethodOp(function(gutterID) { + var this$1 = this; + + this.iter(function (line) { + if (line.gutterMarkers && line.gutterMarkers[gutterID]) { + changeLine(this$1, line, "gutter", function () { + line.gutterMarkers[gutterID] = null; + if (isEmpty(line.gutterMarkers)) { line.gutterMarkers = null; } + return true + }); + } + }); + }), + + lineInfo: function(line) { + var n; + if (typeof line == "number") { + if (!isLine(this, line)) { return null } + n = line; + line = getLine(this, line); + if (!line) { return null } + } else { + n = lineNo(line); + if (n == null) { return null } + } + return {line: n, handle: line, text: line.text, gutterMarkers: line.gutterMarkers, + textClass: line.textClass, bgClass: line.bgClass, wrapClass: line.wrapClass, + widgets: line.widgets} + }, + + addLineClass: docMethodOp(function(handle, where, cls) { + return changeLine(this, handle, where == "gutter" ? "gutter" : "class", function (line) { + var prop = where == "text" ? "textClass" + : where == "background" ? "bgClass" + : where == "gutter" ? "gutterClass" : "wrapClass"; + if (!line[prop]) { line[prop] = cls; } + else if (classTest(cls).test(line[prop])) { return false } + else { line[prop] += " " + cls; } + return true + }) + }), + removeLineClass: docMethodOp(function(handle, where, cls) { + return changeLine(this, handle, where == "gutter" ? "gutter" : "class", function (line) { + var prop = where == "text" ? "textClass" + : where == "background" ? "bgClass" + : where == "gutter" ? "gutterClass" : "wrapClass"; + var cur = line[prop]; + if (!cur) { return false } + else if (cls == null) { line[prop] = null; } + else { + var found = cur.match(classTest(cls)); + if (!found) { return false } + var end = found.index + found[0].length; + line[prop] = cur.slice(0, found.index) + (!found.index || end == cur.length ? "" : " ") + cur.slice(end) || null; + } + return true + }) + }), + + addLineWidget: docMethodOp(function(handle, node, options) { + return addLineWidget(this, handle, node, options) + }), + removeLineWidget: function(widget) { widget.clear(); }, + + markText: function(from, to, options) { + return markText(this, clipPos(this, from), clipPos(this, to), options, options && options.type || "range") + }, + setBookmark: function(pos, options) { + var realOpts = {replacedWith: options && (options.nodeType == null ? options.widget : options), + insertLeft: options && options.insertLeft, + clearWhenEmpty: false, shared: options && options.shared, + handleMouseEvents: options && options.handleMouseEvents}; + pos = clipPos(this, pos); + return markText(this, pos, pos, realOpts, "bookmark") + }, + findMarksAt: function(pos) { + pos = clipPos(this, pos); + var markers = [], spans = getLine(this, pos.line).markedSpans; + if (spans) { for (var i = 0; i < spans.length; ++i) { + var span = spans[i]; + if ((span.from == null || span.from <= pos.ch) && + (span.to == null || span.to >= pos.ch)) + { markers.push(span.marker.parent || span.marker); } + } } + return markers + }, + findMarks: function(from, to, filter) { + from = clipPos(this, from); to = clipPos(this, to); + var found = [], lineNo = from.line; + this.iter(from.line, to.line + 1, function (line) { + var spans = line.markedSpans; + if (spans) { for (var i = 0; i < spans.length; i++) { + var span = spans[i]; + if (!(span.to != null && lineNo == from.line && from.ch >= span.to || + span.from == null && lineNo != from.line || + span.from != null && lineNo == to.line && span.from >= to.ch) && + (!filter || filter(span.marker))) + { found.push(span.marker.parent || span.marker); } + } } + ++lineNo; + }); + return found + }, + getAllMarks: function() { + var markers = []; + this.iter(function (line) { + var sps = line.markedSpans; + if (sps) { for (var i = 0; i < sps.length; ++i) + { if (sps[i].from != null) { markers.push(sps[i].marker); } } } + }); + return markers + }, + + posFromIndex: function(off) { + var ch, lineNo = this.first, sepSize = this.lineSeparator().length; + this.iter(function (line) { + var sz = line.text.length + sepSize; + if (sz > off) { ch = off; return true } + off -= sz; + ++lineNo; + }); + return clipPos(this, Pos(lineNo, ch)) + }, + indexFromPos: function (coords) { + coords = clipPos(this, coords); + var index = coords.ch; + if (coords.line < this.first || coords.ch < 0) { return 0 } + var sepSize = this.lineSeparator().length; + this.iter(this.first, coords.line, function (line) { // iter aborts when callback returns a truthy value + index += line.text.length + sepSize; + }); + return index + }, + + copy: function(copyHistory) { + var doc = new Doc(getLines(this, this.first, this.first + this.size), + this.modeOption, this.first, this.lineSep, this.direction); + doc.scrollTop = this.scrollTop; doc.scrollLeft = this.scrollLeft; + doc.sel = this.sel; + doc.extend = false; + if (copyHistory) { + doc.history.undoDepth = this.history.undoDepth; + doc.setHistory(this.getHistory()); + } + return doc + }, + + linkedDoc: function(options) { + if (!options) { options = {}; } + var from = this.first, to = this.first + this.size; + if (options.from != null && options.from > from) { from = options.from; } + if (options.to != null && options.to < to) { to = options.to; } + var copy = new Doc(getLines(this, from, to), options.mode || this.modeOption, from, this.lineSep, this.direction); + if (options.sharedHist) { copy.history = this.history + ; }(this.linked || (this.linked = [])).push({doc: copy, sharedHist: options.sharedHist}); + copy.linked = [{doc: this, isParent: true, sharedHist: options.sharedHist}]; + copySharedMarkers(copy, findSharedMarkers(this)); + return copy + }, + unlinkDoc: function(other) { + if (other instanceof CodeMirror) { other = other.doc; } + if (this.linked) { for (var i = 0; i < this.linked.length; ++i) { + var link = this.linked[i]; + if (link.doc != other) { continue } + this.linked.splice(i, 1); + other.unlinkDoc(this); + detachSharedMarkers(findSharedMarkers(this)); + break + } } + // If the histories were shared, split them again + if (other.history == this.history) { + var splitIds = [other.id]; + linkedDocs(other, function (doc) { return splitIds.push(doc.id); }, true); + other.history = new History(null); + other.history.done = copyHistoryArray(this.history.done, splitIds); + other.history.undone = copyHistoryArray(this.history.undone, splitIds); + } + }, + iterLinkedDocs: function(f) {linkedDocs(this, f);}, + + getMode: function() {return this.mode}, + getEditor: function() {return this.cm}, + + splitLines: function(str) { + if (this.lineSep) { return str.split(this.lineSep) } + return splitLinesAuto(str) + }, + lineSeparator: function() { return this.lineSep || "\n" }, + + setDirection: docMethodOp(function (dir) { + if (dir != "rtl") { dir = "ltr"; } + if (dir == this.direction) { return } + this.direction = dir; + this.iter(function (line) { return line.order = null; }); + if (this.cm) { directionChanged(this.cm); } + }) + }); + + // Public alias. + Doc.prototype.eachLine = Doc.prototype.iter; + + // Kludge to work around strange IE behavior where it'll sometimes + // re-fire a series of drag-related events right after the drop (#1551) + var lastDrop = 0; + + function onDrop(e) { + var cm = this; + clearDragCursor(cm); + if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e)) + { return } + e_preventDefault(e); + if (ie) { lastDrop = +new Date; } + var pos = posFromMouse(cm, e, true), files = e.dataTransfer.files; + if (!pos || cm.isReadOnly()) { return } + // Might be a file drop, in which case we simply extract the text + // and insert it. + if (files && files.length && window.FileReader && window.File) { + var n = files.length, text = Array(n), read = 0; + var markAsReadAndPasteIfAllFilesAreRead = function () { + if (++read == n) { + operation(cm, function () { + pos = clipPos(cm.doc, pos); + var change = {from: pos, to: pos, + text: cm.doc.splitLines( + text.filter(function (t) { return t != null; }).join(cm.doc.lineSeparator())), + origin: "paste"}; + makeChange(cm.doc, change); + setSelectionReplaceHistory(cm.doc, simpleSelection(clipPos(cm.doc, pos), clipPos(cm.doc, changeEnd(change)))); + })(); + } + }; + var readTextFromFile = function (file, i) { + if (cm.options.allowDropFileTypes && + indexOf(cm.options.allowDropFileTypes, file.type) == -1) { + markAsReadAndPasteIfAllFilesAreRead(); + return + } + var reader = new FileReader; + reader.onerror = function () { return markAsReadAndPasteIfAllFilesAreRead(); }; + reader.onload = function () { + var content = reader.result; + if (/[\x00-\x08\x0e-\x1f]{2}/.test(content)) { + markAsReadAndPasteIfAllFilesAreRead(); + return + } + text[i] = content; + markAsReadAndPasteIfAllFilesAreRead(); + }; + reader.readAsText(file); + }; + for (var i = 0; i < files.length; i++) { readTextFromFile(files[i], i); } + } else { // Normal drop + // Don't do a replace if the drop happened inside of the selected text. + if (cm.state.draggingText && cm.doc.sel.contains(pos) > -1) { + cm.state.draggingText(e); + // Ensure the editor is re-focused + setTimeout(function () { return cm.display.input.focus(); }, 20); + return + } + try { + var text$1 = e.dataTransfer.getData("Text"); + if (text$1) { + var selected; + if (cm.state.draggingText && !cm.state.draggingText.copy) + { selected = cm.listSelections(); } + setSelectionNoUndo(cm.doc, simpleSelection(pos, pos)); + if (selected) { for (var i$1 = 0; i$1 < selected.length; ++i$1) + { replaceRange(cm.doc, "", selected[i$1].anchor, selected[i$1].head, "drag"); } } + cm.replaceSelection(text$1, "around", "paste"); + cm.display.input.focus(); + } + } + catch(e$1){} + } + } + + function onDragStart(cm, e) { + if (ie && (!cm.state.draggingText || +new Date - lastDrop < 100)) { e_stop(e); return } + if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e)) { return } + + e.dataTransfer.setData("Text", cm.getSelection()); + e.dataTransfer.effectAllowed = "copyMove"; + + // Use dummy image instead of default browsers image. + // Recent Safari (~6.0.2) have a tendency to segfault when this happens, so we don't do it there. + if (e.dataTransfer.setDragImage && !safari) { + var img = elt("img", null, null, "position: fixed; left: 0; top: 0;"); + img.src = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="; + if (presto) { + img.width = img.height = 1; + cm.display.wrapper.appendChild(img); + // Force a relayout, or Opera won't use our image for some obscure reason + img._top = img.offsetTop; + } + e.dataTransfer.setDragImage(img, 0, 0); + if (presto) { img.parentNode.removeChild(img); } + } + } + + function onDragOver(cm, e) { + var pos = posFromMouse(cm, e); + if (!pos) { return } + var frag = document.createDocumentFragment(); + drawSelectionCursor(cm, pos, frag); + if (!cm.display.dragCursor) { + cm.display.dragCursor = elt("div", null, "CodeMirror-cursors CodeMirror-dragcursors"); + cm.display.lineSpace.insertBefore(cm.display.dragCursor, cm.display.cursorDiv); + } + removeChildrenAndAdd(cm.display.dragCursor, frag); + } + + function clearDragCursor(cm) { + if (cm.display.dragCursor) { + cm.display.lineSpace.removeChild(cm.display.dragCursor); + cm.display.dragCursor = null; + } + } + + // These must be handled carefully, because naively registering a + // handler for each editor will cause the editors to never be + // garbage collected. + + function forEachCodeMirror(f) { + if (!document.getElementsByClassName) { return } + var byClass = document.getElementsByClassName("CodeMirror"), editors = []; + for (var i = 0; i < byClass.length; i++) { + var cm = byClass[i].CodeMirror; + if (cm) { editors.push(cm); } + } + if (editors.length) { editors[0].operation(function () { + for (var i = 0; i < editors.length; i++) { f(editors[i]); } + }); } + } + + var globalsRegistered = false; + function ensureGlobalHandlers() { + if (globalsRegistered) { return } + registerGlobalHandlers(); + globalsRegistered = true; + } + function registerGlobalHandlers() { + // When the window resizes, we need to refresh active editors. + var resizeTimer; + on(window, "resize", function () { + if (resizeTimer == null) { resizeTimer = setTimeout(function () { + resizeTimer = null; + forEachCodeMirror(onResize); + }, 100); } + }); + // When the window loses focus, we want to show the editor as blurred + on(window, "blur", function () { return forEachCodeMirror(onBlur); }); + } + // Called when the window resizes + function onResize(cm) { + var d = cm.display; + // Might be a text scaling operation, clear size caches. + d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null; + d.scrollbarsClipped = false; + cm.setSize(); + } + + var keyNames = { + 3: "Pause", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt", + 19: "Pause", 20: "CapsLock", 27: "Esc", 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End", + 36: "Home", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "PrintScrn", 45: "Insert", + 46: "Delete", 59: ";", 61: "=", 91: "Mod", 92: "Mod", 93: "Mod", + 106: "*", 107: "=", 109: "-", 110: ".", 111: "/", 145: "ScrollLock", + 173: "-", 186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\", + 221: "]", 222: "'", 224: "Mod", 63232: "Up", 63233: "Down", 63234: "Left", 63235: "Right", 63272: "Delete", + 63273: "Home", 63275: "End", 63276: "PageUp", 63277: "PageDown", 63302: "Insert" + }; + + // Number keys + for (var i = 0; i < 10; i++) { keyNames[i + 48] = keyNames[i + 96] = String(i); } + // Alphabetic keys + for (var i$1 = 65; i$1 <= 90; i$1++) { keyNames[i$1] = String.fromCharCode(i$1); } + // Function keys + for (var i$2 = 1; i$2 <= 12; i$2++) { keyNames[i$2 + 111] = keyNames[i$2 + 63235] = "F" + i$2; } + + var keyMap = {}; + + keyMap.basic = { + "Left": "goCharLeft", "Right": "goCharRight", "Up": "goLineUp", "Down": "goLineDown", + "End": "goLineEnd", "Home": "goLineStartSmart", "PageUp": "goPageUp", "PageDown": "goPageDown", + "Delete": "delCharAfter", "Backspace": "delCharBefore", "Shift-Backspace": "delCharBefore", + "Tab": "defaultTab", "Shift-Tab": "indentAuto", + "Enter": "newlineAndIndent", "Insert": "toggleOverwrite", + "Esc": "singleSelection" + }; + // Note that the save and find-related commands aren't defined by + // default. User code or addons can define them. Unknown commands + // are simply ignored. + keyMap.pcDefault = { + "Ctrl-A": "selectAll", "Ctrl-D": "deleteLine", "Ctrl-Z": "undo", "Shift-Ctrl-Z": "redo", "Ctrl-Y": "redo", + "Ctrl-Home": "goDocStart", "Ctrl-End": "goDocEnd", "Ctrl-Up": "goLineUp", "Ctrl-Down": "goLineDown", + "Ctrl-Left": "goGroupLeft", "Ctrl-Right": "goGroupRight", "Alt-Left": "goLineStart", "Alt-Right": "goLineEnd", + "Ctrl-Backspace": "delGroupBefore", "Ctrl-Delete": "delGroupAfter", "Ctrl-S": "save", "Ctrl-F": "find", + "Ctrl-G": "findNext", "Shift-Ctrl-G": "findPrev", "Shift-Ctrl-F": "replace", "Shift-Ctrl-R": "replaceAll", + "Ctrl-[": "indentLess", "Ctrl-]": "indentMore", + "Ctrl-U": "undoSelection", "Shift-Ctrl-U": "redoSelection", "Alt-U": "redoSelection", + "fallthrough": "basic" + }; + // Very basic readline/emacs-style bindings, which are standard on Mac. + keyMap.emacsy = { + "Ctrl-F": "goCharRight", "Ctrl-B": "goCharLeft", "Ctrl-P": "goLineUp", "Ctrl-N": "goLineDown", + "Alt-F": "goWordRight", "Alt-B": "goWordLeft", "Ctrl-A": "goLineStart", "Ctrl-E": "goLineEnd", + "Ctrl-V": "goPageDown", "Shift-Ctrl-V": "goPageUp", "Ctrl-D": "delCharAfter", "Ctrl-H": "delCharBefore", + "Alt-D": "delWordAfter", "Alt-Backspace": "delWordBefore", "Ctrl-K": "killLine", "Ctrl-T": "transposeChars", + "Ctrl-O": "openLine" + }; + keyMap.macDefault = { + "Cmd-A": "selectAll", "Cmd-D": "deleteLine", "Cmd-Z": "undo", "Shift-Cmd-Z": "redo", "Cmd-Y": "redo", + "Cmd-Home": "goDocStart", "Cmd-Up": "goDocStart", "Cmd-End": "goDocEnd", "Cmd-Down": "goDocEnd", "Alt-Left": "goGroupLeft", + "Alt-Right": "goGroupRight", "Cmd-Left": "goLineLeft", "Cmd-Right": "goLineRight", "Alt-Backspace": "delGroupBefore", + "Ctrl-Alt-Backspace": "delGroupAfter", "Alt-Delete": "delGroupAfter", "Cmd-S": "save", "Cmd-F": "find", + "Cmd-G": "findNext", "Shift-Cmd-G": "findPrev", "Cmd-Alt-F": "replace", "Shift-Cmd-Alt-F": "replaceAll", + "Cmd-[": "indentLess", "Cmd-]": "indentMore", "Cmd-Backspace": "delWrappedLineLeft", "Cmd-Delete": "delWrappedLineRight", + "Cmd-U": "undoSelection", "Shift-Cmd-U": "redoSelection", "Ctrl-Up": "goDocStart", "Ctrl-Down": "goDocEnd", + "fallthrough": ["basic", "emacsy"] + }; + keyMap["default"] = mac ? keyMap.macDefault : keyMap.pcDefault; + + // KEYMAP DISPATCH + + function normalizeKeyName(name) { + var parts = name.split(/-(?!$)/); + name = parts[parts.length - 1]; + var alt, ctrl, shift, cmd; + for (var i = 0; i < parts.length - 1; i++) { + var mod = parts[i]; + if (/^(cmd|meta|m)$/i.test(mod)) { cmd = true; } + else if (/^a(lt)?$/i.test(mod)) { alt = true; } + else if (/^(c|ctrl|control)$/i.test(mod)) { ctrl = true; } + else if (/^s(hift)?$/i.test(mod)) { shift = true; } + else { throw new Error("Unrecognized modifier name: " + mod) } + } + if (alt) { name = "Alt-" + name; } + if (ctrl) { name = "Ctrl-" + name; } + if (cmd) { name = "Cmd-" + name; } + if (shift) { name = "Shift-" + name; } + return name + } + + // This is a kludge to keep keymaps mostly working as raw objects + // (backwards compatibility) while at the same time support features + // like normalization and multi-stroke key bindings. It compiles a + // new normalized keymap, and then updates the old object to reflect + // this. + function normalizeKeyMap(keymap) { + var copy = {}; + for (var keyname in keymap) { if (keymap.hasOwnProperty(keyname)) { + var value = keymap[keyname]; + if (/^(name|fallthrough|(de|at)tach)$/.test(keyname)) { continue } + if (value == "...") { delete keymap[keyname]; continue } + + var keys = map(keyname.split(" "), normalizeKeyName); + for (var i = 0; i < keys.length; i++) { + var val = (void 0), name = (void 0); + if (i == keys.length - 1) { + name = keys.join(" "); + val = value; + } else { + name = keys.slice(0, i + 1).join(" "); + val = "..."; + } + var prev = copy[name]; + if (!prev) { copy[name] = val; } + else if (prev != val) { throw new Error("Inconsistent bindings for " + name) } + } + delete keymap[keyname]; + } } + for (var prop in copy) { keymap[prop] = copy[prop]; } + return keymap + } + + function lookupKey(key, map, handle, context) { + map = getKeyMap(map); + var found = map.call ? map.call(key, context) : map[key]; + if (found === false) { return "nothing" } + if (found === "...") { return "multi" } + if (found != null && handle(found)) { return "handled" } + + if (map.fallthrough) { + if (Object.prototype.toString.call(map.fallthrough) != "[object Array]") + { return lookupKey(key, map.fallthrough, handle, context) } + for (var i = 0; i < map.fallthrough.length; i++) { + var result = lookupKey(key, map.fallthrough[i], handle, context); + if (result) { return result } + } + } + } + + // Modifier key presses don't count as 'real' key presses for the + // purpose of keymap fallthrough. + function isModifierKey(value) { + var name = typeof value == "string" ? value : keyNames[value.keyCode]; + return name == "Ctrl" || name == "Alt" || name == "Shift" || name == "Mod" + } + + function addModifierNames(name, event, noShift) { + var base = name; + if (event.altKey && base != "Alt") { name = "Alt-" + name; } + if ((flipCtrlCmd ? event.metaKey : event.ctrlKey) && base != "Ctrl") { name = "Ctrl-" + name; } + if ((flipCtrlCmd ? event.ctrlKey : event.metaKey) && base != "Mod") { name = "Cmd-" + name; } + if (!noShift && event.shiftKey && base != "Shift") { name = "Shift-" + name; } + return name + } + + // Look up the name of a key as indicated by an event object. + function keyName(event, noShift) { + if (presto && event.keyCode == 34 && event["char"]) { return false } + var name = keyNames[event.keyCode]; + if (name == null || event.altGraphKey) { return false } + // Ctrl-ScrollLock has keyCode 3, same as Ctrl-Pause, + // so we'll use event.code when available (Chrome 48+, FF 38+, Safari 10.1+) + if (event.keyCode == 3 && event.code) { name = event.code; } + return addModifierNames(name, event, noShift) + } + + function getKeyMap(val) { + return typeof val == "string" ? keyMap[val] : val + } + + // Helper for deleting text near the selection(s), used to implement + // backspace, delete, and similar functionality. + function deleteNearSelection(cm, compute) { + var ranges = cm.doc.sel.ranges, kill = []; + // Build up a set of ranges to kill first, merging overlapping + // ranges. + for (var i = 0; i < ranges.length; i++) { + var toKill = compute(ranges[i]); + while (kill.length && cmp(toKill.from, lst(kill).to) <= 0) { + var replaced = kill.pop(); + if (cmp(replaced.from, toKill.from) < 0) { + toKill.from = replaced.from; + break + } + } + kill.push(toKill); + } + // Next, remove those actual ranges. + runInOp(cm, function () { + for (var i = kill.length - 1; i >= 0; i--) + { replaceRange(cm.doc, "", kill[i].from, kill[i].to, "+delete"); } + ensureCursorVisible(cm); + }); + } + + function moveCharLogically(line, ch, dir) { + var target = skipExtendingChars(line.text, ch + dir, dir); + return target < 0 || target > line.text.length ? null : target + } + + function moveLogically(line, start, dir) { + var ch = moveCharLogically(line, start.ch, dir); + return ch == null ? null : new Pos(start.line, ch, dir < 0 ? "after" : "before") + } + + function endOfLine(visually, cm, lineObj, lineNo, dir) { + if (visually) { + if (cm.doc.direction == "rtl") { dir = -dir; } + var order = getOrder(lineObj, cm.doc.direction); + if (order) { + var part = dir < 0 ? lst(order) : order[0]; + var moveInStorageOrder = (dir < 0) == (part.level == 1); + var sticky = moveInStorageOrder ? "after" : "before"; + var ch; + // With a wrapped rtl chunk (possibly spanning multiple bidi parts), + // it could be that the last bidi part is not on the last visual line, + // since visual lines contain content order-consecutive chunks. + // Thus, in rtl, we are looking for the first (content-order) character + // in the rtl chunk that is on the last line (that is, the same line + // as the last (content-order) character). + if (part.level > 0 || cm.doc.direction == "rtl") { + var prep = prepareMeasureForLine(cm, lineObj); + ch = dir < 0 ? lineObj.text.length - 1 : 0; + var targetTop = measureCharPrepared(cm, prep, ch).top; + ch = findFirst(function (ch) { return measureCharPrepared(cm, prep, ch).top == targetTop; }, (dir < 0) == (part.level == 1) ? part.from : part.to - 1, ch); + if (sticky == "before") { ch = moveCharLogically(lineObj, ch, 1); } + } else { ch = dir < 0 ? part.to : part.from; } + return new Pos(lineNo, ch, sticky) + } + } + return new Pos(lineNo, dir < 0 ? lineObj.text.length : 0, dir < 0 ? "before" : "after") + } + + function moveVisually(cm, line, start, dir) { + var bidi = getOrder(line, cm.doc.direction); + if (!bidi) { return moveLogically(line, start, dir) } + if (start.ch >= line.text.length) { + start.ch = line.text.length; + start.sticky = "before"; + } else if (start.ch <= 0) { + start.ch = 0; + start.sticky = "after"; + } + var partPos = getBidiPartAt(bidi, start.ch, start.sticky), part = bidi[partPos]; + if (cm.doc.direction == "ltr" && part.level % 2 == 0 && (dir > 0 ? part.to > start.ch : part.from < start.ch)) { + // Case 1: We move within an ltr part in an ltr editor. Even with wrapped lines, + // nothing interesting happens. + return moveLogically(line, start, dir) + } + + var mv = function (pos, dir) { return moveCharLogically(line, pos instanceof Pos ? pos.ch : pos, dir); }; + var prep; + var getWrappedLineExtent = function (ch) { + if (!cm.options.lineWrapping) { return {begin: 0, end: line.text.length} } + prep = prep || prepareMeasureForLine(cm, line); + return wrappedLineExtentChar(cm, line, prep, ch) + }; + var wrappedLineExtent = getWrappedLineExtent(start.sticky == "before" ? mv(start, -1) : start.ch); + + if (cm.doc.direction == "rtl" || part.level == 1) { + var moveInStorageOrder = (part.level == 1) == (dir < 0); + var ch = mv(start, moveInStorageOrder ? 1 : -1); + if (ch != null && (!moveInStorageOrder ? ch >= part.from && ch >= wrappedLineExtent.begin : ch <= part.to && ch <= wrappedLineExtent.end)) { + // Case 2: We move within an rtl part or in an rtl editor on the same visual line + var sticky = moveInStorageOrder ? "before" : "after"; + return new Pos(start.line, ch, sticky) + } + } + + // Case 3: Could not move within this bidi part in this visual line, so leave + // the current bidi part + + var searchInVisualLine = function (partPos, dir, wrappedLineExtent) { + var getRes = function (ch, moveInStorageOrder) { return moveInStorageOrder + ? new Pos(start.line, mv(ch, 1), "before") + : new Pos(start.line, ch, "after"); }; + + for (; partPos >= 0 && partPos < bidi.length; partPos += dir) { + var part = bidi[partPos]; + var moveInStorageOrder = (dir > 0) == (part.level != 1); + var ch = moveInStorageOrder ? wrappedLineExtent.begin : mv(wrappedLineExtent.end, -1); + if (part.from <= ch && ch < part.to) { return getRes(ch, moveInStorageOrder) } + ch = moveInStorageOrder ? part.from : mv(part.to, -1); + if (wrappedLineExtent.begin <= ch && ch < wrappedLineExtent.end) { return getRes(ch, moveInStorageOrder) } + } + }; + + // Case 3a: Look for other bidi parts on the same visual line + var res = searchInVisualLine(partPos + dir, dir, wrappedLineExtent); + if (res) { return res } + + // Case 3b: Look for other bidi parts on the next visual line + var nextCh = dir > 0 ? wrappedLineExtent.end : mv(wrappedLineExtent.begin, -1); + if (nextCh != null && !(dir > 0 && nextCh == line.text.length)) { + res = searchInVisualLine(dir > 0 ? 0 : bidi.length - 1, dir, getWrappedLineExtent(nextCh)); + if (res) { return res } + } + + // Case 4: Nowhere to move + return null + } + + // Commands are parameter-less actions that can be performed on an + // editor, mostly used for keybindings. + var commands = { + selectAll: selectAll, + singleSelection: function (cm) { return cm.setSelection(cm.getCursor("anchor"), cm.getCursor("head"), sel_dontScroll); }, + killLine: function (cm) { return deleteNearSelection(cm, function (range) { + if (range.empty()) { + var len = getLine(cm.doc, range.head.line).text.length; + if (range.head.ch == len && range.head.line < cm.lastLine()) + { return {from: range.head, to: Pos(range.head.line + 1, 0)} } + else + { return {from: range.head, to: Pos(range.head.line, len)} } + } else { + return {from: range.from(), to: range.to()} + } + }); }, + deleteLine: function (cm) { return deleteNearSelection(cm, function (range) { return ({ + from: Pos(range.from().line, 0), + to: clipPos(cm.doc, Pos(range.to().line + 1, 0)) + }); }); }, + delLineLeft: function (cm) { return deleteNearSelection(cm, function (range) { return ({ + from: Pos(range.from().line, 0), to: range.from() + }); }); }, + delWrappedLineLeft: function (cm) { return deleteNearSelection(cm, function (range) { + var top = cm.charCoords(range.head, "div").top + 5; + var leftPos = cm.coordsChar({left: 0, top: top}, "div"); + return {from: leftPos, to: range.from()} + }); }, + delWrappedLineRight: function (cm) { return deleteNearSelection(cm, function (range) { + var top = cm.charCoords(range.head, "div").top + 5; + var rightPos = cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div"); + return {from: range.from(), to: rightPos } + }); }, + undo: function (cm) { return cm.undo(); }, + redo: function (cm) { return cm.redo(); }, + undoSelection: function (cm) { return cm.undoSelection(); }, + redoSelection: function (cm) { return cm.redoSelection(); }, + goDocStart: function (cm) { return cm.extendSelection(Pos(cm.firstLine(), 0)); }, + goDocEnd: function (cm) { return cm.extendSelection(Pos(cm.lastLine())); }, + goLineStart: function (cm) { return cm.extendSelectionsBy(function (range) { return lineStart(cm, range.head.line); }, + {origin: "+move", bias: 1} + ); }, + goLineStartSmart: function (cm) { return cm.extendSelectionsBy(function (range) { return lineStartSmart(cm, range.head); }, + {origin: "+move", bias: 1} + ); }, + goLineEnd: function (cm) { return cm.extendSelectionsBy(function (range) { return lineEnd(cm, range.head.line); }, + {origin: "+move", bias: -1} + ); }, + goLineRight: function (cm) { return cm.extendSelectionsBy(function (range) { + var top = cm.cursorCoords(range.head, "div").top + 5; + return cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div") + }, sel_move); }, + goLineLeft: function (cm) { return cm.extendSelectionsBy(function (range) { + var top = cm.cursorCoords(range.head, "div").top + 5; + return cm.coordsChar({left: 0, top: top}, "div") + }, sel_move); }, + goLineLeftSmart: function (cm) { return cm.extendSelectionsBy(function (range) { + var top = cm.cursorCoords(range.head, "div").top + 5; + var pos = cm.coordsChar({left: 0, top: top}, "div"); + if (pos.ch < cm.getLine(pos.line).search(/\S/)) { return lineStartSmart(cm, range.head) } + return pos + }, sel_move); }, + goLineUp: function (cm) { return cm.moveV(-1, "line"); }, + goLineDown: function (cm) { return cm.moveV(1, "line"); }, + goPageUp: function (cm) { return cm.moveV(-1, "page"); }, + goPageDown: function (cm) { return cm.moveV(1, "page"); }, + goCharLeft: function (cm) { return cm.moveH(-1, "char"); }, + goCharRight: function (cm) { return cm.moveH(1, "char"); }, + goColumnLeft: function (cm) { return cm.moveH(-1, "column"); }, + goColumnRight: function (cm) { return cm.moveH(1, "column"); }, + goWordLeft: function (cm) { return cm.moveH(-1, "word"); }, + goGroupRight: function (cm) { return cm.moveH(1, "group"); }, + goGroupLeft: function (cm) { return cm.moveH(-1, "group"); }, + goWordRight: function (cm) { return cm.moveH(1, "word"); }, + delCharBefore: function (cm) { return cm.deleteH(-1, "codepoint"); }, + delCharAfter: function (cm) { return cm.deleteH(1, "char"); }, + delWordBefore: function (cm) { return cm.deleteH(-1, "word"); }, + delWordAfter: function (cm) { return cm.deleteH(1, "word"); }, + delGroupBefore: function (cm) { return cm.deleteH(-1, "group"); }, + delGroupAfter: function (cm) { return cm.deleteH(1, "group"); }, + indentAuto: function (cm) { return cm.indentSelection("smart"); }, + indentMore: function (cm) { return cm.indentSelection("add"); }, + indentLess: function (cm) { return cm.indentSelection("subtract"); }, + insertTab: function (cm) { return cm.replaceSelection("\t"); }, + insertSoftTab: function (cm) { + var spaces = [], ranges = cm.listSelections(), tabSize = cm.options.tabSize; + for (var i = 0; i < ranges.length; i++) { + var pos = ranges[i].from(); + var col = countColumn(cm.getLine(pos.line), pos.ch, tabSize); + spaces.push(spaceStr(tabSize - col % tabSize)); + } + cm.replaceSelections(spaces); + }, + defaultTab: function (cm) { + if (cm.somethingSelected()) { cm.indentSelection("add"); } + else { cm.execCommand("insertTab"); } + }, + // Swap the two chars left and right of each selection's head. + // Move cursor behind the two swapped characters afterwards. + // + // Doesn't consider line feeds a character. + // Doesn't scan more than one line above to find a character. + // Doesn't do anything on an empty line. + // Doesn't do anything with non-empty selections. + transposeChars: function (cm) { return runInOp(cm, function () { + var ranges = cm.listSelections(), newSel = []; + for (var i = 0; i < ranges.length; i++) { + if (!ranges[i].empty()) { continue } + var cur = ranges[i].head, line = getLine(cm.doc, cur.line).text; + if (line) { + if (cur.ch == line.length) { cur = new Pos(cur.line, cur.ch - 1); } + if (cur.ch > 0) { + cur = new Pos(cur.line, cur.ch + 1); + cm.replaceRange(line.charAt(cur.ch - 1) + line.charAt(cur.ch - 2), + Pos(cur.line, cur.ch - 2), cur, "+transpose"); + } else if (cur.line > cm.doc.first) { + var prev = getLine(cm.doc, cur.line - 1).text; + if (prev) { + cur = new Pos(cur.line, 1); + cm.replaceRange(line.charAt(0) + cm.doc.lineSeparator() + + prev.charAt(prev.length - 1), + Pos(cur.line - 1, prev.length - 1), cur, "+transpose"); + } + } + } + newSel.push(new Range(cur, cur)); + } + cm.setSelections(newSel); + }); }, + newlineAndIndent: function (cm) { return runInOp(cm, function () { + var sels = cm.listSelections(); + for (var i = sels.length - 1; i >= 0; i--) + { cm.replaceRange(cm.doc.lineSeparator(), sels[i].anchor, sels[i].head, "+input"); } + sels = cm.listSelections(); + for (var i$1 = 0; i$1 < sels.length; i$1++) + { cm.indentLine(sels[i$1].from().line, null, true); } + ensureCursorVisible(cm); + }); }, + openLine: function (cm) { return cm.replaceSelection("\n", "start"); }, + toggleOverwrite: function (cm) { return cm.toggleOverwrite(); } + }; + + + function lineStart(cm, lineN) { + var line = getLine(cm.doc, lineN); + var visual = visualLine(line); + if (visual != line) { lineN = lineNo(visual); } + return endOfLine(true, cm, visual, lineN, 1) + } + function lineEnd(cm, lineN) { + var line = getLine(cm.doc, lineN); + var visual = visualLineEnd(line); + if (visual != line) { lineN = lineNo(visual); } + return endOfLine(true, cm, line, lineN, -1) + } + function lineStartSmart(cm, pos) { + var start = lineStart(cm, pos.line); + var line = getLine(cm.doc, start.line); + var order = getOrder(line, cm.doc.direction); + if (!order || order[0].level == 0) { + var firstNonWS = Math.max(start.ch, line.text.search(/\S/)); + var inWS = pos.line == start.line && pos.ch <= firstNonWS && pos.ch; + return Pos(start.line, inWS ? 0 : firstNonWS, start.sticky) + } + return start + } + + // Run a handler that was bound to a key. + function doHandleBinding(cm, bound, dropShift) { + if (typeof bound == "string") { + bound = commands[bound]; + if (!bound) { return false } + } + // Ensure previous input has been read, so that the handler sees a + // consistent view of the document + cm.display.input.ensurePolled(); + var prevShift = cm.display.shift, done = false; + try { + if (cm.isReadOnly()) { cm.state.suppressEdits = true; } + if (dropShift) { cm.display.shift = false; } + done = bound(cm) != Pass; + } finally { + cm.display.shift = prevShift; + cm.state.suppressEdits = false; + } + return done + } + + function lookupKeyForEditor(cm, name, handle) { + for (var i = 0; i < cm.state.keyMaps.length; i++) { + var result = lookupKey(name, cm.state.keyMaps[i], handle, cm); + if (result) { return result } + } + return (cm.options.extraKeys && lookupKey(name, cm.options.extraKeys, handle, cm)) + || lookupKey(name, cm.options.keyMap, handle, cm) + } + + // Note that, despite the name, this function is also used to check + // for bound mouse clicks. + + var stopSeq = new Delayed; + + function dispatchKey(cm, name, e, handle) { + var seq = cm.state.keySeq; + if (seq) { + if (isModifierKey(name)) { return "handled" } + if (/\'$/.test(name)) + { cm.state.keySeq = null; } + else + { stopSeq.set(50, function () { + if (cm.state.keySeq == seq) { + cm.state.keySeq = null; + cm.display.input.reset(); + } + }); } + if (dispatchKeyInner(cm, seq + " " + name, e, handle)) { return true } + } + return dispatchKeyInner(cm, name, e, handle) + } + + function dispatchKeyInner(cm, name, e, handle) { + var result = lookupKeyForEditor(cm, name, handle); + + if (result == "multi") + { cm.state.keySeq = name; } + if (result == "handled") + { signalLater(cm, "keyHandled", cm, name, e); } + + if (result == "handled" || result == "multi") { + e_preventDefault(e); + restartBlink(cm); + } + + return !!result + } + + // Handle a key from the keydown event. + function handleKeyBinding(cm, e) { + var name = keyName(e, true); + if (!name) { return false } + + if (e.shiftKey && !cm.state.keySeq) { + // First try to resolve full name (including 'Shift-'). Failing + // that, see if there is a cursor-motion command (starting with + // 'go') bound to the keyname without 'Shift-'. + return dispatchKey(cm, "Shift-" + name, e, function (b) { return doHandleBinding(cm, b, true); }) + || dispatchKey(cm, name, e, function (b) { + if (typeof b == "string" ? /^go[A-Z]/.test(b) : b.motion) + { return doHandleBinding(cm, b) } + }) + } else { + return dispatchKey(cm, name, e, function (b) { return doHandleBinding(cm, b); }) + } + } + + // Handle a key from the keypress event + function handleCharBinding(cm, e, ch) { + return dispatchKey(cm, "'" + ch + "'", e, function (b) { return doHandleBinding(cm, b, true); }) + } + + var lastStoppedKey = null; + function onKeyDown(e) { + var cm = this; + if (e.target && e.target != cm.display.input.getField()) { return } + cm.curOp.focus = activeElt(); + if (signalDOMEvent(cm, e)) { return } + // IE does strange things with escape. + if (ie && ie_version < 11 && e.keyCode == 27) { e.returnValue = false; } + var code = e.keyCode; + cm.display.shift = code == 16 || e.shiftKey; + var handled = handleKeyBinding(cm, e); + if (presto) { + lastStoppedKey = handled ? code : null; + // Opera has no cut event... we try to at least catch the key combo + if (!handled && code == 88 && !hasCopyEvent && (mac ? e.metaKey : e.ctrlKey)) + { cm.replaceSelection("", null, "cut"); } + } + if (gecko && !mac && !handled && code == 46 && e.shiftKey && !e.ctrlKey && document.execCommand) + { document.execCommand("cut"); } + + // Turn mouse into crosshair when Alt is held on Mac. + if (code == 18 && !/\bCodeMirror-crosshair\b/.test(cm.display.lineDiv.className)) + { showCrossHair(cm); } + } + + function showCrossHair(cm) { + var lineDiv = cm.display.lineDiv; + addClass(lineDiv, "CodeMirror-crosshair"); + + function up(e) { + if (e.keyCode == 18 || !e.altKey) { + rmClass(lineDiv, "CodeMirror-crosshair"); + off(document, "keyup", up); + off(document, "mouseover", up); + } + } + on(document, "keyup", up); + on(document, "mouseover", up); + } + + function onKeyUp(e) { + if (e.keyCode == 16) { this.doc.sel.shift = false; } + signalDOMEvent(this, e); + } + + function onKeyPress(e) { + var cm = this; + if (e.target && e.target != cm.display.input.getField()) { return } + if (eventInWidget(cm.display, e) || signalDOMEvent(cm, e) || e.ctrlKey && !e.altKey || mac && e.metaKey) { return } + var keyCode = e.keyCode, charCode = e.charCode; + if (presto && keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return} + if ((presto && (!e.which || e.which < 10)) && handleKeyBinding(cm, e)) { return } + var ch = String.fromCharCode(charCode == null ? keyCode : charCode); + // Some browsers fire keypress events for backspace + if (ch == "\x08") { return } + if (handleCharBinding(cm, e, ch)) { return } + cm.display.input.onKeyPress(e); + } + + var DOUBLECLICK_DELAY = 400; + + var PastClick = function(time, pos, button) { + this.time = time; + this.pos = pos; + this.button = button; + }; + + PastClick.prototype.compare = function (time, pos, button) { + return this.time + DOUBLECLICK_DELAY > time && + cmp(pos, this.pos) == 0 && button == this.button + }; + + var lastClick, lastDoubleClick; + function clickRepeat(pos, button) { + var now = +new Date; + if (lastDoubleClick && lastDoubleClick.compare(now, pos, button)) { + lastClick = lastDoubleClick = null; + return "triple" + } else if (lastClick && lastClick.compare(now, pos, button)) { + lastDoubleClick = new PastClick(now, pos, button); + lastClick = null; + return "double" + } else { + lastClick = new PastClick(now, pos, button); + lastDoubleClick = null; + return "single" + } + } + + // A mouse down can be a single click, double click, triple click, + // start of selection drag, start of text drag, new cursor + // (ctrl-click), rectangle drag (alt-drag), or xwin + // middle-click-paste. Or it might be a click on something we should + // not interfere with, such as a scrollbar or widget. + function onMouseDown(e) { + var cm = this, display = cm.display; + if (signalDOMEvent(cm, e) || display.activeTouch && display.input.supportsTouch()) { return } + display.input.ensurePolled(); + display.shift = e.shiftKey; + + if (eventInWidget(display, e)) { + if (!webkit) { + // Briefly turn off draggability, to allow widgets to do + // normal dragging things. + display.scroller.draggable = false; + setTimeout(function () { return display.scroller.draggable = true; }, 100); + } + return + } + if (clickInGutter(cm, e)) { return } + var pos = posFromMouse(cm, e), button = e_button(e), repeat = pos ? clickRepeat(pos, button) : "single"; + window.focus(); + + // #3261: make sure, that we're not starting a second selection + if (button == 1 && cm.state.selectingText) + { cm.state.selectingText(e); } + + if (pos && handleMappedButton(cm, button, pos, repeat, e)) { return } + + if (button == 1) { + if (pos) { leftButtonDown(cm, pos, repeat, e); } + else if (e_target(e) == display.scroller) { e_preventDefault(e); } + } else if (button == 2) { + if (pos) { extendSelection(cm.doc, pos); } + setTimeout(function () { return display.input.focus(); }, 20); + } else if (button == 3) { + if (captureRightClick) { cm.display.input.onContextMenu(e); } + else { delayBlurEvent(cm); } + } + } + + function handleMappedButton(cm, button, pos, repeat, event) { + var name = "Click"; + if (repeat == "double") { name = "Double" + name; } + else if (repeat == "triple") { name = "Triple" + name; } + name = (button == 1 ? "Left" : button == 2 ? "Middle" : "Right") + name; + + return dispatchKey(cm, addModifierNames(name, event), event, function (bound) { + if (typeof bound == "string") { bound = commands[bound]; } + if (!bound) { return false } + var done = false; + try { + if (cm.isReadOnly()) { cm.state.suppressEdits = true; } + done = bound(cm, pos) != Pass; + } finally { + cm.state.suppressEdits = false; + } + return done + }) + } + + function configureMouse(cm, repeat, event) { + var option = cm.getOption("configureMouse"); + var value = option ? option(cm, repeat, event) : {}; + if (value.unit == null) { + var rect = chromeOS ? event.shiftKey && event.metaKey : event.altKey; + value.unit = rect ? "rectangle" : repeat == "single" ? "char" : repeat == "double" ? "word" : "line"; + } + if (value.extend == null || cm.doc.extend) { value.extend = cm.doc.extend || event.shiftKey; } + if (value.addNew == null) { value.addNew = mac ? event.metaKey : event.ctrlKey; } + if (value.moveOnDrag == null) { value.moveOnDrag = !(mac ? event.altKey : event.ctrlKey); } + return value + } + + function leftButtonDown(cm, pos, repeat, event) { + if (ie) { setTimeout(bind(ensureFocus, cm), 0); } + else { cm.curOp.focus = activeElt(); } + + var behavior = configureMouse(cm, repeat, event); + + var sel = cm.doc.sel, contained; + if (cm.options.dragDrop && dragAndDrop && !cm.isReadOnly() && + repeat == "single" && (contained = sel.contains(pos)) > -1 && + (cmp((contained = sel.ranges[contained]).from(), pos) < 0 || pos.xRel > 0) && + (cmp(contained.to(), pos) > 0 || pos.xRel < 0)) + { leftButtonStartDrag(cm, event, pos, behavior); } + else + { leftButtonSelect(cm, event, pos, behavior); } + } + + // Start a text drag. When it ends, see if any dragging actually + // happen, and treat as a click if it didn't. + function leftButtonStartDrag(cm, event, pos, behavior) { + var display = cm.display, moved = false; + var dragEnd = operation(cm, function (e) { + if (webkit) { display.scroller.draggable = false; } + cm.state.draggingText = false; + off(display.wrapper.ownerDocument, "mouseup", dragEnd); + off(display.wrapper.ownerDocument, "mousemove", mouseMove); + off(display.scroller, "dragstart", dragStart); + off(display.scroller, "drop", dragEnd); + if (!moved) { + e_preventDefault(e); + if (!behavior.addNew) + { extendSelection(cm.doc, pos, null, null, behavior.extend); } + // Work around unexplainable focus problem in IE9 (#2127) and Chrome (#3081) + if ((webkit && !safari) || ie && ie_version == 9) + { setTimeout(function () {display.wrapper.ownerDocument.body.focus({preventScroll: true}); display.input.focus();}, 20); } + else + { display.input.focus(); } + } + }); + var mouseMove = function(e2) { + moved = moved || Math.abs(event.clientX - e2.clientX) + Math.abs(event.clientY - e2.clientY) >= 10; + }; + var dragStart = function () { return moved = true; }; + // Let the drag handler handle this. + if (webkit) { display.scroller.draggable = true; } + cm.state.draggingText = dragEnd; + dragEnd.copy = !behavior.moveOnDrag; + // IE's approach to draggable + if (display.scroller.dragDrop) { display.scroller.dragDrop(); } + on(display.wrapper.ownerDocument, "mouseup", dragEnd); + on(display.wrapper.ownerDocument, "mousemove", mouseMove); + on(display.scroller, "dragstart", dragStart); + on(display.scroller, "drop", dragEnd); + + delayBlurEvent(cm); + setTimeout(function () { return display.input.focus(); }, 20); + } + + function rangeForUnit(cm, pos, unit) { + if (unit == "char") { return new Range(pos, pos) } + if (unit == "word") { return cm.findWordAt(pos) } + if (unit == "line") { return new Range(Pos(pos.line, 0), clipPos(cm.doc, Pos(pos.line + 1, 0))) } + var result = unit(cm, pos); + return new Range(result.from, result.to) + } + + // Normal selection, as opposed to text dragging. + function leftButtonSelect(cm, event, start, behavior) { + var display = cm.display, doc = cm.doc; + e_preventDefault(event); + + var ourRange, ourIndex, startSel = doc.sel, ranges = startSel.ranges; + if (behavior.addNew && !behavior.extend) { + ourIndex = doc.sel.contains(start); + if (ourIndex > -1) + { ourRange = ranges[ourIndex]; } + else + { ourRange = new Range(start, start); } + } else { + ourRange = doc.sel.primary(); + ourIndex = doc.sel.primIndex; + } + + if (behavior.unit == "rectangle") { + if (!behavior.addNew) { ourRange = new Range(start, start); } + start = posFromMouse(cm, event, true, true); + ourIndex = -1; + } else { + var range = rangeForUnit(cm, start, behavior.unit); + if (behavior.extend) + { ourRange = extendRange(ourRange, range.anchor, range.head, behavior.extend); } + else + { ourRange = range; } + } + + if (!behavior.addNew) { + ourIndex = 0; + setSelection(doc, new Selection([ourRange], 0), sel_mouse); + startSel = doc.sel; + } else if (ourIndex == -1) { + ourIndex = ranges.length; + setSelection(doc, normalizeSelection(cm, ranges.concat([ourRange]), ourIndex), + {scroll: false, origin: "*mouse"}); + } else if (ranges.length > 1 && ranges[ourIndex].empty() && behavior.unit == "char" && !behavior.extend) { + setSelection(doc, normalizeSelection(cm, ranges.slice(0, ourIndex).concat(ranges.slice(ourIndex + 1)), 0), + {scroll: false, origin: "*mouse"}); + startSel = doc.sel; + } else { + replaceOneSelection(doc, ourIndex, ourRange, sel_mouse); + } + + var lastPos = start; + function extendTo(pos) { + if (cmp(lastPos, pos) == 0) { return } + lastPos = pos; + + if (behavior.unit == "rectangle") { + var ranges = [], tabSize = cm.options.tabSize; + var startCol = countColumn(getLine(doc, start.line).text, start.ch, tabSize); + var posCol = countColumn(getLine(doc, pos.line).text, pos.ch, tabSize); + var left = Math.min(startCol, posCol), right = Math.max(startCol, posCol); + for (var line = Math.min(start.line, pos.line), end = Math.min(cm.lastLine(), Math.max(start.line, pos.line)); + line <= end; line++) { + var text = getLine(doc, line).text, leftPos = findColumn(text, left, tabSize); + if (left == right) + { ranges.push(new Range(Pos(line, leftPos), Pos(line, leftPos))); } + else if (text.length > leftPos) + { ranges.push(new Range(Pos(line, leftPos), Pos(line, findColumn(text, right, tabSize)))); } + } + if (!ranges.length) { ranges.push(new Range(start, start)); } + setSelection(doc, normalizeSelection(cm, startSel.ranges.slice(0, ourIndex).concat(ranges), ourIndex), + {origin: "*mouse", scroll: false}); + cm.scrollIntoView(pos); + } else { + var oldRange = ourRange; + var range = rangeForUnit(cm, pos, behavior.unit); + var anchor = oldRange.anchor, head; + if (cmp(range.anchor, anchor) > 0) { + head = range.head; + anchor = minPos(oldRange.from(), range.anchor); + } else { + head = range.anchor; + anchor = maxPos(oldRange.to(), range.head); + } + var ranges$1 = startSel.ranges.slice(0); + ranges$1[ourIndex] = bidiSimplify(cm, new Range(clipPos(doc, anchor), head)); + setSelection(doc, normalizeSelection(cm, ranges$1, ourIndex), sel_mouse); + } + } + + var editorSize = display.wrapper.getBoundingClientRect(); + // Used to ensure timeout re-tries don't fire when another extend + // happened in the meantime (clearTimeout isn't reliable -- at + // least on Chrome, the timeouts still happen even when cleared, + // if the clear happens after their scheduled firing time). + var counter = 0; + + function extend(e) { + var curCount = ++counter; + var cur = posFromMouse(cm, e, true, behavior.unit == "rectangle"); + if (!cur) { return } + if (cmp(cur, lastPos) != 0) { + cm.curOp.focus = activeElt(); + extendTo(cur); + var visible = visibleLines(display, doc); + if (cur.line >= visible.to || cur.line < visible.from) + { setTimeout(operation(cm, function () {if (counter == curCount) { extend(e); }}), 150); } + } else { + var outside = e.clientY < editorSize.top ? -20 : e.clientY > editorSize.bottom ? 20 : 0; + if (outside) { setTimeout(operation(cm, function () { + if (counter != curCount) { return } + display.scroller.scrollTop += outside; + extend(e); + }), 50); } + } + } + + function done(e) { + cm.state.selectingText = false; + counter = Infinity; + // If e is null or undefined we interpret this as someone trying + // to explicitly cancel the selection rather than the user + // letting go of the mouse button. + if (e) { + e_preventDefault(e); + display.input.focus(); + } + off(display.wrapper.ownerDocument, "mousemove", move); + off(display.wrapper.ownerDocument, "mouseup", up); + doc.history.lastSelOrigin = null; + } + + var move = operation(cm, function (e) { + if (e.buttons === 0 || !e_button(e)) { done(e); } + else { extend(e); } + }); + var up = operation(cm, done); + cm.state.selectingText = up; + on(display.wrapper.ownerDocument, "mousemove", move); + on(display.wrapper.ownerDocument, "mouseup", up); + } + + // Used when mouse-selecting to adjust the anchor to the proper side + // of a bidi jump depending on the visual position of the head. + function bidiSimplify(cm, range) { + var anchor = range.anchor; + var head = range.head; + var anchorLine = getLine(cm.doc, anchor.line); + if (cmp(anchor, head) == 0 && anchor.sticky == head.sticky) { return range } + var order = getOrder(anchorLine); + if (!order) { return range } + var index = getBidiPartAt(order, anchor.ch, anchor.sticky), part = order[index]; + if (part.from != anchor.ch && part.to != anchor.ch) { return range } + var boundary = index + ((part.from == anchor.ch) == (part.level != 1) ? 0 : 1); + if (boundary == 0 || boundary == order.length) { return range } + + // Compute the relative visual position of the head compared to the + // anchor (<0 is to the left, >0 to the right) + var leftSide; + if (head.line != anchor.line) { + leftSide = (head.line - anchor.line) * (cm.doc.direction == "ltr" ? 1 : -1) > 0; + } else { + var headIndex = getBidiPartAt(order, head.ch, head.sticky); + var dir = headIndex - index || (head.ch - anchor.ch) * (part.level == 1 ? -1 : 1); + if (headIndex == boundary - 1 || headIndex == boundary) + { leftSide = dir < 0; } + else + { leftSide = dir > 0; } + } + + var usePart = order[boundary + (leftSide ? -1 : 0)]; + var from = leftSide == (usePart.level == 1); + var ch = from ? usePart.from : usePart.to, sticky = from ? "after" : "before"; + return anchor.ch == ch && anchor.sticky == sticky ? range : new Range(new Pos(anchor.line, ch, sticky), head) + } + + + // Determines whether an event happened in the gutter, and fires the + // handlers for the corresponding event. + function gutterEvent(cm, e, type, prevent) { + var mX, mY; + if (e.touches) { + mX = e.touches[0].clientX; + mY = e.touches[0].clientY; + } else { + try { mX = e.clientX; mY = e.clientY; } + catch(e$1) { return false } + } + if (mX >= Math.floor(cm.display.gutters.getBoundingClientRect().right)) { return false } + if (prevent) { e_preventDefault(e); } + + var display = cm.display; + var lineBox = display.lineDiv.getBoundingClientRect(); + + if (mY > lineBox.bottom || !hasHandler(cm, type)) { return e_defaultPrevented(e) } + mY -= lineBox.top - display.viewOffset; + + for (var i = 0; i < cm.display.gutterSpecs.length; ++i) { + var g = display.gutters.childNodes[i]; + if (g && g.getBoundingClientRect().right >= mX) { + var line = lineAtHeight(cm.doc, mY); + var gutter = cm.display.gutterSpecs[i]; + signal(cm, type, cm, line, gutter.className, e); + return e_defaultPrevented(e) + } + } + } + + function clickInGutter(cm, e) { + return gutterEvent(cm, e, "gutterClick", true) + } + + // CONTEXT MENU HANDLING + + // To make the context menu work, we need to briefly unhide the + // textarea (making it as unobtrusive as possible) to let the + // right-click take effect on it. + function onContextMenu(cm, e) { + if (eventInWidget(cm.display, e) || contextMenuInGutter(cm, e)) { return } + if (signalDOMEvent(cm, e, "contextmenu")) { return } + if (!captureRightClick) { cm.display.input.onContextMenu(e); } + } + + function contextMenuInGutter(cm, e) { + if (!hasHandler(cm, "gutterContextMenu")) { return false } + return gutterEvent(cm, e, "gutterContextMenu", false) + } + + function themeChanged(cm) { + cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-s-\S+/g, "") + + cm.options.theme.replace(/(^|\s)\s*/g, " cm-s-"); + clearCaches(cm); + } + + var Init = {toString: function(){return "CodeMirror.Init"}}; + + var defaults = {}; + var optionHandlers = {}; + + function defineOptions(CodeMirror) { + var optionHandlers = CodeMirror.optionHandlers; + + function option(name, deflt, handle, notOnInit) { + CodeMirror.defaults[name] = deflt; + if (handle) { optionHandlers[name] = + notOnInit ? function (cm, val, old) {if (old != Init) { handle(cm, val, old); }} : handle; } + } + + CodeMirror.defineOption = option; + + // Passed to option handlers when there is no old value. + CodeMirror.Init = Init; + + // These two are, on init, called from the constructor because they + // have to be initialized before the editor can start at all. + option("value", "", function (cm, val) { return cm.setValue(val); }, true); + option("mode", null, function (cm, val) { + cm.doc.modeOption = val; + loadMode(cm); + }, true); + + option("indentUnit", 2, loadMode, true); + option("indentWithTabs", false); + option("smartIndent", true); + option("tabSize", 4, function (cm) { + resetModeState(cm); + clearCaches(cm); + regChange(cm); + }, true); + + option("lineSeparator", null, function (cm, val) { + cm.doc.lineSep = val; + if (!val) { return } + var newBreaks = [], lineNo = cm.doc.first; + cm.doc.iter(function (line) { + for (var pos = 0;;) { + var found = line.text.indexOf(val, pos); + if (found == -1) { break } + pos = found + val.length; + newBreaks.push(Pos(lineNo, found)); + } + lineNo++; + }); + for (var i = newBreaks.length - 1; i >= 0; i--) + { replaceRange(cm.doc, val, newBreaks[i], Pos(newBreaks[i].line, newBreaks[i].ch + val.length)); } + }); + option("specialChars", /[\u0000-\u001f\u007f-\u009f\u00ad\u061c\u200b-\u200c\u200e\u200f\u2028\u2029\ufeff\ufff9-\ufffc]/g, function (cm, val, old) { + cm.state.specialChars = new RegExp(val.source + (val.test("\t") ? "" : "|\t"), "g"); + if (old != Init) { cm.refresh(); } + }); + option("specialCharPlaceholder", defaultSpecialCharPlaceholder, function (cm) { return cm.refresh(); }, true); + option("electricChars", true); + option("inputStyle", mobile ? "contenteditable" : "textarea", function () { + throw new Error("inputStyle can not (yet) be changed in a running editor") // FIXME + }, true); + option("spellcheck", false, function (cm, val) { return cm.getInputField().spellcheck = val; }, true); + option("autocorrect", false, function (cm, val) { return cm.getInputField().autocorrect = val; }, true); + option("autocapitalize", false, function (cm, val) { return cm.getInputField().autocapitalize = val; }, true); + option("rtlMoveVisually", !windows); + option("wholeLineUpdateBefore", true); + + option("theme", "default", function (cm) { + themeChanged(cm); + updateGutters(cm); + }, true); + option("keyMap", "default", function (cm, val, old) { + var next = getKeyMap(val); + var prev = old != Init && getKeyMap(old); + if (prev && prev.detach) { prev.detach(cm, next); } + if (next.attach) { next.attach(cm, prev || null); } + }); + option("extraKeys", null); + option("configureMouse", null); + + option("lineWrapping", false, wrappingChanged, true); + option("gutters", [], function (cm, val) { + cm.display.gutterSpecs = getGutters(val, cm.options.lineNumbers); + updateGutters(cm); + }, true); + option("fixedGutter", true, function (cm, val) { + cm.display.gutters.style.left = val ? compensateForHScroll(cm.display) + "px" : "0"; + cm.refresh(); + }, true); + option("coverGutterNextToScrollbar", false, function (cm) { return updateScrollbars(cm); }, true); + option("scrollbarStyle", "native", function (cm) { + initScrollbars(cm); + updateScrollbars(cm); + cm.display.scrollbars.setScrollTop(cm.doc.scrollTop); + cm.display.scrollbars.setScrollLeft(cm.doc.scrollLeft); + }, true); + option("lineNumbers", false, function (cm, val) { + cm.display.gutterSpecs = getGutters(cm.options.gutters, val); + updateGutters(cm); + }, true); + option("firstLineNumber", 1, updateGutters, true); + option("lineNumberFormatter", function (integer) { return integer; }, updateGutters, true); + option("showCursorWhenSelecting", false, updateSelection, true); + + option("resetSelectionOnContextMenu", true); + option("lineWiseCopyCut", true); + option("pasteLinesPerSelection", true); + option("selectionsMayTouch", false); + + option("readOnly", false, function (cm, val) { + if (val == "nocursor") { + onBlur(cm); + cm.display.input.blur(); + } + cm.display.input.readOnlyChanged(val); + }); + + option("screenReaderLabel", null, function (cm, val) { + val = (val === '') ? null : val; + cm.display.input.screenReaderLabelChanged(val); + }); + + option("disableInput", false, function (cm, val) {if (!val) { cm.display.input.reset(); }}, true); + option("dragDrop", true, dragDropChanged); + option("allowDropFileTypes", null); + + option("cursorBlinkRate", 530); + option("cursorScrollMargin", 0); + option("cursorHeight", 1, updateSelection, true); + option("singleCursorHeightPerLine", true, updateSelection, true); + option("workTime", 100); + option("workDelay", 100); + option("flattenSpans", true, resetModeState, true); + option("addModeClass", false, resetModeState, true); + option("pollInterval", 100); + option("undoDepth", 200, function (cm, val) { return cm.doc.history.undoDepth = val; }); + option("historyEventDelay", 1250); + option("viewportMargin", 10, function (cm) { return cm.refresh(); }, true); + option("maxHighlightLength", 10000, resetModeState, true); + option("moveInputWithCursor", true, function (cm, val) { + if (!val) { cm.display.input.resetPosition(); } + }); + + option("tabindex", null, function (cm, val) { return cm.display.input.getField().tabIndex = val || ""; }); + option("autofocus", null); + option("direction", "ltr", function (cm, val) { return cm.doc.setDirection(val); }, true); + option("phrases", null); + } + + function dragDropChanged(cm, value, old) { + var wasOn = old && old != Init; + if (!value != !wasOn) { + var funcs = cm.display.dragFunctions; + var toggle = value ? on : off; + toggle(cm.display.scroller, "dragstart", funcs.start); + toggle(cm.display.scroller, "dragenter", funcs.enter); + toggle(cm.display.scroller, "dragover", funcs.over); + toggle(cm.display.scroller, "dragleave", funcs.leave); + toggle(cm.display.scroller, "drop", funcs.drop); + } + } + + function wrappingChanged(cm) { + if (cm.options.lineWrapping) { + addClass(cm.display.wrapper, "CodeMirror-wrap"); + cm.display.sizer.style.minWidth = ""; + cm.display.sizerWidth = null; + } else { + rmClass(cm.display.wrapper, "CodeMirror-wrap"); + findMaxLine(cm); + } + estimateLineHeights(cm); + regChange(cm); + clearCaches(cm); + setTimeout(function () { return updateScrollbars(cm); }, 100); + } + + // A CodeMirror instance represents an editor. This is the object + // that user code is usually dealing with. + + function CodeMirror(place, options) { + var this$1 = this; + + if (!(this instanceof CodeMirror)) { return new CodeMirror(place, options) } + + this.options = options = options ? copyObj(options) : {}; + // Determine effective options based on given values and defaults. + copyObj(defaults, options, false); + + var doc = options.value; + if (typeof doc == "string") { doc = new Doc(doc, options.mode, null, options.lineSeparator, options.direction); } + else if (options.mode) { doc.modeOption = options.mode; } + this.doc = doc; + + var input = new CodeMirror.inputStyles[options.inputStyle](this); + var display = this.display = new Display(place, doc, input, options); + display.wrapper.CodeMirror = this; + themeChanged(this); + if (options.lineWrapping) + { this.display.wrapper.className += " CodeMirror-wrap"; } + initScrollbars(this); + + this.state = { + keyMaps: [], // stores maps added by addKeyMap + overlays: [], // highlighting overlays, as added by addOverlay + modeGen: 0, // bumped when mode/overlay changes, used to invalidate highlighting info + overwrite: false, + delayingBlurEvent: false, + focused: false, + suppressEdits: false, // used to disable editing during key handlers when in readOnly mode + pasteIncoming: -1, cutIncoming: -1, // help recognize paste/cut edits in input.poll + selectingText: false, + draggingText: false, + highlight: new Delayed(), // stores highlight worker timeout + keySeq: null, // Unfinished key sequence + specialChars: null + }; + + if (options.autofocus && !mobile) { display.input.focus(); } + + // Override magic textarea content restore that IE sometimes does + // on our hidden textarea on reload + if (ie && ie_version < 11) { setTimeout(function () { return this$1.display.input.reset(true); }, 20); } + + registerEventHandlers(this); + ensureGlobalHandlers(); + + startOperation(this); + this.curOp.forceUpdate = true; + attachDoc(this, doc); + + if ((options.autofocus && !mobile) || this.hasFocus()) + { setTimeout(function () { + if (this$1.hasFocus() && !this$1.state.focused) { onFocus(this$1); } + }, 20); } + else + { onBlur(this); } + + for (var opt in optionHandlers) { if (optionHandlers.hasOwnProperty(opt)) + { optionHandlers[opt](this, options[opt], Init); } } + maybeUpdateLineNumberWidth(this); + if (options.finishInit) { options.finishInit(this); } + for (var i = 0; i < initHooks.length; ++i) { initHooks[i](this); } + endOperation(this); + // Suppress optimizelegibility in Webkit, since it breaks text + // measuring on line wrapping boundaries. + if (webkit && options.lineWrapping && + getComputedStyle(display.lineDiv).textRendering == "optimizelegibility") + { display.lineDiv.style.textRendering = "auto"; } + } + + // The default configuration options. + CodeMirror.defaults = defaults; + // Functions to run when options are changed. + CodeMirror.optionHandlers = optionHandlers; + + // Attach the necessary event handlers when initializing the editor + function registerEventHandlers(cm) { + var d = cm.display; + on(d.scroller, "mousedown", operation(cm, onMouseDown)); + // Older IE's will not fire a second mousedown for a double click + if (ie && ie_version < 11) + { on(d.scroller, "dblclick", operation(cm, function (e) { + if (signalDOMEvent(cm, e)) { return } + var pos = posFromMouse(cm, e); + if (!pos || clickInGutter(cm, e) || eventInWidget(cm.display, e)) { return } + e_preventDefault(e); + var word = cm.findWordAt(pos); + extendSelection(cm.doc, word.anchor, word.head); + })); } + else + { on(d.scroller, "dblclick", function (e) { return signalDOMEvent(cm, e) || e_preventDefault(e); }); } + // Some browsers fire contextmenu *after* opening the menu, at + // which point we can't mess with it anymore. Context menu is + // handled in onMouseDown for these browsers. + on(d.scroller, "contextmenu", function (e) { return onContextMenu(cm, e); }); + on(d.input.getField(), "contextmenu", function (e) { + if (!d.scroller.contains(e.target)) { onContextMenu(cm, e); } + }); + + // Used to suppress mouse event handling when a touch happens + var touchFinished, prevTouch = {end: 0}; + function finishTouch() { + if (d.activeTouch) { + touchFinished = setTimeout(function () { return d.activeTouch = null; }, 1000); + prevTouch = d.activeTouch; + prevTouch.end = +new Date; + } + } + function isMouseLikeTouchEvent(e) { + if (e.touches.length != 1) { return false } + var touch = e.touches[0]; + return touch.radiusX <= 1 && touch.radiusY <= 1 + } + function farAway(touch, other) { + if (other.left == null) { return true } + var dx = other.left - touch.left, dy = other.top - touch.top; + return dx * dx + dy * dy > 20 * 20 + } + on(d.scroller, "touchstart", function (e) { + if (!signalDOMEvent(cm, e) && !isMouseLikeTouchEvent(e) && !clickInGutter(cm, e)) { + d.input.ensurePolled(); + clearTimeout(touchFinished); + var now = +new Date; + d.activeTouch = {start: now, moved: false, + prev: now - prevTouch.end <= 300 ? prevTouch : null}; + if (e.touches.length == 1) { + d.activeTouch.left = e.touches[0].pageX; + d.activeTouch.top = e.touches[0].pageY; + } + } + }); + on(d.scroller, "touchmove", function () { + if (d.activeTouch) { d.activeTouch.moved = true; } + }); + on(d.scroller, "touchend", function (e) { + var touch = d.activeTouch; + if (touch && !eventInWidget(d, e) && touch.left != null && + !touch.moved && new Date - touch.start < 300) { + var pos = cm.coordsChar(d.activeTouch, "page"), range; + if (!touch.prev || farAway(touch, touch.prev)) // Single tap + { range = new Range(pos, pos); } + else if (!touch.prev.prev || farAway(touch, touch.prev.prev)) // Double tap + { range = cm.findWordAt(pos); } + else // Triple tap + { range = new Range(Pos(pos.line, 0), clipPos(cm.doc, Pos(pos.line + 1, 0))); } + cm.setSelection(range.anchor, range.head); + cm.focus(); + e_preventDefault(e); + } + finishTouch(); + }); + on(d.scroller, "touchcancel", finishTouch); + + // Sync scrolling between fake scrollbars and real scrollable + // area, ensure viewport is updated when scrolling. + on(d.scroller, "scroll", function () { + if (d.scroller.clientHeight) { + updateScrollTop(cm, d.scroller.scrollTop); + setScrollLeft(cm, d.scroller.scrollLeft, true); + signal(cm, "scroll", cm); + } + }); + + // Listen to wheel events in order to try and update the viewport on time. + on(d.scroller, "mousewheel", function (e) { return onScrollWheel(cm, e); }); + on(d.scroller, "DOMMouseScroll", function (e) { return onScrollWheel(cm, e); }); + + // Prevent wrapper from ever scrolling + on(d.wrapper, "scroll", function () { return d.wrapper.scrollTop = d.wrapper.scrollLeft = 0; }); + + d.dragFunctions = { + enter: function (e) {if (!signalDOMEvent(cm, e)) { e_stop(e); }}, + over: function (e) {if (!signalDOMEvent(cm, e)) { onDragOver(cm, e); e_stop(e); }}, + start: function (e) { return onDragStart(cm, e); }, + drop: operation(cm, onDrop), + leave: function (e) {if (!signalDOMEvent(cm, e)) { clearDragCursor(cm); }} + }; + + var inp = d.input.getField(); + on(inp, "keyup", function (e) { return onKeyUp.call(cm, e); }); + on(inp, "keydown", operation(cm, onKeyDown)); + on(inp, "keypress", operation(cm, onKeyPress)); + on(inp, "focus", function (e) { return onFocus(cm, e); }); + on(inp, "blur", function (e) { return onBlur(cm, e); }); + } + + var initHooks = []; + CodeMirror.defineInitHook = function (f) { return initHooks.push(f); }; + + // Indent the given line. The how parameter can be "smart", + // "add"/null, "subtract", or "prev". When aggressive is false + // (typically set to true for forced single-line indents), empty + // lines are not indented, and places where the mode returns Pass + // are left alone. + function indentLine(cm, n, how, aggressive) { + var doc = cm.doc, state; + if (how == null) { how = "add"; } + if (how == "smart") { + // Fall back to "prev" when the mode doesn't have an indentation + // method. + if (!doc.mode.indent) { how = "prev"; } + else { state = getContextBefore(cm, n).state; } + } + + var tabSize = cm.options.tabSize; + var line = getLine(doc, n), curSpace = countColumn(line.text, null, tabSize); + if (line.stateAfter) { line.stateAfter = null; } + var curSpaceString = line.text.match(/^\s*/)[0], indentation; + if (!aggressive && !/\S/.test(line.text)) { + indentation = 0; + how = "not"; + } else if (how == "smart") { + indentation = doc.mode.indent(state, line.text.slice(curSpaceString.length), line.text); + if (indentation == Pass || indentation > 150) { + if (!aggressive) { return } + how = "prev"; + } + } + if (how == "prev") { + if (n > doc.first) { indentation = countColumn(getLine(doc, n-1).text, null, tabSize); } + else { indentation = 0; } + } else if (how == "add") { + indentation = curSpace + cm.options.indentUnit; + } else if (how == "subtract") { + indentation = curSpace - cm.options.indentUnit; + } else if (typeof how == "number") { + indentation = curSpace + how; + } + indentation = Math.max(0, indentation); + + var indentString = "", pos = 0; + if (cm.options.indentWithTabs) + { for (var i = Math.floor(indentation / tabSize); i; --i) {pos += tabSize; indentString += "\t";} } + if (pos < indentation) { indentString += spaceStr(indentation - pos); } + + if (indentString != curSpaceString) { + replaceRange(doc, indentString, Pos(n, 0), Pos(n, curSpaceString.length), "+input"); + line.stateAfter = null; + return true + } else { + // Ensure that, if the cursor was in the whitespace at the start + // of the line, it is moved to the end of that space. + for (var i$1 = 0; i$1 < doc.sel.ranges.length; i$1++) { + var range = doc.sel.ranges[i$1]; + if (range.head.line == n && range.head.ch < curSpaceString.length) { + var pos$1 = Pos(n, curSpaceString.length); + replaceOneSelection(doc, i$1, new Range(pos$1, pos$1)); + break + } + } + } + } + + // This will be set to a {lineWise: bool, text: [string]} object, so + // that, when pasting, we know what kind of selections the copied + // text was made out of. + var lastCopied = null; + + function setLastCopied(newLastCopied) { + lastCopied = newLastCopied; + } + + function applyTextInput(cm, inserted, deleted, sel, origin) { + var doc = cm.doc; + cm.display.shift = false; + if (!sel) { sel = doc.sel; } + + var recent = +new Date - 200; + var paste = origin == "paste" || cm.state.pasteIncoming > recent; + var textLines = splitLinesAuto(inserted), multiPaste = null; + // When pasting N lines into N selections, insert one line per selection + if (paste && sel.ranges.length > 1) { + if (lastCopied && lastCopied.text.join("\n") == inserted) { + if (sel.ranges.length % lastCopied.text.length == 0) { + multiPaste = []; + for (var i = 0; i < lastCopied.text.length; i++) + { multiPaste.push(doc.splitLines(lastCopied.text[i])); } + } + } else if (textLines.length == sel.ranges.length && cm.options.pasteLinesPerSelection) { + multiPaste = map(textLines, function (l) { return [l]; }); + } + } + + var updateInput = cm.curOp.updateInput; + // Normal behavior is to insert the new text into every selection + for (var i$1 = sel.ranges.length - 1; i$1 >= 0; i$1--) { + var range = sel.ranges[i$1]; + var from = range.from(), to = range.to(); + if (range.empty()) { + if (deleted && deleted > 0) // Handle deletion + { from = Pos(from.line, from.ch - deleted); } + else if (cm.state.overwrite && !paste) // Handle overwrite + { to = Pos(to.line, Math.min(getLine(doc, to.line).text.length, to.ch + lst(textLines).length)); } + else if (paste && lastCopied && lastCopied.lineWise && lastCopied.text.join("\n") == textLines.join("\n")) + { from = to = Pos(from.line, 0); } + } + var changeEvent = {from: from, to: to, text: multiPaste ? multiPaste[i$1 % multiPaste.length] : textLines, + origin: origin || (paste ? "paste" : cm.state.cutIncoming > recent ? "cut" : "+input")}; + makeChange(cm.doc, changeEvent); + signalLater(cm, "inputRead", cm, changeEvent); + } + if (inserted && !paste) + { triggerElectric(cm, inserted); } + + ensureCursorVisible(cm); + if (cm.curOp.updateInput < 2) { cm.curOp.updateInput = updateInput; } + cm.curOp.typing = true; + cm.state.pasteIncoming = cm.state.cutIncoming = -1; + } + + function handlePaste(e, cm) { + var pasted = e.clipboardData && e.clipboardData.getData("Text"); + if (pasted) { + e.preventDefault(); + if (!cm.isReadOnly() && !cm.options.disableInput) + { runInOp(cm, function () { return applyTextInput(cm, pasted, 0, null, "paste"); }); } + return true + } + } + + function triggerElectric(cm, inserted) { + // When an 'electric' character is inserted, immediately trigger a reindent + if (!cm.options.electricChars || !cm.options.smartIndent) { return } + var sel = cm.doc.sel; + + for (var i = sel.ranges.length - 1; i >= 0; i--) { + var range = sel.ranges[i]; + if (range.head.ch > 100 || (i && sel.ranges[i - 1].head.line == range.head.line)) { continue } + var mode = cm.getModeAt(range.head); + var indented = false; + if (mode.electricChars) { + for (var j = 0; j < mode.electricChars.length; j++) + { if (inserted.indexOf(mode.electricChars.charAt(j)) > -1) { + indented = indentLine(cm, range.head.line, "smart"); + break + } } + } else if (mode.electricInput) { + if (mode.electricInput.test(getLine(cm.doc, range.head.line).text.slice(0, range.head.ch))) + { indented = indentLine(cm, range.head.line, "smart"); } + } + if (indented) { signalLater(cm, "electricInput", cm, range.head.line); } + } + } + + function copyableRanges(cm) { + var text = [], ranges = []; + for (var i = 0; i < cm.doc.sel.ranges.length; i++) { + var line = cm.doc.sel.ranges[i].head.line; + var lineRange = {anchor: Pos(line, 0), head: Pos(line + 1, 0)}; + ranges.push(lineRange); + text.push(cm.getRange(lineRange.anchor, lineRange.head)); + } + return {text: text, ranges: ranges} + } + + function disableBrowserMagic(field, spellcheck, autocorrect, autocapitalize) { + field.setAttribute("autocorrect", autocorrect ? "" : "off"); + field.setAttribute("autocapitalize", autocapitalize ? "" : "off"); + field.setAttribute("spellcheck", !!spellcheck); + } + + function hiddenTextarea() { + var te = elt("textarea", null, null, "position: absolute; bottom: -1em; padding: 0; width: 1px; height: 1em; outline: none"); + var div = elt("div", [te], null, "overflow: hidden; position: relative; width: 3px; height: 0px;"); + // The textarea is kept positioned near the cursor to prevent the + // fact that it'll be scrolled into view on input from scrolling + // our fake cursor out of view. On webkit, when wrap=off, paste is + // very slow. So make the area wide instead. + if (webkit) { te.style.width = "1000px"; } + else { te.setAttribute("wrap", "off"); } + // If border: 0; -- iOS fails to open keyboard (issue #1287) + if (ios) { te.style.border = "1px solid black"; } + disableBrowserMagic(te); + return div + } + + // The publicly visible API. Note that methodOp(f) means + // 'wrap f in an operation, performed on its `this` parameter'. + + // This is not the complete set of editor methods. Most of the + // methods defined on the Doc type are also injected into + // CodeMirror.prototype, for backwards compatibility and + // convenience. + + function addEditorMethods(CodeMirror) { + var optionHandlers = CodeMirror.optionHandlers; + + var helpers = CodeMirror.helpers = {}; + + CodeMirror.prototype = { + constructor: CodeMirror, + focus: function(){window.focus(); this.display.input.focus();}, + + setOption: function(option, value) { + var options = this.options, old = options[option]; + if (options[option] == value && option != "mode") { return } + options[option] = value; + if (optionHandlers.hasOwnProperty(option)) + { operation(this, optionHandlers[option])(this, value, old); } + signal(this, "optionChange", this, option); + }, + + getOption: function(option) {return this.options[option]}, + getDoc: function() {return this.doc}, + + addKeyMap: function(map, bottom) { + this.state.keyMaps[bottom ? "push" : "unshift"](getKeyMap(map)); + }, + removeKeyMap: function(map) { + var maps = this.state.keyMaps; + for (var i = 0; i < maps.length; ++i) + { if (maps[i] == map || maps[i].name == map) { + maps.splice(i, 1); + return true + } } + }, + + addOverlay: methodOp(function(spec, options) { + var mode = spec.token ? spec : CodeMirror.getMode(this.options, spec); + if (mode.startState) { throw new Error("Overlays may not be stateful.") } + insertSorted(this.state.overlays, + {mode: mode, modeSpec: spec, opaque: options && options.opaque, + priority: (options && options.priority) || 0}, + function (overlay) { return overlay.priority; }); + this.state.modeGen++; + regChange(this); + }), + removeOverlay: methodOp(function(spec) { + var overlays = this.state.overlays; + for (var i = 0; i < overlays.length; ++i) { + var cur = overlays[i].modeSpec; + if (cur == spec || typeof spec == "string" && cur.name == spec) { + overlays.splice(i, 1); + this.state.modeGen++; + regChange(this); + return + } + } + }), + + indentLine: methodOp(function(n, dir, aggressive) { + if (typeof dir != "string" && typeof dir != "number") { + if (dir == null) { dir = this.options.smartIndent ? "smart" : "prev"; } + else { dir = dir ? "add" : "subtract"; } + } + if (isLine(this.doc, n)) { indentLine(this, n, dir, aggressive); } + }), + indentSelection: methodOp(function(how) { + var ranges = this.doc.sel.ranges, end = -1; + for (var i = 0; i < ranges.length; i++) { + var range = ranges[i]; + if (!range.empty()) { + var from = range.from(), to = range.to(); + var start = Math.max(end, from.line); + end = Math.min(this.lastLine(), to.line - (to.ch ? 0 : 1)) + 1; + for (var j = start; j < end; ++j) + { indentLine(this, j, how); } + var newRanges = this.doc.sel.ranges; + if (from.ch == 0 && ranges.length == newRanges.length && newRanges[i].from().ch > 0) + { replaceOneSelection(this.doc, i, new Range(from, newRanges[i].to()), sel_dontScroll); } + } else if (range.head.line > end) { + indentLine(this, range.head.line, how, true); + end = range.head.line; + if (i == this.doc.sel.primIndex) { ensureCursorVisible(this); } + } + } + }), + + // Fetch the parser token for a given character. Useful for hacks + // that want to inspect the mode state (say, for completion). + getTokenAt: function(pos, precise) { + return takeToken(this, pos, precise) + }, + + getLineTokens: function(line, precise) { + return takeToken(this, Pos(line), precise, true) + }, + + getTokenTypeAt: function(pos) { + pos = clipPos(this.doc, pos); + var styles = getLineStyles(this, getLine(this.doc, pos.line)); + var before = 0, after = (styles.length - 1) / 2, ch = pos.ch; + var type; + if (ch == 0) { type = styles[2]; } + else { for (;;) { + var mid = (before + after) >> 1; + if ((mid ? styles[mid * 2 - 1] : 0) >= ch) { after = mid; } + else if (styles[mid * 2 + 1] < ch) { before = mid + 1; } + else { type = styles[mid * 2 + 2]; break } + } } + var cut = type ? type.indexOf("overlay ") : -1; + return cut < 0 ? type : cut == 0 ? null : type.slice(0, cut - 1) + }, + + getModeAt: function(pos) { + var mode = this.doc.mode; + if (!mode.innerMode) { return mode } + return CodeMirror.innerMode(mode, this.getTokenAt(pos).state).mode + }, + + getHelper: function(pos, type) { + return this.getHelpers(pos, type)[0] + }, + + getHelpers: function(pos, type) { + var found = []; + if (!helpers.hasOwnProperty(type)) { return found } + var help = helpers[type], mode = this.getModeAt(pos); + if (typeof mode[type] == "string") { + if (help[mode[type]]) { found.push(help[mode[type]]); } + } else if (mode[type]) { + for (var i = 0; i < mode[type].length; i++) { + var val = help[mode[type][i]]; + if (val) { found.push(val); } + } + } else if (mode.helperType && help[mode.helperType]) { + found.push(help[mode.helperType]); + } else if (help[mode.name]) { + found.push(help[mode.name]); + } + for (var i$1 = 0; i$1 < help._global.length; i$1++) { + var cur = help._global[i$1]; + if (cur.pred(mode, this) && indexOf(found, cur.val) == -1) + { found.push(cur.val); } + } + return found + }, + + getStateAfter: function(line, precise) { + var doc = this.doc; + line = clipLine(doc, line == null ? doc.first + doc.size - 1: line); + return getContextBefore(this, line + 1, precise).state + }, + + cursorCoords: function(start, mode) { + var pos, range = this.doc.sel.primary(); + if (start == null) { pos = range.head; } + else if (typeof start == "object") { pos = clipPos(this.doc, start); } + else { pos = start ? range.from() : range.to(); } + return cursorCoords(this, pos, mode || "page") + }, + + charCoords: function(pos, mode) { + return charCoords(this, clipPos(this.doc, pos), mode || "page") + }, + + coordsChar: function(coords, mode) { + coords = fromCoordSystem(this, coords, mode || "page"); + return coordsChar(this, coords.left, coords.top) + }, + + lineAtHeight: function(height, mode) { + height = fromCoordSystem(this, {top: height, left: 0}, mode || "page").top; + return lineAtHeight(this.doc, height + this.display.viewOffset) + }, + heightAtLine: function(line, mode, includeWidgets) { + var end = false, lineObj; + if (typeof line == "number") { + var last = this.doc.first + this.doc.size - 1; + if (line < this.doc.first) { line = this.doc.first; } + else if (line > last) { line = last; end = true; } + lineObj = getLine(this.doc, line); + } else { + lineObj = line; + } + return intoCoordSystem(this, lineObj, {top: 0, left: 0}, mode || "page", includeWidgets || end).top + + (end ? this.doc.height - heightAtLine(lineObj) : 0) + }, + + defaultTextHeight: function() { return textHeight(this.display) }, + defaultCharWidth: function() { return charWidth(this.display) }, + + getViewport: function() { return {from: this.display.viewFrom, to: this.display.viewTo}}, + + addWidget: function(pos, node, scroll, vert, horiz) { + var display = this.display; + pos = cursorCoords(this, clipPos(this.doc, pos)); + var top = pos.bottom, left = pos.left; + node.style.position = "absolute"; + node.setAttribute("cm-ignore-events", "true"); + this.display.input.setUneditable(node); + display.sizer.appendChild(node); + if (vert == "over") { + top = pos.top; + } else if (vert == "above" || vert == "near") { + var vspace = Math.max(display.wrapper.clientHeight, this.doc.height), + hspace = Math.max(display.sizer.clientWidth, display.lineSpace.clientWidth); + // Default to positioning above (if specified and possible); otherwise default to positioning below + if ((vert == 'above' || pos.bottom + node.offsetHeight > vspace) && pos.top > node.offsetHeight) + { top = pos.top - node.offsetHeight; } + else if (pos.bottom + node.offsetHeight <= vspace) + { top = pos.bottom; } + if (left + node.offsetWidth > hspace) + { left = hspace - node.offsetWidth; } + } + node.style.top = top + "px"; + node.style.left = node.style.right = ""; + if (horiz == "right") { + left = display.sizer.clientWidth - node.offsetWidth; + node.style.right = "0px"; + } else { + if (horiz == "left") { left = 0; } + else if (horiz == "middle") { left = (display.sizer.clientWidth - node.offsetWidth) / 2; } + node.style.left = left + "px"; + } + if (scroll) + { scrollIntoView(this, {left: left, top: top, right: left + node.offsetWidth, bottom: top + node.offsetHeight}); } + }, + + triggerOnKeyDown: methodOp(onKeyDown), + triggerOnKeyPress: methodOp(onKeyPress), + triggerOnKeyUp: onKeyUp, + triggerOnMouseDown: methodOp(onMouseDown), + + execCommand: function(cmd) { + if (commands.hasOwnProperty(cmd)) + { return commands[cmd].call(null, this) } + }, + + triggerElectric: methodOp(function(text) { triggerElectric(this, text); }), + + findPosH: function(from, amount, unit, visually) { + var dir = 1; + if (amount < 0) { dir = -1; amount = -amount; } + var cur = clipPos(this.doc, from); + for (var i = 0; i < amount; ++i) { + cur = findPosH(this.doc, cur, dir, unit, visually); + if (cur.hitSide) { break } + } + return cur + }, + + moveH: methodOp(function(dir, unit) { + var this$1 = this; + + this.extendSelectionsBy(function (range) { + if (this$1.display.shift || this$1.doc.extend || range.empty()) + { return findPosH(this$1.doc, range.head, dir, unit, this$1.options.rtlMoveVisually) } + else + { return dir < 0 ? range.from() : range.to() } + }, sel_move); + }), + + deleteH: methodOp(function(dir, unit) { + var sel = this.doc.sel, doc = this.doc; + if (sel.somethingSelected()) + { doc.replaceSelection("", null, "+delete"); } + else + { deleteNearSelection(this, function (range) { + var other = findPosH(doc, range.head, dir, unit, false); + return dir < 0 ? {from: other, to: range.head} : {from: range.head, to: other} + }); } + }), + + findPosV: function(from, amount, unit, goalColumn) { + var dir = 1, x = goalColumn; + if (amount < 0) { dir = -1; amount = -amount; } + var cur = clipPos(this.doc, from); + for (var i = 0; i < amount; ++i) { + var coords = cursorCoords(this, cur, "div"); + if (x == null) { x = coords.left; } + else { coords.left = x; } + cur = findPosV(this, coords, dir, unit); + if (cur.hitSide) { break } + } + return cur + }, + + moveV: methodOp(function(dir, unit) { + var this$1 = this; + + var doc = this.doc, goals = []; + var collapse = !this.display.shift && !doc.extend && doc.sel.somethingSelected(); + doc.extendSelectionsBy(function (range) { + if (collapse) + { return dir < 0 ? range.from() : range.to() } + var headPos = cursorCoords(this$1, range.head, "div"); + if (range.goalColumn != null) { headPos.left = range.goalColumn; } + goals.push(headPos.left); + var pos = findPosV(this$1, headPos, dir, unit); + if (unit == "page" && range == doc.sel.primary()) + { addToScrollTop(this$1, charCoords(this$1, pos, "div").top - headPos.top); } + return pos + }, sel_move); + if (goals.length) { for (var i = 0; i < doc.sel.ranges.length; i++) + { doc.sel.ranges[i].goalColumn = goals[i]; } } + }), + + // Find the word at the given position (as returned by coordsChar). + findWordAt: function(pos) { + var doc = this.doc, line = getLine(doc, pos.line).text; + var start = pos.ch, end = pos.ch; + if (line) { + var helper = this.getHelper(pos, "wordChars"); + if ((pos.sticky == "before" || end == line.length) && start) { --start; } else { ++end; } + var startChar = line.charAt(start); + var check = isWordChar(startChar, helper) + ? function (ch) { return isWordChar(ch, helper); } + : /\s/.test(startChar) ? function (ch) { return /\s/.test(ch); } + : function (ch) { return (!/\s/.test(ch) && !isWordChar(ch)); }; + while (start > 0 && check(line.charAt(start - 1))) { --start; } + while (end < line.length && check(line.charAt(end))) { ++end; } + } + return new Range(Pos(pos.line, start), Pos(pos.line, end)) + }, + + toggleOverwrite: function(value) { + if (value != null && value == this.state.overwrite) { return } + if (this.state.overwrite = !this.state.overwrite) + { addClass(this.display.cursorDiv, "CodeMirror-overwrite"); } + else + { rmClass(this.display.cursorDiv, "CodeMirror-overwrite"); } + + signal(this, "overwriteToggle", this, this.state.overwrite); + }, + hasFocus: function() { return this.display.input.getField() == activeElt() }, + isReadOnly: function() { return !!(this.options.readOnly || this.doc.cantEdit) }, + + scrollTo: methodOp(function (x, y) { scrollToCoords(this, x, y); }), + getScrollInfo: function() { + var scroller = this.display.scroller; + return {left: scroller.scrollLeft, top: scroller.scrollTop, + height: scroller.scrollHeight - scrollGap(this) - this.display.barHeight, + width: scroller.scrollWidth - scrollGap(this) - this.display.barWidth, + clientHeight: displayHeight(this), clientWidth: displayWidth(this)} + }, + + scrollIntoView: methodOp(function(range, margin) { + if (range == null) { + range = {from: this.doc.sel.primary().head, to: null}; + if (margin == null) { margin = this.options.cursorScrollMargin; } + } else if (typeof range == "number") { + range = {from: Pos(range, 0), to: null}; + } else if (range.from == null) { + range = {from: range, to: null}; + } + if (!range.to) { range.to = range.from; } + range.margin = margin || 0; + + if (range.from.line != null) { + scrollToRange(this, range); + } else { + scrollToCoordsRange(this, range.from, range.to, range.margin); + } + }), + + setSize: methodOp(function(width, height) { + var this$1 = this; + + var interpret = function (val) { return typeof val == "number" || /^\d+$/.test(String(val)) ? val + "px" : val; }; + if (width != null) { this.display.wrapper.style.width = interpret(width); } + if (height != null) { this.display.wrapper.style.height = interpret(height); } + if (this.options.lineWrapping) { clearLineMeasurementCache(this); } + var lineNo = this.display.viewFrom; + this.doc.iter(lineNo, this.display.viewTo, function (line) { + if (line.widgets) { for (var i = 0; i < line.widgets.length; i++) + { if (line.widgets[i].noHScroll) { regLineChange(this$1, lineNo, "widget"); break } } } + ++lineNo; + }); + this.curOp.forceUpdate = true; + signal(this, "refresh", this); + }), + + operation: function(f){return runInOp(this, f)}, + startOperation: function(){return startOperation(this)}, + endOperation: function(){return endOperation(this)}, + + refresh: methodOp(function() { + var oldHeight = this.display.cachedTextHeight; + regChange(this); + this.curOp.forceUpdate = true; + clearCaches(this); + scrollToCoords(this, this.doc.scrollLeft, this.doc.scrollTop); + updateGutterSpace(this.display); + if (oldHeight == null || Math.abs(oldHeight - textHeight(this.display)) > .5 || this.options.lineWrapping) + { estimateLineHeights(this); } + signal(this, "refresh", this); + }), + + swapDoc: methodOp(function(doc) { + var old = this.doc; + old.cm = null; + // Cancel the current text selection if any (#5821) + if (this.state.selectingText) { this.state.selectingText(); } + attachDoc(this, doc); + clearCaches(this); + this.display.input.reset(); + scrollToCoords(this, doc.scrollLeft, doc.scrollTop); + this.curOp.forceScroll = true; + signalLater(this, "swapDoc", this, old); + return old + }), + + phrase: function(phraseText) { + var phrases = this.options.phrases; + return phrases && Object.prototype.hasOwnProperty.call(phrases, phraseText) ? phrases[phraseText] : phraseText + }, + + getInputField: function(){return this.display.input.getField()}, + getWrapperElement: function(){return this.display.wrapper}, + getScrollerElement: function(){return this.display.scroller}, + getGutterElement: function(){return this.display.gutters} + }; + eventMixin(CodeMirror); + + CodeMirror.registerHelper = function(type, name, value) { + if (!helpers.hasOwnProperty(type)) { helpers[type] = CodeMirror[type] = {_global: []}; } + helpers[type][name] = value; + }; + CodeMirror.registerGlobalHelper = function(type, name, predicate, value) { + CodeMirror.registerHelper(type, name, value); + helpers[type]._global.push({pred: predicate, val: value}); + }; + } + + // Used for horizontal relative motion. Dir is -1 or 1 (left or + // right), unit can be "codepoint", "char", "column" (like char, but + // doesn't cross line boundaries), "word" (across next word), or + // "group" (to the start of next group of word or + // non-word-non-whitespace chars). The visually param controls + // whether, in right-to-left text, direction 1 means to move towards + // the next index in the string, or towards the character to the right + // of the current position. The resulting position will have a + // hitSide=true property if it reached the end of the document. + function findPosH(doc, pos, dir, unit, visually) { + var oldPos = pos; + var origDir = dir; + var lineObj = getLine(doc, pos.line); + var lineDir = visually && doc.direction == "rtl" ? -dir : dir; + function findNextLine() { + var l = pos.line + lineDir; + if (l < doc.first || l >= doc.first + doc.size) { return false } + pos = new Pos(l, pos.ch, pos.sticky); + return lineObj = getLine(doc, l) + } + function moveOnce(boundToLine) { + var next; + if (unit == "codepoint") { + var ch = lineObj.text.charCodeAt(pos.ch + (unit > 0 ? 0 : -1)); + if (isNaN(ch)) { next = null; } + else { next = new Pos(pos.line, Math.max(0, Math.min(lineObj.text.length, pos.ch + dir * (ch >= 0xD800 && ch < 0xDC00 ? 2 : 1))), + -dir); } + } else if (visually) { + next = moveVisually(doc.cm, lineObj, pos, dir); + } else { + next = moveLogically(lineObj, pos, dir); + } + if (next == null) { + if (!boundToLine && findNextLine()) + { pos = endOfLine(visually, doc.cm, lineObj, pos.line, lineDir); } + else + { return false } + } else { + pos = next; + } + return true + } + + if (unit == "char" || unit == "codepoint") { + moveOnce(); + } else if (unit == "column") { + moveOnce(true); + } else if (unit == "word" || unit == "group") { + var sawType = null, group = unit == "group"; + var helper = doc.cm && doc.cm.getHelper(pos, "wordChars"); + for (var first = true;; first = false) { + if (dir < 0 && !moveOnce(!first)) { break } + var cur = lineObj.text.charAt(pos.ch) || "\n"; + var type = isWordChar(cur, helper) ? "w" + : group && cur == "\n" ? "n" + : !group || /\s/.test(cur) ? null + : "p"; + if (group && !first && !type) { type = "s"; } + if (sawType && sawType != type) { + if (dir < 0) {dir = 1; moveOnce(); pos.sticky = "after";} + break + } + + if (type) { sawType = type; } + if (dir > 0 && !moveOnce(!first)) { break } + } + } + var result = skipAtomic(doc, pos, oldPos, origDir, true); + if (equalCursorPos(oldPos, result)) { result.hitSide = true; } + return result + } + + // For relative vertical movement. Dir may be -1 or 1. Unit can be + // "page" or "line". The resulting position will have a hitSide=true + // property if it reached the end of the document. + function findPosV(cm, pos, dir, unit) { + var doc = cm.doc, x = pos.left, y; + if (unit == "page") { + var pageSize = Math.min(cm.display.wrapper.clientHeight, window.innerHeight || document.documentElement.clientHeight); + var moveAmount = Math.max(pageSize - .5 * textHeight(cm.display), 3); + y = (dir > 0 ? pos.bottom : pos.top) + dir * moveAmount; + + } else if (unit == "line") { + y = dir > 0 ? pos.bottom + 3 : pos.top - 3; + } + var target; + for (;;) { + target = coordsChar(cm, x, y); + if (!target.outside) { break } + if (dir < 0 ? y <= 0 : y >= doc.height) { target.hitSide = true; break } + y += dir * 5; + } + return target + } + + // CONTENTEDITABLE INPUT STYLE + + var ContentEditableInput = function(cm) { + this.cm = cm; + this.lastAnchorNode = this.lastAnchorOffset = this.lastFocusNode = this.lastFocusOffset = null; + this.polling = new Delayed(); + this.composing = null; + this.gracePeriod = false; + this.readDOMTimeout = null; + }; + + ContentEditableInput.prototype.init = function (display) { + var this$1 = this; + + var input = this, cm = input.cm; + var div = input.div = display.lineDiv; + disableBrowserMagic(div, cm.options.spellcheck, cm.options.autocorrect, cm.options.autocapitalize); + + function belongsToInput(e) { + for (var t = e.target; t; t = t.parentNode) { + if (t == div) { return true } + if (/\bCodeMirror-(?:line)?widget\b/.test(t.className)) { break } + } + return false + } + + on(div, "paste", function (e) { + if (!belongsToInput(e) || signalDOMEvent(cm, e) || handlePaste(e, cm)) { return } + // IE doesn't fire input events, so we schedule a read for the pasted content in this way + if (ie_version <= 11) { setTimeout(operation(cm, function () { return this$1.updateFromDOM(); }), 20); } + }); + + on(div, "compositionstart", function (e) { + this$1.composing = {data: e.data, done: false}; + }); + on(div, "compositionupdate", function (e) { + if (!this$1.composing) { this$1.composing = {data: e.data, done: false}; } + }); + on(div, "compositionend", function (e) { + if (this$1.composing) { + if (e.data != this$1.composing.data) { this$1.readFromDOMSoon(); } + this$1.composing.done = true; + } + }); + + on(div, "touchstart", function () { return input.forceCompositionEnd(); }); + + on(div, "input", function () { + if (!this$1.composing) { this$1.readFromDOMSoon(); } + }); + + function onCopyCut(e) { + if (!belongsToInput(e) || signalDOMEvent(cm, e)) { return } + if (cm.somethingSelected()) { + setLastCopied({lineWise: false, text: cm.getSelections()}); + if (e.type == "cut") { cm.replaceSelection("", null, "cut"); } + } else if (!cm.options.lineWiseCopyCut) { + return + } else { + var ranges = copyableRanges(cm); + setLastCopied({lineWise: true, text: ranges.text}); + if (e.type == "cut") { + cm.operation(function () { + cm.setSelections(ranges.ranges, 0, sel_dontScroll); + cm.replaceSelection("", null, "cut"); + }); + } + } + if (e.clipboardData) { + e.clipboardData.clearData(); + var content = lastCopied.text.join("\n"); + // iOS exposes the clipboard API, but seems to discard content inserted into it + e.clipboardData.setData("Text", content); + if (e.clipboardData.getData("Text") == content) { + e.preventDefault(); + return + } + } + // Old-fashioned briefly-focus-a-textarea hack + var kludge = hiddenTextarea(), te = kludge.firstChild; + cm.display.lineSpace.insertBefore(kludge, cm.display.lineSpace.firstChild); + te.value = lastCopied.text.join("\n"); + var hadFocus = document.activeElement; + selectInput(te); + setTimeout(function () { + cm.display.lineSpace.removeChild(kludge); + hadFocus.focus(); + if (hadFocus == div) { input.showPrimarySelection(); } + }, 50); + } + on(div, "copy", onCopyCut); + on(div, "cut", onCopyCut); + }; + + ContentEditableInput.prototype.screenReaderLabelChanged = function (label) { + // Label for screenreaders, accessibility + if(label) { + this.div.setAttribute('aria-label', label); + } else { + this.div.removeAttribute('aria-label'); + } + }; + + ContentEditableInput.prototype.prepareSelection = function () { + var result = prepareSelection(this.cm, false); + result.focus = document.activeElement == this.div; + return result + }; + + ContentEditableInput.prototype.showSelection = function (info, takeFocus) { + if (!info || !this.cm.display.view.length) { return } + if (info.focus || takeFocus) { this.showPrimarySelection(); } + this.showMultipleSelections(info); + }; + + ContentEditableInput.prototype.getSelection = function () { + return this.cm.display.wrapper.ownerDocument.getSelection() + }; + + ContentEditableInput.prototype.showPrimarySelection = function () { + var sel = this.getSelection(), cm = this.cm, prim = cm.doc.sel.primary(); + var from = prim.from(), to = prim.to(); + + if (cm.display.viewTo == cm.display.viewFrom || from.line >= cm.display.viewTo || to.line < cm.display.viewFrom) { + sel.removeAllRanges(); + return + } + + var curAnchor = domToPos(cm, sel.anchorNode, sel.anchorOffset); + var curFocus = domToPos(cm, sel.focusNode, sel.focusOffset); + if (curAnchor && !curAnchor.bad && curFocus && !curFocus.bad && + cmp(minPos(curAnchor, curFocus), from) == 0 && + cmp(maxPos(curAnchor, curFocus), to) == 0) + { return } + + var view = cm.display.view; + var start = (from.line >= cm.display.viewFrom && posToDOM(cm, from)) || + {node: view[0].measure.map[2], offset: 0}; + var end = to.line < cm.display.viewTo && posToDOM(cm, to); + if (!end) { + var measure = view[view.length - 1].measure; + var map = measure.maps ? measure.maps[measure.maps.length - 1] : measure.map; + end = {node: map[map.length - 1], offset: map[map.length - 2] - map[map.length - 3]}; + } + + if (!start || !end) { + sel.removeAllRanges(); + return + } + + var old = sel.rangeCount && sel.getRangeAt(0), rng; + try { rng = range(start.node, start.offset, end.offset, end.node); } + catch(e) {} // Our model of the DOM might be outdated, in which case the range we try to set can be impossible + if (rng) { + if (!gecko && cm.state.focused) { + sel.collapse(start.node, start.offset); + if (!rng.collapsed) { + sel.removeAllRanges(); + sel.addRange(rng); + } + } else { + sel.removeAllRanges(); + sel.addRange(rng); + } + if (old && sel.anchorNode == null) { sel.addRange(old); } + else if (gecko) { this.startGracePeriod(); } + } + this.rememberSelection(); + }; + + ContentEditableInput.prototype.startGracePeriod = function () { + var this$1 = this; + + clearTimeout(this.gracePeriod); + this.gracePeriod = setTimeout(function () { + this$1.gracePeriod = false; + if (this$1.selectionChanged()) + { this$1.cm.operation(function () { return this$1.cm.curOp.selectionChanged = true; }); } + }, 20); + }; + + ContentEditableInput.prototype.showMultipleSelections = function (info) { + removeChildrenAndAdd(this.cm.display.cursorDiv, info.cursors); + removeChildrenAndAdd(this.cm.display.selectionDiv, info.selection); + }; + + ContentEditableInput.prototype.rememberSelection = function () { + var sel = this.getSelection(); + this.lastAnchorNode = sel.anchorNode; this.lastAnchorOffset = sel.anchorOffset; + this.lastFocusNode = sel.focusNode; this.lastFocusOffset = sel.focusOffset; + }; + + ContentEditableInput.prototype.selectionInEditor = function () { + var sel = this.getSelection(); + if (!sel.rangeCount) { return false } + var node = sel.getRangeAt(0).commonAncestorContainer; + return contains(this.div, node) + }; + + ContentEditableInput.prototype.focus = function () { + if (this.cm.options.readOnly != "nocursor") { + if (!this.selectionInEditor() || document.activeElement != this.div) + { this.showSelection(this.prepareSelection(), true); } + this.div.focus(); + } + }; + ContentEditableInput.prototype.blur = function () { this.div.blur(); }; + ContentEditableInput.prototype.getField = function () { return this.div }; + + ContentEditableInput.prototype.supportsTouch = function () { return true }; + + ContentEditableInput.prototype.receivedFocus = function () { + var input = this; + if (this.selectionInEditor()) + { this.pollSelection(); } + else + { runInOp(this.cm, function () { return input.cm.curOp.selectionChanged = true; }); } + + function poll() { + if (input.cm.state.focused) { + input.pollSelection(); + input.polling.set(input.cm.options.pollInterval, poll); + } + } + this.polling.set(this.cm.options.pollInterval, poll); + }; + + ContentEditableInput.prototype.selectionChanged = function () { + var sel = this.getSelection(); + return sel.anchorNode != this.lastAnchorNode || sel.anchorOffset != this.lastAnchorOffset || + sel.focusNode != this.lastFocusNode || sel.focusOffset != this.lastFocusOffset + }; + + ContentEditableInput.prototype.pollSelection = function () { + if (this.readDOMTimeout != null || this.gracePeriod || !this.selectionChanged()) { return } + var sel = this.getSelection(), cm = this.cm; + // On Android Chrome (version 56, at least), backspacing into an + // uneditable block element will put the cursor in that element, + // and then, because it's not editable, hide the virtual keyboard. + // Because Android doesn't allow us to actually detect backspace + // presses in a sane way, this code checks for when that happens + // and simulates a backspace press in this case. + if (android && chrome && this.cm.display.gutterSpecs.length && isInGutter(sel.anchorNode)) { + this.cm.triggerOnKeyDown({type: "keydown", keyCode: 8, preventDefault: Math.abs}); + this.blur(); + this.focus(); + return + } + if (this.composing) { return } + this.rememberSelection(); + var anchor = domToPos(cm, sel.anchorNode, sel.anchorOffset); + var head = domToPos(cm, sel.focusNode, sel.focusOffset); + if (anchor && head) { runInOp(cm, function () { + setSelection(cm.doc, simpleSelection(anchor, head), sel_dontScroll); + if (anchor.bad || head.bad) { cm.curOp.selectionChanged = true; } + }); } + }; + + ContentEditableInput.prototype.pollContent = function () { + if (this.readDOMTimeout != null) { + clearTimeout(this.readDOMTimeout); + this.readDOMTimeout = null; + } + + var cm = this.cm, display = cm.display, sel = cm.doc.sel.primary(); + var from = sel.from(), to = sel.to(); + if (from.ch == 0 && from.line > cm.firstLine()) + { from = Pos(from.line - 1, getLine(cm.doc, from.line - 1).length); } + if (to.ch == getLine(cm.doc, to.line).text.length && to.line < cm.lastLine()) + { to = Pos(to.line + 1, 0); } + if (from.line < display.viewFrom || to.line > display.viewTo - 1) { return false } + + var fromIndex, fromLine, fromNode; + if (from.line == display.viewFrom || (fromIndex = findViewIndex(cm, from.line)) == 0) { + fromLine = lineNo(display.view[0].line); + fromNode = display.view[0].node; + } else { + fromLine = lineNo(display.view[fromIndex].line); + fromNode = display.view[fromIndex - 1].node.nextSibling; + } + var toIndex = findViewIndex(cm, to.line); + var toLine, toNode; + if (toIndex == display.view.length - 1) { + toLine = display.viewTo - 1; + toNode = display.lineDiv.lastChild; + } else { + toLine = lineNo(display.view[toIndex + 1].line) - 1; + toNode = display.view[toIndex + 1].node.previousSibling; + } + + if (!fromNode) { return false } + var newText = cm.doc.splitLines(domTextBetween(cm, fromNode, toNode, fromLine, toLine)); + var oldText = getBetween(cm.doc, Pos(fromLine, 0), Pos(toLine, getLine(cm.doc, toLine).text.length)); + while (newText.length > 1 && oldText.length > 1) { + if (lst(newText) == lst(oldText)) { newText.pop(); oldText.pop(); toLine--; } + else if (newText[0] == oldText[0]) { newText.shift(); oldText.shift(); fromLine++; } + else { break } + } + + var cutFront = 0, cutEnd = 0; + var newTop = newText[0], oldTop = oldText[0], maxCutFront = Math.min(newTop.length, oldTop.length); + while (cutFront < maxCutFront && newTop.charCodeAt(cutFront) == oldTop.charCodeAt(cutFront)) + { ++cutFront; } + var newBot = lst(newText), oldBot = lst(oldText); + var maxCutEnd = Math.min(newBot.length - (newText.length == 1 ? cutFront : 0), + oldBot.length - (oldText.length == 1 ? cutFront : 0)); + while (cutEnd < maxCutEnd && + newBot.charCodeAt(newBot.length - cutEnd - 1) == oldBot.charCodeAt(oldBot.length - cutEnd - 1)) + { ++cutEnd; } + // Try to move start of change to start of selection if ambiguous + if (newText.length == 1 && oldText.length == 1 && fromLine == from.line) { + while (cutFront && cutFront > from.ch && + newBot.charCodeAt(newBot.length - cutEnd - 1) == oldBot.charCodeAt(oldBot.length - cutEnd - 1)) { + cutFront--; + cutEnd++; + } + } + + newText[newText.length - 1] = newBot.slice(0, newBot.length - cutEnd).replace(/^\u200b+/, ""); + newText[0] = newText[0].slice(cutFront).replace(/\u200b+$/, ""); + + var chFrom = Pos(fromLine, cutFront); + var chTo = Pos(toLine, oldText.length ? lst(oldText).length - cutEnd : 0); + if (newText.length > 1 || newText[0] || cmp(chFrom, chTo)) { + replaceRange(cm.doc, newText, chFrom, chTo, "+input"); + return true + } + }; + + ContentEditableInput.prototype.ensurePolled = function () { + this.forceCompositionEnd(); + }; + ContentEditableInput.prototype.reset = function () { + this.forceCompositionEnd(); + }; + ContentEditableInput.prototype.forceCompositionEnd = function () { + if (!this.composing) { return } + clearTimeout(this.readDOMTimeout); + this.composing = null; + this.updateFromDOM(); + this.div.blur(); + this.div.focus(); + }; + ContentEditableInput.prototype.readFromDOMSoon = function () { + var this$1 = this; + + if (this.readDOMTimeout != null) { return } + this.readDOMTimeout = setTimeout(function () { + this$1.readDOMTimeout = null; + if (this$1.composing) { + if (this$1.composing.done) { this$1.composing = null; } + else { return } + } + this$1.updateFromDOM(); + }, 80); + }; + + ContentEditableInput.prototype.updateFromDOM = function () { + var this$1 = this; + + if (this.cm.isReadOnly() || !this.pollContent()) + { runInOp(this.cm, function () { return regChange(this$1.cm); }); } + }; + + ContentEditableInput.prototype.setUneditable = function (node) { + node.contentEditable = "false"; + }; + + ContentEditableInput.prototype.onKeyPress = function (e) { + if (e.charCode == 0 || this.composing) { return } + e.preventDefault(); + if (!this.cm.isReadOnly()) + { operation(this.cm, applyTextInput)(this.cm, String.fromCharCode(e.charCode == null ? e.keyCode : e.charCode), 0); } + }; + + ContentEditableInput.prototype.readOnlyChanged = function (val) { + this.div.contentEditable = String(val != "nocursor"); + }; + + ContentEditableInput.prototype.onContextMenu = function () {}; + ContentEditableInput.prototype.resetPosition = function () {}; + + ContentEditableInput.prototype.needsContentAttribute = true; + + function posToDOM(cm, pos) { + var view = findViewForLine(cm, pos.line); + if (!view || view.hidden) { return null } + var line = getLine(cm.doc, pos.line); + var info = mapFromLineView(view, line, pos.line); + + var order = getOrder(line, cm.doc.direction), side = "left"; + if (order) { + var partPos = getBidiPartAt(order, pos.ch); + side = partPos % 2 ? "right" : "left"; + } + var result = nodeAndOffsetInLineMap(info.map, pos.ch, side); + result.offset = result.collapse == "right" ? result.end : result.start; + return result + } + + function isInGutter(node) { + for (var scan = node; scan; scan = scan.parentNode) + { if (/CodeMirror-gutter-wrapper/.test(scan.className)) { return true } } + return false + } + + function badPos(pos, bad) { if (bad) { pos.bad = true; } return pos } + + function domTextBetween(cm, from, to, fromLine, toLine) { + var text = "", closing = false, lineSep = cm.doc.lineSeparator(), extraLinebreak = false; + function recognizeMarker(id) { return function (marker) { return marker.id == id; } } + function close() { + if (closing) { + text += lineSep; + if (extraLinebreak) { text += lineSep; } + closing = extraLinebreak = false; + } + } + function addText(str) { + if (str) { + close(); + text += str; + } + } + function walk(node) { + if (node.nodeType == 1) { + var cmText = node.getAttribute("cm-text"); + if (cmText) { + addText(cmText); + return + } + var markerID = node.getAttribute("cm-marker"), range; + if (markerID) { + var found = cm.findMarks(Pos(fromLine, 0), Pos(toLine + 1, 0), recognizeMarker(+markerID)); + if (found.length && (range = found[0].find(0))) + { addText(getBetween(cm.doc, range.from, range.to).join(lineSep)); } + return + } + if (node.getAttribute("contenteditable") == "false") { return } + var isBlock = /^(pre|div|p|li|table|br)$/i.test(node.nodeName); + if (!/^br$/i.test(node.nodeName) && node.textContent.length == 0) { return } + + if (isBlock) { close(); } + for (var i = 0; i < node.childNodes.length; i++) + { walk(node.childNodes[i]); } + + if (/^(pre|p)$/i.test(node.nodeName)) { extraLinebreak = true; } + if (isBlock) { closing = true; } + } else if (node.nodeType == 3) { + addText(node.nodeValue.replace(/\u200b/g, "").replace(/\u00a0/g, " ")); + } + } + for (;;) { + walk(from); + if (from == to) { break } + from = from.nextSibling; + extraLinebreak = false; + } + return text + } + + function domToPos(cm, node, offset) { + var lineNode; + if (node == cm.display.lineDiv) { + lineNode = cm.display.lineDiv.childNodes[offset]; + if (!lineNode) { return badPos(cm.clipPos(Pos(cm.display.viewTo - 1)), true) } + node = null; offset = 0; + } else { + for (lineNode = node;; lineNode = lineNode.parentNode) { + if (!lineNode || lineNode == cm.display.lineDiv) { return null } + if (lineNode.parentNode && lineNode.parentNode == cm.display.lineDiv) { break } + } + } + for (var i = 0; i < cm.display.view.length; i++) { + var lineView = cm.display.view[i]; + if (lineView.node == lineNode) + { return locateNodeInLineView(lineView, node, offset) } + } + } + + function locateNodeInLineView(lineView, node, offset) { + var wrapper = lineView.text.firstChild, bad = false; + if (!node || !contains(wrapper, node)) { return badPos(Pos(lineNo(lineView.line), 0), true) } + if (node == wrapper) { + bad = true; + node = wrapper.childNodes[offset]; + offset = 0; + if (!node) { + var line = lineView.rest ? lst(lineView.rest) : lineView.line; + return badPos(Pos(lineNo(line), line.text.length), bad) + } + } + + var textNode = node.nodeType == 3 ? node : null, topNode = node; + if (!textNode && node.childNodes.length == 1 && node.firstChild.nodeType == 3) { + textNode = node.firstChild; + if (offset) { offset = textNode.nodeValue.length; } + } + while (topNode.parentNode != wrapper) { topNode = topNode.parentNode; } + var measure = lineView.measure, maps = measure.maps; + + function find(textNode, topNode, offset) { + for (var i = -1; i < (maps ? maps.length : 0); i++) { + var map = i < 0 ? measure.map : maps[i]; + for (var j = 0; j < map.length; j += 3) { + var curNode = map[j + 2]; + if (curNode == textNode || curNode == topNode) { + var line = lineNo(i < 0 ? lineView.line : lineView.rest[i]); + var ch = map[j] + offset; + if (offset < 0 || curNode != textNode) { ch = map[j + (offset ? 1 : 0)]; } + return Pos(line, ch) + } + } + } + } + var found = find(textNode, topNode, offset); + if (found) { return badPos(found, bad) } + + // FIXME this is all really shaky. might handle the few cases it needs to handle, but likely to cause problems + for (var after = topNode.nextSibling, dist = textNode ? textNode.nodeValue.length - offset : 0; after; after = after.nextSibling) { + found = find(after, after.firstChild, 0); + if (found) + { return badPos(Pos(found.line, found.ch - dist), bad) } + else + { dist += after.textContent.length; } + } + for (var before = topNode.previousSibling, dist$1 = offset; before; before = before.previousSibling) { + found = find(before, before.firstChild, -1); + if (found) + { return badPos(Pos(found.line, found.ch + dist$1), bad) } + else + { dist$1 += before.textContent.length; } + } + } + + // TEXTAREA INPUT STYLE + + var TextareaInput = function(cm) { + this.cm = cm; + // See input.poll and input.reset + this.prevInput = ""; + + // Flag that indicates whether we expect input to appear real soon + // now (after some event like 'keypress' or 'input') and are + // polling intensively. + this.pollingFast = false; + // Self-resetting timeout for the poller + this.polling = new Delayed(); + // Used to work around IE issue with selection being forgotten when focus moves away from textarea + this.hasSelection = false; + this.composing = null; + }; + + TextareaInput.prototype.init = function (display) { + var this$1 = this; + + var input = this, cm = this.cm; + this.createField(display); + var te = this.textarea; + + display.wrapper.insertBefore(this.wrapper, display.wrapper.firstChild); + + // Needed to hide big blue blinking cursor on Mobile Safari (doesn't seem to work in iOS 8 anymore) + if (ios) { te.style.width = "0px"; } + + on(te, "input", function () { + if (ie && ie_version >= 9 && this$1.hasSelection) { this$1.hasSelection = null; } + input.poll(); + }); + + on(te, "paste", function (e) { + if (signalDOMEvent(cm, e) || handlePaste(e, cm)) { return } + + cm.state.pasteIncoming = +new Date; + input.fastPoll(); + }); + + function prepareCopyCut(e) { + if (signalDOMEvent(cm, e)) { return } + if (cm.somethingSelected()) { + setLastCopied({lineWise: false, text: cm.getSelections()}); + } else if (!cm.options.lineWiseCopyCut) { + return + } else { + var ranges = copyableRanges(cm); + setLastCopied({lineWise: true, text: ranges.text}); + if (e.type == "cut") { + cm.setSelections(ranges.ranges, null, sel_dontScroll); + } else { + input.prevInput = ""; + te.value = ranges.text.join("\n"); + selectInput(te); + } + } + if (e.type == "cut") { cm.state.cutIncoming = +new Date; } + } + on(te, "cut", prepareCopyCut); + on(te, "copy", prepareCopyCut); + + on(display.scroller, "paste", function (e) { + if (eventInWidget(display, e) || signalDOMEvent(cm, e)) { return } + if (!te.dispatchEvent) { + cm.state.pasteIncoming = +new Date; + input.focus(); + return + } + + // Pass the `paste` event to the textarea so it's handled by its event listener. + var event = new Event("paste"); + event.clipboardData = e.clipboardData; + te.dispatchEvent(event); + }); + + // Prevent normal selection in the editor (we handle our own) + on(display.lineSpace, "selectstart", function (e) { + if (!eventInWidget(display, e)) { e_preventDefault(e); } + }); + + on(te, "compositionstart", function () { + var start = cm.getCursor("from"); + if (input.composing) { input.composing.range.clear(); } + input.composing = { + start: start, + range: cm.markText(start, cm.getCursor("to"), {className: "CodeMirror-composing"}) + }; + }); + on(te, "compositionend", function () { + if (input.composing) { + input.poll(); + input.composing.range.clear(); + input.composing = null; + } + }); + }; + + TextareaInput.prototype.createField = function (_display) { + // Wraps and hides input textarea + this.wrapper = hiddenTextarea(); + // The semihidden textarea that is focused when the editor is + // focused, and receives input. + this.textarea = this.wrapper.firstChild; + }; + + TextareaInput.prototype.screenReaderLabelChanged = function (label) { + // Label for screenreaders, accessibility + if(label) { + this.textarea.setAttribute('aria-label', label); + } else { + this.textarea.removeAttribute('aria-label'); + } + }; + + TextareaInput.prototype.prepareSelection = function () { + // Redraw the selection and/or cursor + var cm = this.cm, display = cm.display, doc = cm.doc; + var result = prepareSelection(cm); + + // Move the hidden textarea near the cursor to prevent scrolling artifacts + if (cm.options.moveInputWithCursor) { + var headPos = cursorCoords(cm, doc.sel.primary().head, "div"); + var wrapOff = display.wrapper.getBoundingClientRect(), lineOff = display.lineDiv.getBoundingClientRect(); + result.teTop = Math.max(0, Math.min(display.wrapper.clientHeight - 10, + headPos.top + lineOff.top - wrapOff.top)); + result.teLeft = Math.max(0, Math.min(display.wrapper.clientWidth - 10, + headPos.left + lineOff.left - wrapOff.left)); + } + + return result + }; + + TextareaInput.prototype.showSelection = function (drawn) { + var cm = this.cm, display = cm.display; + removeChildrenAndAdd(display.cursorDiv, drawn.cursors); + removeChildrenAndAdd(display.selectionDiv, drawn.selection); + if (drawn.teTop != null) { + this.wrapper.style.top = drawn.teTop + "px"; + this.wrapper.style.left = drawn.teLeft + "px"; + } + }; + + // Reset the input to correspond to the selection (or to be empty, + // when not typing and nothing is selected) + TextareaInput.prototype.reset = function (typing) { + if (this.contextMenuPending || this.composing) { return } + var cm = this.cm; + if (cm.somethingSelected()) { + this.prevInput = ""; + var content = cm.getSelection(); + this.textarea.value = content; + if (cm.state.focused) { selectInput(this.textarea); } + if (ie && ie_version >= 9) { this.hasSelection = content; } + } else if (!typing) { + this.prevInput = this.textarea.value = ""; + if (ie && ie_version >= 9) { this.hasSelection = null; } + } + }; + + TextareaInput.prototype.getField = function () { return this.textarea }; + + TextareaInput.prototype.supportsTouch = function () { return false }; + + TextareaInput.prototype.focus = function () { + if (this.cm.options.readOnly != "nocursor" && (!mobile || activeElt() != this.textarea)) { + try { this.textarea.focus(); } + catch (e) {} // IE8 will throw if the textarea is display: none or not in DOM + } + }; + + TextareaInput.prototype.blur = function () { this.textarea.blur(); }; + + TextareaInput.prototype.resetPosition = function () { + this.wrapper.style.top = this.wrapper.style.left = 0; + }; + + TextareaInput.prototype.receivedFocus = function () { this.slowPoll(); }; + + // Poll for input changes, using the normal rate of polling. This + // runs as long as the editor is focused. + TextareaInput.prototype.slowPoll = function () { + var this$1 = this; + + if (this.pollingFast) { return } + this.polling.set(this.cm.options.pollInterval, function () { + this$1.poll(); + if (this$1.cm.state.focused) { this$1.slowPoll(); } + }); + }; + + // When an event has just come in that is likely to add or change + // something in the input textarea, we poll faster, to ensure that + // the change appears on the screen quickly. + TextareaInput.prototype.fastPoll = function () { + var missed = false, input = this; + input.pollingFast = true; + function p() { + var changed = input.poll(); + if (!changed && !missed) {missed = true; input.polling.set(60, p);} + else {input.pollingFast = false; input.slowPoll();} + } + input.polling.set(20, p); + }; + + // Read input from the textarea, and update the document to match. + // When something is selected, it is present in the textarea, and + // selected (unless it is huge, in which case a placeholder is + // used). When nothing is selected, the cursor sits after previously + // seen text (can be empty), which is stored in prevInput (we must + // not reset the textarea when typing, because that breaks IME). + TextareaInput.prototype.poll = function () { + var this$1 = this; + + var cm = this.cm, input = this.textarea, prevInput = this.prevInput; + // Since this is called a *lot*, try to bail out as cheaply as + // possible when it is clear that nothing happened. hasSelection + // will be the case when there is a lot of text in the textarea, + // in which case reading its value would be expensive. + if (this.contextMenuPending || !cm.state.focused || + (hasSelection(input) && !prevInput && !this.composing) || + cm.isReadOnly() || cm.options.disableInput || cm.state.keySeq) + { return false } + + var text = input.value; + // If nothing changed, bail. + if (text == prevInput && !cm.somethingSelected()) { return false } + // Work around nonsensical selection resetting in IE9/10, and + // inexplicable appearance of private area unicode characters on + // some key combos in Mac (#2689). + if (ie && ie_version >= 9 && this.hasSelection === text || + mac && /[\uf700-\uf7ff]/.test(text)) { + cm.display.input.reset(); + return false + } + + if (cm.doc.sel == cm.display.selForContextMenu) { + var first = text.charCodeAt(0); + if (first == 0x200b && !prevInput) { prevInput = "\u200b"; } + if (first == 0x21da) { this.reset(); return this.cm.execCommand("undo") } + } + // Find the part of the input that is actually new + var same = 0, l = Math.min(prevInput.length, text.length); + while (same < l && prevInput.charCodeAt(same) == text.charCodeAt(same)) { ++same; } + + runInOp(cm, function () { + applyTextInput(cm, text.slice(same), prevInput.length - same, + null, this$1.composing ? "*compose" : null); + + // Don't leave long text in the textarea, since it makes further polling slow + if (text.length > 1000 || text.indexOf("\n") > -1) { input.value = this$1.prevInput = ""; } + else { this$1.prevInput = text; } + + if (this$1.composing) { + this$1.composing.range.clear(); + this$1.composing.range = cm.markText(this$1.composing.start, cm.getCursor("to"), + {className: "CodeMirror-composing"}); + } + }); + return true + }; + + TextareaInput.prototype.ensurePolled = function () { + if (this.pollingFast && this.poll()) { this.pollingFast = false; } + }; + + TextareaInput.prototype.onKeyPress = function () { + if (ie && ie_version >= 9) { this.hasSelection = null; } + this.fastPoll(); + }; + + TextareaInput.prototype.onContextMenu = function (e) { + var input = this, cm = input.cm, display = cm.display, te = input.textarea; + if (input.contextMenuPending) { input.contextMenuPending(); } + var pos = posFromMouse(cm, e), scrollPos = display.scroller.scrollTop; + if (!pos || presto) { return } // Opera is difficult. + + // Reset the current text selection only if the click is done outside of the selection + // and 'resetSelectionOnContextMenu' option is true. + var reset = cm.options.resetSelectionOnContextMenu; + if (reset && cm.doc.sel.contains(pos) == -1) + { operation(cm, setSelection)(cm.doc, simpleSelection(pos), sel_dontScroll); } + + var oldCSS = te.style.cssText, oldWrapperCSS = input.wrapper.style.cssText; + var wrapperBox = input.wrapper.offsetParent.getBoundingClientRect(); + input.wrapper.style.cssText = "position: static"; + te.style.cssText = "position: absolute; width: 30px; height: 30px;\n top: " + (e.clientY - wrapperBox.top - 5) + "px; left: " + (e.clientX - wrapperBox.left - 5) + "px;\n z-index: 1000; background: " + (ie ? "rgba(255, 255, 255, .05)" : "transparent") + ";\n outline: none; border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);"; + var oldScrollY; + if (webkit) { oldScrollY = window.scrollY; } // Work around Chrome issue (#2712) + display.input.focus(); + if (webkit) { window.scrollTo(null, oldScrollY); } + display.input.reset(); + // Adds "Select all" to context menu in FF + if (!cm.somethingSelected()) { te.value = input.prevInput = " "; } + input.contextMenuPending = rehide; + display.selForContextMenu = cm.doc.sel; + clearTimeout(display.detectingSelectAll); + + // Select-all will be greyed out if there's nothing to select, so + // this adds a zero-width space so that we can later check whether + // it got selected. + function prepareSelectAllHack() { + if (te.selectionStart != null) { + var selected = cm.somethingSelected(); + var extval = "\u200b" + (selected ? te.value : ""); + te.value = "\u21da"; // Used to catch context-menu undo + te.value = extval; + input.prevInput = selected ? "" : "\u200b"; + te.selectionStart = 1; te.selectionEnd = extval.length; + // Re-set this, in case some other handler touched the + // selection in the meantime. + display.selForContextMenu = cm.doc.sel; + } + } + function rehide() { + if (input.contextMenuPending != rehide) { return } + input.contextMenuPending = false; + input.wrapper.style.cssText = oldWrapperCSS; + te.style.cssText = oldCSS; + if (ie && ie_version < 9) { display.scrollbars.setScrollTop(display.scroller.scrollTop = scrollPos); } + + // Try to detect the user choosing select-all + if (te.selectionStart != null) { + if (!ie || (ie && ie_version < 9)) { prepareSelectAllHack(); } + var i = 0, poll = function () { + if (display.selForContextMenu == cm.doc.sel && te.selectionStart == 0 && + te.selectionEnd > 0 && input.prevInput == "\u200b") { + operation(cm, selectAll)(cm); + } else if (i++ < 10) { + display.detectingSelectAll = setTimeout(poll, 500); + } else { + display.selForContextMenu = null; + display.input.reset(); + } + }; + display.detectingSelectAll = setTimeout(poll, 200); + } + } + + if (ie && ie_version >= 9) { prepareSelectAllHack(); } + if (captureRightClick) { + e_stop(e); + var mouseup = function () { + off(window, "mouseup", mouseup); + setTimeout(rehide, 20); + }; + on(window, "mouseup", mouseup); + } else { + setTimeout(rehide, 50); + } + }; + + TextareaInput.prototype.readOnlyChanged = function (val) { + if (!val) { this.reset(); } + this.textarea.disabled = val == "nocursor"; + this.textarea.readOnly = !!val; + }; + + TextareaInput.prototype.setUneditable = function () {}; + + TextareaInput.prototype.needsContentAttribute = false; + + function fromTextArea(textarea, options) { + options = options ? copyObj(options) : {}; + options.value = textarea.value; + if (!options.tabindex && textarea.tabIndex) + { options.tabindex = textarea.tabIndex; } + if (!options.placeholder && textarea.placeholder) + { options.placeholder = textarea.placeholder; } + // Set autofocus to true if this textarea is focused, or if it has + // autofocus and no other element is focused. + if (options.autofocus == null) { + var hasFocus = activeElt(); + options.autofocus = hasFocus == textarea || + textarea.getAttribute("autofocus") != null && hasFocus == document.body; + } + + function save() {textarea.value = cm.getValue();} + + var realSubmit; + if (textarea.form) { + on(textarea.form, "submit", save); + // Deplorable hack to make the submit method do the right thing. + if (!options.leaveSubmitMethodAlone) { + var form = textarea.form; + realSubmit = form.submit; + try { + var wrappedSubmit = form.submit = function () { + save(); + form.submit = realSubmit; + form.submit(); + form.submit = wrappedSubmit; + }; + } catch(e) {} + } + } + + options.finishInit = function (cm) { + cm.save = save; + cm.getTextArea = function () { return textarea; }; + cm.toTextArea = function () { + cm.toTextArea = isNaN; // Prevent this from being ran twice + save(); + textarea.parentNode.removeChild(cm.getWrapperElement()); + textarea.style.display = ""; + if (textarea.form) { + off(textarea.form, "submit", save); + if (!options.leaveSubmitMethodAlone && typeof textarea.form.submit == "function") + { textarea.form.submit = realSubmit; } + } + }; + }; + + textarea.style.display = "none"; + var cm = CodeMirror(function (node) { return textarea.parentNode.insertBefore(node, textarea.nextSibling); }, + options); + return cm + } + + function addLegacyProps(CodeMirror) { + CodeMirror.off = off; + CodeMirror.on = on; + CodeMirror.wheelEventPixels = wheelEventPixels; + CodeMirror.Doc = Doc; + CodeMirror.splitLines = splitLinesAuto; + CodeMirror.countColumn = countColumn; + CodeMirror.findColumn = findColumn; + CodeMirror.isWordChar = isWordCharBasic; + CodeMirror.Pass = Pass; + CodeMirror.signal = signal; + CodeMirror.Line = Line; + CodeMirror.changeEnd = changeEnd; + CodeMirror.scrollbarModel = scrollbarModel; + CodeMirror.Pos = Pos; + CodeMirror.cmpPos = cmp; + CodeMirror.modes = modes; + CodeMirror.mimeModes = mimeModes; + CodeMirror.resolveMode = resolveMode; + CodeMirror.getMode = getMode; + CodeMirror.modeExtensions = modeExtensions; + CodeMirror.extendMode = extendMode; + CodeMirror.copyState = copyState; + CodeMirror.startState = startState; + CodeMirror.innerMode = innerMode; + CodeMirror.commands = commands; + CodeMirror.keyMap = keyMap; + CodeMirror.keyName = keyName; + CodeMirror.isModifierKey = isModifierKey; + CodeMirror.lookupKey = lookupKey; + CodeMirror.normalizeKeyMap = normalizeKeyMap; + CodeMirror.StringStream = StringStream; + CodeMirror.SharedTextMarker = SharedTextMarker; + CodeMirror.TextMarker = TextMarker; + CodeMirror.LineWidget = LineWidget; + CodeMirror.e_preventDefault = e_preventDefault; + CodeMirror.e_stopPropagation = e_stopPropagation; + CodeMirror.e_stop = e_stop; + CodeMirror.addClass = addClass; + CodeMirror.contains = contains; + CodeMirror.rmClass = rmClass; + CodeMirror.keyNames = keyNames; + } + + // EDITOR CONSTRUCTOR + + defineOptions(CodeMirror); + + addEditorMethods(CodeMirror); + + // Set up methods on CodeMirror's prototype to redirect to the editor's document. + var dontDelegate = "iter insert remove copy getEditor constructor".split(" "); + for (var prop in Doc.prototype) { if (Doc.prototype.hasOwnProperty(prop) && indexOf(dontDelegate, prop) < 0) + { CodeMirror.prototype[prop] = (function(method) { + return function() {return method.apply(this.doc, arguments)} + })(Doc.prototype[prop]); } } + + eventMixin(Doc); + CodeMirror.inputStyles = {"textarea": TextareaInput, "contenteditable": ContentEditableInput}; + + // Extra arguments are stored as the mode's dependencies, which is + // used by (legacy) mechanisms like loadmode.js to automatically + // load a mode. (Preferred mechanism is the require/define calls.) + CodeMirror.defineMode = function(name/*, mode, …*/) { + if (!CodeMirror.defaults.mode && name != "null") { CodeMirror.defaults.mode = name; } + defineMode.apply(this, arguments); + }; + + CodeMirror.defineMIME = defineMIME; + + // Minimal default mode. + CodeMirror.defineMode("null", function () { return ({token: function (stream) { return stream.skipToEnd(); }}); }); + CodeMirror.defineMIME("text/plain", "null"); + + // EXTENSIONS + + CodeMirror.defineExtension = function (name, func) { + CodeMirror.prototype[name] = func; + }; + CodeMirror.defineDocExtension = function (name, func) { + Doc.prototype[name] = func; + }; + + CodeMirror.fromTextArea = fromTextArea; + + addLegacyProps(CodeMirror); + + CodeMirror.version = "5.58.2"; + + return CodeMirror; + + }))); + }); - function getHandlers(emitter, type) { - return emitter._handlers && emitter._handlers[type] || noHandlers - } + var xml = createCommonjsModule(function (module, exports) { + // CodeMirror, copyright (c) by Marijn Haverbeke and others + // Distributed under an MIT license: https://codemirror.net/LICENSE + + (function(mod) { + mod(codemirror); + })(function(CodeMirror) { + + var htmlConfig = { + autoSelfClosers: {'area': true, 'base': true, 'br': true, 'col': true, 'command': true, + 'embed': true, 'frame': true, 'hr': true, 'img': true, 'input': true, + 'keygen': true, 'link': true, 'meta': true, 'param': true, 'source': true, + 'track': true, 'wbr': true, 'menuitem': true}, + implicitlyClosed: {'dd': true, 'li': true, 'optgroup': true, 'option': true, 'p': true, + 'rp': true, 'rt': true, 'tbody': true, 'td': true, 'tfoot': true, + 'th': true, 'tr': true}, + contextGrabbers: { + 'dd': {'dd': true, 'dt': true}, + 'dt': {'dd': true, 'dt': true}, + 'li': {'li': true}, + 'option': {'option': true, 'optgroup': true}, + 'optgroup': {'optgroup': true}, + 'p': {'address': true, 'article': true, 'aside': true, 'blockquote': true, 'dir': true, + 'div': true, 'dl': true, 'fieldset': true, 'footer': true, 'form': true, + 'h1': true, 'h2': true, 'h3': true, 'h4': true, 'h5': true, 'h6': true, + 'header': true, 'hgroup': true, 'hr': true, 'menu': true, 'nav': true, 'ol': true, + 'p': true, 'pre': true, 'section': true, 'table': true, 'ul': true}, + 'rp': {'rp': true, 'rt': true}, + 'rt': {'rp': true, 'rt': true}, + 'tbody': {'tbody': true, 'tfoot': true}, + 'td': {'td': true, 'th': true}, + 'tfoot': {'tbody': true}, + 'th': {'td': true, 'th': true}, + 'thead': {'tbody': true, 'tfoot': true}, + 'tr': {'tr': true} + }, + doNotIndent: {"pre": true}, + allowUnquoted: true, + allowMissing: true, + caseFold: true + }; - function off(emitter, type, f) { - if (emitter.removeEventListener) { - emitter.removeEventListener(type, f, false); - } else if (emitter.detachEvent) { - emitter.detachEvent("on" + type, f); - } else { - var map = emitter._handlers, arr = map && map[type]; - if (arr) { - var index = indexOf(arr, f); - if (index > -1) { map[type] = arr.slice(0, index).concat(arr.slice(index + 1)); } - } - } - } + var xmlConfig = { + autoSelfClosers: {}, + implicitlyClosed: {}, + contextGrabbers: {}, + doNotIndent: {}, + allowUnquoted: false, + allowMissing: false, + allowMissingTagName: false, + caseFold: false + }; - function signal(emitter, type /*, values...*/) { - var handlers = getHandlers(emitter, type); - if (!handlers.length) { return } - var args = Array.prototype.slice.call(arguments, 2); - for (var i = 0; i < handlers.length; ++i) { handlers[i].apply(null, args); } - } + CodeMirror.defineMode("xml", function(editorConf, config_) { + var indentUnit = editorConf.indentUnit; + var config = {}; + var defaults = config_.htmlMode ? htmlConfig : xmlConfig; + for (var prop in defaults) config[prop] = defaults[prop]; + for (var prop in config_) config[prop] = config_[prop]; + + // Return variables for tokenizers + var type, setStyle; + + function inText(stream, state) { + function chain(parser) { + state.tokenize = parser; + return parser(stream, state); + } + + var ch = stream.next(); + if (ch == "<") { + if (stream.eat("!")) { + if (stream.eat("[")) { + if (stream.match("CDATA[")) return chain(inBlock("atom", "]]>")); + else return null; + } else if (stream.match("--")) { + return chain(inBlock("comment", "-->")); + } else if (stream.match("DOCTYPE", true, true)) { + stream.eatWhile(/[\w\._\-]/); + return chain(doctype(1)); + } else { + return null; + } + } else if (stream.eat("?")) { + stream.eatWhile(/[\w\._\-]/); + state.tokenize = inBlock("meta", "?>"); + return "meta"; + } else { + type = stream.eat("/") ? "closeTag" : "openTag"; + state.tokenize = inTag; + return "tag bracket"; + } + } else if (ch == "&") { + var ok; + if (stream.eat("#")) { + if (stream.eat("x")) { + ok = stream.eatWhile(/[a-fA-F\d]/) && stream.eat(";"); + } else { + ok = stream.eatWhile(/[\d]/) && stream.eat(";"); + } + } else { + ok = stream.eatWhile(/[\w\.\-:]/) && stream.eat(";"); + } + return ok ? "atom" : "error"; + } else { + stream.eatWhile(/[^&<]/); + return null; + } + } + inText.isInText = true; + + function inTag(stream, state) { + var ch = stream.next(); + if (ch == ">" || (ch == "/" && stream.eat(">"))) { + state.tokenize = inText; + type = ch == ">" ? "endTag" : "selfcloseTag"; + return "tag bracket"; + } else if (ch == "=") { + type = "equals"; + return null; + } else if (ch == "<") { + state.tokenize = inText; + state.state = baseState; + state.tagName = state.tagStart = null; + var next = state.tokenize(stream, state); + return next ? next + " tag error" : "tag error"; + } else if (/[\'\"]/.test(ch)) { + state.tokenize = inAttribute(ch); + state.stringStartCol = stream.column(); + return state.tokenize(stream, state); + } else { + stream.match(/^[^\s\u00a0=<>\"\']*[^\s\u00a0=<>\"\'\/]/); + return "word"; + } + } + + function inAttribute(quote) { + var closure = function(stream, state) { + while (!stream.eol()) { + if (stream.next() == quote) { + state.tokenize = inTag; + break; + } + } + return "string"; + }; + closure.isInAttribute = true; + return closure; + } + + function inBlock(style, terminator) { + return function(stream, state) { + while (!stream.eol()) { + if (stream.match(terminator)) { + state.tokenize = inText; + break; + } + stream.next(); + } + return style; + } + } + + function doctype(depth) { + return function(stream, state) { + var ch; + while ((ch = stream.next()) != null) { + if (ch == "<") { + state.tokenize = doctype(depth + 1); + return state.tokenize(stream, state); + } else if (ch == ">") { + if (depth == 1) { + state.tokenize = inText; + break; + } else { + state.tokenize = doctype(depth - 1); + return state.tokenize(stream, state); + } + } + } + return "meta"; + }; + } + + function Context(state, tagName, startOfLine) { + this.prev = state.context; + this.tagName = tagName; + this.indent = state.indented; + this.startOfLine = startOfLine; + if (config.doNotIndent.hasOwnProperty(tagName) || (state.context && state.context.noIndent)) + this.noIndent = true; + } + function popContext(state) { + if (state.context) state.context = state.context.prev; + } + function maybePopContext(state, nextTagName) { + var parentTagName; + while (true) { + if (!state.context) { + return; + } + parentTagName = state.context.tagName; + if (!config.contextGrabbers.hasOwnProperty(parentTagName) || + !config.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) { + return; + } + popContext(state); + } + } + + function baseState(type, stream, state) { + if (type == "openTag") { + state.tagStart = stream.column(); + return tagNameState; + } else if (type == "closeTag") { + return closeTagNameState; + } else { + return baseState; + } + } + function tagNameState(type, stream, state) { + if (type == "word") { + state.tagName = stream.current(); + setStyle = "tag"; + return attrState; + } else if (config.allowMissingTagName && type == "endTag") { + setStyle = "tag bracket"; + return attrState(type, stream, state); + } else { + setStyle = "error"; + return tagNameState; + } + } + function closeTagNameState(type, stream, state) { + if (type == "word") { + var tagName = stream.current(); + if (state.context && state.context.tagName != tagName && + config.implicitlyClosed.hasOwnProperty(state.context.tagName)) + popContext(state); + if ((state.context && state.context.tagName == tagName) || config.matchClosing === false) { + setStyle = "tag"; + return closeState; + } else { + setStyle = "tag error"; + return closeStateErr; + } + } else if (config.allowMissingTagName && type == "endTag") { + setStyle = "tag bracket"; + return closeState(type, stream, state); + } else { + setStyle = "error"; + return closeStateErr; + } + } + + function closeState(type, _stream, state) { + if (type != "endTag") { + setStyle = "error"; + return closeState; + } + popContext(state); + return baseState; + } + function closeStateErr(type, stream, state) { + setStyle = "error"; + return closeState(type, stream, state); + } + + function attrState(type, _stream, state) { + if (type == "word") { + setStyle = "attribute"; + return attrEqState; + } else if (type == "endTag" || type == "selfcloseTag") { + var tagName = state.tagName, tagStart = state.tagStart; + state.tagName = state.tagStart = null; + if (type == "selfcloseTag" || + config.autoSelfClosers.hasOwnProperty(tagName)) { + maybePopContext(state, tagName); + } else { + maybePopContext(state, tagName); + state.context = new Context(state, tagName, tagStart == state.indented); + } + return baseState; + } + setStyle = "error"; + return attrState; + } + function attrEqState(type, stream, state) { + if (type == "equals") return attrValueState; + if (!config.allowMissing) setStyle = "error"; + return attrState(type, stream, state); + } + function attrValueState(type, stream, state) { + if (type == "string") return attrContinuedState; + if (type == "word" && config.allowUnquoted) {setStyle = "string"; return attrState;} + setStyle = "error"; + return attrState(type, stream, state); + } + function attrContinuedState(type, stream, state) { + if (type == "string") return attrContinuedState; + return attrState(type, stream, state); + } + + return { + startState: function(baseIndent) { + var state = {tokenize: inText, + state: baseState, + indented: baseIndent || 0, + tagName: null, tagStart: null, + context: null}; + if (baseIndent != null) state.baseIndent = baseIndent; + return state + }, + + token: function(stream, state) { + if (!state.tagName && stream.sol()) + state.indented = stream.indentation(); + + if (stream.eatSpace()) return null; + type = null; + var style = state.tokenize(stream, state); + if ((style || type) && style != "comment") { + setStyle = null; + state.state = state.state(type || style, stream, state); + if (setStyle) + style = setStyle == "error" ? style + " error" : setStyle; + } + return style; + }, + + indent: function(state, textAfter, fullLine) { + var context = state.context; + // Indent multi-line strings (e.g. css). + if (state.tokenize.isInAttribute) { + if (state.tagStart == state.indented) + return state.stringStartCol + 1; + else + return state.indented + indentUnit; + } + if (context && context.noIndent) return CodeMirror.Pass; + if (state.tokenize != inTag && state.tokenize != inText) + return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0; + // Indent the starts of attribute names. + if (state.tagName) { + if (config.multilineTagIndentPastTag !== false) + return state.tagStart + state.tagName.length + 2; + else + return state.tagStart + indentUnit * (config.multilineTagIndentFactor || 1); + } + if (config.alignCDATA && /$/, + blockCommentStart: "", + + configuration: config.htmlMode ? "html" : "xml", + helperType: config.htmlMode ? "html" : "xml", + + skipAttribute: function(state) { + if (state.state == attrValueState) + state.state = attrState; + }, + + xmlCurrentTag: function(state) { + return state.tagName ? {name: state.tagName, close: state.type == "closeTag"} : null + }, + + xmlCurrentContext: function(state) { + var context = []; + for (var cx = state.context; cx; cx = cx.prev) + if (cx.tagName) context.push(cx.tagName); + return context.reverse() + } + }; + }); - // The DOM events that CodeMirror handles can be overridden by - // registering a (non-DOM) handler on the editor for the event name, - // and preventDefault-ing the event in that handler. - function signalDOMEvent(cm, e, override) { - if (typeof e == "string") { e = { type: e, preventDefault: function () { this.defaultPrevented = true; } }; } - signal(cm, override || e.type, cm, e); - return e_defaultPrevented(e) || e.codemirrorIgnore - } + CodeMirror.defineMIME("text/xml", "xml"); + CodeMirror.defineMIME("application/xml", "xml"); + if (!CodeMirror.mimeModes.hasOwnProperty("text/html")) + CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: true}); - function signalCursorActivity(cm) { - var arr = cm._handlers && cm._handlers.cursorActivity; - if (!arr) { return } - var set = cm.curOp.cursorActivityHandlers || (cm.curOp.cursorActivityHandlers = []); - for (var i = 0; i < arr.length; ++i) { - if (indexOf(set, arr[i]) == -1) { set.push(arr[i]); } - } - } + }); + }); - function hasHandler(emitter, type) { - return getHandlers(emitter, type).length > 0 - } + var meta = createCommonjsModule(function (module, exports) { + // CodeMirror, copyright (c) by Marijn Haverbeke and others + // Distributed under an MIT license: https://codemirror.net/LICENSE + + (function(mod) { + mod(codemirror); + })(function(CodeMirror) { + + CodeMirror.modeInfo = [ + {name: "APL", mime: "text/apl", mode: "apl", ext: ["dyalog", "apl"]}, + {name: "PGP", mimes: ["application/pgp", "application/pgp-encrypted", "application/pgp-keys", "application/pgp-signature"], mode: "asciiarmor", ext: ["asc", "pgp", "sig"]}, + {name: "ASN.1", mime: "text/x-ttcn-asn", mode: "asn.1", ext: ["asn", "asn1"]}, + {name: "Asterisk", mime: "text/x-asterisk", mode: "asterisk", file: /^extensions\.conf$/i}, + {name: "Brainfuck", mime: "text/x-brainfuck", mode: "brainfuck", ext: ["b", "bf"]}, + {name: "C", mime: "text/x-csrc", mode: "clike", ext: ["c", "h", "ino"]}, + {name: "C++", mime: "text/x-c++src", mode: "clike", ext: ["cpp", "c++", "cc", "cxx", "hpp", "h++", "hh", "hxx"], alias: ["cpp"]}, + {name: "Cobol", mime: "text/x-cobol", mode: "cobol", ext: ["cob", "cpy"]}, + {name: "C#", mime: "text/x-csharp", mode: "clike", ext: ["cs"], alias: ["csharp", "cs"]}, + {name: "Clojure", mime: "text/x-clojure", mode: "clojure", ext: ["clj", "cljc", "cljx"]}, + {name: "ClojureScript", mime: "text/x-clojurescript", mode: "clojure", ext: ["cljs"]}, + {name: "Closure Stylesheets (GSS)", mime: "text/x-gss", mode: "css", ext: ["gss"]}, + {name: "CMake", mime: "text/x-cmake", mode: "cmake", ext: ["cmake", "cmake.in"], file: /^CMakeLists\.txt$/}, + {name: "CoffeeScript", mimes: ["application/vnd.coffeescript", "text/coffeescript", "text/x-coffeescript"], mode: "coffeescript", ext: ["coffee"], alias: ["coffee", "coffee-script"]}, + {name: "Common Lisp", mime: "text/x-common-lisp", mode: "commonlisp", ext: ["cl", "lisp", "el"], alias: ["lisp"]}, + {name: "Cypher", mime: "application/x-cypher-query", mode: "cypher", ext: ["cyp", "cypher"]}, + {name: "Cython", mime: "text/x-cython", mode: "python", ext: ["pyx", "pxd", "pxi"]}, + {name: "Crystal", mime: "text/x-crystal", mode: "crystal", ext: ["cr"]}, + {name: "CSS", mime: "text/css", mode: "css", ext: ["css"]}, + {name: "CQL", mime: "text/x-cassandra", mode: "sql", ext: ["cql"]}, + {name: "D", mime: "text/x-d", mode: "d", ext: ["d"]}, + {name: "Dart", mimes: ["application/dart", "text/x-dart"], mode: "dart", ext: ["dart"]}, + {name: "diff", mime: "text/x-diff", mode: "diff", ext: ["diff", "patch"]}, + {name: "Django", mime: "text/x-django", mode: "django"}, + {name: "Dockerfile", mime: "text/x-dockerfile", mode: "dockerfile", file: /^Dockerfile$/}, + {name: "DTD", mime: "application/xml-dtd", mode: "dtd", ext: ["dtd"]}, + {name: "Dylan", mime: "text/x-dylan", mode: "dylan", ext: ["dylan", "dyl", "intr"]}, + {name: "EBNF", mime: "text/x-ebnf", mode: "ebnf"}, + {name: "ECL", mime: "text/x-ecl", mode: "ecl", ext: ["ecl"]}, + {name: "edn", mime: "application/edn", mode: "clojure", ext: ["edn"]}, + {name: "Eiffel", mime: "text/x-eiffel", mode: "eiffel", ext: ["e"]}, + {name: "Elm", mime: "text/x-elm", mode: "elm", ext: ["elm"]}, + {name: "Embedded Javascript", mime: "application/x-ejs", mode: "htmlembedded", ext: ["ejs"]}, + {name: "Embedded Ruby", mime: "application/x-erb", mode: "htmlembedded", ext: ["erb"]}, + {name: "Erlang", mime: "text/x-erlang", mode: "erlang", ext: ["erl"]}, + {name: "Esper", mime: "text/x-esper", mode: "sql"}, + {name: "Factor", mime: "text/x-factor", mode: "factor", ext: ["factor"]}, + {name: "FCL", mime: "text/x-fcl", mode: "fcl"}, + {name: "Forth", mime: "text/x-forth", mode: "forth", ext: ["forth", "fth", "4th"]}, + {name: "Fortran", mime: "text/x-fortran", mode: "fortran", ext: ["f", "for", "f77", "f90", "f95"]}, + {name: "F#", mime: "text/x-fsharp", mode: "mllike", ext: ["fs"], alias: ["fsharp"]}, + {name: "Gas", mime: "text/x-gas", mode: "gas", ext: ["s"]}, + {name: "Gherkin", mime: "text/x-feature", mode: "gherkin", ext: ["feature"]}, + {name: "GitHub Flavored Markdown", mime: "text/x-gfm", mode: "gfm", file: /^(readme|contributing|history)\.md$/i}, + {name: "Go", mime: "text/x-go", mode: "go", ext: ["go"]}, + {name: "Groovy", mime: "text/x-groovy", mode: "groovy", ext: ["groovy", "gradle"], file: /^Jenkinsfile$/}, + {name: "HAML", mime: "text/x-haml", mode: "haml", ext: ["haml"]}, + {name: "Haskell", mime: "text/x-haskell", mode: "haskell", ext: ["hs"]}, + {name: "Haskell (Literate)", mime: "text/x-literate-haskell", mode: "haskell-literate", ext: ["lhs"]}, + {name: "Haxe", mime: "text/x-haxe", mode: "haxe", ext: ["hx"]}, + {name: "HXML", mime: "text/x-hxml", mode: "haxe", ext: ["hxml"]}, + {name: "ASP.NET", mime: "application/x-aspx", mode: "htmlembedded", ext: ["aspx"], alias: ["asp", "aspx"]}, + {name: "HTML", mime: "text/html", mode: "htmlmixed", ext: ["html", "htm", "handlebars", "hbs"], alias: ["xhtml"]}, + {name: "HTTP", mime: "message/http", mode: "http"}, + {name: "IDL", mime: "text/x-idl", mode: "idl", ext: ["pro"]}, + {name: "Pug", mime: "text/x-pug", mode: "pug", ext: ["jade", "pug"], alias: ["jade"]}, + {name: "Java", mime: "text/x-java", mode: "clike", ext: ["java"]}, + {name: "Java Server Pages", mime: "application/x-jsp", mode: "htmlembedded", ext: ["jsp"], alias: ["jsp"]}, + {name: "JavaScript", mimes: ["text/javascript", "text/ecmascript", "application/javascript", "application/x-javascript", "application/ecmascript"], + mode: "javascript", ext: ["js"], alias: ["ecmascript", "js", "node"]}, + {name: "JSON", mimes: ["application/json", "application/x-json"], mode: "javascript", ext: ["json", "map"], alias: ["json5"]}, + {name: "JSON-LD", mime: "application/ld+json", mode: "javascript", ext: ["jsonld"], alias: ["jsonld"]}, + {name: "JSX", mime: "text/jsx", mode: "jsx", ext: ["jsx"]}, + {name: "Jinja2", mime: "text/jinja2", mode: "jinja2", ext: ["j2", "jinja", "jinja2"]}, + {name: "Julia", mime: "text/x-julia", mode: "julia", ext: ["jl"]}, + {name: "Kotlin", mime: "text/x-kotlin", mode: "clike", ext: ["kt"]}, + {name: "LESS", mime: "text/x-less", mode: "css", ext: ["less"]}, + {name: "LiveScript", mime: "text/x-livescript", mode: "livescript", ext: ["ls"], alias: ["ls"]}, + {name: "Lua", mime: "text/x-lua", mode: "lua", ext: ["lua"]}, + {name: "Markdown", mime: "text/x-markdown", mode: "markdown", ext: ["markdown", "md", "mkd"]}, + {name: "mIRC", mime: "text/mirc", mode: "mirc"}, + {name: "MariaDB SQL", mime: "text/x-mariadb", mode: "sql"}, + {name: "Mathematica", mime: "text/x-mathematica", mode: "mathematica", ext: ["m", "nb", "wl", "wls"]}, + {name: "Modelica", mime: "text/x-modelica", mode: "modelica", ext: ["mo"]}, + {name: "MUMPS", mime: "text/x-mumps", mode: "mumps", ext: ["mps"]}, + {name: "MS SQL", mime: "text/x-mssql", mode: "sql"}, + {name: "mbox", mime: "application/mbox", mode: "mbox", ext: ["mbox"]}, + {name: "MySQL", mime: "text/x-mysql", mode: "sql"}, + {name: "Nginx", mime: "text/x-nginx-conf", mode: "nginx", file: /nginx.*\.conf$/i}, + {name: "NSIS", mime: "text/x-nsis", mode: "nsis", ext: ["nsh", "nsi"]}, + {name: "NTriples", mimes: ["application/n-triples", "application/n-quads", "text/n-triples"], + mode: "ntriples", ext: ["nt", "nq"]}, + {name: "Objective-C", mime: "text/x-objectivec", mode: "clike", ext: ["m"], alias: ["objective-c", "objc"]}, + {name: "Objective-C++", mime: "text/x-objectivec++", mode: "clike", ext: ["mm"], alias: ["objective-c++", "objc++"]}, + {name: "OCaml", mime: "text/x-ocaml", mode: "mllike", ext: ["ml", "mli", "mll", "mly"]}, + {name: "Octave", mime: "text/x-octave", mode: "octave", ext: ["m"]}, + {name: "Oz", mime: "text/x-oz", mode: "oz", ext: ["oz"]}, + {name: "Pascal", mime: "text/x-pascal", mode: "pascal", ext: ["p", "pas"]}, + {name: "PEG.js", mime: "null", mode: "pegjs", ext: ["jsonld"]}, + {name: "Perl", mime: "text/x-perl", mode: "perl", ext: ["pl", "pm"]}, + {name: "PHP", mimes: ["text/x-php", "application/x-httpd-php", "application/x-httpd-php-open"], mode: "php", ext: ["php", "php3", "php4", "php5", "php7", "phtml"]}, + {name: "Pig", mime: "text/x-pig", mode: "pig", ext: ["pig"]}, + {name: "Plain Text", mime: "text/plain", mode: "null", ext: ["txt", "text", "conf", "def", "list", "log"]}, + {name: "PLSQL", mime: "text/x-plsql", mode: "sql", ext: ["pls"]}, + {name: "PostgreSQL", mime: "text/x-pgsql", mode: "sql"}, + {name: "PowerShell", mime: "application/x-powershell", mode: "powershell", ext: ["ps1", "psd1", "psm1"]}, + {name: "Properties files", mime: "text/x-properties", mode: "properties", ext: ["properties", "ini", "in"], alias: ["ini", "properties"]}, + {name: "ProtoBuf", mime: "text/x-protobuf", mode: "protobuf", ext: ["proto"]}, + {name: "Python", mime: "text/x-python", mode: "python", ext: ["BUILD", "bzl", "py", "pyw"], file: /^(BUCK|BUILD)$/}, + {name: "Puppet", mime: "text/x-puppet", mode: "puppet", ext: ["pp"]}, + {name: "Q", mime: "text/x-q", mode: "q", ext: ["q"]}, + {name: "R", mime: "text/x-rsrc", mode: "r", ext: ["r", "R"], alias: ["rscript"]}, + {name: "reStructuredText", mime: "text/x-rst", mode: "rst", ext: ["rst"], alias: ["rst"]}, + {name: "RPM Changes", mime: "text/x-rpm-changes", mode: "rpm"}, + {name: "RPM Spec", mime: "text/x-rpm-spec", mode: "rpm", ext: ["spec"]}, + {name: "Ruby", mime: "text/x-ruby", mode: "ruby", ext: ["rb"], alias: ["jruby", "macruby", "rake", "rb", "rbx"]}, + {name: "Rust", mime: "text/x-rustsrc", mode: "rust", ext: ["rs"]}, + {name: "SAS", mime: "text/x-sas", mode: "sas", ext: ["sas"]}, + {name: "Sass", mime: "text/x-sass", mode: "sass", ext: ["sass"]}, + {name: "Scala", mime: "text/x-scala", mode: "clike", ext: ["scala"]}, + {name: "Scheme", mime: "text/x-scheme", mode: "scheme", ext: ["scm", "ss"]}, + {name: "SCSS", mime: "text/x-scss", mode: "css", ext: ["scss"]}, + {name: "Shell", mimes: ["text/x-sh", "application/x-sh"], mode: "shell", ext: ["sh", "ksh", "bash"], alias: ["bash", "sh", "zsh"], file: /^PKGBUILD$/}, + {name: "Sieve", mime: "application/sieve", mode: "sieve", ext: ["siv", "sieve"]}, + {name: "Slim", mimes: ["text/x-slim", "application/x-slim"], mode: "slim", ext: ["slim"]}, + {name: "Smalltalk", mime: "text/x-stsrc", mode: "smalltalk", ext: ["st"]}, + {name: "Smarty", mime: "text/x-smarty", mode: "smarty", ext: ["tpl"]}, + {name: "Solr", mime: "text/x-solr", mode: "solr"}, + {name: "SML", mime: "text/x-sml", mode: "mllike", ext: ["sml", "sig", "fun", "smackspec"]}, + {name: "Soy", mime: "text/x-soy", mode: "soy", ext: ["soy"], alias: ["closure template"]}, + {name: "SPARQL", mime: "application/sparql-query", mode: "sparql", ext: ["rq", "sparql"], alias: ["sparul"]}, + {name: "Spreadsheet", mime: "text/x-spreadsheet", mode: "spreadsheet", alias: ["excel", "formula"]}, + {name: "SQL", mime: "text/x-sql", mode: "sql", ext: ["sql"]}, + {name: "SQLite", mime: "text/x-sqlite", mode: "sql"}, + {name: "Squirrel", mime: "text/x-squirrel", mode: "clike", ext: ["nut"]}, + {name: "Stylus", mime: "text/x-styl", mode: "stylus", ext: ["styl"]}, + {name: "Swift", mime: "text/x-swift", mode: "swift", ext: ["swift"]}, + {name: "sTeX", mime: "text/x-stex", mode: "stex"}, + {name: "LaTeX", mime: "text/x-latex", mode: "stex", ext: ["text", "ltx", "tex"], alias: ["tex"]}, + {name: "SystemVerilog", mime: "text/x-systemverilog", mode: "verilog", ext: ["v", "sv", "svh"]}, + {name: "Tcl", mime: "text/x-tcl", mode: "tcl", ext: ["tcl"]}, + {name: "Textile", mime: "text/x-textile", mode: "textile", ext: ["textile"]}, + {name: "TiddlyWiki", mime: "text/x-tiddlywiki", mode: "tiddlywiki"}, + {name: "Tiki wiki", mime: "text/tiki", mode: "tiki"}, + {name: "TOML", mime: "text/x-toml", mode: "toml", ext: ["toml"]}, + {name: "Tornado", mime: "text/x-tornado", mode: "tornado"}, + {name: "troff", mime: "text/troff", mode: "troff", ext: ["1", "2", "3", "4", "5", "6", "7", "8", "9"]}, + {name: "TTCN", mime: "text/x-ttcn", mode: "ttcn", ext: ["ttcn", "ttcn3", "ttcnpp"]}, + {name: "TTCN_CFG", mime: "text/x-ttcn-cfg", mode: "ttcn-cfg", ext: ["cfg"]}, + {name: "Turtle", mime: "text/turtle", mode: "turtle", ext: ["ttl"]}, + {name: "TypeScript", mime: "application/typescript", mode: "javascript", ext: ["ts"], alias: ["ts"]}, + {name: "TypeScript-JSX", mime: "text/typescript-jsx", mode: "jsx", ext: ["tsx"], alias: ["tsx"]}, + {name: "Twig", mime: "text/x-twig", mode: "twig"}, + {name: "Web IDL", mime: "text/x-webidl", mode: "webidl", ext: ["webidl"]}, + {name: "VB.NET", mime: "text/x-vb", mode: "vb", ext: ["vb"]}, + {name: "VBScript", mime: "text/vbscript", mode: "vbscript", ext: ["vbs"]}, + {name: "Velocity", mime: "text/velocity", mode: "velocity", ext: ["vtl"]}, + {name: "Verilog", mime: "text/x-verilog", mode: "verilog", ext: ["v"]}, + {name: "VHDL", mime: "text/x-vhdl", mode: "vhdl", ext: ["vhd", "vhdl"]}, + {name: "Vue.js Component", mimes: ["script/x-vue", "text/x-vue"], mode: "vue", ext: ["vue"]}, + {name: "XML", mimes: ["application/xml", "text/xml"], mode: "xml", ext: ["xml", "xsl", "xsd", "svg"], alias: ["rss", "wsdl", "xsd"]}, + {name: "XQuery", mime: "application/xquery", mode: "xquery", ext: ["xy", "xquery"]}, + {name: "Yacas", mime: "text/x-yacas", mode: "yacas", ext: ["ys"]}, + {name: "YAML", mimes: ["text/x-yaml", "text/yaml"], mode: "yaml", ext: ["yaml", "yml"], alias: ["yml"]}, + {name: "Z80", mime: "text/x-z80", mode: "z80", ext: ["z80"]}, + {name: "mscgen", mime: "text/x-mscgen", mode: "mscgen", ext: ["mscgen", "mscin", "msc"]}, + {name: "xu", mime: "text/x-xu", mode: "mscgen", ext: ["xu"]}, + {name: "msgenny", mime: "text/x-msgenny", mode: "mscgen", ext: ["msgenny"]}, + {name: "WebAssembly", mime: "text/webassembly", mode: "wast", ext: ["wat", "wast"]}, + ]; + // Ensure all modes have a mime property for backwards compatibility + for (var i = 0; i < CodeMirror.modeInfo.length; i++) { + var info = CodeMirror.modeInfo[i]; + if (info.mimes) info.mime = info.mimes[0]; + } + + CodeMirror.findModeByMIME = function(mime) { + mime = mime.toLowerCase(); + for (var i = 0; i < CodeMirror.modeInfo.length; i++) { + var info = CodeMirror.modeInfo[i]; + if (info.mime == mime) return info; + if (info.mimes) for (var j = 0; j < info.mimes.length; j++) + if (info.mimes[j] == mime) return info; + } + if (/\+xml$/.test(mime)) return CodeMirror.findModeByMIME("application/xml") + if (/\+json$/.test(mime)) return CodeMirror.findModeByMIME("application/json") + }; + + CodeMirror.findModeByExtension = function(ext) { + ext = ext.toLowerCase(); + for (var i = 0; i < CodeMirror.modeInfo.length; i++) { + var info = CodeMirror.modeInfo[i]; + if (info.ext) for (var j = 0; j < info.ext.length; j++) + if (info.ext[j] == ext) return info; + } + }; + + CodeMirror.findModeByFileName = function(filename) { + for (var i = 0; i < CodeMirror.modeInfo.length; i++) { + var info = CodeMirror.modeInfo[i]; + if (info.file && info.file.test(filename)) return info; + } + var dot = filename.lastIndexOf("."); + var ext = dot > -1 && filename.substring(dot + 1, filename.length); + if (ext) return CodeMirror.findModeByExtension(ext); + }; + + CodeMirror.findModeByName = function(name) { + name = name.toLowerCase(); + for (var i = 0; i < CodeMirror.modeInfo.length; i++) { + var info = CodeMirror.modeInfo[i]; + if (info.name.toLowerCase() == name) return info; + if (info.alias) for (var j = 0; j < info.alias.length; j++) + if (info.alias[j].toLowerCase() == name) return info; + } + }; + }); + }); - // Add on and off methods to a constructor's prototype, to make - // registering events on such objects more convenient. - function eventMixin(ctor) { - ctor.prototype.on = function (type, f) { on(this, type, f); }; - ctor.prototype.off = function (type, f) { off(this, type, f); }; - } + var markdown = createCommonjsModule(function (module, exports) { + // CodeMirror, copyright (c) by Marijn Haverbeke and others + // Distributed under an MIT license: https://codemirror.net/LICENSE + + (function(mod) { + mod(codemirror, xml, meta); + })(function(CodeMirror) { + + CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) { + + var htmlMode = CodeMirror.getMode(cmCfg, "text/html"); + var htmlModeMissing = htmlMode.name == "null"; + + function getMode(name) { + if (CodeMirror.findModeByName) { + var found = CodeMirror.findModeByName(name); + if (found) name = found.mime || found.mimes[0]; + } + var mode = CodeMirror.getMode(cmCfg, name); + return mode.name == "null" ? null : mode; + } + + // Should characters that affect highlighting be highlighted separate? + // Does not include characters that will be output (such as `1.` and `-` for lists) + if (modeCfg.highlightFormatting === undefined) + modeCfg.highlightFormatting = false; + + // Maximum number of nested blockquotes. Set to 0 for infinite nesting. + // Excess `>` will emit `error` token. + if (modeCfg.maxBlockquoteDepth === undefined) + modeCfg.maxBlockquoteDepth = 0; + + // Turn on task lists? ("- [ ] " and "- [x] ") + if (modeCfg.taskLists === undefined) modeCfg.taskLists = false; + + // Turn on strikethrough syntax + if (modeCfg.strikethrough === undefined) + modeCfg.strikethrough = false; + + if (modeCfg.emoji === undefined) + modeCfg.emoji = false; + + if (modeCfg.fencedCodeBlockHighlighting === undefined) + modeCfg.fencedCodeBlockHighlighting = true; + + if (modeCfg.fencedCodeBlockDefaultMode === undefined) + modeCfg.fencedCodeBlockDefaultMode = 'text/plain'; + + if (modeCfg.xml === undefined) + modeCfg.xml = true; + + // Allow token types to be overridden by user-provided token types. + if (modeCfg.tokenTypeOverrides === undefined) + modeCfg.tokenTypeOverrides = {}; + + var tokenTypes = { + header: "header", + code: "comment", + quote: "quote", + list1: "variable-2", + list2: "variable-3", + list3: "keyword", + hr: "hr", + image: "image", + imageAltText: "image-alt-text", + imageMarker: "image-marker", + formatting: "formatting", + linkInline: "link", + linkEmail: "link", + linkText: "link", + linkHref: "string", + em: "em", + strong: "strong", + strikethrough: "strikethrough", + emoji: "builtin" + }; + + for (var tokenType in tokenTypes) { + if (tokenTypes.hasOwnProperty(tokenType) && modeCfg.tokenTypeOverrides[tokenType]) { + tokenTypes[tokenType] = modeCfg.tokenTypeOverrides[tokenType]; + } + } + + var hrRE = /^([*\-_])(?:\s*\1){2,}\s*$/ + , listRE = /^(?:[*\-+]|^[0-9]+([.)]))\s+/ + , taskListRE = /^\[(x| )\](?=\s)/i // Must follow listRE + , atxHeaderRE = modeCfg.allowAtxHeaderWithoutSpace ? /^(#+)/ : /^(#+)(?: |$)/ + , setextHeaderRE = /^ {0,3}(?:\={1,}|-{2,})\s*$/ + , textRE = /^[^#!\[\]*_\\<>` "'(~:]+/ + , fencedCodeRE = /^(~~~+|```+)[ \t]*([\w\/+#-]*)[^\n`]*$/ + , linkDefRE = /^\s*\[[^\]]+?\]:.*$/ // naive link-definition + , punctuation = /[!"#$%&'()*+,\-.\/:;<=>?@\[\\\]^_`{|}~\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061E\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u0AF0\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166D\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E42\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]|\uD800[\uDD00-\uDD02\uDF9F\uDFD0]|\uD801\uDD6F|\uD802[\uDC57\uDD1F\uDD3F\uDE50-\uDE58\uDE7F\uDEF0-\uDEF6\uDF39-\uDF3F\uDF99-\uDF9C]|\uD804[\uDC47-\uDC4D\uDCBB\uDCBC\uDCBE-\uDCC1\uDD40-\uDD43\uDD74\uDD75\uDDC5-\uDDC9\uDDCD\uDDDB\uDDDD-\uDDDF\uDE38-\uDE3D\uDEA9]|\uD805[\uDCC6\uDDC1-\uDDD7\uDE41-\uDE43\uDF3C-\uDF3E]|\uD809[\uDC70-\uDC74]|\uD81A[\uDE6E\uDE6F\uDEF5\uDF37-\uDF3B\uDF44]|\uD82F\uDC9F|\uD836[\uDE87-\uDE8B]/ + , expandedTab = " "; // CommonMark specifies tab as 4 spaces + + function switchInline(stream, state, f) { + state.f = state.inline = f; + return f(stream, state); + } + + function switchBlock(stream, state, f) { + state.f = state.block = f; + return f(stream, state); + } + + function lineIsEmpty(line) { + return !line || !/\S/.test(line.string) + } + + // Blocks + + function blankLine(state) { + // Reset linkTitle state + state.linkTitle = false; + state.linkHref = false; + state.linkText = false; + // Reset EM state + state.em = false; + // Reset STRONG state + state.strong = false; + // Reset strikethrough state + state.strikethrough = false; + // Reset state.quote + state.quote = 0; + // Reset state.indentedCode + state.indentedCode = false; + if (state.f == htmlBlock) { + var exit = htmlModeMissing; + if (!exit) { + var inner = CodeMirror.innerMode(htmlMode, state.htmlState); + exit = inner.mode.name == "xml" && inner.state.tagStart === null && + (!inner.state.context && inner.state.tokenize.isInText); + } + if (exit) { + state.f = inlineNormal; + state.block = blockNormal; + state.htmlState = null; + } + } + // Reset state.trailingSpace + state.trailingSpace = 0; + state.trailingSpaceNewLine = false; + // Mark this line as blank + state.prevLine = state.thisLine; + state.thisLine = {stream: null}; + return null; + } + + function blockNormal(stream, state) { + var firstTokenOnLine = stream.column() === state.indentation; + var prevLineLineIsEmpty = lineIsEmpty(state.prevLine.stream); + var prevLineIsIndentedCode = state.indentedCode; + var prevLineIsHr = state.prevLine.hr; + var prevLineIsList = state.list !== false; + var maxNonCodeIndentation = (state.listStack[state.listStack.length - 1] || 0) + 3; + + state.indentedCode = false; + + var lineIndentation = state.indentation; + // compute once per line (on first token) + if (state.indentationDiff === null) { + state.indentationDiff = state.indentation; + if (prevLineIsList) { + state.list = null; + // While this list item's marker's indentation is less than the deepest + // list item's content's indentation,pop the deepest list item + // indentation off the stack, and update block indentation state + while (lineIndentation < state.listStack[state.listStack.length - 1]) { + state.listStack.pop(); + if (state.listStack.length) { + state.indentation = state.listStack[state.listStack.length - 1]; + // less than the first list's indent -> the line is no longer a list + } else { + state.list = false; + } + } + if (state.list !== false) { + state.indentationDiff = lineIndentation - state.listStack[state.listStack.length - 1]; + } + } + } + + // not comprehensive (currently only for setext detection purposes) + var allowsInlineContinuation = ( + !prevLineLineIsEmpty && !prevLineIsHr && !state.prevLine.header && + (!prevLineIsList || !prevLineIsIndentedCode) && + !state.prevLine.fencedCodeEnd + ); + + var isHr = (state.list === false || prevLineIsHr || prevLineLineIsEmpty) && + state.indentation <= maxNonCodeIndentation && stream.match(hrRE); + + var match = null; + if (state.indentationDiff >= 4 && (prevLineIsIndentedCode || state.prevLine.fencedCodeEnd || + state.prevLine.header || prevLineLineIsEmpty)) { + stream.skipToEnd(); + state.indentedCode = true; + return tokenTypes.code; + } else if (stream.eatSpace()) { + return null; + } else if (firstTokenOnLine && state.indentation <= maxNonCodeIndentation && (match = stream.match(atxHeaderRE)) && match[1].length <= 6) { + state.quote = 0; + state.header = match[1].length; + state.thisLine.header = true; + if (modeCfg.highlightFormatting) state.formatting = "header"; + state.f = state.inline; + return getType(state); + } else if (state.indentation <= maxNonCodeIndentation && stream.eat('>')) { + state.quote = firstTokenOnLine ? 1 : state.quote + 1; + if (modeCfg.highlightFormatting) state.formatting = "quote"; + stream.eatSpace(); + return getType(state); + } else if (!isHr && !state.setext && firstTokenOnLine && state.indentation <= maxNonCodeIndentation && (match = stream.match(listRE))) { + var listType = match[1] ? "ol" : "ul"; + + state.indentation = lineIndentation + stream.current().length; + state.list = true; + state.quote = 0; + + // Add this list item's content's indentation to the stack + state.listStack.push(state.indentation); + // Reset inline styles which shouldn't propagate aross list items + state.em = false; + state.strong = false; + state.code = false; + state.strikethrough = false; + + if (modeCfg.taskLists && stream.match(taskListRE, false)) { + state.taskList = true; + } + state.f = state.inline; + if (modeCfg.highlightFormatting) state.formatting = ["list", "list-" + listType]; + return getType(state); + } else if (firstTokenOnLine && state.indentation <= maxNonCodeIndentation && (match = stream.match(fencedCodeRE, true))) { + state.quote = 0; + state.fencedEndRE = new RegExp(match[1] + "+ *$"); + // try switching mode + state.localMode = modeCfg.fencedCodeBlockHighlighting && getMode(match[2] || modeCfg.fencedCodeBlockDefaultMode ); + if (state.localMode) state.localState = CodeMirror.startState(state.localMode); + state.f = state.block = local; + if (modeCfg.highlightFormatting) state.formatting = "code-block"; + state.code = -1; + return getType(state); + // SETEXT has lowest block-scope precedence after HR, so check it after + // the others (code, blockquote, list...) + } else if ( + // if setext set, indicates line after ---/=== + state.setext || ( + // line before ---/=== + (!allowsInlineContinuation || !prevLineIsList) && !state.quote && state.list === false && + !state.code && !isHr && !linkDefRE.test(stream.string) && + (match = stream.lookAhead(1)) && (match = match.match(setextHeaderRE)) + ) + ) { + if ( !state.setext ) { + state.header = match[0].charAt(0) == '=' ? 1 : 2; + state.setext = state.header; + } else { + state.header = state.setext; + // has no effect on type so we can reset it now + state.setext = 0; + stream.skipToEnd(); + if (modeCfg.highlightFormatting) state.formatting = "header"; + } + state.thisLine.header = true; + state.f = state.inline; + return getType(state); + } else if (isHr) { + stream.skipToEnd(); + state.hr = true; + state.thisLine.hr = true; + return tokenTypes.hr; + } else if (stream.peek() === '[') { + return switchInline(stream, state, footnoteLink); + } + + return switchInline(stream, state, state.inline); + } + + function htmlBlock(stream, state) { + var style = htmlMode.token(stream, state.htmlState); + if (!htmlModeMissing) { + var inner = CodeMirror.innerMode(htmlMode, state.htmlState); + if ((inner.mode.name == "xml" && inner.state.tagStart === null && + (!inner.state.context && inner.state.tokenize.isInText)) || + (state.md_inside && stream.current().indexOf(">") > -1)) { + state.f = inlineNormal; + state.block = blockNormal; + state.htmlState = null; + } + } + return style; + } + + function local(stream, state) { + var currListInd = state.listStack[state.listStack.length - 1] || 0; + var hasExitedList = state.indentation < currListInd; + var maxFencedEndInd = currListInd + 3; + if (state.fencedEndRE && state.indentation <= maxFencedEndInd && (hasExitedList || stream.match(state.fencedEndRE))) { + if (modeCfg.highlightFormatting) state.formatting = "code-block"; + var returnType; + if (!hasExitedList) returnType = getType(state); + state.localMode = state.localState = null; + state.block = blockNormal; + state.f = inlineNormal; + state.fencedEndRE = null; + state.code = 0; + state.thisLine.fencedCodeEnd = true; + if (hasExitedList) return switchBlock(stream, state, state.block); + return returnType; + } else if (state.localMode) { + return state.localMode.token(stream, state.localState); + } else { + stream.skipToEnd(); + return tokenTypes.code; + } + } + + // Inline + function getType(state) { + var styles = []; + + if (state.formatting) { + styles.push(tokenTypes.formatting); + + if (typeof state.formatting === "string") state.formatting = [state.formatting]; + + for (var i = 0; i < state.formatting.length; i++) { + styles.push(tokenTypes.formatting + "-" + state.formatting[i]); + + if (state.formatting[i] === "header") { + styles.push(tokenTypes.formatting + "-" + state.formatting[i] + "-" + state.header); + } + + // Add `formatting-quote` and `formatting-quote-#` for blockquotes + // Add `error` instead if the maximum blockquote nesting depth is passed + if (state.formatting[i] === "quote") { + if (!modeCfg.maxBlockquoteDepth || modeCfg.maxBlockquoteDepth >= state.quote) { + styles.push(tokenTypes.formatting + "-" + state.formatting[i] + "-" + state.quote); + } else { + styles.push("error"); + } + } + } + } + + if (state.taskOpen) { + styles.push("meta"); + return styles.length ? styles.join(' ') : null; + } + if (state.taskClosed) { + styles.push("property"); + return styles.length ? styles.join(' ') : null; + } + + if (state.linkHref) { + styles.push(tokenTypes.linkHref, "url"); + } else { // Only apply inline styles to non-url text + if (state.strong) { styles.push(tokenTypes.strong); } + if (state.em) { styles.push(tokenTypes.em); } + if (state.strikethrough) { styles.push(tokenTypes.strikethrough); } + if (state.emoji) { styles.push(tokenTypes.emoji); } + if (state.linkText) { styles.push(tokenTypes.linkText); } + if (state.code) { styles.push(tokenTypes.code); } + if (state.image) { styles.push(tokenTypes.image); } + if (state.imageAltText) { styles.push(tokenTypes.imageAltText, "link"); } + if (state.imageMarker) { styles.push(tokenTypes.imageMarker); } + } + + if (state.header) { styles.push(tokenTypes.header, tokenTypes.header + "-" + state.header); } + + if (state.quote) { + styles.push(tokenTypes.quote); + + // Add `quote-#` where the maximum for `#` is modeCfg.maxBlockquoteDepth + if (!modeCfg.maxBlockquoteDepth || modeCfg.maxBlockquoteDepth >= state.quote) { + styles.push(tokenTypes.quote + "-" + state.quote); + } else { + styles.push(tokenTypes.quote + "-" + modeCfg.maxBlockquoteDepth); + } + } + + if (state.list !== false) { + var listMod = (state.listStack.length - 1) % 3; + if (!listMod) { + styles.push(tokenTypes.list1); + } else if (listMod === 1) { + styles.push(tokenTypes.list2); + } else { + styles.push(tokenTypes.list3); + } + } + + if (state.trailingSpaceNewLine) { + styles.push("trailing-space-new-line"); + } else if (state.trailingSpace) { + styles.push("trailing-space-" + (state.trailingSpace % 2 ? "a" : "b")); + } + + return styles.length ? styles.join(' ') : null; + } + + function handleText(stream, state) { + if (stream.match(textRE, true)) { + return getType(state); + } + return undefined; + } + + function inlineNormal(stream, state) { + var style = state.text(stream, state); + if (typeof style !== 'undefined') + return style; + + if (state.list) { // List marker (*, +, -, 1., etc) + state.list = null; + return getType(state); + } + + if (state.taskList) { + var taskOpen = stream.match(taskListRE, true)[1] === " "; + if (taskOpen) state.taskOpen = true; + else state.taskClosed = true; + if (modeCfg.highlightFormatting) state.formatting = "task"; + state.taskList = false; + return getType(state); + } + + state.taskOpen = false; + state.taskClosed = false; + + if (state.header && stream.match(/^#+$/, true)) { + if (modeCfg.highlightFormatting) state.formatting = "header"; + return getType(state); + } + + var ch = stream.next(); + + // Matches link titles present on next line + if (state.linkTitle) { + state.linkTitle = false; + var matchCh = ch; + if (ch === '(') { + matchCh = ')'; + } + matchCh = (matchCh+'').replace(/([.?*+^\[\]\\(){}|-])/g, "\\$1"); + var regex = '^\\s*(?:[^' + matchCh + '\\\\]+|\\\\\\\\|\\\\.)' + matchCh; + if (stream.match(new RegExp(regex), true)) { + return tokenTypes.linkHref; + } + } + + // If this block is changed, it may need to be updated in GFM mode + if (ch === '`') { + var previousFormatting = state.formatting; + if (modeCfg.highlightFormatting) state.formatting = "code"; + stream.eatWhile('`'); + var count = stream.current().length; + if (state.code == 0 && (!state.quote || count == 1)) { + state.code = count; + return getType(state) + } else if (count == state.code) { // Must be exact + var t = getType(state); + state.code = 0; + return t + } else { + state.formatting = previousFormatting; + return getType(state) + } + } else if (state.code) { + return getType(state); + } + + if (ch === '\\') { + stream.next(); + if (modeCfg.highlightFormatting) { + var type = getType(state); + var formattingEscape = tokenTypes.formatting + "-escape"; + return type ? type + " " + formattingEscape : formattingEscape; + } + } + + if (ch === '!' && stream.match(/\[[^\]]*\] ?(?:\(|\[)/, false)) { + state.imageMarker = true; + state.image = true; + if (modeCfg.highlightFormatting) state.formatting = "image"; + return getType(state); + } + + if (ch === '[' && state.imageMarker && stream.match(/[^\]]*\](\(.*?\)| ?\[.*?\])/, false)) { + state.imageMarker = false; + state.imageAltText = true; + if (modeCfg.highlightFormatting) state.formatting = "image"; + return getType(state); + } + + if (ch === ']' && state.imageAltText) { + if (modeCfg.highlightFormatting) state.formatting = "image"; + var type = getType(state); + state.imageAltText = false; + state.image = false; + state.inline = state.f = linkHref; + return type; + } + + if (ch === '[' && !state.image) { + if (state.linkText && stream.match(/^.*?\]/)) return getType(state) + state.linkText = true; + if (modeCfg.highlightFormatting) state.formatting = "link"; + return getType(state); + } + + if (ch === ']' && state.linkText) { + if (modeCfg.highlightFormatting) state.formatting = "link"; + var type = getType(state); + state.linkText = false; + state.inline = state.f = stream.match(/\(.*?\)| ?\[.*?\]/, false) ? linkHref : inlineNormal; + return type; + } + + if (ch === '<' && stream.match(/^(https?|ftps?):\/\/(?:[^\\>]|\\.)+>/, false)) { + state.f = state.inline = linkInline; + if (modeCfg.highlightFormatting) state.formatting = "link"; + var type = getType(state); + if (type){ + type += " "; + } else { + type = ""; + } + return type + tokenTypes.linkInline; + } + + if (ch === '<' && stream.match(/^[^> \\]+@(?:[^\\>]|\\.)+>/, false)) { + state.f = state.inline = linkInline; + if (modeCfg.highlightFormatting) state.formatting = "link"; + var type = getType(state); + if (type){ + type += " "; + } else { + type = ""; + } + return type + tokenTypes.linkEmail; + } + + if (modeCfg.xml && ch === '<' && stream.match(/^(!--|\?|!\[CDATA\[|[a-z][a-z0-9-]*(?:\s+[a-z_:.\-]+(?:\s*=\s*[^>]+)?)*\s*(?:>|$))/i, false)) { + var end = stream.string.indexOf(">", stream.pos); + if (end != -1) { + var atts = stream.string.substring(stream.start, end); + if (/markdown\s*=\s*('|"){0,1}1('|"){0,1}/.test(atts)) state.md_inside = true; + } + stream.backUp(1); + state.htmlState = CodeMirror.startState(htmlMode); + return switchBlock(stream, state, htmlBlock); + } + + if (modeCfg.xml && ch === '<' && stream.match(/^\/\w*?>/)) { + state.md_inside = false; + return "tag"; + } else if (ch === "*" || ch === "_") { + var len = 1, before = stream.pos == 1 ? " " : stream.string.charAt(stream.pos - 2); + while (len < 3 && stream.eat(ch)) len++; + var after = stream.peek() || " "; + // See http://spec.commonmark.org/0.27/#emphasis-and-strong-emphasis + var leftFlanking = !/\s/.test(after) && (!punctuation.test(after) || /\s/.test(before) || punctuation.test(before)); + var rightFlanking = !/\s/.test(before) && (!punctuation.test(before) || /\s/.test(after) || punctuation.test(after)); + var setEm = null, setStrong = null; + if (len % 2) { // Em + if (!state.em && leftFlanking && (ch === "*" || !rightFlanking || punctuation.test(before))) + setEm = true; + else if (state.em == ch && rightFlanking && (ch === "*" || !leftFlanking || punctuation.test(after))) + setEm = false; + } + if (len > 1) { // Strong + if (!state.strong && leftFlanking && (ch === "*" || !rightFlanking || punctuation.test(before))) + setStrong = true; + else if (state.strong == ch && rightFlanking && (ch === "*" || !leftFlanking || punctuation.test(after))) + setStrong = false; + } + if (setStrong != null || setEm != null) { + if (modeCfg.highlightFormatting) state.formatting = setEm == null ? "strong" : setStrong == null ? "em" : "strong em"; + if (setEm === true) state.em = ch; + if (setStrong === true) state.strong = ch; + var t = getType(state); + if (setEm === false) state.em = false; + if (setStrong === false) state.strong = false; + return t + } + } else if (ch === ' ') { + if (stream.eat('*') || stream.eat('_')) { // Probably surrounded by spaces + if (stream.peek() === ' ') { // Surrounded by spaces, ignore + return getType(state); + } else { // Not surrounded by spaces, back up pointer + stream.backUp(1); + } + } + } + + if (modeCfg.strikethrough) { + if (ch === '~' && stream.eatWhile(ch)) { + if (state.strikethrough) {// Remove strikethrough + if (modeCfg.highlightFormatting) state.formatting = "strikethrough"; + var t = getType(state); + state.strikethrough = false; + return t; + } else if (stream.match(/^[^\s]/, false)) {// Add strikethrough + state.strikethrough = true; + if (modeCfg.highlightFormatting) state.formatting = "strikethrough"; + return getType(state); + } + } else if (ch === ' ') { + if (stream.match(/^~~/, true)) { // Probably surrounded by space + if (stream.peek() === ' ') { // Surrounded by spaces, ignore + return getType(state); + } else { // Not surrounded by spaces, back up pointer + stream.backUp(2); + } + } + } + } + + if (modeCfg.emoji && ch === ":" && stream.match(/^(?:[a-z_\d+][a-z_\d+-]*|\-[a-z_\d+][a-z_\d+-]*):/)) { + state.emoji = true; + if (modeCfg.highlightFormatting) state.formatting = "emoji"; + var retType = getType(state); + state.emoji = false; + return retType; + } + + if (ch === ' ') { + if (stream.match(/^ +$/, false)) { + state.trailingSpace++; + } else if (state.trailingSpace) { + state.trailingSpaceNewLine = true; + } + } + + return getType(state); + } + + function linkInline(stream, state) { + var ch = stream.next(); + + if (ch === ">") { + state.f = state.inline = inlineNormal; + if (modeCfg.highlightFormatting) state.formatting = "link"; + var type = getType(state); + if (type){ + type += " "; + } else { + type = ""; + } + return type + tokenTypes.linkInline; + } + + stream.match(/^[^>]+/, true); + + return tokenTypes.linkInline; + } + + function linkHref(stream, state) { + // Check if space, and return NULL if so (to avoid marking the space) + if(stream.eatSpace()){ + return null; + } + var ch = stream.next(); + if (ch === '(' || ch === '[') { + state.f = state.inline = getLinkHrefInside(ch === "(" ? ")" : "]"); + if (modeCfg.highlightFormatting) state.formatting = "link-string"; + state.linkHref = true; + return getType(state); + } + return 'error'; + } + + var linkRE = { + ")": /^(?:[^\\\(\)]|\\.|\((?:[^\\\(\)]|\\.)*\))*?(?=\))/, + "]": /^(?:[^\\\[\]]|\\.|\[(?:[^\\\[\]]|\\.)*\])*?(?=\])/ + }; + + function getLinkHrefInside(endChar) { + return function(stream, state) { + var ch = stream.next(); + + if (ch === endChar) { + state.f = state.inline = inlineNormal; + if (modeCfg.highlightFormatting) state.formatting = "link-string"; + var returnState = getType(state); + state.linkHref = false; + return returnState; + } + + stream.match(linkRE[endChar]); + state.linkHref = true; + return getType(state); + }; + } + + function footnoteLink(stream, state) { + if (stream.match(/^([^\]\\]|\\.)*\]:/, false)) { + state.f = footnoteLinkInside; + stream.next(); // Consume [ + if (modeCfg.highlightFormatting) state.formatting = "link"; + state.linkText = true; + return getType(state); + } + return switchInline(stream, state, inlineNormal); + } + + function footnoteLinkInside(stream, state) { + if (stream.match(/^\]:/, true)) { + state.f = state.inline = footnoteUrl; + if (modeCfg.highlightFormatting) state.formatting = "link"; + var returnType = getType(state); + state.linkText = false; + return returnType; + } + + stream.match(/^([^\]\\]|\\.)+/, true); + + return tokenTypes.linkText; + } + + function footnoteUrl(stream, state) { + // Check if space, and return NULL if so (to avoid marking the space) + if(stream.eatSpace()){ + return null; + } + // Match URL + stream.match(/^[^\s]+/, true); + // Check for link title + if (stream.peek() === undefined) { // End of line, set flag to check next line + state.linkTitle = true; + } else { // More content on line, check if link title + stream.match(/^(?:\s+(?:"(?:[^"\\]|\\\\|\\.)+"|'(?:[^'\\]|\\\\|\\.)+'|\((?:[^)\\]|\\\\|\\.)+\)))?/, true); + } + state.f = state.inline = inlineNormal; + return tokenTypes.linkHref + " url"; + } + + var mode = { + startState: function() { + return { + f: blockNormal, + + prevLine: {stream: null}, + thisLine: {stream: null}, + + block: blockNormal, + htmlState: null, + indentation: 0, + + inline: inlineNormal, + text: handleText, + + formatting: false, + linkText: false, + linkHref: false, + linkTitle: false, + code: 0, + em: false, + strong: false, + header: 0, + setext: 0, + hr: false, + taskList: false, + list: false, + listStack: [], + quote: 0, + trailingSpace: 0, + trailingSpaceNewLine: false, + strikethrough: false, + emoji: false, + fencedEndRE: null + }; + }, + + copyState: function(s) { + return { + f: s.f, + + prevLine: s.prevLine, + thisLine: s.thisLine, + + block: s.block, + htmlState: s.htmlState && CodeMirror.copyState(htmlMode, s.htmlState), + indentation: s.indentation, + + localMode: s.localMode, + localState: s.localMode ? CodeMirror.copyState(s.localMode, s.localState) : null, + + inline: s.inline, + text: s.text, + formatting: false, + linkText: s.linkText, + linkTitle: s.linkTitle, + linkHref: s.linkHref, + code: s.code, + em: s.em, + strong: s.strong, + strikethrough: s.strikethrough, + emoji: s.emoji, + header: s.header, + setext: s.setext, + hr: s.hr, + taskList: s.taskList, + list: s.list, + listStack: s.listStack.slice(0), + quote: s.quote, + indentedCode: s.indentedCode, + trailingSpace: s.trailingSpace, + trailingSpaceNewLine: s.trailingSpaceNewLine, + md_inside: s.md_inside, + fencedEndRE: s.fencedEndRE + }; + }, + + token: function(stream, state) { + + // Reset state.formatting + state.formatting = false; + + if (stream != state.thisLine.stream) { + state.header = 0; + state.hr = false; + + if (stream.match(/^\s*$/, true)) { + blankLine(state); + return null; + } + + state.prevLine = state.thisLine; + state.thisLine = {stream: stream}; + + // Reset state.taskList + state.taskList = false; + + // Reset state.trailingSpace + state.trailingSpace = 0; + state.trailingSpaceNewLine = false; + + if (!state.localState) { + state.f = state.block; + if (state.f != htmlBlock) { + var indentation = stream.match(/^\s*/, true)[0].replace(/\t/g, expandedTab).length; + state.indentation = indentation; + state.indentationDiff = null; + if (indentation > 0) return null; + } + } + } + return state.f(stream, state); + }, + + innerMode: function(state) { + if (state.block == htmlBlock) return {state: state.htmlState, mode: htmlMode}; + if (state.localState) return {state: state.localState, mode: state.localMode}; + return {state: state, mode: mode}; + }, + + indent: function(state, textAfter, line) { + if (state.block == htmlBlock && htmlMode.indent) return htmlMode.indent(state.htmlState, textAfter, line) + if (state.localState && state.localMode.indent) return state.localMode.indent(state.localState, textAfter, line) + return CodeMirror.Pass + }, + + blankLine: blankLine, + + getType: getType, + + blockCommentStart: "", + closeBrackets: "()[]{}''\"\"``", + fold: "markdown" + }; + return mode; + }, "xml"); + + CodeMirror.defineMIME("text/markdown", "markdown"); + + CodeMirror.defineMIME("text/x-markdown", "markdown"); - // Due to the fact that we still support jurassic IE versions, some - // compatibility wrappers are needed. + }); + }); - function e_preventDefault(e) { - if (e.preventDefault) { e.preventDefault(); } - else { e.returnValue = false; } - } - function e_stopPropagation(e) { - if (e.stopPropagation) { e.stopPropagation(); } - else { e.cancelBubble = true; } - } - function e_defaultPrevented(e) { - return e.defaultPrevented != null ? e.defaultPrevented : e.returnValue == false - } - function e_stop(e) { e_preventDefault(e); e_stopPropagation(e); } - - function e_target(e) { return e.target || e.srcElement } - function e_button(e) { - var b = e.which; - if (b == null) { - if (e.button & 1) { b = 1; } - else if (e.button & 2) { b = 3; } - else if (e.button & 4) { b = 2; } - } - if (mac && e.ctrlKey && b == 1) { b = 3; } - return b - } + var overlay = createCommonjsModule(function (module, exports) { + // CodeMirror, copyright (c) by Marijn Haverbeke and others + // Distributed under an MIT license: https://codemirror.net/LICENSE + + // Utility function that allows modes to be combined. The mode given + // as the base argument takes care of most of the normal mode + // functionality, but a second (typically simple) mode is used, which + // can override the style of text. Both modes get to parse all of the + // text, but when both assign a non-null style to a piece of code, the + // overlay wins, unless the combine argument was true and not overridden, + // or state.overlay.combineTokens was true, in which case the styles are + // combined. + + (function(mod) { + mod(codemirror); + })(function(CodeMirror) { + + CodeMirror.overlayMode = function(base, overlay, combine) { + return { + startState: function() { + return { + base: CodeMirror.startState(base), + overlay: CodeMirror.startState(overlay), + basePos: 0, baseCur: null, + overlayPos: 0, overlayCur: null, + streamSeen: null + }; + }, + copyState: function(state) { + return { + base: CodeMirror.copyState(base, state.base), + overlay: CodeMirror.copyState(overlay, state.overlay), + basePos: state.basePos, baseCur: null, + overlayPos: state.overlayPos, overlayCur: null + }; + }, + + token: function(stream, state) { + if (stream != state.streamSeen || + Math.min(state.basePos, state.overlayPos) < stream.start) { + state.streamSeen = stream; + state.basePos = state.overlayPos = stream.start; + } + + if (stream.start == state.basePos) { + state.baseCur = base.token(stream, state.base); + state.basePos = stream.pos; + } + if (stream.start == state.overlayPos) { + stream.pos = stream.start; + state.overlayCur = overlay.token(stream, state.overlay); + state.overlayPos = stream.pos; + } + stream.pos = Math.min(state.basePos, state.overlayPos); + + // state.overlay.combineTokens always takes precedence over combine, + // unless set to null + if (state.overlayCur == null) return state.baseCur; + else if (state.baseCur != null && + state.overlay.combineTokens || + combine && state.overlay.combineTokens == null) + return state.baseCur + " " + state.overlayCur; + else return state.overlayCur; + }, + + indent: base.indent && function(state, textAfter, line) { + return base.indent(state.base, textAfter, line); + }, + electricChars: base.electricChars, + + innerMode: function(state) { return {state: state.base, mode: base}; }, + + blankLine: function(state) { + var baseToken, overlayToken; + if (base.blankLine) baseToken = base.blankLine(state.base); + if (overlay.blankLine) overlayToken = overlay.blankLine(state.overlay); + + return overlayToken == null ? + baseToken : + (combine && baseToken != null ? baseToken + " " + overlayToken : overlayToken); + } + }; + }; - // Detect drag-and-drop - var dragAndDrop = function () { - // There is *some* kind of drag-and-drop support in IE6-8, but I - // couldn't get it to work yet. - if (ie && ie_version < 9) { return false } - var div = elt('div'); - return "draggable" in div || "dragDrop" in div - }(); - - var zwspSupported; - function zeroWidthElement(measure) { - if (zwspSupported == null) { - var test = elt("span", "\u200b"); - removeChildrenAndAdd(measure, elt("span", [test, document.createTextNode("x")])); - if (measure.firstChild.offsetHeight != 0) { zwspSupported = test.offsetWidth <= 1 && test.offsetHeight > 2 && !(ie && ie_version < 8); } - } - var node = zwspSupported ? elt("span", "\u200b") : - elt("span", "\u00a0", null, "display: inline-block; width: 1px; margin-right: -1px"); - node.setAttribute("cm-text", ""); - return node - } + }); + }); - // Feature-detect IE's crummy client rect reporting for bidi text - var badBidiRects; - function hasBadBidiRects(measure) { - if (badBidiRects != null) { return badBidiRects } - var txt = removeChildrenAndAdd(measure, document.createTextNode("A\u062eA")); - var r0 = range(txt, 0, 1).getBoundingClientRect(); - var r1 = range(txt, 1, 2).getBoundingClientRect(); - removeChildren(measure); - if (!r0 || r0.left == r0.right) { return false } // Safari returns null in some cases (#2780) - return badBidiRects = (r1.right - r0.right < 3) - } + var gfm = createCommonjsModule(function (module, exports) { + // CodeMirror, copyright (c) by Marijn Haverbeke and others + // Distributed under an MIT license: https://codemirror.net/LICENSE + + (function(mod) { + mod(codemirror, markdown, overlay); + })(function(CodeMirror) { + + var urlRE = /^((?:(?:aaas?|about|acap|adiumxtra|af[ps]|aim|apt|attachment|aw|beshare|bitcoin|bolo|callto|cap|chrome(?:-extension)?|cid|coap|com-eventbrite-attendee|content|crid|cvs|data|dav|dict|dlna-(?:playcontainer|playsingle)|dns|doi|dtn|dvb|ed2k|facetime|feed|file|finger|fish|ftp|geo|gg|git|gizmoproject|go|gopher|gtalk|h323|hcp|https?|iax|icap|icon|im|imap|info|ipn|ipp|irc[6s]?|iris(?:\.beep|\.lwz|\.xpc|\.xpcs)?|itms|jar|javascript|jms|keyparc|lastfm|ldaps?|magnet|mailto|maps|market|message|mid|mms|ms-help|msnim|msrps?|mtqp|mumble|mupdate|mvn|news|nfs|nih?|nntp|notes|oid|opaquelocktoken|palm|paparazzi|platform|pop|pres|proxy|psyc|query|res(?:ource)?|rmi|rsync|rtmp|rtsp|secondlife|service|session|sftp|sgn|shttp|sieve|sips?|skype|sm[bs]|snmp|soap\.beeps?|soldat|spotify|ssh|steam|svn|tag|teamspeak|tel(?:net)?|tftp|things|thismessage|tip|tn3270|tv|udp|unreal|urn|ut2004|vemmi|ventrilo|view-source|webcal|wss?|wtai|wyciwyg|xcon(?:-userid)?|xfire|xmlrpc\.beeps?|xmpp|xri|ymsgr|z39\.50[rs]?):(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]|\([^\s()<>]*\))+(?:\([^\s()<>]*\)|[^\s`*!()\[\]{};:'".,<>?«»“”‘’]))/i; + + CodeMirror.defineMode("gfm", function(config, modeConfig) { + var codeDepth = 0; + function blankLine(state) { + state.code = false; + return null; + } + var gfmOverlay = { + startState: function() { + return { + code: false, + codeBlock: false, + ateSpace: false + }; + }, + copyState: function(s) { + return { + code: s.code, + codeBlock: s.codeBlock, + ateSpace: s.ateSpace + }; + }, + token: function(stream, state) { + state.combineTokens = null; + + // Hack to prevent formatting override inside code blocks (block and inline) + if (state.codeBlock) { + if (stream.match(/^```+/)) { + state.codeBlock = false; + return null; + } + stream.skipToEnd(); + return null; + } + if (stream.sol()) { + state.code = false; + } + if (stream.sol() && stream.match(/^```+/)) { + stream.skipToEnd(); + state.codeBlock = true; + return null; + } + // If this block is changed, it may need to be updated in Markdown mode + if (stream.peek() === '`') { + stream.next(); + var before = stream.pos; + stream.eatWhile('`'); + var difference = 1 + stream.pos - before; + if (!state.code) { + codeDepth = difference; + state.code = true; + } else { + if (difference === codeDepth) { // Must be exact + state.code = false; + } + } + return null; + } else if (state.code) { + stream.next(); + return null; + } + // Check if space. If so, links can be formatted later on + if (stream.eatSpace()) { + state.ateSpace = true; + return null; + } + if (stream.sol() || state.ateSpace) { + state.ateSpace = false; + if (modeConfig.gitHubSpice !== false) { + if(stream.match(/^(?:[a-zA-Z0-9\-_]+\/)?(?:[a-zA-Z0-9\-_]+@)?(?=.{0,6}\d)(?:[a-f0-9]{7,40}\b)/)) { + // User/Project@SHA + // User@SHA + // SHA + state.combineTokens = true; + return "link"; + } else if (stream.match(/^(?:[a-zA-Z0-9\-_]+\/)?(?:[a-zA-Z0-9\-_]+)?#[0-9]+\b/)) { + // User/Project#Num + // User#Num + // #Num + state.combineTokens = true; + return "link"; + } + } + } + if (stream.match(urlRE) && + stream.string.slice(stream.start - 2, stream.start) != "](" && + (stream.start == 0 || /\W/.test(stream.string.charAt(stream.start - 1)))) { + // URLs + // Taken from http://daringfireball.net/2010/07/improved_regex_for_matching_urls + // And then (issue #1160) simplified to make it not crash the Chrome Regexp engine + // And then limited url schemes to the CommonMark list, so foo:bar isn't matched as a URL + state.combineTokens = true; + return "link"; + } + stream.next(); + return null; + }, + blankLine: blankLine + }; + + var markdownConfig = { + taskLists: true, + strikethrough: true, + emoji: true + }; + for (var attr in modeConfig) { + markdownConfig[attr] = modeConfig[attr]; + } + markdownConfig.name = "markdown"; + return CodeMirror.overlayMode(CodeMirror.getMode(config, markdownConfig), gfmOverlay); + + }, "markdown"); + + CodeMirror.defineMIME("text/x-gfm", "gfm"); + }); + }); - // See if "".split is the broken IE version, if so, provide an - // alternative way to split lines. - var splitLinesAuto = "\n\nb".split(/\n/).length != 3 ? function (string) { - var pos = 0, result = [], l = string.length; - while (pos <= l) { - var nl = string.indexOf("\n", pos); - if (nl == -1) { nl = string.length; } - var line = string.slice(pos, string.charAt(nl - 1) == "\r" ? nl - 1 : nl); - var rt = line.indexOf("\r"); - if (rt != -1) { - result.push(line.slice(0, rt)); - pos += rt + 1; - } else { - result.push(line); - pos = nl + 1; - } - } - return result - } : function (string) { return string.split(/\r\n?|\n/); }; - - var hasSelection = window.getSelection ? function (te) { - try { return te.selectionStart != te.selectionEnd } - catch (e) { return false } - } : function (te) { - var range; - try { range = te.ownerDocument.selection.createRange(); } - catch (e) { } - if (!range || range.parentElement() != te) { return false } - return range.compareEndPoints("StartToEnd", range) != 0 - }; + var continuelist = createCommonjsModule(function (module, exports) { + // CodeMirror, copyright (c) by Marijn Haverbeke and others + // Distributed under an MIT license: https://codemirror.net/LICENSE + + (function(mod) { + mod(codemirror); + })(function(CodeMirror) { + + var listRE = /^(\s*)(>[> ]*|[*+-] \[[x ]\]\s|[*+-]\s|(\d+)([.)]))(\s*)/, + emptyListRE = /^(\s*)(>[> ]*|[*+-] \[[x ]\]|[*+-]|(\d+)[.)])(\s*)$/, + unorderedListRE = /[*+-]\s/; + + CodeMirror.commands.newlineAndIndentContinueMarkdownList = function(cm) { + if (cm.getOption("disableInput")) return CodeMirror.Pass; + var ranges = cm.listSelections(), replacements = []; + for (var i = 0; i < ranges.length; i++) { + var pos = ranges[i].head; + + // If we're not in Markdown mode, fall back to normal newlineAndIndent + var eolState = cm.getStateAfter(pos.line); + var inner = CodeMirror.innerMode(cm.getMode(), eolState); + if (inner.mode.name !== "markdown") { + cm.execCommand("newlineAndIndent"); + return; + } else { + eolState = inner.state; + } + + var inList = eolState.list !== false; + var inQuote = eolState.quote !== 0; + + var line = cm.getLine(pos.line), match = listRE.exec(line); + var cursorBeforeBullet = /^\s*$/.test(line.slice(0, pos.ch)); + if (!ranges[i].empty() || (!inList && !inQuote) || !match || cursorBeforeBullet) { + cm.execCommand("newlineAndIndent"); + return; + } + if (emptyListRE.test(line)) { + var endOfQuote = inQuote && />\s*$/.test(line); + var endOfList = !/>\s*$/.test(line); + if (endOfQuote || endOfList) cm.replaceRange("", { + line: pos.line, ch: 0 + }, { + line: pos.line, ch: pos.ch + 1 + }); + replacements[i] = "\n"; + } else { + var indent = match[1], after = match[5]; + var numbered = !(unorderedListRE.test(match[2]) || match[2].indexOf(">") >= 0); + var bullet = numbered ? (parseInt(match[3], 10) + 1) + match[4] : match[2].replace("x", " "); + replacements[i] = "\n" + indent + bullet + after; + + if (numbered) incrementRemainingMarkdownListNumbers(cm, pos); + } + } + + cm.replaceSelections(replacements); + }; + + // Auto-updating Markdown list numbers when a new item is added to the + // middle of a list + function incrementRemainingMarkdownListNumbers(cm, pos) { + var startLine = pos.line, lookAhead = 0, skipCount = 0; + var startItem = listRE.exec(cm.getLine(startLine)), startIndent = startItem[1]; + + do { + lookAhead += 1; + var nextLineNumber = startLine + lookAhead; + var nextLine = cm.getLine(nextLineNumber), nextItem = listRE.exec(nextLine); + + if (nextItem) { + var nextIndent = nextItem[1]; + var newNumber = (parseInt(startItem[3], 10) + lookAhead - skipCount); + var nextNumber = (parseInt(nextItem[3], 10)), itemNumber = nextNumber; + + if (startIndent === nextIndent && !isNaN(nextNumber)) { + if (newNumber === nextNumber) itemNumber = nextNumber + 1; + if (newNumber > nextNumber) itemNumber = newNumber + 1; + cm.replaceRange( + nextLine.replace(listRE, nextIndent + itemNumber + nextItem[4] + nextItem[5]), + { + line: nextLineNumber, ch: 0 + }, { + line: nextLineNumber, ch: nextLine.length + }); + } else { + if (startIndent.length > nextIndent.length) return; + // This doesn't run if the next line immediatley indents, as it is + // not clear of the users intention (new indented item or same level) + if ((startIndent.length < nextIndent.length) && (lookAhead === 1)) return; + skipCount += 1; + } + } + } while (nextItem); + } + }); + }); - var hasCopyEvent = (function () { - var e = elt("div"); - if ("oncopy" in e) { return true } - e.setAttribute("oncopy", "return;"); - return typeof e.oncopy == "function" - })(); - - var badZoomedRects = null; - function hasBadZoomedRects(measure) { - if (badZoomedRects != null) { return badZoomedRects } - var node = removeChildrenAndAdd(measure, elt("span", "x")); - var normal = node.getBoundingClientRect(); - var fromRange = range(node, 0, 1).getBoundingClientRect(); - return badZoomedRects = Math.abs(normal.left - fromRange.left) > 1 - } + var xmlFold = createCommonjsModule(function (module, exports) { + // CodeMirror, copyright (c) by Marijn Haverbeke and others + // Distributed under an MIT license: https://codemirror.net/LICENSE + + (function(mod) { + mod(codemirror); + })(function(CodeMirror) { + + var Pos = CodeMirror.Pos; + function cmp(a, b) { return a.line - b.line || a.ch - b.ch; } + + var nameStartChar = "A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD"; + var nameChar = nameStartChar + "\-\:\.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040"; + var xmlTagStart = new RegExp("<(/?)([" + nameStartChar + "][" + nameChar + "]*)", "g"); + + function Iter(cm, line, ch, range) { + this.line = line; this.ch = ch; + this.cm = cm; this.text = cm.getLine(line); + this.min = range ? Math.max(range.from, cm.firstLine()) : cm.firstLine(); + this.max = range ? Math.min(range.to - 1, cm.lastLine()) : cm.lastLine(); + } + + function tagAt(iter, ch) { + var type = iter.cm.getTokenTypeAt(Pos(iter.line, ch)); + return type && /\btag\b/.test(type); + } + + function nextLine(iter) { + if (iter.line >= iter.max) return; + iter.ch = 0; + iter.text = iter.cm.getLine(++iter.line); + return true; + } + function prevLine(iter) { + if (iter.line <= iter.min) return; + iter.text = iter.cm.getLine(--iter.line); + iter.ch = iter.text.length; + return true; + } + + function toTagEnd(iter) { + for (;;) { + var gt = iter.text.indexOf(">", iter.ch); + if (gt == -1) { if (nextLine(iter)) continue; else return; } + if (!tagAt(iter, gt + 1)) { iter.ch = gt + 1; continue; } + var lastSlash = iter.text.lastIndexOf("/", gt); + var selfClose = lastSlash > -1 && !/\S/.test(iter.text.slice(lastSlash + 1, gt)); + iter.ch = gt + 1; + return selfClose ? "selfClose" : "regular"; + } + } + function toTagStart(iter) { + for (;;) { + var lt = iter.ch ? iter.text.lastIndexOf("<", iter.ch - 1) : -1; + if (lt == -1) { if (prevLine(iter)) continue; else return; } + if (!tagAt(iter, lt + 1)) { iter.ch = lt; continue; } + xmlTagStart.lastIndex = lt; + iter.ch = lt; + var match = xmlTagStart.exec(iter.text); + if (match && match.index == lt) return match; + } + } + + function toNextTag(iter) { + for (;;) { + xmlTagStart.lastIndex = iter.ch; + var found = xmlTagStart.exec(iter.text); + if (!found) { if (nextLine(iter)) continue; else return; } + if (!tagAt(iter, found.index + 1)) { iter.ch = found.index + 1; continue; } + iter.ch = found.index + found[0].length; + return found; + } + } + function toPrevTag(iter) { + for (;;) { + var gt = iter.ch ? iter.text.lastIndexOf(">", iter.ch - 1) : -1; + if (gt == -1) { if (prevLine(iter)) continue; else return; } + if (!tagAt(iter, gt + 1)) { iter.ch = gt; continue; } + var lastSlash = iter.text.lastIndexOf("/", gt); + var selfClose = lastSlash > -1 && !/\S/.test(iter.text.slice(lastSlash + 1, gt)); + iter.ch = gt + 1; + return selfClose ? "selfClose" : "regular"; + } + } + + function findMatchingClose(iter, tag) { + var stack = []; + for (;;) { + var next = toNextTag(iter), end, startLine = iter.line, startCh = iter.ch - (next ? next[0].length : 0); + if (!next || !(end = toTagEnd(iter))) return; + if (end == "selfClose") continue; + if (next[1]) { // closing tag + for (var i = stack.length - 1; i >= 0; --i) if (stack[i] == next[2]) { + stack.length = i; + break; + } + if (i < 0 && (!tag || tag == next[2])) return { + tag: next[2], + from: Pos(startLine, startCh), + to: Pos(iter.line, iter.ch) + }; + } else { // opening tag + stack.push(next[2]); + } + } + } + function findMatchingOpen(iter, tag) { + var stack = []; + for (;;) { + var prev = toPrevTag(iter); + if (!prev) return; + if (prev == "selfClose") { toTagStart(iter); continue; } + var endLine = iter.line, endCh = iter.ch; + var start = toTagStart(iter); + if (!start) return; + if (start[1]) { // closing tag + stack.push(start[2]); + } else { // opening tag + for (var i = stack.length - 1; i >= 0; --i) if (stack[i] == start[2]) { + stack.length = i; + break; + } + if (i < 0 && (!tag || tag == start[2])) return { + tag: start[2], + from: Pos(iter.line, iter.ch), + to: Pos(endLine, endCh) + }; + } + } + } + + CodeMirror.registerHelper("fold", "xml", function(cm, start) { + var iter = new Iter(cm, start.line, 0); + for (;;) { + var openTag = toNextTag(iter); + if (!openTag || iter.line != start.line) return + var end = toTagEnd(iter); + if (!end) return + if (!openTag[1] && end != "selfClose") { + var startPos = Pos(iter.line, iter.ch); + var endPos = findMatchingClose(iter, openTag[2]); + return endPos && cmp(endPos.from, startPos) > 0 ? {from: startPos, to: endPos.from} : null + } + } + }); + CodeMirror.findMatchingTag = function(cm, pos, range) { + var iter = new Iter(cm, pos.line, pos.ch, range); + if (iter.text.indexOf(">") == -1 && iter.text.indexOf("<") == -1) return; + var end = toTagEnd(iter), to = end && Pos(iter.line, iter.ch); + var start = end && toTagStart(iter); + if (!end || !start || cmp(iter, pos) > 0) return; + var here = {from: Pos(iter.line, iter.ch), to: to, tag: start[2]}; + if (end == "selfClose") return {open: here, close: null, at: "open"}; + + if (start[1]) { // closing tag + return {open: findMatchingOpen(iter, start[2]), close: here, at: "close"}; + } else { // opening tag + iter = new Iter(cm, to.line, to.ch, range); + return {open: here, close: findMatchingClose(iter, start[2]), at: "open"}; + } + }; + + CodeMirror.findEnclosingTag = function(cm, pos, range, tag) { + var iter = new Iter(cm, pos.line, pos.ch, range); + for (;;) { + var open = findMatchingOpen(iter, tag); + if (!open) break; + var forward = new Iter(cm, pos.line, pos.ch, range); + var close = findMatchingClose(forward, open.tag); + if (close) return {open: open, close: close}; + } + }; + + // Used by addon/edit/closetag.js + CodeMirror.scanForClosingTag = function(cm, pos, name, end) { + var iter = new Iter(cm, pos.line, pos.ch, end ? {from: 0, to: end} : null); + return findMatchingClose(iter, name); + }; + }); + }); - // Known modes, by name and by MIME - var modes = {}, mimeModes = {}; + var closetag = createCommonjsModule(function (module, exports) { + // CodeMirror, copyright (c) by Marijn Haverbeke and others + // Distributed under an MIT license: https://codemirror.net/LICENSE - // Extra arguments are stored as the mode's dependencies, which is - // used by (legacy) mechanisms like loadmode.js to automatically - // load a mode. (Preferred mechanism is the require/define calls.) - function defineMode(name, mode) { - if (arguments.length > 2) { mode.dependencies = Array.prototype.slice.call(arguments, 2); } - modes[name] = mode; - } + /** + * Tag-closer extension for CodeMirror. + * + * This extension adds an "autoCloseTags" option that can be set to + * either true to get the default behavior, or an object to further + * configure its behavior. + * + * These are supported options: + * + * `whenClosing` (default true) + * Whether to autoclose when the '/' of a closing tag is typed. + * `whenOpening` (default true) + * Whether to autoclose the tag when the final '>' of an opening + * tag is typed. + * `dontCloseTags` (default is empty tags for HTML, none for XML) + * An array of tag names that should not be autoclosed. + * `indentTags` (default is block tags for HTML, none for XML) + * An array of tag names that should, when opened, cause a + * blank line to be added inside the tag, and the blank line and + * closing line to be indented. + * `emptyTags` (default is none) + * An array of XML tag names that should be autoclosed with '/>'. + * + * See demos/closetag.html for a usage example. + */ - function defineMIME(mime, spec) { - mimeModes[mime] = spec; - } + (function(mod) { + mod(codemirror, xmlFold); + })(function(CodeMirror) { + CodeMirror.defineOption("autoCloseTags", false, function(cm, val, old) { + if (old != CodeMirror.Init && old) + cm.removeKeyMap("autoCloseTags"); + if (!val) return; + var map = {name: "autoCloseTags"}; + if (typeof val != "object" || val.whenClosing !== false) + map["'/'"] = function(cm) { return autoCloseSlash(cm); }; + if (typeof val != "object" || val.whenOpening !== false) + map["'>'"] = function(cm) { return autoCloseGT(cm); }; + cm.addKeyMap(map); + }); + + var htmlDontClose = ["area", "base", "br", "col", "command", "embed", "hr", "img", "input", "keygen", "link", "meta", "param", + "source", "track", "wbr"]; + var htmlIndent = ["applet", "blockquote", "body", "button", "div", "dl", "fieldset", "form", "frameset", "h1", "h2", "h3", "h4", + "h5", "h6", "head", "html", "iframe", "layer", "legend", "object", "ol", "p", "select", "table", "ul"]; + + function autoCloseGT(cm) { + if (cm.getOption("disableInput")) return CodeMirror.Pass; + var ranges = cm.listSelections(), replacements = []; + var opt = cm.getOption("autoCloseTags"); + for (var i = 0; i < ranges.length; i++) { + if (!ranges[i].empty()) return CodeMirror.Pass; + var pos = ranges[i].head, tok = cm.getTokenAt(pos); + var inner = CodeMirror.innerMode(cm.getMode(), tok.state), state = inner.state; + var tagInfo = inner.mode.xmlCurrentTag && inner.mode.xmlCurrentTag(state); + var tagName = tagInfo && tagInfo.name; + if (!tagName) return CodeMirror.Pass + + var html = inner.mode.configuration == "html"; + var dontCloseTags = (typeof opt == "object" && opt.dontCloseTags) || (html && htmlDontClose); + var indentTags = (typeof opt == "object" && opt.indentTags) || (html && htmlIndent); + + if (tok.end > pos.ch) tagName = tagName.slice(0, tagName.length - tok.end + pos.ch); + var lowerTagName = tagName.toLowerCase(); + // Don't process the '>' at the end of an end-tag or self-closing tag + if (!tagName || + tok.type == "string" && (tok.end != pos.ch || !/[\"\']/.test(tok.string.charAt(tok.string.length - 1)) || tok.string.length == 1) || + tok.type == "tag" && tagInfo.close || + tok.string.indexOf("/") == (pos.ch - tok.start - 1) || // match something like + dontCloseTags && indexOf(dontCloseTags, lowerTagName) > -1 || + closingTagExists(cm, inner.mode.xmlCurrentContext && inner.mode.xmlCurrentContext(state) || [], tagName, pos, true)) + return CodeMirror.Pass; + + var emptyTags = typeof opt == "object" && opt.emptyTags; + if (emptyTags && indexOf(emptyTags, tagName) > -1) { + replacements[i] = { text: "/>", newPos: CodeMirror.Pos(pos.line, pos.ch + 2) }; + continue; + } + + var indent = indentTags && indexOf(indentTags, lowerTagName) > -1; + replacements[i] = {indent: indent, + text: ">" + (indent ? "\n\n" : "") + "", + newPos: indent ? CodeMirror.Pos(pos.line + 1, 0) : CodeMirror.Pos(pos.line, pos.ch + 1)}; + } + + var dontIndentOnAutoClose = (typeof opt == "object" && opt.dontIndentOnAutoClose); + for (var i = ranges.length - 1; i >= 0; i--) { + var info = replacements[i]; + cm.replaceRange(info.text, ranges[i].head, ranges[i].anchor, "+insert"); + var sel = cm.listSelections().slice(0); + sel[i] = {head: info.newPos, anchor: info.newPos}; + cm.setSelections(sel); + if (!dontIndentOnAutoClose && info.indent) { + cm.indentLine(info.newPos.line, null, true); + cm.indentLine(info.newPos.line + 1, null, true); + } + } + } + + function autoCloseCurrent(cm, typingSlash) { + var ranges = cm.listSelections(), replacements = []; + var head = typingSlash ? "/" : "") replacement += ">"; + replacements[i] = replacement; + } + cm.replaceSelections(replacements); + ranges = cm.listSelections(); + if (!dontIndentOnAutoClose) { + for (var i = 0; i < ranges.length; i++) + if (i == ranges.length - 1 || ranges[i].head.line < ranges[i + 1].head.line) + cm.indentLine(ranges[i].head.line); + } + } + + function autoCloseSlash(cm) { + if (cm.getOption("disableInput")) return CodeMirror.Pass; + return autoCloseCurrent(cm, true); + } + + CodeMirror.commands.closeTag = function(cm) { return autoCloseCurrent(cm); }; + + function indexOf(collection, elt) { + if (collection.indexOf) return collection.indexOf(elt); + for (var i = 0, e = collection.length; i < e; ++i) + if (collection[i] == elt) return i; + return -1; + } + + // If xml-fold is loaded, we use its functionality to try and verify + // whether a given tag is actually unclosed. + function closingTagExists(cm, context, tagName, pos, newTag) { + if (!CodeMirror.scanForClosingTag) return false; + var end = Math.min(cm.lastLine() + 1, pos.line + 500); + var nextClose = CodeMirror.scanForClosingTag(cm, pos, null, end); + if (!nextClose || nextClose.tag != tagName) return false; + // If the immediate wrapping context contains onCx instances of + // the same tag, a closing tag only exists if there are at least + // that many closing tags of that type following. + var onCx = newTag ? 1 : 0; + for (var i = context.length - 1; i >= 0; i--) { + if (context[i] == tagName) ++onCx; + else break + } + pos = nextClose.to; + for (var i = 1; i < onCx; i++) { + var next = CodeMirror.scanForClosingTag(cm, pos, null, end); + if (!next || next.tag != tagName) return false; + pos = next.to; + } + return true; + } + }); + }); - // Given a MIME type, a {name, ...options} config object, or a name - // string, return a mode config object. - function resolveMode(spec) { - if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) { - spec = mimeModes[spec]; - } else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) { - var found = mimeModes[spec.name]; - if (typeof found == "string") { found = { name: found }; } - spec = createObj(found, spec); - spec.name = found.name; - } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+xml$/.test(spec)) { - return resolveMode("application/xml") - } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+json$/.test(spec)) { - return resolveMode("application/json") - } - if (typeof spec == "string") { return { name: spec } } - else { return spec || { name: "null" } } - } + var matchtags = createCommonjsModule(function (module, exports) { + // CodeMirror, copyright (c) by Marijn Haverbeke and others + // Distributed under an MIT license: https://codemirror.net/LICENSE + + (function(mod) { + mod(codemirror, xmlFold); + })(function(CodeMirror) { + + CodeMirror.defineOption("matchTags", false, function(cm, val, old) { + if (old && old != CodeMirror.Init) { + cm.off("cursorActivity", doMatchTags); + cm.off("viewportChange", maybeUpdateMatch); + clear(cm); + } + if (val) { + cm.state.matchBothTags = typeof val == "object" && val.bothTags; + cm.on("cursorActivity", doMatchTags); + cm.on("viewportChange", maybeUpdateMatch); + doMatchTags(cm); + } + }); + + function clear(cm) { + if (cm.state.tagHit) cm.state.tagHit.clear(); + if (cm.state.tagOther) cm.state.tagOther.clear(); + cm.state.tagHit = cm.state.tagOther = null; + } + + function doMatchTags(cm) { + cm.state.failedTagMatch = false; + cm.operation(function() { + clear(cm); + if (cm.somethingSelected()) return; + var cur = cm.getCursor(), range = cm.getViewport(); + range.from = Math.min(range.from, cur.line); range.to = Math.max(cur.line + 1, range.to); + var match = CodeMirror.findMatchingTag(cm, cur, range); + if (!match) return; + if (cm.state.matchBothTags) { + var hit = match.at == "open" ? match.open : match.close; + if (hit) cm.state.tagHit = cm.markText(hit.from, hit.to, {className: "CodeMirror-matchingtag"}); + } + var other = match.at == "close" ? match.open : match.close; + if (other) + cm.state.tagOther = cm.markText(other.from, other.to, {className: "CodeMirror-matchingtag"}); + else + cm.state.failedTagMatch = true; + }); + } + + function maybeUpdateMatch(cm) { + if (cm.state.failedTagMatch) doMatchTags(cm); + } + + CodeMirror.commands.toMatchingTag = function(cm) { + var found = CodeMirror.findMatchingTag(cm, cm.getCursor()); + if (found) { + var other = found.at == "close" ? found.open : found.close; + if (other) cm.extendSelection(other.to, other.from); + } + }; + }); + }); - // Given a mode spec (anything that resolveMode accepts), find and - // initialize an actual mode object. - function getMode(options, spec) { - spec = resolveMode(spec); - var mfactory = modes[spec.name]; - if (!mfactory) { return getMode(options, "text/plain") } - var modeObj = mfactory(options, spec); - if (modeExtensions.hasOwnProperty(spec.name)) { - var exts = modeExtensions[spec.name]; - for (var prop in exts) { - if (!exts.hasOwnProperty(prop)) { continue } - if (modeObj.hasOwnProperty(prop)) { modeObj["_" + prop] = modeObj[prop]; } - modeObj[prop] = exts[prop]; - } - } - modeObj.name = spec.name; - if (spec.helperType) { modeObj.helperType = spec.helperType; } - if (spec.modeProps) { - for (var prop$1 in spec.modeProps) { modeObj[prop$1] = spec.modeProps[prop$1]; } - } + var searchcursor = createCommonjsModule(function (module, exports) { + // CodeMirror, copyright (c) by Marijn Haverbeke and others + // Distributed under an MIT license: https://codemirror.net/LICENSE + + (function(mod) { + mod(codemirror); + })(function(CodeMirror) { + var Pos = CodeMirror.Pos; + + function regexpFlags(regexp) { + var flags = regexp.flags; + return flags != null ? flags : (regexp.ignoreCase ? "i" : "") + + (regexp.global ? "g" : "") + + (regexp.multiline ? "m" : "") + } + + function ensureFlags(regexp, flags) { + var current = regexpFlags(regexp), target = current; + for (var i = 0; i < flags.length; i++) if (target.indexOf(flags.charAt(i)) == -1) + target += flags.charAt(i); + return current == target ? regexp : new RegExp(regexp.source, target) + } + + function maybeMultiline(regexp) { + return /\\s|\\n|\n|\\W|\\D|\[\^/.test(regexp.source) + } + + function searchRegexpForward(doc, regexp, start) { + regexp = ensureFlags(regexp, "g"); + for (var line = start.line, ch = start.ch, last = doc.lastLine(); line <= last; line++, ch = 0) { + regexp.lastIndex = ch; + var string = doc.getLine(line), match = regexp.exec(string); + if (match) + return {from: Pos(line, match.index), + to: Pos(line, match.index + match[0].length), + match: match} + } + } + + function searchRegexpForwardMultiline(doc, regexp, start) { + if (!maybeMultiline(regexp)) return searchRegexpForward(doc, regexp, start) + + regexp = ensureFlags(regexp, "gm"); + var string, chunk = 1; + for (var line = start.line, last = doc.lastLine(); line <= last;) { + // This grows the search buffer in exponentially-sized chunks + // between matches, so that nearby matches are fast and don't + // require concatenating the whole document (in case we're + // searching for something that has tons of matches), but at the + // same time, the amount of retries is limited. + for (var i = 0; i < chunk; i++) { + if (line > last) break + var curLine = doc.getLine(line++); + string = string == null ? curLine : string + "\n" + curLine; + } + chunk = chunk * 2; + regexp.lastIndex = start.ch; + var match = regexp.exec(string); + if (match) { + var before = string.slice(0, match.index).split("\n"), inside = match[0].split("\n"); + var startLine = start.line + before.length - 1, startCh = before[before.length - 1].length; + return {from: Pos(startLine, startCh), + to: Pos(startLine + inside.length - 1, + inside.length == 1 ? startCh + inside[0].length : inside[inside.length - 1].length), + match: match} + } + } + } + + function lastMatchIn(string, regexp, endMargin) { + var match, from = 0; + while (from <= string.length) { + regexp.lastIndex = from; + var newMatch = regexp.exec(string); + if (!newMatch) break + var end = newMatch.index + newMatch[0].length; + if (end > string.length - endMargin) break + if (!match || end > match.index + match[0].length) + match = newMatch; + from = newMatch.index + 1; + } + return match + } + + function searchRegexpBackward(doc, regexp, start) { + regexp = ensureFlags(regexp, "g"); + for (var line = start.line, ch = start.ch, first = doc.firstLine(); line >= first; line--, ch = -1) { + var string = doc.getLine(line); + var match = lastMatchIn(string, regexp, ch < 0 ? 0 : string.length - ch); + if (match) + return {from: Pos(line, match.index), + to: Pos(line, match.index + match[0].length), + match: match} + } + } + + function searchRegexpBackwardMultiline(doc, regexp, start) { + if (!maybeMultiline(regexp)) return searchRegexpBackward(doc, regexp, start) + regexp = ensureFlags(regexp, "gm"); + var string, chunkSize = 1, endMargin = doc.getLine(start.line).length - start.ch; + for (var line = start.line, first = doc.firstLine(); line >= first;) { + for (var i = 0; i < chunkSize && line >= first; i++) { + var curLine = doc.getLine(line--); + string = string == null ? curLine : curLine + "\n" + string; + } + chunkSize *= 2; + + var match = lastMatchIn(string, regexp, endMargin); + if (match) { + var before = string.slice(0, match.index).split("\n"), inside = match[0].split("\n"); + var startLine = line + before.length, startCh = before[before.length - 1].length; + return {from: Pos(startLine, startCh), + to: Pos(startLine + inside.length - 1, + inside.length == 1 ? startCh + inside[0].length : inside[inside.length - 1].length), + match: match} + } + } + } + + var doFold, noFold; + if (String.prototype.normalize) { + doFold = function(str) { return str.normalize("NFD").toLowerCase() }; + noFold = function(str) { return str.normalize("NFD") }; + } else { + doFold = function(str) { return str.toLowerCase() }; + noFold = function(str) { return str }; + } + + // Maps a position in a case-folded line back to a position in the original line + // (compensating for codepoints increasing in number during folding) + function adjustPos(orig, folded, pos, foldFunc) { + if (orig.length == folded.length) return pos + for (var min = 0, max = pos + Math.max(0, orig.length - folded.length);;) { + if (min == max) return min + var mid = (min + max) >> 1; + var len = foldFunc(orig.slice(0, mid)).length; + if (len == pos) return mid + else if (len > pos) max = mid; + else min = mid + 1; + } + } + + function searchStringForward(doc, query, start, caseFold) { + // Empty string would match anything and never progress, so we + // define it to match nothing instead. + if (!query.length) return null + var fold = caseFold ? doFold : noFold; + var lines = fold(query).split(/\r|\n\r?/); + + search: for (var line = start.line, ch = start.ch, last = doc.lastLine() + 1 - lines.length; line <= last; line++, ch = 0) { + var orig = doc.getLine(line).slice(ch), string = fold(orig); + if (lines.length == 1) { + var found = string.indexOf(lines[0]); + if (found == -1) continue search + var start = adjustPos(orig, string, found, fold) + ch; + return {from: Pos(line, adjustPos(orig, string, found, fold) + ch), + to: Pos(line, adjustPos(orig, string, found + lines[0].length, fold) + ch)} + } else { + var cutFrom = string.length - lines[0].length; + if (string.slice(cutFrom) != lines[0]) continue search + for (var i = 1; i < lines.length - 1; i++) + if (fold(doc.getLine(line + i)) != lines[i]) continue search + var end = doc.getLine(line + lines.length - 1), endString = fold(end), lastLine = lines[lines.length - 1]; + if (endString.slice(0, lastLine.length) != lastLine) continue search + return {from: Pos(line, adjustPos(orig, string, cutFrom, fold) + ch), + to: Pos(line + lines.length - 1, adjustPos(end, endString, lastLine.length, fold))} + } + } + } + + function searchStringBackward(doc, query, start, caseFold) { + if (!query.length) return null + var fold = caseFold ? doFold : noFold; + var lines = fold(query).split(/\r|\n\r?/); + + search: for (var line = start.line, ch = start.ch, first = doc.firstLine() - 1 + lines.length; line >= first; line--, ch = -1) { + var orig = doc.getLine(line); + if (ch > -1) orig = orig.slice(0, ch); + var string = fold(orig); + if (lines.length == 1) { + var found = string.lastIndexOf(lines[0]); + if (found == -1) continue search + return {from: Pos(line, adjustPos(orig, string, found, fold)), + to: Pos(line, adjustPos(orig, string, found + lines[0].length, fold))} + } else { + var lastLine = lines[lines.length - 1]; + if (string.slice(0, lastLine.length) != lastLine) continue search + for (var i = 1, start = line - lines.length + 1; i < lines.length - 1; i++) + if (fold(doc.getLine(start + i)) != lines[i]) continue search + var top = doc.getLine(line + 1 - lines.length), topString = fold(top); + if (topString.slice(topString.length - lines[0].length) != lines[0]) continue search + return {from: Pos(line + 1 - lines.length, adjustPos(top, topString, top.length - lines[0].length, fold)), + to: Pos(line, adjustPos(orig, string, lastLine.length, fold))} + } + } + } + + function SearchCursor(doc, query, pos, options) { + this.atOccurrence = false; + this.doc = doc; + pos = pos ? doc.clipPos(pos) : Pos(0, 0); + this.pos = {from: pos, to: pos}; + + var caseFold; + if (typeof options == "object") { + caseFold = options.caseFold; + } else { // Backwards compat for when caseFold was the 4th argument + caseFold = options; + options = null; + } + + if (typeof query == "string") { + if (caseFold == null) caseFold = false; + this.matches = function(reverse, pos) { + return (reverse ? searchStringBackward : searchStringForward)(doc, query, pos, caseFold) + }; + } else { + query = ensureFlags(query, "gm"); + if (!options || options.multiline !== false) + this.matches = function(reverse, pos) { + return (reverse ? searchRegexpBackwardMultiline : searchRegexpForwardMultiline)(doc, query, pos) + }; + else + this.matches = function(reverse, pos) { + return (reverse ? searchRegexpBackward : searchRegexpForward)(doc, query, pos) + }; + } + } + + SearchCursor.prototype = { + findNext: function() {return this.find(false)}, + findPrevious: function() {return this.find(true)}, + + find: function(reverse) { + var result = this.matches(reverse, this.doc.clipPos(reverse ? this.pos.from : this.pos.to)); + + // Implements weird auto-growing behavior on null-matches for + // backwards-compatibility with the vim code (unfortunately) + while (result && CodeMirror.cmpPos(result.from, result.to) == 0) { + if (reverse) { + if (result.from.ch) result.from = Pos(result.from.line, result.from.ch - 1); + else if (result.from.line == this.doc.firstLine()) result = null; + else result = this.matches(reverse, this.doc.clipPos(Pos(result.from.line - 1))); + } else { + if (result.to.ch < this.doc.getLine(result.to.line).length) result.to = Pos(result.to.line, result.to.ch + 1); + else if (result.to.line == this.doc.lastLine()) result = null; + else result = this.matches(reverse, Pos(result.to.line + 1, 0)); + } + } + + if (result) { + this.pos = result; + this.atOccurrence = true; + return this.pos.match || true + } else { + var end = Pos(reverse ? this.doc.firstLine() : this.doc.lastLine() + 1, 0); + this.pos = {from: end, to: end}; + return this.atOccurrence = false + } + }, + + from: function() {if (this.atOccurrence) return this.pos.from}, + to: function() {if (this.atOccurrence) return this.pos.to}, + + replace: function(newText, origin) { + if (!this.atOccurrence) return + var lines = CodeMirror.splitLines(newText); + this.doc.replaceRange(lines, this.pos.from, this.pos.to, origin); + this.pos.to = Pos(this.pos.from.line + lines.length - 1, + lines[lines.length - 1].length + (lines.length == 1 ? this.pos.from.ch : 0)); + } + }; + + CodeMirror.defineExtension("getSearchCursor", function(query, pos, caseFold) { + return new SearchCursor(this.doc, query, pos, caseFold) + }); + CodeMirror.defineDocExtension("getSearchCursor", function(query, pos, caseFold) { + return new SearchCursor(this, query, pos, caseFold) + }); + + CodeMirror.defineExtension("selectMatches", function(query, caseFold) { + var ranges = []; + var cur = this.getSearchCursor(query, this.getCursor("from"), caseFold); + while (cur.findNext()) { + if (CodeMirror.cmpPos(cur.to(), this.getCursor("to")) > 0) break + ranges.push({anchor: cur.from(), head: cur.to()}); + } + if (ranges.length) + this.setSelections(ranges, 0); + }); + }); + }); - return modeObj - } + var placeholder = createCommonjsModule(function (module, exports) { + // CodeMirror, copyright (c) by Marijn Haverbeke and others + // Distributed under an MIT license: https://codemirror.net/LICENSE + + (function(mod) { + mod(codemirror); + })(function(CodeMirror) { + CodeMirror.defineOption("placeholder", "", function(cm, val, old) { + var prev = old && old != CodeMirror.Init; + if (val && !prev) { + cm.on("blur", onBlur); + cm.on("change", onChange); + cm.on("swapDoc", onChange); + CodeMirror.on(cm.getInputField(), "compositionupdate", cm.state.placeholderCompose = function() { onComposition(cm); }); + onChange(cm); + } else if (!val && prev) { + cm.off("blur", onBlur); + cm.off("change", onChange); + cm.off("swapDoc", onChange); + CodeMirror.off(cm.getInputField(), "compositionupdate", cm.state.placeholderCompose); + clearPlaceholder(cm); + var wrapper = cm.getWrapperElement(); + wrapper.className = wrapper.className.replace(" CodeMirror-empty", ""); + } + + if (val && !cm.hasFocus()) onBlur(cm); + }); + + function clearPlaceholder(cm) { + if (cm.state.placeholder) { + cm.state.placeholder.parentNode.removeChild(cm.state.placeholder); + cm.state.placeholder = null; + } + } + function setPlaceholder(cm) { + clearPlaceholder(cm); + var elt = cm.state.placeholder = document.createElement("pre"); + elt.style.cssText = "height: 0; overflow: visible"; + elt.style.direction = cm.getOption("direction"); + elt.className = "CodeMirror-placeholder CodeMirror-line-like"; + var placeHolder = cm.getOption("placeholder"); + if (typeof placeHolder == "string") placeHolder = document.createTextNode(placeHolder); + elt.appendChild(placeHolder); + cm.display.lineSpace.insertBefore(elt, cm.display.lineSpace.firstChild); + } + + function onComposition(cm) { + setTimeout(function() { + var empty = false, input = cm.getInputField(); + if (input.nodeName == "TEXTAREA") + empty = !input.value; + else if (cm.lineCount() == 1) + empty = !/[^\u200b]/.test(input.querySelector(".CodeMirror-line").textContent); + if (empty) setPlaceholder(cm); + else clearPlaceholder(cm); + }, 20); + } + + function onBlur(cm) { + if (isEmpty(cm)) setPlaceholder(cm); + } + function onChange(cm) { + var wrapper = cm.getWrapperElement(), empty = isEmpty(cm); + wrapper.className = wrapper.className.replace(" CodeMirror-empty", "") + (empty ? " CodeMirror-empty" : ""); + + if (empty) setPlaceholder(cm); + else clearPlaceholder(cm); + } + + function isEmpty(cm) { + return (cm.lineCount() === 1) && (cm.getLine(0) === ""); + } + }); + }); - // This can be used to attach properties to mode objects from - // outside the actual mode definition. - var modeExtensions = {}; - function extendMode(mode, properties) { - var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {}); - copyObj(properties, exts); - } + var matchbrackets = createCommonjsModule(function (module, exports) { + // CodeMirror, copyright (c) by Marijn Haverbeke and others + // Distributed under an MIT license: https://codemirror.net/LICENSE + + (function(mod) { + mod(codemirror); + })(function(CodeMirror) { + var ie_lt8 = /MSIE \d/.test(navigator.userAgent) && + (document.documentMode == null || document.documentMode < 8); + + var Pos = CodeMirror.Pos; + + var matching = {"(": ")>", ")": "(<", "[": "]>", "]": "[<", "{": "}>", "}": "{<", "<": ">>", ">": "<<"}; + + function bracketRegex(config) { + return config && config.bracketRegex || /[(){}[\]]/ + } + + function findMatchingBracket(cm, where, config) { + var line = cm.getLineHandle(where.line), pos = where.ch - 1; + var afterCursor = config && config.afterCursor; + if (afterCursor == null) + afterCursor = /(^| )cm-fat-cursor($| )/.test(cm.getWrapperElement().className); + var re = bracketRegex(config); + + // A cursor is defined as between two characters, but in in vim command mode + // (i.e. not insert mode), the cursor is visually represented as a + // highlighted box on top of the 2nd character. Otherwise, we allow matches + // from before or after the cursor. + var match = (!afterCursor && pos >= 0 && re.test(line.text.charAt(pos)) && matching[line.text.charAt(pos)]) || + re.test(line.text.charAt(pos + 1)) && matching[line.text.charAt(++pos)]; + if (!match) return null; + var dir = match.charAt(1) == ">" ? 1 : -1; + if (config && config.strict && (dir > 0) != (pos == where.ch)) return null; + var style = cm.getTokenTypeAt(Pos(where.line, pos + 1)); + + var found = scanForBracket(cm, Pos(where.line, pos + (dir > 0 ? 1 : 0)), dir, style || null, config); + if (found == null) return null; + return {from: Pos(where.line, pos), to: found && found.pos, + match: found && found.ch == match.charAt(0), forward: dir > 0}; + } + + // bracketRegex is used to specify which type of bracket to scan + // should be a regexp, e.g. /[[\]]/ + // + // Note: If "where" is on an open bracket, then this bracket is ignored. + // + // Returns false when no bracket was found, null when it reached + // maxScanLines and gave up + function scanForBracket(cm, where, dir, style, config) { + var maxScanLen = (config && config.maxScanLineLength) || 10000; + var maxScanLines = (config && config.maxScanLines) || 1000; + + var stack = []; + var re = bracketRegex(config); + var lineEnd = dir > 0 ? Math.min(where.line + maxScanLines, cm.lastLine() + 1) + : Math.max(cm.firstLine() - 1, where.line - maxScanLines); + for (var lineNo = where.line; lineNo != lineEnd; lineNo += dir) { + var line = cm.getLine(lineNo); + if (!line) continue; + var pos = dir > 0 ? 0 : line.length - 1, end = dir > 0 ? line.length : -1; + if (line.length > maxScanLen) continue; + if (lineNo == where.line) pos = where.ch - (dir < 0 ? 1 : 0); + for (; pos != end; pos += dir) { + var ch = line.charAt(pos); + if (re.test(ch) && (style === undefined || cm.getTokenTypeAt(Pos(lineNo, pos + 1)) == style)) { + var match = matching[ch]; + if (match && (match.charAt(1) == ">") == (dir > 0)) stack.push(ch); + else if (!stack.length) return {pos: Pos(lineNo, pos), ch: ch}; + else stack.pop(); + } + } + } + return lineNo - dir == (dir > 0 ? cm.lastLine() : cm.firstLine()) ? false : null; + } + + function matchBrackets(cm, autoclear, config) { + // Disable brace matching in long lines, since it'll cause hugely slow updates + var maxHighlightLen = cm.state.matchBrackets.maxHighlightLineLength || 1000; + var marks = [], ranges = cm.listSelections(); + for (var i = 0; i < ranges.length; i++) { + var match = ranges[i].empty() && findMatchingBracket(cm, ranges[i].head, config); + if (match && cm.getLine(match.from.line).length <= maxHighlightLen) { + var style = match.match ? "CodeMirror-matchingbracket" : "CodeMirror-nonmatchingbracket"; + marks.push(cm.markText(match.from, Pos(match.from.line, match.from.ch + 1), {className: style})); + if (match.to && cm.getLine(match.to.line).length <= maxHighlightLen) + marks.push(cm.markText(match.to, Pos(match.to.line, match.to.ch + 1), {className: style})); + } + } + + if (marks.length) { + // Kludge to work around the IE bug from issue #1193, where text + // input stops going to the textare whever this fires. + if (ie_lt8 && cm.state.focused) cm.focus(); + + var clear = function() { + cm.operation(function() { + for (var i = 0; i < marks.length; i++) marks[i].clear(); + }); + }; + if (autoclear) setTimeout(clear, 800); + else return clear; + } + } + + function doMatchBrackets(cm) { + cm.operation(function() { + if (cm.state.matchBrackets.currentlyHighlighted) { + cm.state.matchBrackets.currentlyHighlighted(); + cm.state.matchBrackets.currentlyHighlighted = null; + } + cm.state.matchBrackets.currentlyHighlighted = matchBrackets(cm, false, cm.state.matchBrackets); + }); + } + + CodeMirror.defineOption("matchBrackets", false, function(cm, val, old) { + function clear(cm) { + if (cm.state.matchBrackets && cm.state.matchBrackets.currentlyHighlighted) { + cm.state.matchBrackets.currentlyHighlighted(); + cm.state.matchBrackets.currentlyHighlighted = null; + } + } + + if (old && old != CodeMirror.Init) { + cm.off("cursorActivity", doMatchBrackets); + cm.off("focus", doMatchBrackets); + cm.off("blur", clear); + clear(cm); + } + if (val) { + cm.state.matchBrackets = typeof val == "object" ? val : {}; + cm.on("cursorActivity", doMatchBrackets); + cm.on("focus", doMatchBrackets); + cm.on("blur", clear); + } + }); + + CodeMirror.defineExtension("matchBrackets", function() {matchBrackets(this, true);}); + CodeMirror.defineExtension("findMatchingBracket", function(pos, config, oldConfig){ + // Backwards-compatibility kludge + if (oldConfig || typeof config == "boolean") { + if (!oldConfig) { + config = config ? {strict: true} : null; + } else { + oldConfig.strict = config; + config = oldConfig; + } + } + return findMatchingBracket(this, pos, config) + }); + CodeMirror.defineExtension("scanForBracket", function(pos, dir, style, config){ + return scanForBracket(this, pos, dir, style, config); + }); + }); + }); - function copyState(mode, state) { - if (state === true) { return state } - if (mode.copyState) { return mode.copyState(state) } - var nstate = {}; - for (var n in state) { - var val = state[n]; - if (val instanceof Array) { val = val.concat([]); } - nstate[n] = val; - } - return nstate - } + var sublime = createCommonjsModule(function (module, exports) { + // CodeMirror, copyright (c) by Marijn Haverbeke and others + // Distributed under an MIT license: https://codemirror.net/LICENSE + + // A rough approximation of Sublime Text's keybindings + // Depends on addon/search/searchcursor.js and optionally addon/dialog/dialogs.js + + (function(mod) { + mod(codemirror, searchcursor, matchbrackets); + })(function(CodeMirror) { + + var cmds = CodeMirror.commands; + var Pos = CodeMirror.Pos; + + // This is not exactly Sublime's algorithm. I couldn't make heads or tails of that. + function findPosSubword(doc, start, dir) { + if (dir < 0 && start.ch == 0) return doc.clipPos(Pos(start.line - 1)); + var line = doc.getLine(start.line); + if (dir > 0 && start.ch >= line.length) return doc.clipPos(Pos(start.line + 1, 0)); + var state = "start", type, startPos = start.ch; + for (var pos = startPos, e = dir < 0 ? 0 : line.length, i = 0; pos != e; pos += dir, i++) { + var next = line.charAt(dir < 0 ? pos - 1 : pos); + var cat = next != "_" && CodeMirror.isWordChar(next) ? "w" : "o"; + if (cat == "w" && next.toUpperCase() == next) cat = "W"; + if (state == "start") { + if (cat != "o") { state = "in"; type = cat; } + else startPos = pos + dir; + } else if (state == "in") { + if (type != cat) { + if (type == "w" && cat == "W" && dir < 0) pos--; + if (type == "W" && cat == "w" && dir > 0) { // From uppercase to lowercase + if (pos == startPos + 1) { type = "w"; continue; } + else pos--; + } + break; + } + } + } + return Pos(start.line, pos); + } + + function moveSubword(cm, dir) { + cm.extendSelectionsBy(function(range) { + if (cm.display.shift || cm.doc.extend || range.empty()) + return findPosSubword(cm.doc, range.head, dir); + else + return dir < 0 ? range.from() : range.to(); + }); + } + + cmds.goSubwordLeft = function(cm) { moveSubword(cm, -1); }; + cmds.goSubwordRight = function(cm) { moveSubword(cm, 1); }; + + cmds.scrollLineUp = function(cm) { + var info = cm.getScrollInfo(); + if (!cm.somethingSelected()) { + var visibleBottomLine = cm.lineAtHeight(info.top + info.clientHeight, "local"); + if (cm.getCursor().line >= visibleBottomLine) + cm.execCommand("goLineUp"); + } + cm.scrollTo(null, info.top - cm.defaultTextHeight()); + }; + cmds.scrollLineDown = function(cm) { + var info = cm.getScrollInfo(); + if (!cm.somethingSelected()) { + var visibleTopLine = cm.lineAtHeight(info.top, "local")+1; + if (cm.getCursor().line <= visibleTopLine) + cm.execCommand("goLineDown"); + } + cm.scrollTo(null, info.top + cm.defaultTextHeight()); + }; + + cmds.splitSelectionByLine = function(cm) { + var ranges = cm.listSelections(), lineRanges = []; + for (var i = 0; i < ranges.length; i++) { + var from = ranges[i].from(), to = ranges[i].to(); + for (var line = from.line; line <= to.line; ++line) + if (!(to.line > from.line && line == to.line && to.ch == 0)) + lineRanges.push({anchor: line == from.line ? from : Pos(line, 0), + head: line == to.line ? to : Pos(line)}); + } + cm.setSelections(lineRanges, 0); + }; + + cmds.singleSelectionTop = function(cm) { + var range = cm.listSelections()[0]; + cm.setSelection(range.anchor, range.head, {scroll: false}); + }; + + cmds.selectLine = function(cm) { + var ranges = cm.listSelections(), extended = []; + for (var i = 0; i < ranges.length; i++) { + var range = ranges[i]; + extended.push({anchor: Pos(range.from().line, 0), + head: Pos(range.to().line + 1, 0)}); + } + cm.setSelections(extended); + }; + + function insertLine(cm, above) { + if (cm.isReadOnly()) return CodeMirror.Pass + cm.operation(function() { + var len = cm.listSelections().length, newSelection = [], last = -1; + for (var i = 0; i < len; i++) { + var head = cm.listSelections()[i].head; + if (head.line <= last) continue; + var at = Pos(head.line + (above ? 0 : 1), 0); + cm.replaceRange("\n", at, null, "+insertLine"); + cm.indentLine(at.line, null, true); + newSelection.push({head: at, anchor: at}); + last = head.line + 1; + } + cm.setSelections(newSelection); + }); + cm.execCommand("indentAuto"); + } + + cmds.insertLineAfter = function(cm) { return insertLine(cm, false); }; + + cmds.insertLineBefore = function(cm) { return insertLine(cm, true); }; + + function wordAt(cm, pos) { + var start = pos.ch, end = start, line = cm.getLine(pos.line); + while (start && CodeMirror.isWordChar(line.charAt(start - 1))) --start; + while (end < line.length && CodeMirror.isWordChar(line.charAt(end))) ++end; + return {from: Pos(pos.line, start), to: Pos(pos.line, end), word: line.slice(start, end)}; + } + + cmds.selectNextOccurrence = function(cm) { + var from = cm.getCursor("from"), to = cm.getCursor("to"); + var fullWord = cm.state.sublimeFindFullWord == cm.doc.sel; + if (CodeMirror.cmpPos(from, to) == 0) { + var word = wordAt(cm, from); + if (!word.word) return; + cm.setSelection(word.from, word.to); + fullWord = true; + } else { + var text = cm.getRange(from, to); + var query = fullWord ? new RegExp("\\b" + text + "\\b") : text; + var cur = cm.getSearchCursor(query, to); + var found = cur.findNext(); + if (!found) { + cur = cm.getSearchCursor(query, Pos(cm.firstLine(), 0)); + found = cur.findNext(); + } + if (!found || isSelectedRange(cm.listSelections(), cur.from(), cur.to())) return + cm.addSelection(cur.from(), cur.to()); + } + if (fullWord) + cm.state.sublimeFindFullWord = cm.doc.sel; + }; + + cmds.skipAndSelectNextOccurrence = function(cm) { + var prevAnchor = cm.getCursor("anchor"), prevHead = cm.getCursor("head"); + cmds.selectNextOccurrence(cm); + if (CodeMirror.cmpPos(prevAnchor, prevHead) != 0) { + cm.doc.setSelections(cm.doc.listSelections() + .filter(function (sel) { + return sel.anchor != prevAnchor || sel.head != prevHead; + })); + } + }; + + function addCursorToSelection(cm, dir) { + var ranges = cm.listSelections(), newRanges = []; + for (var i = 0; i < ranges.length; i++) { + var range = ranges[i]; + var newAnchor = cm.findPosV( + range.anchor, dir, "line", range.anchor.goalColumn); + var newHead = cm.findPosV( + range.head, dir, "line", range.head.goalColumn); + newAnchor.goalColumn = range.anchor.goalColumn != null ? + range.anchor.goalColumn : cm.cursorCoords(range.anchor, "div").left; + newHead.goalColumn = range.head.goalColumn != null ? + range.head.goalColumn : cm.cursorCoords(range.head, "div").left; + var newRange = {anchor: newAnchor, head: newHead}; + newRanges.push(range); + newRanges.push(newRange); + } + cm.setSelections(newRanges); + } + cmds.addCursorToPrevLine = function(cm) { addCursorToSelection(cm, -1); }; + cmds.addCursorToNextLine = function(cm) { addCursorToSelection(cm, 1); }; + + function isSelectedRange(ranges, from, to) { + for (var i = 0; i < ranges.length; i++) + if (CodeMirror.cmpPos(ranges[i].from(), from) == 0 && + CodeMirror.cmpPos(ranges[i].to(), to) == 0) return true + return false + } + + var mirror = "(){}[]"; + function selectBetweenBrackets(cm) { + var ranges = cm.listSelections(), newRanges = []; + for (var i = 0; i < ranges.length; i++) { + var range = ranges[i], pos = range.head, opening = cm.scanForBracket(pos, -1); + if (!opening) return false; + for (;;) { + var closing = cm.scanForBracket(pos, 1); + if (!closing) return false; + if (closing.ch == mirror.charAt(mirror.indexOf(opening.ch) + 1)) { + var startPos = Pos(opening.pos.line, opening.pos.ch + 1); + if (CodeMirror.cmpPos(startPos, range.from()) == 0 && + CodeMirror.cmpPos(closing.pos, range.to()) == 0) { + opening = cm.scanForBracket(opening.pos, -1); + if (!opening) return false; + } else { + newRanges.push({anchor: startPos, head: closing.pos}); + break; + } + } + pos = Pos(closing.pos.line, closing.pos.ch + 1); + } + } + cm.setSelections(newRanges); + return true; + } + + cmds.selectScope = function(cm) { + selectBetweenBrackets(cm) || cm.execCommand("selectAll"); + }; + cmds.selectBetweenBrackets = function(cm) { + if (!selectBetweenBrackets(cm)) return CodeMirror.Pass; + }; + + function puncType(type) { + return !type ? null : /\bpunctuation\b/.test(type) ? type : undefined + } + + cmds.goToBracket = function(cm) { + cm.extendSelectionsBy(function(range) { + var next = cm.scanForBracket(range.head, 1, puncType(cm.getTokenTypeAt(range.head))); + if (next && CodeMirror.cmpPos(next.pos, range.head) != 0) return next.pos; + var prev = cm.scanForBracket(range.head, -1, puncType(cm.getTokenTypeAt(Pos(range.head.line, range.head.ch + 1)))); + return prev && Pos(prev.pos.line, prev.pos.ch + 1) || range.head; + }); + }; + + cmds.swapLineUp = function(cm) { + if (cm.isReadOnly()) return CodeMirror.Pass + var ranges = cm.listSelections(), linesToMove = [], at = cm.firstLine() - 1, newSels = []; + for (var i = 0; i < ranges.length; i++) { + var range = ranges[i], from = range.from().line - 1, to = range.to().line; + newSels.push({anchor: Pos(range.anchor.line - 1, range.anchor.ch), + head: Pos(range.head.line - 1, range.head.ch)}); + if (range.to().ch == 0 && !range.empty()) --to; + if (from > at) linesToMove.push(from, to); + else if (linesToMove.length) linesToMove[linesToMove.length - 1] = to; + at = to; + } + cm.operation(function() { + for (var i = 0; i < linesToMove.length; i += 2) { + var from = linesToMove[i], to = linesToMove[i + 1]; + var line = cm.getLine(from); + cm.replaceRange("", Pos(from, 0), Pos(from + 1, 0), "+swapLine"); + if (to > cm.lastLine()) + cm.replaceRange("\n" + line, Pos(cm.lastLine()), null, "+swapLine"); + else + cm.replaceRange(line + "\n", Pos(to, 0), null, "+swapLine"); + } + cm.setSelections(newSels); + cm.scrollIntoView(); + }); + }; + + cmds.swapLineDown = function(cm) { + if (cm.isReadOnly()) return CodeMirror.Pass + var ranges = cm.listSelections(), linesToMove = [], at = cm.lastLine() + 1; + for (var i = ranges.length - 1; i >= 0; i--) { + var range = ranges[i], from = range.to().line + 1, to = range.from().line; + if (range.to().ch == 0 && !range.empty()) from--; + if (from < at) linesToMove.push(from, to); + else if (linesToMove.length) linesToMove[linesToMove.length - 1] = to; + at = to; + } + cm.operation(function() { + for (var i = linesToMove.length - 2; i >= 0; i -= 2) { + var from = linesToMove[i], to = linesToMove[i + 1]; + var line = cm.getLine(from); + if (from == cm.lastLine()) + cm.replaceRange("", Pos(from - 1), Pos(from), "+swapLine"); + else + cm.replaceRange("", Pos(from, 0), Pos(from + 1, 0), "+swapLine"); + cm.replaceRange(line + "\n", Pos(to, 0), null, "+swapLine"); + } + cm.scrollIntoView(); + }); + }; + + cmds.toggleCommentIndented = function(cm) { + cm.toggleComment({ indent: true }); + }; + + cmds.joinLines = function(cm) { + var ranges = cm.listSelections(), joined = []; + for (var i = 0; i < ranges.length; i++) { + var range = ranges[i], from = range.from(); + var start = from.line, end = range.to().line; + while (i < ranges.length - 1 && ranges[i + 1].from().line == end) + end = ranges[++i].to().line; + joined.push({start: start, end: end, anchor: !range.empty() && from}); + } + cm.operation(function() { + var offset = 0, ranges = []; + for (var i = 0; i < joined.length; i++) { + var obj = joined[i]; + var anchor = obj.anchor && Pos(obj.anchor.line - offset, obj.anchor.ch), head; + for (var line = obj.start; line <= obj.end; line++) { + var actual = line - offset; + if (line == obj.end) head = Pos(actual, cm.getLine(actual).length + 1); + if (actual < cm.lastLine()) { + cm.replaceRange(" ", Pos(actual), Pos(actual + 1, /^\s*/.exec(cm.getLine(actual + 1))[0].length)); + ++offset; + } + } + ranges.push({anchor: anchor || head, head: head}); + } + cm.setSelections(ranges, 0); + }); + }; + + cmds.duplicateLine = function(cm) { + cm.operation(function() { + var rangeCount = cm.listSelections().length; + for (var i = 0; i < rangeCount; i++) { + var range = cm.listSelections()[i]; + if (range.empty()) + cm.replaceRange(cm.getLine(range.head.line) + "\n", Pos(range.head.line, 0)); + else + cm.replaceRange(cm.getRange(range.from(), range.to()), range.from()); + } + cm.scrollIntoView(); + }); + }; + + + function sortLines(cm, caseSensitive) { + if (cm.isReadOnly()) return CodeMirror.Pass + var ranges = cm.listSelections(), toSort = [], selected; + for (var i = 0; i < ranges.length; i++) { + var range = ranges[i]; + if (range.empty()) continue; + var from = range.from().line, to = range.to().line; + while (i < ranges.length - 1 && ranges[i + 1].from().line == to) + to = ranges[++i].to().line; + if (!ranges[i].to().ch) to--; + toSort.push(from, to); + } + if (toSort.length) selected = true; + else toSort.push(cm.firstLine(), cm.lastLine()); + + cm.operation(function() { + var ranges = []; + for (var i = 0; i < toSort.length; i += 2) { + var from = toSort[i], to = toSort[i + 1]; + var start = Pos(from, 0), end = Pos(to); + var lines = cm.getRange(start, end, false); + if (caseSensitive) + lines.sort(); + else + lines.sort(function(a, b) { + var au = a.toUpperCase(), bu = b.toUpperCase(); + if (au != bu) { a = au; b = bu; } + return a < b ? -1 : a == b ? 0 : 1; + }); + cm.replaceRange(lines, start, end); + if (selected) ranges.push({anchor: start, head: Pos(to + 1, 0)}); + } + if (selected) cm.setSelections(ranges, 0); + }); + } + + cmds.sortLines = function(cm) { sortLines(cm, true); }; + cmds.sortLinesInsensitive = function(cm) { sortLines(cm, false); }; + + cmds.nextBookmark = function(cm) { + var marks = cm.state.sublimeBookmarks; + if (marks) while (marks.length) { + var current = marks.shift(); + var found = current.find(); + if (found) { + marks.push(current); + return cm.setSelection(found.from, found.to); + } + } + }; + + cmds.prevBookmark = function(cm) { + var marks = cm.state.sublimeBookmarks; + if (marks) while (marks.length) { + marks.unshift(marks.pop()); + var found = marks[marks.length - 1].find(); + if (!found) + marks.pop(); + else + return cm.setSelection(found.from, found.to); + } + }; + + cmds.toggleBookmark = function(cm) { + var ranges = cm.listSelections(); + var marks = cm.state.sublimeBookmarks || (cm.state.sublimeBookmarks = []); + for (var i = 0; i < ranges.length; i++) { + var from = ranges[i].from(), to = ranges[i].to(); + var found = ranges[i].empty() ? cm.findMarksAt(from) : cm.findMarks(from, to); + for (var j = 0; j < found.length; j++) { + if (found[j].sublimeBookmark) { + found[j].clear(); + for (var k = 0; k < marks.length; k++) + if (marks[k] == found[j]) + marks.splice(k--, 1); + break; + } + } + if (j == found.length) + marks.push(cm.markText(from, to, {sublimeBookmark: true, clearWhenEmpty: false})); + } + }; + + cmds.clearBookmarks = function(cm) { + var marks = cm.state.sublimeBookmarks; + if (marks) for (var i = 0; i < marks.length; i++) marks[i].clear(); + marks.length = 0; + }; + + cmds.selectBookmarks = function(cm) { + var marks = cm.state.sublimeBookmarks, ranges = []; + if (marks) for (var i = 0; i < marks.length; i++) { + var found = marks[i].find(); + if (!found) + marks.splice(i--, 0); + else + ranges.push({anchor: found.from, head: found.to}); + } + if (ranges.length) + cm.setSelections(ranges, 0); + }; + + function modifyWordOrSelection(cm, mod) { + cm.operation(function() { + var ranges = cm.listSelections(), indices = [], replacements = []; + for (var i = 0; i < ranges.length; i++) { + var range = ranges[i]; + if (range.empty()) { indices.push(i); replacements.push(""); } + else replacements.push(mod(cm.getRange(range.from(), range.to()))); + } + cm.replaceSelections(replacements, "around", "case"); + for (var i = indices.length - 1, at; i >= 0; i--) { + var range = ranges[indices[i]]; + if (at && CodeMirror.cmpPos(range.head, at) > 0) continue; + var word = wordAt(cm, range.head); + at = word.from; + cm.replaceRange(mod(word.word), word.from, word.to); + } + }); + } + + cmds.smartBackspace = function(cm) { + if (cm.somethingSelected()) return CodeMirror.Pass; + + cm.operation(function() { + var cursors = cm.listSelections(); + var indentUnit = cm.getOption("indentUnit"); + + for (var i = cursors.length - 1; i >= 0; i--) { + var cursor = cursors[i].head; + var toStartOfLine = cm.getRange({line: cursor.line, ch: 0}, cursor); + var column = CodeMirror.countColumn(toStartOfLine, null, cm.getOption("tabSize")); + + // Delete by one character by default + var deletePos = cm.findPosH(cursor, -1, "char", false); + + if (toStartOfLine && !/\S/.test(toStartOfLine) && column % indentUnit == 0) { + var prevIndent = new Pos(cursor.line, + CodeMirror.findColumn(toStartOfLine, column - indentUnit, indentUnit)); + + // Smart delete only if we found a valid prevIndent location + if (prevIndent.ch != cursor.ch) deletePos = prevIndent; + } + + cm.replaceRange("", deletePos, cursor, "+delete"); + } + }); + }; + + cmds.delLineRight = function(cm) { + cm.operation(function() { + var ranges = cm.listSelections(); + for (var i = ranges.length - 1; i >= 0; i--) + cm.replaceRange("", ranges[i].anchor, Pos(ranges[i].to().line), "+delete"); + cm.scrollIntoView(); + }); + }; + + cmds.upcaseAtCursor = function(cm) { + modifyWordOrSelection(cm, function(str) { return str.toUpperCase(); }); + }; + cmds.downcaseAtCursor = function(cm) { + modifyWordOrSelection(cm, function(str) { return str.toLowerCase(); }); + }; + + cmds.setSublimeMark = function(cm) { + if (cm.state.sublimeMark) cm.state.sublimeMark.clear(); + cm.state.sublimeMark = cm.setBookmark(cm.getCursor()); + }; + cmds.selectToSublimeMark = function(cm) { + var found = cm.state.sublimeMark && cm.state.sublimeMark.find(); + if (found) cm.setSelection(cm.getCursor(), found); + }; + cmds.deleteToSublimeMark = function(cm) { + var found = cm.state.sublimeMark && cm.state.sublimeMark.find(); + if (found) { + var from = cm.getCursor(), to = found; + if (CodeMirror.cmpPos(from, to) > 0) { var tmp = to; to = from; from = tmp; } + cm.state.sublimeKilled = cm.getRange(from, to); + cm.replaceRange("", from, to); + } + }; + cmds.swapWithSublimeMark = function(cm) { + var found = cm.state.sublimeMark && cm.state.sublimeMark.find(); + if (found) { + cm.state.sublimeMark.clear(); + cm.state.sublimeMark = cm.setBookmark(cm.getCursor()); + cm.setCursor(found); + } + }; + cmds.sublimeYank = function(cm) { + if (cm.state.sublimeKilled != null) + cm.replaceSelection(cm.state.sublimeKilled, null, "paste"); + }; + + cmds.showInCenter = function(cm) { + var pos = cm.cursorCoords(null, "local"); + cm.scrollTo(null, (pos.top + pos.bottom) / 2 - cm.getScrollInfo().clientHeight / 2); + }; + + function getTarget(cm) { + var from = cm.getCursor("from"), to = cm.getCursor("to"); + if (CodeMirror.cmpPos(from, to) == 0) { + var word = wordAt(cm, from); + if (!word.word) return; + from = word.from; + to = word.to; + } + return {from: from, to: to, query: cm.getRange(from, to), word: word}; + } + + function findAndGoTo(cm, forward) { + var target = getTarget(cm); + if (!target) return; + var query = target.query; + var cur = cm.getSearchCursor(query, forward ? target.to : target.from); + + if (forward ? cur.findNext() : cur.findPrevious()) { + cm.setSelection(cur.from(), cur.to()); + } else { + cur = cm.getSearchCursor(query, forward ? Pos(cm.firstLine(), 0) + : cm.clipPos(Pos(cm.lastLine()))); + if (forward ? cur.findNext() : cur.findPrevious()) + cm.setSelection(cur.from(), cur.to()); + else if (target.word) + cm.setSelection(target.from, target.to); + } + } cmds.findUnder = function(cm) { findAndGoTo(cm, true); }; + cmds.findUnderPrevious = function(cm) { findAndGoTo(cm,false); }; + cmds.findAllUnder = function(cm) { + var target = getTarget(cm); + if (!target) return; + var cur = cm.getSearchCursor(target.query); + var matches = []; + var primaryIndex = -1; + while (cur.findNext()) { + matches.push({anchor: cur.from(), head: cur.to()}); + if (cur.from().line <= target.from.line && cur.from().ch <= target.from.ch) + primaryIndex++; + } + cm.setSelections(matches, primaryIndex); + }; + + + var keyMap = CodeMirror.keyMap; + keyMap.macSublime = { + "Cmd-Left": "goLineStartSmart", + "Shift-Tab": "indentLess", + "Shift-Ctrl-K": "deleteLine", + "Alt-Q": "wrapLines", + "Ctrl-Left": "goSubwordLeft", + "Ctrl-Right": "goSubwordRight", + "Ctrl-Alt-Up": "scrollLineUp", + "Ctrl-Alt-Down": "scrollLineDown", + "Cmd-L": "selectLine", + "Shift-Cmd-L": "splitSelectionByLine", + "Esc": "singleSelectionTop", + "Cmd-Enter": "insertLineAfter", + "Shift-Cmd-Enter": "insertLineBefore", + "Cmd-D": "selectNextOccurrence", + "Shift-Cmd-Space": "selectScope", + "Shift-Cmd-M": "selectBetweenBrackets", + "Cmd-M": "goToBracket", + "Cmd-Ctrl-Up": "swapLineUp", + "Cmd-Ctrl-Down": "swapLineDown", + "Cmd-/": "toggleCommentIndented", + "Cmd-J": "joinLines", + "Shift-Cmd-D": "duplicateLine", + "F5": "sortLines", + "Cmd-F5": "sortLinesInsensitive", + "F2": "nextBookmark", + "Shift-F2": "prevBookmark", + "Cmd-F2": "toggleBookmark", + "Shift-Cmd-F2": "clearBookmarks", + "Alt-F2": "selectBookmarks", + "Backspace": "smartBackspace", + "Cmd-K Cmd-D": "skipAndSelectNextOccurrence", + "Cmd-K Cmd-K": "delLineRight", + "Cmd-K Cmd-U": "upcaseAtCursor", + "Cmd-K Cmd-L": "downcaseAtCursor", + "Cmd-K Cmd-Space": "setSublimeMark", + "Cmd-K Cmd-A": "selectToSublimeMark", + "Cmd-K Cmd-W": "deleteToSublimeMark", + "Cmd-K Cmd-X": "swapWithSublimeMark", + "Cmd-K Cmd-Y": "sublimeYank", + "Cmd-K Cmd-C": "showInCenter", + "Cmd-K Cmd-G": "clearBookmarks", + "Cmd-K Cmd-Backspace": "delLineLeft", + "Cmd-K Cmd-1": "foldAll", + "Cmd-K Cmd-0": "unfoldAll", + "Cmd-K Cmd-J": "unfoldAll", + "Ctrl-Shift-Up": "addCursorToPrevLine", + "Ctrl-Shift-Down": "addCursorToNextLine", + "Cmd-F3": "findUnder", + "Shift-Cmd-F3": "findUnderPrevious", + "Alt-F3": "findAllUnder", + "Shift-Cmd-[": "fold", + "Shift-Cmd-]": "unfold", + "Cmd-I": "findIncremental", + "Shift-Cmd-I": "findIncrementalReverse", + "Cmd-H": "replace", + "F3": "findNext", + "Shift-F3": "findPrev", + "fallthrough": "macDefault" + }; + CodeMirror.normalizeKeyMap(keyMap.macSublime); + + keyMap.pcSublime = { + "Shift-Tab": "indentLess", + "Shift-Ctrl-K": "deleteLine", + "Alt-Q": "wrapLines", + "Ctrl-T": "transposeChars", + "Alt-Left": "goSubwordLeft", + "Alt-Right": "goSubwordRight", + "Ctrl-Up": "scrollLineUp", + "Ctrl-Down": "scrollLineDown", + "Ctrl-L": "selectLine", + "Shift-Ctrl-L": "splitSelectionByLine", + "Esc": "singleSelectionTop", + "Ctrl-Enter": "insertLineAfter", + "Shift-Ctrl-Enter": "insertLineBefore", + "Ctrl-D": "selectNextOccurrence", + "Shift-Ctrl-Space": "selectScope", + "Shift-Ctrl-M": "selectBetweenBrackets", + "Ctrl-M": "goToBracket", + "Shift-Ctrl-Up": "swapLineUp", + "Shift-Ctrl-Down": "swapLineDown", + "Ctrl-/": "toggleCommentIndented", + "Ctrl-J": "joinLines", + "Shift-Ctrl-D": "duplicateLine", + "F9": "sortLines", + "Ctrl-F9": "sortLinesInsensitive", + "F2": "nextBookmark", + "Shift-F2": "prevBookmark", + "Ctrl-F2": "toggleBookmark", + "Shift-Ctrl-F2": "clearBookmarks", + "Alt-F2": "selectBookmarks", + "Backspace": "smartBackspace", + "Ctrl-K Ctrl-D": "skipAndSelectNextOccurrence", + "Ctrl-K Ctrl-K": "delLineRight", + "Ctrl-K Ctrl-U": "upcaseAtCursor", + "Ctrl-K Ctrl-L": "downcaseAtCursor", + "Ctrl-K Ctrl-Space": "setSublimeMark", + "Ctrl-K Ctrl-A": "selectToSublimeMark", + "Ctrl-K Ctrl-W": "deleteToSublimeMark", + "Ctrl-K Ctrl-X": "swapWithSublimeMark", + "Ctrl-K Ctrl-Y": "sublimeYank", + "Ctrl-K Ctrl-C": "showInCenter", + "Ctrl-K Ctrl-G": "clearBookmarks", + "Ctrl-K Ctrl-Backspace": "delLineLeft", + "Ctrl-K Ctrl-1": "foldAll", + "Ctrl-K Ctrl-0": "unfoldAll", + "Ctrl-K Ctrl-J": "unfoldAll", + "Ctrl-Alt-Up": "addCursorToPrevLine", + "Ctrl-Alt-Down": "addCursorToNextLine", + "Ctrl-F3": "findUnder", + "Shift-Ctrl-F3": "findUnderPrevious", + "Alt-F3": "findAllUnder", + "Shift-Ctrl-[": "fold", + "Shift-Ctrl-]": "unfold", + "Ctrl-I": "findIncremental", + "Shift-Ctrl-I": "findIncrementalReverse", + "Ctrl-H": "replace", + "F3": "findNext", + "Shift-F3": "findPrev", + "fallthrough": "pcDefault" + }; + CodeMirror.normalizeKeyMap(keyMap.pcSublime); + + var mac = keyMap.default == keyMap.macDefault; + keyMap.sublime = mac ? keyMap.macSublime : keyMap.pcSublime; + }); + }); - // Given a mode and a state (for that mode), find the inner mode and - // state at the position that the state refers to. - function innerMode(mode, state) { - var info; - while (mode.innerMode) { - info = mode.innerMode(state); - if (!info || info.mode == mode) { break } - state = info.state; - mode = info.mode; - } - return info || { mode: mode, state: state } - } + var search = createCommonjsModule(function (module, exports) { + (function (mod) { + + mod(codemirror); + })(function (CodeMirror) { + + var Search; + + CodeMirror.defineOption("searchbox", false, function (cm) { + cm.addKeyMap({ + "Ctrl-F": function () { + var cmEle = cm.display.wrapper; + if (!Search || !cmEle.parentElement.contains(Search.searchBox)) { + Search = new SearchBox(cm); + } + var isReplace = false; + if (cmEle.parentElement.querySelector("[action=toggleReplace]")) { + isReplace = + cmEle.parentElement.querySelector("[action=toggleReplace]") + .innerText === "-"; + } + Search.show(cm.getSelection(), isReplace); + }, + + Esc: function () { + if (!Search || !Search.isVisible()) return CodeMirror.Pass; + + Search.hide(); + + if (typeof event !== "undefined") event.stopPropagation(); + }, + + "Cmd-F": function () { + if (!Search) Search = new SearchBox(cm); + Search.show(); + }, + }); + }); + + function SearchBox(cm) { + var self = this; + + init(); + + function initElements(el) { + self.searchBox = el.querySelector(".ace_search_form"); + self.replaceBox = el.querySelector(".ace_replace_form"); + self.searchOptions = el.querySelector(".ace_search_options"); + + self.regExpOption = el.querySelector("[action=toggleRegexpMode]"); + self.caseSensitiveOption = el.querySelector( + "[action=toggleCaseSensitive]" + ); + self.wholeWordOption = el.querySelector("[action=toggleWholeWords]"); + + self.searchInput = self.searchBox.querySelector(".ace_search_field"); + self.replaceInput = self.replaceBox.querySelector(".ace_search_field"); + } + + function init() { + var el = (self.element = addHtml()); + + addStyle(); + + initElements(el); + bindKeys(); + + el.addEventListener("mousedown", function (e) { + setTimeout(function () { + self.activeInput.focus(); + }, 0); + + e.stopPropagation(); + }); + + el.addEventListener("click", function (e) { + var t = e.target || e.srcElement; + var action = t.getAttribute("action"); + if (action && self[action]) self[action](); + else if (self.commands[action]) self.commands[action](); + e.stopPropagation(); + }); + + self.searchInput.addEventListener("input", function () { + self.$onChange.schedule(20); + }); + + self.searchInput.addEventListener("focus", function () { + self.activeInput = self.searchInput; + }); + + self.replaceInput.addEventListener("focus", function () { + self.activeInput = self.replaceInput; + }); + + self.$onChange = delayedCall(function () { + self.find(false, false); + }); + } + + function bindKeys() { + var sb = self, + obj = { + "Ctrl-F|Cmd-F|Ctrl-H|Command-Alt-F": function () { + var isReplace = (sb.isReplace = !sb.isReplace); + sb.replaceBox.style.display = isReplace ? "" : "none"; + sb[isReplace ? "replaceInput" : "searchInput"].focus(); + }, + "Ctrl-G|Cmd-G": function () { + sb.findNext(); + }, + "Ctrl-Shift-G|Cmd-Shift-G": function () { + sb.findPrev(); + }, + Esc: function () { + setTimeout(function () { + sb.hide(); + }); + }, + Enter: function () { + if (sb.activeInput === sb.replaceInput) sb.replace(); + sb.findNext(); + }, + "Shift-Enter": function () { + if (sb.activeInput === sb.replaceInput) sb.replace(); + sb.findPrev(); + }, + "Alt-Enter": function () { + if (sb.activeInput === sb.replaceInput) sb.replaceAll(); + sb.findAll(); + }, + Tab: function () { + if (self.activeInput === self.replaceInput) + self.searchInput.focus(); + else self.replaceInput.focus(); + }, + }; + + self.element.addEventListener("keydown", function (event) { + Object.keys(obj).some(function (name) { + var is = key(name, event); + + if (is) { + event.stopPropagation(); + event.preventDefault(); + obj[name](event); + } + + return is; + }); + }); + } + + this.commands = { + toggleRegexpMode: function () { + self.regExpOption.checked = !self.regExpOption.checked; + self.$syncOptions(); + }, + + toggleCaseSensitive: function () { + self.caseSensitiveOption.checked = !self.caseSensitiveOption.checked; + self.$syncOptions(); + }, + + toggleWholeWords: function () { + self.wholeWordOption.checked = !self.wholeWordOption.checked; + self.$syncOptions(); + }, + }; + + this.$syncOptions = function () { + setCssClass(this.regExpOption, "checked", this.regExpOption.checked); + setCssClass( + this.wholeWordOption, + "checked", + this.wholeWordOption.checked + ); + setCssClass( + this.caseSensitiveOption, + "checked", + this.caseSensitiveOption.checked + ); + + this.find(false, false); + }; + + this.find = function (skipCurrent, backwards) { + var value = this.searchInput.value, + options = { + skipCurrent: skipCurrent, + backwards: backwards, + regExp: this.regExpOption.checked, + caseSensitive: this.caseSensitiveOption.checked, + wholeWord: this.wholeWordOption.checked, + }; + + find(value, options, function (searchCursor) { + var current = searchCursor.matches(false, searchCursor.from()); + cm.setSelection(current.from, current.to); + }); + }; + + function find(value, options, callback) { + if (!value) { + clearSearch(cm); + updateCount(); + return; + } + var done, + noMatch, + searchCursor, + next, + prev, + matches, + cursor, + position, + val = value, + o = options, + is = true, + caseSensitive = o.caseSensitive, + regExp = o.regExp, + wholeWord = o.wholeWord; + + if (regExp) { + val = val.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); + } + if (wholeWord) { + if (caseSensitive) { + val = val = RegExp("\\b" + val + "\\b"); + } else { + val = RegExp("\\b" + val + "\\b", "i"); + } + } + if (regExp) { + val = RegExp(val); + } + clearSearch(cm); + doSearch(cm, val, caseSensitive); + updateCount(); + if (o.backwards) position = o.skipCurrent ? "from" : "to"; + else position = o.skipCurrent ? "to" : "from"; + + cursor = cm.getCursor(position); + searchCursor = cm.getSearchCursor(val, cursor, !caseSensitive); + + (next = searchCursor.findNext.bind(searchCursor)), + (prev = searchCursor.findPrevious.bind(searchCursor)), + (matches = searchCursor.matches.bind(searchCursor)); + + if (o.backwards && !prev()) { + is = next(); + + if (is) { + cm.setCursor(cm.doc.size - 1, 0); + find(value, options, callback); + done = true; + } + } else if (!o.backwards && !next()) { + is = prev(); + + if (is) { + cm.setCursor(0, 0); + find(value, options, callback); + done = true; + } + } + + noMatch = !is && self.searchInput.value; + setCssClass(self.searchBox, "ace_nomatch", noMatch); + + if (!done && is) callback(searchCursor); + } + + this.findNext = function () { + this.find(true, false); + }; + + this.findPrev = function () { + this.find(true, true); + }; + + this.findAll = function () { + var value = this.searchInput.value, + noMatch = this.searchInput.value; + + setCssClass(this.searchBox, "ace_nomatch", noMatch); + + if (cm.showMatchesOnScrollbar) cm.showMatchesOnScrollbar(value); + + this.hide(); + }; + + this.replace = function () { + var readOnly = cm.getOption("readOnly"), + isSelection = !!cm.getSelection(); + if (!readOnly && isSelection) + cm.replaceSelection(this.replaceInput.value, "start"); + updateCount(); + }; + + this.replaceAndFindNext = function () { + var readOnly = cm.getOption("readOnly"); + + if (!readOnly) { + this.replace(); + this.findNext(); + } + }; + + this.replaceAll = function () { + var value, + cursor, + from = this.searchInput.value, + to = this.replaceInput.value, + reg = RegExp(from, this.caseSensitiveOption.checked ? "g" : "gi"); + + if (this.wholeWordOption.checked && !this.regExpOption.checked) { + if (this.caseSensitiveOption.checked) { + reg = RegExp("\\b" + from + "\\b", 'g'); + } else { + reg = RegExp("\\b" + from + "\\b", "gi"); + } + } + + if (!cm.getOption("readOnly") && cm.getSelection()) { + cursor = cm.getCursor(); + value = cm.getValue(); + value = value.replace(reg, to); + + cm.setValue(value); + cm.setCursor(cursor); + } + updateCount(); + }; + + this.toggleReplace = function () { + var cmEle = cm.display.wrapper; + if ( + cmEle.parentElement.querySelector("[action=toggleReplace]") + .innerText === "+" + ) { + cmEle.parentElement.querySelector("[action=toggleReplace]").innerText = + "-"; + this.replaceBox.style.display = ""; + this.isReplace = true; + } else { + cmEle.parentElement.querySelector("[action=toggleReplace]").innerText = + "+"; + this.replaceBox.style.display = "none"; + this.isReplace = false; + } + }; + + this.hide = function () { + clearSearch(cm); + var cmEle = cm.getWrapperElement(); + Search = null; + cmEle.removeChild(this.element); + cm.focus(); + }; + + this.isVisible = function () { + var is = this.element.style.display === ""; + return is; + }; + + this.show = function (value, isReplace) { + this.element.style.display = ""; + if (!isReplace) { + this.replaceBox.style.display = isReplace ? "" : "none"; + } + this.isReplace = isReplace; + if (value) { + this.searchInput.value = value; + this.find(false, false); + } + this.searchInput.focus(); + this.searchInput.select(); + }; + + this.isFocused = function () { + var el = document.activeElement; + return el === this.searchInput || el === this.replaceInput; + }; + + function doSearch(cm, value, caseSensitive) { + var state = getSearchState(cm); + var query = value; + if (query && query !== state.queryText) { + startSearch(cm, state, query, caseSensitive); + state.posFrom = state.posTo = cm.getCursor(); + } + } + + function parseString(string) { + return string.replace(/\\([nrt\\])/g, function (match, ch) { + if (ch == "n") return "\n"; + if (ch == "r") return "\r"; + if (ch == "t") return "\t"; + if (ch == "\\") return "\\"; + return match; + }); + } + + function parseQuery(query) { + var reStr = typeof query === "object" ? query.toString() : query; + var isRE = reStr.match(/^\/(.*)\/([a-z]*)$/); + if (isRE) { + try { + query = new RegExp(isRE[1], isRE[2].indexOf("i") == -1 ? "" : "i"); + } catch (e) {} // Not a regular expression after all, do a string search + } else { + query = parseString(query); + } + if (typeof query == "string" ? query == "" : query.test("")) query = /x^/; + return query; + } + + function startSearch(cm, state, query, caseSensitive) { + state.queryText = query; + state.query = parseQuery(query); + cm.removeOverlay( + state.overlay, + queryCaseInsensitive(state.query, caseSensitive) + ); + state.overlay = searchOverlay( + state.query, + queryCaseInsensitive(state.query, caseSensitive) + ); + cm.addOverlay(state.overlay); + if (cm.showMatchesOnScrollbar) { + if (state.annotate) { + state.annotate.clear(); + state.annotate = null; + } + state.annotate = cm.showMatchesOnScrollbar( + state.query, + queryCaseInsensitive(state.query, caseSensitive) + ); + } + } + + function queryCaseInsensitive(query, caseSensitive) { + return typeof query == "string" && !caseSensitive; + } + + function searchOverlay(query, caseInsensitive) { + if (typeof query == "string") + query = new RegExp( + query.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"), + caseInsensitive ? "gi" : "g" + ); + else if (!query.global) + query = new RegExp(query.source, query.ignoreCase ? "gi" : "g"); + + return { + token: function (stream) { + query.lastIndex = stream.pos; + var match = query.exec(stream.string); + if (match && match.index == stream.pos) { + stream.pos += match[0].length || 1; + return "searching"; + } else if (match) { + stream.pos = match.index; + } else { + stream.skipToEnd(); + } + }, + }; + } + + function SearchState() { + this.posFrom = this.posTo = this.lastQuery = this.query = null; + this.overlay = null; + } + + function getSearchState(cm) { + return cm.state.search || (cm.state.search = new SearchState()); + } + + function clearSearch(cm) { + cm.operation(function () { + var state = getSearchState(cm); + state.lastQuery = state.query; + if (!state.query) return; + state.query = state.queryText = null; + cm.removeOverlay(state.overlay); + if (state.annotate) { + state.annotate.clear(); + state.annotate = null; + } + }); + } + + function updateCount() { + var val = self.searchInput.value; + var matches = []; + if (val) { + val = val.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); + var reg; + if (self.caseSensitiveOption.checked) { + reg = RegExp(val, "g"); + } else { + reg = RegExp(val, "gi"); + } + if (self.wholeWordOption.checked) { + if (self.caseSensitiveOption.checked) { + reg = RegExp("\\b" + val + "\\b", "g"); + } else { + reg = RegExp("\\b" + val + "\\b", "gi"); + } + } + if (self.regExpOption.checked) { + reg = RegExp(val, "gi"); + } + matches = cm.getValue().match(reg); + } + var count = matches ? matches.length : 0; + var cmEle = cm.display.wrapper; + var countEle = cmEle.parentElement.querySelector(".ace_search_counter"); + if (countEle) { + countEle.innerText = count + " matches found."; + } + if (count === 0){ + cm.setSelection({ch: 0, line: 0},{ch: 0, line: 0}); + } + } + + function addStyle() { + var style = document.createElement("style"), + css = [ + ".ace_search {", + "color: black;", + "background-color: #ddd;", + "border: 1px solid #cbcbcb;", + "border-top: 0 none;", + "max-width: 325px;", + "overflow: hidden;", + "margin: 0;", + "padding: 4px;", + "padding-right: 6px;", + "padding-bottom: 0;", + "position: absolute;", + "top: 0px;", + "z-index: 99;", + "white-space: normal;", + "font-size: 12px;", + "}", + ".ace_search.left {", + "border-left: 0 none;", + "border-radius: 0px 0px 5px 0px;", + "left: 0;", + "}", + ".ace_search.right {", + "border-radius: 0px 0px 0px 5px;", + "border-right: 0 none;", + "right: 0;", + "}", + ".ace_search_form, .ace_replace_form {", + "border-radius: 3px;", + "border: 1px solid #cbcbcb;", + "float: left;", + "margin-bottom: 4px;", + "overflow: hidden;", + "}", + ".ace_search_form.ace_nomatch {", + "outline: 1px solid red;", + "}", + ".ace_search_field {", + "background-color: white;", + "border-right: 1px solid #cbcbcb;", + "border: 0 none;", + "-webkit-box-sizing: border-box;", + "-moz-box-sizing: border-box;", + "box-sizing: border-box;", + "float: left;", + "height: 22px;", + "outline: 0;", + "padding: 0 7px;", + "width: 238px;", + "margin: 0;", + "}", + ".ace_searchbtn,", + ".ace_replacebtn {", + "background: #fff;", + "border: 0 none;", + "border-left: 1px solid #dcdcdc;", + "cursor: pointer;", + "float: left;", + "height: 22px;", + "padding: 0 5px;", + "margin: 0;", + "position: relative;", + "}", + ".ace_searchbtn:last-child,", + ".ace_replacebtn:last-child {", + "border-top-right-radius: 3px;", + "border-bottom-right-radius: 3px;", + "}", + ".ace_searchbtn:disabled {", + "background: none;", + "cursor: default;", + "}", + ".ace_searchbtn {", + "background-position: 50% 50%;", + "background-repeat: no-repeat;", + "width: 27px;", + "}", + ".ace_searchbtn.prev {", + "background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAFCAYAAAB4ka1VAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADFJREFUeNpiSU1NZUAC/6E0I0yACYskCpsJiySKIiY0SUZk40FyTEgCjGgKwTRAgAEAQJUIPCE+qfkAAAAASUVORK5CYII=); ", + "}", + ".ace_searchbtn.next {", + "background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAFCAYAAAB4ka1VAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADRJREFUeNpiTE1NZQCC/0DMyIAKwGJMUAYDEo3M/s+EpvM/mkKwCQxYjIeLMaELoLMBAgwAU7UJObTKsvAAAAAASUVORK5CYII=); ", + "}", + ".ace_searchbtn_close {", + "background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAcCAYAAABRVo5BAAAAZ0lEQVR42u2SUQrAMAhDvazn8OjZBilCkYVVxiis8H4CT0VrAJb4WHT3C5xU2a2IQZXJjiQIRMdkEoJ5Q2yMqpfDIo+XY4k6h+YXOyKqTIj5REaxloNAd0xiKmAtsTHqW8sR2W5f7gCu5nWFUpVjZwAAAABJRU5ErkJggg==) no-repeat 50% 0;", + "border-radius: 50%;", + "border: 0 none;", + "color: #656565;", + "cursor: pointer;", + "float: right;", + "font: 16px/16px Arial;", + "height: 14px;", + "margin: 5px 1px 9px 5px;", + "padding: 0;", + "text-align: center;", + "width: 14px;", + "}", + ".ace_searchbtn_close:hover {", + "background-color: #656565;", + "background-position: 50% 100%;", + "color: white;", + "}", + ".ace_replacebtn.prev {", + "width: 54px", + "}", + ".ace_replacebtn.next {", + "width: 27px", + "}", + ".ace_button {", + "margin-left: 2px;", + "cursor: pointer;", + "-webkit-user-select: none;", + "-moz-user-select: none;", + "-o-user-select: none;", + "-ms-user-select: none;", + "user-select: none;", + "overflow: hidden;", + "opacity: 0.7;", + "border: 1px solid rgba(100,100,100,0.23);", + "padding: 1px;", + "-moz-box-sizing: border-box;", + "box-sizing: border-box;", + "color: black;", + "}", + ".ace_button:hover {", + "background-color: #eee;", + "opacity:1;", + "}", + ".ace_button:active {", + "background-color: #ddd;", + "}", + ".ace_button.checked {", + "border-color: #3399ff;", + "opacity:1;", + "}", + ".ace_search_options{", + "clear: both;", + "margin: 4px 0;", + "text-align: right;", + "-webkit-user-select: none;", + "-moz-user-select: none;", + "-o-user-select: none;", + "-ms-user-select: none;", + "user-select: none;", + "}", + ".replace_toggle{", + "float: left;", + "margin-top: -2px;", + "padding: 0 5px;", + " }", + ".ace_search_counter{", + "float: left;", + "font-family: arial;", + "padding: 0 8px;", + "}", + "button svg,path {", + "pointer-events: none;", + "}", + ].join(""); + + style.setAttribute("data-name", "js-searchbox"); + + style.textContent = css; + + document.head.appendChild(style); + } + + function addHtml() { + var elSearch, + el = cm.getWrapperElement(), + div = document.createElement("div"), + html = [ + '", + ].join(""); + + div.innerHTML = html; + + elSearch = div.firstChild; + + el.appendChild(elSearch); + + return elSearch; + } + } + + function setCssClass(el, className, condition) { + var list = el.classList; + + list[condition ? "add" : "remove"](className); + } + + function delayedCall(fcn, defaultTimeout) { + var timer, + callback = function () { + timer = null; + fcn(); + }, + _self = function (timeout) { + if (!timer) timer = setTimeout(callback, timeout || defaultTimeout); + }; + + _self.delay = function (timeout) { + timer && clearTimeout(timer); + timer = setTimeout(callback, timeout || defaultTimeout); + }; + _self.schedule = _self; + + _self.call = function () { + this.cancel(); + fcn(); + }; + + _self.cancel = function () { + timer && clearTimeout(timer); + timer = null; + }; + + _self.isPending = function () { + return timer; + }; + + return _self; + } + + /* https://github.com/coderaiser/key */ + function key(str, event) { + var right, + KEY = { + BACKSPACE: 8, + TAB: 9, + ENTER: 13, + ESC: 27, + + SPACE: 32, + PAGE_UP: 33, + PAGE_DOWN: 34, + END: 35, + HOME: 36, + UP: 38, + DOWN: 40, + + INSERT: 45, + DELETE: 46, + + INSERT_MAC: 96, + + ASTERISK: 106, + PLUS: 107, + MINUS: 109, + + F1: 112, + F2: 113, + F3: 114, + F4: 115, + F5: 116, + F6: 117, + F7: 118, + F8: 119, + F9: 120, + F10: 121, + + SLASH: 191, + TRA: 192 /* Typewritten Reverse Apostrophe (`) */, + BACKSLASH: 220, + }; + + keyCheck(str, event); + + right = str.split("|").some(function (combination) { + var wrong; + + wrong = combination.split("-").some(function (key) { + var right; + + switch (key) { + case "Ctrl": + right = event.ctrlKey; + break; + + case "Shift": + right = event.shiftKey; + break; + + case "Alt": + right = event.altKey; + break; + + case "Cmd": + right = event.metaKey; + break; + + default: + if (key.length === 1) right = event.keyCode === key.charCodeAt(0); + else + Object.keys(KEY).some(function (name) { + var up = key.toUpperCase(); + + if (up === name) right = event.keyCode === KEY[name]; + }); + break; + } + + return !right; + }); + + return !wrong; + }); + + return right; + } + + function keyCheck(str, event) { + if (typeof str !== "string") throw Error("str should be string!"); + + if (typeof event !== "object") throw Error("event should be object!"); + } + }); + }); - function startState(mode, a1, a2) { - return mode.startState ? mode.startState(a1, a2) : true - } + var annotatescrollbar = createCommonjsModule(function (module, exports) { + // CodeMirror, copyright (c) by Marijn Haverbeke and others + // Distributed under an MIT license: https://codemirror.net/LICENSE + + (function(mod) { + mod(codemirror); + })(function(CodeMirror) { + + CodeMirror.defineExtension("annotateScrollbar", function(options) { + if (typeof options == "string") options = {className: options}; + return new Annotation(this, options); + }); + + CodeMirror.defineOption("scrollButtonHeight", 0); + + function Annotation(cm, options) { + this.cm = cm; + this.options = options; + this.buttonHeight = options.scrollButtonHeight || cm.getOption("scrollButtonHeight"); + this.annotations = []; + this.doRedraw = this.doUpdate = null; + this.div = cm.getWrapperElement().appendChild(document.createElement("div")); + this.div.style.cssText = "position: absolute; right: 0; top: 0; z-index: 7; pointer-events: none"; + this.computeScale(); + + function scheduleRedraw(delay) { + clearTimeout(self.doRedraw); + self.doRedraw = setTimeout(function() { self.redraw(); }, delay); + } + + var self = this; + cm.on("refresh", this.resizeHandler = function() { + clearTimeout(self.doUpdate); + self.doUpdate = setTimeout(function() { + if (self.computeScale()) scheduleRedraw(20); + }, 100); + }); + cm.on("markerAdded", this.resizeHandler); + cm.on("markerCleared", this.resizeHandler); + if (options.listenForChanges !== false) + cm.on("changes", this.changeHandler = function() { + scheduleRedraw(250); + }); + } + + Annotation.prototype.computeScale = function() { + var cm = this.cm; + var hScale = (cm.getWrapperElement().clientHeight - cm.display.barHeight - this.buttonHeight * 2) / + cm.getScrollerElement().scrollHeight; + if (hScale != this.hScale) { + this.hScale = hScale; + return true; + } + }; + + Annotation.prototype.update = function(annotations) { + this.annotations = annotations; + this.redraw(); + }; + + Annotation.prototype.redraw = function(compute) { + if (compute !== false) this.computeScale(); + var cm = this.cm, hScale = this.hScale; + + var frag = document.createDocumentFragment(), anns = this.annotations; + + var wrapping = cm.getOption("lineWrapping"); + var singleLineH = wrapping && cm.defaultTextHeight() * 1.5; + var curLine = null, curLineObj = null; + + function getY(pos, top) { + if (curLine != pos.line) { + curLine = pos.line; + curLineObj = cm.getLineHandle(pos.line); + var visual = cm.getLineHandleVisualStart(curLineObj); + if (visual != curLineObj) { + curLine = cm.getLineNumber(visual); + curLineObj = visual; + } + } + if ((curLineObj.widgets && curLineObj.widgets.length) || + (wrapping && curLineObj.height > singleLineH)) + return cm.charCoords(pos, "local")[top ? "top" : "bottom"]; + var topY = cm.heightAtLine(curLineObj, "local"); + return topY + (top ? 0 : curLineObj.height); + } + + var lastLine = cm.lastLine(); + if (cm.display.barWidth) for (var i = 0, nextTop; i < anns.length; i++) { + var ann = anns[i]; + if (ann.to.line > lastLine) continue; + var top = nextTop || getY(ann.from, true) * hScale; + var bottom = getY(ann.to, false) * hScale; + while (i < anns.length - 1) { + if (anns[i + 1].to.line > lastLine) break; + nextTop = getY(anns[i + 1].from, true) * hScale; + if (nextTop > bottom + .9) break; + ann = anns[++i]; + bottom = getY(ann.to, false) * hScale; + } + if (bottom == top) continue; + var height = Math.max(bottom - top, 3); + + var elt = frag.appendChild(document.createElement("div")); + elt.style.cssText = "position: absolute; right: 0px; width: " + Math.max(cm.display.barWidth - 1, 2) + "px; top: " + + (top + this.buttonHeight) + "px; height: " + height + "px"; + elt.className = this.options.className; + if (ann.id) { + elt.setAttribute("annotation-id", ann.id); + } + } + this.div.textContent = ""; + this.div.appendChild(frag); + }; + + Annotation.prototype.clear = function() { + this.cm.off("refresh", this.resizeHandler); + this.cm.off("markerAdded", this.resizeHandler); + this.cm.off("markerCleared", this.resizeHandler); + if (this.changeHandler) this.cm.off("changes", this.changeHandler); + this.div.parentNode.removeChild(this.div); + }; + }); + }); - // STRING STREAM + var matchesonscrollbar = createCommonjsModule(function (module, exports) { + // CodeMirror, copyright (c) by Marijn Haverbeke and others + // Distributed under an MIT license: https://codemirror.net/LICENSE + + (function(mod) { + mod(codemirror, searchcursor, annotatescrollbar); + })(function(CodeMirror) { + + CodeMirror.defineExtension("showMatchesOnScrollbar", function(query, caseFold, options) { + if (typeof options == "string") options = {className: options}; + if (!options) options = {}; + return new SearchAnnotation(this, query, caseFold, options); + }); + + function SearchAnnotation(cm, query, caseFold, options) { + this.cm = cm; + this.options = options; + var annotateOptions = {listenForChanges: false}; + for (var prop in options) annotateOptions[prop] = options[prop]; + if (!annotateOptions.className) annotateOptions.className = "CodeMirror-search-match"; + this.annotation = cm.annotateScrollbar(annotateOptions); + this.query = query; + this.caseFold = caseFold; + this.gap = {from: cm.firstLine(), to: cm.lastLine() + 1}; + this.matches = []; + this.update = null; + + this.findMatches(); + this.annotation.update(this.matches); + + var self = this; + cm.on("change", this.changeHandler = function(_cm, change) { self.onChange(change); }); + } + + var MAX_MATCHES = 1000; + + SearchAnnotation.prototype.findMatches = function() { + if (!this.gap) return; + for (var i = 0; i < this.matches.length; i++) { + var match = this.matches[i]; + if (match.from.line >= this.gap.to) break; + if (match.to.line >= this.gap.from) this.matches.splice(i--, 1); + } + var cursor = this.cm.getSearchCursor(this.query, CodeMirror.Pos(this.gap.from, 0), {caseFold: this.caseFold, multiline: this.options.multiline}); + var maxMatches = this.options && this.options.maxMatches || MAX_MATCHES; + while (cursor.findNext()) { + var match = {from: cursor.from(), to: cursor.to()}; + if (match.from.line >= this.gap.to) break; + this.matches.splice(i++, 0, match); + if (this.matches.length > maxMatches) break; + } + this.gap = null; + }; + + function offsetLine(line, changeStart, sizeChange) { + if (line <= changeStart) return line; + return Math.max(changeStart, line + sizeChange); + } + + SearchAnnotation.prototype.onChange = function(change) { + var startLine = change.from.line; + var endLine = CodeMirror.changeEnd(change).line; + var sizeChange = endLine - change.to.line; + if (this.gap) { + this.gap.from = Math.min(offsetLine(this.gap.from, startLine, sizeChange), change.from.line); + this.gap.to = Math.max(offsetLine(this.gap.to, startLine, sizeChange), change.from.line); + } else { + this.gap = {from: change.from.line, to: endLine + 1}; + } + + if (sizeChange) for (var i = 0; i < this.matches.length; i++) { + var match = this.matches[i]; + var newFrom = offsetLine(match.from.line, startLine, sizeChange); + if (newFrom != match.from.line) match.from = CodeMirror.Pos(newFrom, match.from.ch); + var newTo = offsetLine(match.to.line, startLine, sizeChange); + if (newTo != match.to.line) match.to = CodeMirror.Pos(newTo, match.to.ch); + } + clearTimeout(this.update); + var self = this; + this.update = setTimeout(function() { self.updateAfterChange(); }, 250); + }; + + SearchAnnotation.prototype.updateAfterChange = function() { + this.findMatches(); + this.annotation.update(this.matches); + }; + + SearchAnnotation.prototype.clear = function() { + this.cm.off("change", this.changeHandler); + this.annotation.clear(); + }; + }); + }); - // Fed to the mode parsers, provides helper functions to make - // parsers more succinct. + // `Array.isArray` method + // https://tc39.es/ecma262/#sec-array.isarray + _export({ target: 'Array', stat: true }, { + isArray: isArray + }); - var StringStream = function (string, tabSize, lineOracle) { - this.pos = this.start = 0; - this.string = string; - this.tabSize = tabSize || 8; - this.lastColumnPos = this.lastColumnValue = 0; - this.lineStart = 0; - this.lineOracle = lineOracle; - }; + var isArray$2 = path.Array.isArray; - StringStream.prototype.eol = function () { return this.pos >= this.string.length }; - StringStream.prototype.sol = function () { return this.pos == this.lineStart }; - StringStream.prototype.peek = function () { return this.string.charAt(this.pos) || undefined }; - StringStream.prototype.next = function () { - if (this.pos < this.string.length) { return this.string.charAt(this.pos++) } - }; - StringStream.prototype.eat = function (match) { - var ch = this.string.charAt(this.pos); - var ok; - if (typeof match == "string") { ok = ch == match; } - else { ok = ch && (match.test ? match.test(ch) : match(ch)); } - if (ok) { ++this.pos; return ch } - }; - StringStream.prototype.eatWhile = function (match) { - var start = this.pos; - while (this.eat(match)) { } - return this.pos > start - }; - StringStream.prototype.eatSpace = function () { - var start = this.pos; - while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) { ++this.pos; } - return this.pos > start - }; - StringStream.prototype.skipToEnd = function () { this.pos = this.string.length; }; - StringStream.prototype.skipTo = function (ch) { - var found = this.string.indexOf(ch, this.pos); - if (found > -1) { this.pos = found; return true } - }; - StringStream.prototype.backUp = function (n) { this.pos -= n; }; - StringStream.prototype.column = function () { - if (this.lastColumnPos < this.start) { - this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue); - this.lastColumnPos = this.start; - } - return this.lastColumnValue - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0) - }; - StringStream.prototype.indentation = function () { - return countColumn(this.string, null, this.tabSize) - - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0) - }; - StringStream.prototype.match = function (pattern, consume, caseInsensitive) { - if (typeof pattern == "string") { - var cased = function (str) { return caseInsensitive ? str.toLowerCase() : str; }; - var substr = this.string.substr(this.pos, pattern.length); - if (cased(substr) == cased(pattern)) { - if (consume !== false) { this.pos += pattern.length; } - return true - } - } else { - var match = this.string.slice(this.pos).match(pattern); - if (match && match.index > 0) { return null } - if (match && consume !== false) { this.pos += match[0].length; } - return match - } - }; - StringStream.prototype.current = function () { return this.string.slice(this.start, this.pos) }; - StringStream.prototype.hideFirstChars = function (n, inner) { - this.lineStart += n; - try { return inner() } - finally { this.lineStart -= n; } - }; - StringStream.prototype.lookAhead = function (n) { - var oracle = this.lineOracle; - return oracle && oracle.lookAhead(n) - }; - StringStream.prototype.baseToken = function () { - var oracle = this.lineOracle; - return oracle && oracle.baseToken(this.pos) - }; + var isArray$3 = isArray$2; - // Find the line object corresponding to the given line number. - function getLine(doc, n) { - n -= doc.first; - if (n < 0 || n >= doc.size) { throw new Error("There is no line " + (n + doc.first) + " in the document.") } - var chunk = doc; - while (!chunk.lines) { - for (var i = 0; ; ++i) { - var child = chunk.children[i], sz = child.chunkSize(); - if (n < sz) { chunk = child; break } - n -= sz; - } - } - return chunk.lines[n] - } + var isArray$4 = isArray$3; - // Get the part of a document between two positions, as an array of - // strings. - function getBetween(doc, start, end) { - var out = [], n = start.line; - doc.iter(start.line, end.line + 1, function (line) { - var text = line.text; - if (n == end.line) { text = text.slice(0, end.ch); } - if (n == start.line) { text = text.slice(start.ch); } - out.push(text); - ++n; - }); - return out - } - // Get the lines between from and to, as array of strings. - function getLines(doc, from, to) { - var out = []; - doc.iter(from, to, function (line) { out.push(line.text); }); // iter aborts when callback returns truthy value - return out - } + var isArray$5 = isArray$4; - // Update the height of a line, propagating the height change - // upwards to parent nodes. - function updateLineHeight(line, height) { - var diff = height - line.height; - if (diff) { for (var n = line; n; n = n.parent) { n.height += diff; } } - } + var isArray$6 = isArray$5; - // Given a line object, find its line number by walking up through - // its parent links. - function lineNo(line) { - if (line.parent == null) { return null } - var cur = line.parent, no = indexOf(cur.lines, line); - for (var chunk = cur.parent; chunk; cur = chunk, chunk = chunk.parent) { - for (var i = 0; ; ++i) { - if (chunk.children[i] == cur) { break } - no += chunk.children[i].chunkSize(); - } - } - return no + cur.first - } + var isArray$7 = isArray$6; - // Find the line at the given vertical position, using the height - // information in the document tree. - function lineAtHeight(chunk, h) { - var n = chunk.first; - outer: do { - for (var i$1 = 0; i$1 < chunk.children.length; ++i$1) { - var child = chunk.children[i$1], ch = child.height; - if (h < ch) { chunk = child; continue outer } - h -= ch; - n += child.chunkSize(); - } - return n - } while (!chunk.lines) - var i = 0; - for (; i < chunk.lines.length; ++i) { - var line = chunk.lines[i], lh = line.height; - if (h < lh) { break } - h -= lh; - } - return n + i - } + var arrayWithHoles = createCommonjsModule(function (module) { + function _arrayWithHoles(arr) { + if (isArray$7(arr)) return arr; + } - function isLine(doc, l) { return l >= doc.first && l < doc.first + doc.size } + module.exports = _arrayWithHoles, module.exports.__esModule = true, module.exports["default"] = module.exports; + }); - function lineNumberFor(options, i) { - return String(options.lineNumberFormatter(i + options.firstLineNumber)) - } + unwrapExports(arrayWithHoles); - // A Pos instance represents a position within the text. - function Pos(line, ch, sticky) { - if (sticky === void 0) sticky = null; + var getIteratorMethod_1 = getIteratorMethod; - if (!(this instanceof Pos)) { return new Pos(line, ch, sticky) } - this.line = line; - this.ch = ch; - this.sticky = sticky; - } + var getIteratorMethod$1 = getIteratorMethod_1; - // Compare two positions, return 0 if they are the same, a negative - // number when a is less, and a positive number otherwise. - function cmp(a, b) { return a.line - b.line || a.ch - b.ch } + var getIteratorMethod$2 = getIteratorMethod$1; - function equalCursorPos(a, b) { return a.sticky == b.sticky && cmp(a, b) == 0 } + var getIteratorMethod$3 = getIteratorMethod$2; - function copyPos(x) { return Pos(x.line, x.ch) } - function maxPos(a, b) { return cmp(a, b) < 0 ? b : a } - function minPos(a, b) { return cmp(a, b) < 0 ? a : b } + var getIteratorMethod$4 = getIteratorMethod$3; - // Most of the external API clips given positions to make sure they - // actually exist within the document. - function clipLine(doc, n) { return Math.max(doc.first, Math.min(n, doc.first + doc.size - 1)) } - function clipPos(doc, pos) { - if (pos.line < doc.first) { return Pos(doc.first, 0) } - var last = doc.first + doc.size - 1; - if (pos.line > last) { return Pos(last, getLine(doc, last).text.length) } - return clipToLen(pos, getLine(doc, pos.line).text.length) - } - function clipToLen(pos, linelen) { - var ch = pos.ch; - if (ch == null || ch > linelen) { return Pos(pos.line, linelen) } - else if (ch < 0) { return Pos(pos.line, 0) } - else { return pos } - } - function clipPosArray(doc, array) { - var out = []; - for (var i = 0; i < array.length; i++) { out[i] = clipPos(doc, array[i]); } - return out - } + var getIteratorMethod$5 = getIteratorMethod$4; - var SavedContext = function (state, lookAhead) { - this.state = state; - this.lookAhead = lookAhead; - }; + var iterableToArrayLimit = createCommonjsModule(function (module) { + function _iterableToArrayLimit(arr, i) { + var _i = arr == null ? null : typeof symbol$5 !== "undefined" && getIteratorMethod$5(arr) || arr["@@iterator"]; - var Context = function (doc, state, line, lookAhead) { - this.state = state; - this.doc = doc; - this.line = line; - this.maxLookAhead = lookAhead || 0; - this.baseTokens = null; - this.baseTokenPos = 1; - }; + if (_i == null) return; + var _arr = []; + var _n = true; + var _d = false; - Context.prototype.lookAhead = function (n) { - var line = this.doc.getLine(this.line + n); - if (line != null && n > this.maxLookAhead) { this.maxLookAhead = n; } - return line - }; + var _s, _e; - Context.prototype.baseToken = function (n) { - if (!this.baseTokens) { return null } - while (this.baseTokens[this.baseTokenPos] <= n) { this.baseTokenPos += 2; } - var type = this.baseTokens[this.baseTokenPos + 1]; - return { - type: type && type.replace(/( |^)overlay .*/, ""), - size: this.baseTokens[this.baseTokenPos] - n - } - }; + try { + for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { + _arr.push(_s.value); - Context.prototype.nextLine = function () { - this.line++; - if (this.maxLookAhead > 0) { this.maxLookAhead--; } - }; + if (i && _arr.length === i) break; + } + } catch (err) { + _d = true; + _e = err; + } finally { + try { + if (!_n && _i["return"] != null) _i["return"](); + } finally { + if (_d) throw _e; + } + } - Context.fromSaved = function (doc, saved, line) { - if (saved instanceof SavedContext) { return new Context(doc, copyState(doc.mode, saved.state), line, saved.lookAhead) } - else { return new Context(doc, copyState(doc.mode, saved), line) } - }; + return _arr; + } - Context.prototype.save = function (copy) { - var state = copy !== false ? copyState(this.doc.mode, this.state) : this.state; - return this.maxLookAhead > 0 ? new SavedContext(state, this.maxLookAhead) : state - }; + module.exports = _iterableToArrayLimit, module.exports.__esModule = true, module.exports["default"] = module.exports; + }); + unwrapExports(iterableToArrayLimit); - // Compute a style array (an array starting with a mode generation - // -- for invalidation -- followed by pairs of end positions and - // style strings), which is used to highlight the tokens on the - // line. - function highlightLine(cm, line, context, forceToEnd) { - // A styles array always starts with a number identifying the - // mode/overlays that it is based on (for easy invalidation). - var st = [cm.state.modeGen], lineClasses = {}; - // Compute the base array of styles - runMode(cm, line.text, cm.doc.mode, context, function (end, style) { return st.push(end, style); }, - lineClasses, forceToEnd); - var state = context.state; - - // Run overlays, adjust style array. - var loop = function (o) { - context.baseTokens = st; - var overlay = cm.state.overlays[o], i = 1, at = 0; - context.state = true; - runMode(cm, line.text, overlay.mode, context, function (end, style) { - var start = i; - // Ensure there's a token end at the current position, and that i points at it - while (at < end) { - var i_end = st[i]; - if (i_end > end) { st.splice(i, 1, end, st[i + 1], i_end); } - i += 2; - at = Math.min(end, i_end); - } - if (!style) { return } - if (overlay.opaque) { - st.splice(start, i - start, end, "overlay " + style); - i = start + 2; - } else { - for (; start < i; start += 2) { - var cur = st[start + 1]; - st[start + 1] = (cur ? cur + " " : "") + "overlay " + style; - } - } - }, lineClasses); - context.state = state; - context.baseTokens = null; - context.baseTokenPos = 1; - }; + var HAS_SPECIES_SUPPORT$1 = arrayMethodHasSpeciesSupport('slice'); - for (var o = 0; o < cm.state.overlays.length; ++o) loop(o); + var SPECIES$2 = wellKnownSymbol('species'); + var Array$4 = global_1.Array; + var max$2 = Math.max; - return { styles: st, classes: lineClasses.bgClass || lineClasses.textClass ? lineClasses : null } - } + // `Array.prototype.slice` method + // https://tc39.es/ecma262/#sec-array.prototype.slice + // fallback for not array-like ES3 strings and DOM objects + _export({ target: 'Array', proto: true, forced: !HAS_SPECIES_SUPPORT$1 }, { + slice: function slice(start, end) { + var O = toIndexedObject(this); + var length = lengthOfArrayLike(O); + var k = toAbsoluteIndex(start, length); + var fin = toAbsoluteIndex(end === undefined ? length : end, length); + // inline `ArraySpeciesCreate` for usage native `Array#slice` where it's possible + var Constructor, result, n; + if (isArray(O)) { + Constructor = O.constructor; + // cross-realm fallback + if (isConstructor(Constructor) && (Constructor === Array$4 || isArray(Constructor.prototype))) { + Constructor = undefined; + } else if (isObject(Constructor)) { + Constructor = Constructor[SPECIES$2]; + if (Constructor === null) Constructor = undefined; + } + if (Constructor === Array$4 || Constructor === undefined) { + return arraySlice(O, k, fin); + } + } + result = new (Constructor === undefined ? Array$4 : Constructor)(max$2(fin - k, 0)); + for (n = 0; k < fin; k++, n++) if (k in O) createProperty(result, n, O[k]); + result.length = n; + return result; + } + }); - function getLineStyles(cm, line, updateFrontier) { - if (!line.styles || line.styles[0] != cm.state.modeGen) { - var context = getContextBefore(cm, lineNo(line)); - var resetState = line.text.length > cm.options.maxHighlightLength && copyState(cm.doc.mode, context.state); - var result = highlightLine(cm, line, context); - if (resetState) { context.state = resetState; } - line.stateAfter = context.save(!resetState); - line.styles = result.styles; - if (result.classes) { line.styleClasses = result.classes; } - else if (line.styleClasses) { line.styleClasses = null; } - if (updateFrontier === cm.doc.highlightFrontier) { cm.doc.modeFrontier = Math.max(cm.doc.modeFrontier, ++cm.doc.highlightFrontier); } - } - return line.styles - } + var slice = entryVirtual('Array').slice; - function getContextBefore(cm, n, precise) { - var doc = cm.doc, display = cm.display; - if (!doc.mode.startState) { return new Context(doc, true, n) } - var start = findStartLine(cm, n, precise); - var saved = start > doc.first && getLine(doc, start - 1).stateAfter; - var context = saved ? Context.fromSaved(doc, saved, start) : new Context(doc, startState(doc.mode), start); - - doc.iter(start, n, function (line) { - processLine(cm, line.text, context); - var pos = context.line; - line.stateAfter = pos == n - 1 || pos % 5 == 0 || pos >= display.viewFrom && pos < display.viewTo ? context.save() : null; - context.nextLine(); - }); - if (precise) { doc.modeFrontier = context.line; } - return context - } + var ArrayPrototype$6 = Array.prototype; - // Lightweight form of highlight -- proceed over this line and - // update state, but don't save a style array. Used for lines that - // aren't currently visible. - function processLine(cm, text, context, startAt) { - var mode = cm.doc.mode; - var stream = new StringStream(text, cm.options.tabSize, context); - stream.start = stream.pos = startAt || 0; - if (text == "") { callBlankLine(mode, context.state); } - while (!stream.eol()) { - readToken(mode, stream, context.state); - stream.start = stream.pos; - } - } + var slice$1 = function (it) { + var own = it.slice; + return it === ArrayPrototype$6 || (objectIsPrototypeOf(ArrayPrototype$6, it) && own === ArrayPrototype$6.slice) ? slice : own; + }; - function callBlankLine(mode, state) { - if (mode.blankLine) { return mode.blankLine(state) } - if (!mode.innerMode) { return } - var inner = innerMode(mode, state); - if (inner.mode.blankLine) { return inner.mode.blankLine(inner.state) } - } + var slice$2 = slice$1; - function readToken(mode, stream, state, inner) { - for (var i = 0; i < 10; i++) { - if (inner) { inner[0] = innerMode(mode, state).mode; } - var style = mode.token(stream, state); - if (stream.pos > stream.start) { return style } - } - throw new Error("Mode " + mode.name + " failed to advance stream.") - } + var slice$3 = slice$2; - var Token = function (stream, type, state) { - this.start = stream.start; this.end = stream.pos; - this.string = stream.current(); - this.type = type || null; - this.state = state; - }; + var slice$4 = slice$3; - // Utility for getTokenAt and getLineTokens - function takeToken(cm, pos, precise, asArray) { - var doc = cm.doc, mode = doc.mode, style; - pos = clipPos(doc, pos); - var line = getLine(doc, pos.line), context = getContextBefore(cm, pos.line, precise); - var stream = new StringStream(line.text, cm.options.tabSize, context), tokens; - if (asArray) { tokens = []; } - while ((asArray || stream.pos < pos.ch) && !stream.eol()) { - stream.start = stream.pos; - style = readToken(mode, stream, context.state); - if (asArray) { tokens.push(new Token(stream, style, copyState(doc.mode, context.state))); } - } - return asArray ? tokens : new Token(stream, style, context.state) - } + var slice$5 = slice$4; - function extractLineClasses(type, output) { - if (type) { - for (; ;) { - var lineClass = type.match(/(?:^|\s+)line-(background-)?(\S+)/); - if (!lineClass) { break } - type = type.slice(0, lineClass.index) + type.slice(lineClass.index + lineClass[0].length); - var prop = lineClass[1] ? "bgClass" : "textClass"; - if (output[prop] == null) { output[prop] = lineClass[2]; } - else if (!(new RegExp("(?:^|\\s)" + lineClass[2] + "(?:$|\\s)")).test(output[prop])) { output[prop] += " " + lineClass[2]; } - } - } - return type - } + var slice$6 = slice$5; - // Run the given mode's parser over a line, calling f for each token. - function runMode(cm, text, mode, context, f, lineClasses, forceToEnd) { - var flattenSpans = mode.flattenSpans; - if (flattenSpans == null) { flattenSpans = cm.options.flattenSpans; } - var curStart = 0, curStyle = null; - var stream = new StringStream(text, cm.options.tabSize, context), style; - var inner = cm.options.addModeClass && [null]; - if (text == "") { extractLineClasses(callBlankLine(mode, context.state), lineClasses); } - while (!stream.eol()) { - if (stream.pos > cm.options.maxHighlightLength) { - flattenSpans = false; - if (forceToEnd) { processLine(cm, text, context, stream.pos); } - stream.pos = text.length; - style = null; - } else { - style = extractLineClasses(readToken(mode, stream, context.state, inner), lineClasses); - } - if (inner) { - var mName = inner[0].name; - if (mName) { style = "m-" + (style ? mName + " " + style : mName); } - } - if (!flattenSpans || curStyle != style) { - while (curStart < stream.start) { - curStart = Math.min(stream.start, curStart + 5000); - f(curStart, curStyle); - } - curStyle = style; - } - stream.start = stream.pos; - } - while (curStart < stream.pos) { - // Webkit seems to refuse to render text nodes longer than 57444 - // characters, and returns inaccurate measurements in nodes - // starting around 5000 chars. - var pos = Math.min(stream.pos, curStart + 5000); - f(pos, curStyle); - curStart = pos; - } - } + var from_1$3 = from_1$1; - // Finds the line to start with when starting a parse. Tries to - // find a line with a stateAfter, so that it can start with a - // valid state. If that fails, it returns the line with the - // smallest indentation, which tends to need the least context to - // parse correctly. - function findStartLine(cm, n, precise) { - var minindent, minline, doc = cm.doc; - var lim = precise ? -1 : n - (cm.doc.mode.innerMode ? 1000 : 100); - for (var search = n; search > lim; --search) { - if (search <= doc.first) { return doc.first } - var line = getLine(doc, search - 1), after = line.stateAfter; - if (after && (!precise || search + (after instanceof SavedContext ? after.lookAhead : 0) <= doc.modeFrontier)) { return search } - var indented = countColumn(line.text, null, cm.options.tabSize); - if (minline == null || minindent > indented) { - minline = search - 1; - minindent = indented; - } - } - return minline - } + var from_1$4 = from_1$3; - function retreatFrontier(doc, n) { - doc.modeFrontier = Math.min(doc.modeFrontier, n); - if (doc.highlightFrontier < n - 10) { return } - var start = doc.first; - for (var line = n - 1; line > start; line--) { - var saved = getLine(doc, line).stateAfter; - // change is on 3 - // state on line 1 looked ahead 2 -- so saw 3 - // test 1 + 2 < 3 should cover this - if (saved && (!(saved instanceof SavedContext) || line + saved.lookAhead < n)) { - start = line + 1; - break - } - } - doc.highlightFrontier = Math.min(doc.highlightFrontier, start); - } + var from_1$5 = from_1$4; - // Optimize some code when these features are not used. - var sawReadOnlySpans = false, sawCollapsedSpans = false; + var from_1$6 = from_1$5; - function seeReadOnlySpans() { - sawReadOnlySpans = true; - } + var arrayLikeToArray = createCommonjsModule(function (module) { + function _arrayLikeToArray(arr, len) { + if (len == null || len > arr.length) len = arr.length; - function seeCollapsedSpans() { - sawCollapsedSpans = true; - } + for (var i = 0, arr2 = new Array(len); i < len; i++) { + arr2[i] = arr[i]; + } - // TEXTMARKER SPANS + return arr2; + } - function MarkedSpan(marker, from, to) { - this.marker = marker; - this.from = from; this.to = to; - } + module.exports = _arrayLikeToArray, module.exports.__esModule = true, module.exports["default"] = module.exports; + }); - // Search an array of spans for a span matching the given marker. - function getMarkedSpanFor(spans, marker) { - if (spans) { - for (var i = 0; i < spans.length; ++i) { - var span = spans[i]; - if (span.marker == marker) { return span } - } - } - } - // Remove a span from an array, returning undefined if no spans are - // left (we don't store arrays for lines without spans). - function removeMarkedSpan(spans, span) { - var r; - for (var i = 0; i < spans.length; ++i) { if (spans[i] != span) { (r || (r = [])).push(spans[i]); } } - return r - } - // Add a span to a line. - function addMarkedSpan(line, span) { - line.markedSpans = line.markedSpans ? line.markedSpans.concat([span]) : [span]; - span.marker.attachLine(line); - } + unwrapExports(arrayLikeToArray); - // Used for the algorithm that adjusts markers for a change in the - // document. These functions cut an array of spans at a given - // character position, returning an array of remaining chunks (or - // undefined if nothing remains). - function markedSpansBefore(old, startCh, isInsert) { - var nw; - if (old) { - for (var i = 0; i < old.length; ++i) { - var span = old[i], marker = span.marker; - var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= startCh : span.from < startCh); - if (startsBefore || span.from == startCh && marker.type == "bookmark" && (!isInsert || !span.marker.insertLeft)) { - var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= startCh : span.to > startCh) - ; (nw || (nw = [])).push(new MarkedSpan(marker, span.from, endsAfter ? null : span.to)); - } - } - } - return nw - } - function markedSpansAfter(old, endCh, isInsert) { - var nw; - if (old) { - for (var i = 0; i < old.length; ++i) { - var span = old[i], marker = span.marker; - var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= endCh : span.to > endCh); - if (endsAfter || span.from == endCh && marker.type == "bookmark" && (!isInsert || span.marker.insertLeft)) { - var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= endCh : span.from < endCh) - ; (nw || (nw = [])).push(new MarkedSpan(marker, startsBefore ? null : span.from - endCh, - span.to == null ? null : span.to - endCh)); - } - } - } - return nw - } + var unsupportedIterableToArray = createCommonjsModule(function (module) { + function _unsupportedIterableToArray(o, minLen) { + var _context; - // Given a change object, compute the new set of marker spans that - // cover the line in which the change took place. Removes spans - // entirely within the change, reconnects spans belonging to the - // same marker that appear on both sides of the change, and cuts off - // spans partially within the change. Returns an array of span - // arrays with one element for each line in (after) the change. - function stretchSpansOverChange(doc, change) { - if (change.full) { return null } - var oldFirst = isLine(doc, change.from.line) && getLine(doc, change.from.line).markedSpans; - var oldLast = isLine(doc, change.to.line) && getLine(doc, change.to.line).markedSpans; - if (!oldFirst && !oldLast) { return null } - - var startCh = change.from.ch, endCh = change.to.ch, isInsert = cmp(change.from, change.to) == 0; - // Get the spans that 'stick out' on both sides - var first = markedSpansBefore(oldFirst, startCh, isInsert); - var last = markedSpansAfter(oldLast, endCh, isInsert); - - // Next, merge those two ends - var sameLine = change.text.length == 1, offset = lst(change.text).length + (sameLine ? startCh : 0); - if (first) { - // Fix up .to properties of first - for (var i = 0; i < first.length; ++i) { - var span = first[i]; - if (span.to == null) { - var found = getMarkedSpanFor(last, span.marker); - if (!found) { span.to = startCh; } - else if (sameLine) { span.to = found.to == null ? null : found.to + offset; } - } - } - } - if (last) { - // Fix up .from in last (or move them into first in case of sameLine) - for (var i$1 = 0; i$1 < last.length; ++i$1) { - var span$1 = last[i$1]; - if (span$1.to != null) { span$1.to += offset; } - if (span$1.from == null) { - var found$1 = getMarkedSpanFor(first, span$1.marker); - if (!found$1) { - span$1.from = offset; - if (sameLine) { (first || (first = [])).push(span$1); } - } - } else { - span$1.from += offset; - if (sameLine) { (first || (first = [])).push(span$1); } - } - } - } - // Make sure we didn't create any zero-length spans - if (first) { first = clearEmptySpans(first); } - if (last && last != first) { last = clearEmptySpans(last); } - - var newMarkers = [first]; - if (!sameLine) { - // Fill gap with whole-line-spans - var gap = change.text.length - 2, gapMarkers; - if (gap > 0 && first) { - for (var i$2 = 0; i$2 < first.length; ++i$2) { - if (first[i$2].to == null) { (gapMarkers || (gapMarkers = [])).push(new MarkedSpan(first[i$2].marker, null, null)); } - } - } - for (var i$3 = 0; i$3 < gap; ++i$3) { newMarkers.push(gapMarkers); } - newMarkers.push(last); - } - return newMarkers - } + if (!o) return; + if (typeof o === "string") return arrayLikeToArray(o, minLen); - // Remove spans that are empty and don't have a clearWhenEmpty - // option of false. - function clearEmptySpans(spans) { - for (var i = 0; i < spans.length; ++i) { - var span = spans[i]; - if (span.from != null && span.from == span.to && span.marker.clearWhenEmpty !== false) { spans.splice(i--, 1); } - } - if (!spans.length) { return null } - return spans - } + var n = slice$6(_context = Object.prototype.toString.call(o)).call(_context, 8, -1); - // Used to 'clip' out readOnly ranges when making a change. - function removeReadOnlyRanges(doc, from, to) { - var markers = null; - doc.iter(from.line, to.line + 1, function (line) { - if (line.markedSpans) { - for (var i = 0; i < line.markedSpans.length; ++i) { - var mark = line.markedSpans[i].marker; - if (mark.readOnly && (!markers || indexOf(markers, mark) == -1)) { (markers || (markers = [])).push(mark); } - } - } - }); - if (!markers) { return null } - var parts = [{ from: from, to: to }]; - for (var i = 0; i < markers.length; ++i) { - var mk = markers[i], m = mk.find(0); - for (var j = 0; j < parts.length; ++j) { - var p = parts[j]; - if (cmp(p.to, m.from) < 0 || cmp(p.from, m.to) > 0) { continue } - var newParts = [j, 1], dfrom = cmp(p.from, m.from), dto = cmp(p.to, m.to); - if (dfrom < 0 || !mk.inclusiveLeft && !dfrom) { newParts.push({ from: p.from, to: m.from }); } - if (dto > 0 || !mk.inclusiveRight && !dto) { newParts.push({ from: m.to, to: p.to }); } - parts.splice.apply(parts, newParts); - j += newParts.length - 3; - } - } - return parts - } + if (n === "Object" && o.constructor) n = o.constructor.name; + if (n === "Map" || n === "Set") return from_1$6(o); + if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return arrayLikeToArray(o, minLen); + } - // Connect or disconnect spans from a line. - function detachMarkedSpans(line) { - var spans = line.markedSpans; - if (!spans) { return } - for (var i = 0; i < spans.length; ++i) { spans[i].marker.detachLine(line); } - line.markedSpans = null; - } - function attachMarkedSpans(line, spans) { - if (!spans) { return } - for (var i = 0; i < spans.length; ++i) { spans[i].marker.attachLine(line); } - line.markedSpans = spans; - } + module.exports = _unsupportedIterableToArray, module.exports.__esModule = true, module.exports["default"] = module.exports; + }); - // Helpers used when computing which overlapping collapsed span - // counts as the larger one. - function extraLeft(marker) { return marker.inclusiveLeft ? -1 : 0 } - function extraRight(marker) { return marker.inclusiveRight ? 1 : 0 } - - // Returns a number indicating which of two overlapping collapsed - // spans is larger (and thus includes the other). Falls back to - // comparing ids when the spans cover exactly the same range. - function compareCollapsedMarkers(a, b) { - var lenDiff = a.lines.length - b.lines.length; - if (lenDiff != 0) { return lenDiff } - var aPos = a.find(), bPos = b.find(); - var fromCmp = cmp(aPos.from, bPos.from) || extraLeft(a) - extraLeft(b); - if (fromCmp) { return -fromCmp } - var toCmp = cmp(aPos.to, bPos.to) || extraRight(a) - extraRight(b); - if (toCmp) { return toCmp } - return b.id - a.id - } + unwrapExports(unsupportedIterableToArray); - // Find out whether a line ends or starts in a collapsed span. If - // so, return the marker for that span. - function collapsedSpanAtSide(line, start) { - var sps = sawCollapsedSpans && line.markedSpans, found; - if (sps) { - for (var sp = (void 0), i = 0; i < sps.length; ++i) { - sp = sps[i]; - if (sp.marker.collapsed && (start ? sp.from : sp.to) == null && - (!found || compareCollapsedMarkers(found, sp.marker) < 0)) { found = sp.marker; } - } - } - return found - } - function collapsedSpanAtStart(line) { return collapsedSpanAtSide(line, true) } - function collapsedSpanAtEnd(line) { return collapsedSpanAtSide(line, false) } - - function collapsedSpanAround(line, ch) { - var sps = sawCollapsedSpans && line.markedSpans, found; - if (sps) { - for (var i = 0; i < sps.length; ++i) { - var sp = sps[i]; - if (sp.marker.collapsed && (sp.from == null || sp.from < ch) && (sp.to == null || sp.to > ch) && - (!found || compareCollapsedMarkers(found, sp.marker) < 0)) { found = sp.marker; } - } - } - return found - } + var nonIterableRest = createCommonjsModule(function (module) { + function _nonIterableRest() { + throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); + } - // Test whether there exists a collapsed span that partially - // overlaps (covers the start or end, but not both) of a new span. - // Such overlap is not allowed. - function conflictingCollapsedRange(doc, lineNo, from, to, marker) { - var line = getLine(doc, lineNo); - var sps = sawCollapsedSpans && line.markedSpans; - if (sps) { - for (var i = 0; i < sps.length; ++i) { - var sp = sps[i]; - if (!sp.marker.collapsed) { continue } - var found = sp.marker.find(0); - var fromCmp = cmp(found.from, from) || extraLeft(sp.marker) - extraLeft(marker); - var toCmp = cmp(found.to, to) || extraRight(sp.marker) - extraRight(marker); - if (fromCmp >= 0 && toCmp <= 0 || fromCmp <= 0 && toCmp >= 0) { continue } - if (fromCmp <= 0 && (sp.marker.inclusiveRight && marker.inclusiveLeft ? cmp(found.to, from) >= 0 : cmp(found.to, from) > 0) || - fromCmp >= 0 && (sp.marker.inclusiveRight && marker.inclusiveLeft ? cmp(found.from, to) <= 0 : cmp(found.from, to) < 0)) { return true } - } - } - } + module.exports = _nonIterableRest, module.exports.__esModule = true, module.exports["default"] = module.exports; + }); - // A visual line is a line as drawn on the screen. Folding, for - // example, can cause multiple logical lines to appear on the same - // visual line. This finds the start of the visual line that the - // given line is part of (usually that is the line itself). - function visualLine(line) { - var merged; - while (merged = collapsedSpanAtStart(line)) { line = merged.find(-1, true).line; } - return line - } + unwrapExports(nonIterableRest); - function visualLineEnd(line) { - var merged; - while (merged = collapsedSpanAtEnd(line)) { line = merged.find(1, true).line; } - return line - } + var slicedToArray = createCommonjsModule(function (module) { + function _slicedToArray(arr, i) { + return arrayWithHoles(arr) || iterableToArrayLimit(arr, i) || unsupportedIterableToArray(arr, i) || nonIterableRest(); + } - // Returns an array of logical lines that continue the visual line - // started by the argument, or undefined if there are no such lines. - function visualLineContinued(line) { - var merged, lines; - while (merged = collapsedSpanAtEnd(line)) { - line = merged.find(1, true).line - ; (lines || (lines = [])).push(line); - } - return lines - } + module.exports = _slicedToArray, module.exports.__esModule = true, module.exports["default"] = module.exports; + }); - // Get the line number of the start of the visual line that the - // given line number is part of. - function visualLineNo(doc, lineN) { - var line = getLine(doc, lineN), vis = visualLine(line); - if (line == vis) { return lineN } - return lineNo(vis) - } + var _slicedToArray = unwrapExports(slicedToArray); - // Get the line number of the start of the next visual line after - // the given line. - function visualLineEndNo(doc, lineN) { - if (lineN > doc.lastLine()) { return lineN } - var line = getLine(doc, lineN), merged; - if (!lineIsHidden(doc, line)) { return lineN } - while (merged = collapsedSpanAtEnd(line)) { line = merged.find(1, true).line; } - return lineNo(line) + 1 - } + var indexOf$8 = indexOf$3; - // Compute whether a line is hidden. Lines count as hidden when they - // are part of a visual line that starts with another line, or when - // they are entirely covered by collapsed, non-widget span. - function lineIsHidden(doc, line) { - var sps = sawCollapsedSpans && line.markedSpans; - if (sps) { - for (var sp = (void 0), i = 0; i < sps.length; ++i) { - sp = sps[i]; - if (!sp.marker.collapsed) { continue } - if (sp.from == null) { return true } - if (sp.marker.widgetNode) { continue } - if (sp.from == 0 && sp.marker.inclusiveLeft && lineIsHiddenInner(doc, line, sp)) { return true } - } - } - } - function lineIsHiddenInner(doc, line, span) { - if (span.to == null) { - var end = span.marker.find(1, true); - return lineIsHiddenInner(doc, end.line, getMarkedSpanFor(end.line.markedSpans, span.marker)) - } - if (span.marker.inclusiveRight && span.to == line.text.length) { return true } - for (var sp = (void 0), i = 0; i < line.markedSpans.length; ++i) { - sp = line.markedSpans[i]; - if (sp.marker.collapsed && !sp.marker.widgetNode && sp.from == span.to && - (sp.to == null || sp.to != span.from) && - (sp.marker.inclusiveLeft || span.marker.inclusiveRight) && - lineIsHiddenInner(doc, line, sp)) { return true } - } - } + var create$6 = create$1; - // Find the height above the given line. - function heightAtLine(lineObj) { - lineObj = visualLine(lineObj); + var slice$7 = slice$2; - var h = 0, chunk = lineObj.parent; - for (var i = 0; i < chunk.lines.length; ++i) { - var line = chunk.lines[i]; - if (line == lineObj) { break } - else { h += line.height; } - } - for (var p = chunk.parent; p; chunk = p, p = chunk.parent) { - for (var i$1 = 0; i$1 < p.children.length; ++i$1) { - var cur = p.children[i$1]; - if (cur == chunk) { break } - else { h += cur.height; } - } - } - return h - } + var trim$4 = stringTrim.trim; - // Compute the character length of a line, taking into account - // collapsed ranges (see markText) that might hide parts, and join - // other lines onto it. - function lineLength(line) { - if (line.height == 0) { return 0 } - var len = line.text.length, merged, cur = line; - while (merged = collapsedSpanAtStart(cur)) { - var found = merged.find(0, true); - cur = found.from.line; - len += found.from.ch - found.to.ch; - } - cur = line; - while (merged = collapsedSpanAtEnd(cur)) { - var found$1 = merged.find(0, true); - len -= cur.text.length - found$1.from.ch; - cur = found$1.to.line; - len += cur.text.length - found$1.to.ch; - } - return len - } - // Find the longest line in the document. - function findMaxLine(cm) { - var d = cm.display, doc = cm.doc; - d.maxLine = getLine(doc, doc.first); - d.maxLineLength = lineLength(d.maxLine); - d.maxLineChanged = true; - doc.iter(function (line) { - var len = lineLength(line); - if (len > d.maxLineLength) { - d.maxLineLength = len; - d.maxLine = line; - } - }); - } + var $parseInt = global_1.parseInt; + var Symbol$3 = global_1.Symbol; + var ITERATOR$5 = Symbol$3 && Symbol$3.iterator; + var hex = /^[+-]?0x/i; + var exec$2 = functionUncurryThis(hex.exec); + var FORCED$4 = $parseInt(whitespaces + '08') !== 8 || $parseInt(whitespaces + '0x16') !== 22 + // MS Edge 18- broken with boxed symbols + || (ITERATOR$5 && !fails(function () { $parseInt(Object(ITERATOR$5)); })); - // LINE DATA STRUCTURE + // `parseInt` method + // https://tc39.es/ecma262/#sec-parseint-string-radix + var numberParseInt = FORCED$4 ? function parseInt(string, radix) { + var S = trim$4(toString_1(string)); + return $parseInt(S, (radix >>> 0) || (exec$2(hex, S) ? 16 : 10)); + } : $parseInt; - // Line objects. These hold state related to a line, including - // highlighting info (the styles array). - var Line = function (text, markedSpans, estimateHeight) { - this.text = text; - attachMarkedSpans(this, markedSpans); - this.height = estimateHeight ? estimateHeight(this) : 1; - }; + // `parseInt` method + // https://tc39.es/ecma262/#sec-parseint-string-radix + _export({ global: true, forced: parseInt != numberParseInt }, { + parseInt: numberParseInt + }); - Line.prototype.lineNo = function () { return lineNo(this) }; - eventMixin(Line); - - // Change the content (text, markers) of a line. Automatically - // invalidates cached information and tries to re-estimate the - // line's height. - function updateLine(line, text, markedSpans, estimateHeight) { - line.text = text; - if (line.stateAfter) { line.stateAfter = null; } - if (line.styles) { line.styles = null; } - if (line.order != null) { line.order = null; } - detachMarkedSpans(line); - attachMarkedSpans(line, markedSpans); - var estHeight = estimateHeight ? estimateHeight(line) : 1; - if (estHeight != line.height) { updateLineHeight(line, estHeight); } - } + var _parseInt = path.parseInt; - // Detach a line from the document tree and its markers. - function cleanUpLine(line) { - line.parent = null; - detachMarkedSpans(line); - } + var _parseInt$1 = _parseInt; - // Convert a style as returned by a mode (either null, or a string - // containing one or more styles) to a CSS style. This is cached, - // and also looks for line-wide styles. - var styleToClassCache = {}, styleToClassCacheWithMode = {}; - function interpretTokenStyle(style, options) { - if (!style || /^\s*$/.test(style)) { return null } - var cache = options.addModeClass ? styleToClassCacheWithMode : styleToClassCache; - return cache[style] || - (cache[style] = style.replace(/\S+/g, "cm-$&")) - } + var _parseInt$2 = _parseInt$1; - // Render the DOM representation of the text of a line. Also builds - // up a 'line map', which points at the DOM nodes that represent - // specific stretches of text, and is used by the measuring code. - // The returned object contains the DOM node, this map, and - // information about line-wide styles that were set by the mode. - function buildLineContent(cm, lineView) { - // The padding-right forces the element to have a 'border', which - // is needed on Webkit to be able to get line-level bounding - // rectangles for it (in measureChar). - var content = eltP("span", null, null, webkit ? "padding-right: .1px" : null); - var builder = { - pre: eltP("pre", [content], "CodeMirror-line"), content: content, - col: 0, pos: 0, cm: cm, - trailingSpace: false, - splitSpaces: cm.getOption("lineWrapping") - }; - lineView.measure = {}; - - // Iterate over the logical lines that make up this visual line. - for (var i = 0; i <= (lineView.rest ? lineView.rest.length : 0); i++) { - var line = i ? lineView.rest[i - 1] : lineView.line, order = (void 0); - builder.pos = 0; - builder.addToken = buildToken; - // Optionally wire in some hacks into the token-rendering - // algorithm, to deal with browser quirks. - if (hasBadBidiRects(cm.display.measure) && (order = getOrder(line, cm.doc.direction))) { builder.addToken = buildTokenBadBidi(builder.addToken, order); } - builder.map = []; - var allowFrontierUpdate = lineView != cm.display.externalMeasured && lineNo(line); - insertLineContent(line, builder, getLineStyles(cm, line, allowFrontierUpdate)); - if (line.styleClasses) { - if (line.styleClasses.bgClass) { builder.bgClass = joinClasses(line.styleClasses.bgClass, builder.bgClass || ""); } - if (line.styleClasses.textClass) { builder.textClass = joinClasses(line.styleClasses.textClass, builder.textClass || ""); } - } + /** + * Copyright (C) 2021 THL A29 Limited, a Tencent company. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + // @ts-nocheck - // Ensure at least a single node is present, for measuring. - if (builder.map.length == 0) { builder.map.push(0, 0, builder.content.appendChild(zeroWidthElement(cm.display.measure))); } + /** + * 将html内容转换成md内容的工具 + * 调用方式为:htmlParser.run(htmlStr) + * 主要流程为: + * 1、接收html字符串 + * 2、根据html字符串生成html语法树 + * 3、递归遍历语法树,将标签替换为对应的markdown语法 + **/ + var htmlParser = { + /** + * 入口函数,负责将传入的html字符串转成对应的markdown源码 + * @param {string} htmlStr + * @returns {string} 对应的markdown源码 + */ + run: function run(htmlStr) { + var _context; + + var $htmlStr = "
".concat(htmlStr, "
"); // 挂载对应的格式化引擎,这里挂载的是markdown逆向引擎,后续可以扩展支持其他标记语言 + + this.tagParser.formatEngine = this.mdFormatEngine; // 去掉注释 + + $htmlStr = $htmlStr.replace(//g, ''); // 将html字符串解析成html语法树 + + var htmlparsedArrays = this.htmlParser.parseHtml($htmlStr); // 预处理,去掉一些不需要的样式、属性 + + htmlparsedArrays = this.paragraphStyleClear(htmlparsedArrays); // 核心逻辑,遍历html语法树,生成对应的markdown源码 + + return trim$3(_context = this.$dealHtml(htmlparsedArrays).replace(/\n{3,}/g, '\n\n\n').replace(/>/g, '>').replace(/</g, '<').replace(/&/g, '&')).call(_context, '\n'); + }, + + /** + * 解析html语法树 + * @param {Array} arr + * @returns {string} 对应的markdown源码 + */ + $dealHtml: function $dealHtml(arr) { + var ret = ''; + + for (var i = 0; i < arr.length; i++) { + var temObj = arr[i]; + if (temObj.type === 'tag') ret = this.$handleTagObject(temObj, ret);else if (temObj.type === 'text' && temObj.content.length > 0) { + ret += temObj.content.replace(/ /g, ' ').replace(/[\n]+/g, '\n').replace(/^[ \t\n]+\n\s*$/, '\n'); + } + } + + return ret; + }, + + /** + * 处理html标签内容 + * @param {object} temObj + * @param {string} returnString + */ + $handleTagObject: function $handleTagObject(temObj, returnString) { + var ret = returnString; + + if (temObj.attrs["class"] && /(ch-icon-square|ch-icon-check)/.test(temObj.attrs["class"])) { + var _context2; + + // 针对checklist + if (indexOf$8(_context2 = temObj.attrs["class"]).call(_context2, 'ch-icon-check') >= 0) { + ret += '[x]'; + } else { + ret += '[ ]'; + } + } else if (temObj.attrs["class"] && /cherry-code-preview-lang-select/.test(temObj.attrs["class"])) { + // 如果是代码块的选择语言标签,则不做任何处理 + ret += ''; + } else { + // 如果是标签 + ret += this.$dealTag(temObj); + } + + return ret; + }, + + /** + * 解析具体的html标签 + * @param {HTMLElement} obj + * @returns {string} 对应的markdown源码 + */ + $dealTag: function $dealTag(obj) { + var self = this; + var tmpText = ''; + + if (obj.children) { + // 递归每一个子元素 + tmpText = self.$dealHtml(obj.children); + } + + if (obj.name === 'style') { + // 不解析样式属性,只处理行内样式 + return ''; + } + + if (obj.name === 'code' || obj.name === 'pre') { + // 解析代码块 或 行内代码 + // pre时,强制转成代码块 + return self.tagParser.codeParser(obj, self.$dealCodeTag(obj), obj.name === 'pre'); + } + + if (typeof self.tagParser["".concat(obj.name, "Parser")] === 'function') { + // 解析对应的具体标签 + return self.tagParser["".concat(obj.name, "Parser")](obj, tmpText); + } + + return tmpText; + }, + + /** + * 解析代码块 + * 本函数认为代码块是由text标签和li标签组成的 + * @param {HTMLElement} obj + * @returns {string} 对应的markdown源码 + */ + $dealCodeTag: function $dealCodeTag(obj) { + var self = this; + + if (obj.children.length < 0) { + return ''; + } + + var ret = ''; + + for (var i = 0; i < obj.children.length; i++) { + var temObj = obj.children[i]; + + if (temObj.type !== 'text') { + // 如果是非text标签,则需要处理换行逻辑 + if (temObj.name === 'li') { + ret += '\n'; + } + + if (temObj.name === 'br') { + ret += '\n'; + } // 递归找到对应的代码文本 + + + ret += self.$dealCodeTag(temObj); + } else { + ret += temObj.content; + } + } + + return ret; + }, + + /** ** + * html解析器 + * 将html解析成对象数组 + * https://github.com/HenrikJoreteg/html-parse-stringify + **/ + htmlParser: { + attrRE: /([\w-]+)|['"]{1}([^'"]*)['"]{1}/g, + lookup: { + area: true, + base: true, + br: true, + col: true, + embed: true, + hr: true, + img: true, + video: true, + input: true, + keygen: true, + link: true, + menuitem: true, + meta: true, + param: true, + source: true, + track: true, + wbr: true + }, + tagRE: /<(?:"[^"]*"['"]*|'[^']*'['"]*|[^'">])+>/g, + empty: create$6 ? create$6(null) : {}, + parseTags: function parseTags(tag) { + var self = this; + var i = 0; + var key; + var res = { + type: 'tag', + name: '', + voidElement: false, + attrs: {}, + children: [] + }; + tag.replace(this.attrRE, function (match) { + if (i % 2) { + key = match; + } else { + if (i === 0) { + if (self.lookup[match] || tag.charAt(tag.length - 2) === '/') { + res.voidElement = true; + } + + res.name = match; + } else { + res.attrs[key] = match.replace(/['"]/g, ''); + } + } + + i += 1; + }); + return res; + }, + parseHtml: function parseHtml(html, options) { + var self = this; + var $options = options || {}; + $options.components || ($options.components = this.empty); + var result = []; + var current; + var level = -1; + var arr = []; + var byTag = {}; + var inComponent = false; + html.replace(this.tagRE, function (tag, index) { + if (inComponent) { + if (tag !== "")) { + return; + } + + inComponent = false; + } + + var isOpen = tag.charAt(1) !== '/'; + var start = index + tag.length; + var nextChar = html.charAt(start); + var parent; + + if (isOpen) { + level += 1; + current = self.parseTags(tag); + + if (current.type === 'tag' && $options.components[current.name]) { + current.type = 'component'; + inComponent = true; + } + + if (!current.voidElement && !inComponent && nextChar && nextChar !== '<') { + current.children.push({ + type: 'text', + content: slice$7(html).call(html, start, indexOf$8(html).call(html, '<', start)) + }); + } + + byTag[current.tagName] = current; // if we're at root, push new base node + + if (level === 0) { + result.push(current); + } + + parent = arr[level - 1]; + + if (parent) { + parent.children.push(current); + } + + arr[level] = current; + } + + if (!isOpen || current.voidElement) { + level -= 1; + + if (!inComponent && nextChar !== '<' && nextChar) { + // trailing text node + if (arr[level]) { + arr[level].children.push({ + type: 'text', + content: slice$7(html).call(html, start, indexOf$8(html).call(html, '<', start)) + }); + } + } + } + }); + return result; + } + }, + + /** ** + * 标签解析器 + * 解析对应的标签,并调用格式化引擎生成对应格式内容 + **/ + tagParser: { + // 挂载的解析引擎,一次只能挂在一个解析引擎,目前只实现和挂载了markdown解析引擎 + formatEngine: {}, + + /** + * 解析p标签 + * @param {HTMLElement} obj + * @param {string} str 需要回填的字符串 + * @returns {string} str + */ + pParser: function pParser(obj, str) { + var $str = str; + + if (/\n$/.test($str)) { + return $str; + } + + return "".concat($str, "\n"); + }, + + /** + * 解析div标签 + * @param {HTMLElement} obj + * @param {string} str 需要回填的字符串 + * @returns {string} str + */ + divParser: function divParser(obj, str) { + var $str = str; + + if (/\n$/.test($str)) { + return $str; + } + + return "".concat($str, "\n"); + }, + + /** + * 解析span标签 + * @param {HTMLElement} obj + * @param {string} str 需要回填的字符串 + * @returns {string} str + */ + spanParser: function spanParser(obj, str) { + var $str = str.replace(/\t/g, '').replace(/\n/g, ' '); // span标签里不应该有\n的,有的话就转化成空格 + + if (obj.attrs && obj.attrs.style) ; + + return $str; + }, + + /** + * 解析code标签 + * @param {HTMLElement} obj + * @param {string} str 需要回填的字符串 + * @param {boolean} isBlock 是否强制为代码块 + * @returns {string} str + */ + codeParser: function codeParser(obj, str) { + var isBlock = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + return this.formatEngine.convertCode(str, isBlock); + }, + + /** + * 解析br标签 + * @param {HTMLElement} obj + * @param {string} str 需要回填的字符串 + * @returns {string} str + */ + brParser: function brParser(obj, str) { + return this.formatEngine.convertBr(str, '\n'); + }, + + /** + * 解析img标签 + * @param {HTMLElement} obj + * @param {string} str 需要回填的字符串 + * @returns {string} str + */ + imgParser: function imgParser(obj, str) { + if (obj.attrs && obj.attrs['data-control'] === 'tapd-graph') { + return this.formatEngine.convertGraph(obj.attrs.title, obj.attrs.src, obj.attrs['data-origin-xml'], obj); + } + + if (obj.attrs && obj.attrs.src) { + return this.formatEngine.convertImg(obj.attrs.alt, obj.attrs.src); + } + }, + + /** + * 解析video标签 + * @param {HTMLElement} obj + * @param {string} str 需要回填的字符串 + * @returns {string} str + */ + videoParser: function videoParser(obj, str) { + if (obj.attrs && obj.attrs.src) { + return this.formatEngine.convertVideo(str, obj.attrs.src, obj.attrs.poster, obj.attrs.title); + } + }, + + /** + * 解析b标签 + * @param {HTMLElement} obj + * @param {string} str 需要回填的字符串 + * @returns {string} str + */ + bParser: function bParser(obj, str) { + var strArr = str.split('\n'); + var ret = []; + + for (var i = 0; i < strArr.length; i++) { + ret.push(this.formatEngine.convertB(strArr[i])); + } + + return ret.join('\n'); + }, + + /** + * 解析i标签 + * @param {HTMLElement} obj + * @param {string} str 需要回填的字符串 + * @returns {string} str + */ + iParser: function iParser(obj, str) { + var strArr = str.split('\n'); + var ret = []; + + for (var i = 0; i < strArr.length; i++) { + ret.push(this.formatEngine.convertI(strArr[i])); + } + + return ret.join('\n'); + }, + + /** + * 解析strike标签 + * @param {HTMLElement} obj + * @param {string} str 需要回填的字符串 + * @returns {string} str + */ + strikeParser: function strikeParser(obj, str) { + var strArr = str.split('\n'); + var ret = []; + + for (var i = 0; i < strArr.length; i++) { + ret.push(this.formatEngine.convertStrike(strArr[i])); + } + + return ret.join('\n'); + }, + + /** + * 解析del标签 + * @param {HTMLElement} obj + * @param {string} str 需要回填的字符串 + * @returns {string} str + */ + delParser: function delParser(obj, str) { + var strArr = str.split('\n'); + var ret = []; + + for (var i = 0; i < strArr.length; i++) { + ret.push(this.formatEngine.convertDel(strArr[i])); + } + + return ret.join('\n'); + }, + + /** + * 解析u标签 + * @param {HTMLElement} obj + * @param {string} str 需要回填的字符串 + * @returns {string} str + */ + uParser: function uParser(obj, str) { + var strArr = str.split('\n'); + var ret = []; + + for (var i = 0; i < strArr.length; i++) { + ret.push(this.formatEngine.convertU(strArr[i])); + } + + return ret.join('\n'); + }, + + /** + * 解析a标签 + * @param {HTMLElement} obj + * @param {string} str 需要回填的字符串 + * @returns {string} str + */ + aParser: function aParser(obj, str) { + if (obj.attrs && obj.attrs.href) { + return this.formatEngine.convertA(str, obj.attrs.href); + } + + return ''; + }, + + /** + * 解析sup标签 + * @param {HTMLElement} obj + * @param {string} str 需要回填的字符串 + * @returns {string} str + */ + supParser: function supParser(obj, str) { + return this.formatEngine.convertSup(str); + }, + + /** + * 解析sub标签 + * @param {HTMLElement} obj + * @param {string} str 需要回填的字符串 + * @returns {string} str + */ + subParser: function subParser(obj, str) { + return this.formatEngine.convertSub(str); + }, + + /** + * 解析td标签 + * @param {HTMLElement} obj + * @param {string} str 需要回填的字符串 + * @returns {string} str + */ + tdParser: function tdParser(obj, str) { + return this.formatEngine.convertTd(str); + }, + + /** + * 解析tr标签 + * @param {HTMLElement} obj + * @param {string} str 需要回填的字符串 + * @returns {string} str + */ + trParser: function trParser(obj, str) { + return this.formatEngine.convertTr(str); + }, + + /** + * 解析th标签 + * @param {HTMLElement} obj + * @param {string} str 需要回填的字符串 + * @returns {string} str + */ + thParser: function thParser(obj, str) { + return this.formatEngine.convertTh(str); + }, + + /** + * 解析thead标签 + * @param {HTMLElement} obj + * @param {string} str 需要回填的字符串 + * @returns {string} str + */ + theadParser: function theadParser(obj, str) { + return this.formatEngine.convertThead(str); + }, + + /** + * 解析table标签 + * @param {HTMLElement} obj + * @param {string} str 需要回填的字符串 + * @returns {string} str + */ + tableParser: function tableParser(obj, str) { + return this.formatEngine.convertTable(str); + }, + + /** + * 解析li标签 + * @param {HTMLElement} obj + * @param {string} str 需要回填的字符串 + * @returns {string} str + */ + liParser: function liParser(obj, str) { + return this.formatEngine.convertLi(str); + }, + + /** + * 解析ul标签 + * @param {HTMLElement} obj + * @param {string} str 需要回填的字符串 + * @returns {string} str + */ + ulParser: function ulParser(obj, str) { + return this.formatEngine.convertUl(str); + }, + + /** + * 解析ol标签 + * @param {HTMLElement} obj + * @param {string} str 需要回填的字符串 + * @returns {string} str + */ + olParser: function olParser(obj, str) { + return this.formatEngine.convertOl(str); + }, + + /** + * 解析strong标签 + * @param {HTMLElement} obj + * @param {string} str 需要回填的字符串 + * @returns {string} str + */ + strongParser: function strongParser(obj, str) { + return this.formatEngine.convertStrong(str); + }, + + /** + * 解析hr标签 + * @param {HTMLElement} obj + * @param {string} str 需要回填的字符串 + * @returns {string} str + */ + hrParser: function hrParser(obj, str) { + return this.formatEngine.convertHr(str); + }, + + /** + * 解析h1标签 + * @param {HTMLElement} obj + * @param {string} str 需要回填的字符串 + * @returns {string} str + */ + h1Parser: function h1Parser(obj, str) { + return this.formatEngine.convertH1(str); + }, + + /** + * 解析h2标签 + * @param {HTMLElement} obj + * @param {string} str 需要回填的字符串 + * @returns {string} str + */ + h2Parser: function h2Parser(obj, str) { + return this.formatEngine.convertH2(str); + }, + + /** + * 解析h3标签 + * @param {HTMLElement} obj + * @param {string} str 需要回填的字符串 + * @returns {string} str + */ + h3Parser: function h3Parser(obj, str) { + return this.formatEngine.convertH3(str); + }, + + /** + * 解析h4标签 + * @param {HTMLElement} obj + * @param {string} str 需要回填的字符串 + * @returns {string} str + */ + h4Parser: function h4Parser(obj, str) { + return this.formatEngine.convertH4(str); + }, + + /** + * 解析h5标签 + * @param {HTMLElement} obj + * @param {string} str 需要回填的字符串 + * @returns {string} str + */ + h5Parser: function h5Parser(obj, str) { + return this.formatEngine.convertH5(str); + }, + + /** + * 解析h6标签 + * @param {HTMLElement} obj + * @param {string} str 需要回填的字符串 + * @returns {string} str + */ + h6Parser: function h6Parser(obj, str) { + return this.formatEngine.convertH6(str); + }, + + /** + * 解析blockquote标签 + * @param {HTMLElement} obj + * @param {string} str 需要回填的字符串 + * @returns {string} str + */ + blockquoteParser: function blockquoteParser(obj, str) { + return this.formatEngine.convertBlockquote(str.replace(/\n+/g, '\n')); + }, + + /** + * 解析address标签 + * @param {HTMLElement} obj + * @param {string} str 需要回填的字符串 + * @returns {string} str + */ + addressParser: function addressParser(obj, str) { + return this.formatEngine.convertAddress(str.replace(/\n+/g, '\n')); + }, + // 样式解析器 + styleParser: { + // 识别字体颜色 color + colorAttrParser: function colorAttrParser(style) { + var color = style.match(/color:\s*(#[a-zA-Z0-9]{3,6});/); + + if (color && color[1]) { + return color[1]; + } + + return ''; + }, + // 识别字体大小 font-size + sizeAttrParser: function sizeAttrParser(style) { + var fontSize = style.match(/font-size:\s*([a-zA-Z0-9-]+?);/); + + if (fontSize && fontSize[1]) { + var size = 0; + + if (/[0-9]+px/.test(fontSize[1])) { + var _context3; + + size = trim$3(_context3 = fontSize[1].replace(/px/, '')).call(_context3); + } else { + switch (fontSize[1]) { + case 'x-small': + size = 10; + break; + + case 'small': + size = 12; + break; + + case 'medium': + size = 16; + break; + + case 'large': + size = 18; + break; + + case 'x-large': + size = 24; + break; + + case 'xx-large': + size = 32; + break; + + default: + size = ''; + } + } + + return size > 0 ? size : ''; + } + + return ''; + }, + // 识别字体背景颜色 background-color + bgColorAttrParser: function bgColorAttrParser(style) { + var color = style.match(/background-color:\s*([^;]+?);/); + + if (color && color[1]) { + var bgColor = ''; + + if (/rgb\([ 0-9]+,[ 0-9]+,[ 0-9]+\)/.test(color[1])) { + var values = color[1].match(/rgb\(([ 0-9]+),([ 0-9]+),([ 0-9]+)\)/); + + if (values[1] && values[2] && values[3]) { + var _context4, _context5, _context6, _context7, _context8; + + values[1] = _parseInt$2(trim$3(_context4 = values[1]).call(_context4), 10); + values[2] = _parseInt$2(trim$3(_context5 = values[2]).call(_context5), 10); + values[3] = _parseInt$2(trim$3(_context6 = values[3]).call(_context6), 10); + bgColor = concat$5(_context7 = concat$5(_context8 = "#".concat(values[1].toString(16))).call(_context8, values[2].toString(16))).call(_context7, values[3].toString(16)); + } + } else { + var _color = _slicedToArray(color, 2); + + bgColor = _color[1]; + } + + return bgColor; + } + + return ''; + } + } + }, + + /** + * 一个格式化引擎 + * 将字符串格式化成markdown语法的引擎 + **/ + mdFormatEngine: { + convertColor: function convertColor(str, attr) { + var _context9; + + var $str = trim$3(str).call(str); + + if (!$str || /\n/.test($str)) { + return $str; + } + + return attr ? concat$5(_context9 = "!!".concat(attr, " ")).call(_context9, $str, "!!") : $str; + }, + convertSize: function convertSize(str, attr) { + var _context10; + + var $str = trim$3(str).call(str); + + if (!$str || /\n/.test($str)) { + return $str; + } + + return attr ? concat$5(_context10 = "!".concat(attr, " ")).call(_context10, $str, "!") : $str; + }, + convertBgColor: function convertBgColor(str, attr) { + var _context11; + + var $str = trim$3(str).call(str); + + if (!$str || /\n/.test($str)) { + return $str; + } + + return attr ? concat$5(_context11 = "!!!".concat(attr, " ")).call(_context11, $str, "!!!") : $str; + }, + convertBr: function convertBr(str, attr) { + return str + attr; + }, + convertCode: function convertCode(str) { + var isBlock = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + + if (/\n/.test(str) || isBlock) { + return "```\n".concat(str.replace(/\n+$/, ''), "\n```"); + } + + return "`".concat(str.replace(/`/g, '\\`'), "`"); + }, + convertB: function convertB(str) { + return /^\s*$/.test(str) ? '' : "**".concat(str, "**"); + }, + convertI: function convertI(str) { + return /^\s*$/.test(str) ? '' : "*".concat(str, "*"); + }, + convertU: function convertU(str) { + return /^\s*$/.test(str) ? '' : " /".concat(str, "/ "); + }, + convertImg: function convertImg(alt, src) { + var _context12; + + var $alt = alt && alt.length > 0 ? alt : 'image'; + return concat$5(_context12 = "![".concat($alt, "](")).call(_context12, src, ")"); + }, + convertGraph: function convertGraph(str, attr, data, obj) { + var _context15, _context16, _context17; + + var $str = str && str.length > 0 ? str : 'graph'; + var moreAttrs = ''; + + if (obj) { + try { + var _context13; + + var attrs = obj.attrs; + + forEach$3(_context13 = keys$3(attrs)).call(_context13, function (prop) { + if (Object.prototype.hasOwnProperty.call(attrs, prop)) { + if (indexOf$8(prop).call(prop, 'data-graph-') >= 0 && attrs[prop]) { + var _context14; + + moreAttrs += concat$5(_context14 = " ".concat(prop, "=")).call(_context14, attrs[prop]); + } + } + }); + } catch (error) {// console.log('error', error) + } + } + + return concat$5(_context15 = concat$5(_context16 = concat$5(_context17 = "![".concat($str, "](")).call(_context17, attr, "){data-control=tapd-graph data-origin-xml=")).call(_context16, data)).call(_context15, moreAttrs, "}"); + }, + convertVideo: function convertVideo(str, src, poster, title) { + var _context18, _context19; + + var $title = title && title.length > 0 ? title : 'video'; + return concat$5(_context18 = concat$5(_context19 = "!video[".concat($title, "](")).call(_context19, src, "){poster=")).call(_context18, poster, "}"); + }, + convertA: function convertA(str, attr) { + var _context20; + + if (str === attr) { + return "".concat(str, " "); + } + + var $str = trim$3(str).call(str); + + if (!$str) { + return $str; + } + + return concat$5(_context20 = "[".concat($str, "](")).call(_context20, attr, ")"); + }, + convertSup: function convertSup(str) { + return "^".concat(trim$3(str).call(str).replace(/\^/g, '\\^'), "^"); + }, + convertSub: function convertSub(str) { + return "^^".concat(trim$3(str).call(str).replace(/\^\^/g, '\\^\\^'), "^^"); + }, + convertTd: function convertTd(str) { + return "~|".concat(trim$3(str).call(str).replace(/\n{1,}/g, '
'), " ~|"); + }, + convertTh: function convertTh(str) { + return "~|".concat(trim$3(str).call(str).replace(/\n{1,}/g, '
'), " ~|"); + }, + convertTr: function convertTr(str) { + return "".concat(str.replace(/\n/g, ''), "\n"); + }, + convertThead: function convertThead(str) { + return "".concat(str.replace(/~\|~\|/g, '~|').replace(/~\|/g, '|'), "|:--|\n"); + }, + convertTable: function convertTable(str) { + var ret = "\n".concat(str.replace(/~\|~\|/g, '~|').replace(/~\|/g, '|'), "\n").replace(/\n{2,}/g, '\n'); + + if (/\|:--\|/.test(ret)) { + return ret; + } + + return "\n| |\n|:--|".concat(ret); + }, + convertLi: function convertLi(str) { + return "- ".concat(str.replace(/^\n/, '').replace(/\n+$/, '').replace(/\n+/g, '\n\t'), "\n"); + }, + convertUl: function convertUl(str) { + return "".concat(str, "\n"); + }, + convertOl: function convertOl(str) { + var arr = str.split('\n'); + var index = 1; + + for (var i = 0; i < arr.length; i++) { + if (/^- /.test(arr[i])) { + arr[i] = arr[i].replace(/^- /, "".concat(index, ". ")); + index += 1; + } + } + + var $str = arr.join('\n'); + return "".concat($str, "\n"); + }, + convertStrong: function convertStrong(str) { + return /^\s*$/.test(str) ? '' : "**".concat(str, "**"); + }, + convertStrike: function convertStrike(str) { + return /^\s*$/.test(str) ? '' : "~~".concat(str, "~~"); + }, + convertDel: function convertDel(str) { + return /^\s*$/.test(str) ? '' : "~~".concat(str, "~~"); + }, + convertHr: function convertHr(str) { + return /^\s*$/.test(str) ? '\n\n----\n' : "\n\n----\n".concat(str); + }, + convertH1: function convertH1(str) { + return "# ".concat(trim$3(str).call(str).replace(/\n+$/, ''), "\n\n"); + }, + convertH2: function convertH2(str) { + return "## ".concat(trim$3(str).call(str).replace(/\n+$/, ''), "\n\n"); + }, + convertH3: function convertH3(str) { + return "### ".concat(trim$3(str).call(str).replace(/\n+$/, ''), "\n\n"); + }, + convertH4: function convertH4(str) { + return "#### ".concat(trim$3(str).call(str).replace(/\n+$/, ''), "\n\n"); + }, + convertH5: function convertH5(str) { + return "##### ".concat(trim$3(str).call(str).replace(/\n+$/, ''), "\n\n"); + }, + convertH6: function convertH6(str) { + return "###### ".concat(trim$3(str).call(str).replace(/\n+$/, ''), "\n\n"); + }, + convertBlockquote: function convertBlockquote(str) { + return ">".concat(trim$3(str).call(str), "\n\n"); + }, + convertAddress: function convertAddress(str) { + return ">".concat(trim$3(str).call(str), "\n\n"); + } + }, + + /** + * 清除整段的样式、方便编辑 + * 暂时先屏蔽字体色和背景色 + * @param {Array} htmlparsedArrays 由HTMLElement组成的数组 + */ + paragraphStyleClear: function paragraphStyleClear(htmlparsedArrays) { + for (var index = 0; index < htmlparsedArrays[0].children.length; index++) { + var htmlItem = htmlparsedArrays[0].children[index]; + var stack = [htmlItem]; + var paragraphs = []; + + while (stack.length) { + var temp = stack.shift(); + var childCount = this.notEmptyTagCount(temp); + + if (childCount === 1) { + paragraphs.push(temp); + } else if (childCount > 1) { + for (var k = 0; k < temp.children.length; k++) { + stack.push(temp.children[k]); + } + } else { + if (paragraphs.length === 1) { + this.clearChildColorAttrs(paragraphs.pop()); + } + + paragraphs = []; + } + } + + if (paragraphs.length === 1) { + this.clearChildColorAttrs(paragraphs.pop()); + } + } + + return htmlparsedArrays; + }, + + /** + * 非空子元素数量 + */ + notEmptyTagCount: function notEmptyTagCount(htmlItem) { + if (!htmlItem || htmlItem.voidElement || htmlItem.type === 'tag' && !htmlItem.children.length || htmlItem.type === 'text' && !htmlItem.content.replace(/(\r|\n|\s)+/g, '')) { + return 0; + } + + if (htmlItem.children && htmlItem.children.length) { + var res = 0; + + for (var index = 0; index < htmlItem.children.length; index++) { + res += this.notEmptyTagCount(htmlItem.children[index]); + } + + return res; + } + + return 1; + }, + clearChildColorAttrs: function clearChildColorAttrs(htmlItems) { + var self = this; + this.forEachHtmlParsedItems(htmlItems, function (htmlItem) { + self.clearSelfNodeColorAttrs(htmlItem); + }); + }, + clearSelfNodeColorAttrs: function clearSelfNodeColorAttrs(htmlItem) { + if (htmlItem.attrs && htmlItem.attrs.style) { + var styles = htmlItem.attrs.style.split(';'); + var newStyles = []; + + for (var index = 0; index < styles.length; index++) { + var _context21; + + if (styles[index] && indexOf$8(_context21 = styles[index]).call(_context21, 'color') === -1) { + newStyles.push(styles[index]); + } + } + + if (newStyles.length) { + htmlItem.attrs.style = "".concat(newStyles.join(';'), ";"); + } else { + delete htmlItem.attrs.style; + } + } + }, + forEachHtmlParsedItems: function forEachHtmlParsedItems(htmlItems, cb) { + if (htmlItems) { + cb(htmlItems); + + if (htmlItems.children && htmlItems.children.length) { + for (var index = 0; index < htmlItems.children.length; index++) { + this.forEachHtmlParsedItems(htmlItems.children[index], cb); + } + } + } + } + }; - // Store the map and a cache object for the current logical line - if (i == 0) { - lineView.measure.map = builder.map; - lineView.measure.cache = {}; - } else { - (lineView.measure.maps || (lineView.measure.maps = [])).push(builder.map) - ; (lineView.measure.caches || (lineView.measure.caches = [])).push({}); - } - } + var assign$3 = assign$1; - // See issue #2901 - if (webkit) { - var last = builder.content.lastChild; - if (/\bcm-tab\b/.test(last.className) || (last.querySelector && last.querySelector(".cm-tab"))) { builder.content.className = "cm-tab-wrap-hack"; } - } + var assign$4 = assign$3; - signal(cm, "renderLine", cm, lineView.line, builder.pre); - if (builder.pre.className) { builder.textClass = joinClasses(builder.pre.className, builder.textClass || ""); } + var assign$5 = assign$4; - return builder - } + var assign$6 = assign$5; - function defaultSpecialCharPlaceholder(ch) { - var token = elt("span", "\u2022", "cm-invalidchar"); - token.title = "\\u" + ch.charCodeAt(0).toString(16); - token.setAttribute("aria-label", token.title); - return token - } + var _extends_1 = createCommonjsModule(function (module) { + function _extends() { + module.exports = _extends = assign$6 || function (target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; - // Build up the DOM representation for a single token, and add it to - // the line map. Takes care to render special characters separately. - function buildToken(builder, text, style, startStyle, endStyle, css, attributes) { - if (!text) { return } - var displayText = builder.splitSpaces ? splitSpaces(text, builder.trailingSpace) : text; - var special = builder.cm.state.specialChars, mustWrap = false; - var content; - if (!special.test(text)) { - builder.col += text.length; - content = document.createTextNode(displayText); - builder.map.push(builder.pos, builder.pos + text.length, content); - if (ie && ie_version < 9) { mustWrap = true; } - builder.pos += text.length; - } else { - content = document.createDocumentFragment(); - var pos = 0; - while (true) { - special.lastIndex = pos; - var m = special.exec(text); - var skipped = m ? m.index - pos : text.length - pos; - if (skipped) { - var txt = document.createTextNode(displayText.slice(pos, pos + skipped)); - if (ie && ie_version < 9) { content.appendChild(elt("span", [txt])); } - else { content.appendChild(txt); } - builder.map.push(builder.pos, builder.pos + skipped, txt); - builder.col += skipped; - builder.pos += skipped; - } - if (!m) { break } - pos += skipped + 1; - var txt$1 = (void 0); - if (m[0] == "\t") { - var tabSize = builder.cm.options.tabSize, tabWidth = tabSize - builder.col % tabSize; - txt$1 = content.appendChild(elt("span", spaceStr(tabWidth), "cm-tab")); - txt$1.setAttribute("role", "presentation"); - txt$1.setAttribute("cm-text", "\t"); - builder.col += tabWidth; - } else if (m[0] == "\r" || m[0] == "\n") { - txt$1 = content.appendChild(elt("span", m[0] == "\r" ? "\u240d" : "\u2424", "cm-invalidchar")); - txt$1.setAttribute("cm-text", m[0]); - builder.col += 1; - } else { - txt$1 = builder.cm.options.specialCharPlaceholder(m[0]); - txt$1.setAttribute("cm-text", m[0]); - if (ie && ie_version < 9) { content.appendChild(elt("span", [txt$1])); } - else { content.appendChild(txt$1); } - builder.col += 1; - } - builder.map.push(builder.pos, builder.pos + 1, txt$1); - builder.pos++; - } - } - builder.trailingSpace = displayText.charCodeAt(text.length - 1) == 32; - if (style || startStyle || endStyle || mustWrap || css || attributes) { - var fullStyle = style || ""; - if (startStyle) { fullStyle += startStyle; } - if (endStyle) { fullStyle += endStyle; } - var token = elt("span", [content], fullStyle, css); - if (attributes) { - for (var attr in attributes) { - if (attributes.hasOwnProperty(attr) && attr != "style" && attr != "class") { token.setAttribute(attr, attributes[attr]); } - } - } - return builder.content.appendChild(token) - } - builder.content.appendChild(content); - } + for (var key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) { + target[key] = source[key]; + } + } + } - // Change some spaces to NBSP to prevent the browser from collapsing - // trailing spaces at the end of a line when rendering text (issue #1362). - function splitSpaces(text, trailingBefore) { - if (text.length > 1 && !/ /.test(text)) { return text } - var spaceBefore = trailingBefore, result = ""; - for (var i = 0; i < text.length; i++) { - var ch = text.charAt(i); - if (ch == " " && spaceBefore && (i == text.length - 1 || text.charCodeAt(i + 1) == 32)) { ch = "\u00a0"; } - result += ch; - spaceBefore = ch == " "; - } - return result - } + return target; + }, module.exports.__esModule = true, module.exports["default"] = module.exports; + return _extends.apply(this, arguments); + } - // Work around nonsense dimensions being reported for stretches of - // right-to-left text. - function buildTokenBadBidi(inner, order) { - return function (builder, text, style, startStyle, endStyle, css, attributes) { - style = style ? style + " cm-force-border" : "cm-force-border"; - var start = builder.pos, end = start + text.length; - for (; ;) { - // Find the part that overlaps with the start of this text - var part = (void 0); - for (var i = 0; i < order.length; i++) { - part = order[i]; - if (part.to > start && part.from <= start) { break } - } - if (part.to >= end) { return inner(builder, text, style, startStyle, endStyle, css, attributes) } - inner(builder, text.slice(0, part.to - start), style, startStyle, null, css, attributes); - startStyle = null; - text = text.slice(part.to - start); - start = part.to; - } - } - } + module.exports = _extends, module.exports.__esModule = true, module.exports["default"] = module.exports; + }); - function buildCollapsedSpan(builder, size, marker, ignoreWidget) { - var widget = !ignoreWidget && marker.widgetNode; - if (widget) { builder.map.push(builder.pos, builder.pos + size, widget); } - if (!ignoreWidget && builder.cm.display.input.needsContentAttribute) { - if (!widget) { widget = builder.content.appendChild(document.createElement("span")); } - widget.setAttribute("cm-marker", marker.id); - } - if (widget) { - builder.cm.display.input.setUneditable(widget); - builder.content.appendChild(widget); - } - builder.pos += size; - builder.trailingSpace = false; - } + var _extends = unwrapExports(_extends_1); - // Outputs a number of spans to make up a line, taking highlighting - // and marked text into account. - function insertLineContent(line, builder, styles) { - var spans = line.markedSpans, allText = line.text, at = 0; - if (!spans) { - for (var i$1 = 1; i$1 < styles.length; i$1 += 2) { builder.addToken(builder, allText.slice(at, at = styles[i$1]), interpretTokenStyle(styles[i$1 + 1], builder.cm.options)); } - return - } + var trim$5 = stringTrim.trim; - var len = allText.length, pos = 0, i = 1, text = "", style, css; - var nextChange = 0, spanStyle, spanEndStyle, spanStartStyle, collapsed, attributes; - for (; ;) { - if (nextChange == pos) { // Update current marker set - spanStyle = spanEndStyle = spanStartStyle = css = ""; - attributes = null; - collapsed = null; nextChange = Infinity; - var foundBookmarks = [], endStyles = (void 0); - for (var j = 0; j < spans.length; ++j) { - var sp = spans[j], m = sp.marker; - if (m.type == "bookmark" && sp.from == pos && m.widgetNode) { - foundBookmarks.push(m); - } else if (sp.from <= pos && (sp.to == null || sp.to > pos || m.collapsed && sp.to == pos && sp.from == pos)) { - if (sp.to != null && sp.to != pos && nextChange > sp.to) { - nextChange = sp.to; - spanEndStyle = ""; - } - if (m.className) { spanStyle += " " + m.className; } - if (m.css) { css = (css ? css + ";" : "") + m.css; } - if (m.startStyle && sp.from == pos) { spanStartStyle += " " + m.startStyle; } - if (m.endStyle && sp.to == nextChange) { (endStyles || (endStyles = [])).push(m.endStyle, sp.to); } - // support for the old title property - // https://github.com/codemirror/CodeMirror/pull/5673 - if (m.title) { (attributes || (attributes = {})).title = m.title; } - if (m.attributes) { - for (var attr in m.attributes) { (attributes || (attributes = {}))[attr] = m.attributes[attr]; } - } - if (m.collapsed && (!collapsed || compareCollapsedMarkers(collapsed.marker, m) < 0)) { collapsed = sp; } - } else if (sp.from > pos && nextChange > sp.from) { - nextChange = sp.from; - } - } - if (endStyles) { - for (var j$1 = 0; j$1 < endStyles.length; j$1 += 2) { if (endStyles[j$1 + 1] == nextChange) { spanEndStyle += " " + endStyles[j$1]; } } - } - if (!collapsed || collapsed.from == pos) { - for (var j$2 = 0; j$2 < foundBookmarks.length; ++j$2) { buildCollapsedSpan(builder, 0, foundBookmarks[j$2]); } - } - if (collapsed && (collapsed.from || 0) == pos) { - buildCollapsedSpan(builder, (collapsed.to == null ? len + 1 : collapsed.to) - pos, - collapsed.marker, collapsed.from == null); - if (collapsed.to == null) { return } - if (collapsed.to == pos) { collapsed = false; } - } - } - if (pos >= len) { break } - - var upto = Math.min(len, nextChange); - while (true) { - if (text) { - var end = pos + text.length; - if (!collapsed) { - var tokenText = end > upto ? text.slice(0, upto - pos) : text; - builder.addToken(builder, tokenText, style ? style + spanStyle : spanStyle, - spanStartStyle, pos + tokenText.length == nextChange ? spanEndStyle : "", css, attributes); - } - if (end >= upto) { text = text.slice(upto - pos); pos = upto; break } - pos = end; - spanStartStyle = ""; - } - text = allText.slice(at, at = styles[i++]); - style = interpretTokenStyle(styles[i++], builder.cm.options); - } - } - } + var charAt$3 = functionUncurryThis(''.charAt); + var n$ParseFloat = global_1.parseFloat; + var Symbol$4 = global_1.Symbol; + var ITERATOR$6 = Symbol$4 && Symbol$4.iterator; + var FORCED$5 = 1 / n$ParseFloat(whitespaces + '-0') !== -Infinity + // MS Edge 18- broken with boxed symbols + || (ITERATOR$6 && !fails(function () { n$ParseFloat(Object(ITERATOR$6)); })); + // `parseFloat` method + // https://tc39.es/ecma262/#sec-parsefloat-string + var numberParseFloat = FORCED$5 ? function parseFloat(string) { + var trimmedString = trim$5(toString_1(string)); + var result = n$ParseFloat(trimmedString); + return result === 0 && charAt$3(trimmedString, 0) == '-' ? -0 : result; + } : n$ParseFloat; - // These objects are used to represent the visible (currently drawn) - // part of the document. A LineView may correspond to multiple - // logical lines, if those are connected by collapsed ranges. - function LineView(doc, line, lineN) { - // The starting line - this.line = line; - // Continuing lines, if any - this.rest = visualLineContinued(line); - // Number of logical lines in this visual line - this.size = this.rest ? lineNo(lst(this.rest)) - lineN + 1 : 1; - this.node = this.text = null; - this.hidden = lineIsHidden(doc, line); - } + // `parseFloat` method + // https://tc39.es/ecma262/#sec-parsefloat-string + _export({ global: true, forced: parseFloat != numberParseFloat }, { + parseFloat: numberParseFloat + }); - // Create a range of LineView objects for the given lines. - function buildViewArray(cm, from, to) { - var array = [], nextPos; - for (var pos = from; pos < to; pos = nextPos) { - var view = new LineView(cm.doc, getLine(cm.doc, pos), pos); - nextPos = pos + view.size; - array.push(view); - } - return array - } + var _parseFloat = path.parseFloat; - var operationGroup = null; + var _parseFloat$1 = _parseFloat; - function pushOperation(op) { - if (operationGroup) { - operationGroup.ops.push(op); - } else { - op.ownsGroup = operationGroup = { - ops: [op], - delayedCallbacks: [] - }; - } - } + var _parseFloat$2 = _parseFloat$1; - function fireCallbacksForOps(group) { - // Calls delayed callbacks and cursorActivity handlers until no - // new ones appear - var callbacks = group.delayedCallbacks, i = 0; - do { - for (; i < callbacks.length; i++) { callbacks[i].call(null); } - for (var j = 0; j < group.ops.length; j++) { - var op = group.ops[j]; - if (op.cursorActivityHandlers) { - while (op.cursorActivityCalled < op.cursorActivityHandlers.length) { op.cursorActivityHandlers[op.cursorActivityCalled++].call(null, op.cm); } - } - } - } while (i < callbacks.length) - } + /** + * Copyright (C) 2021 THL A29 Limited, a Tencent company. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + function mergeMarginBottom(bottom, top) { + var currentBottom = _parseFloat$2(bottom); - function finishOperation(op, endCb) { - var group = op.ownsGroup; - if (!group) { return } + var nextTop = _parseFloat$2(top); - try { fireCallbacksForOps(group); } - finally { - operationGroup = null; - endCb(group); - } - } + if (nextTop >= 0) { + // 不受合并影响 + return currentBottom; + } - var orphanDelayedCallbacks = null; - - // Often, we want to signal events at a point where we are in the - // middle of some work, but don't want the handler to start calling - // other methods on the editor, which might be in an inconsistent - // state or simply not expect any other events to happen. - // signalLater looks whether there are any handlers, and schedules - // them to be executed when the last operation ends, or, if no - // operation is active, when a timeout fires. - function signalLater(emitter, type /*, values...*/) { - var arr = getHandlers(emitter, type); - if (!arr.length) { return } - var args = Array.prototype.slice.call(arguments, 2), list; - if (operationGroup) { - list = operationGroup.delayedCallbacks; - } else if (orphanDelayedCallbacks) { - list = orphanDelayedCallbacks; - } else { - list = orphanDelayedCallbacks = []; - setTimeout(fireOrphanDelayed, 0); - } - var loop = function (i) { - list.push(function () { return arr[i].apply(null, args); }); - }; + if (currentBottom >= 0) { + return currentBottom + nextTop; + } // 同时为负数,取最小的 - for (var i = 0; i < arr.length; ++i) - loop(i); - } - function fireOrphanDelayed() { - var delayed = orphanDelayedCallbacks; - orphanDelayedCallbacks = null; - for (var i = 0; i < delayed.length; ++i) { delayed[i](); } - } + return Math.min(currentBottom, nextTop); + } - // When an aspect of a line changes, a string is added to - // lineView.changes. This updates the relevant part of the line's - // DOM structure. - function updateLineForChanges(cm, lineView, lineN, dims) { - for (var j = 0; j < lineView.changes.length; j++) { - var type = lineView.changes[j]; - if (type == "text") { updateLineText(cm, lineView); } - else if (type == "gutter") { updateLineGutter(cm, lineView, lineN, dims); } - else if (type == "class") { updateLineClasses(cm, lineView); } - else if (type == "widget") { updateLineWidgets(cm, lineView, dims); } - } - lineView.changes = null; - } + function mergeMarginTop(bottom, top) { + var prevBottom = _parseFloat$2(bottom); - // Lines with gutter elements, widgets or a background class need to - // be wrapped, and have the extra elements added to the wrapper div - function ensureLineWrapped(lineView) { - if (lineView.node == lineView.text) { - lineView.node = elt("div", null, null, "position: relative"); - if (lineView.text.parentNode) { lineView.text.parentNode.replaceChild(lineView.node, lineView.text); } - lineView.node.appendChild(lineView.text); - if (ie && ie_version < 8) { lineView.node.style.zIndex = 2; } - } - return lineView.node - } + var currentTop = _parseFloat$2(top); - function updateLineBackground(cm, lineView) { - var cls = lineView.bgClass ? lineView.bgClass + " " + (lineView.line.bgClass || "") : lineView.line.bgClass; - if (cls) { cls += " CodeMirror-linebackground"; } - if (lineView.background) { - if (cls) { lineView.background.className = cls; } - else { lineView.background.parentNode.removeChild(lineView.background); lineView.background = null; } - } else if (cls) { - var wrap = ensureLineWrapped(lineView); - lineView.background = wrap.insertBefore(elt("div", null, cls), wrap.firstChild); - cm.display.input.setUneditable(lineView.background); - } - } + if (currentTop < 0) { + // 负数的margin都被上一个区块吸收了 + return 0; + } - // Wrapper around buildLineContent which will reuse the structure - // in display.externalMeasured when possible. - function getLineContent(cm, lineView) { - var ext = cm.display.externalMeasured; - if (ext && ext.line == lineView.line) { - cm.display.externalMeasured = null; - lineView.measure = ext.measure; - return ext.built - } - return buildLineContent(cm, lineView) - } + if (prevBottom >= 0) { + // 如果当前margin-top比上一个margin-bottom要大,则只合并部分;反之合并全部,归属于上一个区块 + return Math.max(currentTop - prevBottom, 0); + } // 上一个margin-bottom为负数不受影响 - // Redraw the line's text. Interacts with the background and text - // classes because the mode may output tokens that influence these - // classes. - function updateLineText(cm, lineView) { - var cls = lineView.text.className; - var built = getLineContent(cm, lineView); - if (lineView.text == lineView.node) { lineView.node = built.pre; } - lineView.text.parentNode.replaceChild(built.pre, lineView.text); - lineView.text = built.pre; - if (built.bgClass != lineView.bgClass || built.textClass != lineView.textClass) { - lineView.bgClass = built.bgClass; - lineView.textClass = built.textClass; - updateLineClasses(cm, lineView); - } else if (cls) { - lineView.text.className = cls; - } - } - function updateLineClasses(cm, lineView) { - updateLineBackground(cm, lineView); - if (lineView.line.wrapClass) { ensureLineWrapped(lineView).className = lineView.line.wrapClass; } - else if (lineView.node != lineView.text) { lineView.node.className = ""; } - var textClass = lineView.textClass ? lineView.textClass + " " + (lineView.line.textClass || "") : lineView.line.textClass; - lineView.text.className = textClass || ""; - } + return currentTop; + } + /** + * 用于解决块级元素边距合并问题 + * @param {HTMLElement} element + */ - function updateLineGutter(cm, lineView, lineN, dims) { - if (lineView.gutter) { - lineView.node.removeChild(lineView.gutter); - lineView.gutter = null; - } - if (lineView.gutterBackground) { - lineView.node.removeChild(lineView.gutterBackground); - lineView.gutterBackground = null; - } - if (lineView.line.gutterClass) { - var wrap = ensureLineWrapped(lineView); - lineView.gutterBackground = elt("div", null, "CodeMirror-gutter-background " + lineView.line.gutterClass, - ("left: " + (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px; width: " + (dims.gutterTotalWidth) + "px")); - cm.display.input.setUneditable(lineView.gutterBackground); - wrap.insertBefore(lineView.gutterBackground, lineView.text); - } - var markers = lineView.line.gutterMarkers; - if (cm.options.lineNumbers || markers) { - var wrap$1 = ensureLineWrapped(lineView); - var gutterWrap = lineView.gutter = elt("div", null, "CodeMirror-gutter-wrapper", ("left: " + (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px")); - cm.display.input.setUneditable(gutterWrap); - wrap$1.insertBefore(gutterWrap, lineView.text); - if (lineView.line.gutterClass) { gutterWrap.className += " " + lineView.line.gutterClass; } - if (cm.options.lineNumbers && (!markers || !markers["CodeMirror-linenumbers"])) { - lineView.lineNumber = gutterWrap.appendChild( - elt("div", lineNumberFor(cm.options, lineN), - "CodeMirror-linenumber CodeMirror-gutter-elt", - ("left: " + (dims.gutterLeft["CodeMirror-linenumbers"]) + "px; width: " + (cm.display.lineNumInnerWidth) + "px"))); - } - if (markers) { - for (var k = 0; k < cm.display.gutterSpecs.length; ++k) { - var id = cm.display.gutterSpecs[k].className, found = markers.hasOwnProperty(id) && markers[id]; - if (found) { - gutterWrap.appendChild(elt("div", [found], "CodeMirror-gutter-elt", - ("left: " + (dims.gutterLeft[id]) + "px; width: " + (dims.gutterWidth[id]) + "px"))); - } - } - } - } - } - function updateLineWidgets(cm, lineView, dims) { - if (lineView.alignable) { lineView.alignable = null; } - var isWidget = classTest("CodeMirror-linewidget"); - for (var node = lineView.node.firstChild, next = (void 0); node; node = next) { - next = node.nextSibling; - if (isWidget.test(node.className)) { lineView.node.removeChild(node); } - } - insertLineWidgets(cm, lineView, dims); - } + function getBlockTopAndHeightWithMargin(element) { + var prevSibling = element.previousElementSibling; + var nextSibling = element.nextElementSibling; + + if (!prevSibling) { + var _style = getComputedStyle(element); + + var _rect = element.getBoundingClientRect(); + + if (!nextSibling) { + return { + // marginBottom可能为负数 + height: Math.max(_parseFloat$2(_style.marginTop) + _rect.height + _parseFloat$2(_style.marginBottom), 0), + offsetTop: element.offsetTop - Math.abs(_parseFloat$2(_style.marginTop)) + }; + } + + var _nextSibStyle = getComputedStyle(nextSibling); + + var _marginBottom = mergeMarginBottom(_style.marginBottom, _nextSibStyle.marginTop); + + return { + height: Math.max(_parseFloat$2(_style.marginTop) + _rect.height + _marginBottom, 0), + // marginBottom可能为负数 + offsetTop: element.offsetTop - Math.abs(_parseFloat$2(_style.marginTop)) + }; + } + + var style = getComputedStyle(element); + var rect = element.getBoundingClientRect(); + var prevSibStyle = getComputedStyle(prevSibling); + var marginTop = mergeMarginTop(prevSibStyle.marginBottom, style.marginTop); + + if (!nextSibling) { + return { + height: Math.max(marginTop + rect.height + _parseFloat$2(style.marginBottom), 0), + // marginBottom可能为负数 + offsetTop: element.offsetTop - Math.abs(_parseFloat$2(style.marginTop)) + }; + } + + var nextSibStyle = getComputedStyle(nextSibling); + var marginBottom = mergeMarginBottom(style.marginBottom, nextSibStyle.marginTop); + return { + height: Math.max(marginTop + rect.height + marginBottom, 0), + // marginBottom可能为负数 + offsetTop: element.offsetTop - Math.abs(marginTop) + }; + } + /** + * document.elementsFromPoint polyfill + * ref: https://github.com/JSmith01/elementsfrompoint-polyfill/blob/master/index.js + * @param {number} x + * @param {number} y + */ - // Build a line's DOM representation from scratch - function buildLineElement(cm, lineView, lineN, dims) { - var built = getLineContent(cm, lineView); - lineView.text = lineView.node = built.pre; - if (built.bgClass) { lineView.bgClass = built.bgClass; } - if (built.textClass) { lineView.textClass = built.textClass; } - - updateLineClasses(cm, lineView); - updateLineGutter(cm, lineView, lineN, dims); - insertLineWidgets(cm, lineView, dims); - return lineView.node - } + function elementsFromPoint(x, y) { + // see https://caniuse.com/#search=elementsFromPoint + if (typeof document.elementsFromPoint === 'function') { + return document.elementsFromPoint(x, y); + } + + if (typeof + /** @type {any}*/ + document.msElementsFromPoint === 'function') { + var nodeList = + /** @type {any}*/ + document.msElementsFromPoint(x, y); + return nodeList !== null ? from_1$2(nodeList) : nodeList; + } + + var elements = []; + var pointerEvents = []; + /** @type {HTMLElement} */ + + var ele; + + do { + var currentElement = + /** @type {HTMLElement} */ + document.elementFromPoint(x, y); + + if (ele !== currentElement) { + ele = currentElement; + elements.push(ele); + pointerEvents.push(ele.style.pointerEvents); + ele.style.pointerEvents = 'none'; + } else { + ele = null; + } + } while (ele); + + forEach$3(elements).call(elements, function (e, index) { + e.style.pointerEvents = pointerEvents[index]; + }); + + return elements; + } + function getHTML(who, deep) { + if (!who || !who.tagName) { + return ''; + } - // A lineView may contain multiple logical lines (when merged by - // collapsed spans). The widgets for all of them need to be drawn. - function insertLineWidgets(cm, lineView, dims) { - insertLineWidgetsFor(cm, lineView.line, lineView, dims, true); - if (lineView.rest) { - for (var i = 0; i < lineView.rest.length; i++) { insertLineWidgetsFor(cm, lineView.rest[i], lineView, dims, false); } - } - } + var txt; + var ax; + var el = document.createElement('div'); + el.appendChild(who.cloneNode(false)); + txt = el.innerHTML; - function insertLineWidgetsFor(cm, line, lineView, dims, allowAbove) { - if (!line.widgets) { return } - var wrap = ensureLineWrapped(lineView); - for (var i = 0, ws = line.widgets; i < ws.length; ++i) { - var widget = ws[i], node = elt("div", [widget.node], "CodeMirror-linewidget" + (widget.className ? " " + widget.className : "")); - if (!widget.handleMouseEvents) { node.setAttribute("cm-ignore-events", "true"); } - positionLineWidget(widget, node, lineView, dims); - cm.display.input.setUneditable(node); - if (allowAbove && widget.above) { wrap.insertBefore(node, lineView.gutter || lineView.text); } - else { wrap.appendChild(node); } - signalLater(widget, "redraw"); - } - } + if (deep) { + ax = indexOf$8(txt).call(txt, '>') + 1; + txt = txt.substring(0, ax) + who.innerHTML + txt.substring(ax); + } - function positionLineWidget(widget, node, lineView, dims) { - if (widget.noHScroll) { - (lineView.alignable || (lineView.alignable = [])).push(node); - var width = dims.wrapperWidth; - node.style.left = dims.fixedPos + "px"; - if (!widget.coverGutter) { - width -= dims.gutterTotalWidth; - node.style.paddingLeft = dims.gutterTotalWidth + "px"; - } - node.style.width = width + "px"; - } - if (widget.coverGutter) { - node.style.zIndex = 5; - node.style.position = "relative"; - if (!widget.noHScroll) { node.style.marginLeft = -dims.gutterTotalWidth + "px"; } - } - } + el = null; + return txt; + } + /** + * @template {keyof HTMLElementTagNameMap} K + * @param {K} tagName 标签名 + * @param {string} className 元素类名 + * @param {Record} attributes 附加属性 + * @returns {HTMLElementTagNameMap[K]} + */ - function widgetHeight(widget) { - if (widget.height != null) { return widget.height } - var cm = widget.doc.cm; - if (!cm) { return 0 } - if (!contains(document.body, widget.node)) { - var parentStyle = "position: relative;"; - if (widget.coverGutter) { parentStyle += "margin-left: -" + cm.display.gutters.offsetWidth + "px;"; } - if (widget.noHScroll) { parentStyle += "width: " + cm.display.wrapper.clientWidth + "px;"; } - removeChildrenAndAdd(cm.display.measure, elt("div", [widget.node], null, parentStyle)); - } - return widget.height = widget.node.parentNode.offsetHeight - } + function createElement(tagName) { + var className = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; + var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + var element = document.createElement(tagName); + element.className = className; - // Return true when the given mouse event happened in a widget - function eventInWidget(display, e) { - for (var n = e_target(e); n != display.wrapper; n = n.parentNode) { - if (!n || (n.nodeType == 1 && n.getAttribute("cm-ignore-events") == "true") || - (n.parentNode == display.sizer && n != display.mover)) { return true } - } - } + if (typeof attributes !== 'undefined') { + var _context; - // POSITION MEASUREMENT - - function paddingTop(display) { return display.lineSpace.offsetTop } - function paddingVert(display) { return display.mover.offsetHeight - display.lineSpace.offsetHeight } - function paddingH(display) { - if (display.cachedPaddingH) { return display.cachedPaddingH } - var e = removeChildrenAndAdd(display.measure, elt("pre", "x", "CodeMirror-line-like")); - var style = window.getComputedStyle ? window.getComputedStyle(e) : e.currentStyle; - var data = { left: parseInt(style.paddingLeft), right: parseInt(style.paddingRight) }; - if (!isNaN(data.left) && !isNaN(data.right)) { display.cachedPaddingH = data; } - return data - } + forEach$3(_context = keys$3(attributes)).call(_context, function (key) { + var value = attributes[key]; - function scrollGap(cm) { return scrollerGap - cm.display.nativeBarWidth } - function displayWidth(cm) { - return cm.display.scroller.clientWidth - scrollGap(cm) - cm.display.barWidth - } - function displayHeight(cm) { - return cm.display.scroller.clientHeight - scrollGap(cm) - cm.display.barHeight - } + if (startsWith$3(key).call(key, 'data-')) { + var dataName = key.replace(/^data-/, ''); + element.dataset[dataName] = value; + return; + } - // Ensure the lineView.wrapping.heights array is populated. This is - // an array of bottom offsets for the lines that make up a drawn - // line. When lineWrapping is on, there might be more than one - // height. - function ensureLineHeights(cm, lineView, rect) { - var wrapping = cm.options.lineWrapping; - var curWidth = wrapping && displayWidth(cm); - if (!lineView.measure.heights || wrapping && lineView.measure.width != curWidth) { - var heights = lineView.measure.heights = []; - if (wrapping) { - lineView.measure.width = curWidth; - var rects = lineView.text.firstChild.getClientRects(); - for (var i = 0; i < rects.length - 1; i++) { - var cur = rects[i], next = rects[i + 1]; - if (Math.abs(cur.bottom - next.bottom) > 2) { heights.push((cur.bottom + next.top) / 2 - rect.top); } - } - } - heights.push(rect.bottom - rect.top); - } - } + element.setAttribute(key, value); + }); + } - // Find a line map (mapping character offsets to text nodes) and a - // measurement cache for the given line number. (A line view might - // contain multiple lines when collapsed ranges are present.) - function mapFromLineView(lineView, line, lineN) { - if (lineView.line == line) { return { map: lineView.measure.map, cache: lineView.measure.cache } } - for (var i = 0; i < lineView.rest.length; i++) { - if (lineView.rest[i] == line) { return { map: lineView.measure.maps[i], cache: lineView.measure.caches[i] } } - } - for (var i$1 = 0; i$1 < lineView.rest.length; i$1++) { - if (lineNo(lineView.rest[i$1]) > lineN) { return { map: lineView.measure.maps[i$1], cache: lineView.measure.caches[i$1], before: true } } - } - } + return element; + } - // Render a line into the hidden node display.externalMeasured. Used - // when measurement is needed for a line that's not in the viewport. - function updateExternalMeasurement(cm, line) { - line = visualLine(line); - var lineN = lineNo(line); - var view = cm.display.externalMeasured = new LineView(cm.doc, line, lineN); - view.lineN = lineN; - var built = view.built = buildLineContent(cm, view); - view.text = built.pre; - removeChildrenAndAdd(cm.display.lineMeasure, built.pre); - return view - } + var SAFE_AREA_MARGIN = 15; + /** + * Cherry实现了将粘贴的html内容转成对应的markdown源码的功能 + * 本工具主要实现将粘贴html转成的markdown源码在编辑器中选中,并给出切换按钮 + * 可以切换为纯文本内容,或者markdown内容 + */ - // Get a {top, bottom, left, right} box (in line-local coordinates) - // for a given character. - function measureChar(cm, line, ch, bias) { - return measureCharPrepared(cm, prepareMeasureForLine(cm, line), ch, bias) - } + var pasteHelper = { + /** + * 核心方法,粘贴后展示切换按钮 + * 只有粘贴html时才会出现切换按钮 + * @param {Object} currentCursor 当前的光标位置 + * @param {Object} editor 编辑器对象 + * @param {string} html html里的纯文本内容 + * @param {string} md html对应的markdown源码 + * @returns + */ + showSwitchBtnAfterPasteHtml: function showSwitchBtnAfterPasteHtml($cherry, currentCursor, editor, html, md) { + if (trim$3(html).call(html) === trim$3(md).call(md)) { + return; + } + + this.init($cherry, currentCursor, editor, html, md); + this.setSelection(); + this.bindListener(); + this.initBubble(); + this.showBubble(); // 默认粘贴成markdown格式,如果用户上次选择粘贴为纯文本,则需要切换为text + + if (this.getTypeFromLocalStorage() === 'text') { + this.switchTextClick(); + } + }, + init: function init($cherry, currentCursor, editor, html, md) { + this.$cherry = $cherry; + this.html = html; + this.md = md; + this.codemirror = editor; + this.currentCursor = currentCursor; + this.locale = $cherry.locale; + }, + + /** + * 获取缓存中的复制粘贴类型 + */ + getTypeFromLocalStorage: function getTypeFromLocalStorage() { + if (typeof localStorage === 'undefined') { + return 'md'; + } + + return localStorage.getItem('cherry-paste-type') || 'md'; + }, + + /** + * 记忆最近一次用户选择的粘贴类型 + */ + setTypeToLocalStorage: function setTypeToLocalStorage(type) { + if (typeof localStorage === 'undefined') { + return; + } + + localStorage.setItem('cherry-paste-type', type); + }, + + /** + * 在编辑器中自动选中刚刚粘贴的内容 + */ + setSelection: function setSelection() { + var _this$codemirror$getC = this.codemirror.getCursor(), + end = _extends({}, _this$codemirror$getC); + + var begin = this.currentCursor; + this.codemirror.setSelection(begin, end); + }, + + /** + * 绑定事件 + * 当编辑器选中区域改变、内容改变时,隐藏切换按钮 + * 当编辑器滚动时,实时更新切换按钮的位置 + * @returns null + */ + bindListener: function bindListener() { + var _this = this; + + if (!this.hasBindListener) { + this.hasBindListener = true; + } else { + return true; + } + + this.codemirror.on('beforeSelectionChange', function (codemirror, info) { + _this.hideBubble(); + }); + this.codemirror.on('beforeChange', function (codemirror, info) { + _this.hideBubble(); + }); + this.codemirror.on('scroll', function (codemirror) { + _this.updatePositionWhenScroll(); + }); + }, + isHidden: function isHidden() { + return this.bubbleDom.style.display === 'none'; + }, + toggleBubbleDisplay: function toggleBubbleDisplay() { + if (this.isHidden()) { + this.bubbleDom.style.display = ''; + return; + } + + this.bubbleDom.style.display = 'none'; + return; + }, + hideBubble: function hideBubble() { + if (this.noHide) { + return true; + } + + if (this.isHidden()) { + return; + } + + this.toggleBubbleDisplay(); + }, + updatePositionWhenScroll: function updatePositionWhenScroll() { + if (this.isHidden()) { + return; + } // FIXME: update position when stick to the bottom + // const isStickToBottom = !this.bubbleDom.style.top; + + + var offset = this.bubbleDom.dataset.scrollTop - this.getScrollTop(); + this.bubbleDom.style.marginTop = "".concat(offset, "px"); + }, + getScrollTop: function getScrollTop() { + return this.codemirror.getScrollInfo().top; + }, + showBubble: function showBubble() { + var _this$getLastSelected = this.getLastSelectedPosition(), + top = _this$getLastSelected.top; + + if (this.isHidden()) { + this.toggleBubbleDisplay(); + this.bubbleDom.style.marginTop = '0'; + this.bubbleDom.dataset.scrollTop = this.getScrollTop(); + } + /** + * @type {HTMLDivElement} + */ + + + var codemirrorWrapper = this.codemirror.getWrapperElement(); + var maxTop = codemirrorWrapper.clientHeight - this.bubbleDom.getBoundingClientRect().height - SAFE_AREA_MARGIN; + + if (top > maxTop) { + this.bubbleDom.style.top = ''; + this.bubbleDom.style.bottom = "".concat(SAFE_AREA_MARGIN, "px"); + } else { + this.bubbleDom.style.top = "".concat(top, "px"); + this.bubbleDom.style.bottom = ''; + } + }, + initBubble: function initBubble() { + var _context, _context2; + + if (this.bubbleDom) { + this.bubbleDom.setAttribute('data-type', 'md'); + return true; + } + + var dom = createElement('div', 'cherry-bubble cherry-bubble--centered cherry-switch-paste'); + dom.style.display = 'none'; + var switchText = createElement('span', 'cherry-toolbar-button cherry-text-btn', { + title: this.locale.pastePlain + }); + switchText.innerText = 'TEXT'; + var switchMd = createElement('span', 'cherry-toolbar-button cherry-md-btn', { + title: this.locale.pasteMarkdown + }); + switchMd.innerText = 'Markdown'; + var switchBG = createElement('span', 'switch-btn--bg'); + this.bubbleDom = dom; + this.switchText = switchText; + this.switchMd = switchMd; + this.switchBG = switchBG; + this.bubbleDom.appendChild(switchText); + this.bubbleDom.appendChild(switchMd); + this.bubbleDom.appendChild(switchBG); + this.bubbleDom.setAttribute('data-type', 'md'); + this.codemirror.getWrapperElement().appendChild(this.bubbleDom); + this.switchMd.addEventListener('click', bind$5(_context = this.switchMDClick).call(_context, this)); + this.switchText.addEventListener('click', bind$5(_context2 = this.switchTextClick).call(_context2, this)); + }, + switchMDClick: function switchMDClick(event) { + this.setTypeToLocalStorage('md'); + + if (this.bubbleDom.getAttribute('data-type') === 'md') { + return; + } + + this.noHide = true; + this.bubbleDom.setAttribute('data-type', 'md'); + this.codemirror.doc.replaceSelection(this.md); + this.setSelection(); + this.showBubble(); + this.noHide = false; + }, + switchTextClick: function switchTextClick(event) { + this.setTypeToLocalStorage('text'); + + if (this.bubbleDom.getAttribute('data-type') === 'text') { + return; + } + + this.noHide = true; + this.bubbleDom.setAttribute('data-type', 'text'); + this.codemirror.doc.replaceSelection(this.html); + this.setSelection(); + this.showBubble(); + this.noHide = false; + }, + getLastSelectedPosition: function getLastSelectedPosition() { + var selectedObjs = from_1$2(this.codemirror.getWrapperElement().getElementsByClassName('CodeMirror-selected')); + + var width = 0; + var top = 0; + + if (selectedObjs.length <= 0) { + this.hideBubble(); + return {}; + } // FIXME: remove redundant width calculation + + + for (var key = 0; key < selectedObjs.length; key++) { + var item = selectedObjs[key]; + var position = item.getBoundingClientRect(); + var tmpWidth = position.left + position.width / 2; + var tmpTop = position.top + position.height; + + if (tmpTop > top && tmpWidth >= width) { + top = tmpTop; + } + + if (tmpWidth > width) { + width = tmpWidth; + } + } + + return { + top: top + }; + } + }; - // Find a line view that corresponds to the given line number. - function findViewForLine(cm, lineN) { - if (lineN >= cm.display.viewFrom && lineN < cm.display.viewTo) { return cm.display.view[findViewIndex(cm, lineN)] } - var ext = cm.display.externalMeasured; - if (ext && lineN >= ext.lineN && lineN < ext.lineN + ext.size) { return ext } - } + /** + * Copyright (C) 2021 THL A29 Limited, a Tencent company. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + function addEvent(elm, evType, fn, useCapture) { + if (elm.addEventListener) { + elm.addEventListener(evType, fn, useCapture); // DOM2.0 - // Measurement can be split in two steps, the set-up work that - // applies to the whole line, and the measurement of the actual - // character. Functions like coordsChar, that need to do a lot of - // measurements in a row, can thus ensure that the set-up work is - // only done once. - function prepareMeasureForLine(cm, line) { - var lineN = lineNo(line); - var view = findViewForLine(cm, lineN); - if (view && !view.text) { - view = null; - } else if (view && view.changes) { - updateLineForChanges(cm, view, lineN, getDimensions(cm)); - cm.curOp.forceUpdate = true; - } - if (!view) { view = updateExternalMeasurement(cm, line); } + return true; + } - var info = mapFromLineView(view, line, lineN); - return { - line: line, view: view, rect: null, - map: info.map, cache: info.cache, before: info.before, - hasHeights: false - } - } - - // Given a prepared measurement object, measures the position of an - // actual character (or fetches it from the cache). - function measureCharPrepared(cm, prepared, ch, bias, varHeight) { - if (prepared.before) { ch = -1; } - var key = ch + (bias || ""), found; - if (prepared.cache.hasOwnProperty(key)) { - found = prepared.cache[key]; - } else { - if (!prepared.rect) { prepared.rect = prepared.view.text.getBoundingClientRect(); } - if (!prepared.hasHeights) { - ensureLineHeights(cm, prepared.view, prepared.rect); - prepared.hasHeights = true; - } - found = measureCharInner(cm, prepared, ch, bias); - if (!found.bogus) { prepared.cache[key] = found; } - } - return { - left: found.left, right: found.right, - top: varHeight ? found.rtop : found.top, - bottom: varHeight ? found.rbottom : found.bottom - } - } + if (elm.attachEvent) { + var r = elm.attachEvent("on".concat(evType), fn); // IE5+ - var nullRect = { left: 0, right: 0, top: 0, bottom: 0 }; - - function nodeAndOffsetInLineMap(map, ch, bias) { - var node, start, end, collapse, mStart, mEnd; - // First, search the line map for the text node corresponding to, - // or closest to, the target character. - for (var i = 0; i < map.length; i += 3) { - mStart = map[i]; - mEnd = map[i + 1]; - if (ch < mStart) { - start = 0; end = 1; - collapse = "left"; - } else if (ch < mEnd) { - start = ch - mStart; - end = start + 1; - } else if (i == map.length - 3 || ch == mEnd && map[i + 3] > ch) { - end = mEnd - mStart; - start = end - 1; - if (ch >= mEnd) { collapse = "right"; } - } - if (start != null) { - node = map[i + 2]; - if (mStart == mEnd && bias == (node.insertLeft ? "left" : "right")) { collapse = bias; } - if (bias == "left" && start == 0) { - while (i && map[i - 2] == map[i - 3] && map[i - 1].insertLeft) { - node = map[(i -= 3) + 2]; - collapse = "left"; - } - } - if (bias == "right" && start == mEnd - mStart) { - while (i < map.length - 3 && map[i + 3] == map[i + 4] && !map[i + 5].insertLeft) { - node = map[(i += 3) + 2]; - collapse = "right"; - } - } - break - } - } - return { node: node, start: start, end: end, collapse: collapse, coverStart: mStart, coverEnd: mEnd } - } + return r; + } - function getUsefulRect(rects, bias) { - var rect = nullRect; - if (bias == "left") { - for (var i = 0; i < rects.length; i++) { - if ((rect = rects[i]).left != rect.right) { break } - } - } else { - for (var i$1 = rects.length - 1; i$1 >= 0; i$1--) { - if ((rect = rects[i$1]).left != rect.right) { break } - } - } - return rect - } + elm["on".concat(evType)] = fn; // DOM 0 + } + function removeEvent(elm, evType, fn, useCapture) { + if (elm.removeEventListener) { + elm.removeEventListener(evType, fn, useCapture); // DOM2.0 + } else if (elm.detachEvent) { + var r = elm.detachEvent("on".concat(evType), fn); // IE5+ - function measureCharInner(cm, prepared, ch, bias) { - var place = nodeAndOffsetInLineMap(prepared.map, ch, bias); - var node = place.node, start = place.start, end = place.end, collapse = place.collapse; - - var rect; - if (node.nodeType == 3) { // If it is a text node, use a range to retrieve the coordinates. - for (var i$1 = 0; i$1 < 4; i$1++) { // Retry a maximum of 4 times when nonsense rectangles are returned - while (start && isExtendingChar(prepared.line.text.charAt(place.coverStart + start))) { --start; } - while (place.coverStart + end < place.coverEnd && isExtendingChar(prepared.line.text.charAt(place.coverStart + end))) { ++end; } - if (ie && ie_version < 9 && start == 0 && end == place.coverEnd - place.coverStart) { rect = node.parentNode.getBoundingClientRect(); } - else { rect = getUsefulRect(range(node, start, end).getClientRects(), bias); } - if (rect.left || rect.right || start == 0) { break } - end = start; - start = start - 1; - collapse = "right"; - } - if (ie && ie_version < 11) { rect = maybeUpdateRectForZooming(cm.display.measure, rect); } - } else { // If it is a widget, simply get the box for the whole widget. - if (start > 0) { collapse = bias = "right"; } - var rects; - if (cm.options.lineWrapping && (rects = node.getClientRects()).length > 1) { rect = rects[bias == "right" ? rects.length - 1 : 0]; } - else { rect = node.getBoundingClientRect(); } - } - if (ie && ie_version < 9 && !start && (!rect || !rect.left && !rect.right)) { - var rSpan = node.parentNode.getClientRects()[0]; - if (rSpan) { rect = { left: rSpan.left, right: rSpan.left + charWidth(cm.display), top: rSpan.top, bottom: rSpan.bottom }; } - else { rect = nullRect; } - } + return r; + } else { + elm["on".concat(evType)] = null; // DOM 0 + } + } - var rtop = rect.top - prepared.rect.top, rbot = rect.bottom - prepared.rect.top; - var mid = (rtop + rbot) / 2; - var heights = prepared.view.measure.heights; - var i = 0; - for (; i < heights.length - 1; i++) { if (mid < heights[i]) { break } } - var top = i ? heights[i - 1] : 0, bot = heights[i]; - var result = { - left: (collapse == "right" ? rect.right : rect.left) - prepared.rect.left, - right: (collapse == "left" ? rect.left : rect.right) - prepared.rect.left, - top: top, bottom: bot - }; - if (!rect.left && !rect.right) { result.bogus = true; } - if (!cm.options.singleCursorHeightPerLine) { result.rtop = rtop; result.rbottom = rbot; } + /** + * Copyright (C) 2021 THL A29 Limited, a Tencent company. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + // @ts-check - return result - } + /** @type {Partial} */ + var Logger = new Proxy({}, { + get: function get(target, prop, receiver) { + // @ts-ignore + if ( typeof console !== 'undefined' && prop in console) { + return console[prop]; + } + + return function () {}; + } + }); - // Work around problem with bounding client rects on ranges being - // returned incorrectly when zoomed on IE10 and below. - function maybeUpdateRectForZooming(measure, rect) { - if (!window.screen || screen.logicalXDPI == null || - screen.logicalXDPI == screen.deviceXDPI || !hasBadZoomedRects(measure)) { return rect } - var scaleX = screen.logicalXDPI / screen.deviceXDPI; - var scaleY = screen.logicalYDPI / screen.deviceYDPI; - return { - left: rect.left * scaleX, right: rect.right * scaleX, - top: rect.top * scaleY, bottom: rect.bottom * scaleY - } - } + function mitt(n){return {all:n=n||new Map,on:function(t,e){var i=n.get(t);i?i.push(e):n.set(t,[e]);},off:function(t,e){var i=n.get(t);i&&(e?i.splice(i.indexOf(e)>>>0,1):n.set(t,[]));},emit:function(t,e){var i=n.get(t);i&&i.slice().map(function(n){n(e);}),(i=n.get("*"))&&i.slice().map(function(n){n(t,e);});}}} - function clearLineMeasurementCacheFor(lineView) { - if (lineView.measure) { - lineView.measure.cache = {}; - lineView.measure.heights = null; - if (lineView.rest) { - for (var i = 0; i < lineView.rest.length; i++) { lineView.measure.caches[i] = {}; } - } - } - } + /** + * 事件管理 + */ - function clearLineMeasurementCache(cm) { - cm.display.externalMeasure = null; - removeChildren(cm.display.lineMeasure); - for (var i = 0; i < cm.display.view.length; i++) { clearLineMeasurementCacheFor(cm.display.view[i]); } - } + var Event$1 = new ( /*#__PURE__*/function () { + function Event() { + _classCallCheck(this, Event); + + _defineProperty(this, "Events", { + previewerClose: 'previewer:close', + previewerOpen: 'previewer:open', + editorClose: 'editor:close', + editorOpen: 'editor:open', + toolbarHide: 'toolbar:hide', + toolbarShow: 'toolbar:show', + cleanAllSubMenus: 'cleanAllSubMenus' // 清除所有子菜单弹窗 + + }); + + _defineProperty(this, "emitter", mitt()); + } + + _createClass(Event, [{ + key: "on", + value: + /** + * 注册监听事件 + * @param {string} instanceId 接收消息的频道 + * @param {string} event 要注册监听的事件 + * @param {(event: any) => void} handler 事件回调 + */ + function on(instanceId, event, handler) { + var _context; + + this.emitter.on(concat$5(_context = "".concat(instanceId, ":")).call(_context, event), handler); + } + /** + * 触发事件 + * @param {string} instanceId 发送消息的频道 + * @param {string} event 要触发的事件 + */ + + }, { + key: "emit", + value: function emit(instanceId, event) { + var _context2; + + this.emitter.emit(concat$5(_context2 = "".concat(instanceId, ":")).call(_context2, event)); + } + }]); + + return Event; + }())(); - function clearCaches(cm) { - clearLineMeasurementCache(cm); - cm.display.cachedCharWidth = cm.display.cachedTextHeight = cm.display.cachedPaddingH = null; - if (!cm.options.lineWrapping) { cm.display.maxLineChanged = true; } - cm.display.lineNumChars = null; - } + /** + * Copyright (C) 2021 THL A29 Limited, a Tencent company. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ - function pageScrollX() { - // Work around https://bugs.chromium.org/p/chromium/issues/detail?id=489206 - // which causes page_Offset and bounding client rects to use - // different reference viewports and invalidate our calculations. - if (chrome && android) { return -(document.body.getBoundingClientRect().left - parseInt(getComputedStyle(document.body).marginLeft)) } - return window.pageXOffset || (document.documentElement || document.body).scrollLeft - } - function pageScrollY() { - if (chrome && android) { return -(document.body.getBoundingClientRect().top - parseInt(getComputedStyle(document.body).marginTop)) } - return window.pageYOffset || (document.documentElement || document.body).scrollTop - } + /** + * 上传文件的逻辑,如果有callback,则不再走默认的替换文本的逻辑,而是调用callback + * @param {string} type 上传文件的类型 + */ + function handleUpload(editor) { + var type = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'image'; + var accept = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '*'; + var callback = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null; + // type为上传文件类型 image|video|audio|pdf|word + var input = document.createElement('input'); + input.type = 'file'; + input.id = 'fileUpload'; + input.value = ''; + input.style.display = 'none'; + input.accept = accept; // document.body.appendChild(input); + + input.addEventListener('change', function (event) { + // @ts-ignore + var _event$target$files = _slicedToArray(event.target.files, 1), + file = _event$target$files[0]; // 文件上传后的回调函数可以由调用方自己实现 + + + editor.options.fileUpload(file, function (url) { + var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + // 文件上传的默认回调行数,调用方可以完全不使用该函数 + if (typeof url !== 'string' || !url) { + return; + } + + if (callback) { + return callback(file.name, url, params); + } + + var code = ''; + + if (type === 'image') { + var _context; + + // 如果是图片,则返回固定的图片markdown源码 + code = concat$5(_context = "![".concat(file.name, "](")).call(_context, url, ")"); + } else if (type === 'video') { + var _context2; + + // 如果是视频,则返回固定的视频markdown源码 + code = concat$5(_context2 = "!video[".concat(file.name, "](")).call(_context2, url, ")"); + } else if (type === 'audio') { + var _context3; + + // 如果是音频,则返回固定的音频markdown源码 + code = concat$5(_context3 = "!audio[".concat(file.name, "](")).call(_context3, url, ")"); + } else { + var _context4; + + // 默认返回超链接 + code = concat$5(_context4 = "[".concat(file.name, "](")).call(_context4, url, ")"); + } // 替换选中区域 + // @ts-ignore + + + editor.editor.doc.replaceSelection(code); + }); + }); + input.click(); + } + /** + * 解析params参数 + * @param params?.isBorder 是否有边框样式(图片场景下生效) + * @param params?.isShadow 是否有阴影样式(图片场景下生效) + * @param params?.isRadius 是否有圆角样式(图片场景下生效) + * @param params?.width 设置宽度,可以是像素、也可以是百分比(图片、视频场景下生效) + * @param params?.height 设置高度,可以是像素、也可以是百分比(图片、视频场景下生效) + */ - function widgetTopHeight(lineObj) { - var height = 0; - if (lineObj.widgets) { - for (var i = 0; i < lineObj.widgets.length; ++i) { - if (lineObj.widgets[i].above) { height += widgetHeight(lineObj.widgets[i]); } - } - } - return height - } + function handelParams(params) { + var ret = []; - // Converts a {top, bottom, left, right} box from line-local - // coordinates into another coordinate system. Context may be one of - // "line", "div" (display.lineDiv), "local"./null (editor), "window", - // or "page". - function intoCoordSystem(cm, lineObj, rect, context, includeWidgets) { - if (!includeWidgets) { - var height = widgetTopHeight(lineObj); - rect.top += height; rect.bottom += height; - } - if (context == "line") { return rect } - if (!context) { context = "local"; } - var yOff = heightAtLine(lineObj); - if (context == "local") { yOff += paddingTop(cm.display); } - else { yOff -= cm.display.viewOffset; } - if (context == "page" || context == "window") { - var lOff = cm.display.lineSpace.getBoundingClientRect(); - yOff += lOff.top + (context == "window" ? 0 : pageScrollY()); - var xOff = lOff.left + (context == "window" ? 0 : pageScrollX()); - rect.left += xOff; rect.right += xOff; - } - rect.top += yOff; rect.bottom += yOff; - return rect - } + if (params.isBorder) { + ret.push('#B'); + } - // Coverts a box from "div" coords to another coordinate system. - // Context may be "window", "page", "div", or "local"./null. - function fromCoordSystem(cm, coords, context) { - if (context == "div") { return coords } - var left = coords.left, top = coords.top; - // First move into "page" coordinate system - if (context == "page") { - left -= pageScrollX(); - top -= pageScrollY(); - } else if (context == "local" || !context) { - var localBox = cm.display.sizer.getBoundingClientRect(); - left += localBox.left; - top += localBox.top; - } + if (params.isShadow) { + ret.push('#S'); + } - var lineSpaceBox = cm.display.lineSpace.getBoundingClientRect(); - return { left: left - lineSpaceBox.left, top: top - lineSpaceBox.top } - } + if (params.isRadius) { + ret.push('#R'); + } - function charCoords(cm, pos, context, lineObj, bias) { - if (!lineObj) { lineObj = getLine(cm.doc, pos.line); } - return intoCoordSystem(cm, lineObj, measureChar(cm, lineObj, pos.ch, bias), context) - } + if (params.width) { + ret.push("#".concat(params.width)); + } - // Returns a box for a given cursor position, which may have an - // 'other' property containing the position of the secondary cursor - // on a bidi boundary. - // A cursor Pos(line, char, "before") is on the same visual line as `char - 1` - // and after `char - 1` in writing order of `char - 1` - // A cursor Pos(line, char, "after") is on the same visual line as `char` - // and before `char` in writing order of `char` - // Examples (upper-case letters are RTL, lower-case are LTR): - // Pos(0, 1, ...) - // before after - // ab a|b a|b - // aB a|B aB| - // Ab |Ab A|b - // AB B|A B|A - // Every position after the last character on a line is considered to stick - // to the last character on the line. - function cursorCoords(cm, pos, context, lineObj, preparedMeasure, varHeight) { - lineObj = lineObj || getLine(cm.doc, pos.line); - if (!preparedMeasure) { preparedMeasure = prepareMeasureForLine(cm, lineObj); } - function get(ch, right) { - var m = measureCharPrepared(cm, preparedMeasure, ch, right ? "right" : "left", varHeight); - if (right) { m.left = m.right; } else { m.right = m.left; } - return intoCoordSystem(cm, lineObj, m, context) - } - var order = getOrder(lineObj, cm.doc.direction), ch = pos.ch, sticky = pos.sticky; - if (ch >= lineObj.text.length) { - ch = lineObj.text.length; - sticky = "before"; - } else if (ch <= 0) { - ch = 0; - sticky = "after"; - } - if (!order) { return get(sticky == "before" ? ch - 1 : ch, sticky == "before") } + if (params.height) { + if (!params.width) { + ret.push('#auto'); + } - function getBidi(ch, partPos, invert) { - var part = order[partPos], right = part.level == 1; - return get(invert ? ch - 1 : ch, right != invert) - } - var partPos = getBidiPartAt(order, ch, sticky); - var other = bidiOther; - var val = getBidi(ch, partPos, sticky == "before"); - if (other != null) { val.other = getBidi(ch, other, sticky != "before"); } - return val - } + ret.push("#".concat(params.height)); + } - // Used to cheaply estimate the coordinates for a position. Used for - // intermediate scroll updates. - function estimateCoords(cm, pos) { - var left = 0; - pos = clipPos(cm.doc, pos); - if (!cm.options.lineWrapping) { left = charWidth(cm.display) * pos.ch; } - var lineObj = getLine(cm.doc, pos.line); - var top = heightAtLine(lineObj) + paddingTop(cm.display); - return { left: left, right: left, top: top, bottom: top + lineObj.height } - } + return ret.join(' '); + } - // Positions returned by coordsChar contain some extra information. - // xRel is the relative x position of the input coordinates compared - // to the found position (so xRel > 0 means the coordinates are to - // the right of the character position, for example). When outside - // is true, that means the coordinates lie outside the line's - // vertical range. - function PosWithInfo(line, ch, sticky, outside, xRel) { - var pos = Pos(line, ch, sticky); - pos.xRel = xRel; - if (outside) { pos.outside = outside; } - return pos - } + /** + * Copyright (C) 2021 THL A29 Limited, a Tencent company. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + function compileRegExp(obj, flags, allowExtendedFlags) { + var source = obj.begin + obj.content + obj.end; - // Compute the character position closest to the given coordinates. - // Input must be lineSpace-local ("div" coordinate system). - function coordsChar(cm, x, y) { - var doc = cm.doc; - y += cm.display.viewOffset; - if (y < 0) { return PosWithInfo(doc.first, 0, null, -1, -1) } - var lineN = lineAtHeight(doc, y), last = doc.first + doc.size - 1; - if (lineN > last) { return PosWithInfo(doc.first + doc.size - 1, getLine(doc, last).text.length, null, 1, 1) } - if (x < 0) { x = 0; } - - var lineObj = getLine(doc, lineN); - for (; ;) { - var found = coordsCharInner(cm, lineObj, lineN, x, y); - var collapsed = collapsedSpanAround(lineObj, found.ch + (found.xRel > 0 || found.outside > 0 ? 1 : 0)); - if (!collapsed) { return found } - var rangeEnd = collapsed.find(1); - if (rangeEnd.line == lineN) { return rangeEnd } - lineObj = getLine(doc, lineN = rangeEnd.line); - } - } + if (allowExtendedFlags) { + // Extend \h for horizontal whitespace + source = source.replace(/\[\\h\]/g, HORIZONTAL_WHITESPACE).replace(/\\h/g, HORIZONTAL_WHITESPACE); + } - function wrappedLineExtent(cm, lineObj, preparedMeasure, y) { - y -= widgetTopHeight(lineObj); - var end = lineObj.text.length; - var begin = findFirst(function (ch) { return measureCharPrepared(cm, preparedMeasure, ch - 1).bottom <= y; }, end, 0); - end = findFirst(function (ch) { return measureCharPrepared(cm, preparedMeasure, ch).top > y; }, begin, end); - return { begin: begin, end: end } - } + return new RegExp(source, flags || 'g'); + } + function isLookbehindSupported() { + try { + new RegExp('(?<=.)'); + return true; + } catch (ignore) {} - function wrappedLineExtentChar(cm, lineObj, preparedMeasure, target) { - if (!preparedMeasure) { preparedMeasure = prepareMeasureForLine(cm, lineObj); } - var targetTop = intoCoordSystem(cm, lineObj, measureCharPrepared(cm, preparedMeasure, target), "line").top; - return wrappedLineExtent(cm, lineObj, preparedMeasure, targetTop) - } + return false; + } + var HORIZONTAL_WHITESPACE = "[ \\t\\u00a0]"; // 仅适用非多行模式的正则 - // Returns true if the given side of a box is after the given - // coordinates, in top-to-bottom, left-to-right order. - function boxIsAfter(box, x, y, left) { - return box.bottom <= y ? false : box.top > y ? true : (left ? box.left : box.right) > x - } + var ALLOW_WHITESPACE_MULTILINE = '(?:.*?)(?:(?:\\n.*?)*?)'; + var DO_NOT_STARTS_AND_END_WITH_SPACES_MULTILINE_ALLOW_EMPTY = '(?:(?:\\S|(?:\\S.*?\\S))(?:[ \\t]*\\n.*?)*?)'; + var NOT_ALL_WHITE_SPACES_INLINE = '(?:[^\\n]*?\\S[^\\n]*?)'; + // !, ", #, $, %, &, ', (, ), *, +, ,, -, ., / (U+0021–2F), + // :, ;, <, =, >, ?, @ (U+003A–0040), + // [, \, ], ^, _, ` (U+005B–0060), + // {, |, }, or ~ (U+007B–007E). - function coordsCharInner(cm, lineObj, lineNo, x, y) { - // Move y into line-local coordinate space - y -= heightAtLine(lineObj); - var preparedMeasure = prepareMeasureForLine(cm, lineObj); - // When directly calling `measureCharPrepared`, we have to adjust - // for the widgets at this line. - var widgetHeight = widgetTopHeight(lineObj); - var begin = 0, end = lineObj.text.length, ltr = true; - - var order = getOrder(lineObj, cm.doc.direction); - // If the line isn't plain left-to-right text, first figure out - // which bidi section the coordinates fall into. - if (order) { - var part = (cm.options.lineWrapping ? coordsBidiPartWrapped : coordsBidiPart) - (cm, lineObj, lineNo, preparedMeasure, order, x, y); - ltr = part.level != 1; - // The awkward -1 offsets are needed because findFirst (called - // on these below) will treat its first bound as inclusive, - // second as exclusive, but we want to actually address the - // characters in the part's range - begin = ltr ? part.from : part.to - 1; - end = ltr ? part.to : part.from - 1; - } + var PUNCTUATION = "[\\u0021-\\u002F\\u003a-\\u0040\\u005b-\\u0060\\u007b-\\u007e]"; // extra punctuations - // A binary search to find the first character whose bounding box - // starts after the coordinates. If we run across any whose box wrap - // the coordinates, store that. - var chAround = null, boxAround = null; - var ch = findFirst(function (ch) { - var box = measureCharPrepared(cm, preparedMeasure, ch); - box.top += widgetHeight; box.bottom += widgetHeight; - if (!boxIsAfter(box, x, y, false)) { return false } - if (box.top <= y && box.left <= x) { - chAround = ch; - boxAround = box; - } - return true - }, begin, end); - - var baseX, sticky, outside = false; - // If a box around the coordinates was found, use that - if (boxAround) { - // Distinguish coordinates nearer to the left or right side of the box - var atLeft = x - boxAround.left < boxAround.right - x, atStart = atLeft == ltr; - ch = chAround + (atStart ? 0 : 1); - sticky = atStart ? "after" : "before"; - baseX = atLeft ? boxAround.left : boxAround.right; - } else { - // (Adjust for extended bound, if necessary.) - if (!ltr && (ch == end || ch == begin)) { ch++; } - // To determine which side to associate with, get the box to the - // left of the character and compare it's vertical position to the - // coordinates - sticky = ch == 0 ? "after" : ch == lineObj.text.length ? "before" : - (measureCharPrepared(cm, preparedMeasure, ch - (ltr ? 1 : 0)).bottom + widgetHeight <= y) == ltr ? - "after" : "before"; - // Now get accurate coordinates for this place, in order to get a - // base X position - var coords = cursorCoords(cm, Pos(lineNo, ch, sticky), "line", lineObj, preparedMeasure); - baseX = coords.left; - outside = y < coords.top ? -1 : y >= coords.bottom ? 1 : 0; - } + var UNDERSCORE_EMPHASIS_BOUNDARY = '[' + "\\u0021-\\u002F\\u003a-\\u0040\\u005b\\u005d\\u005e\\u0060\\u007b-\\u007e" + // punctuations defined in commonmark + ' ' + '\\t\\n' + '!“”¥‘’(),。—:;《》?【】「」·~|' + // chinese punctuations + ']'; // https://html.spec.whatwg.org/multipage/input.html#e-mail-state-(type%3Demail) - ch = skipExtendingChars(lineObj.text, ch, 1); - return PosWithInfo(lineNo, ch, sticky, outside, x - baseX) - } + var EMAIL_INLINE = new RegExp([/[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+/.source, '@', /[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*/.source].join('')); + var EMAIL = new RegExp("^".concat(EMAIL_INLINE.source, "$")); // https://gist.github.com/dperini/729294 + // [USERNAME[:PASSWORD]@](IP|HOST)[:PORT][/SOURCE_PATH?QUERY_PARAMS#HASH] - function coordsBidiPart(cm, lineObj, lineNo, preparedMeasure, order, x, y) { - // Bidi parts are sorted left-to-right, and in a non-line-wrapping - // situation, we can take this ordering to correspond to the visual - // ordering. This finds the first part whose end is after the given - // coordinates. - var index = findFirst(function (i) { - var part = order[i], ltr = part.level != 1; - return boxIsAfter(cursorCoords(cm, Pos(lineNo, ltr ? part.to : part.from, ltr ? "before" : "after"), - "line", lineObj, preparedMeasure), x, y, true) - }, 0, order.length - 1); - var part = order[index]; - // If this isn't the first part, the part's start is also after - // the coordinates, and the coordinates aren't on the same line as - // that start, move one part back. - if (index > 0) { - var ltr = part.level != 1; - var start = cursorCoords(cm, Pos(lineNo, ltr ? part.from : part.to, ltr ? "after" : "before"), - "line", lineObj, preparedMeasure); - if (boxIsAfter(start, x, y, true) && start.top > y) { part = order[index - 1]; } - } - return part - } + var URL_INLINE_NO_SLASH = new RegExp('' + // 针对eslint的特殊处理 + '(?:\\S+(?::\\S*)?@)?' + '(?:' + // IP address exclusion + // IP address dotted notation octets + // excludes loopback network 0.0.0.0 + // excludes reserved space >= 224.0.0.0 + // excludes network & broadcast addresses + // (first & last IP address of each class) + '(?:1\\d\\d|2[01]\\d|22[0-3]|[1-9]\\d?)' + '(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}' + '(?:\\.(?:1\\d\\d|2[0-4]\\d|25[0-4]|[1-9]\\d?))' + '|' + // host & domain names, may end with dot + '(?![-_])(?:[-\\w\\xa1-\\xff]{0,63}[^-_]\\.)+' + // TLD identifier name, may end with dot + '(?:[a-zA-Z\\xa1-\\xff]{2,}\\.?)' + ')' + // port number (optional) + '(?::\\d{2,5})?' + // resource path (optional) + '(?:[/?#][^\\s<>\\x00-\\x1f"\\(\\)]*)?'); + var URL_INLINE = new RegExp( // eslint特殊处理 + // protocol identifier (optional) + // short syntax // still required + // '(?:(?:(?:https?|ftp):)?\\/\\/)' + + "(?:\\/\\/)".concat(URL_INLINE_NO_SLASH.source)); + var URL_NO_SLASH = new RegExp("^".concat(URL_INLINE_NO_SLASH.source, "$")); + var URL$1 = new RegExp("^".concat(URL_INLINE.source, "$")); + function getTableRule() { + var _context; + + var merge = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + // ^(\|[^\n]+\|\r?\n)((?:\|:?[-]+:?)+\|)(\n(?:\|[^\n]+\|\r?\n?)*)?$ + // (\\|?[^\\n|]+\\|?\\n)(?:\\|?[\\s]*:?[-]{2,}:?[\\s]* + // (?:\\|[\\s]*:?[-]{2,}:?[\\s]*)+\\|?)(\\n\\|?(\\|[^\\n|]+)*\\|?)? + + /** + * (\|[^\n]+\|\n) Headers + * ((\|[\s]*:?[-]{2,}:?[\s]*)+\|) Column Options + * ((?:\n\|[^\n]+\|)*) Rows + */ + var strict = { + begin: '(?:^|\\n)(\\n*)', + content: ['(\\h*\\|[^\\n]+\\|?\\h*)', // Header + '\\n', '(?:(?:\\h*\\|\\h*:?[-]{1,}:?\\h*)+\\|?\\h*)', // Column Options + '((\\n\\h*\\|[^\\n]+\\|?\\h*)*)' // Rows + ].join(''), + end: '(?=$|\\n)' + }; + strict.reg = compileRegExp(strict, 'g', true); + var loose = { + begin: '(?:^|\\n)(\\n*)', + content: ['(\\|?[^\\n|]+(\\|[^\\n|]+)+\\|?)', // Header + '\\n', '(?:\\|?\\h*:?[-]{1,}:?[\\h]*(?:\\|[\\h]*:?[-]{1,}:?\\h*)+\\|?)', // Column Options + '((\\n\\|?([^\\n|]+(\\|[^\\n|]*)+)\\|?)*)' // Rows + ].join(''), + end: '(?=$|\\n)' + }; + loose.reg = compileRegExp(loose, 'g', true); + + if (merge === false) { + return { + strict: strict, + loose: loose + }; + } + + var regStr = concat$5(_context = "(?:".concat(strict.begin + strict.content + strict.end, "|")).call(_context, loose.begin + loose.content + loose.end, ")"); + + return compileRegExp({ + begin: '', + content: regStr, + end: '' + }, 'g', true); + } + function getCodeBlockRule() { + var codeBlock = { + /** + * (?:^|\n)是区块的通用开头 + * (\n*)捕获区块前的所有换行 + * ((?:>\s*)*) 捕获代码块前面的引用("> > > " 这种东西) + * (?:[^\S\n]*)捕获```前置的空格字符 + * 只要有连续3个及以上`并且前后`的数量相等,则认为是代码快语法 + */ + begin: /(?:^|\n)(\n*((?:>[\t ]*)*)(?:[^\S\n]*))(`{3,})([^`]*?)\n/, + content: /([\w\W]*?)/, + // '([\\w\\W]*?)', + end: /[^\S\n]*\3[ \t]*(?=$|\n+)/ // '\\s*```[ \\t]*(?=$|\\n+)', + + }; + codeBlock.reg = new RegExp(codeBlock.begin.source + codeBlock.content.source + codeBlock.end.source, 'g'); + return codeBlock; + } + /** + * 从selection里获取列表语法 + * @param {*} selection + * @param {('ol'|'ul'|'checklist')} type 列表类型 + * @returns {String} + */ - function coordsBidiPartWrapped(cm, lineObj, _lineNo, preparedMeasure, order, x, y) { - // In a wrapped line, rtl text on wrapping boundaries can do things - // that don't correspond to the ordering in our `order` array at - // all, so a binary search doesn't work, and we want to return a - // part that only spans one line so that the binary search in - // coordsCharInner is safe. As such, we first find the extent of the - // wrapped line, and then do a flat search in which we discard any - // spans that aren't on the line. - var ref = wrappedLineExtent(cm, lineObj, preparedMeasure, y); - var begin = ref.begin; - var end = ref.end; - if (/\s/.test(lineObj.text.charAt(end - 1))) { end--; } - var part = null, closestDist = null; - for (var i = 0; i < order.length; i++) { - var p = order[i]; - if (p.from >= end || p.to <= begin) { continue } - var ltr = p.level != 1; - var endX = measureCharPrepared(cm, preparedMeasure, ltr ? Math.min(end, p.to) - 1 : Math.max(begin, p.from)).right; - // Weigh against spans ending before this, so that they are only - // picked if nothing ends after - var dist = endX < x ? x - endX + 1e9 : endX - x; - if (!part || closestDist > dist) { - part = p; - closestDist = dist; - } - } - if (!part) { part = order[order.length - 1]; } - // Clip the part to the wrapped line. - if (part.from < begin) { part = { from: begin, to: part.to, level: part.level }; } - if (part.to > end) { part = { from: part.from, to: end, level: part.level }; } - return part - } + function getListFromStr(selection, type) { + var $selection = selection ? selection : 'Item 1\n Item 1.1\nItem 2'; + $selection = $selection.replace(/^\n+/, '').replace(/\n+$/, ''); + var pre = '1.'; - var measureText; - // Compute the default text height. - function textHeight(display) { - if (display.cachedTextHeight != null) { return display.cachedTextHeight } - if (measureText == null) { - measureText = elt("pre", null, "CodeMirror-line-like"); - // Measure a bunch of lines, for browsers that compute - // fractional heights. - for (var i = 0; i < 49; ++i) { - measureText.appendChild(document.createTextNode("x")); - measureText.appendChild(elt("br")); - } - measureText.appendChild(document.createTextNode("x")); - } - removeChildrenAndAdd(display.measure, measureText); - var height = measureText.offsetHeight / 50; - if (height > 3) { display.cachedTextHeight = height; } - removeChildren(display.measure); - return height || 1 - } + switch (type) { + case 'ol': + pre = '1.'; + break; - // Compute the default character width. - function charWidth(display) { - if (display.cachedCharWidth != null) { return display.cachedCharWidth } - var anchor = elt("span", "xxxxxxxxxx"); - var pre = elt("pre", [anchor], "CodeMirror-line-like"); - removeChildrenAndAdd(display.measure, pre); - var rect = anchor.getBoundingClientRect(), width = (rect.right - rect.left) / 10; - if (width > 2) { display.cachedCharWidth = width; } - return width || 10 - } + case 'ul': + pre = '-'; + break; - // Do a bulk-read of the DOM positions and sizes needed to draw the - // view, so that we don't interleave reading and writing to the DOM. - function getDimensions(cm) { - var d = cm.display, left = {}, width = {}; - var gutterLeft = d.gutters.clientLeft; - for (var n = d.gutters.firstChild, i = 0; n; n = n.nextSibling, ++i) { - var id = cm.display.gutterSpecs[i].className; - left[id] = n.offsetLeft + n.clientLeft + gutterLeft; - width[id] = n.clientWidth; - } - return { - fixedPos: compensateForHScroll(d), - gutterTotalWidth: d.gutters.offsetWidth, - gutterLeft: left, - gutterWidth: width, - wrapperWidth: d.wrapper.clientWidth - } - } + case 'checklist': + pre = '- [x]'; + break; + } - // Computes display.scroller.scrollLeft + display.gutters.offsetWidth, - // but using getBoundingClientRect to get a sub-pixel-accurate - // result. - function compensateForHScroll(display) { - return display.scroller.getBoundingClientRect().left - display.sizer.getBoundingClientRect().left - } + $selection = $selection.replace(/^(\s*)([0-9a-zA-Z]+\.|- \[x\]|- \[ \]|-) /gm, '$1'); // 对有序列表进行序号自增处理 - // Returns a function that estimates the height of a line, to use as - // first approximation until the line becomes visible (and is thus - // properly measurable). - function estimateHeight(cm) { - var th = textHeight(cm.display), wrapping = cm.options.lineWrapping; - var perLine = wrapping && Math.max(5, cm.display.scroller.clientWidth / charWidth(cm.display) - 3); - return function (line) { - if (lineIsHidden(cm.doc, line)) { return 0 } - - var widgetsHeight = 0; - if (line.widgets) { - for (var i = 0; i < line.widgets.length; i++) { - if (line.widgets[i].height) { widgetsHeight += line.widgets[i].height; } - } - } + if (pre === '1.') { + var listNum = {}; + $selection = $selection.replace(/^(\s*)(\S[\s\S]*?)$/gm, function (match, p1, p2) { + var _p1$match, _context2, _context3; - if (wrapping) { return widgetsHeight + (Math.ceil(line.text.length / perLine) || 1) * th } - else { return widgetsHeight + th } - } - } + var space = ((_p1$match = p1.match(/[ \t]/g)) === null || _p1$match === void 0 ? void 0 : _p1$match.length) || 0; + listNum[space] = listNum[space] ? listNum[space] + 1 : 1; + return concat$5(_context2 = concat$5(_context3 = "".concat(p1)).call(_context3, listNum[space], ". ")).call(_context2, p2); + }); + } else { + $selection = $selection.replace(/^(\s*)(\S[\s\S]*?)$/gm, "$1".concat(pre, " $2")); + } - function estimateLineHeights(cm) { - var doc = cm.doc, est = estimateHeight(cm); - doc.iter(function (line) { - var estHeight = est(line); - if (estHeight != line.height) { updateLineHeight(line, estHeight); } - }); - } + return $selection; + } + /** + * 信息面板的识别正则 + * @returns {object} + */ - // Given a mouse event, find the corresponding position. If liberal - // is false, it checks whether a gutter or scrollbar was clicked, - // and returns null if it was. forRect is used by rectangular - // selections, and tries to estimate a character position even for - // coordinates beyond the right of the text. - function posFromMouse(cm, e, liberal, forRect) { - var display = cm.display; - if (!liberal && e_target(e).getAttribute("cm-not-content") == "true") { return null } - - var x, y, space = display.lineSpace.getBoundingClientRect(); - // Fails unpredictably on IE[67] when mouse is dragged around quickly. - try { x = e.clientX - space.left; y = e.clientY - space.top; } - catch (e$1) { return null } - var coords = coordsChar(cm, x, y), line; - if (forRect && coords.xRel > 0 && (line = getLine(cm.doc, coords.line).text).length == coords.ch) { - var colDiff = countColumn(line, line.length, cm.options.tabSize) - line.length; - coords = Pos(coords.line, Math.max(0, Math.round((x - paddingH(cm.display).left) / charWidth(cm.display)) - colDiff)); - } - return coords - } + function getPanelRule() { + var ret = { + begin: /(?:^|\n)(\n*(?:[^\S\n]*)):::([^:][^\n]+?)\s*\n/, + content: /([\w\W]*?)/, + end: /\n[ \t]*:::[ \t]*(?=$|\n+)/ + }; + ret.reg = new RegExp(ret.begin.source + ret.content.source + ret.end.source, 'g'); + return ret; + } + /** + * 手风琴/detail语法的识别正则 + * 例: + * +++(-) 点击查看详情 + * body + * body + * ++ 标题(默认收起内容) + * 内容 + * ++- 标题(默认展开内容) + * 内容2 + * +++ + * @returns {object} + */ - // Find the view element corresponding to a given line. Return null - // when the line isn't visible. - function findViewIndex(cm, n) { - if (n >= cm.display.viewTo) { return null } - n -= cm.display.viewFrom; - if (n < 0) { return null } - var view = cm.display.view; - for (var i = 0; i < view.length; i++) { - n -= view[i].size; - if (n < 0) { return i } - } - } + function getDetailRule() { + var ret = { + begin: /(?:^|\n)(\n*(?:[^\S\n]*))\+\+\+([-]{0,1})\s+([^\n]+)\n/, + content: /([\w\W]+?)/, + end: /\n[ \t]*\+\+\+[ \t]*(?=$|\n+)/ + }; + ret.reg = new RegExp(ret.begin.source + ret.content.source + ret.end.source, 'g'); + return ret; + } // 匹配图片URL里的base64 - // Updates the display.view data structure for a given change to the - // document. From and to are in pre-change coordinates. Lendiff is - // the amount of lines added or subtracted by the change. This is - // used for changes that span multiple lines, or change the way - // lines are divided into visual lines. regLineChange (below) - // registers single-line changes. - function regChange(cm, from, to, lendiff) { - if (from == null) { from = cm.doc.first; } - if (to == null) { to = cm.doc.first + cm.doc.size; } - if (!lendiff) { lendiff = 0; } - - var display = cm.display; - if (lendiff && to < display.viewTo && - (display.updateLineNumbers == null || display.updateLineNumbers > from)) { display.updateLineNumbers = from; } - - cm.curOp.viewChanged = true; - - if (from >= display.viewTo) { // Change after - if (sawCollapsedSpans && visualLineNo(cm.doc, from) < display.viewTo) { resetView(cm); } - } else if (to <= display.viewFrom) { // Change before - if (sawCollapsedSpans && visualLineEndNo(cm.doc, to + lendiff) > display.viewFrom) { - resetView(cm); - } else { - display.viewFrom += lendiff; - display.viewTo += lendiff; - } - } else if (from <= display.viewFrom && to >= display.viewTo) { // Full overlap - resetView(cm); - } else if (from <= display.viewFrom) { // Top overlap - var cut = viewCuttingPoint(cm, to, to + lendiff, 1); - if (cut) { - display.view = display.view.slice(cut.index); - display.viewFrom = cut.lineN; - display.viewTo += lendiff; - } else { - resetView(cm); - } - } else if (to >= display.viewTo) { // Bottom overlap - var cut$1 = viewCuttingPoint(cm, from, from, -1); - if (cut$1) { - display.view = display.view.slice(0, cut$1.index); - display.viewTo = cut$1.lineN; - } else { - resetView(cm); - } - } else { // Gap in the middle - var cutTop = viewCuttingPoint(cm, from, from, -1); - var cutBot = viewCuttingPoint(cm, to, to + lendiff, 1); - if (cutTop && cutBot) { - display.view = display.view.slice(0, cutTop.index) - .concat(buildViewArray(cm, cutTop.lineN, cutBot.lineN)) - .concat(display.view.slice(cutBot.index)); - display.viewTo += lendiff; - } else { - resetView(cm); - } - } + var imgBase64Reg = /(!\[[^\n]*?\]\(data:image\/png;base64,)([^)]+)\)/g; // 匹配图片{}里的data-xml属性 - var ext = display.externalMeasured; - if (ext) { - if (to < ext.lineN) { ext.lineN += lendiff; } - else if (from < ext.lineN + ext.size) { display.externalMeasured = null; } - } - } + var imgDrawioXmlReg = /(!\[[^\n]*?\]\([^)]+\)\{[^}]* data-xml=)([^}]+)\}/g; + /** + * 匹配draw.io的图片语法 + * 图片的语法为 ![alt](${base64}){data-type=drawio data-xml=${xml}} + */ - // Register a change to a single line. Type must be one of "text", - // "gutter", "class", "widget" - function regLineChange(cm, line, type) { - cm.curOp.viewChanged = true; - var display = cm.display, ext = cm.display.externalMeasured; - if (ext && line >= ext.lineN && line < ext.lineN + ext.size) { display.externalMeasured = null; } - - if (line < display.viewFrom || line >= display.viewTo) { return } - var lineView = display.view[findViewIndex(cm, line)]; - if (lineView.node == null) { return } - var arr = lineView.changes || (lineView.changes = []); - if (indexOf(arr, type) == -1) { arr.push(type); } - } + var imgDrawioReg = /(!\[[^\n]*?\]\(data:image\/png;base64,[^)]+\)\{data-type=drawio data-xml=[^}]+\})/g; - // Clear the view. - function resetView(cm) { - cm.display.viewFrom = cm.display.viewTo = cm.doc.first; - cm.display.view = []; - cm.display.viewOffset = 0; - } + /** + * Copyright (C) 2021 THL A29 Limited, a Tencent company. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ - function viewCuttingPoint(cm, oldN, newN, dir) { - var index = findViewIndex(cm, oldN), diff, view = cm.display.view; - if (!sawCollapsedSpans || newN == cm.doc.first + cm.doc.size) { return { index: index, lineN: newN } } - var n = cm.display.viewFrom; - for (var i = 0; i < index; i++) { n += view[i].size; } - if (n != oldN) { - if (dir > 0) { - if (index == view.length - 1) { return null } - diff = (n + view[index].size) - oldN; - index++; - } else { - diff = n - oldN; - } - oldN += diff; newN += diff; - } - while (visualLineNo(cm.doc, newN) != newN) { - if (index == (dir < 0 ? 0 : view.length - 1)) { return null } - newN += dir * view[index - (dir < 0 ? 1 : 0)].size; - index += dir; - } - return { index: index, lineN: newN } - } + /** + * @param {CodeMirror.Editor} cm + */ + function handleNewlineIndentList(cm) { + if (handleCherryList(cm)) return; + cm.execCommand('newlineAndIndentContinueMarkdownList'); + } + + function handleCherryList(cm) { + var cherryListRE = /^(\s*)([I一二三四五六七八九十]+)\.(\s+)/; + var cherryListEmptyRE = /^(\s*)([I一二三四五六七八九十]+)\.(\s+)$/; + if (cm.getOption('disableInput')) return false; + var ranges = cm.listSelections(); + var replacements = []; + + for (var i = 0; i < ranges.length; i++) { + var pos = ranges[i].head; + var line = cm.getLine(pos.line); + var match = cherryListRE.exec(line); + var cursorBeforeBullet = /^\s*$/.test(slice$7(line).call(line, 0, pos.ch)); + if (!ranges[i].empty() || cursorBeforeBullet || !match) return; + + if (cherryListEmptyRE.test(line)) { + cm.replaceRange('', { + line: pos.line, + ch: 0 + }, { + line: pos.line, + ch: pos.ch + 1 + }); + replacements[i] = '\n'; + } else { + var _context; + + var indent = match[1]; + var after = match[3]; + replacements[i] = concat$5(_context = "\n".concat(indent, "I.")).call(_context, after); + } + } + + cm.replaceSelections(replacements); + return true; + } - // Force the view to cover a given range, adding empty view element - // or clipping off existing ones as needed. - function adjustView(cm, from, to) { - var display = cm.display, view = display.view; - if (view.length == 0 || from >= display.viewTo || to <= display.viewFrom) { - display.view = buildViewArray(cm, from, to); - display.viewFrom = from; - } else { - if (display.viewFrom > from) { display.view = buildViewArray(cm, from, display.viewFrom).concat(display.view); } - else if (display.viewFrom < from) { display.view = display.view.slice(findViewIndex(cm, from)); } - display.viewFrom = from; - if (display.viewTo < to) { display.view = display.view.concat(buildViewArray(cm, display.viewTo, to)); } - else if (display.viewTo > to) { display.view = display.view.slice(0, findViewIndex(cm, to)); } - } - display.viewTo = to; - } - - // Count the number of lines in the view whose DOM representation is - // out of date (or nonexistent). - function countDirtyView(cm) { - var view = cm.display.view, dirty = 0; - for (var i = 0; i < view.length; i++) { - var lineView = view[i]; - if (!lineView.hidden && (!lineView.node || lineView.changes)) { ++dirty; } - } - return dirty - } + var _excluded = ["codemirror"]; + /** + * @typedef {import('~types/editor').EditorConfiguration} EditorConfiguration + * @typedef {import('~types/editor').EditorEventCallback} EditorEventCallback + * @typedef {import('codemirror')} CodeMirror + */ - function updateSelection(cm) { - cm.display.input.showSelection(cm.display.input.prepareSelection()); - } + /** @type {import('~types/editor')} */ - function prepareSelection(cm, primary) { - if (primary === void 0) primary = true; + var Editor = /*#__PURE__*/function () { + /** + * @constructor + * @param {Partial} options + */ + function Editor(options) { + var _this = this; + + _classCallCheck(this, Editor); + + _defineProperty(this, "dealBigData", function () { + if (_this.noChange) { + _this.noChange = false; + return; + } + + _this.formatBigData2Mark(imgBase64Reg, 'cm-url base64'); + + _this.formatBigData2Mark(imgDrawioXmlReg, 'cm-url drawio'); + }); + + _defineProperty(this, "formatBigData2Mark", function (reg, className) { + var codemirror = _this.editor; + var searcher = codemirror.getSearchCursor(reg); + var oneSearch = searcher.findNext(); + + for (; oneSearch !== false; oneSearch = searcher.findNext()) { + var _oneSearch$, _oneSearch$2; + + var target = searcher.from(); + + if (!target) { + continue; + } + + var bigString = (_oneSearch$ = oneSearch[2]) !== null && _oneSearch$ !== void 0 ? _oneSearch$ : ''; + var targetChFrom = target.ch + ((_oneSearch$2 = oneSearch[1]) === null || _oneSearch$2 === void 0 ? void 0 : _oneSearch$2.length); + var targetChTo = targetChFrom + bigString.length; + var targetLine = target.line; + var begin = { + line: targetLine, + ch: targetChFrom + }; + var end = { + line: targetLine, + ch: targetChTo + }; // 如果所在区域已经有mark了,则不再增加mark + + if (codemirror.findMarks(begin, end).length > 0) { + continue; + } + + var newSpan = createElement('span', "cm-string ".concat(className), { + title: bigString + }); + newSpan.textContent = bigString; + _this.noChange = true; + codemirror.markText(begin, end, { + replacedWith: newSpan, + atomic: true + }); + } + }); + + _defineProperty(this, "onKeyup", function (e, codemirror) { + var _codemirror$getCursor = codemirror.getCursor(), + targetLine = _codemirror$getCursor.line; + + _this.previewer.highlightLine(targetLine + 1); + }); + + _defineProperty(this, "onScroll", function (codemirror) { + Event$1.emit(_this.instanceId, Event$1.Events.cleanAllSubMenus); // 滚动时清除所有子菜单,这不应该在Bubble中处理,我们关注的是编辑器的滚动 add by ufec + + if (_this.disableScrollListener) { + _this.disableScrollListener = false; + return; + } + + var scroller = codemirror.getScrollerElement(); + + if (scroller.scrollTop <= 0) { + _this.previewer.scrollToLineNum(0); + + return; + } + + if (scroller.scrollTop + scroller.clientHeight >= scroller.scrollHeight - 20) { + _this.previewer.scrollToLineNum(null); // 滚动到底 + + + return; + } + + var currentTop = codemirror.getScrollInfo().top; + var targetLine = codemirror.lineAtHeight(currentTop, 'local'); + var lineRect = codemirror.charCoords({ + line: targetLine, + ch: 0 + }, 'local'); + var lineHeight = codemirror.getLineHandle(targetLine).height; + var lineTop = lineRect.bottom - lineHeight; // 直接用lineRect.top在自动折行时计算的是最后一行的top + + var percent = 100 * (currentTop - lineTop) / lineHeight / 100; // console.log(percent); + // codemirror中行号以0开始,所以需要+1 + + _this.previewer.scrollToLineNum(targetLine + 1, percent); + }); + + _defineProperty(this, "onMouseDown", function (codemirror, evt) { + Event$1.emit(_this.instanceId, Event$1.Events.cleanAllSubMenus); // Bubble中处理需要考虑太多,直接在编辑器中处理可包括Bubble中所有情况,因为产生Bubble的前提是光标在编辑器中 add by ufec + + var _codemirror$getCursor2 = codemirror.getCursor(), + targetLine = _codemirror$getCursor2.line; + + var top = Math.abs(evt.y - codemirror.getWrapperElement().getBoundingClientRect().y); + + _this.previewer.scrollToLineNumWithOffset(targetLine + 1, top); + }); + + _defineProperty(this, "onCursorActivity", function () { + _this.refreshWritingStatus(); + }); + + /** + * @property + * @type {EditorConfiguration} + */ + this.options = { + id: 'code', + // textarea 的id属性值 + name: 'code', + // textarea 的name属性值 + autoSave2Textarea: false, + editorDom: document.createElement('div'), + wrapperDom: null, + autoScrollByCursor: true, + convertWhenPaste: true, + codemirror: { + lineNumbers: false, + // 显示行数 + cursorHeight: 0.85, + // 光标高度,0.85好看一些 + indentUnit: 4, + // 缩进单位为4 + tabSize: 4, + // 一个tab转换成的空格数量 + // styleActiveLine: false, // 当前行背景高亮 + // matchBrackets: true, // 括号匹配 + mode: 'gfm', + // 从markdown模式改成gfm模式,以使用默认高亮规则 + lineWrapping: true, + // 自动换行 + indentWithTabs: true, + // 缩进用tab表示 + autofocus: true, + theme: 'default', + autoCloseTags: true, + // 输入html标签时自动补充闭合标签 + extraKeys: { + Enter: handleNewlineIndentList + }, + // 增加markdown回车自动补全 + matchTags: { + bothTags: true + }, + // 自动高亮选中的闭合html标签 + placeholder: '', + // 设置为 contenteditable 对输入法定位更友好 + // 但已知会影响某些悬浮菜单的定位,如粘贴选择文本或markdown模式的菜单 + // inputStyle: 'contenteditable', + keyMap: 'sublime' + }, + toolbars: {}, + onKeydown: function onKeydown() {}, + onChange: function onChange() {}, + onFocus: function onFocus() {}, + onBlur: function onBlur() {}, + onPaste: this.onPaste, + onScroll: this.onScroll + }; + /** + * @property + * @private + * @type {{ timer?: number; destinationTop?: number }} + */ + + this.animation = {}; + + var _codemirror = options.codemirror, + restOptions = _objectWithoutProperties(options, _excluded); + + if (_codemirror) { + assign$2(this.options.codemirror, _codemirror); + } + + assign$2(this.options, restOptions); + + this.$cherry = this.options.$cherry; + this.instanceId = this.$cherry.getInstanceId(); + } + /** + * 处理draw.io的xml数据和图片的base64数据,对这种超大的数据增加省略号 + */ + + + _createClass(Editor, [{ + key: "onPaste", + value: + /** + * + * @param {ClipboardEvent} e + * @param {CodeMirror.Editor} codemirror + */ + function onPaste(e, codemirror) { + var clipboardData = e.clipboardData; + + if (clipboardData) { + this.handlePaste(e, clipboardData, codemirror); + } else { + var _window = window; + clipboardData = _window.clipboardData; + this.handlePaste(e, clipboardData, codemirror); + } + } + /** + * + * @param {ClipboardEvent} event + * @param {ClipboardEvent['clipboardData']} clipboardData + * @param {CodeMirror.Editor} codemirror + * @returns {boolean | void} + */ + + }, { + key: "handlePaste", + value: function handlePaste(event, clipboardData, codemirror) { + var _test$match; + + var items = clipboardData.items; + var types = clipboardData.types || []; + var codemirrorDoc = codemirror.getDoc(); + + for (var i = 0; i < types.length; i++) { + var item = items[i]; // 判断是否为图片数据 + + if (item && item.kind === 'file' && item.type.match(/^image\//i)) { + // 读取该图片 + var file = item.getAsFile(); + this.options.fileUpload(file, function (url) { + if (typeof url !== 'string') { + return; + } + + codemirrorDoc.replaceSelection("![enter image description here](".concat(url, ")")); + }); + event.preventDefault(); + } + } // 复制html转换markdown + + + var htmlText = clipboardData.getData('text/plain'); + var html = clipboardData.getData('Text/Html'); + + if (!html || !this.options.convertWhenPaste) { + return true; + } + /** + * 这里需要处理一个特殊逻辑: + * 从excel中复制而来的内容,剪切板里会有一张图片(一个元素)和一段纯文本,在这种场景下,需要丢掉图片,直接粘贴纯文本 + * 与此同时,当剪切板里有图片和其他html标签时(从web页面上复制的内容),则需要走下面的html转md的逻辑 + * 基于上述两个场景,才有了下面四行奇葩的代码 + */ + + + var test = html.replace(/<(html|head|body|!)/g, ''); + + if (((_test$match = test.match(/<[a-zA-Z]/g)) === null || _test$match === void 0 ? void 0 : _test$match.length) <= 1 && / 0) { + var range = codemirror.listSelections(); + + if (codemirror.getSelections().length <= 1 && range[0] && range[0].anchor) { + var currentCursor = {}; + currentCursor.line = range[0].anchor.line; + currentCursor.ch = range[0].anchor.ch; + codemirrorDoc.replaceSelection(mdText); + pasteHelper.showSwitchBtnAfterPasteHtml(this.$cherry, currentCursor, codemirror, htmlText, mdText); + } else { + codemirrorDoc.replaceSelection(mdText); + } + + event.preventDefault(); + } + + divObj = null; + } + /** + * + * @param {CodeMirror.Editor} codemirror + */ + + }, { + key: "init", + value: + /** + * + * @param {*} previewer + */ + function init(previewer) { + var _this2 = this; + + var textArea = this.options.editorDom.querySelector("#".concat(this.options.id)); + + if (!(textArea instanceof HTMLTextAreaElement)) { + throw new Error('The specific element is not a textarea.'); + } + + var editor = codemirror.fromTextArea(textArea, this.options.codemirror); + editor.addOverlay({ + name: 'invisibles', + token: function nextToken(stream) { + var tokenClass; + var spaces = 0; + var peek = stream.peek() === ' '; + + if (peek) { + while (peek && spaces < Number.MAX_VALUE) { + spaces += 1; + stream.next(); + peek = stream.peek() === ' '; + } + + tokenClass = "whitespace whitespace-".concat(spaces); + } else { + while (!stream.eol()) { + stream.next(); + } + + tokenClass = ''; + } + + return tokenClass; + } + }); + this.previewer = previewer; + this.disableScrollListener = false; + + if (this.options.value) { + editor.setOption('value', this.options.value); + } + + editor.on('blur', function (codemirror, evt) { + _this2.options.onBlur(evt, codemirror); + }); + editor.on('focus', function (codemirror, evt) { + _this2.options.onFocus(evt, codemirror); + }); + editor.on('change', function (codemirror, evt) { + _this2.options.onChange(evt, codemirror); + + _this2.dealBigData(); + + if (_this2.options.autoSave2Textarea) { + // @ts-ignore + // 将codemirror里的内容回写到textarea里 + codemirror.save(); + } + }); + editor.on('keydown', function (codemirror, evt) { + _this2.options.onKeydown(evt, codemirror); + }); + editor.on('keyup', function (codemirror, evt) { + _this2.onKeyup(evt, codemirror); + }); + editor.on('paste', function (codemirror, evt) { + _this2.options.onPaste.call(_this2, evt, codemirror); + }); + + if (this.options.autoScrollByCursor) { + editor.on('mousedown', function (codemirror, evt) { + setTimeout$3(function () { + _this2.onMouseDown(codemirror, evt); + }); + }); + } + + editor.on('drop', function (codemirror, evt) { + var files = evt.dataTransfer.files || []; + + if (files && files.length > 0) { + // 增加延时,让drop的位置变成codemirror的光标位置 + setTimeout$3(function () { + var _loop = function _loop(i, _needBr) { + var file = files[i]; + var fileType = file.type || ''; // 文本类型或者无类型的,直接读取内容,不做上传文件的操作 + + if (fileType === '' || /^text/i.test(fileType)) { + needBr = _needBr; + return "continue"; + } + + _this2.options.fileUpload(file, function (url) { + var _context, _context2, _context3, _context4; + + var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + if (typeof url !== 'string') { + needBr = _needBr; + return; + } // 拖拽上传文件时,强制改成没有文字选择区的状态 + + + codemirror.setSelection(codemirror.getCursor()); + var name = params.name ? params.name : file.name; + var type = ''; + var poster = ''; + + if (/video/i.test(file.type)) { + type = '!video'; + poster = params.poster ? "{poster=".concat(params.poster, "}") : ''; + } + + if (/audio/i.test(file.type)) { + type = '!audio'; + } + + if (/image/i.test(file.type)) { + type = '!'; + } + + var style = type ? handelParams(params) : ''; + type = _needBr ? "\n".concat(type) : type; + + var insertValue = concat$5(_context = concat$5(_context2 = concat$5(_context3 = concat$5(_context4 = "".concat(type, "[")).call(_context4, name)).call(_context3, style, "](")).call(_context2, url, ")")).call(_context, poster); // 当批量上传文件时,每个被插入的文件中间需要加个换行,但单个上传文件的时候不需要加换行 + + + _needBr = true; + codemirror.replaceSelection(insertValue); + }); + + needBr = _needBr; + }; + + for (var i = 0, needBr = false; i < files.length; i++) { + var _ret = _loop(i, needBr); + + if (_ret === "continue") continue; + } + }, 50); + } + }); + editor.on('scroll', function (codemirror) { + _this2.options.onScroll(codemirror); + + _this2.options.writingStyle === 'focus' && _this2.refreshWritingStatus(); + }); + editor.on('cursorActivity', function () { + _this2.onCursorActivity(); + }); + addEvent(this.getEditorDom(), 'wheel', function () { + // 鼠标滚轮滚动时,强制监听滚动事件 + _this2.disableScrollListener = false; // 打断滚动动画 + + cancelAnimationFrame(_this2.animation.timer); + _this2.animation.timer = 0; + }, false); + /** + * @property + * @type {CodeMirror.Editor} + */ + + this.editor = editor; + + if (this.options.writingStyle !== 'normal') { + this.initWritingStyle(); + } + } + /** + * + * @param {number | null} beginLine 起始行,传入null时跳转到文档尾部 + * @param {number} [endLine] 终止行 + * @param {number} [percent] 百分比,取值0~1 + */ + + }, { + key: "jumpToLine", + value: function jumpToLine(beginLine, endLine, percent) { + var _this3 = this; + + if (beginLine === null) { + cancelAnimationFrame(this.animation.timer); + this.disableScrollListener = true; + this.editor.scrollIntoView({ + line: this.editor.lineCount() - 1, + ch: 1 + }); + this.animation.timer = 0; + return; + } + + var position = this.editor.charCoords({ + line: beginLine, + ch: 0 + }, 'local'); + var top = position.top; + var positionEnd = this.editor.charCoords({ + line: beginLine + endLine, + ch: 0 + }, 'local'); + var height = positionEnd.top - position.top; + top += height * percent; + this.animation.destinationTop = Math.ceil(top - 15); + + if (this.animation.timer) { + return; + } + + var animationHandler = function animationHandler() { + var currentTop = _this3.editor.getScrollInfo().top; + + var delta = _this3.animation.destinationTop - currentTop; // 100毫秒内完成动画 + + var move = Math.ceil(Math.min(Math.abs(delta), Math.max(1, Math.abs(delta) / (100 / 16.7)))); // console.log('should scroll: ', move, delta, currentTop, this.animation.destinationTop); + + if (delta > 0) { + if (currentTop >= _this3.animation.destinationTop) { + _this3.animation.timer = 0; + return; + } + + _this3.disableScrollListener = true; + + _this3.editor.scrollTo(null, currentTop + move); + } else if (delta < 0) { + if (currentTop <= _this3.animation.destinationTop || currentTop <= 0) { + _this3.animation.timer = 0; + return; + } + + _this3.disableScrollListener = true; + + _this3.editor.scrollTo(null, currentTop - move); + } else { + _this3.animation.timer = 0; + return; + } // 无法再继续滚动 + + + if (currentTop === _this3.editor.getScrollInfo().top || move >= Math.abs(delta)) { + _this3.animation.timer = 0; + return; + } + + _this3.animation.timer = requestAnimationFrame(animationHandler); + }; + + this.animation.timer = requestAnimationFrame(animationHandler); + } + /** + * + * @param {number | null} lineNum + * @param {number} [endLine] + * @param {number} [percent] + */ + + }, { + key: "scrollToLineNum", + value: function scrollToLineNum(lineNum, endLine, percent) { + if (lineNum === null) { + this.jumpToLine(null); + return; + } + + var $lineNum = Math.max(0, lineNum); + this.jumpToLine($lineNum, endLine, percent); + Logger.log('滚动预览区域,左侧应scroll to ', $lineNum); + } + /** + * + * @returns {HTMLElement} + */ + + }, { + key: "getEditorDom", + value: function getEditorDom() { + return this.options.editorDom; + } + /** + * + * @param {string} event 事件名 + * @param {EditorEventCallback} callback 回调函数 + */ + + }, { + key: "addListener", + value: function addListener(event, callback) { + this.editor.on(event, callback); + } + /** + * 初始化书写风格 + */ + + }, { + key: "initWritingStyle", + value: function initWritingStyle() { + var _context5, _context6; + + var writingStyle = this.options.writingStyle; + var className = "cherry-editor-writing-style--".concat(writingStyle); + var editorDom = this.getEditorDom(); // 重置状态 + + forEach$3(_context5 = filter$3(_context6 = from_1$2(editorDom.classList)).call(_context6, function (className) { + return startsWith$3(className).call(className, 'cherry-editor-writing-style--'); + })).call(_context5, function (className) { + return editorDom.classList.remove(className); + }); + + if (writingStyle === 'normal') { + return; + } + + editorDom.classList.add(className); + this.refreshWritingStatus(); + } + /** + * 刷新书写状态 + */ + + }, { + key: "refreshWritingStatus", + value: function refreshWritingStatus() { + var _context7, _context8; + + var writingStyle = this.options.writingStyle; + var className = "cherry-editor-writing-style--".concat(writingStyle); + /** + * @type {HTMLStyleElement} + */ + + var style = document.querySelector('#cherry-editor-writing-style') || document.createElement('style'); + style.id = 'cherry-editor-writing-style'; + find$3(_context7 = from_1$2(document.head.childNodes)).call(_context7, function (node) { + return node === style; + }) || document.head.appendChild(style); + var sheet = style.sheet; + + forEach$3(_context8 = from_1$2(Array(sheet.cssRules.length))).call(_context8, function () { + return sheet.deleteRule(0); + }); + + if (writingStyle === 'focus') { + var _context9, _context10; + + var editorDomRect = this.getEditorDom().getBoundingClientRect(); // 获取光标所在位置 + + var _this$editor$charCoor = this.editor.charCoords(this.editor.getCursor()), + top = _this$editor$charCoor.top, + bottom = _this$editor$charCoor.bottom; // 光标上部距离编辑器顶部距离(不包含菜单) + + + var topHeight = top - editorDomRect.top; // 光标下部距离编辑器底部距离 + + var bottomHeight = editorDomRect.height - (bottom - editorDomRect.top); + sheet.insertRule(concat$5(_context9 = ".".concat(className, "::before { height: ")).call(_context9, topHeight > 0 ? topHeight : 0, "px; }"), 0); + sheet.insertRule(concat$5(_context10 = ".".concat(className, "::after { height: ")).call(_context10, bottomHeight > 0 ? bottomHeight : 0, "px; }"), 0); + } + + if (writingStyle === 'typewriter') { + var _context11, _context12; + + // 编辑器顶/底部填充的空白高度 (用于内容不足时使光标所在行滚动到编辑器中央) + var height = this.editor.getScrollInfo().clientHeight / 2; + sheet.insertRule(concat$5(_context11 = ".".concat(className, " .CodeMirror-lines::before { height: ")).call(_context11, height, "px; }"), 0); + sheet.insertRule(concat$5(_context12 = ".".concat(className, " .CodeMirror-lines::after { height: ")).call(_context12, height, "px; }"), 0); + this.editor.scrollTo(null, this.editor.cursorCoords(null, 'local').top - height); + } + } + /** + * 修改书写风格 + */ + + }, { + key: "setWritingStyle", + value: function setWritingStyle(writingStyle) { + this.options.writingStyle = writingStyle; + this.initWritingStyle(); + } + }]); + + return Editor; + }(); - var doc = cm.doc, result = {}; - var curFragment = result.cursors = document.createDocumentFragment(); - var selFragment = result.selection = document.createDocumentFragment(); + var $findIndex = arrayIteration.findIndex; - for (var i = 0; i < doc.sel.ranges.length; i++) { - if (!primary && i == doc.sel.primIndex) { continue } - var range = doc.sel.ranges[i]; - if (range.from().line >= cm.display.viewTo || range.to().line < cm.display.viewFrom) { continue } - var collapsed = range.empty(); - if (collapsed || cm.options.showCursorWhenSelecting) { drawSelectionCursor(cm, range.head, curFragment); } - if (!collapsed) { drawSelectionRange(cm, range, selFragment); } - } - return result - } - // Draws a cursor for the given range - function drawSelectionCursor(cm, head, output) { - var pos = cursorCoords(cm, head, "div", null, null, !cm.options.singleCursorHeightPerLine); - - var cursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor")); - cursor.style.left = pos.left + "px"; - cursor.style.top = pos.top + "px"; - cursor.style.height = Math.max(0, pos.bottom - pos.top) * cm.options.cursorHeight + "px"; - - if (pos.other) { - // Secondary cursor, shown when on a 'jump' in bi-directional text - var otherCursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor CodeMirror-secondarycursor")); - otherCursor.style.display = ""; - otherCursor.style.left = pos.other.left + "px"; - otherCursor.style.top = pos.other.top + "px"; - otherCursor.style.height = (pos.other.bottom - pos.other.top) * .85 + "px"; - } - } + var FIND_INDEX = 'findIndex'; + var SKIPS_HOLES$1 = true; - function cmpCoords(a, b) { return a.top - b.top || a.left - b.left } - - // Draws the given range as a highlighted selection - function drawSelectionRange(cm, range, output) { - var display = cm.display, doc = cm.doc; - var fragment = document.createDocumentFragment(); - var padding = paddingH(cm.display), leftSide = padding.left; - var rightSide = Math.max(display.sizerWidth, displayWidth(cm) - display.sizer.offsetLeft) - padding.right; - var docLTR = doc.direction == "ltr"; - - function add(left, top, width, bottom) { - if (top < 0) { top = 0; } - top = Math.round(top); - bottom = Math.round(bottom); - fragment.appendChild(elt("div", null, "CodeMirror-selected", ("position: absolute; left: " + left + "px;\n top: " + top + "px; width: " + (width == null ? rightSide - left : width) + "px;\n height: " + (bottom - top) + "px"))); - } + // Shouldn't skip holes + if (FIND_INDEX in []) Array(1)[FIND_INDEX](function () { SKIPS_HOLES$1 = false; }); - function drawForLine(line, fromArg, toArg) { - var lineObj = getLine(doc, line); - var lineLen = lineObj.text.length; - var start, end; - function coords(ch, bias) { - return charCoords(cm, Pos(line, ch), "div", lineObj, bias) - } + // `Array.prototype.findIndex` method + // https://tc39.es/ecma262/#sec-array.prototype.findindex + _export({ target: 'Array', proto: true, forced: SKIPS_HOLES$1 }, { + findIndex: function findIndex(callbackfn /* , that = undefined */) { + return $findIndex(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined); + } + }); - function wrapX(pos, dir, side) { - var extent = wrappedLineExtentChar(cm, lineObj, null, pos); - var prop = (dir == "ltr") == (side == "after") ? "left" : "right"; - var ch = side == "after" ? extent.begin : extent.end - (/\s/.test(lineObj.text.charAt(extent.end - 1)) ? 2 : 1); - return coords(ch, prop)[prop] - } + var findIndex = entryVirtual('Array').findIndex; - var order = getOrder(lineObj, doc.direction); - iterateBidiSections(order, fromArg || 0, toArg == null ? lineLen : toArg, function (from, to, dir, i) { - var ltr = dir == "ltr"; - var fromPos = coords(from, ltr ? "left" : "right"); - var toPos = coords(to - 1, ltr ? "right" : "left"); - - var openStart = fromArg == null && from == 0, openEnd = toArg == null && to == lineLen; - var first = i == 0, last = !order || i == order.length - 1; - if (toPos.top - fromPos.top <= 3) { // Single line - var openLeft = (docLTR ? openStart : openEnd) && first; - var openRight = (docLTR ? openEnd : openStart) && last; - var left = openLeft ? leftSide : (ltr ? fromPos : toPos).left; - var right = openRight ? rightSide : (ltr ? toPos : fromPos).right; - add(left, fromPos.top, right - left, fromPos.bottom); - } else { // Multiple lines - var topLeft, topRight, botLeft, botRight; - if (ltr) { - topLeft = docLTR && openStart && first ? leftSide : fromPos.left; - topRight = docLTR ? rightSide : wrapX(from, dir, "before"); - botLeft = docLTR ? leftSide : wrapX(to, dir, "after"); - botRight = docLTR && openEnd && last ? rightSide : toPos.right; - } else { - topLeft = !docLTR ? leftSide : wrapX(from, dir, "before"); - topRight = !docLTR && openStart && first ? rightSide : fromPos.right; - botLeft = !docLTR && openEnd && last ? leftSide : toPos.left; - botRight = !docLTR ? rightSide : wrapX(to, dir, "after"); - } - add(topLeft, fromPos.top, topRight - topLeft, fromPos.bottom); - if (fromPos.bottom < toPos.top) { add(leftSide, fromPos.bottom, null, toPos.top); } - add(botLeft, toPos.top, botRight - botLeft, toPos.bottom); - } + var ArrayPrototype$7 = Array.prototype; - if (!start || cmpCoords(fromPos, start) < 0) { start = fromPos; } - if (cmpCoords(toPos, start) < 0) { start = toPos; } - if (!end || cmpCoords(fromPos, end) < 0) { end = fromPos; } - if (cmpCoords(toPos, end) < 0) { end = toPos; } - }); - return { start: start, end: end } - } + var findIndex$1 = function (it) { + var own = it.findIndex; + return it === ArrayPrototype$7 || (objectIsPrototypeOf(ArrayPrototype$7, it) && own === ArrayPrototype$7.findIndex) ? findIndex : own; + }; - var sFrom = range.from(), sTo = range.to(); - if (sFrom.line == sTo.line) { - drawForLine(sFrom.line, sFrom.ch, sTo.ch); - } else { - var fromLine = getLine(doc, sFrom.line), toLine = getLine(doc, sTo.line); - var singleVLine = visualLine(fromLine) == visualLine(toLine); - var leftEnd = drawForLine(sFrom.line, sFrom.ch, singleVLine ? fromLine.text.length + 1 : null).end; - var rightStart = drawForLine(sTo.line, singleVLine ? 0 : null, sTo.ch).start; - if (singleVLine) { - if (leftEnd.top < rightStart.top - 2) { - add(leftEnd.right, leftEnd.top, null, leftEnd.bottom); - add(leftSide, rightStart.top, rightStart.left, rightStart.bottom); - } else { - add(leftEnd.right, leftEnd.top, rightStart.left - leftEnd.right, leftEnd.bottom); - } - } - if (leftEnd.bottom < rightStart.top) { add(leftSide, leftEnd.bottom, null, rightStart.top); } - } + var findIndex$2 = findIndex$1; - output.appendChild(fragment); - } + var findIndex$3 = findIndex$2; - // Cursor-blinking - function restartBlink(cm) { - if (!cm.state.focused) { return } - var display = cm.display; - clearInterval(display.blinker); - var on = true; - display.cursorDiv.style.visibility = ""; - if (cm.options.cursorBlinkRate > 0) { - display.blinker = setInterval(function () { - if (!cm.hasFocus()) { onBlur(cm); } - display.cursorDiv.style.visibility = (on = !on) ? "" : "hidden"; - }, cm.options.cursorBlinkRate); - } - else if (cm.options.cursorBlinkRate < 0) { display.cursorDiv.style.visibility = "hidden"; } - } + var HAS_SPECIES_SUPPORT$2 = arrayMethodHasSpeciesSupport('splice'); - function ensureFocus(cm) { - if (!cm.state.focused) { cm.display.input.focus(); onFocus(cm); } - } + var TypeError$f = global_1.TypeError; + var max$3 = Math.max; + var min$3 = Math.min; + var MAX_SAFE_INTEGER$3 = 0x1FFFFFFFFFFFFF; + var MAXIMUM_ALLOWED_LENGTH_EXCEEDED = 'Maximum allowed length exceeded'; - function delayBlurEvent(cm) { - cm.state.delayingBlurEvent = true; - setTimeout(function () { - if (cm.state.delayingBlurEvent) { - cm.state.delayingBlurEvent = false; - onBlur(cm); - } - }, 100); - } + // `Array.prototype.splice` method + // https://tc39.es/ecma262/#sec-array.prototype.splice + // with adding support of @@species + _export({ target: 'Array', proto: true, forced: !HAS_SPECIES_SUPPORT$2 }, { + splice: function splice(start, deleteCount /* , ...items */) { + var O = toObject(this); + var len = lengthOfArrayLike(O); + var actualStart = toAbsoluteIndex(start, len); + var argumentsLength = arguments.length; + var insertCount, actualDeleteCount, A, k, from, to; + if (argumentsLength === 0) { + insertCount = actualDeleteCount = 0; + } else if (argumentsLength === 1) { + insertCount = 0; + actualDeleteCount = len - actualStart; + } else { + insertCount = argumentsLength - 2; + actualDeleteCount = min$3(max$3(toIntegerOrInfinity(deleteCount), 0), len - actualStart); + } + if (len + insertCount - actualDeleteCount > MAX_SAFE_INTEGER$3) { + throw TypeError$f(MAXIMUM_ALLOWED_LENGTH_EXCEEDED); + } + A = arraySpeciesCreate(O, actualDeleteCount); + for (k = 0; k < actualDeleteCount; k++) { + from = actualStart + k; + if (from in O) createProperty(A, k, O[from]); + } + A.length = actualDeleteCount; + if (insertCount < actualDeleteCount) { + for (k = actualStart; k < len - actualDeleteCount; k++) { + from = k + actualDeleteCount; + to = k + insertCount; + if (from in O) O[to] = O[from]; + else delete O[to]; + } + for (k = len; k > len - actualDeleteCount + insertCount; k--) delete O[k - 1]; + } else if (insertCount > actualDeleteCount) { + for (k = len - actualDeleteCount; k > actualStart; k--) { + from = k + actualDeleteCount - 1; + to = k + insertCount - 1; + if (from in O) O[to] = O[from]; + else delete O[to]; + } + } + for (k = 0; k < insertCount; k++) { + O[k + actualStart] = arguments[k + 2]; + } + O.length = len - actualDeleteCount + insertCount; + return A; + } + }); - function onFocus(cm, e) { - if (cm.state.delayingBlurEvent) { cm.state.delayingBlurEvent = false; } - - if (cm.options.readOnly == "nocursor") { return } - if (!cm.state.focused) { - signal(cm, "focus", cm, e); - cm.state.focused = true; - addClass(cm.display.wrapper, "CodeMirror-focused"); - // This test prevents this from firing when a context - // menu is closed (since the input reset would kill the - // select-all detection hack) - if (!cm.curOp && cm.display.selForContextMenu != cm.doc.sel) { - cm.display.input.reset(); - if (webkit) { setTimeout(function () { return cm.display.input.reset(true); }, 20); } // Issue #1730 - } - cm.display.input.receivedFocus(); - } - restartBlink(cm); - } - function onBlur(cm, e) { - if (cm.state.delayingBlurEvent) { return } + var splice$1 = entryVirtual('Array').splice; - if (cm.state.focused) { - signal(cm, "blur", cm, e); - cm.state.focused = false; - rmClass(cm.display.wrapper, "CodeMirror-focused"); - } - clearInterval(cm.display.blinker); - setTimeout(function () { if (!cm.state.focused) { cm.display.shift = false; } }, 150); - } + var ArrayPrototype$8 = Array.prototype; - // Read the actual heights of the rendered lines, and update their - // stored heights to match. - function updateHeightsInViewport(cm) { - var display = cm.display; - var prevBottom = display.lineDiv.offsetTop; - for (var i = 0; i < display.view.length; i++) { - var cur = display.view[i], wrapping = cm.options.lineWrapping; - var height = (void 0), width = 0; - if (cur.hidden) { continue } - if (ie && ie_version < 8) { - var bot = cur.node.offsetTop + cur.node.offsetHeight; - height = bot - prevBottom; - prevBottom = bot; - } else { - var box = cur.node.getBoundingClientRect(); - height = box.bottom - box.top; - // Check that lines don't extend past the right of the current - // editor width - if (!wrapping && cur.text.firstChild) { width = cur.text.firstChild.getBoundingClientRect().right - box.left - 1; } - } - var diff = cur.line.height - height; - if (diff > .005 || diff < -.005) { - updateLineHeight(cur.line, height); - updateWidgetHeight(cur.line); - if (cur.rest) { - for (var j = 0; j < cur.rest.length; j++) { updateWidgetHeight(cur.rest[j]); } - } - } - if (width > cm.display.sizerWidth) { - var chWidth = Math.ceil(width / charWidth(cm.display)); - if (chWidth > cm.display.maxLineLength) { - cm.display.maxLineLength = chWidth; - cm.display.maxLine = cur.line; - cm.display.maxLineChanged = true; - } - } - } - } + var splice$2 = function (it) { + var own = it.splice; + return it === ArrayPrototype$8 || (objectIsPrototypeOf(ArrayPrototype$8, it) && own === ArrayPrototype$8.splice) ? splice$1 : own; + }; - // Read and store the height of line widgets associated with the - // given line. - function updateWidgetHeight(line) { - if (line.widgets) { - for (var i = 0; i < line.widgets.length; ++i) { - var w = line.widgets[i], parent = w.node.parentNode; - if (parent) { w.height = parent.offsetHeight; } - } - } - } + var splice$3 = splice$2; - // Compute the lines that are visible in a given viewport (defaults - // the the current scroll position). viewport may contain top, - // height, and ensure (see op.scrollToPos) properties. - function visibleLines(display, doc, viewport) { - var top = viewport && viewport.top != null ? Math.max(0, viewport.top) : display.scroller.scrollTop; - top = Math.floor(top - paddingTop(display)); - var bottom = viewport && viewport.bottom != null ? viewport.bottom : top + display.wrapper.clientHeight; - - var from = lineAtHeight(doc, top), to = lineAtHeight(doc, bottom); - // Ensure is a {from: {line, ch}, to: {line, ch}} object, and - // forces those lines into the viewport (if possible). - if (viewport && viewport.ensure) { - var ensureFrom = viewport.ensure.from.line, ensureTo = viewport.ensure.to.line; - if (ensureFrom < from) { - from = ensureFrom; - to = lineAtHeight(doc, heightAtLine(getLine(doc, ensureFrom)) + display.wrapper.clientHeight); - } else if (Math.min(ensureTo, doc.lastLine()) >= to) { - from = lineAtHeight(doc, heightAtLine(getLine(doc, ensureTo)) - display.wrapper.clientHeight); - to = ensureTo; - } - } - return { from: from, to: Math.max(to, from + 1) } - } + var splice$4 = splice$3; - // SCROLLING THINGS INTO VIEW - - // If an editor sits on the top or bottom of the window, partially - // scrolled out of view, this ensures that the cursor is visible. - function maybeScrollWindow(cm, rect) { - if (signalDOMEvent(cm, "scrollCursorIntoView")) { return } - - var display = cm.display, box = display.sizer.getBoundingClientRect(), doScroll = null; - if (rect.top + box.top < 0) { doScroll = true; } - else if (rect.bottom + box.top > (window.innerHeight || document.documentElement.clientHeight)) { doScroll = false; } - if (doScroll != null && !phantom) { - var scrollNode = elt("div", "\u200b", null, ("position: absolute;\n top: " + (rect.top - display.viewOffset - paddingTop(cm.display)) + "px;\n height: " + (rect.bottom - rect.top + scrollGap(cm) + display.barHeight) + "px;\n left: " + (rect.left) + "px; width: " + (Math.max(2, rect.right - rect.left)) + "px;")); - cm.display.lineSpace.appendChild(scrollNode); - scrollNode.scrollIntoView(doScroll); - cm.display.lineSpace.removeChild(scrollNode); - } - } + /** + * Copyright (C) 2021 THL A29 Limited, a Tencent company. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ - // Scroll a given position into view (immediately), verifying that - // it actually became visible (as line heights are accurately - // measured, the position of something may 'drift' during drawing). - function scrollPosIntoView(cm, pos, end, margin) { - if (margin == null) { margin = 0; } - var rect; - if (!cm.options.lineWrapping && pos == end) { - // Set pos and end to the cursor positions around the character pos sticks to - // If pos.sticky == "before", that is around pos.ch - 1, otherwise around pos.ch - // If pos == Pos(_, 0, "before"), pos and end are unchanged - pos = pos.ch ? Pos(pos.line, pos.sticky == "before" ? pos.ch - 1 : pos.ch, "after") : pos; - end = pos.sticky == "before" ? Pos(pos.line, pos.ch + 1, "before") : pos; - } - for (var limit = 0; limit < 5; limit++) { - var changed = false; - var coords = cursorCoords(cm, pos); - var endCoords = !end || end == pos ? coords : cursorCoords(cm, end); - rect = { - left: Math.min(coords.left, endCoords.left), - top: Math.min(coords.top, endCoords.top) - margin, - right: Math.max(coords.left, endCoords.left), - bottom: Math.max(coords.bottom, endCoords.bottom) + margin - }; - var scrollPos = calculateScrollPos(cm, rect); - var startTop = cm.doc.scrollTop, startLeft = cm.doc.scrollLeft; - if (scrollPos.scrollTop != null) { - updateScrollTop(cm, scrollPos.scrollTop); - if (Math.abs(cm.doc.scrollTop - startTop) > 1) { changed = true; } - } - if (scrollPos.scrollLeft != null) { - setScrollLeft(cm, scrollPos.scrollLeft); - if (Math.abs(cm.doc.scrollLeft - startLeft) > 1) { changed = true; } - } - if (!changed) { break } - } - return rect - } + /** + * @typedef {import('~types/syntax').HookType} HookType + * @typedef {import('~types/syntax').HookTypesList} HookTypesList + * @typedef {import('~types/syntax').EditorConfig} EditorConfig + * @typedef {import('~types/syntax').HookRegexpRule} HookRegexpRule + */ - // Scroll a given set of coordinates into view (immediately). - function scrollIntoView(cm, rect) { - var scrollPos = calculateScrollPos(cm, rect); - if (scrollPos.scrollTop != null) { updateScrollTop(cm, scrollPos.scrollTop); } - if (scrollPos.scrollLeft != null) { setScrollLeft(cm, scrollPos.scrollLeft); } - } + /** @type {boolean} */ + var isMathjaxConfig = false; + /** + * @type {HookTypesList} + */ - // Calculate a new scroll position needed to scroll the given - // rectangle into view. Returns an object with scrollTop and - // scrollLeft properties. When these are undefined, the - // vertical/horizontal position does not need to be adjusted. - function calculateScrollPos(cm, rect) { - var display = cm.display, snapMargin = textHeight(cm.display); - if (rect.top < 0) { rect.top = 0; } - var screentop = cm.curOp && cm.curOp.scrollTop != null ? cm.curOp.scrollTop : display.scroller.scrollTop; - var screen = displayHeight(cm), result = {}; - if (rect.bottom - rect.top > screen) { rect.bottom = rect.top + screen; } - var docBottom = cm.doc.height + paddingVert(display); - var atTop = rect.top < snapMargin, atBottom = rect.bottom > docBottom - snapMargin; - if (rect.top < screentop) { - result.scrollTop = atTop ? 0 : rect.top; - } else if (rect.bottom > screentop + screen) { - var newTop = Math.min(rect.top, (atBottom ? docBottom : rect.bottom) - screen); - if (newTop != screentop) { result.scrollTop = newTop; } - } + var HOOKS_TYPE_LIST = { + SEN: 'sentence', + PAR: 'paragraph', + DEFAULT: 'sentence' + }; - var gutterSpace = cm.options.fixedGutter ? 0 : display.gutters.offsetWidth; - var screenleft = cm.curOp && cm.curOp.scrollLeft != null ? cm.curOp.scrollLeft : display.scroller.scrollLeft - gutterSpace; - var screenw = displayWidth(cm) - display.gutters.offsetWidth; - var tooWide = rect.right - rect.left > screenw; - if (tooWide) { rect.right = rect.left + screenw; } - if (rect.left < 10) { result.scrollLeft = 0; } - else if (rect.left < screenleft) { result.scrollLeft = Math.max(0, rect.left + gutterSpace - (tooWide ? 0 : 10)); } - else if (rect.right > screenw + screenleft - 3) { result.scrollLeft = rect.right + (tooWide ? 0 : 10) - screenw; } - return result - } + var SyntaxBase = /*#__PURE__*/function () { + /** + * @static + * @type {string} + */ + + /** + * @static + * @type {HookType} + */ + + /** + * @protected + * @type {import('../Engine').default} + */ + + /** + * @constructor + * @param {Partial} editorConfig + */ + function SyntaxBase(editorConfig) { + _classCallCheck(this, SyntaxBase); + + _defineProperty(this, "$engine", void 0); + + _defineProperty(this, "$locale", void 0); + + // editorConfig.pageHooks: 已实例化的页面级hook + // editorConfig.syntaxOptions: 当前Hook的用户配置 + // editorConfig.externals: 第三方库 + this.RULE = this.rule(editorConfig); + } + + _createClass(SyntaxBase, [{ + key: "getType", + value: function getType() { + return ( + /** @type {typeof SyntaxBase} */ + this.constructor.HOOK_TYPE || HOOKS_TYPE_LIST.DEFAULT + ); + } + }, { + key: "getName", + value: function getName() { + return ( + /** @type {typeof SyntaxBase} */ + this.constructor.HOOK_NAME + ); + } + }, { + key: "afterInit", + value: function afterInit(callback) { + if (typeof callback === 'function') { + callback(); + } + } + }, { + key: "setLocale", + value: function setLocale(locale) { + this.$locale = locale; + } + /** + * 生命周期函数 + * @param {string} str 待处理的markdown文本 + * @returns {string} 处理后的文本,一般为html + */ + + }, { + key: "beforeMakeHtml", + value: function beforeMakeHtml(str) { + return str; + } + /** + * 生命周期函数 + * @param {string} str 待处理的markdown文本 + * @returns {string} 处理后的文本,一般为html + */ + + }, { + key: "makeHtml", + value: function makeHtml(str) { + return str; + } + /** + * 生命周期函数 + * @param {string} str 待处理的markdown文本 + * @returns {string} 处理后的文本,一般为html + */ + + }, { + key: "afterMakeHtml", + value: function afterMakeHtml(str) { + return str; + } // getMakeHtml() { + // return this.makeHtml || false; + // } + + /** + * + * @param {KeyboardEvent} e 触发事件 + * @param {*} str + */ + + }, { + key: "onKeyDown", + value: function onKeyDown(e, str) {} + }, { + key: "getOnKeyDown", + value: function getOnKeyDown() { + return this.onKeyDown || false; + } + }, { + key: "getAttributesTest", + value: function getAttributesTest() { + return /^(color|fontSize|font-size|id|title|class|target|underline|line-through|overline|sub|super)$/; + } + /** + * + * @param {string} attr + * @param {() => {}} func 回调函数 + */ + + }, { + key: "$testAttributes", + value: function $testAttributes(attr, func) { + if (this.getAttributesTest().test(attr)) { + func(); + } + } + /** + * 提取属性 + * @param {string} str 待提取字符串 + * @returns {{attrs: Record; str: string}} + */ + + }, { + key: "getAttributes", + value: function getAttributes(str) { + var ret = { + attrs: {}, + str: str + }; // if(/(?<=[^\\]){([a-zA-Z-]+=[0-9a-z-]+(?=;|\||}))+}$/.test(str)) { + // str.match(/(?<=[^\\]){[^\n]+?}$/)[0] + // .match(/([a-zA-Z-]+=[0-9a-z-]+(?=;|\||}))+/g) + // .foreach((one) => { + // one = one.split('='); + // this._testAttributes(one[0], ()=>{ + // ret.attrs[one[0]] = one[1]; + // }); + // }); + // ret.str = str.replace(/(?<=[^\\]){[^\n]+?}$/, ''); + // } + + return ret; + } + }, { + key: "test", + value: + /** + * 测试输入的字符串是否匹配当前Hook规则 + * @param {string} str 待匹配文本 + * @returns {boolean} + */ + function test(str) { + return this.RULE.reg ? this.RULE.reg.test(str) : false; + } + /** + * + * @param {Partial} editorConfig + * @returns {HookRegexpRule} + */ + + }, { + key: "rule", + value: function rule(editorConfig) { + return { + begin: '', + end: '', + content: '', + reg: new RegExp('') + }; + } + }, { + key: "mounted", + value: function mounted() {// console.log('base mounted'); + } + }], [{ + key: "getMathJaxConfig", + value: function getMathJaxConfig() { + return isMathjaxConfig; + } + /** + * + * @param {boolean} version 指定mathJax是否使用MathJax + */ + + }, { + key: "setMathJaxConfig", + value: function setMathJaxConfig(version) { + isMathjaxConfig = version; + } + }]); + + return SyntaxBase; + }(); - // Store a relative adjustment to the scroll position in the current - // operation (to be applied when the operation finishes). - function addToScrollTop(cm, top) { - if (top == null) { return } - resolveScrollToPos(cm); - cm.curOp.scrollTop = (cm.curOp.scrollTop == null ? cm.doc.scrollTop : cm.curOp.scrollTop) + top; - } + _defineProperty(SyntaxBase, "HOOK_NAME", 'default'); - // Make sure that at the end of the operation the current cursor is - // shown. - function ensureCursorVisible(cm) { - resolveScrollToPos(cm); - var cur = cm.getCursor(); - cm.curOp.scrollToPos = { from: cur, to: cur, margin: cm.options.cursorScrollMargin }; - } + _defineProperty(SyntaxBase, "HOOK_TYPE", HOOKS_TYPE_LIST.DEFAULT); - function scrollToCoords(cm, x, y) { - if (x != null || y != null) { resolveScrollToPos(cm); } - if (x != null) { cm.curOp.scrollLeft = x; } - if (y != null) { cm.curOp.scrollTop = y; } - } + var $map = arrayIteration.map; - function scrollToRange(cm, range) { - resolveScrollToPos(cm); - cm.curOp.scrollToPos = range; - } - // When an operation has its scrollToPos property set, and another - // scroll action is applied before the end of the operation, this - // 'simulates' scrolling that position into view in a cheap way, so - // that the effect of intermediate scroll commands is not ignored. - function resolveScrollToPos(cm) { - var range = cm.curOp.scrollToPos; - if (range) { - cm.curOp.scrollToPos = null; - var from = estimateCoords(cm, range.from), to = estimateCoords(cm, range.to); - scrollToCoordsRange(cm, from, to, range.margin); - } - } + var HAS_SPECIES_SUPPORT$3 = arrayMethodHasSpeciesSupport('map'); - function scrollToCoordsRange(cm, from, to, margin) { - var sPos = calculateScrollPos(cm, { - left: Math.min(from.left, to.left), - top: Math.min(from.top, to.top) - margin, - right: Math.max(from.right, to.right), - bottom: Math.max(from.bottom, to.bottom) + margin - }); - scrollToCoords(cm, sPos.scrollLeft, sPos.scrollTop); - } + // `Array.prototype.map` method + // https://tc39.es/ecma262/#sec-array.prototype.map + // with adding support of @@species + _export({ target: 'Array', proto: true, forced: !HAS_SPECIES_SUPPORT$3 }, { + map: function map(callbackfn /* , thisArg */) { + return $map(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined); + } + }); - // Sync the scrollable area and scrollbars, ensure the viewport - // covers the visible area. - function updateScrollTop(cm, val) { - if (Math.abs(cm.doc.scrollTop - val) < 2) { return } - if (!gecko) { updateDisplaySimple(cm, { top: val }); } - setScrollTop(cm, val, true); - if (gecko) { updateDisplaySimple(cm); } - startWorker(cm, 100); - } + var map = entryVirtual('Array').map; - function setScrollTop(cm, val, forceScroll) { - val = Math.max(0, Math.min(cm.display.scroller.scrollHeight - cm.display.scroller.clientHeight, val)); - if (cm.display.scroller.scrollTop == val && !forceScroll) { return } - cm.doc.scrollTop = val; - cm.display.scrollbars.setScrollTop(val); - if (cm.display.scroller.scrollTop != val) { cm.display.scroller.scrollTop = val; } - } + var ArrayPrototype$9 = Array.prototype; - // Sync scroller and scrollbar, ensure the gutter elements are - // aligned. - function setScrollLeft(cm, val, isScroller, forceScroll) { - val = Math.max(0, Math.min(val, cm.display.scroller.scrollWidth - cm.display.scroller.clientWidth)); - if ((isScroller ? val == cm.doc.scrollLeft : Math.abs(cm.doc.scrollLeft - val) < 2) && !forceScroll) { return } - cm.doc.scrollLeft = val; - alignHorizontally(cm); - if (cm.display.scroller.scrollLeft != val) { cm.display.scroller.scrollLeft = val; } - cm.display.scrollbars.setScrollLeft(val); - } + var map$1 = function (it) { + var own = it.map; + return it === ArrayPrototype$9 || (objectIsPrototypeOf(ArrayPrototype$9, it) && own === ArrayPrototype$9.map) ? map : own; + }; - // SCROLLBARS - - // Prepare DOM reads needed to update the scrollbars. Done in one - // shot to minimize update/measure roundtrips. - function measureForScrollbars(cm) { - var d = cm.display, gutterW = d.gutters.offsetWidth; - var docH = Math.round(cm.doc.height + paddingVert(cm.display)); - return { - clientHeight: d.scroller.clientHeight, - viewHeight: d.wrapper.clientHeight, - scrollWidth: d.scroller.scrollWidth, clientWidth: d.scroller.clientWidth, - viewWidth: d.wrapper.clientWidth, - barLeft: cm.options.fixedGutter ? gutterW : 0, - docHeight: docH, - scrollHeight: docH + scrollGap(cm) + d.barHeight, - nativeBarWidth: d.nativeBarWidth, - gutterWidth: gutterW - } - } + var map$2 = map$1; - var NativeScrollbars = function (place, scroll, cm) { - this.cm = cm; - var vert = this.vert = elt("div", [elt("div", null, null, "min-width: 1px")], "CodeMirror-vscrollbar"); - var horiz = this.horiz = elt("div", [elt("div", null, null, "height: 100%; min-height: 1px")], "CodeMirror-hscrollbar"); - vert.tabIndex = horiz.tabIndex = -1; - place(vert); place(horiz); + var map$3 = map$2; - on(vert, "scroll", function () { - if (vert.clientHeight) { scroll(vert.scrollTop, "vertical"); } - }); - on(horiz, "scroll", function () { - if (horiz.clientWidth) { scroll(horiz.scrollLeft, "horizontal"); } - }); + /** + * Copyright (C) 2021 THL A29 Limited, a Tencent company. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ - this.checkedZeroWidth = false; - // Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8). - if (ie && ie_version < 8) { this.horiz.style.minHeight = this.vert.style.minWidth = "18px"; } - }; + /** + * 为段落前加换行符 + * @param {string} match 匹配全文 + * @param {string} processedContent 加入的内容 + */ + function prependLineFeedForParagraph(match, processedContent) { + var canNestedInList = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; - NativeScrollbars.prototype.update = function (measure) { - var needsH = measure.scrollWidth > measure.clientWidth + 1; - var needsV = measure.scrollHeight > measure.clientHeight + 1; - var sWidth = measure.nativeBarWidth; - - if (needsV) { - this.vert.style.display = "block"; - this.vert.style.bottom = needsH ? sWidth + "px" : "0"; - var totalHeight = measure.viewHeight - (needsH ? sWidth : 0); - // A bug in IE8 can cause this value to be negative, so guard it. - this.vert.firstChild.style.height = - Math.max(0, measure.scrollHeight - measure.clientHeight + totalHeight) + "px"; - } else { - this.vert.style.display = ""; - this.vert.firstChild.style.height = "0"; - } + if (!/^\n/.test(match)) { + return processedContent; + } - if (needsH) { - this.horiz.style.display = "block"; - this.horiz.style.right = needsV ? sWidth + "px" : "0"; - this.horiz.style.left = measure.barLeft + "px"; - var totalWidth = measure.viewWidth - measure.barLeft - (needsV ? sWidth : 0); - this.horiz.firstChild.style.width = - Math.max(0, measure.scrollWidth - measure.clientWidth + totalWidth) + "px"; - } else { - this.horiz.style.display = ""; - this.horiz.firstChild.style.width = "0"; - } + if (canNestedInList) { + var _match$match$0$length, _match$match, _match$match$; - if (!this.checkedZeroWidth && measure.clientHeight > 0) { - if (sWidth == 0) { this.zeroWidthHack(); } - this.checkedZeroWidth = true; - } + var leadingLinesCount = (_match$match$0$length = (_match$match = match.match(/^\n+/g)) === null || _match$match === void 0 ? void 0 : (_match$match$ = _match$match[0]) === null || _match$match$ === void 0 ? void 0 : _match$match$.length) !== null && _match$match$0$length !== void 0 ? _match$match$0$length : 0; // 前置换行符数量大于2时,补充两个换行符,否则只补充一个 - return { right: needsV ? sWidth : 0, bottom: needsH ? sWidth : 0 } - }; + if (leadingLinesCount > 1) { + return "\n\n".concat(processedContent); + } - NativeScrollbars.prototype.setScrollLeft = function (pos) { - if (this.horiz.scrollLeft != pos) { this.horiz.scrollLeft = pos; } - if (this.disableHoriz) { this.enableZeroWidthBar(this.horiz, this.disableHoriz, "horiz"); } - }; + return "\n".concat(processedContent); + } - NativeScrollbars.prototype.setScrollTop = function (pos) { - if (this.vert.scrollTop != pos) { this.vert.scrollTop = pos; } - if (this.disableVert) { this.enableZeroWidthBar(this.vert, this.disableVert, "vert"); } - }; + return "\n\n".concat(processedContent); + } + /** + * 计算段落所占行数,必须传入通过 prependLineFeedForParagraph 方法处理后的内容,才能计算准确 + * @param {string} preLinesMatch 前置匹配行 + * @param {number} contentLines 实际内容行数 + */ - NativeScrollbars.prototype.zeroWidthHack = function () { - var w = mac && !mac_geMountainLion ? "12px" : "18px"; - this.horiz.style.height = this.vert.style.width = w; - this.horiz.style.pointerEvents = this.vert.style.pointerEvents = "none"; - this.disableHoriz = new Delayed; - this.disableVert = new Delayed; - }; + function calculateLinesOfParagraph(preLinesMatch, contentLines) { + var preLineCount = (preLinesMatch.match(/\n/g) || []).length; // 前置行匹配文本为空,说明是全文开头 + // 非全文开头前面必有两个从 prependLineFeed 方法新增加的换行符 - NativeScrollbars.prototype.enableZeroWidthBar = function (bar, delay, type) { - bar.style.pointerEvents = "auto"; - function maybeDisable() { - // To find out whether the scrollbar is still visible, we - // check whether the element under the pixel in the bottom - // right corner of the scrollbar box is the scrollbar box - // itself (when the bar is still visible) or its filler child - // (when the bar is hidden). If it is still visible, we keep - // it enabled, if it's hidden, we disable pointer events. - var box = bar.getBoundingClientRect(); - var elt = type == "vert" ? document.elementFromPoint(box.right - 1, (box.top + box.bottom) / 2) - : document.elementFromPoint((box.right + box.left) / 2, box.bottom - 1); - if (elt != bar) { bar.style.pointerEvents = "none"; } - else { delay.set(1000, maybeDisable); } - } - delay.set(1000, maybeDisable); - }; + if (preLinesMatch !== '') { + preLineCount -= 2; + } - NativeScrollbars.prototype.clear = function () { - var parent = this.horiz.parentNode; - parent.removeChild(this.horiz); - parent.removeChild(this.vert); - }; + return preLineCount + contentLines; + } - var NullScrollbars = function () { }; - - NullScrollbars.prototype.update = function () { return { bottom: 0, right: 0 } }; - NullScrollbars.prototype.setScrollLeft = function () { }; - NullScrollbars.prototype.setScrollTop = function () { }; - NullScrollbars.prototype.clear = function () { }; - - function updateScrollbars(cm, measure) { - if (!measure) { measure = measureForScrollbars(cm); } - var startWidth = cm.display.barWidth, startHeight = cm.display.barHeight; - updateScrollbarsInner(cm, measure); - for (var i = 0; i < 4 && startWidth != cm.display.barWidth || startHeight != cm.display.barHeight; i++) { - if (startWidth != cm.display.barWidth && cm.options.lineWrapping) { updateHeightsInViewport(cm); } - updateScrollbarsInner(cm, measureForScrollbars(cm)); - startWidth = cm.display.barWidth; startHeight = cm.display.barHeight; - } - } + var isArray$8 = isArray$3; - // Re-synchronize the fake scrollbars with the actual size of the - // content. - function updateScrollbarsInner(cm, measure) { - var d = cm.display; - var sizes = d.scrollbars.update(measure); - - d.sizer.style.paddingRight = (d.barWidth = sizes.right) + "px"; - d.sizer.style.paddingBottom = (d.barHeight = sizes.bottom) + "px"; - d.heightForcer.style.borderBottom = sizes.bottom + "px solid transparent"; - - if (sizes.right && sizes.bottom) { - d.scrollbarFiller.style.display = "block"; - d.scrollbarFiller.style.height = sizes.bottom + "px"; - d.scrollbarFiller.style.width = sizes.right + "px"; - } else { d.scrollbarFiller.style.display = ""; } - if (sizes.bottom && cm.options.coverGutterNextToScrollbar && cm.options.fixedGutter) { - d.gutterFiller.style.display = "block"; - d.gutterFiller.style.height = sizes.bottom + "px"; - d.gutterFiller.style.width = measure.gutterWidth + "px"; - } else { d.gutterFiller.style.display = ""; } - } + /** + * Copyright (C) 2021 THL A29 Limited, a Tencent company. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ - var scrollbarModel = { "native": NativeScrollbars, "null": NullScrollbars }; + /** + * 用于lodash.mergeWith的customizer + * @param {any} objValue + * @param {any} srcValue + * @returns + */ + function customizer(objValue, srcValue) { + if (isArray$8(srcValue)) { + return srcValue; + } + } + /** + * 检查本地有没有值 + * @param {string} key + */ - function initScrollbars(cm) { - if (cm.display.scrollbars) { - cm.display.scrollbars.clear(); - if (cm.display.scrollbars.addClass) { rmClass(cm.display.wrapper, cm.display.scrollbars.addClass); } - } + function testKeyInLocal(key) { + if (typeof localStorage !== 'undefined') { + return localStorage.getItem("cherry-".concat(key)) !== null; + } - cm.display.scrollbars = new scrollbarModel[cm.options.scrollbarStyle](function (node) { - cm.display.wrapper.insertBefore(node, cm.display.scrollbarFiller); - // Prevent clicks in the scrollbars from killing focus - on(node, "mousedown", function () { - if (cm.state.focused) { setTimeout(function () { return cm.display.input.focus(); }, 0); } - }); - node.setAttribute("cm-not-content", "true"); - }, function (pos, axis) { - if (axis == "horizontal") { setScrollLeft(cm, pos); } - else { updateScrollTop(cm, pos); } - }, cm); - if (cm.display.scrollbars.addClass) { addClass(cm.display.wrapper, cm.display.scrollbars.addClass); } - } + return false; + } + /** + * 保存是否经典换行 + * @param {boolean} isClassicBr + */ - // Operations are used to wrap a series of changes to the editor - // state in such a way that each change won't have to update the - // cursor and display (which would be awkward, slow, and - // error-prone). Instead, display updates are batched and then all - // combined and executed at once. - - var nextOpId = 0; - // Start a new operation. - function startOperation(cm) { - cm.curOp = { - cm: cm, - viewChanged: false, // Flag that indicates that lines might need to be redrawn - startHeight: cm.doc.height, // Used to detect need to update scrollbar - forceUpdate: false, // Used to force a redraw - updateInput: 0, // Whether to reset the input textarea - typing: false, // Whether this reset should be careful to leave existing text (for compositing) - changeObjs: null, // Accumulated changes, for firing change events - cursorActivityHandlers: null, // Set of handlers to fire cursorActivity on - cursorActivityCalled: 0, // Tracks which cursorActivity handlers have been called already - selectionChanged: false, // Whether the selection needs to be redrawn - updateMaxLine: false, // Set when the widest line needs to be determined anew - scrollLeft: null, scrollTop: null, // Intermediate scroll position, not pushed to DOM yet - scrollToPos: null, // Used to scroll to a specific position - focus: false, - id: ++nextOpId // Unique ID - }; - pushOperation(cm.curOp); - } + function saveIsClassicBrToLocal(isClassicBr) { + if (typeof localStorage !== 'undefined') { + localStorage.setItem('cherry-classicBr', isClassicBr ? 'true' : 'false'); + } + } + /** + * 是否经典换行 + */ - // Finish an operation, updating the display and signalling delayed events - function endOperation(cm) { - var op = cm.curOp; - if (op) { - finishOperation(op, function (group) { - for (var i = 0; i < group.ops.length; i++) { group.ops[i].cm.curOp = null; } - endOperations(group); - }); - } - } + function getIsClassicBrFromLocal() { + var ret = 'false'; - // The DOM updates done when an operation finishes are batched so - // that the minimum number of relayouts are required. - function endOperations(group) { - var ops = group.ops; - for (var i = 0; i < ops.length; i++) // Read DOM - { endOperation_R1(ops[i]); } - for (var i$1 = 0; i$1 < ops.length; i$1++) // Write DOM (maybe) - { endOperation_W1(ops[i$1]); } - for (var i$2 = 0; i$2 < ops.length; i$2++) // Read DOM - { endOperation_R2(ops[i$2]); } - for (var i$3 = 0; i$3 < ops.length; i$3++) // Write DOM (maybe) - { endOperation_W2(ops[i$3]); } - for (var i$4 = 0; i$4 < ops.length; i$4++) // Read DOM - { endOperation_finish(ops[i$4]); } - } + if (typeof localStorage !== 'undefined') { + ret = localStorage.getItem('cherry-classicBr'); + } - function endOperation_R1(op) { - var cm = op.cm, display = cm.display; - maybeClipScrollbars(cm); - if (op.updateMaxLine) { findMaxLine(cm); } - - op.mustUpdate = op.viewChanged || op.forceUpdate || op.scrollTop != null || - op.scrollToPos && (op.scrollToPos.from.line < display.viewFrom || - op.scrollToPos.to.line >= display.viewTo) || - display.maxLineChanged && cm.options.lineWrapping; - op.update = op.mustUpdate && - new DisplayUpdate(cm, op.mustUpdate && { top: op.scrollTop, ensure: op.scrollToPos }, op.forceUpdate); - } + return ret === 'true'; + } + /** + * 保存当前主题 + * @param {string} theme + */ - function endOperation_W1(op) { - op.updatedDisplay = op.mustUpdate && updateDisplayIfNeeded(op.cm, op.update); - } + function saveThemeToLocal(theme) { + if (typeof localStorage !== 'undefined') { + localStorage.setItem('cherry-theme', theme); + } + } + /** + * 获取当前主题 + * @returns {string} 主题名 + */ - function endOperation_R2(op) { - var cm = op.cm, display = cm.display; - if (op.updatedDisplay) { updateHeightsInViewport(cm); } - - op.barMeasure = measureForScrollbars(cm); - - // If the max line changed since it was last measured, measure it, - // and ensure the document's width matches it. - // updateDisplay_W2 will use these properties to do the actual resizing - if (display.maxLineChanged && !cm.options.lineWrapping) { - op.adjustWidthTo = measureChar(cm, display.maxLine, display.maxLine.text.length).left + 3; - cm.display.sizerWidth = op.adjustWidthTo; - op.barMeasure.scrollWidth = - Math.max(display.scroller.clientWidth, display.sizer.offsetLeft + op.adjustWidthTo + scrollGap(cm) + cm.display.barWidth); - op.maxScrollLeft = Math.max(0, display.sizer.offsetLeft + op.adjustWidthTo - displayWidth(cm)); - } - if (op.updatedDisplay || op.selectionChanged) { op.preparedSelection = display.input.prepareSelection(); } - } + function getThemeFromLocal() { + var fullClass = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + var ret = 'default'; - function endOperation_W2(op) { - var cm = op.cm; + if (typeof localStorage !== 'undefined') { + var localTheme = localStorage.getItem('cherry-theme'); - if (op.adjustWidthTo != null) { - cm.display.sizer.style.minWidth = op.adjustWidthTo + "px"; - if (op.maxScrollLeft < cm.doc.scrollLeft) { setScrollLeft(cm, Math.min(cm.display.scroller.scrollLeft, op.maxScrollLeft), true); } - cm.display.maxLineChanged = false; - } + if (localTheme) { + ret = localTheme; + } + } - var takeFocus = op.focus && op.focus == activeElt(); - if (op.preparedSelection) { cm.display.input.showSelection(op.preparedSelection, takeFocus); } - if (op.updatedDisplay || op.startHeight != cm.doc.height) { updateScrollbars(cm, op.barMeasure); } - if (op.updatedDisplay) { setDocumentHeight(cm, op.barMeasure); } + return fullClass ? "theme__".concat(ret) : ret; + } + /** + * 修改主题 + * @param {object} $cherry + * @param {string} theme 如果没有传theme,则从本地缓存里取 + */ - if (op.selectionChanged) { restartBlink(cm); } + function changeTheme($cherry) { + var theme = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; + var newTheme = (theme ? theme : getThemeFromLocal()).replace(/^.*theme__/, ''); + var newClass = " theme__".concat(newTheme); + $cherry.wrapperDom.className = $cherry.wrapperDom.className.replace(/ theme__[^ $]+?( |$)/g, '') + newClass; + $cherry.previewer.getDomContainer().className = $cherry.previewer.getDomContainer().className.replace(/ theme__[^ $]+?( |$)/g, '') + newClass; + saveThemeToLocal(newTheme); + } - if (cm.state.focused && op.updateInput) { cm.display.input.reset(op.typing); } - if (takeFocus) { ensureFocus(op.cm); } - } + var RangeError$1 = global_1.RangeError; + var fromCharCode = String.fromCharCode; + // eslint-disable-next-line es-x/no-string-fromcodepoint -- required for testing + var $fromCodePoint = String.fromCodePoint; + var join$1 = functionUncurryThis([].join); - function endOperation_finish(op) { - var cm = op.cm, display = cm.display, doc = cm.doc; + // length should be 1, old FF problem + var INCORRECT_LENGTH = !!$fromCodePoint && $fromCodePoint.length != 1; - if (op.updatedDisplay) { postUpdateDisplay(cm, op.update); } + // `String.fromCodePoint` method + // https://tc39.es/ecma262/#sec-string.fromcodepoint + _export({ target: 'String', stat: true, arity: 1, forced: INCORRECT_LENGTH }, { + // eslint-disable-next-line no-unused-vars -- required for `.length` + fromCodePoint: function fromCodePoint(x) { + var elements = []; + var length = arguments.length; + var i = 0; + var code; + while (length > i) { + code = +arguments[i++]; + if (toAbsoluteIndex(code, 0x10FFFF) !== code) throw RangeError$1(code + ' is not a valid code point'); + elements[i] = code < 0x10000 + ? fromCharCode(code) + : fromCharCode(((code -= 0x10000) >> 10) + 0xD800, code % 0x400 + 0xDC00); + } return join$1(elements, ''); + } + }); - // Abort mouse wheel delta measurement, when scrolling explicitly - if (display.wheelStartX != null && (op.scrollTop != null || op.scrollLeft != null || op.scrollToPos)) { display.wheelStartX = display.wheelStartY = null; } + var fromCodePoint = path.String.fromCodePoint; - // Propagate the scroll position to the actual DOM scroller - if (op.scrollTop != null) { setScrollTop(cm, op.scrollTop, op.forceScroll); } + var fromCodePoint$1 = fromCodePoint; - if (op.scrollLeft != null) { setScrollLeft(cm, op.scrollLeft, true, true); } - // If we need to scroll a specific position into view, do so. - if (op.scrollToPos) { - var rect = scrollPosIntoView(cm, clipPos(doc, op.scrollToPos.from), - clipPos(doc, op.scrollToPos.to), op.scrollToPos.margin); - maybeScrollWindow(cm, rect); - } + var fromCodePoint$2 = fromCodePoint$1; - // Fire events for markers that are hidden/unidden by editing or - // undoing - var hidden = op.maybeHiddenMarkers, unhidden = op.maybeUnhiddenMarkers; - if (hidden) { - for (var i = 0; i < hidden.length; ++i) { if (!hidden[i].lines.length) { signal(hidden[i], "hide"); } } - } - if (unhidden) { - for (var i$1 = 0; i$1 < unhidden.length; ++i$1) { if (unhidden[i$1].lines.length) { signal(unhidden[i$1], "unhide"); } } - } + var _context, _context2; - if (display.wrapper.offsetHeight) { doc.scrollTop = cm.display.scroller.scrollTop; } + function ownKeys$1(object, enumerableOnly) { var keys = keys$3(object); if (getOwnPropertySymbols$2) { var symbols = getOwnPropertySymbols$2(object); enumerableOnly && (symbols = filter$3(symbols).call(symbols, function (sym) { return getOwnPropertyDescriptor$3(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } - // Fire change events, and delayed event handlers - if (op.changeObjs) { signal(cm, "changes", cm, op.changeObjs); } - if (op.update) { op.update.finish(); } - } + function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var _context3, _context4; var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? forEach$3(_context3 = ownKeys$1(Object(source), !0)).call(_context3, function (key) { _defineProperty(target, key, source[key]); }) : getOwnPropertyDescriptors$2 ? defineProperties$2(target, getOwnPropertyDescriptors$2(source)) : forEach$3(_context4 = ownKeys$1(Object(source))).call(_context4, function (key) { defineProperty$5(target, key, getOwnPropertyDescriptor$3(source, key)); }); } return target; } - // Run the given function in an operation - function runInOp(cm, f) { - if (cm.curOp) { return f() } - startOperation(cm); - try { return f() } - finally { endOperation(cm); } - } - // Wraps a function in an operation. Returns the wrapped function. - function operation(cm, f) { - return function () { - if (cm.curOp) { return f.apply(cm, arguments) } - startOperation(cm); - try { return f.apply(cm, arguments) } - finally { endOperation(cm); } - } - } - // Used to add methods to editor and doc instances, wrapping them in - // operations. - function methodOp(f) { - return function () { - if (this.curOp) { return f.apply(this, arguments) } - startOperation(this); - try { return f.apply(this, arguments) } - finally { endOperation(this); } - } - } - function docMethodOp(f) { - return function () { - var cm = this.cm; - if (!cm || cm.curOp) { return f.apply(this, arguments) } - startOperation(cm); - try { return f.apply(this, arguments) } - finally { endOperation(cm); } - } - } + /** + * Copyright (C) 2021 THL A29 Limited, a Tencent company. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + var escapeMap = { + '<': '<', + '>': '>', + '&': '&', + '"': '"', + "'": ''' + }; + var unescapeMap = { + lt: '<', + gt: '>', + amp: '&', + quot: '"', + apos: "'" + }; // refs: https://www.freeformatter.com/html-entities.html - // HIGHLIGHT WORKER + var ASCIICharacters = { + 34: '"', + 38: '&', + 39: ''', + 60: '<', + 62: '>' + }; + var ISO88591Characters = { + 192: 'À', + 193: 'Á', + 194: 'Â', + 195: 'Ã', + 196: 'Ä', + 197: 'Å', + 198: 'Æ', + 199: 'Ç', + 200: 'È', + 201: 'É', + 202: 'Ê', + 203: 'Ë', + 204: 'Ì', + 205: 'Í', + 206: 'Î', + 207: 'Ï', + 208: 'Ð', + 209: 'Ñ', + 210: 'Ò', + 211: 'Ó', + 212: 'Ô', + 213: 'Õ', + 214: 'Ö', + 216: 'Ø', + 217: 'Ù', + 218: 'Ú', + 219: 'Û', + 220: 'Ü', + 221: 'Ý', + 222: 'Þ', + 223: 'ß', + 224: 'à', + 225: 'á', + 226: 'â', + 227: 'ã', + 228: 'ä', + 229: 'å', + 230: 'æ', + 231: 'ç', + 232: 'è', + 233: 'é', + 234: 'ê', + 235: 'ë', + 236: 'ì', + 237: 'í', + 238: 'î', + 239: 'ï', + 240: 'ð', + 241: 'ñ', + 242: 'ò', + 243: 'ó', + 244: 'ô', + 245: 'õ', + 246: 'ö', + 248: 'ø', + 249: 'ù', + 250: 'ú', + 251: 'û', + 252: 'ü', + 253: 'ý', + 254: 'þ', + 255: 'ÿ' + }; + var ISO88591Symbols = { + 160: ' ', + 161: '¡', + 162: '¢', + 163: '£', + 164: '¤', + 165: '¥', + 166: '¦', + 167: '§', + 168: '¨', + 169: '©', + 170: 'ª', + 171: '«', + 172: '¬', + 173: '­', + 174: '®', + 175: '¯', + 176: '°', + 177: '±', + 178: '²', + 179: '³', + 180: '´', + 181: 'µ', + 182: '¶', + 184: '¸', + 185: '¹', + 186: 'º', + 187: '»', + 188: '¼', + 189: '½', + 190: '¾', + 191: '¿', + 215: '×', + 247: '÷' + }; + var MathSymbols = { + 8704: '∀', + 8706: '∂', + 8707: '∃', + 8709: '∅', + 8711: '∇', + 8712: '∈', + 8713: '∉', + 8715: '∋', + 8719: '∏', + 8721: '∑', + 8722: '−', + 8727: '∗', + 8730: '√', + 8733: '∝', + 8734: '∞', + 8736: '∠', + 8743: '∧', + 8744: '∨', + 8745: '∩', + 8746: '∪', + 8747: '∫', + 8756: '∴', + 8764: '∼', + 8773: '≅', + 8776: '≈', + 8800: '≠', + 8801: '≡', + 8804: '≤', + 8805: '≥', + 8834: '⊂', + 8835: '⊃', + 8836: '⊄', + 8838: '⊆', + 8839: '⊇', + 8853: '⊕', + 8855: '⊗', + 8869: '⊥', + 8901: '⋅' + }; + var GreekLetters = { + 913: 'Α', + 914: 'Β', + 915: 'Γ', + 916: 'Δ', + 917: 'Ε', + 918: 'Ζ', + 919: 'Η', + 920: 'Θ', + 921: 'Ι', + 922: 'Κ', + 923: 'Λ', + 924: 'Μ', + 925: 'Ν', + 926: 'Ξ', + 927: 'Ο', + 928: 'Π', + 929: 'Ρ', + 931: 'Σ', + 932: 'Τ', + 933: 'Υ', + 934: 'Φ', + 935: 'Χ', + 936: 'Ψ', + 937: 'Ω', + 945: 'α', + 946: 'β', + 947: 'γ', + 948: 'δ', + 949: 'ε', + 950: 'ζ', + 951: 'η', + 952: 'θ', + 953: 'ι', + 954: 'κ', + 955: 'λ', + 956: 'μ', + 957: 'ν', + 958: 'ξ', + 959: 'ο', + 960: 'π', + 961: 'ρ', + 962: 'ς', + 963: 'σ', + 964: 'τ', + 965: 'υ', + 966: 'φ', + 967: 'χ', + 968: 'ψ', + 969: 'ω', + 977: 'ϑ', + 978: 'ϒ', + 982: 'ϖ' + }; + var MiscellaneousHTMLEntities = { + 338: 'Œ', + 339: 'œ', + 352: 'Š', + 353: 'š', + 376: 'Ÿ', + 402: 'ƒ', + 710: 'ˆ', + 732: '˜', + 8194: ' ', + 8195: ' ', + 8201: ' ', + 8204: '‌', + 8205: '‍', + 8206: '‎', + 8207: '‏', + 8211: '–', + 8212: '—', + 8216: '‘', + 8217: '’', + 8218: '‚', + 8220: '“', + 8221: '”', + 8222: '„', + 8224: '†', + 8225: '‡', + 8226: '•', + 8230: '…', + 8240: '‰', + 8242: '′', + 8243: '″', + 8249: '‹', + 8250: '›', + 8254: '‾', + 8364: '€', + 8482: '™', + 8592: '←', + 8593: '↑', + 8594: '→', + 8595: '↓', + 8596: '↔', + 8629: '↵', + 8968: '⌈', + 8969: '⌉', + 8970: '⌊', + 8971: '⌋', + 9674: '◊', + 9824: '♠', + 9827: '♣', + 9829: '♥', + 9830: '♦' + }; // TODO: 使用whatwg的entities.json - function startWorker(cm, time) { - if (cm.doc.highlightFrontier < cm.display.viewTo) { cm.state.highlight.set(time, bind(highlightWorker, cm)); } - } + var htmlEntitiesMap = _objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({}, ASCIICharacters), ISO88591Characters), ISO88591Symbols), MathSymbols), GreekLetters), MiscellaneousHTMLEntities); - function highlightWorker(cm) { - var doc = cm.doc; - if (doc.highlightFrontier >= cm.display.viewTo) { return } - var end = +new Date + cm.options.workTime; - var context = getContextBefore(cm, doc.highlightFrontier); - var changedLines = []; - - doc.iter(context.line, Math.min(doc.first + doc.size, cm.display.viewTo + 500), function (line) { - if (context.line >= cm.display.viewFrom) { // Visible - var oldStyles = line.styles; - var resetState = line.text.length > cm.options.maxHighlightLength ? copyState(doc.mode, context.state) : null; - var highlighted = highlightLine(cm, line, context, true); - if (resetState) { context.state = resetState; } - line.styles = highlighted.styles; - var oldCls = line.styleClasses, newCls = highlighted.classes; - if (newCls) { line.styleClasses = newCls; } - else if (oldCls) { line.styleClasses = null; } - var ischange = !oldStyles || oldStyles.length != line.styles.length || - oldCls != newCls && (!oldCls || !newCls || oldCls.bgClass != newCls.bgClass || oldCls.textClass != newCls.textClass); - for (var i = 0; !ischange && i < oldStyles.length; ++i) { ischange = oldStyles[i] != line.styles[i]; } - if (ischange) { changedLines.push(context.line); } - line.stateAfter = context.save(); - context.nextLine(); - } else { - if (line.text.length <= cm.options.maxHighlightLength) { processLine(cm, line.text, context); } - line.stateAfter = context.line % 5 == 0 ? context.save() : null; - context.nextLine(); - } - if (+new Date > end) { - startWorker(cm, cm.options.workDelay); - return true - } - }); - doc.highlightFrontier = context.line; - doc.modeFrontier = Math.max(doc.modeFrontier, context.line); - if (changedLines.length) { - runInOp(cm, function () { - for (var i = 0; i < changedLines.length; i++) { regLineChange(cm, changedLines[i], "text"); } - }); - } - } + var htmlEntitiesCodePoint = keys$3(htmlEntitiesMap); - // DISPLAY DRAWING - - var DisplayUpdate = function (cm, viewport, force) { - var display = cm.display; - - this.viewport = viewport; - // Store some values that we'll need later (but don't want to force a relayout for) - this.visible = visibleLines(display, cm.doc, viewport); - this.editorIsHidden = !display.wrapper.offsetWidth; - this.wrapperHeight = display.wrapper.clientHeight; - this.wrapperWidth = display.wrapper.clientWidth; - this.oldDisplayWidth = displayWidth(cm); - this.force = force; - this.dims = getDimensions(cm); - this.events = []; - }; + var htmlEntitiesWithoutSemicolon = map$3(htmlEntitiesCodePoint).call(htmlEntitiesCodePoint, function (code) { + return htmlEntitiesMap[code].replace(/^&(\w+);$/g, function (match, name) { + return name.toLowerCase(); + }); + }); + /** + * 非字符串类型与长度为0的字符串都认为是空串 + * @param {any} str 需要判断的字符串 + * @returns {boolean} + */ - DisplayUpdate.prototype.signal = function (emitter, type) { - if (hasHandler(emitter, type)) { this.events.push(arguments); } - }; - DisplayUpdate.prototype.finish = function () { - for (var i = 0; i < this.events.length; i++) { signal.apply(null, this.events[i]); } - }; - function maybeClipScrollbars(cm) { - var display = cm.display; - if (!display.scrollbarsClipped && display.scroller.offsetWidth) { - display.nativeBarWidth = display.scroller.offsetWidth - display.scroller.clientWidth; - display.heightForcer.style.height = scrollGap(cm) + "px"; - display.sizer.style.marginBottom = -display.nativeBarWidth + "px"; - display.sizer.style.borderRightWidth = scrollGap(cm) + "px"; - display.scrollbarsClipped = true; - } - } + var isEmptyString = function isEmptyString(str) { + return typeof str !== 'string' || str.length <= 0; + }; - function selectionSnapshot(cm) { - if (cm.hasFocus()) { return null } - var active = activeElt(); - if (!active || !contains(cm.display.lineDiv, active)) { return null } - var result = { activeElt: active }; - if (window.getSelection) { - var sel = window.getSelection(); - if (sel.anchorNode && sel.extend && contains(cm.display.lineDiv, sel.anchorNode)) { - result.anchorNode = sel.anchorNode; - result.anchorOffset = sel.anchorOffset; - result.focusNode = sel.focusNode; - result.focusOffset = sel.focusOffset; - } - } - return result - } + var isValidStringCodePoint = function isValidStringCodePoint(codePoint) { + try { + var string = fromCodePoint$2(codePoint); + + return !isEmptyString(string); // 如果转换的为空串,说明CodePoint不合法 + } catch (e) { + // 转换出错,也是不合法的CodePoint + return false; + } + }; - function restoreSelection(snapshot) { - if (!snapshot || !snapshot.activeElt || snapshot.activeElt == activeElt()) { return } - snapshot.activeElt.focus(); - if (!/^(INPUT|TEXTAREA)$/.test(snapshot.activeElt.nodeName) && - snapshot.anchorNode && contains(document.body, snapshot.anchorNode) && contains(document.body, snapshot.focusNode)) { - var sel = window.getSelection(), range = document.createRange(); - range.setEnd(snapshot.anchorNode, snapshot.anchorOffset); - range.collapse(false); - sel.removeAllRanges(); - sel.addRange(range); - sel.extend(snapshot.focusNode, snapshot.focusOffset); - } - } + function escapeHTMLEntitiesWithoutSemicolon(content) { + if (typeof content !== 'string') { + return ''; + } // 先处理字符实体 - // Does the actual updating of the line display. Bails out - // (returning false) when there is nothing to be done and forced is - // false. - function updateDisplayIfNeeded(cm, update) { - var display = cm.display, doc = cm.doc; - if (update.editorIsHidden) { - resetView(cm); - return false - } + var namedRegex = /&(\w+);?/g; + var escaped = content.replace(namedRegex, function (match, name) { + // 不在合法列表里的全部转义,无分号的情况也转义 + if (indexOf$8(match).call(match, ';') === -1 || indexOf$8(htmlEntitiesWithoutSemicolon).call(htmlEntitiesWithoutSemicolon, name.toLowerCase()) === -1) { + return match.replace(/&/g, '&'); + } - // Bail out if the visible area is already rendered and nothing changed. - if (!update.force && - update.visible.from >= display.viewFrom && update.visible.to <= display.viewTo && - (display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo) && - display.renderedView == display.view && countDirtyView(cm) == 0) { return false } + return match; + }); // 处理十进制数字实体,需要防止误匹配16进制 - if (maybeUpdateLineNumberWidth(cm)) { - resetView(cm); - update.dims = getDimensions(cm); - } + var numericRegex = /&#(?!x)(\d*);?/gi; + escaped = escaped.replace(numericRegex, function (match, decimalCodePoint) { + // 不在合法列表里的全部转义,无分号的情况也转义 + // 且位数不能大于7,否则可能导致溢出: https://spec.commonmark.org/0.29/#decimal-numeric-character + if (isEmptyString(decimalCodePoint) || indexOf$8(match).call(match, ';') === -1 || decimalCodePoint.lenth > 7 || // Object.keys(htmlEntitiesMap).indexOf(+decimalCodePoint) === -1 || + !isValidStringCodePoint(decimalCodePoint)) { + return match.replace(/&/g, '&'); + } - // Compute a suitable new viewport (from & to) - var end = doc.first + doc.size; - var from = Math.max(update.visible.from - cm.options.viewportMargin, doc.first); - var to = Math.min(end, update.visible.to + cm.options.viewportMargin); - if (display.viewFrom < from && from - display.viewFrom < 20) { from = Math.max(doc.first, display.viewFrom); } - if (display.viewTo > to && display.viewTo - to < 20) { to = Math.min(end, display.viewTo); } - if (sawCollapsedSpans) { - from = visualLineNo(cm.doc, from); - to = visualLineEndNo(cm.doc, to); - } + return match; + }); // 处理十六进制数字实体 - var different = from != display.viewFrom || to != display.viewTo || - display.lastWrapHeight != update.wrapperHeight || display.lastWrapWidth != update.wrapperWidth; - adjustView(cm, from, to); - - display.viewOffset = heightAtLine(getLine(cm.doc, display.viewFrom)); - // Position the mover div to align with the current scroll position - cm.display.mover.style.top = display.viewOffset + "px"; - - var toUpdate = countDirtyView(cm); - if (!different && toUpdate == 0 && !update.force && display.renderedView == display.view && - (display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo)) { return false } - - // For big changes, we hide the enclosing element during the - // update, since that speeds up the operations on most browsers. - var selSnapshot = selectionSnapshot(cm); - if (toUpdate > 4) { display.lineDiv.style.display = "none"; } - patchDisplay(cm, display.updateLineNumbers, update.dims); - if (toUpdate > 4) { display.lineDiv.style.display = ""; } - display.renderedView = display.view; - // There might have been a widget with a focused element that got - // hidden or updated, if so re-focus it. - restoreSelection(selSnapshot); - - // Prevent selection and cursors from interfering with the scroll - // width and height. - removeChildren(display.cursorDiv); - removeChildren(display.selectionDiv); - display.gutters.style.height = display.sizer.style.minHeight = 0; - - if (different) { - display.lastWrapHeight = update.wrapperHeight; - display.lastWrapWidth = update.wrapperWidth; - startWorker(cm, 400); - } + var hexRegex = /&#x([0-9a-f]*);?/gi; + escaped = escaped.replace(hexRegex, function (match, hexCodePoint) { + if (isEmptyString(hexCodePoint)) { + return match.replace(/&/g, '&'); + } - display.updateLineNumbers = null; + var hexCode = "0x".concat(hexCodePoint); - return true - } + var decimalCodePoint = _parseInt$2(hexCode, 16); // parseInt非数字、不在合法列表里、无分号的情况全部转义 + // 且位数不能大于6: https://spec.commonmark.org/0.29/#hexadecimal-numeric-character - function postUpdateDisplay(cm, update) { - var viewport = update.viewport; - - for (var first = true; ; first = false) { - if (!first || !cm.options.lineWrapping || update.oldDisplayWidth == displayWidth(cm)) { - // Clip forced viewport to actual scrollable area. - if (viewport && viewport.top != null) { viewport = { top: Math.min(cm.doc.height + paddingVert(cm.display) - displayHeight(cm), viewport.top) }; } - // Updated line heights might result in the drawn area not - // actually covering the viewport. Keep looping until it does. - update.visible = visibleLines(cm.display, cm.doc, viewport); - if (update.visible.from >= cm.display.viewFrom && update.visible.to <= cm.display.viewTo) { break } - } else if (first) { - update.visible = visibleLines(cm.display, cm.doc, viewport); - } - if (!updateDisplayIfNeeded(cm, update)) { break } - updateHeightsInViewport(cm); - var barMeasure = measureForScrollbars(cm); - updateSelection(cm); - updateScrollbars(cm, barMeasure); - setDocumentHeight(cm, barMeasure); - update.force = false; - } - update.signal(cm, "update", cm); - if (cm.display.viewFrom != cm.display.reportedViewFrom || cm.display.viewTo != cm.display.reportedViewTo) { - update.signal(cm, "viewportChange", cm, cm.display.viewFrom, cm.display.viewTo); - cm.display.reportedViewFrom = cm.display.viewFrom; cm.display.reportedViewTo = cm.display.viewTo; - } - } + if (isNaN(decimalCodePoint) || indexOf$8(match).call(match, ';') === -1 || hexCodePoint.lenth > 6 || // Object.keys(htmlEntitiesMap).indexOf(decimalCodePoint) === -1 + !isValidStringCodePoint(hexCode)) { + return match.replace(/&/g, '&'); + } - function updateDisplaySimple(cm, viewport) { - var update = new DisplayUpdate(cm, viewport); - if (updateDisplayIfNeeded(cm, update)) { - updateHeightsInViewport(cm); - postUpdateDisplay(cm, update); - var barMeasure = measureForScrollbars(cm); - updateSelection(cm); - updateScrollbars(cm, barMeasure); - setDocumentHeight(cm, barMeasure); - update.finish(); - } - } + return match; + }); + return escaped; + } + var blockNames = ['h1|h2|h3|h4|h5|h6', 'ul|ol|li|dd|dl|dt', 'table|thead|tbody|tfoot|col|colgroup|th|td|tr', 'div|article|section|footer|aside|details|summary|code|audio|video|canvas|figure', 'address|center|cite|p|pre|blockquote|marquee|caption|figcaption|track|source|output|svg'].join('|'); + var inlineNames = ['span|a|link|b|s|i|del|u|em|strong|sup|sub|kbd', 'nav|font|bdi|samp|map|area|small|time|bdo|var|wbr|meter|dfn', 'ruby|rt|rp|mark|q|progress|input|textarea|select|ins'].join('|'); + var inlineBlock = 'br|img|hr'; + var whiteList = new RegExp(concat$5(_context = concat$5(_context2 = "^(".concat(blockNames, "|")).call(_context2, inlineNames, "|")).call(_context, inlineBlock, ")( |$|/)"), 'i'); + function escapeHTMLSpecialChar(content, enableQuote) { + if (typeof content !== 'string') { + return ''; + } - // Sync the actual display DOM structure with display.view, removing - // nodes for lines that are no longer in view, and creating the ones - // that are not there yet, and updating the ones that are out of - // date. - function patchDisplay(cm, updateNumbersFrom, dims) { - var display = cm.display, lineNumbers = cm.options.lineNumbers; - var container = display.lineDiv, cur = container.firstChild; - - function rm(node) { - var next = node.nextSibling; - // Works around a throw-scroll bug in OS X Webkit - if (webkit && mac && cm.display.currentWheelTarget == node) { node.style.display = "none"; } - else { node.parentNode.removeChild(node); } - return next - } + if (enableQuote) { + return content.replace(/[<>&]/g, function (_char) { + return escapeMap[_char] || _char; + }); + } - var view = display.view, lineN = display.viewFrom; - // Loop over the elements in the view, syncing cur (the DOM nodes - // in display.lineDiv) with the view as we go. - for (var i = 0; i < view.length; i++) { - var lineView = view[i]; - if (lineView.hidden); else if (!lineView.node || lineView.node.parentNode != container) { // Not drawn yet - var node = buildLineElement(cm, lineView, lineN, dims); - container.insertBefore(node, cur); - } else { // Already drawn - while (cur != lineView.node) { cur = rm(cur); } - var updateNumber = lineNumbers && updateNumbersFrom != null && - updateNumbersFrom <= lineN && lineView.lineNumber; - if (lineView.changes) { - if (indexOf(lineView.changes, "gutter") > -1) { updateNumber = false; } - updateLineForChanges(cm, lineView, lineN, dims); - } - if (updateNumber) { - removeChildren(lineView.lineNumber); - lineView.lineNumber.appendChild(document.createTextNode(lineNumberFor(cm.options, lineN))); - } - cur = lineView.node.nextSibling; - } - lineN += lineView.size; - } - while (cur) { cur = rm(cur); } - } + return content.replace(/[<>&"']/g, function (_char2) { + return escapeMap[_char2] || _char2; + }); + } + function unescapeHTMLSpecialChar(content) { + if (typeof content !== 'string') { + return ''; + } - function updateGutterSpace(display) { - var width = display.gutters.offsetWidth; - display.sizer.style.marginLeft = width + "px"; - } + return content.replace(/&(\w+);?/g, function (escaped, name) { + return unescapeMap[name] || escaped; + }); + } + function escapeHTMLSpecialCharOnce(content, enableQuote) { + if (typeof content !== 'string') { + return ''; + } - function setDocumentHeight(cm, measure) { - cm.display.sizer.style.minHeight = measure.docHeight + "px"; - cm.display.heightForcer.style.top = measure.docHeight + "px"; - cm.display.gutters.style.height = (measure.docHeight + cm.display.barHeight + scrollGap(cm)) + "px"; - } + var str = convertHTMLNumberToName(content); + str = unescapeHTMLSpecialChar(str); + return escapeHTMLSpecialChar(str, enableQuote); + } + function convertHTMLNumberToName(html) { + var entities = /&#(\d+);?/g; + return html.replace(entities, function (match, codePoint) { + return htmlEntitiesMap[codePoint] || match; + }); + } + function unescapeHTMLNumberEntities(html) { + var entities = /&#(\d+);?/g; + return html.replace(entities, function (match, codePoint) { + try { + var escaped = fromCodePoint$2(codePoint); - // Re-align line numbers and gutter marks to compensate for - // horizontal scrolling. - function alignHorizontally(cm) { - var display = cm.display, view = display.view; - if (!display.alignWidgets && (!display.gutters.firstChild || !cm.options.fixedGutter)) { return } - var comp = compensateForHScroll(display) - display.scroller.scrollLeft + cm.doc.scrollLeft; - var gutterW = display.gutters.offsetWidth, left = comp + "px"; - for (var i = 0; i < view.length; i++) { - if (!view[i].hidden) { - if (cm.options.fixedGutter) { - if (view[i].gutter) { view[i].gutter.style.left = left; } - if (view[i].gutterBackground) { view[i].gutterBackground.style.left = left; } - } - var align = view[i].alignable; - if (align) { - for (var j = 0; j < align.length; j++) { align[j].style.left = left; } - } - } - } - if (cm.options.fixedGutter) { display.gutters.style.left = (comp + gutterW) + "px"; } - } + return escaped; + } catch (e) { + return match; + } + }); + } + function unescapeHTMLHexEntities(html) { + var entities = /&#x([0-9a-f]+);?/gi; + return html.replace(entities, function (match, codePoint) { + var hexCode = _parseInt$2("0x".concat(codePoint), 16); - // Used to ensure that the line number gutter is still the right - // size for the current document size. Returns true when an update - // is needed. - function maybeUpdateLineNumberWidth(cm) { - if (!cm.options.lineNumbers) { return false } - var doc = cm.doc, last = lineNumberFor(cm.options, doc.first + doc.size - 1), display = cm.display; - if (last.length != display.lineNumChars) { - var test = display.measure.appendChild(elt("div", [elt("div", last)], - "CodeMirror-linenumber CodeMirror-gutter-elt")); - var innerW = test.firstChild.offsetWidth, padding = test.offsetWidth - innerW; - display.lineGutter.style.width = ""; - display.lineNumInnerWidth = Math.max(innerW, display.lineGutter.offsetWidth - padding) + 1; - display.lineNumWidth = display.lineNumInnerWidth + padding; - display.lineNumChars = display.lineNumInnerWidth ? last.length : -1; - display.lineGutter.style.width = display.lineNumWidth + "px"; - updateGutterSpace(cm.display); - return true - } - return false - } + try { + var escaped = fromCodePoint$2(hexCode); - function getGutters(gutters, lineNumbers) { - var result = [], sawLineNumbers = false; - for (var i = 0; i < gutters.length; i++) { - var name = gutters[i], style = null; - if (typeof name != "string") { style = name.style; name = name.className; } - if (name == "CodeMirror-linenumbers") { - if (!lineNumbers) { continue } - else { sawLineNumbers = true; } - } - result.push({ className: name, style: style }); - } - if (lineNumbers && !sawLineNumbers) { result.push({ className: "CodeMirror-linenumbers", style: null }); } - return result - } + return escaped; + } catch (e) { + return match; + } + }); + } + function isValidScheme(url) { + var regex = /^\s*([\w\W]+?)(?=:)/i; + var match = unescapeHTMLHexEntities(unescapeHTMLNumberEntities(url)).match(regex); - // Rebuild the gutter elements, ensure the margin to the left of the - // code matches their width. - function renderGutters(display) { - var gutters = display.gutters, specs = display.gutterSpecs; - removeChildren(gutters); - display.lineGutter = null; - for (var i = 0; i < specs.length; ++i) { - var ref = specs[i]; - var className = ref.className; - var style = ref.style; - var gElt = gutters.appendChild(elt("div", null, "CodeMirror-gutter " + className)); - if (style) { gElt.style.cssText = style; } - if (className == "CodeMirror-linenumbers") { - display.lineGutter = gElt; - gElt.style.width = (display.lineNumWidth || 1) + "px"; - } - } - gutters.style.display = specs.length ? "" : "none"; - updateGutterSpace(display); - } + if (!match) { + return true; + } - function updateGutters(cm) { - renderGutters(cm.display); - regChange(cm); - alignHorizontally(cm); - } + var SCHEME_BLACKLIST = ['javascript', 'data']; + var scheme = match[1].replace(/[\s]/g, ''); // 协议中间可能会出现空白字符绕过检查 - // The display handles the DOM integration, both for input reading - // and content drawing. It holds references to DOM nodes and - // display-related state. - - function Display(place, doc, input, options) { - var d = this; - this.input = input; - - // Covers bottom-right square when both scrollbars are present. - d.scrollbarFiller = elt("div", null, "CodeMirror-scrollbar-filler"); - d.scrollbarFiller.setAttribute("cm-not-content", "true"); - // Covers bottom of gutter when coverGutterNextToScrollbar is on - // and h scrollbar is present. - d.gutterFiller = elt("div", null, "CodeMirror-gutter-filler"); - d.gutterFiller.setAttribute("cm-not-content", "true"); - // Will contain the actual code, positioned to cover the viewport. - d.lineDiv = eltP("div", null, "CodeMirror-code"); - // Elements are added to these to represent selection and cursors. - d.selectionDiv = elt("div", null, null, "position: relative; z-index: 1"); - d.cursorDiv = elt("div", null, "CodeMirror-cursors"); - // A visibility: hidden element used to find the size of things. - d.measure = elt("div", null, "CodeMirror-measure"); - // When lines outside of the viewport are measured, they are drawn in this. - d.lineMeasure = elt("div", null, "CodeMirror-measure"); - // Wraps everything that needs to exist inside the vertically-padded coordinate system - d.lineSpace = eltP("div", [d.measure, d.lineMeasure, d.selectionDiv, d.cursorDiv, d.lineDiv], - null, "position: relative; outline: none"); - var lines = eltP("div", [d.lineSpace], "CodeMirror-lines"); - // Moved around its parent to cover visible view. - d.mover = elt("div", [lines], null, "position: relative"); - // Set to the height of the document, allowing scrolling. - d.sizer = elt("div", [d.mover], "CodeMirror-sizer"); - d.sizerWidth = null; - // Behavior of elts with overflow: auto and padding is - // inconsistent across browsers. This is used to ensure the - // scrollable area is big enough. - d.heightForcer = elt("div", null, null, "position: absolute; height: " + scrollerGap + "px; width: 1px;"); - // Will contain the gutters, if any. - d.gutters = elt("div", null, "CodeMirror-gutters"); - d.lineGutter = null; - // Actual scrollable element. - d.scroller = elt("div", [d.sizer, d.heightForcer, d.gutters], "CodeMirror-scroll"); - d.scroller.setAttribute("tabIndex", "-1"); - // The element in which the editor lives. - d.wrapper = elt("div", [d.scrollbarFiller, d.gutterFiller, d.scroller], "CodeMirror"); - - // Work around IE7 z-index bug (not perfect, hence IE7 not really being supported) - if (ie && ie_version < 8) { d.gutters.style.zIndex = -1; d.scroller.style.paddingRight = 0; } - if (!webkit && !(gecko && mobile)) { d.scroller.draggable = true; } - - if (place) { - if (place.appendChild) { place.appendChild(d.wrapper); } - else { place(d.wrapper); } - } + if (indexOf$8(SCHEME_BLACKLIST).call(SCHEME_BLACKLIST, scheme.toLowerCase()) !== -1) { + return false; + } - // Current rendered range (may be bigger than the view window). - d.viewFrom = d.viewTo = doc.first; - d.reportedViewFrom = d.reportedViewTo = doc.first; - // Information about the rendered lines. - d.view = []; - d.renderedView = null; - // Holds info about a single rendered line when it was rendered - // for measurement, while not in view. - d.externalMeasured = null; - // Empty space (in pixels) above the view - d.viewOffset = 0; - d.lastWrapHeight = d.lastWrapWidth = 0; - d.updateLineNumbers = null; - - d.nativeBarWidth = d.barHeight = d.barWidth = 0; - d.scrollbarsClipped = false; - - // Used to only resize the line number gutter when necessary (when - // the amount of lines crosses a boundary that makes its width change) - d.lineNumWidth = d.lineNumInnerWidth = d.lineNumChars = null; - // Set to true when a non-horizontal-scrolling line widget is - // added. As an optimization, line widget aligning is skipped when - // this is false. - d.alignWidgets = false; - - d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null; - - // Tracks the maximum line length so that the horizontal scrollbar - // can be kept static when scrolling. - d.maxLine = null; - d.maxLineLength = 0; - d.maxLineChanged = false; - - // Used for measuring wheel scrolling granularity - d.wheelDX = d.wheelDY = d.wheelStartX = d.wheelStartY = null; - - // True when shift is held down. - d.shift = false; - - // Used to track whether anything happened since the context menu - // was opened. - d.selForContextMenu = null; - - d.activeTouch = null; - - d.gutterSpecs = getGutters(options.gutters, options.lineNumbers); - renderGutters(d); - - input.init(d); - } + return true; + } + /** + * ref: https://stackoverflow.com/questions/9245333/should-encodeuri-ever-be-used + * @param {string} str + */ - // Since the delta values reported on mouse wheel events are - // unstandardized between browsers and even browser versions, and - // generally horribly unpredictable, this code starts by measuring - // the scroll effect that the first few mouse wheel events have, - // and, from that, detects the way it can convert deltas to pixel - // offsets afterwards. - // - // The reason we want to know the amount a wheel event will scroll - // is that it gives us a chance to update the display before the - // actual scrolling happens, reducing flickering. - - var wheelSamples = 0, wheelPixelsPerUnit = null; - // Fill in a browser-detected starting value on browsers where we - // know one. These don't have to be accurate -- the result of them - // being wrong would just be a slight flicker on the first wheel - // scroll (if it is large enough). - if (ie) { wheelPixelsPerUnit = -.53; } - else if (gecko) { wheelPixelsPerUnit = 15; } - else if (chrome) { wheelPixelsPerUnit = -.7; } - else if (safari) { wheelPixelsPerUnit = -1 / 3; } - - function wheelEventDelta(e) { - var dx = e.wheelDeltaX, dy = e.wheelDeltaY; - if (dx == null && e.detail && e.axis == e.HORIZONTAL_AXIS) { dx = e.detail; } - if (dy == null && e.detail && e.axis == e.VERTICAL_AXIS) { dy = e.detail; } - else if (dy == null) { dy = e.wheelDelta; } - return { x: dx, y: dy } - } - function wheelEventPixels(e) { - var delta = wheelEventDelta(e); - delta.x *= wheelPixelsPerUnit; - delta.y *= wheelPixelsPerUnit; - return delta - } + function encodeURIOnce(str) { + return encodeURI(str).replace(/[!'()*]/g, function (_char4) { + return "%".concat(_char4.charCodeAt(0).toString(16)); + }).replace(/%25/g, '%'); + } - function onScrollWheel(cm, e) { - var delta = wheelEventDelta(e), dx = delta.x, dy = delta.y; - - var display = cm.display, scroll = display.scroller; - // Quit if there's nothing to scroll here - var canScrollX = scroll.scrollWidth > scroll.clientWidth; - var canScrollY = scroll.scrollHeight > scroll.clientHeight; - if (!(dx && canScrollX || dy && canScrollY)) { return } - - // Webkit browsers on OS X abort momentum scrolls when the target - // of the scroll event is removed from the scrollable element. - // This hack (see related code in patchDisplay) makes sure the - // element is kept around. - if (dy && mac && webkit) { - outer: for (var cur = e.target, view = display.view; cur != scroll; cur = cur.parentNode) { - for (var i = 0; i < view.length; i++) { - if (view[i].node == cur) { - cm.display.currentWheelTarget = cur; - break outer - } - } - } - } + function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = construct$4(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } - // On some browsers, horizontal scrolling will cause redraws to - // happen before the gutter has been realigned, causing it to - // wriggle around in a most unseemly way. When we have an - // estimated pixels/delta value, we just handle horizontal - // scrolling entirely here. It'll be slightly off from native, but - // better than glitching out. - if (dx && !gecko && !presto && wheelPixelsPerUnit != null) { - if (dy && canScrollY) { updateScrollTop(cm, Math.max(0, scroll.scrollTop + dy * wheelPixelsPerUnit)); } - setScrollLeft(cm, Math.max(0, scroll.scrollLeft + dx * wheelPixelsPerUnit)); - // Only prevent default scrolling if vertical scrolling is - // actually possible. Otherwise, it causes vertical scroll - // jitter on OSX trackpads when deltaX is small and deltaY - // is large (issue #3579) - if (!dy || (dy && canScrollY)) { e_preventDefault(e); } - display.wheelStartX = null; // Abort measurement, if in progress - return - } + function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !construct$4) return false; if (construct$4.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(construct$4(Boolean, [], function () {})); return true; } catch (e) { return false; } } + var cacheCounter = 0; // ~~C${cacheCounter}I${cacheIndex}$ + // let cacheMap = {}; - // 'Project' the visible viewport to cover the area that is being - // scrolled into view (if we know enough to estimate it). - if (dy && wheelPixelsPerUnit != null) { - var pixels = dy * wheelPixelsPerUnit; - var top = cm.doc.scrollTop, bot = top + display.wrapper.clientHeight; - if (pixels < 0) { top = Math.max(0, top + pixels - 50); } - else { bot = Math.min(cm.doc.height, bot + pixels + 50); } - updateDisplaySimple(cm, { top: top, bottom: bot }); - } + var ParagraphBase = /*#__PURE__*/function (_SyntaxBase) { + _inherits(ParagraphBase, _SyntaxBase); + + var _super = _createSuper(ParagraphBase); + + // 不需要排他的sign前缀,如~~C0I${IN_PARAGRAPH_CACHE_KEY_PREFIX}sign$ + function ParagraphBase() { + var _this; + + var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : { + needCache: false + }, + needCache = _ref.needCache, + _ref$defaultCache = _ref.defaultCache, + defaultCache = _ref$defaultCache === void 0 ? {} : _ref$defaultCache; + + _classCallCheck(this, ParagraphBase); + + _this = _super.call(this, {}); + _this.needCache = !!needCache; + _this.sign = ''; + + if (needCache) { + _this.cache = defaultCache || {}; + _this.cacheKey = "~~C".concat(cacheCounter); + cacheCounter += 1; + } + + return _this; + } + + _createClass(ParagraphBase, [{ + key: "initBrReg", + value: function initBrReg() { + var classicBr = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + // 是否启用经典换行逻辑 + // true:一个换行会被忽略,两个以上连续换行会分割成段落, + // false: 一个换行会转成
,两个连续换行会分割成段落,三个以上连续换行会转成
并分割段落 + this.classicBr = testKeyInLocal('classicBr') ? getIsClassicBrFromLocal() : classicBr; + this.removeBrAfterBlock = null; + this.removeBrBeforeBlock = null; + this.removeNewlinesBetweenTags = null; + } + /** + * 处理经典换行问题 + * @param {string} str markdown源码 + * @returns markdown源码 + */ + + }, { + key: "$cleanParagraph", + value: function $cleanParagraph(str) { + // remove leading and trailing newlines + var trimedPar = str.replace(/^\n+/, '').replace(/\n+$/, ''); + + if (this.classicBr) { + return trimedPar; + } + + var minifiedPar = this.joinRawHtml(trimedPar); + return minifiedPar.replace(/\n/g, '
').replace(/\r/g, '\n'); // recover \n from \r + } + /** + * remove all newlines in html text + * + * @param {string} textContainsHtml + */ + + }, { + key: "joinRawHtml", + value: function joinRawHtml(textContainsHtml) { + if (!this.removeBrAfterBlock) { + var _this$$engine$htmlWhi, _this$$engine$htmlWhi2, _context, _context2; + + // preprocess custom white list + var customTagWhiteList = (_this$$engine$htmlWhi = (_this$$engine$htmlWhi2 = this.$engine.htmlWhiteListAppend) === null || _this$$engine$htmlWhi2 === void 0 ? void 0 : _this$$engine$htmlWhi2.split('|')) !== null && _this$$engine$htmlWhi !== void 0 ? _this$$engine$htmlWhi : []; + customTagWhiteList = filter$3(_context = map$3(customTagWhiteList).call(customTagWhiteList, function (tag) { + if (/[a-z-]+/gi.test(tag)) { + return tag; + } + + return null; + })).call(_context, function (tag) { + return tag !== null; + }); // concat all white list + + var allBlockNames = concat$5(customTagWhiteList).call(customTagWhiteList, blockNames).join('|'); // 段落标签自然换行,所以去掉段落标签两边的换行符 + + /** + * remove newlines after start tag, and remove whitespaces before newline + * e.g. + *

\n text

=>

text

+ * ^^ + * $1$2 + */ + + + this.removeBrAfterBlock = new RegExp("<(".concat(allBlockNames, ")(>| [^>]*?>)[^\\S\\n]*?\\n"), 'ig'); + /** + * remove newlines before end tag, and whitespaces before end tag will be preserved + * e.g. + *

text\n

=>

text

+ * ^ + * $1 + */ + + this.removeBrBeforeBlock = new RegExp("\\n[^\\S\\n]*?<\\/(".concat(allBlockNames, ")>[^\\S\\n]*?\\n"), 'ig'); + /** + * remove newlines between end tag & start tag + * e.g. + *

\n

=>

\r

+ * ^ ^^ ^ ^^^^^^^^^^^^ + * $1 $2 $3 $4 + */ + + this.removeNewlinesBetweenTags = new RegExp(concat$5(_context2 = "<\\/(".concat(allBlockNames, ")>[^\\S\\n]*?\\n([^\\S\\n]*?)<(")).call(_context2, allBlockNames, ")(>| [^>]*?>)"), 'ig'); + } + + return textContainsHtml.replace(this.removeBrAfterBlock, '<$1$2').replace(this.removeBrBeforeBlock, '').replace(this.removeNewlinesBetweenTags, '\r$2<$3$4'); // replace \n to \r + } + }, { + key: "toHtml", + value: function toHtml(str, sentenceMakeFunc) { + return str; + } + }, { + key: "makeHtml", + value: function makeHtml(str, sentenceMakeFunc) { + return sentenceMakeFunc(str).html; + } + }, { + key: "afterMakeHtml", + value: function afterMakeHtml(html) { + return this.restoreCache(html); + } + }, { + key: "isContainsCache", + value: function isContainsCache(str, fullMatch) { + if (fullMatch) { + // 如果是全匹配:不能包含CherryINPRAGRAPH + var containsParagraphCache = /^(\s*~~C\d+I\w+\$\s*)+$/g.test(str); + var containsInParagraphCache = new RegExp("~~C\\d+I".concat(ParagraphBase.IN_PARAGRAPH_CACHE_KEY_PREFIX_REGEX, "\\w+\\$"), 'g').test(str); + return containsParagraphCache && !containsInParagraphCache; + } // 如果是局部匹配: 不能只包含CherryINPRAGRAPH + // const containsParagraphCache = /~~C\d+I\w+\$/g.test(str); + // const containsInParagraphCache = new RegExp( + // `~~C\\d+I${ParagraphBase.IN_PARAGRAPH_CACHE_KEY_PREFIX}\\w+\\$`, 'g').test(str); + + + var containsNonInParagraphCache = new RegExp("~~C\\d+I(?!".concat(ParagraphBase.IN_PARAGRAPH_CACHE_KEY_PREFIX_REGEX, ")\\w+\\$"), 'g').test(str); + return containsNonInParagraphCache; // return fullMatch ? + // /^(\s*~~C\d+I\w+\$\s*)+$/g.test(str) && !/^(\s*~~C\d+ICherryINPRAGRAPH\w+\$\s*)+$/g.test(str) : + // /~~C\d+I\w+\$/g.test(str) && !(/~~C\d+ICherryINPRAGRAPH\w+\$/g.test(str) + // && !/~~C\d+I(?!CherryINPRAGRAPH)\w+\$/g.test(str)); + } + /** + * + * @param {string} html + * @return + */ + + }, { + key: "$splitHtmlByCache", + value: function $splitHtmlByCache(html) { + // ~~C0I(?!prefix)sign$ + var regex = new RegExp("\\n*~~C\\d+I(?!".concat(ParagraphBase.IN_PARAGRAPH_CACHE_KEY_PREFIX_REGEX, ")\\w+\\$\\n?"), 'g'); + return { + caches: html.match(regex), + contents: html.split(regex) + }; + } + }, { + key: "makeExcludingCached", + value: function makeExcludingCached(content, processor) { + var _this$$splitHtmlByCac = this.$splitHtmlByCache(content), + caches = _this$$splitHtmlByCac.caches, + contents = _this$$splitHtmlByCac.contents; + + var paragraphs = map$3(contents).call(contents, processor); + + var ret = ''; + + for (var i = 0; i < paragraphs.length; i++) { + ret += paragraphs[i]; + + if (caches && caches[i]) { + var _context3; + + ret += trim$3(_context3 = caches[i]).call(_context3); + } + } + + return ret; + } + /** + * 获取非捕获匹配丢掉的换行,适用于能被【嵌套】的段落语法 + * + * @param {string} cache 需要返回的cache + * @param {string} md 原始的md字符串 + * @param {boolean} alwaysAlone 是否能被【嵌套】,true:不能被嵌套,如标题、注释等;false:能被嵌套,如代码块、有序列表等 + * @return {string} str + */ + + }, { + key: "getCacheWithSpace", + value: function getCacheWithSpace(cache, md) { + var _md$match$, _md$match, _md$match$2, _md$match2, _context4, _context5; + + var alwaysAlone = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + var preSpace = (_md$match$ = (_md$match = md.match(/^\n+/)) === null || _md$match === void 0 ? void 0 : _md$match[0]) !== null && _md$match$ !== void 0 ? _md$match$ : ''; + var afterSpace = (_md$match$2 = (_md$match2 = md.match(/\n+$/)) === null || _md$match2 === void 0 ? void 0 : _md$match2[0]) !== null && _md$match$2 !== void 0 ? _md$match$2 : ''; + + if (alwaysAlone) { + return prependLineFeedForParagraph(md, cache); + } + + return concat$5(_context4 = concat$5(_context5 = "".concat(preSpace)).call(_context5, cache)).call(_context4, afterSpace); + } + /** + * 获取行号,只负责向上计算\n + * 会计算cache的行号 + * + * @param {string} md md内容 + * @param {string} preSpace 前置换行 + * @return {number} 行数 + */ + + }, { + key: "getLineCount", + value: function getLineCount(md) { + var _preSpace$match$0$len, _preSpace$match, _preSpace$match$; + + var preSpace = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; + var content = md; + /** + * 前置换行个数,【注意】:前置换行个数不包括上文的最后一个\n + * 例: + * - aa\n + * - bb\n + * \n + * cc\n + * + * cc的前置换行个数为 1,bb后的\n不计算在内 + * cc的正则为:/(?:^|\n)(\n*)xxxxxx/ + */ + + var preLineCount = (_preSpace$match$0$len = (_preSpace$match = preSpace.match(/^\n+/g)) === null || _preSpace$match === void 0 ? void 0 : (_preSpace$match$ = _preSpace$match[0]) === null || _preSpace$match$ === void 0 ? void 0 : _preSpace$match$.length) !== null && _preSpace$match$0$len !== void 0 ? _preSpace$match$0$len : 0; + preLineCount = preLineCount === 1 ? 1 : 0; // 前置换行超过2个就交给BR进行渲染 + + content = content.replace(/^\n+/g, ''); + var regex = new RegExp("\n*~~C\\d+I(?:".concat(ParagraphBase.IN_PARAGRAPH_CACHE_KEY_PREFIX_REGEX, ")?\\w+?_L(\\d+)\\$"), 'g'); + var cacheLineCount = 0; + content = content.replace(regex, function (match, lineCount) { + cacheLineCount += _parseInt$2(lineCount, 10); + return match.replace(/^\n+/g, ''); + }); + return preLineCount + cacheLineCount + (content.match(/\n/g) || []).length + 1; // 实际内容所占行数,至少为1行 + } + /** + * + * @param {string} str 渲染后的内容 + * @param {string} sign 签名 + * @param {number} lineCount md原文的行数 + * @return {string} cacheKey ~~C0I0_L1$ + */ + + }, { + key: "pushCache", + value: function pushCache(str) { + var _context6, _context7; + + var sign = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; + var lineCount = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; + + if (!this.needCache) { + return; + } + + var $sign = sign || this.$engine.md5(str); + this.cache[$sign] = { + content: str, + using: true + }; + return concat$5(_context6 = concat$5(_context7 = "".concat(this.cacheKey, "I")).call(_context7, $sign, "_L")).call(_context6, lineCount, "$"); + } + }, { + key: "popCache", + value: function popCache(sign) { + if (!this.needCache) { + return; + } + + return this.cache[sign].content || ''; + } + }, { + key: "resetCache", + value: function resetCache() { + if (!this.needCache) { + return; + } + + for (var _i = 0, _Object$keys = keys$3(this.cache); _i < _Object$keys.length; _i++) { + var key = _Object$keys[_i]; + if (!this.cache[key].using) delete this.cache[key]; + } + + for (var _i2 = 0, _Object$keys3 = keys$3(this.cache); _i2 < _Object$keys3.length; _i2++) { + var _key = _Object$keys3[_i2]; + this.cache[_key].using = false; + } + } + }, { + key: "restoreCache", + value: function restoreCache(html) { + var _context8, + _this2 = this; + + // restore cached content + if (!this.needCache) { + return html; + } + + var regex = new RegExp(concat$5(_context8 = "".concat(this.cacheKey, "I((?:")).call(_context8, ParagraphBase.IN_PARAGRAPH_CACHE_KEY_PREFIX_REGEX, ")?\\w+)\\$"), 'g'); + var $html = html.replace(regex, function (match, cacheSign) { + return _this2.popCache(cacheSign.replace(/_L\d+$/, '')); + }); + this.resetCache(); + return $html; + } + /** + * + * @param {string} wholeMatch whole match + */ + + }, { + key: "checkCache", + value: function checkCache(wholeMatch, sentenceMakeFunc) { + var _context9, _context10; + + var lineCount = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; + this.sign = this.$engine.md5(wholeMatch); // miss cache + + if (!this.cache[this.sign]) { + return this.toHtml(wholeMatch, sentenceMakeFunc); + } // hit & mark cache + + + this.cache[this.sign].using = true; + return concat$5(_context9 = concat$5(_context10 = "".concat(this.cacheKey, "I")).call(_context10, this.sign, "_L")).call(_context9, lineCount, "$"); + } + }, { + key: "mounted", + value: function mounted() {// console.log('base mounted'); + } + }, { + key: "signWithCache", + value: function signWithCache(html) { + return false; + } + }]); + + return ParagraphBase; + }(SyntaxBase); - if (wheelSamples < 20) { - if (display.wheelStartX == null) { - display.wheelStartX = scroll.scrollLeft; display.wheelStartY = scroll.scrollTop; - display.wheelDX = dx; display.wheelDY = dy; - setTimeout(function () { - if (display.wheelStartX == null) { return } - var movedX = scroll.scrollLeft - display.wheelStartX; - var movedY = scroll.scrollTop - display.wheelStartY; - var sample = (movedY && display.wheelDY && movedY / display.wheelDY) || - (movedX && display.wheelDX && movedX / display.wheelDX); - display.wheelStartX = display.wheelStartY = null; - if (!sample) { return } - wheelPixelsPerUnit = (wheelPixelsPerUnit * wheelSamples + sample) / (wheelSamples + 1); - ++wheelSamples; - }, 200); - } else { - display.wheelDX += dx; display.wheelDY += dy; - } - } - } + _defineProperty(ParagraphBase, "HOOK_TYPE", HOOKS_TYPE_LIST.PAR); - // Selection objects are immutable. A new one is created every time - // the selection changes. A selection is one or more non-overlapping - // (and non-touching) ranges, sorted, and an integer that indicates - // which one is the primary selection (the one that's scrolled into - // view, that getCursor returns, etc). - var Selection = function (ranges, primIndex) { - this.ranges = ranges; - this.primIndex = primIndex; - }; + _defineProperty(ParagraphBase, "IN_PARAGRAPH_CACHE_KEY_PREFIX", '!'); - Selection.prototype.primary = function () { return this.ranges[this.primIndex] }; + _defineProperty(ParagraphBase, "IN_PARAGRAPH_CACHE_KEY_PREFIX_REGEX", '\\!'); - Selection.prototype.equals = function (other) { - if (other == this) { return true } - if (other.primIndex != this.primIndex || other.ranges.length != this.ranges.length) { return false } - for (var i = 0; i < this.ranges.length; i++) { - var here = this.ranges[i], there = other.ranges[i]; - if (!equalCursorPos(here.anchor, there.anchor) || !equalCursorPos(here.head, there.head)) { return false } - } - return true - }; + // FF26- bug: ArrayBuffers are non-extensible, but Object.isExtensible does not report it - Selection.prototype.deepCopy = function () { - var out = []; - for (var i = 0; i < this.ranges.length; i++) { out[i] = new Range(copyPos(this.ranges[i].anchor), copyPos(this.ranges[i].head)); } - return new Selection(out, this.primIndex) - }; - Selection.prototype.somethingSelected = function () { - for (var i = 0; i < this.ranges.length; i++) { if (!this.ranges[i].empty()) { return true } } - return false - }; + var arrayBufferNonExtensible = fails(function () { + if (typeof ArrayBuffer == 'function') { + var buffer = new ArrayBuffer(8); + // eslint-disable-next-line es-x/no-object-isextensible, es-x/no-object-defineproperty -- safe + if (Object.isExtensible(buffer)) Object.defineProperty(buffer, 'a', { value: 8 }); + } + }); - Selection.prototype.contains = function (pos, end) { - if (!end) { end = pos; } - for (var i = 0; i < this.ranges.length; i++) { - var range = this.ranges[i]; - if (cmp(end, range.from()) >= 0 && cmp(pos, range.to()) <= 0) { return i } - } - return -1 - }; + // eslint-disable-next-line es-x/no-object-isextensible -- safe + var $isExtensible = Object.isExtensible; + var FAILS_ON_PRIMITIVES$3 = fails(function () { $isExtensible(1); }); - var Range = function (anchor, head) { - this.anchor = anchor; this.head = head; - }; + // `Object.isExtensible` method + // https://tc39.es/ecma262/#sec-object.isextensible + var objectIsExtensible = (FAILS_ON_PRIMITIVES$3 || arrayBufferNonExtensible) ? function isExtensible(it) { + if (!isObject(it)) return false; + if (arrayBufferNonExtensible && classofRaw(it) == 'ArrayBuffer') return false; + return $isExtensible ? $isExtensible(it) : true; + } : $isExtensible; - Range.prototype.from = function () { return minPos(this.anchor, this.head) }; - Range.prototype.to = function () { return maxPos(this.anchor, this.head) }; - Range.prototype.empty = function () { return this.head.line == this.anchor.line && this.head.ch == this.anchor.ch }; - - // Take an unsorted, potentially overlapping set of ranges, and - // build a selection out of it. 'Consumes' ranges array (modifying - // it). - function normalizeSelection(cm, ranges, primIndex) { - var mayTouch = cm && cm.options.selectionsMayTouch; - var prim = ranges[primIndex]; - ranges.sort(function (a, b) { return cmp(a.from(), b.from()); }); - primIndex = indexOf(ranges, prim); - for (var i = 1; i < ranges.length; i++) { - var cur = ranges[i], prev = ranges[i - 1]; - var diff = cmp(prev.to(), cur.from()); - if (mayTouch && !cur.empty() ? diff > 0 : diff >= 0) { - var from = minPos(prev.from(), cur.from()), to = maxPos(prev.to(), cur.to()); - var inv = prev.empty() ? cur.from() == cur.head : prev.from() == prev.head; - if (i <= primIndex) { --primIndex; } - ranges.splice(--i, 2, new Range(inv ? to : from, inv ? from : to)); - } - } - return new Selection(ranges, primIndex) - } + var freezing = !fails(function () { + // eslint-disable-next-line es-x/no-object-isextensible, es-x/no-object-preventextensions -- required for testing + return Object.isExtensible(Object.preventExtensions({})); + }); - function simpleSelection(anchor, head) { - return new Selection([new Range(anchor, head || anchor)], 0) - } + var internalMetadata = createCommonjsModule(function (module) { + var defineProperty = objectDefineProperty.f; - // Compute the position of the end of a change (its 'to' property - // refers to the pre-change end). - function changeEnd(change) { - if (!change.text) { return change.to } - return Pos(change.from.line + change.text.length - 1, - lst(change.text).length + (change.text.length == 1 ? change.from.ch : 0)) - } - // Adjust a position to refer to the post-change position of the - // same text, or the end of the change if the change covers it. - function adjustForChange(pos, change) { - if (cmp(pos, change.from) < 0) { return pos } - if (cmp(pos, change.to) <= 0) { return changeEnd(change) } - var line = pos.line + change.text.length - (change.to.line - change.from.line) - 1, ch = pos.ch; - if (pos.line == change.to.line) { ch += changeEnd(change).ch - change.to.ch; } - return Pos(line, ch) - } - function computeSelAfterChange(doc, change) { - var out = []; - for (var i = 0; i < doc.sel.ranges.length; i++) { - var range = doc.sel.ranges[i]; - out.push(new Range(adjustForChange(range.anchor, change), - adjustForChange(range.head, change))); - } - return normalizeSelection(doc.cm, out, doc.sel.primIndex) - } - function offsetPos(pos, old, nw) { - if (pos.line == old.line) { return Pos(nw.line, pos.ch - old.ch + nw.ch) } - else { return Pos(nw.line + (pos.line - old.line), pos.ch) } - } - // Used by replaceSelections to allow moving the selection to the - // start or around the replaced test. Hint may be "start" or "around". - function computeReplacedSel(doc, changes, hint) { - var out = []; - var oldPrev = Pos(doc.first, 0), newPrev = oldPrev; - for (var i = 0; i < changes.length; i++) { - var change = changes[i]; - var from = offsetPos(change.from, oldPrev, newPrev); - var to = offsetPos(changeEnd(change), oldPrev, newPrev); - oldPrev = change.to; - newPrev = to; - if (hint == "around") { - var range = doc.sel.ranges[i], inv = cmp(range.head, range.anchor) < 0; - out[i] = new Range(inv ? to : from, inv ? from : to); - } else { - out[i] = new Range(from, from); - } - } - return new Selection(out, doc.sel.primIndex) - } + var REQUIRED = false; + var METADATA = uid('meta'); + var id = 0; - // Used to get the editor into a consistent state again when options change. + var setMetadata = function (it) { + defineProperty(it, METADATA, { value: { + objectID: 'O' + id++, // object ID + weakData: {} // weak collections IDs + } }); + }; - function loadMode(cm) { - cm.doc.mode = getMode(cm.options, cm.doc.modeOption); - resetModeState(cm); - } + var fastKey = function (it, create) { + // return a primitive with prefix + if (!isObject(it)) return typeof it == 'symbol' ? it : (typeof it == 'string' ? 'S' : 'P') + it; + if (!hasOwnProperty_1(it, METADATA)) { + // can't set metadata to uncaught frozen object + if (!objectIsExtensible(it)) return 'F'; + // not necessary to add metadata + if (!create) return 'E'; + // add missing metadata + setMetadata(it); + // return object ID + } return it[METADATA].objectID; + }; - function resetModeState(cm) { - cm.doc.iter(function (line) { - if (line.stateAfter) { line.stateAfter = null; } - if (line.styles) { line.styles = null; } - }); - cm.doc.modeFrontier = cm.doc.highlightFrontier = cm.doc.first; - startWorker(cm, 100); - cm.state.modeGen++; - if (cm.curOp) { regChange(cm); } - } + var getWeakData = function (it, create) { + if (!hasOwnProperty_1(it, METADATA)) { + // can't set metadata to uncaught frozen object + if (!objectIsExtensible(it)) return true; + // not necessary to add metadata + if (!create) return false; + // add missing metadata + setMetadata(it); + // return the store of weak collections IDs + } return it[METADATA].weakData; + }; - // DOCUMENT DATA STRUCTURE + // add metadata on freeze-family methods calling + var onFreeze = function (it) { + if (freezing && REQUIRED && objectIsExtensible(it) && !hasOwnProperty_1(it, METADATA)) setMetadata(it); + return it; + }; - // By default, updates that start and end at the beginning of a line - // are treated specially, in order to make the association of line - // widgets and marker elements with the text behave more intuitive. - function isWholeLineUpdate(doc, change) { - return change.from.ch == 0 && change.to.ch == 0 && lst(change.text) == "" && - (!doc.cm || doc.cm.options.wholeLineUpdateBefore) - } + var enable = function () { + meta.enable = function () { /* empty */ }; + REQUIRED = true; + var getOwnPropertyNames = objectGetOwnPropertyNames.f; + var splice = functionUncurryThis([].splice); + var test = {}; + test[METADATA] = 1; + + // prevent exposing of metadata key + if (getOwnPropertyNames(test).length) { + objectGetOwnPropertyNames.f = function (it) { + var result = getOwnPropertyNames(it); + for (var i = 0, length = result.length; i < length; i++) { + if (result[i] === METADATA) { + splice(result, i, 1); + break; + } + } return result; + }; + + _export({ target: 'Object', stat: true, forced: true }, { + getOwnPropertyNames: objectGetOwnPropertyNamesExternal.f + }); + } + }; - // Perform a change on the document data structure. - function updateDoc(doc, change, markedSpans, estimateHeight) { - function spansFor(n) { return markedSpans ? markedSpans[n] : null } - function update(line, text, spans) { - updateLine(line, text, spans, estimateHeight); - signalLater(line, "change", line, change); - } - function linesFor(start, end) { - var result = []; - for (var i = start; i < end; ++i) { result.push(new Line(text[i], spansFor(i), estimateHeight)); } - return result - } + var meta = module.exports = { + enable: enable, + fastKey: fastKey, + getWeakData: getWeakData, + onFreeze: onFreeze + }; - var from = change.from, to = change.to, text = change.text; - var firstLine = getLine(doc, from.line), lastLine = getLine(doc, to.line); - var lastText = lst(text), lastSpans = spansFor(text.length - 1), nlines = to.line - from.line; - - // Adjust the line structure - if (change.full) { - doc.insert(0, linesFor(0, text.length)); - doc.remove(text.length, doc.size - text.length); - } else if (isWholeLineUpdate(doc, change)) { - // This is a whole-line replace. Treated specially to make - // sure line objects move the way they are supposed to. - var added = linesFor(0, text.length - 1); - update(lastLine, lastLine.text, lastSpans); - if (nlines) { doc.remove(from.line, nlines); } - if (added.length) { doc.insert(from.line, added); } - } else if (firstLine == lastLine) { - if (text.length == 1) { - update(firstLine, firstLine.text.slice(0, from.ch) + lastText + firstLine.text.slice(to.ch), lastSpans); - } else { - var added$1 = linesFor(1, text.length - 1); - added$1.push(new Line(lastText + firstLine.text.slice(to.ch), lastSpans, estimateHeight)); - update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0)); - doc.insert(from.line + 1, added$1); - } - } else if (text.length == 1) { - update(firstLine, firstLine.text.slice(0, from.ch) + text[0] + lastLine.text.slice(to.ch), spansFor(0)); - doc.remove(from.line + 1, nlines); - } else { - update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0)); - update(lastLine, lastText + lastLine.text.slice(to.ch), lastSpans); - var added$2 = linesFor(1, text.length - 1); - if (nlines > 1) { doc.remove(from.line + 1, nlines - 1); } - doc.insert(from.line + 1, added$2); - } + hiddenKeys[METADATA] = true; + }); + var internalMetadata_1 = internalMetadata.enable; + var internalMetadata_2 = internalMetadata.fastKey; + var internalMetadata_3 = internalMetadata.getWeakData; + var internalMetadata_4 = internalMetadata.onFreeze; - signalLater(doc, "change", doc, change); - } + var TypeError$g = global_1.TypeError; - // Call f for all linked documents. - function linkedDocs(doc, f, sharedHistOnly) { - function propagate(doc, skip, sharedHist) { - if (doc.linked) { - for (var i = 0; i < doc.linked.length; ++i) { - var rel = doc.linked[i]; - if (rel.doc == skip) { continue } - var shared = sharedHist && rel.sharedHist; - if (sharedHistOnly && !shared) { continue } - f(rel.doc, shared); - propagate(rel.doc, doc, shared); - } - } - } - propagate(doc, null, true); - } + var Result = function (stopped, result) { + this.stopped = stopped; + this.result = result; + }; - // Attach a document to an editor. - function attachDoc(cm, doc) { - if (doc.cm) { throw new Error("This document is already in use.") } - cm.doc = doc; - doc.cm = cm; - estimateLineHeights(cm); - loadMode(cm); - setDirectionClass(cm); - if (!cm.options.lineWrapping) { findMaxLine(cm); } - cm.options.mode = doc.modeOption; - regChange(cm); - } + var ResultPrototype = Result.prototype; - function setDirectionClass(cm) { - (cm.doc.direction == "rtl" ? addClass : rmClass)(cm.display.lineDiv, "CodeMirror-rtl"); - } + var iterate = function (iterable, unboundFunction, options) { + var that = options && options.that; + var AS_ENTRIES = !!(options && options.AS_ENTRIES); + var IS_ITERATOR = !!(options && options.IS_ITERATOR); + var INTERRUPTED = !!(options && options.INTERRUPTED); + var fn = functionBindContext(unboundFunction, that); + var iterator, iterFn, index, length, result, next, step; + + var stop = function (condition) { + if (iterator) iteratorClose(iterator, 'normal', condition); + return new Result(true, condition); + }; + + var callFn = function (value) { + if (AS_ENTRIES) { + anObject(value); + return INTERRUPTED ? fn(value[0], value[1], stop) : fn(value[0], value[1]); + } return INTERRUPTED ? fn(value, stop) : fn(value); + }; + + if (IS_ITERATOR) { + iterator = iterable; + } else { + iterFn = getIteratorMethod(iterable); + if (!iterFn) throw TypeError$g(tryToString(iterable) + ' is not iterable'); + // optimisation for array iterators + if (isArrayIteratorMethod(iterFn)) { + for (index = 0, length = lengthOfArrayLike(iterable); length > index; index++) { + result = callFn(iterable[index]); + if (result && objectIsPrototypeOf(ResultPrototype, result)) return result; + } return new Result(false); + } + iterator = getIterator(iterable, iterFn); + } + + next = iterator.next; + while (!(step = functionCall(next, iterator)).done) { + try { + result = callFn(step.value); + } catch (error) { + iteratorClose(iterator, 'throw', error); + } + if (typeof result == 'object' && result && objectIsPrototypeOf(ResultPrototype, result)) return result; + } return new Result(false); + }; - function directionChanged(cm) { - runInOp(cm, function () { - setDirectionClass(cm); - regChange(cm); - }); - } + var TypeError$h = global_1.TypeError; - function History(startGen) { - // Arrays of change events and selections. Doing something adds an - // event to done and clears undo. Undoing moves events from done - // to undone, redoing moves them in the other direction. - this.done = []; this.undone = []; - this.undoDepth = Infinity; - // Used to track when changes can be merged into a single undo - // event - this.lastModTime = this.lastSelTime = 0; - this.lastOp = this.lastSelOp = null; - this.lastOrigin = this.lastSelOrigin = null; - // Used by the isClean() method - this.generation = this.maxGeneration = startGen || 1; - } + var anInstance = function (it, Prototype) { + if (objectIsPrototypeOf(Prototype, it)) return it; + throw TypeError$h('Incorrect invocation'); + }; - // Create a history change event from an updateDoc-style change - // object. - function historyChangeFromChange(doc, change) { - var histChange = { from: copyPos(change.from), to: changeEnd(change), text: getBetween(doc, change.from, change.to) }; - attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1); - linkedDocs(doc, function (doc) { return attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1); }, true); - return histChange - } + var defineProperty$d = objectDefineProperty.f; + var forEach$4 = arrayIteration.forEach; - // Pop all selection events off the end of a history array. Stop at - // a change event. - function clearSelectionEvents(array) { - while (array.length) { - var last = lst(array); - if (last.ranges) { array.pop(); } - else { break } - } - } - // Find the top change event in the history. Pop off selection - // events that are in the way. - function lastChangeEvent(hist, force) { - if (force) { - clearSelectionEvents(hist.done); - return lst(hist.done) - } else if (hist.done.length && !lst(hist.done).ranges) { - return lst(hist.done) - } else if (hist.done.length > 1 && !hist.done[hist.done.length - 2].ranges) { - hist.done.pop(); - return lst(hist.done) - } - } - // Register a change in the history. Merges changes that are within - // a single operation, or are close together with an origin that - // allows merging (starting with "+") into a single event. - function addChangeToHistory(doc, change, selAfter, opId) { - var hist = doc.history; - hist.undone.length = 0; - var time = +new Date, cur; - var last; - - if ((hist.lastOp == opId || - hist.lastOrigin == change.origin && change.origin && - ((change.origin.charAt(0) == "+" && hist.lastModTime > time - (doc.cm ? doc.cm.options.historyEventDelay : 500)) || - change.origin.charAt(0) == "*")) && - (cur = lastChangeEvent(hist, hist.lastOp == opId))) { - // Merge this change into the last event - last = lst(cur.changes); - if (cmp(change.from, change.to) == 0 && cmp(change.from, last.to) == 0) { - // Optimized case for simple insertion -- don't want to add - // new changesets for every character typed - last.to = changeEnd(change); - } else { - // Add new sub-event - cur.changes.push(historyChangeFromChange(doc, change)); - } - } else { - // Can not be merged, start a new event. - var before = lst(hist.done); - if (!before || !before.ranges) { pushSelectionToHistory(doc.sel, hist.done); } - cur = { - changes: [historyChangeFromChange(doc, change)], - generation: hist.generation - }; - hist.done.push(cur); - while (hist.done.length > hist.undoDepth) { - hist.done.shift(); - if (!hist.done[0].ranges) { hist.done.shift(); } - } - } - hist.done.push(selAfter); - hist.generation = ++hist.maxGeneration; - hist.lastModTime = hist.lastSelTime = time; - hist.lastOp = hist.lastSelOp = opId; - hist.lastOrigin = hist.lastSelOrigin = change.origin; + var setInternalState$3 = internalState.set; + var internalStateGetterFor = internalState.getterFor; - if (!last) { signal(doc, "historyAdded"); } - } + var collection = function (CONSTRUCTOR_NAME, wrapper, common) { + var IS_MAP = CONSTRUCTOR_NAME.indexOf('Map') !== -1; + var IS_WEAK = CONSTRUCTOR_NAME.indexOf('Weak') !== -1; + var ADDER = IS_MAP ? 'set' : 'add'; + var NativeConstructor = global_1[CONSTRUCTOR_NAME]; + var NativePrototype = NativeConstructor && NativeConstructor.prototype; + var exported = {}; + var Constructor; + + if (!descriptors || !isCallable(NativeConstructor) + || !(IS_WEAK || NativePrototype.forEach && !fails(function () { new NativeConstructor().entries().next(); })) + ) { + // create collection constructor + Constructor = common.getConstructor(wrapper, CONSTRUCTOR_NAME, IS_MAP, ADDER); + internalMetadata.enable(); + } else { + Constructor = wrapper(function (target, iterable) { + setInternalState$3(anInstance(target, Prototype), { + type: CONSTRUCTOR_NAME, + collection: new NativeConstructor() + }); + if (iterable != undefined) iterate(iterable, target[ADDER], { that: target, AS_ENTRIES: IS_MAP }); + }); + + var Prototype = Constructor.prototype; + + var getInternalState = internalStateGetterFor(CONSTRUCTOR_NAME); + + forEach$4(['add', 'clear', 'delete', 'forEach', 'get', 'has', 'set', 'keys', 'values', 'entries'], function (KEY) { + var IS_ADDER = KEY == 'add' || KEY == 'set'; + if (KEY in NativePrototype && !(IS_WEAK && KEY == 'clear')) { + createNonEnumerableProperty(Prototype, KEY, function (a, b) { + var collection = getInternalState(this).collection; + if (!IS_ADDER && IS_WEAK && !isObject(a)) return KEY == 'get' ? undefined : false; + var result = collection[KEY](a === 0 ? 0 : a, b); + return IS_ADDER ? this : result; + }); + } + }); + + IS_WEAK || defineProperty$d(Prototype, 'size', { + configurable: true, + get: function () { + return getInternalState(this).collection.size; + } + }); + } + + setToStringTag(Constructor, CONSTRUCTOR_NAME, false, true); + + exported[CONSTRUCTOR_NAME] = Constructor; + _export({ global: true, forced: true }, exported); + + if (!IS_WEAK) common.setStrong(Constructor, CONSTRUCTOR_NAME, IS_MAP); + + return Constructor; + }; - function selectionEventCanBeMerged(doc, origin, prev, sel) { - var ch = origin.charAt(0); - return ch == "*" || - ch == "+" && - prev.ranges.length == sel.ranges.length && - prev.somethingSelected() == sel.somethingSelected() && - new Date - doc.history.lastSelTime <= (doc.cm ? doc.cm.options.historyEventDelay : 500) - } + var defineBuiltIns = function (target, src, options) { + for (var key in src) { + if (options && options.unsafe && target[key]) target[key] = src[key]; + else defineBuiltIn(target, key, src[key], options); + } return target; + }; - // Called whenever the selection changes, sets the new selection as - // the pending selection in the history, and pushes the old pending - // selection into the 'done' array when it was significantly - // different (in number of selected ranges, emptiness, or time). - function addSelectionToHistory(doc, sel, opId, options) { - var hist = doc.history, origin = options && options.origin; - - // A new event is started when the previous origin does not match - // the current, or the origins don't allow matching. Origins - // starting with * are always merged, those starting with + are - // merged when similar and close together in time. - if (opId == hist.lastSelOp || - (origin && hist.lastSelOrigin == origin && - (hist.lastModTime == hist.lastSelTime && hist.lastOrigin == origin || - selectionEventCanBeMerged(doc, origin, lst(hist.done), sel)))) { hist.done[hist.done.length - 1] = sel; } - else { pushSelectionToHistory(sel, hist.done); } - - hist.lastSelTime = +new Date; - hist.lastSelOrigin = origin; - hist.lastSelOp = opId; - if (options && options.clearRedo !== false) { clearSelectionEvents(hist.undone); } - } + var SPECIES$3 = wellKnownSymbol('species'); - function pushSelectionToHistory(sel, dest) { - var top = lst(dest); - if (!(top && top.ranges && top.equals(sel))) { dest.push(sel); } - } + var setSpecies = function (CONSTRUCTOR_NAME) { + var Constructor = getBuiltIn(CONSTRUCTOR_NAME); + var defineProperty = objectDefineProperty.f; + + if (descriptors && Constructor && !Constructor[SPECIES$3]) { + defineProperty(Constructor, SPECIES$3, { + configurable: true, + get: function () { return this; } + }); + } + }; - // Used to store marked span information in the history. - function attachLocalSpans(doc, change, from, to) { - var existing = change["spans_" + doc.id], n = 0; - doc.iter(Math.max(doc.first, from), Math.min(doc.first + doc.size, to), function (line) { - if (line.markedSpans) { (existing || (existing = change["spans_" + doc.id] = {}))[n] = line.markedSpans; } - ++n; - }); - } + var defineProperty$e = objectDefineProperty.f; - // When un/re-doing restores text containing marked spans, those - // that have been explicitly cleared should not be restored. - function removeClearedSpans(spans) { - if (!spans) { return null } - var out; - for (var i = 0; i < spans.length; ++i) { - if (spans[i].marker.explicitlyCleared) { if (!out) { out = spans.slice(0, i); } } - else if (out) { out.push(spans[i]); } - } - return !out ? spans : out.length ? out : null - } - // Retrieve and filter the old marked spans stored in a change event. - function getOldSpans(doc, change) { - var found = change["spans_" + doc.id]; - if (!found) { return null } - var nw = []; - for (var i = 0; i < change.text.length; ++i) { nw.push(removeClearedSpans(found[i])); } - return nw - } - // Used for un/re-doing changes from the history. Combines the - // result of computing the existing spans with the set of spans that - // existed in the history (so that deleting around a span and then - // undoing brings back the span). - function mergeOldSpans(doc, change) { - var old = getOldSpans(doc, change); - var stretched = stretchSpansOverChange(doc, change); - if (!old) { return stretched } - if (!stretched) { return old } - - for (var i = 0; i < old.length; ++i) { - var oldCur = old[i], stretchCur = stretched[i]; - if (oldCur && stretchCur) { - spans: for (var j = 0; j < stretchCur.length; ++j) { - var span = stretchCur[j]; - for (var k = 0; k < oldCur.length; ++k) { if (oldCur[k].marker == span.marker) { continue spans } } - oldCur.push(span); - } - } else if (stretchCur) { - old[i] = stretchCur; - } - } - return old - } - // Used both to provide a JSON-safe object in .getHistory, and, when - // detaching a document, to split the history in two - function copyHistoryArray(events, newGroup, instantiateSel) { - var copy = []; - for (var i = 0; i < events.length; ++i) { - var event = events[i]; - if (event.ranges) { - copy.push(instantiateSel ? Selection.prototype.deepCopy.call(event) : event); - continue - } - var changes = event.changes, newChanges = []; - copy.push({ changes: newChanges }); - for (var j = 0; j < changes.length; ++j) { - var change = changes[j], m = (void 0); - newChanges.push({ from: change.from, to: change.to, text: change.text }); - if (newGroup) { - for (var prop in change) { - if (m = prop.match(/^spans_(\d+)$/)) { - if (indexOf(newGroup, Number(m[1])) > -1) { - lst(newChanges)[prop] = change[prop]; - delete change[prop]; - } - } - } - } - } - } - return copy - } - // The 'scroll' parameter given to many of these indicated whether - // the new cursor position should be scrolled into view after - // modifying the selection. - - // If shift is held or the extend flag is set, extends a range to - // include a given position (and optionally a second position). - // Otherwise, simply returns the range between the given positions. - // Used for cursor motion and such. - function extendRange(range, head, other, extend) { - if (extend) { - var anchor = range.anchor; - if (other) { - var posBefore = cmp(head, anchor) < 0; - if (posBefore != (cmp(other, anchor) < 0)) { - anchor = head; - head = other; - } else if (posBefore != (cmp(head, other) < 0)) { - head = other; - } - } - return new Range(anchor, head) - } else { - return new Range(other || head, head) - } - } - // Extend the primary selection range, discard the rest. - function extendSelection(doc, head, other, options, extend) { - if (extend == null) { extend = doc.cm && (doc.cm.display.shift || doc.extend); } - setSelection(doc, new Selection([extendRange(doc.sel.primary(), head, other, extend)], 0), options); - } - // Extend all selections (pos is an array of selections with length - // equal the number of selections) - function extendSelections(doc, heads, options) { - var out = []; - var extend = doc.cm && (doc.cm.display.shift || doc.extend); - for (var i = 0; i < doc.sel.ranges.length; i++) { out[i] = extendRange(doc.sel.ranges[i], heads[i], null, extend); } - var newSel = normalizeSelection(doc.cm, out, doc.sel.primIndex); - setSelection(doc, newSel, options); - } - // Updates a single range in the selection. - function replaceOneSelection(doc, i, range, options) { - var ranges = doc.sel.ranges.slice(0); - ranges[i] = range; - setSelection(doc, normalizeSelection(doc.cm, ranges, doc.sel.primIndex), options); - } + var fastKey = internalMetadata.fastKey; - // Reset the selection to a single range. - function setSimpleSelection(doc, anchor, head, options) { - setSelection(doc, simpleSelection(anchor, head), options); - } - // Give beforeSelectionChange handlers a change to influence a - // selection update. - function filterSelectionChange(doc, sel, options) { - var obj = { - ranges: sel.ranges, - update: function (ranges) { - this.ranges = []; - for (var i = 0; i < ranges.length; i++) { - this.ranges[i] = new Range(clipPos(doc, ranges[i].anchor), - clipPos(doc, ranges[i].head)); - } - }, - origin: options && options.origin - }; - signal(doc, "beforeSelectionChange", doc, obj); - if (doc.cm) { signal(doc.cm, "beforeSelectionChange", doc.cm, obj); } - if (obj.ranges != sel.ranges) { return normalizeSelection(doc.cm, obj.ranges, obj.ranges.length - 1) } - else { return sel } - } + var setInternalState$4 = internalState.set; + var internalStateGetterFor$1 = internalState.getterFor; - function setSelectionReplaceHistory(doc, sel, options) { - var done = doc.history.done, last = lst(done); - if (last && last.ranges) { - done[done.length - 1] = sel; - setSelectionNoUndo(doc, sel, options); - } else { - setSelection(doc, sel, options); - } - } + var collectionStrong = { + getConstructor: function (wrapper, CONSTRUCTOR_NAME, IS_MAP, ADDER) { + var Constructor = wrapper(function (that, iterable) { + anInstance(that, Prototype); + setInternalState$4(that, { + type: CONSTRUCTOR_NAME, + index: objectCreate(null), + first: undefined, + last: undefined, + size: 0 + }); + if (!descriptors) that.size = 0; + if (iterable != undefined) iterate(iterable, that[ADDER], { that: that, AS_ENTRIES: IS_MAP }); + }); + + var Prototype = Constructor.prototype; + + var getInternalState = internalStateGetterFor$1(CONSTRUCTOR_NAME); + + var define = function (that, key, value) { + var state = getInternalState(that); + var entry = getEntry(that, key); + var previous, index; + // change existing entry + if (entry) { + entry.value = value; + // create new entry + } else { + state.last = entry = { + index: index = fastKey(key, true), + key: key, + value: value, + previous: previous = state.last, + next: undefined, + removed: false + }; + if (!state.first) state.first = entry; + if (previous) previous.next = entry; + if (descriptors) state.size++; + else that.size++; + // add to index + if (index !== 'F') state.index[index] = entry; + } return that; + }; + + var getEntry = function (that, key) { + var state = getInternalState(that); + // fast case + var index = fastKey(key); + var entry; + if (index !== 'F') return state.index[index]; + // frozen object case + for (entry = state.first; entry; entry = entry.next) { + if (entry.key == key) return entry; + } + }; + + defineBuiltIns(Prototype, { + // `{ Map, Set }.prototype.clear()` methods + // https://tc39.es/ecma262/#sec-map.prototype.clear + // https://tc39.es/ecma262/#sec-set.prototype.clear + clear: function clear() { + var that = this; + var state = getInternalState(that); + var data = state.index; + var entry = state.first; + while (entry) { + entry.removed = true; + if (entry.previous) entry.previous = entry.previous.next = undefined; + delete data[entry.index]; + entry = entry.next; + } + state.first = state.last = undefined; + if (descriptors) state.size = 0; + else that.size = 0; + }, + // `{ Map, Set }.prototype.delete(key)` methods + // https://tc39.es/ecma262/#sec-map.prototype.delete + // https://tc39.es/ecma262/#sec-set.prototype.delete + 'delete': function (key) { + var that = this; + var state = getInternalState(that); + var entry = getEntry(that, key); + if (entry) { + var next = entry.next; + var prev = entry.previous; + delete state.index[entry.index]; + entry.removed = true; + if (prev) prev.next = next; + if (next) next.previous = prev; + if (state.first == entry) state.first = next; + if (state.last == entry) state.last = prev; + if (descriptors) state.size--; + else that.size--; + } return !!entry; + }, + // `{ Map, Set }.prototype.forEach(callbackfn, thisArg = undefined)` methods + // https://tc39.es/ecma262/#sec-map.prototype.foreach + // https://tc39.es/ecma262/#sec-set.prototype.foreach + forEach: function forEach(callbackfn /* , that = undefined */) { + var state = getInternalState(this); + var boundFunction = functionBindContext(callbackfn, arguments.length > 1 ? arguments[1] : undefined); + var entry; + while (entry = entry ? entry.next : state.first) { + boundFunction(entry.value, entry.key, this); + // revert to the last existing entry + while (entry && entry.removed) entry = entry.previous; + } + }, + // `{ Map, Set}.prototype.has(key)` methods + // https://tc39.es/ecma262/#sec-map.prototype.has + // https://tc39.es/ecma262/#sec-set.prototype.has + has: function has(key) { + return !!getEntry(this, key); + } + }); + + defineBuiltIns(Prototype, IS_MAP ? { + // `Map.prototype.get(key)` method + // https://tc39.es/ecma262/#sec-map.prototype.get + get: function get(key) { + var entry = getEntry(this, key); + return entry && entry.value; + }, + // `Map.prototype.set(key, value)` method + // https://tc39.es/ecma262/#sec-map.prototype.set + set: function set(key, value) { + return define(this, key === 0 ? 0 : key, value); + } + } : { + // `Set.prototype.add(value)` method + // https://tc39.es/ecma262/#sec-set.prototype.add + add: function add(value) { + return define(this, value = value === 0 ? 0 : value, value); + } + }); + if (descriptors) defineProperty$e(Prototype, 'size', { + get: function () { + return getInternalState(this).size; + } + }); + return Constructor; + }, + setStrong: function (Constructor, CONSTRUCTOR_NAME, IS_MAP) { + var ITERATOR_NAME = CONSTRUCTOR_NAME + ' Iterator'; + var getInternalCollectionState = internalStateGetterFor$1(CONSTRUCTOR_NAME); + var getInternalIteratorState = internalStateGetterFor$1(ITERATOR_NAME); + // `{ Map, Set }.prototype.{ keys, values, entries, @@iterator }()` methods + // https://tc39.es/ecma262/#sec-map.prototype.entries + // https://tc39.es/ecma262/#sec-map.prototype.keys + // https://tc39.es/ecma262/#sec-map.prototype.values + // https://tc39.es/ecma262/#sec-map.prototype-@@iterator + // https://tc39.es/ecma262/#sec-set.prototype.entries + // https://tc39.es/ecma262/#sec-set.prototype.keys + // https://tc39.es/ecma262/#sec-set.prototype.values + // https://tc39.es/ecma262/#sec-set.prototype-@@iterator + defineIterator(Constructor, CONSTRUCTOR_NAME, function (iterated, kind) { + setInternalState$4(this, { + type: ITERATOR_NAME, + target: iterated, + state: getInternalCollectionState(iterated), + kind: kind, + last: undefined + }); + }, function () { + var state = getInternalIteratorState(this); + var kind = state.kind; + var entry = state.last; + // revert to the last existing entry + while (entry && entry.removed) entry = entry.previous; + // get next entry + if (!state.target || !(state.last = entry = entry ? entry.next : state.state.first)) { + // or finish the iteration + state.target = undefined; + return { value: undefined, done: true }; + } + // return step by kind + if (kind == 'keys') return { value: entry.key, done: false }; + if (kind == 'values') return { value: entry.value, done: false }; + return { value: [entry.key, entry.value], done: false }; + }, IS_MAP ? 'entries' : 'values', !IS_MAP, true); + + // `{ Map, Set }.prototype[@@species]` accessors + // https://tc39.es/ecma262/#sec-get-map-@@species + // https://tc39.es/ecma262/#sec-get-set-@@species + setSpecies(CONSTRUCTOR_NAME); + } + }; - // Set a new selection. - function setSelection(doc, sel, options) { - setSelectionNoUndo(doc, sel, options); - addSelectionToHistory(doc, doc.sel, doc.cm ? doc.cm.curOp.id : NaN, options); - } + // `Map` constructor + // https://tc39.es/ecma262/#sec-map-objects + collection('Map', function (init) { + return function Map() { return init(this, arguments.length ? arguments[0] : undefined); }; + }, collectionStrong); - function setSelectionNoUndo(doc, sel, options) { - if (hasHandler(doc, "beforeSelectionChange") || doc.cm && hasHandler(doc.cm, "beforeSelectionChange")) { sel = filterSelectionChange(doc, sel, options); } + var map$4 = path.Map; - var bias = options && options.bias || - (cmp(sel.primary().head, doc.sel.primary().head) < 0 ? -1 : 1); - setSelectionInner(doc, skipAtomicInSelection(doc, sel, bias, true)); + var map$5 = map$4; - if (!(options && options.scroll === false) && doc.cm) { ensureCursorVisible(doc.cm); } - } + var map$6 = map$5; - function setSelectionInner(doc, sel) { - if (sel.equals(doc.sel)) { return } + // https://tc39.github.io/proposal-setmap-offrom/ - doc.sel = sel; - if (doc.cm) { - doc.cm.curOp.updateInput = 1; - doc.cm.curOp.selectionChanged = true; - signalCursorActivity(doc.cm); - } - signalLater(doc, "cursorActivity", doc); - } - // Verify that the selection does not partially select any atomic - // marked ranges. - function reCheckSelection(doc) { - setSelectionInner(doc, skipAtomicInSelection(doc, doc.sel, null, false)); - } - // Return a selection that does not partially select any atomic - // ranges. - function skipAtomicInSelection(doc, sel, bias, mayClear) { - var out; - for (var i = 0; i < sel.ranges.length; i++) { - var range = sel.ranges[i]; - var old = sel.ranges.length == doc.sel.ranges.length && doc.sel.ranges[i]; - var newAnchor = skipAtomic(doc, range.anchor, old && old.anchor, bias, mayClear); - var newHead = skipAtomic(doc, range.head, old && old.head, bias, mayClear); - if (out || newAnchor != range.anchor || newHead != range.head) { - if (!out) { out = sel.ranges.slice(0, i); } - out[i] = new Range(newAnchor, newHead); - } - } - return out ? normalizeSelection(doc.cm, out, sel.primIndex) : sel - } - function skipAtomicInner(doc, pos, oldPos, dir, mayClear) { - var line = getLine(doc, pos.line); - if (line.markedSpans) { - for (var i = 0; i < line.markedSpans.length; ++i) { - var sp = line.markedSpans[i], m = sp.marker; - - // Determine if we should prevent the cursor being placed to the left/right of an atomic marker - // Historically this was determined using the inclusiveLeft/Right option, but the new way to control it - // is with selectLeft/Right - var preventCursorLeft = ("selectLeft" in m) ? !m.selectLeft : m.inclusiveLeft; - var preventCursorRight = ("selectRight" in m) ? !m.selectRight : m.inclusiveRight; - - if ((sp.from == null || (preventCursorLeft ? sp.from <= pos.ch : sp.from < pos.ch)) && - (sp.to == null || (preventCursorRight ? sp.to >= pos.ch : sp.to > pos.ch))) { - if (mayClear) { - signal(m, "beforeCursorEnter"); - if (m.explicitlyCleared) { - if (!line.markedSpans) { break } - else { --i; continue } - } - } - if (!m.atomic) { continue } - if (oldPos) { - var near = m.find(dir < 0 ? 1 : -1), diff = (void 0); - if (dir < 0 ? preventCursorRight : preventCursorLeft) { near = movePos(doc, near, -dir, near && near.line == pos.line ? line : null); } - if (near && near.line == pos.line && (diff = cmp(near, oldPos)) && (dir < 0 ? diff < 0 : diff > 0)) { return skipAtomicInner(doc, near, pos, dir, mayClear) } - } + var push$4 = [].push; - var far = m.find(dir < 0 ? -1 : 1); - if (dir < 0 ? preventCursorLeft : preventCursorRight) { far = movePos(doc, far, dir, far.line == pos.line ? line : null); } - return far ? skipAtomicInner(doc, far, pos, dir, mayClear) : null - } - } - } - return pos - } + var collectionFrom = function from(source /* , mapFn, thisArg */) { + var length = arguments.length; + var mapFn = length > 1 ? arguments[1] : undefined; + var mapping, array, n, boundFunction; + aConstructor(this); + mapping = mapFn !== undefined; + if (mapping) aCallable(mapFn); + if (source == undefined) return new this(); + array = []; + if (mapping) { + n = 0; + boundFunction = functionBindContext(mapFn, length > 2 ? arguments[2] : undefined); + iterate(source, function (nextItem) { + functionCall(push$4, array, boundFunction(nextItem, n++)); + }); + } else { + iterate(source, push$4, { that: array }); + } + return new this(array); + }; - // Ensure a given position is not inside an atomic range. - function skipAtomic(doc, pos, oldPos, bias, mayClear) { - var dir = bias || 1; - var found = skipAtomicInner(doc, pos, oldPos, dir, mayClear) || - (!mayClear && skipAtomicInner(doc, pos, oldPos, dir, true)) || - skipAtomicInner(doc, pos, oldPos, -dir, mayClear) || - (!mayClear && skipAtomicInner(doc, pos, oldPos, -dir, true)); - if (!found) { - doc.cantEdit = true; - return Pos(doc.first, 0) - } - return found - } + // `Map.from` method + // https://tc39.github.io/proposal-setmap-offrom/#sec-map.from + _export({ target: 'Map', stat: true, forced: true }, { + from: collectionFrom + }); - function movePos(doc, pos, dir, line) { - if (dir < 0 && pos.ch == 0) { - if (pos.line > doc.first) { return clipPos(doc, Pos(pos.line - 1)) } - else { return null } - } else if (dir > 0 && pos.ch == (line || getLine(doc, pos.line)).text.length) { - if (pos.line < doc.first + doc.size - 1) { return Pos(pos.line + 1, 0) } - else { return null } - } else { - return new Pos(pos.line, pos.ch + dir) - } - } + // https://tc39.github.io/proposal-setmap-offrom/ + var collectionOf = function of() { + return new this(arraySlice(arguments)); + }; - function selectAll(cm) { - cm.setSelection(Pos(cm.firstLine(), 0), Pos(cm.lastLine()), sel_dontScroll); - } + // `Map.of` method + // https://tc39.github.io/proposal-setmap-offrom/#sec-map.of + _export({ target: 'Map', stat: true, forced: true }, { + of: collectionOf + }); - // UPDATING - - // Allow "beforeChange" event handlers to influence a change - function filterChange(doc, change, update) { - var obj = { - canceled: false, - from: change.from, - to: change.to, - text: change.text, - origin: change.origin, - cancel: function () { return obj.canceled = true; } - }; - if (update) { - obj.update = function (from, to, text, origin) { - if (from) { obj.from = clipPos(doc, from); } - if (to) { obj.to = clipPos(doc, to); } - if (text) { obj.text = text; } - if (origin !== undefined) { obj.origin = origin; } - }; - } - signal(doc, "beforeChange", doc, obj); - if (doc.cm) { signal(doc.cm, "beforeChange", doc.cm, obj); } + // https://github.com/tc39/collection-methods + var collectionDeleteAll = function deleteAll(/* ...elements */) { + var collection = anObject(this); + var remover = aCallable(collection['delete']); + var allDeleted = true; + var wasDeleted; + for (var k = 0, len = arguments.length; k < len; k++) { + wasDeleted = functionCall(remover, collection, arguments[k]); + allDeleted = allDeleted && wasDeleted; + } + return !!allDeleted; + }; - if (obj.canceled) { - if (doc.cm) { doc.cm.curOp.updateInput = 2; } - return null - } - return { from: obj.from, to: obj.to, text: obj.text, origin: obj.origin } - } + // `Map.prototype.deleteAll` method + // https://github.com/tc39/proposal-collection-methods + _export({ target: 'Map', proto: true, real: true, forced: true }, { + deleteAll: collectionDeleteAll + }); - // Apply a change to a document, and add it to the document's - // history, and propagating it to all linked documents. - function makeChange(doc, change, ignoreReadOnly) { - if (doc.cm) { - if (!doc.cm.curOp) { return operation(doc.cm, makeChange)(doc, change, ignoreReadOnly) } - if (doc.cm.state.suppressEdits) { return } - } + // `Map.prototype.emplace` method + // https://github.com/thumbsupep/proposal-upsert + var mapEmplace = function emplace(key, handler) { + var map = anObject(this); + var get = aCallable(map.get); + var has = aCallable(map.has); + var set = aCallable(map.set); + var value = (functionCall(has, map, key) && 'update' in handler) + ? handler.update(functionCall(get, map, key), key, map) + : handler.insert(key, map); + functionCall(set, map, key, value); + return value; + }; - if (hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange")) { - change = filterChange(doc, change, true); - if (!change) { return } - } + // `Map.prototype.emplace` method + // https://github.com/thumbsupep/proposal-upsert + _export({ target: 'Map', proto: true, real: true, forced: true }, { + emplace: mapEmplace + }); - // Possibly split or suppress the update based on the presence - // of read-only spans in its range. - var split = sawReadOnlySpans && !ignoreReadOnly && removeReadOnlyRanges(doc, change.from, change.to); - if (split) { - for (var i = split.length - 1; i >= 0; --i) { makeChangeInner(doc, { from: split[i].from, to: split[i].to, text: i ? [""] : change.text, origin: change.origin }); } - } else { - makeChangeInner(doc, change); - } - } + var getMapIterator = getIterator; - function makeChangeInner(doc, change) { - if (change.text.length == 1 && change.text[0] == "" && cmp(change.from, change.to) == 0) { return } - var selAfter = computeSelAfterChange(doc, change); - addChangeToHistory(doc, change, selAfter, doc.cm ? doc.cm.curOp.id : NaN); + // `Map.prototype.every` method + // https://github.com/tc39/proposal-collection-methods + _export({ target: 'Map', proto: true, real: true, forced: true }, { + every: function every(callbackfn /* , thisArg */) { + var map = anObject(this); + var iterator = getMapIterator(map); + var boundFunction = functionBindContext(callbackfn, arguments.length > 1 ? arguments[1] : undefined); + return !iterate(iterator, function (key, value, stop) { + if (!boundFunction(value, key, map)) return stop(); + }, { AS_ENTRIES: true, IS_ITERATOR: true, INTERRUPTED: true }).stopped; + } + }); - makeChangeSingleDoc(doc, change, selAfter, stretchSpansOverChange(doc, change)); - var rebased = []; + var SPECIES$4 = wellKnownSymbol('species'); - linkedDocs(doc, function (doc, sharedHist) { - if (!sharedHist && indexOf(rebased, doc.history) == -1) { - rebaseHist(doc.history, change); - rebased.push(doc.history); - } - makeChangeSingleDoc(doc, change, null, stretchSpansOverChange(doc, change)); - }); - } + // `SpeciesConstructor` abstract operation + // https://tc39.es/ecma262/#sec-speciesconstructor + var speciesConstructor = function (O, defaultConstructor) { + var C = anObject(O).constructor; + var S; + return C === undefined || (S = anObject(C)[SPECIES$4]) == undefined ? defaultConstructor : aConstructor(S); + }; - // Revert a change stored in a document's history. - function makeChangeFromHistory(doc, type, allowSelectionOnly) { - var suppress = doc.cm && doc.cm.state.suppressEdits; - if (suppress && !allowSelectionOnly) { return } + // `Map.prototype.filter` method + // https://github.com/tc39/proposal-collection-methods + _export({ target: 'Map', proto: true, real: true, forced: true }, { + filter: function filter(callbackfn /* , thisArg */) { + var map = anObject(this); + var iterator = getMapIterator(map); + var boundFunction = functionBindContext(callbackfn, arguments.length > 1 ? arguments[1] : undefined); + var newMap = new (speciesConstructor(map, getBuiltIn('Map')))(); + var setter = aCallable(newMap.set); + iterate(iterator, function (key, value) { + if (boundFunction(value, key, map)) functionCall(setter, newMap, key, value); + }, { AS_ENTRIES: true, IS_ITERATOR: true }); + return newMap; + } + }); - var hist = doc.history, event, selAfter = doc.sel; - var source = type == "undo" ? hist.done : hist.undone, dest = type == "undo" ? hist.undone : hist.done; + // `Map.prototype.find` method + // https://github.com/tc39/proposal-collection-methods + _export({ target: 'Map', proto: true, real: true, forced: true }, { + find: function find(callbackfn /* , thisArg */) { + var map = anObject(this); + var iterator = getMapIterator(map); + var boundFunction = functionBindContext(callbackfn, arguments.length > 1 ? arguments[1] : undefined); + return iterate(iterator, function (key, value, stop) { + if (boundFunction(value, key, map)) return stop(value); + }, { AS_ENTRIES: true, IS_ITERATOR: true, INTERRUPTED: true }).result; + } + }); - // Verify that there is a useable event (so that ctrl-z won't - // needlessly clear selection events) - var i = 0; - for (; i < source.length; i++) { - event = source[i]; - if (allowSelectionOnly ? event.ranges && !event.equals(doc.sel) : !event.ranges) { break } - } - if (i == source.length) { return } - hist.lastOrigin = hist.lastSelOrigin = null; - - for (; ;) { - event = source.pop(); - if (event.ranges) { - pushSelectionToHistory(event, dest); - if (allowSelectionOnly && !event.equals(doc.sel)) { - setSelection(doc, event, { clearRedo: false }); - return - } - selAfter = event; - } else if (suppress) { - source.push(event); - return - } else { break } - } + // `Map.prototype.findKey` method + // https://github.com/tc39/proposal-collection-methods + _export({ target: 'Map', proto: true, real: true, forced: true }, { + findKey: function findKey(callbackfn /* , thisArg */) { + var map = anObject(this); + var iterator = getMapIterator(map); + var boundFunction = functionBindContext(callbackfn, arguments.length > 1 ? arguments[1] : undefined); + return iterate(iterator, function (key, value, stop) { + if (boundFunction(value, key, map)) return stop(key); + }, { AS_ENTRIES: true, IS_ITERATOR: true, INTERRUPTED: true }).result; + } + }); - // Build up a reverse change object to add to the opposite history - // stack (redo when undoing, and vice versa). - var antiChanges = []; - pushSelectionToHistory(selAfter, dest); - dest.push({ changes: antiChanges, generation: hist.generation }); - hist.generation = event.generation || ++hist.maxGeneration; - - var filter = hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange"); - - var loop = function (i) { - var change = event.changes[i]; - change.origin = type; - if (filter && !filterChange(doc, change, false)) { - source.length = 0; - return {} - } + var push$5 = functionUncurryThis([].push); - antiChanges.push(historyChangeFromChange(doc, change)); + // `Map.groupBy` method + // https://github.com/tc39/proposal-collection-methods + _export({ target: 'Map', stat: true, forced: true }, { + groupBy: function groupBy(iterable, keyDerivative) { + aCallable(keyDerivative); + var iterator = getIterator(iterable); + var newMap = new this(); + var has = aCallable(newMap.has); + var get = aCallable(newMap.get); + var set = aCallable(newMap.set); + iterate(iterator, function (element) { + var derivedKey = keyDerivative(element); + if (!functionCall(has, newMap, derivedKey)) functionCall(set, newMap, derivedKey, [element]); + else push$5(functionCall(get, newMap, derivedKey), element); + }, { IS_ITERATOR: true }); + return newMap; + } + }); - var after = i ? computeSelAfterChange(doc, change) : lst(source); - makeChangeSingleDoc(doc, change, after, mergeOldSpans(doc, change)); - if (!i && doc.cm) { doc.cm.scrollIntoView({ from: change.from, to: changeEnd(change) }); } - var rebased = []; + // `SameValueZero` abstract operation + // https://tc39.es/ecma262/#sec-samevaluezero + var sameValueZero = function (x, y) { + // eslint-disable-next-line no-self-compare -- NaN check + return x === y || x != x && y != y; + }; - // Propagate to the linked documents - linkedDocs(doc, function (doc, sharedHist) { - if (!sharedHist && indexOf(rebased, doc.history) == -1) { - rebaseHist(doc.history, change); - rebased.push(doc.history); - } - makeChangeSingleDoc(doc, change, null, mergeOldSpans(doc, change)); - }); - }; + // `Map.prototype.includes` method + // https://github.com/tc39/proposal-collection-methods + _export({ target: 'Map', proto: true, real: true, forced: true }, { + includes: function includes(searchElement) { + return iterate(getMapIterator(anObject(this)), function (key, value, stop) { + if (sameValueZero(value, searchElement)) return stop(); + }, { AS_ENTRIES: true, IS_ITERATOR: true, INTERRUPTED: true }).stopped; + } + }); - for (var i$1 = event.changes.length - 1; i$1 >= 0; --i$1) { - var returned = loop(i$1); + // `Map.keyBy` method + // https://github.com/tc39/proposal-collection-methods + _export({ target: 'Map', stat: true, forced: true }, { + keyBy: function keyBy(iterable, keyDerivative) { + var newMap = new this(); + aCallable(keyDerivative); + var setter = aCallable(newMap.set); + iterate(iterable, function (element) { + functionCall(setter, newMap, keyDerivative(element), element); + }); + return newMap; + } + }); - if (returned) return returned.v; - } - } + // `Map.prototype.keyOf` method + // https://github.com/tc39/proposal-collection-methods + _export({ target: 'Map', proto: true, real: true, forced: true }, { + keyOf: function keyOf(searchElement) { + return iterate(getMapIterator(anObject(this)), function (key, value, stop) { + if (value === searchElement) return stop(key); + }, { AS_ENTRIES: true, IS_ITERATOR: true, INTERRUPTED: true }).result; + } + }); - // Sub-views need their line numbers shifted when text is added - // above or below them in the parent document. - function shiftDoc(doc, distance) { - if (distance == 0) { return } - doc.first += distance; - doc.sel = new Selection(map(doc.sel.ranges, function (range) { - return new Range( - Pos(range.anchor.line + distance, range.anchor.ch), - Pos(range.head.line + distance, range.head.ch) - ); - }), doc.sel.primIndex); - if (doc.cm) { - regChange(doc.cm, doc.first, doc.first - distance, distance); - for (var d = doc.cm.display, l = d.viewFrom; l < d.viewTo; l++) { regLineChange(doc.cm, l, "gutter"); } - } - } + // `Map.prototype.mapKeys` method + // https://github.com/tc39/proposal-collection-methods + _export({ target: 'Map', proto: true, real: true, forced: true }, { + mapKeys: function mapKeys(callbackfn /* , thisArg */) { + var map = anObject(this); + var iterator = getMapIterator(map); + var boundFunction = functionBindContext(callbackfn, arguments.length > 1 ? arguments[1] : undefined); + var newMap = new (speciesConstructor(map, getBuiltIn('Map')))(); + var setter = aCallable(newMap.set); + iterate(iterator, function (key, value) { + functionCall(setter, newMap, boundFunction(value, key, map), value); + }, { AS_ENTRIES: true, IS_ITERATOR: true }); + return newMap; + } + }); - // More lower-level change function, handling only a single document - // (not linked ones). - function makeChangeSingleDoc(doc, change, selAfter, spans) { - if (doc.cm && !doc.cm.curOp) { return operation(doc.cm, makeChangeSingleDoc)(doc, change, selAfter, spans) } + // `Map.prototype.mapValues` method + // https://github.com/tc39/proposal-collection-methods + _export({ target: 'Map', proto: true, real: true, forced: true }, { + mapValues: function mapValues(callbackfn /* , thisArg */) { + var map = anObject(this); + var iterator = getMapIterator(map); + var boundFunction = functionBindContext(callbackfn, arguments.length > 1 ? arguments[1] : undefined); + var newMap = new (speciesConstructor(map, getBuiltIn('Map')))(); + var setter = aCallable(newMap.set); + iterate(iterator, function (key, value) { + functionCall(setter, newMap, key, boundFunction(value, key, map)); + }, { AS_ENTRIES: true, IS_ITERATOR: true }); + return newMap; + } + }); - if (change.to.line < doc.first) { - shiftDoc(doc, change.text.length - 1 - (change.to.line - change.from.line)); - return - } - if (change.from.line > doc.lastLine()) { return } - - // Clip the change to the size of this doc - if (change.from.line < doc.first) { - var shift = change.text.length - 1 - (doc.first - change.from.line); - shiftDoc(doc, shift); - change = { - from: Pos(doc.first, 0), to: Pos(change.to.line + shift, change.to.ch), - text: [lst(change.text)], origin: change.origin - }; - } - var last = doc.lastLine(); - if (change.to.line > last) { - change = { - from: change.from, to: Pos(last, getLine(doc, last).text.length), - text: [change.text[0]], origin: change.origin - }; - } + // `Map.prototype.merge` method + // https://github.com/tc39/proposal-collection-methods + _export({ target: 'Map', proto: true, real: true, arity: 1, forced: true }, { + // eslint-disable-next-line no-unused-vars -- required for `.length` + merge: function merge(iterable /* ...iterables */) { + var map = anObject(this); + var setter = aCallable(map.set); + var argumentsLength = arguments.length; + var i = 0; + while (i < argumentsLength) { + iterate(arguments[i++], setter, { that: map, AS_ENTRIES: true }); + } + return map; + } + }); - change.removed = getBetween(doc, change.from, change.to); + var TypeError$i = global_1.TypeError; - if (!selAfter) { selAfter = computeSelAfterChange(doc, change); } - if (doc.cm) { makeChangeSingleDocInEditor(doc.cm, change, spans); } - else { updateDoc(doc, change, spans); } - setSelectionNoUndo(doc, selAfter, sel_dontScroll); + // `Map.prototype.reduce` method + // https://github.com/tc39/proposal-collection-methods + _export({ target: 'Map', proto: true, real: true, forced: true }, { + reduce: function reduce(callbackfn /* , initialValue */) { + var map = anObject(this); + var iterator = getMapIterator(map); + var noInitial = arguments.length < 2; + var accumulator = noInitial ? undefined : arguments[1]; + aCallable(callbackfn); + iterate(iterator, function (key, value) { + if (noInitial) { + noInitial = false; + accumulator = value; + } else { + accumulator = callbackfn(accumulator, value, key, map); + } + }, { AS_ENTRIES: true, IS_ITERATOR: true }); + if (noInitial) throw TypeError$i('Reduce of empty map with no initial value'); + return accumulator; + } + }); - if (doc.cantEdit && skipAtomic(doc, Pos(doc.firstLine(), 0))) { doc.cantEdit = false; } - } + // `Set.prototype.some` method + // https://github.com/tc39/proposal-collection-methods + _export({ target: 'Map', proto: true, real: true, forced: true }, { + some: function some(callbackfn /* , thisArg */) { + var map = anObject(this); + var iterator = getMapIterator(map); + var boundFunction = functionBindContext(callbackfn, arguments.length > 1 ? arguments[1] : undefined); + return iterate(iterator, function (key, value, stop) { + if (boundFunction(value, key, map)) return stop(); + }, { AS_ENTRIES: true, IS_ITERATOR: true, INTERRUPTED: true }).stopped; + } + }); - // Handle the interaction of a change to a document with the editor - // that this document is part of. - function makeChangeSingleDocInEditor(cm, change, spans) { - var doc = cm.doc, display = cm.display, from = change.from, to = change.to; - - var recomputeMaxLength = false, checkWidthStart = from.line; - if (!cm.options.lineWrapping) { - checkWidthStart = lineNo(visualLine(getLine(doc, from.line))); - doc.iter(checkWidthStart, to.line + 1, function (line) { - if (line == display.maxLine) { - recomputeMaxLength = true; - return true - } - }); - } + var TypeError$j = global_1.TypeError; - if (doc.sel.contains(change.from, change.to) > -1) { signalCursorActivity(cm); } + // `Set.prototype.update` method + // https://github.com/tc39/proposal-collection-methods + _export({ target: 'Map', proto: true, real: true, forced: true }, { + update: function update(key, callback /* , thunk */) { + var map = anObject(this); + var get = aCallable(map.get); + var has = aCallable(map.has); + var set = aCallable(map.set); + var length = arguments.length; + aCallable(callback); + var isPresentInMap = functionCall(has, map, key); + if (!isPresentInMap && length < 3) { + throw TypeError$j('Updating absent value'); + } + var value = isPresentInMap ? functionCall(get, map, key) : aCallable(length > 2 ? arguments[2] : undefined)(key, map); + functionCall(set, map, key, callback(value, key, map)); + return map; + } + }); - updateDoc(doc, change, spans, estimateHeight(cm)); + var TypeError$k = global_1.TypeError; - if (!cm.options.lineWrapping) { - doc.iter(checkWidthStart, from.line + change.text.length, function (line) { - var len = lineLength(line); - if (len > display.maxLineLength) { - display.maxLine = line; - display.maxLineLength = len; - display.maxLineChanged = true; - recomputeMaxLength = false; - } - }); - if (recomputeMaxLength) { cm.curOp.updateMaxLine = true; } - } + // `Map.prototype.upsert` method + // https://github.com/thumbsupep/proposal-upsert + var mapUpsert = function upsert(key, updateFn /* , insertFn */) { + var map = anObject(this); + var get = aCallable(map.get); + var has = aCallable(map.has); + var set = aCallable(map.set); + var insertFn = arguments.length > 2 ? arguments[2] : undefined; + var value; + if (!isCallable(updateFn) && !isCallable(insertFn)) { + throw TypeError$k('At least one callback required'); + } + if (functionCall(has, map, key)) { + value = functionCall(get, map, key); + if (isCallable(updateFn)) { + value = updateFn(value); + functionCall(set, map, key, value); + } + } else if (isCallable(insertFn)) { + value = insertFn(); + functionCall(set, map, key, value); + } return value; + }; - retreatFrontier(doc, from.line); - startWorker(cm, 400); - - var lendiff = change.text.length - (to.line - from.line) - 1; - // Remember that these lines changed, for updating the display - if (change.full) { regChange(cm); } - else if (from.line == to.line && change.text.length == 1 && !isWholeLineUpdate(cm.doc, change)) { regLineChange(cm, from.line, "text"); } - else { regChange(cm, from.line, to.line + 1, lendiff); } - - var changesHandler = hasHandler(cm, "changes"), changeHandler = hasHandler(cm, "change"); - if (changeHandler || changesHandler) { - var obj = { - from: from, to: to, - text: change.text, - removed: change.removed, - origin: change.origin - }; - if (changeHandler) { signalLater(cm, "change", cm, obj); } - if (changesHandler) { (cm.curOp.changeObjs || (cm.curOp.changeObjs = [])).push(obj); } - } - cm.display.selForContextMenu = null; - } + // TODO: remove from `core-js@4` - function replaceRange(doc, code, from, to, origin) { - var assign; - if (!to) { to = from; } - if (cmp(to, from) < 0) { (assign = [to, from], from = assign[0], to = assign[1]); } - if (typeof code == "string") { code = doc.splitLines(code); } - makeChange(doc, { from: from, to: to, text: code, origin: origin }); - } - // Rebasing/resetting history to deal with externally-sourced changes + // `Map.prototype.upsert` method (replaced by `Map.prototype.emplace`) + // https://github.com/thumbsupep/proposal-upsert + _export({ target: 'Map', proto: true, real: true, forced: true }, { + upsert: mapUpsert + }); - function rebaseHistSelSingle(pos, from, to, diff) { - if (to < pos.line) { - pos.line += diff; - } else if (from < pos.line) { - pos.line = from; - pos.ch = 0; - } - } + // TODO: remove from `core-js@4` - // Tries to rebase an array of history events given a change in the - // document. If the change touches the same lines as the event, the - // event, and everything 'behind' it, is discarded. If the change is - // before the event, the event's positions are updated. Uses a - // copy-on-write scheme for the positions, to avoid having to - // reallocate them all on every rebase, but also avoid problems with - // shared position objects being unsafely updated. - function rebaseHistArray(array, from, to, diff) { - for (var i = 0; i < array.length; ++i) { - var sub = array[i], ok = true; - if (sub.ranges) { - if (!sub.copied) { sub = array[i] = sub.deepCopy(); sub.copied = true; } - for (var j = 0; j < sub.ranges.length; j++) { - rebaseHistSelSingle(sub.ranges[j].anchor, from, to, diff); - rebaseHistSelSingle(sub.ranges[j].head, from, to, diff); - } - continue - } - for (var j$1 = 0; j$1 < sub.changes.length; ++j$1) { - var cur = sub.changes[j$1]; - if (to < cur.from.line) { - cur.from = Pos(cur.from.line + diff, cur.from.ch); - cur.to = Pos(cur.to.line + diff, cur.to.ch); - } else if (from <= cur.to.line) { - ok = false; - break - } - } - if (!ok) { - array.splice(0, i + 1); - i = 0; - } - } - } - - function rebaseHist(hist, change) { - var from = change.from.line, to = change.to.line, diff = change.text.length - (to - from) - 1; - rebaseHistArray(hist.done, from, to, diff); - rebaseHistArray(hist.undone, from, to, diff); - } - // Utility for applying a change to a line by handle or number, - // returning the number and optionally registering the line as - // changed. - function changeLine(doc, handle, changeType, op) { - var no = handle, line = handle; - if (typeof handle == "number") { line = getLine(doc, clipLine(doc, handle)); } - else { no = lineNo(handle); } - if (no == null) { return null } - if (op(line, no) && doc.cm) { regLineChange(doc.cm, no, changeType); } - return line - } - // The document is represented as a BTree consisting of leaves, with - // chunk of lines in them, and branches, with up to ten leaves or - // other branch nodes below them. The top node is always a branch - // node, and is the document object itself (meaning it has - // additional methods and properties). - // - // All nodes have parent links. The tree is used both to go from - // line numbers to line objects, and to go from objects to numbers. - // It also indexes by height, and is used to convert between height - // and line object, and to find the total height of the document. - // - // See also http://marijnhaverbeke.nl/blog/codemirror-line-tree.html - - function LeafChunk(lines) { - this.lines = lines; - this.parent = null; - var height = 0; - for (var i = 0; i < lines.length; ++i) { - lines[i].parent = this; - height += lines[i].height; - } - this.height = height; - } + // `Map.prototype.updateOrInsert` method (replaced by `Map.prototype.emplace`) + // https://github.com/thumbsupep/proposal-upsert + _export({ target: 'Map', proto: true, real: true, name: 'upsert', forced: true }, { + updateOrInsert: mapUpsert + }); - LeafChunk.prototype = { - chunkSize: function () { return this.lines.length }, + // TODO: remove from `core-js@4` - // Remove the n lines at offset 'at'. - removeInner: function (at, n) { - for (var i = at, e = at + n; i < e; ++i) { - var line = this.lines[i]; - this.height -= line.height; - cleanUpLine(line); - signalLater(line, "delete"); - } - this.lines.splice(at, n); - }, + // TODO: remove from `core-js@4` - // Helper used to collapse a small branch into a single leaf. - collapse: function (lines) { - lines.push.apply(lines, this.lines); - }, - // Insert the given array of lines at offset 'at', count them as - // having the given height. - insertInner: function (at, lines, height) { - this.height += height; - this.lines = this.lines.slice(0, at).concat(lines).concat(this.lines.slice(at)); - for (var i = 0; i < lines.length; ++i) { lines[i].parent = this; } - }, + var map$7 = map$6; - // Used to iterate over a part of the tree. - iterN: function (at, n, op) { - for (var e = at + n; at < e; ++at) { if (op(this.lines[at])) { return true } } - } - }; + var map$8 = map$7; - function BranchChunk(children) { - this.children = children; - var size = 0, height = 0; - for (var i = 0; i < children.length; ++i) { - var ch = children[i]; - size += ch.chunkSize(); height += ch.height; - ch.parent = this; - } - this.size = size; - this.height = height; - this.parent = null; - } + var map$9 = map$8; - BranchChunk.prototype = { - chunkSize: function () { return this.size }, - - removeInner: function (at, n) { - this.size -= n; - for (var i = 0; i < this.children.length; ++i) { - var child = this.children[i], sz = child.chunkSize(); - if (at < sz) { - var rm = Math.min(n, sz - at), oldHeight = child.height; - child.removeInner(at, rm); - this.height -= oldHeight - child.height; - if (sz == rm) { this.children.splice(i--, 1); child.parent = null; } - if ((n -= rm) == 0) { break } - at = 0; - } else { at -= sz; } - } - // If the result is smaller than 25 lines, ensure that it is a - // single leaf node. - if (this.size - n < 25 && - (this.children.length > 1 || !(this.children[0] instanceof LeafChunk))) { - var lines = []; - this.collapse(lines); - this.children = [new LeafChunk(lines)]; - this.children[0].parent = this; - } - }, + var isNativeFunction = createCommonjsModule(function (module) { + function _isNativeFunction(fn) { + var _context; - collapse: function (lines) { - for (var i = 0; i < this.children.length; ++i) { this.children[i].collapse(lines); } - }, + return indexOf$7(_context = Function.toString.call(fn)).call(_context, "[native code]") !== -1; + } - insertInner: function (at, lines, height) { - this.size += lines.length; - this.height += height; - for (var i = 0; i < this.children.length; ++i) { - var child = this.children[i], sz = child.chunkSize(); - if (at <= sz) { - child.insertInner(at, lines, height); - if (child.lines && child.lines.length > 50) { - // To avoid memory thrashing when child.lines is huge (e.g. first view of a large file), it's never spliced. - // Instead, small slices are taken. They're taken in order because sequential memory accesses are fastest. - var remaining = child.lines.length % 25 + 25; - for (var pos = remaining; pos < child.lines.length;) { - var leaf = new LeafChunk(child.lines.slice(pos, pos += 25)); - child.height -= leaf.height; - this.children.splice(++i, 0, leaf); - leaf.parent = this; - } - child.lines = child.lines.slice(0, remaining); - this.maybeSpill(); - } - break - } - at -= sz; - } - }, + module.exports = _isNativeFunction, module.exports.__esModule = true, module.exports["default"] = module.exports; + }); - // When a node has grown, check whether it should be split. - maybeSpill: function () { - if (this.children.length <= 10) { return } - var me = this; - do { - var spilled = me.children.splice(me.children.length - 5, 5); - var sibling = new BranchChunk(spilled); - if (!me.parent) { // Become the parent node - var copy = new BranchChunk(me.children); - copy.parent = me; - me.children = [copy, sibling]; - me = copy; - } else { - me.size -= sibling.size; - me.height -= sibling.height; - var myIndex = indexOf(me.parent.children, me); - me.parent.children.splice(myIndex + 1, 0, sibling); - } - sibling.parent = me.parent; - } while (me.children.length > 10) - me.parent.maybeSpill(); - }, + unwrapExports(isNativeFunction); - iterN: function (at, n, op) { - for (var i = 0; i < this.children.length; ++i) { - var child = this.children[i], sz = child.chunkSize(); - if (at < sz) { - var used = Math.min(n, sz - at); - if (child.iterN(at, used, op)) { return true } - if ((n -= used) == 0) { break } - at = 0; - } else { at -= sz; } - } - } - }; + var construct$5 = construct$3; - // Line widgets are block elements displayed above or below a line. + var construct$6 = construct$5; - var LineWidget = function (doc, node, options) { - if (options) { - for (var opt in options) { - if (options.hasOwnProperty(opt)) { this[opt] = options[opt]; } - } - } - this.doc = doc; - this.node = node; - }; + var construct$7 = construct$6; - LineWidget.prototype.clear = function () { - var cm = this.doc.cm, ws = this.line.widgets, line = this.line, no = lineNo(line); - if (no == null || !ws) { return } - for (var i = 0; i < ws.length; ++i) { if (ws[i] == this) { ws.splice(i--, 1); } } - if (!ws.length) { line.widgets = null; } - var height = widgetHeight(this); - updateLineHeight(line, Math.max(0, line.height - height)); - if (cm) { - runInOp(cm, function () { - adjustScrollWhenAboveVisible(cm, line, -height); - regLineChange(cm, no, "widget"); - }); - signalLater(cm, "lineWidgetCleared", cm, this, no); - } - }; + var construct$8 = construct$7; - LineWidget.prototype.changed = function () { - var this$1 = this; - - var oldH = this.height, cm = this.doc.cm, line = this.line; - this.height = null; - var diff = widgetHeight(this) - oldH; - if (!diff) { return } - if (!lineIsHidden(this.doc, line)) { updateLineHeight(line, line.height + diff); } - if (cm) { - runInOp(cm, function () { - cm.curOp.forceUpdate = true; - adjustScrollWhenAboveVisible(cm, line, diff); - signalLater(cm, "lineWidgetChanged", cm, this$1, lineNo(line)); - }); - } - }; - eventMixin(LineWidget); + var bind$6 = bind$4; - function adjustScrollWhenAboveVisible(cm, line, diff) { - if (heightAtLine(line) < ((cm.curOp && cm.curOp.scrollTop) || cm.doc.scrollTop)) { addToScrollTop(cm, diff); } - } + var bind$7 = bind$6; - function addLineWidget(doc, handle, node, options) { - var widget = new LineWidget(doc, node, options); - var cm = doc.cm; - if (cm && widget.noHScroll) { cm.display.alignWidgets = true; } - changeLine(doc, handle, "widget", function (line) { - var widgets = line.widgets || (line.widgets = []); - if (widget.insertAt == null) { widgets.push(widget); } - else { widgets.splice(Math.min(widgets.length - 1, Math.max(0, widget.insertAt)), 0, widget); } - widget.line = line; - if (cm && !lineIsHidden(doc, line)) { - var aboveVisible = heightAtLine(line) < doc.scrollTop; - updateLineHeight(line, line.height + widgetHeight(widget)); - if (aboveVisible) { addToScrollTop(cm, widget.height); } - cm.curOp.forceUpdate = true; - } - return true - }); - if (cm) { signalLater(cm, "lineWidgetAdded", cm, widget, typeof handle == "number" ? handle : lineNo(handle)); } - return widget - } + var bind$8 = bind$7; - // TEXTMARKERS - - // Created with markText and setBookmark methods. A TextMarker is a - // handle that can be used to clear or find a marked position in the - // document. Line objects hold arrays (markedSpans) containing - // {from, to, marker} object pointing to such marker objects, and - // indicating that such a marker is present on that line. Multiple - // lines may point to the same marker when it spans across lines. - // The spans will have null for their from/to properties when the - // marker continues beyond the start/end of the line. Markers have - // links back to the lines they currently touch. - - // Collapsed markers have unique ids, in order to be able to order - // them, which is needed for uniquely determining an outer marker - // when they overlap (they may nest, but not partially overlap). - var nextMarkerId = 0; - - var TextMarker = function (doc, type) { - this.lines = []; - this.type = type; - this.doc = doc; - this.id = ++nextMarkerId; - }; + var bind$9 = bind$8; - // Clear the marker. - TextMarker.prototype.clear = function () { - if (this.explicitlyCleared) { return } - var cm = this.doc.cm, withOp = cm && !cm.curOp; - if (withOp) { startOperation(cm); } - if (hasHandler(this, "clear")) { - var found = this.find(); - if (found) { signalLater(this, "clear", found.from, found.to); } - } - var min = null, max = null; - for (var i = 0; i < this.lines.length; ++i) { - var line = this.lines[i]; - var span = getMarkedSpanFor(line.markedSpans, this); - if (cm && !this.collapsed) { regLineChange(cm, lineNo(line), "text"); } - else if (cm) { - if (span.to != null) { max = lineNo(line); } - if (span.from != null) { min = lineNo(line); } - } - line.markedSpans = removeMarkedSpan(line.markedSpans, span); - if (span.from == null && this.collapsed && !lineIsHidden(this.doc, line) && cm) { updateLineHeight(line, textHeight(cm.display)); } - } - if (cm && this.collapsed && !cm.options.lineWrapping) { - for (var i$1 = 0; i$1 < this.lines.length; ++i$1) { - var visual = visualLine(this.lines[i$1]), len = lineLength(visual); - if (len > cm.display.maxLineLength) { - cm.display.maxLine = visual; - cm.display.maxLineLength = len; - cm.display.maxLineChanged = true; - } - } - } + var isNativeReflectConstruct = createCommonjsModule(function (module) { + function _isNativeReflectConstruct() { + if (typeof Reflect === "undefined" || !construct$8) return false; + if (construct$8.sham) return false; + if (typeof Proxy === "function") return true; - if (min != null && cm && this.collapsed) { regChange(cm, min, max + 1); } - this.lines.length = 0; - this.explicitlyCleared = true; - if (this.atomic && this.doc.cantEdit) { - this.doc.cantEdit = false; - if (cm) { reCheckSelection(cm.doc); } - } - if (cm) { signalLater(cm, "markerCleared", cm, this, min, max); } - if (withOp) { endOperation(cm); } - if (this.parent) { this.parent.clear(); } - }; + try { + Boolean.prototype.valueOf.call(construct$8(Boolean, [], function () {})); + return true; + } catch (e) { + return false; + } + } - // Find the position of the marker in the document. Returns a {from, - // to} object by default. Side can be passed to get a specific side - // -- 0 (both), -1 (left), or 1 (right). When lineObj is true, the - // Pos objects returned contain a line object, rather than a line - // number (used to prevent looking up the same line twice). - TextMarker.prototype.find = function (side, lineObj) { - if (side == null && this.type == "bookmark") { side = 1; } - var from, to; - for (var i = 0; i < this.lines.length; ++i) { - var line = this.lines[i]; - var span = getMarkedSpanFor(line.markedSpans, this); - if (span.from != null) { - from = Pos(lineObj ? line : lineNo(line), span.from); - if (side == -1) { return from } - } - if (span.to != null) { - to = Pos(lineObj ? line : lineNo(line), span.to); - if (side == 1) { return to } - } - } - return from && { from: from, to: to } - }; + module.exports = _isNativeReflectConstruct, module.exports.__esModule = true, module.exports["default"] = module.exports; + }); - // Signals that the marker's widget changed, and surrounding layout - // should be recomputed. - TextMarker.prototype.changed = function () { - var this$1 = this; - - var pos = this.find(-1, true), widget = this, cm = this.doc.cm; - if (!pos || !cm) { return } - runInOp(cm, function () { - var line = pos.line, lineN = lineNo(pos.line); - var view = findViewForLine(cm, lineN); - if (view) { - clearLineMeasurementCacheFor(view); - cm.curOp.selectionChanged = cm.curOp.forceUpdate = true; - } - cm.curOp.updateMaxLine = true; - if (!lineIsHidden(widget.doc, line) && widget.height != null) { - var oldHeight = widget.height; - widget.height = null; - var dHeight = widgetHeight(widget) - oldHeight; - if (dHeight) { updateLineHeight(line, line.height + dHeight); } - } - signalLater(cm, "markerChanged", cm, this$1); - }); - }; + unwrapExports(isNativeReflectConstruct); - TextMarker.prototype.attachLine = function (line) { - if (!this.lines.length && this.doc.cm) { - var op = this.doc.cm.curOp; - if (!op.maybeHiddenMarkers || indexOf(op.maybeHiddenMarkers, this) == -1) { (op.maybeUnhiddenMarkers || (op.maybeUnhiddenMarkers = [])).push(this); } - } - this.lines.push(line); - }; + var construct$9 = createCommonjsModule(function (module) { + function _construct(Parent, args, Class) { + if (isNativeReflectConstruct()) { + module.exports = _construct = construct$8, module.exports.__esModule = true, module.exports["default"] = module.exports; + } else { + module.exports = _construct = function _construct(Parent, args, Class) { + var a = [null]; + a.push.apply(a, args); - TextMarker.prototype.detachLine = function (line) { - this.lines.splice(indexOf(this.lines, line), 1); - if (!this.lines.length && this.doc.cm) { - var op = this.doc.cm.curOp - ; (op.maybeHiddenMarkers || (op.maybeHiddenMarkers = [])).push(this); - } - }; - eventMixin(TextMarker); - - // Create a marker, wire it up to the right lines, and - function markText(doc, from, to, options, type) { - // Shared markers (across linked documents) are handled separately - // (markTextShared will call out to this again, once per - // document). - if (options && options.shared) { return markTextShared(doc, from, to, options, type) } - // Ensure we are in an operation. - if (doc.cm && !doc.cm.curOp) { return operation(doc.cm, markText)(doc, from, to, options, type) } - - var marker = new TextMarker(doc, type), diff = cmp(from, to); - if (options) { copyObj(options, marker, false); } - // Don't connect empty markers unless clearWhenEmpty is false - if (diff > 0 || diff == 0 && marker.clearWhenEmpty !== false) { return marker } - if (marker.replacedWith) { - // Showing up as a widget implies collapsed (widget replaces text) - marker.collapsed = true; - marker.widgetNode = eltP("span", [marker.replacedWith], "CodeMirror-widget"); - if (!options.handleMouseEvents) { marker.widgetNode.setAttribute("cm-ignore-events", "true"); } - if (options.insertLeft) { marker.widgetNode.insertLeft = true; } - } - if (marker.collapsed) { - if (conflictingCollapsedRange(doc, from.line, from, to, marker) || - from.line != to.line && conflictingCollapsedRange(doc, to.line, from, to, marker)) { throw new Error("Inserting collapsed marker partially overlapping an existing one") } - seeCollapsedSpans(); - } + var Constructor = bind$9(Function).apply(Parent, a); - if (marker.addToHistory) { addChangeToHistory(doc, { from: from, to: to, origin: "markText" }, doc.sel, NaN); } + var instance = new Constructor(); + if (Class) setPrototypeOf$6(instance, Class.prototype); + return instance; + }, module.exports.__esModule = true, module.exports["default"] = module.exports; + } - var curLine = from.line, cm = doc.cm, updateMaxLine; - doc.iter(curLine, to.line + 1, function (line) { - if (cm && marker.collapsed && !cm.options.lineWrapping && visualLine(line) == cm.display.maxLine) { updateMaxLine = true; } - if (marker.collapsed && curLine != from.line) { updateLineHeight(line, 0); } - addMarkedSpan(line, new MarkedSpan(marker, - curLine == from.line ? from.ch : null, - curLine == to.line ? to.ch : null)); - ++curLine; - }); - // lineIsHidden depends on the presence of the spans, so needs a second pass - if (marker.collapsed) { - doc.iter(from.line, to.line + 1, function (line) { - if (lineIsHidden(doc, line)) { updateLineHeight(line, 0); } - }); - } + return _construct.apply(null, arguments); + } - if (marker.clearOnEnter) { on(marker, "beforeCursorEnter", function () { return marker.clear(); }); } + module.exports = _construct, module.exports.__esModule = true, module.exports["default"] = module.exports; + }); - if (marker.readOnly) { - seeReadOnlySpans(); - if (doc.history.done.length || doc.history.undone.length) { doc.clearHistory(); } - } - if (marker.collapsed) { - marker.id = ++nextMarkerId; - marker.atomic = true; - } - if (cm) { - // Sync editor state - if (updateMaxLine) { cm.curOp.updateMaxLine = true; } - if (marker.collapsed) { regChange(cm, from.line, to.line + 1); } - else if (marker.className || marker.startStyle || marker.endStyle || marker.css || - marker.attributes || marker.title) { for (var i = from.line; i <= to.line; i++) { regLineChange(cm, i, "text"); } } - if (marker.atomic) { reCheckSelection(cm.doc); } - signalLater(cm, "markerAdded", cm, marker); - } - return marker - } + var _construct = unwrapExports(construct$9); - // SHARED TEXTMARKERS + var wrapNativeSuper = createCommonjsModule(function (module) { + function _wrapNativeSuper(Class) { + var _cache = typeof map$9 === "function" ? new map$9() : undefined; - // A shared marker spans multiple linked documents. It is - // implemented as a meta-marker-object controlling multiple normal - // markers. - var SharedTextMarker = function (markers, primary) { - this.markers = markers; - this.primary = primary; - for (var i = 0; i < markers.length; ++i) { markers[i].parent = this; } - }; + module.exports = _wrapNativeSuper = function _wrapNativeSuper(Class) { + if (Class === null || !isNativeFunction(Class)) return Class; - SharedTextMarker.prototype.clear = function () { - if (this.explicitlyCleared) { return } - this.explicitlyCleared = true; - for (var i = 0; i < this.markers.length; ++i) { this.markers[i].clear(); } - signalLater(this, "clear"); - }; + if (typeof Class !== "function") { + throw new TypeError("Super expression must either be null or a function"); + } - SharedTextMarker.prototype.find = function (side, lineObj) { - return this.primary.find(side, lineObj) - }; - eventMixin(SharedTextMarker); - - function markTextShared(doc, from, to, options, type) { - options = copyObj(options); - options.shared = false; - var markers = [markText(doc, from, to, options, type)], primary = markers[0]; - var widget = options.widgetNode; - linkedDocs(doc, function (doc) { - if (widget) { options.widgetNode = widget.cloneNode(true); } - markers.push(markText(doc, clipPos(doc, from), clipPos(doc, to), options, type)); - for (var i = 0; i < doc.linked.length; ++i) { if (doc.linked[i].isParent) { return } } - primary = lst(markers); - }); - return new SharedTextMarker(markers, primary) - } + if (typeof _cache !== "undefined") { + if (_cache.has(Class)) return _cache.get(Class); - function findSharedMarkers(doc) { - return doc.findMarks(Pos(doc.first, 0), doc.clipPos(Pos(doc.lastLine())), function (m) { return m.parent; }) - } + _cache.set(Class, Wrapper); + } - function copySharedMarkers(doc, markers) { - for (var i = 0; i < markers.length; i++) { - var marker = markers[i], pos = marker.find(); - var mFrom = doc.clipPos(pos.from), mTo = doc.clipPos(pos.to); - if (cmp(mFrom, mTo)) { - var subMark = markText(doc, mFrom, mTo, marker.primary, marker.primary.type); - marker.markers.push(subMark); - subMark.parent = marker; - } - } - } + function Wrapper() { + return construct$9(Class, arguments, getPrototypeOf$6(this).constructor); + } - function detachSharedMarkers(markers) { - var loop = function (i) { - var marker = markers[i], linked = [marker.primary.doc]; - linkedDocs(marker.primary.doc, function (d) { return linked.push(d); }); - for (var j = 0; j < marker.markers.length; j++) { - var subMarker = marker.markers[j]; - if (indexOf(linked, subMarker.doc) == -1) { - subMarker.parent = null; - marker.markers.splice(j--, 1); - } - } - }; + Wrapper.prototype = create$5(Class.prototype, { + constructor: { + value: Wrapper, + enumerable: false, + writable: true, + configurable: true + } + }); + return setPrototypeOf$6(Wrapper, Class); + }, module.exports.__esModule = true, module.exports["default"] = module.exports; + return _wrapNativeSuper(Class); + } - for (var i = 0; i < markers.length; i++) loop(i); - } + module.exports = _wrapNativeSuper, module.exports.__esModule = true, module.exports["default"] = module.exports; + }); - var nextDocId = 0; - var Doc = function (text, mode, firstLine, lineSep, direction) { - if (!(this instanceof Doc)) { return new Doc(text, mode, firstLine, lineSep, direction) } - if (firstLine == null) { firstLine = 0; } - - BranchChunk.call(this, [new LeafChunk([new Line("", null)])]); - this.first = firstLine; - this.scrollTop = this.scrollLeft = 0; - this.cantEdit = false; - this.cleanGeneration = 1; - this.modeFrontier = this.highlightFrontier = firstLine; - var start = Pos(firstLine, 0); - this.sel = simpleSelection(start); - this.history = new History(null); - this.id = ++nextDocId; - this.modeOption = mode; - this.lineSep = lineSep; - this.direction = (direction == "rtl") ? "rtl" : "ltr"; - this.extend = false; - - if (typeof text == "string") { text = this.splitLines(text); } - updateDoc(this, { from: start, to: start, text: text }); - setSelection(this, simpleSelection(start), sel_dontScroll); - }; + var _wrapNativeSuper = unwrapExports(wrapNativeSuper); - Doc.prototype = createObj(BranchChunk.prototype, { - constructor: Doc, - // Iterate over the document. Supports two forms -- with only one - // argument, it calls that for each line in the document. With - // three, it iterates over the range given by the first two (with - // the second being non-inclusive). - iter: function (from, to, op) { - if (op) { this.iterN(from - this.first, to - from, op); } - else { this.iterN(this.first, this.first + this.size, from); } - }, + function _createSuper$1(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$1(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = construct$4(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } - // Non-public interface for adding and removing lines. - insert: function (at, lines) { - var height = 0; - for (var i = 0; i < lines.length; ++i) { height += lines[i].height; } - this.insertInner(at - this.first, lines, height); - }, - remove: function (at, n) { this.removeInner(at - this.first, n); }, + function _isNativeReflectConstruct$1() { if (typeof Reflect === "undefined" || !construct$4) return false; if (construct$4.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(construct$4(Boolean, [], function () {})); return true; } catch (e) { return false; } } - // From here, the methods are part of the public interface. Most - // are also available from CodeMirror (editor) instances. + /** + * Copyright (C) 2021 THL A29 Limited, a Tencent company. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ - getValue: function (lineSep) { - var lines = getLines(this, this.first, this.first + this.size); - if (lineSep === false) { return lines } - return lines.join(lineSep || this.lineSeparator()) - }, - setValue: docMethodOp(function (code) { - var top = Pos(this.first, 0), last = this.first + this.size - 1; - makeChange(this, { - from: top, to: Pos(last, getLine(this, last).text.length), - text: this.splitLines(code), origin: "setValue", full: true - }, true); - if (this.cm) { scrollToCoords(this.cm, 0, 0); } - setSelection(this, simpleSelection(top), sel_dontScroll); - }), - replaceRange: function (code, from, to, origin) { - from = clipPos(this, from); - to = to ? clipPos(this, to) : from; - replaceRange(this, code, from, to, origin); - }, - getRange: function (from, to, lineSep) { - var lines = getBetween(this, clipPos(this, from), clipPos(this, to)); - if (lineSep === false) { return lines } - return lines.join(lineSep || this.lineSeparator()) - }, + /** + * 三个地方的错误异常校验 + * 1. markdown 对象参数校验 + * 2. editText 用户输入校验,执行engine过程以防异常 + * 3. 自定义hook校验 对外开发者开发标准校验 + */ + var $expectTarget = function $expectTarget(target, Constructor) { + if (!isArray$8(target) && _typeof(target) !== Constructor.name.toLowerCase() || !isArray$8(target) && Constructor.name.toLowerCase() === 'array') { + throw new TypeError("parameter given must be ".concat(Constructor.name)); + } - getLine: function (line) { var l = this.getLineHandle(line); return l && l.text }, + return true; + }; + var $expectInherit = function $expectInherit(target, parent) { + if (!(target instanceof parent)) { + throw new Error('the hook does not correctly inherit'); + } - getLineHandle: function (line) { if (isLine(this, line)) { return getLine(this, line) } }, - getLineNumber: function (line) { return lineNo(line) }, + return true; + }; + var $expectInstance = function $expectInstance(target) { + if (_typeof(target) !== 'object') { + throw new Error('the hook must be a instance, not a class'); + } - getLineHandleVisualStart: function (line) { - if (typeof line == "number") { line = getLine(this, line); } - return visualLine(line) - }, + return true; + }; // ref: https://github.com/mdlavin/nested-error-stacks - lineCount: function () { return this.size }, - firstLine: function () { return this.first }, - lastLine: function () { return this.first + this.size - 1 }, + var NestedError = /*#__PURE__*/function (_Error) { + _inherits(NestedError, _Error); - clipPos: function (pos) { return clipPos(this, pos) }, + var _super = _createSuper$1(NestedError); - getCursor: function (start) { - var range = this.sel.primary(), pos; - if (start == null || start == "head") { pos = range.head; } - else if (start == "anchor") { pos = range.anchor; } - else if (start == "end" || start == "to" || start === false) { pos = range.to(); } - else { pos = range.from(); } - return pos - }, - listSelections: function () { return this.sel.ranges }, - somethingSelected: function () { return this.sel.somethingSelected() }, - - setCursor: docMethodOp(function (line, ch, options) { - setSimpleSelection(this, clipPos(this, typeof line == "number" ? Pos(line, ch || 0) : line), null, options); - }), - setSelection: docMethodOp(function (anchor, head, options) { - setSimpleSelection(this, clipPos(this, anchor), clipPos(this, head || anchor), options); - }), - extendSelection: docMethodOp(function (head, other, options) { - extendSelection(this, clipPos(this, head), other && clipPos(this, other), options); - }), - extendSelections: docMethodOp(function (heads, options) { - extendSelections(this, clipPosArray(this, heads), options); - }), - extendSelectionsBy: docMethodOp(function (f, options) { - var heads = map(this.sel.ranges, f); - extendSelections(this, clipPosArray(this, heads), options); - }), - setSelections: docMethodOp(function (ranges, primary, options) { - if (!ranges.length) { return } - var out = []; - for (var i = 0; i < ranges.length; i++) { - out[i] = new Range(clipPos(this, ranges[i].anchor), - clipPos(this, ranges[i].head)); - } - if (primary == null) { primary = Math.min(ranges.length - 1, this.sel.primIndex); } - setSelection(this, normalizeSelection(this.cm, out, primary), options); - }), - addSelection: docMethodOp(function (anchor, head, options) { - var ranges = this.sel.ranges.slice(0); - ranges.push(new Range(clipPos(this, anchor), clipPos(this, head || anchor))); - setSelection(this, normalizeSelection(this.cm, ranges, ranges.length - 1), options); - }), - - getSelection: function (lineSep) { - var ranges = this.sel.ranges, lines; - for (var i = 0; i < ranges.length; i++) { - var sel = getBetween(this, ranges[i].from(), ranges[i].to()); - lines = lines ? lines.concat(sel) : sel; - } - if (lineSep === false) { return lines } - else { return lines.join(lineSep || this.lineSeparator()) } - }, - getSelections: function (lineSep) { - var parts = [], ranges = this.sel.ranges; - for (var i = 0; i < ranges.length; i++) { - var sel = getBetween(this, ranges[i].from(), ranges[i].to()); - if (lineSep !== false) { sel = sel.join(lineSep || this.lineSeparator()); } - parts[i] = sel; - } - return parts - }, - replaceSelection: function (code, collapse, origin) { - var dup = []; - for (var i = 0; i < this.sel.ranges.length; i++) { dup[i] = code; } - this.replaceSelections(dup, collapse, origin || "+input"); - }, - replaceSelections: docMethodOp(function (code, collapse, origin) { - var changes = [], sel = this.sel; - for (var i = 0; i < sel.ranges.length; i++) { - var range = sel.ranges[i]; - changes[i] = { from: range.from(), to: range.to(), text: this.splitLines(code[i]), origin: origin }; - } - var newSel = collapse && collapse != "end" && computeReplacedSel(this, changes, collapse); - for (var i$1 = changes.length - 1; i$1 >= 0; i$1--) { makeChange(this, changes[i$1]); } - if (newSel) { setSelectionReplaceHistory(this, newSel); } - else if (this.cm) { ensureCursorVisible(this.cm); } - }), - undo: docMethodOp(function () { makeChangeFromHistory(this, "undo"); }), - redo: docMethodOp(function () { makeChangeFromHistory(this, "redo"); }), - undoSelection: docMethodOp(function () { makeChangeFromHistory(this, "undo", true); }), - redoSelection: docMethodOp(function () { makeChangeFromHistory(this, "redo", true); }), - - setExtending: function (val) { this.extend = val; }, - getExtending: function () { return this.extend }, - - historySize: function () { - var hist = this.history, done = 0, undone = 0; - for (var i = 0; i < hist.done.length; i++) { if (!hist.done[i].ranges) { ++done; } } - for (var i$1 = 0; i$1 < hist.undone.length; i$1++) { if (!hist.undone[i$1].ranges) { ++undone; } } - return { undo: done, redo: undone } - }, - clearHistory: function () { - var this$1 = this; + function NestedError(message, nested) { + var _this; - this.history = new History(this.history.maxGeneration); - linkedDocs(this, function (doc) { return doc.history = this$1.history; }, true); - }, + _classCallCheck(this, NestedError); - markClean: function () { - this.cleanGeneration = this.changeGeneration(true); - }, - changeGeneration: function (forceSplit) { - if (forceSplit) { this.history.lastOp = this.history.lastSelOp = this.history.lastOrigin = null; } - return this.history.generation - }, - isClean: function (gen) { - return this.history.generation == (gen || this.cleanGeneration) - }, + _this = _super.call(this, message); + _this.name = 'Error'; + _this.stack = _this.buildStackTrace(nested); + return _this; + } - getHistory: function () { - return { - done: copyHistoryArray(this.history.done), - undone: copyHistoryArray(this.history.undone) - } - }, - setHistory: function (histData) { - var hist = this.history = new History(this.history.maxGeneration); - hist.done = copyHistoryArray(histData.done.slice(0), null, true); - hist.undone = copyHistoryArray(histData.undone.slice(0), null, true); - }, + _createClass(NestedError, [{ + key: "buildStackTrace", + value: function buildStackTrace(nested) { + var _context; - setGutterMarker: docMethodOp(function (line, gutterID, value) { - return changeLine(this, line, "gutter", function (line) { - var markers = line.gutterMarkers || (line.gutterMarkers = {}); - markers[gutterID] = value; - if (!value && isEmpty(markers)) { line.gutterMarkers = null; } - return true - }) - }), - - clearGutter: docMethodOp(function (gutterID) { - var this$1 = this; - - this.iter(function (line) { - if (line.gutterMarkers && line.gutterMarkers[gutterID]) { - changeLine(this$1, line, "gutter", function () { - line.gutterMarkers[gutterID] = null; - if (isEmpty(line.gutterMarkers)) { line.gutterMarkers = null; } - return true - }); - } - }); - }), - - lineInfo: function (line) { - var n; - if (typeof line == "number") { - if (!isLine(this, line)) { return null } - n = line; - line = getLine(this, line); - if (!line) { return null } - } else { - n = lineNo(line); - if (n == null) { return null } - } - return { - line: n, handle: line, text: line.text, gutterMarkers: line.gutterMarkers, - textClass: line.textClass, bgClass: line.bgClass, wrapClass: line.wrapClass, - widgets: line.widgets - } - }, + var stack = nested && nested.stack ? nested.stack : ''; - addLineClass: docMethodOp(function (handle, where, cls) { - return changeLine(this, handle, where == "gutter" ? "gutter" : "class", function (line) { - var prop = where == "text" ? "textClass" - : where == "background" ? "bgClass" - : where == "gutter" ? "gutterClass" : "wrapClass"; - if (!line[prop]) { line[prop] = cls; } - else if (classTest(cls).test(line[prop])) { return false } - else { line[prop] += " " + cls; } - return true - }) - }), - removeLineClass: docMethodOp(function (handle, where, cls) { - return changeLine(this, handle, where == "gutter" ? "gutter" : "class", function (line) { - var prop = where == "text" ? "textClass" - : where == "background" ? "bgClass" - : where == "gutter" ? "gutterClass" : "wrapClass"; - var cur = line[prop]; - if (!cur) { return false } - else if (cls == null) { line[prop] = null; } - else { - var found = cur.match(classTest(cls)); - if (!found) { return false } - var end = found.index + found[0].length; - line[prop] = cur.slice(0, found.index) + (!found.index || end == cur.length ? "" : " ") + cur.slice(end) || null; - } - return true - }) - }), + var newStack = concat$5(_context = "".concat(this.stack, "\nCaused By: ")).call(_context, stack); - addLineWidget: docMethodOp(function (handle, node, options) { - return addLineWidget(this, handle, node, options) - }), - removeLineWidget: function (widget) { widget.clear(); }, + return newStack; + } + }]); - markText: function (from, to, options) { - return markText(this, clipPos(this, from), clipPos(this, to), options, options && options.type || "range") - }, - setBookmark: function (pos, options) { - var realOpts = { - replacedWith: options && (options.nodeType == null ? options.widget : options), - insertLeft: options && options.insertLeft, - clearWhenEmpty: false, shared: options && options.shared, - handleMouseEvents: options && options.handleMouseEvents - }; - pos = clipPos(this, pos); - return markText(this, pos, pos, realOpts, "bookmark") - }, - findMarksAt: function (pos) { - pos = clipPos(this, pos); - var markers = [], spans = getLine(this, pos.line).markedSpans; - if (spans) { - for (var i = 0; i < spans.length; ++i) { - var span = spans[i]; - if ((span.from == null || span.from <= pos.ch) && - (span.to == null || span.to >= pos.ch)) { markers.push(span.marker.parent || span.marker); } - } - } - return markers - }, - findMarks: function (from, to, filter) { - from = clipPos(this, from); to = clipPos(this, to); - var found = [], lineNo = from.line; - this.iter(from.line, to.line + 1, function (line) { - var spans = line.markedSpans; - if (spans) { - for (var i = 0; i < spans.length; i++) { - var span = spans[i]; - if (!(span.to != null && lineNo == from.line && from.ch >= span.to || - span.from == null && lineNo != from.line || - span.from != null && lineNo == to.line && span.from >= to.ch) && - (!filter || filter(span.marker))) { found.push(span.marker.parent || span.marker); } - } - } - ++lineNo; - }); - return found - }, - getAllMarks: function () { - var markers = []; - this.iter(function (line) { - var sps = line.markedSpans; - if (sps) { - for (var i = 0; i < sps.length; ++i) { if (sps[i].from != null) { markers.push(sps[i].marker); } } - } - }); - return markers - }, + return NestedError; + }( /*#__PURE__*/_wrapNativeSuper(Error)); - posFromIndex: function (off) { - var ch, lineNo = this.first, sepSize = this.lineSeparator().length; - this.iter(function (line) { - var sz = line.text.length + sepSize; - if (sz > off) { ch = off; return true } - off -= sz; - ++lineNo; - }); - return clipPos(this, Pos(lineNo, ch)) - }, - indexFromPos: function (coords) { - coords = clipPos(this, coords); - var index = coords.ch; - if (coords.line < this.first || coords.ch < 0) { return 0 } - var sepSize = this.lineSeparator().length; - this.iter(this.first, coords.line, function (line) { // iter aborts when callback returns a truthy value - index += line.text.length + sepSize; - }); - return index - }, + /** + * @typedef {import('~types/cherry').CherryOptions} CherryOptions + * @typedef {import('~types/cherry').CherryEngineOptions} CherryEngineOptions + * @typedef {import('~types/cherry').CustomSyntaxRegConfig} CustomSyntaxRegConfig + * @typedef { (SyntaxBase | ParagraphBase) & { Cherry$$CUSTOM: true } } CustomSyntax + * @typedef { (typeof SyntaxBase | typeof ParagraphBase) & { Cherry$$CUSTOM: true } } CustomSyntaxClass + */ - copy: function (copyHistory) { - var doc = new Doc(getLines(this, this.first, this.first + this.size), - this.modeOption, this.first, this.lineSep, this.direction); - doc.scrollTop = this.scrollTop; doc.scrollLeft = this.scrollLeft; - doc.sel = this.sel; - doc.extend = false; - if (copyHistory) { - doc.history.undoDepth = this.history.undoDepth; - doc.setHistory(this.getHistory()); - } - return doc - }, + var WARN_DUPLICATED = -1; + var WARN_NOT_A_VALID_HOOK = -2; + /** + * 处理报错信息,在dev模式下才会输出报错信息 + * @param {number} type + * @param {any} objClass + * @param {number} index + */ - linkedDoc: function (options) { - if (!options) { options = {}; } - var from = this.first, to = this.first + this.size; - if (options.from != null && options.from > from) { from = options.from; } - if (options.to != null && options.to < to) { to = options.to; } - var copy = new Doc(getLines(this, from, to), options.mode || this.modeOption, from, this.lineSep, this.direction); - if (options.sharedHist) { - copy.history = this.history; - } (this.linked || (this.linked = [])).push({ doc: copy, sharedHist: options.sharedHist }); - copy.linked = [{ doc: this, isParent: true, sharedHist: options.sharedHist }]; - copySharedMarkers(copy, findSharedMarkers(this)); - return copy - }, - unlinkDoc: function (other) { - if (other instanceof CodeMirror) { other = other.doc; } - if (this.linked) { - for (var i = 0; i < this.linked.length; ++i) { - var link = this.linked[i]; - if (link.doc != other) { continue } - this.linked.splice(i, 1); - other.unlinkDoc(this); - detachSharedMarkers(findSharedMarkers(this)); - break - } - } - // If the histories were shared, split them again - if (other.history == this.history) { - var splitIds = [other.id]; - linkedDocs(other, function (doc) { return splitIds.push(doc.id); }, true); - other.history = new History(null); - other.history.done = copyHistoryArray(this.history.done, splitIds); - other.history.undone = copyHistoryArray(this.history.undone, splitIds); - } - }, - iterLinkedDocs: function (f) { linkedDocs(this, f); }, + function processWarning(type, objClass, index) { + if (type === WARN_DUPLICATED) { + var _context, _context2; - getMode: function () { return this.mode }, - getEditor: function () { return this.cm }, + Logger.warn(concat$5(_context = concat$5(_context2 = "Duplicate hook name [".concat(objClass.HOOK_NAME, "] found, hook [")).call(_context2, objClass.toString(), "] ")).call(_context, isNaN(index) ? '' : "at index [".concat(index, "] "), "will not take effect.")); + } else if (type === WARN_NOT_A_VALID_HOOK) { + var _context3; - splitLines: function (str) { - if (this.lineSep) { return str.split(this.lineSep) } - return splitLinesAuto(str) - }, - lineSeparator: function () { return this.lineSep || "\n" }, - - setDirection: docMethodOp(function (dir) { - if (dir != "rtl") { dir = "ltr"; } - if (dir == this.direction) { return } - this.direction = dir; - this.iter(function (line) { return line.order = null; }); - if (this.cm) { directionChanged(this.cm); } - }) - }); + Logger.warn(concat$5(_context3 = "Hook [".concat(objClass.toString(), "] ")).call(_context3, isNaN(index) ? '' : "at index [".concat(index, "] "), "is not a valid hook, and will not take effect.")); + } + } + /** + * 是否一个合法的 HookClass + * @param {any} HookClass + * @returns { HookClass is (typeof SyntaxBase | typeof ParagraphBase) } + */ - // Public alias. - Doc.prototype.eachLine = Doc.prototype.iter; - - // Kludge to work around strange IE behavior where it'll sometimes - // re-fire a series of drag-related events right after the drop (#1551) - var lastDrop = 0; - - function onDrop(e) { - var cm = this; - clearDragCursor(cm); - if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e)) { return } - e_preventDefault(e); - if (ie) { lastDrop = +new Date; } - var pos = posFromMouse(cm, e, true), files = e.dataTransfer.files; - if (!pos || cm.isReadOnly()) { return } - // Might be a file drop, in which case we simply extract the text - // and insert it. - if (files && files.length && window.FileReader && window.File) { - var n = files.length, text = Array(n), read = 0; - var markAsReadAndPasteIfAllFilesAreRead = function () { - if (++read == n) { - operation(cm, function () { - pos = clipPos(cm.doc, pos); - var change = { - from: pos, to: pos, - text: cm.doc.splitLines( - text.filter(function (t) { return t != null; }).join(cm.doc.lineSeparator())), - origin: "paste" - }; - makeChange(cm.doc, change); - setSelectionReplaceHistory(cm.doc, simpleSelection(clipPos(cm.doc, pos), clipPos(cm.doc, changeEnd(change)))); - })(); - } - }; - var readTextFromFile = function (file, i) { - if (cm.options.allowDropFileTypes && - indexOf(cm.options.allowDropFileTypes, file.type) == -1) { - markAsReadAndPasteIfAllFilesAreRead(); - return - } - var reader = new FileReader; - reader.onerror = function () { return markAsReadAndPasteIfAllFilesAreRead(); }; - reader.onload = function () { - var content = reader.result; - if (/[\x00-\x08\x0e-\x1f]{2}/.test(content)) { - markAsReadAndPasteIfAllFilesAreRead(); - return - } - text[i] = content; - markAsReadAndPasteIfAllFilesAreRead(); - }; - reader.readAsText(file); - }; - for (var i = 0; i < files.length; i++) { readTextFromFile(files[i], i); } - } else { // Normal drop - // Don't do a replace if the drop happened inside of the selected text. - if (cm.state.draggingText && cm.doc.sel.contains(pos) > -1) { - cm.state.draggingText(e); - // Ensure the editor is re-focused - setTimeout(function () { return cm.display.input.focus(); }, 20); - return - } - try { - var text$1 = e.dataTransfer.getData("Text"); - if (text$1) { - var selected; - if (cm.state.draggingText && !cm.state.draggingText.copy) { selected = cm.listSelections(); } - setSelectionNoUndo(cm.doc, simpleSelection(pos, pos)); - if (selected) { - for (var i$1 = 0; i$1 < selected.length; ++i$1) { replaceRange(cm.doc, "", selected[i$1].anchor, selected[i$1].head, "drag"); } - } - cm.replaceSelection(text$1, "around", "paste"); - cm.display.input.focus(); - } - } - catch (e$1) { } - } - } - function onDragStart(cm, e) { - if (ie && (!cm.state.draggingText || +new Date - lastDrop < 100)) { e_stop(e); return } - if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e)) { return } - - e.dataTransfer.setData("Text", cm.getSelection()); - e.dataTransfer.effectAllowed = "copyMove"; - - // Use dummy image instead of default browsers image. - // Recent Safari (~6.0.2) have a tendency to segfault when this happens, so we don't do it there. - if (e.dataTransfer.setDragImage && !safari) { - var img = elt("img", null, null, "position: fixed; left: 0; top: 0;"); - img.src = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="; - if (presto) { - img.width = img.height = 1; - cm.display.wrapper.appendChild(img); - // Force a relayout, or Opera won't use our image for some obscure reason - img._top = img.offsetTop; - } - e.dataTransfer.setDragImage(img, 0, 0); - if (presto) { img.parentNode.removeChild(img); } - } - } + function isHookValid(HookClass) { + return isProtoOfSyntaxBase(HookClass) || isProtoOfParagraphBase(HookClass); + } + /** + * 传入的类是否 SyntaxBase 的子类 + * @param {any} value + * @returns { value is typeof SyntaxBase } + */ - function onDragOver(cm, e) { - var pos = posFromMouse(cm, e); - if (!pos) { return } - var frag = document.createDocumentFragment(); - drawSelectionCursor(cm, pos, frag); - if (!cm.display.dragCursor) { - cm.display.dragCursor = elt("div", null, "CodeMirror-cursors CodeMirror-dragcursors"); - cm.display.lineSpace.insertBefore(cm.display.dragCursor, cm.display.cursorDiv); - } - removeChildrenAndAdd(cm.display.dragCursor, frag); - } - function clearDragCursor(cm) { - if (cm.display.dragCursor) { - cm.display.lineSpace.removeChild(cm.display.dragCursor); - cm.display.dragCursor = null; - } - } + function isProtoOfSyntaxBase(value) { + return Object.prototype.isPrototypeOf.call(SyntaxBase, value); + } + /** + * 传入的类是否 ParagraphBase 的子类 + * @param {any} value + * @returns { value is typeof ParagraphBase } + */ - // These must be handled carefully, because naively registering a - // handler for each editor will cause the editors to never be - // garbage collected. - function forEachCodeMirror(f) { - if (!document.getElementsByClassName) { return } - var byClass = document.getElementsByClassName("CodeMirror"), editors = []; - for (var i = 0; i < byClass.length; i++) { - var cm = byClass[i].CodeMirror; - if (cm) { editors.push(cm); } - } - if (editors.length) { - editors[0].operation(function () { - for (var i = 0; i < editors.length; i++) { f(editors[i]); } - }); - } - } + function isProtoOfParagraphBase(value) { + return Object.prototype.isPrototypeOf.call(ParagraphBase, value); + } + /** + * 是否一个配置型的自定义语法 + * @param {any} value + * @returns { value is CustomSyntaxRegConfig } + */ - var globalsRegistered = false; - function ensureGlobalHandlers() { - if (globalsRegistered) { return } - registerGlobalHandlers(); - globalsRegistered = true; - } - function registerGlobalHandlers() { - // When the window resizes, we need to refresh active editors. - var resizeTimer; - on(window, "resize", function () { - if (resizeTimer == null) { - resizeTimer = setTimeout(function () { - resizeTimer = null; - forEachCodeMirror(onResize); - }, 100); - } - }); - // When the window loses focus, we want to show the editor as blurred - on(window, "blur", function () { return forEachCodeMirror(onBlur); }); - } - // Called when the window resizes - function onResize(cm) { - var d = cm.display; - // Might be a text scaling operation, clear size caches. - d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null; - d.scrollbarsClipped = false; - cm.setSize(); - } - var keyNames = { - 3: "Pause", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt", - 19: "Pause", 20: "CapsLock", 27: "Esc", 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End", - 36: "Home", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "PrintScrn", 45: "Insert", - 46: "Delete", 59: ";", 61: "=", 91: "Mod", 92: "Mod", 93: "Mod", - 106: "*", 107: "=", 109: "-", 110: ".", 111: "/", 145: "ScrollLock", - 173: "-", 186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\", - 221: "]", 222: "'", 224: "Mod", 63232: "Up", 63233: "Down", 63234: "Left", 63235: "Right", 63272: "Delete", - 63273: "Home", 63275: "End", 63276: "PageUp", 63277: "PageDown", 63302: "Insert" - }; + function isCustomSyntaxConfig(value) { + var syntaxClass = + /** @type {any} */ - // Number keys - for (var i = 0; i < 10; i++) { keyNames[i + 48] = keyNames[i + 96] = String(i); } - // Alphabetic keys - for (var i$1 = 65; i$1 <= 90; i$1++) { keyNames[i$1] = String.fromCharCode(i$1); } - // Function keys - for (var i$2 = 1; i$2 <= 12; i$2++) { keyNames[i$2 + 111] = keyNames[i$2 + 63235] = "F" + i$2; } - - var keyMap = {}; - - keyMap.basic = { - "Left": "goCharLeft", "Right": "goCharRight", "Up": "goLineUp", "Down": "goLineDown", - "End": "goLineEnd", "Home": "goLineStartSmart", "PageUp": "goPageUp", "PageDown": "goPageDown", - "Delete": "delCharAfter", "Backspace": "delCharBefore", "Shift-Backspace": "delCharBefore", - "Tab": "defaultTab", "Shift-Tab": "indentAuto", - "Enter": "newlineAndIndent", "Insert": "toggleOverwrite", - "Esc": "singleSelection" - }; - // Note that the save and find-related commands aren't defined by - // default. User code or addons can define them. Unknown commands - // are simply ignored. - keyMap.pcDefault = { - "Ctrl-A": "selectAll", "Ctrl-D": "deleteLine", "Ctrl-Z": "undo", "Shift-Ctrl-Z": "redo", "Ctrl-Y": "redo", - "Ctrl-Home": "goDocStart", "Ctrl-End": "goDocEnd", "Ctrl-Up": "goLineUp", "Ctrl-Down": "goLineDown", - "Ctrl-Left": "goGroupLeft", "Ctrl-Right": "goGroupRight", "Alt-Left": "goLineStart", "Alt-Right": "goLineEnd", - "Ctrl-Backspace": "delGroupBefore", "Ctrl-Delete": "delGroupAfter", "Ctrl-S": "save", "Ctrl-F": "find", - "Ctrl-G": "findNext", "Shift-Ctrl-G": "findPrev", "Shift-Ctrl-F": "replace", "Shift-Ctrl-R": "replaceAll", - "Ctrl-[": "indentLess", "Ctrl-]": "indentMore", - "Ctrl-U": "undoSelection", "Shift-Ctrl-U": "redoSelection", "Alt-U": "redoSelection", - "fallthrough": "basic" - }; - // Very basic readline/emacs-style bindings, which are standard on Mac. - keyMap.emacsy = { - "Ctrl-F": "goCharRight", "Ctrl-B": "goCharLeft", "Ctrl-P": "goLineUp", "Ctrl-N": "goLineDown", - "Alt-F": "goWordRight", "Alt-B": "goWordLeft", "Ctrl-A": "goLineStart", "Ctrl-E": "goLineEnd", - "Ctrl-V": "goPageDown", "Shift-Ctrl-V": "goPageUp", "Ctrl-D": "delCharAfter", "Ctrl-H": "delCharBefore", - "Alt-D": "delWordAfter", "Alt-Backspace": "delWordBefore", "Ctrl-K": "killLine", "Ctrl-T": "transposeChars", - "Ctrl-O": "openLine" - }; - keyMap.macDefault = { - "Cmd-A": "selectAll", "Cmd-D": "deleteLine", "Cmd-Z": "undo", "Shift-Cmd-Z": "redo", "Cmd-Y": "redo", - "Cmd-Home": "goDocStart", "Cmd-Up": "goDocStart", "Cmd-End": "goDocEnd", "Cmd-Down": "goDocEnd", "Alt-Left": "goGroupLeft", - "Alt-Right": "goGroupRight", "Cmd-Left": "goLineLeft", "Cmd-Right": "goLineRight", "Alt-Backspace": "delGroupBefore", - "Ctrl-Alt-Backspace": "delGroupAfter", "Alt-Delete": "delGroupAfter", "Cmd-S": "save", "Cmd-F": "find", - "Cmd-G": "findNext", "Shift-Cmd-G": "findPrev", "Cmd-Alt-F": "replace", "Shift-Cmd-Alt-F": "replaceAll", - "Cmd-[": "indentLess", "Cmd-]": "indentMore", "Cmd-Backspace": "delWrappedLineLeft", "Cmd-Delete": "delWrappedLineRight", - "Cmd-U": "undoSelection", "Shift-Cmd-U": "redoSelection", "Ctrl-Up": "goDocStart", "Ctrl-Down": "goDocEnd", - "fallthrough": ["basic", "emacsy"] - }; - keyMap["default"] = mac ? keyMap.macDefault : keyMap.pcDefault; - - // KEYMAP DISPATCH - - function normalizeKeyName(name) { - var parts = name.split(/-(?!$)/); - name = parts[parts.length - 1]; - var alt, ctrl, shift, cmd; - for (var i = 0; i < parts.length - 1; i++) { - var mod = parts[i]; - if (/^(cmd|meta|m)$/i.test(mod)) { cmd = true; } - else if (/^a(lt)?$/i.test(mod)) { alt = true; } - else if (/^(c|ctrl|control)$/i.test(mod)) { ctrl = true; } - else if (/^s(hift)?$/i.test(mod)) { shift = true; } - else { throw new Error("Unrecognized modifier name: " + mod) } - } - if (alt) { name = "Alt-" + name; } - if (ctrl) { name = "Ctrl-" + name; } - if (cmd) { name = "Cmd-" + name; } - if (shift) { name = "Shift-" + name; } - return name - } + /** @type {CustomSyntaxRegConfig} */ + value === null || value === void 0 ? void 0 : value.syntaxClass; + return isProtoOfSyntaxBase(syntaxClass) || isProtoOfParagraphBase(syntaxClass); + } + /** + * 是否一个已注册的自定义语法hook类 + * @param {any} value + * @returns { value is CustomSyntaxClass } + */ - // This is a kludge to keep keymaps mostly working as raw objects - // (backwards compatibility) while at the same time support features - // like normalization and multi-stroke key bindings. It compiles a - // new normalized keymap, and then updates the old object to reflect - // this. - function normalizeKeyMap(keymap) { - var copy = {}; - for (var keyname in keymap) { - if (keymap.hasOwnProperty(keyname)) { - var value = keymap[keyname]; - if (/^(name|fallthrough|(de|at)tach)$/.test(keyname)) { continue } - if (value == "...") { delete keymap[keyname]; continue } - - var keys = map(keyname.split(" "), normalizeKeyName); - for (var i = 0; i < keys.length; i++) { - var val = (void 0), name = (void 0); - if (i == keys.length - 1) { - name = keys.join(" "); - val = value; - } else { - name = keys.slice(0, i + 1).join(" "); - val = "..."; - } - var prev = copy[name]; - if (!prev) { copy[name] = val; } - else if (prev != val) { throw new Error("Inconsistent bindings for " + name) } - } - delete keymap[keyname]; - } - } - for (var prop in copy) { keymap[prop] = copy[prop]; } - return keymap - } - function lookupKey(key, map, handle, context) { - map = getKeyMap(map); - var found = map.call ? map.call(key, context) : map[key]; - if (found === false) { return "nothing" } - if (found === "...") { return "multi" } - if (found != null && handle(found)) { return "handled" } - - if (map.fallthrough) { - if (Object.prototype.toString.call(map.fallthrough) != "[object Array]") { return lookupKey(key, map.fallthrough, handle, context) } - for (var i = 0; i < map.fallthrough.length; i++) { - var result = lookupKey(key, map.fallthrough[i], handle, context); - if (result) { return result } - } - } - } + function isRegisteredCustomSyntaxClass(value) { + return isHookValid(value) && + /** @type {CustomSyntaxClass} */ + (value === null || value === void 0 ? void 0 : value.Cherry$$CUSTOM) === true; + } + /** + * 语法注册中心 + */ - // Modifier key presses don't count as 'real' key presses for the - // purpose of keymap fallthrough. - function isModifierKey(value) { - var name = typeof value == "string" ? value : keyNames[value.keyCode]; - return name == "Ctrl" || name == "Alt" || name == "Shift" || name == "Mod" - } - function addModifierNames(name, event, noShift) { - var base = name; - if (event.altKey && base != "Alt") { name = "Alt-" + name; } - if ((flipCtrlCmd ? event.metaKey : event.ctrlKey) && base != "Ctrl") { name = "Ctrl-" + name; } - if ((flipCtrlCmd ? event.ctrlKey : event.metaKey) && base != "Mod") { name = "Cmd-" + name; } - if (!noShift && event.shiftKey && base != "Shift") { name = "Shift-" + name; } - return name - } + var HookCenter = /*#__PURE__*/function () { + /** + * + * @param {(typeof SyntaxBase)[]} hooksConfig + * @param {Partial} editorConfig + */ + function HookCenter(hooksConfig, editorConfig, cherry) { + _classCallCheck(this, HookCenter); + + this.$locale = cherry.locale; + /** + * @property + * @type {Record} hookList hook 名称 -> hook 类型的映射 + */ + + this.hookList = + /** @type {any} */ + {}; + /** + * @property + * @type {Record} hookNameList hook 名称 -> hook 类型的映射 + */ + + this.hookNameList = {}; + $expectTarget(hooksConfig, Array); + this.registerInternalHooks(hooksConfig, editorConfig); + this.registerCustomHooks(editorConfig.engine.customSyntax, editorConfig); + } + /** + * 注册系统默认的语法hook + * @param {any[]} hooksConfig 在hookconfig.js里定义的配置 + * @param {Partial} editorConfig 编辑器配置 + */ + + + _createClass(HookCenter, [{ + key: "registerInternalHooks", + value: function registerInternalHooks(hooksConfig, editorConfig) { + var _this = this; + + forEach$3(hooksConfig).call(hooksConfig, + /** + * + * @param {typeof SyntaxBase} HookClass + * @param {number} index + */ + function (HookClass, index) { + var result = _this.register(HookClass, editorConfig); + + processWarning(result, HookClass, index); + }); + } + /** + * 注册第三方的语法hook + * @param {CherryEngineOptions['customSyntax']} customHooks 用户传入的配置 + * @param {Partial} editorConfig 编辑器配置 + */ + + }, { + key: "registerCustomHooks", + value: function registerCustomHooks(customHooks, editorConfig) { + var _this2 = this; + + if (!customHooks) { + return; + } + + var hookNames = keys$3(customHooks); + + forEach$3(hookNames).call(hookNames, function (hookName) { + /** @type {number} */ + var result; + /** @type {typeof SyntaxBase} */ + + var HookClass; + var customHookConfig = {}; + var hookClassOrConfig = customHooks[hookName]; + + if (isProtoOfSyntaxBase(hookClassOrConfig)) { + HookClass = hookClassOrConfig; + } else if (isCustomSyntaxConfig(hookClassOrConfig)) { + HookClass = hookClassOrConfig.syntaxClass; + customHookConfig.force = Boolean(hookClassOrConfig.force); + + if (hookClassOrConfig.before) { + customHookConfig.before = hookClassOrConfig.before; + } else if (hookClassOrConfig.after) { + customHookConfig.after = hookClassOrConfig.after; + } + } else { + return; + } + + if (isHookValid(HookClass)) { + // 自定义Hook标识 + defineProperty$5(HookClass, 'Cherry$$CUSTOM', { + enumerable: false, + configurable: false, + writable: false, + value: true + }); + + result = _this2.register(HookClass, editorConfig, customHookConfig); + } else { + result = WARN_NOT_A_VALID_HOOK; + } + + processWarning(result, HookClass, undefined); + }); + } + }, { + key: "getHookList", + value: function getHookList() { + return this.hookList; + } + }, { + key: "getHookNameList", + value: function getHookNameList() { + return this.hookNameList; + } + /** + * + * @param {((...args: any[]) => any) | typeof SyntaxBase} HookClass + * @param {Partial} editorConfig + * @param {Omit} [customHookConfig] + * @returns + */ + + }, { + key: "register", + value: function register(HookClass, editorConfig, customHookConfig) { + var _this3 = this; + + // filter Configs Here + var externals = editorConfig.externals, + engine = editorConfig.engine; + var syntax = engine.syntax; + /** @type {SyntaxBase | CustomSyntax} */ + + var instance; + /** @type {string} */ + + var hookName; // 首先校验Hook是否合法 + + if (!isHookValid(HookClass)) { + // 可能是一个function hook + if (typeof HookClass === 'function') { + var funcHook = HookClass; + instance = funcHook(editorConfig); + + if (!instance || !isHookValid(instance.constructor)) { + return WARN_NOT_A_VALID_HOOK; + } + + hookName = instance.getName(); + } else { + return WARN_NOT_A_VALID_HOOK; + } + } else { + hookName = HookClass.HOOK_NAME; // TODO: 需要考虑自定义 hook 配置的传入方式 + + var config = (syntax === null || syntax === void 0 ? void 0 : syntax[hookName]) || {}; + instance = new HookClass({ + externals: externals, + config: config, + globalConfig: engine.global + }); + instance.afterInit(function () { + instance.setLocale(_this3.$locale); + }); + } // TODO: 待校验是否需要跳过禁用的自定义 hook + // Skip Disabled Internal Hooks + + + if (syntax[hookName] === false && !isRegisteredCustomSyntaxClass(HookClass)) { + return; + } // 下面处理的都是 CustomSyntax + + + var hookType = instance.getType(); + + if (this.hookNameList[hookName]) { + var _context4; + + // 内置 hook 重名 + if (!isRegisteredCustomSyntaxClass(HookClass)) { + return WARN_DUPLICATED; + } // 自定义 hook 重名且没有开启覆盖的选项 + + + if (!customHookConfig.force) { + return WARN_DUPLICATED; + } // 强制覆盖以前的Hook,所以需要移除 + + + var duplicateHookType = this.hookNameList[hookName].type; + this.hookList[duplicateHookType] = filter$3(_context4 = this.hookList[duplicateHookType]).call(_context4, function (hook) { + return hook.getName() !== hookName; + }); + } + + this.hookNameList[hookName] = { + type: hookType + }; + this.hookList[hookType] = this.hookList[hookType] || []; // 内置Hook直接push到结尾 + + if (!isRegisteredCustomSyntaxClass(HookClass)) { + this.hookList[hookType].push(instance); + return; + } // 插入自定义Hook + + + var insertIndex = -1; + + if (customHookConfig.before) { + var _context5; + + insertIndex = findIndex$3(_context5 = this.hookList[hookType]).call(_context5, function (hook) { + return hook.getName() === customHookConfig.before; + }); - // Look up the name of a key as indicated by an event object. - function keyName(event, noShift) { - if (presto && event.keyCode == 34 && event["char"]) { return false } - var name = keyNames[event.keyCode]; - if (name == null || event.altGraphKey) { return false } - // Ctrl-ScrollLock has keyCode 3, same as Ctrl-Pause, - // so we'll use event.code when available (Chrome 48+, FF 38+, Safari 10.1+) - if (event.keyCode == 3 && event.code) { name = event.code; } - return addModifierNames(name, event, noShift) - } + if (insertIndex === -1) { + var _context6; - function getKeyMap(val) { - return typeof val == "string" ? keyMap[val] : val - } + Logger.warn(concat$5(_context6 = "Cannot find hook named [".concat(customHookConfig.before, "],\n custom hook [")).call(_context6, hookName, "] will append to the end of the hooks.")); + } + } else if (customHookConfig.after) { + var _context7, _context8; - // Helper for deleting text near the selection(s), used to implement - // backspace, delete, and similar functionality. - function deleteNearSelection(cm, compute) { - var ranges = cm.doc.sel.ranges, kill = []; - // Build up a set of ranges to kill first, merging overlapping - // ranges. - for (var i = 0; i < ranges.length; i++) { - var toKill = compute(ranges[i]); - while (kill.length && cmp(toKill.from, lst(kill).to) <= 0) { - var replaced = kill.pop(); - if (cmp(replaced.from, toKill.from) < 0) { - toKill.from = replaced.from; - break - } - } - kill.push(toKill); - } - // Next, remove those actual ranges. - runInOp(cm, function () { - for (var i = kill.length - 1; i >= 0; i--) { replaceRange(cm.doc, "", kill[i].from, kill[i].to, "+delete"); } - ensureCursorVisible(cm); - }); - } + insertIndex = findIndex$3(_context7 = this.hookList[hookType]).call(_context7, function (hook) { + return hook.getName() === customHookConfig.after; + }); + insertIndex === -1 ? Logger.warn(concat$5(_context8 = "Cannot find hook named [".concat(customHookConfig.after, "],\n custom hook [")).call(_context8, hookName, "] will append to the end of the hooks.")) : insertIndex += 1; // 统一处理往前插入的逻辑,所以要插入某Hook之后,索引需要加一 + } // 无需插入或目标索引为数组结尾 - function moveCharLogically(line, ch, dir) { - var target = skipExtendingChars(line.text, ch + dir, dir); - return target < 0 || target > line.text.length ? null : target - } - function moveLogically(line, start, dir) { - var ch = moveCharLogically(line, start.ch, dir); - return ch == null ? null : new Pos(start.line, ch, dir < 0 ? "after" : "before") - } + if (insertIndex < 0 || insertIndex >= this.hookList[hookType].length) { + this.hookList[hookType].push(instance); + } else { + var _context9; - function endOfLine(visually, cm, lineObj, lineNo, dir) { - if (visually) { - if (cm.doc.direction == "rtl") { dir = -dir; } - var order = getOrder(lineObj, cm.doc.direction); - if (order) { - var part = dir < 0 ? lst(order) : order[0]; - var moveInStorageOrder = (dir < 0) == (part.level == 1); - var sticky = moveInStorageOrder ? "after" : "before"; - var ch; - // With a wrapped rtl chunk (possibly spanning multiple bidi parts), - // it could be that the last bidi part is not on the last visual line, - // since visual lines contain content order-consecutive chunks. - // Thus, in rtl, we are looking for the first (content-order) character - // in the rtl chunk that is on the last line (that is, the same line - // as the last (content-order) character). - if (part.level > 0 || cm.doc.direction == "rtl") { - var prep = prepareMeasureForLine(cm, lineObj); - ch = dir < 0 ? lineObj.text.length - 1 : 0; - var targetTop = measureCharPrepared(cm, prep, ch).top; - ch = findFirst(function (ch) { return measureCharPrepared(cm, prep, ch).top == targetTop; }, (dir < 0) == (part.level == 1) ? part.from : part.to - 1, ch); - if (sticky == "before") { ch = moveCharLogically(lineObj, ch, 1); } - } else { ch = dir < 0 ? part.to : part.from; } - return new Pos(lineNo, ch, sticky) - } - } - return new Pos(lineNo, dir < 0 ? lineObj.text.length : 0, dir < 0 ? "before" : "after") - } + splice$4(_context9 = this.hookList[hookType]).call(_context9, insertIndex, 0, instance); + } // console.log(this.hookList[hookType]); - function moveVisually(cm, line, start, dir) { - var bidi = getOrder(line, cm.doc.direction); - if (!bidi) { return moveLogically(line, start, dir) } - if (start.ch >= line.text.length) { - start.ch = line.text.length; - start.sticky = "before"; - } else if (start.ch <= 0) { - start.ch = 0; - start.sticky = "after"; - } - var partPos = getBidiPartAt(bidi, start.ch, start.sticky), part = bidi[partPos]; - if (cm.doc.direction == "ltr" && part.level % 2 == 0 && (dir > 0 ? part.to > start.ch : part.from < start.ch)) { - // Case 1: We move within an ltr part in an ltr editor. Even with wrapped lines, - // nothing interesting happens. - return moveLogically(line, start, dir) - } + } + }]); - var mv = function (pos, dir) { return moveCharLogically(line, pos instanceof Pos ? pos.ch : pos, dir); }; - var prep; - var getWrappedLineExtent = function (ch) { - if (!cm.options.lineWrapping) { return { begin: 0, end: line.text.length } } - prep = prep || prepareMeasureForLine(cm, line); - return wrappedLineExtentChar(cm, line, prep, ch) - }; - var wrappedLineExtent = getWrappedLineExtent(start.sticky == "before" ? mv(start, -1) : start.ch); - - if (cm.doc.direction == "rtl" || part.level == 1) { - var moveInStorageOrder = (part.level == 1) == (dir < 0); - var ch = mv(start, moveInStorageOrder ? 1 : -1); - if (ch != null && (!moveInStorageOrder ? ch >= part.from && ch >= wrappedLineExtent.begin : ch <= part.to && ch <= wrappedLineExtent.end)) { - // Case 2: We move within an rtl part or in an rtl editor on the same visual line - var sticky = moveInStorageOrder ? "before" : "after"; - return new Pos(start.line, ch, sticky) - } - } + return HookCenter; + }(); - // Case 3: Could not move within this bidi part in this visual line, so leave - // the current bidi part + var arrayWithoutHoles = createCommonjsModule(function (module) { + function _arrayWithoutHoles(arr) { + if (isArray$7(arr)) return arrayLikeToArray(arr); + } - var searchInVisualLine = function (partPos, dir, wrappedLineExtent) { - var getRes = function (ch, moveInStorageOrder) { - return moveInStorageOrder - ? new Pos(start.line, mv(ch, 1), "before") - : new Pos(start.line, ch, "after"); - }; + module.exports = _arrayWithoutHoles, module.exports.__esModule = true, module.exports["default"] = module.exports; + }); - for (; partPos >= 0 && partPos < bidi.length; partPos += dir) { - var part = bidi[partPos]; - var moveInStorageOrder = (dir > 0) == (part.level != 1); - var ch = moveInStorageOrder ? wrappedLineExtent.begin : mv(wrappedLineExtent.end, -1); - if (part.from <= ch && ch < part.to) { return getRes(ch, moveInStorageOrder) } - ch = moveInStorageOrder ? part.from : mv(part.to, -1); - if (wrappedLineExtent.begin <= ch && ch < wrappedLineExtent.end) { return getRes(ch, moveInStorageOrder) } - } - }; + unwrapExports(arrayWithoutHoles); - // Case 3a: Look for other bidi parts on the same visual line - var res = searchInVisualLine(partPos + dir, dir, wrappedLineExtent); - if (res) { return res } + var iterableToArray = createCommonjsModule(function (module) { + function _iterableToArray(iter) { + if (typeof symbol$5 !== "undefined" && getIteratorMethod$5(iter) != null || iter["@@iterator"] != null) return from_1$6(iter); + } - // Case 3b: Look for other bidi parts on the next visual line - var nextCh = dir > 0 ? wrappedLineExtent.end : mv(wrappedLineExtent.begin, -1); - if (nextCh != null && !(dir > 0 && nextCh == line.text.length)) { - res = searchInVisualLine(dir > 0 ? 0 : bidi.length - 1, dir, getWrappedLineExtent(nextCh)); - if (res) { return res } - } + module.exports = _iterableToArray, module.exports.__esModule = true, module.exports["default"] = module.exports; + }); - // Case 4: Nowhere to move - return null - } + unwrapExports(iterableToArray); - // Commands are parameter-less actions that can be performed on an - // editor, mostly used for keybindings. - var commands = { - selectAll: selectAll, - singleSelection: function (cm) { return cm.setSelection(cm.getCursor("anchor"), cm.getCursor("head"), sel_dontScroll); }, - killLine: function (cm) { - return deleteNearSelection(cm, function (range) { - if (range.empty()) { - var len = getLine(cm.doc, range.head.line).text.length; - if (range.head.ch == len && range.head.line < cm.lastLine()) { return { from: range.head, to: Pos(range.head.line + 1, 0) } } - else { return { from: range.head, to: Pos(range.head.line, len) } } - } else { - return { from: range.from(), to: range.to() } - } - }); - }, - deleteLine: function (cm) { - return deleteNearSelection(cm, function (range) { - return ({ - from: Pos(range.from().line, 0), - to: clipPos(cm.doc, Pos(range.to().line + 1, 0)) - }); - }); - }, - delLineLeft: function (cm) { - return deleteNearSelection(cm, function (range) { - return ({ - from: Pos(range.from().line, 0), to: range.from() - }); - }); - }, - delWrappedLineLeft: function (cm) { - return deleteNearSelection(cm, function (range) { - var top = cm.charCoords(range.head, "div").top + 5; - var leftPos = cm.coordsChar({ left: 0, top: top }, "div"); - return { from: leftPos, to: range.from() } - }); - }, - delWrappedLineRight: function (cm) { - return deleteNearSelection(cm, function (range) { - var top = cm.charCoords(range.head, "div").top + 5; - var rightPos = cm.coordsChar({ left: cm.display.lineDiv.offsetWidth + 100, top: top }, "div"); - return { from: range.from(), to: rightPos } - }); - }, - undo: function (cm) { return cm.undo(); }, - redo: function (cm) { return cm.redo(); }, - undoSelection: function (cm) { return cm.undoSelection(); }, - redoSelection: function (cm) { return cm.redoSelection(); }, - goDocStart: function (cm) { return cm.extendSelection(Pos(cm.firstLine(), 0)); }, - goDocEnd: function (cm) { return cm.extendSelection(Pos(cm.lastLine())); }, - goLineStart: function (cm) { - return cm.extendSelectionsBy(function (range) { return lineStart(cm, range.head.line); }, - { origin: "+move", bias: 1 } - ); - }, - goLineStartSmart: function (cm) { - return cm.extendSelectionsBy(function (range) { return lineStartSmart(cm, range.head); }, - { origin: "+move", bias: 1 } - ); - }, - goLineEnd: function (cm) { - return cm.extendSelectionsBy(function (range) { return lineEnd(cm, range.head.line); }, - { origin: "+move", bias: -1 } - ); - }, - goLineRight: function (cm) { - return cm.extendSelectionsBy(function (range) { - var top = cm.cursorCoords(range.head, "div").top + 5; - return cm.coordsChar({ left: cm.display.lineDiv.offsetWidth + 100, top: top }, "div") - }, sel_move); - }, - goLineLeft: function (cm) { - return cm.extendSelectionsBy(function (range) { - var top = cm.cursorCoords(range.head, "div").top + 5; - return cm.coordsChar({ left: 0, top: top }, "div") - }, sel_move); - }, - goLineLeftSmart: function (cm) { - return cm.extendSelectionsBy(function (range) { - var top = cm.cursorCoords(range.head, "div").top + 5; - var pos = cm.coordsChar({ left: 0, top: top }, "div"); - if (pos.ch < cm.getLine(pos.line).search(/\S/)) { return lineStartSmart(cm, range.head) } - return pos - }, sel_move); - }, - goLineUp: function (cm) { return cm.moveV(-1, "line"); }, - goLineDown: function (cm) { return cm.moveV(1, "line"); }, - goPageUp: function (cm) { return cm.moveV(-1, "page"); }, - goPageDown: function (cm) { return cm.moveV(1, "page"); }, - goCharLeft: function (cm) { return cm.moveH(-1, "char"); }, - goCharRight: function (cm) { return cm.moveH(1, "char"); }, - goColumnLeft: function (cm) { return cm.moveH(-1, "column"); }, - goColumnRight: function (cm) { return cm.moveH(1, "column"); }, - goWordLeft: function (cm) { return cm.moveH(-1, "word"); }, - goGroupRight: function (cm) { return cm.moveH(1, "group"); }, - goGroupLeft: function (cm) { return cm.moveH(-1, "group"); }, - goWordRight: function (cm) { return cm.moveH(1, "word"); }, - delCharBefore: function (cm) { return cm.deleteH(-1, "codepoint"); }, - delCharAfter: function (cm) { return cm.deleteH(1, "char"); }, - delWordBefore: function (cm) { return cm.deleteH(-1, "word"); }, - delWordAfter: function (cm) { return cm.deleteH(1, "word"); }, - delGroupBefore: function (cm) { return cm.deleteH(-1, "group"); }, - delGroupAfter: function (cm) { return cm.deleteH(1, "group"); }, - indentAuto: function (cm) { return cm.indentSelection("smart"); }, - indentMore: function (cm) { return cm.indentSelection("add"); }, - indentLess: function (cm) { return cm.indentSelection("subtract"); }, - insertTab: function (cm) { return cm.replaceSelection("\t"); }, - insertSoftTab: function (cm) { - var spaces = [], ranges = cm.listSelections(), tabSize = cm.options.tabSize; - for (var i = 0; i < ranges.length; i++) { - var pos = ranges[i].from(); - var col = countColumn(cm.getLine(pos.line), pos.ch, tabSize); - spaces.push(spaceStr(tabSize - col % tabSize)); - } - cm.replaceSelections(spaces); - }, - defaultTab: function (cm) { - if (cm.somethingSelected()) { cm.indentSelection("add"); } - else { cm.execCommand("insertTab"); } - }, - // Swap the two chars left and right of each selection's head. - // Move cursor behind the two swapped characters afterwards. - // - // Doesn't consider line feeds a character. - // Doesn't scan more than one line above to find a character. - // Doesn't do anything on an empty line. - // Doesn't do anything with non-empty selections. - transposeChars: function (cm) { - return runInOp(cm, function () { - var ranges = cm.listSelections(), newSel = []; - for (var i = 0; i < ranges.length; i++) { - if (!ranges[i].empty()) { continue } - var cur = ranges[i].head, line = getLine(cm.doc, cur.line).text; - if (line) { - if (cur.ch == line.length) { cur = new Pos(cur.line, cur.ch - 1); } - if (cur.ch > 0) { - cur = new Pos(cur.line, cur.ch + 1); - cm.replaceRange(line.charAt(cur.ch - 1) + line.charAt(cur.ch - 2), - Pos(cur.line, cur.ch - 2), cur, "+transpose"); - } else if (cur.line > cm.doc.first) { - var prev = getLine(cm.doc, cur.line - 1).text; - if (prev) { - cur = new Pos(cur.line, 1); - cm.replaceRange(line.charAt(0) + cm.doc.lineSeparator() + - prev.charAt(prev.length - 1), - Pos(cur.line - 1, prev.length - 1), cur, "+transpose"); - } - } - } - newSel.push(new Range(cur, cur)); - } - cm.setSelections(newSel); - }); - }, - newlineAndIndent: function (cm) { - return runInOp(cm, function () { - var sels = cm.listSelections(); - for (var i = sels.length - 1; i >= 0; i--) { cm.replaceRange(cm.doc.lineSeparator(), sels[i].anchor, sels[i].head, "+input"); } - sels = cm.listSelections(); - for (var i$1 = 0; i$1 < sels.length; i$1++) { cm.indentLine(sels[i$1].from().line, null, true); } - ensureCursorVisible(cm); - }); - }, - openLine: function (cm) { return cm.replaceSelection("\n", "start"); }, - toggleOverwrite: function (cm) { return cm.toggleOverwrite(); } - }; + var nonIterableSpread = createCommonjsModule(function (module) { + function _nonIterableSpread() { + throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); + } + module.exports = _nonIterableSpread, module.exports.__esModule = true, module.exports["default"] = module.exports; + }); - function lineStart(cm, lineN) { - var line = getLine(cm.doc, lineN); - var visual = visualLine(line); - if (visual != line) { lineN = lineNo(visual); } - return endOfLine(true, cm, visual, lineN, 1) - } - function lineEnd(cm, lineN) { - var line = getLine(cm.doc, lineN); - var visual = visualLineEnd(line); - if (visual != line) { lineN = lineNo(visual); } - return endOfLine(true, cm, line, lineN, -1) - } - function lineStartSmart(cm, pos) { - var start = lineStart(cm, pos.line); - var line = getLine(cm.doc, start.line); - var order = getOrder(line, cm.doc.direction); - if (!order || order[0].level == 0) { - var firstNonWS = Math.max(start.ch, line.text.search(/\S/)); - var inWS = pos.line == start.line && pos.ch <= firstNonWS && pos.ch; - return Pos(start.line, inWS ? 0 : firstNonWS, start.sticky) - } - return start - } + unwrapExports(nonIterableSpread); - // Run a handler that was bound to a key. - function doHandleBinding(cm, bound, dropShift) { - if (typeof bound == "string") { - bound = commands[bound]; - if (!bound) { return false } - } - // Ensure previous input has been read, so that the handler sees a - // consistent view of the document - cm.display.input.ensurePolled(); - var prevShift = cm.display.shift, done = false; - try { - if (cm.isReadOnly()) { cm.state.suppressEdits = true; } - if (dropShift) { cm.display.shift = false; } - done = bound(cm) != Pass; - } finally { - cm.display.shift = prevShift; - cm.state.suppressEdits = false; - } - return done - } + var toConsumableArray = createCommonjsModule(function (module) { + function _toConsumableArray(arr) { + return arrayWithoutHoles(arr) || iterableToArray(arr) || unsupportedIterableToArray(arr) || nonIterableSpread(); + } - function lookupKeyForEditor(cm, name, handle) { - for (var i = 0; i < cm.state.keyMaps.length; i++) { - var result = lookupKey(name, cm.state.keyMaps[i], handle, cm); - if (result) { return result } - } - return (cm.options.extraKeys && lookupKey(name, cm.options.extraKeys, handle, cm)) - || lookupKey(name, cm.options.keyMap, handle, cm) - } + module.exports = _toConsumableArray, module.exports.__esModule = true, module.exports["default"] = module.exports; + }); - // Note that, despite the name, this function is also used to check - // for bound mouse clicks. - - var stopSeq = new Delayed; - - function dispatchKey(cm, name, e, handle) { - var seq = cm.state.keySeq; - if (seq) { - if (isModifierKey(name)) { return "handled" } - if (/\'$/.test(name)) { cm.state.keySeq = null; } - else { - stopSeq.set(50, function () { - if (cm.state.keySeq == seq) { - cm.state.keySeq = null; - cm.display.input.reset(); - } - }); - } - if (dispatchKeyInner(cm, seq + " " + name, e, handle)) { return true } - } - return dispatchKeyInner(cm, name, e, handle) - } + var _toConsumableArray = unwrapExports(toConsumableArray); - function dispatchKeyInner(cm, name, e, handle) { - var result = lookupKeyForEditor(cm, name, handle); + var toArray = createCommonjsModule(function (module) { + function _toArray(arr) { + return arrayWithHoles(arr) || iterableToArray(arr) || unsupportedIterableToArray(arr) || nonIterableRest(); + } - if (result == "multi") { cm.state.keySeq = name; } - if (result == "handled") { signalLater(cm, "keyHandled", cm, name, e); } + module.exports = _toArray, module.exports.__esModule = true, module.exports["default"] = module.exports; + }); - if (result == "handled" || result == "multi") { - e_preventDefault(e); - restartBlink(cm); - } + var _toArray = unwrapExports(toArray); - return !!result - } + function ownKeys$2(object, enumerableOnly) { var keys = keys$3(object); if (getOwnPropertySymbols$2) { var symbols = getOwnPropertySymbols$2(object); enumerableOnly && (symbols = filter$3(symbols).call(symbols, function (sym) { return getOwnPropertyDescriptor$3(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } - // Handle a key from the keydown event. - function handleKeyBinding(cm, e) { - var name = keyName(e, true); - if (!name) { return false } - - if (e.shiftKey && !cm.state.keySeq) { - // First try to resolve full name (including 'Shift-'). Failing - // that, see if there is a cursor-motion command (starting with - // 'go') bound to the keyname without 'Shift-'. - return dispatchKey(cm, "Shift-" + name, e, function (b) { return doHandleBinding(cm, b, true); }) - || dispatchKey(cm, name, e, function (b) { - if (typeof b == "string" ? /^go[A-Z]/.test(b) : b.motion) { return doHandleBinding(cm, b) } - }) - } else { - return dispatchKey(cm, name, e, function (b) { return doHandleBinding(cm, b); }) - } - } + function _objectSpread$1(target) { for (var i = 1; i < arguments.length; i++) { var _context2, _context3; var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? forEach$3(_context2 = ownKeys$2(Object(source), !0)).call(_context2, function (key) { _defineProperty(target, key, source[key]); }) : getOwnPropertyDescriptors$2 ? defineProperties$2(target, getOwnPropertyDescriptors$2(source)) : forEach$3(_context3 = ownKeys$2(Object(source))).call(_context3, function (key) { defineProperty$5(target, key, getOwnPropertyDescriptor$3(source, key)); }); } return target; } - // Handle a key from the keypress event - function handleCharBinding(cm, e, ch) { - return dispatchKey(cm, "'" + ch + "'", e, function (b) { return doHandleBinding(cm, b, true); }) - } + /** + * Copyright (C) 2021 THL A29 Limited, a Tencent company. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ - var lastStoppedKey = null; - function onKeyDown(e) { - var cm = this; - if (e.target && e.target != cm.display.input.getField()) { return } - cm.curOp.focus = activeElt(); - if (signalDOMEvent(cm, e)) { return } - // IE does strange things with escape. - if (ie && ie_version < 11 && e.keyCode == 27) { e.returnValue = false; } - var code = e.keyCode; - cm.display.shift = code == 16 || e.shiftKey; - var handled = handleKeyBinding(cm, e); - if (presto) { - lastStoppedKey = handled ? code : null; - // Opera has no cut event... we try to at least catch the key combo - if (!handled && code == 88 && !hasCopyEvent && (mac ? e.metaKey : e.ctrlKey)) { cm.replaceSelection("", null, "cut"); } - } - if (gecko && !mac && !handled && code == 46 && e.shiftKey && !e.ctrlKey && document.execCommand) { document.execCommand("cut"); } + /** + * + * @param {string} str + * @param {{replacedText:string;begin:number;length:number;}[]} buffer + */ + function replaceStringByBuffer(str, buffer) { + if (!buffer.length) { + return str; + } - // Turn mouse into crosshair when Alt is held on Mac. - if (code == 18 && !/\bCodeMirror-crosshair\b/.test(cm.display.lineDiv.className)) { showCrossHair(cm); } - } + var slicedString = []; + var offset = 0; - function showCrossHair(cm) { - var lineDiv = cm.display.lineDiv; - addClass(lineDiv, "CodeMirror-crosshair"); + forEach$3(buffer).call(buffer, function (buf, index) { + slicedString.push(slice$7(str).call(str, offset, buf.begin)); + slicedString.push(buf.replacedText); + offset = buf.begin + buf.length; - function up(e) { - if (e.keyCode == 18 || !e.altKey) { - rmClass(lineDiv, "CodeMirror-crosshair"); - off(document, "keyup", up); - off(document, "mouseover", up); - } - } - on(document, "keyup", up); - on(document, "mouseover", up); - } + if (index === buffer.length - 1) { + slicedString.push(slice$7(str).call(str, offset)); + } + }); // console.log(slicedString, slicedString.join('')); - function onKeyUp(e) { - if (e.keyCode == 16) { this.doc.sel.shift = false; } - signalDOMEvent(this, e); - } - function onKeyPress(e) { - var cm = this; - if (e.target && e.target != cm.display.input.getField()) { return } - if (eventInWidget(cm.display, e) || signalDOMEvent(cm, e) || e.ctrlKey && !e.altKey || mac && e.metaKey) { return } - var keyCode = e.keyCode, charCode = e.charCode; - if (presto && keyCode == lastStoppedKey) { lastStoppedKey = null; e_preventDefault(e); return } - if ((presto && (!e.which || e.which < 10)) && handleKeyBinding(cm, e)) { return } - var ch = String.fromCharCode(charCode == null ? keyCode : charCode); - // Some browsers fire keypress events for backspace - if (ch == "\x08") { return } - if (handleCharBinding(cm, e, ch)) { return } - cm.display.input.onKeyPress(e); - } + return slicedString.join(''); + } + /** + * @param {string} str 原始字符串 + * @param {RegExp} regex 正则 + * @param {(...args: any[])=>string} replacer 字符串替换函数 + * @param {boolean} [continuousMatch=false] 是否连续匹配,主要用于需要后向断言的连续语法匹配 + * @param {number} [rollbackLength=1] 连续匹配时,每次指针回退的长度,默认为 1 + */ - var DOUBLECLICK_DELAY = 400; - var PastClick = function (time, pos, button) { - this.time = time; - this.pos = pos; - this.button = button; - }; + function replaceLookbehind(str, regex, replacer) { + var continuousMatch = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; + var rollbackLength = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1; - PastClick.prototype.compare = function (time, pos, button) { - return this.time + DOUBLECLICK_DELAY > time && - cmp(pos, this.pos) == 0 && button == this.button - }; + if (!regex) { + return str; + } // 从头开始匹配 - var lastClick, lastDoubleClick; - function clickRepeat(pos, button) { - var now = +new Date; - if (lastDoubleClick && lastDoubleClick.compare(now, pos, button)) { - lastClick = lastDoubleClick = null; - return "triple" - } else if (lastClick && lastClick.compare(now, pos, button)) { - lastDoubleClick = new PastClick(now, pos, button); - lastClick = null; - return "double" - } else { - lastClick = new PastClick(now, pos, button); - lastDoubleClick = null; - return "single" - } - } - // A mouse down can be a single click, double click, triple click, - // start of selection drag, start of text drag, new cursor - // (ctrl-click), rectangle drag (alt-drag), or xwin - // middle-click-paste. Or it might be a click on something we should - // not interfere with, such as a scrollbar or widget. - function onMouseDown(e) { - var cm = this, display = cm.display; - if (signalDOMEvent(cm, e) || display.activeTouch && display.input.supportsTouch()) { return } - display.input.ensurePolled(); - display.shift = e.shiftKey; - - if (eventInWidget(display, e)) { - if (!webkit) { - // Briefly turn off draggability, to allow widgets to do - // normal dragging things. - display.scroller.draggable = false; - setTimeout(function () { return display.scroller.draggable = true; }, 100); - } - return - } - if (clickInGutter(cm, e)) { return } - var pos = posFromMouse(cm, e), button = e_button(e), repeat = pos ? clickRepeat(pos, button) : "single"; - window.focus(); - - // #3261: make sure, that we're not starting a second selection - if (button == 1 && cm.state.selectingText) { cm.state.selectingText(e); } - - if (pos && handleMappedButton(cm, button, pos, repeat, e)) { return } - - if (button == 1) { - if (pos) { leftButtonDown(cm, pos, repeat, e); } - else if (e_target(e) == display.scroller) { e_preventDefault(e); } - } else if (button == 2) { - if (pos) { extendSelection(cm.doc, pos); } - setTimeout(function () { return display.input.focus(); }, 20); - } else if (button == 3) { - if (captureRightClick) { cm.display.input.onContextMenu(e); } - else { delayBlurEvent(cm); } - } - } + regex.lastIndex = 0; + var args; + var lastIndex = 0; + var replaceBuffer = []; - function handleMappedButton(cm, button, pos, repeat, event) { - var name = "Click"; - if (repeat == "double") { name = "Double" + name; } - else if (repeat == "triple") { name = "Triple" + name; } - name = (button == 1 ? "Left" : button == 2 ? "Middle" : "Right") + name; + while ((args = regex.exec(str)) !== null) { + var replaceInfo = { + begin: args.index, + length: args[0].length + }; - return dispatchKey(cm, addModifierNames(name, event), event, function (bound) { - if (typeof bound == "string") { bound = commands[bound]; } - if (!bound) { return false } - var done = false; - try { - if (cm.isReadOnly()) { cm.state.suppressEdits = true; } - done = bound(cm, pos) != Pass; - } finally { - cm.state.suppressEdits = false; - } - return done - }) - } + if (continuousMatch && args.index === lastIndex - rollbackLength) { + var _context; - function configureMouse(cm, repeat, event) { - var option = cm.getOption("configureMouse"); - var value = option ? option(cm, repeat, event) : {}; - if (value.unit == null) { - var rect = chromeOS ? event.shiftKey && event.metaKey : event.altKey; - value.unit = rect ? "rectangle" : repeat == "single" ? "char" : repeat == "double" ? "word" : "line"; - } - if (value.extend == null || cm.doc.extend) { value.extend = cm.doc.extend || event.shiftKey; } - if (value.addNew == null) { value.addNew = mac ? event.metaKey : event.ctrlKey; } - if (value.moveOnDrag == null) { value.moveOnDrag = !(mac ? event.altKey : event.ctrlKey); } - return value - } + var _args = args, + _args2 = _toArray(_args), + match = _args2[0], + restArgs = slice$7(_args2).call(_args2, 2); // 丢弃 leadingChar,需要调整begin和length - function leftButtonDown(cm, pos, repeat, event) { - if (ie) { setTimeout(bind(ensureFocus, cm), 0); } - else { cm.curOp.focus = activeElt(); } - var behavior = configureMouse(cm, repeat, event); + replaceBuffer.push({ + begin: replaceInfo.begin + rollbackLength, + length: replaceInfo.length - rollbackLength, + replacedText: replacer.apply(void 0, concat$5(_context = [slice$7(match).call(match, rollbackLength), '']).call(_context, _toConsumableArray(restArgs))) + }); + } else { + replaceBuffer.push(_objectSpread$1(_objectSpread$1({}, replaceInfo), {}, { + replacedText: replacer.apply(void 0, _toConsumableArray(args)) + })); + } // console.log(args); - var sel = cm.doc.sel, contained; - if (cm.options.dragDrop && dragAndDrop && !cm.isReadOnly() && - repeat == "single" && (contained = sel.contains(pos)) > -1 && - (cmp((contained = sel.ranges[contained]).from(), pos) < 0 || pos.xRel > 0) && - (cmp(contained.to(), pos) > 0 || pos.xRel < 0)) { leftButtonStartDrag(cm, event, pos, behavior); } - else { leftButtonSelect(cm, event, pos, behavior); } - } - // Start a text drag. When it ends, see if any dragging actually - // happen, and treat as a click if it didn't. - function leftButtonStartDrag(cm, event, pos, behavior) { - var display = cm.display, moved = false; - var dragEnd = operation(cm, function (e) { - if (webkit) { display.scroller.draggable = false; } - cm.state.draggingText = false; - off(display.wrapper.ownerDocument, "mouseup", dragEnd); - off(display.wrapper.ownerDocument, "mousemove", mouseMove); - off(display.scroller, "dragstart", dragStart); - off(display.scroller, "drop", dragEnd); - if (!moved) { - e_preventDefault(e); - if (!behavior.addNew) { extendSelection(cm.doc, pos, null, null, behavior.extend); } - // Work around unexplainable focus problem in IE9 (#2127) and Chrome (#3081) - if ((webkit && !safari) || ie && ie_version == 9) { setTimeout(function () { display.wrapper.ownerDocument.body.focus({ preventScroll: true }); display.input.focus(); }, 20); } - else { display.input.focus(); } - } - }); - var mouseMove = function (e2) { - moved = moved || Math.abs(event.clientX - e2.clientX) + Math.abs(event.clientY - e2.clientY) >= 10; - }; - var dragStart = function () { return moved = true; }; - // Let the drag handler handle this. - if (webkit) { display.scroller.draggable = true; } - cm.state.draggingText = dragEnd; - dragEnd.copy = !behavior.moveOnDrag; - // IE's approach to draggable - if (display.scroller.dragDrop) { display.scroller.dragDrop(); } - on(display.wrapper.ownerDocument, "mouseup", dragEnd); - on(display.wrapper.ownerDocument, "mousemove", mouseMove); - on(display.scroller, "dragstart", dragStart); - on(display.scroller, "drop", dragEnd); - - delayBlurEvent(cm); - setTimeout(function () { return display.input.focus(); }, 20); - } + lastIndex = regex.lastIndex; + regex.lastIndex -= rollbackLength; + } // 正则复位,避免影响其他逻辑 - function rangeForUnit(cm, pos, unit) { - if (unit == "char") { return new Range(pos, pos) } - if (unit == "word") { return cm.findWordAt(pos) } - if (unit == "line") { return new Range(Pos(pos.line, 0), clipPos(cm.doc, Pos(pos.line + 1, 0))) } - var result = unit(cm, pos); - return new Range(result.from, result.to) - } - // Normal selection, as opposed to text dragging. - function leftButtonSelect(cm, event, start, behavior) { - var display = cm.display, doc = cm.doc; - e_preventDefault(event); + regex.lastIndex = 0; + return replaceStringByBuffer(str, replaceBuffer); + } - var ourRange, ourIndex, startSel = doc.sel, ranges = startSel.ranges; - if (behavior.addNew && !behavior.extend) { - ourIndex = doc.sel.contains(start); - if (ourIndex > -1) { ourRange = ranges[ourIndex]; } - else { ourRange = new Range(start, start); } - } else { - ourRange = doc.sel.primary(); - ourIndex = doc.sel.primIndex; - } + function _createSuper$2(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$2(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = construct$4(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } - if (behavior.unit == "rectangle") { - if (!behavior.addNew) { ourRange = new Range(start, start); } - start = posFromMouse(cm, event, true, true); - ourIndex = -1; - } else { - var range = rangeForUnit(cm, start, behavior.unit); - if (behavior.extend) { ourRange = extendRange(ourRange, range.anchor, range.head, behavior.extend); } - else { ourRange = range; } - } + function _isNativeReflectConstruct$2() { if (typeof Reflect === "undefined" || !construct$4) return false; if (construct$4.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(construct$4(Boolean, [], function () {})); return true; } catch (e) { return false; } } - if (!behavior.addNew) { - ourIndex = 0; - setSelection(doc, new Selection([ourRange], 0), sel_mouse); - startSel = doc.sel; - } else if (ourIndex == -1) { - ourIndex = ranges.length; - setSelection(doc, normalizeSelection(cm, ranges.concat([ourRange]), ourIndex), - { scroll: false, origin: "*mouse" }); - } else if (ranges.length > 1 && ranges[ourIndex].empty() && behavior.unit == "char" && !behavior.extend) { - setSelection(doc, normalizeSelection(cm, ranges.slice(0, ourIndex).concat(ranges.slice(ourIndex + 1)), 0), - { scroll: false, origin: "*mouse" }); - startSel = doc.sel; - } else { - replaceOneSelection(doc, ourIndex, ourRange, sel_mouse); - } + var Color = /*#__PURE__*/function (_SyntaxBase) { + _inherits(Color, _SyntaxBase); + + var _super = _createSuper$2(Color); + + function Color() { + _classCallCheck(this, Color); + + return _super.apply(this, arguments); + } + + _createClass(Color, [{ + key: "toHtml", + value: // constructor() { + // super(); + // } + function toHtml(whole, leadingChar, m1, m2) { + var _context, _context2; + + return concat$5(_context = concat$5(_context2 = "".concat(leadingChar, "")).call(_context, m2, ""); + } + }, { + key: "makeHtml", + value: function makeHtml(str) { + if (isLookbehindSupported()) { + return str.replace(this.RULE.reg, this.toHtml); + } + + return replaceLookbehind(str, this.RULE.reg, this.toHtml, true, 1); + } + }, { + key: "rule", + value: function rule() { + var ret = { + begin: isLookbehindSupported() ? '((? leftPos) { ranges.push(new Range(Pos(line, leftPos), Pos(line, findColumn(text, right, tabSize)))); } - } - if (!ranges.length) { ranges.push(new Range(start, start)); } - setSelection(doc, normalizeSelection(cm, startSel.ranges.slice(0, ourIndex).concat(ranges), ourIndex), - { origin: "*mouse", scroll: false }); - cm.scrollIntoView(pos); - } else { - var oldRange = ourRange; - var range = rangeForUnit(cm, pos, behavior.unit); - var anchor = oldRange.anchor, head; - if (cmp(range.anchor, anchor) > 0) { - head = range.head; - anchor = minPos(oldRange.from(), range.anchor); - } else { - head = range.anchor; - anchor = maxPos(oldRange.to(), range.head); - } - var ranges$1 = startSel.ranges.slice(0); - ranges$1[ourIndex] = bidiSimplify(cm, new Range(clipPos(doc, anchor), head)); - setSelection(doc, normalizeSelection(cm, ranges$1, ourIndex), sel_mouse); - } - } + _defineProperty(Color, "HOOK_NAME", 'fontColor'); - var editorSize = display.wrapper.getBoundingClientRect(); - // Used to ensure timeout re-tries don't fire when another extend - // happened in the meantime (clearTimeout isn't reliable -- at - // least on Chrome, the timeouts still happen even when cleared, - // if the clear happens after their scheduled firing time). - var counter = 0; - - function extend(e) { - var curCount = ++counter; - var cur = posFromMouse(cm, e, true, behavior.unit == "rectangle"); - if (!cur) { return } - if (cmp(cur, lastPos) != 0) { - cm.curOp.focus = activeElt(); - extendTo(cur); - var visible = visibleLines(display, doc); - if (cur.line >= visible.to || cur.line < visible.from) { setTimeout(operation(cm, function () { if (counter == curCount) { extend(e); } }), 150); } - } else { - var outside = e.clientY < editorSize.top ? -20 : e.clientY > editorSize.bottom ? 20 : 0; - if (outside) { - setTimeout(operation(cm, function () { - if (counter != curCount) { return } - display.scroller.scrollTop += outside; - extend(e); - }), 50); - } - } - } + function _createSuper$3(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$3(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = construct$4(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } - function done(e) { - cm.state.selectingText = false; - counter = Infinity; - // If e is null or undefined we interpret this as someone trying - // to explicitly cancel the selection rather than the user - // letting go of the mouse button. - if (e) { - e_preventDefault(e); - display.input.focus(); - } - off(display.wrapper.ownerDocument, "mousemove", move); - off(display.wrapper.ownerDocument, "mouseup", up); - doc.history.lastSelOrigin = null; - } + function _isNativeReflectConstruct$3() { if (typeof Reflect === "undefined" || !construct$4) return false; if (construct$4.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(construct$4(Boolean, [], function () {})); return true; } catch (e) { return false; } } - var move = operation(cm, function (e) { - if (e.buttons === 0 || !e_button(e)) { done(e); } - else { extend(e); } - }); - var up = operation(cm, done); - cm.state.selectingText = up; - on(display.wrapper.ownerDocument, "mousemove", move); - on(display.wrapper.ownerDocument, "mouseup", up); - } + var BackgroundColor = /*#__PURE__*/function (_SyntaxBase) { + _inherits(BackgroundColor, _SyntaxBase); + + var _super = _createSuper$3(BackgroundColor); + + function BackgroundColor() { + _classCallCheck(this, BackgroundColor); + + return _super.apply(this, arguments); + } + + _createClass(BackgroundColor, [{ + key: "toHtml", + value: // constructor() { + // super(); + // } + function toHtml(whole, leadingChar, m1, m2) { + var _context, _context2; + + return concat$5(_context = concat$5(_context2 = "".concat(leadingChar, "")).call(_context, m2, ""); + } + }, { + key: "makeHtml", + value: function makeHtml(str) { + if (isLookbehindSupported()) { + return str.replace(this.RULE.reg, this.toHtml); + } + + return replaceLookbehind(str, this.RULE.reg, this.toHtml, true, 1); + } + }, { + key: "rule", + value: function rule() { + var ret = { + begin: isLookbehindSupported() ? '((?0 to the right) - var leftSide; - if (head.line != anchor.line) { - leftSide = (head.line - anchor.line) * (cm.doc.direction == "ltr" ? 1 : -1) > 0; - } else { - var headIndex = getBidiPartAt(order, head.ch, head.sticky); - var dir = headIndex - index || (head.ch - anchor.ch) * (part.level == 1 ? -1 : 1); - if (headIndex == boundary - 1 || headIndex == boundary) { leftSide = dir < 0; } - else { leftSide = dir > 0; } - } + _defineProperty(BackgroundColor, "HOOK_NAME", 'bgColor'); - var usePart = order[boundary + (leftSide ? -1 : 0)]; - var from = leftSide == (usePart.level == 1); - var ch = from ? usePart.from : usePart.to, sticky = from ? "after" : "before"; - return anchor.ch == ch && anchor.sticky == sticky ? range : new Range(new Pos(anchor.line, ch, sticky), head) - } + function _createSuper$4(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$4(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = construct$4(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } + function _isNativeReflectConstruct$4() { if (typeof Reflect === "undefined" || !construct$4) return false; if (construct$4.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(construct$4(Boolean, [], function () {})); return true; } catch (e) { return false; } } - // Determines whether an event happened in the gutter, and fires the - // handlers for the corresponding event. - function gutterEvent(cm, e, type, prevent) { - var mX, mY; - if (e.touches) { - mX = e.touches[0].clientX; - mY = e.touches[0].clientY; - } else { - try { mX = e.clientX; mY = e.clientY; } - catch (e$1) { return false } - } - if (mX >= Math.floor(cm.display.gutters.getBoundingClientRect().right)) { return false } - if (prevent) { e_preventDefault(e); } - - var display = cm.display; - var lineBox = display.lineDiv.getBoundingClientRect(); - - if (mY > lineBox.bottom || !hasHandler(cm, type)) { return e_defaultPrevented(e) } - mY -= lineBox.top - display.viewOffset; - - for (var i = 0; i < cm.display.gutterSpecs.length; ++i) { - var g = display.gutters.childNodes[i]; - if (g && g.getBoundingClientRect().right >= mX) { - var line = lineAtHeight(cm.doc, mY); - var gutter = cm.display.gutterSpecs[i]; - signal(cm, type, cm, line, gutter.className, e); - return e_defaultPrevented(e) - } - } - } + var Size = /*#__PURE__*/function (_SyntaxBase) { + _inherits(Size, _SyntaxBase); + + var _super = _createSuper$4(Size); + + function Size() { + _classCallCheck(this, Size); + + return _super.apply(this, arguments); + } + + _createClass(Size, [{ + key: "toHtml", + value: // constructor() { + // super(); + // } + function toHtml(whole, m1, m2, m3) { + var _context, _context2; + + return concat$5(_context = concat$5(_context2 = "".concat(m1, "")).call(_context, m3, ""); + } + }, { + key: "makeHtml", + value: function makeHtml(str) { + if (!this.test(str)) { + return str; + } + + if (isLookbehindSupported()) { + return str.replace(this.RULE.reg, this.toHtml); + } + + return replaceLookbehind(str, this.RULE.reg, this.toHtml, true, 1); + } + }, { + key: "rule", + value: function rule() { + var ret = { + begin: isLookbehindSupported() ? '((? 0 && arguments[0] !== undefined ? arguments[0] : { + config: undefined + }, + config = _ref.config; + + _classCallCheck(this, Strikethrough); + + _this = _super.call(this, { + config: config + }); + + if (!config) { + return _possibleConstructorReturn(_this); + } + + _this.needWhitespace = !!config.needWhitespace; + return _this; + } + /** + * 主要逻辑 + * @param {string} str markdown源码 + * @returns {string} html内容 + */ + + + _createClass(Strikethrough, [{ + key: "makeHtml", + value: function makeHtml(str) { + if (!this.test(str)) { + return str; + } + + return str.replace(this.RULE.reg, '$1$2'); + } + }, { + key: "rule", + value: function rule() { + var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : { + config: undefined + }, + config = _ref2.config; + + /** @type {Partial} */ + var ret = {}; + + if (!!config.needWhitespace) { + ret = { + begin: '(^|[\\s])\\~T\\~T', + end: '\\~T\\~T(?=\\s|$)', + content: '([\\w\\W]+?)' + }; + } else { + ret = { + begin: '(^|[^\\\\])\\~T\\~T', + end: '\\~T\\~T', + content: '([\\w\\W]+?)' + }; + } + + ret.reg = new RegExp(ret.begin + ret.content + ret.end, 'g'); + return ret; + } + }]); + + return Strikethrough; + }(SyntaxBase); - function themeChanged(cm) { - cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-s-\S+/g, "") + - cm.options.theme.replace(/(^|\s)\s*/g, " cm-s-"); - clearCaches(cm); - } - - var Init = { toString: function () { return "CodeMirror.Init" } }; - - var defaults = {}; - var optionHandlers = {}; + _defineProperty(Strikethrough, "HOOK_NAME", 'strikethrough'); - function defineOptions(CodeMirror) { - var optionHandlers = CodeMirror.optionHandlers; + function _createSuper$6(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$6(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = construct$4(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } - function option(name, deflt, handle, notOnInit) { - CodeMirror.defaults[name] = deflt; - if (handle) { - optionHandlers[name] = - notOnInit ? function (cm, val, old) { if (old != Init) { handle(cm, val, old); } } : handle; - } - } + function _isNativeReflectConstruct$6() { if (typeof Reflect === "undefined" || !construct$4) return false; if (construct$4.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(construct$4(Boolean, [], function () {})); return true; } catch (e) { return false; } } - CodeMirror.defineOption = option; - - // Passed to option handlers when there is no old value. - CodeMirror.Init = Init; - - // These two are, on init, called from the constructor because they - // have to be initialized before the editor can start at all. - option("value", "", function (cm, val) { return cm.setValue(val); }, true); - option("mode", null, function (cm, val) { - cm.doc.modeOption = val; - loadMode(cm); - }, true); - - option("indentUnit", 2, loadMode, true); - option("indentWithTabs", false); - option("smartIndent", true); - option("tabSize", 4, function (cm) { - resetModeState(cm); - clearCaches(cm); - regChange(cm); - }, true); - - option("lineSeparator", null, function (cm, val) { - cm.doc.lineSep = val; - if (!val) { return } - var newBreaks = [], lineNo = cm.doc.first; - cm.doc.iter(function (line) { - for (var pos = 0; ;) { - var found = line.text.indexOf(val, pos); - if (found == -1) { break } - pos = found + val.length; - newBreaks.push(Pos(lineNo, found)); - } - lineNo++; - }); - for (var i = newBreaks.length - 1; i >= 0; i--) { replaceRange(cm.doc, val, newBreaks[i], Pos(newBreaks[i].line, newBreaks[i].ch + val.length)); } - }); - option("specialChars", /[\u0000-\u001f\u007f-\u009f\u00ad\u061c\u200b-\u200c\u200e\u200f\u2028\u2029\ufeff\ufff9-\ufffc]/g, function (cm, val, old) { - cm.state.specialChars = new RegExp(val.source + (val.test("\t") ? "" : "|\t"), "g"); - if (old != Init) { cm.refresh(); } - }); - option("specialCharPlaceholder", defaultSpecialCharPlaceholder, function (cm) { return cm.refresh(); }, true); - option("electricChars", true); - option("inputStyle", mobile ? "contenteditable" : "textarea", function () { - throw new Error("inputStyle can not (yet) be changed in a running editor") // FIXME - }, true); - option("spellcheck", false, function (cm, val) { return cm.getInputField().spellcheck = val; }, true); - option("autocorrect", false, function (cm, val) { return cm.getInputField().autocorrect = val; }, true); - option("autocapitalize", false, function (cm, val) { return cm.getInputField().autocapitalize = val; }, true); - option("rtlMoveVisually", !windows); - option("wholeLineUpdateBefore", true); - - option("theme", "default", function (cm) { - themeChanged(cm); - updateGutters(cm); - }, true); - option("keyMap", "default", function (cm, val, old) { - var next = getKeyMap(val); - var prev = old != Init && getKeyMap(old); - if (prev && prev.detach) { prev.detach(cm, next); } - if (next.attach) { next.attach(cm, prev || null); } - }); - option("extraKeys", null); - option("configureMouse", null); - - option("lineWrapping", false, wrappingChanged, true); - option("gutters", [], function (cm, val) { - cm.display.gutterSpecs = getGutters(val, cm.options.lineNumbers); - updateGutters(cm); - }, true); - option("fixedGutter", true, function (cm, val) { - cm.display.gutters.style.left = val ? compensateForHScroll(cm.display) + "px" : "0"; - cm.refresh(); - }, true); - option("coverGutterNextToScrollbar", false, function (cm) { return updateScrollbars(cm); }, true); - option("scrollbarStyle", "native", function (cm) { - initScrollbars(cm); - updateScrollbars(cm); - cm.display.scrollbars.setScrollTop(cm.doc.scrollTop); - cm.display.scrollbars.setScrollLeft(cm.doc.scrollLeft); - }, true); - option("lineNumbers", false, function (cm, val) { - cm.display.gutterSpecs = getGutters(cm.options.gutters, val); - updateGutters(cm); - }, true); - option("firstLineNumber", 1, updateGutters, true); - option("lineNumberFormatter", function (integer) { return integer; }, updateGutters, true); - option("showCursorWhenSelecting", false, updateSelection, true); - - option("resetSelectionOnContextMenu", true); - option("lineWiseCopyCut", true); - option("pasteLinesPerSelection", true); - option("selectionsMayTouch", false); - - option("readOnly", false, function (cm, val) { - if (val == "nocursor") { - onBlur(cm); - cm.display.input.blur(); - } - cm.display.input.readOnlyChanged(val); - }); + var Sup = /*#__PURE__*/function (_SyntaxBase) { + _inherits(Sup, _SyntaxBase); + + var _super = _createSuper$6(Sup); + + function Sup() { + _classCallCheck(this, Sup); + + return _super.apply(this, arguments); + } + + _createClass(Sup, [{ + key: "toHtml", + value: // constructor() { + // super(); + // } + function toHtml(whole, leadingChar, m1) { + var _context; + + return concat$5(_context = "".concat(leadingChar, "")).call(_context, m1, ""); + } + }, { + key: "makeHtml", + value: function makeHtml(str) { + if (isLookbehindSupported()) { + return str.replace(this.RULE.reg, this.toHtml); + } + + return replaceLookbehind(str, this.RULE.reg, this.toHtml, true, 1); + } + }, { + key: "rule", + value: function rule() { + var ret = { + begin: isLookbehindSupported() ? '((?")).call(_context, m1, ""); + } + }, { + key: "makeHtml", + value: function makeHtml(str) { + if (isLookbehindSupported()) { + return str.replace(this.RULE.reg, this.toHtml); + } + + return replaceLookbehind(str, this.RULE.reg, this.toHtml, true, 1); + } + }, { + key: "rule", + value: function rule() { + var ret = { + begin: isLookbehindSupported() ? '((? + + var _self = (typeof window !== 'undefined') + ? window // if in browser + : ( + (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) + ? self // if in worker + : {} // if in node js + ); - if (options.autofocus && !mobile) { display.input.focus(); } + /** + * Prism: Lightweight, robust, elegant syntax highlighting + * + * @license MIT + * @author Lea Verou + * @namespace + * @public + */ + var Prism = (function (_self) { - // Override magic textarea content restore that IE sometimes does - // on our hidden textarea on reload - if (ie && ie_version < 11) { setTimeout(function () { return this$1.display.input.reset(true); }, 20); } + // Private helper vars + var lang = /(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i; + var uniqueId = 0; - registerEventHandlers(this); - ensureGlobalHandlers(); + // The grammar object for plaintext + var plainTextGrammar = {}; - startOperation(this); - this.curOp.forceUpdate = true; - attachDoc(this, doc); - if ((options.autofocus && !mobile) || this.hasFocus()) { - setTimeout(function () { - if (this$1.hasFocus() && !this$1.state.focused) { onFocus(this$1); } - }, 20); - } - else { onBlur(this); } + var _ = { + /** + * By default, Prism will attempt to highlight all code elements (by calling {@link Prism.highlightAll}) on the + * current page after the page finished loading. This might be a problem if e.g. you wanted to asynchronously load + * additional languages or plugins yourself. + * + * By setting this value to `true`, Prism will not automatically highlight all code elements on the page. + * + * You obviously have to change this value before the automatic highlighting started. To do this, you can add an + * empty Prism object into the global scope before loading the Prism script like this: + * + * ```js + * window.Prism = window.Prism || {}; + * Prism.manual = true; + * // add a new `. - this.sequenceIndex = Number(c === CharCodes.Lt); - } - } - stateCDATASequence(c) { - if (c === Sequences.Cdata[this.sequenceIndex]) { - if (++this.sequenceIndex === Sequences.Cdata.length) { - this.state = State$2.InCommentLike; - this.currentSequence = Sequences.CdataEnd; - this.sequenceIndex = 0; - this.sectionStart = this.index + 1; - } - } - else { - this.sequenceIndex = 0; - this.state = State$2.InDeclaration; - this.stateInDeclaration(c); // Reconsume the character - } - } - /** - * When we wait for one specific character, we can speed things up - * by skipping through the buffer until we find it. - * - * @returns Whether the character was found. - */ - fastForwardTo(c) { - while (++this.index < this.buffer.length + this.offset) { - if (this.buffer.charCodeAt(this.index - this.offset) === c) { - return true; - } - } - /* - * We increment the index at the end of the `parse` loop, - * so set it to `buffer.length - 1` here. - * - * TODO: Refactor `parse` to increment index before calling states. - */ - this.index = this.buffer.length + this.offset - 1; - return false; - } - /** - * Comments and CDATA end with `-->` and `]]>`. - * - * Their common qualities are: - * - Their end sequences have a distinct character they start with. - * - That character is then repeated, so we have to check multiple repeats. - * - All characters but the start character of the sequence can be skipped. - */ - stateInCommentLike(c) { - if (c === this.currentSequence[this.sequenceIndex]) { - if (++this.sequenceIndex === this.currentSequence.length) { - if (this.currentSequence === Sequences.CdataEnd) { - this.cbs.oncdata(this.sectionStart, this.index, 2); - } - else { - this.cbs.oncomment(this.sectionStart, this.index, 2); - } - this.sequenceIndex = 0; - this.sectionStart = this.index + 1; - this.state = State$2.Text; - } - } - else if (this.sequenceIndex === 0) { - // Fast-forward to the first character of the sequence - if (this.fastForwardTo(this.currentSequence[0])) { - this.sequenceIndex = 1; - } - } - else if (c !== this.currentSequence[this.sequenceIndex - 1]) { - // Allow long sequences, eg. --->, ]]]> - this.sequenceIndex = 0; - } - } - /** - * HTML only allows ASCII alpha characters (a-z and A-Z) at the beginning of a tag name. - * - * XML allows a lot more characters here (@see https://www.w3.org/TR/REC-xml/#NT-NameStartChar). - * We allow anything that wouldn't end the tag. - */ - isTagStartChar(c) { - return this.xmlMode ? !isEndOfTagSection(c) : isASCIIAlpha(c); - } - startSpecial(sequence, offset) { - this.isSpecial = true; - this.currentSequence = sequence; - this.sequenceIndex = offset; - this.state = State$2.SpecialStartSequence; - } - stateBeforeTagName(c) { - if (c === CharCodes.ExclamationMark) { - this.state = State$2.BeforeDeclaration; - this.sectionStart = this.index + 1; - } - else if (c === CharCodes.Questionmark) { - this.state = State$2.InProcessingInstruction; - this.sectionStart = this.index + 1; - } - else if (this.isTagStartChar(c)) { - const lower = c | 0x20; - this.sectionStart = this.index; - if (!this.xmlMode && lower === Sequences.TitleEnd[2]) { - this.startSpecial(Sequences.TitleEnd, 3); - } - else { - this.state = - !this.xmlMode && lower === Sequences.ScriptEnd[2] - ? State$2.BeforeSpecialS - : State$2.InTagName; - } - } - else if (c === CharCodes.Slash) { - this.state = State$2.BeforeClosingTagName; - } - else { - this.state = State$2.Text; - this.stateText(c); - } - } - stateInTagName(c) { - if (isEndOfTagSection(c)) { - this.cbs.onopentagname(this.sectionStart, this.index); - this.sectionStart = -1; - this.state = State$2.BeforeAttributeName; - this.stateBeforeAttributeName(c); - } - } - stateBeforeClosingTagName(c) { - if (isWhitespace$2(c)); - else if (c === CharCodes.Gt) { - this.state = State$2.Text; - } - else { - this.state = this.isTagStartChar(c) - ? State$2.InClosingTagName - : State$2.InSpecialComment; - this.sectionStart = this.index; - } - } - stateInClosingTagName(c) { - if (c === CharCodes.Gt || isWhitespace$2(c)) { - this.cbs.onclosetag(this.sectionStart, this.index); - this.sectionStart = -1; - this.state = State$2.AfterClosingTagName; - this.stateAfterClosingTagName(c); - } - } - stateAfterClosingTagName(c) { - // Skip everything until ">" - if (c === CharCodes.Gt || this.fastForwardTo(CharCodes.Gt)) { - this.state = State$2.Text; - this.sectionStart = this.index + 1; - } - } - stateBeforeAttributeName(c) { - if (c === CharCodes.Gt) { - this.cbs.onopentagend(this.index); - if (this.isSpecial) { - this.state = State$2.InSpecialTag; - this.sequenceIndex = 0; - } - else { - this.state = State$2.Text; - } - this.baseState = this.state; - this.sectionStart = this.index + 1; - } - else if (c === CharCodes.Slash) { - this.state = State$2.InSelfClosingTag; - } - else if (!isWhitespace$2(c)) { - this.state = State$2.InAttributeName; - this.sectionStart = this.index; - } - } - stateInSelfClosingTag(c) { - if (c === CharCodes.Gt) { - this.cbs.onselfclosingtag(this.index); - this.state = State$2.Text; - this.baseState = State$2.Text; - this.sectionStart = this.index + 1; - this.isSpecial = false; // Reset special state, in case of self-closing special tags - } - else if (!isWhitespace$2(c)) { - this.state = State$2.BeforeAttributeName; - this.stateBeforeAttributeName(c); - } - } - stateInAttributeName(c) { - if (c === CharCodes.Eq || isEndOfTagSection(c)) { - this.cbs.onattribname(this.sectionStart, this.index); - this.sectionStart = -1; - this.state = State$2.AfterAttributeName; - this.stateAfterAttributeName(c); - } - } - stateAfterAttributeName(c) { - if (c === CharCodes.Eq) { - this.state = State$2.BeforeAttributeValue; - } - else if (c === CharCodes.Slash || c === CharCodes.Gt) { - this.cbs.onattribend(QuoteType.NoValue, this.index); - this.state = State$2.BeforeAttributeName; - this.stateBeforeAttributeName(c); - } - else if (!isWhitespace$2(c)) { - this.cbs.onattribend(QuoteType.NoValue, this.index); - this.state = State$2.InAttributeName; - this.sectionStart = this.index; - } - } - stateBeforeAttributeValue(c) { - if (c === CharCodes.DoubleQuote) { - this.state = State$2.InAttributeValueDq; - this.sectionStart = this.index + 1; - } - else if (c === CharCodes.SingleQuote) { - this.state = State$2.InAttributeValueSq; - this.sectionStart = this.index + 1; - } - else if (!isWhitespace$2(c)) { - this.sectionStart = this.index; - this.state = State$2.InAttributeValueNq; - this.stateInAttributeValueNoQuotes(c); // Reconsume token - } - } - handleInAttributeValue(c, quote) { - if (c === quote || - (!this.decodeEntities && this.fastForwardTo(quote))) { - this.cbs.onattribdata(this.sectionStart, this.index); - this.sectionStart = -1; - this.cbs.onattribend(quote === CharCodes.DoubleQuote - ? QuoteType.Double - : QuoteType.Single, this.index); - this.state = State$2.BeforeAttributeName; - } - else if (this.decodeEntities && c === CharCodes.Amp) { - this.baseState = this.state; - this.state = State$2.BeforeEntity; - } - } - stateInAttributeValueDoubleQuotes(c) { - this.handleInAttributeValue(c, CharCodes.DoubleQuote); - } - stateInAttributeValueSingleQuotes(c) { - this.handleInAttributeValue(c, CharCodes.SingleQuote); - } - stateInAttributeValueNoQuotes(c) { - if (isWhitespace$2(c) || c === CharCodes.Gt) { - this.cbs.onattribdata(this.sectionStart, this.index); - this.sectionStart = -1; - this.cbs.onattribend(QuoteType.Unquoted, this.index); - this.state = State$2.BeforeAttributeName; - this.stateBeforeAttributeName(c); - } - else if (this.decodeEntities && c === CharCodes.Amp) { - this.baseState = this.state; - this.state = State$2.BeforeEntity; - } - } - stateBeforeDeclaration(c) { - if (c === CharCodes.OpeningSquareBracket) { - this.state = State$2.CDATASequence; - this.sequenceIndex = 0; - } - else { - this.state = - c === CharCodes.Dash - ? State$2.BeforeComment - : State$2.InDeclaration; - } - } - stateInDeclaration(c) { - if (c === CharCodes.Gt || this.fastForwardTo(CharCodes.Gt)) { - this.cbs.ondeclaration(this.sectionStart, this.index); - this.state = State$2.Text; - this.sectionStart = this.index + 1; - } - } - stateInProcessingInstruction(c) { - if (c === CharCodes.Gt || this.fastForwardTo(CharCodes.Gt)) { - this.cbs.onprocessinginstruction(this.sectionStart, this.index); - this.state = State$2.Text; - this.sectionStart = this.index + 1; - } - } - stateBeforeComment(c) { - if (c === CharCodes.Dash) { - this.state = State$2.InCommentLike; - this.currentSequence = Sequences.CommentEnd; - // Allow short comments (eg. ) - this.sequenceIndex = 2; - this.sectionStart = this.index + 1; - } - else { - this.state = State$2.InDeclaration; - } - } - stateInSpecialComment(c) { - if (c === CharCodes.Gt || this.fastForwardTo(CharCodes.Gt)) { - this.cbs.oncomment(this.sectionStart, this.index, 0); - this.state = State$2.Text; - this.sectionStart = this.index + 1; - } - } - stateBeforeSpecialS(c) { - const lower = c | 0x20; - if (lower === Sequences.ScriptEnd[3]) { - this.startSpecial(Sequences.ScriptEnd, 4); - } - else if (lower === Sequences.StyleEnd[3]) { - this.startSpecial(Sequences.StyleEnd, 4); - } - else { - this.state = State$2.InTagName; - this.stateInTagName(c); // Consume the token again - } - } - stateBeforeEntity(c) { - // Start excess with 1 to include the '&' - this.entityExcess = 1; - this.entityResult = 0; - if (c === CharCodes.Num) { - this.state = State$2.BeforeNumericEntity; - } - else if (c === CharCodes.Amp); - else { - this.trieIndex = 0; - this.trieCurrent = this.entityTrie[0]; - this.state = State$2.InNamedEntity; - this.stateInNamedEntity(c); - } - } - stateInNamedEntity(c) { - this.entityExcess += 1; - this.trieIndex = decode_4(this.entityTrie, this.trieCurrent, this.trieIndex + 1, c); - if (this.trieIndex < 0) { - this.emitNamedEntity(); - this.index--; - return; - } - this.trieCurrent = this.entityTrie[this.trieIndex]; - const masked = this.trieCurrent & decode_5.VALUE_LENGTH; - // If the branch is a value, store it and continue - if (masked) { - // The mask is the number of bytes of the value, including the current byte. - const valueLength = (masked >> 14) - 1; - // If we have a legacy entity while parsing strictly, just skip the number of bytes - if (!this.allowLegacyEntity() && c !== CharCodes.Semi) { - this.trieIndex += valueLength; - } - else { - // Add 1 as we have already incremented the excess - const entityStart = this.index - this.entityExcess + 1; - if (entityStart > this.sectionStart) { - this.emitPartial(this.sectionStart, entityStart); - } - // If this is a surrogate pair, consume the next two bytes - this.entityResult = this.trieIndex; - this.trieIndex += valueLength; - this.entityExcess = 0; - this.sectionStart = this.index + 1; - if (valueLength === 0) { - this.emitNamedEntity(); - } - } - } - } - emitNamedEntity() { - this.state = this.baseState; - if (this.entityResult === 0) { - return; - } - const valueLength = (this.entityTrie[this.entityResult] & decode_5.VALUE_LENGTH) >> - 14; - switch (valueLength) { - case 1: - this.emitCodePoint(this.entityTrie[this.entityResult] & - ~decode_5.VALUE_LENGTH); - break; - case 2: - this.emitCodePoint(this.entityTrie[this.entityResult + 1]); - break; - case 3: { - this.emitCodePoint(this.entityTrie[this.entityResult + 1]); - this.emitCodePoint(this.entityTrie[this.entityResult + 2]); - } - } - } - stateBeforeNumericEntity(c) { - if ((c | 0x20) === CharCodes.LowerX) { - this.entityExcess++; - this.state = State$2.InHexEntity; - } - else { - this.state = State$2.InNumericEntity; - this.stateInNumericEntity(c); - } - } - emitNumericEntity(strict) { - const entityStart = this.index - this.entityExcess - 1; - const numberStart = entityStart + 2 + Number(this.state === State$2.InHexEntity); - if (numberStart !== this.index) { - // Emit leading data if any - if (entityStart > this.sectionStart) { - this.emitPartial(this.sectionStart, entityStart); - } - this.sectionStart = this.index + Number(strict); - this.emitCodePoint(decode_7(this.entityResult)); - } - this.state = this.baseState; - } - stateInNumericEntity(c) { - if (c === CharCodes.Semi) { - this.emitNumericEntity(true); - } - else if (isNumber(c)) { - this.entityResult = this.entityResult * 10 + (c - CharCodes.Zero); - this.entityExcess++; - } - else { - if (this.allowLegacyEntity()) { - this.emitNumericEntity(false); - } - else { - this.state = this.baseState; - } - this.index--; - } - } - stateInHexEntity(c) { - if (c === CharCodes.Semi) { - this.emitNumericEntity(true); - } - else if (isNumber(c)) { - this.entityResult = this.entityResult * 16 + (c - CharCodes.Zero); - this.entityExcess++; - } - else if (isHexDigit(c)) { - this.entityResult = - this.entityResult * 16 + ((c | 0x20) - CharCodes.LowerA + 10); - this.entityExcess++; - } - else { - if (this.allowLegacyEntity()) { - this.emitNumericEntity(false); - } - else { - this.state = this.baseState; - } - this.index--; - } - } - allowLegacyEntity() { - return (!this.xmlMode && - (this.baseState === State$2.Text || - this.baseState === State$2.InSpecialTag)); - } - /** - * Remove data that has already been consumed from the buffer. - */ - cleanup() { - // If we are inside of text or attributes, emit what we already have. - if (this.running && this.sectionStart !== this.index) { - if (this.state === State$2.Text || - (this.state === State$2.InSpecialTag && this.sequenceIndex === 0)) { - this.cbs.ontext(this.sectionStart, this.index); - this.sectionStart = this.index; - } - else if (this.state === State$2.InAttributeValueDq || - this.state === State$2.InAttributeValueSq || - this.state === State$2.InAttributeValueNq) { - this.cbs.onattribdata(this.sectionStart, this.index); - this.sectionStart = this.index; - } - } - } - shouldContinue() { - return this.index < this.buffer.length + this.offset && this.running; - } - /** - * Iterates through the buffer, calling the function corresponding to the current state. - * - * States that are more likely to be hit are higher up, as a performance improvement. - */ - parse() { - while (this.shouldContinue()) { - const c = this.buffer.charCodeAt(this.index - this.offset); - if (this.state === State$2.Text) { - this.stateText(c); - } - else if (this.state === State$2.SpecialStartSequence) { - this.stateSpecialStartSequence(c); - } - else if (this.state === State$2.InSpecialTag) { - this.stateInSpecialTag(c); - } - else if (this.state === State$2.CDATASequence) { - this.stateCDATASequence(c); - } - else if (this.state === State$2.InAttributeValueDq) { - this.stateInAttributeValueDoubleQuotes(c); - } - else if (this.state === State$2.InAttributeName) { - this.stateInAttributeName(c); - } - else if (this.state === State$2.InCommentLike) { - this.stateInCommentLike(c); - } - else if (this.state === State$2.InSpecialComment) { - this.stateInSpecialComment(c); - } - else if (this.state === State$2.BeforeAttributeName) { - this.stateBeforeAttributeName(c); - } - else if (this.state === State$2.InTagName) { - this.stateInTagName(c); - } - else if (this.state === State$2.InClosingTagName) { - this.stateInClosingTagName(c); - } - else if (this.state === State$2.BeforeTagName) { - this.stateBeforeTagName(c); - } - else if (this.state === State$2.AfterAttributeName) { - this.stateAfterAttributeName(c); - } - else if (this.state === State$2.InAttributeValueSq) { - this.stateInAttributeValueSingleQuotes(c); - } - else if (this.state === State$2.BeforeAttributeValue) { - this.stateBeforeAttributeValue(c); - } - else if (this.state === State$2.BeforeClosingTagName) { - this.stateBeforeClosingTagName(c); - } - else if (this.state === State$2.AfterClosingTagName) { - this.stateAfterClosingTagName(c); - } - else if (this.state === State$2.BeforeSpecialS) { - this.stateBeforeSpecialS(c); - } - else if (this.state === State$2.InAttributeValueNq) { - this.stateInAttributeValueNoQuotes(c); - } - else if (this.state === State$2.InSelfClosingTag) { - this.stateInSelfClosingTag(c); - } - else if (this.state === State$2.InDeclaration) { - this.stateInDeclaration(c); - } - else if (this.state === State$2.BeforeDeclaration) { - this.stateBeforeDeclaration(c); - } - else if (this.state === State$2.BeforeComment) { - this.stateBeforeComment(c); - } - else if (this.state === State$2.InProcessingInstruction) { - this.stateInProcessingInstruction(c); - } - else if (this.state === State$2.InNamedEntity) { - this.stateInNamedEntity(c); - } - else if (this.state === State$2.BeforeEntity) { - this.stateBeforeEntity(c); - } - else if (this.state === State$2.InHexEntity) { - this.stateInHexEntity(c); - } - else if (this.state === State$2.InNumericEntity) { - this.stateInNumericEntity(c); - } - else { - // `this._state === State.BeforeNumericEntity` - this.stateBeforeNumericEntity(c); - } - this.index++; - } - this.cleanup(); - } - finish() { - if (this.state === State$2.InNamedEntity) { - this.emitNamedEntity(); - } - // If there is remaining data, emit it in a reasonable way - if (this.sectionStart < this.index) { - this.handleTrailingData(); - } - this.cbs.onend(); - } - /** Handle any trailing data. */ - handleTrailingData() { - const endIndex = this.buffer.length + this.offset; - if (this.state === State$2.InCommentLike) { - if (this.currentSequence === Sequences.CdataEnd) { - this.cbs.oncdata(this.sectionStart, endIndex, 0); - } - else { - this.cbs.oncomment(this.sectionStart, endIndex, 0); - } - } - else if (this.state === State$2.InNumericEntity && - this.allowLegacyEntity()) { - this.emitNumericEntity(false); - // All trailing data will have been consumed - } - else if (this.state === State$2.InHexEntity && - this.allowLegacyEntity()) { - this.emitNumericEntity(false); - // All trailing data will have been consumed - } - else if (this.state === State$2.InTagName || - this.state === State$2.BeforeAttributeName || - this.state === State$2.BeforeAttributeValue || - this.state === State$2.AfterAttributeName || - this.state === State$2.InAttributeName || - this.state === State$2.InAttributeValueSq || - this.state === State$2.InAttributeValueDq || - this.state === State$2.InAttributeValueNq || - this.state === State$2.InClosingTagName); - else { - this.cbs.ontext(this.sectionStart, endIndex); - } - } - emitPartial(start, endIndex) { - if (this.baseState !== State$2.Text && - this.baseState !== State$2.InSpecialTag) { - this.cbs.onattribdata(start, endIndex); - } - else { - this.cbs.ontext(start, endIndex); - } - } - emitCodePoint(cp) { - if (this.baseState !== State$2.Text && - this.baseState !== State$2.InSpecialTag) { - this.cbs.onattribentity(cp); - } - else { - this.cbs.ontextentity(cp); - } - } - } - - const formTags = new Set([ - "input", - "option", - "optgroup", - "select", - "button", - "datalist", - "textarea", - ]); - const pTag = new Set(["p"]); - const tableSectionTags = new Set(["thead", "tbody"]); - const ddtTags = new Set(["dd", "dt"]); - const rtpTags = new Set(["rt", "rp"]); - const openImpliesClose = new Map([ - ["tr", new Set(["tr", "th", "td"])], - ["th", new Set(["th"])], - ["td", new Set(["thead", "th", "td"])], - ["body", new Set(["head", "link", "script"])], - ["li", new Set(["li"])], - ["p", pTag], - ["h1", pTag], - ["h2", pTag], - ["h3", pTag], - ["h4", pTag], - ["h5", pTag], - ["h6", pTag], - ["select", formTags], - ["input", formTags], - ["output", formTags], - ["button", formTags], - ["datalist", formTags], - ["textarea", formTags], - ["option", new Set(["option"])], - ["optgroup", new Set(["optgroup", "option"])], - ["dd", ddtTags], - ["dt", ddtTags], - ["address", pTag], - ["article", pTag], - ["aside", pTag], - ["blockquote", pTag], - ["details", pTag], - ["div", pTag], - ["dl", pTag], - ["fieldset", pTag], - ["figcaption", pTag], - ["figure", pTag], - ["footer", pTag], - ["form", pTag], - ["header", pTag], - ["hr", pTag], - ["main", pTag], - ["nav", pTag], - ["ol", pTag], - ["pre", pTag], - ["section", pTag], - ["table", pTag], - ["ul", pTag], - ["rt", rtpTags], - ["rp", rtpTags], - ["tbody", tableSectionTags], - ["tfoot", tableSectionTags], - ]); - const voidElements = new Set([ - "area", - "base", - "basefont", - "br", - "col", - "command", - "embed", - "frame", - "hr", - "img", - "input", - "isindex", - "keygen", - "link", - "meta", - "param", - "source", - "track", - "wbr", - ]); - const foreignContextElements = new Set(["math", "svg"]); - const htmlIntegrationElements = new Set([ - "mi", - "mo", - "mn", - "ms", - "mtext", - "annotation-xml", - "foreignobject", - "desc", - "title", - ]); - const reNameEnd = /\s|\//; - class Parser$1 { - constructor(cbs, options = {}) { - var _a, _b, _c, _d, _e; - this.options = options; - /** The start index of the last event. */ - this.startIndex = 0; - /** The end index of the last event. */ - this.endIndex = 0; - /** - * Store the start index of the current open tag, - * so we can update the start index for attributes. - */ - this.openTagStart = 0; - this.tagname = ""; - this.attribname = ""; - this.attribvalue = ""; - this.attribs = null; - this.stack = []; - this.foreignContext = []; - this.buffers = []; - this.bufferOffset = 0; - /** The index of the last written buffer. Used when resuming after a `pause()`. */ - this.writeIndex = 0; - /** Indicates whether the parser has finished running / `.end` has been called. */ - this.ended = false; - this.cbs = cbs !== null && cbs !== void 0 ? cbs : {}; - this.lowerCaseTagNames = (_a = options.lowerCaseTags) !== null && _a !== void 0 ? _a : !options.xmlMode; - this.lowerCaseAttributeNames = - (_b = options.lowerCaseAttributeNames) !== null && _b !== void 0 ? _b : !options.xmlMode; - this.tokenizer = new ((_c = options.Tokenizer) !== null && _c !== void 0 ? _c : Tokenizer$1)(this.options, this); - (_e = (_d = this.cbs).onparserinit) === null || _e === void 0 ? void 0 : _e.call(_d, this); - } - // Tokenizer event handlers - /** @internal */ - ontext(start, endIndex) { - var _a, _b; - const data = this.getSlice(start, endIndex); - this.endIndex = endIndex - 1; - (_b = (_a = this.cbs).ontext) === null || _b === void 0 ? void 0 : _b.call(_a, data); - this.startIndex = endIndex; - } - /** @internal */ - ontextentity(cp) { - var _a, _b; - /* - * Entities can be emitted on the character, or directly after. - * We use the section start here to get accurate indices. - */ - const idx = this.tokenizer.getSectionStart(); - this.endIndex = idx - 1; - (_b = (_a = this.cbs).ontext) === null || _b === void 0 ? void 0 : _b.call(_a, decode_6(cp)); - this.startIndex = idx; - } - isVoidElement(name) { - return !this.options.xmlMode && voidElements.has(name); - } - /** @internal */ - onopentagname(start, endIndex) { - this.endIndex = endIndex; - let name = this.getSlice(start, endIndex); - if (this.lowerCaseTagNames) { - name = name.toLowerCase(); - } - this.emitOpenTag(name); - } - emitOpenTag(name) { - var _a, _b, _c, _d; - this.openTagStart = this.startIndex; - this.tagname = name; - const impliesClose = !this.options.xmlMode && openImpliesClose.get(name); - if (impliesClose) { - while (this.stack.length > 0 && - impliesClose.has(this.stack[this.stack.length - 1])) { - const el = this.stack.pop(); - (_b = (_a = this.cbs).onclosetag) === null || _b === void 0 ? void 0 : _b.call(_a, el, true); - } - } - if (!this.isVoidElement(name)) { - this.stack.push(name); - if (foreignContextElements.has(name)) { - this.foreignContext.push(true); - } - else if (htmlIntegrationElements.has(name)) { - this.foreignContext.push(false); - } - } - (_d = (_c = this.cbs).onopentagname) === null || _d === void 0 ? void 0 : _d.call(_c, name); - if (this.cbs.onopentag) - this.attribs = {}; - } - endOpenTag(isImplied) { - var _a, _b; - this.startIndex = this.openTagStart; - if (this.attribs) { - (_b = (_a = this.cbs).onopentag) === null || _b === void 0 ? void 0 : _b.call(_a, this.tagname, this.attribs, isImplied); - this.attribs = null; - } - if (this.cbs.onclosetag && this.isVoidElement(this.tagname)) { - this.cbs.onclosetag(this.tagname, true); - } - this.tagname = ""; - } - /** @internal */ - onopentagend(endIndex) { - this.endIndex = endIndex; - this.endOpenTag(false); - // Set `startIndex` for next node - this.startIndex = endIndex + 1; - } - /** @internal */ - onclosetag(start, endIndex) { - var _a, _b, _c, _d, _e, _f; - this.endIndex = endIndex; - let name = this.getSlice(start, endIndex); - if (this.lowerCaseTagNames) { - name = name.toLowerCase(); - } - if (foreignContextElements.has(name) || - htmlIntegrationElements.has(name)) { - this.foreignContext.pop(); - } - if (!this.isVoidElement(name)) { - const pos = this.stack.lastIndexOf(name); - if (pos !== -1) { - if (this.cbs.onclosetag) { - let count = this.stack.length - pos; - while (count--) { - // We know the stack has sufficient elements. - this.cbs.onclosetag(this.stack.pop(), count !== 0); - } - } - else - this.stack.length = pos; - } - else if (!this.options.xmlMode && name === "p") { - // Implicit open before close - this.emitOpenTag("p"); - this.closeCurrentTag(true); - } - } - else if (!this.options.xmlMode && name === "br") { - // We can't use `emitOpenTag` for implicit open, as `br` would be implicitly closed. - (_b = (_a = this.cbs).onopentagname) === null || _b === void 0 ? void 0 : _b.call(_a, "br"); - (_d = (_c = this.cbs).onopentag) === null || _d === void 0 ? void 0 : _d.call(_c, "br", {}, true); - (_f = (_e = this.cbs).onclosetag) === null || _f === void 0 ? void 0 : _f.call(_e, "br", false); - } - // Set `startIndex` for next node - this.startIndex = endIndex + 1; - } - /** @internal */ - onselfclosingtag(endIndex) { - this.endIndex = endIndex; - if (this.options.xmlMode || - this.options.recognizeSelfClosing || - this.foreignContext[this.foreignContext.length - 1]) { - this.closeCurrentTag(false); - // Set `startIndex` for next node - this.startIndex = endIndex + 1; - } - else { - // Ignore the fact that the tag is self-closing. - this.onopentagend(endIndex); - } - } - closeCurrentTag(isOpenImplied) { - var _a, _b; - const name = this.tagname; - this.endOpenTag(isOpenImplied); - // Self-closing tags will be on the top of the stack - if (this.stack[this.stack.length - 1] === name) { - // If the opening tag isn't implied, the closing tag has to be implied. - (_b = (_a = this.cbs).onclosetag) === null || _b === void 0 ? void 0 : _b.call(_a, name, !isOpenImplied); - this.stack.pop(); - } - } - /** @internal */ - onattribname(start, endIndex) { - this.startIndex = start; - const name = this.getSlice(start, endIndex); - this.attribname = this.lowerCaseAttributeNames - ? name.toLowerCase() - : name; - } - /** @internal */ - onattribdata(start, endIndex) { - this.attribvalue += this.getSlice(start, endIndex); - } - /** @internal */ - onattribentity(cp) { - this.attribvalue += decode_6(cp); - } - /** @internal */ - onattribend(quote, endIndex) { - var _a, _b; - this.endIndex = endIndex; - (_b = (_a = this.cbs).onattribute) === null || _b === void 0 ? void 0 : _b.call(_a, this.attribname, this.attribvalue, quote === QuoteType.Double - ? '"' - : quote === QuoteType.Single - ? "'" - : quote === QuoteType.NoValue - ? undefined - : null); - if (this.attribs && - !Object.prototype.hasOwnProperty.call(this.attribs, this.attribname)) { - this.attribs[this.attribname] = this.attribvalue; - } - this.attribvalue = ""; - } - getInstructionName(value) { - const idx = value.search(reNameEnd); - let name = idx < 0 ? value : value.substr(0, idx); - if (this.lowerCaseTagNames) { - name = name.toLowerCase(); - } - return name; - } - /** @internal */ - ondeclaration(start, endIndex) { - this.endIndex = endIndex; - const value = this.getSlice(start, endIndex); - if (this.cbs.onprocessinginstruction) { - const name = this.getInstructionName(value); - this.cbs.onprocessinginstruction(`!${name}`, `!${value}`); - } - // Set `startIndex` for next node - this.startIndex = endIndex + 1; - } - /** @internal */ - onprocessinginstruction(start, endIndex) { - this.endIndex = endIndex; - const value = this.getSlice(start, endIndex); - if (this.cbs.onprocessinginstruction) { - const name = this.getInstructionName(value); - this.cbs.onprocessinginstruction(`?${name}`, `?${value}`); - } - // Set `startIndex` for next node - this.startIndex = endIndex + 1; - } - /** @internal */ - oncomment(start, endIndex, offset) { - var _a, _b, _c, _d; - this.endIndex = endIndex; - (_b = (_a = this.cbs).oncomment) === null || _b === void 0 ? void 0 : _b.call(_a, this.getSlice(start, endIndex - offset)); - (_d = (_c = this.cbs).oncommentend) === null || _d === void 0 ? void 0 : _d.call(_c); - // Set `startIndex` for next node - this.startIndex = endIndex + 1; - } - /** @internal */ - oncdata(start, endIndex, offset) { - var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k; - this.endIndex = endIndex; - const value = this.getSlice(start, endIndex - offset); - if (this.options.xmlMode || this.options.recognizeCDATA) { - (_b = (_a = this.cbs).oncdatastart) === null || _b === void 0 ? void 0 : _b.call(_a); - (_d = (_c = this.cbs).ontext) === null || _d === void 0 ? void 0 : _d.call(_c, value); - (_f = (_e = this.cbs).oncdataend) === null || _f === void 0 ? void 0 : _f.call(_e); - } - else { - (_h = (_g = this.cbs).oncomment) === null || _h === void 0 ? void 0 : _h.call(_g, `[CDATA[${value}]]`); - (_k = (_j = this.cbs).oncommentend) === null || _k === void 0 ? void 0 : _k.call(_j); - } - // Set `startIndex` for next node - this.startIndex = endIndex + 1; - } - /** @internal */ - onend() { - var _a, _b; - if (this.cbs.onclosetag) { - // Set the end index for all remaining tags - this.endIndex = this.startIndex; - for (let i = this.stack.length; i > 0; this.cbs.onclosetag(this.stack[--i], true)) - ; - } - (_b = (_a = this.cbs).onend) === null || _b === void 0 ? void 0 : _b.call(_a); - } - /** - * Resets the parser to a blank state, ready to parse a new HTML document - */ - reset() { - var _a, _b, _c, _d; - (_b = (_a = this.cbs).onreset) === null || _b === void 0 ? void 0 : _b.call(_a); - this.tokenizer.reset(); - this.tagname = ""; - this.attribname = ""; - this.attribs = null; - this.stack.length = 0; - this.startIndex = 0; - this.endIndex = 0; - (_d = (_c = this.cbs).onparserinit) === null || _d === void 0 ? void 0 : _d.call(_c, this); - this.buffers.length = 0; - this.bufferOffset = 0; - this.writeIndex = 0; - this.ended = false; - } - /** - * Resets the parser, then parses a complete document and - * pushes it to the handler. - * - * @param data Document to parse. - */ - parseComplete(data) { - this.reset(); - this.end(data); - } - getSlice(start, end) { - while (start - this.bufferOffset >= this.buffers[0].length) { - this.shiftBuffer(); - } - let str = this.buffers[0].slice(start - this.bufferOffset, end - this.bufferOffset); - while (end - this.bufferOffset > this.buffers[0].length) { - this.shiftBuffer(); - str += this.buffers[0].slice(0, end - this.bufferOffset); - } - return str; - } - shiftBuffer() { - this.bufferOffset += this.buffers[0].length; - this.writeIndex--; - this.buffers.shift(); - } - /** - * Parses a chunk of data and calls the corresponding callbacks. - * - * @param chunk Chunk to parse. - */ - write(chunk) { - var _a, _b; - if (this.ended) { - (_b = (_a = this.cbs).onerror) === null || _b === void 0 ? void 0 : _b.call(_a, new Error(".write() after done!")); - return; - } - this.buffers.push(chunk); - if (this.tokenizer.running) { - this.tokenizer.write(chunk); - this.writeIndex++; - } - } - /** - * Parses the end of the buffer and clears the stack, calls onend. - * - * @param chunk Optional final chunk to parse. - */ - end(chunk) { - var _a, _b; - if (this.ended) { - (_b = (_a = this.cbs).onerror) === null || _b === void 0 ? void 0 : _b.call(_a, Error(".end() after done!")); - return; - } - if (chunk) - this.write(chunk); - this.ended = true; - this.tokenizer.end(); - } - /** - * Pauses parsing. The parser won't emit events until `resume` is called. - */ - pause() { - this.tokenizer.pause(); - } - /** - * Resumes parsing after `pause` was called. - */ - resume() { - this.tokenizer.resume(); - while (this.tokenizer.running && - this.writeIndex < this.buffers.length) { - this.tokenizer.write(this.buffers[this.writeIndex++]); - } - if (this.ended) - this.tokenizer.end(); - } - /** - * Alias of `write`, for backwards compatibility. - * - * @param chunk Chunk to parse. - * @deprecated - */ - parseChunk(chunk) { - this.write(chunk); - } - /** - * Alias of `end`, for backwards compatibility. - * - * @param chunk Optional final chunk to parse. - * @deprecated - */ - done(chunk) { - this.end(chunk); - } - } - - // Helper methods - /** - * Parses the data, returns the resulting document. - * - * @param data The data that should be parsed. - * @param options Optional options for the parser and DOM builder. - */ - function parseDocument(data, options) { - const handler = new DomHandler(undefined, options); - new Parser$1(handler, options).end(data); - return handler.root; - } - - /** - * Types used in signatures of Cheerio methods. - * - * @category Cheerio - */ - const parse$4 = getParse((content, options, isDocument, context) => options.xmlMode || options._useHtmlParser2 - ? parseDocument(content, options) - : parseWithParse5(content, options, isDocument, context)); - // Duplicate docs due to https://github.com/TypeStrong/typedoc/issues/1616 - /** - * Create a querying function, bound to a document created from the provided markup. - * - * Note that similar to web browser contexts, this operation may introduce - * ``, ``, and `` elements; set `isDocument` to `false` to - * switch to fragment mode and disable this. - * - * @param content - Markup to be loaded. - * @param options - Options for the created instance. - * @param isDocument - Allows parser to be switched to fragment mode. - * @returns The loaded document. - * @see {@link https://cheerio.js.org#loading} for additional usage information. - */ - const load = getLoad(parse$4, (dom, options) => options.xmlMode || options._useHtmlParser2 - ? render(dom, options) - : renderWithParse5(dom)); - /** - * The default cheerio instance. - * - * @deprecated Use the function returned by `load` instead. - */ - var cheerio = load([]); - - var debug_1 = createCommonjsModule(function (module, exports) { - exports = module.exports = debug; - - function debug(label) { - return _debug.bind(null, label); - } - - function _debug(label) { - var args = [].slice.call(arguments, 1); - args.unshift('[' + label + ']'); - process.stderr.write(args.join(' ') + '\n'); - } - }); - - var lexer = createCommonjsModule(function (module, exports) { - - var debug = debug_1('lex'); - - exports = module.exports = lex; - - /** - * Convert a CSS string into an array of lexical tokens. - * - * @param {String} css CSS - * @returns {Array} lexical tokens - */ - function lex(css) { - - var buffer = ''; // Character accumulator - var ch; // Current character - var column = 0; // Current source column number - var cursor = -1; // Current source cursor position - var depth = 0; // Current nesting depth - var line = 1; // Current source line number - var state = 'before-selector'; // Current state - var stack = [state]; // State stack - var token = {}; // Current token - var tokens = []; // Token accumulator - - // Supported @-rules, in roughly descending order of usage probability. - var atRules = [ - 'media', - 'keyframes', - { name: '-webkit-keyframes', type: 'keyframes', prefix: '-webkit-' }, - { name: '-moz-keyframes', type: 'keyframes', prefix: '-moz-' }, - { name: '-ms-keyframes', type: 'keyframes', prefix: '-ms-' }, - { name: '-o-keyframes', type: 'keyframes', prefix: '-o-' }, - 'font-face', - { name: 'import', state: 'before-at-value' }, - { name: 'charset', state: 'before-at-value' }, - 'supports', - 'viewport', - { name: 'namespace', state: 'before-at-value' }, - 'document', - { name: '-moz-document', type: 'document', prefix: '-moz-' }, - 'page' - ]; - - // -- Functions ------------------------------------------------------------ - - /** - * Advance the character cursor and return the next character. - * - * @returns {String} The next character. - */ - function getCh() { - skip(); - return css[cursor]; - } - - /** - * Return the state at the given index in the stack. - * The stack is LIFO so indexing is from the right. - * - * @param {Number} [index=0] Index to return. - * @returns {String} state - */ - function getState(index) { - return index ? stack[stack.length - 1 - index] : state; - } - - /** - * Look ahead for a string beginning from the next position. The string - * being looked for must start at the next position. - * - * @param {String} str The string to look for. - * @returns {Boolean} Whether the string was found. - */ - function isNextString(str) { - var start = cursor + 1; - return (str === css.slice(start, start + str.length)); - } - - /** - * Find the start position of a substring beginning from the next - * position. The string being looked for may begin anywhere. - * - * @param {String} str The substring to look for. - * @returns {Number|false} The position, or `false` if not found. - */ - function find(str) { - var pos = css.slice(cursor).indexOf(str); - - return pos > 0 ? pos : false; - } - - /** - * Determine whether a character is next. - * - * @param {String} ch Character. - * @returns {Boolean} Whether the character is next. - */ - function isNextChar(ch) { - return ch === peek(1); - } - - /** - * Return the character at the given cursor offset. The offset is relative - * to the cursor, so negative values move backwards. - * - * @param {Number} [offset=1] Cursor offset. - * @returns {String} Character. - */ - function peek(offset) { - return css[cursor + (offset || 1)]; - } - - /** - * Remove the current state from the stack and set the new current state. - * - * @returns {String} The removed state. - */ - function popState() { - var removed = stack.pop(); - state = stack[stack.length - 1]; - - return removed; - } - - /** - * Set the current state and add it to the stack. - * - * @param {String} newState The new state. - * @returns {Number} The new stack length. - */ - function pushState(newState) { - state = newState; - stack.push(state); - - return stack.length; - } - - /** - * Replace the current state with a new state. - * - * @param {String} newState The new state. - * @returns {String} The replaced state. - */ - function replaceState(newState) { - var previousState = state; - stack[stack.length - 1] = state = newState; - - return previousState; - } - - /** - * Move the character cursor. Positive numbers move the cursor forward. - * Negative numbers are not supported! - * - * @param {Number} [n=1] Number of characters to skip. - */ - function skip(n) { - if ((n || 1) == 1) { - if (css[cursor] == '\n') { - line++; - column = 1; - } else { - column++; - } - cursor++; - } else { - var skipStr = css.slice(cursor, cursor + n).split('\n'); - if (skipStr.length > 1) { - line += skipStr.length - 1; - column = 1; - } - column += skipStr[skipStr.length - 1].length; - cursor = cursor + n; - } - } - - /** - * Add the current token to the pile and reset the buffer. - */ - function addToken() { - token.end = { - line: line, - col: column - }; - - tokens.push(token); - - buffer = ''; - token = {}; - } - - /** - * Set the current token. - * - * @param {String} type Token type. - */ - function initializeToken(type) { - token = { - type: type, - start: { - line: line, - col: column - } - }; - } - - while (ch = getCh()) { - - // column += 1; - - switch (ch) { - // Space - case ' ': - switch (getState()) { - case 'selector': - case 'value': - case 'value-paren': - case 'at-group': - case 'at-value': - case 'comment': - case 'double-string': - case 'single-string': - buffer += ch; - break; - } - break; - - // Newline or tab - case '\n': - case '\t': - case '\r': - case '\f': - switch (getState()) { - case 'value': - case 'value-paren': - case 'at-group': - case 'comment': - case 'single-string': - case 'double-string': - case 'selector': - buffer += ch; - break; - - case 'at-value': - // Tokenize an @-rule if a semi-colon was omitted. - if ('\n' === ch) { - token.value = buffer.trim(); - addToken(); - popState(); - } - break; - } - - // if ('\n' === ch) { - // column = 0; - // line += 1; - // } - break; - - case ':': - switch (getState()) { - case 'name': - token.name = buffer.trim(); - buffer = ''; - - replaceState('before-value'); - break; - - case 'before-selector': - buffer += ch; - - initializeToken('selector'); - pushState('selector'); - break; - - case 'before-value': - replaceState('value'); - buffer += ch; - break; - - default: - buffer += ch; - break; - } - break; - - case ';': - switch (getState()) { - case 'name': - case 'before-value': - case 'value': - // Tokenize a declaration - // if value is empty skip the declaration - if (buffer.trim().length > 0) { - token.value = buffer.trim(), - addToken(); - } - replaceState('before-name'); - break; - - case 'value-paren': - // Insignificant semi-colon - buffer += ch; - break; - - case 'at-value': - // Tokenize an @-rule - token.value = buffer.trim(); - addToken(); - popState(); - break; - - case 'before-name': - // Extraneous semi-colon - break; - - default: - buffer += ch; - break; - } - break; - - case '{': - switch (getState()) { - case 'selector': - // If the sequence is `\{` then assume that the brace should be escaped. - if (peek(-1) === '\\') { - buffer += ch; - break; - } - - // Tokenize a selector - token.text = buffer.trim(); - addToken(); - replaceState('before-name'); - depth = depth + 1; - break; - - case 'at-group': - // Tokenize an @-group - token.name = buffer.trim(); - - // XXX: @-rules are starting to get hairy - switch (token.type) { - case 'font-face': - case 'viewport': - case 'page': - pushState('before-name'); - break; - - default: - pushState('before-selector'); - } - - addToken(); - depth = depth + 1; - break; - - case 'name': - case 'at-rule': - // Tokenize a declaration or an @-rule - token.name = buffer.trim(); - addToken(); - pushState('before-name'); - depth = depth + 1; - break; - - case 'comment': - case 'double-string': - case 'single-string': - // Ignore braces in comments and strings - buffer += ch; - break; - case 'before-value': - replaceState('value'); - buffer += ch; - break; - } - - break; - - case '}': - switch (getState()) { - case 'before-name': - case 'name': - case 'before-value': - case 'value': - // If the buffer contains anything, it is a value - if (buffer) { - token.value = buffer.trim(); - } - - // If the current token has a name and a value it should be tokenized. - if (token.name && token.value) { - addToken(); - } - - // Leave the block - initializeToken('end'); - addToken(); - popState(); - - // We might need to leave again. - // XXX: What about 3 levels deep? - if ('at-group' === getState()) { - initializeToken('at-group-end'); - addToken(); - popState(); - } - - if (depth > 0) { - depth = depth - 1; - } - - break; - - case 'at-group': - case 'before-selector': - case 'selector': - // If the sequence is `\}` then assume that the brace should be escaped. - if (peek(-1) === '\\') { - buffer += ch; - break; - } - - if (depth > 0) { - // Leave block if in an at-group - if ('at-group' === getState(1)) { - initializeToken('at-group-end'); - addToken(); - } - } - - if (depth > 1) { - popState(); - } - - if (depth > 0) { - depth = depth - 1; - } - break; - - case 'double-string': - case 'single-string': - case 'comment': - // Ignore braces in comments and strings. - buffer += ch; - break; - } - - break; - - // Strings - case '"': - case "'": - switch (getState()) { - case 'double-string': - if ('"' === ch && '\\' !== peek(-1)) { - popState(); - } - break; - - case 'single-string': - if ("'" === ch && '\\' !== peek(-1)) { - popState(); - } - break; - - case 'before-at-value': - replaceState('at-value'); - pushState('"' === ch ? 'double-string' : 'single-string'); - break; - - case 'before-value': - replaceState('value'); - pushState('"' === ch ? 'double-string' : 'single-string'); - break; - - case 'comment': - // Ignore strings within comments. - break; - - default: - if ('\\' !== peek(-1)) { - pushState('"' === ch ? 'double-string' : 'single-string'); - } - } - - buffer += ch; - break; - - // Comments - case '/': - switch (getState()) { - case 'comment': - case 'double-string': - case 'single-string': - // Ignore - buffer += ch; - break; - - case 'before-value': - case 'selector': - case 'name': - case 'value': - if (isNextChar('*')) { - // Ignore comments in selectors, properties and values. They are - // difficult to represent in the AST. - var pos = find('*/'); - - if (pos) { - skip(pos + 1); - } - } else { - if (getState() == 'before-value') replaceState('value'); - buffer += ch; - } - break; - - default: - if (isNextChar('*')) { - // Create a comment token - initializeToken('comment'); - pushState('comment'); - skip(); - } - else { - buffer += ch; - } - break; - } - break; - - // Comment end or universal selector - case '*': - switch (getState()) { - case 'comment': - if (isNextChar('/')) { - // Tokenize a comment - token.text = buffer; // Don't trim()! - skip(); - addToken(); - popState(); - } - else { - buffer += ch; - } - break; - - case 'before-selector': - buffer += ch; - initializeToken('selector'); - pushState('selector'); - break; - - case 'before-value': - replaceState('value'); - buffer += ch; - break; - - default: - buffer += ch; - } - break; - - // @-rules - case '@': - switch (getState()) { - case 'comment': - case 'double-string': - case 'single-string': - buffer += ch; - break; - case 'before-value': - replaceState('value'); - buffer += ch; - break; - - default: - // Iterate over the supported @-rules and attempt to tokenize one. - var tokenized = false; - var name; - var rule; - - for (var j = 0, len = atRules.length; !tokenized && j < len; ++j) { - rule = atRules[j]; - name = rule.name || rule; - - if (!isNextString(name)) { continue; } - - tokenized = true; - - initializeToken(name); - pushState(rule.state || 'at-group'); - skip(name.length); - - if (rule.prefix) { - token.prefix = rule.prefix; - } - - if (rule.type) { - token.type = rule.type; - } - } - - if (!tokenized) { - // Keep on truckin' America! - buffer += ch; - } - break; - } - break; - - // Parentheses are tracked to disambiguate semi-colons, such as within a - // data URI. - case '(': - switch (getState()) { - case 'value': - pushState('value-paren'); - break; - case 'before-value': - replaceState('value'); - break; - } - - buffer += ch; - break; - - case ')': - switch (getState()) { - case 'value-paren': - popState(); - break; - case 'before-value': - replaceState('value'); - break; - } - - buffer += ch; - break; - - default: - switch (getState()) { - case 'before-selector': - initializeToken('selector'); - pushState('selector'); - break; - - case 'before-name': - initializeToken('property'); - replaceState('name'); - break; - - case 'before-value': - replaceState('value'); - break; - - case 'before-at-value': - replaceState('at-value'); - break; - } - - buffer += ch; - break; - } - } - - return tokens; - } - }); - - var parser = createCommonjsModule(function (module, exports) { - - var debug = debug_1('parse'); - - - exports = module.exports = parse; - - var _comments; // Whether comments are allowed. - var _depth; // Current block nesting depth. - var _position; // Whether to include line/column position. - var _tokens; // Array of lexical tokens. - - /** - * Convert a CSS string or array of lexical tokens into a `stringify`-able AST. - * - * @param {String} css CSS string or array of lexical token - * @param {Object} [options] - * @param {Boolean} [options.comments=false] allow comment nodes in the AST - * @returns {Object} `stringify`-able AST - */ - function parse(css, options) { - - options || (options = {}); - _comments = !!options.comments; - _position = !!options.position; - - _depth = 0; - - // Operate on a copy of the given tokens, or the lex()'d CSS string. - _tokens = Array.isArray(css) ? css.slice() : lexer(css); - - var rule; - var rules = []; - var token; - - while ((token = next())) { - rule = parseToken(token); - rule && rules.push(rule); - } - - return { - type: "stylesheet", - stylesheet: { - rules: rules - } - }; - } - - // -- Functions -------------------------------------------------------------- - - /** - * Build an AST node from a lexical token. - * - * @param {Object} token lexical token - * @param {Object} [override] object hash of properties that override those - * already in the token, or that will be added to the token. - * @returns {Object} AST node - */ - function astNode(token, override) { - override || (override = {}); - - var key; - var keys = ['type', 'name', 'value']; - var node = {}; - - // Avoiding [].forEach for performance reasons. - for (var i = 0; i < keys.length; ++i) { - key = keys[i]; - - if (token[key]) { - node[key] = override[key] || token[key]; - } - } - - keys = Object.keys(override); - - for (i = 0; i < keys.length; ++i) { - key = keys[i]; - - if (!node[key]) { - node[key] = override[key]; - } - } - - if (_position) { - node.position = { - start: token.start, - end: token.end - }; - } - - return node; - } - - /** - * Remove a lexical token from the stack and return the removed token. - * - * @returns {Object} lexical token - */ - function next() { - var token = _tokens.shift(); - return token; - } - - // -- Parse* Functions --------------------------------------------------------- - - /** - * Convert an @-group lexical token to an AST node. - * - * @param {Object} token @-group lexical token - * @returns {Object} @-group AST node - */ - function parseAtGroup(token) { - _depth = _depth + 1; - - // As the @-group token is assembled, relevant token values are captured here - // temporarily. They will later be used as `tokenize()` overrides. - var overrides = {}; - - switch (token.type) { - case 'font-face': - case 'viewport': - overrides.declarations = parseDeclarations(); - break; - - case 'page': - overrides.prefix = token.prefix; - overrides.declarations = parseDeclarations(); - break; - - default: - overrides.prefix = token.prefix; - overrides.rules = parseRules(); - } - - return astNode(token, overrides); - } - - /** - * Convert an @import lexical token to an AST node. - * - * @param {Object} token @import lexical token - * @returns {Object} @import AST node - */ - function parseAtImport(token) { - return astNode(token); - } - - /** - * Convert an @charset token to an AST node. - * - * @param {Object} token @charset lexical token - * @returns {Object} @charset node - */ - function parseCharset(token) { - return astNode(token); - } - - /** - * Convert a comment token to an AST Node. - * - * @param {Object} token comment lexical token - * @returns {Object} comment node - */ - function parseComment(token) { - return astNode(token, { text: token.text }); - } - - function parseNamespace(token) { - return astNode(token); - } - - /** - * Convert a property lexical token to a property AST node. - * - * @returns {Object} property node - */ - function parseProperty(token) { - return astNode(token); - } - - /** - * Convert a selector lexical token to a selector AST node. - * - * @param {Object} token selector lexical token - * @returns {Object} selector node - */ - function parseSelector(token) { - function trim(str) { - return str.trim(); - } - - return astNode(token, { - type: 'rule', - selectors: token.text.split(',').map(trim), - declarations: parseDeclarations() - }); - } - - /** - * Convert a lexical token to an AST node. - * - * @returns {Object|undefined} AST node - */ - function parseToken(token) { - switch (token.type) { - // Cases are listed in roughly descending order of probability. - case 'property': return parseProperty(token); - - case 'selector': return parseSelector(token); - - case 'at-group-end': _depth = _depth - 1; return; - - case 'media': - case 'keyframes': return parseAtGroup(token); - - case 'comment': if (_comments) { return parseComment(token); } break; - - case 'charset': return parseCharset(token); - case 'import': return parseAtImport(token); - - case 'namespace': return parseNamespace(token); - - case 'font-face': - case 'supports': - case 'viewport': - case 'document': - case 'page': return parseAtGroup(token); - } - } - - // -- Parse Helper Functions --------------------------------------------------- - - /** - * Iteratively parses lexical tokens from the stack into AST nodes until a - * conditional function returns `false`, at which point iteration terminates - * and any AST nodes collected are returned. - * - * @param {Function} conditionFn - * @param {Object} token the lexical token being parsed - * @returns {Boolean} `true` if the token should be parsed, `false` otherwise - * @return {Array} AST nodes - */ - function parseTokensWhile(conditionFn) { - var node; - var nodes = []; - var token; - - while ((token = next()) && (conditionFn && conditionFn(token))) { - node = parseToken(token); - node && nodes.push(node); - } - - // Place an unused non-`end` lexical token back onto the stack. - if (token && token.type !== 'end') { - _tokens.unshift(token); - } - - return nodes; - } - - /** - * Convert a series of tokens into a sequence of declaration AST nodes. - * - * @returns {Array} declaration nodes - */ - function parseDeclarations() { - return parseTokensWhile(function (token) { - return (token.type === 'property' || token.type === 'comment'); - }); - } - - /** - * Convert a series of tokens into a sequence of rule nodes. - * - * @returns {Array} rule nodes - */ - function parseRules() { - return parseTokensWhile(function () { return _depth; }); - } - }); - - var stringify_1 = createCommonjsModule(function (module, exports) { - - var debug = debug_1('stringify'); - - var _comments; // Whether comments are allowed in the stringified CSS. - var _compress; // Whether the stringified CSS should be compressed. - var _indentation; // Indentation option value. - var _level; // Current indentation level. - var _n; // Compression-aware newline character. - var _s; // Compression-aware space character. - - exports = module.exports = stringify; - - /** - * Convert a `stringify`-able AST into a CSS string. - * - * @param {Object} `stringify`-able AST - * @param {Object} [options] - * @param {Boolean} [options.comments=false] allow comments in the CSS - * @param {Boolean} [options.compress=false] compress whitespace - * @param {String} [options.indentation=''] indentation sequence - * @returns {String} CSS - */ - function stringify(ast, options) { - - options || (options = {}); - _indentation = options.indentation || ''; - _compress = !!options.compress; - _comments = !!options.comments; - _level = 1; - - if (_compress) { - _n = _s = ''; - } else { - _n = '\n'; - _s = ' '; - } - - var css = reduce(ast.stylesheet.rules, stringifyNode).join('\n').trim(); - - return css; - } - - // -- Functions -------------------------------------------------------------- - - /** - * Modify the indentation level, or return a compression-aware sequence of - * spaces equal to the current indentation level. - * - * @param {Number} [level=undefined] indentation level modifier - * @returns {String} sequence of spaces - */ - function indent(level) { - if (level) { - _level += level; - return; - } - - if (_compress) { return ''; } - - return Array(_level).join(_indentation || ''); - } - - // -- Stringify Functions ------------------------------------------------------ - - /** - * Stringify an @-rule AST node. - * - * Use `stringifyAtGroup()` when dealing with @-groups that may contain blocks - * such as @media. - * - * @param {String} type @-rule type. E.g., import, charset - * @returns {String} Stringified @-rule - */ - function stringifyAtRule(node) { - return '@' + node.type + ' ' + node.value + ';' + _n; - } - - /** - * Stringify an @-group AST node. - * - * Use `stringifyAtRule()` when dealing with @-rules that may not contain blocks - * such as @import. - * - * @param {Object} node @-group AST node - * @returns {String} - */ - function stringifyAtGroup(node) { - var label = ''; - var prefix = node.prefix || ''; - - if (node.name) { - label = ' ' + node.name; - } - - // FIXME: @-rule conditional logic is leaking everywhere. - var chomp = node.type !== 'page'; - - return '@' + prefix + node.type + label + _s + stringifyBlock(node, chomp) + _n; - } - - /** - * Stringify a comment AST node. - * - * @param {Object} node comment AST node - * @returns {String} - */ - function stringifyComment(node) { - if (!_comments) { return ''; } - - return '/*' + (node.text || '') + '*/' + _n; - } - - /** - * Stringify a rule AST node. - * - * @param {Object} node rule AST node - * @returns {String} - */ - function stringifyRule(node) { - var label; - - if (node.selectors) { - label = node.selectors.join(',' + _n); - } else { - label = '@' + node.type; - label += node.name ? ' ' + node.name : ''; - } - - return indent() + label + _s + stringifyBlock(node) + _n; - } - - - // -- Stringify Helper Functions ----------------------------------------------- - - /** - * Reduce an array by applying a function to each item and retaining the truthy - * results. - * - * When `item.type` is `'comment'` `stringifyComment` will be applied instead. - * - * @param {Array} items array to reduce - * @param {Function} fn function to call for each item in the array - * @returns {Mixed} Truthy values will be retained, falsy values omitted - * @returns {Array} retained results - */ - function reduce(items, fn) { - return items.reduce(function (results, item) { - var result = (item.type === 'comment') ? stringifyComment(item) : fn(item); - result && results.push(result); - return results; - }, []); - } - - /** - * Stringify an AST node with the assumption that it represents a block of - * declarations or other @-group contents. - * - * @param {Object} node AST node - * @returns {String} - */ - // FIXME: chomp should not be a magic boolean parameter - function stringifyBlock(node, chomp) { - var children = node.declarations; - var fn = stringifyDeclaration; - - if (node.rules) { - children = node.rules; - fn = stringifyRule; - } - - children = stringifyChildren(children, fn); - children && (children = _n + children + (chomp ? '' : _n)); - - return '{' + children + indent() + '}'; - } - - /** - * Stringify an array of child AST nodes by calling the given stringify function - * once for each child, and concatenating the results. - * - * @param {Array} children `node.rules` or `node.declarations` - * @param {Function} fn stringify function - * @returns {String} - */ - function stringifyChildren(children, fn) { - if (!children) { return ''; } - - indent(1); - var results = reduce(children, fn); - indent(-1); - - if (!results.length) { return ''; } - - return results.join(_n); - } - - /** - * Stringify a declaration AST node. - * - * @param {Object} node declaration AST node - * @returns {String} - */ - function stringifyDeclaration(node) { - if (node.type === 'property') { - return stringifyProperty(node); - } - } - - /** - * Stringify an AST node. - * - * @param {Object} node AST node - * @returns {String} - */ - function stringifyNode(node) { - switch (node.type) { - // Cases are listed in roughly descending order of probability. - case 'rule': return stringifyRule(node); - - case 'media': - case 'keyframes': return stringifyAtGroup(node); - - case 'comment': return stringifyComment(node); - - case 'import': - case 'charset': - case 'namespace': return stringifyAtRule(node); - - case 'font-face': - case 'supports': - case 'viewport': - case 'document': - case 'page': return stringifyAtGroup(node); - } - } - - /** - * Stringify an AST property node. - * - * @param {Object} node AST property node - * @returns {String} - */ - function stringifyProperty(node) { - var name = node.name ? node.name + ':' + _s : ''; - - return indent() + name + node.value + ';'; - } - }); - - var mensch = { - lex: lexer, - parse: parser, - stringify: stringify_1 - }; - - // Notable changes from Slick.Parser 1.0.x - - // The parser now uses 2 classes: Expressions and Expression - // `new Expressions` produces an array-like object containing a list of Expression objects - // - Expressions::toString() produces a cleaned up expressions string - // `new Expression` produces an array-like object - // - Expression::toString() produces a cleaned up expression string - // The only exposed method is parse, which produces a (cached) `new Expressions` instance - // parsed.raw is no longer present, use .toString() - // parsed.expression is now useless, just use the indices - // parsed.reverse() has been removed for now, due to its apparent uselessness - // Other changes in the Expressions object: - // - classNames are now unique, and save both escaped and unescaped values - // - attributes now save both escaped and unescaped values - // - pseudos now save both escaped and unescaped values - - var escapeRe = /([-.*+?^${}()|[\]\/\\])/g, - unescapeRe = /\\/g; - - var escape$1 = function (string) { - // XRegExp v2.0.0-beta-3 - // « https://github.com/slevithan/XRegExp/blob/master/src/xregexp.js - return (string + "").replace(escapeRe, '\\$1') - }; - - var unescape$1 = function (string) { - return (string + "").replace(unescapeRe, '') - }; - - var slickRe = RegExp( - /* - #!/usr/bin/env ruby - puts "\t\t" + DATA.read.gsub(/\(\?x\)|\s+#.*$|\s+|\\$|\\n/,'') - __END__ - "(?x)^(?:\ - \\s* ( , ) \\s* # Separator \n\ - | \\s* ( + ) \\s* # Combinator \n\ - | ( \\s+ ) # CombinatorChildren \n\ - | ( + | \\* ) # Tag \n\ - | \\# ( + ) # ID \n\ - | \\. ( + ) # ClassName \n\ - | # Attribute \n\ - \\[ \ - \\s* (+) (?: \ - \\s* ([*^$!~|]?=) (?: \ - \\s* (?:\ - ([\"']?)(.*?)\\9 \ - )\ - ) \ - )? \\s* \ - \\](?!\\]) \n\ - | :+ ( + )(?:\ - \\( (?:\ - (?:([\"'])([^\\12]*)\\12)|((?:\\([^)]+\\)|[^()]*)+)\ - ) \\)\ - )?\ - )" - */ - "^(?:\\s*(,)\\s*|\\s*(+)\\s*|(\\s+)|(+|\\*)|\\#(+)|\\.(+)|\\[\\s*(+)(?:\\s*([*^$!~|]?=)(?:\\s*(?:([\"']?)(.*?)\\9)))?\\s*\\](?!\\])|(:+)(+)(?:\\((?:(?:([\"'])([^\\13]*)\\13)|((?:\\([^)]+\\)|[^()]*)+))\\))?)" - .replace(//, '[' + escape$1(">+~`!@$%^&={}\\;/g, '(?:[\\w\\u00a1-\\uFFFF-]|\\\\[^\\s0-9a-f])') - .replace(//g, '(?:[:\\w\\u00a1-\\uFFFF-]|\\\\[^\\s0-9a-f])') - ); - - // Part - - var Part = function Part(combinator) { - this.combinator = combinator || " "; - this.tag = "*"; - }; - - Part.prototype.toString = function () { - - if (!this.raw) { - - var xpr = "", k, part; - - xpr += this.tag || "*"; - if (this.id) xpr += "#" + this.id; - if (this.classes) xpr += "." + this.classList.join("."); - if (this.attributes) for (k = 0; part = this.attributes[k++];) { - xpr += "[" + part.name + (part.operator ? part.operator + '"' + part.value + '"' : '') + "]"; - } - if (this.pseudos) for (k = 0; part = this.pseudos[k++];) { - xpr += ":" + part.name; - if (part.value) xpr += "(" + part.value + ")"; - } - - this.raw = xpr; - - } - - return this.raw - }; - - // Expression - - var Expression = function Expression() { - this.length = 0; - }; - - Expression.prototype.toString = function () { - - if (!this.raw) { - - var xpr = ""; - - for (var j = 0, bit; bit = this[j++];) { - if (j !== 1) xpr += " "; - if (bit.combinator !== " ") xpr += bit.combinator + " "; - xpr += bit; - } - - this.raw = xpr; - - } - - return this.raw - }; - - var replacer$1 = function ( - rawMatch, - - separator, - combinator, - combinatorChildren, - - tagName, - id, - className, - - attributeKey, - attributeOperator, - attributeQuote, - attributeValue, - - pseudoMarker, - pseudoClass, - pseudoQuote, - pseudoClassQuotedValue, - pseudoClassValue - ) { - - var expression, current; - - if (separator || !this.length) { - expression = this[this.length++] = new Expression; - if (separator) return '' - } - - if (!expression) expression = this[this.length - 1]; - - if (combinator || combinatorChildren || !expression.length) { - current = expression[expression.length++] = new Part(combinator); - } - - if (!current) current = expression[expression.length - 1]; - - if (tagName) { - - current.tag = unescape$1(tagName); - - } else if (id) { - - current.id = unescape$1(id); - - } else if (className) { - - var unescaped = unescape$1(className); - - var classes = current.classes || (current.classes = {}); - if (!classes[unescaped]) { - classes[unescaped] = escape$1(className); - var classList = current.classList || (current.classList = []); - classList.push(unescaped); - classList.sort(); - } - - } else if (pseudoClass) { - - pseudoClassValue = pseudoClassValue || pseudoClassQuotedValue - - ; (current.pseudos || (current.pseudos = [])).push({ - type: pseudoMarker.length == 1 ? 'class' : 'element', - name: unescape$1(pseudoClass), - escapedName: escape$1(pseudoClass), - value: pseudoClassValue ? unescape$1(pseudoClassValue) : null, - escapedValue: pseudoClassValue ? escape$1(pseudoClassValue) : null - }); - - } else if (attributeKey) { - - attributeValue = attributeValue ? escape$1(attributeValue) : null - - ; (current.attributes || (current.attributes = [])).push({ - operator: attributeOperator, - name: unescape$1(attributeKey), - escapedName: escape$1(attributeKey), - value: attributeValue ? unescape$1(attributeValue) : null, - escapedValue: attributeValue ? escape$1(attributeValue) : null - }); - - } - - return '' - - }; - - // Expressions - - var Expressions = function Expressions(expression) { - this.length = 0; - - var self = this; - - var original = expression, replaced; - - while (expression) { - replaced = expression.replace(slickRe, function () { - return replacer$1.apply(self, arguments) - }); - if (replaced === expression) throw new Error(original + ' is an invalid expression') - expression = replaced; - } - }; - - Expressions.prototype.toString = function () { - if (!this.raw) { - var expressions = []; - for (var i = 0, expression; expression = this[i++];) expressions.push(expression); - this.raw = expressions.join(", "); - } - - return this.raw - }; - - var cache = {}; - - var parse$5 = function (expression) { - if (expression == null) return null - expression = ('' + expression).replace(/^\s+|\s+$/g, ''); - return cache[expression] || (cache[expression] = new Expressions(expression)) - }; - - var parser$1 = parse$5; - - var selector = createCommonjsModule(function (module, exports) { - - - - module.exports = exports = Selector; - - /** - * CSS selector constructor. - * - * @param {String} selector text - * @param {Array} optionally, precalculated specificity - * @api public - */ - - function Selector(text, styleAttribute) { - this.text = text; - this.spec = undefined; - this.styleAttribute = styleAttribute || false; - } - - /** - * Get parsed selector. - * - * @api public - */ - - Selector.prototype.parsed = function () { - if (!this.tokens) { this.tokens = parse(this.text); } - return this.tokens; - }; - - /** - * Lazy specificity getter - * - * @api public - */ - - Selector.prototype.specificity = function () { - var styleAttribute = this.styleAttribute; - if (!this.spec) { this.spec = specificity(this.text, this.parsed()); } - return this.spec; - - function specificity(text, parsed) { - var expressions = parsed || parse(text); - var spec = [styleAttribute ? 1 : 0, 0, 0, 0]; - var nots = []; - - for (var i = 0; i < expressions.length; i++) { - var expression = expressions[i]; - var pseudos = expression.pseudos; - - // id awards a point in the second column - if (expression.id) { spec[1]++; } - - // classes and attributes award a point each in the third column - if (expression.attributes) { spec[2] += expression.attributes.length; } - if (expression.classList) { spec[2] += expression.classList.length; } - - // tag awards a point in the fourth column - if (expression.tag && expression.tag !== '*') { spec[3]++; } - - // pseudos award a point each in the fourth column - if (pseudos) { - spec[3] += pseudos.length; - - for (var p = 0; p < pseudos.length; p++) { - if (pseudos[p].name === 'not') { - nots.push(pseudos[p].value); - spec[3]--; - } - } - } - } - - for (var ii = nots.length; ii--;) { - var not = specificity(nots[ii]); - for (var jj = 4; jj--;) { spec[jj] += not[jj]; } - } - - return spec; - } - }; - - /** - * Parses a selector and returns the tokens. - * - * @param {String} selector - * @api private. - */ - - function parse(text) { - try { - return parser$1(text)[0]; - } catch (e) { - return []; - } - } - }); - - var property = createCommonjsModule(function (module, exports) { - - module.exports = exports = Property; - - /** - * Module dependencies. - */ - - - - /** - * CSS property constructor. - * - * @param {String} property - * @param {String} value - * @param {Selector} selector the property originates from - * @param {Integer} priority 0 for normal properties, 2 for !important properties. - * @param {Array} additional array of integers representing more detailed priorities (sorting) - * @api public - */ - - function Property(prop, value, selector, priority, additionalPriority) { - this.prop = prop; - this.value = value; - this.selector = selector; - this.priority = priority || 0; - this.additionalPriority = additionalPriority || []; - } - - /** - * Compares with another Property based on Selector#specificity. - * - * @api public - */ - - Property.prototype.compareFunc = function (property) { - var a = []; - a.push.apply(a, this.selector.specificity()); - a.push.apply(a, this.additionalPriority); - a[0] += this.priority; - var b = []; - b.push.apply(b, property.selector.specificity()); - b.push.apply(b, property.additionalPriority); - b[0] += property.priority; - return utils.compareFunc(a, b); - }; - - Property.prototype.compare = function (property) { - var winner = this.compareFunc(property); - if (winner === 1) { - return this; - } - return property; - }; - - - /** - * Returns CSS property - * - * @api public - */ - - Property.prototype.toString = function () { - return this.prop + ': ' + this.value.replace(/['"]+/g, '') + ';'; - }; - }); - - var utils = createCommonjsModule(function (module, exports) { - - /** - * Module dependencies. - */ - - - - - - exports.Selector = selector; - exports.Property = property; - - /** - * Returns an array of the selectors. - * - * @license Sizzle CSS Selector Engine - MIT - * @param {String} selectorText from mensch - * @api public - */ - - exports.extract = function extract(selectorText) { - var attr = 0; - var sels = []; - var sel = ''; - - for (var i = 0, l = selectorText.length; i < l; i++) { - var c = selectorText.charAt(i); - - if (attr) { - if (']' === c || ')' === c) { attr--; } - sel += c; - } else { - if (',' === c) { - sels.push(sel); - sel = ''; - } else { - if ('[' === c || '(' === c) { attr++; } - if (sel.length || (c !== ',' && c !== '\n' && c !== ' ')) { sel += c; } - } - } - } - - if (sel.length) { - sels.push(sel); - } - - return sels; - }; - - /** - * Returns a parse tree for a CSS source. - * If it encounters multiple selectors separated by a comma, it splits the - * tree. - * - * @param {String} css source - * @api public - */ - - exports.parseCSS = function (css) { - var parsed = mensch.parse(css, { position: true, comments: true }); - var rules = typeof parsed.stylesheet != 'undefined' && parsed.stylesheet.rules ? parsed.stylesheet.rules : []; - var ret = []; - - for (var i = 0, l = rules.length; i < l; i++) { - if (rules[i].type == 'rule') { - var rule = rules[i]; - var selectors = rule.selectors; - - for (var ii = 0, ll = selectors.length; ii < ll; ii++) { - ret.push([selectors[ii], rule.declarations]); - } - } - } - - return ret; - }; - - /** - * Returns preserved text for a CSS source. - * - * @param {String} css source - * @param {Object} options - * @api public - */ - - exports.getPreservedText = function (css, options, ignoredPseudos) { - var parsed = mensch.parse(css, { position: true, comments: true }); - var rules = typeof parsed.stylesheet != 'undefined' && parsed.stylesheet.rules ? parsed.stylesheet.rules : []; - var preserved = []; - var lastStart = null; - - for (var i = rules.length - 1; i >= 0; i--) { - if ((options.fontFaces && rules[i].type === 'font-face') || - (options.mediaQueries && rules[i].type === 'media') || - (options.keyFrames && rules[i].type === 'keyframes') || - (options.pseudos && rules[i].selectors && this.matchesPseudo(rules[i].selectors[0], ignoredPseudos))) { - preserved.unshift( - mensch.stringify( - { stylesheet: { rules: [rules[i]] } }, - { comments: false, indentation: ' ' } - ) - ); - } - lastStart = rules[i].position.start; - } - - if (preserved.length === 0) { - return false; - } - return '\n' + preserved.join('\n') + '\n'; - }; - - exports.normalizeLineEndings = function (text) { - return text.replace(/\r\n/g, '\n').replace(/\n/g, '\r\n'); - }; - - exports.matchesPseudo = function (needle, haystack) { - return haystack.find(function (element) { - return needle.indexOf(element) > -1; - }) - }; - - /** - * Compares two specificity vectors, returning the winning one. - * - * @param {Array} vector a - * @param {Array} vector b - * @return {Array} - * @api public - */ - - exports.compareFunc = function (a, b) { - var min = Math.min(a.length, b.length); - for (var i = 0; i < min; i++) { - if (a[i] === b[i]) { continue; } - if (a[i] > b[i]) { return 1; } - return -1; - } - - return a.length - b.length; - }; - - exports.compare = function (a, b) { - return exports.compareFunc(a, b) == 1 ? a : b; - }; - - exports.getDefaultOptions = function (options) { - var result = Object.assign({ - extraCss: '', - insertPreservedExtraCss: true, - applyStyleTags: true, - removeStyleTags: true, - preserveMediaQueries: true, - preserveFontFaces: true, - preserveKeyFrames: true, - preservePseudos: true, - applyWidthAttributes: true, - applyHeightAttributes: true, - applyAttributesTableElements: true, - url: '' - }, options); - - result.webResources = result.webResources || {}; - - return result; - }; - }); - var utils_1 = utils.Selector; - var utils_2 = utils.Property; - var utils_3 = utils.extract; - var utils_4 = utils.parseCSS; - var utils_5 = utils.getPreservedText; - var utils_6 = utils.normalizeLineEndings; - var utils_7 = utils.matchesPseudo; - var utils_8 = utils.compareFunc; - var utils_9 = utils.compare; - var utils_10 = utils.getDefaultOptions; - - var cheerio_1 = createCommonjsModule(function (module) { - - /** - * Module dependencies. - */ - - - - var cheerioLoad = function (html, options, encodeEntities) { - options = Object.assign({ decodeEntities: false, _useHtmlParser2: true }, options); - html = encodeEntities(html); - return cheerio.load(html, options); - }; - - var createEntityConverters = function () { - var codeBlockLookup = []; - - var encodeCodeBlocks = function (html) { - var blocks = module.exports.codeBlocks; - Object.keys(blocks).forEach(function (key) { - var re = new RegExp(blocks[key].start + '([\\S\\s]*?)' + blocks[key].end, 'g'); - html = html.replace(re, function (match, subMatch) { - codeBlockLookup.push(match); - return 'JUICE_CODE_BLOCK_' + (codeBlockLookup.length - 1) + '_'; - }); - }); - return html; - }; - - var decodeCodeBlocks = function (html) { - for (var index = 0; index < codeBlockLookup.length; index++) { - var re = new RegExp('JUICE_CODE_BLOCK_' + index + '_(="")?', 'gi'); - html = html.replace(re, function () { - return codeBlockLookup[index]; - }); - } - return html; - }; - - return { - encodeEntities: encodeCodeBlocks, - decodeEntities: decodeCodeBlocks, - }; - }; - - /** - * Parses the input, calls the callback on the parsed DOM, and generates the output - * - * @param {String} html input html to be processed - * @param {Object} options for the parser - * @param {Function} callback to be invoked on the DOM - * @param {Array} callbackExtraArguments to be passed to the callback - * @return {String} resulting html - */ - module.exports = function (html, options, callback, callbackExtraArguments) { - var entityConverters = createEntityConverters(); - - var $ = cheerioLoad(html, options, entityConverters.encodeEntities); - var args = [$]; - args.push.apply(args, callbackExtraArguments); - var doc = callback.apply(undefined, args) || $; + var Traversing = /*#__PURE__*/Object.freeze({ + __proto__: null, + find: find$7, + parent: parent, + parents: parents, + parentsUntil: parentsUntil, + closest: closest, + next: next, + nextAll: nextAll, + nextUntil: nextUntil, + prev: prev, + prevAll: prevAll, + prevUntil: prevUntil, + siblings: siblings, + children: children, + contents: contents, + each: each, + map: map$a, + filter: filter$6, + filterArray: filterArray, + is: is$2, + not: not, + has: has$1, + first: first, + last: last$1, + eq: eq$1, + get: get$9, + toArray: toArray$1, + index: index, + slice: slice$8, + end: end, + add: add, + addBack: addBack + }); - if (options && options.xmlMode) { - return entityConverters.decodeEntities(doc.xml()); - } - return entityConverters.decodeEntities(doc.html()); - }; + /** + * Get the parse function with options. + * + * @param parser - The parser function. + * @returns The parse function with options. + */ + function getParse(parser) { + /** + * Parse a HTML string or a node. + * + * @param content - The HTML string or node. + * @param options - The parser options. + * @param isDocument - If `content` is a document. + * @param context - The context node in the DOM tree. + * @returns The parsed document node. + */ + return function parse(content, options, isDocument$1, context) { + if (typeof Buffer !== 'undefined' && Buffer.isBuffer(content)) { + content = content.toString(); + } + if (typeof content === 'string') { + return parser(content, options, isDocument$1, context); + } + const doc = content; + if (!Array.isArray(doc) && isDocument(doc)) { + // If `doc` is already a root, just return it + return doc; + } + // Add conent to new root element + const root = new Document([]); + // Update the DOM using the root + update(doc, root); + return root; + }; + } + /** + * Update the dom structure, for one changed layer. + * + * @param newChilds - The new children. + * @param parent - The new parent. + * @returns The parent node. + */ + function update(newChilds, parent) { + // Normalize + const arr = Array.isArray(newChilds) ? newChilds : [newChilds]; + // Update parent + if (parent) { + parent.children = arr; + } + else { + parent = null; + } + // Update neighbors + for (let i = 0; i < arr.length; i++) { + const node = arr[i]; + // Cleanly remove existing nodes from their previous structures. + if (node.parent && node.parent.children !== arr) { + removeElement(node); + } + if (parent) { + node.prev = arr[i - 1] || null; + node.next = arr[i + 1] || null; + } + else { + node.prev = node.next = null; + } + node.parent = parent; + } + return parent; + } - module.exports.codeBlocks = { - EJS: { start: '<%', end: '%>' }, - HBS: { start: '{{', end: '}}' } - }; + /** + * Methods for modifying the DOM structure. + * + * @module cheerio/manipulation + */ + /** + * Create an array of nodes, recursing into arrays and parsing strings if necessary. + * + * @private + * @category Manipulation + * @param elem - Elements to make an array of. + * @param clone - Optionally clone nodes. + * @returns The array of nodes. + */ + function _makeDomArray(elem, clone) { + if (elem == null) { + return []; + } + if (isCheerio(elem)) { + return clone ? cloneDom(elem.get()) : elem.get(); + } + if (Array.isArray(elem)) { + return elem.reduce((newElems, el) => newElems.concat(this._makeDomArray(el, clone)), []); + } + if (typeof elem === 'string') { + return this._parse(elem, this.options, false, null).children; + } + return clone ? cloneDom([elem]) : [elem]; + } + function _insert(concatenator) { + return function (...elems) { + const lastIdx = this.length - 1; + return domEach(this, (el, i) => { + if (!hasChildren(el)) + return; + const domSrc = typeof elems[0] === 'function' + ? elems[0].call(el, i, this._render(el.children)) + : elems; + const dom = this._makeDomArray(domSrc, i < lastIdx); + concatenator(dom, el.children, el); + }); + }; + } + /** + * Modify an array in-place, removing some number of elements and adding new + * elements directly following them. + * + * @private + * @category Manipulation + * @param array - Target array to splice. + * @param spliceIdx - Index at which to begin changing the array. + * @param spliceCount - Number of elements to remove from the array. + * @param newElems - Elements to insert into the array. + * @param parent - The parent of the node. + * @returns The spliced array. + */ + function uniqueSplice(array, spliceIdx, spliceCount, newElems, parent) { + var _a, _b; + const spliceArgs = [ + spliceIdx, + spliceCount, + ...newElems, + ]; + const prev = spliceIdx === 0 ? null : array[spliceIdx - 1]; + const next = spliceIdx + spliceCount >= array.length + ? null + : array[spliceIdx + spliceCount]; + /* + * Before splicing in new elements, ensure they do not already appear in the + * current array. + */ + for (let idx = 0; idx < newElems.length; ++idx) { + const node = newElems[idx]; + const oldParent = node.parent; + if (oldParent) { + const oldSiblings = oldParent.children; + const prevIdx = oldSiblings.indexOf(node); + if (prevIdx > -1) { + oldParent.children.splice(prevIdx, 1); + if (parent === oldParent && spliceIdx > prevIdx) { + spliceArgs[0]--; + } + } + } + node.parent = parent; + if (node.prev) { + node.prev.next = (_a = node.next) !== null && _a !== void 0 ? _a : null; + } + if (node.next) { + node.next.prev = (_b = node.prev) !== null && _b !== void 0 ? _b : null; + } + node.prev = idx === 0 ? prev : newElems[idx - 1]; + node.next = idx === newElems.length - 1 ? next : newElems[idx + 1]; + } + if (prev) { + prev.next = newElems[0]; + } + if (next) { + next.prev = newElems[newElems.length - 1]; + } + return array.splice(...spliceArgs); + } + /** + * Insert every element in the set of matched elements to the end of the target. + * + * @category Manipulation + * @example + * + * ```js + * $('

  • Plum
  • ').appendTo('#fruits'); + * $.html(); + * //=>
      + * //
    • Apple
    • + * //
    • Orange
    • + * //
    • Pear
    • + * //
    • Plum
    • + * //
    + * ``` + * + * @param target - Element to append elements to. + * @returns The instance itself. + * @see {@link https://api.jquery.com/appendTo/} + */ + function appendTo(target) { + const appendTarget = isCheerio(target) ? target : this._make(target); + appendTarget.append(this); + return this; + } + /** + * Insert every element in the set of matched elements to the beginning of the target. + * + * @category Manipulation + * @example + * + * ```js + * $('
  • Plum
  • ').prependTo('#fruits'); + * $.html(); + * //=>
      + * //
    • Plum
    • + * //
    • Apple
    • + * //
    • Orange
    • + * //
    • Pear
    • + * //
    + * ``` + * + * @param target - Element to prepend elements to. + * @returns The instance itself. + * @see {@link https://api.jquery.com/prependTo/} + */ + function prependTo(target) { + const prependTarget = isCheerio(target) ? target : this._make(target); + prependTarget.prepend(this); + return this; + } + /** + * Inserts content as the _last_ child of each of the selected elements. + * + * @category Manipulation + * @example + * + * ```js + * $('ul').append('
  • Plum
  • '); + * $.html(); + * //=>
      + * //
    • Apple
    • + * //
    • Orange
    • + * //
    • Pear
    • + * //
    • Plum
    • + * //
    + * ``` + * + * @see {@link https://api.jquery.com/append/} + */ + const append$1 = _insert((dom, children, parent) => { + uniqueSplice(children, children.length, 0, dom, parent); }); - var cheerio_2 = cheerio_1.codeBlocks; - /** - * Converts a decimal number to roman numeral. - * https://stackoverflow.com/questions/9083037/convert-a-number-into-a-roman-numeral-in-javascript + * Inserts content as the _first_ child of each of the selected elements. + * + * @category Manipulation + * @example + * + * ```js + * $('ul').prepend('
  • Plum
  • '); + * $.html(); + * //=>
      + * //
    • Plum
    • + * //
    • Apple
    • + * //
    • Orange
    • + * //
    • Pear
    • + * //
    + * ``` + * + * @see {@link https://api.jquery.com/prepend/} + */ + const prepend$1 = _insert((dom, children, parent) => { + uniqueSplice(children, 0, 0, dom, parent); + }); + function _wrap(insert) { + return function (wrapper) { + const lastIdx = this.length - 1; + const lastParent = this.parents().last(); + for (let i = 0; i < this.length; i++) { + const el = this[i]; + const wrap = typeof wrapper === 'function' + ? wrapper.call(el, i, el) + : typeof wrapper === 'string' && !isHtml(wrapper) + ? lastParent.find(wrapper).clone() + : wrapper; + const [wrapperDom] = this._makeDomArray(wrap, i < lastIdx); + if (!wrapperDom || !hasChildren(wrapperDom)) + continue; + let elInsertLocation = wrapperDom; + /* + * Find the deepest child. Only consider the first tag child of each node + * (ignore text); stop if no children are found. + */ + let j = 0; + while (j < elInsertLocation.children.length) { + const child = elInsertLocation.children[j]; + if (isTag$1(child)) { + elInsertLocation = child; + j = 0; + } + else { + j++; + } + } + insert(el, elInsertLocation, [wrapperDom]); + } + return this; + }; + } + /** + * The .wrap() function can take any string or object that could be passed to + * the $() factory function to specify a DOM structure. This structure may be + * nested several levels deep, but should contain only one inmost element. A + * copy of this structure will be wrapped around each of the elements in the set + * of matched elements. This method returns the original set of elements for + * chaining purposes. + * + * @category Manipulation + * @example + * + * ```js + * const redFruit = $('
    '); + * $('.apple').wrap(redFruit); + * + * //=>
      + * //
      + * //
    • Apple
    • + * //
      + * //
    • Orange
    • + * //
    • Plum
    • + * //
    + * + * const healthy = $('
    '); + * $('li').wrap(healthy); + * + * //=>
      + * //
      + * //
    • Apple
    • + * //
      + * //
      + * //
    • Orange
    • + * //
      + * //
      + * //
    • Plum
    • + * //
      + * //
    + * ``` + * + * @param wrapper - The DOM structure to wrap around each element in the selection. + * @see {@link https://api.jquery.com/wrap/} + */ + const wrap$2 = _wrap((el, elInsertLocation, wrapperDom) => { + const { parent } = el; + if (!parent) + return; + const siblings = parent.children; + const index = siblings.indexOf(el); + update([el], elInsertLocation); + /* + * The previous operation removed the current element from the `siblings` + * array, so the `dom` array can be inserted without removing any + * additional elements. + */ + uniqueSplice(siblings, index, 0, wrapperDom, parent); + }); + /** + * The .wrapInner() function can take any string or object that could be passed + * to the $() factory function to specify a DOM structure. This structure may be + * nested several levels deep, but should contain only one inmost element. The + * structure will be wrapped around the content of each of the elements in the + * set of matched elements. + * + * @category Manipulation + * @example + * + * ```js + * const redFruit = $('
    '); + * $('.apple').wrapInner(redFruit); + * + * //=>
      + * //
    • + * //
      Apple
      + * //
    • + * //
    • Orange
    • + * //
    • Pear
    • + * //
    + * + * const healthy = $('
    '); + * $('li').wrapInner(healthy); * - * @param {Number} number - * @api private. + * //=>
      + * //
    • + * //
      Apple
      + * //
    • + * //
    • + * //
      Orange
      + * //
    • + * //
    • + * //
      Pear
      + * //
    • + * //
    + * ``` + * + * @param wrapper - The DOM structure to wrap around the content of each element + * in the selection. + * @returns The instance itself, for chaining. + * @see {@link https://api.jquery.com/wrapInner/} */ - var romanize = function (num) { - if (isNaN(num)) - return NaN; - var digits = String(+num).split(""), - key = ["", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM", - "", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC", - "", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"], - roman = "", - i = 3; - while (i--) - roman = (key[+digits.pop() + (i * 10)] || "") + roman; - return Array(+digits.join("") + 1).join("M") + roman; - }; - + const wrapInner = _wrap((el, elInsertLocation, wrapperDom) => { + if (!hasChildren(el)) + return; + update(el.children, elInsertLocation); + update(wrapperDom, el); + }); /** - * Converts a decimal number to alphanumeric numeral. - * https://stackoverflow.com/questions/45787459/convert-number-to-alphabet-string-javascript + * The .unwrap() function, removes the parents of the set of matched elements + * from the DOM, leaving the matched elements in their place. * - * @param {Number} number - * @api private. - */ - var alphanumeric = function (num) { - var s = '', t; - - while (num > 0) { - t = (num - 1) % 26; - s = String.fromCharCode(65 + t) + s; - num = (num - t) / 26 | 0; - } - return s || undefined; - }; - - var numbers = { - romanize: romanize, - alphanumeric: alphanumeric - }; - - var inline = function makeJuiceClient(juiceClient) { - - juiceClient.ignoredPseudos = ['hover', 'active', 'focus', 'visited', 'link']; - juiceClient.widthElements = ['TABLE', 'TD', 'TH', 'IMG']; - juiceClient.heightElements = ['TABLE', 'TD', 'TH', 'IMG']; - juiceClient.tableElements = ['TABLE', 'TH', 'TR', 'TD', 'CAPTION', 'COLGROUP', 'COL', 'THEAD', 'TBODY', 'TFOOT']; - juiceClient.nonVisualElements = ['HEAD', 'TITLE', 'BASE', 'LINK', 'STYLE', 'META', 'SCRIPT', 'NOSCRIPT']; - juiceClient.styleToAttribute = { - 'background-color': 'bgcolor', - 'background-image': 'background', - 'text-align': 'align', - 'vertical-align': 'valign' - }; - juiceClient.excludedProperties = []; - - juiceClient.juiceDocument = juiceDocument; - juiceClient.inlineDocument = inlineDocument; - - function inlineDocument($, css, options) { - - options = options || {}; - var rules = utils.parseCSS(css); - var editedElements = []; - var styleAttributeName = 'style'; - var counters = {}; - - if (options.styleAttributeName) { - styleAttributeName = options.styleAttributeName; - } - - rules.forEach(handleRule); - editedElements.forEach(setStyleAttrs); - - if (options.inlinePseudoElements) { - editedElements.forEach(inlinePseudoElements); - } - - if (options.applyWidthAttributes) { - editedElements.forEach(function (el) { - setDimensionAttrs(el, 'width'); - }); - } - - if (options.applyHeightAttributes) { - editedElements.forEach(function (el) { - setDimensionAttrs(el, 'height'); - }); - } - - if (options.applyAttributesTableElements) { - editedElements.forEach(setAttributesOnTableElements); - } - - if (options.insertPreservedExtraCss && options.extraCss) { - var preservedText = utils.getPreservedText(options.extraCss, { - mediaQueries: options.preserveMediaQueries, - fontFaces: options.preserveFontFaces, - keyFrames: options.preserveKeyFrames - }); - if (preservedText) { - var $appendTo = null; - if (options.insertPreservedExtraCss !== true) { - $appendTo = $(options.insertPreservedExtraCss); - } else { - $appendTo = $('head'); - if (!$appendTo.length) { $appendTo = $('body'); } - if (!$appendTo.length) { $appendTo = $.root(); } - } - - $appendTo.first().append(''); - } - } - - function handleRule(rule) { - var sel = rule[0]; - var style = rule[1]; - var selector = new utils.Selector(sel); - var parsedSelector = selector.parsed(); - - if (!parsedSelector) { - return; - } - - var pseudoElementType = getPseudoElementType(parsedSelector); - - // skip rule if the selector has any pseudos which are ignored - for (var i = 0; i < parsedSelector.length; ++i) { - var subSel = parsedSelector[i]; - if (subSel.pseudos) { - for (var j = 0; j < subSel.pseudos.length; ++j) { - var subSelPseudo = subSel.pseudos[j]; - if (juiceClient.ignoredPseudos.indexOf(subSelPseudo.name) >= 0) { - return; - } - } - } - } - - if (pseudoElementType) { - var last = parsedSelector[parsedSelector.length - 1]; - var pseudos = last.pseudos; - last.pseudos = filterElementPseudos(last.pseudos); - sel = parsedSelector.toString(); - last.pseudos = pseudos; - } - - var els; - try { - els = $(sel); - } catch (err) { - // skip invalid selector - return; - } - - els.each(function () { - var el = this; - - if (el.name && juiceClient.nonVisualElements.indexOf(el.name.toUpperCase()) >= 0) { - return; - } - - if (pseudoElementType) { - var pseudoElPropName = 'pseudo' + pseudoElementType; - var pseudoEl = el[pseudoElPropName]; - if (!pseudoEl) { - pseudoEl = el[pseudoElPropName] = $('').get(0); - pseudoEl.pseudoElementType = pseudoElementType; - pseudoEl.pseudoElementParent = el; - pseudoEl.counterProps = el.counterProps; - el[pseudoElPropName] = pseudoEl; - } - el = pseudoEl; - } - - if (!el.styleProps) { - el.styleProps = {}; - - // if the element has inline styles, fake selector with topmost specificity - if ($(el).attr(styleAttributeName)) { - var cssText = '* { ' + $(el).attr(styleAttributeName) + ' } '; - addProps(utils.parseCSS(cssText)[0][1], new utils.Selector('"); - } - }, { - key: "computeStyle", - value: function computeStyle() { - // 计算需要append进富文本的style - var mathStyle = this.getStyleFromSheets('mjx-container'); - var cherryStyle = this.getStyleFromSheets('cherry'); - var echartStyle = ''; - return { - mathStyle: mathStyle, - echartStyle: echartStyle, - cherryStyle: cherryStyle - }; - } - /** - * 由于复制操作会随着预览区域的内容增加而耗时变长,所以需要增加“正在复制”的状态回显 - * 同时该状态也用于限频 - */ - - }, { - key: "toggleLoading", - value: function toggleLoading() { - // 切换loading状态 - if (this.isLoading) { - var loadingButton = document.querySelector('.icon-loading'); - loadingButton.outerHTML = ''; - } else { - var copyButton = document.querySelector('.ch-icon-copy'); - copyButton.outerHTML = '
    '; - } - - this.isLoading = !this.isLoading; - } - /** - * 响应点击事件 - * 该按钮不会引发编辑区域的内容改动,所以不用处理用户在编辑区域的选中内容 - * @param {Event} e 点击事件 - */ - - }, { - key: "onClick", - value: function onClick(e) { - var _this2 = this; - - this.toggleLoading(); - var inlineCodeTheme = document.querySelector('.cherry').getAttribute('data-inline-code-theme'); - var codeBlockTheme = document.querySelector('.cherry').getAttribute('data-code-block-theme'); - - var _this$computeStyle = this.computeStyle(), - mathStyle = _this$computeStyle.mathStyle, - echartStyle = _this$computeStyle.echartStyle, - cherryStyle = _this$computeStyle.cherryStyle; - - var html = this.previewer.isPreviewerHidden() ? this.previewer.options.previewerCache.html : this.previewer.getValue(); // 将css样式以行内样式的形式插入到html内容里 - - this.adaptWechat(html).then(function (html) { - var _context7, _context8, _context9; - - copyToClip(client(concat$5(_context7 = concat$5(_context8 = concat$5(_context9 = "
    \n
    ")).call(_context8, html, "
    \n
    ")).call(_context7, mathStyle + echartStyle + cherryStyle))); - - _this2.toggleLoading(); - }); - } - }]); - - return Copy; - }(MenuBase); - - function convertImgToBase64(url, callback, outputFormat) { - return new promise$7(function (resolve) { - var canvas = - /** @type {HTMLCanvasElement}*/ - document.createElement('CANVAS'); - var ctx = canvas.getContext('2d'); - var img = new Image(); - img.crossOrigin = 'Anonymous'; - - img.onload = function () { - canvas.height = img.height; - canvas.width = img.width; - ctx.drawImage(img, 0, 0); - var dataURL = canvas.toDataURL(outputFormat || 'image/png'); - resolve(dataURL); - canvas = null; - }; - - img.src = url; - }); + function after(...elems) { + const lastIdx = this.length - 1; + return domEach(this, (el, i) => { + const { parent } = el; + if (!hasChildren(el) || !parent) { + return; + } + const siblings = parent.children; + const index = siblings.indexOf(el); + // If not found, move on + /* istanbul ignore next */ + if (index < 0) + return; + const domSrc = typeof elems[0] === 'function' + ? elems[0].call(el, i, this._render(el.children)) + : elems; + const dom = this._makeDomArray(domSrc, i < lastIdx); + // Add element after `this` element + uniqueSplice(siblings, index + 1, 0, dom, parent); + }); } - - function _createSuper$1j(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$1j(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = construct$4(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } - - function _isNativeReflectConstruct$1j() { if (typeof Reflect === "undefined" || !construct$4) return false; if (construct$4.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(construct$4(Boolean, [], function () { })); return true; } catch (e) { return false; } } + /* eslint-enable jsdoc/check-param-names*/ /** - * 插入面板 + * Insert every element in the set of matched elements after the target. + * + * @category Manipulation + * @example + * + * ```js + * $('
  • Plum
  • ').insertAfter('.apple'); + * $.html(); + * //=>
      + * //
    • Apple
    • + * //
    • Plum
    • + * //
    • Orange
    • + * //
    • Pear
    • + * //
    + * ``` + * + * @param target - Element to insert elements after. + * @returns The set of newly inserted elements. + * @see {@link https://api.jquery.com/insertAfter/} */ - - var Panel$1 = /*#__PURE__*/function (_MenuBase) { - _inherits(Panel, _MenuBase); - - var _super = _createSuper$1j(Panel); - - function Panel($cherry) { - var _context, _context2, _context3, _context4, _context5; - - var _this; - - _classCallCheck(this, Panel); - - _this = _super.call(this, $cherry); - - _this.setName('panel', 'tips'); - - _this.panelRule = getPanelRule().reg; - _this.subMenuConfig = [{ - iconName: 'tips', - name: 'tips', - onclick: bind$5(_context = _this.bindSubClick).call(_context, _assertThisInitialized(_this), 'primary') - }, { - iconName: 'info', - name: 'info', - onclick: bind$5(_context2 = _this.bindSubClick).call(_context2, _assertThisInitialized(_this), 'info') - }, { - iconName: 'warning', - name: 'warning', - onclick: bind$5(_context3 = _this.bindSubClick).call(_context3, _assertThisInitialized(_this), 'warning') - }, { - iconName: 'danger', - name: 'danger', - onclick: bind$5(_context4 = _this.bindSubClick).call(_context4, _assertThisInitialized(_this), 'danger') - }, { - iconName: 'success', - name: 'success', - onclick: bind$5(_context5 = _this.bindSubClick).call(_context5, _assertThisInitialized(_this), 'success') - }]; - return _this; - } - /** - * 从字符串中找打面板的name - * @param {string} str - * @returns {string | false} - */ - - - _createClass(Panel, [{ - key: "$getNameFromStr", - value: function $getNameFromStr(str) { - var ret = false; - this.panelRule.lastIndex = 0; - str.replace(this.panelRule, function (match, preLines, name, content) { - var $name = /\s/.test(trim$3(name).call(name)) ? trim$3(name).call(name).replace(/\s.*$/, '') : name; - ret = $name ? trim$3($name).call($name).toLowerCase() : ''; - return match; - }); - return ret; - } - }, { - key: "$getTitle", - value: function $getTitle(str) { - this.panelRule.lastIndex = 0; - str.replace(this.panelRule, function (match, preLines, name, content) { - var $name = trim$3(name).call(name); - - return /\s/.test($name) ? $name.replace(/[^\s]+\s/, '') : ''; - }); - return ''; - } - /** - * 响应点击事件 - * @param {string} selection 被用户选中的文本内容 - * @param {string} shortKey 快捷键参数 - * @returns {string} 回填到编辑器光标位置/选中文本区域的内容 - */ - - }, { - key: "onClick", - value: function onClick(selection) { - var _this2 = this, - _context9, - _context10; - - var shortKey = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; - var $selection = getSelection(this.editor.editor, selection, 'line', true) || '内容'; - var currentName = this.$getNameFromStr($selection); - var title = this.$getTitle($selection); - - if (currentName === false) { - // 如果没有命中面板语法,则尝试扩大选区 - this.getMoreSelection('::: ', '\n', function () { - var newSelection = _this2.editor.editor.getSelection(); - - var isMatch = _this2.$getNameFromStr(newSelection); - - if (isMatch !== false) { - $selection = newSelection; - currentName = isMatch; - title = _this2.$getTitle(newSelection); - } - - return isMatch !== false; - }); - } - - if (currentName !== false) { - // 如果命中了面板语法,则尝试去掉语法或者变更语法 - if (currentName === shortKey) { - // 去掉面板语法 - this.panelRule.lastIndex = 0; - return $selection.replace(this.panelRule, function (match, preLines, name, content) { - var _context6; - - var $name = trim$3(name).call(name); - - var $title = /\s/.test($name) ? $name.replace(/[^\s]+\s/, '') : ''; - return concat$5(_context6 = "".concat($title, "\n")).call(_context6, content); - }); - } // 修改name - - - this.registerAfterClickCb(function () { - _this2.setLessSelection('::: ', '\n'); - }); - this.panelRule.lastIndex = 0; - return $selection.replace(this.panelRule, function (match, preLines, name, content) { - var _context7, _context8; - - var $name = trim$3(name).call(name); - - var $title = /\s/.test($name) ? $name.replace(/[^\s]+\s/, '') : ''; - return concat$5(_context7 = concat$5(_context8 = "::: ".concat(shortKey, " ")).call(_context8, $title, "\n")).call(_context7, content.replace(/\n+$/, ''), "\n:::"); - }); - } - - this.registerAfterClickCb(function () { - _this2.setLessSelection('::: ', '\n'); - }); - $selection = $selection.replace(/^\n+/, ''); - - if (/\n/.test($selection)) { - if (!title) { - title = $selection.replace(/\n[\w\W]+$/, ''); - $selection = $selection.replace(/^[^\n]+\n/, ''); - } - } else { - title = title ? title : '标题'; - } - - return concat$5(_context9 = concat$5(_context10 = "::: ".concat(shortKey, " ")).call(_context10, title, "\n")).call(_context9, $selection, "\n:::").replace(/\n{2,}:::/g, '\n:::'); - } - }]); - - return Panel; - }(MenuBase); - - function _createSuper$1k(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$1k(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = construct$4(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } - - function _isNativeReflectConstruct$1k() { if (typeof Reflect === "undefined" || !construct$4) return false; if (construct$4.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(construct$4(Boolean, [], function () { })); return true; } catch (e) { return false; } } + function insertAfter(target) { + if (typeof target === 'string') { + target = this._make(target); + } + this.remove(); + const clones = []; + this._makeDomArray(target).forEach((el) => { + const clonedSelf = this.clone().toArray(); + const { parent } = el; + if (!parent) { + return; + } + const siblings = parent.children; + const index = siblings.indexOf(el); + // If not found, move on + /* istanbul ignore next */ + if (index < 0) + return; + // Add cloned `this` element(s) after target element + uniqueSplice(siblings, index + 1, 0, clonedSelf, parent); + clones.push(...clonedSelf); + }); + return this._make(clones); + } + /* eslint-disable jsdoc/check-param-names*/ /** - * 插入手风琴 - */ - - var Detail$1 = /*#__PURE__*/function (_MenuBase) { - _inherits(Detail, _MenuBase); - - var _super = _createSuper$1k(Detail); - - function Detail($cherry) { - var _this; - - _classCallCheck(this, Detail); - - _this = _super.call(this, $cherry); - - _this.setName('detail', 'insertFlow'); - - _this.detailRule = getDetailRule().reg; - return _this; - } - /** - * 响应点击事件 - * @param {string} selection 被用户选中的文本内容 - * @returns {string} 回填到编辑器光标位置/选中文本区域的内容 - */ - - - _createClass(Detail, [{ - key: "onClick", - value: function onClick(selection) { - var _this2 = this; - - var $selection = getSelection(this.editor.editor, selection, 'line', true) || '点击展开更多\n内容\n++- 默认展开\n内容\n++ 默认收起\n内容'; - this.detailRule.lastIndex = 0; - - if (!this.detailRule.test($selection)) { - // 如果没有命中手风琴语法,则尝试扩大选区 - this.getMoreSelection('+++ ', '\n', function () { - var newSelection = _this2.editor.editor.getSelection(); - - _this2.detailRule.lastIndex = 0; - - var isMatch = _this2.detailRule.test(newSelection); - - if (isMatch !== false) { - $selection = newSelection; - } - - return isMatch !== false; - }); - } - - this.detailRule.lastIndex = 0; - - if (this.detailRule.test($selection)) { - // 如果命中了手风琴语法,则去掉手风琴语法 - this.detailRule.lastIndex = 0; - return $selection.replace(this.detailRule, function (match, preLines, isOpen, title, content) { - var _context; - - return concat$5(_context = "".concat(title, "\n")).call(_context, content); - }); - } // 去掉开头的空格 - - - $selection = $selection.replace(/^\s+/, ''); // 如果选中的内容不包含换行,则强制增加一个换行 - - if (!/\n/.test($selection)) { - var _context2; - - $selection = concat$5(_context2 = "".concat($selection, "\n")).call(_context2, $selection); - } - - this.registerAfterClickCb(function () { - _this2.setLessSelection('+++ ', '\n'); - }); - return "+++ ".concat($selection, "\n+++").replace(/\n{2,}\+\+\+/g, '\n+++'); - } - }]); - - return Detail; - }(MenuBase); - - function _createSuper$1l(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$1l(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = construct$4(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } - - function _isNativeReflectConstruct$1l() { if (typeof Reflect === "undefined" || !construct$4) return false; if (construct$4.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(construct$4(Boolean, [], function () { })); return true; } catch (e) { return false; } } + * Insert content previous to each element in the set of matched elements. + * + * @category Manipulation + * @example + * + * ```js + * $('.apple').before('
  • Plum
  • '); + * $.html(); + * //=>
      + * //
    • Plum
    • + * //
    • Apple
    • + * //
    • Orange
    • + * //
    • Pear
    • + * //
    + * ``` + * + * @param content - HTML string, DOM element, array of DOM elements or Cheerio + * to insert before each element in the set of matched elements. + * @returns The instance itself. + * @see {@link https://api.jquery.com/before/} + */ + function before(...elems) { + const lastIdx = this.length - 1; + return domEach(this, (el, i) => { + const { parent } = el; + if (!hasChildren(el) || !parent) { + return; + } + const siblings = parent.children; + const index = siblings.indexOf(el); + // If not found, move on + /* istanbul ignore next */ + if (index < 0) + return; + const domSrc = typeof elems[0] === 'function' + ? elems[0].call(el, i, this._render(el.children)) + : elems; + const dom = this._makeDomArray(domSrc, i < lastIdx); + // Add element before `el` element + uniqueSplice(siblings, index, 0, dom, parent); + }); + } + /* eslint-enable jsdoc/check-param-names*/ /** - * 打开draw.io画图对话框,点击确定后向编辑器插入图片语法 + * Insert every element in the set of matched elements before the target. + * + * @category Manipulation + * @example + * + * ```js + * $('
  • Plum
  • ').insertBefore('.apple'); + * $.html(); + * //=>
      + * //
    • Plum
    • + * //
    • Apple
    • + * //
    • Orange
    • + * //
    • Pear
    • + * //
    + * ``` + * + * @param target - Element to insert elements before. + * @returns The set of newly inserted elements. + * @see {@link https://api.jquery.com/insertBefore/} */ - - var DrawIo = /*#__PURE__*/function (_MenuBase) { - _inherits(DrawIo, _MenuBase); - - var _super = _createSuper$1l(DrawIo); - - function DrawIo($cherry) { - var _this; - - _classCallCheck(this, DrawIo); - - _this = _super.call(this, $cherry); - - _this.setName('draw.io', 'draw.io'); - - _this.noIcon = true; - _this.drawioIframeUrl = $cherry.options.drawioIframeUrl; - return _this; - } - /** - * 响应点击事件 - * @param {string} selection 被用户选中的文本内容 - * @param {string} shortKey 快捷键参数,本函数不处理这个参数 - * @returns {string} 回填到编辑器光标位置/选中文本区域的内容 - */ - - - _createClass(DrawIo, [{ - key: "onClick", - value: function onClick(selection) { - var _this2 = this; - - if (!this.drawioIframeUrl) { - // 如果没有配置drawio的编辑页URL,则直接失效 - return selection; - } - - if (this.hasCacheOnce()) { - var _context; - - // @ts-ignore - var _this$getAndCleanCach = this.getAndCleanCacheOnce(), - xmlData = _this$getAndCleanCach.xmlData, - base64 = _this$getAndCleanCach.base64; - - var begin = '!['; - - var end = concat$5(_context = "](".concat(base64, "){data-type=drawio data-xml=")).call(_context, encodeURI(xmlData), "}"); - - this.registerAfterClickCb(function () { - _this2.setLessSelection(begin, end); - }); - return "".concat(begin, "\u5728\u9884\u89C8\u533A\u70B9\u51FB\u56FE\u7247\u91CD\u65B0\u7F16\u8F91draw.io").concat(end); - } // 插入图片,调用上传文件逻辑 - - - drawioDialog(this.drawioIframeUrl, '', function (data) { - _this2.setCacheOnce(data); - - _this2.fire(null); - }); - this.updateMarkdown = false; - return selection; - } - }]); - - return DrawIo; - }(MenuBase); - - // 目前不支持按需动态加载 - // 如果对CherryMarkdown构建后的文件大小有比较严格的要求,可以根据实际情况删减hook - - var HookList = { - bold: Bold, - italic: Italic, - '|': Split, - strikethrough: Strikethrough$1, - sub: Sub$1, - sup: Sup$1, - header: Header$1, - insert: Insert, - list: List$1, - ol: Ol, - ul: Ul, - checklist: Checklist, - graph: Graph, - size: Size$1, - h1: H1, - h2: H2, - h3: H3, - color: Color$1, - quote: Quote, - quickTable: QuickTable, - togglePreview: TogglePreview, - code: Code, - codeTheme: CodeTheme, - "export": Export, - settings: Settings, - fullScreen: FullScreen, - mobilePreview: MobilePreview, - copy: Copy, - undo: Undo, - redo: Redo, - underline: Underline$1, - switchModel: SwitchModel, - image: Image$2, - audio: Audio, - video: Video, - br: Br$1, - hr: Hr$1, - formula: Formula, - link: Link$1, - table: Table$1, - toc: Toc$1, - lineTable: LineTable, - barTable: BrTable, - pdf: Pdf, - word: Word, - ruby: Ruby$1, - theme: Theme, - file: File, - panel: Panel$1, - detail: Detail$1, - drawIo: DrawIo - }; - - var HookCenter$1 = /*#__PURE__*/function () { - function HookCenter(toolbar) { - _classCallCheck(this, HookCenter); - - this.toolbar = toolbar; - /** - * @type {{[key: string]: import('@/toolbars/MenuBase').default}} 保存所有菜单实例 - */ - - this.hooks = {}; - /** - * @type {string[]} 所有注册的菜单名称 - */ - - this.allMenusName = []; - /** - * @type {string[]} 一级菜单的名称 - */ - - this.level1MenusName = []; - /** - * @type {{ [parentName: string]: string[]}} 二级菜单的名称, e.g. {一级菜单名称: [二级菜单名称1, 二级菜单名称2]} - */ - - this.level2MenusName = {}; - this.init(); - } - - _createClass(HookCenter, [{ - key: "$newMenu", - value: function $newMenu(name) { - if (this.hooks[name]) { - return; - } - - var _this$toolbar$options = this.toolbar.options, - $cherry = _this$toolbar$options.$cherry, - customMenu = _this$toolbar$options.customMenu; - - if (HookList[name]) { - this.allMenusName.push(name); - this.hooks[name] = new HookList[name]($cherry); - } else if (customMenu !== undefined && customMenu !== null && customMenu[name]) { - this.allMenusName.push(name); // 如果是自定义菜单,传参兼容旧版 - - this.hooks[name] = new customMenu[name]($cherry); - } - } - /** - * 根据配置动态渲染、绑定工具栏 - * @returns - */ - - }, { - key: "init", - value: function init() { - var _this = this; - - var buttonConfig = this.toolbar.options.buttonConfig; - - forEach$3(buttonConfig).call(buttonConfig, function (item) { - if (typeof item === 'string') { - _this.level1MenusName.push(item); - - _this.$newMenu(item); - } else if (_typeof(item) === 'object') { - var keys = keys$3(item); - - if (keys.length === 1) { - var _context; - - // 只接受形如{ name: [ subMenu ] }的参数 - var _keys = _slicedToArray(keys, 1), - name = _keys[0]; - - _this.level1MenusName.push(name); - - _this.$newMenu(name); - - _this.level2MenusName[name] = item[name]; - - forEach$3(_context = item[name]).call(_context, function (subItem) { - _this.$newMenu(subItem); - }); - } - } - }); - } - }]); - - return HookCenter; - }(); - - var Toolbar = /*#__PURE__*/function () { - /** - * @type {Record} 外部获取 toolbarHandler - */ - function Toolbar(options) { - _classCallCheck(this, Toolbar); - - _defineProperty(this, "toolbarHandlers", {}); - - // 存储所有菜单的实例 - this.menus = {}; // 存储所有快捷键的影射 {快捷键: 菜单名称} - - this.shortcutKeyMap = {}; // 存储所有二级菜单面板 - - this.subMenus = {}; // 默认的菜单配置 - - this.options = { - dom: document.createElement('div'), - buttonConfig: ['bold'], - customMenu: [] - }; - - assign$2(this.options, options); - - this.$cherry = this.options.$cherry; - this.instanceId = this.$cherry.instanceId; - this.menus = new HookCenter$1(this); - this.drawMenus(); - this.init(); - } - - _createClass(Toolbar, [{ - key: "init", - value: function init() { - var _this = this; - - this.collectShortcutKey(); - this.collectToolbarHandler(); - Event$1.on(this.instanceId, Event$1.Events.cleanAllSubMenus, function () { - return _this.hideAllSubMenu(); - }); - } - }, { - key: "previewOnly", - value: function previewOnly() { - this.options.dom.classList.add('preview-only'); - Event$1.emit(this.instanceId, Event$1.Events.toolbarHide); - } - }, { - key: "showToolbar", - value: function showToolbar() { - this.options.dom.classList.remove('preview-only'); - Event$1.emit(this.instanceId, Event$1.Events.toolbarShow); - } - }, { - key: "isHasLevel2Menu", - value: function isHasLevel2Menu(name) { - // FIXME: return boolean - return this.menus.level2MenusName[name]; - } - }, { - key: "isHasConfigMenu", - value: function isHasConfigMenu(name) { - // FIXME: return boolean - return this.menus.hooks[name].subMenuConfig || []; - } - /** - * 判断是否有子菜单,目前有两种子菜单配置方式:1、通过`subMenuConfig`属性 2、通过`buttonConfig`配置属性 - * @param {string} name - * @returns {boolean} 是否有子菜单 - */ - - }, { - key: "isHasSubMenu", - value: function isHasSubMenu(name) { - return Boolean(this.isHasLevel2Menu(name) || this.isHasConfigMenu(name).length > 0); - } - /** - * 根据配置画出来一级工具栏 - */ - - }, { - key: "drawMenus", - value: function drawMenus() { - var _context, - _this2 = this; - - var frag = document.createDocumentFragment(); - - forEach$3(_context = this.menus.level1MenusName).call(_context, function (name) { - var btn = _this2.menus.hooks[name].createBtn(); - - btn.addEventListener('click', function (event) { - _this2.onClick(event, name); - }, false); - - if (_this2.isHasSubMenu(name)) { - btn.classList.add('cherry-toolbar-dropdown'); - } - - frag.appendChild(btn); - }); - - this.options.dom.appendChild(frag); - } - }, { - key: "drawSubMenus", - value: function drawSubMenus(name) { - var _this3 = this; - - var menu = this.menus.hooks[name]; - var pos = menu.getMenuPosition(); - this.subMenus[name] = createElement('div', 'cherry-dropdown', { - name: name - }); - this.subMenus[name].style.left = "".concat(pos.left + pos.width / 2, "px"); - this.subMenus[name].style.top = "".concat(pos.top + pos.height, "px"); - this.subMenus[name].style.position = menu.positionModel; // 如果有配置的二级菜单 - - var level2MenusName = this.isHasLevel2Menu(name); - - if (level2MenusName) { - forEach$3(level2MenusName).call(level2MenusName, function (level2Name) { - var subMenu = _this3.menus.hooks[level2Name]; - - if (subMenu !== undefined && typeof subMenu.createBtn === 'function') { - var btn = subMenu.createBtn(true); // 二级菜单的dom认定为一级菜单的 - - subMenu.dom = subMenu.dom ? subMenu.dom : _this3.menus.hooks[name].dom; - btn.addEventListener('click', function (event) { - return _this3.onClick(event, level2Name, true); - }, false); - - _this3.subMenus[name].appendChild(btn); - } - }); - } // 兼容旧版本配置的二级菜单 - - - var subMenuConfig = this.isHasConfigMenu(name); - - if (subMenuConfig.length > 0) { - forEach$3(subMenuConfig).call(subMenuConfig, function (config) { - var btn = _this3.menus.hooks[name].createSubBtnByConfig(config); - - btn.addEventListener('click', function () { - return _this3.hideAllSubMenu(); - }, false); - - _this3.subMenus[name].appendChild(btn); - }); - } - - this.$cherry.wrapperDom.appendChild(this.subMenus[name]); - } - /** - * 处理点击事件 - */ - - }, { - key: "onClick", - value: function onClick(event, name) { - var focusEvent = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; - var menu = this.menus.hooks[name]; - - if (!menu) { - return; - } - - if (this.isHasSubMenu(name) && !focusEvent) { - this.toggleSubMenu(name); - } else { - this.hideAllSubMenu(); - menu.fire(event, name); - } - } - /** - * 展开/收起二级菜单 - */ - - }, { - key: "toggleSubMenu", - value: function toggleSubMenu(name) { - if (!this.subMenus[name]) { - // 如果没有二级菜单,则先画出来,然后再显示 - this.hideAllSubMenu(); - this.drawSubMenus(name); - this.subMenus[name].style.display = 'block'; - return; - } - - if (this.subMenus[name].style.display === 'none') { - // 如果是隐藏的,则先隐藏所有二级菜单,再显示当前二级菜单 - this.hideAllSubMenu(); - this.subMenus[name].style.display = 'block'; - } else { - // 如果是显示的,则隐藏当前二级菜单 - this.subMenus[name].style.display = 'none'; - } - } - /** - * 隐藏所有的二级菜单 - */ - - }, { - key: "hideAllSubMenu", - value: function hideAllSubMenu() { - var _context2; - - forEach$3(_context2 = this.$cherry.wrapperDom.querySelectorAll('.cherry-dropdown')).call(_context2, function (dom) { - dom.style.display = 'none'; - }); - } - /** - * 收集快捷键 - */ - - }, { - key: "collectShortcutKey", - value: function collectShortcutKey() { - var _context3, - _this4 = this; - - forEach$3(_context3 = this.menus.allMenusName).call(_context3, function (name) { - var _this4$menus$hooks$na; - - (_this4$menus$hooks$na = _this4.menus.hooks[name].shortcutKeys) === null || _this4$menus$hooks$na === void 0 ? void 0 : forEach$3(_this4$menus$hooks$na).call(_this4$menus$hooks$na, function (key) { - _this4.shortcutKeyMap[key] = name; - }); - }); - } - }, { - key: "collectToolbarHandler", - value: function collectToolbarHandler() { - var _context4, - _this5 = this; - - this.toolbarHandlers = reduce$3(_context4 = this.menus.allMenusName).call(_context4, function (handlerMap, name) { - var menuHook = _this5.menus.hooks[name]; - - if (!menuHook) { - return handlerMap; - } - - handlerMap[name] = function (shortcut, _callback) { - if (typeof _callback === 'function') { - Logger.warn('MenuBase#onClick param callback is no longer supported. Please register the callback via MenuBase#registerAfterClickCb instead.'); - } - - menuHook.fire.call(menuHook, undefined, shortcut); - }; - - return handlerMap; - }, {}); - } - /** - * 监测是否有对应的快捷键 - * @param {KeyboardEvent} evt keydown 事件 - * @returns {boolean} 是否有对应的快捷键 - */ - - }, { - key: "matchShortcutKey", - value: function matchShortcutKey(evt) { - return !!this.shortcutKeyMap[this.getCurrentKey(evt)]; - } - /** - * 触发对应快捷键的事件 - * @param {KeyboardEvent} evt - */ - - }, { - key: "fireShortcutKey", - value: function fireShortcutKey(evt) { - var _this$menus$hooks$thi; - - var currentKey = this.getCurrentKey(evt); - (_this$menus$hooks$thi = this.menus.hooks[this.shortcutKeyMap[currentKey]]) === null || _this$menus$hooks$thi === void 0 ? void 0 : _this$menus$hooks$thi.fire(evt, currentKey); - } - /** - * 格式化当前按键,mac下的command按键转换为ctrl - * @param {KeyboardEvent} event - * @returns - */ - - }, { - key: "getCurrentKey", - value: function getCurrentKey(event) { - var key = ''; - - if (event.ctrlKey) { - key += 'Ctrl-'; - } - - if (event.altKey) { - key += 'Alt-'; - } - - if (event.metaKey && mac) { - key += 'Ctrl-'; - } // 如果存在shift键 - - - if (event.shiftKey) { - key += "Shift-"; - } // 如果还有第三个键 且不是 shift键 - - - if (event.key && event.key.toLowerCase() !== 'shift') { - key += event.key.toLowerCase(); - } - - return key; - } - }]); - - return Toolbar; - }(); - - function _createSuper$1m(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$1m(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = construct$4(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } - - function _isNativeReflectConstruct$1m() { if (typeof Reflect === "undefined" || !construct$4) return false; if (construct$4.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(construct$4(Boolean, [], function () { })); return true; } catch (e) { return false; } } + function insertBefore(target) { + const targetArr = this._make(target); + this.remove(); + const clones = []; + domEach(targetArr, (el) => { + const clonedSelf = this.clone().toArray(); + const { parent } = el; + if (!parent) { + return; + } + const siblings = parent.children; + const index = siblings.indexOf(el); + // If not found, move on + /* istanbul ignore next */ + if (index < 0) + return; + // Add cloned `this` element(s) after target element + uniqueSplice(siblings, index, 0, clonedSelf, parent); + clones.push(...clonedSelf); + }); + return this._make(clones); + } + /** + * Removes the set of matched elements from the DOM and all their children. + * `selector` filters the set of matched elements to be removed. + * + * @category Manipulation + * @example + * + * ```js + * $('.pear').remove(); + * $.html(); + * //=>
      + * //
    • Apple
    • + * //
    • Orange
    • + * //
    + * ``` + * + * @param selector - Optional selector for elements to remove. + * @returns The instance itself. + * @see {@link https://api.jquery.com/remove/} + */ + function remove$1(selector) { + // Filter if we have selector + const elems = selector ? this.filter(selector) : this; + domEach(elems, (el) => { + removeElement(el); + el.prev = el.next = el.parent = null; + }); + return this; + } /** - * 在编辑区域选中文本时浮现的bubble工具栏 + * Replaces matched elements with `content`. + * + * @category Manipulation + * @example + * + * ```js + * const plum = $('
  • Plum
  • '); + * $('.pear').replaceWith(plum); + * $.html(); + * //=>
      + * //
    • Apple
    • + * //
    • Orange
    • + * //
    • Plum
    • + * //
    + * ``` + * + * @param content - Replacement for matched elements. + * @returns The instance itself. + * @see {@link https://api.jquery.com/replaceWith/} */ + function replaceWith(content) { + return domEach(this, (el, i) => { + const { parent } = el; + if (!parent) { + return; + } + const siblings = parent.children; + const cont = typeof content === 'function' ? content.call(el, i, el) : content; + const dom = this._makeDomArray(cont); + /* + * In the case that `dom` contains nodes that already exist in other + * structures, ensure those nodes are properly removed. + */ + update(dom, null); + const index = siblings.indexOf(el); + // Completely remove old element + uniqueSplice(siblings, index, 1, dom, parent); + if (!dom.includes(el)) { + el.parent = el.prev = el.next = null; + } + }); + } + /** + * Empties an element, removing all its children. + * + * @category Manipulation + * @example + * + * ```js + * $('ul').empty(); + * $.html(); + * //=>
      + * ``` + * + * @returns The instance itself. + * @see {@link https://api.jquery.com/empty/} + */ + function empty$1() { + return domEach(this, (el) => { + if (!hasChildren(el)) + return; + el.children.forEach((child) => { + child.next = child.prev = child.parent = null; + }); + el.children.length = 0; + }); + } + function html$2(str) { + if (str === undefined) { + const el = this[0]; + if (!el || !hasChildren(el)) + return null; + return this._render(el.children); + } + return domEach(this, (el) => { + if (!hasChildren(el)) + return; + el.children.forEach((child) => { + child.next = child.prev = child.parent = null; + }); + const content = isCheerio(str) + ? str.toArray() + : this._parse(`${str}`, this.options, false, el).children; + update(content, el); + }); + } + /** + * Turns the collection to a string. Alias for `.html()`. + * + * @category Manipulation + * @returns The rendered document. + */ + function toString$5() { + return this._render(this); + } + function text$1(str) { + // If `str` is undefined, act as a "getter" + if (str === undefined) { + return text(this); + } + if (typeof str === 'function') { + // Function support + return domEach(this, (el, i) => this._make(el).text(str.call(el, i, text([el])))); + } + // Append text node to each selected elements + return domEach(this, (el) => { + if (!hasChildren(el)) + return; + el.children.forEach((child) => { + child.next = child.prev = child.parent = null; + }); + const textNode = new Text$1(`${str}`); + update(textNode, el); + }); + } + /** + * Clone the cheerio object. + * + * @category Manipulation + * @example + * + * ```js + * const moreFruit = $('#fruits').clone(); + * ``` + * + * @returns The cloned object. + * @see {@link https://api.jquery.com/clone/} + */ + function clone() { + return this._make(cloneDom(this.get())); + } - var Bubble = /*#__PURE__*/function (_Toolbar) { - _inherits(Bubble, _Toolbar); - - var _super = _createSuper$1m(Bubble); - - function Bubble() { - _classCallCheck(this, Bubble); - - return _super.apply(this, arguments); - } - - _createClass(Bubble, [{ - key: "visible", - get: function get() { - var bubbleStyle = window.getComputedStyle(this.bubbleDom); - return bubbleStyle.display !== 'none' && bubbleStyle.visibility !== 'hidden'; - }, - set: - /** - * @type {'flex' | 'block'} - */ - // constructor(options) { - // super(options); - // } - function set(visible) { - var bubbleStyle = window.getComputedStyle(this.bubbleDom); - - if (visible) { - bubbleStyle.display === 'none' && (this.bubbleDom.style.display = Bubble.displayType); // bubbleStyle.visibility !== 'visible' && (this.bubbleBottom.style.visibility = 'visible'); - } else { - bubbleStyle.display !== 'none' && (this.bubbleDom.style.display = 'none'); // bubbleStyle.visibility !== 'hidden' && (this.bubbleBottom.style.visibility = 'hidden'); - } - } - }, { - key: "init", - value: function init() { - this.options.editor = this.$cherry.editor; - this.addSelectionChangeListener(); - this.bubbleDom = this.options.dom; - this.editorDom = this.options.editor.getEditorDom(); - this.initBubbleDom(); - this.editorDom.querySelector('.CodeMirror').appendChild(this.bubbleDom); - } - /** - * 计算编辑区域的偏移量 - * @returns {number} 编辑区域的滚动区域 - */ - - }, { - key: "getScrollTop", - value: function getScrollTop() { - return this.options.editor.editor.getScrollInfo().top; - } - /** - * 当编辑区域滚动的时候自动隐藏bubble工具栏和子工具栏 - */ - - }, { - key: "updatePositionWhenScroll", - value: function updatePositionWhenScroll() { - if (this.bubbleDom.style.display === Bubble.displayType) { - this.bubbleDom.style.marginTop = "".concat(_parseFloat$2(this.bubbleDom.dataset.scrollTop) - this.getScrollTop(), "px"); - } - } - /** - * 根据高度计算bubble工具栏出现的位置的高度 - * 根据宽度计算bubble工具栏出现的位置的left值,以及bubble工具栏三角箭头的left值 - * @param {number} top 高度 - * @param {number} width 选中文本内容的宽度 - */ - - }, { - key: "showBubble", - value: function showBubble(top, width) { - if (!this.visible) { - this.visible = true; - this.bubbleDom.style.marginTop = '0'; - this.bubbleDom.dataset.scrollTop = String(this.getScrollTop()); - } - - var positionLimit = this.editorDom.querySelector('.CodeMirror-lines').firstChild.getBoundingClientRect(); - var editorPosition = this.editorDom.getBoundingClientRect(); - var minLeft = positionLimit.left - editorPosition.left; - var maxLeft = positionLimit.width + minLeft; - var minTop = this.bubbleDom.offsetHeight * 2; - var $top = top; - - if ($top < minTop) { - // 如果高度小于编辑器的顶部,则让bubble工具栏出现在选中文本的下放 - $top += this.bubbleDom.offsetHeight - this.bubbleTop.getBoundingClientRect().height; - this.bubbleTop.style.display = 'block'; - this.bubbleBottom.style.display = 'none'; - } else { - // 反之出现在选中文本内容的上方 - $top -= this.bubbleDom.offsetHeight + 2 * this.bubbleBottom.getBoundingClientRect().height; - this.bubbleTop.style.display = 'none'; - this.bubbleBottom.style.display = 'block'; - } - - this.bubbleDom.style.top = "".concat($top, "px"); - var left = width - this.bubbleDom.offsetWidth / 2; - - if (left < minLeft) { - // 如果位置超过了编辑器的最左边,则控制bubble工具栏不超出编辑器最左边 - // 同时bubble工具栏上的箭头尽量指向选中文本内容的中间位置 - left = minLeft; - this.$setBubbleCursorPosition("".concat(width - minLeft, "px")); - } else if (left + this.bubbleDom.offsetWidth > maxLeft) { - // 如果位置超过了编辑器的最右边,则控制bubble工具栏不超出编辑器最右边 - // 同时bubble工具栏上的箭头尽量指向选中文本内容的中间位置 - left = maxLeft - this.bubbleDom.offsetWidth; - this.$setBubbleCursorPosition("".concat(width - left, "px")); - } else { - // 让bubble工具栏的箭头处于工具栏的中间位置 - this.$setBubbleCursorPosition('50%'); - } // 安全边距 20px - - - this.bubbleDom.style.left = "".concat(Math.max(20, left), "px"); - } - }, { - key: "hideBubble", - value: function hideBubble() { - this.visible = false; - } - /** - * 控制bubble工具栏的箭头的位置 - * @param {string} left 左偏移量 - */ - - }, { - key: "$setBubbleCursorPosition", - value: function $setBubbleCursorPosition() { - var left = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '50%'; - - if (left === '50%') { - this.bubbleTop.style.left = '50%'; - this.bubbleBottom.style.left = '50%'; - } else { - var $left = _parseFloat$2(left) < 10 ? '10px' : left; - this.bubbleTop.style.left = $left; - this.bubbleBottom.style.left = $left; - } - } - }, { - key: "initBubbleDom", - value: function initBubbleDom() { - var top = document.createElement('div'); - top.className = 'cherry-bubble-top'; - var bottom = document.createElement('div'); - bottom.className = 'cherry-bubble-bottom'; - this.bubbleTop = top; - this.bubbleBottom = bottom; - this.bubbleDom.appendChild(top); - this.bubbleDom.appendChild(bottom); // 默认不可见 - - this.visible = false; - } - }, { - key: "getBubbleDom", - value: function getBubbleDom() { - return this.bubbleDom; - } - }, { - key: "addSelectionChangeListener", - value: function addSelectionChangeListener() { - var _this = this; - - this.options.editor.addListener('change', function (codemirror) { - // 当编辑区内容变更时自动隐藏bubble工具栏 - _this.hideBubble(); - }); - this.options.editor.addListener('refresh', function (codemirror) { - // 当编辑区内容刷新时自动隐藏bubble工具栏 - _this.hideBubble(); - }); - this.options.editor.addListener('scroll', function (codemirror) { - // 当编辑区滚动时,需要实时同步bubble工具栏的位置 - _this.updatePositionWhenScroll(); - }); - this.options.editor.addListener('beforeSelectionChange', function (codemirror, info) { - // 当编辑区选中内容改变时,需要展示/隐藏bubble工具栏,并计算工具栏位置 - if (info.origin !== '*mouse' && (info.origin !== null || typeof info.origin === 'undefined')) { - return true; - } - - if (!info.ranges[0]) { - return true; - } - - var anchor = info.ranges[0].anchor.line * 1000000 + info.ranges[0].anchor.ch; - var head = info.ranges[0].head.line * 1000000 + info.ranges[0].head.ch; - var direction = 'asc'; - - if (anchor > head) { - direction = 'desc'; - } - - setTimeout$3(function () { - var selections = codemirror.getSelections(); - - if (selections.join('').length <= 0) { - _this.hideBubble(); - - return; - } - - var selectedObjs = codemirror.getWrapperElement().getElementsByClassName('CodeMirror-selected'); - - var editorPosition = _this.editorDom.getBoundingClientRect(); - - var width = 0; - var top = 0; - - if (_typeof(selectedObjs) !== 'object' || selectedObjs.length <= 0) { - _this.hideBubble(); - - return; - } - - for (var key = 0; key < selectedObjs.length; key++) { - var one = selectedObjs[key]; - var position = one.getBoundingClientRect(); - var targetTop = position.top - editorPosition.top; - - if (direction === 'asc') { - if (targetTop >= top) { - top = targetTop; - width = position.left - editorPosition.left + position.width / 2; - } - } else { - if (targetTop <= top || top <= 0) { - top = targetTop; - width = position.left - editorPosition.left + position.width / 2; - } - } - } - - _this.showBubble(top, width); - }, 10); - }); - } - }]); - - return Bubble; - }(Toolbar); + var Manipulation = /*#__PURE__*/Object.freeze({ + __proto__: null, + _makeDomArray: _makeDomArray, + appendTo: appendTo, + prependTo: prependTo, + append: append$1, + prepend: prepend$1, + wrap: wrap$2, + wrapInner: wrapInner, + unwrap: unwrap, + wrapAll: wrapAll, + after: after, + insertAfter: insertAfter, + before: before, + insertBefore: insertBefore, + remove: remove$1, + replaceWith: replaceWith, + empty: empty$1, + html: html$2, + toString: toString$5, + text: text$1, + clone: clone + }); - _defineProperty(Bubble, "displayType", 'flex'); + /** + * Set multiple CSS properties for every matched element. + * + * @category CSS + * @param prop - The names of the properties. + * @param val - The new values. + * @returns The instance itself. + * @see {@link https://api.jquery.com/css/} + */ + function css(prop, val) { + if ((prop != null && val != null) || + // When `prop` is a "plain" object + (typeof prop === 'object' && !Array.isArray(prop))) { + return domEach(this, (el, i) => { + if (isTag$1(el)) { + // `prop` can't be an array here anymore. + setCss(el, prop, val, i); + } + }); + } + if (this.length === 0) { + return undefined; + } + return getCss(this[0], prop); + } + /** + * Set styles of all elements. + * + * @private + * @param el - Element to set style of. + * @param prop - Name of property. + * @param value - Value to set property to. + * @param idx - Optional index within the selection. + */ + function setCss(el, prop, value, idx) { + if (typeof prop === 'string') { + const styles = getCss(el); + const val = typeof value === 'function' ? value.call(el, idx, styles[prop]) : value; + if (val === '') { + delete styles[prop]; + } + else if (val != null) { + styles[prop] = val; + } + el.attribs['style'] = stringify$3(styles); + } + else if (typeof prop === 'object') { + Object.keys(prop).forEach((k, i) => { + setCss(el, k, prop[k], i); + }); + } + } + function getCss(el, prop) { + if (!el || !isTag$1(el)) + return; + const styles = parse$2(el.attribs['style']); + if (typeof prop === 'string') { + return styles[prop]; + } + if (Array.isArray(prop)) { + const newStyles = {}; + prop.forEach((item) => { + if (styles[item] != null) { + newStyles[item] = styles[item]; + } + }); + return newStyles; + } + return styles; + } + /** + * Stringify `obj` to styles. + * + * @private + * @category CSS + * @param obj - Object to stringify. + * @returns The serialized styles. + */ + function stringify$3(obj) { + return Object.keys(obj).reduce((str, prop) => `${str}${str ? ' ' : ''}${prop}: ${obj[prop]};`, ''); + } + /** + * Parse `styles`. + * + * @private + * @category CSS + * @param styles - Styles to be parsed. + * @returns The parsed styles. + */ + function parse$2(styles) { + styles = (styles || '').trim(); + if (!styles) + return {}; + const obj = {}; + let key; + for (const str of styles.split(';')) { + const n = str.indexOf(':'); + // If there is no :, or if it is the first/last character, add to the previous item's value + if (n < 1 || n === str.length - 1) { + const trimmed = str.trimEnd(); + if (trimmed.length > 0 && key !== undefined) { + obj[key] += `;${trimmed}`; + } + } + else { + key = str.slice(0, n).trim(); + obj[key] = str.slice(n + 1).trim(); + } + } + return obj; + } - function _createSuper$1n(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$1n(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = construct$4(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } + var Css = /*#__PURE__*/Object.freeze({ + __proto__: null, + css: css + }); - function _isNativeReflectConstruct$1n() { if (typeof Reflect === "undefined" || !construct$4) return false; if (construct$4.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(construct$4(Boolean, [], function () { })); return true; } catch (e) { return false; } } + /* + * https://github.com/jquery/jquery/blob/2.1.3/src/manipulation/var/rcheckableType.js + * https://github.com/jquery/jquery/blob/2.1.3/src/serialize.js + */ + const submittableSelector = 'input,select,textarea,keygen'; + const r20 = /%20/g; + const rCRLF = /\r?\n/g; /** - * 当光标处于编辑器新行起始位置时出现的浮动工具栏 + * Encode a set of form elements as a string for submission. + * + * @category Forms + * @example + * + * ```js + * $('
      ').serialize(); + * //=> 'foo=bar' + * ``` + * + * @returns The serialized form. + * @see {@link https://api.jquery.com/serialize/} + */ + function serialize$1() { + // Convert form elements into name/value objects + const arr = this.serializeArray(); + // Serialize each element into a key/value string + const retArr = arr.map((data) => `${encodeURIComponent(data.name)}=${encodeURIComponent(data.value)}`); + // Return the resulting serialization + return retArr.join('&').replace(r20, '+'); + } + /** + * Encode a set of form elements as an array of names and values. + * + * @category Forms + * @example + * + * ```js + * $('
      ').serializeArray(); + * //=> [ { name: 'foo', value: 'bar' } ] + * ``` + * + * @returns The serialized form. + * @see {@link https://api.jquery.com/serializeArray/} */ + function serializeArray() { + // Resolve all form elements from either forms or collections of form elements + return this.map((_, elem) => { + const $elem = this._make(elem); + if (isTag$1(elem) && elem.name === 'form') { + return $elem.find(submittableSelector).toArray(); + } + return $elem.filter(submittableSelector).toArray(); + }) + .filter( + // Verify elements have a name (`attr.name`) and are not disabled (`:enabled`) + '[name!=""]:enabled' + + // And cannot be clicked (`[type=submit]`) or are used in `x-www-form-urlencoded` (`[type=file]`) + ':not(:submit, :button, :image, :reset, :file)' + + // And are either checked/don't have a checkable state + ':matches([checked], :not(:checkbox, :radio))' + // Convert each of the elements to its value(s) + ) + .map((_, elem) => { + var _a; + const $elem = this._make(elem); + const name = $elem.attr('name'); // We have filtered for elements with a name before. + // If there is no value set (e.g. `undefined`, `null`), then default value to empty + const value = (_a = $elem.val()) !== null && _a !== void 0 ? _a : ''; + // If we have an array of values (e.g. `