LaravelTest
163 строки · 5.2 Кб
1// CodeMirror, copyright (c) by Marijn Haverbeke and others
2// Distributed under an MIT license: https://codemirror.net/LICENSE
3
4(function(mod) {5if (typeof exports == "object" && typeof module == "object") // CommonJS6mod(require("../../lib/codemirror"), require("./foldcode"));7else if (typeof define == "function" && define.amd) // AMD8define(["../../lib/codemirror", "./foldcode"], mod);9else // Plain browser env10mod(CodeMirror);11})(function(CodeMirror) {12"use strict";13
14CodeMirror.defineOption("foldGutter", false, function(cm, val, old) {15if (old && old != CodeMirror.Init) {16cm.clearGutter(cm.state.foldGutter.options.gutter);17cm.state.foldGutter = null;18cm.off("gutterClick", onGutterClick);19cm.off("changes", onChange);20cm.off("viewportChange", onViewportChange);21cm.off("fold", onFold);22cm.off("unfold", onFold);23cm.off("swapDoc", onChange);24}25if (val) {26cm.state.foldGutter = new State(parseOptions(val));27updateInViewport(cm);28cm.on("gutterClick", onGutterClick);29cm.on("changes", onChange);30cm.on("viewportChange", onViewportChange);31cm.on("fold", onFold);32cm.on("unfold", onFold);33cm.on("swapDoc", onChange);34}35});36
37var Pos = CodeMirror.Pos;38
39function State(options) {40this.options = options;41this.from = this.to = 0;42}43
44function parseOptions(opts) {45if (opts === true) opts = {};46if (opts.gutter == null) opts.gutter = "CodeMirror-foldgutter";47if (opts.indicatorOpen == null) opts.indicatorOpen = "CodeMirror-foldgutter-open";48if (opts.indicatorFolded == null) opts.indicatorFolded = "CodeMirror-foldgutter-folded";49return opts;50}51
52function isFolded(cm, line) {53var marks = cm.findMarks(Pos(line, 0), Pos(line + 1, 0));54for (var i = 0; i < marks.length; ++i) {55if (marks[i].__isFold) {56var fromPos = marks[i].find(-1);57if (fromPos && fromPos.line === line)58return marks[i];59}60}61}62
63function marker(spec) {64if (typeof spec == "string") {65var elt = document.createElement("div");66elt.className = spec + " CodeMirror-guttermarker-subtle";67return elt;68} else {69return spec.cloneNode(true);70}71}72
73function updateFoldInfo(cm, from, to) {74var opts = cm.state.foldGutter.options, cur = from - 1;75var minSize = cm.foldOption(opts, "minFoldSize");76var func = cm.foldOption(opts, "rangeFinder");77// we can reuse the built-in indicator element if its className matches the new state78var clsFolded = typeof opts.indicatorFolded == "string" && classTest(opts.indicatorFolded);79var clsOpen = typeof opts.indicatorOpen == "string" && classTest(opts.indicatorOpen);80cm.eachLine(from, to, function(line) {81++cur;82var mark = null;83var old = line.gutterMarkers;84if (old) old = old[opts.gutter];85if (isFolded(cm, cur)) {86if (clsFolded && old && clsFolded.test(old.className)) return;87mark = marker(opts.indicatorFolded);88} else {89var pos = Pos(cur, 0);90var range = func && func(cm, pos);91if (range && range.to.line - range.from.line >= minSize) {92if (clsOpen && old && clsOpen.test(old.className)) return;93mark = marker(opts.indicatorOpen);94}95}96if (!mark && !old) return;97cm.setGutterMarker(line, opts.gutter, mark);98});99}100
101// copied from CodeMirror/src/util/dom.js102function classTest(cls) { return new RegExp("(^|\\s)" + cls + "(?:$|\\s)\\s*") }103
104function updateInViewport(cm) {105var vp = cm.getViewport(), state = cm.state.foldGutter;106if (!state) return;107cm.operation(function() {108updateFoldInfo(cm, vp.from, vp.to);109});110state.from = vp.from; state.to = vp.to;111}112
113function onGutterClick(cm, line, gutter) {114var state = cm.state.foldGutter;115if (!state) return;116var opts = state.options;117if (gutter != opts.gutter) return;118var folded = isFolded(cm, line);119if (folded) folded.clear();120else cm.foldCode(Pos(line, 0), opts);121}122
123function onChange(cm) {124var state = cm.state.foldGutter;125if (!state) return;126var opts = state.options;127state.from = state.to = 0;128clearTimeout(state.changeUpdate);129state.changeUpdate = setTimeout(function() { updateInViewport(cm); }, opts.foldOnChangeTimeSpan || 600);130}131
132function onViewportChange(cm) {133var state = cm.state.foldGutter;134if (!state) return;135var opts = state.options;136clearTimeout(state.changeUpdate);137state.changeUpdate = setTimeout(function() {138var vp = cm.getViewport();139if (state.from == state.to || vp.from - state.to > 20 || state.from - vp.to > 20) {140updateInViewport(cm);141} else {142cm.operation(function() {143if (vp.from < state.from) {144updateFoldInfo(cm, vp.from, state.from);145state.from = vp.from;146}147if (vp.to > state.to) {148updateFoldInfo(cm, state.to, vp.to);149state.to = vp.to;150}151});152}153}, opts.updateViewportTimeSpan || 400);154}155
156function onFold(cm, from) {157var state = cm.state.foldGutter;158if (!state) return;159var line = from.line;160if (line >= state.from && line < state.to)161updateFoldInfo(cm, line, line + 1);162}163});164