summaryrefslogtreecommitdiff
path: root/help3
diff options
context:
space:
mode:
authorOlivier Hallot <olivier.hallot@libreoffice.org>2021-06-07 12:55:01 -0300
committerOlivier Hallot <olivier.hallot@libreoffice.org>2021-06-07 18:50:28 +0200
commit3487affff835b8ed828cc998b2f7f01318f80d3b (patch)
tree898c65488a4693a735759e66e62d28059bfc429a /help3
parent335d75a0fabbe5d674c910a1093d254989a48882 (diff)
Update codemirror editor to 5.61.1
Change-Id: Ie974339e17f5d81533d84e31c98ec49e2efb23f2 Reviewed-on: https://gerrit.libreoffice.org/c/dev-tools/+/116790 Tested-by: Olivier Hallot <olivier.hallot@libreoffice.org> Reviewed-by: Olivier Hallot <olivier.hallot@libreoffice.org>
Diffstat (limited to 'help3')
-rw-r--r--help3/xhpeditor/cm/AUTHORS84
-rw-r--r--help3/xhpeditor/cm/CHANGELOG.md300
-rw-r--r--help3/xhpeditor/cm/README.md1
-rw-r--r--help3/xhpeditor/cm/addon/comment/comment.js4
-rw-r--r--help3/xhpeditor/cm/addon/dialog/dialog.js4
-rw-r--r--help3/xhpeditor/cm/addon/display/panel.js10
-rw-r--r--help3/xhpeditor/cm/addon/display/placeholder.js15
-rw-r--r--help3/xhpeditor/cm/addon/edit/closebrackets.js22
-rw-r--r--help3/xhpeditor/cm/addon/edit/closetag.js9
-rw-r--r--help3/xhpeditor/cm/addon/edit/continuelist.js6
-rw-r--r--help3/xhpeditor/cm/addon/edit/matchbrackets.js28
-rw-r--r--help3/xhpeditor/cm/addon/fold/brace-fold.js13
-rw-r--r--help3/xhpeditor/cm/addon/hint/html-hint.js1
-rw-r--r--help3/xhpeditor/cm/addon/hint/javascript-hint.js7
-rw-r--r--help3/xhpeditor/cm/addon/hint/show-hint.js87
-rw-r--r--help3/xhpeditor/cm/addon/hint/sql-hint.js8
-rw-r--r--help3/xhpeditor/cm/addon/hint/xml-hint.js23
-rw-r--r--help3/xhpeditor/cm/addon/lint/javascript-lint.js2
-rw-r--r--help3/xhpeditor/cm/addon/lint/lint.css24
-rw-r--r--help3/xhpeditor/cm/addon/lint/lint.js43
-rw-r--r--help3/xhpeditor/cm/addon/merge/merge.js16
-rw-r--r--help3/xhpeditor/cm/addon/mode/loadmode.js22
-rw-r--r--help3/xhpeditor/cm/addon/mode/multiplex.js13
-rw-r--r--help3/xhpeditor/cm/addon/mode/multiplex_test.js16
-rw-r--r--help3/xhpeditor/cm/addon/mode/simple.js4
-rw-r--r--help3/xhpeditor/cm/addon/runmode/runmode-standalone.js448
-rw-r--r--help3/xhpeditor/cm/addon/runmode/runmode.js16
-rw-r--r--help3/xhpeditor/cm/addon/runmode/runmode.node.js396
-rw-r--r--help3/xhpeditor/cm/addon/scroll/annotatescrollbar.js10
-rw-r--r--help3/xhpeditor/cm/addon/search/jump-to-line.js5
-rw-r--r--help3/xhpeditor/cm/addon/search/match-highlighter.js6
-rw-r--r--help3/xhpeditor/cm/addon/search/search.js8
-rw-r--r--help3/xhpeditor/cm/addon/search/searchcursor.js2
-rw-r--r--help3/xhpeditor/cm/addon/tern/tern.js46
-rw-r--r--help3/xhpeditor/cm/addon/wrap/hardwrap.js31
-rw-r--r--help3/xhpeditor/cm/demo/anywordhint.html24
-rw-r--r--help3/xhpeditor/cm/demo/closetag.html1
-rw-r--r--help3/xhpeditor/cm/demo/complete.html4
-rw-r--r--help3/xhpeditor/cm/demo/matchhighlighter.html2
-rw-r--r--help3/xhpeditor/cm/demo/mustache.html2
-rw-r--r--help3/xhpeditor/cm/demo/runmode-standalone.html61
-rw-r--r--help3/xhpeditor/cm/demo/simplemode.html5
-rw-r--r--help3/xhpeditor/cm/demo/tern.html20
-rw-r--r--help3/xhpeditor/cm/demo/theme.html2
-rw-r--r--help3/xhpeditor/cm/demo/vim.html10
-rw-r--r--help3/xhpeditor/cm/doc/internals.html2
-rw-r--r--help3/xhpeditor/cm/doc/manual.html202
-rw-r--r--help3/xhpeditor/cm/doc/realworld.html18
-rw-r--r--help3/xhpeditor/cm/doc/releases.html211
-rw-r--r--help3/xhpeditor/cm/doc/upgrade_v2.2.html2
-rw-r--r--help3/xhpeditor/cm/index.html40
-rw-r--r--help3/xhpeditor/cm/keymap/emacs.js395
-rw-r--r--help3/xhpeditor/cm/keymap/sublime.js18
-rw-r--r--help3/xhpeditor/cm/keymap/vim.js402
-rw-r--r--help3/xhpeditor/cm/lib/codemirror.css11
-rw-r--r--help3/xhpeditor/cm/lib/codemirror.js699
-rw-r--r--help3/xhpeditor/cm/mode/asn.1/asn.1.js2
-rw-r--r--help3/xhpeditor/cm/mode/clike/clike.js20
-rw-r--r--help3/xhpeditor/cm/mode/clike/index.html2
-rw-r--r--help3/xhpeditor/cm/mode/clojure/clojure.js4
-rw-r--r--help3/xhpeditor/cm/mode/crystal/crystal.js12
-rw-r--r--help3/xhpeditor/cm/mode/css/css.js227
-rw-r--r--help3/xhpeditor/cm/mode/css/gss.html2
-rw-r--r--help3/xhpeditor/cm/mode/css/index.html6
-rw-r--r--help3/xhpeditor/cm/mode/cypher/cypher.js4
-rw-r--r--help3/xhpeditor/cm/mode/dart/dart.js4
-rw-r--r--help3/xhpeditor/cm/mode/dtd/dtd.js4
-rw-r--r--help3/xhpeditor/cm/mode/ebnf/ebnf.js14
-rw-r--r--help3/xhpeditor/cm/mode/erlang/erlang.js4
-rw-r--r--help3/xhpeditor/cm/mode/factor/factor.js2
-rw-r--r--help3/xhpeditor/cm/mode/factor/index.html4
-rw-r--r--help3/xhpeditor/cm/mode/fcl/index.html10
-rw-r--r--help3/xhpeditor/cm/mode/forth/index.html4
-rw-r--r--help3/xhpeditor/cm/mode/gas/gas.js4
-rw-r--r--help3/xhpeditor/cm/mode/gfm/test.js2
-rw-r--r--help3/xhpeditor/cm/mode/haml/haml.js2
-rw-r--r--help3/xhpeditor/cm/mode/htmlembedded/index.html2
-rw-r--r--help3/xhpeditor/cm/mode/htmlmixed/htmlmixed.js3
-rw-r--r--help3/xhpeditor/cm/mode/idl/idl.js2
-rw-r--r--help3/xhpeditor/cm/mode/index.html1
-rw-r--r--help3/xhpeditor/cm/mode/javascript/index.html6
-rw-r--r--help3/xhpeditor/cm/mode/javascript/javascript.js75
-rw-r--r--help3/xhpeditor/cm/mode/javascript/test.js16
-rw-r--r--help3/xhpeditor/cm/mode/jsx/jsx.js2
-rw-r--r--help3/xhpeditor/cm/mode/jsx/test.js7
-rw-r--r--help3/xhpeditor/cm/mode/julia/julia.js73
-rw-r--r--help3/xhpeditor/cm/mode/lua/lua.js1
-rw-r--r--help3/xhpeditor/cm/mode/markdown/index.html24
-rw-r--r--help3/xhpeditor/cm/mode/markdown/markdown.js17
-rw-r--r--help3/xhpeditor/cm/mode/markdown/test.js22
-rw-r--r--help3/xhpeditor/cm/mode/meta.js13
-rw-r--r--help3/xhpeditor/cm/mode/modelica/modelica.js6
-rw-r--r--help3/xhpeditor/cm/mode/mscgen/mscgen.js8
-rw-r--r--help3/xhpeditor/cm/mode/mumps/mumps.js2
-rw-r--r--help3/xhpeditor/cm/mode/nginx/index.html4
-rw-r--r--help3/xhpeditor/cm/mode/nsis/nsis.js2
-rw-r--r--help3/xhpeditor/cm/mode/ntriples/index.html2
-rw-r--r--help3/xhpeditor/cm/mode/oz/oz.js4
-rw-r--r--help3/xhpeditor/cm/mode/pascal/pascal.js17
-rw-r--r--help3/xhpeditor/cm/mode/pegjs/pegjs.js6
-rw-r--r--help3/xhpeditor/cm/mode/perl/perl.js8
-rw-r--r--help3/xhpeditor/cm/mode/php/php.js6
-rw-r--r--help3/xhpeditor/cm/mode/powershell/index.html4
-rw-r--r--help3/xhpeditor/cm/mode/powershell/powershell.js2
-rw-r--r--help3/xhpeditor/cm/mode/powershell/test.js2
-rw-r--r--help3/xhpeditor/cm/mode/protobuf/protobuf.js5
-rw-r--r--help3/xhpeditor/cm/mode/pug/pug.js2
-rw-r--r--help3/xhpeditor/cm/mode/puppet/puppet.js2
-rw-r--r--help3/xhpeditor/cm/mode/python/index.html2
-rw-r--r--help3/xhpeditor/cm/mode/python/python.js14
-rw-r--r--help3/xhpeditor/cm/mode/python/test.js6
-rw-r--r--help3/xhpeditor/cm/mode/r/r.js4
-rw-r--r--help3/xhpeditor/cm/mode/rpm/rpm.js8
-rw-r--r--help3/xhpeditor/cm/mode/ruby/index.html2
-rw-r--r--help3/xhpeditor/cm/mode/ruby/ruby.js41
-rw-r--r--help3/xhpeditor/cm/mode/rust/rust.js4
-rwxr-xr-xhelp3/xhpeditor/cm/mode/sas/sas.js2
-rw-r--r--help3/xhpeditor/cm/mode/sass/sass.js9
-rw-r--r--help3/xhpeditor/cm/mode/scheme/scheme.js6
-rw-r--r--help3/xhpeditor/cm/mode/shell/shell.js16
-rw-r--r--help3/xhpeditor/cm/mode/shell/test.js15
-rw-r--r--help3/xhpeditor/cm/mode/sieve/sieve.js2
-rw-r--r--help3/xhpeditor/cm/mode/soy/soy.js273
-rw-r--r--help3/xhpeditor/cm/mode/soy/test.js98
-rw-r--r--help3/xhpeditor/cm/mode/sparql/sparql.js14
-rw-r--r--help3/xhpeditor/cm/mode/sql/sql.js12
-rw-r--r--help3/xhpeditor/cm/mode/stex/stex.js2
-rw-r--r--help3/xhpeditor/cm/mode/stylus/stylus.js10
-rw-r--r--help3/xhpeditor/cm/mode/tcl/tcl.js3
-rw-r--r--help3/xhpeditor/cm/mode/tiddlywiki/tiddlywiki.js2
-rw-r--r--help3/xhpeditor/cm/mode/twig/index.html4
-rw-r--r--help3/xhpeditor/cm/mode/vb/index.html2
-rw-r--r--help3/xhpeditor/cm/mode/vbscript/vbscript.js4
-rw-r--r--help3/xhpeditor/cm/mode/velocity/velocity.js3
-rw-r--r--help3/xhpeditor/cm/mode/verilog/test.js170
-rw-r--r--help3/xhpeditor/cm/mode/verilog/verilog.js144
-rw-r--r--help3/xhpeditor/cm/mode/vue/index.html2
-rw-r--r--help3/xhpeditor/cm/mode/wast/index.html73
-rw-r--r--help3/xhpeditor/cm/mode/wast/test.js424
-rw-r--r--help3/xhpeditor/cm/mode/wast/wast.js132
-rw-r--r--help3/xhpeditor/cm/mode/xml/xml.js4
-rw-r--r--help3/xhpeditor/cm/mode/xquery/index.html2
-rw-r--r--help3/xhpeditor/cm/mode/yaml-frontmatter/yaml-frontmatter.js6
-rw-r--r--help3/xhpeditor/cm/mode/yaml/yaml.js8
-rw-r--r--help3/xhpeditor/cm/package.json9
-rw-r--r--help3/xhpeditor/cm/rollup.config.js42
-rw-r--r--help3/xhpeditor/cm/src/addon/runmode/codemirror-standalone.js24
-rw-r--r--help3/xhpeditor/cm/src/addon/runmode/codemirror.node.js21
-rw-r--r--help3/xhpeditor/cm/src/addon/runmode/runmode-standalone.js2
-rw-r--r--help3/xhpeditor/cm/src/addon/runmode/runmode.node.js2
-rw-r--r--help3/xhpeditor/cm/src/display/focus.js9
-rw-r--r--help3/xhpeditor/cm/src/display/operations.js3
-rw-r--r--help3/xhpeditor/cm/src/display/scrolling.js13
-rw-r--r--help3/xhpeditor/cm/src/display/selection.js7
-rw-r--r--help3/xhpeditor/cm/src/display/update_display.js8
-rw-r--r--help3/xhpeditor/cm/src/display/update_line.js1
-rw-r--r--help3/xhpeditor/cm/src/edit/CodeMirror.js6
-rw-r--r--help3/xhpeditor/cm/src/edit/commands.js4
-rw-r--r--help3/xhpeditor/cm/src/edit/drop_events.js4
-rw-r--r--help3/xhpeditor/cm/src/edit/key_events.js2
-rw-r--r--help3/xhpeditor/cm/src/edit/main.js2
-rw-r--r--help3/xhpeditor/cm/src/edit/methods.js32
-rw-r--r--help3/xhpeditor/cm/src/edit/mouse_events.js17
-rw-r--r--help3/xhpeditor/cm/src/edit/options.js8
-rw-r--r--help3/xhpeditor/cm/src/input/ContentEditableInput.js30
-rw-r--r--help3/xhpeditor/cm/src/input/TextareaInput.js10
-rw-r--r--help3/xhpeditor/cm/src/input/input.js2
-rw-r--r--help3/xhpeditor/cm/src/input/keymap.js9
-rw-r--r--help3/xhpeditor/cm/src/input/keynames.js2
-rw-r--r--help3/xhpeditor/cm/src/input/movement.js2
-rw-r--r--help3/xhpeditor/cm/src/line/highlight.js2
-rw-r--r--help3/xhpeditor/cm/src/line/line_data.js2
-rw-r--r--help3/xhpeditor/cm/src/line/spans.js12
-rw-r--r--help3/xhpeditor/cm/src/model/Doc.js6
-rw-r--r--help3/xhpeditor/cm/src/model/document_data.js1
-rw-r--r--help3/xhpeditor/cm/src/model/history.js6
-rw-r--r--help3/xhpeditor/cm/src/model/line_widget.js2
-rw-r--r--help3/xhpeditor/cm/src/model/mark_text.js2
-rw-r--r--help3/xhpeditor/cm/src/model/selection_updates.js2
-rw-r--r--help3/xhpeditor/cm/src/util/bidi.js5
-rw-r--r--help3/xhpeditor/cm/src/util/browser.js2
-rw-r--r--help3/xhpeditor/cm/src/util/misc.js2
-rw-r--r--help3/xhpeditor/cm/test/annotatescrollbar.js55
-rw-r--r--help3/xhpeditor/cm/test/driver.js15
-rw-r--r--help3/xhpeditor/cm/test/emacs_test.js21
-rw-r--r--help3/xhpeditor/cm/test/index.html5
-rw-r--r--help3/xhpeditor/cm/test/lint.js3
-rwxr-xr-xhelp3/xhpeditor/cm/test/run.js4
-rw-r--r--help3/xhpeditor/cm/test/test.js4
-rw-r--r--help3/xhpeditor/cm/test/vim_test.js351
-rw-r--r--help3/xhpeditor/cm/theme/abbott.css268
-rw-r--r--help3/xhpeditor/cm/theme/solarized.css2
-rw-r--r--help3/xhpeditor/cm/theme/zenburn.css2
193 files changed, 5474 insertions, 1634 deletions
diff --git a/help3/xhpeditor/cm/AUTHORS b/help3/xhpeditor/cm/AUTHORS
index 77952afc..a8ded264 100644
--- a/help3/xhpeditor/cm/AUTHORS
+++ b/help3/xhpeditor/cm/AUTHORS
@@ -10,29 +10,35 @@ Abhishek Gahlot
Adam Ahmed
Adam King
Adam Particka
+Adam Wight
adanlobato
Adán Lobato
Aditya Toshniwal
Adrian Aichner
Adrian Heine
+Adrian Kunz
Adrien Bertrand
aeroson
Ahmad Amireh
Ahmad M. Zawawi
ahoward
+Ajin Abraham
Akeksandr Motsjonov
Alasdair Smith
AlbertHilb
Alberto González Palomo
Alberto Pose
Albert Xing
+Alexander Marks
Alexander Pavlov
Alexander Schepanovski
Alexander Shvets
Alexander Solovyov
Alexandre Bique
+Alex Churchill
alexey-k
Alex Piggott
+Alf Eaton
Aliaksei Chapyzhenka
Allen Sarkisyan
Ami Fischman
@@ -97,6 +103,9 @@ Bastian Müller
belhaj
Bem Jones-Bey
benbro
+Benedikt Meurer
+benhormann
+Ben Hormann
Beni Cherniavsky-Paskin
Benjamin DeCoste
Benjamin Young
@@ -108,6 +117,7 @@ Bert Chang
Bharad
BigBlueHat
Billy Moon
+Bin Ni
binny
Bjorn Hansen
B Krishna Chaitanya
@@ -117,12 +127,14 @@ Bo
boomyjee
Bo Peng
borawjm
+Boris K
Brad Metcalf
Brandon Frohs
Brandon Wamboldt
Bret Little
Brett Zamir
Brian Grinstead
+BrianHung
Brian Sletten
brrd
Bruce Mitchener
@@ -134,6 +146,7 @@ Calin Barbat
callodacity
Camilo Roca
Casey Klebba
+cBiscuit87
César González Íñiguez
Chad Jolly
Chandra Sekhar Pydi
@@ -160,15 +173,18 @@ Christopher Pfohl
Christopher Wallis
Chunliang Lyu
ciaranj
+clone-it
clso
CodeAnimal
CodeBitt
coderaiser
Cole R Lawrence
ComFreek
+Cornelius Weig
Cristian Prieto
Curran Kelleher
Curtis Gagliardi
+d8888
dagsta
daines
Dale Jung
@@ -196,6 +212,8 @@ David Barnett
David H. Bronke
David Mignot
David Pathakjee
+David R. Myers
+David Rodrigues
David Santana
David Vázquez
David Whittington
@@ -208,6 +226,7 @@ Dick Choi
Diego Fernandez
dignifiedquire
Dimage Sapelkin
+Dinindu D. Wanniarachchi
dmaclach
Dmitry Kiselyov
domagoj412
@@ -223,11 +242,13 @@ Dror BG
Duncan Lilley
duralog
dwelle
+Ealton
eborden
edoroshenko
edsharp
ekhaled
Elisée
+Elmar Peise
elpnt
Emmanuel Schanzer
Enam Mijbah Noor
@@ -235,6 +256,7 @@ Eric Allam
Eric Bogard
Erik Demaine
Erik Welander
+erosman
eustas
Evan Minsk
Fabien Dubosson
@@ -245,6 +267,7 @@ Fauntleroy
fbuchinger
feizhang365
Felipe Lalanne
+Felipe S. S. Schneider
Felix Raab
ficristo
Filip Noetzel
@@ -253,6 +276,7 @@ Filype Pereira
finalfantasia
flack
Florian Felten
+Fons van der Plas
Forbes Lindesay
ForbesLindesay
Ford_Lawnmower
@@ -299,6 +323,7 @@ Hakan Tunc
Hanno Fellmann
Hans Engel
Hanzhao Deng
+Haoran Yu
Harald Schilly
Hardest
Harshvardhan Gupta
@@ -306,7 +331,9 @@ Hasan Delibaş
Hasan Karahan
Heanes
Hector Oswaldo Caballero
+Hein Htat
Hélio
+Hendrik Erz
Hendrik Wallbaum
Henrik Haugbølle
Herculano Campos
@@ -314,10 +341,14 @@ hidaiy
Hiroyuki Makino
hitsthings
Hocdoc
+Howard
+Howard Jing
Hugues Malphettes
Ian Beck
Ian Davies
Ian Dickinson
+Ian Henderson
+ianhi
Ian Rose
Ian Wehrman
Ian Wetherbee
@@ -327,14 +358,20 @@ idleberg
Igor Petruk
ilvalle
Ilya Kharlamov
+Ilya Zverev
Ingo Richter
+Intervue
Irakli Gozalishvili
+iteriani
Ivan Kurnosov
Ivoah
+Jack Douglas
Jacob Lee
Jaimin
Jake Peyser
+Jakob Kummerow
Jakob Miland
+Jakub T. Jankiewicz
Jakub Vrana
Jakub Vrána
James Campos
@@ -361,6 +398,7 @@ Jason Johnston
Jason San Jose
Jason Siefken
Jayaprabhakar
+Jay Contonio
Jaydeep Solanki
Jean Boussier
Jeff Blaisdell
@@ -378,9 +416,11 @@ jochenberger
Jochen Berger
Joel Einbinder
joelpinheiro
+Joe Predham
joewalsh
Johan Ask
Johannes
+John Chen
John Connor
John-David Dalton
John Engler
@@ -394,12 +434,14 @@ Jonas Helfer
Jonathan Dierksen
Jonathan Hart
Jonathan Malmaud
+Jonathan Rascher
Jon Gacnik
jongalloway
Jon Malmaud
Jon Sangster
Joo
Joost-Wim Boekesteijn
+José dBruxelles
Joseph Pecoraro
Josh Barnes
Josh Cohen
@@ -421,6 +463,7 @@ jwallers@gmail.com
kaniga
karevn
Karol
+Kaushik Kulkarni
Kayur Patel
Kazuhito Hokamura
kcwiakala
@@ -435,14 +478,17 @@ Kevin Muret
Kevin Sawicki
Kevin Ushey
Kier Darby
+Kim-Anh Tran
Klaus Silveira
Koh Zi Han, Cliff
komakino
+Konstantin Chernenko
Konstantin Lopuhin
koops
Kris Ciccarello
ks-ifware
kubelsmieci
+kvncp
KwanEsq
Kyle Kelley
KyleMcNutt
@@ -462,6 +508,7 @@ Liam Newman
Libo Cannici
Lior Goldberg
Lior Shub
+lishid
LloydMilligan
LM
lochel
@@ -470,9 +517,11 @@ Lorenzo Simionato
Lorenzo Stoakes
Louis Mauchet
Luca Fabbri
+Lucas Buchala
Luciano Longo
Luciano Santana
Lu Fangjian
+Łukasz Wielgus
Luke Browning
Luke Granger-Brown
Luke Stagner
@@ -487,6 +536,7 @@ Manuel Rego Casasnovas
Marat Dreizin
Marcel Gerber
Marcelo Camargo
+Marc Espín
Marco Aurélio
Marco Munizaga
Marcus Bointon
@@ -495,6 +545,7 @@ Marijn Haverbeke
Mário Gonçalves
Mario Pietsch
Mark Anderson
+Mark Boyes
Mark Dalgleish
Mark Hamstra
Mark Lentczner
@@ -508,13 +559,16 @@ Martin Hasoň
Martin Hunt
Martin Laine
Martin Zagora
+Masahiro MATAYOSHI
Mason Malone
Mateusz Paprocki
Mathias Bynens
mats cronqvist
+Matt Diehl
Matt Gaide
Matthew Bauer
Matthew Beale
+Matthew Casperson
matthewhayes
Matthew Rathbone
Matthew Suozzo
@@ -535,11 +589,13 @@ Max Xiantu
mbarkhau
McBrainy
mce2
+Mélanie Chauvel
melpon
meshuamam
Metatheos
Micah Dubinko
Michael
+Michael Chirico
Michael Goderbauer
Michael Grey
Michael Kaminsky
@@ -567,6 +623,7 @@ Miraculix87
misfo
mkaminsky11
mloginov
+mlsad3
Moritz Schubotz (physikerwelt)
Moritz Schwörer
Moshe Wajnberg
@@ -577,6 +634,7 @@ Mu-An ✌️ Chiou
Mu-An Chiou
mzabuawala
Narciso Jaramillo
+nathanlesage
Nathan Williams
ndr
Neil Anderson
@@ -603,6 +661,7 @@ Nikolaj Kappler
Nikolay Kostov
nilp0inter
Nils Knappmeier
+Nina Pypchenko
Nisarg Jhaveri
nlwillia
noragrossman
@@ -613,6 +672,7 @@ Olivia Ytterbrink
Opender Singh
opl-
Oreoluwa Onatemowo
+orionlee
oscar.lofwenhamn
Oskar Segersvärd
ossdev
@@ -628,11 +688,13 @@ paris
Paris
Paris Kasidiaris
Patil Arpith
+Patrick Kettner
Patrick Stoica
Patrick Strawderman
Paul Garvin
Paul Ivanov
Paul Masson
+Paul Schmidt
Pavel
Pavel Feldman
Pavel Petržela
@@ -643,12 +705,15 @@ peter
Peter Flynn
peterkroon
Peter Kroon
+Peter László
+Phil DeJarnett
Philipp A
Philipp Markovics
Philip Stadermann
Pi Delport
Pierre Gerold
Pieter Ouwerkerk
+Piyush
Pontus Melke
prasanthj
Prasanth J
@@ -656,6 +721,7 @@ Prayag Verma
prendota
Prendota
Qiang Li
+quiddity-wp
Radek Piórkowski
Rahul
Rahul Anand
@@ -683,10 +749,14 @@ Robert Crossfield
Robert Martin
Roberto Abdelkader Martínez Pérez
robertop23
+Roberto Vidal
Robert Plummer
+Roman Frolov
+Roman Janusz
Rrandom
Rrrandom
Ruslan Osmanov
+rvalavicius
Ryan Pangrle
Ryan Petrello
Ryan Prior
@@ -713,6 +783,7 @@ Scott Aikin
Scott Feeney
Scott Goodhew
Seb35
+Sebastian Ślepowroński
Sebastian Wilzbach
Sebastian Zaha
Seren D
@@ -730,9 +801,12 @@ Shiv Deepak
Shmuel Englard
Shubham Jain
Siamak Mokhtari
+Siddhartha Gunti
silverwind
Simon Edwards
+Simon Huber
sinkuu
+Slava Rozhnev
snasa
soliton4
sonson
@@ -765,6 +839,7 @@ Takuya Matsuyama
Tarmil
T. Brandon Ashley
TDaglis
+Teja
tel
Tentone
tfjgeorge
@@ -772,6 +847,7 @@ Thaddee Tyl
thanasis
TheHowl
themrmax
+Thiemo Kreuz
think
Thomas Brouard
Thomas Dvornik
@@ -780,13 +856,16 @@ thomasmaclean
Thomas Schmid
Tim Alby
Tim Baumann
+Tim Gates
Timothy Farrell
Timothy Gu
Timothy Hatcher
+Tim van der Lippe
Tobias Bertelsen
TobiasBg
Todd Berman
Todd Kennedy
+tokafew420
Tomas-A
Tomas Varaneckas
Tom Erik Støwer
@@ -795,6 +874,7 @@ Tom MacWright
Tom McLaughlin
Tony Jian
tophf
+Torben Bundt
Torgeir Thoresen
totalamd
Travis Heppe
@@ -808,6 +888,7 @@ Tyler Makaro
Vadim Dyachenko
Vadzim Ramanenka
Vaibhav Sagar
+vamshi.revu
VapidWorx
Vestimir Markov
vf
@@ -832,6 +913,8 @@ wonderboyjon
Wu Cheng-Han
Xavier Mendez
Yang Guo
+Yash Singh
+Yash-Singh1
Yassin N. Hassan
YNH Webdev
yoongu
@@ -840,6 +923,7 @@ Yuvi Panda
Yvonnick Esnault
Zac Anger
Zachary Dremann
+ZeeshanNoor
Zeno Rocha
Zhang Hao
Ziv
diff --git a/help3/xhpeditor/cm/CHANGELOG.md b/help3/xhpeditor/cm/CHANGELOG.md
index 4adfb8b9..4145ff47 100644
--- a/help3/xhpeditor/cm/CHANGELOG.md
+++ b/help3/xhpeditor/cm/CHANGELOG.md
@@ -1,3 +1,285 @@
+## 5.61.1 (2021-05-20)
+
+### Bug fixes
+
+Fix a bug where changing the editor's document could confuse text-direction management.
+
+Fix a bug in horizontally scrolling the cursor into view.
+
+Optimize adding lots of marks in a single transaction.
+
+[simple mode addon](https://codemirror.net/demo/simplemode.html): Support regexps with a unicode flag.
+
+[javascript mode](https://codemirror.net/mode/javascript/index.html): Add support for TypeScript template string types, improve integration with JSX mode.
+
+## 5.61.0 (2021-04-20)
+
+### Bug fixes
+
+Improve support for being in a shadow DOM in contenteditable mode.
+
+Prevent line number from being read by screen readers.
+
+[show-hint addon](https://codemirror.net/doc/manual.html#addon_show-hint): Fix a crash caused by a race condition.
+
+[javascript mode](https://codemirror.net/mode/javascript/): Improve scope tracking.
+
+### New features
+
+The library now emits an `"updateGutter"` event when the gutter width changes.
+
+[emacs bindings](https://codemirror.net/demo/emacs.html): Provide named commands for all bindings.
+
+## 5.60.0 (2021-03-20)
+
+### Bug fixes
+
+Fix autofocus feature in contenteditable mode.
+
+[simple mode addon](https://codemirror.net/demo/simplemode.html): Fix a null-dereference crash.
+
+[multiplex addon](https://codemirror.net/demo/multiplex.html): Make it possible to use `parseDelimiters` when both delimiters are the same.
+
+[julia mode](https://codemirror.net/mode/julia/): Fix a lockup bug.
+
+### New features
+
+`setSelections` now allows ranges to omit the `head` property when it is equal to `anchor`.
+
+[sublime bindings](https://codemirror.net/demo/sublime.html): Add support for reverse line sorting.
+
+## 5.59.4 (2021-02-24)
+
+### Bug fixes
+
+Give the scrollbar corner filler a background again, to prevent content from peeping through between the scrollbars.
+
+## 5.59.3 (2021-02-20)
+
+### Bug fixes
+
+Don't override the way zero-with non-joiners are rendered.
+
+Fix an issue where resetting the history cleared the `undoDepth` option's value.
+
+[vim bindings](https://codemirror.net/demo/vim.html): Fix substitute command when joining and splitting lines, fix global command when line number change, add support for `:vglobal`, properly treat caps lock as a modifier key.
+
+## 5.59.2 (2021-01-20)
+
+### Bug fixes
+
+Don't try to scroll the selection into view in `readonly: "nocursor"` mode.
+
+[closebrackets addon](https://codemirror.net/doc/manual.html#addon_closebrackets): Fix a regression in the behavior of pressing enter between brackets.
+
+[javascript mode](https://codemirror.net/mode/javascript/): Fix an infinite loop on specific syntax errors in object types.
+
+various modes: Fix inefficient RegExp matching.
+
+## 5.59.1 (2020-12-31)
+
+### Bug fixes
+
+Fix an issue where some Chrome browsers were detected as iOS.
+
+## 5.59.0 (2020-12-20)
+
+### Bug fixes
+
+Fix platform detection on recent iPadOS.
+
+[lint addon](https://codemirror.net/doc/manual.html#addon_lint): Don't show duplicate messages for a given line.
+
+[clojure mode](https://codemirror.net/mode/clojure/index.html): Fix regexp that matched in exponential time for some inputs.
+
+[hardwrap addon](https://codemirror.net/doc/manual.html#addon_hardwrap): Improve handling of words that are longer than the line length.
+
+[matchbrackets addon](https://codemirror.net/doc/manual.html#addon_matchbrackets): Fix leaked event handler on disabling the addon.
+
+### New features
+
+[search addon](https://codemirror.net/demo/search.html): Make it possible to configure the search addon to show the dialog at the bottom of the editor.
+
+## 5.58.3 (2020-11-19)
+
+### Bug fixes
+
+Suppress quick-firing of blur-focus events when dragging and clicking on Internet Explorer.
+
+Fix the `insertAt` option to `addLineWidget` to actually allow the widget to be placed after all widgets for the line.
+
+[soy mode](https://codemirror.net/mode/soy/): Support `@Attribute` and element composition.
+
+[shell mode](https://codemirror.net/mode/shell/): Support heredoc quoting.
+
+## 5.58.2 (2020-10-23)
+
+### Bug fixes
+
+Fix a bug where horizontally scrolling the cursor into view sometimes failed with a non-fixed gutter.
+
+[julia mode](https://codemirror.net/mode/julia/): Fix an infinite recursion bug.
+
+## 5.58.1 (2020-09-23)
+
+### Bug fixes
+
+[placeholder addon](https://codemirror.net/doc/manual.html#addon_placeholder): Remove arrow function that ended up in the code.
+
+## 5.58.0 (2020-09-21)
+
+### Bug fixes
+
+Make backspace delete by code point, not glyph.
+
+Suppress flickering focus outline when clicking on scrollbars in Chrome.
+
+Fix a bug that prevented attributes added via `markText` from showing up unless the span also had some other styling.
+
+Suppress cut and paste context menu entries in readonly editors in Chrome.
+
+[placeholder addon](https://codemirror.net/doc/manual.html#addon_placeholder): Update placeholder visibility during composition.
+
+### New features
+
+Make it less cumbersome to style new lint message types.
+
+[vim bindings](https://codemirror.net/demo/vim.html): Support black hole register, `gn` and `gN`
+
+## 5.57.0 (2020-08-20)
+
+### Bug fixes
+
+Fix issue that broke binding the macOS Command key.
+
+[comment addon](https://codemirror.net/doc/manual.html#addon_comment): Keep selection in front of inserted markers when adding a block comment.
+
+[css mode](https://codemirror.net/mode/css/): Recognize more properties and value names.
+
+[annotatescrollbar addon](https://codemirror.net/doc/manual.html#addon_annotatescrollbar): Don't hide matches in collapsed content.
+
+### New features
+
+[vim bindings](https://codemirror.net/demo/vim.html): Support tag text objects in xml and html modes.
+
+## 5.56.0 (2020-07-20)
+
+### Bug fixes
+
+Line-wise pasting was fixed on Chrome Windows.
+
+[wast mode](https://codemirror.net/mode/wast/): Follow standard changes.
+
+[soy mode](https://codemirror.net/mode/soy/): Support import expressions, template type, and loop indices.
+
+[sql-hint addon](https://codemirror.net/doc/manual.html#addon_sql-hint): Improve handling of double quotes.
+
+### New features
+
+[show-hint addon](https://codemirror.net/doc/manual.html#addon_show-hint): New option `scrollMargin` to control how many options are visible beyond the selected one.
+
+[hardwrap addon](https://codemirror.net/doc/manual.html#addon_hardwrap): New option `forceBreak` to disable breaking of words that are longer than a line.
+
+## 5.55.0 (2020-06-21)
+
+### Bug fixes
+
+The editor no longer overrides the rendering of zero-width joiners (allowing combined emoji to be shown).
+
+[vim bindings](https://codemirror.net/demo/vim.html): Fix an issue where the `vim-mode-change` event was fired twice.
+
+[javascript mode](https://codemirror.net/mode/javascript/): Only allow `-->`-style comments at the start of a line.
+
+[julia mode](https://codemirror.net/mode/julia/): Improve indentation.
+
+[pascal mode](https://codemirror.net/mode/pascal/index.html): Recognize curly bracket comments.
+
+[runmode addon](https://codemirror.net/doc/manual.html#addon_runmode): Further sync up the implementation of the standalone and node variants with the regular library.
+
+### New features
+
+[loadmode addon](https://codemirror.net/doc/manual.html#addon_loadmode): Allow overriding the way the addon constructs filenames and loads modules.
+
+## 5.54.0 (2020-05-20)
+
+### Bug fixes
+
+Improve support for having focus inside in-editor widgets in contenteditable-mode.
+
+Fix issue where the scroll position could jump when clicking on a selection in Chrome.
+
+[python mode](https://codemirror.net/mode/python/): Better format string support.
+
+[javascript mode](https://codemirror.net/mode/javascript/): Improve parsing of private properties and class fields.
+
+[matchbrackets addon](https://codemirror.net/doc/manual.html#addon_matchbrackets): Disable highlighting when the editor doesn't have focus.
+
+### New features
+
+[runmode addon](https://codemirror.net/doc/manual.html#addon_runmode): Properly support for cross-line lookahead.
+
+[vim bindings](https://codemirror.net/demo/vim.html): Allow Ex-Commands with non-word names.
+
+[gfm mode](https://codemirror.net/mode/gfm/): Add a `fencedCodeBlockDefaultMode` option.
+
+## 5.53.2 (2020-04-21)
+
+### Bug fixes
+
+[show-hint addon](https://codemirror.net/doc/manual.html#addon_show-hint): Fix a regression that broke completion picking.
+
+## 5.53.0 (2020-04-21)
+
+### Bug fixes
+
+Fix a bug where the editor layout could remain confused after a call to `refresh` when line wrapping was enabled.
+
+[dialog addon](https://codemirror.net/doc/manual.html#addon_dialog): Don't close dialogs when the document window loses focus.
+
+[merge addon](https://codemirror.net/doc/manual.html#addon_merge): Compensate for editor top position when aligning lines.
+
+[vim bindings](https://codemirror.net/demo/vim.html): Improve EOL handling.
+
+[emacs bindings](https://codemirror.net/demo/emacs.html): Include default keymap as a fallback.
+
+[julia mode](https://codemirror.net/mode/julia/): Fix an infinite loop bug.
+
+[show-hint addon](https://codemirror.net/doc/manual.html#addon_show-hint): Scroll cursor into view when picking a completion.
+
+### New features
+
+New option: [`screenReaderLabel`](https://codemirror.net/doc/manual.html#option_screenReaderLabel) to add a label to the editor.
+
+New mode: [wast](https://codemirror.net/mode/wast/).
+
+## 5.52.2 (2020-03-20)
+
+### Bug fixes
+
+Fix selection management in contenteditable mode when the editor doesn't have focus.
+
+Fix a bug that would cause the editor to get confused about the visible viewport in some situations in line-wrapping mode.
+
+[markdown mode](https://codemirror.net/mode/markdown/): Don't treat single dashes as setext header markers.
+
+[zenburn theme](https://codemirror.net/demo/theme.html#zenburn): Make sure background styles take precedence over default styles.
+
+[css mode](https://codemirror.net/mode/css/): Recognize a number of new properties.
+
+## 5.52.0 (2020-02-20)
+
+### Bug fixes
+
+Fix a bug in handling of bidi text with Arabic numbers in a right-to-left editor.
+
+Fix a crash when combining file drop with a `"beforeChange"` filter.
+
+Prevent issue when passing negative coordinates to `scrollTo`.
+
+### New features
+
+[lint](https://codemirror.net/doc/manual.html#addon_lint) and [tern](https://codemirror.net/demo/tern.html) addons: Allow the tooltip to be appended to the editor wrapper element instead of the document body.
+
## 5.51.0 (2020-01-20)
### Bug fixes
@@ -12,7 +294,7 @@ Make sure `clearHistory` clears the history in all linked docs with a shared his
### New features
-[vim bindings](https://codemirror.net/demo/vim.html): Support `gi`, gI`, and `gJ`.
+[vim bindings](https://codemirror.net/demo/vim.html): Support `gi`, `gI`, and `gJ`.
## 5.50.2 (2020-01-01)
@@ -30,7 +312,7 @@ Make Shift-Delete to cut work on Firefox.
[handlebars mode](https://codemirror.net/mode/handlebars/): Fix triple-brace support.
-[searchcursor addon](https://codemirror.net/doc/manual.html#addon_searchcursor): Support mathing `$` in reverse regexp search.
+[searchcursor addon](https://codemirror.net/doc/manual.html#addon_searchcursor): Support matching `$` in reverse regexp search.
[panel addon](https://codemirror.net/doc/manual.html#addon_panel): Don't get confused by changing panel sizes.
@@ -286,7 +568,7 @@ Add `hintWords` (basic completion) helper to [clojure](https://codemirror.net/mo
[panel addon](https://codemirror.net/doc/manual.html#addon_panel): Fix problem where replacing the last remaining panel dropped the newly added panel.
-[hardwrap addon](https://codemirror.net/doc/manual.html#addon_hardwrap): Fix an infinite loop when the indention is greater than the target column.
+[hardwrap addon](https://codemirror.net/doc/manual.html#addon_hardwrap): Fix an infinite loop when the indentation is greater than the target column.
[jinja2](https://codemirror.net/mode/jinja2/) and [markdown](https://codemirror.net/mode/markdown/) modes: Add comment metadata.
@@ -674,7 +956,7 @@ Add `role=presentation` to more DOM elements to improve screen reader support.
[merge addon](https://codemirror.net/doc/manual.html#addon_merge): Make aligning of unchanged chunks more robust.
-[comment addon](https://codemirror.net/doc/manual.html#addon_comment): Fix comment-toggling on a block of text that starts and ends in a (differnet) block comment.
+[comment addon](https://codemirror.net/doc/manual.html#addon_comment): Fix comment-toggling on a block of text that starts and ends in a (different) block comment.
[javascript mode](https://codemirror.net/mode/javascript/): Improve support for TypeScript syntax.
@@ -792,7 +1074,7 @@ New event: [`optionChange`](https://codemirror.net/doc/manual.html#event_optionC
Tapping/clicking the editor in [contentEditable mode](https://codemirror.net/doc/manual.html#option_inputStyle) on Chrome now puts the cursor at the tapped position.
-Fix various crashes and misbehaviors when reading composition events in [contentEditable mode](https://codemirror.net/doc/manual.html#option_inputStyle).
+Fix various crashes and misbehavior when reading composition events in [contentEditable mode](https://codemirror.net/doc/manual.html#option_inputStyle).
Catches and ignores an IE 'Unspecified Error' when creating an editor in an iframe before there is a `<body>`.
@@ -1127,7 +1409,7 @@ Fix a [bug](https://github.com/codemirror/CodeMirror/issues/3834) that caused ph
* New modes: [Vue](https://codemirror.net/mode/vue/index.html), [Oz](https://codemirror.net/mode/oz/index.html), [MscGen](https://codemirror.net/mode/mscgen/index.html) (and dialects), [Closure Stylesheets](https://codemirror.net/mode/css/gss.html)
* Implement [CommonMark](http://commonmark.org)-style flexible list indent and cross-line code spans in [Markdown](https://codemirror.net/mode/markdown/index.html) mode
* Add a replace-all button to the [search addon](https://codemirror.net/doc/manual.html#addon_search), and make the persistent search dialog transparent when it obscures the match
-* Handle `acync`/`await` and ocal and binary numbers in [JavaScript mode](https://codemirror.net/mode/javascript/index.html)
+* Handle `async`/`await` and ocal and binary numbers in [JavaScript mode](https://codemirror.net/mode/javascript/index.html)
* Fix various issues with the [Haxe mode](https://codemirror.net/mode/haxe/index.html)
* Make the [closebrackets addon](https://codemirror.net/doc/manual.html#addon_closebrackets) select only the wrapped text when wrapping selection in brackets
* Tokenize properties as properties in the [CoffeeScript mode](https://codemirror.net/mode/coffeescript/index.html)
@@ -1614,7 +1896,7 @@ Emergency fix for a bug where an editor with line wrapping on IE will break when
* Slightly incompatible API changes. Read [this](https://codemirror.net/doc/upgrade_v2.2.html).
* New approach to [binding](https://codemirror.net/doc/manual.html#option_extraKeys) keys, support for [custom bindings](https://codemirror.net/doc/manual.html#option_keyMap).
* Support for overwrite (insert).
-* [Custom-width](https://codemirror.net/doc/manual.html#option_tabSize) and [stylable](https://codemirror.net/demo/visibletabs.html) tabs.
+* [Custom-width](https://codemirror.net/doc/manual.html#option_tabSize) and [styleable](https://codemirror.net/demo/visibletabs.html) tabs.
* Moved more code into [add-on scripts](https://codemirror.net/doc/manual.html#addons).
* Support for sane vertical cursor movement in wrapped lines.
* More reliable handling of editing [marked text](https://codemirror.net/doc/manual.html#markText).
@@ -1628,7 +1910,7 @@ Fixes `TextMarker.clear`, which is broken in 2.17.
## 2.17.0 (2011-11-21)
* Add support for [line wrapping](https://codemirror.net/doc/manual.html#option_lineWrapping) and [code folding](https://codemirror.net/doc/manual.html#hideLine).
-* Add [Github-style Markdown](https://codemirror.net/mode/gfm/index.html) mode.
+* Add [GitHub-style Markdown](https://codemirror.net/mode/gfm/index.html) mode.
* Add [Monokai](https://codemirror.net/theme/monokai.css) and [Rubyblue](https://codemirror.net/theme/rubyblue.css) themes.
* Add [`setBookmark`](https://codemirror.net/doc/manual.html#setBookmark) method.
* Move some of the demo code into reusable components under [`lib/util`](https://codemirror.net/addon/).
@@ -1729,4 +2011,4 @@ Add a [theme](https://codemirror.net/doc/manual.html#option_theme) system ([demo
## 2.0.0 (2011-03-28)
-CodeMirror 2 is a complete rewrite that's faster, smaller, simpler to use, and less dependent on browser quirks. See [this](https://codemirror.net/doc/internals.html) and [this](https://groups.google.com/group/codemirror/browse_thread/thread/5a8e894024a9f580) for more information.
+CodeMirror 2 is a complete rewrite that's faster, smaller, simpler to use, and less dependent on browser quirks. See [this](https://codemirror.net/doc/internals.html) and [this](http://groups.google.com/group/codemirror/browse_thread/thread/5a8e894024a9f580) for more information.
diff --git a/help3/xhpeditor/cm/README.md b/help3/xhpeditor/cm/README.md
index 2a7b1f5e..92debf44 100644
--- a/help3/xhpeditor/cm/README.md
+++ b/help3/xhpeditor/cm/README.md
@@ -2,7 +2,6 @@
[![Build Status](https://travis-ci.org/codemirror/CodeMirror.svg)](https://travis-ci.org/codemirror/CodeMirror)
[![NPM version](https://img.shields.io/npm/v/codemirror.svg)](https://www.npmjs.org/package/codemirror)
-[![Join the chat at https://gitter.im/codemirror/CodeMirror](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/codemirror/CodeMirror)
CodeMirror is a versatile text editor implemented in JavaScript for
the browser. It is specialized for editing code, and comes with over
diff --git a/help3/xhpeditor/cm/addon/comment/comment.js b/help3/xhpeditor/cm/addon/comment/comment.js
index 8394e85a..dac48d03 100644
--- a/help3/xhpeditor/cm/addon/comment/comment.js
+++ b/help3/xhpeditor/cm/addon/comment/comment.js
@@ -13,7 +13,7 @@
var noOptions = {};
var nonWS = /[^\s\u00a0]/;
- var Pos = CodeMirror.Pos;
+ var Pos = CodeMirror.Pos, cmp = CodeMirror.cmpPos;
function firstNonWS(str) {
var found = str.search(nonWS);
@@ -126,7 +126,9 @@
if (i != end || lastLineHasText)
self.replaceRange(lead + pad, Pos(i, 0));
} else {
+ var atCursor = cmp(self.getCursor("to"), to) == 0, empty = !self.somethingSelected()
self.replaceRange(endString, to);
+ if (atCursor) self.setSelection(empty ? to : self.getCursor("from"), to)
self.replaceRange(startString, from);
}
});
diff --git a/help3/xhpeditor/cm/addon/dialog/dialog.js b/help3/xhpeditor/cm/addon/dialog/dialog.js
index 23b06a83..5f1f4aa4 100644
--- a/help3/xhpeditor/cm/addon/dialog/dialog.js
+++ b/help3/xhpeditor/cm/addon/dialog/dialog.js
@@ -82,7 +82,9 @@
if (e.keyCode == 13) callback(inp.value, e);
});
- if (options.closeOnBlur !== false) CodeMirror.on(inp, "blur", close);
+ if (options.closeOnBlur !== false) CodeMirror.on(dialog, "focusout", function (evt) {
+ if (evt.relatedTarget !== null) close();
+ });
} else if (button = dialog.getElementsByTagName("button")[0]) {
CodeMirror.on(button, "click", function() {
close();
diff --git a/help3/xhpeditor/cm/addon/display/panel.js b/help3/xhpeditor/cm/addon/display/panel.js
index 4c9f2c0f..29f7e0be 100644
--- a/help3/xhpeditor/cm/addon/display/panel.js
+++ b/help3/xhpeditor/cm/addon/display/panel.js
@@ -76,7 +76,7 @@
};
function initPanels(cm) {
- var wrap = cm.getWrapperElement();
+ var wrap = cm.getWrapperElement()
var style = window.getComputedStyle ? window.getComputedStyle(wrap) : wrap.currentStyle;
var height = parseInt(style.height);
var info = cm.state.panels = {
@@ -84,9 +84,10 @@
panels: [],
wrapper: document.createElement("div")
};
+ var hasFocus = cm.hasFocus(), scrollPos = cm.getScrollInfo()
wrap.parentNode.insertBefore(info.wrapper, wrap);
- var hasFocus = cm.hasFocus();
info.wrapper.appendChild(wrap);
+ cm.scrollTo(scrollPos.left, scrollPos.top)
if (hasFocus) cm.focus();
cm._setSize = cm.setSize;
@@ -114,8 +115,11 @@
var info = cm.state.panels;
cm.state.panels = null;
- var wrap = cm.getWrapperElement();
+ var wrap = cm.getWrapperElement()
+ var hasFocus = cm.hasFocus(), scrollPos = cm.getScrollInfo()
info.wrapper.parentNode.replaceChild(wrap, info.wrapper);
+ cm.scrollTo(scrollPos.left, scrollPos.top)
+ if (hasFocus) cm.focus();
wrap.style.height = info.setHeight;
cm.setSize = cm._setSize;
cm.setSize();
diff --git a/help3/xhpeditor/cm/addon/display/placeholder.js b/help3/xhpeditor/cm/addon/display/placeholder.js
index 4eabe3d9..cfb8341d 100644
--- a/help3/xhpeditor/cm/addon/display/placeholder.js
+++ b/help3/xhpeditor/cm/addon/display/placeholder.js
@@ -15,11 +15,13 @@
cm.on("blur", onBlur);
cm.on("change", onChange);
cm.on("swapDoc", onChange);
+ CodeMirror.on(cm.getInputField(), "compositionupdate", cm.state.placeholderCompose = function() { onComposition(cm) })
onChange(cm);
} else if (!val && prev) {
cm.off("blur", onBlur);
cm.off("change", onChange);
cm.off("swapDoc", onChange);
+ CodeMirror.off(cm.getInputField(), "compositionupdate", cm.state.placeholderCompose)
clearPlaceholder(cm);
var wrapper = cm.getWrapperElement();
wrapper.className = wrapper.className.replace(" CodeMirror-empty", "");
@@ -46,6 +48,19 @@
cm.display.lineSpace.insertBefore(elt, cm.display.lineSpace.firstChild);
}
+ function onComposition(cm) {
+ setTimeout(function() {
+ var empty = false
+ if (cm.lineCount() == 1) {
+ var input = cm.getInputField()
+ empty = input.nodeName == "TEXTAREA" ? !cm.getLine(0).length
+ : !/[^\u200b]/.test(input.querySelector(".CodeMirror-line").textContent)
+ }
+ if (empty) setPlaceholder(cm)
+ else clearPlaceholder(cm)
+ }, 20)
+ }
+
function onBlur(cm) {
if (isEmpty(cm)) setPlaceholder(cm);
}
diff --git a/help3/xhpeditor/cm/addon/edit/closebrackets.js b/help3/xhpeditor/cm/addon/edit/closebrackets.js
index 4415c393..593d4439 100644
--- a/help3/xhpeditor/cm/addon/edit/closebrackets.js
+++ b/help3/xhpeditor/cm/addon/edit/closebrackets.js
@@ -87,7 +87,7 @@
cm.operation(function() {
var linesep = cm.lineSeparator() || "\n";
cm.replaceSelection(linesep + linesep, null);
- cm.execCommand("goCharLeft");
+ moveSel(cm, -1)
ranges = cm.listSelections();
for (var i = 0; i < ranges.length; i++) {
var line = ranges[i].head.line;
@@ -97,6 +97,17 @@
});
}
+ function moveSel(cm, dir) {
+ var newRanges = [], ranges = cm.listSelections(), primary = 0
+ for (var i = 0; i < ranges.length; i++) {
+ var range = ranges[i]
+ if (range.head == cm.getCursor()) primary = i
+ var pos = range.head.ch || dir > 0 ? {line: range.head.line, ch: range.head.ch + dir} : {line: range.head.line - 1}
+ newRanges.push({anchor: pos, head: pos})
+ }
+ cm.setSelections(newRanges, primary)
+ }
+
function contractSelection(sel) {
var inverted = CodeMirror.cmpPos(sel.anchor, sel.head) > 0;
return {anchor: new Pos(sel.anchor.line, sel.anchor.ch + (inverted ? -1 : 1)),
@@ -153,10 +164,9 @@
var right = pos % 2 ? ch : pairs.charAt(pos + 1);
cm.operation(function() {
if (type == "skip") {
- cm.execCommand("goCharRight");
+ moveSel(cm, 1)
} else if (type == "skipThree") {
- for (var i = 0; i < 3; i++)
- cm.execCommand("goCharRight");
+ moveSel(cm, 3)
} else if (type == "surround") {
var sels = cm.getSelections();
for (var i = 0; i < sels.length; i++)
@@ -169,10 +179,10 @@
} else if (type == "both") {
cm.replaceSelection(left + right, null);
cm.triggerElectric(left + right);
- cm.execCommand("goCharLeft");
+ moveSel(cm, -1)
} else if (type == "addFour") {
cm.replaceSelection(left + left + left + left, "before");
- cm.execCommand("goCharRight");
+ moveSel(cm, 1)
}
});
}
diff --git a/help3/xhpeditor/cm/addon/edit/closetag.js b/help3/xhpeditor/cm/addon/edit/closetag.js
index b8cbf950..7c22a50e 100644
--- a/help3/xhpeditor/cm/addon/edit/closetag.js
+++ b/help3/xhpeditor/cm/addon/edit/closetag.js
@@ -40,9 +40,9 @@
cm.removeKeyMap("autoCloseTags");
if (!val) return;
var map = {name: "autoCloseTags"};
- if (typeof val != "object" || val.whenClosing)
+ if (typeof val != "object" || val.whenClosing !== false)
map["'/'"] = function(cm) { return autoCloseSlash(cm); };
- if (typeof val != "object" || val.whenOpening)
+ if (typeof val != "object" || val.whenOpening !== false)
map["'>'"] = function(cm) { return autoCloseGT(cm); };
cm.addKeyMap(map);
});
@@ -128,9 +128,10 @@
replacement = head + "style";
} else {
var context = inner.mode.xmlCurrentContext && inner.mode.xmlCurrentContext(state)
- if (!context || (context.length && closingTagExists(cm, context, context[context.length - 1], pos)))
+ var top = context.length ? context[context.length - 1] : ""
+ if (!context || (context.length && closingTagExists(cm, context, top, pos)))
return CodeMirror.Pass;
- replacement = head + context[context.length - 1]
+ replacement = head + top
}
if (cm.getLine(pos.line).charAt(tok.end) != ">") replacement += ">";
replacements[i] = replacement;
diff --git a/help3/xhpeditor/cm/addon/edit/continuelist.js b/help3/xhpeditor/cm/addon/edit/continuelist.js
index fb5f0373..6ec65010 100644
--- a/help3/xhpeditor/cm/addon/edit/continuelist.js
+++ b/help3/xhpeditor/cm/addon/edit/continuelist.js
@@ -41,7 +41,9 @@
return;
}
if (emptyListRE.test(line)) {
- if (!/>\s*$/.test(line)) cm.replaceRange("", {
+ var endOfQuote = inQuote && />\s*$/.test(line)
+ var endOfList = !/>\s*$/.test(line)
+ if (endOfQuote || endOfList) cm.replaceRange("", {
line: pos.line, ch: 0
}, {
line: pos.line, ch: pos.ch + 1
@@ -88,7 +90,7 @@
});
} else {
if (startIndent.length > nextIndent.length) return;
- // This doesn't run if the next line immediatley indents, as it is
+ // This doesn't run if the next line immediately 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;
diff --git a/help3/xhpeditor/cm/addon/edit/matchbrackets.js b/help3/xhpeditor/cm/addon/edit/matchbrackets.js
index 2a147282..43dc8840 100644
--- a/help3/xhpeditor/cm/addon/edit/matchbrackets.js
+++ b/help3/xhpeditor/cm/addon/edit/matchbrackets.js
@@ -38,7 +38,7 @@
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);
+ var found = scanForBracket(cm, Pos(where.line, pos + (dir > 0 ? 1 : 0)), dir, style, config);
if (found == null) return null;
return {from: Pos(where.line, pos), to: found && found.pos,
match: found && found.ch == match.charAt(0), forward: dir > 0};
@@ -67,7 +67,8 @@
if (lineNo == where.line) pos = where.ch - (dir < 0 ? 1 : 0);
for (; pos != end; pos += dir) {
var ch = line.charAt(pos);
- if (re.test(ch) && (style === undefined || cm.getTokenTypeAt(Pos(lineNo, pos + 1)) == style)) {
+ if (re.test(ch) && (style === undefined ||
+ (cm.getTokenTypeAt(Pos(lineNo, pos + 1)) || "") == (style || ""))) {
var match = matching[ch];
if (match && (match.charAt(1) == ">") == (dir > 0)) stack.push(ch);
else if (!stack.length) return {pos: Pos(lineNo, pos), ch: ch};
@@ -80,11 +81,12 @@
function matchBrackets(cm, autoclear, config) {
// Disable brace matching in long lines, since it'll cause hugely slow updates
- var maxHighlightLen = cm.state.matchBrackets.maxHighlightLineLength || 1000;
+ var maxHighlightLen = cm.state.matchBrackets.maxHighlightLineLength || 1000,
+ highlightNonMatching = config && config.highlightNonMatching;
var marks = [], ranges = cm.listSelections();
for (var i = 0; i < ranges.length; i++) {
var match = ranges[i].empty() && findMatchingBracket(cm, ranges[i].head, config);
- if (match && cm.getLine(match.from.line).length <= maxHighlightLen) {
+ if (match && (match.match || highlightNonMatching !== false) && cm.getLine(match.from.line).length <= maxHighlightLen) {
var style = match.match ? "CodeMirror-matchingbracket" : "CodeMirror-nonmatchingbracket";
marks.push(cm.markText(match.from, Pos(match.from.line, match.from.ch + 1), {className: style}));
if (match.to && cm.getLine(match.to.line).length <= maxHighlightLen)
@@ -94,7 +96,7 @@
if (marks.length) {
// Kludge to work around the IE bug from issue #1193, where text
- // input stops going to the textare whever this fires.
+ // input stops going to the textarea whenever this fires.
if (ie_lt8 && cm.state.focused) cm.focus();
var clear = function() {
@@ -117,17 +119,25 @@
});
}
+ function clearHighlighted(cm) {
+ if (cm.state.matchBrackets && cm.state.matchBrackets.currentlyHighlighted) {
+ cm.state.matchBrackets.currentlyHighlighted();
+ cm.state.matchBrackets.currentlyHighlighted = null;
+ }
+ }
+
CodeMirror.defineOption("matchBrackets", false, function(cm, val, old) {
if (old && old != CodeMirror.Init) {
cm.off("cursorActivity", doMatchBrackets);
- if (cm.state.matchBrackets && cm.state.matchBrackets.currentlyHighlighted) {
- cm.state.matchBrackets.currentlyHighlighted();
- cm.state.matchBrackets.currentlyHighlighted = null;
- }
+ cm.off("focus", doMatchBrackets)
+ cm.off("blur", clearHighlighted)
+ clearHighlighted(cm);
}
if (val) {
cm.state.matchBrackets = typeof val == "object" ? val : {};
cm.on("cursorActivity", doMatchBrackets);
+ cm.on("focus", doMatchBrackets)
+ cm.on("blur", clearHighlighted)
}
});
diff --git a/help3/xhpeditor/cm/addon/fold/brace-fold.js b/help3/xhpeditor/cm/addon/fold/brace-fold.js
index 654d1fb6..79a331cf 100644
--- a/help3/xhpeditor/cm/addon/fold/brace-fold.js
+++ b/help3/xhpeditor/cm/addon/fold/brace-fold.js
@@ -31,13 +31,16 @@ CodeMirror.registerHelper("fold", "brace", function(cm, start) {
}
}
- var startToken = "{", endToken = "}", startCh = findOpening("{");
- if (startCh == null) {
- startToken = "[", endToken = "]";
- startCh = findOpening("[");
+ var startBrace = findOpening("{"), startBracket = findOpening("[")
+ var startToken, endToken, startCh
+ if (startBrace != null && (startBracket == null || startBracket > startBrace)) {
+ startCh = startBrace; startToken = "{"; endToken = "}"
+ } else if (startBracket != null) {
+ startCh = startBracket; startToken = "["; endToken = "]"
+ } else {
+ return
}
- if (startCh == null) return;
var count = 1, lastLine = cm.lastLine(), end, endCh;
outer: for (var i = line; i <= lastLine; ++i) {
var text = cm.getLine(i), pos = i == line ? startCh : 0;
diff --git a/help3/xhpeditor/cm/addon/hint/html-hint.js b/help3/xhpeditor/cm/addon/hint/html-hint.js
index d0cca4f6..9878eca6 100644
--- a/help3/xhpeditor/cm/addon/hint/html-hint.js
+++ b/help3/xhpeditor/cm/addon/hint/html-hint.js
@@ -98,6 +98,7 @@
dfn: s,
dir: s,
div: s,
+ dialog: { attrs: { open: null } },
dl: s,
dt: s,
em: s,
diff --git a/help3/xhpeditor/cm/addon/hint/javascript-hint.js b/help3/xhpeditor/cm/addon/hint/javascript-hint.js
index 182224d5..9f06b1b5 100644
--- a/help3/xhpeditor/cm/addon/hint/javascript-hint.js
+++ b/help3/xhpeditor/cm/addon/hint/javascript-hint.js
@@ -69,7 +69,7 @@
function getCoffeeScriptToken(editor, cur) {
// This getToken, it is for coffeescript, imitates the behavior of
// getTokenAt method in javascript.js, that is, returning "property"
- // type and treat "." as indepenent token.
+ // type and treat "." as independent token.
var token = editor.getTokenAt(cur);
if (cur.ch == token.start + 1 && token.string.charAt(0) == '.') {
token.end = token.start;
@@ -144,12 +144,15 @@
base = base[context.pop().string];
if (base != null) gatherCompletions(base);
} else {
- // If not, just look in the global object and any local scope
+ // If not, just look in the global object, any local scope, and optional additional-context
// (reading into JS mode internals to get at the local and global variables)
for (var v = token.state.localVars; v; v = v.next) maybeAdd(v.name);
for (var c = token.state.context; c; c = c.prev)
for (var v = c.vars; v; v = v.next) maybeAdd(v.name)
for (var v = token.state.globalVars; v; v = v.next) maybeAdd(v.name);
+ if (options && options.additionalContext != null)
+ for (var key in options.additionalContext)
+ maybeAdd(key);
if (!options || options.useGlobalScope !== false)
gatherCompletions(global);
forEach(keywords, maybeAdd);
diff --git a/help3/xhpeditor/cm/addon/hint/show-hint.js b/help3/xhpeditor/cm/addon/hint/show-hint.js
index 374cddfe..8f236562 100644
--- a/help3/xhpeditor/cm/addon/hint/show-hint.js
+++ b/help3/xhpeditor/cm/addon/hint/show-hint.js
@@ -1,6 +1,8 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
+// declare global: DOMRect
+
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
@@ -59,8 +61,10 @@
this.startPos = this.cm.getCursor("start");
this.startLen = this.cm.getLine(this.startPos.line).length - this.cm.getSelection().length;
- var self = this;
- cm.on("cursorActivity", this.activityFunc = function() { self.cursorActivity(); });
+ if (this.options.updateOnCursorActivity) {
+ var self = this;
+ cm.on("cursorActivity", this.activityFunc = function() { self.cursorActivity(); });
+ }
}
var requestAnimationFrame = window.requestAnimationFrame || function(fn) {
@@ -73,7 +77,9 @@
if (!this.active()) return;
this.cm.state.completionActive = null;
this.tick = null;
- this.cm.off("cursorActivity", this.activityFunc);
+ if (this.options.updateOnCursorActivity) {
+ this.cm.off("cursorActivity", this.activityFunc);
+ }
if (this.widget && this.data) CodeMirror.signal(this.data, "close");
if (this.widget) this.widget.close();
@@ -85,12 +91,19 @@
},
pick: function(data, i) {
- var completion = data.list[i];
- if (completion.hint) completion.hint(this.cm, data, completion);
- else this.cm.replaceRange(getText(completion), completion.from || data.from,
- completion.to || data.to, "complete");
- CodeMirror.signal(data, "pick", completion);
- this.close();
+ var completion = data.list[i], self = this;
+ this.cm.operation(function() {
+ if (completion.hint)
+ completion.hint(self.cm, data, completion);
+ else
+ self.cm.replaceRange(getText(completion), completion.from || data.from,
+ completion.to || data.to, "complete");
+ CodeMirror.signal(data, "pick", completion);
+ self.cm.scrollIntoView();
+ });
+ if (this.options.closeOnPick) {
+ this.close();
+ }
},
cursorActivity: function() {
@@ -99,9 +112,14 @@
this.debounce = 0;
}
+ var identStart = this.startPos;
+ if(this.data) {
+ identStart = this.data.from;
+ }
+
var pos = this.cm.getCursor(), line = this.cm.getLine(pos.line);
if (pos.line != this.startPos.line || line.length - pos.ch != this.startLen - this.startPos.ch ||
- pos.ch < this.startPos.ch || this.cm.somethingSelected() ||
+ pos.ch < identStart.ch || this.cm.somethingSelected() ||
(!pos.ch || this.options.closeCharacters.test(line.charAt(pos.ch - 1)))) {
this.close();
} else {
@@ -249,10 +267,15 @@
var winW = parentWindow.innerWidth || Math.max(ownerDocument.body.offsetWidth, ownerDocument.documentElement.offsetWidth);
var winH = parentWindow.innerHeight || Math.max(ownerDocument.body.offsetHeight, ownerDocument.documentElement.offsetHeight);
container.appendChild(hints);
- var box = hints.getBoundingClientRect(), overlapY = box.bottom - winH;
- var scrolls = hints.scrollHeight > hints.clientHeight + 1
- var startScroll = cm.getScrollInfo();
+ var box = completion.options.moveOnOverlap ? hints.getBoundingClientRect() : new DOMRect();
+ var scrolls = completion.options.paddingForScrollbar ? hints.scrollHeight > hints.clientHeight + 1 : false;
+
+ // Compute in the timeout to avoid reflow on init
+ var startScroll;
+ setTimeout(function() { startScroll = cm.getScrollInfo(); });
+
+ var overlapY = box.bottom - winH;
if (overlapY > 0) {
var height = box.bottom - box.top, curTop = pos.top - (pos.bottom - box.top);
if (curTop - height > 0) { // Fits above cursor
@@ -270,6 +293,7 @@
}
}
var overlapX = box.right - winW;
+ if (scrolls) overlapX += cm.display.nativeBarWidth;
if (overlapX > 0) {
if (box.right - box.left > winW) {
hints.style.width = (winW - 5) + "px";
@@ -298,6 +322,7 @@
cm.on("scroll", this.onScroll = function() {
var curScroll = cm.getScrollInfo(), editor = cm.getWrapperElement().getBoundingClientRect();
+ if (!startScroll) startScroll = cm.getScrollInfo();
var newTop = top + startScroll.top - curScroll.top;
var point = newTop - (parentWindow.pageYOffset || (ownerDocument.documentElement || ownerDocument.body).scrollTop);
if (!below) point += hints.offsetHeight;
@@ -322,7 +347,12 @@
CodeMirror.on(hints, "mousedown", function() {
setTimeout(function(){cm.focus();}, 20);
});
- this.scrollToActive()
+
+ // The first hint doesn't need to be scrolled to on init
+ var selectedHintRange = this.getSelectedHintRange();
+ if (selectedHintRange.from !== 0 || selectedHintRange.to !== 0) {
+ this.scrollToActive();
+ }
CodeMirror.signal(data, "select", completions[this.selectedHint], hints.childNodes[this.selectedHint]);
return true;
@@ -332,7 +362,7 @@
close: function() {
if (this.completion.widget != this) return;
this.completion.widget = null;
- this.hints.parentNode.removeChild(this.hints);
+ if (this.hints.parentNode) this.hints.parentNode.removeChild(this.hints);
this.completion.cm.removeKeyMap(this.keyMap);
var cm = this.completion.cm;
@@ -369,15 +399,26 @@
},
scrollToActive: function() {
- var node = this.hints.childNodes[this.selectedHint]
- if (node.offsetTop < this.hints.scrollTop)
- this.hints.scrollTop = node.offsetTop - 3;
- else if (node.offsetTop + node.offsetHeight > this.hints.scrollTop + this.hints.clientHeight)
- this.hints.scrollTop = node.offsetTop + node.offsetHeight - this.hints.clientHeight + 3;
+ var selectedHintRange = this.getSelectedHintRange();
+ var node1 = this.hints.childNodes[selectedHintRange.from];
+ var node2 = this.hints.childNodes[selectedHintRange.to];
+ var firstNode = this.hints.firstChild;
+ if (node1.offsetTop < this.hints.scrollTop)
+ this.hints.scrollTop = node1.offsetTop - firstNode.offsetTop;
+ else if (node2.offsetTop + node2.offsetHeight > this.hints.scrollTop + this.hints.clientHeight)
+ this.hints.scrollTop = node2.offsetTop + node2.offsetHeight - this.hints.clientHeight + firstNode.offsetTop;
},
screenAmount: function() {
return Math.floor(this.hints.clientHeight / this.hints.firstChild.offsetHeight) || 1;
+ },
+
+ getSelectedHintRange: function() {
+ var margin = this.completion.options.scrollMargin || 0;
+ return {
+ from: Math.max(0, this.selectedHint - margin),
+ to: Math.min(this.data.list.length - 1, this.selectedHint + margin),
+ };
}
};
@@ -455,11 +496,15 @@
completeSingle: true,
alignWithWord: true,
closeCharacters: /[\s()\[\]{};:>,]/,
+ closeOnPick: true,
closeOnUnfocus: true,
+ updateOnCursorActivity: true,
completeOnSingleClick: true,
container: null,
customKeys: null,
- extraKeys: null
+ extraKeys: null,
+ paddingForScrollbar: true,
+ moveOnOverlap: true,
};
CodeMirror.defineOption("hintOptions", null);
diff --git a/help3/xhpeditor/cm/addon/hint/sql-hint.js b/help3/xhpeditor/cm/addon/hint/sql-hint.js
index 444eba8b..efdce813 100644
--- a/help3/xhpeditor/cm/addon/hint/sql-hint.js
+++ b/help3/xhpeditor/cm/addon/hint/sql-hint.js
@@ -97,7 +97,7 @@
if (name.charAt(0) == ".") {
name = name.substr(1);
}
- // replace doublicated identifierQuotes with single identifierQuotes
+ // replace duplicated identifierQuotes with single identifierQuotes
// and remove single identifierQuotes
var nameParts = name.split(identifierQuote+identifierQuote);
for (var i = 0; i < nameParts.length; i++)
@@ -109,7 +109,7 @@
var nameParts = getText(name).split(".");
for (var i = 0; i < nameParts.length; i++)
nameParts[i] = identifierQuote +
- // doublicate identifierQuotes
+ // duplicate identifierQuotes
nameParts[i].replace(new RegExp(identifierQuote,"g"), identifierQuote+identifierQuote) +
identifierQuote;
var escaped = nameParts.join(".");
@@ -187,7 +187,7 @@
function eachWord(lineText, f) {
var words = lineText.split(/\s+/)
for (var i = 0; i < words.length; i++)
- if (words[i]) f(words[i].replace(/[,;]/g, ''))
+ if (words[i]) f(words[i].replace(/[`,;]/g, ''))
}
function findTableByAlias(alias, editor) {
@@ -264,7 +264,7 @@
token.string = token.string.slice(0, cur.ch - token.start);
}
- if (token.string.match(/^[.`"\w@]\w*$/)) {
+ if (token.string.match(/^[.`"'\w@][\w$#]*$/g)) {
search = token.string;
start = token.start;
end = token.end;
diff --git a/help3/xhpeditor/cm/addon/hint/xml-hint.js b/help3/xhpeditor/cm/addon/hint/xml-hint.js
index 7575b370..2b315312 100644
--- a/help3/xhpeditor/cm/addon/hint/xml-hint.js
+++ b/help3/xhpeditor/cm/addon/hint/xml-hint.js
@@ -101,8 +101,14 @@
}
replaceToken = true;
}
- for (var i = 0; i < atValues.length; ++i) if (!prefix || matches(atValues[i], prefix, matchInMiddle))
- result.push(quote + atValues[i] + quote);
+ var returnHintsFromAtValues = function(atValues) {
+ if (atValues)
+ for (var i = 0; i < atValues.length; ++i) if (!prefix || matches(atValues[i], prefix, matchInMiddle))
+ result.push(quote + atValues[i] + quote);
+ return returnHints();
+ };
+ if (atValues && atValues.then) return atValues.then(returnHintsFromAtValues);
+ return returnHintsFromAtValues(atValues);
} else { // An attribute name
if (token.type == "attribute") {
prefix = token.string;
@@ -112,11 +118,14 @@
result.push(attr);
}
}
- return {
- list: result,
- from: replaceToken ? Pos(cur.line, tagStart == null ? token.start : tagStart) : cur,
- to: replaceToken ? Pos(cur.line, token.end) : cur
- };
+ function returnHints() {
+ return {
+ list: result,
+ from: replaceToken ? Pos(cur.line, tagStart == null ? token.start : tagStart) : cur,
+ to: replaceToken ? Pos(cur.line, token.end) : cur
+ };
+ }
+ return returnHints();
}
CodeMirror.registerHelper("hint", "xml", getHints);
diff --git a/help3/xhpeditor/cm/addon/lint/javascript-lint.js b/help3/xhpeditor/cm/addon/lint/javascript-lint.js
index cc132d7f..e5bc7523 100644
--- a/help3/xhpeditor/cm/addon/lint/javascript-lint.js
+++ b/help3/xhpeditor/cm/addon/lint/javascript-lint.js
@@ -1,6 +1,8 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
+// Depends on jshint.js from https://github.com/jshint/jshint
+
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
diff --git a/help3/xhpeditor/cm/addon/lint/lint.css b/help3/xhpeditor/cm/addon/lint/lint.css
index f097cfe3..08718659 100644
--- a/help3/xhpeditor/cm/addon/lint/lint.css
+++ b/help3/xhpeditor/cm/addon/lint/lint.css
@@ -25,22 +25,20 @@
-ms-transition: opacity .4s;
}
-.CodeMirror-lint-mark-error, .CodeMirror-lint-mark-warning {
+.CodeMirror-lint-mark {
background-position: left bottom;
background-repeat: repeat-x;
}
-.CodeMirror-lint-mark-error {
- background-image:
- url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAYAAAC09K7GAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sJDw4cOCW1/KIAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAHElEQVQI12NggIL/DAz/GdA5/xkY/qPKMDAwAADLZwf5rvm+LQAAAABJRU5ErkJggg==")
- ;
-}
-
.CodeMirror-lint-mark-warning {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAYAAAC09K7GAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sJFhQXEbhTg7YAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAMklEQVQI12NkgIIvJ3QXMjAwdDN+OaEbysDA4MPAwNDNwMCwiOHLCd1zX07o6kBVGQEAKBANtobskNMAAAAASUVORK5CYII=");
}
-.CodeMirror-lint-marker-error, .CodeMirror-lint-marker-warning {
+.CodeMirror-lint-mark-error {
+ background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAYAAAC09K7GAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sJDw4cOCW1/KIAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAHElEQVQI12NggIL/DAz/GdA5/xkY/qPKMDAwAADLZwf5rvm+LQAAAABJRU5ErkJggg==");
+}
+
+.CodeMirror-lint-marker {
background-position: center center;
background-repeat: no-repeat;
cursor: pointer;
@@ -51,20 +49,20 @@
position: relative;
}
-.CodeMirror-lint-message-error, .CodeMirror-lint-message-warning {
+.CodeMirror-lint-message {
padding-left: 18px;
background-position: top left;
background-repeat: no-repeat;
}
-.CodeMirror-lint-marker-error, .CodeMirror-lint-message-error {
- background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAHlBMVEW7AAC7AACxAAC7AAC7AAAAAAC4AAC5AAD///+7AAAUdclpAAAABnRSTlMXnORSiwCK0ZKSAAAATUlEQVR42mWPOQ7AQAgDuQLx/z8csYRmPRIFIwRGnosRrpamvkKi0FTIiMASR3hhKW+hAN6/tIWhu9PDWiTGNEkTtIOucA5Oyr9ckPgAWm0GPBog6v4AAAAASUVORK5CYII=");
-}
-
.CodeMirror-lint-marker-warning, .CodeMirror-lint-message-warning {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAANlBMVEX/uwDvrwD/uwD/uwD/uwD/uwD/uwD/uwD/uwD6twD/uwAAAADurwD2tQD7uAD+ugAAAAD/uwDhmeTRAAAADHRSTlMJ8mN1EYcbmiixgACm7WbuAAAAVklEQVR42n3PUQqAIBBFUU1LLc3u/jdbOJoW1P08DA9Gba8+YWJ6gNJoNYIBzAA2chBth5kLmG9YUoG0NHAUwFXwO9LuBQL1giCQb8gC9Oro2vp5rncCIY8L8uEx5ZkAAAAASUVORK5CYII=");
}
+.CodeMirror-lint-marker-error, .CodeMirror-lint-message-error {
+ background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAHlBMVEW7AAC7AACxAAC7AAC7AAAAAAC4AAC5AAD///+7AAAUdclpAAAABnRSTlMXnORSiwCK0ZKSAAAATUlEQVR42mWPOQ7AQAgDuQLx/z8csYRmPRIFIwRGnosRrpamvkKi0FTIiMASR3hhKW+hAN6/tIWhu9PDWiTGNEkTtIOucA5Oyr9ckPgAWm0GPBog6v4AAAAASUVORK5CYII=");
+}
+
.CodeMirror-lint-marker-multiple {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAMAAADzjKfhAAAACVBMVEUAAAAAAAC/v7914kyHAAAAAXRSTlMAQObYZgAAACNJREFUeNo1ioEJAAAIwmz/H90iFFSGJgFMe3gaLZ0od+9/AQZ0ADosbYraAAAAAElFTkSuQmCC");
background-repeat: no-repeat;
diff --git a/help3/xhpeditor/cm/addon/lint/lint.js b/help3/xhpeditor/cm/addon/lint/lint.js
index aa75ba0e..395f0d93 100644
--- a/help3/xhpeditor/cm/addon/lint/lint.js
+++ b/help3/xhpeditor/cm/addon/lint/lint.js
@@ -12,11 +12,14 @@
"use strict";
var GUTTER_ID = "CodeMirror-lint-markers";
- function showTooltip(e, content) {
+ function showTooltip(cm, e, content) {
var tt = document.createElement("div");
- tt.className = "CodeMirror-lint-tooltip";
+ tt.className = "CodeMirror-lint-tooltip cm-s-" + cm.options.theme;
tt.appendChild(content.cloneNode(true));
- document.body.appendChild(tt);
+ if (cm.state.lint.options.selfContain)
+ cm.getWrapperElement().appendChild(tt);
+ else
+ document.body.appendChild(tt);
function position(e) {
if (!tt.parentNode) return CodeMirror.off(document, "mousemove", position);
@@ -38,8 +41,8 @@
setTimeout(function() { rm(tt); }, 600);
}
- function showTooltipFor(e, content, node) {
- var tooltip = showTooltip(e, content);
+ function showTooltipFor(cm, e, content, node) {
+ var tooltip = showTooltip(cm, e, content);
function hide() {
CodeMirror.off(node, "mouseout", hide);
if (tooltip) { hideTooltip(tooltip); tooltip = null; }
@@ -78,16 +81,16 @@
state.marked.length = 0;
}
- function makeMarker(labels, severity, multiple, tooltips) {
+ function makeMarker(cm, labels, severity, multiple, tooltips) {
var marker = document.createElement("div"), inner = marker;
- marker.className = "CodeMirror-lint-marker-" + severity;
+ marker.className = "CodeMirror-lint-marker CodeMirror-lint-marker-" + severity;
if (multiple) {
inner = marker.appendChild(document.createElement("div"));
- inner.className = "CodeMirror-lint-marker-multiple";
+ inner.className = "CodeMirror-lint-marker CodeMirror-lint-marker-multiple";
}
if (tooltips != false) CodeMirror.on(inner, "mouseover", function(e) {
- showTooltipFor(e, labels, inner);
+ showTooltipFor(cm, e, labels, inner);
});
return marker;
@@ -111,11 +114,11 @@
var severity = ann.severity;
if (!severity) severity = "error";
var tip = document.createElement("div");
- tip.className = "CodeMirror-lint-message-" + severity;
+ tip.className = "CodeMirror-lint-message CodeMirror-lint-message-" + severity;
if (typeof ann.messageHTML != 'undefined') {
- tip.innerHTML = ann.messageHTML;
+ tip.innerHTML = ann.messageHTML;
} else {
- tip.appendChild(document.createTextNode(ann.message));
+ tip.appendChild(document.createTextNode(ann.message));
}
return tip;
}
@@ -167,6 +170,10 @@
var anns = annotations[line];
if (!anns) continue;
+ // filter out duplicate messages
+ var message = [];
+ anns = anns.filter(function(item) { return message.indexOf(item.message) > -1 ? false : message.push(item.message) });
+
var maxSeverity = null;
var tipLabel = state.hasGutter && document.createDocumentFragment();
@@ -180,13 +187,13 @@
if (state.hasGutter) tipLabel.appendChild(annotationTooltip(ann));
if (ann.to) state.marked.push(cm.markText(ann.from, ann.to, {
- className: "CodeMirror-lint-mark-" + severity,
+ className: "CodeMirror-lint-mark CodeMirror-lint-mark-" + severity,
__annotation: ann
}));
}
-
+ // use original annotations[line] to show multiple messages
if (state.hasGutter)
- cm.setGutterMarker(line, GUTTER_ID, makeMarker(tipLabel, maxSeverity, anns.length > 1,
+ cm.setGutterMarker(line, GUTTER_ID, makeMarker(cm, tipLabel, maxSeverity, annotations[line].length > 1,
state.options.tooltips));
}
if (options.onUpdateLinting) options.onUpdateLinting(annotationsNotSorted, annotations, cm);
@@ -199,14 +206,14 @@
state.timeout = setTimeout(function(){startLinting(cm);}, state.options.delay || 500);
}
- function popupTooltips(annotations, e) {
+ function popupTooltips(cm, annotations, e) {
var target = e.target || e.srcElement;
var tooltip = document.createDocumentFragment();
for (var i = 0; i < annotations.length; i++) {
var ann = annotations[i];
tooltip.appendChild(annotationTooltip(ann));
}
- showTooltipFor(e, tooltip, target);
+ showTooltipFor(cm, e, tooltip, target);
}
function onMouseOver(cm, e) {
@@ -220,7 +227,7 @@
var ann = spans[i].__annotation;
if (ann) annotations.push(ann);
}
- if (annotations.length) popupTooltips(annotations, e);
+ if (annotations.length) popupTooltips(cm, annotations, e);
}
CodeMirror.defineOption("lint", false, function(cm, val, old) {
diff --git a/help3/xhpeditor/cm/addon/merge/merge.js b/help3/xhpeditor/cm/addon/merge/merge.js
index 8296540a..827edb71 100644
--- a/help3/xhpeditor/cm/addon/merge/merge.js
+++ b/help3/xhpeditor/cm/addon/merge/merge.js
@@ -443,22 +443,26 @@
aligners[i].clear();
aligners.length = 0;
- var cm = [dv.edit, dv.orig], scroll = [];
+ var cm = [dv.edit, dv.orig], scroll = [], offset = []
if (other) cm.push(other.orig);
- for (var i = 0; i < cm.length; i++)
+ for (var i = 0; i < cm.length; i++) {
scroll.push(cm[i].getScrollInfo().top);
+ offset.push(-cm[i].getScrollerElement().getBoundingClientRect().top)
+ }
+ if (offset[0] != offset[1] || cm.length == 3 && offset[1] != offset[2])
+ alignLines(cm, offset, [0, 0, 0], aligners)
for (var ln = 0; ln < linesToAlign.length; ln++)
- alignLines(cm, linesToAlign[ln], aligners);
+ alignLines(cm, offset, linesToAlign[ln], aligners);
for (var i = 0; i < cm.length; i++)
cm[i].scrollTo(null, scroll[i]);
}
- function alignLines(cm, lines, aligners) {
- var maxOffset = 0, offset = [];
+ function alignLines(cm, cmOffset, lines, aligners) {
+ var maxOffset = -1e8, offset = [];
for (var i = 0; i < cm.length; i++) if (lines[i] != null) {
- var off = cm[i].heightAtLine(lines[i], "local");
+ var off = cm[i].heightAtLine(lines[i], "local") - cmOffset[i];
offset[i] = off;
maxOffset = Math.max(maxOffset, off);
}
diff --git a/help3/xhpeditor/cm/addon/mode/loadmode.js b/help3/xhpeditor/cm/addon/mode/loadmode.js
index 4ce716a0..fc695d0c 100644
--- a/help3/xhpeditor/cm/addon/mode/loadmode.js
+++ b/help3/xhpeditor/cm/addon/mode/loadmode.js
@@ -16,8 +16,8 @@
var countDown = n;
return function() { if (--countDown == 0) cont(); };
}
- function ensureDeps(mode, cont) {
- var deps = CodeMirror.modes[mode].dependencies;
+ function ensureDeps(mode, cont, options) {
+ var modeObj = CodeMirror.modes[mode], deps = modeObj && modeObj.dependencies;
if (!deps) return cont();
var missing = [];
for (var i = 0; i < deps.length; ++i) {
@@ -27,16 +27,18 @@
if (!missing.length) return cont();
var split = splitCallback(cont, missing.length);
for (var i = 0; i < missing.length; ++i)
- CodeMirror.requireMode(missing[i], split);
+ CodeMirror.requireMode(missing[i], split, options);
}
- CodeMirror.requireMode = function(mode, cont) {
+ CodeMirror.requireMode = function(mode, cont, options) {
if (typeof mode != "string") mode = mode.name;
- if (CodeMirror.modes.hasOwnProperty(mode)) return ensureDeps(mode, cont);
+ if (CodeMirror.modes.hasOwnProperty(mode)) return ensureDeps(mode, cont, options);
if (loading.hasOwnProperty(mode)) return loading[mode].push(cont);
- var file = CodeMirror.modeURL.replace(/%N/g, mode);
- if (env == "plain") {
+ var file = options && options.path ? options.path(mode) : CodeMirror.modeURL.replace(/%N/g, mode);
+ if (options && options.loadMode) {
+ options.loadMode(file, function() { ensureDeps(mode, cont, options) })
+ } else if (env == "plain") {
var script = document.createElement("script");
script.src = file;
var others = document.getElementsByTagName("script")[0];
@@ -44,7 +46,7 @@
CodeMirror.on(script, "load", function() {
ensureDeps(mode, function() {
for (var i = 0; i < list.length; ++i) list[i]();
- });
+ }, options);
});
others.parentNode.insertBefore(script, others);
} else if (env == "cjs") {
@@ -55,10 +57,10 @@
}
};
- CodeMirror.autoLoadMode = function(instance, mode) {
+ CodeMirror.autoLoadMode = function(instance, mode, options) {
if (!CodeMirror.modes.hasOwnProperty(mode))
CodeMirror.requireMode(mode, function() {
instance.setOption("mode", instance.getOption("mode"));
- });
+ }, options);
};
});
diff --git a/help3/xhpeditor/cm/addon/mode/multiplex.js b/help3/xhpeditor/cm/addon/mode/multiplex.js
index 93fd9a5a..6140bc4f 100644
--- a/help3/xhpeditor/cm/addon/mode/multiplex.js
+++ b/help3/xhpeditor/cm/addon/mode/multiplex.js
@@ -12,7 +12,7 @@
"use strict";
CodeMirror.multiplexingMode = function(outer /*, others */) {
- // Others should be {open, close, mode [, delimStyle] [, innerStyle]} objects
+ // Others should be {open, close, mode [, delimStyle] [, innerStyle] [, parseDelimiters]} objects
var others = Array.prototype.slice.call(arguments, 1);
function indexOf(string, pattern, from, returnEnd) {
@@ -29,7 +29,8 @@ CodeMirror.multiplexingMode = function(outer /*, others */) {
return {
outer: CodeMirror.startState(outer),
innerActive: null,
- inner: null
+ inner: null,
+ startingInner: false
};
},
@@ -37,7 +38,8 @@ CodeMirror.multiplexingMode = function(outer /*, others */) {
return {
outer: CodeMirror.copyState(outer, state.outer),
innerActive: state.innerActive,
- inner: state.innerActive && CodeMirror.copyState(state.innerActive.mode, state.inner)
+ inner: state.innerActive && CodeMirror.copyState(state.innerActive.mode, state.inner),
+ startingInner: state.startingInner
};
},
@@ -49,6 +51,7 @@ CodeMirror.multiplexingMode = function(outer /*, others */) {
var found = indexOf(oldContent, other.open, stream.pos);
if (found == stream.pos) {
if (!other.parseDelimiters) stream.match(other.open);
+ state.startingInner = !!other.parseDelimiters
state.innerActive = other;
// Get the outer indent, making sure to handle CodeMirror.Pass
@@ -74,7 +77,8 @@ CodeMirror.multiplexingMode = function(outer /*, others */) {
state.innerActive = state.inner = null;
return this.token(stream, state);
}
- var found = curInner.close ? indexOf(oldContent, curInner.close, stream.pos, curInner.parseDelimiters) : -1;
+ var found = curInner.close && !state.startingInner ?
+ indexOf(oldContent, curInner.close, stream.pos, curInner.parseDelimiters) : -1;
if (found == stream.pos && !curInner.parseDelimiters) {
stream.match(curInner.close);
state.innerActive = state.inner = null;
@@ -83,6 +87,7 @@ CodeMirror.multiplexingMode = function(outer /*, others */) {
if (found > -1) stream.string = oldContent.slice(0, found);
var innerToken = curInner.mode.token(stream, state.inner);
if (found > -1) stream.string = oldContent;
+ else if (stream.pos > stream.start) state.startingInner = false
if (found == stream.pos && curInner.parseDelimiters)
state.innerActive = state.inner = null;
diff --git a/help3/xhpeditor/cm/addon/mode/multiplex_test.js b/help3/xhpeditor/cm/addon/mode/multiplex_test.js
index c51cad45..85039886 100644
--- a/help3/xhpeditor/cm/addon/mode/multiplex_test.js
+++ b/help3/xhpeditor/cm/addon/mode/multiplex_test.js
@@ -30,4 +30,20 @@
MT(
"stexInsideMarkdown",
"[strong **Equation:**] [delim&delim-open $][inner&tag \\pi][delim&delim-close $]");
+
+ CodeMirror.defineMode("identical_delim_multiplex", function() {
+ return CodeMirror.multiplexingMode(CodeMirror.getMode({indentUnit: 2}, "javascript"), {
+ open: "#",
+ close: "#",
+ mode: CodeMirror.getMode({}, "markdown"),
+ parseDelimiters: true,
+ innerStyle: "q"
+ });
+ });
+
+ var mode2 = CodeMirror.getMode({}, "identical_delim_multiplex");
+
+ test.mode("identical_delimiters_with_parseDelimiters", mode2, [
+ "[keyword let] [def x] [operator =] [q #foo][q&em *bar*][q #];"
+ ], "multiplexing")
})();
diff --git a/help3/xhpeditor/cm/addon/mode/simple.js b/help3/xhpeditor/cm/addon/mode/simple.js
index 655f9914..0d8cbdeb 100644
--- a/help3/xhpeditor/cm/addon/mode/simple.js
+++ b/help3/xhpeditor/cm/addon/mode/simple.js
@@ -68,6 +68,7 @@
var flags = "";
if (val instanceof RegExp) {
if (val.ignoreCase) flags = "i";
+ if (val.unicode) flags += "u"
val = val.source;
} else {
val = String(val);
@@ -137,10 +138,9 @@
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]});
+ (state.pending || (state.pending = [])).push({text: matches[j], token: rule.token[j - 1]});
stream.backUp(matches[0].length - (matches[1] ? matches[1].length : 0));
return token[0];
} else if (token && token.join) {
diff --git a/help3/xhpeditor/cm/addon/runmode/runmode-standalone.js b/help3/xhpeditor/cm/addon/runmode/runmode-standalone.js
index 745eaf84..76cf3d75 100644
--- a/help3/xhpeditor/cm/addon/runmode/runmode-standalone.js
+++ b/help3/xhpeditor/cm/addon/runmode/runmode-standalone.js
@@ -1,158 +1,334 @@
-// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: https://codemirror.net/LICENSE
-
-window.CodeMirror = {};
-
-(function() {
-"use strict";
-
-function splitLines(string){ return string.split(/\r?\n|\r/); };
-
-function StringStream(string) {
- this.pos = this.start = 0;
- this.string = string;
- this.lineStart = 0;
-}
-StringStream.prototype = {
- eol: function() {return this.pos >= this.string.length;},
- sol: function() {return this.pos == 0;},
- peek: function() {return this.string.charAt(this.pos) || null;},
- next: function() {
+(function () {
+ 'use strict';
+
+ function copyObj(obj, target, overwrite) {
+ if (!target) { target = {}; }
+ for (var prop in obj)
+ { if (obj.hasOwnProperty(prop) && (overwrite !== false || !target.hasOwnProperty(prop)))
+ { target[prop] = obj[prop]; } }
+ return target
+ }
+
+ // Counts the column offset in a string, taking tabs into account.
+ // Used mostly to find indentation.
+ function countColumn(string, end, tabSize, startIndex, startValue) {
+ if (end == null) {
+ end = string.search(/[^\s\u00a0]/);
+ if (end == -1) { end = string.length; }
+ }
+ for (var i = startIndex || 0, n = startValue || 0;;) {
+ var nextTab = string.indexOf("\t", i);
+ if (nextTab < 0 || nextTab >= end)
+ { return n + (end - i) }
+ n += nextTab - i;
+ n += tabSize - (n % tabSize);
+ i = nextTab + 1;
+ }
+ }
+
+ function nothing() {}
+
+ function createObj(base, props) {
+ var inst;
+ if (Object.create) {
+ inst = Object.create(base);
+ } else {
+ nothing.prototype = base;
+ inst = new nothing();
+ }
+ if (props) { copyObj(props, inst); }
+ return inst
+ }
+
+ // STRING STREAM
+
+ // Fed to the mode parsers, provides helper functions to make
+ // parsers more succinct.
+
+ 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};
+ StringStream.prototype.sol = function () {return this.pos == this.lineStart};
+ StringStream.prototype.peek = function () {return this.string.charAt(this.pos) || undefined};
+ StringStream.prototype.next = function () {
if (this.pos < this.string.length)
- return this.string.charAt(this.pos++);
- },
- eat: function(match) {
+ { return this.string.charAt(this.pos++) }
+ };
+ StringStream.prototype.eat = function (match) {
var ch = this.string.charAt(this.pos);
- if (typeof match == "string") var ok = ch == match;
- else var ok = ch && (match.test ? match.test(ch) : match(ch));
- if (ok) {++this.pos; return ch;}
- },
- eatWhile: function(match) {
+ var ok;
+ if (typeof match == "string") { ok = ch == match; }
+ else { ok = ch && (match.test ? match.test(ch) : match(ch)); }
+ if (ok) {++this.pos; return ch}
+ };
+ StringStream.prototype.eatWhile = function (match) {
var start = this.pos;
while (this.eat(match)){}
- return this.pos > start;
- },
- eatSpace: function() {
+ return this.pos > start
+ };
+ StringStream.prototype.eatSpace = function () {
var start = this.pos;
- while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos;
- return this.pos > start;
- },
- skipToEnd: function() {this.pos = this.string.length;},
- skipTo: function(ch) {
+ while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) { ++this.pos; }
+ return this.pos > start
+ };
+ StringStream.prototype.skipToEnd = function () {this.pos = this.string.length;};
+ StringStream.prototype.skipTo = function (ch) {
var found = this.string.indexOf(ch, this.pos);
- if (found > -1) {this.pos = found; return true;}
- },
- backUp: function(n) {this.pos -= n;},
- column: function() {return this.start - this.lineStart;},
- indentation: function() {return 0;},
- match: function(pattern, consume, caseInsensitive) {
+ if (found > -1) {this.pos = found; return true}
+ };
+ StringStream.prototype.backUp = function (n) {this.pos -= n;};
+ StringStream.prototype.column = function () {
+ if (this.lastColumnPos < this.start) {
+ this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue);
+ this.lastColumnPos = this.start;
+ }
+ return this.lastColumnValue - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0)
+ };
+ StringStream.prototype.indentation = function () {
+ return countColumn(this.string, null, this.tabSize) -
+ (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0)
+ };
+ StringStream.prototype.match = function (pattern, consume, caseInsensitive) {
if (typeof pattern == "string") {
- var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;};
+ var cased = function (str) { return caseInsensitive ? str.toLowerCase() : str; };
var substr = this.string.substr(this.pos, pattern.length);
if (cased(substr) == cased(pattern)) {
- if (consume !== false) this.pos += pattern.length;
- return true;
+ if (consume !== false) { this.pos += pattern.length; }
+ return true
}
} else {
var match = this.string.slice(this.pos).match(pattern);
- if (match && match.index > 0) return null;
- if (match && consume !== false) this.pos += match[0].length;
- return match;
+ if (match && match.index > 0) { return null }
+ if (match && consume !== false) { this.pos += match[0].length; }
+ return match
}
- },
- current: function(){return this.string.slice(this.start, this.pos);},
- hideFirstChars: function(n, inner) {
+ };
+ StringStream.prototype.current = function (){return this.string.slice(this.start, this.pos)};
+ StringStream.prototype.hideFirstChars = function (n, inner) {
this.lineStart += n;
- try { return inner(); }
+ try { return inner() }
finally { this.lineStart -= n; }
- },
- lookAhead: function() { return null }
-};
-CodeMirror.StringStream = StringStream;
-
-CodeMirror.startState = function (mode, a1, a2) {
- return mode.startState ? mode.startState(a1, a2) : true;
-};
-
-var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.mimeModes = {};
-CodeMirror.defineMode = function (name, mode) {
- if (arguments.length > 2)
- mode.dependencies = Array.prototype.slice.call(arguments, 2);
- modes[name] = mode;
-};
-CodeMirror.defineMIME = function (mime, spec) { mimeModes[mime] = spec; };
-CodeMirror.resolveMode = function(spec) {
- if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) {
- spec = mimeModes[spec];
- } else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) {
- spec = mimeModes[spec.name];
+ };
+ 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)
+ };
+
+ // Known modes, by name and by MIME
+ var modes = {}, mimeModes = {};
+
+ // Extra arguments are stored as the mode's dependencies, which is
+ // used by (legacy) mechanisms like loadmode.js to automatically
+ // load a mode. (Preferred mechanism is the require/define calls.)
+ function defineMode(name, mode) {
+ if (arguments.length > 2)
+ { mode.dependencies = Array.prototype.slice.call(arguments, 2); }
+ modes[name] = mode;
}
- if (typeof spec == "string") return {name: spec};
- else return spec || {name: "null"};
-};
-CodeMirror.getMode = function (options, spec) {
- spec = CodeMirror.resolveMode(spec);
- var mfactory = modes[spec.name];
- if (!mfactory) throw new Error("Unknown mode: " + spec);
- return mfactory(options, spec);
-};
-CodeMirror.registerHelper = CodeMirror.registerGlobalHelper = Math.min;
-CodeMirror.defineMode("null", function() {
- return {token: function(stream) {stream.skipToEnd();}};
-});
-CodeMirror.defineMIME("text/plain", "null");
-
-CodeMirror.runMode = function (string, modespec, callback, options) {
- var mode = CodeMirror.getMode({ indentUnit: 2 }, modespec);
-
- if (callback.nodeType == 1) {
- var tabSize = (options && options.tabSize) || 4;
- var node = callback, col = 0;
- node.innerHTML = "";
- callback = function (text, style) {
- if (text == "\n") {
- node.appendChild(document.createElement("br"));
- col = 0;
- return;
- }
- var content = "";
- // replace tabs
- for (var pos = 0; ;) {
- var idx = text.indexOf("\t", pos);
- if (idx == -1) {
- content += text.slice(pos);
- col += text.length - pos;
- break;
- } else {
- col += idx - pos;
- content += text.slice(pos, idx);
- var size = tabSize - col % tabSize;
- col += size;
- for (var i = 0; i < size; ++i) content += " ";
- pos = idx + 1;
- }
- }
- if (style) {
- var sp = node.appendChild(document.createElement("span"));
- sp.className = "cm-" + style.replace(/ +/g, " cm-");
- sp.appendChild(document.createTextNode(content));
- } else {
- node.appendChild(document.createTextNode(content));
+ function defineMIME(mime, spec) {
+ mimeModes[mime] = spec;
+ }
+
+ // Given a MIME type, a {name, ...options} config object, or a name
+ // string, return a mode config object.
+ function resolveMode(spec) {
+ if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) {
+ spec = mimeModes[spec];
+ } else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) {
+ var found = mimeModes[spec.name];
+ if (typeof found == "string") { found = {name: found}; }
+ spec = createObj(found, spec);
+ spec.name = found.name;
+ } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+xml$/.test(spec)) {
+ return resolveMode("application/xml")
+ } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+json$/.test(spec)) {
+ return resolveMode("application/json")
+ }
+ if (typeof spec == "string") { return {name: spec} }
+ else { return spec || {name: "null"} }
+ }
+
+ // Given a mode spec (anything that resolveMode accepts), find and
+ // initialize an actual mode object.
+ function getMode(options, spec) {
+ spec = resolveMode(spec);
+ var mfactory = modes[spec.name];
+ if (!mfactory) { return getMode(options, "text/plain") }
+ var modeObj = mfactory(options, spec);
+ if (modeExtensions.hasOwnProperty(spec.name)) {
+ var exts = modeExtensions[spec.name];
+ for (var prop in exts) {
+ if (!exts.hasOwnProperty(prop)) { continue }
+ if (modeObj.hasOwnProperty(prop)) { modeObj["_" + prop] = modeObj[prop]; }
+ modeObj[prop] = exts[prop];
}
- };
+ }
+ modeObj.name = spec.name;
+ if (spec.helperType) { modeObj.helperType = spec.helperType; }
+ if (spec.modeProps) { for (var prop$1 in spec.modeProps)
+ { modeObj[prop$1] = spec.modeProps[prop$1]; } }
+
+ return modeObj
}
- var lines = splitLines(string), state = (options && options.state) || CodeMirror.startState(mode);
- for (var i = 0, e = lines.length; i < e; ++i) {
- if (i) callback("\n");
- var stream = new CodeMirror.StringStream(lines[i]);
- if (!stream.string && mode.blankLine) mode.blankLine(state);
- while (!stream.eol()) {
- var style = mode.token(stream, state);
- callback(stream.current(), style, i, stream.start, state);
- stream.start = stream.pos;
+ // This can be used to attach properties to mode objects from
+ // outside the actual mode definition.
+ var modeExtensions = {};
+ function extendMode(mode, properties) {
+ var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {});
+ copyObj(properties, exts);
+ }
+
+ function copyState(mode, state) {
+ if (state === true) { return state }
+ if (mode.copyState) { return mode.copyState(state) }
+ var nstate = {};
+ for (var n in state) {
+ var val = state[n];
+ if (val instanceof Array) { val = val.concat([]); }
+ nstate[n] = val;
}
+ return nstate
+ }
+
+ // Given a mode and a state (for that mode), find the inner mode and
+ // state at the position that the state refers to.
+ function innerMode(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}
+ }
+
+ function startState(mode, a1, a2) {
+ return mode.startState ? mode.startState(a1, a2) : true
}
-};
-})();
+
+ var modeMethods = {
+ __proto__: null,
+ modes: modes,
+ mimeModes: mimeModes,
+ defineMode: defineMode,
+ defineMIME: defineMIME,
+ resolveMode: resolveMode,
+ getMode: getMode,
+ modeExtensions: modeExtensions,
+ extendMode: extendMode,
+ copyState: copyState,
+ innerMode: innerMode,
+ startState: startState
+ };
+
+ // declare global: globalThis, CodeMirror
+
+ // Create a minimal CodeMirror needed to use runMode, and assign to root.
+ var root = typeof globalThis !== 'undefined' ? globalThis : window;
+ root.CodeMirror = {};
+
+ // Copy StringStream and mode methods into CodeMirror object.
+ CodeMirror.StringStream = StringStream;
+ for (var exported in modeMethods) { CodeMirror[exported] = modeMethods[exported]; }
+
+ // Minimal default mode.
+ CodeMirror.defineMode("null", function () { return ({token: function (stream) { return stream.skipToEnd(); }}); });
+ CodeMirror.defineMIME("text/plain", "null");
+
+ CodeMirror.registerHelper = CodeMirror.registerGlobalHelper = Math.min;
+ CodeMirror.splitLines = function(string) { return string.split(/\r?\n|\r/) };
+ CodeMirror.countColumn = countColumn;
+
+ CodeMirror.defaults = { indentUnit: 2 };
+
+ // CodeMirror, copyright (c) by Marijn Haverbeke and others
+ // Distributed under an MIT license: https://codemirror.net/LICENSE
+
+ (function(mod) {
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
+ { mod(require("../../lib/codemirror")); }
+ else if (typeof define == "function" && define.amd) // AMD
+ { define(["../../lib/codemirror"], mod); }
+ else // Plain browser env
+ { mod(CodeMirror); }
+ })(function(CodeMirror) {
+
+ CodeMirror.runMode = function(string, modespec, callback, options) {
+ var mode = CodeMirror.getMode(CodeMirror.defaults, modespec);
+ var tabSize = (options && options.tabSize) || CodeMirror.defaults.tabSize;
+
+ // Create a tokenizing callback function if passed-in callback is a DOM element.
+ if (callback.appendChild) {
+ var ie = /MSIE \d/.test(navigator.userAgent);
+ var ie_lt9 = ie && (document.documentMode == null || document.documentMode < 9);
+ var node = callback, col = 0;
+ node.innerHTML = "";
+ callback = function(text, style) {
+ if (text == "\n") {
+ // Emitting LF or CRLF on IE8 or earlier results in an incorrect display.
+ // Emitting a carriage return makes everything ok.
+ node.appendChild(document.createTextNode(ie_lt9 ? '\r' : text));
+ col = 0;
+ return;
+ }
+ var content = "";
+ // replace tabs
+ for (var pos = 0;;) {
+ var idx = text.indexOf("\t", pos);
+ if (idx == -1) {
+ content += text.slice(pos);
+ col += text.length - pos;
+ break;
+ } else {
+ col += idx - pos;
+ content += text.slice(pos, idx);
+ var size = tabSize - col % tabSize;
+ col += size;
+ for (var i = 0; i < size; ++i) { content += " "; }
+ pos = idx + 1;
+ }
+ }
+ // Create a node with token style and append it to the callback DOM element.
+ if (style) {
+ var sp = node.appendChild(document.createElement("span"));
+ sp.className = "cm-" + style.replace(/ +/g, " cm-");
+ sp.appendChild(document.createTextNode(content));
+ } else {
+ node.appendChild(document.createTextNode(content));
+ }
+ };
+ }
+
+ var lines = CodeMirror.splitLines(string), state = (options && options.state) || CodeMirror.startState(mode);
+ for (var i = 0, e = lines.length; i < e; ++i) {
+ if (i) { callback("\n"); }
+ var stream = new CodeMirror.StringStream(lines[i], null, {
+ lookAhead: function(n) { return lines[i + n] },
+ baseToken: function() {}
+ });
+ if (!stream.string && mode.blankLine) { mode.blankLine(state); }
+ while (!stream.eol()) {
+ var style = mode.token(stream, state);
+ callback(stream.current(), style, i, stream.start, state, mode);
+ stream.start = stream.pos;
+ }
+ }
+ };
+
+ });
+
+}());
diff --git a/help3/xhpeditor/cm/addon/runmode/runmode.js b/help3/xhpeditor/cm/addon/runmode/runmode.js
index eb4cadf5..f5d58e24 100644
--- a/help3/xhpeditor/cm/addon/runmode/runmode.js
+++ b/help3/xhpeditor/cm/addon/runmode/runmode.js
@@ -13,11 +13,12 @@
CodeMirror.runMode = function(string, modespec, callback, options) {
var mode = CodeMirror.getMode(CodeMirror.defaults, modespec);
- var ie = /MSIE \d/.test(navigator.userAgent);
- var ie_lt9 = ie && (document.documentMode == null || document.documentMode < 9);
+ var tabSize = (options && options.tabSize) || CodeMirror.defaults.tabSize;
+ // Create a tokenizing callback function if passed-in callback is a DOM element.
if (callback.appendChild) {
- var tabSize = (options && options.tabSize) || CodeMirror.defaults.tabSize;
+ var ie = /MSIE \d/.test(navigator.userAgent);
+ var ie_lt9 = ie && (document.documentMode == null || document.documentMode < 9);
var node = callback, col = 0;
node.innerHTML = "";
callback = function(text, style) {
@@ -45,7 +46,7 @@ CodeMirror.runMode = function(string, modespec, callback, options) {
pos = idx + 1;
}
}
-
+ // Create a node with token style and append it to the callback DOM element.
if (style) {
var sp = node.appendChild(document.createElement("span"));
sp.className = "cm-" + style.replace(/ +/g, " cm-");
@@ -59,11 +60,14 @@ CodeMirror.runMode = function(string, modespec, callback, options) {
var lines = CodeMirror.splitLines(string), state = (options && options.state) || CodeMirror.startState(mode);
for (var i = 0, e = lines.length; i < e; ++i) {
if (i) callback("\n");
- var stream = new CodeMirror.StringStream(lines[i]);
+ var stream = new CodeMirror.StringStream(lines[i], null, {
+ lookAhead: function(n) { return lines[i + n] },
+ baseToken: function() {}
+ });
if (!stream.string && mode.blankLine) mode.blankLine(state);
while (!stream.eol()) {
var style = mode.token(stream, state);
- callback(stream.current(), style, i, stream.start, state);
+ callback(stream.current(), style, i, stream.start, state, mode);
stream.start = stream.pos;
}
}
diff --git a/help3/xhpeditor/cm/addon/runmode/runmode.node.js b/help3/xhpeditor/cm/addon/runmode/runmode.node.js
index 53b6994c..ddd255ab 100644
--- a/help3/xhpeditor/cm/addon/runmode/runmode.node.js
+++ b/help3/xhpeditor/cm/addon/runmode/runmode.node.js
@@ -1,197 +1,329 @@
-// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: https://codemirror.net/LICENSE
-
-/* Just enough of CodeMirror to run runMode under node.js */
+'use strict';
-function splitLines(string){return string.split(/\r\n?|\n/);};
+function copyObj(obj, target, overwrite) {
+ if (!target) { target = {}; }
+ for (var prop in obj)
+ { if (obj.hasOwnProperty(prop) && (overwrite !== false || !target.hasOwnProperty(prop)))
+ { target[prop] = obj[prop]; } }
+ return target
+}
// Counts the column offset in a string, taking tabs into account.
// Used mostly to find indentation.
-var countColumn = exports.countColumn = function(string, end, tabSize, startIndex, startValue) {
+function countColumn(string, end, tabSize, startIndex, startValue) {
if (end == null) {
end = string.search(/[^\s\u00a0]/);
- if (end == -1) end = string.length;
+ if (end == -1) { end = string.length; }
}
for (var i = startIndex || 0, n = startValue || 0;;) {
var nextTab = string.indexOf("\t", i);
if (nextTab < 0 || nextTab >= end)
- return n + (end - i);
+ { return n + (end - i) }
n += nextTab - i;
n += tabSize - (n % tabSize);
i = nextTab + 1;
}
-};
+}
+
+function nothing() {}
+
+function createObj(base, props) {
+ var inst;
+ if (Object.create) {
+ inst = Object.create(base);
+ } else {
+ nothing.prototype = base;
+ inst = new nothing();
+ }
+ if (props) { copyObj(props, inst); }
+ return inst
+}
+
+// STRING STREAM
-function StringStream(string, tabSize, context) {
+// Fed to the mode parsers, provides helper functions to make
+// parsers more succinct.
+
+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.context = context
+ this.lineOracle = lineOracle;
};
-StringStream.prototype = {
- eol: function() {return this.pos >= this.string.length;},
- sol: function() {return this.pos == this.lineStart;},
- peek: function() {return this.string.charAt(this.pos) || undefined;},
- next: function() {
- if (this.pos < this.string.length)
- return this.string.charAt(this.pos++);
- },
- eat: function(match) {
- var ch = this.string.charAt(this.pos);
- if (typeof match == "string") var ok = ch == match;
- else var ok = ch && (match.test ? match.test(ch) : match(ch));
- if (ok) {++this.pos; return ch;}
- },
- eatWhile: function(match) {
- var start = this.pos;
- while (this.eat(match)){}
- return this.pos > start;
- },
- eatSpace: function() {
- var start = this.pos;
- while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos;
- return this.pos > start;
- },
- skipToEnd: function() {this.pos = this.string.length;},
- skipTo: function(ch) {
- var found = this.string.indexOf(ch, this.pos);
- if (found > -1) {this.pos = found; return true;}
- },
- backUp: function(n) {this.pos -= n;},
- column: function() {
- if (this.lastColumnPos < this.start) {
- this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue);
- this.lastColumnPos = this.start;
- }
- return this.lastColumnValue - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0);
- },
- indentation: function() {
- return countColumn(this.string, null, this.tabSize) -
- (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0);
- },
- match: function(pattern, consume, caseInsensitive) {
- if (typeof pattern == "string") {
- var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;};
- var substr = this.string.substr(this.pos, pattern.length);
- if (cased(substr) == cased(pattern)) {
- if (consume !== false) this.pos += pattern.length;
- return true;
- }
- } else {
- var match = this.string.slice(this.pos).match(pattern);
- if (match && match.index > 0) return null;
- if (match && consume !== false) this.pos += match[0].length;
- return match;
+StringStream.prototype.eol = function () {return this.pos >= this.string.length};
+StringStream.prototype.sol = function () {return this.pos == this.lineStart};
+StringStream.prototype.peek = function () {return this.string.charAt(this.pos) || undefined};
+StringStream.prototype.next = function () {
+ if (this.pos < this.string.length)
+ { return this.string.charAt(this.pos++) }
+};
+StringStream.prototype.eat = function (match) {
+ var ch = this.string.charAt(this.pos);
+ var ok;
+ if (typeof match == "string") { ok = ch == match; }
+ else { ok = ch && (match.test ? match.test(ch) : match(ch)); }
+ if (ok) {++this.pos; return ch}
+};
+StringStream.prototype.eatWhile = function (match) {
+ var start = this.pos;
+ while (this.eat(match)){}
+ return this.pos > start
+};
+StringStream.prototype.eatSpace = function () {
+ var start = this.pos;
+ while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) { ++this.pos; }
+ return this.pos > start
+};
+StringStream.prototype.skipToEnd = function () {this.pos = this.string.length;};
+StringStream.prototype.skipTo = function (ch) {
+ var found = this.string.indexOf(ch, this.pos);
+ if (found > -1) {this.pos = found; return true}
+};
+StringStream.prototype.backUp = function (n) {this.pos -= n;};
+StringStream.prototype.column = function () {
+ if (this.lastColumnPos < this.start) {
+ this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue);
+ this.lastColumnPos = this.start;
+ }
+ return this.lastColumnValue - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0)
+};
+StringStream.prototype.indentation = function () {
+ return countColumn(this.string, null, this.tabSize) -
+ (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0)
+};
+StringStream.prototype.match = function (pattern, consume, caseInsensitive) {
+ if (typeof pattern == "string") {
+ var cased = function (str) { return caseInsensitive ? str.toLowerCase() : str; };
+ var substr = this.string.substr(this.pos, pattern.length);
+ if (cased(substr) == cased(pattern)) {
+ if (consume !== false) { this.pos += pattern.length; }
+ return true
}
- },
- current: function(){return this.string.slice(this.start, this.pos);},
- hideFirstChars: function(n, inner) {
- 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]
+ } else {
+ var match = this.string.slice(this.pos).match(pattern);
+ if (match && match.index > 0) { return null }
+ if (match && consume !== false) { this.pos += match[0].length; }
+ return match
}
};
-exports.StringStream = StringStream;
-
-exports.startState = function(mode, a1, a2) {
- return mode.startState ? mode.startState(a1, a2) : true;
+StringStream.prototype.current = function (){return this.string.slice(this.start, this.pos)};
+StringStream.prototype.hideFirstChars = function (n, inner) {
+ this.lineStart += n;
+ 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 modes = exports.modes = {}, mimeModes = exports.mimeModes = {};
-exports.defineMode = function(name, mode) {
+// Known modes, by name and by MIME
+var modes = {}, mimeModes = {};
+
+// Extra arguments are stored as the mode's dependencies, which is
+// used by (legacy) mechanisms like loadmode.js to automatically
+// load a mode. (Preferred mechanism is the require/define calls.)
+function defineMode(name, mode) {
if (arguments.length > 2)
- mode.dependencies = Array.prototype.slice.call(arguments, 2);
+ { mode.dependencies = Array.prototype.slice.call(arguments, 2); }
modes[name] = mode;
-};
-exports.defineMIME = function(mime, spec) { mimeModes[mime] = spec; };
+}
-exports.defineMode("null", function() {
- return {token: function(stream) {stream.skipToEnd();}};
-});
-exports.defineMIME("text/plain", "null");
+function defineMIME(mime, spec) {
+ mimeModes[mime] = spec;
+}
-exports.resolveMode = function(spec) {
+// Given a MIME type, a {name, ...options} config object, or a name
+// string, return a mode config object.
+function resolveMode(spec) {
if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) {
spec = mimeModes[spec];
} else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) {
- spec = mimeModes[spec.name];
+ var found = mimeModes[spec.name];
+ if (typeof found == "string") { found = {name: found}; }
+ spec = createObj(found, spec);
+ spec.name = found.name;
+ } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+xml$/.test(spec)) {
+ return resolveMode("application/xml")
+ } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+json$/.test(spec)) {
+ return resolveMode("application/json")
}
- if (typeof spec == "string") return {name: spec};
- else return spec || {name: "null"};
-};
-
-function copyObj(obj, target, overwrite) {
- if (!target) target = {};
- for (var prop in obj)
- if (obj.hasOwnProperty(prop) && (overwrite !== false || !target.hasOwnProperty(prop)))
- target[prop] = obj[prop];
- return target;
+ if (typeof spec == "string") { return {name: spec} }
+ else { return spec || {name: "null"} }
}
-// This can be used to attach properties to mode objects from
-// outside the actual mode definition.
-var modeExtensions = exports.modeExtensions = {};
-exports.extendMode = function(mode, properties) {
- var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {});
- copyObj(properties, exts);
-};
-
-exports.getMode = function(options, spec) {
- var spec = exports.resolveMode(spec);
+// Given a mode spec (anything that resolveMode accepts), find and
+// initialize an actual mode object.
+function getMode(options, spec) {
+ spec = resolveMode(spec);
var mfactory = modes[spec.name];
- if (!mfactory) return exports.getMode(options, "text/plain");
+ if (!mfactory) { return getMode(options, "text/plain") }
var modeObj = mfactory(options, spec);
if (modeExtensions.hasOwnProperty(spec.name)) {
var exts = modeExtensions[spec.name];
for (var prop in exts) {
- if (!exts.hasOwnProperty(prop)) continue;
- if (modeObj.hasOwnProperty(prop)) modeObj["_" + prop] = modeObj[prop];
+ if (!exts.hasOwnProperty(prop)) { continue }
+ if (modeObj.hasOwnProperty(prop)) { modeObj["_" + prop] = modeObj[prop]; }
modeObj[prop] = exts[prop];
}
}
modeObj.name = spec.name;
- if (spec.helperType) modeObj.helperType = spec.helperType;
- if (spec.modeProps) for (var prop in spec.modeProps)
- modeObj[prop] = spec.modeProps[prop];
+ if (spec.helperType) { modeObj.helperType = spec.helperType; }
+ if (spec.modeProps) { for (var prop$1 in spec.modeProps)
+ { modeObj[prop$1] = spec.modeProps[prop$1]; } }
- return modeObj;
-};
+ return modeObj
+}
+
+// This can be used to attach properties to mode objects from
+// outside the actual mode definition.
+var modeExtensions = {};
+function extendMode(mode, properties) {
+ var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {});
+ copyObj(properties, exts);
+}
+
+function copyState(mode, state) {
+ if (state === true) { return state }
+ if (mode.copyState) { return mode.copyState(state) }
+ var nstate = {};
+ for (var n in state) {
+ var val = state[n];
+ if (val instanceof Array) { val = val.concat([]); }
+ nstate[n] = val;
+ }
+ return nstate
+}
-exports.innerMode = function(mode, state) {
+// Given a mode and a state (for that mode), find the inner mode and
+// state at the position that the state refers to.
+function innerMode(mode, state) {
var info;
while (mode.innerMode) {
info = mode.innerMode(state);
- if (!info || info.mode == mode) break;
+ if (!info || info.mode == mode) { break }
state = info.state;
mode = info.mode;
}
- return info || {mode: mode, state: state};
+ return info || {mode: mode, state: state}
}
+function startState(mode, a1, a2) {
+ return mode.startState ? mode.startState(a1, a2) : true
+}
+
+var modeMethods = {
+ __proto__: null,
+ modes: modes,
+ mimeModes: mimeModes,
+ defineMode: defineMode,
+ defineMIME: defineMIME,
+ resolveMode: resolveMode,
+ getMode: getMode,
+ modeExtensions: modeExtensions,
+ extendMode: extendMode,
+ copyState: copyState,
+ innerMode: innerMode,
+ startState: startState
+};
+
+// Copy StringStream and mode methods into exports (CodeMirror) object.
+exports.StringStream = StringStream;
+exports.countColumn = countColumn;
+for (var exported in modeMethods) { exports[exported] = modeMethods[exported]; }
+
+// Shim library CodeMirror with the minimal CodeMirror defined above.
+require.cache[require.resolve("../../lib/codemirror")] = require.cache[require.resolve("./runmode.node")];
+require.cache[require.resolve("../../addon/runmode/runmode")] = require.cache[require.resolve("./runmode.node")];
+
+// Minimal default mode.
+exports.defineMode("null", function () { return ({token: function (stream) { return stream.skipToEnd(); }}); });
+exports.defineMIME("text/plain", "null");
+
exports.registerHelper = exports.registerGlobalHelper = Math.min;
+exports.splitLines = function(string) { return string.split(/\r?\n|\r/) };
+
+exports.defaults = { indentUnit: 2 };
+
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: https://codemirror.net/LICENSE
-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);
- 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], 4, context);
- if (!stream.string && mode.blankLine) mode.blankLine(state);
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
+ { mod(require("../../lib/codemirror")); }
+ else if (typeof define == "function" && define.amd) // AMD
+ { define(["../../lib/codemirror"], mod); }
+ else // Plain browser env
+ { mod(CodeMirror); }
+})(function(CodeMirror) {
+
+CodeMirror.runMode = function(string, modespec, callback, options) {
+ var mode = CodeMirror.getMode(CodeMirror.defaults, modespec);
+ var tabSize = (options && options.tabSize) || CodeMirror.defaults.tabSize;
+
+ // Create a tokenizing callback function if passed-in callback is a DOM element.
+ if (callback.appendChild) {
+ var ie = /MSIE \d/.test(navigator.userAgent);
+ var ie_lt9 = ie && (document.documentMode == null || document.documentMode < 9);
+ var node = callback, col = 0;
+ node.innerHTML = "";
+ callback = function(text, style) {
+ if (text == "\n") {
+ // Emitting LF or CRLF on IE8 or earlier results in an incorrect display.
+ // Emitting a carriage return makes everything ok.
+ node.appendChild(document.createTextNode(ie_lt9 ? '\r' : text));
+ col = 0;
+ return;
+ }
+ var content = "";
+ // replace tabs
+ for (var pos = 0;;) {
+ var idx = text.indexOf("\t", pos);
+ if (idx == -1) {
+ content += text.slice(pos);
+ col += text.length - pos;
+ break;
+ } else {
+ col += idx - pos;
+ content += text.slice(pos, idx);
+ var size = tabSize - col % tabSize;
+ col += size;
+ for (var i = 0; i < size; ++i) { content += " "; }
+ pos = idx + 1;
+ }
+ }
+ // Create a node with token style and append it to the callback DOM element.
+ if (style) {
+ var sp = node.appendChild(document.createElement("span"));
+ sp.className = "cm-" + style.replace(/ +/g, " cm-");
+ sp.appendChild(document.createTextNode(content));
+ } else {
+ node.appendChild(document.createTextNode(content));
+ }
+ };
+ }
+
+ var lines = CodeMirror.splitLines(string), state = (options && options.state) || CodeMirror.startState(mode);
+ for (var i = 0, e = lines.length; i < e; ++i) {
+ if (i) { callback("\n"); }
+ var stream = new CodeMirror.StringStream(lines[i], null, {
+ lookAhead: function(n) { return lines[i + n] },
+ baseToken: function() {}
+ });
+ if (!stream.string && mode.blankLine) { mode.blankLine(state); }
while (!stream.eol()) {
var style = mode.token(stream, state);
- callback(stream.current(), style, i, stream.start, state);
+ callback(stream.current(), style, i, stream.start, state, mode);
stream.start = stream.pos;
}
}
};
-require.cache[require.resolve("../../lib/codemirror")] = require.cache[require.resolve("./runmode.node")];
-require.cache[require.resolve("../../addon/runmode/runmode")] = require.cache[require.resolve("./runmode.node")];
+});
diff --git a/help3/xhpeditor/cm/addon/scroll/annotatescrollbar.js b/help3/xhpeditor/cm/addon/scroll/annotatescrollbar.js
index 9fe61ec1..c12e44cd 100644
--- a/help3/xhpeditor/cm/addon/scroll/annotatescrollbar.js
+++ b/help3/xhpeditor/cm/addon/scroll/annotatescrollbar.js
@@ -72,10 +72,16 @@
var wrapping = cm.getOption("lineWrapping");
var singleLineH = wrapping && cm.defaultTextHeight() * 1.5;
var curLine = null, curLineObj = null;
+
function getY(pos, top) {
if (curLine != pos.line) {
- curLine = pos.line;
- curLineObj = cm.getLineHandle(curLine);
+ curLine = pos.line
+ curLineObj = cm.getLineHandle(pos.line)
+ var visual = cm.getLineHandleVisualStart(curLineObj)
+ if (visual != curLineObj) {
+ curLine = cm.getLineNumber(visual)
+ curLineObj = visual
+ }
}
if ((curLineObj.widgets && curLineObj.widgets.length) ||
(wrapping && curLineObj.height > singleLineH))
diff --git a/help3/xhpeditor/cm/addon/search/jump-to-line.js b/help3/xhpeditor/cm/addon/search/jump-to-line.js
index 1f3526d2..990c235e 100644
--- a/help3/xhpeditor/cm/addon/search/jump-to-line.js
+++ b/help3/xhpeditor/cm/addon/search/jump-to-line.js
@@ -13,8 +13,11 @@
})(function(CodeMirror) {
"use strict";
+ // default search panel location
+ CodeMirror.defineOption("search", {bottom: false});
+
function dialog(cm, text, shortText, deflt, f) {
- if (cm.openDialog) cm.openDialog(text, f, {value: deflt, selectValueOnOpen: true});
+ if (cm.openDialog) cm.openDialog(text, f, {value: deflt, selectValueOnOpen: true, bottom: cm.options.search.bottom});
else f(prompt(shortText, deflt));
}
diff --git a/help3/xhpeditor/cm/addon/search/match-highlighter.js b/help3/xhpeditor/cm/addon/search/match-highlighter.js
index b344ac79..9b181ebc 100644
--- a/help3/xhpeditor/cm/addon/search/match-highlighter.js
+++ b/help3/xhpeditor/cm/addon/search/match-highlighter.js
@@ -16,7 +16,7 @@
// highlighted only if the selected text is a word. showToken, when enabled,
// will cause the current token to be highlighted when nothing is selected.
// delay is used to specify how much time to wait, in milliseconds, before
-// highlighting the matches. If annotateScrollbar is enabled, the occurences
+// highlighting the matches. If annotateScrollbar is enabled, the occurrences
// will be highlighted on the scrollbar via the matchesonscrollbar addon.
(function(mod) {
@@ -90,7 +90,9 @@
var state = cm.state.matchHighlighter;
cm.addOverlay(state.overlay = makeOverlay(query, hasBoundary, style));
if (state.options.annotateScrollbar && cm.showMatchesOnScrollbar) {
- var searchFor = hasBoundary ? new RegExp("\\b" + query.replace(/[\\\[.+*?(){|^$]/g, "\\$&") + "\\b") : query;
+ var searchFor = hasBoundary ? new RegExp((/\w/.test(query.charAt(0)) ? "\\b" : "") +
+ query.replace(/[\\\[.+*?(){|^$]/g, "\\$&") +
+ (/\w/.test(query.charAt(query.length - 1)) ? "\\b" : "")) : query;
state.matchesonscroll = cm.showMatchesOnScrollbar(searchFor, false,
{className: "CodeMirror-selection-highlight-scrollbar"});
}
diff --git a/help3/xhpeditor/cm/addon/search/search.js b/help3/xhpeditor/cm/addon/search/search.js
index cecdd52e..118f1112 100644
--- a/help3/xhpeditor/cm/addon/search/search.js
+++ b/help3/xhpeditor/cm/addon/search/search.js
@@ -19,6 +19,9 @@
})(function(CodeMirror) {
"use strict";
+ // default search panel location
+ CodeMirror.defineOption("search", {bottom: false});
+
function searchOverlay(query, caseInsensitive) {
if (typeof query == "string")
query = new RegExp(query.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"), caseInsensitive ? "gi" : "g");
@@ -63,12 +66,13 @@
selectValueOnOpen: true,
closeOnEnter: false,
onClose: function() { clearSearch(cm); },
- onKeyDown: onKeyDown
+ onKeyDown: onKeyDown,
+ bottom: cm.options.search.bottom
});
}
function dialog(cm, text, shortText, deflt, f) {
- if (cm.openDialog) cm.openDialog(text, f, {value: deflt, selectValueOnOpen: true});
+ if (cm.openDialog) cm.openDialog(text, f, {value: deflt, selectValueOnOpen: true, bottom: cm.options.search.bottom});
else f(prompt(shortText, deflt));
}
diff --git a/help3/xhpeditor/cm/addon/search/searchcursor.js b/help3/xhpeditor/cm/addon/search/searchcursor.js
index 816bf774..d5869578 100644
--- a/help3/xhpeditor/cm/addon/search/searchcursor.js
+++ b/help3/xhpeditor/cm/addon/search/searchcursor.js
@@ -240,7 +240,7 @@
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)
+ // backwards-compatibility 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)
diff --git a/help3/xhpeditor/cm/addon/tern/tern.js b/help3/xhpeditor/cm/addon/tern/tern.js
index 253309d6..a8837174 100644
--- a/help3/xhpeditor/cm/addon/tern/tern.js
+++ b/help3/xhpeditor/cm/addon/tern/tern.js
@@ -231,8 +231,7 @@
var content = ts.options.completionTip ? ts.options.completionTip(cur.data) : cur.data.doc;
if (content) {
tooltip = makeTooltip(node.parentNode.getBoundingClientRect().right + window.pageXOffset,
- node.getBoundingClientRect().top + window.pageYOffset, content);
- tooltip.className += " " + cls + "hint-doc";
+ node.getBoundingClientRect().top + window.pageYOffset, content, cm, cls + "hint-doc");
}
});
c(obj);
@@ -334,7 +333,7 @@
tip.appendChild(document.createTextNode(tp.rettype ? ") ->\u00a0" : ")"));
if (tp.rettype) tip.appendChild(elt("span", cls + "type", tp.rettype));
var place = cm.cursorCoords(null, "page");
- var tooltip = ts.activeArgHints = makeTooltip(place.right + 1, place.bottom, tip)
+ var tooltip = ts.activeArgHints = makeTooltip(place.right + 1, place.bottom, tip, cm)
setTimeout(function() {
tooltip.clear = onEditorActivity(cm, function() {
if (ts.activeArgHints == tooltip) closeArgHints(ts) })
@@ -601,7 +600,7 @@
function tempTooltip(cm, content, ts) {
if (cm.state.ternTooltip) remove(cm.state.ternTooltip);
var where = cm.cursorCoords();
- var tip = cm.state.ternTooltip = makeTooltip(where.right + 1, where.bottom, content);
+ var tip = cm.state.ternTooltip = makeTooltip(where.right + 1, where.bottom, content, cm);
function maybeClear() {
old = true;
if (!mouseOnTip) clear();
@@ -637,11 +636,44 @@
}
}
- function makeTooltip(x, y, content) {
- var node = elt("div", cls + "tooltip", content);
+ function makeTooltip(x, y, content, cm, className) {
+ var node = elt("div", cls + "tooltip" + " " + (className || ""), content);
node.style.left = x + "px";
node.style.top = y + "px";
- document.body.appendChild(node);
+ var container = ((cm.options || {}).hintOptions || {}).container || document.body;
+ container.appendChild(node);
+
+ var pos = cm.cursorCoords();
+ var winW = window.innerWidth;
+ var winH = window.innerHeight;
+ var box = node.getBoundingClientRect();
+ var hints = document.querySelector(".CodeMirror-hints");
+ var overlapY = box.bottom - winH;
+ var overlapX = box.right - winW;
+
+ if (hints && overlapX > 0) {
+ node.style.left = 0;
+ var box = node.getBoundingClientRect();
+ node.style.left = (x = x - hints.offsetWidth - box.width) + "px";
+ overlapX = box.right - winW;
+ }
+ if (overlapY > 0) {
+ var height = box.bottom - box.top, curTop = pos.top - (pos.bottom - box.top);
+ if (curTop - height > 0) { // Fits above cursor
+ node.style.top = (pos.top - height) + "px";
+ } else if (height > winH) {
+ node.style.height = (winH - 5) + "px";
+ node.style.top = (pos.bottom - box.top) + "px";
+ }
+ }
+ if (overlapX > 0) {
+ if (box.right - box.left > winW) {
+ node.style.width = (winW - 5) + "px";
+ overlapX -= (box.right - box.left) - winW;
+ }
+ node.style.left = (x - overlapX) + "px";
+ }
+
return node;
}
diff --git a/help3/xhpeditor/cm/addon/wrap/hardwrap.js b/help3/xhpeditor/cm/addon/wrap/hardwrap.js
index 29cc15f0..516368c8 100644
--- a/help3/xhpeditor/cm/addon/wrap/hardwrap.js
+++ b/help3/xhpeditor/cm/addon/wrap/hardwrap.js
@@ -29,11 +29,20 @@
return {from: start, to: end};
}
- function findBreakPoint(text, column, wrapOn, killTrailingSpace) {
+ function findBreakPoint(text, column, wrapOn, killTrailingSpace, forceBreak) {
var at = column
while (at < text.length && text.charAt(at) == " ") at++
for (; at > 0; --at)
if (wrapOn.test(text.slice(at - 1, at + 1))) break;
+
+ if (!forceBreak && at <= text.match(/^[ \t]*/)[0].length) {
+ // didn't find a break point before column, in non-forceBreak mode try to
+ // find one after 'column'.
+ for (at = column + 1; at < text.length - 1; ++at) {
+ if (wrapOn.test(text.slice(at - 1, at + 1))) break;
+ }
+ }
+
for (var first = true;; first = false) {
var endOfText = at;
if (killTrailingSpace)
@@ -47,6 +56,7 @@
from = cm.clipPos(from); to = cm.clipPos(to);
var column = options.column || 80;
var wrapOn = options.wrapOn || /\s\S|-[^\.\d]/;
+ var forceBreak = options.forceBreak !== false;
var killTrailing = options.killTrailingSpace !== false;
var changes = [], curLine = "", curNo = from.line;
var lines = cm.getRange(from, to, false);
@@ -68,7 +78,7 @@
curLine += text;
if (i) {
var firstBreak = curLine.length > column && leadingSpace == spaceTrimmed &&
- findBreakPoint(curLine, column, wrapOn, killTrailing);
+ findBreakPoint(curLine, column, wrapOn, killTrailing, forceBreak);
// If this isn't broken, or is broken at a different point, remove old break
if (!firstBreak || firstBreak.from != oldLen || firstBreak.to != oldLen + spaceInserted) {
changes.push({text: [spaceInserted ? " " : ""],
@@ -80,12 +90,17 @@
}
}
while (curLine.length > column) {
- var bp = findBreakPoint(curLine, column, wrapOn, killTrailing);
- changes.push({text: ["", leadingSpace],
- from: Pos(curNo, bp.from),
- to: Pos(curNo, bp.to)});
- curLine = leadingSpace + curLine.slice(bp.to);
- ++curNo;
+ var bp = findBreakPoint(curLine, column, wrapOn, killTrailing, forceBreak);
+ if (bp.from != bp.to ||
+ forceBreak && leadingSpace !== curLine.slice(0, bp.to)) {
+ changes.push({text: ["", leadingSpace],
+ from: Pos(curNo, bp.from),
+ to: Pos(curNo, bp.to)});
+ curLine = leadingSpace + curLine.slice(bp.to);
+ ++curNo;
+ } else {
+ break;
+ }
}
}
if (changes.length) cm.operation(function() {
diff --git a/help3/xhpeditor/cm/demo/anywordhint.html b/help3/xhpeditor/cm/demo/anywordhint.html
index 471b5bde..57df9a36 100644
--- a/help3/xhpeditor/cm/demo/anywordhint.html
+++ b/help3/xhpeditor/cm/demo/anywordhint.html
@@ -8,7 +8,7 @@
<link rel="stylesheet" href="../addon/hint/show-hint.css">
<script src="../lib/codemirror.js"></script>
<script src="../addon/hint/show-hint.js"></script>
-<script src="../addon/hint/anyword-hint.js"></script>
+<script src="../addon/hint/anyword-hint.js" id=anyword></script>
<script src="../mode/javascript/javascript.js"></script>
<div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
@@ -29,33 +29,31 @@
(function() {
"use strict";
- var WORD = /[\w$]+/g, RANGE = 500;
+ var WORD = /[\w$]+/, RANGE = 500;
CodeMirror.registerHelper("hint", "anyword", function(editor, options) {
var word = options && options.word || WORD;
var range = options && options.range || RANGE;
var cur = editor.getCursor(), curLine = editor.getLine(cur.line);
- var start = cur.ch, end = start;
- while (end < curLine.length && word.test(curLine.charAt(end))) ++end;
+ var end = cur.ch, start = end;
while (start && word.test(curLine.charAt(start - 1))) --start;
var curWord = start != end && curLine.slice(start, end);
- var list = [], seen = {};
- function scan(dir) {
- var line = cur.line, end = Math.min(Math.max(line + dir * range, editor.firstLine()), editor.lastLine()) + dir;
- for (; line != end; line += dir) {
+ var list = options && options.list || [], seen = {};
+ var re = new RegExp(word.source, "g");
+ for (var dir = -1; dir <= 1; dir += 2) {
+ var line = cur.line, endLine = Math.min(Math.max(line + dir * range, editor.firstLine()), editor.lastLine()) + dir;
+ for (; line != endLine; line += dir) {
var text = editor.getLine(line), m;
- word.lastIndex = 0;
- while (m = word.exec(text)) {
- if ((!curWord || m[0].indexOf(curWord) == 0) && !seen.hasOwnProperty(m[0])) {
+ while (m = re.exec(text)) {
+ if (line == cur.line && m[0] === curWord) continue;
+ if ((!curWord || m[0].lastIndexOf(curWord, 0) == 0) && !Object.prototype.hasOwnProperty.call(seen, m[0])) {
seen[m[0]] = true;
list.push(m[0]);
}
}
}
}
- scan(-1);
- scan(1);
return {list: list, from: CodeMirror.Pos(cur.line, start), to: CodeMirror.Pos(cur.line, end)};
});
})();
diff --git a/help3/xhpeditor/cm/demo/closetag.html b/help3/xhpeditor/cm/demo/closetag.html
index 4f857fa4..1f86114a 100644
--- a/help3/xhpeditor/cm/demo/closetag.html
+++ b/help3/xhpeditor/cm/demo/closetag.html
@@ -38,4 +38,5 @@
autoCloseTags: true
});
</script>
+ <p>Uses the <a href="https://codemirror.net/doc/manual.html#addon_closetag">closetag</a> addon to auto-close tags.</p>
</article>
diff --git a/help3/xhpeditor/cm/demo/complete.html b/help3/xhpeditor/cm/demo/complete.html
index 2fef7964..3e7bd5ff 100644
--- a/help3/xhpeditor/cm/demo/complete.html
+++ b/help3/xhpeditor/cm/demo/complete.html
@@ -71,7 +71,7 @@ and <a href="../doc/manual.html#addon_javascript-hint"><code>javascript-hint</co
addons.</p>
<form><textarea style="display: none" id="synonyms" name="synonyms">
-Here, the completion use an asynchronous hinting functions to provide
+Here, the completion use an asynchronous hinting function to provide
synonyms for each words. If your browser support `Promises`, the
hinting function can also return one.
</textarea></form>
@@ -88,7 +88,7 @@ if (typeof Promise !== "undefined") {
["here", "hither"],
["asynchronous", "nonsynchronous"],
["completion", "achievement", "conclusion", "culmination", "expirations"],
- ["hinting", "advive", "broach", "imply"],
+ ["hinting", "advise", "broach", "imply"],
["function","action"],
["provide", "add", "bring", "give"],
["synonyms", "equivalents"],
diff --git a/help3/xhpeditor/cm/demo/matchhighlighter.html b/help3/xhpeditor/cm/demo/matchhighlighter.html
index 6aa93778..8e0ff25b 100644
--- a/help3/xhpeditor/cm/demo/matchhighlighter.html
+++ b/help3/xhpeditor/cm/demo/matchhighlighter.html
@@ -98,6 +98,6 @@ var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
});
</script>
- <p>Search and highlight occurences of the selected text.</p>
+ <p>Search and highlight occurrences of the selected text.</p>
</article>
diff --git a/help3/xhpeditor/cm/demo/mustache.html b/help3/xhpeditor/cm/demo/mustache.html
index 2d193f09..f37f01b5 100644
--- a/help3/xhpeditor/cm/demo/mustache.html
+++ b/help3/xhpeditor/cm/demo/mustache.html
@@ -61,7 +61,7 @@ var editor = CodeMirror.fromTextArea(document.getElementById("code"), {mode: "mu
</script>
<p>Demonstration of a mode that parses HTML, highlighting
- the <a href="http://mustache.github.com/">Mustache</a> templating
+ the <a href="http://mustache.github.io/">Mustache</a> templating
directives inside of it by using the code
in <a href="../addon/mode/overlay.js"><code>overlay.js</code></a>. View
source to see the 15 lines of code needed to accomplish this.</p>
diff --git a/help3/xhpeditor/cm/demo/runmode-standalone.html b/help3/xhpeditor/cm/demo/runmode-standalone.html
new file mode 100644
index 00000000..f3503b98
--- /dev/null
+++ b/help3/xhpeditor/cm/demo/runmode-standalone.html
@@ -0,0 +1,61 @@
+<!doctype html>
+
+<title>CodeMirror: Mode Runner Demo</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../doc/docs.css">
+
+<link rel="stylesheet" href="../lib/codemirror.css">
+<script src="../addon/runmode/runmode-standalone.js"></script>
+<script src="../mode/xml/xml.js"></script>
+<div id=nav>
+ <a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
+
+ <ul>
+ <li><a href="../index.html">Home</a>
+ <li><a href="../doc/manual.html">Manual</a>
+ <li><a href="https://github.com/codemirror/codemirror">Code</a>
+ </ul>
+ <ul>
+ <li><a class=active href="#">Mode Runner</a>
+ </ul>
+</div>
+
+<article>
+<h2>Mode Runner Demo</h2>
+
+
+ <textarea id="code" style="width: 90%; height: 7em; border: 1px solid black; padding: .2em .4em;">
+<foobar>
+ <blah>Enter your xml here and press the button below to display
+ it as highlighted by the CodeMirror XML mode</blah>
+ <tag2 foo="2" bar="&amp;quot;bar&amp;quot;"/>
+</foobar></textarea><br>
+ <button onclick="doHighlight();">Highlight!</button>
+ <pre id="output" class="cm-s-default"></pre>
+
+ <script>
+function doHighlight() {
+ CodeMirror.runMode(document.getElementById("code").value, "application/xml",
+ document.getElementById("output"));
+}
+</script>
+
+ <p>Running a CodeMirror mode outside of the editor.
+ The <code>CodeMirror.runMode</code> function, defined
+ in <code><a href="../addon/runmode/runmode.js">addon/runmode/runmode.js</a></code> takes the following arguments:</p>
+
+ <dl>
+ <dt><code>text (string)</code></dt>
+ <dd>The document to run through the highlighter.</dd>
+ <dt><code>mode (<a href="../doc/manual.html#option_mode">mode spec</a>)</code></dt>
+ <dd>The mode to use (must be loaded as normal).</dd>
+ <dt><code>output (function or DOM node)</code></dt>
+ <dd>If this is a function, it will be called for each token with
+ two arguments, the token's text and the token's style class (may
+ be <code>null</code> for unstyled tokens). If it is a DOM node,
+ the tokens will be converted to <code>span</code> elements as in
+ an editor, and inserted into the node
+ (through <code>innerHTML</code>).</dd>
+ </dl>
+
+ </article>
diff --git a/help3/xhpeditor/cm/demo/simplemode.html b/help3/xhpeditor/cm/demo/simplemode.html
index 6b44a788..b03335fb 100644
--- a/help3/xhpeditor/cm/demo/simplemode.html
+++ b/help3/xhpeditor/cm/demo/simplemode.html
@@ -67,7 +67,8 @@ highlighted by the mode shown in it).</p>
will be taken into account when matching the token. This regex
has to capture groups when the <code>token</code> property is
an array. If it captures groups, it must capture <em>all</em> of the string
- (since JS provides no way to find out where a group matched).</dd>
+ (since JS provides no way to find out where a group matched).
+ Currently negative lookbehind assertion for regex is not supported, regardless of browser support.</dd>
<dt><code><strong>token</strong></code>: string | array&lt;string&gt; | null</dt>
<dd>An optional token style. Multiple styles can be specified by
separating them with dots or spaces. When this property holds an array of token styles,
@@ -128,7 +129,7 @@ recognizes a few such properties:</p>
*/
CodeMirror.defineSimpleMode("simplemode", {
- // The start state contains the rules that are intially used
+ // The start state contains the rules that are initially used
start: [
// The regex matches the token, the token property contains the type
{regex: /"(?:[^\\]|\\.)*?(?:"|$)/, token: "string"},
diff --git a/help3/xhpeditor/cm/demo/tern.html b/help3/xhpeditor/cm/demo/tern.html
index c6834e88..e331fd5c 100644
--- a/help3/xhpeditor/cm/demo/tern.html
+++ b/help3/xhpeditor/cm/demo/tern.html
@@ -13,16 +13,16 @@
<script src="../addon/dialog/dialog.js"></script>
<script src="../addon/hint/show-hint.js"></script>
<script src="../addon/tern/tern.js"></script>
-<script src="//ternjs.net/node_modules/acorn/dist/acorn.js"></script>
-<script src="//ternjs.net/node_modules/acorn-loose/dist/acorn-loose.js"></script>
-<script src="//ternjs.net/node_modules/acorn-walk/dist/walk.js"></script>
+<script src="https://unpkg.com/acorn/dist/acorn.js"></script>
+<script src="https://unpkg.com/acorn-loose/dist/acorn-loose.js"></script>
+<script src="https://unpkg.com/acorn-walk/dist/walk.js"></script>
<script src="//ternjs.net/doc/demo/polyfill.js"></script>
-<script src="//ternjs.net/lib/signal.js"></script>
-<script src="//ternjs.net/lib/tern.js"></script>
-<script src="//ternjs.net/lib/def.js"></script>
-<script src="//ternjs.net/lib/comment.js"></script>
-<script src="//ternjs.net/lib/infer.js"></script>
-<script src="//ternjs.net/plugin/doc_comment.js"></script>
+<script src="https://unpkg.com/tern/lib/signal.js"></script>
+<script src="https://unpkg.com/tern/lib/tern.js"></script>
+<script src="https://unpkg.com/tern/lib/def.js"></script>
+<script src="https://unpkg.com/tern/lib/comment.js"></script>
+<script src="https://unpkg.com/tern/lib/infer.js"></script>
+<script src="https://unpkg.com/tern/plugin/doc_comment.js"></script>
<style>
.CodeMirror {border: 1px solid #ddd;}
</style>
@@ -109,7 +109,7 @@ overview.</p>
}
var server;
- getURL("//ternjs.net/defs/ecmascript.json", function(err, code) {
+ getURL("https://unpkg.com/tern/defs/ecmascript.json", function(err, code) {
if (err) throw new Error("Request for ecmascript.json: " + err);
server = new CodeMirror.TernServer({defs: [JSON.parse(code)]});
editor.setOption("extraKeys", {
diff --git a/help3/xhpeditor/cm/demo/theme.html b/help3/xhpeditor/cm/demo/theme.html
index 95d0f391..a4ca59cf 100644
--- a/help3/xhpeditor/cm/demo/theme.html
+++ b/help3/xhpeditor/cm/demo/theme.html
@@ -7,6 +7,7 @@
<link rel="stylesheet" href="../lib/codemirror.css">
<link rel="stylesheet" href="../theme/3024-day.css">
<link rel="stylesheet" href="../theme/3024-night.css">
+<link rel="stylesheet" href="../theme/abbott.css">
<link rel="stylesheet" href="../theme/abcdef.css">
<link rel="stylesheet" href="../theme/ambiance.css">
<link rel="stylesheet" href="../theme/ayu-dark.css">
@@ -106,6 +107,7 @@ function findSequence(goal) {
<option selected>default</option>
<option>3024-day</option>
<option>3024-night</option>
+ <option>abbott</option>
<option>abcdef</option>
<option>ambiance</option>
<option>ayu-dark</option>
diff --git a/help3/xhpeditor/cm/demo/vim.html b/help3/xhpeditor/cm/demo/vim.html
index c939505d..172ab6f0 100644
--- a/help3/xhpeditor/cm/demo/vim.html
+++ b/help3/xhpeditor/cm/demo/vim.html
@@ -56,6 +56,7 @@ int getchar(void)
}
</textarea></form>
<div style="font-size: 13px; width: 300px; height: 30px;">Key buffer: <span id="command-display"></span></div>
+<div style="font-size: 13px; width: 300px; height: 30px;">Vim mode: <span id="vim-mode"></span></div>
<p>The vim keybindings are enabled by including <code><a
href="../keymap/vim.js">keymap/vim.js</a></code> and setting the
@@ -95,19 +96,22 @@ become a complete vim implementation</p>
mode: "text/x-csrc",
keyMap: "vim",
matchBrackets: true,
- showCursorWhenSelecting: true,
- inputStyle: "contenteditable"
+ showCursorWhenSelecting: true
});
var commandDisplay = document.getElementById('command-display');
var keys = '';
CodeMirror.on(editor, 'vim-keypress', function(key) {
keys = keys + key;
- commandDisplay.innerHTML = keys;
+ commandDisplay.innerText = keys;
});
CodeMirror.on(editor, 'vim-command-done', function(e) {
keys = '';
commandDisplay.innerHTML = keys;
});
+ var vimMode = document.getElementById('vim-mode');
+ CodeMirror.on(editor, 'vim-mode-change', function(e) {
+ vimMode.innerText = JSON.stringify(e);
+ });
</script>
</article>
diff --git a/help3/xhpeditor/cm/doc/internals.html b/help3/xhpeditor/cm/doc/internals.html
index 2137c937..893604e9 100644
--- a/help3/xhpeditor/cm/doc/internals.html
+++ b/help3/xhpeditor/cm/doc/internals.html
@@ -293,7 +293,7 @@ single <code>innerHTML</code> update to do the refresh.</p>
<h2>Parsers can be Simple</h2>
<p>When I wrote CodeMirror 1, I
-thought <a href="https://codemirror.net/story.html#parser">interruptable
+thought <a href="https://codemirror.net/story.html#parser">interruptible
parsers</a> were a hugely scary and complicated thing, and I used a
bunch of heavyweight abstractions to keep this supposed complexity
under control: parsers
diff --git a/help3/xhpeditor/cm/doc/manual.html b/help3/xhpeditor/cm/doc/manual.html
index e943ce63..4aa44202 100644
--- a/help3/xhpeditor/cm/doc/manual.html
+++ b/help3/xhpeditor/cm/doc/manual.html
@@ -58,6 +58,7 @@
<li><a href="#vimapi">Vim Mode API</a>
<ul>
<li><a href="#vimapi_configuration">Configuration</a></li>
+ <li><a href="#vimapi_events">Events</a></li>
<li><a href="#vimapi_extending">Extending VIM</a></li>
</ul>
</li>
@@ -69,7 +70,7 @@
<section class=first id=overview>
<h2 style="position: relative">
User manual and reference guide
- <span style="color: #888; font-size: 1rem; position: absolute; right: 0; bottom: 0">version 5.51.0</span>
+ <span style="color: #888; font-size: 1rem; position: absolute; right: 0; bottom: 0">version 5.61.1</span>
</h2>
<p>CodeMirror is a code-editor component that can be embedded in
@@ -78,9 +79,9 @@
functionality. It does provide a rich API on top of which such
functionality can be straightforwardly implemented. See
the <a href="#addons">addons</a> included in the distribution,
- and the <a href="https://github.com/codemirror/CodeMirror/wiki/CodeMirror-addons">list
- of externally hosted addons</a>, for reusable
- implementations of extra features.</p>
+ and <a href="https://npms.io/search?q=codemirror">3rd party
+ packages on npm</a>, for reusable implementations of extra
+ features.</p>
<p>CodeMirror works with language-specific modes. Modes are
JavaScript programs that help color (and optionally indent) text
@@ -421,6 +422,10 @@
simply <code>true</code>), focusing of the editor is also
disallowed.</dd>
+ <dt id="option_screenReaderLabel"><code><strong>screenReaderLabel</strong>: string</code></dt>
+ <dd>This label is read by the screenreaders when CodeMirror text area is focused. This
+ is helpful for accessibility.</dd>
+
<dt id="option_showCursorWhenSelecting"><code><strong>showCursorWhenSelecting</strong>: boolean</code></dt>
<dd>Whether the cursor should be drawn when a selection is
active. Defaults to false.</dd>
@@ -507,6 +512,12 @@
which causes the cursor to not reach all the way to the bottom
of the line, looks better</dd>
+ <dt id="option_singleCursorHeightPerLine"><code><strong>singleCursorHeightPerLine</strong>: boolean</code></dt>
+ <dd>If set to <code>true</code> (the default), will keep the
+ cursor height constant for an entire line (or wrapped part of a
+ line). When <code>false</code>, the cursor's height is based on
+ the height of the adjacent reference character.</dd>
+
<dt id="option_resetSelectionOnContextMenu"><code><strong>resetSelectionOnContextMenu</strong>: boolean</code></dt>
<dd>Controls whether, when the context menu is opened with a
click outside of the current selection, the cursor is moved to
@@ -558,13 +569,13 @@
always rendered, and thus the browser's text search works on it.
This <em>will</em> have bad effects on performance of big
documents.</dd>
-
+
<dt id="option_spellcheck"><code><strong>spellcheck</strong>: boolean</code></dt>
<dd>Specifies whether or not spellcheck will be enabled on the input.</dd>
-
+
<dt id="option_autocorrect"><code><strong>autocorrect</strong>: boolean</code></dt>
<dd>Specifies whether or not autocorrect will be enabled on the input.</dd>
-
+
<dt id="option_autocapitalize"><code><strong>autocapitalize</strong>: boolean</code></dt>
<dd>Specifies whether or not autocapitalization will be enabled on the input.</dd>
</dl>
@@ -1421,14 +1432,15 @@ editor.setOption("extraKeys", {
stuck.</dd>
</dl></dd>
- <dt id="setSelections"><code><strong>doc.setSelections</strong>(ranges: array&lt;{anchor, head}&gt;, ?primary: integer, ?options: object)</code></dt>
+ <dt id="setSelections"><code><strong>doc.setSelections</strong>(ranges: array&lt;{anchor, ?head}&gt;, ?primary: integer, ?options: object)</code></dt>
<dd>Sets a new set of selections. There must be at least one
selection in the given array. When <code>primary</code> is a
number, it determines which selection is the primary one. When
it is not given, the primary index is taken from the previous
selection, or set to the last range if the previous selection
had less ranges than the new one. Supports the same options
- as <a href="#setSelection"><code>setSelection</code></a>.</dd>
+ as <a href="#setSelection"><code>setSelection</code></a>.
+ <code>head</code> defaults to <code>anchor</code> when not given.</dd>
<dt id="addSelection"><code><strong>doc.addSelection</strong>(anchor: {line, ch}, ?head: {line, ch})</code></dt>
<dd>Adds a new selection to the existing set of selections, and
makes it the primary selection.</dd>
@@ -2394,7 +2406,7 @@ editor.setOption("extraKeys", {
Accepts <code>linenumber</code>, <code>+/-linenumber</code>, <code>line:char</code>,
<code>scroll%</code> and <code>:linenumber</code> formats.
This will make use of <a href="#addon_dialog"><code>openDialog</code></a>
- when available to make prompting for line number neater.</dd>
+ when available to make prompting for line number neater.</dd> Demo available <a href="https://codemirror.net/demo/search.html">here</a>.
<dt id="addon_matchesonscrollbar"><a href="../addon/search/matchesonscrollbar.js"><code>search/matchesonscrollbar.js</code></a></dt>
<dd>Adds a <code>showMatchesOnScrollbar</code> method to editor
@@ -2432,6 +2444,8 @@ editor.setOption("extraKeys", {
<dl>
<dt><strong><code>afterCursor</code></strong></dt>
<dd>Only use the character after the start position, never the one before it.</dd>
+ <dt><strong><code>highlightNonMatching</code></strong></dt>
+ <dd>Also highlight pairs of non-matching as well as stray brackets. Enabled by default.</dd>
<dt><strong><code>strict</code></strong></dt>
<dd>Causes only matches where both brackets are at the same side of the start position to be considered.</dd>
<dt><strong><code>maxScanLines</code></strong></dt>
@@ -2571,7 +2585,7 @@ editor.setOption("extraKeys", {
<dd>The widget to show for folded ranges. Can be either a
string, in which case it'll become a span with
class <code>CodeMirror-foldmarker</code>, or a DOM node.
- To dynamically generate the widget, this can be a function
+ To dynamically generate the widget, this can be a function
that returns a string or DOM node, which will then render
as described. The function will be invoked with parameters
identifying the range to be folded.</dd>
@@ -2695,8 +2709,8 @@ editor.setOption("extraKeys", {
Defines <code>editor.showHint</code>, which takes an optional
options object, and pops up a widget that allows the user to
select a completion. Finding hints is done with a hinting
- functions (the <code>hint</code> option), which is a function
- that take an editor instance and options object, and return
+ function (the <code>hint</code> option). This function
+ takes an editor instance and an options object, and returns
a <code>{list, from, to}</code> object, where <code>list</code>
is an array of strings or objects (the completions),
and <code>from</code> and <code>to</code> give the start and end
@@ -2710,7 +2724,7 @@ editor.setOption("extraKeys", {
the <code>"hint"</code> type to find applicable hinting
functions, and tries them one by one. If that fails, it looks
for a <code>"hintWords"</code> helper to fetch a list of
- completable words for the mode, and
+ completeable words for the mode, and
uses <code>CodeMirror.hint.fromList</code> to complete from
those.</dd>
<dd>When completions aren't simple strings, they should be
@@ -2766,9 +2780,22 @@ editor.setOption("extraKeys", {
<dt><code><strong>alignWithWord</strong>: boolean</code></dt>
<dd>Whether the pop-up should be horizontally aligned with the
start of the word (true, default), or with the cursor (false).</dd>
+ <dt><code><strong>closeCharacters</strong>: RegExp</code></dt>
+ <dd>A regular expression object used to match characters which
+ cause the pop up to be closed (default: <code>/[\s()\[\]{};:>,]/</code>).
+ If the user types one of these characters, the pop up will close, and
+ the <code>endCompletion</code> event is fired on the editor instance.</dd>
<dt><code><strong>closeOnUnfocus</strong>: boolean</code></dt>
<dd>When enabled (which is the default), the pop-up will close
when the editor is unfocused.</dd>
+ <dt><code><strong>completeOnSingleClick</strong>: boolean</code></dt>
+ <dd>Whether a single click on a list item suffices to trigger the
+ completion (which is the default), or if the user has to use a
+ doubleclick.</dd>
+ <dt><code><strong>container</strong>: Element|null</code></dt>
+ <dd>Can be used to define a custom container for the widget. The default
+ is <code>null</code>, in which case the <code>body</code>-element will
+ be used.</dd>
<dt><code><strong>customKeys</strong>: keymap</code></dt>
<dd>Allows you to provide a custom key map of keys to be active
when the pop-up is active. The handlers will be called with an
@@ -2785,6 +2812,9 @@ editor.setOption("extraKeys", {
<dd>Like <code>customKeys</code> above, but the bindings will
be added to the set of default bindings, instead of replacing
them.</dd>
+ <dt><code><strong>scrollMargin</strong>: integer</code></dt>
+ <dd>Show this many lines before and after the selected item.
+ Default is 0.</dd>
</dl>
The following events will be fired on the completions object
during completion:
@@ -2801,6 +2831,14 @@ editor.setOption("extraKeys", {
<dt><code><strong>"close"</strong> ()</code></dt>
<dd>Fired when the completion is finished.</dd>
</dl>
+ The following events will be fired on the editor instance during
+ completion:
+ <dl>
+ <dt><code><strong>"endCompletion"</strong> ()</code></dt>
+ <dd>Fired when the pop-up is being closed programmatically, e.g., when
+ the user types a character which matches the
+ <code>closeCharacters</code> option.</dd>
+ </dl>
This addon depends on styles
from <code>addon/hint/show-hint.css</code>. Check
out <a href="../demo/complete.html">the demo</a> for an
@@ -2911,6 +2949,7 @@ editor.setOption("extraKeys", {
will only be executed when the promise resolves.
By default, the linter will run (debounced) whenever the document is changed.
You can pass a <code>lintOnChange: false</code> option to disable that.
+ You can pass a <code>selfContain: true</code> option to render the tooltip inside the editor instance.
Depends on <code>addon/lint/lint.css</code>. A demo can be
found <a href="../demo/lint.html">here</a>.</dd>
@@ -2945,13 +2984,20 @@ editor.setOption("extraKeys", {
see a demo <a href="../mode/htmlmixed/index.html">here</a>.</dd>
<dt id="addon_loadmode"><a href="../addon/mode/loadmode.js"><code>mode/loadmode.js</code></a></dt>
- <dd>Defines a <code>CodeMirror.requireMode(modename,
- callback)</code> function that will try to load a given mode and
- call the callback when it succeeded. You'll have to
- set <code>CodeMirror.modeURL</code> to a string that mode paths
- can be constructed from, for
- example <code>"mode/%N/%N.js"</code>—the <code>%N</code>'s will
- be replaced with the mode name. Also
+ <dd>Defines a <code>CodeMirror.requireMode(modename, callback,
+ options)</code> function that will try to load a given mode and
+ call the callback when it succeeded. <code>options</code> is an
+ optional object that may contain:
+ <dl>
+ <dt><code><strong>path</strong>: fn(modeName: string) → string</code></dt>
+ <dd>Defines the way mode names are mapped to paths.</dd>
+ <dt><code><strong>loadMode</strong>: fn(path: string, cont: fn())</code></dt>
+ <dd>Override the way the mode script is loaded. By default,
+ this will use the CommonJS or AMD module loader if one is
+ present, and fall back to creating
+ a <code>&lt;script></code> tag otherwise.</dd>
+ </dl>
+ This addon also
defines <code>CodeMirror.autoLoadMode(instance, mode)</code>,
which will ensure the given mode is loaded and cause the given
editor instance to refresh its mode when the loading
@@ -3122,10 +3168,20 @@ editor.setOption("extraKeys", {
<dt><code><strong>killTrailingSpace</strong>: boolean</code></dt>
<dd>Whether trailing space caused by wrapping should be
preserved, or deleted. Defaults to true.</dd>
+ <dt><code><strong>forceBreak</strong>: boolean</code></dt>
+ <dd>If set to true forces a break at <code>column</code> in the case
+ when no <code>wrapOn</code> pattern is found in the range. If set to
+ false allows line to overflow the <code>column</code> limit if no
+ <code>wrapOn</code> pattern found. Defaults to true.</dd>
</dl>
A demo of the addon is available <a href="../demo/hardwrap.html">here</a>.
</dd>
+ <dt id="addon_scrollpastend"><a href="../addon/scroll/scrollpastend.js"><code>scroll/scrollpastend.js</code></a></dt>
+ <dd>Defines an option `"scrollPastEnd"` that, when set to a
+ truthy value, allows the user to scroll one editor height of
+ empty space into view at the bottom of the editor.</dd>
+
<dt id="addon_merge"><a href="../addon/merge/merge.js"><code>merge/merge.js</code></a></dt>
<dd>Implements an interface for merging changes, using either a
2-way or a 3-way view. The <code>CodeMirror.MergeView</code>
@@ -3525,6 +3581,41 @@ editor.setOption("extraKeys", {
<code>extras.isEdit</code> is applicable only to actions,
determining whether it is recorded for replay for the
<code>.</code> single-repeat command.
+
+ <dt id="vimapi_unmap"><strong><code>unmap(lhs: string, ctx: string)</code></strong></dt>
+ <dd>
+ Remove the command <code>lhs</code> if it is a user defined command.
+ If the command is an Ex to Ex or Ex to key mapping then the context
+ must be <code>undefined</code> or <code>false</code>.
+ </dd>
+
+ <dt id="vimapi_mapclear"><strong><code>mapclear(ctx: string)</code></strong></dt>
+ <dd>
+ Remove all user-defined mappings for the provided context.
+ </dd>
+
+ <dt id="vimapi_noremap"><strong><code>noremap(lhs: string, rhs: string, ctx: {string, array&lt;string&gt;})</code></strong></dt>
+ <dd>
+ Non-recursive map function. This will not create mappings to key maps
+ that aren't present in the default key map.
+ If no context is provided then the mapping will be applied to each of
+ normal, insert, and visual mode.
+ </dd>
+ </dl>
+
+ <h3 id="vimapi_events">Events</h3>
+
+ <p>VIM mode signals a few events on the editor instance. For an example usage, see <a href="https://github.com/codemirror/CodeMirror/blob/5.55.0/demo/vim.html#L101-L110">demo/vim.html#L101</a>.</p>
+
+ <dl>
+ <dt id="vimapi_commanddone"><code><strong>"vim-command-done"</strong> (reason: undefined)</code></dt>
+ <dd>Fired on keypress and mousedown where command has completed or no command found.</dd>
+
+ <dt id="vimapi_keypress"><code><strong>"vim-keypress"</strong> (vimKey: string)</code></dt>
+ <dd>Fired on keypress, <code>vimKey</code> is in Vim's key notation.</dd>
+
+ <dt id="vimapi_modechange"><code><strong>"vim-mode-change"</strong> (modeObj: object)</code></dt>
+ <dd>Fired after mode change, <code>modeObj</code> parameter is a <code>{mode: string, ?subMode: string}</code> object. Modes: <code>"insert", "normal", "replace", "visual"</code>. Visual sub-modes: <code>"linewise", "blockwise"</code>.</dd>
</dl>
<h3 id="vimapi_extending">Extending VIM</h3>
@@ -3590,7 +3681,74 @@ editor.setOption("extraKeys", {
command was prefixed with a
<code><strong><a href="http://vimdoc.sourceforge.net/htmldoc/cmdline.html#cmdline-ranges">line range</a></strong></code>,
<code>params.line</code> and <code>params.lineEnd</code> will
- be set.
+ be set.</dd>
+
+ <dt id="vimapi_getRegisterController"><strong><code>getRegisterController()</code></strong></dt>
+ <dd>Returns the RegisterController that manages the state of registers
+ used by vim mode. For the RegisterController api see its
+ definition <a href="https://github.com/CodeMirror/CodeMirror/blob/b2d26b4ccb1d0994ae84d18ad8b84018de176da9/keymap/vim.js#L1123">here</a>.
+ </dd>
+
+ <dt id='vimapi_buildkeymap'><strong><code>buildKeyMap()</code></strong></dt>
+ <dd>
+ Not currently implemented. If you would like to contribute this please open
+ a pull request on <a href="https://github.com/codemirror/CodeMirror">GitHub</a>.
+ </dd>
+
+ <dt id="vimapi_defineRegister"><strong><code>defineRegister()</code></strong></dt>
+ <dd> Defines an external register. The name should be a single character
+ that will be used to reference the register. The register should support
+ <code>setText</code>, <code>pushText</code>, <code>clear</code>, and <code>toString</code>.
+ See <a href="https://github.com/CodeMirror/CodeMirror/blob/b2d26b4ccb1d0994ae84d18ad8b84018de176da9/keymap/vim.js#L1055">Register</a> for a reference implementation.
+ </dd>
+
+ <dt id="vimapi_getVimGlobalState_"><strong><code>getVimGlobalState_()</code></strong></dt>
+ <dd>
+ Return a reference to the VimGlobalState.
+ </dd>
+
+ <dt id="vimapi_resetVimGlobalState_"><strong><code>resetVimGlobalState_()</code></strong></dt>
+ <dd>
+ Reset the default values of the VimGlobalState to fresh values. Any options
+ set with <code>setOption</code> will also be applied to the reset global state.
+ </dd>
+
+ <dt id="vimapi_maybeInitVimState_"><strong><code>maybeInitVimState_(cm: CodeMirror)</code></strong></dt>
+ <dd>
+ Initialize <code>cm.state.vim</code> if it does not exist. Returns <code>cm.state.vim</code>.
+ </dd>
+
+ <dt id="vimapi_handleKey"><strong><code>handleKey(cm: CodeMirror, key: string, origin: string)</code></strong></dt>
+ <dd>
+ Convenience function to pass the arguments to <code>findKey</code> and
+ call returned function if it is defined.
+ </dd>
+
+ <dt id="vimapi_findKey"><strong><code>findKey(cm: CodeMirror, key: string, origin: string)</code></strong></dt>
+ <dd>
+ This is the outermost function called by CodeMirror, after keys have
+ been mapped to their Vim equivalents. Finds a command based on the key
+ (and cached keys if there is a multi-key sequence). Returns <code>undefined</code>
+ if no key is matched, a noop function if a partial match is found (multi-key),
+ and a function to execute the bound command if a a key is matched. The
+ function always returns true.
+ </dd>
+
+ <dt id="vimapi_option_suppressErrorLogging"><code><strong>suppressErrorLogging</strong>: boolean</code></dt>
+ <dd>Whether to use suppress the use of <code>console.log</code> when catching an
+ error in the function returned by <code>findKey</code>.
+ Defaults to false.</dd>
+
+ <dt id="vimapi_exitVisualMode"><strong><code>exitVisualMode(cm: CodeMirror, ?moveHead: boolean)</code></strong></dt>
+ <dd> Exit visual mode. If moveHead is set to false, the CodeMirror selection
+ will not be touched. The caller assumes the responsibility of putting
+ the cursor in the right place.
+ </dd>
+
+ <dt id="vimapi_exitInsertMode"><strong><code>exitInsertMode(cm: CodeMirror)</code></strong></dt>
+ <dd>
+ Exit insert mode.
+ </dd>
</dl>
</section>
diff --git a/help3/xhpeditor/cm/doc/realworld.html b/help3/xhpeditor/cm/doc/realworld.html
index 03b02c92..5120167b 100644
--- a/help3/xhpeditor/cm/doc/realworld.html
+++ b/help3/xhpeditor/cm/doc/realworld.html
@@ -25,6 +25,7 @@
request</a> if you'd like your project to be added to this list.</p>
<ul>
+ <li><a href="https://www.adaface.com/pair-pro">Adaface PairPro</a> (Shared code editor with compiler and video conferencing)</li>
<li><a href="http://brackets.io">Adobe Brackets</a> (code editor)</li>
<li><a href="http://adnuntius.com">Adnuntius</a> (used for in-browser code editing and version history)</li>
<li><a href="http://alm.tools">ALM Tools</a> (TypeScript powered IDE)</li>
@@ -40,6 +41,7 @@
<li><a href="http://cargocollective.com/">Cargo Collective</a> (creative publishing platform)</li>
<li><a href="https://developers.google.com/chrome-developer-tools/">Chrome DevTools</a></li>
<li><a href="http://clickhelp.co/">ClickHelp</a> (technical writing tool)</li>
+ <li><a href="https://encap.github.io/clone-it/">Clone-It</a> (HTML & CSS learning game)</li>
<li><a href="https://electronjs.org/apps/colon">Colon</a> (A flexible text editor or IDE)</li>
<li><a href="http://code.world/">CodeWorld</a> (Haskell playground)</li>
<li><a href="http://complete-ly.appspot.com/playground/code.playground.html">Complete.ly playground</a></li>
@@ -50,11 +52,13 @@
<li><a href="http://codefights.com/">CodeFights</a> (practice programming)</li>
<li><a href="https://github.com/angelozerr/CodeMirror-Eclipse">CodeMirror Eclipse</a> (embed CM in Eclipse)</li>
<li><a href="http://emmet.io/blog/codemirror-movie/">CodeMirror movie</a> (scripted editing demos)</li>
- <li><a href="https://code.google.com/p/codemirror2-gwt/">CodeMirror2-GWT</a> (Google Web Toolkit wrapper)</li>
+ <li><a href="https://github.com/haoranyu/codemirror-record/">CodeMirror Record</a> (codemirror activity recording and playback)</li>
+ <li><a href="http://code.google.com/p/codemirror2-gwt/">CodeMirror2-GWT</a> (Google Web Toolkit wrapper)</li>
<li><a href="http://www.crunchzilla.com/code-monster">Code Monster</a> & <a href="http://www.crunchzilla.com/code-maven">Code Maven</a> (learning environment)</li>
<li><a href="http://codepen.io">Codepen</a> (gallery of animations)</li>
<li><a href="https://github.com/pepstock-org/Coderba">Coderba</a> Google Web Toolkit (GWT) wrapper</li>
<li><a href="https://coderpad.io/">Coderpad</a> (interviewing tool)</li>
+ <li><a href="https:/coderush.xyz/">CodeRush</a> typing speed test for programmers</li>
<li><a href="http://sasstwo.codeschool.com/levels/1/challenges/1">Code School</a> (online tech learning environment)</li>
<li><a href="http://code-snippets.bungeshea.com/">Code Snippets</a> (WordPress snippet management plugin)</li>
<li><a href="http://antonmi.github.io/code_together/">Code together</a> (collaborative editing)</li>
@@ -77,7 +81,7 @@
<li><a href="http://eloquentjavascript.net/chapter1.html">Eloquent JavaScript</a> (book)</li>
<li><a href="http://emmet.io">Emmet</a> (fast XML editing)</li>
<li><a href="https://github.com/espruino/EspruinoWebIDE">Espruino Web IDE</a> (Chrome App for writing code on Espruino devices)</li>
- <li><a href="https://exlskills.com/learn-en/talent/interviews">EXLskills Live Interivews</a></li>
+ <li><a href="https://exlskills.com/learn-en/talent/interviews">EXLskills Live Interviews</a></li>
<li><a href="http://www.fastfig.com/">Fastfig</a> (online computation/math tool)</li>
<li><a href="https://metacpan.org/module/Farabi">Farabi</a> (modern Perl IDE)</li>
<li><a href="http://blog.pamelafox.org/2012/02/interactive-html5-slides-with-fathomjs.html">FathomJS integration</a> (slides with editors, again)</li>
@@ -88,11 +92,12 @@
<li><a href="https://gerritcodereview.com/">Gerrit</a>'s diff view and inline editor</li>
<li><a href="https://github.com/maks/git-crx">Git Crx</a> (Chrome App for browsing local git repos)</li>
<li><a href="https://github.com/github/android">GitHub's Android app</a></li>
- <li><a href="https://github.com/">Github</a>'s in-browser edit feature</li>
+ <li><a href="https://github.com/">GitHub</a>'s in-browser edit feature</li>
<li><a href="https://glitch.com/">Glitch</a> (community-driven app building)</li>
<li><a href="http://tour.golang.org">Go language tour</a></li>
<li><a href="https://script.google.com/">Google Apps Script</a></li>
<li><a href="http://web.uvic.ca/~siefkenj/graphit/graphit.html">Graphit</a> (function graphing)</li>
+ <li><a href="https://graviton.netlify.app/">Graviton Editor</a> (Cross-platform and modern-looking code editor)</li>
<li><a href="https://hackmd.io">HackMD</a> (Realtime collaborative markdown notes on all platforms)</li>
<li><a href="http://www.handcraft.com/">Handcraft</a> (HTML prototyping)</li>
<li><a href="http://hawkee.com/">Hawkee</a></li>
@@ -101,6 +106,8 @@
<li><a href="http://megafonweblab.github.com/histone-javascript/">Histone template engine playground</a></li>
<li><a href="http://www.homegenie.it/docs/automation_getstarted.php">Homegenie</a> (home automation server)</li>
<li><a href="http://icecoder.net">ICEcoder</a> (web IDE)</li>
+ <li><a href="https://innovay.app/formatter/html">Innovay Web Tools</a> (HTML, JS, CSS code beautifier)</li>
+ <li><a href="https://www.intervue.io">Intervue</a> (Pair programming for interviews)</li>
<li><a href="http://ipython.org/">IPython</a> (interactive computing shell)</li>
<li><a href="https://joelpinheiro.github.io/itrading/">iTrading</a> (Algorithmic Trading)</li>
<li><a href="http://i-mos.org/imos/">i-MOS</a> (modeling and simulation platform)</li>
@@ -123,6 +130,7 @@
<li><a href="https://liveuml.com/">LiveUML</a> (PlantUML online editor)</li>
<li><a href="https://github.com/TuvaLabs/markdown-delight-editor">Markdown Delight Editor</a> (extensible markdown editor polymer component)</li>
<li><a href="http://marklighteditor.com/">Marklight editor</a> (lightweight markup editor)</li>
+ <li><a href="https://www.mediawiki.org/wiki/Extension:CodeMirror">MediaWiki extension</a> (wiki engine)</li>
<li><a href="http://www.mergely.com/">Mergely</a> (interactive diffing)</li>
<li><a href="http://www.iunbug.com/mihtool">MIHTool</a> (iOS web-app debugging tool)</li>
<li><a href="http://mscgen.js.org/index.html">mscgen_js</a> (online sequence chart editor)</li>
@@ -135,6 +143,7 @@
<li><a href="http://www.greycampus.com/opencampus">OpenCampus</a></li>
<li><a href="http://clrhome.org/asm/">ORG</a> (z80 assembly IDE)</li>
<li><a href="https://github.com/mamacdon/orion-codemirror">Orion-CodeMirror integration</a> (running CodeMirror modes in Orion)</li>
+ <li><a href="https://www.overleaf.com/">Overleaf</a> (Collaborative LaTeX Editor)</li>
<li><a href="http://paperjs.org/">Paper.js</a> (graphics scripting)</li>
<li><a href="http://pharaoh.js.org/">Pharaoh</a> (browser &amp; desktop editor for the classroom)</li>
<li><a href="http://prinbit.com/">PrinBit</a> (collaborative coding tool)</li>
@@ -150,6 +159,7 @@
<li><a href="https://www.realtime.io/">RealTime.io</a> (Internet-of-Things infrastructure)</li>
<li><a href="http://refork.com/">Refork</a> (animation demo gallery and sharing)</li>
<li><a href="http://sagecell.sagemath.org">SageMathCell</a> (interactive mathematical software)</li>
+ <li><a href="https://sass2css.herokuapp.com/">SASS2CSS</a> (SASS, SCSS or LESS to CSS converter and CSS beautifier)</li>
<li><a href="https://cloud.sagemath.com/">SageMathCloud</a> (interactive mathematical software environment)</li>
<li><a href="https://github.com/szekelymilan/salvare">salvare</a> (real-time collaborative code editor)</li>
<li><a href="https://chrome.google.com/webstore/detail/servephp/mnpikomdchjhkhbhmbboehfdjkobbfpo">ServePHP</a> (PHP code testing in Chrome dev tools)</li>
@@ -177,6 +187,7 @@
<li><a href="http://turbopy.com/">TurboPY</a> (web publishing framework)</li>
<li><a href="http://cruise.eecs.uottawa.ca/umpleonline/">UmpleOnline</a> (model-oriented programming tool)</li>
<li><a href="https://upsource.jetbrains.com/idea-ce/file/idea-ce-7706e7832aa9e2fd0c2decdb5cbef2225692c696/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorFactoryImpl.java">Upsource</a> (code browser and review tool)</li>
+ <li><a href="https://violentmonkey.github.io/">Violentmonkey</a> (userscript manager / editor)</li>
<li><a href="https://github.com/mgaitan/waliki">Waliki</a> (wiki engine)</li>
<li><a href="http://wamer.net/">Wamer</a> (web application builder)</li>
<li><a href="https://github.com/brettz9/webappfind">webappfind</a> (windows file bindings for webapps)</li>
@@ -186,7 +197,6 @@
<li><a href="http://www.wescheme.org/">WeScheme</a> (learning tool)</li>
<li><a href="https://github.com/b3log/wide">Wide</a> (golang web IDE)</li>
<li><a href="http://wordpress.org/extend/plugins/codemirror-for-codeeditor/">WordPress plugin</a></li>
- <li><a href="https://www.writelatex.com">writeLaTeX</a> (Collaborative LaTeX Editor)</li>
<li><a href="http://www.xosystem.org/home/applications_websites/xosystem_website/xoside_EN.php">XOSide</a> (online editor)</li>
<li><a href="http://videlibri.sourceforge.net/cgi-bin/xidelcgi">XQuery tester</a></li>
<li><a href="http://q42jaap.github.io/xsd2codemirror/">xsd2codemirror</a> (convert XSD to CM XML completion info)</li>
diff --git a/help3/xhpeditor/cm/doc/releases.html b/help3/xhpeditor/cm/doc/releases.html
index e33ca152..7ae3f3a6 100644
--- a/help3/xhpeditor/cm/doc/releases.html
+++ b/help3/xhpeditor/cm/doc/releases.html
@@ -30,6 +30,199 @@
<h2>Version 5.x</h2>
+ <p class="rel">20-05-2021: <a href="https://codemirror.net/codemirror-5.61.1.zip">Version 5.61.1</a>:</p>
+
+ <ul class="rel-note">
+ <li>Fix a bug where changing the editor’s document could confuse text-direction management.</li>
+ <li>Fix a bug in horizontally scrolling the cursor into view.</li>
+ <li>Optimize adding lots of marks in a single transaction.</li>
+ <li><a href="https://codemirror.net/demo/simplemode.html">simple mode addon</a>: Support regexps with a unicode flag.</li>
+ <li><a href="https://codemirror.net/mode/javascript/index.html">javascript mode</a>: Add support for TypeScript template string types, improve integration with JSX mode.</li>
+ </ul>
+
+ <p class="rel">20-04-2021: <a href="https://codemirror.net/codemirror-5.61.0.zip">Version 5.61.0</a>:</p>
+
+ <ul class="rel-note">
+ <li>The library now emits an <code>"updateGutter"</code> event when the gutter width changes.</li>
+ <li><a href="https://codemirror.net/demo/emacs.html">emacs bindings</a>: Provide named commands for all bindings.</li>
+ <li>Improve support for being in a shadow DOM in contenteditable mode.</li>
+ <li>Prevent line number from being read by screen readers.</li>
+ <li><a href="https://codemirror.net/doc/manual.html#addon_show-hint">show-hint addon</a>: Fix a crash caused by a race condition.</li>
+ <li><a href="https://codemirror.net/mode/javascript/">javascript mode</a>: Improve scope tracking.</li>
+ </ul>
+
+ <p class="rel">20-03-2021: <a href="https://codemirror.net/codemirror-5.60.0.zip">Version 5.60.0</a>:</p>
+
+ <ul class="rel-note">
+ <li><code>setSelections</code> now allows ranges to omit the <code>head</code> property when it is equal to <code>anchor</code>.</li>
+ <li><a href="https://codemirror.net/demo/sublime.html">sublime bindings</a>: Add support for reverse line sorting.</li>
+ <li>Fix autofocus feature in contenteditable mode.</li>
+ <li><a href="https://codemirror.net/demo/simplemode.html">simple mode addon</a>: Fix a null-dereference crash.</li>
+ <li><a href="https://codemirror.net/demo/multiplex.html">multiplex addon</a>: Make it possible to use <code>parseDelimiters</code> when both delimiters are the same.</li>
+ <li><a href="https://codemirror.net/mode/julia/">julia mode</a>: Fix a lockup bug.</li>
+ </ul>
+
+ <p class="rel">24-02-2021: <a href="https://codemirror.net/codemirror-5.59.4.zip">Version 5.59.4</a>:</p>
+
+ <ul class="rel-note">
+ <li>Give the scrollbar corner filler a background again, to prevent content from peeping through between the scrollbars.
+ </ul>
+
+ <p class="rel">20-02-2021: <a href="https://codemirror.net/codemirror-5.59.3.zip">Version 5.59.3</a>:</p>
+
+ <ul class="rel-note">
+ <li>Don’t override the way zero-with non-joiners are rendered.</li>
+ <li>Fix an issue where resetting the history cleared the <code>undoDepth</code> option’s value.</li>
+ <li><a href="https://codemirror.net/demo/vim.html">vim bindings</a>: Fix substitute command when joining and splitting lines, fix global command when line number change, add support for <code>:vglobal</code>, properly treat caps lock as a modifier key.</li>
+ </ul>
+
+ <p class="rel">20-01-2021: <a href="https://codemirror.net/codemirror-5.59.2.zip">Version 5.59.2</a>:</p>
+
+ <ul class="rel-note">
+ <li>Don’t try to scroll the selection into view in <code>readonly: "nocursor"</code> mode.</li>
+ <li><a href="https://codemirror.net/doc/manual.html#addon_closebrackets">closebrackets addon</a>: Fix a regression in the behavior of pressing enter between brackets.</li>
+ <li><a href="https://codemirror.net/mode/javascript/">javascript mode</a>: Fix an infinite loop on specific syntax errors in object types.</li>
+ <li>various modes: Fix inefficient RegExp matching.</li>
+ </ul>
+
+ <p class="rel">31-12-2020: <a href="https://codemirror.net/codemirror-5.59.1.zip">Version 5.59.1</a>:</p>
+
+ <ul class="rel-note">
+ <li>Fix an issue where some Chrome browsers were detected as iOS.</li>
+ </ul>
+
+ <p class="rel">20-12-2020: <a href="https://codemirror.net/codemirror-5.59.0.zip">Version 5.59.0</a>:</p>
+
+ <ul class="rel-note">
+ <li>Fix platform detection on recent iPadOS.</li>
+ <li><a href="https://codemirror.net/doc/manual.html#addon_lint">lint addon</a>: Don't show duplicate messages for a given line.</li>
+ <li><a href="https://codemirror.net/mode/clojure/index.html">clojure mode</a>: Fix regexp that matched in exponential time for some inputs.</li>
+ <li><a href="https://codemirror.net/doc/manual.html#addon_hardwrap">hardwrap addon</a>: Improve handling of words that are longer than the line length.</li>
+ <li><a href="https://codemirror.net/doc/manual.html#addon_matchbrackets">matchbrackets addon</a>: Fix leaked event handler on disabling the addon.</li>
+ <li><a href="https://codemirror.net/demo/search/">search addon</a>: Make it possible to configure the search addon to show the dialog at the bottom of the editor.</li>
+ </ul>
+
+ <p class="rel">19-11-2020: <a href="https://codemirror.net/codemirror-5.58.3.zip">Version 5.58.3</a>:</p>
+
+ <ul class="rel-note">
+ <li>Suppress quick-firing of blur-focus events when dragging and clicking on Internet Explorer.</li>
+ <li>Fix the <code>insertAt</code> option to <code>addLineWidget</code> to actually allow the widget to be placed after all widgets for the line.</li>
+ <li><a href="https://codemirror.net/mode/soy/">soy mode</a>: Support <code>@Attribute</code> and element composition.</li>
+ <li><a href="https://codemirror.net/mode/shell/">shell mode</a>: Support heredoc quoting.</li>
+ </ul>
+
+ <p class="rel">23-10-2020: <a href="https://codemirror.net/codemirror-5.58.2.zip">Version 5.58.2</a>:</p>
+
+ <ul class="rel-note">
+ <li>Fix a bug where horizontally scrolling the cursor into view sometimes failed with a non-fixed gutter.</li>
+ <li><a href="https://codemirror.net/mode/julia/">julia mode</a>: Fix an infinite recursion bug.</li>
+ </ul>
+
+ <p class="rel">21-09-2020: <a href="https://codemirror.net/codemirror-5.58.1.zip">Version 5.58.1</a>:</p>
+
+ <ul class="rel-note">
+ <li><a href="https://codemirror.net/doc/manual.html#addon_placeholder">placeholder addon</a>: Remove arrow function that ended up in the code.</li>
+ </ul>
+
+ <p class="rel">21-09-2020: <a href="https://codemirror.net/codemirror-5.58.0.zip">Version 5.58.0</a>:</p>
+
+ <ul class="rel-note">
+ <li>Make backspace delete by code point, not glyph.</li>
+ <li>Suppress flickering focus outline when clicking on scrollbars in Chrome.</li>
+ <li>Fix a bug that prevented attributes added via <code>markText</code> from showing up unless the span also had some other styling.</li>
+ <li>Suppress cut and paste context menu entries in readonly editors in Chrome.</li>
+ <li><a href="https://codemirror.net/doc/manual.html#addon_placeholder">placeholder addon</a>: Update placeholder visibility during composition.</li>
+ <li>Make it less cumbersome to style new lint message types.</li>
+ <li><a href="https://codemirror.net/demo/vim.html">vim bindings</a>: Support black hole register, <code>gn</code> and <code>gN</code></li>
+ </ul>
+
+ <p class="rel">20-08-2020: <a href="https://codemirror.net/codemirror-5.57.0.zip">Version 5.57.0</a>:</p>
+
+ <ul class="rel-note">
+ <li>Fix issue that broke binding the macOS Command key.</li>
+ <li><a href="https://codemirror.net/doc/manual.html#addon_comment">comment addon</a>: Keep selection in front of inserted markers when adding a block comment.</li>
+ <li><a href="https://codemirror.net/mode/css/">css mode</a>: Recognize more properties and value names.</li>
+ <li><a href="https://codemirror.net/doc/manual.html#addon_annotatescrollbar">annotatescrollbar addon</a>: Don’t hide matches in collapsed content.</li>
+ <li><a href="https://codemirror.net/demo/vim.html">vim bindings</a>: Support tag text objects in xml and html modes.</li>
+ </ul>
+
+ <p class="rel">20-07-2020: <a href="https://codemirror.net/codemirror-5.56.0.zip">Version 5.56.0</a>:</p>
+
+ <ul class="rel-note">
+ <li>Line-wise pasting was fixed on Chrome Windows.</li>
+ <li><a href="https://codemirror.net/mode/wast/">wast mode</a>: Follow standard changes.</li>
+ <li><a href="https://codemirror.net/mode/soy/">soy mode</a>: Support import expressions, template type, and loop indices.</li>
+ <li><a href="https://codemirror.net/doc/manual.html#addon_sql-hint">sql-hint addon</a>: Improve handling of double quotes.</li>
+ <li><h3 id="new-features">New features</h3></li>
+ <li><a href="https://codemirror.net/doc/manual.html#addon_show-hint">show-hint addon</a>: New option <code>scrollMargin</code> to control how many options are visible beyond the selected one.</li>
+ <li><a href="https://codemirror.net/doc/manual.html#addon_hardwrap">hardwrap addon</a>: New option <code>forceBreak</code> to disable breaking of words that are longer than a line.</li>
+ </ul>
+
+ <p class="rel">21-06-2020: <a href="https://codemirror.net/codemirror-5.55.0.zip">Version 5.55.0</a>:</p>
+
+ <ul class="rel-note">
+ <li>The editor no longer overrides the rendering of zero-width joiners (allowing combined emoji to be shown).</li>
+ <li><a href="https://codemirror.net/demo/vim.html">vim bindings</a>: Fix an issue where the <code>vim-mode-change</code> event was fired twice.</li>
+ <li><a href="https://codemirror.net/mode/javascript/">javascript mode</a>: Only allow <code>--&gt;</code>-style comments at the start of a line.</li>
+ <li><a href="https://codemirror.net/mode/julia/">julia mode</a>: Improve indentation.</li>
+ <li><a href="https://codemirror.net/mode/pascal/index.html">pascal mode</a>: Recognize curly bracket comments.</li>
+ <li><a href="https://codemirror.net/doc/manual.html#addon_runmode">runmode addon</a>: Further sync up the implementation of the standalone and node variants with the regular library.</li>
+ <li><h3 id="new-features">New features</h3></li>
+ <li><a href="https://codemirror.net/doc/manual.html#addon_loadmode">loadmode addon</a>: Allow overriding the way the addon constructs filenames and loads modules.</li>
+ </ul>
+
+ <p class="rel">20-05-2020: <a href="https://codemirror.net/codemirror-5.54.0.zip">Version 5.54.0</a>:</p>
+
+ <ul class="rel-note">
+ <li><a href="https://codemirror.net/doc/manual.html#addon_runmode">runmode addon</a>: Properly support for cross-line lookahead.</li>
+ <li><a href="https://codemirror.net/demo/vim.html">vim bindings</a>: Allow Ex-Commands with non-word names.</li>
+ <li><a href="https://codemirror.net/mode/gfm/">gfm mode</a>: Add a <code>fencedCodeBlockDefaultMode</code> option.</li>
+ <li>Improve support for having focus inside in-editor widgets in contenteditable-mode.</li>
+ <li>Fix issue where the scroll position could jump when clicking on a selection in Chrome.</li>
+ <li><a href="https://codemirror.net/mode/python/">python mode</a>: Better format string support.</li>
+ <li><a href="https://codemirror.net/mode/javascript/">javascript mode</a>: Improve parsing of private properties and class fields.</li>
+ <li><a href="https://codemirror.net/doc/manual.html#addon_matchbrackets">matchbrackets addon</a>: Disable highlighting when the editor doesn’t have focus.</li>
+ </ul>
+
+ <p class="rel">21-04-2020: <a href="https://codemirror.net/codemirror-5.53.2.zip">Version 5.53.2</a>:</p>
+
+ <ul class="rel-note">
+ <li><a href="https://codemirror.net/doc/manual.html#addon_show-hint">show-hint addon</a>: Fix a regression that broke completion picking.
+ </ul>
+
+ <p class="rel">21-04-2020: <a href="https://codemirror.net/codemirror-5.53.0.zip">Version 5.53.0</a>:</p>
+
+ <ul class="rel-note">
+ <li>New option: <a href="https://codemirror.net/doc/manual.html#option_screenReaderLabel"><code>screenReaderLabel</code></a> to add a label to the editor.</li>
+ <li>New mode: <a href="https://codemirror.net/mode/wast/">wast</a>.</li>
+ <li>Fix a bug where the editor layout could remain confused after a call to <code>refresh</code> when line wrapping was enabled.</li>
+ <li><a href="https://codemirror.net/doc/manual.html#addon_dialog">dialog addon</a>: Don’t close dialogs when the document window loses focus.</li>
+ <li><a href="https://codemirror.net/doc/manual.html#addon_merge">merge addon</a>: Compensate for editor top position when aligning lines.</li>
+ <li><a href="https://codemirror.net/demo/vim.html">vim bindings</a>: Improve EOL handling.</li>
+ <li><a href="https://codemirror.net/demo/emacs.html">emacs bindings</a>: Include default keymap as a fallback.</li>
+ <li><a href="https://codemirror.net/mode/julia/">julia mode</a>: Fix an infinite loop bug.</li>
+ <li><a href="https://codemirror.net/doc/manual.html#addon_show-hint">show-hint addon</a>: Scroll cursor into view when picking a completion.</li>
+ </ul>
+
+ <p class="rel">20-03-2020: <a href="https://codemirror.net/codemirror-5.52.2.zip">Version 5.52.2</a>:</p>
+
+ <ul class="rel-note">
+ <li>Fix selection management in contenteditable mode when the editor doesn’t have focus.</li>
+ <li>Fix a bug that would cause the editor to get confused about the visible viewport in some situations in line-wrapping mode.</li>
+ <li><a href="https://codemirror.net/mode/markdown/">markdown mode</a>: Don’t treat single dashes as setext header markers.</li>
+ <li><a href="https://codemirror.net/demo/theme.html#zenburn">zenburn theme</a>: Make sure background styles take precedence over default styles.</li>
+ <li><a href="https://codemirror.net/mode/css/">css mode</a>: Recognize a number of new properties.</li>
+ </ul>
+
+ <p class="rel">20-02-2020: <a href="https://codemirror.net/codemirror-5.52.0.zip">Version 5.52.0</a>:</p>
+
+ <ul class="rel-note">
+ <li>Fix a bug in handling of bidi text with Arabic numbers in a right-to-left editor.</li>
+ <li>Fix a crash when combining file drop with a <code>"beforeChange"</code> filter.</li>
+ <li>Prevent issue when passing negative coordinates to <code>scrollTo</code>.</li>
+ <li><a href="https://codemirror.net/doc/manual.html#addon_lint">lint</a> and <a href="https://codemirror.net/demo/tern.html">tern</a> addons: Allow the tooltip to be appended to the editor wrapper element instead of the document body.</li>
+ </ul>
+
<p class="rel">20-01-2020: <a href="https://codemirror.net/codemirror-5.51.0.zip">Version 5.51.0</a>:</p>
<ul class="rel-note">
@@ -37,7 +230,7 @@
<li>When dropping multiple files, don’t abort the drop of the valid files when there’s an invalid or binary file among them.</li>
<li>Make sure <code>clearHistory</code> clears the history in all linked docs with a shared history.</li>
<li><a href="https://codemirror.net/demo/vim.html">vim bindings</a>: Fix behavior of <code>'</code> and <code>`</code> marks, fix <code>R</code> in visual mode.</li>
- <li><a href="https://codemirror.net/demo/vim.html">vim bindings</a>: Support <code>gi</code>, gI<code>, and</code>gJ`.</li>
+ <li><a href="https://codemirror.net/demo/vim.html">vim bindings</a>: Support <code>gi</code>, <code>gI<code>, and <code>gJ</code>.</li>
</ul>
<p class="rel">01-01-2020: <a href="https://codemirror.net/codemirror-5.50.2.zip">Version 5.50.2</a>:</p>
@@ -55,7 +248,7 @@
<li>Make Shift-Delete to cut work on Firefox.</li>
<li><a href="https://codemirror.net/demo/closetag.html">closetag addon</a>: Properly handle self-closing tags.</li>
<li><a href="https://codemirror.net/mode/handlebars/">handlebars mode</a>: Fix triple-brace support.</li>
- <li><a href="https://codemirror.net/doc/manual.html#addon_searchcursor">searchcursor addon</a>: Support mathing <code>$</code> in reverse regexp search.</li>
+ <li><a href="https://codemirror.net/doc/manual.html#addon_searchcursor">searchcursor addon</a>: Support matching <code>$</code> in reverse regexp search.</li>
<li><a href="https://codemirror.net/doc/manual.html#addon_panel">panel addon</a>: Don’t get confused by changing panel sizes.</li>
<li><a href="https://codemirror.net/doc/manual.html#addon_javascript-hint">javascript-hint addon</a>: Complete variables defined in outer scopes.</li>
<li><a href="https://codemirror.net/demo/sublime.html">sublime bindings</a>: Make by-subword motion more consistent with Sublime Text.</li>
@@ -216,7 +409,7 @@
<li>New method <a href="https://codemirror.net/doc/manual.html#phrase"><code>phrase</code></a> and option <a href="https://codemirror.net/doc/manual.html#option_phrases"><code>phrases</code></a> to make translating UI text in addons easier.</li>
<li><a href="https://codemirror.net/doc/manual.html#addon_closebrackets">closebrackets addon</a>: Fix issue where bracket-closing wouldn't work before punctuation.</li>
<li><a href="https://codemirror.net/doc/manual.html#addon_panel">panel addon</a>: Fix problem where replacing the last remaining panel dropped the newly added panel.</li>
- <li><a href="https://codemirror.net/doc/manual.html#addon_hardwrap">hardwrap addon</a>: Fix an infinite loop when the indention is greater than the target column.</li>
+ <li><a href="https://codemirror.net/doc/manual.html#addon_hardwrap">hardwrap addon</a>: Fix an infinite loop when the indentation is greater than the target column.</li>
<li><a href="https://codemirror.net/mode/jinja2/">jinja2</a> and <a href="https://codemirror.net/mode/markdown/">markdown</a> modes: Add comment metadata.</li>
</ul>
@@ -450,7 +643,7 @@
<li>Fix handling of shadow DOM roots when finding the active element.</li>
<li>Add <code>role=presentation</code> to more DOM elements to improve screen reader support.</li>
<li><a href="https://codemirror.net/doc/manual.html#addon_merge">merge addon</a>: Make aligning of unchanged chunks more robust.</li>
- <li><a href="https://codemirror.net/doc/manual.html#addon_comment">comment addon</a>: Fix comment-toggling on a block of text that starts and ends in a (differnet) block comment.</li>
+ <li><a href="https://codemirror.net/doc/manual.html#addon_comment">comment addon</a>: Fix comment-toggling on a block of text that starts and ends in a (different) block comment.</li>
<li><a href="https://codemirror.net/mode/javascript/">javascript mode</a>: Improve support for TypeScript syntax.</li>
<li><a href="https://codemirror.net/mode/r/">r mode</a>: Fix indentation after semicolon-less statements.</li>
<li><a href="https://codemirror.net/mode/shell/">shell mode</a>: Properly handle escaped parentheses in parenthesized expressions.</li>
@@ -515,7 +708,7 @@
<ul class=rel-note>
<li>Tapping/clicking the editor in <a href="https://codemirror.net/doc/manual.html#option_inputStyle">contentEditable mode</a> on Chrome now puts the cursor at the tapped position.</li>
- <li>Fix various crashes and misbehaviors when reading composition events in <a href="https://codemirror.net/doc/manual.html#option_inputStyle">contentEditable mode</a>.</li>
+ <li>Fix various crashes and misbehavior when reading composition events in <a href="https://codemirror.net/doc/manual.html#option_inputStyle">contentEditable mode</a>.</li>
<li>Catches and ignores an IE 'Unspecified Error' when creating an editor in an iframe before there is a <code>&lt;body&gt;</code>.</li>
<li><a href="https://codemirror.net/doc/manual.html#addon_merge">merge addon</a>: Fix several issues in the chunk-aligning feature.</li>
<li><a href="https://codemirror.net/mode/verilog">verilog mode</a>: Rewritten to address various issues.</li>
@@ -738,7 +931,7 @@
<li>New modes: <a href="../mode/vue/index.html">Vue</a>, <a href="../mode/oz/index.html">Oz</a>, <a href="../mode/mscgen/index.html">MscGen</a> (and dialects), <a href="../mode/css/gss.html">Closure Stylesheets</a></li>
<li>Implement <a href="http://commonmark.org">CommonMark</a>-style flexible list indent and cross-line code spans in <a href="../mode/markdown/index.html">Markdown</a> mode</li>
<li>Add a replace-all button to the <a href="manual.html#addon_search">search addon</a>, and make the persistent search dialog transparent when it obscures the match</li>
- <li>Handle <code>acync</code>/<code>await</code> and ocal and binary numbers in <a href="../mode/javascript/index.html">JavaScript mode</a></li>
+ <li>Handle <code>async</code>/<code>await</code> and ocal and binary numbers in <a href="../mode/javascript/index.html">JavaScript mode</a></li>
<li>Fix various issues with the <a href="../mode/haxe/index.html">Haxe mode</a></li>
<li>Make the <a href="manual.html#addon_closebrackets">closebrackets addon</a> select only the wrapped text when wrapping selection in brackets</li>
<li>Tokenize properties as properties in the <a href="../mode/coffeescript/index.html">CoffeeScript mode</a></li>
@@ -1545,7 +1738,7 @@
bindings</a>.</li>
<li>Support for overwrite (insert).</li>
<li><a href="manual.html#option_tabSize">Custom-width</a>
- and <a href="../demo/visibletabs.html">stylable</a> tabs.</li>
+ and <a href="../demo/visibletabs.html">styleable</a> tabs.</li>
<li>Moved more code into <a href="manual.html#addons">add-on scripts</a>.</li>
<li>Support for sane vertical cursor movement in wrapped lines.</li>
<li>More reliable handling of
@@ -1566,7 +1759,7 @@
<li>Add support for <a href="manual.html#option_lineWrapping">line
wrapping</a> and <a href="manual.html#hideLine">code
folding</a>.</li>
- <li>Add <a href="../mode/gfm/index.html">Github-style Markdown</a> mode.</li>
+ <li>Add <a href="../mode/gfm/index.html">GitHub-style Markdown</a> mode.</li>
<li>Add <a href="../theme/monokai.css">Monokai</a>
and <a href="../theme/rubyblue.css">Rubyblue</a> themes.</li>
<li>Add <a href="manual.html#setBookmark"><code>setBookmark</code></a> method.</li>
@@ -1686,7 +1879,7 @@
<p class="rel-note">CodeMirror 2 is a complete rewrite that's
faster, smaller, simpler to use, and less dependent on browser
quirks. See <a href="internals.html">this</a>
- and <a href="https://groups.google.com/group/codemirror/browse_thread/thread/5a8e894024a9f580">this</a>
+ and <a href="http://groups.google.com/group/codemirror/browse_thread/thread/5a8e894024a9f580">this</a>
for more information.</p>
<p class="rel">22-02-2011: <a href="https://github.com/codemirror/codemirror/tree/beta2">Version 2.0 beta 2</a>:</p>
diff --git a/help3/xhpeditor/cm/doc/upgrade_v2.2.html b/help3/xhpeditor/cm/doc/upgrade_v2.2.html
index 5709e652..dabe974c 100644
--- a/help3/xhpeditor/cm/doc/upgrade_v2.2.html
+++ b/help3/xhpeditor/cm/doc/upgrade_v2.2.html
@@ -79,7 +79,7 @@ to indent the current line more (<code>"indentMore"</code> command),
and indent it less when shift is held (<code>"indentLess"</code>).
There are also <code>"indentAuto"</code> (smart indent)
and <code>"insertTab"</code> commands provided for alternate
-behaviors. Or you can write your own handler function to do something
+behavior. Or you can write your own handler function to do something
different altogether.</p>
<h3>Tabs</h3>
diff --git a/help3/xhpeditor/cm/index.html b/help3/xhpeditor/cm/index.html
index bebe38fe..1bf64b18 100644
--- a/help3/xhpeditor/cm/index.html
+++ b/help3/xhpeditor/cm/index.html
@@ -18,10 +18,13 @@
.CodeMirror { height: auto; border: 1px solid #ddd; }
.CodeMirror-scroll { max-height: 200px; }
.CodeMirror pre { padding-left: 7px; line-height: 1.25; }
- .banner { background: #ffc; padding: 6px; border-bottom: 2px solid silver; }
- .banner div { margin: 0 auto; max-width: 700px; text-align: center; }
+ .banner { background: #ffc; padding: 6px; border-bottom: 2px solid silver; text-align: center }
</style>
+<div class=banner>
+ ‼️ Check out the upcoming <a href="https://codemirror.net/6/">CodeMirror 6</a>, a much-improved rewrite! ✨
+</div>
+
<div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="doc/logo.png"></a>
@@ -99,8 +102,8 @@
</div>
</div>
<div class=actionsleft>
- Get the current version: <a href="https://codemirror.net/codemirror.zip">5.51.0</a>.<br>
- You can see the <a href="https://github.com/codemirror/codemirror" title="Github repository">code</a>,<br>
+ Get the current version: <a href="https://codemirror.net/codemirror.zip">5.61.1</a>.<br>
+ You can see the <a href="https://github.com/codemirror/codemirror" title="GitHub repository">code</a>,<br>
read the <a href="doc/releases.html">release notes</a>,<br>
or study the <a href="doc/manual.html">user manual</a>.
</div>
@@ -171,11 +174,6 @@
that explicit, we have
a <a href="http://contributor-covenant.org/version/1/1/0/">code of
conduct</a> that applies to communication around the project.</p>
-
- <p>A list of CodeMirror-related software that is not part of the
- main distribution is maintained
- on <a href="https://github.com/codemirror/CodeMirror/wiki/CodeMirror-addons">our
- wiki</a>. Feel free to add your project.</p>
</section>
<section id=browsersupport>
@@ -195,4 +193,28 @@
pretty well.</p>
</section>
+<section id=sponsors>
+ <style>
+ ul.sponsor-list { padding-left: 10px; font-size: 200%; }
+ ul.sponsor-list a { color: black; text-decoration: none }
+ ul.sponsor-list li { list-style: none; margin-bottom: 16px }
+ ul.sponsor-list img { max-width: 80%; max-height: 160px; width: 320px }
+ ul.sponsor-list img.captioned { vertical-align: middle; width: 80px; max-width: 40%; height: auto; margin-right: 16px }
+ </style>
+
+ <h2>Sponsors</h2>
+ <p>These companies support development of this project:</p>
+ <ul class=sponsor-list>
+ <li><a href="http://observablehq.com/"><img alt="Observable" src='data:image/svg+xml;utf8,<svg viewBox="-3 0 171 28" width="350" height="57" fill="black" xmlns="http://www.w3.org/2000/svg"><path d="M12.5 22.66c-1.15 0-2.15-.25-3-.75a5.09 5.09 0 01-1.94-2.04 10.80 10.80 0 01-.99-2.74A14.74 14.74 0 016.25 14c0-.83.05-1.62.16-2.38.10-.75.30-1.52.60-2.31a7.37 7.37 0 011.12-2.03 5.11 5.11 0 011.80-1.40c.74-.36 1.59-.53 2.54-.53 1.15 0 2.15.25 3 .75.84.50 1.51 1.21 1.94 2.04.45.86.78 1.77.99 2.74.20.96.31 2.00.31 3.12a16.7 16.7 0 01-.16 2.38 10.63 10.63 0 01-.61 2.31c-.30.78-.67 1.46-1.13 2.03-.45.57-1.05 1.04-1.79 1.40-.74.36-1.59.53-2.54.53zm2.20-6.37c.59-.6.93-1.43.91-2.29 0-.89-.29-1.65-.89-2.29-.59-.63-1.34-.95-2.22-.95s-1.63.31-2.23.95A3.23 3.23 0 009.37 14c0 .89.29 1.65.89 2.29.59.63 1.34.95 2.22.95s1.62-.31 2.20-.95zM12.5 27C19.40 27 25 21.18 25 14S19.40 1 12.5 1 0 6.82 0 14s5.59 13 12.5 13z"/><g transform="translate(30, -3.5)"><path d="M6.41 17.75c0 1.09.05 2.09.15 2.98.11.87.29 1.62.53 2.25.23.62.54 1.11.91 1.46.37.33.82.50 1.36.50.54 0 .99-.17 1.36-.50.37-.35.67-.84.91-1.46.23-.62.40-1.37.50-2.25.11-.89.17-1.89.17-2.98 0-1.08-.06-2.06-.17-2.96-.10-.89-.27-1.65-.50-2.27-.23-.64-.54-1.13-.91-1.46-.37-.35-.82-.53-1.36-.53s-.99.17-1.36.53c-.37.33-.67.82-.91 1.46-.23.62-.41 1.38-.53 2.27-.10.89-.15 1.88-.15 2.96zm2.96-8.75c1.06 0 2.08.17 3.06.53a7.36 7.36 0 012.60 1.62c.76.72 1.35 1.63 1.79 2.73.45 1.09.68 2.38.68 3.87 0 1.48-.22 2.77-.68 3.87-.43 1.09-1.03 2.00-1.79 2.73a7.07 7.07 0 01-2.60 1.62 8.92 8.92 0 01-3.06.53 9.14 9.14 0 01-3.08-.53 7.36 7.36 0 01-2.60-1.62c-.74-.72-1.34-1.63-1.79-2.73-.43-1.09-.65-2.38-.65-3.87 0-1.48.21-2.77.65-3.87.45-1.09 1.06-2.00 1.82-2.73a7.36 7.36 0 012.60-1.62 8.92 8.92 0 013.06-.53zm9.32 17.03v-1.29l1.13-.25c.01-.60.02-1.25.02-1.94V10.21l-1.36-.17V8.89l5.77-1.13.43.27-.10 3.51v3.18c.99-.97 2.19-1.46 3.59-1.46.69 0 1.34.13 1.94.40.60.27 1.13.67 1.59 1.21.45.54.81 1.21 1.06 2.02.27.81.40 1.75.40 2.83 0 1.04-.16 1.98-.48 2.80-.30.81-.70 1.50-1.21 2.07a5.24 5.24 0 01-1.74 1.31 4.83 4.83 0 01-2.05.45c-.74 0-1.38-.12-1.92-.38a4.12 4.12 0 01-1.39-1.03l-.50 1.41-5.18-.38zm7.16-2.05c.67 0 1.21-.33 1.62-1.01.40-.69.60-1.76.60-3.21 0-1.45-.20-2.47-.60-3.06-.40-.60-.94-.91-1.62-.91-.40 0-.8.12-1.18.38v7.46c.33.23.73.35 1.19.35zm13.10 2.42c-1.75 0-3.30-.41-4.65-1.24l.12-3.23h2.30l.40 2.63c.28.11.57.21.86.27.30.05.62.07.96.07.64 0 1.13-.09 1.49-.27.35-.20.53-.54.53-1.03 0-.33-.13-.63-.40-.88-.25-.27-.80-.52-1.64-.76l-1.44-.37c-1.01-.27-1.78-.74-2.30-1.41-.50-.67-.75-1.51-.75-2.50 0-.62.11-1.20.35-1.74a3.95 3.95 0 011.08-1.39c.48-.38 1.08-.69 1.77-.91.71-.22 1.51-.33 2.43-.33.77 0 1.49.08 2.15.25.65.16 1.34.42 2.05.75l-.20 2.85H41.75l-.55-2.25a4.91 4.91 0 00-.55-.07 3.89 3.89 0 00-.68-.05c-.48 0-.89.11-1.21.32-.32.20-.48.52-.48.96 0 .13.02.27.07.40.05.11.14.24.27.38a4.3 4.3 0 00.60.37c.27.11.62.23 1.06.35l1.41.38c1.18.32 2.02.81 2.53 1.49.52.65.78 1.49.78 2.50 0 .74-.14 1.39-.43 1.94a3.84 3.84 0 01-1.21 1.39c-.52.37-1.15.64-1.89.83-.74.18-1.57.27-2.50.27zM52.83 13.27c.91 0 1.70.14 2.37.43.67.28 1.24.68 1.69 1.18a4.85 4.85 0 011.01 1.77c.23.67.35 1.39.35 2.15 0 .27-.00.50-.02.71-.01.18-.05.39-.10.63H51.11c.13 1.24.49 2.15 1.08 2.70.59.54 1.26.81 2.02.81.64 0 1.18-.11 1.64-.32a5.07 5.07 0 001.24-.86l.98.96c-.54 1.03-1.27 1.78-2.20 2.25-.92.47-2.02.70-3.29.70a7.82 7.82 0 01-2.63-.43 6.19 6.19 0 01-2.1-1.29 6.34 6.34 0 01-1.36-2.07c-.32-.82-.48-1.76-.48-2.80 0-1.08.19-2.02.58-2.83.40-.82.92-1.51 1.57-2.05a6.61 6.61 0 012.2-1.24 7.71 7.71 0 012.45-.40zm-.30 1.36a.87.87 0 00-.55.20c-.17.11-.32.33-.45.65-.11.32-.22.74-.30 1.26-.06.52-.11 1.17-.12 1.94h1.19c.60 0 1.01-.11 1.21-.35.22-.25.32-.7.32-1.34 0-.87-.13-1.49-.40-1.84-.25-.35-.54-.53-.88-.53zM59.31 26v-1.29l1.21-.27c.01-.60.02-1.24.02-1.92V19.09v-.88c0-.23-.00-.45-.02-.65 0-.20-.00-.39-.02-.58 0-.20-.00-.43-.02-.68l-1.36-.22v-1.03l5.59-1.74.45.27.20 2.91c.33-1.08.81-1.88 1.44-2.40.64-.52 1.26-.78 1.87-.78.62 0 1.14.18 1.56.55.43.35.7.92.78 1.69-.03.69-.23 1.22-.60 1.59-.37.37-.81.55-1.31.55-.42 0-.80-.11-1.13-.32-.32-.21-.64-.57-.98-1.06l-.12-.17c-.30.33-.60.77-.91 1.31a5.62 5.62 0 00-.58 1.67V22.40c0 .65.00 1.28.02 1.87l1.97.43V26h-8.04zm19.93 0h-2.27l-4.50-10.88-1.21-.25v-1.19h7.61v1.19l-1.34.30 2.1 5.79 1.94-5.82-1.39-.27v-1.19h4.75v1.19l-1.51.25L79.25 26zm11.35-1.79c.32 0 .67-.14 1.06-.43v-4.2c-.25.06-.49.16-.73.27a2.55 2.55 0 00-.55.35 2.97 2.97 0 00-.53.50 2.36 2.36 0 00-.40.73c-.1.27-.15.57-.15.91 0 .62.12 1.08.38 1.39.25.30.56.45.93.45zm4.17 2.20c-.81 0-1.45-.15-1.92-.45-.47-.30-.81-.75-1.03-1.34-.25.27-.49.51-.73.73-.22.22-.47.41-.75.58-.27.15-.57.27-.91.35a4.94 4.94 0 01-1.19.12c-1.01 0-1.81-.27-2.40-.83-.59-.57-.88-1.38-.88-2.43 0-.48.07-.93.22-1.34.15-.42.42-.81.81-1.16.40-.35.93-.68 1.59-.98.67-.30 1.52-.59 2.55-.86l.70-.17c.27-.06.54-.14.83-.22v-.91c0-.54-.02-.98-.07-1.34-.05-.37-.15-.66-.30-.88a1.05 1.05 0 00-.58-.45c-.23-.10-.55-.15-.96-.15h-.38v.86c0 1.03-.21 1.76-.63 2.20-.42.42-.90.63-1.44.63-1.03 0-1.67-.45-1.92-1.36 0-1.09.51-1.98 1.54-2.65 1.04-.69 2.59-1.03 4.63-1.03.87 0 1.62.09 2.22.27.60.18 1.09.48 1.46.88.38.38.66.89.83 1.51.16.62.25 1.36.25 2.22v5.79c0 .28.14.43.43.43a.54.54 0 00.30-.10c.1-.06.22-.22.38-.45l.73.40c-.30.77-.71 1.33-1.24 1.67-.52.32-1.24.48-2.15.48zm3.89-.38v-1.29l1.13-.25c.01-.60.02-1.25.02-1.94V10.21l-1.36-.17V8.89l5.77-1.13.43.27-.10 3.51v3.18c.99-.97 2.19-1.46 3.59-1.46.69 0 1.34.13 1.94.40a4.42 4.42 0 011.59 1.21c.45.54.81 1.21 1.06 2.02.27.81.40 1.75.40 2.83 0 1.04-.16 1.98-.48 2.80-.30.81-.70 1.50-1.21 2.07a5.24 5.24 0 01-1.74 1.31 4.83 4.83 0 01-2.04.45c-.74 0-1.38-.12-1.92-.38a4.12 4.12 0 01-1.39-1.03l-.50 1.41-5.18-.38zm7.16-2.05c.67 0 1.21-.33 1.61-1.01.40-.69.60-1.76.60-3.21 0-1.45-.20-2.47-.60-3.06-.40-.60-.94-.91-1.61-.91-.40 0-.80.12-1.19.38v7.46c.33.23.73.35 1.19.35zm8.40-15.08l5.84-1.13.43.27-.10 3.51v11.03l.05 1.89 1.13.22V26h-7.18v-1.29l1.13-.25a70.7 70.7 0 00.02-1.87c.01-.62.02-1.25.02-1.89v-10.4l-1.36-.25V8.89zm15.30 4.37c.91 0 1.70.14 2.37.43.67.28 1.24.68 1.69 1.18a4.84 4.84 0 011.01 1.77c.23.67.35 1.39.35 2.15 0 .27-.00.50-.02.71-.01.18-.05.39-.10.63h-7.03c.13 1.24.49 2.15 1.08 2.70.59.54 1.26.81 2.02.81.64 0 1.18-.11 1.64-.32a5.09 5.09 0 001.24-.86l.98.96c-.53 1.03-1.27 1.78-2.20 2.25-.92.47-2.02.70-3.28.70a7.83 7.83 0 01-2.63-.43 6.18 6.18 0 01-2.1-1.29 6.34 6.34 0 01-1.36-2.07c-.32-.82-.48-1.76-.48-2.80 0-1.08.19-2.02.58-2.83.40-.82.92-1.51 1.56-2.05a6.61 6.61 0 012.20-1.24 7.71 7.71 0 012.45-.40zm-.30 1.36a.87.87 0 00-.55.20c-.16.11-.32.33-.45.65-.11.32-.22.74-.30 1.26-.06.52-.11 1.17-.12 1.94h1.18c.60 0 1.01-.11 1.21-.35.22-.25.32-.7.32-1.34 0-.87-.13-1.49-.40-1.84-.25-.35-.54-.53-.88-.53z"/></g></svg>'></a></li>
+ <li><a href="https://holmusk.com"><img class=captioned alt="" src='data:image/svg+xml;utf8,<svg viewBox="0 0 60 60" version="1.1" xmlns="http://www.w3.org/2000/svg" style="background: %231649BF"><g transform="translate(-780, -40)" fill="%23FFFFFF"><path d="M780,4 L840,4 L840,1 L780,1 L780,4 Z M794,55 L794,84.65 L796.806,84.65 L796.806,72.739 C796.806,69.633 799.325,67.104 802.420,67.104 C805.516,67.104 808.031,69.633 808.031,72.739 L808.031,84.65 L810.838,84.65 L810.838,72.739 C810.838,68.077 807.062,64.288 802.420,64.288 C800.271,64.288 798.311,65.106 796.819,66.447 L796.819,55 L794,55 Z M817.582,63.931 C815.372,63.931 813.367,64.798 811.862,66.199 L812.163,66.653 C812.613,67.33 812.972,68.051 813.248,68.805 C814.281,67.549 815.840,66.746 817.582,66.746 C820.674,66.746 823.193,69.276 823.193,72.382 L823.193,72.385 L823.193,84.293 L826,84.293 L826,72.385 L826,72.379 C826,70.658 825.483,69.057 824.598,67.72 L824.598,67.723 C824.537,67.629 824.473,67.543 824.409,67.452 C824.345,67.365 824.280,67.278 824.213,67.191 C824.139,67.098 824.068,67.008 823.995,66.917 C823.870,66.776 823.744,66.634 823.616,66.502 C823.542,66.424 823.465,66.35 823.385,66.276 C823.289,66.183 823.190,66.093 823.090,66.002 C823.004,65.932 822.917,65.854 822.830,65.787 C822.689,65.671 822.542,65.561 822.394,65.458 C822.320,65.406 822.243,65.354 822.169,65.307 C821.999,65.194 821.829,65.087 821.650,64.991 C821.592,64.955 821.531,64.923 821.473,64.894 C821.307,64.807 821.142,64.726 820.976,64.653 C820.909,64.623 820.845,64.594 820.774,64.566 C820.569,64.478 820.357,64.401 820.138,64.33 C820.084,64.314 820.026,64.298 819.969,64.282 C819.773,64.224 819.577,64.172 819.382,64.131 C819.330,64.118 819.285,64.104 819.234,64.095 C819,64.05 818.766,64.015 818.525,63.985 C818.461,63.979 818.400,63.976 818.339,63.969 C818.095,63.947 817.855,63.931 817.611,63.931 L817.582,63.931 Z"></path></g></svg>'>Holmusk</a></li>
+ <li><a href="https://codepen.io/"><img style="margin: 16px 0" src='data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 138 26"><path fill="none" stroke="black" stroke-width="2.3" stroke-linecap="round" stroke-linejoin="round" d="M15 8a7 7 0 100 10m7-8.7L33 2l11 7.3v7.4L33 24l-11-7.3zm0 0l11 7.4 11-7.4m0 7.4L33 9.3l-11 7.4M33 2v7.3m0 7.4V24M52 6h5a7 7 0 010 14h-5zm28 0h-9v14h9m-9-7h6m11 1h6a4 4 0 000-8h-6v14m26-14h-9v14h9m-9-7h6m11 7V6l11 14V6"/></svg>' alt="CodePen"></a></li>
+ <li><a href="https://4me.com"><img style="width: auto" src='data:image/svg+xml;utf8,<svg fill-rule="evenodd" viewBox="10538 7547.8 6693 4459" xmlns="http://www.w3.org/2000/svg"><rect fill="%23062341" x="10538" y="7547.8" width="6693.4" height="4459.4"/><path fill="%23fefefe" d="m15757 9524c-11.38-73.68-40.63-133.26-87.74-178.76-47.13-45.5-109.68-68.26-187.68-68.26s-140.98 22.39-188.91 67.18c-47.94 44.78-79.21 104.72-93.86 179.84h558.19zm-2797.1-489.69h369.08v166.12c21.04-24.93 44.1-48.39 69.19-71.15 25.08-22.38 53.02-42.25 83.76-59.94 30.77-17.35 65.16-31.06 103.19-41.53 38.04-10.12 80.54-15.17 127.47-15.17 85.8 0 159.84 15.88 222.16 48.02 62.33 32.15 110.49 77.64 144.49 137.6 56.64-61.38 119.77-107.26 189.37-138.68 69.59-31.42 148.93-46.94 237.95-46.94 137.58 0 245.22 36.12 322.93 108.33 48.42 45.04 81.78 103.28 100 174.71 24.57-38.29 53.4-73.42 86.51-105.37 56.87-54.89 124.72-98.22 203.53-130 78.8-31.79 166.14-47.67 262.02-47.67 108.86 0 203.12 17.34 282.73 52 79.64 34.66 145.85 81.26 198.66 139.76 52.81 58.51 91.79 125.67 117 201.52 25.19 75.84 37.77 154.92 37.77 237.27 0 12.99-0.4 26.71-1.21 41.17-0.81 14.43-2.04 29.6-3.68 45.49h-909.14c17.86 75.11 54.83 131.82 110.9 170.09 56.06 38.29 125.53 57.43 208.39 57.43 61.76 0 117.01-9.4 165.77-28.18 48.74-18.78 99.11-49.11 151.1-91l212.06 166.84c-61.76 67.89-136.5 120.98-224.26 159.26-87.72 38.27-190.92 57.41-309.53 57.41-97.51 0-188.1-14.44-271.78-43.33-83.69-28.89-156-70.06-216.93-123.5-31.34-27.5-59.13-57.55-83.39-90.2v231.03h-369.04v-646.42c0-77.65-18.61-136.51-55.83-175.87-37.24-39.72-90.65-59.58-160.27-59.58-69.6 0-124.23 19.86-163.88 59.58-39.68 39.36-59.48 98.22-59.48 175.87v646.42h-369.06v-646.42c0-77.65-18.62-136.51-55.86-175.87-37.22-39.72-90.63-59.58-160.23-59.58s-124.24 19.86-163.9 59.58c-39.66 39.36-59.48 98.22-59.48 175.87v646.42h-563.64v325.09h-318.66v-325.09h-795.02l-0.53-238.52 827.03-922.87h287.18v888.19h194.56v-888.19zm-513.22 888.19v-472.57l-403.19 472.57h403.19z"/><path fill="%23fefefe" d="m16236 9012.7c66.1 0 119.69 53.6 119.69 119.7 0 66.11-53.59 119.7-119.69 119.7-66.11 0-119.7-53.59-119.7-119.7 0-66.1 53.59-119.7 119.7-119.7zm0 24.2c52.74 0 95.51 42.77 95.51 95.5 0 52.74-42.77 95.52-95.51 95.52s-95.52-42.78-95.52-95.52c0-52.73 42.78-95.5 95.52-95.5z"/><path fill="%23fefefe" d="m16297 9193.9h-32.6l-19.55-32.41c-1.49-2.45-2.88-4.63-4.24-6.59-1.35-1.93-2.71-3.57-4.07-4.95-1.39-1.37-2.83-2.42-4.32-3.18-1.5-0.71-3.11-1.06-4.85-1.06h-7.65v48.19h-28.38v-125.91h44.96c30.57 0 45.86 11.41 45.86 34.23 0 4.39-0.69 8.44-2.05 12.16-1.34 3.71-3.24 7.08-5.69 10.07-2.45 2.97-5.42 5.55-8.9 7.71-3.5 2.18-7.37 3.86-11.67 5.08v0.36c1.9 0.6 3.7 1.54 5.46 2.86 1.78 1.31 3.46 2.85 5.09 4.62 1.66 1.77 3.22 3.65 4.72 5.66 1.49 2.01 2.85 3.98 4.08 5.93l23.8 37.23zm-77.28-104.66v35.03h12.28c6.1 0 11-1.77 14.67-5.28 3.75-3.56 5.62-8 5.62-13.25 0-11.03-6.59-16.5-19.77-16.5h-12.8z"/></svg>' alt="4me"></a></li>
+ <li><a href="https://www.jetbrains.com/"><img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='39 0 142.7 119'%3E%3ClinearGradient id='SVGID_1_' gradientUnits='userSpaceOnUse' x1='4.7875' y1='6.8451' x2='75.7999' y2='54.4038'%3E%3Cstop offset='0' stop-color='%23AA4A9B'/%3E%3Cstop offset='1' stop-color='%23F05922'/%3E%3C/linearGradient%3E%3Cpath fill='url(%23SVGID_1_)' d='M81.3,57.6L18.7,3.1c-1.9-1.8-4.5-3-7.3-3.1C5.2-0.2,0.2,4.6,0,10.7c-0.1,4.3,2.3,8.1,5.8,10l70.4,43.7c0.1,0.1,0.2,0.1,0.3,0.2c2.1,1.1,4.6,0.4,5.8-1.6C83.4,61.2,82.9,58.9,81.3,57.6z'/%3E%3ClinearGradient id='SVGID_2_' gradientUnits='userSpaceOnUse' x1='28.3538' y1='119.6551' x2='139.5938' y2='60.2551'%3E%3Cstop offset='0' stop-color='%23FFE42E'/%3E%3Cstop offset='1' stop-color='%23ED417C'/%3E%3C/linearGradient%3E%3Cpath fill='url(%23SVGID_2_)' d='M142.7,66.3c-0.3-8.6-7.6-15.3-16.2-14.9c-2.7,0.1-5.3,0.9-7.5,2.2l-88,50.1c0,0-0.1,0-0.1,0.1c-3,1.2-5,4.2-4.9,7.6c0.2,4.4,3.8,7.8,8.2,7.6c1,0,2-0.3,2.9-0.7l95.9-37c0,0,0.1,0,0.2-0.1C138.9,78.8,142.9,73,142.7,66.3z'/%3E%3ClinearGradient id='SVGID_3_' gradientUnits='userSpaceOnUse' x1='31.6974' y1='114.3816' x2='72.0174' y2='55.3416'%3E%3Cstop offset='0' stop-color='%23FFE42E'/%3E%3Cstop offset='1' stop-color='%23F05922'/%3E%3C/linearGradient%3E%3Cpath fill='url(%23SVGID_3_)' d='M71.8,64c1.1-2.1,0.3-4.7-1.8-5.7c-1.9-1-4.2-0.4-5.4,1.3l-37.1,47.1c0,0,0,0.1-0.1,0.2c-1.8,2.7-1.8,6.3,0.3,9c2.6,3.5,7.5,4.2,11,1.7c1-0.8,1.8-1.8,2.4-2.8l30.5-50.2C71.6,64.3,71.7,64.1,71.8,64z'/%3E%3Crect x='45.5' y='35.7' width='51' height='51'/%3E%3Crect x='49.9' y='77.1' fill='%23fff' width='19.1' height='3.2'/%3E%3Cpath fill='%23fff' d='M49.7,49.1l1.5-1.4c0.4,0.5,0.8,0.8,1.3,0.8c0.6,0,0.9-0.4,0.9-1.2V42h2.3v5.3c0,1-0.3,1.8-0.8,2.3c-0.5,0.5-1.3,0.8-2.3,0.8C51.2,50.5,50.3,49.9,49.7,49.1z'/%3E%3Cpath fill='%23fff' d='M56.3,42h6.7V44h-4.4v1.3h4v1.8h-4v1.3H63v2h-6.7V42z'/%3E%3Cpath fill='%23fff' d='M66,44.1h-2.5v-2h7.3v2h-2.5v6.3H66V44.1z'/%3E%3Cpath fill='%23fff' d='M49.9,52.3h4.3c1,0,1.8,0.3,2.3,0.7c0.3,0.3,0.5,0.8,0.5,1.4v0c0,1-0.5,1.5-1.3,1.9c1,0.3,1.7,0.9,1.7,2v0c0,1.4-1.2,2.3-3.1,2.3h-4.3V52.3z M54.7,54.9c0-0.5-0.4-0.7-1-0.7h-1.5v1.5h1.4C54.3,55.6,54.7,55.4,54.7,54.9L54.7,54.9z M53.9,57.2h-1.8v1.5h1.8c0.7,0,1.1-0.3,1.1-0.8v0C55,57.5,54.7,57.2,53.9,57.2z'/%3E%3Cpath fill='%23fff' d='M57.7,52.3h3.9c1.3,0,2.2,0.3,2.7,0.9c0.5,0.5,0.7,1.1,0.7,1.9v0c0,1.3-0.7,2.1-1.7,2.6l2,2.9h-2.6L61,58.1h-1v2.5h-2.3V52.3z M61.5,56.3c0.8,0,1.2-0.4,1.2-1v0c0-0.7-0.5-1-1.2-1H60v2H61.5z'/%3E%3Cpath fill='%23fff' d='M67.8,52.2H70l3.5,8.4h-2.5l-0.6-1.5h-3.2l-0.6,1.5h-2.4L67.8,52.2z M69.8,57.3L68.9,55l-0.9,2.4H69.8z'/%3E%3Cpath fill='%23fff' d='M73.8,52.3h2.3v8.3h-2.3V52.3z'/%3E%3Cpath fill='%23fff' d='M76.7,52.3h2.2l3.4,4.4v-4.4h2.3v8.3h-2L79,56.1v4.6h-2.3V52.3z'/%3E%3Cpath fill='%23fff' d='M84.7,59.4l1.3-1.5c0.8,0.7,1.7,1,2.7,1c0.6,0,1-0.2,1-0.6v0c0-0.4-0.3-0.5-1.4-0.8c-1.8-0.4-3.1-0.9-3.1-2.6v0c0-1.5,1.2-2.7,3.2-2.7c1.4,0,2.5,0.4,3.4,1.1l-1.2,1.6c-0.8-0.5-1.6-0.8-2.3-0.8c-0.6,0-0.8,0.2-0.8,0.5v0c0,0.4,0.3,0.5,1.4,0.8c1.9,0.4,3.1,1,3.1,2.6v0c0,1.7-1.3,2.7-3.4,2.7C87.1,60.8,85.7,60.3,84.7,59.4z'/%3E%3C/svg%3E%0A" alt="JetBrains"></a>
+ <li><a href="https://www.desmos.com/"><img src='data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 107.05 22.17" fill="%23187a3d"%3E%3Cpath d="M89.91 7.50c-1.62-1.67-3.64-2.53-5.98-2.53-2.34 0-4.36.85-5.99 2.53s-2.45 3.73-2.45 6.1a8.4 8.4 0 0 0 2.43 6.02 8.13 8.13 0 0 0 6.02 2.51c2.37 0 4.4-.85 6-2.51 1.6-1.68 2.43-3.7 2.43-6.05a8.41 8.41 0 0 0-2.46-6.07m-5.98.41c1.47 0 2.72.56 3.81 1.68a5.6 5.6 0 0 1 1.61 4.01c0 1.58-.52 2.88-1.6 3.98-1.06 1.1-2.32 1.63-3.87 1.63-1.53 0-2.8-.53-3.82-1.61-1.05-1.1-1.56-2.4-1.56-3.97 0-1.58.53-2.90 1.61-4.05 1.07-1.13 2.32-1.68 3.80-1.68M15.25 0a1.47 1.47 0 0 0-1.44 1.25l-.00 5.78c-1.27-1.12-2.75-1.8-4.42-1.97h-.04c-.10-.01-.22-.01-.32-.03l-.33-.03a10.1 10.1 0 0 0-.76.01l-.06.01c-.11 0-.23.01-.34.02l-.43.04-.09.02-.28.04c-.14.01-.26.06-.41.08a7.94 7.94 0 0 0-3.55 1.98l-.04.02-.37.4-.18.21a7.34 7.34 0 0 0-.52.65 1.78 1.78 0 0 0-.15.21l-.04.06C.46 10.17 0 11.79 0 13.55l.00.44.07.78.05.33.07.33.05.26c.36 1.41 1.08 2.7 2.15 3.80a8.59 8.59 0 0 0 1.38 1.17l.23.15c.03.02.06.03.09.05l.03.01c.19.12.4.22.57.32l.38.17c.99.41 2.09.62 3.26.62h.04l.39-.01a1.36 1.36 0 0 0 .19-.01h.05l.18-.01c.04-.01.09-.01.12-.01a7.86 7.86 0 0 0 4.42-1.93v.67l.00.07a1.47 1.47 0 0 0 1.26 1.24h.38c.73-.1 1.27-.73 1.27-1.46V1.47c0-.8-.65-1.47-1.46-1.47M13.74 13.59c0 1.57-.51 2.85-1.57 3.94s-2.30 1.62-3.82 1.62a5.39 5.39 0 0 1-1.87-.32c-.02-.00-.04-.00-.05-.01l-.07-.03c-.64-.25-1.26-.67-1.79-1.23a5.46 5.46 0 0 1-1.38-2.58c-.1-.43-.14-.88-.14-1.34 0-1.57.51-2.87 1.58-4.01C5.66 8.48 6.9 7.94 8.36 7.94c1.47 0 2.69.54 3.77 1.67 1.1 1.13 1.60 2.43 1.60 3.97m21.89-.36c0-.2-.02-.43-.03-.65-.13-1.25-.52-2.41-1.15-3.45-.34-.57-.75-1.11-1.25-1.62-1.2-1.24-2.64-2.05-4.26-2.37l-.13-.01c-.11-.03-.24-.04-.35-.06l-.52-.05-.33-.02a11.34 11.34 0 0 0-.82 0c-1.50.07-2.88.50-4.08 1.30a7.49 7.49 0 0 0-.50.36l-.63.54-.32.31a8.49 8.49 0 0 0-2.45 6.10c0 1.1.19 2.17.57 3.14.39 1.03 1.02 2 1.86 2.86l.62.59a9.28 9.28 0 0 0 1.00.74l.72.39a8.75 8.75 0 0 0 1.96.64l.43.07.42.04c.13.01.26.02.40.02l.06.00a4.88 4.88 0 0 0 .37.01h.04l.39-.01.28-.01.12-.01a7.97 7.97 0 0 0 5.15-2.47c.32-.33.61-.68.86-1.04a4.51 4.51 0 0 0 .27-.40l.04-.08a1.45 1.45 0 0 0 .10-.53 1.5 1.5 0 0 0-1.50-1.49c-.5 0-.95.24-1.24.65a5.5 5.5 0 0 1-.71.89c-1.05 1.1-2.32 1.63-3.87 1.63-1.53 0-2.78-.53-3.83-1.61a7.25 7.25 0 0 1-.50-.6l-.05-.09c-.12-.18-.24-.36-.36-.60a5.01 5.01 0 0 1-.50-1.49h12.45l.11-.02c.62-.13 1.1-.65 1.16-1.30v-.04l-.01-.24m-13.64-1.11a5.36 5.36 0 0 1 .68-1.57l.04-.07c.2-.30.43-.58.7-.87 1.07-1.13 2.31-1.68 3.79-1.68s2.73.56 3.81 1.68c.50.53.89 1.11 1.17 1.74a5.44 5.44 0 0 1 .25.76zm51.46-1.14v9.57a1.48 1.48 0 0 1-1.48 1.47c-.75 0-1.39-.55-1.47-1.32v-9.68a3.2 3.2 0 0 0-.91-2.30c-.56-.57-1.19-.9-1.93-.94-.06-.01-.14-.01-.22-.01-.84 0-1.53.31-2.13.95a3.19 3.19 0 0 0-.91 2.14v.13l.00.09-.00.02v9.45a1.47 1.47 0 0 1-1.47 1.47 1.47 1.47 0 0 1-1.48-1.32l-.00-.05.01-9.64c-.01-.07-.01-.12-.01-.17-.02-.46-.41-1.37-.41-1.37s-.30-.53-.50-.74c-.60-.63-1.31-.95-2.15-.95-.83 0-1.52.31-2.13.95a3.2 3.2 0 0 0-.92 2.3v9.73a1.48 1.48 0 0 1-1.47 1.28 1.48 1.48 0 0 1-1.47-1.47V6.33c0-.82.66-1.48 1.47-1.48.60 0 1.14.38 1.37.91l.32-.21a5.89 5.89 0 0 1 2.83-.7c1.5 0 2.82.5 3.92 1.46a3.73 3.73 0 0 1 .34.34l.27.28.26-.28.35-.34a5.76 5.76 0 0 1 3.90-1.46l.50.02c1.3.1 2.45.58 3.42 1.46l.34.33a5.99 5.99 0 0 1 1.74 4.32"/%3E%3Cpath d="M50.32 17.13c0 2.74-2.21 4.98-4.94 5.03h-5.98a1.45 1.45 0 0 1-1.44-1.45c0-.8.64-1.44 1.45-1.44h5.91a2.13 2.13 0 0 0 2.1-2.13 2.13 2.13 0 0 0-2.12-2.12h-2.86c-2.77 0-5.03-2.24-5.03-5.02a5.04 5.04 0 0 1 5.03-5.03h5.91a1.46 1.46 0 0 1 1.45 1.46 1.46 1.46 0 0 1-1.45 1.44h-5.91c-1.17 0-2.12.95-2.12 2.12 0 1.15.94 2.1 2.1 2.12h.05c.01 0 .04 0 .09-.00h2.73c.70 0 1.39.14 2.03.43a5.04 5.04 0 0 1 3 4.59m56.74-.00c0 2.74-2.22 5-4.95 5.03h-5.98a1.46 1.46 0 0 1-1.45-1.45 1.45 1.45 0 0 1 1.45-1.44h5.9c1.15-.01 2.10-.96 2.10-2.13a2.13 2.13 0 0 0-2.12-2.12h-2.63c-.07.01-.14.01-.22.01-2.77 0-5.03-2.24-5.03-5.03a5.04 5.04 0 0 1 5.03-5.03h5.90a1.47 1.47 0 0 1 1.45 1.46c0 .79-.65 1.45-1.45 1.45h-5.90a2.13 2.13 0 0 0-2.13 2.12 2.14 2.14 0 0 0 2.10 2.12h.05c.01 0 .05 0 .08-.00h2.74a4.87 4.87 0 0 1 2.03.43c1.82.8 3 2.61 3 4.59"/%3E%3C/svg%3E%0A' alt=desmos></a></li>
+ <li><a href="https://www.executeprogram.com"><img style="background: #003; margin: 10px 0; padding: 10px 30px 10px 20px" src='data:image/svg+xml,%3Csvg%20width%3D%22397%22%20height%3D%22109%22%20viewBox%3D%220%200%20397%20109%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cg%20fill-rule%3D%22nonzero%22%20fill%3D%22none%22%3E%3Cpath%20d%3D%22M169.495%2063.68c2.8%200%205.254.671%207.36%202.015%202.105%201.344%203.688%203.162%204.751%205.453%201.063%202.292%201.594%204.878%201.594%207.76%200%204.408-1.241%208.054-3.724%2010.935-2.483%202.881-5.81%204.322-9.98%204.322-3.953%200-7.18-1.402-9.683-4.206v12.62c0%20.271-.085.489-.254.653a.88.88%200%200%201-.64.247h-4.767a.966.966%200%200%201-.656-.232c-.178-.155-.268-.377-.268-.668V65.188c0-.271.09-.489.268-.653a.932.932%200%200%201%20.656-.247h4.767a.88.88%200%200%201%20.64.247c.17.164.254.382.254.653v3.393h.625c1.986-3.268%205.006-4.902%209.057-4.902zm-.84%2024.874c2.752%200%204.865-.86%206.34-2.578%201.473-1.719%202.21-4.034%202.21-6.947%200-2.874-.737-5.156-2.21-6.846-1.475-1.69-3.588-2.534-6.34-2.534-2.576%200-4.625.855-6.148%202.563-1.524%201.71-2.285%203.986-2.285%206.831s.761%205.141%202.285%206.89c1.523%201.747%203.572%202.62%206.148%202.62zm39.147-24.875c3.374%200%206.111.99%208.213%202.968%202.1%201.978%203.151%204.771%203.151%208.379%200%20.582-.296.902-.888.96l-4.705.64c-.592.097-.917-.165-.977-.786-.138-2.114-.813-3.67-2.027-4.67-1.213-.998-2.836-1.497-4.868-1.497-1.44%200-2.757.266-3.95.8-1.194.533-2.142%201.183-2.842%201.949-.7.766-1.238%201.513-1.613%202.24-.375.727-.562%201.333-.562%201.818v16.147c0%20.271-.084.49-.252.654a.87.87%200%200%201-.636.248h-4.735a.954.954%200%200%201-.651-.233c-.178-.155-.267-.378-.267-.669V65.221c0-.271.09-.49.267-.654a.922.922%200%200%201%20.65-.248h4.47c.552%200%20.858.3.917.902l.237%203.928h.68c1.086-1.571%202.52-2.876%204.306-3.913%201.786-1.038%203.813-1.557%206.082-1.557zm31.331%2030.845c-4.25%200-7.807-1.475-10.673-4.423-2.866-2.95-4.298-6.616-4.298-11s1.432-8.05%204.298-10.999c2.866-2.948%206.423-4.423%2010.673-4.423%202.788%200%205.332.674%207.632%202.021%202.3%201.348%204.103%203.203%205.41%205.566%201.306%202.363%201.959%204.975%201.959%207.835%200%202.861-.653%205.468-1.96%207.821-1.306%202.353-3.109%204.209-5.41%205.566-2.3%201.357-4.843%202.036-7.63%202.036zm-6.43-8.608c1.7%201.759%203.847%202.638%206.445%202.638%202.597%200%204.745-.88%206.444-2.638%201.698-1.759%202.547-4.03%202.547-6.814%200-2.785-.849-5.057-2.547-6.815-1.699-1.759-3.847-2.638-6.444-2.638-2.598%200-4.746.88-6.444%202.638-1.699%201.758-2.548%204.03-2.548%206.815%200%202.784.85%205.055%202.548%206.814zm55.522-21.623c.272%200%20.487.082.642.248.156.165.234.384.234.657v27.976c0%201.772-.302%203.373-.906%204.804-.603%201.431-1.402%202.6-2.395%203.504-.993.906-2.157%201.67-3.49%202.293a16.713%2016.713%200%200%201-4.076%201.314c-1.383.253-2.814.38-4.294.38-2.337%200-4.543-.297-6.617-.891-2.074-.594-3.86-1.397-5.36-2.41-.448-.291-.546-.7-.293-1.226l1.49-2.774c.273-.526.672-.652%201.198-.38%202.707%201.46%205.735%202.19%209.085%202.19%201.169%200%202.293-.116%203.374-.35%201.074-.23%202.107-.62%203.068-1.153a6.016%206.016%200%200%200%202.293-2.235c.564-.953.847-2.073.847-3.358v-3.855c-2.513%203.154-5.726%204.731-9.64%204.731-2.688%200-5.132-.676-7.333-2.03a13.905%2013.905%200%200%201-5.112-5.475c-1.207-2.297-1.811-4.809-1.811-7.534%200-2.726.604-5.237%201.811-7.534%201.208-2.298%202.907-4.123%205.098-5.476%202.19-1.353%204.64-2.03%207.347-2.03%203.856%200%207.03%201.548%209.523%204.644l.175-3.125c.059-.604.36-.905.906-.905h4.236zm-13.596%2023.266c2.408%200%204.424-.894%206.045-2.68%201.622-1.788%202.433-3.898%202.433-6.332%200-2.396-.811-4.477-2.433-6.246-1.621-1.768-3.637-2.652-6.045-2.652-2.428%200-4.452.86-6.074%202.581-1.622%201.72-2.433%203.826-2.433%206.317%200%202.529.811%204.663%202.433%206.402%201.621%201.74%203.646%202.61%206.074%202.61zm40.073-23.88c3.374%200%206.111.99%208.213%202.968%202.1%201.978%203.151%204.771%203.151%208.379%200%20.582-.296.902-.888.96l-4.705.64c-.592.097-.917-.165-.977-.786-.138-2.114-.813-3.67-2.027-4.67-1.213-.998-2.836-1.497-4.868-1.497-1.44%200-2.757.266-3.95.8-1.194.533-2.142%201.183-2.842%201.949-.7.766-1.238%201.513-1.613%202.24-.375.727-.562%201.333-.562%201.818v16.147c0%20.271-.084.49-.252.654a.87.87%200%200%201-.636.248h-4.735a.954.954%200%200%201-.651-.233c-.178-.155-.267-.378-.267-.669V65.221c0-.271.09-.49.267-.654a.922.922%200%200%201%20.65-.248h4.47c.552%200%20.858.3.917.902l.237%203.928h.68c1.086-1.571%202.52-2.876%204.306-3.913%201.786-1.038%203.813-1.557%206.082-1.557zm46.24%2024.74c.393.098.673.22.84.367.167.147.25.377.25.69v3.551c0%20.626-.569.959-1.708.998-2.2.039-3.826-.343-4.877-1.145-1.051-.802-1.577-2.064-1.577-3.785h-.265c-1.493%201.682-3.399%203.008-5.717%203.976-2.318.968-4.577%201.453-6.778%201.453-3.241%200-5.726-.749-7.455-2.245-1.729-1.497-2.593-3.547-2.593-6.149%200-2.621.835-4.656%202.504-6.104%201.67-1.448%204.214-2.416%207.633-2.906l6.984-1.085c1.355-.196%202.347-.401%202.976-.617.629-.215%201.041-.479%201.238-.792-.079-1.957-.649-3.35-1.71-4.182-1.06-.832-2.622-1.247-4.685-1.247-4.302%200-6.65%201.36-7.043%204.079-.059.45-.353.665-.884.646h-4.48c-.647%200-.942-.304-.883-.91.334-3.326%201.66-5.713%203.978-7.161%202.318-1.448%205.452-2.172%209.4-2.172%204.224%200%207.392.959%209.504%202.876%202.112%201.918%203.168%204.706%203.168%208.364v11.035c-.02%201.35.707%202.172%202.18%202.466zm-19.06.135c4.132%200%207.518-1.307%2010.16-3.922v-6.028c-.258.566-1.53%201.024-3.814%201.375l-6.375.995c-1.728.274-2.96.742-3.695%201.405-.735.663-1.102%201.512-1.102%202.546%200%201.132.397%202.02%201.192%202.663.794.644%202.006.966%203.635.966zm48.252-24.875c2.377%200%204.116.796%205.216%202.386%201.1%201.59%201.65%204.248%201.65%207.971v18.59c0%20.272-.079.49-.236.655-.157.165-.383.248-.677.248h-4.244a.948.948%200%200%201-.648-.233c-.177-.155-.265-.378-.265-.669v-18.59c0-1.785-.207-3.036-.62-3.754-.412-.717-1.11-1.076-2.091-1.076-1.042%200-1.886.403-2.535%201.207a5.452%205.452%200%200%200-1.178%202.75v19.463c0%20.271-.079.49-.236.654-.157.165-.383.248-.678.248h-4.155c-.275%200-.496-.078-.663-.233-.167-.155-.25-.378-.25-.669v-18.59c0-1.804-.207-3.06-.62-3.768-.412-.708-1.11-1.062-2.092-1.062-1.04%200-1.88.398-2.52%201.193a5.675%205.675%200%200%200-1.193%202.764v19.463c0%20.271-.083.49-.25.654a.864.864%200%200%201-.634.248h-4.273c-.275%200-.496-.078-.662-.233-.168-.155-.251-.378-.251-.669V65.221c0-.271.083-.49.25-.654.167-.165.388-.248.663-.248h4.008c.57%200%20.874.3.914.902l.147%202.386h.442c.943-2.619%202.898-3.928%205.864-3.928%202.849%200%204.745%201.31%205.688%203.928h.353c1.061-2.619%202.986-3.928%205.776-3.928zM162.091%2016.126c1.86-.801%203.86-1.201%206.001-1.201%202.141%200%204.112.395%205.914%201.186%201.802.791%203.293%201.86%204.475%203.208%201.182%201.347%202.097%202.905%202.746%204.672.65%201.767.974%203.637.974%205.609%200%201.191-.121%202.04-.363%202.549-.243.507-.76.761-1.555.761h-20.807c.33%202.285%201.385%204.106%203.168%205.463%201.782%201.357%204.01%202.036%206.683%202.036%202.693%200%205.134-.84%207.324-2.52.464-.35.881-.341%201.249.03l1.947%201.992c.465.469.465.918%200%201.347-2.983%203.008-6.713%204.511-11.188%204.511-4.572%200-8.287-1.47-11.144-4.408-2.858-2.94-4.287-6.615-4.287-11.029%200-2.148.373-4.164%201.119-6.048.746-1.885%201.763-3.516%203.051-4.892%201.288-1.377%202.853-2.466%204.694-3.266zm5.71%203.774c-2.28%200-4.202.718-5.767%202.154-1.565%201.437-2.502%203.372-2.812%205.806h16.985c-.232-2.414-1.111-4.344-2.638-5.79-1.526-1.447-3.449-2.17-5.767-2.17zm51.123%2022.816c.236.268.3.513.191.733-.107.22-.348.33-.72.33h-5.562c-.47%200-.824-.162-1.06-.488l-8.592-10.002-8.592%2010.002c-.255.326-.618.488-1.089.488h-5.532c-.373%200-.613-.11-.72-.33-.109-.22-.045-.465.19-.733l12.036-13.795-11.212-12.933c-.235-.268-.299-.512-.191-.733.108-.22.348-.33.72-.33h5.504c.47%200%20.833.172%201.088.517l7.798%209.082%207.798-9.082c.255-.325.618-.498%201.089-.517h5.473c.373%200%20.618.105.736.316.117.21.059.46-.177.747l-11.152%2012.933%2011.976%2013.795zm14.101-26.59c1.86-.801%203.86-1.201%206-1.201%202.142%200%204.113.395%205.915%201.186%201.801.791%203.293%201.86%204.475%203.208%201.182%201.347%202.097%202.905%202.746%204.672.65%201.767.974%203.637.974%205.609%200%201.191-.122%202.04-.364%202.549-.242.507-.76.761-1.554.761H230.41c.329%202.285%201.385%204.106%203.167%205.463%201.782%201.357%204.01%202.036%206.684%202.036%202.693%200%205.134-.84%207.323-2.52.465-.35.882-.341%201.25.03l1.947%201.992c.465.469.465.918%200%201.347-2.984%203.008-6.713%204.511-11.189%204.511-4.572%200-8.286-1.47-11.144-4.408-2.858-2.94-4.286-6.615-4.286-11.029%200-2.148.373-4.164%201.118-6.048.746-1.885%201.764-3.516%203.052-4.892%201.288-1.377%202.852-2.466%204.693-3.266zm5.71%203.774c-2.28%200-4.203.718-5.767%202.154-1.566%201.437-2.503%203.372-2.812%205.806h16.984c-.232-2.414-1.11-4.344-2.637-5.79-1.527-1.447-3.45-2.17-5.768-2.17zm37.83%2019.894c3.133%200%205.619-1.191%207.457-3.574.348-.45.745-.527%201.19-.234l3.394%201.962c.542.332.639.733.29%201.201-1.315%202.012-3.06%203.618-5.237%204.819-2.176%201.2-4.58%201.801-7.21%201.801-4.392%200-8.043-1.474-10.955-4.423-2.911-2.949-4.367-6.615-4.367-10.999s1.456-8.05%204.367-11c2.912-2.948%206.563-4.422%2010.954-4.422%202.631%200%205.04.595%207.225%201.787%202.186%201.19%203.927%202.792%205.224%204.803.328.47.232.87-.29%201.202l-3.396%201.991c-.444.274-.841.196-1.19-.234-1.837-2.382-4.323-3.574-7.457-3.574-2.67%200-4.88.884-6.63%202.651-1.75%201.768-2.626%204.033-2.626%206.796s.875%205.028%202.626%206.796c1.75%201.767%203.96%202.65%206.63%202.65zm46.585-24.87c.276%200%20.499.083.666.248.168.165.252.383.252.654v27.379c0%20.271-.084.49-.252.654-.167.165-.39.247-.666.247h-4.475c-.573%200-.88-.3-.919-.901l-.237-3.953h-.652c-1.007%201.608-2.35%202.93-4.03%203.968-1.68%201.036-3.674%201.554-5.986%201.554-3.26%200-5.867-1.056-7.823-3.168-1.956-2.112-2.934-5.067-2.934-8.864V15.826c0-.271.08-.49.237-.654.159-.165.376-.247.652-.247h4.742c.276%200%20.499.082.666.247.168.165.252.383.252.654v15.956c0%202.403.583%204.18%201.749%205.334%201.165%201.153%202.785%201.73%204.86%201.73%201.343%200%202.573-.258%203.689-.771s1.99-1.129%202.623-1.846c.632-.717%201.116-1.4%201.452-2.049.335-.649.503-1.157.503-1.526V15.826c0-.271.08-.49.237-.654.158-.165.376-.247.652-.247h4.742zm37.595%2024.474c.353.446.382.852.088%201.22-.882%201.047-2.172%202.001-3.868%202.863-1.697.862-3.731%201.293-6.104%201.293-8.002%200-12.003-3.932-12.003-11.799V20.537h-7.884a.885.885%200%200%201-.647-.261.864.864%200%200%201-.264-.64v-3.603c0-.272.083-.49.25-.654.166-.165.387-.247.661-.247h7.884l.02-9.285c0-.271.084-.485.25-.64.167-.155.388-.232.662-.232h4.707c.255%200%20.466.078.633.233.166.154.25.368.25.639l-.02%209.285h11.943c.255%200%20.466.082.632.247.167.164.25.382.25.654v3.603a.89.89%200%200%201-.25.64.837.837%200%200%201-.632.261H345.36v11.741c0%201.337.18%202.465.544%203.386.363.92.873%201.613%201.53%202.077a6.487%206.487%200%200%200%202.059.989c.716.193%201.534.29%202.456.29%201.98%200%203.824-.668%205.53-2.005.452-.426.873-.407%201.265.058l2%202.325zm15.146-23.272c1.86-.801%203.86-1.201%206.001-1.201%202.141%200%204.112.395%205.914%201.186%201.802.791%203.293%201.86%204.475%203.208%201.182%201.347%202.097%202.905%202.746%204.672.65%201.767.974%203.637.974%205.609%200%201.191-.121%202.04-.363%202.549-.243.507-.76.761-1.555.761h-20.807c.33%202.285%201.385%204.106%203.168%205.463%201.782%201.357%204.01%202.036%206.683%202.036%202.693%200%205.134-.84%207.324-2.52.464-.35.881-.341%201.249.03l1.947%201.992c.465.469.465.918%200%201.347-2.983%203.008-6.713%204.511-11.188%204.511-4.572%200-8.287-1.47-11.145-4.408-2.857-2.94-4.286-6.615-4.286-11.029%200-2.148.373-4.164%201.119-6.048.746-1.885%201.763-3.516%203.051-4.892%201.288-1.377%202.853-2.466%204.693-3.266zm5.71%203.774c-2.28%200-4.202.718-5.767%202.154-1.565%201.437-2.502%203.372-2.812%205.806h16.985c-.232-2.414-1.112-4.344-2.638-5.79-1.526-1.447-3.449-2.17-5.768-2.17z%22%20fill%3D%22%23FFF%22%2F%3E%3Cpath%20d%3D%22M102.022%2037.886V19.427c0-2.582-1.455-3.873-4.363-3.873H82.51a1.87%201.87%200%200%201-1.333-.515c-.364-.342-.584-.776-.584-1.3V1.875c0-.565.22-1.019.584-1.361A1.87%201.87%200%200%201%2082.511%200h26.297c1.171%200%202.312.1%203.423.303%201.11.201%202.282.615%203.514%201.24a11.807%2011.807%200%200%201%203.212%202.36c.909.949%201.646%202.23%202.211%203.844.566%201.613.849%203.47.849%205.568v23.421c.04%201.09.262%201.877.666%202.36l12.18%2014.102c.645.767.605%201.594-.122%202.481l-12.058%2013.799c-.444.484-.666%201.271-.666%202.36V95.14c0%202.622-.414%204.852-1.243%206.688-.828%201.835-1.938%203.207-3.332%204.115-1.394.908-2.787%201.553-4.18%201.937-1.394.383-2.879.575-4.454.575H82.51c-.525%200-.97-.162-1.333-.485a1.716%201.716%200%200%201-.584-1.331V94.715c0-.564.22-1.018.584-1.361a1.87%201.87%200%200%201%201.333-.515H97.66c2.908%200%204.363-1.25%204.363-3.752V70.749c0-1.009.242-1.755.727-2.24l13.31-13.952a.217.217%200%200%200%200-.298l-13.31-14.194c-.485-.444-.728-1.17-.728-2.179zm-32.788-8.585L93.083%2053.15a1.523%201.523%200%200%201%200%202.154l-23.85%2023.849a1.523%201.523%200%200%201-2.153%200l-23.85-23.85a1.523%201.523%200%200%201%200-2.153L67.08%2029.3a1.523%201.523%200%200%201%202.154%200zm-35.937%208.585c0%201.009-.243%201.735-.728%202.18L19.26%2054.258a.217.217%200%200%200%200%20.298L32.57%2068.51c.485.484.728%201.23.728%202.24v18.337c0%202.501%201.454%203.752%204.362%203.752h15.148c.525%200%20.97.172%201.333.515.364.343.584.797.584%201.361v11.923c0%20.565-.22%201.009-.584%201.331-.363.323-.808.485-1.333.485H26.511c-1.576%200-3.06-.192-4.454-.575-1.394-.384-2.787-1.03-4.18-1.937-1.394-.908-2.505-2.28-3.333-4.115-.828-1.836-1.242-4.065-1.242-6.688v-23.3c0-1.09-.223-1.877-.667-2.36L.577%2055.678c-.727-.887-.767-1.715-.12-2.481l12.178-14.101c.404-.485.626-1.271.667-2.36V13.314c0-2.099.282-3.955.848-5.568.565-1.614%201.303-2.895%202.211-3.843a11.807%2011.807%200%200%201%203.212-2.36C20.805.917%2021.976.503%2023.087.302A19.123%2019.123%200%200%201%2026.511%200h26.296c.525%200%20.97.171%201.333.515.364.342.584.796.584%201.361v11.862c0%20.525-.22.959-.584%201.301a1.87%201.87%200%200%201-1.333.515H37.66c-2.908%200-4.362%201.291-4.362%203.873v18.459z%22%20fill%3D%22%234547E0%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E' alt="Execute Program"></a></li>
+ <li><a href="https://cargo.site"><img alt=Cargo style="max-height: 120px" src='data:image/svg+xml;utf8,<svg width="3311" height="1605" viewBox="400 0 3311 1605" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M1133 1602C1182 1602 1191 1602 1189 1579C1153 1301 1125 1076 1098 855L1098 855C1067 601 1037 354 995 41C991 2 973 0 916 0C865 0 854 2 849 34C824 242 798 437 772 636L772 636L772 636L772 636L772 636C734 928 695 1227 653 1581C651 1602 681 1602 715 1602C721 1602 726 1602 732 1602C791 1602 809 1602 811 1579C822 1446 833 1334 847 1206C849 1185 868 1185 905 1186C908 1186 912 1186 916 1186C919 1186 922 1186 925 1186C957 1185 984 1185 986 1206C996 1272 1004 1335 1013 1399L1013 1399C1020 1456 1028 1514 1036 1574C1040 1602 1050 1602 1097 1602C1103 1602 1110 1602 1118 1602C1124 1602 1128 1602 1133 1602ZM264 1602C451 1602 528 1478 528 1334V1195C528 1175 509 1176 470 1176L470 1176C463 1176 455 1177 446 1177C405 1177 376 1177 376 1195V1330C376 1391 342 1448 264 1448C180 1448 148 1387 148 1323V265C148 212 193 143 264 143C332 143 376 217 376 267V374C376 400 403 400 443 399H443H443H443H443H443C447 399 450 399 453 399C494 399 528 397 528 374V271C528 173 453 2 264 2C86 2 0 148 0 271V1336C0 1458 86 1602 264 1602ZM968 1042C959 928 953 837 946 746C942 681 937 615 931 539C931 530 929 514 916 514C904 514 902 530 902 537C896 625 890 707 885 784L885 784C879 874 874 958 868 1039C865 1055 886 1060 918 1060C945 1060 970 1060 968 1042ZM1784 1602C1845 1602 1861 1602 1861 1565V996C1861 992 1861 988 1861 984C1861 936 1861 903 1836 852C1812 804 1767 783 1743 771C1733 766 1727 763 1727 761C1727 758 1734 754 1744 748C1768 736 1810 713 1834 669C1859 623 1859 586 1859 537V537C1859 533 1859 529 1859 525V319C1859 239 1843 146 1775 82C1706 20 1608 2 1535 2H1405C1401 2 1397 1 1393 1C1379 0 1367 -0 1353 11C1339 25 1337 50 1337 73V1570C1337 1602 1353 1602 1405 1602C1474 1602 1483 1602 1483 1565V873C1483 838 1495 838 1586 838H1586H1586L1586 838C1591 838 1597 838 1604 838C1654 838 1715 895 1715 989V1570C1715 1602 1729 1602 1774 1602C1777 1602 1780 1602 1784 1602ZM1711 537V319C1711 267 1702 228 1663 187C1638 164 1624 153 1542 153C1521 153 1501 153 1492 169C1485 182 1485 194 1485 207V635C1485 639 1485 643 1485 648V648V648V648C1484 668 1483 687 1499 699C1510 709 1524 708 1535 708C1536 708 1538 708 1540 708C1565 708 1624 701 1665 658C1711 607 1711 569 1711 537ZM2588 1557L2588 1557C2588 1555 2588 1553 2588 1551V790C2588 788 2589 784 2589 781C2591 773 2592 764 2586 763C2569 760 2496 762 2429 763C2393 764 2359 765 2337 765C2321 765 2319 786 2319 836C2319 884 2321 902 2339 902C2345 902 2352 902 2360 901C2384 900 2414 898 2426 907C2436 915 2436 926 2435 936L2435 936C2435 937 2435 938 2435 938C2435 939 2435 940 2435 941V1334C2435 1382 2412 1453 2323 1453C2232 1453 2207 1384 2207 1327V265C2207 217 2253 143 2323 143C2392 143 2435 217 2435 267C2435 283 2436 303 2436 323C2437 343 2437 363 2437 379C2437 399 2451 402 2508 402C2570 402 2588 395 2588 374V271C2588 189 2524 2 2323 2C2118 2 2059 182 2059 271V1336C2059 1442 2130 1602 2323 1602C2393 1602 2429 1567 2452 1545C2466 1531 2476 1522 2485 1528C2503 1540 2508 1560 2512 1576C2516 1589 2518 1599 2526 1599C2534 1599 2541 1601 2547 1602C2559 1605 2569 1607 2577 1599C2589 1587 2588 1572 2588 1557ZM3310 1316C3310 1464 3249 1602 3046 1602C2856 1602 2781 1464 2781 1316V281C2781 109 2897 2 3046 2C3196 2 3310 121 3310 281V1316ZM3160 281V1309C3160 1373 3137 1448 3046 1448C2943 1448 2929 1375 2929 1309V281C2929 217 2977 143 3046 143C3112 143 3160 217 3160 281Z" fill="black"/></svg>'></a></li>
+ <li><a href="https://primo.af"><img alt=primo src='data:image/svg+xml;utf8,<svg viewBox="0 0 258 66" xmlns="http://www.w3.org/2000/svg"><path d="M17.6 13.8C19.5 11.9 22.7 11.9 24.6 13.8C26.5 15.7 26.6 18.7 24.8 20.7L24.6 20.9L12.0 33.5L35.4 56.8C37.3 58.6 37.4 61.7 35.6 63.6L35.4 63.8C33.6 65.7 30.5 65.8 28.6 64.0L28.4 63.8L1.4 37.1C-0.4 35.2 -0.4 32.1 1.2 30.2L1.4 30.0L17.6 13.8Z" fill="url(%23paint0_linear)"></path><path d="M50.0 11C62.4 11 72.5 21.0 72.5 33.5C72.5 46.0 62.4 56.1 50.0 56.1C47.2 56.1 45.0 53.8 45.0 51.1C45.0 48.3 47.2 46.1 50.0 46.1C56.9 46.1 62.5 40.4 62.5 33.5C62.5 26.6 56.9 21 50.0 21C43.2 21 37.6 26.4 37.4 33.3L37.4 33.6L36.9 60.4C36.8 63.2 34.6 65.4 31.8 65.3C29.1 65.2 27.0 63.1 26.9 60.4V60.2L27.4 33.5C27.4 21.0 37.5 11 50.0 11Z" fill="%23EE4645"></path><path d="M75.3 13.8C77.2 11.9 80.3 11.9 82.2 13.6L82.4 13.8L98.6 30.0C100.4 31.9 100.5 34.9 98.7 36.9L98.6 37.0L82.4 53.2C80.4 55.1 77.3 55.1 75.3 53.2C73.4 51.3 73.4 48.3 75.2 46.3L75.3 46.1L87.9 33.5L75.3 20.9C73.4 19.0 73.4 16.0 75.2 14.0L75.3 13.8Z" fill="%23EE4645"></path><path d="M134.5 19.4C136.8 19.4 138.8 19.9 140.6 21.0C142.5 22.0 143.9 23.4 145.0 25.3C146.0 27.2 146.6 29.4 146.6 31.8C146.6 34.3 146.0 36.5 145.0 38.4C143.9 40.3 142.5 41.7 140.6 42.8C138.8 43.8 136.8 44.3 134.5 44.3C131.4 44.3 129.0 43.3 127.2 41.4V52.7H120.2V19.7H126.9V22.5C128.6 20.4 131.2 19.4 134.5 19.4ZM133.3 38.6C135.1 38.6 136.6 38 137.7 36.8C138.9 35.5 139.5 33.9 139.5 31.8C139.5 29.8 138.9 28.2 137.7 27.0C136.6 25.8 135.1 25.1 133.3 25.1C131.5 25.1 130.0 25.8 128.8 27.0C127.7 28.2 127.1 29.8 127.1 31.8C127.1 33.9 127.7 35.5 128.8 36.8C130.0 38 131.5 38.6 133.3 38.6ZM158.0 22.9C158.8 21.8 159.9 20.9 161.3 20.3C162.8 19.7 164.4 19.4 166.3 19.4V25.9C165.5 25.8 165.0 25.8 164.7 25.8C162.7 25.8 161.1 26.3 160.0 27.5C158.8 28.6 158.3 30.3 158.3 32.5V44H151.3V19.7H158.0V22.9ZM170.5 19.7H177.5V44H170.5V19.7ZM174.0 16.4C172.7 16.4 171.6 16.0 170.8 15.2C170.0 14.5 169.6 13.6 169.6 12.5C169.6 11.3 170.0 10.4 170.8 9.7C171.6 8.9 172.7 8.5 174.0 8.5C175.3 8.5 176.3 8.9 177.1 9.6C177.9 10.3 178.3 11.2 178.3 12.3C178.3 13.5 177.9 14.5 177.1 15.2C176.3 16.0 175.3 16.4 174.0 16.4ZM215.0 19.4C218.0 19.4 220.4 20.3 222.2 22.1C224.0 23.9 224.9 26.5 224.9 30.1V44H217.9V31.2C217.9 29.3 217.5 27.8 216.7 26.9C215.9 25.9 214.8 25.5 213.3 25.5C211.6 25.5 210.3 26.0 209.4 27.1C208.4 28.1 207.9 29.7 207.9 31.8V44H200.9V31.2C200.9 27.4 199.4 25.5 196.3 25.5C194.7 25.5 193.4 26.0 192.5 27.1C191.5 28.1 191.0 29.7 191.0 31.8V44H184.0V19.7H190.7V22.5C191.6 21.5 192.7 20.7 194.0 20.2C195.3 19.7 196.7 19.4 198.3 19.4C200.0 19.4 201.6 19.7 202.9 20.4C204.3 21.1 205.4 22.1 206.3 23.3C207.3 22.1 208.5 21.1 210.0 20.4C211.5 19.7 213.2 19.4 215.0 19.4ZM243.0 44.3C240.4 44.3 238.1 43.8 236.1 42.7C234.1 41.7 232.5 40.2 231.4 38.3C230.2 36.4 229.7 34.2 229.7 31.8C229.7 29.4 230.2 27.3 231.4 25.4C232.5 23.5 234.1 22.1 236.1 21.0C238.1 19.9 240.4 19.4 243.0 19.4C245.5 19.4 247.8 19.9 249.8 21.0C251.8 22.1 253.4 23.5 254.5 25.4C255.7 27.3 256.3 29.4 256.3 31.8C256.3 34.2 255.7 36.4 254.5 38.3C253.4 40.2 251.8 41.7 249.8 42.7C247.8 43.8 245.5 44.3 243.0 44.3ZM243.0 38.6C244.8 38.6 246.3 38 247.4 36.8C248.6 35.5 249.1 33.9 249.1 31.8C249.1 29.8 248.6 28.2 247.4 27.0C246.3 25.8 244.8 25.1 243.0 25.1C241.2 25.1 239.7 25.8 238.5 27.0C237.4 28.2 236.8 29.8 236.8 31.8C236.8 33.9 237.4 35.5 238.5 36.8C239.7 38 241.2 38.6 243.0 38.6Z" fill="%23343434"></path><path d="M140.6 21.0L140.4 21.4L140.4 21.4L140.6 21.0ZM145.0 25.3L144.5 25.6L144.6 25.6L145.0 25.3ZM145.0 38.4L145.4 38.7L145.4 38.7L145.0 38.4ZM140.6 42.8L140.9 43.2L140.9 43.2L140.6 42.8ZM127.2 41.4L127.6 41.0L126.7 40.1V41.4H127.2ZM127.2 52.7V53.2H127.7V52.7H127.2ZM120.2 52.7H119.7V53.2H120.2V52.7ZM120.2 19.7V19.2H119.7V19.7H120.2ZM126.9 19.7H127.4V19.2H126.9V19.7ZM126.9 22.5H126.4V23.9L127.3 22.8L126.9 22.5ZM137.7 36.8L137.3 36.4L137.3 36.4L137.7 36.8ZM137.7 27.0L137.3 27.3L137.3 27.3L137.7 27.0ZM128.8 27.0L128.5 26.6L128.5 26.6L128.8 27.0ZM128.8 36.8L128.5 37.1L128.5 37.1L128.8 36.8ZM134.5 19.9C136.7 19.9 138.6 20.4 140.4 21.4L140.9 20.5C139.0 19.4 136.8 18.9 134.5 18.9V19.9ZM140.4 21.4C142.2 22.4 143.5 23.8 144.5 25.6L145.4 25.1C144.3 23.1 142.8 21.6 140.9 20.5L140.4 21.4ZM144.6 25.6C145.6 27.3 146.1 29.4 146.1 31.8H147.1C147.1 29.3 146.5 27.0 145.4 25.1L144.6 25.6ZM146.1 31.8C146.1 34.3 145.6 36.4 144.5 38.2L145.4 38.7C146.5 36.7 147.1 34.4 147.1 31.8H146.1ZM144.6 38.2C143.5 39.9 142.2 41.3 140.4 42.3L140.9 43.2C142.8 42.1 144.3 40.6 145.4 38.7L144.6 38.2ZM140.4 42.3C138.6 43.3 136.7 43.8 134.5 43.8V44.8C136.8 44.8 139.0 44.3 140.9 43.2L140.4 42.3ZM134.5 43.8C131.5 43.8 129.2 42.9 127.6 41.0L126.8 41.7C128.7 43.8 131.3 44.8 134.5 44.8V43.8ZM126.7 41.4V52.7H127.7V41.4H126.7ZM127.2 52.2H120.2V53.2H127.2V52.2ZM120.7 52.7V19.7H119.7V52.7H120.7ZM120.2 20.2H126.9V19.2H120.2V20.2ZM126.4 19.7V22.5H127.4V19.7H126.4ZM127.3 22.8C128.9 20.9 131.3 19.9 134.5 19.9V18.9C131.1 18.9 128.4 20.0 126.5 22.2L127.3 22.8ZM133.3 39.1C135.2 39.1 136.8 38.4 138.1 37.1L137.3 36.4C136.3 37.5 135.0 38.1 133.3 38.1V39.1ZM138.1 37.1C139.3 35.8 140 34.0 140 31.8H139C139 33.8 138.4 35.3 137.3 36.4L138.1 37.1ZM140 31.8C140 29.7 139.3 27.9 138.1 26.6L137.3 27.3C138.4 28.4 139 29.9 139 31.8H140ZM138.1 26.6C136.8 25.3 135.2 24.6 133.3 24.6V25.6C135.0 25.6 136.3 26.2 137.3 27.3L138.1 26.6ZM133.3 24.6C131.4 24.6 129.7 25.3 128.5 26.6L129.2 27.3C130.3 26.2 131.6 25.6 133.3 25.6V24.6ZM128.5 26.6C127.2 28.0 126.6 29.7 126.6 31.8H127.6C127.6 29.9 128.2 28.4 129.2 27.3L128.5 26.6ZM126.6 31.8C126.6 34.0 127.2 35.7 128.5 37.1L129.2 36.4C128.2 35.3 127.6 33.8 127.6 31.8H126.6ZM128.5 37.1C129.7 38.4 131.4 39.1 133.3 39.1V38.1C131.6 38.1 130.3 37.5 129.2 36.4L128.5 37.1ZM158.0 22.9H157.5V24.5L158.4 23.2L158.0 22.9ZM161.3 20.3L161.1 19.8L161.1 19.8L161.3 20.3ZM166.3 19.4H166.8V18.9H166.3V19.4ZM166.3 25.9L166.3 26.4L166.8 26.4V25.9H166.3ZM160.0 27.5L160.3 27.8L160.3 27.8L160.0 27.5ZM158.3 44V44.5H158.8V44H158.3ZM151.3 44H150.8V44.5H151.3V44ZM151.3 19.7V19.2H150.8V19.7H151.3ZM158.0 19.7H158.5V19.2H158.0V19.7ZM158.4 23.2C159.2 22.1 160.2 21.3 161.5 20.7L161.1 19.8C159.7 20.5 158.5 21.4 157.6 22.6L158.4 23.2ZM161.5 20.7C162.9 20.2 164.5 19.9 166.3 19.9V18.9C164.4 18.9 162.7 19.2 161.1 19.8L161.5 20.7ZM165.8 19.4V25.9H166.8V19.4H165.8ZM166.3 25.4C165.6 25.3 165.0 25.3 164.7 25.3V26.3C165.0 26.3 165.5 26.3 166.3 26.4L166.3 25.4ZM164.7 25.3C162.6 25.3 160.9 25.9 159.6 27.1L160.3 27.8C161.4 26.8 162.8 26.3 164.7 26.3V25.3ZM159.6 27.1C158.4 28.4 157.8 30.2 157.8 32.5H158.8C158.8 30.3 159.3 28.8 160.3 27.8L159.6 27.1ZM157.8 32.5V44H158.8V32.5H157.8ZM158.3 43.5H151.3V44.5H158.3V43.5ZM151.8 44V19.7H150.8V44H151.8ZM151.3 20.2H158.0V19.2H151.3V20.2ZM157.5 19.7V22.9H158.5V19.7H157.5ZM170.5 19.7V19.2H170.0V19.7H170.5ZM177.5 19.7H178.0V19.2H177.5V19.7ZM177.5 44V44.5H178.0V44H177.5ZM170.5 44H170.0V44.5H170.5V44ZM170.8 15.2L170.5 15.6V15.6L170.8 15.2ZM170.8 9.7L171.2 10.0V10.0L170.8 9.7ZM177.1 9.6L176.8 10.0L177.1 9.6ZM177.1 15.2L177.5 15.6L177.5 15.6L177.1 15.2ZM170.5 20.2H177.5V19.2H170.5V20.2ZM177.0 19.7V44H178.0V19.7H177.0ZM177.5 43.5H170.5V44.5H177.5V43.5ZM171.0 44V19.7H170.0V44H171.0ZM174.0 15.9C172.8 15.9 171.9 15.5 171.2 14.9L170.5 15.6C171.4 16.5 172.6 16.9 174.0 16.9V15.9ZM171.2 14.9C170.5 14.2 170.1 13.4 170.1 12.5H169.1C169.1 13.7 169.6 14.8 170.5 15.6L171.2 14.9ZM170.1 12.5C170.1 11.5 170.5 10.7 171.2 10.0L170.5 9.3C169.6 10.1 169.1 11.2 169.1 12.5H170.1ZM171.2 10.0C171.9 9.4 172.8 9.0 174.0 9.0V8.0C172.6 8.0 171.4 8.4 170.5 9.3L171.2 10.0ZM174.0 9.0C175.2 9.0 176.1 9.4 176.8 10.0L177.5 9.2C176.5 8.4 175.4 8.0 174.0 8.0V9.0ZM176.8 10.0C177.5 10.6 177.8 11.4 177.8 12.3H178.8C178.8 11.1 178.4 10.1 177.5 9.2L176.8 10.0ZM177.8 12.3C177.8 13.4 177.5 14.2 176.8 14.9L177.5 15.6C178.4 14.7 178.8 13.6 178.8 12.3H177.8ZM176.8 14.9C176.1 15.5 175.2 15.9 174.0 15.9V16.9C175.4 16.9 176.5 16.5 177.5 15.6L176.8 14.9ZM222.2 22.1L221.8 22.4L221.9 22.4L222.2 22.1ZM224.9 44V44.5H225.4V44H224.9ZM217.9 44H217.4V44.5H217.9V44ZM216.7 26.9L216.3 27.2L216.3 27.2L216.3 27.2L216.7 26.9ZM209.4 27.1L209.7 27.4L209.8 27.4L209.4 27.1ZM207.9 44V44.5H208.4V44H207.9ZM200.9 44H200.4V44.5H200.9V44ZM192.5 27.1L192.8 27.4L192.8 27.4L192.5 27.1ZM191.0 44V44.5H191.5V44H191.0ZM184.0 44H183.5V44.5H184.0V44ZM184.0 19.7V19.2H183.5V19.7H184.0ZM190.7 19.7H191.2V19.2H190.7V19.7ZM190.7 22.5H190.2V23.9L191.1 22.9L190.7 22.5ZM194.0 20.2L193.8 19.7L193.8 19.7L194.0 20.2ZM202.9 20.4L202.7 20.9L202.7 20.9L202.9 20.4ZM206.3 23.3L205.9 23.6L206.2 24.2L206.7 23.6L206.3 23.3ZM210.0 20.4L209.8 20.0L209.8 20.0L210.0 20.4ZM215.0 19.9C217.9 19.9 220.2 20.7 221.8 22.4L222.6 21.7C220.7 19.8 218.1 18.9 215.0 18.9V19.9ZM221.9 22.4C223.5 24.1 224.4 26.6 224.4 30.1H225.4C225.4 26.4 224.5 23.6 222.6 21.7L221.9 22.4ZM224.4 30.1V44H225.4V30.1H224.4ZM224.9 43.5H217.9V44.5H224.9V43.5ZM218.4 44V31.2H217.4V44H218.4ZM218.4 31.2C218.4 29.2 218.0 27.6 217.0 26.6L216.3 27.2C217.0 28.0 217.4 29.3 217.4 31.2H218.4ZM217.1 26.6C216.2 25.5 214.9 25.0 213.3 25.0V26.0C214.6 26.0 215.6 26.4 216.3 27.2L217.1 26.6ZM213.3 25.0C211.5 25.0 210.1 25.5 209.0 26.7L209.8 27.4C210.6 26.4 211.8 26.0 213.3 26.0V25.0ZM209.0 26.7C207.9 27.9 207.4 29.6 207.4 31.8H208.4C208.4 29.8 208.9 28.3 209.7 27.4L209.0 26.7ZM207.4 31.8V44H208.4V31.8H207.4ZM207.9 43.5H200.9V44.5H207.9V43.5ZM201.4 44V31.2H200.4V44H201.4ZM201.4 31.2C201.4 29.2 201.0 27.6 200.2 26.6C199.3 25.5 198.0 25.0 196.3 25.0V26.0C197.7 26.0 198.7 26.4 199.4 27.2C200.0 28.0 200.4 29.3 200.4 31.2H201.4ZM196.3 25.0C194.6 25.0 193.2 25.5 192.1 26.7L192.8 27.4C193.7 26.4 194.8 26.0 196.3 26.0V25.0ZM192.1 26.7C191.0 27.9 190.5 29.6 190.5 31.8H191.5C191.5 29.8 192.0 28.3 192.8 27.4L192.1 26.7ZM190.5 31.8V44H191.5V31.8H190.5ZM191.0 43.5H184.0V44.5H191.0V43.5ZM184.5 44V19.7H183.5V44H184.5ZM184.0 20.2H190.7V19.2H184.0V20.2ZM190.2 19.7V22.5H191.2V19.7H190.2ZM191.1 22.9C191.9 21.9 193.0 21.2 194.2 20.7L193.8 19.7C192.4 20.3 191.3 21.1 190.3 22.2L191.1 22.9ZM194.2 20.7C195.4 20.1 196.8 19.9 198.3 19.9V18.9C196.7 18.9 195.2 19.2 193.8 19.7L194.2 20.7ZM198.3 19.9C199.9 19.9 201.4 20.2 202.7 20.9L203.2 20.0C201.7 19.2 200.1 18.9 198.3 18.9V19.9ZM202.7 20.9C204.0 21.5 205.1 22.4 205.9 23.6L206.7 23.1C205.8 21.7 204.6 20.7 203.2 20.0L202.7 20.9ZM206.7 23.6C207.6 22.5 208.8 21.5 210.2 20.9L209.8 20.0C208.2 20.7 206.9 21.7 205.9 23.0L206.7 23.6ZM210.2 20.9C211.7 20.2 213.3 19.9 215.0 19.9V18.9C213.1 18.9 211.4 19.2 209.8 20.0L210.2 20.9ZM236.1 42.7L235.9 43.2L235.9 43.2L236.1 42.7ZM231.4 38.3L230.9 38.5L231.4 38.3ZM231.4 25.4L230.9 25.2L231.4 25.4ZM236.1 21.0L236.3 21.4L236.3 21.4L236.1 21.0ZM249.8 21.0L249.6 21.4L249.6 21.4L249.8 21.0ZM254.5 25.4L255.0 25.2L254.5 25.4ZM254.5 38.3L255.0 38.5L254.5 38.3ZM249.8 42.7L250.1 43.2L250.1 43.2L249.8 42.7ZM247.4 36.8L247.0 36.4L247.0 36.4L247.4 36.8ZM247.4 27.0L247.0 27.3L247.0 27.3L247.4 27.0ZM238.5 27.0L238.9 27.3L238.9 27.3L238.5 27.0ZM238.5 36.8L238.2 37.1L238.2 37.1L238.5 36.8ZM243.0 43.8C240.5 43.8 238.3 43.3 236.3 42.3L235.9 43.2C238.0 44.3 240.4 44.8 243.0 44.8V43.8ZM236.3 42.3C234.4 41.3 232.9 39.8 231.8 38.0L230.9 38.5C232.1 40.5 233.8 42.1 235.9 43.2L236.3 42.3ZM231.8 38.0C230.7 36.2 230.2 34.2 230.2 31.8H229.2C229.2 34.3 229.8 36.6 230.9 38.5L231.8 38.0ZM230.2 31.8C230.2 29.5 230.7 27.5 231.8 25.7L230.9 25.2C229.8 27.1 229.2 29.4 229.2 31.8H230.2ZM231.8 25.7C232.9 23.9 234.4 22.5 236.3 21.4L235.9 20.6C233.8 21.6 232.1 23.2 230.9 25.2L231.8 25.7ZM236.3 21.4C238.3 20.4 240.5 19.9 243.0 19.9V18.9C240.4 18.9 238.0 19.4 235.9 20.6L236.3 21.4ZM243.0 19.9C245.5 19.9 247.7 20.4 249.6 21.4L250.1 20.6C248.0 19.4 245.6 18.9 243.0 18.9V19.9ZM249.6 21.4C251.5 22.5 253.0 23.9 254.1 25.7L255.0 25.2C253.8 23.2 252.1 21.6 250.1 20.6L249.6 21.4ZM254.1 25.7C255.2 27.5 255.8 29.5 255.8 31.8H256.8C256.8 29.4 256.2 27.1 255.0 25.2L254.1 25.7ZM255.8 31.8C255.8 34.2 255.2 36.2 254.1 38.0L255.0 38.5C256.2 36.6 256.8 34.3 256.8 31.8H255.8ZM254.1 38.0C253.0 39.8 251.5 41.3 249.6 42.3L250.1 43.2C252.1 42.1 253.8 40.5 255.0 38.5L254.1 38.0ZM249.6 42.3C247.7 43.3 245.5 43.8 243.0 43.8V44.8C245.6 44.8 248.0 44.3 250.1 43.2L249.6 42.3ZM243.0 39.1C244.9 39.1 246.5 38.4 247.8 37.1L247.0 36.4C246.0 37.5 244.7 38.1 243.0 38.1V39.1ZM247.8 37.1C249.0 35.8 249.6 34.0 249.6 31.8H248.6C248.6 33.8 248.1 35.3 247.0 36.4L247.8 37.1ZM249.6 31.8C249.6 29.7 249.0 27.9 247.7 26.6L247.0 27.3C248.1 28.4 248.6 29.9 248.6 31.8H249.6ZM247.8 26.6C246.5 25.3 244.9 24.6 243.0 24.6V25.6C244.7 25.6 246.0 26.2 247.0 27.3L247.8 26.6ZM243.0 24.6C241.1 24.6 239.4 25.3 238.2 26.6L238.9 27.3C240.0 26.2 241.3 25.6 243.0 25.6V24.6ZM238.2 26.6C236.9 27.9 236.3 29.7 236.3 31.8H237.3C237.3 29.9 237.8 28.4 238.9 27.3L238.2 26.6ZM236.3 31.8C236.3 34.0 236.9 35.8 238.2 37.1L238.9 36.4C237.8 35.3 237.3 33.8 237.3 31.8H236.3ZM238.2 37.1C239.4 38.4 241.1 39.1 243.0 39.1V38.1C241.3 38.1 240.0 37.5 238.9 36.4L238.2 37.1Z" fill="%23343434"></path><defs><linearGradient id="paint0_linear" x1="14.5" y1="41.1" x2="33.6" y2="58.5" gradientUnits="userSpaceOnUse"><stop stop-color="%23EE4645"></stop><stop offset="1" stop-color="%23810707"></stop></linearGradient></defs></svg>'></a></li>
+ </ul>
+</section>
+
</article>
diff --git a/help3/xhpeditor/cm/keymap/emacs.js b/help3/xhpeditor/cm/keymap/emacs.js
index fe62d44f..84744e40 100644
--- a/help3/xhpeditor/cm/keymap/emacs.js
+++ b/help3/xhpeditor/cm/keymap/emacs.js
@@ -11,6 +11,7 @@
})(function(CodeMirror) {
"use strict";
+ var cmds = CodeMirror.commands;
var Pos = CodeMirror.Pos;
function posEq(a, b) { return a.line == b.line && a.ch == b.ch; }
@@ -30,7 +31,8 @@
var lastKill = null;
- function kill(cm, from, to, ring, text) {
+ // Internal generic kill function, used by several mapped kill "family" functions.
+ function _kill(cm, from, to, ring, text) {
if (text == null) text = cm.getRange(from, to);
if (ring == "grow" && lastKill && lastKill.cm == cm && posEq(from, lastKill.pos) && cm.isClean(lastKill.gen))
@@ -156,17 +158,17 @@
var i = selections.length;
while (i--) {
cursor = selections[i].head;
- kill(cm, cursor, findEnd(cm, cursor, by, dir), ring);
+ _kill(cm, cursor, findEnd(cm, cursor, by, dir), ring);
}
}
- function killRegion(cm, ring) {
+ function _killRegion(cm, ring) {
if (cm.somethingSelected()) {
var selections = cm.listSelections(), selection;
var i = selections.length;
while (i--) {
selection = selections[i];
- kill(cm, selection.anchor, selection.head, ring);
+ _kill(cm, selection.anchor, selection.head, ring);
}
return true;
}
@@ -205,13 +207,6 @@
}
}
- function addPrefixMap(cm) {
- cm.state.emacsPrefixMap = true;
- cm.addKeyMap(prefixMap);
- cm.on("keyHandled", maybeRemovePrefixMap);
- cm.on("inputRead", maybeRemovePrefixMap);
- }
-
function maybeRemovePrefixMap(cm, arg) {
if (typeof arg == "string" && (/^\d$/.test(arg) || arg == "Ctrl-U")) return;
cm.removeKeyMap(prefixMap);
@@ -222,7 +217,7 @@
// Utilities
- function setMark(cm) {
+ cmds.setMark = function (cm) {
cm.setCursor(cm.getCursor());
cm.setExtending(!cm.getExtending());
cm.on("change", function() { cm.setExtending(false); });
@@ -233,9 +228,19 @@
cm.setCursor(cm.getCursor());
}
+ function makePrompt(msg) {
+ var fragment = document.createDocumentFragment();
+ var input = document.createElement("input");
+ input.setAttribute("type", "text");
+ input.style.width = "10em";
+ fragment.appendChild(document.createTextNode(msg + ": "));
+ fragment.appendChild(input);
+ return fragment;
+ }
+
function getInput(cm, msg, f) {
if (cm.openDialog)
- cm.openDialog(msg + ": <input type=\"text\" style=\"width: 10em\"/>", f, {bottom: true});
+ cm.openDialog(makePrompt(msg), f, {bottom: true});
else
f(prompt(msg, ""));
}
@@ -266,145 +271,267 @@
}
}
- function quit(cm) {
+ // Commands. Names should match emacs function names (albeit in camelCase)
+ // except where emacs function names collide with code mirror core commands.
+
+ cmds.killRegion = function(cm) {
+ _kill(cm, cm.getCursor("start"), cm.getCursor("end"), true);
+ };
+
+ // Maps to emacs kill-line
+ cmds.killLineEmacs = repeated(function(cm) {
+ var start = cm.getCursor(), end = cm.clipPos(Pos(start.line));
+ var text = cm.getRange(start, end);
+ if (!/\S/.test(text)) {
+ text += "\n";
+ end = Pos(start.line + 1, 0);
+ }
+ _kill(cm, start, end, "grow", text);
+ });
+
+ cmds.killRingSave = function(cm) {
+ addToRing(cm.getSelection());
+ clearMark(cm);
+ };
+
+ cmds.yank = function(cm) {
+ var start = cm.getCursor();
+ cm.replaceRange(getFromRing(getPrefix(cm)), start, start, "paste");
+ cm.setSelection(start, cm.getCursor());
+ };
+
+ cmds.yankPop = function(cm) {
+ cm.replaceSelection(popFromRing(), "around", "paste");
+ };
+
+ cmds.forwardChar = move(byChar, 1);
+
+ cmds.backwardChar = move(byChar, -1)
+
+ cmds.deleteChar = function(cm) { killTo(cm, byChar, 1, false); };
+
+ cmds.deleteForwardChar = function(cm) {
+ _killRegion(cm, false) || killTo(cm, byChar, 1, false);
+ };
+
+ cmds.deleteBackwardChar = function(cm) {
+ _killRegion(cm, false) || killTo(cm, byChar, -1, false);
+ };
+
+ cmds.forwardWord = move(byWord, 1);
+
+ cmds.backwardWord = move(byWord, -1);
+
+ cmds.killWord = function(cm) { killTo(cm, byWord, 1, "grow"); };
+
+ cmds.backwardKillWord = function(cm) { killTo(cm, byWord, -1, "grow"); };
+
+ cmds.nextLine = move(byLine, 1);
+
+ cmds.previousLine = move(byLine, -1);
+
+ cmds.scrollDownCommand = move(byPage, 1);
+
+ cmds.scrollUpCommand = move(byPage, -1);
+
+ cmds.backwardParagraph = move(byParagraph, -1);
+
+ cmds.forwardParagraph = move(byParagraph, 1);
+
+ cmds.backwardSentence = move(bySentence, -1);
+
+ cmds.forwardSentence = move(bySentence, 1);
+
+ cmds.killSentence = function(cm) { killTo(cm, bySentence, 1, "grow"); };
+
+ cmds.backwardKillSentence = function(cm) {
+ _kill(cm, cm.getCursor(), bySentence(cm, cm.getCursor(), 1), "grow");
+ };
+
+ cmds.killSexp = function(cm) { killTo(cm, byExpr, 1, "grow"); };
+
+ cmds.backwardKillSexp = function(cm) { killTo(cm, byExpr, -1, "grow"); };
+
+ cmds.forwardSexp = move(byExpr, 1);
+
+ cmds.backwardSexp = move(byExpr, -1);
+
+ cmds.markSexp = function(cm) {
+ var cursor = cm.getCursor();
+ cm.setSelection(findEnd(cm, cursor, byExpr, 1), cursor);
+ };
+
+ cmds.transposeSexps = function(cm) {
+ var leftStart = byExpr(cm, cm.getCursor(), -1);
+ var leftEnd = byExpr(cm, leftStart, 1);
+ var rightEnd = byExpr(cm, leftEnd, 1);
+ var rightStart = byExpr(cm, rightEnd, -1);
+ cm.replaceRange(cm.getRange(rightStart, rightEnd) +
+ cm.getRange(leftEnd, rightStart) +
+ cm.getRange(leftStart, leftEnd), leftStart, rightEnd);
+ };
+
+ cmds.backwardUpList = repeated(toEnclosingExpr);
+
+ cmds.justOneSpace = function(cm) {
+ var pos = cm.getCursor(), from = pos.ch;
+ var to = pos.ch, text = cm.getLine(pos.line);
+ while (from && /\s/.test(text.charAt(from - 1))) --from;
+ while (to < text.length && /\s/.test(text.charAt(to))) ++to;
+ cm.replaceRange(" ", Pos(pos.line, from), Pos(pos.line, to));
+ };
+
+ cmds.openLine = repeated(function(cm) {
+ cm.replaceSelection("\n", "start");
+ });
+
+ // maps to emacs 'transpose-chars'
+ cmds.transposeCharsRepeatable = repeated(function(cm) {
+ cm.execCommand("transposeChars");
+ });
+
+ cmds.capitalizeWord = repeated(function(cm) {
+ operateOnWord(cm, function(w) {
+ var letter = w.search(/\w/);
+ if (letter == -1) return w;
+ return w.slice(0, letter) + w.charAt(letter).toUpperCase() +
+ w.slice(letter + 1).toLowerCase();
+ });
+ });
+
+ cmds.upcaseWord = repeated(function(cm) {
+ operateOnWord(cm, function(w) { return w.toUpperCase(); });
+ });
+
+ cmds.downcaseWord = repeated(function(cm) {
+ operateOnWord(cm, function(w) { return w.toLowerCase(); });
+ });
+
+ // maps to emacs 'undo'
+ cmds.undoRepeatable = repeated("undo");
+
+ cmds.keyboardQuit = function(cm) {
cm.execCommand("clearSearch");
clearMark(cm);
}
- CodeMirror.emacs = {kill: kill, killRegion: killRegion, repeated: repeated};
+ cmds.newline = repeated(function(cm) { cm.replaceSelection("\n", "end"); });
- // Actual keymap
+ cmds.gotoLine = function(cm) {
+ var prefix = getPrefix(cm, true);
+ if (prefix != null && prefix > 0) return cm.setCursor(prefix - 1);
- var keyMap = CodeMirror.keyMap.emacs = CodeMirror.normalizeKeyMap({
- "Ctrl-W": function(cm) {kill(cm, cm.getCursor("start"), cm.getCursor("end"), true);},
- "Ctrl-K": repeated(function(cm) {
- var start = cm.getCursor(), end = cm.clipPos(Pos(start.line));
- var text = cm.getRange(start, end);
- if (!/\S/.test(text)) {
- text += "\n";
- end = Pos(start.line + 1, 0);
- }
- kill(cm, start, end, "grow", text);
- }),
- "Alt-W": function(cm) {
- addToRing(cm.getSelection());
- clearMark(cm);
- },
- "Ctrl-Y": function(cm) {
- var start = cm.getCursor();
- cm.replaceRange(getFromRing(getPrefix(cm)), start, start, "paste");
- cm.setSelection(start, cm.getCursor());
- },
- "Alt-Y": function(cm) {cm.replaceSelection(popFromRing(), "around", "paste");},
-
- "Ctrl-Space": setMark, "Ctrl-Shift-2": setMark,
-
- "Ctrl-F": move(byChar, 1), "Ctrl-B": move(byChar, -1),
- "Right": move(byChar, 1), "Left": move(byChar, -1),
- "Ctrl-D": function(cm) { killTo(cm, byChar, 1, false); },
- "Delete": function(cm) { killRegion(cm, false) || killTo(cm, byChar, 1, false); },
- "Ctrl-H": function(cm) { killTo(cm, byChar, -1, false); },
- "Backspace": function(cm) { killRegion(cm, false) || killTo(cm, byChar, -1, false); },
-
- "Alt-F": move(byWord, 1), "Alt-B": move(byWord, -1),
- "Alt-Right": move(byWord, 1), "Alt-Left": move(byWord, -1),
- "Alt-D": function(cm) { killTo(cm, byWord, 1, "grow"); },
- "Alt-Backspace": function(cm) { killTo(cm, byWord, -1, "grow"); },
-
- "Ctrl-N": move(byLine, 1), "Ctrl-P": move(byLine, -1),
- "Down": move(byLine, 1), "Up": move(byLine, -1),
- "Ctrl-A": "goLineStart", "Ctrl-E": "goLineEnd",
- "End": "goLineEnd", "Home": "goLineStart",
-
- "Alt-V": move(byPage, -1), "Ctrl-V": move(byPage, 1),
- "PageUp": move(byPage, -1), "PageDown": move(byPage, 1),
-
- "Ctrl-Up": move(byParagraph, -1), "Ctrl-Down": move(byParagraph, 1),
-
- "Alt-A": move(bySentence, -1), "Alt-E": move(bySentence, 1),
- "Alt-K": function(cm) { killTo(cm, bySentence, 1, "grow"); },
-
- "Ctrl-Alt-K": function(cm) { killTo(cm, byExpr, 1, "grow"); },
- "Ctrl-Alt-Backspace": function(cm) { killTo(cm, byExpr, -1, "grow"); },
- "Ctrl-Alt-F": move(byExpr, 1), "Ctrl-Alt-B": move(byExpr, -1, "grow"),
-
- "Shift-Ctrl-Alt-2": function(cm) {
- var cursor = cm.getCursor();
- cm.setSelection(findEnd(cm, cursor, byExpr, 1), cursor);
- },
- "Ctrl-Alt-T": function(cm) {
- var leftStart = byExpr(cm, cm.getCursor(), -1), leftEnd = byExpr(cm, leftStart, 1);
- var rightEnd = byExpr(cm, leftEnd, 1), rightStart = byExpr(cm, rightEnd, -1);
- cm.replaceRange(cm.getRange(rightStart, rightEnd) + cm.getRange(leftEnd, rightStart) +
- cm.getRange(leftStart, leftEnd), leftStart, rightEnd);
- },
- "Ctrl-Alt-U": repeated(toEnclosingExpr),
-
- "Alt-Space": function(cm) {
- var pos = cm.getCursor(), from = pos.ch, to = pos.ch, text = cm.getLine(pos.line);
- while (from && /\s/.test(text.charAt(from - 1))) --from;
- while (to < text.length && /\s/.test(text.charAt(to))) ++to;
- cm.replaceRange(" ", Pos(pos.line, from), Pos(pos.line, to));
- },
- "Ctrl-O": repeated(function(cm) { cm.replaceSelection("\n", "start"); }),
- "Ctrl-T": repeated(function(cm) {
- cm.execCommand("transposeChars");
- }),
-
- "Alt-C": repeated(function(cm) {
- operateOnWord(cm, function(w) {
- var letter = w.search(/\w/);
- if (letter == -1) return w;
- return w.slice(0, letter) + w.charAt(letter).toUpperCase() + w.slice(letter + 1).toLowerCase();
- });
- }),
- "Alt-U": repeated(function(cm) {
- operateOnWord(cm, function(w) { return w.toUpperCase(); });
- }),
- "Alt-L": repeated(function(cm) {
- operateOnWord(cm, function(w) { return w.toLowerCase(); });
- }),
+ getInput(cm, "Goto line", function(str) {
+ var num;
+ if (str && !isNaN(num = Number(str)) && num == (num|0) && num > 0)
+ cm.setCursor(num - 1);
+ });
+ };
- "Alt-;": "toggleComment",
+ cmds.indentRigidly = function(cm) {
+ cm.indentSelection(getPrefix(cm, true) || cm.getOption("indentUnit"));
+ };
+
+ cmds.exchangePointAndMark = function(cm) {
+ cm.setSelection(cm.getCursor("head"), cm.getCursor("anchor"));
+ };
+
+ cmds.quotedInsertTab = repeated("insertTab");
+
+ cmds.universalArgument = function addPrefixMap(cm) {
+ cm.state.emacsPrefixMap = true;
+ cm.addKeyMap(prefixMap);
+ cm.on("keyHandled", maybeRemovePrefixMap);
+ cm.on("inputRead", maybeRemovePrefixMap);
+ };
- "Ctrl-/": repeated("undo"), "Shift-Ctrl--": repeated("undo"),
- "Ctrl-Z": repeated("undo"), "Cmd-Z": repeated("undo"),
+ CodeMirror.emacs = {kill: _kill, killRegion: _killRegion, repeated: repeated};
+
+ // Actual keymap
+ var keyMap = CodeMirror.keyMap.emacs = CodeMirror.normalizeKeyMap({
+ "Ctrl-W": "killRegion",
+ "Ctrl-K": "killLineEmacs",
+ "Alt-W": "killRingSave",
+ "Ctrl-Y": "yank",
+ "Alt-Y": "yankPop",
+ "Ctrl-Space": "setMark",
+ "Ctrl-Shift-2": "setMark",
+ "Ctrl-F": "forwardChar",
+ "Ctrl-B": "backwardChar",
+ "Right": "forwardChar",
+ "Left": "backwardChar",
+ "Ctrl-D": "deleteChar",
+ "Delete": "deleteForwardChar",
+ "Ctrl-H": "deleteBackwardChar",
+ "Backspace": "deleteBackwardChar",
+ "Alt-F": "forwardWord",
+ "Alt-B": "backwardWord",
+ "Alt-Right": "forwardWord",
+ "Alt-Left": "backwardWord",
+ "Alt-D": "killWord",
+ "Alt-Backspace": "backwardKillWord",
+ "Ctrl-N": "nextLine",
+ "Ctrl-P": "previousLine",
+ "Down": "nextLine",
+ "Up": "previousLine",
+ "Ctrl-A": "goLineStart",
+ "Ctrl-E": "goLineEnd",
+ "End": "goLineEnd",
+ "Home": "goLineStart",
+ "Alt-V": "scrollDownCommand",
+ "Ctrl-V": "scrollUpCommand",
+ "PageUp": "scrollUpCommand",
+ "PageDown": "scrollDownCommand",
+ "Ctrl-Up": "backwardParagraph",
+ "Ctrl-Down": "forwardParagraph",
+ "Alt-{": "backwardParagraph",
+ "Alt-}": "forwardParagraph",
+ "Alt-A": "backwardSentence",
+ "Alt-E": "forwardSentence",
+ "Alt-K": "killSentence",
+ "Ctrl-X Delete": "backwardKillSentence",
+ "Ctrl-Alt-K": "killSexp",
+ "Ctrl-Alt-Backspace": "backwardKillSexp",
+ "Ctrl-Alt-F": "forwardSexp",
+ "Ctrl-Alt-B": "backwardSexp",
+ "Shift-Ctrl-Alt-2": "markSexp",
+ "Ctrl-Alt-T": "transposeSexps",
+ "Ctrl-Alt-U": "backwardUpList",
+ "Alt-Space": "justOneSpace",
+ "Ctrl-O": "openLine",
+ "Ctrl-T": "transposeCharsRepeatable",
+ "Alt-C": "capitalizeWord",
+ "Alt-U": "upcaseWord",
+ "Alt-L": "downcaseWord",
+ "Alt-;": "toggleComment",
+ "Ctrl-/": "undoRepeatable",
+ "Shift-Ctrl--": "undoRepeatable",
+ "Ctrl-Z": "undoRepeatable",
+ "Cmd-Z": "undoRepeatable",
+ "Ctrl-X U": "undoRepeatable",
"Shift-Ctrl-Z": "redo",
- "Shift-Alt-,": "goDocStart", "Shift-Alt-.": "goDocEnd",
- "Ctrl-S": "findPersistentNext", "Ctrl-R": "findPersistentPrev", "Ctrl-G": quit, "Shift-Alt-5": "replace",
+ "Shift-Alt-,": "goDocStart",
+ "Shift-Alt-.": "goDocEnd",
+ "Ctrl-S": "findPersistentNext",
+ "Ctrl-R": "findPersistentPrev",
+ "Ctrl-G": "keyboardQuit",
+ "Shift-Alt-5": "replace",
"Alt-/": "autocomplete",
"Enter": "newlineAndIndent",
- "Ctrl-J": repeated(function(cm) { cm.replaceSelection("\n", "end"); }),
+ "Ctrl-J": "newline",
"Tab": "indentAuto",
-
- "Alt-G G": function(cm) {
- var prefix = getPrefix(cm, true);
- if (prefix != null && prefix > 0) return cm.setCursor(prefix - 1);
-
- getInput(cm, "Goto line", function(str) {
- var num;
- if (str && !isNaN(num = Number(str)) && num == (num|0) && num > 0)
- cm.setCursor(num - 1);
- });
- },
-
- "Ctrl-X Tab": function(cm) {
- cm.indentSelection(getPrefix(cm, true) || cm.getOption("indentUnit"));
- },
- "Ctrl-X Ctrl-X": function(cm) {
- cm.setSelection(cm.getCursor("head"), cm.getCursor("anchor"));
- },
+ "Alt-G G": "gotoLine",
+ "Ctrl-X Tab": "indentRigidly",
+ "Ctrl-X Ctrl-X": "exchangePointAndMark",
"Ctrl-X Ctrl-S": "save",
"Ctrl-X Ctrl-W": "save",
"Ctrl-X S": "saveAll",
"Ctrl-X F": "open",
- "Ctrl-X U": repeated("undo"),
"Ctrl-X K": "close",
- "Ctrl-X Delete": function(cm) { kill(cm, cm.getCursor(), bySentence(cm, cm.getCursor(), 1), "grow"); },
"Ctrl-X H": "selectAll",
-
- "Ctrl-Q Tab": repeated("insertTab"),
- "Ctrl-U": addPrefixMap
+ "Ctrl-Q Tab": "quotedInsertTab",
+ "Ctrl-U": "universalArgument",
+ "fallthrough": "default"
});
var prefixMap = {"Ctrl-G": clearPrefix};
diff --git a/help3/xhpeditor/cm/keymap/sublime.js b/help3/xhpeditor/cm/keymap/sublime.js
index cfdf71ed..0c9a63e0 100644
--- a/help3/xhpeditor/cm/keymap/sublime.js
+++ b/help3/xhpeditor/cm/keymap/sublime.js
@@ -339,7 +339,7 @@
};
- function sortLines(cm, caseSensitive) {
+ function sortLines(cm, caseSensitive, direction) {
if (cm.isReadOnly()) return CodeMirror.Pass
var ranges = cm.listSelections(), toSort = [], selected;
for (var i = 0; i < ranges.length; i++) {
@@ -361,12 +361,12 @@
var start = Pos(from, 0), end = Pos(to);
var lines = cm.getRange(start, end, false);
if (caseSensitive)
- lines.sort();
+ lines.sort(function(a, b) { return a < b ? -direction : a == b ? 0 : direction; });
else
lines.sort(function(a, b) {
var au = a.toUpperCase(), bu = b.toUpperCase();
if (au != bu) { a = au; b = bu; }
- return a < b ? -1 : a == b ? 0 : 1;
+ return a < b ? -direction : a == b ? 0 : direction;
});
cm.replaceRange(lines, start, end);
if (selected) ranges.push({anchor: start, head: Pos(to + 1, 0)});
@@ -375,8 +375,10 @@
});
}
- cmds.sortLines = function(cm) { sortLines(cm, true); };
- cmds.sortLinesInsensitive = function(cm) { sortLines(cm, false); };
+ cmds.sortLines = function(cm) { sortLines(cm, true, 1); };
+ cmds.reverseSortLines = function(cm) { sortLines(cm, true, -1); };
+ cmds.sortLinesInsensitive = function(cm) { sortLines(cm, false, 1); };
+ cmds.reverseSortLinesInsensitive = function(cm) { sortLines(cm, false, -1); };
cmds.nextBookmark = function(cm) {
var marks = cm.state.sublimeBookmarks;
@@ -609,7 +611,9 @@
"Cmd-J": "joinLines",
"Shift-Cmd-D": "duplicateLine",
"F5": "sortLines",
+ "Shift-F5": "reverseSortLines",
"Cmd-F5": "sortLinesInsensitive",
+ "Shift-Cmd-F5": "reverseSortLinesInsensitive",
"F2": "nextBookmark",
"Shift-F2": "prevBookmark",
"Cmd-F2": "toggleBookmark",
@@ -628,6 +632,7 @@
"Cmd-K Cmd-C": "showInCenter",
"Cmd-K Cmd-G": "clearBookmarks",
"Cmd-K Cmd-Backspace": "delLineLeft",
+ "Cmd-K Cmd-1": "foldAll",
"Cmd-K Cmd-0": "unfoldAll",
"Cmd-K Cmd-J": "unfoldAll",
"Ctrl-Shift-Up": "addCursorToPrevLine",
@@ -670,7 +675,9 @@
"Ctrl-J": "joinLines",
"Shift-Ctrl-D": "duplicateLine",
"F9": "sortLines",
+ "Shift-F9": "reverseSortLines",
"Ctrl-F9": "sortLinesInsensitive",
+ "Shift-Ctrl-F9": "reverseSortLinesInsensitive",
"F2": "nextBookmark",
"Shift-F2": "prevBookmark",
"Ctrl-F2": "toggleBookmark",
@@ -689,6 +696,7 @@
"Ctrl-K Ctrl-C": "showInCenter",
"Ctrl-K Ctrl-G": "clearBookmarks",
"Ctrl-K Ctrl-Backspace": "delLineLeft",
+ "Ctrl-K Ctrl-1": "foldAll",
"Ctrl-K Ctrl-0": "unfoldAll",
"Ctrl-K Ctrl-J": "unfoldAll",
"Ctrl-Alt-Up": "addCursorToPrevLine",
diff --git a/help3/xhpeditor/cm/keymap/vim.js b/help3/xhpeditor/cm/keymap/vim.js
index ce5983d8..6630b6f6 100644
--- a/help3/xhpeditor/cm/keymap/vim.js
+++ b/help3/xhpeditor/cm/keymap/vim.js
@@ -8,7 +8,7 @@
* Supported Ex commands:
* Refer to defaultExCommandMap below.
*
- * Registers: unnamed, -, a-z, A-Z, 0-9
+ * Registers: unnamed, -, ., :, /, _, a-z, A-Z, 0-9
* (Does not respect the special case for number registers when delete
* operator is made with these commands: %, (, ), , /, ?, n, N, {, } )
* TODO: Implement the remaining registers.
@@ -141,6 +141,8 @@
{ keys: 'gU', type: 'operator', operator: 'changeCase', operatorArgs: {toLower: false}, isEdit: true },
{ keys: 'n', type: 'motion', motion: 'findNext', motionArgs: { forward: true, toJumplist: true }},
{ keys: 'N', type: 'motion', motion: 'findNext', motionArgs: { forward: false, toJumplist: true }},
+ { keys: 'gn', type: 'motion', motion: 'findAndSelectNextInclusive', motionArgs: { forward: true }},
+ { keys: 'gN', type: 'motion', motion: 'findAndSelectNextInclusive', motionArgs: { forward: false }},
// Operator-Motion dual commands
{ keys: 'x', type: 'operatorMotion', operator: 'delete', motion: 'moveByCharacters', motionArgs: { forward: true }, operatorMotionArgs: { visualLine: false }},
{ keys: 'X', type: 'operatorMotion', operator: 'delete', motion: 'moveByCharacters', motionArgs: { forward: false }, operatorMotionArgs: { visualLine: true }},
@@ -234,7 +236,6 @@
{ name: 'undo', shortName: 'u' },
{ name: 'redo', shortName: 'red' },
{ name: 'set', shortName: 'se' },
- { name: 'set', shortName: 'se' },
{ name: 'setlocal', shortName: 'setl' },
{ name: 'setglobal', shortName: 'setg' },
{ name: 'sort', shortName: 'sor' },
@@ -243,6 +244,7 @@
{ name: 'yank', shortName: 'y' },
{ name: 'delmarks', shortName: 'delm' },
{ name: 'registers', shortName: 'reg', excludeFromCommandHistory: true },
+ { name: 'vglobal', shortName: 'v' },
{ name: 'global', shortName: 'g' }
];
@@ -295,16 +297,16 @@
clearFatCursorMark(cm);
var ranges = cm.listSelections(), result = []
for (var i = 0; i < ranges.length; i++) {
- var range = ranges[i]
+ var range = ranges[i];
if (range.empty()) {
- if (range.anchor.ch < cm.getLine(range.anchor.line).length) {
+ var lineLength = cm.getLine(range.anchor.line).length;
+ if (range.anchor.ch < lineLength) {
result.push(cm.markText(range.anchor, Pos(range.anchor.line, range.anchor.ch + 1),
- {className: "cm-fat-cursor-mark"}))
+ {className: "cm-fat-cursor-mark"}));
} else {
- var widget = document.createElement("span")
- widget.textContent = "\u00a0"
- widget.className = "cm-fat-cursor-mark"
- result.push(cm.setBookmark(range.anchor, {widget: widget}))
+ result.push(cm.markText(Pos(range.anchor.line, lineLength - 1),
+ Pos(range.anchor.line, lineLength),
+ {className: "cm-fat-cursor-mark"}));
}
}
}
@@ -352,7 +354,7 @@
return cmd;
}
- var modifiers = {'Shift': 'S', 'Ctrl': 'C', 'Alt': 'A', 'Cmd': 'D', 'Mod': 'A'};
+ var modifiers = {Shift:'S',Ctrl:'C',Alt:'A',Cmd:'D',Mod:'A',CapsLock:''};
var specialKeys = {Enter:'CR',Backspace:'BS',Delete:'Del',Insert:'Ins'};
function cmKeyToVimKey(key) {
if (key.charAt(0) == '\'') {
@@ -417,7 +419,7 @@
var lowerCaseAlphabet = makeKeyRange(97, 26);
var numbers = makeKeyRange(48, 10);
var validMarks = [].concat(upperCaseAlphabet, lowerCaseAlphabet, numbers, ['<', '>']);
- var validRegisters = [].concat(upperCaseAlphabet, lowerCaseAlphabet, numbers, ['-', '"', '.', ':', '/']);
+ var validRegisters = [].concat(upperCaseAlphabet, lowerCaseAlphabet, numbers, ['-', '"', '.', ':', '_', '/']);
function isLine(cm, line) {
return line >= cm.firstLine() && line <= cm.lastLine();
@@ -736,7 +738,7 @@
// TODO: Convert keymap into dictionary format for fast lookup.
},
// Testing hook, though it might be useful to expose the register
- // controller anyways.
+ // controller anyway.
getRegisterController: function() {
return vimGlobalState.registerController;
},
@@ -1129,6 +1131,8 @@
}
RegisterController.prototype = {
pushText: function(registerName, operator, text, linewise, blockwise) {
+ // The black hole register, "_, means delete/yank to nowhere.
+ if (registerName === '_') return;
if (linewise && text.charAt(text.length - 1) !== '\n'){
text += '\n';
}
@@ -1447,7 +1451,7 @@
showPrompt(cm, {
onClose: onPromptClose,
prefix: promptPrefix,
- desc: searchPromptDesc,
+ desc: '(JavaScript regexp)',
onKeyUp: onPromptKeyUp,
onKeyDown: onPromptKeyDown
});
@@ -1575,7 +1579,7 @@
motionArgs.repeat = repeat;
clearInputState(cm);
if (motion) {
- var motionResult = motions[motion](cm, origHead, motionArgs, vim);
+ var motionResult = motions[motion](cm, origHead, motionArgs, vim, inputState);
vim.lastMotion = motions[motion];
if (!motionResult) {
return;
@@ -1603,10 +1607,10 @@
}
if (vim.visualMode) {
if (!(vim.visualBlock && newHead.ch === Infinity)) {
- newHead = clipCursorToContent(cm, newHead, vim.visualBlock);
+ newHead = clipCursorToContent(cm, newHead);
}
if (newAnchor) {
- newAnchor = clipCursorToContent(cm, newAnchor, true);
+ newAnchor = clipCursorToContent(cm, newAnchor);
}
newAnchor = newAnchor || oldAnchor;
sel.anchor = newAnchor;
@@ -1773,6 +1777,87 @@
highlightSearchMatches(cm, query);
return findNext(cm, prev/** prev */, query, motionArgs.repeat);
},
+ /**
+ * Find and select the next occurrence of the search query. If the cursor is currently
+ * within a match, then find and select the current match. Otherwise, find the next occurrence in the
+ * appropriate direction.
+ *
+ * This differs from `findNext` in the following ways:
+ *
+ * 1. Instead of only returning the "from", this returns a "from", "to" range.
+ * 2. If the cursor is currently inside a search match, this selects the current match
+ * instead of the next match.
+ * 3. If there is no associated operator, this will turn on visual mode.
+ */
+ findAndSelectNextInclusive: function(cm, _head, motionArgs, vim, prevInputState) {
+ var state = getSearchState(cm);
+ var query = state.getQuery();
+
+ if (!query) {
+ return;
+ }
+
+ var prev = !motionArgs.forward;
+ prev = (state.isReversed()) ? !prev : prev;
+
+ // next: [from, to] | null
+ var next = findNextFromAndToInclusive(cm, prev, query, motionArgs.repeat, vim);
+
+ // No matches.
+ if (!next) {
+ return;
+ }
+
+ // If there's an operator that will be executed, return the selection.
+ if (prevInputState.operator) {
+ return next;
+ }
+
+ // At this point, we know that there is no accompanying operator -- let's
+ // deal with visual mode in order to select an appropriate match.
+
+ var from = next[0];
+ // For whatever reason, when we use the "to" as returned by searchcursor.js directly,
+ // the resulting selection is extended by 1 char. Let's shrink it so that only the
+ // match is selected.
+ var to = Pos(next[1].line, next[1].ch - 1);
+
+ if (vim.visualMode) {
+ // If we were in visualLine or visualBlock mode, get out of it.
+ if (vim.visualLine || vim.visualBlock) {
+ vim.visualLine = false;
+ vim.visualBlock = false;
+ CodeMirror.signal(cm, "vim-mode-change", {mode: "visual", subMode: ""});
+ }
+
+ // If we're currently in visual mode, we should extend the selection to include
+ // the search result.
+ var anchor = vim.sel.anchor;
+ if (anchor) {
+ if (state.isReversed()) {
+ if (motionArgs.forward) {
+ return [anchor, from];
+ }
+
+ return [anchor, to];
+ } else {
+ if (motionArgs.forward) {
+ return [anchor, to];
+ }
+
+ return [anchor, from];
+ }
+ }
+ } else {
+ // Let's turn visual mode on.
+ vim.visualMode = true;
+ vim.visualLine = false;
+ vim.visualBlock = false;
+ CodeMirror.signal(cm, "vim-mode-change", {mode: "visual", subMode: ""});
+ }
+
+ return prev ? [to, from] : [from, to];
+ },
goToMark: function(cm, _head, motionArgs, vim) {
var pos = getMarkPos(cm, vim, motionArgs.selectedCharacter);
if (pos) {
@@ -1868,8 +1953,8 @@
// move to previous/next line is triggered.
if (line < first && cur.line == first){
return this.moveToStartOfLine(cm, head, motionArgs, vim);
- }else if (line > last && cur.line == last){
- return this.moveToEol(cm, head, motionArgs, vim, true);
+ } else if (line > last && cur.line == last){
+ return moveToEol(cm, head, motionArgs, vim, true);
}
if (motionArgs.toFirstChar){
endCh=findFirstNonWhiteSpaceCharacter(cm.getLine(line));
@@ -1971,16 +2056,8 @@
vim.lastHSPos = cm.charCoords(head,'div').left;
return moveToColumn(cm, repeat);
},
- moveToEol: function(cm, head, motionArgs, vim, keepHPos) {
- var cur = head;
- var retval= Pos(cur.line + motionArgs.repeat - 1, Infinity);
- var end=cm.clipPos(retval);
- end.ch--;
- if (!keepHPos) {
- vim.lastHPos = Infinity;
- vim.lastHSPos = cm.charCoords(end,'div').left;
- }
- return retval;
+ moveToEol: function(cm, head, motionArgs, vim) {
+ return moveToEol(cm, head, motionArgs, vim, false);
},
moveToFirstNonWhiteSpaceCharacter: function(cm, head) {
// Go to the start of the line where the text begins, or the end for
@@ -2070,6 +2147,8 @@
if (operatorArgs) { operatorArgs.linewise = true; }
tmp.end.line--;
}
+ } else if (character === 't') {
+ tmp = expandTagUnderCursor(cm, head, inclusive);
} else {
// No text object defined for this, don't move.
return null;
@@ -2200,8 +2279,7 @@
vimGlobalState.registerController.pushText(
args.registerName, 'delete', text,
args.linewise, vim.visualBlock);
- var includeLineBreak = vim.insertMode
- return clipCursorToContent(cm, finalHead, includeLineBreak);
+ return clipCursorToContent(cm, finalHead);
},
indent: function(cm, args, ranges) {
var vim = cm.state.vim;
@@ -2460,8 +2538,7 @@
vim.visualLine = !!actionArgs.linewise;
vim.visualBlock = !!actionArgs.blockwise;
head = clipCursorToContent(
- cm, Pos(anchor.line, anchor.ch + repeat - 1),
- true /** includeLineBreak */);
+ cm, Pos(anchor.line, anchor.ch + repeat - 1));
vim.sel = {
anchor: anchor,
head: head
@@ -2837,10 +2914,11 @@
* Clips cursor to ensure that line is within the buffer's range
* If includeLineBreak is true, then allow cur.ch == lineLength.
*/
- function clipCursorToContent(cm, cur, includeLineBreak) {
+ function clipCursorToContent(cm, cur) {
+ var vim = cm.state.vim;
+ var includeLineBreak = vim.insertMode || vim.visualMode;
var line = Math.min(Math.max(cm.firstLine(), cur.line), cm.lastLine() );
- var maxCh = lineLength(cm, line) - 1;
- maxCh = (includeLineBreak) ? maxCh + 1 : maxCh;
+ var maxCh = lineLength(cm, line) - 1 + !!includeLineBreak;
var ch = Math.min(Math.max(0, cur.ch), maxCh);
return Pos(line, ch);
}
@@ -3205,10 +3283,8 @@
vim.visualMode = false;
vim.visualLine = false;
vim.visualBlock = false;
- CodeMirror.signal(cm, "vim-mode-change", {mode: "normal"});
- if (vim.fakeCursor) {
- vim.fakeCursor.clear();
- }
+ if (!vim.insertMode) CodeMirror.signal(cm, "vim-mode-change", {mode: "normal"});
+ clearFakeCursor(vim);
}
// Remove any trailing newlines from the selection. For
@@ -3299,6 +3375,49 @@
return { start: Pos(cur.line, start), end: Pos(cur.line, end) };
}
+ /**
+ * Depends on the following:
+ *
+ * - editor mode should be htmlmixedmode / xml
+ * - mode/xml/xml.js should be loaded
+ * - addon/fold/xml-fold.js should be loaded
+ *
+ * If any of the above requirements are not true, this function noops.
+ *
+ * This is _NOT_ a 100% accurate implementation of vim tag text objects.
+ * The following caveats apply (based off cursory testing, I'm sure there
+ * are other discrepancies):
+ *
+ * - Does not work inside comments:
+ * ```
+ * <!-- <div>broken</div> -->
+ * ```
+ * - Does not work when tags have different cases:
+ * ```
+ * <div>broken</DIV>
+ * ```
+ * - Does not work when cursor is inside a broken tag:
+ * ```
+ * <div><brok><en></div>
+ * ```
+ */
+ function expandTagUnderCursor(cm, head, inclusive) {
+ var cur = head;
+ if (!CodeMirror.findMatchingTag || !CodeMirror.findEnclosingTag) {
+ return { start: cur, end: cur };
+ }
+
+ var tags = CodeMirror.findMatchingTag(cm, head) || CodeMirror.findEnclosingTag(cm, head);
+ if (!tags || !tags.open || !tags.close) {
+ return { start: cur, end: cur };
+ }
+
+ if (inclusive) {
+ return { start: tags.open.from, end: tags.close.to };
+ }
+ return { start: tags.open.to, end: tags.close.from };
+ }
+
function recordJumpPosition(cm, oldCur, newCur) {
if (!cursorEqual(oldCur, newCur)) {
vimGlobalState.jumpList.add(cm, oldCur, newCur);
@@ -3365,7 +3484,7 @@
},
isComplete: function(state) {
if (state.nextCh === '#') {
- var token = state.lineText.match(/#(\w+)/)[1];
+ var token = state.lineText.match(/^#(\w+)/)[1];
if (token === 'endif') {
if (state.forward && state.depth === 0) {
return true;
@@ -3566,6 +3685,18 @@
}
}
+ function moveToEol(cm, head, motionArgs, vim, keepHPos) {
+ var cur = head;
+ var retval= Pos(cur.line + motionArgs.repeat - 1, Infinity);
+ var end=cm.clipPos(retval);
+ end.ch--;
+ if (!keepHPos) {
+ vim.lastHPos = Infinity;
+ vim.lastHSPos = cm.charCoords(end,'div').left;
+ }
+ return retval;
+ }
+
function moveToCharacter(cm, repeat, forward, character) {
var cur = cm.getCursor();
var start = cur.ch;
@@ -3840,7 +3971,7 @@
return Pos(curr_index.ln, curr_index.pos);
}
- // TODO: perhaps this finagling of start and end positions belonds
+ // TODO: perhaps this finagling of start and end positions belongs
// in codemirror/replaceRange?
function selectCompanionObject(cm, head, symb, inclusive) {
var cur = head, start, end;
@@ -3980,16 +4111,6 @@
var vim = cm.state.vim;
return vim.searchState_ || (vim.searchState_ = new SearchState());
}
- function dialog(cm, template, shortText, onClose, options) {
- if (cm.openDialog) {
- cm.openDialog(template, onClose, { bottom: true, value: options.value,
- onKeyDown: options.onKeyDown, onKeyUp: options.onKeyUp,
- selectValueOnOpen: false});
- }
- else {
- onClose(prompt(shortText, ''));
- }
- }
function splitBySlash(argString) {
return splitBySeparator(argString, '/');
}
@@ -4176,27 +4297,64 @@
(ignoreCase || forceIgnoreCase) ? 'i' : undefined);
return regexp;
}
- function showConfirm(cm, text) {
+
+ /**
+ * dom - Document Object Manipulator
+ * Usage:
+ * dom('<tag>'|<node>[, ...{<attributes>|<$styles>}|<child-node>|'<text>'])
+ * Examples:
+ * dom('div', {id:'xyz'}, dom('p', 'CM rocks!', {$color:'red'}))
+ * dom(document.head, dom('script', 'alert("hello!")'))
+ * Not supported:
+ * dom('p', ['arrays are objects'], Error('objects specify attributes'))
+ */
+ function dom(n) {
+ if (typeof n === 'string') n = document.createElement(n);
+ for (var a, i = 1; i < arguments.length; i++) {
+ if (!(a = arguments[i])) continue;
+ if (typeof a !== 'object') a = document.createTextNode(a);
+ if (a.nodeType) n.appendChild(a);
+ else for (var key in a) {
+ if (!Object.prototype.hasOwnProperty.call(a, key)) continue;
+ if (key[0] === '$') n.style[key.slice(1)] = a[key];
+ else n.setAttribute(key, a[key]);
+ }
+ }
+ return n;
+ }
+
+ function showConfirm(cm, template) {
+ var pre = dom('pre', {$color: 'red'}, template);
if (cm.openNotification) {
- cm.openNotification('<span style="color: red">' + text + '</span>',
- {bottom: true, duration: 5000});
+ cm.openNotification(pre, {bottom: true, duration: 5000});
} else {
- alert(text);
+ alert(pre.innerText);
}
}
+
function makePrompt(prefix, desc) {
- var raw = '<span style="font-family: monospace; white-space: pre">' +
- (prefix || "") + '<input type="text"></span>';
- if (desc)
- raw += ' <span style="color: #888">' + desc + '</span>';
- return raw;
+ return dom(document.createDocumentFragment(),
+ dom('span', {$fontFamily: 'monospace', $whiteSpace: 'pre'},
+ prefix,
+ dom('input', {type: 'text', autocorrect: 'off',
+ autocapitalize: 'off', spellcheck: 'false'})),
+ desc && dom('span', {$color: '#888'}, desc));
}
- var searchPromptDesc = '(Javascript regexp)';
+
function showPrompt(cm, options) {
var shortText = (options.prefix || '') + ' ' + (options.desc || '');
- var prompt = makePrompt(options.prefix, options.desc);
- dialog(cm, prompt, shortText, options.onClose, options);
+ var template = makePrompt(options.prefix, options.desc);
+ if (cm.openDialog) {
+ cm.openDialog(template, options.onClose, {
+ onKeyDown: options.onKeyDown, onKeyUp: options.onKeyUp,
+ bottom: true, selectValueOnOpen: false, value: options.value
+ });
+ }
+ else {
+ options.onClose(prompt(shortText, ''));
+ }
}
+
function regexEqual(r1, r2) {
if (r1 instanceof RegExp && r2 instanceof RegExp) {
var props = ['global', 'multiline', 'ignoreCase', 'source'];
@@ -4306,6 +4464,42 @@
return cursor.from();
});
}
+ /**
+ * Pretty much the same as `findNext`, except for the following differences:
+ *
+ * 1. Before starting the search, move to the previous search. This way if our cursor is
+ * already inside a match, we should return the current match.
+ * 2. Rather than only returning the cursor's from, we return the cursor's from and to as a tuple.
+ */
+ function findNextFromAndToInclusive(cm, prev, query, repeat, vim) {
+ if (repeat === undefined) { repeat = 1; }
+ return cm.operation(function() {
+ var pos = cm.getCursor();
+ var cursor = cm.getSearchCursor(query, pos);
+
+ // Go back one result to ensure that if the cursor is currently a match, we keep it.
+ var found = cursor.find(!prev);
+
+ // If we haven't moved, go back one more (similar to if i==0 logic in findNext).
+ if (!vim.visualMode && found && cursorEqual(cursor.from(), pos)) {
+ cursor.find(!prev);
+ }
+
+ for (var i = 0; i < repeat; i++) {
+ found = cursor.find(prev);
+ if (!found) {
+ // SearchCursor may have returned null because it hit EOF, wrap
+ // around and try again.
+ cursor = cm.getSearchCursor(query,
+ (prev) ? Pos(cm.lastLine()) : Pos(cm.firstLine(), 0) );
+ if (!cursor.find(prev)) {
+ return;
+ }
+ }
+ }
+ return [cursor.from(), cursor.to()];
+ });
+ }
function clearSearchHighlight(cm) {
var state = getSearchState(cm);
cm.removeOverlay(getSearchState(cm).getOverlay());
@@ -4334,7 +4528,7 @@
if (start instanceof Array) {
return inArray(pos, start);
} else {
- if (end) {
+ if (typeof end == 'number') {
return (pos >= start && pos <= end);
} else {
return pos == start;
@@ -4397,7 +4591,7 @@
try {
this.parseInput_(cm, inputStream, params);
} catch(e) {
- showConfirm(cm, e);
+ showConfirm(cm, e.toString());
throw e;
}
var command;
@@ -4441,7 +4635,7 @@
params.callback();
}
} catch(e) {
- showConfirm(cm, e);
+ showConfirm(cm, e.toString());
throw e;
}
},
@@ -4459,7 +4653,7 @@
}
// Parse command name.
- var commandMatch = inputStream.match(/^(\w+)/);
+ var commandMatch = inputStream.match(/^(\w+|!!|@@|[!#&*<=>@~])/);
if (commandMatch) {
result.commandName = commandMatch[1];
} else {
@@ -4713,12 +4907,12 @@
registers: function(cm, params) {
var regArgs = params.args;
var registers = vimGlobalState.registerController.registers;
- var regInfo = '----------Registers----------<br><br>';
+ var regInfo = '----------Registers----------\n\n';
if (!regArgs) {
for (var registerName in registers) {
var text = registers[registerName].toString();
if (text.length) {
- regInfo += '"' + registerName + ' ' + text + '<br>';
+ regInfo += '"' + registerName + ' ' + text + '\n'
}
}
} else {
@@ -4730,7 +4924,7 @@
continue;
}
var register = registers[registerName] || new Register();
- regInfo += '"' + registerName + ' ' + register.toString() + '<br>';
+ regInfo += '"' + registerName + ' ' + register.toString() + '\n'
}
}
showConfirm(cm, regInfo);
@@ -4825,6 +5019,10 @@
}
cm.replaceRange(text.join('\n'), curStart, curEnd);
},
+ vglobal: function(cm, params) {
+ // global inspects params.commandName
+ this.global(cm, params);
+ },
global: function(cm, params) {
// a global command is of the form
// :[range]g/pattern/[cmd]
@@ -4834,6 +5032,7 @@
showConfirm(cm, 'Regular Expression missing from global');
return;
}
+ var inverted = params.commandName[0] === 'v';
// range is specified here
var lineStart = (params.line !== undefined) ? params.line : cm.firstLine();
var lineEnd = params.lineEnd || params.line || cm.lastLine();
@@ -4858,28 +5057,33 @@
// now that we have the regexPart, search for regex matches in the
// specified range of lines
var query = getSearchState(cm).getQuery();
- var matchedLines = [], content = '';
+ var matchedLines = [];
for (var i = lineStart; i <= lineEnd; i++) {
- var matched = query.test(cm.getLine(i));
- if (matched) {
- matchedLines.push(i+1);
- content+= cm.getLine(i) + '<br>';
+ var line = cm.getLineHandle(i);
+ var matched = query.test(line.text);
+ if (matched !== inverted) {
+ matchedLines.push(cmd ? line : line.text);
}
}
// if there is no [cmd], just display the list of matched lines
if (!cmd) {
- showConfirm(cm, content);
+ showConfirm(cm, matchedLines.join('\n'));
return;
}
var index = 0;
var nextCommand = function() {
if (index < matchedLines.length) {
- var command = matchedLines[index] + cmd;
+ var line = matchedLines[index++];
+ var lineNum = cm.getLineNumber(line);
+ if (lineNum == null) {
+ nextCommand();
+ return;
+ }
+ var command = (lineNum + 1) + cmd;
exCommandDispatcher.processCommand(cm, command, {
callback: nextCommand
});
}
- index++;
};
nextCommand();
},
@@ -4899,9 +5103,11 @@
regexPart = new RegExp(regexPart).source; //normalize not escaped characters
}
replacePart = tokens[1];
- if (regexPart && regexPart[regexPart.length - 1] === '$') {
- regexPart = regexPart.slice(0, regexPart.length - 1) + '\\n';
- replacePart = replacePart ? replacePart + '\n' : '\n';
+ // If the pattern ends with $ (line boundary assertion), change $ to \n.
+ // Caveat: this workaround cannot match on the last line of the document.
+ if (/(^|[^\\])(\\\\)*\$$/.test(regexPart)) {
+ regexPart = regexPart.slice(0, -1) + '\\n';
+ replacePart = (replacePart || '') + '\n';
}
if (replacePart !== undefined) {
if (getOption('pcre')) {
@@ -4930,11 +5136,9 @@
if (flagsPart) {
if (flagsPart.indexOf('c') != -1) {
confirm = true;
- flagsPart.replace('c', '');
}
if (flagsPart.indexOf('g') != -1) {
global = true;
- flagsPart.replace('g', '');
}
if (getOption('pcre')) {
regexPart = regexPart + '/' + flagsPart;
@@ -5067,7 +5271,7 @@
* @param {Cursor} lineEnd Line to stop replacing at.
* @param {RegExp} query Query for performing matches with.
* @param {string} replaceWith Text to replace matches with. May contain $1,
- * $2, etc for replacing captured groups using Javascript replace.
+ * $2, etc for replacing captured groups using JavaScript replace.
* @param {function()} callback A callback for when the replace is done.
*/
function doReplace(cm, confirm, global, lineStart, lineEnd, searchCursor, query,
@@ -5075,7 +5279,7 @@
// Set up all the functions.
cm.state.vim.exMode = true;
var done = false;
- var lastPos = searchCursor.from();
+ var lastPos, modifiedLineNumber, joined;
function replaceAll() {
cm.operation(function() {
while (!done) {
@@ -5088,14 +5292,18 @@
function replace() {
var text = cm.getRange(searchCursor.from(), searchCursor.to());
var newText = text.replace(query, replaceWith);
+ var unmodifiedLineNumber = searchCursor.to().line;
searchCursor.replace(newText);
+ modifiedLineNumber = searchCursor.to().line;
+ lineEnd += modifiedLineNumber - unmodifiedLineNumber;
+ joined = modifiedLineNumber < unmodifiedLineNumber;
}
function next() {
// The below only loops to skip over multiple occurrences on the same
// line when 'global' is not true.
while(searchCursor.findNext() &&
isInRange(searchCursor.from(), lineStart, lineEnd)) {
- if (!global && lastPos && searchCursor.from().line == lastPos.line) {
+ if (!global && searchCursor.from().line == modifiedLineNumber && !joined) {
continue;
}
cm.scrollIntoView(searchCursor.from(), 30);
@@ -5160,7 +5368,7 @@
return;
}
showPrompt(cm, {
- prefix: 'replace with <strong>' + replaceWith + '</strong> (y/n/a/q/l)',
+ prefix: dom('span', 'replace with ', dom('strong', replaceWith), ' (y/n/a/q/l)'),
onKeyDown: onPromptKeyDown
});
}
@@ -5357,14 +5565,32 @@
updateFakeCursor(cm);
}
}
+ /**
+ * Keeps track of a fake cursor to support visual mode cursor behavior.
+ */
function updateFakeCursor(cm) {
+ var className = 'cm-animate-fat-cursor';
var vim = cm.state.vim;
var from = clipCursorToContent(cm, copyCursor(vim.sel.head));
var to = offsetCursor(from, 0, 1);
+ clearFakeCursor(vim);
+ // In visual mode, the cursor may be positioned over EOL.
+ if (from.ch == cm.getLine(from.line).length) {
+ var widget = dom('span', { 'class': className }, '\u00a0');
+ vim.fakeCursorBookmark = cm.setBookmark(from, {widget: widget});
+ } else {
+ vim.fakeCursor = cm.markText(from, to, {className: className});
+ }
+ }
+ function clearFakeCursor(vim) {
if (vim.fakeCursor) {
vim.fakeCursor.clear();
+ vim.fakeCursor = null;
+ }
+ if (vim.fakeCursorBookmark) {
+ vim.fakeCursorBookmark.clear();
+ vim.fakeCursorBookmark = null;
}
- vim.fakeCursor = cm.markText(from, to, {className: 'cm-animate-fat-cursor'});
}
function handleExternalSelection(cm, vim) {
var anchor = cm.getCursor('anchor');
diff --git a/help3/xhpeditor/cm/lib/codemirror.css b/help3/xhpeditor/cm/lib/codemirror.css
index bc910fb9..a64f97c7 100644
--- a/help3/xhpeditor/cm/lib/codemirror.css
+++ b/help3/xhpeditor/cm/lib/codemirror.css
@@ -164,17 +164,17 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #a22;}
.CodeMirror-scroll {
overflow: scroll !important; /* Things will break if this is overridden */
- /* 30px is the magic margin used to hide the element's real scrollbars */
+ /* 50px is the magic margin used to hide the element's real scrollbars */
/* See overflow: hidden in .CodeMirror */
- margin-bottom: -30px; margin-right: -30px;
- padding-bottom: 30px;
+ margin-bottom: -50px; margin-right: -50px;
+ padding-bottom: 50px;
height: 100%;
outline: none; /* Prevent dragging from highlighting the element */
position: relative;
}
.CodeMirror-sizer {
position: relative;
- border-right: 30px solid transparent;
+ border-right: 50px solid transparent;
}
/* The fake, visible scrollbars. Used to force redraw during scrolling
@@ -184,6 +184,7 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #a22;}
position: absolute;
z-index: 6;
display: none;
+ outline: none;
}
.CodeMirror-vscrollbar {
right: 0; top: 0;
@@ -212,7 +213,7 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #a22;}
height: 100%;
display: inline-block;
vertical-align: top;
- margin-bottom: -30px;
+ margin-bottom: -50px;
}
.CodeMirror-gutter-wrapper {
position: absolute;
diff --git a/help3/xhpeditor/cm/lib/codemirror.js b/help3/xhpeditor/cm/lib/codemirror.js
index 72267f69..42c068c2 100644
--- a/help3/xhpeditor/cm/lib/codemirror.js
+++ b/help3/xhpeditor/cm/lib/codemirror.js
@@ -10,7 +10,7 @@
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
- (global.CodeMirror = factory());
+ (global = global || self, global.CodeMirror = factory());
}(this, (function () { 'use strict';
// Kludges for bugs and behavior differences that can't be feature
@@ -32,7 +32,7 @@
var mac_geMountainLion = /Mac OS X 1\d\D([8-9]|\d\d)\D/.test(userAgent);
var phantom = /PhantomJS/.test(userAgent);
- var ios = !edge && /AppleWebKit/.test(userAgent) && /Mobile\/\w+/.test(userAgent);
+ var ios = safari && (/Mobile\/\w+/.test(userAgent) || navigator.maxTouchPoints > 2);
var android = /Android/.test(userAgent);
// This is woefully incomplete. Suggestions for alternative methods welcome.
var mobile = ios || android || /webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(userAgent);
@@ -204,7 +204,7 @@
}
// Number of pixels added to scroller and sizer to hide scrollbar
- var scrollerGap = 30;
+ var scrollerGap = 50;
// Returned or thrown by various protocols to signal 'I'm not
// handling this'.
@@ -485,14 +485,15 @@
for (++i$7; i$7 < len && countsAsLeft.test(types[i$7]); ++i$7) {}
order.push(new BidiSpan(0, start, i$7));
} else {
- var pos = i$7, at = order.length;
+ var pos = i$7, at = order.length, isRTL = direction == "rtl" ? 1 : 0;
for (++i$7; i$7 < len && types[i$7] != "L"; ++i$7) {}
for (var j$2 = pos; j$2 < i$7;) {
if (countsAsNum.test(types[j$2])) {
- if (pos < j$2) { order.splice(at, 0, new BidiSpan(1, pos, j$2)); }
+ if (pos < j$2) { order.splice(at, 0, new BidiSpan(1, pos, j$2)); at += isRTL; }
var nstart = j$2;
for (++j$2; j$2 < i$7 && countsAsNum.test(types[j$2]); ++j$2) {}
order.splice(at, 0, new BidiSpan(2, nstart, j$2));
+ at += isRTL;
pos = j$2;
} else { ++j$2; }
}
@@ -536,8 +537,8 @@
} else if (emitter.attachEvent) {
emitter.attachEvent("on" + type, f);
} else {
- var map$$1 = emitter._handlers || (emitter._handlers = {});
- map$$1[type] = (map$$1[type] || noHandlers).concat(f);
+ var map = emitter._handlers || (emitter._handlers = {});
+ map[type] = (map[type] || noHandlers).concat(f);
}
};
@@ -551,11 +552,11 @@
} else if (emitter.detachEvent) {
emitter.detachEvent("on" + type, f);
} else {
- var map$$1 = emitter._handlers, arr = map$$1 && map$$1[type];
+ var map = emitter._handlers, arr = map && map[type];
if (arr) {
var index = indexOf(arr, f);
if (index > -1)
- { map$$1[type] = arr.slice(0, index).concat(arr.slice(index + 1)); }
+ { map[type] = arr.slice(0, index).concat(arr.slice(index + 1)); }
}
}
}
@@ -683,11 +684,11 @@
try { return te.selectionStart != te.selectionEnd }
catch(e) { return false }
} : function (te) {
- var range$$1;
- try {range$$1 = te.ownerDocument.selection.createRange();}
+ var range;
+ try {range = te.ownerDocument.selection.createRange();}
catch(e) {}
- if (!range$$1 || range$$1.parentElement() != te) { return false }
- return range$$1.compareEndPoints("StartToEnd", range$$1) != 0
+ if (!range || range.parentElement() != te) { return false }
+ return range.compareEndPoints("StartToEnd", range) != 0
};
var hasCopyEvent = (function () {
@@ -835,10 +836,8 @@
return this.pos > start
};
StringStream.prototype.eatSpace = function () {
- var this$1 = this;
-
var start = this.pos;
- while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) { ++this$1.pos; }
+ while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) { ++this.pos; }
return this.pos > start
};
StringStream.prototype.skipToEnd = function () {this.pos = this.string.length;};
@@ -1034,11 +1033,9 @@
};
Context.prototype.baseToken = function (n) {
- var this$1 = this;
-
if (!this.baseTokens) { return null }
while (this.baseTokens[this.baseTokenPos] <= n)
- { this$1.baseTokenPos += 2; }
+ { this.baseTokenPos += 2; }
var type = this.baseTokens[this.baseTokenPos + 1];
return {type: type && type.replace(/( |^)overlay .*/, ""),
size: this.baseTokens[this.baseTokenPos] - n}
@@ -1204,7 +1201,7 @@
var prop = lineClass[1] ? "bgClass" : "textClass";
if (output[prop] == null)
{ output[prop] = lineClass[2]; }
- else if (!(new RegExp("(?:^|\s)" + lineClass[2] + "(?:$|\s)")).test(output[prop]))
+ else if (!(new RegExp("(?:^|\\s)" + lineClass[2] + "(?:$|\\s)")).test(output[prop]))
{ output[prop] += " " + lineClass[2]; }
} }
return type
@@ -1314,6 +1311,7 @@
if (span.marker == marker) { return span }
} }
}
+
// Remove a span from an array, returning undefined if no spans are
// left (we don't store arrays for lines without spans).
function removeMarkedSpan(spans, span) {
@@ -1322,9 +1320,16 @@
{ if (spans[i] != span) { (r || (r = [])).push(spans[i]); } }
return r
}
+
// Add a span to a line.
- function addMarkedSpan(line, span) {
- line.markedSpans = line.markedSpans ? line.markedSpans.concat([span]) : [span];
+ function addMarkedSpan(line, span, op) {
+ var inThisOp = op && window.WeakSet && (op.markedSpans || (op.markedSpans = new WeakSet));
+ if (inThisOp && inThisOp.has(line.markedSpans)) {
+ line.markedSpans.push(span);
+ } else {
+ line.markedSpans = line.markedSpans ? line.markedSpans.concat([span]) : [span];
+ if (inThisOp) { inThisOp.add(line.markedSpans); }
+ }
span.marker.attachLine(line);
}
@@ -1527,8 +1532,8 @@
// Test whether there exists a collapsed span that partially
// overlaps (covers the start or end, but not both) of a new span.
// Such overlap is not allowed.
- function conflictingCollapsedRange(doc, lineNo$$1, from, to, marker) {
- var line = getLine(doc, lineNo$$1);
+ function conflictingCollapsedRange(doc, lineNo, from, to, marker) {
+ var line = getLine(doc, lineNo);
var sps = sawCollapsedSpans && line.markedSpans;
if (sps) { for (var i = 0; i < sps.length; ++i) {
var sp = sps[i];
@@ -1844,7 +1849,7 @@
}
}
builder.trailingSpace = displayText.charCodeAt(text.length - 1) == 32;
- if (style || startStyle || endStyle || mustWrap || css) {
+ if (style || startStyle || endStyle || mustWrap || css || attributes) {
var fullStyle = style || "";
if (startStyle) { fullStyle += startStyle; }
if (endStyle) { fullStyle += endStyle; }
@@ -2189,6 +2194,7 @@
if (cm.options.lineNumbers || markers) {
var wrap$1 = ensureLineWrapped(lineView);
var gutterWrap = lineView.gutter = elt("div", null, "CodeMirror-gutter-wrapper", ("left: " + (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px"));
+ gutterWrap.setAttribute("aria-hidden", "true");
cm.display.input.setUneditable(gutterWrap);
wrap$1.insertBefore(gutterWrap, lineView.text);
if (lineView.line.gutterClass)
@@ -2430,36 +2436,36 @@
var nullRect = {left: 0, right: 0, top: 0, bottom: 0};
- function nodeAndOffsetInLineMap(map$$1, ch, bias) {
+ function nodeAndOffsetInLineMap(map, ch, bias) {
var node, start, end, collapse, mStart, mEnd;
// First, search the line map for the text node corresponding to,
// or closest to, the target character.
- for (var i = 0; i < map$$1.length; i += 3) {
- mStart = map$$1[i];
- mEnd = map$$1[i + 1];
+ for (var i = 0; i < map.length; i += 3) {
+ mStart = map[i];
+ mEnd = map[i + 1];
if (ch < mStart) {
start = 0; end = 1;
collapse = "left";
} else if (ch < mEnd) {
start = ch - mStart;
end = start + 1;
- } else if (i == map$$1.length - 3 || ch == mEnd && map$$1[i + 3] > ch) {
+ } else if (i == map.length - 3 || ch == mEnd && map[i + 3] > ch) {
end = mEnd - mStart;
start = end - 1;
if (ch >= mEnd) { collapse = "right"; }
}
if (start != null) {
- node = map$$1[i + 2];
+ node = map[i + 2];
if (mStart == mEnd && bias == (node.insertLeft ? "left" : "right"))
{ collapse = bias; }
if (bias == "left" && start == 0)
- { while (i && map$$1[i - 2] == map$$1[i - 3] && map$$1[i - 1].insertLeft) {
- node = map$$1[(i -= 3) + 2];
+ { while (i && map[i - 2] == map[i - 3] && map[i - 1].insertLeft) {
+ node = map[(i -= 3) + 2];
collapse = "left";
} }
if (bias == "right" && start == mEnd - mStart)
- { while (i < map$$1.length - 3 && map$$1[i + 3] == map$$1[i + 4] && !map$$1[i + 5].insertLeft) {
- node = map$$1[(i += 3) + 2];
+ { while (i < map.length - 3 && map[i + 3] == map[i + 4] && !map[i + 5].insertLeft) {
+ node = map[(i += 3) + 2];
collapse = "right";
} }
break
@@ -2742,13 +2748,13 @@
return box.bottom <= y ? false : box.top > y ? true : (left ? box.left : box.right) > x
}
- function coordsCharInner(cm, lineObj, lineNo$$1, x, y) {
+ function coordsCharInner(cm, lineObj, lineNo, x, y) {
// Move y into line-local coordinate space
y -= heightAtLine(lineObj);
var preparedMeasure = prepareMeasureForLine(cm, lineObj);
// When directly calling `measureCharPrepared`, we have to adjust
// for the widgets at this line.
- var widgetHeight$$1 = widgetTopHeight(lineObj);
+ var widgetHeight = widgetTopHeight(lineObj);
var begin = 0, end = lineObj.text.length, ltr = true;
var order = getOrder(lineObj, cm.doc.direction);
@@ -2756,7 +2762,7 @@
// which bidi section the coordinates fall into.
if (order) {
var part = (cm.options.lineWrapping ? coordsBidiPartWrapped : coordsBidiPart)
- (cm, lineObj, lineNo$$1, preparedMeasure, order, x, y);
+ (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,
@@ -2772,7 +2778,7 @@
var chAround = null, boxAround = null;
var ch = findFirst(function (ch) {
var box = measureCharPrepared(cm, preparedMeasure, ch);
- box.top += widgetHeight$$1; box.bottom += widgetHeight$$1;
+ box.top += widgetHeight; box.bottom += widgetHeight;
if (!boxIsAfter(box, x, y, false)) { return false }
if (box.top <= y && box.left <= x) {
chAround = ch;
@@ -2796,27 +2802,27 @@
// 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$$1 <= y) == ltr ?
+ (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$$1, ch, sticky), "line", lineObj, preparedMeasure);
+ var coords = cursorCoords(cm, Pos(lineNo, ch, sticky), "line", lineObj, preparedMeasure);
baseX = coords.left;
outside = y < coords.top ? -1 : y >= coords.bottom ? 1 : 0;
}
ch = skipExtendingChars(lineObj.text, ch, 1);
- return PosWithInfo(lineNo$$1, ch, sticky, outside, x - baseX)
+ return PosWithInfo(lineNo, ch, sticky, outside, x - baseX)
}
- function coordsBidiPart(cm, lineObj, lineNo$$1, preparedMeasure, order, x, y) {
+ 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$$1, ltr ? part.to : part.from, ltr ? "before" : "after"),
+ 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];
@@ -2825,7 +2831,7 @@
// that start, move one part back.
if (index > 0) {
var ltr = part.level != 1;
- var start = cursorCoords(cm, Pos(lineNo$$1, ltr ? part.from : part.to, ltr ? "after" : "before"),
+ 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]; }
@@ -2963,7 +2969,7 @@
var x, y, space = display.lineSpace.getBoundingClientRect();
// Fails unpredictably on IE[67] when mouse is dragged around quickly.
try { x = e.clientX - space.left; y = e.clientY - space.top; }
- catch (e) { return null }
+ catch (e$1) { return null }
var coords = coordsChar(cm, x, y), line;
if (forRect && coords.xRel > 0 && (line = getLine(cm.doc, coords.line).text).length == coords.ch) {
var colDiff = countColumn(line, line.length, cm.options.tabSize) - line.length;
@@ -3146,13 +3152,13 @@
for (var i = 0; i < doc.sel.ranges.length; i++) {
if (!primary && i == doc.sel.primIndex) { continue }
- var range$$1 = doc.sel.ranges[i];
- if (range$$1.from().line >= cm.display.viewTo || range$$1.to().line < cm.display.viewFrom) { continue }
- var collapsed = range$$1.empty();
+ var range = doc.sel.ranges[i];
+ if (range.from().line >= cm.display.viewTo || range.to().line < cm.display.viewFrom) { continue }
+ var collapsed = range.empty();
if (collapsed || cm.options.showCursorWhenSelecting)
- { drawSelectionCursor(cm, range$$1.head, curFragment); }
+ { drawSelectionCursor(cm, range.head, curFragment); }
if (!collapsed)
- { drawSelectionRange(cm, range$$1, selFragment); }
+ { drawSelectionRange(cm, range, selFragment); }
}
return result
}
@@ -3179,7 +3185,7 @@
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$$1, output) {
+ function drawSelectionRange(cm, range, output) {
var display = cm.display, doc = cm.doc;
var fragment = document.createDocumentFragment();
var padding = paddingH(cm.display), leftSide = padding.left;
@@ -3248,7 +3254,7 @@
return {start: start, end: end}
}
- var sFrom = range$$1.from(), sTo = range$$1.to();
+ var sFrom = range.from(), sTo = range.to();
if (sFrom.line == sTo.line) {
drawForLine(sFrom.line, sFrom.ch, sTo.ch);
} else {
@@ -3279,26 +3285,31 @@
var on = true;
display.cursorDiv.style.visibility = "";
if (cm.options.cursorBlinkRate > 0)
- { display.blinker = setInterval(function () { return display.cursorDiv.style.visibility = (on = !on) ? "" : "hidden"; },
- cm.options.cursorBlinkRate); }
+ { display.blinker = setInterval(function () {
+ if (!cm.hasFocus()) { onBlur(cm); }
+ display.cursorDiv.style.visibility = (on = !on) ? "" : "hidden";
+ }, cm.options.cursorBlinkRate); }
else if (cm.options.cursorBlinkRate < 0)
{ display.cursorDiv.style.visibility = "hidden"; }
}
function ensureFocus(cm) {
- if (!cm.state.focused) { cm.display.input.focus(); onFocus(cm); }
+ if (!cm.hasFocus()) {
+ cm.display.input.focus();
+ if (!cm.state.focused) { onFocus(cm); }
+ }
}
function delayBlurEvent(cm) {
cm.state.delayingBlurEvent = true;
setTimeout(function () { if (cm.state.delayingBlurEvent) {
cm.state.delayingBlurEvent = false;
- onBlur(cm);
+ if (cm.state.focused) { onBlur(cm); }
} }, 100);
}
function onFocus(cm, e) {
- if (cm.state.delayingBlurEvent) { cm.state.delayingBlurEvent = false; }
+ if (cm.state.delayingBlurEvent && !cm.state.draggingText) { cm.state.delayingBlurEvent = false; }
if (cm.options.readOnly == "nocursor") { return }
if (!cm.state.focused) {
@@ -3428,8 +3439,8 @@
// 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;
+ pos = pos.ch ? Pos(pos.line, pos.sticky == "before" ? pos.ch - 1 : pos.ch, "after") : pos;
}
for (var limit = 0; limit < 5; limit++) {
var changed = false;
@@ -3480,14 +3491,15 @@
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 gutterSpace = cm.options.fixedGutter ? 0 : display.gutters.offsetWidth;
+ var screenleft = cm.curOp && cm.curOp.scrollLeft != null ? cm.curOp.scrollLeft : display.scroller.scrollLeft - gutterSpace;
+ var screenw = displayWidth(cm) - display.gutters.offsetWidth;
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)); }
+ { result.scrollLeft = Math.max(0, rect.left + gutterSpace - (tooWide ? 0 : 10)); }
else if (rect.right > screenw + screenleft - 3)
{ result.scrollLeft = rect.right + (tooWide ? 0 : 10) - screenw; }
return result
@@ -3515,9 +3527,9 @@
if (y != null) { cm.curOp.scrollTop = y; }
}
- function scrollToRange(cm, range$$1) {
+ function scrollToRange(cm, range) {
resolveScrollToPos(cm);
- cm.curOp.scrollToPos = range$$1;
+ cm.curOp.scrollToPos = range;
}
// When an operation has its scrollToPos property set, and another
@@ -3525,11 +3537,11 @@
// '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$$1 = cm.curOp.scrollToPos;
- if (range$$1) {
+ var range = cm.curOp.scrollToPos;
+ if (range) {
cm.curOp.scrollToPos = null;
- var from = estimateCoords(cm, range$$1.from), to = estimateCoords(cm, range$$1.to);
- scrollToCoordsRange(cm, from, to, range$$1.margin);
+ var from = estimateCoords(cm, range.from), to = estimateCoords(cm, range.to);
+ scrollToCoordsRange(cm, from, to, range.margin);
}
}
@@ -3554,7 +3566,7 @@
}
function setScrollTop(cm, val, forceScroll) {
- val = Math.min(cm.display.scroller.scrollHeight - cm.display.scroller.clientHeight, val);
+ val = Math.max(0, 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);
@@ -3564,7 +3576,7 @@
// Sync scroller and scrollbar, ensure the gutter elements are
// aligned.
function setScrollLeft(cm, val, isScroller, forceScroll) {
- val = Math.min(val, cm.display.scroller.scrollWidth - cm.display.scroller.clientWidth);
+ val = Math.max(0, 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);
@@ -3676,9 +3688,9 @@
// (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$$1 = type == "vert" ? document.elementFromPoint(box.right - 1, (box.top + box.bottom) / 2)
+ 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$$1 != bar) { bar.style.pointerEvents = "none"; }
+ if (elt != bar) { bar.style.pointerEvents = "none"; }
else { delay.set(1000, maybeDisable); }
}
delay.set(1000, maybeDisable);
@@ -3779,7 +3791,8 @@
scrollLeft: null, scrollTop: null, // Intermediate scroll position, not pushed to DOM yet
scrollToPos: null, // Used to scroll to a specific position
focus: false,
- id: ++nextOpId // Unique ID
+ id: ++nextOpId, // Unique ID
+ markArrays: null // Used by addMarkedSpan
};
pushOperation(cm.curOp);
}
@@ -4018,10 +4031,8 @@
{ this.events.push(arguments); }
};
DisplayUpdate.prototype.finish = function () {
- var this$1 = this;
-
for (var i = 0; i < this.events.length; i++)
- { signal.apply(null, this$1.events[i]); }
+ { signal.apply(null, this.events[i]); }
};
function maybeClipScrollbars(cm) {
@@ -4055,12 +4066,13 @@
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$$1 = document.createRange();
- range$$1.setEnd(snapshot.anchorNode, snapshot.anchorOffset);
- range$$1.collapse(false);
+ if (!/^(INPUT|TEXTAREA)$/.test(snapshot.activeElt.nodeName) &&
+ 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$$1);
+ sel.addRange(range);
sel.extend(snapshot.focusNode, snapshot.focusOffset);
}
}
@@ -4153,6 +4165,8 @@
update.visible = visibleLines(cm.display, cm.doc, viewport);
if (update.visible.from >= cm.display.viewFrom && update.visible.to <= cm.display.viewTo)
{ break }
+ } else if (first) {
+ update.visible = visibleLines(cm.display, cm.doc, viewport);
}
if (!updateDisplayIfNeeded(cm, update)) { break }
updateHeightsInViewport(cm);
@@ -4231,6 +4245,8 @@
function updateGutterSpace(display) {
var width = display.gutters.offsetWidth;
display.sizer.style.marginLeft = width + "px";
+ // Send an event to consumers responding to changes in gutter width.
+ signalLater(display, "gutterChanged", display);
}
function setDocumentHeight(cm, measure) {
@@ -4553,40 +4569,32 @@
Selection.prototype.primary = function () { return this.ranges[this.primIndex] };
Selection.prototype.equals = function (other) {
- var this$1 = this;
-
if (other == this) { return true }
if (other.primIndex != this.primIndex || other.ranges.length != this.ranges.length) { return false }
for (var i = 0; i < this.ranges.length; i++) {
- var here = this$1.ranges[i], there = other.ranges[i];
+ var here = this.ranges[i], there = other.ranges[i];
if (!equalCursorPos(here.anchor, there.anchor) || !equalCursorPos(here.head, there.head)) { return false }
}
return true
};
Selection.prototype.deepCopy = function () {
- var this$1 = this;
-
var out = [];
for (var i = 0; i < this.ranges.length; i++)
- { out[i] = new Range(copyPos(this$1.ranges[i].anchor), copyPos(this$1.ranges[i].head)); }
+ { out[i] = new Range(copyPos(this.ranges[i].anchor), copyPos(this.ranges[i].head)); }
return new Selection(out, this.primIndex)
};
Selection.prototype.somethingSelected = function () {
- var this$1 = this;
-
for (var i = 0; i < this.ranges.length; i++)
- { if (!this$1.ranges[i].empty()) { return true } }
+ { if (!this.ranges[i].empty()) { return true } }
return false
};
Selection.prototype.contains = function (pos, end) {
- var this$1 = this;
-
if (!end) { end = pos; }
for (var i = 0; i < this.ranges.length; i++) {
- var range = this$1.ranges[i];
+ var range = this.ranges[i];
if (cmp(end, range.from()) >= 0 && cmp(pos, range.to()) <= 0)
{ return i }
}
@@ -4712,16 +4720,16 @@
}
// Perform a change on the document data structure.
- function updateDoc(doc, change, markedSpans, estimateHeight$$1) {
+ function updateDoc(doc, change, markedSpans, estimateHeight) {
function spansFor(n) {return markedSpans ? markedSpans[n] : null}
function update(line, text, spans) {
- updateLine(line, text, spans, estimateHeight$$1);
+ updateLine(line, text, spans, estimateHeight);
signalLater(line, "change", line, change);
}
function linesFor(start, end) {
var result = [];
for (var i = start; i < end; ++i)
- { result.push(new Line(text[i], spansFor(i), estimateHeight$$1)); }
+ { result.push(new Line(text[i], spansFor(i), estimateHeight)); }
return result
}
@@ -4745,7 +4753,7 @@
update(firstLine, firstLine.text.slice(0, from.ch) + lastText + firstLine.text.slice(to.ch), lastSpans);
} else {
var added$1 = linesFor(1, text.length - 1);
- added$1.push(new Line(lastText + firstLine.text.slice(to.ch), lastSpans, estimateHeight$$1));
+ added$1.push(new Line(lastText + firstLine.text.slice(to.ch), lastSpans, estimateHeight));
update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0));
doc.insert(from.line + 1, added$1);
}
@@ -4786,6 +4794,7 @@
estimateLineHeights(cm);
loadMode(cm);
setDirectionClass(cm);
+ cm.options.direction = doc.direction;
if (!cm.options.lineWrapping) { findMaxLine(cm); }
cm.options.mode = doc.modeOption;
regChange(cm);
@@ -4802,19 +4811,19 @@
});
}
- function History(startGen) {
+ function History(prev) {
// Arrays of change events and selections. Doing something adds an
// event to done and clears undo. Undoing moves events from done
// to undone, redoing moves them in the other direction.
this.done = []; this.undone = [];
- this.undoDepth = Infinity;
+ this.undoDepth = prev ? prev.undoDepth : Infinity;
// Used to track when changes can be merged into a single undo
// event
this.lastModTime = this.lastSelTime = 0;
this.lastOp = this.lastSelOp = null;
this.lastOrigin = this.lastSelOrigin = null;
// Used by the isClean() method
- this.generation = this.maxGeneration = startGen || 1;
+ this.generation = this.maxGeneration = prev ? prev.maxGeneration : 1;
}
// Create a history change event from an updateDoc-style change
@@ -5082,11 +5091,9 @@
var obj = {
ranges: sel.ranges,
update: function(ranges) {
- var this$1 = this;
-
this.ranges = [];
for (var i = 0; i < ranges.length; i++)
- { this$1.ranges[i] = new Range(clipPos(doc, ranges[i].anchor),
+ { this.ranges[i] = new Range(clipPos(doc, ranges[i].anchor),
clipPos(doc, ranges[i].head)); }
},
origin: options && options.origin
@@ -5121,7 +5128,7 @@
(cmp(sel.primary().head, doc.sel.primary().head) < 0 ? -1 : 1);
setSelectionInner(doc, skipAtomicInSelection(doc, sel, bias, true));
- if (!(options && options.scroll === false) && doc.cm)
+ if (!(options && options.scroll === false) && doc.cm && doc.cm.getOption("readOnly") != "nocursor")
{ ensureCursorVisible(doc.cm); }
}
@@ -5573,13 +5580,11 @@
// See also http://marijnhaverbeke.nl/blog/codemirror-line-tree.html
function LeafChunk(lines) {
- var this$1 = this;
-
this.lines = lines;
this.parent = null;
var height = 0;
for (var i = 0; i < lines.length; ++i) {
- lines[i].parent = this$1;
+ lines[i].parent = this;
height += lines[i].height;
}
this.height = height;
@@ -5590,11 +5595,9 @@
// Remove the n lines at offset 'at'.
removeInner: function(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;
+ var line = this.lines[i];
+ this.height -= line.height;
cleanUpLine(line);
signalLater(line, "delete");
}
@@ -5609,31 +5612,25 @@
// Insert the given array of lines at offset 'at', count them as
// having the given height.
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; }
+ for (var i = 0; i < lines.length; ++i) { lines[i].parent = this; }
},
// Used to iterate over a part of the tree.
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 } }
+ { if (op(this.lines[at])) { return true } }
}
};
function BranchChunk(children) {
- var this$1 = this;
-
this.children = children;
var size = 0, height = 0;
for (var i = 0; i < children.length; ++i) {
var ch = children[i];
size += ch.chunkSize(); height += ch.height;
- ch.parent = this$1;
+ ch.parent = this;
}
this.size = size;
this.height = height;
@@ -5644,16 +5641,14 @@
chunkSize: function() { return this.size },
removeInner: function(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();
+ var child = this.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; }
+ this.height -= oldHeight - child.height;
+ if (sz == rm) { this.children.splice(i--, 1); child.parent = null; }
if ((n -= rm) == 0) { break }
at = 0;
} else { at -= sz; }
@@ -5670,18 +5665,14 @@
},
collapse: function(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.children[i].collapse(lines); }
},
insertInner: function(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();
+ var child = this.children[i], sz = child.chunkSize();
if (at <= sz) {
child.insertInner(at, lines, height);
if (child.lines && child.lines.length > 50) {
@@ -5691,11 +5682,11 @@
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.children.splice(++i, 0, leaf);
+ leaf.parent = this;
}
child.lines = child.lines.slice(0, remaining);
- this$1.maybeSpill();
+ this.maybeSpill();
}
break
}
@@ -5727,10 +5718,8 @@
},
iterN: function(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();
+ var child = this.children[i], sz = child.chunkSize();
if (at < sz) {
var used = Math.min(n, sz - at);
if (child.iterN(at, used, op)) { return true }
@@ -5744,20 +5733,16 @@
// Line widgets are block elements displayed above or below a line.
var LineWidget = function(doc, node, options) {
- var this$1 = this;
-
if (options) { for (var opt in options) { if (options.hasOwnProperty(opt))
- { this$1[opt] = options[opt]; } } }
+ { this[opt] = options[opt]; } } }
this.doc = doc;
this.node = node;
};
LineWidget.prototype.clear = function () {
- var this$1 = this;
-
var cm = this.doc.cm, ws = this.line.widgets, line = this.line, no = lineNo(line);
if (no == null || !ws) { return }
- for (var i = 0; i < ws.length; ++i) { if (ws[i] == this$1) { ws.splice(i--, 1); } }
+ for (var i = 0; i < ws.length; ++i) { if (ws[i] == this) { ws.splice(i--, 1); } }
if (!ws.length) { line.widgets = null; }
var height = widgetHeight(this);
updateLineHeight(line, Math.max(0, line.height - height));
@@ -5800,7 +5785,7 @@
changeLine(doc, handle, "widget", function (line) {
var widgets = line.widgets || (line.widgets = []);
if (widget.insertAt == null) { widgets.push(widget); }
- else { widgets.splice(Math.min(widgets.length - 1, Math.max(0, widget.insertAt)), 0, widget); }
+ else { widgets.splice(Math.min(widgets.length, Math.max(0, widget.insertAt)), 0, widget); }
widget.line = line;
if (cm && !lineIsHidden(doc, line)) {
var aboveVisible = heightAtLine(line) < doc.scrollTop;
@@ -5840,8 +5825,6 @@
// Clear the marker.
TextMarker.prototype.clear = function () {
- var this$1 = this;
-
if (this.explicitlyCleared) { return }
var cm = this.doc.cm, withOp = cm && !cm.curOp;
if (withOp) { startOperation(cm); }
@@ -5851,19 +5834,19 @@
}
var min = null, max = null;
for (var i = 0; i < this.lines.length; ++i) {
- var line = this$1.lines[i];
- var span = getMarkedSpanFor(line.markedSpans, this$1);
- if (cm && !this$1.collapsed) { regLineChange(cm, lineNo(line), "text"); }
+ var line = this.lines[i];
+ var span = getMarkedSpanFor(line.markedSpans, this);
+ if (cm && !this.collapsed) { regLineChange(cm, lineNo(line), "text"); }
else if (cm) {
if (span.to != null) { max = lineNo(line); }
if (span.from != null) { min = lineNo(line); }
}
line.markedSpans = removeMarkedSpan(line.markedSpans, span);
- if (span.from == null && this$1.collapsed && !lineIsHidden(this$1.doc, line) && cm)
+ if (span.from == null && this.collapsed && !lineIsHidden(this.doc, line) && cm)
{ updateLineHeight(line, textHeight(cm.display)); }
}
if (cm && this.collapsed && !cm.options.lineWrapping) { for (var i$1 = 0; i$1 < this.lines.length; ++i$1) {
- var visual = visualLine(this$1.lines[i$1]), len = lineLength(visual);
+ var visual = visualLine(this.lines[i$1]), len = lineLength(visual);
if (len > cm.display.maxLineLength) {
cm.display.maxLine = visual;
cm.display.maxLineLength = len;
@@ -5889,13 +5872,11 @@
// Pos objects returned contain a line object, rather than a line
// number (used to prevent looking up the same line twice).
TextMarker.prototype.find = function (side, lineObj) {
- var this$1 = this;
-
if (side == null && this.type == "bookmark") { side = 1; }
var from, to;
for (var i = 0; i < this.lines.length; ++i) {
- var line = this$1.lines[i];
- var span = getMarkedSpanFor(line.markedSpans, this$1);
+ var line = this.lines[i];
+ var span = getMarkedSpanFor(line.markedSpans, this);
if (span.from != null) {
from = Pos(lineObj ? line : lineNo(line), span.from);
if (side == -1) { return from }
@@ -5990,7 +5971,7 @@
if (marker.collapsed && curLine != from.line) { updateLineHeight(line, 0); }
addMarkedSpan(line, new MarkedSpan(marker,
curLine == from.line ? from.ch : null,
- curLine == to.line ? to.ch : null));
+ curLine == to.line ? to.ch : null), doc.cm && doc.cm.curOp);
++curLine;
});
// lineIsHidden depends on the presence of the spans, so needs a second pass
@@ -6029,21 +6010,17 @@
// implemented as a meta-marker-object controlling multiple normal
// markers.
var SharedTextMarker = function(markers, primary) {
- var this$1 = this;
-
this.markers = markers;
this.primary = primary;
for (var i = 0; i < markers.length; ++i)
- { markers[i].parent = this$1; }
+ { markers[i].parent = this; }
};
SharedTextMarker.prototype.clear = function () {
- var this$1 = this;
-
if (this.explicitlyCleared) { return }
this.explicitlyCleared = true;
for (var i = 0; i < this.markers.length; ++i)
- { this$1.markers[i].clear(); }
+ { this.markers[i].clear(); }
signalLater(this, "clear");
};
@@ -6186,11 +6163,11 @@
clipPos: function(pos) {return clipPos(this, pos)},
getCursor: function(start) {
- var range$$1 = this.sel.primary(), pos;
- if (start == null || start == "head") { pos = range$$1.head; }
- else if (start == "anchor") { pos = range$$1.anchor; }
- else if (start == "end" || start == "to" || start === false) { pos = range$$1.to(); }
- else { pos = range$$1.from(); }
+ var range = this.sel.primary(), pos;
+ if (start == null || start == "head") { pos = range.head; }
+ else if (start == "anchor") { pos = range.anchor; }
+ else if (start == "end" || start == "to" || start === false) { pos = range.to(); }
+ else { pos = range.from(); }
return pos
},
listSelections: function() { return this.sel.ranges },
@@ -6213,13 +6190,11 @@
extendSelections(this, clipPosArray(this, heads), options);
}),
setSelections: docMethodOp(function(ranges, primary, options) {
- var this$1 = this;
-
if (!ranges.length) { return }
var out = [];
for (var i = 0; i < ranges.length; i++)
- { out[i] = new Range(clipPos(this$1, ranges[i].anchor),
- clipPos(this$1, ranges[i].head)); }
+ { out[i] = new Range(clipPos(this, ranges[i].anchor),
+ clipPos(this, ranges[i].head || ranges[i].anchor)); }
if (primary == null) { primary = Math.min(ranges.length - 1, this.sel.primIndex); }
setSelection(this, normalizeSelection(this.cm, out, primary), options);
}),
@@ -6230,23 +6205,19 @@
}),
getSelection: function(lineSep) {
- var this$1 = this;
-
var ranges = this.sel.ranges, lines;
for (var i = 0; i < ranges.length; i++) {
- var sel = getBetween(this$1, ranges[i].from(), ranges[i].to());
+ var sel = getBetween(this, ranges[i].from(), ranges[i].to());
lines = lines ? lines.concat(sel) : sel;
}
if (lineSep === false) { return lines }
else { return lines.join(lineSep || this.lineSeparator()) }
},
getSelections: function(lineSep) {
- var this$1 = this;
-
var parts = [], ranges = this.sel.ranges;
for (var i = 0; i < ranges.length; i++) {
- var sel = getBetween(this$1, ranges[i].from(), ranges[i].to());
- if (lineSep !== false) { sel = sel.join(lineSep || this$1.lineSeparator()); }
+ var sel = getBetween(this, ranges[i].from(), ranges[i].to());
+ if (lineSep !== false) { sel = sel.join(lineSep || this.lineSeparator()); }
parts[i] = sel;
}
return parts
@@ -6258,16 +6229,14 @@
this.replaceSelections(dup, collapse, origin || "+input");
},
replaceSelections: docMethodOp(function(code, collapse, origin) {
- var this$1 = this;
-
var changes = [], sel = this.sel;
for (var i = 0; i < sel.ranges.length; i++) {
- var range$$1 = sel.ranges[i];
- changes[i] = {from: range$$1.from(), to: range$$1.to(), text: this$1.splitLines(code[i]), origin: origin};
+ var range = sel.ranges[i];
+ changes[i] = {from: range.from(), to: range.to(), text: this.splitLines(code[i]), origin: origin};
}
var newSel = collapse && collapse != "end" && computeReplacedSel(this, changes, collapse);
for (var i$1 = changes.length - 1; i$1 >= 0; i$1--)
- { makeChange(this$1, changes[i$1]); }
+ { makeChange(this, changes[i$1]); }
if (newSel) { setSelectionReplaceHistory(this, newSel); }
else if (this.cm) { ensureCursorVisible(this.cm); }
}),
@@ -6288,7 +6257,7 @@
clearHistory: function() {
var this$1 = this;
- this.history = new History(this.history.maxGeneration);
+ this.history = new History(this.history);
linkedDocs(this, function (doc) { return doc.history = this$1.history; }, true);
},
@@ -6309,7 +6278,7 @@
undone: copyHistoryArray(this.history.undone)}
},
setHistory: function(histData) {
- var hist = this.history = new History(this.history.maxGeneration);
+ var hist = this.history = new History(this.history);
hist.done = copyHistoryArray(histData.done.slice(0), null, true);
hist.undone = copyHistoryArray(histData.undone.slice(0), null, true);
},
@@ -6411,18 +6380,18 @@
},
findMarks: function(from, to, filter) {
from = clipPos(this, from); to = clipPos(this, to);
- var found = [], lineNo$$1 = from.line;
+ var found = [], lineNo = from.line;
this.iter(from.line, to.line + 1, function (line) {
var spans = line.markedSpans;
if (spans) { for (var i = 0; i < spans.length; i++) {
var span = spans[i];
- if (!(span.to != null && lineNo$$1 == from.line && from.ch >= span.to ||
- span.from == null && lineNo$$1 != from.line ||
- span.from != null && lineNo$$1 == to.line && span.from >= to.ch) &&
+ if (!(span.to != null && lineNo == from.line && from.ch >= span.to ||
+ span.from == null && lineNo != from.line ||
+ span.from != null && lineNo == to.line && span.from >= to.ch) &&
(!filter || filter(span.marker)))
{ found.push(span.marker.parent || span.marker); }
} }
- ++lineNo$$1;
+ ++lineNo;
});
return found
},
@@ -6437,14 +6406,14 @@
},
posFromIndex: function(off) {
- var ch, lineNo$$1 = this.first, sepSize = this.lineSeparator().length;
+ var ch, lineNo = this.first, sepSize = this.lineSeparator().length;
this.iter(function (line) {
var sz = line.text.length + sepSize;
if (sz > off) { ch = off; return true }
off -= sz;
- ++lineNo$$1;
+ ++lineNo;
});
- return clipPos(this, Pos(lineNo$$1, ch))
+ return clipPos(this, Pos(lineNo, ch))
},
indexFromPos: function (coords) {
coords = clipPos(this, coords);
@@ -6483,15 +6452,13 @@
return copy
},
unlinkDoc: function(other) {
- var this$1 = this;
-
if (other instanceof CodeMirror) { other = other.doc; }
if (this.linked) { for (var i = 0; i < this.linked.length; ++i) {
- var link = this$1.linked[i];
+ var link = this.linked[i];
if (link.doc != other) { continue }
- this$1.linked.splice(i, 1);
- other.unlinkDoc(this$1);
- detachSharedMarkers(findSharedMarkers(this$1));
+ this.linked.splice(i, 1);
+ other.unlinkDoc(this);
+ detachSharedMarkers(findSharedMarkers(this));
break
} }
// If the histories were shared, split them again
@@ -6552,7 +6519,7 @@
text.filter(function (t) { return t != null; }).join(cm.doc.lineSeparator())),
origin: "paste"};
makeChange(cm.doc, change);
- setSelectionReplaceHistory(cm.doc, simpleSelection(pos, changeEnd(change)));
+ setSelectionReplaceHistory(cm.doc, simpleSelection(clipPos(cm.doc, pos), clipPos(cm.doc, changeEnd(change))));
})();
}
};
@@ -6597,7 +6564,7 @@
cm.display.input.focus();
}
}
- catch(e){}
+ catch(e$1){}
}
}
@@ -6693,7 +6660,7 @@
46: "Delete", 59: ";", 61: "=", 91: "Mod", 92: "Mod", 93: "Mod",
106: "*", 107: "=", 109: "-", 110: ".", 111: "/", 145: "ScrollLock",
173: "-", 186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\",
- 221: "]", 222: "'", 63232: "Up", 63233: "Down", 63234: "Left", 63235: "Right", 63272: "Delete",
+ 221: "]", 222: "'", 224: "Mod", 63232: "Up", 63233: "Down", 63234: "Left", 63235: "Right", 63272: "Delete",
63273: "Home", 63275: "End", 63276: "PageUp", 63277: "PageDown", 63302: "Insert"
};
@@ -6730,10 +6697,9 @@
// Very basic readline/emacs-style bindings, which are standard on Mac.
keyMap.emacsy = {
"Ctrl-F": "goCharRight", "Ctrl-B": "goCharLeft", "Ctrl-P": "goLineUp", "Ctrl-N": "goLineDown",
- "Alt-F": "goWordRight", "Alt-B": "goWordLeft", "Ctrl-A": "goLineStart", "Ctrl-E": "goLineEnd",
- "Ctrl-V": "goPageDown", "Shift-Ctrl-V": "goPageUp", "Ctrl-D": "delCharAfter", "Ctrl-H": "delCharBefore",
- "Alt-D": "delWordAfter", "Alt-Backspace": "delWordBefore", "Ctrl-K": "killLine", "Ctrl-T": "transposeChars",
- "Ctrl-O": "openLine"
+ "Ctrl-A": "goLineStart", "Ctrl-E": "goLineEnd", "Ctrl-V": "goPageDown", "Shift-Ctrl-V": "goPageUp",
+ "Ctrl-D": "delCharAfter", "Ctrl-H": "delCharBefore", "Alt-Backspace": "delWordBefore", "Ctrl-K": "killLine",
+ "Ctrl-T": "transposeChars", "Ctrl-O": "openLine"
};
keyMap.macDefault = {
"Cmd-A": "selectAll", "Cmd-D": "deleteLine", "Cmd-Z": "undo", "Shift-Cmd-Z": "redo", "Cmd-Y": "redo",
@@ -6800,18 +6766,18 @@
return keymap
}
- function lookupKey(key, map$$1, handle, context) {
- map$$1 = getKeyMap(map$$1);
- var found = map$$1.call ? map$$1.call(key, context) : map$$1[key];
+ function lookupKey(key, map, handle, context) {
+ map = getKeyMap(map);
+ var found = map.call ? map.call(key, context) : map[key];
if (found === false) { return "nothing" }
if (found === "...") { return "multi" }
if (found != null && handle(found)) { return "handled" }
- if (map$$1.fallthrough) {
- if (Object.prototype.toString.call(map$$1.fallthrough) != "[object Array]")
- { return lookupKey(key, map$$1.fallthrough, handle, context) }
- for (var i = 0; i < map$$1.fallthrough.length; i++) {
- var result = lookupKey(key, map$$1.fallthrough[i], handle, context);
+ if (map.fallthrough) {
+ if (Object.prototype.toString.call(map.fallthrough) != "[object Array]")
+ { return lookupKey(key, map.fallthrough, handle, context) }
+ for (var i = 0; i < map.fallthrough.length; i++) {
+ var result = lookupKey(key, map.fallthrough[i], handle, context);
if (result) { return result }
}
}
@@ -6828,7 +6794,7 @@
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; }
+ if ((flipCtrlCmd ? event.ctrlKey : event.metaKey) && base != "Mod") { name = "Cmd-" + name; }
if (!noShift && event.shiftKey && base != "Shift") { name = "Shift-" + name; }
return name
}
@@ -6885,7 +6851,7 @@
function endOfLine(visually, cm, lineObj, lineNo, dir) {
if (visually) {
- if (cm.getOption("direction") == "rtl") { dir = -dir; }
+ if (cm.doc.direction == "rtl") { dir = -dir; }
var order = getOrder(lineObj, cm.doc.direction);
if (order) {
var part = dir < 0 ? lst(order) : order[0];
@@ -7054,7 +7020,7 @@
goGroupRight: function (cm) { return cm.moveH(1, "group"); },
goGroupLeft: function (cm) { return cm.moveH(-1, "group"); },
goWordRight: function (cm) { return cm.moveH(1, "word"); },
- delCharBefore: function (cm) { return cm.deleteH(-1, "char"); },
+ delCharBefore: function (cm) { return cm.deleteH(-1, "codepoint"); },
delCharAfter: function (cm) { return cm.deleteH(1, "char"); },
delWordBefore: function (cm) { return cm.deleteH(-1, "word"); },
delWordAfter: function (cm) { return cm.deleteH(1, "word"); },
@@ -7140,7 +7106,7 @@
var line = getLine(cm.doc, start.line);
var order = getOrder(line, cm.doc.direction);
if (!order || order[0].level == 0) {
- var firstNonWS = Math.max(0, line.text.search(/\S/));
+ var firstNonWS = Math.max(start.ch, line.text.search(/\S/));
var inWS = pos.line == start.line && pos.ch <= firstNonWS && pos.ch;
return Pos(start.line, inWS ? 0 : firstNonWS, start.sticky)
}
@@ -7243,6 +7209,7 @@
var lastStoppedKey = null;
function onKeyDown(e) {
var cm = this;
+ if (e.target && e.target != cm.display.input.getField()) { return }
cm.curOp.focus = activeElt();
if (signalDOMEvent(cm, e)) { return }
// IE does strange things with escape.
@@ -7286,6 +7253,7 @@
function onKeyPress(e) {
var cm = this;
+ if (e.target && e.target != cm.display.input.getField()) { return }
if (eventInWidget(cm.display, e) || signalDOMEvent(cm, e) || e.ctrlKey && !e.altKey || mac && e.metaKey) { return }
var keyCode = e.keyCode, charCode = e.charCode;
if (presto && keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return}
@@ -7425,6 +7393,10 @@
var dragEnd = operation(cm, function (e) {
if (webkit) { display.scroller.draggable = false; }
cm.state.draggingText = false;
+ if (cm.state.delayingBlurEvent) {
+ if (cm.hasFocus()) { cm.state.delayingBlurEvent = false; }
+ else { delayBlurEvent(cm); }
+ }
off(display.wrapper.ownerDocument, "mouseup", dragEnd);
off(display.wrapper.ownerDocument, "mousemove", mouseMove);
off(display.scroller, "dragstart", dragStart);
@@ -7434,8 +7406,8 @@
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 () {display.wrapper.ownerDocument.body.focus(); display.input.focus();}, 20); }
+ if ((webkit && !safari) || ie && ie_version == 9)
+ { setTimeout(function () {display.wrapper.ownerDocument.body.focus({preventScroll: true}); display.input.focus();}, 20); }
else
{ display.input.focus(); }
}
@@ -7448,15 +7420,15 @@
if (webkit) { display.scroller.draggable = true; }
cm.state.draggingText = dragEnd;
dragEnd.copy = !behavior.moveOnDrag;
- // IE's approach to draggable
- if (display.scroller.dragDrop) { display.scroller.dragDrop(); }
on(display.wrapper.ownerDocument, "mouseup", dragEnd);
on(display.wrapper.ownerDocument, "mousemove", mouseMove);
on(display.scroller, "dragstart", dragStart);
on(display.scroller, "drop", dragEnd);
- delayBlurEvent(cm);
+ cm.state.delayingBlurEvent = true;
setTimeout(function () { return display.input.focus(); }, 20);
+ // IE's approach to draggable
+ if (display.scroller.dragDrop) { display.scroller.dragDrop(); }
}
function rangeForUnit(cm, pos, unit) {
@@ -7469,6 +7441,7 @@
// Normal selection, as opposed to text dragging.
function leftButtonSelect(cm, event, start, behavior) {
+ if (ie) { delayBlurEvent(cm); }
var display = cm.display, doc = cm.doc;
e_preventDefault(event);
@@ -7489,11 +7462,11 @@
start = posFromMouse(cm, event, true, true);
ourIndex = -1;
} else {
- var range$$1 = rangeForUnit(cm, start, behavior.unit);
+ var range = rangeForUnit(cm, start, behavior.unit);
if (behavior.extend)
- { ourRange = extendRange(ourRange, range$$1.anchor, range$$1.head, behavior.extend); }
+ { ourRange = extendRange(ourRange, range.anchor, range.head, behavior.extend); }
else
- { ourRange = range$$1; }
+ { ourRange = range; }
}
if (!behavior.addNew) {
@@ -7536,14 +7509,14 @@
cm.scrollIntoView(pos);
} else {
var oldRange = ourRange;
- var range$$1 = rangeForUnit(cm, pos, behavior.unit);
+ var range = rangeForUnit(cm, pos, behavior.unit);
var anchor = oldRange.anchor, head;
- if (cmp(range$$1.anchor, anchor) > 0) {
- head = range$$1.head;
- anchor = minPos(oldRange.from(), range$$1.anchor);
+ if (cmp(range.anchor, anchor) > 0) {
+ head = range.head;
+ anchor = minPos(oldRange.from(), range.anchor);
} else {
- head = range$$1.anchor;
- anchor = maxPos(oldRange.to(), range$$1.head);
+ head = range.anchor;
+ anchor = maxPos(oldRange.to(), range.head);
}
var ranges$1 = startSel.ranges.slice(0);
ranges$1[ourIndex] = bidiSimplify(cm, new Range(clipPos(doc, anchor), head));
@@ -7605,17 +7578,17 @@
// 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$$1) {
- var anchor = range$$1.anchor;
- var head = range$$1.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$$1 }
+ if (cmp(anchor, head) == 0 && anchor.sticky == head.sticky) { return range }
var order = getOrder(anchorLine);
- if (!order) { return range$$1 }
+ 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$$1 }
+ 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$$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)
@@ -7634,7 +7607,7 @@
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$$1 : new Range(new Pos(anchor.line, ch, sticky), head)
+ return anchor.ch == ch && anchor.sticky == sticky ? range : new Range(new Pos(anchor.line, ch, sticky), head)
}
@@ -7647,7 +7620,7 @@
mY = e.touches[0].clientY;
} else {
try { mX = e.clientX; mY = e.clientY; }
- catch(e) { return false }
+ catch(e$1) { return false }
}
if (mX >= Math.floor(cm.display.gutters.getBoundingClientRect().right)) { return false }
if (prevent) { e_preventDefault(e); }
@@ -7747,7 +7720,7 @@
for (var i = newBreaks.length - 1; i >= 0; i--)
{ replaceRange(cm.doc, val, newBreaks[i], Pos(newBreaks[i].line, newBreaks[i].ch + val.length)); }
});
- option("specialChars", /[\u0000-\u001f\u007f-\u009f\u00ad\u061c\u200b-\u200f\u2028\u2029\ufeff\ufff9-\ufffc]/g, function (cm, val, old) {
+ option("specialChars", /[\u0000-\u001f\u007f-\u009f\u00ad\u061c\u200b\u200e\u200f\u2028\u2029\ufeff\ufff9-\ufffc]/g, function (cm, val, old) {
cm.state.specialChars = new RegExp(val.source + (val.test("\t") ? "" : "|\t"), "g");
if (old != Init) { cm.refresh(); }
});
@@ -7811,6 +7784,12 @@
}
cm.display.input.readOnlyChanged(val);
});
+
+ option("screenReaderLabel", null, function (cm, val) {
+ val = (val === '') ? null : val;
+ cm.display.input.screenReaderLabelChanged(val);
+ });
+
option("disableInput", false, function (cm, val) {if (!val) { cm.display.input.reset(); }}, true);
option("dragDrop", true, dragDropChanged);
option("allowDropFileTypes", null);
@@ -7921,15 +7900,17 @@
attachDoc(this, doc);
if ((options.autofocus && !mobile) || this.hasFocus())
- { setTimeout(bind(onFocus, this), 20); }
+ { setTimeout(function () {
+ if (this$1.hasFocus() && !this$1.state.focused) { onFocus(this$1); }
+ }, 20); }
else
{ onBlur(this); }
for (var opt in optionHandlers) { if (optionHandlers.hasOwnProperty(opt))
- { optionHandlers[opt](this$1, options[opt], Init); } }
+ { optionHandlers[opt](this, options[opt], Init); } }
maybeUpdateLineNumberWidth(this);
if (options.finishInit) { options.finishInit(this); }
- for (var i = 0; i < initHooks.length; ++i) { initHooks[i](this$1); }
+ for (var i = 0; i < initHooks.length; ++i) { initHooks[i](this); }
endOperation(this);
// Suppress optimizelegibility in Webkit, since it breaks text
// measuring on line wrapping boundaries.
@@ -8154,14 +8135,14 @@
var updateInput = cm.curOp.updateInput;
// Normal behavior is to insert the new text into every selection
for (var i$1 = sel.ranges.length - 1; i$1 >= 0; i$1--) {
- var range$$1 = sel.ranges[i$1];
- var from = range$$1.from(), to = range$$1.to();
- if (range$$1.empty()) {
+ var range = sel.ranges[i$1];
+ var from = range.from(), to = range.to();
+ if (range.empty()) {
if (deleted && deleted > 0) // Handle deletion
{ from = Pos(from.line, from.ch - deleted); }
else if (cm.state.overwrite && !paste) // Handle overwrite
{ to = Pos(to.line, Math.min(getLine(doc, to.line).text.length, to.ch + lst(textLines).length)); }
- else if (paste && lastCopied && lastCopied.lineWise && lastCopied.text.join("\n") == inserted)
+ else if (paste && lastCopied && lastCopied.lineWise && lastCopied.text.join("\n") == textLines.join("\n"))
{ from = to = Pos(from.line, 0); }
}
var changeEvent = {from: from, to: to, text: multiPaste ? multiPaste[i$1 % multiPaste.length] : textLines,
@@ -8194,21 +8175,21 @@
var sel = cm.doc.sel;
for (var i = sel.ranges.length - 1; i >= 0; i--) {
- var range$$1 = sel.ranges[i];
- if (range$$1.head.ch > 100 || (i && sel.ranges[i - 1].head.line == range$$1.head.line)) { continue }
- var mode = cm.getModeAt(range$$1.head);
+ var range = sel.ranges[i];
+ if (range.head.ch > 100 || (i && sel.ranges[i - 1].head.line == range.head.line)) { continue }
+ var mode = cm.getModeAt(range.head);
var indented = false;
if (mode.electricChars) {
for (var j = 0; j < mode.electricChars.length; j++)
{ if (inserted.indexOf(mode.electricChars.charAt(j)) > -1) {
- indented = indentLine(cm, range$$1.head.line, "smart");
+ indented = indentLine(cm, range.head.line, "smart");
break
} }
} else if (mode.electricInput) {
- if (mode.electricInput.test(getLine(cm.doc, range$$1.head.line).text.slice(0, range$$1.head.ch)))
- { indented = indentLine(cm, range$$1.head.line, "smart"); }
+ if (mode.electricInput.test(getLine(cm.doc, range.head.line).text.slice(0, range.head.ch)))
+ { indented = indentLine(cm, range.head.line, "smart"); }
}
- if (indented) { signalLater(cm, "electricInput", cm, range$$1.head.line); }
+ if (indented) { signalLater(cm, "electricInput", cm, range.head.line); }
}
}
@@ -8273,13 +8254,13 @@
getOption: function(option) {return this.options[option]},
getDoc: function() {return this.doc},
- addKeyMap: function(map$$1, bottom) {
- this.state.keyMaps[bottom ? "push" : "unshift"](getKeyMap(map$$1));
+ addKeyMap: function(map, bottom) {
+ this.state.keyMaps[bottom ? "push" : "unshift"](getKeyMap(map));
},
- removeKeyMap: function(map$$1) {
+ removeKeyMap: function(map) {
var maps = this.state.keyMaps;
for (var i = 0; i < maps.length; ++i)
- { if (maps[i] == map$$1 || maps[i].name == map$$1) {
+ { if (maps[i] == map || maps[i].name == map) {
maps.splice(i, 1);
return true
} }
@@ -8296,15 +8277,13 @@
regChange(this);
}),
removeOverlay: methodOp(function(spec) {
- var this$1 = this;
-
var overlays = this.state.overlays;
for (var i = 0; i < overlays.length; ++i) {
var cur = overlays[i].modeSpec;
if (cur == spec || typeof spec == "string" && cur.name == spec) {
overlays.splice(i, 1);
- this$1.state.modeGen++;
- regChange(this$1);
+ this.state.modeGen++;
+ regChange(this);
return
}
}
@@ -8318,24 +8297,22 @@
if (isLine(this.doc, n)) { indentLine(this, n, dir, aggressive); }
}),
indentSelection: methodOp(function(how) {
- var this$1 = this;
-
var ranges = this.doc.sel.ranges, end = -1;
for (var i = 0; i < ranges.length; i++) {
- var range$$1 = ranges[i];
- if (!range$$1.empty()) {
- var from = range$$1.from(), to = range$$1.to();
+ var range = ranges[i];
+ if (!range.empty()) {
+ var from = range.from(), to = range.to();
var start = Math.max(end, from.line);
- end = Math.min(this$1.lastLine(), to.line - (to.ch ? 0 : 1)) + 1;
+ end = Math.min(this.lastLine(), to.line - (to.ch ? 0 : 1)) + 1;
for (var j = start; j < end; ++j)
- { indentLine(this$1, j, how); }
- var newRanges = this$1.doc.sel.ranges;
+ { indentLine(this, j, how); }
+ var newRanges = this.doc.sel.ranges;
if (from.ch == 0 && ranges.length == newRanges.length && newRanges[i].from().ch > 0)
- { replaceOneSelection(this$1.doc, i, new Range(from, newRanges[i].to()), sel_dontScroll); }
- } else if (range$$1.head.line > end) {
- indentLine(this$1, range$$1.head.line, how, true);
- end = range$$1.head.line;
- if (i == this$1.doc.sel.primIndex) { ensureCursorVisible(this$1); }
+ { replaceOneSelection(this.doc, i, new Range(from, newRanges[i].to()), sel_dontScroll); }
+ } else if (range.head.line > end) {
+ indentLine(this, range.head.line, how, true);
+ end = range.head.line;
+ if (i == this.doc.sel.primIndex) { ensureCursorVisible(this); }
}
}
}),
@@ -8377,8 +8354,6 @@
},
getHelpers: function(pos, type) {
- var this$1 = this;
-
var found = [];
if (!helpers.hasOwnProperty(type)) { return found }
var help = helpers[type], mode = this.getModeAt(pos);
@@ -8396,7 +8371,7 @@
}
for (var i$1 = 0; i$1 < help._global.length; i$1++) {
var cur = help._global[i$1];
- if (cur.pred(mode, this$1) && indexOf(found, cur.val) == -1)
+ if (cur.pred(mode, this) && indexOf(found, cur.val) == -1)
{ found.push(cur.val); }
}
return found
@@ -8409,10 +8384,10 @@
},
cursorCoords: function(start, mode) {
- var pos, range$$1 = this.doc.sel.primary();
- if (start == null) { pos = range$$1.head; }
+ var pos, range = this.doc.sel.primary();
+ if (start == null) { pos = range.head; }
else if (typeof start == "object") { pos = clipPos(this.doc, start); }
- else { pos = start ? range$$1.from() : range$$1.to(); }
+ else { pos = start ? range.from() : range.to(); }
return cursorCoords(this, pos, mode || "page")
},
@@ -8496,13 +8471,11 @@
triggerElectric: methodOp(function(text) { triggerElectric(this, text); }),
findPosH: function(from, amount, unit, visually) {
- var this$1 = this;
-
var dir = 1;
if (amount < 0) { dir = -1; amount = -amount; }
var cur = clipPos(this.doc, from);
for (var i = 0; i < amount; ++i) {
- cur = findPosH(this$1.doc, cur, dir, unit, visually);
+ cur = findPosH(this.doc, cur, dir, unit, visually);
if (cur.hitSide) { break }
}
return cur
@@ -8511,11 +8484,11 @@
moveH: methodOp(function(dir, unit) {
var this$1 = this;
- this.extendSelectionsBy(function (range$$1) {
- if (this$1.display.shift || this$1.doc.extend || range$$1.empty())
- { return findPosH(this$1.doc, range$$1.head, dir, unit, this$1.options.rtlMoveVisually) }
+ this.extendSelectionsBy(function (range) {
+ if (this$1.display.shift || this$1.doc.extend || range.empty())
+ { return findPosH(this$1.doc, range.head, dir, unit, this$1.options.rtlMoveVisually) }
else
- { return dir < 0 ? range$$1.from() : range$$1.to() }
+ { return dir < 0 ? range.from() : range.to() }
}, sel_move);
}),
@@ -8524,23 +8497,21 @@
if (sel.somethingSelected())
{ doc.replaceSelection("", null, "+delete"); }
else
- { deleteNearSelection(this, function (range$$1) {
- var other = findPosH(doc, range$$1.head, dir, unit, false);
- return dir < 0 ? {from: other, to: range$$1.head} : {from: range$$1.head, to: other}
+ { deleteNearSelection(this, function (range) {
+ var other = findPosH(doc, range.head, dir, unit, false);
+ return dir < 0 ? {from: other, to: range.head} : {from: range.head, to: other}
}); }
}),
findPosV: function(from, amount, unit, goalColumn) {
- var this$1 = this;
-
var dir = 1, x = goalColumn;
if (amount < 0) { dir = -1; amount = -amount; }
var cur = clipPos(this.doc, from);
for (var i = 0; i < amount; ++i) {
- var coords = cursorCoords(this$1, cur, "div");
+ var coords = cursorCoords(this, cur, "div");
if (x == null) { x = coords.left; }
else { coords.left = x; }
- cur = findPosV(this$1, coords, dir, unit);
+ cur = findPosV(this, coords, dir, unit);
if (cur.hitSide) { break }
}
return cur
@@ -8551,14 +8522,14 @@
var doc = this.doc, goals = [];
var collapse = !this.display.shift && !doc.extend && doc.sel.somethingSelected();
- doc.extendSelectionsBy(function (range$$1) {
+ doc.extendSelectionsBy(function (range) {
if (collapse)
- { return dir < 0 ? range$$1.from() : range$$1.to() }
- var headPos = cursorCoords(this$1, range$$1.head, "div");
- if (range$$1.goalColumn != null) { headPos.left = range$$1.goalColumn; }
+ { return dir < 0 ? range.from() : range.to() }
+ var headPos = cursorCoords(this$1, range.head, "div");
+ if (range.goalColumn != null) { headPos.left = range.goalColumn; }
goals.push(headPos.left);
var pos = findPosV(this$1, headPos, dir, unit);
- if (unit == "page" && range$$1 == doc.sel.primary())
+ if (unit == "page" && range == doc.sel.primary())
{ addToScrollTop(this$1, charCoords(this$1, pos, "div").top - headPos.top); }
return pos
}, sel_move);
@@ -8605,22 +8576,22 @@
clientHeight: displayHeight(this), clientWidth: displayWidth(this)}
},
- scrollIntoView: methodOp(function(range$$1, margin) {
- if (range$$1 == null) {
- range$$1 = {from: this.doc.sel.primary().head, to: null};
+ scrollIntoView: methodOp(function(range, margin) {
+ if (range == null) {
+ range = {from: this.doc.sel.primary().head, to: null};
if (margin == null) { margin = this.options.cursorScrollMargin; }
- } else if (typeof range$$1 == "number") {
- range$$1 = {from: Pos(range$$1, 0), to: null};
- } else if (range$$1.from == null) {
- range$$1 = {from: range$$1, to: null};
+ } else if (typeof range == "number") {
+ range = {from: Pos(range, 0), to: null};
+ } else if (range.from == null) {
+ range = {from: range, to: null};
}
- if (!range$$1.to) { range$$1.to = range$$1.from; }
- range$$1.margin = margin || 0;
+ if (!range.to) { range.to = range.from; }
+ range.margin = margin || 0;
- if (range$$1.from.line != null) {
- scrollToRange(this, range$$1);
+ if (range.from.line != null) {
+ scrollToRange(this, range);
} else {
- scrollToCoordsRange(this, range$$1.from, range$$1.to, range$$1.margin);
+ scrollToCoordsRange(this, range.from, range.to, range.margin);
}
}),
@@ -8631,11 +8602,11 @@
if (width != null) { this.display.wrapper.style.width = interpret(width); }
if (height != null) { this.display.wrapper.style.height = interpret(height); }
if (this.options.lineWrapping) { clearLineMeasurementCache(this); }
- var lineNo$$1 = this.display.viewFrom;
- this.doc.iter(lineNo$$1, this.display.viewTo, function (line) {
+ var lineNo = this.display.viewFrom;
+ this.doc.iter(lineNo, this.display.viewTo, function (line) {
if (line.widgets) { for (var i = 0; i < line.widgets.length; i++)
- { if (line.widgets[i].noHScroll) { regLineChange(this$1, lineNo$$1, "widget"); break } } }
- ++lineNo$$1;
+ { if (line.widgets[i].noHScroll) { regLineChange(this$1, lineNo, "widget"); break } } }
+ ++lineNo;
});
this.curOp.forceUpdate = true;
signal(this, "refresh", this);
@@ -8652,7 +8623,7 @@
clearCaches(this);
scrollToCoords(this, this.doc.scrollLeft, this.doc.scrollTop);
updateGutterSpace(this.display);
- if (oldHeight == null || Math.abs(oldHeight - textHeight(this.display)) > .5)
+ if (oldHeight == null || Math.abs(oldHeight - textHeight(this.display)) > .5 || this.options.lineWrapping)
{ estimateLineHeights(this); }
signal(this, "refresh", this);
}),
@@ -8694,19 +8665,19 @@
}
// Used for horizontal relative motion. Dir is -1 or 1 (left or
- // right), unit can be "char", "column" (like char, but doesn't
- // cross line boundaries), "word" (across next word), or "group" (to
- // the start of next group of word or non-word-non-whitespace
- // chars). The visually param controls whether, in right-to-left
- // text, direction 1 means to move towards the next index in the
- // string, or towards the character to the right of the current
- // position. The resulting position will have a hitSide=true
- // property if it reached the end of the document.
+ // right), unit can be "codepoint", "char", "column" (like char, but
+ // doesn't cross line boundaries), "word" (across next word), or
+ // "group" (to the start of next group of word or
+ // non-word-non-whitespace chars). The visually param controls
+ // whether, in right-to-left text, direction 1 means to move towards
+ // the next index in the string, or towards the character to the right
+ // of the current position. The resulting position will have a
+ // hitSide=true property if it reached the end of the document.
function findPosH(doc, pos, dir, unit, visually) {
var oldPos = pos;
var origDir = dir;
var lineObj = getLine(doc, pos.line);
- var lineDir = visually && doc.cm && doc.cm.getOption("direction") == "rtl" ? -dir : dir;
+ var lineDir = visually && doc.direction == "rtl" ? -dir : dir;
function findNextLine() {
var l = pos.line + lineDir;
if (l < doc.first || l >= doc.first + doc.size) { return false }
@@ -8715,7 +8686,15 @@
}
function moveOnce(boundToLine) {
var next;
- if (visually) {
+ if (unit == "codepoint") {
+ var ch = lineObj.text.charCodeAt(pos.ch + (dir > 0 ? 0 : -1));
+ if (isNaN(ch)) {
+ next = null;
+ } else {
+ var astral = dir > 0 ? ch >= 0xD800 && ch < 0xDC00 : ch >= 0xDC00 && ch < 0xDFFF;
+ next = new Pos(pos.line, Math.max(0, Math.min(lineObj.text.length, pos.ch + dir * (astral ? 2 : 1))), -dir);
+ }
+ } else if (visually) {
next = moveVisually(doc.cm, lineObj, pos, dir);
} else {
next = moveLogically(lineObj, pos, dir);
@@ -8731,7 +8710,7 @@
return true
}
- if (unit == "char") {
+ if (unit == "char" || unit == "codepoint") {
moveOnce();
} else if (unit == "column") {
moveOnce(true);
@@ -8799,10 +8778,19 @@
var input = this, cm = input.cm;
var div = input.div = display.lineDiv;
+ div.contentEditable = true;
disableBrowserMagic(div, cm.options.spellcheck, cm.options.autocorrect, cm.options.autocapitalize);
+ function belongsToInput(e) {
+ for (var t = e.target; t; t = t.parentNode) {
+ if (t == div) { return true }
+ if (/\bCodeMirror-(?:line)?widget\b/.test(t.className)) { break }
+ }
+ return false
+ }
+
on(div, "paste", function (e) {
- if (signalDOMEvent(cm, e) || handlePaste(e, cm)) { return }
+ if (!belongsToInput(e) || signalDOMEvent(cm, e) || handlePaste(e, cm)) { return }
// IE doesn't fire input events, so we schedule a read for the pasted content in this way
if (ie_version <= 11) { setTimeout(operation(cm, function () { return this$1.updateFromDOM(); }), 20); }
});
@@ -8827,7 +8815,7 @@
});
function onCopyCut(e) {
- if (signalDOMEvent(cm, e)) { return }
+ if (!belongsToInput(e) || signalDOMEvent(cm, e)) { return }
if (cm.somethingSelected()) {
setLastCopied({lineWise: false, text: cm.getSelections()});
if (e.type == "cut") { cm.replaceSelection("", null, "cut"); }
@@ -8857,7 +8845,7 @@
var kludge = hiddenTextarea(), te = kludge.firstChild;
cm.display.lineSpace.insertBefore(kludge, cm.display.lineSpace.firstChild);
te.value = lastCopied.text.join("\n");
- var hadFocus = document.activeElement;
+ var hadFocus = activeElt();
selectInput(te);
setTimeout(function () {
cm.display.lineSpace.removeChild(kludge);
@@ -8869,9 +8857,18 @@
on(div, "cut", onCopyCut);
};
+ ContentEditableInput.prototype.screenReaderLabelChanged = function (label) {
+ // Label for screenreaders, accessibility
+ if(label) {
+ this.div.setAttribute('aria-label', label);
+ } else {
+ this.div.removeAttribute('aria-label');
+ }
+ };
+
ContentEditableInput.prototype.prepareSelection = function () {
var result = prepareSelection(this.cm, false);
- result.focus = this.cm.state.focused;
+ result.focus = activeElt() == this.div;
return result
};
@@ -8907,8 +8904,8 @@
var end = to.line < cm.display.viewTo && posToDOM(cm, to);
if (!end) {
var measure = view[view.length - 1].measure;
- var map$$1 = measure.maps ? measure.maps[measure.maps.length - 1] : measure.map;
- end = {node: map$$1[map$$1.length - 1], offset: map$$1[map$$1.length - 2] - map$$1[map$$1.length - 3]};
+ 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]};
}
if (!start || !end) {
@@ -8967,7 +8964,7 @@
ContentEditableInput.prototype.focus = function () {
if (this.cm.options.readOnly != "nocursor") {
- if (!this.selectionInEditor())
+ if (!this.selectionInEditor() || activeElt() != this.div)
{ this.showSelection(this.prepareSelection(), true); }
this.div.focus();
}
@@ -9197,11 +9194,11 @@
addText(cmText);
return
}
- var markerID = node.getAttribute("cm-marker"), range$$1;
+ 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$$1 = found[0].find(0)))
- { addText(getBetween(cm.doc, range$$1.from, range$$1.to).join(lineSep)); }
+ if (found.length && (range = found[0].find(0)))
+ { addText(getBetween(cm.doc, range.from, range.to).join(lineSep)); }
return
}
if (node.getAttribute("contenteditable") == "false") { return }
@@ -9269,13 +9266,13 @@
function find(textNode, topNode, offset) {
for (var i = -1; i < (maps ? maps.length : 0); i++) {
- var map$$1 = i < 0 ? measure.map : maps[i];
- for (var j = 0; j < map$$1.length; j += 3) {
- var curNode = map$$1[j + 2];
+ var map = i < 0 ? measure.map : maps[i];
+ for (var j = 0; j < map.length; j += 3) {
+ var curNode = map[j + 2];
if (curNode == textNode || curNode == topNode) {
var line = lineNo(i < 0 ? lineView.line : lineView.rest[i]);
- var ch = map$$1[j] + offset;
- if (offset < 0 || curNode != textNode) { ch = map$$1[j + (offset ? 1 : 0)]; }
+ var ch = map[j] + offset;
+ if (offset < 0 || curNode != textNode) { ch = map[j + (offset ? 1 : 0)]; }
return Pos(line, ch)
}
}
@@ -9409,6 +9406,15 @@
this.textarea = this.wrapper.firstChild;
};
+ TextareaInput.prototype.screenReaderLabelChanged = function (label) {
+ // Label for screenreaders, accessibility
+ if(label) {
+ this.textarea.setAttribute('aria-label', label);
+ } else {
+ this.textarea.removeAttribute('aria-label');
+ }
+ };
+
TextareaInput.prototype.prepareSelection = function () {
// Redraw the selection and/or cursor
var cm = this.cm, display = cm.display, doc = cm.doc;
@@ -9649,6 +9655,7 @@
TextareaInput.prototype.readOnlyChanged = function (val) {
if (!val) { this.reset(); }
this.textarea.disabled = val == "nocursor";
+ this.textarea.readOnly = !!val;
};
TextareaInput.prototype.setUneditable = function () {};
@@ -9799,7 +9806,7 @@
addLegacyProps(CodeMirror);
- CodeMirror.version = "5.51.0";
+ CodeMirror.version = "5.61.1";
return CodeMirror;
diff --git a/help3/xhpeditor/cm/mode/asn.1/asn.1.js b/help3/xhpeditor/cm/mode/asn.1/asn.1.js
index d3ecb087..df1330b6 100644
--- a/help3/xhpeditor/cm/mode/asn.1/asn.1.js
+++ b/help3/xhpeditor/cm/mode/asn.1/asn.1.js
@@ -190,7 +190,7 @@
" NetworkAddress BITS BMPString TimeStamp TimeTicks" +
" TruthValue RowStatus DisplayString GeneralString" +
" GraphicString IA5String NumericString" +
- " PrintableString SnmpAdminAtring TeletexString" +
+ " PrintableString SnmpAdminString TeletexString" +
" UTF8String VideotexString VisibleString StringStore" +
" ISO646String T61String UniversalString Unsigned32" +
" Integer32 Gauge Gauge32 Counter Counter32 Counter64"),
diff --git a/help3/xhpeditor/cm/mode/clike/clike.js b/help3/xhpeditor/cm/mode/clike/clike.js
index 37da2ec9..15c0fd11 100644
--- a/help3/xhpeditor/cm/mode/clike/clike.js
+++ b/help3/xhpeditor/cm/mode/clike/clike.js
@@ -82,15 +82,15 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
state.tokenize = tokenString(ch);
return state.tokenize(stream, state);
}
- if (isPunctuationChar.test(ch)) {
- curPunc = ch;
- return null;
- }
if (numberStart.test(ch)) {
stream.backUp(1)
if (stream.match(number)) return "number"
stream.next()
}
+ if (isPunctuationChar.test(ch)) {
+ curPunc = ch;
+ return null;
+ }
if (ch == "/") {
if (stream.eat("*")) {
state.tokenize = tokenComment;
@@ -350,8 +350,8 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
function cpp11StringHook(stream, state) {
stream.backUp(1);
// Raw strings.
- if (stream.match(/(R|u8R|uR|UR|LR)/)) {
- var match = stream.match(/"([^\s\\()]{0,16})\(/);
+ if (stream.match(/^(?:R|u8R|uR|UR|LR)/)) {
+ var match = stream.match(/^"([^\s\\()]{0,16})\(/);
if (!match) {
return false;
}
@@ -360,8 +360,8 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
return tokenRawString(stream, state);
}
// Unicode strings/chars.
- if (stream.match(/(u8|u|U|L)/)) {
- if (stream.match(/["']/, /* eat */ false)) {
+ if (stream.match(/^(?:u8|u|U|L)/)) {
+ if (stream.match(/^["']/, /* eat */ false)) {
return "string";
}
return false;
@@ -659,7 +659,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 suspend actual expect setparam"
+ "external annotation crossinline const operator infix suspend actual expect setparam value"
),
types: words(
/* package java.lang */
@@ -749,7 +749,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
"gl_ModelViewMatrix gl_ProjectionMatrix gl_ModelViewProjectionMatrix " +
"gl_TextureMatrix gl_NormalMatrix gl_ModelViewMatrixInverse " +
"gl_ProjectionMatrixInverse gl_ModelViewProjectionMatrixInverse " +
- "gl_TexureMatrixTranspose gl_ModelViewMatrixInverseTranspose " +
+ "gl_TextureMatrixTranspose gl_ModelViewMatrixInverseTranspose " +
"gl_ProjectionMatrixInverseTranspose " +
"gl_ModelViewProjectionMatrixInverseTranspose " +
"gl_TextureMatrixInverseTranspose " +
diff --git a/help3/xhpeditor/cm/mode/clike/index.html b/help3/xhpeditor/cm/mode/clike/index.html
index 0cfae214..b1c88190 100644
--- a/help3/xhpeditor/cm/mode/clike/index.html
+++ b/help3/xhpeditor/cm/mode/clike/index.html
@@ -148,7 +148,7 @@ That spans two lines
*/
#import "MyClass.h"
-#import <AFramework/AFrameork.h>
+#import <AFramework/AFramework.h>
@import BFrameworkModule;
NS_ENUM(SomeValues) {
diff --git a/help3/xhpeditor/cm/mode/clojure/clojure.js b/help3/xhpeditor/cm/mode/clojure/clojure.js
index 25d308ab..0b9d6acc 100644
--- a/help3/xhpeditor/cm/mode/clojure/clojure.js
+++ b/help3/xhpeditor/cm/mode/clojure/clojure.js
@@ -160,10 +160,10 @@ CodeMirror.defineMode("clojure", function (options) {
var numberLiteral = /^(?:[+\-]?\d+(?:(?:N|(?:[eE][+\-]?\d+))|(?:\.?\d*(?:M|(?:[eE][+\-]?\d+))?)|\/\d+|[xX][0-9a-fA-F]+|r[0-9a-zA-Z]+)?(?=[\\\[\]\s"#'(),;@^`{}~]|$))/;
var characterLiteral = /^(?:\\(?:backspace|formfeed|newline|return|space|tab|o[0-7]{3}|u[0-9A-Fa-f]{4}|x[0-9A-Fa-f]{4}|.)?(?=[\\\[\]\s"(),;@^`{}~]|$))/;
- // simple-namespace := /^[^\\\/\[\]\d\s"#'(),;@^`{}~][^\\\[\]\s"(),;@^`{}~]*/
+ // simple-namespace := /^[^\\\/\[\]\d\s"#'(),;@^`{}~.][^\\\[\]\s"(),;@^`{}~.\/]*/
// simple-symbol := /^(?:\/|[^\\\/\[\]\d\s"#'(),;@^`{}~][^\\\[\]\s"(),;@^`{}~]*)/
// qualified-symbol := (<simple-namespace>(<.><simple-namespace>)*</>)?<simple-symbol>
- var qualifiedSymbol = /^(?:(?:[^\\\/\[\]\d\s"#'(),;@^`{}~][^\\\[\]\s"(),;@^`{}~]*(?:\.[^\\\/\[\]\d\s"#'(),;@^`{}~][^\\\[\]\s"(),;@^`{}~]*)*\/)?(?:\/|[^\\\/\[\]\d\s"#'(),;@^`{}~][^\\\[\]\s"(),;@^`{}~]*)*(?=[\\\[\]\s"(),;@^`{}~]|$))/;
+ var qualifiedSymbol = /^(?:(?:[^\\\/\[\]\d\s"#'(),;@^`{}~.][^\\\[\]\s"(),;@^`{}~.\/]*(?:\.[^\\\/\[\]\d\s"#'(),;@^`{}~.][^\\\[\]\s"(),;@^`{}~.\/]*)*\/)?(?:\/|[^\\\/\[\]\d\s"#'(),;@^`{}~][^\\\[\]\s"(),;@^`{}~]*)*(?=[\\\[\]\s"(),;@^`{}~]|$))/;
function base(stream, state) {
if (stream.eatSpace() || stream.eat(",")) return ["space", null];
diff --git a/help3/xhpeditor/cm/mode/crystal/crystal.js b/help3/xhpeditor/cm/mode/crystal/crystal.js
index 5c601c6a..5dae5032 100644
--- a/help3/xhpeditor/cm/mode/crystal/crystal.js
+++ b/help3/xhpeditor/cm/mode/crystal/crystal.js
@@ -164,10 +164,10 @@
} else {
if(delim = stream.match(/^%([^\w\s=])/)) {
delim = delim[1];
- } else if (stream.match(/^%[a-zA-Z0-9_\u009F-\uFFFF]*/)) {
+ } else if (stream.match(/^%[a-zA-Z_\u009F-\uFFFF][\w\u009F-\uFFFF]*/)) {
// Macro variables
return "meta";
- } else {
+ } else if (stream.eat('%')) {
// '%' operator
return "operator";
}
@@ -194,17 +194,17 @@
// Numbers
if (stream.eat("0")) {
if (stream.eat("x")) {
- stream.match(/^[0-9a-fA-F]+/);
+ stream.match(/^[0-9a-fA-F_]+/);
} else if (stream.eat("o")) {
- stream.match(/^[0-7]+/);
+ stream.match(/^[0-7_]+/);
} else if (stream.eat("b")) {
- stream.match(/^[01]+/);
+ stream.match(/^[01_]+/);
}
return "number";
}
if (stream.eat(/^\d/)) {
- stream.match(/^\d*(?:\.\d+)?(?:[eE][+-]?\d+)?/);
+ stream.match(/^[\d_]*(?:\.[\d_]+)?(?:[eE][+-]?\d+)?/);
return "number";
}
diff --git a/help3/xhpeditor/cm/mode/css/css.js b/help3/xhpeditor/cm/mode/css/css.js
index 05742c5c..88a869bf 100644
--- a/help3/xhpeditor/cm/mode/css/css.js
+++ b/help3/xhpeditor/cm/mode/css/css.js
@@ -29,7 +29,8 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
valueKeywords = parserConfig.valueKeywords || {},
allowNested = parserConfig.allowNested,
lineComment = parserConfig.lineComment,
- supportsAtComponent = parserConfig.supportsAtComponent === true;
+ supportsAtComponent = parserConfig.supportsAtComponent === true,
+ highlightNonStandardPropertyKeywords = config.highlightNonStandardPropertyKeywords !== false;
var type, override;
function ret(style, tp) { type = tp; return style; }
@@ -77,8 +78,8 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
return ret("qualifier", "qualifier");
} else if (/[:;{}\[\]\(\)]/.test(ch)) {
return ret(null, ch);
- } else if (stream.match(/[\w-.]+(?=\()/)) {
- if (/^(url(-prefix)?|domain|regexp)$/.test(stream.current().toLowerCase())) {
+ } else if (stream.match(/^[\w-.]+(?=\()/)) {
+ if (/^(url(-prefix)?|domain|regexp)$/i.test(stream.current())) {
state.tokenize = tokenParenthesized;
}
return ret("variable callee", "variable");
@@ -107,7 +108,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
function tokenParenthesized(stream, state) {
stream.next(); // Must be '('
- if (!stream.match(/\s*[\"\')]/, false))
+ if (!stream.match(/^\s*[\"\')]/, false))
state.tokenize = tokenString(")");
else
state.tokenize = null;
@@ -197,7 +198,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
override = "property";
return "maybeprop";
} else if (nonStandardPropertyKeywords.hasOwnProperty(word)) {
- override = "string-2";
+ override = highlightNonStandardPropertyKeywords ? "string-2" : "property";
return "maybeprop";
} else if (allowNested) {
override = stream.match(/^\s*:(?:\s|$)/, false) ? "property" : "tag";
@@ -291,7 +292,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
else if (propertyKeywords.hasOwnProperty(word))
override = "property";
else if (nonStandardPropertyKeywords.hasOwnProperty(word))
- override = "string-2";
+ override = highlightNonStandardPropertyKeywords ? "string-2" : "property";
else if (valueKeywords.hasOwnProperty(word))
override = "atom";
else if (colorKeywords.hasOwnProperty(word))
@@ -442,117 +443,149 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
"monochrome", "min-monochrome", "max-monochrome", "resolution",
"min-resolution", "max-resolution", "scan", "grid", "orientation",
"device-pixel-ratio", "min-device-pixel-ratio", "max-device-pixel-ratio",
- "pointer", "any-pointer", "hover", "any-hover"
+ "pointer", "any-pointer", "hover", "any-hover", "prefers-color-scheme"
], mediaFeatures = keySet(mediaFeatures_);
var mediaValueKeywords_ = [
"landscape", "portrait", "none", "coarse", "fine", "on-demand", "hover",
- "interlace", "progressive"
+ "interlace", "progressive",
+ "dark", "light"
], mediaValueKeywords = keySet(mediaValueKeywords_);
var propertyKeywords_ = [
"align-content", "align-items", "align-self", "alignment-adjust",
- "alignment-baseline", "anchor-point", "animation", "animation-delay",
+ "alignment-baseline", "all", "anchor-point", "animation", "animation-delay",
"animation-direction", "animation-duration", "animation-fill-mode",
"animation-iteration-count", "animation-name", "animation-play-state",
- "animation-timing-function", "appearance", "azimuth", "backface-visibility",
- "background", "background-attachment", "background-blend-mode", "background-clip",
- "background-color", "background-image", "background-origin", "background-position",
- "background-repeat", "background-size", "baseline-shift", "binding",
- "bleed", "bookmark-label", "bookmark-level", "bookmark-state",
- "bookmark-target", "border", "border-bottom", "border-bottom-color",
- "border-bottom-left-radius", "border-bottom-right-radius",
- "border-bottom-style", "border-bottom-width", "border-collapse",
- "border-color", "border-image", "border-image-outset",
+ "animation-timing-function", "appearance", "azimuth", "backdrop-filter",
+ "backface-visibility", "background", "background-attachment",
+ "background-blend-mode", "background-clip", "background-color",
+ "background-image", "background-origin", "background-position",
+ "background-position-x", "background-position-y", "background-repeat",
+ "background-size", "baseline-shift", "binding", "bleed", "block-size",
+ "bookmark-label", "bookmark-level", "bookmark-state", "bookmark-target",
+ "border", "border-bottom", "border-bottom-color", "border-bottom-left-radius",
+ "border-bottom-right-radius", "border-bottom-style", "border-bottom-width",
+ "border-collapse", "border-color", "border-image", "border-image-outset",
"border-image-repeat", "border-image-slice", "border-image-source",
- "border-image-width", "border-left", "border-left-color",
- "border-left-style", "border-left-width", "border-radius", "border-right",
- "border-right-color", "border-right-style", "border-right-width",
- "border-spacing", "border-style", "border-top", "border-top-color",
- "border-top-left-radius", "border-top-right-radius", "border-top-style",
- "border-top-width", "border-width", "bottom", "box-decoration-break",
- "box-shadow", "box-sizing", "break-after", "break-before", "break-inside",
- "caption-side", "caret-color", "clear", "clip", "color", "color-profile", "column-count",
- "column-fill", "column-gap", "column-rule", "column-rule-color",
- "column-rule-style", "column-rule-width", "column-span", "column-width",
- "columns", "content", "counter-increment", "counter-reset", "crop", "cue",
- "cue-after", "cue-before", "cursor", "direction", "display",
- "dominant-baseline", "drop-initial-after-adjust",
- "drop-initial-after-align", "drop-initial-before-adjust",
- "drop-initial-before-align", "drop-initial-size", "drop-initial-value",
- "elevation", "empty-cells", "fit", "fit-position", "flex", "flex-basis",
- "flex-direction", "flex-flow", "flex-grow", "flex-shrink", "flex-wrap",
- "float", "float-offset", "flow-from", "flow-into", "font", "font-feature-settings",
- "font-family", "font-kerning", "font-language-override", "font-size", "font-size-adjust",
- "font-stretch", "font-style", "font-synthesis", "font-variant",
- "font-variant-alternates", "font-variant-caps", "font-variant-east-asian",
- "font-variant-ligatures", "font-variant-numeric", "font-variant-position",
- "font-weight", "grid", "grid-area", "grid-auto-columns", "grid-auto-flow",
- "grid-auto-rows", "grid-column", "grid-column-end", "grid-column-gap",
- "grid-column-start", "grid-gap", "grid-row", "grid-row-end", "grid-row-gap",
- "grid-row-start", "grid-template", "grid-template-areas", "grid-template-columns",
- "grid-template-rows", "hanging-punctuation", "height", "hyphens",
- "icon", "image-orientation", "image-rendering", "image-resolution",
- "inline-box-align", "justify-content", "justify-items", "justify-self", "left", "letter-spacing",
- "line-break", "line-height", "line-stacking", "line-stacking-ruby",
+ "border-image-width", "border-left", "border-left-color", "border-left-style",
+ "border-left-width", "border-radius", "border-right", "border-right-color",
+ "border-right-style", "border-right-width", "border-spacing", "border-style",
+ "border-top", "border-top-color", "border-top-left-radius",
+ "border-top-right-radius", "border-top-style", "border-top-width",
+ "border-width", "bottom", "box-decoration-break", "box-shadow", "box-sizing",
+ "break-after", "break-before", "break-inside", "caption-side", "caret-color",
+ "clear", "clip", "color", "color-profile", "column-count", "column-fill",
+ "column-gap", "column-rule", "column-rule-color", "column-rule-style",
+ "column-rule-width", "column-span", "column-width", "columns", "contain",
+ "content", "counter-increment", "counter-reset", "crop", "cue", "cue-after",
+ "cue-before", "cursor", "direction", "display", "dominant-baseline",
+ "drop-initial-after-adjust", "drop-initial-after-align",
+ "drop-initial-before-adjust", "drop-initial-before-align", "drop-initial-size",
+ "drop-initial-value", "elevation", "empty-cells", "fit", "fit-position",
+ "flex", "flex-basis", "flex-direction", "flex-flow", "flex-grow",
+ "flex-shrink", "flex-wrap", "float", "float-offset", "flow-from", "flow-into",
+ "font", "font-family", "font-feature-settings", "font-kerning",
+ "font-language-override", "font-optical-sizing", "font-size",
+ "font-size-adjust", "font-stretch", "font-style", "font-synthesis",
+ "font-variant", "font-variant-alternates", "font-variant-caps",
+ "font-variant-east-asian", "font-variant-ligatures", "font-variant-numeric",
+ "font-variant-position", "font-variation-settings", "font-weight", "gap",
+ "grid", "grid-area", "grid-auto-columns", "grid-auto-flow", "grid-auto-rows",
+ "grid-column", "grid-column-end", "grid-column-gap", "grid-column-start",
+ "grid-gap", "grid-row", "grid-row-end", "grid-row-gap", "grid-row-start",
+ "grid-template", "grid-template-areas", "grid-template-columns",
+ "grid-template-rows", "hanging-punctuation", "height", "hyphens", "icon",
+ "image-orientation", "image-rendering", "image-resolution", "inline-box-align",
+ "inset", "inset-block", "inset-block-end", "inset-block-start", "inset-inline",
+ "inset-inline-end", "inset-inline-start", "isolation", "justify-content",
+ "justify-items", "justify-self", "left", "letter-spacing", "line-break",
+ "line-height", "line-height-step", "line-stacking", "line-stacking-ruby",
"line-stacking-shift", "line-stacking-strategy", "list-style",
"list-style-image", "list-style-position", "list-style-type", "margin",
- "margin-bottom", "margin-left", "margin-right", "margin-top",
- "marks", "marquee-direction", "marquee-loop",
- "marquee-play-count", "marquee-speed", "marquee-style", "max-height",
- "max-width", "min-height", "min-width", "mix-blend-mode", "move-to", "nav-down", "nav-index",
- "nav-left", "nav-right", "nav-up", "object-fit", "object-position",
- "opacity", "order", "orphans", "outline",
- "outline-color", "outline-offset", "outline-style", "outline-width",
- "overflow", "overflow-style", "overflow-wrap", "overflow-x", "overflow-y",
- "padding", "padding-bottom", "padding-left", "padding-right", "padding-top",
- "page", "page-break-after", "page-break-before", "page-break-inside",
- "page-policy", "pause", "pause-after", "pause-before", "perspective",
- "perspective-origin", "pitch", "pitch-range", "place-content", "place-items", "place-self", "play-during", "position",
- "presentation-level", "punctuation-trim", "quotes", "region-break-after",
- "region-break-before", "region-break-inside", "region-fragment",
- "rendering-intent", "resize", "rest", "rest-after", "rest-before", "richness",
- "right", "rotation", "rotation-point", "ruby-align", "ruby-overhang",
- "ruby-position", "ruby-span", "shape-image-threshold", "shape-inside", "shape-margin",
- "shape-outside", "size", "speak", "speak-as", "speak-header",
- "speak-numeral", "speak-punctuation", "speech-rate", "stress", "string-set",
- "tab-size", "table-layout", "target", "target-name", "target-new",
- "target-position", "text-align", "text-align-last", "text-decoration",
+ "margin-bottom", "margin-left", "margin-right", "margin-top", "marks",
+ "marquee-direction", "marquee-loop", "marquee-play-count", "marquee-speed",
+ "marquee-style", "mask-clip", "mask-composite", "mask-image", "mask-mode",
+ "mask-origin", "mask-position", "mask-repeat", "mask-size","mask-type",
+ "max-block-size", "max-height", "max-inline-size",
+ "max-width", "min-block-size", "min-height", "min-inline-size", "min-width",
+ "mix-blend-mode", "move-to", "nav-down", "nav-index", "nav-left", "nav-right",
+ "nav-up", "object-fit", "object-position", "offset", "offset-anchor",
+ "offset-distance", "offset-path", "offset-position", "offset-rotate",
+ "opacity", "order", "orphans", "outline", "outline-color", "outline-offset",
+ "outline-style", "outline-width", "overflow", "overflow-style",
+ "overflow-wrap", "overflow-x", "overflow-y", "padding", "padding-bottom",
+ "padding-left", "padding-right", "padding-top", "page", "page-break-after",
+ "page-break-before", "page-break-inside", "page-policy", "pause",
+ "pause-after", "pause-before", "perspective", "perspective-origin", "pitch",
+ "pitch-range", "place-content", "place-items", "place-self", "play-during",
+ "position", "presentation-level", "punctuation-trim", "quotes",
+ "region-break-after", "region-break-before", "region-break-inside",
+ "region-fragment", "rendering-intent", "resize", "rest", "rest-after",
+ "rest-before", "richness", "right", "rotate", "rotation", "rotation-point",
+ "row-gap", "ruby-align", "ruby-overhang", "ruby-position", "ruby-span",
+ "scale", "scroll-behavior", "scroll-margin", "scroll-margin-block",
+ "scroll-margin-block-end", "scroll-margin-block-start", "scroll-margin-bottom",
+ "scroll-margin-inline", "scroll-margin-inline-end",
+ "scroll-margin-inline-start", "scroll-margin-left", "scroll-margin-right",
+ "scroll-margin-top", "scroll-padding", "scroll-padding-block",
+ "scroll-padding-block-end", "scroll-padding-block-start",
+ "scroll-padding-bottom", "scroll-padding-inline", "scroll-padding-inline-end",
+ "scroll-padding-inline-start", "scroll-padding-left", "scroll-padding-right",
+ "scroll-padding-top", "scroll-snap-align", "scroll-snap-type",
+ "shape-image-threshold", "shape-inside", "shape-margin", "shape-outside",
+ "size", "speak", "speak-as", "speak-header", "speak-numeral",
+ "speak-punctuation", "speech-rate", "stress", "string-set", "tab-size",
+ "table-layout", "target", "target-name", "target-new", "target-position",
+ "text-align", "text-align-last", "text-combine-upright", "text-decoration",
"text-decoration-color", "text-decoration-line", "text-decoration-skip",
- "text-decoration-style", "text-emphasis", "text-emphasis-color",
- "text-emphasis-position", "text-emphasis-style", "text-height",
- "text-indent", "text-justify", "text-outline", "text-overflow", "text-shadow",
- "text-size-adjust", "text-space-collapse", "text-transform", "text-underline-position",
- "text-wrap", "top", "transform", "transform-origin", "transform-style",
- "transition", "transition-delay", "transition-duration",
- "transition-property", "transition-timing-function", "unicode-bidi",
- "user-select", "vertical-align", "visibility", "voice-balance", "voice-duration",
- "voice-family", "voice-pitch", "voice-range", "voice-rate", "voice-stress",
- "voice-volume", "volume", "white-space", "widows", "width", "will-change", "word-break",
- "word-spacing", "word-wrap", "z-index",
+ "text-decoration-skip-ink", "text-decoration-style", "text-emphasis",
+ "text-emphasis-color", "text-emphasis-position", "text-emphasis-style",
+ "text-height", "text-indent", "text-justify", "text-orientation",
+ "text-outline", "text-overflow", "text-rendering", "text-shadow",
+ "text-size-adjust", "text-space-collapse", "text-transform",
+ "text-underline-position", "text-wrap", "top", "touch-action", "transform", "transform-origin",
+ "transform-style", "transition", "transition-delay", "transition-duration",
+ "transition-property", "transition-timing-function", "translate",
+ "unicode-bidi", "user-select", "vertical-align", "visibility", "voice-balance",
+ "voice-duration", "voice-family", "voice-pitch", "voice-range", "voice-rate",
+ "voice-stress", "voice-volume", "volume", "white-space", "widows", "width",
+ "will-change", "word-break", "word-spacing", "word-wrap", "writing-mode", "z-index",
// SVG-specific
"clip-path", "clip-rule", "mask", "enable-background", "filter", "flood-color",
"flood-opacity", "lighting-color", "stop-color", "stop-opacity", "pointer-events",
"color-interpolation", "color-interpolation-filters",
"color-rendering", "fill", "fill-opacity", "fill-rule", "image-rendering",
- "marker", "marker-end", "marker-mid", "marker-start", "shape-rendering", "stroke",
+ "marker", "marker-end", "marker-mid", "marker-start", "paint-order", "shape-rendering", "stroke",
"stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin",
"stroke-miterlimit", "stroke-opacity", "stroke-width", "text-rendering",
"baseline-shift", "dominant-baseline", "glyph-orientation-horizontal",
- "glyph-orientation-vertical", "text-anchor", "writing-mode"
+ "glyph-orientation-vertical", "text-anchor", "writing-mode",
], propertyKeywords = keySet(propertyKeywords_);
var nonStandardPropertyKeywords_ = [
+ "border-block", "border-block-color", "border-block-end",
+ "border-block-end-color", "border-block-end-style", "border-block-end-width",
+ "border-block-start", "border-block-start-color", "border-block-start-style",
+ "border-block-start-width", "border-block-style", "border-block-width",
+ "border-inline", "border-inline-color", "border-inline-end",
+ "border-inline-end-color", "border-inline-end-style",
+ "border-inline-end-width", "border-inline-start", "border-inline-start-color",
+ "border-inline-start-style", "border-inline-start-width",
+ "border-inline-style", "border-inline-width", "margin-block",
+ "margin-block-end", "margin-block-start", "margin-inline", "margin-inline-end",
+ "margin-inline-start", "padding-block", "padding-block-end",
+ "padding-block-start", "padding-inline", "padding-inline-end",
+ "padding-inline-start", "scroll-snap-stop", "scrollbar-3d-light-color",
"scrollbar-arrow-color", "scrollbar-base-color", "scrollbar-dark-shadow-color",
"scrollbar-face-color", "scrollbar-highlight-color", "scrollbar-shadow-color",
- "scrollbar-3d-light-color", "scrollbar-track-color", "shape-inside",
- "searchfield-cancel-button", "searchfield-decoration", "searchfield-results-button",
- "searchfield-results-decoration", "zoom"
+ "scrollbar-track-color", "searchfield-cancel-button", "searchfield-decoration",
+ "searchfield-results-button", "searchfield-results-decoration", "shape-inside", "zoom"
], nonStandardPropertyKeywords = keySet(nonStandardPropertyKeywords_);
var fontProperties_ = [
- "font-family", "src", "unicode-range", "font-variant", "font-feature-settings",
- "font-stretch", "font-weight", "font-style"
+ "font-display", "font-family", "src", "unicode-range", "font-variant",
+ "font-feature-settings", "font-stretch", "font-weight", "font-style"
], fontProperties = keySet(fontProperties_);
var counterDescriptors_ = [
@@ -594,7 +627,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
"after-white-space", "ahead", "alias", "all", "all-scroll", "alphabetic", "alternate",
"always", "amharic", "amharic-abegede", "antialiased", "appworkspace",
"arabic-indic", "armenian", "asterisks", "attr", "auto", "auto-flow", "avoid", "avoid-column", "avoid-page",
- "avoid-region", "background", "backwards", "baseline", "below", "bidi-override", "binary",
+ "avoid-region", "axis-pan", "background", "backwards", "baseline", "below", "bidi-override", "binary",
"bengali", "blink", "block", "block-axis", "bold", "bolder", "border", "border-box",
"both", "bottom", "break", "break-all", "break-word", "bullets", "button", "button-bevel",
"buttonface", "buttonhighlight", "buttonshadow", "buttontext", "calc", "cambodian",
@@ -618,7 +651,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
"ethiopic-halehame-sid-et", "ethiopic-halehame-so-et",
"ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et", "ethiopic-halehame-tig",
"ethiopic-numeric", "ew-resize", "exclusion", "expanded", "extends", "extra-condensed",
- "extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "flex", "flex-end", "flex-start", "footnotes",
+ "extra-expanded", "fantasy", "fast", "fill", "fill-box", "fixed", "flat", "flex", "flex-end", "flex-start", "footnotes",
"forwards", "from", "geometricPrecision", "georgian", "graytext", "grid", "groove",
"gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hard-light", "hebrew",
"help", "hidden", "hide", "higher", "highlight", "highlighttext",
@@ -633,7 +666,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
"line-through", "linear", "linear-gradient", "lines", "list-item", "listbox", "listitem",
"local", "logical", "loud", "lower", "lower-alpha", "lower-armenian",
"lower-greek", "lower-hexadecimal", "lower-latin", "lower-norwegian",
- "lower-roman", "lowercase", "ltr", "luminosity", "malayalam", "match", "matrix", "matrix3d",
+ "lower-roman", "lowercase", "ltr", "luminosity", "malayalam", "manipulation", "match", "matrix", "matrix3d",
"media-controls-background", "media-current-time-display",
"media-fullscreen-button", "media-mute-button", "media-play-button",
"media-return-to-realtime-button", "media-rewind-button",
@@ -642,13 +675,13 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
"media-volume-slider-container", "media-volume-sliderthumb", "medium",
"menu", "menulist", "menulist-button", "menulist-text",
"menulist-textfield", "menutext", "message-box", "middle", "min-intrinsic",
- "mix", "mongolian", "monospace", "move", "multiple", "multiply", "myanmar", "n-resize",
+ "mix", "mongolian", "monospace", "move", "multiple", "multiple_mask_images", "multiply", "myanmar", "n-resize",
"narrower", "ne-resize", "nesw-resize", "no-close-quote", "no-drop",
"no-open-quote", "no-repeat", "none", "normal", "not-allowed", "nowrap",
"ns-resize", "numbers", "numeric", "nw-resize", "nwse-resize", "oblique", "octal", "opacity", "open-quote",
"optimizeLegibility", "optimizeSpeed", "oriya", "oromo", "outset",
"outside", "outside-shape", "overlay", "overline", "padding", "padding-box",
- "painted", "page", "paused", "persian", "perspective", "plus-darker", "plus-lighter",
+ "painted", "page", "paused", "persian", "perspective", "pinch-zoom", "plus-darker", "plus-lighter",
"pointer", "polygon", "portrait", "pre", "pre-line", "pre-wrap", "preserve-3d",
"progress", "push-button", "radial-gradient", "radio", "read-only",
"read-write", "read-write-plaintext-only", "rectangle", "region",
@@ -666,8 +699,8 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
"slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow",
"small", "small-caps", "small-caption", "smaller", "soft-light", "solid", "somali",
"source-atop", "source-in", "source-out", "source-over", "space", "space-around", "space-between", "space-evenly", "spell-out", "square",
- "square-button", "start", "static", "status-bar", "stretch", "stroke", "sub",
- "subpixel-antialiased", "super", "sw-resize", "symbolic", "symbols", "system-ui", "table",
+ "square-button", "start", "static", "status-bar", "stretch", "stroke", "stroke-box", "sub",
+ "subpixel-antialiased", "svg_masks", "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",
@@ -677,10 +710,10 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
"tigrinya-er-abegede", "tigrinya-et", "tigrinya-et-abegede", "to", "top",
"trad-chinese-formal", "trad-chinese-informal", "transform",
"translate", "translate3d", "translateX", "translateY", "translateZ",
- "transparent", "ultra-condensed", "ultra-expanded", "underline", "unset", "up",
+ "transparent", "ultra-condensed", "ultra-expanded", "underline", "unidirectional-pan", "unset", "up",
"upper-alpha", "upper-armenian", "upper-greek", "upper-hexadecimal",
"upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url",
- "var", "vertical", "vertical-text", "visible", "visibleFill", "visiblePainted",
+ "var", "vertical", "vertical-text", "view-box", "visible", "visibleFill", "visiblePainted",
"visibleStroke", "visual", "w-resize", "wait", "wave", "wider",
"window", "windowframe", "windowtext", "words", "wrap", "wrap-reverse", "x-large", "x-small", "xor",
"xx-large", "xx-small"
@@ -748,7 +781,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
}
},
":": function(stream) {
- if (stream.match(/\s*\{/, false))
+ if (stream.match(/^\s*\{/, false))
return [null, null]
return false;
},
diff --git a/help3/xhpeditor/cm/mode/css/gss.html b/help3/xhpeditor/cm/mode/css/gss.html
index e0007296..17d24f8a 100644
--- a/help3/xhpeditor/cm/mode/css/gss.html
+++ b/help3/xhpeditor/cm/mode/css/gss.html
@@ -82,7 +82,7 @@ body {
.logo {
@mixin size(150px, 55px);
- background-image: url('https://www.google.com/images/logo_sm.gif');
+ background-image: url('http://www.google.com/images/logo_sm.gif');
}
}
diff --git a/help3/xhpeditor/cm/mode/css/index.html b/help3/xhpeditor/cm/mode/css/index.html
index 6588c408..42b327ca 100644
--- a/help3/xhpeditor/cm/mode/css/index.html
+++ b/help3/xhpeditor/cm/mode/css/index.html
@@ -68,6 +68,12 @@ code {
});
</script>
+ <p>CSS mode supports this option:</p>
+ <d1>
+ <dt><code><strong>highlightNonStandardPropertyKeywords</strong>: boolean</code></dt>
+ <dd>Whether to highlight non-standard CSS property keywords such as <code>margin-inline</code> or <code>zoom</code> (default: <code>true</code>).</dd>
+ </d1>
+
<p><strong>MIME types defined:</strong> <code>text/css</code>, <code>text/x-scss</code> (<a href="scss.html">demo</a>), <code>text/x-less</code> (<a href="less.html">demo</a>).</p>
<p><strong>Parsing/Highlighting Tests:</strong> <a href="../../test/index.html#css_*">normal</a>, <a href="../../test/index.html#verbose,css_*">verbose</a>.</p>
diff --git a/help3/xhpeditor/cm/mode/cypher/cypher.js b/help3/xhpeditor/cm/mode/cypher/cypher.js
index aa76eb9e..6d88fa0e 100644
--- a/help3/xhpeditor/cm/mode/cypher/cypher.js
+++ b/help3/xhpeditor/cm/mode/cypher/cypher.js
@@ -21,11 +21,11 @@
var tokenBase = function(stream/*, state*/) {
var ch = stream.next();
if (ch ==='"') {
- stream.match(/.*?"/);
+ stream.match(/^[^"]*"/);
return "string";
}
if (ch === "'") {
- stream.match(/.*?'/);
+ stream.match(/^[^']*'/);
return "string";
}
if (/[{}\(\),\.;\[\]]/.test(ch)) {
diff --git a/help3/xhpeditor/cm/mode/dart/dart.js b/help3/xhpeditor/cm/mode/dart/dart.js
index f6a4939e..fe64517a 100644
--- a/help3/xhpeditor/cm/mode/dart/dart.js
+++ b/help3/xhpeditor/cm/mode/dart/dart.js
@@ -15,10 +15,10 @@
"implements mixin 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 extension on").split(" ");
+ "part of show hide is as extension on yield late required").split(" ");
var blockKeywords = "try catch finally do else for if switch while".split(" ");
var atoms = "true false null".split(" ");
- var builtins = "void bool num int double dynamic var String".split(" ");
+ var builtins = "void bool num int double dynamic var String Null Never".split(" ");
function set(words) {
var obj = {};
diff --git a/help3/xhpeditor/cm/mode/dtd/dtd.js b/help3/xhpeditor/cm/mode/dtd/dtd.js
index 74b8c6bd..1bff91cb 100644
--- a/help3/xhpeditor/cm/mode/dtd/dtd.js
+++ b/help3/xhpeditor/cm/mode/dtd/dtd.js
@@ -34,7 +34,7 @@ CodeMirror.defineMode("dtd", function(config) {
state.tokenize = inBlock("meta", "?>");
return ret("meta", ch);
} else if (ch == "#" && stream.eatWhile(/[\w]/)) return ret("atom", "tag");
- else if (ch == "|") return ret("keyword", "seperator");
+ else if (ch == "|") return ret("keyword", "separator");
else if (ch.match(/[\(\)\[\]\-\.,\+\?>]/)) return ret(null, ch);//if(ch === ">") return ret(null, "endtag"); else
else if (ch.match(/[\[\]]/)) return ret("rule", ch);
else if (ch == "\"" || ch == "'") {
@@ -112,7 +112,7 @@ CodeMirror.defineMode("dtd", function(config) {
indent: function(state, textAfter) {
var n = state.stack.length;
- if( textAfter.match(/\]\s+|\]/) )n=n-1;
+ if( textAfter.charAt(0) === ']' )n--;
else if(textAfter.substr(textAfter.length-1, textAfter.length) === ">"){
if(textAfter.substr(0,1) === "<") {}
else if( type == "doindent" && textAfter.length > 1 ) {}
diff --git a/help3/xhpeditor/cm/mode/ebnf/ebnf.js b/help3/xhpeditor/cm/mode/ebnf/ebnf.js
index 238bbe23..d8fb3f3a 100644
--- a/help3/xhpeditor/cm/mode/ebnf/ebnf.js
+++ b/help3/xhpeditor/cm/mode/ebnf/ebnf.js
@@ -41,10 +41,10 @@
state.stringType = stream.peek();
stream.next(); // Skip quote
state.stack.unshift(stateType._string);
- } else if (stream.match(/^\/\*/)) { //comments starting with /*
+ } else if (stream.match('/*')) { //comments starting with /*
state.stack.unshift(stateType.comment);
state.commentType = commentType.slash;
- } else if (stream.match(/^\(\*/)) { //comments starting with (*
+ } else if (stream.match('(*')) { //comments starting with (*
state.stack.unshift(stateType.comment);
state.commentType = commentType.parenthesis;
}
@@ -69,10 +69,10 @@
case stateType.comment:
while (state.stack[0] === stateType.comment && !stream.eol()) {
- if (state.commentType === commentType.slash && stream.match(/\*\//)) {
+ if (state.commentType === commentType.slash && stream.match('*/')) {
state.stack.shift(); // Clear flag
state.commentType = null;
- } else if (state.commentType === commentType.parenthesis && stream.match(/\*\)/)) {
+ } else if (state.commentType === commentType.parenthesis && stream.match('*)')) {
state.stack.shift(); // Clear flag
state.commentType = null;
} else {
@@ -83,7 +83,7 @@
case stateType.characterClass:
while (state.stack[0] === stateType.characterClass && !stream.eol()) {
- if (!(stream.match(/^[^\]\\]+/) || stream.match(/^\\./))) {
+ if (!(stream.match(/^[^\]\\]+/) || stream.match('.'))) {
state.stack.shift();
}
}
@@ -168,10 +168,10 @@
}
}
- if (stream.match(/^\/\//)) {
+ if (stream.match('//')) {
stream.skipToEnd();
return "comment";
- } else if (stream.match(/return/)) {
+ } else if (stream.match('return')) {
return "operator";
} else if (stream.match(/^[a-zA-Z_][a-zA-Z0-9_]*/)) {
if (stream.match(/(?=[\(.])/)) {
diff --git a/help3/xhpeditor/cm/mode/erlang/erlang.js b/help3/xhpeditor/cm/mode/erlang/erlang.js
index f0541bb9..d827296f 100644
--- a/help3/xhpeditor/cm/mode/erlang/erlang.js
+++ b/help3/xhpeditor/cm/mode/erlang/erlang.js
@@ -339,8 +339,8 @@ CodeMirror.defineMode("erlang", function(cmCfg) {
}
function lookahead(stream) {
- var m = stream.match(/([\n\s]+|%[^\n]*\n)*(.)/,false);
- return m ? m.pop() : "";
+ var m = stream.match(/^\s*([^\s%])/, false)
+ return m ? m[1] : "";
}
function is_member(element,list) {
diff --git a/help3/xhpeditor/cm/mode/factor/factor.js b/help3/xhpeditor/cm/mode/factor/factor.js
index 7108278c..4c876d4d 100644
--- a/help3/xhpeditor/cm/mode/factor/factor.js
+++ b/help3/xhpeditor/cm/mode/factor/factor.js
@@ -16,7 +16,7 @@
"use strict";
CodeMirror.defineSimpleMode("factor", {
- // The start state contains the rules that are intially used
+ // The start state contains the rules that are initially used
start: [
// comments
{regex: /#?!.*/, token: "comment"},
diff --git a/help3/xhpeditor/cm/mode/factor/index.html b/help3/xhpeditor/cm/mode/factor/index.html
index 9a3362aa..6a77230d 100644
--- a/help3/xhpeditor/cm/mode/factor/index.html
+++ b/help3/xhpeditor/cm/mode/factor/index.html
@@ -4,7 +4,7 @@
<meta charset="utf-8"/>
<link rel=stylesheet href="../../doc/docs.css">
-<link href='https://fonts.googleapis.com/css?family=Droid+Sans+Mono' rel='stylesheet' type='text/css'>
+<link href='http://fonts.googleapis.com/css?family=Droid+Sans+Mono' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="../../addon/mode/simple.js"></script>
@@ -70,7 +70,7 @@ MAIN: start-time-server
});
</script>
<p/>
-<p>Simple mode that handles Factor Syntax (<a href="http://en.wikipedia.org/wiki/Factor_(programming_language)">Factor on WikiPedia</a>).</p>
+<p>Simple mode that handles Factor Syntax (<a href="http://en.wikipedia.org/wiki/Factor_(programming_language)">Factor on Wikipedia</a>).</p>
<p><strong>MIME types defined:</strong> <code>text/x-factor</code>.</p>
diff --git a/help3/xhpeditor/cm/mode/fcl/index.html b/help3/xhpeditor/cm/mode/fcl/index.html
index e51fa166..9194dfdd 100644
--- a/help3/xhpeditor/cm/mode/fcl/index.html
+++ b/help3/xhpeditor/cm/mode/fcl/index.html
@@ -61,7 +61,7 @@
END_FUZZIFY
DEFUZZIFY ProbabilityAccess
- TERM hight := 1;
+ TERM height := 1;
TERM medium := 0.5;
TERM low := 0;
ACCU: MAX;
@@ -70,7 +70,7 @@
END_DEFUZZIFY
DEFUZZIFY ProbabilityDistribution
- TERM hight := 1;
+ TERM height := 1;
TERM medium := 0.5;
TERM low := 0;
ACCU: MAX;
@@ -80,14 +80,14 @@
RULEBLOCK No1
AND : MIN;
- RULE 1 : IF TimeDay IS outside AND ApplicateHost IS few THEN ProbabilityAccess IS hight;
- RULE 2 : IF ApplicateHost IS many THEN ProbabilityAccess IS hight;
+ RULE 1 : IF TimeDay IS outside AND ApplicateHost IS few THEN ProbabilityAccess IS height;
+ RULE 2 : IF ApplicateHost IS many THEN ProbabilityAccess IS height;
RULE 3 : IF TimeDay IS inside AND ApplicateHost IS few THEN ProbabilityAccess IS low;
END_RULEBLOCK
RULEBLOCK No2
AND : MIN;
- RULE 1 : IF ApplicateHost IS many THEN ProbabilityDistribution IS hight;
+ RULE 1 : IF ApplicateHost IS many THEN ProbabilityDistribution IS height;
END_RULEBLOCK
END_FUNCTION_BLOCK
diff --git a/help3/xhpeditor/cm/mode/forth/index.html b/help3/xhpeditor/cm/mode/forth/index.html
index ae725ad0..6b6477ca 100644
--- a/help3/xhpeditor/cm/mode/forth/index.html
+++ b/help3/xhpeditor/cm/mode/forth/index.html
@@ -4,7 +4,7 @@
<meta charset="utf-8"/>
<link rel=stylesheet href="../../doc/docs.css">
-<link href='https://fonts.googleapis.com/css?family=Droid+Sans+Mono' rel='stylesheet' type='text/css'>
+<link href='http://fonts.googleapis.com/css?family=Droid+Sans+Mono' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="../../lib/codemirror.css">
<link rel=stylesheet href="../../theme/colorforth.css">
<script src="../../lib/codemirror.js"></script>
@@ -68,7 +68,7 @@
});
</script>
-<p>Simple mode that handle Forth-Syntax (<a href="http://en.wikipedia.org/wiki/Forth_%28programming_language%29">Forth on WikiPedia</a>).</p>
+<p>Simple mode that handle Forth-Syntax (<a href="http://en.wikipedia.org/wiki/Forth_%28programming_language%29">Forth on Wikipedia</a>).</p>
<p><strong>MIME types defined:</strong> <code>text/x-forth</code>.</p>
diff --git a/help3/xhpeditor/cm/mode/gas/gas.js b/help3/xhpeditor/cm/mode/gas/gas.js
index e34d7a7b..b3515abe 100644
--- a/help3/xhpeditor/cm/mode/gas/gas.js
+++ b/help3/xhpeditor/cm/mode/gas/gas.js
@@ -302,11 +302,11 @@ CodeMirror.defineMode("gas", function(_config, parserConfig) {
}
if (ch === '{') {
- return "braket";
+ return "bracket";
}
if (ch === '}') {
- return "braket";
+ return "bracket";
}
if (/\d/.test(ch)) {
diff --git a/help3/xhpeditor/cm/mode/gfm/test.js b/help3/xhpeditor/cm/mode/gfm/test.js
index d933896a..e2002879 100644
--- a/help3/xhpeditor/cm/mode/gfm/test.js
+++ b/help3/xhpeditor/cm/mode/gfm/test.js
@@ -92,7 +92,7 @@
"[em *foo ][em&link bar/hello@be6a8cc1c1ecfe9489fb51e4869af15a13fc2cd2][em *]");
MT("wordSHA",
- "ask for feedbac")
+ "ask for feedback")
MT("num",
"foo [link #1] bar");
diff --git a/help3/xhpeditor/cm/mode/haml/haml.js b/help3/xhpeditor/cm/mode/haml/haml.js
index 3c8f505e..d941d974 100644
--- a/help3/xhpeditor/cm/mode/haml/haml.js
+++ b/help3/xhpeditor/cm/mode/haml/haml.js
@@ -72,7 +72,7 @@
}
}
- // donot handle --> as valid ruby, make it HTML close comment instead
+ // do not handle --> as valid ruby, make it HTML close comment instead
if (state.startOfLine && !stream.match("-->", false) && (ch == "=" || ch == "-" )) {
state.tokenize = ruby;
return state.tokenize(stream, state);
diff --git a/help3/xhpeditor/cm/mode/htmlembedded/index.html b/help3/xhpeditor/cm/mode/htmlembedded/index.html
index b1cafde9..d17afec8 100644
--- a/help3/xhpeditor/cm/mode/htmlembedded/index.html
+++ b/help3/xhpeditor/cm/mode/htmlembedded/index.html
@@ -55,6 +55,6 @@ This is an example of EJS (embedded javascript)
JavaScript, CSS and XML.<br />Other dependencies include those of the scripting language chosen.</p>
<p><strong>MIME types defined:</strong> <code>application/x-aspx</code> (ASP.NET),
- <code>application/x-ejs</code> (Embedded Javascript), <code>application/x-jsp</code> (JavaServer Pages)
+ <code>application/x-ejs</code> (Embedded JavaScript), <code>application/x-jsp</code> (JavaServer Pages)
and <code>application/x-erb</code></p>
</article>
diff --git a/help3/xhpeditor/cm/mode/htmlmixed/htmlmixed.js b/help3/xhpeditor/cm/mode/htmlmixed/htmlmixed.js
index 8341ac82..66a15827 100644
--- a/help3/xhpeditor/cm/mode/htmlmixed/htmlmixed.js
+++ b/help3/xhpeditor/cm/mode/htmlmixed/htmlmixed.js
@@ -74,7 +74,8 @@
name: "xml",
htmlMode: true,
multilineTagIndentFactor: parserConfig.multilineTagIndentFactor,
- multilineTagIndentPastTag: parserConfig.multilineTagIndentPastTag
+ multilineTagIndentPastTag: parserConfig.multilineTagIndentPastTag,
+ allowMissingTagName: parserConfig.allowMissingTagName,
});
var tags = {};
diff --git a/help3/xhpeditor/cm/mode/idl/idl.js b/help3/xhpeditor/cm/mode/idl/idl.js
index 168761cd..37302bb9 100644
--- a/help3/xhpeditor/cm/mode/idl/idl.js
+++ b/help3/xhpeditor/cm/mode/idl/idl.js
@@ -62,7 +62,7 @@
'empty', 'enable_sysrtn', 'eof', 'eos', 'erase',
'erf', 'erfc', 'erfcx', 'erode', 'errorplot',
'errplot', 'estimator_filter', 'execute', 'exit', 'exp',
- 'expand', 'expand_path', 'expint', 'extrac', 'extract_slice',
+ 'expand', 'expand_path', 'expint', 'extract', 'extract_slice',
'f_cvf', 'f_pdf', 'factorial', 'fft', 'file_basename',
'file_chmod', 'file_copy', 'file_delete', 'file_dirname',
'file_expand_path', 'file_gunzip', 'file_gzip', 'file_info',
diff --git a/help3/xhpeditor/cm/mode/index.html b/help3/xhpeditor/cm/mode/index.html
index 858ba127..51205ddc 100644
--- a/help3/xhpeditor/cm/mode/index.html
+++ b/help3/xhpeditor/cm/mode/index.html
@@ -153,6 +153,7 @@ option.</p>
<li><a href="vhdl/index.html">VHDL</a></li>
<li><a href="vue/index.html">Vue.js app</a></li>
<li><a href="webidl/index.html">Web IDL</a></li>
+ <li><a href="wast/index.html">WebAssembly Text Format</a></li>
<li><a href="xml/index.html">XML/HTML</a></li>
<li><a href="xquery/index.html">XQuery</a></li>
<li><a href="yacas/index.html">Yacas</a></li>
diff --git a/help3/xhpeditor/cm/mode/javascript/index.html b/help3/xhpeditor/cm/mode/javascript/index.html
index d1f7f68e..2b6cede8 100644
--- a/help3/xhpeditor/cm/mode/javascript/index.html
+++ b/help3/xhpeditor/cm/mode/javascript/index.html
@@ -99,6 +99,10 @@ StringStream.prototype = {
<li><code>typescript</code> which will activate additional
syntax highlighting and some other things for TypeScript code
(<a href="typescript.html">demo</a>).</li>
+ <li><code>trackScope</code> can be set to false to turn off
+ tracking of local variables. This will prevent locals from
+ getting the <code>"variable-2"</code> token type, and will
+ break completion of locals with javascript-hint.</li>
<li><code>statementIndent</code> which (given a number) will
determine the amount of indentation to use for statements
continued on a new line.</li>
@@ -110,5 +114,5 @@ StringStream.prototype = {
</ul>
</p>
- <p><strong>MIME types defined:</strong> <code>text/javascript</code>, <code>application/json</code>, <code>application/ld+json</code>, <code>text/typescript</code>, <code>application/typescript</code>.</p>
+ <p><strong>MIME types defined:</strong> <code>text/javascript</code>, <code>application/javascript</code>, <code>application/x-javascript</code>, <code>text/ecmascript</code>, <code>application/ecmascript</code>, <code>application/json</code>, <code>application/x-json</code>, <code>application/manifest+json</code>, <code>application/ld+json</code>, <code>text/typescript</code>, <code>application/typescript</code>.</p>
</article>
diff --git a/help3/xhpeditor/cm/mode/javascript/javascript.js b/help3/xhpeditor/cm/mode/javascript/javascript.js
index 16943a9e..2b508c48 100644
--- a/help3/xhpeditor/cm/mode/javascript/javascript.js
+++ b/help3/xhpeditor/cm/mode/javascript/javascript.js
@@ -16,6 +16,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
var statementIndent = parserConfig.statementIndent;
var jsonldMode = parserConfig.jsonld;
var jsonMode = parserConfig.json || jsonldMode;
+ var trackScope = parserConfig.trackScope !== false
var isTS = parserConfig.typescript;
var wordRE = parserConfig.wordCharacters || /[\w$\xa1-\uffff]/;
@@ -98,21 +99,25 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
} else if (ch == "`") {
state.tokenize = tokenQuasi;
return tokenQuasi(stream, state);
- } else if (ch == "#") {
+ } else if (ch == "#" && stream.peek() == "!") {
stream.skipToEnd();
- return ret("error", "error");
- } else if (ch == "<" && stream.match("!--") || ch == "-" && stream.match("->")) {
+ return ret("meta", "meta");
+ } else if (ch == "#" && stream.eatWhile(wordRE)) {
+ return ret("variable", "property")
+ } else if (ch == "<" && stream.match("!--") ||
+ (ch == "-" && stream.match("->") && !/\S/.test(stream.string.slice(0, stream.start)))) {
stream.skipToEnd()
return ret("comment", "comment")
} else if (isOperatorChar.test(ch)) {
if (ch != ">" || !state.lexical || state.lexical.type != ">") {
if (stream.eat("=")) {
if (ch == "!" || ch == "=") stream.eat("=")
- } else if (/[<>*+\-]/.test(ch)) {
+ } else if (/[<>*+\-|&?]/.test(ch)) {
stream.eat(ch)
if (ch == ">") stream.eat(ch)
}
}
+ if (ch == "?" && stream.eat(".")) return ret(".")
return ret("operator", "operator", stream.current());
} else if (wordRE.test(ch)) {
stream.eatWhile(wordRE);
@@ -122,7 +127,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
var kw = keywords[word]
return ret(kw.type, kw.style, word)
}
- if (word == "async" && stream.match(/^(\s|\/\*.*?\*\/)*[\[\(\w]/, false))
+ if (word == "async" && stream.match(/^(\s|\/\*([^*]|\*(?!\/))*?\*\/)*[\[\(\w]/, false))
return ret("async", "keyword", word)
}
return ret("variable", "variable", word)
@@ -214,7 +219,8 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
// Parser
- var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true, "this": true, "jsonld-keyword": true};
+ var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true,
+ "regexp": true, "this": true, "import": true, "jsonld-keyword": true};
function JSLexical(indented, column, type, align, prev, info) {
this.indented = indented;
@@ -226,6 +232,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
}
function inScope(state, varname) {
+ if (!trackScope) return false
for (var v = state.localVars; v; v = v.next)
if (v.name == varname) return true;
for (var cx = state.context; cx; cx = cx.prev) {
@@ -272,6 +279,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
function register(varname) {
var state = cx.state;
cx.marked = "def";
+ if (!trackScope) return
if (state.context) {
if (state.lexical.info == "var" && state.context && state.context.block) {
// FIXME function decls are also not block scoped
@@ -371,7 +379,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
return cont(pushlex("form"), parenExpr, statement, poplex, maybeelse);
}
if (type == "function") return cont(functiondef);
- if (type == "for") return cont(pushlex("form"), forspec, statement, poplex);
+ if (type == "for") return cont(pushlex("form"), pushblockcontext, forspec, statement, popcontext, poplex);
if (type == "class" || (isTS && value == "interface")) {
cx.marked = "keyword"
return cont(pushlex("form", type == "class" ? type : value), className, poplex)
@@ -417,7 +425,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
}
function parenExpr(type) {
if (type != "(") return pass()
- return cont(pushlex(")"), expression, expect(")"), poplex)
+ return cont(pushlex(")"), maybeexpression, expect(")"), poplex)
}
function expressionInner(type, value, noComma) {
if (cx.state.fatArrowAt == cx.stream.start) {
@@ -437,7 +445,6 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (type == "{") return contCommasep(objprop, "}", null, maybeop);
if (type == "quasi") return pass(quasi, maybeop);
if (type == "new") return cont(maybeTarget(noComma));
- if (type == "import") return cont(expression);
return cont();
}
function maybeexpression(type) {
@@ -446,7 +453,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
}
function maybeoperatorComma(type, value) {
- if (type == ",") return cont(expression);
+ if (type == ",") return cont(maybeexpression);
return maybeoperatorNoComma(type, value, false);
}
function maybeoperatorNoComma(type, value, noComma) {
@@ -455,7 +462,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (type == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext);
if (type == "operator") {
if (/\+\+|--/.test(value) || isTS && value == "!") return cont(me);
- if (isTS && value == "<" && cx.stream.match(/^([^>]|<.*?>)*>\s*\(/, false))
+ if (isTS && value == "<" && cx.stream.match(/^([^<>]|<[^<>]*>)*>\s*\(/, false))
return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, me);
if (value == "?") return cont(expression, expect(":"), expr);
return cont(expr);
@@ -601,7 +608,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
}
}
function typeexpr(type, value) {
- if (value == "keyof" || value == "typeof" || value == "infer") {
+ if (value == "keyof" || value == "typeof" || value == "infer" || value == "readonly") {
cx.marked = "keyword"
return cont(value == "typeof" ? expressionNoComma : typeexpr)
}
@@ -612,13 +619,19 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (value == "|" || value == "&") return cont(typeexpr)
if (type == "string" || type == "number" || type == "atom") return cont(afterType);
if (type == "[") return cont(pushlex("]"), commasep(typeexpr, "]", ","), poplex, afterType)
- if (type == "{") return cont(pushlex("}"), commasep(typeprop, "}", ",;"), poplex, afterType)
+ if (type == "{") return cont(pushlex("}"), typeprops, poplex, afterType)
if (type == "(") return cont(commasep(typearg, ")"), maybeReturnType, afterType)
if (type == "<") return cont(commasep(typeexpr, ">"), typeexpr)
+ if (type == "quasi") { return pass(quasiType, afterType); }
}
function maybeReturnType(type) {
if (type == "=>") return cont(typeexpr)
}
+ function typeprops(type) {
+ if (type.match(/[\}\)\]]/)) return cont()
+ if (type == "," || type == ";") return cont(typeprops)
+ return pass(typeprop, typeprops)
+ }
function typeprop(type, value) {
if (type == "variable" || cx.style == "keyword") {
cx.marked = "property"
@@ -631,6 +644,20 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
return cont(expect("variable"), maybetypeOrIn, expect("]"), typeprop)
} else if (type == "(") {
return pass(functiondecl, typeprop)
+ } else if (!type.match(/[;\}\)\],]/)) {
+ return cont()
+ }
+ }
+ function quasiType(type, value) {
+ if (type != "quasi") return pass();
+ if (value.slice(value.length - 2) != "${") return cont(quasiType);
+ return cont(typeexpr, continueQuasiType);
+ }
+ function continueQuasiType(type) {
+ if (type == "}") {
+ cx.marked = "string-2";
+ cx.state.tokenize = tokenQuasi;
+ return cont(quasiType);
}
}
function typearg(type, value) {
@@ -757,11 +784,11 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
}
if (type == "variable" || cx.style == "keyword") {
cx.marked = "property";
- return cont(isTS ? classfield : functiondef, classBody);
+ return cont(classfield, classBody);
}
- if (type == "number" || type == "string") return cont(isTS ? classfield : functiondef, classBody);
+ if (type == "number" || type == "string") return cont(classfield, classBody);
if (type == "[")
- return cont(expression, maybetype, expect("]"), isTS ? classfield : functiondef, classBody)
+ return cont(expression, maybetype, expect("]"), classfield, classBody)
if (value == "*") {
cx.marked = "keyword";
return cont(classBody);
@@ -772,6 +799,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (value == "@") return cont(expression, classBody)
}
function classfield(type, value) {
+ if (value == "!") return cont(classfield)
if (value == "?") return cont(classfield)
if (type == ":") return cont(typeexpr, maybeAssign)
if (value == "=") return cont(expressionNoComma)
@@ -791,6 +819,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
function afterImport(type) {
if (type == "string") return cont();
if (type == "(") return pass(expression);
+ if (type == ".") return pass(maybeoperatorComma);
return pass(importSpec, maybeMoreImports, maybeFrom);
}
function importSpec(type, value) {
@@ -864,14 +893,14 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
},
indent: function(state, textAfter) {
- if (state.tokenize == tokenComment) return CodeMirror.Pass;
+ if (state.tokenize == tokenComment || state.tokenize == tokenQuasi) return CodeMirror.Pass;
if (state.tokenize != tokenBase) return 0;
var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical, top
// Kludge to prevent 'maybelse' from blocking lexical scope pops
if (!/^\s*else\b/.test(textAfter)) for (var i = state.cc.length - 1; i >= 0; --i) {
var c = state.cc[i];
if (c == poplex) lexical = lexical.prev;
- else if (c != maybeelse) break;
+ else if (c != maybeelse && c != popcontext) break;
}
while ((lexical.type == "stat" || lexical.type == "form") &&
(firstChar == "}" || ((top = state.cc[state.cc.length - 1]) &&
@@ -908,8 +937,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
expressionAllowed: expressionAllowed,
skipExpression: function(state) {
- var top = state.cc[state.cc.length - 1]
- if (top == expression || top == expressionNoComma) state.cc.pop()
+ parseJS(state, "atom", "atom", "true", new CodeMirror.StringStream("", 2, null))
}
};
});
@@ -921,9 +949,10 @@ CodeMirror.defineMIME("text/ecmascript", "javascript");
CodeMirror.defineMIME("application/javascript", "javascript");
CodeMirror.defineMIME("application/x-javascript", "javascript");
CodeMirror.defineMIME("application/ecmascript", "javascript");
-CodeMirror.defineMIME("application/json", {name: "javascript", json: true});
-CodeMirror.defineMIME("application/x-json", {name: "javascript", json: true});
-CodeMirror.defineMIME("application/ld+json", {name: "javascript", jsonld: true});
+CodeMirror.defineMIME("application/json", { name: "javascript", json: true });
+CodeMirror.defineMIME("application/x-json", { name: "javascript", json: true });
+CodeMirror.defineMIME("application/manifest+json", { name: "javascript", json: true })
+CodeMirror.defineMIME("application/ld+json", { name: "javascript", jsonld: true });
CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true });
CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript: true });
diff --git a/help3/xhpeditor/cm/mode/javascript/test.js b/help3/xhpeditor/cm/mode/javascript/test.js
index 327eac76..e7303020 100644
--- a/help3/xhpeditor/cm/mode/javascript/test.js
+++ b/help3/xhpeditor/cm/mode/javascript/test.js
@@ -164,9 +164,9 @@
MT("indent_for",
"[keyword for] ([keyword var] [def i] [operator =] [number 0];",
- " [variable i] [operator <] [number 100];",
- " [variable i][operator ++])",
- " [variable doSomething]([variable i]);",
+ " [variable-2 i] [operator <] [number 100];",
+ " [variable-2 i][operator ++])",
+ " [variable doSomething]([variable-2 i]);",
"[keyword debugger];");
MT("indent_c_style",
@@ -252,7 +252,7 @@
MT("async_object",
"[keyword let] [def obj] [operator =] { [property async]: [atom false] };");
- // async be highlighet as keyword and foo as def, but it requires potentially expensive look-ahead. See #4173
+ // async be highlighted as keyword and foo as def, but it requires potentially expensive look-ahead. See #4173
MT("async_object_function",
"[keyword let] [def obj] [operator =] { [property async] [property foo]([def args]) { [keyword return] [atom true]; } };");
@@ -317,6 +317,14 @@
"[variable _for];",
"[variable _123];")
+ MT("private properties",
+ "[keyword class] [def C] {",
+ " [property #x] [operator =] [number 2];",
+ " [property #read]() {",
+ " [keyword return] [keyword this].[property #x]",
+ " }",
+ "}")
+
var ts_mode = CodeMirror.getMode({indentUnit: 2}, "application/typescript")
function TS(name) {
test.mode(name, ts_mode, Array.prototype.slice.call(arguments, 1))
diff --git a/help3/xhpeditor/cm/mode/jsx/jsx.js b/help3/xhpeditor/cm/mode/jsx/jsx.js
index 889d3fe5..beea3b91 100644
--- a/help3/xhpeditor/cm/mode/jsx/jsx.js
+++ b/help3/xhpeditor/cm/mode/jsx/jsx.js
@@ -104,9 +104,9 @@
function jsToken(stream, state, cx) {
if (stream.peek() == "<" && jsMode.expressionAllowed(stream, cx.state)) {
- jsMode.skipExpression(cx.state)
state.context = new Context(CodeMirror.startState(xmlMode, jsMode.indent(cx.state, "", "")),
xmlMode, 0, state.context)
+ jsMode.skipExpression(cx.state)
return null
}
diff --git a/help3/xhpeditor/cm/mode/jsx/test.js b/help3/xhpeditor/cm/mode/jsx/test.js
index 5ecd5a8b..b47a3521 100644
--- a/help3/xhpeditor/cm/mode/jsx/test.js
+++ b/help3/xhpeditor/cm/mode/jsx/test.js
@@ -73,6 +73,13 @@
MT("tag_attribute",
"([bracket&tag <][tag foo] [attribute bar]=[bracket&tag <][tag foo][bracket&tag />/>][operator ++])")
+ MT("in_array",
+ "[[",
+ " [bracket&tag <][tag Something][bracket&tag />],",
+ " [string-2 `${][variable x][string-2 }`],",
+ " [variable y]",
+ "]]")
+
var ts_mode = CodeMirror.getMode({indentUnit: 2}, "text/typescript-jsx")
function TS(name) { test.mode(name, ts_mode, Array.prototype.slice.call(arguments, 1)) }
diff --git a/help3/xhpeditor/cm/mode/julia/julia.js b/help3/xhpeditor/cm/mode/julia/julia.js
index 0cc9bc07..de9f987d 100644
--- a/help3/xhpeditor/cm/mode/julia/julia.js
+++ b/help3/xhpeditor/cm/mode/julia/julia.js
@@ -80,7 +80,7 @@ CodeMirror.defineMode("julia", function(config, parserConf) {
// tokenizers
function tokenBase(stream, state) {
// Handle multiline comments
- if (stream.match(/^#=/, false)) {
+ if (stream.match('#=', false)) {
state.tokenize = tokenComment;
return state.tokenize(stream, state);
}
@@ -127,24 +127,24 @@ CodeMirror.defineMode("julia", function(config, parserConf) {
}
if (inArray(state) && ch === ']') {
- while (currentScope(state) !== "[") { state.scopes.pop(); }
+ while (state.scopes.length && currentScope(state) !== "[") { state.scopes.pop(); }
state.scopes.pop();
state.nestedArrays--;
state.leavingExpr = true;
}
if (inGenerator(state) && ch === ')') {
- while (currentScope(state) !== "(") { state.scopes.pop(); }
+ while (state.scopes.length && currentScope(state) !== "(") { state.scopes.pop(); }
state.scopes.pop();
state.nestedGenerators--;
state.leavingExpr = true;
}
if (inArray(state)) {
- if (state.lastToken == "end" && stream.match(/^:/)) {
+ if (state.lastToken == "end" && stream.match(':')) {
return "operator";
}
- if (stream.match(/^end/)) {
+ if (stream.match('end')) {
return "number";
}
}
@@ -201,7 +201,7 @@ CodeMirror.defineMode("julia", function(config, parserConf) {
}
// Handle Chars
- if (stream.match(/^'/)) {
+ if (stream.match('\'')) {
state.tokenize = tokenChar;
return state.tokenize(stream, state);
}
@@ -241,10 +241,6 @@ CodeMirror.defineMode("julia", function(config, parserConf) {
state.isDefinition = false;
return "def";
}
- if (stream.match(/^({[^}]*})*\(/, false)) {
- state.tokenize = tokenCallOrDef;
- return state.tokenize(stream, state);
- }
state.leavingExpr = true;
return "variable";
}
@@ -254,49 +250,11 @@ CodeMirror.defineMode("julia", function(config, parserConf) {
return "error";
}
- function tokenCallOrDef(stream, state) {
- var match = stream.match(/^(\(\s*)/);
- if (match) {
- if (state.firstParenPos < 0)
- state.firstParenPos = state.scopes.length;
- state.scopes.push('(');
- state.charsAdvanced += match[1].length;
- }
- if (currentScope(state) == '(' && stream.match(/^\)/)) {
- state.scopes.pop();
- state.charsAdvanced += 1;
- if (state.scopes.length <= state.firstParenPos) {
- var isDefinition = stream.match(/^(\s*where\s+[^\s=]+)*\s*?=(?!=)/, false);
- stream.backUp(state.charsAdvanced);
- state.firstParenPos = -1;
- state.charsAdvanced = 0;
- state.tokenize = tokenBase;
- if (isDefinition)
- return "def";
- return "builtin";
- }
- }
- // Unfortunately javascript does not support multiline strings, so we have
- // to undo anything done upto here if a function call or definition splits
- // over two or more lines.
- if (stream.match(/^$/g, false)) {
- stream.backUp(state.charsAdvanced);
- while (state.scopes.length > state.firstParenPos)
- state.scopes.pop();
- state.firstParenPos = -1;
- state.charsAdvanced = 0;
- state.tokenize = tokenBase;
- return "builtin";
- }
- state.charsAdvanced += stream.match(/^([^()]*)/)[1].length;
- return state.tokenize(stream, state);
- }
-
function tokenAnnotation(stream, state) {
- stream.match(/.*?(?=,|;|{|}|\(|\)|=|$|\s)/);
- if (stream.match(/^{/)) {
+ stream.match(/.*?(?=[,;{}()=\s]|$)/);
+ if (stream.match('{')) {
state.nestedParameters++;
- } else if (stream.match(/^}/) && state.nestedParameters > 0) {
+ } else if (stream.match('}') && state.nestedParameters > 0) {
state.nestedParameters--;
}
if (state.nestedParameters > 0) {
@@ -308,13 +266,13 @@ CodeMirror.defineMode("julia", function(config, parserConf) {
}
function tokenComment(stream, state) {
- if (stream.match(/^#=/)) {
+ if (stream.match('#=')) {
state.nestedComments++;
}
if (!stream.match(/.*?(?=(#=|=#))/)) {
stream.skipToEnd();
}
- if (stream.match(/^=#/)) {
+ if (stream.match('=#')) {
state.nestedComments--;
if (state.nestedComments == 0)
state.tokenize = tokenBase;
@@ -345,7 +303,7 @@ CodeMirror.defineMode("julia", function(config, parserConf) {
return "string";
}
if (!stream.match(/^[^']+(?=')/)) { stream.skipToEnd(); }
- if (stream.match(/^'/)) { state.tokenize = tokenBase; }
+ if (stream.match('\'')) { state.tokenize = tokenBase; }
return "error";
}
@@ -383,7 +341,6 @@ CodeMirror.defineMode("julia", function(config, parserConf) {
nestedComments: 0,
nestedGenerators: 0,
nestedParameters: 0,
- charsAdvanced: 0,
firstParenPos: -1
};
},
@@ -401,9 +358,9 @@ CodeMirror.defineMode("julia", function(config, parserConf) {
indent: function(state, textAfter) {
var delta = 0;
- if ( textAfter === ']' || textAfter === ')' || textAfter === "end" ||
- textAfter === "else" || textAfter === "catch" || textAfter === "elseif" ||
- textAfter === "finally" ) {
+ if ( textAfter === ']' || textAfter === ')' || /^end\b/.test(textAfter) ||
+ /^else/.test(textAfter) || /^catch\b/.test(textAfter) || /^elseif\b/.test(textAfter) ||
+ /^finally/.test(textAfter) ) {
delta = -1;
}
return (state.scopes.length + delta) * config.indentUnit;
diff --git a/help3/xhpeditor/cm/mode/lua/lua.js b/help3/xhpeditor/cm/mode/lua/lua.js
index 202f3735..2fad0180 100644
--- a/help3/xhpeditor/cm/mode/lua/lua.js
+++ b/help3/xhpeditor/cm/mode/lua/lua.js
@@ -148,6 +148,7 @@ CodeMirror.defineMode("lua", function(config, parserConfig) {
return state.basecol + indentUnit * (state.indentDepth - (closing ? 1 : 0));
},
+ electricInput: /^\s*(?:end|until|else|\)|\})$/,
lineComment: "--",
blockCommentStart: "--[[",
blockCommentEnd: "]]"
diff --git a/help3/xhpeditor/cm/mode/markdown/index.html b/help3/xhpeditor/cm/mode/markdown/index.html
index 96df23eb..4984c04b 100644
--- a/help3/xhpeditor/cm/mode/markdown/index.html
+++ b/help3/xhpeditor/cm/mode/markdown/index.html
@@ -159,7 +159,7 @@ Output:
Unordered (bulleted) lists use asterisks, pluses, and hyphens (`*`,
`+`, and `-`) as list markers. These three markers are
-interchangable; this:
+interchangeable; this:
* Candy.
* Gum.
@@ -251,13 +251,13 @@ you define elsewhere in your document:
I get 10 times more traffic from [Google][1] than from
[Yahoo][2] or [MSN][3].
- [1]: https://google.com/ "Google"
+ [1]: http://google.com/ "Google"
[2]: http://search.yahoo.com/ "Yahoo Search"
[3]: http://search.msn.com/ "MSN Search"
Output:
- &lt;p&gt;I get 10 times more traffic from &lt;a href="https://google.com/"
+ &lt;p&gt;I get 10 times more traffic from &lt;a href="http://google.com/"
title="Google"&gt;Google&lt;/a&gt; than from &lt;a href="http://search.yahoo.com/"
title="Yahoo Search"&gt;Yahoo&lt;/a&gt; or &lt;a href="http://search.msn.com/"
title="MSN Search"&gt;MSN&lt;/a&gt;.&lt;/p&gt;
@@ -306,7 +306,7 @@ it easy to use Markdown to write about HTML example code:
I strongly recommend against using any `&lt;blink&gt;` tags.
I wish SmartyPants used named entities like `&amp;mdash;`
- instead of decimal-encoded entites like `&amp;#8212;`.
+ instead of decimal-encoded entities like `&amp;#8212;`.
Output:
@@ -315,7 +315,7 @@ Output:
&lt;p&gt;I wish SmartyPants used named entities like
&lt;code&gt;&amp;amp;mdash;&lt;/code&gt; instead of decimal-encoded
- entites like &lt;code&gt;&amp;amp;#8212;&lt;/code&gt;.&lt;/p&gt;
+ entities like &lt;code&gt;&amp;amp;#8212;&lt;/code&gt;.&lt;/p&gt;
To specify an entire block of pre-formatted code, indent every line of
@@ -360,7 +360,7 @@ for (var i = 0; i < items.length; i++) {
});
</script>
- <p>If you also want support <code>strikethrough</code>, <code>emoji</code> and few other goodies, check out <a href="../gfm/index.html">Github-Flavored Markdown mode</a>.</p>
+ <p>If you also want support <code>strikethrough</code>, <code>emoji</code> and few other goodies, check out <a href="../gfm/index.html">GitHub-Flavored Markdown mode</a>.</p>
<p>Optionally depends on other modes for properly highlighted code blocks,
and XML mode for properly highlighted inline XML blocks.</p>
@@ -370,7 +370,7 @@ for (var i = 0; i < items.length; i++) {
<li>
<d1>
<dt><code>highlightFormatting: boolean</code></dt>
- <dd>Whether to separately highlight markdown meta characterts (<code>*[]()</code>etc.) (default: <code>false</code>).</dd>
+ <dd>Whether to separately highlight markdown meta characters (<code>*[]()</code>etc.) (default: <code>false</code>).</dd>
</d1>
</li>
<li>
@@ -388,13 +388,19 @@ for (var i = 0; i < items.length; i++) {
<li>
<d1>
<dt><code>fencedCodeBlockHighlighting: boolean</code></dt>
- <dd>Whether to syntax-highlight fenced code blocks, if given mode is included (default: <code>true</code>).</dd>
+ <dd>Whether to syntax-highlight fenced code blocks, if given mode is included, or fencedCodeBlockDefaultMode is set (default: <code>true</code>).</dd>
+ </d1>
+ </li>
+ <li>
+ <d1>
+ <dt><code>fencedCodeBlockDefaultMode: string</code></dt>
+ <dd>Mode to use for fencedCodeBlockHighlighting, if given mode is not included.</dd>
</d1>
</li>
<li>
<d1>
<dt><code>tokenTypeOverrides: Object</code></dt>
- <dd>When you want ot override default token type names (e.g. <code>{code: "code"}</code>).</dd>
+ <dd>When you want to override default token type names (e.g. <code>{code: "code"}</code>).</dd>
</d1>
</li>
<li>
diff --git a/help3/xhpeditor/cm/mode/markdown/markdown.js b/help3/xhpeditor/cm/mode/markdown/markdown.js
index 30f94e09..a9e272ea 100644
--- a/help3/xhpeditor/cm/mode/markdown/markdown.js
+++ b/help3/xhpeditor/cm/mode/markdown/markdown.js
@@ -48,6 +48,9 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
if (modeCfg.fencedCodeBlockHighlighting === undefined)
modeCfg.fencedCodeBlockHighlighting = true;
+ if (modeCfg.fencedCodeBlockDefaultMode === undefined)
+ modeCfg.fencedCodeBlockDefaultMode = 'text/plain';
+
if (modeCfg.xml === undefined)
modeCfg.xml = true;
@@ -87,9 +90,9 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
, listRE = /^(?:[*\-+]|^[0-9]+([.)]))\s+/
, taskListRE = /^\[(x| )\](?=\s)/i // Must follow listRE
, atxHeaderRE = modeCfg.allowAtxHeaderWithoutSpace ? /^(#+)/ : /^(#+)(?: |$)/
- , setextHeaderRE = /^ *(?:\={1,}|-{1,})\s*$/
+ , setextHeaderRE = /^ {0,3}(?:\={1,}|-{2,})\s*$/
, textRE = /^[^#!\[\]*_\\<>` "'(~:]+/
- , fencedCodeRE = /^(~~~+|```+)[ \t]*([\w+#-]*)[^\n`]*$/
+ , fencedCodeRE = /^(~~~+|```+)[ \t]*([\w\/+#-]*)[^\n`]*$/
, linkDefRE = /^\s*\[[^\]]+?\]:.*$/ // naive link-definition
, punctuation = /[!"#$%&'()*+,\-.\/:;<=>?@\[\\\]^_`{|}~\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061E\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u0AF0\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166D\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E42\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]|\uD800[\uDD00-\uDD02\uDF9F\uDFD0]|\uD801\uDD6F|\uD802[\uDC57\uDD1F\uDD3F\uDE50-\uDE58\uDE7F\uDEF0-\uDEF6\uDF39-\uDF3F\uDF99-\uDF9C]|\uD804[\uDC47-\uDC4D\uDCBB\uDCBC\uDCBE-\uDCC1\uDD40-\uDD43\uDD74\uDD75\uDDC5-\uDDC9\uDDCD\uDDDB\uDDDD-\uDDDF\uDE38-\uDE3D\uDEA9]|\uD805[\uDCC6\uDDC1-\uDDD7\uDE41-\uDE43\uDF3C-\uDF3E]|\uD809[\uDC70-\uDC74]|\uD81A[\uDE6E\uDE6F\uDEF5\uDF37-\uDF3B\uDF44]|\uD82F\uDC9F|\uD836[\uDE87-\uDE8B]/
, expandedTab = " " // CommonMark specifies tab as 4 spaces
@@ -220,7 +223,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
// Add this list item's content's indentation to the stack
state.listStack.push(state.indentation);
- // Reset inline styles which shouldn't propagate aross list items
+ // Reset inline styles which shouldn't propagate across list items
state.em = false;
state.strong = false;
state.code = false;
@@ -236,7 +239,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
state.quote = 0;
state.fencedEndRE = new RegExp(match[1] + "+ *$");
// try switching mode
- state.localMode = modeCfg.fencedCodeBlockHighlighting && getMode(match[2]);
+ state.localMode = modeCfg.fencedCodeBlockHighlighting && getMode(match[2] || modeCfg.fencedCodeBlockDefaultMode );
if (state.localMode) state.localState = CodeMirror.startState(state.localMode);
state.f = state.block = local;
if (modeCfg.highlightFormatting) state.formatting = "code-block";
@@ -609,7 +612,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
return getType(state);
}
} else if (ch === ' ') {
- if (stream.match(/^~~/, true)) { // Probably surrounded by space
+ if (stream.match('~~', true)) { // Probably surrounded by space
if (stream.peek() === ' ') { // Surrounded by spaces, ignore
return getType(state);
} else { // Not surrounded by spaces, back up pointer
@@ -708,7 +711,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
}
function footnoteLinkInside(stream, state) {
- if (stream.match(/^\]:/, true)) {
+ if (stream.match(']:', true)) {
state.f = state.inline = footnoteUrl;
if (modeCfg.highlightFormatting) state.formatting = "link";
var returnType = getType(state);
@@ -732,7 +735,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
if (stream.peek() === undefined) { // End of line, set flag to check next line
state.linkTitle = true;
} else { // More content on line, check if link title
- stream.match(/^(?:\s+(?:"(?:[^"\\]|\\\\|\\.)+"|'(?:[^'\\]|\\\\|\\.)+'|\((?:[^)\\]|\\\\|\\.)+\)))?/, true);
+ stream.match(/^(?:\s+(?:"(?:[^"\\]|\\.)+"|'(?:[^'\\]|\\.)+'|\((?:[^)\\]|\\.)+\)))?/, true);
}
state.f = state.inline = inlineNormal;
return tokenTypes.linkHref + " url";
diff --git a/help3/xhpeditor/cm/mode/markdown/test.js b/help3/xhpeditor/cm/mode/markdown/test.js
index c85589cf..fd5a1fb4 100644
--- a/help3/xhpeditor/cm/mode/markdown/test.js
+++ b/help3/xhpeditor/cm/mode/markdown/test.js
@@ -286,10 +286,12 @@
"[header&header-1 foo]",
"[header&header-1 ===]");
- // Check if single underlining - works
- MT("setextH2",
- "[header&header-2 foo]",
- "[header&header-2 -]");
+ // Check if single underlining - should not be interpreted
+ // as it might lead to an empty list:
+ // https://spec.commonmark.org/0.28/#setext-heading-underline
+ MT("setextH2Single",
+ "foo",
+ "-");
// Check if 3+ -'s work
MT("setextH2",
@@ -313,7 +315,7 @@
"[header&header-2 bar]",
"[header&header-2 ---]");
- MT("setextAferATX",
+ MT("setextAfterATX",
"[header&header-1 # foo]",
"[header&header-2 bar]",
"[header&header-2 ---]");
@@ -370,7 +372,7 @@
"[header&header-1 =]");
MT("setext_linkDef",
- "[link [[aaa]]:] [string&url https://google.com 'title']",
+ "[link [[aaa]]:] [string&url http://google.com 'title']",
"[hr ---]");
// currently, looks max one line ahead, thus won't catch valid CommonMark
@@ -380,10 +382,10 @@
"[header&header-1 bar]",
"[header&header-1 =]");
- // ensure we don't regard space after dash as a list
+ // ensure we regard space after a single dash as a list
MT("setext_emptyList",
- "[header&header-2 foo]",
- "[header&header-2 - ]",
+ "foo",
+ "[variable-2 - ]",
"foo");
// Single-line blockquote with trailing space
@@ -657,7 +659,7 @@
" [variable-2 text after fenced code]");
// should correctly parse numbered list content indentation
- MT("listCommonMark_NumeberedListIndent",
+ MT("listCommonMark_NumberedListIndent",
"[variable-2 1000. list with base indent of 6]",
"",
" [variable-2 text must be indented 6 spaces at minimum]",
diff --git a/help3/xhpeditor/cm/mode/meta.js b/help3/xhpeditor/cm/mode/meta.js
index d44590f6..477d6ae2 100644
--- a/help3/xhpeditor/cm/mode/meta.js
+++ b/help3/xhpeditor/cm/mode/meta.js
@@ -24,7 +24,7 @@
{name: "Clojure", mime: "text/x-clojure", mode: "clojure", ext: ["clj", "cljc", "cljx"]},
{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: "CMake", mime: "text/x-cmake", mode: "cmake", ext: ["cmake", "cmake.in"], file: /^CMakeLists\.txt$/},
{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"]},
@@ -44,7 +44,7 @@
{name: "edn", mime: "application/edn", mode: "clojure", ext: ["edn"]},
{name: "Eiffel", mime: "text/x-eiffel", mode: "eiffel", ext: ["e"]},
{name: "Elm", mime: "text/x-elm", mode: "elm", ext: ["elm"]},
- {name: "Embedded Javascript", mime: "application/x-ejs", mode: "htmlembedded", ext: ["ejs"]},
+ {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"},
@@ -55,7 +55,7 @@
{name: "F#", mime: "text/x-fsharp", mode: "mllike", ext: ["fs"], alias: ["fsharp"]},
{name: "Gas", mime: "text/x-gas", mode: "gas", ext: ["s"]},
{name: "Gherkin", mime: "text/x-feature", mode: "gherkin", ext: ["feature"]},
- {name: "GitHub Flavored Markdown", mime: "text/x-gfm", mode: "gfm", file: /^(readme|contributing|history).md$/i},
+ {name: "GitHub Flavored Markdown", mime: "text/x-gfm", mode: "gfm", file: /^(readme|contributing|history)\.md$/i},
{name: "Go", mime: "text/x-go", mode: "go", ext: ["go"]},
{name: "Groovy", mime: "text/x-groovy", mode: "groovy", ext: ["groovy", "gradle"], file: /^Jenkinsfile$/},
{name: "HAML", mime: "text/x-haml", mode: "haml", ext: ["haml"]},
@@ -76,7 +76,7 @@
{name: "JSON-LD", mime: "application/ld+json", mode: "javascript", ext: ["jsonld"], alias: ["jsonld"]},
{name: "JSX", mime: "text/jsx", mode: "jsx", ext: ["jsx"]},
{name: "Jinja2", mime: "text/jinja2", mode: "jinja2", ext: ["j2", "jinja", "jinja2"]},
- {name: "Julia", mime: "text/x-julia", mode: "julia", ext: ["jl"]},
+ {name: "Julia", mime: "text/x-julia", mode: "julia", ext: ["jl"], alias: ["jl"]},
{name: "Kotlin", mime: "text/x-kotlin", mode: "clike", ext: ["kt"]},
{name: "LESS", mime: "text/x-less", mode: "css", ext: ["less"]},
{name: "LiveScript", mime: "text/x-livescript", mode: "livescript", ext: ["ls"], alias: ["ls"]},
@@ -144,7 +144,7 @@
{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"},
+ {name: "TiddlyWiki", mime: "text/x-tiddlywiki", mode: "tiddlywiki"},
{name: "Tiki wiki", mime: "text/tiki", mode: "tiki"},
{name: "TOML", mime: "text/x-toml", mode: "toml", ext: ["toml"]},
{name: "Tornado", mime: "text/x-tornado", mode: "tornado"},
@@ -169,7 +169,8 @@
{name: "Z80", mime: "text/x-z80", mode: "z80", ext: ["z80"]},
{name: "mscgen", mime: "text/x-mscgen", mode: "mscgen", ext: ["mscgen", "mscin", "msc"]},
{name: "xu", mime: "text/x-xu", mode: "mscgen", ext: ["xu"]},
- {name: "msgenny", mime: "text/x-msgenny", mode: "mscgen", ext: ["msgenny"]}
+ {name: "msgenny", mime: "text/x-msgenny", mode: "mscgen", ext: ["msgenny"]},
+ {name: "WebAssembly", mime: "text/webassembly", mode: "wast", ext: ["wat", "wast"]},
];
// Ensure all modes have a mime property for backwards compatibility
for (var i = 0; i < CodeMirror.modeInfo.length; i++) {
diff --git a/help3/xhpeditor/cm/mode/modelica/modelica.js b/help3/xhpeditor/cm/mode/modelica/modelica.js
index a83a4135..2e9622f0 100644
--- a/help3/xhpeditor/cm/mode/modelica/modelica.js
+++ b/help3/xhpeditor/cm/mode/modelica/modelica.js
@@ -90,7 +90,7 @@
return "error";
}
- function tokenUnsignedNuber(stream, state) {
+ function tokenUnsignedNumber(stream, state) {
stream.eatWhile(isDigit);
if (stream.eat('.')) {
stream.eatWhile(isDigit);
@@ -164,9 +164,9 @@
else if(ch == '"') {
state.tokenize = tokenString;
}
- // UNSIGNED_NUBER
+ // UNSIGNED_NUMBER
else if(isDigit.test(ch)) {
- state.tokenize = tokenUnsignedNuber;
+ state.tokenize = tokenUnsignedNumber;
}
// ERROR
else {
diff --git a/help3/xhpeditor/cm/mode/mscgen/mscgen.js b/help3/xhpeditor/cm/mode/mscgen/mscgen.js
index 6f4f9cd8..8d39341c 100644
--- a/help3/xhpeditor/cm/mode/mscgen/mscgen.js
+++ b/help3/xhpeditor/cm/mode/mscgen/mscgen.js
@@ -72,11 +72,11 @@
CodeMirror.defineMIME("text/x-msgenny", {name: "mscgen", language: "msgenny"});
function wordRegexpBoundary(pWords) {
- return new RegExp("\\b(" + pWords.join("|") + ")\\b", "i");
+ return new RegExp("^\\b(?:" + pWords.join("|") + ")\\b", "i");
}
function wordRegexp(pWords) {
- return new RegExp("(" + pWords.join("|") + ")", "i");
+ return new RegExp("^(?:" + pWords.join("|") + ")", "i");
}
function startStateFn() {
@@ -153,7 +153,7 @@
return "variable";
/* attribute lists */
- if (!pConfig.inAttributeList && !!pConfig.attributes && pStream.match(/\[/, true, true)) {
+ if (!pConfig.inAttributeList && !!pConfig.attributes && pStream.match('[', true, true)) {
pConfig.inAttributeList = true;
return "bracket";
}
@@ -161,7 +161,7 @@
if (pConfig.attributes !== null && pStream.match(wordRegexpBoundary(pConfig.attributes), true, true)) {
return "attribute";
}
- if (pStream.match(/]/, true, true)) {
+ if (pStream.match(']', true, true)) {
pConfig.inAttributeList = false;
return "bracket";
}
diff --git a/help3/xhpeditor/cm/mode/mumps/mumps.js b/help3/xhpeditor/cm/mode/mumps/mumps.js
index 3671c9cb..c53b4bf3 100644
--- a/help3/xhpeditor/cm/mode/mumps/mumps.js
+++ b/help3/xhpeditor/cm/mode/mumps/mumps.js
@@ -26,7 +26,7 @@
var brackets = new RegExp("[()]");
var identifiers = new RegExp("^[%A-Za-z][A-Za-z0-9]*");
var commandKeywords = ["break","close","do","else","for","goto", "halt", "hang", "if", "job","kill","lock","merge","new","open", "quit", "read", "set", "tcommit", "trollback", "tstart", "use", "view", "write", "xecute", "b","c","d","e","f","g", "h", "i", "j","k","l","m","n","o", "q", "r", "s", "tc", "tro", "ts", "u", "v", "w", "x"];
- // The following list includes instrinsic functions _and_ special variables
+ // The following list includes intrinsic functions _and_ special variables
var intrinsicFuncsWords = ["\\$ascii", "\\$char", "\\$data", "\\$ecode", "\\$estack", "\\$etrap", "\\$extract", "\\$find", "\\$fnumber", "\\$get", "\\$horolog", "\\$io", "\\$increment", "\\$job", "\\$justify", "\\$length", "\\$name", "\\$next", "\\$order", "\\$piece", "\\$qlength", "\\$qsubscript", "\\$query", "\\$quit", "\\$random", "\\$reverse", "\\$select", "\\$stack", "\\$test", "\\$text", "\\$translate", "\\$view", "\\$x", "\\$y", "\\$a", "\\$c", "\\$d", "\\$e", "\\$ec", "\\$es", "\\$et", "\\$f", "\\$fn", "\\$g", "\\$h", "\\$i", "\\$j", "\\$l", "\\$n", "\\$na", "\\$o", "\\$p", "\\$q", "\\$ql", "\\$qs", "\\$r", "\\$re", "\\$s", "\\$st", "\\$t", "\\$tr", "\\$v", "\\$z"];
var intrinsicFuncs = wordRegexp(intrinsicFuncsWords);
var command = wordRegexp(commandKeywords);
diff --git a/help3/xhpeditor/cm/mode/nginx/index.html b/help3/xhpeditor/cm/mode/nginx/index.html
index 5c2bc6e2..1aa690a6 100644
--- a/help3/xhpeditor/cm/mode/nginx/index.html
+++ b/help3/xhpeditor/cm/mode/nginx/index.html
@@ -62,7 +62,7 @@ server {
location / {
index index.html index.php; ## Allow a static html file to be shown first
try_files $uri $uri/ @handler; ## If missing pass the URI to Magento's front handler
- expires 30d; ## Assume all files are cachable
+ expires 30d; ## Assume all files are cacheable
}
## These locations would be hidden by .htaccess normally
@@ -128,7 +128,7 @@ server {
location / {
index index.html index.php; ## Allow a static html file to be shown first
try_files $uri $uri/ @handler; ## If missing pass the URI to Magento's front handler
- expires 30d; ## Assume all files are cachable
+ expires 30d; ## Assume all files are cacheable
}
## These locations would be hidden by .htaccess normally
diff --git a/help3/xhpeditor/cm/mode/nsis/nsis.js b/help3/xhpeditor/cm/mode/nsis/nsis.js
index 10816608..636940f5 100644
--- a/help3/xhpeditor/cm/mode/nsis/nsis.js
+++ b/help3/xhpeditor/cm/mode/nsis/nsis.js
@@ -31,7 +31,7 @@ CodeMirror.defineSimpleMode("nsis",{
{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|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|Int64Cmp|Int64CmpU|Int64Fmt|IntCmp|IntCmpU|IntFmt|IntOp|IntPtrCmp|IntPtrCmpU|IntPtrOp|IsWindow|LangString|LicenseBkColor|LicenseData|LicenseForceSelection|LicenseLangString|LicenseText|LoadAndSetImage|LoadLanguageFile|LockWindow|LogSet|LogText|ManifestDPIAware|ManifestLongPathAware|ManifestMaxVersionTested|ManifestSupportedOS|MessageBox|MiscButtonText|Name|Nop|OutFile|Page|PageCallbacks|PEAddResource|PEDllCharacteristics|PERemoveResource|PESubsysVer|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*(?: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|GetKnownFolderPath|GetLabelAddress|GetTempFileName|Goto|HideWindow|Icon|IfAbort|IfErrors|IfFileExists|IfRebootFlag|IfRtlLanguage|IfShellVarContextAll|IfSilent|InitPluginsDir|InstallButtonText|InstallColors|InstallDir|InstallDirRegKey|InstProgressFlags|InstType|InstTypeGetText|InstTypeSetText|Int64Cmp|Int64CmpU|Int64Fmt|IntCmp|IntCmpU|IntFmt|IntOp|IntPtrCmp|IntPtrCmpU|IntPtrOp|IsWindow|LangString|LicenseBkColor|LicenseData|LicenseForceSelection|LicenseLangString|LicenseText|LoadAndSetImage|LoadLanguageFile|LockWindow|LogSet|LogText|ManifestDPIAware|ManifestLongPathAware|ManifestMaxVersionTested|ManifestSupportedOS|MessageBox|MiscButtonText|Name|Nop|OutFile|Page|PageCallbacks|PEAddResource|PEDllCharacteristics|PERemoveResource|PESubsysVer|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},
diff --git a/help3/xhpeditor/cm/mode/ntriples/index.html b/help3/xhpeditor/cm/mode/ntriples/index.html
index 5473dbff..275cf08b 100644
--- a/help3/xhpeditor/cm/mode/ntriples/index.html
+++ b/help3/xhpeditor/cm/mode/ntriples/index.html
@@ -58,7 +58,7 @@ _:bnode5 <http://pred5> "literal 3"^^<http://type> .
<http://Sub2> <http://pred2#an2> "literal 1" <http://graph2> .
<http://Sub3#an3> <http://pred3> _:bnode3 <http://graph2> .
_:bnode4 <http://pred4> "literal 2"@lang <http://graph2> .
- # if a graph labe
+ # if a graph label
_:bnode5 <http://pred5> "literal 3"^^<http://type> .
</textarea>
</form>
diff --git a/help3/xhpeditor/cm/mode/oz/oz.js b/help3/xhpeditor/cm/mode/oz/oz.js
index a9738495..73857e4c 100644
--- a/help3/xhpeditor/cm/mode/oz/oz.js
+++ b/help3/xhpeditor/cm/mode/oz/oz.js
@@ -45,7 +45,7 @@ CodeMirror.defineMode("oz", function (conf) {
}
// Special [] keyword
- if (stream.match(/(\[])/)) {
+ if (stream.match('[]')) {
return "keyword"
}
@@ -130,7 +130,7 @@ CodeMirror.defineMode("oz", function (conf) {
return "operator";
}
- // If nothing match, we skip the entire alphanumerical block
+ // If nothing match, we skip the entire alphanumeric block
stream.eatWhile(/\w/);
return "variable";
diff --git a/help3/xhpeditor/cm/mode/pascal/pascal.js b/help3/xhpeditor/cm/mode/pascal/pascal.js
index dc3b1a3a..c48698bd 100644
--- a/help3/xhpeditor/cm/mode/pascal/pascal.js
+++ b/help3/xhpeditor/cm/mode/pascal/pascal.js
@@ -50,7 +50,11 @@ CodeMirror.defineMode("pascal", function() {
state.tokenize = tokenComment;
return tokenComment(stream, state);
}
- if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
+ if (ch == "{") {
+ state.tokenize = tokenCommentBraces;
+ return tokenCommentBraces(stream, state);
+ }
+ if (/[\[\]\(\),;\:\.]/.test(ch)) {
return null;
}
if (/\d/.test(ch)) {
@@ -98,6 +102,17 @@ CodeMirror.defineMode("pascal", function() {
return "comment";
}
+ function tokenCommentBraces(stream, state) {
+ var ch;
+ while (ch = stream.next()) {
+ if (ch == "}") {
+ state.tokenize = null;
+ break;
+ }
+ }
+ return "comment";
+ }
+
// Interface
return {
diff --git a/help3/xhpeditor/cm/mode/pegjs/pegjs.js b/help3/xhpeditor/cm/mode/pegjs/pegjs.js
index 19d5fa4c..ac011d3c 100644
--- a/help3/xhpeditor/cm/mode/pegjs/pegjs.js
+++ b/help3/xhpeditor/cm/mode/pegjs/pegjs.js
@@ -39,7 +39,7 @@ CodeMirror.defineMode("pegjs", function (config) {
stream.next(); // Skip quote
state.inString = true; // Update state
}
- if (!state.inString && !state.inComment && stream.match(/^\/\*/)) {
+ if (!state.inString && !state.inComment && stream.match('/*')) {
state.inComment = true;
}
@@ -59,7 +59,7 @@ CodeMirror.defineMode("pegjs", function (config) {
return state.lhs ? "property string" : "string"; // Token style
} else if (state.inComment) {
while (state.inComment && !stream.eol()) {
- if (stream.match(/\*\//)) {
+ if (stream.match('*/')) {
state.inComment = false; // Clear flag
} else {
stream.match(/^.[^\*]*/);
@@ -76,7 +76,7 @@ CodeMirror.defineMode("pegjs", function (config) {
stream.next();
state.inCharacterClass = true;
return 'bracket';
- } else if (stream.match(/^\/\//)) {
+ } else if (stream.match('//')) {
stream.skipToEnd();
return "comment";
} else if (state.braced || stream.peek() === '{') {
diff --git a/help3/xhpeditor/cm/mode/perl/perl.js b/help3/xhpeditor/cm/mode/perl/perl.js
index a3101a7c..ffe7877a 100644
--- a/help3/xhpeditor/cm/mode/perl/perl.js
+++ b/help3/xhpeditor/cm/mode/perl/perl.js
@@ -347,7 +347,7 @@ CodeMirror.defineMode("perl",function(){
lc :1, // - return lower-case version of a string
lcfirst :1, // - return a string with just the next letter in lower case
length :1, // - return the number of bytes in a string
- 'link' :1, // - create a hard link in the filesytem
+ 'link' :1, // - create a hard link in the filesystem
listen :1, // - register your socket as a server
local : 2, // - create a temporary value for a global variable (dynamic scoping)
localtime :1, // - convert UNIX time into record or string using local time
@@ -441,7 +441,7 @@ CodeMirror.defineMode("perl",function(){
state :1, // - declare and assign a state variable (persistent lexical scoping)
study :1, // - optimize input data for repeated searches
'sub' :1, // - declare a subroutine, possibly anonymously
- 'substr' :1, // - get or alter a portion of a stirng
+ 'substr' :1, // - get or alter a portion of a string
symlink :1, // - create a symbolic link to a file
syscall :1, // - execute an arbitrary system call
sysopen :1, // - open a file, pipe, or descriptor
@@ -516,7 +516,7 @@ CodeMirror.defineMode("perl",function(){
if(stream.match(/^\-?[\d\.]/,false))
if(stream.match(/^(\-?(\d*\.\d+(e[+-]?\d+)?|\d+\.\d*)|0x[\da-fA-F]+|0b[01]+|\d+(e[+-]?\d+)?)/))
return 'number';
- if(stream.match(/^<<(?=\w)/)){ // NOTE: <<SOMETHING\n...\nSOMETHING\n
+ if(stream.match(/^<<(?=[_a-zA-Z])/)){ // NOTE: <<SOMETHING\n...\nSOMETHING\n
stream.eatWhile(/\w/);
return tokenSOMETHING(stream,state,stream.current().substr(2));}
if(stream.sol()&&stream.match(/^\=item(?!\w)/)){// NOTE: \n=item...\n=cut\n
@@ -697,7 +697,7 @@ CodeMirror.defineMode("perl",function(){
return "variable-2";}
stream.pos=p;}
if(/[$@%&]/.test(ch)){
- if(stream.eatWhile(/[\w$\[\]]/)||stream.eat("{")&&stream.eatWhile(/[\w$\[\]]/)&&stream.eat("}")){
+ if(stream.eatWhile(/[\w$]/)||stream.eat("{")&&stream.eatWhile(/[\w$]/)&&stream.eat("}")){
var c=stream.current();
if(PERL[c])
return "variable-2";
diff --git a/help3/xhpeditor/cm/mode/php/php.js b/help3/xhpeditor/cm/mode/php/php.js
index 5f3a1439..b2cae960 100644
--- a/help3/xhpeditor/cm/mode/php/php.js
+++ b/help3/xhpeditor/cm/mode/php/php.js
@@ -53,7 +53,7 @@
[["]", null]]
], closing, escapes);
}
- if (stream.match(/\-\>\w/, false)) {
+ if (stream.match(/^->\w/, false)) {
// Match object operator
state.tokenize = matchSequence([
[["->", null]],
@@ -86,7 +86,7 @@
"die echo empty exit eval include include_once isset list require require_once return " +
"print unset __halt_compiler self static parent yield insteadof finally";
var phpAtoms = "true false null TRUE FALSE NULL __CLASS__ __DIR__ __FILE__ __LINE__ __METHOD__ __FUNCTION__ __NAMESPACE__ __TRAIT__";
- var phpBuiltin = "func_num_args func_get_arg func_get_args strlen strcmp strncmp strcasecmp strncasecmp each error_reporting define defined trigger_error user_error set_error_handler restore_error_handler get_declared_classes get_loaded_extensions extension_loaded get_extension_funcs debug_backtrace constant bin2hex hex2bin sleep usleep time mktime gmmktime strftime gmstrftime strtotime date gmdate getdate localtime checkdate flush wordwrap htmlspecialchars htmlentities html_entity_decode md5 md5_file crc32 getimagesize image_type_to_mime_type phpinfo phpversion phpcredits strnatcmp strnatcasecmp substr_count strspn strcspn strtok strtoupper strtolower strpos strrpos strrev hebrev hebrevc nl2br basename dirname pathinfo stripslashes stripcslashes strstr stristr strrchr str_shuffle str_word_count strcoll substr substr_replace quotemeta ucfirst ucwords strtr addslashes addcslashes rtrim str_replace str_repeat count_chars chunk_split trim ltrim strip_tags similar_text explode implode setlocale localeconv parse_str str_pad chop strchr sprintf printf vprintf vsprintf sscanf fscanf parse_url urlencode urldecode rawurlencode rawurldecode readlink linkinfo link unlink exec system escapeshellcmd escapeshellarg passthru shell_exec proc_open proc_close rand srand getrandmax mt_rand mt_srand mt_getrandmax base64_decode base64_encode abs ceil floor round is_finite is_nan is_infinite bindec hexdec octdec decbin decoct dechex base_convert number_format fmod ip2long long2ip getenv putenv getopt microtime gettimeofday getrusage uniqid quoted_printable_decode set_time_limit get_cfg_var magic_quotes_runtime set_magic_quotes_runtime get_magic_quotes_gpc get_magic_quotes_runtime import_request_variables error_log serialize unserialize memory_get_usage var_dump var_export debug_zval_dump print_r highlight_file show_source highlight_string ini_get ini_get_all ini_set ini_alter ini_restore get_include_path set_include_path restore_include_path setcookie header headers_sent connection_aborted connection_status ignore_user_abort parse_ini_file is_uploaded_file move_uploaded_file intval floatval doubleval strval gettype settype is_null is_resource is_bool is_long is_float is_int is_integer is_double is_real is_numeric is_string is_array is_object is_scalar ereg ereg_replace eregi eregi_replace split spliti join sql_regcase dl pclose popen readfile rewind rmdir umask fclose feof fgetc fgets fgetss fread fopen fpassthru ftruncate fstat fseek ftell fflush fwrite fputs mkdir rename copy tempnam tmpfile file file_get_contents file_put_contents stream_select stream_context_create stream_context_set_params stream_context_set_option stream_context_get_options stream_filter_prepend stream_filter_append fgetcsv flock get_meta_tags stream_set_write_buffer set_file_buffer set_socket_blocking stream_set_blocking socket_set_blocking stream_get_meta_data stream_register_wrapper stream_wrapper_register stream_set_timeout socket_set_timeout socket_get_status realpath fnmatch fsockopen pfsockopen pack unpack get_browser crypt opendir closedir chdir getcwd rewinddir readdir dir glob fileatime filectime filegroup fileinode filemtime fileowner fileperms filesize filetype file_exists is_writable is_writeable is_readable is_executable is_file is_dir is_link stat lstat chown touch clearstatcache mail ob_start ob_flush ob_clean ob_end_flush ob_end_clean ob_get_flush ob_get_clean ob_get_length ob_get_level ob_get_status ob_get_contents ob_implicit_flush ob_list_handlers ksort krsort natsort natcasesort asort arsort sort rsort usort uasort uksort shuffle array_walk count end prev next reset current key min max in_array array_search extract compact array_fill range array_multisort array_push array_pop array_shift array_unshift array_splice array_slice array_merge array_merge_recursive array_keys array_values array_count_values array_reverse array_reduce array_pad array_flip array_change_key_case array_rand array_unique array_intersect array_intersect_assoc array_diff array_diff_assoc array_sum array_filter array_map array_chunk array_key_exists array_intersect_key array_combine array_column pos sizeof key_exists assert assert_options version_compare ftok str_rot13 aggregate session_name session_module_name session_save_path session_id session_regenerate_id session_decode session_register session_unregister session_is_registered session_encode session_start session_destroy session_unset session_set_save_handler session_cache_limiter session_cache_expire session_set_cookie_params session_get_cookie_params session_write_close preg_match preg_match_all preg_replace preg_replace_callback preg_split preg_quote preg_grep overload ctype_alnum ctype_alpha ctype_cntrl ctype_digit ctype_lower ctype_graph ctype_print ctype_punct ctype_space ctype_upper ctype_xdigit virtual apache_request_headers apache_note apache_lookup_uri apache_child_terminate apache_setenv apache_response_headers apache_get_version getallheaders mysql_connect mysql_pconnect mysql_close mysql_select_db mysql_create_db mysql_drop_db mysql_query mysql_unbuffered_query mysql_db_query mysql_list_dbs mysql_list_tables mysql_list_fields mysql_list_processes mysql_error mysql_errno mysql_affected_rows mysql_insert_id mysql_result mysql_num_rows mysql_num_fields mysql_fetch_row mysql_fetch_array mysql_fetch_assoc mysql_fetch_object mysql_data_seek mysql_fetch_lengths mysql_fetch_field mysql_field_seek mysql_free_result mysql_field_name mysql_field_table mysql_field_len mysql_field_type mysql_field_flags mysql_escape_string mysql_real_escape_string mysql_stat mysql_thread_id mysql_client_encoding mysql_get_client_info mysql_get_host_info mysql_get_proto_info mysql_get_server_info mysql_info mysql mysql_fieldname mysql_fieldtable mysql_fieldlen mysql_fieldtype mysql_fieldflags mysql_selectdb mysql_createdb mysql_dropdb mysql_freeresult mysql_numfields mysql_numrows mysql_listdbs mysql_listtables mysql_listfields mysql_db_name mysql_dbname mysql_tablename mysql_table_name pg_connect pg_pconnect pg_close pg_connection_status pg_connection_busy pg_connection_reset pg_host pg_dbname pg_port pg_tty pg_options pg_ping pg_query pg_send_query pg_cancel_query pg_fetch_result pg_fetch_row pg_fetch_assoc pg_fetch_array pg_fetch_object pg_fetch_all pg_affected_rows pg_get_result pg_result_seek pg_result_status pg_free_result pg_last_oid pg_num_rows pg_num_fields pg_field_name pg_field_num pg_field_size pg_field_type pg_field_prtlen pg_field_is_null pg_get_notify pg_get_pid pg_result_error pg_last_error pg_last_notice pg_put_line pg_end_copy pg_copy_to pg_copy_from pg_trace pg_untrace pg_lo_create pg_lo_unlink pg_lo_open pg_lo_close pg_lo_read pg_lo_write pg_lo_read_all pg_lo_import pg_lo_export pg_lo_seek pg_lo_tell pg_escape_string pg_escape_bytea pg_unescape_bytea pg_client_encoding pg_set_client_encoding pg_meta_data pg_convert pg_insert pg_update pg_delete pg_select pg_exec pg_getlastoid pg_cmdtuples pg_errormessage pg_numrows pg_numfields pg_fieldname pg_fieldsize pg_fieldtype pg_fieldnum pg_fieldprtlen pg_fieldisnull pg_freeresult pg_result pg_loreadall pg_locreate pg_lounlink pg_loopen pg_loclose pg_loread pg_lowrite pg_loimport pg_loexport http_response_code get_declared_traits getimagesizefromstring socket_import_stream stream_set_chunk_size trait_exists header_register_callback class_uses session_status session_register_shutdown echo print global static exit array empty eval isset unset die include require include_once require_once json_decode json_encode json_last_error json_last_error_msg curl_close curl_copy_handle curl_errno curl_error curl_escape curl_exec curl_file_create curl_getinfo curl_init curl_multi_add_handle curl_multi_close curl_multi_exec curl_multi_getcontent curl_multi_info_read curl_multi_init curl_multi_remove_handle curl_multi_select curl_multi_setopt curl_multi_strerror curl_pause curl_reset curl_setopt_array curl_setopt curl_share_close curl_share_init curl_share_setopt curl_strerror curl_unescape curl_version mysqli_affected_rows mysqli_autocommit mysqli_change_user mysqli_character_set_name mysqli_close mysqli_commit mysqli_connect_errno mysqli_connect_error mysqli_connect mysqli_data_seek mysqli_debug mysqli_dump_debug_info mysqli_errno mysqli_error_list mysqli_error mysqli_fetch_all mysqli_fetch_array mysqli_fetch_assoc mysqli_fetch_field_direct mysqli_fetch_field mysqli_fetch_fields mysqli_fetch_lengths mysqli_fetch_object mysqli_fetch_row mysqli_field_count mysqli_field_seek mysqli_field_tell mysqli_free_result mysqli_get_charset mysqli_get_client_info mysqli_get_client_stats mysqli_get_client_version mysqli_get_connection_stats mysqli_get_host_info mysqli_get_proto_info mysqli_get_server_info mysqli_get_server_version mysqli_info mysqli_init mysqli_insert_id mysqli_kill mysqli_more_results mysqli_multi_query mysqli_next_result mysqli_num_fields mysqli_num_rows mysqli_options mysqli_ping mysqli_prepare mysqli_query mysqli_real_connect mysqli_real_escape_string mysqli_real_query mysqli_reap_async_query mysqli_refresh mysqli_rollback mysqli_select_db mysqli_set_charset mysqli_set_local_infile_default mysqli_set_local_infile_handler mysqli_sqlstate mysqli_ssl_set mysqli_stat mysqli_stmt_init mysqli_store_result mysqli_thread_id mysqli_thread_safe mysqli_use_result mysqli_warning_count";
+ var phpBuiltin = "func_num_args func_get_arg func_get_args strlen strcmp strncmp strcasecmp strncasecmp each error_reporting define defined trigger_error user_error set_error_handler restore_error_handler get_declared_classes get_loaded_extensions extension_loaded get_extension_funcs debug_backtrace constant bin2hex hex2bin sleep usleep time mktime gmmktime strftime gmstrftime strtotime date gmdate getdate localtime checkdate flush wordwrap htmlspecialchars htmlentities html_entity_decode md5 md5_file crc32 getimagesize image_type_to_mime_type phpinfo phpversion phpcredits strnatcmp strnatcasecmp substr_count strspn strcspn strtok strtoupper strtolower strpos strrpos strrev hebrev hebrevc nl2br basename dirname pathinfo stripslashes stripcslashes strstr stristr strrchr str_shuffle str_word_count strcoll substr substr_replace quotemeta ucfirst ucwords strtr addslashes addcslashes rtrim str_replace str_repeat count_chars chunk_split trim ltrim strip_tags similar_text explode implode setlocale localeconv parse_str str_pad chop strchr sprintf printf vprintf vsprintf sscanf fscanf parse_url urlencode urldecode rawurlencode rawurldecode readlink linkinfo link unlink exec system escapeshellcmd escapeshellarg passthru shell_exec proc_open proc_close rand srand getrandmax mt_rand mt_srand mt_getrandmax base64_decode base64_encode abs ceil floor round is_finite is_nan is_infinite bindec hexdec octdec decbin decoct dechex base_convert number_format fmod ip2long long2ip getenv putenv getopt microtime gettimeofday getrusage uniqid quoted_printable_decode set_time_limit get_cfg_var magic_quotes_runtime set_magic_quotes_runtime get_magic_quotes_gpc get_magic_quotes_runtime import_request_variables error_log serialize unserialize memory_get_usage memory_get_peak_usage var_dump var_export debug_zval_dump print_r highlight_file show_source highlight_string ini_get ini_get_all ini_set ini_alter ini_restore get_include_path set_include_path restore_include_path setcookie header headers_sent connection_aborted connection_status ignore_user_abort parse_ini_file is_uploaded_file move_uploaded_file intval floatval doubleval strval gettype settype is_null is_resource is_bool is_long is_float is_int is_integer is_double is_real is_numeric is_string is_array is_object is_scalar ereg ereg_replace eregi eregi_replace split spliti join sql_regcase dl pclose popen readfile rewind rmdir umask fclose feof fgetc fgets fgetss fread fopen fpassthru ftruncate fstat fseek ftell fflush fwrite fputs mkdir rename copy tempnam tmpfile file file_get_contents file_put_contents stream_select stream_context_create stream_context_set_params stream_context_set_option stream_context_get_options stream_filter_prepend stream_filter_append fgetcsv flock get_meta_tags stream_set_write_buffer set_file_buffer set_socket_blocking stream_set_blocking socket_set_blocking stream_get_meta_data stream_register_wrapper stream_wrapper_register stream_set_timeout socket_set_timeout socket_get_status realpath fnmatch fsockopen pfsockopen pack unpack get_browser crypt opendir closedir chdir getcwd rewinddir readdir dir glob fileatime filectime filegroup fileinode filemtime fileowner fileperms filesize filetype file_exists is_writable is_writeable is_readable is_executable is_file is_dir is_link stat lstat chown touch clearstatcache mail ob_start ob_flush ob_clean ob_end_flush ob_end_clean ob_get_flush ob_get_clean ob_get_length ob_get_level ob_get_status ob_get_contents ob_implicit_flush ob_list_handlers ksort krsort natsort natcasesort asort arsort sort rsort usort uasort uksort shuffle array_walk count end prev next reset current key min max in_array array_search extract compact array_fill range array_multisort array_push array_pop array_shift array_unshift array_splice array_slice array_merge array_merge_recursive array_keys array_values array_count_values array_reverse array_reduce array_pad array_flip array_change_key_case array_rand array_unique array_intersect array_intersect_assoc array_diff array_diff_assoc array_sum array_filter array_map array_chunk array_key_exists array_intersect_key array_combine array_column pos sizeof key_exists assert assert_options version_compare ftok str_rot13 aggregate session_name session_module_name session_save_path session_id session_regenerate_id session_decode session_register session_unregister session_is_registered session_encode session_start session_destroy session_unset session_set_save_handler session_cache_limiter session_cache_expire session_set_cookie_params session_get_cookie_params session_write_close preg_match preg_match_all preg_replace preg_replace_callback preg_split preg_quote preg_grep overload ctype_alnum ctype_alpha ctype_cntrl ctype_digit ctype_lower ctype_graph ctype_print ctype_punct ctype_space ctype_upper ctype_xdigit virtual apache_request_headers apache_note apache_lookup_uri apache_child_terminate apache_setenv apache_response_headers apache_get_version getallheaders mysql_connect mysql_pconnect mysql_close mysql_select_db mysql_create_db mysql_drop_db mysql_query mysql_unbuffered_query mysql_db_query mysql_list_dbs mysql_list_tables mysql_list_fields mysql_list_processes mysql_error mysql_errno mysql_affected_rows mysql_insert_id mysql_result mysql_num_rows mysql_num_fields mysql_fetch_row mysql_fetch_array mysql_fetch_assoc mysql_fetch_object mysql_data_seek mysql_fetch_lengths mysql_fetch_field mysql_field_seek mysql_free_result mysql_field_name mysql_field_table mysql_field_len mysql_field_type mysql_field_flags mysql_escape_string mysql_real_escape_string mysql_stat mysql_thread_id mysql_client_encoding mysql_get_client_info mysql_get_host_info mysql_get_proto_info mysql_get_server_info mysql_info mysql mysql_fieldname mysql_fieldtable mysql_fieldlen mysql_fieldtype mysql_fieldflags mysql_selectdb mysql_createdb mysql_dropdb mysql_freeresult mysql_numfields mysql_numrows mysql_listdbs mysql_listtables mysql_listfields mysql_db_name mysql_dbname mysql_tablename mysql_table_name pg_connect pg_pconnect pg_close pg_connection_status pg_connection_busy pg_connection_reset pg_host pg_dbname pg_port pg_tty pg_options pg_ping pg_query pg_send_query pg_cancel_query pg_fetch_result pg_fetch_row pg_fetch_assoc pg_fetch_array pg_fetch_object pg_fetch_all pg_affected_rows pg_get_result pg_result_seek pg_result_status pg_free_result pg_last_oid pg_num_rows pg_num_fields pg_field_name pg_field_num pg_field_size pg_field_type pg_field_prtlen pg_field_is_null pg_get_notify pg_get_pid pg_result_error pg_last_error pg_last_notice pg_put_line pg_end_copy pg_copy_to pg_copy_from pg_trace pg_untrace pg_lo_create pg_lo_unlink pg_lo_open pg_lo_close pg_lo_read pg_lo_write pg_lo_read_all pg_lo_import pg_lo_export pg_lo_seek pg_lo_tell pg_escape_string pg_escape_bytea pg_unescape_bytea pg_client_encoding pg_set_client_encoding pg_meta_data pg_convert pg_insert pg_update pg_delete pg_select pg_exec pg_getlastoid pg_cmdtuples pg_errormessage pg_numrows pg_numfields pg_fieldname pg_fieldsize pg_fieldtype pg_fieldnum pg_fieldprtlen pg_fieldisnull pg_freeresult pg_result pg_loreadall pg_locreate pg_lounlink pg_loopen pg_loclose pg_loread pg_lowrite pg_loimport pg_loexport http_response_code get_declared_traits getimagesizefromstring socket_import_stream stream_set_chunk_size trait_exists header_register_callback class_uses session_status session_register_shutdown echo print global static exit array empty eval isset unset die include require include_once require_once json_decode json_encode json_last_error json_last_error_msg curl_close curl_copy_handle curl_errno curl_error curl_escape curl_exec curl_file_create curl_getinfo curl_init curl_multi_add_handle curl_multi_close curl_multi_exec curl_multi_getcontent curl_multi_info_read curl_multi_init curl_multi_remove_handle curl_multi_select curl_multi_setopt curl_multi_strerror curl_pause curl_reset curl_setopt_array curl_setopt curl_share_close curl_share_init curl_share_setopt curl_strerror curl_unescape curl_version mysqli_affected_rows mysqli_autocommit mysqli_change_user mysqli_character_set_name mysqli_close mysqli_commit mysqli_connect_errno mysqli_connect_error mysqli_connect mysqli_data_seek mysqli_debug mysqli_dump_debug_info mysqli_errno mysqli_error_list mysqli_error mysqli_fetch_all mysqli_fetch_array mysqli_fetch_assoc mysqli_fetch_field_direct mysqli_fetch_field mysqli_fetch_fields mysqli_fetch_lengths mysqli_fetch_object mysqli_fetch_row mysqli_field_count mysqli_field_seek mysqli_field_tell mysqli_free_result mysqli_get_charset mysqli_get_client_info mysqli_get_client_stats mysqli_get_client_version mysqli_get_connection_stats mysqli_get_host_info mysqli_get_proto_info mysqli_get_server_info mysqli_get_server_version mysqli_info mysqli_init mysqli_insert_id mysqli_kill mysqli_more_results mysqli_multi_query mysqli_next_result mysqli_num_fields mysqli_num_rows mysqli_options mysqli_ping mysqli_prepare mysqli_query mysqli_real_connect mysqli_real_escape_string mysqli_real_query mysqli_reap_async_query mysqli_refresh mysqli_rollback mysqli_select_db mysqli_set_charset mysqli_set_local_infile_default mysqli_set_local_infile_handler mysqli_sqlstate mysqli_ssl_set mysqli_stat mysqli_stmt_init mysqli_store_result mysqli_thread_id mysqli_thread_safe mysqli_use_result mysqli_warning_count";
CodeMirror.registerHelper("hintWords", "php", [phpKeywords, phpAtoms, phpBuiltin].join(" ").split(" "));
CodeMirror.registerHelper("wordChars", "php", /[\w$]/);
@@ -106,7 +106,7 @@
},
"<": function(stream, state) {
var before;
- if (before = stream.match(/<<\s*/)) {
+ if (before = stream.match(/^<<\s*/)) {
var quoted = stream.eat(/['"]/);
stream.eatWhile(/[\w\.]/);
var delim = stream.current().slice(before[0].length + (quoted ? 2 : 1));
diff --git a/help3/xhpeditor/cm/mode/powershell/index.html b/help3/xhpeditor/cm/mode/powershell/index.html
index 6bb7babc..fae02982 100644
--- a/help3/xhpeditor/cm/mode/powershell/index.html
+++ b/help3/xhpeditor/cm/mode/powershell/index.html
@@ -28,6 +28,10 @@
<h2>PowerShell mode</h2>
<div><textarea id="code" name="code">
+# Paths
+cd c:\
+c:\windows\calc.exe
+
# Number Literals
0 12345
12kb 12mb 12gB 12Tb 12PB 12L 12D 12lkb 12dtb
diff --git a/help3/xhpeditor/cm/mode/powershell/powershell.js b/help3/xhpeditor/cm/mode/powershell/powershell.js
index 85f89b9e..4869ae73 100644
--- a/help3/xhpeditor/cm/mode/powershell/powershell.js
+++ b/help3/xhpeditor/cm/mode/powershell/powershell.js
@@ -38,7 +38,7 @@ CodeMirror.defineMode('powershell', function() {
/param|process|return|switch|throw|trap|try|until|where|while/
], { suffix: notCharacterOrDash });
- var punctuation = /[\[\]{},;`\.]|@[({]/;
+ var punctuation = /[\[\]{},;`\\\.]|@[({]/;
var wordOperators = buildRegexp([
'f',
/b?not/,
diff --git a/help3/xhpeditor/cm/mode/powershell/test.js b/help3/xhpeditor/cm/mode/powershell/test.js
index ba1ecf19..261406df 100644
--- a/help3/xhpeditor/cm/mode/powershell/test.js
+++ b/help3/xhpeditor/cm/mode/powershell/test.js
@@ -63,7 +63,7 @@
MT('operator_long', "[operator -match]");
forEach([
- '(', ')', '[[', ']]', '{', '}', ',', '`', ';', '.'
+ '(', ')', '[[', ']]', '{', '}', ',', '`', ';', '.', '\\'
], function(punctuation) {
MT("punctuation_" + punctuation.replace(/^[\[\]]/,''), "[punctuation " + punctuation + "]");
});
diff --git a/help3/xhpeditor/cm/mode/protobuf/protobuf.js b/help3/xhpeditor/cm/mode/protobuf/protobuf.js
index 68b240a4..40b0842d 100644
--- a/help3/xhpeditor/cm/mode/protobuf/protobuf.js
+++ b/help3/xhpeditor/cm/mode/protobuf/protobuf.js
@@ -62,7 +62,10 @@
};
CodeMirror.defineMode("protobuf", function() {
- return {token: tokenBase};
+ return {
+ token: tokenBase,
+ fold: "brace"
+ };
});
CodeMirror.defineMIME("text/x-protobuf", "protobuf");
diff --git a/help3/xhpeditor/cm/mode/pug/pug.js b/help3/xhpeditor/cm/mode/pug/pug.js
index a4c0e16b..73e9ae2f 100644
--- a/help3/xhpeditor/cm/mode/pug/pug.js
+++ b/help3/xhpeditor/cm/mode/pug/pug.js
@@ -261,7 +261,7 @@ CodeMirror.defineMode("pug", function (config) {
}
return 'variable';
}
- if (stream.match(/^\+#{/, false)) {
+ if (stream.match('+#{', false)) {
stream.next();
state.mixinCallAfter = true;
return interpolation(stream, state);
diff --git a/help3/xhpeditor/cm/mode/puppet/puppet.js b/help3/xhpeditor/cm/mode/puppet/puppet.js
index 36493420..a92ca110 100644
--- a/help3/xhpeditor/cm/mode/puppet/puppet.js
+++ b/help3/xhpeditor/cm/mode/puppet/puppet.js
@@ -176,7 +176,7 @@ CodeMirror.defineMode("puppet", function () {
// Match characters that we are going to assume
// are trying to be regex
if (ch == '/') {
- stream.match(/.*?\//);
+ stream.match(/^[^\/]*\//);
return 'variable-3';
}
// Match all the numbers
diff --git a/help3/xhpeditor/cm/mode/python/index.html b/help3/xhpeditor/cm/mode/python/index.html
index bdfc8f57..78a3a146 100644
--- a/help3/xhpeditor/cm/mode/python/index.html
+++ b/help3/xhpeditor/cm/mode/python/index.html
@@ -190,7 +190,7 @@ def pairwise_cython(double[:, ::1] X):
<li>hangingIndent - int - If you want to write long arguments to a function starting on a new line, how much that line should be indented. Defaults to one normal indentation unit.</li>
</ul>
<h2>Advanced Configuration Options:</h2>
- <p>Usefull for superset of python syntax like Enthought enaml, IPython magics and questionmark help</p>
+ <p>Useful for superset of python syntax like Enthought enaml, IPython magics and questionmark help</p>
<ul>
<li>singleOperators - RegEx - Regular Expression for single operator matching, default : <pre>^[\\+\\-\\*/%&amp;|\\^~&lt;&gt;!]</pre> including <pre>@</pre> on Python 3</li>
<li>singleDelimiters - RegEx - Regular Expression for single delimiter matching, default : <pre>^[\\(\\)\\[\\]\\{\\}@,:`=;\\.]</pre></li>
diff --git a/help3/xhpeditor/cm/mode/python/python.js b/help3/xhpeditor/cm/mode/python/python.js
index 97451038..7dff2d1e 100644
--- a/help3/xhpeditor/cm/mode/python/python.js
+++ b/help3/xhpeditor/cm/mode/python/python.js
@@ -42,7 +42,7 @@
var ERRORCLASS = "error";
var delimiters = parserConf.delimiters || parserConf.singleDelimiters || /^[\(\)\[\]\{\}@,:`=;\.\\]/;
- // (Backwards-compatiblity with old, cumbersome config system)
+ // (Backwards-compatibility 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)
@@ -98,11 +98,11 @@
return tokenBaseInner(stream, state);
}
- function tokenBaseInner(stream, state) {
+ function tokenBaseInner(stream, state, inFormat) {
if (stream.eatSpace()) return null;
// Handle Comments
- if (stream.match(/^#.*/)) return "comment";
+ if (!inFormat && stream.match(/^#.*/)) return "comment";
// Handle Number Literals
if (stream.match(/^[0-9\.]/, false)) {
@@ -177,7 +177,7 @@
// Handle non-detected items
stream.next();
- return ERRORCLASS;
+ return inFormat ? null :ERRORCLASS;
}
function formatStringFactory(delimiter, tokenOuter) {
@@ -189,7 +189,7 @@
function tokenNestedExpr(depth) {
return function(stream, state) {
- var inner = tokenBaseInner(stream, state)
+ var inner = tokenBaseInner(stream, state, true)
if (inner == "punctuation") {
if (stream.current() == "{") {
state.tokenize = tokenNestedExpr(depth + 1)
@@ -282,7 +282,7 @@
}
function pushBracketScope(stream, state, type) {
- var align = stream.match(/^([\s\[\{\(]|#.*)*$/, false) ? null : stream.column() + 1
+ var align = stream.match(/^[\s\[\{\(]*(?:#|$)/, false) ? null : stream.column() + 1
state.scopes.push({offset: state.indent + hangingIndent,
type: type,
align: align})
@@ -318,7 +318,7 @@
state.dedent += 1;
if (current == "lambda") state.lambda = true;
- if (current == ":" && !state.lambda && top(state).type == "py")
+ if (current == ":" && !state.lambda && top(state).type == "py" && stream.match(/^\s*(?:#|$)/, false))
pushPyScope(state);
if (current.length == 1 && !/string|comment/.test(style)) {
diff --git a/help3/xhpeditor/cm/mode/python/test.js b/help3/xhpeditor/cm/mode/python/test.js
index 2b605b8e..5fff328b 100644
--- a/help3/xhpeditor/cm/mode/python/test.js
+++ b/help3/xhpeditor/cm/mode/python/test.js
@@ -31,7 +31,7 @@
}
MT("fValidStringPrefix", "[string f'this is a]{[variable formatted]}[string string']");
- MT("fValidExpressioninFString", "[string f'expression ]{[number 100][operator *][number 5]}[string string']");
+ MT("fValidExpressionInFString", "[string f'expression ]{[number 100][operator *][number 5]}[string string']");
MT("fInvalidFString", "[error f'this is wrong}]");
MT("fNestedFString", "[string f'expression ]{[number 100] [operator +] [string f'inner]{[number 5]}[string ']}[string string']");
MT("uValidStringPrefix", "[string u'this is an unicode string']");
@@ -41,4 +41,8 @@
MT("bracesInFString", "[string f']{[variable x] [operator +] {}}[string !']")
MT("nestedFString", "[string f']{[variable b][[ [string f\"c\"] ]]}[string f'] [comment # oops]")
+
+ MT("dontIndentTypeDecl",
+ "[variable i]: [builtin int] [operator =] [number 32]",
+ "[builtin print]([variable i])")
})();
diff --git a/help3/xhpeditor/cm/mode/r/r.js b/help3/xhpeditor/cm/mode/r/r.js
index c422af9a..de34c201 100644
--- a/help3/xhpeditor/cm/mode/r/r.js
+++ b/help3/xhpeditor/cm/mode/r/r.js
@@ -54,9 +54,9 @@ CodeMirror.defineMode("r", function(config) {
} else if (ch == "`") {
stream.match(/[^`]+`/);
return "variable-3";
- } else if (ch == "." && stream.match(/.[.\d]+/)) {
+ } else if (ch == "." && stream.match(/.(?:[.]|\d+)/)) {
return "keyword";
- } else if (/[\w\.]/.test(ch) && ch != "_") {
+ } else if (/[a-zA-Z\.]/.test(ch)) {
stream.eatWhile(/[\w\.]/);
var word = stream.current();
if (atoms.propertyIsEnumerable(word)) return "atom";
diff --git a/help3/xhpeditor/cm/mode/rpm/rpm.js b/help3/xhpeditor/cm/mode/rpm/rpm.js
index 2dece2ea..bb9ec9ff 100644
--- a/help3/xhpeditor/cm/mode/rpm/rpm.js
+++ b/help3/xhpeditor/cm/mode/rpm/rpm.js
@@ -12,14 +12,14 @@
"use strict";
CodeMirror.defineMode("rpm-changes", function() {
- var headerSeperator = /^-+$/;
+ var headerSeparator = /^-+$/;
var headerLine = /^(Mon|Tue|Wed|Thu|Fri|Sat|Sun) (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) ?\d{1,2} \d{2}:\d{2}(:\d{2})? [A-Z]{3,4} \d{4} - /;
var simpleEmail = /^[\w+.-]+@[\w.-]+/;
return {
token: function(stream) {
if (stream.sol()) {
- if (stream.match(headerSeperator)) { return 'tag'; }
+ if (stream.match(headerSeparator)) { return 'tag'; }
if (stream.match(headerLine)) { return 'tag'; }
}
if (stream.match(simpleEmail)) { return 'string'; }
@@ -80,12 +80,12 @@ CodeMirror.defineMode("rpm-spec", function() {
// Macros like '%make_install' or '%attr(0775,root,root)'
if (stream.match(/^%[\w]+/)) {
- if (stream.match(/^\(/)) { state.macroParameters = true; }
+ if (stream.match('(')) { state.macroParameters = true; }
return "keyword";
}
if (state.macroParameters) {
if (stream.match(/^\d+/)) { return "number";}
- if (stream.match(/^\)/)) {
+ if (stream.match(')')) {
state.macroParameters = false;
return "keyword";
}
diff --git a/help3/xhpeditor/cm/mode/ruby/index.html b/help3/xhpeditor/cm/mode/ruby/index.html
index 55fe6c58..daebdca2 100644
--- a/help3/xhpeditor/cm/mode/ruby/index.html
+++ b/help3/xhpeditor/cm/mode/ruby/index.html
@@ -34,7 +34,7 @@
# This program evaluates polynomials. It first asks for the coefficients
# of a polynomial, which must be entered on one line, highest-order first.
# It then requests values of x and will compute the value of the poly for
-# each x. It will repeatly ask for x values, unless you the user enters
+# each x. It will repeatedly ask for x values, unless you the user enters
# a blank line. It that case, it will ask for another polynomial. If the
# user types quit for either input, the program immediately exits.
#
diff --git a/help3/xhpeditor/cm/mode/ruby/ruby.js b/help3/xhpeditor/cm/mode/ruby/ruby.js
index dd0e603e..85bbfc65 100644
--- a/help3/xhpeditor/cm/mode/ruby/ruby.js
+++ b/help3/xhpeditor/cm/mode/ruby/ruby.js
@@ -11,25 +11,28 @@
})(function(CodeMirror) {
"use strict";
+function wordObj(words) {
+ var o = {};
+ for (var i = 0, e = words.length; i < e; ++i) o[words[i]] = true;
+ return o;
+}
+
+var keywordList = [
+ "alias", "and", "BEGIN", "begin", "break", "case", "class", "def", "defined?", "do", "else",
+ "elsif", "END", "end", "ensure", "false", "for", "if", "in", "module", "next", "not", "or",
+ "redo", "rescue", "retry", "return", "self", "super", "then", "true", "undef", "unless",
+ "until", "when", "while", "yield", "nil", "raise", "throw", "catch", "fail", "loop", "callcc",
+ "caller", "lambda", "proc", "public", "protected", "private", "require", "load",
+ "require_relative", "extend", "autoload", "__END__", "__FILE__", "__LINE__", "__dir__"
+], keywords = wordObj(keywordList);
+
+var indentWords = wordObj(["def", "class", "case", "for", "while", "until", "module", "then",
+ "catch", "loop", "proc", "begin"]);
+var dedentWords = wordObj(["end", "until"]);
+var opening = {"[": "]", "{": "}", "(": ")"};
+var closing = {"]": "[", "}": "{", ")": "("};
+
CodeMirror.defineMode("ruby", function(config) {
- function wordObj(words) {
- var o = {};
- for (var i = 0, e = words.length; i < e; ++i) o[words[i]] = true;
- return o;
- }
- var keywords = wordObj([
- "alias", "and", "BEGIN", "begin", "break", "case", "class", "def", "defined?", "do", "else",
- "elsif", "END", "end", "ensure", "false", "for", "if", "in", "module", "next", "not", "or",
- "redo", "rescue", "retry", "return", "self", "super", "then", "true", "undef", "unless",
- "until", "when", "while", "yield", "nil", "raise", "throw", "catch", "fail", "loop", "callcc",
- "caller", "lambda", "proc", "public", "protected", "private", "require", "load",
- "require_relative", "extend", "autoload", "__END__", "__FILE__", "__LINE__", "__dir__"
- ]);
- var indentWords = wordObj(["def", "class", "case", "for", "while", "until", "module", "then",
- "catch", "loop", "proc", "begin"]);
- var dedentWords = wordObj(["end", "until"]);
- var opening = {"[": "]", "{": "}", "(": ")"};
- var closing = {"]": "[", "}": "{", ")": "("};
var curPunc;
function chain(newtok, stream, state) {
@@ -295,4 +298,6 @@ CodeMirror.defineMode("ruby", function(config) {
CodeMirror.defineMIME("text/x-ruby", "ruby");
+CodeMirror.registerHelper("hintWords", "ruby", keywordList);
+
});
diff --git a/help3/xhpeditor/cm/mode/rust/rust.js b/help3/xhpeditor/cm/mode/rust/rust.js
index 6bcfbc44..f95f320d 100644
--- a/help3/xhpeditor/cm/mode/rust/rust.js
+++ b/help3/xhpeditor/cm/mode/rust/rust.js
@@ -25,8 +25,8 @@ CodeMirror.defineSimpleMode("rust",{
{regex: /(?:(?:[0-9][0-9_]*)(?:(?:[Ee][+-]?[0-9_]+)|\.[0-9_]+(?:[Ee][+-]?[0-9_]+)?)(?:f32|f64)?)|(?:0(?:b[01_]+|(?:o[0-7_]+)|(?:x[0-9a-fA-F_]+))|(?:[0-9][0-9_]*))(?:u8|u16|u32|u64|i8|i16|i32|i64|isize|usize)?/,
token: "number"},
- {regex: /(let(?:\s+mut)?|fn|enum|mod|struct|type)(\s+)([a-zA-Z_][a-zA-Z0-9_]*)/, token: ["keyword", null, "def"]},
- {regex: /(?:abstract|alignof|as|box|break|continue|const|crate|do|else|enum|extern|fn|for|final|if|impl|in|loop|macro|match|mod|move|offsetof|override|priv|proc|pub|pure|ref|return|self|sizeof|static|struct|super|trait|type|typeof|unsafe|unsized|use|virtual|where|while|yield)\b/, token: "keyword"},
+ {regex: /(let(?:\s+mut)?|fn|enum|mod|struct|type|union)(\s+)([a-zA-Z_][a-zA-Z0-9_]*)/, token: ["keyword", null, "def"]},
+ {regex: /(?:abstract|alignof|as|async|await|box|break|continue|const|crate|do|dyn|else|enum|extern|fn|for|final|if|impl|in|loop|macro|match|mod|move|offsetof|override|priv|proc|pub|pure|ref|return|self|sizeof|static|struct|super|trait|type|typeof|union|unsafe|unsized|use|virtual|where|while|yield)\b/, token: "keyword"},
{regex: /\b(?:Self|isize|usize|char|bool|u8|u16|u32|u64|f16|f32|f64|i8|i16|i32|i64|str|Option)\b/, token: "atom"},
{regex: /\b(?:true|false|Some|None|Ok|Err)\b/, token: "builtin"},
{regex: /\b(fn)(\s+)([a-zA-Z_][a-zA-Z0-9_]*)/,
diff --git a/help3/xhpeditor/cm/mode/sas/sas.js b/help3/xhpeditor/cm/mode/sas/sas.js
index c6f528e0..49b96b66 100755
--- a/help3/xhpeditor/cm/mode/sas/sas.js
+++ b/help3/xhpeditor/cm/mode/sas/sas.js
@@ -88,7 +88,7 @@
define('def', 'source2 nosource2 page pageno pagesize', ['ALL']);
//proc and datastep
- define('def', '_all_ _character_ _cmd_ _freq_ _i_ _infile_ _last_ _msg_ _null_ _numeric_ _temporary_ _type_ abort abs addr adjrsq airy alpha alter altlog altprint and arcos array arsin as atan attrc attrib attrn authserver autoexec awscontrol awsdef awsmenu awsmenumerge awstitle backward band base betainv between blocksize blshift bnot bor brshift bufno bufsize bxor by byerr byline byte calculated call cards cards4 catcache cbufno cdf ceil center cexist change chisq cinv class cleanup close cnonct cntllev coalesce codegen col collate collin column comamid comaux1 comaux2 comdef compbl compound compress config continue convert cos cosh cpuid create cross crosstab css curobs cv daccdb daccdbsl daccsl daccsyd dacctab dairy datalines datalines4 datejul datepart datetime day dbcslang dbcstype dclose ddm delete delimiter depdb depdbsl depsl depsyd deptab dequote descending descript design= device dflang dhms dif digamma dim dinfo display distinct dkricond dkrocond dlm dnum do dopen doptname doptnum dread drop dropnote dsname dsnferr echo else emaildlg emailid emailpw emailserver emailsys encrypt end endsas engine eof eov erf erfc error errorcheck errors exist exp fappend fclose fcol fdelete feedback fetch fetchobs fexist fget file fileclose fileexist filefmt filename fileref fmterr fmtsearch fnonct fnote font fontalias fopen foptname foptnum force formatted formchar formdelim formdlim forward fpoint fpos fput fread frewind frlen from fsep fuzz fwrite gaminv gamma getoption getvarc getvarn go goto group gwindow hbar hbound helpenv helploc hms honorappearance hosthelp hostprint hour hpct html hvar ibessel ibr id if index indexc indexw initcmd initstmt inner input inputc inputn inr insert int intck intnx into intrr invaliddata irr is jbessel join juldate keep kentb kurtosis label lag last lbound leave left length levels lgamma lib library libref line linesize link list log log10 log2 logpdf logpmf logsdf lostcard lowcase lrecl ls macro macrogen maps mautosource max maxdec maxr mdy mean measures median memtype merge merror min minute missing missover mlogic mod mode model modify month mopen mort mprint mrecall msglevel msymtabmax mvarsize myy n nest netpv new news nmiss no nobatch nobs nocaps nocardimage nocenter nocharcode nocmdmac nocol nocum nodate nodbcs nodetails nodmr nodms nodmsbatch nodup nodupkey noduplicates noechoauto noequals noerrorabend noexitwindows nofullstimer noicon noimplmac noint nolist noloadlist nomiss nomlogic nomprint nomrecall nomsgcase nomstored nomultenvappl nonotes nonumber noobs noovp nopad nopercent noprint noprintinit normal norow norsasuser nosetinit nosplash nosymbolgen note notes notitle notitles notsorted noverbose noxsync noxwait npv null number numkeys nummousekeys nway obs on open order ordinal otherwise out outer outp= output over ovp p(1 5 10 25 50 75 90 95 99) pad pad2 paired parm parmcards path pathdll pathname pdf peek peekc pfkey pmf point poisson poke position printer probbeta probbnml probchi probf probgam probhypr probit probnegb probnorm probsig probt procleave prt ps pw pwreq qtr quote r ranbin rancau ranexp rangam range ranks rannor ranpoi rantbl rantri ranuni read recfm register regr remote remove rename repeat replace resolve retain return reuse reverse rewind right round rsquare rtf rtrace rtraceloc s s2 samploc sasautos sascontrol sasfrscr sasmsg sasmstore sasscript sasuser saving scan sdf second select selection separated seq serror set setcomm setot sign simple sin sinh siteinfo skewness skip sle sls sortedby sortpgm sortseq sortsize soundex spedis splashlocation split spool sqrt start std stderr stdin stfips stimer stname stnamel stop stopover subgroup subpopn substr sum sumwgt symbol symbolgen symget symput sysget sysin sysleave sysmsg sysparm sysprint sysprintfont sysprod sysrc system t table tables tan tanh tapeclose tbufsize terminal test then timepart tinv tnonct to today tol tooldef totper transformout translate trantab tranwrd trigamma trim trimn trunc truncover type unformatted uniform union until upcase update user usericon uss validate value var weight when where while wincharset window work workinit workterm write wsum xsync xwait yearcutoff yes yyq min max', ['inDataStep', 'inProc']);
+ define('def', '_all_ _character_ _cmd_ _freq_ _i_ _infile_ _last_ _msg_ _null_ _numeric_ _temporary_ _type_ abort abs addr adjrsq airy alpha alter altlog altprint and arcos array arsin as atan attrc attrib attrn authserver autoexec awscontrol awsdef awsmenu awsmenumerge awstitle backward band base betainv between blocksize blshift bnot bor brshift bufno bufsize bxor by byerr byline byte calculated call cards cards4 catcache cbufno cdf ceil center cexist change chisq cinv class cleanup close cnonct cntllev coalesce codegen col collate collin column comamid comaux1 comaux2 comdef compbl compound compress config continue convert cos cosh cpuid create cross crosstab css curobs cv daccdb daccdbsl daccsl daccsyd dacctab dairy datalines datalines4 datejul datepart datetime day dbcslang dbcstype dclose ddfm ddm delete delimiter depdb depdbsl depsl depsyd deptab dequote descending descript design= device dflang dhms dif digamma dim dinfo display distinct dkricond dkrocond dlm dnum do dopen doptname doptnum dread drop dropnote dsname dsnferr echo else emaildlg emailid emailpw emailserver emailsys encrypt end endsas engine eof eov erf erfc error errorcheck errors exist exp fappend fclose fcol fdelete feedback fetch fetchobs fexist fget file fileclose fileexist filefmt filename fileref fmterr fmtsearch fnonct fnote font fontalias fopen foptname foptnum force formatted formchar formdelim formdlim forward fpoint fpos fput fread frewind frlen from fsep fuzz fwrite gaminv gamma getoption getvarc getvarn go goto group gwindow hbar hbound helpenv helploc hms honorappearance hosthelp hostprint hour hpct html hvar ibessel ibr id if index indexc indexw initcmd initstmt inner input inputc inputn inr insert int intck intnx into intrr invaliddata irr is jbessel join juldate keep kentb kurtosis label lag last lbound leave left length levels lgamma lib library libref line linesize link list log log10 log2 logpdf logpmf logsdf lostcard lowcase lrecl ls macro macrogen maps mautosource max maxdec maxr mdy mean measures median memtype merge merror min minute missing missover mlogic mod mode model modify month mopen mort mprint mrecall msglevel msymtabmax mvarsize myy n nest netpv new news nmiss no nobatch nobs nocaps nocardimage nocenter nocharcode nocmdmac nocol nocum nodate nodbcs nodetails nodmr nodms nodmsbatch nodup nodupkey noduplicates noechoauto noequals noerrorabend noexitwindows nofullstimer noicon noimplmac noint nolist noloadlist nomiss nomlogic nomprint nomrecall nomsgcase nomstored nomultenvappl nonotes nonumber noobs noovp nopad nopercent noprint noprintinit normal norow norsasuser nosetinit nosplash nosymbolgen note notes notitle notitles notsorted noverbose noxsync noxwait npv null number numkeys nummousekeys nway obs on open order ordinal otherwise out outer outp= output over ovp p(1 5 10 25 50 75 90 95 99) pad pad2 paired parm parmcards path pathdll pathname pdf peek peekc pfkey pmf point poisson poke position printer probbeta probbnml probchi probf probgam probhypr probit probnegb probnorm probsig probt procleave prt ps pw pwreq qtr quote r ranbin rancau random ranexp rangam range ranks rannor ranpoi rantbl rantri ranuni rcorr read recfm register regr remote remove rename repeat repeated replace resolve retain return reuse reverse rewind right round rsquare rtf rtrace rtraceloc s s2 samploc sasautos sascontrol sasfrscr sasmsg sasmstore sasscript sasuser saving scan sdf second select selection separated seq serror set setcomm setot sign simple sin sinh siteinfo skewness skip sle sls sortedby sortpgm sortseq sortsize soundex spedis splashlocation split spool sqrt start std stderr stdin stfips stimer stname stnamel stop stopover sub subgroup subpopn substr sum sumwgt symbol symbolgen symget symput sysget sysin sysleave sysmsg sysparm sysprint sysprintfont sysprod sysrc system t table tables tan tanh tapeclose tbufsize terminal test then timepart tinv tnonct to today tol tooldef totper transformout translate trantab tranwrd trigamma trim trimn trunc truncover type unformatted uniform union until upcase update user usericon uss validate value var weight when where while wincharset window work workinit workterm write wsum xsync xwait yearcutoff yes yyq min max', ['inDataStep', 'inProc']);
define('operator', 'and not ', ['inDataStep', 'inProc']);
// Main function
diff --git a/help3/xhpeditor/cm/mode/sass/sass.js b/help3/xhpeditor/cm/mode/sass/sass.js
index c37ab0b2..d8427bff 100644
--- a/help3/xhpeditor/cm/mode/sass/sass.js
+++ b/help3/xhpeditor/cm/mode/sass/sass.js
@@ -231,7 +231,7 @@ CodeMirror.defineMode("sass", function(config) {
}
if(ch === "@"){
- if(stream.match(/@extend/)){
+ if(stream.match('@extend')){
if(!stream.match(/\s*[\w]/))
dedent(state);
}
@@ -445,7 +445,12 @@ CodeMirror.defineMode("sass", function(config) {
indent: function(state) {
return state.scopes[0].offset;
- }
+ },
+
+ blockCommentStart: "/*",
+ blockCommentEnd: "*/",
+ lineComment: "//",
+ fold: "indent"
};
}, "css");
diff --git a/help3/xhpeditor/cm/mode/scheme/scheme.js b/help3/xhpeditor/cm/mode/scheme/scheme.js
index 56e4e332..370250d8 100644
--- a/help3/xhpeditor/cm/mode/scheme/scheme.js
+++ b/help3/xhpeditor/cm/mode/scheme/scheme.js
@@ -26,8 +26,8 @@ CodeMirror.defineMode("scheme", function () {
return obj;
}
- var keywords = makeKeywords("λ case-lambda call/cc class define-class exit-handler field import inherit init-field interface let*-values let-values let/ec mixin opt-lambda override protect provide public rename require require-for-syntax syntax syntax-case syntax-error unit/sig unless when with-syntax and begin call-with-current-continuation call-with-input-file call-with-output-file case cond define define-syntax delay do dynamic-wind else for-each if lambda let let* let-syntax letrec letrec-syntax map or syntax-rules abs acos angle append apply asin assoc assq assv atan boolean? caar cadr call-with-input-file call-with-output-file call-with-values car cdddar cddddr cdr ceiling char->integer char-alphabetic? char-ci<=? char-ci<? char-ci=? char-ci>=? char-ci>? char-downcase char-lower-case? char-numeric? char-ready? char-upcase char-upper-case? char-whitespace? char<=? char<? char=? char>=? char>? char? close-input-port close-output-port complex? cons cos current-input-port current-output-port denominator display eof-object? eq? equal? eqv? eval even? exact->inexact exact? exp expt #f floor force gcd imag-part inexact->exact inexact? input-port? integer->char integer? interaction-environment lcm length list list->string list->vector list-ref list-tail list? load log magnitude make-polar make-rectangular make-string make-vector max member memq memv min modulo negative? newline not null-environment null? number->string number? numerator odd? open-input-file open-output-file output-port? pair? peek-char port? positive? procedure? quasiquote quote quotient rational? rationalize read read-char real-part real? remainder reverse round scheme-report-environment set! set-car! set-cdr! sin sqrt string string->list string->number string->symbol string-append string-ci<=? string-ci<? string-ci=? string-ci>=? string-ci>? string-copy string-fill! string-length string-ref string-set! string<=? string<? string=? string>=? string>? string? substring symbol->string symbol? #t tan transcript-off transcript-on truncate values vector vector->list vector-fill! vector-length vector-ref vector-set! with-input-from-file with-output-to-file write write-char zero?");
- var indentKeys = makeKeywords("define let letrec let* lambda");
+ var keywords = makeKeywords("λ case-lambda call/cc class cond-expand define-class define-values exit-handler field import inherit init-field interface let*-values let-values let/ec mixin opt-lambda override protect provide public rename require require-for-syntax syntax syntax-case syntax-error unit/sig unless when with-syntax and begin call-with-current-continuation call-with-input-file call-with-output-file case cond define define-syntax define-macro defmacro delay do dynamic-wind else for-each if lambda let let* let-syntax letrec letrec-syntax map or syntax-rules abs acos angle append apply asin assoc assq assv atan boolean? caar cadr call-with-input-file call-with-output-file call-with-values car cdddar cddddr cdr ceiling char->integer char-alphabetic? char-ci<=? char-ci<? char-ci=? char-ci>=? char-ci>? char-downcase char-lower-case? char-numeric? char-ready? char-upcase char-upper-case? char-whitespace? char<=? char<? char=? char>=? char>? char? close-input-port close-output-port complex? cons cos current-input-port current-output-port denominator display eof-object? eq? equal? eqv? eval even? exact->inexact exact? exp expt #f floor force gcd imag-part inexact->exact inexact? input-port? integer->char integer? interaction-environment lcm length list list->string list->vector list-ref list-tail list? load log magnitude make-polar make-rectangular make-string make-vector max member memq memv min modulo negative? newline not null-environment null? number->string number? numerator odd? open-input-file open-output-file output-port? pair? peek-char port? positive? procedure? quasiquote quote quotient rational? rationalize read read-char real-part real? remainder reverse round scheme-report-environment set! set-car! set-cdr! sin sqrt string string->list string->number string->symbol string-append string-ci<=? string-ci<? string-ci=? string-ci>=? string-ci>? string-copy string-fill! string-length string-ref string-set! string<=? string<? string=? string>=? string>? string? substring symbol->string symbol? #t tan transcript-off transcript-on truncate values vector vector->list vector-fill! vector-length vector-ref vector-set! with-input-from-file with-output-to-file write write-char zero?");
+ var indentKeys = makeKeywords("define let letrec let* lambda define-macro defmacro let-syntax letrec-syntax let-values let*-values define-syntax syntax-rules define-values when unless");
function stateStack(indent, type, prev) { // represents a state stack object
this.indent = indent;
@@ -170,7 +170,7 @@ CodeMirror.defineMode("scheme", function () {
} else if (stream.match(/^[-+0-9.]/, false)) {
hasRadix = false;
numTest = isDecimalNumber;
- // re-consume the intial # if all matches failed
+ // re-consume the initial # if all matches failed
} else if (!hasExactness) {
stream.eat('#');
}
diff --git a/help3/xhpeditor/cm/mode/shell/shell.js b/help3/xhpeditor/cm/mode/shell/shell.js
index 5af12413..8271485f 100644
--- a/help3/xhpeditor/cm/mode/shell/shell.js
+++ b/help3/xhpeditor/cm/mode/shell/shell.js
@@ -70,6 +70,14 @@ CodeMirror.defineMode('shell', function() {
stream.eatWhile(/\w/);
return 'attribute';
}
+ if (ch == "<") {
+ if (stream.match("<<")) return "operator"
+ var heredoc = stream.match(/^<-?\s*['"]?([^'"]*)['"]?/)
+ if (heredoc) {
+ state.tokens.unshift(tokenHeredoc(heredoc[1]))
+ return 'string-2'
+ }
+ }
if (/\d/.test(ch)) {
stream.eatWhile(/\d/);
if(stream.eol() || !/\w/.test(stream.peek())) {
@@ -129,6 +137,14 @@ CodeMirror.defineMode('shell', function() {
return 'def';
};
+ function tokenHeredoc(delim) {
+ return function(stream, state) {
+ if (stream.sol() && stream.string == delim) state.tokens.shift()
+ stream.skipToEnd()
+ return "string-2"
+ }
+ }
+
function tokenize(stream, state) {
return (state.tokens[0] || tokenBase) (stream, state);
};
diff --git a/help3/xhpeditor/cm/mode/shell/test.js b/help3/xhpeditor/cm/mode/shell/test.js
index 7571d907..237375d4 100644
--- a/help3/xhpeditor/cm/mode/shell/test.js
+++ b/help3/xhpeditor/cm/mode/shell/test.js
@@ -65,9 +65,16 @@
MT("strings in parens",
"[def FOO][operator =]([quote $(<][string \"][def $MYDIR][string \"][quote /myfile grep ][string 'hello$'][quote )])")
- MT ("string ending in dollar",
- '[def a][operator =][string "xyz$"]; [def b][operator =][string "y"]')
+ MT("string ending in dollar",
+ '[def a][operator =][string "xyz$"]; [def b][operator =][string "y"]')
- MT ("quote ending in dollar",
- "[quote $(echo a$)]")
+ MT("quote ending in dollar",
+ "[quote $(echo a$)]")
+
+ MT("heredoc",
+ "[builtin cat] [string-2 <<- end]",
+ "[string-2 content one]",
+ "[string-2 content two end]",
+ "[string-2 end]",
+ "[builtin echo]")
})();
diff --git a/help3/xhpeditor/cm/mode/sieve/sieve.js b/help3/xhpeditor/cm/mode/sieve/sieve.js
index f02a867e..b7236401 100644
--- a/help3/xhpeditor/cm/mode/sieve/sieve.js
+++ b/help3/xhpeditor/cm/mode/sieve/sieve.js
@@ -43,7 +43,7 @@ CodeMirror.defineMode("sieve", function(config) {
if (ch == "(") {
state._indent.push("(");
// add virtual angel wings so that editor behaves...
- // ...more sane incase of broken brackets
+ // ...more sane in case of broken brackets
state._indent.push("{");
return null;
}
diff --git a/help3/xhpeditor/cm/mode/soy/soy.js b/help3/xhpeditor/cm/mode/soy/soy.js
index fc280c77..1f8a13c4 100644
--- a/help3/xhpeditor/cm/mode/soy/soy.js
+++ b/help3/xhpeditor/cm/mode/soy/soy.js
@@ -16,6 +16,8 @@
"alias": { noEndTag: true },
"delpackage": { noEndTag: true },
"namespace": { noEndTag: true, soyState: "namespace-def" },
+ "@attribute": paramData,
+ "@attribute?": paramData,
"@param": paramData,
"@param?": paramData,
"@inject": paramData,
@@ -34,9 +36,9 @@
"switch": {},
"case": { noEndTag: true, reduceIndent: true},
"default": { noEndTag: true, reduceIndent: true},
- "foreach": { variableScope: true, soyState: "var-def" },
+ "foreach": { variableScope: true, soyState: "for-loop" },
"ifempty": { noEndTag: true, reduceIndent: true},
- "for": { variableScope: true, soyState: "var-def" },
+ "for": { variableScope: true, soyState: "for-loop" },
"call": { soyState: "templ-ref" },
"param": { soyState: "param-ref"},
"print": { noEndTag: true },
@@ -53,7 +55,7 @@
CodeMirror.defineMode("soy", function(config) {
var textMode = CodeMirror.getMode(config, "text/plain");
var modes = {
- html: CodeMirror.getMode(config, {name: "text/html", multilineTagIndentFactor: 2, multilineTagIndentPastTag: false}),
+ html: CodeMirror.getMode(config, {name: "text/html", multilineTagIndentFactor: 2, multilineTagIndentPastTag: false, allowMissingTagName: true}),
attributes: textMode,
text: textMode,
uri: textMode,
@@ -125,16 +127,55 @@
this.scope = scope;
}
+ function expression(stream, state) {
+ var match;
+ if (stream.match(/[[]/)) {
+ state.soyState.push("list-literal");
+ state.context = new Context(state.context, "list-literal", state.variables);
+ state.lookupVariables = false;
+ return null;
+ } else if (stream.match(/map\b/)) {
+ state.soyState.push("map-literal");
+ return "keyword";
+ } else if (stream.match(/record\b/)) {
+ state.soyState.push("record-literal");
+ return "keyword";
+ } else if (stream.match(/([\w]+)(?=\()/)) {
+ return "variable callee";
+ } else if (match = stream.match(/^["']/)) {
+ state.soyState.push("string");
+ state.quoteKind = match[0];
+ return "string";
+ } else if (stream.match(/^[(]/)) {
+ state.soyState.push("open-parentheses");
+ return null;
+ } else if (stream.match(/(null|true|false)(?!\w)/) ||
+ stream.match(/0x([0-9a-fA-F]{2,})/) ||
+ stream.match(/-?([0-9]*[.])?[0-9]+(e[0-9]*)?/)) {
+ return "atom";
+ } else if (stream.match(/(\||[+\-*\/%]|[=!]=|\?:|[<>]=?)/)) {
+ // Tokenize filter, binary, null propagator, and equality operators.
+ return "operator";
+ } else if (match = stream.match(/^\$([\w]+)/)) {
+ return ref(state.variables, match[1], !state.lookupVariables);
+ } else if (match = stream.match(/^\w+/)) {
+ return /^(?:as|and|or|not|in|if)$/.test(match[0]) ? "keyword" : null;
+ }
+
+ stream.next();
+ return null;
+ }
+
return {
startState: function() {
return {
soyState: [],
- templates: null,
variables: prepend(null, 'ij'),
scopes: null,
indent: 0,
quoteKind: null,
context: null,
+ lookupVariables: true, // Is unknown variables considered an error
localStates: [{
mode: modes.html,
state: CodeMirror.startState(modes.html)
@@ -146,11 +187,11 @@
return {
tag: state.tag, // Last seen Soy tag.
soyState: state.soyState.concat([]),
- templates: state.templates,
variables: state.variables,
context: state.context,
indent: state.indent, // Indentation of the following line.
quoteKind: state.quoteKind,
+ lookupVariables: state.lookupVariables,
localStates: state.localStates.map(function(localState) {
return {
mode: localState.mode,
@@ -202,7 +243,6 @@
switch (last(state.soyState)) {
case "templ-def":
if (match = stream.match(/^\.?([\w]+(?!\.[\w]+)*)/)) {
- state.templates = prepend(state.templates, match[1]);
state.soyState.pop();
return "def";
}
@@ -219,6 +259,11 @@
// Otherwise
return "variable";
}
+ if (match = stream.match(/^\$([\w]+)/)) {
+ state.soyState.pop();
+ return ref(state.variables, match[1], !state.lookupVariables);
+ }
+
stream.next();
return null;
@@ -231,6 +276,11 @@
return null;
case "param-def":
+ if (match = stream.match(/^\*/)) {
+ state.soyState.pop();
+ state.soyState.push("param-type");
+ return "type";
+ }
if (match = stream.match(/^\w+/)) {
state.variables = prepend(state.variables, match[0]);
state.soyState.pop();
@@ -248,18 +298,71 @@
stream.next();
return null;
+ case "open-parentheses":
+ if (stream.match(/[)]/)) {
+ state.soyState.pop();
+ return null;
+ }
+ return expression(stream, state);
+
case "param-type":
var peekChar = stream.peek();
- if (peekChar == "}" || peekChar == "=") {
+ if ("}]=>,".indexOf(peekChar) != -1) {
state.soyState.pop();
return null;
- }
- if (stream.eatWhile(/^([\w]+|[?])/)) {
+ } else if (peekChar == "[") {
+ state.soyState.push('param-type-record');
+ return null;
+ } else if (peekChar == "(") {
+ state.soyState.push('param-type-template');
+ return null;
+ } else if (peekChar == "<") {
+ state.soyState.push('param-type-parameter');
+ return null;
+ } else if (match = stream.match(/^([\w]+|[?])/)) {
return "type";
}
stream.next();
return null;
+ case "param-type-record":
+ var peekChar = stream.peek();
+ if (peekChar == "]") {
+ state.soyState.pop();
+ return null;
+ }
+ if (stream.match(/^\w+/)) {
+ state.soyState.push('param-type');
+ return "property";
+ }
+ stream.next();
+ return null;
+
+ case "param-type-parameter":
+ if (stream.match(/^[>]/)) {
+ state.soyState.pop();
+ return null;
+ }
+ if (stream.match(/^[<,]/)) {
+ state.soyState.push('param-type');
+ return null;
+ }
+ stream.next();
+ return null;
+
+ case "param-type-template":
+ if (stream.match(/[>]/)) {
+ state.soyState.pop();
+ state.soyState.push('param-type');
+ return null;
+ }
+ if (stream.match(/^\w+/)) {
+ state.soyState.push('param-type');
+ return "def";
+ }
+ stream.next();
+ return null;
+
case "var-def":
if (match = stream.match(/^\$([\w]+)/)) {
state.variables = prepend(state.variables, match[1]);
@@ -269,9 +372,106 @@
stream.next();
return null;
+ case "for-loop":
+ if (stream.match(/\bin\b/)) {
+ state.soyState.pop();
+ return "keyword";
+ }
+ if (stream.peek() == "$") {
+ state.soyState.push('var-def');
+ return null;
+ }
+ stream.next();
+ return null;
+
+ case "record-literal":
+ if (stream.match(/^[)]/)) {
+ state.soyState.pop();
+ return null;
+ }
+ if (stream.match(/[(,]/)) {
+ state.soyState.push("map-value")
+ state.soyState.push("record-key")
+ return null;
+ }
+ stream.next()
+ return null;
+
+ case "map-literal":
+ if (stream.match(/^[)]/)) {
+ state.soyState.pop();
+ return null;
+ }
+ if (stream.match(/[(,]/)) {
+ state.soyState.push("map-value")
+ state.soyState.push("map-value")
+ return null;
+ }
+ stream.next()
+ return null;
+
+ case "list-literal":
+ if (stream.match(']')) {
+ state.soyState.pop();
+ state.lookupVariables = true;
+ popcontext(state);
+ return null;
+ }
+ if (stream.match(/\bfor\b/)) {
+ state.lookupVariables = true;
+ state.soyState.push('for-loop');
+ return "keyword";
+ }
+ return expression(stream, state);
+
+ case "record-key":
+ if (stream.match(/[\w]+/)) {
+ return "property";
+ }
+ if (stream.match(/^[:]/)) {
+ state.soyState.pop();
+ return null;
+ }
+ stream.next();
+ return null;
+
+ case "map-value":
+ if (stream.peek() == ")" || stream.peek() == "," || stream.match(/^[:)]/)) {
+ state.soyState.pop();
+ return null;
+ }
+ return expression(stream, state);
+
+ case "import":
+ if (stream.eat(";")) {
+ state.soyState.pop();
+ state.indent -= 2 * config.indentUnit;
+ return null;
+ }
+ if (stream.match(/\w+(?=\s+as)/)) {
+ return "variable";
+ }
+ if (match = stream.match(/\w+/)) {
+ return /(from|as)/.test(match[0]) ? "keyword" : "def";
+ }
+ if (match = stream.match(/^["']/)) {
+ state.soyState.push("string");
+ state.quoteKind = match[0];
+ return "string";
+ }
+ stream.next();
+ return null;
+
case "tag":
- var endTag = state.tag[0] == "/";
- var tagName = endTag ? state.tag.substring(1) : state.tag;
+ var endTag;
+ var tagName;
+ if (state.tag === undefined) {
+ endTag = true;
+ tagName = '';
+ } else {
+ endTag = state.tag[0] == "/";
+ tagName = endTag ? state.tag.substring(1) : state.tag;
+ }
var tag = tags[tagName];
if (stream.match(/^\/?}/)) {
var selfClosed = stream.current() == "/}";
@@ -302,40 +502,29 @@
});
}
return "attribute";
- } else if (match = stream.match(/([\w]+)(?=\()/)) {
- return "variable callee";
- } else if (match = stream.match(/^["']/)) {
- state.soyState.push("string");
- state.quoteKind = match;
- return "string";
- }
- if (stream.match(/(null|true|false)(?!\w)/) ||
- stream.match(/0x([0-9a-fA-F]{2,})/) ||
- stream.match(/-?([0-9]*[.])?[0-9]+(e[0-9]*)?/)) {
- return "atom";
- }
- if (stream.match(/(\||[+\-*\/%]|[=!]=|\?:|[<>]=?)/)) {
- // Tokenize filter, binary, null propagator, and equality operators.
- return "operator";
- }
- if (match = stream.match(/^\$([\w]+)/)) {
- return ref(state.variables, match[1]);
- }
- if (match = stream.match(/^\w+/)) {
- return /^(?:as|and|or|not|in)$/.test(match[0]) ? "keyword" : null;
}
- stream.next();
- return null;
+ return expression(stream, state);
+ case "template-call-expression":
+ if (stream.match(/^([\w-?]+)(?==)/)) {
+ return "attribute";
+ } else if (stream.eat('>')) {
+ state.soyState.pop();
+ return "keyword";
+ } else if (stream.eat('/>')) {
+ state.soyState.pop();
+ return "keyword";
+ }
+ return expression(stream, state);
case "literal":
- if (stream.match(/^(?=\{\/literal})/)) {
+ if (stream.match('{/literal}', false)) {
state.soyState.pop();
return this.token(stream, state);
}
return tokenUntil(stream, state, /\{\/literal}/);
}
- if (stream.match(/^\{literal}/)) {
+ if (stream.match('{literal}')) {
state.indent += config.indentUnit;
state.soyState.push("literal");
state.context = new Context(state.context, "literal", state.variables);
@@ -388,6 +577,18 @@
state.indent += 2 * config.indentUnit;
state.soyState.push("tag");
return "keyword";
+ } else if (!state.context && stream.match(/\bimport\b/)) {
+ state.soyState.push("import");
+ state.indent += 2 * config.indentUnit;
+ return "keyword";
+ } else if (match = stream.match('<{')) {
+ state.soyState.push("template-call-expression");
+ state.indent += 2 * config.indentUnit;
+ state.soyState.push("tag");
+ return "keyword";
+ } else if (match = stream.match('</>')) {
+ state.indent -= 1 * config.indentUnit;
+ return "keyword";
}
return tokenUntil(stream, state, /\{|\s+\/\/|\/\*/);
diff --git a/help3/xhpeditor/cm/mode/soy/test.js b/help3/xhpeditor/cm/mode/soy/test.js
index 8234813f..ae131587 100644
--- a/help3/xhpeditor/cm/mode/soy/test.js
+++ b/help3/xhpeditor/cm/mode/soy/test.js
@@ -26,6 +26,15 @@
'[keyword {] [callee&variable index]([variable-2&error $list])[keyword }]' +
'[string "][tag&bracket />]');
+ MT('soy-element-composition-test',
+ '[keyword <{][callee&variable foo]()[keyword }]',
+ '[keyword ></>]');
+
+ MT('soy-element-composition-attribute-test',
+ '[keyword <{][callee&variable foo]()[keyword }]',
+ '[attribute class]=[string "Foo"]',
+ '[keyword ></>]');
+
MT('namespace-test',
'[keyword {namespace] [variable namespace][keyword }]')
@@ -63,13 +72,27 @@
'[keyword {] [atom 0x1F] [keyword }]',
'[keyword {] [atom 0x1F00BBEA] [keyword }]');
- MT('param-type-test',
+ MT('param-type-record',
+ '[keyword {@param] [def record]: [[[property foo]: [type bool], [property bar]: [type int] ]][keyword }]'
+ );
+
+ MT('param-type-map',
+ '[keyword {@param] [def unknown]: [type map]<[type string], [type bool]>[keyword }]'
+ );
+
+ MT('param-type-list',
+ '[keyword {@param] [def list]: [type list]<[type ?]>[keyword }]'
+ );
+
+ MT('param-type-any',
+ '[keyword {@param] [def unknown]: [type ?][keyword }]'
+ );
+
+ MT('param-type-nested',
'[keyword {@param] [def a]: ' +
- '[type list]<[[[type a]: [type int], ' +
- '[type b]: [type map]<[type string], ' +
- '[type bool]>]]>][keyword }]',
- '[keyword {@param] [def unknown]: [type ?][keyword }]',
- '[keyword {@param] [def list]: [type list]<[type ?]>[keyword }]');
+ '[type list]<[[[property a]: [type int], ' +
+ '[property b]: [type map]<[type string], ' +
+ '[type bool]>]]>][keyword }]');
MT('undefined-var',
'[keyword {][variable-2&error $var]');
@@ -124,6 +147,11 @@
'[keyword {/foreach}]',
'');
+ MT('foreach-index',
+ '[keyword {foreach] [def $foo],[def $index] [keyword in] [[]] [keyword }]',
+ ' [keyword {][variable-2 $foo][keyword }] [keyword {][variable-2 $index][keyword }]',
+ '[keyword {/foreach}]');
+
MT('nested-kind-test',
'[keyword {template] [def .foo] [attribute kind]=[string "html"][keyword }]',
' [tag&bracket <][tag div][tag&bracket >]',
@@ -157,6 +185,24 @@
'[keyword {/template}]',
'');
+ MT('attribute-type',
+ '[keyword {template] [def .foo][keyword }]',
+ ' [keyword {@attribute] [def bar]: [type string][keyword }]',
+ '[keyword {/template}]',
+ '');
+
+ MT('attribute-type-optional',
+ '[keyword {template] [def .foo][keyword }]',
+ ' [keyword {@attribute] [def bar]: [type string][keyword }]',
+ '[keyword {/template}]',
+ '');
+
+ MT('attribute-type-all',
+ '[keyword {template] [def .foo][keyword }]',
+ ' [keyword {@attribute] [type *][keyword }]',
+ '[keyword {/template}]',
+ '');
+
MT('state-variable-reference',
'[keyword {template] [def .foo][keyword }]',
' [keyword {@param] [def bar]:= [atom true][keyword }]',
@@ -164,6 +210,13 @@
'[keyword {/template}]',
'');
+ MT('param-type-template',
+ '[keyword {template] [def .foo][keyword }]',
+ ' [keyword {@param] [def renderer]: ([def s]:[type string])=>[type html][keyword }]',
+ ' [keyword {call] [variable-2 $renderer] [keyword /}]',
+ '[keyword {/template}]',
+ '');
+
MT('single-quote-strings',
'[keyword {][string "foo"] [string \'bar\'][keyword }]',
'');
@@ -218,8 +271,41 @@
'[keyword {lb}]',
'[keyword {rb}]');
+ MT('let-list-literal',
+ '[keyword {let] [def $test]: [[[[[string \'a\'] ], [[[string \'b\'] ] ] [keyword /}]');
+
+ MT('let-record-literal',
+ '[keyword {let] [def $test]: [keyword record]([property test]: [callee&variable bidiGlobalDir](), ' +
+ '[property foo]: [atom 5]) [keyword /}]');
+
+ MT('let-map-literal',
+ '[keyword {let] [def $test]: [keyword map]([string \'outer\']: [keyword map]([atom 5]: [atom false]), ' +
+ '[string \'foo\']: [string \'bar\']) [keyword /}]');
+
MT('wrong-closing-tag',
'[keyword {if] [atom true][keyword }]',
' Optional',
'[keyword&error {/badend][keyword }]');
+
+ MT('list-comprehension',
+ '[keyword {let] [def $myList]: [[[[[string \'a\'] ] ] [keyword /}] ' +
+ '[keyword {let] [def $test]: [[[variable $a] [operator +] [atom 1] [keyword for] ' +
+ '[def $a] [keyword in] [variable-2 $myList] [keyword if] [variable-2 $a] [operator >=] [atom 3] ] [keyword /}]');
+
+ MT('list-comprehension-index',
+ '[keyword {let] [def $test]: [[[variable $a] [operator +] [variable $index] [keyword for] ' +
+ '[def $a],[def $index] [keyword in] [[]] [keyword if] [variable-2 $a] [operator >=] [variable-2 $index] ] [keyword /}]');
+
+
+ MT('list-comprehension-variable-scope',
+ '[keyword {let] [def $name]: [string "world"][keyword /}]',
+ '[keyword {let] [def $test]: [[[variable $a] [operator +] [variable $index] [keyword for] ' +
+ '[def $a],[def $index] [keyword in] [[]] [keyword if] [variable-2 $a] [operator >=] [variable-2 $index] ] [keyword /}]',
+ '[keyword {][variable-2&error $a][keyword }]',
+ '[keyword {][variable-2&error $index][keyword }]',
+ '[keyword {][variable-2 $test][keyword }]',
+ '[keyword {][variable-2 $name][keyword }]');
+
+ MT('import',
+ '[keyword import] {[def Name], [variable Person] [keyword as] [def P]} [keyword from] [string \'examples/proto/example.proto\'];');
})();
diff --git a/help3/xhpeditor/cm/mode/sparql/sparql.js b/help3/xhpeditor/cm/mode/sparql/sparql.js
index bb79abff..6d1d2446 100644
--- a/help3/xhpeditor/cm/mode/sparql/sparql.js
+++ b/help3/xhpeditor/cm/mode/sparql/sparql.js
@@ -60,12 +60,18 @@ CodeMirror.defineMode("sparql", function(config) {
stream.skipToEnd();
return "comment";
}
+ else if (ch === "^") {
+ ch = stream.peek();
+ if (ch === "^") stream.eat("^");
+ else stream.eatWhile(operatorChars);
+ return "operator";
+ }
else if (operatorChars.test(ch)) {
stream.eatWhile(operatorChars);
return "operator";
}
else if (ch == ":") {
- stream.eatWhile(/[\w\d\._\-]/);
+ eatPnLocal(stream);
return "atom";
}
else if (ch == "@") {
@@ -75,7 +81,7 @@ CodeMirror.defineMode("sparql", function(config) {
else {
stream.eatWhile(/[_\w\d]/);
if (stream.eat(":")) {
- stream.eatWhile(/[\w\d_\-]/);
+ eatPnLocal(stream);
return "atom";
}
var word = stream.current();
@@ -88,6 +94,10 @@ CodeMirror.defineMode("sparql", function(config) {
}
}
+ function eatPnLocal(stream) {
+ stream.match(/(\.(?=[\w_\-\\%])|[:\w_-]|\\[-\\_~.!$&'()*+,;=/?#@%]|%[a-f\d][a-f\d])+/i);
+ }
+
function tokenLiteral(quote) {
return function(stream, state) {
var escaped = false, ch;
diff --git a/help3/xhpeditor/cm/mode/sql/sql.js b/help3/xhpeditor/cm/mode/sql/sql.js
index e43495d2..ead4d6db 100644
--- a/help3/xhpeditor/cm/mode/sql/sql.js
+++ b/help3/xhpeditor/cm/mode/sql/sql.js
@@ -96,7 +96,7 @@ CodeMirror.defineMode("sql", function(config, parserConfig) {
return null
// .table_name (ODBC)
// // ref: http://dev.mysql.com/doc/refman/5.6/en/identifier-qualifiers.html
- if (support.ODBCdotTable && stream.match(/^[\w\d_]+/))
+ if (support.ODBCdotTable && stream.match(/^[\w\d_$#]+/))
return "variable-2";
} else if (operatorChars.test(ch)) {
// operators
@@ -243,9 +243,9 @@ CodeMirror.defineMode("sql", function(config, parserConfig) {
// varName can be quoted with ` or ' or "
// ref: http://dev.mysql.com/doc/refman/5.5/en/user-variables.html
if (stream.eat("@")) {
- stream.match(/^session\./);
- stream.match(/^local\./);
- stream.match(/^global\./);
+ stream.match('session.');
+ stream.match('local.');
+ stream.match('global.');
}
if (stream.eat("'")) {
@@ -370,7 +370,7 @@ CodeMirror.defineMode("sql", function(config, parserConfig) {
"$": hookVar,
// The preferred way to escape Identifiers is using double quotes, ref: http://sqlite.org/lang_keywords.html
"\"": hookIdentifierDoublequote,
- // there is also support for backtics, ref: http://sqlite.org/lang_keywords.html
+ // there is also support for backticks, ref: http://sqlite.org/lang_keywords.html
"`": hookIdentifier
}
});
@@ -451,7 +451,7 @@ CodeMirror.defineMode("sql", function(config, parserConfig) {
// Spark SQL
CodeMirror.defineMIME("text/x-sparksql", {
name: "sql",
- keywords: set("add after all alter analyze and anti archive array as asc at between bucket buckets by cache cascade case cast change clear cluster clustered codegen collection column columns comment commit compact compactions compute concatenate cost create cross cube current current_date current_timestamp database databases datata dbproperties defined delete delimited deny desc describe dfs directories distinct distribute drop else end escaped except exchange exists explain export extended external false fields fileformat first following for format formatted from full function functions global grant group grouping having if ignore import in index indexes inner inpath inputformat insert intersect interval into is items join keys last lateral lazy left like limit lines list load local location lock locks logical macro map minus msck natural no not null nulls of on optimize option options or order out outer outputformat over overwrite partition partitioned partitions percent preceding principals purge range recordreader recordwriter recover reduce refresh regexp rename repair replace reset restrict revoke right rlike role roles rollback rollup row rows schema schemas select semi separated serde serdeproperties set sets show skewed sort sorted start statistics stored stratify struct table tables tablesample tblproperties temp temporary terminated then to touch transaction transactions transform true truncate unarchive unbounded uncache union unlock unset use using values view when where window with"),
+ keywords: set("add after all alter analyze and anti archive array as asc at between bucket buckets by cache cascade case cast change clear cluster clustered codegen collection column columns comment commit compact compactions compute concatenate cost create cross cube current current_date current_timestamp database databases data dbproperties defined delete delimited deny desc describe dfs directories distinct distribute drop else end escaped except exchange exists explain export extended external false fields fileformat first following for format formatted from full function functions global grant group grouping having if ignore import in index indexes inner inpath inputformat insert intersect interval into is items join keys last lateral lazy left like limit lines list load local location lock locks logical macro map minus msck natural no not null nulls of on optimize option options or order out outer outputformat over overwrite partition partitioned partitions percent preceding principals purge range recordreader recordwriter recover reduce refresh regexp rename repair replace reset restrict revoke right rlike role roles rollback rollup row rows schema schemas select semi separated serde serdeproperties set sets show skewed sort sorted start statistics stored stratify struct table tables tablesample tblproperties temp temporary terminated then to touch transaction transactions transform true truncate unarchive unbounded uncache union unlock unset use using values view when where window with"),
builtin: set("tinyint smallint int bigint boolean float double string binary timestamp decimal array map struct uniontype delimited serde sequencefile textfile rcfile inputformat outputformat"),
atoms: set("false true null"),
operatorChars: /^[*\/+\-%<>!=~&|^]/,
diff --git a/help3/xhpeditor/cm/mode/stex/stex.js b/help3/xhpeditor/cm/mode/stex/stex.js
index 140e5a8a..20c3bc7a 100644
--- a/help3/xhpeditor/cm/mode/stex/stex.js
+++ b/help3/xhpeditor/cm/mode/stex/stex.js
@@ -103,7 +103,7 @@
// Do we look like '\command' ? If so, attempt to apply the plugin 'command'
if (source.match(/^\\[a-zA-Z@]+/)) {
var cmdName = source.current().slice(1);
- plug = plugins[cmdName] || plugins["DEFAULT"];
+ plug = plugins.hasOwnProperty(cmdName) ? plugins[cmdName] : plugins["DEFAULT"];
plug = new plug();
pushCommand(state, plug);
setState(state, beginParams);
diff --git a/help3/xhpeditor/cm/mode/stylus/stylus.js b/help3/xhpeditor/cm/mode/stylus/stylus.js
index dbe241d6..5cddff03 100644
--- a/help3/xhpeditor/cm/mode/stylus/stylus.js
+++ b/help3/xhpeditor/cm/mode/stylus/stylus.js
@@ -76,7 +76,7 @@
if (ch == "#") {
stream.next();
// Hex color
- if (stream.match(/^[0-9a-f]{3}([0-9a-f]([0-9a-f]{2}){0,2})?\b/i)) {
+ if (stream.match(/^[0-9a-f]{3}([0-9a-f]([0-9a-f]{2}){0,2})?\b(?!-)/i)) {
return ["atom", "atom"];
}
// ID selector
@@ -138,7 +138,7 @@
// Variable
if (stream.match(/^(\.|\[)[\w-\'\"\]]+/i, false)) {
if (!wordIsTag(stream.current())) {
- stream.match(/\./);
+ stream.match('.');
return ["variable-2", "variable-name"];
}
}
@@ -722,6 +722,9 @@
return indent;
},
electricChars: "}",
+ blockCommentStart: "/*",
+ blockCommentEnd: "*/",
+ blockCommentContinue: " * ",
lineComment: "//",
fold: "indent"
};
@@ -731,7 +734,8 @@
var tagKeywords_ = ["a","abbr","address","area","article","aside","audio", "b", "base","bdi", "bdo","bgsound","blockquote","body","br","button","canvas","caption","cite", "code","col","colgroup","data","datalist","dd","del","details","dfn","div", "dl","dt","em","embed","fieldset","figcaption","figure","footer","form","h1", "h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","iframe", "img","input","ins","kbd","keygen","label","legend","li","link","main","map", "mark","marquee","menu","menuitem","meta","meter","nav","nobr","noframes", "noscript","object","ol","optgroup","option","output","p","param","pre", "progress","q","rp","rt","ruby","s","samp","script","section","select", "small","source","span","strong","style","sub","summary","sup","table","tbody","td","textarea","tfoot","th","thead","time","tr","track", "u","ul","var","video"];
// github.com/codemirror/CodeMirror/blob/master/mode/css/css.js
- var documentTypes_ = ["domain", "regexp", "url", "url-prefix"];
+ // Note, "url-prefix" should precede "url" in order to match correctly in documentTypesRegexp
+ var documentTypes_ = ["domain", "regexp", "url-prefix", "url"];
var mediaTypes_ = ["all","aural","braille","handheld","print","projection","screen","tty","tv","embossed"];
var mediaFeatures_ = ["width","min-width","max-width","height","min-height","max-height","device-width","min-device-width","max-device-width","device-height","min-device-height","max-device-height","aspect-ratio","min-aspect-ratio","max-aspect-ratio","device-aspect-ratio","min-device-aspect-ratio","max-device-aspect-ratio","color","min-color","max-color","color-index","min-color-index","max-color-index","monochrome","min-monochrome","max-monochrome","resolution","min-resolution","max-resolution","scan","grid"];
var propertyKeywords_ = ["align-content","align-items","align-self","alignment-adjust","alignment-baseline","anchor-point","animation","animation-delay","animation-direction","animation-duration","animation-fill-mode","animation-iteration-count","animation-name","animation-play-state","animation-timing-function","appearance","azimuth","backface-visibility","background","background-attachment","background-clip","background-color","background-image","background-origin","background-position","background-repeat","background-size","baseline-shift","binding","bleed","bookmark-label","bookmark-level","bookmark-state","bookmark-target","border","border-bottom","border-bottom-color","border-bottom-left-radius","border-bottom-right-radius","border-bottom-style","border-bottom-width","border-collapse","border-color","border-image","border-image-outset","border-image-repeat","border-image-slice","border-image-source","border-image-width","border-left","border-left-color","border-left-style","border-left-width","border-radius","border-right","border-right-color","border-right-style","border-right-width","border-spacing","border-style","border-top","border-top-color","border-top-left-radius","border-top-right-radius","border-top-style","border-top-width","border-width","bottom","box-decoration-break","box-shadow","box-sizing","break-after","break-before","break-inside","caption-side","clear","clip","color","color-profile","column-count","column-fill","column-gap","column-rule","column-rule-color","column-rule-style","column-rule-width","column-span","column-width","columns","content","counter-increment","counter-reset","crop","cue","cue-after","cue-before","cursor","direction","display","dominant-baseline","drop-initial-after-adjust","drop-initial-after-align","drop-initial-before-adjust","drop-initial-before-align","drop-initial-size","drop-initial-value","elevation","empty-cells","fit","fit-position","flex","flex-basis","flex-direction","flex-flow","flex-grow","flex-shrink","flex-wrap","float","float-offset","flow-from","flow-into","font","font-feature-settings","font-family","font-kerning","font-language-override","font-size","font-size-adjust","font-stretch","font-style","font-synthesis","font-variant","font-variant-alternates","font-variant-caps","font-variant-east-asian","font-variant-ligatures","font-variant-numeric","font-variant-position","font-weight","grid","grid-area","grid-auto-columns","grid-auto-flow","grid-auto-position","grid-auto-rows","grid-column","grid-column-end","grid-column-start","grid-row","grid-row-end","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","line-break","line-height","line-stacking","line-stacking-ruby","line-stacking-shift","line-stacking-strategy","list-style","list-style-image","list-style-position","list-style-type","margin","margin-bottom","margin-left","margin-right","margin-top","marker-offset","marks","marquee-direction","marquee-loop","marquee-play-count","marquee-speed","marquee-style","max-height","max-width","min-height","min-width","move-to","nav-down","nav-index","nav-left","nav-right","nav-up","object-fit","object-position","opacity","order","orphans","outline","outline-color","outline-offset","outline-style","outline-width","overflow","overflow-style","overflow-wrap","overflow-x","overflow-y","padding","padding-bottom","padding-left","padding-right","padding-top","page","page-break-after","page-break-before","page-break-inside","page-policy","pause","pause-after","pause-before","perspective","perspective-origin","pitch","pitch-range","play-during","position","presentation-level","punctuation-trim","quotes","region-break-after","region-break-before","region-break-inside","region-fragment","rendering-intent","resize","rest","rest-after","rest-before","richness","right","rotation","rotation-point","ruby-align","ruby-overhang","ruby-position","ruby-span","shape-image-threshold","shape-inside","shape-margin","shape-outside","size","speak","speak-as","speak-header","speak-numeral","speak-punctuation","speech-rate","stress","string-set","tab-size","table-layout","target","target-name","target-new","target-position","text-align","text-align-last","text-decoration","text-decoration-color","text-decoration-line","text-decoration-skip","text-decoration-style","text-emphasis","text-emphasis-color","text-emphasis-position","text-emphasis-style","text-height","text-indent","text-justify","text-outline","text-overflow","text-shadow","text-size-adjust","text-space-collapse","text-transform","text-underline-position","text-wrap","top","transform","transform-origin","transform-style","transition","transition-delay","transition-duration","transition-property","transition-timing-function","unicode-bidi","vertical-align","visibility","voice-balance","voice-duration","voice-family","voice-pitch","voice-range","voice-rate","voice-stress","voice-volume","volume","white-space","widows","width","will-change","word-break","word-spacing","word-wrap","z-index","clip-path","clip-rule","mask","enable-background","filter","flood-color","flood-opacity","lighting-color","stop-color","stop-opacity","pointer-events","color-interpolation","color-interpolation-filters","color-rendering","fill","fill-opacity","fill-rule","image-rendering","marker","marker-end","marker-mid","marker-start","shape-rendering","stroke","stroke-dasharray","stroke-dashoffset","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke-width","text-rendering","baseline-shift","dominant-baseline","glyph-orientation-horizontal","glyph-orientation-vertical","text-anchor","writing-mode","font-smoothing","osx-font-smoothing"];
diff --git a/help3/xhpeditor/cm/mode/tcl/tcl.js b/help3/xhpeditor/cm/mode/tcl/tcl.js
index a7ec89c9..dec0662a 100644
--- a/help3/xhpeditor/cm/mode/tcl/tcl.js
+++ b/help3/xhpeditor/cm/mode/tcl/tcl.js
@@ -131,7 +131,8 @@ CodeMirror.defineMode("tcl", function() {
token: function(stream, state) {
if (stream.eatSpace()) return null;
return state.tokenize(stream, state);
- }
+ },
+ lineComment: "#"
};
});
CodeMirror.defineMIME("text/x-tcl", "tcl");
diff --git a/help3/xhpeditor/cm/mode/tiddlywiki/tiddlywiki.js b/help3/xhpeditor/cm/mode/tiddlywiki/tiddlywiki.js
index a4fb89f6..6a9ce447 100644
--- a/help3/xhpeditor/cm/mode/tiddlywiki/tiddlywiki.js
+++ b/help3/xhpeditor/cm/mode/tiddlywiki/tiddlywiki.js
@@ -114,7 +114,7 @@ CodeMirror.defineMode("tiddlywiki", function () {
return 'header';
}
- if (ch == '{' && stream.match(/\{\{/))
+ if (ch == '{' && stream.match('{{'))
return chain(stream, state, twTokenCode);
// rudimentary html:// file:// link matching. TW knows much more ...
diff --git a/help3/xhpeditor/cm/mode/twig/index.html b/help3/xhpeditor/cm/mode/twig/index.html
index 7552eacd..3107d500 100644
--- a/help3/xhpeditor/cm/mode/twig/index.html
+++ b/help3/xhpeditor/cm/mode/twig/index.html
@@ -7,6 +7,8 @@
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="twig.js"></script>
+<script src="../xml/xml.js"></script>
+<script src="../../addon/mode/multiplex.js"></script>
<style>.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
<div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt=""></a>
@@ -40,6 +42,6 @@
<script>
var editor =
CodeMirror.fromTextArea(document.getElementById("code"), {mode:
- {name: "twig", htmlMode: true}});
+ {name: "twig", base: "text/html"}});
</script>
</article>
diff --git a/help3/xhpeditor/cm/mode/vb/index.html b/help3/xhpeditor/cm/mode/vb/index.html
index ecde2f45..84922c19 100644
--- a/help3/xhpeditor/cm/mode/vb/index.html
+++ b/help3/xhpeditor/cm/mode/vb/index.html
@@ -5,7 +5,7 @@
<link rel=stylesheet href="../../doc/docs.css">
<link rel="stylesheet" href="../../lib/codemirror.css">
-<link href="https://fonts.googleapis.com/css?family=Inconsolata" rel="stylesheet">
+<link href="http://fonts.googleapis.com/css?family=Inconsolata" rel="stylesheet">
<script src="../../lib/codemirror.js"></script>
<script src="vb.js"></script>
<script src="../../addon/runmode/runmode.js"></script>
diff --git a/help3/xhpeditor/cm/mode/vbscript/vbscript.js b/help3/xhpeditor/cm/mode/vbscript/vbscript.js
index 0670c0ce..40339481 100644
--- a/help3/xhpeditor/cm/mode/vbscript/vbscript.js
+++ b/help3/xhpeditor/cm/mode/vbscript/vbscript.js
@@ -32,7 +32,7 @@ CodeMirror.defineMode("vbscript", function(conf, parserConf) {
var singleOperators = new RegExp("^[\\+\\-\\*/&\\\\\\^<>=]");
var doubleOperators = new RegExp("^((<>)|(<=)|(>=))");
var singleDelimiters = new RegExp('^[\\.,]');
- var brakets = new RegExp('^[\\(\\)]');
+ var brackets = new RegExp('^[\\(\\)]');
var identifiers = new RegExp("^[A-Za-z][_A-Za-z0-9]*");
var openingKeywords = ['class','sub','select','while','if','function', 'property', 'with', 'for'];
@@ -183,7 +183,7 @@ CodeMirror.defineMode("vbscript", function(conf, parserConf) {
return null;
}
- if (stream.match(brakets)) {
+ if (stream.match(brackets)) {
return "bracket";
}
diff --git a/help3/xhpeditor/cm/mode/velocity/velocity.js b/help3/xhpeditor/cm/mode/velocity/velocity.js
index 56caa671..79a621a5 100644
--- a/help3/xhpeditor/cm/mode/velocity/velocity.js
+++ b/help3/xhpeditor/cm/mode/velocity/velocity.js
@@ -48,7 +48,7 @@ CodeMirror.defineMode("velocity", function() {
else if (state.inParams)
return chain(stream, state, tokenString(ch));
}
- // is it one of the special signs []{}().,;? Seperator?
+ // is it one of the special signs []{}().,;? Separator?
else if (/[\[\]{}\(\),;\.]/.test(ch)) {
if (ch == "(" && beforeParams)
state.inParams = true;
@@ -82,6 +82,7 @@ CodeMirror.defineMode("velocity", function() {
}
// variable?
else if (ch == "$") {
+ stream.eat("!");
stream.eatWhile(/[\w\d\$_\.{}-]/);
// is it one of the specials?
if (specials && specials.propertyIsEnumerable(stream.current())) {
diff --git a/help3/xhpeditor/cm/mode/verilog/test.js b/help3/xhpeditor/cm/mode/verilog/test.js
index bafe726d..38c1cbe4 100644
--- a/help3/xhpeditor/cm/mode/verilog/test.js
+++ b/help3/xhpeditor/cm/mode/verilog/test.js
@@ -139,6 +139,32 @@
""
);
+ MT("align_assignments",
+ /**
+ * always @(posedge clk) begin
+ * if (rst)
+ * data_out <= 8'b0 +
+ * 8'b1;
+ * else
+ * data_out = 8'b0 +
+ * 8'b1;
+ * data_out =
+ * 8'b0 + 8'b1;
+ * end
+ */
+ "[keyword always] [def @][bracket (][keyword posedge] [variable clk][bracket )] [keyword begin]",
+ " [keyword if] [bracket (][variable rst][bracket )]",
+ " [variable data_out] [meta <=] [number 8'b0] [meta +]",
+ " [number 8'b1];",
+ " [keyword else]",
+ " [variable data_out] [meta =] [number 8'b0] [meta +]",
+ " [number 8'b1];",
+ " [variable data_out] [meta =] [number 8'b0] [meta +]",
+ " [number 8'b1];",
+ "[keyword end]",
+ ""
+ );
+
// Indentation tests
MT("indent_single_statement_if",
"[keyword if] [bracket (][variable foo][bracket )]",
@@ -270,4 +296,148 @@
""
);
+ MT("indent_uvm_macros",
+ /**
+ * `uvm_object_utils_begin(foo)
+ * `uvm_field_event(foo, UVM_ALL_ON)
+ * `uvm_object_utils_end
+ */
+ "[def `uvm_object_utils_begin][bracket (][variable foo][bracket )]",
+ " [def `uvm_field_event][bracket (][variable foo], [variable UVM_ALL_ON][bracket )]",
+ "[def `uvm_object_utils_end]",
+ ""
+ );
+
+ MT("indent_uvm_macros2",
+ /**
+ * `uvm_do_with(mem_read,{
+ * bar_nb == 0;
+ * })
+ */
+ "[def `uvm_do_with][bracket (][variable mem_read],[bracket {]",
+ " [variable bar_nb] [meta ==] [number 0];",
+ "[bracket })]",
+ ""
+ );
+
+ MT("indent_wait_disable_fork",
+ /**
+ * virtual task body();
+ * repeat (20) begin
+ * fork
+ * `uvm_create_on(t,p_seq)
+ * join_none
+ * end
+ * wait fork;
+ * disable fork;
+ * endtask : body
+ */
+ "[keyword virtual] [keyword task] [variable body][bracket ()];",
+ " [keyword repeat] [bracket (][number 20][bracket )] [keyword begin]",
+ " [keyword fork]",
+ " [def `uvm_create_on][bracket (][variable t],[variable p_seq][bracket )]",
+ " [keyword join_none]",
+ " [keyword end]",
+ " [keyword wait] [keyword fork];",
+ " [keyword disable] [keyword fork];",
+ "[keyword endtask] : [variable body]",
+ ""
+ );
+
+ MT("indent_typedef_class",
+ /**
+ * typedef class asdf;
+ * typedef p p_t[];
+ * typedef enum {
+ * ASDF
+ * } t;
+ */
+ "[keyword typedef] [keyword class] [variable asdf];",
+ "[keyword typedef] [variable p] [variable p_t][bracket [[]]];",
+ "[keyword typedef] [keyword enum] [bracket {]",
+ " [variable ASDF]",
+ "[bracket }] [variable t];",
+ ""
+ );
+
+ MT("indent_case_with_macro",
+ /**
+ * // It should be assumed that Macros can have ';' inside, or 'begin'/'end' blocks.
+ * // As such, 'case' statement should indent correctly with macros inside.
+ * case(foo)
+ * ASDF : this.foo = seqNum;
+ * ABCD : `update(f)
+ * EFGH : `update(g)
+ * endcase
+ */
+ "[keyword case][bracket (][variable foo][bracket )]",
+ " [variable ASDF] : [keyword this].[variable foo] [meta =] [variable seqNum];",
+ " [variable ABCD] : [def `update][bracket (][variable f][bracket )]",
+ " [variable EFGH] : [def `update][bracket (][variable g][bracket )]",
+ "[keyword endcase]",
+ ""
+ );
+
+ MT("indent_extern_function",
+ /**
+ * extern virtual function void do(ref packet trans);
+ * extern virtual function void do2(ref packet trans);
+ */
+ "[keyword extern] [keyword virtual] [keyword function] [keyword void] [variable do1][bracket (][keyword ref] [variable packet] [variable trans][bracket )];",
+ "[keyword extern] [keyword virtual] [keyword function] [keyword void] [variable do2][bracket (][keyword ref] [variable packet] [variable trans][bracket )];",
+ ""
+ );
+
+ MT("indent_assignment",
+ /**
+ * for (int i=1;i < fun;i++) begin
+ * foo = 2 << asdf || 11'h35 >> abcd
+ * && 8'h6 | 1'b1;
+ * end
+ */
+ "[keyword for] [bracket (][keyword int] [variable i][meta =][number 1];[variable i] [meta <] [variable fun];[variable i][meta ++][bracket )] [keyword begin]",
+ " [variable foo] [meta =] [number 2] [meta <<] [variable asdf] [meta ||] [number 11'h35] [meta >>] [variable abcd]",
+ " [meta &&] [number 8'h6] [meta |] [number 1'b1];",
+ "[keyword end]",
+ ""
+ );
+
+ MT("indent_foreach_constraint",
+ /**
+ * `uvm_rand_send_with(wrTlp, {
+ * length ==1;
+ * foreach (Data[i]) {
+ * payload[i] == Data[i];
+ * }
+ * })
+ */
+ "[def `uvm_rand_send_with][bracket (][variable wrTlp], [bracket {]",
+ " [variable length] [meta ==][number 1];",
+ " [keyword foreach] [bracket (][variable Data][bracket [[][variable i][bracket ]])] [bracket {]",
+ " [variable payload][bracket [[][variable i][bracket ]]] [meta ==] [variable Data][bracket [[][variable i][bracket ]]];",
+ " [bracket }]",
+ "[bracket })]",
+ ""
+ );
+
+ MT("indent_compiler_directives",
+ /**
+ * `ifdef DUT
+ * `else
+ * `ifndef FOO
+ * `define FOO
+ * `endif
+ * `endif
+ * `timescale 1ns/1ns
+ */
+ "[def `ifdef] [variable DUT]",
+ "[def `else]",
+ " [def `ifndef] [variable FOO]",
+ " [def `define] [variable FOO]",
+ " [def `endif]",
+ "[def `endif]",
+ "[def `timescale] [number 1][variable ns][meta /][number 1][variable ns]",
+ ""
+ );
+
})();
diff --git a/help3/xhpeditor/cm/mode/verilog/verilog.js b/help3/xhpeditor/cm/mode/verilog/verilog.js
index 2b685065..6c799f29 100644
--- a/help3/xhpeditor/cm/mode/verilog/verilog.js
+++ b/help3/xhpeditor/cm/mode/verilog/verilog.js
@@ -16,6 +16,12 @@ CodeMirror.defineMode("verilog", function(config, parserConfig) {
var indentUnit = config.indentUnit,
statementIndentUnit = parserConfig.statementIndentUnit || indentUnit,
dontAlignCalls = parserConfig.dontAlignCalls,
+ // compilerDirectivesUseRegularIndentation - If set, Compiler directive
+ // indentation follows the same rules as everything else. Otherwise if
+ // false, compiler directives will track their own indentation.
+ // For example, `ifdef nested inside another `ifndef will be indented,
+ // but a `ifdef inside a function block may not be indented.
+ compilerDirectivesUseRegularIndentation = parserConfig.compilerDirectivesUseRegularIndentation,
noIndentKeywords = parserConfig.noIndentKeywords || [],
multiLineStrings = parserConfig.multiLineStrings,
hooks = parserConfig.hooks || {};
@@ -62,7 +68,7 @@ CodeMirror.defineMode("verilog", function(config, parserConfig) {
binary_module_path_operator ::=
== | != | && | || | & | | | ^ | ^~ | ~^
*/
- var isOperatorChar = /[\+\-\*\/!~&|^%=?:]/;
+ var isOperatorChar = /[\+\-\*\/!~&|^%=?:<>]/;
var isBracketChar = /[\[\]{}()]/;
var unsignedNumber = /\d[0-9_]*/;
@@ -72,8 +78,13 @@ CodeMirror.defineMode("verilog", function(config, parserConfig) {
var hexLiteral = /\d*\s*'s?h\s*[0-9a-fxz?][0-9a-fxz?_]*/i;
var realLiteral = /(\d[\d_]*(\.\d[\d_]*)?E-?[\d_]+)|(\d[\d_]*\.\d[\d_]*)/i;
- var closingBracketOrWord = /^((\w+)|[)}\]])/;
+ var closingBracketOrWord = /^((`?\w+)|[)}\]])/;
var closingBracket = /[)}\]]/;
+ var compilerDirectiveRegex = new RegExp(
+ "^(`(?:ifdef|ifndef|elsif|else|endif|undef|undefineall|define|include|begin_keywords|celldefine|default|" +
+ "nettype|end_keywords|endcelldefine|line|nounconnected_drive|pragma|resetall|timescale|unconnected_drive))\\b");
+ var compilerDirectiveBeginRegex = /^(`(?:ifdef|ifndef|elsif|else))\b/;
+ var compilerDirectiveEndRegex = /^(`(?:elsif|else|endif))\b/;
var curPunc;
var curKeyword;
@@ -96,6 +107,7 @@ CodeMirror.defineMode("verilog", function(config, parserConfig) {
openClose["do" ] = "while";
openClose["fork" ] = "join;join_any;join_none";
openClose["covergroup"] = "endgroup";
+ openClose["macro_begin"] = "macro_end";
for (var i in noIndentKeywords) {
var keyword = noIndentKeywords[i];
@@ -105,7 +117,7 @@ CodeMirror.defineMode("verilog", function(config, parserConfig) {
}
// Keywords which open statements that are ended with a semi-colon
- var statementKeywords = words("always always_comb always_ff always_latch assert assign assume else export for foreach forever if import initial repeat while");
+ var statementKeywords = words("always always_comb always_ff always_latch assert assign assume else export for foreach forever if import initial repeat while extern typedef");
function tokenBase(stream, state) {
var ch = stream.peek(), style;
@@ -125,6 +137,23 @@ CodeMirror.defineMode("verilog", function(config, parserConfig) {
if (ch == '`') {
stream.next();
if (stream.eatWhile(/[\w\$_]/)) {
+ var cur = stream.current();
+ curKeyword = cur;
+ // Macros that end in _begin, are start of block and end with _end
+ if (cur.startsWith("`uvm_") && cur.endsWith("_begin")) {
+ var keywordClose = curKeyword.substr(0,curKeyword.length - 5) + "end";
+ openClose[cur] = keywordClose;
+ curPunc = "newblock";
+ } else {
+ stream.eatSpace();
+ if (stream.peek() == '(') {
+ // Check if this is a block
+ curPunc = "newmacro";
+ }
+ var withSpace = stream.current();
+ // Move the stream back before the spaces
+ stream.backUp(withSpace.length - cur.length);
+ }
return "def";
} else {
return null;
@@ -145,6 +174,12 @@ CodeMirror.defineMode("verilog", function(config, parserConfig) {
stream.eatWhile(/[\d_.]/);
return "def";
}
+ // Event
+ if (ch == '@') {
+ stream.next();
+ stream.eatWhile(/[@]/);
+ return "def";
+ }
// Strings
if (ch == '"') {
stream.next();
@@ -178,6 +213,7 @@ CodeMirror.defineMode("verilog", function(config, parserConfig) {
// Operators
if (stream.eatWhile(isOperatorChar)) {
+ curPunc = stream.current();
return "meta";
}
@@ -187,6 +223,15 @@ CodeMirror.defineMode("verilog", function(config, parserConfig) {
if (keywords[cur]) {
if (openClose[cur]) {
curPunc = "newblock";
+ if (cur === "fork") {
+ // Fork can be a statement instead of block in cases of:
+ // "disable fork;" and "wait fork;" (trailing semicolon)
+ stream.eatSpace()
+ if (stream.peek() == ';') {
+ curPunc = "newstatement";
+ }
+ stream.backUp(stream.current().length - cur.length);
+ }
}
if (statementKeywords[cur]) {
curPunc = "newstatement";
@@ -226,16 +271,17 @@ CodeMirror.defineMode("verilog", function(config, parserConfig) {
return "comment";
}
- function Context(indented, column, type, align, prev) {
+ function Context(indented, column, type, scopekind, align, prev) {
this.indented = indented;
this.column = column;
this.type = type;
+ this.scopekind = scopekind;
this.align = align;
this.prev = prev;
}
- function pushContext(state, col, type) {
+ function pushContext(state, col, type, scopekind) {
var indent = state.indented;
- var c = new Context(indent, col, type, null, state.context);
+ var c = new Context(indent, col, type, scopekind ? scopekind : "", null, state.context);
return state.context = c;
}
function popContext(state) {
@@ -261,6 +307,16 @@ CodeMirror.defineMode("verilog", function(config, parserConfig) {
}
}
+ function isInsideScopeKind(ctx, scopekind) {
+ if (ctx == null) {
+ return false;
+ }
+ if (ctx.scopekind === scopekind) {
+ return true;
+ }
+ return isInsideScopeKind(ctx.prev, scopekind);
+ }
+
function buildElectricInputRegEx() {
// Reindentation should occur on any bracket char: {}()[]
// or on a match of any of the block closing keywords, at
@@ -287,8 +343,9 @@ CodeMirror.defineMode("verilog", function(config, parserConfig) {
startState: function(basecolumn) {
var state = {
tokenize: null,
- context: new Context((basecolumn || 0) - indentUnit, 0, "top", false),
+ context: new Context((basecolumn || 0) - indentUnit, 0, "top", "top", false),
indented: 0,
+ compilerDirectiveIndented: 0,
startOfLine: true
};
if (hooks.startState) hooks.startState(state);
@@ -313,15 +370,42 @@ CodeMirror.defineMode("verilog", function(config, parserConfig) {
curPunc = null;
curKeyword = null;
var style = (state.tokenize || tokenBase)(stream, state);
- if (style == "comment" || style == "meta" || style == "variable") return style;
+ if (style == "comment" || style == "meta" || style == "variable") {
+ if (((curPunc === "=") || (curPunc === "<=")) && !isInsideScopeKind(ctx, "assignment")) {
+ // '<=' could be nonblocking assignment or lessthan-equals (which shouldn't cause indent)
+ // Search through the context to see if we are already in an assignment.
+ // '=' could be inside port declaration with comma or ')' afterward, or inside for(;;) block.
+ pushContext(state, stream.column() + curPunc.length, "assignment", "assignment");
+ if (ctx.align == null) ctx.align = true;
+ }
+ return style;
+ }
if (ctx.align == null) ctx.align = true;
- if (curPunc == ctx.type) {
- popContext(state);
- } else if ((curPunc == ";" && ctx.type == "statement") ||
+ var isClosingAssignment = ctx.type == "assignment" &&
+ closingBracket.test(curPunc) && ctx.prev && ctx.prev.type === curPunc;
+ if (curPunc == ctx.type || isClosingAssignment) {
+ if (isClosingAssignment) {
+ ctx = popContext(state);
+ }
+ ctx = popContext(state);
+ if (curPunc == ")") {
+ // Handle closing macros, assuming they could have a semicolon or begin/end block inside.
+ if (ctx && (ctx.type === "macro")) {
+ ctx = popContext(state);
+ while (ctx && (ctx.type == "statement" || ctx.type == "assignment")) ctx = popContext(state);
+ }
+ } else if (curPunc == "}") {
+ // Handle closing statements like constraint block: "foreach () {}" which
+ // do not have semicolon at end.
+ if (ctx && (ctx.type === "statement")) {
+ while (ctx && (ctx.type == "statement")) ctx = popContext(state);
+ }
+ }
+ } else if (((curPunc == ";" || curPunc == ",") && (ctx.type == "statement" || ctx.type == "assignment")) ||
(ctx.type && isClosing(curKeyword, ctx.type))) {
ctx = popContext(state);
- while (ctx && ctx.type == "statement") ctx = popContext(state);
+ while (ctx && (ctx.type == "statement" || ctx.type == "assignment")) ctx = popContext(state);
} else if (curPunc == "{") {
pushContext(state, stream.column(), "}");
} else if (curPunc == "[") {
@@ -329,9 +413,9 @@ CodeMirror.defineMode("verilog", function(config, parserConfig) {
} else if (curPunc == "(") {
pushContext(state, stream.column(), ")");
} else if (ctx && ctx.type == "endcase" && curPunc == ":") {
- pushContext(state, stream.column(), "statement");
+ pushContext(state, stream.column(), "statement", "case");
} else if (curPunc == "newstatement") {
- pushContext(state, stream.column(), "statement");
+ pushContext(state, stream.column(), "statement", curKeyword);
} else if (curPunc == "newblock") {
if (curKeyword == "function" && ctx && (ctx.type == "statement" || ctx.type == "endgroup")) {
// The 'function' keyword can appear in some other contexts where it actually does not
@@ -339,9 +423,23 @@ CodeMirror.defineMode("verilog", function(config, parserConfig) {
// Do nothing in this case
} else if (curKeyword == "task" && ctx && ctx.type == "statement") {
// Same thing for task
+ } else if (curKeyword == "class" && ctx && ctx.type == "statement") {
+ // Same thing for class (e.g. typedef)
} else {
var close = openClose[curKeyword];
- pushContext(state, stream.column(), close);
+ pushContext(state, stream.column(), close, curKeyword);
+ }
+ } else if (curPunc == "newmacro" || (curKeyword && curKeyword.match(compilerDirectiveRegex))) {
+ if (curPunc == "newmacro") {
+ // Macros (especially if they have parenthesis) potentially have a semicolon
+ // or complete statement/block inside, and should be treated as such.
+ pushContext(state, stream.column(), "macro", "macro");
+ }
+ if (curKeyword.match(compilerDirectiveEndRegex)) {
+ state.compilerDirectiveIndented -= statementIndentUnit;
+ }
+ if (curKeyword.match(compilerDirectiveBeginRegex)) {
+ state.compilerDirectiveIndented += statementIndentUnit;
}
}
@@ -361,15 +459,23 @@ CodeMirror.defineMode("verilog", function(config, parserConfig) {
var possibleClosing = textAfter.match(closingBracketOrWord);
if (possibleClosing)
closing = isClosing(possibleClosing[0], ctx.type);
+ if (!compilerDirectivesUseRegularIndentation && textAfter.match(compilerDirectiveRegex)) {
+ if (textAfter.match(compilerDirectiveEndRegex)) {
+ return state.compilerDirectiveIndented - statementIndentUnit;
+ }
+ return state.compilerDirectiveIndented;
+ }
if (ctx.type == "statement") return ctx.indented + (firstChar == "{" ? 0 : statementIndentUnit);
- else if (closingBracket.test(ctx.type) && ctx.align && !dontAlignCalls) return ctx.column + (closing ? 0 : 1);
+ else if ((closingBracket.test(ctx.type) || ctx.type == "assignment")
+ && ctx.align && !dontAlignCalls) return ctx.column + (closing ? 0 : 1);
else if (ctx.type == ")" && !closing) return ctx.indented + statementIndentUnit;
else return ctx.indented + (closing ? 0 : indentUnit);
},
blockCommentStart: "/*",
blockCommentEnd: "*/",
- lineComment: "//"
+ lineComment: "//",
+ fold: "indent"
};
});
@@ -436,7 +542,7 @@ CodeMirror.defineMode("verilog", function(config, parserConfig) {
};
var tlvIndentUnit = 3;
var tlvTrackStatements = false;
- var tlvIdentMatch = /^([~!@#\$%\^&\*-\+=\?\/\\\|'"<>]+)([\d\w_]*)/; // Matches an identifiere.
+ var tlvIdentMatch = /^([~!@#\$%\^&\*-\+=\?\/\\\|'"<>]+)([\d\w_]*)/; // Matches an identifier.
// Note that ':' is excluded, because of it's use in [:].
var tlvFirstLevelIndentMatch = /^[! ] /;
var tlvLineIndentationMatch = /^[! ] */;
@@ -613,7 +719,7 @@ CodeMirror.defineMode("verilog", function(config, parserConfig) {
} else {
// Just swallow one character and try again.
// This enables subsequent identifier match with preceding symbol character, which
- // is legal within a statement. (Eg, !$reset). It also enables detection of
+ // is legal within a statement. (E.g., !$reset). It also enables detection of
// comment start with preceding symbols.
stream.backUp(stream.current().length - 1);
style = "tlv-default";
diff --git a/help3/xhpeditor/cm/mode/vue/index.html b/help3/xhpeditor/cm/mode/vue/index.html
index df519a5c..6ea54b75 100644
--- a/help3/xhpeditor/cm/mode/vue/index.html
+++ b/help3/xhpeditor/cm/mode/vue/index.html
@@ -38,7 +38,7 @@
<h2>Vue.js mode</h2>
<form><textarea id="code" name="code">
<template>
- <div class="sass">Im am a {{mustache-like}} template</div>
+ <div class="sass">I'm a {{mustache-like}} template</div>
</template>
<script lang="coffee">
diff --git a/help3/xhpeditor/cm/mode/wast/index.html b/help3/xhpeditor/cm/mode/wast/index.html
new file mode 100644
index 00000000..e589d90e
--- /dev/null
+++ b/help3/xhpeditor/cm/mode/wast/index.html
@@ -0,0 +1,73 @@
+<!DOCTYPE html>
+
+<title>CodeMirror: WebAssembly mode</title>
+<meta charset="utf-8" />
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="../../addon/mode/simple.js"></script>
+<script src="wast.js"></script>
+<style>
+ .CodeMirror {
+ border-top: 1px solid black;
+ border-bottom: 1px solid black;
+ }
+</style>
+<div id=nav>
+ <a href="https://codemirror.net">
+ <h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt="">
+ </a>
+
+ <ul>
+ <li><a href="../../index.html">Home</a>
+ <li><a href="../../doc/manual.html">Manual</a>
+ <li><a href="https://github.com/codemirror/codemirror">Code</a>
+ </ul>
+ <ul>
+ <li><a href="../index.html">Language modes</a>
+ <li><a class=active href="#">WebAssembly</a>
+ </ul>
+</div>
+
+<article>
+ <h2>WebAssembly mode</h2>
+
+
+ <div><textarea id="code" name="code">
+/* Example WebAssembly */
+(module $foo
+ (export "fac" (func $fac))
+ (export "plus" (func $plus))
+
+ (func $fac (type $t0) (param $p0 i64) (result i64)
+ (if $I0 (result i64)
+ (i64.lt_s
+ (local.get $p0)
+ (i64.const 1))
+ (then
+ (i64.const 1))
+ (else
+ (i64.mul
+ (local.get $p0)
+ (call $fac
+ (i64.sub
+ (local.get $p0)
+ (i64.const 1)))))))
+
+ (func $plus (param $x i32) (param $y i32) (result i32)
+ (i32.add
+ (local.get $x)
+ (local.get $y))))</textarea></div>
+
+ <script>
+ var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
+ lineNumbers: true,
+ lineWrapping: true,
+ indentUnit: 4,
+ mode: "wast"
+ });
+ </script>
+
+ <p><strong>MIME types defined:</strong> <code>text/webassembly</code>.</p>
+</article>
diff --git a/help3/xhpeditor/cm/mode/wast/test.js b/help3/xhpeditor/cm/mode/wast/test.js
new file mode 100644
index 00000000..0ebb388c
--- /dev/null
+++ b/help3/xhpeditor/cm/mode/wast/test.js
@@ -0,0 +1,424 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: https://codemirror.net/LICENSE
+
+(function() {
+ var mode = CodeMirror.getMode({indentUnit: 4}, "wast");
+ function MT(name) {test.mode(name, mode, Array.prototype.slice.call(arguments, 1));}
+
+ MT('number-test',
+ '[number 0]',
+ '[number 123]',
+ '[number nan]',
+ '[number inf]',
+ '[number infinity]',
+ '[number 0.1]',
+ '[number 123.0]',
+ '[number 12E+99]');
+
+ MT('string-literals-test',
+ '[string "foo"]',
+ '[string "\\"foo\\""]',
+ '[string "foo #\\"# bar"]');
+
+ MT('atom-test',
+ '[atom funcref]',
+ '[atom externref]',
+ '[atom i32]',
+ '[atom i64]',
+ '[atom f32]',
+ '[atom f64]');
+
+ MT('keyword-test',
+ '[keyword br]',
+ '[keyword if]',
+ '[keyword loop]',
+ '[keyword i32.add]',
+ '[keyword local.get]');
+
+ MT('control-instructions',
+ '[keyword unreachable]',
+ '[keyword nop]',
+ '[keyword br] [variable-2 $label0]',
+ '[keyword br_if] [variable-2 $label0]',
+ '[keyword br_table] [variable-2 $label0] [variable-2 $label1] [variable-2 $label3]',
+ '[keyword return]',
+ '[keyword call] [variable-2 $func0]',
+ '[keyword call_indirect] [variable-2 $table] ([keyword param] [atom f32] [atom f64]) ([keyword result] [atom i32] [atom i64])',
+ '[keyword return_call] [variable-2 $func0]',
+ '[keyword return_call_indirect] ([keyword param] [atom f32] [atom f64]) ([keyword result] [atom i32] [atom i64])',
+ '[keyword select] ([keyword local.get] [number 1]) ([keyword local.get] [number 2]) ([keyword local.get] [number 3])',
+ '[keyword try] ([keyword result] [atom i32])',
+ '[keyword throw] [number 0]',
+ '[keyword rethrow] [number 0]',
+ '[keyword catch] [number 0]',
+ '[keyword catch_all]',
+ '[keyword delegate] [number 0]',
+ '[keyword unwind]');
+
+
+ MT('memory-instructions',
+ '[keyword i32.load] [keyword offset]=[number 4] [keyword align]=[number 4]',
+ '[keyword i32.load8_s] [keyword offset]=[number 4] [keyword align]=[number 4]',
+ '[keyword i32.load8_u] [keyword offset]=[number 4] [keyword align]=[number 4]',
+ '[keyword i32.load16_s] [keyword offset]=[number 4] [keyword align]=[number 4]',
+ '[keyword i32.load16_u] [keyword offset]=[number 4] [keyword align]=[number 4]',
+ '[keyword i32.store] [keyword offset]=[number 4] [keyword align]=[number 4]',
+ '[keyword i32.store8] [keyword offset]=[number 4] [keyword align]=[number 4]',
+ '[keyword i32.store16] [keyword offset]=[number 4] [keyword align]=[number 4]',
+ '[keyword i64.store] [keyword offset]=[number 4] [keyword align]=[number 4]',
+ '[keyword i64.load] [keyword offset]=[number 4] [keyword align]=[number 4]',
+ '[keyword i64.load8_s] [keyword offset]=[number 4] [keyword align]=[number 4]',
+ '[keyword i64.load8_u] [keyword offset]=[number 4] [keyword align]=[number 4]',
+ '[keyword i64.load16_s] [keyword offset]=[number 4] [keyword align]=[number 4]',
+ '[keyword i64.load16_u] [keyword offset]=[number 4] [keyword align]=[number 4]',
+ '[keyword i64.load32_s] [keyword offset]=[number 4] [keyword align]=[number 4]',
+ '[keyword i64.load32_u] [keyword offset]=[number 4] [keyword align]=[number 4]',
+ '[keyword i64.store8] [keyword offset]=[number 4] [keyword align]=[number 4]',
+ '[keyword i64.store16] [keyword offset]=[number 4] [keyword align]=[number 4]',
+ '[keyword i64.store32] [keyword offset]=[number 4] [keyword align]=[number 4]',
+ '[keyword f32.load] [keyword offset]=[number 4] [keyword align]=[number 4]',
+ '[keyword f32.store] [keyword offset]=[number 4] [keyword align]=[number 4]',
+ '[keyword f64.load] [keyword offset]=[number 4] [keyword align]=[number 4]',
+ '[keyword f64.store] [keyword offset]=[number 4] [keyword align]=[number 4]');
+
+ MT('atomic-memory-instructions',
+ '[keyword memory.atomic.notify] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword memory.atomic.wait32] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword memory.atomic.wait64] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i32.atomic.load] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i32.atomic.load8_u] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i32.atomic.load16_u] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i32.atomic.store] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i32.atomic.store8] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i32.atomic.store16] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i64.atomic.load] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i64.atomic.load8_u] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i64.atomic.load16_u] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i64.atomic.load32_u] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i64.atomic.store] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i64.atomic.store8] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i64.atomic.store16] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i64.atomic.store32] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i32.atomic.rmw.add] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i32.atomic.rmw8.add_u] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i32.atomic.rmw16.add_u] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i64.atomic.rmw.add] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i64.atomic.rmw8.add_u] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i64.atomic.rmw16.add_u] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i64.atomic.rmw32.add_u] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i32.atomic.rmw.sub] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i32.atomic.rmw8.sub_u] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i32.atomic.rmw16.sub_u] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i64.atomic.rmw.sub] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i64.atomic.rmw8.sub_u] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i64.atomic.rmw16.sub_u] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i64.atomic.rmw32.sub_u] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i32.atomic.rmw.and] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i32.atomic.rmw8.and_u] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i32.atomic.rmw16.and_u] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i64.atomic.rmw.and] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i64.atomic.rmw8.and_u] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i64.atomic.rmw16.and_u] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i64.atomic.rmw32.and_u] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i32.atomic.rmw.or] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i32.atomic.rmw8.or_u] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i32.atomic.rmw16.or_u] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i64.atomic.rmw.or] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i64.atomic.rmw8.or_u] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i64.atomic.rmw16.or_u] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i64.atomic.rmw32.or_u] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i32.atomic.rmw.xor] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i32.atomic.rmw8.xor_u] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i32.atomic.rmw16.xor_u] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i64.atomic.rmw.xor] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i64.atomic.rmw8.xor_u] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i64.atomic.rmw16.xor_u] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i64.atomic.rmw32.xor_u] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i32.atomic.rmw.xchg] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i32.atomic.rmw8.xchg_u] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i32.atomic.rmw16.xchg_u] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i64.atomic.rmw.xchg] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i64.atomic.rmw8.xchg_u] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i64.atomic.rmw16.xchg_u] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i64.atomic.rmw32.xchg_u] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i32.atomic.rmw.cmpxchg] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i32.atomic.rmw8.cmpxchg_u] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i32.atomic.rmw16.cmpxchg_u] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i64.atomic.rmw.cmpxchg] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i64.atomic.rmw8.cmpxchg_u] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i64.atomic.rmw16.cmpxchg_u] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword i64.atomic.rmw32.cmpxchg_u] [keyword offset]=[number 32] [keyword align]=[number 4]');
+
+ MT('simd-instructions',
+ '[keyword v128.load] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword v128.load8x8_s] [keyword offset]=[number 64] [keyword align]=[number 0]',
+ '[keyword v128.load8x8_u] [keyword offset]=[number 64] [keyword align]=[number 0]',
+ '[keyword v128.load16x4_s] [keyword offset]=[number 64] [keyword align]=[number 0]',
+ '[keyword v128.load16x4_u] [keyword offset]=[number 64] [keyword align]=[number 0]',
+ '[keyword v128.load32x2_s] [keyword offset]=[number 64] [keyword align]=[number 0]',
+ '[keyword v128.load32x2_u] [keyword offset]=[number 64] [keyword align]=[number 0]',
+ '[keyword v128.load8_splat] [keyword offset]=[number 64] [keyword align]=[number 0]',
+ '[keyword v128.load16_splat] [keyword offset]=[number 64] [keyword align]=[number 0]',
+ '[keyword v128.load32_splat] [keyword offset]=[number 64] [keyword align]=[number 0]',
+ '[keyword v128.load64_splat] [keyword offset]=[number 64] [keyword align]=[number 0]',
+ '[keyword v128.store] [keyword offset]=[number 32] [keyword align]=[number 4]',
+ '[keyword v128.const] [number 0] [number 1] [number 2] [number 3] [number 4] [number 5] [number 6] [number 7] [number 8] [number 9] [number 10] [number 11] [number 12] [number 13] [number 14] [number 15]',
+ '[keyword i8x16.shuffle] [number 0] [number 1] [number 2] [number 3] [number 4] [number 5] [number 6] [number 7] [number 8] [number 9] [number 10] [number 11] [number 12] [number 13] [number 14] [number 15]',
+ '[keyword i8x16.swizzle]',
+ '[keyword i8x16.splat]',
+ '[keyword i16x8.splat]',
+ '[keyword i32x4.splat]',
+ '[keyword i64x2.splat]',
+ '[keyword f32x4.splat]',
+ '[keyword f64x2.splat]',
+ '[keyword i8x16.extract_lane_s] [number 1]',
+ '[keyword i8x16.extract_lane_u] [number 1]',
+ '[keyword i8x16.replace_lane] [number 1]',
+ '[keyword i16x8.extract_lane_s] [number 1]',
+ '[keyword i16x8.extract_lane_u] [number 1]',
+ '[keyword i16x8.replace_lane] [number 1]',
+ '[keyword i32x4.extract_lane] [number 1]',
+ '[keyword i32x4.replace_lane] [number 1]',
+ '[keyword i64x2.extract_lane] [number 1]',
+ '[keyword i64x2.replace_lane] [number 1]',
+ '[keyword f32x4.extract_lane] [number 1]',
+ '[keyword f32x4.replace_lane] [number 1]',
+ '[keyword f64x2.extract_lane] [number 1]',
+ '[keyword f64x2.replace_lane] [number 1]',
+ '[keyword i8x16.eq]',
+ '[keyword i8x16.ne]',
+ '[keyword i8x16.lt_s]',
+ '[keyword i8x16.lt_u]',
+ '[keyword i8x16.gt_s]',
+ '[keyword i8x16.gt_u]',
+ '[keyword i8x16.le_s]',
+ '[keyword i8x16.le_u]',
+ '[keyword i8x16.ge_s]',
+ '[keyword i8x16.ge_u]',
+ '[keyword i16x8.eq]',
+ '[keyword i16x8.ne]',
+ '[keyword i16x8.lt_s]',
+ '[keyword i16x8.lt_u]',
+ '[keyword i16x8.gt_s]',
+ '[keyword i16x8.gt_u]',
+ '[keyword i16x8.le_s]',
+ '[keyword i16x8.le_u]',
+ '[keyword i16x8.ge_s]',
+ '[keyword i16x8.ge_u]',
+ '[keyword i32x4.eq]',
+ '[keyword i32x4.ne]',
+ '[keyword i32x4.lt_s]',
+ '[keyword i32x4.lt_u]',
+ '[keyword i32x4.gt_s]',
+ '[keyword i32x4.gt_u]',
+ '[keyword i32x4.le_s]',
+ '[keyword i32x4.le_u]',
+ '[keyword i32x4.ge_s]',
+ '[keyword i32x4.ge_u]',
+ '[keyword f32x4.eq]',
+ '[keyword f32x4.ne]',
+ '[keyword f32x4.lt]',
+ '[keyword f32x4.gt]',
+ '[keyword f32x4.le]',
+ '[keyword f32x4.ge]',
+ '[keyword f64x2.eq]',
+ '[keyword f64x2.ne]',
+ '[keyword f64x2.lt]',
+ '[keyword f64x2.gt]',
+ '[keyword f64x2.le]',
+ '[keyword f64x2.ge]',
+ '[keyword v128.not]',
+ '[keyword v128.and]',
+ '[keyword v128.andnot]',
+ '[keyword v128.or]',
+ '[keyword v128.xor]',
+ '[keyword v128.bitselect]',
+ '[keyword v128.any_true]',
+ '[keyword v128.load8_lane] [keyword offset]=[number 64] [keyword align]=[number 0] [number 1]',
+ '[keyword v128.load16_lane] [keyword offset]=[number 64] [keyword align]=[number 0] [number 1]',
+ '[keyword v128.load32_lane] [keyword offset]=[number 64] [keyword align]=[number 0] [number 1]',
+ '[keyword v128.load64_lane] [keyword offset]=[number 64] [keyword align]=[number 0] [number 1]',
+ '[keyword v128.store8_lane] [keyword offset]=[number 64] [keyword align]=[number 0] [number 1]',
+ '[keyword v128.store16_lane] [keyword offset]=[number 64] [keyword align]=[number 0] [number 1]',
+ '[keyword v128.store32_lane] [keyword offset]=[number 64] [keyword align]=[number 0] [number 1]',
+ '[keyword v128.store64_lane] [keyword offset]=[number 64] [keyword align]=[number 0] [number 1]',
+ '[keyword v128.load32_zero] [keyword offset]=[number 64] [keyword align]=[number 0]',
+ '[keyword v128.load64_zero] [keyword offset]=[number 64] [keyword align]=[number 0]',
+ '[keyword f32x4.demote_f64x2_zero]',
+ '[keyword f64x2.promote_low_f32x4]',
+ '[keyword i8x16.abs]',
+ '[keyword i8x16.neg]',
+ '[keyword i8x16.popcnt]',
+ '[keyword i8x16.all_true]',
+ '[keyword i8x16.bitmask]',
+ '[keyword i8x16.narrow_i16x8_s]',
+ '[keyword i8x16.narrow_i16x8_u]',
+ '[keyword f32x4.ceil]',
+ '[keyword f32x4.floor]',
+ '[keyword f32x4.trunc]',
+ '[keyword f32x4.nearest]',
+ '[keyword i8x16.shl]',
+ '[keyword i8x16.shr_s]',
+ '[keyword i8x16.shr_u]',
+ '[keyword i8x16.add]',
+ '[keyword i8x16.add_sat_s]',
+ '[keyword i8x16.add_sat_u]',
+ '[keyword i8x16.sub]',
+ '[keyword i8x16.sub_sat_s]',
+ '[keyword i8x16.sub_sat_u]',
+ '[keyword f64x2.ceil]',
+ '[keyword f64x2.floor]',
+ '[keyword i8x16.min_s]',
+ '[keyword i8x16.min_u]',
+ '[keyword i8x16.max_s]',
+ '[keyword i8x16.max_u]',
+ '[keyword f64x2.trunc]',
+ '[keyword i8x16.avgr_u]',
+ '[keyword i16x8.extadd_pairwise_i8x16_s]',
+ '[keyword i16x8.extadd_pairwise_i8x16_u]',
+ '[keyword i32x4.extadd_pairwise_i16x8_s]',
+ '[keyword i32x4.extadd_pairwise_i16x8_u]',
+ '[keyword i16x8.abs]',
+ '[keyword i16x8.neg]',
+ '[keyword i16x8.q15mulr_sat_s]',
+ '[keyword i16x8.all_true]',
+ '[keyword i16x8.bitmask]',
+ '[keyword i16x8.narrow_i32x4_s]',
+ '[keyword i16x8.narrow_i32x4_u]',
+ '[keyword i16x8.extend_low_i8x16_s]',
+ '[keyword i16x8.extend_high_i8x16_s]',
+ '[keyword i16x8.extend_low_i8x16_u]',
+ '[keyword i16x8.extend_high_i8x16_u]',
+ '[keyword i16x8.shl]',
+ '[keyword i16x8.shr_s]',
+ '[keyword i16x8.shr_u]',
+ '[keyword i16x8.add]',
+ '[keyword i16x8.add_sat_s]',
+ '[keyword i16x8.add_sat_u]',
+ '[keyword i16x8.sub]',
+ '[keyword i16x8.sub_sat_s]',
+ '[keyword i16x8.sub_sat_u]',
+ '[keyword f64x2.nearest]',
+ '[keyword i16x8.mul]',
+ '[keyword i16x8.min_s]',
+ '[keyword i16x8.min_u]',
+ '[keyword i16x8.max_s]',
+ '[keyword i16x8.max_u]',
+ '[keyword i16x8.avgr_u]',
+ '[keyword i16x8.extmul_low_i8x16_s]',
+ '[keyword i16x8.extmul_high_i8x16_s]',
+ '[keyword i16x8.extmul_low_i8x16_u]',
+ '[keyword i16x8.extmul_high_i8x16_u]',
+ '[keyword i32x4.abs]',
+ '[keyword i32x4.neg]',
+ '[keyword i32x4.all_true]',
+ '[keyword i32x4.bitmask]',
+ '[keyword i32x4.extend_low_i16x8_s]',
+ '[keyword i32x4.extend_high_i16x8_s]',
+ '[keyword i32x4.extend_low_i16x8_u]',
+ '[keyword i32x4.extend_high_i16x8_u]',
+ '[keyword i32x4.shl]',
+ '[keyword i32x4.shr_s]',
+ '[keyword i32x4.shr_u]',
+ '[keyword i32x4.add]',
+ '[keyword i32x4.sub]',
+ '[keyword i32x4.mul]',
+ '[keyword i32x4.min_s]',
+ '[keyword i32x4.min_u]',
+ '[keyword i32x4.max_s]',
+ '[keyword i32x4.max_u]',
+ '[keyword i32x4.dot_i16x8_s]',
+ '[keyword i32x4.extmul_low_i16x8_s]',
+ '[keyword i32x4.extmul_high_i16x8_s]',
+ '[keyword i32x4.extmul_low_i16x8_u]',
+ '[keyword i32x4.extmul_high_i16x8_u]',
+ '[keyword i64x2.abs]',
+ '[keyword i64x2.neg]',
+ '[keyword i64x2.all_true]',
+ '[keyword i64x2.bitmask]',
+ '[keyword i64x2.extend_low_i32x4_s]',
+ '[keyword i64x2.extend_high_i32x4_s]',
+ '[keyword i64x2.extend_low_i32x4_u]',
+ '[keyword i64x2.extend_high_i32x4_u]',
+ '[keyword i64x2.shl]',
+ '[keyword i64x2.shr_s]',
+ '[keyword i64x2.shr_u]',
+ '[keyword i64x2.add]',
+ '[keyword i64x2.sub]',
+ '[keyword i64x2.mul]',
+ '[keyword i64x2.eq]',
+ '[keyword i64x2.ne]',
+ '[keyword i64x2.lt_s]',
+ '[keyword i64x2.gt_s]',
+ '[keyword i64x2.le_s]',
+ '[keyword i64x2.ge_s]',
+ '[keyword i64x2.extmul_low_i32x4_s]',
+ '[keyword i64x2.extmul_high_i32x4_s]',
+ '[keyword i64x2.extmul_low_i32x4_u]',
+ '[keyword i64x2.extmul_high_i32x4_u]',
+ '[keyword f32x4.abs]',
+ '[keyword f32x4.neg]',
+ '[keyword f32x4.sqrt]',
+ '[keyword f32x4.add]',
+ '[keyword f32x4.sub]',
+ '[keyword f32x4.mul]',
+ '[keyword f32x4.div]',
+ '[keyword f32x4.min]',
+ '[keyword f32x4.max]',
+ '[keyword f64x2.abs]',
+ '[keyword f64x2.neg]',
+ '[keyword f64x2.sqrt]',
+ '[keyword f64x2.add]',
+ '[keyword f64x2.sub]',
+ '[keyword f64x2.mul]',
+ '[keyword f64x2.div]',
+ '[keyword f64x2.min]',
+ '[keyword f64x2.max]',
+ '[keyword i32x4.trunc_sat_f32x4_s]',
+ '[keyword i32x4.trunc_sat_f32x4_u]',
+ '[keyword f32x4.convert_i32x4_s]',
+ '[keyword f32x4.convert_i32x4_u]',
+ '[keyword i32x4.trunc_sat_f64x2_s_zero]',
+ '[keyword i32x4.trunc_sat_f64x2_u_zero]',
+ '[keyword f64x2.convert_low_i32x4_s]',
+ '[keyword f64x2.convert_low_i32x4_u]');
+
+ MT('reference-type-instructions',
+ '[keyword ref.null] [keyword extern]',
+ '[keyword ref.null] [keyword func]',
+ '[keyword ref.is_null] ([keyword ref.func] [variable-2 $f])',
+ '[keyword ref.func] [variable-2 $f]');
+
+ MT('table-instructions',
+ '[keyword table.get] [variable-2 $t] ([keyword i32.const] [number 5])',
+ '[keyword table.set] [variable-2 $t] ([keyword i32.const] [number 5]) ([keyword ref.func] [variable-2 $f])',
+ '[keyword table.size] [variable-2 $t]',
+ '[keyword table.grow] [variable-2 $t] ([keyword ref.null] [keyword extern]) ([keyword i32.const] [number 5])',
+ '[keyword table.fill] [variable-2 $t] ([keyword i32.const] [number 5]) ([keyword param] [variable-2 $r] [atom externref]) ([keyword i32.const] [number 5])',
+ '[keyword table.init] [variable-2 $t] [number 1] ([keyword i32.const] [number 5]) ([keyword i32.const] [number 10]) ([keyword i32.const] [number 15])',
+ '[keyword table.copy] [variable-2 $t] [variable-2 $t2] ([keyword i32.const] [number 5]) ([keyword i32.const] [number 10]) ([keyword i32.const] [number 15])'
+ );
+ MT('gc-proposal',
+ '[keyword call_ref] [keyword return_call_ref]',
+ '[keyword ref.as_non_null] [keyword br_on_null] [keyword ref.eq]');
+ MT('gc-proposal-structs',
+ '[keyword struct.new_with_rtt] [keyword struct.new_default_with_rtt]',
+ '[keyword struct.get] [keyword struct.get_s] [keyword struct.get_u]',
+ '[keyword struct.set]');
+ MT('gc-proposal-arrays',
+ '[keyword array.new_with_rtt] [keyword array.new_default_with_rtt]',
+ '[keyword array.get] [keyword array.get_s] [keyword array.get_u]',
+ '[keyword array.len] [keyword array.set]');
+ MT('gc-proposal-i31',
+ '[keyword i31.new] [keyword i31.get_s] [keyword i31.get_u]');
+ MT('gc-proposal-rtt',
+ '[keyword rtt.canon] [keyword rtt.sub]');
+ MT('gc-proposal-typechecks',
+ '[keyword ref.test] [keyword ref.cast] [keyword br_on_cast]',
+ '[keyword ref.is_func] [keyword ref.is_data] [keyword ref.is_i31]',
+ '[keyword ref.as_func] [keyword ref.as_data] [keyword ref.as_i31]',
+ '[keyword br_on_func] [keyword br_on_data] [keyword br_on_i31]');
+ MT('gc-proposal-types',
+ '[atom i8] [atom i16]',
+ '[atom anyref] [atom dataref] [atom eqref] [atom i31ref]');
+})();
diff --git a/help3/xhpeditor/cm/mode/wast/wast.js b/help3/xhpeditor/cm/mode/wast/wast.js
new file mode 100644
index 00000000..471ace5b
--- /dev/null
+++ b/help3/xhpeditor/cm/mode/wast/wast.js
@@ -0,0 +1,132 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: https://codemirror.net/LICENSE
+
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
+ mod(require("../../lib/codemirror"), require("../../addon/mode/simple"));
+ else if (typeof define == "function" && define.amd) // AMD
+ define(["../../lib/codemirror", "../../addon/mode/simple"], mod);
+ else // Plain browser env
+ mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+var kKeywords = [
+ "align",
+ "block",
+ "br(_if|_table|_on_(cast|data|func|i31|null))?",
+ "call(_indirect|_ref)?",
+ "current_memory",
+ "\\bdata\\b",
+ "catch(_all)?",
+ "delegate",
+ "drop",
+ "elem",
+ "else",
+ "end",
+ "export",
+ "\\bextern\\b",
+ "\\bfunc\\b",
+ "global(\\.(get|set))?",
+ "if",
+ "import",
+ "local(\\.(get|set|tee))?",
+ "loop",
+ "module",
+ "mut",
+ "nop",
+ "offset",
+ "param",
+ "result",
+ "rethrow",
+ "return(_call(_indirect|_ref)?)?",
+ "select",
+ "start",
+ "table(\\.(size|get|set|size|grow|fill|init|copy))?",
+ "then",
+ "throw",
+ "try",
+ "type",
+ "unreachable",
+ "unwind",
+
+ // Numeric opcodes.
+ "i(32|64)\\.(store(8|16)|(load(8|16)_[su]))",
+ "i64\\.(load32_[su]|store32)",
+ "[fi](32|64)\\.(const|load|store)",
+ "f(32|64)\\.(abs|add|ceil|copysign|div|eq|floor|[gl][et]|max|min|mul|nearest|neg?|sqrt|sub|trunc)",
+ "i(32|64)\\.(a[dn]d|c[lt]z|(div|rem)_[su]|eqz?|[gl][te]_[su]|mul|ne|popcnt|rot[lr]|sh(l|r_[su])|sub|x?or)",
+ "i64\\.extend_[su]_i32",
+ "i32\\.wrap_i64",
+ "i(32|64)\\.trunc_f(32|64)_[su]",
+ "f(32|64)\\.convert_i(32|64)_[su]",
+ "f64\\.promote_f32",
+ "f32\\.demote_f64",
+ "f32\\.reinterpret_i32",
+ "i32\\.reinterpret_f32",
+ "f64\\.reinterpret_i64",
+ "i64\\.reinterpret_f64",
+ // Atomics.
+ "memory(\\.((atomic\\.(notify|wait(32|64)))|grow|size))?",
+ "i64\.atomic\\.(load32_u|store32|rmw32\\.(a[dn]d|sub|x?or|(cmp)?xchg)_u)",
+ "i(32|64)\\.atomic\\.(load((8|16)_u)?|store(8|16)?|rmw(\\.(a[dn]d|sub|x?or|(cmp)?xchg)|(8|16)\\.(a[dn]d|sub|x?or|(cmp)?xchg)_u))",
+ // SIMD.
+ "v128\\.load(8x8|16x4|32x2)_[su]",
+ "v128\\.load(8|16|32|64)_splat",
+ "v128\\.(load|store)(8|16|32|64)_lane",
+ "v128\\.load(32|64)_zero",
+ "v128\.(load|store|const|not|andnot|and|or|xor|bitselect|any_true)",
+ "i(8x16|16x8)\\.(extract_lane_[su]|(add|sub)_sat_[su]|avgr_u)",
+ "i(8x16|16x8|32x4|64x2)\\.(neg|add|sub|abs|shl|shr_[su]|all_true|bitmask|eq|ne|[lg][te]_s)",
+ "(i(8x16|16x8|32x4|64x2)|f(32x4|64x2))\.(splat|replace_lane)",
+ "i(8x16|16x8|32x4)\\.(([lg][te]_u)|((min|max)_[su]))",
+ "f(32x4|64x2)\\.(neg|add|sub|abs|nearest|eq|ne|[lg][te]|sqrt|mul|div|min|max|ceil|floor|trunc)",
+ "[fi](32x4|64x2)\\.extract_lane",
+ "i8x16\\.(shuffle|swizzle|popcnt|narrow_i16x8_[su])",
+ "i16x8\\.(narrow_i32x4_[su]|mul|extadd_pairwise_i8x16_[su]|q15mulr_sat_s)",
+ "i16x8\\.(extend|extmul)_(low|high)_i8x16_[su]",
+ "i32x4\\.(mul|dot_i16x8_s|trunc_sat_f64x2_[su]_zero)",
+ "i32x4\\.((extend|extmul)_(low|high)_i16x8_|trunc_sat_f32x4_|extadd_pairwise_i16x8_)[su]",
+ "i64x2\\.(mul|(extend|extmul)_(low|high)_i32x4_[su])",
+ "f32x4\\.(convert_i32x4_[su]|demote_f64x2_zero)",
+ "f64x2\\.(promote_low_f32x4|convert_low_i32x4_[su])",
+ // Reference types, function references, and GC.
+ "\\bany\\b",
+ "array\\.len",
+ "(array|struct)(\\.(new_(default_)?with_rtt|get(_[su])?|set))?",
+ "\\beq\\b",
+ "field",
+ "i31\\.(new|get_[su])",
+ "\\bnull\\b",
+ "ref(\\.(([ai]s_(data|func|i31))|cast|eq|func|(is_|as_non_)?null|test))?",
+ "rtt(\\.(canon|sub))?",
+];
+
+CodeMirror.defineSimpleMode('wast', {
+ start: [
+ {regex: /[+\-]?(?:nan(?::0x[0-9a-fA-F]+)?|infinity|inf|0x[0-9a-fA-F]+\.?[0-9a-fA-F]*p[+\/-]?\d+|\d+(?:\.\d*)?[eE][+\-]?\d*|\d+\.\d*|0x[0-9a-fA-F]+|\d+)/, token: "number"},
+ {regex: new RegExp(kKeywords.join('|')), token: "keyword"},
+ {regex: /\b((any|data|eq|extern|i31|func)ref|[fi](32|64)|i(8|16))\b/, token: "atom"},
+ {regex: /\$([a-zA-Z0-9_`\+\-\*\/\\\^~=<>!\?@#$%&|:\.]+)/, token: "variable-2"},
+ {regex: /"(?:[^"\\\x00-\x1f\x7f]|\\[nt\\'"]|\\[0-9a-fA-F][0-9a-fA-F])*"/, token: "string"},
+ {regex: /\(;.*?/, token: "comment", next: "comment"},
+ {regex: /;;.*$/, token: "comment"},
+ {regex: /\(/, indent: true},
+ {regex: /\)/, dedent: true},
+ ],
+
+ comment: [
+ {regex: /.*?;\)/, token: "comment", next: "start"},
+ {regex: /.*/, token: "comment"},
+ ],
+
+ meta: {
+ dontIndentStates: ['comment'],
+ },
+});
+
+// https://github.com/WebAssembly/design/issues/981 mentions text/webassembly,
+// which seems like a reasonable choice, although it's not standard right now.
+CodeMirror.defineMIME("text/webassembly", "wast");
+
+});
diff --git a/help3/xhpeditor/cm/mode/xml/xml.js b/help3/xhpeditor/cm/mode/xml/xml.js
index 73c6e0e0..46806ac4 100644
--- a/help3/xhpeditor/cm/mode/xml/xml.js
+++ b/help3/xhpeditor/cm/mode/xml/xml.js
@@ -189,7 +189,7 @@ CodeMirror.defineMode("xml", function(editorConf, config_) {
function Context(state, tagName, startOfLine) {
this.prev = state.context;
- this.tagName = tagName;
+ this.tagName = tagName || "";
this.indent = state.indented;
this.startOfLine = startOfLine;
if (config.doNotIndent.hasOwnProperty(tagName) || (state.context && state.context.noIndent))
@@ -399,7 +399,7 @@ CodeMirror.defineMode("xml", function(editorConf, config_) {
xmlCurrentContext: function(state) {
var context = []
for (var cx = state.context; cx; cx = cx.prev)
- if (cx.tagName) context.push(cx.tagName)
+ context.push(cx.tagName)
return context.reverse()
}
};
diff --git a/help3/xhpeditor/cm/mode/xquery/index.html b/help3/xhpeditor/cm/mode/xquery/index.html
index 6555b7fe..bca4d06b 100644
--- a/help3/xhpeditor/cm/mode/xquery/index.html
+++ b/help3/xhpeditor/cm/mode/xquery/index.html
@@ -74,7 +74,7 @@ xquery version &quot;1.0-ml&quot;;
: you may not use this file except in compliance with the License.
: You may obtain a copy of the License at
:
- : https://www.apache.org/licenses/LICENSE-2.0
+ : http://www.apache.org/licenses/LICENSE-2.0
:
: Unless required by applicable law or agreed to in writing, software
: distributed under the License is distributed on an &quot;AS IS&quot; BASIS,
diff --git a/help3/xhpeditor/cm/mode/yaml-frontmatter/yaml-frontmatter.js b/help3/xhpeditor/cm/mode/yaml-frontmatter/yaml-frontmatter.js
index 87fdf80d..88c845e2 100644
--- a/help3/xhpeditor/cm/mode/yaml-frontmatter/yaml-frontmatter.js
+++ b/help3/xhpeditor/cm/mode/yaml-frontmatter/yaml-frontmatter.js
@@ -36,7 +36,7 @@
},
token: function (stream, state) {
if (state.state == START) {
- if (stream.match(/---/, false)) {
+ if (stream.match('---', false)) {
state.state = FRONTMATTER
return yamlMode.token(stream, state.inner)
} else {
@@ -59,6 +59,10 @@
innerMode: function (state) {
return {mode: curMode(state), state: state.inner}
},
+ indent: function(state, a, b) {
+ var mode = curMode(state)
+ return mode.indent ? mode.indent(state.inner, a, b) : CodeMirror.Pass
+ },
blankLine: function (state) {
var mode = curMode(state)
if (mode.blankLine) return mode.blankLine(state.inner)
diff --git a/help3/xhpeditor/cm/mode/yaml/yaml.js b/help3/xhpeditor/cm/mode/yaml/yaml.js
index a29d7ea4..d4649410 100644
--- a/help3/xhpeditor/cm/mode/yaml/yaml.js
+++ b/help3/xhpeditor/cm/mode/yaml/yaml.js
@@ -38,9 +38,9 @@ CodeMirror.defineMode("yaml", function() {
state.pair = false;
state.pairStart = false;
/* document start */
- if(stream.match(/---/)) { return "def"; }
+ if(stream.match('---')) { return "def"; }
/* document end */
- if (stream.match(/\.\.\./)) { return "def"; }
+ if (stream.match('...')) { return "def"; }
/* array list item */
if (stream.match(/\s*-\s+/)) { return 'meta'; }
}
@@ -57,12 +57,12 @@ CodeMirror.defineMode("yaml", function() {
return 'meta';
}
- /* list seperator */
+ /* list separator */
if (state.inlineList > 0 && !esc && ch == ',') {
stream.next();
return 'meta';
}
- /* pairs seperator */
+ /* pairs separator */
if (state.inlinePairs > 0 && !esc && ch == ',') {
state.keyCol = 0;
state.pair = false;
diff --git a/help3/xhpeditor/cm/package.json b/help3/xhpeditor/cm/package.json
index 29d0732b..250a75b3 100644
--- a/help3/xhpeditor/cm/package.json
+++ b/help3/xhpeditor/cm/package.json
@@ -1,6 +1,6 @@
{
"name": "codemirror",
- "version": "5.51.0",
+ "version": "5.61.1",
"main": "lib/codemirror.js",
"style": "lib/codemirror.css",
"author": {
@@ -21,11 +21,11 @@
"lint": "bin/lint"
},
"devDependencies": {
+ "@rollup/plugin-buble": "^0.21.3",
"blint": "^1.1.0",
"node-static": "0.7.11",
"puppeteer": "^1.20.0",
- "rollup": "^1.26.3",
- "rollup-plugin-buble": "^0.19.8"
+ "rollup": "^1.26.3"
},
"bugs": "http://github.com/codemirror/CodeMirror/issues",
"keywords": [
@@ -42,5 +42,6 @@
"directories": {},
"dependencies": {},
"devDependencies": {}
- }
+ },
+ "dependencies": {}
}
diff --git a/help3/xhpeditor/cm/rollup.config.js b/help3/xhpeditor/cm/rollup.config.js
index fbb43571..f50f62fa 100644
--- a/help3/xhpeditor/cm/rollup.config.js
+++ b/help3/xhpeditor/cm/rollup.config.js
@@ -1,9 +1,10 @@
-import buble from 'rollup-plugin-buble';
+import buble from '@rollup/plugin-buble';
-export default {
- input: "src/codemirror.js",
- output: {
- banner: `// CodeMirror, copyright (c) by Marijn Haverbeke and others
+export default [
+ {
+ input: "src/codemirror.js",
+ output: {
+ banner: `// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
// This is CodeMirror (https://codemirror.net), a code editor
@@ -12,9 +13,30 @@ export default {
// You can find some technical background for some of the code below
// at http://marijnhaverbeke.nl/blog/#cm-internals .
`,
- format: "umd",
- file: "lib/codemirror.js",
- name: "CodeMirror"
+ format: "umd",
+ file: "lib/codemirror.js",
+ name: "CodeMirror"
+ },
+ plugins: [ buble({namedFunctionExpressions: false}) ]
},
- plugins: [ buble({namedFunctionExpressions: false}) ]
-};
+ {
+ input: ["src/addon/runmode/runmode-standalone.js"],
+ output: {
+ format: "iife",
+ file: "addon/runmode/runmode-standalone.js",
+ name: "CodeMirror",
+ freeze: false, // IE8 doesn't support Object.freeze.
+ },
+ plugins: [ buble({namedFunctionExpressions: false}) ]
+ },
+ {
+ input: ["src/addon/runmode/runmode.node.js"],
+ output: {
+ format: "cjs",
+ file: "addon/runmode/runmode.node.js",
+ name: "CodeMirror",
+ freeze: false, // IE8 doesn't support Object.freeze.
+ },
+ plugins: [ buble({namedFunctionExpressions: false}) ]
+ },
+];
diff --git a/help3/xhpeditor/cm/src/addon/runmode/codemirror-standalone.js b/help3/xhpeditor/cm/src/addon/runmode/codemirror-standalone.js
new file mode 100644
index 00000000..f13f32b2
--- /dev/null
+++ b/help3/xhpeditor/cm/src/addon/runmode/codemirror-standalone.js
@@ -0,0 +1,24 @@
+import StringStream from "../../util/StringStream.js"
+import { countColumn } from "../../util/misc.js"
+import * as modeMethods from "../../modes.js"
+
+// declare global: globalThis, CodeMirror
+
+// Create a minimal CodeMirror needed to use runMode, and assign to root.
+var root = typeof globalThis !== 'undefined' ? globalThis : window
+root.CodeMirror = {}
+
+// Copy StringStream and mode methods into CodeMirror object.
+CodeMirror.StringStream = StringStream
+for (var exported in modeMethods) CodeMirror[exported] = modeMethods[exported]
+
+// Minimal default mode.
+CodeMirror.defineMode("null", () => ({token: stream => stream.skipToEnd()}))
+CodeMirror.defineMIME("text/plain", "null")
+
+CodeMirror.registerHelper = CodeMirror.registerGlobalHelper = Math.min
+CodeMirror.splitLines = function(string) { return string.split(/\r?\n|\r/) }
+CodeMirror.countColumn = countColumn
+
+CodeMirror.defaults = { indentUnit: 2 }
+export default CodeMirror
diff --git a/help3/xhpeditor/cm/src/addon/runmode/codemirror.node.js b/help3/xhpeditor/cm/src/addon/runmode/codemirror.node.js
new file mode 100644
index 00000000..58efc528
--- /dev/null
+++ b/help3/xhpeditor/cm/src/addon/runmode/codemirror.node.js
@@ -0,0 +1,21 @@
+import StringStream from "../../util/StringStream.js"
+import * as modeMethods from "../../modes.js"
+import {countColumn} from "../../util/misc.js"
+
+// Copy StringStream and mode methods into exports (CodeMirror) object.
+exports.StringStream = StringStream
+exports.countColumn = countColumn
+for (var exported in modeMethods) exports[exported] = modeMethods[exported]
+
+// Shim library CodeMirror with the minimal CodeMirror defined above.
+require.cache[require.resolve("../../lib/codemirror")] = require.cache[require.resolve("./runmode.node")]
+require.cache[require.resolve("../../addon/runmode/runmode")] = require.cache[require.resolve("./runmode.node")]
+
+// Minimal default mode.
+exports.defineMode("null", () => ({token: stream => stream.skipToEnd()}))
+exports.defineMIME("text/plain", "null")
+
+exports.registerHelper = exports.registerGlobalHelper = Math.min
+exports.splitLines = function(string) { return string.split(/\r?\n|\r/) }
+
+exports.defaults = { indentUnit: 2 }
diff --git a/help3/xhpeditor/cm/src/addon/runmode/runmode-standalone.js b/help3/xhpeditor/cm/src/addon/runmode/runmode-standalone.js
new file mode 100644
index 00000000..0d7aa6bb
--- /dev/null
+++ b/help3/xhpeditor/cm/src/addon/runmode/runmode-standalone.js
@@ -0,0 +1,2 @@
+import "./codemirror-standalone.js"
+import "../../../addon/runmode/runmode.js" \ No newline at end of file
diff --git a/help3/xhpeditor/cm/src/addon/runmode/runmode.node.js b/help3/xhpeditor/cm/src/addon/runmode/runmode.node.js
new file mode 100644
index 00000000..4f2ed817
--- /dev/null
+++ b/help3/xhpeditor/cm/src/addon/runmode/runmode.node.js
@@ -0,0 +1,2 @@
+import "./codemirror.node.js"
+import "../../../addon/runmode/runmode.js" \ No newline at end of file
diff --git a/help3/xhpeditor/cm/src/display/focus.js b/help3/xhpeditor/cm/src/display/focus.js
index aa731b43..0337327e 100644
--- a/help3/xhpeditor/cm/src/display/focus.js
+++ b/help3/xhpeditor/cm/src/display/focus.js
@@ -4,19 +4,22 @@ import { addClass, rmClass } from "../util/dom.js"
import { signal } from "../util/event.js"
export function ensureFocus(cm) {
- if (!cm.state.focused) { cm.display.input.focus(); onFocus(cm) }
+ if (!cm.hasFocus()) {
+ cm.display.input.focus()
+ if (!cm.state.focused) onFocus(cm)
+ }
}
export function delayBlurEvent(cm) {
cm.state.delayingBlurEvent = true
setTimeout(() => { if (cm.state.delayingBlurEvent) {
cm.state.delayingBlurEvent = false
- onBlur(cm)
+ if (cm.state.focused) onBlur(cm)
} }, 100)
}
export function onFocus(cm, e) {
- if (cm.state.delayingBlurEvent) cm.state.delayingBlurEvent = false
+ if (cm.state.delayingBlurEvent && !cm.state.draggingText) cm.state.delayingBlurEvent = false
if (cm.options.readOnly == "nocursor") return
if (!cm.state.focused) {
diff --git a/help3/xhpeditor/cm/src/display/operations.js b/help3/xhpeditor/cm/src/display/operations.js
index 6f3c9d08..79396e9b 100644
--- a/help3/xhpeditor/cm/src/display/operations.js
+++ b/help3/xhpeditor/cm/src/display/operations.js
@@ -36,7 +36,8 @@ export function startOperation(cm) {
scrollLeft: null, scrollTop: null, // Intermediate scroll position, not pushed to DOM yet
scrollToPos: null, // Used to scroll to a specific position
focus: false,
- id: ++nextOpId // Unique ID
+ id: ++nextOpId, // Unique ID
+ markArrays: null // Used by addMarkedSpan
}
pushOperation(cm.curOp)
}
diff --git a/help3/xhpeditor/cm/src/display/scrolling.js b/help3/xhpeditor/cm/src/display/scrolling.js
index 26ec993b..27d6f70c 100644
--- a/help3/xhpeditor/cm/src/display/scrolling.js
+++ b/help3/xhpeditor/cm/src/display/scrolling.js
@@ -39,8 +39,8 @@ export function scrollPosIntoView(cm, pos, end, margin) {
// 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
+ pos = pos.ch ? Pos(pos.line, pos.sticky == "before" ? pos.ch - 1 : pos.ch, "after") : pos
}
for (let limit = 0; limit < 5; limit++) {
let changed = false
@@ -91,14 +91,15 @@ function calculateScrollPos(cm, rect) {
if (newTop != screentop) result.scrollTop = newTop
}
- let screenleft = cm.curOp && cm.curOp.scrollLeft != null ? cm.curOp.scrollLeft : display.scroller.scrollLeft
- let screenw = displayWidth(cm) - (cm.options.fixedGutter ? display.gutters.offsetWidth : 0)
+ let gutterSpace = cm.options.fixedGutter ? 0 : display.gutters.offsetWidth
+ let screenleft = cm.curOp && cm.curOp.scrollLeft != null ? cm.curOp.scrollLeft : display.scroller.scrollLeft - gutterSpace
+ let screenw = displayWidth(cm) - display.gutters.offsetWidth
let 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))
+ result.scrollLeft = Math.max(0, rect.left + gutterSpace - (tooWide ? 0 : 10))
else if (rect.right > screenw + screenleft - 3)
result.scrollLeft = rect.right + (tooWide ? 0 : 10) - screenw
return result
@@ -165,7 +166,7 @@ export function updateScrollTop(cm, val) {
}
export function setScrollTop(cm, val, forceScroll) {
- val = Math.min(cm.display.scroller.scrollHeight - cm.display.scroller.clientHeight, val)
+ val = Math.max(0, 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)
@@ -175,7 +176,7 @@ export function setScrollTop(cm, val, forceScroll) {
// Sync scroller and scrollbar, ensure the gutter elements are
// aligned.
export function setScrollLeft(cm, val, isScroller, forceScroll) {
- val = Math.min(val, cm.display.scroller.scrollWidth - cm.display.scroller.clientWidth)
+ val = Math.max(0, 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)
diff --git a/help3/xhpeditor/cm/src/display/selection.js b/help3/xhpeditor/cm/src/display/selection.js
index c658c0a2..d377a9f4 100644
--- a/help3/xhpeditor/cm/src/display/selection.js
+++ b/help3/xhpeditor/cm/src/display/selection.js
@@ -4,6 +4,7 @@ import { getLine } from "../line/utils_line.js"
import { charCoords, cursorCoords, displayWidth, paddingH, wrappedLineExtentChar } from "../measurement/position_measurement.js"
import { getOrder, iterateBidiSections } from "../util/bidi.js"
import { elt } from "../util/dom.js"
+import { onBlur } from "./focus.js"
export function updateSelection(cm) {
cm.display.input.showSelection(cm.display.input.prepareSelection())
@@ -151,8 +152,10 @@ export function restartBlink(cm) {
let on = true
display.cursorDiv.style.visibility = ""
if (cm.options.cursorBlinkRate > 0)
- display.blinker = setInterval(() => display.cursorDiv.style.visibility = (on = !on) ? "" : "hidden",
- cm.options.cursorBlinkRate)
+ display.blinker = setInterval(() => {
+ if (!cm.hasFocus()) onBlur(cm)
+ display.cursorDiv.style.visibility = (on = !on) ? "" : "hidden"
+ }, cm.options.cursorBlinkRate)
else if (cm.options.cursorBlinkRate < 0)
display.cursorDiv.style.visibility = "hidden"
}
diff --git a/help3/xhpeditor/cm/src/display/update_display.js b/help3/xhpeditor/cm/src/display/update_display.js
index 20798f59..83c25407 100644
--- a/help3/xhpeditor/cm/src/display/update_display.js
+++ b/help3/xhpeditor/cm/src/display/update_display.js
@@ -5,6 +5,7 @@ import { displayHeight, displayWidth, getDimensions, paddingVert, scrollGap } fr
import { mac, webkit } from "../util/browser.js"
import { activeElt, removeChildren, contains } from "../util/dom.js"
import { hasHandler, signal } from "../util/event.js"
+import { signalLater } from "../util/operation_group.js"
import { indexOf } from "../util/misc.js"
import { buildLineElement, updateLineForChanges } from "./update_line.js"
@@ -74,7 +75,8 @@ function selectionSnapshot(cm) {
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)) {
+ if (!/^(INPUT|TEXTAREA)$/.test(snapshot.activeElt.nodeName) &&
+ snapshot.anchorNode && contains(document.body, snapshot.anchorNode) && contains(document.body, snapshot.focusNode)) {
let sel = window.getSelection(), range = document.createRange()
range.setEnd(snapshot.anchorNode, snapshot.anchorOffset)
range.collapse(false)
@@ -172,6 +174,8 @@ export function postUpdateDisplay(cm, update) {
update.visible = visibleLines(cm.display, cm.doc, viewport)
if (update.visible.from >= cm.display.viewFrom && update.visible.to <= cm.display.viewTo)
break
+ } else if (first) {
+ update.visible = visibleLines(cm.display, cm.doc, viewport)
}
if (!updateDisplayIfNeeded(cm, update)) break
updateHeightsInViewport(cm)
@@ -251,6 +255,8 @@ function patchDisplay(cm, updateNumbersFrom, dims) {
export function updateGutterSpace(display) {
let width = display.gutters.offsetWidth
display.sizer.style.marginLeft = width + "px"
+ // Send an event to consumers responding to changes in gutter width.
+ signalLater(display, "gutterChanged", display)
}
export function setDocumentHeight(cm, measure) {
diff --git a/help3/xhpeditor/cm/src/display/update_line.js b/help3/xhpeditor/cm/src/display/update_line.js
index 50d781ee..dd1aac8b 100644
--- a/help3/xhpeditor/cm/src/display/update_line.js
+++ b/help3/xhpeditor/cm/src/display/update_line.js
@@ -104,6 +104,7 @@ function updateLineGutter(cm, lineView, lineN, dims) {
if (cm.options.lineNumbers || markers) {
let wrap = ensureLineWrapped(lineView)
let gutterWrap = lineView.gutter = elt("div", null, "CodeMirror-gutter-wrapper", `left: ${cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth}px`)
+ gutterWrap.setAttribute("aria-hidden", "true")
cm.display.input.setUneditable(gutterWrap)
wrap.insertBefore(gutterWrap, lineView.text)
if (lineView.line.gutterClass)
diff --git a/help3/xhpeditor/cm/src/edit/CodeMirror.js b/help3/xhpeditor/cm/src/edit/CodeMirror.js
index 3429da1e..dc016113 100644
--- a/help3/xhpeditor/cm/src/edit/CodeMirror.js
+++ b/help3/xhpeditor/cm/src/edit/CodeMirror.js
@@ -14,7 +14,7 @@ import { Range } from "../model/selection.js"
import { extendSelection } from "../model/selection_updates.js"
import { ie, ie_version, mobile, webkit } from "../util/browser.js"
import { e_preventDefault, e_stop, on, signal, signalDOMEvent } from "../util/event.js"
-import { bind, copyObj, Delayed } from "../util/misc.js"
+import { copyObj, Delayed } from "../util/misc.js"
import { clearDragCursor, onDragOver, onDragStart, onDrop } from "./drop_events.js"
import { ensureGlobalHandlers } from "./global_events.js"
@@ -76,7 +76,9 @@ export function CodeMirror(place, options) {
attachDoc(this, doc)
if ((options.autofocus && !mobile) || this.hasFocus())
- setTimeout(bind(onFocus, this), 20)
+ setTimeout(() => {
+ if (this.hasFocus() && !this.state.focused) onFocus(this)
+ }, 20)
else
onBlur(this)
diff --git a/help3/xhpeditor/cm/src/edit/commands.js b/help3/xhpeditor/cm/src/edit/commands.js
index 3916b129..4c4cc4cd 100644
--- a/help3/xhpeditor/cm/src/edit/commands.js
+++ b/help3/xhpeditor/cm/src/edit/commands.js
@@ -84,7 +84,7 @@ export let commands = {
goGroupRight: cm => cm.moveH(1, "group"),
goGroupLeft: cm => cm.moveH(-1, "group"),
goWordRight: cm => cm.moveH(1, "word"),
- delCharBefore: cm => cm.deleteH(-1, "char"),
+ delCharBefore: cm => cm.deleteH(-1, "codepoint"),
delCharAfter: cm => cm.deleteH(1, "char"),
delWordBefore: cm => cm.deleteH(-1, "word"),
delWordAfter: cm => cm.deleteH(1, "word"),
@@ -170,7 +170,7 @@ function lineStartSmart(cm, pos) {
let line = getLine(cm.doc, start.line)
let order = getOrder(line, cm.doc.direction)
if (!order || order[0].level == 0) {
- let firstNonWS = Math.max(0, line.text.search(/\S/))
+ let firstNonWS = Math.max(start.ch, line.text.search(/\S/))
let inWS = pos.line == start.line && pos.ch <= firstNonWS && pos.ch
return Pos(start.line, inWS ? 0 : firstNonWS, start.sticky)
}
diff --git a/help3/xhpeditor/cm/src/edit/drop_events.js b/help3/xhpeditor/cm/src/edit/drop_events.js
index c6fbbbc1..f309b2df 100644
--- a/help3/xhpeditor/cm/src/edit/drop_events.js
+++ b/help3/xhpeditor/cm/src/edit/drop_events.js
@@ -38,7 +38,7 @@ export function onDrop(e) {
text.filter(t => t != null).join(cm.doc.lineSeparator())),
origin: "paste"}
makeChange(cm.doc, change)
- setSelectionReplaceHistory(cm.doc, simpleSelection(pos, changeEnd(change)))
+ setSelectionReplaceHistory(cm.doc, simpleSelection(clipPos(cm.doc, pos), clipPos(cm.doc, changeEnd(change))))
})()
}
}
@@ -56,7 +56,7 @@ export function onDrop(e) {
markAsReadAndPasteIfAllFilesAreRead()
return
}
- text[i] = content;
+ text[i] = content
markAsReadAndPasteIfAllFilesAreRead()
}
reader.readAsText(file)
diff --git a/help3/xhpeditor/cm/src/edit/key_events.js b/help3/xhpeditor/cm/src/edit/key_events.js
index 1e7c27bb..8f72182a 100644
--- a/help3/xhpeditor/cm/src/edit/key_events.js
+++ b/help3/xhpeditor/cm/src/edit/key_events.js
@@ -106,6 +106,7 @@ function handleCharBinding(cm, e, ch) {
let lastStoppedKey = null
export function onKeyDown(e) {
let cm = this
+ if (e.target && e.target != cm.display.input.getField()) return
cm.curOp.focus = activeElt()
if (signalDOMEvent(cm, e)) return
// IE does strange things with escape.
@@ -149,6 +150,7 @@ export function onKeyUp(e) {
export function onKeyPress(e) {
let cm = this
+ if (e.target && e.target != cm.display.input.getField()) return
if (eventInWidget(cm.display, e) || signalDOMEvent(cm, e) || e.ctrlKey && !e.altKey || mac && e.metaKey) return
let keyCode = e.keyCode, charCode = e.charCode
if (presto && keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return}
diff --git a/help3/xhpeditor/cm/src/edit/main.js b/help3/xhpeditor/cm/src/edit/main.js
index 934206c8..929a2bdc 100644
--- a/help3/xhpeditor/cm/src/edit/main.js
+++ b/help3/xhpeditor/cm/src/edit/main.js
@@ -66,4 +66,4 @@ import { addLegacyProps } from "./legacy.js"
addLegacyProps(CodeMirror)
-CodeMirror.version = "5.51.0"
+CodeMirror.version = "5.61.1"
diff --git a/help3/xhpeditor/cm/src/edit/methods.js b/help3/xhpeditor/cm/src/edit/methods.js
index 6b24f2bb..c33a8598 100644
--- a/help3/xhpeditor/cm/src/edit/methods.js
+++ b/help3/xhpeditor/cm/src/edit/methods.js
@@ -415,7 +415,7 @@ export default function(CodeMirror) {
clearCaches(this)
scrollToCoords(this, this.doc.scrollLeft, this.doc.scrollTop)
updateGutterSpace(this.display)
- if (oldHeight == null || Math.abs(oldHeight - textHeight(this.display)) > .5)
+ if (oldHeight == null || Math.abs(oldHeight - textHeight(this.display)) > .5 || this.options.lineWrapping)
estimateLineHeights(this)
signal(this, "refresh", this)
}),
@@ -457,19 +457,19 @@ export default function(CodeMirror) {
}
// Used for horizontal relative motion. Dir is -1 or 1 (left or
-// right), unit can be "char", "column" (like char, but doesn't
-// cross line boundaries), "word" (across next word), or "group" (to
-// the start of next group of word or non-word-non-whitespace
-// chars). The visually param controls whether, in right-to-left
-// text, direction 1 means to move towards the next index in the
-// string, or towards the character to the right of the current
-// position. The resulting position will have a hitSide=true
-// property if it reached the end of the document.
+// right), unit can be "codepoint", "char", "column" (like char, but
+// doesn't cross line boundaries), "word" (across next word), or
+// "group" (to the start of next group of word or
+// non-word-non-whitespace chars). The visually param controls
+// whether, in right-to-left text, direction 1 means to move towards
+// the next index in the string, or towards the character to the right
+// of the current position. The resulting position will have a
+// hitSide=true property if it reached the end of the document.
function findPosH(doc, pos, dir, unit, visually) {
let oldPos = pos
let origDir = dir
let lineObj = getLine(doc, pos.line)
- let lineDir = visually && doc.cm && doc.cm.getOption("direction") == "rtl" ? -dir : dir
+ let lineDir = visually && doc.direction == "rtl" ? -dir : dir
function findNextLine() {
let l = pos.line + lineDir
if (l < doc.first || l >= doc.first + doc.size) return false
@@ -478,7 +478,15 @@ function findPosH(doc, pos, dir, unit, visually) {
}
function moveOnce(boundToLine) {
let next
- if (visually) {
+ if (unit == "codepoint") {
+ let ch = lineObj.text.charCodeAt(pos.ch + (dir > 0 ? 0 : -1))
+ if (isNaN(ch)) {
+ next = null
+ } else {
+ let astral = dir > 0 ? ch >= 0xD800 && ch < 0xDC00 : ch >= 0xDC00 && ch < 0xDFFF
+ next = new Pos(pos.line, Math.max(0, Math.min(lineObj.text.length, pos.ch + dir * (astral ? 2 : 1))), -dir)
+ }
+ } else if (visually) {
next = moveVisually(doc.cm, lineObj, pos, dir)
} else {
next = moveLogically(lineObj, pos, dir)
@@ -494,7 +502,7 @@ function findPosH(doc, pos, dir, unit, visually) {
return true
}
- if (unit == "char") {
+ if (unit == "char" || unit == "codepoint") {
moveOnce()
} else if (unit == "column") {
moveOnce(true)
diff --git a/help3/xhpeditor/cm/src/edit/mouse_events.js b/help3/xhpeditor/cm/src/edit/mouse_events.js
index d0bbfba1..b5d0b5a6 100644
--- a/help3/xhpeditor/cm/src/edit/mouse_events.js
+++ b/help3/xhpeditor/cm/src/edit/mouse_events.js
@@ -7,7 +7,7 @@ import { posFromMouse } from "../measurement/position_measurement.js"
import { eventInWidget } from "../measurement/widgets.js"
import { normalizeSelection, Range, Selection } from "../model/selection.js"
import { extendRange, extendSelection, replaceOneSelection, setSelection } from "../model/selection_updates.js"
-import { captureRightClick, chromeOS, ie, ie_version, mac, webkit } from "../util/browser.js"
+import { captureRightClick, chromeOS, ie, ie_version, mac, webkit, safari } from "../util/browser.js"
import { getOrder, getBidiPartAt } from "../util/bidi.js"
import { activeElt } from "../util/dom.js"
import { e_button, e_defaultPrevented, e_preventDefault, e_target, hasHandler, off, on, signal, signalDOMEvent } from "../util/event.js"
@@ -149,6 +149,10 @@ function leftButtonStartDrag(cm, event, pos, behavior) {
let dragEnd = operation(cm, e => {
if (webkit) display.scroller.draggable = false
cm.state.draggingText = false
+ if (cm.state.delayingBlurEvent) {
+ if (cm.hasFocus()) cm.state.delayingBlurEvent = false
+ else delayBlurEvent(cm)
+ }
off(display.wrapper.ownerDocument, "mouseup", dragEnd)
off(display.wrapper.ownerDocument, "mousemove", mouseMove)
off(display.scroller, "dragstart", dragStart)
@@ -158,8 +162,8 @@ function leftButtonStartDrag(cm, event, pos, behavior) {
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(() => {display.wrapper.ownerDocument.body.focus(); display.input.focus()}, 20)
+ if ((webkit && !safari) || ie && ie_version == 9)
+ setTimeout(() => {display.wrapper.ownerDocument.body.focus({preventScroll: true}); display.input.focus()}, 20)
else
display.input.focus()
}
@@ -172,15 +176,15 @@ function leftButtonStartDrag(cm, event, pos, behavior) {
if (webkit) display.scroller.draggable = true
cm.state.draggingText = dragEnd
dragEnd.copy = !behavior.moveOnDrag
- // IE's approach to draggable
- if (display.scroller.dragDrop) display.scroller.dragDrop()
on(display.wrapper.ownerDocument, "mouseup", dragEnd)
on(display.wrapper.ownerDocument, "mousemove", mouseMove)
on(display.scroller, "dragstart", dragStart)
on(display.scroller, "drop", dragEnd)
- delayBlurEvent(cm)
+ cm.state.delayingBlurEvent = true
setTimeout(() => display.input.focus(), 20)
+ // IE's approach to draggable
+ if (display.scroller.dragDrop) display.scroller.dragDrop()
}
function rangeForUnit(cm, pos, unit) {
@@ -193,6 +197,7 @@ function rangeForUnit(cm, pos, unit) {
// Normal selection, as opposed to text dragging.
function leftButtonSelect(cm, event, start, behavior) {
+ if (ie) delayBlurEvent(cm)
let display = cm.display, doc = cm.doc
e_preventDefault(event)
diff --git a/help3/xhpeditor/cm/src/edit/options.js b/help3/xhpeditor/cm/src/edit/options.js
index 3abd3c3c..8cb9cee0 100644
--- a/help3/xhpeditor/cm/src/edit/options.js
+++ b/help3/xhpeditor/cm/src/edit/options.js
@@ -68,7 +68,7 @@ export function defineOptions(CodeMirror) {
for (let i = newBreaks.length - 1; i >= 0; i--)
replaceRange(cm.doc, val, newBreaks[i], Pos(newBreaks[i].line, newBreaks[i].ch + val.length))
})
- option("specialChars", /[\u0000-\u001f\u007f-\u009f\u00ad\u061c\u200b-\u200f\u2028\u2029\ufeff\ufff9-\ufffc]/g, (cm, val, old) => {
+ option("specialChars", /[\u0000-\u001f\u007f-\u009f\u00ad\u061c\u200b\u200e\u200f\u2028\u2029\ufeff\ufff9-\ufffc]/g, (cm, val, old) => {
cm.state.specialChars = new RegExp(val.source + (val.test("\t") ? "" : "|\t"), "g")
if (old != Init) cm.refresh()
})
@@ -132,6 +132,12 @@ export function defineOptions(CodeMirror) {
}
cm.display.input.readOnlyChanged(val)
})
+
+ option("screenReaderLabel", null, (cm, val) => {
+ val = (val === '') ? null : val
+ cm.display.input.screenReaderLabelChanged(val)
+ })
+
option("disableInput", false, (cm, val) => {if (!val) cm.display.input.reset()}, true)
option("dragDrop", true, dragDropChanged)
option("allowDropFileTypes", null)
diff --git a/help3/xhpeditor/cm/src/input/ContentEditableInput.js b/help3/xhpeditor/cm/src/input/ContentEditableInput.js
index b77c7d49..f5df0ebc 100644
--- a/help3/xhpeditor/cm/src/input/ContentEditableInput.js
+++ b/help3/xhpeditor/cm/src/input/ContentEditableInput.js
@@ -10,7 +10,7 @@ import { simpleSelection } from "../model/selection.js"
import { setSelection } from "../model/selection_updates.js"
import { getBidiPartAt, getOrder } from "../util/bidi.js"
import { android, chrome, gecko, ie_version } from "../util/browser.js"
-import { contains, range, removeChildrenAndAdd, selectInput } from "../util/dom.js"
+import { activeElt, contains, range, removeChildrenAndAdd, selectInput } from "../util/dom.js"
import { on, signalDOMEvent } from "../util/event.js"
import { Delayed, lst, sel_dontScroll } from "../util/misc.js"
@@ -29,10 +29,19 @@ export default class ContentEditableInput {
init(display) {
let input = this, cm = input.cm
let div = input.div = display.lineDiv
+ div.contentEditable = true
disableBrowserMagic(div, cm.options.spellcheck, cm.options.autocorrect, cm.options.autocapitalize)
+ function belongsToInput(e) {
+ for (let t = e.target; t; t = t.parentNode) {
+ if (t == div) return true
+ if (/\bCodeMirror-(?:line)?widget\b/.test(t.className)) break
+ }
+ return false
+ }
+
on(div, "paste", e => {
- if (signalDOMEvent(cm, e) || handlePaste(e, cm)) return
+ if (!belongsToInput(e) || signalDOMEvent(cm, e) || handlePaste(e, cm)) return
// IE doesn't fire input events, so we schedule a read for the pasted content in this way
if (ie_version <= 11) setTimeout(operation(cm, () => this.updateFromDOM()), 20)
})
@@ -57,7 +66,7 @@ export default class ContentEditableInput {
})
function onCopyCut(e) {
- if (signalDOMEvent(cm, e)) return
+ if (!belongsToInput(e) || signalDOMEvent(cm, e)) return
if (cm.somethingSelected()) {
setLastCopied({lineWise: false, text: cm.getSelections()})
if (e.type == "cut") cm.replaceSelection("", null, "cut")
@@ -87,7 +96,7 @@ export default class ContentEditableInput {
let kludge = hiddenTextarea(), te = kludge.firstChild
cm.display.lineSpace.insertBefore(kludge, cm.display.lineSpace.firstChild)
te.value = lastCopied.text.join("\n")
- let hadFocus = document.activeElement
+ let hadFocus = activeElt()
selectInput(te)
setTimeout(() => {
cm.display.lineSpace.removeChild(kludge)
@@ -99,9 +108,18 @@ export default class ContentEditableInput {
on(div, "cut", onCopyCut)
}
+ screenReaderLabelChanged(label) {
+ // Label for screenreaders, accessibility
+ if(label) {
+ this.div.setAttribute('aria-label', label)
+ } else {
+ this.div.removeAttribute('aria-label')
+ }
+ }
+
prepareSelection() {
let result = prepareSelection(this.cm, false)
- result.focus = this.cm.state.focused
+ result.focus = activeElt() == this.div
return result
}
@@ -195,7 +213,7 @@ export default class ContentEditableInput {
focus() {
if (this.cm.options.readOnly != "nocursor") {
- if (!this.selectionInEditor())
+ if (!this.selectionInEditor() || activeElt() != this.div)
this.showSelection(this.prepareSelection(), true)
this.div.focus()
}
diff --git a/help3/xhpeditor/cm/src/input/TextareaInput.js b/help3/xhpeditor/cm/src/input/TextareaInput.js
index ab02230f..977eb227 100644
--- a/help3/xhpeditor/cm/src/input/TextareaInput.js
+++ b/help3/xhpeditor/cm/src/input/TextareaInput.js
@@ -118,6 +118,15 @@ export default class TextareaInput {
this.textarea = this.wrapper.firstChild
}
+ screenReaderLabelChanged(label) {
+ // Label for screenreaders, accessibility
+ if(label) {
+ this.textarea.setAttribute('aria-label', label)
+ } else {
+ this.textarea.removeAttribute('aria-label')
+ }
+ }
+
prepareSelection() {
// Redraw the selection and/or cursor
let cm = this.cm, display = cm.display, doc = cm.doc
@@ -357,6 +366,7 @@ export default class TextareaInput {
readOnlyChanged(val) {
if (!val) this.reset()
this.textarea.disabled = val == "nocursor"
+ this.textarea.readOnly = !!val
}
setUneditable() {}
diff --git a/help3/xhpeditor/cm/src/input/input.js b/help3/xhpeditor/cm/src/input/input.js
index 26bba1d2..32adbf9b 100644
--- a/help3/xhpeditor/cm/src/input/input.js
+++ b/help3/xhpeditor/cm/src/input/input.js
@@ -51,7 +51,7 @@ export function applyTextInput(cm, inserted, deleted, sel, origin) {
from = Pos(from.line, from.ch - deleted)
else if (cm.state.overwrite && !paste) // Handle overwrite
to = Pos(to.line, Math.min(getLine(doc, to.line).text.length, to.ch + lst(textLines).length))
- else if (paste && lastCopied && lastCopied.lineWise && lastCopied.text.join("\n") == inserted)
+ else if (paste && lastCopied && lastCopied.lineWise && lastCopied.text.join("\n") == textLines.join("\n"))
from = to = Pos(from.line, 0)
}
let changeEvent = {from: from, to: to, text: multiPaste ? multiPaste[i % multiPaste.length] : textLines,
diff --git a/help3/xhpeditor/cm/src/input/keymap.js b/help3/xhpeditor/cm/src/input/keymap.js
index 046b3505..2df588de 100644
--- a/help3/xhpeditor/cm/src/input/keymap.js
+++ b/help3/xhpeditor/cm/src/input/keymap.js
@@ -29,10 +29,9 @@ keyMap.pcDefault = {
// Very basic readline/emacs-style bindings, which are standard on Mac.
keyMap.emacsy = {
"Ctrl-F": "goCharRight", "Ctrl-B": "goCharLeft", "Ctrl-P": "goLineUp", "Ctrl-N": "goLineDown",
- "Alt-F": "goWordRight", "Alt-B": "goWordLeft", "Ctrl-A": "goLineStart", "Ctrl-E": "goLineEnd",
- "Ctrl-V": "goPageDown", "Shift-Ctrl-V": "goPageUp", "Ctrl-D": "delCharAfter", "Ctrl-H": "delCharBefore",
- "Alt-D": "delWordAfter", "Alt-Backspace": "delWordBefore", "Ctrl-K": "killLine", "Ctrl-T": "transposeChars",
- "Ctrl-O": "openLine"
+ "Ctrl-A": "goLineStart", "Ctrl-E": "goLineEnd", "Ctrl-V": "goPageDown", "Shift-Ctrl-V": "goPageUp",
+ "Ctrl-D": "delCharAfter", "Ctrl-H": "delCharBefore", "Alt-Backspace": "delWordBefore", "Ctrl-K": "killLine",
+ "Ctrl-T": "transposeChars", "Ctrl-O": "openLine"
}
keyMap.macDefault = {
"Cmd-A": "selectAll", "Cmd-D": "deleteLine", "Cmd-Z": "undo", "Shift-Cmd-Z": "redo", "Cmd-Y": "redo",
@@ -127,7 +126,7 @@ export function addModifierNames(name, event, noShift) {
let 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
+ if ((flipCtrlCmd ? event.ctrlKey : event.metaKey) && base != "Mod") name = "Cmd-" + name
if (!noShift && event.shiftKey && base != "Shift") name = "Shift-" + name
return name
}
diff --git a/help3/xhpeditor/cm/src/input/keynames.js b/help3/xhpeditor/cm/src/input/keynames.js
index d3339038..eb09ca17 100644
--- a/help3/xhpeditor/cm/src/input/keynames.js
+++ b/help3/xhpeditor/cm/src/input/keynames.js
@@ -5,7 +5,7 @@ export let keyNames = {
46: "Delete", 59: ";", 61: "=", 91: "Mod", 92: "Mod", 93: "Mod",
106: "*", 107: "=", 109: "-", 110: ".", 111: "/", 145: "ScrollLock",
173: "-", 186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\",
- 221: "]", 222: "'", 63232: "Up", 63233: "Down", 63234: "Left", 63235: "Right", 63272: "Delete",
+ 221: "]", 222: "'", 224: "Mod", 63232: "Up", 63233: "Down", 63234: "Left", 63235: "Right", 63272: "Delete",
63273: "Home", 63275: "End", 63276: "PageUp", 63277: "PageDown", 63302: "Insert"
}
diff --git a/help3/xhpeditor/cm/src/input/movement.js b/help3/xhpeditor/cm/src/input/movement.js
index 946bce68..479f221f 100644
--- a/help3/xhpeditor/cm/src/input/movement.js
+++ b/help3/xhpeditor/cm/src/input/movement.js
@@ -15,7 +15,7 @@ export function moveLogically(line, start, dir) {
export function endOfLine(visually, cm, lineObj, lineNo, dir) {
if (visually) {
- if (cm.getOption("direction") == "rtl") dir = -dir
+ if (cm.doc.direction == "rtl") dir = -dir
let order = getOrder(lineObj, cm.doc.direction)
if (order) {
let part = dir < 0 ? lst(order) : order[0]
diff --git a/help3/xhpeditor/cm/src/line/highlight.js b/help3/xhpeditor/cm/src/line/highlight.js
index 9835d462..7b4ca0b3 100644
--- a/help3/xhpeditor/cm/src/line/highlight.js
+++ b/help3/xhpeditor/cm/src/line/highlight.js
@@ -198,7 +198,7 @@ function extractLineClasses(type, output) {
let prop = lineClass[1] ? "bgClass" : "textClass"
if (output[prop] == null)
output[prop] = lineClass[2]
- else if (!(new RegExp("(?:^|\s)" + lineClass[2] + "(?:$|\s)")).test(output[prop]))
+ else if (!(new RegExp("(?:^|\\s)" + lineClass[2] + "(?:$|\\s)")).test(output[prop]))
output[prop] += " " + lineClass[2]
}
return type
diff --git a/help3/xhpeditor/cm/src/line/line_data.js b/help3/xhpeditor/cm/src/line/line_data.js
index 20dd4328..e650b3e3 100644
--- a/help3/xhpeditor/cm/src/line/line_data.js
+++ b/help3/xhpeditor/cm/src/line/line_data.js
@@ -178,7 +178,7 @@ function buildToken(builder, text, style, startStyle, endStyle, css, attributes)
}
}
builder.trailingSpace = displayText.charCodeAt(text.length - 1) == 32
- if (style || startStyle || endStyle || mustWrap || css) {
+ if (style || startStyle || endStyle || mustWrap || css || attributes) {
let fullStyle = style || ""
if (startStyle) fullStyle += startStyle
if (endStyle) fullStyle += endStyle
diff --git a/help3/xhpeditor/cm/src/line/spans.js b/help3/xhpeditor/cm/src/line/spans.js
index d81dec4b..ac17bf6b 100644
--- a/help3/xhpeditor/cm/src/line/spans.js
+++ b/help3/xhpeditor/cm/src/line/spans.js
@@ -18,6 +18,7 @@ export function getMarkedSpanFor(spans, marker) {
if (span.marker == marker) return span
}
}
+
// Remove a span from an array, returning undefined if no spans are
// left (we don't store arrays for lines without spans).
export function removeMarkedSpan(spans, span) {
@@ -26,9 +27,16 @@ export function removeMarkedSpan(spans, span) {
if (spans[i] != span) (r || (r = [])).push(spans[i])
return r
}
+
// Add a span to a line.
-export function addMarkedSpan(line, span) {
- line.markedSpans = line.markedSpans ? line.markedSpans.concat([span]) : [span]
+export function addMarkedSpan(line, span, op) {
+ let inThisOp = op && window.WeakSet && (op.markedSpans || (op.markedSpans = new WeakSet))
+ if (inThisOp && inThisOp.has(line.markedSpans)) {
+ line.markedSpans.push(span)
+ } else {
+ line.markedSpans = line.markedSpans ? line.markedSpans.concat([span]) : [span]
+ if (inThisOp) inThisOp.add(line.markedSpans)
+ }
span.marker.attachLine(line)
}
diff --git a/help3/xhpeditor/cm/src/model/Doc.js b/help3/xhpeditor/cm/src/model/Doc.js
index c305eee2..8a2082aa 100644
--- a/help3/xhpeditor/cm/src/model/Doc.js
+++ b/help3/xhpeditor/cm/src/model/Doc.js
@@ -137,7 +137,7 @@ Doc.prototype = createObj(BranchChunk.prototype, {
let out = []
for (let i = 0; i < ranges.length; i++)
out[i] = new Range(clipPos(this, ranges[i].anchor),
- clipPos(this, ranges[i].head))
+ clipPos(this, ranges[i].head || ranges[i].anchor))
if (primary == null) primary = Math.min(ranges.length - 1, this.sel.primIndex)
setSelection(this, normalizeSelection(this.cm, out, primary), options)
}),
@@ -198,7 +198,7 @@ Doc.prototype = createObj(BranchChunk.prototype, {
return {undo: done, redo: undone}
},
clearHistory: function() {
- this.history = new History(this.history.maxGeneration)
+ this.history = new History(this.history)
linkedDocs(this, doc => doc.history = this.history, true)
},
@@ -219,7 +219,7 @@ Doc.prototype = createObj(BranchChunk.prototype, {
undone: copyHistoryArray(this.history.undone)}
},
setHistory: function(histData) {
- let hist = this.history = new History(this.history.maxGeneration)
+ let hist = this.history = new History(this.history)
hist.done = copyHistoryArray(histData.done.slice(0), null, true)
hist.undone = copyHistoryArray(histData.undone.slice(0), null, true)
},
diff --git a/help3/xhpeditor/cm/src/model/document_data.js b/help3/xhpeditor/cm/src/model/document_data.js
index d946e7af..c4204828 100644
--- a/help3/xhpeditor/cm/src/model/document_data.js
+++ b/help3/xhpeditor/cm/src/model/document_data.js
@@ -94,6 +94,7 @@ export function attachDoc(cm, doc) {
estimateLineHeights(cm)
loadMode(cm)
setDirectionClass(cm)
+ cm.options.direction = doc.direction
if (!cm.options.lineWrapping) findMaxLine(cm)
cm.options.mode = doc.modeOption
regChange(cm)
diff --git a/help3/xhpeditor/cm/src/model/history.js b/help3/xhpeditor/cm/src/model/history.js
index 2d9359f0..a5bfbb38 100644
--- a/help3/xhpeditor/cm/src/model/history.js
+++ b/help3/xhpeditor/cm/src/model/history.js
@@ -8,19 +8,19 @@ import { changeEnd } from "./change_measurement.js"
import { linkedDocs } from "./document_data.js"
import { Selection } from "./selection.js"
-export function History(startGen) {
+export function History(prev) {
// Arrays of change events and selections. Doing something adds an
// event to done and clears undo. Undoing moves events from done
// to undone, redoing moves them in the other direction.
this.done = []; this.undone = []
- this.undoDepth = Infinity
+ this.undoDepth = prev ? prev.undoDepth : Infinity
// Used to track when changes can be merged into a single undo
// event
this.lastModTime = this.lastSelTime = 0
this.lastOp = this.lastSelOp = null
this.lastOrigin = this.lastSelOrigin = null
// Used by the isClean() method
- this.generation = this.maxGeneration = startGen || 1
+ this.generation = this.maxGeneration = prev ? prev.maxGeneration : 1
}
// Create a history change event from an updateDoc-style change
diff --git a/help3/xhpeditor/cm/src/model/line_widget.js b/help3/xhpeditor/cm/src/model/line_widget.js
index 5444d89d..f94727e5 100644
--- a/help3/xhpeditor/cm/src/model/line_widget.js
+++ b/help3/xhpeditor/cm/src/model/line_widget.js
@@ -63,7 +63,7 @@ export function addLineWidget(doc, handle, node, options) {
changeLine(doc, handle, "widget", line => {
let widgets = line.widgets || (line.widgets = [])
if (widget.insertAt == null) widgets.push(widget)
- else widgets.splice(Math.min(widgets.length - 1, Math.max(0, widget.insertAt)), 0, widget)
+ else widgets.splice(Math.min(widgets.length, Math.max(0, widget.insertAt)), 0, widget)
widget.line = line
if (cm && !lineIsHidden(doc, line)) {
let aboveVisible = heightAtLine(line) < doc.scrollTop
diff --git a/help3/xhpeditor/cm/src/model/mark_text.js b/help3/xhpeditor/cm/src/model/mark_text.js
index 088f9c98..64d40d29 100644
--- a/help3/xhpeditor/cm/src/model/mark_text.js
+++ b/help3/xhpeditor/cm/src/model/mark_text.js
@@ -187,7 +187,7 @@ export function markText(doc, from, to, options, type) {
if (marker.collapsed && curLine != from.line) updateLineHeight(line, 0)
addMarkedSpan(line, new MarkedSpan(marker,
curLine == from.line ? from.ch : null,
- curLine == to.line ? to.ch : null))
+ curLine == to.line ? to.ch : null), doc.cm && doc.cm.curOp)
++curLine
})
// lineIsHidden depends on the presence of the spans, so needs a second pass
diff --git a/help3/xhpeditor/cm/src/model/selection_updates.js b/help3/xhpeditor/cm/src/model/selection_updates.js
index 4db2bd7f..3f399e5f 100644
--- a/help3/xhpeditor/cm/src/model/selection_updates.js
+++ b/help3/xhpeditor/cm/src/model/selection_updates.js
@@ -106,7 +106,7 @@ export function setSelectionNoUndo(doc, sel, options) {
(cmp(sel.primary().head, doc.sel.primary().head) < 0 ? -1 : 1)
setSelectionInner(doc, skipAtomicInSelection(doc, sel, bias, true))
- if (!(options && options.scroll === false) && doc.cm)
+ if (!(options && options.scroll === false) && doc.cm && doc.cm.getOption("readOnly") != "nocursor")
ensureCursorVisible(doc.cm)
}
diff --git a/help3/xhpeditor/cm/src/util/bidi.js b/help3/xhpeditor/cm/src/util/bidi.js
index 33ab854d..92c4191d 100644
--- a/help3/xhpeditor/cm/src/util/bidi.js
+++ b/help3/xhpeditor/cm/src/util/bidi.js
@@ -175,14 +175,15 @@ let bidiOrdering = (function() {
for (++i; i < len && countsAsLeft.test(types[i]); ++i) {}
order.push(new BidiSpan(0, start, i))
} else {
- let pos = i, at = order.length
+ let pos = i, at = order.length, isRTL = direction == "rtl" ? 1 : 0
for (++i; i < len && types[i] != "L"; ++i) {}
for (let j = pos; j < i;) {
if (countsAsNum.test(types[j])) {
- if (pos < j) order.splice(at, 0, new BidiSpan(1, pos, j))
+ if (pos < j) { order.splice(at, 0, new BidiSpan(1, pos, j)); at += isRTL }
let nstart = j
for (++j; j < i && countsAsNum.test(types[j]); ++j) {}
order.splice(at, 0, new BidiSpan(2, nstart, j))
+ at += isRTL
pos = j
} else ++j
}
diff --git a/help3/xhpeditor/cm/src/util/browser.js b/help3/xhpeditor/cm/src/util/browser.js
index 9fc4602c..ae9d6af7 100644
--- a/help3/xhpeditor/cm/src/util/browser.js
+++ b/help3/xhpeditor/cm/src/util/browser.js
@@ -17,7 +17,7 @@ export let safari = /Apple Computer/.test(navigator.vendor)
export let mac_geMountainLion = /Mac OS X 1\d\D([8-9]|\d\d)\D/.test(userAgent)
export let phantom = /PhantomJS/.test(userAgent)
-export let ios = !edge && /AppleWebKit/.test(userAgent) && /Mobile\/\w+/.test(userAgent)
+export let ios = safari && (/Mobile\/\w+/.test(userAgent) || navigator.maxTouchPoints > 2)
export let android = /Android/.test(userAgent)
// This is woefully incomplete. Suggestions for alternative methods welcome.
export let mobile = ios || android || /webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(userAgent)
diff --git a/help3/xhpeditor/cm/src/util/misc.js b/help3/xhpeditor/cm/src/util/misc.js
index 3337989b..6dc8d861 100644
--- a/help3/xhpeditor/cm/src/util/misc.js
+++ b/help3/xhpeditor/cm/src/util/misc.js
@@ -61,7 +61,7 @@ export function indexOf(array, elt) {
}
// Number of pixels added to scroller and sizer to hide scrollbar
-export let scrollerGap = 30
+export let scrollerGap = 50
// Returned or thrown by various protocols to signal 'I'm not
// handling this'.
diff --git a/help3/xhpeditor/cm/test/annotatescrollbar.js b/help3/xhpeditor/cm/test/annotatescrollbar.js
new file mode 100644
index 00000000..4a4d0533
--- /dev/null
+++ b/help3/xhpeditor/cm/test/annotatescrollbar.js
@@ -0,0 +1,55 @@
+namespace = "annotatescrollbar_";
+
+(function () {
+ function test(name, run, content, query, expected) {
+ return testCM(name, function (cm) {
+ var annotation = cm.annotateScrollbar({
+ listenForChanges: false,
+ className: "CodeMirror-search-match"
+ });
+ var matches = [];
+ var cursor = cm.getSearchCursor(query, CodeMirror.Pos(0, 0));
+ while (cursor.findNext()) {
+ var match = {
+ from: cursor.from(),
+ to: cursor.to()
+ };
+ matches.push(match)
+ }
+
+ if (run) run(cm);
+
+ cm.display.barWidth = 5;
+ annotation.update(matches);
+
+ var annotations = cm.getWrapperElement().getElementsByClassName(annotation.options.className);
+ eq(annotations.length, expected, "Expected " + expected + " annotations on the scrollbar.")
+ }, {
+ value: content,
+ mode: "javascript",
+ foldOptions: {
+ rangeFinder: CodeMirror.fold.brace
+ }
+ });
+ }
+
+ function doFold(cm) {
+ cm.foldCode(cm.getCursor());
+ }
+ var simpleProg = "function foo() {\n\n return \"foo\";\n\n}\n\nfoo();\n";
+ var consecutiveLineMatches = "function foo() {\n return \"foo\";\n}\nfoo();\n";
+ var singleLineMatches = "function foo() { return \"foo\"; }foo();\n";
+
+ // Base case - expect 3 matches and 3 annotations
+ test("simple", null, simpleProg, "foo", 3);
+ // Consecutive line matches are combines into a single annotation - expect 3 matches and 2 annotations
+ test("combineConsecutiveLine", null, consecutiveLineMatches, "foo", 2);
+ // Matches on a single line get a single annotation - expect 3 matches and 1 annotation
+ test("combineSingleLine", null, singleLineMatches, "foo", 1);
+ // Matches within a fold are annotated on the folded line - expect 3 matches and 2 annotations
+ test("simpleFold", doFold, simpleProg, "foo", 2);
+ // Combination of combineConsecutiveLine and simpleFold cases - expect 3 matches and 1 annotation
+ test("foldedMatch", doFold, consecutiveLineMatches, "foo", 1);
+ // Hidden matches within a fold are annotated on the folded line - expect 1 match and 1 annotation
+ test("hiddenMatch", doFold, simpleProg, "return", 1);
+})(); \ No newline at end of file
diff --git a/help3/xhpeditor/cm/test/driver.js b/help3/xhpeditor/cm/test/driver.js
index 22de01e3..bc1634ea 100644
--- a/help3/xhpeditor/cm/test/driver.js
+++ b/help3/xhpeditor/cm/test/driver.js
@@ -1,4 +1,4 @@
-var tests = [], filters = [], allNames = [];
+var tests = [], filters = [], nameCounts = {};
function Failure(why) {this.message = why;}
Failure.prototype.toString = function() { return this.message; };
@@ -11,16 +11,13 @@ function indexOf(collection, elt) {
}
function test(name, run, expectedFail) {
- if (!/^vim/.test(name)) return
- console.log(name)
// Force unique names
- var originalName = name;
- var i = 2; // Second function would be NAME_2
- while (indexOf(allNames, name) !== -1){
- name = originalName + "_" + i;
- i++;
+ if (nameCounts[name] == undefined){
+ nameCounts[name] = 2;
+ } else {
+ // Append number if not first test with this name.
+ name = name + '_' + (nameCounts[name]++);
}
- allNames.push(name);
// Add test
tests.push({name: name, func: run, expectedFail: expectedFail});
return name;
diff --git a/help3/xhpeditor/cm/test/emacs_test.js b/help3/xhpeditor/cm/test/emacs_test.js
index 412dba4b..4d2fde68 100644
--- a/help3/xhpeditor/cm/test/emacs_test.js
+++ b/help3/xhpeditor/cm/test/emacs_test.js
@@ -39,6 +39,8 @@
}, {keyMap: "emacs", value: start, mode: "javascript"});
}
+ function dialog(answer) { return function(cm) { cm.openDialog = function(_, cb) { cb(answer); }; }; }
+
function at(line, ch, sticky) { return function(cm) { eqCursorPos(cm.getCursor(), Pos(line, ch, sticky)); }; }
function txt(str) { return function(cm) { eq(cm.getValue(), str); }; }
@@ -133,6 +135,19 @@
sim("backspaceDoesntAddToRing", "foobar", "Ctrl-F", "Ctrl-F", "Ctrl-F", "Ctrl-K", "Backspace", "Backspace", "Ctrl-Y", txt("fbar"));
+ sim("gotoLine", "0\n1\n2\n3", dialog("3"), "Alt-G", "G", at(2, 0));
+ sim("gotoInvalidLineFloat", "0\n1\n2\n3", dialog("2.2"), "Alt-G", "G", at(0, 0));
+
+ testCM("gotoDialogTemplate", function(cm) {
+ cm.openDialog = function(template, cb) {
+ var input = template.querySelector("input");
+ eq(template.textContent, "Goto line: ");
+ eq(input.tagName, "INPUT");
+ };
+ cm.triggerOnKeyDown(fakeEvent("Alt-G"));
+ cm.triggerOnKeyDown(fakeEvent("G"));
+ }, {value: "", keyMap: "emacs"});
+
testCM("save", function(cm) {
var saved = false;
CodeMirror.commands.save = function(cm) { saved = cm.getValue(); };
@@ -140,10 +155,4 @@
cm.triggerOnKeyDown(fakeEvent("Ctrl-S"));
is(saved, "hi");
}, {value: "hi", keyMap: "emacs"});
-
- testCM("gotoInvalidLineFloat", function(cm) {
- cm.openDialog = function(_, cb) { cb("2.2"); };
- cm.triggerOnKeyDown(fakeEvent("Alt-G"));
- cm.triggerOnKeyDown(fakeEvent("G"));
- }, {value: "1\n2\n3\n4", keyMap: "emacs"});
})();
diff --git a/help3/xhpeditor/cm/test/index.html b/help3/xhpeditor/cm/test/index.html
index 13f2b6dc..3369beac 100644
--- a/help3/xhpeditor/cm/test/index.html
+++ b/help3/xhpeditor/cm/test/index.html
@@ -57,6 +57,7 @@
<script src="../mode/rust/rust.js"></script>
<script src="../mode/mscgen/mscgen.js"></script>
<script src="../mode/dylan/dylan.js"></script>
+<script src="../mode/wast/wast.js"></script>
<style>
.ok { color: #090; }
@@ -147,6 +148,7 @@
<script src="../mode/xquery/test.js"></script>
<script src="../mode/python/test.js"></script>
<script src="../mode/rust/test.js"></script>
+ <script src="../mode/wast/test.js"></script>
<script src="../mode/mscgen/mscgen_test.js"></script>
<script src="../mode/mscgen/xu_test.js"></script>
<script src="../mode/mscgen/msgenny_test.js"></script>
@@ -154,12 +156,15 @@
<script src="../addon/mode/multiplex_test.js"></script>
<script src="../addon/fold/foldcode.js"></script>
<script src="../addon/fold/brace-fold.js"></script>
+ <script src="../addon/fold/xml-fold.js"></script>
+ <script src="../addon/scroll/annotatescrollbar.js"></script>
<script src="emacs_test.js"></script>
<script src="sql-hint-test.js"></script>
<script src="sublime_test.js"></script>
<script src="vim_test.js"></script>
<script src="html-hint-test.js"></script>
+ <script src="annotatescrollbar.js"></script>
<script>
window.onload = runHarness;
CodeMirror.on(window, 'hashchange', runHarness);
diff --git a/help3/xhpeditor/cm/test/lint.js b/help3/xhpeditor/cm/test/lint.js
index e7c114cd..561f1462 100644
--- a/help3/xhpeditor/cm/test/lint.js
+++ b/help3/xhpeditor/cm/test/lint.js
@@ -3,7 +3,7 @@ var blint = require("blint");
["mode", "lib", "addon", "keymap"].forEach(function(dir) {
blint.checkDir(dir, {
browser: true,
- allowedGlobals: ["CodeMirror", "define", "test", "requirejs"],
+ allowedGlobals: ["CodeMirror", "define", "test", "requirejs", "globalThis", "WeakSet"],
ecmaVersion: 5,
tabs: dir == "lib"
});
@@ -12,6 +12,7 @@ var blint = require("blint");
["src"].forEach(function(dir) {
blint.checkDir(dir, {
browser: true,
+ allowedGlobals: ["WeakSet"],
ecmaVersion: 6,
semicolons: false
});
diff --git a/help3/xhpeditor/cm/test/run.js b/help3/xhpeditor/cm/test/run.js
index 7e4b3897..914cb976 100755
--- a/help3/xhpeditor/cm/test/run.js
+++ b/help3/xhpeditor/cm/test/run.js
@@ -1,6 +1,6 @@
#!/usr/bin/env node
-var ok = require("./lint").ok;
+var lint = require("./lint");
var files = new (require('node-static').Server)();
@@ -34,7 +34,7 @@ var server = require('http').createServer(function (req, res) {
for (let error of errors) console.log(error)
console.log(await page.evaluate(() => document.getElementById('output').innerText + "\n" +
document.getElementById('status').innerText))
- process.exit(failed > 0 || errors.length ? 1 : 0)
+ process.exit(failed > 0 || errors.length || !lint.ok ? 1 : 0)
await browser.close()
})())
diff --git a/help3/xhpeditor/cm/test/test.js b/help3/xhpeditor/cm/test/test.js
index 2a5101f4..07fa6785 100644
--- a/help3/xhpeditor/cm/test/test.js
+++ b/help3/xhpeditor/cm/test/test.js
@@ -1807,8 +1807,8 @@ testCM("atomicMarker", function(cm) {
inclusiveRight: ri
};
- if (ls === true || ls === false) options["selectLeft"] = ls;
- if (rs === true || rs === false) options["selectRight"] = rs;
+ if (ls === true || ls === false) options.selectLeft = ls;
+ if (rs === true || rs === false) options.selectRight = rs;
return cm.markText(Pos(ll, cl), Pos(lr, cr), options);
}
diff --git a/help3/xhpeditor/cm/test/vim_test.js b/help3/xhpeditor/cm/test/vim_test.js
index 577a80b1..20eabf5c 100644
--- a/help3/xhpeditor/cm/test/vim_test.js
+++ b/help3/xhpeditor/cm/test/vim_test.js
@@ -197,13 +197,13 @@ function testVim(name, run, opts, expectedFail) {
}
}
function fakeOpenDialog(result) {
- return function(text, callback) {
+ return function(template, callback) {
return callback(result);
}
}
function fakeOpenNotification(matcher) {
- return function(text) {
- matcher(text);
+ return function(template) {
+ matcher(template.innerHTML);
}
}
var helpers = {
@@ -396,6 +396,7 @@ testMotion('_', ['6','_'], makeCursor(5, lines[5].textStart), makeCursor(0, 8));
testMotion('$', '$', makeCursor(0, lines[0].length - 1), makeCursor(0, 1));
testMotion('$_repeat', ['2', '$'], makeCursor(1, lines[1].length - 1),
makeCursor(0, 3));
+testMotion('$', ['v', '$'], makeCursor(0, lines[0].length), makeCursor(0, 1));
testMotion('f', ['f', 'p'], pChars[0], makeCursor(charLine.line, 0));
testMotion('f_repeat', ['2', 'f', 'p'], pChars[2], pChars[0]);
testMotion('f_num', ['f', '2'], numChars[2], makeCursor(charLine.line, 0));
@@ -494,7 +495,7 @@ testVim('j_k_and_gj_gk', function(cm,vim,helpers){
//should return to the same character-index
helpers.doKeys('k');
helpers.assertCursorAt(0, 176);
-},{ lineWrapping:true, value: 'This line is intentially long to test movement of gj and gk over wrapped lines. I will start on the end of this line, then make a step up and back to set the origin for j and k.\nThis line is supposed to be even longer than the previous. I will jump here and make another wiggle with gj and gk, before I jump back to the line above. Both wiggles should not change my cursor\'s target character but both j/k and gj/gk change each other\'s reference position.'});
+},{ lineWrapping:true, value: 'This line is intentionally long. It tests movements of gj and gk over wrapped lines. Starts on the end of this line, then makes a step up and back to set the origin for j and k.\nThis line is supposed to be even longer than the previous. I will jump here and make another wiggle with gj and gk, before I jump back to the line above. Both wiggles should not change my cursor\'s target character but both j/k and gj/gk change each other\'s reference position.'});
testVim('gj_gk', function(cm, vim, helpers) {
cm.setSize(120);
// Test top of document edge case.
@@ -1152,6 +1153,41 @@ testVim('s_visual_block', function(cm, vim, helpers) {
eq('1hello{\n world\n', cm.getValue());
}, {value: '1234\n5678\nabcdefg\n'});
+// Test mode change event. It should only fire once per mode transition.
+testVim('on_mode_change', function(cm, vim, helpers) {
+ var modeHist = [];
+ function callback(arg) {
+ var subMode = arg.subMode ? ':' + arg.subMode : '';
+ modeHist.push(arg.mode + subMode);
+ }
+ helpers.doKeys('<Esc>', '<Esc>');
+ cm.on('vim-mode-change', callback);
+ function test(key, mode) {
+ modeHist.length = 0;
+ helpers.doKeys(key);
+ eq(modeHist.join(';'), mode);
+ }
+ test('v', 'visual');
+ test('c', 'insert');
+ test('<Esc>', 'normal');
+ test('<C-v>', 'visual:blockwise');
+ test('I', 'insert');
+ test('<Esc>', 'normal');
+ test('R', 'replace');
+ test('x', '');
+ test('<C-[>', 'normal');
+ test('v', 'visual');
+ test('V', 'visual:linewise');
+ test('<C-v>', 'visual:blockwise');
+ test('v', 'visual');
+ test('<C-c>', 'normal');
+ test('a', 'insert');
+ test('<Esc>', 'normal');
+ test('v', 'visual');
+ test(':', ''); // Event for Command-line mode not implemented.
+ test('y', 'normal');
+});
+
// Swapcase commands edit in place and do not modify registers.
testVim('g~w_repeat', function(cm, vim, helpers) {
// Assert that dw does delete newline if it should go to the next line, and
@@ -1281,9 +1317,13 @@ testVim('=', function(cm, vim, helpers) {
eq(expectedValue, cm.getValue());
}, { value: ' word1\n word2\n word3', indentUnit: 2 });
-// Edit tests
-function testEdit(name, before, pos, edit, after) {
+// Edit tests - configureCm is an optional argument that gives caller
+// access to the cm object.
+function testEdit(name, before, pos, edit, after, configureCm) {
return testVim(name, function(cm, vim, helpers) {
+ if (configureCm) {
+ configureCm(cm);
+ }
var ch = before.search(pos)
var line = before.substring(0, ch).split('\n').length - 1;
if (line) {
@@ -1388,6 +1428,28 @@ testEdit('di>_middle_spc', 'a\t<\n\tbar\n>b', /r/, 'di>', 'a\t<>b');
testEdit('da<_middle_spc', 'a\t<\n\tbar\n>b', /r/, 'da<', 'a\tb');
testEdit('da>_middle_spc', 'a\t<\n\tbar\n>b', /r/, 'da>', 'a\tb');
+// deleting tag objects
+testEdit('dat_noop', '<outer><inner>hello</inner></outer>', /n/, 'dat', '<outer><inner>hello</inner></outer>');
+testEdit('dat_open_tag', '<outer><inner>hello</inner></outer>', /n/, 'dat', '<outer></outer>', function(cm) {
+ cm.setOption('mode', 'xml');
+});
+testEdit('dat_inside_tag', '<outer><inner>hello</inner></outer>', /l/, 'dat', '<outer></outer>', function(cm) {
+ cm.setOption('mode', 'xml');
+});
+testEdit('dat_close_tag', '<outer><inner>hello</inner></outer>', /\//, 'dat', '<outer></outer>', function(cm) {
+ cm.setOption('mode', 'xml');
+});
+
+testEdit('dit_open_tag', '<outer><inner>hello</inner></outer>', /n/, 'dit', '<outer><inner></inner></outer>', function(cm) {
+ cm.setOption('mode', 'xml');
+});
+testEdit('dit_inside_tag', '<outer><inner>hello</inner></outer>', /l/, 'dit', '<outer><inner></inner></outer>', function(cm) {
+ cm.setOption('mode', 'xml');
+});
+testEdit('dit_close_tag', '<outer><inner>hello</inner></outer>', /\//, 'dit', '<outer><inner></inner></outer>', function(cm) {
+ cm.setOption('mode', 'xml');
+});
+
function testSelection(name, before, pos, keys, sel) {
return testVim(name, function(cm, vim, helpers) {
var ch = before.search(pos)
@@ -2517,6 +2579,91 @@ testVim('/ and n/N', function(cm, vim, helpers) {
helpers.doKeys('2', '/');
helpers.assertCursorAt(1, 6);
}, { value: 'match nope match \n nope Match' });
+testVim('/ and gn selects the appropriate word', function(cm, vim, helpers) {
+ cm.openDialog = helpers.fakeOpenDialog('match');
+ helpers.doKeys('/');
+ helpers.assertCursorAt(0, 11);
+
+ // gn should highlight the the current word while it is within a match.
+
+ // gn when cursor is in beginning of match
+ helpers.doKeys('gn', '<Esc>');
+ helpers.assertCursorAt(0, 15);
+
+ // gn when cursor is at end of match
+ helpers.doKeys('gn', '<Esc>');
+ helpers.doKeys('<Esc>');
+ helpers.assertCursorAt(0, 15);
+
+ // consecutive gns should extend the selection
+ helpers.doKeys('gn');
+ helpers.assertCursorAt(0, 16);
+ helpers.doKeys('gn');
+ helpers.assertCursorAt(1, 11);
+
+ // we should have selected the second and third "match"
+ helpers.doKeys('d');
+ eq('match nope ', cm.getValue());
+}, { value: 'match nope match \n nope Match' });
+testVim('/ and gN selects the appropriate word', function(cm, vim, helpers) {
+ cm.openDialog = helpers.fakeOpenDialog('match');
+ helpers.doKeys('/');
+ helpers.assertCursorAt(0, 11);
+
+ // gN when cursor is at beginning of match
+ helpers.doKeys('gN', '<Esc>');
+ helpers.assertCursorAt(0, 11);
+
+ // gN when cursor is at end of match
+ helpers.doKeys('e', 'gN', '<Esc>');
+ helpers.assertCursorAt(0, 11);
+
+ // consecutive gNs should extend the selection
+ helpers.doKeys('gN');
+ helpers.assertCursorAt(0, 11);
+ helpers.doKeys('gN');
+ helpers.assertCursorAt(0, 0);
+
+ // we should have selected the first and second "match"
+ helpers.doKeys('d');
+ eq(' \n nope Match', cm.getValue());
+}, { value: 'match nope match \n nope Match' })
+testVim('/ and gn with an associated operator', function(cm, vim, helpers) {
+ cm.openDialog = helpers.fakeOpenDialog('match');
+ helpers.doKeys('/');
+ helpers.assertCursorAt(0, 11);
+
+ helpers.doKeys('c', 'gn', 'changed', '<Esc>');
+
+ // change the current match.
+ eq('match nope changed \n nope Match', cm.getValue());
+
+ // change the next match.
+ helpers.doKeys('.');
+ eq('match nope changed \n nope changed', cm.getValue());
+
+ // change the final match.
+ helpers.doKeys('.');
+ eq('changed nope changed \n nope changed', cm.getValue());
+}, { value: 'match nope match \n nope Match' });
+testVim('/ and gN with an associated operator', function(cm, vim, helpers) {
+ cm.openDialog = helpers.fakeOpenDialog('match');
+ helpers.doKeys('/');
+ helpers.assertCursorAt(0, 11);
+
+ helpers.doKeys('c', 'gN', 'changed', '<Esc>');
+
+ // change the current match.
+ eq('match nope changed \n nope Match', cm.getValue());
+
+ // change the next match.
+ helpers.doKeys('.');
+ eq('changed nope changed \n nope Match', cm.getValue());
+
+ // change the final match.
+ helpers.doKeys('.');
+ eq('changed nope changed \n nope changed', cm.getValue());
+}, { value: 'match nope match \n nope Match' });
testVim('/_case', function(cm, vim, helpers) {
cm.openDialog = helpers.fakeOpenDialog('Match');
helpers.doKeys('/');
@@ -2617,6 +2764,90 @@ testVim('? and n/N', function(cm, vim, helpers) {
helpers.doKeys('2', '?');
helpers.assertCursorAt(0, 11);
}, { value: 'match nope match \n nope Match' });
+testVim('? and gn selects the appropriate word', function(cm, vim, helpers) {
+ cm.openDialog = helpers.fakeOpenDialog('match');
+ helpers.doKeys('?', 'n');
+ helpers.assertCursorAt(0, 11);
+
+ // gn should highlight the the current word while it is within a match.
+
+ // gn when cursor is in beginning of match
+ helpers.doKeys('gn', '<Esc>');
+ helpers.assertCursorAt(0, 11);
+
+ // gn when cursor is at end of match
+ helpers.doKeys('e', 'gn', '<Esc>');
+ helpers.assertCursorAt(0, 11);
+
+ // consecutive gns should extend the selection
+ helpers.doKeys('gn');
+ helpers.assertCursorAt(0, 11);
+ helpers.doKeys('gn');
+ helpers.assertCursorAt(0, 0);
+
+ // we should have selected the first and second "match"
+ helpers.doKeys('d');
+ eq(' \n nope Match', cm.getValue());
+}, { value: 'match nope match \n nope Match' });
+testVim('? and gN selects the appropriate word', function(cm, vim, helpers) {
+ cm.openDialog = helpers.fakeOpenDialog('match');
+ helpers.doKeys('?', 'n');
+ helpers.assertCursorAt(0, 11);
+
+ // gN when cursor is at beginning of match
+ helpers.doKeys('gN', '<Esc>');
+ helpers.assertCursorAt(0, 15);
+
+ // gN when cursor is at end of match
+ helpers.doKeys('gN', '<Esc>');
+ helpers.assertCursorAt(0, 15);
+
+ // consecutive gNs should extend the selection
+ helpers.doKeys('gN');
+ helpers.assertCursorAt(0, 16);
+ helpers.doKeys('gN');
+ helpers.assertCursorAt(1, 11);
+
+ // we should have selected the second and third "match"
+ helpers.doKeys('d');
+ eq('match nope ', cm.getValue());
+}, { value: 'match nope match \n nope Match' })
+testVim('? and gn with an associated operator', function(cm, vim, helpers) {
+ cm.openDialog = helpers.fakeOpenDialog('match');
+ helpers.doKeys('?', 'n');
+ helpers.assertCursorAt(0, 11);
+
+ helpers.doKeys('c', 'gn', 'changed', '<Esc>');
+
+ // change the current match.
+ eq('match nope changed \n nope Match', cm.getValue());
+
+ // change the next match.
+ helpers.doKeys('.');
+ eq('changed nope changed \n nope Match', cm.getValue());
+
+ // change the final match.
+ helpers.doKeys('.');
+ eq('changed nope changed \n nope changed', cm.getValue());
+}, { value: 'match nope match \n nope Match' });
+testVim('? and gN with an associated operator', function(cm, vim, helpers) {
+ cm.openDialog = helpers.fakeOpenDialog('match');
+ helpers.doKeys('?', 'n');
+ helpers.assertCursorAt(0, 11);
+
+ helpers.doKeys('c', 'gN', 'changed', '<Esc>');
+
+ // change the current match.
+ eq('match nope changed \n nope Match', cm.getValue());
+
+ // change the next match.
+ helpers.doKeys('.');
+ eq('match nope changed \n nope changed', cm.getValue());
+
+ // change the final match.
+ helpers.doKeys('.');
+ eq('changed nope changed \n nope changed', cm.getValue());
+}, { value: 'match nope match \n nope Match' });
testVim('*', function(cm, vim, helpers) {
cm.setCursor(0, 9);
helpers.doKeys('*');
@@ -2884,6 +3115,23 @@ testVim('yank_append_word_to_line_register', function(cm, vim, helpers) {
});
helpers.doKeys(':');
}, { value: 'foo\nbar'});
+testVim('black_hole_register', function(cm,vim,helpers) {
+ helpers.doKeys('g', 'g', 'y', 'G');
+ var registersText;
+ cm.openDialog = helpers.fakeOpenDialog('registers');
+ cm.openNotification = helpers.fakeOpenNotification(function(text) {
+ registersText = text;
+ });
+ helpers.doKeys(':');
+ helpers.doKeys('"', '_', 'd', 'G');
+ cm.openDialog = helpers.fakeOpenDialog('registers');
+ cm.openNotification = helpers.fakeOpenNotification(function(text) {
+ eq(registersText, text, 'One or more registers were modified');
+ });
+ helpers.doKeys(':');
+ helpers.doKeys('"', '_', 'p');
+ eq('', cm.getValue());
+}, { value: 'foo\nbar'});
testVim('macro_register', function(cm, vim, helpers) {
cm.setCursor(0, 0);
helpers.doKeys('q', 'a', 'i');
@@ -2920,6 +3168,13 @@ testVim(':_register', function(cm,vim,helpers) {
});
helpers.doKeys(':');
}, {value: ''});
+testVim('registers_html_encoding', function(cm,vim,helpers) {
+ helpers.doKeys('y', 'y');
+ cm.openNotification = helpers.fakeOpenNotification(function(text) {
+ is(/"\s+&lt;script&gt;throw "&amp;amp;"&lt;\/script&gt;/.test(text));
+ });
+ helpers.doEx('registers');
+}, {value: '<script>throw "&amp;"</script>'});
testVim('search_register_escape', function(cm, vim, helpers) {
// Check that the register is restored if the user escapes rather than confirms.
cm.openDialog = helpers.fakeOpenDialog('waldo');
@@ -3815,10 +4070,22 @@ testVim('ex_sort_pattern_alpha_num', function(cm, vim, helpers) {
testVim('ex_global', function(cm, vim, helpers) {
cm.setCursor(0, 0);
helpers.doEx('g/one/s//two');
- eq('two two\n two two\n two two', cm.getValue());
+ eq('two one\n two one\n two one', cm.getValue());
helpers.doEx('1,2g/two/s//one');
- eq('one one\n one one\n two two', cm.getValue());
+ eq('one one\n one one\n two one', cm.getValue());
+ cm.openNotification = helpers.fakeOpenNotification(function(text) {
+ eq(' one one\n two one', text);
+ });
+ helpers.doEx('g/^ /');
}, {value: 'one one\n one one\n one one'});
+testVim('ex_global_substitute_join', function(cm, vim, helpers) {
+ helpers.doEx('g/o/s/\\n/;');
+ eq('one;two\nthree\nfour;five\n', cm.getValue());
+}, {value: 'one\ntwo\nthree\nfour\nfive\n'});
+testVim('ex_global_substitute_split', function(cm, vim, helpers) {
+ helpers.doEx('g/e/s/[or]/\\n');
+ eq('\nne\ntwo\nth\nee\nfour\nfive\n', cm.getValue());
+}, {value: 'one\ntwo\nthree\nfour\nfive\n'});
testVim('ex_global_confirm', function(cm, vim, helpers) {
cm.setCursor(0, 0);
var onKeyDown;
@@ -3846,6 +4113,15 @@ testVim('ex_global_confirm', function(cm, vim, helpers) {
onKeyDown({keyCode: KEYCODES.y}, '', close);
eq('one two\n two two\n one one\n two one\n one one', cm.getValue());
}, {value: 'one one\n one one\n one one\n one one\n one one'});
+// test for :vglobal command
+testVim('ex_vglobal', function(cm, vim, helpers) {
+ helpers.doEx('v/e/s/o/e');
+ eq('one\n twe\n three\n feur\n five\n', cm.getValue());
+ cm.openNotification = helpers.fakeOpenNotification(function(text) {
+ eq('one\n three\n feur\n', text);
+ });
+ helpers.doEx('v/[vw]');
+}, {value: 'one\n two\n three\n four\n five\n'});
// Basic substitute tests.
testVim('ex_substitute_same_line', function(cm, vim, helpers) {
cm.setCursor(1, 0);
@@ -4044,18 +4320,38 @@ testSubstitute('ex_substitute_multibackslash_replacement', {
value: 'one,two \n three,four',
expectedValue: 'one\\\\\\\\two \n three\\\\\\\\four', // 2*8 backslashes.
expr: '%s/,/\\\\\\\\\\\\\\\\/g'}); // 16 backslashes.
-testSubstitute('ex_substitute_dollar_match', {
+testSubstitute('ex_substitute_dollar_assertion', {
value: 'one,two \n three,four',
- expectedValue: 'one,two ,\n three,four',
+ expectedValue: 'one,two ,\n three,four', // TODO: should match at end of doc.
expr: '%s/$/,/g'});
+testSubstitute('ex_substitute_dollar_literal', {
+ value: 'one$two\n$three\nfour$\n$',
+ expectedValue: 'one,two\n,three\nfour,\n,',
+ expr: '%s/\\$/,/g'});
testSubstitute('ex_substitute_newline_match', {
value: 'one,two \n three,four',
expectedValue: 'one,two , three,four',
expr: '%s/\\n/,/g'});
+testSubstitute('ex_substitute_newline_join_global', {
+ value: 'one,two \n three,four \n five \n six',
+ expectedValue: 'one,two \n three,four , five \n six',
+ expr: '2s/\\n/,/g'});
+testSubstitute('ex_substitute_newline_join_noglobal', {
+ value: 'one,two \n three,four \n five \n six\n',
+ expectedValue: 'one,two \n three,four , five , six\n',
+ expr: '2,3s/\\n/,/'});
testSubstitute('ex_substitute_newline_replacement', {
- value: 'one,two \n three,four',
- expectedValue: 'one\ntwo \n three\nfour',
+ value: 'one,two, \n three,four,',
+ expectedValue: 'one\ntwo\n \n three\nfour\n',
expr: '%s/,/\\n/g'});
+testSubstitute('ex_substitute_newline_multiple_splits', {
+ value: 'one,two, \n three,four,five,six, \n seven,',
+ expectedValue: 'one,two, \n three\nfour\nfive\nsix\n \n seven,',
+ expr: '2s/,/\\n/g'});
+testSubstitute('ex_substitute_newline_first_occurrences', {
+ value: 'one,two, \n three,four,five,six, \n seven,',
+ expectedValue: 'one\ntwo, \n three\nfour,five,six, \n seven\n',
+ expr: '%s/,/\\n/'});
testSubstitute('ex_substitute_braces_word', {
value: 'ababab abb ab{2}',
expectedValue: 'ab abb ab{2}',
@@ -4478,6 +4774,37 @@ testVim('ex_api_test', function(cm, vim, helpers) {
is(res,'Mapping to key failed');
CodeMirror.Vim.mapclear();
});
+// Testing ex-commands with non-alpha names.
+testVim('ex_special_names', function(cm, vim, helpers) {
+ var ran,val;
+ var cmds = ['!','!!','#','&','*','<','=','>','@','@@','~','regtest1','RT2'];
+ cmds.forEach(function(name){
+ CodeMirror.Vim.defineEx(name,'',function(cm,params){
+ ran=params.commandName;
+ val=params.argString;
+ });
+ helpers.doEx(':'+name);
+ eq(ran,name,'Running ex-command failed');
+ helpers.doEx(':'+name+' x');
+ eq(val,' x','Running ex-command with param failed: '+name);
+ if(/^\W+$/.test(name)){
+ helpers.doEx(':'+name+'y');
+ eq(val,'y','Running ex-command with param failed: '+name);
+ }
+ else{
+ helpers.doEx(':'+name+'-y');
+ eq(val,'-y','Running ex-command with param failed: '+name);
+ }
+ if(name!=='!'){
+ helpers.doEx(':'+name+'!');
+ eq(ran,name,'Running ex-command with bang failed');
+ eq(val,'!','Running ex-command with bang failed: '+name);
+ helpers.doEx(':'+name+'!z');
+ eq(ran,name,'Running ex-command with bang & param failed');
+ eq(val,'!z','Running ex-command with bang & param failed: '+name);
+ }
+ });
+});
// For now, this test needs to be last because it messes up : for future tests.
testVim('ex_map_key2key_from_colon', function(cm, vim, helpers) {
helpers.doEx('map : x');
diff --git a/help3/xhpeditor/cm/theme/abbott.css b/help3/xhpeditor/cm/theme/abbott.css
new file mode 100644
index 00000000..3e516a67
--- /dev/null
+++ b/help3/xhpeditor/cm/theme/abbott.css
@@ -0,0 +1,268 @@
+/*
+ * abbott.css
+ * A warm, dark theme for prose and code, with pastels and pretty greens.
+ *
+ * Ported from abbott.vim (https://github.com/bcat/abbott.vim) version 2.1.
+ * Original design and CodeMirror port by Jonathan Rascher.
+ *
+ * This theme shares the following color palette with the Vim color scheme.
+ *
+ * Brown shades:
+ * bistre: #231c14
+ * chocolate: #3c3022
+ * cocoa: #745d42
+ * vanilla_cream: #fef3b4
+ *
+ * Red shades:
+ * crimson: #d80450
+ * cinnabar: #f63f05
+ *
+ * Green shades:
+ * dark_olive: #273900
+ * forest_green: #24a507
+ * chartreuse: #a0ea00
+ * pastel_chartreuse: #d8ff84
+ *
+ * Yellow shades:
+ * marigold: #fbb32f
+ * lemon_meringue: #fbec5d
+ *
+ * Blue shades:
+ * cornflower_blue: #3f91f1
+ * periwinkle_blue: #8ccdf0
+ *
+ * Magenta shades:
+ * french_pink: #ec6c99
+ * lavender: #e6a2f3
+ *
+ * Cyan shades:
+ * zomp: #39a78d
+ * seafoam_green: #00ff7f
+ */
+
+/* Style the UI: */
+
+/* Equivalent to Vim's Normal group. */
+.cm-s-abbott.CodeMirror {
+ background: #231c14 /* bistre */;
+ color: #d8ff84 /* pastel_chartreuse */;
+}
+
+/* Roughly equivalent to Vim's LineNr group. */
+.cm-s-abbott .CodeMirror-gutters {
+ background: #231c14 /* bistre */;
+ border: none;
+}
+.cm-s-abbott .CodeMirror-linenumber { color: #fbec5d /* lemon_meringue */; }
+
+.cm-s-abbott .CodeMirror-guttermarker { color: #f63f05 /* cinnabar */; }
+
+/* Roughly equivalent to Vim's FoldColumn group. */
+.cm-s-abbott .CodeMirror-guttermarker-subtle { color: #fbb32f /* marigold */; }
+
+/*
+ * Roughly equivalent to Vim's CursorColumn group. (We use a brighter color
+ * since Vim's cursorcolumn option highlights a whole column, whereas
+ * CodeMirror's rule just highlights a thin line.)
+ */
+.cm-s-abbott .CodeMirror-ruler { border-color: #745d42 /* cocoa */; }
+
+/* Equivalent to Vim's Cursor group in insert mode. */
+.cm-s-abbott .CodeMirror-cursor { border-color: #a0ea00 /* chartreuse */; }
+
+/* Equivalent to Vim's Cursor group in normal mode. */
+.cm-s-abbott.cm-fat-cursor .CodeMirror-cursor,
+.cm-s-abbott .cm-animate-fat-cursor {
+ /*
+ * CodeMirror doesn't allow changing the foreground color of the character
+ * under the cursor, so we can't use a reverse video effect for the cursor.
+ * Instead, make it semitransparent.
+ */
+ background: rgba(160, 234, 0, 0.5) /* chartreuse */;
+}
+.cm-s-abbott.cm-fat-cursor .CodeMirror-cursors {
+ /*
+ * Boost the z-index so the fat cursor shows up on top of text and
+ * matchingbracket/matchingtag highlights.
+ */
+ z-index: 3;
+}
+
+/* Equivalent to Vim's Cursor group in replace mode. */
+.cm-s-abbott .CodeMirror-overwrite .CodeMirror-cursor {
+ border-bottom: 1px solid #a0ea00 /* chartreuse */;
+ border-left: none;
+ width: auto;
+}
+
+/* Roughly equivalent to Vim's CursorIM group. */
+.cm-s-abbott .CodeMirror-secondarycursor {
+ border-color: #00ff7f /* seafoam_green */;
+}
+
+/* Roughly equivalent to Vim's Visual group. */
+.cm-s-abbott .CodeMirror-selected,
+.cm-s-abbott.CodeMirror-focused .CodeMirror-selected {
+ background: #273900 /* dark_olive */;
+}
+.cm-s-abbott .CodeMirror-line::selection,
+.cm-s-abbott .CodeMirror-line > span::selection,
+.cm-s-abbott .CodeMirror-line > span > span::selection {
+ background: #273900 /* dark_olive */;
+}
+.cm-s-abbott .CodeMirror-line::-moz-selection,
+.cm-s-abbott .CodeMirror-line > span::-moz-selection,
+.cm-s-abbott .CodeMirror-line > span > span::-moz-selection {
+ background: #273900 /* dark_olive */;
+}
+
+/* Roughly equivalent to Vim's SpecialKey group. */
+.cm-s-abbott .cm-tab { color: #00ff7f /* seafoam_green */; }
+
+/* Equivalent to Vim's Search group. */
+.cm-s-abbott .cm-searching {
+ background: #fef3b4 /* vanilla_cream */ !important;
+ color: #231c14 /* bistre */ !important;
+}
+
+/* Style syntax highlighting modes: */
+
+/* Equivalent to Vim's Comment group. */
+.cm-s-abbott span.cm-comment {
+ color: #fbb32f /* marigold */;
+ font-style: italic;
+}
+
+/* Equivalent to Vim's String group. */
+.cm-s-abbott span.cm-string,
+.cm-s-abbott span.cm-string-2 {
+ color: #e6a2f3 /* lavender */;
+}
+
+/* Equivalent to Vim's Constant group. */
+.cm-s-abbott span.cm-number,
+.cm-s-abbott span.cm-string.cm-url { color: #f63f05 /* cinnabar */; }
+
+/* Roughly equivalent to Vim's SpecialKey group. */
+.cm-s-abbott span.cm-invalidchar { color: #00ff7f /* seafoam_green */; }
+
+/* Equivalent to Vim's Special group. */
+.cm-s-abbott span.cm-atom { color: #fef3b4 /* vanilla_cream */; }
+
+/* Equivalent to Vim's Delimiter group. */
+.cm-s-abbott span.cm-bracket,
+.cm-s-abbott span.cm-punctuation {
+ color: #fef3b4 /* vanilla_cream */;
+}
+
+/* Equivalent Vim's Operator group. */
+.cm-s-abbott span.cm-operator { font-weight: bold; }
+
+/* Roughly equivalent to Vim's Identifier group. */
+.cm-s-abbott span.cm-def,
+.cm-s-abbott span.cm-variable,
+.cm-s-abbott span.cm-variable-2,
+.cm-s-abbott span.cm-variable-3 {
+ color: #8ccdf0 /* periwinkle_blue */;
+}
+
+/* Roughly equivalent to Vim's Function group. */
+.cm-s-abbott span.cm-builtin,
+.cm-s-abbott span.cm-property,
+.cm-s-abbott span.cm-qualifier {
+ color: #3f91f1 /* cornflower_blue */;
+}
+
+/* Equivalent to Vim's Type group. */
+.cm-s-abbott span.cm-type { color: #24a507 /* forest_green */; }
+
+/* Equivalent to Vim's Keyword group. */
+.cm-s-abbott span.cm-keyword {
+ color: #d80450 /* crimson */;
+ font-weight: bold;
+}
+
+/* Equivalent to Vim's PreProc group. */
+.cm-s-abbott span.cm-meta { color: #ec6c99 /* french_pink */; }
+
+/* Equivalent to Vim's htmlTagName group (linked to Statement). */
+.cm-s-abbott span.cm-tag {
+ color: #d80450 /* crimson */;
+ font-weight: bold;
+}
+
+/* Equivalent to Vim's htmlArg group (linked to Type). */
+.cm-s-abbott span.cm-attribute { color: #24a507 /* forest_green */; }
+
+/* Equivalent to Vim's htmlH1, markdownH1, etc. groups (linked to Title). */
+.cm-s-abbott span.cm-header {
+ color: #d80450 /* crimson */;
+ font-weight: bold;
+}
+
+/* Equivalent to Vim's markdownRule group (linked to PreProc). */
+.cm-s-abbott span.cm-hr { color: #ec6c99 /* french_pink */; }
+
+/* Roughly equivalent to Vim's Underlined group. */
+.cm-s-abbott span.cm-link { color: #e6a2f3 /* lavender */; }
+
+/* Equivalent to Vim's diffRemoved group. */
+.cm-s-abbott span.cm-negative {
+ background: #d80450 /* crimson */;
+ color: #231c14 /* bistre */;
+}
+
+/* Equivalent to Vim's diffAdded group. */
+.cm-s-abbott span.cm-positive {
+ background: #a0ea00 /* chartreuse */;
+ color: #231c14 /* bistre */;
+ font-weight: bold;
+}
+
+/* Equivalent to Vim's Error group. */
+.cm-s-abbott span.cm-error {
+ background: #d80450 /* crimson */;
+ color: #231c14 /* bistre */;
+}
+
+/* Style addons: */
+
+/* Equivalent to Vim's MatchParen group. */
+.cm-s-abbott span.CodeMirror-matchingbracket {
+ background: #745d42 /* cocoa */ !important;
+ color: #231c14 /* bistre */ !important;
+ font-weight: bold;
+}
+
+/*
+ * Roughly equivalent to Vim's Error group. (Vim doesn't seem to have a direct
+ * equivalent in its own matchparen plugin, but many syntax highlighting plugins
+ * mark mismatched brackets as Error.)
+ */
+.cm-s-abbott span.CodeMirror-nonmatchingbracket {
+ background: #d80450 /* crimson */ !important;
+ color: #231c14 /* bistre */ !important;
+}
+
+.cm-s-abbott .CodeMirror-matchingtag,
+.cm-s-abbott .cm-matchhighlight {
+ outline: 1px solid #39a78d /* zomp */;
+}
+
+/* Equivalent to Vim's CursorLine group. */
+.cm-s-abbott .CodeMirror-activeline-background,
+.cm-s-abbott .CodeMirror-activeline-gutter {
+ background: #3c3022 /* chocolate */;
+}
+
+/* Equivalent to Vim's CursorLineNr group. */
+.cm-s-abbott .CodeMirror-activeline-gutter .CodeMirror-linenumber {
+ color: #d8ff84 /* pastel_chartreuse */;
+ font-weight: bold;
+}
+
+/* Roughly equivalent to Vim's Folded group. */
+.cm-s-abbott .CodeMirror-foldmarker {
+ color: #f63f05 /* cinnabar */;
+ text-shadow: none;
+}
diff --git a/help3/xhpeditor/cm/theme/solarized.css b/help3/xhpeditor/cm/theme/solarized.css
index fcd1d70d..9c6b1265 100644
--- a/help3/xhpeditor/cm/theme/solarized.css
+++ b/help3/xhpeditor/cm/theme/solarized.css
@@ -99,7 +99,7 @@ http://ethanschoonover.com/solarized/img/solarized-palette.png
.cm-s-solarized.cm-s-light div.CodeMirror-selected { background: #eee8d5; }
.cm-s-solarized.cm-s-light .CodeMirror-line::selection, .cm-s-light .CodeMirror-line > span::selection, .cm-s-light .CodeMirror-line > span > span::selection { background: #eee8d5; }
-.cm-s-solarized.cm-s-light .CodeMirror-line::-moz-selection, .cm-s-ligh .CodeMirror-line > span::-moz-selection, .cm-s-ligh .CodeMirror-line > span > span::-moz-selection { background: #eee8d5; }
+.cm-s-solarized.cm-s-light .CodeMirror-line::-moz-selection, .cm-s-light .CodeMirror-line > span::-moz-selection, .cm-s-light .CodeMirror-line > span > span::-moz-selection { background: #eee8d5; }
/* Editor styling */
diff --git a/help3/xhpeditor/cm/theme/zenburn.css b/help3/xhpeditor/cm/theme/zenburn.css
index 781c40ac..4eb4247c 100644
--- a/help3/xhpeditor/cm/theme/zenburn.css
+++ b/help3/xhpeditor/cm/theme/zenburn.css
@@ -11,7 +11,7 @@
.cm-s-zenburn .CodeMirror-gutters { background: #3f3f3f !important; }
.cm-s-zenburn .CodeMirror-foldgutter-open, .CodeMirror-foldgutter-folded { color: #999; }
.cm-s-zenburn .CodeMirror-cursor { border-left: 1px solid white; }
-.cm-s-zenburn { background-color: #3f3f3f; color: #dcdccc; }
+.cm-s-zenburn.CodeMirror { background-color: #3f3f3f; color: #dcdccc; }
.cm-s-zenburn span.cm-builtin { color: #dcdccc; font-weight: bold; }
.cm-s-zenburn span.cm-comment { color: #7f9f7f; }
.cm-s-zenburn span.cm-keyword { color: #f0dfaf; font-weight: bold; }