From 0336f84a831671f0555d05c97a00b21dc2ca092d Mon Sep 17 00:00:00 2001
From: Harvey Kandola
Date: Mon, 18 Dec 2017 13:10:51 +0000
Subject: [PATCH] CodeMirror dependency upgraded to v5.32.0
For handling Markdown and Code section types
---
.../components/section/code/type-editor.js | 2 +-
gui/app/styles/section/code.scss | 29 +-
.../codemirror/addon/comment/comment.js | 12 +-
.../addon/comment/continuecomment.js | 35 +-
gui/public/codemirror/addon/dialog/dialog.css | 0
gui/public/codemirror/addon/dialog/dialog.js | 0
.../codemirror/addon/display/autorefresh.js | 0
.../codemirror/addon/display/fullscreen.css | 0
.../codemirror/addon/display/fullscreen.js | 0
gui/public/codemirror/addon/display/panel.js | 2 +-
.../codemirror/addon/display/placeholder.js | 0
gui/public/codemirror/addon/display/rulers.js | 0
.../codemirror/addon/edit/closebrackets.js | 36 +-
gui/public/codemirror/addon/edit/closetag.js | 0
.../codemirror/addon/edit/continuelist.js | 46 +-
.../codemirror/addon/edit/matchbrackets.js | 30 +-
gui/public/codemirror/addon/edit/matchtags.js | 0
.../codemirror/addon/edit/trailingspace.js | 0
.../codemirror/addon/fold/brace-fold.js | 0
.../codemirror/addon/fold/comment-fold.js | 0
gui/public/codemirror/addon/fold/foldcode.js | 2 +
.../codemirror/addon/fold/foldgutter.css | 0
.../codemirror/addon/fold/foldgutter.js | 0
.../codemirror/addon/fold/indent-fold.js | 2 +-
.../codemirror/addon/fold/markdown-fold.js | 0
gui/public/codemirror/addon/fold/xml-fold.js | 4 +-
.../codemirror/addon/hint/anyword-hint.js | 0
gui/public/codemirror/addon/hint/css-hint.js | 0
gui/public/codemirror/addon/hint/html-hint.js | 0
.../codemirror/addon/hint/javascript-hint.js | 0
.../codemirror/addon/hint/show-hint.css | 0
gui/public/codemirror/addon/hint/show-hint.js | 8 +-
gui/public/codemirror/addon/hint/sql-hint.js | 47 +-
gui/public/codemirror/addon/hint/xml-hint.js | 0
.../addon/lint/coffeescript-lint.js | 6 +
gui/public/codemirror/addon/lint/css-lint.js | 11 +-
gui/public/codemirror/addon/lint/html-lint.js | 13 +-
.../codemirror/addon/lint/javascript-lint.js | 7 +-
gui/public/codemirror/addon/lint/json-lint.js | 6 +
gui/public/codemirror/addon/lint/lint.css | 0
gui/public/codemirror/addon/lint/lint.js | 19 +-
gui/public/codemirror/addon/lint/yaml-lint.js | 17 +-
gui/public/codemirror/addon/merge/merge.css | 0
gui/public/codemirror/addon/merge/merge.js | 51 +-
gui/public/codemirror/addon/mode/loadmode.js | 0
gui/public/codemirror/addon/mode/multiplex.js | 0
.../codemirror/addon/mode/multiplex_test.js | 0
gui/public/codemirror/addon/mode/overlay.js | 0
gui/public/codemirror/addon/mode/simple.js | 13 +-
.../codemirror/addon/runmode/colorize.js | 0
.../addon/runmode/runmode-standalone.js | 3 +-
.../codemirror/addon/runmode/runmode.js | 0
.../codemirror/addon/runmode/runmode.node.js | 26 +-
.../addon/scroll/annotatescrollbar.js | 0
.../codemirror/addon/scroll/scrollpastend.js | 0
.../addon/scroll/simplescrollbars.css | 0
.../addon/scroll/simplescrollbars.js | 0
.../codemirror/addon/search/jump-to-line.js | 0
.../addon/search/match-highlighter.js | 0
.../addon/search/matchesonscrollbar.css | 0
.../addon/search/matchesonscrollbar.js | 0
gui/public/codemirror/addon/search/search.js | 14 +-
.../codemirror/addon/search/searchcursor.js | 404 ++--
.../codemirror/addon/selection/active-line.js | 0
.../addon/selection/mark-selection.js | 7 +-
.../addon/selection/selection-pointer.js | 0
gui/public/codemirror/addon/tern/tern.css | 0
gui/public/codemirror/addon/tern/tern.js | 38 +-
gui/public/codemirror/addon/tern/worker.js | 0
gui/public/codemirror/addon/wrap/hardwrap.js | 0
gui/public/codemirror/lib/codemirror.js | 2106 ++++++++++-------
gui/public/codemirror/mode/apl/apl.js | 0
gui/public/codemirror/mode/apl/index.html | 0
.../codemirror/mode/asciiarmor/asciiarmor.js | 1 +
.../codemirror/mode/asciiarmor/index.html | 2 +-
gui/public/codemirror/mode/asn.1/asn.1.js | 0
gui/public/codemirror/mode/asn.1/index.html | 0
.../codemirror/mode/asterisk/asterisk.js | 0
.../codemirror/mode/asterisk/index.html | 0
.../codemirror/mode/brainfuck/brainfuck.js | 0
.../codemirror/mode/brainfuck/index.html | 0
gui/public/codemirror/mode/clike/clike.js | 30 +-
gui/public/codemirror/mode/clike/index.html | 0
gui/public/codemirror/mode/clike/scala.html | 0
gui/public/codemirror/mode/clike/test.js | 16 +-
gui/public/codemirror/mode/clojure/clojure.js | 0
gui/public/codemirror/mode/clojure/index.html | 0
gui/public/codemirror/mode/cmake/cmake.js | 0
gui/public/codemirror/mode/cmake/index.html | 0
gui/public/codemirror/mode/cobol/cobol.js | 0
gui/public/codemirror/mode/cobol/index.html | 0
.../mode/coffeescript/coffeescript.js | 4 +
.../codemirror/mode/coffeescript/index.html | 2 +-
.../codemirror/mode/commonlisp/commonlisp.js | 0
.../codemirror/mode/commonlisp/index.html | 0
gui/public/codemirror/mode/crystal/crystal.js | 0
gui/public/codemirror/mode/crystal/index.html | 0
gui/public/codemirror/mode/css/css.js | 21 +-
gui/public/codemirror/mode/css/gss.html | 0
gui/public/codemirror/mode/css/gss_test.js | 0
gui/public/codemirror/mode/css/index.html | 0
gui/public/codemirror/mode/css/less.html | 0
gui/public/codemirror/mode/css/less_test.js | 0
gui/public/codemirror/mode/css/scss.html | 0
gui/public/codemirror/mode/css/scss_test.js | 0
gui/public/codemirror/mode/css/test.js | 6 +
gui/public/codemirror/mode/cypher/cypher.js | 0
gui/public/codemirror/mode/cypher/index.html | 0
gui/public/codemirror/mode/cypher/test.js | 0
gui/public/codemirror/mode/d/d.js | 2 +-
gui/public/codemirror/mode/d/index.html | 0
gui/public/codemirror/mode/d/test.js | 11 +
gui/public/codemirror/mode/dart/dart.js | 4 +-
gui/public/codemirror/mode/dart/index.html | 0
gui/public/codemirror/mode/diff/diff.js | 0
gui/public/codemirror/mode/diff/index.html | 0
gui/public/codemirror/mode/django/django.js | 0
gui/public/codemirror/mode/django/index.html | 0
gui/public/codemirror/mode/dtd/dtd.js | 0
gui/public/codemirror/mode/dtd/index.html | 0
gui/public/codemirror/mode/dylan/dylan.js | 0
gui/public/codemirror/mode/dylan/index.html | 0
gui/public/codemirror/mode/dylan/test.js | 0
gui/public/codemirror/mode/ebnf/ebnf.js | 0
gui/public/codemirror/mode/ebnf/index.html | 0
gui/public/codemirror/mode/ecl/ecl.js | 0
gui/public/codemirror/mode/ecl/index.html | 0
gui/public/codemirror/mode/eiffel/eiffel.js | 0
gui/public/codemirror/mode/eiffel/index.html | 0
gui/public/codemirror/mode/elm/elm.js | 2 +-
gui/public/codemirror/mode/elm/index.html | 0
gui/public/codemirror/mode/erlang/erlang.js | 0
gui/public/codemirror/mode/erlang/index.html | 0
gui/public/codemirror/mode/factor/factor.js | 50 +-
gui/public/codemirror/mode/factor/index.html | 0
gui/public/codemirror/mode/fcl/fcl.js | 0
gui/public/codemirror/mode/fcl/index.html | 0
gui/public/codemirror/mode/forth/forth.js | 0
gui/public/codemirror/mode/forth/index.html | 0
gui/public/codemirror/mode/fortran/fortran.js | 0
gui/public/codemirror/mode/fortran/index.html | 0
gui/public/codemirror/mode/gas/gas.js | 0
gui/public/codemirror/mode/gas/index.html | 0
gui/public/codemirror/mode/gfm/gfm.js | 7 +-
gui/public/codemirror/mode/gfm/index.html | 49 +-
gui/public/codemirror/mode/gfm/test.js | 92 +-
gui/public/codemirror/mode/gherkin/gherkin.js | 0
gui/public/codemirror/mode/gherkin/index.html | 0
gui/public/codemirror/mode/go/go.js | 4 +-
gui/public/codemirror/mode/go/index.html | 0
gui/public/codemirror/mode/groovy/groovy.js | 4 +-
gui/public/codemirror/mode/groovy/index.html | 0
gui/public/codemirror/mode/haml/haml.js | 0
gui/public/codemirror/mode/haml/index.html | 0
gui/public/codemirror/mode/haml/test.js | 0
.../codemirror/mode/handlebars/handlebars.js | 0
.../codemirror/mode/handlebars/index.html | 0
.../mode/haskell-literate/haskell-literate.js | 0
.../mode/haskell-literate/index.html | 0
gui/public/codemirror/mode/haskell/haskell.js | 0
gui/public/codemirror/mode/haskell/index.html | 0
gui/public/codemirror/mode/haxe/haxe.js | 2 +-
gui/public/codemirror/mode/haxe/index.html | 0
.../mode/htmlembedded/htmlembedded.js | 0
.../codemirror/mode/htmlembedded/index.html | 0
.../codemirror/mode/htmlmixed/htmlmixed.js | 4 +-
.../codemirror/mode/htmlmixed/index.html | 2 +-
gui/public/codemirror/mode/http/http.js | 0
gui/public/codemirror/mode/http/index.html | 0
gui/public/codemirror/mode/idl/idl.js | 0
gui/public/codemirror/mode/idl/index.html | 0
gui/public/codemirror/mode/index.html | 2 +-
.../codemirror/mode/javascript/index.html | 0
.../codemirror/mode/javascript/javascript.js | 169 +-
.../codemirror/mode/javascript/json-ld.html | 0
gui/public/codemirror/mode/javascript/test.js | 138 +-
.../mode/javascript/typescript.html | 0
gui/public/codemirror/mode/jinja2/index.html | 0
gui/public/codemirror/mode/jinja2/jinja2.js | 2 +-
gui/public/codemirror/mode/jsx/index.html | 0
gui/public/codemirror/mode/jsx/jsx.js | 0
gui/public/codemirror/mode/jsx/test.js | 19 +
gui/public/codemirror/mode/julia/index.html | 0
gui/public/codemirror/mode/julia/julia.js | 84 +-
.../codemirror/mode/livescript/index.html | 0
.../codemirror/mode/livescript/livescript.js | 0
gui/public/codemirror/mode/lua/index.html | 0
gui/public/codemirror/mode/lua/lua.js | 0
.../codemirror/mode/markdown/index.html | 90 +-
.../codemirror/mode/markdown/markdown.js | 335 +--
gui/public/codemirror/mode/markdown/test.js | 390 ++-
.../codemirror/mode/mathematica/index.html | 0
.../mode/mathematica/mathematica.js | 0
gui/public/codemirror/mode/mbox/index.html | 0
gui/public/codemirror/mode/mbox/mbox.js | 0
gui/public/codemirror/mode/meta.js | 16 +-
gui/public/codemirror/mode/mirc/index.html | 0
gui/public/codemirror/mode/mirc/mirc.js | 2 +-
gui/public/codemirror/mode/mllike/index.html | 0
gui/public/codemirror/mode/mllike/mllike.js | 0
.../codemirror/mode/modelica/index.html | 0
.../codemirror/mode/modelica/modelica.js | 0
gui/public/codemirror/mode/mscgen/index.html | 0
gui/public/codemirror/mode/mscgen/mscgen.js | 0
.../codemirror/mode/mscgen/mscgen_test.js | 0
.../codemirror/mode/mscgen/msgenny_test.js | 0
gui/public/codemirror/mode/mscgen/xu_test.js | 0
gui/public/codemirror/mode/mumps/index.html | 0
gui/public/codemirror/mode/mumps/mumps.js | 0
gui/public/codemirror/mode/nginx/index.html | 0
gui/public/codemirror/mode/nginx/nginx.js | 0
gui/public/codemirror/mode/nsis/index.html | 0
gui/public/codemirror/mode/nsis/nsis.js | 8 +-
.../codemirror/mode/ntriples/index.html | 33 +-
.../codemirror/mode/ntriples/ntriples.js | 15 +-
gui/public/codemirror/mode/octave/index.html | 0
gui/public/codemirror/mode/octave/octave.js | 4 +-
gui/public/codemirror/mode/oz/index.html | 0
gui/public/codemirror/mode/oz/oz.js | 2 +-
gui/public/codemirror/mode/pascal/index.html | 0
gui/public/codemirror/mode/pascal/pascal.js | 0
gui/public/codemirror/mode/pegjs/index.html | 0
gui/public/codemirror/mode/pegjs/pegjs.js | 0
gui/public/codemirror/mode/perl/index.html | 0
gui/public/codemirror/mode/perl/perl.js | 0
gui/public/codemirror/mode/php/index.html | 0
gui/public/codemirror/mode/php/php.js | 2 +-
gui/public/codemirror/mode/php/test.js | 0
gui/public/codemirror/mode/pig/index.html | 0
gui/public/codemirror/mode/pig/pig.js | 0
.../codemirror/mode/powershell/index.html | 0
.../codemirror/mode/powershell/powershell.js | 4 +-
gui/public/codemirror/mode/powershell/test.js | 0
.../codemirror/mode/properties/index.html | 0
.../codemirror/mode/properties/properties.js | 0
.../codemirror/mode/protobuf/index.html | 42 +-
.../codemirror/mode/protobuf/protobuf.js | 3 +-
gui/public/codemirror/mode/pug/index.html | 0
gui/public/codemirror/mode/pug/pug.js | 0
gui/public/codemirror/mode/puppet/index.html | 0
gui/public/codemirror/mode/puppet/puppet.js | 0
gui/public/codemirror/mode/python/index.html | 0
gui/public/codemirror/mode/python/python.js | 26 +-
gui/public/codemirror/mode/python/test.js | 5 +
gui/public/codemirror/mode/q/index.html | 0
gui/public/codemirror/mode/q/q.js | 14 +-
gui/public/codemirror/mode/r/index.html | 0
gui/public/codemirror/mode/r/r.js | 28 +-
.../codemirror/mode/rpm/changes/index.html | 0
gui/public/codemirror/mode/rpm/index.html | 0
gui/public/codemirror/mode/rpm/rpm.js | 0
gui/public/codemirror/mode/rst/index.html | 0
gui/public/codemirror/mode/rst/rst.js | 0
gui/public/codemirror/mode/ruby/index.html | 0
gui/public/codemirror/mode/ruby/ruby.js | 45 +-
gui/public/codemirror/mode/ruby/test.js | 2 +
gui/public/codemirror/mode/rust/index.html | 0
gui/public/codemirror/mode/rust/rust.js | 1 +
gui/public/codemirror/mode/rust/test.js | 0
gui/public/codemirror/mode/sas/index.html | 0
gui/public/codemirror/mode/sas/sas.js | 27 +-
gui/public/codemirror/mode/sass/index.html | 0
gui/public/codemirror/mode/sass/sass.js | 2 +-
gui/public/codemirror/mode/sass/test.js | 0
gui/public/codemirror/mode/scheme/index.html | 0
gui/public/codemirror/mode/scheme/scheme.js | 2 +-
gui/public/codemirror/mode/shell/index.html | 2 +-
gui/public/codemirror/mode/shell/shell.js | 25 +-
gui/public/codemirror/mode/shell/test.js | 3 +
gui/public/codemirror/mode/sieve/index.html | 0
gui/public/codemirror/mode/sieve/sieve.js | 2 +-
gui/public/codemirror/mode/slim/index.html | 0
gui/public/codemirror/mode/slim/slim.js | 0
gui/public/codemirror/mode/slim/test.js | 0
.../codemirror/mode/smalltalk/index.html | 0
.../codemirror/mode/smalltalk/smalltalk.js | 0
gui/public/codemirror/mode/smarty/index.html | 0
gui/public/codemirror/mode/smarty/smarty.js | 0
gui/public/codemirror/mode/solr/index.html | 0
gui/public/codemirror/mode/solr/solr.js | 4 +-
gui/public/codemirror/mode/soy/index.html | 0
gui/public/codemirror/mode/soy/soy.js | 132 +-
gui/public/codemirror/mode/soy/test.js | 31 +
gui/public/codemirror/mode/sparql/index.html | 0
gui/public/codemirror/mode/sparql/sparql.js | 0
.../codemirror/mode/spreadsheet/index.html | 0
.../mode/spreadsheet/spreadsheet.js | 0
gui/public/codemirror/mode/sql/index.html | 10 +-
gui/public/codemirror/mode/sql/sql.js | 127 +-
gui/public/codemirror/mode/stex/index.html | 0
gui/public/codemirror/mode/stex/stex.js | 0
gui/public/codemirror/mode/stex/test.js | 0
gui/public/codemirror/mode/stylus/index.html | 0
gui/public/codemirror/mode/stylus/stylus.js | 10 +-
gui/public/codemirror/mode/swift/index.html | 0
gui/public/codemirror/mode/swift/swift.js | 0
gui/public/codemirror/mode/swift/test.js | 0
gui/public/codemirror/mode/tcl/index.html | 0
gui/public/codemirror/mode/tcl/tcl.js | 0
gui/public/codemirror/mode/textile/index.html | 0
gui/public/codemirror/mode/textile/test.js | 0
gui/public/codemirror/mode/textile/textile.js | 2 +-
.../codemirror/mode/tiddlywiki/index.html | 0
.../codemirror/mode/tiddlywiki/tiddlywiki.css | 0
.../codemirror/mode/tiddlywiki/tiddlywiki.js | 0
gui/public/codemirror/mode/tiki/index.html | 0
gui/public/codemirror/mode/tiki/tiki.css | 0
gui/public/codemirror/mode/tiki/tiki.js | 16 +-
gui/public/codemirror/mode/toml/index.html | 0
gui/public/codemirror/mode/toml/toml.js | 0
gui/public/codemirror/mode/tornado/index.html | 0
gui/public/codemirror/mode/tornado/tornado.js | 0
gui/public/codemirror/mode/troff/index.html | 0
gui/public/codemirror/mode/troff/troff.js | 0
.../codemirror/mode/ttcn-cfg/index.html | 0
.../codemirror/mode/ttcn-cfg/ttcn-cfg.js | 0
gui/public/codemirror/mode/ttcn/index.html | 0
gui/public/codemirror/mode/ttcn/ttcn.js | 0
gui/public/codemirror/mode/turtle/index.html | 0
gui/public/codemirror/mode/turtle/turtle.js | 0
gui/public/codemirror/mode/twig/index.html | 0
gui/public/codemirror/mode/twig/twig.js | 2 +-
gui/public/codemirror/mode/vb/index.html | 79 +-
gui/public/codemirror/mode/vb/vb.js | 1 -
.../codemirror/mode/vbscript/index.html | 0
.../codemirror/mode/vbscript/vbscript.js | 0
.../codemirror/mode/velocity/index.html | 0
.../codemirror/mode/velocity/velocity.js | 0
gui/public/codemirror/mode/verilog/index.html | 0
gui/public/codemirror/mode/verilog/test.js | 0
gui/public/codemirror/mode/verilog/verilog.js | 4 +-
gui/public/codemirror/mode/vhdl/index.html | 0
gui/public/codemirror/mode/vhdl/vhdl.js | 0
gui/public/codemirror/mode/vue/index.html | 0
gui/public/codemirror/mode/vue/vue.js | 11 +-
gui/public/codemirror/mode/webidl/index.html | 0
gui/public/codemirror/mode/webidl/webidl.js | 0
gui/public/codemirror/mode/xml/index.html | 0
gui/public/codemirror/mode/xml/test.js | 0
gui/public/codemirror/mode/xml/xml.js | 0
gui/public/codemirror/mode/xquery/index.html | 0
gui/public/codemirror/mode/xquery/test.js | 10 +-
gui/public/codemirror/mode/xquery/xquery.js | 57 +-
gui/public/codemirror/mode/yacas/index.html | 0
gui/public/codemirror/mode/yacas/yacas.js | 2 +-
.../mode/yaml-frontmatter/index.html | 0
.../mode/yaml-frontmatter/yaml-frontmatter.js | 0
gui/public/codemirror/mode/yaml/index.html | 0
gui/public/codemirror/mode/yaml/yaml.js | 0
gui/public/codemirror/mode/z80/index.html | 0
gui/public/codemirror/mode/z80/z80.js | 0
351 files changed, 3408 insertions(+), 1945 deletions(-)
mode change 100755 => 100644 gui/public/codemirror/addon/comment/comment.js
mode change 100755 => 100644 gui/public/codemirror/addon/comment/continuecomment.js
mode change 100755 => 100644 gui/public/codemirror/addon/dialog/dialog.css
mode change 100755 => 100644 gui/public/codemirror/addon/dialog/dialog.js
mode change 100755 => 100644 gui/public/codemirror/addon/display/autorefresh.js
mode change 100755 => 100644 gui/public/codemirror/addon/display/fullscreen.css
mode change 100755 => 100644 gui/public/codemirror/addon/display/fullscreen.js
mode change 100755 => 100644 gui/public/codemirror/addon/display/panel.js
mode change 100755 => 100644 gui/public/codemirror/addon/display/placeholder.js
mode change 100755 => 100644 gui/public/codemirror/addon/display/rulers.js
mode change 100755 => 100644 gui/public/codemirror/addon/edit/closebrackets.js
mode change 100755 => 100644 gui/public/codemirror/addon/edit/closetag.js
mode change 100755 => 100644 gui/public/codemirror/addon/edit/continuelist.js
mode change 100755 => 100644 gui/public/codemirror/addon/edit/matchbrackets.js
mode change 100755 => 100644 gui/public/codemirror/addon/edit/matchtags.js
mode change 100755 => 100644 gui/public/codemirror/addon/edit/trailingspace.js
mode change 100755 => 100644 gui/public/codemirror/addon/fold/brace-fold.js
mode change 100755 => 100644 gui/public/codemirror/addon/fold/comment-fold.js
mode change 100755 => 100644 gui/public/codemirror/addon/fold/foldcode.js
mode change 100755 => 100644 gui/public/codemirror/addon/fold/foldgutter.css
mode change 100755 => 100644 gui/public/codemirror/addon/fold/foldgutter.js
mode change 100755 => 100644 gui/public/codemirror/addon/fold/indent-fold.js
mode change 100755 => 100644 gui/public/codemirror/addon/fold/markdown-fold.js
mode change 100755 => 100644 gui/public/codemirror/addon/fold/xml-fold.js
mode change 100755 => 100644 gui/public/codemirror/addon/hint/anyword-hint.js
mode change 100755 => 100644 gui/public/codemirror/addon/hint/css-hint.js
mode change 100755 => 100644 gui/public/codemirror/addon/hint/html-hint.js
mode change 100755 => 100644 gui/public/codemirror/addon/hint/javascript-hint.js
mode change 100755 => 100644 gui/public/codemirror/addon/hint/show-hint.css
mode change 100755 => 100644 gui/public/codemirror/addon/hint/show-hint.js
mode change 100755 => 100644 gui/public/codemirror/addon/hint/sql-hint.js
mode change 100755 => 100644 gui/public/codemirror/addon/hint/xml-hint.js
mode change 100755 => 100644 gui/public/codemirror/addon/lint/coffeescript-lint.js
mode change 100755 => 100644 gui/public/codemirror/addon/lint/css-lint.js
mode change 100755 => 100644 gui/public/codemirror/addon/lint/html-lint.js
mode change 100755 => 100644 gui/public/codemirror/addon/lint/javascript-lint.js
mode change 100755 => 100644 gui/public/codemirror/addon/lint/json-lint.js
mode change 100755 => 100644 gui/public/codemirror/addon/lint/lint.css
mode change 100755 => 100644 gui/public/codemirror/addon/lint/lint.js
mode change 100755 => 100644 gui/public/codemirror/addon/lint/yaml-lint.js
mode change 100755 => 100644 gui/public/codemirror/addon/merge/merge.css
mode change 100755 => 100644 gui/public/codemirror/addon/merge/merge.js
mode change 100755 => 100644 gui/public/codemirror/addon/mode/loadmode.js
mode change 100755 => 100644 gui/public/codemirror/addon/mode/multiplex.js
mode change 100755 => 100644 gui/public/codemirror/addon/mode/multiplex_test.js
mode change 100755 => 100644 gui/public/codemirror/addon/mode/overlay.js
mode change 100755 => 100644 gui/public/codemirror/addon/mode/simple.js
mode change 100755 => 100644 gui/public/codemirror/addon/runmode/colorize.js
mode change 100755 => 100644 gui/public/codemirror/addon/runmode/runmode-standalone.js
mode change 100755 => 100644 gui/public/codemirror/addon/runmode/runmode.js
mode change 100755 => 100644 gui/public/codemirror/addon/runmode/runmode.node.js
mode change 100755 => 100644 gui/public/codemirror/addon/scroll/annotatescrollbar.js
mode change 100755 => 100644 gui/public/codemirror/addon/scroll/scrollpastend.js
mode change 100755 => 100644 gui/public/codemirror/addon/scroll/simplescrollbars.css
mode change 100755 => 100644 gui/public/codemirror/addon/scroll/simplescrollbars.js
mode change 100755 => 100644 gui/public/codemirror/addon/search/jump-to-line.js
mode change 100755 => 100644 gui/public/codemirror/addon/search/match-highlighter.js
mode change 100755 => 100644 gui/public/codemirror/addon/search/matchesonscrollbar.css
mode change 100755 => 100644 gui/public/codemirror/addon/search/matchesonscrollbar.js
mode change 100755 => 100644 gui/public/codemirror/addon/search/search.js
mode change 100755 => 100644 gui/public/codemirror/addon/search/searchcursor.js
mode change 100755 => 100644 gui/public/codemirror/addon/selection/active-line.js
mode change 100755 => 100644 gui/public/codemirror/addon/selection/mark-selection.js
mode change 100755 => 100644 gui/public/codemirror/addon/selection/selection-pointer.js
mode change 100755 => 100644 gui/public/codemirror/addon/tern/tern.css
mode change 100755 => 100644 gui/public/codemirror/addon/tern/tern.js
mode change 100755 => 100644 gui/public/codemirror/addon/tern/worker.js
mode change 100755 => 100644 gui/public/codemirror/addon/wrap/hardwrap.js
mode change 100755 => 100644 gui/public/codemirror/mode/apl/apl.js
mode change 100755 => 100644 gui/public/codemirror/mode/apl/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/asciiarmor/asciiarmor.js
mode change 100755 => 100644 gui/public/codemirror/mode/asciiarmor/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/asn.1/asn.1.js
mode change 100755 => 100644 gui/public/codemirror/mode/asn.1/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/asterisk/asterisk.js
mode change 100755 => 100644 gui/public/codemirror/mode/asterisk/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/brainfuck/brainfuck.js
mode change 100755 => 100644 gui/public/codemirror/mode/brainfuck/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/clike/clike.js
mode change 100755 => 100644 gui/public/codemirror/mode/clike/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/clike/scala.html
mode change 100755 => 100644 gui/public/codemirror/mode/clike/test.js
mode change 100755 => 100644 gui/public/codemirror/mode/clojure/clojure.js
mode change 100755 => 100644 gui/public/codemirror/mode/clojure/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/cmake/cmake.js
mode change 100755 => 100644 gui/public/codemirror/mode/cmake/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/cobol/cobol.js
mode change 100755 => 100644 gui/public/codemirror/mode/cobol/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/coffeescript/coffeescript.js
mode change 100755 => 100644 gui/public/codemirror/mode/coffeescript/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/commonlisp/commonlisp.js
mode change 100755 => 100644 gui/public/codemirror/mode/commonlisp/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/crystal/crystal.js
mode change 100755 => 100644 gui/public/codemirror/mode/crystal/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/css/css.js
mode change 100755 => 100644 gui/public/codemirror/mode/css/gss.html
mode change 100755 => 100644 gui/public/codemirror/mode/css/gss_test.js
mode change 100755 => 100644 gui/public/codemirror/mode/css/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/css/less.html
mode change 100755 => 100644 gui/public/codemirror/mode/css/less_test.js
mode change 100755 => 100644 gui/public/codemirror/mode/css/scss.html
mode change 100755 => 100644 gui/public/codemirror/mode/css/scss_test.js
mode change 100755 => 100644 gui/public/codemirror/mode/css/test.js
mode change 100755 => 100644 gui/public/codemirror/mode/cypher/cypher.js
mode change 100755 => 100644 gui/public/codemirror/mode/cypher/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/cypher/test.js
mode change 100755 => 100644 gui/public/codemirror/mode/d/d.js
mode change 100755 => 100644 gui/public/codemirror/mode/d/index.html
create mode 100644 gui/public/codemirror/mode/d/test.js
mode change 100755 => 100644 gui/public/codemirror/mode/dart/dart.js
mode change 100755 => 100644 gui/public/codemirror/mode/dart/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/diff/diff.js
mode change 100755 => 100644 gui/public/codemirror/mode/diff/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/django/django.js
mode change 100755 => 100644 gui/public/codemirror/mode/django/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/dtd/dtd.js
mode change 100755 => 100644 gui/public/codemirror/mode/dtd/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/dylan/dylan.js
mode change 100755 => 100644 gui/public/codemirror/mode/dylan/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/dylan/test.js
mode change 100755 => 100644 gui/public/codemirror/mode/ebnf/ebnf.js
mode change 100755 => 100644 gui/public/codemirror/mode/ebnf/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/ecl/ecl.js
mode change 100755 => 100644 gui/public/codemirror/mode/ecl/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/eiffel/eiffel.js
mode change 100755 => 100644 gui/public/codemirror/mode/eiffel/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/elm/elm.js
mode change 100755 => 100644 gui/public/codemirror/mode/elm/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/erlang/erlang.js
mode change 100755 => 100644 gui/public/codemirror/mode/erlang/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/factor/factor.js
mode change 100755 => 100644 gui/public/codemirror/mode/factor/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/fcl/fcl.js
mode change 100755 => 100644 gui/public/codemirror/mode/fcl/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/forth/forth.js
mode change 100755 => 100644 gui/public/codemirror/mode/forth/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/fortran/fortran.js
mode change 100755 => 100644 gui/public/codemirror/mode/fortran/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/gas/gas.js
mode change 100755 => 100644 gui/public/codemirror/mode/gas/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/gfm/gfm.js
mode change 100755 => 100644 gui/public/codemirror/mode/gfm/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/gfm/test.js
mode change 100755 => 100644 gui/public/codemirror/mode/gherkin/gherkin.js
mode change 100755 => 100644 gui/public/codemirror/mode/gherkin/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/go/go.js
mode change 100755 => 100644 gui/public/codemirror/mode/go/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/groovy/groovy.js
mode change 100755 => 100644 gui/public/codemirror/mode/groovy/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/haml/haml.js
mode change 100755 => 100644 gui/public/codemirror/mode/haml/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/haml/test.js
mode change 100755 => 100644 gui/public/codemirror/mode/handlebars/handlebars.js
mode change 100755 => 100644 gui/public/codemirror/mode/handlebars/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/haskell-literate/haskell-literate.js
mode change 100755 => 100644 gui/public/codemirror/mode/haskell-literate/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/haskell/haskell.js
mode change 100755 => 100644 gui/public/codemirror/mode/haskell/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/haxe/haxe.js
mode change 100755 => 100644 gui/public/codemirror/mode/haxe/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/htmlembedded/htmlembedded.js
mode change 100755 => 100644 gui/public/codemirror/mode/htmlembedded/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/htmlmixed/htmlmixed.js
mode change 100755 => 100644 gui/public/codemirror/mode/htmlmixed/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/http/http.js
mode change 100755 => 100644 gui/public/codemirror/mode/http/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/idl/idl.js
mode change 100755 => 100644 gui/public/codemirror/mode/idl/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/javascript/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/javascript/javascript.js
mode change 100755 => 100644 gui/public/codemirror/mode/javascript/json-ld.html
mode change 100755 => 100644 gui/public/codemirror/mode/javascript/test.js
mode change 100755 => 100644 gui/public/codemirror/mode/javascript/typescript.html
mode change 100755 => 100644 gui/public/codemirror/mode/jinja2/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/jinja2/jinja2.js
mode change 100755 => 100644 gui/public/codemirror/mode/jsx/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/jsx/jsx.js
mode change 100755 => 100644 gui/public/codemirror/mode/jsx/test.js
mode change 100755 => 100644 gui/public/codemirror/mode/julia/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/julia/julia.js
mode change 100755 => 100644 gui/public/codemirror/mode/livescript/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/livescript/livescript.js
mode change 100755 => 100644 gui/public/codemirror/mode/lua/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/lua/lua.js
mode change 100755 => 100644 gui/public/codemirror/mode/markdown/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/markdown/markdown.js
mode change 100755 => 100644 gui/public/codemirror/mode/markdown/test.js
mode change 100755 => 100644 gui/public/codemirror/mode/mathematica/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/mathematica/mathematica.js
mode change 100755 => 100644 gui/public/codemirror/mode/mbox/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/mbox/mbox.js
mode change 100755 => 100644 gui/public/codemirror/mode/meta.js
mode change 100755 => 100644 gui/public/codemirror/mode/mirc/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/mirc/mirc.js
mode change 100755 => 100644 gui/public/codemirror/mode/mllike/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/mllike/mllike.js
mode change 100755 => 100644 gui/public/codemirror/mode/modelica/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/modelica/modelica.js
mode change 100755 => 100644 gui/public/codemirror/mode/mscgen/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/mscgen/mscgen.js
mode change 100755 => 100644 gui/public/codemirror/mode/mscgen/mscgen_test.js
mode change 100755 => 100644 gui/public/codemirror/mode/mscgen/msgenny_test.js
mode change 100755 => 100644 gui/public/codemirror/mode/mscgen/xu_test.js
mode change 100755 => 100644 gui/public/codemirror/mode/mumps/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/mumps/mumps.js
mode change 100755 => 100644 gui/public/codemirror/mode/nginx/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/nginx/nginx.js
mode change 100755 => 100644 gui/public/codemirror/mode/nsis/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/nsis/nsis.js
mode change 100755 => 100644 gui/public/codemirror/mode/ntriples/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/ntriples/ntriples.js
mode change 100755 => 100644 gui/public/codemirror/mode/octave/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/octave/octave.js
mode change 100755 => 100644 gui/public/codemirror/mode/oz/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/oz/oz.js
mode change 100755 => 100644 gui/public/codemirror/mode/pascal/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/pascal/pascal.js
mode change 100755 => 100644 gui/public/codemirror/mode/pegjs/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/pegjs/pegjs.js
mode change 100755 => 100644 gui/public/codemirror/mode/perl/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/perl/perl.js
mode change 100755 => 100644 gui/public/codemirror/mode/php/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/php/php.js
mode change 100755 => 100644 gui/public/codemirror/mode/php/test.js
mode change 100755 => 100644 gui/public/codemirror/mode/pig/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/pig/pig.js
mode change 100755 => 100644 gui/public/codemirror/mode/powershell/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/powershell/powershell.js
mode change 100755 => 100644 gui/public/codemirror/mode/powershell/test.js
mode change 100755 => 100644 gui/public/codemirror/mode/properties/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/properties/properties.js
mode change 100755 => 100644 gui/public/codemirror/mode/protobuf/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/protobuf/protobuf.js
mode change 100755 => 100644 gui/public/codemirror/mode/pug/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/pug/pug.js
mode change 100755 => 100644 gui/public/codemirror/mode/puppet/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/puppet/puppet.js
mode change 100755 => 100644 gui/public/codemirror/mode/python/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/python/python.js
mode change 100755 => 100644 gui/public/codemirror/mode/python/test.js
mode change 100755 => 100644 gui/public/codemirror/mode/q/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/q/q.js
mode change 100755 => 100644 gui/public/codemirror/mode/r/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/r/r.js
mode change 100755 => 100644 gui/public/codemirror/mode/rpm/changes/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/rpm/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/rpm/rpm.js
mode change 100755 => 100644 gui/public/codemirror/mode/rst/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/rst/rst.js
mode change 100755 => 100644 gui/public/codemirror/mode/ruby/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/ruby/ruby.js
mode change 100755 => 100644 gui/public/codemirror/mode/ruby/test.js
mode change 100755 => 100644 gui/public/codemirror/mode/rust/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/rust/rust.js
mode change 100755 => 100644 gui/public/codemirror/mode/rust/test.js
mode change 100755 => 100644 gui/public/codemirror/mode/sas/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/sass/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/sass/sass.js
mode change 100755 => 100644 gui/public/codemirror/mode/sass/test.js
mode change 100755 => 100644 gui/public/codemirror/mode/scheme/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/scheme/scheme.js
mode change 100755 => 100644 gui/public/codemirror/mode/shell/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/shell/shell.js
mode change 100755 => 100644 gui/public/codemirror/mode/shell/test.js
mode change 100755 => 100644 gui/public/codemirror/mode/sieve/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/sieve/sieve.js
mode change 100755 => 100644 gui/public/codemirror/mode/slim/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/slim/slim.js
mode change 100755 => 100644 gui/public/codemirror/mode/slim/test.js
mode change 100755 => 100644 gui/public/codemirror/mode/smalltalk/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/smalltalk/smalltalk.js
mode change 100755 => 100644 gui/public/codemirror/mode/smarty/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/smarty/smarty.js
mode change 100755 => 100644 gui/public/codemirror/mode/solr/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/solr/solr.js
mode change 100755 => 100644 gui/public/codemirror/mode/soy/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/soy/soy.js
mode change 100755 => 100644 gui/public/codemirror/mode/soy/test.js
mode change 100755 => 100644 gui/public/codemirror/mode/sparql/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/sparql/sparql.js
mode change 100755 => 100644 gui/public/codemirror/mode/spreadsheet/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/spreadsheet/spreadsheet.js
mode change 100755 => 100644 gui/public/codemirror/mode/sql/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/sql/sql.js
mode change 100755 => 100644 gui/public/codemirror/mode/stex/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/stex/stex.js
mode change 100755 => 100644 gui/public/codemirror/mode/stex/test.js
mode change 100755 => 100644 gui/public/codemirror/mode/stylus/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/stylus/stylus.js
mode change 100755 => 100644 gui/public/codemirror/mode/swift/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/swift/swift.js
mode change 100755 => 100644 gui/public/codemirror/mode/swift/test.js
mode change 100755 => 100644 gui/public/codemirror/mode/tcl/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/tcl/tcl.js
mode change 100755 => 100644 gui/public/codemirror/mode/textile/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/textile/test.js
mode change 100755 => 100644 gui/public/codemirror/mode/textile/textile.js
mode change 100755 => 100644 gui/public/codemirror/mode/tiddlywiki/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/tiddlywiki/tiddlywiki.css
mode change 100755 => 100644 gui/public/codemirror/mode/tiddlywiki/tiddlywiki.js
mode change 100755 => 100644 gui/public/codemirror/mode/tiki/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/tiki/tiki.css
mode change 100755 => 100644 gui/public/codemirror/mode/tiki/tiki.js
mode change 100755 => 100644 gui/public/codemirror/mode/toml/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/toml/toml.js
mode change 100755 => 100644 gui/public/codemirror/mode/tornado/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/tornado/tornado.js
mode change 100755 => 100644 gui/public/codemirror/mode/troff/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/troff/troff.js
mode change 100755 => 100644 gui/public/codemirror/mode/ttcn-cfg/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/ttcn-cfg/ttcn-cfg.js
mode change 100755 => 100644 gui/public/codemirror/mode/ttcn/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/ttcn/ttcn.js
mode change 100755 => 100644 gui/public/codemirror/mode/turtle/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/turtle/turtle.js
mode change 100755 => 100644 gui/public/codemirror/mode/twig/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/twig/twig.js
mode change 100755 => 100644 gui/public/codemirror/mode/vb/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/vb/vb.js
mode change 100755 => 100644 gui/public/codemirror/mode/vbscript/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/vbscript/vbscript.js
mode change 100755 => 100644 gui/public/codemirror/mode/velocity/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/velocity/velocity.js
mode change 100755 => 100644 gui/public/codemirror/mode/verilog/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/verilog/test.js
mode change 100755 => 100644 gui/public/codemirror/mode/verilog/verilog.js
mode change 100755 => 100644 gui/public/codemirror/mode/vhdl/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/vhdl/vhdl.js
mode change 100755 => 100644 gui/public/codemirror/mode/vue/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/vue/vue.js
mode change 100755 => 100644 gui/public/codemirror/mode/webidl/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/webidl/webidl.js
mode change 100755 => 100644 gui/public/codemirror/mode/xml/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/xml/test.js
mode change 100755 => 100644 gui/public/codemirror/mode/xml/xml.js
mode change 100755 => 100644 gui/public/codemirror/mode/xquery/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/xquery/test.js
mode change 100755 => 100644 gui/public/codemirror/mode/xquery/xquery.js
mode change 100755 => 100644 gui/public/codemirror/mode/yacas/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/yacas/yacas.js
mode change 100755 => 100644 gui/public/codemirror/mode/yaml-frontmatter/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/yaml-frontmatter/yaml-frontmatter.js
mode change 100755 => 100644 gui/public/codemirror/mode/yaml/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/yaml/yaml.js
mode change 100755 => 100644 gui/public/codemirror/mode/z80/index.html
mode change 100755 => 100644 gui/public/codemirror/mode/z80/z80.js
diff --git a/gui/app/components/section/code/type-editor.js b/gui/app/components/section/code/type-editor.js
index 980d484c..db53131a 100644
--- a/gui/app/components/section/code/type-editor.js
+++ b/gui/app/components/section/code/type-editor.js
@@ -101,7 +101,7 @@ export default Component.extend(TooltipMixin, {
this.set('codeEditor', null);
}
- this.removeT0oltips();
+ this.removeTooltips();
},
diff --git a/gui/app/styles/section/code.scss b/gui/app/styles/section/code.scss
index da710c7e..2465a231 100644
--- a/gui/app/styles/section/code.scss
+++ b/gui/app/styles/section/code.scss
@@ -5,8 +5,6 @@
margin-bottom: 15px;
}
}
-
-
/* BASICS */
.CodeMirror {
@@ -14,6 +12,7 @@
font-family: monospace;
height: 300px;
color: black;
+ direction: ltr;
}
/* PADDING */
@@ -67,7 +66,12 @@
.cm-fat-cursor div.CodeMirror-cursors {
z-index: 1;
}
-
+.cm-fat-cursor-mark {
+ background-color: rgba(20, 255, 20, 0.5);
+ -webkit-animation: blink 1.06s steps(1) infinite;
+ -moz-animation: blink 1.06s steps(1) infinite;
+ animation: blink 1.06s steps(1) infinite;
+}
.cm-animate-fat-cursor {
width: auto;
border: 0;
@@ -128,7 +132,7 @@
.cm-s-default .cm-property,
.cm-s-default .cm-operator {}
.cm-s-default .cm-variable-2 {color: #05a;}
-.cm-s-default .cm-variable-3 {color: #085;}
+.cm-s-default .cm-variable-3, .cm-s-default .cm-type {color: #085;}
.cm-s-default .cm-comment {color: #a50;}
.cm-s-default .cm-string {color: #a11;}
.cm-s-default .cm-string-2 {color: #f50;}
@@ -148,8 +152,8 @@
/* Default styles for common addons */
-div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}
-div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
+div.CodeMirror span.CodeMirror-matchingbracket {color: #0b0;}
+div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #a22;}
.CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); }
.CodeMirror-activeline-background {background: #e8f2ff;}
@@ -232,11 +236,8 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
cursor: default;
z-index: 4;
}
-.CodeMirror-gutter-wrapper {
- -webkit-user-select: none;
- -moz-user-select: none;
- user-select: none;
-}
+.CodeMirror-gutter-wrapper ::selection { background-color: transparent }
+.CodeMirror-gutter-wrapper ::-moz-selection { background-color: transparent }
.CodeMirror-lines {
cursor: text;
@@ -281,6 +282,8 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
.CodeMirror-widget {}
+.CodeMirror-rtl pre { direction: rtl; }
+
.CodeMirror-code {
outline: none;
}
@@ -329,8 +332,8 @@ div.CodeMirror-dragcursors {
.CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; }
.cm-searching {
- background: #ffa;
- background: rgba(255, 255, 0, .4);
+ background-color: #ffa;
+ background-color: rgba(255, 255, 0, .4);
}
/* Used to force a border model for a node */
diff --git a/gui/public/codemirror/addon/comment/comment.js b/gui/public/codemirror/addon/comment/comment.js
old mode 100755
new mode 100644
index 1c987871..84c67edf
--- a/gui/public/codemirror/addon/comment/comment.js
+++ b/gui/public/codemirror/addon/comment/comment.js
@@ -46,7 +46,7 @@
// Rough heuristic to try and detect lines that are part of multi-line string
function probablyInsideString(cm, pos, line) {
- return /\bstring\b/.test(cm.getTokenTypeAt(Pos(pos.line, 0))) && !/^[\'\"`]/.test(line)
+ return /\bstring\b/.test(cm.getTokenTypeAt(Pos(pos.line, 0))) && !/^[\'\"\`]/.test(line)
}
function getMode(cm, pos) {
@@ -172,13 +172,11 @@
if (open == -1) return false
var endLine = end == start ? startLine : self.getLine(end)
var close = endLine.indexOf(endString, end == start ? open + startString.length : 0);
- if (close == -1 && start != end) {
- endLine = self.getLine(--end);
- close = endLine.indexOf(endString);
- }
+ var insideStart = Pos(start, open + 1), insideEnd = Pos(end, close + 1)
if (close == -1 ||
- !/comment/.test(self.getTokenTypeAt(Pos(start, open + 1))) ||
- !/comment/.test(self.getTokenTypeAt(Pos(end, close + 1))))
+ !/comment/.test(self.getTokenTypeAt(insideStart)) ||
+ !/comment/.test(self.getTokenTypeAt(insideEnd)) ||
+ self.getRange(insideStart, insideEnd, "\n").indexOf(endString) > -1)
return false;
// Avoid killing block comments completely outside the selection.
diff --git a/gui/public/codemirror/addon/comment/continuecomment.js b/gui/public/codemirror/addon/comment/continuecomment.js
old mode 100755
new mode 100644
index b11d51e6..d92318b3
--- a/gui/public/codemirror/addon/comment/continuecomment.js
+++ b/gui/public/codemirror/addon/comment/continuecomment.js
@@ -9,39 +9,32 @@
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
- var modes = ["clike", "css", "javascript"];
-
- for (var i = 0; i < modes.length; ++i)
- CodeMirror.extendMode(modes[i], {blockCommentContinue: " * "});
-
function continueComment(cm) {
if (cm.getOption("disableInput")) return CodeMirror.Pass;
var ranges = cm.listSelections(), mode, inserts = [];
for (var i = 0; i < ranges.length; i++) {
- var pos = ranges[i].head, token = cm.getTokenAt(pos);
- if (token.type != "comment") return CodeMirror.Pass;
- var modeHere = CodeMirror.innerMode(cm.getMode(), token.state).mode;
+ var pos = ranges[i].head
+ if (!/\bcomment\b/.test(cm.getTokenTypeAt(pos))) return CodeMirror.Pass;
+ var modeHere = cm.getModeAt(pos)
if (!mode) mode = modeHere;
else if (mode != modeHere) return CodeMirror.Pass;
var insert = null;
if (mode.blockCommentStart && mode.blockCommentContinue) {
- var end = token.string.indexOf(mode.blockCommentEnd);
- var full = cm.getRange(CodeMirror.Pos(pos.line, 0), CodeMirror.Pos(pos.line, token.end)), found;
- if (end != -1 && end == token.string.length - mode.blockCommentEnd.length && pos.ch >= end) {
+ var line = cm.getLine(pos.line).slice(0, pos.ch)
+ var end = line.lastIndexOf(mode.blockCommentEnd), found
+ if (end != -1 && end == pos.ch - mode.blockCommentEnd.length) {
// Comment ended, don't continue it
- } else if (token.string.indexOf(mode.blockCommentStart) == 0) {
- insert = full.slice(0, token.start);
- if (!/^\s*$/.test(insert)) {
- insert = "";
- for (var j = 0; j < token.start; ++j) insert += " ";
+ } else if ((found = line.lastIndexOf(mode.blockCommentStart)) > -1 && found > end) {
+ insert = line.slice(0, found)
+ if (/\S/.test(insert)) {
+ insert = ""
+ for (var j = 0; j < found; ++j) insert += " "
}
- } else if ((found = full.indexOf(mode.blockCommentContinue)) != -1 &&
- found + mode.blockCommentContinue.length > token.start &&
- /^\s*$/.test(full.slice(0, found))) {
- insert = full.slice(0, found);
+ } else if ((found = line.indexOf(mode.blockCommentContinue)) > -1 && !/\S/.test(line.slice(0, found))) {
+ insert = line.slice(0, found)
}
- if (insert != null) insert += mode.blockCommentContinue;
+ if (insert != null) insert += mode.blockCommentContinue
}
if (insert == null && mode.lineComment && continueLineCommentEnabled(cm)) {
var line = cm.getLine(pos.line), found = line.indexOf(mode.lineComment);
diff --git a/gui/public/codemirror/addon/dialog/dialog.css b/gui/public/codemirror/addon/dialog/dialog.css
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/addon/dialog/dialog.js b/gui/public/codemirror/addon/dialog/dialog.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/addon/display/autorefresh.js b/gui/public/codemirror/addon/display/autorefresh.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/addon/display/fullscreen.css b/gui/public/codemirror/addon/display/fullscreen.css
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/addon/display/fullscreen.js b/gui/public/codemirror/addon/display/fullscreen.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/addon/display/panel.js b/gui/public/codemirror/addon/display/panel.js
old mode 100755
new mode 100644
index 74199ff0..f88d152b
--- a/gui/public/codemirror/addon/display/panel.js
+++ b/gui/public/codemirror/addon/display/panel.js
@@ -66,7 +66,7 @@
Panel.prototype.changed = function(height) {
var newHeight = height == null ? this.node.offsetHeight : height;
var info = this.cm.state.panels;
- this.cm._setSize(null, info.height += (newHeight - this.height));
+ this.cm._setSize(null, info.heightLeft -= (newHeight - this.height));
this.height = newHeight;
};
diff --git a/gui/public/codemirror/addon/display/placeholder.js b/gui/public/codemirror/addon/display/placeholder.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/addon/display/rulers.js b/gui/public/codemirror/addon/display/rulers.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/addon/edit/closebrackets.js b/gui/public/codemirror/addon/edit/closebrackets.js
old mode 100755
new mode 100644
index 01fdd96c..460f662f
--- a/gui/public/codemirror/addon/edit/closebrackets.js
+++ b/gui/public/codemirror/addon/edit/closebrackets.js
@@ -23,6 +23,7 @@
cm.state.closeBrackets = null;
}
if (val) {
+ ensureBound(getOption(val, "pairs"))
cm.state.closeBrackets = val;
cm.addKeyMap(keyMap);
}
@@ -34,10 +35,14 @@
return defaults[name];
}
- var bind = defaults.pairs + "`";
var keyMap = {Backspace: handleBackspace, Enter: handleEnter};
- for (var i = 0; i < bind.length; i++)
- keyMap["'" + bind.charAt(i) + "'"] = handler(bind.charAt(i));
+ 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); };
@@ -79,7 +84,8 @@
if (!around || explode.indexOf(around) % 2 != 0) return CodeMirror.Pass;
}
cm.operation(function() {
- cm.replaceSelection("\n\n", null);
+ var linesep = cm.lineSeparator() || "\n";
+ cm.replaceSelection(linesep + linesep, null);
cm.execCommand("goCharLeft");
ranges = cm.listSelections();
for (var i = 0; i < ranges.length; i++) {
@@ -127,7 +133,8 @@
(cur.ch <= 2 || cm.getRange(Pos(cur.line, cur.ch - 3), Pos(cur.line, cur.ch - 2)) != ch)) {
curType = "addFour";
} else if (identical) {
- if (!CodeMirror.isWordChar(next) && enteringString(cm, cur, ch)) curType = "both";
+ 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 && (cm.getLine(cur.line).length == cur.ch ||
isClosingBracket(next, pairs) ||
@@ -179,24 +186,9 @@
return str.length == 2 ? str : null;
}
- // Project the token type that will exists after the given char is
- // typed, and use it to determine whether it would cause the start
- // of a string token.
- function enteringString(cm, pos, ch) {
- var line = cm.getLine(pos.line);
- var token = cm.getTokenAt(pos);
- if (/\bstring2?\b/.test(token.type) || stringStartsAfter(cm, pos)) return false;
- var stream = new CodeMirror.StringStream(line.slice(0, pos.ch) + ch + line.slice(pos.ch), 4);
- stream.pos = stream.start = token.start;
- for (;;) {
- var type1 = cm.getMode().token(stream, token.state);
- if (stream.pos >= pos.ch + 1) return /\bstring2?\b/.test(type1);
- stream.start = stream.pos;
- }
- }
-
function stringStartsAfter(cm, pos) {
var token = cm.getTokenAt(Pos(pos.line, pos.ch + 1))
- return /\bstring/.test(token.type) && token.start == pos.ch
+ return /\bstring/.test(token.type) && token.start == pos.ch &&
+ (pos.ch == 0 || !/\bstring/.test(cm.getTokenTypeAt(pos)))
}
});
diff --git a/gui/public/codemirror/addon/edit/closetag.js b/gui/public/codemirror/addon/edit/closetag.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/addon/edit/continuelist.js b/gui/public/codemirror/addon/edit/continuelist.js
old mode 100755
new mode 100644
index 5a845907..30893965
--- a/gui/public/codemirror/addon/edit/continuelist.js
+++ b/gui/public/codemirror/addon/edit/continuelist.js
@@ -11,8 +11,8 @@
})(function(CodeMirror) {
"use strict";
- var listRE = /^(\s*)(>[> ]*|- \[[x ]\]\s|[*+-]\s|(\d+)([.)]))(\s*)/,
- emptyListRE = /^(\s*)(>[> ]*|- \[[x ]\]|[*+-]|(\d+)[.)])(\s*)$/,
+ var listRE = /^(\s*)(>[> ]*|[*+-] \[[x ]\]\s|[*+-]\s|(\d+)([.)]))(\s*)/,
+ emptyListRE = /^(\s*)(>[> ]*|[*+-] \[[x ]\]|[*+-]|(\d+)[.)])(\s*)$/,
unorderedListRE = /[*+-]\s/;
CodeMirror.commands.newlineAndIndentContinueMarkdownList = function(cm) {
@@ -25,7 +25,8 @@
var inQuote = eolState.quote !== 0;
var line = cm.getLine(pos.line), match = listRE.exec(line);
- if (!ranges[i].empty() || (!inList && !inQuote) || !match) {
+ var cursorBeforeBullet = /^\s*$/.test(line.slice(0, pos.ch));
+ if (!ranges[i].empty() || (!inList && !inQuote) || !match || cursorBeforeBullet) {
cm.execCommand("newlineAndIndent");
return;
}
@@ -43,9 +44,48 @@
: (parseInt(match[3], 10) + 1) + match[4];
replacements[i] = "\n" + indent + bullet + after;
+
+ incrementRemainingMarkdownListNumbers(cm, pos);
}
}
cm.replaceSelections(replacements);
};
+
+ // Auto-updating Markdown list numbers when a new item is added to the
+ // middle of a list
+ function incrementRemainingMarkdownListNumbers(cm, pos) {
+ var startLine = pos.line, lookAhead = 0, skipCount = 0;
+ var startItem = listRE.exec(cm.getLine(startLine)), startIndent = startItem[1];
+
+ do {
+ lookAhead += 1;
+ var nextLineNumber = startLine + lookAhead;
+ var nextLine = cm.getLine(nextLineNumber), nextItem = listRE.exec(nextLine);
+
+ if (nextItem) {
+ var nextIndent = nextItem[1];
+ var newNumber = (parseInt(startItem[3], 10) + lookAhead - skipCount);
+ var nextNumber = (parseInt(nextItem[3], 10)), itemNumber = nextNumber;
+
+ if (startIndent === nextIndent) {
+ if (newNumber === nextNumber) itemNumber = nextNumber + 1;
+ if (newNumber > nextNumber) itemNumber = newNumber + 1;
+ cm.replaceRange(
+ nextLine.replace(listRE, nextIndent + itemNumber + nextItem[4] + nextItem[5]),
+ {
+ line: nextLineNumber, ch: 0
+ }, {
+ line: nextLineNumber, ch: nextLine.length
+ });
+ } else {
+ if (startIndent.length > nextIndent.length) return;
+ // This doesn't run if the next line immediatley indents, as it is
+ // not clear of the users intention (new indented item or same level)
+ if ((startIndent.length < nextIndent.length) && (lookAhead === 1)) return;
+ skipCount += 1;
+ }
+ }
+ } while (nextItem);
+ }
});
diff --git a/gui/public/codemirror/addon/edit/matchbrackets.js b/gui/public/codemirror/addon/edit/matchbrackets.js
old mode 100755
new mode 100644
index 76754ed5..4d7a2308
--- a/gui/public/codemirror/addon/edit/matchbrackets.js
+++ b/gui/public/codemirror/addon/edit/matchbrackets.js
@@ -16,12 +16,21 @@
var matching = {"(": ")>", ")": "(<", "[": "]>", "]": "[<", "{": "}>", "}": "{<"};
- function findMatchingBracket(cm, where, strict, config) {
+ function findMatchingBracket(cm, where, config) {
var line = cm.getLineHandle(where.line), pos = where.ch - 1;
- var match = (pos >= 0 && matching[line.text.charAt(pos)]) || matching[line.text.charAt(++pos)];
+ var afterCursor = config && config.afterCursor
+ if (afterCursor == null)
+ afterCursor = /(^| )cm-fat-cursor($| )/.test(cm.getWrapperElement().className)
+
+ // 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 && matching[line.text.charAt(pos)]) ||
+ matching[line.text.charAt(++pos)];
if (!match) return null;
var dir = match.charAt(1) == ">" ? 1 : -1;
- if (strict && (dir > 0) != (pos == where.ch)) return null;
+ 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);
@@ -69,7 +78,7 @@
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, false, config);
+ 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}));
@@ -113,8 +122,17 @@
});
CodeMirror.defineExtension("matchBrackets", function() {matchBrackets(this, true);});
- CodeMirror.defineExtension("findMatchingBracket", function(pos, strict, config){
- return findMatchingBracket(this, pos, strict, config);
+ 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);
diff --git a/gui/public/codemirror/addon/edit/matchtags.js b/gui/public/codemirror/addon/edit/matchtags.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/addon/edit/trailingspace.js b/gui/public/codemirror/addon/edit/trailingspace.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/addon/fold/brace-fold.js b/gui/public/codemirror/addon/fold/brace-fold.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/addon/fold/comment-fold.js b/gui/public/codemirror/addon/fold/comment-fold.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/addon/fold/foldcode.js b/gui/public/codemirror/addon/fold/foldcode.js
old mode 100755
new mode 100644
index 78b36c46..826766b6
--- a/gui/public/codemirror/addon/fold/foldcode.js
+++ b/gui/public/codemirror/addon/fold/foldcode.js
@@ -65,6 +65,8 @@
widget = document.createElement("span");
widget.appendChild(text);
widget.className = "CodeMirror-foldmarker";
+ } else if (widget) {
+ widget = widget.cloneNode(true)
}
return widget;
}
diff --git a/gui/public/codemirror/addon/fold/foldgutter.css b/gui/public/codemirror/addon/fold/foldgutter.css
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/addon/fold/foldgutter.js b/gui/public/codemirror/addon/fold/foldgutter.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/addon/fold/indent-fold.js b/gui/public/codemirror/addon/fold/indent-fold.js
old mode 100755
new mode 100644
index 743150c6..f93edec2
--- a/gui/public/codemirror/addon/fold/indent-fold.js
+++ b/gui/public/codemirror/addon/fold/indent-fold.js
@@ -18,7 +18,7 @@ function lineIndent(cm, lineNo) {
return -1
return CodeMirror.countColumn(text, null, cm.getOption("tabSize"))
}
- !
+
CodeMirror.registerHelper("fold", "indent", function(cm, start) {
var myIndent = lineIndent(cm, start.line)
if (myIndent < 0) return
diff --git a/gui/public/codemirror/addon/fold/markdown-fold.js b/gui/public/codemirror/addon/fold/markdown-fold.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/addon/fold/xml-fold.js b/gui/public/codemirror/addon/fold/xml-fold.js
old mode 100755
new mode 100644
index 75a9e305..08e21495
--- a/gui/public/codemirror/addon/fold/xml-fold.js
+++ b/gui/public/codemirror/addon/fold/xml-fold.js
@@ -163,10 +163,10 @@
}
};
- CodeMirror.findEnclosingTag = function(cm, pos, range) {
+ CodeMirror.findEnclosingTag = function(cm, pos, range, tag) {
var iter = new Iter(cm, pos.line, pos.ch, range);
for (;;) {
- var open = findMatchingOpen(iter);
+ var open = findMatchingOpen(iter, tag);
if (!open) break;
var forward = new Iter(cm, pos.line, pos.ch, range);
var close = findMatchingClose(forward, open.tag);
diff --git a/gui/public/codemirror/addon/hint/anyword-hint.js b/gui/public/codemirror/addon/hint/anyword-hint.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/addon/hint/css-hint.js b/gui/public/codemirror/addon/hint/css-hint.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/addon/hint/html-hint.js b/gui/public/codemirror/addon/hint/html-hint.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/addon/hint/javascript-hint.js b/gui/public/codemirror/addon/hint/javascript-hint.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/addon/hint/show-hint.css b/gui/public/codemirror/addon/hint/show-hint.css
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/addon/hint/show-hint.js b/gui/public/codemirror/addon/hint/show-hint.js
old mode 100755
new mode 100644
index 604bd3b7..62c683cb
--- a/gui/public/codemirror/addon/hint/show-hint.js
+++ b/gui/public/codemirror/addon/hint/show-hint.js
@@ -121,7 +121,6 @@
var picked = (this.widget && this.widget.picked) || (first && this.options.completeSingle);
if (this.widget) this.widget.close();
- if (data && this.data && isNewCompletion(this.data, data)) return;
this.data = data;
if (data && data.list.length) {
@@ -135,11 +134,6 @@
}
};
- function isNewCompletion(old, nw) {
- var moved = CodeMirror.cmpPos(nw.from, old.from)
- return moved > 0 && old.to.ch - old.from.ch != nw.to.ch - nw.from.ch
- }
-
function parseOptions(cm, pos, options) {
var editor = cm.options.hintOptions;
var out = {};
@@ -302,7 +296,7 @@
setTimeout(function(){cm.focus();}, 20);
});
- CodeMirror.signal(data, "select", completions[0], hints.firstChild);
+ CodeMirror.signal(data, "select", completions[this.selectedHint], hints.childNodes[this.selectedHint]);
return true;
}
diff --git a/gui/public/codemirror/addon/hint/sql-hint.js b/gui/public/codemirror/addon/hint/sql-hint.js
old mode 100755
new mode 100644
index 1ee4f0bb..f5ec2cac
--- a/gui/public/codemirror/addon/hint/sql-hint.js
+++ b/gui/public/codemirror/addon/hint/sql-hint.js
@@ -14,6 +14,7 @@
var tables;
var defaultTable;
var keywords;
+ var identifierQuote;
var CONS = {
QUERY_DIV: ";",
ALIAS_KEYWORD: "AS"
@@ -28,6 +29,12 @@
return CodeMirror.resolveMode(mode).keywords;
}
+ function getIdentifierQuote(editor) {
+ var mode = editor.doc.modeOption;
+ if (mode === "sql") mode = "text/x-sql";
+ return CodeMirror.resolveMode(mode).identifierQuote || "`";
+ }
+
function getText(item) {
return typeof item == "string" ? item : item.text;
}
@@ -86,17 +93,25 @@
}
function cleanName(name) {
- // Get rid name from backticks(`) and preceding dot(.)
+ // Get rid name from identifierQuote and preceding dot(.)
if (name.charAt(0) == ".") {
name = name.substr(1);
}
- return name.replace(/`/g, "");
+ // replace doublicated identifierQuotes with single identifierQuotes
+ // and remove single identifierQuotes
+ var nameParts = name.split(identifierQuote+identifierQuote);
+ for (var i = 0; i < nameParts.length; i++)
+ nameParts[i] = nameParts[i].replace(new RegExp(identifierQuote,"g"), "");
+ return nameParts.join(identifierQuote);
}
- function insertBackticks(name) {
+ function insertIdentifierQuotes(name) {
var nameParts = getText(name).split(".");
for (var i = 0; i < nameParts.length; i++)
- nameParts[i] = "`" + nameParts[i] + "`";
+ nameParts[i] = identifierQuote +
+ // doublicate identifierQuotes
+ nameParts[i].replace(new RegExp(identifierQuote,"g"), identifierQuote+identifierQuote) +
+ identifierQuote;
var escaped = nameParts.join(".");
if (typeof name == "string") return escaped;
name = shallowClone(name);
@@ -106,13 +121,13 @@
function nameCompletion(cur, token, result, editor) {
// Try to complete table, column names and return start position of completion
- var useBacktick = false;
+ var useIdentifierQuotes = false;
var nameParts = [];
var start = token.start;
var cont = true;
while (cont) {
cont = (token.string.charAt(0) == ".");
- useBacktick = useBacktick || (token.string.charAt(0) == "`");
+ useIdentifierQuotes = useIdentifierQuotes || (token.string.charAt(0) == identifierQuote);
start = token.start;
nameParts.unshift(cleanName(token.string));
@@ -127,12 +142,12 @@
// Try to complete table names
var string = nameParts.join(".");
addMatches(result, string, tables, function(w) {
- return useBacktick ? insertBackticks(w) : w;
+ return useIdentifierQuotes ? insertIdentifierQuotes(w) : w;
});
// Try to complete columns from defaultTable
addMatches(result, string, defaultTable, function(w) {
- return useBacktick ? insertBackticks(w) : w;
+ return useIdentifierQuotes ? insertIdentifierQuotes(w) : w;
});
// Try to complete columns
@@ -162,7 +177,7 @@
w = shallowClone(w);
w.text = tableInsert + "." + w.text;
}
- return useBacktick ? insertBackticks(w) : w;
+ return useIdentifierQuotes ? insertIdentifierQuotes(w) : w;
});
}
@@ -170,12 +185,9 @@
}
function eachWord(lineText, f) {
- if (!lineText) return;
- var excepted = /[,;]/g;
- var words = lineText.split(" ");
- for (var i = 0; i < words.length; i++) {
- f(words[i]?words[i].replace(excepted, '') : '');
- }
+ var words = lineText.split(/\s+/)
+ for (var i = 0; i < words.length; i++)
+ if (words[i]) f(words[i].replace(/[,;]/g, ''))
}
function findTableByAlias(alias, editor) {
@@ -232,6 +244,7 @@
var disableKeywords = options && options.disableKeywords;
defaultTable = defaultTableName && getTable(defaultTableName);
keywords = getKeywords(editor);
+ identifierQuote = getIdentifierQuote(editor);
if (defaultTableName && !defaultTable)
defaultTable = findTableByAlias(defaultTableName, editor);
@@ -249,7 +262,7 @@
token.string = token.string.slice(0, cur.ch - token.start);
}
- if (token.string.match(/^[.`\w@]\w*$/)) {
+ if (token.string.match(/^[.`"\w@]\w*$/)) {
search = token.string;
start = token.start;
end = token.end;
@@ -257,7 +270,7 @@
start = end = cur.ch;
search = "";
}
- if (search.charAt(0) == "." || search.charAt(0) == "`") {
+ if (search.charAt(0) == "." || search.charAt(0) == identifierQuote) {
start = nameCompletion(cur, token, result, editor);
} else {
addMatches(result, search, tables, function(w) {return w;});
diff --git a/gui/public/codemirror/addon/hint/xml-hint.js b/gui/public/codemirror/addon/hint/xml-hint.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/addon/lint/coffeescript-lint.js b/gui/public/codemirror/addon/lint/coffeescript-lint.js
old mode 100755
new mode 100644
index 7e39428f..70621a1b
--- a/gui/public/codemirror/addon/lint/coffeescript-lint.js
+++ b/gui/public/codemirror/addon/lint/coffeescript-lint.js
@@ -17,6 +17,12 @@
CodeMirror.registerHelper("lint", "coffeescript", function(text) {
var found = [];
+ if (!window.coffeelint) {
+ if (window.console) {
+ window.console.error("Error: window.coffeelint not defined, CodeMirror CoffeeScript linting cannot run.");
+ }
+ return found;
+ }
var parseError = function(err) {
var loc = err.lineNumber;
found.push({from: CodeMirror.Pos(loc-1, 0),
diff --git a/gui/public/codemirror/addon/lint/css-lint.js b/gui/public/codemirror/addon/lint/css-lint.js
old mode 100755
new mode 100644
index 1f61b479..135d031a
--- a/gui/public/codemirror/addon/lint/css-lint.js
+++ b/gui/public/codemirror/addon/lint/css-lint.js
@@ -15,10 +15,15 @@
})(function(CodeMirror) {
"use strict";
-CodeMirror.registerHelper("lint", "css", function(text) {
+CodeMirror.registerHelper("lint", "css", function(text, options) {
var found = [];
- if (!window.CSSLint) return found;
- var results = CSSLint.verify(text), messages = results.messages, message = null;
+ if (!window.CSSLint) {
+ if (window.console) {
+ window.console.error("Error: window.CSSLint not defined, CodeMirror CSS linting cannot run.");
+ }
+ return found;
+ }
+ var results = CSSLint.verify(text, options), messages = results.messages, message = null;
for ( var i = 0; i < messages.length; i++) {
message = messages[i];
var startLine = message.line -1, endLine = message.line -1, startCol = message.col -1, endCol = message.col;
diff --git a/gui/public/codemirror/addon/lint/html-lint.js b/gui/public/codemirror/addon/lint/html-lint.js
old mode 100755
new mode 100644
index 1e841709..23de9bb2
--- a/gui/public/codemirror/addon/lint/html-lint.js
+++ b/gui/public/codemirror/addon/lint/html-lint.js
@@ -11,8 +11,8 @@
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "htmlhint"], mod);
else // Plain browser env
- mod(CodeMirror);
-})(function(CodeMirror) {
+ mod(CodeMirror, window.HTMLHint);
+})(function(CodeMirror, HTMLHint) {
"use strict";
var defaultRules = {
@@ -29,7 +29,14 @@
CodeMirror.registerHelper("lint", "html", function(text, options) {
var found = [];
- if (!window.HTMLHint) return found;
+ if (HTMLHint && !HTMLHint.verify) HTMLHint = HTMLHint.HTMLHint;
+ if (!HTMLHint) HTMLHint = window.HTMLHint;
+ if (!HTMLHint) {
+ if (window.console) {
+ window.console.error("Error: HTMLHint not found, not defined on window, or not available through define/require, CodeMirror HTML linting cannot run.");
+ }
+ return found;
+ }
var messages = HTMLHint.verify(text, options && options.rules || defaultRules);
for (var i = 0; i < messages.length; i++) {
var message = messages[i];
diff --git a/gui/public/codemirror/addon/lint/javascript-lint.js b/gui/public/codemirror/addon/lint/javascript-lint.js
old mode 100755
new mode 100644
index d4f2ae9a..c58f7850
--- a/gui/public/codemirror/addon/lint/javascript-lint.js
+++ b/gui/public/codemirror/addon/lint/javascript-lint.js
@@ -22,7 +22,12 @@
"Unclosed string", "Stopping, unable to continue" ];
function validator(text, options) {
- if (!window.JSHINT) return [];
+ if (!window.JSHINT) {
+ if (window.console) {
+ window.console.error("Error: window.JSHINT not defined, CodeMirror JavaScript linting cannot run.");
+ }
+ return [];
+ }
JSHINT(text, options, options.globals);
var errors = JSHINT.data().errors, result = [];
if (errors) parseErrors(errors, result);
diff --git a/gui/public/codemirror/addon/lint/json-lint.js b/gui/public/codemirror/addon/lint/json-lint.js
old mode 100755
new mode 100644
index 9dbb616b..849641ee
--- a/gui/public/codemirror/addon/lint/json-lint.js
+++ b/gui/public/codemirror/addon/lint/json-lint.js
@@ -17,6 +17,12 @@
CodeMirror.registerHelper("lint", "json", function(text) {
var found = [];
+ if (!window.jsonlint) {
+ if (window.console) {
+ window.console.error("Error: window.jsonlint not defined, CodeMirror JSON linting cannot run.");
+ }
+ return found;
+ }
jsonlint.parseError = function(str, hash) {
var loc = hash.loc;
found.push({from: CodeMirror.Pos(loc.first_line - 1, loc.first_column),
diff --git a/gui/public/codemirror/addon/lint/lint.css b/gui/public/codemirror/addon/lint/lint.css
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/addon/lint/lint.js b/gui/public/codemirror/addon/lint/lint.js
old mode 100755
new mode 100644
index c1f1702f..a9eb8fa6
--- a/gui/public/codemirror/addon/lint/lint.js
+++ b/gui/public/codemirror/addon/lint/lint.js
@@ -112,7 +112,11 @@
if (!severity) severity = "error";
var tip = document.createElement("div");
tip.className = "CodeMirror-lint-message-" + severity;
- tip.appendChild(document.createTextNode(ann.message));
+ if (typeof ann.messageHTML != 'undefined') {
+ tip.innerHTML = ann.messageHTML;
+ } else {
+ tip.appendChild(document.createTextNode(ann.message));
+ }
return tip;
}
@@ -134,13 +138,22 @@
function startLinting(cm) {
var state = cm.state.lint, options = state.options;
- var passOptions = options.options || options; // Support deprecated passing of `options` property in options
+ /*
+ * Passing rules in `options` property prevents JSHint (and other linters) from complaining
+ * about unrecognized rules like `onUpdateLinting`, `delay`, `lintOnChange`, etc.
+ */
+ var passOptions = options.options || options;
var getAnnotations = options.getAnnotations || cm.getHelper(CodeMirror.Pos(0, 0), "lint");
if (!getAnnotations) return;
if (options.async || getAnnotations.async) {
lintAsync(cm, getAnnotations, passOptions)
} else {
- updateLinting(cm, getAnnotations(cm.getValue(), passOptions, cm));
+ var annotations = getAnnotations(cm.getValue(), passOptions, cm);
+ if (!annotations) return;
+ if (annotations.then) annotations.then(function(issues) {
+ updateLinting(cm, issues);
+ });
+ else updateLinting(cm, annotations);
}
}
diff --git a/gui/public/codemirror/addon/lint/yaml-lint.js b/gui/public/codemirror/addon/lint/yaml-lint.js
old mode 100755
new mode 100644
index 3f77e525..3954ed38
--- a/gui/public/codemirror/addon/lint/yaml-lint.js
+++ b/gui/public/codemirror/addon/lint/yaml-lint.js
@@ -17,10 +17,23 @@
CodeMirror.registerHelper("lint", "yaml", function(text) {
var found = [];
+ if (!window.jsyaml) {
+ if (window.console) {
+ window.console.error("Error: window.jsyaml not defined, CodeMirror YAML linting cannot run.");
+ }
+ return found;
+ }
try { jsyaml.load(text); }
catch(e) {
- var loc = e.mark;
- found.push({ from: CodeMirror.Pos(loc.line, loc.column), to: CodeMirror.Pos(loc.line, loc.column), message: e.message });
+ var loc = e.mark,
+ // js-yaml YAMLException doesn't always provide an accurate lineno
+ // e.g., when there are multiple yaml docs
+ // ---
+ // ---
+ // foo:bar
+ from = loc ? CodeMirror.Pos(loc.line, loc.column) : CodeMirror.Pos(0, 0),
+ to = from;
+ found.push({ from: from, to: to, message: e.message });
}
return found;
});
diff --git a/gui/public/codemirror/addon/merge/merge.css b/gui/public/codemirror/addon/merge/merge.css
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/addon/merge/merge.js b/gui/public/codemirror/addon/merge/merge.js
old mode 100755
new mode 100644
index 66d160f3..dc2e77c6
--- a/gui/public/codemirror/addon/merge/merge.js
+++ b/gui/public/codemirror/addon/merge/merge.js
@@ -49,17 +49,17 @@
if (Object.prototype.toString.call(classLocation) != "[object Array]") classLocation = [classLocation]
this.classes.classLocation = classLocation
- this.diff = getDiff(asString(orig), asString(options.value));
+ this.diff = getDiff(asString(orig), asString(options.value), this.mv.options.ignoreWhitespace);
this.chunks = getChunks(this.diff);
this.diffOutOfDate = this.dealigned = false;
this.needsScrollSync = null
this.showDifferences = options.showDifferences !== false;
},
- registerEvents: function() {
+ registerEvents: function(otherDv) {
this.forceUpdate = registerUpdate(this);
setScrollLock(this, true, false);
- registerScroll(this);
+ registerScroll(this, otherDv);
},
setShowDifferences: function(val) {
val = val !== false;
@@ -72,7 +72,7 @@
function ensureDiff(dv) {
if (dv.diffOutOfDate) {
- dv.diff = getDiff(dv.orig.getValue(), dv.edit.getValue());
+ dv.diff = getDiff(dv.orig.getValue(), dv.edit.getValue(), dv.mv.options.ignoreWhitespace);
dv.chunks = getChunks(dv.diff);
dv.diffOutOfDate = false;
CodeMirror.signal(dv.edit, "updateDiff", dv.diff);
@@ -128,6 +128,7 @@
}
function swapDoc() {
dv.diffOutOfDate = true;
+ dv.dealigned = true;
update("full");
}
dv.edit.on("change", change);
@@ -144,12 +145,13 @@
return update;
}
- function registerScroll(dv) {
+ function registerScroll(dv, otherDv) {
dv.edit.on("scroll", function() {
syncScroll(dv, true) && makeConnections(dv);
});
dv.orig.on("scroll", function() {
syncScroll(dv, false) && makeConnections(dv);
+ if (otherDv) syncScroll(otherDv, true) && makeConnections(otherDv);
});
}
@@ -352,11 +354,11 @@
var result = []
for (var i = 0;; i++) {
var chunk = chunks[i]
- var chunkStart = !chunk ? cm.lastLine() + 1 : isOrig ? chunk.origFrom : chunk.editFrom
+ var chunkStart = !chunk ? 1e9 : isOrig ? chunk.origFrom : chunk.editFrom
for (; trackI < tracker.alignable.length; trackI += 2) {
var n = tracker.alignable[trackI] + 1
if (n <= start) continue
- if (n < chunkStart) result.push(n)
+ if (n <= chunkStart) result.push(n)
else break
}
if (!chunk) break
@@ -370,14 +372,22 @@
// lines that need to be aligned with each other.
function mergeAlignable(result, origAlignable, chunks, setIndex) {
var rI = 0, origI = 0, chunkI = 0, diff = 0
- for (;; rI++) {
+ outer: for (;; rI++) {
var nextR = result[rI], nextO = origAlignable[origI]
if (!nextR && nextO == null) break
var rLine = nextR ? nextR[0] : 1e9, oLine = nextO == null ? 1e9 : nextO
while (chunkI < chunks.length) {
var chunk = chunks[chunkI]
- if (chunk.editTo > rLine) break
+ if (chunk.origFrom <= oLine && chunk.origTo > oLine) {
+ origI++
+ rI--
+ continue outer;
+ }
+ if (chunk.editTo > rLine) {
+ if (chunk.editFrom <= rLine) continue outer;
+ break
+ }
diff += (chunk.origTo - chunk.origFrom) - (chunk.editTo - chunk.editFrom)
chunkI++
}
@@ -467,7 +477,7 @@
var elt = document.createElement("div");
elt.className = "CodeMirror-merge-spacer";
elt.style.height = size + "px"; elt.style.minWidth = "1px";
- return cm.addLineWidget(line, elt, {height: size, above: above, mergeSpacer: true});
+ return cm.addLineWidget(line, elt, {height: size, above: above, mergeSpacer: true, handleMouseEvents: true});
}
function drawConnectorsForChunk(dv, chunk, sTopOrig, sTopEdit, w) {
@@ -567,8 +577,8 @@
this.aligners = [];
alignChunks(this.left || this.right, true);
}
- if (left) left.registerEvents()
- if (right) right.registerEvents()
+ if (left) left.registerEvents(right)
+ if (right) right.registerEvents(left)
var onResize = function() {
@@ -634,14 +644,15 @@
}
// Operations on diffs
+ var dmp;
+ function getDiff(a, b, ignoreWhitespace) {
+ if (!dmp) dmp = new diff_match_patch();
- var dmp = new diff_match_patch();
- function getDiff(a, b) {
var diff = dmp.diff_main(a, b);
// The library sometimes leaves in empty parts, which confuse the algorithm
for (var i = 0; i < diff.length; ++i) {
var part = diff[i];
- if (!part[1]) {
+ if (ignoreWhitespace ? !/[^ \t]/.test(part[1]) : !part[1]) {
diff.splice(i--, 1);
} else if (i && diff[i - 1][0] == part[0]) {
diff.splice(i--, 1);
@@ -658,7 +669,7 @@
for (var i = 0; i < diff.length; ++i) {
var part = diff[i], tp = part[0];
if (tp == DIFF_EQUAL) {
- var startOff = startOfLineClean(diff, i) ? 0 : 1;
+ var startOff = !startOfLineClean(diff, i) || edit.line < startEdit || orig.line < startOrig ? 1 : 0;
var cleanFromEdit = edit.line + startOff, cleanFromOrig = orig.line + startOff;
moveOver(edit, part[1], null, orig);
var endOff = endOfLineClean(diff, i) ? 1 : 0;
@@ -727,6 +738,9 @@
mark.clear();
cm.removeLineClass(from, "wrap", "CodeMirror-merge-collapsed-line");
}
+ if (mark.explicitlyCleared) clear();
+ CodeMirror.on(widget, "click", clear);
+ mark.on("clear", clear);
CodeMirror.on(widget, "click", clear);
return {mark: mark, clear: clear};
}
@@ -826,6 +840,7 @@
function TrackAlignable(cm) {
this.cm = cm
this.alignable = []
+ this.height = cm.doc.height
var self = this
cm.on("markerAdded", function(_, marker) {
if (!marker.collapsed) return
@@ -855,11 +870,15 @@
self.check(end, F_MARKER, self.hasMarker)
if (nBefore || nAfter) self.check(change.from.line, F_MARKER, self.hasMarker)
})
+ cm.on("viewportChange", function() {
+ if (self.cm.doc.height != self.height) self.signal()
+ })
}
TrackAlignable.prototype = {
signal: function() {
CodeMirror.signal(this, "realign")
+ this.height = this.cm.doc.height
},
set: function(n, flags) {
diff --git a/gui/public/codemirror/addon/mode/loadmode.js b/gui/public/codemirror/addon/mode/loadmode.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/addon/mode/multiplex.js b/gui/public/codemirror/addon/mode/multiplex.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/addon/mode/multiplex_test.js b/gui/public/codemirror/addon/mode/multiplex_test.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/addon/mode/overlay.js b/gui/public/codemirror/addon/mode/overlay.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/addon/mode/simple.js b/gui/public/codemirror/addon/mode/simple.js
old mode 100755
new mode 100644
index df663365..c0f80108
--- a/gui/public/codemirror/addon/mode/simple.js
+++ b/gui/public/codemirror/addon/mode/simple.js
@@ -77,6 +77,7 @@
function asToken(val) {
if (!val) return null;
+ if (val.apply) return val
if (typeof val == "string") return val.replace(/\./g, " ");
var result = [];
for (var i = 0; i < val.length; i++)
@@ -133,17 +134,19 @@
state.indent.push(stream.indentation() + config.indentUnit);
if (rule.data.dedent)
state.indent.pop();
- if (matches.length > 2) {
+ var token = rule.token
+ if (token && token.apply) token = token(matches)
+ if (matches.length > 2 && rule.token && typeof rule.token != "string") {
state.pending = [];
for (var j = 2; j < matches.length; j++)
if (matches[j])
state.pending.push({text: matches[j], token: rule.token[j - 1]});
stream.backUp(matches[0].length - (matches[1] ? matches[1].length : 0));
- return rule.token[0];
- } else if (rule.token && rule.token.join) {
- return rule.token[0];
+ return token[0];
+ } else if (token && token.join) {
+ return token[0];
} else {
- return rule.token;
+ return token;
}
}
}
diff --git a/gui/public/codemirror/addon/runmode/colorize.js b/gui/public/codemirror/addon/runmode/colorize.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/addon/runmode/runmode-standalone.js b/gui/public/codemirror/addon/runmode/runmode-standalone.js
old mode 100755
new mode 100644
index f4f352c8..1bd808c7
--- a/gui/public/codemirror/addon/runmode/runmode-standalone.js
+++ b/gui/public/codemirror/addon/runmode/runmode-standalone.js
@@ -65,7 +65,8 @@ StringStream.prototype = {
this.lineStart += n;
try { return inner(); }
finally { this.lineStart -= n; }
- }
+ },
+ lookAhead: function() { return null }
};
CodeMirror.StringStream = StringStream;
diff --git a/gui/public/codemirror/addon/runmode/runmode.js b/gui/public/codemirror/addon/runmode/runmode.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/addon/runmode/runmode.node.js b/gui/public/codemirror/addon/runmode/runmode.node.js
old mode 100755
new mode 100644
index b22a5187..21c72696
--- a/gui/public/codemirror/addon/runmode/runmode.node.js
+++ b/gui/public/codemirror/addon/runmode/runmode.node.js
@@ -7,7 +7,7 @@ function splitLines(string){return string.split(/\r\n?|\n/);};
// Counts the column offset in a string, taking tabs into account.
// Used mostly to find indentation.
-var countColumn = function(string, end, tabSize, startIndex, startValue) {
+var countColumn = exports.countColumn = function(string, end, tabSize, startIndex, startValue) {
if (end == null) {
end = string.search(/[^\s\u00a0]/);
if (end == -1) end = string.length;
@@ -22,12 +22,13 @@ var countColumn = function(string, end, tabSize, startIndex, startValue) {
}
};
-function StringStream(string, tabSize) {
+function StringStream(string, tabSize, context) {
this.pos = this.start = 0;
this.string = string;
this.tabSize = tabSize || 8;
this.lastColumnPos = this.lastColumnValue = 0;
this.lineStart = 0;
+ this.context = context
};
StringStream.prototype = {
@@ -91,6 +92,10 @@ StringStream.prototype = {
this.lineStart += n;
try { return inner(); }
finally { this.lineStart -= n; }
+ },
+ lookAhead: function(n) {
+ var line = this.context.line + n
+ return line >= this.context.lines.length ? null : this.context.lines[line]
}
};
exports.StringStream = StringStream;
@@ -158,14 +163,27 @@ exports.getMode = function(options, spec) {
return modeObj;
};
+
+exports.innerMode = function(mode, state) {
+ var info;
+ while (mode.innerMode) {
+ info = mode.innerMode(state);
+ if (!info || info.mode == mode) break;
+ state = info.state;
+ mode = info.mode;
+ }
+ return info || {mode: mode, state: state};
+}
+
exports.registerHelper = exports.registerGlobalHelper = Math.min;
exports.runMode = function(string, modespec, callback, options) {
var mode = exports.getMode({indentUnit: 2}, modespec);
var lines = splitLines(string), state = (options && options.state) || exports.startState(mode);
- for (var i = 0, e = lines.length; i < e; ++i) {
+ var context = {lines: lines, line: 0}
+ for (var i = 0, e = lines.length; i < e; ++i, ++context.line) {
if (i) callback("\n");
- var stream = new exports.StringStream(lines[i]);
+ var stream = new exports.StringStream(lines[i], 4, context);
if (!stream.string && mode.blankLine) mode.blankLine(state);
while (!stream.eol()) {
var style = mode.token(stream, state);
diff --git a/gui/public/codemirror/addon/scroll/annotatescrollbar.js b/gui/public/codemirror/addon/scroll/annotatescrollbar.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/addon/scroll/scrollpastend.js b/gui/public/codemirror/addon/scroll/scrollpastend.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/addon/scroll/simplescrollbars.css b/gui/public/codemirror/addon/scroll/simplescrollbars.css
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/addon/scroll/simplescrollbars.js b/gui/public/codemirror/addon/scroll/simplescrollbars.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/addon/search/jump-to-line.js b/gui/public/codemirror/addon/search/jump-to-line.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/addon/search/match-highlighter.js b/gui/public/codemirror/addon/search/match-highlighter.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/addon/search/matchesonscrollbar.css b/gui/public/codemirror/addon/search/matchesonscrollbar.css
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/addon/search/matchesonscrollbar.js b/gui/public/codemirror/addon/search/matchesonscrollbar.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/addon/search/search.js b/gui/public/codemirror/addon/search/search.js
old mode 100755
new mode 100644
index 753b1afe..4059ccdd
--- a/gui/public/codemirror/addon/search/search.js
+++ b/gui/public/codemirror/addon/search/search.js
@@ -54,7 +54,7 @@
function getSearchCursor(cm, query, pos) {
// Heuristic: if the query string is all lowercase, do a case insensitive search.
- return cm.getSearchCursor(query, pos, queryCaseInsensitive(query));
+ return cm.getSearchCursor(query, pos, {caseFold: queryCaseInsensitive(query), multiline: true});
}
function persistentDialog(cm, text, deflt, onEnter, onKeyDown) {
@@ -99,7 +99,7 @@
}
var queryDialog =
- 'Search: (Use /re/ syntax for regexp search)';
+ 'Search: (Use /re/ syntax for regexp search)';
function startSearch(cm, state, query) {
state.queryText = query;
@@ -117,6 +117,7 @@
var state = getSearchState(cm);
if (state.query) return findNext(cm, rev);
var q = cm.getSelection() || state.lastQuery;
+ if (q instanceof RegExp && q.source == "x^") q = null
if (persistent && cm.openDialog) {
var hiding = null
var searchNext = function(query, event) {
@@ -137,8 +138,7 @@
};
persistentDialog(cm, queryDialog, q, searchNext, function(event, query) {
var keyName = CodeMirror.keyName(event)
- var cmd = CodeMirror.keyMap[cm.getOption("keyMap")][keyName]
- if (!cmd) cmd = cm.getOption('extraKeys')[keyName]
+ var extra = cm.getOption('extraKeys'), cmd = (extra && extra[keyName]) || CodeMirror.keyMap[cm.getOption("keyMap")][keyName]
if (cmd == "findNext" || cmd == "findPrev" ||
cmd == "findPersistentNext" || cmd == "findPersistentPrev") {
CodeMirror.e_stop(event);
@@ -188,8 +188,8 @@
var replaceQueryDialog =
' (Use /re/ syntax for regexp search)';
- var replacementQueryDialog = 'With: ';
- var doReplaceConfirm = "Replace? ";
+ var replacementQueryDialog = 'With: ';
+ var doReplaceConfirm = 'Replace? ';
function replaceAll(cm, query, text) {
cm.operation(function() {
@@ -205,7 +205,7 @@
function replace(cm, all) {
if (cm.getOption("readOnly")) return;
var query = cm.getSelection() || getSearchState(cm).lastQuery;
- var dialogText = all ? "Replace all:" : "Replace:"
+ var dialogText = '' + (all ? 'Replace all:' : 'Replace:') + '';
dialog(cm, dialogText + replaceQueryDialog, dialogText, query, function(query) {
if (!query) return;
query = parseQuery(query);
diff --git a/gui/public/codemirror/addon/search/searchcursor.js b/gui/public/codemirror/addon/search/searchcursor.js
old mode 100755
new mode 100644
index b70242ee..58bc47c2
--- a/gui/public/codemirror/addon/search/searchcursor.js
+++ b/gui/public/codemirror/addon/search/searchcursor.js
@@ -3,187 +3,287 @@
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
- mod(require("../../lib/codemirror"));
+ mod(require("../../lib/codemirror"))
else if (typeof define == "function" && define.amd) // AMD
- define(["../../lib/codemirror"], mod);
+ define(["../../lib/codemirror"], mod)
else // Plain browser env
- mod(CodeMirror);
+ mod(CodeMirror)
})(function(CodeMirror) {
- "use strict";
- var Pos = CodeMirror.Pos;
+ "use strict"
+ var Pos = CodeMirror.Pos
- function SearchCursor(doc, query, pos, caseFold) {
- this.atOccurrence = false; this.doc = doc;
- if (caseFold == null && typeof query == "string") caseFold = false;
+ function regexpFlags(regexp) {
+ var flags = regexp.flags
+ return flags != null ? flags : (regexp.ignoreCase ? "i" : "")
+ + (regexp.global ? "g" : "")
+ + (regexp.multiline ? "m" : "")
+ }
- pos = pos ? doc.clipPos(pos) : Pos(0, 0);
- this.pos = {from: pos, to: pos};
+ function ensureGlobal(regexp) {
+ return regexp.global ? regexp : new RegExp(regexp.source, regexpFlags(regexp) + "g")
+ }
- // The matches method is filled in based on the type of query.
- // It takes a position and a direction, and returns an object
- // describing the next occurrence of the query, or null if no
- // more matches were found.
- if (typeof query != "string") { // Regexp match
- if (!query.global) query = new RegExp(query.source, query.ignoreCase ? "ig" : "g");
- this.matches = function(reverse, pos) {
- if (reverse) {
- query.lastIndex = 0;
- var line = doc.getLine(pos.line).slice(0, pos.ch), cutOff = 0, match, start;
- for (;;) {
- query.lastIndex = cutOff;
- var newMatch = query.exec(line);
- if (!newMatch) break;
- match = newMatch;
- start = match.index;
- cutOff = match.index + (match[0].length || 1);
- if (cutOff == line.length) break;
- }
- var matchLen = (match && match[0].length) || 0;
- if (!matchLen) {
- if (start == 0 && line.length == 0) {match = undefined;}
- else if (start != doc.getLine(pos.line).length) {
- matchLen++;
- }
- }
- } else {
- query.lastIndex = pos.ch;
- var line = doc.getLine(pos.line), match = query.exec(line);
- var matchLen = (match && match[0].length) || 0;
- var start = match && match.index;
- if (start + matchLen != line.length && !matchLen) matchLen = 1;
- }
- if (match && matchLen)
- return {from: Pos(pos.line, start),
- to: Pos(pos.line, start + matchLen),
- match: match};
- };
- } else { // String query
- var origQuery = query;
- if (caseFold) query = query.toLowerCase();
- var fold = caseFold ? function(str){return str.toLowerCase();} : function(str){return str;};
- var target = query.split("\n");
- // Different methods for single-line and multi-line queries
- if (target.length == 1) {
- if (!query.length) {
- // Empty string would match anything and never progress, so
- // we define it to match nothing instead.
- this.matches = function() {};
- } else {
- this.matches = function(reverse, pos) {
- if (reverse) {
- var orig = doc.getLine(pos.line).slice(0, pos.ch), line = fold(orig);
- var match = line.lastIndexOf(query);
- if (match > -1) {
- match = adjustPos(orig, line, match);
- return {from: Pos(pos.line, match), to: Pos(pos.line, match + origQuery.length)};
- }
- } else {
- var orig = doc.getLine(pos.line).slice(pos.ch), line = fold(orig);
- var match = line.indexOf(query);
- if (match > -1) {
- match = adjustPos(orig, line, match) + pos.ch;
- return {from: Pos(pos.line, match), to: Pos(pos.line, match + origQuery.length)};
- }
- }
- };
- }
- } else {
- var origTarget = origQuery.split("\n");
- this.matches = function(reverse, pos) {
- var last = target.length - 1;
- if (reverse) {
- if (pos.line - (target.length - 1) < doc.firstLine()) return;
- if (fold(doc.getLine(pos.line).slice(0, origTarget[last].length)) != target[target.length - 1]) return;
- var to = Pos(pos.line, origTarget[last].length);
- for (var ln = pos.line - 1, i = last - 1; i >= 1; --i, --ln)
- if (target[i] != fold(doc.getLine(ln))) return;
- var line = doc.getLine(ln), cut = line.length - origTarget[0].length;
- if (fold(line.slice(cut)) != target[0]) return;
- return {from: Pos(ln, cut), to: to};
- } else {
- if (pos.line + (target.length - 1) > doc.lastLine()) return;
- var line = doc.getLine(pos.line), cut = line.length - origTarget[0].length;
- if (fold(line.slice(cut)) != target[0]) return;
- var from = Pos(pos.line, cut);
- for (var ln = pos.line + 1, i = 1; i < last; ++i, ++ln)
- if (target[i] != fold(doc.getLine(ln))) return;
- if (fold(doc.getLine(ln).slice(0, origTarget[last].length)) != target[last]) return;
- return {from: from, to: Pos(ln, origTarget[last].length)};
- }
- };
+ function maybeMultiline(regexp) {
+ return /\\s|\\n|\n|\\W|\\D|\[\^/.test(regexp.source)
+ }
+
+ function searchRegexpForward(doc, regexp, start) {
+ regexp = ensureGlobal(regexp)
+ for (var line = start.line, ch = start.ch, last = doc.lastLine(); line <= last; line++, ch = 0) {
+ regexp.lastIndex = ch
+ var string = doc.getLine(line), match = regexp.exec(string)
+ if (match)
+ return {from: Pos(line, match.index),
+ to: Pos(line, match.index + match[0].length),
+ match: match}
+ }
+ }
+
+ function searchRegexpForwardMultiline(doc, regexp, start) {
+ if (!maybeMultiline(regexp)) return searchRegexpForward(doc, regexp, start)
+
+ regexp = ensureGlobal(regexp)
+ var string, chunk = 1
+ for (var line = start.line, last = doc.lastLine(); line <= last;) {
+ // This grows the search buffer in exponentially-sized chunks
+ // between matches, so that nearby matches are fast and don't
+ // require concatenating the whole document (in case we're
+ // searching for something that has tons of matches), but at the
+ // same time, the amount of retries is limited.
+ for (var i = 0; i < chunk; i++) {
+ var curLine = doc.getLine(line++)
+ string = string == null ? curLine : string + "\n" + curLine
}
+ chunk = chunk * 2
+ regexp.lastIndex = start.ch
+ var match = regexp.exec(string)
+ if (match) {
+ var before = string.slice(0, match.index).split("\n"), inside = match[0].split("\n")
+ var startLine = start.line + before.length - 1, startCh = before[before.length - 1].length
+ return {from: Pos(startLine, startCh),
+ to: Pos(startLine + inside.length - 1,
+ inside.length == 1 ? startCh + inside[0].length : inside[inside.length - 1].length),
+ match: match}
+ }
+ }
+ }
+
+ function lastMatchIn(string, regexp) {
+ var cutOff = 0, match
+ for (;;) {
+ regexp.lastIndex = cutOff
+ var newMatch = regexp.exec(string)
+ if (!newMatch) return match
+ match = newMatch
+ cutOff = match.index + (match[0].length || 1)
+ if (cutOff == string.length) return match
+ }
+ }
+
+ function searchRegexpBackward(doc, regexp, start) {
+ regexp = ensureGlobal(regexp)
+ for (var line = start.line, ch = start.ch, first = doc.firstLine(); line >= first; line--, ch = -1) {
+ var string = doc.getLine(line)
+ if (ch > -1) string = string.slice(0, ch)
+ var match = lastMatchIn(string, regexp)
+ if (match)
+ return {from: Pos(line, match.index),
+ to: Pos(line, match.index + match[0].length),
+ match: match}
+ }
+ }
+
+ function searchRegexpBackwardMultiline(doc, regexp, start) {
+ regexp = ensureGlobal(regexp)
+ var string, chunk = 1
+ for (var line = start.line, first = doc.firstLine(); line >= first;) {
+ for (var i = 0; i < chunk; i++) {
+ var curLine = doc.getLine(line--)
+ string = string == null ? curLine.slice(0, start.ch) : curLine + "\n" + string
+ }
+ chunk *= 2
+
+ var match = lastMatchIn(string, regexp)
+ if (match) {
+ var before = string.slice(0, match.index).split("\n"), inside = match[0].split("\n")
+ var startLine = line + before.length, startCh = before[before.length - 1].length
+ return {from: Pos(startLine, startCh),
+ to: Pos(startLine + inside.length - 1,
+ inside.length == 1 ? startCh + inside[0].length : inside[inside.length - 1].length),
+ match: match}
+ }
+ }
+ }
+
+ var doFold, noFold
+ if (String.prototype.normalize) {
+ doFold = function(str) { return str.normalize("NFD").toLowerCase() }
+ noFold = function(str) { return str.normalize("NFD") }
+ } else {
+ doFold = function(str) { return str.toLowerCase() }
+ noFold = function(str) { return str }
+ }
+
+ // Maps a position in a case-folded line back to a position in the original line
+ // (compensating for codepoints increasing in number during folding)
+ function adjustPos(orig, folded, pos, foldFunc) {
+ if (orig.length == folded.length) return pos
+ for (var min = 0, max = pos + Math.max(0, orig.length - folded.length);;) {
+ if (min == max) return min
+ var mid = (min + max) >> 1
+ var len = foldFunc(orig.slice(0, mid)).length
+ if (len == pos) return mid
+ else if (len > pos) max = mid
+ else min = mid + 1
+ }
+ }
+
+ function searchStringForward(doc, query, start, caseFold) {
+ // Empty string would match anything and never progress, so we
+ // define it to match nothing instead.
+ if (!query.length) return null
+ var fold = caseFold ? doFold : noFold
+ var lines = fold(query).split(/\r|\n\r?/)
+
+ search: for (var line = start.line, ch = start.ch, last = doc.lastLine() + 1 - lines.length; line <= last; line++, ch = 0) {
+ var orig = doc.getLine(line).slice(ch), string = fold(orig)
+ if (lines.length == 1) {
+ var found = string.indexOf(lines[0])
+ if (found == -1) continue search
+ var start = adjustPos(orig, string, found, fold) + ch
+ return {from: Pos(line, adjustPos(orig, string, found, fold) + ch),
+ to: Pos(line, adjustPos(orig, string, found + lines[0].length, fold) + ch)}
+ } else {
+ var cutFrom = string.length - lines[0].length
+ if (string.slice(cutFrom) != lines[0]) continue search
+ for (var i = 1; i < lines.length - 1; i++)
+ if (fold(doc.getLine(line + i)) != lines[i]) continue search
+ var end = doc.getLine(line + lines.length - 1), endString = fold(end), lastLine = lines[lines.length - 1]
+ if (endString.slice(0, lastLine.length) != lastLine) continue search
+ return {from: Pos(line, adjustPos(orig, string, cutFrom, fold) + ch),
+ to: Pos(line + lines.length - 1, adjustPos(end, endString, lastLine.length, fold))}
+ }
+ }
+ }
+
+ function searchStringBackward(doc, query, start, caseFold) {
+ if (!query.length) return null
+ var fold = caseFold ? doFold : noFold
+ var lines = fold(query).split(/\r|\n\r?/)
+
+ search: for (var line = start.line, ch = start.ch, first = doc.firstLine() - 1 + lines.length; line >= first; line--, ch = -1) {
+ var orig = doc.getLine(line)
+ if (ch > -1) orig = orig.slice(0, ch)
+ var string = fold(orig)
+ if (lines.length == 1) {
+ var found = string.lastIndexOf(lines[0])
+ if (found == -1) continue search
+ return {from: Pos(line, adjustPos(orig, string, found, fold)),
+ to: Pos(line, adjustPos(orig, string, found + lines[0].length, fold))}
+ } else {
+ var lastLine = lines[lines.length - 1]
+ if (string.slice(0, lastLine.length) != lastLine) continue search
+ for (var i = 1, start = line - lines.length + 1; i < lines.length - 1; i++)
+ if (fold(doc.getLine(start + i)) != lines[i]) continue search
+ var top = doc.getLine(line + 1 - lines.length), topString = fold(top)
+ if (topString.slice(topString.length - lines[0].length) != lines[0]) continue search
+ return {from: Pos(line + 1 - lines.length, adjustPos(top, topString, top.length - lines[0].length, fold)),
+ to: Pos(line, adjustPos(orig, string, lastLine.length, fold))}
+ }
+ }
+ }
+
+ function SearchCursor(doc, query, pos, options) {
+ this.atOccurrence = false
+ this.doc = doc
+ pos = pos ? doc.clipPos(pos) : Pos(0, 0)
+ this.pos = {from: pos, to: pos}
+
+ var caseFold
+ if (typeof options == "object") {
+ caseFold = options.caseFold
+ } else { // Backwards compat for when caseFold was the 4th argument
+ caseFold = options
+ options = null
+ }
+
+ if (typeof query == "string") {
+ if (caseFold == null) caseFold = false
+ this.matches = function(reverse, pos) {
+ return (reverse ? searchStringBackward : searchStringForward)(doc, query, pos, caseFold)
+ }
+ } else {
+ query = ensureGlobal(query)
+ if (!options || options.multiline !== false)
+ this.matches = function(reverse, pos) {
+ return (reverse ? searchRegexpBackwardMultiline : searchRegexpForwardMultiline)(doc, query, pos)
+ }
+ else
+ this.matches = function(reverse, pos) {
+ return (reverse ? searchRegexpBackward : searchRegexpForward)(doc, query, pos)
+ }
}
}
SearchCursor.prototype = {
- findNext: function() {return this.find(false);},
- findPrevious: function() {return this.find(true);},
+ findNext: function() {return this.find(false)},
+ findPrevious: function() {return this.find(true)},
find: function(reverse) {
- var self = this, pos = this.doc.clipPos(reverse ? this.pos.from : this.pos.to);
- function savePosAndFail(line) {
- var pos = Pos(line, 0);
- self.pos = {from: pos, to: pos};
- self.atOccurrence = false;
- return false;
+ var result = this.matches(reverse, this.doc.clipPos(reverse ? this.pos.from : this.pos.to))
+
+ // Implements weird auto-growing behavior on null-matches for
+ // backwards-compatiblity with the vim code (unfortunately)
+ while (result && CodeMirror.cmpPos(result.from, result.to) == 0) {
+ if (reverse) {
+ if (result.from.ch) result.from = Pos(result.from.line, result.from.ch - 1)
+ else if (result.from.line == this.doc.firstLine()) result = null
+ else result = this.matches(reverse, this.doc.clipPos(Pos(result.from.line - 1)))
+ } else {
+ if (result.to.ch < this.doc.getLine(result.to.line).length) result.to = Pos(result.to.line, result.to.ch + 1)
+ else if (result.to.line == this.doc.lastLine()) result = null
+ else result = this.matches(reverse, Pos(result.to.line + 1, 0))
+ }
}
- for (;;) {
- if (this.pos = this.matches(reverse, pos)) {
- this.atOccurrence = true;
- return this.pos.match || true;
- }
- if (reverse) {
- if (!pos.line) return savePosAndFail(0);
- pos = Pos(pos.line-1, this.doc.getLine(pos.line-1).length);
- }
- else {
- var maxLine = this.doc.lineCount();
- if (pos.line == maxLine - 1) return savePosAndFail(maxLine);
- pos = Pos(pos.line + 1, 0);
- }
+ if (result) {
+ this.pos = result
+ this.atOccurrence = true
+ return this.pos.match || true
+ } else {
+ var end = Pos(reverse ? this.doc.firstLine() : this.doc.lastLine() + 1, 0)
+ this.pos = {from: end, to: end}
+ return this.atOccurrence = false
}
},
- from: function() {if (this.atOccurrence) return this.pos.from;},
- to: function() {if (this.atOccurrence) return this.pos.to;},
+ from: function() {if (this.atOccurrence) return this.pos.from},
+ to: function() {if (this.atOccurrence) return this.pos.to},
replace: function(newText, origin) {
- if (!this.atOccurrence) return;
- var lines = CodeMirror.splitLines(newText);
- this.doc.replaceRange(lines, this.pos.from, this.pos.to, origin);
+ if (!this.atOccurrence) return
+ var lines = CodeMirror.splitLines(newText)
+ this.doc.replaceRange(lines, this.pos.from, this.pos.to, origin)
this.pos.to = Pos(this.pos.from.line + lines.length - 1,
- lines[lines.length - 1].length + (lines.length == 1 ? this.pos.from.ch : 0));
- }
- };
-
- // Maps a position in a case-folded line back to a position in the original line
- // (compensating for codepoints increasing in number during folding)
- function adjustPos(orig, folded, pos) {
- if (orig.length == folded.length) return pos;
- for (var pos1 = Math.min(pos, orig.length);;) {
- var len1 = orig.slice(0, pos1).toLowerCase().length;
- if (len1 < pos) ++pos1;
- else if (len1 > pos) --pos1;
- else return pos1;
+ lines[lines.length - 1].length + (lines.length == 1 ? this.pos.from.ch : 0))
}
}
CodeMirror.defineExtension("getSearchCursor", function(query, pos, caseFold) {
- return new SearchCursor(this.doc, query, pos, caseFold);
- });
+ return new SearchCursor(this.doc, query, pos, caseFold)
+ })
CodeMirror.defineDocExtension("getSearchCursor", function(query, pos, caseFold) {
- return new SearchCursor(this, query, pos, caseFold);
- });
+ return new SearchCursor(this, query, pos, caseFold)
+ })
CodeMirror.defineExtension("selectMatches", function(query, caseFold) {
- var ranges = [];
- var cur = this.getSearchCursor(query, this.getCursor("from"), caseFold);
+ var ranges = []
+ var cur = this.getSearchCursor(query, this.getCursor("from"), caseFold)
while (cur.findNext()) {
- if (CodeMirror.cmpPos(cur.to(), this.getCursor("to")) > 0) break;
- ranges.push({anchor: cur.from(), head: cur.to()});
+ if (CodeMirror.cmpPos(cur.to(), this.getCursor("to")) > 0) break
+ ranges.push({anchor: cur.from(), head: cur.to()})
}
if (ranges.length)
- this.setSelections(ranges, 0);
- });
+ this.setSelections(ranges, 0)
+ })
});
diff --git a/gui/public/codemirror/addon/selection/active-line.js b/gui/public/codemirror/addon/selection/active-line.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/addon/selection/mark-selection.js b/gui/public/codemirror/addon/selection/mark-selection.js
old mode 100755
new mode 100644
index 5c42d21e..1602acc3
--- a/gui/public/codemirror/addon/selection/mark-selection.js
+++ b/gui/public/codemirror/addon/selection/mark-selection.js
@@ -34,11 +34,12 @@
});
function onCursorActivity(cm) {
- cm.operation(function() { update(cm); });
+ if (cm.state.markedSelection)
+ cm.operation(function() { update(cm); });
}
function onChange(cm) {
- if (cm.state.markedSelection.length)
+ if (cm.state.markedSelection && cm.state.markedSelection.length)
cm.operation(function() { clear(cm); });
}
@@ -85,7 +86,7 @@
if (!array.length) return coverRange(cm, from, to);
var coverStart = array[0].find(), coverEnd = array[array.length - 1].find();
- if (!coverStart || !coverEnd || to.line - from.line < CHUNK_SIZE ||
+ if (!coverStart || !coverEnd || to.line - from.line <= CHUNK_SIZE ||
cmp(from, coverEnd.to) >= 0 || cmp(to, coverStart.from) <= 0)
return reset(cm);
diff --git a/gui/public/codemirror/addon/selection/selection-pointer.js b/gui/public/codemirror/addon/selection/selection-pointer.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/addon/tern/tern.css b/gui/public/codemirror/addon/tern/tern.css
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/addon/tern/tern.js b/gui/public/codemirror/addon/tern/tern.js
old mode 100755
new mode 100644
index efdf2ed6..a80dc7e4
--- a/gui/public/codemirror/addon/tern/tern.js
+++ b/gui/public/codemirror/addon/tern/tern.js
@@ -334,7 +334,11 @@
tip.appendChild(document.createTextNode(tp.rettype ? ") ->\u00a0" : ")"));
if (tp.rettype) tip.appendChild(elt("span", cls + "type", tp.rettype));
var place = cm.cursorCoords(null, "page");
- ts.activeArgHints = makeTooltip(place.right + 1, place.bottom, tip);
+ var tooltip = ts.activeArgHints = makeTooltip(place.right + 1, place.bottom, tip)
+ setTimeout(function() {
+ tooltip.clear = onEditorActivity(cm, function() {
+ if (ts.activeArgHints == tooltip) closeArgHints(ts) })
+ }, 20)
}
function parseFnType(text) {
@@ -567,7 +571,7 @@
return {type: "part",
name: data.name,
offsetLines: from.line,
- text: doc.getRange(from, Pos(endLine, 0))};
+ text: doc.getRange(from, Pos(endLine, end.line == endLine ? null : 0))};
}
// Generic utilities
@@ -604,11 +608,8 @@
}
function clear() {
cm.state.ternTooltip = null;
- if (!tip.parentNode) return;
- cm.off("cursorActivity", clear);
- cm.off('blur', clear);
- cm.off('scroll', clear);
- fadeOut(tip);
+ if (tip.parentNode) fadeOut(tip)
+ clearActivity()
}
var mouseOnTip = false, old = false;
CodeMirror.on(tip, "mousemove", function() { mouseOnTip = true; });
@@ -619,9 +620,20 @@
}
});
setTimeout(maybeClear, ts.options.hintDelay ? ts.options.hintDelay : 1700);
- cm.on("cursorActivity", clear);
- cm.on('blur', clear);
- cm.on('scroll', clear);
+ var clearActivity = onEditorActivity(cm, clear)
+ }
+
+ function onEditorActivity(cm, f) {
+ cm.on("cursorActivity", f)
+ cm.on("blur", f)
+ cm.on("scroll", f)
+ cm.on("setDoc", f)
+ return function() {
+ cm.off("cursorActivity", f)
+ cm.off("blur", f)
+ cm.off("scroll", f)
+ cm.off("setDoc", f)
+ }
}
function makeTooltip(x, y, content) {
@@ -650,7 +662,11 @@
}
function closeArgHints(ts) {
- if (ts.activeArgHints) { remove(ts.activeArgHints); ts.activeArgHints = null; }
+ if (ts.activeArgHints) {
+ if (ts.activeArgHints.clear) ts.activeArgHints.clear()
+ remove(ts.activeArgHints)
+ ts.activeArgHints = null
+ }
}
function docValue(ts, doc) {
diff --git a/gui/public/codemirror/addon/tern/worker.js b/gui/public/codemirror/addon/tern/worker.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/addon/wrap/hardwrap.js b/gui/public/codemirror/addon/wrap/hardwrap.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/lib/codemirror.js b/gui/public/codemirror/lib/codemirror.js
index 80ab0653..a9fa82fa 100755
--- a/gui/public/codemirror/lib/codemirror.js
+++ b/gui/public/codemirror/lib/codemirror.js
@@ -76,6 +76,12 @@ function elt(tag, content, className, style) {
else if (content) { for (var i = 0; i < content.length; ++i) { e.appendChild(content[i]) } }
return e
}
+// wrapper for elt, which removes the elt from the accessibility tree
+function eltP(tag, content, className, style) {
+ var e = elt(tag, content, className, style)
+ e.setAttribute("role", "presentation")
+ return e
+}
var range
if (document.createRange) { range = function(node, start, end, endNode) {
@@ -272,13 +278,18 @@ function skipExtendingChars(str, pos, dir) {
}
// Returns the value from the range [`from`; `to`] that satisfies
-// `pred` and is closest to `from`. Assumes that at least `to` satisfies `pred`.
+// `pred` and is closest to `from`. Assumes that at least `to`
+// satisfies `pred`. Supports `from` being greater than `to`.
function findFirst(pred, from, to) {
+ // At any point we are certain `to` satisfies `pred`, don't know
+ // whether `from` does.
+ var dir = from > to ? -1 : 1
for (;;) {
- if (Math.abs(from - to) <= 1) { return pred(from) ? from : to }
- var mid = Math.floor((from + to) / 2)
+ if (from == to) { return from }
+ var midF = (from + to) / 2, mid = dir < 0 ? Math.ceil(midF) : Math.floor(midF)
+ if (mid == from) { return pred(mid) ? from : to }
if (pred(mid)) { to = mid }
- else { from = mid }
+ else { from = mid + dir }
}
}
@@ -298,7 +309,7 @@ function Display(place, doc, input) {
d.gutterFiller = elt("div", null, "CodeMirror-gutter-filler")
d.gutterFiller.setAttribute("cm-not-content", "true")
// Will contain the actual code, positioned to cover the viewport.
- d.lineDiv = elt("div", null, "CodeMirror-code")
+ d.lineDiv = eltP("div", null, "CodeMirror-code")
// Elements are added to these to represent selection and cursors.
d.selectionDiv = elt("div", null, null, "position: relative; z-index: 1")
d.cursorDiv = elt("div", null, "CodeMirror-cursors")
@@ -307,10 +318,11 @@ function Display(place, doc, input) {
// When lines outside of the viewport are measured, they are drawn in this.
d.lineMeasure = elt("div", null, "CodeMirror-measure")
// Wraps everything that needs to exist inside the vertically-padded coordinate system
- d.lineSpace = elt("div", [d.measure, d.lineMeasure, d.selectionDiv, d.cursorDiv, d.lineDiv],
+ d.lineSpace = eltP("div", [d.measure, d.lineMeasure, d.selectionDiv, d.cursorDiv, d.lineDiv],
null, "position: relative; outline: none")
+ var lines = eltP("div", [d.lineSpace], "CodeMirror-lines")
// Moved around its parent to cover visible view.
- d.mover = elt("div", [elt("div", [d.lineSpace], "CodeMirror-lines")], null, "position: relative")
+ d.mover = elt("div", [lines], null, "position: relative")
// Set to the height of the document, allowing scrolling.
d.sizer = elt("div", [d.mover], "CodeMirror-sizer")
d.sizerWidth = null
@@ -890,12 +902,12 @@ function findMaxLine(cm) {
// BIDI HELPERS
function iterateBidiSections(order, from, to, f) {
- if (!order) { return f(from, to, "ltr") }
+ if (!order) { return f(from, to, "ltr", 0) }
var found = false
for (var i = 0; i < order.length; ++i) {
var part = order[i]
if (part.from < to && part.to > from || from == to && part.to == from) {
- f(Math.max(part.from, from), Math.min(part.to, to), part.level == 1 ? "rtl" : "ltr")
+ f(Math.max(part.from, from), Math.min(part.to, to), part.level == 1 ? "rtl" : "ltr", i)
found = true
}
}
@@ -1076,13 +1088,15 @@ var bidiOrdering = (function() {
if (pos < i$7) { order.splice(at, 0, new BidiSpan(1, pos, i$7)) }
}
}
- if (order[0].level == 1 && (m = str.match(/^\s+/))) {
- order[0].from = m[0].length
- order.unshift(new BidiSpan(0, 0, m[0].length))
- }
- if (lst(order).level == 1 && (m = str.match(/\s+$/))) {
- lst(order).to -= m[0].length
- order.push(new BidiSpan(0, len - m[0].length, len))
+ if (direction == "ltr") {
+ if (order[0].level == 1 && (m = str.match(/^\s+/))) {
+ order[0].from = m[0].length
+ order.unshift(new BidiSpan(0, 0, m[0].length))
+ }
+ if (lst(order).level == 1 && (m = str.match(/\s+$/))) {
+ lst(order).to -= m[0].length
+ order.push(new BidiSpan(0, len - m[0].length, len))
+ }
}
return direction == "rtl" ? order.reverse() : order
@@ -1098,112 +1112,6 @@ function getOrder(line, direction) {
return order
}
-function moveCharLogically(line, ch, dir) {
- var target = skipExtendingChars(line.text, ch + dir, dir)
- return target < 0 || target > line.text.length ? null : target
-}
-
-function moveLogically(line, start, dir) {
- var ch = moveCharLogically(line, start.ch, dir)
- return ch == null ? null : new Pos(start.line, ch, dir < 0 ? "after" : "before")
-}
-
-function endOfLine(visually, cm, lineObj, lineNo, dir) {
- if (visually) {
- var order = getOrder(lineObj, cm.doc.direction)
- if (order) {
- var part = dir < 0 ? lst(order) : order[0]
- var moveInStorageOrder = (dir < 0) == (part.level == 1)
- var sticky = moveInStorageOrder ? "after" : "before"
- var ch
- // With a wrapped rtl chunk (possibly spanning multiple bidi parts),
- // it could be that the last bidi part is not on the last visual line,
- // since visual lines contain content order-consecutive chunks.
- // Thus, in rtl, we are looking for the first (content-order) character
- // in the rtl chunk that is on the last line (that is, the same line
- // as the last (content-order) character).
- if (part.level > 0) {
- var prep = prepareMeasureForLine(cm, lineObj)
- ch = dir < 0 ? lineObj.text.length - 1 : 0
- var targetTop = measureCharPrepared(cm, prep, ch).top
- ch = findFirst(function (ch) { return measureCharPrepared(cm, prep, ch).top == targetTop; }, (dir < 0) == (part.level == 1) ? part.from : part.to - 1, ch)
- if (sticky == "before") { ch = moveCharLogically(lineObj, ch, 1, true) }
- } else { ch = dir < 0 ? part.to : part.from }
- return new Pos(lineNo, ch, sticky)
- }
- }
- return new Pos(lineNo, dir < 0 ? lineObj.text.length : 0, dir < 0 ? "before" : "after")
-}
-
-function moveVisually(cm, line, start, dir) {
- var bidi = getOrder(line, cm.doc.direction)
- if (!bidi) { return moveLogically(line, start, dir) }
- if (start.ch >= line.text.length) {
- start.ch = line.text.length
- start.sticky = "before"
- } else if (start.ch <= 0) {
- start.ch = 0
- start.sticky = "after"
- }
- var partPos = getBidiPartAt(bidi, start.ch, start.sticky), part = bidi[partPos]
- if (cm.doc.direction == "ltr" && part.level % 2 == 0 && (dir > 0 ? part.to > start.ch : part.from < start.ch)) {
- // Case 1: We move within an ltr part in an ltr editor. Even with wrapped lines,
- // nothing interesting happens.
- return moveLogically(line, start, dir)
- }
-
- var mv = function (pos, dir) { return moveCharLogically(line, pos instanceof Pos ? pos.ch : pos, dir); }
- var prep
- var getWrappedLineExtent = function (ch) {
- if (!cm.options.lineWrapping) { return {begin: 0, end: line.text.length} }
- prep = prep || prepareMeasureForLine(cm, line)
- return wrappedLineExtentChar(cm, line, prep, ch)
- }
- var wrappedLineExtent = getWrappedLineExtent(start.sticky == "before" ? mv(start, -1) : start.ch)
-
- if (cm.doc.direction == "rtl" || part.level == 1) {
- var moveInStorageOrder = (part.level == 1) == (dir < 0)
- var ch = mv(start, moveInStorageOrder ? 1 : -1)
- if (ch != null && (!moveInStorageOrder ? ch >= part.from && ch >= wrappedLineExtent.begin : ch <= part.to && ch <= wrappedLineExtent.end)) {
- // Case 2: We move within an rtl part or in an rtl editor on the same visual line
- var sticky = moveInStorageOrder ? "before" : "after"
- return new Pos(start.line, ch, sticky)
- }
- }
-
- // Case 3: Could not move within this bidi part in this visual line, so leave
- // the current bidi part
-
- var searchInVisualLine = function (partPos, dir, wrappedLineExtent) {
- var getRes = function (ch, moveInStorageOrder) { return moveInStorageOrder
- ? new Pos(start.line, mv(ch, 1), "before")
- : new Pos(start.line, ch, "after"); }
-
- for (; partPos >= 0 && partPos < bidi.length; partPos += dir) {
- var part = bidi[partPos]
- var moveInStorageOrder = (dir > 0) == (part.level != 1)
- var ch = moveInStorageOrder ? wrappedLineExtent.begin : mv(wrappedLineExtent.end, -1)
- if (part.from <= ch && ch < part.to) { return getRes(ch, moveInStorageOrder) }
- ch = moveInStorageOrder ? part.from : mv(part.to, -1)
- if (wrappedLineExtent.begin <= ch && ch < wrappedLineExtent.end) { return getRes(ch, moveInStorageOrder) }
- }
- }
-
- // Case 3a: Look for other bidi parts on the same visual line
- var res = searchInVisualLine(partPos + dir, dir, wrappedLineExtent)
- if (res) { return res }
-
- // Case 3b: Look for other bidi parts on the next visual line
- var nextCh = dir > 0 ? wrappedLineExtent.end : mv(wrappedLineExtent.begin, -1)
- if (nextCh != null && !(dir > 0 && nextCh == line.text.length)) {
- res = searchInVisualLine(dir > 0 ? 0 : bidi.length - 1, dir, getWrappedLineExtent(nextCh))
- if (res) { return res }
- }
-
- // Case 4: Nowhere to move
- return null
-}
-
// EVENT HANDLING
// Lightweight event framework. on/off also work on DOM nodes,
@@ -1486,12 +1394,13 @@ function startState(mode, a1, a2) {
// Fed to the mode parsers, provides helper functions to make
// parsers more succinct.
-var StringStream = function(string, tabSize) {
+var StringStream = function(string, tabSize, lineOracle) {
this.pos = this.start = 0
this.string = string
this.tabSize = tabSize || 8
this.lastColumnPos = this.lastColumnValue = 0
this.lineStart = 0
+ this.lineOracle = lineOracle
};
StringStream.prototype.eol = function () {return this.pos >= this.string.length};
@@ -1558,23 +1467,83 @@ StringStream.prototype.hideFirstChars = function (n, inner) {
try { return inner() }
finally { this.lineStart -= n }
};
+StringStream.prototype.lookAhead = function (n) {
+ var oracle = this.lineOracle
+ return oracle && oracle.lookAhead(n)
+};
+StringStream.prototype.baseToken = function () {
+ var oracle = this.lineOracle
+ return oracle && oracle.baseToken(this.pos)
+};
+
+var SavedContext = function(state, lookAhead) {
+ this.state = state
+ this.lookAhead = lookAhead
+};
+
+var Context = function(doc, state, line, lookAhead) {
+ this.state = state
+ this.doc = doc
+ this.line = line
+ this.maxLookAhead = lookAhead || 0
+ this.baseTokens = null
+ this.baseTokenPos = 1
+};
+
+Context.prototype.lookAhead = function (n) {
+ var line = this.doc.getLine(this.line + n)
+ if (line != null && n > this.maxLookAhead) { this.maxLookAhead = n }
+ return line
+};
+
+Context.prototype.baseToken = function (n) {
+ var this$1 = this;
+
+ if (!this.baseTokens) { return null }
+ while (this.baseTokens[this.baseTokenPos] <= n)
+ { this$1.baseTokenPos += 2 }
+ var type = this.baseTokens[this.baseTokenPos + 1]
+ return {type: type && type.replace(/( |^)overlay .*/, ""),
+ size: this.baseTokens[this.baseTokenPos] - n}
+};
+
+Context.prototype.nextLine = function () {
+ this.line++
+ if (this.maxLookAhead > 0) { this.maxLookAhead-- }
+};
+
+Context.fromSaved = function (doc, saved, line) {
+ if (saved instanceof SavedContext)
+ { return new Context(doc, copyState(doc.mode, saved.state), line, saved.lookAhead) }
+ else
+ { return new Context(doc, copyState(doc.mode, saved), line) }
+};
+
+Context.prototype.save = function (copy) {
+ var state = copy !== false ? copyState(this.doc.mode, this.state) : this.state
+ return this.maxLookAhead > 0 ? new SavedContext(state, this.maxLookAhead) : state
+};
+
// Compute a style array (an array starting with a mode generation
// -- for invalidation -- followed by pairs of end positions and
// style strings), which is used to highlight the tokens on the
// line.
-function highlightLine(cm, line, state, forceToEnd) {
+function highlightLine(cm, line, context, forceToEnd) {
// A styles array always starts with a number identifying the
// mode/overlays that it is based on (for easy invalidation).
var st = [cm.state.modeGen], lineClasses = {}
// Compute the base array of styles
- runMode(cm, line.text, cm.doc.mode, state, function (end, style) { return st.push(end, style); },
- lineClasses, forceToEnd)
+ runMode(cm, line.text, cm.doc.mode, context, function (end, style) { return st.push(end, style); },
+ lineClasses, forceToEnd)
+ var state = context.state
// Run overlays, adjust style array.
var loop = function ( o ) {
+ context.baseTokens = st
var overlay = cm.state.overlays[o], i = 1, at = 0
- runMode(cm, line.text, overlay.mode, true, function (end, style) {
+ context.state = true
+ runMode(cm, line.text, overlay.mode, context, function (end, style) {
var start = i
// Ensure there's a token end at the current position, and that i points at it
while (at < end) {
@@ -1595,6 +1564,9 @@ function highlightLine(cm, line, state, forceToEnd) {
}
}
}, lineClasses)
+ context.state = state
+ context.baseTokens = null
+ context.baseTokenPos = 1
};
for (var o = 0; o < cm.state.overlays.length; ++o) loop( o );
@@ -1604,43 +1576,47 @@ function highlightLine(cm, line, state, forceToEnd) {
function getLineStyles(cm, line, updateFrontier) {
if (!line.styles || line.styles[0] != cm.state.modeGen) {
- var state = getStateBefore(cm, lineNo(line))
- var result = highlightLine(cm, line, line.text.length > cm.options.maxHighlightLength ? copyState(cm.doc.mode, state) : state)
- line.stateAfter = state
+ var context = getContextBefore(cm, lineNo(line))
+ var resetState = line.text.length > cm.options.maxHighlightLength && copyState(cm.doc.mode, context.state)
+ var result = highlightLine(cm, line, context)
+ if (resetState) { context.state = resetState }
+ line.stateAfter = context.save(!resetState)
line.styles = result.styles
if (result.classes) { line.styleClasses = result.classes }
else if (line.styleClasses) { line.styleClasses = null }
- if (updateFrontier === cm.doc.frontier) { cm.doc.frontier++ }
+ if (updateFrontier === cm.doc.highlightFrontier)
+ { cm.doc.modeFrontier = Math.max(cm.doc.modeFrontier, ++cm.doc.highlightFrontier) }
}
return line.styles
}
-function getStateBefore(cm, n, precise) {
+function getContextBefore(cm, n, precise) {
var doc = cm.doc, display = cm.display
- if (!doc.mode.startState) { return true }
- var pos = findStartLine(cm, n, precise), state = pos > doc.first && getLine(doc, pos-1).stateAfter
- if (!state) { state = startState(doc.mode) }
- else { state = copyState(doc.mode, state) }
- doc.iter(pos, n, function (line) {
- processLine(cm, line.text, state)
- var save = pos == n - 1 || pos % 5 == 0 || pos >= display.viewFrom && pos < display.viewTo
- line.stateAfter = save ? copyState(doc.mode, state) : null
- ++pos
+ if (!doc.mode.startState) { return new Context(doc, true, n) }
+ var start = findStartLine(cm, n, precise)
+ var saved = start > doc.first && getLine(doc, start - 1).stateAfter
+ var context = saved ? Context.fromSaved(doc, saved, start) : new Context(doc, startState(doc.mode), start)
+
+ doc.iter(start, n, function (line) {
+ processLine(cm, line.text, context)
+ var pos = context.line
+ line.stateAfter = pos == n - 1 || pos % 5 == 0 || pos >= display.viewFrom && pos < display.viewTo ? context.save() : null
+ context.nextLine()
})
- if (precise) { doc.frontier = pos }
- return state
+ if (precise) { doc.modeFrontier = context.line }
+ return context
}
// Lightweight form of highlight -- proceed over this line and
// update state, but don't save a style array. Used for lines that
// aren't currently visible.
-function processLine(cm, text, state, startAt) {
+function processLine(cm, text, context, startAt) {
var mode = cm.doc.mode
- var stream = new StringStream(text, cm.options.tabSize)
+ var stream = new StringStream(text, cm.options.tabSize, context)
stream.start = stream.pos = startAt || 0
- if (text == "") { callBlankLine(mode, state) }
+ if (text == "") { callBlankLine(mode, context.state) }
while (!stream.eol()) {
- readToken(mode, stream, state)
+ readToken(mode, stream, context.state)
stream.start = stream.pos
}
}
@@ -1661,26 +1637,26 @@ function readToken(mode, stream, state, inner) {
throw new Error("Mode " + mode.name + " failed to advance stream.")
}
+var Token = function(stream, type, state) {
+ this.start = stream.start; this.end = stream.pos
+ this.string = stream.current()
+ this.type = type || null
+ this.state = state
+};
+
// Utility for getTokenAt and getLineTokens
function takeToken(cm, pos, precise, asArray) {
- var getObj = function (copy) { return ({
- start: stream.start, end: stream.pos,
- string: stream.current(),
- type: style || null,
- state: copy ? copyState(doc.mode, state) : state
- }); }
-
var doc = cm.doc, mode = doc.mode, style
pos = clipPos(doc, pos)
- var line = getLine(doc, pos.line), state = getStateBefore(cm, pos.line, precise)
- var stream = new StringStream(line.text, cm.options.tabSize), tokens
+ var line = getLine(doc, pos.line), context = getContextBefore(cm, pos.line, precise)
+ var stream = new StringStream(line.text, cm.options.tabSize, context), tokens
if (asArray) { tokens = [] }
while ((asArray || stream.pos < pos.ch) && !stream.eol()) {
stream.start = stream.pos
- style = readToken(mode, stream, state)
- if (asArray) { tokens.push(getObj(true)) }
+ style = readToken(mode, stream, context.state)
+ if (asArray) { tokens.push(new Token(stream, style, copyState(doc.mode, context.state))) }
}
- return asArray ? tokens : getObj()
+ return asArray ? tokens : new Token(stream, style, context.state)
}
function extractLineClasses(type, output) {
@@ -1698,21 +1674,21 @@ function extractLineClasses(type, output) {
}
// Run the given mode's parser over a line, calling f for each token.
-function runMode(cm, text, mode, state, f, lineClasses, forceToEnd) {
+function runMode(cm, text, mode, context, f, lineClasses, forceToEnd) {
var flattenSpans = mode.flattenSpans
if (flattenSpans == null) { flattenSpans = cm.options.flattenSpans }
var curStart = 0, curStyle = null
- var stream = new StringStream(text, cm.options.tabSize), style
+ var stream = new StringStream(text, cm.options.tabSize, context), style
var inner = cm.options.addModeClass && [null]
- if (text == "") { extractLineClasses(callBlankLine(mode, state), lineClasses) }
+ if (text == "") { extractLineClasses(callBlankLine(mode, context.state), lineClasses) }
while (!stream.eol()) {
if (stream.pos > cm.options.maxHighlightLength) {
flattenSpans = false
- if (forceToEnd) { processLine(cm, text, state, stream.pos) }
+ if (forceToEnd) { processLine(cm, text, context, stream.pos) }
stream.pos = text.length
style = null
} else {
- style = extractLineClasses(readToken(mode, stream, state, inner), lineClasses)
+ style = extractLineClasses(readToken(mode, stream, context.state, inner), lineClasses)
}
if (inner) {
var mName = inner[0].name
@@ -1747,8 +1723,9 @@ function findStartLine(cm, n, precise) {
var lim = precise ? -1 : n - (cm.doc.mode.innerMode ? 1000 : 100)
for (var search = n; search > lim; --search) {
if (search <= doc.first) { return doc.first }
- var line = getLine(doc, search - 1)
- if (line.stateAfter && (!precise || search <= doc.frontier)) { return search }
+ var line = getLine(doc, search - 1), after = line.stateAfter
+ if (after && (!precise || search + (after instanceof SavedContext ? after.lookAhead : 0) <= doc.modeFrontier))
+ { return search }
var indented = countColumn(line.text, null, cm.options.tabSize)
if (minline == null || minindent > indented) {
minline = search - 1
@@ -1758,6 +1735,23 @@ function findStartLine(cm, n, precise) {
return minline
}
+function retreatFrontier(doc, n) {
+ doc.modeFrontier = Math.min(doc.modeFrontier, n)
+ if (doc.highlightFrontier < n - 10) { return }
+ var start = doc.first
+ for (var line = n - 1; line > start; line--) {
+ var saved = getLine(doc, line).stateAfter
+ // change is on 3
+ // state on line 1 looked ahead 2 -- so saw 3
+ // test 1 + 2 < 3 should cover this
+ if (saved && (!(saved instanceof SavedContext) || line + saved.lookAhead < n)) {
+ start = line + 1
+ break
+ }
+ }
+ doc.highlightFrontier = Math.min(doc.highlightFrontier, start)
+}
+
// LINE DATA STRUCTURE
// Line objects. These hold state related to a line, including
@@ -1812,14 +1806,11 @@ function buildLineContent(cm, lineView) {
// The padding-right forces the element to have a 'border', which
// is needed on Webkit to be able to get line-level bounding
// rectangles for it (in measureChar).
- var content = elt("span", null, null, webkit ? "padding-right: .1px" : null)
- var builder = {pre: elt("pre", [content], "CodeMirror-line"), content: content,
+ var content = eltP("span", null, null, webkit ? "padding-right: .1px" : null)
+ var builder = {pre: eltP("pre", [content], "CodeMirror-line"), content: content,
col: 0, pos: 0, cm: cm,
trailingSpace: false,
splitSpaces: (ie || webkit) && cm.getOption("lineWrapping")}
- // hide from accessibility tree
- content.setAttribute("role", "presentation")
- builder.pre.setAttribute("role", "presentation")
lineView.measure = {}
// Iterate over the logical lines that make up this visual line.
@@ -2637,18 +2628,34 @@ function clearCaches(cm) {
cm.display.lineNumChars = null
}
-function pageScrollX() { return window.pageXOffset || (document.documentElement || document.body).scrollLeft }
-function pageScrollY() { return window.pageYOffset || (document.documentElement || document.body).scrollTop }
+function pageScrollX() {
+ // Work around https://bugs.chromium.org/p/chromium/issues/detail?id=489206
+ // which causes page_Offset and bounding client rects to use
+ // different reference viewports and invalidate our calculations.
+ if (chrome && android) { return -(document.body.getBoundingClientRect().left - parseInt(getComputedStyle(document.body).marginLeft)) }
+ return window.pageXOffset || (document.documentElement || document.body).scrollLeft
+}
+function pageScrollY() {
+ if (chrome && android) { return -(document.body.getBoundingClientRect().top - parseInt(getComputedStyle(document.body).marginTop)) }
+ return window.pageYOffset || (document.documentElement || document.body).scrollTop
+}
+
+function widgetTopHeight(lineObj) {
+ var height = 0
+ if (lineObj.widgets) { for (var i = 0; i < lineObj.widgets.length; ++i) { if (lineObj.widgets[i].above)
+ { height += widgetHeight(lineObj.widgets[i]) } } }
+ return height
+}
// Converts a {top, bottom, left, right} box from line-local
// coordinates into another coordinate system. Context may be one of
// "line", "div" (display.lineDiv), "local"./null (editor), "window",
// or "page".
function intoCoordSystem(cm, lineObj, rect, context, includeWidgets) {
- if (!includeWidgets && lineObj.widgets) { for (var i = 0; i < lineObj.widgets.length; ++i) { if (lineObj.widgets[i].above) {
- var size = widgetHeight(lineObj.widgets[i])
- rect.top += size; rect.bottom += size
- } } }
+ if (!includeWidgets) {
+ var height = widgetTopHeight(lineObj)
+ rect.top += height; rect.bottom += height
+ }
if (context == "line") { return rect }
if (!context) { context = "local" }
var yOff = heightAtLine(lineObj)
@@ -2723,7 +2730,7 @@ function cursorCoords(cm, pos, context, lineObj, preparedMeasure, varHeight) {
if (!order) { return get(sticky == "before" ? ch - 1 : ch, sticky == "before") }
function getBidi(ch, partPos, invert) {
- var part = order[partPos], right = (part.level % 2) != 0
+ var part = order[partPos], right = part.level == 1
return get(invert ? ch - 1 : ch, right != invert)
}
var partPos = getBidiPartAt(order, ch, sticky)
@@ -2781,67 +2788,147 @@ function coordsChar(cm, x, y) {
}
function wrappedLineExtent(cm, lineObj, preparedMeasure, y) {
- var measure = function (ch) { return intoCoordSystem(cm, lineObj, measureCharPrepared(cm, preparedMeasure, ch), "line"); }
+ y -= widgetTopHeight(lineObj)
var end = lineObj.text.length
- var begin = findFirst(function (ch) { return measure(ch - 1).bottom <= y; }, end, 0)
- end = findFirst(function (ch) { return measure(ch).top > y; }, begin, end)
+ var begin = findFirst(function (ch) { return measureCharPrepared(cm, preparedMeasure, ch - 1).bottom <= y; }, end, 0)
+ end = findFirst(function (ch) { return measureCharPrepared(cm, preparedMeasure, ch).top > y; }, begin, end)
return {begin: begin, end: end}
}
function wrappedLineExtentChar(cm, lineObj, preparedMeasure, target) {
+ if (!preparedMeasure) { preparedMeasure = prepareMeasureForLine(cm, lineObj) }
var targetTop = intoCoordSystem(cm, lineObj, measureCharPrepared(cm, preparedMeasure, target), "line").top
return wrappedLineExtent(cm, lineObj, preparedMeasure, targetTop)
}
+// Returns true if the given side of a box is after the given
+// coordinates, in top-to-bottom, left-to-right order.
+function boxIsAfter(box, x, y, left) {
+ return box.bottom <= y ? false : box.top > y ? true : (left ? box.left : box.right) > x
+}
+
function coordsCharInner(cm, lineObj, lineNo, x, y) {
+ // Move y into line-local coordinate space
y -= heightAtLine(lineObj)
- var begin = 0, end = lineObj.text.length
var preparedMeasure = prepareMeasureForLine(cm, lineObj)
- var pos
+ // When directly calling `measureCharPrepared`, we have to adjust
+ // for the widgets at this line.
+ var widgetHeight = widgetTopHeight(lineObj)
+ var begin = 0, end = lineObj.text.length, ltr = true
+
var order = getOrder(lineObj, cm.doc.direction)
+ // If the line isn't plain left-to-right text, first figure out
+ // which bidi section the coordinates fall into.
if (order) {
- if (cm.options.lineWrapping) {
- ;var assign;
- ((assign = wrappedLineExtent(cm, lineObj, preparedMeasure, y), begin = assign.begin, end = assign.end, assign))
- }
- pos = new Pos(lineNo, begin)
- var beginLeft = cursorCoords(cm, pos, "line", lineObj, preparedMeasure).left
- var dir = beginLeft < x ? 1 : -1
- var prevDiff, diff = beginLeft - x, prevPos
- do {
- prevDiff = diff
- prevPos = pos
- pos = moveVisually(cm, lineObj, pos, dir)
- if (pos == null || pos.ch < begin || end <= (pos.sticky == "before" ? pos.ch - 1 : pos.ch)) {
- pos = prevPos
- break
- }
- diff = cursorCoords(cm, pos, "line", lineObj, preparedMeasure).left - x
- } while ((dir < 0) != (diff < 0) && (Math.abs(diff) <= Math.abs(prevDiff)))
- if (Math.abs(diff) > Math.abs(prevDiff)) {
- if ((diff < 0) == (prevDiff < 0)) { throw new Error("Broke out of infinite loop in coordsCharInner") }
- pos = prevPos
- }
- } else {
- var ch = findFirst(function (ch) {
- var box = intoCoordSystem(cm, lineObj, measureCharPrepared(cm, preparedMeasure, ch), "line")
- if (box.top > y) {
- // For the cursor stickiness
- end = Math.min(ch, end)
- return true
- }
- else if (box.bottom <= y) { return false }
- else if (box.left > x) { return true }
- else if (box.right < x) { return false }
- else { return (x - box.left < box.right - x) }
- }, begin, end)
- ch = skipExtendingChars(lineObj.text, ch, 1)
- pos = new Pos(lineNo, ch, ch == end ? "before" : "after")
+ var part = (cm.options.lineWrapping ? coordsBidiPartWrapped : coordsBidiPart)
+ (cm, lineObj, lineNo, preparedMeasure, order, x, y)
+ ltr = part.level != 1
+ // The awkward -1 offsets are needed because findFirst (called
+ // on these below) will treat its first bound as inclusive,
+ // second as exclusive, but we want to actually address the
+ // characters in the part's range
+ begin = ltr ? part.from : part.to - 1
+ end = ltr ? part.to : part.from - 1
}
- var coords = cursorCoords(cm, pos, "line", lineObj, preparedMeasure)
- if (y < coords.top || coords.bottom < y) { pos.outside = true }
- pos.xRel = x < coords.left ? -1 : (x > coords.right ? 1 : 0)
- return pos
+
+ // A binary search to find the first character whose bounding box
+ // starts after the coordinates. If we run across any whose box wrap
+ // the coordinates, store that.
+ var chAround = null, boxAround = null
+ var ch = findFirst(function (ch) {
+ var box = measureCharPrepared(cm, preparedMeasure, ch)
+ box.top += widgetHeight; box.bottom += widgetHeight
+ if (!boxIsAfter(box, x, y, false)) { return false }
+ if (box.top <= y && box.left <= x) {
+ chAround = ch
+ boxAround = box
+ }
+ return true
+ }, begin, end)
+
+ var baseX, sticky, outside = false
+ // If a box around the coordinates was found, use that
+ if (boxAround) {
+ // Distinguish coordinates nearer to the left or right side of the box
+ var atLeft = x - boxAround.left < boxAround.right - x, atStart = atLeft == ltr
+ ch = chAround + (atStart ? 0 : 1)
+ sticky = atStart ? "after" : "before"
+ baseX = atLeft ? boxAround.left : boxAround.right
+ } else {
+ // (Adjust for extended bound, if necessary.)
+ if (!ltr && (ch == end || ch == begin)) { ch++ }
+ // To determine which side to associate with, get the box to the
+ // left of the character and compare it's vertical position to the
+ // coordinates
+ sticky = ch == 0 ? "after" : ch == lineObj.text.length ? "before" :
+ (measureCharPrepared(cm, preparedMeasure, ch - (ltr ? 1 : 0)).bottom + widgetHeight <= y) == ltr ?
+ "after" : "before"
+ // Now get accurate coordinates for this place, in order to get a
+ // base X position
+ var coords = cursorCoords(cm, Pos(lineNo, ch, sticky), "line", lineObj, preparedMeasure)
+ baseX = coords.left
+ outside = y < coords.top || y >= coords.bottom
+ }
+
+ ch = skipExtendingChars(lineObj.text, ch, 1)
+ return PosWithInfo(lineNo, ch, sticky, outside, x - baseX)
+}
+
+function coordsBidiPart(cm, lineObj, lineNo, preparedMeasure, order, x, y) {
+ // Bidi parts are sorted left-to-right, and in a non-line-wrapping
+ // situation, we can take this ordering to correspond to the visual
+ // ordering. This finds the first part whose end is after the given
+ // coordinates.
+ var index = findFirst(function (i) {
+ var part = order[i], ltr = part.level != 1
+ return boxIsAfter(cursorCoords(cm, Pos(lineNo, ltr ? part.to : part.from, ltr ? "before" : "after"),
+ "line", lineObj, preparedMeasure), x, y, true)
+ }, 0, order.length - 1)
+ var part = order[index]
+ // If this isn't the first part, the part's start is also after
+ // the coordinates, and the coordinates aren't on the same line as
+ // that start, move one part back.
+ if (index > 0) {
+ var ltr = part.level != 1
+ var start = cursorCoords(cm, Pos(lineNo, ltr ? part.from : part.to, ltr ? "after" : "before"),
+ "line", lineObj, preparedMeasure)
+ if (boxIsAfter(start, x, y, true) && start.top > y)
+ { part = order[index - 1] }
+ }
+ return part
+}
+
+function coordsBidiPartWrapped(cm, lineObj, _lineNo, preparedMeasure, order, x, y) {
+ // In a wrapped line, rtl text on wrapping boundaries can do things
+ // that don't correspond to the ordering in our `order` array at
+ // all, so a binary search doesn't work, and we want to return a
+ // part that only spans one line so that the binary search in
+ // coordsCharInner is safe. As such, we first find the extent of the
+ // wrapped line, and then do a flat search in which we discard any
+ // spans that aren't on the line.
+ var ref = wrappedLineExtent(cm, lineObj, preparedMeasure, y);
+ var begin = ref.begin;
+ var end = ref.end;
+ if (/\s/.test(lineObj.text.charAt(end - 1))) { end-- }
+ var part = null, closestDist = null
+ for (var i = 0; i < order.length; i++) {
+ var p = order[i]
+ if (p.from >= end || p.to <= begin) { continue }
+ var ltr = p.level != 1
+ var endX = measureCharPrepared(cm, preparedMeasure, ltr ? Math.min(end, p.to) - 1 : Math.max(begin, p.from)).right
+ // Weigh against spans ending before this, so that they are only
+ // picked if nothing ends after
+ var dist = endX < x ? x - endX + 1e9 : endX - x
+ if (!part || closestDist > dist) {
+ part = p
+ closestDist = dist
+ }
+ }
+ if (!part) { part = order[order.length - 1] }
+ // Clip the part to the wrapped line.
+ if (part.from < begin) { part = {from: begin, to: part.to, level: part.level} }
+ if (part.to > end) { part = {from: part.from, to: end, level: part.level} }
+ return part
}
var measureText
@@ -2967,12 +3054,14 @@ function updateSelection(cm) {
}
function prepareSelection(cm, primary) {
+ if ( primary === void 0 ) primary = true;
+
var doc = cm.doc, result = {}
var curFragment = result.cursors = document.createDocumentFragment()
var selFragment = result.selection = document.createDocumentFragment()
for (var i = 0; i < doc.sel.ranges.length; i++) {
- if (primary === false && i == doc.sel.primIndex) { continue }
+ if (!primary && i == doc.sel.primIndex) { continue }
var range = doc.sel.ranges[i]
if (range.from().line >= cm.display.viewTo || range.to().line < cm.display.viewFrom) { continue }
var collapsed = range.empty()
@@ -3003,12 +3092,15 @@ function drawSelectionCursor(cm, head, output) {
}
}
+function cmpCoords(a, b) { return a.top - b.top || a.left - b.left }
+
// Draws the given range as a highlighted selection
function drawSelectionRange(cm, range, output) {
var display = cm.display, doc = cm.doc
var fragment = document.createDocumentFragment()
var padding = paddingH(cm.display), leftSide = padding.left
var rightSide = Math.max(display.sizerWidth, displayWidth(cm) - display.sizer.offsetLeft) - padding.right
+ var docLTR = doc.direction == "ltr"
function add(left, top, width, bottom) {
if (top < 0) { top = 0 }
@@ -3025,30 +3117,49 @@ function drawSelectionRange(cm, range, output) {
return charCoords(cm, Pos(line, ch), "div", lineObj, bias)
}
- iterateBidiSections(getOrder(lineObj, doc.direction), fromArg || 0, toArg == null ? lineLen : toArg, function (from, to, dir) {
- var leftPos = coords(from, "left"), rightPos, left, right
- if (from == to) {
- rightPos = leftPos
- left = right = leftPos.left
- } else {
- rightPos = coords(to - 1, "right")
- if (dir == "rtl") { var tmp = leftPos; leftPos = rightPos; rightPos = tmp }
- left = leftPos.left
- right = rightPos.right
+ function wrapX(pos, dir, side) {
+ var extent = wrappedLineExtentChar(cm, lineObj, null, pos)
+ var prop = (dir == "ltr") == (side == "after") ? "left" : "right"
+ var ch = side == "after" ? extent.begin : extent.end - (/\s/.test(lineObj.text.charAt(extent.end - 1)) ? 2 : 1)
+ return coords(ch, prop)[prop]
+ }
+
+ var order = getOrder(lineObj, doc.direction)
+ iterateBidiSections(order, fromArg || 0, toArg == null ? lineLen : toArg, function (from, to, dir, i) {
+ var ltr = dir == "ltr"
+ var fromPos = coords(from, ltr ? "left" : "right")
+ var toPos = coords(to - 1, ltr ? "right" : "left")
+
+ var openStart = fromArg == null && from == 0, openEnd = toArg == null && to == lineLen
+ var first = i == 0, last = !order || i == order.length - 1
+ if (toPos.top - fromPos.top <= 3) { // Single line
+ var openLeft = (docLTR ? openStart : openEnd) && first
+ var openRight = (docLTR ? openEnd : openStart) && last
+ var left = openLeft ? leftSide : (ltr ? fromPos : toPos).left
+ var right = openRight ? rightSide : (ltr ? toPos : fromPos).right
+ add(left, fromPos.top, right - left, fromPos.bottom)
+ } else { // Multiple lines
+ var topLeft, topRight, botLeft, botRight
+ if (ltr) {
+ topLeft = docLTR && openStart && first ? leftSide : fromPos.left
+ topRight = docLTR ? rightSide : wrapX(from, dir, "before")
+ botLeft = docLTR ? leftSide : wrapX(to, dir, "after")
+ botRight = docLTR && openEnd && last ? rightSide : toPos.right
+ } else {
+ topLeft = !docLTR ? leftSide : wrapX(from, dir, "before")
+ topRight = !docLTR && openStart && first ? rightSide : fromPos.right
+ botLeft = !docLTR && openEnd && last ? leftSide : toPos.left
+ botRight = !docLTR ? rightSide : wrapX(to, dir, "after")
+ }
+ add(topLeft, fromPos.top, topRight - topLeft, fromPos.bottom)
+ if (fromPos.bottom < toPos.top) { add(leftSide, fromPos.bottom, null, toPos.top) }
+ add(botLeft, toPos.top, botRight - botLeft, toPos.bottom)
}
- if (fromArg == null && from == 0) { left = leftSide }
- if (rightPos.top - leftPos.top > 3) { // Different lines, draw top part
- add(left, leftPos.top, null, leftPos.bottom)
- left = leftSide
- if (leftPos.bottom < rightPos.top) { add(left, leftPos.bottom, null, rightPos.top) }
- }
- if (toArg == null && to == lineLen) { right = rightSide }
- if (!start || leftPos.top < start.top || leftPos.top == start.top && leftPos.left < start.left)
- { start = leftPos }
- if (!end || rightPos.bottom > end.bottom || rightPos.bottom == end.bottom && rightPos.right > end.right)
- { end = rightPos }
- if (left < leftSide + 1) { left = leftSide }
- add(left, rightPos.top, right - left, rightPos.bottom)
+
+ if (!start || cmpCoords(fromPos, start) < 0) { start = fromPos }
+ if (cmpCoords(toPos, start) < 0) { start = toPos }
+ if (!end || cmpCoords(fromPos, end) < 0) { end = fromPos }
+ if (cmpCoords(toPos, end) < 0) { end = toPos }
})
return {start: start, end: end}
}
@@ -3133,6 +3244,66 @@ function onBlur(cm, e) {
setTimeout(function () { if (!cm.state.focused) { cm.display.shift = false } }, 150)
}
+// Read the actual heights of the rendered lines, and update their
+// stored heights to match.
+function updateHeightsInViewport(cm) {
+ var display = cm.display
+ var prevBottom = display.lineDiv.offsetTop
+ for (var i = 0; i < display.view.length; i++) {
+ var cur = display.view[i], height = (void 0)
+ if (cur.hidden) { continue }
+ if (ie && ie_version < 8) {
+ var bot = cur.node.offsetTop + cur.node.offsetHeight
+ height = bot - prevBottom
+ prevBottom = bot
+ } else {
+ var box = cur.node.getBoundingClientRect()
+ height = box.bottom - box.top
+ }
+ var diff = cur.line.height - height
+ if (height < 2) { height = textHeight(display) }
+ if (diff > .005 || diff < -.005) {
+ updateLineHeight(cur.line, height)
+ updateWidgetHeight(cur.line)
+ if (cur.rest) { for (var j = 0; j < cur.rest.length; j++)
+ { updateWidgetHeight(cur.rest[j]) } }
+ }
+ }
+}
+
+// Read and store the height of line widgets associated with the
+// given line.
+function updateWidgetHeight(line) {
+ if (line.widgets) { for (var i = 0; i < line.widgets.length; ++i) {
+ var w = line.widgets[i], parent = w.node.parentNode
+ if (parent) { w.height = parent.offsetHeight }
+ } }
+}
+
+// Compute the lines that are visible in a given viewport (defaults
+// the the current scroll position). viewport may contain top,
+// height, and ensure (see op.scrollToPos) properties.
+function visibleLines(display, doc, viewport) {
+ var top = viewport && viewport.top != null ? Math.max(0, viewport.top) : display.scroller.scrollTop
+ top = Math.floor(top - paddingTop(display))
+ var bottom = viewport && viewport.bottom != null ? viewport.bottom : top + display.wrapper.clientHeight
+
+ var from = lineAtHeight(doc, top), to = lineAtHeight(doc, bottom)
+ // Ensure is a {from: {line, ch}, to: {line, ch}} object, and
+ // forces those lines into the viewport (if possible).
+ if (viewport && viewport.ensure) {
+ var ensureFrom = viewport.ensure.from.line, ensureTo = viewport.ensure.to.line
+ if (ensureFrom < from) {
+ from = ensureFrom
+ to = lineAtHeight(doc, heightAtLine(getLine(doc, ensureFrom)) + display.wrapper.clientHeight)
+ } else if (Math.min(ensureTo, doc.lastLine()) >= to) {
+ from = lineAtHeight(doc, heightAtLine(getLine(doc, ensureTo)) - display.wrapper.clientHeight)
+ to = ensureTo
+ }
+ }
+ return {from: from, to: Math.max(to, from + 1)}
+}
+
// Re-align line numbers and gutter marks to compensate for
// horizontal scrolling.
function alignHorizontally(cm) {
@@ -3176,197 +3347,178 @@ function maybeUpdateLineNumberWidth(cm) {
return false
}
-// Read the actual heights of the rendered lines, and update their
-// stored heights to match.
-function updateHeightsInViewport(cm) {
- var display = cm.display
- var prevBottom = display.lineDiv.offsetTop
- for (var i = 0; i < display.view.length; i++) {
- var cur = display.view[i], height = (void 0)
- if (cur.hidden) { continue }
- if (ie && ie_version < 8) {
- var bot = cur.node.offsetTop + cur.node.offsetHeight
- height = bot - prevBottom
- prevBottom = bot
- } else {
- var box = cur.node.getBoundingClientRect()
- height = box.bottom - box.top
- }
- var diff = cur.line.height - height
- if (height < 2) { height = textHeight(display) }
- if (diff > .001 || diff < -.001) {
- updateLineHeight(cur.line, height)
- updateWidgetHeight(cur.line)
- if (cur.rest) { for (var j = 0; j < cur.rest.length; j++)
- { updateWidgetHeight(cur.rest[j]) } }
- }
+// SCROLLING THINGS INTO VIEW
+
+// If an editor sits on the top or bottom of the window, partially
+// scrolled out of view, this ensures that the cursor is visible.
+function maybeScrollWindow(cm, rect) {
+ if (signalDOMEvent(cm, "scrollCursorIntoView")) { return }
+
+ var display = cm.display, box = display.sizer.getBoundingClientRect(), doScroll = null
+ if (rect.top + box.top < 0) { doScroll = true }
+ else if (rect.bottom + box.top > (window.innerHeight || document.documentElement.clientHeight)) { doScroll = false }
+ if (doScroll != null && !phantom) {
+ var scrollNode = elt("div", "\u200b", null, ("position: absolute;\n top: " + (rect.top - display.viewOffset - paddingTop(cm.display)) + "px;\n height: " + (rect.bottom - rect.top + scrollGap(cm) + display.barHeight) + "px;\n left: " + (rect.left) + "px; width: " + (Math.max(2, rect.right - rect.left)) + "px;"))
+ cm.display.lineSpace.appendChild(scrollNode)
+ scrollNode.scrollIntoView(doScroll)
+ cm.display.lineSpace.removeChild(scrollNode)
}
}
-// Read and store the height of line widgets associated with the
-// given line.
-function updateWidgetHeight(line) {
- if (line.widgets) { for (var i = 0; i < line.widgets.length; ++i)
- { line.widgets[i].height = line.widgets[i].node.parentNode.offsetHeight } }
+// Scroll a given position into view (immediately), verifying that
+// it actually became visible (as line heights are accurately
+// measured, the position of something may 'drift' during drawing).
+function scrollPosIntoView(cm, pos, end, margin) {
+ if (margin == null) { margin = 0 }
+ var rect
+ if (!cm.options.lineWrapping && pos == end) {
+ // Set pos and end to the cursor positions around the character pos sticks to
+ // If pos.sticky == "before", that is around pos.ch - 1, otherwise around pos.ch
+ // If pos == Pos(_, 0, "before"), pos and end are unchanged
+ pos = pos.ch ? Pos(pos.line, pos.sticky == "before" ? pos.ch - 1 : pos.ch, "after") : pos
+ end = pos.sticky == "before" ? Pos(pos.line, pos.ch + 1, "before") : pos
+ }
+ for (var limit = 0; limit < 5; limit++) {
+ var changed = false
+ var coords = cursorCoords(cm, pos)
+ var endCoords = !end || end == pos ? coords : cursorCoords(cm, end)
+ rect = {left: Math.min(coords.left, endCoords.left),
+ top: Math.min(coords.top, endCoords.top) - margin,
+ right: Math.max(coords.left, endCoords.left),
+ bottom: Math.max(coords.bottom, endCoords.bottom) + margin}
+ var scrollPos = calculateScrollPos(cm, rect)
+ var startTop = cm.doc.scrollTop, startLeft = cm.doc.scrollLeft
+ if (scrollPos.scrollTop != null) {
+ updateScrollTop(cm, scrollPos.scrollTop)
+ if (Math.abs(cm.doc.scrollTop - startTop) > 1) { changed = true }
+ }
+ if (scrollPos.scrollLeft != null) {
+ setScrollLeft(cm, scrollPos.scrollLeft)
+ if (Math.abs(cm.doc.scrollLeft - startLeft) > 1) { changed = true }
+ }
+ if (!changed) { break }
+ }
+ return rect
}
-// Compute the lines that are visible in a given viewport (defaults
-// the the current scroll position). viewport may contain top,
-// height, and ensure (see op.scrollToPos) properties.
-function visibleLines(display, doc, viewport) {
- var top = viewport && viewport.top != null ? Math.max(0, viewport.top) : display.scroller.scrollTop
- top = Math.floor(top - paddingTop(display))
- var bottom = viewport && viewport.bottom != null ? viewport.bottom : top + display.wrapper.clientHeight
+// Scroll a given set of coordinates into view (immediately).
+function scrollIntoView(cm, rect) {
+ var scrollPos = calculateScrollPos(cm, rect)
+ if (scrollPos.scrollTop != null) { updateScrollTop(cm, scrollPos.scrollTop) }
+ if (scrollPos.scrollLeft != null) { setScrollLeft(cm, scrollPos.scrollLeft) }
+}
- var from = lineAtHeight(doc, top), to = lineAtHeight(doc, bottom)
- // Ensure is a {from: {line, ch}, to: {line, ch}} object, and
- // forces those lines into the viewport (if possible).
- if (viewport && viewport.ensure) {
- var ensureFrom = viewport.ensure.from.line, ensureTo = viewport.ensure.to.line
- if (ensureFrom < from) {
- from = ensureFrom
- to = lineAtHeight(doc, heightAtLine(getLine(doc, ensureFrom)) + display.wrapper.clientHeight)
- } else if (Math.min(ensureTo, doc.lastLine()) >= to) {
- from = lineAtHeight(doc, heightAtLine(getLine(doc, ensureTo)) - display.wrapper.clientHeight)
- to = ensureTo
- }
+// Calculate a new scroll position needed to scroll the given
+// rectangle into view. Returns an object with scrollTop and
+// scrollLeft properties. When these are undefined, the
+// vertical/horizontal position does not need to be adjusted.
+function calculateScrollPos(cm, rect) {
+ var display = cm.display, snapMargin = textHeight(cm.display)
+ if (rect.top < 0) { rect.top = 0 }
+ var screentop = cm.curOp && cm.curOp.scrollTop != null ? cm.curOp.scrollTop : display.scroller.scrollTop
+ var screen = displayHeight(cm), result = {}
+ if (rect.bottom - rect.top > screen) { rect.bottom = rect.top + screen }
+ var docBottom = cm.doc.height + paddingVert(display)
+ var atTop = rect.top < snapMargin, atBottom = rect.bottom > docBottom - snapMargin
+ if (rect.top < screentop) {
+ result.scrollTop = atTop ? 0 : rect.top
+ } else if (rect.bottom > screentop + screen) {
+ var newTop = Math.min(rect.top, (atBottom ? docBottom : rect.bottom) - screen)
+ if (newTop != screentop) { result.scrollTop = newTop }
}
- return {from: from, to: Math.max(to, from + 1)}
+
+ var screenleft = cm.curOp && cm.curOp.scrollLeft != null ? cm.curOp.scrollLeft : display.scroller.scrollLeft
+ var screenw = displayWidth(cm) - (cm.options.fixedGutter ? display.gutters.offsetWidth : 0)
+ var tooWide = rect.right - rect.left > screenw
+ if (tooWide) { rect.right = rect.left + screenw }
+ if (rect.left < 10)
+ { result.scrollLeft = 0 }
+ else if (rect.left < screenleft)
+ { result.scrollLeft = Math.max(0, rect.left - (tooWide ? 0 : 10)) }
+ else if (rect.right > screenw + screenleft - 3)
+ { result.scrollLeft = rect.right + (tooWide ? 0 : 10) - screenw }
+ return result
+}
+
+// Store a relative adjustment to the scroll position in the current
+// operation (to be applied when the operation finishes).
+function addToScrollTop(cm, top) {
+ if (top == null) { return }
+ resolveScrollToPos(cm)
+ cm.curOp.scrollTop = (cm.curOp.scrollTop == null ? cm.doc.scrollTop : cm.curOp.scrollTop) + top
+}
+
+// Make sure that at the end of the operation the current cursor is
+// shown.
+function ensureCursorVisible(cm) {
+ resolveScrollToPos(cm)
+ var cur = cm.getCursor()
+ cm.curOp.scrollToPos = {from: cur, to: cur, margin: cm.options.cursorScrollMargin}
+}
+
+function scrollToCoords(cm, x, y) {
+ if (x != null || y != null) { resolveScrollToPos(cm) }
+ if (x != null) { cm.curOp.scrollLeft = x }
+ if (y != null) { cm.curOp.scrollTop = y }
+}
+
+function scrollToRange(cm, range) {
+ resolveScrollToPos(cm)
+ cm.curOp.scrollToPos = range
+}
+
+// When an operation has its scrollToPos property set, and another
+// scroll action is applied before the end of the operation, this
+// 'simulates' scrolling that position into view in a cheap way, so
+// that the effect of intermediate scroll commands is not ignored.
+function resolveScrollToPos(cm) {
+ var range = cm.curOp.scrollToPos
+ if (range) {
+ cm.curOp.scrollToPos = null
+ var from = estimateCoords(cm, range.from), to = estimateCoords(cm, range.to)
+ scrollToCoordsRange(cm, from, to, range.margin)
+ }
+}
+
+function scrollToCoordsRange(cm, from, to, margin) {
+ var sPos = calculateScrollPos(cm, {
+ left: Math.min(from.left, to.left),
+ top: Math.min(from.top, to.top) - margin,
+ right: Math.max(from.right, to.right),
+ bottom: Math.max(from.bottom, to.bottom) + margin
+ })
+ scrollToCoords(cm, sPos.scrollLeft, sPos.scrollTop)
}
// Sync the scrollable area and scrollbars, ensure the viewport
// covers the visible area.
-function setScrollTop(cm, val) {
+function updateScrollTop(cm, val) {
if (Math.abs(cm.doc.scrollTop - val) < 2) { return }
- cm.doc.scrollTop = val
if (!gecko) { updateDisplaySimple(cm, {top: val}) }
- if (cm.display.scroller.scrollTop != val) { cm.display.scroller.scrollTop = val }
- cm.display.scrollbars.setScrollTop(val)
+ setScrollTop(cm, val, true)
if (gecko) { updateDisplaySimple(cm) }
startWorker(cm, 100)
}
+
+function setScrollTop(cm, val, forceScroll) {
+ val = Math.min(cm.display.scroller.scrollHeight - cm.display.scroller.clientHeight, val)
+ if (cm.display.scroller.scrollTop == val && !forceScroll) { return }
+ cm.doc.scrollTop = val
+ cm.display.scrollbars.setScrollTop(val)
+ if (cm.display.scroller.scrollTop != val) { cm.display.scroller.scrollTop = val }
+}
+
// Sync scroller and scrollbar, ensure the gutter elements are
// aligned.
-function setScrollLeft(cm, val, isScroller) {
- if (isScroller ? val == cm.doc.scrollLeft : Math.abs(cm.doc.scrollLeft - val) < 2) { return }
+function setScrollLeft(cm, val, isScroller, forceScroll) {
val = Math.min(val, cm.display.scroller.scrollWidth - cm.display.scroller.clientWidth)
+ if ((isScroller ? val == cm.doc.scrollLeft : Math.abs(cm.doc.scrollLeft - val) < 2) && !forceScroll) { return }
cm.doc.scrollLeft = val
alignHorizontally(cm)
if (cm.display.scroller.scrollLeft != val) { cm.display.scroller.scrollLeft = val }
cm.display.scrollbars.setScrollLeft(val)
}
-// Since the delta values reported on mouse wheel events are
-// unstandardized between browsers and even browser versions, and
-// generally horribly unpredictable, this code starts by measuring
-// the scroll effect that the first few mouse wheel events have,
-// and, from that, detects the way it can convert deltas to pixel
-// offsets afterwards.
-//
-// The reason we want to know the amount a wheel event will scroll
-// is that it gives us a chance to update the display before the
-// actual scrolling happens, reducing flickering.
-
-var wheelSamples = 0;
-var wheelPixelsPerUnit = null;
-// Fill in a browser-detected starting value on browsers where we
-// know one. These don't have to be accurate -- the result of them
-// being wrong would just be a slight flicker on the first wheel
-// scroll (if it is large enough).
-if (ie) { wheelPixelsPerUnit = -.53 }
-else if (gecko) { wheelPixelsPerUnit = 15 }
-else if (chrome) { wheelPixelsPerUnit = -.7 }
-else if (safari) { wheelPixelsPerUnit = -1/3 }
-
-function wheelEventDelta(e) {
- var dx = e.wheelDeltaX, dy = e.wheelDeltaY
- if (dx == null && e.detail && e.axis == e.HORIZONTAL_AXIS) { dx = e.detail }
- if (dy == null && e.detail && e.axis == e.VERTICAL_AXIS) { dy = e.detail }
- else if (dy == null) { dy = e.wheelDelta }
- return {x: dx, y: dy}
-}
-function wheelEventPixels(e) {
- var delta = wheelEventDelta(e)
- delta.x *= wheelPixelsPerUnit
- delta.y *= wheelPixelsPerUnit
- return delta
-}
-
-function onScrollWheel(cm, e) {
- var delta = wheelEventDelta(e), dx = delta.x, dy = delta.y
-
- var display = cm.display, scroll = display.scroller
- // Quit if there's nothing to scroll here
- var canScrollX = scroll.scrollWidth > scroll.clientWidth
- var canScrollY = scroll.scrollHeight > scroll.clientHeight
- if (!(dx && canScrollX || dy && canScrollY)) { return }
-
- // Webkit browsers on OS X abort momentum scrolls when the target
- // of the scroll event is removed from the scrollable element.
- // This hack (see related code in patchDisplay) makes sure the
- // element is kept around.
- if (dy && mac && webkit) {
- outer: for (var cur = e.target, view = display.view; cur != scroll; cur = cur.parentNode) {
- for (var i = 0; i < view.length; i++) {
- if (view[i].node == cur) {
- cm.display.currentWheelTarget = cur
- break outer
- }
- }
- }
- }
-
- // On some browsers, horizontal scrolling will cause redraws to
- // happen before the gutter has been realigned, causing it to
- // wriggle around in a most unseemly way. When we have an
- // estimated pixels/delta value, we just handle horizontal
- // scrolling entirely here. It'll be slightly off from native, but
- // better than glitching out.
- if (dx && !gecko && !presto && wheelPixelsPerUnit != null) {
- if (dy && canScrollY)
- { setScrollTop(cm, Math.max(0, Math.min(scroll.scrollTop + dy * wheelPixelsPerUnit, scroll.scrollHeight - scroll.clientHeight))) }
- setScrollLeft(cm, Math.max(0, Math.min(scroll.scrollLeft + dx * wheelPixelsPerUnit, scroll.scrollWidth - scroll.clientWidth)))
- // Only prevent default scrolling if vertical scrolling is
- // actually possible. Otherwise, it causes vertical scroll
- // jitter on OSX trackpads when deltaX is small and deltaY
- // is large (issue #3579)
- if (!dy || (dy && canScrollY))
- { e_preventDefault(e) }
- display.wheelStartX = null // Abort measurement, if in progress
- return
- }
-
- // 'Project' the visible viewport to cover the area that is being
- // scrolled into view (if we know enough to estimate it).
- if (dy && wheelPixelsPerUnit != null) {
- var pixels = dy * wheelPixelsPerUnit
- var top = cm.doc.scrollTop, bot = top + display.wrapper.clientHeight
- if (pixels < 0) { top = Math.max(0, top + pixels - 50) }
- else { bot = Math.min(cm.doc.height, bot + pixels + 50) }
- updateDisplaySimple(cm, {top: top, bottom: bot})
- }
-
- if (wheelSamples < 20) {
- if (display.wheelStartX == null) {
- display.wheelStartX = scroll.scrollLeft; display.wheelStartY = scroll.scrollTop
- display.wheelDX = dx; display.wheelDY = dy
- setTimeout(function () {
- if (display.wheelStartX == null) { return }
- var movedX = scroll.scrollLeft - display.wheelStartX
- var movedY = scroll.scrollTop - display.wheelStartY
- var sample = (movedY && display.wheelDY && movedY / display.wheelDY) ||
- (movedX && display.wheelDX && movedX / display.wheelDX)
- display.wheelStartX = display.wheelStartY = null
- if (!sample) { return }
- wheelPixelsPerUnit = (wheelPixelsPerUnit * wheelSamples + sample) / (wheelSamples + 1)
- ++wheelSamples
- }, 200)
- } else {
- display.wheelDX += dx; display.wheelDY += dy
- }
- }
-}
-
// SCROLLBARS
// Prepare DOM reads needed to update the scrollbars. Done in one
@@ -3444,12 +3596,12 @@ NativeScrollbars.prototype.update = function (measure) {
NativeScrollbars.prototype.setScrollLeft = function (pos) {
if (this.horiz.scrollLeft != pos) { this.horiz.scrollLeft = pos }
- if (this.disableHoriz) { this.enableZeroWidthBar(this.horiz, this.disableHoriz) }
+ if (this.disableHoriz) { this.enableZeroWidthBar(this.horiz, this.disableHoriz, "horiz") }
};
NativeScrollbars.prototype.setScrollTop = function (pos) {
if (this.vert.scrollTop != pos) { this.vert.scrollTop = pos }
- if (this.disableVert) { this.enableZeroWidthBar(this.vert, this.disableVert) }
+ if (this.disableVert) { this.enableZeroWidthBar(this.vert, this.disableVert, "vert") }
};
NativeScrollbars.prototype.zeroWidthHack = function () {
@@ -3460,17 +3612,18 @@ NativeScrollbars.prototype.zeroWidthHack = function () {
this.disableVert = new Delayed
};
-NativeScrollbars.prototype.enableZeroWidthBar = function (bar, delay) {
+NativeScrollbars.prototype.enableZeroWidthBar = function (bar, delay, type) {
bar.style.pointerEvents = "auto"
function maybeDisable() {
// To find out whether the scrollbar is still visible, we
// check whether the element under the pixel in the bottom
- // left corner of the scrollbar box is the scrollbar box
+ // right corner of the scrollbar box is the scrollbar box
// itself (when the bar is still visible) or its filler child
// (when the bar is hidden). If it is still visible, we keep
// it enabled, if it's hidden, we disable pointer events.
var box = bar.getBoundingClientRect()
- var elt = document.elementFromPoint(box.left + 1, box.bottom - 1)
+ var elt = type == "vert" ? document.elementFromPoint(box.right - 1, (box.top + box.bottom) / 2)
+ : document.elementFromPoint((box.right + box.left) / 2, box.bottom - 1)
if (elt != bar) { bar.style.pointerEvents = "none" }
else { delay.set(1000, maybeDisable) }
}
@@ -3542,139 +3695,12 @@ function initScrollbars(cm) {
node.setAttribute("cm-not-content", "true")
}, function (pos, axis) {
if (axis == "horizontal") { setScrollLeft(cm, pos) }
- else { setScrollTop(cm, pos) }
+ else { updateScrollTop(cm, pos) }
}, cm)
if (cm.display.scrollbars.addClass)
{ addClass(cm.display.wrapper, cm.display.scrollbars.addClass) }
}
-// SCROLLING THINGS INTO VIEW
-
-// If an editor sits on the top or bottom of the window, partially
-// scrolled out of view, this ensures that the cursor is visible.
-function maybeScrollWindow(cm, rect) {
- if (signalDOMEvent(cm, "scrollCursorIntoView")) { return }
-
- var display = cm.display, box = display.sizer.getBoundingClientRect(), doScroll = null
- if (rect.top + box.top < 0) { doScroll = true }
- else if (rect.bottom + box.top > (window.innerHeight || document.documentElement.clientHeight)) { doScroll = false }
- if (doScroll != null && !phantom) {
- var scrollNode = elt("div", "\u200b", null, ("position: absolute;\n top: " + (rect.top - display.viewOffset - paddingTop(cm.display)) + "px;\n height: " + (rect.bottom - rect.top + scrollGap(cm) + display.barHeight) + "px;\n left: " + (rect.left) + "px; width: " + (Math.max(2, rect.right - rect.left)) + "px;"))
- cm.display.lineSpace.appendChild(scrollNode)
- scrollNode.scrollIntoView(doScroll)
- cm.display.lineSpace.removeChild(scrollNode)
- }
-}
-
-// Scroll a given position into view (immediately), verifying that
-// it actually became visible (as line heights are accurately
-// measured, the position of something may 'drift' during drawing).
-function scrollPosIntoView(cm, pos, end, margin) {
- if (margin == null) { margin = 0 }
- var rect
- for (var limit = 0; limit < 5; limit++) {
- var changed = false
- var coords = cursorCoords(cm, pos)
- var endCoords = !end || end == pos ? coords : cursorCoords(cm, end)
- rect = {left: Math.min(coords.left, endCoords.left),
- top: Math.min(coords.top, endCoords.top) - margin,
- right: Math.max(coords.left, endCoords.left),
- bottom: Math.max(coords.bottom, endCoords.bottom) + margin}
- var scrollPos = calculateScrollPos(cm, rect)
- var startTop = cm.doc.scrollTop, startLeft = cm.doc.scrollLeft
- if (scrollPos.scrollTop != null) {
- setScrollTop(cm, scrollPos.scrollTop)
- if (Math.abs(cm.doc.scrollTop - startTop) > 1) { changed = true }
- }
- if (scrollPos.scrollLeft != null) {
- setScrollLeft(cm, scrollPos.scrollLeft)
- if (Math.abs(cm.doc.scrollLeft - startLeft) > 1) { changed = true }
- }
- if (!changed) { break }
- }
- return rect
-}
-
-// Scroll a given set of coordinates into view (immediately).
-function scrollIntoView(cm, rect) {
- var scrollPos = calculateScrollPos(cm, rect)
- if (scrollPos.scrollTop != null) { setScrollTop(cm, scrollPos.scrollTop) }
- if (scrollPos.scrollLeft != null) { setScrollLeft(cm, scrollPos.scrollLeft) }
-}
-
-// Calculate a new scroll position needed to scroll the given
-// rectangle into view. Returns an object with scrollTop and
-// scrollLeft properties. When these are undefined, the
-// vertical/horizontal position does not need to be adjusted.
-function calculateScrollPos(cm, rect) {
- var display = cm.display, snapMargin = textHeight(cm.display)
- if (rect.top < 0) { rect.top = 0 }
- var screentop = cm.curOp && cm.curOp.scrollTop != null ? cm.curOp.scrollTop : display.scroller.scrollTop
- var screen = displayHeight(cm), result = {}
- if (rect.bottom - rect.top > screen) { rect.bottom = rect.top + screen }
- var docBottom = cm.doc.height + paddingVert(display)
- var atTop = rect.top < snapMargin, atBottom = rect.bottom > docBottom - snapMargin
- if (rect.top < screentop) {
- result.scrollTop = atTop ? 0 : rect.top
- } else if (rect.bottom > screentop + screen) {
- var newTop = Math.min(rect.top, (atBottom ? docBottom : rect.bottom) - screen)
- if (newTop != screentop) { result.scrollTop = newTop }
- }
-
- var screenleft = cm.curOp && cm.curOp.scrollLeft != null ? cm.curOp.scrollLeft : display.scroller.scrollLeft
- var screenw = displayWidth(cm) - (cm.options.fixedGutter ? display.gutters.offsetWidth : 0)
- var tooWide = rect.right - rect.left > screenw
- if (tooWide) { rect.right = rect.left + screenw }
- if (rect.left < 10)
- { result.scrollLeft = 0 }
- else if (rect.left < screenleft)
- { result.scrollLeft = Math.max(0, rect.left - (tooWide ? 0 : 10)) }
- else if (rect.right > screenw + screenleft - 3)
- { result.scrollLeft = rect.right + (tooWide ? 0 : 10) - screenw }
- return result
-}
-
-// Store a relative adjustment to the scroll position in the current
-// operation (to be applied when the operation finishes).
-function addToScrollPos(cm, left, top) {
- if (left != null || top != null) { resolveScrollToPos(cm) }
- if (left != null)
- { cm.curOp.scrollLeft = (cm.curOp.scrollLeft == null ? cm.doc.scrollLeft : cm.curOp.scrollLeft) + left }
- if (top != null)
- { cm.curOp.scrollTop = (cm.curOp.scrollTop == null ? cm.doc.scrollTop : cm.curOp.scrollTop) + top }
-}
-
-// Make sure that at the end of the operation the current cursor is
-// shown.
-function ensureCursorVisible(cm) {
- resolveScrollToPos(cm)
- var cur = cm.getCursor(), from = cur, to = cur
- if (!cm.options.lineWrapping) {
- from = cur.ch ? Pos(cur.line, cur.ch - 1) : cur
- to = Pos(cur.line, cur.ch + 1)
- }
- cm.curOp.scrollToPos = {from: from, to: to, margin: cm.options.cursorScrollMargin}
-}
-
-// When an operation has its scrollToPos property set, and another
-// scroll action is applied before the end of the operation, this
-// 'simulates' scrolling that position into view in a cheap way, so
-// that the effect of intermediate scroll commands is not ignored.
-function resolveScrollToPos(cm) {
- var range = cm.curOp.scrollToPos
- if (range) {
- cm.curOp.scrollToPos = null
- var from = estimateCoords(cm, range.from), to = estimateCoords(cm, range.to)
- var sPos = calculateScrollPos(cm, {
- left: Math.min(from.left, to.left),
- top: Math.min(from.top, to.top) - range.margin,
- right: Math.max(from.right, to.right),
- bottom: Math.max(from.bottom, to.bottom) + range.margin
- })
- cm.scrollTo(sPos.scrollLeft, sPos.scrollTop)
- }
-}
-
// Operations are used to wrap a series of changes to the editor
// state in such a way that each change won't have to update the
// cursor and display (which would be awkward, slow, and
@@ -3765,7 +3791,7 @@ function endOperation_R2(op) {
}
if (op.updatedDisplay || op.selectionChanged)
- { op.preparedSelection = display.input.prepareSelection(op.focus) }
+ { op.preparedSelection = display.input.prepareSelection() }
}
function endOperation_W2(op) {
@@ -3778,7 +3804,7 @@ function endOperation_W2(op) {
cm.display.maxLineChanged = false
}
- var takeFocus = op.focus && op.focus == activeElt() && (!document.hasFocus || document.hasFocus())
+ var takeFocus = op.focus && op.focus == activeElt()
if (op.preparedSelection)
{ cm.display.input.showSelection(op.preparedSelection, takeFocus) }
if (op.updatedDisplay || op.startHeight != cm.doc.height)
@@ -3803,17 +3829,9 @@ function endOperation_finish(op) {
{ display.wheelStartX = display.wheelStartY = null }
// Propagate the scroll position to the actual DOM scroller
- if (op.scrollTop != null && (display.scroller.scrollTop != op.scrollTop || op.forceScroll)) {
- doc.scrollTop = Math.max(0, Math.min(display.scroller.scrollHeight - display.scroller.clientHeight, op.scrollTop))
- display.scrollbars.setScrollTop(doc.scrollTop)
- display.scroller.scrollTop = doc.scrollTop
- }
- if (op.scrollLeft != null && (display.scroller.scrollLeft != op.scrollLeft || op.forceScroll)) {
- doc.scrollLeft = Math.max(0, Math.min(display.scroller.scrollWidth - display.scroller.clientWidth, op.scrollLeft))
- display.scrollbars.setScrollLeft(doc.scrollLeft)
- display.scroller.scrollLeft = doc.scrollLeft
- alignHorizontally(cm)
- }
+ if (op.scrollTop != null) { setScrollTop(cm, op.scrollTop, op.forceScroll) }
+
+ if (op.scrollLeft != null) { setScrollLeft(cm, op.scrollLeft, true, true) }
// If we need to scroll a specific position into view, do so.
if (op.scrollToPos) {
var rect = scrollPosIntoView(cm, clipPos(doc, op.scrollToPos.from),
@@ -4026,22 +4044,23 @@ function countDirtyView(cm) {
// HIGHLIGHT WORKER
function startWorker(cm, time) {
- if (cm.doc.mode.startState && cm.doc.frontier < cm.display.viewTo)
+ if (cm.doc.highlightFrontier < cm.display.viewTo)
{ cm.state.highlight.set(time, bind(highlightWorker, cm)) }
}
function highlightWorker(cm) {
var doc = cm.doc
- if (doc.frontier < doc.first) { doc.frontier = doc.first }
- if (doc.frontier >= cm.display.viewTo) { return }
+ if (doc.highlightFrontier >= cm.display.viewTo) { return }
var end = +new Date + cm.options.workTime
- var state = copyState(doc.mode, getStateBefore(cm, doc.frontier))
+ var context = getContextBefore(cm, doc.highlightFrontier)
var changedLines = []
- doc.iter(doc.frontier, Math.min(doc.first + doc.size, cm.display.viewTo + 500), function (line) {
- if (doc.frontier >= cm.display.viewFrom) { // Visible
- var oldStyles = line.styles, tooLong = line.text.length > cm.options.maxHighlightLength
- var highlighted = highlightLine(cm, line, tooLong ? copyState(doc.mode, state) : state, true)
+ doc.iter(context.line, Math.min(doc.first + doc.size, cm.display.viewTo + 500), function (line) {
+ if (context.line >= cm.display.viewFrom) { // Visible
+ var oldStyles = line.styles
+ var resetState = line.text.length > cm.options.maxHighlightLength ? copyState(doc.mode, context.state) : null
+ var highlighted = highlightLine(cm, line, context, true)
+ if (resetState) { context.state = resetState }
line.styles = highlighted.styles
var oldCls = line.styleClasses, newCls = highlighted.classes
if (newCls) { line.styleClasses = newCls }
@@ -4049,19 +4068,22 @@ function highlightWorker(cm) {
var ischange = !oldStyles || oldStyles.length != line.styles.length ||
oldCls != newCls && (!oldCls || !newCls || oldCls.bgClass != newCls.bgClass || oldCls.textClass != newCls.textClass)
for (var i = 0; !ischange && i < oldStyles.length; ++i) { ischange = oldStyles[i] != line.styles[i] }
- if (ischange) { changedLines.push(doc.frontier) }
- line.stateAfter = tooLong ? state : copyState(doc.mode, state)
+ if (ischange) { changedLines.push(context.line) }
+ line.stateAfter = context.save()
+ context.nextLine()
} else {
if (line.text.length <= cm.options.maxHighlightLength)
- { processLine(cm, line.text, state) }
- line.stateAfter = doc.frontier % 5 == 0 ? copyState(doc.mode, state) : null
+ { processLine(cm, line.text, context) }
+ line.stateAfter = context.line % 5 == 0 ? context.save() : null
+ context.nextLine()
}
- ++doc.frontier
if (+new Date > end) {
startWorker(cm, cm.options.workDelay)
return true
}
})
+ doc.highlightFrontier = context.line
+ doc.modeFrontier = Math.max(doc.modeFrontier, context.line)
if (changedLines.length) { runInOp(cm, function () {
for (var i = 0; i < changedLines.length; i++)
{ regLineChange(cm, changedLines[i], "text") }
@@ -4107,6 +4129,36 @@ function maybeClipScrollbars(cm) {
}
}
+function selectionSnapshot(cm) {
+ if (cm.hasFocus()) { return null }
+ var active = activeElt()
+ if (!active || !contains(cm.display.lineDiv, active)) { return null }
+ var result = {activeElt: active}
+ if (window.getSelection) {
+ var sel = window.getSelection()
+ if (sel.anchorNode && sel.extend && contains(cm.display.lineDiv, sel.anchorNode)) {
+ result.anchorNode = sel.anchorNode
+ result.anchorOffset = sel.anchorOffset
+ result.focusNode = sel.focusNode
+ result.focusOffset = sel.focusOffset
+ }
+ }
+ return result
+}
+
+function restoreSelection(snapshot) {
+ if (!snapshot || !snapshot.activeElt || snapshot.activeElt == activeElt()) { return }
+ snapshot.activeElt.focus()
+ if (snapshot.anchorNode && contains(document.body, snapshot.anchorNode) && contains(document.body, snapshot.focusNode)) {
+ var sel = window.getSelection(), range = document.createRange()
+ range.setEnd(snapshot.anchorNode, snapshot.anchorOffset)
+ range.collapse(false)
+ sel.removeAllRanges()
+ sel.addRange(range)
+ sel.extend(snapshot.focusNode, snapshot.focusOffset)
+ }
+}
+
// Does the actual updating of the line display. Bails out
// (returning false) when there is nothing to be done and forced is
// false.
@@ -4156,14 +4208,14 @@ function updateDisplayIfNeeded(cm, update) {
// For big changes, we hide the enclosing element during the
// update, since that speeds up the operations on most browsers.
- var focused = activeElt()
+ var selSnapshot = selectionSnapshot(cm)
if (toUpdate > 4) { display.lineDiv.style.display = "none" }
patchDisplay(cm, display.updateLineNumbers, update.dims)
if (toUpdate > 4) { display.lineDiv.style.display = "" }
display.renderedView = display.view
// There might have been a widget with a focused element that got
// hidden or updated, if so re-focus it.
- if (focused && activeElt() != focused && focused.offsetHeight) { focused.focus() }
+ restoreSelection(selSnapshot)
// Prevent selection and cursors from interfering with the scroll
// width and height.
@@ -4202,6 +4254,7 @@ function postUpdateDisplay(cm, update) {
updateSelection(cm)
updateScrollbars(cm, barMeasure)
setDocumentHeight(cm, barMeasure)
+ update.force = false
}
update.signal(cm, "update", cm)
@@ -4311,6 +4364,106 @@ function setGuttersForLineNumbers(options) {
}
}
+var wheelSamples = 0;
+var wheelPixelsPerUnit = null;
+// Fill in a browser-detected starting value on browsers where we
+// know one. These don't have to be accurate -- the result of them
+// being wrong would just be a slight flicker on the first wheel
+// scroll (if it is large enough).
+if (ie) { wheelPixelsPerUnit = -.53 }
+else if (gecko) { wheelPixelsPerUnit = 15 }
+else if (chrome) { wheelPixelsPerUnit = -.7 }
+else if (safari) { wheelPixelsPerUnit = -1/3 }
+
+function wheelEventDelta(e) {
+ var dx = e.wheelDeltaX, dy = e.wheelDeltaY
+ if (dx == null && e.detail && e.axis == e.HORIZONTAL_AXIS) { dx = e.detail }
+ if (dy == null && e.detail && e.axis == e.VERTICAL_AXIS) { dy = e.detail }
+ else if (dy == null) { dy = e.wheelDelta }
+ return {x: dx, y: dy}
+}
+function wheelEventPixels(e) {
+ var delta = wheelEventDelta(e)
+ delta.x *= wheelPixelsPerUnit
+ delta.y *= wheelPixelsPerUnit
+ return delta
+}
+
+function onScrollWheel(cm, e) {
+ var delta = wheelEventDelta(e), dx = delta.x, dy = delta.y
+
+ var display = cm.display, scroll = display.scroller
+ // Quit if there's nothing to scroll here
+ var canScrollX = scroll.scrollWidth > scroll.clientWidth
+ var canScrollY = scroll.scrollHeight > scroll.clientHeight
+ if (!(dx && canScrollX || dy && canScrollY)) { return }
+
+ // Webkit browsers on OS X abort momentum scrolls when the target
+ // of the scroll event is removed from the scrollable element.
+ // This hack (see related code in patchDisplay) makes sure the
+ // element is kept around.
+ if (dy && mac && webkit) {
+ outer: for (var cur = e.target, view = display.view; cur != scroll; cur = cur.parentNode) {
+ for (var i = 0; i < view.length; i++) {
+ if (view[i].node == cur) {
+ cm.display.currentWheelTarget = cur
+ break outer
+ }
+ }
+ }
+ }
+
+ // On some browsers, horizontal scrolling will cause redraws to
+ // happen before the gutter has been realigned, causing it to
+ // wriggle around in a most unseemly way. When we have an
+ // estimated pixels/delta value, we just handle horizontal
+ // scrolling entirely here. It'll be slightly off from native, but
+ // better than glitching out.
+ if (dx && !gecko && !presto && wheelPixelsPerUnit != null) {
+ if (dy && canScrollY)
+ { updateScrollTop(cm, Math.max(0, scroll.scrollTop + dy * wheelPixelsPerUnit)) }
+ setScrollLeft(cm, Math.max(0, scroll.scrollLeft + dx * wheelPixelsPerUnit))
+ // Only prevent default scrolling if vertical scrolling is
+ // actually possible. Otherwise, it causes vertical scroll
+ // jitter on OSX trackpads when deltaX is small and deltaY
+ // is large (issue #3579)
+ if (!dy || (dy && canScrollY))
+ { e_preventDefault(e) }
+ display.wheelStartX = null // Abort measurement, if in progress
+ return
+ }
+
+ // 'Project' the visible viewport to cover the area that is being
+ // scrolled into view (if we know enough to estimate it).
+ if (dy && wheelPixelsPerUnit != null) {
+ var pixels = dy * wheelPixelsPerUnit
+ var top = cm.doc.scrollTop, bot = top + display.wrapper.clientHeight
+ if (pixels < 0) { top = Math.max(0, top + pixels - 50) }
+ else { bot = Math.min(cm.doc.height, bot + pixels + 50) }
+ updateDisplaySimple(cm, {top: top, bottom: bot})
+ }
+
+ if (wheelSamples < 20) {
+ if (display.wheelStartX == null) {
+ display.wheelStartX = scroll.scrollLeft; display.wheelStartY = scroll.scrollTop
+ display.wheelDX = dx; display.wheelDY = dy
+ setTimeout(function () {
+ if (display.wheelStartX == null) { return }
+ var movedX = scroll.scrollLeft - display.wheelStartX
+ var movedY = scroll.scrollTop - display.wheelStartY
+ var sample = (movedY && display.wheelDY && movedY / display.wheelDY) ||
+ (movedX && display.wheelDX && movedX / display.wheelDX)
+ display.wheelStartX = display.wheelStartY = null
+ if (!sample) { return }
+ wheelPixelsPerUnit = (wheelPixelsPerUnit * wheelSamples + sample) / (wheelSamples + 1)
+ ++wheelSamples
+ }, 200)
+ } else {
+ display.wheelDX += dx; display.wheelDY += dy
+ }
+ }
+}
+
// Selection objects are immutable. A new one is created every time
// the selection changes. A selection is one or more non-overlapping
// (and non-touching) ranges, sorted, and an integer that indicates
@@ -4464,7 +4617,7 @@ function resetModeState(cm) {
if (line.stateAfter) { line.stateAfter = null }
if (line.styles) { line.styles = null }
})
- cm.doc.frontier = cm.doc.first
+ cm.doc.modeFrontier = cm.doc.highlightFrontier = cm.doc.first
startWorker(cm, 100)
cm.state.modeGen++
if (cm.curOp) { regChange(cm) }
@@ -4798,8 +4951,8 @@ function copyHistoryArray(events, newGroup, instantiateSel) {
// include a given position (and optionally a second position).
// Otherwise, simply returns the range between the given positions.
// Used for cursor motion and such.
-function extendRange(doc, range, head, other) {
- if (doc.cm && doc.cm.display.shift || doc.extend) {
+function extendRange(range, head, other, extend) {
+ if (extend) {
var anchor = range.anchor
if (other) {
var posBefore = cmp(head, anchor) < 0
@@ -4817,16 +4970,18 @@ function extendRange(doc, range, head, other) {
}
// Extend the primary selection range, discard the rest.
-function extendSelection(doc, head, other, options) {
- setSelection(doc, new Selection([extendRange(doc, doc.sel.primary(), head, other)], 0), options)
+function extendSelection(doc, head, other, options, extend) {
+ if (extend == null) { extend = doc.cm && (doc.cm.display.shift || doc.extend) }
+ setSelection(doc, new Selection([extendRange(doc.sel.primary(), head, other, extend)], 0), options)
}
// Extend all selections (pos is an array of selections with length
// equal the number of selections)
function extendSelections(doc, heads, options) {
var out = []
+ var extend = doc.cm && (doc.cm.display.shift || doc.extend)
for (var i = 0; i < doc.sel.ranges.length; i++)
- { out[i] = extendRange(doc, doc.sel.ranges[i], heads[i], null) }
+ { out[i] = extendRange(doc.sel.ranges[i], heads[i], null, extend) }
var newSel = normalizeSelection(out, doc.sel.primIndex)
setSelection(doc, newSel, options)
}
@@ -4907,7 +5062,7 @@ function setSelectionInner(doc, sel) {
// Verify that the selection does not partially select any atomic
// marked ranges.
function reCheckSelection(doc) {
- setSelectionInner(doc, skipAtomicInSelection(doc, doc.sel, null, false), sel_dontScroll)
+ setSelectionInner(doc, skipAtomicInSelection(doc, doc.sel, null, false))
}
// Return a selection that does not partially select any atomic
@@ -5032,7 +5187,7 @@ function makeChange(doc, change, ignoreReadOnly) {
var split = sawReadOnlySpans && !ignoreReadOnly && removeReadOnlyRanges(doc, change.from, change.to)
if (split) {
for (var i = split.length - 1; i >= 0; --i)
- { makeChangeInner(doc, {from: split[i].from, to: split[i].to, text: i ? [""] : change.text}) }
+ { makeChangeInner(doc, {from: split[i].from, to: split[i].to, text: i ? [""] : change.text, origin: change.origin}) }
} else {
makeChangeInner(doc, change)
}
@@ -5210,8 +5365,7 @@ function makeChangeSingleDocInEditor(cm, change, spans) {
if (recomputeMaxLength) { cm.curOp.updateMaxLine = true }
}
- // Adjust frontier, schedule worker
- doc.frontier = Math.min(doc.frontier, from.line)
+ retreatFrontier(doc, from.line)
startWorker(cm, 400)
var lendiff = change.text.length - (to.line - from.line) - 1
@@ -5239,7 +5393,8 @@ function makeChangeSingleDocInEditor(cm, change, spans) {
function replaceRange(doc, code, from, to, origin) {
if (!to) { to = from }
- if (cmp(to, from) < 0) { var tmp = to; to = from; from = tmp }
+ if (cmp(to, from) < 0) { var assign;
+ (assign = [to, from], from = assign[0], to = assign[1], assign) }
if (typeof code == "string") { code = doc.splitLines(code) }
makeChange(doc, {from: from, to: to, text: code, origin: origin})
}
@@ -5321,7 +5476,7 @@ function changeLine(doc, handle, changeType, op) {
//
// See also http://marijnhaverbeke.nl/blog/codemirror-line-tree.html
-var LeafChunk = function(lines) {
+function LeafChunk(lines) {
var this$1 = this;
this.lines = lines
@@ -5332,47 +5487,49 @@ var LeafChunk = function(lines) {
height += lines[i].height
}
this.height = height
-};
+}
-LeafChunk.prototype.chunkSize = function () { return this.lines.length };
+LeafChunk.prototype = {
+ chunkSize: function chunkSize() { return this.lines.length },
-// Remove the n lines at offset 'at'.
-LeafChunk.prototype.removeInner = function (at, n) {
+ // Remove the n lines at offset 'at'.
+ removeInner: function removeInner(at, n) {
var this$1 = this;
- for (var i = at, e = at + n; i < e; ++i) {
- var line = this$1.lines[i]
- this$1.height -= line.height
- cleanUpLine(line)
- signalLater(line, "delete")
+ for (var i = at, e = at + n; i < e; ++i) {
+ var line = this$1.lines[i]
+ this$1.height -= line.height
+ cleanUpLine(line)
+ signalLater(line, "delete")
+ }
+ this.lines.splice(at, n)
+ },
+
+ // Helper used to collapse a small branch into a single leaf.
+ collapse: function collapse(lines) {
+ lines.push.apply(lines, this.lines)
+ },
+
+ // Insert the given array of lines at offset 'at', count them as
+ // having the given height.
+ insertInner: function insertInner(at, lines, height) {
+ var this$1 = this;
+
+ this.height += height
+ this.lines = this.lines.slice(0, at).concat(lines).concat(this.lines.slice(at))
+ for (var i = 0; i < lines.length; ++i) { lines[i].parent = this$1 }
+ },
+
+ // Used to iterate over a part of the tree.
+ iterN: function iterN(at, n, op) {
+ var this$1 = this;
+
+ for (var e = at + n; at < e; ++at)
+ { if (op(this$1.lines[at])) { return true } }
}
- this.lines.splice(at, n)
-};
+}
-// Helper used to collapse a small branch into a single leaf.
-LeafChunk.prototype.collapse = function (lines) {
- lines.push.apply(lines, this.lines)
-};
-
-// Insert the given array of lines at offset 'at', count them as
-// having the given height.
-LeafChunk.prototype.insertInner = function (at, lines, height) {
- var this$1 = this;
-
- this.height += height
- this.lines = this.lines.slice(0, at).concat(lines).concat(this.lines.slice(at))
- for (var i = 0; i < lines.length; ++i) { lines[i].parent = this$1 }
-};
-
-// Used to iterate over a part of the tree.
-LeafChunk.prototype.iterN = function (at, n, op) {
- var this$1 = this;
-
- for (var e = at + n; at < e; ++at)
- { if (op(this$1.lines[at])) { return true } }
-};
-
-var BranchChunk = function(children) {
+function BranchChunk(children) {
var this$1 = this;
this.children = children
@@ -5385,106 +5542,108 @@ var BranchChunk = function(children) {
this.size = size
this.height = height
this.parent = null
-};
+}
-BranchChunk.prototype.chunkSize = function () { return this.size };
+BranchChunk.prototype = {
+ chunkSize: function chunkSize() { return this.size },
-BranchChunk.prototype.removeInner = function (at, n) {
+ removeInner: function removeInner(at, n) {
var this$1 = this;
- this.size -= n
- for (var i = 0; i < this.children.length; ++i) {
- var child = this$1.children[i], sz = child.chunkSize()
- if (at < sz) {
- var rm = Math.min(n, sz - at), oldHeight = child.height
- child.removeInner(at, rm)
- this$1.height -= oldHeight - child.height
- if (sz == rm) { this$1.children.splice(i--, 1); child.parent = null }
- if ((n -= rm) == 0) { break }
- at = 0
- } else { at -= sz }
- }
- // If the result is smaller than 25 lines, ensure that it is a
- // single leaf node.
- if (this.size - n < 25 &&
- (this.children.length > 1 || !(this.children[0] instanceof LeafChunk))) {
- var lines = []
- this.collapse(lines)
- this.children = [new LeafChunk(lines)]
- this.children[0].parent = this
- }
-};
+ this.size -= n
+ for (var i = 0; i < this.children.length; ++i) {
+ var child = this$1.children[i], sz = child.chunkSize()
+ if (at < sz) {
+ var rm = Math.min(n, sz - at), oldHeight = child.height
+ child.removeInner(at, rm)
+ this$1.height -= oldHeight - child.height
+ if (sz == rm) { this$1.children.splice(i--, 1); child.parent = null }
+ if ((n -= rm) == 0) { break }
+ at = 0
+ } else { at -= sz }
+ }
+ // If the result is smaller than 25 lines, ensure that it is a
+ // single leaf node.
+ if (this.size - n < 25 &&
+ (this.children.length > 1 || !(this.children[0] instanceof LeafChunk))) {
+ var lines = []
+ this.collapse(lines)
+ this.children = [new LeafChunk(lines)]
+ this.children[0].parent = this
+ }
+ },
-BranchChunk.prototype.collapse = function (lines) {
+ collapse: function collapse(lines) {
var this$1 = this;
- for (var i = 0; i < this.children.length; ++i) { this$1.children[i].collapse(lines) }
-};
+ for (var i = 0; i < this.children.length; ++i) { this$1.children[i].collapse(lines) }
+ },
-BranchChunk.prototype.insertInner = function (at, lines, height) {
+ insertInner: function insertInner(at, lines, height) {
var this$1 = this;
- this.size += lines.length
- this.height += height
- for (var i = 0; i < this.children.length; ++i) {
- var child = this$1.children[i], sz = child.chunkSize()
- if (at <= sz) {
- child.insertInner(at, lines, height)
- if (child.lines && child.lines.length > 50) {
- // To avoid memory thrashing when child.lines is huge (e.g. first view of a large file), it's never spliced.
- // Instead, small slices are taken. They're taken in order because sequential memory accesses are fastest.
- var remaining = child.lines.length % 25 + 25
- for (var pos = remaining; pos < child.lines.length;) {
- var leaf = new LeafChunk(child.lines.slice(pos, pos += 25))
- child.height -= leaf.height
- this$1.children.splice(++i, 0, leaf)
- leaf.parent = this$1
+ this.size += lines.length
+ this.height += height
+ for (var i = 0; i < this.children.length; ++i) {
+ var child = this$1.children[i], sz = child.chunkSize()
+ if (at <= sz) {
+ child.insertInner(at, lines, height)
+ if (child.lines && child.lines.length > 50) {
+ // To avoid memory thrashing when child.lines is huge (e.g. first view of a large file), it's never spliced.
+ // Instead, small slices are taken. They're taken in order because sequential memory accesses are fastest.
+ var remaining = child.lines.length % 25 + 25
+ for (var pos = remaining; pos < child.lines.length;) {
+ var leaf = new LeafChunk(child.lines.slice(pos, pos += 25))
+ child.height -= leaf.height
+ this$1.children.splice(++i, 0, leaf)
+ leaf.parent = this$1
+ }
+ child.lines = child.lines.slice(0, remaining)
+ this$1.maybeSpill()
}
- child.lines = child.lines.slice(0, remaining)
- this$1.maybeSpill()
+ break
}
- break
+ at -= sz
}
- at -= sz
- }
-};
+ },
-// When a node has grown, check whether it should be split.
-BranchChunk.prototype.maybeSpill = function () {
- if (this.children.length <= 10) { return }
- var me = this
- do {
- var spilled = me.children.splice(me.children.length - 5, 5)
- var sibling = new BranchChunk(spilled)
- if (!me.parent) { // Become the parent node
- var copy = new BranchChunk(me.children)
- copy.parent = me
- me.children = [copy, sibling]
- me = copy
- } else {
- me.size -= sibling.size
- me.height -= sibling.height
- var myIndex = indexOf(me.parent.children, me)
- me.parent.children.splice(myIndex + 1, 0, sibling)
- }
- sibling.parent = me.parent
- } while (me.children.length > 10)
- me.parent.maybeSpill()
-};
+ // When a node has grown, check whether it should be split.
+ maybeSpill: function maybeSpill() {
+ if (this.children.length <= 10) { return }
+ var me = this
+ do {
+ var spilled = me.children.splice(me.children.length - 5, 5)
+ var sibling = new BranchChunk(spilled)
+ if (!me.parent) { // Become the parent node
+ var copy = new BranchChunk(me.children)
+ copy.parent = me
+ me.children = [copy, sibling]
+ me = copy
+ } else {
+ me.size -= sibling.size
+ me.height -= sibling.height
+ var myIndex = indexOf(me.parent.children, me)
+ me.parent.children.splice(myIndex + 1, 0, sibling)
+ }
+ sibling.parent = me.parent
+ } while (me.children.length > 10)
+ me.parent.maybeSpill()
+ },
-BranchChunk.prototype.iterN = function (at, n, op) {
+ iterN: function iterN(at, n, op) {
var this$1 = this;
- for (var i = 0; i < this.children.length; ++i) {
- var child = this$1.children[i], sz = child.chunkSize()
- if (at < sz) {
- var used = Math.min(n, sz - at)
- if (child.iterN(at, used, op)) { return true }
- if ((n -= used) == 0) { break }
- at = 0
- } else { at -= sz }
+ for (var i = 0; i < this.children.length; ++i) {
+ var child = this$1.children[i], sz = child.chunkSize()
+ if (at < sz) {
+ var used = Math.min(n, sz - at)
+ if (child.iterN(at, used, op)) { return true }
+ if ((n -= used) == 0) { break }
+ at = 0
+ } else { at -= sz }
+ }
}
-};
+}
// Line widgets are block elements displayed above or below a line.
@@ -5535,7 +5694,7 @@ eventMixin(LineWidget)
function adjustScrollWhenAboveVisible(cm, line, diff) {
if (heightAtLine(line) < ((cm.curOp && cm.curOp.scrollTop) || cm.doc.scrollTop))
- { addToScrollPos(cm, null, diff) }
+ { addToScrollTop(cm, diff) }
}
function addLineWidget(doc, handle, node, options) {
@@ -5550,7 +5709,7 @@ function addLineWidget(doc, handle, node, options) {
if (cm && !lineIsHidden(doc, line)) {
var aboveVisible = heightAtLine(line) < doc.scrollTop
updateLineHeight(line, line.height + widgetHeight(widget))
- if (aboveVisible) { addToScrollPos(cm, null, widget.height) }
+ if (aboveVisible) { addToScrollTop(cm, widget.height) }
cm.curOp.forceUpdate = true
}
return true
@@ -5714,8 +5873,7 @@ function markText(doc, from, to, options, type) {
if (marker.replacedWith) {
// Showing up as a widget implies collapsed (widget replaces text)
marker.collapsed = true
- marker.widgetNode = elt("span", [marker.replacedWith], "CodeMirror-widget")
- marker.widgetNode.setAttribute("role", "presentation") // hide from accessibility tree
+ marker.widgetNode = eltP("span", [marker.replacedWith], "CodeMirror-widget")
if (!options.handleMouseEvents) { marker.widgetNode.setAttribute("cm-ignore-events", "true") }
if (options.insertLeft) { marker.widgetNode.insertLeft = true }
}
@@ -5854,7 +6012,7 @@ var Doc = function(text, mode, firstLine, lineSep, direction) {
this.scrollTop = this.scrollLeft = 0
this.cantEdit = false
this.cleanGeneration = 1
- this.frontier = firstLine
+ this.modeFrontier = this.highlightFrontier = firstLine
var start = Pos(firstLine, 0)
this.sel = simpleSelection(start)
this.history = new History(null)
@@ -5900,7 +6058,8 @@ Doc.prototype = createObj(BranchChunk.prototype, {
var top = Pos(this.first, 0), last = this.first + this.size - 1
makeChange(this, {from: top, to: Pos(last, getLine(this, last).text.length),
text: this.splitLines(code), origin: "setValue", full: true}, true)
- setSelection(this, simpleSelection(top))
+ if (this.cm) { scrollToCoords(this.cm, 0, 0) }
+ setSelection(this, simpleSelection(top), sel_dontScroll)
}),
replaceRange: function(code, from, to, origin) {
from = clipPos(this, from)
@@ -6376,8 +6535,8 @@ function clearDragCursor(cm) {
// garbage collected.
function forEachCodeMirror(f) {
- if (!document.body.getElementsByClassName) { return }
- var byClass = document.body.getElementsByClassName("CodeMirror")
+ if (!document.getElementsByClassName) { return }
+ var byClass = document.getElementsByClassName("CodeMirror")
for (var i = 0; i < byClass.length; i++) {
var cm = byClass[i].CodeMirror
if (cm) { f(cm) }
@@ -6551,11 +6710,8 @@ function isModifierKey(value) {
return name == "Ctrl" || name == "Alt" || name == "Shift" || name == "Mod"
}
-// Look up the name of a key as indicated by an event object.
-function keyName(event, noShift) {
- if (presto && event.keyCode == 34 && event["char"]) { return false }
- var base = keyNames[event.keyCode], name = base
- if (name == null || event.altGraphKey) { return false }
+function addModifierNames(name, event, noShift) {
+ var base = name
if (event.altKey && base != "Alt") { name = "Alt-" + name }
if ((flipCtrlCmd ? event.metaKey : event.ctrlKey) && base != "Ctrl") { name = "Ctrl-" + name }
if ((flipCtrlCmd ? event.ctrlKey : event.metaKey) && base != "Cmd") { name = "Cmd-" + name }
@@ -6563,6 +6719,14 @@ function keyName(event, noShift) {
return name
}
+// Look up the name of a key as indicated by an event object.
+function keyName(event, noShift) {
+ if (presto && event.keyCode == 34 && event["char"]) { return false }
+ var name = keyNames[event.keyCode]
+ if (name == null || event.altGraphKey) { return false }
+ return addModifierNames(name, event, noShift)
+}
+
function getKeyMap(val) {
return typeof val == "string" ? keyMap[val] : val
}
@@ -6592,6 +6756,112 @@ function deleteNearSelection(cm, compute) {
})
}
+function moveCharLogically(line, ch, dir) {
+ var target = skipExtendingChars(line.text, ch + dir, dir)
+ return target < 0 || target > line.text.length ? null : target
+}
+
+function moveLogically(line, start, dir) {
+ var ch = moveCharLogically(line, start.ch, dir)
+ return ch == null ? null : new Pos(start.line, ch, dir < 0 ? "after" : "before")
+}
+
+function endOfLine(visually, cm, lineObj, lineNo, dir) {
+ if (visually) {
+ var order = getOrder(lineObj, cm.doc.direction)
+ if (order) {
+ var part = dir < 0 ? lst(order) : order[0]
+ var moveInStorageOrder = (dir < 0) == (part.level == 1)
+ var sticky = moveInStorageOrder ? "after" : "before"
+ var ch
+ // With a wrapped rtl chunk (possibly spanning multiple bidi parts),
+ // it could be that the last bidi part is not on the last visual line,
+ // since visual lines contain content order-consecutive chunks.
+ // Thus, in rtl, we are looking for the first (content-order) character
+ // in the rtl chunk that is on the last line (that is, the same line
+ // as the last (content-order) character).
+ if (part.level > 0 || cm.doc.direction == "rtl") {
+ var prep = prepareMeasureForLine(cm, lineObj)
+ ch = dir < 0 ? lineObj.text.length - 1 : 0
+ var targetTop = measureCharPrepared(cm, prep, ch).top
+ ch = findFirst(function (ch) { return measureCharPrepared(cm, prep, ch).top == targetTop; }, (dir < 0) == (part.level == 1) ? part.from : part.to - 1, ch)
+ if (sticky == "before") { ch = moveCharLogically(lineObj, ch, 1) }
+ } else { ch = dir < 0 ? part.to : part.from }
+ return new Pos(lineNo, ch, sticky)
+ }
+ }
+ return new Pos(lineNo, dir < 0 ? lineObj.text.length : 0, dir < 0 ? "before" : "after")
+}
+
+function moveVisually(cm, line, start, dir) {
+ var bidi = getOrder(line, cm.doc.direction)
+ if (!bidi) { return moveLogically(line, start, dir) }
+ if (start.ch >= line.text.length) {
+ start.ch = line.text.length
+ start.sticky = "before"
+ } else if (start.ch <= 0) {
+ start.ch = 0
+ start.sticky = "after"
+ }
+ var partPos = getBidiPartAt(bidi, start.ch, start.sticky), part = bidi[partPos]
+ if (cm.doc.direction == "ltr" && part.level % 2 == 0 && (dir > 0 ? part.to > start.ch : part.from < start.ch)) {
+ // Case 1: We move within an ltr part in an ltr editor. Even with wrapped lines,
+ // nothing interesting happens.
+ return moveLogically(line, start, dir)
+ }
+
+ var mv = function (pos, dir) { return moveCharLogically(line, pos instanceof Pos ? pos.ch : pos, dir); }
+ var prep
+ var getWrappedLineExtent = function (ch) {
+ if (!cm.options.lineWrapping) { return {begin: 0, end: line.text.length} }
+ prep = prep || prepareMeasureForLine(cm, line)
+ return wrappedLineExtentChar(cm, line, prep, ch)
+ }
+ var wrappedLineExtent = getWrappedLineExtent(start.sticky == "before" ? mv(start, -1) : start.ch)
+
+ if (cm.doc.direction == "rtl" || part.level == 1) {
+ var moveInStorageOrder = (part.level == 1) == (dir < 0)
+ var ch = mv(start, moveInStorageOrder ? 1 : -1)
+ if (ch != null && (!moveInStorageOrder ? ch >= part.from && ch >= wrappedLineExtent.begin : ch <= part.to && ch <= wrappedLineExtent.end)) {
+ // Case 2: We move within an rtl part or in an rtl editor on the same visual line
+ var sticky = moveInStorageOrder ? "before" : "after"
+ return new Pos(start.line, ch, sticky)
+ }
+ }
+
+ // Case 3: Could not move within this bidi part in this visual line, so leave
+ // the current bidi part
+
+ var searchInVisualLine = function (partPos, dir, wrappedLineExtent) {
+ var getRes = function (ch, moveInStorageOrder) { return moveInStorageOrder
+ ? new Pos(start.line, mv(ch, 1), "before")
+ : new Pos(start.line, ch, "after"); }
+
+ for (; partPos >= 0 && partPos < bidi.length; partPos += dir) {
+ var part = bidi[partPos]
+ var moveInStorageOrder = (dir > 0) == (part.level != 1)
+ var ch = moveInStorageOrder ? wrappedLineExtent.begin : mv(wrappedLineExtent.end, -1)
+ if (part.from <= ch && ch < part.to) { return getRes(ch, moveInStorageOrder) }
+ ch = moveInStorageOrder ? part.from : mv(part.to, -1)
+ if (wrappedLineExtent.begin <= ch && ch < wrappedLineExtent.end) { return getRes(ch, moveInStorageOrder) }
+ }
+ }
+
+ // Case 3a: Look for other bidi parts on the same visual line
+ var res = searchInVisualLine(partPos + dir, dir, wrappedLineExtent)
+ if (res) { return res }
+
+ // Case 3b: Look for other bidi parts on the next visual line
+ var nextCh = dir > 0 ? wrappedLineExtent.end : mv(wrappedLineExtent.begin, -1)
+ if (nextCh != null && !(dir > 0 && nextCh == line.text.length)) {
+ res = searchInVisualLine(dir > 0 ? 0 : bidi.length - 1, dir, getWrappedLineExtent(nextCh))
+ if (res) { return res }
+ }
+
+ // Case 4: Nowhere to move
+ return null
+}
+
// Commands are parameter-less actions that can be performed on an
// editor, mostly used for keybindings.
var commands = {
@@ -6641,15 +6911,15 @@ var commands = {
{origin: "+move", bias: -1}
); },
goLineRight: function (cm) { return cm.extendSelectionsBy(function (range) {
- var top = cm.charCoords(range.head, "div").top + 5
+ var top = cm.cursorCoords(range.head, "div").top + 5
return cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div")
}, sel_move); },
goLineLeft: function (cm) { return cm.extendSelectionsBy(function (range) {
- var top = cm.charCoords(range.head, "div").top + 5
+ var top = cm.cursorCoords(range.head, "div").top + 5
return cm.coordsChar({left: 0, top: top}, "div")
}, sel_move); },
goLineLeftSmart: function (cm) { return cm.extendSelectionsBy(function (range) {
- var top = cm.charCoords(range.head, "div").top + 5
+ var top = cm.cursorCoords(range.head, "div").top + 5
var pos = cm.coordsChar({left: 0, top: top}, "div")
if (pos.ch < cm.getLine(pos.line).search(/\S/)) { return lineStartSmart(cm, range.head) }
return pos
@@ -6789,19 +7059,30 @@ function lookupKeyForEditor(cm, name, handle) {
|| lookupKey(name, cm.options.keyMap, handle, cm)
}
+// Note that, despite the name, this function is also used to check
+// for bound mouse clicks.
+
var stopSeq = new Delayed
+
function dispatchKey(cm, name, e, handle) {
var seq = cm.state.keySeq
if (seq) {
if (isModifierKey(name)) { return "handled" }
- stopSeq.set(50, function () {
- if (cm.state.keySeq == seq) {
- cm.state.keySeq = null
- cm.display.input.reset()
- }
- })
- name = seq + " " + name
+ if (/\'$/.test(name))
+ { cm.state.keySeq = null }
+ else
+ { stopSeq.set(50, function () {
+ if (cm.state.keySeq == seq) {
+ cm.state.keySeq = null
+ cm.display.input.reset()
+ }
+ }) }
+ if (dispatchKeyInner(cm, seq + " " + name, e, handle)) { return true }
}
+ return dispatchKeyInner(cm, name, e, handle)
+}
+
+function dispatchKeyInner(cm, name, e, handle) {
var result = lookupKeyForEditor(cm, name, handle)
if (result == "multi")
@@ -6814,10 +7095,6 @@ function dispatchKey(cm, name, e, handle) {
restartBlink(cm)
}
- if (seq && !result && /\'$/.test(name)) {
- e_preventDefault(e)
- return true
- }
return !!result
}
@@ -6900,6 +7177,37 @@ function onKeyPress(e) {
cm.display.input.onKeyPress(e)
}
+var DOUBLECLICK_DELAY = 400
+
+var PastClick = function(time, pos, button) {
+ this.time = time
+ this.pos = pos
+ this.button = button
+};
+
+PastClick.prototype.compare = function (time, pos, button) {
+ return this.time + DOUBLECLICK_DELAY > time &&
+ cmp(pos, this.pos) == 0 && button == this.button
+};
+
+var lastClick;
+var lastDoubleClick;
+function clickRepeat(pos, button) {
+ var now = +new Date
+ if (lastDoubleClick && lastDoubleClick.compare(now, pos, button)) {
+ lastClick = lastDoubleClick = null
+ return "triple"
+ } else if (lastClick && lastClick.compare(now, pos, button)) {
+ lastDoubleClick = new PastClick(now, pos, button)
+ lastClick = null
+ return "double"
+ } else {
+ lastClick = new PastClick(now, pos, button)
+ lastDoubleClick = null
+ return "single"
+ }
+}
+
// A mouse down can be a single click, double click, triple click,
// start of selection drag, start of text drag, new cursor
// (ctrl-click), rectangle drag (alt-drag), or xwin
@@ -6921,72 +7229,91 @@ function onMouseDown(e) {
return
}
if (clickInGutter(cm, e)) { return }
- var start = posFromMouse(cm, e)
+ var pos = posFromMouse(cm, e), button = e_button(e), repeat = pos ? clickRepeat(pos, button) : "single"
window.focus()
- switch (e_button(e)) {
- case 1:
- // #3261: make sure, that we're not starting a second selection
- if (cm.state.selectingText)
- { cm.state.selectingText(e) }
- else if (start)
- { leftButtonDown(cm, e, start) }
- else if (e_target(e) == display.scroller)
- { e_preventDefault(e) }
- break
- case 2:
- if (webkit) { cm.state.lastMiddleDown = +new Date }
- if (start) { extendSelection(cm.doc, start) }
+ // #3261: make sure, that we're not starting a second selection
+ if (button == 1 && cm.state.selectingText)
+ { cm.state.selectingText(e) }
+
+ if (pos && handleMappedButton(cm, button, pos, repeat, e)) { return }
+
+ if (button == 1) {
+ if (pos) { leftButtonDown(cm, pos, repeat, e) }
+ else if (e_target(e) == display.scroller) { e_preventDefault(e) }
+ } else if (button == 2) {
+ if (pos) { extendSelection(cm.doc, pos) }
setTimeout(function () { return display.input.focus(); }, 20)
- e_preventDefault(e)
- break
- case 3:
+ } else if (button == 3) {
if (captureRightClick) { onContextMenu(cm, e) }
else { delayBlurEvent(cm) }
- break
}
}
-var lastClick;
-var lastDoubleClick;
-function leftButtonDown(cm, e, start) {
+function handleMappedButton(cm, button, pos, repeat, event) {
+ var name = "Click"
+ if (repeat == "double") { name = "Double" + name }
+ else if (repeat == "triple") { name = "Triple" + name }
+ name = (button == 1 ? "Left" : button == 2 ? "Middle" : "Right") + name
+
+ return dispatchKey(cm, addModifierNames(name, event), event, function (bound) {
+ if (typeof bound == "string") { bound = commands[bound] }
+ if (!bound) { return false }
+ var done = false
+ try {
+ if (cm.isReadOnly()) { cm.state.suppressEdits = true }
+ done = bound(cm, pos) != Pass
+ } finally {
+ cm.state.suppressEdits = false
+ }
+ return done
+ })
+}
+
+function configureMouse(cm, repeat, event) {
+ var option = cm.getOption("configureMouse")
+ var value = option ? option(cm, repeat, event) : {}
+ if (value.unit == null) {
+ var rect = chromeOS ? event.shiftKey && event.metaKey : event.altKey
+ value.unit = rect ? "rectangle" : repeat == "single" ? "char" : repeat == "double" ? "word" : "line"
+ }
+ if (value.extend == null || cm.doc.extend) { value.extend = cm.doc.extend || event.shiftKey }
+ if (value.addNew == null) { value.addNew = mac ? event.metaKey : event.ctrlKey }
+ if (value.moveOnDrag == null) { value.moveOnDrag = !(mac ? event.altKey : event.ctrlKey) }
+ return value
+}
+
+function leftButtonDown(cm, pos, repeat, event) {
if (ie) { setTimeout(bind(ensureFocus, cm), 0) }
else { cm.curOp.focus = activeElt() }
- var now = +new Date, type
- if (lastDoubleClick && lastDoubleClick.time > now - 400 && cmp(lastDoubleClick.pos, start) == 0) {
- type = "triple"
- } else if (lastClick && lastClick.time > now - 400 && cmp(lastClick.pos, start) == 0) {
- type = "double"
- lastDoubleClick = {time: now, pos: start}
- } else {
- type = "single"
- lastClick = {time: now, pos: start}
- }
+ var behavior = configureMouse(cm, repeat, event)
- var sel = cm.doc.sel, modifier = mac ? e.metaKey : e.ctrlKey, contained
+ var sel = cm.doc.sel, contained
if (cm.options.dragDrop && dragAndDrop && !cm.isReadOnly() &&
- type == "single" && (contained = sel.contains(start)) > -1 &&
- (cmp((contained = sel.ranges[contained]).from(), start) < 0 || start.xRel > 0) &&
- (cmp(contained.to(), start) > 0 || start.xRel < 0))
- { leftButtonStartDrag(cm, e, start, modifier) }
+ repeat == "single" && (contained = sel.contains(pos)) > -1 &&
+ (cmp((contained = sel.ranges[contained]).from(), pos) < 0 || pos.xRel > 0) &&
+ (cmp(contained.to(), pos) > 0 || pos.xRel < 0))
+ { leftButtonStartDrag(cm, event, pos, behavior) }
else
- { leftButtonSelect(cm, e, start, type, modifier) }
+ { leftButtonSelect(cm, event, pos, behavior) }
}
// Start a text drag. When it ends, see if any dragging actually
// happen, and treat as a click if it didn't.
-function leftButtonStartDrag(cm, e, start, modifier) {
- var display = cm.display, startTime = +new Date
- var dragEnd = operation(cm, function (e2) {
+function leftButtonStartDrag(cm, event, pos, behavior) {
+ var display = cm.display, moved = false
+ var dragEnd = operation(cm, function (e) {
if (webkit) { display.scroller.draggable = false }
cm.state.draggingText = false
off(document, "mouseup", dragEnd)
+ off(document, "mousemove", mouseMove)
+ off(display.scroller, "dragstart", dragStart)
off(display.scroller, "drop", dragEnd)
- if (Math.abs(e.clientX - e2.clientX) + Math.abs(e.clientY - e2.clientY) < 10) {
- e_preventDefault(e2)
- if (!modifier && +new Date - 200 < startTime)
- { extendSelection(cm.doc, start) }
+ if (!moved) {
+ e_preventDefault(e)
+ if (!behavior.addNew)
+ { extendSelection(cm.doc, pos, null, null, behavior.extend) }
// Work around unexplainable focus problem in IE9 (#2127) and Chrome (#3081)
if (webkit || ie && ie_version == 9)
{ setTimeout(function () {document.body.focus(); display.input.focus()}, 20) }
@@ -6994,23 +7321,40 @@ function leftButtonStartDrag(cm, e, start, modifier) {
{ display.input.focus() }
}
})
+ var mouseMove = function(e2) {
+ moved = moved || Math.abs(event.clientX - e2.clientX) + Math.abs(event.clientY - e2.clientY) >= 10
+ }
+ var dragStart = function () { return moved = true; }
// Let the drag handler handle this.
if (webkit) { display.scroller.draggable = true }
cm.state.draggingText = dragEnd
- dragEnd.copy = mac ? e.altKey : e.ctrlKey
+ dragEnd.copy = !behavior.moveOnDrag
// IE's approach to draggable
if (display.scroller.dragDrop) { display.scroller.dragDrop() }
on(document, "mouseup", dragEnd)
+ on(document, "mousemove", mouseMove)
+ on(display.scroller, "dragstart", dragStart)
on(display.scroller, "drop", dragEnd)
+
+ delayBlurEvent(cm)
+ setTimeout(function () { return display.input.focus(); }, 20)
+}
+
+function rangeForUnit(cm, pos, unit) {
+ if (unit == "char") { return new Range(pos, pos) }
+ if (unit == "word") { return cm.findWordAt(pos) }
+ if (unit == "line") { return new Range(Pos(pos.line, 0), clipPos(cm.doc, Pos(pos.line + 1, 0))) }
+ var result = unit(cm, pos)
+ return new Range(result.from, result.to)
}
// Normal selection, as opposed to text dragging.
-function leftButtonSelect(cm, e, start, type, addNew) {
+function leftButtonSelect(cm, event, start, behavior) {
var display = cm.display, doc = cm.doc
- e_preventDefault(e)
+ e_preventDefault(event)
var ourRange, ourIndex, startSel = doc.sel, ranges = startSel.ranges
- if (addNew && !e.shiftKey) {
+ if (behavior.addNew && !behavior.extend) {
ourIndex = doc.sel.contains(start)
if (ourIndex > -1)
{ ourRange = ranges[ourIndex] }
@@ -7021,28 +7365,19 @@ function leftButtonSelect(cm, e, start, type, addNew) {
ourIndex = doc.sel.primIndex
}
- if (chromeOS ? e.shiftKey && e.metaKey : e.altKey) {
- type = "rect"
- if (!addNew) { ourRange = new Range(start, start) }
- start = posFromMouse(cm, e, true, true)
+ if (behavior.unit == "rectangle") {
+ if (!behavior.addNew) { ourRange = new Range(start, start) }
+ start = posFromMouse(cm, event, true, true)
ourIndex = -1
- } else if (type == "double") {
- var word = cm.findWordAt(start)
- if (cm.display.shift || doc.extend)
- { ourRange = extendRange(doc, ourRange, word.anchor, word.head) }
- else
- { ourRange = word }
- } else if (type == "triple") {
- var line = new Range(Pos(start.line, 0), clipPos(doc, Pos(start.line + 1, 0)))
- if (cm.display.shift || doc.extend)
- { ourRange = extendRange(doc, ourRange, line.anchor, line.head) }
- else
- { ourRange = line }
} else {
- ourRange = extendRange(doc, ourRange, start)
+ var range = rangeForUnit(cm, start, behavior.unit)
+ if (behavior.extend)
+ { ourRange = extendRange(ourRange, range.anchor, range.head, behavior.extend) }
+ else
+ { ourRange = range }
}
- if (!addNew) {
+ if (!behavior.addNew) {
ourIndex = 0
setSelection(doc, new Selection([ourRange], 0), sel_mouse)
startSel = doc.sel
@@ -7050,7 +7385,7 @@ function leftButtonSelect(cm, e, start, type, addNew) {
ourIndex = ranges.length
setSelection(doc, normalizeSelection(ranges.concat([ourRange]), ourIndex),
{scroll: false, origin: "*mouse"})
- } else if (ranges.length > 1 && ranges[ourIndex].empty() && type == "single" && !e.shiftKey) {
+ } else if (ranges.length > 1 && ranges[ourIndex].empty() && behavior.unit == "char" && !behavior.extend) {
setSelection(doc, normalizeSelection(ranges.slice(0, ourIndex).concat(ranges.slice(ourIndex + 1)), 0),
{scroll: false, origin: "*mouse"})
startSel = doc.sel
@@ -7063,7 +7398,7 @@ function leftButtonSelect(cm, e, start, type, addNew) {
if (cmp(lastPos, pos) == 0) { return }
lastPos = pos
- if (type == "rect") {
+ if (behavior.unit == "rectangle") {
var ranges = [], tabSize = cm.options.tabSize
var startCol = countColumn(getLine(doc, start.line).text, start.ch, tabSize)
var posCol = countColumn(getLine(doc, pos.line).text, pos.ch, tabSize)
@@ -7082,23 +7417,17 @@ function leftButtonSelect(cm, e, start, type, addNew) {
cm.scrollIntoView(pos)
} else {
var oldRange = ourRange
- var anchor = oldRange.anchor, head = pos
- if (type != "single") {
- var range
- if (type == "double")
- { range = cm.findWordAt(pos) }
- else
- { range = new Range(Pos(pos.line, 0), clipPos(doc, Pos(pos.line + 1, 0))) }
- if (cmp(range.anchor, anchor) > 0) {
- head = range.head
- anchor = minPos(oldRange.from(), range.anchor)
- } else {
- head = range.anchor
- anchor = maxPos(oldRange.to(), range.head)
- }
+ var range = rangeForUnit(cm, pos, behavior.unit)
+ var anchor = oldRange.anchor, head
+ if (cmp(range.anchor, anchor) > 0) {
+ head = range.head
+ anchor = minPos(oldRange.from(), range.anchor)
+ } else {
+ head = range.anchor
+ anchor = maxPos(oldRange.to(), range.head)
}
var ranges$1 = startSel.ranges.slice(0)
- ranges$1[ourIndex] = new Range(clipPos(doc, anchor), head)
+ ranges$1[ourIndex] = bidiSimplify(cm, new Range(clipPos(doc, anchor), head))
setSelection(doc, normalizeSelection(ranges$1, ourIndex), sel_mouse)
}
}
@@ -7112,7 +7441,7 @@ function leftButtonSelect(cm, e, start, type, addNew) {
function extend(e) {
var curCount = ++counter
- var cur = posFromMouse(cm, e, true, type == "rect")
+ var cur = posFromMouse(cm, e, true, behavior.unit == "rectangle")
if (!cur) { return }
if (cmp(cur, lastPos) != 0) {
cm.curOp.focus = activeElt()
@@ -7150,13 +7479,52 @@ function leftButtonSelect(cm, e, start, type, addNew) {
on(document, "mouseup", up)
}
+// Used when mouse-selecting to adjust the anchor to the proper side
+// of a bidi jump depending on the visual position of the head.
+function bidiSimplify(cm, range) {
+ var anchor = range.anchor;
+ var head = range.head;
+ var anchorLine = getLine(cm.doc, anchor.line)
+ if (cmp(anchor, head) == 0 && anchor.sticky == head.sticky) { return range }
+ var order = getOrder(anchorLine)
+ if (!order) { return range }
+ var index = getBidiPartAt(order, anchor.ch, anchor.sticky), part = order[index]
+ if (part.from != anchor.ch && part.to != anchor.ch) { return range }
+ var boundary = index + ((part.from == anchor.ch) == (part.level != 1) ? 0 : 1)
+ if (boundary == 0 || boundary == order.length) { return range }
+
+ // Compute the relative visual position of the head compared to the
+ // anchor (<0 is to the left, >0 to the right)
+ var leftSide
+ if (head.line != anchor.line) {
+ leftSide = (head.line - anchor.line) * (cm.doc.direction == "ltr" ? 1 : -1) > 0
+ } else {
+ var headIndex = getBidiPartAt(order, head.ch, head.sticky)
+ var dir = headIndex - index || (head.ch - anchor.ch) * (part.level == 1 ? -1 : 1)
+ if (headIndex == boundary - 1 || headIndex == boundary)
+ { leftSide = dir < 0 }
+ else
+ { leftSide = dir > 0 }
+ }
+
+ var usePart = order[boundary + (leftSide ? -1 : 0)]
+ var from = leftSide == (usePart.level == 1)
+ var ch = from ? usePart.from : usePart.to, sticky = from ? "after" : "before"
+ return anchor.ch == ch && anchor.sticky == sticky ? range : new Range(new Pos(anchor.line, ch, sticky), head)
+}
+
// Determines whether an event happened in the gutter, and fires the
// handlers for the corresponding event.
function gutterEvent(cm, e, type, prevent) {
var mX, mY
- try { mX = e.clientX; mY = e.clientY }
- catch(e) { return false }
+ if (e.touches) {
+ mX = e.touches[0].clientX
+ mY = e.touches[0].clientY
+ } else {
+ try { mX = e.clientX; mY = e.clientY }
+ catch(e) { return false }
+ }
if (mX >= Math.floor(cm.display.gutters.getBoundingClientRect().right)) { return false }
if (prevent) { e_preventDefault(e) }
@@ -7278,6 +7646,7 @@ function defineOptions(CodeMirror) {
if (next.attach) { next.attach(cm, prev || null) }
})
option("extraKeys", null)
+ option("configureMouse", null)
option("lineWrapping", false, wrappingChanged, true)
option("gutters", [], function (cm) {
@@ -7305,14 +7674,12 @@ function defineOptions(CodeMirror) {
option("resetSelectionOnContextMenu", true)
option("lineWiseCopyCut", true)
+ option("pasteLinesPerSelection", true)
option("readOnly", false, function (cm, val) {
if (val == "nocursor") {
onBlur(cm)
cm.display.input.blur()
- cm.display.disabled = true
- } else {
- cm.display.disabled = false
}
cm.display.input.readOnlyChanged(val)
})
@@ -7495,7 +7862,7 @@ function registerEventHandlers(cm) {
return dx * dx + dy * dy > 20 * 20
}
on(d.scroller, "touchstart", function (e) {
- if (!signalDOMEvent(cm, e) && !isMouseLikeTouchEvent(e)) {
+ if (!signalDOMEvent(cm, e) && !isMouseLikeTouchEvent(e) && !clickInGutter(cm, e)) {
d.input.ensurePolled()
clearTimeout(touchFinished)
var now = +new Date
@@ -7533,7 +7900,7 @@ function registerEventHandlers(cm) {
// area, ensure viewport is updated when scrolling.
on(d.scroller, "scroll", function () {
if (d.scroller.clientHeight) {
- setScrollTop(cm, d.scroller.scrollTop)
+ updateScrollTop(cm, d.scroller.scrollTop)
setScrollLeft(cm, d.scroller.scrollLeft, true)
signal(cm, "scroll", cm)
}
@@ -7577,7 +7944,7 @@ function indentLine(cm, n, how, aggressive) {
// Fall back to "prev" when the mode doesn't have an indentation
// method.
if (!doc.mode.indent) { how = "prev" }
- else { state = getStateBefore(cm, n) }
+ else { state = getContextBefore(cm, n).state }
}
var tabSize = cm.options.tabSize
@@ -7653,7 +8020,7 @@ function applyTextInput(cm, inserted, deleted, sel, origin) {
for (var i = 0; i < lastCopied.text.length; i++)
{ multiPaste.push(doc.splitLines(lastCopied.text[i])) }
}
- } else if (textLines.length == sel.ranges.length) {
+ } else if (textLines.length == sel.ranges.length && cm.options.pasteLinesPerSelection) {
multiPaste = map(textLines, function (l) { return [l]; })
}
}
@@ -7913,7 +8280,7 @@ function addEditorMethods(CodeMirror) {
getStateAfter: function(line, precise) {
var doc = this.doc
line = clipLine(doc, line == null ? doc.first + doc.size - 1: line)
- return getStateBefore(this, line + 1, precise)
+ return getContextBefore(this, line + 1, precise).state
},
cursorCoords: function(start, mode) {
@@ -7994,6 +8361,7 @@ function addEditorMethods(CodeMirror) {
triggerOnKeyDown: methodOp(onKeyDown),
triggerOnKeyPress: methodOp(onKeyPress),
triggerOnKeyUp: onKeyUp,
+ triggerOnMouseDown: methodOp(onMouseDown),
execCommand: function(cmd) {
if (commands.hasOwnProperty(cmd))
@@ -8066,7 +8434,7 @@ function addEditorMethods(CodeMirror) {
goals.push(headPos.left)
var pos = findPosV(this$1, headPos, dir, unit)
if (unit == "page" && range == doc.sel.primary())
- { addToScrollPos(this$1, null, charCoords(this$1, pos, "div").top - headPos.top) }
+ { addToScrollTop(this$1, charCoords(this$1, pos, "div").top - headPos.top) }
return pos
}, sel_move)
if (goals.length) { for (var i = 0; i < doc.sel.ranges.length; i++)
@@ -8103,11 +8471,7 @@ function addEditorMethods(CodeMirror) {
hasFocus: function() { return this.display.input.getField() == activeElt() },
isReadOnly: function() { return !!(this.options.readOnly || this.doc.cantEdit) },
- scrollTo: methodOp(function(x, y) {
- if (x != null || y != null) { resolveScrollToPos(this) }
- if (x != null) { this.curOp.scrollLeft = x }
- if (y != null) { this.curOp.scrollTop = y }
- }),
+ scrollTo: methodOp(function (x, y) { scrollToCoords(this, x, y) }),
getScrollInfo: function() {
var scroller = this.display.scroller
return {left: scroller.scrollLeft, top: scroller.scrollTop,
@@ -8129,16 +8493,9 @@ function addEditorMethods(CodeMirror) {
range.margin = margin || 0
if (range.from.line != null) {
- resolveScrollToPos(this)
- this.curOp.scrollToPos = range
+ scrollToRange(this, range)
} else {
- var sPos = calculateScrollPos(this, {
- left: Math.min(range.from.left, range.to.left),
- top: Math.min(range.from.top, range.to.top) - range.margin,
- right: Math.max(range.from.right, range.to.right),
- bottom: Math.max(range.from.bottom, range.to.bottom) + range.margin
- })
- this.scrollTo(sPos.scrollLeft, sPos.scrollTop)
+ scrollToCoordsRange(this, range.from, range.to, range.margin)
}
}),
@@ -8160,13 +8517,15 @@ function addEditorMethods(CodeMirror) {
}),
operation: function(f){return runInOp(this, f)},
+ startOperation: function(){return startOperation(this)},
+ endOperation: function(){return endOperation(this)},
refresh: methodOp(function() {
var oldHeight = this.display.cachedTextHeight
regChange(this)
this.curOp.forceUpdate = true
clearCaches(this)
- this.scrollTo(this.doc.scrollLeft, this.doc.scrollTop)
+ scrollToCoords(this, this.doc.scrollLeft, this.doc.scrollTop)
updateGutterSpace(this)
if (oldHeight == null || Math.abs(oldHeight - textHeight(this.display)) > .5)
{ estimateLineHeights(this) }
@@ -8179,7 +8538,7 @@ function addEditorMethods(CodeMirror) {
attachDoc(this, doc)
clearCaches(this)
this.display.input.reset()
- this.scrollTo(doc.scrollLeft, doc.scrollTop)
+ scrollToCoords(this, doc.scrollLeft, doc.scrollTop)
this.curOp.forceScroll = true
signalLater(this, "swapDoc", this, old)
return old
@@ -8390,36 +8749,41 @@ ContentEditableInput.prototype.showSelection = function (info, takeFocus) {
};
ContentEditableInput.prototype.showPrimarySelection = function () {
- var sel = window.getSelection(), prim = this.cm.doc.sel.primary()
- var curAnchor = domToPos(this.cm, sel.anchorNode, sel.anchorOffset)
- var curFocus = domToPos(this.cm, sel.focusNode, sel.focusOffset)
- if (curAnchor && !curAnchor.bad && curFocus && !curFocus.bad &&
- cmp(minPos(curAnchor, curFocus), prim.from()) == 0 &&
- cmp(maxPos(curAnchor, curFocus), prim.to()) == 0)
- { return }
+ var sel = window.getSelection(), cm = this.cm, prim = cm.doc.sel.primary()
+ var from = prim.from(), to = prim.to()
- var start = posToDOM(this.cm, prim.from())
- var end = posToDOM(this.cm, prim.to())
- if (!start && !end) {
+ if (cm.display.viewTo == cm.display.viewFrom || from.line >= cm.display.viewTo || to.line < cm.display.viewFrom) {
sel.removeAllRanges()
return
}
- var view = this.cm.display.view
- var old = sel.rangeCount && sel.getRangeAt(0)
- if (!start) {
- start = {node: view[0].measure.map[2], offset: 0}
- } else if (!end) { // FIXME dangerously hacky
+ var curAnchor = domToPos(cm, sel.anchorNode, sel.anchorOffset)
+ var curFocus = domToPos(cm, sel.focusNode, sel.focusOffset)
+ if (curAnchor && !curAnchor.bad && curFocus && !curFocus.bad &&
+ cmp(minPos(curAnchor, curFocus), from) == 0 &&
+ cmp(maxPos(curAnchor, curFocus), to) == 0)
+ { return }
+
+ var view = cm.display.view
+ var start = (from.line >= cm.display.viewFrom && posToDOM(cm, from)) ||
+ {node: view[0].measure.map[2], offset: 0}
+ var end = to.line < cm.display.viewTo && posToDOM(cm, to)
+ if (!end) {
var measure = view[view.length - 1].measure
var map = measure.maps ? measure.maps[measure.maps.length - 1] : measure.map
end = {node: map[map.length - 1], offset: map[map.length - 2] - map[map.length - 3]}
}
- var rng
+ if (!start || !end) {
+ sel.removeAllRanges()
+ return
+ }
+
+ var old = sel.rangeCount && sel.getRangeAt(0), rng
try { rng = range(start.node, start.offset, end.offset, end.node) }
catch(e) {} // Our model of the DOM might be outdated, in which case the range we try to set can be impossible
if (rng) {
- if (!gecko && this.cm.state.focused) {
+ if (!gecko && cm.state.focused) {
sel.collapse(start.node, start.offset)
if (!rng.collapsed) {
sel.removeAllRanges()
@@ -8698,7 +9062,7 @@ function domTextBetween(cm, from, to, fromLine, toLine) {
var markerID = node.getAttribute("cm-marker"), range
if (markerID) {
var found = cm.findMarks(Pos(fromLine, 0), Pos(toLine + 1, 0), recognizeMarker(+markerID))
- if (found.length && (range = found[0].find()))
+ if (found.length && (range = found[0].find(0)))
{ addText(getBetween(cm.doc, range.from, range.to).join(lineSep)) }
return
}
@@ -8807,9 +9171,6 @@ var TextareaInput = function(cm) {
this.pollingFast = false
// Self-resetting timeout for the poller
this.polling = new Delayed()
- // Tracks when input.reset has punted to just putting a short
- // string into the textarea instead of the full selection.
- this.inaccurateSelection = false
// Used to work around IE issue with selection being forgotten when focus moves away from textarea
this.hasSelection = false
this.composing = null
@@ -8846,12 +9207,6 @@ TextareaInput.prototype.init = function (display) {
if (signalDOMEvent(cm, e)) { return }
if (cm.somethingSelected()) {
setLastCopied({lineWise: false, text: cm.getSelections()})
- if (input.inaccurateSelection) {
- input.prevInput = ""
- input.inaccurateSelection = false
- te.value = lastCopied.text.join("\n")
- selectInput(te)
- }
} else if (!cm.options.lineWiseCopyCut) {
return
} else {
@@ -8929,14 +9284,11 @@ TextareaInput.prototype.showSelection = function (drawn) {
// Reset the input to correspond to the selection (or to be empty,
// when not typing and nothing is selected)
TextareaInput.prototype.reset = function (typing) {
- if (this.contextMenuPending) { return }
- var minimal, selected, cm = this.cm, doc = cm.doc
+ if (this.contextMenuPending || this.composing) { return }
+ var cm = this.cm
if (cm.somethingSelected()) {
this.prevInput = ""
- var range = doc.sel.primary()
- minimal = hasCopyEvent &&
- (range.to().line - range.from().line > 100 || (selected = cm.getSelection()).length > 1000)
- var content = minimal ? "-" : selected || cm.getSelection()
+ var content = cm.getSelection()
this.textarea.value = content
if (cm.state.focused) { selectInput(this.textarea) }
if (ie && ie_version >= 9) { this.hasSelection = content }
@@ -8944,7 +9296,6 @@ TextareaInput.prototype.reset = function (typing) {
this.prevInput = this.textarea.value = ""
if (ie && ie_version >= 9) { this.hasSelection = null }
}
- this.inaccurateSelection = minimal
};
TextareaInput.prototype.getField = function () { return this.textarea };
@@ -9139,6 +9490,7 @@ TextareaInput.prototype.onContextMenu = function (e) {
TextareaInput.prototype.readOnlyChanged = function (val) {
if (!val) { this.reset() }
+ this.textarea.disabled = val == "nocursor"
};
TextareaInput.prototype.setUneditable = function () {};
@@ -9294,7 +9646,7 @@ CodeMirror.fromTextArea = fromTextArea
addLegacyProps(CodeMirror)
-CodeMirror.version = "5.24.3"
+CodeMirror.version = "5.32.0"
return CodeMirror;
diff --git a/gui/public/codemirror/mode/apl/apl.js b/gui/public/codemirror/mode/apl/apl.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/apl/index.html b/gui/public/codemirror/mode/apl/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/asciiarmor/asciiarmor.js b/gui/public/codemirror/mode/asciiarmor/asciiarmor.js
old mode 100755
new mode 100644
index d8309037..fa1b0f8c
--- a/gui/public/codemirror/mode/asciiarmor/asciiarmor.js
+++ b/gui/public/codemirror/mode/asciiarmor/asciiarmor.js
@@ -68,6 +68,7 @@
});
CodeMirror.defineMIME("application/pgp", "asciiarmor");
+ CodeMirror.defineMIME("application/pgp-encrypted", "asciiarmor");
CodeMirror.defineMIME("application/pgp-keys", "asciiarmor");
CodeMirror.defineMIME("application/pgp-signature", "asciiarmor");
});
diff --git a/gui/public/codemirror/mode/asciiarmor/index.html b/gui/public/codemirror/mode/asciiarmor/index.html
old mode 100755
new mode 100644
index 8ba1b5c7..4d584efb
--- a/gui/public/codemirror/mode/asciiarmor/index.html
+++ b/gui/public/codemirror/mode/asciiarmor/index.html
@@ -41,6 +41,6 @@ var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
MIME types
-defined: application/pgp
, application/pgp-keys
, application/pgp-signature
+defined: application/pgp
, application/pgp-encrypted
, application/pgp-keys
, application/pgp-signature
diff --git a/gui/public/codemirror/mode/asn.1/asn.1.js b/gui/public/codemirror/mode/asn.1/asn.1.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/asn.1/index.html b/gui/public/codemirror/mode/asn.1/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/asterisk/asterisk.js b/gui/public/codemirror/mode/asterisk/asterisk.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/asterisk/index.html b/gui/public/codemirror/mode/asterisk/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/brainfuck/brainfuck.js b/gui/public/codemirror/mode/brainfuck/brainfuck.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/brainfuck/index.html b/gui/public/codemirror/mode/brainfuck/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/clike/clike.js b/gui/public/codemirror/mode/clike/clike.js
old mode 100755
new mode 100644
index 7424c9a0..02a85319
--- a/gui/public/codemirror/mode/clike/clike.js
+++ b/gui/public/codemirror/mode/clike/clike.js
@@ -33,7 +33,7 @@ function popContext(state) {
}
function typeBefore(stream, state, pos) {
- if (state.prevToken == "variable" || state.prevToken == "variable-3") return true;
+ if (state.prevToken == "variable" || state.prevToken == "type") return true;
if (/\S(?:[^- ]>|[*\]])\s*$|\*$/.test(stream.string.slice(0, pos))) return true;
if (state.typeAtEndOfLine && stream.column() == stream.indentation()) return true;
}
@@ -64,7 +64,8 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
isPunctuationChar = parserConfig.isPunctuationChar || /[\[\]{}\(\),;\:\.]/,
numberStart = parserConfig.numberStart || /[\d\.]/,
number = parserConfig.number || /^(?:0x[a-f\d]+|0b[01]+|(?:\d+\.?\d*|\.\d+)(?:e[-+]?\d+)?)(u|ll?|l|f)?/i,
- isOperatorChar = parserConfig.isOperatorChar || /[+\-*&%=<>!?|\/]/;
+ isOperatorChar = parserConfig.isOperatorChar || /[+\-*&%=<>!?|\/]/,
+ isIdentifierChar = parserConfig.isIdentifierChar || /[\w\$_\xa1-\uffff]/;
var curPunc, isDefKeyword;
@@ -101,9 +102,9 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
while (!stream.match(/^\/[\/*]/, false) && stream.eat(isOperatorChar)) {}
return "operator";
}
- stream.eatWhile(/[\w\$_\xa1-\uffff]/);
+ stream.eatWhile(isIdentifierChar);
if (namespaceSeparator) while (stream.match(namespaceSeparator))
- stream.eatWhile(/[\w\$_\xa1-\uffff]/);
+ stream.eatWhile(isIdentifierChar);
var cur = stream.current();
if (contains(keywords, cur)) {
@@ -111,7 +112,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
if (contains(defKeywords, cur)) isDefKeyword = true;
return "keyword";
}
- if (contains(types, cur)) return "variable-3";
+ if (contains(types, cur)) return "type";
if (contains(builtin, cur)) {
if (contains(blockKeywords, cur)) curPunc = "newstatement";
return "builtin";
@@ -243,6 +244,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
electricInput: indentSwitch ? /^\s*(?:case .*?:|default:|\{\}?|\})$/ : /^\s*[{}]$/,
blockCommentStart: "/*",
blockCommentEnd: "*/",
+ blockCommentContinue: " * ",
lineComment: "//",
fold: "brace"
};
@@ -280,7 +282,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
}
function pointerHook(_stream, state) {
- if (state.prevToken == "variable-3") return "variable-3";
+ if (state.prevToken == "type") return "type";
return false;
}
@@ -314,7 +316,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
}
function cppLooksLikeConstructor(word) {
- var lastTwo = /(\w+)::(\w+)$/.exec(word);
+ var lastTwo = /(\w+)::~?(\w+)$/.exec(word);
return lastTwo && lastTwo[1] == lastTwo[2];
}
@@ -390,6 +392,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
typeFirstDefinitions: true,
atoms: words("true false null"),
dontIndentStatements: /^template$/,
+ isIdentifierChar: /[\w\$_~\xa1-\uffff]/,
hooks: {
"#": cppHook,
"*": pointerHook,
@@ -429,7 +432,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
types: words("byte short int long float double boolean char void Boolean Byte Character Double Float " +
"Integer Long Number Object Short String StringBuffer StringBuilder Void"),
blockKeywords: words("catch class do else finally for if switch try while"),
- defKeywords: words("class interface package enum @interface"),
+ defKeywords: words("class interface enum @interface"),
typeFirstDefinitions: true,
atoms: words("true false null"),
number: /^(?:0x[a-f\d_]+|0b[01_]+|(?:[\d_]+\.?\d*|\.\d+)(?:e[-+]?[\d_]+)?)(u|ll?|l|f)?/i,
@@ -513,8 +516,8 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
"StringBuffer System Thread ThreadGroup ThreadLocal Throwable Triple Void"
),
multiLineStrings: true,
- blockKeywords: words("catch class do else finally for forSome if match switch try while"),
- defKeywords: words("class def object package trait type val var"),
+ blockKeywords: words("catch class enum do else finally for forSome if match switch try while"),
+ defKeywords: words("class enum def object package trait type val var"),
atoms: words("true false null"),
indentStatements: false,
indentSwitch: false,
@@ -575,7 +578,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
"file import where by get set abstract enum open inner override private public internal " +
"protected catch finally out final vararg reified dynamic companion constructor init " +
"sealed field property receiver param sparam lateinit data inline noinline tailrec " +
- "external annotation crossinline const operator infix"
+ "external annotation crossinline const operator infix suspend"
),
types: words(
/* package java.lang */
@@ -587,8 +590,9 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
intendSwitch: false,
indentStatements: false,
multiLineStrings: true,
+ number: /^(?:0x[a-f\d_]+|0b[01_]+|(?:[\d_]+\.?\d*|\.\d+)(?:e[-+]?[\d_]+)?)(u|ll?|l|f)?/i,
blockKeywords: words("catch class do else finally for if where try while enum"),
- defKeywords: words("class val var object package interface fun"),
+ defKeywords: words("class val var object interface fun"),
atoms: words("true false null this"),
hooks: {
'"': function(stream, state) {
@@ -771,7 +775,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
return "atom";
},
token: function(_stream, state, style) {
- if ((style == "variable" || style == "variable-3") &&
+ if ((style == "variable" || style == "type") &&
state.prevToken == ".") {
return "variable-2";
}
diff --git a/gui/public/codemirror/mode/clike/index.html b/gui/public/codemirror/mode/clike/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/clike/scala.html b/gui/public/codemirror/mode/clike/scala.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/clike/test.js b/gui/public/codemirror/mode/clike/test.js
old mode 100755
new mode 100644
index bea85b86..dad2e246
--- a/gui/public/codemirror/mode/clike/test.js
+++ b/gui/public/codemirror/mode/clike/test.js
@@ -6,8 +6,8 @@
function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }
MT("indent",
- "[variable-3 void] [def foo]([variable-3 void*] [variable a], [variable-3 int] [variable b]) {",
- " [variable-3 int] [variable c] [operator =] [variable b] [operator +]",
+ "[type void] [def foo]([type void*] [variable a], [type int] [variable b]) {",
+ " [type int] [variable c] [operator =] [variable b] [operator +]",
" [number 1];",
" [keyword return] [operator *][variable a];",
"}");
@@ -21,9 +21,9 @@
"}");
MT("def",
- "[variable-3 void] [def foo]() {}",
+ "[type void] [def foo]() {}",
"[keyword struct] [def bar]{}",
- "[variable-3 int] [variable-3 *][def baz]() {}");
+ "[type int] [type *][def baz]() {}");
MT("def_new_line",
"::[variable std]::[variable SomeTerribleType][operator <][variable T][operator >]",
@@ -37,10 +37,10 @@
MT("preprocessor",
"[meta #define FOO 3]",
- "[variable-3 int] [variable foo];",
+ "[type int] [variable foo];",
"[meta #define BAR\\]",
"[meta 4]",
- "[variable-3 unsigned] [variable-3 int] [variable bar] [operator =] [number 8];",
+ "[type unsigned] [type int] [variable bar] [operator =] [number 8];",
"[meta #include ][comment // comment]")
@@ -52,4 +52,8 @@
"[number 0b10'000];",
"[number 0x10'000];",
"[string '100000'];");
+
+ MTCPP("ctor_dtor",
+ "[def Foo::Foo]() {}",
+ "[def Foo::~Foo]() {}");
})();
diff --git a/gui/public/codemirror/mode/clojure/clojure.js b/gui/public/codemirror/mode/clojure/clojure.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/clojure/index.html b/gui/public/codemirror/mode/clojure/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/cmake/cmake.js b/gui/public/codemirror/mode/cmake/cmake.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/cmake/index.html b/gui/public/codemirror/mode/cmake/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/cobol/cobol.js b/gui/public/codemirror/mode/cobol/cobol.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/cobol/index.html b/gui/public/codemirror/mode/cobol/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/coffeescript/coffeescript.js b/gui/public/codemirror/mode/coffeescript/coffeescript.js
old mode 100755
new mode 100644
index adf2184f..ae955db3
--- a/gui/public/codemirror/mode/coffeescript/coffeescript.js
+++ b/gui/public/codemirror/mode/coffeescript/coffeescript.js
@@ -349,6 +349,10 @@ CodeMirror.defineMode("coffeescript", function(conf, parserConf) {
return external;
});
+// IANA registered media type
+// https://www.iana.org/assignments/media-types/
+CodeMirror.defineMIME("application/vnd.coffeescript", "coffeescript");
+
CodeMirror.defineMIME("text/x-coffeescript", "coffeescript");
CodeMirror.defineMIME("text/coffeescript", "coffeescript");
diff --git a/gui/public/codemirror/mode/coffeescript/index.html b/gui/public/codemirror/mode/coffeescript/index.html
old mode 100755
new mode 100644
index 93a5f4f3..92d161e9
--- a/gui/public/codemirror/mode/coffeescript/index.html
+++ b/gui/public/codemirror/mode/coffeescript/index.html
@@ -733,7 +733,7 @@ wrapper::value = -> this._wrapped
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {});
- MIME types defined: text/x-coffeescript
.
+ MIME types defined: application/vnd.coffeescript
, text/coffeescript
, text/x-coffeescript
.
The CoffeeScript mode was written by Jeff Pickhardt.
diff --git a/gui/public/codemirror/mode/commonlisp/commonlisp.js b/gui/public/codemirror/mode/commonlisp/commonlisp.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/commonlisp/index.html b/gui/public/codemirror/mode/commonlisp/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/crystal/crystal.js b/gui/public/codemirror/mode/crystal/crystal.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/crystal/index.html b/gui/public/codemirror/mode/crystal/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/css/css.js b/gui/public/codemirror/mode/css/css.js
old mode 100755
new mode 100644
index 23d0b4db..00e9b3df
--- a/gui/public/codemirror/mode/css/css.js
+++ b/gui/public/codemirror/mode/css/css.js
@@ -383,7 +383,8 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
style = style[0];
}
override = style;
- state.state = states[state.state](type, stream, state);
+ if (type != "comment")
+ state.state = states[state.state](type, stream, state);
return override;
},
@@ -401,7 +402,6 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
ch == "{" && (cx.type == "at" || cx.type == "atBlock")) {
// Dedent relative to current context.
indent = Math.max(0, cx.indent - indentUnit);
- cx = cx.prev;
}
}
return indent;
@@ -410,6 +410,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
electricChars: "}",
blockCommentStart: "/*",
blockCommentEnd: "*/",
+ blockCommentContinue: " * ",
lineComment: lineComment,
fold: "brace"
};
@@ -472,7 +473,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
"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", "clear", "clip", "color", "color-profile", "column-count",
+ "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",
@@ -493,7 +494,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
"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", "left", "letter-spacing",
+ "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",
@@ -508,7 +509,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
"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", "play-during", "position",
+ "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",
@@ -659,15 +660,15 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
"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",
+ "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", "spell-out", "square",
+ "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", "table",
+ "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",
@@ -748,8 +749,8 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
}
},
":": function(stream) {
- if (stream.match(/\s*\{/))
- return [null, "{"];
+ if (stream.match(/\s*\{/, false))
+ return [null, null]
return false;
},
"$": function(stream) {
diff --git a/gui/public/codemirror/mode/css/gss.html b/gui/public/codemirror/mode/css/gss.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/css/gss_test.js b/gui/public/codemirror/mode/css/gss_test.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/css/index.html b/gui/public/codemirror/mode/css/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/css/less.html b/gui/public/codemirror/mode/css/less.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/css/less_test.js b/gui/public/codemirror/mode/css/less_test.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/css/scss.html b/gui/public/codemirror/mode/css/scss.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/css/scss_test.js b/gui/public/codemirror/mode/css/scss_test.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/css/test.js b/gui/public/codemirror/mode/css/test.js
old mode 100755
new mode 100644
index 7a496fb0..6fc6e33c
--- a/gui/public/codemirror/mode/css/test.js
+++ b/gui/public/codemirror/mode/css/test.js
@@ -197,4 +197,10 @@
MT("counter-style-symbols",
"[tag ol] { [property list-style]: [atom symbols]([atom cyclic] [string \"*\"] [string \"\\2020\"] [string \"\\2021\"] [string \"\\A7\"]); }");
+
+ MT("comment-does-not-disrupt",
+ "[def @font-face] [comment /* foo */] {",
+ " [property src]: [atom url]([string x]);",
+ " [property font-family]: [variable One];",
+ "}")
})();
diff --git a/gui/public/codemirror/mode/cypher/cypher.js b/gui/public/codemirror/mode/cypher/cypher.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/cypher/index.html b/gui/public/codemirror/mode/cypher/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/cypher/test.js b/gui/public/codemirror/mode/cypher/test.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/d/d.js b/gui/public/codemirror/mode/d/d.js
old mode 100755
new mode 100644
index c927a7e3..77b09c22
--- a/gui/public/codemirror/mode/d/d.js
+++ b/gui/public/codemirror/mode/d/d.js
@@ -44,7 +44,7 @@ CodeMirror.defineMode("d", function(config, parserConfig) {
}
if (ch == "/") {
if (stream.eat("+")) {
- state.tokenize = tokenComment;
+ state.tokenize = tokenNestedComment;
return tokenNestedComment(stream, state);
}
if (stream.eat("*")) {
diff --git a/gui/public/codemirror/mode/d/index.html b/gui/public/codemirror/mode/d/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/d/test.js b/gui/public/codemirror/mode/d/test.js
new file mode 100644
index 00000000..d8de4ad3
--- /dev/null
+++ b/gui/public/codemirror/mode/d/test.js
@@ -0,0 +1,11 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: http://codemirror.net/LICENSE
+
+(function() {
+ var mode = CodeMirror.getMode({indentUnit: 2}, "d");
+ function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }
+
+ MT("nested_comments",
+ "[comment /+]","[comment comment]","[comment +/]","[variable void] [variable main](){}");
+
+})();
diff --git a/gui/public/codemirror/mode/dart/dart.js b/gui/public/codemirror/mode/dart/dart.js
old mode 100755
new mode 100644
index 8d383a95..4db0d371
--- a/gui/public/codemirror/mode/dart/dart.js
+++ b/gui/public/codemirror/mode/dart/dart.js
@@ -12,8 +12,8 @@
"use strict";
var keywords = ("this super static final const abstract class extends external factory " +
- "implements get native operator set typedef with enum throw rethrow " +
- "assert break case continue default in return new deferred async await " +
+ "implements get native set typedef with enum throw rethrow " +
+ "assert break case continue default in return new deferred async await covariant " +
"try catch finally do else for if switch while import library export " +
"part of show hide is as").split(" ");
var blockKeywords = "try catch finally do else for if switch while".split(" ");
diff --git a/gui/public/codemirror/mode/dart/index.html b/gui/public/codemirror/mode/dart/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/diff/diff.js b/gui/public/codemirror/mode/diff/diff.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/diff/index.html b/gui/public/codemirror/mode/diff/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/django/django.js b/gui/public/codemirror/mode/django/django.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/django/index.html b/gui/public/codemirror/mode/django/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/dtd/dtd.js b/gui/public/codemirror/mode/dtd/dtd.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/dtd/index.html b/gui/public/codemirror/mode/dtd/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/dylan/dylan.js b/gui/public/codemirror/mode/dylan/dylan.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/dylan/index.html b/gui/public/codemirror/mode/dylan/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/dylan/test.js b/gui/public/codemirror/mode/dylan/test.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/ebnf/ebnf.js b/gui/public/codemirror/mode/ebnf/ebnf.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/ebnf/index.html b/gui/public/codemirror/mode/ebnf/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/ecl/ecl.js b/gui/public/codemirror/mode/ecl/ecl.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/ecl/index.html b/gui/public/codemirror/mode/ecl/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/eiffel/eiffel.js b/gui/public/codemirror/mode/eiffel/eiffel.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/eiffel/index.html b/gui/public/codemirror/mode/eiffel/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/elm/elm.js b/gui/public/codemirror/mode/elm/elm.js
old mode 100755
new mode 100644
index b31e6637..9fcfc883
--- a/gui/public/codemirror/mode/elm/elm.js
+++ b/gui/public/codemirror/mode/elm/elm.js
@@ -70,7 +70,7 @@
if (smallRE.test(ch)) {
var isDef = source.pos === 1;
source.eatWhile(idRE);
- return isDef ? "variable-3" : "variable";
+ return isDef ? "type" : "variable";
}
if (digitRE.test(ch)) {
diff --git a/gui/public/codemirror/mode/elm/index.html b/gui/public/codemirror/mode/elm/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/erlang/erlang.js b/gui/public/codemirror/mode/erlang/erlang.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/erlang/index.html b/gui/public/codemirror/mode/erlang/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/factor/factor.js b/gui/public/codemirror/mode/factor/factor.js
old mode 100755
new mode 100644
index 86d7adf6..e238c5ea
--- a/gui/public/codemirror/mode/factor/factor.js
+++ b/gui/public/codemirror/mode/factor/factor.js
@@ -22,52 +22,54 @@
{regex: /#?!.*/, token: "comment"},
// strings """, multiline --> state
{regex: /"""/, token: "string", next: "string3"},
- {regex: /"/, token: "string", next: "string"},
+ {regex: /(STRING:)(\s)/, token: ["keyword", null], next: "string2"},
+ {regex: /\S*?"/, token: "string", next: "string"},
// numbers: dec, hex, unicode, bin, fractional, complex
- {regex: /(?:[+-]?)(?:0x[\d,a-f]+)|(?:0o[0-7]+)|(?:0b[0,1]+)|(?:\d+.?\d*)/, token: "number"},
+ {regex: /(?:0x[\d,a-f]+)|(?:0o[0-7]+)|(?:0b[0,1]+)|(?:\-?\d+.?\d*)(?=\s)/, token: "number"},
//{regex: /[+-]?/} //fractional
// definition: defining word, defined word, etc
- {regex: /(\:)(\s+)(\S+)(\s+)(\()/, token: ["keyword", null, "def", null, "keyword"], next: "stack"},
+ {regex: /((?:GENERIC)|\:?\:)(\s+)(\S+)(\s+)(\()/, token: ["keyword", null, "def", null, "bracket"], next: "stack"},
+ // method definition: defining word, type, defined word, etc
+ {regex: /(M\:)(\s+)(\S+)(\s+)(\S+)/, token: ["keyword", null, "def", null, "tag"]},
// vocabulary using --> state
{regex: /USING\:/, token: "keyword", next: "vocabulary"},
// vocabulary definition/use
- {regex: /(USE\:|IN\:)(\s+)(\S+)/, token: ["keyword", null, "variable-2"]},
- //
- {regex: /<\S+>/, token: "builtin"},
+ {regex: /(USE\:|IN\:)(\s+)(\S+)(?=\s|$)/, token: ["keyword", null, "tag"]},
+ // definition: a defining word, defined word
+ {regex: /(\S+\:)(\s+)(\S+)(?=\s|$)/, token: ["keyword", null, "def"]},
// "keywords", incl. ; t f . [ ] { } defining words
- {regex: /;|t|f|if|\.|\[|\]|\{|\}|MAIN:/, token: "keyword"},
+ {regex: /(?:;|\\|t|f|if|loop|while|until|do|PRIVATE>| and the like
+ {regex: /\S+[\)>\.\*\?]+(?=\s|$)/, token: "builtin"},
+ {regex: /[\)><]+\S+(?=\s|$)/, token: "builtin"},
+ // operators
+ {regex: /(?:[\+\-\=\/\*<>])(?=\s|$)/, token: "keyword"},
// any id (?)
{regex: /\S+/, token: "variable"},
-
- {
- regex: /./,
- token: null
- }
+ {regex: /\s+|./, token: null}
],
vocabulary: [
{regex: /;/, token: "keyword", next: "start"},
- {regex: /\S+/, token: "variable-2"},
- {
- regex: /./,
- token: null
- }
+ {regex: /\S+/, token: "tag"},
+ {regex: /\s+|./, token: null}
],
string: [
{regex: /(?:[^\\]|\\.)*?"/, token: "string", next: "start"},
{regex: /.*/, token: "string"}
],
+ string2: [
+ {regex: /^;/, token: "keyword", next: "start"},
+ {regex: /.*/, token: "string"}
+ ],
string3: [
{regex: /(?:[^\\]|\\.)*?"""/, token: "string", next: "start"},
{regex: /.*/, token: "string"}
],
stack: [
- {regex: /\)/, token: "meta", next: "start"},
- {regex: /--/, token: "meta"},
- {regex: /\S+/, token: "variable-3"},
- {
- regex: /./,
- token: null
- }
+ {regex: /\)/, token: "bracket", next: "start"},
+ {regex: /--/, token: "bracket"},
+ {regex: /\S+/, token: "meta"},
+ {regex: /\s+|./, token: null}
],
// The meta property contains global information about the mode. It
// can contain properties like lineComment, which are supported by
diff --git a/gui/public/codemirror/mode/factor/index.html b/gui/public/codemirror/mode/factor/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/fcl/fcl.js b/gui/public/codemirror/mode/fcl/fcl.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/fcl/index.html b/gui/public/codemirror/mode/fcl/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/forth/forth.js b/gui/public/codemirror/mode/forth/forth.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/forth/index.html b/gui/public/codemirror/mode/forth/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/fortran/fortran.js b/gui/public/codemirror/mode/fortran/fortran.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/fortran/index.html b/gui/public/codemirror/mode/fortran/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/gas/gas.js b/gui/public/codemirror/mode/gas/gas.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/gas/index.html b/gui/public/codemirror/mode/gas/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/gfm/gfm.js b/gui/public/codemirror/mode/gfm/gfm.js
old mode 100755
new mode 100644
index 6e74ad4f..471ae906
--- a/gui/public/codemirror/mode/gfm/gfm.js
+++ b/gui/public/codemirror/mode/gfm/gfm.js
@@ -81,7 +81,7 @@ CodeMirror.defineMode("gfm", function(config, modeConfig) {
if (stream.sol() || state.ateSpace) {
state.ateSpace = false;
if (modeConfig.gitHubSpice !== false) {
- if(stream.match(/^(?:[a-zA-Z0-9\-_]+\/)?(?:[a-zA-Z0-9\-_]+@)?(?:[a-f0-9]{7,40}\b)/)) {
+ if(stream.match(/^(?:[a-zA-Z0-9\-_]+\/)?(?:[a-zA-Z0-9\-_]+@)?(?=.{0,6}\d)(?:[a-f0-9]{7,40}\b)/)) {
// User/Project@SHA
// User@SHA
// SHA
@@ -113,10 +113,9 @@ CodeMirror.defineMode("gfm", function(config, modeConfig) {
};
var markdownConfig = {
- underscoresBreakWords: false,
taskLists: true,
- fencedCodeBlocks: '```',
- strikethrough: true
+ strikethrough: true,
+ emoji: true
};
for (var attr in modeConfig) {
markdownConfig[attr] = modeConfig[attr];
diff --git a/gui/public/codemirror/mode/gfm/index.html b/gui/public/codemirror/mode/gfm/index.html
old mode 100755
new mode 100644
index 24c90c06..ea4bac15
--- a/gui/public/codemirror/mode/gfm/index.html
+++ b/gui/public/codemirror/mode/gfm/index.html
@@ -15,7 +15,10 @@
-
+
CodeMirror

@@ -67,6 +70,10 @@ for (var i = 0; i < items.length; i++) {
## A bit of GitHub spice
+See http://github.github.com/github-flavored-markdown/.
+
+(Set `gitHubSpice: false` in mode options to disable):
+
* SHA: be6a8cc1c1ecfe9489fb51e4869af15a13fc2cd2
* User@SHA ref: mojombo@be6a8cc1c1ecfe9489fb51e4869af15a13fc2cd2
* User/Project@SHA: mojombo/god@be6a8cc1c1ecfe9489fb51e4869af15a13fc2cd2
@@ -74,13 +81,21 @@ for (var i = 0; i < items.length; i++) {
* User/#Num: mojombo#1
* User/Project#Num: mojombo/god#1
-See http://github.github.com/github-flavored-markdown/.
+(Set `emoji: false` in mode options to disable):
+
+* emoji: :smile:
+
-
You might want to use the Github-Flavored Markdown mode instead, which adds support for fenced code blocks and a few other things.
+
If you also want support strikethrough
, emoji
and few other goodies, check out Github-Flavored Markdown mode.
+
+
Optionally depends on other modes for properly highlighted code blocks,
+ and XML mode for properly highlighted inline XML blocks.
+
+
Markdown mode supports these options:
+
+ -
+
+
highlightFormatting: boolean
+ - Whether to separately highlight markdown meta characterts (
*[]()
etc.) (default: false
).
+
+
+ -
+
+
maxBlockquoteDepth: boolean
+ - Maximum allowed blockquote nesting (default:
0
- infinite nesting).
+
+
+ -
+
+
xml: boolean
+ - Whether to highlight inline XML (default:
true
).
+
+
+ -
+
+
fencedCodeBlockHighlighting: boolean
+ - Whether to syntax-highlight fenced code blocks, if given mode is included (default:
true
).
+
+
+ -
+
+
tokenTypeOverrides: Object
+ - When you want ot override default token type names (e.g.
{code: "code"}
).
+
+
+ -
+
+
allowAtxHeaderWithoutSpace: boolean
+ - Allow lazy headers without whitespace between hashtag and text (default:
false
).
+
+
+
-
Optionally depends on the XML mode for properly highlighted inline XML blocks.
-
MIME types defined: text/x-markdown
.
Parsing/Highlighting Tests: normal, verbose.
diff --git a/gui/public/codemirror/mode/markdown/markdown.js b/gui/public/codemirror/mode/markdown/markdown.js
old mode 100755
new mode 100644
index 4ba57e44..b2f79fc3
--- a/gui/public/codemirror/mode/markdown/markdown.js
+++ b/gui/public/codemirror/mode/markdown/markdown.js
@@ -35,15 +35,6 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
if (modeCfg.maxBlockquoteDepth === undefined)
modeCfg.maxBlockquoteDepth = 0;
- // Should underscores in words open/close em/strong?
- if (modeCfg.underscoresBreakWords === undefined)
- modeCfg.underscoresBreakWords = true;
-
- // Use `fencedCodeBlocks` to configure fenced code blocks. false to
- // disable, string to specify a precise regexp that the fence should
- // match, and true to allow three or more backticks or tildes (as
- // per CommonMark).
-
// Turn on task lists? ("- [ ] " and "- [x] ")
if (modeCfg.taskLists === undefined) modeCfg.taskLists = false;
@@ -51,6 +42,15 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
if (modeCfg.strikethrough === undefined)
modeCfg.strikethrough = false;
+ if (modeCfg.emoji === undefined)
+ modeCfg.emoji = false;
+
+ if (modeCfg.fencedCodeBlockHighlighting === undefined)
+ modeCfg.fencedCodeBlockHighlighting = true;
+
+ if (modeCfg.xml === undefined)
+ modeCfg.xml = true;
+
// Allow token types to be overridden by user-provided token types.
if (modeCfg.tokenTypeOverrides === undefined)
modeCfg.tokenTypeOverrides = {};
@@ -73,7 +73,8 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
linkHref: "string",
em: "em",
strong: "strong",
- strikethrough: "strikethrough"
+ strikethrough: "strikethrough",
+ emoji: "builtin"
};
for (var tokenType in tokenTypes) {
@@ -84,12 +85,14 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
var hrRE = /^([*\-_])(?:\s*\1){2,}\s*$/
, listRE = /^(?:[*\-+]|^[0-9]+([.)]))\s+/
- , taskListRE = /^\[(x| )\](?=\s)/ // Must follow listRE
+ , taskListRE = /^\[(x| )\](?=\s)/i // Must follow listRE
, atxHeaderRE = modeCfg.allowAtxHeaderWithoutSpace ? /^(#+)/ : /^(#+)(?: |$)/
, setextHeaderRE = /^ *(?:\={1,}|-{1,})\s*$/
- , textRE = /^[^#!\[\]*_\\<>` "'(~]+/
- , fencedCodeRE = new RegExp("^(" + (modeCfg.fencedCodeBlocks === true ? "~~~+|```+" : modeCfg.fencedCodeBlocks) +
- ")[ \\t]*([\\w+#\-]*)");
+ , textRE = /^[^#!\[\]*_\\<>` "'(~:]+/
+ , fencedCodeRE = /^(~~~+|```+)[ \t]*([\w+#-]*)[^\n`]*$/
+ , linkDefRE = /^\s*\[[^\]]+?\]:\s*\S+(\s*\S*\s*)?$/ // naive link-definition
+ , punctuation = /[!\"#$%&\'()*+,\-\.\/:;<=>?@\[\\\]^_`{|}~—]/
+ , expandedTab = " " // CommonMark specifies tab as 4 spaces
function switchInline(stream, state, f) {
state.f = state.inline = f;
@@ -120,7 +123,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
state.quote = 0;
// Reset state.indentedCode
state.indentedCode = false;
- if (htmlModeMissing && state.f == htmlBlock) {
+ if (state.f == htmlBlock) {
state.f = inlineNormal;
state.block = blockNormal;
}
@@ -129,76 +132,80 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
state.trailingSpaceNewLine = false;
// Mark this line as blank
state.prevLine = state.thisLine
- state.thisLine = null
+ state.thisLine = {stream: null}
return null;
}
function blockNormal(stream, state) {
-
- var sol = stream.sol();
-
- var prevLineIsList = state.list !== false,
- prevLineIsIndentedCode = state.indentedCode;
+ var firstTokenOnLine = stream.column() === state.indentation;
+ var prevLineLineIsEmpty = lineIsEmpty(state.prevLine.stream);
+ var prevLineIsIndentedCode = state.indentedCode;
+ var prevLineIsHr = state.prevLine.hr;
+ var prevLineIsList = state.list !== false;
+ var maxNonCodeIndentation = (state.listStack[state.listStack.length - 1] || 0) + 3;
state.indentedCode = false;
- if (prevLineIsList) {
- if (state.indentationDiff >= 0) { // Continued list
- if (state.indentationDiff < 4) { // Only adjust indentation if *not* a code block
- state.indentation -= state.indentationDiff;
+ var lineIndentation = state.indentation;
+ // compute once per line (on first token)
+ if (state.indentationDiff === null) {
+ state.indentationDiff = state.indentation;
+ if (prevLineIsList) {
+ state.list = null;
+ // While this list item's marker's indentation is less than the deepest
+ // list item's content's indentation,pop the deepest list item
+ // indentation off the stack, and update block indentation state
+ while (lineIndentation < state.listStack[state.listStack.length - 1]) {
+ state.listStack.pop();
+ if (state.listStack.length) {
+ state.indentation = state.listStack[state.listStack.length - 1];
+ // less than the first list's indent -> the line is no longer a list
+ } else {
+ state.list = false;
+ }
+ }
+ if (state.list !== false) {
+ state.indentationDiff = lineIndentation - state.listStack[state.listStack.length - 1]
}
- state.list = null;
- } else if (state.indentation > 0) {
- state.list = null;
- } else { // No longer a list
- state.list = false;
}
}
+ // not comprehensive (currently only for setext detection purposes)
+ var allowsInlineContinuation = (
+ !prevLineLineIsEmpty && !prevLineIsHr && !state.prevLine.header &&
+ (!prevLineIsList || !prevLineIsIndentedCode) &&
+ !state.prevLine.fencedCodeEnd
+ );
+
+ var isHr = (state.list === false || prevLineIsHr || prevLineLineIsEmpty) &&
+ state.indentation <= maxNonCodeIndentation && stream.match(hrRE);
+
var match = null;
- if (state.indentationDiff >= 4) {
+ if (state.indentationDiff >= 4 && (prevLineIsIndentedCode || state.prevLine.fencedCodeEnd ||
+ state.prevLine.header || prevLineLineIsEmpty)) {
stream.skipToEnd();
- if (prevLineIsIndentedCode || lineIsEmpty(state.prevLine)) {
- state.indentation -= 4;
- state.indentedCode = true;
- return tokenTypes.code;
- } else {
- return null;
- }
+ state.indentedCode = true;
+ return tokenTypes.code;
} else if (stream.eatSpace()) {
return null;
- } else if ((match = stream.match(atxHeaderRE)) && match[1].length <= 6) {
+ } else if (firstTokenOnLine && state.indentation <= maxNonCodeIndentation && (match = stream.match(atxHeaderRE)) && match[1].length <= 6) {
+ state.quote = 0;
state.header = match[1].length;
+ state.thisLine.header = true;
if (modeCfg.highlightFormatting) state.formatting = "header";
state.f = state.inline;
return getType(state);
- } else if (!lineIsEmpty(state.prevLine) && !state.quote && !prevLineIsList &&
- !prevLineIsIndentedCode && (match = stream.match(setextHeaderRE))) {
- state.header = match[0].charAt(0) == '=' ? 1 : 2;
- if (modeCfg.highlightFormatting) state.formatting = "header";
- state.f = state.inline;
- return getType(state);
- } else if (stream.eat('>')) {
- state.quote = sol ? 1 : state.quote + 1;
+ } else if (state.indentation <= maxNonCodeIndentation && stream.eat('>')) {
+ state.quote = firstTokenOnLine ? 1 : state.quote + 1;
if (modeCfg.highlightFormatting) state.formatting = "quote";
stream.eatSpace();
return getType(state);
- } else if (stream.peek() === '[') {
- return switchInline(stream, state, footnoteLink);
- } else if (stream.match(hrRE, true)) {
- state.hr = true;
- return tokenTypes.hr;
- } else if (match = stream.match(listRE)) {
+ } else if (!isHr && !state.setext && firstTokenOnLine && state.indentation <= maxNonCodeIndentation && (match = stream.match(listRE))) {
var listType = match[1] ? "ol" : "ul";
- state.indentation = stream.column() + stream.current().length;
- state.list = true;
- // While this list item's marker's indentation
- // is less than the deepest list item's content's indentation,
- // pop the deepest list item indentation off the stack.
- while (state.listStack && stream.column() < state.listStack[state.listStack.length - 1]) {
- state.listStack.pop();
- }
+ state.indentation = lineIndentation + stream.current().length;
+ state.list = true;
+ state.quote = 0;
// Add this list item's content's indentation to the stack
state.listStack.push(state.indentation);
@@ -209,15 +216,47 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
state.f = state.inline;
if (modeCfg.highlightFormatting) state.formatting = ["list", "list-" + listType];
return getType(state);
- } else if (modeCfg.fencedCodeBlocks && (match = stream.match(fencedCodeRE, true))) {
- state.fencedChars = match[1]
+ } else if (firstTokenOnLine && state.indentation <= maxNonCodeIndentation && (match = stream.match(fencedCodeRE, true))) {
+ state.quote = 0;
+ state.fencedEndRE = new RegExp(match[1] + "+ *$");
// try switching mode
- state.localMode = getMode(match[2]);
+ state.localMode = modeCfg.fencedCodeBlockHighlighting && getMode(match[2]);
if (state.localMode) state.localState = CodeMirror.startState(state.localMode);
state.f = state.block = local;
if (modeCfg.highlightFormatting) state.formatting = "code-block";
state.code = -1
return getType(state);
+ // SETEXT has lowest block-scope precedence after HR, so check it after
+ // the others (code, blockquote, list...)
+ } else if (
+ // if setext set, indicates line after ---/===
+ state.setext || (
+ // line before ---/===
+ (!allowsInlineContinuation || !prevLineIsList) && !state.quote && state.list === false &&
+ !state.code && !isHr && !linkDefRE.test(stream.string) &&
+ (match = stream.lookAhead(1)) && (match = match.match(setextHeaderRE))
+ )
+ ) {
+ if ( !state.setext ) {
+ state.header = match[0].charAt(0) == '=' ? 1 : 2;
+ state.setext = state.header;
+ } else {
+ state.header = state.setext;
+ // has no effect on type so we can reset it now
+ state.setext = 0;
+ stream.skipToEnd();
+ if (modeCfg.highlightFormatting) state.formatting = "header";
+ }
+ state.thisLine.header = true;
+ state.f = state.inline;
+ return getType(state);
+ } else if (isHr) {
+ stream.skipToEnd();
+ state.hr = true;
+ state.thisLine.hr = true;
+ return tokenTypes.hr;
+ } else if (stream.peek() === '[') {
+ return switchInline(stream, state, footnoteLink);
}
return switchInline(stream, state, state.inline);
@@ -239,13 +278,21 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
}
function local(stream, state) {
- if (state.fencedChars && stream.match(state.fencedChars)) {
+ var currListInd = state.listStack[state.listStack.length - 1] || 0;
+ var hasExitedList = state.indentation < currListInd;
+ var maxFencedEndInd = currListInd + 3;
+ if (state.fencedEndRE && state.indentation <= maxFencedEndInd && (hasExitedList || stream.match(state.fencedEndRE))) {
if (modeCfg.highlightFormatting) state.formatting = "code-block";
+ var returnType;
+ if (!hasExitedList) returnType = getType(state)
state.localMode = state.localState = null;
- state.f = state.block = leavingLocal;
- return getType(state)
- } else if (state.fencedChars && stream.skipTo(state.fencedChars)) {
- return "comment"
+ state.block = blockNormal;
+ state.f = inlineNormal;
+ state.fencedEndRE = null;
+ state.code = 0
+ state.thisLine.fencedCodeEnd = true;
+ if (hasExitedList) return switchBlock(stream, state, state.block);
+ return returnType;
} else if (state.localMode) {
return state.localMode.token(stream, state.localState);
} else {
@@ -254,18 +301,6 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
}
}
- function leavingLocal(stream, state) {
- stream.match(state.fencedChars);
- state.block = blockNormal;
- state.f = inlineNormal;
- state.fencedChars = null;
- if (modeCfg.highlightFormatting) state.formatting = "code-block";
- state.code = 1
- var returnType = getType(state);
- state.code = 0
- return returnType;
- }
-
// Inline
function getType(state) {
var styles = [];
@@ -309,6 +344,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
if (state.strong) { styles.push(tokenTypes.strong); }
if (state.em) { styles.push(tokenTypes.em); }
if (state.strikethrough) { styles.push(tokenTypes.strikethrough); }
+ if (state.emoji) { styles.push(tokenTypes.emoji); }
if (state.linkText) { styles.push(tokenTypes.linkText); }
if (state.code) { styles.push(tokenTypes.code); }
if (state.image) { styles.push(tokenTypes.image); }
@@ -367,7 +403,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
}
if (state.taskList) {
- var taskOpen = stream.match(taskListRE, true)[1] !== "x";
+ var taskOpen = stream.match(taskListRE, true)[1] === " ";
if (taskOpen) state.taskOpen = true;
else state.taskClosed = true;
if (modeCfg.highlightFormatting) state.formatting = "task";
@@ -383,9 +419,6 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
return getType(state);
}
- // Get sol() value now, before character is consumed
- var sol = stream.sol();
-
var ch = stream.next();
// Matches link titles present on next line
@@ -395,7 +428,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
if (ch === '(') {
matchCh = ')';
}
- matchCh = (matchCh+'').replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
+ matchCh = (matchCh+'').replace(/([.?*+^\[\]\\(){}|-])/g, "\\$1");
var regex = '^\\s*(?:[^' + matchCh + '\\\\]+|\\\\\\\\|\\\\.)' + matchCh;
if (stream.match(new RegExp(regex), true)) {
return tokenTypes.linkHref;
@@ -408,7 +441,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
if (modeCfg.highlightFormatting) state.formatting = "code";
stream.eatWhile('`');
var count = stream.current().length
- if (state.code == 0) {
+ if (state.code == 0 && (!state.quote || count == 1)) {
state.code = count
return getType(state)
} else if (count == state.code) { // Must be exact
@@ -455,17 +488,17 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
return type;
}
- if (ch === '[' && stream.match(/[^\]]*\](\(.*\)| ?\[.*?\])/, false) && !state.image) {
+ if (ch === '[' && !state.image) {
state.linkText = true;
if (modeCfg.highlightFormatting) state.formatting = "link";
return getType(state);
}
- if (ch === ']' && state.linkText && stream.match(/\(.*?\)| ?\[.*?\]/, false)) {
+ if (ch === ']' && state.linkText) {
if (modeCfg.highlightFormatting) state.formatting = "link";
var type = getType(state);
state.linkText = false;
- state.inline = state.f = linkHref;
+ state.inline = state.f = stream.match(/\(.*?\)| ?\[.*?\]/, false) ? linkHref : inlineNormal
return type;
}
@@ -493,7 +526,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
return type + tokenTypes.linkEmail;
}
- if (ch === '<' && stream.match(/^(!--|[a-z]+(?:\s+[a-z_:.\-]+(?:\s*=\s*[^ >]+)?)*\s*>)/i, false)) {
+ if (modeCfg.xml && ch === '<' && stream.match(/^(!--|[a-z]+(?:\s+[a-z_:.\-]+(?:\s*=\s*[^ >]+)?)*\s*>)/i, false)) {
var end = stream.string.indexOf(">", stream.pos);
if (end != -1) {
var atts = stream.string.substring(stream.start, end);
@@ -504,44 +537,37 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
return switchBlock(stream, state, htmlBlock);
}
- if (ch === '<' && stream.match(/^\/\w*?>/)) {
+ if (modeCfg.xml && ch === '<' && stream.match(/^\/\w*?>/)) {
state.md_inside = false;
return "tag";
- }
-
- var ignoreUnderscore = false;
- if (!modeCfg.underscoresBreakWords) {
- if (ch === '_' && stream.peek() !== '_' && stream.match(/(\w)/, false)) {
- var prevPos = stream.pos - 2;
- if (prevPos >= 0) {
- var prevCh = stream.string.charAt(prevPos);
- if (prevCh !== '_' && prevCh.match(/(\w)/, false)) {
- ignoreUnderscore = true;
- }
- }
+ } else if (ch === "*" || ch === "_") {
+ var len = 1, before = stream.pos == 1 ? " " : stream.string.charAt(stream.pos - 2)
+ while (len < 3 && stream.eat(ch)) len++
+ var after = stream.peek() || " "
+ // See http://spec.commonmark.org/0.27/#emphasis-and-strong-emphasis
+ var leftFlanking = !/\s/.test(after) && (!punctuation.test(after) || /\s/.test(before) || punctuation.test(before))
+ var rightFlanking = !/\s/.test(before) && (!punctuation.test(before) || /\s/.test(after) || punctuation.test(after))
+ var setEm = null, setStrong = null
+ if (len % 2) { // Em
+ if (!state.em && leftFlanking && (ch === "*" || !rightFlanking || punctuation.test(before)))
+ setEm = true
+ else if (state.em == ch && rightFlanking && (ch === "*" || !leftFlanking || punctuation.test(after)))
+ setEm = false
}
- }
- if (ch === '*' || (ch === '_' && !ignoreUnderscore)) {
- if (sol && stream.peek() === ' ') {
- // Do nothing, surrounded by newline and space
- } else if (state.strong === ch && stream.eat(ch)) { // Remove STRONG
- if (modeCfg.highlightFormatting) state.formatting = "strong";
- var t = getType(state);
- state.strong = false;
- return t;
- } else if (!state.strong && stream.eat(ch)) { // Add STRONG
- state.strong = ch;
- if (modeCfg.highlightFormatting) state.formatting = "strong";
- return getType(state);
- } else if (state.em === ch) { // Remove EM
- if (modeCfg.highlightFormatting) state.formatting = "em";
- var t = getType(state);
- state.em = false;
- return t;
- } else if (!state.em) { // Add EM
- state.em = ch;
- if (modeCfg.highlightFormatting) state.formatting = "em";
- return getType(state);
+ if (len > 1) { // Strong
+ if (!state.strong && leftFlanking && (ch === "*" || !rightFlanking || punctuation.test(before)))
+ setStrong = true
+ else if (state.strong == ch && rightFlanking && (ch === "*" || !leftFlanking || punctuation.test(after)))
+ setStrong = false
+ }
+ if (setStrong != null || setEm != null) {
+ if (modeCfg.highlightFormatting) state.formatting = setEm == null ? "strong" : setStrong == null ? "em" : "strong em"
+ if (setEm === true) state.em = ch
+ if (setStrong === true) state.strong = ch
+ var t = getType(state)
+ if (setEm === false) state.em = false
+ if (setStrong === false) state.strong = false
+ return t
}
} else if (ch === ' ') {
if (stream.eat('*') || stream.eat('_')) { // Probably surrounded by spaces
@@ -576,6 +602,14 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
}
}
+ if (modeCfg.emoji && ch === ":" && stream.match(/^[a-z_\d+-]+:/)) {
+ state.emoji = true;
+ if (modeCfg.highlightFormatting) state.formatting = "emoji";
+ var retType = getType(state);
+ state.emoji = false;
+ return retType;
+ }
+
if (ch === ' ') {
if (stream.match(/ +$/, false)) {
state.trailingSpace++;
@@ -614,7 +648,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
}
var ch = stream.next();
if (ch === '(' || ch === '[') {
- state.f = state.inline = getLinkHrefInside(ch === "(" ? ")" : "]", 0);
+ state.f = state.inline = getLinkHrefInside(ch === "(" ? ")" : "]");
if (modeCfg.highlightFormatting) state.formatting = "link-string";
state.linkHref = true;
return getType(state);
@@ -624,7 +658,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
var linkRE = {
")": /^(?:[^\\\(\)]|\\.|\((?:[^\\\(\)]|\\.)*\))*?(?=\))/,
- "]": /^(?:[^\\\[\]]|\\.|\[(?:[^\\\[\\]]|\\.)*\])*?(?=\])/
+ "]": /^(?:[^\\\[\]]|\\.|\[(?:[^\\\[\]]|\\.)*\])*?(?=\])/
}
function getLinkHrefInside(endChar) {
@@ -692,8 +726,8 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
return {
f: blockNormal,
- prevLine: null,
- thisLine: null,
+ prevLine: {stream: null},
+ thisLine: {stream: null},
block: blockNormal,
htmlState: null,
@@ -710,6 +744,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
em: false,
strong: false,
header: 0,
+ setext: 0,
hr: false,
taskList: false,
list: false,
@@ -718,7 +753,8 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
trailingSpace: 0,
trailingSpaceNewLine: false,
strikethrough: false,
- fencedChars: null
+ emoji: false,
+ fencedEndRE: null
};
},
@@ -739,12 +775,15 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
inline: s.inline,
text: s.text,
formatting: false,
+ linkText: s.linkText,
linkTitle: s.linkTitle,
code: s.code,
em: s.em,
strong: s.strong,
strikethrough: s.strikethrough,
+ emoji: s.emoji,
header: s.header,
+ setext: s.setext,
hr: s.hr,
taskList: s.taskList,
list: s.list,
@@ -754,7 +793,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
trailingSpace: s.trailingSpace,
trailingSpaceNewLine: s.trailingSpaceNewLine,
md_inside: s.md_inside,
- fencedChars: s.fencedChars
+ fencedEndRE: s.fencedEndRE
};
},
@@ -763,21 +802,17 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
// Reset state.formatting
state.formatting = false;
- if (stream != state.thisLine) {
- var forceBlankLine = state.header || state.hr;
-
- // Reset state.header and state.hr
+ if (stream != state.thisLine.stream) {
state.header = 0;
state.hr = false;
- if (stream.match(/^\s*$/, true) || forceBlankLine) {
+ if (stream.match(/^\s*$/, true)) {
blankLine(state);
- if (!forceBlankLine) return null
- state.prevLine = null
+ return null;
}
state.prevLine = state.thisLine
- state.thisLine = stream
+ state.thisLine = {stream: stream}
// Reset state.taskList
state.taskList = false;
@@ -786,11 +821,15 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
state.trailingSpace = 0;
state.trailingSpaceNewLine = false;
- state.f = state.block;
- var indentation = stream.match(/^\s*/, true)[0].replace(/\t/g, ' ').length;
- state.indentationDiff = Math.min(indentation - state.indentation, 4);
- state.indentation = state.indentation + state.indentationDiff;
- if (indentation > 0) return null;
+ if (!state.localState) {
+ state.f = state.block;
+ if (state.f != htmlBlock) {
+ var indentation = stream.match(/^\s*/, true)[0].replace(/\t/g, expandedTab).length;
+ state.indentation = indentation;
+ state.indentationDiff = null;
+ if (indentation > 0) return null;
+ }
+ }
}
return state.f(stream, state);
},
@@ -801,6 +840,12 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
return {state: state, mode: mode};
},
+ indent: function(state, textAfter, line) {
+ if (state.block == htmlBlock && htmlMode.indent) return htmlMode.indent(state.htmlState, textAfter, line)
+ if (state.localState && state.localMode.indent) return state.localMode.indent(state.localState, textAfter, line)
+ return CodeMirror.Pass
+ },
+
blankLine: blankLine,
getType: getType,
diff --git a/gui/public/codemirror/mode/markdown/test.js b/gui/public/codemirror/mode/markdown/test.js
old mode 100755
new mode 100644
index 37ecb4bb..a89fbca6
--- a/gui/public/codemirror/mode/markdown/test.js
+++ b/gui/public/codemirror/mode/markdown/test.js
@@ -2,17 +2,21 @@
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function() {
- var mode = CodeMirror.getMode({tabSize: 4}, "markdown");
+ var config = {tabSize: 4, indentUnit: 2}
+ var mode = CodeMirror.getMode(config, "markdown");
function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }
- var modeHighlightFormatting = CodeMirror.getMode({tabSize: 4}, {name: "markdown", highlightFormatting: true});
+ var modeHighlightFormatting = CodeMirror.getMode(config, {name: "markdown", highlightFormatting: true});
function FT(name) { test.mode(name, modeHighlightFormatting, Array.prototype.slice.call(arguments, 1)); }
- var modeAtxNoSpace = CodeMirror.getMode({tabSize: 4}, {name: "markdown", allowAtxHeaderWithoutSpace: true});
+ var modeMT_noXml = CodeMirror.getMode(config, {name: "markdown", xml: false});
+ function MT_noXml(name) { test.mode(name, modeMT_noXml, Array.prototype.slice.call(arguments, 1)); }
+ var modeMT_noFencedHighlight = CodeMirror.getMode(config, {name: "markdown", fencedCodeBlockHighlighting: false});
+ function MT_noFencedHighlight(name) { test.mode(name, modeMT_noFencedHighlight, Array.prototype.slice.call(arguments, 1)); }
+ var modeAtxNoSpace = CodeMirror.getMode(config, {name: "markdown", allowAtxHeaderWithoutSpace: true});
function AtxNoSpaceTest(name) { test.mode(name, modeAtxNoSpace, Array.prototype.slice.call(arguments, 1)); }
- var modeFenced = CodeMirror.getMode({tabSize: 4}, {name: "markdown", fencedCodeBlocks: true});
- function FencedTest(name) { test.mode(name, modeFenced, Array.prototype.slice.call(arguments, 1)); }
- var modeOverrideClasses = CodeMirror.getMode({tabsize: 4}, {
+ var modeOverrideClasses = CodeMirror.getMode(config, {
name: "markdown",
strikethrough: true,
+ emoji: true,
tokenTypeOverrides: {
"header" : "override-header",
"code" : "override-code",
@@ -30,10 +34,11 @@
"linkHref" : "override-link-href",
"em" : "override-em",
"strong" : "override-strong",
- "strikethrough" : "override-strikethrough"
+ "strikethrough" : "override-strikethrough",
+ "emoji" : "override-emoji"
}});
function TokenTypeOverrideTest(name) { test.mode(name, modeOverrideClasses, Array.prototype.slice.call(arguments, 1)); }
- var modeFormattingOverride = CodeMirror.getMode({tabsize: 4}, {
+ var modeFormattingOverride = CodeMirror.getMode(config, {
name: "markdown",
highlightFormatting: true,
tokenTypeOverrides: {
@@ -64,7 +69,7 @@
"[header&header-1&formatting&formatting-header&formatting-header-1 # ][header&header-1 foo # bar ][header&header-1&formatting&formatting-header&formatting-header-1 #]");
FT("formatting_setextHeader",
- "foo",
+ "[header&header-1 foo]",
"[header&header-1&formatting&formatting-header&formatting-header-1 =]");
FT("formatting_blockquote",
@@ -94,6 +99,11 @@
FT("formatting_image",
"[formatting&formatting-image&image&image-marker !][formatting&formatting-image&image&image-alt-text&link [[][image&image-alt-text&link alt text][formatting&formatting-image&image&image-alt-text&link ]]][formatting&formatting-link-string&string&url (][url&string http://link.to/image.jpg][formatting&formatting-link-string&string&url )]");
+ FT("codeBlock",
+ "[comment&formatting&formatting-code-block ```css]",
+ "[tag foo]",
+ "[comment&formatting&formatting-code-block ```]");
+
MT("plainText",
"foo");
@@ -141,6 +151,21 @@
"Foo",
" Bar");
+ MT("codeBlocksAfterATX",
+ "[header&header-1 # foo]",
+ " [comment code]");
+
+ MT("codeBlocksAfterSetext",
+ "[header&header-2 foo]",
+ "[header&header-2 ---]",
+ " [comment code]");
+
+ MT("codeBlocksAfterFencedCode",
+ "[comment ```]",
+ "[comment foo]",
+ "[comment ```]",
+ " [comment code]");
+
// Inline code using backticks
MT("inlineCodeUsingBackticks",
"foo [comment `bar`]");
@@ -182,6 +207,10 @@
MT("closedBackticks",
"[comment ``foo ``` bar` hello``] world");
+ // info string cannot contain backtick, thus should result in inline code
+ MT("closingFencedMarksOnSameLine",
+ "[comment ``` code ```] foo");
+
// atx headers
// http://daringfireball.net/projects/markdown/syntax#header
@@ -225,6 +254,19 @@
MT("atxH1inline",
"[header&header-1 # foo ][header&header-1&em *bar*]");
+ MT("atxIndentedTooMuch",
+ "[header&header-1 # foo]",
+ " [comment # bar]");
+
+ // disable atx inside blockquote until we implement proper blockquote inner mode
+ // TODO: fix to be CommonMark-compliant
+ MT("atxNestedInsideBlockquote",
+ "[quote"e-1 > # foo]");
+
+ MT("atxAfterBlockquote",
+ "[quote"e-1 > foo]",
+ "[header&header-1 # bar]");
+
// Setext headers - H1, H2
// Per documentation, "Any number of underlining =’s or -’s will work."
// http://daringfireball.net/projects/markdown/syntax#header
@@ -234,27 +276,27 @@
//
// Check if single underlining = works
MT("setextH1",
- "foo",
+ "[header&header-1 foo]",
"[header&header-1 =]");
// Check if 3+ ='s work
MT("setextH1",
- "foo",
+ "[header&header-1 foo]",
"[header&header-1 ===]");
// Check if single underlining - works
MT("setextH2",
- "foo",
+ "[header&header-2 foo]",
"[header&header-2 -]");
// Check if 3+ -'s work
MT("setextH2",
- "foo",
+ "[header&header-2 foo]",
"[header&header-2 ---]");
// http://spec.commonmark.org/0.19/#example-45
MT("setextH2AllowSpaces",
- "foo",
+ "[header&header-2 foo]",
" [header&header-2 ---- ]");
// http://spec.commonmark.org/0.19/#example-44
@@ -262,15 +304,86 @@
" [comment foo]",
"[hr ---]");
+ MT("setextAfterFencedCode",
+ "[comment ```]",
+ "[comment foo]",
+ "[comment ```]",
+ "[header&header-2 bar]",
+ "[header&header-2 ---]");
+
+ MT("setextAferATX",
+ "[header&header-1 # foo]",
+ "[header&header-2 bar]",
+ "[header&header-2 ---]");
+
// http://spec.commonmark.org/0.19/#example-51
MT("noSetextAfterQuote",
"[quote"e-1 > foo]",
+ "[hr ---]",
+ "",
+ "[quote"e-1 > foo]",
+ "[quote"e-1 bar]",
"[hr ---]");
MT("noSetextAfterList",
"[variable-2 - foo]",
"[hr ---]");
+ MT("noSetextAfterList_listContinuation",
+ "[variable-2 - foo]",
+ "bar",
+ "[hr ---]");
+
+ MT("setextAfterList_afterIndentedCode",
+ "[variable-2 - foo]",
+ "",
+ " [comment bar]",
+ "[header&header-2 baz]",
+ "[header&header-2 ---]");
+
+ MT("setextAfterList_afterFencedCodeBlocks",
+ "[variable-2 - foo]",
+ "",
+ " [comment ```]",
+ " [comment bar]",
+ " [comment ```]",
+ "[header&header-2 baz]",
+ "[header&header-2 ---]");
+
+ MT("setextAfterList_afterHeader",
+ "[variable-2 - foo]",
+ " [variable-2&header&header-1 # bar]",
+ "[header&header-2 baz]",
+ "[header&header-2 ---]");
+
+ MT("setextAfterList_afterHr",
+ "[variable-2 - foo]",
+ "",
+ " [hr ---]",
+ "[header&header-2 bar]",
+ "[header&header-2 ---]");
+
+ MT("setext_nestedInlineMarkup",
+ "[header&header-1 foo ][em&header&header-1 *bar*]",
+ "[header&header-1 =]");
+
+ MT("setext_linkDef",
+ "[link [[aaa]]:] [string&url http://google.com 'title']",
+ "[hr ---]");
+
+ // currently, looks max one line ahead, thus won't catch valid CommonMark
+ // markup
+ MT("setext_oneLineLookahead",
+ "foo",
+ "[header&header-1 bar]",
+ "[header&header-1 =]");
+
+ // ensure we don't regard space after dash as a list
+ MT("setext_emptyList",
+ "[header&header-2 foo]",
+ "[header&header-2 - ]",
+ "foo");
+
// Single-line blockquote with trailing space
MT("blockquoteSpace",
"[quote"e-1 > foo]");
@@ -284,12 +397,22 @@
"foo",
"[quote"e-1 > bar]");
- // Nested blockquote
- MT("blockquoteSpace",
+ MT("blockquoteNested",
"[quote"e-1 > foo]",
"[quote"e-1 >][quote"e-2 > foo]",
"[quote"e-1 >][quote"e-2 >][quote"e-3 > foo]");
+ // ensure quote-level is inferred correctly even if indented
+ MT("blockquoteNestedIndented",
+ " [quote"e-1 > foo]",
+ " [quote"e-1 >][quote"e-2 > foo]",
+ " [quote"e-1 >][quote"e-2 >][quote"e-3 > foo]");
+
+ // ensure quote-level is inferred correctly even if indented
+ MT("blockquoteIndentedTooMuch",
+ "foo",
+ " > bar");
+
// Single-line blockquote followed by normal paragraph
MT("blockquoteThenParagraph",
"[quote"e-1 >foo]",
@@ -320,6 +443,20 @@
"",
"hello");
+ // disallow lists inside blockquote for now because it causes problems outside blockquote
+ // TODO: fix to be CommonMark-compliant
+ MT("listNestedInBlockquote",
+ "[quote"e-1 > - foo]");
+
+ // disallow fenced blocks inside blockquote because it causes problems outside blockquote
+ // TODO: fix to be CommonMark-compliant
+ MT("fencedBlockNestedInBlockquote",
+ "[quote"e-1 > ```]",
+ "[quote"e-1 > code]",
+ "[quote"e-1 > ```]",
+ // ensure we still allow inline code
+ "[quote"e-1 > ][quote"e-1&comment `code`]");
+
// Header with leading space after continued blockquote (#3287, negative indentation)
MT("headerAfterContinuedBlockquote",
"[quote"e-1 > foo]",
@@ -377,32 +514,53 @@
"[variable-2 - foo]",
"[hr -----]");
+ MT("hrAfterFencedCode",
+ "[comment ```]",
+ "[comment code]",
+ "[comment ```]",
+ "[hr ---]");
+
+ // allow hr inside lists
+ // (require prev line to be empty or hr, TODO: non-CommonMark-compliant)
+ MT("hrInsideList",
+ "[variable-2 - foo]",
+ "",
+ " [hr ---]",
+ " [hr ---]",
+ "",
+ " [comment ---]");
+
+ MT("consecutiveHr",
+ "[hr ---]",
+ "[hr ---]",
+ "[hr ---]");
+
// Formatting in lists (*)
MT("listAsteriskFormatting",
"[variable-2 * ][variable-2&em *foo*][variable-2 bar]",
"[variable-2 * ][variable-2&strong **foo**][variable-2 bar]",
- "[variable-2 * ][variable-2&strong **][variable-2&em&strong *foo**][variable-2&em *][variable-2 bar]",
+ "[variable-2 * ][variable-2&em&strong ***foo***][variable-2 bar]",
"[variable-2 * ][variable-2&comment `foo`][variable-2 bar]");
// Formatting in lists (+)
MT("listPlusFormatting",
"[variable-2 + ][variable-2&em *foo*][variable-2 bar]",
"[variable-2 + ][variable-2&strong **foo**][variable-2 bar]",
- "[variable-2 + ][variable-2&strong **][variable-2&em&strong *foo**][variable-2&em *][variable-2 bar]",
+ "[variable-2 + ][variable-2&em&strong ***foo***][variable-2 bar]",
"[variable-2 + ][variable-2&comment `foo`][variable-2 bar]");
// Formatting in lists (-)
MT("listDashFormatting",
"[variable-2 - ][variable-2&em *foo*][variable-2 bar]",
"[variable-2 - ][variable-2&strong **foo**][variable-2 bar]",
- "[variable-2 - ][variable-2&strong **][variable-2&em&strong *foo**][variable-2&em *][variable-2 bar]",
+ "[variable-2 - ][variable-2&em&strong ***foo***][variable-2 bar]",
"[variable-2 - ][variable-2&comment `foo`][variable-2 bar]");
// Formatting in lists (1.)
MT("listNumberFormatting",
"[variable-2 1. ][variable-2&em *foo*][variable-2 bar]",
"[variable-2 2. ][variable-2&strong **foo**][variable-2 bar]",
- "[variable-2 3. ][variable-2&strong **][variable-2&em&strong *foo**][variable-2&em *][variable-2 bar]",
+ "[variable-2 3. ][variable-2&em&strong ***foo***][variable-2 bar]",
"[variable-2 4. ][variable-2&comment `foo`][variable-2 bar]");
// Paragraph lists
@@ -468,6 +626,66 @@
" [variable-3 * Otherwise, it will be part of the level where it does meet this.]",
" [variable-2 * World]");
+ // should handle nested and un-nested lists
+ MT("listCommonMark_MixedIndents",
+ "[variable-2 * list1]",
+ " [variable-2 list1]",
+ " [variable-2&header&header-1 # heading still part of list1]",
+ " [variable-2 text after heading still part of list1]",
+ "",
+ " [comment indented codeblock]",
+ " [variable-2 list1 after code block]",
+ " [variable-3 * list2]",
+ // amount of spaces on empty lines between lists doesn't matter
+ " ",
+ // extra empty lines irrelevant
+ "",
+ "",
+ " [variable-3 indented text part of list2]",
+ " [keyword * list3]",
+ "",
+ " [variable-3 text at level of list2]",
+ "",
+ " [variable-2 de-indented text part of list1 again]",
+ "",
+ " [variable-2&comment ```]",
+ " [comment code]",
+ " [variable-2&comment ```]",
+ "",
+ " [variable-2 text after fenced code]");
+
+ // should correctly parse numbered list content indentation
+ MT("listCommonMark_NumeberedListIndent",
+ "[variable-2 1000. list with base indent of 6]",
+ "",
+ " [variable-2 text must be indented 6 spaces at minimum]",
+ "",
+ " [variable-2 9-spaces indented text still part of list]",
+ "",
+ " [comment indented codeblock starts at 10 spaces]",
+ "",
+ " [comment text indented by 5 spaces no longer belong to list]");
+
+ // should consider tab as 4 spaces
+ MT("listCommonMark_TabIndented",
+ "[variable-2 * list]",
+ "\t[variable-3 * list2]",
+ "",
+ "\t\t[variable-3 part of list2]");
+
+ MT("listAfterBlockquote",
+ "[quote"e-1 > foo]",
+ "[variable-2 - bar]");
+
+ // shouldn't create sublist if it's indented more than allowed
+ MT("nestedListIndentedTooMuch",
+ "[variable-2 - foo]",
+ " [variable-2 - bar]");
+
+ MT("listIndentedTooMuchAfterParagraph",
+ "foo",
+ " - bar");
+
// Blockquote
MT("blockquote",
"[variable-2 * foo]",
@@ -605,7 +823,7 @@
"[image&image-marker !][image&image-alt-text&link [[][image-alt-text&strong&image&link **alt text**][image&image-alt-text&link ]]][string&url (http://link.to/image.jpg)]");
MT("imageEmStrong",
- "[image&image-marker !][image&image-alt-text&link [[][image-alt-text&image&strong&link **][image&image-alt-text&em&strong&link *alt text**][image&image-alt-text&em&link *][image&image-alt-text&link ]]][string&url (http://link.to/image.jpg)]");
+ "[image&image-marker !][image&image-alt-text&link [[][image&image-alt-text&em&strong&link ***alt text***][image&image-alt-text&link ]]][string&url (http://link.to/image.jpg)]");
// Inline link with title
MT("linkTitle",
@@ -629,7 +847,12 @@
// Inline link with EmStrong
MT("linkEmStrong",
- "[link [[][link&strong **][link&em&strong *foo**][link&em *][link ]]][string&url (http://example.com/)] bar");
+ "[link [[][link&em&strong ***foo***][link ]]][string&url (http://example.com/)] bar");
+
+ MT("multilineLink",
+ "[link [[foo]",
+ "[link bar]]][string&url (https://foo#_a)]",
+ "should not be italics")
// Image with title
MT("imageTitle",
@@ -647,7 +870,7 @@
// regularly in text, especially in quoted material, and no space is allowed
// between square brackets and parentheses (per Dingus).
MT("notALink",
- "[[foo]] (bar)");
+ "[link [[foo]]] (bar)");
// Reference-style links
MT("linkReference",
@@ -663,7 +886,7 @@
// Reference-style links with EmStrong
MT("linkReferenceEmStrong",
- "[link [[][link&strong **][link&em&strong *foo**][link&em *][link ]]][string&url [[bar]]] hello");
+ "[link [[][link&em&strong ***foo***][link ]]][string&url [[bar]]] hello");
// Reference-style links with optional space separator (per documentation)
// "You can optionally use a space to separate the sets of brackets"
@@ -672,7 +895,7 @@
// Should only allow a single space ("...use *a* space...")
MT("linkReferenceDoubleSpace",
- "[[foo]] [[bar]] hello");
+ "[link [[foo]]] [link [[bar]]] hello");
// Reference-style links with implicit link name
MT("linkImplicit",
@@ -733,7 +956,7 @@
"[link [[foo \\]]: bar]]:] [string&url http://example.com/]");
MT("labelEscapeEnd",
- "[[foo\\]]: http://example.com/");
+ "\\[[foo\\]]: http://example.com/");
MT("linkWeb",
"[link
] foo");
@@ -757,7 +980,7 @@
"foo[em *bar*]hello");
MT("emInWordUnderscore",
- "foo[em _bar_]hello");
+ "foo_bar_hello");
// Per documentation: "...surround an * or _ with spaces, it’ll be
// treated as a literal asterisk or underscore."
@@ -766,11 +989,11 @@
"foo [em _bar _ hello_] world");
MT("emEscapedBySpaceOut",
- "foo _ bar[em _hello_]world");
+ "foo _ bar [em _hello_] world");
MT("emEscapedByNewline",
"foo",
- "_ bar[em _hello_]world");
+ "_ bar [em _hello_] world");
// Unclosed emphasis characters
// Instead of simply marking as EM / STRONG, it would be nice to have an
@@ -791,14 +1014,14 @@
"[em *foo][em&strong **bar*][strong hello**] world");
MT("emStrongUnderscore",
- "[em _foo][em&strong __bar_][strong hello__] world");
+ "[em _foo ][em&strong __bar_][strong hello__] world");
// "...same character must be used to open and close an emphasis span.""
MT("emStrongMixed",
"[em _foo][em&strong **bar*hello__ world]");
MT("emStrongMixed",
- "[em *foo][em&strong __bar_hello** world]");
+ "[em *foo ][em&strong __bar_hello** world]");
MT("linkWithNestedParens",
"[link [[foo]]][string&url (bar(baz))]")
@@ -913,26 +1136,77 @@
TokenTypeOverrideTest("overrideStrikethrough",
"[override-strikethrough ~~foo~~]");
+ TokenTypeOverrideTest("overrideEmoji",
+ "[override-emoji :foo:]");
+
FormatTokenTypeOverrideTest("overrideFormatting",
"[override-formatting-escape \\*]");
// Tests to make sure GFM-specific things aren't getting through
MT("taskList",
- "[variable-2 * [ ]] bar]");
+ "[variable-2 * ][link&variable-2 [[ ]]][variable-2 bar]");
- MT("noFencedCodeBlocks",
- "~~~",
- "foo",
- "~~~");
-
- FencedTest("fencedCodeBlocks",
+ MT("fencedCodeBlocks",
"[comment ```]",
"[comment foo]",
+ "",
+ "[comment bar]",
+ "[comment ```]",
+ "baz");
+
+ MT("fencedCodeBlocks_invalidClosingFence_trailingText",
+ "[comment ```]",
+ "[comment foo]",
+ "[comment ``` must not have trailing text]",
+ "[comment baz]");
+
+ MT("fencedCodeBlocks_invalidClosingFence_trailingTabs",
+ "[comment ```]",
+ "[comment foo]",
+ "[comment ```\t]",
+ "[comment baz]");
+
+ MT("fencedCodeBlocks_validClosingFence",
+ "[comment ```]",
+ "[comment foo]",
+ // may have trailing spaces
+ "[comment ``` ]",
+ "baz");
+
+ MT("fencedCodeBlocksInList_closingFenceIndented",
+ "[variable-2 - list]",
+ " [variable-2&comment ```]",
+ " [comment foo]",
+ " [variable-2&comment ```]",
+ " [variable-2 baz]");
+
+ MT("fencedCodeBlocksInList_closingFenceIndentedTooMuch",
+ "[variable-2 - list]",
+ " [variable-2&comment ```]",
+ " [comment foo]",
+ " [comment ```]",
+ " [comment baz]");
+
+ MT("fencedCodeBlockModeSwitching",
+ "[comment ```javascript]",
+ "[variable foo]",
+ "",
"[comment ```]",
"bar");
- FencedTest("fencedCodeBlocksMultipleChars",
+ MT_noFencedHighlight("fencedCodeBlock_noHighlight",
+ "[comment ```javascript]",
+ "[comment foo]",
+ "[comment ```]");
+
+ MT("fencedCodeBlockModeSwitchingObjc",
+ "[comment ```objective-c]",
+ "[keyword @property] [variable NSString] [operator *] [variable foo];",
+ "[comment ```]",
+ "bar");
+
+ MT("fencedCodeBlocksMultipleChars",
"[comment `````]",
"[comment foo]",
"[comment ```]",
@@ -940,20 +1214,20 @@
"[comment `````]",
"bar");
- FencedTest("fencedCodeBlocksTildes",
+ MT("fencedCodeBlocksTildes",
"[comment ~~~]",
"[comment foo]",
"[comment ~~~]",
"bar");
- FencedTest("fencedCodeBlocksTildesMultipleChars",
+ MT("fencedCodeBlocksTildesMultipleChars",
"[comment ~~~~~]",
"[comment ~~~]",
"[comment foo]",
"[comment ~~~~~]",
"bar");
- FencedTest("fencedCodeBlocksMultipleChars",
+ MT("fencedCodeBlocksMultipleChars",
"[comment `````]",
"[comment foo]",
"[comment ```]",
@@ -961,19 +1235,42 @@
"[comment `````]",
"bar");
- FencedTest("fencedCodeBlocksMixed",
+ MT("fencedCodeBlocksMixed",
"[comment ~~~]",
"[comment ```]",
"[comment foo]",
"[comment ~~~]",
"bar");
+ MT("fencedCodeBlocksAfterBlockquote",
+ "[quote"e-1 > foo]",
+ "[comment ```]",
+ "[comment bar]",
+ "[comment ```]");
+
+ // fencedCode indented too much should act as simple indentedCode
+ // (hence has no highlight formatting)
+ FT("tooMuchIndentedFencedCode",
+ " [comment ```]",
+ " [comment code]",
+ " [comment ```]");
+
+ MT("autoTerminateFencedCodeWhenLeavingList",
+ "[variable-2 - list1]",
+ " [variable-3 - list2]",
+ " [variable-3&comment ```]",
+ " [comment code]",
+ " [variable-3 - list2]",
+ " [variable-2&comment ```]",
+ " [comment code]",
+ "[quote"e-1 > foo]");
+
// Tests that require XML mode
MT("xmlMode",
"[tag&bracket <][tag div][tag&bracket >]",
- "*foo*",
- "[tag&bracket <][tag http://github.com][tag&bracket />]",
+ " *foo*",
+ " [tag&bracket <][tag http://github.com][tag&bracket />]",
"[tag&bracket ][tag div][tag&bracket >]",
"[link
]");
@@ -986,4 +1283,7 @@
"[tag&bracket <][tag div][tag&bracket >]",
"[tag&bracket ][tag div][tag&bracket >]");
+ MT_noXml("xmlHighlightDisabled",
+ "
foo
");
+
})();
diff --git a/gui/public/codemirror/mode/mathematica/index.html b/gui/public/codemirror/mode/mathematica/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/mathematica/mathematica.js b/gui/public/codemirror/mode/mathematica/mathematica.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/mbox/index.html b/gui/public/codemirror/mode/mbox/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/mbox/mbox.js b/gui/public/codemirror/mode/mbox/mbox.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/meta.js b/gui/public/codemirror/mode/meta.js
old mode 100755
new mode 100644
index bb605024..34da269f
--- a/gui/public/codemirror/mode/meta.js
+++ b/gui/public/codemirror/mode/meta.js
@@ -13,7 +13,7 @@
CodeMirror.modeInfo = [
{name: "APL", mime: "text/apl", mode: "apl", ext: ["dyalog", "apl"]},
- {name: "PGP", mimes: ["application/pgp", "application/pgp-keys", "application/pgp-signature"], mode: "asciiarmor", ext: ["pgp"]},
+ {name: "PGP", mimes: ["application/pgp", "application/pgp-encrypted", "application/pgp-keys", "application/pgp-signature"], mode: "asciiarmor", ext: ["asc", "pgp", "sig"]},
{name: "ASN.1", mime: "text/x-ttcn-asn", mode: "asn.1", ext: ["asn", "asn1"]},
{name: "Asterisk", mime: "text/x-asterisk", mode: "asterisk", file: /^extensions\.conf$/i},
{name: "Brainfuck", mime: "text/x-brainfuck", mode: "brainfuck", ext: ["b", "bf"]},
@@ -25,7 +25,7 @@
{name: "ClojureScript", mime: "text/x-clojurescript", mode: "clojure", ext: ["cljs"]},
{name: "Closure Stylesheets (GSS)", mime: "text/x-gss", mode: "css", ext: ["gss"]},
{name: "CMake", mime: "text/x-cmake", mode: "cmake", ext: ["cmake", "cmake.in"], file: /^CMakeLists.txt$/},
- {name: "CoffeeScript", mime: "text/x-coffeescript", mode: "coffeescript", ext: ["coffee"], alias: ["coffee", "coffee-script"]},
+ {name: "CoffeeScript", mimes: ["application/vnd.coffeescript", "text/coffeescript", "text/x-coffeescript"], mode: "coffeescript", ext: ["coffee"], alias: ["coffee", "coffee-script"]},
{name: "Common Lisp", mime: "text/x-common-lisp", mode: "commonlisp", ext: ["cl", "lisp", "el"], alias: ["lisp"]},
{name: "Cypher", mime: "application/x-cypher-query", mode: "cypher", ext: ["cyp", "cypher"]},
{name: "Cython", mime: "text/x-cython", mode: "python", ext: ["pyx", "pxd", "pxi"]},
@@ -47,6 +47,7 @@
{name: "Embedded Javascript", mime: "application/x-ejs", mode: "htmlembedded", ext: ["ejs"]},
{name: "Embedded Ruby", mime: "application/x-erb", mode: "htmlembedded", ext: ["erb"]},
{name: "Erlang", mime: "text/x-erlang", mode: "erlang", ext: ["erl"]},
+ {name: "Esper", mime: "text/x-esper", mode: "sql"},
{name: "Factor", mime: "text/x-factor", mode: "factor", ext: ["factor"]},
{name: "FCL", mime: "text/x-fcl", mode: "fcl"},
{name: "Forth", mime: "text/x-forth", mode: "forth", ext: ["forth", "fth", "4th"]},
@@ -91,7 +92,8 @@
{name: "MySQL", mime: "text/x-mysql", mode: "sql"},
{name: "Nginx", mime: "text/x-nginx-conf", mode: "nginx", file: /nginx.*\.conf$/i},
{name: "NSIS", mime: "text/x-nsis", mode: "nsis", ext: ["nsh", "nsi"]},
- {name: "NTriples", mime: "text/n-triples", mode: "ntriples", ext: ["nt"]},
+ {name: "NTriples", mimes: ["application/n-triples", "application/n-quads", "text/n-triples"],
+ mode: "ntriples", ext: ["nt", "nq"]},
{name: "Objective C", mime: "text/x-objectivec", mode: "clike", ext: ["m", "mm"], alias: ["objective-c", "objc"]},
{name: "OCaml", mime: "text/x-ocaml", mode: "mllike", ext: ["ml", "mli", "mll", "mly"]},
{name: "Octave", mime: "text/x-octave", mode: "octave", ext: ["m"]},
@@ -99,7 +101,7 @@
{name: "Pascal", mime: "text/x-pascal", mode: "pascal", ext: ["p", "pas"]},
{name: "PEG.js", mime: "null", mode: "pegjs", ext: ["jsonld"]},
{name: "Perl", mime: "text/x-perl", mode: "perl", ext: ["pl", "pm"]},
- {name: "PHP", mime: "application/x-httpd-php", mode: "php", ext: ["php", "php3", "php4", "php5", "phtml"]},
+ {name: "PHP", mime: ["application/x-httpd-php", "text/x-php"], mode: "php", ext: ["php", "php3", "php4", "php5", "php7", "phtml"]},
{name: "Pig", mime: "text/x-pig", mode: "pig", ext: ["pig"]},
{name: "Plain Text", mime: "text/plain", mode: "null", ext: ["txt", "text", "conf", "def", "list", "log"]},
{name: "PLSQL", mime: "text/x-plsql", mode: "sql", ext: ["pls"]},
@@ -120,7 +122,7 @@
{name: "Scala", mime: "text/x-scala", mode: "clike", ext: ["scala"]},
{name: "Scheme", mime: "text/x-scheme", mode: "scheme", ext: ["scm", "ss"]},
{name: "SCSS", mime: "text/x-scss", mode: "css", ext: ["scss"]},
- {name: "Shell", mime: "text/x-sh", mode: "shell", ext: ["sh", "ksh", "bash"], alias: ["bash", "sh", "zsh"], file: /^PKGBUILD$/},
+ {name: "Shell", mimes: ["text/x-sh", "application/x-sh"], mode: "shell", ext: ["sh", "ksh", "bash"], alias: ["bash", "sh", "zsh"], file: /^PKGBUILD$/},
{name: "Sieve", mime: "application/sieve", mode: "sieve", ext: ["siv", "sieve"]},
{name: "Slim", mimes: ["text/x-slim", "application/x-slim"], mode: "slim", ext: ["slim"]},
{name: "Smalltalk", mime: "text/x-stsrc", mode: "smalltalk", ext: ["st"]},
@@ -130,12 +132,13 @@
{name: "SPARQL", mime: "application/sparql-query", mode: "sparql", ext: ["rq", "sparql"], alias: ["sparul"]},
{name: "Spreadsheet", mime: "text/x-spreadsheet", mode: "spreadsheet", alias: ["excel", "formula"]},
{name: "SQL", mime: "text/x-sql", mode: "sql", ext: ["sql"]},
+ {name: "SQLite", mime: "text/x-sqlite", mode: "sql"},
{name: "Squirrel", mime: "text/x-squirrel", mode: "clike", ext: ["nut"]},
{name: "Stylus", mime: "text/x-styl", mode: "stylus", ext: ["styl"]},
{name: "Swift", mime: "text/x-swift", mode: "swift", ext: ["swift"]},
{name: "sTeX", mime: "text/x-stex", mode: "stex"},
{name: "LaTeX", mime: "text/x-latex", mode: "stex", ext: ["text", "ltx"], alias: ["tex"]},
- {name: "SystemVerilog", mime: "text/x-systemverilog", mode: "verilog", ext: ["v"]},
+ {name: "SystemVerilog", mime: "text/x-systemverilog", mode: "verilog", ext: ["v", "sv", "svh"]},
{name: "Tcl", mime: "text/x-tcl", mode: "tcl", ext: ["tcl"]},
{name: "Textile", mime: "text/x-textile", mode: "textile", ext: ["textile"]},
{name: "TiddlyWiki ", mime: "text/x-tiddlywiki", mode: "tiddlywiki"},
@@ -147,6 +150,7 @@
{name: "TTCN_CFG", mime: "text/x-ttcn-cfg", mode: "ttcn-cfg", ext: ["cfg"]},
{name: "Turtle", mime: "text/turtle", mode: "turtle", ext: ["ttl"]},
{name: "TypeScript", mime: "application/typescript", mode: "javascript", ext: ["ts"], alias: ["ts"]},
+ {name: "TypeScript-JSX", mime: "text/typescript-jsx", mode: "jsx", ext: ["tsx"], alias: ["tsx"]},
{name: "Twig", mime: "text/x-twig", mode: "twig"},
{name: "Web IDL", mime: "text/x-webidl", mode: "webidl", ext: ["webidl"]},
{name: "VB.NET", mime: "text/x-vb", mode: "vb", ext: ["vb"]},
diff --git a/gui/public/codemirror/mode/mirc/index.html b/gui/public/codemirror/mode/mirc/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/mirc/mirc.js b/gui/public/codemirror/mode/mirc/mirc.js
old mode 100755
new mode 100644
index f0d5c6ad..71ac4ddf
--- a/gui/public/codemirror/mode/mirc/mirc.js
+++ b/gui/public/codemirror/mode/mirc/mirc.js
@@ -130,7 +130,7 @@ CodeMirror.defineMode("mirc", function() {
}
}
else if (ch == "%") {
- stream.eatWhile(/[^,^\s^\(^\)]/);
+ stream.eatWhile(/[^,\s()]/);
state.beforeParams = true;
return "string";
}
diff --git a/gui/public/codemirror/mode/mllike/index.html b/gui/public/codemirror/mode/mllike/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/mllike/mllike.js b/gui/public/codemirror/mode/mllike/mllike.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/modelica/index.html b/gui/public/codemirror/mode/modelica/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/modelica/modelica.js b/gui/public/codemirror/mode/modelica/modelica.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/mscgen/index.html b/gui/public/codemirror/mode/mscgen/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/mscgen/mscgen.js b/gui/public/codemirror/mode/mscgen/mscgen.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/mscgen/mscgen_test.js b/gui/public/codemirror/mode/mscgen/mscgen_test.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/mscgen/msgenny_test.js b/gui/public/codemirror/mode/mscgen/msgenny_test.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/mscgen/xu_test.js b/gui/public/codemirror/mode/mscgen/xu_test.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/mumps/index.html b/gui/public/codemirror/mode/mumps/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/mumps/mumps.js b/gui/public/codemirror/mode/mumps/mumps.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/nginx/index.html b/gui/public/codemirror/mode/nginx/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/nginx/nginx.js b/gui/public/codemirror/mode/nginx/nginx.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/nsis/index.html b/gui/public/codemirror/mode/nsis/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/nsis/nsis.js b/gui/public/codemirror/mode/nsis/nsis.js
old mode 100755
new mode 100644
index dc8c74cd..d6c61fac
--- a/gui/public/codemirror/mode/nsis/nsis.js
+++ b/gui/public/codemirror/mode/nsis/nsis.js
@@ -24,20 +24,20 @@ CodeMirror.defineSimpleMode("nsis",{
{ regex: /`(?:[^\\`]|\\.)*`?/, token: "string" },
// Compile Time Commands
- {regex: /^\s*(?:\!(include|addincludedir|addplugindir|appendfile|cd|delfile|echo|error|execute|packhdr|finalize|getdllversion|system|tempfile|warning|verbose|define|undef|insertmacro|makensis|searchparse|searchreplace))\b/, token: "keyword"},
+ {regex: /^\s*(?:\!(include|addincludedir|addplugindir|appendfile|cd|delfile|echo|error|execute|packhdr|pragma|finalize|getdllversion|system|tempfile|warning|verbose|define|undef|insertmacro|makensis|searchparse|searchreplace))\b/, token: "keyword"},
// Conditional Compilation
{regex: /^\s*(?:\!(if(?:n?def)?|ifmacron?def|macro))\b/, token: "keyword", indent: true},
{regex: /^\s*(?:\!(else|endif|macroend))\b/, token: "keyword", dedent: true},
// Runtime Commands
- {regex: /^\s*(?:Abort|AddBrandingImage|AddSize|AllowRootDirInstall|AllowSkipFiles|AutoCloseWindow|BGFont|BGGradient|BrandingText|BringToFront|Call|CallInstDLL|Caption|ChangeUI|CheckBitmap|ClearErrors|CompletedText|ComponentText|CopyFiles|CRCCheck|CreateDirectory|CreateFont|CreateShortCut|Delete|DeleteINISec|DeleteINIStr|DeleteRegKey|DeleteRegValue|DetailPrint|DetailsButtonText|DirText|DirVar|DirVerify|EnableWindow|EnumRegKey|EnumRegValue|Exch|Exec|ExecShell|ExecWait|ExpandEnvStrings|File|FileBufSize|FileClose|FileErrorText|FileOpen|FileRead|FileReadByte|FileReadUTF16LE|FileReadWord|FileWriteUTF16LE|FileSeek|FileWrite|FileWriteByte|FileWriteWord|FindClose|FindFirst|FindNext|FindWindow|FlushINI|GetCurInstType|GetCurrentAddress|GetDlgItem|GetDLLVersion|GetDLLVersionLocal|GetErrorLevel|GetFileTime|GetFileTimeLocal|GetFullPathName|GetFunctionAddress|GetInstDirError|GetLabelAddress|GetTempFileName|Goto|HideWindow|Icon|IfAbort|IfErrors|IfFileExists|IfRebootFlag|IfSilent|InitPluginsDir|InstallButtonText|InstallColors|InstallDir|InstallDirRegKey|InstProgressFlags|InstType|InstTypeGetText|InstTypeSetText|IntCmp|IntCmpU|IntFmt|IntOp|IsWindow|LangString|LicenseBkColor|LicenseData|LicenseForceSelection|LicenseLangString|LicenseText|LoadLanguageFile|LockWindow|LogSet|LogText|ManifestDPIAware|ManifestSupportedOS|MessageBox|MiscButtonText|Name|Nop|OutFile|Page|PageCallbacks|Pop|Push|Quit|ReadEnvStr|ReadINIStr|ReadRegDWORD|ReadRegStr|Reboot|RegDLL|Rename|RequestExecutionLevel|ReserveFile|Return|RMDir|SearchPath|SectionGetFlags|SectionGetInstTypes|SectionGetSize|SectionGetText|SectionIn|SectionSetFlags|SectionSetInstTypes|SectionSetSize|SectionSetText|SendMessage|SetAutoClose|SetBrandingImage|SetCompress|SetCompressor|SetCompressorDictSize|SetCtlColors|SetCurInstType|SetDatablockOptimize|SetDateSave|SetDetailsPrint|SetDetailsView|SetErrorLevel|SetErrors|SetFileAttributes|SetFont|SetOutPath|SetOverwrite|SetRebootFlag|SetRegView|SetShellVarContext|SetSilent|ShowInstDetails|ShowUninstDetails|ShowWindow|SilentInstall|SilentUnInstall|Sleep|SpaceTexts|StrCmp|StrCmpS|StrCpy|StrLen|SubCaption|Unicode|UninstallButtonText|UninstallCaption|UninstallIcon|UninstallSubCaption|UninstallText|UninstPage|UnRegDLL|Var|VIAddVersionKey|VIFileVersion|VIProductVersion|WindowIcon|WriteINIStr|WriteRegBin|WriteRegDWORD|WriteRegExpandStr|WriteRegStr|WriteUninstaller|XPStyle)\b/, token: "keyword"},
+ {regex: /^\s*(?:Abort|AddBrandingImage|AddSize|AllowRootDirInstall|AllowSkipFiles|AutoCloseWindow|BGFont|BGGradient|BrandingText|BringToFront|Call|CallInstDLL|Caption|ChangeUI|CheckBitmap|ClearErrors|CompletedText|ComponentText|CopyFiles|CRCCheck|CreateDirectory|CreateFont|CreateShortCut|Delete|DeleteINISec|DeleteINIStr|DeleteRegKey|DeleteRegValue|DetailPrint|DetailsButtonText|DirText|DirVar|DirVerify|EnableWindow|EnumRegKey|EnumRegValue|Exch|Exec|ExecShell|ExecShellWait|ExecWait|ExpandEnvStrings|File|FileBufSize|FileClose|FileErrorText|FileOpen|FileRead|FileReadByte|FileReadUTF16LE|FileReadWord|FileWriteUTF16LE|FileSeek|FileWrite|FileWriteByte|FileWriteWord|FindClose|FindFirst|FindNext|FindWindow|FlushINI|GetCurInstType|GetCurrentAddress|GetDlgItem|GetDLLVersion|GetDLLVersionLocal|GetErrorLevel|GetFileTime|GetFileTimeLocal|GetFullPathName|GetFunctionAddress|GetInstDirError|GetLabelAddress|GetTempFileName|Goto|HideWindow|Icon|IfAbort|IfErrors|IfFileExists|IfRebootFlag|IfSilent|InitPluginsDir|InstallButtonText|InstallColors|InstallDir|InstallDirRegKey|InstProgressFlags|InstType|InstTypeGetText|InstTypeSetText|IntCmp|IntCmpU|IntFmt|IntOp|IsWindow|LangString|LicenseBkColor|LicenseData|LicenseForceSelection|LicenseLangString|LicenseText|LoadLanguageFile|LockWindow|LogSet|LogText|ManifestDPIAware|ManifestSupportedOS|MessageBox|MiscButtonText|Name|Nop|OutFile|Page|PageCallbacks|Pop|Push|Quit|ReadEnvStr|ReadINIStr|ReadRegDWORD|ReadRegStr|Reboot|RegDLL|Rename|RequestExecutionLevel|ReserveFile|Return|RMDir|SearchPath|SectionGetFlags|SectionGetInstTypes|SectionGetSize|SectionGetText|SectionIn|SectionSetFlags|SectionSetInstTypes|SectionSetSize|SectionSetText|SendMessage|SetAutoClose|SetBrandingImage|SetCompress|SetCompressor|SetCompressorDictSize|SetCtlColors|SetCurInstType|SetDatablockOptimize|SetDateSave|SetDetailsPrint|SetDetailsView|SetErrorLevel|SetErrors|SetFileAttributes|SetFont|SetOutPath|SetOverwrite|SetRebootFlag|SetRegView|SetShellVarContext|SetSilent|ShowInstDetails|ShowUninstDetails|ShowWindow|SilentInstall|SilentUnInstall|Sleep|SpaceTexts|StrCmp|StrCmpS|StrCpy|StrLen|SubCaption|Unicode|UninstallButtonText|UninstallCaption|UninstallIcon|UninstallSubCaption|UninstallText|UninstPage|UnRegDLL|Var|VIAddVersionKey|VIFileVersion|VIProductVersion|WindowIcon|WriteINIStr|WriteRegBin|WriteRegDWORD|WriteRegExpandStr|WriteRegMultiStr|WriteRegNone|WriteRegStr|WriteUninstaller|XPStyle)\b/, token: "keyword"},
{regex: /^\s*(?:Function|PageEx|Section(?:Group)?)\b/, token: "keyword", indent: true},
{regex: /^\s*(?:(Function|PageEx|Section(?:Group)?)End)\b/, token: "keyword", dedent: true},
// Command Options
- {regex: /\b(?:ARCHIVE|FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_NORMAL|FILE_ATTRIBUTE_OFFLINE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_TEMPORARY|HIDDEN|HKCC|HKCR|HKCU|HKDD|HKEY_CLASSES_ROOT|HKEY_CURRENT_CONFIG|HKEY_CURRENT_USER|HKEY_DYN_DATA|HKEY_LOCAL_MACHINE|HKEY_PERFORMANCE_DATA|HKEY_USERS|HKLM|HKPD|HKU|IDABORT|IDCANCEL|IDD_DIR|IDD_INST|IDD_INSTFILES|IDD_LICENSE|IDD_SELCOM|IDD_UNINST|IDD_VERIFY|IDIGNORE|IDNO|IDOK|IDRETRY|IDYES|MB_ABORTRETRYIGNORE|MB_DEFBUTTON1|MB_DEFBUTTON2|MB_DEFBUTTON3|MB_DEFBUTTON4|MB_ICONEXCLAMATION|MB_ICONINFORMATION|MB_ICONQUESTION|MB_ICONSTOP|MB_OK|MB_OKCANCEL|MB_RETRYCANCEL|MB_RIGHT|MB_RTLREADING|MB_SETFOREGROUND|MB_TOPMOST|MB_USERICON|MB_YESNO|MB_YESNOCANCEL|NORMAL|OFFLINE|READONLY|SHCTX|SHELL_CONTEXT|SW_HIDE|SW_SHOWDEFAULT|SW_SHOWMAXIMIZED|SW_SHOWMINIMIZED|SW_SHOWNORMAL|SYSTEM|TEMPORARY)\b/, token: "atom"},
- {regex: /\b(?:admin|all|auto|both|bottom|bzip2|components|current|custom|directory|force|hide|highest|ifdiff|ifnewer|instfiles|lastused|leave|left|license|listonly|lzma|nevershow|none|normal|notset|right|show|silent|silentlog|textonly|top|try|un\.components|un\.custom|un\.directory|un\.instfiles|un\.license|uninstConfirm|user|Win10|Win7|Win8|WinVista|zlib)\b/, token: "builtin"},
+ {regex: /\b(?:ARCHIVE|FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_NORMAL|FILE_ATTRIBUTE_OFFLINE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_TEMPORARY|HIDDEN|HKCC|HKCR(32|64)?|HKCU(32|64)?|HKDD|HKEY_CLASSES_ROOT|HKEY_CURRENT_CONFIG|HKEY_CURRENT_USER|HKEY_DYN_DATA|HKEY_LOCAL_MACHINE|HKEY_PERFORMANCE_DATA|HKEY_USERS|HKLM(32|64)?|HKPD|HKU|IDABORT|IDCANCEL|IDD_DIR|IDD_INST|IDD_INSTFILES|IDD_LICENSE|IDD_SELCOM|IDD_UNINST|IDD_VERIFY|IDIGNORE|IDNO|IDOK|IDRETRY|IDYES|MB_ABORTRETRYIGNORE|MB_DEFBUTTON1|MB_DEFBUTTON2|MB_DEFBUTTON3|MB_DEFBUTTON4|MB_ICONEXCLAMATION|MB_ICONINFORMATION|MB_ICONQUESTION|MB_ICONSTOP|MB_OK|MB_OKCANCEL|MB_RETRYCANCEL|MB_RIGHT|MB_RTLREADING|MB_SETFOREGROUND|MB_TOPMOST|MB_USERICON|MB_YESNO|MB_YESNOCANCEL|NORMAL|OFFLINE|READONLY|SHCTX|SHELL_CONTEXT|SW_HIDE|SW_SHOWDEFAULT|SW_SHOWMAXIMIZED|SW_SHOWMINIMIZED|SW_SHOWNORMAL|SYSTEM|TEMPORARY)\b/, token: "atom"},
+ {regex: /\b(?:admin|all|auto|both|bottom|bzip2|components|current|custom|directory|false|force|hide|highest|ifdiff|ifnewer|instfiles|lastused|leave|left|license|listonly|lzma|nevershow|none|normal|notset|off|on|right|show|silent|silentlog|textonly|top|true|try|un\.components|un\.custom|un\.directory|un\.instfiles|un\.license|uninstConfirm|user|Win10|Win7|Win8|WinVista|zlib)\b/, token: "builtin"},
// LogicLib.nsh
{regex: /\$\{(?:And(?:If(?:Not)?|Unless)|Break|Case(?:Else)?|Continue|Default|Do(?:Until|While)?|Else(?:If(?:Not)?|Unless)?|End(?:If|Select|Switch)|Exit(?:Do|For|While)|For(?:Each)?|If(?:Cmd|Not(?:Then)?|Then)?|Loop(?:Until|While)?|Or(?:If(?:Not)?|Unless)|Select|Switch|Unless|While)\}/, token: "variable-2", indent: true},
diff --git a/gui/public/codemirror/mode/ntriples/index.html b/gui/public/codemirror/mode/ntriples/index.html
old mode 100755
new mode 100644
index 1355e718..9c998463
--- a/gui/public/codemirror/mode/ntriples/index.html
+++ b/gui/public/codemirror/mode/ntriples/index.html
@@ -1,6 +1,6 @@
-
CodeMirror: NTriples mode
+
CodeMirror: N-Triples mode
@@ -10,6 +10,7 @@
-NTriples mode
+
+ The N-Triples mode also works well with on
+ N-Quad documents.
+
diff --git a/gui/public/codemirror/mode/ntriples/ntriples.js b/gui/public/codemirror/mode/ntriples/ntriples.js
old mode 100755
new mode 100644
index 0524b1e8..148272e1
--- a/gui/public/codemirror/mode/ntriples/ntriples.js
+++ b/gui/public/codemirror/mode/ntriples/ntriples.js
@@ -3,9 +3,9 @@
/**********************************************************
* This script provides syntax highlighting support for
-* the Ntriples format.
-* Ntriples format specification:
-* http://www.w3.org/TR/rdf-testcases/#ntriples
+* the N-Triples format.
+* N-Triples format specification:
+* https://www.w3.org/TR/n-triples/
***********************************************************/
/*
@@ -181,6 +181,15 @@ CodeMirror.defineMode("ntriples", function() {
};
});
+// define the registered Media Type for n-triples:
+// https://www.w3.org/TR/n-triples/#n-triples-mediatype
+CodeMirror.defineMIME("application/n-triples", "ntriples");
+
+// N-Quads is based on the N-Triples format (so same highlighting works)
+// https://www.w3.org/TR/n-quads/
+CodeMirror.defineMIME("application/n-quads", "ntriples");
+
+// previously used, though technically incorrect media type for n-triples
CodeMirror.defineMIME("text/n-triples", "ntriples");
});
diff --git a/gui/public/codemirror/mode/octave/index.html b/gui/public/codemirror/mode/octave/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/octave/octave.js b/gui/public/codemirror/mode/octave/octave.js
old mode 100755
new mode 100644
index f38b751d..b77ad682
--- a/gui/public/codemirror/mode/octave/octave.js
+++ b/gui/public/codemirror/mode/octave/octave.js
@@ -90,8 +90,8 @@ CodeMirror.defineMode("octave", function() {
if (stream.match(wordRegexp(['nan','NaN','inf','Inf']))) { return 'number'; };
// Handle Strings
- if (stream.match(/^"([^"]|(""))*"/)) { return 'string'; } ;
- if (stream.match(/^'([^']|(''))*'/)) { return 'string'; } ;
+ var m = stream.match(/^"(?:[^"]|"")*("|$)/) || stream.match(/^'(?:[^']|'')*('|$)/)
+ if (m) { return m[1] ? 'string' : "string error"; }
// Handle words
if (stream.match(keywords)) { return 'keyword'; } ;
diff --git a/gui/public/codemirror/mode/oz/index.html b/gui/public/codemirror/mode/oz/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/oz/oz.js b/gui/public/codemirror/mode/oz/oz.js
old mode 100755
new mode 100644
index ee8cb0ad..50ffda37
--- a/gui/public/codemirror/mode/oz/oz.js
+++ b/gui/public/codemirror/mode/oz/oz.js
@@ -27,7 +27,7 @@ CodeMirror.defineMode("oz", function (conf) {
var atoms = wordRegexp(["true", "false", "nil", "unit"]);
var commonKeywords = wordRegexp(["andthen", "at", "attr", "declare", "feat", "from", "lex",
- "mod", "mode", "orelse", "parser", "prod", "prop", "scanner", "self", "syn", "token"]);
+ "mod", "div", "mode", "orelse", "parser", "prod", "prop", "scanner", "self", "syn", "token"]);
var openingKeywords = wordRegexp(["local", "proc", "fun", "case", "class", "if", "cond", "or", "dis",
"choice", "not", "thread", "try", "raise", "lock", "for", "suchthat", "meth", "functor"]);
var middleKeywords = wordRegexp(middle);
diff --git a/gui/public/codemirror/mode/pascal/index.html b/gui/public/codemirror/mode/pascal/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/pascal/pascal.js b/gui/public/codemirror/mode/pascal/pascal.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/pegjs/index.html b/gui/public/codemirror/mode/pegjs/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/pegjs/pegjs.js b/gui/public/codemirror/mode/pegjs/pegjs.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/perl/index.html b/gui/public/codemirror/mode/perl/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/perl/perl.js b/gui/public/codemirror/mode/perl/perl.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/php/index.html b/gui/public/codemirror/mode/php/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/php/php.js b/gui/public/codemirror/mode/php/php.js
old mode 100755
new mode 100644
index 57ba812d..589c9a66
--- a/gui/public/codemirror/mode/php/php.js
+++ b/gui/public/codemirror/mode/php/php.js
@@ -151,7 +151,7 @@
};
CodeMirror.defineMode("php", function(config, parserConfig) {
- var htmlMode = CodeMirror.getMode(config, "text/html");
+ var htmlMode = CodeMirror.getMode(config, (parserConfig && parserConfig.htmlMode) || "text/html");
var phpMode = CodeMirror.getMode(config, phpConfig);
function dispatch(stream, state) {
diff --git a/gui/public/codemirror/mode/php/test.js b/gui/public/codemirror/mode/php/test.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/pig/index.html b/gui/public/codemirror/mode/pig/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/pig/pig.js b/gui/public/codemirror/mode/pig/pig.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/powershell/index.html b/gui/public/codemirror/mode/powershell/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/powershell/powershell.js b/gui/public/codemirror/mode/powershell/powershell.js
old mode 100755
new mode 100644
index 5eae9794..2728ef9d
--- a/gui/public/codemirror/mode/powershell/powershell.js
+++ b/gui/public/codemirror/mode/powershell/powershell.js
@@ -4,9 +4,9 @@
(function(mod) {
'use strict';
if (typeof exports == 'object' && typeof module == 'object') // CommonJS
- mod(require('codemirror'));
+ mod(require('../../lib/codemirror'));
else if (typeof define == 'function' && define.amd) // AMD
- define(['codemirror'], mod);
+ define(['../../lib/codemirror'], mod);
else // Plain browser env
mod(window.CodeMirror);
})(function(CodeMirror) {
diff --git a/gui/public/codemirror/mode/powershell/test.js b/gui/public/codemirror/mode/powershell/test.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/properties/index.html b/gui/public/codemirror/mode/properties/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/properties/properties.js b/gui/public/codemirror/mode/properties/properties.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/protobuf/index.html b/gui/public/codemirror/mode/protobuf/index.html
old mode 100755
new mode 100644
index cfe7b9dc..55d45356
--- a/gui/public/codemirror/mode/protobuf/index.html
+++ b/gui/public/codemirror/mode/protobuf/index.html
@@ -54,9 +54,49 @@ message Person {
required bool deleted = 11 [default = false];
}
-
+
+
+
MIME types defined: text/x-protobuf
.
diff --git a/gui/public/codemirror/mode/protobuf/protobuf.js b/gui/public/codemirror/mode/protobuf/protobuf.js
old mode 100755
new mode 100644
index bcae276e..93cb3b0e
--- a/gui/public/codemirror/mode/protobuf/protobuf.js
+++ b/gui/public/codemirror/mode/protobuf/protobuf.js
@@ -19,7 +19,8 @@
"package", "message", "import", "syntax",
"required", "optional", "repeated", "reserved", "default", "extensions", "packed",
"bool", "bytes", "double", "enum", "float", "string",
- "int32", "int64", "uint32", "uint64", "sint32", "sint64", "fixed32", "fixed64", "sfixed32", "sfixed64"
+ "int32", "int64", "uint32", "uint64", "sint32", "sint64", "fixed32", "fixed64", "sfixed32", "sfixed64",
+ "option", "service", "rpc", "returns"
];
var keywords = wordRegexp(keywordArray);
diff --git a/gui/public/codemirror/mode/pug/index.html b/gui/public/codemirror/mode/pug/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/pug/pug.js b/gui/public/codemirror/mode/pug/pug.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/puppet/index.html b/gui/public/codemirror/mode/puppet/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/puppet/puppet.js b/gui/public/codemirror/mode/puppet/puppet.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/python/index.html b/gui/public/codemirror/mode/python/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/python/python.js b/gui/public/codemirror/mode/python/python.js
old mode 100755
new mode 100644
index b539d84a..c3187932
--- a/gui/public/codemirror/mode/python/python.js
+++ b/gui/public/codemirror/mode/python/python.js
@@ -41,10 +41,11 @@
CodeMirror.defineMode("python", function(conf, parserConf) {
var ERRORCLASS = "error";
- var singleDelimiters = parserConf.singleDelimiters || /^[\(\)\[\]\{\}@,:`=;\.]/;
- var doubleOperators = parserConf.doubleOperators || /^([!<>]==|<>|<<|>>|\/\/|\*\*)/;
- var doubleDelimiters = parserConf.doubleDelimiters || /^(\+=|\-=|\*=|%=|\/=|&=|\|=|\^=)/;
- var tripleDelimiters = parserConf.tripleDelimiters || /^(\/\/=|>>=|<<=|\*\*=)/;
+ var delimiters = parserConf.delimiters || parserConf.singleDelimiters || /^[\(\)\[\]\{\}@,:`=;\.]/;
+ // (Backwards-compatiblity with old, cumbersome config system)
+ var operators = [parserConf.singleOperators, parserConf.doubleOperators, parserConf.doubleDelimiters, parserConf.tripleDelimiters,
+ parserConf.operators || /^([-+*/%\/&|^]=?|[<>=]+|\/\/=?|\*\*=?|!=|[~!@])/]
+ for (var i = 0; i < operators.length; i++) if (!operators[i]) operators.splice(i--, 1)
var hangingIndent = parserConf.hangingIndent || conf.indentUnit;
@@ -58,13 +59,11 @@
var py3 = !(parserConf.version && Number(parserConf.version) < 3)
if (py3) {
// since http://legacy.python.org/dev/peps/pep-0465/ @ is also an operator
- var singleOperators = parserConf.singleOperators || /^[\+\-\*\/%&|\^~<>!@]/;
var identifiers = parserConf.identifiers|| /^[_A-Za-z\u00A1-\uFFFF][_A-Za-z0-9\u00A1-\uFFFF]*/;
myKeywords = myKeywords.concat(["nonlocal", "False", "True", "None", "async", "await"]);
myBuiltins = myBuiltins.concat(["ascii", "bytes", "exec", "print"]);
var stringPrefixes = new RegExp("^(([rbuf]|(br))?('{3}|\"{3}|['\"]))", "i");
} else {
- var singleOperators = parserConf.singleOperators || /^[\+\-\*\/%&|\^~<>!]/;
var identifiers = parserConf.identifiers|| /^[_A-Za-z][_A-Za-z0-9]*/;
myKeywords = myKeywords.concat(["exec", "print"]);
myBuiltins = myBuiltins.concat(["apply", "basestring", "buffer", "cmp", "coerce", "execfile",
@@ -151,15 +150,10 @@
return state.tokenize(stream, state);
}
- // Handle operators and Delimiters
- if (stream.match(tripleDelimiters) || stream.match(doubleDelimiters))
- return "punctuation";
+ for (var i = 0; i < operators.length; i++)
+ if (stream.match(operators[i])) return "operator"
- if (stream.match(doubleOperators) || stream.match(singleOperators))
- return "operator";
-
- if (stream.match(singleDelimiters))
- return "punctuation";
+ if (stream.match(delimiters)) return "punctuation";
if (state.lastToken == "." && stream.match(identifiers))
return "property";
@@ -332,8 +326,8 @@
CodeMirror.defineMIME("text/x-cython", {
name: "python",
- extra_keywords: words("by cdef cimport cpdef ctypedef enum except"+
- "extern gil include nogil property public"+
+ extra_keywords: words("by cdef cimport cpdef ctypedef enum except "+
+ "extern gil include nogil property public "+
"readonly struct union DEF IF ELIF ELSE")
});
diff --git a/gui/public/codemirror/mode/python/test.js b/gui/public/codemirror/mode/python/test.js
old mode 100755
new mode 100644
index c1a9c6a9..950eed51
--- a/gui/public/codemirror/mode/python/test.js
+++ b/gui/public/codemirror/mode/python/test.js
@@ -24,6 +24,11 @@
MT("matmulWithSpace:", "[variable a] [operator @] [variable b]");
MT("matmulWithoutSpace:", "[variable a][operator @][variable b]");
MT("matmulSpaceBefore:", "[variable a] [operator @][variable b]");
+ var before_equal_sign = ["+", "-", "*", "/", "=", "!", ">", "<"];
+ for (var i = 0; i < before_equal_sign.length; ++i) {
+ var c = before_equal_sign[i]
+ MT("before_equal_sign_" + c, "[variable a] [operator " + c + "=] [variable b]");
+ }
MT("fValidStringPrefix", "[string f'this is a {formatted} string']");
MT("uValidStringPrefix", "[string u'this is an unicode string']");
diff --git a/gui/public/codemirror/mode/q/index.html b/gui/public/codemirror/mode/q/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/q/q.js b/gui/public/codemirror/mode/q/q.js
old mode 100755
new mode 100644
index a4af9383..9aee18ab
--- a/gui/public/codemirror/mode/q/q.js
+++ b/gui/public/codemirror/mode/q/q.js
@@ -25,7 +25,7 @@ CodeMirror.defineMode("q",function(config){
return(state.tokenize=tokenLineComment)(stream,state);
else if(c=="\\"){
if(stream.eol()||/\s/.test(stream.peek()))
- return stream.skipToEnd(),/^\\\s*$/.test(stream.current())?(state.tokenize=tokenCommentToEOF)(stream, state):state.tokenize=tokenBase,"comment";
+ return stream.skipToEnd(),/^\\\s*$/.test(stream.current())?(state.tokenize=tokenCommentToEOF)(stream):state.tokenize=tokenBase,"comment";
else
return state.tokenize=tokenBase,"builtin";
}
@@ -34,25 +34,25 @@ CodeMirror.defineMode("q",function(config){
if(c=='"')
return(state.tokenize=tokenString)(stream,state);
if(c=='`')
- return stream.eatWhile(/[A-Z|a-z|\d|_|:|\/|\.]/),"symbol";
+ return stream.eatWhile(/[A-Za-z\d_:\/.]/),"symbol";
if(("."==c&&/\d/.test(stream.peek()))||/\d/.test(c)){
var t=null;
stream.backUp(1);
- if(stream.match(/^\d{4}\.\d{2}(m|\.\d{2}([D|T](\d{2}(:\d{2}(:\d{2}(\.\d{1,9})?)?)?)?)?)/)
+ if(stream.match(/^\d{4}\.\d{2}(m|\.\d{2}([DT](\d{2}(:\d{2}(:\d{2}(\.\d{1,9})?)?)?)?)?)/)
|| stream.match(/^\d+D(\d{2}(:\d{2}(:\d{2}(\.\d{1,9})?)?)?)/)
|| stream.match(/^\d{2}:\d{2}(:\d{2}(\.\d{1,9})?)?/)
|| stream.match(/^\d+[ptuv]{1}/))
t="temporal";
else if(stream.match(/^0[NwW]{1}/)
- || stream.match(/^0x[\d|a-f|A-F]*/)
- || stream.match(/^[0|1]+[b]{1}/)
+ || stream.match(/^0x[\da-fA-F]*/)
+ || stream.match(/^[01]+[b]{1}/)
|| stream.match(/^\d+[chijn]{1}/)
|| stream.match(/-?\d*(\.\d*)?(e[+\-]?\d+)?(e|f)?/))
t="number";
return(t&&(!(c=stream.peek())||E.test(c)))?t:(stream.next(),"error");
}
- if(/[A-Z|a-z]|\./.test(c))
- return stream.eatWhile(/[A-Z|a-z|\.|_|\d]/),keywords.test(stream.current())?"keyword":"variable";
+ if(/[A-Za-z]|\./.test(c))
+ return stream.eatWhile(/[A-Za-z._\d]/),keywords.test(stream.current())?"keyword":"variable";
if(/[|/&^!+:\\\-*%$=~#;@><\.,?_\']/.test(c))
return null;
if(/[{}\(\[\]\)]/.test(c))
diff --git a/gui/public/codemirror/mode/r/index.html b/gui/public/codemirror/mode/r/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/r/r.js b/gui/public/codemirror/mode/r/r.js
old mode 100755
new mode 100644
index 7e15beac..be7db46b
--- a/gui/public/codemirror/mode/r/r.js
+++ b/gui/public/codemirror/mode/r/r.js
@@ -108,13 +108,23 @@ CodeMirror.defineMode("r", function(config) {
};
}
+ var ALIGN_YES = 1, ALIGN_NO = 2, BRACELESS = 4
+
function push(state, type, stream) {
state.ctx = {type: type,
indent: state.indent,
- align: null,
+ flags: 0,
column: stream.column(),
prev: state.ctx};
}
+ function setFlag(state, flag) {
+ var ctx = state.ctx
+ state.ctx = {type: ctx.type,
+ indent: ctx.indent,
+ flags: ctx.flags | flag,
+ column: ctx.column,
+ prev: ctx.prev}
+ }
function pop(state) {
state.indent = state.ctx.indent;
state.ctx = state.ctx.prev;
@@ -125,22 +135,22 @@ CodeMirror.defineMode("r", function(config) {
return {tokenize: tokenBase,
ctx: {type: "top",
indent: -config.indentUnit,
- align: false},
+ flags: ALIGN_NO},
indent: 0,
afterIdent: false};
},
token: function(stream, state) {
if (stream.sol()) {
- if (state.ctx.align == null) state.ctx.align = false;
+ if ((state.ctx.flags & 3) == 0) state.ctx.flags |= ALIGN_NO
+ if (state.ctx.flags & BRACELESS) pop(state)
state.indent = stream.indentation();
}
if (stream.eatSpace()) return null;
var style = state.tokenize(stream, state);
- if (style != "comment" && state.ctx.align == null) state.ctx.align = true;
+ if (style != "comment" && (state.ctx.flags & ALIGN_NO) == 0) setFlag(state, ALIGN_YES)
- var ctype = state.ctx.type;
- if ((curPunc == ";" || curPunc == "{" || curPunc == "}") && ctype == "block") pop(state);
+ if ((curPunc == ";" || curPunc == "{" || curPunc == "}") && state.ctx.type == "block") pop(state);
if (curPunc == "{") push(state, "}", stream);
else if (curPunc == "(") {
push(state, ")", stream);
@@ -148,7 +158,8 @@ CodeMirror.defineMode("r", function(config) {
}
else if (curPunc == "[") push(state, "]", stream);
else if (curPunc == "block") push(state, "block", stream);
- else if (curPunc == ctype) pop(state);
+ else if (curPunc == state.ctx.type) pop(state);
+ else if (state.ctx.type == "block" && style != "comment") setFlag(state, BRACELESS)
state.afterIdent = style == "variable" || style == "keyword";
return style;
},
@@ -157,8 +168,9 @@ CodeMirror.defineMode("r", function(config) {
if (state.tokenize != tokenBase) return 0;
var firstChar = textAfter && textAfter.charAt(0), ctx = state.ctx,
closing = firstChar == ctx.type;
+ if (ctx.flags & BRACELESS) ctx = ctx.prev
if (ctx.type == "block") return ctx.indent + (firstChar == "{" ? 0 : config.indentUnit);
- else if (ctx.align) return ctx.column + (closing ? 0 : 1);
+ else if (ctx.flags & ALIGN_YES) return ctx.column + (closing ? 0 : 1);
else return ctx.indent + (closing ? 0 : config.indentUnit);
},
diff --git a/gui/public/codemirror/mode/rpm/changes/index.html b/gui/public/codemirror/mode/rpm/changes/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/rpm/index.html b/gui/public/codemirror/mode/rpm/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/rpm/rpm.js b/gui/public/codemirror/mode/rpm/rpm.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/rst/index.html b/gui/public/codemirror/mode/rst/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/rst/rst.js b/gui/public/codemirror/mode/rst/rst.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/ruby/index.html b/gui/public/codemirror/mode/ruby/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/ruby/ruby.js b/gui/public/codemirror/mode/ruby/ruby.js
old mode 100755
new mode 100644
index 085f909f..874c1830
--- a/gui/public/codemirror/mode/ruby/ruby.js
+++ b/gui/public/codemirror/mode/ruby/ruby.js
@@ -46,22 +46,10 @@ CodeMirror.defineMode("ruby", function(config) {
if (ch == "`" || ch == "'" || ch == '"') {
return chain(readQuoted(ch, "string", ch == '"' || ch == "`"), stream, state);
} else if (ch == "/") {
- var currentIndex = stream.current().length;
- if (stream.skipTo("/")) {
- var search_till = stream.current().length;
- stream.backUp(stream.current().length - currentIndex);
- var balance = 0; // balance brackets
- while (stream.current().length < search_till) {
- var chchr = stream.next();
- if (chchr == "(") balance += 1;
- else if (chchr == ")") balance -= 1;
- if (balance < 0) break;
- }
- stream.backUp(stream.current().length - currentIndex);
- if (balance == 0)
- return chain(readQuoted(ch, "string-2", true), stream, state);
- }
- return "operator";
+ if (regexpAhead(stream))
+ return chain(readQuoted(ch, "string-2", true), stream, state);
+ else
+ return "operator";
} else if (ch == "%") {
var style = "string", embed = true;
if (stream.eat("s")) style = "atom";
@@ -148,6 +136,28 @@ CodeMirror.defineMode("ruby", function(config) {
}
}
+ function regexpAhead(stream) {
+ var start = stream.pos, depth = 0, next, found = false, escaped = false
+ while ((next = stream.next()) != null) {
+ if (!escaped) {
+ if ("[{(".indexOf(next) > -1) {
+ depth++
+ } else if ("]})".indexOf(next) > -1) {
+ depth--
+ if (depth < 0) break
+ } else if (next == "/" && depth == 0) {
+ found = true
+ break
+ }
+ escaped = next == "\\"
+ } else {
+ escaped = false
+ }
+ }
+ stream.backUp(stream.pos - start)
+ return found
+ }
+
function tokenBaseUntilBrace(depth) {
if (!depth) depth = 1;
return function(stream, state) {
@@ -276,7 +286,8 @@ CodeMirror.defineMode("ruby", function(config) {
},
electricInput: /^\s*(?:end|rescue|elsif|else|\})$/,
- lineComment: "#"
+ lineComment: "#",
+ fold: "indent"
};
});
diff --git a/gui/public/codemirror/mode/ruby/test.js b/gui/public/codemirror/mode/ruby/test.js
old mode 100755
new mode 100644
index cade864f..3133bd63
--- a/gui/public/codemirror/mode/ruby/test.js
+++ b/gui/public/codemirror/mode/ruby/test.js
@@ -11,4 +11,6 @@
MT("divide_equal_operator_no_spacing",
"[variable foo][operator /=][number 42]");
+ MT("complex_regexp",
+ "[keyword if] [variable cr] [operator =~] [string-2 /(?: \\( #{][tag RE_NOT][string-2 }\\( | #{][tag RE_NOT_PAR_OR][string-2 }* #{][tag RE_OPA_OR][string-2 } )/][variable x]")
})();
diff --git a/gui/public/codemirror/mode/rust/index.html b/gui/public/codemirror/mode/rust/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/rust/rust.js b/gui/public/codemirror/mode/rust/rust.js
old mode 100755
new mode 100644
index 8558b53f..b635563a
--- a/gui/public/codemirror/mode/rust/rust.js
+++ b/gui/public/codemirror/mode/rust/rust.js
@@ -68,4 +68,5 @@ CodeMirror.defineSimpleMode("rust",{
CodeMirror.defineMIME("text/x-rustsrc", "rust");
+CodeMirror.defineMIME("text/rust", "rust");
});
diff --git a/gui/public/codemirror/mode/rust/test.js b/gui/public/codemirror/mode/rust/test.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/sas/index.html b/gui/public/codemirror/mode/sas/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/sas/sas.js b/gui/public/codemirror/mode/sas/sas.js
index a6109eb1..d85b3353 100755
--- a/gui/public/codemirror/mode/sas/sas.js
+++ b/gui/public/codemirror/mode/sas/sas.js
@@ -11,7 +11,7 @@
//Definitions
-// comment -- text withing * ; or /* */
+// comment -- text within * ; or /* */
// keyword -- SAS language variable
// variable -- macro variables starts with '&' or variable formats
// variable-2 -- DATA Step, proc, or macro names
@@ -116,28 +116,15 @@
return "comment";
}
+ if (ch == "*" && stream.column() == stream.indentation()) {
+ stream.skipToEnd()
+ return "comment"
+ }
+
// DoubleOperator match
var doubleOperator = ch + stream.peek();
- // Match all line comments.
- var myString = stream.string;
- var myRegexp = /(?:^\s*|[;]\s*)(\*.*?);/ig;
- var match = myRegexp.exec(myString);
- if (match !== null) {
- if (match.index === 0 && (stream.column() !== (match.index + match[0].length - 1))) {
- stream.backUp(stream.column());
- stream.skipTo(';');
- stream.next();
- return 'comment';
- } else if (match.index + 1 < stream.column() && stream.column() < match.index + match[0].length - 1) {
- // the ';' triggers the match so move one past it to start
- // the comment block that is why match.index+1
- stream.backUp(stream.column() - match.index - 1);
- stream.skipTo(';');
- stream.next();
- return 'comment';
- }
- } else if ((ch === '"' || ch === "'") && !state.continueString) {
+ if ((ch === '"' || ch === "'") && !state.continueString) {
state.continueString = ch
return "string"
} else if (state.continueString) {
diff --git a/gui/public/codemirror/mode/sass/index.html b/gui/public/codemirror/mode/sass/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/sass/sass.js b/gui/public/codemirror/mode/sass/sass.js
old mode 100755
new mode 100644
index ba0e0562..7d8135bf
--- a/gui/public/codemirror/mode/sass/sass.js
+++ b/gui/public/codemirror/mode/sass/sass.js
@@ -447,7 +447,7 @@ CodeMirror.defineMode("sass", function(config) {
return state.scopes[0].offset;
}
};
-});
+}, "css");
CodeMirror.defineMIME("text/x-sass", "sass");
diff --git a/gui/public/codemirror/mode/sass/test.js b/gui/public/codemirror/mode/sass/test.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/scheme/index.html b/gui/public/codemirror/mode/scheme/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/scheme/scheme.js b/gui/public/codemirror/mode/scheme/scheme.js
old mode 100755
new mode 100644
index 22346459..1d8f7d17
--- a/gui/public/codemirror/mode/scheme/scheme.js
+++ b/gui/public/codemirror/mode/scheme/scheme.js
@@ -224,7 +224,7 @@ CodeMirror.defineMode("scheme", function () {
}
}
} else {
- stream.eatWhile(/[\w\$_\-!$%&*+\.\/:<=>?@\^~]/);
+ stream.eatWhile(/[\w_\-!$%&*+\.\/:<=>?@\^~]/);
if (keywords && keywords.propertyIsEnumerable(stream.current())) {
returnType = BUILTIN;
diff --git a/gui/public/codemirror/mode/shell/index.html b/gui/public/codemirror/mode/shell/index.html
old mode 100755
new mode 100644
index 0b56300b..e42f4b5f
--- a/gui/public/codemirror/mode/shell/index.html
+++ b/gui/public/codemirror/mode/shell/index.html
@@ -62,5 +62,5 @@ exit 0
});
-
MIME types defined: text/x-sh
.
+
MIME types defined: text/x-sh
, application/x-sh
.
diff --git a/gui/public/codemirror/mode/shell/shell.js b/gui/public/codemirror/mode/shell/shell.js
old mode 100755
new mode 100644
index 944f64dc..9b8b90b3
--- a/gui/public/codemirror/mode/shell/shell.js
+++ b/gui/public/codemirror/mode/shell/shell.js
@@ -30,9 +30,9 @@ CodeMirror.defineMode('shell', function() {
// Commands
define('builtin', 'ab awk bash beep cat cc cd chown chmod chroot clear cp ' +
- 'curl cut diff echo find gawk gcc get git grep kill killall ln ls make ' +
+ 'curl cut diff echo find gawk gcc get git grep hg kill killall ln ls make ' +
'mkdir openssl mv nc node npm ping ps restart rm rmdir sed service sh ' +
- 'shopt shred source sort sleep ssh start stop su sudo tee telnet top ' +
+ 'shopt shred source sort sleep ssh start stop su sudo svn tee telnet top ' +
'touch vi vim wall wc wget who write yes zsh');
function tokenBase(stream, state) {
@@ -82,7 +82,7 @@ CodeMirror.defineMode('shell', function() {
}
function tokenString(quote, style) {
- var close = quote == "(" ? ")" : quote
+ var close = quote == "(" ? ")" : quote == "{" ? "}" : quote
return function(stream, state) {
var next, end = false, escaped = false;
while ((next = stream.next()) != null) {
@@ -96,29 +96,25 @@ CodeMirror.defineMode('shell', function() {
state.tokens.unshift(tokenDollar);
break;
}
- if (next === "(" && quote === "(") {
+ if (!escaped && next === quote && quote !== close) {
state.tokens.unshift(tokenString(quote, style))
return tokenize(stream, state)
}
escaped = !escaped && next === '\\';
}
- if (end || !escaped) state.tokens.shift();
+ if (end) state.tokens.shift();
return style;
};
};
var tokenDollar = function(stream, state) {
if (state.tokens.length > 1) stream.eat('$');
- var ch = stream.next(), hungry = /\w/;
- if (ch === '{') hungry = /[^}]/;
- if (/['"(]/.test(ch)) {
- state.tokens[0] = tokenString(ch, ch == "(" ? "quote" : "string");
+ var ch = stream.next()
+ if (/['"({]/.test(ch)) {
+ state.tokens[0] = tokenString(ch, ch == "(" ? "quote" : ch == "{" ? "def" : "string");
return tokenize(stream, state);
}
- if (!/\d/.test(ch)) {
- stream.eatWhile(hungry);
- stream.eat('}');
- }
+ if (!/\d/.test(ch)) stream.eatWhile(/\w/);
state.tokens.shift();
return 'def';
};
@@ -139,5 +135,8 @@ CodeMirror.defineMode('shell', function() {
});
CodeMirror.defineMIME('text/x-sh', 'shell');
+// Apache uses a slightly different Media Type for Shell scripts
+// http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types
+CodeMirror.defineMIME('application/x-sh', 'shell');
});
diff --git a/gui/public/codemirror/mode/shell/test.js b/gui/public/codemirror/mode/shell/test.js
old mode 100755
new mode 100644
index e42dd162..86e344c5
--- a/gui/public/codemirror/mode/shell/test.js
+++ b/gui/public/codemirror/mode/shell/test.js
@@ -58,4 +58,7 @@
MT("doubleParens",
"foo [quote $((bar))]")
+
+ MT("nested braces",
+ "[builtin echo] [def ${A[${B}]]}]")
})();
diff --git a/gui/public/codemirror/mode/sieve/index.html b/gui/public/codemirror/mode/sieve/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/sieve/sieve.js b/gui/public/codemirror/mode/sieve/sieve.js
old mode 100755
new mode 100644
index f67db2f5..0920d0ba
--- a/gui/public/codemirror/mode/sieve/sieve.js
+++ b/gui/public/codemirror/mode/sieve/sieve.js
@@ -170,7 +170,7 @@ CodeMirror.defineMode("sieve", function(config) {
if (stream.eatSpace())
return null;
- return (state.tokenize || tokenBase)(stream, state);;
+ return (state.tokenize || tokenBase)(stream, state);
},
indent: function(state, _textAfter) {
diff --git a/gui/public/codemirror/mode/slim/index.html b/gui/public/codemirror/mode/slim/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/slim/slim.js b/gui/public/codemirror/mode/slim/slim.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/slim/test.js b/gui/public/codemirror/mode/slim/test.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/smalltalk/index.html b/gui/public/codemirror/mode/smalltalk/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/smalltalk/smalltalk.js b/gui/public/codemirror/mode/smalltalk/smalltalk.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/smarty/index.html b/gui/public/codemirror/mode/smarty/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/smarty/smarty.js b/gui/public/codemirror/mode/smarty/smarty.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/solr/index.html b/gui/public/codemirror/mode/solr/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/solr/solr.js b/gui/public/codemirror/mode/solr/solr.js
old mode 100755
new mode 100644
index f7f70878..dc8b8250
--- a/gui/public/codemirror/mode/solr/solr.js
+++ b/gui/public/codemirror/mode/solr/solr.js
@@ -14,12 +14,12 @@
CodeMirror.defineMode("solr", function() {
"use strict";
- var isStringChar = /[^\s\|\!\+\-\*\?\~\^\&\:\(\)\[\]\{\}\^\"\\]/;
+ var isStringChar = /[^\s\|\!\+\-\*\?\~\^\&\:\(\)\[\]\{\}\"\\]/;
var isOperatorChar = /[\|\!\+\-\*\?\~\^\&]/;
var isOperatorString = /^(OR|AND|NOT|TO)$/i;
function isNumber(word) {
- return parseFloat(word, 10).toString() === word;
+ return parseFloat(word).toString() === word;
}
function tokenString(quote) {
diff --git a/gui/public/codemirror/mode/soy/index.html b/gui/public/codemirror/mode/soy/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/soy/soy.js b/gui/public/codemirror/mode/soy/soy.js
old mode 100755
new mode 100644
index 1c1f74d1..98f30865
--- a/gui/public/codemirror/mode/soy/soy.js
+++ b/gui/public/codemirror/mode/soy/soy.js
@@ -31,6 +31,12 @@
}
function tokenUntil(stream, state, untilRegExp) {
+ if (stream.sol()) {
+ for (var indent = 0; indent < state.indent; indent++) {
+ if (!stream.eat(/\s/)) break;
+ }
+ if (indent) return null;
+ }
var oldString = stream.string;
var match = untilRegExp.exec(oldString.substr(stream.pos));
if (match) {
@@ -39,7 +45,8 @@
stream.string = oldString.substr(0, stream.pos + match.index);
}
var result = stream.hideFirstChars(state.indent, function() {
- return state.localMode.token(stream, state.localState);
+ var localState = last(state.localStates);
+ return localState.mode.token(stream, localState.state);
});
stream.string = oldString;
return result;
@@ -80,11 +87,14 @@
kindTag: [],
soyState: [],
templates: null,
- variables: null,
+ variables: prepend(null, 'ij'),
scopes: null,
indent: 0,
- localMode: modes.html,
- localState: CodeMirror.startState(modes.html)
+ quoteKind: null,
+ localStates: [{
+ mode: modes.html,
+ state: CodeMirror.startState(modes.html)
+ }]
};
},
@@ -98,8 +108,13 @@
variables: state.variables,
scopes: state.scopes,
indent: state.indent, // Indentation of the following line.
- localMode: state.localMode,
- localState: CodeMirror.copyState(state.localMode, state.localState)
+ quoteKind: state.quoteKind,
+ localStates: state.localStates.map(function(localState) {
+ return {
+ mode: localState.mode,
+ state: CodeMirror.copyState(localState.mode, localState.state)
+ };
+ })
};
},
@@ -113,8 +128,34 @@
} else {
stream.skipToEnd();
}
+ if (!state.scopes) {
+ var paramRe = /@param\??\s+(\S+)/g;
+ var current = stream.current();
+ for (var match; (match = paramRe.exec(current)); ) {
+ state.variables = prepend(state.variables, match[1]);
+ }
+ }
return "comment";
+ case "string":
+ var match = stream.match(/^.*?(["']|\\[\s\S])/);
+ if (!match) {
+ stream.skipToEnd();
+ } else if (match[1] == state.quoteKind) {
+ state.quoteKind = null;
+ state.soyState.pop();
+ }
+ return "string";
+ }
+
+ if (stream.match(/^\/\*/)) {
+ state.soyState.push("comment");
+ return "comment";
+ } else if (stream.match(stream.sol() || (state.soyState.length && last(state.soyState) != "literal") ? /^\s*\/\/.*/ : /^\s+\/\/.*/)) {
+ return "comment";
+ }
+
+ switch (last(state.soyState)) {
case "templ-def":
if (match = stream.match(/^\.?([\w]+(?!\.[\w]+)*)/)) {
state.templates = prepend(state.templates, match[1]);
@@ -139,8 +180,8 @@
return null;
case "param-def":
- if (match = stream.match(/^([\w]+)(?=:)/)) {
- state.variables = prepend(state.variables, match[1]);
+ if (match = stream.match(/^\w+/)) {
+ state.variables = prepend(state.variables, match[0]);
state.soyState.pop();
state.soyState.push("param-type");
return "def";
@@ -172,6 +213,7 @@
if (stream.match(/^\/?}/)) {
if (state.tag == "/template" || state.tag == "/deltemplate") {
popscope(state);
+ state.variables = prepend(null, 'ij');
state.indent = 0;
} else {
if (state.tag == "/for" || state.tag == "/foreach") {
@@ -187,12 +229,20 @@
var kind = match[1];
state.kind.push(kind);
state.kindTag.push(state.tag);
- state.localMode = modes[kind] || modes.html;
- state.localState = CodeMirror.startState(state.localMode);
+ var mode = modes[kind] || modes.html;
+ var localState = last(state.localStates);
+ if (localState.mode.indent) {
+ state.indent += localState.mode.indent(localState.state, "");
+ }
+ state.localStates.push({
+ mode: mode,
+ state: CodeMirror.startState(mode)
+ });
}
return "attribute";
- } else if (stream.match(/^"/)) {
+ } else if (match = stream.match(/^["']/)) {
state.soyState.push("string");
+ state.quoteKind = match;
return "string";
}
if (match = stream.match(/^\$([\w]+)/)) {
@@ -211,55 +261,53 @@
return this.token(stream, state);
}
return tokenUntil(stream, state, /\{\/literal}/);
-
- case "string":
- var match = stream.match(/^.*?("|\\[\s\S])/);
- if (!match) {
- stream.skipToEnd();
- } else if (match[1] == "\"") {
- state.soyState.pop();
- }
- return "string";
}
- if (stream.match(/^\/\*/)) {
- state.soyState.push("comment");
- return "comment";
- } else if (stream.match(stream.sol() ? /^\s*\/\/.*/ : /^\s+\/\/.*/)) {
- return "comment";
- } else if (stream.match(/^\{literal}/)) {
+ if (stream.match(/^\{literal}/)) {
state.indent += config.indentUnit;
state.soyState.push("literal");
return "keyword";
- } else if (match = stream.match(/^\{([\/@\\]?[\w?]*)/)) {
+
+ // A tag-keyword must be followed by whitespace, comment or a closing tag.
+ } else if (match = stream.match(/^\{([\/@\\]?\w+\??)(?=[\s\}]|\/[/*])/)) {
if (match[1] != "/switch")
- state.indent += (/^(\/|(else|elseif|ifempty|case|default)$)/.test(match[1]) && state.tag != "switch" ? 1 : 2) * config.indentUnit;
+ state.indent += (/^(\/|(else|elseif|ifempty|case|fallbackmsg|default)$)/.test(match[1]) && state.tag != "switch" ? 1 : 2) * config.indentUnit;
state.tag = match[1];
if (state.tag == "/" + last(state.kindTag)) {
// We found the tag that opened the current kind="".
state.kind.pop();
state.kindTag.pop();
- state.localMode = modes[last(state.kind)] || modes.html;
- state.localState = CodeMirror.startState(state.localMode);
+ state.localStates.pop();
+ var localState = last(state.localStates);
+ if (localState.mode.indent) {
+ state.indent -= localState.mode.indent(localState.state, "");
+ }
}
state.soyState.push("tag");
if (state.tag == "template" || state.tag == "deltemplate") {
state.soyState.push("templ-def");
- }
- if (state.tag == "call" || state.tag == "delcall") {
+ } else if (state.tag == "call" || state.tag == "delcall") {
state.soyState.push("templ-ref");
- }
- if (state.tag == "let") {
+ } else if (state.tag == "let") {
state.soyState.push("var-def");
- }
- if (state.tag == "for" || state.tag == "foreach") {
+ } else if (state.tag == "for" || state.tag == "foreach") {
state.scopes = prepend(state.scopes, state.variables);
state.soyState.push("var-def");
- }
- if (state.tag.match(/^@param\??/)) {
+ } else if (state.tag == "namespace") {
+ if (!state.scopes) {
+ state.variables = prepend(null, 'ij');
+ }
+ } else if (state.tag.match(/^@(?:param\??|inject)/)) {
state.soyState.push("param-def");
}
return "keyword";
+
+ // Not a tag-keyword; it's an implicit print tag.
+ } else if (stream.eat('{')) {
+ state.tag = "print";
+ state.indent += 2 * config.indentUnit;
+ state.soyState.push("tag");
+ return "keyword";
}
return tokenUntil(stream, state, /\{|\s+\/\/|\/\*/);
@@ -277,14 +325,16 @@
if (state.tag != "switch" && /^\{(case|default)\b/.test(textAfter)) indent -= config.indentUnit;
if (/^\{\/switch\b/.test(textAfter)) indent -= config.indentUnit;
}
- if (indent && state.localMode.indent)
- indent += state.localMode.indent(state.localState, textAfter);
+ var localState = last(state.localStates);
+ if (indent && localState.mode.indent) {
+ indent += localState.mode.indent(localState.state, textAfter);
+ }
return indent;
},
innerMode: function(state) {
if (state.soyState.length && last(state.soyState) != "literal") return null;
- else return {state: state.localState, mode: state.localMode};
+ else return last(state.localStates);
},
electricInput: /^\s*\{(\/|\/template|\/deltemplate|\/switch|fallbackmsg|elseif|else|case|default|ifempty|\/literal\})$/,
diff --git a/gui/public/codemirror/mode/soy/test.js b/gui/public/codemirror/mode/soy/test.js
old mode 100755
new mode 100644
index 9e265c1b..7cd111f2
--- a/gui/public/codemirror/mode/soy/test.js
+++ b/gui/public/codemirror/mode/soy/test.js
@@ -80,4 +80,35 @@
' nothing',
'[keyword {/foreach}]',
'');
+
+ MT('nested-kind-test',
+ '[keyword {template] [def .foo] [attribute kind]=[string "html"][keyword }]',
+ ' [tag&bracket <][tag div][tag&bracket >]',
+ ' [keyword {call] [variable .bar][keyword }]',
+ ' [keyword {param] [attribute kind]=[string "js"][keyword }]',
+ ' [keyword var] [def bar] [operator =] [number 5];',
+ ' [keyword {/param}]',
+ ' [keyword {/call}]',
+ ' [tag&bracket ][tag div][tag&bracket >]',
+ '[keyword {/template}]',
+ '');
+
+ MT('tag-starting-with-function-call-is-not-a-keyword',
+ '[keyword {]index([variable-2&error $foo])[keyword }]',
+ '[keyword {css] [string "some-class"][keyword }]',
+ '[keyword {]css([string "some-class"])[keyword }]',
+ '');
+
+ MT('allow-missing-colon-in-@param',
+ '[keyword {template] [def .foo][keyword }]',
+ ' [keyword {@param] [def showThing] [variable-3 bool][keyword }]',
+ ' [keyword {if] [variable-2 $showThing][keyword }]',
+ ' Yo!',
+ ' [keyword {/if}]',
+ '[keyword {/template}]',
+ '');
+
+ MT('single-quote-strings',
+ '[keyword {][string "foo"] [string \'bar\'][keyword }]',
+ '');
})();
diff --git a/gui/public/codemirror/mode/sparql/index.html b/gui/public/codemirror/mode/sparql/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/sparql/sparql.js b/gui/public/codemirror/mode/sparql/sparql.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/spreadsheet/index.html b/gui/public/codemirror/mode/spreadsheet/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/spreadsheet/spreadsheet.js b/gui/public/codemirror/mode/spreadsheet/spreadsheet.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/sql/index.html b/gui/public/codemirror/mode/sql/index.html
old mode 100755
new mode 100644
index dba069dc..b434f0f4
--- a/gui/public/codemirror/mode/sql/index.html
+++ b/gui/public/codemirror/mode/sql/index.html
@@ -49,7 +49,7 @@ SELECT SQL_NO_CACHE DISTINCT
LIMIT 1 OFFSET 0;
-
MIME types defined:
+
MIME types defined:
text/x-sql
,
text/x-mysql
,
text/x-mariadb
,
@@ -58,7 +58,9 @@ SELECT SQL_NO_CACHE DISTINCT
text/x-mssql
,
text/x-hive
,
text/x-pgsql
,
- text/x-gql
.
+ text/x-gql
,
+ text/x-gpsql
.
+ text/x-esper
.
-
-
+
-
MIME type defined: text/x-vb
.
-
+
diff --git a/gui/public/codemirror/mode/vb/vb.js b/gui/public/codemirror/mode/vb/vb.js
old mode 100755
new mode 100644
index d78f91f7..735eb7f7
--- a/gui/public/codemirror/mode/vb/vb.js
+++ b/gui/public/codemirror/mode/vb/vb.js
@@ -202,7 +202,6 @@ CodeMirror.defineMode("vb", function(conf, parserConf) {
// Handle '.' connected identifiers
if (current === '.') {
style = state.tokenize(stream, state);
- current = stream.current();
if (style === 'variable') {
return 'variable';
} else {
diff --git a/gui/public/codemirror/mode/vbscript/index.html b/gui/public/codemirror/mode/vbscript/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/vbscript/vbscript.js b/gui/public/codemirror/mode/vbscript/vbscript.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/velocity/index.html b/gui/public/codemirror/mode/velocity/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/velocity/velocity.js b/gui/public/codemirror/mode/velocity/velocity.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/verilog/index.html b/gui/public/codemirror/mode/verilog/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/verilog/test.js b/gui/public/codemirror/mode/verilog/test.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/verilog/verilog.js b/gui/public/codemirror/mode/verilog/verilog.js
old mode 100755
new mode 100644
index 460cdb3b..34046860
--- a/gui/public/codemirror/mode/verilog/verilog.js
+++ b/gui/public/codemirror/mode/verilog/verilog.js
@@ -81,7 +81,7 @@ CodeMirror.defineMode("verilog", function(config, parserConfig) {
// Block openings which are closed by a matching keyword in the form of ("end" + keyword)
// E.g. "task" => "endtask"
var blockKeywords = words(
- "case checker class clocking config function generate interface module package" +
+ "case checker class clocking config function generate interface module package " +
"primitive program property specify sequence table task"
);
@@ -602,7 +602,7 @@ CodeMirror.defineMode("verilog", function(config, parserConfig) {
var prefix = match[1];
var mnemonic = match[2];
if (// is identifier prefix
- (prefix in tlvIdentifierStyle) &&
+ tlvIdentifierStyle.hasOwnProperty(prefix) &&
// has mnemonic or we're at the end of the line (maybe it hasn't been typed yet)
(mnemonic.length > 0 || stream.eol())) {
style = tlvIdentifierStyle[prefix];
diff --git a/gui/public/codemirror/mode/vhdl/index.html b/gui/public/codemirror/mode/vhdl/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/vhdl/vhdl.js b/gui/public/codemirror/mode/vhdl/vhdl.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/vue/index.html b/gui/public/codemirror/mode/vue/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/vue/vue.js b/gui/public/codemirror/mode/vue/vue.js
old mode 100755
new mode 100644
index c0eab6b8..84cd07c9
--- a/gui/public/codemirror/mode/vue/vue.js
+++ b/gui/public/codemirror/mode/vue/vue.js
@@ -32,13 +32,20 @@
var tagLanguages = {
script: [
["lang", /coffee(script)?/, "coffeescript"],
- ["type", /^(?:text|application)\/(?:x-)?coffee(?:script)?$/, "coffeescript"]
+ ["type", /^(?:text|application)\/(?:x-)?coffee(?:script)?$/, "coffeescript"],
+ ["lang", /^babel$/, "javascript"],
+ ["type", /^text\/babel$/, "javascript"],
+ ["type", /^text\/ecmascript-\d+$/, "javascript"]
],
style: [
["lang", /^stylus$/i, "stylus"],
["lang", /^sass$/i, "sass"],
+ ["lang", /^less$/i, "text/x-less"],
+ ["lang", /^scss$/i, "text/x-scss"],
["type", /^(text\/)?(x-)?styl(us)?$/i, "stylus"],
- ["type", /^text\/sass/i, "sass"]
+ ["type", /^text\/sass/i, "sass"],
+ ["type", /^(text\/)?(x-)?scss$/i, "text/x-scss"],
+ ["type", /^(text\/)?(x-)?less$/i, "text/x-less"]
],
template: [
["lang", /^vue-template$/i, "vue"],
diff --git a/gui/public/codemirror/mode/webidl/index.html b/gui/public/codemirror/mode/webidl/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/webidl/webidl.js b/gui/public/codemirror/mode/webidl/webidl.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/xml/index.html b/gui/public/codemirror/mode/xml/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/xml/test.js b/gui/public/codemirror/mode/xml/test.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/xml/xml.js b/gui/public/codemirror/mode/xml/xml.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/xquery/index.html b/gui/public/codemirror/mode/xquery/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/xquery/test.js b/gui/public/codemirror/mode/xquery/test.js
old mode 100755
new mode 100644
index 1f148cdb..9697f9b0
--- a/gui/public/codemirror/mode/xquery/test.js
+++ b/gui/public/codemirror/mode/xquery/test.js
@@ -20,14 +20,14 @@
" [def&variable fn:doc]()[[ [variable foo][keyword /][variable @bar] [keyword eq] [variable $let] ]],",
" [keyword //][variable x] } [comment (: a more 'evil' test :)]",
" [comment (: Modified Blakeley example (: with nested comment :) ... :)]",
- " [keyword declare] [keyword private] [keyword function] [def&variable local:declare]() {()}[variable ;]",
- " [keyword declare] [keyword private] [keyword function] [def&variable local:private]() {()}[variable ;]",
- " [keyword declare] [keyword private] [keyword function] [def&variable local:function]() {()}[variable ;]",
- " [keyword declare] [keyword private] [keyword function] [def&variable local:local]() {()}[variable ;]",
+ " [keyword declare] [variable private] [keyword function] [def&variable local:declare]() {()}[variable ;]",
+ " [keyword declare] [variable private] [keyword function] [def&variable local:private]() {()}[variable ;]",
+ " [keyword declare] [variable private] [keyword function] [def&variable local:function]() {()}[variable ;]",
+ " [keyword declare] [variable private] [keyword function] [def&variable local:local]() {()}[variable ;]",
" [keyword let] [variable $let] [keyword :=] [variable <let>let] [variable $let] [keyword :=] [variable "let"<][keyword /let][variable >]",
" [keyword return] [keyword element] [variable element] {",
" [keyword attribute] [variable attribute] { [keyword try] { [def&variable xdmp:version]() } [keyword catch]([variable $e]) { [def&variable xdmp:log]([variable $e]) } },",
- " [keyword attribute] [variable fn:doc] { [variable "bar"] [variable castable] [keyword as] [atom xs:string] },",
+ " [keyword attribute] [variable fn:doc] { [variable "bar"] [keyword castable] [keyword as] [atom xs:string] },",
" [keyword element] [variable text] { [keyword text] { [variable "text"] } },",
" [def&variable fn:doc]()[[ [qualifier child::][variable eq][keyword /]([variable @bar] [keyword |] [qualifier attribute::][variable attribute]) [keyword eq] [variable $let] ]],",
" [keyword //][variable fn:doc]",
diff --git a/gui/public/codemirror/mode/xquery/xquery.js b/gui/public/codemirror/mode/xquery/xquery.js
old mode 100755
new mode 100644
index 75dcbee3..f5db831c
--- a/gui/public/codemirror/mode/xquery/xquery.js
+++ b/gui/public/codemirror/mode/xquery/xquery.js
@@ -19,41 +19,52 @@ CodeMirror.defineMode("xquery", function() {
var keywords = function(){
// convenience functions used to build keywords object
function kw(type) {return {type: type, style: "keyword"};}
- var A = kw("keyword a")
- , B = kw("keyword b")
- , C = kw("keyword c")
- , operator = kw("operator")
+ var operator = kw("operator")
, atom = {type: "atom", style: "atom"}
, punctuation = {type: "punctuation", style: null}
, qualifier = {type: "axis_specifier", style: "qualifier"};
// kwObj is what is return from this function at the end
var kwObj = {
- 'if': A, 'switch': A, 'while': A, 'for': A,
- 'else': B, 'then': B, 'try': B, 'finally': B, 'catch': B,
- 'element': C, 'attribute': C, 'let': C, 'implements': C, 'import': C, 'module': C, 'namespace': C,
- 'return': C, 'super': C, 'this': C, 'throws': C, 'where': C, 'private': C,
- ',': punctuation,
- 'null': atom, 'fn:false()': atom, 'fn:true()': atom
+ ',': punctuation
};
// a list of 'basic' keywords. For each add a property to kwObj with the value of
// {type: basic[i], style: "keyword"} e.g. 'after' --> {type: "after", style: "keyword"}
- var basic = ['after','ancestor','ancestor-or-self','and','as','ascending','assert','attribute','before',
- 'by','case','cast','child','comment','declare','default','define','descendant','descendant-or-self',
- 'descending','document','document-node','element','else','eq','every','except','external','following',
- 'following-sibling','follows','for','function','if','import','in','instance','intersect','item',
- 'let','module','namespace','node','node','of','only','or','order','parent','precedes','preceding',
- 'preceding-sibling','processing-instruction','ref','return','returns','satisfies','schema','schema-element',
- 'self','some','sortby','stable','text','then','to','treat','typeswitch','union','variable','version','where',
- 'xquery', 'empty-sequence'];
+ var basic = ['after', 'all', 'allowing', 'ancestor', 'ancestor-or-self', 'any', 'array', 'as',
+ 'ascending', 'at', 'attribute', 'base-uri', 'before', 'boundary-space', 'by', 'case', 'cast',
+ 'castable', 'catch', 'child', 'collation', 'comment', 'construction', 'contains', 'content',
+ 'context', 'copy', 'copy-namespaces', 'count', 'decimal-format', 'declare', 'default', 'delete',
+ 'descendant', 'descendant-or-self', 'descending', 'diacritics', 'different', 'distance',
+ 'document', 'document-node', 'element', 'else', 'empty', 'empty-sequence', 'encoding', 'end',
+ 'entire', 'every', 'exactly', 'except', 'external', 'first', 'following', 'following-sibling',
+ 'for', 'from', 'ftand', 'ftnot', 'ft-option', 'ftor', 'function', 'fuzzy', 'greatest', 'group',
+ 'if', 'import', 'in', 'inherit', 'insensitive', 'insert', 'instance', 'intersect', 'into',
+ 'invoke', 'is', 'item', 'language', 'last', 'lax', 'least', 'let', 'levels', 'lowercase', 'map',
+ 'modify', 'module', 'most', 'namespace', 'next', 'no', 'node', 'nodes', 'no-inherit',
+ 'no-preserve', 'not', 'occurs', 'of', 'only', 'option', 'order', 'ordered', 'ordering',
+ 'paragraph', 'paragraphs', 'parent', 'phrase', 'preceding', 'preceding-sibling', 'preserve',
+ 'previous', 'processing-instruction', 'relationship', 'rename', 'replace', 'return',
+ 'revalidation', 'same', 'satisfies', 'schema', 'schema-attribute', 'schema-element', 'score',
+ 'self', 'sensitive', 'sentence', 'sentences', 'sequence', 'skip', 'sliding', 'some', 'stable',
+ 'start', 'stemming', 'stop', 'strict', 'strip', 'switch', 'text', 'then', 'thesaurus', 'times',
+ 'to', 'transform', 'treat', 'try', 'tumbling', 'type', 'typeswitch', 'union', 'unordered',
+ 'update', 'updating', 'uppercase', 'using', 'validate', 'value', 'variable', 'version',
+ 'weight', 'when', 'where', 'wildcards', 'window', 'with', 'without', 'word', 'words', 'xquery'];
for(var i=0, l=basic.length; i < l; i++) { kwObj[basic[i]] = kw(basic[i]);};
// a list of types. For each add a property to kwObj with the value of
// {type: "atom", style: "atom"}
- var types = ['xs:string', 'xs:float', 'xs:decimal', 'xs:double', 'xs:integer', 'xs:boolean', 'xs:date', 'xs:dateTime',
- 'xs:time', 'xs:duration', 'xs:dayTimeDuration', 'xs:time', 'xs:yearMonthDuration', 'numeric', 'xs:hexBinary',
- 'xs:base64Binary', 'xs:anyURI', 'xs:QName', 'xs:byte','xs:boolean','xs:anyURI','xf:yearMonthDuration'];
+ var types = ['xs:anyAtomicType', 'xs:anySimpleType', 'xs:anyType', 'xs:anyURI',
+ 'xs:base64Binary', 'xs:boolean', 'xs:byte', 'xs:date', 'xs:dateTime', 'xs:dateTimeStamp',
+ 'xs:dayTimeDuration', 'xs:decimal', 'xs:double', 'xs:duration', 'xs:ENTITIES', 'xs:ENTITY',
+ 'xs:float', 'xs:gDay', 'xs:gMonth', 'xs:gMonthDay', 'xs:gYear', 'xs:gYearMonth', 'xs:hexBinary',
+ 'xs:ID', 'xs:IDREF', 'xs:IDREFS', 'xs:int', 'xs:integer', 'xs:item', 'xs:java', 'xs:language',
+ 'xs:long', 'xs:Name', 'xs:NCName', 'xs:negativeInteger', 'xs:NMTOKEN', 'xs:NMTOKENS',
+ 'xs:nonNegativeInteger', 'xs:nonPositiveInteger', 'xs:normalizedString', 'xs:NOTATION',
+ 'xs:numeric', 'xs:positiveInteger', 'xs:precisionDecimal', 'xs:QName', 'xs:short', 'xs:string',
+ 'xs:time', 'xs:token', 'xs:unsignedByte', 'xs:unsignedInt', 'xs:unsignedLong',
+ 'xs:unsignedShort', 'xs:untyped', 'xs:untypedAtomic', 'xs:yearMonthDuration'];
for(var i=0, l=types.length; i < l; i++) { kwObj[types[i]] = atom;};
// each operator will add a property to kwObj with value of {type: "operator", style: "keyword"}
@@ -102,7 +113,7 @@ CodeMirror.defineMode("xquery", function() {
}
// start code block
else if(ch == "{") {
- pushStateStack(state,{ type: "codeblock"});
+ pushStateStack(state, { type: "codeblock"});
return null;
}
// end code block
@@ -132,7 +143,7 @@ CodeMirror.defineMode("xquery", function() {
return chain(stream, state, tokenComment);
}
// quoted string
- else if ( !isEQName && (ch === '"' || ch === "'"))
+ else if (!isEQName && (ch === '"' || ch === "'"))
return chain(stream, state, tokenString(ch));
// variable
else if(ch === "$") {
diff --git a/gui/public/codemirror/mode/yacas/index.html b/gui/public/codemirror/mode/yacas/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/yacas/yacas.js b/gui/public/codemirror/mode/yacas/yacas.js
old mode 100755
new mode 100644
index 30bd60b2..34c84fbd
--- a/gui/public/codemirror/mode/yacas/yacas.js
+++ b/gui/public/codemirror/mode/yacas/yacas.js
@@ -125,7 +125,7 @@ CodeMirror.defineMode('yacas', function(_config, _parserConfig) {
}
// operators; note that operators like @@ or /; are matched separately for each symbol.
- if (stream.match(/(?:\\|\+|\-|\*|\/|,|;|\.|:|@|~|=|>|<|&|\||_|`|'|\^|\?|!|%)/, true, false)) {
+ if (stream.match(/(?:\\|\+|\-|\*|\/|,|;|\.|:|@|~|=|>|<|&|\||_|`|'|\^|\?|!|%|#)/, true, false)) {
return 'operator';
}
diff --git a/gui/public/codemirror/mode/yaml-frontmatter/index.html b/gui/public/codemirror/mode/yaml-frontmatter/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/yaml-frontmatter/yaml-frontmatter.js b/gui/public/codemirror/mode/yaml-frontmatter/yaml-frontmatter.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/yaml/index.html b/gui/public/codemirror/mode/yaml/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/yaml/yaml.js b/gui/public/codemirror/mode/yaml/yaml.js
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/z80/index.html b/gui/public/codemirror/mode/z80/index.html
old mode 100755
new mode 100644
diff --git a/gui/public/codemirror/mode/z80/z80.js b/gui/public/codemirror/mode/z80/z80.js
old mode 100755
new mode 100644