mirror of
https://github.com/doocs/md.git
synced 2024-10-30 15:57:50 +08:00
feat: remove jquery/pretty
This commit is contained in:
parent
6ebee5b7f3
commit
c063606349
224
index.html
224
index.html
@ -1,224 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<!--
|
|
||||||
_.._ ,------------.
|
|
||||||
,' `. ( 你终于发现我啦 )
|
|
||||||
/ __) __` \ `-,----------'
|
|
||||||
( (`-`(-') ) _.-'
|
|
||||||
/) \ = / (
|
|
||||||
/' |--' . \
|
|
||||||
( ,---| `-.)__`
|
|
||||||
)( `-.,--' _`-.
|
|
||||||
'/,' ( Uu",
|
|
||||||
(_ , `/,-' )
|
|
||||||
`.__, : `-'/ /`--'
|
|
||||||
| `--' |
|
|
||||||
` `-._ /
|
|
||||||
\ (
|
|
||||||
/\ . \.
|
|
||||||
/ |` \ ,-\
|
|
||||||
/ \| .) / \
|
|
||||||
( ,'|\ ,' :
|
|
||||||
| \,`.`--"/ }
|
|
||||||
`,' \ |,' /
|
|
||||||
/ "-._ `-/ |
|
|
||||||
"-. "-.,'| ;
|
|
||||||
/ _/["---'""]
|
|
||||||
: / |"- '
|
|
||||||
' | /
|
|
||||||
` |
|
|
||||||
-->
|
|
||||||
<html lang="en">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
|
||||||
<meta name="keywords" content="md,markdown,markdown-editor,wechat,official-account,yanglbme,doocs">
|
|
||||||
<meta name="description" content="Wechat Markdown Editor | 一款高度简洁的微信 Markdown 编辑器">
|
|
||||||
<meta name="viewport"
|
|
||||||
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
|
||||||
<title>微信 Markdown 编辑器</title>
|
|
||||||
<link rel="shortcut icon" href="assets/images/favicon.png">
|
|
||||||
<link rel="apple-touch-icon-precomposed" href="assets/images/favicon.png">
|
|
||||||
<link rel="stylesheet" href="assets/css/loading.css">
|
|
||||||
<link rel="stylesheet" href="libs/css/index.css">
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="libs/css/xq-light.min.css">
|
|
||||||
<link rel="stylesheet" href="libs/css/code-themes/github-v2.min.css">
|
|
||||||
|
|
||||||
<!-- codemirror -->
|
|
||||||
<link rel="stylesheet" href="libs/css/codemirror.min.css">
|
|
||||||
<link rel="stylesheet" href="libs/css/show-hint.css">
|
|
||||||
<link rel="stylesheet" href="libs/css/style-mirror.css">
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="libs/css/animate.css">
|
|
||||||
<link rel="stylesheet" href="assets/css/app.css">
|
|
||||||
|
|
||||||
<!-- 默认CSS/JS -->
|
|
||||||
<script src="assets/scripts/themes/default-theme-css.js"></script>
|
|
||||||
<script src="assets/scripts/default-content.js"></script>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<!--loading 界面-->
|
|
||||||
<div class="loading" id="loading">
|
|
||||||
<div class="loading-wrapper">
|
|
||||||
<div class="loading-text">Loading...</div>
|
|
||||||
<div class="loading-anim"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!--应用主体-->
|
|
||||||
<div id="app" class="container">
|
|
||||||
<el-container>
|
|
||||||
<el-header class="top">
|
|
||||||
<!-- 图片上传 -->
|
|
||||||
<el-upload action="https://imgkr.com/api/files/upload" headers="{'Content-Type': 'multipart/form-data'}"
|
|
||||||
:show-file-list="false" :multiple="true" accept=".jpg,.jpeg,.png,.gif" name="file"
|
|
||||||
:before-upload="beforeUpload" :on-success="uploaded">
|
|
||||||
<el-tooltip class="item" effect="dark" content="上传图片" placement="bottom-start">
|
|
||||||
<i class="el-icon-upload" size="medium"> </i>
|
|
||||||
</el-tooltip>
|
|
||||||
</el-upload>
|
|
||||||
<!-- 下载文本文档 -->
|
|
||||||
<el-tooltip class="item" effect="dark" content="下载编辑框Markdown文档" placement="bottom-start">
|
|
||||||
<i class="el-icon-download" size="medium" @click="downloadEditorContent"> </i>
|
|
||||||
</el-tooltip>
|
|
||||||
<!-- 页面重置 -->
|
|
||||||
<el-tooltip class="item" effect="dark" content="重置页面" placement="bottom-start">
|
|
||||||
<i class="el-icon-refresh" size="medium" @click="reset"> </i>
|
|
||||||
</el-tooltip>
|
|
||||||
<!-- 插入表格 -->
|
|
||||||
<el-tooltip class="item" effect="dark" content="插入表格" placement="bottom-start">
|
|
||||||
<i class="el-icon-s-grid" size="medium" @click="dialogFormVisible = true"> </i>
|
|
||||||
</el-tooltip>
|
|
||||||
<el-form size="mini" class="ctrl" :inline=true>
|
|
||||||
<el-form-item>
|
|
||||||
<el-select v-model="currentFont" size="mini" placeholder="选择字体" clearable @change="fontChanged">
|
|
||||||
<el-option v-for="font in builtinFonts" :style="{fontFamily: font.value}" :key="font.value"
|
|
||||||
:label="font.label" :value="font.value">
|
|
||||||
<span class="select-item-left">{{ font.label }}</span>
|
|
||||||
<span class="select-item-right">Abc</span>
|
|
||||||
</el-option>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<el-select v-model="currentSize" size="mini" placeholder="选择段落字号" clearable @change="sizeChanged">
|
|
||||||
<el-option v-for="size in sizeOption" :key="size.value" :label="size.label" :value="size.value">
|
|
||||||
<span class="select-item-left">{{ size.label }}</span>
|
|
||||||
<span class="select-item-right">{{ size.desc }}</span>
|
|
||||||
</el-option>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<el-select v-model="currentColor" size="mini" placeholder="选择颜色" clearable @change="colorChanged">
|
|
||||||
<el-option v-for="color in colorOption" :key="color.value" :label="color.label" :value="color.value">
|
|
||||||
<span class="select-item-left">{{ color.label }}</span>
|
|
||||||
<span class="select-item-right">{{ color.hex }}</span>
|
|
||||||
</el-option>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-tooltip content="自定义颜色" placement="top">
|
|
||||||
<el-color-picker v-model="currentColor" size="mini" show-alpha @change="colorChanged"></el-color-picker>
|
|
||||||
</el-tooltip>
|
|
||||||
|
|
||||||
<el-tooltip content="微信外链自动转为文末引用" placement="top">
|
|
||||||
<el-switch v-model="status" active-color="#67c23a" inactive-color="#dcdfe6" @change="statusChanged">
|
|
||||||
</el-switch>
|
|
||||||
</el-tooltip>
|
|
||||||
</el-form>
|
|
||||||
<el-tooltip class="item" effect="dark" content="自定义CSS样式" placement="left">
|
|
||||||
<el-button type="success" plain size="medium" icon="el-icon-setting" @click="customStyle"></el-button>
|
|
||||||
</el-tooltip>
|
|
||||||
<el-button type="success" plain size="medium" @click="copy">复制</el-button>
|
|
||||||
<el-button type="success" plain size="medium" class="about" @click="aboutDialogVisible = true">关于</el-button>
|
|
||||||
</el-header>
|
|
||||||
<el-main class="main-body">
|
|
||||||
<el-row :gutter="10" class="main-section">
|
|
||||||
<el-col :span="12">
|
|
||||||
<textarea id="editor" type="textarea" placeholder="Your markdown text here." v-model="source">
|
|
||||||
</textarea>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12" class="preview-wrapper" id="preview">
|
|
||||||
<section>
|
|
||||||
<div class="preview" contenteditable="true">
|
|
||||||
<section id="output" v-html="output">
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</el-col>
|
|
||||||
<transition name="custom-classes-transition" enter-active-class="animated bounceInRight">
|
|
||||||
<el-col id="cssBox" :span="12" v-show="showBox">
|
|
||||||
<textarea id="cssEditor" type="textarea" placeholder="Your custom css here.">
|
|
||||||
</textarea>
|
|
||||||
</el-col>
|
|
||||||
</transition>
|
|
||||||
|
|
||||||
</el-row>
|
|
||||||
</el-main>
|
|
||||||
</el-container>
|
|
||||||
<el-dialog title="关于" :visible.sync="aboutDialogVisible" width="30%" center>
|
|
||||||
<div style="text-align: center;">
|
|
||||||
<h3>一款高度简洁的微信 Markdown 编辑器</h3>
|
|
||||||
</div>
|
|
||||||
<div style="text-align: center;margin-top:10px;">
|
|
||||||
<p>扫码关注我的公众号,原创技术文章第一时间推送!</p>
|
|
||||||
<img src="assets/images/qrcode-for-doocs.jpg" style="width: 40%; display: block; margin: 20px auto 10px;">
|
|
||||||
</div>
|
|
||||||
<span slot="footer" class="dialog-footer">
|
|
||||||
<a href="https://github.com/doocs/md" target="_blank">
|
|
||||||
<el-button type="success" plain>GitHub 仓库</el-button>
|
|
||||||
</a>
|
|
||||||
<a href="https://gitee.com/doocs/md" target="_blank">
|
|
||||||
<el-button type="success" plain>Gitee 仓库</el-button>
|
|
||||||
</a>
|
|
||||||
</span>
|
|
||||||
</el-dialog>
|
|
||||||
<el-dialog title="插入表格" :visible.sync="dialogFormVisible">
|
|
||||||
<el-form :model="form">
|
|
||||||
<el-form-item label="行数(表头不计入行数)">
|
|
||||||
<el-input v-model="form.rows"></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="列数">
|
|
||||||
<el-input v-model="form.cols"></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
<div slot="footer" class="dialog-footer">
|
|
||||||
<el-button type="success" plain @click="dialogFormVisible = false">取 消</el-button>
|
|
||||||
<el-button type="success" @click="insertTable">确 定</el-button>
|
|
||||||
</div>
|
|
||||||
</el-dialog>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script src="libs/scripts/vue.min.js"></script>
|
|
||||||
<script src="libs/scripts/axios.min.js"></script>
|
|
||||||
<script src="libs/scripts/marked.min.js"></script>
|
|
||||||
|
|
||||||
<!-- codemirror -->
|
|
||||||
<script src="libs/scripts/codemirror/codemirror.min.js"></script>
|
|
||||||
<script src="libs/scripts/codemirror/css.js"></script>
|
|
||||||
<script src="libs/scripts/codemirror/matchbrackets.js"></script>
|
|
||||||
<script src="libs/scripts/codemirror/active-line.js"></script>
|
|
||||||
<script src="libs/scripts/codemirror/show-hint.js"></script>
|
|
||||||
<script src="libs/scripts/codemirror/css-hint.js"></script>
|
|
||||||
<script src="libs/scripts/codemirror/format.js"></script>
|
|
||||||
|
|
||||||
<script src="libs/scripts/markdown.min.js"></script>
|
|
||||||
<script src="libs/scripts/prettify.min.js"></script>
|
|
||||||
<script src="libs/scripts/index.js"></script>
|
|
||||||
<script src="libs/scripts/jquery.min.js"></script>
|
|
||||||
<script src="libs/scripts/closebrackets.js"></script>
|
|
||||||
|
|
||||||
<script src="assets/scripts/sync-scroll.js"></script>
|
|
||||||
<script src="assets/scripts/themes/default-theme.js"></script>
|
|
||||||
<script src="assets/scripts/renderers/wx-renderer.js"></script>
|
|
||||||
<script src="assets/scripts/util.js"></script>
|
|
||||||
<script src="assets/scripts/editor.js"></script>
|
|
||||||
<script>
|
|
||||||
$('#loading').hide();
|
|
||||||
window.console
|
|
||||||
&& window.console.log
|
|
||||||
&& (console.log("Think big, train fast, learn deep. See https://github.com/yanglbme"))
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
@ -12,6 +12,8 @@
|
|||||||
"axios": "^0.19.1",
|
"axios": "^0.19.1",
|
||||||
"codemirror": "^5.50.2",
|
"codemirror": "^5.50.2",
|
||||||
"core-js": "^3.4.4",
|
"core-js": "^3.4.4",
|
||||||
|
"element-ui": "^2.13.0",
|
||||||
|
"jquery": "^3.4.1",
|
||||||
"markdown": "^0.5.0",
|
"markdown": "^0.5.0",
|
||||||
"marked": "^0.8.0",
|
"marked": "^0.8.0",
|
||||||
"prettify": "^0.1.7",
|
"prettify": "^0.1.7",
|
||||||
|
@ -1,4 +0,0 @@
|
|||||||
// 左右栏同步滚动
|
|
||||||
$(document).ready(() => {
|
|
||||||
|
|
||||||
})
|
|
@ -49,20 +49,7 @@
|
|||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div id="app" >
|
<div id="app" >
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<script src="libs/scripts/prettify.min.js"></script>
|
|
||||||
<script src="libs/scripts/jquery.min.js"></script>
|
|
||||||
<script>
|
|
||||||
window.console
|
|
||||||
&& window.console.log
|
|
||||||
&& (console.log("Think big, train fast, learn deep. See https://github.com/yanglbme"))
|
|
||||||
setTimeout(() => {
|
|
||||||
document.body.addEventListener('load', prettyPrint())
|
|
||||||
}, 2000)
|
|
||||||
</script>
|
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
9
public/libs/scripts/axios.min.js
vendored
9
public/libs/scripts/axios.min.js
vendored
File diff suppressed because one or more lines are too long
@ -1,191 +0,0 @@
|
|||||||
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
|
||||||
// Distributed under an MIT license: https://codemirror.net/LICENSE
|
|
||||||
|
|
||||||
(function(mod) {
|
|
||||||
if (typeof exports == "object" && typeof module == "object") // CommonJS
|
|
||||||
mod(require("../../lib/codemirror"));
|
|
||||||
else if (typeof define == "function" && define.amd) // AMD
|
|
||||||
define(["../../lib/codemirror"], mod);
|
|
||||||
else // Plain browser env
|
|
||||||
mod(CodeMirror);
|
|
||||||
})(function(CodeMirror) {
|
|
||||||
var defaults = {
|
|
||||||
pairs: "()[]{}''\"\"",
|
|
||||||
closeBefore: ")]}'\":;>",
|
|
||||||
triples: "",
|
|
||||||
explode: "[]{}"
|
|
||||||
};
|
|
||||||
|
|
||||||
var Pos = CodeMirror.Pos;
|
|
||||||
|
|
||||||
CodeMirror.defineOption("autoCloseBrackets", false, function(cm, val, old) {
|
|
||||||
if (old && old != CodeMirror.Init) {
|
|
||||||
cm.removeKeyMap(keyMap);
|
|
||||||
cm.state.closeBrackets = null;
|
|
||||||
}
|
|
||||||
if (val) {
|
|
||||||
ensureBound(getOption(val, "pairs"))
|
|
||||||
cm.state.closeBrackets = val;
|
|
||||||
cm.addKeyMap(keyMap);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
function getOption(conf, name) {
|
|
||||||
if (name == "pairs" && typeof conf == "string") return conf;
|
|
||||||
if (typeof conf == "object" && conf[name] != null) return conf[name];
|
|
||||||
return defaults[name];
|
|
||||||
}
|
|
||||||
|
|
||||||
var keyMap = {Backspace: handleBackspace, Enter: handleEnter};
|
|
||||||
function ensureBound(chars) {
|
|
||||||
for (var i = 0; i < chars.length; i++) {
|
|
||||||
var ch = chars.charAt(i), key = "'" + ch + "'"
|
|
||||||
if (!keyMap[key]) keyMap[key] = handler(ch)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ensureBound(defaults.pairs + "`")
|
|
||||||
|
|
||||||
function handler(ch) {
|
|
||||||
return function(cm) { return handleChar(cm, ch); };
|
|
||||||
}
|
|
||||||
|
|
||||||
function getConfig(cm) {
|
|
||||||
var deflt = cm.state.closeBrackets;
|
|
||||||
if (!deflt || deflt.override) return deflt;
|
|
||||||
var mode = cm.getModeAt(cm.getCursor());
|
|
||||||
return mode.closeBrackets || deflt;
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleBackspace(cm) {
|
|
||||||
var conf = getConfig(cm);
|
|
||||||
if (!conf || cm.getOption("disableInput")) return CodeMirror.Pass;
|
|
||||||
|
|
||||||
var pairs = getOption(conf, "pairs");
|
|
||||||
var ranges = cm.listSelections();
|
|
||||||
for (var i = 0; i < ranges.length; i++) {
|
|
||||||
if (!ranges[i].empty()) return CodeMirror.Pass;
|
|
||||||
var around = charsAround(cm, ranges[i].head);
|
|
||||||
if (!around || pairs.indexOf(around) % 2 != 0) return CodeMirror.Pass;
|
|
||||||
}
|
|
||||||
for (var i = ranges.length - 1; i >= 0; i--) {
|
|
||||||
var cur = ranges[i].head;
|
|
||||||
cm.replaceRange("", Pos(cur.line, cur.ch - 1), Pos(cur.line, cur.ch + 1), "+delete");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleEnter(cm) {
|
|
||||||
var conf = getConfig(cm);
|
|
||||||
var explode = conf && getOption(conf, "explode");
|
|
||||||
if (!explode || cm.getOption("disableInput")) return CodeMirror.Pass;
|
|
||||||
|
|
||||||
var ranges = cm.listSelections();
|
|
||||||
for (var i = 0; i < ranges.length; i++) {
|
|
||||||
if (!ranges[i].empty()) return CodeMirror.Pass;
|
|
||||||
var around = charsAround(cm, ranges[i].head);
|
|
||||||
if (!around || explode.indexOf(around) % 2 != 0) return CodeMirror.Pass;
|
|
||||||
}
|
|
||||||
cm.operation(function() {
|
|
||||||
var linesep = cm.lineSeparator() || "\n";
|
|
||||||
cm.replaceSelection(linesep + linesep, null);
|
|
||||||
cm.execCommand("goCharLeft");
|
|
||||||
ranges = cm.listSelections();
|
|
||||||
for (var i = 0; i < ranges.length; i++) {
|
|
||||||
var line = ranges[i].head.line;
|
|
||||||
cm.indentLine(line, null, true);
|
|
||||||
cm.indentLine(line + 1, null, true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function contractSelection(sel) {
|
|
||||||
var inverted = CodeMirror.cmpPos(sel.anchor, sel.head) > 0;
|
|
||||||
return {anchor: new Pos(sel.anchor.line, sel.anchor.ch + (inverted ? -1 : 1)),
|
|
||||||
head: new Pos(sel.head.line, sel.head.ch + (inverted ? 1 : -1))};
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleChar(cm, ch) {
|
|
||||||
var conf = getConfig(cm);
|
|
||||||
if (!conf || cm.getOption("disableInput")) return CodeMirror.Pass;
|
|
||||||
|
|
||||||
var pairs = getOption(conf, "pairs");
|
|
||||||
var pos = pairs.indexOf(ch);
|
|
||||||
if (pos == -1) return CodeMirror.Pass;
|
|
||||||
|
|
||||||
var closeBefore = getOption(conf,"closeBefore");
|
|
||||||
|
|
||||||
var triples = getOption(conf, "triples");
|
|
||||||
|
|
||||||
var identical = pairs.charAt(pos + 1) == ch;
|
|
||||||
var ranges = cm.listSelections();
|
|
||||||
var opening = pos % 2 == 0;
|
|
||||||
|
|
||||||
var type;
|
|
||||||
for (var i = 0; i < ranges.length; i++) {
|
|
||||||
var range = ranges[i], cur = range.head, curType;
|
|
||||||
var next = cm.getRange(cur, Pos(cur.line, cur.ch + 1));
|
|
||||||
if (opening && !range.empty()) {
|
|
||||||
curType = "surround";
|
|
||||||
} else if ((identical || !opening) && next == ch) {
|
|
||||||
if (identical && stringStartsAfter(cm, cur))
|
|
||||||
curType = "both";
|
|
||||||
else if (triples.indexOf(ch) >= 0 && cm.getRange(cur, Pos(cur.line, cur.ch + 3)) == ch + ch + ch)
|
|
||||||
curType = "skipThree";
|
|
||||||
else
|
|
||||||
curType = "skip";
|
|
||||||
} else if (identical && cur.ch > 1 && triples.indexOf(ch) >= 0 &&
|
|
||||||
cm.getRange(Pos(cur.line, cur.ch - 2), cur) == ch + ch) {
|
|
||||||
if (cur.ch > 2 && /\bstring/.test(cm.getTokenTypeAt(Pos(cur.line, cur.ch - 2)))) return CodeMirror.Pass;
|
|
||||||
curType = "addFour";
|
|
||||||
} else if (identical) {
|
|
||||||
var prev = cur.ch == 0 ? " " : cm.getRange(Pos(cur.line, cur.ch - 1), cur)
|
|
||||||
if (!CodeMirror.isWordChar(next) && prev != ch && !CodeMirror.isWordChar(prev)) curType = "both";
|
|
||||||
else return CodeMirror.Pass;
|
|
||||||
} else if (opening && (next.length === 0 || /\s/.test(next) || closeBefore.indexOf(next) > -1)) {
|
|
||||||
curType = "both";
|
|
||||||
} else {
|
|
||||||
return CodeMirror.Pass;
|
|
||||||
}
|
|
||||||
if (!type) type = curType;
|
|
||||||
else if (type != curType) return CodeMirror.Pass;
|
|
||||||
}
|
|
||||||
|
|
||||||
var left = pos % 2 ? pairs.charAt(pos - 1) : ch;
|
|
||||||
var right = pos % 2 ? ch : pairs.charAt(pos + 1);
|
|
||||||
cm.operation(function() {
|
|
||||||
if (type == "skip") {
|
|
||||||
cm.execCommand("goCharRight");
|
|
||||||
} else if (type == "skipThree") {
|
|
||||||
for (var i = 0; i < 3; i++)
|
|
||||||
cm.execCommand("goCharRight");
|
|
||||||
} else if (type == "surround") {
|
|
||||||
var sels = cm.getSelections();
|
|
||||||
for (var i = 0; i < sels.length; i++)
|
|
||||||
sels[i] = left + sels[i] + right;
|
|
||||||
cm.replaceSelections(sels, "around");
|
|
||||||
sels = cm.listSelections().slice();
|
|
||||||
for (var i = 0; i < sels.length; i++)
|
|
||||||
sels[i] = contractSelection(sels[i]);
|
|
||||||
cm.setSelections(sels);
|
|
||||||
} else if (type == "both") {
|
|
||||||
cm.replaceSelection(left + right, null);
|
|
||||||
cm.triggerElectric(left + right);
|
|
||||||
cm.execCommand("goCharLeft");
|
|
||||||
} else if (type == "addFour") {
|
|
||||||
cm.replaceSelection(left + left + left + left, "before");
|
|
||||||
cm.execCommand("goCharRight");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function charsAround(cm, pos) {
|
|
||||||
var str = cm.getRange(Pos(pos.line, pos.ch - 1),
|
|
||||||
Pos(pos.line, pos.ch + 1));
|
|
||||||
return str.length == 2 ? str : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function stringStartsAfter(cm, pos) {
|
|
||||||
var token = cm.getTokenAt(Pos(pos.line, pos.ch + 1))
|
|
||||||
return /\bstring/.test(token.type) && token.start == pos.ch &&
|
|
||||||
(pos.ch == 0 || !/\bstring/.test(cm.getTokenTypeAt(pos)))
|
|
||||||
}
|
|
||||||
});
|
|
@ -1,72 +0,0 @@
|
|||||||
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
|
||||||
// Distributed under an MIT license: https://codemirror.net/LICENSE
|
|
||||||
|
|
||||||
(function(mod) {
|
|
||||||
if (typeof exports == "object" && typeof module == "object") // CommonJS
|
|
||||||
mod(require("../../lib/codemirror"));
|
|
||||||
else if (typeof define == "function" && define.amd) // AMD
|
|
||||||
define(["../../lib/codemirror"], mod);
|
|
||||||
else // Plain browser env
|
|
||||||
mod(CodeMirror);
|
|
||||||
})(function(CodeMirror) {
|
|
||||||
"use strict";
|
|
||||||
var WRAP_CLASS = "CodeMirror-activeline";
|
|
||||||
var BACK_CLASS = "CodeMirror-activeline-background";
|
|
||||||
var GUTT_CLASS = "CodeMirror-activeline-gutter";
|
|
||||||
|
|
||||||
CodeMirror.defineOption("styleActiveLine", false, function(cm, val, old) {
|
|
||||||
var prev = old == CodeMirror.Init ? false : old;
|
|
||||||
if (val == prev) return
|
|
||||||
if (prev) {
|
|
||||||
cm.off("beforeSelectionChange", selectionChange);
|
|
||||||
clearActiveLines(cm);
|
|
||||||
delete cm.state.activeLines;
|
|
||||||
}
|
|
||||||
if (val) {
|
|
||||||
cm.state.activeLines = [];
|
|
||||||
updateActiveLines(cm, cm.listSelections());
|
|
||||||
cm.on("beforeSelectionChange", selectionChange);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
function clearActiveLines(cm) {
|
|
||||||
for (var i = 0; i < cm.state.activeLines.length; i++) {
|
|
||||||
cm.removeLineClass(cm.state.activeLines[i], "wrap", WRAP_CLASS);
|
|
||||||
cm.removeLineClass(cm.state.activeLines[i], "background", BACK_CLASS);
|
|
||||||
cm.removeLineClass(cm.state.activeLines[i], "gutter", GUTT_CLASS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function sameArray(a, b) {
|
|
||||||
if (a.length != b.length) return false;
|
|
||||||
for (var i = 0; i < a.length; i++)
|
|
||||||
if (a[i] != b[i]) return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateActiveLines(cm, ranges) {
|
|
||||||
var active = [];
|
|
||||||
for (var i = 0; i < ranges.length; i++) {
|
|
||||||
var range = ranges[i];
|
|
||||||
var option = cm.getOption("styleActiveLine");
|
|
||||||
if (typeof option == "object" && option.nonEmpty ? range.anchor.line != range.head.line : !range.empty())
|
|
||||||
continue
|
|
||||||
var line = cm.getLineHandleVisualStart(range.head.line);
|
|
||||||
if (active[active.length - 1] != line) active.push(line);
|
|
||||||
}
|
|
||||||
if (sameArray(cm.state.activeLines, active)) return;
|
|
||||||
cm.operation(function() {
|
|
||||||
clearActiveLines(cm);
|
|
||||||
for (var i = 0; i < active.length; i++) {
|
|
||||||
cm.addLineClass(active[i], "wrap", WRAP_CLASS);
|
|
||||||
cm.addLineClass(active[i], "background", BACK_CLASS);
|
|
||||||
cm.addLineClass(active[i], "gutter", GUTT_CLASS);
|
|
||||||
}
|
|
||||||
cm.state.activeLines = active;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function selectionChange(cm, sel) {
|
|
||||||
updateActiveLines(cm, sel.ranges);
|
|
||||||
}
|
|
||||||
});
|
|
File diff suppressed because one or more lines are too long
@ -1,60 +0,0 @@
|
|||||||
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
|
||||||
// Distributed under an MIT license: https://codemirror.net/LICENSE
|
|
||||||
|
|
||||||
(function(mod) {
|
|
||||||
if (typeof exports == "object" && typeof module == "object") // CommonJS
|
|
||||||
mod(require("../../lib/codemirror"), require("../../mode/css/css"));
|
|
||||||
else if (typeof define == "function" && define.amd) // AMD
|
|
||||||
define(["../../lib/codemirror", "../../mode/css/css"], mod);
|
|
||||||
else // Plain browser env
|
|
||||||
mod(CodeMirror);
|
|
||||||
})(function(CodeMirror) {
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
var pseudoClasses = {link: 1, visited: 1, active: 1, hover: 1, focus: 1,
|
|
||||||
"first-letter": 1, "first-line": 1, "first-child": 1,
|
|
||||||
before: 1, after: 1, lang: 1};
|
|
||||||
|
|
||||||
CodeMirror.registerHelper("hint", "css", function(cm) {
|
|
||||||
var cur = cm.getCursor(), token = cm.getTokenAt(cur);
|
|
||||||
var inner = CodeMirror.innerMode(cm.getMode(), token.state);
|
|
||||||
if (inner.mode.name != "css") return;
|
|
||||||
|
|
||||||
if (token.type == "keyword" && "!important".indexOf(token.string) == 0)
|
|
||||||
return {list: ["!important"], from: CodeMirror.Pos(cur.line, token.start),
|
|
||||||
to: CodeMirror.Pos(cur.line, token.end)};
|
|
||||||
|
|
||||||
var start = token.start, end = cur.ch, word = token.string.slice(0, end - start);
|
|
||||||
if (/[^\w$_-]/.test(word)) {
|
|
||||||
word = ""; start = end = cur.ch;
|
|
||||||
}
|
|
||||||
|
|
||||||
var spec = CodeMirror.resolveMode("text/css");
|
|
||||||
|
|
||||||
var result = [];
|
|
||||||
function add(keywords) {
|
|
||||||
for (var name in keywords)
|
|
||||||
if (!word || name.lastIndexOf(word, 0) == 0)
|
|
||||||
result.push(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
var st = inner.state.state;
|
|
||||||
if (st == "pseudo" || token.type == "variable-3") {
|
|
||||||
add(pseudoClasses);
|
|
||||||
} else if (st == "block" || st == "maybeprop") {
|
|
||||||
add(spec.propertyKeywords);
|
|
||||||
} else if (st == "prop" || st == "parens" || st == "at" || st == "params") {
|
|
||||||
add(spec.valueKeywords);
|
|
||||||
add(spec.colorKeywords);
|
|
||||||
} else if (st == "media" || st == "media_parens") {
|
|
||||||
add(spec.mediaTypes);
|
|
||||||
add(spec.mediaFeatures);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result.length) return {
|
|
||||||
list: result,
|
|
||||||
from: CodeMirror.Pos(cur.line, start),
|
|
||||||
to: CodeMirror.Pos(cur.line, end)
|
|
||||||
};
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,831 +0,0 @@
|
|||||||
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
|
||||||
// Distributed under an MIT license: https://codemirror.net/LICENSE
|
|
||||||
|
|
||||||
(function(mod) {
|
|
||||||
if (typeof exports == "object" && typeof module == "object") // CommonJS
|
|
||||||
mod(require("../../lib/codemirror"));
|
|
||||||
else if (typeof define == "function" && define.amd) // AMD
|
|
||||||
define(["../../lib/codemirror"], mod);
|
|
||||||
else // Plain browser env
|
|
||||||
mod(CodeMirror);
|
|
||||||
})(function(CodeMirror) {
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
CodeMirror.defineMode("css", function(config, parserConfig) {
|
|
||||||
var inline = parserConfig.inline
|
|
||||||
if (!parserConfig.propertyKeywords) parserConfig = CodeMirror.resolveMode("text/css");
|
|
||||||
|
|
||||||
var indentUnit = config.indentUnit,
|
|
||||||
tokenHooks = parserConfig.tokenHooks,
|
|
||||||
documentTypes = parserConfig.documentTypes || {},
|
|
||||||
mediaTypes = parserConfig.mediaTypes || {},
|
|
||||||
mediaFeatures = parserConfig.mediaFeatures || {},
|
|
||||||
mediaValueKeywords = parserConfig.mediaValueKeywords || {},
|
|
||||||
propertyKeywords = parserConfig.propertyKeywords || {},
|
|
||||||
nonStandardPropertyKeywords = parserConfig.nonStandardPropertyKeywords || {},
|
|
||||||
fontProperties = parserConfig.fontProperties || {},
|
|
||||||
counterDescriptors = parserConfig.counterDescriptors || {},
|
|
||||||
colorKeywords = parserConfig.colorKeywords || {},
|
|
||||||
valueKeywords = parserConfig.valueKeywords || {},
|
|
||||||
allowNested = parserConfig.allowNested,
|
|
||||||
lineComment = parserConfig.lineComment,
|
|
||||||
supportsAtComponent = parserConfig.supportsAtComponent === true;
|
|
||||||
|
|
||||||
var type, override;
|
|
||||||
function ret(style, tp) { type = tp; return style; }
|
|
||||||
|
|
||||||
// Tokenizers
|
|
||||||
|
|
||||||
function tokenBase(stream, state) {
|
|
||||||
var ch = stream.next();
|
|
||||||
if (tokenHooks[ch]) {
|
|
||||||
var result = tokenHooks[ch](stream, state);
|
|
||||||
if (result !== false) return result;
|
|
||||||
}
|
|
||||||
if (ch == "@") {
|
|
||||||
stream.eatWhile(/[\w\\\-]/);
|
|
||||||
return ret("def", stream.current());
|
|
||||||
} else if (ch == "=" || (ch == "~" || ch == "|") && stream.eat("=")) {
|
|
||||||
return ret(null, "compare");
|
|
||||||
} else if (ch == "\"" || ch == "'") {
|
|
||||||
state.tokenize = tokenString(ch);
|
|
||||||
return state.tokenize(stream, state);
|
|
||||||
} else if (ch == "#") {
|
|
||||||
stream.eatWhile(/[\w\\\-]/);
|
|
||||||
return ret("atom", "hash");
|
|
||||||
} else if (ch == "!") {
|
|
||||||
stream.match(/^\s*\w*/);
|
|
||||||
return ret("keyword", "important");
|
|
||||||
} else if (/\d/.test(ch) || ch == "." && stream.eat(/\d/)) {
|
|
||||||
stream.eatWhile(/[\w.%]/);
|
|
||||||
return ret("number", "unit");
|
|
||||||
} else if (ch === "-") {
|
|
||||||
if (/[\d.]/.test(stream.peek())) {
|
|
||||||
stream.eatWhile(/[\w.%]/);
|
|
||||||
return ret("number", "unit");
|
|
||||||
} else if (stream.match(/^-[\w\\\-]*/)) {
|
|
||||||
stream.eatWhile(/[\w\\\-]/);
|
|
||||||
if (stream.match(/^\s*:/, false))
|
|
||||||
return ret("variable-2", "variable-definition");
|
|
||||||
return ret("variable-2", "variable");
|
|
||||||
} else if (stream.match(/^\w+-/)) {
|
|
||||||
return ret("meta", "meta");
|
|
||||||
}
|
|
||||||
} else if (/[,+>*\/]/.test(ch)) {
|
|
||||||
return ret(null, "select-op");
|
|
||||||
} else if (ch == "." && stream.match(/^-?[_a-z][_a-z0-9-]*/i)) {
|
|
||||||
return ret("qualifier", "qualifier");
|
|
||||||
} else if (/[:;{}\[\]\(\)]/.test(ch)) {
|
|
||||||
return ret(null, ch);
|
|
||||||
} else if (stream.match(/[\w-.]+(?=\()/)) {
|
|
||||||
if (/^(url(-prefix)?|domain|regexp)$/.test(stream.current().toLowerCase())) {
|
|
||||||
state.tokenize = tokenParenthesized;
|
|
||||||
}
|
|
||||||
return ret("variable callee", "variable");
|
|
||||||
} else if (/[\w\\\-]/.test(ch)) {
|
|
||||||
stream.eatWhile(/[\w\\\-]/);
|
|
||||||
return ret("property", "word");
|
|
||||||
} else {
|
|
||||||
return ret(null, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function tokenString(quote) {
|
|
||||||
return function(stream, state) {
|
|
||||||
var escaped = false, ch;
|
|
||||||
while ((ch = stream.next()) != null) {
|
|
||||||
if (ch == quote && !escaped) {
|
|
||||||
if (quote == ")") stream.backUp(1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
escaped = !escaped && ch == "\\";
|
|
||||||
}
|
|
||||||
if (ch == quote || !escaped && quote != ")") state.tokenize = null;
|
|
||||||
return ret("string", "string");
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function tokenParenthesized(stream, state) {
|
|
||||||
stream.next(); // Must be '('
|
|
||||||
if (!stream.match(/\s*[\"\')]/, false))
|
|
||||||
state.tokenize = tokenString(")");
|
|
||||||
else
|
|
||||||
state.tokenize = null;
|
|
||||||
return ret(null, "(");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Context management
|
|
||||||
|
|
||||||
function Context(type, indent, prev) {
|
|
||||||
this.type = type;
|
|
||||||
this.indent = indent;
|
|
||||||
this.prev = prev;
|
|
||||||
}
|
|
||||||
|
|
||||||
function pushContext(state, stream, type, indent) {
|
|
||||||
state.context = new Context(type, stream.indentation() + (indent === false ? 0 : indentUnit), state.context);
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
function popContext(state) {
|
|
||||||
if (state.context.prev)
|
|
||||||
state.context = state.context.prev;
|
|
||||||
return state.context.type;
|
|
||||||
}
|
|
||||||
|
|
||||||
function pass(type, stream, state) {
|
|
||||||
return states[state.context.type](type, stream, state);
|
|
||||||
}
|
|
||||||
function popAndPass(type, stream, state, n) {
|
|
||||||
for (var i = n || 1; i > 0; i--)
|
|
||||||
state.context = state.context.prev;
|
|
||||||
return pass(type, stream, state);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parser
|
|
||||||
|
|
||||||
function wordAsValue(stream) {
|
|
||||||
var word = stream.current().toLowerCase();
|
|
||||||
if (valueKeywords.hasOwnProperty(word))
|
|
||||||
override = "atom";
|
|
||||||
else if (colorKeywords.hasOwnProperty(word))
|
|
||||||
override = "keyword";
|
|
||||||
else
|
|
||||||
override = "variable";
|
|
||||||
}
|
|
||||||
|
|
||||||
var states = {};
|
|
||||||
|
|
||||||
states.top = function(type, stream, state) {
|
|
||||||
if (type == "{") {
|
|
||||||
return pushContext(state, stream, "block");
|
|
||||||
} else if (type == "}" && state.context.prev) {
|
|
||||||
return popContext(state);
|
|
||||||
} else if (supportsAtComponent && /@component/i.test(type)) {
|
|
||||||
return pushContext(state, stream, "atComponentBlock");
|
|
||||||
} else if (/^@(-moz-)?document$/i.test(type)) {
|
|
||||||
return pushContext(state, stream, "documentTypes");
|
|
||||||
} else if (/^@(media|supports|(-moz-)?document|import)$/i.test(type)) {
|
|
||||||
return pushContext(state, stream, "atBlock");
|
|
||||||
} else if (/^@(font-face|counter-style)/i.test(type)) {
|
|
||||||
state.stateArg = type;
|
|
||||||
return "restricted_atBlock_before";
|
|
||||||
} else if (/^@(-(moz|ms|o|webkit)-)?keyframes$/i.test(type)) {
|
|
||||||
return "keyframes";
|
|
||||||
} else if (type && type.charAt(0) == "@") {
|
|
||||||
return pushContext(state, stream, "at");
|
|
||||||
} else if (type == "hash") {
|
|
||||||
override = "builtin";
|
|
||||||
} else if (type == "word") {
|
|
||||||
override = "tag";
|
|
||||||
} else if (type == "variable-definition") {
|
|
||||||
return "maybeprop";
|
|
||||||
} else if (type == "interpolation") {
|
|
||||||
return pushContext(state, stream, "interpolation");
|
|
||||||
} else if (type == ":") {
|
|
||||||
return "pseudo";
|
|
||||||
} else if (allowNested && type == "(") {
|
|
||||||
return pushContext(state, stream, "parens");
|
|
||||||
}
|
|
||||||
return state.context.type;
|
|
||||||
};
|
|
||||||
|
|
||||||
states.block = function(type, stream, state) {
|
|
||||||
if (type == "word") {
|
|
||||||
var word = stream.current().toLowerCase();
|
|
||||||
if (propertyKeywords.hasOwnProperty(word)) {
|
|
||||||
override = "property";
|
|
||||||
return "maybeprop";
|
|
||||||
} else if (nonStandardPropertyKeywords.hasOwnProperty(word)) {
|
|
||||||
override = "string-2";
|
|
||||||
return "maybeprop";
|
|
||||||
} else if (allowNested) {
|
|
||||||
override = stream.match(/^\s*:(?:\s|$)/, false) ? "property" : "tag";
|
|
||||||
return "block";
|
|
||||||
} else {
|
|
||||||
override += " error";
|
|
||||||
return "maybeprop";
|
|
||||||
}
|
|
||||||
} else if (type == "meta") {
|
|
||||||
return "block";
|
|
||||||
} else if (!allowNested && (type == "hash" || type == "qualifier")) {
|
|
||||||
override = "error";
|
|
||||||
return "block";
|
|
||||||
} else {
|
|
||||||
return states.top(type, stream, state);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
states.maybeprop = function(type, stream, state) {
|
|
||||||
if (type == ":") return pushContext(state, stream, "prop");
|
|
||||||
return pass(type, stream, state);
|
|
||||||
};
|
|
||||||
|
|
||||||
states.prop = function(type, stream, state) {
|
|
||||||
if (type == ";") return popContext(state);
|
|
||||||
if (type == "{" && allowNested) return pushContext(state, stream, "propBlock");
|
|
||||||
if (type == "}" || type == "{") return popAndPass(type, stream, state);
|
|
||||||
if (type == "(") return pushContext(state, stream, "parens");
|
|
||||||
|
|
||||||
if (type == "hash" && !/^#([0-9a-fA-f]{3,4}|[0-9a-fA-f]{6}|[0-9a-fA-f]{8})$/.test(stream.current())) {
|
|
||||||
override += " error";
|
|
||||||
} else if (type == "word") {
|
|
||||||
wordAsValue(stream);
|
|
||||||
} else if (type == "interpolation") {
|
|
||||||
return pushContext(state, stream, "interpolation");
|
|
||||||
}
|
|
||||||
return "prop";
|
|
||||||
};
|
|
||||||
|
|
||||||
states.propBlock = function(type, _stream, state) {
|
|
||||||
if (type == "}") return popContext(state);
|
|
||||||
if (type == "word") { override = "property"; return "maybeprop"; }
|
|
||||||
return state.context.type;
|
|
||||||
};
|
|
||||||
|
|
||||||
states.parens = function(type, stream, state) {
|
|
||||||
if (type == "{" || type == "}") return popAndPass(type, stream, state);
|
|
||||||
if (type == ")") return popContext(state);
|
|
||||||
if (type == "(") return pushContext(state, stream, "parens");
|
|
||||||
if (type == "interpolation") return pushContext(state, stream, "interpolation");
|
|
||||||
if (type == "word") wordAsValue(stream);
|
|
||||||
return "parens";
|
|
||||||
};
|
|
||||||
|
|
||||||
states.pseudo = function(type, stream, state) {
|
|
||||||
if (type == "meta") return "pseudo";
|
|
||||||
|
|
||||||
if (type == "word") {
|
|
||||||
override = "variable-3";
|
|
||||||
return state.context.type;
|
|
||||||
}
|
|
||||||
return pass(type, stream, state);
|
|
||||||
};
|
|
||||||
|
|
||||||
states.documentTypes = function(type, stream, state) {
|
|
||||||
if (type == "word" && documentTypes.hasOwnProperty(stream.current())) {
|
|
||||||
override = "tag";
|
|
||||||
return state.context.type;
|
|
||||||
} else {
|
|
||||||
return states.atBlock(type, stream, state);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
states.atBlock = function(type, stream, state) {
|
|
||||||
if (type == "(") return pushContext(state, stream, "atBlock_parens");
|
|
||||||
if (type == "}" || type == ";") return popAndPass(type, stream, state);
|
|
||||||
if (type == "{") return popContext(state) && pushContext(state, stream, allowNested ? "block" : "top");
|
|
||||||
|
|
||||||
if (type == "interpolation") return pushContext(state, stream, "interpolation");
|
|
||||||
|
|
||||||
if (type == "word") {
|
|
||||||
var word = stream.current().toLowerCase();
|
|
||||||
if (word == "only" || word == "not" || word == "and" || word == "or")
|
|
||||||
override = "keyword";
|
|
||||||
else if (mediaTypes.hasOwnProperty(word))
|
|
||||||
override = "attribute";
|
|
||||||
else if (mediaFeatures.hasOwnProperty(word))
|
|
||||||
override = "property";
|
|
||||||
else if (mediaValueKeywords.hasOwnProperty(word))
|
|
||||||
override = "keyword";
|
|
||||||
else if (propertyKeywords.hasOwnProperty(word))
|
|
||||||
override = "property";
|
|
||||||
else if (nonStandardPropertyKeywords.hasOwnProperty(word))
|
|
||||||
override = "string-2";
|
|
||||||
else if (valueKeywords.hasOwnProperty(word))
|
|
||||||
override = "atom";
|
|
||||||
else if (colorKeywords.hasOwnProperty(word))
|
|
||||||
override = "keyword";
|
|
||||||
else
|
|
||||||
override = "error";
|
|
||||||
}
|
|
||||||
return state.context.type;
|
|
||||||
};
|
|
||||||
|
|
||||||
states.atComponentBlock = function(type, stream, state) {
|
|
||||||
if (type == "}")
|
|
||||||
return popAndPass(type, stream, state);
|
|
||||||
if (type == "{")
|
|
||||||
return popContext(state) && pushContext(state, stream, allowNested ? "block" : "top", false);
|
|
||||||
if (type == "word")
|
|
||||||
override = "error";
|
|
||||||
return state.context.type;
|
|
||||||
};
|
|
||||||
|
|
||||||
states.atBlock_parens = function(type, stream, state) {
|
|
||||||
if (type == ")") return popContext(state);
|
|
||||||
if (type == "{" || type == "}") return popAndPass(type, stream, state, 2);
|
|
||||||
return states.atBlock(type, stream, state);
|
|
||||||
};
|
|
||||||
|
|
||||||
states.restricted_atBlock_before = function(type, stream, state) {
|
|
||||||
if (type == "{")
|
|
||||||
return pushContext(state, stream, "restricted_atBlock");
|
|
||||||
if (type == "word" && state.stateArg == "@counter-style") {
|
|
||||||
override = "variable";
|
|
||||||
return "restricted_atBlock_before";
|
|
||||||
}
|
|
||||||
return pass(type, stream, state);
|
|
||||||
};
|
|
||||||
|
|
||||||
states.restricted_atBlock = function(type, stream, state) {
|
|
||||||
if (type == "}") {
|
|
||||||
state.stateArg = null;
|
|
||||||
return popContext(state);
|
|
||||||
}
|
|
||||||
if (type == "word") {
|
|
||||||
if ((state.stateArg == "@font-face" && !fontProperties.hasOwnProperty(stream.current().toLowerCase())) ||
|
|
||||||
(state.stateArg == "@counter-style" && !counterDescriptors.hasOwnProperty(stream.current().toLowerCase())))
|
|
||||||
override = "error";
|
|
||||||
else
|
|
||||||
override = "property";
|
|
||||||
return "maybeprop";
|
|
||||||
}
|
|
||||||
return "restricted_atBlock";
|
|
||||||
};
|
|
||||||
|
|
||||||
states.keyframes = function(type, stream, state) {
|
|
||||||
if (type == "word") { override = "variable"; return "keyframes"; }
|
|
||||||
if (type == "{") return pushContext(state, stream, "top");
|
|
||||||
return pass(type, stream, state);
|
|
||||||
};
|
|
||||||
|
|
||||||
states.at = function(type, stream, state) {
|
|
||||||
if (type == ";") return popContext(state);
|
|
||||||
if (type == "{" || type == "}") return popAndPass(type, stream, state);
|
|
||||||
if (type == "word") override = "tag";
|
|
||||||
else if (type == "hash") override = "builtin";
|
|
||||||
return "at";
|
|
||||||
};
|
|
||||||
|
|
||||||
states.interpolation = function(type, stream, state) {
|
|
||||||
if (type == "}") return popContext(state);
|
|
||||||
if (type == "{" || type == ";") return popAndPass(type, stream, state);
|
|
||||||
if (type == "word") override = "variable";
|
|
||||||
else if (type != "variable" && type != "(" && type != ")") override = "error";
|
|
||||||
return "interpolation";
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
|
||||||
startState: function(base) {
|
|
||||||
return {tokenize: null,
|
|
||||||
state: inline ? "block" : "top",
|
|
||||||
stateArg: null,
|
|
||||||
context: new Context(inline ? "block" : "top", base || 0, null)};
|
|
||||||
},
|
|
||||||
|
|
||||||
token: function(stream, state) {
|
|
||||||
if (!state.tokenize && stream.eatSpace()) return null;
|
|
||||||
var style = (state.tokenize || tokenBase)(stream, state);
|
|
||||||
if (style && typeof style == "object") {
|
|
||||||
type = style[1];
|
|
||||||
style = style[0];
|
|
||||||
}
|
|
||||||
override = style;
|
|
||||||
if (type != "comment")
|
|
||||||
state.state = states[state.state](type, stream, state);
|
|
||||||
return override;
|
|
||||||
},
|
|
||||||
|
|
||||||
indent: function(state, textAfter) {
|
|
||||||
var cx = state.context, ch = textAfter && textAfter.charAt(0);
|
|
||||||
var indent = cx.indent;
|
|
||||||
if (cx.type == "prop" && (ch == "}" || ch == ")")) cx = cx.prev;
|
|
||||||
if (cx.prev) {
|
|
||||||
if (ch == "}" && (cx.type == "block" || cx.type == "top" ||
|
|
||||||
cx.type == "interpolation" || cx.type == "restricted_atBlock")) {
|
|
||||||
// Resume indentation from parent context.
|
|
||||||
cx = cx.prev;
|
|
||||||
indent = cx.indent;
|
|
||||||
} else if (ch == ")" && (cx.type == "parens" || cx.type == "atBlock_parens") ||
|
|
||||||
ch == "{" && (cx.type == "at" || cx.type == "atBlock")) {
|
|
||||||
// Dedent relative to current context.
|
|
||||||
indent = Math.max(0, cx.indent - indentUnit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return indent;
|
|
||||||
},
|
|
||||||
|
|
||||||
electricChars: "}",
|
|
||||||
blockCommentStart: "/*",
|
|
||||||
blockCommentEnd: "*/",
|
|
||||||
blockCommentContinue: " * ",
|
|
||||||
lineComment: lineComment,
|
|
||||||
fold: "brace"
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
function keySet(array) {
|
|
||||||
var keys = {};
|
|
||||||
for (var i = 0; i < array.length; ++i) {
|
|
||||||
keys[array[i].toLowerCase()] = true;
|
|
||||||
}
|
|
||||||
return keys;
|
|
||||||
}
|
|
||||||
|
|
||||||
var documentTypes_ = [
|
|
||||||
"domain", "regexp", "url", "url-prefix"
|
|
||||||
], documentTypes = keySet(documentTypes_);
|
|
||||||
|
|
||||||
var mediaTypes_ = [
|
|
||||||
"all", "aural", "braille", "handheld", "print", "projection", "screen",
|
|
||||||
"tty", "tv", "embossed"
|
|
||||||
], mediaTypes = keySet(mediaTypes_);
|
|
||||||
|
|
||||||
var mediaFeatures_ = [
|
|
||||||
"width", "min-width", "max-width", "height", "min-height", "max-height",
|
|
||||||
"device-width", "min-device-width", "max-device-width", "device-height",
|
|
||||||
"min-device-height", "max-device-height", "aspect-ratio",
|
|
||||||
"min-aspect-ratio", "max-aspect-ratio", "device-aspect-ratio",
|
|
||||||
"min-device-aspect-ratio", "max-device-aspect-ratio", "color", "min-color",
|
|
||||||
"max-color", "color-index", "min-color-index", "max-color-index",
|
|
||||||
"monochrome", "min-monochrome", "max-monochrome", "resolution",
|
|
||||||
"min-resolution", "max-resolution", "scan", "grid", "orientation",
|
|
||||||
"device-pixel-ratio", "min-device-pixel-ratio", "max-device-pixel-ratio",
|
|
||||||
"pointer", "any-pointer", "hover", "any-hover"
|
|
||||||
], mediaFeatures = keySet(mediaFeatures_);
|
|
||||||
|
|
||||||
var mediaValueKeywords_ = [
|
|
||||||
"landscape", "portrait", "none", "coarse", "fine", "on-demand", "hover",
|
|
||||||
"interlace", "progressive"
|
|
||||||
], mediaValueKeywords = keySet(mediaValueKeywords_);
|
|
||||||
|
|
||||||
var propertyKeywords_ = [
|
|
||||||
"align-content", "align-items", "align-self", "alignment-adjust",
|
|
||||||
"alignment-baseline", "anchor-point", "animation", "animation-delay",
|
|
||||||
"animation-direction", "animation-duration", "animation-fill-mode",
|
|
||||||
"animation-iteration-count", "animation-name", "animation-play-state",
|
|
||||||
"animation-timing-function", "appearance", "azimuth", "backface-visibility",
|
|
||||||
"background", "background-attachment", "background-blend-mode", "background-clip",
|
|
||||||
"background-color", "background-image", "background-origin", "background-position",
|
|
||||||
"background-repeat", "background-size", "baseline-shift", "binding",
|
|
||||||
"bleed", "bookmark-label", "bookmark-level", "bookmark-state",
|
|
||||||
"bookmark-target", "border", "border-bottom", "border-bottom-color",
|
|
||||||
"border-bottom-left-radius", "border-bottom-right-radius",
|
|
||||||
"border-bottom-style", "border-bottom-width", "border-collapse",
|
|
||||||
"border-color", "border-image", "border-image-outset",
|
|
||||||
"border-image-repeat", "border-image-slice", "border-image-source",
|
|
||||||
"border-image-width", "border-left", "border-left-color",
|
|
||||||
"border-left-style", "border-left-width", "border-radius", "border-right",
|
|
||||||
"border-right-color", "border-right-style", "border-right-width",
|
|
||||||
"border-spacing", "border-style", "border-top", "border-top-color",
|
|
||||||
"border-top-left-radius", "border-top-right-radius", "border-top-style",
|
|
||||||
"border-top-width", "border-width", "bottom", "box-decoration-break",
|
|
||||||
"box-shadow", "box-sizing", "break-after", "break-before", "break-inside",
|
|
||||||
"caption-side", "caret-color", "clear", "clip", "color", "color-profile", "column-count",
|
|
||||||
"column-fill", "column-gap", "column-rule", "column-rule-color",
|
|
||||||
"column-rule-style", "column-rule-width", "column-span", "column-width",
|
|
||||||
"columns", "content", "counter-increment", "counter-reset", "crop", "cue",
|
|
||||||
"cue-after", "cue-before", "cursor", "direction", "display",
|
|
||||||
"dominant-baseline", "drop-initial-after-adjust",
|
|
||||||
"drop-initial-after-align", "drop-initial-before-adjust",
|
|
||||||
"drop-initial-before-align", "drop-initial-size", "drop-initial-value",
|
|
||||||
"elevation", "empty-cells", "fit", "fit-position", "flex", "flex-basis",
|
|
||||||
"flex-direction", "flex-flow", "flex-grow", "flex-shrink", "flex-wrap",
|
|
||||||
"float", "float-offset", "flow-from", "flow-into", "font", "font-feature-settings",
|
|
||||||
"font-family", "font-kerning", "font-language-override", "font-size", "font-size-adjust",
|
|
||||||
"font-stretch", "font-style", "font-synthesis", "font-variant",
|
|
||||||
"font-variant-alternates", "font-variant-caps", "font-variant-east-asian",
|
|
||||||
"font-variant-ligatures", "font-variant-numeric", "font-variant-position",
|
|
||||||
"font-weight", "grid", "grid-area", "grid-auto-columns", "grid-auto-flow",
|
|
||||||
"grid-auto-rows", "grid-column", "grid-column-end", "grid-column-gap",
|
|
||||||
"grid-column-start", "grid-gap", "grid-row", "grid-row-end", "grid-row-gap",
|
|
||||||
"grid-row-start", "grid-template", "grid-template-areas", "grid-template-columns",
|
|
||||||
"grid-template-rows", "hanging-punctuation", "height", "hyphens",
|
|
||||||
"icon", "image-orientation", "image-rendering", "image-resolution",
|
|
||||||
"inline-box-align", "justify-content", "justify-items", "justify-self", "left", "letter-spacing",
|
|
||||||
"line-break", "line-height", "line-stacking", "line-stacking-ruby",
|
|
||||||
"line-stacking-shift", "line-stacking-strategy", "list-style",
|
|
||||||
"list-style-image", "list-style-position", "list-style-type", "margin",
|
|
||||||
"margin-bottom", "margin-left", "margin-right", "margin-top",
|
|
||||||
"marks", "marquee-direction", "marquee-loop",
|
|
||||||
"marquee-play-count", "marquee-speed", "marquee-style", "max-height",
|
|
||||||
"max-width", "min-height", "min-width", "mix-blend-mode", "move-to", "nav-down", "nav-index",
|
|
||||||
"nav-left", "nav-right", "nav-up", "object-fit", "object-position",
|
|
||||||
"opacity", "order", "orphans", "outline",
|
|
||||||
"outline-color", "outline-offset", "outline-style", "outline-width",
|
|
||||||
"overflow", "overflow-style", "overflow-wrap", "overflow-x", "overflow-y",
|
|
||||||
"padding", "padding-bottom", "padding-left", "padding-right", "padding-top",
|
|
||||||
"page", "page-break-after", "page-break-before", "page-break-inside",
|
|
||||||
"page-policy", "pause", "pause-after", "pause-before", "perspective",
|
|
||||||
"perspective-origin", "pitch", "pitch-range", "place-content", "place-items", "place-self", "play-during", "position",
|
|
||||||
"presentation-level", "punctuation-trim", "quotes", "region-break-after",
|
|
||||||
"region-break-before", "region-break-inside", "region-fragment",
|
|
||||||
"rendering-intent", "resize", "rest", "rest-after", "rest-before", "richness",
|
|
||||||
"right", "rotation", "rotation-point", "ruby-align", "ruby-overhang",
|
|
||||||
"ruby-position", "ruby-span", "shape-image-threshold", "shape-inside", "shape-margin",
|
|
||||||
"shape-outside", "size", "speak", "speak-as", "speak-header",
|
|
||||||
"speak-numeral", "speak-punctuation", "speech-rate", "stress", "string-set",
|
|
||||||
"tab-size", "table-layout", "target", "target-name", "target-new",
|
|
||||||
"target-position", "text-align", "text-align-last", "text-decoration",
|
|
||||||
"text-decoration-color", "text-decoration-line", "text-decoration-skip",
|
|
||||||
"text-decoration-style", "text-emphasis", "text-emphasis-color",
|
|
||||||
"text-emphasis-position", "text-emphasis-style", "text-height",
|
|
||||||
"text-indent", "text-justify", "text-outline", "text-overflow", "text-shadow",
|
|
||||||
"text-size-adjust", "text-space-collapse", "text-transform", "text-underline-position",
|
|
||||||
"text-wrap", "top", "transform", "transform-origin", "transform-style",
|
|
||||||
"transition", "transition-delay", "transition-duration",
|
|
||||||
"transition-property", "transition-timing-function", "unicode-bidi",
|
|
||||||
"user-select", "vertical-align", "visibility", "voice-balance", "voice-duration",
|
|
||||||
"voice-family", "voice-pitch", "voice-range", "voice-rate", "voice-stress",
|
|
||||||
"voice-volume", "volume", "white-space", "widows", "width", "will-change", "word-break",
|
|
||||||
"word-spacing", "word-wrap", "z-index",
|
|
||||||
// SVG-specific
|
|
||||||
"clip-path", "clip-rule", "mask", "enable-background", "filter", "flood-color",
|
|
||||||
"flood-opacity", "lighting-color", "stop-color", "stop-opacity", "pointer-events",
|
|
||||||
"color-interpolation", "color-interpolation-filters",
|
|
||||||
"color-rendering", "fill", "fill-opacity", "fill-rule", "image-rendering",
|
|
||||||
"marker", "marker-end", "marker-mid", "marker-start", "shape-rendering", "stroke",
|
|
||||||
"stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin",
|
|
||||||
"stroke-miterlimit", "stroke-opacity", "stroke-width", "text-rendering",
|
|
||||||
"baseline-shift", "dominant-baseline", "glyph-orientation-horizontal",
|
|
||||||
"glyph-orientation-vertical", "text-anchor", "writing-mode"
|
|
||||||
], propertyKeywords = keySet(propertyKeywords_);
|
|
||||||
|
|
||||||
var nonStandardPropertyKeywords_ = [
|
|
||||||
"scrollbar-arrow-color", "scrollbar-base-color", "scrollbar-dark-shadow-color",
|
|
||||||
"scrollbar-face-color", "scrollbar-highlight-color", "scrollbar-shadow-color",
|
|
||||||
"scrollbar-3d-light-color", "scrollbar-track-color", "shape-inside",
|
|
||||||
"searchfield-cancel-button", "searchfield-decoration", "searchfield-results-button",
|
|
||||||
"searchfield-results-decoration", "zoom"
|
|
||||||
], nonStandardPropertyKeywords = keySet(nonStandardPropertyKeywords_);
|
|
||||||
|
|
||||||
var fontProperties_ = [
|
|
||||||
"font-family", "src", "unicode-range", "font-variant", "font-feature-settings",
|
|
||||||
"font-stretch", "font-weight", "font-style"
|
|
||||||
], fontProperties = keySet(fontProperties_);
|
|
||||||
|
|
||||||
var counterDescriptors_ = [
|
|
||||||
"additive-symbols", "fallback", "negative", "pad", "prefix", "range",
|
|
||||||
"speak-as", "suffix", "symbols", "system"
|
|
||||||
], counterDescriptors = keySet(counterDescriptors_);
|
|
||||||
|
|
||||||
var colorKeywords_ = [
|
|
||||||
"aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige",
|
|
||||||
"bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown",
|
|
||||||
"burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue",
|
|
||||||
"cornsilk", "crimson", "cyan", "darkblue", "darkcyan", "darkgoldenrod",
|
|
||||||
"darkgray", "darkgreen", "darkkhaki", "darkmagenta", "darkolivegreen",
|
|
||||||
"darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen",
|
|
||||||
"darkslateblue", "darkslategray", "darkturquoise", "darkviolet",
|
|
||||||
"deeppink", "deepskyblue", "dimgray", "dodgerblue", "firebrick",
|
|
||||||
"floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite",
|
|
||||||
"gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew",
|
|
||||||
"hotpink", "indianred", "indigo", "ivory", "khaki", "lavender",
|
|
||||||
"lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral",
|
|
||||||
"lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightpink",
|
|
||||||
"lightsalmon", "lightseagreen", "lightskyblue", "lightslategray",
|
|
||||||
"lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta",
|
|
||||||
"maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple",
|
|
||||||
"mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise",
|
|
||||||
"mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin",
|
|
||||||
"navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered",
|
|
||||||
"orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred",
|
|
||||||
"papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue",
|
|
||||||
"purple", "rebeccapurple", "red", "rosybrown", "royalblue", "saddlebrown",
|
|
||||||
"salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue",
|
|
||||||
"slateblue", "slategray", "snow", "springgreen", "steelblue", "tan",
|
|
||||||
"teal", "thistle", "tomato", "turquoise", "violet", "wheat", "white",
|
|
||||||
"whitesmoke", "yellow", "yellowgreen"
|
|
||||||
], colorKeywords = keySet(colorKeywords_);
|
|
||||||
|
|
||||||
var valueKeywords_ = [
|
|
||||||
"above", "absolute", "activeborder", "additive", "activecaption", "afar",
|
|
||||||
"after-white-space", "ahead", "alias", "all", "all-scroll", "alphabetic", "alternate",
|
|
||||||
"always", "amharic", "amharic-abegede", "antialiased", "appworkspace",
|
|
||||||
"arabic-indic", "armenian", "asterisks", "attr", "auto", "auto-flow", "avoid", "avoid-column", "avoid-page",
|
|
||||||
"avoid-region", "background", "backwards", "baseline", "below", "bidi-override", "binary",
|
|
||||||
"bengali", "blink", "block", "block-axis", "bold", "bolder", "border", "border-box",
|
|
||||||
"both", "bottom", "break", "break-all", "break-word", "bullets", "button", "button-bevel",
|
|
||||||
"buttonface", "buttonhighlight", "buttonshadow", "buttontext", "calc", "cambodian",
|
|
||||||
"capitalize", "caps-lock-indicator", "caption", "captiontext", "caret",
|
|
||||||
"cell", "center", "checkbox", "circle", "cjk-decimal", "cjk-earthly-branch",
|
|
||||||
"cjk-heavenly-stem", "cjk-ideographic", "clear", "clip", "close-quote",
|
|
||||||
"col-resize", "collapse", "color", "color-burn", "color-dodge", "column", "column-reverse",
|
|
||||||
"compact", "condensed", "contain", "content", "contents",
|
|
||||||
"content-box", "context-menu", "continuous", "copy", "counter", "counters", "cover", "crop",
|
|
||||||
"cross", "crosshair", "currentcolor", "cursive", "cyclic", "darken", "dashed", "decimal",
|
|
||||||
"decimal-leading-zero", "default", "default-button", "dense", "destination-atop",
|
|
||||||
"destination-in", "destination-out", "destination-over", "devanagari", "difference",
|
|
||||||
"disc", "discard", "disclosure-closed", "disclosure-open", "document",
|
|
||||||
"dot-dash", "dot-dot-dash",
|
|
||||||
"dotted", "double", "down", "e-resize", "ease", "ease-in", "ease-in-out", "ease-out",
|
|
||||||
"element", "ellipse", "ellipsis", "embed", "end", "ethiopic", "ethiopic-abegede",
|
|
||||||
"ethiopic-abegede-am-et", "ethiopic-abegede-gez", "ethiopic-abegede-ti-er",
|
|
||||||
"ethiopic-abegede-ti-et", "ethiopic-halehame-aa-er",
|
|
||||||
"ethiopic-halehame-aa-et", "ethiopic-halehame-am-et",
|
|
||||||
"ethiopic-halehame-gez", "ethiopic-halehame-om-et",
|
|
||||||
"ethiopic-halehame-sid-et", "ethiopic-halehame-so-et",
|
|
||||||
"ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et", "ethiopic-halehame-tig",
|
|
||||||
"ethiopic-numeric", "ew-resize", "exclusion", "expanded", "extends", "extra-condensed",
|
|
||||||
"extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "flex", "flex-end", "flex-start", "footnotes",
|
|
||||||
"forwards", "from", "geometricPrecision", "georgian", "graytext", "grid", "groove",
|
|
||||||
"gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hard-light", "hebrew",
|
|
||||||
"help", "hidden", "hide", "higher", "highlight", "highlighttext",
|
|
||||||
"hiragana", "hiragana-iroha", "horizontal", "hsl", "hsla", "hue", "icon", "ignore",
|
|
||||||
"inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite",
|
|
||||||
"infobackground", "infotext", "inherit", "initial", "inline", "inline-axis",
|
|
||||||
"inline-block", "inline-flex", "inline-grid", "inline-table", "inset", "inside", "intrinsic", "invert",
|
|
||||||
"italic", "japanese-formal", "japanese-informal", "justify", "kannada",
|
|
||||||
"katakana", "katakana-iroha", "keep-all", "khmer",
|
|
||||||
"korean-hangul-formal", "korean-hanja-formal", "korean-hanja-informal",
|
|
||||||
"landscape", "lao", "large", "larger", "left", "level", "lighter", "lighten",
|
|
||||||
"line-through", "linear", "linear-gradient", "lines", "list-item", "listbox", "listitem",
|
|
||||||
"local", "logical", "loud", "lower", "lower-alpha", "lower-armenian",
|
|
||||||
"lower-greek", "lower-hexadecimal", "lower-latin", "lower-norwegian",
|
|
||||||
"lower-roman", "lowercase", "ltr", "luminosity", "malayalam", "match", "matrix", "matrix3d",
|
|
||||||
"media-controls-background", "media-current-time-display",
|
|
||||||
"media-fullscreen-button", "media-mute-button", "media-play-button",
|
|
||||||
"media-return-to-realtime-button", "media-rewind-button",
|
|
||||||
"media-seek-back-button", "media-seek-forward-button", "media-slider",
|
|
||||||
"media-sliderthumb", "media-time-remaining-display", "media-volume-slider",
|
|
||||||
"media-volume-slider-container", "media-volume-sliderthumb", "medium",
|
|
||||||
"menu", "menulist", "menulist-button", "menulist-text",
|
|
||||||
"menulist-textfield", "menutext", "message-box", "middle", "min-intrinsic",
|
|
||||||
"mix", "mongolian", "monospace", "move", "multiple", "multiply", "myanmar", "n-resize",
|
|
||||||
"narrower", "ne-resize", "nesw-resize", "no-close-quote", "no-drop",
|
|
||||||
"no-open-quote", "no-repeat", "none", "normal", "not-allowed", "nowrap",
|
|
||||||
"ns-resize", "numbers", "numeric", "nw-resize", "nwse-resize", "oblique", "octal", "opacity", "open-quote",
|
|
||||||
"optimizeLegibility", "optimizeSpeed", "oriya", "oromo", "outset",
|
|
||||||
"outside", "outside-shape", "overlay", "overline", "padding", "padding-box",
|
|
||||||
"painted", "page", "paused", "persian", "perspective", "plus-darker", "plus-lighter",
|
|
||||||
"pointer", "polygon", "portrait", "pre", "pre-line", "pre-wrap", "preserve-3d",
|
|
||||||
"progress", "push-button", "radial-gradient", "radio", "read-only",
|
|
||||||
"read-write", "read-write-plaintext-only", "rectangle", "region",
|
|
||||||
"relative", "repeat", "repeating-linear-gradient",
|
|
||||||
"repeating-radial-gradient", "repeat-x", "repeat-y", "reset", "reverse",
|
|
||||||
"rgb", "rgba", "ridge", "right", "rotate", "rotate3d", "rotateX", "rotateY",
|
|
||||||
"rotateZ", "round", "row", "row-resize", "row-reverse", "rtl", "run-in", "running",
|
|
||||||
"s-resize", "sans-serif", "saturation", "scale", "scale3d", "scaleX", "scaleY", "scaleZ", "screen",
|
|
||||||
"scroll", "scrollbar", "scroll-position", "se-resize", "searchfield",
|
|
||||||
"searchfield-cancel-button", "searchfield-decoration",
|
|
||||||
"searchfield-results-button", "searchfield-results-decoration", "self-start", "self-end",
|
|
||||||
"semi-condensed", "semi-expanded", "separate", "serif", "show", "sidama",
|
|
||||||
"simp-chinese-formal", "simp-chinese-informal", "single",
|
|
||||||
"skew", "skewX", "skewY", "skip-white-space", "slide", "slider-horizontal",
|
|
||||||
"slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow",
|
|
||||||
"small", "small-caps", "small-caption", "smaller", "soft-light", "solid", "somali",
|
|
||||||
"source-atop", "source-in", "source-out", "source-over", "space", "space-around", "space-between", "space-evenly", "spell-out", "square",
|
|
||||||
"square-button", "start", "static", "status-bar", "stretch", "stroke", "sub",
|
|
||||||
"subpixel-antialiased", "super", "sw-resize", "symbolic", "symbols", "system-ui", "table",
|
|
||||||
"table-caption", "table-cell", "table-column", "table-column-group",
|
|
||||||
"table-footer-group", "table-header-group", "table-row", "table-row-group",
|
|
||||||
"tamil",
|
|
||||||
"telugu", "text", "text-bottom", "text-top", "textarea", "textfield", "thai",
|
|
||||||
"thick", "thin", "threeddarkshadow", "threedface", "threedhighlight",
|
|
||||||
"threedlightshadow", "threedshadow", "tibetan", "tigre", "tigrinya-er",
|
|
||||||
"tigrinya-er-abegede", "tigrinya-et", "tigrinya-et-abegede", "to", "top",
|
|
||||||
"trad-chinese-formal", "trad-chinese-informal", "transform",
|
|
||||||
"translate", "translate3d", "translateX", "translateY", "translateZ",
|
|
||||||
"transparent", "ultra-condensed", "ultra-expanded", "underline", "unset", "up",
|
|
||||||
"upper-alpha", "upper-armenian", "upper-greek", "upper-hexadecimal",
|
|
||||||
"upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url",
|
|
||||||
"var", "vertical", "vertical-text", "visible", "visibleFill", "visiblePainted",
|
|
||||||
"visibleStroke", "visual", "w-resize", "wait", "wave", "wider",
|
|
||||||
"window", "windowframe", "windowtext", "words", "wrap", "wrap-reverse", "x-large", "x-small", "xor",
|
|
||||||
"xx-large", "xx-small"
|
|
||||||
], valueKeywords = keySet(valueKeywords_);
|
|
||||||
|
|
||||||
var allWords = documentTypes_.concat(mediaTypes_).concat(mediaFeatures_).concat(mediaValueKeywords_)
|
|
||||||
.concat(propertyKeywords_).concat(nonStandardPropertyKeywords_).concat(colorKeywords_)
|
|
||||||
.concat(valueKeywords_);
|
|
||||||
CodeMirror.registerHelper("hintWords", "css", allWords);
|
|
||||||
|
|
||||||
function tokenCComment(stream, state) {
|
|
||||||
var maybeEnd = false, ch;
|
|
||||||
while ((ch = stream.next()) != null) {
|
|
||||||
if (maybeEnd && ch == "/") {
|
|
||||||
state.tokenize = null;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
maybeEnd = (ch == "*");
|
|
||||||
}
|
|
||||||
return ["comment", "comment"];
|
|
||||||
}
|
|
||||||
|
|
||||||
CodeMirror.defineMIME("text/css", {
|
|
||||||
documentTypes: documentTypes,
|
|
||||||
mediaTypes: mediaTypes,
|
|
||||||
mediaFeatures: mediaFeatures,
|
|
||||||
mediaValueKeywords: mediaValueKeywords,
|
|
||||||
propertyKeywords: propertyKeywords,
|
|
||||||
nonStandardPropertyKeywords: nonStandardPropertyKeywords,
|
|
||||||
fontProperties: fontProperties,
|
|
||||||
counterDescriptors: counterDescriptors,
|
|
||||||
colorKeywords: colorKeywords,
|
|
||||||
valueKeywords: valueKeywords,
|
|
||||||
tokenHooks: {
|
|
||||||
"/": function(stream, state) {
|
|
||||||
if (!stream.eat("*")) return false;
|
|
||||||
state.tokenize = tokenCComment;
|
|
||||||
return tokenCComment(stream, state);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
name: "css"
|
|
||||||
});
|
|
||||||
|
|
||||||
CodeMirror.defineMIME("text/x-scss", {
|
|
||||||
mediaTypes: mediaTypes,
|
|
||||||
mediaFeatures: mediaFeatures,
|
|
||||||
mediaValueKeywords: mediaValueKeywords,
|
|
||||||
propertyKeywords: propertyKeywords,
|
|
||||||
nonStandardPropertyKeywords: nonStandardPropertyKeywords,
|
|
||||||
colorKeywords: colorKeywords,
|
|
||||||
valueKeywords: valueKeywords,
|
|
||||||
fontProperties: fontProperties,
|
|
||||||
allowNested: true,
|
|
||||||
lineComment: "//",
|
|
||||||
tokenHooks: {
|
|
||||||
"/": function(stream, state) {
|
|
||||||
if (stream.eat("/")) {
|
|
||||||
stream.skipToEnd();
|
|
||||||
return ["comment", "comment"];
|
|
||||||
} else if (stream.eat("*")) {
|
|
||||||
state.tokenize = tokenCComment;
|
|
||||||
return tokenCComment(stream, state);
|
|
||||||
} else {
|
|
||||||
return ["operator", "operator"];
|
|
||||||
}
|
|
||||||
},
|
|
||||||
":": function(stream) {
|
|
||||||
if (stream.match(/\s*\{/, false))
|
|
||||||
return [null, null]
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
"$": function(stream) {
|
|
||||||
stream.match(/^[\w-]+/);
|
|
||||||
if (stream.match(/^\s*:/, false))
|
|
||||||
return ["variable-2", "variable-definition"];
|
|
||||||
return ["variable-2", "variable"];
|
|
||||||
},
|
|
||||||
"#": function(stream) {
|
|
||||||
if (!stream.eat("{")) return false;
|
|
||||||
return [null, "interpolation"];
|
|
||||||
}
|
|
||||||
},
|
|
||||||
name: "css",
|
|
||||||
helperType: "scss"
|
|
||||||
});
|
|
||||||
|
|
||||||
CodeMirror.defineMIME("text/x-less", {
|
|
||||||
mediaTypes: mediaTypes,
|
|
||||||
mediaFeatures: mediaFeatures,
|
|
||||||
mediaValueKeywords: mediaValueKeywords,
|
|
||||||
propertyKeywords: propertyKeywords,
|
|
||||||
nonStandardPropertyKeywords: nonStandardPropertyKeywords,
|
|
||||||
colorKeywords: colorKeywords,
|
|
||||||
valueKeywords: valueKeywords,
|
|
||||||
fontProperties: fontProperties,
|
|
||||||
allowNested: true,
|
|
||||||
lineComment: "//",
|
|
||||||
tokenHooks: {
|
|
||||||
"/": function(stream, state) {
|
|
||||||
if (stream.eat("/")) {
|
|
||||||
stream.skipToEnd();
|
|
||||||
return ["comment", "comment"];
|
|
||||||
} else if (stream.eat("*")) {
|
|
||||||
state.tokenize = tokenCComment;
|
|
||||||
return tokenCComment(stream, state);
|
|
||||||
} else {
|
|
||||||
return ["operator", "operator"];
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"@": function(stream) {
|
|
||||||
if (stream.eat("{")) return [null, "interpolation"];
|
|
||||||
if (stream.match(/^(charset|document|font-face|import|(-(moz|ms|o|webkit)-)?keyframes|media|namespace|page|supports)\b/i, false)) return false;
|
|
||||||
stream.eatWhile(/[\w\\\-]/);
|
|
||||||
if (stream.match(/^\s*:/, false))
|
|
||||||
return ["variable-2", "variable-definition"];
|
|
||||||
return ["variable-2", "variable"];
|
|
||||||
},
|
|
||||||
"&": function() {
|
|
||||||
return ["atom", "atom"];
|
|
||||||
}
|
|
||||||
},
|
|
||||||
name: "css",
|
|
||||||
helperType: "less"
|
|
||||||
});
|
|
||||||
|
|
||||||
CodeMirror.defineMIME("text/x-gss", {
|
|
||||||
documentTypes: documentTypes,
|
|
||||||
mediaTypes: mediaTypes,
|
|
||||||
mediaFeatures: mediaFeatures,
|
|
||||||
propertyKeywords: propertyKeywords,
|
|
||||||
nonStandardPropertyKeywords: nonStandardPropertyKeywords,
|
|
||||||
fontProperties: fontProperties,
|
|
||||||
counterDescriptors: counterDescriptors,
|
|
||||||
colorKeywords: colorKeywords,
|
|
||||||
valueKeywords: valueKeywords,
|
|
||||||
supportsAtComponent: true,
|
|
||||||
tokenHooks: {
|
|
||||||
"/": function(stream, state) {
|
|
||||||
if (!stream.eat("*")) return false;
|
|
||||||
state.tokenize = tokenCComment;
|
|
||||||
return tokenCComment(stream, state);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
name: "css",
|
|
||||||
helperType: "gss"
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
@ -1,111 +0,0 @@
|
|||||||
CodeMirror.extendMode('css', {
|
|
||||||
commentStart: '/*',
|
|
||||||
commentEnd: '*/',
|
|
||||||
newlineAfterToken: function (type, content) {
|
|
||||||
return /^[;{}]$/.test(content)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// Comment/uncomment the specified range
|
|
||||||
CodeMirror.defineExtension('commentRange', function (isComment, from, to) {
|
|
||||||
var cm = this
|
|
||||||
var curMode = CodeMirror.innerMode(cm.getMode(), cm.getTokenAt(from).state)
|
|
||||||
.mode
|
|
||||||
cm.operation(function () {
|
|
||||||
if (isComment) {
|
|
||||||
// Comment range
|
|
||||||
cm.replaceRange(curMode.commentEnd, to)
|
|
||||||
cm.replaceRange(curMode.commentStart, from)
|
|
||||||
if (from.line == to.line && from.ch == to.ch) {
|
|
||||||
// An empty comment inserted - put cursor inside
|
|
||||||
cm.setCursor(from.line, from.ch + curMode.commentStart.length)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Uncomment range
|
|
||||||
var selText = cm.getRange(from, to)
|
|
||||||
var startIndex = selText.indexOf(curMode.commentStart)
|
|
||||||
var endIndex = selText.lastIndexOf(curMode.commentEnd)
|
|
||||||
if (startIndex > -1 && endIndex > -1 && endIndex > startIndex) {
|
|
||||||
// Take string till comment start
|
|
||||||
selText =
|
|
||||||
selText.substr(0, startIndex) +
|
|
||||||
// From comment start till comment end
|
|
||||||
selText.substring(
|
|
||||||
startIndex + curMode.commentStart.length,
|
|
||||||
endIndex
|
|
||||||
) +
|
|
||||||
// From comment end till string end
|
|
||||||
selText.substr(endIndex + curMode.commentEnd.length)
|
|
||||||
}
|
|
||||||
cm.replaceRange(selText, from, to)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
// Applies automatic mode-aware indentation to the specified range
|
|
||||||
CodeMirror.defineExtension('autoIndentRange', function (from, to) {
|
|
||||||
var cmInstance = this
|
|
||||||
this.operation(function () {
|
|
||||||
for (var i = from.line; i <= to.line; i++) {
|
|
||||||
cmInstance.indentLine(i, 'smart')
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
// Applies automatic formatting to the specified range
|
|
||||||
CodeMirror.defineExtension('autoFormatRange', function (from, to) {
|
|
||||||
var cm = this
|
|
||||||
var outer = cm.getMode()
|
|
||||||
var text = cm.getRange(from, to).split('\n')
|
|
||||||
var state = CodeMirror.copyState(outer, cm.getTokenAt(from).state)
|
|
||||||
var tabSize = cm.getOption('tabSize')
|
|
||||||
|
|
||||||
var out = ''
|
|
||||||
var lines = 0
|
|
||||||
var atSol = from.ch == 0
|
|
||||||
function newline () {
|
|
||||||
out += '\n'
|
|
||||||
atSol = true
|
|
||||||
++lines
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var i = 0; i < text.length; ++i) {
|
|
||||||
var stream = new CodeMirror.StringStream(text[i], tabSize)
|
|
||||||
while (!stream.eol()) {
|
|
||||||
var inner = CodeMirror.innerMode(outer, state)
|
|
||||||
var style = outer.token(stream, state)
|
|
||||||
var cur = stream.current()
|
|
||||||
stream.start = stream.pos
|
|
||||||
if (!atSol || /\S/.test(cur)) {
|
|
||||||
out += cur
|
|
||||||
atSol = false
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
!atSol &&
|
|
||||||
inner.mode.newlineAfterToken &&
|
|
||||||
inner.mode.newlineAfterToken(
|
|
||||||
style,
|
|
||||||
cur,
|
|
||||||
stream.string.slice(stream.pos) || text[i + 1] || '',
|
|
||||||
inner.state
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
newline()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!stream.pos && outer.blankLine) outer.blankLine(state)
|
|
||||||
if (!atSol) newline()
|
|
||||||
}
|
|
||||||
|
|
||||||
cm.operation(function () {
|
|
||||||
cm.replaceRange(out, from, to)
|
|
||||||
for (
|
|
||||||
var cur = from.line + 1, end = from.line + lines;
|
|
||||||
cur <= end;
|
|
||||||
++cur
|
|
||||||
) {
|
|
||||||
cm.indentLine(cur, 'smart')
|
|
||||||
}
|
|
||||||
cm.setSelection(from, cm.getCursor(false))
|
|
||||||
})
|
|
||||||
})
|
|
@ -1,150 +0,0 @@
|
|||||||
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
|
||||||
// Distributed under an MIT license: https://codemirror.net/LICENSE
|
|
||||||
|
|
||||||
(function(mod) {
|
|
||||||
if (typeof exports == "object" && typeof module == "object") // CommonJS
|
|
||||||
mod(require("../../lib/codemirror"));
|
|
||||||
else if (typeof define == "function" && define.amd) // AMD
|
|
||||||
define(["../../lib/codemirror"], mod);
|
|
||||||
else // Plain browser env
|
|
||||||
mod(CodeMirror);
|
|
||||||
})(function(CodeMirror) {
|
|
||||||
var ie_lt8 = /MSIE \d/.test(navigator.userAgent) &&
|
|
||||||
(document.documentMode == null || document.documentMode < 8);
|
|
||||||
|
|
||||||
var Pos = CodeMirror.Pos;
|
|
||||||
|
|
||||||
var matching = {"(": ")>", ")": "(<", "[": "]>", "]": "[<", "{": "}>", "}": "{<", "<": ">>", ">": "<<"};
|
|
||||||
|
|
||||||
function bracketRegex(config) {
|
|
||||||
return config && config.bracketRegex || /[(){}[\]]/
|
|
||||||
}
|
|
||||||
|
|
||||||
function findMatchingBracket(cm, where, config) {
|
|
||||||
var line = cm.getLineHandle(where.line), pos = where.ch - 1;
|
|
||||||
var afterCursor = config && config.afterCursor
|
|
||||||
if (afterCursor == null)
|
|
||||||
afterCursor = /(^| )cm-fat-cursor($| )/.test(cm.getWrapperElement().className)
|
|
||||||
var re = bracketRegex(config)
|
|
||||||
|
|
||||||
// A cursor is defined as between two characters, but in in vim command mode
|
|
||||||
// (i.e. not insert mode), the cursor is visually represented as a
|
|
||||||
// highlighted box on top of the 2nd character. Otherwise, we allow matches
|
|
||||||
// from before or after the cursor.
|
|
||||||
var match = (!afterCursor && pos >= 0 && re.test(line.text.charAt(pos)) && matching[line.text.charAt(pos)]) ||
|
|
||||||
re.test(line.text.charAt(pos + 1)) && matching[line.text.charAt(++pos)];
|
|
||||||
if (!match) return null;
|
|
||||||
var dir = match.charAt(1) == ">" ? 1 : -1;
|
|
||||||
if (config && config.strict && (dir > 0) != (pos == where.ch)) return null;
|
|
||||||
var style = cm.getTokenTypeAt(Pos(where.line, pos + 1));
|
|
||||||
|
|
||||||
var found = scanForBracket(cm, Pos(where.line, pos + (dir > 0 ? 1 : 0)), dir, style || null, config);
|
|
||||||
if (found == null) return null;
|
|
||||||
return {from: Pos(where.line, pos), to: found && found.pos,
|
|
||||||
match: found && found.ch == match.charAt(0), forward: dir > 0};
|
|
||||||
}
|
|
||||||
|
|
||||||
// bracketRegex is used to specify which type of bracket to scan
|
|
||||||
// should be a regexp, e.g. /[[\]]/
|
|
||||||
//
|
|
||||||
// Note: If "where" is on an open bracket, then this bracket is ignored.
|
|
||||||
//
|
|
||||||
// Returns false when no bracket was found, null when it reached
|
|
||||||
// maxScanLines and gave up
|
|
||||||
function scanForBracket(cm, where, dir, style, config) {
|
|
||||||
var maxScanLen = (config && config.maxScanLineLength) || 10000;
|
|
||||||
var maxScanLines = (config && config.maxScanLines) || 1000;
|
|
||||||
|
|
||||||
var stack = [];
|
|
||||||
var re = bracketRegex(config)
|
|
||||||
var lineEnd = dir > 0 ? Math.min(where.line + maxScanLines, cm.lastLine() + 1)
|
|
||||||
: Math.max(cm.firstLine() - 1, where.line - maxScanLines);
|
|
||||||
for (var lineNo = where.line; lineNo != lineEnd; lineNo += dir) {
|
|
||||||
var line = cm.getLine(lineNo);
|
|
||||||
if (!line) continue;
|
|
||||||
var pos = dir > 0 ? 0 : line.length - 1, end = dir > 0 ? line.length : -1;
|
|
||||||
if (line.length > maxScanLen) continue;
|
|
||||||
if (lineNo == where.line) pos = where.ch - (dir < 0 ? 1 : 0);
|
|
||||||
for (; pos != end; pos += dir) {
|
|
||||||
var ch = line.charAt(pos);
|
|
||||||
if (re.test(ch) && (style === undefined || cm.getTokenTypeAt(Pos(lineNo, pos + 1)) == style)) {
|
|
||||||
var match = matching[ch];
|
|
||||||
if (match && (match.charAt(1) == ">") == (dir > 0)) stack.push(ch);
|
|
||||||
else if (!stack.length) return {pos: Pos(lineNo, pos), ch: ch};
|
|
||||||
else stack.pop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return lineNo - dir == (dir > 0 ? cm.lastLine() : cm.firstLine()) ? false : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function matchBrackets(cm, autoclear, config) {
|
|
||||||
// Disable brace matching in long lines, since it'll cause hugely slow updates
|
|
||||||
var maxHighlightLen = cm.state.matchBrackets.maxHighlightLineLength || 1000;
|
|
||||||
var marks = [], ranges = cm.listSelections();
|
|
||||||
for (var i = 0; i < ranges.length; i++) {
|
|
||||||
var match = ranges[i].empty() && findMatchingBracket(cm, ranges[i].head, config);
|
|
||||||
if (match && cm.getLine(match.from.line).length <= maxHighlightLen) {
|
|
||||||
var style = match.match ? "CodeMirror-matchingbracket" : "CodeMirror-nonmatchingbracket";
|
|
||||||
marks.push(cm.markText(match.from, Pos(match.from.line, match.from.ch + 1), {className: style}));
|
|
||||||
if (match.to && cm.getLine(match.to.line).length <= maxHighlightLen)
|
|
||||||
marks.push(cm.markText(match.to, Pos(match.to.line, match.to.ch + 1), {className: style}));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (marks.length) {
|
|
||||||
// Kludge to work around the IE bug from issue #1193, where text
|
|
||||||
// input stops going to the textare whever this fires.
|
|
||||||
if (ie_lt8 && cm.state.focused) cm.focus();
|
|
||||||
|
|
||||||
var clear = function() {
|
|
||||||
cm.operation(function() {
|
|
||||||
for (var i = 0; i < marks.length; i++) marks[i].clear();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
if (autoclear) setTimeout(clear, 800);
|
|
||||||
else return clear;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function doMatchBrackets(cm) {
|
|
||||||
cm.operation(function() {
|
|
||||||
if (cm.state.matchBrackets.currentlyHighlighted) {
|
|
||||||
cm.state.matchBrackets.currentlyHighlighted();
|
|
||||||
cm.state.matchBrackets.currentlyHighlighted = null;
|
|
||||||
}
|
|
||||||
cm.state.matchBrackets.currentlyHighlighted = matchBrackets(cm, false, cm.state.matchBrackets);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
CodeMirror.defineOption("matchBrackets", false, function(cm, val, old) {
|
|
||||||
if (old && old != CodeMirror.Init) {
|
|
||||||
cm.off("cursorActivity", doMatchBrackets);
|
|
||||||
if (cm.state.matchBrackets && cm.state.matchBrackets.currentlyHighlighted) {
|
|
||||||
cm.state.matchBrackets.currentlyHighlighted();
|
|
||||||
cm.state.matchBrackets.currentlyHighlighted = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (val) {
|
|
||||||
cm.state.matchBrackets = typeof val == "object" ? val : {};
|
|
||||||
cm.on("cursorActivity", doMatchBrackets);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
CodeMirror.defineExtension("matchBrackets", function() {matchBrackets(this, true);});
|
|
||||||
CodeMirror.defineExtension("findMatchingBracket", function(pos, config, oldConfig){
|
|
||||||
// Backwards-compatibility kludge
|
|
||||||
if (oldConfig || typeof config == "boolean") {
|
|
||||||
if (!oldConfig) {
|
|
||||||
config = config ? {strict: true} : null
|
|
||||||
} else {
|
|
||||||
oldConfig.strict = config
|
|
||||||
config = oldConfig
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return findMatchingBracket(this, pos, config)
|
|
||||||
});
|
|
||||||
CodeMirror.defineExtension("scanForBracket", function(pos, dir, style, config){
|
|
||||||
return scanForBracket(this, pos, dir, style, config);
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,460 +0,0 @@
|
|||||||
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
|
||||||
// Distributed under an MIT license: https://codemirror.net/LICENSE
|
|
||||||
|
|
||||||
(function(mod) {
|
|
||||||
if (typeof exports == "object" && typeof module == "object") // CommonJS
|
|
||||||
mod(require("../../lib/codemirror"));
|
|
||||||
else if (typeof define == "function" && define.amd) // AMD
|
|
||||||
define(["../../lib/codemirror"], mod);
|
|
||||||
else // Plain browser env
|
|
||||||
mod(CodeMirror);
|
|
||||||
})(function(CodeMirror) {
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
var HINT_ELEMENT_CLASS = "CodeMirror-hint";
|
|
||||||
var ACTIVE_HINT_ELEMENT_CLASS = "CodeMirror-hint-active";
|
|
||||||
|
|
||||||
// This is the old interface, kept around for now to stay
|
|
||||||
// backwards-compatible.
|
|
||||||
CodeMirror.showHint = function(cm, getHints, options) {
|
|
||||||
if (!getHints) return cm.showHint(options);
|
|
||||||
if (options && options.async) getHints.async = true;
|
|
||||||
var newOpts = {hint: getHints};
|
|
||||||
if (options) for (var prop in options) newOpts[prop] = options[prop];
|
|
||||||
return cm.showHint(newOpts);
|
|
||||||
};
|
|
||||||
|
|
||||||
CodeMirror.defineExtension("showHint", function(options) {
|
|
||||||
options = parseOptions(this, this.getCursor("start"), options);
|
|
||||||
var selections = this.listSelections()
|
|
||||||
if (selections.length > 1) return;
|
|
||||||
// By default, don't allow completion when something is selected.
|
|
||||||
// A hint function can have a `supportsSelection` property to
|
|
||||||
// indicate that it can handle selections.
|
|
||||||
if (this.somethingSelected()) {
|
|
||||||
if (!options.hint.supportsSelection) return;
|
|
||||||
// Don't try with cross-line selections
|
|
||||||
for (var i = 0; i < selections.length; i++)
|
|
||||||
if (selections[i].head.line != selections[i].anchor.line) return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.state.completionActive) this.state.completionActive.close();
|
|
||||||
var completion = this.state.completionActive = new Completion(this, options);
|
|
||||||
if (!completion.options.hint) return;
|
|
||||||
|
|
||||||
CodeMirror.signal(this, "startCompletion", this);
|
|
||||||
completion.update(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
CodeMirror.defineExtension("closeHint", function() {
|
|
||||||
if (this.state.completionActive) this.state.completionActive.close()
|
|
||||||
})
|
|
||||||
|
|
||||||
function Completion(cm, options) {
|
|
||||||
this.cm = cm;
|
|
||||||
this.options = options;
|
|
||||||
this.widget = null;
|
|
||||||
this.debounce = 0;
|
|
||||||
this.tick = 0;
|
|
||||||
this.startPos = this.cm.getCursor("start");
|
|
||||||
this.startLen = this.cm.getLine(this.startPos.line).length - this.cm.getSelection().length;
|
|
||||||
|
|
||||||
var self = this;
|
|
||||||
cm.on("cursorActivity", this.activityFunc = function() { self.cursorActivity(); });
|
|
||||||
}
|
|
||||||
|
|
||||||
var requestAnimationFrame = window.requestAnimationFrame || function(fn) {
|
|
||||||
return setTimeout(fn, 1000/60);
|
|
||||||
};
|
|
||||||
var cancelAnimationFrame = window.cancelAnimationFrame || clearTimeout;
|
|
||||||
|
|
||||||
Completion.prototype = {
|
|
||||||
close: function() {
|
|
||||||
if (!this.active()) return;
|
|
||||||
this.cm.state.completionActive = null;
|
|
||||||
this.tick = null;
|
|
||||||
this.cm.off("cursorActivity", this.activityFunc);
|
|
||||||
|
|
||||||
if (this.widget && this.data) CodeMirror.signal(this.data, "close");
|
|
||||||
if (this.widget) this.widget.close();
|
|
||||||
CodeMirror.signal(this.cm, "endCompletion", this.cm);
|
|
||||||
},
|
|
||||||
|
|
||||||
active: function() {
|
|
||||||
return this.cm.state.completionActive == this;
|
|
||||||
},
|
|
||||||
|
|
||||||
pick: function(data, i) {
|
|
||||||
var completion = data.list[i];
|
|
||||||
if (completion.hint) completion.hint(this.cm, data, completion);
|
|
||||||
else this.cm.replaceRange(getText(completion), completion.from || data.from,
|
|
||||||
completion.to || data.to, "complete");
|
|
||||||
CodeMirror.signal(data, "pick", completion);
|
|
||||||
this.close();
|
|
||||||
},
|
|
||||||
|
|
||||||
cursorActivity: function() {
|
|
||||||
if (this.debounce) {
|
|
||||||
cancelAnimationFrame(this.debounce);
|
|
||||||
this.debounce = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
var pos = this.cm.getCursor(), line = this.cm.getLine(pos.line);
|
|
||||||
if (pos.line != this.startPos.line || line.length - pos.ch != this.startLen - this.startPos.ch ||
|
|
||||||
pos.ch < this.startPos.ch || this.cm.somethingSelected() ||
|
|
||||||
(!pos.ch || this.options.closeCharacters.test(line.charAt(pos.ch - 1)))) {
|
|
||||||
this.close();
|
|
||||||
} else {
|
|
||||||
var self = this;
|
|
||||||
this.debounce = requestAnimationFrame(function() {self.update();});
|
|
||||||
if (this.widget) this.widget.disable();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
update: function(first) {
|
|
||||||
if (this.tick == null) return
|
|
||||||
var self = this, myTick = ++this.tick
|
|
||||||
fetchHints(this.options.hint, this.cm, this.options, function(data) {
|
|
||||||
if (self.tick == myTick) self.finishUpdate(data, first)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
finishUpdate: function(data, first) {
|
|
||||||
if (this.data) CodeMirror.signal(this.data, "update");
|
|
||||||
|
|
||||||
var picked = (this.widget && this.widget.picked) || (first && this.options.completeSingle);
|
|
||||||
if (this.widget) this.widget.close();
|
|
||||||
|
|
||||||
this.data = data;
|
|
||||||
|
|
||||||
if (data && data.list.length) {
|
|
||||||
if (picked && data.list.length == 1) {
|
|
||||||
this.pick(data, 0);
|
|
||||||
} else {
|
|
||||||
this.widget = new Widget(this, data);
|
|
||||||
CodeMirror.signal(data, "shown");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function parseOptions(cm, pos, options) {
|
|
||||||
var editor = cm.options.hintOptions;
|
|
||||||
var out = {};
|
|
||||||
for (var prop in defaultOptions) out[prop] = defaultOptions[prop];
|
|
||||||
if (editor) for (var prop in editor)
|
|
||||||
if (editor[prop] !== undefined) out[prop] = editor[prop];
|
|
||||||
if (options) for (var prop in options)
|
|
||||||
if (options[prop] !== undefined) out[prop] = options[prop];
|
|
||||||
if (out.hint.resolve) out.hint = out.hint.resolve(cm, pos)
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getText(completion) {
|
|
||||||
if (typeof completion == "string") return completion;
|
|
||||||
else return completion.text;
|
|
||||||
}
|
|
||||||
|
|
||||||
function buildKeyMap(completion, handle) {
|
|
||||||
var baseMap = {
|
|
||||||
Up: function() {handle.moveFocus(-1);},
|
|
||||||
Down: function() {handle.moveFocus(1);},
|
|
||||||
PageUp: function() {handle.moveFocus(-handle.menuSize() + 1, true);},
|
|
||||||
PageDown: function() {handle.moveFocus(handle.menuSize() - 1, true);},
|
|
||||||
Home: function() {handle.setFocus(0);},
|
|
||||||
End: function() {handle.setFocus(handle.length - 1);},
|
|
||||||
Enter: handle.pick,
|
|
||||||
Tab: handle.pick,
|
|
||||||
Esc: handle.close
|
|
||||||
};
|
|
||||||
|
|
||||||
var mac = /Mac/.test(navigator.platform);
|
|
||||||
|
|
||||||
if (mac) {
|
|
||||||
baseMap["Ctrl-P"] = function() {handle.moveFocus(-1);};
|
|
||||||
baseMap["Ctrl-N"] = function() {handle.moveFocus(1);};
|
|
||||||
}
|
|
||||||
|
|
||||||
var custom = completion.options.customKeys;
|
|
||||||
var ourMap = custom ? {} : baseMap;
|
|
||||||
function addBinding(key, val) {
|
|
||||||
var bound;
|
|
||||||
if (typeof val != "string")
|
|
||||||
bound = function(cm) { return val(cm, handle); };
|
|
||||||
// This mechanism is deprecated
|
|
||||||
else if (baseMap.hasOwnProperty(val))
|
|
||||||
bound = baseMap[val];
|
|
||||||
else
|
|
||||||
bound = val;
|
|
||||||
ourMap[key] = bound;
|
|
||||||
}
|
|
||||||
if (custom)
|
|
||||||
for (var key in custom) if (custom.hasOwnProperty(key))
|
|
||||||
addBinding(key, custom[key]);
|
|
||||||
var extra = completion.options.extraKeys;
|
|
||||||
if (extra)
|
|
||||||
for (var key in extra) if (extra.hasOwnProperty(key))
|
|
||||||
addBinding(key, extra[key]);
|
|
||||||
return ourMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getHintElement(hintsElement, el) {
|
|
||||||
while (el && el != hintsElement) {
|
|
||||||
if (el.nodeName.toUpperCase() === "LI" && el.parentNode == hintsElement) return el;
|
|
||||||
el = el.parentNode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function Widget(completion, data) {
|
|
||||||
this.completion = completion;
|
|
||||||
this.data = data;
|
|
||||||
this.picked = false;
|
|
||||||
var widget = this, cm = completion.cm;
|
|
||||||
var ownerDocument = cm.getInputField().ownerDocument;
|
|
||||||
var parentWindow = ownerDocument.defaultView || ownerDocument.parentWindow;
|
|
||||||
|
|
||||||
var hints = this.hints = ownerDocument.createElement("ul");
|
|
||||||
var theme = completion.cm.options.theme;
|
|
||||||
hints.className = "CodeMirror-hints " + theme;
|
|
||||||
this.selectedHint = data.selectedHint || 0;
|
|
||||||
|
|
||||||
var completions = data.list;
|
|
||||||
for (var i = 0; i < completions.length; ++i) {
|
|
||||||
var elt = hints.appendChild(ownerDocument.createElement("li")), cur = completions[i];
|
|
||||||
var className = HINT_ELEMENT_CLASS + (i != this.selectedHint ? "" : " " + ACTIVE_HINT_ELEMENT_CLASS);
|
|
||||||
if (cur.className != null) className = cur.className + " " + className;
|
|
||||||
elt.className = className;
|
|
||||||
if (cur.render) cur.render(elt, data, cur);
|
|
||||||
else elt.appendChild(ownerDocument.createTextNode(cur.displayText || getText(cur)));
|
|
||||||
elt.hintId = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
var container = completion.options.container || ownerDocument.body;
|
|
||||||
var pos = cm.cursorCoords(completion.options.alignWithWord ? data.from : null);
|
|
||||||
var left = pos.left, top = pos.bottom, below = true;
|
|
||||||
var offsetLeft = 0, offsetTop = 0;
|
|
||||||
if (container !== ownerDocument.body) {
|
|
||||||
// We offset the cursor position because left and top are relative to the offsetParent's top left corner.
|
|
||||||
var isContainerPositioned = ['absolute', 'relative', 'fixed'].indexOf(parentWindow.getComputedStyle(container).position) !== -1;
|
|
||||||
var offsetParent = isContainerPositioned ? container : container.offsetParent;
|
|
||||||
var offsetParentPosition = offsetParent.getBoundingClientRect();
|
|
||||||
var bodyPosition = ownerDocument.body.getBoundingClientRect();
|
|
||||||
offsetLeft = (offsetParentPosition.left - bodyPosition.left - offsetParent.scrollLeft);
|
|
||||||
offsetTop = (offsetParentPosition.top - bodyPosition.top - offsetParent.scrollTop);
|
|
||||||
}
|
|
||||||
hints.style.left = (left - offsetLeft) + "px";
|
|
||||||
hints.style.top = (top - offsetTop) + "px";
|
|
||||||
|
|
||||||
// If we're at the edge of the screen, then we want the menu to appear on the left of the cursor.
|
|
||||||
var winW = parentWindow.innerWidth || Math.max(ownerDocument.body.offsetWidth, ownerDocument.documentElement.offsetWidth);
|
|
||||||
var winH = parentWindow.innerHeight || Math.max(ownerDocument.body.offsetHeight, ownerDocument.documentElement.offsetHeight);
|
|
||||||
container.appendChild(hints);
|
|
||||||
var box = hints.getBoundingClientRect(), overlapY = box.bottom - winH;
|
|
||||||
var scrolls = hints.scrollHeight > hints.clientHeight + 1
|
|
||||||
var startScroll = cm.getScrollInfo();
|
|
||||||
|
|
||||||
if (overlapY > 0) {
|
|
||||||
var height = box.bottom - box.top, curTop = pos.top - (pos.bottom - box.top);
|
|
||||||
if (curTop - height > 0) { // Fits above cursor
|
|
||||||
hints.style.top = (top = pos.top - height - offsetTop) + "px";
|
|
||||||
below = false;
|
|
||||||
} else if (height > winH) {
|
|
||||||
hints.style.height = (winH - 5) + "px";
|
|
||||||
hints.style.top = (top = pos.bottom - box.top - offsetTop) + "px";
|
|
||||||
var cursor = cm.getCursor();
|
|
||||||
if (data.from.ch != cursor.ch) {
|
|
||||||
pos = cm.cursorCoords(cursor);
|
|
||||||
hints.style.left = (left = pos.left - offsetLeft) + "px";
|
|
||||||
box = hints.getBoundingClientRect();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var overlapX = box.right - winW;
|
|
||||||
if (overlapX > 0) {
|
|
||||||
if (box.right - box.left > winW) {
|
|
||||||
hints.style.width = (winW - 5) + "px";
|
|
||||||
overlapX -= (box.right - box.left) - winW;
|
|
||||||
}
|
|
||||||
hints.style.left = (left = pos.left - overlapX - offsetLeft) + "px";
|
|
||||||
}
|
|
||||||
if (scrolls) for (var node = hints.firstChild; node; node = node.nextSibling)
|
|
||||||
node.style.paddingRight = cm.display.nativeBarWidth + "px"
|
|
||||||
|
|
||||||
cm.addKeyMap(this.keyMap = buildKeyMap(completion, {
|
|
||||||
moveFocus: function(n, avoidWrap) { widget.changeActive(widget.selectedHint + n, avoidWrap); },
|
|
||||||
setFocus: function(n) { widget.changeActive(n); },
|
|
||||||
menuSize: function() { return widget.screenAmount(); },
|
|
||||||
length: completions.length,
|
|
||||||
close: function() { completion.close(); },
|
|
||||||
pick: function() { widget.pick(); },
|
|
||||||
data: data
|
|
||||||
}));
|
|
||||||
|
|
||||||
if (completion.options.closeOnUnfocus) {
|
|
||||||
var closingOnBlur;
|
|
||||||
cm.on("blur", this.onBlur = function() { closingOnBlur = setTimeout(function() { completion.close(); }, 100); });
|
|
||||||
cm.on("focus", this.onFocus = function() { clearTimeout(closingOnBlur); });
|
|
||||||
}
|
|
||||||
|
|
||||||
cm.on("scroll", this.onScroll = function() {
|
|
||||||
var curScroll = cm.getScrollInfo(), editor = cm.getWrapperElement().getBoundingClientRect();
|
|
||||||
var newTop = top + startScroll.top - curScroll.top;
|
|
||||||
var point = newTop - (parentWindow.pageYOffset || (ownerDocument.documentElement || ownerDocument.body).scrollTop);
|
|
||||||
if (!below) point += hints.offsetHeight;
|
|
||||||
if (point <= editor.top || point >= editor.bottom) return completion.close();
|
|
||||||
hints.style.top = newTop + "px";
|
|
||||||
hints.style.left = (left + startScroll.left - curScroll.left) + "px";
|
|
||||||
});
|
|
||||||
|
|
||||||
CodeMirror.on(hints, "dblclick", function(e) {
|
|
||||||
var t = getHintElement(hints, e.target || e.srcElement);
|
|
||||||
if (t && t.hintId != null) {widget.changeActive(t.hintId); widget.pick();}
|
|
||||||
});
|
|
||||||
|
|
||||||
CodeMirror.on(hints, "click", function(e) {
|
|
||||||
var t = getHintElement(hints, e.target || e.srcElement);
|
|
||||||
if (t && t.hintId != null) {
|
|
||||||
widget.changeActive(t.hintId);
|
|
||||||
if (completion.options.completeOnSingleClick) widget.pick();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
CodeMirror.on(hints, "mousedown", function() {
|
|
||||||
setTimeout(function(){cm.focus();}, 20);
|
|
||||||
});
|
|
||||||
|
|
||||||
CodeMirror.signal(data, "select", completions[this.selectedHint], hints.childNodes[this.selectedHint]);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget.prototype = {
|
|
||||||
close: function() {
|
|
||||||
if (this.completion.widget != this) return;
|
|
||||||
this.completion.widget = null;
|
|
||||||
this.hints.parentNode.removeChild(this.hints);
|
|
||||||
this.completion.cm.removeKeyMap(this.keyMap);
|
|
||||||
|
|
||||||
var cm = this.completion.cm;
|
|
||||||
if (this.completion.options.closeOnUnfocus) {
|
|
||||||
cm.off("blur", this.onBlur);
|
|
||||||
cm.off("focus", this.onFocus);
|
|
||||||
}
|
|
||||||
cm.off("scroll", this.onScroll);
|
|
||||||
},
|
|
||||||
|
|
||||||
disable: function() {
|
|
||||||
this.completion.cm.removeKeyMap(this.keyMap);
|
|
||||||
var widget = this;
|
|
||||||
this.keyMap = {Enter: function() { widget.picked = true; }};
|
|
||||||
this.completion.cm.addKeyMap(this.keyMap);
|
|
||||||
},
|
|
||||||
|
|
||||||
pick: function() {
|
|
||||||
this.completion.pick(this.data, this.selectedHint);
|
|
||||||
},
|
|
||||||
|
|
||||||
changeActive: function(i, avoidWrap) {
|
|
||||||
if (i >= this.data.list.length)
|
|
||||||
i = avoidWrap ? this.data.list.length - 1 : 0;
|
|
||||||
else if (i < 0)
|
|
||||||
i = avoidWrap ? 0 : this.data.list.length - 1;
|
|
||||||
if (this.selectedHint == i) return;
|
|
||||||
var node = this.hints.childNodes[this.selectedHint];
|
|
||||||
if (node) node.className = node.className.replace(" " + ACTIVE_HINT_ELEMENT_CLASS, "");
|
|
||||||
node = this.hints.childNodes[this.selectedHint = i];
|
|
||||||
node.className += " " + ACTIVE_HINT_ELEMENT_CLASS;
|
|
||||||
if (node.offsetTop < this.hints.scrollTop)
|
|
||||||
this.hints.scrollTop = node.offsetTop - 3;
|
|
||||||
else if (node.offsetTop + node.offsetHeight > this.hints.scrollTop + this.hints.clientHeight)
|
|
||||||
this.hints.scrollTop = node.offsetTop + node.offsetHeight - this.hints.clientHeight + 3;
|
|
||||||
CodeMirror.signal(this.data, "select", this.data.list[this.selectedHint], node);
|
|
||||||
},
|
|
||||||
|
|
||||||
screenAmount: function() {
|
|
||||||
return Math.floor(this.hints.clientHeight / this.hints.firstChild.offsetHeight) || 1;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function applicableHelpers(cm, helpers) {
|
|
||||||
if (!cm.somethingSelected()) return helpers
|
|
||||||
var result = []
|
|
||||||
for (var i = 0; i < helpers.length; i++)
|
|
||||||
if (helpers[i].supportsSelection) result.push(helpers[i])
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
function fetchHints(hint, cm, options, callback) {
|
|
||||||
if (hint.async) {
|
|
||||||
hint(cm, callback, options)
|
|
||||||
} else {
|
|
||||||
var result = hint(cm, options)
|
|
||||||
if (result && result.then) result.then(callback)
|
|
||||||
else callback(result)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function resolveAutoHints(cm, pos) {
|
|
||||||
var helpers = cm.getHelpers(pos, "hint"), words
|
|
||||||
if (helpers.length) {
|
|
||||||
var resolved = function(cm, callback, options) {
|
|
||||||
var app = applicableHelpers(cm, helpers);
|
|
||||||
function run(i) {
|
|
||||||
if (i == app.length) return callback(null)
|
|
||||||
fetchHints(app[i], cm, options, function(result) {
|
|
||||||
if (result && result.list.length > 0) callback(result)
|
|
||||||
else run(i + 1)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
run(0)
|
|
||||||
}
|
|
||||||
resolved.async = true
|
|
||||||
resolved.supportsSelection = true
|
|
||||||
return resolved
|
|
||||||
} else if (words = cm.getHelper(cm.getCursor(), "hintWords")) {
|
|
||||||
return function(cm) { return CodeMirror.hint.fromList(cm, {words: words}) }
|
|
||||||
} else if (CodeMirror.hint.anyword) {
|
|
||||||
return function(cm, options) { return CodeMirror.hint.anyword(cm, options) }
|
|
||||||
} else {
|
|
||||||
return function() {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CodeMirror.registerHelper("hint", "auto", {
|
|
||||||
resolve: resolveAutoHints
|
|
||||||
});
|
|
||||||
|
|
||||||
CodeMirror.registerHelper("hint", "fromList", function(cm, options) {
|
|
||||||
var cur = cm.getCursor(), token = cm.getTokenAt(cur)
|
|
||||||
var term, from = CodeMirror.Pos(cur.line, token.start), to = cur
|
|
||||||
if (token.start < cur.ch && /\w/.test(token.string.charAt(cur.ch - token.start - 1))) {
|
|
||||||
term = token.string.substr(0, cur.ch - token.start)
|
|
||||||
} else {
|
|
||||||
term = ""
|
|
||||||
from = cur
|
|
||||||
}
|
|
||||||
var found = [];
|
|
||||||
for (var i = 0; i < options.words.length; i++) {
|
|
||||||
var word = options.words[i];
|
|
||||||
if (word.slice(0, term.length) == term)
|
|
||||||
found.push(word);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (found.length) return {list: found, from: from, to: to};
|
|
||||||
});
|
|
||||||
|
|
||||||
CodeMirror.commands.autocomplete = CodeMirror.showHint;
|
|
||||||
|
|
||||||
var defaultOptions = {
|
|
||||||
hint: CodeMirror.hint.auto,
|
|
||||||
completeSingle: true,
|
|
||||||
alignWithWord: true,
|
|
||||||
closeCharacters: /[\s()\[\]{};:>,]/,
|
|
||||||
closeOnUnfocus: true,
|
|
||||||
completeOnSingleClick: true,
|
|
||||||
container: null,
|
|
||||||
customKeys: null,
|
|
||||||
extraKeys: null
|
|
||||||
};
|
|
||||||
|
|
||||||
CodeMirror.defineOption("hintOptions", null);
|
|
||||||
});
|
|
File diff suppressed because one or more lines are too long
2
public/libs/scripts/jquery.min.js
vendored
2
public/libs/scripts/jquery.min.js
vendored
File diff suppressed because one or more lines are too long
1
public/libs/scripts/markdown.min.js
vendored
1
public/libs/scripts/markdown.min.js
vendored
File diff suppressed because one or more lines are too long
1
public/libs/scripts/marked.min.js
vendored
1
public/libs/scripts/marked.min.js
vendored
File diff suppressed because one or more lines are too long
1
public/libs/scripts/prettify.min.js
vendored
1
public/libs/scripts/prettify.min.js
vendored
File diff suppressed because one or more lines are too long
@ -6,6 +6,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import Loading from './components/Loading'
|
import Loading from './components/Loading'
|
||||||
import CodemirrorEditor from './components/CodemirrorEditor'
|
import CodemirrorEditor from './components/CodemirrorEditor'
|
||||||
|
import prettyPrint from 'prettify'
|
||||||
export default {
|
export default {
|
||||||
name: 'App',
|
name: 'App',
|
||||||
components: {
|
components: {
|
||||||
@ -21,6 +22,12 @@ export default {
|
|||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.loading = false
|
this.loading = false
|
||||||
}, 200)
|
}, 200)
|
||||||
|
window.console
|
||||||
|
&& window.console.log
|
||||||
|
&& (console.log("Think big, train fast, learn deep. See https://github.com/yanglbme"))
|
||||||
|
setTimeout(() => {
|
||||||
|
document.body.addEventListener('load', prettyPrint())
|
||||||
|
}, 2000)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -148,6 +148,7 @@ import DEFAULT_CSS_CONTENT from '../scripts/themes/default-theme-css'
|
|||||||
|
|
||||||
require('codemirror/mode/javascript/javascript')
|
require('codemirror/mode/javascript/javascript')
|
||||||
import '../scripts/closebrackets'
|
import '../scripts/closebrackets'
|
||||||
|
import $ from 'jquery'
|
||||||
export default {
|
export default {
|
||||||
data () {
|
data () {
|
||||||
let d = {
|
let d = {
|
||||||
@ -207,29 +208,6 @@ export default {
|
|||||||
autoCloseBrackets: true
|
autoCloseBrackets: true
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
this.cssEditor = CodeMirror.fromTextArea(
|
|
||||||
document.getElementById('cssEditor'), {
|
|
||||||
value: '',
|
|
||||||
mode: 'css',
|
|
||||||
theme: 'style-mirror',
|
|
||||||
lineNumbers: false,
|
|
||||||
lineWrapping: true,
|
|
||||||
matchBrackets: true,
|
|
||||||
autofocus: true,
|
|
||||||
extraKeys: {
|
|
||||||
'Ctrl-F': function autoFormat (editor) {
|
|
||||||
const totalLines = editor.lineCount()
|
|
||||||
editor.autoFormatRange({ line: 0, ch: 0 }, { line: totalLines })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
// 自动提示
|
|
||||||
this.cssEditor.on('keyup', (cm, e) => {
|
|
||||||
if ((e.keyCode >= 65 && e.keyCode <= 90) || e.keyCode === 189) {
|
|
||||||
cm.showHint(e)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
this.editor.on('change', (cm, e) => {
|
this.editor.on('change', (cm, e) => {
|
||||||
this.refresh()
|
this.refresh()
|
||||||
this.saveEditorContent(this.editor, '__editor_content')
|
this.saveEditorContent(this.editor, '__editor_content')
|
||||||
@ -263,13 +241,10 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
this.cssEditor.on('update', (instance) => {
|
|
||||||
this.cssChanged()
|
|
||||||
this.saveEditorContent(this.cssEditor, '__css_content')
|
|
||||||
})
|
|
||||||
// 如果有编辑器内容被保存则读取,否则加载默认内容
|
// 如果有编辑器内容被保存则读取,否则加载默认内容
|
||||||
this.loadLocalStorage(this.editor, '__editor_content', DEFAULT_CONTENT)
|
this.loadLocalStorage(this.editor, '__editor_content', DEFAULT_CONTENT)
|
||||||
this.loadLocalStorage(this.cssEditor, '__css_content', DEFAULT_CSS_CONTENT)
|
|
||||||
})
|
})
|
||||||
this.wxRenderer = new WxRenderer({
|
this.wxRenderer = new WxRenderer({
|
||||||
theme: setColor(this.currentColor),
|
theme: setColor(this.currentColor),
|
||||||
@ -279,6 +254,36 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
initCssEditor() {
|
||||||
|
this.cssEditor = CodeMirror.fromTextArea(
|
||||||
|
document.getElementById('cssEditor'), {
|
||||||
|
value: DEFAULT_CSS_CONTENT,
|
||||||
|
mode: 'css',
|
||||||
|
theme: 'style-mirror',
|
||||||
|
lineNumbers: false,
|
||||||
|
lineWrapping: true,
|
||||||
|
matchBrackets: true,
|
||||||
|
autofocus: true,
|
||||||
|
extraKeys: {
|
||||||
|
'Ctrl-F': function autoFormat (editor) {
|
||||||
|
const totalLines = editor.lineCount()
|
||||||
|
editor.autoFormatRange({ line: 0, ch: 0 }, { line: totalLines })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
// 自动提示
|
||||||
|
this.cssEditor.on('keyup', (cm, e) => {
|
||||||
|
if ((e.keyCode >= 65 && e.keyCode <= 90) || e.keyCode === 189) {
|
||||||
|
cm.showHint(e)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.cssEditor.on('update', (instance) => {
|
||||||
|
this.cssChanged()
|
||||||
|
this.saveEditorContent(this.cssEditor, '__css_content')
|
||||||
|
})
|
||||||
|
this.loadLocalStorage(this.cssEditor, '__css_content', DEFAULT_CSS_CONTENT)
|
||||||
|
},
|
||||||
renderWeChat (source) {
|
renderWeChat (source) {
|
||||||
let output = marked(source, { renderer: this.wxRenderer.getRenderer(this.status) })
|
let output = marked(source, { renderer: this.wxRenderer.getRenderer(this.status) })
|
||||||
// 去除第一行的 margin-top
|
// 去除第一行的 margin-top
|
||||||
@ -472,6 +477,7 @@ export default {
|
|||||||
},
|
},
|
||||||
// 自定义CSS样式
|
// 自定义CSS样式
|
||||||
async customStyle () {
|
async customStyle () {
|
||||||
|
this.initCssEditor()
|
||||||
this.showBox = !this.showBox
|
this.showBox = !this.showBox
|
||||||
let flag = await localStorage.getItem('__css_content')
|
let flag = await localStorage.getItem('__css_content')
|
||||||
if (!flag) {
|
if (!flag) {
|
||||||
|
12
yarn.lock
12
yarn.lock
@ -3166,7 +3166,7 @@ electron-to-chromium@^1.3.322:
|
|||||||
version "1.3.331"
|
version "1.3.331"
|
||||||
resolved "https://registry.npm.taobao.org/electron-to-chromium/download/electron-to-chromium-1.3.331.tgz?cache=0&sync_timestamp=1578704528155&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Felectron-to-chromium%2Fdownload%2Felectron-to-chromium-1.3.331.tgz#6dcf73db9ecd3b518818fdd50a8aa3bc52df8237"
|
resolved "https://registry.npm.taobao.org/electron-to-chromium/download/electron-to-chromium-1.3.331.tgz?cache=0&sync_timestamp=1578704528155&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Felectron-to-chromium%2Fdownload%2Felectron-to-chromium-1.3.331.tgz#6dcf73db9ecd3b518818fdd50a8aa3bc52df8237"
|
||||||
|
|
||||||
element-ui@^2.3.6:
|
element-ui@^2.13.0:
|
||||||
version "2.13.0"
|
version "2.13.0"
|
||||||
resolved "https://registry.npm.taobao.org/element-ui/download/element-ui-2.13.0.tgz#f6bb04e5b0a76ea5f62466044b774407ba4ebd2d"
|
resolved "https://registry.npm.taobao.org/element-ui/download/element-ui-2.13.0.tgz#f6bb04e5b0a76ea5f62466044b774407ba4ebd2d"
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -5177,6 +5177,10 @@ jest@^24.9.0:
|
|||||||
import-local "^2.0.0"
|
import-local "^2.0.0"
|
||||||
jest-cli "^24.9.0"
|
jest-cli "^24.9.0"
|
||||||
|
|
||||||
|
jquery@^3.4.1:
|
||||||
|
version "3.4.1"
|
||||||
|
resolved "https://registry.npm.taobao.org/jquery/download/jquery-3.4.1.tgz#714f1f8d9dde4bdfa55764ba37ef214630d80ef2"
|
||||||
|
|
||||||
js-base64@^2.1.8:
|
js-base64@^2.1.8:
|
||||||
version "2.5.1"
|
version "2.5.1"
|
||||||
resolved "https://registry.npm.taobao.org/js-base64/download/js-base64-2.5.1.tgz#1efa39ef2c5f7980bb1784ade4a8af2de3291121"
|
resolved "https://registry.npm.taobao.org/js-base64/download/js-base64-2.5.1.tgz#1efa39ef2c5f7980bb1784ade4a8af2de3291121"
|
||||||
@ -8270,7 +8274,7 @@ throat@^4.0.0:
|
|||||||
|
|
||||||
throttle-debounce@^1.0.1:
|
throttle-debounce@^1.0.1:
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.npm.taobao.org/throttle-debounce/download/throttle-debounce-1.1.0.tgz#51853da37be68a155cb6e827b3514a3c422e89cd"
|
resolved "https://registry.npm.taobao.org/throttle-debounce/download/throttle-debounce-1.1.0.tgz?cache=0&sync_timestamp=1571657203390&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fthrottle-debounce%2Fdownload%2Fthrottle-debounce-1.1.0.tgz#51853da37be68a155cb6e827b3514a3c422e89cd"
|
||||||
|
|
||||||
through2@^2.0.0:
|
through2@^2.0.0:
|
||||||
version "2.0.5"
|
version "2.0.5"
|
||||||
@ -8645,10 +8649,6 @@ vm-browserify@^1.0.1:
|
|||||||
version "1.1.2"
|
version "1.1.2"
|
||||||
resolved "https://registry.npm.taobao.org/vm-browserify/download/vm-browserify-1.1.2.tgz?cache=0&sync_timestamp=1572870717730&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvm-browserify%2Fdownload%2Fvm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0"
|
resolved "https://registry.npm.taobao.org/vm-browserify/download/vm-browserify-1.1.2.tgz?cache=0&sync_timestamp=1572870717730&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvm-browserify%2Fdownload%2Fvm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0"
|
||||||
|
|
||||||
vue-cli-plugin-element-ui@^1.1.4:
|
|
||||||
version "1.1.4"
|
|
||||||
resolved "https://registry.npm.taobao.org/vue-cli-plugin-element-ui/download/vue-cli-plugin-element-ui-1.1.4.tgz#8307640d85230ba61e15e926879f695ba8eeaedf"
|
|
||||||
|
|
||||||
vue-eslint-parser@^5.0.0:
|
vue-eslint-parser@^5.0.0:
|
||||||
version "5.0.0"
|
version "5.0.0"
|
||||||
resolved "https://registry.npm.taobao.org/vue-eslint-parser/download/vue-eslint-parser-5.0.0.tgz?cache=0&sync_timestamp=1573306368916&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvue-eslint-parser%2Fdownload%2Fvue-eslint-parser-5.0.0.tgz#00f4e4da94ec974b821a26ff0ed0f7a78402b8a1"
|
resolved "https://registry.npm.taobao.org/vue-eslint-parser/download/vue-eslint-parser-5.0.0.tgz?cache=0&sync_timestamp=1573306368916&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvue-eslint-parser%2Fdownload%2Fvue-eslint-parser-5.0.0.tgz#00f4e4da94ec974b821a26ff0ed0f7a78402b8a1"
|
||||||
|
Loading…
Reference in New Issue
Block a user