├── README.md ├── assets ├── css │ ├── app.css │ └── vue-eleui.css ├── default-content.md ├── images │ ├── qr.jpg │ └── wechat_qrcode.jpg └── scripts │ ├── FuriganaMD.js │ ├── axios.min.js │ ├── editor.js │ ├── marked.min.js │ ├── renderers │ └── wx-renderer.js │ ├── themes │ ├── default.js │ └── lupeng.js │ ├── vue-eleui.js │ └── vue.js ├── codemirror ├── addon │ ├── comment │ │ ├── comment.js │ │ └── continuecomment.js │ ├── dialog │ │ ├── dialog.css │ │ └── dialog.js │ ├── display │ │ ├── autorefresh.js │ │ ├── fullscreen.css │ │ ├── fullscreen.js │ │ ├── panel.js │ │ ├── placeholder.js │ │ └── rulers.js │ ├── edit │ │ ├── closebrackets.js │ │ ├── closetag.js │ │ ├── continuelist.js │ │ ├── matchbrackets.js │ │ ├── matchtags.js │ │ └── trailingspace.js │ ├── fold │ │ ├── brace-fold.js │ │ ├── comment-fold.js │ │ ├── foldcode.js │ │ ├── foldgutter.css │ │ ├── foldgutter.js │ │ ├── indent-fold.js │ │ ├── markdown-fold.js │ │ └── xml-fold.js │ ├── hint │ │ ├── anyword-hint.js │ │ ├── css-hint.js │ │ ├── html-hint.js │ │ ├── javascript-hint.js │ │ ├── show-hint.css │ │ ├── show-hint.js │ │ ├── sql-hint.js │ │ └── xml-hint.js │ ├── lint │ │ ├── coffeescript-lint.js │ │ ├── css-lint.js │ │ ├── html-lint.js │ │ ├── javascript-lint.js │ │ ├── json-lint.js │ │ ├── lint.css │ │ ├── lint.js │ │ └── yaml-lint.js │ ├── merge │ │ ├── merge.css │ │ └── merge.js │ ├── mode │ │ ├── loadmode.js │ │ ├── multiplex.js │ │ ├── multiplex_test.js │ │ ├── overlay.js │ │ └── simple.js │ ├── runmode │ │ ├── colorize.js │ │ ├── runmode-standalone.js │ │ ├── runmode.js │ │ └── runmode.node.js │ ├── scroll │ │ ├── annotatescrollbar.js │ │ ├── scrollpastend.js │ │ ├── simplescrollbars.css │ │ └── simplescrollbars.js │ ├── search │ │ ├── jump-to-line.js │ │ ├── match-highlighter.js │ │ ├── matchesonscrollbar.css │ │ ├── matchesonscrollbar.js │ │ ├── search.js │ │ └── searchcursor.js │ ├── selection │ │ ├── active-line.js │ │ ├── mark-selection.js │ │ └── selection-pointer.js │ ├── tern │ │ ├── tern.css │ │ ├── tern.js │ │ └── worker.js │ └── wrap │ │ └── hardwrap.js ├── codemirror.css ├── codemirror.js ├── mode │ ├── index.html │ ├── markdown │ │ ├── index.html │ │ ├── markdown.js │ │ └── test.js │ └── meta.js └── theme │ ├── base16-light.css │ ├── duotone-light.css │ └── monokai.css ├── favicon.png └── index.html /README.md: -------------------------------------------------------------------------------- 1 | 微信公众号排版编辑器 2 | 3 | -------------------------------------------------------------------------------- /assets/css/app.css: -------------------------------------------------------------------------------- 1 | * { box-sizing: border-box; margin: 0; padding: 0; } 2 | a { text-decoration: none; color: #ff3502 } 3 | input, button, textarea { font-family: inherit; } 4 | h1, h2, h3, h4, h5, h6 { font-weight: normal; } 5 | em { font-style: normal !important; } 6 | html, body { 7 | height: 100%; 8 | font-family: 'PingFang SC', BlinkMacSystemFont, Roboto, 'Helvetica Neue', sans-serif; 9 | } 10 | .el-message__icon { display: none } 11 | .container { 12 | height: 100%; 13 | display: flex; 14 | flex-direction: column; 15 | } 16 | .top { 17 | height: 60px; 18 | padding: 10px 20px; 19 | display: flex; 20 | align-items: center; 21 | } 22 | .top .logo { 23 | margin-right: 20px; 24 | } 25 | #editor { 26 | height: 100%; 27 | display: block; 28 | border: none; 29 | width: 100%; 30 | padding: 10px; 31 | } 32 | section { 33 | height: 100%; 34 | } 35 | .main-body { 36 | display: flex; 37 | flex-direction: column; 38 | padding-top: 0; 39 | padding-bottom: 10px; 40 | } 41 | .ctrl { 42 | flex-basis: 60px; 43 | display: flex; 44 | flex: 1; 45 | align-items: center; 46 | } 47 | .preview-wrapper { 48 | box-shadow: inset 0 0 0 1px rgba(0,0,0,0.1); 49 | padding: 0; 50 | align-items: center; 51 | justify-content: center; 52 | display: flex; 53 | /* height: 100%; */ 54 | overflow: scroll; 55 | } 56 | .main-section { 57 | display: flex; 58 | height: 100%; 59 | } 60 | .hint { 61 | opacity: 0.6; 62 | margin: 20px 0; 63 | } 64 | .preview { 65 | margin: 0 -20px; 66 | width: 375px; 67 | padding: 20px; 68 | font-size: 16px; 69 | outline: none; 70 | box-shadow: 0 0 60px rgba(0,0,0,0.1); 71 | } 72 | .preview ul, .preview ol { 73 | padding-left: 40px !important; 74 | } 75 | .CodeMirror { 76 | height: 100%; 77 | box-shadow: inset 0 0 0 1px rgba(0,0,0,0.1); 78 | font-size: 16px; 79 | padding: 20px; 80 | width: 100%; 81 | font-family: 'PingFang SC', BlinkMacSystemFont, Roboto, 'Helvetica Neue', sans-serif; 82 | } 83 | /* ele ui */ 84 | .el-form-item { 85 | margin-bottom: 0px !important; 86 | } 87 | /*wechat code block*/ 88 | .rich_media_content .code-snippet *, .rich_media_content .code-snippet__fix * { 89 | max-width: 1000% !important; 90 | } 91 | .code-snippet__fix { 92 | word-wrap: break-word !important; 93 | ont-size: 14px; 94 | margin: 10px 0; 95 | display: block; 96 | color: #333; 97 | position: relative; 98 | background-color: rgba(0,0,0,0.03); 99 | border: 1px solid #f0f0f0; 100 | border-radius: 2px; 101 | display: flex; 102 | line-height: 26px; 103 | } 104 | .code-snippet__fix .code-snippet__line-index { 105 | counter-reset: line; 106 | flex-shrink: 0; 107 | height: 100%; 108 | padding: 1em; 109 | list-style-type: none; 110 | } 111 | .code-snippet__fix .code-snippet__line-index li { 112 | list-style-type: none; 113 | text-align: right; 114 | } 115 | .code-snippet__fix .code-snippet__line-index li::before { 116 | min-width: 1.5em; 117 | text-align: right; 118 | left: -2.5em; 119 | counter-increment: line; 120 | content: counter(line); 121 | display: inline; 122 | color: rgba(0,0,0,0.15); 123 | } 124 | .code-snippet__fix pre { 125 | overflow-x: auto; 126 | padding: 1em; 127 | padding-left: 1em; 128 | padding-left: 0; 129 | white-space: normal; 130 | flex: 1; 131 | -webkit-overflow-scrolling: touch; 132 | } 133 | .code-snippet__fix code { 134 | text-align: left; 135 | font-size: 14px; 136 | display: block; 137 | white-space: pre; 138 | display: flex; 139 | position: relative; 140 | font-family: Consolas,"Liberation Mono",Menlo,Courier,monospace; 141 | } -------------------------------------------------------------------------------- /assets/default-content.md: -------------------------------------------------------------------------------- 1 | 使用时,你得把默认的 Markdown 内容换成你自己的内容。 2 | 3 | 关于本工具的介绍请看[这篇公众号文章](https://mp.weixin.qq.com/s/pn0LzyfgUj6rGUfVHUksjg)。 4 | 5 | 6 | ## 一级标题 7 | 8 | 这是一级标题 9 | 10 | 11 | ### 二级标题 12 | 13 | 上面是二级标题 14 | 15 | ## 文字样式 16 | 17 | ### 基本样式 18 | 19 | 你好,我是一个来自地球的人。 20 | 21 | 我是一个[智人](https://zh.wikipedia.org/wiki/智人 "学名:Homo sapiens,意为“有智慧的人”"), 22 | 我喜欢穿新衣服,都是**黑衣服**。 23 | 24 | 我最大的*爱好*是拆汽车,我拆了很多汽车,宝马、奔驰、劳斯莱斯和特斯拉,但是都没装回去。 25 | 26 | 上面表现了链接和加重两种样式,公众号以外的链接会被转换为脚注。 27 | 28 | 29 | ### 注音符号 30 | 31 | [注音符号 W3C 定义](http://www.w3.org/TR/ruby/)。支持日语注音假名,小夜時雨【さ・よ・しぐれ】 和 汉语拼音 上海【Shàng・hǎi】 32 | 33 | 用法有以下几种: 34 | 35 | ``` 36 | 世界【せかい】 37 | 世界{せかい} 38 | ``` 39 | 40 | 世界{せかい} 41 | 42 | ``` 43 | 小夜時雨【さ・よ・しぐれ】 44 | ``` 45 | 46 | 小夜時雨【さ・よ・しぐれ】 47 | 48 | ``` 49 | 食べる【たべる】 50 | 食べる{たべる} 51 | ``` 52 | 53 | 食べる{たべる}\n\n english【英文】 will not translated{fan yi}' 54 | 55 | 56 | ## 段落、列表、引用 57 | 58 | [Markdown](https://sspai.com/post/25137 "认识与入门 Markdown") 是一种写文章用的语法。 59 | 60 | 我们日常写文章用的工具,比如说 Word,提供了大量排版格式样式相关的选项。 61 | 62 | 在写作之外,大量的时间都在处理这些排版、格式、样式、字体、图片位置等等。这不但是耗时耗力的事情,而且还会打乱里写作时的思绪,影响你的工作。 63 | 64 | 列表项: 65 | 66 | - 一个列表项 67 | - 另一个列表项 68 | - 第三个列表项 69 | 70 | 托 [Neko](https://github.com/nekocode) 的福,有序的列表项支持了。 71 | 72 | 1. 一个列表项 73 | 2. 另一个列表项 74 | 3. 第三个列表项 75 | 76 | 使用 Markdown 最大的意义在于可以让你关注写作本身,不需要花费精力在别的事情上。无论是严肃写作还是随手记,Markdown 都是最佳形式。 77 | 78 | > 引用:使用 Markdown 最大的意义在于可以让你关注写作本身 —— Lyric 79 | 80 | 好。 81 | 82 | ## 代码块、表格、图片 83 | 84 | 接下来是一张图片。你可以用自己图床,也可以上传到微信媒体库再把图片 URL 粘贴回来,或者编辑好以后,在公众号里插入图片。 85 | 86 | ![](https://res.wx.qq.com/mpres/zh_CN/htmledition/pages/login/loginpage/images/bg_banner4273fb.png) 87 | 88 | 代码块,使用微信官方的高亮配色,在代码块标示语言即可。粘贴到公众号后,需要用鼠标点一下代码块,完成高亮。 89 | 90 | 91 | ```cpp 92 | 你的代码 93 | ``` 94 | 95 | 96 | 97 | ```cpp 98 | #include 99 | 100 | const int MAX = 10; 101 | int cache[MAX] = {0}; 102 | 103 | int fib(int x) { 104 | if (x == 1) return 1; 105 | if (x == 0) return 0; 106 | if (cache[x] == 0) { 107 | int ret = fib(x - 1) + fib(x - 2); 108 | cache[x] = ret; 109 | } 110 | return cache[x]; 111 | } 112 | 113 | int main() { 114 | int i; 115 | printf("fibonacci series:\n"); 116 | for (i = 0; i < MAX; ++i) { 117 | printf("%d ", fib(i)); 118 | } 119 | return 0; 120 | } 121 | ``` 122 | 123 | 然后是一个内联代码: a paragraphg with inline code `{code: 0}`。 124 | 125 | 接下来是表格示例: 126 | 127 | | Header 1 | Header 2 | 128 | | --- | --- | 129 | | Key 1 | Value 1 | 130 | | Key 2 | Value 2 | 131 | | Key 3 | Value 3 | 132 | 133 | -------------------------------------------------------------------------------- /assets/images/qr.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanyf/wechat-format/4885331f60a8a4bf43eb95eea52cbe7eca2d2b67/assets/images/qr.jpg -------------------------------------------------------------------------------- /assets/images/wechat_qrcode.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanyf/wechat-format/4885331f60a8a4bf43eb95eea52cbe7eca2d2b67/assets/images/wechat_qrcode.jpg -------------------------------------------------------------------------------- /assets/scripts/editor.js: -------------------------------------------------------------------------------- 1 | var app = new Vue({ 2 | el: '#app', 3 | data: function () { 4 | return { 5 | title: 'WeChat Format', 6 | aboutOutput: '', 7 | output: '', 8 | source: '', 9 | editorThemes: [ 10 | { label: 'base16-light', value: 'base16-light' }, 11 | { label: 'duotone-light', value: 'duotone-light' }, 12 | { label: 'monokai', value: 'monokai' } 13 | ], 14 | currentEditorTheme: 'base16-light', 15 | editor: null, 16 | builtinFonts: [ 17 | { label: '衬线', value: "Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, 'PingFang SC', Cambria, Cochin, Georgia, Times, 'Times New Roman', serif"}, 18 | { label: '无衬线', value: "Roboto, Oxygen, Ubuntu, Cantarell, PingFangSC-light, PingFangTC-light, 'Open Sans', 'Helvetica Neue', sans-serif"} 19 | ], 20 | currentFont: "Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, 'PingFang SC', Cambria, Cochin, Georgia, Times, 'Times New Roman', serif", 21 | currentSize: '16px', 22 | sizeOption: [ 23 | { label: '16px', value: '16px', desc: '默认' }, 24 | { label: '17px', value: '17px', desc: '正常' }, 25 | { label: '18px', value: '18px', desc: '稍大' } 26 | ], 27 | currentTheme: 'default', 28 | themeOption: [ 29 | { label: 'default', value: 'default', author: 'Lyric'}, 30 | { label: 'lupeng', value: 'lupeng', author: '鲁鹏'} 31 | ], 32 | styleThemes: { 33 | default: defaultTheme, 34 | lupeng: lupengTheme 35 | }, 36 | aboutDialogVisible: false 37 | } 38 | }, 39 | mounted () { 40 | var self = this 41 | this.editor = CodeMirror.fromTextArea(document.getElementById('editor'), { 42 | lineNumbers: false, 43 | lineWrapping: true, 44 | styleActiveLine: true, 45 | theme: this.currentEditorTheme, 46 | mode: 'text/x-markdown', 47 | }); 48 | this.editor.on("change", function(cm, change) { 49 | self.refresh() 50 | }) 51 | // this.currentFont = this.builtinFonts[0], 52 | this.wxRenderer = new WxRenderer({ 53 | theme: this.styleThemes.default, 54 | fonts: this.currentFont, 55 | size: this.currentSize 56 | }) 57 | axios({ 58 | method: 'get', 59 | url: './assets/default-content.md', 60 | }).then(function (resp) { 61 | self.editor.setValue(resp.data) 62 | }) 63 | }, 64 | methods: { 65 | renderWeChat: function (source) { 66 | var output = marked(source, { renderer: this.wxRenderer.getRenderer() }) 67 | if (this.wxRenderer.hasFootnotes()) { 68 | output += this.wxRenderer.buildFootnotes() 69 | } 70 | return output 71 | }, 72 | editorThemeChanged: function (editorTheme) { 73 | this.editor.setOption('theme', editorTheme) 74 | }, 75 | fontChanged: function (fonts) { 76 | this.wxRenderer.setOptions({ 77 | fonts: fonts 78 | }) 79 | this.refresh() 80 | }, 81 | sizeChanged: function(size){ 82 | this.wxRenderer.setOptions({ 83 | size: size 84 | }) 85 | this.refresh() 86 | }, 87 | themeChanged: function(themeName){ 88 | var themeName = themeName; 89 | var themeObject = this.styleThemes[themeName]; 90 | this.wxRenderer.setOptions({ 91 | theme: themeObject 92 | }) 93 | this.refresh() 94 | }, 95 | refresh: function () { 96 | this.output = this.renderWeChat(this.editor.getValue()) 97 | }, 98 | copy: function () { 99 | var clipboardDiv = document.getElementById('output') 100 | clipboardDiv.focus(); 101 | window.getSelection().removeAllRanges(); 102 | var range = document.createRange(); 103 | range.setStartBefore(clipboardDiv.firstChild); 104 | range.setEndAfter(clipboardDiv.lastChild); 105 | window.getSelection().addRange(range); 106 | 107 | try { 108 | if (document.execCommand('copy')) { 109 | this.$message({ 110 | message: '已复制到剪贴板', type: 'success' 111 | }) 112 | } else { 113 | this.$message({ 114 | message: '未能复制到剪贴板,请全选后右键复制', type: 'warning' 115 | }) 116 | } 117 | } catch (err) { 118 | this.$message({ 119 | message: '未能复制到剪贴板,请全选后右键复制', type: 'warning' 120 | }) 121 | } 122 | } 123 | } 124 | }) -------------------------------------------------------------------------------- /assets/scripts/renderers/wx-renderer.js: -------------------------------------------------------------------------------- 1 | var WxRenderer = function (opts) { 2 | this.opts = opts 3 | var ENV_USE_REFERENCES = true 4 | var ENV_STETCH_IMAGE = true 5 | 6 | var footnotes = [] 7 | var footnoteindex = 0 8 | var styleMapping = null 9 | 10 | var FONT_FAMILY_MONO = "Operator Mono, Consolas, Monaco, Menlo, monospace" 11 | 12 | var COPY = function (base, extend) { return Object.assign({}, base, extend)} 13 | 14 | this.buildTheme = function (themeTpl) { 15 | var mapping = {} 16 | var base = COPY(themeTpl.BASE, { 17 | 'font-family': this.opts.fonts, 18 | 'font-size': this.opts.size 19 | }) 20 | var base_block = COPY(base, { 21 | 'margin': '20px 10px' 22 | }) 23 | for (var ele in themeTpl.inline) { 24 | if (themeTpl.inline.hasOwnProperty(ele)) { 25 | var style = themeTpl.inline[ele] 26 | if (ele === 'codespan') { 27 | style['font-family'] = FONT_FAMILY_MONO 28 | } 29 | mapping[ele] = COPY(base, style) 30 | } 31 | } 32 | for (var ele in themeTpl.block) { 33 | if (themeTpl.block.hasOwnProperty(ele)) { 34 | var style = themeTpl.block[ele] 35 | if (ele === 'code') { 36 | style['font-family'] = FONT_FAMILY_MONO 37 | } 38 | mapping[ele] = COPY(base_block, style) 39 | } 40 | } 41 | return mapping 42 | } 43 | 44 | var S = function (tokenName) { 45 | var arr = [] 46 | var dict = styleMapping[tokenName] 47 | for (const key in dict) { 48 | arr.push(key + ':' + dict[key]) 49 | } 50 | return 'style="' + arr.join(';') + '"' 51 | } 52 | 53 | var addFootnote = function (title, link) { 54 | footnoteindex += 1 55 | footnotes.push([footnoteindex, title, link]) 56 | return footnoteindex 57 | } 58 | 59 | this.buildFootnotes = function () { 60 | var footnoteArray = footnotes.map(function (x) { 61 | if (x[1] === x[2]) { 62 | return '[' + x[0] + ']: ' + x[1] +'
' 63 | } 64 | return '[' + x[0] + '] ' + x[1] + ': ' + x[2] +'
' 65 | }) 66 | return '

References

' + footnoteArray.join('\n') + '

' 67 | } 68 | 69 | this.setOptions = function (newOpts) { 70 | this.opts = COPY(this.opts, newOpts) 71 | } 72 | 73 | this.hasFootnotes = function () { 74 | return footnotes.length !== 0 75 | } 76 | 77 | this.getRenderer = function () { 78 | footnotes = [] 79 | footnoteindex = 0 80 | 81 | styleMapping = this.buildTheme(this.opts.theme) 82 | var renderer = new marked.Renderer() 83 | FuriganaMD.register(renderer); 84 | 85 | renderer.heading = function (text, level) { 86 | if (level < 3) { 87 | return '

' + text + '

' 88 | } else { 89 | return '

' + text + '

' 90 | } 91 | } 92 | renderer.paragraph = function (text) { 93 | return '

' + text + '

' 94 | } 95 | renderer.blockquote = function (text) { 96 | return '
' + text + '
' 97 | } 98 | renderer.code = function (text, infostring) { 99 | text = text.replace(//g, ">") 101 | 102 | var lines = text.split('\n') 103 | var codeLines = [] 104 | var numbers = [] 105 | for (let i = 0; i < lines.length; i++) { 106 | const line = lines[i] 107 | codeLines.push('' + (line || '
') + '
') 108 | numbers.push('
  • ') 109 | } 110 | var lang = infostring || '' 111 | return '
    ' 112 | + '' 113 | + '
    ' 
    114 |           + codeLines.join('')
    115 |         + '
    ' 116 | } 117 | renderer.codespan = function (text, infostring) { 118 | return '' + text + '' 119 | } 120 | renderer.listitem = function (text) { 121 | return '<%s/>' + text + ''; 122 | } 123 | renderer.list = function (text, ordered, start) { 124 | var segments = text.split('<%s/>'); 125 | if (!ordered) { 126 | text = segments.join('•'); 127 | return '

    ' + text + '

    '; 128 | } 129 | text = segments[0]; 130 | for (var i = 1; i < segments.length; i++) { 131 | text = text + i + '.' + segments[i]; 132 | } 133 | return '

    ' + text + '

    '; 134 | } 135 | renderer.image = function (href, title, text) { 136 | return ''+text+'' 137 | } 138 | renderer.link = function (href, title, text) { 139 | if (href.indexOf('https://mp.weixin.qq.com') === 0) { 140 | return '' + text + ''; 141 | }else if( href === text){ 142 | return text; 143 | } else { 144 | if (ENV_USE_REFERENCES) { 145 | var ref = addFootnote(title || text, href) 146 | return '' + text + '['+ref+']'; 147 | } else { 148 | return '' + text + ''; 149 | } 150 | } 151 | } 152 | renderer.strong = renderer.em = function (text) { 153 | return '' + text + ''; 154 | } 155 | renderer.table = function (header, body) { 156 | return '' + header + '' + body + '
    '; 157 | } 158 | renderer.tablecell = function (text, flags) { 159 | return '' + text + ''; 160 | } 161 | renderer.hr = function(){ 162 | return '
    '; 163 | } 164 | return renderer 165 | } 166 | } -------------------------------------------------------------------------------- /assets/scripts/themes/default.js: -------------------------------------------------------------------------------- 1 | var defaultTheme = { 2 | BASE: { 3 | 'text-align': 'left', 4 | 'color': '#3f3f3f', 5 | 'line-height': '1.5' 6 | }, 7 | BASE_BLOCK: { 8 | 'margin': '20px 10px' 9 | }, 10 | // block element 11 | block: { 12 | h2: { 13 | 'font-size': '140%', 14 | 'text-align': 'center', 15 | 'font-weight': 'normal', 16 | 'text-align': 'center', 17 | 'margin': '80px 10px 40px 10px' 18 | }, 19 | h3: { 20 | 'font-weight': 'bold', 21 | 'font-size': '120%', 22 | 'margin': '40px 10px 20px 10px' 23 | }, 24 | p: { 25 | 'margin': '10px 10px', 26 | 'line-height': '1.6' 27 | }, 28 | blockquote: { 29 | 'color': 'rgb(91, 91, 91)', 30 | 'padding': '1px 0 1px 10px', 31 | 'background': 'rgba(158, 158, 158, 0.1)', 32 | 'border-left': '3px solid rgb(158,158,158)', 33 | }, 34 | code: { 35 | 'font-size': '80%', 36 | 'overflow': 'auto', 37 | 'color': '#333', 38 | 'background': 'rgb(247, 247, 247)', 39 | 'border-radius': '2px', 40 | 'padding': '10px', 41 | 'line-height': '1.3', 42 | 'border': '1px solid rgb(236,236,236)', 43 | 'margin': '20px 0', 44 | }, 45 | image: { 46 | 'border-radius': '4px', 47 | 'display': 'block', 48 | 'margin': '20px auto', 49 | 'width': '100%', 50 | }, 51 | image_org: { 52 | 'border-radius': '4px', 53 | 'display': 'block', 54 | }, 55 | ol: { 56 | 'margin-left': '0', 57 | 'padding-left': '20px' 58 | }, 59 | ul: { 60 | 'margin-left': '0', 61 | 'padding-left': '20px', 62 | 'list-style': 'circle', 63 | }, 64 | footnotes: { 65 | 'margin': '10px 10px', 66 | 'font-size': '14px' 67 | } 68 | }, 69 | inline: { 70 | // inline element 71 | listitem: { 72 | 'text-indent': '-20px', 73 | 'display': 'block', 74 | 'margin': '10px 10px', 75 | }, 76 | codespan: { 77 | 'font-size': '90%', 78 | // 'font-family': FONT_FAMILY_MONO, 79 | 'color': '#ff3502', 80 | 'background': '#f8f5ec', 81 | 'padding': '3px 5px', 82 | 'border-radius': '2px', 83 | }, 84 | link: { 85 | 'color': '#ff3502' 86 | }, 87 | strong: { 88 | 'color': '#ff3502' 89 | }, 90 | table: { 91 | 'border-collapse': 'collapse', 92 | 'margin': '20px 0', 93 | }, 94 | thead: { 95 | 'background': 'rgba(0,0,0,0.05)', 96 | }, 97 | td: { 98 | 'font-size': '80%', 99 | 'border': '1px solid #dfdfdf', 100 | 'padding': '4px 8px', 101 | }, 102 | footnote: { 103 | 'font-size': '12px', 104 | } 105 | } 106 | } -------------------------------------------------------------------------------- /assets/scripts/themes/lupeng.js: -------------------------------------------------------------------------------- 1 | var lupengTheme = { 2 | BASE: { 3 | 'text-align': 'left', 4 | 'color': '#595959', 5 | 'line-height': '1.55em', 6 | 'letter-spacing': '0.06em' 7 | }, 8 | BASE_BLOCK: defaultTheme.BASE_BLOCK, 9 | block: { 10 | h2: { 11 | 'font-size': '140%', 12 | 'text-align': 'center', 13 | 'font-weight': 'normal', 14 | 'text-align': 'center', 15 | 'margin': '80px 10px 40px 10px' 16 | }, 17 | h3: { 18 | 'font-weight': 'bold', 19 | 'font-size': '120%', 20 | 'margin': '40px 10px 20px 10px' 21 | }, 22 | p: { 23 | 'margin': '10px 10px', 24 | 'line-height': '1.6' 25 | }, 26 | blockquote: { 27 | 'color': '#9a9a9a', 28 | 'padding-left': '10px', 29 | // 'padding-top': '0.05px', 30 | 'background-color': '#fefefe', 31 | 'line-height': '1.6', 32 | 'border-left': '3px solid #dbdbdb', 33 | 'font-size': '15px', 34 | 'margin': '1em 0' 35 | }, 36 | code: { 37 | 'font-size': '80%', 38 | 'overflow': 'auto', 39 | 'color': '#333', 40 | 'background': 'rgb(247, 247, 247)', 41 | 'border-radius': '2px', 42 | 'padding': '10px', 43 | 'line-height': '1.3', 44 | 'border': '1px solid rgb(236,236,236)', 45 | 'margin': '20px 0', 46 | }, 47 | image: { 48 | 'border-radius': '4px', 49 | 'display': 'block', 50 | 'margin': '20px auto', 51 | 'width': '100%', 52 | }, 53 | image_org: { 54 | 'border-radius': '4px', 55 | 'display': 'block', 56 | }, 57 | ol: { 58 | 'margin-left': '0', 59 | 'padding-left': '20px' 60 | }, 61 | ul: { 62 | 'margin-left': '0', 63 | 'padding-left': '20px', 64 | 'list-style': 'circle', 65 | }, 66 | footnotes: { 67 | 'margin': '10px 10px', 68 | 'font-size': '14px' 69 | } 70 | }, 71 | inline: { 72 | // inline element 73 | listitem: { 74 | 'text-indent': '-20px', 75 | 'display': 'block', 76 | 'margin': '10px 10px', 77 | }, 78 | codespan: { 79 | 'font-size': '0.8em', 80 | 'color': '#d14', 81 | 'background': '#fefefe', 82 | 'padding': '3px 5px 0px', 83 | 'margin': '0px 2px', 84 | 'border': '1px solid #ddd', 85 | 'border-radius': '3px', 86 | }, 87 | link: { 88 | 'color': '#ff3502' 89 | }, 90 | wx_link: { 91 | 'color': '#576b95', 92 | 'text-decoration': 'none' 93 | }, 94 | strong: { 95 | 'font-weight': 'bold', 96 | }, 97 | table: { 98 | 'border-collapse': 'collapse', 99 | 'margin': '20px 0', 100 | }, 101 | thead: { 102 | 'background': 'rgba(0,0,0,0.05)', 103 | }, 104 | td: { 105 | 'font-size': '80%', 106 | 'border': '1px solid #dfdfdf', 107 | 'padding': '4px 8px', 108 | }, 109 | footnote: { 110 | 'font-size': '12px', 111 | } 112 | } 113 | } -------------------------------------------------------------------------------- /codemirror/addon/comment/continuecomment.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: https://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | function continueComment(cm) { 13 | if (cm.getOption("disableInput")) return CodeMirror.Pass; 14 | var ranges = cm.listSelections(), mode, inserts = []; 15 | for (var i = 0; i < ranges.length; i++) { 16 | var pos = ranges[i].head 17 | if (!/\bcomment\b/.test(cm.getTokenTypeAt(pos))) return CodeMirror.Pass; 18 | var modeHere = cm.getModeAt(pos) 19 | if (!mode) mode = modeHere; 20 | else if (mode != modeHere) return CodeMirror.Pass; 21 | 22 | var insert = null; 23 | if (mode.blockCommentStart && mode.blockCommentContinue) { 24 | var line = cm.getLine(pos.line).slice(0, pos.ch) 25 | var end = line.lastIndexOf(mode.blockCommentEnd), found 26 | if (end != -1 && end == pos.ch - mode.blockCommentEnd.length) { 27 | // Comment ended, don't continue it 28 | } else if ((found = line.lastIndexOf(mode.blockCommentStart)) > -1 && found > end) { 29 | insert = line.slice(0, found) 30 | if (/\S/.test(insert)) { 31 | insert = "" 32 | for (var j = 0; j < found; ++j) insert += " " 33 | } 34 | } else if ((found = line.indexOf(mode.blockCommentContinue)) > -1 && !/\S/.test(line.slice(0, found))) { 35 | insert = line.slice(0, found) 36 | } 37 | if (insert != null) insert += mode.blockCommentContinue 38 | } 39 | if (insert == null && mode.lineComment && continueLineCommentEnabled(cm)) { 40 | var line = cm.getLine(pos.line), found = line.indexOf(mode.lineComment); 41 | if (found > -1) { 42 | insert = line.slice(0, found); 43 | if (/\S/.test(insert)) insert = null; 44 | else insert += mode.lineComment + line.slice(found + mode.lineComment.length).match(/^\s*/)[0]; 45 | } 46 | } 47 | if (insert == null) return CodeMirror.Pass; 48 | inserts[i] = "\n" + insert; 49 | } 50 | 51 | cm.operation(function() { 52 | for (var i = ranges.length - 1; i >= 0; i--) 53 | cm.replaceRange(inserts[i], ranges[i].from(), ranges[i].to(), "+insert"); 54 | }); 55 | } 56 | 57 | function continueLineCommentEnabled(cm) { 58 | var opt = cm.getOption("continueComments"); 59 | if (opt && typeof opt == "object") 60 | return opt.continueLineComment !== false; 61 | return true; 62 | } 63 | 64 | CodeMirror.defineOption("continueComments", null, function(cm, val, prev) { 65 | if (prev && prev != CodeMirror.Init) 66 | cm.removeKeyMap("continueComment"); 67 | if (val) { 68 | var key = "Enter"; 69 | if (typeof val == "string") 70 | key = val; 71 | else if (typeof val == "object" && val.key) 72 | key = val.key; 73 | var map = {name: "continueComment"}; 74 | map[key] = continueComment; 75 | cm.addKeyMap(map); 76 | } 77 | }); 78 | }); 79 | -------------------------------------------------------------------------------- /codemirror/addon/dialog/dialog.css: -------------------------------------------------------------------------------- 1 | .CodeMirror-dialog { 2 | position: absolute; 3 | left: 0; right: 0; 4 | background: inherit; 5 | z-index: 15; 6 | padding: .1em .8em; 7 | overflow: hidden; 8 | color: inherit; 9 | } 10 | 11 | .CodeMirror-dialog-top { 12 | border-bottom: 1px solid #eee; 13 | top: 0; 14 | } 15 | 16 | .CodeMirror-dialog-bottom { 17 | border-top: 1px solid #eee; 18 | bottom: 0; 19 | } 20 | 21 | .CodeMirror-dialog input { 22 | border: none; 23 | outline: none; 24 | background: transparent; 25 | width: 20em; 26 | color: inherit; 27 | font-family: monospace; 28 | } 29 | 30 | .CodeMirror-dialog button { 31 | font-size: 70%; 32 | } 33 | -------------------------------------------------------------------------------- /codemirror/addon/dialog/dialog.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: https://codemirror.net/LICENSE 3 | 4 | // Open simple dialogs on top of an editor. Relies on dialog.css. 5 | 6 | (function(mod) { 7 | if (typeof exports == "object" && typeof module == "object") // CommonJS 8 | mod(require("../../lib/codemirror")); 9 | else if (typeof define == "function" && define.amd) // AMD 10 | define(["../../lib/codemirror"], mod); 11 | else // Plain browser env 12 | mod(CodeMirror); 13 | })(function(CodeMirror) { 14 | function dialogDiv(cm, template, bottom) { 15 | var wrap = cm.getWrapperElement(); 16 | var dialog; 17 | dialog = wrap.appendChild(document.createElement("div")); 18 | if (bottom) 19 | dialog.className = "CodeMirror-dialog CodeMirror-dialog-bottom"; 20 | else 21 | dialog.className = "CodeMirror-dialog CodeMirror-dialog-top"; 22 | 23 | if (typeof template == "string") { 24 | dialog.innerHTML = template; 25 | } else { // Assuming it's a detached DOM element. 26 | dialog.appendChild(template); 27 | } 28 | CodeMirror.addClass(wrap, 'dialog-opened'); 29 | return dialog; 30 | } 31 | 32 | function closeNotification(cm, newVal) { 33 | if (cm.state.currentNotificationClose) 34 | cm.state.currentNotificationClose(); 35 | cm.state.currentNotificationClose = newVal; 36 | } 37 | 38 | CodeMirror.defineExtension("openDialog", function(template, callback, options) { 39 | if (!options) options = {}; 40 | 41 | closeNotification(this, null); 42 | 43 | var dialog = dialogDiv(this, template, options.bottom); 44 | var closed = false, me = this; 45 | function close(newVal) { 46 | if (typeof newVal == 'string') { 47 | inp.value = newVal; 48 | } else { 49 | if (closed) return; 50 | closed = true; 51 | CodeMirror.rmClass(dialog.parentNode, 'dialog-opened'); 52 | dialog.parentNode.removeChild(dialog); 53 | me.focus(); 54 | 55 | if (options.onClose) options.onClose(dialog); 56 | } 57 | } 58 | 59 | var inp = dialog.getElementsByTagName("input")[0], button; 60 | if (inp) { 61 | inp.focus(); 62 | 63 | if (options.value) { 64 | inp.value = options.value; 65 | if (options.selectValueOnOpen !== false) { 66 | inp.select(); 67 | } 68 | } 69 | 70 | if (options.onInput) 71 | CodeMirror.on(inp, "input", function(e) { options.onInput(e, inp.value, close);}); 72 | if (options.onKeyUp) 73 | CodeMirror.on(inp, "keyup", function(e) {options.onKeyUp(e, inp.value, close);}); 74 | 75 | CodeMirror.on(inp, "keydown", function(e) { 76 | if (options && options.onKeyDown && options.onKeyDown(e, inp.value, close)) { return; } 77 | if (e.keyCode == 27 || (options.closeOnEnter !== false && e.keyCode == 13)) { 78 | inp.blur(); 79 | CodeMirror.e_stop(e); 80 | close(); 81 | } 82 | if (e.keyCode == 13) callback(inp.value, e); 83 | }); 84 | 85 | if (options.closeOnBlur !== false) CodeMirror.on(inp, "blur", close); 86 | } else if (button = dialog.getElementsByTagName("button")[0]) { 87 | CodeMirror.on(button, "click", function() { 88 | close(); 89 | me.focus(); 90 | }); 91 | 92 | if (options.closeOnBlur !== false) CodeMirror.on(button, "blur", close); 93 | 94 | button.focus(); 95 | } 96 | return close; 97 | }); 98 | 99 | CodeMirror.defineExtension("openConfirm", function(template, callbacks, options) { 100 | closeNotification(this, null); 101 | var dialog = dialogDiv(this, template, options && options.bottom); 102 | var buttons = dialog.getElementsByTagName("button"); 103 | var closed = false, me = this, blurring = 1; 104 | function close() { 105 | if (closed) return; 106 | closed = true; 107 | CodeMirror.rmClass(dialog.parentNode, 'dialog-opened'); 108 | dialog.parentNode.removeChild(dialog); 109 | me.focus(); 110 | } 111 | buttons[0].focus(); 112 | for (var i = 0; i < buttons.length; ++i) { 113 | var b = buttons[i]; 114 | (function(callback) { 115 | CodeMirror.on(b, "click", function(e) { 116 | CodeMirror.e_preventDefault(e); 117 | close(); 118 | if (callback) callback(me); 119 | }); 120 | })(callbacks[i]); 121 | CodeMirror.on(b, "blur", function() { 122 | --blurring; 123 | setTimeout(function() { if (blurring <= 0) close(); }, 200); 124 | }); 125 | CodeMirror.on(b, "focus", function() { ++blurring; }); 126 | } 127 | }); 128 | 129 | /* 130 | * openNotification 131 | * Opens a notification, that can be closed with an optional timer 132 | * (default 5000ms timer) and always closes on click. 133 | * 134 | * If a notification is opened while another is opened, it will close the 135 | * currently opened one and open the new one immediately. 136 | */ 137 | CodeMirror.defineExtension("openNotification", function(template, options) { 138 | closeNotification(this, close); 139 | var dialog = dialogDiv(this, template, options && options.bottom); 140 | var closed = false, doneTimer; 141 | var duration = options && typeof options.duration !== "undefined" ? options.duration : 5000; 142 | 143 | function close() { 144 | if (closed) return; 145 | closed = true; 146 | clearTimeout(doneTimer); 147 | CodeMirror.rmClass(dialog.parentNode, 'dialog-opened'); 148 | dialog.parentNode.removeChild(dialog); 149 | } 150 | 151 | CodeMirror.on(dialog, 'click', function(e) { 152 | CodeMirror.e_preventDefault(e); 153 | close(); 154 | }); 155 | 156 | if (duration) 157 | doneTimer = setTimeout(close, duration); 158 | 159 | return close; 160 | }); 161 | }); 162 | -------------------------------------------------------------------------------- /codemirror/addon/display/autorefresh.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: https://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")) 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod) 9 | else // Plain browser env 10 | mod(CodeMirror) 11 | })(function(CodeMirror) { 12 | "use strict" 13 | 14 | CodeMirror.defineOption("autoRefresh", false, function(cm, val) { 15 | if (cm.state.autoRefresh) { 16 | stopListening(cm, cm.state.autoRefresh) 17 | cm.state.autoRefresh = null 18 | } 19 | if (val && cm.display.wrapper.offsetHeight == 0) 20 | startListening(cm, cm.state.autoRefresh = {delay: val.delay || 250}) 21 | }) 22 | 23 | function startListening(cm, state) { 24 | function check() { 25 | if (cm.display.wrapper.offsetHeight) { 26 | stopListening(cm, state) 27 | if (cm.display.lastWrapHeight != cm.display.wrapper.clientHeight) 28 | cm.refresh() 29 | } else { 30 | state.timeout = setTimeout(check, state.delay) 31 | } 32 | } 33 | state.timeout = setTimeout(check, state.delay) 34 | state.hurry = function() { 35 | clearTimeout(state.timeout) 36 | state.timeout = setTimeout(check, 50) 37 | } 38 | CodeMirror.on(window, "mouseup", state.hurry) 39 | CodeMirror.on(window, "keyup", state.hurry) 40 | } 41 | 42 | function stopListening(_cm, state) { 43 | clearTimeout(state.timeout) 44 | CodeMirror.off(window, "mouseup", state.hurry) 45 | CodeMirror.off(window, "keyup", state.hurry) 46 | } 47 | }); 48 | -------------------------------------------------------------------------------- /codemirror/addon/display/fullscreen.css: -------------------------------------------------------------------------------- 1 | .CodeMirror-fullscreen { 2 | position: fixed; 3 | top: 0; left: 0; right: 0; bottom: 0; 4 | height: auto; 5 | z-index: 9; 6 | } 7 | -------------------------------------------------------------------------------- /codemirror/addon/display/fullscreen.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: https://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | CodeMirror.defineOption("fullScreen", false, function(cm, val, old) { 15 | if (old == CodeMirror.Init) old = false; 16 | if (!old == !val) return; 17 | if (val) setFullscreen(cm); 18 | else setNormal(cm); 19 | }); 20 | 21 | function setFullscreen(cm) { 22 | var wrap = cm.getWrapperElement(); 23 | cm.state.fullScreenRestore = {scrollTop: window.pageYOffset, scrollLeft: window.pageXOffset, 24 | width: wrap.style.width, height: wrap.style.height}; 25 | wrap.style.width = ""; 26 | wrap.style.height = "auto"; 27 | wrap.className += " CodeMirror-fullscreen"; 28 | document.documentElement.style.overflow = "hidden"; 29 | cm.refresh(); 30 | } 31 | 32 | function setNormal(cm) { 33 | var wrap = cm.getWrapperElement(); 34 | wrap.className = wrap.className.replace(/\s*CodeMirror-fullscreen\b/, ""); 35 | document.documentElement.style.overflow = ""; 36 | var info = cm.state.fullScreenRestore; 37 | wrap.style.width = info.width; wrap.style.height = info.height; 38 | window.scrollTo(info.scrollLeft, info.scrollTop); 39 | cm.refresh(); 40 | } 41 | }); 42 | -------------------------------------------------------------------------------- /codemirror/addon/display/panel.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: https://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | CodeMirror.defineExtension("addPanel", function(node, options) { 13 | options = options || {}; 14 | 15 | if (!this.state.panels) initPanels(this); 16 | 17 | var info = this.state.panels; 18 | var wrapper = info.wrapper; 19 | var cmWrapper = this.getWrapperElement(); 20 | var replace = options.replace instanceof Panel && !options.replace.cleared; 21 | 22 | if (options.after instanceof Panel && !options.after.cleared) { 23 | wrapper.insertBefore(node, options.before.node.nextSibling); 24 | } else if (options.before instanceof Panel && !options.before.cleared) { 25 | wrapper.insertBefore(node, options.before.node); 26 | } else if (replace) { 27 | wrapper.insertBefore(node, options.replace.node); 28 | info.panels++; 29 | options.replace.clear(); 30 | } else if (options.position == "bottom") { 31 | wrapper.appendChild(node); 32 | } else if (options.position == "before-bottom") { 33 | wrapper.insertBefore(node, cmWrapper.nextSibling); 34 | } else if (options.position == "after-top") { 35 | wrapper.insertBefore(node, cmWrapper); 36 | } else { 37 | wrapper.insertBefore(node, wrapper.firstChild); 38 | } 39 | 40 | var height = (options && options.height) || node.offsetHeight; 41 | this._setSize(null, info.heightLeft -= height); 42 | if (!replace) { 43 | info.panels++; 44 | } 45 | if (options.stable && isAtTop(this, node)) 46 | this.scrollTo(null, this.getScrollInfo().top + height) 47 | 48 | return new Panel(this, node, options, height); 49 | }); 50 | 51 | function Panel(cm, node, options, height) { 52 | this.cm = cm; 53 | this.node = node; 54 | this.options = options; 55 | this.height = height; 56 | this.cleared = false; 57 | } 58 | 59 | Panel.prototype.clear = function() { 60 | if (this.cleared) return; 61 | this.cleared = true; 62 | var info = this.cm.state.panels; 63 | this.cm._setSize(null, info.heightLeft += this.height); 64 | if (this.options.stable && isAtTop(this.cm, this.node)) 65 | this.cm.scrollTo(null, this.cm.getScrollInfo().top - this.height) 66 | info.wrapper.removeChild(this.node); 67 | if (--info.panels == 0) removePanels(this.cm); 68 | }; 69 | 70 | Panel.prototype.changed = function(height) { 71 | var newHeight = height == null ? this.node.offsetHeight : height; 72 | var info = this.cm.state.panels; 73 | this.cm._setSize(null, info.heightLeft -= (newHeight - this.height)); 74 | this.height = newHeight; 75 | }; 76 | 77 | function initPanels(cm) { 78 | var wrap = cm.getWrapperElement(); 79 | var style = window.getComputedStyle ? window.getComputedStyle(wrap) : wrap.currentStyle; 80 | var height = parseInt(style.height); 81 | var info = cm.state.panels = { 82 | setHeight: wrap.style.height, 83 | heightLeft: height, 84 | panels: 0, 85 | wrapper: document.createElement("div") 86 | }; 87 | wrap.parentNode.insertBefore(info.wrapper, wrap); 88 | var hasFocus = cm.hasFocus(); 89 | info.wrapper.appendChild(wrap); 90 | if (hasFocus) cm.focus(); 91 | 92 | cm._setSize = cm.setSize; 93 | if (height != null) cm.setSize = function(width, newHeight) { 94 | if (newHeight == null) return this._setSize(width, newHeight); 95 | info.setHeight = newHeight; 96 | if (typeof newHeight != "number") { 97 | var px = /^(\d+\.?\d*)px$/.exec(newHeight); 98 | if (px) { 99 | newHeight = Number(px[1]); 100 | } else { 101 | info.wrapper.style.height = newHeight; 102 | newHeight = info.wrapper.offsetHeight; 103 | info.wrapper.style.height = ""; 104 | } 105 | } 106 | cm._setSize(width, info.heightLeft += (newHeight - height)); 107 | height = newHeight; 108 | }; 109 | } 110 | 111 | function removePanels(cm) { 112 | var info = cm.state.panels; 113 | cm.state.panels = null; 114 | 115 | var wrap = cm.getWrapperElement(); 116 | info.wrapper.parentNode.replaceChild(wrap, info.wrapper); 117 | wrap.style.height = info.setHeight; 118 | cm.setSize = cm._setSize; 119 | cm.setSize(); 120 | } 121 | 122 | function isAtTop(cm, dom) { 123 | for (var sibling = dom.nextSibling; sibling; sibling = sibling.nextSibling) 124 | if (sibling == cm.getWrapperElement()) return true 125 | return false 126 | } 127 | }); 128 | -------------------------------------------------------------------------------- /codemirror/addon/display/placeholder.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: https://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | CodeMirror.defineOption("placeholder", "", function(cm, val, old) { 13 | var prev = old && old != CodeMirror.Init; 14 | if (val && !prev) { 15 | cm.on("blur", onBlur); 16 | cm.on("change", onChange); 17 | cm.on("swapDoc", onChange); 18 | onChange(cm); 19 | } else if (!val && prev) { 20 | cm.off("blur", onBlur); 21 | cm.off("change", onChange); 22 | cm.off("swapDoc", onChange); 23 | clearPlaceholder(cm); 24 | var wrapper = cm.getWrapperElement(); 25 | wrapper.className = wrapper.className.replace(" CodeMirror-empty", ""); 26 | } 27 | 28 | if (val && !cm.hasFocus()) onBlur(cm); 29 | }); 30 | 31 | function clearPlaceholder(cm) { 32 | if (cm.state.placeholder) { 33 | cm.state.placeholder.parentNode.removeChild(cm.state.placeholder); 34 | cm.state.placeholder = null; 35 | } 36 | } 37 | function setPlaceholder(cm) { 38 | clearPlaceholder(cm); 39 | var elt = cm.state.placeholder = document.createElement("pre"); 40 | elt.style.cssText = "height: 0; overflow: visible"; 41 | elt.style.direction = cm.getOption("direction"); 42 | elt.className = "CodeMirror-placeholder"; 43 | var placeHolder = cm.getOption("placeholder") 44 | if (typeof placeHolder == "string") placeHolder = document.createTextNode(placeHolder) 45 | elt.appendChild(placeHolder) 46 | cm.display.lineSpace.insertBefore(elt, cm.display.lineSpace.firstChild); 47 | } 48 | 49 | function onBlur(cm) { 50 | if (isEmpty(cm)) setPlaceholder(cm); 51 | } 52 | function onChange(cm) { 53 | var wrapper = cm.getWrapperElement(), empty = isEmpty(cm); 54 | wrapper.className = wrapper.className.replace(" CodeMirror-empty", "") + (empty ? " CodeMirror-empty" : ""); 55 | 56 | if (empty) setPlaceholder(cm); 57 | else clearPlaceholder(cm); 58 | } 59 | 60 | function isEmpty(cm) { 61 | return (cm.lineCount() === 1) && (cm.getLine(0) === ""); 62 | } 63 | }); 64 | -------------------------------------------------------------------------------- /codemirror/addon/display/rulers.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: https://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | CodeMirror.defineOption("rulers", false, function(cm, val) { 15 | if (cm.state.rulerDiv) { 16 | cm.state.rulerDiv.parentElement.removeChild(cm.state.rulerDiv) 17 | cm.state.rulerDiv = null 18 | cm.off("refresh", drawRulers) 19 | } 20 | if (val && val.length) { 21 | cm.state.rulerDiv = cm.display.lineSpace.parentElement.insertBefore(document.createElement("div"), cm.display.lineSpace) 22 | cm.state.rulerDiv.className = "CodeMirror-rulers" 23 | drawRulers(cm) 24 | cm.on("refresh", drawRulers) 25 | } 26 | }); 27 | 28 | function drawRulers(cm) { 29 | cm.state.rulerDiv.textContent = "" 30 | var val = cm.getOption("rulers"); 31 | var cw = cm.defaultCharWidth(); 32 | var left = cm.charCoords(CodeMirror.Pos(cm.firstLine(), 0), "div").left; 33 | cm.state.rulerDiv.style.minHeight = (cm.display.scroller.offsetHeight + 30) + "px"; 34 | for (var i = 0; i < val.length; i++) { 35 | var elt = document.createElement("div"); 36 | elt.className = "CodeMirror-ruler"; 37 | var col, conf = val[i]; 38 | if (typeof conf == "number") { 39 | col = conf; 40 | } else { 41 | col = conf.column; 42 | if (conf.className) elt.className += " " + conf.className; 43 | if (conf.color) elt.style.borderColor = conf.color; 44 | if (conf.lineStyle) elt.style.borderLeftStyle = conf.lineStyle; 45 | if (conf.width) elt.style.borderLeftWidth = conf.width; 46 | } 47 | elt.style.left = (left + col * cw) + "px"; 48 | cm.state.rulerDiv.appendChild(elt) 49 | } 50 | } 51 | }); 52 | -------------------------------------------------------------------------------- /codemirror/addon/edit/closebrackets.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: https://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | var defaults = { 13 | pairs: "()[]{}''\"\"", 14 | triples: "", 15 | explode: "[]{}" 16 | }; 17 | 18 | var Pos = CodeMirror.Pos; 19 | 20 | CodeMirror.defineOption("autoCloseBrackets", false, function(cm, val, old) { 21 | if (old && old != CodeMirror.Init) { 22 | cm.removeKeyMap(keyMap); 23 | cm.state.closeBrackets = null; 24 | } 25 | if (val) { 26 | ensureBound(getOption(val, "pairs")) 27 | cm.state.closeBrackets = val; 28 | cm.addKeyMap(keyMap); 29 | } 30 | }); 31 | 32 | function getOption(conf, name) { 33 | if (name == "pairs" && typeof conf == "string") return conf; 34 | if (typeof conf == "object" && conf[name] != null) return conf[name]; 35 | return defaults[name]; 36 | } 37 | 38 | var keyMap = {Backspace: handleBackspace, Enter: handleEnter}; 39 | function ensureBound(chars) { 40 | for (var i = 0; i < chars.length; i++) { 41 | var ch = chars.charAt(i), key = "'" + ch + "'" 42 | if (!keyMap[key]) keyMap[key] = handler(ch) 43 | } 44 | } 45 | ensureBound(defaults.pairs + "`") 46 | 47 | function handler(ch) { 48 | return function(cm) { return handleChar(cm, ch); }; 49 | } 50 | 51 | function getConfig(cm) { 52 | var deflt = cm.state.closeBrackets; 53 | if (!deflt || deflt.override) return deflt; 54 | var mode = cm.getModeAt(cm.getCursor()); 55 | return mode.closeBrackets || deflt; 56 | } 57 | 58 | function handleBackspace(cm) { 59 | var conf = getConfig(cm); 60 | if (!conf || cm.getOption("disableInput")) return CodeMirror.Pass; 61 | 62 | var pairs = getOption(conf, "pairs"); 63 | var ranges = cm.listSelections(); 64 | for (var i = 0; i < ranges.length; i++) { 65 | if (!ranges[i].empty()) return CodeMirror.Pass; 66 | var around = charsAround(cm, ranges[i].head); 67 | if (!around || pairs.indexOf(around) % 2 != 0) return CodeMirror.Pass; 68 | } 69 | for (var i = ranges.length - 1; i >= 0; i--) { 70 | var cur = ranges[i].head; 71 | cm.replaceRange("", Pos(cur.line, cur.ch - 1), Pos(cur.line, cur.ch + 1), "+delete"); 72 | } 73 | } 74 | 75 | function handleEnter(cm) { 76 | var conf = getConfig(cm); 77 | var explode = conf && getOption(conf, "explode"); 78 | if (!explode || cm.getOption("disableInput")) return CodeMirror.Pass; 79 | 80 | var ranges = cm.listSelections(); 81 | for (var i = 0; i < ranges.length; i++) { 82 | if (!ranges[i].empty()) return CodeMirror.Pass; 83 | var around = charsAround(cm, ranges[i].head); 84 | if (!around || explode.indexOf(around) % 2 != 0) return CodeMirror.Pass; 85 | } 86 | cm.operation(function() { 87 | var linesep = cm.lineSeparator() || "\n"; 88 | cm.replaceSelection(linesep + linesep, null); 89 | cm.execCommand("goCharLeft"); 90 | ranges = cm.listSelections(); 91 | for (var i = 0; i < ranges.length; i++) { 92 | var line = ranges[i].head.line; 93 | cm.indentLine(line, null, true); 94 | cm.indentLine(line + 1, null, true); 95 | } 96 | }); 97 | } 98 | 99 | function contractSelection(sel) { 100 | var inverted = CodeMirror.cmpPos(sel.anchor, sel.head) > 0; 101 | return {anchor: new Pos(sel.anchor.line, sel.anchor.ch + (inverted ? -1 : 1)), 102 | head: new Pos(sel.head.line, sel.head.ch + (inverted ? 1 : -1))}; 103 | } 104 | 105 | function handleChar(cm, ch) { 106 | var conf = getConfig(cm); 107 | if (!conf || cm.getOption("disableInput")) return CodeMirror.Pass; 108 | 109 | var pairs = getOption(conf, "pairs"); 110 | var pos = pairs.indexOf(ch); 111 | if (pos == -1) return CodeMirror.Pass; 112 | var triples = getOption(conf, "triples"); 113 | 114 | var identical = pairs.charAt(pos + 1) == ch; 115 | var ranges = cm.listSelections(); 116 | var opening = pos % 2 == 0; 117 | 118 | var type; 119 | for (var i = 0; i < ranges.length; i++) { 120 | var range = ranges[i], cur = range.head, curType; 121 | var next = cm.getRange(cur, Pos(cur.line, cur.ch + 1)); 122 | if (opening && !range.empty()) { 123 | curType = "surround"; 124 | } else if ((identical || !opening) && next == ch) { 125 | if (identical && stringStartsAfter(cm, cur)) 126 | curType = "both"; 127 | else if (triples.indexOf(ch) >= 0 && cm.getRange(cur, Pos(cur.line, cur.ch + 3)) == ch + ch + ch) 128 | curType = "skipThree"; 129 | else 130 | curType = "skip"; 131 | } else if (identical && cur.ch > 1 && triples.indexOf(ch) >= 0 && 132 | cm.getRange(Pos(cur.line, cur.ch - 2), cur) == ch + ch) { 133 | if (cur.ch > 2 && /\bstring/.test(cm.getTokenTypeAt(Pos(cur.line, cur.ch - 2)))) return CodeMirror.Pass; 134 | curType = "addFour"; 135 | } else if (identical) { 136 | var prev = cur.ch == 0 ? " " : cm.getRange(Pos(cur.line, cur.ch - 1), cur) 137 | if (!CodeMirror.isWordChar(next) && prev != ch && !CodeMirror.isWordChar(prev)) curType = "both"; 138 | else return CodeMirror.Pass; 139 | } else if (opening) { 140 | curType = "both"; 141 | } else { 142 | return CodeMirror.Pass; 143 | } 144 | if (!type) type = curType; 145 | else if (type != curType) return CodeMirror.Pass; 146 | } 147 | 148 | var left = pos % 2 ? pairs.charAt(pos - 1) : ch; 149 | var right = pos % 2 ? ch : pairs.charAt(pos + 1); 150 | cm.operation(function() { 151 | if (type == "skip") { 152 | cm.execCommand("goCharRight"); 153 | } else if (type == "skipThree") { 154 | for (var i = 0; i < 3; i++) 155 | cm.execCommand("goCharRight"); 156 | } else if (type == "surround") { 157 | var sels = cm.getSelections(); 158 | for (var i = 0; i < sels.length; i++) 159 | sels[i] = left + sels[i] + right; 160 | cm.replaceSelections(sels, "around"); 161 | sels = cm.listSelections().slice(); 162 | for (var i = 0; i < sels.length; i++) 163 | sels[i] = contractSelection(sels[i]); 164 | cm.setSelections(sels); 165 | } else if (type == "both") { 166 | cm.replaceSelection(left + right, null); 167 | cm.triggerElectric(left + right); 168 | cm.execCommand("goCharLeft"); 169 | } else if (type == "addFour") { 170 | cm.replaceSelection(left + left + left + left, "before"); 171 | cm.execCommand("goCharRight"); 172 | } 173 | }); 174 | } 175 | 176 | function charsAround(cm, pos) { 177 | var str = cm.getRange(Pos(pos.line, pos.ch - 1), 178 | Pos(pos.line, pos.ch + 1)); 179 | return str.length == 2 ? str : null; 180 | } 181 | 182 | function stringStartsAfter(cm, pos) { 183 | var token = cm.getTokenAt(Pos(pos.line, pos.ch + 1)) 184 | return /\bstring/.test(token.type) && token.start == pos.ch && 185 | (pos.ch == 0 || !/\bstring/.test(cm.getTokenTypeAt(pos))) 186 | } 187 | }); 188 | -------------------------------------------------------------------------------- /codemirror/addon/edit/continuelist.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: https://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | var listRE = /^(\s*)(>[> ]*|[*+-] \[[x ]\]\s|[*+-]\s|(\d+)([.)]))(\s*)/, 15 | emptyListRE = /^(\s*)(>[> ]*|[*+-] \[[x ]\]|[*+-]|(\d+)[.)])(\s*)$/, 16 | unorderedListRE = /[*+-]\s/; 17 | 18 | CodeMirror.commands.newlineAndIndentContinueMarkdownList = function(cm) { 19 | if (cm.getOption("disableInput")) return CodeMirror.Pass; 20 | var ranges = cm.listSelections(), replacements = []; 21 | for (var i = 0; i < ranges.length; i++) { 22 | var pos = ranges[i].head; 23 | var eolState = cm.getStateAfter(pos.line); 24 | var inList = eolState.list !== false; 25 | var inQuote = eolState.quote !== 0; 26 | 27 | var line = cm.getLine(pos.line), match = listRE.exec(line); 28 | var cursorBeforeBullet = /^\s*$/.test(line.slice(0, pos.ch)); 29 | if (!ranges[i].empty() || (!inList && !inQuote) || !match || cursorBeforeBullet) { 30 | cm.execCommand("newlineAndIndent"); 31 | return; 32 | } 33 | if (emptyListRE.test(line)) { 34 | if (!/>\s*$/.test(line)) cm.replaceRange("", { 35 | line: pos.line, ch: 0 36 | }, { 37 | line: pos.line, ch: pos.ch + 1 38 | }); 39 | replacements[i] = "\n"; 40 | } else { 41 | var indent = match[1], after = match[5]; 42 | var numbered = !(unorderedListRE.test(match[2]) || match[2].indexOf(">") >= 0); 43 | var bullet = numbered ? (parseInt(match[3], 10) + 1) + match[4] : match[2].replace("x", " "); 44 | replacements[i] = "\n" + indent + bullet + after; 45 | 46 | if (numbered) incrementRemainingMarkdownListNumbers(cm, pos); 47 | } 48 | } 49 | 50 | cm.replaceSelections(replacements); 51 | }; 52 | 53 | // Auto-updating Markdown list numbers when a new item is added to the 54 | // middle of a list 55 | function incrementRemainingMarkdownListNumbers(cm, pos) { 56 | var startLine = pos.line, lookAhead = 0, skipCount = 0; 57 | var startItem = listRE.exec(cm.getLine(startLine)), startIndent = startItem[1]; 58 | 59 | do { 60 | lookAhead += 1; 61 | var nextLineNumber = startLine + lookAhead; 62 | var nextLine = cm.getLine(nextLineNumber), nextItem = listRE.exec(nextLine); 63 | 64 | if (nextItem) { 65 | var nextIndent = nextItem[1]; 66 | var newNumber = (parseInt(startItem[3], 10) + lookAhead - skipCount); 67 | var nextNumber = (parseInt(nextItem[3], 10)), itemNumber = nextNumber; 68 | 69 | if (startIndent === nextIndent && !isNaN(nextNumber)) { 70 | if (newNumber === nextNumber) itemNumber = nextNumber + 1; 71 | if (newNumber > nextNumber) itemNumber = newNumber + 1; 72 | cm.replaceRange( 73 | nextLine.replace(listRE, nextIndent + itemNumber + nextItem[4] + nextItem[5]), 74 | { 75 | line: nextLineNumber, ch: 0 76 | }, { 77 | line: nextLineNumber, ch: nextLine.length 78 | }); 79 | } else { 80 | if (startIndent.length > nextIndent.length) return; 81 | // This doesn't run if the next line immediatley indents, as it is 82 | // not clear of the users intention (new indented item or same level) 83 | if ((startIndent.length < nextIndent.length) && (lookAhead === 1)) return; 84 | skipCount += 1; 85 | } 86 | } 87 | } while (nextItem); 88 | } 89 | }); 90 | -------------------------------------------------------------------------------- /codemirror/addon/edit/matchbrackets.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: https://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | var ie_lt8 = /MSIE \d/.test(navigator.userAgent) && 13 | (document.documentMode == null || document.documentMode < 8); 14 | 15 | var Pos = CodeMirror.Pos; 16 | 17 | var matching = {"(": ")>", ")": "(<", "[": "]>", "]": "[<", "{": "}>", "}": "{<", "<": ">>", ">": "<<"}; 18 | 19 | function bracketRegex(config) { 20 | return config && config.bracketRegex || /[(){}[\]]/ 21 | } 22 | 23 | function findMatchingBracket(cm, where, config) { 24 | var line = cm.getLineHandle(where.line), pos = where.ch - 1; 25 | var afterCursor = config && config.afterCursor 26 | if (afterCursor == null) 27 | afterCursor = /(^| )cm-fat-cursor($| )/.test(cm.getWrapperElement().className) 28 | var re = bracketRegex(config) 29 | 30 | // A cursor is defined as between two characters, but in in vim command mode 31 | // (i.e. not insert mode), the cursor is visually represented as a 32 | // highlighted box on top of the 2nd character. Otherwise, we allow matches 33 | // from before or after the cursor. 34 | var match = (!afterCursor && pos >= 0 && re.test(line.text.charAt(pos)) && matching[line.text.charAt(pos)]) || 35 | re.test(line.text.charAt(pos + 1)) && matching[line.text.charAt(++pos)]; 36 | if (!match) return null; 37 | var dir = match.charAt(1) == ">" ? 1 : -1; 38 | if (config && config.strict && (dir > 0) != (pos == where.ch)) return null; 39 | var style = cm.getTokenTypeAt(Pos(where.line, pos + 1)); 40 | 41 | var found = scanForBracket(cm, Pos(where.line, pos + (dir > 0 ? 1 : 0)), dir, style || null, config); 42 | if (found == null) return null; 43 | return {from: Pos(where.line, pos), to: found && found.pos, 44 | match: found && found.ch == match.charAt(0), forward: dir > 0}; 45 | } 46 | 47 | // bracketRegex is used to specify which type of bracket to scan 48 | // should be a regexp, e.g. /[[\]]/ 49 | // 50 | // Note: If "where" is on an open bracket, then this bracket is ignored. 51 | // 52 | // Returns false when no bracket was found, null when it reached 53 | // maxScanLines and gave up 54 | function scanForBracket(cm, where, dir, style, config) { 55 | var maxScanLen = (config && config.maxScanLineLength) || 10000; 56 | var maxScanLines = (config && config.maxScanLines) || 1000; 57 | 58 | var stack = []; 59 | var re = bracketRegex(config) 60 | var lineEnd = dir > 0 ? Math.min(where.line + maxScanLines, cm.lastLine() + 1) 61 | : Math.max(cm.firstLine() - 1, where.line - maxScanLines); 62 | for (var lineNo = where.line; lineNo != lineEnd; lineNo += dir) { 63 | var line = cm.getLine(lineNo); 64 | if (!line) continue; 65 | var pos = dir > 0 ? 0 : line.length - 1, end = dir > 0 ? line.length : -1; 66 | if (line.length > maxScanLen) continue; 67 | if (lineNo == where.line) pos = where.ch - (dir < 0 ? 1 : 0); 68 | for (; pos != end; pos += dir) { 69 | var ch = line.charAt(pos); 70 | if (re.test(ch) && (style === undefined || cm.getTokenTypeAt(Pos(lineNo, pos + 1)) == style)) { 71 | var match = matching[ch]; 72 | if ((match.charAt(1) == ">") == (dir > 0)) stack.push(ch); 73 | else if (!stack.length) return {pos: Pos(lineNo, pos), ch: ch}; 74 | else stack.pop(); 75 | } 76 | } 77 | } 78 | return lineNo - dir == (dir > 0 ? cm.lastLine() : cm.firstLine()) ? false : null; 79 | } 80 | 81 | function matchBrackets(cm, autoclear, config) { 82 | // Disable brace matching in long lines, since it'll cause hugely slow updates 83 | var maxHighlightLen = cm.state.matchBrackets.maxHighlightLineLength || 1000; 84 | var marks = [], ranges = cm.listSelections(); 85 | for (var i = 0; i < ranges.length; i++) { 86 | var match = ranges[i].empty() && findMatchingBracket(cm, ranges[i].head, config); 87 | if (match && cm.getLine(match.from.line).length <= maxHighlightLen) { 88 | var style = match.match ? "CodeMirror-matchingbracket" : "CodeMirror-nonmatchingbracket"; 89 | marks.push(cm.markText(match.from, Pos(match.from.line, match.from.ch + 1), {className: style})); 90 | if (match.to && cm.getLine(match.to.line).length <= maxHighlightLen) 91 | marks.push(cm.markText(match.to, Pos(match.to.line, match.to.ch + 1), {className: style})); 92 | } 93 | } 94 | 95 | if (marks.length) { 96 | // Kludge to work around the IE bug from issue #1193, where text 97 | // input stops going to the textare whever this fires. 98 | if (ie_lt8 && cm.state.focused) cm.focus(); 99 | 100 | var clear = function() { 101 | cm.operation(function() { 102 | for (var i = 0; i < marks.length; i++) marks[i].clear(); 103 | }); 104 | }; 105 | if (autoclear) setTimeout(clear, 800); 106 | else return clear; 107 | } 108 | } 109 | 110 | function doMatchBrackets(cm) { 111 | cm.operation(function() { 112 | if (cm.state.matchBrackets.currentlyHighlighted) { 113 | cm.state.matchBrackets.currentlyHighlighted(); 114 | cm.state.matchBrackets.currentlyHighlighted = null; 115 | } 116 | cm.state.matchBrackets.currentlyHighlighted = matchBrackets(cm, false, cm.state.matchBrackets); 117 | }); 118 | } 119 | 120 | CodeMirror.defineOption("matchBrackets", false, function(cm, val, old) { 121 | if (old && old != CodeMirror.Init) { 122 | cm.off("cursorActivity", doMatchBrackets); 123 | if (cm.state.matchBrackets && cm.state.matchBrackets.currentlyHighlighted) { 124 | cm.state.matchBrackets.currentlyHighlighted(); 125 | cm.state.matchBrackets.currentlyHighlighted = null; 126 | } 127 | } 128 | if (val) { 129 | cm.state.matchBrackets = typeof val == "object" ? val : {}; 130 | cm.on("cursorActivity", doMatchBrackets); 131 | } 132 | }); 133 | 134 | CodeMirror.defineExtension("matchBrackets", function() {matchBrackets(this, true);}); 135 | CodeMirror.defineExtension("findMatchingBracket", function(pos, config, oldConfig){ 136 | // Backwards-compatibility kludge 137 | if (oldConfig || typeof config == "boolean") { 138 | if (!oldConfig) { 139 | config = config ? {strict: true} : null 140 | } else { 141 | oldConfig.strict = config 142 | config = oldConfig 143 | } 144 | } 145 | return findMatchingBracket(this, pos, config) 146 | }); 147 | CodeMirror.defineExtension("scanForBracket", function(pos, dir, style, config){ 148 | return scanForBracket(this, pos, dir, style, config); 149 | }); 150 | }); 151 | -------------------------------------------------------------------------------- /codemirror/addon/edit/matchtags.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: https://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror"), require("../fold/xml-fold")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror", "../fold/xml-fold"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | CodeMirror.defineOption("matchTags", false, function(cm, val, old) { 15 | if (old && old != CodeMirror.Init) { 16 | cm.off("cursorActivity", doMatchTags); 17 | cm.off("viewportChange", maybeUpdateMatch); 18 | clear(cm); 19 | } 20 | if (val) { 21 | cm.state.matchBothTags = typeof val == "object" && val.bothTags; 22 | cm.on("cursorActivity", doMatchTags); 23 | cm.on("viewportChange", maybeUpdateMatch); 24 | doMatchTags(cm); 25 | } 26 | }); 27 | 28 | function clear(cm) { 29 | if (cm.state.tagHit) cm.state.tagHit.clear(); 30 | if (cm.state.tagOther) cm.state.tagOther.clear(); 31 | cm.state.tagHit = cm.state.tagOther = null; 32 | } 33 | 34 | function doMatchTags(cm) { 35 | cm.state.failedTagMatch = false; 36 | cm.operation(function() { 37 | clear(cm); 38 | if (cm.somethingSelected()) return; 39 | var cur = cm.getCursor(), range = cm.getViewport(); 40 | range.from = Math.min(range.from, cur.line); range.to = Math.max(cur.line + 1, range.to); 41 | var match = CodeMirror.findMatchingTag(cm, cur, range); 42 | if (!match) return; 43 | if (cm.state.matchBothTags) { 44 | var hit = match.at == "open" ? match.open : match.close; 45 | if (hit) cm.state.tagHit = cm.markText(hit.from, hit.to, {className: "CodeMirror-matchingtag"}); 46 | } 47 | var other = match.at == "close" ? match.open : match.close; 48 | if (other) 49 | cm.state.tagOther = cm.markText(other.from, other.to, {className: "CodeMirror-matchingtag"}); 50 | else 51 | cm.state.failedTagMatch = true; 52 | }); 53 | } 54 | 55 | function maybeUpdateMatch(cm) { 56 | if (cm.state.failedTagMatch) doMatchTags(cm); 57 | } 58 | 59 | CodeMirror.commands.toMatchingTag = function(cm) { 60 | var found = CodeMirror.findMatchingTag(cm, cm.getCursor()); 61 | if (found) { 62 | var other = found.at == "close" ? found.open : found.close; 63 | if (other) cm.extendSelection(other.to, other.from); 64 | } 65 | }; 66 | }); 67 | -------------------------------------------------------------------------------- /codemirror/addon/edit/trailingspace.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: https://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | CodeMirror.defineOption("showTrailingSpace", false, function(cm, val, prev) { 13 | if (prev == CodeMirror.Init) prev = false; 14 | if (prev && !val) 15 | cm.removeOverlay("trailingspace"); 16 | else if (!prev && val) 17 | cm.addOverlay({ 18 | token: function(stream) { 19 | for (var l = stream.string.length, i = l; i && /\s/.test(stream.string.charAt(i - 1)); --i) {} 20 | if (i > stream.pos) { stream.pos = i; return null; } 21 | stream.pos = l; 22 | return "trailingspace"; 23 | }, 24 | name: "trailingspace" 25 | }); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /codemirror/addon/fold/brace-fold.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: https://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | CodeMirror.registerHelper("fold", "brace", function(cm, start) { 15 | var line = start.line, lineText = cm.getLine(line); 16 | var tokenType; 17 | 18 | function findOpening(openCh) { 19 | for (var at = start.ch, pass = 0;;) { 20 | var found = at <= 0 ? -1 : lineText.lastIndexOf(openCh, at - 1); 21 | if (found == -1) { 22 | if (pass == 1) break; 23 | pass = 1; 24 | at = lineText.length; 25 | continue; 26 | } 27 | if (pass == 1 && found < start.ch) break; 28 | tokenType = cm.getTokenTypeAt(CodeMirror.Pos(line, found + 1)); 29 | if (!/^(comment|string)/.test(tokenType)) return found + 1; 30 | at = found - 1; 31 | } 32 | } 33 | 34 | var startToken = "{", endToken = "}", startCh = findOpening("{"); 35 | if (startCh == null) { 36 | startToken = "[", endToken = "]"; 37 | startCh = findOpening("["); 38 | } 39 | 40 | if (startCh == null) return; 41 | var count = 1, lastLine = cm.lastLine(), end, endCh; 42 | outer: for (var i = line; i <= lastLine; ++i) { 43 | var text = cm.getLine(i), pos = i == line ? startCh : 0; 44 | for (;;) { 45 | var nextOpen = text.indexOf(startToken, pos), nextClose = text.indexOf(endToken, pos); 46 | if (nextOpen < 0) nextOpen = text.length; 47 | if (nextClose < 0) nextClose = text.length; 48 | pos = Math.min(nextOpen, nextClose); 49 | if (pos == text.length) break; 50 | if (cm.getTokenTypeAt(CodeMirror.Pos(i, pos + 1)) == tokenType) { 51 | if (pos == nextOpen) ++count; 52 | else if (!--count) { end = i; endCh = pos; break outer; } 53 | } 54 | ++pos; 55 | } 56 | } 57 | if (end == null || line == end) return; 58 | return {from: CodeMirror.Pos(line, startCh), 59 | to: CodeMirror.Pos(end, endCh)}; 60 | }); 61 | 62 | CodeMirror.registerHelper("fold", "import", function(cm, start) { 63 | function hasImport(line) { 64 | if (line < cm.firstLine() || line > cm.lastLine()) return null; 65 | var start = cm.getTokenAt(CodeMirror.Pos(line, 1)); 66 | if (!/\S/.test(start.string)) start = cm.getTokenAt(CodeMirror.Pos(line, start.end + 1)); 67 | if (start.type != "keyword" || start.string != "import") return null; 68 | // Now find closing semicolon, return its position 69 | for (var i = line, e = Math.min(cm.lastLine(), line + 10); i <= e; ++i) { 70 | var text = cm.getLine(i), semi = text.indexOf(";"); 71 | if (semi != -1) return {startCh: start.end, end: CodeMirror.Pos(i, semi)}; 72 | } 73 | } 74 | 75 | var startLine = start.line, has = hasImport(startLine), prev; 76 | if (!has || hasImport(startLine - 1) || ((prev = hasImport(startLine - 2)) && prev.end.line == startLine - 1)) 77 | return null; 78 | for (var end = has.end;;) { 79 | var next = hasImport(end.line + 1); 80 | if (next == null) break; 81 | end = next.end; 82 | } 83 | return {from: cm.clipPos(CodeMirror.Pos(startLine, has.startCh + 1)), to: end}; 84 | }); 85 | 86 | CodeMirror.registerHelper("fold", "include", function(cm, start) { 87 | function hasInclude(line) { 88 | if (line < cm.firstLine() || line > cm.lastLine()) return null; 89 | var start = cm.getTokenAt(CodeMirror.Pos(line, 1)); 90 | if (!/\S/.test(start.string)) start = cm.getTokenAt(CodeMirror.Pos(line, start.end + 1)); 91 | if (start.type == "meta" && start.string.slice(0, 8) == "#include") return start.start + 8; 92 | } 93 | 94 | var startLine = start.line, has = hasInclude(startLine); 95 | if (has == null || hasInclude(startLine - 1) != null) return null; 96 | for (var end = startLine;;) { 97 | var next = hasInclude(end + 1); 98 | if (next == null) break; 99 | ++end; 100 | } 101 | return {from: CodeMirror.Pos(startLine, has + 1), 102 | to: cm.clipPos(CodeMirror.Pos(end))}; 103 | }); 104 | 105 | }); 106 | -------------------------------------------------------------------------------- /codemirror/addon/fold/comment-fold.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: https://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | CodeMirror.registerGlobalHelper("fold", "comment", function(mode) { 15 | return mode.blockCommentStart && mode.blockCommentEnd; 16 | }, function(cm, start) { 17 | var mode = cm.getModeAt(start), startToken = mode.blockCommentStart, endToken = mode.blockCommentEnd; 18 | if (!startToken || !endToken) return; 19 | var line = start.line, lineText = cm.getLine(line); 20 | 21 | var startCh; 22 | for (var at = start.ch, pass = 0;;) { 23 | var found = at <= 0 ? -1 : lineText.lastIndexOf(startToken, at - 1); 24 | if (found == -1) { 25 | if (pass == 1) return; 26 | pass = 1; 27 | at = lineText.length; 28 | continue; 29 | } 30 | if (pass == 1 && found < start.ch) return; 31 | if (/comment/.test(cm.getTokenTypeAt(CodeMirror.Pos(line, found + 1))) && 32 | (found == 0 || lineText.slice(found - endToken.length, found) == endToken || 33 | !/comment/.test(cm.getTokenTypeAt(CodeMirror.Pos(line, found))))) { 34 | startCh = found + startToken.length; 35 | break; 36 | } 37 | at = found - 1; 38 | } 39 | 40 | var depth = 1, lastLine = cm.lastLine(), end, endCh; 41 | outer: for (var i = line; i <= lastLine; ++i) { 42 | var text = cm.getLine(i), pos = i == line ? startCh : 0; 43 | for (;;) { 44 | var nextOpen = text.indexOf(startToken, pos), nextClose = text.indexOf(endToken, pos); 45 | if (nextOpen < 0) nextOpen = text.length; 46 | if (nextClose < 0) nextClose = text.length; 47 | pos = Math.min(nextOpen, nextClose); 48 | if (pos == text.length) break; 49 | if (pos == nextOpen) ++depth; 50 | else if (!--depth) { end = i; endCh = pos; break outer; } 51 | ++pos; 52 | } 53 | } 54 | if (end == null || line == end && endCh == startCh) return; 55 | return {from: CodeMirror.Pos(line, startCh), 56 | to: CodeMirror.Pos(end, endCh)}; 57 | }); 58 | 59 | }); 60 | -------------------------------------------------------------------------------- /codemirror/addon/fold/foldcode.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: https://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | function doFold(cm, pos, options, force) { 15 | if (options && options.call) { 16 | var finder = options; 17 | options = null; 18 | } else { 19 | var finder = getOption(cm, options, "rangeFinder"); 20 | } 21 | if (typeof pos == "number") pos = CodeMirror.Pos(pos, 0); 22 | var minSize = getOption(cm, options, "minFoldSize"); 23 | 24 | function getRange(allowFolded) { 25 | var range = finder(cm, pos); 26 | if (!range || range.to.line - range.from.line < minSize) return null; 27 | var marks = cm.findMarksAt(range.from); 28 | for (var i = 0; i < marks.length; ++i) { 29 | if (marks[i].__isFold && force !== "fold") { 30 | if (!allowFolded) return null; 31 | range.cleared = true; 32 | marks[i].clear(); 33 | } 34 | } 35 | return range; 36 | } 37 | 38 | var range = getRange(true); 39 | if (getOption(cm, options, "scanUp")) while (!range && pos.line > cm.firstLine()) { 40 | pos = CodeMirror.Pos(pos.line - 1, 0); 41 | range = getRange(false); 42 | } 43 | if (!range || range.cleared || force === "unfold") return; 44 | 45 | var myWidget = makeWidget(cm, options); 46 | CodeMirror.on(myWidget, "mousedown", function(e) { 47 | myRange.clear(); 48 | CodeMirror.e_preventDefault(e); 49 | }); 50 | var myRange = cm.markText(range.from, range.to, { 51 | replacedWith: myWidget, 52 | clearOnEnter: getOption(cm, options, "clearOnEnter"), 53 | __isFold: true 54 | }); 55 | myRange.on("clear", function(from, to) { 56 | CodeMirror.signal(cm, "unfold", cm, from, to); 57 | }); 58 | CodeMirror.signal(cm, "fold", cm, range.from, range.to); 59 | } 60 | 61 | function makeWidget(cm, options) { 62 | var widget = getOption(cm, options, "widget"); 63 | if (typeof widget == "string") { 64 | var text = document.createTextNode(widget); 65 | widget = document.createElement("span"); 66 | widget.appendChild(text); 67 | widget.className = "CodeMirror-foldmarker"; 68 | } else if (widget) { 69 | widget = widget.cloneNode(true) 70 | } 71 | return widget; 72 | } 73 | 74 | // Clumsy backwards-compatible interface 75 | CodeMirror.newFoldFunction = function(rangeFinder, widget) { 76 | return function(cm, pos) { doFold(cm, pos, {rangeFinder: rangeFinder, widget: widget}); }; 77 | }; 78 | 79 | // New-style interface 80 | CodeMirror.defineExtension("foldCode", function(pos, options, force) { 81 | doFold(this, pos, options, force); 82 | }); 83 | 84 | CodeMirror.defineExtension("isFolded", function(pos) { 85 | var marks = this.findMarksAt(pos); 86 | for (var i = 0; i < marks.length; ++i) 87 | if (marks[i].__isFold) return true; 88 | }); 89 | 90 | CodeMirror.commands.toggleFold = function(cm) { 91 | cm.foldCode(cm.getCursor()); 92 | }; 93 | CodeMirror.commands.fold = function(cm) { 94 | cm.foldCode(cm.getCursor(), null, "fold"); 95 | }; 96 | CodeMirror.commands.unfold = function(cm) { 97 | cm.foldCode(cm.getCursor(), null, "unfold"); 98 | }; 99 | CodeMirror.commands.foldAll = function(cm) { 100 | cm.operation(function() { 101 | for (var i = cm.firstLine(), e = cm.lastLine(); i <= e; i++) 102 | cm.foldCode(CodeMirror.Pos(i, 0), null, "fold"); 103 | }); 104 | }; 105 | CodeMirror.commands.unfoldAll = function(cm) { 106 | cm.operation(function() { 107 | for (var i = cm.firstLine(), e = cm.lastLine(); i <= e; i++) 108 | cm.foldCode(CodeMirror.Pos(i, 0), null, "unfold"); 109 | }); 110 | }; 111 | 112 | CodeMirror.registerHelper("fold", "combine", function() { 113 | var funcs = Array.prototype.slice.call(arguments, 0); 114 | return function(cm, start) { 115 | for (var i = 0; i < funcs.length; ++i) { 116 | var found = funcs[i](cm, start); 117 | if (found) return found; 118 | } 119 | }; 120 | }); 121 | 122 | CodeMirror.registerHelper("fold", "auto", function(cm, start) { 123 | var helpers = cm.getHelpers(start, "fold"); 124 | for (var i = 0; i < helpers.length; i++) { 125 | var cur = helpers[i](cm, start); 126 | if (cur) return cur; 127 | } 128 | }); 129 | 130 | var defaultOptions = { 131 | rangeFinder: CodeMirror.fold.auto, 132 | widget: "\u2194", 133 | minFoldSize: 0, 134 | scanUp: false, 135 | clearOnEnter: true 136 | }; 137 | 138 | CodeMirror.defineOption("foldOptions", null); 139 | 140 | function getOption(cm, options, name) { 141 | if (options && options[name] !== undefined) 142 | return options[name]; 143 | var editorOptions = cm.options.foldOptions; 144 | if (editorOptions && editorOptions[name] !== undefined) 145 | return editorOptions[name]; 146 | return defaultOptions[name]; 147 | } 148 | 149 | CodeMirror.defineExtension("foldOption", function(options, name) { 150 | return getOption(this, options, name); 151 | }); 152 | }); 153 | -------------------------------------------------------------------------------- /codemirror/addon/fold/foldgutter.css: -------------------------------------------------------------------------------- 1 | .CodeMirror-foldmarker { 2 | color: blue; 3 | text-shadow: #b9f 1px 1px 2px, #b9f -1px -1px 2px, #b9f 1px -1px 2px, #b9f -1px 1px 2px; 4 | font-family: arial; 5 | line-height: .3; 6 | cursor: pointer; 7 | } 8 | .CodeMirror-foldgutter { 9 | width: .7em; 10 | } 11 | .CodeMirror-foldgutter-open, 12 | .CodeMirror-foldgutter-folded { 13 | cursor: pointer; 14 | } 15 | .CodeMirror-foldgutter-open:after { 16 | content: "\25BE"; 17 | } 18 | .CodeMirror-foldgutter-folded:after { 19 | content: "\25B8"; 20 | } 21 | -------------------------------------------------------------------------------- /codemirror/addon/fold/foldgutter.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: https://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror"), require("./foldcode")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror", "./foldcode"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | CodeMirror.defineOption("foldGutter", false, function(cm, val, old) { 15 | if (old && old != CodeMirror.Init) { 16 | cm.clearGutter(cm.state.foldGutter.options.gutter); 17 | cm.state.foldGutter = null; 18 | cm.off("gutterClick", onGutterClick); 19 | cm.off("change", onChange); 20 | cm.off("viewportChange", onViewportChange); 21 | cm.off("fold", onFold); 22 | cm.off("unfold", onFold); 23 | cm.off("swapDoc", onChange); 24 | } 25 | if (val) { 26 | cm.state.foldGutter = new State(parseOptions(val)); 27 | updateInViewport(cm); 28 | cm.on("gutterClick", onGutterClick); 29 | cm.on("change", onChange); 30 | cm.on("viewportChange", onViewportChange); 31 | cm.on("fold", onFold); 32 | cm.on("unfold", onFold); 33 | cm.on("swapDoc", onChange); 34 | } 35 | }); 36 | 37 | var Pos = CodeMirror.Pos; 38 | 39 | function State(options) { 40 | this.options = options; 41 | this.from = this.to = 0; 42 | } 43 | 44 | function parseOptions(opts) { 45 | if (opts === true) opts = {}; 46 | if (opts.gutter == null) opts.gutter = "CodeMirror-foldgutter"; 47 | if (opts.indicatorOpen == null) opts.indicatorOpen = "CodeMirror-foldgutter-open"; 48 | if (opts.indicatorFolded == null) opts.indicatorFolded = "CodeMirror-foldgutter-folded"; 49 | return opts; 50 | } 51 | 52 | function isFolded(cm, line) { 53 | var marks = cm.findMarks(Pos(line, 0), Pos(line + 1, 0)); 54 | for (var i = 0; i < marks.length; ++i) 55 | if (marks[i].__isFold && marks[i].find().from.line == line) return marks[i]; 56 | } 57 | 58 | function marker(spec) { 59 | if (typeof spec == "string") { 60 | var elt = document.createElement("div"); 61 | elt.className = spec + " CodeMirror-guttermarker-subtle"; 62 | return elt; 63 | } else { 64 | return spec.cloneNode(true); 65 | } 66 | } 67 | 68 | function updateFoldInfo(cm, from, to) { 69 | var opts = cm.state.foldGutter.options, cur = from; 70 | var minSize = cm.foldOption(opts, "minFoldSize"); 71 | var func = cm.foldOption(opts, "rangeFinder"); 72 | cm.eachLine(from, to, function(line) { 73 | var mark = null; 74 | if (isFolded(cm, cur)) { 75 | mark = marker(opts.indicatorFolded); 76 | } else { 77 | var pos = Pos(cur, 0); 78 | var range = func && func(cm, pos); 79 | if (range && range.to.line - range.from.line >= minSize) 80 | mark = marker(opts.indicatorOpen); 81 | } 82 | cm.setGutterMarker(line, opts.gutter, mark); 83 | ++cur; 84 | }); 85 | } 86 | 87 | function updateInViewport(cm) { 88 | var vp = cm.getViewport(), state = cm.state.foldGutter; 89 | if (!state) return; 90 | cm.operation(function() { 91 | updateFoldInfo(cm, vp.from, vp.to); 92 | }); 93 | state.from = vp.from; state.to = vp.to; 94 | } 95 | 96 | function onGutterClick(cm, line, gutter) { 97 | var state = cm.state.foldGutter; 98 | if (!state) return; 99 | var opts = state.options; 100 | if (gutter != opts.gutter) return; 101 | var folded = isFolded(cm, line); 102 | if (folded) folded.clear(); 103 | else cm.foldCode(Pos(line, 0), opts.rangeFinder); 104 | } 105 | 106 | function onChange(cm) { 107 | var state = cm.state.foldGutter; 108 | if (!state) return; 109 | var opts = state.options; 110 | state.from = state.to = 0; 111 | clearTimeout(state.changeUpdate); 112 | state.changeUpdate = setTimeout(function() { updateInViewport(cm); }, opts.foldOnChangeTimeSpan || 600); 113 | } 114 | 115 | function onViewportChange(cm) { 116 | var state = cm.state.foldGutter; 117 | if (!state) return; 118 | var opts = state.options; 119 | clearTimeout(state.changeUpdate); 120 | state.changeUpdate = setTimeout(function() { 121 | var vp = cm.getViewport(); 122 | if (state.from == state.to || vp.from - state.to > 20 || state.from - vp.to > 20) { 123 | updateInViewport(cm); 124 | } else { 125 | cm.operation(function() { 126 | if (vp.from < state.from) { 127 | updateFoldInfo(cm, vp.from, state.from); 128 | state.from = vp.from; 129 | } 130 | if (vp.to > state.to) { 131 | updateFoldInfo(cm, state.to, vp.to); 132 | state.to = vp.to; 133 | } 134 | }); 135 | } 136 | }, opts.updateViewportTimeSpan || 400); 137 | } 138 | 139 | function onFold(cm, from) { 140 | var state = cm.state.foldGutter; 141 | if (!state) return; 142 | var line = from.line; 143 | if (line >= state.from && line < state.to) 144 | updateFoldInfo(cm, line, line + 1); 145 | } 146 | }); 147 | -------------------------------------------------------------------------------- /codemirror/addon/fold/indent-fold.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: https://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | function lineIndent(cm, lineNo) { 15 | var text = cm.getLine(lineNo) 16 | var spaceTo = text.search(/\S/) 17 | if (spaceTo == -1 || /\bcomment\b/.test(cm.getTokenTypeAt(CodeMirror.Pos(lineNo, spaceTo + 1)))) 18 | return -1 19 | return CodeMirror.countColumn(text, null, cm.getOption("tabSize")) 20 | } 21 | 22 | CodeMirror.registerHelper("fold", "indent", function(cm, start) { 23 | var myIndent = lineIndent(cm, start.line) 24 | if (myIndent < 0) return 25 | var lastLineInFold = null 26 | 27 | // Go through lines until we find a line that definitely doesn't belong in 28 | // the block we're folding, or to the end. 29 | for (var i = start.line + 1, end = cm.lastLine(); i <= end; ++i) { 30 | var indent = lineIndent(cm, i) 31 | if (indent == -1) { 32 | } else if (indent > myIndent) { 33 | // Lines with a greater indent are considered part of the block. 34 | lastLineInFold = i; 35 | } else { 36 | // If this line has non-space, non-comment content, and is 37 | // indented less or equal to the start line, it is the start of 38 | // another block. 39 | break; 40 | } 41 | } 42 | if (lastLineInFold) return { 43 | from: CodeMirror.Pos(start.line, cm.getLine(start.line).length), 44 | to: CodeMirror.Pos(lastLineInFold, cm.getLine(lastLineInFold).length) 45 | }; 46 | }); 47 | 48 | }); 49 | -------------------------------------------------------------------------------- /codemirror/addon/fold/markdown-fold.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: https://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | CodeMirror.registerHelper("fold", "markdown", function(cm, start) { 15 | var maxDepth = 100; 16 | 17 | function isHeader(lineNo) { 18 | var tokentype = cm.getTokenTypeAt(CodeMirror.Pos(lineNo, 0)); 19 | return tokentype && /\bheader\b/.test(tokentype); 20 | } 21 | 22 | function headerLevel(lineNo, line, nextLine) { 23 | var match = line && line.match(/^#+/); 24 | if (match && isHeader(lineNo)) return match[0].length; 25 | match = nextLine && nextLine.match(/^[=\-]+\s*$/); 26 | if (match && isHeader(lineNo + 1)) return nextLine[0] == "=" ? 1 : 2; 27 | return maxDepth; 28 | } 29 | 30 | var firstLine = cm.getLine(start.line), nextLine = cm.getLine(start.line + 1); 31 | var level = headerLevel(start.line, firstLine, nextLine); 32 | if (level === maxDepth) return undefined; 33 | 34 | var lastLineNo = cm.lastLine(); 35 | var end = start.line, nextNextLine = cm.getLine(end + 2); 36 | while (end < lastLineNo) { 37 | if (headerLevel(end + 1, nextLine, nextNextLine) <= level) break; 38 | ++end; 39 | nextLine = nextNextLine; 40 | nextNextLine = cm.getLine(end + 2); 41 | } 42 | 43 | return { 44 | from: CodeMirror.Pos(start.line, firstLine.length), 45 | to: CodeMirror.Pos(end, cm.getLine(end).length) 46 | }; 47 | }); 48 | 49 | }); 50 | -------------------------------------------------------------------------------- /codemirror/addon/fold/xml-fold.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: https://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | var Pos = CodeMirror.Pos; 15 | function cmp(a, b) { return a.line - b.line || a.ch - b.ch; } 16 | 17 | 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"; 18 | var nameChar = nameStartChar + "\-\:\.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040"; 19 | var xmlTagStart = new RegExp("<(/?)([" + nameStartChar + "][" + nameChar + "]*)", "g"); 20 | 21 | function Iter(cm, line, ch, range) { 22 | this.line = line; this.ch = ch; 23 | this.cm = cm; this.text = cm.getLine(line); 24 | this.min = range ? Math.max(range.from, cm.firstLine()) : cm.firstLine(); 25 | this.max = range ? Math.min(range.to - 1, cm.lastLine()) : cm.lastLine(); 26 | } 27 | 28 | function tagAt(iter, ch) { 29 | var type = iter.cm.getTokenTypeAt(Pos(iter.line, ch)); 30 | return type && /\btag\b/.test(type); 31 | } 32 | 33 | function nextLine(iter) { 34 | if (iter.line >= iter.max) return; 35 | iter.ch = 0; 36 | iter.text = iter.cm.getLine(++iter.line); 37 | return true; 38 | } 39 | function prevLine(iter) { 40 | if (iter.line <= iter.min) return; 41 | iter.text = iter.cm.getLine(--iter.line); 42 | iter.ch = iter.text.length; 43 | return true; 44 | } 45 | 46 | function toTagEnd(iter) { 47 | for (;;) { 48 | var gt = iter.text.indexOf(">", iter.ch); 49 | if (gt == -1) { if (nextLine(iter)) continue; else return; } 50 | if (!tagAt(iter, gt + 1)) { iter.ch = gt + 1; continue; } 51 | var lastSlash = iter.text.lastIndexOf("/", gt); 52 | var selfClose = lastSlash > -1 && !/\S/.test(iter.text.slice(lastSlash + 1, gt)); 53 | iter.ch = gt + 1; 54 | return selfClose ? "selfClose" : "regular"; 55 | } 56 | } 57 | function toTagStart(iter) { 58 | for (;;) { 59 | var lt = iter.ch ? iter.text.lastIndexOf("<", iter.ch - 1) : -1; 60 | if (lt == -1) { if (prevLine(iter)) continue; else return; } 61 | if (!tagAt(iter, lt + 1)) { iter.ch = lt; continue; } 62 | xmlTagStart.lastIndex = lt; 63 | iter.ch = lt; 64 | var match = xmlTagStart.exec(iter.text); 65 | if (match && match.index == lt) return match; 66 | } 67 | } 68 | 69 | function toNextTag(iter) { 70 | for (;;) { 71 | xmlTagStart.lastIndex = iter.ch; 72 | var found = xmlTagStart.exec(iter.text); 73 | if (!found) { if (nextLine(iter)) continue; else return; } 74 | if (!tagAt(iter, found.index + 1)) { iter.ch = found.index + 1; continue; } 75 | iter.ch = found.index + found[0].length; 76 | return found; 77 | } 78 | } 79 | function toPrevTag(iter) { 80 | for (;;) { 81 | var gt = iter.ch ? iter.text.lastIndexOf(">", iter.ch - 1) : -1; 82 | if (gt == -1) { if (prevLine(iter)) continue; else return; } 83 | if (!tagAt(iter, gt + 1)) { iter.ch = gt; continue; } 84 | var lastSlash = iter.text.lastIndexOf("/", gt); 85 | var selfClose = lastSlash > -1 && !/\S/.test(iter.text.slice(lastSlash + 1, gt)); 86 | iter.ch = gt + 1; 87 | return selfClose ? "selfClose" : "regular"; 88 | } 89 | } 90 | 91 | function findMatchingClose(iter, tag) { 92 | var stack = []; 93 | for (;;) { 94 | var next = toNextTag(iter), end, startLine = iter.line, startCh = iter.ch - (next ? next[0].length : 0); 95 | if (!next || !(end = toTagEnd(iter))) return; 96 | if (end == "selfClose") continue; 97 | if (next[1]) { // closing tag 98 | for (var i = stack.length - 1; i >= 0; --i) if (stack[i] == next[2]) { 99 | stack.length = i; 100 | break; 101 | } 102 | if (i < 0 && (!tag || tag == next[2])) return { 103 | tag: next[2], 104 | from: Pos(startLine, startCh), 105 | to: Pos(iter.line, iter.ch) 106 | }; 107 | } else { // opening tag 108 | stack.push(next[2]); 109 | } 110 | } 111 | } 112 | function findMatchingOpen(iter, tag) { 113 | var stack = []; 114 | for (;;) { 115 | var prev = toPrevTag(iter); 116 | if (!prev) return; 117 | if (prev == "selfClose") { toTagStart(iter); continue; } 118 | var endLine = iter.line, endCh = iter.ch; 119 | var start = toTagStart(iter); 120 | if (!start) return; 121 | if (start[1]) { // closing tag 122 | stack.push(start[2]); 123 | } else { // opening tag 124 | for (var i = stack.length - 1; i >= 0; --i) if (stack[i] == start[2]) { 125 | stack.length = i; 126 | break; 127 | } 128 | if (i < 0 && (!tag || tag == start[2])) return { 129 | tag: start[2], 130 | from: Pos(iter.line, iter.ch), 131 | to: Pos(endLine, endCh) 132 | }; 133 | } 134 | } 135 | } 136 | 137 | CodeMirror.registerHelper("fold", "xml", function(cm, start) { 138 | var iter = new Iter(cm, start.line, 0); 139 | for (;;) { 140 | var openTag = toNextTag(iter) 141 | if (!openTag || iter.line != start.line) return 142 | var end = toTagEnd(iter) 143 | if (!end) return 144 | if (!openTag[1] && end != "selfClose") { 145 | var startPos = Pos(iter.line, iter.ch); 146 | var endPos = findMatchingClose(iter, openTag[2]); 147 | return endPos && cmp(endPos.from, startPos) > 0 ? {from: startPos, to: endPos.from} : null 148 | } 149 | } 150 | }); 151 | CodeMirror.findMatchingTag = function(cm, pos, range) { 152 | var iter = new Iter(cm, pos.line, pos.ch, range); 153 | if (iter.text.indexOf(">") == -1 && iter.text.indexOf("<") == -1) return; 154 | var end = toTagEnd(iter), to = end && Pos(iter.line, iter.ch); 155 | var start = end && toTagStart(iter); 156 | if (!end || !start || cmp(iter, pos) > 0) return; 157 | var here = {from: Pos(iter.line, iter.ch), to: to, tag: start[2]}; 158 | if (end == "selfClose") return {open: here, close: null, at: "open"}; 159 | 160 | if (start[1]) { // closing tag 161 | return {open: findMatchingOpen(iter, start[2]), close: here, at: "close"}; 162 | } else { // opening tag 163 | iter = new Iter(cm, to.line, to.ch, range); 164 | return {open: here, close: findMatchingClose(iter, start[2]), at: "open"}; 165 | } 166 | }; 167 | 168 | CodeMirror.findEnclosingTag = function(cm, pos, range, tag) { 169 | var iter = new Iter(cm, pos.line, pos.ch, range); 170 | for (;;) { 171 | var open = findMatchingOpen(iter, tag); 172 | if (!open) break; 173 | var forward = new Iter(cm, pos.line, pos.ch, range); 174 | var close = findMatchingClose(forward, open.tag); 175 | if (close) return {open: open, close: close}; 176 | } 177 | }; 178 | 179 | // Used by addon/edit/closetag.js 180 | CodeMirror.scanForClosingTag = function(cm, pos, name, end) { 181 | var iter = new Iter(cm, pos.line, pos.ch, end ? {from: 0, to: end} : null); 182 | return findMatchingClose(iter, name); 183 | }; 184 | }); 185 | -------------------------------------------------------------------------------- /codemirror/addon/hint/anyword-hint.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: https://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | var WORD = /[\w$]+/, RANGE = 500; 15 | 16 | CodeMirror.registerHelper("hint", "anyword", function(editor, options) { 17 | var word = options && options.word || WORD; 18 | var range = options && options.range || RANGE; 19 | var cur = editor.getCursor(), curLine = editor.getLine(cur.line); 20 | var end = cur.ch, start = end; 21 | while (start && word.test(curLine.charAt(start - 1))) --start; 22 | var curWord = start != end && curLine.slice(start, end); 23 | 24 | var list = options && options.list || [], seen = {}; 25 | var re = new RegExp(word.source, "g"); 26 | for (var dir = -1; dir <= 1; dir += 2) { 27 | var line = cur.line, endLine = Math.min(Math.max(line + dir * range, editor.firstLine()), editor.lastLine()) + dir; 28 | for (; line != endLine; line += dir) { 29 | var text = editor.getLine(line), m; 30 | while (m = re.exec(text)) { 31 | if (line == cur.line && m[0] === curWord) continue; 32 | if ((!curWord || m[0].lastIndexOf(curWord, 0) == 0) && !Object.prototype.hasOwnProperty.call(seen, m[0])) { 33 | seen[m[0]] = true; 34 | list.push(m[0]); 35 | } 36 | } 37 | } 38 | } 39 | return {list: list, from: CodeMirror.Pos(cur.line, start), to: CodeMirror.Pos(cur.line, end)}; 40 | }); 41 | }); 42 | -------------------------------------------------------------------------------- /codemirror/addon/hint/css-hint.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: https://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror"), require("../../mode/css/css")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror", "../../mode/css/css"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | var pseudoClasses = {link: 1, visited: 1, active: 1, hover: 1, focus: 1, 15 | "first-letter": 1, "first-line": 1, "first-child": 1, 16 | before: 1, after: 1, lang: 1}; 17 | 18 | CodeMirror.registerHelper("hint", "css", function(cm) { 19 | var cur = cm.getCursor(), token = cm.getTokenAt(cur); 20 | var inner = CodeMirror.innerMode(cm.getMode(), token.state); 21 | if (inner.mode.name != "css") return; 22 | 23 | if (token.type == "keyword" && "!important".indexOf(token.string) == 0) 24 | return {list: ["!important"], from: CodeMirror.Pos(cur.line, token.start), 25 | to: CodeMirror.Pos(cur.line, token.end)}; 26 | 27 | var start = token.start, end = cur.ch, word = token.string.slice(0, end - start); 28 | if (/[^\w$_-]/.test(word)) { 29 | word = ""; start = end = cur.ch; 30 | } 31 | 32 | var spec = CodeMirror.resolveMode("text/css"); 33 | 34 | var result = []; 35 | function add(keywords) { 36 | for (var name in keywords) 37 | if (!word || name.lastIndexOf(word, 0) == 0) 38 | result.push(name); 39 | } 40 | 41 | var st = inner.state.state; 42 | if (st == "pseudo" || token.type == "variable-3") { 43 | add(pseudoClasses); 44 | } else if (st == "block" || st == "maybeprop") { 45 | add(spec.propertyKeywords); 46 | } else if (st == "prop" || st == "parens" || st == "at" || st == "params") { 47 | add(spec.valueKeywords); 48 | add(spec.colorKeywords); 49 | } else if (st == "media" || st == "media_parens") { 50 | add(spec.mediaTypes); 51 | add(spec.mediaFeatures); 52 | } 53 | 54 | if (result.length) return { 55 | list: result, 56 | from: CodeMirror.Pos(cur.line, start), 57 | to: CodeMirror.Pos(cur.line, end) 58 | }; 59 | }); 60 | }); 61 | -------------------------------------------------------------------------------- /codemirror/addon/hint/javascript-hint.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: https://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | var Pos = CodeMirror.Pos; 13 | 14 | function forEach(arr, f) { 15 | for (var i = 0, e = arr.length; i < e; ++i) f(arr[i]); 16 | } 17 | 18 | function arrayContains(arr, item) { 19 | if (!Array.prototype.indexOf) { 20 | var i = arr.length; 21 | while (i--) { 22 | if (arr[i] === item) { 23 | return true; 24 | } 25 | } 26 | return false; 27 | } 28 | return arr.indexOf(item) != -1; 29 | } 30 | 31 | function scriptHint(editor, keywords, getToken, options) { 32 | // Find the token at the cursor 33 | var cur = editor.getCursor(), token = getToken(editor, cur); 34 | if (/\b(?:string|comment)\b/.test(token.type)) return; 35 | var innerMode = CodeMirror.innerMode(editor.getMode(), token.state); 36 | if (innerMode.mode.helperType === "json") return; 37 | token.state = innerMode.state; 38 | 39 | // If it's not a 'word-style' token, ignore the token. 40 | if (!/^[\w$_]*$/.test(token.string)) { 41 | token = {start: cur.ch, end: cur.ch, string: "", state: token.state, 42 | type: token.string == "." ? "property" : null}; 43 | } else if (token.end > cur.ch) { 44 | token.end = cur.ch; 45 | token.string = token.string.slice(0, cur.ch - token.start); 46 | } 47 | 48 | var tprop = token; 49 | // If it is a property, find out what it is a property of. 50 | while (tprop.type == "property") { 51 | tprop = getToken(editor, Pos(cur.line, tprop.start)); 52 | if (tprop.string != ".") return; 53 | tprop = getToken(editor, Pos(cur.line, tprop.start)); 54 | if (!context) var context = []; 55 | context.push(tprop); 56 | } 57 | return {list: getCompletions(token, context, keywords, options), 58 | from: Pos(cur.line, token.start), 59 | to: Pos(cur.line, token.end)}; 60 | } 61 | 62 | function javascriptHint(editor, options) { 63 | return scriptHint(editor, javascriptKeywords, 64 | function (e, cur) {return e.getTokenAt(cur);}, 65 | options); 66 | }; 67 | CodeMirror.registerHelper("hint", "javascript", javascriptHint); 68 | 69 | function getCoffeeScriptToken(editor, cur) { 70 | // This getToken, it is for coffeescript, imitates the behavior of 71 | // getTokenAt method in javascript.js, that is, returning "property" 72 | // type and treat "." as indepenent token. 73 | var token = editor.getTokenAt(cur); 74 | if (cur.ch == token.start + 1 && token.string.charAt(0) == '.') { 75 | token.end = token.start; 76 | token.string = '.'; 77 | token.type = "property"; 78 | } 79 | else if (/^\.[\w$_]*$/.test(token.string)) { 80 | token.type = "property"; 81 | token.start++; 82 | token.string = token.string.replace(/\./, ''); 83 | } 84 | return token; 85 | } 86 | 87 | function coffeescriptHint(editor, options) { 88 | return scriptHint(editor, coffeescriptKeywords, getCoffeeScriptToken, options); 89 | } 90 | CodeMirror.registerHelper("hint", "coffeescript", coffeescriptHint); 91 | 92 | var stringProps = ("charAt charCodeAt indexOf lastIndexOf substring substr slice trim trimLeft trimRight " + 93 | "toUpperCase toLowerCase split concat match replace search").split(" "); 94 | var arrayProps = ("length concat join splice push pop shift unshift slice reverse sort indexOf " + 95 | "lastIndexOf every some filter forEach map reduce reduceRight ").split(" "); 96 | var funcProps = "prototype apply call bind".split(" "); 97 | var javascriptKeywords = ("break case catch class const continue debugger default delete do else export extends false finally for function " + 98 | "if in import instanceof new null return super switch this throw true try typeof var void while with yield").split(" "); 99 | var coffeescriptKeywords = ("and break catch class continue delete do else extends false finally for " + 100 | "if in instanceof isnt new no not null of off on or return switch then throw true try typeof until void while with yes").split(" "); 101 | 102 | function forAllProps(obj, callback) { 103 | if (!Object.getOwnPropertyNames || !Object.getPrototypeOf) { 104 | for (var name in obj) callback(name) 105 | } else { 106 | for (var o = obj; o; o = Object.getPrototypeOf(o)) 107 | Object.getOwnPropertyNames(o).forEach(callback) 108 | } 109 | } 110 | 111 | function getCompletions(token, context, keywords, options) { 112 | var found = [], start = token.string, global = options && options.globalScope || window; 113 | function maybeAdd(str) { 114 | if (str.lastIndexOf(start, 0) == 0 && !arrayContains(found, str)) found.push(str); 115 | } 116 | function gatherCompletions(obj) { 117 | if (typeof obj == "string") forEach(stringProps, maybeAdd); 118 | else if (obj instanceof Array) forEach(arrayProps, maybeAdd); 119 | else if (obj instanceof Function) forEach(funcProps, maybeAdd); 120 | forAllProps(obj, maybeAdd) 121 | } 122 | 123 | if (context && context.length) { 124 | // If this is a property, see if it belongs to some object we can 125 | // find in the current environment. 126 | var obj = context.pop(), base; 127 | if (obj.type && obj.type.indexOf("variable") === 0) { 128 | if (options && options.additionalContext) 129 | base = options.additionalContext[obj.string]; 130 | if (!options || options.useGlobalScope !== false) 131 | base = base || global[obj.string]; 132 | } else if (obj.type == "string") { 133 | base = ""; 134 | } else if (obj.type == "atom") { 135 | base = 1; 136 | } else if (obj.type == "function") { 137 | if (global.jQuery != null && (obj.string == '$' || obj.string == 'jQuery') && 138 | (typeof global.jQuery == 'function')) 139 | base = global.jQuery(); 140 | else if (global._ != null && (obj.string == '_') && (typeof global._ == 'function')) 141 | base = global._(); 142 | } 143 | while (base != null && context.length) 144 | base = base[context.pop().string]; 145 | if (base != null) gatherCompletions(base); 146 | } else { 147 | // If not, just look in the global object and any local scope 148 | // (reading into JS mode internals to get at the local and global variables) 149 | for (var v = token.state.localVars; v; v = v.next) maybeAdd(v.name); 150 | for (var v = token.state.globalVars; v; v = v.next) maybeAdd(v.name); 151 | if (!options || options.useGlobalScope !== false) 152 | gatherCompletions(global); 153 | forEach(keywords, maybeAdd); 154 | } 155 | return found; 156 | } 157 | }); 158 | -------------------------------------------------------------------------------- /codemirror/addon/hint/show-hint.css: -------------------------------------------------------------------------------- 1 | .CodeMirror-hints { 2 | position: absolute; 3 | z-index: 10; 4 | overflow: hidden; 5 | list-style: none; 6 | 7 | margin: 0; 8 | padding: 2px; 9 | 10 | -webkit-box-shadow: 2px 3px 5px rgba(0,0,0,.2); 11 | -moz-box-shadow: 2px 3px 5px rgba(0,0,0,.2); 12 | box-shadow: 2px 3px 5px rgba(0,0,0,.2); 13 | border-radius: 3px; 14 | border: 1px solid silver; 15 | 16 | background: white; 17 | font-size: 90%; 18 | font-family: monospace; 19 | 20 | max-height: 20em; 21 | overflow-y: auto; 22 | } 23 | 24 | .CodeMirror-hint { 25 | margin: 0; 26 | padding: 0 4px; 27 | border-radius: 2px; 28 | white-space: pre; 29 | color: black; 30 | cursor: pointer; 31 | } 32 | 33 | li.CodeMirror-hint-active { 34 | background: #08f; 35 | color: white; 36 | } 37 | -------------------------------------------------------------------------------- /codemirror/addon/hint/xml-hint.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: https://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | var Pos = CodeMirror.Pos; 15 | 16 | function getHints(cm, options) { 17 | var tags = options && options.schemaInfo; 18 | var quote = (options && options.quoteChar) || '"'; 19 | if (!tags) return; 20 | var cur = cm.getCursor(), token = cm.getTokenAt(cur); 21 | if (token.end > cur.ch) { 22 | token.end = cur.ch; 23 | token.string = token.string.slice(0, cur.ch - token.start); 24 | } 25 | var inner = CodeMirror.innerMode(cm.getMode(), token.state); 26 | if (inner.mode.name != "xml") return; 27 | var result = [], replaceToken = false, prefix; 28 | var tag = /\btag\b/.test(token.type) && !/>$/.test(token.string); 29 | var tagName = tag && /^\w/.test(token.string), tagStart; 30 | 31 | if (tagName) { 32 | var before = cm.getLine(cur.line).slice(Math.max(0, token.start - 2), token.start); 33 | var tagType = /<\/$/.test(before) ? "close" : /<$/.test(before) ? "open" : null; 34 | if (tagType) tagStart = token.start - (tagType == "close" ? 2 : 1); 35 | } else if (tag && token.string == "<") { 36 | tagType = "open"; 37 | } else if (tag && token.string == ""); 57 | } else { 58 | // Attribute completion 59 | var curTag = tags[inner.state.tagName], attrs = curTag && curTag.attrs; 60 | var globalAttrs = tags["!attrs"]; 61 | if (!attrs && !globalAttrs) return; 62 | if (!attrs) { 63 | attrs = globalAttrs; 64 | } else if (globalAttrs) { // Combine tag-local and global attributes 65 | var set = {}; 66 | for (var nm in globalAttrs) if (globalAttrs.hasOwnProperty(nm)) set[nm] = globalAttrs[nm]; 67 | for (var nm in attrs) if (attrs.hasOwnProperty(nm)) set[nm] = attrs[nm]; 68 | attrs = set; 69 | } 70 | if (token.type == "string" || token.string == "=") { // A value 71 | var before = cm.getRange(Pos(cur.line, Math.max(0, cur.ch - 60)), 72 | Pos(cur.line, token.type == "string" ? token.start : token.end)); 73 | var atName = before.match(/([^\s\u00a0=<>\"\']+)=$/), atValues; 74 | if (!atName || !attrs.hasOwnProperty(atName[1]) || !(atValues = attrs[atName[1]])) return; 75 | if (typeof atValues == 'function') atValues = atValues.call(this, cm); // Functions can be used to supply values for autocomplete widget 76 | if (token.type == "string") { 77 | prefix = token.string; 78 | var n = 0; 79 | if (/['"]/.test(token.string.charAt(0))) { 80 | quote = token.string.charAt(0); 81 | prefix = token.string.slice(1); 82 | n++; 83 | } 84 | var len = token.string.length; 85 | if (/['"]/.test(token.string.charAt(len - 1))) { 86 | quote = token.string.charAt(len - 1); 87 | prefix = token.string.substr(n, len - 2); 88 | } 89 | replaceToken = true; 90 | } 91 | for (var i = 0; i < atValues.length; ++i) if (!prefix || atValues[i].lastIndexOf(prefix, 0) == 0) 92 | result.push(quote + atValues[i] + quote); 93 | } else { // An attribute name 94 | if (token.type == "attribute") { 95 | prefix = token.string; 96 | replaceToken = true; 97 | } 98 | for (var attr in attrs) if (attrs.hasOwnProperty(attr) && (!prefix || attr.lastIndexOf(prefix, 0) == 0)) 99 | result.push(attr); 100 | } 101 | } 102 | return { 103 | list: result, 104 | from: replaceToken ? Pos(cur.line, tagStart == null ? token.start : tagStart) : cur, 105 | to: replaceToken ? Pos(cur.line, token.end) : cur 106 | }; 107 | } 108 | 109 | CodeMirror.registerHelper("hint", "xml", getHints); 110 | }); 111 | -------------------------------------------------------------------------------- /codemirror/addon/lint/coffeescript-lint.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: https://codemirror.net/LICENSE 3 | 4 | // Depends on coffeelint.js from http://www.coffeelint.org/js/coffeelint.js 5 | 6 | // declare global: coffeelint 7 | 8 | (function(mod) { 9 | if (typeof exports == "object" && typeof module == "object") // CommonJS 10 | mod(require("../../lib/codemirror")); 11 | else if (typeof define == "function" && define.amd) // AMD 12 | define(["../../lib/codemirror"], mod); 13 | else // Plain browser env 14 | mod(CodeMirror); 15 | })(function(CodeMirror) { 16 | "use strict"; 17 | 18 | CodeMirror.registerHelper("lint", "coffeescript", function(text) { 19 | var found = []; 20 | if (!window.coffeelint) { 21 | if (window.console) { 22 | window.console.error("Error: window.coffeelint not defined, CodeMirror CoffeeScript linting cannot run."); 23 | } 24 | return found; 25 | } 26 | var parseError = function(err) { 27 | var loc = err.lineNumber; 28 | found.push({from: CodeMirror.Pos(loc-1, 0), 29 | to: CodeMirror.Pos(loc, 0), 30 | severity: err.level, 31 | message: err.message}); 32 | }; 33 | try { 34 | var res = coffeelint.lint(text); 35 | for(var i = 0; i < res.length; i++) { 36 | parseError(res[i]); 37 | } 38 | } catch(e) { 39 | found.push({from: CodeMirror.Pos(e.location.first_line, 0), 40 | to: CodeMirror.Pos(e.location.last_line, e.location.last_column), 41 | severity: 'error', 42 | message: e.message}); 43 | } 44 | return found; 45 | }); 46 | 47 | }); 48 | -------------------------------------------------------------------------------- /codemirror/addon/lint/css-lint.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: https://codemirror.net/LICENSE 3 | 4 | // Depends on csslint.js from https://github.com/stubbornella/csslint 5 | 6 | // declare global: CSSLint 7 | 8 | (function(mod) { 9 | if (typeof exports == "object" && typeof module == "object") // CommonJS 10 | mod(require("../../lib/codemirror")); 11 | else if (typeof define == "function" && define.amd) // AMD 12 | define(["../../lib/codemirror"], mod); 13 | else // Plain browser env 14 | mod(CodeMirror); 15 | })(function(CodeMirror) { 16 | "use strict"; 17 | 18 | CodeMirror.registerHelper("lint", "css", function(text, options) { 19 | var found = []; 20 | if (!window.CSSLint) { 21 | if (window.console) { 22 | window.console.error("Error: window.CSSLint not defined, CodeMirror CSS linting cannot run."); 23 | } 24 | return found; 25 | } 26 | var results = CSSLint.verify(text, options), messages = results.messages, message = null; 27 | for ( var i = 0; i < messages.length; i++) { 28 | message = messages[i]; 29 | var startLine = message.line -1, endLine = message.line -1, startCol = message.col -1, endCol = message.col; 30 | found.push({ 31 | from: CodeMirror.Pos(startLine, startCol), 32 | to: CodeMirror.Pos(endLine, endCol), 33 | message: message.message, 34 | severity : message.type 35 | }); 36 | } 37 | return found; 38 | }); 39 | 40 | }); 41 | -------------------------------------------------------------------------------- /codemirror/addon/lint/html-lint.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: https://codemirror.net/LICENSE 3 | 4 | // Depends on htmlhint.js from http://htmlhint.com/js/htmlhint.js 5 | 6 | // declare global: HTMLHint 7 | 8 | (function(mod) { 9 | if (typeof exports == "object" && typeof module == "object") // CommonJS 10 | mod(require("../../lib/codemirror"), require("htmlhint")); 11 | else if (typeof define == "function" && define.amd) // AMD 12 | define(["../../lib/codemirror", "htmlhint"], mod); 13 | else // Plain browser env 14 | mod(CodeMirror, window.HTMLHint); 15 | })(function(CodeMirror, HTMLHint) { 16 | "use strict"; 17 | 18 | var defaultRules = { 19 | "tagname-lowercase": true, 20 | "attr-lowercase": true, 21 | "attr-value-double-quotes": true, 22 | "doctype-first": false, 23 | "tag-pair": true, 24 | "spec-char-escape": true, 25 | "id-unique": true, 26 | "src-not-empty": true, 27 | "attr-no-duplication": true 28 | }; 29 | 30 | CodeMirror.registerHelper("lint", "html", function(text, options) { 31 | var found = []; 32 | if (HTMLHint && !HTMLHint.verify) HTMLHint = HTMLHint.HTMLHint; 33 | if (!HTMLHint) HTMLHint = window.HTMLHint; 34 | if (!HTMLHint) { 35 | if (window.console) { 36 | window.console.error("Error: HTMLHint not found, not defined on window, or not available through define/require, CodeMirror HTML linting cannot run."); 37 | } 38 | return found; 39 | } 40 | var messages = HTMLHint.verify(text, options && options.rules || defaultRules); 41 | for (var i = 0; i < messages.length; i++) { 42 | var message = messages[i]; 43 | var startLine = message.line - 1, endLine = message.line - 1, startCol = message.col - 1, endCol = message.col; 44 | found.push({ 45 | from: CodeMirror.Pos(startLine, startCol), 46 | to: CodeMirror.Pos(endLine, endCol), 47 | message: message.message, 48 | severity : message.type 49 | }); 50 | } 51 | return found; 52 | }); 53 | }); 54 | -------------------------------------------------------------------------------- /codemirror/addon/lint/javascript-lint.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: https://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | // declare global: JSHINT 14 | 15 | function validator(text, options) { 16 | if (!window.JSHINT) { 17 | if (window.console) { 18 | window.console.error("Error: window.JSHINT not defined, CodeMirror JavaScript linting cannot run."); 19 | } 20 | return []; 21 | } 22 | if (!options.indent) // JSHint error.character actually is a column index, this fixes underlining on lines using tabs for indentation 23 | options.indent = 1; // JSHint default value is 4 24 | JSHINT(text, options, options.globals); 25 | var errors = JSHINT.data().errors, result = []; 26 | if (errors) parseErrors(errors, result); 27 | return result; 28 | } 29 | 30 | CodeMirror.registerHelper("lint", "javascript", validator); 31 | 32 | function parseErrors(errors, output) { 33 | for ( var i = 0; i < errors.length; i++) { 34 | var error = errors[i]; 35 | if (error) { 36 | if (error.line <= 0) { 37 | if (window.console) { 38 | window.console.warn("Cannot display JSHint error (invalid line " + error.line + ")", error); 39 | } 40 | continue; 41 | } 42 | 43 | var start = error.character - 1, end = start + 1; 44 | if (error.evidence) { 45 | var index = error.evidence.substring(start).search(/.\b/); 46 | if (index > -1) { 47 | end += index; 48 | } 49 | } 50 | 51 | // Convert to format expected by validation service 52 | var hint = { 53 | message: error.reason, 54 | severity: error.code ? (error.code.startsWith('W') ? "warning" : "error") : "error", 55 | from: CodeMirror.Pos(error.line - 1, start), 56 | to: CodeMirror.Pos(error.line - 1, end) 57 | }; 58 | 59 | output.push(hint); 60 | } 61 | } 62 | } 63 | }); 64 | -------------------------------------------------------------------------------- /codemirror/addon/lint/json-lint.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: https://codemirror.net/LICENSE 3 | 4 | // Depends on jsonlint.js from https://github.com/zaach/jsonlint 5 | 6 | // declare global: jsonlint 7 | 8 | (function(mod) { 9 | if (typeof exports == "object" && typeof module == "object") // CommonJS 10 | mod(require("../../lib/codemirror")); 11 | else if (typeof define == "function" && define.amd) // AMD 12 | define(["../../lib/codemirror"], mod); 13 | else // Plain browser env 14 | mod(CodeMirror); 15 | })(function(CodeMirror) { 16 | "use strict"; 17 | 18 | CodeMirror.registerHelper("lint", "json", function(text) { 19 | var found = []; 20 | if (!window.jsonlint) { 21 | if (window.console) { 22 | window.console.error("Error: window.jsonlint not defined, CodeMirror JSON linting cannot run."); 23 | } 24 | return found; 25 | } 26 | // for jsonlint's web dist jsonlint is exported as an object with a single property parser, of which parseError 27 | // is a subproperty 28 | var jsonlint = window.jsonlint.parser || window.jsonlint 29 | jsonlint.parseError = function(str, hash) { 30 | var loc = hash.loc; 31 | found.push({from: CodeMirror.Pos(loc.first_line - 1, loc.first_column), 32 | to: CodeMirror.Pos(loc.last_line - 1, loc.last_column), 33 | message: str}); 34 | }; 35 | try { jsonlint.parse(text); } 36 | catch(e) {} 37 | return found; 38 | }); 39 | 40 | }); 41 | -------------------------------------------------------------------------------- /codemirror/addon/lint/lint.css: -------------------------------------------------------------------------------- 1 | /* The lint marker gutter */ 2 | .CodeMirror-lint-markers { 3 | width: 16px; 4 | } 5 | 6 | .CodeMirror-lint-tooltip { 7 | background-color: #ffd; 8 | border: 1px solid black; 9 | border-radius: 4px 4px 4px 4px; 10 | color: black; 11 | font-family: monospace; 12 | font-size: 10pt; 13 | overflow: hidden; 14 | padding: 2px 5px; 15 | position: fixed; 16 | white-space: pre; 17 | white-space: pre-wrap; 18 | z-index: 100; 19 | max-width: 600px; 20 | opacity: 0; 21 | transition: opacity .4s; 22 | -moz-transition: opacity .4s; 23 | -webkit-transition: opacity .4s; 24 | -o-transition: opacity .4s; 25 | -ms-transition: opacity .4s; 26 | } 27 | 28 | .CodeMirror-lint-mark-error, .CodeMirror-lint-mark-warning { 29 | background-position: left bottom; 30 | background-repeat: repeat-x; 31 | } 32 | 33 | .CodeMirror-lint-mark-error { 34 | background-image: 35 | url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAYAAAC09K7GAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sJDw4cOCW1/KIAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAHElEQVQI12NggIL/DAz/GdA5/xkY/qPKMDAwAADLZwf5rvm+LQAAAABJRU5ErkJggg==") 36 | ; 37 | } 38 | 39 | .CodeMirror-lint-mark-warning { 40 | background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAYAAAC09K7GAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sJFhQXEbhTg7YAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAMklEQVQI12NkgIIvJ3QXMjAwdDN+OaEbysDA4MPAwNDNwMCwiOHLCd1zX07o6kBVGQEAKBANtobskNMAAAAASUVORK5CYII="); 41 | } 42 | 43 | .CodeMirror-lint-marker-error, .CodeMirror-lint-marker-warning { 44 | background-position: center center; 45 | background-repeat: no-repeat; 46 | cursor: pointer; 47 | display: inline-block; 48 | height: 16px; 49 | width: 16px; 50 | vertical-align: middle; 51 | position: relative; 52 | } 53 | 54 | .CodeMirror-lint-message-error, .CodeMirror-lint-message-warning { 55 | padding-left: 18px; 56 | background-position: top left; 57 | background-repeat: no-repeat; 58 | } 59 | 60 | .CodeMirror-lint-marker-error, .CodeMirror-lint-message-error { 61 | background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAHlBMVEW7AAC7AACxAAC7AAC7AAAAAAC4AAC5AAD///+7AAAUdclpAAAABnRSTlMXnORSiwCK0ZKSAAAATUlEQVR42mWPOQ7AQAgDuQLx/z8csYRmPRIFIwRGnosRrpamvkKi0FTIiMASR3hhKW+hAN6/tIWhu9PDWiTGNEkTtIOucA5Oyr9ckPgAWm0GPBog6v4AAAAASUVORK5CYII="); 62 | } 63 | 64 | .CodeMirror-lint-marker-warning, .CodeMirror-lint-message-warning { 65 | background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAANlBMVEX/uwDvrwD/uwD/uwD/uwD/uwD/uwD/uwD/uwD6twD/uwAAAADurwD2tQD7uAD+ugAAAAD/uwDhmeTRAAAADHRSTlMJ8mN1EYcbmiixgACm7WbuAAAAVklEQVR42n3PUQqAIBBFUU1LLc3u/jdbOJoW1P08DA9Gba8+YWJ6gNJoNYIBzAA2chBth5kLmG9YUoG0NHAUwFXwO9LuBQL1giCQb8gC9Oro2vp5rncCIY8L8uEx5ZkAAAAASUVORK5CYII="); 66 | } 67 | 68 | .CodeMirror-lint-marker-multiple { 69 | background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAMAAADzjKfhAAAACVBMVEUAAAAAAAC/v7914kyHAAAAAXRSTlMAQObYZgAAACNJREFUeNo1ioEJAAAIwmz/H90iFFSGJgFMe3gaLZ0od+9/AQZ0ADosbYraAAAAAElFTkSuQmCC"); 70 | background-repeat: no-repeat; 71 | background-position: right bottom; 72 | width: 100%; height: 100%; 73 | } 74 | -------------------------------------------------------------------------------- /codemirror/addon/lint/yaml-lint.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: https://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | // Depends on js-yaml.js from https://github.com/nodeca/js-yaml 15 | 16 | // declare global: jsyaml 17 | 18 | CodeMirror.registerHelper("lint", "yaml", function(text) { 19 | var found = []; 20 | if (!window.jsyaml) { 21 | if (window.console) { 22 | window.console.error("Error: window.jsyaml not defined, CodeMirror YAML linting cannot run."); 23 | } 24 | return found; 25 | } 26 | try { jsyaml.loadAll(text); } 27 | catch(e) { 28 | var loc = e.mark, 29 | // js-yaml YAMLException doesn't always provide an accurate lineno 30 | // e.g., when there are multiple yaml docs 31 | // --- 32 | // --- 33 | // foo:bar 34 | from = loc ? CodeMirror.Pos(loc.line, loc.column) : CodeMirror.Pos(0, 0), 35 | to = from; 36 | found.push({ from: from, to: to, message: e.message }); 37 | } 38 | return found; 39 | }); 40 | 41 | }); 42 | -------------------------------------------------------------------------------- /codemirror/addon/merge/merge.css: -------------------------------------------------------------------------------- 1 | .CodeMirror-merge { 2 | position: relative; 3 | border: 1px solid #ddd; 4 | white-space: pre; 5 | } 6 | 7 | .CodeMirror-merge, .CodeMirror-merge .CodeMirror { 8 | height: 350px; 9 | } 10 | 11 | .CodeMirror-merge-2pane .CodeMirror-merge-pane { width: 47%; } 12 | .CodeMirror-merge-2pane .CodeMirror-merge-gap { width: 6%; } 13 | .CodeMirror-merge-3pane .CodeMirror-merge-pane { width: 31%; } 14 | .CodeMirror-merge-3pane .CodeMirror-merge-gap { width: 3.5%; } 15 | 16 | .CodeMirror-merge-pane { 17 | display: inline-block; 18 | white-space: normal; 19 | vertical-align: top; 20 | } 21 | .CodeMirror-merge-pane-rightmost { 22 | position: absolute; 23 | right: 0px; 24 | z-index: 1; 25 | } 26 | 27 | .CodeMirror-merge-gap { 28 | z-index: 2; 29 | display: inline-block; 30 | height: 100%; 31 | -moz-box-sizing: border-box; 32 | box-sizing: border-box; 33 | overflow: hidden; 34 | border-left: 1px solid #ddd; 35 | border-right: 1px solid #ddd; 36 | position: relative; 37 | background: #f8f8f8; 38 | } 39 | 40 | .CodeMirror-merge-scrolllock-wrap { 41 | position: absolute; 42 | bottom: 0; left: 50%; 43 | } 44 | .CodeMirror-merge-scrolllock { 45 | position: relative; 46 | left: -50%; 47 | cursor: pointer; 48 | color: #555; 49 | line-height: 1; 50 | } 51 | .CodeMirror-merge-scrolllock:after { 52 | content: "\21db\00a0\00a0\21da"; 53 | } 54 | .CodeMirror-merge-scrolllock.CodeMirror-merge-scrolllock-enabled:after { 55 | content: "\21db\21da"; 56 | } 57 | 58 | .CodeMirror-merge-copybuttons-left, .CodeMirror-merge-copybuttons-right { 59 | position: absolute; 60 | left: 0; top: 0; 61 | right: 0; bottom: 0; 62 | line-height: 1; 63 | } 64 | 65 | .CodeMirror-merge-copy { 66 | position: absolute; 67 | cursor: pointer; 68 | color: #44c; 69 | z-index: 3; 70 | } 71 | 72 | .CodeMirror-merge-copy-reverse { 73 | position: absolute; 74 | cursor: pointer; 75 | color: #44c; 76 | } 77 | 78 | .CodeMirror-merge-copybuttons-left .CodeMirror-merge-copy { left: 2px; } 79 | .CodeMirror-merge-copybuttons-right .CodeMirror-merge-copy { right: 2px; } 80 | 81 | .CodeMirror-merge-r-inserted, .CodeMirror-merge-l-inserted { 82 | background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAACCAYAAACddGYaAAAAGUlEQVQI12MwuCXy3+CWyH8GBgYGJgYkAABZbAQ9ELXurwAAAABJRU5ErkJggg==); 83 | background-position: bottom left; 84 | background-repeat: repeat-x; 85 | } 86 | 87 | .CodeMirror-merge-r-deleted, .CodeMirror-merge-l-deleted { 88 | background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAACCAYAAACddGYaAAAAGUlEQVQI12M4Kyb2/6yY2H8GBgYGJgYkAABURgPz6Ks7wQAAAABJRU5ErkJggg==); 89 | background-position: bottom left; 90 | background-repeat: repeat-x; 91 | } 92 | 93 | .CodeMirror-merge-r-chunk { background: #ffffe0; } 94 | .CodeMirror-merge-r-chunk-start { border-top: 1px solid #ee8; } 95 | .CodeMirror-merge-r-chunk-end { border-bottom: 1px solid #ee8; } 96 | .CodeMirror-merge-r-connect { fill: #ffffe0; stroke: #ee8; stroke-width: 1px; } 97 | 98 | .CodeMirror-merge-l-chunk { background: #eef; } 99 | .CodeMirror-merge-l-chunk-start { border-top: 1px solid #88e; } 100 | .CodeMirror-merge-l-chunk-end { border-bottom: 1px solid #88e; } 101 | .CodeMirror-merge-l-connect { fill: #eef; stroke: #88e; stroke-width: 1px; } 102 | 103 | .CodeMirror-merge-l-chunk.CodeMirror-merge-r-chunk { background: #dfd; } 104 | .CodeMirror-merge-l-chunk-start.CodeMirror-merge-r-chunk-start { border-top: 1px solid #4e4; } 105 | .CodeMirror-merge-l-chunk-end.CodeMirror-merge-r-chunk-end { border-bottom: 1px solid #4e4; } 106 | 107 | .CodeMirror-merge-collapsed-widget:before { 108 | content: "(...)"; 109 | } 110 | .CodeMirror-merge-collapsed-widget { 111 | cursor: pointer; 112 | color: #88b; 113 | background: #eef; 114 | border: 1px solid #ddf; 115 | font-size: 90%; 116 | padding: 0 3px; 117 | border-radius: 4px; 118 | } 119 | .CodeMirror-merge-collapsed-line .CodeMirror-gutter-elt { display: none; } 120 | -------------------------------------------------------------------------------- /codemirror/addon/mode/loadmode.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: https://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror"), "cjs"); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], function(CM) { mod(CM, "amd"); }); 9 | else // Plain browser env 10 | mod(CodeMirror, "plain"); 11 | })(function(CodeMirror, env) { 12 | if (!CodeMirror.modeURL) CodeMirror.modeURL = "../mode/%N/%N.js"; 13 | 14 | var loading = {}; 15 | function splitCallback(cont, n) { 16 | var countDown = n; 17 | return function() { if (--countDown == 0) cont(); }; 18 | } 19 | function ensureDeps(mode, cont) { 20 | var deps = CodeMirror.modes[mode].dependencies; 21 | if (!deps) return cont(); 22 | var missing = []; 23 | for (var i = 0; i < deps.length; ++i) { 24 | if (!CodeMirror.modes.hasOwnProperty(deps[i])) 25 | missing.push(deps[i]); 26 | } 27 | if (!missing.length) return cont(); 28 | var split = splitCallback(cont, missing.length); 29 | for (var i = 0; i < missing.length; ++i) 30 | CodeMirror.requireMode(missing[i], split); 31 | } 32 | 33 | CodeMirror.requireMode = function(mode, cont) { 34 | if (typeof mode != "string") mode = mode.name; 35 | if (CodeMirror.modes.hasOwnProperty(mode)) return ensureDeps(mode, cont); 36 | if (loading.hasOwnProperty(mode)) return loading[mode].push(cont); 37 | 38 | var file = CodeMirror.modeURL.replace(/%N/g, mode); 39 | if (env == "plain") { 40 | var script = document.createElement("script"); 41 | script.src = file; 42 | var others = document.getElementsByTagName("script")[0]; 43 | var list = loading[mode] = [cont]; 44 | CodeMirror.on(script, "load", function() { 45 | ensureDeps(mode, function() { 46 | for (var i = 0; i < list.length; ++i) list[i](); 47 | }); 48 | }); 49 | others.parentNode.insertBefore(script, others); 50 | } else if (env == "cjs") { 51 | require(file); 52 | cont(); 53 | } else if (env == "amd") { 54 | requirejs([file], cont); 55 | } 56 | }; 57 | 58 | CodeMirror.autoLoadMode = function(instance, mode) { 59 | if (!CodeMirror.modes.hasOwnProperty(mode)) 60 | CodeMirror.requireMode(mode, function() { 61 | instance.setOption("mode", instance.getOption("mode")); 62 | }); 63 | }; 64 | }); 65 | -------------------------------------------------------------------------------- /codemirror/addon/mode/multiplex.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: https://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | CodeMirror.multiplexingMode = function(outer /*, others */) { 15 | // Others should be {open, close, mode [, delimStyle] [, innerStyle]} objects 16 | var others = Array.prototype.slice.call(arguments, 1); 17 | 18 | function indexOf(string, pattern, from, returnEnd) { 19 | if (typeof pattern == "string") { 20 | var found = string.indexOf(pattern, from); 21 | return returnEnd && found > -1 ? found + pattern.length : found; 22 | } 23 | var m = pattern.exec(from ? string.slice(from) : string); 24 | return m ? m.index + from + (returnEnd ? m[0].length : 0) : -1; 25 | } 26 | 27 | return { 28 | startState: function() { 29 | return { 30 | outer: CodeMirror.startState(outer), 31 | innerActive: null, 32 | inner: null 33 | }; 34 | }, 35 | 36 | copyState: function(state) { 37 | return { 38 | outer: CodeMirror.copyState(outer, state.outer), 39 | innerActive: state.innerActive, 40 | inner: state.innerActive && CodeMirror.copyState(state.innerActive.mode, state.inner) 41 | }; 42 | }, 43 | 44 | token: function(stream, state) { 45 | if (!state.innerActive) { 46 | var cutOff = Infinity, oldContent = stream.string; 47 | for (var i = 0; i < others.length; ++i) { 48 | var other = others[i]; 49 | var found = indexOf(oldContent, other.open, stream.pos); 50 | if (found == stream.pos) { 51 | if (!other.parseDelimiters) stream.match(other.open); 52 | state.innerActive = other; 53 | 54 | // Get the outer indent, making sure to handle CodeMirror.Pass 55 | var outerIndent = 0; 56 | if (outer.indent) { 57 | var possibleOuterIndent = outer.indent(state.outer, "", ""); 58 | if (possibleOuterIndent !== CodeMirror.Pass) outerIndent = possibleOuterIndent; 59 | } 60 | 61 | state.inner = CodeMirror.startState(other.mode, outerIndent); 62 | return other.delimStyle && (other.delimStyle + " " + other.delimStyle + "-open"); 63 | } else if (found != -1 && found < cutOff) { 64 | cutOff = found; 65 | } 66 | } 67 | if (cutOff != Infinity) stream.string = oldContent.slice(0, cutOff); 68 | var outerToken = outer.token(stream, state.outer); 69 | if (cutOff != Infinity) stream.string = oldContent; 70 | return outerToken; 71 | } else { 72 | var curInner = state.innerActive, oldContent = stream.string; 73 | if (!curInner.close && stream.sol()) { 74 | state.innerActive = state.inner = null; 75 | return this.token(stream, state); 76 | } 77 | var found = curInner.close ? indexOf(oldContent, curInner.close, stream.pos, curInner.parseDelimiters) : -1; 78 | if (found == stream.pos && !curInner.parseDelimiters) { 79 | stream.match(curInner.close); 80 | state.innerActive = state.inner = null; 81 | return curInner.delimStyle && (curInner.delimStyle + " " + curInner.delimStyle + "-close"); 82 | } 83 | if (found > -1) stream.string = oldContent.slice(0, found); 84 | var innerToken = curInner.mode.token(stream, state.inner); 85 | if (found > -1) stream.string = oldContent; 86 | 87 | if (found == stream.pos && curInner.parseDelimiters) 88 | state.innerActive = state.inner = null; 89 | 90 | if (curInner.innerStyle) { 91 | if (innerToken) innerToken = innerToken + " " + curInner.innerStyle; 92 | else innerToken = curInner.innerStyle; 93 | } 94 | 95 | return innerToken; 96 | } 97 | }, 98 | 99 | indent: function(state, textAfter, line) { 100 | var mode = state.innerActive ? state.innerActive.mode : outer; 101 | if (!mode.indent) return CodeMirror.Pass; 102 | return mode.indent(state.innerActive ? state.inner : state.outer, textAfter, line); 103 | }, 104 | 105 | blankLine: function(state) { 106 | var mode = state.innerActive ? state.innerActive.mode : outer; 107 | if (mode.blankLine) { 108 | mode.blankLine(state.innerActive ? state.inner : state.outer); 109 | } 110 | if (!state.innerActive) { 111 | for (var i = 0; i < others.length; ++i) { 112 | var other = others[i]; 113 | if (other.open === "\n") { 114 | state.innerActive = other; 115 | state.inner = CodeMirror.startState(other.mode, mode.indent ? mode.indent(state.outer, "", "") : 0); 116 | } 117 | } 118 | } else if (state.innerActive.close === "\n") { 119 | state.innerActive = state.inner = null; 120 | } 121 | }, 122 | 123 | electricChars: outer.electricChars, 124 | 125 | innerMode: function(state) { 126 | return state.inner ? {state: state.inner, mode: state.innerActive.mode} : {state: state.outer, mode: outer}; 127 | } 128 | }; 129 | }; 130 | 131 | }); 132 | -------------------------------------------------------------------------------- /codemirror/addon/mode/multiplex_test.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: https://codemirror.net/LICENSE 3 | 4 | (function() { 5 | CodeMirror.defineMode("markdown_with_stex", function(){ 6 | var inner = CodeMirror.getMode({}, "stex"); 7 | var outer = CodeMirror.getMode({}, "markdown"); 8 | 9 | var innerOptions = { 10 | open: '$', 11 | close: '$', 12 | mode: inner, 13 | delimStyle: 'delim', 14 | innerStyle: 'inner' 15 | }; 16 | 17 | return CodeMirror.multiplexingMode(outer, innerOptions); 18 | }); 19 | 20 | var mode = CodeMirror.getMode({}, "markdown_with_stex"); 21 | 22 | function MT(name) { 23 | test.mode( 24 | name, 25 | mode, 26 | Array.prototype.slice.call(arguments, 1), 27 | 'multiplexing'); 28 | } 29 | 30 | MT( 31 | "stexInsideMarkdown", 32 | "[strong **Equation:**] [delim&delim-open $][inner&tag \\pi][delim&delim-close $]"); 33 | })(); 34 | -------------------------------------------------------------------------------- /codemirror/addon/mode/overlay.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: https://codemirror.net/LICENSE 3 | 4 | // Utility function that allows modes to be combined. The mode given 5 | // as the base argument takes care of most of the normal mode 6 | // functionality, but a second (typically simple) mode is used, which 7 | // can override the style of text. Both modes get to parse all of the 8 | // text, but when both assign a non-null style to a piece of code, the 9 | // overlay wins, unless the combine argument was true and not overridden, 10 | // or state.overlay.combineTokens was true, in which case the styles are 11 | // combined. 12 | 13 | (function(mod) { 14 | if (typeof exports == "object" && typeof module == "object") // CommonJS 15 | mod(require("../../lib/codemirror")); 16 | else if (typeof define == "function" && define.amd) // AMD 17 | define(["../../lib/codemirror"], mod); 18 | else // Plain browser env 19 | mod(CodeMirror); 20 | })(function(CodeMirror) { 21 | "use strict"; 22 | 23 | CodeMirror.overlayMode = function(base, overlay, combine) { 24 | return { 25 | startState: function() { 26 | return { 27 | base: CodeMirror.startState(base), 28 | overlay: CodeMirror.startState(overlay), 29 | basePos: 0, baseCur: null, 30 | overlayPos: 0, overlayCur: null, 31 | streamSeen: null 32 | }; 33 | }, 34 | copyState: function(state) { 35 | return { 36 | base: CodeMirror.copyState(base, state.base), 37 | overlay: CodeMirror.copyState(overlay, state.overlay), 38 | basePos: state.basePos, baseCur: null, 39 | overlayPos: state.overlayPos, overlayCur: null 40 | }; 41 | }, 42 | 43 | token: function(stream, state) { 44 | if (stream != state.streamSeen || 45 | Math.min(state.basePos, state.overlayPos) < stream.start) { 46 | state.streamSeen = stream; 47 | state.basePos = state.overlayPos = stream.start; 48 | } 49 | 50 | if (stream.start == state.basePos) { 51 | state.baseCur = base.token(stream, state.base); 52 | state.basePos = stream.pos; 53 | } 54 | if (stream.start == state.overlayPos) { 55 | stream.pos = stream.start; 56 | state.overlayCur = overlay.token(stream, state.overlay); 57 | state.overlayPos = stream.pos; 58 | } 59 | stream.pos = Math.min(state.basePos, state.overlayPos); 60 | 61 | // state.overlay.combineTokens always takes precedence over combine, 62 | // unless set to null 63 | if (state.overlayCur == null) return state.baseCur; 64 | else if (state.baseCur != null && 65 | state.overlay.combineTokens || 66 | combine && state.overlay.combineTokens == null) 67 | return state.baseCur + " " + state.overlayCur; 68 | else return state.overlayCur; 69 | }, 70 | 71 | indent: base.indent && function(state, textAfter, line) { 72 | return base.indent(state.base, textAfter, line); 73 | }, 74 | electricChars: base.electricChars, 75 | 76 | innerMode: function(state) { return {state: state.base, mode: base}; }, 77 | 78 | blankLine: function(state) { 79 | var baseToken, overlayToken; 80 | if (base.blankLine) baseToken = base.blankLine(state.base); 81 | if (overlay.blankLine) overlayToken = overlay.blankLine(state.overlay); 82 | 83 | return overlayToken == null ? 84 | baseToken : 85 | (combine && baseToken != null ? baseToken + " " + overlayToken : overlayToken); 86 | } 87 | }; 88 | }; 89 | 90 | }); 91 | -------------------------------------------------------------------------------- /codemirror/addon/runmode/colorize.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: https://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror"), require("./runmode")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror", "./runmode"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | var isBlock = /^(p|li|div|h\\d|pre|blockquote|td)$/; 15 | 16 | function textContent(node, out) { 17 | if (node.nodeType == 3) return out.push(node.nodeValue); 18 | for (var ch = node.firstChild; ch; ch = ch.nextSibling) { 19 | textContent(ch, out); 20 | if (isBlock.test(node.nodeType)) out.push("\n"); 21 | } 22 | } 23 | 24 | CodeMirror.colorize = function(collection, defaultMode) { 25 | if (!collection) collection = document.body.getElementsByTagName("pre"); 26 | 27 | for (var i = 0; i < collection.length; ++i) { 28 | var node = collection[i]; 29 | var mode = node.getAttribute("data-lang") || defaultMode; 30 | if (!mode) continue; 31 | 32 | var text = []; 33 | textContent(node, text); 34 | node.innerHTML = ""; 35 | CodeMirror.runMode(text.join(""), mode, node); 36 | 37 | node.className += " cm-s-default"; 38 | } 39 | }; 40 | }); 41 | -------------------------------------------------------------------------------- /codemirror/addon/runmode/runmode-standalone.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: https://codemirror.net/LICENSE 3 | 4 | window.CodeMirror = {}; 5 | 6 | (function() { 7 | "use strict"; 8 | 9 | function splitLines(string){ return string.split(/\r?\n|\r/); }; 10 | 11 | function StringStream(string) { 12 | this.pos = this.start = 0; 13 | this.string = string; 14 | this.lineStart = 0; 15 | } 16 | StringStream.prototype = { 17 | eol: function() {return this.pos >= this.string.length;}, 18 | sol: function() {return this.pos == 0;}, 19 | peek: function() {return this.string.charAt(this.pos) || null;}, 20 | next: function() { 21 | if (this.pos < this.string.length) 22 | return this.string.charAt(this.pos++); 23 | }, 24 | eat: function(match) { 25 | var ch = this.string.charAt(this.pos); 26 | if (typeof match == "string") var ok = ch == match; 27 | else var ok = ch && (match.test ? match.test(ch) : match(ch)); 28 | if (ok) {++this.pos; return ch;} 29 | }, 30 | eatWhile: function(match) { 31 | var start = this.pos; 32 | while (this.eat(match)){} 33 | return this.pos > start; 34 | }, 35 | eatSpace: function() { 36 | var start = this.pos; 37 | while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos; 38 | return this.pos > start; 39 | }, 40 | skipToEnd: function() {this.pos = this.string.length;}, 41 | skipTo: function(ch) { 42 | var found = this.string.indexOf(ch, this.pos); 43 | if (found > -1) {this.pos = found; return true;} 44 | }, 45 | backUp: function(n) {this.pos -= n;}, 46 | column: function() {return this.start - this.lineStart;}, 47 | indentation: function() {return 0;}, 48 | match: function(pattern, consume, caseInsensitive) { 49 | if (typeof pattern == "string") { 50 | var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;}; 51 | var substr = this.string.substr(this.pos, pattern.length); 52 | if (cased(substr) == cased(pattern)) { 53 | if (consume !== false) this.pos += pattern.length; 54 | return true; 55 | } 56 | } else { 57 | var match = this.string.slice(this.pos).match(pattern); 58 | if (match && match.index > 0) return null; 59 | if (match && consume !== false) this.pos += match[0].length; 60 | return match; 61 | } 62 | }, 63 | current: function(){return this.string.slice(this.start, this.pos);}, 64 | hideFirstChars: function(n, inner) { 65 | this.lineStart += n; 66 | try { return inner(); } 67 | finally { this.lineStart -= n; } 68 | }, 69 | lookAhead: function() { return null } 70 | }; 71 | CodeMirror.StringStream = StringStream; 72 | 73 | CodeMirror.startState = function (mode, a1, a2) { 74 | return mode.startState ? mode.startState(a1, a2) : true; 75 | }; 76 | 77 | var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.mimeModes = {}; 78 | CodeMirror.defineMode = function (name, mode) { 79 | if (arguments.length > 2) 80 | mode.dependencies = Array.prototype.slice.call(arguments, 2); 81 | modes[name] = mode; 82 | }; 83 | CodeMirror.defineMIME = function (mime, spec) { mimeModes[mime] = spec; }; 84 | CodeMirror.resolveMode = function(spec) { 85 | if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) { 86 | spec = mimeModes[spec]; 87 | } else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) { 88 | spec = mimeModes[spec.name]; 89 | } 90 | if (typeof spec == "string") return {name: spec}; 91 | else return spec || {name: "null"}; 92 | }; 93 | CodeMirror.getMode = function (options, spec) { 94 | spec = CodeMirror.resolveMode(spec); 95 | var mfactory = modes[spec.name]; 96 | if (!mfactory) throw new Error("Unknown mode: " + spec); 97 | return mfactory(options, spec); 98 | }; 99 | CodeMirror.registerHelper = CodeMirror.registerGlobalHelper = Math.min; 100 | CodeMirror.defineMode("null", function() { 101 | return {token: function(stream) {stream.skipToEnd();}}; 102 | }); 103 | CodeMirror.defineMIME("text/plain", "null"); 104 | 105 | CodeMirror.runMode = function (string, modespec, callback, options) { 106 | var mode = CodeMirror.getMode({ indentUnit: 2 }, modespec); 107 | 108 | if (callback.nodeType == 1) { 109 | var tabSize = (options && options.tabSize) || 4; 110 | var node = callback, col = 0; 111 | node.innerHTML = ""; 112 | callback = function (text, style) { 113 | if (text == "\n") { 114 | node.appendChild(document.createElement("br")); 115 | col = 0; 116 | return; 117 | } 118 | var content = ""; 119 | // replace tabs 120 | for (var pos = 0; ;) { 121 | var idx = text.indexOf("\t", pos); 122 | if (idx == -1) { 123 | content += text.slice(pos); 124 | col += text.length - pos; 125 | break; 126 | } else { 127 | col += idx - pos; 128 | content += text.slice(pos, idx); 129 | var size = tabSize - col % tabSize; 130 | col += size; 131 | for (var i = 0; i < size; ++i) content += " "; 132 | pos = idx + 1; 133 | } 134 | } 135 | 136 | if (style) { 137 | var sp = node.appendChild(document.createElement("span")); 138 | sp.className = "cm-" + style.replace(/ +/g, " cm-"); 139 | sp.appendChild(document.createTextNode(content)); 140 | } else { 141 | node.appendChild(document.createTextNode(content)); 142 | } 143 | }; 144 | } 145 | 146 | var lines = splitLines(string), state = (options && options.state) || CodeMirror.startState(mode); 147 | for (var i = 0, e = lines.length; i < e; ++i) { 148 | if (i) callback("\n"); 149 | var stream = new CodeMirror.StringStream(lines[i]); 150 | if (!stream.string && mode.blankLine) mode.blankLine(state); 151 | while (!stream.eol()) { 152 | var style = mode.token(stream, state); 153 | callback(stream.current(), style, i, stream.start, state); 154 | stream.start = stream.pos; 155 | } 156 | } 157 | }; 158 | })(); 159 | -------------------------------------------------------------------------------- /codemirror/addon/runmode/runmode.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: https://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | CodeMirror.runMode = function(string, modespec, callback, options) { 15 | var mode = CodeMirror.getMode(CodeMirror.defaults, modespec); 16 | var ie = /MSIE \d/.test(navigator.userAgent); 17 | var ie_lt9 = ie && (document.documentMode == null || document.documentMode < 9); 18 | 19 | if (callback.appendChild) { 20 | var tabSize = (options && options.tabSize) || CodeMirror.defaults.tabSize; 21 | var node = callback, col = 0; 22 | node.innerHTML = ""; 23 | callback = function(text, style) { 24 | if (text == "\n") { 25 | // Emitting LF or CRLF on IE8 or earlier results in an incorrect display. 26 | // Emitting a carriage return makes everything ok. 27 | node.appendChild(document.createTextNode(ie_lt9 ? '\r' : text)); 28 | col = 0; 29 | return; 30 | } 31 | var content = ""; 32 | // replace tabs 33 | for (var pos = 0;;) { 34 | var idx = text.indexOf("\t", pos); 35 | if (idx == -1) { 36 | content += text.slice(pos); 37 | col += text.length - pos; 38 | break; 39 | } else { 40 | col += idx - pos; 41 | content += text.slice(pos, idx); 42 | var size = tabSize - col % tabSize; 43 | col += size; 44 | for (var i = 0; i < size; ++i) content += " "; 45 | pos = idx + 1; 46 | } 47 | } 48 | 49 | if (style) { 50 | var sp = node.appendChild(document.createElement("span")); 51 | sp.className = "cm-" + style.replace(/ +/g, " cm-"); 52 | sp.appendChild(document.createTextNode(content)); 53 | } else { 54 | node.appendChild(document.createTextNode(content)); 55 | } 56 | }; 57 | } 58 | 59 | var lines = CodeMirror.splitLines(string), state = (options && options.state) || CodeMirror.startState(mode); 60 | for (var i = 0, e = lines.length; i < e; ++i) { 61 | if (i) callback("\n"); 62 | var stream = new CodeMirror.StringStream(lines[i]); 63 | if (!stream.string && mode.blankLine) mode.blankLine(state); 64 | while (!stream.eol()) { 65 | var style = mode.token(stream, state); 66 | callback(stream.current(), style, i, stream.start, state); 67 | stream.start = stream.pos; 68 | } 69 | } 70 | }; 71 | 72 | }); 73 | -------------------------------------------------------------------------------- /codemirror/addon/runmode/runmode.node.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: https://codemirror.net/LICENSE 3 | 4 | /* Just enough of CodeMirror to run runMode under node.js */ 5 | 6 | function splitLines(string){return string.split(/\r\n?|\n/);}; 7 | 8 | // Counts the column offset in a string, taking tabs into account. 9 | // Used mostly to find indentation. 10 | var countColumn = exports.countColumn = function(string, end, tabSize, startIndex, startValue) { 11 | if (end == null) { 12 | end = string.search(/[^\s\u00a0]/); 13 | if (end == -1) end = string.length; 14 | } 15 | for (var i = startIndex || 0, n = startValue || 0;;) { 16 | var nextTab = string.indexOf("\t", i); 17 | if (nextTab < 0 || nextTab >= end) 18 | return n + (end - i); 19 | n += nextTab - i; 20 | n += tabSize - (n % tabSize); 21 | i = nextTab + 1; 22 | } 23 | }; 24 | 25 | function StringStream(string, tabSize, context) { 26 | this.pos = this.start = 0; 27 | this.string = string; 28 | this.tabSize = tabSize || 8; 29 | this.lastColumnPos = this.lastColumnValue = 0; 30 | this.lineStart = 0; 31 | this.context = context 32 | }; 33 | 34 | StringStream.prototype = { 35 | eol: function() {return this.pos >= this.string.length;}, 36 | sol: function() {return this.pos == this.lineStart;}, 37 | peek: function() {return this.string.charAt(this.pos) || undefined;}, 38 | next: function() { 39 | if (this.pos < this.string.length) 40 | return this.string.charAt(this.pos++); 41 | }, 42 | eat: function(match) { 43 | var ch = this.string.charAt(this.pos); 44 | if (typeof match == "string") var ok = ch == match; 45 | else var ok = ch && (match.test ? match.test(ch) : match(ch)); 46 | if (ok) {++this.pos; return ch;} 47 | }, 48 | eatWhile: function(match) { 49 | var start = this.pos; 50 | while (this.eat(match)){} 51 | return this.pos > start; 52 | }, 53 | eatSpace: function() { 54 | var start = this.pos; 55 | while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos; 56 | return this.pos > start; 57 | }, 58 | skipToEnd: function() {this.pos = this.string.length;}, 59 | skipTo: function(ch) { 60 | var found = this.string.indexOf(ch, this.pos); 61 | if (found > -1) {this.pos = found; return true;} 62 | }, 63 | backUp: function(n) {this.pos -= n;}, 64 | column: function() { 65 | if (this.lastColumnPos < this.start) { 66 | this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue); 67 | this.lastColumnPos = this.start; 68 | } 69 | return this.lastColumnValue - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0); 70 | }, 71 | indentation: function() { 72 | return countColumn(this.string, null, this.tabSize) - 73 | (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0); 74 | }, 75 | match: function(pattern, consume, caseInsensitive) { 76 | if (typeof pattern == "string") { 77 | var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;}; 78 | var substr = this.string.substr(this.pos, pattern.length); 79 | if (cased(substr) == cased(pattern)) { 80 | if (consume !== false) this.pos += pattern.length; 81 | return true; 82 | } 83 | } else { 84 | var match = this.string.slice(this.pos).match(pattern); 85 | if (match && match.index > 0) return null; 86 | if (match && consume !== false) this.pos += match[0].length; 87 | return match; 88 | } 89 | }, 90 | current: function(){return this.string.slice(this.start, this.pos);}, 91 | hideFirstChars: function(n, inner) { 92 | this.lineStart += n; 93 | try { return inner(); } 94 | finally { this.lineStart -= n; } 95 | }, 96 | lookAhead: function(n) { 97 | var line = this.context.line + n 98 | return line >= this.context.lines.length ? null : this.context.lines[line] 99 | } 100 | }; 101 | exports.StringStream = StringStream; 102 | 103 | exports.startState = function(mode, a1, a2) { 104 | return mode.startState ? mode.startState(a1, a2) : true; 105 | }; 106 | 107 | var modes = exports.modes = {}, mimeModes = exports.mimeModes = {}; 108 | exports.defineMode = function(name, mode) { 109 | if (arguments.length > 2) 110 | mode.dependencies = Array.prototype.slice.call(arguments, 2); 111 | modes[name] = mode; 112 | }; 113 | exports.defineMIME = function(mime, spec) { mimeModes[mime] = spec; }; 114 | 115 | exports.defineMode("null", function() { 116 | return {token: function(stream) {stream.skipToEnd();}}; 117 | }); 118 | exports.defineMIME("text/plain", "null"); 119 | 120 | exports.resolveMode = function(spec) { 121 | if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) { 122 | spec = mimeModes[spec]; 123 | } else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) { 124 | spec = mimeModes[spec.name]; 125 | } 126 | if (typeof spec == "string") return {name: spec}; 127 | else return spec || {name: "null"}; 128 | }; 129 | 130 | function copyObj(obj, target, overwrite) { 131 | if (!target) target = {}; 132 | for (var prop in obj) 133 | if (obj.hasOwnProperty(prop) && (overwrite !== false || !target.hasOwnProperty(prop))) 134 | target[prop] = obj[prop]; 135 | return target; 136 | } 137 | 138 | // This can be used to attach properties to mode objects from 139 | // outside the actual mode definition. 140 | var modeExtensions = exports.modeExtensions = {}; 141 | exports.extendMode = function(mode, properties) { 142 | var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {}); 143 | copyObj(properties, exts); 144 | }; 145 | 146 | exports.getMode = function(options, spec) { 147 | var spec = exports.resolveMode(spec); 148 | var mfactory = modes[spec.name]; 149 | if (!mfactory) return exports.getMode(options, "text/plain"); 150 | var modeObj = mfactory(options, spec); 151 | if (modeExtensions.hasOwnProperty(spec.name)) { 152 | var exts = modeExtensions[spec.name]; 153 | for (var prop in exts) { 154 | if (!exts.hasOwnProperty(prop)) continue; 155 | if (modeObj.hasOwnProperty(prop)) modeObj["_" + prop] = modeObj[prop]; 156 | modeObj[prop] = exts[prop]; 157 | } 158 | } 159 | modeObj.name = spec.name; 160 | if (spec.helperType) modeObj.helperType = spec.helperType; 161 | if (spec.modeProps) for (var prop in spec.modeProps) 162 | modeObj[prop] = spec.modeProps[prop]; 163 | 164 | return modeObj; 165 | }; 166 | 167 | exports.innerMode = function(mode, state) { 168 | var info; 169 | while (mode.innerMode) { 170 | info = mode.innerMode(state); 171 | if (!info || info.mode == mode) break; 172 | state = info.state; 173 | mode = info.mode; 174 | } 175 | return info || {mode: mode, state: state}; 176 | } 177 | 178 | exports.registerHelper = exports.registerGlobalHelper = Math.min; 179 | 180 | exports.runMode = function(string, modespec, callback, options) { 181 | var mode = exports.getMode({indentUnit: 2}, modespec); 182 | var lines = splitLines(string), state = (options && options.state) || exports.startState(mode); 183 | var context = {lines: lines, line: 0} 184 | for (var i = 0, e = lines.length; i < e; ++i, ++context.line) { 185 | if (i) callback("\n"); 186 | var stream = new exports.StringStream(lines[i], 4, context); 187 | if (!stream.string && mode.blankLine) mode.blankLine(state); 188 | while (!stream.eol()) { 189 | var style = mode.token(stream, state); 190 | callback(stream.current(), style, i, stream.start, state); 191 | stream.start = stream.pos; 192 | } 193 | } 194 | }; 195 | 196 | require.cache[require.resolve("../../lib/codemirror")] = require.cache[require.resolve("./runmode.node")]; 197 | require.cache[require.resolve("../../addon/runmode/runmode")] = require.cache[require.resolve("./runmode.node")]; 198 | -------------------------------------------------------------------------------- /codemirror/addon/scroll/annotatescrollbar.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: https://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | CodeMirror.defineExtension("annotateScrollbar", function(options) { 15 | if (typeof options == "string") options = {className: options}; 16 | return new Annotation(this, options); 17 | }); 18 | 19 | CodeMirror.defineOption("scrollButtonHeight", 0); 20 | 21 | function Annotation(cm, options) { 22 | this.cm = cm; 23 | this.options = options; 24 | this.buttonHeight = options.scrollButtonHeight || cm.getOption("scrollButtonHeight"); 25 | this.annotations = []; 26 | this.doRedraw = this.doUpdate = null; 27 | this.div = cm.getWrapperElement().appendChild(document.createElement("div")); 28 | this.div.style.cssText = "position: absolute; right: 0; top: 0; z-index: 7; pointer-events: none"; 29 | this.computeScale(); 30 | 31 | function scheduleRedraw(delay) { 32 | clearTimeout(self.doRedraw); 33 | self.doRedraw = setTimeout(function() { self.redraw(); }, delay); 34 | } 35 | 36 | var self = this; 37 | cm.on("refresh", this.resizeHandler = function() { 38 | clearTimeout(self.doUpdate); 39 | self.doUpdate = setTimeout(function() { 40 | if (self.computeScale()) scheduleRedraw(20); 41 | }, 100); 42 | }); 43 | cm.on("markerAdded", this.resizeHandler); 44 | cm.on("markerCleared", this.resizeHandler); 45 | if (options.listenForChanges !== false) 46 | cm.on("change", this.changeHandler = function() { 47 | scheduleRedraw(250); 48 | }); 49 | } 50 | 51 | Annotation.prototype.computeScale = function() { 52 | var cm = this.cm; 53 | var hScale = (cm.getWrapperElement().clientHeight - cm.display.barHeight - this.buttonHeight * 2) / 54 | cm.getScrollerElement().scrollHeight 55 | if (hScale != this.hScale) { 56 | this.hScale = hScale; 57 | return true; 58 | } 59 | }; 60 | 61 | Annotation.prototype.update = function(annotations) { 62 | this.annotations = annotations; 63 | this.redraw(); 64 | }; 65 | 66 | Annotation.prototype.redraw = function(compute) { 67 | if (compute !== false) this.computeScale(); 68 | var cm = this.cm, hScale = this.hScale; 69 | 70 | var frag = document.createDocumentFragment(), anns = this.annotations; 71 | 72 | var wrapping = cm.getOption("lineWrapping"); 73 | var singleLineH = wrapping && cm.defaultTextHeight() * 1.5; 74 | var curLine = null, curLineObj = null; 75 | function getY(pos, top) { 76 | if (curLine != pos.line) { 77 | curLine = pos.line; 78 | curLineObj = cm.getLineHandle(curLine); 79 | } 80 | if ((curLineObj.widgets && curLineObj.widgets.length) || 81 | (wrapping && curLineObj.height > singleLineH)) 82 | return cm.charCoords(pos, "local")[top ? "top" : "bottom"]; 83 | var topY = cm.heightAtLine(curLineObj, "local"); 84 | return topY + (top ? 0 : curLineObj.height); 85 | } 86 | 87 | var lastLine = cm.lastLine() 88 | if (cm.display.barWidth) for (var i = 0, nextTop; i < anns.length; i++) { 89 | var ann = anns[i]; 90 | if (ann.to.line > lastLine) continue; 91 | var top = nextTop || getY(ann.from, true) * hScale; 92 | var bottom = getY(ann.to, false) * hScale; 93 | while (i < anns.length - 1) { 94 | if (anns[i + 1].to.line > lastLine) break; 95 | nextTop = getY(anns[i + 1].from, true) * hScale; 96 | if (nextTop > bottom + .9) break; 97 | ann = anns[++i]; 98 | bottom = getY(ann.to, false) * hScale; 99 | } 100 | if (bottom == top) continue; 101 | var height = Math.max(bottom - top, 3); 102 | 103 | var elt = frag.appendChild(document.createElement("div")); 104 | elt.style.cssText = "position: absolute; right: 0px; width: " + Math.max(cm.display.barWidth - 1, 2) + "px; top: " 105 | + (top + this.buttonHeight) + "px; height: " + height + "px"; 106 | elt.className = this.options.className; 107 | if (ann.id) { 108 | elt.setAttribute("annotation-id", ann.id); 109 | } 110 | } 111 | this.div.textContent = ""; 112 | this.div.appendChild(frag); 113 | }; 114 | 115 | Annotation.prototype.clear = function() { 116 | this.cm.off("refresh", this.resizeHandler); 117 | this.cm.off("markerAdded", this.resizeHandler); 118 | this.cm.off("markerCleared", this.resizeHandler); 119 | if (this.changeHandler) this.cm.off("change", this.changeHandler); 120 | this.div.parentNode.removeChild(this.div); 121 | }; 122 | }); 123 | -------------------------------------------------------------------------------- /codemirror/addon/scroll/scrollpastend.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: https://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | CodeMirror.defineOption("scrollPastEnd", false, function(cm, val, old) { 15 | if (old && old != CodeMirror.Init) { 16 | cm.off("change", onChange); 17 | cm.off("refresh", updateBottomMargin); 18 | cm.display.lineSpace.parentNode.style.paddingBottom = ""; 19 | cm.state.scrollPastEndPadding = null; 20 | } 21 | if (val) { 22 | cm.on("change", onChange); 23 | cm.on("refresh", updateBottomMargin); 24 | updateBottomMargin(cm); 25 | } 26 | }); 27 | 28 | function onChange(cm, change) { 29 | if (CodeMirror.changeEnd(change).line == cm.lastLine()) 30 | updateBottomMargin(cm); 31 | } 32 | 33 | function updateBottomMargin(cm) { 34 | var padding = ""; 35 | if (cm.lineCount() > 1) { 36 | var totalH = cm.display.scroller.clientHeight - 30, 37 | lastLineH = cm.getLineHandle(cm.lastLine()).height; 38 | padding = (totalH - lastLineH) + "px"; 39 | } 40 | if (cm.state.scrollPastEndPadding != padding) { 41 | cm.state.scrollPastEndPadding = padding; 42 | cm.display.lineSpace.parentNode.style.paddingBottom = padding; 43 | cm.off("refresh", updateBottomMargin); 44 | cm.setSize(); 45 | cm.on("refresh", updateBottomMargin); 46 | } 47 | } 48 | }); 49 | -------------------------------------------------------------------------------- /codemirror/addon/scroll/simplescrollbars.css: -------------------------------------------------------------------------------- 1 | .CodeMirror-simplescroll-horizontal div, .CodeMirror-simplescroll-vertical div { 2 | position: absolute; 3 | background: #ccc; 4 | -moz-box-sizing: border-box; 5 | box-sizing: border-box; 6 | border: 1px solid #bbb; 7 | border-radius: 2px; 8 | } 9 | 10 | .CodeMirror-simplescroll-horizontal, .CodeMirror-simplescroll-vertical { 11 | position: absolute; 12 | z-index: 6; 13 | background: #eee; 14 | } 15 | 16 | .CodeMirror-simplescroll-horizontal { 17 | bottom: 0; left: 0; 18 | height: 8px; 19 | } 20 | .CodeMirror-simplescroll-horizontal div { 21 | bottom: 0; 22 | height: 100%; 23 | } 24 | 25 | .CodeMirror-simplescroll-vertical { 26 | right: 0; top: 0; 27 | width: 8px; 28 | } 29 | .CodeMirror-simplescroll-vertical div { 30 | right: 0; 31 | width: 100%; 32 | } 33 | 34 | 35 | .CodeMirror-overlayscroll .CodeMirror-scrollbar-filler, .CodeMirror-overlayscroll .CodeMirror-gutter-filler { 36 | display: none; 37 | } 38 | 39 | .CodeMirror-overlayscroll-horizontal div, .CodeMirror-overlayscroll-vertical div { 40 | position: absolute; 41 | background: #bcd; 42 | border-radius: 3px; 43 | } 44 | 45 | .CodeMirror-overlayscroll-horizontal, .CodeMirror-overlayscroll-vertical { 46 | position: absolute; 47 | z-index: 6; 48 | } 49 | 50 | .CodeMirror-overlayscroll-horizontal { 51 | bottom: 0; left: 0; 52 | height: 6px; 53 | } 54 | .CodeMirror-overlayscroll-horizontal div { 55 | bottom: 0; 56 | height: 100%; 57 | } 58 | 59 | .CodeMirror-overlayscroll-vertical { 60 | right: 0; top: 0; 61 | width: 6px; 62 | } 63 | .CodeMirror-overlayscroll-vertical div { 64 | right: 0; 65 | width: 100%; 66 | } 67 | -------------------------------------------------------------------------------- /codemirror/addon/scroll/simplescrollbars.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: https://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | function Bar(cls, orientation, scroll) { 15 | this.orientation = orientation; 16 | this.scroll = scroll; 17 | this.screen = this.total = this.size = 1; 18 | this.pos = 0; 19 | 20 | this.node = document.createElement("div"); 21 | this.node.className = cls + "-" + orientation; 22 | this.inner = this.node.appendChild(document.createElement("div")); 23 | 24 | var self = this; 25 | CodeMirror.on(this.inner, "mousedown", function(e) { 26 | if (e.which != 1) return; 27 | CodeMirror.e_preventDefault(e); 28 | var axis = self.orientation == "horizontal" ? "pageX" : "pageY"; 29 | var start = e[axis], startpos = self.pos; 30 | function done() { 31 | CodeMirror.off(document, "mousemove", move); 32 | CodeMirror.off(document, "mouseup", done); 33 | } 34 | function move(e) { 35 | if (e.which != 1) return done(); 36 | self.moveTo(startpos + (e[axis] - start) * (self.total / self.size)); 37 | } 38 | CodeMirror.on(document, "mousemove", move); 39 | CodeMirror.on(document, "mouseup", done); 40 | }); 41 | 42 | CodeMirror.on(this.node, "click", function(e) { 43 | CodeMirror.e_preventDefault(e); 44 | var innerBox = self.inner.getBoundingClientRect(), where; 45 | if (self.orientation == "horizontal") 46 | where = e.clientX < innerBox.left ? -1 : e.clientX > innerBox.right ? 1 : 0; 47 | else 48 | where = e.clientY < innerBox.top ? -1 : e.clientY > innerBox.bottom ? 1 : 0; 49 | self.moveTo(self.pos + where * self.screen); 50 | }); 51 | 52 | function onWheel(e) { 53 | var moved = CodeMirror.wheelEventPixels(e)[self.orientation == "horizontal" ? "x" : "y"]; 54 | var oldPos = self.pos; 55 | self.moveTo(self.pos + moved); 56 | if (self.pos != oldPos) CodeMirror.e_preventDefault(e); 57 | } 58 | CodeMirror.on(this.node, "mousewheel", onWheel); 59 | CodeMirror.on(this.node, "DOMMouseScroll", onWheel); 60 | } 61 | 62 | Bar.prototype.setPos = function(pos, force) { 63 | if (pos < 0) pos = 0; 64 | if (pos > this.total - this.screen) pos = this.total - this.screen; 65 | if (!force && pos == this.pos) return false; 66 | this.pos = pos; 67 | this.inner.style[this.orientation == "horizontal" ? "left" : "top"] = 68 | (pos * (this.size / this.total)) + "px"; 69 | return true 70 | }; 71 | 72 | Bar.prototype.moveTo = function(pos) { 73 | if (this.setPos(pos)) this.scroll(pos, this.orientation); 74 | } 75 | 76 | var minButtonSize = 10; 77 | 78 | Bar.prototype.update = function(scrollSize, clientSize, barSize) { 79 | var sizeChanged = this.screen != clientSize || this.total != scrollSize || this.size != barSize 80 | if (sizeChanged) { 81 | this.screen = clientSize; 82 | this.total = scrollSize; 83 | this.size = barSize; 84 | } 85 | 86 | var buttonSize = this.screen * (this.size / this.total); 87 | if (buttonSize < minButtonSize) { 88 | this.size -= minButtonSize - buttonSize; 89 | buttonSize = minButtonSize; 90 | } 91 | this.inner.style[this.orientation == "horizontal" ? "width" : "height"] = 92 | buttonSize + "px"; 93 | this.setPos(this.pos, sizeChanged); 94 | }; 95 | 96 | function SimpleScrollbars(cls, place, scroll) { 97 | this.addClass = cls; 98 | this.horiz = new Bar(cls, "horizontal", scroll); 99 | place(this.horiz.node); 100 | this.vert = new Bar(cls, "vertical", scroll); 101 | place(this.vert.node); 102 | this.width = null; 103 | } 104 | 105 | SimpleScrollbars.prototype.update = function(measure) { 106 | if (this.width == null) { 107 | var style = window.getComputedStyle ? window.getComputedStyle(this.horiz.node) : this.horiz.node.currentStyle; 108 | if (style) this.width = parseInt(style.height); 109 | } 110 | var width = this.width || 0; 111 | 112 | var needsH = measure.scrollWidth > measure.clientWidth + 1; 113 | var needsV = measure.scrollHeight > measure.clientHeight + 1; 114 | this.vert.node.style.display = needsV ? "block" : "none"; 115 | this.horiz.node.style.display = needsH ? "block" : "none"; 116 | 117 | if (needsV) { 118 | this.vert.update(measure.scrollHeight, measure.clientHeight, 119 | measure.viewHeight - (needsH ? width : 0)); 120 | this.vert.node.style.bottom = needsH ? width + "px" : "0"; 121 | } 122 | if (needsH) { 123 | this.horiz.update(measure.scrollWidth, measure.clientWidth, 124 | measure.viewWidth - (needsV ? width : 0) - measure.barLeft); 125 | this.horiz.node.style.right = needsV ? width + "px" : "0"; 126 | this.horiz.node.style.left = measure.barLeft + "px"; 127 | } 128 | 129 | return {right: needsV ? width : 0, bottom: needsH ? width : 0}; 130 | }; 131 | 132 | SimpleScrollbars.prototype.setScrollTop = function(pos) { 133 | this.vert.setPos(pos); 134 | }; 135 | 136 | SimpleScrollbars.prototype.setScrollLeft = function(pos) { 137 | this.horiz.setPos(pos); 138 | }; 139 | 140 | SimpleScrollbars.prototype.clear = function() { 141 | var parent = this.horiz.node.parentNode; 142 | parent.removeChild(this.horiz.node); 143 | parent.removeChild(this.vert.node); 144 | }; 145 | 146 | CodeMirror.scrollbarModel.simple = function(place, scroll) { 147 | return new SimpleScrollbars("CodeMirror-simplescroll", place, scroll); 148 | }; 149 | CodeMirror.scrollbarModel.overlay = function(place, scroll) { 150 | return new SimpleScrollbars("CodeMirror-overlayscroll", place, scroll); 151 | }; 152 | }); 153 | -------------------------------------------------------------------------------- /codemirror/addon/search/jump-to-line.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: https://codemirror.net/LICENSE 3 | 4 | // Defines jumpToLine command. Uses dialog.js if present. 5 | 6 | (function(mod) { 7 | if (typeof exports == "object" && typeof module == "object") // CommonJS 8 | mod(require("../../lib/codemirror"), require("../dialog/dialog")); 9 | else if (typeof define == "function" && define.amd) // AMD 10 | define(["../../lib/codemirror", "../dialog/dialog"], mod); 11 | else // Plain browser env 12 | mod(CodeMirror); 13 | })(function(CodeMirror) { 14 | "use strict"; 15 | 16 | function dialog(cm, text, shortText, deflt, f) { 17 | if (cm.openDialog) cm.openDialog(text, f, {value: deflt, selectValueOnOpen: true}); 18 | else f(prompt(shortText, deflt)); 19 | } 20 | 21 | function getJumpDialog(cm) { 22 | return cm.phrase("Jump to line:") + ' ' + cm.phrase("(Use line:column or scroll% syntax)") + ''; 23 | } 24 | 25 | function interpretLine(cm, string) { 26 | var num = Number(string) 27 | if (/^[-+]/.test(string)) return cm.getCursor().line + num 28 | else return num - 1 29 | } 30 | 31 | CodeMirror.commands.jumpToLine = function(cm) { 32 | var cur = cm.getCursor(); 33 | dialog(cm, getJumpDialog(cm), cm.phrase("Jump to line:"), (cur.line + 1) + ":" + cur.ch, function(posStr) { 34 | if (!posStr) return; 35 | 36 | var match; 37 | if (match = /^\s*([\+\-]?\d+)\s*\:\s*(\d+)\s*$/.exec(posStr)) { 38 | cm.setCursor(interpretLine(cm, match[1]), Number(match[2])) 39 | } else if (match = /^\s*([\+\-]?\d+(\.\d+)?)\%\s*/.exec(posStr)) { 40 | var line = Math.round(cm.lineCount() * Number(match[1]) / 100); 41 | if (/^[-+]/.test(match[1])) line = cur.line + line + 1; 42 | cm.setCursor(line - 1, cur.ch); 43 | } else if (match = /^\s*\:?\s*([\+\-]?\d+)\s*/.exec(posStr)) { 44 | cm.setCursor(interpretLine(cm, match[1]), cur.ch); 45 | } 46 | }); 47 | }; 48 | 49 | CodeMirror.keyMap["default"]["Alt-G"] = "jumpToLine"; 50 | }); 51 | -------------------------------------------------------------------------------- /codemirror/addon/search/match-highlighter.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: https://codemirror.net/LICENSE 3 | 4 | // Highlighting text that matches the selection 5 | // 6 | // Defines an option highlightSelectionMatches, which, when enabled, 7 | // will style strings that match the selection throughout the 8 | // document. 9 | // 10 | // The option can be set to true to simply enable it, or to a 11 | // {minChars, style, wordsOnly, showToken, delay} object to explicitly 12 | // configure it. minChars is the minimum amount of characters that should be 13 | // selected for the behavior to occur, and style is the token style to 14 | // apply to the matches. This will be prefixed by "cm-" to create an 15 | // actual CSS class name. If wordsOnly is enabled, the matches will be 16 | // highlighted only if the selected text is a word. showToken, when enabled, 17 | // will cause the current token to be highlighted when nothing is selected. 18 | // delay is used to specify how much time to wait, in milliseconds, before 19 | // highlighting the matches. If annotateScrollbar is enabled, the occurences 20 | // will be highlighted on the scrollbar via the matchesonscrollbar addon. 21 | 22 | (function(mod) { 23 | if (typeof exports == "object" && typeof module == "object") // CommonJS 24 | mod(require("../../lib/codemirror"), require("./matchesonscrollbar")); 25 | else if (typeof define == "function" && define.amd) // AMD 26 | define(["../../lib/codemirror", "./matchesonscrollbar"], mod); 27 | else // Plain browser env 28 | mod(CodeMirror); 29 | })(function(CodeMirror) { 30 | "use strict"; 31 | 32 | var defaults = { 33 | style: "matchhighlight", 34 | minChars: 2, 35 | delay: 100, 36 | wordsOnly: false, 37 | annotateScrollbar: false, 38 | showToken: false, 39 | trim: true 40 | } 41 | 42 | function State(options) { 43 | this.options = {} 44 | for (var name in defaults) 45 | this.options[name] = (options && options.hasOwnProperty(name) ? options : defaults)[name] 46 | this.overlay = this.timeout = null; 47 | this.matchesonscroll = null; 48 | this.active = false; 49 | } 50 | 51 | CodeMirror.defineOption("highlightSelectionMatches", false, function(cm, val, old) { 52 | if (old && old != CodeMirror.Init) { 53 | removeOverlay(cm); 54 | clearTimeout(cm.state.matchHighlighter.timeout); 55 | cm.state.matchHighlighter = null; 56 | cm.off("cursorActivity", cursorActivity); 57 | cm.off("focus", onFocus) 58 | } 59 | if (val) { 60 | var state = cm.state.matchHighlighter = new State(val); 61 | if (cm.hasFocus()) { 62 | state.active = true 63 | highlightMatches(cm) 64 | } else { 65 | cm.on("focus", onFocus) 66 | } 67 | cm.on("cursorActivity", cursorActivity); 68 | } 69 | }); 70 | 71 | function cursorActivity(cm) { 72 | var state = cm.state.matchHighlighter; 73 | if (state.active || cm.hasFocus()) scheduleHighlight(cm, state) 74 | } 75 | 76 | function onFocus(cm) { 77 | var state = cm.state.matchHighlighter 78 | if (!state.active) { 79 | state.active = true 80 | scheduleHighlight(cm, state) 81 | } 82 | } 83 | 84 | function scheduleHighlight(cm, state) { 85 | clearTimeout(state.timeout); 86 | state.timeout = setTimeout(function() {highlightMatches(cm);}, state.options.delay); 87 | } 88 | 89 | function addOverlay(cm, query, hasBoundary, style) { 90 | var state = cm.state.matchHighlighter; 91 | cm.addOverlay(state.overlay = makeOverlay(query, hasBoundary, style)); 92 | if (state.options.annotateScrollbar && cm.showMatchesOnScrollbar) { 93 | var searchFor = hasBoundary ? new RegExp("\\b" + query.replace(/[\\\[.+*?(){|^$]/g, "\\$&") + "\\b") : query; 94 | state.matchesonscroll = cm.showMatchesOnScrollbar(searchFor, false, 95 | {className: "CodeMirror-selection-highlight-scrollbar"}); 96 | } 97 | } 98 | 99 | function removeOverlay(cm) { 100 | var state = cm.state.matchHighlighter; 101 | if (state.overlay) { 102 | cm.removeOverlay(state.overlay); 103 | state.overlay = null; 104 | if (state.matchesonscroll) { 105 | state.matchesonscroll.clear(); 106 | state.matchesonscroll = null; 107 | } 108 | } 109 | } 110 | 111 | function highlightMatches(cm) { 112 | cm.operation(function() { 113 | var state = cm.state.matchHighlighter; 114 | removeOverlay(cm); 115 | if (!cm.somethingSelected() && state.options.showToken) { 116 | var re = state.options.showToken === true ? /[\w$]/ : state.options.showToken; 117 | var cur = cm.getCursor(), line = cm.getLine(cur.line), start = cur.ch, end = start; 118 | while (start && re.test(line.charAt(start - 1))) --start; 119 | while (end < line.length && re.test(line.charAt(end))) ++end; 120 | if (start < end) 121 | addOverlay(cm, line.slice(start, end), re, state.options.style); 122 | return; 123 | } 124 | var from = cm.getCursor("from"), to = cm.getCursor("to"); 125 | if (from.line != to.line) return; 126 | if (state.options.wordsOnly && !isWord(cm, from, to)) return; 127 | var selection = cm.getRange(from, to) 128 | if (state.options.trim) selection = selection.replace(/^\s+|\s+$/g, "") 129 | if (selection.length >= state.options.minChars) 130 | addOverlay(cm, selection, false, state.options.style); 131 | }); 132 | } 133 | 134 | function isWord(cm, from, to) { 135 | var str = cm.getRange(from, to); 136 | if (str.match(/^\w+$/) !== null) { 137 | if (from.ch > 0) { 138 | var pos = {line: from.line, ch: from.ch - 1}; 139 | var chr = cm.getRange(pos, from); 140 | if (chr.match(/\W/) === null) return false; 141 | } 142 | if (to.ch < cm.getLine(from.line).length) { 143 | var pos = {line: to.line, ch: to.ch + 1}; 144 | var chr = cm.getRange(to, pos); 145 | if (chr.match(/\W/) === null) return false; 146 | } 147 | return true; 148 | } else return false; 149 | } 150 | 151 | function boundariesAround(stream, re) { 152 | return (!stream.start || !re.test(stream.string.charAt(stream.start - 1))) && 153 | (stream.pos == stream.string.length || !re.test(stream.string.charAt(stream.pos))); 154 | } 155 | 156 | function makeOverlay(query, hasBoundary, style) { 157 | return {token: function(stream) { 158 | if (stream.match(query) && 159 | (!hasBoundary || boundariesAround(stream, hasBoundary))) 160 | return style; 161 | stream.next(); 162 | stream.skipTo(query.charAt(0)) || stream.skipToEnd(); 163 | }}; 164 | } 165 | }); 166 | -------------------------------------------------------------------------------- /codemirror/addon/search/matchesonscrollbar.css: -------------------------------------------------------------------------------- 1 | .CodeMirror-search-match { 2 | background: gold; 3 | border-top: 1px solid orange; 4 | border-bottom: 1px solid orange; 5 | -moz-box-sizing: border-box; 6 | box-sizing: border-box; 7 | opacity: .5; 8 | } 9 | -------------------------------------------------------------------------------- /codemirror/addon/search/matchesonscrollbar.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: https://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror"), require("./searchcursor"), require("../scroll/annotatescrollbar")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror", "./searchcursor", "../scroll/annotatescrollbar"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | CodeMirror.defineExtension("showMatchesOnScrollbar", function(query, caseFold, options) { 15 | if (typeof options == "string") options = {className: options}; 16 | if (!options) options = {}; 17 | return new SearchAnnotation(this, query, caseFold, options); 18 | }); 19 | 20 | function SearchAnnotation(cm, query, caseFold, options) { 21 | this.cm = cm; 22 | this.options = options; 23 | var annotateOptions = {listenForChanges: false}; 24 | for (var prop in options) annotateOptions[prop] = options[prop]; 25 | if (!annotateOptions.className) annotateOptions.className = "CodeMirror-search-match"; 26 | this.annotation = cm.annotateScrollbar(annotateOptions); 27 | this.query = query; 28 | this.caseFold = caseFold; 29 | this.gap = {from: cm.firstLine(), to: cm.lastLine() + 1}; 30 | this.matches = []; 31 | this.update = null; 32 | 33 | this.findMatches(); 34 | this.annotation.update(this.matches); 35 | 36 | var self = this; 37 | cm.on("change", this.changeHandler = function(_cm, change) { self.onChange(change); }); 38 | } 39 | 40 | var MAX_MATCHES = 1000; 41 | 42 | SearchAnnotation.prototype.findMatches = function() { 43 | if (!this.gap) return; 44 | for (var i = 0; i < this.matches.length; i++) { 45 | var match = this.matches[i]; 46 | if (match.from.line >= this.gap.to) break; 47 | if (match.to.line >= this.gap.from) this.matches.splice(i--, 1); 48 | } 49 | var cursor = this.cm.getSearchCursor(this.query, CodeMirror.Pos(this.gap.from, 0), this.caseFold); 50 | var maxMatches = this.options && this.options.maxMatches || MAX_MATCHES; 51 | while (cursor.findNext()) { 52 | var match = {from: cursor.from(), to: cursor.to()}; 53 | if (match.from.line >= this.gap.to) break; 54 | this.matches.splice(i++, 0, match); 55 | if (this.matches.length > maxMatches) break; 56 | } 57 | this.gap = null; 58 | }; 59 | 60 | function offsetLine(line, changeStart, sizeChange) { 61 | if (line <= changeStart) return line; 62 | return Math.max(changeStart, line + sizeChange); 63 | } 64 | 65 | SearchAnnotation.prototype.onChange = function(change) { 66 | var startLine = change.from.line; 67 | var endLine = CodeMirror.changeEnd(change).line; 68 | var sizeChange = endLine - change.to.line; 69 | if (this.gap) { 70 | this.gap.from = Math.min(offsetLine(this.gap.from, startLine, sizeChange), change.from.line); 71 | this.gap.to = Math.max(offsetLine(this.gap.to, startLine, sizeChange), change.from.line); 72 | } else { 73 | this.gap = {from: change.from.line, to: endLine + 1}; 74 | } 75 | 76 | if (sizeChange) for (var i = 0; i < this.matches.length; i++) { 77 | var match = this.matches[i]; 78 | var newFrom = offsetLine(match.from.line, startLine, sizeChange); 79 | if (newFrom != match.from.line) match.from = CodeMirror.Pos(newFrom, match.from.ch); 80 | var newTo = offsetLine(match.to.line, startLine, sizeChange); 81 | if (newTo != match.to.line) match.to = CodeMirror.Pos(newTo, match.to.ch); 82 | } 83 | clearTimeout(this.update); 84 | var self = this; 85 | this.update = setTimeout(function() { self.updateAfterChange(); }, 250); 86 | }; 87 | 88 | SearchAnnotation.prototype.updateAfterChange = function() { 89 | this.findMatches(); 90 | this.annotation.update(this.matches); 91 | }; 92 | 93 | SearchAnnotation.prototype.clear = function() { 94 | this.cm.off("change", this.changeHandler); 95 | this.annotation.clear(); 96 | }; 97 | }); 98 | -------------------------------------------------------------------------------- /codemirror/addon/selection/active-line.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: https://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | var WRAP_CLASS = "CodeMirror-activeline"; 14 | var BACK_CLASS = "CodeMirror-activeline-background"; 15 | var GUTT_CLASS = "CodeMirror-activeline-gutter"; 16 | 17 | CodeMirror.defineOption("styleActiveLine", false, function(cm, val, old) { 18 | var prev = old == CodeMirror.Init ? false : old; 19 | if (val == prev) return 20 | if (prev) { 21 | cm.off("beforeSelectionChange", selectionChange); 22 | clearActiveLines(cm); 23 | delete cm.state.activeLines; 24 | } 25 | if (val) { 26 | cm.state.activeLines = []; 27 | updateActiveLines(cm, cm.listSelections()); 28 | cm.on("beforeSelectionChange", selectionChange); 29 | } 30 | }); 31 | 32 | function clearActiveLines(cm) { 33 | for (var i = 0; i < cm.state.activeLines.length; i++) { 34 | cm.removeLineClass(cm.state.activeLines[i], "wrap", WRAP_CLASS); 35 | cm.removeLineClass(cm.state.activeLines[i], "background", BACK_CLASS); 36 | cm.removeLineClass(cm.state.activeLines[i], "gutter", GUTT_CLASS); 37 | } 38 | } 39 | 40 | function sameArray(a, b) { 41 | if (a.length != b.length) return false; 42 | for (var i = 0; i < a.length; i++) 43 | if (a[i] != b[i]) return false; 44 | return true; 45 | } 46 | 47 | function updateActiveLines(cm, ranges) { 48 | var active = []; 49 | for (var i = 0; i < ranges.length; i++) { 50 | var range = ranges[i]; 51 | var option = cm.getOption("styleActiveLine"); 52 | if (typeof option == "object" && option.nonEmpty ? range.anchor.line != range.head.line : !range.empty()) 53 | continue 54 | var line = cm.getLineHandleVisualStart(range.head.line); 55 | if (active[active.length - 1] != line) active.push(line); 56 | } 57 | if (sameArray(cm.state.activeLines, active)) return; 58 | cm.operation(function() { 59 | clearActiveLines(cm); 60 | for (var i = 0; i < active.length; i++) { 61 | cm.addLineClass(active[i], "wrap", WRAP_CLASS); 62 | cm.addLineClass(active[i], "background", BACK_CLASS); 63 | cm.addLineClass(active[i], "gutter", GUTT_CLASS); 64 | } 65 | cm.state.activeLines = active; 66 | }); 67 | } 68 | 69 | function selectionChange(cm, sel) { 70 | updateActiveLines(cm, sel.ranges); 71 | } 72 | }); 73 | -------------------------------------------------------------------------------- /codemirror/addon/selection/mark-selection.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: https://codemirror.net/LICENSE 3 | 4 | // Because sometimes you need to mark the selected *text*. 5 | // 6 | // Adds an option 'styleSelectedText' which, when enabled, gives 7 | // selected text the CSS class given as option value, or 8 | // "CodeMirror-selectedtext" when the value is not a string. 9 | 10 | (function(mod) { 11 | if (typeof exports == "object" && typeof module == "object") // CommonJS 12 | mod(require("../../lib/codemirror")); 13 | else if (typeof define == "function" && define.amd) // AMD 14 | define(["../../lib/codemirror"], mod); 15 | else // Plain browser env 16 | mod(CodeMirror); 17 | })(function(CodeMirror) { 18 | "use strict"; 19 | 20 | CodeMirror.defineOption("styleSelectedText", false, function(cm, val, old) { 21 | var prev = old && old != CodeMirror.Init; 22 | if (val && !prev) { 23 | cm.state.markedSelection = []; 24 | cm.state.markedSelectionStyle = typeof val == "string" ? val : "CodeMirror-selectedtext"; 25 | reset(cm); 26 | cm.on("cursorActivity", onCursorActivity); 27 | cm.on("change", onChange); 28 | } else if (!val && prev) { 29 | cm.off("cursorActivity", onCursorActivity); 30 | cm.off("change", onChange); 31 | clear(cm); 32 | cm.state.markedSelection = cm.state.markedSelectionStyle = null; 33 | } 34 | }); 35 | 36 | function onCursorActivity(cm) { 37 | if (cm.state.markedSelection) 38 | cm.operation(function() { update(cm); }); 39 | } 40 | 41 | function onChange(cm) { 42 | if (cm.state.markedSelection && cm.state.markedSelection.length) 43 | cm.operation(function() { clear(cm); }); 44 | } 45 | 46 | var CHUNK_SIZE = 8; 47 | var Pos = CodeMirror.Pos; 48 | var cmp = CodeMirror.cmpPos; 49 | 50 | function coverRange(cm, from, to, addAt) { 51 | if (cmp(from, to) == 0) return; 52 | var array = cm.state.markedSelection; 53 | var cls = cm.state.markedSelectionStyle; 54 | for (var line = from.line;;) { 55 | var start = line == from.line ? from : Pos(line, 0); 56 | var endLine = line + CHUNK_SIZE, atEnd = endLine >= to.line; 57 | var end = atEnd ? to : Pos(endLine, 0); 58 | var mark = cm.markText(start, end, {className: cls}); 59 | if (addAt == null) array.push(mark); 60 | else array.splice(addAt++, 0, mark); 61 | if (atEnd) break; 62 | line = endLine; 63 | } 64 | } 65 | 66 | function clear(cm) { 67 | var array = cm.state.markedSelection; 68 | for (var i = 0; i < array.length; ++i) array[i].clear(); 69 | array.length = 0; 70 | } 71 | 72 | function reset(cm) { 73 | clear(cm); 74 | var ranges = cm.listSelections(); 75 | for (var i = 0; i < ranges.length; i++) 76 | coverRange(cm, ranges[i].from(), ranges[i].to()); 77 | } 78 | 79 | function update(cm) { 80 | if (!cm.somethingSelected()) return clear(cm); 81 | if (cm.listSelections().length > 1) return reset(cm); 82 | 83 | var from = cm.getCursor("start"), to = cm.getCursor("end"); 84 | 85 | var array = cm.state.markedSelection; 86 | if (!array.length) return coverRange(cm, from, to); 87 | 88 | var coverStart = array[0].find(), coverEnd = array[array.length - 1].find(); 89 | if (!coverStart || !coverEnd || to.line - from.line <= CHUNK_SIZE || 90 | cmp(from, coverEnd.to) >= 0 || cmp(to, coverStart.from) <= 0) 91 | return reset(cm); 92 | 93 | while (cmp(from, coverStart.from) > 0) { 94 | array.shift().clear(); 95 | coverStart = array[0].find(); 96 | } 97 | if (cmp(from, coverStart.from) < 0) { 98 | if (coverStart.to.line - from.line < CHUNK_SIZE) { 99 | array.shift().clear(); 100 | coverRange(cm, from, coverStart.to, 0); 101 | } else { 102 | coverRange(cm, from, coverStart.from, 0); 103 | } 104 | } 105 | 106 | while (cmp(to, coverEnd.to) < 0) { 107 | array.pop().clear(); 108 | coverEnd = array[array.length - 1].find(); 109 | } 110 | if (cmp(to, coverEnd.to) > 0) { 111 | if (to.line - coverEnd.from.line < CHUNK_SIZE) { 112 | array.pop().clear(); 113 | coverRange(cm, coverEnd.from, to); 114 | } else { 115 | coverRange(cm, coverEnd.to, to); 116 | } 117 | } 118 | } 119 | }); 120 | -------------------------------------------------------------------------------- /codemirror/addon/selection/selection-pointer.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: https://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | CodeMirror.defineOption("selectionPointer", false, function(cm, val) { 15 | var data = cm.state.selectionPointer; 16 | if (data) { 17 | CodeMirror.off(cm.getWrapperElement(), "mousemove", data.mousemove); 18 | CodeMirror.off(cm.getWrapperElement(), "mouseout", data.mouseout); 19 | CodeMirror.off(window, "scroll", data.windowScroll); 20 | cm.off("cursorActivity", reset); 21 | cm.off("scroll", reset); 22 | cm.state.selectionPointer = null; 23 | cm.display.lineDiv.style.cursor = ""; 24 | } 25 | if (val) { 26 | data = cm.state.selectionPointer = { 27 | value: typeof val == "string" ? val : "default", 28 | mousemove: function(event) { mousemove(cm, event); }, 29 | mouseout: function(event) { mouseout(cm, event); }, 30 | windowScroll: function() { reset(cm); }, 31 | rects: null, 32 | mouseX: null, mouseY: null, 33 | willUpdate: false 34 | }; 35 | CodeMirror.on(cm.getWrapperElement(), "mousemove", data.mousemove); 36 | CodeMirror.on(cm.getWrapperElement(), "mouseout", data.mouseout); 37 | CodeMirror.on(window, "scroll", data.windowScroll); 38 | cm.on("cursorActivity", reset); 39 | cm.on("scroll", reset); 40 | } 41 | }); 42 | 43 | function mousemove(cm, event) { 44 | var data = cm.state.selectionPointer; 45 | if (event.buttons == null ? event.which : event.buttons) { 46 | data.mouseX = data.mouseY = null; 47 | } else { 48 | data.mouseX = event.clientX; 49 | data.mouseY = event.clientY; 50 | } 51 | scheduleUpdate(cm); 52 | } 53 | 54 | function mouseout(cm, event) { 55 | if (!cm.getWrapperElement().contains(event.relatedTarget)) { 56 | var data = cm.state.selectionPointer; 57 | data.mouseX = data.mouseY = null; 58 | scheduleUpdate(cm); 59 | } 60 | } 61 | 62 | function reset(cm) { 63 | cm.state.selectionPointer.rects = null; 64 | scheduleUpdate(cm); 65 | } 66 | 67 | function scheduleUpdate(cm) { 68 | if (!cm.state.selectionPointer.willUpdate) { 69 | cm.state.selectionPointer.willUpdate = true; 70 | setTimeout(function() { 71 | update(cm); 72 | cm.state.selectionPointer.willUpdate = false; 73 | }, 50); 74 | } 75 | } 76 | 77 | function update(cm) { 78 | var data = cm.state.selectionPointer; 79 | if (!data) return; 80 | if (data.rects == null && data.mouseX != null) { 81 | data.rects = []; 82 | if (cm.somethingSelected()) { 83 | for (var sel = cm.display.selectionDiv.firstChild; sel; sel = sel.nextSibling) 84 | data.rects.push(sel.getBoundingClientRect()); 85 | } 86 | } 87 | var inside = false; 88 | if (data.mouseX != null) for (var i = 0; i < data.rects.length; i++) { 89 | var rect = data.rects[i]; 90 | if (rect.left <= data.mouseX && rect.right >= data.mouseX && 91 | rect.top <= data.mouseY && rect.bottom >= data.mouseY) 92 | inside = true; 93 | } 94 | var cursor = inside ? data.value : ""; 95 | if (cm.display.lineDiv.style.cursor != cursor) 96 | cm.display.lineDiv.style.cursor = cursor; 97 | } 98 | }); 99 | -------------------------------------------------------------------------------- /codemirror/addon/tern/tern.css: -------------------------------------------------------------------------------- 1 | .CodeMirror-Tern-completion { 2 | padding-left: 22px; 3 | position: relative; 4 | line-height: 1.5; 5 | } 6 | .CodeMirror-Tern-completion:before { 7 | position: absolute; 8 | left: 2px; 9 | bottom: 2px; 10 | border-radius: 50%; 11 | font-size: 12px; 12 | font-weight: bold; 13 | height: 15px; 14 | width: 15px; 15 | line-height: 16px; 16 | text-align: center; 17 | color: white; 18 | -moz-box-sizing: border-box; 19 | box-sizing: border-box; 20 | } 21 | .CodeMirror-Tern-completion-unknown:before { 22 | content: "?"; 23 | background: #4bb; 24 | } 25 | .CodeMirror-Tern-completion-object:before { 26 | content: "O"; 27 | background: #77c; 28 | } 29 | .CodeMirror-Tern-completion-fn:before { 30 | content: "F"; 31 | background: #7c7; 32 | } 33 | .CodeMirror-Tern-completion-array:before { 34 | content: "A"; 35 | background: #c66; 36 | } 37 | .CodeMirror-Tern-completion-number:before { 38 | content: "1"; 39 | background: #999; 40 | } 41 | .CodeMirror-Tern-completion-string:before { 42 | content: "S"; 43 | background: #999; 44 | } 45 | .CodeMirror-Tern-completion-bool:before { 46 | content: "B"; 47 | background: #999; 48 | } 49 | 50 | .CodeMirror-Tern-completion-guess { 51 | color: #999; 52 | } 53 | 54 | .CodeMirror-Tern-tooltip { 55 | border: 1px solid silver; 56 | border-radius: 3px; 57 | color: #444; 58 | padding: 2px 5px; 59 | font-size: 90%; 60 | font-family: monospace; 61 | background-color: white; 62 | white-space: pre-wrap; 63 | 64 | max-width: 40em; 65 | position: absolute; 66 | z-index: 10; 67 | -webkit-box-shadow: 2px 3px 5px rgba(0,0,0,.2); 68 | -moz-box-shadow: 2px 3px 5px rgba(0,0,0,.2); 69 | box-shadow: 2px 3px 5px rgba(0,0,0,.2); 70 | 71 | transition: opacity 1s; 72 | -moz-transition: opacity 1s; 73 | -webkit-transition: opacity 1s; 74 | -o-transition: opacity 1s; 75 | -ms-transition: opacity 1s; 76 | } 77 | 78 | .CodeMirror-Tern-hint-doc { 79 | max-width: 25em; 80 | margin-top: -3px; 81 | } 82 | 83 | .CodeMirror-Tern-fname { color: black; } 84 | .CodeMirror-Tern-farg { color: #70a; } 85 | .CodeMirror-Tern-farg-current { text-decoration: underline; } 86 | .CodeMirror-Tern-type { color: #07c; } 87 | .CodeMirror-Tern-fhint-guess { opacity: .7; } 88 | -------------------------------------------------------------------------------- /codemirror/addon/tern/worker.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: https://codemirror.net/LICENSE 3 | 4 | // declare global: tern, server 5 | 6 | var server; 7 | 8 | this.onmessage = function(e) { 9 | var data = e.data; 10 | switch (data.type) { 11 | case "init": return startServer(data.defs, data.plugins, data.scripts); 12 | case "add": return server.addFile(data.name, data.text); 13 | case "del": return server.delFile(data.name); 14 | case "req": return server.request(data.body, function(err, reqData) { 15 | postMessage({id: data.id, body: reqData, err: err && String(err)}); 16 | }); 17 | case "getFile": 18 | var c = pending[data.id]; 19 | delete pending[data.id]; 20 | return c(data.err, data.text); 21 | default: throw new Error("Unknown message type: " + data.type); 22 | } 23 | }; 24 | 25 | var nextId = 0, pending = {}; 26 | function getFile(file, c) { 27 | postMessage({type: "getFile", name: file, id: ++nextId}); 28 | pending[nextId] = c; 29 | } 30 | 31 | function startServer(defs, plugins, scripts) { 32 | if (scripts) importScripts.apply(null, scripts); 33 | 34 | server = new tern.Server({ 35 | getFile: getFile, 36 | async: true, 37 | defs: defs, 38 | plugins: plugins 39 | }); 40 | } 41 | 42 | this.console = { 43 | log: function(v) { postMessage({type: "debug", message: v}); } 44 | }; 45 | -------------------------------------------------------------------------------- /codemirror/addon/wrap/hardwrap.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: https://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == "object" && typeof module == "object") // CommonJS 6 | mod(require("../../lib/codemirror")); 7 | else if (typeof define == "function" && define.amd) // AMD 8 | define(["../../lib/codemirror"], mod); 9 | else // Plain browser env 10 | mod(CodeMirror); 11 | })(function(CodeMirror) { 12 | "use strict"; 13 | 14 | var Pos = CodeMirror.Pos; 15 | 16 | function findParagraph(cm, pos, options) { 17 | var startRE = options.paragraphStart || cm.getHelper(pos, "paragraphStart"); 18 | for (var start = pos.line, first = cm.firstLine(); start > first; --start) { 19 | var line = cm.getLine(start); 20 | if (startRE && startRE.test(line)) break; 21 | if (!/\S/.test(line)) { ++start; break; } 22 | } 23 | var endRE = options.paragraphEnd || cm.getHelper(pos, "paragraphEnd"); 24 | for (var end = pos.line + 1, last = cm.lastLine(); end <= last; ++end) { 25 | var line = cm.getLine(end); 26 | if (endRE && endRE.test(line)) { ++end; break; } 27 | if (!/\S/.test(line)) break; 28 | } 29 | return {from: start, to: end}; 30 | } 31 | 32 | function findBreakPoint(text, column, wrapOn, killTrailingSpace) { 33 | var at = column 34 | while (at < text.length && text.charAt(at) == " ") at++ 35 | for (; at > 0; --at) 36 | if (wrapOn.test(text.slice(at - 1, at + 1))) break; 37 | for (var first = true;; first = false) { 38 | var endOfText = at; 39 | if (killTrailingSpace) 40 | while (text.charAt(endOfText - 1) == " ") --endOfText; 41 | if (endOfText == 0 && first) at = column; 42 | else return {from: endOfText, to: at}; 43 | } 44 | } 45 | 46 | function wrapRange(cm, from, to, options) { 47 | from = cm.clipPos(from); to = cm.clipPos(to); 48 | var column = options.column || 80; 49 | var wrapOn = options.wrapOn || /\s\S|-[^\.\d]/; 50 | var killTrailing = options.killTrailingSpace !== false; 51 | var changes = [], curLine = "", curNo = from.line; 52 | var lines = cm.getRange(from, to, false); 53 | if (!lines.length) return null; 54 | var leadingSpace = lines[0].match(/^[ \t]*/)[0]; 55 | if (leadingSpace.length >= column) column = leadingSpace.length + 1 56 | 57 | for (var i = 0; i < lines.length; ++i) { 58 | var text = lines[i], oldLen = curLine.length, spaceInserted = 0; 59 | if (curLine && text && !wrapOn.test(curLine.charAt(curLine.length - 1) + text.charAt(0))) { 60 | curLine += " "; 61 | spaceInserted = 1; 62 | } 63 | var spaceTrimmed = ""; 64 | if (i) { 65 | spaceTrimmed = text.match(/^\s*/)[0]; 66 | text = text.slice(spaceTrimmed.length); 67 | } 68 | curLine += text; 69 | if (i) { 70 | var firstBreak = curLine.length > column && leadingSpace == spaceTrimmed && 71 | findBreakPoint(curLine, column, wrapOn, killTrailing); 72 | // If this isn't broken, or is broken at a different point, remove old break 73 | if (!firstBreak || firstBreak.from != oldLen || firstBreak.to != oldLen + spaceInserted) { 74 | changes.push({text: [spaceInserted ? " " : ""], 75 | from: Pos(curNo, oldLen), 76 | to: Pos(curNo + 1, spaceTrimmed.length)}); 77 | } else { 78 | curLine = leadingSpace + text; 79 | ++curNo; 80 | } 81 | } 82 | while (curLine.length > column) { 83 | var bp = findBreakPoint(curLine, column, wrapOn, killTrailing); 84 | changes.push({text: ["", leadingSpace], 85 | from: Pos(curNo, bp.from), 86 | to: Pos(curNo, bp.to)}); 87 | curLine = leadingSpace + curLine.slice(bp.to); 88 | ++curNo; 89 | } 90 | } 91 | if (changes.length) cm.operation(function() { 92 | for (var i = 0; i < changes.length; ++i) { 93 | var change = changes[i]; 94 | if (change.text || CodeMirror.cmpPos(change.from, change.to)) 95 | cm.replaceRange(change.text, change.from, change.to); 96 | } 97 | }); 98 | return changes.length ? {from: changes[0].from, to: CodeMirror.changeEnd(changes[changes.length - 1])} : null; 99 | } 100 | 101 | CodeMirror.defineExtension("wrapParagraph", function(pos, options) { 102 | options = options || {}; 103 | if (!pos) pos = this.getCursor(); 104 | var para = findParagraph(this, pos, options); 105 | return wrapRange(this, Pos(para.from, 0), Pos(para.to - 1), options); 106 | }); 107 | 108 | CodeMirror.commands.wrapLines = function(cm) { 109 | cm.operation(function() { 110 | var ranges = cm.listSelections(), at = cm.lastLine() + 1; 111 | for (var i = ranges.length - 1; i >= 0; i--) { 112 | var range = ranges[i], span; 113 | if (range.empty()) { 114 | var para = findParagraph(cm, range.head, {}); 115 | span = {from: Pos(para.from, 0), to: Pos(para.to - 1)}; 116 | } else { 117 | span = {from: range.from(), to: range.to()}; 118 | } 119 | if (span.to.line >= at) continue; 120 | at = span.from.line; 121 | wrapRange(cm, span.from, span.to, {}); 122 | } 123 | }); 124 | }; 125 | 126 | CodeMirror.defineExtension("wrapRange", function(from, to, options) { 127 | return wrapRange(this, from, to, options || {}); 128 | }); 129 | 130 | CodeMirror.defineExtension("wrapParagraphsInRange", function(from, to, options) { 131 | options = options || {}; 132 | var cm = this, paras = []; 133 | for (var line = from.line; line <= to.line;) { 134 | var para = findParagraph(cm, Pos(line, 0), options); 135 | paras.push(para); 136 | line = para.to; 137 | } 138 | var madeChange = false; 139 | if (paras.length) cm.operation(function() { 140 | for (var i = paras.length - 1; i >= 0; --i) 141 | madeChange = madeChange || wrapRange(cm, Pos(paras[i].from, 0), Pos(paras[i].to - 1), options); 142 | }); 143 | return madeChange; 144 | }); 145 | }); 146 | -------------------------------------------------------------------------------- /codemirror/theme/base16-light.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Name: Base16 Default Light 4 | Author: Chris Kempson (http://chriskempson.com) 5 | 6 | CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror) 7 | Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) 8 | 9 | */ 10 | 11 | .cm-s-base16-light.CodeMirror { background: #f5f5f5; color: #202020; } 12 | .cm-s-base16-light div.CodeMirror-selected { background: #e0e0e0; } 13 | .cm-s-base16-light .CodeMirror-line::selection, .cm-s-base16-light .CodeMirror-line > span::selection, .cm-s-base16-light .CodeMirror-line > span > span::selection { background: #e0e0e0; } 14 | .cm-s-base16-light .CodeMirror-line::-moz-selection, .cm-s-base16-light .CodeMirror-line > span::-moz-selection, .cm-s-base16-light .CodeMirror-line > span > span::-moz-selection { background: #e0e0e0; } 15 | .cm-s-base16-light .CodeMirror-gutters { background: #f5f5f5; border-right: 0px; } 16 | .cm-s-base16-light .CodeMirror-guttermarker { color: #ac4142; } 17 | .cm-s-base16-light .CodeMirror-guttermarker-subtle { color: #b0b0b0; } 18 | .cm-s-base16-light .CodeMirror-linenumber { color: #b0b0b0; } 19 | .cm-s-base16-light .CodeMirror-cursor { border-left: 1px solid #505050; } 20 | 21 | .cm-s-base16-light span.cm-comment { color: #8f5536; } 22 | .cm-s-base16-light span.cm-atom { color: #aa759f; } 23 | .cm-s-base16-light span.cm-number { color: #aa759f; } 24 | 25 | .cm-s-base16-light span.cm-property, .cm-s-base16-light span.cm-attribute { color: #90a959; } 26 | .cm-s-base16-light span.cm-keyword { color: #ac4142; } 27 | .cm-s-base16-light span.cm-string { color: #f4bf75; } 28 | 29 | .cm-s-base16-light span.cm-variable { color: #90a959; } 30 | .cm-s-base16-light span.cm-variable-2 { color: #6a9fb5; } 31 | .cm-s-base16-light span.cm-def { color: #d28445; } 32 | .cm-s-base16-light span.cm-bracket { color: #202020; } 33 | .cm-s-base16-light span.cm-tag { color: #ac4142; } 34 | .cm-s-base16-light span.cm-link { color: #aa759f; } 35 | .cm-s-base16-light span.cm-error { background: #ac4142; color: #505050; } 36 | 37 | .cm-s-base16-light .CodeMirror-activeline-background { background: #DDDCDC; } 38 | .cm-s-base16-light .CodeMirror-matchingbracket { color: #f5f5f5 !important; background-color: #6A9FB5 !important} 39 | -------------------------------------------------------------------------------- /codemirror/theme/duotone-light.css: -------------------------------------------------------------------------------- 1 | /* 2 | Name: DuoTone-Light 3 | Author: by Bram de Haan, adapted from DuoTone themes by Simurai (http://simurai.com/projects/2016/01/01/duotone-themes) 4 | 5 | CodeMirror template by Jan T. Sott (https://github.com/idleberg), adapted by Bram de Haan (https://github.com/atelierbram/) 6 | */ 7 | 8 | .cm-s-duotone-light.CodeMirror { background: #faf8f5; color: #b29762; } 9 | .cm-s-duotone-light div.CodeMirror-selected { background: #e3dcce !important; } 10 | .cm-s-duotone-light .CodeMirror-gutters { background: #faf8f5; border-right: 0px; } 11 | .cm-s-duotone-light .CodeMirror-linenumber { color: #cdc4b1; } 12 | 13 | /* begin cursor */ 14 | .cm-s-duotone-light .CodeMirror-cursor { border-left: 1px solid #93abdc; /* border-left: 1px solid #93abdc80; */ border-right: .5em solid #93abdc; /* border-right: .5em solid #93abdc80; */ opacity: .5; } 15 | .cm-s-duotone-light .CodeMirror-activeline-background { background: #e3dcce; /* background: #e3dcce80; */ opacity: .5; } 16 | .cm-s-duotone-light .cm-fat-cursor .CodeMirror-cursor { background: #93abdc; /* #93abdc80; */ opacity: .5; } 17 | /* end cursor */ 18 | 19 | .cm-s-duotone-light span.cm-atom, .cm-s-duotone-light span.cm-number, .cm-s-duotone-light span.cm-keyword, .cm-s-duotone-light span.cm-variable, .cm-s-duotone-light span.cm-attribute, .cm-s-duotone-light span.cm-quote, .cm-s-duotone-light-light span.cm-hr, .cm-s-duotone-light-light span.cm-link { color: #063289; } 20 | 21 | .cm-s-duotone-light span.cm-property { color: #b29762; } 22 | .cm-s-duotone-light span.cm-punctuation, .cm-s-duotone-light span.cm-unit, .cm-s-duotone-light span.cm-negative { color: #063289; } 23 | .cm-s-duotone-light span.cm-string, .cm-s-duotone-light span.cm-operator { color: #1659df; } 24 | .cm-s-duotone-light span.cm-positive { color: #896724; } 25 | 26 | .cm-s-duotone-light span.cm-variable-2, .cm-s-duotone-light span.cm-variable-3, .cm-s-duotone-light span.cm-type, .cm-s-duotone-light span.cm-string-2, .cm-s-duotone-light span.cm-url { color: #896724; } 27 | .cm-s-duotone-light span.cm-def, .cm-s-duotone-light span.cm-tag, .cm-s-duotone-light span.cm-builtin, .cm-s-duotone-light span.cm-qualifier, .cm-s-duotone-light span.cm-header, .cm-s-duotone-light span.cm-em { color: #2d2006; } 28 | .cm-s-duotone-light span.cm-bracket, .cm-s-duotone-light span.cm-comment { color: #b6ad9a; } 29 | 30 | /* using #f00 red for errors, don't think any of the colorscheme variables will stand out enough, ... maybe by giving it a background-color ... */ 31 | /* .cm-s-duotone-light span.cm-error { background: #896724; color: #728fcb; } */ 32 | .cm-s-duotone-light span.cm-error, .cm-s-duotone-light span.cm-invalidchar { color: #f00; } 33 | 34 | .cm-s-duotone-light span.cm-header { font-weight: normal; } 35 | .cm-s-duotone-light .CodeMirror-matchingbracket { text-decoration: underline; color: #faf8f5 !important; } 36 | 37 | -------------------------------------------------------------------------------- /codemirror/theme/monokai.css: -------------------------------------------------------------------------------- 1 | /* Based on Sublime Text's Monokai theme */ 2 | 3 | .cm-s-monokai.CodeMirror { background: #272822; color: #f8f8f2; } 4 | .cm-s-monokai div.CodeMirror-selected { background: #49483E; } 5 | .cm-s-monokai .CodeMirror-line::selection, .cm-s-monokai .CodeMirror-line > span::selection, .cm-s-monokai .CodeMirror-line > span > span::selection { background: rgba(73, 72, 62, .99); } 6 | .cm-s-monokai .CodeMirror-line::-moz-selection, .cm-s-monokai .CodeMirror-line > span::-moz-selection, .cm-s-monokai .CodeMirror-line > span > span::-moz-selection { background: rgba(73, 72, 62, .99); } 7 | .cm-s-monokai .CodeMirror-gutters { background: #272822; border-right: 0px; } 8 | .cm-s-monokai .CodeMirror-guttermarker { color: white; } 9 | .cm-s-monokai .CodeMirror-guttermarker-subtle { color: #d0d0d0; } 10 | .cm-s-monokai .CodeMirror-linenumber { color: rgba(255,255,255,0.4); } 11 | .cm-s-monokai .CodeMirror-cursor { border-left: 1px solid #f8f8f0; } 12 | 13 | .cm-s-monokai span.cm-comment { color: #75715e; } 14 | .cm-s-monokai span.cm-atom { color: #ae81ff; } 15 | .cm-s-monokai span.cm-number { color: #ae81ff; } 16 | 17 | .cm-s-monokai span.cm-comment.cm-attribute { color: #97b757; } 18 | .cm-s-monokai span.cm-comment.cm-def { color: #bc9262; } 19 | .cm-s-monokai span.cm-comment.cm-tag { color: #bc6283; } 20 | .cm-s-monokai span.cm-comment.cm-type { color: #5998a6; } 21 | 22 | .cm-s-monokai span.cm-property, .cm-s-monokai span.cm-attribute { color: #a6e22e; } 23 | .cm-s-monokai span.cm-keyword { color: #f92672; } 24 | .cm-s-monokai span.cm-builtin { color: #66d9ef; } 25 | .cm-s-monokai span.cm-string { color: #e6db74; } 26 | 27 | .cm-s-monokai span.cm-variable { color: #f8f8f2; } 28 | .cm-s-monokai span.cm-variable-2 { color: #9effff; } 29 | .cm-s-monokai span.cm-variable-3, .cm-s-monokai span.cm-type { color: #66d9ef; } 30 | .cm-s-monokai span.cm-def { color: #fd971f; } 31 | .cm-s-monokai span.cm-bracket { color: #f8f8f2; } 32 | .cm-s-monokai span.cm-tag { color: #f92672; } 33 | .cm-s-monokai span.cm-header { color: #ae81ff; } 34 | .cm-s-monokai span.cm-link { color: #ae81ff; } 35 | .cm-s-monokai span.cm-error { background: #f92672; color: #f8f8f0; } 36 | 37 | .cm-s-monokai .CodeMirror-activeline-background { background: #373831; } 38 | .cm-s-monokai .CodeMirror-matchingbracket { 39 | text-decoration: underline; 40 | color: white !important; 41 | } 42 | -------------------------------------------------------------------------------- /favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanyf/wechat-format/4885331f60a8a4bf43eb95eea52cbe7eca2d2b67/favicon.png -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 微信公众号格式化编辑器 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
    20 | 21 | 22 | 23 | 24 | 25 | 26 | 28 | 29 | 30 | 31 | 32 | 33 | 37 | {{ font.label }} 38 | Abc 39 | 40 | 41 | 42 | 43 | 44 | 48 | {{ size.label }} 49 | {{ size.desc }} 50 | 51 | 52 | 53 | 54 | 55 | 56 | {{ theme.label }} 57 | {{ theme.author }} 58 | 59 | 60 | 61 | 62 | 关于 63 | 64 | 65 | 66 | 67 | 73 | 74 | 75 |
    76 |
    全选复制或点此复制,然后在公众号编辑器粘贴
    77 |
    78 |
    79 |
    80 |
    81 |
    82 |
    83 |
    84 |
    85 |
    86 | 87 | 88 |
    89 |

    WeChat Format 有什么用?

    90 |

    能较好地排版;

    91 |

    能解决 ulol 渲染时样式被微信编辑器重置的问题;

    92 |

    能把外部链接自动转为参考文献索引,并且附在文章末尾

    93 |

     

    94 |

    关于我

    95 |

    我是 Lyric。如果你喜欢我的工具,可以:

    96 |

    关注我的公众号 "iamlyricw",博客Github

    97 |

    98 | 微信打赏我: 99 | 100 |

    101 |
    102 | 103 | 打赏了! 104 | 105 |
    106 |
    107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 129 | 130 | --------------------------------------------------------------------------------