administrate-field-simple_mde_markdown 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.circleci/config.yml +72 -0
- data/.circleci/setup-rubygems.sh +3 -0
- data/.gitignore +11 -0
- data/.rspec +3 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +196 -0
- data/LICENSE.txt +21 -0
- data/README.md +44 -0
- data/Rakefile +8 -0
- data/administrate-field-simple_mde_markdown.gemspec +31 -0
- data/app/assets/javascripts/administrate-field-simple_mde_markdown/application.js +6 -0
- data/app/assets/stylesheets/administrate-field-simple_mde_markdown/application.css +3 -0
- data/app/views/fields/simple_mde_markdown/_form.html.erb +6 -0
- data/app/views/fields/simple_mde_markdown/_index.html.erb +1 -0
- data/app/views/fields/simple_mde_markdown/_show.html.erb +1 -0
- data/lib/administrate/field/simple_mde_markdown.rb +31 -0
- data/node_modules/.bin/marked +1 -0
- data/node_modules/codemirror-spell-checker/.eslintrc +23 -0
- data/node_modules/codemirror-spell-checker/.npmignore +2 -0
- data/node_modules/codemirror-spell-checker/.travis.yml +18 -0
- data/node_modules/codemirror-spell-checker/CONTRIBUTING 2.md +10 -0
- data/node_modules/codemirror-spell-checker/CONTRIBUTING.md +10 -0
- data/node_modules/codemirror-spell-checker/LICENSE +22 -0
- data/node_modules/codemirror-spell-checker/README.md +50 -0
- data/node_modules/codemirror-spell-checker/bower.json +27 -0
- data/node_modules/codemirror-spell-checker/debug/.spell-checker 2.css.icloud +0 -0
- data/node_modules/codemirror-spell-checker/debug/spell-checker.css +9 -0
- data/node_modules/codemirror-spell-checker/debug/spell-checker.debug.js +2844 -0
- data/node_modules/codemirror-spell-checker/debug/spell-checker.js +2841 -0
- data/node_modules/codemirror-spell-checker/dist/.spell-checker.min 2.css.icloud +0 -0
- data/node_modules/codemirror-spell-checker/dist/en_US.aff +201 -0
- data/node_modules/codemirror-spell-checker/dist/en_US.dic +62120 -0
- data/node_modules/codemirror-spell-checker/dist/spell-checker.min 2.js +7 -0
- data/node_modules/codemirror-spell-checker/dist/spell-checker.min.css +7 -0
- data/node_modules/codemirror-spell-checker/dist/spell-checker.min.js +7 -0
- data/node_modules/codemirror-spell-checker/gulpfile.js +94 -0
- data/node_modules/codemirror-spell-checker/package.json +75 -0
- data/node_modules/codemirror-spell-checker/src/css/spell-checker.css +3 -0
- data/node_modules/codemirror-spell-checker/src/data/en_US.aff +201 -0
- data/node_modules/codemirror-spell-checker/src/data/en_US.dic +62120 -0
- data/node_modules/codemirror-spell-checker/src/js/spell-checker.js +119 -0
- data/node_modules/codemirror/.package 2.json.icloud +0 -0
- data/node_modules/codemirror/AUTHORS +773 -0
- data/node_modules/codemirror/CHANGELOG.md +1486 -0
- data/node_modules/codemirror/CONTRIBUTING.md +92 -0
- data/node_modules/codemirror/LICENSE +21 -0
- data/node_modules/codemirror/README.md +49 -0
- data/node_modules/codemirror/addon/comment/comment.js +209 -0
- data/node_modules/codemirror/addon/comment/continuecomment.js +78 -0
- data/node_modules/codemirror/addon/dialog/dialog.css +32 -0
- data/node_modules/codemirror/addon/dialog/dialog.js +161 -0
- data/node_modules/codemirror/addon/display/autorefresh.js +47 -0
- data/node_modules/codemirror/addon/display/fullscreen.css +6 -0
- data/node_modules/codemirror/addon/display/fullscreen.js +41 -0
- data/node_modules/codemirror/addon/display/panel.js +127 -0
- data/node_modules/codemirror/addon/display/placeholder.js +63 -0
- data/node_modules/codemirror/addon/display/rulers.js +51 -0
- data/node_modules/codemirror/addon/edit/closebrackets.js +187 -0
- data/node_modules/codemirror/addon/edit/closetag.js +175 -0
- data/node_modules/codemirror/addon/edit/continuelist.js +89 -0
- data/node_modules/codemirror/addon/edit/matchbrackets.js +145 -0
- data/node_modules/codemirror/addon/edit/matchtags.js +66 -0
- data/node_modules/codemirror/addon/edit/trailingspace.js +27 -0
- data/node_modules/codemirror/addon/fold/brace-fold.js +105 -0
- data/node_modules/codemirror/addon/fold/comment-fold.js +59 -0
- data/node_modules/codemirror/addon/fold/foldcode.js +152 -0
- data/node_modules/codemirror/addon/fold/foldgutter.css +20 -0
- data/node_modules/codemirror/addon/fold/foldgutter.js +146 -0
- data/node_modules/codemirror/addon/fold/indent-fold.js +48 -0
- data/node_modules/codemirror/addon/fold/markdown-fold.js +49 -0
- data/node_modules/codemirror/addon/fold/xml-fold.js +184 -0
- data/node_modules/codemirror/addon/hint/anyword-hint.js +41 -0
- data/node_modules/codemirror/addon/hint/css-hint.js +60 -0
- data/node_modules/codemirror/addon/hint/html-hint.js +348 -0
- data/node_modules/codemirror/addon/hint/javascript-hint.js +157 -0
- data/node_modules/codemirror/addon/hint/show-hint.css +36 -0
- data/node_modules/codemirror/addon/hint/show-hint.js +434 -0
- data/node_modules/codemirror/addon/hint/sql-hint.js +299 -0
- data/node_modules/codemirror/addon/hint/xml-hint.js +110 -0
- data/node_modules/codemirror/addon/lint/coffeescript-lint.js +47 -0
- data/node_modules/codemirror/addon/lint/css-lint.js +40 -0
- data/node_modules/codemirror/addon/lint/html-lint.js +53 -0
- data/node_modules/codemirror/addon/lint/javascript-lint.js +63 -0
- data/node_modules/codemirror/addon/lint/json-lint.js +40 -0
- data/node_modules/codemirror/addon/lint/lint.css +73 -0
- data/node_modules/codemirror/addon/lint/lint.js +252 -0
- data/node_modules/codemirror/addon/lint/yaml-lint.js +41 -0
- data/node_modules/codemirror/addon/merge/merge.css +119 -0
- data/node_modules/codemirror/addon/merge/merge.js +1002 -0
- data/node_modules/codemirror/addon/mode/loadmode.js +64 -0
- data/node_modules/codemirror/addon/mode/multiplex.js +131 -0
- data/node_modules/codemirror/addon/mode/multiplex_test.js +33 -0
- data/node_modules/codemirror/addon/mode/overlay.js +90 -0
- data/node_modules/codemirror/addon/mode/simple.js +216 -0
- data/node_modules/codemirror/addon/runmode/colorize.js +40 -0
- data/node_modules/codemirror/addon/runmode/runmode-standalone.js +158 -0
- data/node_modules/codemirror/addon/runmode/runmode.js +72 -0
- data/node_modules/codemirror/addon/runmode/runmode.node.js +197 -0
- data/node_modules/codemirror/addon/scroll/annotatescrollbar.js +122 -0
- data/node_modules/codemirror/addon/scroll/scrollpastend.js +48 -0
- data/node_modules/codemirror/addon/scroll/simplescrollbars.css +66 -0
- data/node_modules/codemirror/addon/scroll/simplescrollbars.js +152 -0
- data/node_modules/codemirror/addon/search/jump-to-line.js +50 -0
- data/node_modules/codemirror/addon/search/match-highlighter.js +165 -0
- data/node_modules/codemirror/addon/search/matchesonscrollbar.css +8 -0
- data/node_modules/codemirror/addon/search/matchesonscrollbar.js +97 -0
- data/node_modules/codemirror/addon/search/search.js +258 -0
- data/node_modules/codemirror/addon/search/searchcursor.js +293 -0
- data/node_modules/codemirror/addon/selection/active-line.js +72 -0
- data/node_modules/codemirror/addon/selection/mark-selection.js +119 -0
- data/node_modules/codemirror/addon/selection/selection-pointer.js +98 -0
- data/node_modules/codemirror/addon/tern/tern.css +87 -0
- data/node_modules/codemirror/addon/tern/tern.js +718 -0
- data/node_modules/codemirror/addon/tern/worker.js +44 -0
- data/node_modules/codemirror/addon/wrap/hardwrap.js +145 -0
- data/node_modules/codemirror/bin/source-highlight +48 -0
- data/node_modules/codemirror/keymap/emacs.js +417 -0
- data/node_modules/codemirror/keymap/sublime.js +691 -0
- data/node_modules/codemirror/keymap/vim.js +5467 -0
- data/node_modules/codemirror/lib/codemirror.css +346 -0
- data/node_modules/codemirror/lib/codemirror.js +9698 -0
- data/node_modules/codemirror/mode/apl/apl.js +174 -0
- data/node_modules/codemirror/mode/asciiarmor/asciiarmor.js +74 -0
- data/node_modules/codemirror/mode/asn.1/asn.1.js +204 -0
- data/node_modules/codemirror/mode/asterisk/asterisk.js +196 -0
- data/node_modules/codemirror/mode/brainfuck/brainfuck.js +85 -0
- data/node_modules/codemirror/mode/clike/clike.js +879 -0
- data/node_modules/codemirror/mode/clojure/clojure.js +292 -0
- data/node_modules/codemirror/mode/cmake/cmake.js +97 -0
- data/node_modules/codemirror/mode/cobol/cobol.js +255 -0
- data/node_modules/codemirror/mode/coffeescript/coffeescript.js +359 -0
- data/node_modules/codemirror/mode/commonlisp/commonlisp.js +124 -0
- data/node_modules/codemirror/mode/crystal/crystal.js +433 -0
- data/node_modules/codemirror/mode/css/css.js +832 -0
- data/node_modules/codemirror/mode/cypher/cypher.js +150 -0
- data/node_modules/codemirror/mode/d/d.js +223 -0
- data/node_modules/codemirror/mode/dart/dart.js +157 -0
- data/node_modules/codemirror/mode/diff/diff.js +47 -0
- data/node_modules/codemirror/mode/django/django.js +356 -0
- data/node_modules/codemirror/mode/dockerfile/dockerfile.js +211 -0
- data/node_modules/codemirror/mode/dtd/dtd.js +142 -0
- data/node_modules/codemirror/mode/dylan/dylan.js +352 -0
- data/node_modules/codemirror/mode/ebnf/ebnf.js +195 -0
- data/node_modules/codemirror/mode/ecl/ecl.js +206 -0
- data/node_modules/codemirror/mode/eiffel/eiffel.js +160 -0
- data/node_modules/codemirror/mode/elm/elm.js +205 -0
- data/node_modules/codemirror/mode/erlang/erlang.js +619 -0
- data/node_modules/codemirror/mode/factor/factor.js +85 -0
- data/node_modules/codemirror/mode/fcl/fcl.js +173 -0
- data/node_modules/codemirror/mode/forth/forth.js +180 -0
- data/node_modules/codemirror/mode/fortran/fortran.js +188 -0
- data/node_modules/codemirror/mode/gas/gas.js +345 -0
- data/node_modules/codemirror/mode/gfm/gfm.js +129 -0
- data/node_modules/codemirror/mode/gherkin/gherkin.js +178 -0
- data/node_modules/codemirror/mode/go/go.js +187 -0
- data/node_modules/codemirror/mode/groovy/groovy.js +230 -0
- data/node_modules/codemirror/mode/haml/haml.js +161 -0
- data/node_modules/codemirror/mode/handlebars/handlebars.js +66 -0
- data/node_modules/codemirror/mode/haskell-literate/haskell-literate.js +43 -0
- data/node_modules/codemirror/mode/haskell/haskell.js +268 -0
- data/node_modules/codemirror/mode/haxe/haxe.js +515 -0
- data/node_modules/codemirror/mode/htmlembedded/htmlembedded.js +37 -0
- data/node_modules/codemirror/mode/htmlmixed/htmlmixed.js +152 -0
- data/node_modules/codemirror/mode/http/http.js +113 -0
- data/node_modules/codemirror/mode/idl/idl.js +290 -0
- data/node_modules/codemirror/mode/javascript/javascript.js +899 -0
- data/node_modules/codemirror/mode/jinja2/jinja2.js +144 -0
- data/node_modules/codemirror/mode/jsx/jsx.js +148 -0
- data/node_modules/codemirror/mode/julia/julia.js +433 -0
- data/node_modules/codemirror/mode/livescript/livescript.js +280 -0
- data/node_modules/codemirror/mode/lua/lua.js +159 -0
- data/node_modules/codemirror/mode/markdown/markdown.js +884 -0
- data/node_modules/codemirror/mode/mathematica/mathematica.js +176 -0
- data/node_modules/codemirror/mode/mbox/mbox.js +129 -0
- data/node_modules/codemirror/mode/meta.js +217 -0
- data/node_modules/codemirror/mode/mirc/mirc.js +193 -0
- data/node_modules/codemirror/mode/mllike/mllike.js +359 -0
- data/node_modules/codemirror/mode/modelica/modelica.js +245 -0
- data/node_modules/codemirror/mode/mscgen/mscgen.js +175 -0
- data/node_modules/codemirror/mode/mumps/mumps.js +148 -0
- data/node_modules/codemirror/mode/nginx/nginx.js +178 -0
- data/node_modules/codemirror/mode/nsis/nsis.js +95 -0
- data/node_modules/codemirror/mode/ntriples/ntriples.js +195 -0
- data/node_modules/codemirror/mode/octave/octave.js +139 -0
- data/node_modules/codemirror/mode/oz/oz.js +252 -0
- data/node_modules/codemirror/mode/pascal/pascal.js +121 -0
- data/node_modules/codemirror/mode/pegjs/pegjs.js +114 -0
- data/node_modules/codemirror/mode/perl/perl.js +837 -0
- data/node_modules/codemirror/mode/php/php.js +234 -0
- data/node_modules/codemirror/mode/pig/pig.js +178 -0
- data/node_modules/codemirror/mode/powershell/powershell.js +398 -0
- data/node_modules/codemirror/mode/properties/properties 2.js +78 -0
- data/node_modules/codemirror/mode/properties/properties.js +78 -0
- data/node_modules/codemirror/mode/protobuf/protobuf.js +69 -0
- data/node_modules/codemirror/mode/pug/pug.js +591 -0
- data/node_modules/codemirror/mode/puppet/puppet.js +220 -0
- data/node_modules/codemirror/mode/python/python.js +409 -0
- data/node_modules/codemirror/mode/q/q.js +139 -0
- data/node_modules/codemirror/mode/r/r.js +190 -0
- data/node_modules/codemirror/mode/rpm/changes/index.html +66 -0
- data/node_modules/codemirror/mode/rpm/rpm.js +109 -0
- data/node_modules/codemirror/mode/rst/rst.js +557 -0
- data/node_modules/codemirror/mode/ruby/ruby.js +296 -0
- data/node_modules/codemirror/mode/rust/rust.js +72 -0
- data/node_modules/codemirror/mode/sas/sas.js +303 -0
- data/node_modules/codemirror/mode/sass/sass.js +454 -0
- data/node_modules/codemirror/mode/scheme/scheme.js +265 -0
- data/node_modules/codemirror/mode/shell/shell.js +152 -0
- data/node_modules/codemirror/mode/sieve/sieve.js +193 -0
- data/node_modules/codemirror/mode/slim/slim.js +575 -0
- data/node_modules/codemirror/mode/smalltalk/smalltalk.js +168 -0
- data/node_modules/codemirror/mode/smarty/smarty.js +225 -0
- data/node_modules/codemirror/mode/solr/solr.js +104 -0
- data/node_modules/codemirror/mode/soy/soy 2.js +359 -0
- data/node_modules/codemirror/mode/soy/soy.js +235 -0
- data/node_modules/codemirror/mode/sparql/sparql.js +180 -0
- data/node_modules/codemirror/mode/spreadsheet/spreadsheet.js +112 -0
- data/node_modules/codemirror/mode/sql/sql.js +499 -0
- data/node_modules/codemirror/mode/stex/stex.js +264 -0
- data/node_modules/codemirror/mode/stylus/stylus.js +771 -0
- data/node_modules/codemirror/mode/swift/swift.js +219 -0
- data/node_modules/codemirror/mode/tcl/tcl.js +139 -0
- data/node_modules/codemirror/mode/textile/textile.js +469 -0
- data/node_modules/codemirror/mode/tiddlywiki/tiddlywiki.css +14 -0
- data/node_modules/codemirror/mode/tiddlywiki/tiddlywiki.js +308 -0
- data/node_modules/codemirror/mode/tiki/tiki.css +26 -0
- data/node_modules/codemirror/mode/tiki/tiki.js +312 -0
- data/node_modules/codemirror/mode/toml/toml.js +88 -0
- data/node_modules/codemirror/mode/tornado/tornado.js +68 -0
- data/node_modules/codemirror/mode/troff/troff.js +84 -0
- data/node_modules/codemirror/mode/ttcn-cfg/ttcn-cfg.js +214 -0
- data/node_modules/codemirror/mode/ttcn/ttcn.js +283 -0
- data/node_modules/codemirror/mode/turtle/turtle.js +162 -0
- data/node_modules/codemirror/mode/twig/twig.js +141 -0
- data/node_modules/codemirror/mode/vb/vb.js +275 -0
- data/node_modules/codemirror/mode/vbscript/vbscript.js +350 -0
- data/node_modules/codemirror/mode/velocity/velocity.js +201 -0
- data/node_modules/codemirror/mode/verilog/verilog.js +675 -0
- data/node_modules/codemirror/mode/vhdl/vhdl.js +189 -0
- data/node_modules/codemirror/mode/vue/vue.js +77 -0
- data/node_modules/codemirror/mode/webidl/webidl.js +195 -0
- data/node_modules/codemirror/mode/xml/xml.js +402 -0
- data/node_modules/codemirror/mode/xquery/xquery.js +448 -0
- data/node_modules/codemirror/mode/yacas/yacas.js +204 -0
- data/node_modules/codemirror/mode/yaml-frontmatter/yaml-frontmatter.js +68 -0
- data/node_modules/codemirror/mode/yaml/yaml.js +120 -0
- data/node_modules/codemirror/mode/z80/z80.js +116 -0
- data/node_modules/codemirror/package.json +2395 -0
- data/node_modules/codemirror/rollup.config.js +20 -0
- data/node_modules/codemirror/src/codemirror.js +3 -0
- data/node_modules/codemirror/src/display/Display.js +106 -0
- data/node_modules/codemirror/src/display/focus.js +47 -0
- data/node_modules/codemirror/src/display/gutters.js +34 -0
- data/node_modules/codemirror/src/display/highlight_worker.js +55 -0
- data/node_modules/codemirror/src/display/line_numbers.js +48 -0
- data/node_modules/codemirror/src/display/mode_state.js +22 -0
- data/node_modules/codemirror/src/display/operations.js +205 -0
- data/node_modules/codemirror/src/display/scroll_events.js +115 -0
- data/node_modules/codemirror/src/display/scrollbars.js +193 -0
- data/node_modules/codemirror/src/display/scrolling.js +184 -0
- data/node_modules/codemirror/src/display/selection.js +158 -0
- data/node_modules/codemirror/src/display/update_display.js +260 -0
- data/node_modules/codemirror/src/display/update_line.js +188 -0
- data/node_modules/codemirror/src/display/update_lines.js +64 -0
- data/node_modules/codemirror/src/display/view_tracking.js +153 -0
- data/node_modules/codemirror/src/edit/CodeMirror.js +215 -0
- data/node_modules/codemirror/src/edit/commands.js +178 -0
- data/node_modules/codemirror/src/edit/deleteNearSelection.js +30 -0
- data/node_modules/codemirror/src/edit/drop_events.js +119 -0
- data/node_modules/codemirror/src/edit/fromTextArea.js +61 -0
- data/node_modules/codemirror/src/edit/global_events.js +42 -0
- data/node_modules/codemirror/src/edit/key_events.js +159 -0
- data/node_modules/codemirror/src/edit/legacy.js +62 -0
- data/node_modules/codemirror/src/edit/main.js +69 -0
- data/node_modules/codemirror/src/edit/methods.js +544 -0
- data/node_modules/codemirror/src/edit/mouse_events.js +407 -0
- data/node_modules/codemirror/src/edit/options.js +193 -0
- data/node_modules/codemirror/src/edit/utils.js +7 -0
- data/node_modules/codemirror/src/input/ContentEditableInput.js +527 -0
- data/node_modules/codemirror/src/input/TextareaInput.js +355 -0
- data/node_modules/codemirror/src/input/indent.js +71 -0
- data/node_modules/codemirror/src/input/input.js +135 -0
- data/node_modules/codemirror/src/input/keymap.js +148 -0
- data/node_modules/codemirror/src/input/keynames.js +17 -0
- data/node_modules/codemirror/src/input/movement.js +110 -0
- data/node_modules/codemirror/src/line/highlight.js +284 -0
- data/node_modules/codemirror/src/line/line_data.js +339 -0
- data/node_modules/codemirror/src/line/pos.js +40 -0
- data/node_modules/codemirror/src/line/saw_special_spans.js +10 -0
- data/node_modules/codemirror/src/line/spans.js +382 -0
- data/node_modules/codemirror/src/line/utils_line.js +85 -0
- data/node_modules/codemirror/src/measurement/position_measurement.js +699 -0
- data/node_modules/codemirror/src/measurement/widgets.js +26 -0
- data/node_modules/codemirror/src/model/Doc.js +432 -0
- data/node_modules/codemirror/src/model/change_measurement.js +61 -0
- data/node_modules/codemirror/src/model/changes.js +333 -0
- data/node_modules/codemirror/src/model/chunk.js +167 -0
- data/node_modules/codemirror/src/model/document_data.js +111 -0
- data/node_modules/codemirror/src/model/history.js +228 -0
- data/node_modules/codemirror/src/model/line_widget.js +78 -0
- data/node_modules/codemirror/src/model/mark_text.js +292 -0
- data/node_modules/codemirror/src/model/selection.js +84 -0
- data/node_modules/codemirror/src/model/selection_updates.js +208 -0
- data/node_modules/codemirror/src/modes.js +96 -0
- data/node_modules/codemirror/src/util/StringStream.js +90 -0
- data/node_modules/codemirror/src/util/bidi.js +214 -0
- data/node_modules/codemirror/src/util/browser.js +33 -0
- data/node_modules/codemirror/src/util/dom.js +97 -0
- data/node_modules/codemirror/src/util/event.js +103 -0
- data/node_modules/codemirror/src/util/feature_detection.js +84 -0
- data/node_modules/codemirror/src/util/misc.js +150 -0
- data/node_modules/codemirror/src/util/operation_group.js +72 -0
- data/node_modules/codemirror/theme/3024-day.css +41 -0
- data/node_modules/codemirror/theme/3024-night.css +39 -0
- data/node_modules/codemirror/theme/abcdef.css +32 -0
- data/node_modules/codemirror/theme/ambiance-mobile.css +5 -0
- data/node_modules/codemirror/theme/ambiance.css +74 -0
- data/node_modules/codemirror/theme/base16-dark.css +38 -0
- data/node_modules/codemirror/theme/base16-light.css +38 -0
- data/node_modules/codemirror/theme/bespin.css +34 -0
- data/node_modules/codemirror/theme/blackboard.css +32 -0
- data/node_modules/codemirror/theme/cobalt.css +25 -0
- data/node_modules/codemirror/theme/colorforth.css +33 -0
- data/node_modules/codemirror/theme/darcula.css +46 -0
- data/node_modules/codemirror/theme/dracula.css +40 -0
- data/node_modules/codemirror/theme/duotone-dark.css +35 -0
- data/node_modules/codemirror/theme/duotone-light.css +36 -0
- data/node_modules/codemirror/theme/eclipse.css +23 -0
- data/node_modules/codemirror/theme/elegant.css +13 -0
- data/node_modules/codemirror/theme/erlang-dark.css +34 -0
- data/node_modules/codemirror/theme/gruvbox-dark.css +37 -0
- data/node_modules/codemirror/theme/hopscotch.css +34 -0
- data/node_modules/codemirror/theme/icecoder.css +43 -0
- data/node_modules/codemirror/theme/idea.css +42 -0
- data/node_modules/codemirror/theme/isotope.css +34 -0
- data/node_modules/codemirror/theme/lesser-dark.css +47 -0
- data/node_modules/codemirror/theme/liquibyte.css +95 -0
- data/node_modules/codemirror/theme/lucario.css +37 -0
- data/node_modules/codemirror/theme/material.css +53 -0
- data/node_modules/codemirror/theme/mbo.css +37 -0
- data/node_modules/codemirror/theme/mdn-like.css +46 -0
- data/node_modules/codemirror/theme/midnight.css +43 -0
- data/node_modules/codemirror/theme/monokai.css +41 -0
- data/node_modules/codemirror/theme/neat.css +12 -0
- data/node_modules/codemirror/theme/neo.css +43 -0
- data/node_modules/codemirror/theme/night.css +27 -0
- data/node_modules/codemirror/theme/oceanic-next.css +44 -0
- data/node_modules/codemirror/theme/panda-syntax.css +85 -0
- data/node_modules/codemirror/theme/paraiso-dark.css +38 -0
- data/node_modules/codemirror/theme/paraiso-light.css +38 -0
- data/node_modules/codemirror/theme/pastel-on-dark.css +52 -0
- data/node_modules/codemirror/theme/railscasts.css +34 -0
- data/node_modules/codemirror/theme/rubyblue.css +25 -0
- data/node_modules/codemirror/theme/seti.css +44 -0
- data/node_modules/codemirror/theme/shadowfox.css +52 -0
- data/node_modules/codemirror/theme/solarized.css +168 -0
- data/node_modules/codemirror/theme/ssms.css +16 -0
- data/node_modules/codemirror/theme/the-matrix.css +30 -0
- data/node_modules/codemirror/theme/tomorrow-night-bright.css +35 -0
- data/node_modules/codemirror/theme/tomorrow-night-eighties.css +38 -0
- data/node_modules/codemirror/theme/ttcn.css +64 -0
- data/node_modules/codemirror/theme/twilight.css +32 -0
- data/node_modules/codemirror/theme/vibrant-ink.css +34 -0
- data/node_modules/codemirror/theme/xq-dark.css +53 -0
- data/node_modules/codemirror/theme/xq-light.css +43 -0
- data/node_modules/codemirror/theme/yeti.css +44 -0
- data/node_modules/codemirror/theme/zenburn.css +37 -0
- data/node_modules/marked/.editorconfig +16 -0
- data/node_modules/marked/.eslintignore +1 -0
- data/node_modules/marked/.eslintrc.json +28 -0
- data/node_modules/marked/.package 2.json.icloud +0 -0
- data/node_modules/marked/.travis.yml +47 -0
- data/node_modules/marked/Makefile +15 -0
- data/node_modules/marked/Makefile 2 +15 -0
- data/node_modules/marked/README 2.md +75 -0
- data/node_modules/marked/README.md +75 -0
- data/node_modules/marked/bin/marked +199 -0
- data/node_modules/marked/bower.json +23 -0
- data/node_modules/marked/component.json +10 -0
- data/node_modules/marked/index.js +1 -0
- data/node_modules/marked/jasmine.json +11 -0
- data/node_modules/marked/lib/marked 2.js +1604 -0
- data/node_modules/marked/lib/marked.js +1604 -0
- data/node_modules/marked/man/marked.1 +91 -0
- data/node_modules/marked/man/marked.1.txt +96 -0
- data/node_modules/marked/marked.min.js +6 -0
- data/node_modules/marked/package.json +95 -0
- data/node_modules/simplemde/.eslintrc +23 -0
- data/node_modules/simplemde/.npmignore +9 -0
- data/node_modules/simplemde/.travis.yml +18 -0
- data/node_modules/simplemde/CONTRIBUTING 2.md +10 -0
- data/node_modules/simplemde/CONTRIBUTING.md +10 -0
- data/node_modules/simplemde/LICENSE +22 -0
- data/node_modules/simplemde/README.md +331 -0
- data/node_modules/simplemde/bower.json +23 -0
- data/node_modules/simplemde/debug/.simplemde 2.css.icloud +0 -0
- data/node_modules/simplemde/debug/simplemde.css +676 -0
- data/node_modules/simplemde/debug/simplemde.debug.js +17023 -0
- data/node_modules/simplemde/debug/simplemde.js +17019 -0
- data/node_modules/simplemde/dist/simplemde.min.css +7 -0
- data/node_modules/simplemde/dist/simplemde.min.js +15 -0
- data/node_modules/simplemde/gulpfile.js +96 -0
- data/node_modules/simplemde/package.json +73 -0
- data/node_modules/simplemde/src/css/simplemde.css +328 -0
- data/node_modules/simplemde/src/js/codemirror/tablist 2.js +44 -0
- data/node_modules/simplemde/src/js/codemirror/tablist.js +44 -0
- data/node_modules/simplemde/src/js/simplemde.js +2028 -0
- data/node_modules/typo-js/README.md +45 -0
- data/node_modules/typo-js/dictionaries/en_US/.en_US 2.dic.icloud +0 -0
- data/node_modules/typo-js/dictionaries/en_US/README.md +7 -0
- data/node_modules/typo-js/dictionaries/en_US/en_US.aff +201 -0
- data/node_modules/typo-js/dictionaries/en_US/en_US.dic +62120 -0
- data/node_modules/typo-js/package.json +56 -0
- data/node_modules/typo-js/typo.js +931 -0
- data/package-lock.json +40 -0
- data/package.json +7 -0
- metadata +557 -0
@@ -0,0 +1,85 @@
|
|
1
|
+
import { indexOf } from "../util/misc.js"
|
2
|
+
|
3
|
+
// Find the line object corresponding to the given line number.
|
4
|
+
export function getLine(doc, n) {
|
5
|
+
n -= doc.first
|
6
|
+
if (n < 0 || n >= doc.size) throw new Error("There is no line " + (n + doc.first) + " in the document.")
|
7
|
+
let chunk = doc
|
8
|
+
while (!chunk.lines) {
|
9
|
+
for (let i = 0;; ++i) {
|
10
|
+
let child = chunk.children[i], sz = child.chunkSize()
|
11
|
+
if (n < sz) { chunk = child; break }
|
12
|
+
n -= sz
|
13
|
+
}
|
14
|
+
}
|
15
|
+
return chunk.lines[n]
|
16
|
+
}
|
17
|
+
|
18
|
+
// Get the part of a document between two positions, as an array of
|
19
|
+
// strings.
|
20
|
+
export function getBetween(doc, start, end) {
|
21
|
+
let out = [], n = start.line
|
22
|
+
doc.iter(start.line, end.line + 1, line => {
|
23
|
+
let text = line.text
|
24
|
+
if (n == end.line) text = text.slice(0, end.ch)
|
25
|
+
if (n == start.line) text = text.slice(start.ch)
|
26
|
+
out.push(text)
|
27
|
+
++n
|
28
|
+
})
|
29
|
+
return out
|
30
|
+
}
|
31
|
+
// Get the lines between from and to, as array of strings.
|
32
|
+
export function getLines(doc, from, to) {
|
33
|
+
let out = []
|
34
|
+
doc.iter(from, to, line => { out.push(line.text) }) // iter aborts when callback returns truthy value
|
35
|
+
return out
|
36
|
+
}
|
37
|
+
|
38
|
+
// Update the height of a line, propagating the height change
|
39
|
+
// upwards to parent nodes.
|
40
|
+
export function updateLineHeight(line, height) {
|
41
|
+
let diff = height - line.height
|
42
|
+
if (diff) for (let n = line; n; n = n.parent) n.height += diff
|
43
|
+
}
|
44
|
+
|
45
|
+
// Given a line object, find its line number by walking up through
|
46
|
+
// its parent links.
|
47
|
+
export function lineNo(line) {
|
48
|
+
if (line.parent == null) return null
|
49
|
+
let cur = line.parent, no = indexOf(cur.lines, line)
|
50
|
+
for (let chunk = cur.parent; chunk; cur = chunk, chunk = chunk.parent) {
|
51
|
+
for (let i = 0;; ++i) {
|
52
|
+
if (chunk.children[i] == cur) break
|
53
|
+
no += chunk.children[i].chunkSize()
|
54
|
+
}
|
55
|
+
}
|
56
|
+
return no + cur.first
|
57
|
+
}
|
58
|
+
|
59
|
+
// Find the line at the given vertical position, using the height
|
60
|
+
// information in the document tree.
|
61
|
+
export function lineAtHeight(chunk, h) {
|
62
|
+
let n = chunk.first
|
63
|
+
outer: do {
|
64
|
+
for (let i = 0; i < chunk.children.length; ++i) {
|
65
|
+
let child = chunk.children[i], ch = child.height
|
66
|
+
if (h < ch) { chunk = child; continue outer }
|
67
|
+
h -= ch
|
68
|
+
n += child.chunkSize()
|
69
|
+
}
|
70
|
+
return n
|
71
|
+
} while (!chunk.lines)
|
72
|
+
let i = 0
|
73
|
+
for (; i < chunk.lines.length; ++i) {
|
74
|
+
let line = chunk.lines[i], lh = line.height
|
75
|
+
if (h < lh) break
|
76
|
+
h -= lh
|
77
|
+
}
|
78
|
+
return n + i
|
79
|
+
}
|
80
|
+
|
81
|
+
export function isLine(doc, l) {return l >= doc.first && l < doc.first + doc.size}
|
82
|
+
|
83
|
+
export function lineNumberFor(options, i) {
|
84
|
+
return String(options.lineNumberFormatter(i + options.firstLineNumber))
|
85
|
+
}
|
@@ -0,0 +1,699 @@
|
|
1
|
+
import { buildLineContent, LineView } from "../line/line_data.js"
|
2
|
+
import { clipPos, Pos } from "../line/pos.js"
|
3
|
+
import { collapsedSpanAround, heightAtLine, lineIsHidden, visualLine } from "../line/spans.js"
|
4
|
+
import { getLine, lineAtHeight, lineNo, updateLineHeight } from "../line/utils_line.js"
|
5
|
+
import { bidiOther, getBidiPartAt, getOrder } from "../util/bidi.js"
|
6
|
+
import { chrome, android, ie, ie_version } from "../util/browser.js"
|
7
|
+
import { elt, removeChildren, range, removeChildrenAndAdd } from "../util/dom.js"
|
8
|
+
import { e_target } from "../util/event.js"
|
9
|
+
import { hasBadZoomedRects } from "../util/feature_detection.js"
|
10
|
+
import { countColumn, findFirst, isExtendingChar, scrollerGap, skipExtendingChars } from "../util/misc.js"
|
11
|
+
import { updateLineForChanges } from "../display/update_line.js"
|
12
|
+
|
13
|
+
import { widgetHeight } from "./widgets.js"
|
14
|
+
|
15
|
+
// POSITION MEASUREMENT
|
16
|
+
|
17
|
+
export function paddingTop(display) {return display.lineSpace.offsetTop}
|
18
|
+
export function paddingVert(display) {return display.mover.offsetHeight - display.lineSpace.offsetHeight}
|
19
|
+
export function paddingH(display) {
|
20
|
+
if (display.cachedPaddingH) return display.cachedPaddingH
|
21
|
+
let e = removeChildrenAndAdd(display.measure, elt("pre", "x"))
|
22
|
+
let style = window.getComputedStyle ? window.getComputedStyle(e) : e.currentStyle
|
23
|
+
let data = {left: parseInt(style.paddingLeft), right: parseInt(style.paddingRight)}
|
24
|
+
if (!isNaN(data.left) && !isNaN(data.right)) display.cachedPaddingH = data
|
25
|
+
return data
|
26
|
+
}
|
27
|
+
|
28
|
+
export function scrollGap(cm) { return scrollerGap - cm.display.nativeBarWidth }
|
29
|
+
export function displayWidth(cm) {
|
30
|
+
return cm.display.scroller.clientWidth - scrollGap(cm) - cm.display.barWidth
|
31
|
+
}
|
32
|
+
export function displayHeight(cm) {
|
33
|
+
return cm.display.scroller.clientHeight - scrollGap(cm) - cm.display.barHeight
|
34
|
+
}
|
35
|
+
|
36
|
+
// Ensure the lineView.wrapping.heights array is populated. This is
|
37
|
+
// an array of bottom offsets for the lines that make up a drawn
|
38
|
+
// line. When lineWrapping is on, there might be more than one
|
39
|
+
// height.
|
40
|
+
function ensureLineHeights(cm, lineView, rect) {
|
41
|
+
let wrapping = cm.options.lineWrapping
|
42
|
+
let curWidth = wrapping && displayWidth(cm)
|
43
|
+
if (!lineView.measure.heights || wrapping && lineView.measure.width != curWidth) {
|
44
|
+
let heights = lineView.measure.heights = []
|
45
|
+
if (wrapping) {
|
46
|
+
lineView.measure.width = curWidth
|
47
|
+
let rects = lineView.text.firstChild.getClientRects()
|
48
|
+
for (let i = 0; i < rects.length - 1; i++) {
|
49
|
+
let cur = rects[i], next = rects[i + 1]
|
50
|
+
if (Math.abs(cur.bottom - next.bottom) > 2)
|
51
|
+
heights.push((cur.bottom + next.top) / 2 - rect.top)
|
52
|
+
}
|
53
|
+
}
|
54
|
+
heights.push(rect.bottom - rect.top)
|
55
|
+
}
|
56
|
+
}
|
57
|
+
|
58
|
+
// Find a line map (mapping character offsets to text nodes) and a
|
59
|
+
// measurement cache for the given line number. (A line view might
|
60
|
+
// contain multiple lines when collapsed ranges are present.)
|
61
|
+
export function mapFromLineView(lineView, line, lineN) {
|
62
|
+
if (lineView.line == line)
|
63
|
+
return {map: lineView.measure.map, cache: lineView.measure.cache}
|
64
|
+
for (let i = 0; i < lineView.rest.length; i++)
|
65
|
+
if (lineView.rest[i] == line)
|
66
|
+
return {map: lineView.measure.maps[i], cache: lineView.measure.caches[i]}
|
67
|
+
for (let i = 0; i < lineView.rest.length; i++)
|
68
|
+
if (lineNo(lineView.rest[i]) > lineN)
|
69
|
+
return {map: lineView.measure.maps[i], cache: lineView.measure.caches[i], before: true}
|
70
|
+
}
|
71
|
+
|
72
|
+
// Render a line into the hidden node display.externalMeasured. Used
|
73
|
+
// when measurement is needed for a line that's not in the viewport.
|
74
|
+
function updateExternalMeasurement(cm, line) {
|
75
|
+
line = visualLine(line)
|
76
|
+
let lineN = lineNo(line)
|
77
|
+
let view = cm.display.externalMeasured = new LineView(cm.doc, line, lineN)
|
78
|
+
view.lineN = lineN
|
79
|
+
let built = view.built = buildLineContent(cm, view)
|
80
|
+
view.text = built.pre
|
81
|
+
removeChildrenAndAdd(cm.display.lineMeasure, built.pre)
|
82
|
+
return view
|
83
|
+
}
|
84
|
+
|
85
|
+
// Get a {top, bottom, left, right} box (in line-local coordinates)
|
86
|
+
// for a given character.
|
87
|
+
export function measureChar(cm, line, ch, bias) {
|
88
|
+
return measureCharPrepared(cm, prepareMeasureForLine(cm, line), ch, bias)
|
89
|
+
}
|
90
|
+
|
91
|
+
// Find a line view that corresponds to the given line number.
|
92
|
+
export function findViewForLine(cm, lineN) {
|
93
|
+
if (lineN >= cm.display.viewFrom && lineN < cm.display.viewTo)
|
94
|
+
return cm.display.view[findViewIndex(cm, lineN)]
|
95
|
+
let ext = cm.display.externalMeasured
|
96
|
+
if (ext && lineN >= ext.lineN && lineN < ext.lineN + ext.size)
|
97
|
+
return ext
|
98
|
+
}
|
99
|
+
|
100
|
+
// Measurement can be split in two steps, the set-up work that
|
101
|
+
// applies to the whole line, and the measurement of the actual
|
102
|
+
// character. Functions like coordsChar, that need to do a lot of
|
103
|
+
// measurements in a row, can thus ensure that the set-up work is
|
104
|
+
// only done once.
|
105
|
+
export function prepareMeasureForLine(cm, line) {
|
106
|
+
let lineN = lineNo(line)
|
107
|
+
let view = findViewForLine(cm, lineN)
|
108
|
+
if (view && !view.text) {
|
109
|
+
view = null
|
110
|
+
} else if (view && view.changes) {
|
111
|
+
updateLineForChanges(cm, view, lineN, getDimensions(cm))
|
112
|
+
cm.curOp.forceUpdate = true
|
113
|
+
}
|
114
|
+
if (!view)
|
115
|
+
view = updateExternalMeasurement(cm, line)
|
116
|
+
|
117
|
+
let info = mapFromLineView(view, line, lineN)
|
118
|
+
return {
|
119
|
+
line: line, view: view, rect: null,
|
120
|
+
map: info.map, cache: info.cache, before: info.before,
|
121
|
+
hasHeights: false
|
122
|
+
}
|
123
|
+
}
|
124
|
+
|
125
|
+
// Given a prepared measurement object, measures the position of an
|
126
|
+
// actual character (or fetches it from the cache).
|
127
|
+
export function measureCharPrepared(cm, prepared, ch, bias, varHeight) {
|
128
|
+
if (prepared.before) ch = -1
|
129
|
+
let key = ch + (bias || ""), found
|
130
|
+
if (prepared.cache.hasOwnProperty(key)) {
|
131
|
+
found = prepared.cache[key]
|
132
|
+
} else {
|
133
|
+
if (!prepared.rect)
|
134
|
+
prepared.rect = prepared.view.text.getBoundingClientRect()
|
135
|
+
if (!prepared.hasHeights) {
|
136
|
+
ensureLineHeights(cm, prepared.view, prepared.rect)
|
137
|
+
prepared.hasHeights = true
|
138
|
+
}
|
139
|
+
found = measureCharInner(cm, prepared, ch, bias)
|
140
|
+
if (!found.bogus) prepared.cache[key] = found
|
141
|
+
}
|
142
|
+
return {left: found.left, right: found.right,
|
143
|
+
top: varHeight ? found.rtop : found.top,
|
144
|
+
bottom: varHeight ? found.rbottom : found.bottom}
|
145
|
+
}
|
146
|
+
|
147
|
+
let nullRect = {left: 0, right: 0, top: 0, bottom: 0}
|
148
|
+
|
149
|
+
export function nodeAndOffsetInLineMap(map, ch, bias) {
|
150
|
+
let node, start, end, collapse, mStart, mEnd
|
151
|
+
// First, search the line map for the text node corresponding to,
|
152
|
+
// or closest to, the target character.
|
153
|
+
for (let i = 0; i < map.length; i += 3) {
|
154
|
+
mStart = map[i]
|
155
|
+
mEnd = map[i + 1]
|
156
|
+
if (ch < mStart) {
|
157
|
+
start = 0; end = 1
|
158
|
+
collapse = "left"
|
159
|
+
} else if (ch < mEnd) {
|
160
|
+
start = ch - mStart
|
161
|
+
end = start + 1
|
162
|
+
} else if (i == map.length - 3 || ch == mEnd && map[i + 3] > ch) {
|
163
|
+
end = mEnd - mStart
|
164
|
+
start = end - 1
|
165
|
+
if (ch >= mEnd) collapse = "right"
|
166
|
+
}
|
167
|
+
if (start != null) {
|
168
|
+
node = map[i + 2]
|
169
|
+
if (mStart == mEnd && bias == (node.insertLeft ? "left" : "right"))
|
170
|
+
collapse = bias
|
171
|
+
if (bias == "left" && start == 0)
|
172
|
+
while (i && map[i - 2] == map[i - 3] && map[i - 1].insertLeft) {
|
173
|
+
node = map[(i -= 3) + 2]
|
174
|
+
collapse = "left"
|
175
|
+
}
|
176
|
+
if (bias == "right" && start == mEnd - mStart)
|
177
|
+
while (i < map.length - 3 && map[i + 3] == map[i + 4] && !map[i + 5].insertLeft) {
|
178
|
+
node = map[(i += 3) + 2]
|
179
|
+
collapse = "right"
|
180
|
+
}
|
181
|
+
break
|
182
|
+
}
|
183
|
+
}
|
184
|
+
return {node: node, start: start, end: end, collapse: collapse, coverStart: mStart, coverEnd: mEnd}
|
185
|
+
}
|
186
|
+
|
187
|
+
function getUsefulRect(rects, bias) {
|
188
|
+
let rect = nullRect
|
189
|
+
if (bias == "left") for (let i = 0; i < rects.length; i++) {
|
190
|
+
if ((rect = rects[i]).left != rect.right) break
|
191
|
+
} else for (let i = rects.length - 1; i >= 0; i--) {
|
192
|
+
if ((rect = rects[i]).left != rect.right) break
|
193
|
+
}
|
194
|
+
return rect
|
195
|
+
}
|
196
|
+
|
197
|
+
function measureCharInner(cm, prepared, ch, bias) {
|
198
|
+
let place = nodeAndOffsetInLineMap(prepared.map, ch, bias)
|
199
|
+
let node = place.node, start = place.start, end = place.end, collapse = place.collapse
|
200
|
+
|
201
|
+
let rect
|
202
|
+
if (node.nodeType == 3) { // If it is a text node, use a range to retrieve the coordinates.
|
203
|
+
for (let i = 0; i < 4; i++) { // Retry a maximum of 4 times when nonsense rectangles are returned
|
204
|
+
while (start && isExtendingChar(prepared.line.text.charAt(place.coverStart + start))) --start
|
205
|
+
while (place.coverStart + end < place.coverEnd && isExtendingChar(prepared.line.text.charAt(place.coverStart + end))) ++end
|
206
|
+
if (ie && ie_version < 9 && start == 0 && end == place.coverEnd - place.coverStart)
|
207
|
+
rect = node.parentNode.getBoundingClientRect()
|
208
|
+
else
|
209
|
+
rect = getUsefulRect(range(node, start, end).getClientRects(), bias)
|
210
|
+
if (rect.left || rect.right || start == 0) break
|
211
|
+
end = start
|
212
|
+
start = start - 1
|
213
|
+
collapse = "right"
|
214
|
+
}
|
215
|
+
if (ie && ie_version < 11) rect = maybeUpdateRectForZooming(cm.display.measure, rect)
|
216
|
+
} else { // If it is a widget, simply get the box for the whole widget.
|
217
|
+
if (start > 0) collapse = bias = "right"
|
218
|
+
let rects
|
219
|
+
if (cm.options.lineWrapping && (rects = node.getClientRects()).length > 1)
|
220
|
+
rect = rects[bias == "right" ? rects.length - 1 : 0]
|
221
|
+
else
|
222
|
+
rect = node.getBoundingClientRect()
|
223
|
+
}
|
224
|
+
if (ie && ie_version < 9 && !start && (!rect || !rect.left && !rect.right)) {
|
225
|
+
let rSpan = node.parentNode.getClientRects()[0]
|
226
|
+
if (rSpan)
|
227
|
+
rect = {left: rSpan.left, right: rSpan.left + charWidth(cm.display), top: rSpan.top, bottom: rSpan.bottom}
|
228
|
+
else
|
229
|
+
rect = nullRect
|
230
|
+
}
|
231
|
+
|
232
|
+
let rtop = rect.top - prepared.rect.top, rbot = rect.bottom - prepared.rect.top
|
233
|
+
let mid = (rtop + rbot) / 2
|
234
|
+
let heights = prepared.view.measure.heights
|
235
|
+
let i = 0
|
236
|
+
for (; i < heights.length - 1; i++)
|
237
|
+
if (mid < heights[i]) break
|
238
|
+
let top = i ? heights[i - 1] : 0, bot = heights[i]
|
239
|
+
let result = {left: (collapse == "right" ? rect.right : rect.left) - prepared.rect.left,
|
240
|
+
right: (collapse == "left" ? rect.left : rect.right) - prepared.rect.left,
|
241
|
+
top: top, bottom: bot}
|
242
|
+
if (!rect.left && !rect.right) result.bogus = true
|
243
|
+
if (!cm.options.singleCursorHeightPerLine) { result.rtop = rtop; result.rbottom = rbot }
|
244
|
+
|
245
|
+
return result
|
246
|
+
}
|
247
|
+
|
248
|
+
// Work around problem with bounding client rects on ranges being
|
249
|
+
// returned incorrectly when zoomed on IE10 and below.
|
250
|
+
function maybeUpdateRectForZooming(measure, rect) {
|
251
|
+
if (!window.screen || screen.logicalXDPI == null ||
|
252
|
+
screen.logicalXDPI == screen.deviceXDPI || !hasBadZoomedRects(measure))
|
253
|
+
return rect
|
254
|
+
let scaleX = screen.logicalXDPI / screen.deviceXDPI
|
255
|
+
let scaleY = screen.logicalYDPI / screen.deviceYDPI
|
256
|
+
return {left: rect.left * scaleX, right: rect.right * scaleX,
|
257
|
+
top: rect.top * scaleY, bottom: rect.bottom * scaleY}
|
258
|
+
}
|
259
|
+
|
260
|
+
export function clearLineMeasurementCacheFor(lineView) {
|
261
|
+
if (lineView.measure) {
|
262
|
+
lineView.measure.cache = {}
|
263
|
+
lineView.measure.heights = null
|
264
|
+
if (lineView.rest) for (let i = 0; i < lineView.rest.length; i++)
|
265
|
+
lineView.measure.caches[i] = {}
|
266
|
+
}
|
267
|
+
}
|
268
|
+
|
269
|
+
export function clearLineMeasurementCache(cm) {
|
270
|
+
cm.display.externalMeasure = null
|
271
|
+
removeChildren(cm.display.lineMeasure)
|
272
|
+
for (let i = 0; i < cm.display.view.length; i++)
|
273
|
+
clearLineMeasurementCacheFor(cm.display.view[i])
|
274
|
+
}
|
275
|
+
|
276
|
+
export function clearCaches(cm) {
|
277
|
+
clearLineMeasurementCache(cm)
|
278
|
+
cm.display.cachedCharWidth = cm.display.cachedTextHeight = cm.display.cachedPaddingH = null
|
279
|
+
if (!cm.options.lineWrapping) cm.display.maxLineChanged = true
|
280
|
+
cm.display.lineNumChars = null
|
281
|
+
}
|
282
|
+
|
283
|
+
function pageScrollX() {
|
284
|
+
// Work around https://bugs.chromium.org/p/chromium/issues/detail?id=489206
|
285
|
+
// which causes page_Offset and bounding client rects to use
|
286
|
+
// different reference viewports and invalidate our calculations.
|
287
|
+
if (chrome && android) return -(document.body.getBoundingClientRect().left - parseInt(getComputedStyle(document.body).marginLeft))
|
288
|
+
return window.pageXOffset || (document.documentElement || document.body).scrollLeft
|
289
|
+
}
|
290
|
+
function pageScrollY() {
|
291
|
+
if (chrome && android) return -(document.body.getBoundingClientRect().top - parseInt(getComputedStyle(document.body).marginTop))
|
292
|
+
return window.pageYOffset || (document.documentElement || document.body).scrollTop
|
293
|
+
}
|
294
|
+
|
295
|
+
function widgetTopHeight(lineObj) {
|
296
|
+
let height = 0
|
297
|
+
if (lineObj.widgets) for (let i = 0; i < lineObj.widgets.length; ++i) if (lineObj.widgets[i].above)
|
298
|
+
height += widgetHeight(lineObj.widgets[i])
|
299
|
+
return height
|
300
|
+
}
|
301
|
+
|
302
|
+
// Converts a {top, bottom, left, right} box from line-local
|
303
|
+
// coordinates into another coordinate system. Context may be one of
|
304
|
+
// "line", "div" (display.lineDiv), "local"./null (editor), "window",
|
305
|
+
// or "page".
|
306
|
+
export function intoCoordSystem(cm, lineObj, rect, context, includeWidgets) {
|
307
|
+
if (!includeWidgets) {
|
308
|
+
let height = widgetTopHeight(lineObj)
|
309
|
+
rect.top += height; rect.bottom += height
|
310
|
+
}
|
311
|
+
if (context == "line") return rect
|
312
|
+
if (!context) context = "local"
|
313
|
+
let yOff = heightAtLine(lineObj)
|
314
|
+
if (context == "local") yOff += paddingTop(cm.display)
|
315
|
+
else yOff -= cm.display.viewOffset
|
316
|
+
if (context == "page" || context == "window") {
|
317
|
+
let lOff = cm.display.lineSpace.getBoundingClientRect()
|
318
|
+
yOff += lOff.top + (context == "window" ? 0 : pageScrollY())
|
319
|
+
let xOff = lOff.left + (context == "window" ? 0 : pageScrollX())
|
320
|
+
rect.left += xOff; rect.right += xOff
|
321
|
+
}
|
322
|
+
rect.top += yOff; rect.bottom += yOff
|
323
|
+
return rect
|
324
|
+
}
|
325
|
+
|
326
|
+
// Coverts a box from "div" coords to another coordinate system.
|
327
|
+
// Context may be "window", "page", "div", or "local"./null.
|
328
|
+
export function fromCoordSystem(cm, coords, context) {
|
329
|
+
if (context == "div") return coords
|
330
|
+
let left = coords.left, top = coords.top
|
331
|
+
// First move into "page" coordinate system
|
332
|
+
if (context == "page") {
|
333
|
+
left -= pageScrollX()
|
334
|
+
top -= pageScrollY()
|
335
|
+
} else if (context == "local" || !context) {
|
336
|
+
let localBox = cm.display.sizer.getBoundingClientRect()
|
337
|
+
left += localBox.left
|
338
|
+
top += localBox.top
|
339
|
+
}
|
340
|
+
|
341
|
+
let lineSpaceBox = cm.display.lineSpace.getBoundingClientRect()
|
342
|
+
return {left: left - lineSpaceBox.left, top: top - lineSpaceBox.top}
|
343
|
+
}
|
344
|
+
|
345
|
+
export function charCoords(cm, pos, context, lineObj, bias) {
|
346
|
+
if (!lineObj) lineObj = getLine(cm.doc, pos.line)
|
347
|
+
return intoCoordSystem(cm, lineObj, measureChar(cm, lineObj, pos.ch, bias), context)
|
348
|
+
}
|
349
|
+
|
350
|
+
// Returns a box for a given cursor position, which may have an
|
351
|
+
// 'other' property containing the position of the secondary cursor
|
352
|
+
// on a bidi boundary.
|
353
|
+
// A cursor Pos(line, char, "before") is on the same visual line as `char - 1`
|
354
|
+
// and after `char - 1` in writing order of `char - 1`
|
355
|
+
// A cursor Pos(line, char, "after") is on the same visual line as `char`
|
356
|
+
// and before `char` in writing order of `char`
|
357
|
+
// Examples (upper-case letters are RTL, lower-case are LTR):
|
358
|
+
// Pos(0, 1, ...)
|
359
|
+
// before after
|
360
|
+
// ab a|b a|b
|
361
|
+
// aB a|B aB|
|
362
|
+
// Ab |Ab A|b
|
363
|
+
// AB B|A B|A
|
364
|
+
// Every position after the last character on a line is considered to stick
|
365
|
+
// to the last character on the line.
|
366
|
+
export function cursorCoords(cm, pos, context, lineObj, preparedMeasure, varHeight) {
|
367
|
+
lineObj = lineObj || getLine(cm.doc, pos.line)
|
368
|
+
if (!preparedMeasure) preparedMeasure = prepareMeasureForLine(cm, lineObj)
|
369
|
+
function get(ch, right) {
|
370
|
+
let m = measureCharPrepared(cm, preparedMeasure, ch, right ? "right" : "left", varHeight)
|
371
|
+
if (right) m.left = m.right; else m.right = m.left
|
372
|
+
return intoCoordSystem(cm, lineObj, m, context)
|
373
|
+
}
|
374
|
+
let order = getOrder(lineObj, cm.doc.direction), ch = pos.ch, sticky = pos.sticky
|
375
|
+
if (ch >= lineObj.text.length) {
|
376
|
+
ch = lineObj.text.length
|
377
|
+
sticky = "before"
|
378
|
+
} else if (ch <= 0) {
|
379
|
+
ch = 0
|
380
|
+
sticky = "after"
|
381
|
+
}
|
382
|
+
if (!order) return get(sticky == "before" ? ch - 1 : ch, sticky == "before")
|
383
|
+
|
384
|
+
function getBidi(ch, partPos, invert) {
|
385
|
+
let part = order[partPos], right = part.level == 1
|
386
|
+
return get(invert ? ch - 1 : ch, right != invert)
|
387
|
+
}
|
388
|
+
let partPos = getBidiPartAt(order, ch, sticky)
|
389
|
+
let other = bidiOther
|
390
|
+
let val = getBidi(ch, partPos, sticky == "before")
|
391
|
+
if (other != null) val.other = getBidi(ch, other, sticky != "before")
|
392
|
+
return val
|
393
|
+
}
|
394
|
+
|
395
|
+
// Used to cheaply estimate the coordinates for a position. Used for
|
396
|
+
// intermediate scroll updates.
|
397
|
+
export function estimateCoords(cm, pos) {
|
398
|
+
let left = 0
|
399
|
+
pos = clipPos(cm.doc, pos)
|
400
|
+
if (!cm.options.lineWrapping) left = charWidth(cm.display) * pos.ch
|
401
|
+
let lineObj = getLine(cm.doc, pos.line)
|
402
|
+
let top = heightAtLine(lineObj) + paddingTop(cm.display)
|
403
|
+
return {left: left, right: left, top: top, bottom: top + lineObj.height}
|
404
|
+
}
|
405
|
+
|
406
|
+
// Positions returned by coordsChar contain some extra information.
|
407
|
+
// xRel is the relative x position of the input coordinates compared
|
408
|
+
// to the found position (so xRel > 0 means the coordinates are to
|
409
|
+
// the right of the character position, for example). When outside
|
410
|
+
// is true, that means the coordinates lie outside the line's
|
411
|
+
// vertical range.
|
412
|
+
function PosWithInfo(line, ch, sticky, outside, xRel) {
|
413
|
+
let pos = Pos(line, ch, sticky)
|
414
|
+
pos.xRel = xRel
|
415
|
+
if (outside) pos.outside = true
|
416
|
+
return pos
|
417
|
+
}
|
418
|
+
|
419
|
+
// Compute the character position closest to the given coordinates.
|
420
|
+
// Input must be lineSpace-local ("div" coordinate system).
|
421
|
+
export function coordsChar(cm, x, y) {
|
422
|
+
let doc = cm.doc
|
423
|
+
y += cm.display.viewOffset
|
424
|
+
if (y < 0) return PosWithInfo(doc.first, 0, null, true, -1)
|
425
|
+
let lineN = lineAtHeight(doc, y), last = doc.first + doc.size - 1
|
426
|
+
if (lineN > last)
|
427
|
+
return PosWithInfo(doc.first + doc.size - 1, getLine(doc, last).text.length, null, true, 1)
|
428
|
+
if (x < 0) x = 0
|
429
|
+
|
430
|
+
let lineObj = getLine(doc, lineN)
|
431
|
+
for (;;) {
|
432
|
+
let found = coordsCharInner(cm, lineObj, lineN, x, y)
|
433
|
+
let collapsed = collapsedSpanAround(lineObj, found.ch + (found.xRel > 0 ? 1 : 0))
|
434
|
+
if (!collapsed) return found
|
435
|
+
let rangeEnd = collapsed.find(1)
|
436
|
+
if (rangeEnd.line == lineN) return rangeEnd
|
437
|
+
lineObj = getLine(doc, lineN = rangeEnd.line)
|
438
|
+
}
|
439
|
+
}
|
440
|
+
|
441
|
+
function wrappedLineExtent(cm, lineObj, preparedMeasure, y) {
|
442
|
+
y -= widgetTopHeight(lineObj)
|
443
|
+
let end = lineObj.text.length
|
444
|
+
let begin = findFirst(ch => measureCharPrepared(cm, preparedMeasure, ch - 1).bottom <= y, end, 0)
|
445
|
+
end = findFirst(ch => measureCharPrepared(cm, preparedMeasure, ch).top > y, begin, end)
|
446
|
+
return {begin, end}
|
447
|
+
}
|
448
|
+
|
449
|
+
export function wrappedLineExtentChar(cm, lineObj, preparedMeasure, target) {
|
450
|
+
if (!preparedMeasure) preparedMeasure = prepareMeasureForLine(cm, lineObj)
|
451
|
+
let targetTop = intoCoordSystem(cm, lineObj, measureCharPrepared(cm, preparedMeasure, target), "line").top
|
452
|
+
return wrappedLineExtent(cm, lineObj, preparedMeasure, targetTop)
|
453
|
+
}
|
454
|
+
|
455
|
+
// Returns true if the given side of a box is after the given
|
456
|
+
// coordinates, in top-to-bottom, left-to-right order.
|
457
|
+
function boxIsAfter(box, x, y, left) {
|
458
|
+
return box.bottom <= y ? false : box.top > y ? true : (left ? box.left : box.right) > x
|
459
|
+
}
|
460
|
+
|
461
|
+
function coordsCharInner(cm, lineObj, lineNo, x, y) {
|
462
|
+
// Move y into line-local coordinate space
|
463
|
+
y -= heightAtLine(lineObj)
|
464
|
+
let preparedMeasure = prepareMeasureForLine(cm, lineObj)
|
465
|
+
// When directly calling `measureCharPrepared`, we have to adjust
|
466
|
+
// for the widgets at this line.
|
467
|
+
let widgetHeight = widgetTopHeight(lineObj)
|
468
|
+
let begin = 0, end = lineObj.text.length, ltr = true
|
469
|
+
|
470
|
+
let order = getOrder(lineObj, cm.doc.direction)
|
471
|
+
// If the line isn't plain left-to-right text, first figure out
|
472
|
+
// which bidi section the coordinates fall into.
|
473
|
+
if (order) {
|
474
|
+
let part = (cm.options.lineWrapping ? coordsBidiPartWrapped : coordsBidiPart)
|
475
|
+
(cm, lineObj, lineNo, preparedMeasure, order, x, y)
|
476
|
+
ltr = part.level != 1
|
477
|
+
// The awkward -1 offsets are needed because findFirst (called
|
478
|
+
// on these below) will treat its first bound as inclusive,
|
479
|
+
// second as exclusive, but we want to actually address the
|
480
|
+
// characters in the part's range
|
481
|
+
begin = ltr ? part.from : part.to - 1
|
482
|
+
end = ltr ? part.to : part.from - 1
|
483
|
+
}
|
484
|
+
|
485
|
+
// A binary search to find the first character whose bounding box
|
486
|
+
// starts after the coordinates. If we run across any whose box wrap
|
487
|
+
// the coordinates, store that.
|
488
|
+
let chAround = null, boxAround = null
|
489
|
+
let ch = findFirst(ch => {
|
490
|
+
let box = measureCharPrepared(cm, preparedMeasure, ch)
|
491
|
+
box.top += widgetHeight; box.bottom += widgetHeight
|
492
|
+
if (!boxIsAfter(box, x, y, false)) return false
|
493
|
+
if (box.top <= y && box.left <= x) {
|
494
|
+
chAround = ch
|
495
|
+
boxAround = box
|
496
|
+
}
|
497
|
+
return true
|
498
|
+
}, begin, end)
|
499
|
+
|
500
|
+
let baseX, sticky, outside = false
|
501
|
+
// If a box around the coordinates was found, use that
|
502
|
+
if (boxAround) {
|
503
|
+
// Distinguish coordinates nearer to the left or right side of the box
|
504
|
+
let atLeft = x - boxAround.left < boxAround.right - x, atStart = atLeft == ltr
|
505
|
+
ch = chAround + (atStart ? 0 : 1)
|
506
|
+
sticky = atStart ? "after" : "before"
|
507
|
+
baseX = atLeft ? boxAround.left : boxAround.right
|
508
|
+
} else {
|
509
|
+
// (Adjust for extended bound, if necessary.)
|
510
|
+
if (!ltr && (ch == end || ch == begin)) ch++
|
511
|
+
// To determine which side to associate with, get the box to the
|
512
|
+
// left of the character and compare it's vertical position to the
|
513
|
+
// coordinates
|
514
|
+
sticky = ch == 0 ? "after" : ch == lineObj.text.length ? "before" :
|
515
|
+
(measureCharPrepared(cm, preparedMeasure, ch - (ltr ? 1 : 0)).bottom + widgetHeight <= y) == ltr ?
|
516
|
+
"after" : "before"
|
517
|
+
// Now get accurate coordinates for this place, in order to get a
|
518
|
+
// base X position
|
519
|
+
let coords = cursorCoords(cm, Pos(lineNo, ch, sticky), "line", lineObj, preparedMeasure)
|
520
|
+
baseX = coords.left
|
521
|
+
outside = y < coords.top || y >= coords.bottom
|
522
|
+
}
|
523
|
+
|
524
|
+
ch = skipExtendingChars(lineObj.text, ch, 1)
|
525
|
+
return PosWithInfo(lineNo, ch, sticky, outside, x - baseX)
|
526
|
+
}
|
527
|
+
|
528
|
+
function coordsBidiPart(cm, lineObj, lineNo, preparedMeasure, order, x, y) {
|
529
|
+
// Bidi parts are sorted left-to-right, and in a non-line-wrapping
|
530
|
+
// situation, we can take this ordering to correspond to the visual
|
531
|
+
// ordering. This finds the first part whose end is after the given
|
532
|
+
// coordinates.
|
533
|
+
let index = findFirst(i => {
|
534
|
+
let part = order[i], ltr = part.level != 1
|
535
|
+
return boxIsAfter(cursorCoords(cm, Pos(lineNo, ltr ? part.to : part.from, ltr ? "before" : "after"),
|
536
|
+
"line", lineObj, preparedMeasure), x, y, true)
|
537
|
+
}, 0, order.length - 1)
|
538
|
+
let part = order[index]
|
539
|
+
// If this isn't the first part, the part's start is also after
|
540
|
+
// the coordinates, and the coordinates aren't on the same line as
|
541
|
+
// that start, move one part back.
|
542
|
+
if (index > 0) {
|
543
|
+
let ltr = part.level != 1
|
544
|
+
let start = cursorCoords(cm, Pos(lineNo, ltr ? part.from : part.to, ltr ? "after" : "before"),
|
545
|
+
"line", lineObj, preparedMeasure)
|
546
|
+
if (boxIsAfter(start, x, y, true) && start.top > y)
|
547
|
+
part = order[index - 1]
|
548
|
+
}
|
549
|
+
return part
|
550
|
+
}
|
551
|
+
|
552
|
+
function coordsBidiPartWrapped(cm, lineObj, _lineNo, preparedMeasure, order, x, y) {
|
553
|
+
// In a wrapped line, rtl text on wrapping boundaries can do things
|
554
|
+
// that don't correspond to the ordering in our `order` array at
|
555
|
+
// all, so a binary search doesn't work, and we want to return a
|
556
|
+
// part that only spans one line so that the binary search in
|
557
|
+
// coordsCharInner is safe. As such, we first find the extent of the
|
558
|
+
// wrapped line, and then do a flat search in which we discard any
|
559
|
+
// spans that aren't on the line.
|
560
|
+
let {begin, end} = wrappedLineExtent(cm, lineObj, preparedMeasure, y)
|
561
|
+
if (/\s/.test(lineObj.text.charAt(end - 1))) end--
|
562
|
+
let part = null, closestDist = null
|
563
|
+
for (let i = 0; i < order.length; i++) {
|
564
|
+
let p = order[i]
|
565
|
+
if (p.from >= end || p.to <= begin) continue
|
566
|
+
let ltr = p.level != 1
|
567
|
+
let endX = measureCharPrepared(cm, preparedMeasure, ltr ? Math.min(end, p.to) - 1 : Math.max(begin, p.from)).right
|
568
|
+
// Weigh against spans ending before this, so that they are only
|
569
|
+
// picked if nothing ends after
|
570
|
+
let dist = endX < x ? x - endX + 1e9 : endX - x
|
571
|
+
if (!part || closestDist > dist) {
|
572
|
+
part = p
|
573
|
+
closestDist = dist
|
574
|
+
}
|
575
|
+
}
|
576
|
+
if (!part) part = order[order.length - 1]
|
577
|
+
// Clip the part to the wrapped line.
|
578
|
+
if (part.from < begin) part = {from: begin, to: part.to, level: part.level}
|
579
|
+
if (part.to > end) part = {from: part.from, to: end, level: part.level}
|
580
|
+
return part
|
581
|
+
}
|
582
|
+
|
583
|
+
let measureText
|
584
|
+
// Compute the default text height.
|
585
|
+
export function textHeight(display) {
|
586
|
+
if (display.cachedTextHeight != null) return display.cachedTextHeight
|
587
|
+
if (measureText == null) {
|
588
|
+
measureText = elt("pre")
|
589
|
+
// Measure a bunch of lines, for browsers that compute
|
590
|
+
// fractional heights.
|
591
|
+
for (let i = 0; i < 49; ++i) {
|
592
|
+
measureText.appendChild(document.createTextNode("x"))
|
593
|
+
measureText.appendChild(elt("br"))
|
594
|
+
}
|
595
|
+
measureText.appendChild(document.createTextNode("x"))
|
596
|
+
}
|
597
|
+
removeChildrenAndAdd(display.measure, measureText)
|
598
|
+
let height = measureText.offsetHeight / 50
|
599
|
+
if (height > 3) display.cachedTextHeight = height
|
600
|
+
removeChildren(display.measure)
|
601
|
+
return height || 1
|
602
|
+
}
|
603
|
+
|
604
|
+
// Compute the default character width.
|
605
|
+
export function charWidth(display) {
|
606
|
+
if (display.cachedCharWidth != null) return display.cachedCharWidth
|
607
|
+
let anchor = elt("span", "xxxxxxxxxx")
|
608
|
+
let pre = elt("pre", [anchor])
|
609
|
+
removeChildrenAndAdd(display.measure, pre)
|
610
|
+
let rect = anchor.getBoundingClientRect(), width = (rect.right - rect.left) / 10
|
611
|
+
if (width > 2) display.cachedCharWidth = width
|
612
|
+
return width || 10
|
613
|
+
}
|
614
|
+
|
615
|
+
// Do a bulk-read of the DOM positions and sizes needed to draw the
|
616
|
+
// view, so that we don't interleave reading and writing to the DOM.
|
617
|
+
export function getDimensions(cm) {
|
618
|
+
let d = cm.display, left = {}, width = {}
|
619
|
+
let gutterLeft = d.gutters.clientLeft
|
620
|
+
for (let n = d.gutters.firstChild, i = 0; n; n = n.nextSibling, ++i) {
|
621
|
+
left[cm.options.gutters[i]] = n.offsetLeft + n.clientLeft + gutterLeft
|
622
|
+
width[cm.options.gutters[i]] = n.clientWidth
|
623
|
+
}
|
624
|
+
return {fixedPos: compensateForHScroll(d),
|
625
|
+
gutterTotalWidth: d.gutters.offsetWidth,
|
626
|
+
gutterLeft: left,
|
627
|
+
gutterWidth: width,
|
628
|
+
wrapperWidth: d.wrapper.clientWidth}
|
629
|
+
}
|
630
|
+
|
631
|
+
// Computes display.scroller.scrollLeft + display.gutters.offsetWidth,
|
632
|
+
// but using getBoundingClientRect to get a sub-pixel-accurate
|
633
|
+
// result.
|
634
|
+
export function compensateForHScroll(display) {
|
635
|
+
return display.scroller.getBoundingClientRect().left - display.sizer.getBoundingClientRect().left
|
636
|
+
}
|
637
|
+
|
638
|
+
// Returns a function that estimates the height of a line, to use as
|
639
|
+
// first approximation until the line becomes visible (and is thus
|
640
|
+
// properly measurable).
|
641
|
+
export function estimateHeight(cm) {
|
642
|
+
let th = textHeight(cm.display), wrapping = cm.options.lineWrapping
|
643
|
+
let perLine = wrapping && Math.max(5, cm.display.scroller.clientWidth / charWidth(cm.display) - 3)
|
644
|
+
return line => {
|
645
|
+
if (lineIsHidden(cm.doc, line)) return 0
|
646
|
+
|
647
|
+
let widgetsHeight = 0
|
648
|
+
if (line.widgets) for (let i = 0; i < line.widgets.length; i++) {
|
649
|
+
if (line.widgets[i].height) widgetsHeight += line.widgets[i].height
|
650
|
+
}
|
651
|
+
|
652
|
+
if (wrapping)
|
653
|
+
return widgetsHeight + (Math.ceil(line.text.length / perLine) || 1) * th
|
654
|
+
else
|
655
|
+
return widgetsHeight + th
|
656
|
+
}
|
657
|
+
}
|
658
|
+
|
659
|
+
export function estimateLineHeights(cm) {
|
660
|
+
let doc = cm.doc, est = estimateHeight(cm)
|
661
|
+
doc.iter(line => {
|
662
|
+
let estHeight = est(line)
|
663
|
+
if (estHeight != line.height) updateLineHeight(line, estHeight)
|
664
|
+
})
|
665
|
+
}
|
666
|
+
|
667
|
+
// Given a mouse event, find the corresponding position. If liberal
|
668
|
+
// is false, it checks whether a gutter or scrollbar was clicked,
|
669
|
+
// and returns null if it was. forRect is used by rectangular
|
670
|
+
// selections, and tries to estimate a character position even for
|
671
|
+
// coordinates beyond the right of the text.
|
672
|
+
export function posFromMouse(cm, e, liberal, forRect) {
|
673
|
+
let display = cm.display
|
674
|
+
if (!liberal && e_target(e).getAttribute("cm-not-content") == "true") return null
|
675
|
+
|
676
|
+
let x, y, space = display.lineSpace.getBoundingClientRect()
|
677
|
+
// Fails unpredictably on IE[67] when mouse is dragged around quickly.
|
678
|
+
try { x = e.clientX - space.left; y = e.clientY - space.top }
|
679
|
+
catch (e) { return null }
|
680
|
+
let coords = coordsChar(cm, x, y), line
|
681
|
+
if (forRect && coords.xRel == 1 && (line = getLine(cm.doc, coords.line).text).length == coords.ch) {
|
682
|
+
let colDiff = countColumn(line, line.length, cm.options.tabSize) - line.length
|
683
|
+
coords = Pos(coords.line, Math.max(0, Math.round((x - paddingH(cm.display).left) / charWidth(cm.display)) - colDiff))
|
684
|
+
}
|
685
|
+
return coords
|
686
|
+
}
|
687
|
+
|
688
|
+
// Find the view element corresponding to a given line. Return null
|
689
|
+
// when the line isn't visible.
|
690
|
+
export function findViewIndex(cm, n) {
|
691
|
+
if (n >= cm.display.viewTo) return null
|
692
|
+
n -= cm.display.viewFrom
|
693
|
+
if (n < 0) return null
|
694
|
+
let view = cm.display.view
|
695
|
+
for (let i = 0; i < view.length; i++) {
|
696
|
+
n -= view[i].size
|
697
|
+
if (n < 0) return i
|
698
|
+
}
|
699
|
+
}
|