summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--clang/Makefile4
-rw-r--r--clang/README3
-rwxr-xr-xclang/bin/clang-rename-wrapper4
-rw-r--r--clang/find-unprefixed-members.cxx17
-rw-r--r--help3/xhpeditor/cm/AUTHORS23
-rw-r--r--help3/xhpeditor/cm/CHANGELOG.md94
-rw-r--r--help3/xhpeditor/cm/README.md2
-rw-r--r--help3/xhpeditor/cm/addon/fold/brace-fold.js97
-rw-r--r--help3/xhpeditor/cm/addon/fold/foldcode.js10
-rw-r--r--help3/xhpeditor/cm/addon/hint/show-hint.js20
-rw-r--r--help3/xhpeditor/cm/addon/lint/lint.css8
-rw-r--r--help3/xhpeditor/cm/addon/lint/lint.js68
-rw-r--r--help3/xhpeditor/cm/addon/merge/merge.js3
-rw-r--r--help3/xhpeditor/cm/addon/search/search.js40
-rw-r--r--help3/xhpeditor/cm/addon/search/searchcursor.js31
-rw-r--r--help3/xhpeditor/cm/demo/lint.html4
-rw-r--r--help3/xhpeditor/cm/demo/theme.html2
-rw-r--r--help3/xhpeditor/cm/demo/vim.html2
-rw-r--r--help3/xhpeditor/cm/doc/logos/4me.svg1
-rw-r--r--help3/xhpeditor/cm/doc/logos/anvil.pngbin0 -> 9512 bytes
-rw-r--r--help3/xhpeditor/cm/doc/logos/artcompiler.svg1
-rw-r--r--help3/xhpeditor/cm/doc/logos/cargo.svg1
-rw-r--r--help3/xhpeditor/cm/doc/logos/codepen.svg1
-rw-r--r--help3/xhpeditor/cm/doc/logos/desmos.svg1
-rw-r--r--help3/xhpeditor/cm/doc/logos/executeprogram.svg1
-rw-r--r--help3/xhpeditor/cm/doc/logos/holmusk.svg1
-rw-r--r--help3/xhpeditor/cm/doc/logos/jetbrains.svg1
-rw-r--r--help3/xhpeditor/cm/doc/logos/observable.svg1
-rw-r--r--help3/xhpeditor/cm/doc/logos/primo.svg1
-rw-r--r--help3/xhpeditor/cm/doc/logos/prisma.svg1
-rw-r--r--help3/xhpeditor/cm/doc/manual.html7
-rw-r--r--help3/xhpeditor/cm/doc/releases.html73
-rw-r--r--help3/xhpeditor/cm/index.html23
-rw-r--r--help3/xhpeditor/cm/keymap/emacs.js8
-rw-r--r--help3/xhpeditor/cm/keymap/vim.js366
-rw-r--r--help3/xhpeditor/cm/lib/codemirror.css22
-rw-r--r--help3/xhpeditor/cm/lib/codemirror.js74
-rw-r--r--help3/xhpeditor/cm/mode/clike/clike.js2
-rw-r--r--help3/xhpeditor/cm/mode/cobol/cobol.js2
-rw-r--r--help3/xhpeditor/cm/mode/commonlisp/commonlisp.js1
-rw-r--r--help3/xhpeditor/cm/mode/css/css.js50
-rw-r--r--help3/xhpeditor/cm/mode/factor/factor.js2
-rw-r--r--help3/xhpeditor/cm/mode/fortran/fortran.js2
-rw-r--r--help3/xhpeditor/cm/mode/gas/gas.js8
-rw-r--r--help3/xhpeditor/cm/mode/javascript/javascript.js3
-rw-r--r--help3/xhpeditor/cm/mode/julia/julia.js32
-rw-r--r--help3/xhpeditor/cm/mode/meta.js2
-rw-r--r--help3/xhpeditor/cm/mode/mllike/mllike.js2
-rw-r--r--help3/xhpeditor/cm/mode/nsis/nsis.js40
-rw-r--r--help3/xhpeditor/cm/mode/perl/perl.js5
-rw-r--r--help3/xhpeditor/cm/mode/php/php.js6
-rw-r--r--help3/xhpeditor/cm/mode/python/python.js21
-rw-r--r--help3/xhpeditor/cm/mode/python/test.js26
-rw-r--r--help3/xhpeditor/cm/mode/scheme/scheme.js39
-rw-r--r--help3/xhpeditor/cm/mode/soy/soy.js40
-rw-r--r--help3/xhpeditor/cm/mode/soy/test.js11
-rw-r--r--help3/xhpeditor/cm/mode/sql/sql.js8
-rw-r--r--help3/xhpeditor/cm/mode/stylus/stylus.js4
-rw-r--r--help3/xhpeditor/cm/mode/xml/xml.js18
-rw-r--r--help3/xhpeditor/cm/mode/yaml-frontmatter/yaml-frontmatter.js30
-rw-r--r--help3/xhpeditor/cm/package.json2
-rw-r--r--help3/xhpeditor/cm/src/display/Display.js4
-rw-r--r--help3/xhpeditor/cm/src/display/scroll_events.js18
-rw-r--r--help3/xhpeditor/cm/src/display/scrollbars.js1
-rw-r--r--help3/xhpeditor/cm/src/display/selection.js14
-rw-r--r--help3/xhpeditor/cm/src/display/update_lines.js6
-rw-r--r--help3/xhpeditor/cm/src/edit/main.js2
-rw-r--r--help3/xhpeditor/cm/src/input/ContentEditableInput.js2
-rw-r--r--help3/xhpeditor/cm/src/input/input.js2
-rw-r--r--help3/xhpeditor/cm/src/measurement/position_measurement.js20
-rw-r--r--help3/xhpeditor/cm/src/model/Doc.js1
-rw-r--r--help3/xhpeditor/cm/test/test.js4
-rw-r--r--help3/xhpeditor/cm/test/vim_test.js977
-rw-r--r--help3/xhpeditor/cm/theme/ayu-dark.css2
-rw-r--r--help3/xhpeditor/cm/theme/ayu-mirage.css4
-rw-r--r--help3/xhpeditor/cm/theme/base16-dark.css2
-rw-r--r--help3/xhpeditor/cm/theme/gruvbox-dark.css2
-rw-r--r--help3/xhpeditor/cm/theme/juejin.css30
-rw-r--r--help3/xhpeditor/cm/theme/material-ocean.css8
-rw-r--r--help3/xhpeditor/cm/theme/material-palenight.css8
-rw-r--r--help3/xhpeditor/cm/theme/material.css8
-rw-r--r--help3/xhpeditor/cm/theme/oceanic-next.css2
-rw-r--r--help3/xhpeditor/cm/theme/solarized.css3
-rw-r--r--help3/xhpeditor/links.txt.xsl43
-rwxr-xr-xperf/compare-logs.py36
-rwxr-xr-xperf/test-startup-time.py9
-rw-r--r--test-bugzilla-files/autogen.input1
-rwxr-xr-xtest-bugzilla-files/zip.sh3
-rwxr-xr-xuitest/mass-testing/calc.py111
-rwxr-xr-xuitest/mass-testing/impress.py65
-rw-r--r--uitest/mass-testing/registrymodifications.xcu1
-rwxr-xr-xuitest/mass-testing/run.py29
-rwxr-xr-xuitest/mass-testing/writer.py70
93 files changed, 1698 insertions, 1162 deletions
diff --git a/clang/Makefile b/clang/Makefile
index ae5a54d..71ab3c5 100644
--- a/clang/Makefile
+++ b/clang/Makefile
@@ -2,8 +2,8 @@
CLANGDEFS=-D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -fno-rtti
CLANGWARNS=-Werror -Wall -Wno-missing-braces -Wnon-virtual-dtor -Wendif-labels -Wextra -Wundef -Wunused-macros -Wshadow -Woverloaded-virtual
-CLANGFLAGS = $(CLANGDEFS) $(CLANGWARNS) -g -std=c++11
-CLANGLIBS = -lclangAST -lclangBasic -lclangFrontend -lclangRewrite -lclangTooling -lclangLex -lLLVM
+CLANGFLAGS = $(CLANGDEFS) $(CLANGWARNS) -g
+CLANGLIBS = -lclang-cpp -lLLVM
ifneq ($(GCOV),)
CLANGFLAGS += --coverage
endif
diff --git a/clang/README b/clang/README
index 1906d81..12a932d 100644
--- a/clang/README
+++ b/clang/README
@@ -19,8 +19,7 @@ Details:
- member functions
- classes
- tested with clang
- - 3.5
- - 3.7
+ - 12
== Hello world
diff --git a/clang/bin/clang-rename-wrapper b/clang/bin/clang-rename-wrapper
index da7cbac..d25ece9 100755
--- a/clang/bin/clang-rename-wrapper
+++ b/clang/bin/clang-rename-wrapper
@@ -29,7 +29,9 @@ if [ -n "$file" ]; then
mkdir -p /tmp/rename
RENAME_ARGS="$RENAME_ARGS -export-fixes=$(mktemp -p /tmp/rename XXXXXXXXXX.yaml)"
fi
- $myname $RENAME_ARGS $file -- "$@"
+ # Avoid "error: unable to find plugin 'loplugin'".
+ args="$(echo "$@"|sed "s|-Xclang -load -Xclang $SRC_ROOT/compilerplugins/clang/plugin.so -Xclang -add-plugin -Xclang loplugin||")"
+ $myname $RENAME_ARGS $file -- $args
ret=$?
fi
diff --git a/clang/find-unprefixed-members.cxx b/clang/find-unprefixed-members.cxx
index d3d65b3..e5d80af 100644
--- a/clang/find-unprefixed-members.cxx
+++ b/clang/find-unprefixed-members.cxx
@@ -305,14 +305,10 @@ public:
{
}
-#if (__clang_major__ == 3 && __clang_minor__ >= 6) || __clang_major__ > 3
std::unique_ptr<clang::ASTConsumer> newASTConsumer()
{
- return llvm::make_unique<ASTConsumer>(m_rContext);
+ return std::make_unique<ASTConsumer>(m_rContext);
}
-#else
- clang::ASTConsumer* newASTConsumer() { return new ASTConsumer(m_rContext); }
-#endif
};
int main(int argc, const char** argv)
@@ -340,9 +336,16 @@ int main(int argc, const char** argv)
"path-prefix",
llvm::cl::desc("If not empty, ignore all source code paths not matching this prefix."),
llvm::cl::cat(aCategory));
- clang::tooling::CommonOptionsParser aParser(argc, argv, aCategory);
+ auto aExpectedParser = clang::tooling::CommonOptionsParser::create(argc, argv, aCategory);
+ if (!aExpectedParser)
+ {
+ llvm::errs() << aExpectedParser.takeError();
+ return 1;
+ }
+
+ clang::tooling::CommonOptionsParser& rParser = aExpectedParser.get();
- clang::tooling::ClangTool aTool(aParser.getCompilations(), aParser.getSourcePathList());
+ clang::tooling::ClangTool aTool(rParser.getCompilations(), rParser.getSourcePathList());
Context aContext(aClassName, aClassPrefix, aClassExcludedPrefix, bPoco, bYaml, aPathPrefix);
FrontendAction aAction(aContext);
diff --git a/help3/xhpeditor/cm/AUTHORS b/help3/xhpeditor/cm/AUTHORS
index a8ded26..bacc2b8 100644
--- a/help3/xhpeditor/cm/AUTHORS
+++ b/help3/xhpeditor/cm/AUTHORS
@@ -21,6 +21,7 @@ Adrien Bertrand
aeroson
Ahmad Amireh
Ahmad M. Zawawi
+AHOHNMYC
ahoward
Ajin Abraham
Akeksandr Motsjonov
@@ -77,8 +78,10 @@ Anthony Dugois
anthonygego
Anthony Gégo
Anthony Grimes
+Anthony Stewart
Anton Kovalyov
antosarho
+aoki ken
Apollo Zhu
AQNOUCH Mohammed
Aram Shatakhtsyan
@@ -116,6 +119,7 @@ Bernhard Sirlinger
Bert Chang
Bharad
BigBlueHat
+Billiam
Billy Moon
Bin Ni
binny
@@ -165,6 +169,7 @@ Chris Smith
Christian Gruen
Christian Oyarzun
Christian Petrov
+Christian Sonne
christopherblaser
Christopher Brown
Christopher Kramer
@@ -226,6 +231,7 @@ Dick Choi
Diego Fernandez
dignifiedquire
Dimage Sapelkin
+Dimitri Mitropoulos
Dinindu D. Wanniarachchi
dmaclach
Dmitry Kiselyov
@@ -369,6 +375,7 @@ Jack Douglas
Jacob Lee
Jaimin
Jake Peyser
+Jake Zimmerman
Jakob Kummerow
Jakob Miland
Jakub T. Jankiewicz
@@ -427,6 +434,7 @@ John Engler
John Lees-Miller
John Ryan
John Snelson
+johnspiegel
John Van Der Loo
Jon Ander Peñalba
Jonas Döbertin
@@ -465,9 +473,11 @@ karevn
Karol
Kaushik Kulkarni
Kayur Patel
+Kazuhisa Ishizaka
Kazuhito Hokamura
kcwiakala
Kees de Kooter
+Keldan Chapman
Kenan Christian Dimas
Ken Newman
ken restivo
@@ -504,6 +514,7 @@ Leo Baschy
Leonid Khachaturov
Leon Sorokin
Leonya Khachaturov
+lexer2086
Liam Newman
Libo Cannici
Lior Goldberg
@@ -618,6 +629,7 @@ Mike Ivanov
Mike Kadin
Mike Kobit
Milan Szekely
+MinJune Kim
MinRK
Miraculix87
misfo
@@ -632,6 +644,7 @@ ms
mtaran-google
Mu-An ✌️ Chiou
Mu-An Chiou
+Mykola Martynovets
mzabuawala
Narciso Jaramillo
nathanlesage
@@ -669,6 +682,7 @@ Norman Rzepka
Nouzbe
Oleksandr Yakovenko
Olivia Ytterbrink
+Ondřej Mirtes
Opender Singh
opl-
Oreoluwa Onatemowo
@@ -720,6 +734,7 @@ Prasanth J
Prayag Verma
prendota
Prendota
+ps173
Qiang Li
quiddity-wp
Radek Piórkowski
@@ -753,8 +768,10 @@ Roberto Vidal
Robert Plummer
Roman Frolov
Roman Janusz
+Rongjian Zhang
Rrandom
Rrrandom
+Ruslan Bekenev
Ruslan Osmanov
rvalavicius
Ryan Pangrle
@@ -762,6 +779,7 @@ Ryan Petrello
Ryan Prior
ryu-sato
sabaca
+Sachin Gupta
Sam Lee
Sam Rawlins
Samuel Ainsworth
@@ -816,6 +834,7 @@ srajanpaliwal
Stanislav Oaserele
stan-z
Stas Kobzar
+stasoid
Stefan Borsje
Steffen Beyer
Steffen Bruchmann
@@ -824,6 +843,7 @@ Stephane Moore
Stephen Lavelle
Steve Champagne
Steve Hoover
+Steven Yung
Steve O'Hara
stockiNail
stoskov
@@ -857,6 +877,7 @@ Thomas Schmid
Tim Alby
Tim Baumann
Tim Gates
+Tim Nguyen
Timothy Farrell
Timothy Gu
Timothy Hatcher
@@ -903,7 +924,9 @@ Wes Cossick
Wesley Wiser
Weston Ruter
Will Binns-Smith
+Will Cassella
Will Dean
+Will Hernandez
William Desportes
William Jamieson
William Stein
diff --git a/help3/xhpeditor/cm/CHANGELOG.md b/help3/xhpeditor/cm/CHANGELOG.md
index 4145ff4..165c71a 100644
--- a/help3/xhpeditor/cm/CHANGELOG.md
+++ b/help3/xhpeditor/cm/CHANGELOG.md
@@ -1,3 +1,97 @@
+## 5.65.1 (2022-01-20)
+
+### Bug fixes
+
+Fix miscalculation of vertical positions in lines that have both line widgets and replaced newlines.
+
+## 5.65.0 (2021-12-20)
+
+### Bug fixes
+
+brace-folding addon: Fix broken folding on lines with both braces and square brackets.
+
+### New features
+
+[vim bindings](https://codemirror.net/demo/vim.html): Support g0, g$, g<Arrow>.
+
+## 5.64.0 (2021-11-20)
+
+### Bug fixes
+
+Fix a crash that occurred in some situations with replacing marks across line breaks.
+
+Make sure native scrollbars reset their position when hidden and re-shown.
+
+### New features
+
+[vim bindings](https://codemirror.net/demo/vim.html): Support C-u to delete back a line.
+
+## 5.63.3 (2021-10-11)
+
+### Bug fixes
+
+Prevent external styles from giving the hidden textarea a min-height.
+
+Remove a stray autosave file that was part of the previous release.
+
+## 5.63.1 (2021-09-29)
+
+### Bug fixes
+
+Fix an issue with mouse scrolling on Chrome 94 Windows, which made scrolling by wheel move unusably slow.
+
+## 5.63.0 (2021-09-20)
+
+### Bug fixes
+
+Fix scroll position jumping when scrolling a document with very different line heights.
+
+[xml mode](https://codemirror.net/mode/xml/): Look up HTML element behavior in a case-insensitive way.
+
+### New features
+
+[vim bindings](https://codemirror.net/demo/vim.html): Support guu for case-changing.
+
+## 5.62.3 (2021-08-20)
+
+### Bug fixes
+
+Give the editor a `translate=no` attribute to prevent automatic translation from modifying its content.
+
+Give vim-style cursors a width that matches the character after them.
+
+[merge addon](https://codemirror.net/doc/manual.html#addon_merge): Make buttons keyboard-accessible.
+
+[emacs bindings](https://codemirror.net/demo/emacs.html): Fix by-page scrolling keybindings, which were accidentally inverted.
+
+## 5.62.2 (2021-07-21)
+
+### Bug fixes
+
+[lint addon](https://codemirror.net/doc/manual.html#addon_lint): Fix a regression that broke several addon options.
+
+## 5.62.1 (2021-07-20)
+
+### Bug fixes
+
+[vim bindings](https://codemirror.net/demo/vim.html): Make matching of upper-case characters more Unicode-aware.
+
+[lint addon](https://codemirror.net/doc/manual.html#addon_lint): Prevent options passed to the addon itself from being given to the linter.
+
+[show-hint addon](https://codemirror.net/doc/manual.html#addon_show-hint): Improve screen reader support.
+
+[search addon](https://codemirror.net/demo/search.html): Avoid using `innerHTML`.
+
+## 5.62.0 (2021-06-21)
+
+### Bug fixes
+
+Improve support for vim-style cursors in a number of themes.
+
+### New features
+
+[lint addon](https://codemirror.net/doc/manual.html#addon_lint): Add support for highlighting lines with errors or warnings.
+
## 5.61.1 (2021-05-20)
### Bug fixes
diff --git a/help3/xhpeditor/cm/README.md b/help3/xhpeditor/cm/README.md
index 92debf4..39c2468 100644
--- a/help3/xhpeditor/cm/README.md
+++ b/help3/xhpeditor/cm/README.md
@@ -1,6 +1,6 @@
# CodeMirror
-[![Build Status](https://travis-ci.org/codemirror/CodeMirror.svg)](https://travis-ci.org/codemirror/CodeMirror)
+[![Build Status](https://github.com/codemirror/codemirror/workflows/main/badge.svg)](https://github.com/codemirror/codemirror/actions)
[![NPM version](https://img.shields.io/npm/v/codemirror.svg)](https://www.npmjs.org/package/codemirror)
CodeMirror is a versatile text editor implemented in JavaScript for
diff --git a/help3/xhpeditor/cm/addon/fold/brace-fold.js b/help3/xhpeditor/cm/addon/fold/brace-fold.js
index 79a331c..28cb093 100644
--- a/help3/xhpeditor/cm/addon/fold/brace-fold.js
+++ b/help3/xhpeditor/cm/addon/fold/brace-fold.js
@@ -11,56 +11,67 @@
})(function(CodeMirror) {
"use strict";
-CodeMirror.registerHelper("fold", "brace", function(cm, start) {
- var line = start.line, lineText = cm.getLine(line);
- var tokenType;
+function bracketFolding(pairs) {
+ return function(cm, start) {
+ var line = start.line, lineText = cm.getLine(line);
- function findOpening(openCh) {
- for (var at = start.ch, pass = 0;;) {
- var found = at <= 0 ? -1 : lineText.lastIndexOf(openCh, at - 1);
- if (found == -1) {
- if (pass == 1) break;
- pass = 1;
- at = lineText.length;
- continue;
+ function findOpening(pair) {
+ var tokenType;
+ for (var at = start.ch, pass = 0;;) {
+ var found = at <= 0 ? -1 : lineText.lastIndexOf(pair[0], at - 1);
+ if (found == -1) {
+ if (pass == 1) break;
+ pass = 1;
+ at = lineText.length;
+ continue;
+ }
+ if (pass == 1 && found < start.ch) break;
+ tokenType = cm.getTokenTypeAt(CodeMirror.Pos(line, found + 1));
+ if (!/^(comment|string)/.test(tokenType)) return {ch: found + 1, tokenType: tokenType, pair: pair};
+ at = found - 1;
}
- if (pass == 1 && found < start.ch) break;
- tokenType = cm.getTokenTypeAt(CodeMirror.Pos(line, found + 1));
- if (!/^(comment|string)/.test(tokenType)) return found + 1;
- at = found - 1;
}
- }
-
- 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
- }
- 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;
- for (;;) {
- var nextOpen = text.indexOf(startToken, pos), nextClose = text.indexOf(endToken, pos);
- if (nextOpen < 0) nextOpen = text.length;
- if (nextClose < 0) nextClose = text.length;
- pos = Math.min(nextOpen, nextClose);
- if (pos == text.length) break;
- if (cm.getTokenTypeAt(CodeMirror.Pos(i, pos + 1)) == tokenType) {
- if (pos == nextOpen) ++count;
- else if (!--count) { end = i; endCh = pos; break outer; }
+ function findRange(found) {
+ var count = 1, lastLine = cm.lastLine(), end, startCh = found.ch, endCh
+ outer: for (var i = line; i <= lastLine; ++i) {
+ var text = cm.getLine(i), pos = i == line ? startCh : 0;
+ for (;;) {
+ var nextOpen = text.indexOf(found.pair[0], pos), nextClose = text.indexOf(found.pair[1], pos);
+ if (nextOpen < 0) nextOpen = text.length;
+ if (nextClose < 0) nextClose = text.length;
+ pos = Math.min(nextOpen, nextClose);
+ if (pos == text.length) break;
+ if (cm.getTokenTypeAt(CodeMirror.Pos(i, pos + 1)) == found.tokenType) {
+ if (pos == nextOpen) ++count;
+ else if (!--count) { end = i; endCh = pos; break outer; }
+ }
+ ++pos;
+ }
}
- ++pos;
+
+ if (end == null || line == end) return null
+ return {from: CodeMirror.Pos(line, startCh),
+ to: CodeMirror.Pos(end, endCh)};
+ }
+
+ var found = []
+ for (var i = 0; i < pairs.length; i++) {
+ var open = findOpening(pairs[i])
+ if (open) found.push(open)
+ }
+ found.sort(function(a, b) { return a.ch - b.ch })
+ for (var i = 0; i < found.length; i++) {
+ var range = findRange(found[i])
+ if (range) return range
}
+ return null
}
- if (end == null || line == end) return;
- return {from: CodeMirror.Pos(line, startCh),
- to: CodeMirror.Pos(end, endCh)};
-});
+}
+
+CodeMirror.registerHelper("fold", "brace", bracketFolding([["{", "}"], ["[", "]"]]));
+
+CodeMirror.registerHelper("fold", "brace-paren", bracketFolding([["{", "}"], ["[", "]"], ["(", ")"]]));
CodeMirror.registerHelper("fold", "import", function(cm, start) {
function hasImport(line) {
diff --git a/help3/xhpeditor/cm/addon/fold/foldcode.js b/help3/xhpeditor/cm/addon/fold/foldcode.js
index 887df3f..721bc08 100644
--- a/help3/xhpeditor/cm/addon/fold/foldcode.js
+++ b/help3/xhpeditor/cm/addon/fold/foldcode.js
@@ -24,9 +24,11 @@
function getRange(allowFolded) {
var range = finder(cm, pos);
if (!range || range.to.line - range.from.line < minSize) return null;
+ if (force === "fold") return range;
+
var marks = cm.findMarksAt(range.from);
for (var i = 0; i < marks.length; ++i) {
- if (marks[i].__isFold && force !== "fold") {
+ if (marks[i].__isFold) {
if (!allowFolded) return null;
range.cleared = true;
marks[i].clear();
@@ -99,18 +101,18 @@
cm.foldCode(cm.getCursor(), null, "fold");
};
CodeMirror.commands.unfold = function(cm) {
- cm.foldCode(cm.getCursor(), null, "unfold");
+ cm.foldCode(cm.getCursor(), { scanUp: false }, "unfold");
};
CodeMirror.commands.foldAll = function(cm) {
cm.operation(function() {
for (var i = cm.firstLine(), e = cm.lastLine(); i <= e; i++)
- cm.foldCode(CodeMirror.Pos(i, 0), null, "fold");
+ cm.foldCode(CodeMirror.Pos(i, 0), { scanUp: false }, "fold");
});
};
CodeMirror.commands.unfoldAll = function(cm) {
cm.operation(function() {
for (var i = cm.firstLine(), e = cm.lastLine(); i <= e; i++)
- cm.foldCode(CodeMirror.Pos(i, 0), null, "unfold");
+ cm.foldCode(CodeMirror.Pos(i, 0), { scanUp: false }, "unfold");
});
};
diff --git a/help3/xhpeditor/cm/addon/hint/show-hint.js b/help3/xhpeditor/cm/addon/hint/show-hint.js
index 8f23656..2be2c71 100644
--- a/help3/xhpeditor/cm/addon/hint/show-hint.js
+++ b/help3/xhpeditor/cm/addon/hint/show-hint.js
@@ -224,6 +224,7 @@
}
function Widget(completion, data) {
+ this.id = "cm-complete-" + Math.floor(Math.random(1e6))
this.completion = completion;
this.data = data;
this.picked = false;
@@ -232,6 +233,9 @@
var parentWindow = ownerDocument.defaultView || ownerDocument.parentWindow;
var hints = this.hints = ownerDocument.createElement("ul");
+ hints.setAttribute("role", "listbox")
+ hints.setAttribute("aria-expanded", "true")
+ hints.id = this.id
var theme = completion.cm.options.theme;
hints.className = "CodeMirror-hints " + theme;
this.selectedHint = data.selectedHint || 0;
@@ -242,6 +246,9 @@
var className = HINT_ELEMENT_CLASS + (i != this.selectedHint ? "" : " " + ACTIVE_HINT_ELEMENT_CLASS);
if (cur.className != null) className = cur.className + " " + className;
elt.className = className;
+ if (i == this.selectedHint) elt.setAttribute("aria-selected", "true")
+ elt.id = this.id + "-" + i
+ elt.setAttribute("role", "option")
if (cur.render) cur.render(elt, data, cur);
else elt.appendChild(ownerDocument.createTextNode(cur.displayText || getText(cur)));
elt.hintId = i;
@@ -267,6 +274,9 @@
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);
+ cm.getInputField().setAttribute("aria-autocomplete", "list")
+ cm.getInputField().setAttribute("aria-owns", this.id)
+ cm.getInputField().setAttribute("aria-activedescendant", this.id + "-" + this.selectedHint)
var box = completion.options.moveOnOverlap ? hints.getBoundingClientRect() : new DOMRect();
var scrolls = completion.options.paddingForScrollbar ? hints.scrollHeight > hints.clientHeight + 1 : false;
@@ -364,6 +374,9 @@
this.completion.widget = null;
if (this.hints.parentNode) this.hints.parentNode.removeChild(this.hints);
this.completion.cm.removeKeyMap(this.keyMap);
+ var input = this.completion.cm.getInputField()
+ input.removeAttribute("aria-activedescendant")
+ input.removeAttribute("aria-owns")
var cm = this.completion.cm;
if (this.completion.options.closeOnUnfocus) {
@@ -391,9 +404,14 @@
i = avoidWrap ? 0 : this.data.list.length - 1;
if (this.selectedHint == i) return;
var node = this.hints.childNodes[this.selectedHint];
- if (node) node.className = node.className.replace(" " + ACTIVE_HINT_ELEMENT_CLASS, "");
+ if (node) {
+ node.className = node.className.replace(" " + ACTIVE_HINT_ELEMENT_CLASS, "");
+ node.removeAttribute("aria-selected")
+ }
node = this.hints.childNodes[this.selectedHint = i];
node.className += " " + ACTIVE_HINT_ELEMENT_CLASS;
+ node.setAttribute("aria-selected", "true")
+ this.completion.cm.getInputField().setAttribute("aria-activedescendant", node.id)
this.scrollToActive()
CodeMirror.signal(this.data, "select", this.data.list[this.selectedHint], node);
},
diff --git a/help3/xhpeditor/cm/addon/lint/lint.css b/help3/xhpeditor/cm/addon/lint/lint.css
index 0871865..e1560db 100644
--- a/help3/xhpeditor/cm/addon/lint/lint.css
+++ b/help3/xhpeditor/cm/addon/lint/lint.css
@@ -69,3 +69,11 @@
background-position: right bottom;
width: 100%; height: 100%;
}
+
+.CodeMirror-lint-line-error {
+ background-color: rgba(183, 76, 81, 0.08);
+}
+
+.CodeMirror-lint-line-warning {
+ background-color: rgba(255, 211, 0, 0.1);
+}
diff --git a/help3/xhpeditor/cm/addon/lint/lint.js b/help3/xhpeditor/cm/addon/lint/lint.js
index 395f0d9..1613deb 100644
--- a/help3/xhpeditor/cm/addon/lint/lint.js
+++ b/help3/xhpeditor/cm/addon/lint/lint.js
@@ -11,6 +11,7 @@
})(function(CodeMirror) {
"use strict";
var GUTTER_ID = "CodeMirror-lint-markers";
+ var LINT_LINE_ID = "CodeMirror-lint-line-";
function showTooltip(cm, e, content) {
var tt = document.createElement("div");
@@ -58,29 +59,54 @@
CodeMirror.on(node, "mouseout", hide);
}
- function LintState(cm, options, hasGutter) {
+ function LintState(cm, conf, hasGutter) {
this.marked = [];
- this.options = options;
+ if (conf instanceof Function) conf = {getAnnotations: conf};
+ if (!conf || conf === true) conf = {};
+ this.options = {};
+ this.linterOptions = conf.options || {};
+ for (var prop in defaults) this.options[prop] = defaults[prop];
+ for (var prop in conf) {
+ if (defaults.hasOwnProperty(prop)) {
+ if (conf[prop] != null) this.options[prop] = conf[prop];
+ } else if (!conf.options) {
+ this.linterOptions[prop] = conf[prop];
+ }
+ }
this.timeout = null;
this.hasGutter = hasGutter;
this.onMouseOver = function(e) { onMouseOver(cm, e); };
this.waitingFor = 0
}
- function parseOptions(_cm, options) {
- if (options instanceof Function) return {getAnnotations: options};
- if (!options || options === true) options = {};
- return options;
+ var defaults = {
+ highlightLines: false,
+ tooltips: true,
+ delay: 500,
+ lintOnChange: true,
+ getAnnotations: null,
+ async: false,
+ selfContain: null,
+ formatAnnotation: null,
+ onUpdateLinting: null
}
function clearMarks(cm) {
var state = cm.state.lint;
if (state.hasGutter) cm.clearGutter(GUTTER_ID);
+ if (state.options.highlightLines) clearErrorLines(cm);
for (var i = 0; i < state.marked.length; ++i)
state.marked[i].clear();
state.marked.length = 0;
}
+ function clearErrorLines(cm) {
+ cm.eachLine(function(line) {
+ var has = line.wrapClass && /\bCodeMirror-lint-line-\w+\b/.exec(line.wrapClass);
+ if (has) cm.removeLineClass(line, "wrap", has[0]);
+ })
+ }
+
function makeMarker(cm, labels, severity, multiple, tooltips) {
var marker = document.createElement("div"), inner = marker;
marker.className = "CodeMirror-lint-marker CodeMirror-lint-marker-" + severity;
@@ -123,7 +149,7 @@
return tip;
}
- function lintAsync(cm, getAnnotations, passOptions) {
+ function lintAsync(cm, getAnnotations) {
var state = cm.state.lint
var id = ++state.waitingFor
function abort() {
@@ -136,22 +162,23 @@
if (state.waitingFor != id) return
if (arg2 && annotations instanceof CodeMirror) annotations = arg2
cm.operation(function() {updateLinting(cm, annotations)})
- }, passOptions, cm);
+ }, state.linterOptions, cm);
}
function startLinting(cm) {
- var state = cm.state.lint, options = state.options;
+ var state = cm.state.lint;
+ if (!state) return;
+ var options = state.options;
/*
* Passing rules in `options` property prevents JSHint (and other linters) from complaining
* about unrecognized rules like `onUpdateLinting`, `delay`, `lintOnChange`, etc.
*/
- var passOptions = options.options || options;
var getAnnotations = options.getAnnotations || cm.getHelper(CodeMirror.Pos(0, 0), "lint");
if (!getAnnotations) return;
if (options.async || getAnnotations.async) {
- lintAsync(cm, getAnnotations, passOptions)
+ lintAsync(cm, getAnnotations)
} else {
- var annotations = getAnnotations(cm.getValue(), passOptions, cm);
+ var annotations = getAnnotations(cm.getValue(), state.linterOptions, cm);
if (!annotations) return;
if (annotations.then) annotations.then(function(issues) {
cm.operation(function() {updateLinting(cm, issues)})
@@ -161,8 +188,10 @@
}
function updateLinting(cm, annotationsNotSorted) {
+ var state = cm.state.lint;
+ if (!state) return;
+ var options = state.options;
clearMarks(cm);
- var state = cm.state.lint, options = state.options;
var annotations = groupByLine(annotationsNotSorted);
@@ -194,7 +223,10 @@
// use original annotations[line] to show multiple messages
if (state.hasGutter)
cm.setGutterMarker(line, GUTTER_ID, makeMarker(cm, tipLabel, maxSeverity, annotations[line].length > 1,
- state.options.tooltips));
+ options.tooltips));
+
+ if (options.highlightLines)
+ cm.addLineClass(line, "wrap", LINT_LINE_ID + maxSeverity);
}
if (options.onUpdateLinting) options.onUpdateLinting(annotationsNotSorted, annotations, cm);
}
@@ -203,7 +235,7 @@
var state = cm.state.lint;
if (!state) return;
clearTimeout(state.timeout);
- state.timeout = setTimeout(function(){startLinting(cm);}, state.options.delay || 500);
+ state.timeout = setTimeout(function(){startLinting(cm);}, state.options.delay);
}
function popupTooltips(cm, annotations, e) {
@@ -243,8 +275,8 @@
if (val) {
var gutters = cm.getOption("gutters"), hasLintGutter = false;
for (var i = 0; i < gutters.length; ++i) if (gutters[i] == GUTTER_ID) hasLintGutter = true;
- var state = cm.state.lint = new LintState(cm, parseOptions(cm, val), hasLintGutter);
- if (state.options.lintOnChange !== false)
+ var state = cm.state.lint = new LintState(cm, val, hasLintGutter);
+ if (state.options.lintOnChange)
cm.on("change", onChange);
if (state.options.tooltips != false && state.options.tooltips != "gutter")
CodeMirror.on(cm.getWrapperElement(), "mouseover", state.onMouseOver);
@@ -254,6 +286,6 @@
});
CodeMirror.defineExtension("performLint", function() {
- if (this.state.lint) startLinting(this);
+ startLinting(this);
});
});
diff --git a/help3/xhpeditor/cm/addon/merge/merge.js b/help3/xhpeditor/cm/addon/merge/merge.js
index 827edb7..7fd963f 100644
--- a/help3/xhpeditor/cm/addon/merge/merge.js
+++ b/help3/xhpeditor/cm/addon/merge/merge.js
@@ -508,6 +508,7 @@
copy.title = dv.edit.phrase(editOriginals ? "Push to left" : "Revert chunk");
copy.chunk = chunk;
copy.style.top = (chunk.origTo > chunk.origFrom ? top : dv.edit.heightAtLine(chunk.editFrom, "local") - sTopEdit) + "px";
+ copy.setAttribute("role", "button");
if (editOriginals) {
var topReverse = dv.edit.heightAtLine(chunk.editFrom, "local") - sTopEdit;
@@ -518,6 +519,7 @@
origFrom: chunk.editFrom, origTo: chunk.editTo};
copyReverse.style.top = topReverse + "px";
dv.type == "right" ? copyReverse.style.left = "2px" : copyReverse.style.right = "2px";
+ copyReverse.setAttribute("role", "button");
}
}
}
@@ -599,6 +601,7 @@
function buildGap(dv) {
var lock = dv.lockButton = elt("div", null, "CodeMirror-merge-scrolllock");
+ lock.setAttribute("role", "button");
var lockWrap = elt("div", [lock], "CodeMirror-merge-scrolllock-wrap");
CodeMirror.on(lock, "click", function() { setScrollLock(dv, !dv.lockScroll); });
var gapElts = [lockWrap];
diff --git a/help3/xhpeditor/cm/addon/search/search.js b/help3/xhpeditor/cm/addon/search/search.js
index 118f111..24a0855 100644
--- a/help3/xhpeditor/cm/addon/search/search.js
+++ b/help3/xhpeditor/cm/addon/search/search.js
@@ -189,18 +189,43 @@
if (state.annotate) { state.annotate.clear(); state.annotate = null; }
});}
+ function el(tag, attrs) {
+ var element = tag ? document.createElement(tag) : document.createDocumentFragment();
+ for (var key in attrs) {
+ element[key] = attrs[key];
+ }
+ for (var i = 2; i < arguments.length; i++) {
+ var child = arguments[i]
+ element.appendChild(typeof child == "string" ? document.createTextNode(child) : child);
+ }
+ return element;
+ }
function getQueryDialog(cm) {
- return '<span class="CodeMirror-search-label">' + cm.phrase("Search:") + '</span> <input type="text" style="width: 10em" class="CodeMirror-search-field"/> <span style="color: #888" class="CodeMirror-search-hint">' + cm.phrase("(Use /re/ syntax for regexp search)") + '</span>';
+ return el("", null,
+ el("span", {className: "CodeMirror-search-label"}, cm.phrase("Search:")), " ",
+ el("input", {type: "text", "style": "width: 10em", className: "CodeMirror-search-field"}), " ",
+ el("span", {style: "color: #888", className: "CodeMirror-search-hint"},
+ cm.phrase("(Use /re/ syntax for regexp search)")));
}
function getReplaceQueryDialog(cm) {
- return ' <input type="text" style="width: 10em" class="CodeMirror-search-field"/> <span style="color: #888" class="CodeMirror-search-hint">' + cm.phrase("(Use /re/ syntax for regexp search)") + '</span>';
+ return el("", null, " ",
+ el("input", {type: "text", "style": "width: 10em", className: "CodeMirror-search-field"}), " ",
+ el("span", {style: "color: #888", className: "CodeMirror-search-hint"},
+ cm.phrase("(Use /re/ syntax for regexp search)")));
}
function getReplacementQueryDialog(cm) {
- return '<span class="CodeMirror-search-label">' + cm.phrase("With:") + '</span> <input type="text" style="width: 10em" class="CodeMirror-search-field"/>';
+ return el("", null,
+ el("span", {className: "CodeMirror-search-label"}, cm.phrase("With:")), " ",
+ el("input", {type: "text", "style": "width: 10em", className: "CodeMirror-search-field"}));
}
function getDoReplaceConfirm(cm) {
- return '<span class="CodeMirror-search-label">' + cm.phrase("Replace?") + '</span> <button>' + cm.phrase("Yes") + '</button> <button>' + cm.phrase("No") + '</button> <button>' + cm.phrase("All") + '</button> <button>' + cm.phrase("Stop") + '</button> ';
+ return el("", null,
+ el("span", {className: "CodeMirror-search-label"}, cm.phrase("Replace?")), " ",
+ el("button", {}, cm.phrase("Yes")), " ",
+ el("button", {}, cm.phrase("No")), " ",
+ el("button", {}, cm.phrase("All")), " ",
+ el("button", {}, cm.phrase("Stop")));
}
function replaceAll(cm, query, text) {
@@ -217,8 +242,11 @@
function replace(cm, all) {
if (cm.getOption("readOnly")) return;
var query = cm.getSelection() || getSearchState(cm).lastQuery;
- var dialogText = '<span class="CodeMirror-search-label">' + (all ? cm.phrase("Replace all:") : cm.phrase("Replace:")) + '</span>';
- dialog(cm, dialogText + getReplaceQueryDialog(cm), dialogText, query, function(query) {
+ var dialogText = all ? cm.phrase("Replace all:") : cm.phrase("Replace:")
+ var fragment = el("", null,
+ el("span", {className: "CodeMirror-search-label"}, dialogText),
+ getReplaceQueryDialog(cm))
+ dialog(cm, fragment, dialogText, query, function(query) {
if (!query) return;
query = parseQuery(query);
dialog(cm, getReplacementQueryDialog(cm), cm.phrase("Replace with:"), "", function(text) {
diff --git a/help3/xhpeditor/cm/addon/search/searchcursor.js b/help3/xhpeditor/cm/addon/search/searchcursor.js
index d586957..230017b 100644
--- a/help3/xhpeditor/cm/addon/search/searchcursor.js
+++ b/help3/xhpeditor/cm/addon/search/searchcursor.js
@@ -202,6 +202,7 @@
function SearchCursor(doc, query, pos, options) {
this.atOccurrence = false
+ this.afterEmptyMatch = false
this.doc = doc
pos = pos ? doc.clipPos(pos) : Pos(0, 0)
this.pos = {from: pos, to: pos}
@@ -237,21 +238,29 @@
findPrevious: function() {return this.find(true)},
find: function(reverse) {
- 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-compatibility with the vim code (unfortunately)
- while (result && CodeMirror.cmpPos(result.from, result.to) == 0) {
+ var head = this.doc.clipPos(reverse ? this.pos.from : this.pos.to);
+ if (this.afterEmptyMatch && this.atOccurrence) {
+ // do not return the same 0 width match twice
+ head = Pos(head.line, head.ch)
if (reverse) {
- if (result.from.ch) result.from = Pos(result.from.line, result.from.ch - 1)
- else if (result.from.line == this.doc.firstLine()) result = null
- else result = this.matches(reverse, this.doc.clipPos(Pos(result.from.line - 1)))
+ head.ch--;
+ if (head.ch < 0) {
+ head.line--;
+ head.ch = (this.doc.getLine(head.line) || "").length;
+ }
} else {
- if (result.to.ch < this.doc.getLine(result.to.line).length) result.to = Pos(result.to.line, result.to.ch + 1)
- else if (result.to.line == this.doc.lastLine()) result = null
- else result = this.matches(reverse, Pos(result.to.line + 1, 0))
+ head.ch++;
+ if (head.ch > (this.doc.getLine(head.line) || "").length) {
+ head.ch = 0;
+ head.line++;
+ }
+ }
+ if (CodeMirror.cmpPos(head, this.doc.clipPos(head)) != 0) {
+ return this.atOccurrence = false
}
}
+ var result = this.matches(reverse, head)
+ this.afterEmptyMatch = result && CodeMirror.cmpPos(result.from, result.to) == 0
if (result) {
this.pos = result
diff --git a/help3/xhpeditor/cm/demo/lint.html b/help3/xhpeditor/cm/demo/lint.html
index 1184232..a479cdd 100644
--- a/help3/xhpeditor/cm/demo/lint.html
+++ b/help3/xhpeditor/cm/demo/lint.html
@@ -9,7 +9,7 @@
<script src="../lib/codemirror.js"></script>
<script src="../mode/javascript/javascript.js"></script>
<script src="../mode/css/css.js"></script>
-<script src="https://unpkg.com/jshint@2.9.6/dist/jshint.js"></script>
+<script src="https://unpkg.com/jshint@2.13.2/dist/jshint.js"></script>
<script src="https://unpkg.com/jsonlint@1.6.3/web/jsonlint.js"></script>
<script src="https://unpkg.com/csslint@1.0.5/dist/csslint.js"></script>
<script src="../addon/lint/lint.js"></script>
@@ -150,7 +150,7 @@ li.last {
lineNumbers: true,
mode: "javascript",
gutters: ["CodeMirror-lint-markers"],
- lint: true
+ lint: {options: {esversion: 2021}},
});
var editor_json = CodeMirror.fromTextArea(document.getElementById("code-json"), {
diff --git a/help3/xhpeditor/cm/demo/theme.html b/help3/xhpeditor/cm/demo/theme.html
index a4ca59c..1ccac88 100644
--- a/help3/xhpeditor/cm/demo/theme.html
+++ b/help3/xhpeditor/cm/demo/theme.html
@@ -28,6 +28,7 @@
<link rel="stylesheet" href="../theme/hopscotch.css">
<link rel="stylesheet" href="../theme/icecoder.css">
<link rel="stylesheet" href="../theme/isotope.css">
+<link rel="stylesheet" href="../theme/juejin.css">
<link rel="stylesheet" href="../theme/lesser-dark.css">
<link rel="stylesheet" href="../theme/liquibyte.css">
<link rel="stylesheet" href="../theme/lucario.css">
@@ -130,6 +131,7 @@ function findSequence(goal) {
<option>icecoder</option>
<option>idea</option>
<option>isotope</option>
+ <option>juejin</option>
<option>lesser-dark</option>
<option>liquibyte</option>
<option>lucario</option>
diff --git a/help3/xhpeditor/cm/demo/vim.html b/help3/xhpeditor/cm/demo/vim.html
index 172ab6f..41406b4 100644
--- a/help3/xhpeditor/cm/demo/vim.html
+++ b/help3/xhpeditor/cm/demo/vim.html
@@ -6,8 +6,6 @@
<link rel="stylesheet" href="../lib/codemirror.css">
<link rel="stylesheet" href="../addon/dialog/dialog.css">
-<link rel="stylesheet" href="../theme/midnight.css">
-<link rel="stylesheet" href="../theme/solarized.css">
<script src="../lib/codemirror.js"></script>
<script src="../addon/dialog/dialog.js"></script>
<script src="../addon/search/searchcursor.js"></script>
diff --git a/help3/xhpeditor/cm/doc/logos/4me.svg b/help3/xhpeditor/cm/doc/logos/4me.svg
new file mode 100644
index 0000000..8e894ee
--- /dev/null
+++ b/help3/xhpeditor/cm/doc/logos/4me.svg
@@ -0,0 +1 @@
+<svg fill-rule="evenodd" viewBox="10538 7547.8 6693 4459" xmlns="http://www.w3.org/2000/svg"><rect fill="#062341" x="10538" y="7547.8" width="6693.4" height="4459.4"/><path fill="#fefefe" 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="#fefefe" 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="#fefefe" 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>
diff --git a/help3/xhpeditor/cm/doc/logos/anvil.png b/help3/xhpeditor/cm/doc/logos/anvil.png
new file mode 100644
index 0000000..7cb2ab1
--- /dev/null
+++ b/help3/xhpeditor/cm/doc/logos/anvil.png
Binary files differ
diff --git a/help3/xhpeditor/cm/doc/logos/artcompiler.svg b/help3/xhpeditor/cm/doc/logos/artcompiler.svg
new file mode 100644
index 0000000..d8349a1
--- /dev/null
+++ b/help3/xhpeditor/cm/doc/logos/artcompiler.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 70.5 70.5"><path fill="#fefefe" d="M64.4 114.7V79.5h70.5V150H64.4zm37.6 34.6-1.7-24.2v-.3h-1a9 9 0 0 1-1.7-.3 1079.2 1079.2 0 0 0-7.8 23.2l.8.3a35.6 35.6 0 0 0 11.4 1.3zm-18.5-7.7 3.4-1.9 1 .5a29 29 0 0 0 2.7 1.1l1.5-4.6-.7-.3a23.3 23.3 0 0 1 6.1-44.8v-2.4l-.3-2.4c0-.1-.3-.1-2 .1a27 27 0 0 0-7.2 2.3l-.9.4-3.4-1.9-3.5-1.9a38.4 38.4 0 0 0-9.1 9l-.3.5 2 3.4 2 3.4-.4 1a34 34 0 0 0-.8 1.8l-.3 1-3.9 1.2-3.8 1.1s-.3 1.2-.4 2.6a55.7 55.7 0 0 0 .4 10.7s1 .4 3.9 1.1l3.8 1 .3.8.7 1.7.3 1a432.5 432.5 0 0 1-3.9 6.7c0 .2.8 1.4 2 3a47.7 47.7 0 0 0 7.3 6.6l3.5-1.9zm21.6.3a25.8 25.8 0 0 0 6.8-2.2 1286.7 1286.7 0 0 0-7.8-15.6l-.7.1-1.3.4-.7.1v.4a1616.2 1616.2 0 0 0 1.3 17h.6l1.7-.2zm-10.5-12.4 1.8-5.5-.6-.3a10 10 0 0 1 2.3-18.9c.4 0 .6-.1.6-.2l-1-11.5h-1A21.8 21.8 0 0 0 79.7 122a22.3 22.3 0 0 0 13 13c.1 0 1-2.4 2-5.4zm17.4 4.7 2.6-1.8c1-.8 2.4-2.2 2.4-2.4l-3.6-3.2-4.8-4-1.2-1-.6.4a14.3 14.3 0 0 1-1.6 1.3 391 391 0 0 0 5.8 11.3l1-.6zm12.5-.7a31.1 31.1 0 0 0 4.7-8.8 337.7 337.7 0 0 0-19.6-6.3l-.4.6-.7 1.2-.4.6.3.2a2416.5 2416.5 0 0 1 15.5 13l.5-.5zm-22.7-10a8.6 8.6 0 0 0 4.6-2.5 8.6 8.6 0 0 0 2.6-6.3c0-1.2 0-1.5-.2-2.2-.4-1.6-1.1-2.9-2.2-4a8.9 8.9 0 0 0-8.7-2.6 9 9 0 0 0 4 17.6zm24.9-1.3a29.8 29.8 0 0 0 1-9c-.1-.1-2.5 0-8.6.5l-8.6.8h-.3v.8l-.2 1.4-.1.5 1 .3 15.6 5 .2-.4zm-4.7-9.8 12.1-1h.4v-.6a36.7 36.7 0 0 0-3.4-11.3l-21.6 11.1.2.8.3 1.4.2.6 11.8-1zm-6.5-6.2 4.6-2.4-1.2-2c-.8-1.1-1.8-2.4-2.8-3.3l-.8-.8-4 4.7-4 4.8c-.1.1-.1.2.4.8l.9 1.1.3.5 1-.5 5.6-2.9zm-3-7.1 6.7-7.8.3-.4-.8-.7a31 31 0 0 0-8.6-4.5l-6.3 19.5.8.4a11.1 11.1 0 0 1 1.6 1l6.4-7.5zm-6.1-5.8 3.6-11.6-1.4-.4a40.4 40.4 0 0 0-10.7-1l2 24.2h.7l1.2.2.7.1c.2 0 .6-1.2 3.9-11.5z" transform="translate(-64.4 -79.5)"/><path fill="#efd1cf" d="M102.7 141.2v-.1.2-.1zm-.1-1.1v-.1.2-.1zm-.1-1.1v-.1.2-.1zm0-1.1v-.1.2-.1zm-.2-1.1v-.1c.1 0 .1.1 0 .2v-.1zm0-1.1v-.1.2-.1zm-.1-1.1v-.1.2-.1zm-.1-1.1v-.1.2-.1zm0-1.1v-.1.2-.1zm-.2-1.1v-.1c.1 0 .1.1 0 .2v-.1zm14.4-.5.6-.5-.5.5-.6.6.5-.6zm-14.4-.6v-.1.2zm-.1-1.1v-.1.2zm-.1-1.1v-.1.2zm0-1.1v-.1.2zm-.2-1.1v-.1.2zm-.4-2.2h.1-.1zm4.7-1.9v-.1c.2-.1.2-.1.1 0l-.2.1zm-12.1-.6-.4-.5.4.4.4.5-.4-.4zm33.9-3.8s0-.1 0 0v.1-.1zm0-1.2c0-.1.1-.1.1 0v.2-.2zm-49.2-.3s0-.1 0 0v.2-.1zm12.6-1.1v-.2.4-.2zm20.2-.3h.2-.1c-.1 0-.1 0 0 0zm1 0h.2-.1c-.1 0-.1 0 0 0zm1-.1h.2-.1s-.1 0 0 0zm1-.1h.2-.1zm1 0c.1-.1.2-.1.2 0h-.1zm1-.2h.2-.1zm1 0h.3-.2zm1.1-.1h.2-.2zm1-.1h.2-.1c-.1 0-.1 0 0 0zm1 0c0-.1.2-.1.2 0h-.1c-.1 0-.1 0 0 0zm-42-.3c0-.1 0-.2.1-.1v.2-.1zm43 .1h.2-.1c-.1 0-.1 0 0 0zm6.3-.1v-.1.2-.1zm-5.3 0h.2-.1c-.1 0-.1 0 0 0zm1 0h.2-.1s-.1 0 0 0zm-12.7-.1h.1-.1zm13.8 0h.1-.1zm-12.8 0c0-.1.1-.1.2 0h-.2v-.1zm13.8 0c0-.1.1-.1.2 0h-.2v-.1zm-12.8-.2h.2-.1c-.1 0-.1 0 0 0zm13.8 0h.2-.1c-.1 0-.1 0 0 0zm-12.8 0h.2-.1c-.1 0-.1 0 0 0zm13.8 0h.2-.1c-.1 0-.1 0 0 0zm-12.7-.1h.1-.1s-.1 0 0 0zm1-.1h.1-.1zm1 0c0-.1.1-.1.1 0-.2 0-.2 0-.1-.1zm-23-4.6.4-.4-.4.4-.4.4s0-.2.3-.4zm14-.2c-.1-.2-.1-.2 0 0h.2c0 .1 0 .1-.2 0zm-2-.4.2.2-.1-.1zm2.1-1.2.1-.1c.2-.1.2-.1 0 0l-.1.1zm-6.8-.8h.2-.1c-.1 0-.1 0 0 0zm7.7-.3.2-.1c.1-.1.1-.1 0 0-.1.2-.2.2-.2.1zm-8.6-.8h.4-.4zm9.6-.3.1-.1c.1-.1.1-.1 0 0 0 .2-.1.2-.1.1zm-11.1-.1v-.1.2-.1zm1-.6c0-.1.1-.1.1 0zm11-.4.1-.1c.2-.1.2-.1 0 0 0 .2-.1.2-.1.1zm-11-.6v-.1.2-.1zm12-.4v-.2h.1l-.2.2zm-12-.7v.2-.2zm12.9-.4.1-.2c.1 0 .1 0 0 0l-.1.2zm-13-.6v.1zm-1.2-.5v.1zm15.1 0 .1-.2c.2 0 .2 0 0 0l-.1.2zm-28.7-.6.3-.3-.2.3a2 2 0 0 1-.4.3l.3-.3zm32.3.2-.2-.2.2.1.2.2-.2-.2zm-18.8-.8c0-.1 0-.1 0 0v.1-.1zm-15.3 0 .2-.1c0-.1 0-.1 0 0l-.2.1zm31.4-.2.2-.1c.1-.1.1-.1 0 0-.1.2-.2.2-.2.1zM98.1 98c0-.1 0-.1 0 0zm-14-.1.2-.2-.2.2-.1.1v-.1zm13.9-1v.2-.1zm0-1v.2-.1zm1-.5c0-.1 0-.1 0 0zm0-1c0-.1 0-.2 0 0zm-.1-1v-.1.2-.2zm-1.3-.2h.1-.1zm1.2-.9v.2-.2zM74 91h.2c0-.2 0-.2 0 0-.1 0-.2.1-.2 0zm2-1.9V89c.2-.1.2-.1.1 0l-.2.1zm22.2-2v.2-.1zm0-1v.2-.2zm-.1-1v.1zm-.1-1v.1zm4.5-3.7h.2-.1c-.1 0-.1 0 0 0zm-3.7 0h.5-.4zm1.9 0c.1-.1.3-.1.4 0h-.4z" transform="translate(-64.4 -79.5)"/><path fill="#eac1b8" d="M98.3 149.3h.2-.2zm3.4 0h.2-.2zm-4.7-.1h.2-.1c-.1 0-.1 0 0 0zm4.9-.4c0-.1 0-.1 0 0zm-.1-1.2c0-.1 0-.1 0 0v.1-.1zm0-1.2s0-.1 0 0v.1zm-.2-1.2c.1 0 .1.1 0 .1zm0-1.1v-.1.2-.1zm-.1-1.2c0-.1 0-.1 0 0zm1.3-.9v.1zm-1.4-.3s0-.1 0 0v.1-.1zm1.3-.8v.2-.2zm-1.4-.4v.1zm1.3-.6v-.1.2-.1zm-1.4-.5v-.1c.1 0 .1.1 0 .2v-.1zm1.3-.6c0-.1 0-.1 0 0zm-1.3-.6c0-.1 0-.1 0 0zm1.2-.5c0-.1 0-.1 0 0 .1 0 .1 0 0 0 0 .1 0 0 0 0zm-1.3-.7s0-.1 0 0v.1-.1zm1.3-.4c0-.1 0-.1 0 0zm-1.4-.8v.1zm1.3-.3c0-.1 0-.1 0 0v.1-.1zm-1.4-.8v-.1.2-.1zm1.3-.3s0-.1 0 0v.1-.1zm-1.4-1c0-.1 0-.1 0 0 .1 0 .1 0 0 .1v-.1zm1.3 0v-.1.1zm-1.3-1.2s0-.1 0 0v.1zm1.2 0s0-.1 0 0c.1 0 .1 0 0 .1zm0-1v-.1.1zm-1.3-.2v.1zm-15.3-.3c0-.1 0-.1 0 0l.2.1-.2-.1zm16.5-.7v.1zm-1.3-.1c0-.1 0-.1 0 0zm-16.5-.6c-.1 0-.1 0 0 0l.2.2-.2-.2zm17.7-.4v.2-.2zm-1.3-.2c0-.1 0-.1 0 0v.1-.1zm1.2-.8v-.1.2-.1zm-1.3-.4c.1 0 .1.1 0 .1zm1.2-.7c0-.1 0-.1 0 0zm-1.3-.5c.1 0 .1.1 0 .2v-.2zm1.2-.6c0-.1 0-.1 0 0zm-1.2-.5-.4-.2h-.3.3l.4.1v.2-.1zm-1-1.4c.1 0 0 0 0 0-.1 0-.1 0 0 0zm-6.3-2a2 2 0 0 1-.3-.3l.4.4.3.4-.4-.4zm-28-4v.2-.1zm62.5-.8c.1 0 .1.1 0 .1zm-62.6-.4s0-.1 0 0v.2-.1zm11.8-.3s0-.1 0 0c.1 0 .1 0 0 .1zm51-.8v-.2.5-.3zm-18.7-.3v-.1.2-.1zm1.2-.3v-.2.4-.2zm.2-.4h.2-.2zm1 0h.2-.1c-.1 0-.2 0 0 0zm-2.4-.3v-.1.3-.2zm3.4.1h.2-.1c-.1 0-.1 0 0 0zm15.2-.3v-.1.4-.3zm-14.2.3h.2-.1c-.1 0-.1 0 0 0zm1-.1h.2-.1s-.1 0 0 0zm1-.1h.2-.1zm1 0c.1-.1.2-.1.2 0h-.1zm1-.2h.2-.1zm1 0h.3-.2zm1.1-.1h.2-.2zm1-.1h.2-.1c-.1 0-.1 0 0 0zm1 0c0-.1.2-.1.2 0h-.1c-.1 0-.1 0 0 0zm1-.2h.2-.1c-.1 0-.1 0 0 0zm1 0h.2-.1c-.1 0-.1 0 0 0zm-46.8-.2s0-.1 0 0v.1-.1zm47.9 0h.1l-.1.1s-.1 0 0 0zm1 0h.1-.1zm1 0c0-.1.1-.1.1 0-.2 0-.2 0-.1-.1zm-61.8-.4s0-.1 0 0v.1zm0-1.1c0-.1 0-.1.1 0 0 .1 0 0 0 0zm32.5-23.1v-.1.2-.1zm0-1v-.1.2-.2z" transform="translate(-64.4 -79.5)"/><path fill="#e0a39d" d="M98.7 149.3h.4-.4zm2.5 0h.3H101.2zm-4-.1h.3-.2zm4.7-.1v-.1.2-.1zm0-1.2v-.1.2-.1zm-.2-1.2c0-.1 0-.2 0 0v.1zm0-1.2c0-.1 0-.1 0 0zm-.1-1.2s0-.1 0 0v.1-.1zm-.1-1.2v.1zm-.1-1.2v.1zm1.4-.1c0-.1 0-.1 0 0zm-1.5-1c0-.1 0-.1 0 0zm1.4-.1c0-.1 0-.1 0 0v.1-.1zm-1.5-1.1c0-.1 0-.1 0 0 .1 0 .1 0 0 .1v-.1zm1.4 0c0-.1 0-.1 0 0v.1-.1zm0-1.1c0-.1 0-.1 0 0v.1-.1zm-1.4 0v-.1.1zm1.2-1.1s0-.1 0 0c.1 0 .1 0 0 .1v-.1zm-1.3-.2v.1zm1.2-.9s0-.1.1 0v.1zm-1.3-.2c0-.1 0-.2 0 0zm1.3-.9v.1zm-1.4-.3c0-.1 0-.1 0 0v.1-.1zm1.3-.8v.1zm-1.4-.4v-.1c.1 0 .1.1 0 .2v-.1zm1.3-.7v.1zm-1.3-.5v-.1.2zm1.2-.6c.1 0 .1.1 0 .2v-.2zm-18.5-.6-.2-.3.2.3.3.2-.3-.2zm17.2 0s0-.1 0 0v.1zm1.2-.4c0-.1 0-.2 0 0 .1 0 .1 0 0 0zm-17.2-.9-.5-.6.6.6.5.5-.5-.5zm15.9 0v.2-.1zm1.3-.2c0-.1 0-.2 0 0zm-1.4-.9v.1zm1.3-.2c0-.1 0-.1 0 0zm-1.4-1c.1 0 .1.1 0 .1zm1.3-.1c0-.1 0-.1 0 0zm-1.4-1c0-.1 0-.1.1 0 0 .1 0 0 0 0zm1.3-.1c0-.1 0-.1 0 0v.1-.1zm-1.3-1.1c0-.1 0-.1 0 0v.1-.1zm1.2 0c0-.1 0-.1 0 0 .1 0 .1 0 0 .1v-.1zm-2.2-.4h.2-.2zm.2-1.2h.2-.2zm1 0h.3-.2zm6.7-1.7.1-.1c.2-.1.2-.1 0 0l-.1.1zm-.8-.9.5-.4-.4.4-.4.4zm-41.3-2.5c.1 0 .1.1 0 .1zm0-1v.2-.1zm62.5-.8v.2-.2zm-50.8-.1c0-.1 0-.1 0 0v.1-.1zm-11.8-.3v-.1.2-.1zm26.1-.8s0-.1 0 0c.1 0 .1 0 0 .1v-.1zm-12.6-.3v-.2.4-.2zm31.8.1v.1zm-20.3-.7v-.3.6-.3zm37.7.1v-.1.4-.3zm-18.6 0v-.2.3-.1zm1.6-.2h.2-.1s-.1 0 0 0zm1-.1h.2-.1zm-33.3-.4v-.2.4-.2zm34.4.3h.1-.1zm1 0h.1-.1zm1-.1h.2-.2zm1-.1h.2-.1c-.1 0-.2 0 0 0zm1-.1h.2-.1c-.1 0-.1 0 0 0zm-25.7-.2v.1zm26.7.1h.2-.1c-.1 0-.1 0 0 0zm1 0h.2-.1s-.1 0 0 0zm1-.2h.2-.1zm1 0h.2-.1zm1-.1h.2-.1zm-56.9-.3v-.1.3-.2zm58 .2h.2-.2zm1 0c0-.1.1-.1.2 0h-.1c-.1 0-.1 0 0 0zm-13.5-.2h.1-.1zm14.5 0h.2-.1c-.1 0-.1 0 0 0zm-13.5 0h.2-.2zm14.6 0h.1-.1s-.1 0 0 0zm-13.6-.1h.2-.1c-.1 0-.1 0 0 0zm14.6 0h.1-.1zm-50.2-.2v.1zm36.6 0h.2l-.1.1c-.1 0-.1 0 0 0zm1 0h.2-.1c-.1 0-.1 0 0 0zm1 0h.2-.1c-.1 0-.1 0 0 0zm1-.2h.2-.1s-.1 0 0 0zm1 0h.2-.1zm1-.1h.2-.1zm1 0c.1-.1.2-.1.2 0-.2 0-.2 0-.1-.1zm1-.2h.3-.2zm1.1 0h.2-.2zm1-.1h.2-.1c-.1 0-.1 0 0 0zm1-.1h.2-.1c-.1 0-.1 0 0 0zm1 0c0-.1.2-.1.2 0h-.1c-.1 0-.1 0 0-.1zm1-.2h.2-.1c-.1 0-.1 0 0 0zm1 0h.2-.1s-.1 0 0 0zm1-.1h.2-.1zm1-.1h.2-.1zm1 0c.1-.1.2-.1.2 0-.2 0-.2 0-.1-.1zm1-.2h.3-.2zm1.1 0h.2-.2zm1-.1h.2-.1c-.1 0-.1 0 0 0zm1-.1h.2-.1c-.1 0-.1 0 0 0zm-27.3-3a2 2 0 0 1-.3-.4l.4.4.3.3-.4-.3zm1-.8c-.3-.2-.3-.2-.1-.4.1 0 .1 0 0 0l.1.4.2.3-.2-.3zm.3-.8v-.2h.1c0 .2-.2.2-.2.2zm-8.3-1h.2-.2zm1.1 0h.2-.2zm8-.1.2-.2c.2 0 .2 0 0 0l-.1.2zm-7.8-1.2h.2-.2zm8.8 0h.2c0-.2 0-.2 0 0-.1.1-.2.1-.2 0zm-10.9-.1c0-.1 0-.1 0 0v.1-.1zm1.2 0v-.1.1zm-1.3-1c0-.1 0-.1 0 0zm12 0c.2-.2.2-.2.1 0-.1.1-.2.1-.2 0zm-10.8-.1s0-.1 0 0v.1-.1zm-1.3-1c.1 0 .1.1 0 .2v-.1zm1.2 0c0-.1 0-.1 0 0v.1-.1zm11.8 0h.1c.1-.2.1-.2 0 0 0 .1-.1.2-.1 0zm-13-1v.2-.1zm13.9 0 .1-.1c.2-.1.2-.1 0 0l-.1.1zm-14-1.3c0-.1 0-.2.1-.1v.2-.2zm1.2-.2c0-.1 0-.1 0 0 .1 0 .1 0 0 .1v-.1zm13.8 0 .2-.1c0-.1 0-.1 0 0l-.2.1zm-13.9-1c0-.1 0-.1.1 0zm16.8-.6-.7-.7.7.7zm-2 .5.2-.2c.1 0 .1 0 0 0l-.1.2zm-14.8-1v.2-.2zm-15-.4.1-.2c.1 0 .1 0 0 0l-.1.2zM98 97v.1zm1.2 0V97v.2-.2zm-1.3-1s0-.1 0 0v.1zm1.2 0V96v.1zm-1.3-1s0-.1 0 0v.1-.1zm1.2 0V95v.1zm-1.3-1c0-.1 0-.1 0 0v.1-.1zm1.2 0V94v.1zm-1.4-3.2v.1zm1.2 0v-.1.2-.1zm-24.2-.4.3-.2-.2.2-.2.2.1-.2zm22.9-.6v.1zm1.2 0v-.1.2-.2zm-22.9-.6.3-.2-.2.2-.2.2.1-.2zm21.6-.4s0-.1 0 0v.1-.1zm1.2 0v-.1.1zm-1.3-1c0-.1 0-.1 0 0v.1-.1zm1.2 0v-.1.1zm0-1.1s0-.1 0 0v.1-.1zm-.2-1c0-.1 0-.1 0 0 .1 0 .1 0 0 .1v-.1zm-.2-3.1c0-.1 0-.2 0 0zm0-1v-.1.2-.2zm-.2-1v-.1c.1 0 .1.1 0 .1zm4.5-.4h.2-.2zm-2.5 0h.6-.6z" transform="translate(-64.4 -79.5)"/><path fill="#d6836c" d="m102.8 142.2-1.3-17v-.4l.4-.1 1.2-.3.9-.3a174 174 0 0 1 7.9 15.6 29.9 29.9 0 0 1-9.1 2.5zM76 140.4l-.1-.2.1.2.2.2-.2-.2zm-1.7-1.7c-.1-.1-.1-.1 0 0 .2 0 .2.1.1.1l-.1-.1zm9.6-7-.2-.3.3.2.2.3-.3-.2zm31.7-.2.1-.2v.2l-.3.1.2-.1zm-32.6-.7-.1-.2.2.2.1.2-.2-.2zm33.8-.5.1-.2c.1 0 .1 0 0 0l-.1.2zM99 123.6a9 9 0 0 1-7.8-6.9 9 9 0 0 1 4.9-10.1 9 9 0 0 1 11.3 13.1 9.3 9.3 0 0 1-8.4 3.9zm19-3.8-8.1-2.5v-.6a13 13 0 0 0 .3-2.1l16.8-1.4h.5v1.5a26.9 26.9 0 0 1-1.2 7.7l-8.3-2.5zm-11.2 2.4.2-.2-.1.2-.2.1.1-.1zm-28.5-5.7c0-.1 0-.1 0 0 .1 0 .1 0 0 0zm11.6-1.2c0-.1 0-.1 0 0zm-11.6-.6v-.2.3-.1zM90 114v-.1.2-.1zm20.1-.7v-.1h.1v.1zm1 0h.2-.2zm1-.1h.2-.2zm1-.1h.2-.1c-.1 0-.1 0 0 0zm1 0c0-.1.2-.1.2 0h-.1c-.1 0-.1 0 0 0zm-35.7-.2c0-.1 0-.1 0 0zm36.7 0h.2-.1c-.1 0-.1 0 0 0zm1 0h.2-.1s-.1 0 0 0zm1-.1h.2-.1zm1-.1h.2-.1zm1 0c.1-.1.2-.1.2 0-.2 0-.2 0-.1-.1zm1-.2h.3-.2zm1.1 0h.2-.2zm1-.1h.2-.1c-.1 0-.1 0 0 0zm1-.1h.2-.1c-.1 0-.1 0 0 0zm1 0c0-.1.2-.1.2 0h-.1c-.1 0-.1 0 0-.1zm1-.2h.2-.1c-.1 0-.1 0 0 0zm1 0h.2-.1s-.1 0 0 0zm1-.1h.2-.1zm1-.1h.2-.1zm-19.7-2.7-.9-1.1c-.4-.6-.5-.6-.4-.8.1 0 2-2.2 4-4.8l4-4.6 1 1a22.8 22.8 0 0 1 3.7 5l-11 5.7c-.1 0-.3-.1-.4-.4zm-16-1.3.3-.3.3-.2-.2.2-.3.3zm7.2-3.8v.1zm-1.3-.4s0-.1 0 0v.1zm1.2-.6v.1zm-1.3-.4s0-.1 0 0v.1-.1zm1.2-.6s0-.1 0 0v.1zm0-1s0-.1 0 0v.1-.1zM84 99.9l.2-.2v.2l-.3.1.1-.1zm14-.5s0-.1.1 0v.1-.1zm-12.9-.6.2-.2v.2l-.3.1.1-.1zm12.9-.4c0-.1 0-.1 0 0v.1-.1zm1.1-.6s0-.1.1 0v.1-.1zm-1.2-.4c0-.1 0-.1 0 0zm1.2-.6c0-.1 0-.1 0 0v.1-.1zm-1.3-.4c0-.1 0-.1 0 0zm1.2-.6c0-.1 0-.1 0 0zm-1.3-.4c0-.1 0-.2 0 0zm1.2-.6c0-.1 0-.1 0 0zm-1.3-.5v.2-.2zm1.2-.5c0-.1 0-.2 0 0zm0-1v-.1.2-.2zm-.2-1v-.1c.1 0 .1.1 0 .1zM75.1 90l.4-.4-.3.4-.4.3zm23.5-.4c0-.1 0-.1 0 0v.1-.1zm-.1-1c0-.1 0-.1 0 0zm0-1c0-.1 0-.1 0 0zm-.2-1c0-.1 0-.2 0 0 .1 0 .1 0 0 0zm0-1v-.1.2-.2zm-.1-1v-.1.1zm-.1-1v-.1.1zm-.2-3.2h.2c.2-.1.2 0 0 0H98c0 .1 0 .1 0 0zm5.3 0h.1-.1zm-1.2 0c0-.1.1-.1.2 0h-.2z" transform="translate(-64.4 -79.5)"/><path fill="#c85d4b" d="M99.6 149.3zm-2-.1h.1-.1s-.1 0 0 0zm4.2-1c0-.1 0-.1 0 0v.1-.1zm0-1.2s0-.1 0 0v.1zm-.2-1.2c.1 0 .1.1 0 .1zm0-1.2v.2-.2zm-.1-1.1c0-.1 0-.1 0 0zm-.1-1.2c0-.1 0-.1 0 0v.1-.1zm0-1.2s0-.1 0 0v.1zm-.2-1.2c.1 0 .1.1 0 .1zm0-1.2v.2-.2zm-.1-1.2c0-.1 0-.1 0 0zm-.1-1.2s0-.1 0 0v.1-.1zm0-1.2v.1zm7.2-6-2.9-5.5.5-.4 1-.8.6-.5.2.2a1242.5 1242.5 0 0 0 9.2 7.7l.3.3-.9.8a24.8 24.8 0 0 1-5.2 3.9l-2.8-5.6zm-7.4 4.8c.1 0 .1.1 0 .1zm0-1.1c0-.1 0-.2 0 0zm-.1-1.2c0-.1 0-.1 0 0zm-15-.8c-.1-.1-.1-.1 0 0l.1.1h-.1zm14.9-.4s0-.1 0 0v.1zm-.1-1.2v.1zm-16.6-.2c-.1 0-.1 0 0 0 .2.1.2.2.1.2l-.1-.1zm16.5-1v.2-.2zm0-1.1c0-.1 0-.1 0 0zm-.1-1.2c0-.1 0-.1 0 0v.1-.1zM65 117.5c0-.1 0-.1 0 0 .1 0 .1 0 0 0 0 .1 0 0 0 0zm0-2v-.3.6-.3zm11.7-.6v-.5a15.7 15.7 0 0 1 0 .5zm-11.7-.6v-.3.6-.3zm0-2c.1 0 .1.1 0 .1zm28.2-5h.2c0-.2 0-.2 0 0-.1 0-.2.1-.2 0zm-8.5-8 .4-.3-.4.4-.4.3zm12.8-8.1c0-.1 0-.1 0 0v.1-.1zm-.1-1c0-.1 0-.1 0 0zm0-1c0-.1 0-.1 0 0zm-.2-1c0-.1 0-.2 0 0 .1 0 .1 0 0 0z" transform="translate(-64.4 -79.5)"/><path fill="#c5523e" d="m75.2 139.6-.7-.7.7.6.7.8-.7-.7zm16.6-5A22 22 0 0 1 79 119.9c-.6-2.2-.8-5.2-.6-7.4.5-4.9 2.6-9.3 6-12.9a21.3 21.3 0 0 1 13.1-6.4l1 11.1c0 .3 0 .3-.7.5a10 10 0 0 0-2.2 18.9l.6.3-3.6 11-1-.5zm-7.5-2.6c-.1-.1-.1-.1 0 0l.1.1-.1-.1zm-1.6-1.5c0-.2 0-.2 0 0h.2c0 .1 0 .1-.2 0zm27.4-17.4c-.1-.9-.3-1.5-.5-2l-.2-.4 10.8-5.6 10.9-5.5a30.3 30.3 0 0 1 2.8 8.3l.5 3.2v.2l-12 1-12.2 1v-.2zm-8-8.4-1.3-.2h-1v-.5L98 80.4h2.3a29 29 0 0 1 9.6 1.3l-3.4 11-3.7 11.5-.2.6zm-18.6-6.5.4-.3-.4.4-.4.3z" transform="translate(-64.4 -79.5)"/><path fill="#b4111a" d="M97 149.1a39 39 0 0 1-7.2-1.4l3.8-11.6 3.9-11.6.5.2 1.3.1c.7 0 .9.1.9.2a5523.8 5523.8 0 0 0 1.7 24c0 .2-.2.2-2 .2H97zM79 143a37.9 37.9 0 0 1-7.7-8c-.5-.7-.6-.8-.5-1a155.3 155.3 0 0 1 3.8-6.8l-.4-1a38.9 38.9 0 0 1-1-2.4l-3.6-1-3.7-1h-.3l-.2-1.2a32.9 32.9 0 0 1 0-10.9l.1-1.2.6-.2a395.4 395.4 0 0 1 7-2l.5-1 .8-2 .4-1-2-3.4-2-3.4.5-.7A35.8 35.8 0 0 1 80 86l3.6 1.9 3.5 2 .8-.5a28.5 28.5 0 0 1 9.2-2.5 33.8 33.8 0 0 1 .4 4.4c0 .4 0 .4-.3.4l-3 .5a23.4 23.4 0 0 0-2.2 44.6l-1.5 4.5-2.8-1.1-.8-.4-3.5 1.9c-1.9 1-3.4 1.9-3.4 2l-1-.7zm37.2-15.3-7.8-6.6-.2-.2.4-.5.6-1.2.3-.6 19.6 6.2a27 27 0 0 1-5.1 9.3l-7.8-6.4zm-10.5-21.4-1.9-1a1150.6 1150.6 0 0 1 6.4-19.4 28.3 28.3 0 0 1 9 4.8l.2.3-6.6 7.7a866 866 0 0 1-6.6 7.9l-.5-.3z" transform="translate(-64.4 -79.5)"/></svg>
diff --git a/help3/xhpeditor/cm/doc/logos/cargo.svg b/help3/xhpeditor/cm/doc/logos/cargo.svg
new file mode 100644
index 0000000..0690183
--- /dev/null
+++ b/help3/xhpeditor/cm/doc/logos/cargo.svg
@@ -0,0 +1 @@
+<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>
diff --git a/help3/xhpeditor/cm/doc/logos/codepen.svg b/help3/xhpeditor/cm/doc/logos/codepen.svg
new file mode 100644
index 0000000..cc3d127
--- /dev/null
+++ b/help3/xhpeditor/cm/doc/logos/codepen.svg
@@ -0,0 +1 @@
+<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>
diff --git a/help3/xhpeditor/cm/doc/logos/desmos.svg b/help3/xhpeditor/cm/doc/logos/desmos.svg
new file mode 100644
index 0000000..b47e4d9
--- /dev/null
+++ b/help3/xhpeditor/cm/doc/logos/desmos.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 107.05 22.17" fill="#187a3d"><path 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"/><path 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"/></svg>
diff --git a/help3/xhpeditor/cm/doc/logos/executeprogram.svg b/help3/xhpeditor/cm/doc/logos/executeprogram.svg
new file mode 100644
index 0000000..0f75b69
--- /dev/null
+++ b/help3/xhpeditor/cm/doc/logos/executeprogram.svg
@@ -0,0 +1 @@
+<svg width="397" height="109" viewBox="0 0 397 109" xmlns="http://www.w3.org/2000/svg"><g fill-rule="nonzero" fill="none"><path d="M169.495 63.68c2.8 0 5.254.671 7.36 2.015 2.105 1.344 3.688 3.162 4.751 5.453 1.063 2.292 1.594 4.878 1.594 7.76 0 4.408-1.241 8.054-3.724 10.935-2.483 2.881-5.81 4.322-9.98 4.322-3.953 0-7.18-1.402-9.683-4.206v12.62c0 .271-.085.489-.254.653a.88.88 0 0 1-.64.247h-4.767a.966.966 0 0 1-.656-.232c-.178-.155-.268-.377-.268-.668V65.188c0-.271.09-.489.268-.653a.932.932 0 0 1 .656-.247h4.767a.88.88 0 0 1 .64.247c.17.164.254.382.254.653v3.393h.625c1.986-3.268 5.006-4.902 9.057-4.902zm-.84 24.874c2.752 0 4.865-.86 6.34-2.578 1.473-1.719 2.21-4.034 2.21-6.947 0-2.874-.737-5.156-2.21-6.846-1.475-1.69-3.588-2.534-6.34-2.534-2.576 0-4.625.855-6.148 2.563-1.524 1.71-2.285 3.986-2.285 6.831s.761 5.141 2.285 6.89c1.523 1.747 3.572 2.62 6.148 2.62zm39.147-24.875c3.374 0 6.111.99 8.213 2.968 2.1 1.978 3.151 4.771 3.151 8.379 0 .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 0-2.757.266-3.95.8-1.194.533-2.142 1.183-2.842 1.949-.7.766-1.238 1.513-1.613 2.24-.375.727-.562 1.333-.562 1.818v16.147c0 .271-.084.49-.252.654a.87.87 0 0 1-.636.248h-4.735a.954.954 0 0 1-.651-.233c-.178-.155-.267-.378-.267-.669V65.221c0-.271.09-.49.267-.654a.922.922 0 0 1 .65-.248h4.47c.552 0 .858.3.917.902l.237 3.928h.68c1.086-1.571 2.52-2.876 4.306-3.913 1.786-1.038 3.813-1.557 6.082-1.557zm31.331 30.845c-4.25 0-7.807-1.475-10.673-4.423-2.866-2.95-4.298-6.616-4.298-11s1.432-8.05 4.298-10.999c2.866-2.948 6.423-4.423 10.673-4.423 2.788 0 5.332.674 7.632 2.021 2.3 1.348 4.103 3.203 5.41 5.566 1.306 2.363 1.959 4.975 1.959 7.835 0 2.861-.653 5.468-1.96 7.821-1.306 2.353-3.109 4.209-5.41 5.566-2.3 1.357-4.843 2.036-7.63 2.036zm-6.43-8.608c1.7 1.759 3.847 2.638 6.445 2.638 2.597 0 4.745-.88 6.444-2.638 1.698-1.759 2.547-4.03 2.547-6.814 0-2.785-.849-5.057-2.547-6.815-1.699-1.759-3.847-2.638-6.444-2.638-2.598 0-4.746.88-6.444 2.638-1.699 1.758-2.548 4.03-2.548 6.815 0 2.784.85 5.055 2.548 6.814zm55.522-21.623c.272 0 .487.082.642.248.156.165.234.384.234.657v27.976c0 1.772-.302 3.373-.906 4.804-.603 1.431-1.402 2.6-2.395 3.504-.993.906-2.157 1.67-3.49 2.293a16.713 16.713 0 0 1-4.076 1.314c-1.383.253-2.814.38-4.294.38-2.337 0-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 1.198-.38 2.707 1.46 5.735 2.19 9.085 2.19 1.169 0 2.293-.116 3.374-.35 1.074-.23 2.107-.62 3.068-1.153a6.016 6.016 0 0 0 2.293-2.235c.564-.953.847-2.073.847-3.358v-3.855c-2.513 3.154-5.726 4.731-9.64 4.731-2.688 0-5.132-.676-7.333-2.03a13.905 13.905 0 0 1-5.112-5.475c-1.207-2.297-1.811-4.809-1.811-7.534 0-2.726.604-5.237 1.811-7.534 1.208-2.298 2.907-4.123 5.098-5.476 2.19-1.353 4.64-2.03 7.347-2.03 3.856 0 7.03 1.548 9.523 4.644l.175-3.125c.059-.604.36-.905.906-.905h4.236zm-13.596 23.266c2.408 0 4.424-.894 6.045-2.68 1.622-1.788 2.433-3.898 2.433-6.332 0-2.396-.811-4.477-2.433-6.246-1.621-1.768-3.637-2.652-6.045-2.652-2.428 0-4.452.86-6.074 2.581-1.622 1.72-2.433 3.826-2.433 6.317 0 2.529.811 4.663 2.433 6.402 1.621 1.74 3.646 2.61 6.074 2.61zm40.073-23.88c3.374 0 6.111.99 8.213 2.968 2.1 1.978 3.151 4.771 3.151 8.379 0 .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 0-2.757.266-3.95.8-1.194.533-2.142 1.183-2.842 1.949-.7.766-1.238 1.513-1.613 2.24-.375.727-.562 1.333-.562 1.818v16.147c0 .271-.084.49-.252.654a.87.87 0 0 1-.636.248h-4.735a.954.954 0 0 1-.651-.233c-.178-.155-.267-.378-.267-.669V65.221c0-.271.09-.49.267-.654a.922.922 0 0 1 .65-.248h4.47c.552 0 .858.3.917.902l.237 3.928h.68c1.086-1.571 2.52-2.876 4.306-3.913 1.786-1.038 3.813-1.557 6.082-1.557zm46.24 24.74c.393.098.673.22.84.367.167.147.25.377.25.69v3.551c0 .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 1.682-3.399 3.008-5.717 3.976-2.318.968-4.577 1.453-6.778 1.453-3.241 0-5.726-.749-7.455-2.245-1.729-1.497-2.593-3.547-2.593-6.149 0-2.621.835-4.656 2.504-6.104 1.67-1.448 4.214-2.416 7.633-2.906l6.984-1.085c1.355-.196 2.347-.401 2.976-.617.629-.215 1.041-.479 1.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 0-6.65 1.36-7.043 4.079-.059.45-.353.665-.884.646h-4.48c-.647 0-.942-.304-.883-.91.334-3.326 1.66-5.713 3.978-7.161 2.318-1.448 5.452-2.172 9.4-2.172 4.224 0 7.392.959 9.504 2.876 2.112 1.918 3.168 4.706 3.168 8.364v11.035c-.02 1.35.707 2.172 2.18 2.466zm-19.06.135c4.132 0 7.518-1.307 10.16-3.922v-6.028c-.258.566-1.53 1.024-3.814 1.375l-6.375.995c-1.728.274-2.96.742-3.695 1.405-.735.663-1.102 1.512-1.102 2.546 0 1.132.397 2.02 1.192 2.663.794.644 2.006.966 3.635.966zm48.252-24.875c2.377 0 4.116.796 5.216 2.386 1.1 1.59 1.65 4.248 1.65 7.971v18.59c0 .272-.079.49-.236.655-.157.165-.383.248-.677.248h-4.244a.948.948 0 0 1-.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 0-1.886.403-2.535 1.207a5.452 5.452 0 0 0-1.178 2.75v19.463c0 .271-.079.49-.236.654-.157.165-.383.248-.678.248h-4.155c-.275 0-.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 0-1.88.398-2.52 1.193a5.675 5.675 0 0 0-1.193 2.764v19.463c0 .271-.083.49-.25.654a.864.864 0 0 1-.634.248h-4.273c-.275 0-.496-.078-.662-.233-.168-.155-.251-.378-.251-.669V65.221c0-.271.083-.49.25-.654.167-.165.388-.248.663-.248h4.008c.57 0 .874.3.914.902l.147 2.386h.442c.943-2.619 2.898-3.928 5.864-3.928 2.849 0 4.745 1.31 5.688 3.928h.353c1.061-2.619 2.986-3.928 5.776-3.928zM162.091 16.126c1.86-.801 3.86-1.201 6.001-1.201 2.141 0 4.112.395 5.914 1.186 1.802.791 3.293 1.86 4.475 3.208 1.182 1.347 2.097 2.905 2.746 4.672.65 1.767.974 3.637.974 5.609 0 1.191-.121 2.04-.363 2.549-.243.507-.76.761-1.555.761h-20.807c.33 2.285 1.385 4.106 3.168 5.463 1.782 1.357 4.01 2.036 6.683 2.036 2.693 0 5.134-.84 7.324-2.52.464-.35.881-.341 1.249.03l1.947 1.992c.465.469.465.918 0 1.347-2.983 3.008-6.713 4.511-11.188 4.511-4.572 0-8.287-1.47-11.144-4.408-2.858-2.94-4.287-6.615-4.287-11.029 0-2.148.373-4.164 1.119-6.048.746-1.885 1.763-3.516 3.051-4.892 1.288-1.377 2.853-2.466 4.694-3.266zm5.71 3.774c-2.28 0-4.202.718-5.767 2.154-1.565 1.437-2.502 3.372-2.812 5.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 22.816c.236.268.3.513.191.733-.107.22-.348.33-.72.33h-5.562c-.47 0-.824-.162-1.06-.488l-8.592-10.002-8.592 10.002c-.255.326-.618.488-1.089.488h-5.532c-.373 0-.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 0 .833.172 1.088.517l7.798 9.082 7.798-9.082c.255-.325.618-.498 1.089-.517h5.473c.373 0 .618.105.736.316.117.21.059.46-.177.747l-11.152 12.933 11.976 13.795zm14.101-26.59c1.86-.801 3.86-1.201 6-1.201 2.142 0 4.113.395 5.915 1.186 1.801.791 3.293 1.86 4.475 3.208 1.182 1.347 2.097 2.905 2.746 4.672.65 1.767.974 3.637.974 5.609 0 1.191-.122 2.04-.364 2.549-.242.507-.76.761-1.554.761H230.41c.329 2.285 1.385 4.106 3.167 5.463 1.782 1.357 4.01 2.036 6.684 2.036 2.693 0 5.134-.84 7.323-2.52.465-.35.882-.341 1.25.03l1.947 1.992c.465.469.465.918 0 1.347-2.984 3.008-6.713 4.511-11.189 4.511-4.572 0-8.286-1.47-11.144-4.408-2.858-2.94-4.286-6.615-4.286-11.029 0-2.148.373-4.164 1.118-6.048.746-1.885 1.764-3.516 3.052-4.892 1.288-1.377 2.852-2.466 4.693-3.266zm5.71 3.774c-2.28 0-4.203.718-5.767 2.154-1.566 1.437-2.503 3.372-2.812 5.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 19.894c3.133 0 5.619-1.191 7.457-3.574.348-.45.745-.527 1.19-.234l3.394 1.962c.542.332.639.733.29 1.201-1.315 2.012-3.06 3.618-5.237 4.819-2.176 1.2-4.58 1.801-7.21 1.801-4.392 0-8.043-1.474-10.955-4.423-2.911-2.949-4.367-6.615-4.367-10.999s1.456-8.05 4.367-11c2.912-2.948 6.563-4.422 10.954-4.422 2.631 0 5.04.595 7.225 1.787 2.186 1.19 3.927 2.792 5.224 4.803.328.47.232.87-.29 1.202l-3.396 1.991c-.444.274-.841.196-1.19-.234-1.837-2.382-4.323-3.574-7.457-3.574-2.67 0-4.88.884-6.63 2.651-1.75 1.768-2.626 4.033-2.626 6.796s.875 5.028 2.626 6.796c1.75 1.767 3.96 2.65 6.63 2.65zm46.585-24.87c.276 0 .499.083.666.248.168.165.252.383.252.654v27.379c0 .271-.084.49-.252.654-.167.165-.39.247-.666.247h-4.475c-.573 0-.88-.3-.919-.901l-.237-3.953h-.652c-1.007 1.608-2.35 2.93-4.03 3.968-1.68 1.036-3.674 1.554-5.986 1.554-3.26 0-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 0 .499.082.666.247.168.165.252.383.252.654v15.956c0 2.403.583 4.18 1.749 5.334 1.165 1.153 2.785 1.73 4.86 1.73 1.343 0 2.573-.258 3.689-.771s1.99-1.129 2.623-1.846c.632-.717 1.116-1.4 1.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 24.474c.353.446.382.852.088 1.22-.882 1.047-2.172 2.001-3.868 2.863-1.697.862-3.731 1.293-6.104 1.293-8.002 0-12.003-3.932-12.003-11.799V20.537h-7.884a.885.885 0 0 1-.647-.261.864.864 0 0 1-.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 0 .466.078.633.233.166.154.25.368.25.639l-.02 9.285h11.943c.255 0 .466.082.632.247.167.164.25.382.25.654v3.603a.89.89 0 0 1-.25.64.837.837 0 0 1-.632.261H345.36v11.741c0 1.337.18 2.465.544 3.386.363.92.873 1.613 1.53 2.077a6.487 6.487 0 0 0 2.059.989c.716.193 1.534.29 2.456.29 1.98 0 3.824-.668 5.53-2.005.452-.426.873-.407 1.265.058l2 2.325zm15.146-23.272c1.86-.801 3.86-1.201 6.001-1.201 2.141 0 4.112.395 5.914 1.186 1.802.791 3.293 1.86 4.475 3.208 1.182 1.347 2.097 2.905 2.746 4.672.65 1.767.974 3.637.974 5.609 0 1.191-.121 2.04-.363 2.549-.243.507-.76.761-1.555.761h-20.807c.33 2.285 1.385 4.106 3.168 5.463 1.782 1.357 4.01 2.036 6.683 2.036 2.693 0 5.134-.84 7.324-2.52.464-.35.881-.341 1.249.03l1.947 1.992c.465.469.465.918 0 1.347-2.983 3.008-6.713 4.511-11.188 4.511-4.572 0-8.287-1.47-11.145-4.408-2.857-2.94-4.286-6.615-4.286-11.029 0-2.148.373-4.164 1.119-6.048.746-1.885 1.763-3.516 3.051-4.892 1.288-1.377 2.853-2.466 4.693-3.266zm5.71 3.774c-2.28 0-4.202.718-5.767 2.154-1.565 1.437-2.502 3.372-2.812 5.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" fill="#FFF"/><path d="M102.022 37.886V19.427c0-2.582-1.455-3.873-4.363-3.873H82.51a1.87 1.87 0 0 1-1.333-.515c-.364-.342-.584-.776-.584-1.3V1.875c0-.565.22-1.019.584-1.361A1.87 1.87 0 0 1 82.511 0h26.297c1.171 0 2.312.1 3.423.303 1.11.201 2.282.615 3.514 1.24a11.807 11.807 0 0 1 3.212 2.36c.909.949 1.646 2.23 2.211 3.844.566 1.613.849 3.47.849 5.568v23.421c.04 1.09.262 1.877.666 2.36l12.18 14.102c.645.767.605 1.594-.122 2.481l-12.058 13.799c-.444.484-.666 1.271-.666 2.36V95.14c0 2.622-.414 4.852-1.243 6.688-.828 1.835-1.938 3.207-3.332 4.115-1.394.908-2.787 1.553-4.18 1.937-1.394.383-2.879.575-4.454.575H82.51c-.525 0-.97-.162-1.333-.485a1.716 1.716 0 0 1-.584-1.331V94.715c0-.564.22-1.018.584-1.361a1.87 1.87 0 0 1 1.333-.515H97.66c2.908 0 4.363-1.25 4.363-3.752V70.749c0-1.009.242-1.755.727-2.24l13.31-13.952a.217.217 0 0 0 0-.298l-13.31-14.194c-.485-.444-.728-1.17-.728-2.179zm-32.788-8.585L93.083 53.15a1.523 1.523 0 0 1 0 2.154l-23.85 23.849a1.523 1.523 0 0 1-2.153 0l-23.85-23.85a1.523 1.523 0 0 1 0-2.153L67.08 29.3a1.523 1.523 0 0 1 2.154 0zm-35.937 8.585c0 1.009-.243 1.735-.728 2.18L19.26 54.258a.217.217 0 0 0 0 .298L32.57 68.51c.485.484.728 1.23.728 2.24v18.337c0 2.501 1.454 3.752 4.362 3.752h15.148c.525 0 .97.172 1.333.515.364.343.584.797.584 1.361v11.923c0 .565-.22 1.009-.584 1.331-.363.323-.808.485-1.333.485H26.511c-1.576 0-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 55.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 1.303-2.895 2.211-3.843a11.807 11.807 0 0 1 3.212-2.36C20.805.917 21.976.503 23.087.302A19.123 19.123 0 0 1 26.511 0h26.296c.525 0 .97.171 1.333.515.364.342.584.796.584 1.361v11.862c0 .525-.22.959-.584 1.301a1.87 1.87 0 0 1-1.333.515H37.66c-2.908 0-4.362 1.291-4.362 3.873v18.459z" fill="#4547E0"/></g></svg>
diff --git a/help3/xhpeditor/cm/doc/logos/holmusk.svg b/help3/xhpeditor/cm/doc/logos/holmusk.svg
new file mode 100644
index 0000000..80d1882
--- /dev/null
+++ b/help3/xhpeditor/cm/doc/logos/holmusk.svg
@@ -0,0 +1 @@
+<svg viewBox="0 0 60 60" version="1.1" xmlns="http://www.w3.org/2000/svg" style="background: #1649BF"><g transform="translate(-780, -40)" fill="#FFFFFF"><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>
diff --git a/help3/xhpeditor/cm/doc/logos/jetbrains.svg b/help3/xhpeditor/cm/doc/logos/jetbrains.svg
new file mode 100644
index 0000000..b379536
--- /dev/null
+++ b/help3/xhpeditor/cm/doc/logos/jetbrains.svg
@@ -0,0 +1 @@
+<svg xmlns='http://www.w3.org/2000/svg' viewBox='39 0 142.7 119'><linearGradient id='SVGID_1_' gradientUnits='userSpaceOnUse' x1='4.7875' y1='6.8451' x2='75.7999' y2='54.4038'><stop offset='0' stop-color='#AA4A9B'/><stop offset='1' stop-color='#F05922'/></linearGradient><path fill='url(#SVGID_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'/><linearGradient id='SVGID_2_' gradientUnits='userSpaceOnUse' x1='28.3538' y1='119.6551' x2='139.5938' y2='60.2551'><stop offset='0' stop-color='#FFE42E'/><stop offset='1' stop-color='#ED417C'/></linearGradient><path fill='url(#SVGID_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'/><linearGradient id='SVGID_3_' gradientUnits='userSpaceOnUse' x1='31.6974' y1='114.3816' x2='72.0174' y2='55.3416'><stop offset='0' stop-color='#FFE42E'/><stop offset='1' stop-color='#F05922'/></linearGradient><path fill='url(#SVGID_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'/><rect x='45.5' y='35.7' width='51' height='51'/><rect x='49.9' y='77.1' fill='#fff' width='19.1' height='3.2'/><path fill='#fff' 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'/><path fill='#fff' d='M56.3,42h6.7V44h-4.4v1.3h4v1.8h-4v1.3H63v2h-6.7V42z'/><path fill='#fff' d='M66,44.1h-2.5v-2h7.3v2h-2.5v6.3H66V44.1z'/><path fill='#fff' 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'/><path fill='#fff' 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'/><path fill='#fff' 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'/><path fill='#fff' d='M73.8,52.3h2.3v8.3h-2.3V52.3z'/><path fill='#fff' d='M76.7,52.3h2.2l3.4,4.4v-4.4h2.3v8.3h-2L79,56.1v4.6h-2.3V52.3z'/><path fill='#fff' 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'/></svg>
diff --git a/help3/xhpeditor/cm/doc/logos/observable.svg b/help3/xhpeditor/cm/doc/logos/observable.svg
new file mode 100644
index 0000000..49c3a82
--- /dev/null
+++ b/help3/xhpeditor/cm/doc/logos/observable.svg
@@ -0,0 +1 @@
+<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>
diff --git a/help3/xhpeditor/cm/doc/logos/primo.svg b/help3/xhpeditor/cm/doc/logos/primo.svg
new file mode 100644
index 0000000..ec2f3de
--- /dev/null
+++ b/help3/xhpeditor/cm/doc/logos/primo.svg
@@ -0,0 +1 @@
+<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(#paint0_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="#EE4645"></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="#EE4645"></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="#343434"></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="#343434"></path><defs><linearGradient id="paint0_linear" x1="14.5" y1="41.1" x2="33.6" y2="58.5" gradientUnits="userSpaceOnUse"><stop stop-color="#EE4645"></stop><stop offset="1" stop-color="#810707"></stop></linearGradient></defs></svg>
diff --git a/help3/xhpeditor/cm/doc/logos/prisma.svg b/help3/xhpeditor/cm/doc/logos/prisma.svg
new file mode 100644
index 0000000..6249376
--- /dev/null
+++ b/help3/xhpeditor/cm/doc/logos/prisma.svg
@@ -0,0 +1 @@
+<svg width="90" height="29" viewBox="0 0 90 29" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M0.2 19.5C-0.0 19.0 -0.0 18.5 0.1 18.0L10.3 1.5C10.8 0.6 12.2 0.7 12.7 1.6L21.9 21.7C22.3 22.5 21.9 23.3 21.1 23.6L6.7 27.9C6.1 28.1 5.5 27.8 5.1 27.3L0.2 19.5ZM11.4 6.3C11.5 5.9 12.2 5.8 12.4 6.2L18.8 21.0C18.9 21.3 18.8 21.6 18.5 21.7L8.5 24.7C8.2 24.8 7.8 24.5 7.9 24.1L11.4 6.3ZM48.4 21.6H51.3V11.2H48.4V21.6ZM48.3 8.5C48.3 7.6 48.8 7.2 49.9 7.2C50.9 7.2 51.4 7.6 51.4 8.5C51.4 9.0 51.3 9.3 51.0 9.6C50.8 9.8 50.4 9.9 49.9 9.9C48.8 9.9 48.3 9.5 48.3 8.5ZM87.1 16.8L86.0 16.8C85.2 16.8 84.6 17.0 84.2 17.3C83.8 17.5 83.6 18.0 83.6 18.5C83.6 19.3 84.0 19.7 85.0 19.7C85.6 19.7 86.1 19.5 86.5 19.1C86.9 18.8 87.1 18.3 87.1 17.6V16.8ZM88.0 21.6L87.4 20.2H87.3C86.9 20.8 86.4 21.2 85.9 21.4C85.4 21.7 84.7 21.8 83.9 21.8C82.9 21.8 82.1 21.5 81.5 20.9C81.0 20.4 80.7 19.5 80.7 18.5C80.7 17.4 81.1 16.6 81.8 16.1C82.6 15.5 83.8 15.2 85.3 15.2L87.1 15.1V14.7C87.1 13.6 86.6 13.1 85.5 13.1C84.7 13.1 83.7 13.4 82.6 13.9L81.7 11.9C82.8 11.3 84.2 11.0 85.6 11.0C87.0 11.0 88.1 11.3 88.8 11.9C89.6 12.5 89.9 13.4 89.9 14.7V21.6H88.0ZM72.4 21.6H69.6V15.5C69.6 14.8 69.5 14.2 69.2 13.9C69.0 13.5 68.6 13.3 68.0 13.3C67.3 13.3 66.8 13.6 66.5 14.1C66.1 14.6 66.0 15.5 66.0 16.7V21.6H63.1V11.2H65.3L65.7 12.5H65.8C66.1 12.1 66.5 11.7 67.1 11.4C67.6 11.2 68.2 11.0 68.9 11.0C70.4 11.0 71.5 11.5 72.0 12.5H72.3C72.5 12.1 73.0 11.7 73.5 11.4C74.0 11.2 74.6 11.0 75.3 11.0C76.5 11.0 77.4 11.3 78.0 11.9C78.6 12.5 78.9 13.5 78.9 14.8V21.6H76.1V15.5C76.1 14.8 75.9 14.2 75.7 13.9C75.4 13.5 75.0 13.3 74.5 13.3C73.8 13.3 73.3 13.5 72.9 14.0C72.6 14.5 72.4 15.3 72.4 16.4V21.6ZM60.1 20.9C60.9 20.4 61.2 19.6 61.2 18.5C61.2 18.0 61.1 17.6 61.0 17.2C60.8 16.8 60.5 16.5 60.1 16.2C59.7 15.9 59.2 15.6 58.3 15.3C57.4 14.9 56.8 14.6 56.6 14.5C56.3 14.3 56.2 14.1 56.2 13.8C56.2 13.3 56.6 13.1 57.4 13.1C57.9 13.1 58.4 13.2 58.8 13.3C59.3 13.5 59.7 13.7 60.3 13.9L61.1 11.8C59.9 11.3 58.7 11.0 57.5 11.0C56.2 11.0 55.2 11.3 54.4 11.8C53.7 12.3 53.4 13.0 53.4 13.9C53.4 14.5 53.5 14.9 53.6 15.3C53.8 15.6 54.1 16.0 54.4 16.3C54.8 16.5 55.4 16.9 56.2 17.2C56.8 17.4 57.2 17.6 57.5 17.8C57.9 18.0 58.1 18.1 58.2 18.3C58.4 18.4 58.4 18.6 58.4 18.8C58.4 19.4 57.9 19.7 56.9 19.7C56.4 19.7 55.8 19.6 55.2 19.5C54.5 19.3 53.9 19.1 53.4 18.8V21.2C53.8 21.4 54.3 21.5 54.9 21.6C55.4 21.7 56.1 21.8 56.8 21.8C58.3 21.8 59.4 21.5 60.1 20.9ZM46.9 11.1C46.7 11.1 46.4 11.0 46.0 11.0C45.3 11.0 44.8 11.2 44.2 11.6C43.7 11.9 43.2 12.4 42.9 13.0H42.8L42.3 11.2H40.2V21.6H43.0V16.3C43.0 15.5 43.3 14.8 43.8 14.4C44.3 13.9 45.0 13.7 45.9 13.7C46.2 13.7 46.5 13.7 46.7 13.8L46.9 11.1ZM31.9 14.4H32.8C33.7 14.4 34.4 14.2 34.8 13.9C35.3 13.5 35.5 13.0 35.5 12.4C35.5 11.7 35.3 11.2 34.9 10.9C34.6 10.5 34.0 10.4 33.2 10.4H31.9V14.4ZM38.4 12.3C38.4 13.7 37.9 14.8 37.0 15.6C36.1 16.4 34.8 16.8 33.1 16.8H31.9V21.6H29.0V8.0H33.3C35.0 8.0 36.2 8.4 37.1 9.1C37.9 9.8 38.4 10.9 38.4 12.3Z" fill="black"></path></svg>
diff --git a/help3/xhpeditor/cm/doc/manual.html b/help3/xhpeditor/cm/doc/manual.html
index 4aa4420..07d68be 100644
--- a/help3/xhpeditor/cm/doc/manual.html
+++ b/help3/xhpeditor/cm/doc/manual.html
@@ -70,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.61.1</span>
+ <span style="color: #888; font-size: 1rem; position: absolute; right: 0; bottom: 0">version 5.65.1</span>
</h2>
<p>CodeMirror is a code-editor component that can be embedded in
@@ -1320,6 +1320,8 @@ editor.setOption("extraKeys", {
and <code>end</code> line numbers are given, the range
from <code>start</code> up to (not including) <code>end</code>,
and call <code>f</code> for each line, passing the line handle.
+ <code>eachLine</code> stops iterating if <code>f</code> returns
+ truthy value.
This is a faster way to visit a range of line handlers than
calling <a href="#getLineHandle"><code>getLineHandle</code></a>
for each of them. Note that line handles have
@@ -1826,7 +1828,7 @@ editor.setOption("extraKeys", {
<dt id="addLineClass"><code><strong>doc.addLineClass</strong>(line: integer|LineHandle, where: string, class: string) → LineHandle</code></dt>
<dd>Set a CSS class name for the given line. <code>line</code>
can be a number or a line handle. <code>where</code> determines
- to which element this class should be applied, can can be one
+ to which element this class should be applied, can be one
of <code>"text"</code> (the text element, which lies in front of
the selection), <code>"background"</code> (a background element
that will be behind the selection), <code>"gutter"</code> (the
@@ -2950,6 +2952,7 @@ editor.setOption("extraKeys", {
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.
+ And a <code>highlightLines</code> option to add a style to lines that contain problems.
Depends on <code>addon/lint/lint.css</code>. A demo can be
found <a href="../demo/lint.html">here</a>.</dd>
diff --git a/help3/xhpeditor/cm/doc/releases.html b/help3/xhpeditor/cm/doc/releases.html
index 7ae3f3a..2a013b3 100644
--- a/help3/xhpeditor/cm/doc/releases.html
+++ b/help3/xhpeditor/cm/doc/releases.html
@@ -30,6 +30,79 @@
<h2>Version 5.x</h2>
+ <p class="rel">20-01-2022: <a href="https://codemirror.net/codemirror-5.65.1.zip">Version 5.65.1</a>:</p>
+
+ <ul class="rel-note">
+ <li>Fix miscalculation of vertical positions in lines that have both line widgets and replaced newlines.</li>
+ </ul>
+
+ <p class="rel">20-12-2021: <a href="https://codemirror.net/codemirror-5.65.0.zip">Version 5.65.0</a>:</p>
+
+ <ul class="rel-note">
+ <li>brace-folding addon: Fix broken folding on lines with both braces and square brackets.</li>
+ <li><a href="https://codemirror.net/demo/vim.html">vim bindings</a>: Support g0, g$, g&lt;Arrow&gt;.</li>
+ </ul>
+
+ <p class="rel">20-11-2021: <a href="https://codemirror.net/codemirror-5.64.0.zip">Version 5.64.0</a>:</p>
+
+ <ul class="rel-note">
+ <li>Fix a crash that occurred in some situations with replacing marks across line breaks.</li>
+ <li>Make sure native scrollbars reset their position when hidden and re-shown.</li>
+ <li><a href="https://codemirror.net/demo/vim.html">vim bindings</a>: Support C-u to delete back a line.</li>
+ </ul>
+
+ <p class="rel">11-10-2021: <a href="https://codemirror.net/codemirror-5.63.3.zip">Version 5.63.3</a>:</p>
+
+ <ul class="rel-note">
+ <li>Prevent external styles from giving the hidden textarea a min-height.</li>
+ <li>Remove a stray autosave file that was part of the previous release.</li>
+ </ul>
+
+ <p class="rel">29-09-2021: <a href="https://codemirror.net/codemirror-5.63.1.zip">Version 5.63.1</a>:</p>
+
+ <ul class="rel-note">
+ <li>Fix an issue with mouse scrolling on Chrome 94 Windows, which made scrolling by wheel move unusably slow.</li>
+ </ul>
+
+ <p class="rel">20-09-2021: <a href="https://codemirror.net/codemirror-5.63.0.zip">Version 5.63.0</a>:</p>
+
+ <ul class="rel-note">
+ <li>Fix scroll position jumping when scrolling a document with very different line heights.</li>
+ <li><a href="https://codemirror.net/mode/xml/">xml mode</a>: Look up HTML element behavior in a case-insensitive way.</li>
+ <li><a href="https://codemirror.net/demo/vim.html">vim bindings</a>: Support guu for case-changing.</li>
+ </ul>
+
+ <p class="rel">20-08-2021: <a href="https://codemirror.net/codemirror-5.62.3.zip">Version 5.62.3</a>:</p>
+
+ <ul class="rel-note">
+ <li>Give the editor a <code>translate=no</code> attribute to prevent automatic translation from modifying its content.</li>
+ <li>Give vim-style cursors a width that matches the character after them.</li>
+ <li><a href="https://codemirror.net/doc/manual.html#addon_merge">merge addon</a>: Make buttons keyboard-accessible.</li>
+ <li><a href="https://codemirror.net/demo/emacs.html">emacs bindings</a>: Fix by-page scrolling keybindings, which were accidentally inverted.</li>
+ </ul>
+
+ <p class="rel">21-07-2021: <a href="https://codemirror.net/codemirror-5.62.2.zip">Version 5.62.2</a>:</p>
+
+ <ul class="rel-note">
+ <li><a href="https://codemirror.net/doc/manual.html#addon_lint">lint addon</a>: Fix a regression that broke several addon options.</li>
+ </ul>
+
+ <p class="rel">20-07-2021: <a href="https://codemirror.net/codemirror-5.62.1.zip">Version 5.62.1</a>:</p>
+
+ <ul class="rel-note">
+ <li><a href="https://codemirror.net/demo/vim.html">vim bindings</a>: Make matching of upper-case characters more Unicode-aware.</li>
+ <li><a href="https://codemirror.net/doc/manual.html#addon_lint">lint addon</a>: Prevent options passed to the addon itself from being given to the linter.</li>
+ <li><a href="https://codemirror.net/doc/manual.html#addon_show-hint">show-hint addon</a>: Improve screen reader support.</li>
+ <li><a href="https://codemirror.net/demo/search.html">search addon</a>: Avoid using <code>innerHTML</code>.</li>
+ </ul>
+
+ <p class="rel">21-06-2021: <a href="https://codemirror.net/codemirror-5.62.0.zip">Version 5.62.0</a>:</p>
+
+ <ul class="rel-note">
+ <a href="https://codemirror.net/doc/manual.html#addon_lint">lint addon</a>: Add support for highlighting lines with errors or warnings.</li>
+ <li>Improve support for vim-style cursors in a number of themes.</li>
+ </ul>
+
<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">
diff --git a/help3/xhpeditor/cm/index.html b/help3/xhpeditor/cm/index.html
index 1bf64b1..e3d2ba6 100644
--- a/help3/xhpeditor/cm/index.html
+++ b/help3/xhpeditor/cm/index.html
@@ -102,7 +102,7 @@
</div>
</div>
<div class=actionsleft>
- Get the current version: <a href="https://codemirror.net/codemirror.zip">5.61.1</a>.<br>
+ Get the current version: <a href="https://codemirror.net/codemirror.zip">5.65.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>.
@@ -205,15 +205,18 @@
<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>
+ <li><a href="http://observablehq.com/"><img alt="Observable" src='doc/logos/observable.svg' loading=lazy></a></li>
+ <li><a href="https://holmusk.com"><img class=captioned alt="" src='doc/logos/holmusk.svg' loading=lazy>Holmusk</a></li>
+ <li><a href="https://codepen.io/"><img style="margin: 16px 0" src='doc/logos/codepen.svg' loading=lazy alt="CodePen"></a></li>
+ <li><a href="https://4me.com"><img style="width: auto" src='doc/logos/4me.svg' loading=lazy alt="4me"></a></li>
+ <li><a href="https://www.jetbrains.com/"><img src="doc/logos/jetbrains.svg" loading=lazy alt="JetBrains"></a>
+ <li><a href="https://www.desmos.com/"><img src='doc/logos/desmos.svg' loading=lazy alt=desmos></a></li>
+ <li><a href="https://www.executeprogram.com"><img style="background: #003; margin: 10px 0; padding: 10px 30px 10px 20px" src='doc/logos/executeprogram.svg' loading=lazy alt="Execute Program"></a></li>
+ <li><a href="https://cargo.site"><img alt=Cargo style="max-height: 120px" src='doc/logos/cargo.svg' loading=lazy></a></li>
+ <li><a href="https://primo.af"><img alt=primo src='doc/logos/primo.svg' loading=lazy></a></li>
+ <li><a href="https://www.artcompiler.com"><img class=captioned alt="" src='doc/logos/artcompiler.svg' loading=lazy> ARTCOMPILER</a></li>
+ <li><a href="https://www.prisma.io"><img alt="Prisma" src='doc/logos/prisma.svg' loading=lazy></a>
+ <li><a href="https://anvil.works/"><img alt="Anvil" src='doc/logos/anvil.png' loading=lazy></a>
</ul>
</section>
diff --git a/help3/xhpeditor/cm/keymap/emacs.js b/help3/xhpeditor/cm/keymap/emacs.js
index 84744e4..9e7ae60 100644
--- a/help3/xhpeditor/cm/keymap/emacs.js
+++ b/help3/xhpeditor/cm/keymap/emacs.js
@@ -330,9 +330,9 @@
cmds.previousLine = move(byLine, -1);
- cmds.scrollDownCommand = move(byPage, 1);
+ cmds.scrollDownCommand = move(byPage, -1);
- cmds.scrollUpCommand = move(byPage, -1);
+ cmds.scrollUpCommand = move(byPage, 1);
cmds.backwardParagraph = move(byParagraph, -1);
@@ -480,8 +480,8 @@
"Home": "goLineStart",
"Alt-V": "scrollDownCommand",
"Ctrl-V": "scrollUpCommand",
- "PageUp": "scrollUpCommand",
- "PageDown": "scrollDownCommand",
+ "PageUp": "scrollDownCommand",
+ "PageDown": "scrollUpCommand",
"Ctrl-Up": "backwardParagraph",
"Ctrl-Down": "forwardParagraph",
"Alt-{": "backwardParagraph",
diff --git a/help3/xhpeditor/cm/keymap/vim.js b/help3/xhpeditor/cm/keymap/vim.js
index 6630b6f..1cf9636 100644
--- a/help3/xhpeditor/cm/keymap/vim.js
+++ b/help3/xhpeditor/cm/keymap/vim.js
@@ -44,6 +44,27 @@
})(function(CodeMirror) {
'use strict';
+ var Pos = CodeMirror.Pos;
+
+ function transformCursor(cm, range) {
+ var vim = cm.state.vim;
+ if (!vim || vim.insertMode) return range.head;
+ var head = vim.sel.head;
+ if (!head) return range.head;
+
+ if (vim.visualBlock) {
+ if (range.head.line != head.line) {
+ return;
+ }
+ }
+ if (range.from() == range.anchor && !range.empty()) {
+ if (range.head.line == head.line && range.head.ch != head.ch)
+ return new Pos(range.head.line, range.head.ch - 1);
+ }
+
+ return range.head;
+ }
+
var defaultKeymap = [
// Key to key mapping. This goes first to make it possible to override
// existing mappings.
@@ -51,6 +72,8 @@
{ keys: '<Right>', type: 'keyToKey', toKeys: 'l' },
{ keys: '<Up>', type: 'keyToKey', toKeys: 'k' },
{ keys: '<Down>', type: 'keyToKey', toKeys: 'j' },
+ { keys: 'g<Up>', type: 'keyToKey', toKeys: 'gk' },
+ { keys: 'g<Down>', type: 'keyToKey', toKeys: 'gj' },
{ keys: '<Space>', type: 'keyToKey', toKeys: 'l' },
{ keys: '<BS>', type: 'keyToKey', toKeys: 'h', context: 'normal'},
{ keys: '<Del>', type: 'keyToKey', toKeys: 'x', context: 'normal'},
@@ -73,6 +96,7 @@
{ keys: '<PageUp>', type: 'keyToKey', toKeys: '<C-b>' },
{ keys: '<PageDown>', type: 'keyToKey', toKeys: '<C-f>' },
{ keys: '<CR>', type: 'keyToKey', toKeys: 'j^', context: 'normal' },
+ { keys: '<Ins>', type: 'keyToKey', toKeys: 'i', context: 'normal'},
{ keys: '<Ins>', type: 'action', action: 'toggleOverwrite', context: 'insert' },
// Motions
{ keys: 'H', type: 'motion', motion: 'moveToTopLine', motionArgs: { linewise: true, toJumplist: true }},
@@ -102,6 +126,9 @@
{ keys: '<C-u>', type: 'motion', motion: 'moveByScroll', motionArgs: { forward: false, explicitRepeat: true }},
{ keys: 'gg', type: 'motion', motion: 'moveToLineOrEdgeOfDocument', motionArgs: { forward: false, explicitRepeat: true, linewise: true, toJumplist: true }},
{ keys: 'G', type: 'motion', motion: 'moveToLineOrEdgeOfDocument', motionArgs: { forward: true, explicitRepeat: true, linewise: true, toJumplist: true }},
+ {keys: "g$", type: "motion", motion: "moveToEndOfDisplayLine"},
+ {keys: "g^", type: "motion", motion: "moveToStartOfDisplayLine"},
+ {keys: "g0", type: "motion", motion: "moveToStartOfDisplayLine"},
{ keys: '0', type: 'motion', motion: 'moveToStartOfLine' },
{ keys: '^', type: 'motion', motion: 'moveToFirstNonWhiteSpaceCharacter' },
{ keys: '+', type: 'motion', motion: 'moveByLines', motionArgs: { forward: true, toFirstChar:true }},
@@ -154,6 +181,7 @@
{ keys: 'C', type: 'operator', operator: 'change', operatorArgs: { linewise: true }, context: 'visual'},
{ keys: '~', type: 'operatorMotion', operator: 'changeCase', motion: 'moveByCharacters', motionArgs: { forward: true }, operatorArgs: { shouldMoveCursor: true }, context: 'normal'},
{ keys: '~', type: 'operator', operator: 'changeCase', context: 'visual'},
+ { keys: '<C-u>', type: 'operatorMotion', operator: 'delete', motion: 'moveToStartOfLine', context: 'insert' },
{ keys: '<C-w>', type: 'operatorMotion', operator: 'delete', motion: 'moveByWords', motionArgs: { forward: false, wordEnd: false }, context: 'insert' },
//ignore C-w in normal mode
{ keys: '<C-w>', type: 'idle', context: 'normal' },
@@ -248,8 +276,6 @@
{ name: 'global', shortName: 'g' }
];
- var Pos = CodeMirror.Pos;
-
var Vim = function() {
function enterVimMode(cm) {
cm.setOption('disableInput', true);
@@ -265,15 +291,13 @@
cm.off('cursorActivity', onCursorActivity);
CodeMirror.off(cm.getInputField(), 'paste', getOnPasteFn(cm));
cm.state.vim = null;
+ if (highlightTimeout) clearTimeout(highlightTimeout);
}
function detachVimMap(cm, next) {
if (this == CodeMirror.keyMap.vim) {
+ cm.options.$customCursor = null;
CodeMirror.rmClass(cm.getWrapperElement(), "cm-fat-cursor");
- if (cm.getOption("inputStyle") == "contenteditable" && document.body.style.caretColor != null) {
- disableFatCursorMark(cm);
- cm.getInputField().style.caretColor = "";
- }
}
if (!next || next.attach != attachVimMap)
@@ -281,57 +305,15 @@
}
function attachVimMap(cm, prev) {
if (this == CodeMirror.keyMap.vim) {
+ if (cm.curOp) cm.curOp.selectionChanged = true;
+ cm.options.$customCursor = transformCursor;
CodeMirror.addClass(cm.getWrapperElement(), "cm-fat-cursor");
- if (cm.getOption("inputStyle") == "contenteditable" && document.body.style.caretColor != null) {
- enableFatCursorMark(cm);
- cm.getInputField().style.caretColor = "transparent";
- }
}
if (!prev || prev.attach != attachVimMap)
enterVimMode(cm);
}
- function updateFatCursorMark(cm) {
- if (!cm.state.fatCursorMarks) return;
- clearFatCursorMark(cm);
- var ranges = cm.listSelections(), result = []
- for (var i = 0; i < ranges.length; i++) {
- var range = ranges[i];
- if (range.empty()) {
- 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"}));
- } else {
- result.push(cm.markText(Pos(range.anchor.line, lineLength - 1),
- Pos(range.anchor.line, lineLength),
- {className: "cm-fat-cursor-mark"}));
- }
- }
- }
- cm.state.fatCursorMarks = result;
- }
-
- function clearFatCursorMark(cm) {
- var marks = cm.state.fatCursorMarks;
- if (marks) for (var i = 0; i < marks.length; i++) marks[i].clear();
- }
-
- function enableFatCursorMark(cm) {
- cm.state.fatCursorMarks = [];
- updateFatCursorMark(cm)
- cm.on("cursorActivity", updateFatCursorMark)
- }
-
- function disableFatCursorMark(cm) {
- clearFatCursorMark(cm);
- cm.off("cursorActivity", updateFatCursorMark);
- // explicitly set fatCursorMarks to null because event listener above
- // can be invoke after removing it, if off is called from operation
- cm.state.fatCursorMarks = null;
- }
-
// Deprecated, simply setting the keymap works again.
CodeMirror.defineOption('vimMode', false, function(cm, val, prev) {
if (val && cm.getOption("keyMap") != "vim")
@@ -347,7 +329,7 @@
if (!vimKey) {
return false;
}
- var cmd = CodeMirror.Vim.findKey(cm, vimKey);
+ var cmd = vimApi.findKey(cm, vimKey);
if (typeof cmd == 'function') {
CodeMirror.signal(cm, 'vim-keypress', vimKey);
}
@@ -420,6 +402,9 @@
var numbers = makeKeyRange(48, 10);
var validMarks = [].concat(upperCaseAlphabet, lowerCaseAlphabet, numbers, ['<', '>']);
var validRegisters = [].concat(upperCaseAlphabet, lowerCaseAlphabet, numbers, ['-', '"', '.', ':', '_', '/']);
+ var upperCaseChars;
+ try { upperCaseChars = new RegExp("^[\\p{Lu}]$", "u"); }
+ catch (_) { upperCaseChars = /^[A-Z]$/; }
function isLine(cm, line) {
return line >= cm.firstLine() && line <= cm.lastLine();
@@ -434,7 +419,7 @@
return numberRegex.test(k);
}
function isUpperCase(k) {
- return (/^[A-Z]$/).test(k);
+ return upperCaseChars.test(k);
}
function isWhiteSpaceString(k) {
return (/^\s*$/).test(k);
@@ -658,7 +643,7 @@
this.latestRegister = registerName;
if (cm.openDialog) {
this.onRecordingDone = cm.openDialog(
- '(recording)['+registerName+']', null, {bottom:true});
+ document.createTextNode('(recording)['+registerName+']'), null, {bottom:true});
}
this.isRecording = true;
}
@@ -688,8 +673,6 @@
// executed in between.
lastMotion: null,
marks: {},
- // Mark for rendering fake cursor for visual mode.
- fakeCursor: null,
insertMode: false,
// Repeat count for changes made in insert mode, triggered by key
// sequences like 3,i. Only exists when insertMode is true.
@@ -761,7 +744,7 @@
exCommandDispatcher.map(lhs, rhs, ctx);
},
unmap: function(lhs, ctx) {
- exCommandDispatcher.unmap(lhs, ctx);
+ return exCommandDispatcher.unmap(lhs, ctx);
},
// Non-recursive map function.
// NOTE: This will not create mappings to key maps that aren't present
@@ -901,7 +884,7 @@
match = (/<\w+-.+?>|<\w+>|./).exec(keys);
key = match[0];
keys = keys.substring(match.index + key.length);
- CodeMirror.Vim.handleKey(cm, key, 'mapping');
+ vimApi.handleKey(cm, key, 'mapping');
}
}
@@ -948,7 +931,12 @@
if (!keysMatcher) { clearInputState(cm); return false; }
var context = vim.visualMode ? 'visual' :
'normal';
- var match = commandDispatcher.matchCommand(keysMatcher[2] || keysMatcher[1], defaultKeymap, vim.inputState, context);
+ var mainKey = keysMatcher[2] || keysMatcher[1];
+ if (vim.inputState.operatorShortcut && vim.inputState.operatorShortcut.slice(-1) == mainKey) {
+ // multikey operators act linewise by repeating only the last character
+ mainKey = vim.inputState.operatorShortcut;
+ }
+ var match = commandDispatcher.matchCommand(mainKey, defaultKeymap, vim.inputState, context);
if (match.type == 'none') { clearInputState(cm); return false; }
else if (match.type == 'partial') { return true; }
@@ -984,7 +972,7 @@
// clear VIM state in case it's in a bad state.
cm.state.vim = undefined;
maybeInitVimState(cm);
- if (!CodeMirror.Vim.suppressErrorLogging) {
+ if (!vimApi.suppressErrorLogging) {
console['log'](e);
}
throw e;
@@ -1308,6 +1296,9 @@
}
inputState.operator = command.operator;
inputState.operatorArgs = copyArgs(command.operatorArgs);
+ if (command.keys.length > 1) {
+ inputState.operatorShortcut = command.keys;
+ }
if (command.exitVisualBlock) {
vim.visualBlock = false;
updateCmSelection(cm);
@@ -1636,17 +1627,17 @@
var chOffset = Math.abs(lastSel.head.ch - lastSel.anchor.ch);
if (lastSel.visualLine) {
// Linewise Visual mode: The same number of lines.
- newHead = Pos(oldAnchor.line + lineOffset, oldAnchor.ch);
+ newHead = new Pos(oldAnchor.line + lineOffset, oldAnchor.ch);
} else if (lastSel.visualBlock) {
// Blockwise Visual mode: The same number of lines and columns.
- newHead = Pos(oldAnchor.line + lineOffset, oldAnchor.ch + chOffset);
+ newHead = new Pos(oldAnchor.line + lineOffset, oldAnchor.ch + chOffset);
} else if (lastSel.head.line == lastSel.anchor.line) {
// Normal Visual mode within one line: The same number of characters.
- newHead = Pos(oldAnchor.line, oldAnchor.ch + chOffset);
+ newHead = new Pos(oldAnchor.line, oldAnchor.ch + chOffset);
} else {
// Normal Visual mode with several lines: The same number of lines, in the
// last line the same number of characters as in the last line the last time.
- newHead = Pos(oldAnchor.line + lineOffset, oldAnchor.ch);
+ newHead = new Pos(oldAnchor.line + lineOffset, oldAnchor.ch);
}
vim.visualMode = true;
vim.visualLine = lastSel.visualLine;
@@ -1686,7 +1677,7 @@
ranges[i].head.ch = lineLength(cm, ranges[i].head.line);
}
} else if (mode == 'line') {
- ranges[0].head = Pos(ranges[0].head.line + 1, 0);
+ ranges[0].head = new Pos(ranges[0].head.line + 1, 0);
}
}
} else {
@@ -1748,22 +1739,22 @@
var motions = {
moveToTopLine: function(cm, _head, motionArgs) {
var line = getUserVisibleLines(cm).top + motionArgs.repeat -1;
- return Pos(line, findFirstNonWhiteSpaceCharacter(cm.getLine(line)));
+ return new Pos(line, findFirstNonWhiteSpaceCharacter(cm.getLine(line)));
},
moveToMiddleLine: function(cm) {
var range = getUserVisibleLines(cm);
var line = Math.floor((range.top + range.bottom) * 0.5);
- return Pos(line, findFirstNonWhiteSpaceCharacter(cm.getLine(line)));
+ return new Pos(line, findFirstNonWhiteSpaceCharacter(cm.getLine(line)));
},
moveToBottomLine: function(cm, _head, motionArgs) {
var line = getUserVisibleLines(cm).bottom - motionArgs.repeat +1;
- return Pos(line, findFirstNonWhiteSpaceCharacter(cm.getLine(line)));
+ return new Pos(line, findFirstNonWhiteSpaceCharacter(cm.getLine(line)));
},
expandToLine: function(_cm, head, motionArgs) {
// Expands forward to end of line, and then to next line if repeat is
// >1. Does not handle backward motion!
var cur = head;
- return Pos(cur.line + motionArgs.repeat - 1, Infinity);
+ return new Pos(cur.line + motionArgs.repeat - 1, Infinity);
},
findNext: function(cm, _head, motionArgs) {
var state = getSearchState(cm);
@@ -1820,7 +1811,7 @@
// 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);
+ var to = new Pos(next[1].line, next[1].ch - 1);
if (vim.visualMode) {
// If we were in visualLine or visualBlock mode, get out of it.
@@ -1869,8 +1860,8 @@
if (vim.visualBlock && motionArgs.sameLine) {
var sel = vim.sel;
return [
- clipCursorToContent(cm, Pos(sel.anchor.line, sel.head.ch)),
- clipCursorToContent(cm, Pos(sel.head.line, sel.anchor.ch))
+ clipCursorToContent(cm, new Pos(sel.anchor.line, sel.head.ch)),
+ clipCursorToContent(cm, new Pos(sel.head.line, sel.anchor.ch))
];
} else {
return ([vim.sel.head, vim.sel.anchor]);
@@ -1910,7 +1901,7 @@
// Vim places the cursor on the first non-whitespace character of
// the line if there is one, else it places the cursor at the end
// of the line, regardless of whether a mark was found.
- best = Pos(best.line, findFirstNonWhiteSpaceCharacter(cm.getLine(best.line)));
+ best = new Pos(best.line, findFirstNonWhiteSpaceCharacter(cm.getLine(best.line)));
}
return best;
},
@@ -1918,7 +1909,7 @@
var cur = head;
var repeat = motionArgs.repeat;
var ch = motionArgs.forward ? cur.ch + repeat : cur.ch - repeat;
- return Pos(cur.line, ch);
+ return new Pos(cur.line, ch);
},
moveByLines: function(cm, head, motionArgs, vim) {
var cur = head;
@@ -1960,8 +1951,8 @@
endCh=findFirstNonWhiteSpaceCharacter(cm.getLine(line));
vim.lastHPos = endCh;
}
- vim.lastHSPos = cm.charCoords(Pos(line, endCh),'div').left;
- return Pos(line, endCh);
+ vim.lastHSPos = cm.charCoords(new Pos(line, endCh),'div').left;
+ return new Pos(line, endCh);
},
moveByDisplayLines: function(cm, head, motionArgs, vim) {
var cur = head;
@@ -1983,7 +1974,7 @@
var goalCoords = { top: lastCharCoords.top + 8, left: vim.lastHSPos };
var res = cm.coordsChar(goalCoords, 'div');
} else {
- var resCoords = cm.charCoords(Pos(cm.firstLine(), 0), 'div');
+ var resCoords = cm.charCoords(new Pos(cm.firstLine(), 0), 'div');
resCoords.left = vim.lastHSPos;
res = cm.coordsChar(resCoords, 'div');
}
@@ -2063,7 +2054,7 @@
// Go to the start of the line where the text begins, or the end for
// whitespace-only lines
var cursor = head;
- return Pos(cursor.line,
+ return new Pos(cursor.line,
findFirstNonWhiteSpaceCharacter(cm.getLine(cursor.line)));
},
moveToMatchedSymbol: function(cm, head) {
@@ -2075,7 +2066,7 @@
for (; ch < lineText.length; ch++) {
symbol = lineText.charAt(ch);
if (symbol && isMatchableSymbol(symbol)) {
- var style = cm.getTokenTypeAt(Pos(line, ch + 1));
+ var style = cm.getTokenTypeAt(new Pos(line, ch + 1));
if (style !== "string" && style !== "comment") {
break;
}
@@ -2084,23 +2075,33 @@
if (ch < lineText.length) {
// Only include angle brackets in analysis if they are being matched.
var re = (ch === '<' || ch === '>') ? /[(){}[\]<>]/ : /[(){}[\]]/;
- var matched = cm.findMatchingBracket(Pos(line, ch), {bracketRegex: re});
+ var matched = cm.findMatchingBracket(new Pos(line, ch), {bracketRegex: re});
return matched.to;
} else {
return cursor;
}
},
moveToStartOfLine: function(_cm, head) {
- return Pos(head.line, 0);
+ return new Pos(head.line, 0);
},
moveToLineOrEdgeOfDocument: function(cm, _head, motionArgs) {
var lineNum = motionArgs.forward ? cm.lastLine() : cm.firstLine();
if (motionArgs.repeatIsExplicit) {
lineNum = motionArgs.repeat - cm.getOption('firstLineNumber');
}
- return Pos(lineNum,
+ return new Pos(lineNum,
findFirstNonWhiteSpaceCharacter(cm.getLine(lineNum)));
},
+ moveToStartOfDisplayLine: function(cm) {
+ cm.execCommand("goLineLeft");
+ return cm.getCursor();
+ },
+ moveToEndOfDisplayLine: function(cm) {
+ cm.execCommand("goLineRight");
+ var head = cm.getCursor();
+ if (head.sticky == "before") head.ch--;
+ return head;
+ },
textObjectManipulation: function(cm, head, motionArgs, vim) {
// TODO: lots of possible exceptions that can be thrown here. Try da(
// outside of a () block.
@@ -2261,7 +2262,7 @@
if (anchor.line == cm.firstLine()) {
anchor.ch = 0;
} else {
- anchor = Pos(anchor.line - 1, lineLength(cm, anchor.line - 1));
+ anchor = new Pos(anchor.line - 1, lineLength(cm, anchor.line - 1));
}
}
text = cm.getRange(anchor, head);
@@ -2274,7 +2275,7 @@
text = cm.getSelection();
var replacement = fillArray('', ranges.length);
cm.replaceSelections(replacement);
- finalHead = ranges[0].anchor;
+ finalHead = cursorMin(ranges[0].head, ranges[0].anchor);
}
vimGlobalState.registerController.pushText(
args.registerName, 'delete', text,
@@ -2408,7 +2409,7 @@
},
scrollToCursor: function(cm, actionArgs) {
var lineNum = cm.getCursor().line;
- var charCoords = cm.charCoords(Pos(lineNum, 0), 'local');
+ var charCoords = cm.charCoords(new Pos(lineNum, 0), 'local');
var height = cm.getScrollInfo().clientHeight;
var y = charCoords.top;
var lineHeight = charCoords.bottom - y;
@@ -2460,9 +2461,9 @@
var head = actionArgs.head || cm.getCursor('head');
var height = cm.listSelections().length;
if (insertAt == 'eol') {
- head = Pos(head.line, lineLength(cm, head.line));
+ head = new Pos(head.line, lineLength(cm, head.line));
} else if (insertAt == 'bol') {
- head = Pos(head.line, 0);
+ head = new Pos(head.line, 0);
} else if (insertAt == 'charAfter') {
head = offsetCursor(head, 0, 1);
} else if (insertAt == 'firstNonBlank') {
@@ -2474,10 +2475,10 @@
if (sel.head.line < sel.anchor.line) {
head = sel.head;
} else {
- head = Pos(sel.anchor.line, 0);
+ head = new Pos(sel.anchor.line, 0);
}
} else {
- head = Pos(
+ head = new Pos(
Math.min(sel.head.line, sel.anchor.line),
Math.min(sel.head.ch, sel.anchor.ch));
height = Math.abs(sel.head.line - sel.anchor.line) + 1;
@@ -2489,12 +2490,12 @@
if (sel.head.line >= sel.anchor.line) {
head = offsetCursor(sel.head, 0, 1);
} else {
- head = Pos(sel.anchor.line, 0);
+ head = new Pos(sel.anchor.line, 0);
}
} else {
- head = Pos(
+ head = new Pos(
Math.min(sel.head.line, sel.anchor.line),
- Math.max(sel.head.ch + 1, sel.anchor.ch));
+ Math.max(sel.head.ch, sel.anchor.ch) + 1);
height = Math.abs(sel.head.line - sel.anchor.line) + 1;
}
} else if (insertAt == 'inplace') {
@@ -2538,7 +2539,7 @@
vim.visualLine = !!actionArgs.linewise;
vim.visualBlock = !!actionArgs.blockwise;
head = clipCursorToContent(
- cm, Pos(anchor.line, anchor.ch + repeat - 1));
+ cm, new Pos(anchor.line, anchor.ch + repeat - 1));
vim.sel = {
anchor: anchor,
head: head
@@ -2601,13 +2602,13 @@
// Repeat is the number of lines to join. Minimum 2 lines.
var repeat = Math.max(actionArgs.repeat, 2);
curStart = cm.getCursor();
- curEnd = clipCursorToContent(cm, Pos(curStart.line + repeat - 1,
+ curEnd = clipCursorToContent(cm, new Pos(curStart.line + repeat - 1,
Infinity));
}
var finalCh = 0;
for (var i = curStart.line; i < curEnd.line; i++) {
finalCh = lineLength(cm, curStart.line);
- var tmp = Pos(curStart.line + 1,
+ var tmp = new Pos(curStart.line + 1,
lineLength(cm, curStart.line + 1));
var text = cm.getRange(curStart, tmp);
text = actionArgs.keepSpaces
@@ -2615,7 +2616,7 @@
: text.replace(/\n\s*/g, ' ');
cm.replaceRange(text, curStart, tmp);
}
- var curFinalPos = Pos(curStart.line, finalCh);
+ var curFinalPos = new Pos(curStart.line, finalCh);
if (vim.visualMode) {
exitVisualMode(cm, false);
}
@@ -2626,7 +2627,7 @@
var insertAt = copyCursor(cm.getCursor());
if (insertAt.line === cm.firstLine() && !actionArgs.after) {
// Special case for inserting newline before start of document.
- cm.replaceRange('\n', Pos(cm.firstLine(), 0));
+ cm.replaceRange('\n', new Pos(cm.firstLine(), 0));
cm.setCursor(cm.firstLine(), 0);
} else {
insertAt.line = (actionArgs.after) ? insertAt.line :
@@ -2727,7 +2728,7 @@
// first delete the selected text
cm.replaceSelections(emptyStrings);
// Set new selections as per the block length of the yanked text
- selectionEnd = Pos(selectionStart.line + text.length-1, selectionStart.ch);
+ selectionEnd = new Pos(selectionStart.line + text.length-1, selectionStart.ch);
cm.setCursor(selectionStart);
selectBlock(cm, selectionEnd);
cm.replaceSelections(text);
@@ -2754,7 +2755,7 @@
for (var i = 0; i < text.length; i++) {
var line = cur.line+i;
if (line > cm.lastLine()) {
- cm.replaceRange('\n', Pos(line, 0));
+ cm.replaceRange('\n', new Pos(line, 0));
}
var lastCh = lineLength(cm, line);
if (lastCh < cur.ch) {
@@ -2762,18 +2763,18 @@
}
}
cm.setCursor(cur);
- selectBlock(cm, Pos(cur.line + text.length-1, cur.ch));
+ selectBlock(cm, new Pos(cur.line + text.length-1, cur.ch));
cm.replaceSelections(text);
curPosFinal = cur;
} else {
cm.replaceRange(text, cur);
// Now fine tune the cursor to where we want it.
if (linewise && actionArgs.after) {
- curPosFinal = Pos(
+ curPosFinal = new Pos(
cur.line + 1,
findFirstNonWhiteSpaceCharacter(cm.getLine(cur.line + 1)));
} else if (linewise && !actionArgs.after) {
- curPosFinal = Pos(
+ curPosFinal = new Pos(
cur.line,
findFirstNonWhiteSpaceCharacter(cm.getLine(cur.line)));
} else if (!linewise && actionArgs.after) {
@@ -2821,7 +2822,7 @@
if (replaceTo > line.length) {
replaceTo=line.length;
}
- curEnd = Pos(curStart.line, replaceTo);
+ curEnd = new Pos(curStart.line, replaceTo);
}
if (replaceWith=='\n') {
if (!vim.visualMode) cm.replaceRange('', curStart, curEnd);
@@ -2877,13 +2878,13 @@
} else {
numberStr = baseStr + zeroPadding + numberStr;
}
- var from = Pos(cur.line, start);
- var to = Pos(cur.line, end);
+ var from = new Pos(cur.line, start);
+ var to = new Pos(cur.line, end);
cm.replaceRange(numberStr, from, to);
} else {
return;
}
- cm.setCursor(Pos(cur.line, start + numberStr.length - 1));
+ cm.setCursor(new Pos(cur.line, start + numberStr.length - 1));
},
repeatLastEdit: function(cm, actionArgs, vim) {
var lastEditInputState = vim.lastEditInputState;
@@ -2920,7 +2921,7 @@
var line = Math.min(Math.max(cm.firstLine(), cur.line), cm.lastLine() );
var maxCh = lineLength(cm, line) - 1 + !!includeLineBreak;
var ch = Math.min(Math.max(0, cur.ch), maxCh);
- return Pos(line, ch);
+ return new Pos(line, ch);
}
function copyArgs(args) {
var ret = {};
@@ -2936,7 +2937,7 @@
offsetCh = offsetLine.ch;
offsetLine = offsetLine.line;
}
- return Pos(cur.line + offsetLine, cur.ch + offsetCh);
+ return new Pos(cur.line + offsetLine, cur.ch + offsetCh);
}
function commandMatches(keys, keyMap, context, inputState) {
// Partial matches are not applied. They inform the key handler
@@ -2996,7 +2997,7 @@
};
}
function copyCursor(cur) {
- return Pos(cur.line, cur.ch);
+ return new Pos(cur.line, cur.ch);
}
function cursorEqual(cur1, cur2) {
return cur1.ch == cur2.ch && cur1.line == cur2.line;
@@ -3043,7 +3044,7 @@
function extendLineToColumn(cm, lineNum, column) {
var endCh = lineLength(cm, lineNum);
var spaces = new Array(column-endCh+1).join(' ');
- cm.setCursor(Pos(lineNum, endCh));
+ cm.setCursor(new Pos(lineNum, endCh));
cm.replaceRange(spaces, cm.getCursor());
}
// This functions selects a rectangular block
@@ -3124,13 +3125,13 @@
if (block) {
var width = block.width;
var height = block.height;
- selectionEnd = Pos(selectionStart.line + height, selectionStart.ch + width);
+ selectionEnd = new Pos(selectionStart.line + height, selectionStart.ch + width);
var selections = [];
// selectBlock creates a 'proper' rectangular block.
// We do not want that in all cases, so we manually set selections.
for (var i = selectionStart.line; i < selectionEnd.line; i++) {
- var anchor = Pos(i, selectionStart.ch);
- var head = Pos(i, selectionEnd.ch);
+ var anchor = new Pos(i, selectionStart.ch);
+ var head = new Pos(i, selectionEnd.ch);
var range = {anchor: anchor, head: head};
selections.push(range);
}
@@ -3142,8 +3143,8 @@
var ch = end.ch - start.ch;
selectionEnd = {line: selectionEnd.line + line, ch: line ? selectionEnd.ch : ch + selectionEnd.ch};
if (lastSelection.visualLine) {
- selectionStart = Pos(selectionStart.line, 0);
- selectionEnd = Pos(selectionEnd.line, lineLength(cm, selectionEnd.line));
+ selectionStart = new Pos(selectionStart.line, 0);
+ selectionEnd = new Pos(selectionEnd.line, lineLength(cm, selectionEnd.line));
}
cm.setSelection(selectionStart, selectionEnd);
}
@@ -3192,7 +3193,7 @@
head = cursorMax(head, end);
head = offsetCursor(head, 0, -1);
if (head.ch == -1 && head.line != cm.firstLine()) {
- head = Pos(head.line - 1, lineLength(cm, head.line - 1));
+ head = new Pos(head.line - 1, lineLength(cm, head.line - 1));
}
}
return [anchor, head];
@@ -3208,7 +3209,6 @@
vim.visualLine ? 'line' : vim.visualBlock ? 'block' : 'char';
var cmSel = makeCmSelection(cm, sel, mode);
cm.setSelections(cmSel.ranges, cmSel.primary);
- updateFakeCursor(cm);
}
function makeCmSelection(cm, sel, mode, exclusive) {
var head = copyCursor(sel.head);
@@ -3241,16 +3241,18 @@
};
} else if (mode == 'block') {
var top = Math.min(anchor.line, head.line),
- left = Math.min(anchor.ch, head.ch),
+ fromCh = anchor.ch,
bottom = Math.max(anchor.line, head.line),
- right = Math.max(anchor.ch, head.ch) + 1;
+ toCh = head.ch;
+ if (fromCh < toCh) { toCh += 1 }
+ else { fromCh += 1 };
var height = bottom - top + 1;
var primary = head.line == top ? 0 : height - 1;
var ranges = [];
for (var i = 0; i < height; i++) {
ranges.push({
- anchor: Pos(top + i, left),
- head: Pos(top + i, right)
+ anchor: new Pos(top + i, fromCh),
+ head: new Pos(top + i, toCh)
});
}
return {
@@ -3284,7 +3286,6 @@
vim.visualLine = false;
vim.visualBlock = false;
if (!vim.insertMode) CodeMirror.signal(cm, "vim-mode-change", {mode: "normal"});
- clearFakeCursor(vim);
}
// Remove any trailing newlines from the selection. For
@@ -3372,7 +3373,7 @@
if (!start) { start = wordStart; }
}
}
- return { start: Pos(cur.line, start), end: Pos(cur.line, end) };
+ return { start: new Pos(cur.line, start), end: new Pos(cur.line, end) };
}
/**
@@ -3546,7 +3547,7 @@
}
}
if (state.nextCh || state.curMoveThrough) {
- return Pos(line, state.index);
+ return new Pos(line, state.index);
}
return cur;
}
@@ -3658,7 +3659,7 @@
break;
}
words.push(word);
- cur = Pos(word.line, forward ? (word.to - 1) : word.from);
+ cur = new Pos(word.line, forward ? (word.to - 1) : word.from);
}
var shortCircuit = words.length != repeat;
var firstWord = words[0];
@@ -3669,25 +3670,25 @@
// We did not start in the middle of a word. Discard the extra word at the end.
lastWord = words.pop();
}
- return Pos(lastWord.line, lastWord.from);
+ return new Pos(lastWord.line, lastWord.from);
} else if (forward && wordEnd) {
- return Pos(lastWord.line, lastWord.to - 1);
+ return new Pos(lastWord.line, lastWord.to - 1);
} else if (!forward && wordEnd) {
// ge
if (!shortCircuit && (firstWord.to != curStart.ch || firstWord.line != curStart.line)) {
// We did not start in the middle of a word. Discard the extra word at the end.
lastWord = words.pop();
}
- return Pos(lastWord.line, lastWord.to);
+ return new Pos(lastWord.line, lastWord.to);
} else {
// b
- return Pos(lastWord.line, lastWord.from);
+ return new Pos(lastWord.line, lastWord.from);
}
}
function moveToEol(cm, head, motionArgs, vim, keepHPos) {
var cur = head;
- var retval= Pos(cur.line + motionArgs.repeat - 1, Infinity);
+ var retval= new Pos(cur.line + motionArgs.repeat - 1, Infinity);
var end=cm.clipPos(retval);
end.ch--;
if (!keepHPos) {
@@ -3709,14 +3710,14 @@
}
start = idx;
}
- return Pos(cm.getCursor().line, idx);
+ return new Pos(cm.getCursor().line, idx);
}
function moveToColumn(cm, repeat) {
// repeat is always >= 1, so repeat - 1 always corresponds
// to the column we want to go to.
var line = cm.getCursor().line;
- return clipCursorToContent(cm, Pos(line, repeat - 1));
+ return clipCursorToContent(cm, new Pos(line, repeat - 1));
}
function updateMark(cm, vim, markName, pos) {
@@ -3968,7 +3969,7 @@
repeat--;
}
- return Pos(curr_index.ln, curr_index.pos);
+ return new Pos(curr_index.ln, curr_index.pos);
}
// TODO: perhaps this finagling of start and end positions belongs
@@ -3991,8 +3992,8 @@
// cursor is on a matching open bracket.
var offset = curChar === openSym ? 1 : 0;
- start = cm.scanForBracket(Pos(cur.line, cur.ch + offset), -1, undefined, {'bracketRegex': bracketRegexp});
- end = cm.scanForBracket(Pos(cur.line, cur.ch + offset), 1, undefined, {'bracketRegex': bracketRegexp});
+ start = cm.scanForBracket(new Pos(cur.line, cur.ch + offset), -1, undefined, {'bracketRegex': bracketRegexp});
+ end = cm.scanForBracket(new Pos(cur.line, cur.ch + offset), 1, undefined, {'bracketRegex': bracketRegexp});
if (!start || !end) {
return { start: cur, end: cur };
@@ -4073,8 +4074,8 @@
}
return {
- start: Pos(cur.line, start),
- end: Pos(cur.line, end)
+ start: new Pos(cur.line, start),
+ end: new Pos(cur.line, end)
};
}
@@ -4294,7 +4295,7 @@
ignoreCase = (/^[^A-Z]*$/).test(regexPart);
}
var regexp = new RegExp(regexPart,
- (ignoreCase || forceIgnoreCase) ? 'i' : undefined);
+ (ignoreCase || forceIgnoreCase) ? 'im' : 'm');
return regexp;
}
@@ -4324,7 +4325,7 @@
}
function showConfirm(cm, template) {
- var pre = dom('pre', {$color: 'red'}, template);
+ var pre = dom('pre', {$color: 'red', class: 'cm-vim-message'}, template);
if (cm.openNotification) {
cm.openNotification(pre, {bottom: true, duration: 5000});
} else {
@@ -4342,7 +4343,6 @@
}
function showPrompt(cm, options) {
- var shortText = (options.prefix || '') + ' ' + (options.desc || '');
var template = makePrompt(options.prefix, options.desc);
if (cm.openDialog) {
cm.openDialog(template, options.onClose, {
@@ -4351,6 +4351,9 @@
});
}
else {
+ var shortText = '';
+ if (typeof options.prefix != "string" && options.prefix) shortText += options.prefix.textContent;
+ if (options.desc) shortText += " " + options.desc;
options.onClose(prompt(shortText, ''));
}
}
@@ -4425,6 +4428,7 @@
function highlightSearchMatches(cm, query) {
clearTimeout(highlightTimeout);
highlightTimeout = setTimeout(function() {
+ if (!cm.state.vim) return;
var searchState = getSearchState(cm);
var overlay = searchState.getOverlay();
if (!overlay || query != overlay.query) {
@@ -4450,12 +4454,19 @@
var cursor = cm.getSearchCursor(query, pos);
for (var i = 0; i < repeat; i++) {
var found = cursor.find(prev);
- if (i == 0 && found && cursorEqual(cursor.from(), pos)) { found = cursor.find(prev); }
+ if (i == 0 && found && cursorEqual(cursor.from(), pos)) {
+ var lastEndPos = prev ? cursor.from() : cursor.to();
+ found = cursor.find(prev);
+ if (found && !found[0] && cursorEqual(cursor.from(), lastEndPos)) {
+ if (cm.getLine(lastEndPos.line).length == lastEndPos.ch)
+ 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) );
+ (prev) ? new Pos(cm.lastLine()) : new Pos(cm.firstLine(), 0) );
if (!cursor.find(prev)) {
return;
}
@@ -4491,7 +4502,7 @@
// 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) );
+ (prev) ? new Pos(cm.lastLine()) : new Pos(cm.firstLine(), 0) );
if (!cursor.find(prev)) {
return;
}
@@ -4547,7 +4558,7 @@
function getMarkPos(cm, vim, markName) {
if (markName == '\'' || markName == '`') {
- return vimGlobalState.jumpList.find(cm, -1) || Pos(0, 0);
+ return vimGlobalState.jumpList.find(cm, -1) || new Pos(0, 0);
} else if (markName == '.') {
return getLastEditPos(cm);
}
@@ -4612,7 +4623,7 @@
if (command.type == 'exToKey') {
// Handle Ex to Key mapping.
for (var i = 0; i < command.toKeys.length; i++) {
- CodeMirror.Vim.handleKey(cm, command.toKeys[i], 'mapping');
+ vimApi.handleKey(cm, command.toKeys[i], 'mapping');
}
return;
} else if (command.type == 'exToEx') {
@@ -4787,7 +4798,7 @@
var commandName = lhs.substring(1);
if (this.commandMap_[commandName] && this.commandMap_[commandName].user) {
delete this.commandMap_[commandName];
- return;
+ return true;
}
} else {
// Key to Ex or key to key mapping
@@ -4796,11 +4807,10 @@
if (keys == defaultKeymap[i].keys
&& defaultKeymap[i].context === ctx) {
defaultKeymap.splice(i, 1);
- return;
+ return true;
}
}
}
- throw Error('No such mapping.');
}
};
@@ -4827,13 +4837,11 @@
vmap: function(cm, params) { this.map(cm, params, 'visual'); },
unmap: function(cm, params, ctx) {
var mapArgs = params.args;
- if (!mapArgs || mapArgs.length < 1) {
+ if (!mapArgs || mapArgs.length < 1 || !exCommandDispatcher.unmap(mapArgs[0], ctx)) {
if (cm) {
showConfirm(cm, 'No such mapping: ' + params.input);
}
- return;
}
- exCommandDispatcher.unmap(mapArgs[0], ctx);
},
move: function(cm, params) {
commandDispatcher.processCommand(cm, cm.state.vim, {
@@ -4961,8 +4969,8 @@
var lineStart = params.line || cm.firstLine();
var lineEnd = params.lineEnd || params.line || cm.lastLine();
if (lineStart == lineEnd) { return; }
- var curStart = Pos(lineStart, 0);
- var curEnd = Pos(lineEnd, lineLength(cm, lineEnd));
+ var curStart = new Pos(lineStart, 0);
+ var curEnd = new Pos(lineEnd, lineLength(cm, lineEnd));
var text = cm.getRange(curStart, curEnd).split('\n');
var numberRegex = pattern ? pattern :
(number == 'decimal') ? /(-?)([\d]+)/ :
@@ -5103,12 +5111,6 @@
regexPart = new RegExp(regexPart).source; //normalize not escaped characters
}
replacePart = tokens[1];
- // 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')) {
replacePart = unescapeRegexReplace(replacePart.replace(/([^\\])&/g,"$1$$&"));
@@ -5174,7 +5176,7 @@
lineStart = lineEnd;
lineEnd = lineStart + count - 1;
}
- var startPos = clipCursorToContent(cm, Pos(lineStart, 0));
+ var startPos = clipCursorToContent(cm, new Pos(lineStart, 0));
var cursor = cm.getSearchCursor(query, startPos);
doReplace(cm, confirm, global, lineStart, lineEnd, cursor, query, replacePart, params.callback);
},
@@ -5298,10 +5300,18 @@
lineEnd += modifiedLineNumber - unmodifiedLineNumber;
joined = modifiedLineNumber < unmodifiedLineNumber;
}
+ function findNextValidMatch() {
+ var lastMatchTo = lastPos && copyCursor(searchCursor.to());
+ var match = searchCursor.findNext();
+ if (match && !match[0] && lastMatchTo && cursorEqual(searchCursor.from(), lastMatchTo)) {
+ match = searchCursor.findNext();
+ }
+ return match;
+ }
function next() {
// The below only loops to skip over multiple occurrences on the same
// line when 'global' is not true.
- while(searchCursor.findNext() &&
+ while(findNextValidMatch() &&
isInRange(searchCursor.from(), lineStart, lineEnd)) {
if (!global && searchCursor.from().line == modifiedLineNumber && !joined) {
continue;
@@ -5466,7 +5476,7 @@
match = (/<\w+-.+?>|<\w+>|./).exec(text);
key = match[0];
text = text.substring(match.index + key.length);
- CodeMirror.Vim.handleKey(cm, key, 'macro');
+ vimApi.handleKey(cm, key, 'macro');
if (vim.insertMode) {
var changes = register.insertModeChanges[imc++].changes;
vimGlobalState.macroModeState.lastInsertModeChanges.changes =
@@ -5561,36 +5571,6 @@
} else if (!cm.curOp.isVimOp) {
handleExternalSelection(cm, vim);
}
- if (vim.visualMode) {
- 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;
- }
}
function handleExternalSelection(cm, vim) {
var anchor = cm.getCursor('anchor');
@@ -5732,12 +5712,12 @@
if (change instanceof InsertModeKey) {
CodeMirror.lookupKey(change.keyName, 'vim-insert', keyHandler);
} else if (typeof change == "string") {
- var cur = cm.getCursor();
- cm.replaceRange(change, cur, cur);
+ cm.replaceSelection(change);
} else {
var start = cm.getCursor();
var end = offsetCursor(start, 0, change[0].length);
cm.replaceRange(change[0], start, end);
+ cm.setCursor(end);
}
}
}
diff --git a/help3/xhpeditor/cm/lib/codemirror.css b/help3/xhpeditor/cm/lib/codemirror.css
index a64f97c..f4d5718 100644
--- a/help3/xhpeditor/cm/lib/codemirror.css
+++ b/help3/xhpeditor/cm/lib/codemirror.css
@@ -60,20 +60,13 @@
.cm-fat-cursor div.CodeMirror-cursors {
z-index: 1;
}
-.cm-fat-cursor-mark {
- background-color: rgba(20, 255, 20, 0.5);
- -webkit-animation: blink 1.06s steps(1) infinite;
- -moz-animation: blink 1.06s steps(1) infinite;
- animation: blink 1.06s steps(1) infinite;
-}
-.cm-animate-fat-cursor {
- width: auto;
- border: 0;
- -webkit-animation: blink 1.06s steps(1) infinite;
- -moz-animation: blink 1.06s steps(1) infinite;
- animation: blink 1.06s steps(1) infinite;
- background-color: #7e7;
-}
+.cm-fat-cursor .CodeMirror-line::selection,
+.cm-fat-cursor .CodeMirror-line > span::selection,
+.cm-fat-cursor .CodeMirror-line > span > span::selection { background: transparent; }
+.cm-fat-cursor .CodeMirror-line::-moz-selection,
+.cm-fat-cursor .CodeMirror-line > span::-moz-selection,
+.cm-fat-cursor .CodeMirror-line > span > span::-moz-selection { background: transparent; }
+.cm-fat-cursor { caret-color: transparent; }
@-moz-keyframes blink {
0% {}
50% { background-color: transparent; }
@@ -171,6 +164,7 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #a22;}
height: 100%;
outline: none; /* Prevent dragging from highlighting the element */
position: relative;
+ z-index: 0;
}
.CodeMirror-sizer {
position: relative;
diff --git a/help3/xhpeditor/cm/lib/codemirror.js b/help3/xhpeditor/cm/lib/codemirror.js
index 42c068c..8686b78 100644
--- a/help3/xhpeditor/cm/lib/codemirror.js
+++ b/help3/xhpeditor/cm/lib/codemirror.js
@@ -2351,12 +2351,14 @@
function mapFromLineView(lineView, line, lineN) {
if (lineView.line == line)
{ return {map: lineView.measure.map, cache: lineView.measure.cache} }
- for (var i = 0; i < lineView.rest.length; i++)
- { if (lineView.rest[i] == line)
- { return {map: lineView.measure.maps[i], cache: lineView.measure.caches[i]} } }
- for (var i$1 = 0; i$1 < lineView.rest.length; i$1++)
- { if (lineNo(lineView.rest[i$1]) > lineN)
- { return {map: lineView.measure.maps[i$1], cache: lineView.measure.caches[i$1], before: true} } }
+ if (lineView.rest) {
+ for (var i = 0; i < lineView.rest.length; i++)
+ { if (lineView.rest[i] == line)
+ { return {map: lineView.measure.maps[i], cache: lineView.measure.caches[i]} } }
+ for (var i$1 = 0; i$1 < lineView.rest.length; i$1++)
+ { if (lineNo(lineView.rest[i$1]) > lineN)
+ { return {map: lineView.measure.maps[i$1], cache: lineView.measure.caches[i$1], before: true} } }
+ }
}
// Render a line into the hidden node display.externalMeasured. Used
@@ -2583,9 +2585,11 @@
}
function widgetTopHeight(lineObj) {
+ var ref = visualLine(lineObj);
+ var widgets = ref.widgets;
var height = 0;
- if (lineObj.widgets) { for (var i = 0; i < lineObj.widgets.length; ++i) { if (lineObj.widgets[i].above)
- { height += widgetHeight(lineObj.widgets[i]); } } }
+ if (widgets) { for (var i = 0; i < widgets.length; ++i) { if (widgets[i].above)
+ { height += widgetHeight(widgets[i]); } } }
return height
}
@@ -3150,13 +3154,19 @@
var curFragment = result.cursors = document.createDocumentFragment();
var selFragment = result.selection = document.createDocumentFragment();
+ var customCursor = cm.options.$customCursor;
+ if (customCursor) { primary = true; }
for (var i = 0; i < doc.sel.ranges.length; i++) {
if (!primary && i == doc.sel.primIndex) { continue }
var range = doc.sel.ranges[i];
if (range.from().line >= cm.display.viewTo || range.to().line < cm.display.viewFrom) { continue }
var collapsed = range.empty();
- if (collapsed || cm.options.showCursorWhenSelecting)
- { drawSelectionCursor(cm, range.head, curFragment); }
+ if (customCursor) {
+ var head = customCursor(cm, range);
+ if (head) { drawSelectionCursor(cm, head, curFragment); }
+ } else if (collapsed || cm.options.showCursorWhenSelecting) {
+ drawSelectionCursor(cm, range.head, curFragment);
+ }
if (!collapsed)
{ drawSelectionRange(cm, range, selFragment); }
}
@@ -3172,6 +3182,12 @@
cursor.style.top = pos.top + "px";
cursor.style.height = Math.max(0, pos.bottom - pos.top) * cm.options.cursorHeight + "px";
+ if (/\bcm-fat-cursor\b/.test(cm.getWrapperElement().className)) {
+ var charPos = charCoords(cm, head, "div", null, null);
+ var width = charPos.right - charPos.left;
+ cursor.style.width = (width > 0 ? width : cm.defaultCharWidth()) + "px";
+ }
+
if (pos.other) {
// Secondary cursor, shown when on a 'jump' in bi-directional text
var otherCursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor CodeMirror-secondarycursor"));
@@ -3344,10 +3360,14 @@
function updateHeightsInViewport(cm) {
var display = cm.display;
var prevBottom = display.lineDiv.offsetTop;
+ var viewTop = Math.max(0, display.scroller.getBoundingClientRect().top);
+ var oldHeight = display.lineDiv.getBoundingClientRect().top;
+ var mustScroll = 0;
for (var i = 0; i < display.view.length; i++) {
var cur = display.view[i], wrapping = cm.options.lineWrapping;
var height = (void 0), width = 0;
if (cur.hidden) { continue }
+ oldHeight += cur.line.height;
if (ie && ie_version < 8) {
var bot = cur.node.offsetTop + cur.node.offsetHeight;
height = bot - prevBottom;
@@ -3362,6 +3382,7 @@
}
var diff = cur.line.height - height;
if (diff > .005 || diff < -.005) {
+ if (oldHeight < viewTop) { mustScroll -= diff; }
updateLineHeight(cur.line, height);
updateWidgetHeight(cur.line);
if (cur.rest) { for (var j = 0; j < cur.rest.length; j++)
@@ -3376,6 +3397,7 @@
}
}
}
+ if (Math.abs(mustScroll) > 2) { display.scroller.scrollTop += mustScroll; }
}
// Read and store the height of line widgets associated with the
@@ -3636,6 +3658,7 @@
this.vert.firstChild.style.height =
Math.max(0, measure.scrollHeight - measure.clientHeight + totalHeight) + "px";
} else {
+ this.vert.scrollTop = 0;
this.vert.style.display = "";
this.vert.firstChild.style.height = "0";
}
@@ -4386,6 +4409,10 @@
// The element in which the editor lives.
d.wrapper = elt("div", [d.scrollbarFiller, d.gutterFiller, d.scroller], "CodeMirror");
+ // This attribute is respected by automatic translation systems such as Google Translate,
+ // and may also be respected by tools used by human translators.
+ d.wrapper.setAttribute('translate', 'no');
+
// Work around IE7 z-index bug (not perfect, hence IE7 not really being supported)
if (ie && ie_version < 8) { d.gutters.style.zIndex = -1; d.scroller.style.paddingRight = 0; }
if (!webkit && !(gecko && mobile)) { d.scroller.draggable = true; }
@@ -4483,6 +4510,12 @@
function onScrollWheel(cm, e) {
var delta = wheelEventDelta(e), dx = delta.x, dy = delta.y;
+ var pixelsPerUnit = wheelPixelsPerUnit;
+ if (e.deltaMode === 0) {
+ dx = e.deltaX;
+ dy = e.deltaY;
+ pixelsPerUnit = 1;
+ }
var display = cm.display, scroll = display.scroller;
// Quit if there's nothing to scroll here
@@ -4511,10 +4544,10 @@
// estimated pixels/delta value, we just handle horizontal
// scrolling entirely here. It'll be slightly off from native, but
// better than glitching out.
- if (dx && !gecko && !presto && wheelPixelsPerUnit != null) {
+ if (dx && !gecko && !presto && pixelsPerUnit != null) {
if (dy && canScrollY)
- { updateScrollTop(cm, Math.max(0, scroll.scrollTop + dy * wheelPixelsPerUnit)); }
- setScrollLeft(cm, Math.max(0, scroll.scrollLeft + dx * wheelPixelsPerUnit));
+ { updateScrollTop(cm, Math.max(0, scroll.scrollTop + dy * pixelsPerUnit)); }
+ setScrollLeft(cm, Math.max(0, scroll.scrollLeft + dx * pixelsPerUnit));
// Only prevent default scrolling if vertical scrolling is
// actually possible. Otherwise, it causes vertical scroll
// jitter on OSX trackpads when deltaX is small and deltaY
@@ -4527,15 +4560,15 @@
// 'Project' the visible viewport to cover the area that is being
// scrolled into view (if we know enough to estimate it).
- if (dy && wheelPixelsPerUnit != null) {
- var pixels = dy * wheelPixelsPerUnit;
+ if (dy && pixelsPerUnit != null) {
+ var pixels = dy * pixelsPerUnit;
var top = cm.doc.scrollTop, bot = top + display.wrapper.clientHeight;
if (pixels < 0) { top = Math.max(0, top + pixels - 50); }
else { bot = Math.min(cm.doc.height, bot + pixels + 50); }
updateDisplaySimple(cm, {top: top, bottom: bot});
}
- if (wheelSamples < 20) {
+ if (wheelSamples < 20 && e.deltaMode !== 0) {
if (display.wheelStartX == null) {
display.wheelStartX = scroll.scrollLeft; display.wheelStartY = scroll.scrollTop;
display.wheelDX = dx; display.wheelDY = dy;
@@ -6143,6 +6176,7 @@
getRange: function(from, to, lineSep) {
var lines = getBetween(this, clipPos(this, from), clipPos(this, to));
if (lineSep === false) { return lines }
+ if (lineSep === '') { return lines.join('') }
return lines.join(lineSep || this.lineSeparator())
},
@@ -8211,7 +8245,7 @@
}
function hiddenTextarea() {
- var te = elt("textarea", null, null, "position: absolute; bottom: -1em; padding: 0; width: 1px; height: 1em; outline: none");
+ var te = elt("textarea", null, null, "position: absolute; bottom: -1em; padding: 0; width: 1px; height: 1em; min-height: 1em; outline: none");
var div = elt("div", [te], null, "overflow: hidden; position: relative; width: 3px; height: 0px;");
// The textarea is kept positioned near the cursor to prevent the
// fact that it'll be scrolled into view on input from scrolling
@@ -8975,9 +9009,11 @@
ContentEditableInput.prototype.supportsTouch = function () { return true };
ContentEditableInput.prototype.receivedFocus = function () {
+ var this$1 = this;
+
var input = this;
if (this.selectionInEditor())
- { this.pollSelection(); }
+ { setTimeout(function () { return this$1.pollSelection(); }, 20); }
else
{ runInOp(this.cm, function () { return input.cm.curOp.selectionChanged = true; }); }
@@ -9806,7 +9842,7 @@
addLegacyProps(CodeMirror);
- CodeMirror.version = "5.61.1";
+ CodeMirror.version = "5.65.1";
return CodeMirror;
diff --git a/help3/xhpeditor/cm/mode/clike/clike.js b/help3/xhpeditor/cm/mode/clike/clike.js
index 15c0fd1..916aee6 100644
--- a/help3/xhpeditor/cm/mode/clike/clike.js
+++ b/help3/xhpeditor/cm/mode/clike/clike.js
@@ -484,7 +484,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
"instanceof interface native new package private protected public " +
"return static strictfp super switch synchronized this throw throws transient " +
"try volatile while @interface"),
- types: words("byte short int long float double boolean char void Boolean Byte Character Double Float " +
+ types: words("var byte short int long float double boolean char void Boolean Byte Character Double Float " +
"Integer Long Number Object Short String StringBuffer StringBuilder Void"),
blockKeywords: words("catch class do else finally for if switch try while"),
defKeywords: words("class interface enum @interface"),
diff --git a/help3/xhpeditor/cm/mode/cobol/cobol.js b/help3/xhpeditor/cm/mode/cobol/cobol.js
index 275857b..a7aeafa 100644
--- a/help3/xhpeditor/cm/mode/cobol/cobol.js
+++ b/help3/xhpeditor/cm/mode/cobol/cobol.js
@@ -195,7 +195,7 @@ CodeMirror.defineMode("cobol", function () {
case "string": // multi-line string parsing mode
var next = false;
while ((next = stream.next()) != null) {
- if (next == "\"" || next == "\'") {
+ if ((next == "\"" || next == "\'") && !stream.match(/['"]/, false)) {
state.mode = false;
break;
}
diff --git a/help3/xhpeditor/cm/mode/commonlisp/commonlisp.js b/help3/xhpeditor/cm/mode/commonlisp/commonlisp.js
index 52abbb2..e8528a9 100644
--- a/help3/xhpeditor/cm/mode/commonlisp/commonlisp.js
+++ b/help3/xhpeditor/cm/mode/commonlisp/commonlisp.js
@@ -114,6 +114,7 @@ CodeMirror.defineMode("commonlisp", function (config) {
closeBrackets: {pairs: "()[]{}\"\""},
lineComment: ";;",
+ fold: "brace-paren",
blockCommentStart: "#|",
blockCommentEnd: "|#"
};
diff --git a/help3/xhpeditor/cm/mode/css/css.js b/help3/xhpeditor/cm/mode/css/css.js
index 88a869b..503c48c 100644
--- a/help3/xhpeditor/cm/mode/css/css.js
+++ b/help3/xhpeditor/cm/mode/css/css.js
@@ -443,13 +443,15 @@ 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", "prefers-color-scheme"
+ "pointer", "any-pointer", "hover", "any-hover", "prefers-color-scheme",
+ "dynamic-range", "video-dynamic-range"
], mediaFeatures = keySet(mediaFeatures_);
var mediaValueKeywords_ = [
"landscape", "portrait", "none", "coarse", "fine", "on-demand", "hover",
"interlace", "progressive",
- "dark", "light"
+ "dark", "light",
+ "standard", "high"
], mediaValueKeywords = keySet(mediaValueKeywords_);
var propertyKeywords_ = [
@@ -482,7 +484,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
"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",
+ "drop-initial-value", "elevation", "empty-cells", "fit", "fit-content", "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",
@@ -564,7 +566,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
], propertyKeywords = keySet(propertyKeywords_);
var nonStandardPropertyKeywords_ = [
- "border-block", "border-block-color", "border-block-end",
+ "accent-color", "aspect-ratio", "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",
@@ -572,9 +574,9 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
"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",
+ "border-inline-style", "border-inline-width", "content-visibility", "margin-block",
"margin-block-end", "margin-block-start", "margin-inline", "margin-inline-end",
- "margin-inline-start", "padding-block", "padding-block-end",
+ "margin-inline-start", "overflow-anchor", "overscroll-behavior", "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",
@@ -598,16 +600,16 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
"bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown",
"burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue",
"cornsilk", "crimson", "cyan", "darkblue", "darkcyan", "darkgoldenrod",
- "darkgray", "darkgreen", "darkkhaki", "darkmagenta", "darkolivegreen",
+ "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen",
"darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen",
- "darkslateblue", "darkslategray", "darkturquoise", "darkviolet",
- "deeppink", "deepskyblue", "dimgray", "dodgerblue", "firebrick",
+ "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet",
+ "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "firebrick",
"floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite",
"gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew",
"hotpink", "indianred", "indigo", "ivory", "khaki", "lavender",
"lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral",
- "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightpink",
- "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray",
+ "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink",
+ "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey",
"lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta",
"maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple",
"mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise",
@@ -617,7 +619,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
"papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue",
"purple", "rebeccapurple", "red", "rosybrown", "royalblue", "saddlebrown",
"salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue",
- "slateblue", "slategray", "snow", "springgreen", "steelblue", "tan",
+ "slateblue", "slategray", "slategrey", "snow", "springgreen", "steelblue", "tan",
"teal", "thistle", "tomato", "turquoise", "violet", "wheat", "white",
"whitesmoke", "yellow", "yellowgreen"
], colorKeywords = keySet(colorKeywords_);
@@ -628,21 +630,21 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
"always", "amharic", "amharic-abegede", "antialiased", "appworkspace",
"arabic-indic", "armenian", "asterisks", "attr", "auto", "auto-flow", "avoid", "avoid-column", "avoid-page",
"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",
+ "bengali", "blink", "block", "block-axis", "blur", "bold", "bolder", "border", "border-box",
+ "both", "bottom", "break", "break-all", "break-word", "brightness", "bullets", "button", "button-bevel",
"buttonface", "buttonhighlight", "buttonshadow", "buttontext", "calc", "cambodian",
"capitalize", "caps-lock-indicator", "caption", "captiontext", "caret",
"cell", "center", "checkbox", "circle", "cjk-decimal", "cjk-earthly-branch",
"cjk-heavenly-stem", "cjk-ideographic", "clear", "clip", "close-quote",
"col-resize", "collapse", "color", "color-burn", "color-dodge", "column", "column-reverse",
- "compact", "condensed", "contain", "content", "contents",
- "content-box", "context-menu", "continuous", "copy", "counter", "counters", "cover", "crop",
- "cross", "crosshair", "currentcolor", "cursive", "cyclic", "darken", "dashed", "decimal",
+ "compact", "condensed", "conic-gradient", "contain", "content", "contents",
+ "content-box", "context-menu", "continuous", "contrast", "copy", "counter", "counters", "cover", "crop",
+ "cross", "crosshair", "cubic-bezier", "currentcolor", "cursive", "cyclic", "darken", "dashed", "decimal",
"decimal-leading-zero", "default", "default-button", "dense", "destination-atop",
"destination-in", "destination-out", "destination-over", "devanagari", "difference",
"disc", "discard", "disclosure-closed", "disclosure-open", "document",
"dot-dash", "dot-dot-dash",
- "dotted", "double", "down", "e-resize", "ease", "ease-in", "ease-in-out", "ease-out",
+ "dotted", "double", "down", "drop-shadow", "e-resize", "ease", "ease-in", "ease-in-out", "ease-out",
"element", "ellipse", "ellipsis", "embed", "end", "ethiopic", "ethiopic-abegede",
"ethiopic-abegede-am-et", "ethiopic-abegede-gez", "ethiopic-abegede-ti-er",
"ethiopic-abegede-ti-et", "ethiopic-halehame-aa-er",
@@ -652,10 +654,10 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
"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", "fill-box", "fixed", "flat", "flex", "flex-end", "flex-start", "footnotes",
- "forwards", "from", "geometricPrecision", "georgian", "graytext", "grid", "groove",
+ "forwards", "from", "geometricPrecision", "georgian", "grayscale", "graytext", "grid", "groove",
"gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hard-light", "hebrew",
"help", "hidden", "hide", "higher", "highlight", "highlighttext",
- "hiragana", "hiragana-iroha", "horizontal", "hsl", "hsla", "hue", "icon", "ignore",
+ "hiragana", "hiragana-iroha", "horizontal", "hsl", "hsla", "hue", "hue-rotate", "icon", "ignore",
"inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite",
"infobackground", "infotext", "inherit", "initial", "inline", "inline-axis",
"inline-block", "inline-flex", "inline-grid", "inline-table", "inset", "inside", "intrinsic", "invert",
@@ -685,15 +687,15 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
"pointer", "polygon", "portrait", "pre", "pre-line", "pre-wrap", "preserve-3d",
"progress", "push-button", "radial-gradient", "radio", "read-only",
"read-write", "read-write-plaintext-only", "rectangle", "region",
- "relative", "repeat", "repeating-linear-gradient",
- "repeating-radial-gradient", "repeat-x", "repeat-y", "reset", "reverse",
+ "relative", "repeat", "repeating-linear-gradient", "repeating-radial-gradient",
+ "repeating-conic-gradient", "repeat-x", "repeat-y", "reset", "reverse",
"rgb", "rgba", "ridge", "right", "rotate", "rotate3d", "rotateX", "rotateY",
"rotateZ", "round", "row", "row-resize", "row-reverse", "rtl", "run-in", "running",
- "s-resize", "sans-serif", "saturation", "scale", "scale3d", "scaleX", "scaleY", "scaleZ", "screen",
+ "s-resize", "sans-serif", "saturate", "saturation", "scale", "scale3d", "scaleX", "scaleY", "scaleZ", "screen",
"scroll", "scrollbar", "scroll-position", "se-resize", "searchfield",
"searchfield-cancel-button", "searchfield-decoration",
"searchfield-results-button", "searchfield-results-decoration", "self-start", "self-end",
- "semi-condensed", "semi-expanded", "separate", "serif", "show", "sidama",
+ "semi-condensed", "semi-expanded", "separate", "sepia", "serif", "show", "sidama",
"simp-chinese-formal", "simp-chinese-informal", "single",
"skew", "skewX", "skewY", "skip-white-space", "slide", "slider-horizontal",
"slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow",
diff --git a/help3/xhpeditor/cm/mode/factor/factor.js b/help3/xhpeditor/cm/mode/factor/factor.js
index 4c876d4..d3f7d49 100644
--- a/help3/xhpeditor/cm/mode/factor/factor.js
+++ b/help3/xhpeditor/cm/mode/factor/factor.js
@@ -77,7 +77,7 @@
// specific to simple modes.
meta: {
dontIndentStates: ["start", "vocabulary", "string", "string3", "stack"],
- lineComment: [ "!", "#!" ]
+ lineComment: "!"
}
});
diff --git a/help3/xhpeditor/cm/mode/fortran/fortran.js b/help3/xhpeditor/cm/mode/fortran/fortran.js
index 85bacc4..c33cf63 100644
--- a/help3/xhpeditor/cm/mode/fortran/fortran.js
+++ b/help3/xhpeditor/cm/mode/fortran/fortran.js
@@ -112,7 +112,7 @@ CodeMirror.defineMode("fortran", function() {
"c_short", "c_signed_char", "c_size_t", "character",
"complex", "double", "integer", "logical", "real"]);
var isOperatorChar = /[+\-*&=<>\/\:]/;
- var litOperator = new RegExp("(\.and\.|\.or\.|\.eq\.|\.lt\.|\.le\.|\.gt\.|\.ge\.|\.ne\.|\.not\.|\.eqv\.|\.neqv\.)", "i");
+ var litOperator = /^\.(and|or|eq|lt|le|gt|ge|ne|not|eqv|neqv)\./i;
function tokenBase(stream, state) {
diff --git a/help3/xhpeditor/cm/mode/gas/gas.js b/help3/xhpeditor/cm/mode/gas/gas.js
index b3515ab..016dc29 100644
--- a/help3/xhpeditor/cm/mode/gas/gas.js
+++ b/help3/xhpeditor/cm/mode/gas/gas.js
@@ -144,18 +144,26 @@ CodeMirror.defineMode("gas", function(_config, parserConfig) {
function x86(_parserConfig) {
lineCommentStartSymbol = "#";
+ registers.al = "variable";
+ registers.ah = "variable";
registers.ax = "variable";
registers.eax = "variable-2";
registers.rax = "variable-3";
+ registers.bl = "variable";
+ registers.bh = "variable";
registers.bx = "variable";
registers.ebx = "variable-2";
registers.rbx = "variable-3";
+ registers.cl = "variable";
+ registers.ch = "variable";
registers.cx = "variable";
registers.ecx = "variable-2";
registers.rcx = "variable-3";
+ registers.dl = "variable";
+ registers.dh = "variable";
registers.dx = "variable";
registers.edx = "variable-2";
registers.rdx = "variable-3";
diff --git a/help3/xhpeditor/cm/mode/javascript/javascript.js b/help3/xhpeditor/cm/mode/javascript/javascript.js
index 2b508c4..7cfee31 100644
--- a/help3/xhpeditor/cm/mode/javascript/javascript.js
+++ b/help3/xhpeditor/cm/mode/javascript/javascript.js
@@ -330,6 +330,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
cx.state.context = new Context(cx.state.context, cx.state.localVars, true)
cx.state.localVars = null
}
+ pushcontext.lex = pushblockcontext.lex = true
function popcontext() {
cx.state.localVars = cx.state.context.vars
cx.state.context = cx.state.context.prev
@@ -482,7 +483,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
function quasi(type, value) {
if (type != "quasi") return pass();
if (value.slice(value.length - 2) != "${") return cont(quasi);
- return cont(expression, continueQuasi);
+ return cont(maybeexpression, continueQuasi);
}
function continueQuasi(type) {
if (type == "}") {
diff --git a/help3/xhpeditor/cm/mode/julia/julia.js b/help3/xhpeditor/cm/mode/julia/julia.js
index de9f987..cb0d69c 100644
--- a/help3/xhpeditor/cm/mode/julia/julia.js
+++ b/help3/xhpeditor/cm/mode/julia/julia.js
@@ -12,9 +12,10 @@
"use strict";
CodeMirror.defineMode("julia", function(config, parserConf) {
- function wordRegexp(words, end) {
+ function wordRegexp(words, end, pre) {
+ if (typeof pre === "undefined") { pre = ""; }
if (typeof end === "undefined") { end = "\\b"; }
- return new RegExp("^((" + words.join(")|(") + "))" + end);
+ return new RegExp("^" + pre + "((" + words.join(")|(") + "))" + end);
}
var octChar = "\\\\[0-7]{1,3}";
@@ -22,13 +23,18 @@ CodeMirror.defineMode("julia", function(config, parserConf) {
var sChar = "\\\\[abefnrtv0%?'\"\\\\]";
var uChar = "([^\\u0027\\u005C\\uD800-\\uDFFF]|[\\uD800-\\uDFFF][\\uDC00-\\uDFFF])";
+ var asciiOperatorsList = [
+ "[<>]:", "[<>=]=", "<<=?", ">>>?=?", "=>", "--?>", "<--[->]?", "\\/\\/",
+ "\\.{2,3}", "[\\.\\\\%*+\\-<>!\\/^|&]=?", "\\?", "\\$", "~", ":"
+ ];
var operators = parserConf.operators || wordRegexp([
- "[<>]:", "[<>=]=", "<<=?", ">>>?=?", "=>", "->", "\\/\\/",
- "[\\\\%*+\\-<>!=\\/^|&\\u00F7\\u22BB]=?", "\\?", "\\$", "~", ":",
- "\\u00D7", "\\u2208", "\\u2209", "\\u220B", "\\u220C", "\\u2218",
- "\\u221A", "\\u221B", "\\u2229", "\\u222A", "\\u2260", "\\u2264",
- "\\u2265", "\\u2286", "\\u2288", "\\u228A", "\\u22C5",
- "\\b(in|isa)\\b(?!\.?\\()"], "");
+ "[<>]:", "[<>=]=", "<<=?", ">>>?=?", "=>", "--?>", "<--[->]?", "\\/\\/",
+ "[\\\\%*+\\-<>!\\/^|&\\u00F7\\u22BB]=?", "\\?", "\\$", "~", ":",
+ "\\u00D7", "\\u2208", "\\u2209", "\\u220B", "\\u220C", "\\u2218",
+ "\\u221A", "\\u221B", "\\u2229", "\\u222A", "\\u2260", "\\u2264",
+ "\\u2265", "\\u2286", "\\u2288", "\\u228A", "\\u22C5",
+ "\\b(in|isa)\\b(?!\.?\\()"
+ ], "");
var delimiters = parserConf.delimiters || /^[;,()[\]{}]/;
var identifiers = parserConf.identifiers ||
/^[_A-Za-z\u00A1-\u2217\u2219-\uFFFF][\w\u00A1-\u2217\u2219-\uFFFF]*!*/;
@@ -57,10 +63,13 @@ CodeMirror.defineMode("julia", function(config, parserConf) {
var keywords = wordRegexp(keywordsList);
var builtins = wordRegexp(builtinsList);
- var macro = /^@[_A-Za-z][\w]*/;
+ var macro = /^@[_A-Za-z\u00A1-\uFFFF][\w\u00A1-\uFFFF]*!*/;
var symbol = /^:[_A-Za-z\u00A1-\uFFFF][\w\u00A1-\uFFFF]*!*/;
var stringPrefixes = /^(`|([_A-Za-z\u00A1-\uFFFF]*"("")?))/;
+ var macroOperators = wordRegexp(asciiOperatorsList, "", "@");
+ var symbolOperators = wordRegexp(asciiOperatorsList, "", ":");
+
function inArray(state) {
return (state.nestedArrays > 0);
}
@@ -165,8 +174,7 @@ CodeMirror.defineMode("julia", function(config, parserConf) {
}
// Handle symbols
- if (!leavingExpr && stream.match(symbol) ||
- stream.match(/:([<>]:|<<=?|>>>?=?|->|\/\/|\.{2,3}|[\.\\%*+\-<>!\/^|&]=?|[~\?\$])/)) {
+ if (!leavingExpr && (stream.match(symbol) || stream.match(symbolOperators))) {
return "builtin";
}
@@ -212,7 +220,7 @@ CodeMirror.defineMode("julia", function(config, parserConf) {
return state.tokenize(stream, state);
}
- if (stream.match(macro)) {
+ if (stream.match(macro) || stream.match(macroOperators)) {
return "meta";
}
diff --git a/help3/xhpeditor/cm/mode/meta.js b/help3/xhpeditor/cm/mode/meta.js
index 477d6ae..38d5e01 100644
--- a/help3/xhpeditor/cm/mode/meta.js
+++ b/help3/xhpeditor/cm/mode/meta.js
@@ -19,7 +19,7 @@
{name: "Brainfuck", mime: "text/x-brainfuck", mode: "brainfuck", ext: ["b", "bf"]},
{name: "C", mime: "text/x-csrc", mode: "clike", ext: ["c", "h", "ino"]},
{name: "C++", mime: "text/x-c++src", mode: "clike", ext: ["cpp", "c++", "cc", "cxx", "hpp", "h++", "hh", "hxx"], alias: ["cpp"]},
- {name: "Cobol", mime: "text/x-cobol", mode: "cobol", ext: ["cob", "cpy"]},
+ {name: "Cobol", mime: "text/x-cobol", mode: "cobol", ext: ["cob", "cpy", "cbl"]},
{name: "C#", mime: "text/x-csharp", mode: "clike", ext: ["cs"], alias: ["csharp", "cs"]},
{name: "Clojure", mime: "text/x-clojure", mode: "clojure", ext: ["clj", "cljc", "cljx"]},
{name: "ClojureScript", mime: "text/x-clojurescript", mode: "clojure", ext: ["cljs"]},
diff --git a/help3/xhpeditor/cm/mode/mllike/mllike.js b/help3/xhpeditor/cm/mode/mllike/mllike.js
index a1538f7..8f92372 100644
--- a/help3/xhpeditor/cm/mode/mllike/mllike.js
+++ b/help3/xhpeditor/cm/mode/mllike/mllike.js
@@ -60,7 +60,7 @@ CodeMirror.defineMode('mllike', function(_config, parserConfig) {
}
}
if (ch === '(') {
- if (stream.eat('*')) {
+ if (stream.match(/^\*(?!\))/)) {
state.commentLevel++;
state.tokenize = tokenComment;
return state.tokenize(stream, state);
diff --git a/help3/xhpeditor/cm/mode/nsis/nsis.js b/help3/xhpeditor/cm/mode/nsis/nsis.js
index 636940f..ebd3c8b 100644
--- a/help3/xhpeditor/cm/mode/nsis/nsis.js
+++ b/help3/xhpeditor/cm/mode/nsis/nsis.js
@@ -24,42 +24,42 @@ CodeMirror.defineSimpleMode("nsis",{
{ regex: /`(?:[^\\`]|\\.)*`?/, token: "string" },
// Compile Time Commands
- {regex: /^\s*(?:\!(include|addincludedir|addplugindir|appendfile|cd|delfile|echo|error|execute|packhdr|pragma|finalize|getdllversion|gettlbversion|system|tempfile|warning|verbose|define|undef|insertmacro|macro|macroend|makensis|searchparse|searchreplace))\b/, token: "keyword"},
+ {regex: /^\s*(?:\!(addincludedir|addplugindir|appendfile|cd|define|delfile|echo|error|execute|finalize|getdllversion|gettlbversion|include|insertmacro|macro|macroend|makensis|packhdr|pragma|searchparse|searchreplace|system|tempfile|undef|uninstfinalize|verbose|warning))\b/i, token: "keyword"},
// Conditional Compilation
- {regex: /^\s*(?:\!(if(?:n?def)?|ifmacron?def|macro))\b/, token: "keyword", indent: true},
- {regex: /^\s*(?:\!(else|endif|macroend))\b/, token: "keyword", dedent: true},
+ {regex: /^\s*(?:\!(if(?:n?def)?|ifmacron?def|macro))\b/i, token: "keyword", indent: true},
+ {regex: /^\s*(?:\!(else|endif|macroend))\b/i, 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|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},
+ {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|GetWinVer|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/i, token: "keyword"},
+ {regex: /^\s*(?:Function|PageEx|Section(?:Group)?)\b/i, token: "keyword", indent: true},
+ {regex: /^\s*(?:(Function|PageEx|Section(?:Group)?)End)\b/i, token: "keyword", dedent: true},
// Command Options
- {regex: /\b(?:ARCHIVE|FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_NORMAL|FILE_ATTRIBUTE_OFFLINE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_TEMPORARY|HIDDEN|HKCC|HKCR(32|64)?|HKCU(32|64)?|HKDD|HKEY_CLASSES_ROOT|HKEY_CURRENT_CONFIG|HKEY_CURRENT_USER|HKEY_DYN_DATA|HKEY_LOCAL_MACHINE|HKEY_PERFORMANCE_DATA|HKEY_USERS|HKLM(32|64)?|HKPD|HKU|IDABORT|IDCANCEL|IDD_DIR|IDD_INST|IDD_INSTFILES|IDD_LICENSE|IDD_SELCOM|IDD_UNINST|IDD_VERIFY|IDIGNORE|IDNO|IDOK|IDRETRY|IDYES|MB_ABORTRETRYIGNORE|MB_DEFBUTTON1|MB_DEFBUTTON2|MB_DEFBUTTON3|MB_DEFBUTTON4|MB_ICONEXCLAMATION|MB_ICONINFORMATION|MB_ICONQUESTION|MB_ICONSTOP|MB_OK|MB_OKCANCEL|MB_RETRYCANCEL|MB_RIGHT|MB_RTLREADING|MB_SETFOREGROUND|MB_TOPMOST|MB_USERICON|MB_YESNO|MB_YESNOCANCEL|NORMAL|OFFLINE|READONLY|SHCTX|SHELL_CONTEXT|SW_HIDE|SW_SHOWDEFAULT|SW_SHOWMAXIMIZED|SW_SHOWMINIMIZED|SW_SHOWNORMAL|SYSTEM|TEMPORARY)\b/, token: "atom"},
- {regex: /\b(?:admin|all|auto|both|bottom|bzip2|components|current|custom|directory|false|force|hide|highest|ifdiff|ifnewer|instfiles|lastused|leave|left|license|listonly|lzma|nevershow|none|normal|notset|off|on|right|show|silent|silentlog|textonly|top|true|try|un\.components|un\.custom|un\.directory|un\.instfiles|un\.license|uninstConfirm|user|Win10|Win7|Win8|WinVista|zlib)\b/, token: "builtin"},
+ {regex: /\b(?:ARCHIVE|FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_NORMAL|FILE_ATTRIBUTE_OFFLINE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_TEMPORARY|HIDDEN|HKCC|HKCR(32|64)?|HKCU(32|64)?|HKDD|HKEY_CLASSES_ROOT|HKEY_CURRENT_CONFIG|HKEY_CURRENT_USER|HKEY_DYN_DATA|HKEY_LOCAL_MACHINE|HKEY_PERFORMANCE_DATA|HKEY_USERS|HKLM(32|64)?|HKPD|HKU|IDABORT|IDCANCEL|IDD_DIR|IDD_INST|IDD_INSTFILES|IDD_LICENSE|IDD_SELCOM|IDD_UNINST|IDD_VERIFY|IDIGNORE|IDNO|IDOK|IDRETRY|IDYES|MB_ABORTRETRYIGNORE|MB_DEFBUTTON1|MB_DEFBUTTON2|MB_DEFBUTTON3|MB_DEFBUTTON4|MB_ICONEXCLAMATION|MB_ICONINFORMATION|MB_ICONQUESTION|MB_ICONSTOP|MB_OK|MB_OKCANCEL|MB_RETRYCANCEL|MB_RIGHT|MB_RTLREADING|MB_SETFOREGROUND|MB_TOPMOST|MB_USERICON|MB_YESNO|MB_YESNOCANCEL|NORMAL|OFFLINE|READONLY|SHCTX|SHELL_CONTEXT|SW_HIDE|SW_SHOWDEFAULT|SW_SHOWMAXIMIZED|SW_SHOWMINIMIZED|SW_SHOWNORMAL|SYSTEM|TEMPORARY)\b/i, token: "atom"},
+ {regex: /\b(?:admin|all|auto|both|bottom|bzip2|components|current|custom|directory|false|force|hide|highest|ifdiff|ifnewer|instfiles|lastused|leave|left|license|listonly|lzma|nevershow|none|normal|notset|off|on|right|show|silent|silentlog|textonly|top|true|try|un\.components|un\.custom|un\.directory|un\.instfiles|un\.license|uninstConfirm|user|Win10|Win7|Win8|WinVista|zlib)\b/i, token: "builtin"},
// LogicLib.nsh
- {regex: /\$\{(?:And(?:If(?:Not)?|Unless)|Break|Case(?:Else)?|Continue|Default|Do(?:Until|While)?|Else(?:If(?:Not)?|Unless)?|End(?:If|Select|Switch)|Exit(?:Do|For|While)|For(?:Each)?|If(?:Cmd|Not(?:Then)?|Then)?|Loop(?:Until|While)?|Or(?:If(?:Not)?|Unless)|Select|Switch|Unless|While)\}/, token: "variable-2", indent: true},
+ {regex: /\$\{(?:And(?:If(?:Not)?|Unless)|Break|Case(?:Else)?|Continue|Default|Do(?:Until|While)?|Else(?:If(?:Not)?|Unless)?|End(?:If|Select|Switch)|Exit(?:Do|For|While)|For(?:Each)?|If(?:Cmd|Not(?:Then)?|Then)?|Loop(?:Until|While)?|Or(?:If(?:Not)?|Unless)|Select|Switch|Unless|While)\}/i, token: "variable-2", indent: true},
// FileFunc.nsh
- {regex: /\$\{(?:BannerTrimPath|DirState|DriveSpace|Get(BaseName|Drives|ExeName|ExePath|FileAttributes|FileExt|FileName|FileVersion|Options|OptionsS|Parameters|Parent|Root|Size|Time)|Locate|RefreshShellIcons)\}/, token: "variable-2", dedent: true},
+ {regex: /\$\{(?:BannerTrimPath|DirState|DriveSpace|Get(BaseName|Drives|ExeName|ExePath|FileAttributes|FileExt|FileName|FileVersion|Options|OptionsS|Parameters|Parent|Root|Size|Time)|Locate|RefreshShellIcons)\}/i, token: "variable-2", dedent: true},
// Memento.nsh
- {regex: /\$\{(?:Memento(?:Section(?:Done|End|Restore|Save)?|UnselectedSection))\}/, token: "variable-2", dedent: true},
+ {regex: /\$\{(?:Memento(?:Section(?:Done|End|Restore|Save)?|UnselectedSection))\}/i, token: "variable-2", dedent: true},
// TextFunc.nsh
- {regex: /\$\{(?:Config(?:Read|ReadS|Write|WriteS)|File(?:Join|ReadFromEnd|Recode)|Line(?:Find|Read|Sum)|Text(?:Compare|CompareS)|TrimNewLines)\}/, token: "variable-2", dedent: true},
+ {regex: /\$\{(?:Config(?:Read|ReadS|Write|WriteS)|File(?:Join|ReadFromEnd|Recode)|Line(?:Find|Read|Sum)|Text(?:Compare|CompareS)|TrimNewLines)\}/i, token: "variable-2", dedent: true},
// WinVer.nsh
- {regex: /\$\{(?:(?:At(?:Least|Most)|Is)(?:ServicePack|Win(?:7|8|10|95|98|200(?:0|3|8(?:R2)?)|ME|NT4|Vista|XP))|Is(?:NT|Server))\}/, token: "variable", dedent: true},
+ {regex: /\$\{(?:(?:At(?:Least|Most)|Is)(?:ServicePack|Win(?:7|8|10|95|98|200(?:0|3|8(?:R2)?)|ME|NT4|Vista|XP))|Is(?:NT|Server))\}/i, token: "variable", dedent: true},
// WordFunc.nsh
- {regex: /\$\{(?:StrFilterS?|Version(?:Compare|Convert)|Word(?:AddS?|Find(?:(?:2|3)X)?S?|InsertS?|ReplaceS?))\}/, token: "variable-2", dedent: true},
+ {regex: /\$\{(?:StrFilterS?|Version(?:Compare|Convert)|Word(?:AddS?|Find(?:(?:2|3)X)?S?|InsertS?|ReplaceS?))\}/i, token: "variable-2", dedent: true},
// x64.nsh
- {regex: /\$\{(?:RunningX64)\}/, token: "variable", dedent: true},
- {regex: /\$\{(?:Disable|Enable)X64FSRedirection\}/, token: "variable-2", dedent: true},
+ {regex: /\$\{(?:RunningX64)\}/i, token: "variable", dedent: true},
+ {regex: /\$\{(?:Disable|Enable)X64FSRedirection\}/i, token: "variable-2", dedent: true},
// Line Comment
{regex: /(#|;).*/, token: "comment"},
@@ -71,20 +71,20 @@ CodeMirror.defineSimpleMode("nsis",{
{regex: /[-+\/*=<>!]+/, token: "operator"},
// Variable
- {regex: /\$\w+/, token: "variable"},
+ {regex: /\$\w[\w\.]*/, token: "variable"},
// Constant
- {regex: /\${[\w\.:-]+}/, token: "variable-2"},
+ {regex: /\${[\!\w\.:-]+}/, token: "variable-2"},
// Language String
- {regex: /\$\([\w\.:-]+\)/, token: "variable-3"}
+ {regex: /\$\([\!\w\.:-]+\)/, token: "variable-3"}
],
comment: [
{regex: /.*?\*\//, token: "comment", next: "start"},
{regex: /.*/, token: "comment"}
],
meta: {
- electricInput: /^\s*((Function|PageEx|Section|Section(Group)?)End|(\!(endif|macroend))|\$\{(End(If|Unless|While)|Loop(Until)|Next)\})$/,
+ electricInput: /^\s*((Function|PageEx|Section|Section(Group)?)End|(\!(endif|macroend))|\$\{(End(If|Unless|While)|Loop(Until)|Next)\})$/i,
blockCommentStart: "/*",
blockCommentEnd: "*/",
lineComment: ["#", ";"]
diff --git a/help3/xhpeditor/cm/mode/perl/perl.js b/help3/xhpeditor/cm/mode/perl/perl.js
index ffe7877..41e7bc7 100644
--- a/help3/xhpeditor/cm/mode/perl/perl.js
+++ b/help3/xhpeditor/cm/mode/perl/perl.js
@@ -513,9 +513,8 @@ CodeMirror.defineMode("perl",function(){
return null;
if(state.chain)
return tokenChain(stream,state,state.chain,state.style,state.tail);
- 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(/^(\-?((\d[\d_]*)?\.\d+(e[+-]?\d+)?|\d+\.\d*)|0x[\da-fA-F_]+|0b[01_]+|\d[\d_]*(e[+-]?\d+)?)/))
+ return 'number';
if(stream.match(/^<<(?=[_a-zA-Z])/)){ // NOTE: <<SOMETHING\n...\nSOMETHING\n
stream.eatWhile(/\w/);
return tokenSOMETHING(stream,state,stream.current().substr(2));}
diff --git a/help3/xhpeditor/cm/mode/php/php.js b/help3/xhpeditor/cm/mode/php/php.js
index b2cae96..127b4a2 100644
--- a/help3/xhpeditor/cm/mode/php/php.js
+++ b/help3/xhpeditor/cm/mode/php/php.js
@@ -80,11 +80,11 @@
}
var phpKeywords = "abstract and array as break case catch class clone const continue declare default " +
- "do else elseif enddeclare endfor endforeach endif endswitch endwhile extends final " +
+ "do else elseif enddeclare endfor endforeach endif endswitch endwhile enum extends final " +
"for foreach function global goto if implements interface instanceof namespace " +
"new or private protected public static switch throw trait try use var while xor " +
"die echo empty exit eval include include_once isset list require require_once return " +
- "print unset __halt_compiler self static parent yield insteadof finally";
+ "print unset __halt_compiler self static parent yield insteadof finally readonly match";
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 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(" "));
@@ -95,7 +95,7 @@
helperType: "php",
keywords: keywords(phpKeywords),
blockKeywords: keywords("catch do else elseif for foreach if switch try while finally"),
- defKeywords: keywords("class function interface namespace trait"),
+ defKeywords: keywords("class enum function interface namespace trait"),
atoms: keywords(phpAtoms),
builtin: keywords(phpBuiltin),
multiLineStrings: true,
diff --git a/help3/xhpeditor/cm/mode/python/python.js b/help3/xhpeditor/cm/mode/python/python.js
index 7dff2d1..9e532ea 100644
--- a/help3/xhpeditor/cm/mode/python/python.js
+++ b/help3/xhpeditor/cm/mode/python/python.js
@@ -62,7 +62,7 @@
var identifiers = parserConf.identifiers|| /^[_A-Za-z\u00A1-\uFFFF][_A-Za-z0-9\u00A1-\uFFFF]*/;
myKeywords = myKeywords.concat(["nonlocal", "False", "True", "None", "async", "await"]);
myBuiltins = myBuiltins.concat(["ascii", "bytes", "exec", "print"]);
- var stringPrefixes = new RegExp("^(([rbuf]|(br)|(fr))?('{3}|\"{3}|['\"]))", "i");
+ var stringPrefixes = new RegExp("^(([rbuf]|(br)|(rb)|(fr)|(rf))?('{3}|\"{3}|['\"]))", "i");
} else {
var identifiers = parserConf.identifiers|| /^[_A-Za-z][_A-Za-z0-9]*/;
myKeywords = myKeywords.concat(["exec", "print"]);
@@ -298,7 +298,10 @@
}
function tokenLexer(stream, state) {
- if (stream.sol()) state.beginningOfLine = true;
+ if (stream.sol()) {
+ state.beginningOfLine = true;
+ state.dedent = false;
+ }
var style = state.tokenize(stream, state);
var current = stream.current();
@@ -315,7 +318,7 @@
// Handle scope changes.
if (current == "pass" || current == "return")
- state.dedent += 1;
+ state.dedent = true;
if (current == "lambda") state.lambda = true;
if (current == ":" && !state.lambda && top(state).type == "py" && stream.match(/^\s*(?:#|$)/, false))
@@ -332,10 +335,8 @@
else return ERRORCLASS;
}
}
- if (state.dedent > 0 && stream.eol() && top(state).type == "py") {
- if (state.scopes.length > 1) state.scopes.pop();
- state.dedent -= 1;
- }
+ if (state.dedent && stream.eol() && top(state).type == "py" && state.scopes.length > 1)
+ state.scopes.pop();
return style;
}
@@ -370,14 +371,16 @@
if (state.tokenize != tokenBase)
return state.tokenize.isString ? CodeMirror.Pass : 0;
- var scope = top(state), closing = scope.type == textAfter.charAt(0)
+ var scope = top(state)
+ var closing = scope.type == textAfter.charAt(0) ||
+ scope.type == "py" && !state.dedent && /^(else:|elif |except |finally:)/.test(textAfter)
if (scope.align != null)
return scope.align - (closing ? 1 : 0)
else
return scope.offset - (closing ? hangingIndent : 0)
},
- electricInput: /^\s*[\}\]\)]$/,
+ electricInput: /^\s*([\}\]\)]|else:|elif |except |finally:)$/,
closeBrackets: {triples: "'\""},
lineComment: "#",
fold: "indent"
diff --git a/help3/xhpeditor/cm/mode/python/test.js b/help3/xhpeditor/cm/mode/python/test.js
index 5fff328..1adf953 100644
--- a/help3/xhpeditor/cm/mode/python/test.js
+++ b/help3/xhpeditor/cm/mode/python/test.js
@@ -45,4 +45,30 @@
MT("dontIndentTypeDecl",
"[variable i]: [builtin int] [operator =] [number 32]",
"[builtin print]([variable i])")
+
+ MT("dedentElse",
+ "[keyword if] [variable x]:",
+ " [variable foo]()",
+ "[keyword elif] [variable y]:",
+ " [variable bar]()",
+ "[keyword else]:",
+ " [variable baz]()")
+
+ MT("dedentElsePass",
+ "[keyword if] [variable x]:",
+ " [keyword pass]",
+ "[keyword elif] [variable y]:",
+ " [keyword pass]",
+ "[keyword else]:",
+ " [keyword pass]")
+
+ MT("dedentElseInFunction",
+ "[keyword def] [def foo]():",
+ " [keyword if] [variable x]:",
+ " [variable foo]()",
+ " [keyword elif] [variable y]:",
+ " [variable bar]()",
+ " [keyword pass]",
+ " [keyword else]:",
+ " [variable baz]()")
})();
diff --git a/help3/xhpeditor/cm/mode/scheme/scheme.js b/help3/xhpeditor/cm/mode/scheme/scheme.js
index 370250d..d11a132 100644
--- a/help3/xhpeditor/cm/mode/scheme/scheme.js
+++ b/help3/xhpeditor/cm/mode/scheme/scheme.js
@@ -3,6 +3,7 @@
/**
* Author: Koh Zi Han, based on implementation by Koh Zi Chun
+ * Improved by: Jakub T. Jankiewicz
*/
(function(mod) {
@@ -17,7 +18,7 @@
CodeMirror.defineMode("scheme", function () {
var BUILTIN = "builtin", COMMENT = "comment", STRING = "string",
- ATOM = "atom", NUMBER = "number", BRACKET = "bracket";
+ SYMBOL = "symbol", ATOM = "atom", NUMBER = "number", BRACKET = "bracket";
var INDENT_WORD_SKIP = 2;
function makeKeywords(str) {
@@ -67,6 +68,18 @@ CodeMirror.defineMode("scheme", function () {
return stream.match(hexMatcher);
}
+ function processEscapedSequence(stream, options) {
+ var next, escaped = false;
+ while ((next = stream.next()) != null) {
+ if (next == options.token && !escaped) {
+
+ options.state.mode = false;
+ break;
+ }
+ escaped = !escaped && next == "\\";
+ }
+ }
+
return {
startState: function () {
return {
@@ -92,17 +105,19 @@ CodeMirror.defineMode("scheme", function () {
switch(state.mode){
case "string": // multi-line string parsing mode
- var next, escaped = false;
- while ((next = stream.next()) != null) {
- if (next == "\"" && !escaped) {
-
- state.mode = false;
- break;
- }
- escaped = !escaped && next == "\\";
- }
+ processEscapedSequence(stream, {
+ token: "\"",
+ state: state
+ });
returnType = STRING; // continue on in scheme-string mode
break;
+ case "symbol": // escape symbol
+ processEscapedSequence(stream, {
+ token: "|",
+ state: state
+ });
+ returnType = SYMBOL; // continue on in scheme-symbol mode
+ break;
case "comment": // comment parsing mode
var next, maybeEnd = false;
while ((next = stream.next()) != null) {
@@ -143,6 +158,9 @@ CodeMirror.defineMode("scheme", function () {
stream.eatWhile(/[\w_\-!$%&*+\.\/:<=>?@\^~]/);
returnType = ATOM;
}
+ } else if (ch == '|') {
+ state.mode = "symbol";
+ returnType = SYMBOL;
} else if (ch == '#') {
if (stream.eat("|")) { // Multi-line comment
state.mode = "comment"; // toggle to comment mode
@@ -255,6 +273,7 @@ CodeMirror.defineMode("scheme", function () {
return state.indentStack.indent;
},
+ fold: "brace-paren",
closeBrackets: {pairs: "()[]{}\"\""},
lineComment: ";;"
};
diff --git a/help3/xhpeditor/cm/mode/soy/soy.js b/help3/xhpeditor/cm/mode/soy/soy.js
index 1f8a13c..debe726 100644
--- a/help3/xhpeditor/cm/mode/soy/soy.js
+++ b/help3/xhpeditor/cm/mode/soy/soy.js
@@ -24,6 +24,8 @@
"@inject?": paramData,
"@state": paramData,
"template": { soyState: "templ-def", variableScope: true},
+ "extern": {soyState: "param-def"},
+ "export": {soyState: "export"},
"literal": { },
"msg": {},
"fallbackmsg": { noEndTag: true, reduceIndent: true},
@@ -31,6 +33,8 @@
"plural": {},
"let": { soyState: "var-def" },
"if": {},
+ "javaimpl": {},
+ "jsimpl": {},
"elseif": { noEndTag: true, reduceIndent: true},
"else": { noEndTag: true, reduceIndent: true},
"switch": {},
@@ -46,6 +50,8 @@
"delcall": { soyState: "templ-ref" },
"log": {},
"element": { variableScope: true },
+ "velog": {},
+ "const": { soyState: "const-def"},
};
var indentingTags = Object.keys(tags).filter(function(tag) {
@@ -134,10 +140,10 @@
state.context = new Context(state.context, "list-literal", state.variables);
state.lookupVariables = false;
return null;
- } else if (stream.match(/map\b/)) {
+ } else if (stream.match(/\bmap(?=\()/)) {
state.soyState.push("map-literal");
return "keyword";
- } else if (stream.match(/record\b/)) {
+ } else if (stream.match(/\brecord(?=\()/)) {
state.soyState.push("record-literal");
return "keyword";
} else if (stream.match(/([\w]+)(?=\()/)) {
@@ -448,11 +454,11 @@
state.indent -= 2 * config.indentUnit;
return null;
}
- if (stream.match(/\w+(?=\s+as)/)) {
+ if (stream.match(/\w+(?=\s+as\b)/)) {
return "variable";
}
if (match = stream.match(/\w+/)) {
- return /(from|as)/.test(match[0]) ? "keyword" : "def";
+ return /\b(from|as)\b/.test(match[0]) ? "keyword" : "def";
}
if (match = stream.match(/^["']/)) {
state.soyState.push("string");
@@ -522,6 +528,27 @@
return this.token(stream, state);
}
return tokenUntil(stream, state, /\{\/literal}/);
+ case "export":
+ if (match = stream.match(/\w+/)) {
+ state.soyState.pop();
+ if (match == "const") {
+ state.soyState.push("const-def")
+ return "keyword";
+ } else if (match == "extern") {
+ state.soyState.push("param-def")
+ return "keyword";
+ }
+ } else {
+ stream.next();
+ }
+ return null;
+ case "const-def":
+ if (stream.match(/^\w+/)) {
+ state.soyState.pop();
+ return "def";
+ }
+ stream.next();
+ return null;
}
if (stream.match('{literal}')) {
@@ -552,7 +579,8 @@
state.context = new Context(state.context, state.tag, tag.variableScope ? state.variables : null);
// Otherwise close the current context.
} else if (endTag) {
- if (!state.context || state.context.tag != tagName) {
+ var isBalancedForExtern = tagName == 'extern' && (state.context && state.context.tag == 'export');
+ if (!state.context || ((state.context.tag != tagName) && !isBalancedForExtern)) {
tagError = true;
} else if (state.context) {
if (state.context.kind) {
@@ -577,7 +605,7 @@
state.indent += 2 * config.indentUnit;
state.soyState.push("tag");
return "keyword";
- } else if (!state.context && stream.match(/\bimport\b/)) {
+ } else if (!state.context && stream.sol() && stream.match(/import\b/)) {
state.soyState.push("import");
state.indent += 2 * config.indentUnit;
return "keyword";
diff --git a/help3/xhpeditor/cm/mode/soy/test.js b/help3/xhpeditor/cm/mode/soy/test.js
index ae13158..44e7c4c 100644
--- a/help3/xhpeditor/cm/mode/soy/test.js
+++ b/help3/xhpeditor/cm/mode/soy/test.js
@@ -308,4 +308,15 @@
MT('import',
'[keyword import] {[def Name], [variable Person] [keyword as] [def P]} [keyword from] [string \'examples/proto/example.proto\'];');
+
+ MT('velog',
+ '[keyword {velog] [variable-2&error $data][keyword }] Logged [keyword {/velog}]');
+
+ MT('extern', '[keyword {extern] [def renderer]: ([def s]:[type string])=>[type string][keyword }] [keyword {/extern}]');
+
+ MT('export extern', '[keyword {export] [keyword extern] [def renderer]: ([def s]:[type string])=>[type string][keyword }] [keyword {/extern}]');
+
+ MT('const',
+ '[keyword {const] [def FOO] = [atom 5] [keyword /}]',
+ '[keyword {export] [keyword const] [def FOO] = [atom 5] [keyword /}]');
})();
diff --git a/help3/xhpeditor/cm/mode/sql/sql.js b/help3/xhpeditor/cm/mode/sql/sql.js
index ead4d6d..cd8b757 100644
--- a/help3/xhpeditor/cm/mode/sql/sql.js
+++ b/help3/xhpeditor/cm/mode/sql/sql.js
@@ -122,9 +122,9 @@ CodeMirror.defineMode("sql", function(config, parserConfig) {
if (dateSQL.hasOwnProperty(word) && (stream.match(/^( )+'[^']*'/) || stream.match(/^( )+"[^"]*"/)))
return "number";
if (atoms.hasOwnProperty(word)) return "atom";
- if (builtin.hasOwnProperty(word)) return "builtin";
+ if (builtin.hasOwnProperty(word)) return "type";
if (keywords.hasOwnProperty(word)) return "keyword";
- if (client.hasOwnProperty(word)) return "string-2";
+ if (client.hasOwnProperty(word)) return "builtin";
return null;
}
}
@@ -332,7 +332,7 @@ CodeMirror.defineMode("sql", function(config, parserConfig) {
CodeMirror.defineMIME("text/x-mariadb", {
name: "sql",
client: set("charset clear connect edit ego exit go help nopager notee nowarning pager print prompt quit rehash source status system tee"),
- keywords: set(sqlKeywords + "accessible action add after algorithm all always analyze asensitive at authors auto_increment autocommit avg avg_row_length before binary binlog both btree cache call cascade cascaded case catalog_name chain change changed character check checkpoint checksum class_origin client_statistics close coalesce code collate collation collations column columns comment commit committed completion concurrent condition connection consistent constraint contains continue contributors convert cross current current_date current_time current_timestamp current_user cursor data database databases day_hour day_microsecond day_minute day_second deallocate dec declare default delay_key_write delayed delimiter des_key_file describe deterministic dev_pop dev_samp deviance diagnostics directory disable discard distinctrow div dual dumpfile each elseif enable enclosed end ends engine engines enum errors escape escaped even event events every execute exists exit explain extended fast fetch field fields first flush for force foreign found_rows full fulltext function general generated get global grant grants group groupby_concat handler hard hash help high_priority hosts hour_microsecond hour_minute hour_second if ignore ignore_server_ids import index index_statistics infile inner innodb inout insensitive insert_method install interval invoker isolation iterate key keys kill language last leading leave left level limit linear lines list load local localtime localtimestamp lock logs low_priority master master_heartbeat_period master_ssl_verify_server_cert masters match max max_rows maxvalue message_text middleint migrate min min_rows minute_microsecond minute_second mod mode modifies modify mutex mysql_errno natural next no no_write_to_binlog offline offset one online open optimize option optionally out outer outfile pack_keys parser partition partitions password persistent phase plugin plugins prepare preserve prev primary privileges procedure processlist profile profiles purge query quick range read read_write reads real rebuild recover references regexp relaylog release remove rename reorganize repair repeatable replace require resignal restrict resume return returns revoke right rlike rollback rollup row row_format rtree savepoint schedule schema schema_name schemas second_microsecond security sensitive separator serializable server session share show shutdown signal slave slow smallint snapshot soft soname spatial specific sql sql_big_result sql_buffer_result sql_cache sql_calc_found_rows sql_no_cache sql_small_result sqlexception sqlstate sqlwarning ssl start starting starts status std stddev stddev_pop stddev_samp storage straight_join subclass_origin sum suspend table_name table_statistics tables tablespace temporary terminated to trailing transaction trigger triggers truncate uncommitted undo uninstall unique unlock upgrade usage use use_frm user user_resources user_statistics using utc_date utc_time utc_timestamp value variables varying view views virtual warnings when while with work write xa xor year_month zerofill begin do then else loop repeat"),
+ keywords: set(sqlKeywords + "accessible action add after algorithm all always analyze asensitive at authors auto_increment autocommit avg avg_row_length before binary binlog both btree cache call cascade cascaded case catalog_name chain change changed character check checkpoint checksum class_origin client_statistics close coalesce code collate collation collations column columns comment commit committed completion concurrent condition connection consistent constraint contains continue contributors convert cross current current_date current_time current_timestamp current_user cursor data database databases day_hour day_microsecond day_minute day_second deallocate dec declare default delay_key_write delayed delimiter des_key_file describe deterministic dev_pop dev_samp deviance diagnostics directory disable discard distinctrow div dual dumpfile each elseif enable enclosed end ends engine engines enum errors escape escaped even event events every execute exists exit explain extended fast fetch field fields first flush for force foreign found_rows full fulltext function general generated get global grant grants group group_concat handler hard hash help high_priority hosts hour_microsecond hour_minute hour_second if ignore ignore_server_ids import index index_statistics infile inner innodb inout insensitive insert_method install interval invoker isolation iterate key keys kill language last leading leave left level limit linear lines list load local localtime localtimestamp lock logs low_priority master master_heartbeat_period master_ssl_verify_server_cert masters match max max_rows maxvalue message_text middleint migrate min min_rows minute_microsecond minute_second mod mode modifies modify mutex mysql_errno natural next no no_write_to_binlog offline offset one online open optimize option optionally out outer outfile pack_keys parser partition partitions password persistent phase plugin plugins prepare preserve prev primary privileges procedure processlist profile profiles purge query quick range read read_write reads real rebuild recover references regexp relaylog release remove rename reorganize repair repeatable replace require resignal restrict resume return returns revoke right rlike rollback rollup row row_format rtree savepoint schedule schema schema_name schemas second_microsecond security sensitive separator serializable server session share show shutdown signal slave slow smallint snapshot soft soname spatial specific sql sql_big_result sql_buffer_result sql_cache sql_calc_found_rows sql_no_cache sql_small_result sqlexception sqlstate sqlwarning ssl start starting starts status std stddev stddev_pop stddev_samp storage straight_join subclass_origin sum suspend table_name table_statistics tables tablespace temporary terminated to trailing transaction trigger triggers truncate uncommitted undo uninstall unique unlock upgrade usage use use_frm user user_resources user_statistics using utc_date utc_time utc_timestamp value variables varying view views virtual warnings when while with work write xa xor year_month zerofill begin do then else loop repeat"),
builtin: set("bool boolean bit blob decimal double float long longblob longtext medium mediumblob mediumint mediumtext time timestamp tinyblob tinyint tinytext text bigint int int1 int2 int3 int4 int8 integer float float4 float8 double char varbinary varchar varcharacter precision date datetime year unsigned signed numeric"),
atoms: set("false true null unknown"),
operatorChars: /^[*+\-%<>!=&|^]/,
@@ -452,7 +452,7 @@ CodeMirror.defineMode("sql", function(config, parserConfig) {
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 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"),
+ builtin: set("abs acos acosh add_months aggregate and any approx_count_distinct approx_percentile array array_contains array_distinct array_except array_intersect array_join array_max array_min array_position array_remove array_repeat array_sort array_union arrays_overlap arrays_zip ascii asin asinh assert_true atan atan2 atanh avg base64 between bigint bin binary bit_and bit_count bit_get bit_length bit_or bit_xor bool_and bool_or boolean bround btrim cardinality case cast cbrt ceil ceiling char char_length character_length chr coalesce collect_list collect_set concat concat_ws conv corr cos cosh cot count count_if count_min_sketch covar_pop covar_samp crc32 cume_dist current_catalog current_database current_date current_timestamp current_timezone current_user date date_add date_format date_from_unix_date date_part date_sub date_trunc datediff day dayofmonth dayofweek dayofyear decimal decode degrees delimited dense_rank div double e element_at elt encode every exists exp explode explode_outer expm1 extract factorial filter find_in_set first first_value flatten float floor forall format_number format_string from_csv from_json from_unixtime from_utc_timestamp get_json_object getbit greatest grouping grouping_id hash hex hour hypot if ifnull in initcap inline inline_outer input_file_block_length input_file_block_start input_file_name inputformat instr int isnan isnotnull isnull java_method json_array_length json_object_keys json_tuple kurtosis lag last last_day last_value lcase lead least left length levenshtein like ln locate log log10 log1p log2 lower lpad ltrim make_date make_dt_interval make_interval make_timestamp make_ym_interval map map_concat map_entries map_filter map_from_arrays map_from_entries map_keys map_values map_zip_with max max_by md5 mean min min_by minute mod monotonically_increasing_id month months_between named_struct nanvl negative next_day not now nth_value ntile nullif nvl nvl2 octet_length or outputformat overlay parse_url percent_rank percentile percentile_approx pi pmod posexplode posexplode_outer position positive pow power printf quarter radians raise_error rand randn random rank rcfile reflect regexp regexp_extract regexp_extract_all regexp_like regexp_replace repeat replace reverse right rint rlike round row_number rpad rtrim schema_of_csv schema_of_json second sentences sequence sequencefile serde session_window sha sha1 sha2 shiftleft shiftright shiftrightunsigned shuffle sign signum sin sinh size skewness slice smallint some sort_array soundex space spark_partition_id split sqrt stack std stddev stddev_pop stddev_samp str_to_map string struct substr substring substring_index sum tan tanh textfile timestamp timestamp_micros timestamp_millis timestamp_seconds tinyint to_csv to_date to_json to_timestamp to_unix_timestamp to_utc_timestamp transform transform_keys transform_values translate trim trunc try_add try_divide typeof ucase unbase64 unhex uniontype unix_date unix_micros unix_millis unix_seconds unix_timestamp upper uuid var_pop var_samp variance version weekday weekofyear when width_bucket window xpath xpath_boolean xpath_double xpath_float xpath_int xpath_long xpath_number xpath_short xpath_string xxhash64 year zip_with"),
atoms: set("false true null"),
operatorChars: /^[*\/+\-%<>!=~&|^]/,
dateSQL: set("date time timestamp"),
diff --git a/help3/xhpeditor/cm/mode/stylus/stylus.js b/help3/xhpeditor/cm/mode/stylus/stylus.js
index 5cddff0..978696b 100644
--- a/help3/xhpeditor/cm/mode/stylus/stylus.js
+++ b/help3/xhpeditor/cm/mode/stylus/stylus.js
@@ -737,12 +737,12 @@
// 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 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","dynamic-range","video-dynamic-range"];
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"];
var nonStandardPropertyKeywords_ = ["scrollbar-arrow-color","scrollbar-base-color","scrollbar-dark-shadow-color","scrollbar-face-color","scrollbar-highlight-color","scrollbar-shadow-color","scrollbar-3d-light-color","scrollbar-track-color","shape-inside","searchfield-cancel-button","searchfield-decoration","searchfield-results-button","searchfield-results-decoration","zoom"];
var fontProperties_ = ["font-family","src","unicode-range","font-variant","font-feature-settings","font-stretch","font-weight","font-style"];
var colorKeywords_ = ["aliceblue","antiquewhite","aqua","aquamarine","azure","beige","bisque","black","blanchedalmond","blue","blueviolet","brown","burlywood","cadetblue","chartreuse","chocolate","coral","cornflowerblue","cornsilk","crimson","cyan","darkblue","darkcyan","darkgoldenrod","darkgray","darkgreen","darkkhaki","darkmagenta","darkolivegreen","darkorange","darkorchid","darkred","darksalmon","darkseagreen","darkslateblue","darkslategray","darkturquoise","darkviolet","deeppink","deepskyblue","dimgray","dodgerblue","firebrick","floralwhite","forestgreen","fuchsia","gainsboro","ghostwhite","gold","goldenrod","gray","grey","green","greenyellow","honeydew","hotpink","indianred","indigo","ivory","khaki","lavender","lavenderblush","lawngreen","lemonchiffon","lightblue","lightcoral","lightcyan","lightgoldenrodyellow","lightgray","lightgreen","lightpink","lightsalmon","lightseagreen","lightskyblue","lightslategray","lightsteelblue","lightyellow","lime","limegreen","linen","magenta","maroon","mediumaquamarine","mediumblue","mediumorchid","mediumpurple","mediumseagreen","mediumslateblue","mediumspringgreen","mediumturquoise","mediumvioletred","midnightblue","mintcream","mistyrose","moccasin","navajowhite","navy","oldlace","olive","olivedrab","orange","orangered","orchid","palegoldenrod","palegreen","paleturquoise","palevioletred","papayawhip","peachpuff","peru","pink","plum","powderblue","purple","rebeccapurple","red","rosybrown","royalblue","saddlebrown","salmon","sandybrown","seagreen","seashell","sienna","silver","skyblue","slateblue","slategray","snow","springgreen","steelblue","tan","teal","thistle","tomato","turquoise","violet","wheat","white","whitesmoke","yellow","yellowgreen"];
- var valueKeywords_ = ["above","absolute","activeborder","additive","activecaption","afar","after-white-space","ahead","alias","all","all-scroll","alphabetic","alternate","always","amharic","amharic-abegede","antialiased","appworkspace","arabic-indic","armenian","asterisks","attr","auto","avoid","avoid-column","avoid-page","avoid-region","background","backwards","baseline","below","bidi-override","binary","bengali","blink","block","block-axis","bold","bolder","border","border-box","both","bottom","break","break-all","break-word","bullets","button","button-bevel","buttonface","buttonhighlight","buttonshadow","buttontext","calc","cambodian","capitalize","caps-lock-indicator","caption","captiontext","caret","cell","center","checkbox","circle","cjk-decimal","cjk-earthly-branch","cjk-heavenly-stem","cjk-ideographic","clear","clip","close-quote","col-resize","collapse","column","compact","condensed","contain","content","contents","content-box","context-menu","continuous","copy","counter","counters","cover","crop","cross","crosshair","currentcolor","cursive","cyclic","dashed","decimal","decimal-leading-zero","default","default-button","destination-atop","destination-in","destination-out","destination-over","devanagari","disc","discard","disclosure-closed","disclosure-open","document","dot-dash","dot-dot-dash","dotted","double","down","e-resize","ease","ease-in","ease-in-out","ease-out","element","ellipse","ellipsis","embed","end","ethiopic","ethiopic-abegede","ethiopic-abegede-am-et","ethiopic-abegede-gez","ethiopic-abegede-ti-er","ethiopic-abegede-ti-et","ethiopic-halehame-aa-er","ethiopic-halehame-aa-et","ethiopic-halehame-am-et","ethiopic-halehame-gez","ethiopic-halehame-om-et","ethiopic-halehame-sid-et","ethiopic-halehame-so-et","ethiopic-halehame-ti-er","ethiopic-halehame-ti-et","ethiopic-halehame-tig","ethiopic-numeric","ew-resize","expanded","extends","extra-condensed","extra-expanded","fantasy","fast","fill","fixed","flat","flex","footnotes","forwards","from","geometricPrecision","georgian","graytext","groove","gujarati","gurmukhi","hand","hangul","hangul-consonant","hebrew","help","hidden","hide","higher","highlight","highlighttext","hiragana","hiragana-iroha","horizontal","hsl","hsla","icon","ignore","inactiveborder","inactivecaption","inactivecaptiontext","infinite","infobackground","infotext","inherit","initial","inline","inline-axis","inline-block","inline-flex","inline-table","inset","inside","intrinsic","invert","italic","japanese-formal","japanese-informal","justify","kannada","katakana","katakana-iroha","keep-all","khmer","korean-hangul-formal","korean-hanja-formal","korean-hanja-informal","landscape","lao","large","larger","left","level","lighter","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","malayalam","match","matrix","matrix3d","media-controls-background","media-current-time-display","media-fullscreen-button","media-mute-button","media-play-button","media-return-to-realtime-button","media-rewind-button","media-seek-back-button","media-seek-forward-button","media-slider","media-sliderthumb","media-time-remaining-display","media-volume-slider","media-volume-slider-container","media-volume-sliderthumb","medium","menu","menulist","menulist-button","menulist-text","menulist-textfield","menutext","message-box","middle","min-intrinsic","mix","mongolian","monospace","move","multiple","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","open-quote","optimizeLegibility","optimizeSpeed","oriya","oromo","outset","outside","outside-shape","overlay","overline","padding","padding-box","painted","page","paused","persian","perspective","plus-darker","plus-lighter","pointer","polygon","portrait","pre","pre-line","pre-wrap","preserve-3d","progress","push-button","radial-gradient","radio","read-only","read-write","read-write-plaintext-only","rectangle","region","relative","repeat","repeating-linear-gradient","repeating-radial-gradient","repeat-x","repeat-y","reset","reverse","rgb","rgba","ridge","right","rotate","rotate3d","rotateX","rotateY","rotateZ","round","row-resize","rtl","run-in","running","s-resize","sans-serif","scale","scale3d","scaleX","scaleY","scaleZ","scroll","scrollbar","scroll-position","se-resize","searchfield","searchfield-cancel-button","searchfield-decoration","searchfield-results-button","searchfield-results-decoration","semi-condensed","semi-expanded","separate","serif","show","sidama","simp-chinese-formal","simp-chinese-informal","single","skew","skewX","skewY","skip-white-space","slide","slider-horizontal","slider-vertical","sliderthumb-horizontal","sliderthumb-vertical","slow","small","small-caps","small-caption","smaller","solid","somali","source-atop","source-in","source-out","source-over","space","spell-out","square","square-button","start","static","status-bar","stretch","stroke","sub","subpixel-antialiased","super","sw-resize","symbolic","symbols","table","table-caption","table-cell","table-column","table-column-group","table-footer-group","table-header-group","table-row","table-row-group","tamil","telugu","text","text-bottom","text-top","textarea","textfield","thai","thick","thin","threeddarkshadow","threedface","threedhighlight","threedlightshadow","threedshadow","tibetan","tigre","tigrinya-er","tigrinya-er-abegede","tigrinya-et","tigrinya-et-abegede","to","top","trad-chinese-formal","trad-chinese-informal","translate","translate3d","translateX","translateY","translateZ","transparent","ultra-condensed","ultra-expanded","underline","up","upper-alpha","upper-armenian","upper-greek","upper-hexadecimal","upper-latin","upper-norwegian","upper-roman","uppercase","urdu","url","var","vertical","vertical-text","visible","visibleFill","visiblePainted","visibleStroke","visual","w-resize","wait","wave","wider","window","windowframe","windowtext","words","x-large","x-small","xor","xx-large","xx-small","bicubic","optimizespeed","grayscale","row","row-reverse","wrap","wrap-reverse","column-reverse","flex-start","flex-end","space-between","space-around", "unset"];
+ var valueKeywords_ = ["above","absolute","activeborder","additive","activecaption","afar","after-white-space","ahead","alias","all","all-scroll","alphabetic","alternate","always","amharic","amharic-abegede","antialiased","appworkspace","arabic-indic","armenian","asterisks","attr","auto","avoid","avoid-column","avoid-page","avoid-region","background","backwards","baseline","below","bidi-override","binary","bengali","blink","block","block-axis","bold","bolder","border","border-box","both","bottom","break","break-all","break-word","bullets","button","button-bevel","buttonface","buttonhighlight","buttonshadow","buttontext","calc","cambodian","capitalize","caps-lock-indicator","caption","captiontext","caret","cell","center","checkbox","circle","cjk-decimal","cjk-earthly-branch","cjk-heavenly-stem","cjk-ideographic","clear","clip","close-quote","col-resize","collapse","column","compact","condensed","conic-gradient","contain","content","contents","content-box","context-menu","continuous","copy","counter","counters","cover","crop","cross","crosshair","currentcolor","cursive","cyclic","dashed","decimal","decimal-leading-zero","default","default-button","destination-atop","destination-in","destination-out","destination-over","devanagari","disc","discard","disclosure-closed","disclosure-open","document","dot-dash","dot-dot-dash","dotted","double","down","e-resize","ease","ease-in","ease-in-out","ease-out","element","ellipse","ellipsis","embed","end","ethiopic","ethiopic-abegede","ethiopic-abegede-am-et","ethiopic-abegede-gez","ethiopic-abegede-ti-er","ethiopic-abegede-ti-et","ethiopic-halehame-aa-er","ethiopic-halehame-aa-et","ethiopic-halehame-am-et","ethiopic-halehame-gez","ethiopic-halehame-om-et","ethiopic-halehame-sid-et","ethiopic-halehame-so-et","ethiopic-halehame-ti-er","ethiopic-halehame-ti-et","ethiopic-halehame-tig","ethiopic-numeric","ew-resize","expanded","extends","extra-condensed","extra-expanded","fantasy","fast","fill","fixed","flat","flex","footnotes","forwards","from","geometricPrecision","georgian","graytext","groove","gujarati","gurmukhi","hand","hangul","hangul-consonant","hebrew","help","hidden","hide","high","higher","highlight","highlighttext","hiragana","hiragana-iroha","horizontal","hsl","hsla","icon","ignore","inactiveborder","inactivecaption","inactivecaptiontext","infinite","infobackground","infotext","inherit","initial","inline","inline-axis","inline-block","inline-flex","inline-table","inset","inside","intrinsic","invert","italic","japanese-formal","japanese-informal","justify","kannada","katakana","katakana-iroha","keep-all","khmer","korean-hangul-formal","korean-hanja-formal","korean-hanja-informal","landscape","lao","large","larger","left","level","lighter","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","malayalam","match","matrix","matrix3d","media-controls-background","media-current-time-display","media-fullscreen-button","media-mute-button","media-play-button","media-return-to-realtime-button","media-rewind-button","media-seek-back-button","media-seek-forward-button","media-slider","media-sliderthumb","media-time-remaining-display","media-volume-slider","media-volume-slider-container","media-volume-sliderthumb","medium","menu","menulist","menulist-button","menulist-text","menulist-textfield","menutext","message-box","middle","min-intrinsic","mix","mongolian","monospace","move","multiple","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","open-quote","optimizeLegibility","optimizeSpeed","oriya","oromo","outset","outside","outside-shape","overlay","overline","padding","padding-box","painted","page","paused","persian","perspective","plus-darker","plus-lighter","pointer","polygon","portrait","pre","pre-line","pre-wrap","preserve-3d","progress","push-button","radial-gradient","radio","read-only","read-write","read-write-plaintext-only","rectangle","region","relative","repeat","repeating-linear-gradient","repeating-radial-gradient","repeating-conic-gradient","repeat-x","repeat-y","reset","reverse","rgb","rgba","ridge","right","rotate","rotate3d","rotateX","rotateY","rotateZ","round","row-resize","rtl","run-in","running","s-resize","sans-serif","scale","scale3d","scaleX","scaleY","scaleZ","scroll","scrollbar","scroll-position","se-resize","searchfield","searchfield-cancel-button","searchfield-decoration","searchfield-results-button","searchfield-results-decoration","semi-condensed","semi-expanded","separate","serif","show","sidama","simp-chinese-formal","simp-chinese-informal","single","skew","skewX","skewY","skip-white-space","slide","slider-horizontal","slider-vertical","sliderthumb-horizontal","sliderthumb-vertical","slow","small","small-caps","small-caption","smaller","solid","somali","source-atop","source-in","source-out","source-over","space","spell-out","square","square-button","standard","start","static","status-bar","stretch","stroke","sub","subpixel-antialiased","super","sw-resize","symbolic","symbols","table","table-caption","table-cell","table-column","table-column-group","table-footer-group","table-header-group","table-row","table-row-group","tamil","telugu","text","text-bottom","text-top","textarea","textfield","thai","thick","thin","threeddarkshadow","threedface","threedhighlight","threedlightshadow","threedshadow","tibetan","tigre","tigrinya-er","tigrinya-er-abegede","tigrinya-et","tigrinya-et-abegede","to","top","trad-chinese-formal","trad-chinese-informal","translate","translate3d","translateX","translateY","translateZ","transparent","ultra-condensed","ultra-expanded","underline","up","upper-alpha","upper-armenian","upper-greek","upper-hexadecimal","upper-latin","upper-norwegian","upper-roman","uppercase","urdu","url","var","vertical","vertical-text","visible","visibleFill","visiblePainted","visibleStroke","visual","w-resize","wait","wave","wider","window","windowframe","windowtext","words","x-large","x-small","xor","xx-large","xx-small","bicubic","optimizespeed","grayscale","row","row-reverse","wrap","wrap-reverse","column-reverse","flex-start","flex-end","space-between","space-around", "unset"];
var wordOperatorKeywords_ = ["in","and","or","not","is not","is a","is","isnt","defined","if unless"],
blockKeywords_ = ["for","if","else","unless", "from", "to"],
diff --git a/help3/xhpeditor/cm/mode/xml/xml.js b/help3/xhpeditor/cm/mode/xml/xml.js
index 46806ac..4e36106 100644
--- a/help3/xhpeditor/cm/mode/xml/xml.js
+++ b/help3/xhpeditor/cm/mode/xml/xml.js
@@ -187,6 +187,10 @@ CodeMirror.defineMode("xml", function(editorConf, config_) {
};
}
+ function lower(tagName) {
+ return tagName && tagName.toLowerCase();
+ }
+
function Context(state, tagName, startOfLine) {
this.prev = state.context;
this.tagName = tagName || "";
@@ -205,8 +209,8 @@ CodeMirror.defineMode("xml", function(editorConf, config_) {
return;
}
parentTagName = state.context.tagName;
- if (!config.contextGrabbers.hasOwnProperty(parentTagName) ||
- !config.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) {
+ if (!config.contextGrabbers.hasOwnProperty(lower(parentTagName)) ||
+ !config.contextGrabbers[lower(parentTagName)].hasOwnProperty(lower(nextTagName))) {
return;
}
popContext(state);
@@ -240,7 +244,7 @@ CodeMirror.defineMode("xml", function(editorConf, config_) {
if (type == "word") {
var tagName = stream.current();
if (state.context && state.context.tagName != tagName &&
- config.implicitlyClosed.hasOwnProperty(state.context.tagName))
+ config.implicitlyClosed.hasOwnProperty(lower(state.context.tagName)))
popContext(state);
if ((state.context && state.context.tagName == tagName) || config.matchClosing === false) {
setStyle = "tag";
@@ -279,7 +283,7 @@ CodeMirror.defineMode("xml", function(editorConf, config_) {
var tagName = state.tagName, tagStart = state.tagStart;
state.tagName = state.tagStart = null;
if (type == "selfcloseTag" ||
- config.autoSelfClosers.hasOwnProperty(tagName)) {
+ config.autoSelfClosers.hasOwnProperty(lower(tagName))) {
maybePopContext(state, tagName);
} else {
maybePopContext(state, tagName);
@@ -359,7 +363,7 @@ CodeMirror.defineMode("xml", function(editorConf, config_) {
if (context.tagName == tagAfter[2]) {
context = context.prev;
break;
- } else if (config.implicitlyClosed.hasOwnProperty(context.tagName)) {
+ } else if (config.implicitlyClosed.hasOwnProperty(lower(context.tagName))) {
context = context.prev;
} else {
break;
@@ -367,8 +371,8 @@ CodeMirror.defineMode("xml", function(editorConf, config_) {
}
} else if (tagAfter) { // Opening tag spotted
while (context) {
- var grabbers = config.contextGrabbers[context.tagName];
- if (grabbers && grabbers.hasOwnProperty(tagAfter[2]))
+ var grabbers = config.contextGrabbers[lower(context.tagName)];
+ if (grabbers && grabbers.hasOwnProperty(lower(tagAfter[2])))
context = context.prev;
else
break;
diff --git a/help3/xhpeditor/cm/mode/yaml-frontmatter/yaml-frontmatter.js b/help3/xhpeditor/cm/mode/yaml-frontmatter/yaml-frontmatter.js
index 88c845e..5c6175e 100644
--- a/help3/xhpeditor/cm/mode/yaml-frontmatter/yaml-frontmatter.js
+++ b/help3/xhpeditor/cm/mode/yaml-frontmatter/yaml-frontmatter.js
@@ -17,55 +17,55 @@
var yamlMode = CodeMirror.getMode(config, "yaml")
var innerMode = CodeMirror.getMode(config, parserConfig && parserConfig.base || "gfm")
- function curMode(state) {
- return state.state == BODY ? innerMode : yamlMode
+ function localMode(state) {
+ return state.state == FRONTMATTER ? {mode: yamlMode, state: state.yaml} : {mode: innerMode, state: state.inner}
}
return {
startState: function () {
return {
state: START,
- inner: CodeMirror.startState(yamlMode)
+ yaml: null,
+ inner: CodeMirror.startState(innerMode)
}
},
copyState: function (state) {
return {
state: state.state,
- inner: CodeMirror.copyState(curMode(state), state.inner)
+ yaml: state.yaml && CodeMirror.copyState(yamlMode, state.yaml),
+ inner: CodeMirror.copyState(innerMode, state.inner)
}
},
token: function (stream, state) {
if (state.state == START) {
if (stream.match('---', false)) {
state.state = FRONTMATTER
- return yamlMode.token(stream, state.inner)
+ state.yaml = CodeMirror.startState(yamlMode)
+ return yamlMode.token(stream, state.yaml)
} else {
state.state = BODY
- state.inner = CodeMirror.startState(innerMode)
return innerMode.token(stream, state.inner)
}
} else if (state.state == FRONTMATTER) {
var end = stream.sol() && stream.match(/(---|\.\.\.)/, false)
- var style = yamlMode.token(stream, state.inner)
+ var style = yamlMode.token(stream, state.yaml)
if (end) {
state.state = BODY
- state.inner = CodeMirror.startState(innerMode)
+ state.yaml = null
}
return style
} else {
return innerMode.token(stream, state.inner)
}
},
- innerMode: function (state) {
- return {mode: curMode(state), state: state.inner}
- },
+ innerMode: localMode,
indent: function(state, a, b) {
- var mode = curMode(state)
- return mode.indent ? mode.indent(state.inner, a, b) : CodeMirror.Pass
+ var m = localMode(state)
+ return m.mode.indent ? m.mode.indent(m.state, a, b) : CodeMirror.Pass
},
blankLine: function (state) {
- var mode = curMode(state)
- if (mode.blankLine) return mode.blankLine(state.inner)
+ var m = localMode(state)
+ if (m.mode.blankLine) return m.mode.blankLine(m.state)
}
}
})
diff --git a/help3/xhpeditor/cm/package.json b/help3/xhpeditor/cm/package.json
index 250a75b..1794a38 100644
--- a/help3/xhpeditor/cm/package.json
+++ b/help3/xhpeditor/cm/package.json
@@ -1,6 +1,6 @@
{
"name": "codemirror",
- "version": "5.61.1",
+ "version": "5.65.1",
"main": "lib/codemirror.js",
"style": "lib/codemirror.css",
"author": {
diff --git a/help3/xhpeditor/cm/src/display/Display.js b/help3/xhpeditor/cm/src/display/Display.js
index d57f00b..9d4c036 100644
--- a/help3/xhpeditor/cm/src/display/Display.js
+++ b/help3/xhpeditor/cm/src/display/Display.js
@@ -49,6 +49,10 @@ export function Display(place, doc, input, options) {
// The element in which the editor lives.
d.wrapper = elt("div", [d.scrollbarFiller, d.gutterFiller, d.scroller], "CodeMirror")
+ // This attribute is respected by automatic translation systems such as Google Translate,
+ // and may also be respected by tools used by human translators.
+ d.wrapper.setAttribute('translate', 'no')
+
// Work around IE7 z-index bug (not perfect, hence IE7 not really being supported)
if (ie && ie_version < 8) { d.gutters.style.zIndex = -1; d.scroller.style.paddingRight = 0 }
if (!webkit && !(gecko && mobile)) d.scroller.draggable = true
diff --git a/help3/xhpeditor/cm/src/display/scroll_events.js b/help3/xhpeditor/cm/src/display/scroll_events.js
index fbed426..5c6173a 100644
--- a/help3/xhpeditor/cm/src/display/scroll_events.js
+++ b/help3/xhpeditor/cm/src/display/scroll_events.js
@@ -41,6 +41,12 @@ export function wheelEventPixels(e) {
export function onScrollWheel(cm, e) {
let delta = wheelEventDelta(e), dx = delta.x, dy = delta.y
+ let pixelsPerUnit = wheelPixelsPerUnit
+ if (e.deltaMode === 0) {
+ dx = e.deltaX
+ dy = e.deltaY
+ pixelsPerUnit = 1
+ }
let display = cm.display, scroll = display.scroller
// Quit if there's nothing to scroll here
@@ -69,10 +75,10 @@ export function onScrollWheel(cm, e) {
// estimated pixels/delta value, we just handle horizontal
// scrolling entirely here. It'll be slightly off from native, but
// better than glitching out.
- if (dx && !gecko && !presto && wheelPixelsPerUnit != null) {
+ if (dx && !gecko && !presto && pixelsPerUnit != null) {
if (dy && canScrollY)
- updateScrollTop(cm, Math.max(0, scroll.scrollTop + dy * wheelPixelsPerUnit))
- setScrollLeft(cm, Math.max(0, scroll.scrollLeft + dx * wheelPixelsPerUnit))
+ updateScrollTop(cm, Math.max(0, scroll.scrollTop + dy * pixelsPerUnit))
+ setScrollLeft(cm, Math.max(0, scroll.scrollLeft + dx * pixelsPerUnit))
// Only prevent default scrolling if vertical scrolling is
// actually possible. Otherwise, it causes vertical scroll
// jitter on OSX trackpads when deltaX is small and deltaY
@@ -85,15 +91,15 @@ export function onScrollWheel(cm, e) {
// 'Project' the visible viewport to cover the area that is being
// scrolled into view (if we know enough to estimate it).
- if (dy && wheelPixelsPerUnit != null) {
- let pixels = dy * wheelPixelsPerUnit
+ if (dy && pixelsPerUnit != null) {
+ let pixels = dy * pixelsPerUnit
let top = cm.doc.scrollTop, bot = top + display.wrapper.clientHeight
if (pixels < 0) top = Math.max(0, top + pixels - 50)
else bot = Math.min(cm.doc.height, bot + pixels + 50)
updateDisplaySimple(cm, {top: top, bottom: bot})
}
- if (wheelSamples < 20) {
+ if (wheelSamples < 20 && e.deltaMode !== 0) {
if (display.wheelStartX == null) {
display.wheelStartX = scroll.scrollLeft; display.wheelStartY = scroll.scrollTop
display.wheelDX = dx; display.wheelDY = dy
diff --git a/help3/xhpeditor/cm/src/display/scrollbars.js b/help3/xhpeditor/cm/src/display/scrollbars.js
index 18ac121..f77ffc1 100644
--- a/help3/xhpeditor/cm/src/display/scrollbars.js
+++ b/help3/xhpeditor/cm/src/display/scrollbars.js
@@ -60,6 +60,7 @@ class NativeScrollbars {
this.vert.firstChild.style.height =
Math.max(0, measure.scrollHeight - measure.clientHeight + totalHeight) + "px"
} else {
+ this.vert.scrollTop = 0
this.vert.style.display = ""
this.vert.firstChild.style.height = "0"
}
diff --git a/help3/xhpeditor/cm/src/display/selection.js b/help3/xhpeditor/cm/src/display/selection.js
index d377a9f..f53c790 100644
--- a/help3/xhpeditor/cm/src/display/selection.js
+++ b/help3/xhpeditor/cm/src/display/selection.js
@@ -15,13 +15,19 @@ export function prepareSelection(cm, primary = true) {
let curFragment = result.cursors = document.createDocumentFragment()
let selFragment = result.selection = document.createDocumentFragment()
+ let customCursor = cm.options.$customCursor
+ if (customCursor) primary = true
for (let i = 0; i < doc.sel.ranges.length; i++) {
if (!primary && i == doc.sel.primIndex) continue
let range = doc.sel.ranges[i]
if (range.from().line >= cm.display.viewTo || range.to().line < cm.display.viewFrom) continue
let collapsed = range.empty()
- if (collapsed || cm.options.showCursorWhenSelecting)
+ if (customCursor) {
+ let head = customCursor(cm, range)
+ if (head) drawSelectionCursor(cm, head, curFragment)
+ } else if (collapsed || cm.options.showCursorWhenSelecting) {
drawSelectionCursor(cm, range.head, curFragment)
+ }
if (!collapsed)
drawSelectionRange(cm, range, selFragment)
}
@@ -37,6 +43,12 @@ export function drawSelectionCursor(cm, head, output) {
cursor.style.top = pos.top + "px"
cursor.style.height = Math.max(0, pos.bottom - pos.top) * cm.options.cursorHeight + "px"
+ if (/\bcm-fat-cursor\b/.test(cm.getWrapperElement().className)) {
+ let charPos = charCoords(cm, head, "div", null, null)
+ let width = charPos.right - charPos.left
+ cursor.style.width = (width > 0 ? width : cm.defaultCharWidth()) + "px"
+ }
+
if (pos.other) {
// Secondary cursor, shown when on a 'jump' in bi-directional text
let otherCursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor CodeMirror-secondarycursor"))
diff --git a/help3/xhpeditor/cm/src/display/update_lines.js b/help3/xhpeditor/cm/src/display/update_lines.js
index 60c367e..f09524b 100644
--- a/help3/xhpeditor/cm/src/display/update_lines.js
+++ b/help3/xhpeditor/cm/src/display/update_lines.js
@@ -8,10 +8,14 @@ import { ie, ie_version } from "../util/browser.js"
export function updateHeightsInViewport(cm) {
let display = cm.display
let prevBottom = display.lineDiv.offsetTop
+ let viewTop = Math.max(0, display.scroller.getBoundingClientRect().top)
+ let oldHeight = display.lineDiv.getBoundingClientRect().top
+ let mustScroll = 0
for (let i = 0; i < display.view.length; i++) {
let cur = display.view[i], wrapping = cm.options.lineWrapping
let height, width = 0
if (cur.hidden) continue
+ oldHeight += cur.line.height
if (ie && ie_version < 8) {
let bot = cur.node.offsetTop + cur.node.offsetHeight
height = bot - prevBottom
@@ -26,6 +30,7 @@ export function updateHeightsInViewport(cm) {
}
let diff = cur.line.height - height
if (diff > .005 || diff < -.005) {
+ if (oldHeight < viewTop) mustScroll -= diff
updateLineHeight(cur.line, height)
updateWidgetHeight(cur.line)
if (cur.rest) for (let j = 0; j < cur.rest.length; j++)
@@ -40,6 +45,7 @@ export function updateHeightsInViewport(cm) {
}
}
}
+ if (Math.abs(mustScroll) > 2) display.scroller.scrollTop += mustScroll
}
// Read and store the height of line widgets associated with the
diff --git a/help3/xhpeditor/cm/src/edit/main.js b/help3/xhpeditor/cm/src/edit/main.js
index 929a2bd..49dad2c 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.61.1"
+CodeMirror.version = "5.65.1"
diff --git a/help3/xhpeditor/cm/src/input/ContentEditableInput.js b/help3/xhpeditor/cm/src/input/ContentEditableInput.js
index f5df0eb..4845a4e 100644
--- a/help3/xhpeditor/cm/src/input/ContentEditableInput.js
+++ b/help3/xhpeditor/cm/src/input/ContentEditableInput.js
@@ -226,7 +226,7 @@ export default class ContentEditableInput {
receivedFocus() {
let input = this
if (this.selectionInEditor())
- this.pollSelection()
+ setTimeout(() => this.pollSelection(), 20)
else
runInOp(this.cm, () => input.cm.curOp.selectionChanged = true)
diff --git a/help3/xhpeditor/cm/src/input/input.js b/help3/xhpeditor/cm/src/input/input.js
index 32adbf9..288937b 100644
--- a/help3/xhpeditor/cm/src/input/input.js
+++ b/help3/xhpeditor/cm/src/input/input.js
@@ -120,7 +120,7 @@ export function disableBrowserMagic(field, spellcheck, autocorrect, autocapitali
}
export function hiddenTextarea() {
- let te = elt("textarea", null, null, "position: absolute; bottom: -1em; padding: 0; width: 1px; height: 1em; outline: none")
+ let te = elt("textarea", null, null, "position: absolute; bottom: -1em; padding: 0; width: 1px; height: 1em; min-height: 1em; outline: none")
let div = elt("div", [te], null, "overflow: hidden; position: relative; width: 3px; height: 0px;")
// The textarea is kept positioned near the cursor to prevent the
// fact that it'll be scrolled into view on input from scrolling
diff --git a/help3/xhpeditor/cm/src/measurement/position_measurement.js b/help3/xhpeditor/cm/src/measurement/position_measurement.js
index bb0ad50..2766fb7 100644
--- a/help3/xhpeditor/cm/src/measurement/position_measurement.js
+++ b/help3/xhpeditor/cm/src/measurement/position_measurement.js
@@ -61,12 +61,14 @@ function ensureLineHeights(cm, lineView, rect) {
export function mapFromLineView(lineView, line, lineN) {
if (lineView.line == line)
return {map: lineView.measure.map, cache: lineView.measure.cache}
- for (let i = 0; i < lineView.rest.length; i++)
- if (lineView.rest[i] == line)
- return {map: lineView.measure.maps[i], cache: lineView.measure.caches[i]}
- for (let i = 0; i < lineView.rest.length; i++)
- if (lineNo(lineView.rest[i]) > lineN)
- return {map: lineView.measure.maps[i], cache: lineView.measure.caches[i], before: true}
+ if (lineView.rest) {
+ for (let i = 0; i < lineView.rest.length; i++)
+ if (lineView.rest[i] == line)
+ return {map: lineView.measure.maps[i], cache: lineView.measure.caches[i]}
+ for (let i = 0; i < lineView.rest.length; i++)
+ if (lineNo(lineView.rest[i]) > lineN)
+ return {map: lineView.measure.maps[i], cache: lineView.measure.caches[i], before: true}
+ }
}
// Render a line into the hidden node display.externalMeasured. Used
@@ -293,9 +295,9 @@ function pageScrollY() {
}
function widgetTopHeight(lineObj) {
- let height = 0
- if (lineObj.widgets) for (let i = 0; i < lineObj.widgets.length; ++i) if (lineObj.widgets[i].above)
- height += widgetHeight(lineObj.widgets[i])
+ let {widgets} = visualLine(lineObj), height = 0
+ if (widgets) for (let i = 0; i < widgets.length; ++i) if (widgets[i].above)
+ height += widgetHeight(widgets[i])
return height
}
diff --git a/help3/xhpeditor/cm/src/model/Doc.js b/help3/xhpeditor/cm/src/model/Doc.js
index 8a2082a..3d2f7d2 100644
--- a/help3/xhpeditor/cm/src/model/Doc.js
+++ b/help3/xhpeditor/cm/src/model/Doc.js
@@ -86,6 +86,7 @@ Doc.prototype = createObj(BranchChunk.prototype, {
getRange: function(from, to, lineSep) {
let lines = getBetween(this, clipPos(this, from), clipPos(this, to))
if (lineSep === false) return lines
+ if (lineSep === '') return lines.join('')
return lines.join(lineSep || this.lineSeparator())
},
diff --git a/help3/xhpeditor/cm/test/test.js b/help3/xhpeditor/cm/test/test.js
index 07fa678..357c2b9 100644
--- a/help3/xhpeditor/cm/test/test.js
+++ b/help3/xhpeditor/cm/test/test.js
@@ -2672,3 +2672,7 @@ testCM("mode_lookahead", function(cm) {
eq(cm.getTokenAt(Pos(0, 1)).type, null)
eq(cm.getTokenAt(Pos(1, 1)).type, "atom")
}, {value: "foo\na\nx\nx\n", mode: "lookahead_mode"})
+
+testCM("should have translate=no attribute", function(cm) {
+ eq(cm.getWrapperElement().getAttribute("translate"), "no")
+}, {})
diff --git a/help3/xhpeditor/cm/test/vim_test.js b/help3/xhpeditor/cm/test/vim_test.js
index 20eabf5..7822d62 100644
--- a/help3/xhpeditor/cm/test/vim_test.js
+++ b/help3/xhpeditor/cm/test/vim_test.js
@@ -19,7 +19,7 @@ var code = '' +
'}\n';
var lines = (function() {
- lineText = code.split('\n');
+ var lineText = code.split('\n');
var ret = [];
for (var i = 0; i < lineText.length; i++) {
ret[i] = {
@@ -124,6 +124,12 @@ function expectFail(fn) {
throw new Error("Expected to throw an error");
}
+function vimKeyToKeyName(key) {
+ return key.replace(/[CS]-|CR|BS/g, function(part) {
+ return {"C-": "Ctrl-", "S-": "Shift", CR: "Return", BS: "Backspace"}[part];
+ });
+}
+
function testVim(name, run, opts, expectedFail) {
var vimOpts = {
lineNumbers: true,
@@ -138,51 +144,35 @@ function testVim(name, run, opts, expectedFail) {
}
return test('vim_' + name, function() {
var place = document.getElementById("testground");
+ place.style.visibility = "visible";
var cm = CodeMirror(place, vimOpts);
var vim = CodeMirror.Vim.maybeInitVimState_(cm);
- function doKeysFn(cm) {
- return function(args) {
- if (args instanceof Array) {
- arguments = args;
+ cm.focus();
+ // workaround for cm5 slow polling in blurred window
+ Object.defineProperty(cm.state, "focused", {
+ set: function(e) {},
+ get: function() {
+ return document.activeElement == cm.getInputField();
}
- for (var i = 0; i < arguments.length; i++) {
- var result = CodeMirror.Vim.handleKey(cm, arguments[i]);
- if (!result && cm.state.vim.insertMode) {
- cm.replaceSelections(fillArray(arguments[i], cm.listSelections().length));
- }
- }
- }
- }
- function doInsertModeKeysFn(cm) {
- return function(args) {
- if (args instanceof Array) { arguments = args; }
- function executeHandler(handler) {
- if (typeof handler == 'string') {
- CodeMirror.commands[handler](cm);
- } else {
- handler(cm);
- }
- return true;
- }
- for (var i = 0; i < arguments.length; i++) {
- var key = arguments[i];
- // Find key in keymap and handle.
- var handled = CodeMirror.lookupKey(key, cm.getOption('keyMap'), executeHandler, cm);
- // Record for insert mode.
- if (handled == "handled" && cm.state.vim.insertMode && arguments[i] != 'Esc') {
- var lastChange = CodeMirror.Vim.getVimGlobalState_().macroModeState.lastInsertModeChanges;
- if (lastChange && (key.indexOf('Delete') != -1 || key.indexOf('Backspace') != -1)) {
- lastChange.changes.push(new CodeMirror.Vim.InsertModeKey(key));
- }
+ });
+
+ function doKeysFn(cm) {
+ return function() {
+ var args = arguments[0]
+ if (!Array.isArray(args)) { args = arguments; }
+ for (var i = 0; i < args.length; i++) {
+ var key = args[i];
+ if (key.length > 1 && key[0] == "<" && key.slice(-1) == ">") {
+ key = vimKeyToKeyName(key.slice(1, -1));
}
+ typeKey(key);
}
}
}
function doExFn(cm) {
return function(command) {
- cm.openDialog = helpers.fakeOpenDialog(command);
- helpers.doKeys(':');
+ helpers.doKeys(':', command, '\n');
}
}
function assertCursorAtFn(cm) {
@@ -196,44 +186,25 @@ function testVim(name, run, opts, expectedFail) {
eqCursorPos(cm.getCursor(), pos);
}
}
- function fakeOpenDialog(result) {
- return function(template, callback) {
- return callback(result);
- }
- }
- function fakeOpenNotification(matcher) {
- return function(template) {
- matcher(template.innerHTML);
- }
- }
var helpers = {
doKeys: doKeysFn(cm),
- // Warning: Only emulates keymap events, not character insertions. Use
- // replaceRange to simulate character insertions.
- // Keys are in CodeMirror format, NOT vim format.
- doInsertModeKeys: doInsertModeKeysFn(cm),
doEx: doExFn(cm),
assertCursorAt: assertCursorAtFn(cm),
- fakeOpenDialog: fakeOpenDialog,
- fakeOpenNotification: fakeOpenNotification,
getRegisterController: function() {
return CodeMirror.Vim.getRegisterController();
+ },
+ getNotificationText: function() {
+ return cm.getWrapperElement().querySelector(".cm-vim-message").textContent;
}
}
CodeMirror.Vim.resetVimGlobalState_();
var successful = false;
- var savedOpenNotification = cm.openNotification;
- var savedOpenDialog = cm.openDialog;
try {
run(cm, vim, helpers);
successful = true;
} finally {
- cm.openNotification = savedOpenNotification;
- cm.openDialog = savedOpenDialog;
- if (!successful || verbose) {
- place.style.visibility = "visible";
- } else {
- place.removeChild(cm.getWrapperElement());
+ if (successful && !verbose) {
+ cm.getWrapperElement().remove();
}
}
}, expectedFail);
@@ -264,12 +235,11 @@ var jumplistScene = ''+
'}word\n'+
'word\n'+
'word\n';
-function testJumplist(name, keys, endPos, startPos, dialog) {
+function testJumplist(name, keys, endPos, startPos) {
endPos = makeCursor(endPos[0], endPos[1]);
startPos = makeCursor(startPos[0], startPos[1]);
testVim(name, function(cm, vim, helpers) {
CodeMirror.Vim.resetVimGlobalState_();
- if(dialog)cm.openDialog = helpers.fakeOpenDialog('word');
cm.setCursor(startPos);
helpers.doKeys.apply(null, keys);
helpers.assertCursorAt(endPos);
@@ -294,8 +264,8 @@ testJumplist('jumplist_N', ['#', 'N', '<C-o>'], [1,1], [2,3]);
testJumplist('jumplist_repeat_<c-o>', ['*', '*', '*', '3', '<C-o>'], [2,3], [2,3]);
testJumplist('jumplist_repeat_<c-i>', ['*', '*', '*', '3', '<C-o>', '2', '<C-i>'], [5,0], [2,3]);
testJumplist('jumplist_repeated_motion', ['3', '*', '<C-o>'], [2,3], [2,3]);
-testJumplist('jumplist_/', ['/', '<C-o>'], [2,3], [2,3], 'dialog');
-testJumplist('jumplist_?', ['?', '<C-o>'], [2,3], [2,3], 'dialog');
+testJumplist('jumplist_/', ['/', 'dialog\n', '<C-o>'], [2,3], [2,3]);
+testJumplist('jumplist_?', ['?', 'dialog\n', '<C-o>'], [2,3], [2,3]);
testJumplist('jumplist_skip_deleted_mark<c-o>',
['*', 'n', 'n', 'k', 'd', 'k', '<C-o>', '<C-o>', '<C-o>'],
[0,2], [0,2]);
@@ -518,11 +488,35 @@ testVim('gj_gk', function(cm, vim, helpers) {
// Test bottom of document edge case.
helpers.doKeys('100', 'g', 'j');
var endingPos = cm.getCursor();
- is(endingPos != 0, 'gj should not be on wrapped line 0');
+ is(endingPos.ch != 0, 'gj should not be on wrapped line 0');
var topLeftCharCoords = cm.charCoords(makeCursor(0, 0));
var endingCharCoords = cm.charCoords(endingPos);
is(topLeftCharCoords.left == endingCharCoords.left, 'gj should end up on column 0');
},{ lineNumbers: false, lineWrapping:true, value: 'Thislineisintentionallylongtotestmovementofgjandgkoverwrappedlines.' });
+testVim('g0_g$', function(cm, vim, helpers) {
+ var topLeftCharCoords = cm.charCoords(makeCursor(0, 0));
+ cm.setCursor(0, 4);
+ cm.setSize(120);
+ helpers.doKeys('g', 'Down');
+ var secondLineCoords = cm.charCoords(cm.getCursor());
+ is(secondLineCoords.top > topLeftCharCoords.top);
+ is(secondLineCoords.left > topLeftCharCoords.left);
+
+ helpers.doKeys('g', '0');
+ var start = cm.getCursor();
+ var startCoords = cm.charCoords(start);
+ is(start.ch != 0);
+ is(startCoords.left == topLeftCharCoords.left);
+ is(secondLineCoords.top === startCoords.top);
+ is(secondLineCoords.left > startCoords.left);
+
+ helpers.doKeys('g', '$');
+ var end = cm.getCursor();
+ var endCoords = cm.charCoords(end);
+ is(startCoords.left < endCoords.left);
+ is(startCoords.top == endCoords.top);
+ is(start.ch < end.ch && end.ch < cm.getValue().length / 2);
+},{ lineNumbers: false, lineWrapping:true, value: 'This line is intentionally long to test movement of g$ and g0 over wrapped lines.' });
testVim('}', function(cm, vim, helpers) {
cm.setCursor(0, 0);
helpers.doKeys('}');
@@ -601,14 +595,14 @@ testVim('paragraph_motions', function(cm, vim, helpers) {
// ip inside empty space
cm.setCursor(10, 0);
helpers.doKeys('v', 'i', 'p');
- eqCursorPos(Pos(7, 0), cm.getCursor('anchor'));
- eqCursorPos(Pos(12, 0), cm.getCursor('head'));
+ eqCursorPos(new Pos(7, 0), cm.getCursor('anchor'));
+ eqCursorPos(new Pos(12, 0), cm.getCursor('head'));
helpers.doKeys('i', 'p');
- eqCursorPos(Pos(7, 0), cm.getCursor('anchor'));
- eqCursorPos(Pos(13, 1), cm.getCursor('head'));
+ eqCursorPos(new Pos(7, 0), cm.getCursor('anchor'));
+ eqCursorPos(new Pos(13, 1), cm.getCursor('head'));
helpers.doKeys('2', 'i', 'p');
- eqCursorPos(Pos(7, 0), cm.getCursor('anchor'));
- eqCursorPos(Pos(16, 1), cm.getCursor('head'));
+ eqCursorPos(new Pos(7, 0), cm.getCursor('anchor'));
+ eqCursorPos(new Pos(16, 1), cm.getCursor('head'));
// should switch to visualLine mode
cm.setCursor(14, 0);
@@ -617,31 +611,31 @@ testVim('paragraph_motions', function(cm, vim, helpers) {
cm.setCursor(14, 0);
helpers.doKeys('<Esc>', 'V', 'i', 'p');
- eqCursorPos(Pos(16, 1), cm.getCursor('head'));
+ eqCursorPos(new Pos(16, 1), cm.getCursor('head'));
// ap inside empty space
cm.setCursor(10, 0);
helpers.doKeys('<Esc>', 'v', 'a', 'p');
- eqCursorPos(Pos(7, 0), cm.getCursor('anchor'));
- eqCursorPos(Pos(13, 1), cm.getCursor('head'));
+ eqCursorPos(new Pos(7, 0), cm.getCursor('anchor'));
+ eqCursorPos(new Pos(13, 1), cm.getCursor('head'));
helpers.doKeys('a', 'p');
- eqCursorPos(Pos(7, 0), cm.getCursor('anchor'));
- eqCursorPos(Pos(16, 1), cm.getCursor('head'));
+ eqCursorPos(new Pos(7, 0), cm.getCursor('anchor'));
+ eqCursorPos(new Pos(16, 1), cm.getCursor('head'));
cm.setCursor(13, 0);
helpers.doKeys('v', 'a', 'p');
- eqCursorPos(Pos(13, 0), cm.getCursor('anchor'));
- eqCursorPos(Pos(14, 0), cm.getCursor('head'));
+ eqCursorPos(new Pos(13, 0), cm.getCursor('anchor'));
+ eqCursorPos(new Pos(14, 0), cm.getCursor('head'));
cm.setCursor(16, 0);
helpers.doKeys('v', 'a', 'p');
- eqCursorPos(Pos(14, 0), cm.getCursor('anchor'));
- eqCursorPos(Pos(16, 1), cm.getCursor('head'));
+ eqCursorPos(new Pos(14, 0), cm.getCursor('anchor'));
+ eqCursorPos(new Pos(16, 1), cm.getCursor('head'));
cm.setCursor(0, 0);
helpers.doKeys('v', 'a', 'p');
- eqCursorPos(Pos(0, 0), cm.getCursor('anchor'));
- eqCursorPos(Pos(4, 0), cm.getCursor('head'));
+ eqCursorPos(new Pos(0, 0), cm.getCursor('anchor'));
+ eqCursorPos(new Pos(4, 0), cm.getCursor('head'));
cm.setCursor(0, 0);
helpers.doKeys('d', 'i', 'p');
@@ -998,6 +992,12 @@ testVim('dd_only_line', function(cm, vim, helpers) {
var register = helpers.getRegisterController().getRegister();
eq(expectedRegister, register.toString());
}, { value: "thisistheonlyline" });
+testVim('cG', function(cm, vim, helpers) {
+ cm.setCursor(0, 0);
+ helpers.doKeys('c', 'G', 'inserted');
+ eq('inserted\n', cm.getValue());
+ helpers.assertCursorAt(0, 8);
+}, { value: 'line1\nline2'});
// Yank commands should behave the exact same as d commands, expect that nothing
// gets deleted.
testVim('yw_repeat', function(cm, vim, helpers) {
@@ -1130,6 +1130,23 @@ testVim('I_visual_block_replay', function(cm, vim, helpers) {
eq('12+-34\n5+-6+-78\na+-b+-cdefg\nx+-yz', cm.getValue());
}, {value: '1234\n5678\nabcdefg\nxyz'});
+testVim('visual_block_backwards', function(cm, vim, helpers) {
+ cm.setCursor(0, 0);
+ helpers.doKeys('3', 'l');
+ helpers.doKeys('<C-v>', '2', 'j', '2', '<Left>');
+ eq('123\n678\nbcd', cm.getSelection());
+ helpers.doKeys('A');
+ helpers.assertCursorAt(0, 4);
+ helpers.doKeys('A', '<Esc>');
+ helpers.assertCursorAt(0, 4);
+ helpers.doKeys('g', 'v');
+ eq('123\n678\nbcd', cm.getSelection());
+ helpers.doKeys('x');
+ helpers.assertCursorAt(0, 1);
+ helpers.doKeys('g', 'v');
+ eq('A4 \nA9 \nAef', cm.getSelection());
+}, {value: '01234 line 1\n56789 line 2\nabcdefg line 3\nline 4'});
+
testVim('d_visual_block', function(cm, vim, helpers) {
cm.setCursor(0, 1);
helpers.doKeys('<C-v>', '2', 'j', 'l', 'l', 'l', 'd');
@@ -1185,7 +1202,7 @@ testVim('on_mode_change', function(cm, vim, helpers) {
test('<Esc>', 'normal');
test('v', 'visual');
test(':', ''); // Event for Command-line mode not implemented.
- test('y', 'normal');
+ test('y\n', 'normal');
});
// Swapcase commands edit in place and do not modify registers.
@@ -1232,12 +1249,19 @@ testVim('gu_and_gU', function(cm, vim, helpers) {
eq(cm.getValue(), 'wa wb Xx wc wd');
eqCursorPos(makeCursor(0, 3), cm.getCursor());
- // TODO: support gUgU guu
- // eqCursorPos(makeCursor(0, 0), cm.getCursor());
-
var register = helpers.getRegisterController().getRegister();
eq('', register.toString());
is(!register.linewise);
+
+ cm.setCursor(curStart);
+ cm.setValue('abc efg\nxyz');
+ helpers.doKeys('g', 'U', 'g', 'U');
+ eq(cm.getValue(), 'ABC EFG\nxyz');
+ helpers.doKeys('g', 'u', 'u');
+ eq(cm.getValue(), 'abc efg\nxyz');
+ eqCursorPos(makeCursor(0, 0), cm.getCursor());
+ helpers.doKeys('g', 'U', '2', 'U');
+ eq(cm.getValue(), 'ABC EFG\nXYZ');
}, { value: 'wa wb xx wc wd' });
testVim('visual_block_~', function(cm, vim, helpers) {
cm.setCursor(1, 1);
@@ -1473,7 +1497,7 @@ testSelection('vi{_middle_spc', 'a{\n\tbar\n\t}b', /r/, 'vi{', '\n\tbar\n\t');
testSelection('va{_middle_spc', 'a{\n\tbar\n\t}b', /r/, 'va{', '{\n\tbar\n\t}');
testVim('mouse_select', function(cm, vim, helpers) {
- cm.setSelection(Pos(0, 2), Pos(0, 4), {origin: '*mouse'});
+ cm.setSelection(new Pos(0, 2), new Pos(0, 4), {origin: '*mouse'});
is(cm.state.vim.visualMode);
is(!cm.state.vim.visualLine);
is(!cm.state.vim.visualBlock);
@@ -1565,6 +1589,19 @@ testVim('<C-x>/<C-a> search forward', function(cm, vim, helpers) {
helpers.assertCursorAt(0, 11);
});
}, {value: '__jmp1 jmp2 jmp'});
+testVim('insert_ctrl_u', function(cm, vim, helpers) {
+ var curStart = makeCursor(0, 10);
+ cm.setCursor(curStart);
+ helpers.doKeys('a');
+ helpers.doKeys('<C-u>');
+ eq('', cm.getValue());
+ var register = helpers.getRegisterController().getRegister();
+ eq('word1/word2', register.toString());
+ is(!register.linewise);
+ var curEnd = makeCursor(0, 0);
+ eqCursorPos(curEnd, cm.getCursor());
+ eq('vim-insert', cm.getOption('keyMap'));
+}, { value: 'word1/word2' });
testVim('insert_ctrl_w', function(cm, vim, helpers) {
var curStart = makeCursor(0, 10);
cm.setCursor(curStart);
@@ -1624,7 +1661,7 @@ testVim('i_repeat_delete', function(cm, vim, helpers) {
cm.setCursor(0, 4);
helpers.doKeys('2', 'i');
helpers.doKeys('z')
- helpers.doInsertModeKeys('Backspace', 'Backspace');
+ helpers.doKeys('Backspace', 'Backspace');
helpers.doKeys('<Esc>');
eq('abe', cm.getValue());
helpers.assertCursorAt(0, 1);
@@ -1643,7 +1680,7 @@ testVim('insert', function(cm, vim, helpers) {
testVim('i_backspace', function(cm, vim, helpers) {
cm.setCursor(0, 10);
helpers.doKeys('i');
- helpers.doInsertModeKeys('Backspace');
+ helpers.doKeys('Backspace');
helpers.assertCursorAt(0, 9);
eq('012345678', cm.getValue());
}, { value: '0123456789'});
@@ -1651,20 +1688,20 @@ testVim('i_overwrite_backspace', function(cm, vim, helpers) {
cm.setCursor(0, 10);
helpers.doKeys('i');
helpers.doKeys('<Ins>');
- helpers.doInsertModeKeys('Backspace');
- helpers.assertCursorAt(Pos(0, 9, "after"));
+ helpers.doKeys('Backspace');
+ helpers.assertCursorAt(new Pos(0, 9, "after"));
eq('0123456789', cm.getValue());
}, { value: '0123456789'});
testVim('i_forward_delete', function(cm, vim, helpers) {
cm.setCursor(0, 3);
helpers.doKeys('i');
- helpers.doInsertModeKeys('Delete');
+ helpers.doKeys('Delete');
helpers.assertCursorAt(0, 3);
eq('A124\nBCD', cm.getValue());
- helpers.doInsertModeKeys('Delete');
+ helpers.doKeys('Delete');
helpers.assertCursorAt(0, 3);
eq('A12\nBCD', cm.getValue());
- helpers.doInsertModeKeys('Delete');
+ helpers.doKeys('Delete');
helpers.assertCursorAt(0, 3);
eq('A12BCD', cm.getValue());
}, { value: 'A1234\nBCD'});
@@ -1916,8 +1953,7 @@ testVim('mark\'', function(cm, vim, helpers) {
helpers.doKeys('`', '`');
helpers.assertCursorAt(1, 3);
// motions that update jumplist
- cm.openDialog = helpers.fakeOpenDialog('=');
- helpers.doKeys('/');
+ helpers.doKeys('/', '=', '\n');
helpers.assertCursorAt(6, 20);
helpers.doKeys('`', '`');
helpers.assertCursorAt(1, 3);
@@ -2213,20 +2249,20 @@ testVim('visual_crossover_left', function(cm, vim, helpers) {
testVim('visual_crossover_up', function(cm, vim, helpers) {
cm.setCursor(3, 2);
helpers.doKeys('v', 'j', 'k', 'k');
- eqCursorPos(Pos(2, 2), cm.getCursor('head'));
- eqCursorPos(Pos(3, 3), cm.getCursor('anchor'));
+ eqCursorPos(new Pos(2, 2), cm.getCursor('head'));
+ eqCursorPos(new Pos(3, 3), cm.getCursor('anchor'));
helpers.doKeys('k');
- eqCursorPos(Pos(1, 2), cm.getCursor('head'));
- eqCursorPos(Pos(3, 3), cm.getCursor('anchor'));
+ eqCursorPos(new Pos(1, 2), cm.getCursor('head'));
+ eqCursorPos(new Pos(3, 3), cm.getCursor('anchor'));
}, { value: 'cross\ncross\ncross\ncross\ncross\n'});
testVim('visual_crossover_down', function(cm, vim, helpers) {
cm.setCursor(1, 2);
helpers.doKeys('v', 'k', 'j', 'j');
- eqCursorPos(Pos(2, 3), cm.getCursor('head'));
- eqCursorPos(Pos(1, 2), cm.getCursor('anchor'));
+ eqCursorPos(new Pos(2, 3), cm.getCursor('head'));
+ eqCursorPos(new Pos(1, 2), cm.getCursor('anchor'));
helpers.doKeys('j');
- eqCursorPos(Pos(3, 3), cm.getCursor('head'));
- eqCursorPos(Pos(1, 2), cm.getCursor('anchor'));
+ eqCursorPos(new Pos(3, 3), cm.getCursor('head'));
+ eqCursorPos(new Pos(1, 2), cm.getCursor('anchor'));
}, { value: 'cross\ncross\ncross\ncross\ncross\n'});
testVim('visual_exit', function(cm, vim, helpers) {
helpers.doKeys('<C-v>', 'l', 'j', 'j', '<Esc>');
@@ -2381,14 +2417,14 @@ testVim('reselect_visual_block', function(cm, vim, helpers) {
helpers.doKeys('<C-v>', 'k', 'h', '<C-v>');
cm.setCursor(2, 1);
helpers.doKeys('v', 'l', 'g', 'v');
- eqCursorPos(Pos(1, 2), vim.sel.anchor);
- eqCursorPos(Pos(0, 1), vim.sel.head);
+ eqCursorPos(new Pos(1, 2), vim.sel.anchor);
+ eqCursorPos(new Pos(0, 1), vim.sel.head);
// Ensure selection is done with visual block mode rather than one
// continuous range.
eq(cm.getSelections().join(''), '23oo')
helpers.doKeys('g', 'v');
- eqCursorPos(Pos(2, 1), vim.sel.anchor);
- eqCursorPos(Pos(2, 2), vim.sel.head);
+ eqCursorPos(new Pos(2, 1), vim.sel.anchor);
+ eqCursorPos(new Pos(2, 2), vim.sel.head);
helpers.doKeys('<Esc>');
// Ensure selection of deleted range
cm.setCursor(1, 1);
@@ -2423,14 +2459,14 @@ testVim('o_visual', function(cm, vim, helpers) {
testVim('o_visual_block', function(cm, vim, helpers) {
cm.setCursor(0, 1);
helpers.doKeys('<C-v>','3','j','l','l', 'o');
- eqCursorPos(Pos(3, 3), vim.sel.anchor);
- eqCursorPos(Pos(0, 1), vim.sel.head);
+ eqCursorPos(new Pos(3, 3), vim.sel.anchor);
+ eqCursorPos(new Pos(0, 1), vim.sel.head);
helpers.doKeys('O');
- eqCursorPos(Pos(3, 1), vim.sel.anchor);
- eqCursorPos(Pos(0, 3), vim.sel.head);
+ eqCursorPos(new Pos(3, 1), vim.sel.anchor);
+ eqCursorPos(new Pos(0, 3), vim.sel.head);
helpers.doKeys('o');
- eqCursorPos(Pos(0, 3), vim.sel.anchor);
- eqCursorPos(Pos(3, 1), vim.sel.head);
+ eqCursorPos(new Pos(0, 3), vim.sel.anchor);
+ eqCursorPos(new Pos(3, 1), vim.sel.head);
}, { value: 'abcd\nefgh\nijkl\nmnop'});
testVim('changeCase_visual', function(cm, vim, helpers) {
cm.setCursor(0, 0);
@@ -2485,10 +2521,8 @@ testVim('v_paste_from_register', function(cm, vim, helpers) {
helpers.doKeys('"', 'a', 'y', 'w');
cm.setCursor(1, 0);
helpers.doKeys('v', 'p');
- cm.openDialog = helpers.fakeOpenDialog('registers');
- cm.openNotification = helpers.fakeOpenNotification(function(text) {
- is(/a\s+register/.test(text));
- });
+ helpers.doEx('registers');
+ is(/a\s+register/.test(helpers.getNotificationText()));
}, { value: 'register contents\nare not erased'});
testVim('S_normal', function(cm, vim, helpers) {
cm.setCursor(0, 1);
@@ -2558,17 +2592,14 @@ testVim('S_visual', function(cm, vim, helpers) {
}, { value: 'aa\nbb\ncc'});
testVim('d_/', function(cm, vim, helpers) {
- cm.openDialog = helpers.fakeOpenDialog('match');
- helpers.doKeys('2', 'd', '/');
+ helpers.doKeys('2', 'd', '/', 'match', '\n');
helpers.assertCursorAt(0, 0);
eq('match \n next', cm.getValue());
- cm.openDialog = helpers.fakeOpenDialog('2');
- helpers.doKeys('d', ':');
+ helpers.doKeys('d', ':', '2', '\n');
// TODO eq(' next', cm.getValue());
}, { value: 'text match match \n next' });
testVim('/ and n/N', function(cm, vim, helpers) {
- cm.openDialog = helpers.fakeOpenDialog('match');
- helpers.doKeys('/');
+ helpers.doKeys('/', 'match', '\n');
helpers.assertCursorAt(0, 11);
helpers.doKeys('n');
helpers.assertCursorAt(1, 6);
@@ -2576,12 +2607,11 @@ testVim('/ and n/N', function(cm, vim, helpers) {
helpers.assertCursorAt(0, 11);
cm.setCursor(0, 0);
- helpers.doKeys('2', '/');
+ helpers.doKeys('2', '/', 'match', '\n');
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.doKeys('/', 'match', '\n');
helpers.assertCursorAt(0, 11);
// gn should highlight the the current word while it is within a match.
@@ -2606,8 +2636,7 @@ testVim('/ and gn selects the appropriate word', function(cm, vim, helpers) {
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.doKeys('/', 'match', '\n');
helpers.assertCursorAt(0, 11);
// gN when cursor is at beginning of match
@@ -2629,8 +2658,7 @@ testVim('/ and gN selects the appropriate word', function(cm, vim, helpers) {
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.doKeys('/', 'match', '\n');
helpers.assertCursorAt(0, 11);
helpers.doKeys('c', 'gn', 'changed', '<Esc>');
@@ -2647,8 +2675,7 @@ testVim('/ and gn with an associated operator', function(cm, vim, helpers) {
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.doKeys('/', 'match', '\n');
helpers.assertCursorAt(0, 11);
helpers.doKeys('c', 'gN', 'changed', '<Esc>');
@@ -2665,29 +2692,25 @@ testVim('/ and gN with an associated operator', function(cm, vim, helpers) {
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('/');
+ helpers.doKeys('/', 'Match', '\n');
helpers.assertCursorAt(1, 6);
}, { value: 'match nope match \n nope Match' });
testVim('/_2_pcre', function(cm, vim, helpers) {
CodeMirror.Vim.setOption('pcre', true);
- cm.openDialog = helpers.fakeOpenDialog('(word){2}');
- helpers.doKeys('/');
+ helpers.doKeys('/', '(word){2}', '\n');
helpers.assertCursorAt(1, 9);
helpers.doKeys('n');
helpers.assertCursorAt(2, 1);
}, { value: 'word\n another wordword\n wordwordword\n' });
testVim('/_2_nopcre', function(cm, vim, helpers) {
CodeMirror.Vim.setOption('pcre', false);
- cm.openDialog = helpers.fakeOpenDialog('\\(word\\)\\{2}');
- helpers.doKeys('/');
+ helpers.doKeys('/', '\\(word\\)\\{2}', '\n');
helpers.assertCursorAt(1, 9);
helpers.doKeys('n');
helpers.assertCursorAt(2, 1);
}, { value: 'word\n another wordword\n wordwordword\n' });
testVim('/_nongreedy', function(cm, vim, helpers) {
- cm.openDialog = helpers.fakeOpenDialog('aa');
- helpers.doKeys('/');
+ helpers.doKeys('/', 'aa', '\n');
helpers.assertCursorAt(0, 4);
helpers.doKeys('n');
helpers.assertCursorAt(1, 3);
@@ -2695,8 +2718,7 @@ testVim('/_nongreedy', function(cm, vim, helpers) {
helpers.assertCursorAt(0, 0);
}, { value: 'aaa aa \n a aa'});
testVim('?_nongreedy', function(cm, vim, helpers) {
- cm.openDialog = helpers.fakeOpenDialog('aa');
- helpers.doKeys('?');
+ helpers.doKeys('?', 'aa', '\n');
helpers.assertCursorAt(1, 3);
helpers.doKeys('n');
helpers.assertCursorAt(0, 4);
@@ -2704,8 +2726,7 @@ testVim('?_nongreedy', function(cm, vim, helpers) {
helpers.assertCursorAt(0, 1);
}, { value: 'aaa aa \n a aa'});
testVim('/_greedy', function(cm, vim, helpers) {
- cm.openDialog = helpers.fakeOpenDialog('a+');
- helpers.doKeys('/');
+ helpers.doKeys('/', 'a+', '\n');
helpers.assertCursorAt(0, 4);
helpers.doKeys('n');
helpers.assertCursorAt(1, 1);
@@ -2715,8 +2736,7 @@ testVim('/_greedy', function(cm, vim, helpers) {
helpers.assertCursorAt(0, 0);
}, { value: 'aaa aa \n a aa'});
testVim('?_greedy', function(cm, vim, helpers) {
- cm.openDialog = helpers.fakeOpenDialog('a+');
- helpers.doKeys('?');
+ helpers.doKeys('?', 'a+', '\n');
helpers.assertCursorAt(1, 3);
helpers.doKeys('n');
helpers.assertCursorAt(1, 1);
@@ -2726,8 +2746,7 @@ testVim('?_greedy', function(cm, vim, helpers) {
helpers.assertCursorAt(0, 0);
}, { value: 'aaa aa \n a aa'});
testVim('/_greedy_0_or_more', function(cm, vim, helpers) {
- cm.openDialog = helpers.fakeOpenDialog('a*');
- helpers.doKeys('/');
+ helpers.doKeys('/', 'a*', '\n');
helpers.assertCursorAt(0, 3);
helpers.doKeys('n');
helpers.assertCursorAt(0, 4);
@@ -2741,19 +2760,19 @@ testVim('/_greedy_0_or_more', function(cm, vim, helpers) {
helpers.assertCursorAt(0, 0);
}, { value: 'aaa aa\n aa'});
testVim('?_greedy_0_or_more', function(cm, vim, helpers) {
- cm.openDialog = helpers.fakeOpenDialog('a*');
- helpers.doKeys('?');
+ helpers.doKeys('?', 'a*', '\n');
helpers.assertCursorAt(1, 1);
helpers.doKeys('n');
+ helpers.assertCursorAt(1, 0);
+ helpers.doKeys('n');
helpers.assertCursorAt(0, 5);
helpers.doKeys('n');
- helpers.assertCursorAt(0, 3);
+ helpers.assertCursorAt(0, 4);
helpers.doKeys('n');
helpers.assertCursorAt(0, 0);
}, { value: 'aaa aa\n aa'});
testVim('? and n/N', function(cm, vim, helpers) {
- cm.openDialog = helpers.fakeOpenDialog('match');
- helpers.doKeys('?');
+ helpers.doKeys('?', 'match', '\n');
helpers.assertCursorAt(1, 6);
helpers.doKeys('n');
helpers.assertCursorAt(0, 11);
@@ -2761,12 +2780,11 @@ testVim('? and n/N', function(cm, vim, helpers) {
helpers.assertCursorAt(1, 6);
cm.setCursor(0, 0);
- helpers.doKeys('2', '?');
+ helpers.doKeys('2', '?', 'match', '\n');
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.doKeys('?', 'match', '\n', 'n');
helpers.assertCursorAt(0, 11);
// gn should highlight the the current word while it is within a match.
@@ -2790,8 +2808,7 @@ testVim('? and gn selects the appropriate word', function(cm, vim, helpers) {
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.doKeys('?', 'match', '\n', 'n');
helpers.assertCursorAt(0, 11);
// gN when cursor is at beginning of match
@@ -2813,8 +2830,7 @@ testVim('? and gN selects the appropriate word', function(cm, vim, helpers) {
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.doKeys('?', 'match', '\n', 'n');
helpers.assertCursorAt(0, 11);
helpers.doKeys('c', 'gn', 'changed', '<Esc>');
@@ -2831,8 +2847,7 @@ testVim('? and gn with an associated operator', function(cm, vim, helpers) {
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.doKeys('?', 'match', '\n', 'n');
helpers.assertCursorAt(0, 11);
helpers.doKeys('c', 'gN', 'changed', '<Esc>');
@@ -2962,8 +2977,7 @@ testVim('macro_f_search', function(cm, vim, helpers) {
testVim('macro_slash_search', function(cm, vim, helpers) {
cm.setCursor(0, 0);
helpers.doKeys('q', 'c');
- cm.openDialog = helpers.fakeOpenDialog('e');
- helpers.doKeys('/', 'q');
+ helpers.doKeys('/', 'e', '\n', 'q');
helpers.assertCursorAt(0, 2);
helpers.doKeys('@', 'c');
helpers.assertCursorAt(0, 7);
@@ -2973,10 +2987,8 @@ testVim('macro_slash_search', function(cm, vim, helpers) {
testVim('macro_multislash_search', function(cm, vim, helpers) {
cm.setCursor(0, 0);
helpers.doKeys('q', 'd');
- cm.openDialog = helpers.fakeOpenDialog('e');
- helpers.doKeys('/');
- cm.openDialog = helpers.fakeOpenDialog('t');
- helpers.doKeys('/', 'q');
+ helpers.doKeys('/', 'e', '\n');
+ helpers.doKeys('/', 't', '\n', 'q');
helpers.assertCursorAt(0, 12);
helpers.doKeys('@', 'd');
helpers.assertCursorAt(0, 15);
@@ -3056,79 +3068,60 @@ testVim('yank_register', function(cm, vim, helpers) {
cm.setCursor(0, 0);
helpers.doKeys('"', 'a', 'y', 'y');
helpers.doKeys('j', '"', 'b', 'y', 'y');
- cm.openDialog = helpers.fakeOpenDialog('registers');
- cm.openNotification = helpers.fakeOpenNotification(function(text) {
- is(/a\s+foo/.test(text));
- is(/b\s+bar/.test(text));
- });
- helpers.doKeys(':');
+ helpers.doEx('registers');
+ var text = helpers.getNotificationText();
+ is(/a\s+foo/.test(text));
+ is(/b\s+bar/.test(text));
}, { value: 'foo\nbar'});
testVim('yank_visual_block', function(cm, vim, helpers) {
cm.setCursor(0, 1);
helpers.doKeys('<C-v>', 'l', 'j', '"', 'a', 'y');
- cm.openNotification = helpers.fakeOpenNotification(function(text) {
- is(/a\s+oo\nar/.test(text));
- });
- helpers.doKeys(':');
+ helpers.doEx('registers');
+ is(/a\s+oo\nar/.test(helpers.getNotificationText()));
}, { value: 'foo\nbar'});
testVim('yank_append_line_to_line_register', function(cm, vim, helpers) {
cm.setCursor(0, 0);
helpers.doKeys('"', 'a', 'y', 'y');
helpers.doKeys('j', '"', 'A', 'y', 'y');
- cm.openDialog = helpers.fakeOpenDialog('registers');
- cm.openNotification = helpers.fakeOpenNotification(function(text) {
- is(/a\s+foo\nbar/.test(text));
- is(/"\s+foo\nbar/.test(text));
- });
- helpers.doKeys(':');
+ helpers.doEx('registers');
+ var text = helpers.getNotificationText();
+ is(/a\s+foo\nbar/.test(text));
+ is(/"\s+foo\nbar/.test(text));
}, { value: 'foo\nbar'});
testVim('yank_append_word_to_word_register', function(cm, vim, helpers) {
cm.setCursor(0, 0);
helpers.doKeys('"', 'a', 'y', 'w');
helpers.doKeys('j', '"', 'A', 'y', 'w');
- cm.openDialog = helpers.fakeOpenDialog('registers');
- cm.openNotification = helpers.fakeOpenNotification(function(text) {
- is(/a\s+foobar/.test(text));
- is(/"\s+foobar/.test(text));
- });
- helpers.doKeys(':');
+ helpers.doEx('registers');
+ var text = helpers.getNotificationText();
+ is(/a\s+foobar/.test(text));
+ is(/"\s+foobar/.test(text));
}, { value: 'foo\nbar'});
testVim('yank_append_line_to_word_register', function(cm, vim, helpers) {
cm.setCursor(0, 0);
helpers.doKeys('"', 'a', 'y', 'w');
helpers.doKeys('j', '"', 'A', 'y', 'y');
- cm.openDialog = helpers.fakeOpenDialog('registers');
- cm.openNotification = helpers.fakeOpenNotification(function(text) {
- is(/a\s+foo\nbar/.test(text));
- is(/"\s+foo\nbar/.test(text));
- });
- helpers.doKeys(':');
+ helpers.doEx('registers');
+ var text = helpers.getNotificationText();
+ is(/a\s+foo\nbar/.test(text));
+ is(/"\s+foo\nbar/.test(text));
}, { value: 'foo\nbar'});
testVim('yank_append_word_to_line_register', function(cm, vim, helpers) {
cm.setCursor(0, 0);
helpers.doKeys('"', 'a', 'y', 'y');
helpers.doKeys('j', '"', 'A', 'y', 'w');
- cm.openDialog = helpers.fakeOpenDialog('registers');
- cm.openNotification = helpers.fakeOpenNotification(function(text) {
- is(/a\s+foo\nbar/.test(text));
- is(/"\s+foo\nbar/.test(text));
- });
- helpers.doKeys(':');
+ helpers.doEx('registers');
+ var text = helpers.getNotificationText();
+ is(/a\s+foo\nbar/.test(text));
+ is(/"\s+foo\nbar/.test(text));
}, { 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.doEx('registers');
+ var registersText = helpers.getNotificationText();
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.doEx('registers');
+ eq(registersText, helpers.getNotificationText(), 'One or more registers were modified');
helpers.doKeys('"', '_', 'p');
eq('', cm.getValue());
}, { value: 'foo\nbar'});
@@ -3142,197 +3135,92 @@ testVim('macro_register', function(cm, vim, helpers) {
helpers.doKeys('style')
helpers.doKeys('<Esc>');
helpers.doKeys('q');
- cm.openDialog = helpers.fakeOpenDialog('registers');
- cm.openNotification = helpers.fakeOpenNotification(function(text) {
- is(/a\s+i/.test(text));
- is(/b\s+o/.test(text));
- });
- helpers.doKeys(':');
+ helpers.doEx('registers');
+ var text = helpers.getNotificationText();
+ is(/a\s+i/.test(text));
+ is(/b\s+o/.test(text));
}, { value: ''});
testVim('._register', function(cm,vim,helpers) {
cm.setCursor(0,0);
helpers.doKeys('i');
helpers.doKeys('foo')
helpers.doKeys('<Esc>');
- cm.openDialog = helpers.fakeOpenDialog('registers');
- cm.openNotification = helpers.fakeOpenNotification(function(text) {
- is(/\.\s+foo/.test(text));
- });
- helpers.doKeys(':');
+ helpers.doEx('registers');
+ is(/\.\s+foo/.test(helpers.getNotificationText()));
}, {value: ''});
testVim(':_register', function(cm,vim,helpers) {
helpers.doEx('bar');
- cm.openDialog = helpers.fakeOpenDialog('registers');
- cm.openNotification = helpers.fakeOpenNotification(function(text) {
- is(/:\s+bar/.test(text));
- });
- helpers.doKeys(':');
+ helpers.doEx('registers');
+ is(/:\s+bar/.test(helpers.getNotificationText()));
}, {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');
+ is(/"\s+<script>throw "&amp;"<\/script>/.test(helpers.getNotificationText()));
}, {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');
- helpers.doKeys('/');
- var onKeyDown;
- var onKeyUp;
- var KEYCODES = {
- f: 70,
- o: 79,
- Esc: 27
- };
- cm.openDialog = function(template, callback, options) {
- onKeyDown = options.onKeyDown;
- onKeyUp = options.onKeyUp;
- };
- var close = function() {};
- helpers.doKeys('/');
- // Fake some keyboard events coming in.
- onKeyDown({keyCode: KEYCODES.f}, '', close);
- onKeyUp({keyCode: KEYCODES.f}, '', close);
- onKeyDown({keyCode: KEYCODES.o}, 'f', close);
- onKeyUp({keyCode: KEYCODES.o}, 'f', close);
- onKeyDown({keyCode: KEYCODES.o}, 'fo', close);
- onKeyUp({keyCode: KEYCODES.o}, 'fo', close);
- onKeyDown({keyCode: KEYCODES.Esc}, 'foo', close);
- cm.openDialog = helpers.fakeOpenDialog('registers');
- cm.openNotification = helpers.fakeOpenNotification(function(text) {
- is(/waldo/.test(text));
- is(!/foo/.test(text));
- });
- helpers.doKeys(':');
+ helpers.doKeys('/', 'waldo', '\n');
+ helpers.doKeys('/', 'foo', '<Esc>');
+ helpers.doEx('registers');
+ var text = helpers.getNotificationText();
+ is(/waldo/.test(text));
+ is(!/foo/.test(text));
}, {value: ''});
testVim('search_register', function(cm, vim, helpers) {
- cm.openDialog = helpers.fakeOpenDialog('foo');
- helpers.doKeys('/');
- cm.openDialog = helpers.fakeOpenDialog('registers');
- cm.openNotification = helpers.fakeOpenNotification(function(text) {
- is(/\/\s+foo/.test(text));
- });
- helpers.doKeys(':');
+ helpers.doKeys('/', 'foo', '\n');
+ helpers.doEx('registers');
+ is(/\/\s+foo/.test(helpers.getNotificationText()));
}, {value: ''});
testVim('search_history', function(cm, vim, helpers) {
- cm.openDialog = helpers.fakeOpenDialog('this');
- helpers.doKeys('/');
- cm.openDialog = helpers.fakeOpenDialog('checks');
- helpers.doKeys('/');
- cm.openDialog = helpers.fakeOpenDialog('search');
- helpers.doKeys('/');
- cm.openDialog = helpers.fakeOpenDialog('history');
+ helpers.doKeys('/', 'this', '\n');
+ helpers.doKeys('/', 'checks', '\n');
+ helpers.doKeys('/', 'search', '\n');
+ helpers.doKeys('/', 'history', '\n');
+ helpers.doKeys('/', 'checks', '\n');
helpers.doKeys('/');
- cm.openDialog = helpers.fakeOpenDialog('checks');
- helpers.doKeys('/');
- var onKeyDown;
- var onKeyUp;
- var query = '';
- var keyCodes = {
- Up: 38,
- Down: 40
- };
- cm.openDialog = function(template, callback, options) {
- onKeyUp = options.onKeyUp;
- onKeyDown = options.onKeyDown;
- };
- var close = function(newVal) {
- if (typeof newVal == 'string') query = newVal;
- }
- helpers.doKeys('/');
- onKeyDown({keyCode: keyCodes.Up}, query, close);
- onKeyUp({keyCode: keyCodes.Up}, query, close);
- eq(query, 'checks');
- onKeyDown({keyCode: keyCodes.Up}, query, close);
- onKeyUp({keyCode: keyCodes.Up}, query, close);
- eq(query, 'history');
- onKeyDown({keyCode: keyCodes.Up}, query, close);
- onKeyUp({keyCode: keyCodes.Up}, query, close);
- eq(query, 'search');
- onKeyDown({keyCode: keyCodes.Up}, query, close);
- onKeyUp({keyCode: keyCodes.Up}, query, close);
- eq(query, 'this');
- onKeyDown({keyCode: keyCodes.Down}, query, close);
- onKeyUp({keyCode: keyCodes.Down}, query, close);
- eq(query, 'search');
+ helpers.doKeys('Up');
+ eq(document.activeElement.value, 'checks');
+ helpers.doKeys('Up');
+ eq(document.activeElement.value, 'history');
+ helpers.doKeys('Up');
+ eq(document.activeElement.value, 'search');
+ helpers.doKeys('Up');
+ eq(document.activeElement.value, 'this');
+ helpers.doKeys('Down');
+ eq(document.activeElement.value, 'search');
}, {value: ''});
testVim('exCommand_history', function(cm, vim, helpers) {
- cm.openDialog = helpers.fakeOpenDialog('registers');
- helpers.doKeys(':');
- cm.openDialog = helpers.fakeOpenDialog('sort');
- helpers.doKeys(':');
- cm.openDialog = helpers.fakeOpenDialog('map');
- helpers.doKeys(':');
- cm.openDialog = helpers.fakeOpenDialog('invalid');
- helpers.doKeys(':');
- var onKeyDown;
- var onKeyUp;
- var input = '';
- var keyCodes = {
- Up: 38,
- Down: 40,
- s: 115
- };
- cm.openDialog = function(template, callback, options) {
- onKeyUp = options.onKeyUp;
- onKeyDown = options.onKeyDown;
- };
- var close = function(newVal) {
- if (typeof newVal == 'string') input = newVal;
- }
+ helpers.doEx('registers');
+ helpers.doEx('sort');
+ helpers.doEx('map');
+ helpers.doEx('invalid');
helpers.doKeys(':');
- onKeyDown({keyCode: keyCodes.Up}, input, close);
- eq(input, 'invalid');
- onKeyDown({keyCode: keyCodes.Up}, input, close);
- eq(input, 'map');
- onKeyDown({keyCode: keyCodes.Up}, input, close);
- eq(input, 'sort');
- onKeyDown({keyCode: keyCodes.Up}, input, close);
- eq(input, 'registers');
- onKeyDown({keyCode: keyCodes.s}, '', close);
- input = 's';
- onKeyDown({keyCode: keyCodes.Up}, input, close);
- eq(input, 'sort');
+ helpers.doKeys('Up');
+ eq(document.activeElement.value, 'invalid');
+ helpers.doKeys('Up');
+ eq(document.activeElement.value, 'map');
+ helpers.doKeys('Up');
+ eq(document.activeElement.value, 'sort');
+ helpers.doKeys('Up');
+ eq(document.activeElement.value, 'registers');
+ helpers.doKeys('<Esc>', ':');
+ helpers.doKeys('s');
+ eq(document.activeElement.value, 's');
+ helpers.doKeys('Up');
+ eq(document.activeElement.value, 'sort');
}, {value: ''});
testVim('search_clear', function(cm, vim, helpers) {
- var onKeyDown;
- var input = '';
- var keyCodes = {
- Ctrl: 17,
- u: 85
- };
- cm.openDialog = function(template, callback, options) {
- onKeyDown = options.onKeyDown;
- };
- var close = function(newVal) {
- if (typeof newVal == 'string') input = newVal;
- }
- helpers.doKeys('/');
- input = 'foo';
- onKeyDown({keyCode: keyCodes.Ctrl}, input, close);
- onKeyDown({keyCode: keyCodes.u, ctrlKey: true}, input, close);
- eq(input, '');
+ helpers.doKeys('/', 'foo');
+ eq(document.activeElement.value, 'foo');
+ helpers.doKeys('<C-u>');
+ eq(document.activeElement.value, '');
});
testVim('exCommand_clear', function(cm, vim, helpers) {
- var onKeyDown;
- var input = '';
- var keyCodes = {
- Ctrl: 17,
- u: 85
- };
- cm.openDialog = function(template, callback, options) {
- onKeyDown = options.onKeyDown;
- };
- var close = function(newVal) {
- if (typeof newVal == 'string') input = newVal;
- }
- helpers.doKeys(':');
- input = 'foo';
- onKeyDown({keyCode: keyCodes.Ctrl}, input, close);
- onKeyDown({keyCode: keyCodes.u, ctrlKey: true}, input, close);
- eq(input, '');
+ helpers.doKeys(':', 'foo');
+ eq(document.activeElement.value, 'foo');
+ helpers.doKeys('<C-u>');
+ eq(document.activeElement.value, '');
});
testVim('.', function(cm, vim, helpers) {
cm.setCursor(0, 0);
@@ -3355,8 +3243,8 @@ testVim('._insert', function(cm, vim, helpers) {
helpers.assertCursorAt(0, 6);
helpers.doKeys('O');
helpers.doKeys('xyz')
- helpers.doInsertModeKeys('Backspace');
- helpers.doInsertModeKeys('Down');
+ helpers.doKeys('Backspace');
+ helpers.doKeys('Down');
helpers.doKeys('<Esc>');
helpers.doKeys('.');
eq('xy\nxy\ntestestt', cm.getValue());
@@ -3432,7 +3320,7 @@ testVim('._insert_cw_repeat', function(cm, vim, helpers) {
testVim('._delete', function(cm, vim, helpers) {
cm.setCursor(0, 5);
helpers.doKeys('i');
- helpers.doInsertModeKeys('Backspace');
+ helpers.doKeys('Backspace');
helpers.doKeys('<Esc>');
helpers.doKeys('.');
eq('zace', cm.getValue());
@@ -3441,7 +3329,7 @@ testVim('._delete', function(cm, vim, helpers) {
testVim('._delete_repeat', function(cm, vim, helpers) {
cm.setCursor(0, 6);
helpers.doKeys('i');
- helpers.doInsertModeKeys('Backspace');
+ helpers.doKeys('Backspace');
helpers.doKeys('<Esc>');
helpers.doKeys('2', '.');
eq('zzce', cm.getValue());
@@ -3658,6 +3546,7 @@ testVim('Ty,;', function(cm, vim, helpers) {
eq('01230123456789', cm.getValue());
}, { value: '0123456789'});
testVim('HML', function(cm, vim, helpers) {
+ cm.refresh();
var lines = 35;
var textHeight = cm.defaultTextHeight();
cm.setSize(600, lines*textHeight);
@@ -3682,6 +3571,7 @@ forEach(['zb','zz','zt','z-','z.','z<CR>'], function(e, idx){
var lineNum = 250;
var lines = 35;
testVim(e, function(cm, vim, helpers) {
+ cm.refresh();
var k1 = e[0];
var k2 = e.substring(1);
var textHeight = cm.defaultTextHeight();
@@ -3694,21 +3584,23 @@ forEach(['zb','zz','zt','z-','z.','z<CR>'], function(e, idx){
})()});
});
testVim('zb_to_bottom', function(cm, vim, helpers){
+ cm.refresh();
var lineNum = 250;
cm.setSize(600, 35*cm.defaultTextHeight());
cm.setCursor(lineNum, 0);
helpers.doKeys('z', 'b');
var scrollInfo = cm.getScrollInfo();
- eq(scrollInfo.top + scrollInfo.clientHeight, cm.charCoords(Pos(lineNum, 0), 'local').bottom);
+ eq(scrollInfo.top + scrollInfo.clientHeight, cm.charCoords(new Pos(lineNum, 0), 'local').bottom);
}, { value: (function(){
return new Array(500).join('\n');
})()});
testVim('zt_to_top', function(cm, vim, helpers){
+ cm.refresh();
var lineNum = 250;
cm.setSize(600, 35*cm.defaultTextHeight());
cm.setCursor(lineNum, 0);
helpers.doKeys('z', 't');
- eq(cm.getScrollInfo().top, cm.charCoords(Pos(lineNum, 0), 'local').top);
+ eq(cm.getScrollInfo().top, cm.charCoords(new Pos(lineNum, 0), 'local').top);
}, { value: (function(){
return new Array(500).join('\n');
})()});
@@ -3733,8 +3625,7 @@ var moveTillCharacterSandbox =
testVim('moveTillCharacter', function(cm, vim, helpers){
cm.setCursor(0, 0);
// Search for the 'q'.
- cm.openDialog = helpers.fakeOpenDialog('q');
- helpers.doKeys('/');
+ helpers.doKeys('/', 'q', '\n');
eq(4, cm.getCursor().ch);
// Jump to just before the first o in the list.
helpers.doKeys('t');
@@ -3769,8 +3660,7 @@ testVim('searchForPipe', function(cm, vim, helpers){
CodeMirror.Vim.setOption('pcre', false);
cm.setCursor(0, 0);
// Search for the '|'.
- cm.openDialog = helpers.fakeOpenDialog('|');
- helpers.doKeys('/');
+ helpers.doKeys('/', '|', '\n');
eq(4, cm.getCursor().ch);
}, { value: 'this|that'});
@@ -4073,10 +3963,8 @@ testVim('ex_global', function(cm, vim, helpers) {
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 one', cm.getValue());
- cm.openNotification = helpers.fakeOpenNotification(function(text) {
- eq(' one one\n two one', text);
- });
helpers.doEx('g/^ /');
+ eq(' one one\n two one', helpers.getNotificationText());
}, {value: 'one one\n one one\n one one'});
testVim('ex_global_substitute_join', function(cm, vim, helpers) {
helpers.doEx('g/o/s/\\n/;');
@@ -4088,39 +3976,20 @@ testVim('ex_global_substitute_split', function(cm, vim, helpers) {
}, {value: 'one\ntwo\nthree\nfour\nfive\n'});
testVim('ex_global_confirm', function(cm, vim, helpers) {
cm.setCursor(0, 0);
- var onKeyDown;
- var openDialogSave = cm.openDialog;
- var KEYCODES = {
- a: 65,
- n: 78,
- q: 81,
- y: 89
- };
- // Intercept the ex command, 'global'
- cm.openDialog = function(template, callback, options) {
- // Intercept the prompt for the embedded ex command, 'substitute'
- cm.openDialog = function(template, callback, options) {
- onKeyDown = options.onKeyDown;
- };
- callback('g/one/s//two/gc');
- };
- helpers.doKeys(':');
- var close = function() {};
- onKeyDown({keyCode: KEYCODES.n}, '', close);
- onKeyDown({keyCode: KEYCODES.y}, '', close);
- onKeyDown({keyCode: KEYCODES.a}, '', close);
- onKeyDown({keyCode: KEYCODES.q}, '', close);
- onKeyDown({keyCode: KEYCODES.y}, '', close);
+ helpers.doEx('g/one/s//two/gc');
+ helpers.doKeys('n');
+ helpers.doKeys('y');
+ helpers.doKeys('a');
+ helpers.doKeys('q');
+ helpers.doKeys('y');
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]');
+ eq('one\n three\n feur\n', helpers.getNotificationText());
}, {value: 'one\n two\n three\n four\n five\n'});
// Basic substitute tests.
testVim('ex_substitute_same_line', function(cm, vim, helpers) {
@@ -4191,14 +4060,15 @@ testVim('ex_substitute_visual_range', function(cm, vim, helpers) {
cm.setCursor(1, 0);
// Set last visual mode selection marks '< and '> at lines 2 and 4
helpers.doKeys('V', '2', 'j', 'v');
- helpers.doEx('\'<,\'>s/\\d/0/g');
+ helpers.doKeys(':');
+ eq(document.activeElement.value, "'<,'>");
+ helpers.doKeys('s/\\d/0/g', '\n');
eq('1\n0\n0\n0\n5', cm.getValue());
}, { value: '1\n2\n3\n4\n5' });
testVim('ex_substitute_empty_query', function(cm, vim, helpers) {
// If the query is empty, use last query.
cm.setCursor(1, 0);
- cm.openDialog = helpers.fakeOpenDialog('1');
- helpers.doKeys('/');
+ helpers.doKeys('/', '1\n');
helpers.doEx('s//b/g');
eq('abb ab2 ab3', cm.getValue());
}, { value: 'a11 a12 a13' });
@@ -4322,8 +4192,12 @@ testSubstitute('ex_substitute_multibackslash_replacement', {
expr: '%s/,/\\\\\\\\\\\\\\\\/g'}); // 16 backslashes.
testSubstitute('ex_substitute_dollar_assertion', {
value: 'one,two \n three,four',
- expectedValue: 'one,two ,\n three,four', // TODO: should match at end of doc.
+ expectedValue: 'one,two ,\n three,four,',
expr: '%s/$/,/g'});
+testSubstitute('ex_substitute_dollar_assertion_empty_lines', {
+ value: '\n\n\n\n\n\n',
+ expectedValue: ';\n;\n;\n;\n;\n;\n;',
+ expr: '%s/$/;/g'});
testSubstitute('ex_substitute_dollar_literal', {
value: 'one$two\n$three\nfour$\n$',
expectedValue: 'one,two\n,three\nfour,\n,',
@@ -4389,48 +4263,29 @@ testSubstitute('ex_substitute_not_global', {
value: 'aaa\nbaa\ncaa',
expectedValue: 'xaa\nbxa\ncxa',
expr: '%s/a/x/'});
+testSubstitute('ex_substitute_optional', {
+ value: 'aaa aa\n aa',
+ expectedValue: '<aaa> <> <aa>\n<> <aa>',
+ expr: '%s/(a*)/<$1>/g',
+ noPcreExpr: '%s/\\(a*\\)/<\\1>/g'});
+testSubstitute('ex_substitute_empty_match', {
+ value: 'aaa aa\n aa\nbb\n',
+ expectedValue: '<aaa> <aa>\n <aa>\nbb<>\n<>',
+ expr: '%s/(a+|$)/<$1>/g',
+ noPcreExpr: '%s/\\(a+\\|$\\)/<\\1>/g'});
+testSubstitute('ex_substitute_empty_or_match', {
+ value: '1234\n567\n89\n0\n',
+ expectedValue: '<12><34>\n<56>7<>\n<89>\n0<>\n<>',
+ expr: '%s/(..|$)/<$1>/g',
+ noPcreExpr: '%s/\\(..\\|$\\)/<\\1>/g'});
function testSubstituteConfirm(name, command, initialValue, expectedValue, keys, finalPos) {
testVim(name, function(cm, vim, helpers) {
- var savedOpenDialog = cm.openDialog;
- var savedKeyName = CodeMirror.keyName;
- var onKeyDown;
- var recordedCallback;
- var closed = true; // Start out closed, set false on second openDialog.
- function close() {
- closed = true;
- }
- // First openDialog should save callback.
- cm.openDialog = function(template, callback, options) {
- recordedCallback = callback;
- }
- // Do first openDialog.
- helpers.doKeys(':');
- // Second openDialog should save keyDown handler.
- cm.openDialog = function(template, callback, options) {
- onKeyDown = options.onKeyDown;
- closed = false;
- };
- // Return the command to Vim and trigger second openDialog.
- recordedCallback(command);
- // The event should really use keyCode, but here just mock it out and use
- // key and replace keyName to just return key.
- CodeMirror.keyName = function (e) { return e.key; }
- keys = keys.toUpperCase();
+ helpers.doEx(command);
for (var i = 0; i < keys.length; i++) {
- is(!closed);
- onKeyDown({ key: keys.charAt(i) }, '', close);
- }
- try {
- eq(expectedValue, cm.getValue());
- helpers.assertCursorAt(finalPos);
- is(closed);
- } catch(e) {
- throw e
- } finally {
- // Restore overridden functions.
- CodeMirror.keyName = savedKeyName;
- cm.openDialog = savedOpenDialog;
+ helpers.doKeys(keys.charAt(i))
}
+ eq(expectedValue, cm.getValue());
+ helpers.assertCursorAt(finalPos);
}, { value: initialValue });
}
testSubstituteConfirm('ex_substitute_confirm_emptydoc',
@@ -4463,8 +4318,7 @@ testSubstituteConfirm('ex_substitute_confirm_range_last',
'1,3s/a/b/cg', 'aa\na \na\na', 'bb\nb \na\na', 'yyl', makeCursor(1, 0));
//:noh should clear highlighting of search-results but allow to resume search through n
testVim('ex_noh_clearSearchHighlight', function(cm, vim, helpers) {
- cm.openDialog = helpers.fakeOpenDialog('match');
- helpers.doKeys('?');
+ helpers.doKeys('?', 'match', '\n');
helpers.doEx('noh');
eq(vim.searchState_.getOverlay(),null,'match-highlighting wasn\'t cleared');
helpers.doKeys('n');
@@ -4661,9 +4515,8 @@ testVim('ex_unmap_key2key', function(cm, vim, helpers) {
CodeMirror.Vim.mapclear();
}, { value: 'abc' });
testVim('ex_unmap_key2key_does_not_remove_default', function(cm, vim, helpers) {
- expectFail(function() {
- helpers.doEx('unmap a');
- });
+ helpers.doEx('unmap a');
+ is(/No such mapping: unmap a/.test(helpers.getNotificationText()));
helpers.doKeys('a');
eq('vim-insert', cm.getOption('keyMap'));
CodeMirror.Vim.mapclear();
@@ -4834,10 +4687,10 @@ testVim('noremap_swap', function(cm, vim, helpers) {
cm.setCursor(0, 0);
// 'a' should act like 'i'.
helpers.doKeys('a');
- eqCursorPos(Pos(0, 0), cm.getCursor());
+ eqCursorPos(new Pos(0, 0), cm.getCursor());
// ...and 'i' should act like 'a'.
helpers.doKeys('<Esc>', 'i');
- eqCursorPos(Pos(0, 1), cm.getCursor());
+ eqCursorPos(new Pos(0, 1), cm.getCursor());
// unmap all mappings
CodeMirror.Vim.mapclear();
}, { value: 'foo' });
@@ -4848,13 +4701,13 @@ testVim('noremap_map_interaction', function(cm, vim, helpers) {
CodeMirror.Vim.map('l', 'j');
cm.setCursor(0, 0);
helpers.doKeys(';');
- eqCursorPos(Pos(0, 1), cm.getCursor());
+ eqCursorPos(new Pos(0, 1), cm.getCursor());
helpers.doKeys('l');
- eqCursorPos(Pos(1, 1), cm.getCursor());
+ eqCursorPos(new Pos(1, 1), cm.getCursor());
// map should be able to point to a noremap
CodeMirror.Vim.map('m', ';');
helpers.doKeys('m');
- eqCursorPos(Pos(1, 2), cm.getCursor());
+ eqCursorPos(new Pos(1, 2), cm.getCursor());
// unmap all mappings
CodeMirror.Vim.mapclear();
}, { value: 'wOrd1\nwOrd2' });
@@ -4865,9 +4718,9 @@ testVim('noremap_map_interaction2', function(cm, vim, helpers) {
CodeMirror.Vim.noremap(';', 'h');
cm.setCursor(0, 0);
helpers.doKeys('l');
- eqCursorPos(Pos(0, 1), cm.getCursor());
+ eqCursorPos(new Pos(0, 1), cm.getCursor());
helpers.doKeys('m');
- eqCursorPos(Pos(0, 0), cm.getCursor());
+ eqCursorPos(new Pos(0, 0), cm.getCursor());
// unmap all mappings
CodeMirror.Vim.mapclear();
}, { value: 'wOrd1\nwOrd2' });
@@ -5125,3 +4978,187 @@ testVim('increment_hexadecimal', function(cm, vim, helpers) {
helpers.doKeys('<C-x>');
eq('0x00', cm.getValue());
}, { value: '0x0' });
+
+var typeKey = function() {
+ var keyCodeToKey = {};
+ var keyCodeToCode = {};
+
+ var alias = {};
+ alias.Ctrl = "Control";
+ alias.Option = "Alt";
+ alias.Cmd = alias.Super = alias.Meta = "Command";
+
+ var controlKeys = {
+ Shift: 16, Control: 17, Alt: 18, Meta: 224, Command: 224,
+ Backspace:8, Tab:9, Return: 13, Enter: 13,
+ Pause: 19, Escape: 27, PageUp: 33, PageDown: 34, End: 35, Home: 36,
+ Left: 37, Up: 38, Right: 39, Down: 40, Insert: 45, Delete: 46,
+ ArrowLeft: 37, ArrowUp: 38, ArrowRight: 39, ArrowDown: 40,
+ };
+ var shiftedKeys = {};
+ var printableKeys = {};
+ var specialKeys = {
+ Backquote: [192, "`", "~"], Minus: [189, "-", "_"], Equal: [187, "=", "+"],
+ BracketLeft: [219, "[", "{"], Backslash: [220, "\\", "|"], BracketRight: [221, "]", "}"],
+ Semicolon: [186, ";", ":"], Quote: [222, "'", '"'], Comma: [188, ",", "<"],
+ Period: [190, ".", ">"], Slash: [191, "/", "?"], Space: [32, " "], NumpadAdd: [107, "+"],
+ NumpadDecimal: [110, "."], NumpadSubtract: [109, "-"], NumpadDivide: [111, "/"], NumpadMultiply: [106, "*"]
+ };
+ for (var i in specialKeys) {
+ var key = specialKeys[i];
+ printableKeys[i] = printableKeys[key[1]] = shiftedKeys[key[2]] = key[0];
+ keyCodeToCode[key[0]] = i;
+ }
+ for (var i = 0; i < 10; i++) {
+ printableKeys[i] = shiftedKeys["!@#$%^&*()"[i]] = 48 + i;
+ keyCodeToCode[48 + i] = "Digit" + i;
+ }
+ for (var i = 65; i < 90; i++) {
+ var chr = String.fromCharCode(i + 32);
+ printableKeys[chr] = shiftedKeys[chr.toUpperCase()] = i;
+ keyCodeToCode[i] = "Key" + chr.toUpperCase();
+ }
+ for (var i = 1; i < 13; i++) {
+ controlKeys["F" + i] = 111 + i;
+ }
+
+ for (var i in controlKeys) {
+ keyCodeToKey[controlKeys[i]] = i;
+ keyCodeToCode[controlKeys[i]] = i;
+ }
+ controlKeys["\n"] = controlKeys.Return;
+ controlKeys.Del = controlKeys.Delete;
+ controlKeys.Esc = controlKeys.Escape;
+ controlKeys.Ins = controlKeys.Insert;
+
+ var shift = false;
+ var ctrl = false;
+ var meta = false;
+ var alt = false;
+ function reset() {
+ shift = ctrl = meta = alt = false;
+ }
+ function updateModifierStates(keyCode) {
+ if (keyCode == controlKeys.Shift)
+ return shift = true;
+ if (keyCode == controlKeys.Control)
+ return ctrl = true;
+ if (keyCode == controlKeys.Meta)
+ return meta = true;
+ if (keyCode == controlKeys.Alt)
+ return alt = true;
+ }
+
+ function sendKey(letter, timeout) {
+ var keyCode = controlKeys[letter] || printableKeys[letter] || shiftedKeys[letter];
+ var isModifier = updateModifierStates(keyCode);
+
+ var text = letter;
+ var isTextInput = true;
+ if (ctrl || alt || meta || controlKeys[letter]) {
+ isTextInput = false;
+ } else if (shift) {
+ text = text.toUpperCase();
+ }
+
+ var target = document.activeElement;
+ var prevented = emit("keydown", true);
+ if (isModifier) return;
+ if (!prevented && isTextInput) prevented = emit("keypress", true);
+ if (!prevented && ctrl && !alt && !meta && letter == "c") emitClipboard("copy");
+ if (!prevented) updateTextInput();
+ emit("keyup", true);
+
+ function emitClipboard(type) {
+ var data = {bubbles: true, cancelable:true};
+ var event = new KeyboardEvent(type, data);
+ event.clipboardData = {
+ setData: function() {},
+ getData: function() {},
+ clearData: function() {},
+ };
+ target.dispatchEvent(event);
+ }
+ function emit(type, bubbles) {
+ var el = document.activeElement;
+ var data = {bubbles: bubbles, cancelable:true};
+ data.charCode = text.charCodeAt(0);
+ data.keyCode = type == "keypress" ? data.charCode : keyCode;
+ data.which = data.keyCode;
+ data.shiftKey = shift || shiftedKeys[text];
+ data.ctrlKey = ctrl;
+ data.altKey = alt;
+ data.metaKey = meta;
+ data.key = text || keyCodeToKey[keyCode];
+ data.code = keyCodeToCode[keyCode];
+ var event = new KeyboardEvent(type, data);
+
+ var el = document.activeElement;
+ el.dispatchEvent(event);
+ return event.defaultPrevented;
+ }
+ function updateTextInput() {
+ if (!isTextInput && keyCode == controlKeys.Return) {
+ text = "\n";
+ }
+ if (target._handleInputEventForTest) {
+ return target._handleInputEventForTest(text);
+ }
+ var isTextarea = "selectionStart" in target && typeof target.value == "string";
+ if (!isTextarea) return;
+
+ var start = target.selectionStart;
+ var end = target.selectionEnd;
+ var value = target.value;
+
+ if (!isTextInput) {
+ if (keyCode == controlKeys.Backspace) {
+ if (start != end) start = Math.max(start - 1, 0);
+ } else if (keyCode == controlKeys.Delete) {
+ if (start != end) end = Math.min(end + 1, value.length);
+ } else {
+ return;
+ }
+ }
+ var newValue = value.slice(0, start) + text + value.slice(end);
+ var newStart = start + text.length;
+ var newEnd = newStart;
+ if (newValue != value || newStart != start || newEnd != end) {
+ target.value = newValue;
+ target.setSelectionRange(newStart, newEnd);
+ emit("input", false);
+ }
+ }
+ }
+
+ function type() {
+ var keys = Array.prototype.slice.call(arguments);
+ for (var i = 0; i < keys.length; i++) {
+ var key = keys[i];
+ if (Array.isArray(key)) {
+ type.apply(null, key);
+ continue;
+ }
+ reset();
+ if (key.length > 1) {
+ var isKeyName = controlKeys[key] || printableKeys[key] || shiftedKeys[key];
+ if (!isKeyName) {
+ var parts = key.split("-");
+ var modifier = alias[parts[0]] || parts[0];
+ if (!updateModifierStates(controlKeys[modifier])) {
+ type.apply(null, key.split(""));
+ continue;
+ }
+ key = parts.pop();
+ parts.forEach(function(part) {
+ var keyCode = controlKeys[part];
+ updateModifierStates(keyCode);
+ });
+ }
+ }
+ sendKey(key);
+ }
+ }
+
+ return type;
+}();
diff --git a/help3/xhpeditor/cm/theme/ayu-dark.css b/help3/xhpeditor/cm/theme/ayu-dark.css
index fd41ba3..13656b9 100644
--- a/help3/xhpeditor/cm/theme/ayu-dark.css
+++ b/help3/xhpeditor/cm/theme/ayu-dark.css
@@ -9,6 +9,8 @@
.cm-s-ayu-dark .CodeMirror-guttermarker-subtle { color: #3d424d; }
.cm-s-ayu-dark .CodeMirror-linenumber { color: #3d424d; }
.cm-s-ayu-dark .CodeMirror-cursor { border-left: 1px solid #e6b450; }
+.cm-s-ayu-dark.cm-fat-cursor .CodeMirror-cursor { background-color: #a2a8a175 !important; }
+.cm-s-ayu-dark .cm-animate-fat-cursor { background-color: #a2a8a175 !important; }
.cm-s-ayu-dark span.cm-comment { color: #626a73; }
.cm-s-ayu-dark span.cm-atom { color: #ae81ff; }
diff --git a/help3/xhpeditor/cm/theme/ayu-mirage.css b/help3/xhpeditor/cm/theme/ayu-mirage.css
index 7a5b50c..19403ce 100644
--- a/help3/xhpeditor/cm/theme/ayu-mirage.css
+++ b/help3/xhpeditor/cm/theme/ayu-mirage.css
@@ -8,7 +8,9 @@
.cm-s-ayu-mirage .CodeMirror-guttermarker { color: white; }
.cm-s-ayu-mirage .CodeMirror-guttermarker-subtle { color: rgba(112, 122, 140, 66); }
.cm-s-ayu-mirage .CodeMirror-linenumber { color: rgba(61, 66, 77, 99); }
-.cm-s-ayu-mirage .CodeMirror-cursor { border-left: 1px solid #ffcc66; }
+.cm-s-ayu-mirage .CodeMirror-cursor { border-left: 1px solid #ffcc66; }
+.cm-s-ayu-mirage.cm-fat-cursor .CodeMirror-cursor {background-color: #a2a8a175 !important;}
+.cm-s-ayu-mirage .cm-animate-fat-cursor { background-color: #a2a8a175 !important; }
.cm-s-ayu-mirage span.cm-comment { color: #5c6773; font-style:italic; }
.cm-s-ayu-mirage span.cm-atom { color: #ae81ff; }
diff --git a/help3/xhpeditor/cm/theme/base16-dark.css b/help3/xhpeditor/cm/theme/base16-dark.css
index 026a816..b3c31ab 100644
--- a/help3/xhpeditor/cm/theme/base16-dark.css
+++ b/help3/xhpeditor/cm/theme/base16-dark.css
@@ -17,6 +17,8 @@
.cm-s-base16-dark .CodeMirror-guttermarker-subtle { color: #505050; }
.cm-s-base16-dark .CodeMirror-linenumber { color: #505050; }
.cm-s-base16-dark .CodeMirror-cursor { border-left: 1px solid #b0b0b0; }
+.cm-s-base16-dark.cm-fat-cursor .CodeMirror-cursor { background-color: #8e8d8875 !important; }
+.cm-s-base16-dark .cm-animate-fat-cursor { background-color: #8e8d8875 !important; }
.cm-s-base16-dark span.cm-comment { color: #8f5536; }
.cm-s-base16-dark span.cm-atom { color: #aa759f; }
diff --git a/help3/xhpeditor/cm/theme/gruvbox-dark.css b/help3/xhpeditor/cm/theme/gruvbox-dark.css
index ded215f..d712dda 100644
--- a/help3/xhpeditor/cm/theme/gruvbox-dark.css
+++ b/help3/xhpeditor/cm/theme/gruvbox-dark.css
@@ -11,6 +11,8 @@
.cm-s-gruvbox-dark .CodeMirror-gutters {background: #282828; border-right: 0px;}
.cm-s-gruvbox-dark .CodeMirror-linenumber {color: #7c6f64;}
.cm-s-gruvbox-dark .CodeMirror-cursor { border-left: 1px solid #ebdbb2; }
+.cm-s-gruvbox-dark.cm-fat-cursor .CodeMirror-cursor { background-color: #8e8d8875 !important; }
+.cm-s-gruvbox-dark .cm-animate-fat-cursor { background-color: #8e8d8875 !important; }
.cm-s-gruvbox-dark div.CodeMirror-selected { background: #928374; }
.cm-s-gruvbox-dark span.cm-meta { color: #83a598; }
diff --git a/help3/xhpeditor/cm/theme/juejin.css b/help3/xhpeditor/cm/theme/juejin.css
new file mode 100644
index 0000000..38cf7fe
--- /dev/null
+++ b/help3/xhpeditor/cm/theme/juejin.css
@@ -0,0 +1,30 @@
+.cm-s-juejin.CodeMirror {
+ background: #f8f9fa;
+}
+.cm-s-juejin .cm-header,
+.cm-s-juejin .cm-def {
+ color: #1ba2f0;
+}
+.cm-s-juejin .cm-comment {
+ color: #009e9d;
+}
+.cm-s-juejin .cm-quote,
+.cm-s-juejin .cm-link,
+.cm-s-juejin .cm-strong,
+.cm-s-juejin .cm-attribute {
+ color: #fd7741;
+}
+.cm-s-juejin .cm-url,
+.cm-s-juejin .cm-keyword,
+.cm-s-juejin .cm-builtin {
+ color: #bb51b8;
+}
+.cm-s-juejin .cm-hr {
+ color: #909090;
+}
+.cm-s-juejin .cm-tag {
+ color: #107000;
+}
+.cm-s-juejin .cm-variable-2 {
+ color: #0050a0;
+}
diff --git a/help3/xhpeditor/cm/theme/material-ocean.css b/help3/xhpeditor/cm/theme/material-ocean.css
index 86a6f3c..404178d 100644
--- a/help3/xhpeditor/cm/theme/material-ocean.css
+++ b/help3/xhpeditor/cm/theme/material-ocean.css
@@ -24,6 +24,12 @@
.cm-s-material-ocean .CodeMirror-cursor {
border-left: 1px solid #FFCC00;
}
+.cm-s-material-ocean.cm-fat-cursor .CodeMirror-cursor {
+ background-color: #a2a8a175 !important;
+}
+.cm-s-material-ocean .cm-animate-fat-cursor {
+ background-color: #a2a8a175 !important;
+}
.cm-s-material-ocean div.CodeMirror-selected {
background: rgba(113, 124, 180, 0.2);
@@ -132,4 +138,4 @@
.cm-s-material-ocean .CodeMirror-matchingbracket {
text-decoration: underline;
color: white !important;
-} \ No newline at end of file
+}
diff --git a/help3/xhpeditor/cm/theme/material-palenight.css b/help3/xhpeditor/cm/theme/material-palenight.css
index 66d53dd..6712c43 100644
--- a/help3/xhpeditor/cm/theme/material-palenight.css
+++ b/help3/xhpeditor/cm/theme/material-palenight.css
@@ -24,6 +24,12 @@
.cm-s-material-palenight .CodeMirror-cursor {
border-left: 1px solid #FFCC00;
}
+.cm-s-material-palenight.cm-fat-cursor .CodeMirror-cursor {
+ background-color: #607c8b80 !important;
+}
+.cm-s-material-palenight .cm-animate-fat-cursor {
+ background-color: #607c8b80 !important;
+}
.cm-s-material-palenight div.CodeMirror-selected {
background: rgba(113, 124, 180, 0.2);
@@ -132,4 +138,4 @@
.cm-s-material-palenight .CodeMirror-matchingbracket {
text-decoration: underline;
color: white !important;
-} \ No newline at end of file
+}
diff --git a/help3/xhpeditor/cm/theme/material.css b/help3/xhpeditor/cm/theme/material.css
index 9ac17a3..a784849 100644
--- a/help3/xhpeditor/cm/theme/material.css
+++ b/help3/xhpeditor/cm/theme/material.css
@@ -24,6 +24,12 @@
.cm-s-material .CodeMirror-cursor {
border-left: 1px solid #FFCC00;
}
+.cm-s-material.cm-fat-cursor .CodeMirror-cursor {
+ background-color: #5d6d5c80 !important;
+}
+.cm-s-material .cm-animate-fat-cursor {
+ background-color: #5d6d5c80 !important;
+}
.cm-s-material div.CodeMirror-selected {
background: rgba(128, 203, 196, 0.2);
@@ -132,4 +138,4 @@
.cm-s-material .CodeMirror-matchingbracket {
text-decoration: underline;
color: white !important;
-} \ No newline at end of file
+}
diff --git a/help3/xhpeditor/cm/theme/oceanic-next.css b/help3/xhpeditor/cm/theme/oceanic-next.css
index 296277b..f3d0d08 100644
--- a/help3/xhpeditor/cm/theme/oceanic-next.css
+++ b/help3/xhpeditor/cm/theme/oceanic-next.css
@@ -16,6 +16,8 @@
.cm-s-oceanic-next .CodeMirror-guttermarker-subtle { color: #d0d0d0; }
.cm-s-oceanic-next .CodeMirror-linenumber { color: #d0d0d0; }
.cm-s-oceanic-next .CodeMirror-cursor { border-left: 1px solid #f8f8f0; }
+.cm-s-oceanic-next.cm-fat-cursor .CodeMirror-cursor { background-color: #a2a8a175 !important; }
+.cm-s-oceanic-next .cm-animate-fat-cursor { background-color: #a2a8a175 !important; }
.cm-s-oceanic-next span.cm-comment { color: #65737E; }
.cm-s-oceanic-next span.cm-atom { color: #C594C5; }
diff --git a/help3/xhpeditor/cm/theme/solarized.css b/help3/xhpeditor/cm/theme/solarized.css
index 9c6b126..e978fec 100644
--- a/help3/xhpeditor/cm/theme/solarized.css
+++ b/help3/xhpeditor/cm/theme/solarized.css
@@ -35,12 +35,10 @@ http://ethanschoonover.com/solarized/img/solarized-palette.png
.cm-s-solarized.cm-s-dark {
color: #839496;
background-color: #002b36;
- text-shadow: #002b36 0 1px;
}
.cm-s-solarized.cm-s-light {
background-color: #fdf6e3;
color: #657b83;
- text-shadow: #eee8d5 0 1px;
}
.cm-s-solarized .CodeMirror-widget {
@@ -126,7 +124,6 @@ http://ethanschoonover.com/solarized/img/solarized-palette.png
.cm-s-solarized.cm-s-dark .CodeMirror-linenumber {
color: #586e75;
- text-shadow: #021014 0 -1px;
}
/* Light */
diff --git a/help3/xhpeditor/links.txt.xsl b/help3/xhpeditor/links.txt.xsl
index 87a6fdf..8fa39d8 100644
--- a/help3/xhpeditor/links.txt.xsl
+++ b/help3/xhpeditor/links.txt.xsl
@@ -21,8 +21,6 @@
<xsl:when test="$src1='chart2/res/dataeditor_icon02.png'"><xsl:text>cmd/sc_insertcolumnsafter.svg</xsl:text></xsl:when>
<xsl:when test="$src1='chart2/res/dataeditor_icon03.png'"><xsl:text>cmd/sc_deleterows.svg</xsl:text></xsl:when>
<xsl:when test="$src1='chart2/res/dataeditor_icon04.png'"><xsl:text>cmd/sc_deletecolumns.svg</xsl:text></xsl:when>
-<xsl:when test="$src1='chart2/res/netlinepoint_52x60.png'"><xsl:text>chart2/res/net_52x60.svg</xsl:text></xsl:when>
-<xsl:when test="$src1='chart2/res/netlinepointstack_52x60.png'"><xsl:text>chart2/res/netstack_52x60.svg</xsl:text></xsl:when>
<xsl:when test="$src1='chart2/res/selectrange.png'"><xsl:text>formula/res/refinp1.svg</xsl:text></xsl:when>
<xsl:when test="$src1='cmd/32/charttitlemenu.png'"><xsl:text>cmd/32/toggletitle.svg</xsl:text></xsl:when>
<xsl:when test="$src1='cmd/32/diagramaxisall.png'"><xsl:text>cmd/32/diagramaxisxyz.svg</xsl:text></xsl:when>
@@ -253,6 +251,7 @@
<xsl:when test="$src1='cmd/32/formatimagemenu.png'"><xsl:text>cmd/32/graphic.svg</xsl:text></xsl:when>
<xsl:when test="$src1='cmd/32/formatspacingmenu.png'"><xsl:text>cmd/32/spacepara15.svg</xsl:text></xsl:when>
<xsl:when test="$src1='cmd/32/formattextmenu.png'"><xsl:text>cmd/32/charfontname.svg</xsl:text></xsl:when>
+<xsl:when test="$src1='cmd/32/spacepara115.png'"><xsl:text>cmd/32/spacepara1.svg</xsl:text></xsl:when>
<xsl:when test="$src1='cmd/32/textalign.png'"><xsl:text>cmd/32/alignblock.svg</xsl:text></xsl:when>
<xsl:when test="$src1='cmd/lc_anchormenu.png'"><xsl:text>cmd/lc_toggleanchortype.svg</xsl:text></xsl:when>
<xsl:when test="$src1='cmd/lc_conditionalformatmenu.png'"><xsl:text>cmd/lc_conditionalformatdialog.svg</xsl:text></xsl:when>
@@ -261,6 +260,7 @@
<xsl:when test="$src1='cmd/lc_formatimagemenu.png'"><xsl:text>cmd/lc_graphicdialog.svg</xsl:text></xsl:when>
<xsl:when test="$src1='cmd/lc_formatspacingmenu.png'"><xsl:text>cmd/lc_spacepara15.svg</xsl:text></xsl:when>
<xsl:when test="$src1='cmd/lc_formattextmenu.png'"><xsl:text>cmd/lc_charfontname.svg</xsl:text></xsl:when>
+<xsl:when test="$src1='cmd/lc_spacepara115.png'"><xsl:text>cmd/lc_spacepara1.svg</xsl:text></xsl:when>
<xsl:when test="$src1='cmd/lc_textalign.png'"><xsl:text>cmd/lc_alignblock.svg</xsl:text></xsl:when>
<xsl:when test="$src1='cmd/sc_anchormenu.png'"><xsl:text>cmd/sc_toggleanchortype.svg</xsl:text></xsl:when>
<xsl:when test="$src1='cmd/sc_conditionalformatmenu.png'"><xsl:text>cmd/sc_conditionalformatdialog.svg</xsl:text></xsl:when>
@@ -269,6 +269,7 @@
<xsl:when test="$src1='cmd/sc_formatimagemenu.png'"><xsl:text>cmd/sc_graphicdialog.svg</xsl:text></xsl:when>
<xsl:when test="$src1='cmd/sc_formatspacingmenu.png'"><xsl:text>cmd/sc_spacepara15.svg</xsl:text></xsl:when>
<xsl:when test="$src1='cmd/sc_formattextmenu.png'"><xsl:text>cmd/sc_charfontname.svg</xsl:text></xsl:when>
+<xsl:when test="$src1='cmd/sc_spacepara115.png'"><xsl:text>cmd/sc_spacepara1.svg</xsl:text></xsl:when>
<xsl:when test="$src1='cmd/sc_textalign.png'"><xsl:text>cmd/sc_alignblock.svg</xsl:text></xsl:when>
<xsl:when test="$src1='cmd/32/openurl.png'"><xsl:text>cmd/32/browseview.svg</xsl:text></xsl:when>
<xsl:when test="$src1='cmd/32/webhtml.png'"><xsl:text>cmd/32/browseview.svg</xsl:text></xsl:when>
@@ -1418,15 +1419,15 @@
<xsl:when test="$src1='cmd/sc_arrangeframemenu.png'"><xsl:text>cmd/sc_bringtofront.svg</xsl:text></xsl:when>
<xsl:when test="$src1='cmd/sc_arrangemenu.png'"><xsl:text>cmd/sc_bringtofront.svg</xsl:text></xsl:when>
<xsl:when test="$src1='cmd/32/insertcell.png'"><xsl:text>cmd/32/insertcellsright.svg</xsl:text></xsl:when>
-<xsl:when test="$src1='cmd/32/mergecellsmenu.png'"><xsl:text>cmd/32/togglemergecells.svg</xsl:text></xsl:when>
+<xsl:when test="$src1='cmd/32/mergecellsmenu.png'"><xsl:text>cmd/32/mergecells.svg</xsl:text></xsl:when>
<xsl:when test="$src1='cmd/32/numberformatmenu.png'"><xsl:text>cmd/32/numberformatstandard.svg</xsl:text></xsl:when>
<xsl:when test="$src1='cmd/32/printrangesmenu.png'"><xsl:text>cmd/32/defineprintarea.svg</xsl:text></xsl:when>
<xsl:when test="$src1='cmd/lc_insertcell.png'"><xsl:text>cmd/lc_insertcellsright.svg</xsl:text></xsl:when>
-<xsl:when test="$src1='cmd/lc_mergecellsmenu.png'"><xsl:text>cmd/lc_togglemergecells.svg</xsl:text></xsl:when>
+<xsl:when test="$src1='cmd/lc_mergecellsmenu.png'"><xsl:text>cmd/lc_mergecells.svg</xsl:text></xsl:when>
<xsl:when test="$src1='cmd/lc_numberformatmenu.png'"><xsl:text>cmd/lc_numberformatstandard.svg</xsl:text></xsl:when>
<xsl:when test="$src1='cmd/lc_printrangesmenu.png'"><xsl:text>cmd/lc_defineprintarea.svg</xsl:text></xsl:when>
<xsl:when test="$src1='cmd/sc_insertcell.png'"><xsl:text>cmd/sc_insertcellsright.svg</xsl:text></xsl:when>
-<xsl:when test="$src1='cmd/sc_mergecellsmenu.png'"><xsl:text>cmd/sc_togglemergecells.svg</xsl:text></xsl:when>
+<xsl:when test="$src1='cmd/sc_mergecellsmenu.png'"><xsl:text>cmd/sc_mergecells.svg</xsl:text></xsl:when>
<xsl:when test="$src1='cmd/sc_numberformatmenu.png'"><xsl:text>cmd/sc_numberformatstandard.svg</xsl:text></xsl:when>
<xsl:when test="$src1='cmd/sc_printrangesmenu.png'"><xsl:text>cmd/sc_defineprintarea.svg</xsl:text></xsl:when>
<xsl:when test="$src1='cmd/32/draw.png'"><xsl:text>cmd/32/reload.svg</xsl:text></xsl:when>
@@ -1532,7 +1533,6 @@
<xsl:when test="$src1='cmd/lc_setdefault.png'"><xsl:text>cmd/lc_resetattributes.svg</xsl:text></xsl:when>
<xsl:when test="$src1='cmd/sc_charbackcolor.png'"><xsl:text>cmd/sc_backcolor.svg</xsl:text></xsl:when>
<xsl:when test="$src1='cmd/sc_setdefault.png'"><xsl:text>cmd/sc_resetattributes.svg</xsl:text></xsl:when>
-<xsl:when test="$src1='sfx2/res/symphony/sidebar-transition-small.png'"><xsl:text>cmd/sc_slidechangewindow.svg</xsl:text></xsl:when>
<xsl:when test="$src1='sfx2/res/symphony/sidebar-transition-large.png'"><xsl:text>cmd/lc_slidechangewindow.svg</xsl:text></xsl:when>
<xsl:when test="$src1='cmd/32/showgraphics.png'"><xsl:text>cmd/32/graphic.svg</xsl:text></xsl:when>
<xsl:when test="$src1='cmd/lc_showgraphics.png'"><xsl:text>cmd/lc_graphic.svg</xsl:text></xsl:when>
@@ -1652,7 +1652,6 @@
<xsl:when test="$src1='extensions/res/arrow.png'"><xsl:text>cmd/sc_nextrecord.svg</xsl:text></xsl:when>
<xsl:when test="$src1='extensions/res/buttonminus.png'"><xsl:text>extensions/res/scanner/minus.svg</xsl:text></xsl:when>
<xsl:when test="$src1='extensions/res/buttonplus.png'"><xsl:text>extensions/res/scanner/plus.svg</xsl:text></xsl:when>
-<xsl:when test="$src1='formula/res/fapclose.png'"><xsl:text>svtools/res/folder.svg</xsl:text></xsl:when>
<xsl:when test="$src1='formula/res/faperror.png'"><xsl:text>cmd/sc_cancel.svg</xsl:text></xsl:when>
<xsl:when test="$src1='formula/res/fapok.png'"><xsl:text>cmd/sc_ok.svg</xsl:text></xsl:when>
<xsl:when test="$src1='formula/res/fapopen.png'"><xsl:text>cmd/sc_open.svg</xsl:text></xsl:when>
@@ -1686,13 +1685,11 @@
<xsl:when test="$src1='res/fp010.png'"><xsl:text>svtools/res/up_small.svg</xsl:text></xsl:when>
<xsl:when test="$src1='res/fileopen.png'"><xsl:text>cmd/sc_open.svg</xsl:text></xsl:when>
<xsl:when test="$src1='res/foldercl.png'"><xsl:text>svtools/res/folder.svg</xsl:text></xsl:when>
-<xsl:when test="$src1='res/folderop.png'"><xsl:text>cmd/sc_open.svg</xsl:text></xsl:when>
<xsl:when test="$src1='res/hlinettp.png'"><xsl:text>cmd/32/inserthyperlink.svg</xsl:text></xsl:when>
<xsl:when test="$src1='res/im30820.png'"><xsl:text>cmd/sc_scriptorganizer.svg</xsl:text></xsl:when>
<xsl:when test="$src1='res/im30821.png'"><xsl:text>cmd/sc_choosemacro.svg</xsl:text></xsl:when>
<xsl:when test="$src1='res/info.png'"><xsl:text>cmd/lc_helpindex.svg</xsl:text></xsl:when>
<xsl:when test="$src1='res/info_16.png'"><xsl:text>cmd/sc_helpindex.svg</xsl:text></xsl:when>
-<xsl:when test="$src1='res/lc05504.png'"><xsl:text>cmd/lc_print.svg</xsl:text></xsl:when>
<xsl:when test="$src1='res/lc05509.png'"><xsl:text>cmd/lc_print.svg</xsl:text></xsl:when>
<xsl:when test="$src1='res/lc05539.png'"><xsl:text>cmd/lc_designerdialog.svg</xsl:text></xsl:when>
<xsl:when test="$src1='res/lc05678.png'"><xsl:text>cmd/lc_inserthyperlinkcontrol.svg</xsl:text></xsl:when>
@@ -1700,9 +1697,6 @@
<xsl:when test="$src1='res/lc05701.png'"><xsl:text>cmd/lc_undo.svg</xsl:text></xsl:when>
<xsl:when test="$src1='res/lc05710.png'"><xsl:text>cmd/lc_cut.svg</xsl:text></xsl:when>
<xsl:when test="$src1='res/lc05711.png'"><xsl:text>cmd/lc_copy.svg</xsl:text></xsl:when>
-<xsl:when test="$src1='res/lc05961.png'"><xsl:text>cmd/lc_recsearch.svg</xsl:text></xsl:when>
-<xsl:when test="$src1='res/lc06300.png'"><xsl:text>cmd/lc_nextrecord.svg</xsl:text></xsl:when>
-<xsl:when test="$src1='res/lc06301.png'"><xsl:text>cmd/lc_prevrecord.svg</xsl:text></xsl:when>
<xsl:when test="$src1='res/lc10711.png'"><xsl:text>cmd/lc_removefiltersort.svg</xsl:text></xsl:when>
<xsl:when test="$src1='res/lc10715.png'"><xsl:text>cmd/lc_datafilterstandardfilter.svg</xsl:text></xsl:when>
<xsl:when test="$src1='res/lc10716.png'"><xsl:text>cmd/lc_datafilterautofilter.svg</xsl:text></xsl:when>
@@ -1862,8 +1856,6 @@
<xsl:when test="$src1='res/sx10757.png'"><xsl:text>cmd/sc_timefield.svg</xsl:text></xsl:when>
<xsl:when test="$src1='res/sx10768.png'"><xsl:text>cmd/sc_scrollbar.svg</xsl:text></xsl:when>
<xsl:when test="$src1='res/sx10769.png'"><xsl:text>cmd/sc_spinbutton.svg</xsl:text></xsl:when>
-<xsl:when test="$src1='res/sx18002.png'"><xsl:text>res/plus.svg</xsl:text></xsl:when>
-<xsl:when test="$src1='res/sx18003.png'"><xsl:text>res/minus.svg</xsl:text></xsl:when>
<xsl:when test="$src1='sc/res/date.png'"><xsl:text>cmd/sc_datefield.svg</xsl:text></xsl:when>
<xsl:when test="$src1='sc/res/dropcopy.png'"><xsl:text>cmd/sc_copy.svg</xsl:text></xsl:when>
<xsl:when test="$src1='sc/res/droplink.png'"><xsl:text>cmd/sc_insertbookmark.svg</xsl:text></xsl:when>
@@ -1941,7 +1933,6 @@
<xsl:when test="$src1='sfx2/res/doccl.png'"><xsl:text>cmd/sc_newdoc.svg</xsl:text></xsl:when>
<xsl:when test="$src1='sfx2/res/exec_action.png'"><xsl:text>cmd/sc_optionstreedialog.svg</xsl:text></xsl:when>
<xsl:when test="$src1='sfx2/res/favourite.png'"><xsl:text>cmd/sc_insertbookmark.svg</xsl:text></xsl:when>
-<xsl:when test="$src1='sfx2/res/favourite_big.png'"><xsl:text>cmd/lc_insertbookmark.svg</xsl:text></xsl:when>
<xsl:when test="$src1='sfx2/res/hlpdoc.png'"><xsl:text>cmd/sc_helpindex.svg</xsl:text></xsl:when>
<xsl:when test="$src1='sfx2/res/minus.png'"><xsl:text>res/minus.svg</xsl:text></xsl:when>
<xsl:when test="$src1='sfx2/res/newex.png'"><xsl:text>res/plus.svg</xsl:text></xsl:when>
@@ -1953,28 +1944,15 @@
<xsl:when test="$src1='sfx2/res/styfam2.png'"><xsl:text>cmd/sc_controlcodes.svg</xsl:text></xsl:when>
<xsl:when test="$src1='sfx2/res/styfam3.png'"><xsl:text>cmd/sc_linestyle.svg</xsl:text></xsl:when>
<xsl:when test="$src1='sfx2/res/styfam4.png'"><xsl:text>cmd/sc_showsinglepage.svg</xsl:text></xsl:when>
-<xsl:when test="$src1='sfx2/res/symphony/sidebar-3d-large.png'"><xsl:text>cmd/lc_cube.svg</xsl:text></xsl:when>
-<xsl:when test="$src1='sfx2/res/symphony/sidebar-3d-small.png'"><xsl:text>cmd/sc_cube.svg</xsl:text></xsl:when>
<xsl:when test="$src1='sfx2/res/symphony/sidebar-animation-large.png'"><xsl:text>cmd/lc_diaeffect.svg</xsl:text></xsl:when>
-<xsl:when test="$src1='sfx2/res/symphony/sidebar-animation-small.png'"><xsl:text>cmd/sc_diaeffect.svg</xsl:text></xsl:when>
-<xsl:when test="$src1='sfx2/res/symphony/sidebar-colors-large.png'"><xsl:text>cmd/lc_colorsettings.svg</xsl:text></xsl:when>
<xsl:when test="$src1='sfx2/res/symphony/sidebar-colors-small.png'"><xsl:text>cmd/sc_colorsettings.svg</xsl:text></xsl:when>
-<xsl:when test="$src1='sfx2/res/symphony/sidebar-eyedropper-large.png'"><xsl:text>cmd/lc_bmpmask.svg</xsl:text></xsl:when>
-<xsl:when test="$src1='sfx2/res/symphony/sidebar-eyedropper-small.png'"><xsl:text>cmd/sc_bmpmask.svg</xsl:text></xsl:when>
<xsl:when test="$src1='sfx2/res/symphony/sidebar-functions-large.png'"><xsl:text>cmd/lc_dbviewfunctions.svg</xsl:text></xsl:when>
-<xsl:when test="$src1='sfx2/res/symphony/sidebar-functions-small.png'"><xsl:text>cmd/sc_dbviewfunctions.svg</xsl:text></xsl:when>
<xsl:when test="$src1='sfx2/res/symphony/sidebar-gallery-large.png'"><xsl:text>cmd/lc_gallery.svg</xsl:text></xsl:when>
-<xsl:when test="$src1='sfx2/res/symphony/sidebar-gallery-small.png'"><xsl:text>cmd/sc_gallery.svg</xsl:text></xsl:when>
-<xsl:when test="$src1='sfx2/res/symphony/sidebar-imganim-large.png'"><xsl:text>cmd/lc_diaeffect.svg</xsl:text></xsl:when>
-<xsl:when test="$src1='sfx2/res/symphony/sidebar-imganim-small.png'"><xsl:text>cmd/sc_diaeffect.svg</xsl:text></xsl:when>
<xsl:when test="$src1='sfx2/res/symphony/sidebar-navigator-large.png'"><xsl:text>cmd/lc_navigator.svg</xsl:text></xsl:when>
-<xsl:when test="$src1='sfx2/res/symphony/sidebar-navigator-small.png'"><xsl:text>cmd/sc_navigator.svg</xsl:text></xsl:when>
<xsl:when test="$src1='sfx2/res/symphony/sidebar-property-large.png'"><xsl:text>cmd/lc_configuredialog.svg</xsl:text></xsl:when>
<xsl:when test="$src1='sfx2/res/symphony/sidebar-property-small.png'"><xsl:text>cmd/sc_configuredialog.svg</xsl:text></xsl:when>
<xsl:when test="$src1='sfx2/res/symphony/sidebar-style-large.png'"><xsl:text>cmd/lc_designerdialog.svg</xsl:text></xsl:when>
-<xsl:when test="$src1='sfx2/res/symphony/sidebar-style-small.png'"><xsl:text>cmd/sc_designerdialog.svg</xsl:text></xsl:when>
<xsl:when test="$src1='sfx2/res/symphony/sidebar-template-large.png'"><xsl:text>cmd/lc_slidemasterpage.svg</xsl:text></xsl:when>
-<xsl:when test="$src1='sfx2/res/symphony/sidebar-template-small.png'"><xsl:text>cmd/sc_slidemasterpage.svg</xsl:text></xsl:when>
<xsl:when test="$src1='startmath/res/at21717.png'"><xsl:text>cmd/lc_bold.svg</xsl:text></xsl:when>
<xsl:when test="$src1='startmath/res/at21718.png'"><xsl:text>cmd/lc_italic.svg</xsl:text></xsl:when>
<xsl:when test="$src1='startmath/res/at21719.png'"><xsl:text>cmd/lc_scaletext.svg</xsl:text></xsl:when>
@@ -2220,20 +2198,14 @@
<xsl:when test="$src1='cmd/sc_margins.png'"><xsl:text>cmd/sc_pagemargin.svg</xsl:text></xsl:when>
<xsl:when test="$src1='cmd/sc_namegroup.png'"><xsl:text>cmd/sc_definename.svg</xsl:text></xsl:when>
<xsl:when test="$src1='cmd/32/convertmenu.png'"><xsl:text>cmd/32/bezierconvert.svg</xsl:text></xsl:when>
-<xsl:when test="$src1='cmd/32/deleteshapehyperlink.png'"><xsl:text>cmd/32/removehyperlink.svg</xsl:text></xsl:when>
-<xsl:when test="$src1='cmd/32/editshapehyperlink.png'"><xsl:text>cmd/32/inserthyperlink.svg</xsl:text></xsl:when>
<xsl:when test="$src1='cmd/32/mirrormenu.png'"><xsl:text>cmd/32/rotateleft.svg</xsl:text></xsl:when>
<xsl:when test="$src1='cmd/32/openhyperlinkoncursor.png'"><xsl:text>cmd/32/inserthyperlink.svg</xsl:text></xsl:when>
<xsl:when test="$src1='cmd/32/rotateflipmenu.png'"><xsl:text>cmd/32/rotateleft.svg</xsl:text></xsl:when>
<xsl:when test="$src1='cmd/lc_convertmenu.png'"><xsl:text>cmd/lc_bezierconvert.svg</xsl:text></xsl:when>
-<xsl:when test="$src1='cmd/lc_deleteshapehyperlink.png'"><xsl:text>cmd/lc_removehyperlink.svg</xsl:text></xsl:when>
-<xsl:when test="$src1='cmd/lc_editshapehyperlink.png'"><xsl:text>cmd/lc_inserthyperlink.svg</xsl:text></xsl:when>
<xsl:when test="$src1='cmd/lc_mirrormenu.png'"><xsl:text>cmd/lc_rotateleft.svg</xsl:text></xsl:when>
<xsl:when test="$src1='cmd/lc_openhyperlinkoncursor.png'"><xsl:text>cmd/lc_inserthyperlink.svg</xsl:text></xsl:when>
<xsl:when test="$src1='cmd/lc_rotateflipmenu.png'"><xsl:text>cmd/lc_rotateleft.svg</xsl:text></xsl:when>
<xsl:when test="$src1='cmd/sc_convertmenu.png'"><xsl:text>cmd/sc_bezierconvert.svg</xsl:text></xsl:when>
-<xsl:when test="$src1='cmd/sc_deleteshapehyperlink.png'"><xsl:text>cmd/sc_removehyperlink.svg</xsl:text></xsl:when>
-<xsl:when test="$src1='cmd/sc_editshapehyperlink.png'"><xsl:text>cmd/sc_inserthyperlink.svg</xsl:text></xsl:when>
<xsl:when test="$src1='cmd/sc_mirrormenu.png'"><xsl:text>cmd/sc_rotateleft.svg</xsl:text></xsl:when>
<xsl:when test="$src1='cmd/sc_openhyperlinkoncursor.png'"><xsl:text>cmd/sc_inserthyperlink.svg</xsl:text></xsl:when>
<xsl:when test="$src1='cmd/sc_rotateflipmenu.png'"><xsl:text>cmd/sc_rotateleft.svg</xsl:text></xsl:when>
@@ -2291,6 +2263,9 @@
<xsl:when test="$src1='cmd/sc_librelogo-run.png'"><xsl:text>cmd/sc_runbasic.svg</xsl:text></xsl:when>
<xsl:when test="$src1='cmd/sc_librelogo-stop.png'"><xsl:text>cmd/sc_basicstop.svg</xsl:text></xsl:when>
<xsl:when test="$src1='cmd/sc_librelogo-translate.png'"><xsl:text>cmd/sc_editglossary.svg</xsl:text></xsl:when>
+<xsl:when test="$src1='cmd/32/redactionpreviewexport.png'"><xsl:text>cmd/32/exportdirecttopdf.svg</xsl:text></xsl:when>
+<xsl:when test="$src1='cmd/lc_redactionpreviewexport.png'"><xsl:text>cmd/lc_exportdirecttopdf.svg</xsl:text></xsl:when>
+<xsl:when test="$src1='cmd/sc_redactionpreviewexport.png'"><xsl:text>cmd/sc_exportdirecttopdf.svg</xsl:text></xsl:when>
<xsl:otherwise><xsl:value-of select="$src1"/></xsl:otherwise>
</xsl:choose>
</xsl:template>
diff --git a/perf/compare-logs.py b/perf/compare-logs.py
index 82e6d0c..90a60da 100755
--- a/perf/compare-logs.py
+++ b/perf/compare-logs.py
@@ -25,7 +25,8 @@
# in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
# instead of those above.
-import sys, os, getopt
+import sys, os
+import argparse
def readFile(url):
d = {}
@@ -37,35 +38,16 @@ def readFile(url):
d[key] = float(val)
return d
-def usage():
- message = """usage: {program} [option]..."
- -h | --help: print usage information
- --old=URL path to old file to be compared
- --new=URL path to new file to be comparted"""
-
- print(message.format(program = os.path.basename(sys.argv[0])))
-
-
if __name__ == "__main__":
- try:
- opts,args = getopt.getopt(sys.argv[1:], "o:n:h",
- ["old=", "new=", "help"])
- except getopt.GetoptError:
- usage()
- sys.exit(1)
+ parser = argparse.ArgumentParser()
+
+ parser.add_argument('--old', action='store', dest="old", required=True)
+ parser.add_argument('--new', action="store", dest="new", required=True)
- for opt, arg in opts:
- if opt in ('-h', '--help'):
- usage()
- sys.exit(1)
- elif opt in ('-o', '--old'):
- old_url = arg
- elif opt in ('-n', '--new'):
- new_url = arg
- else:
- usage()
- sys.exit(1)
+ results = parser.parse_args()
+ old_url = results.old
+ new_url = results.new
if not os.path.exists(old_url):
print("File " + old_url + " doesn't exist!")
diff --git a/perf/test-startup-time.py b/perf/test-startup-time.py
index d5b443c..49dca04 100755
--- a/perf/test-startup-time.py
+++ b/perf/test-startup-time.py
@@ -24,6 +24,8 @@
import argparse
import sys
import os
+import glob
+import shutil
import multiprocessing
import tempfile
import time
@@ -66,6 +68,13 @@ def kill_soffice():
print("Killing process: " + str(pid))
os.kill(pid, signal.SIGKILL)
+ # Also clean leftovers in /tmp
+ for filename in glob.glob("/tmp/OSL_PIPE_*"):
+ os.remove(filename)
+
+ for filename in glob.glob("/tmp/lu*.tmp"):
+ shutil.rmtree(filename)
+
def get_file_names(filesPath):
auxNames = []
for fileName in os.listdir(filesPath):
diff --git a/test-bugzilla-files/autogen.input b/test-bugzilla-files/autogen.input
index eb906c7..2bc1d4f 100644
--- a/test-bugzilla-files/autogen.input
+++ b/test-bugzilla-files/autogen.input
@@ -8,4 +8,5 @@
--without-java
--without-krb5
--without-gssapi
+--disable-cups
--disable-werror
diff --git a/test-bugzilla-files/zip.sh b/test-bugzilla-files/zip.sh
index b35117f..4808b43 100755
--- a/test-bugzilla-files/zip.sh
+++ b/test-bugzilla-files/zip.sh
@@ -19,8 +19,10 @@ num_of_excluded_file=$(< "/srv/crashtestdata/odfundiff_exclude_list.txt" wc -l)
previous_hash="$(cat /srv/crashtestdata/previous/hash.txt)"
rm -rf /srv/crashtestdata/logs/$SHA/odfundiff
cd /srv/crashtestdata/current/srv/crashtestdata/files/
+rm -f odfundiff.zip
zip -r -q odfundiff.zip */*.odfundiff
mv odfundiff.zip /srv/crashtestdata/logs/$SHA/.
+rm -f validation.zip
zip -r -q validation.zip */*.log
mv validation.zip /srv/crashtestdata/logs/$SHA/.
cd /srv/crashtestdata/logs/$SHA
@@ -33,6 +35,7 @@ cp ../exportCrashes.csv ../importCrash.csv ../odfundiff.csv ../validationErrors.
python analyze_logs.py
cp exportCrashes.csv importCrash.csv odfundiff.csv validationErrors.csv ../.
cd ..
+rm -f current.zip
zip -r current.zip $SHA/*
if [ -z "$CRASHTEST_NO_UPLOAD" ]; then
scp current.zip upload@gimli.documentfoundation.org:/srv/www/dev-builds.libreoffice.org/crashtest/.
diff --git a/uitest/mass-testing/calc.py b/uitest/mass-testing/calc.py
index b8c1879..ed11b82 100755
--- a/uitest/mass-testing/calc.py
+++ b/uitest/mass-testing/calc.py
@@ -8,40 +8,37 @@ import os
import signal
from uitest.framework import UITestCase
from libreoffice.uno.propertyvalue import mkPropertyValues
-import time
+from contextlib import contextmanager
#Max number of sheets to jump to
maxSheets = 10
class massTesting(UITestCase):
+ @contextmanager
def load_file(self):
#TODO: Ignore password protected files
fileName = os.environ["TESTFILENAME"]
- self.ui_test.create_doc_in_start_center("calc")
+ with self.ui_test.load_file(fileName) as document:
- self.ui_test.load_file(fileName)
- document = self.ui_test.get_component()
-
-
- # Ignore read-only or protected files
- if not hasattr(document, 'isReadonly') or document.isReadonly() or document.isProtected():
- print("mass-uitesting:skipped", flush=True)
- return
+ # Ignore read-only or protected files
+ if not hasattr(document, 'isReadonly') or document.isReadonly() or document.isProtected():
+ print("mass-uitesting:skipped", flush=True)
+ raise
- try:
- xDoc = self.xUITest.getTopFocusWindow()
- xEdit = xDoc.getChild("grid_window")
- except:
- #In case the mimetype is wrong and the file is open with another component
- print("mass-uitesting:skipped", flush=True)
- return
+ try:
+ xDoc = self.xUITest.getTopFocusWindow()
+ xEdit = xDoc.getChild("grid_window")
+ except:
+ #In case the mimetype is wrong and the file is open with another component
+ print("mass-uitesting:skipped", flush=True)
+ raise
- print("mass-uitesting:loaded", flush=True)
+ print("mass-uitesting:loaded", flush=True)
- return xEdit
+ yield xEdit
def go_to_first_sheet(self):
document = self.ui_test.get_component()
@@ -63,8 +60,7 @@ class massTesting(UITestCase):
return nrSheets
def test_remove_all_and_undo(self):
- xEdit = self.load_file()
- if xEdit:
+ with self.load_file() as xEdit:
nrSheets = self.go_to_first_sheet()
for i in range(nrSheets)[:maxSheets]:
@@ -74,11 +70,8 @@ class massTesting(UITestCase):
self.xUITest.executeCommand(".uno:Undo")
self.xUITest.executeCommand(".uno:JumpToNextTable")
- self.ui_test.close_doc()
-
def test_insert_column_and_undo(self):
- xEdit = self.load_file()
- if xEdit:
+ with self.load_file() as xEdit:
nrSheets = self.go_to_first_sheet()
for i in range(nrSheets)[:maxSheets]:
@@ -86,11 +79,8 @@ class massTesting(UITestCase):
self.xUITest.executeCommand(".uno:Undo")
self.xUITest.executeCommand(".uno:JumpToNextTable")
- self.ui_test.close_doc()
-
def test_insert_row_and_undo(self):
- xEdit = self.load_file()
- if xEdit:
+ with self.load_file() as xEdit:
nrSheets = self.go_to_first_sheet()
for i in range(nrSheets)[:maxSheets]:
@@ -98,11 +88,8 @@ class massTesting(UITestCase):
self.xUITest.executeCommand(".uno:Undo")
self.xUITest.executeCommand(".uno:JumpToNextTable")
- self.ui_test.close_doc()
-
def test_copy_all_paste_undo(self):
- xEdit = self.load_file()
- if xEdit:
+ with self.load_file() as xEdit:
nrSheets = self.go_to_first_sheet()
for i in range(nrSheets)[:maxSheets]:
@@ -110,19 +97,14 @@ class massTesting(UITestCase):
self.xUITest.executeCommand(".uno:Copy")
- for i in range(5):
- self.xUITest.executeCommand(".uno:Paste")
+ self.xUITest.executeCommand(".uno:Paste")
- for i in range(5):
- self.xUITest.executeCommand(".uno:Undo")
+ self.xUITest.executeCommand(".uno:Undo")
self.xUITest.executeCommand(".uno:JumpToNextTable")
- self.ui_test.close_doc()
-
def test_print_preview(self):
- xEdit = self.load_file()
- if xEdit:
+ with self.load_file() as xEdit:
nrSheets = self.go_to_first_sheet()
for i in range(nrSheets)[:maxSheets]:
@@ -132,11 +114,8 @@ class massTesting(UITestCase):
self.xUITest.getTopFocusWindow()
- self.ui_test.close_doc()
-
def test_hide_column_and_undo(self):
- xEdit = self.load_file()
- if xEdit:
+ with self.load_file() as xEdit:
nrSheets = self.go_to_first_sheet()
for i in range(nrSheets)[:maxSheets]:
@@ -144,11 +123,8 @@ class massTesting(UITestCase):
self.xUITest.executeCommand(".uno:Undo")
self.xUITest.executeCommand(".uno:JumpToNextTable")
- self.ui_test.close_doc()
-
def test_hide_row_and_undo(self):
- xEdit = self.load_file()
- if xEdit:
+ with self.load_file() as xEdit:
nrSheets = self.go_to_first_sheet()
for i in range(nrSheets)[:maxSheets]:
@@ -156,23 +132,17 @@ class massTesting(UITestCase):
self.xUITest.executeCommand(".uno:Undo")
self.xUITest.executeCommand(".uno:JumpToNextTable")
- self.ui_test.close_doc()
-
def test_copy_sheet_undo_delete_sheet(self):
- xEdit = self.load_file()
- if xEdit:
+ with self.load_file() as xEdit:
nrSheets = self.go_to_first_sheet()
ignoreSheets = 0
document = self.ui_test.get_component()
for i in range(nrSheets)[:maxSheets]:
#copy sheet, undo and delete
- self.ui_test.execute_dialog_through_command(".uno:Move")
- xDialog = self.xUITest.getTopFocusWindow()
- xCopy = xDialog.getChild("copy")
- xCopy.executeAction("CLICK", tuple())
- xOKBtn = xDialog.getChild("ok")
- self.ui_test.close_dialog_through_button(xOKBtn)
+ with self.ui_test.execute_dialog_through_command(".uno:Move") as xDialog:
+ xCopy = xDialog.getChild("copy")
+ xCopy.executeAction("CLICK", tuple())
self.xUITest.executeCommand(".uno:Undo")
@@ -184,18 +154,13 @@ class massTesting(UITestCase):
else:
#Do not delete the last sheet
if i < nrSheets - 1:
- self.ui_test.execute_dialog_through_command(".uno:Remove") #delete sheet
- xDialog = self.xUITest.getTopFocusWindow()
- xOKButton = xDialog.getChild("yes")
- xOKButton.executeAction("CLICK", tuple())
+ with self.ui_test.execute_dialog_through_command(".uno:Remove", close_button="yes"):
+ pass
self.assertEqual(document.Sheets.getCount(), 1 + ignoreSheets + len(range(nrSheets)[maxSheets + 1:]))
- self.ui_test.close_doc()
-
def test_change_text_formatting_and_undo(self):
- xEdit = self.load_file()
- if xEdit:
+ with self.load_file() as xEdit:
nrSheets = self.go_to_first_sheet()
document = self.ui_test.get_component()
@@ -245,5 +210,15 @@ class massTesting(UITestCase):
self.xUITest.executeCommand(".uno:JumpToNextTable")
- self.ui_test.close_doc()
+ def test_sidebar(self):
+ with self.load_file() as xEdit:
+ self.xUITest.executeCommand(".uno:Sidebar")
+
+ panels = [ "TextPropertyPanel", "StyleListPanel", "GalleryPanel", "ScNavigatorPanel", "ScFunctionsPanel" ]
+
+ for panel in panels:
+ xEdit.executeAction("SIDEBAR", mkPropertyValues({"PANEL": panel}))
+
+ self.xUITest.executeCommand(".uno:Sidebar")
+
# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/uitest/mass-testing/impress.py b/uitest/mass-testing/impress.py
index a2adcf6..a885d0a 100755
--- a/uitest/mass-testing/impress.py
+++ b/uitest/mass-testing/impress.py
@@ -7,43 +7,40 @@
import os
from uitest.framework import UITestCase
from libreoffice.uno.propertyvalue import mkPropertyValues
-import time
+from contextlib import contextmanager
class massTesting(UITestCase):
+ @contextmanager
def load_file(self):
#TODO: Ignore password protected files
fileName = os.environ["TESTFILENAME"]
- self.ui_test.create_doc_in_start_center("impress")
+ with self.ui_test.load_file(fileName) as document:
- self.ui_test.load_file(fileName)
- document = self.ui_test.get_component()
+ # Ignore read-only files
+ if not hasattr(document, 'isReadonly') or document.isReadonly():
+ print("mass-uitesting:skipped", flush=True)
+ raise
- # Ignore read-only files
- if not hasattr(document, 'isReadonly') or document.isReadonly():
- print("mass-uitesting:skipped", flush=True)
- return
+ # Go to the normal view
+ self.xUITest.executeCommand(".uno:NormalMultiPaneGUI")
- # Go to the normal view
- self.xUITest.executeCommand(".uno:NormalMultiPaneGUI")
+ try:
+ xDoc = self.xUITest.getTopFocusWindow()
+ xEdit = xDoc.getChild("impress_win")
+ except:
+ #In case the mimetype is wrong and the file is open with another component
+ print("mass-uitesting:skipped", flush=True)
+ raise
- try:
- xDoc = self.xUITest.getTopFocusWindow()
- xEdit = xDoc.getChild("impress_win")
- except:
- #In case the mimetype is wrong and the file is open with another component
- print("mass-uitesting:skipped", flush=True)
- return
-
- print("mass-uitesting:loaded", flush=True)
+ print("mass-uitesting:loaded", flush=True)
- return xEdit
+ yield xEdit
def test_copy_all_paste_undo(self):
- xEdit = self.load_file()
- if xEdit:
+ with self.load_file() as xEdit:
self.xUITest.executeCommand(".uno:SelectAll")
self.xUITest.executeCommand(".uno:Copy")
@@ -53,11 +50,9 @@ class massTesting(UITestCase):
for i in range(5):
self.xUITest.executeCommand(".uno:Undo")
- self.ui_test.close_doc()
def test_traverse_all_slides_and_delete_and_undo(self):
- xEdit = self.load_file()
- if xEdit:
+ with self.load_file() as xEdit:
document = self.ui_test.get_component()
slideCount = document.DrawPages.getCount()
@@ -69,11 +64,9 @@ class massTesting(UITestCase):
xEdit.executeAction("TYPE", mkPropertyValues({"KEYCODE":"DELETE"}))
self.xUITest.executeCommand(".uno:Undo")
- self.ui_test.close_doc()
def test_duplicate_all_slides_and_undo(self):
- xEdit = self.load_file()
- if xEdit:
+ with self.load_file() as xEdit:
# Go to the slide sorter view
self.xUITest.executeCommand(".uno:DiaMode")
@@ -85,11 +78,9 @@ class massTesting(UITestCase):
self.xUITest.executeCommand(".uno:DuplicatePage")
self.xUITest.executeCommand(".uno:Undo")
- self.ui_test.close_doc()
def test_remove_all_slides_and_undo(self):
- xEdit = self.load_file()
- if xEdit:
+ with self.load_file() as xEdit:
# Go to the slide sorter view
self.xUITest.executeCommand(".uno:DiaMode")
@@ -101,6 +92,16 @@ class massTesting(UITestCase):
xEdit.executeAction("TYPE", mkPropertyValues({"KEYCODE":"DELETE"}))
self.xUITest.executeCommand(".uno:Undo")
- self.ui_test.close_doc()
+
+ def test_sidebar(self):
+ with self.load_file() as xEdit:
+ # The sidebar is already displayed
+
+ panels = [ "TextPropertyPanel", "StyleListPanel", "GalleryPanel",
+ "SdNavigatorPanel", "DefaultShapesPanel", "SdSlideTransitionPanel",
+ "SdCustomAnimationPanel", "SdAllMasterPagesPanel" ]
+
+ for panel in panels:
+ xEdit.executeAction("SIDEBAR", mkPropertyValues({"PANEL": panel}))
# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/uitest/mass-testing/registrymodifications.xcu b/uitest/mass-testing/registrymodifications.xcu
index f992e48..55c7228 100644
--- a/uitest/mass-testing/registrymodifications.xcu
+++ b/uitest/mass-testing/registrymodifications.xcu
@@ -15,4 +15,5 @@
<item oor:path="/org.openoffice.Office.Writer/Cursor/Option"><prop oor:name="IgnoreProtectedArea" oor:op="fuse"><value>true</value></prop></item>
<item oor:path="/org.openoffice.Office.Impress/Misc/NewDoc"><prop oor:name="AutoPilot" oor:op="fuse"><value>false</value></prop></item>
<item oor:path="/org.openoffice.Office.Common/Misc"><prop oor:name="ShowTipOfTheDay" oor:op="fuse"><value>false</value></prop></item>
+<item oor:path="/org.openoffice.Office.Calc/Input"><prop oor:name="ReplaceCellsWarning" oor:op="fuse"><value>false</value></prop></item>
</oor:items>
diff --git a/uitest/mass-testing/run.py b/uitest/mass-testing/run.py
index 3acd8bc..1f6b884 100755
--- a/uitest/mass-testing/run.py
+++ b/uitest/mass-testing/run.py
@@ -7,6 +7,8 @@
import os
import argparse
+import glob
+import shutil
from subprocess import Popen, PIPE, TimeoutExpired
import sys
import signal
@@ -15,6 +17,7 @@ from shutil import copyfile
import time
import fcntl
import tempfile
+import magic
import multiprocessing
from multiprocessing_logging import install_mp_handler
@@ -45,6 +48,16 @@ def kill_soffice():
print("Killing process: " + str(pid))
os.kill(pid, signal.SIGKILL)
+ # Also clean leftovers in /tmp
+ for filename in glob.glob("/tmp/OSL_PIPE_*"):
+ os.remove(filename)
+
+ for filename in glob.glob("/tmp/lu*.tmp"):
+ if os.path.isfile(filename):
+ os.remove(filename)
+ else:
+ shutil.rmtree(filename)
+
def start_logger(name):
rootLogger = logging.getLogger()
rootLogger.setLevel(os.environ.get("LOGLEVEL", "INFO"))
@@ -65,7 +78,13 @@ def get_file_names(filesPath):
for key, val in extensions.items():
extension = os.path.splitext(fileName)[1][1:]
if extension in val:
- auxNames.append("file:///" + filesPath + fileName)
+ fullName = filesPath + fileName
+ mimetype = magic.from_file(fullName, mime=True)
+
+ # Ignore CSV files since they prompt the CSV import dialog
+ if mimetype == "application/csv":
+ continue
+ auxNames.append("file:///" + fullName)
#Remove previous lock files
lockFilePath = filesPath + '.~lock.' + fileName + '#'
@@ -228,6 +247,12 @@ if __name__ == '__main__':
"Copy uitest folder from LibreOffice codebase and paste it here")
sys.exit(1)
+ pythonPath = os.path.join(currentPath, 'python/')
+ if not os.path.exists(pythonPath):
+ print("ERROR: " + pythonPath + " doesn't exists. " + \
+ "Copy unotest/source/python/ folder from LibreOffice codebase and paste it here")
+ sys.exit(1)
+
parser = DefaultHelpParser()
parser.add_argument(
@@ -247,7 +272,7 @@ if __name__ == '__main__':
if not os.path.exists(sofficePath) or not sofficePath.endswith('/soffice'):
parser.error(sofficePath + " is an invalid LibreOffice path")
- os.environ["PYTHONPATH"] = sofficePath.split('/soffice')[0]
+ os.environ["PYTHONPATH"] = sofficePath.split('/soffice')[0] + os.pathsep + pythonPath
os.environ["URE_BOOTSTRAP"] = "file://" + sofficePath.split('/soffice')[0] + '/fundamentalrc'
os.environ["SAL_USE_VCLPLUGIN"] = "gen"
diff --git a/uitest/mass-testing/writer.py b/uitest/mass-testing/writer.py
index 9f93ed8..83ead78 100755
--- a/uitest/mass-testing/writer.py
+++ b/uitest/mass-testing/writer.py
@@ -8,40 +8,36 @@ import os
import signal
from uitest.framework import UITestCase
from libreoffice.uno.propertyvalue import mkPropertyValues
-import time
+from contextlib import contextmanager
class massTesting(UITestCase):
+ @contextmanager
def load_file(self):
#TODO: Ignore password protected files
fileName = os.environ["TESTFILENAME"]
- self.ui_test.create_doc_in_start_center("writer")
+ with self.ui_test.load_file(fileName) as document:
+ # Ignore read-only files
+ if not hasattr(document, 'isReadonly') or document.isReadonly():
+ print("mass-uitesting:skipped", flush=True)
+ raise
- self.ui_test.load_file(fileName)
- document = self.ui_test.get_component()
+ try:
+ xDoc = self.xUITest.getTopFocusWindow()
+ xEdit = xDoc.getChild("writer_edit")
+ except:
+ #In case the mimetype is wrong and the file is open with another component
+ print("mass-uitesting:skipped", flush=True)
+ raise
- # Ignore read-only files
- if not hasattr(document, 'isReadonly') or document.isReadonly():
- print("mass-uitesting:skipped", flush=True)
- return
+ print("mass-uitesting:loaded", flush=True)
- try:
- xDoc = self.xUITest.getTopFocusWindow()
- xEdit = xDoc.getChild("writer_edit")
- except:
- #In case the mimetype is wrong and the file is open with another component
- print("mass-uitesting:skipped", flush=True)
- return
-
- print("mass-uitesting:loaded", flush=True)
-
- return xEdit
+ yield xEdit
def test_remove_all_and_undo(self):
- xEdit = self.load_file()
- if xEdit:
+ with self.load_file() as xEdit:
self.xUITest.executeCommand(".uno:SelectAll")
self.xUITest.executeCommand(".uno:SelectAll")
self.xUITest.executeCommand(".uno:SelectAll")
@@ -49,33 +45,24 @@ class massTesting(UITestCase):
self.xUITest.executeCommand(".uno:Undo")
- self.ui_test.close_doc()
-
def test_insert_returns_and_undo(self):
- xEdit = self.load_file()
- if xEdit:
+ with self.load_file() as xEdit:
for i in range(60):
xEdit.executeAction("TYPE", mkPropertyValues({"KEYCODE":"RETURN"}))
for i in range(60):
self.xUITest.executeCommand(".uno:Undo")
- self.ui_test.close_doc()
-
def test_insert_pageBreaks_and_undo(self):
- xEdit = self.load_file()
- if xEdit:
+ with self.load_file() as xEdit:
for i in range(5):
self.xUITest.executeCommand(".uno:InsertPagebreak")
for i in range(5):
self.xUITest.executeCommand(".uno:Undo")
- self.ui_test.close_doc()
-
def test_copy_all_paste_undo(self):
- xEdit = self.load_file()
- if xEdit:
+ with self.load_file() as xEdit:
self.xUITest.executeCommand(".uno:SelectAll")
self.xUITest.executeCommand(".uno:SelectAll")
self.xUITest.executeCommand(".uno:SelectAll")
@@ -88,11 +75,8 @@ class massTesting(UITestCase):
for i in range(5):
self.xUITest.executeCommand(".uno:Undo")
- self.ui_test.close_doc()
-
def test_traverse_all_pages(self):
- xEdit = self.load_file()
- if xEdit:
+ with self.load_file() as xEdit:
document = self.ui_test.get_component()
pageCount = document.CurrentController.PageCount
@@ -102,6 +86,16 @@ class massTesting(UITestCase):
for i in range(pageCount):
xEdit.executeAction("TYPE", mkPropertyValues({"KEYCODE":"PAGEUP"}))
- self.ui_test.close_doc()
+ def test_sidebar(self):
+ with self.load_file() as xEdit:
+ self.xUITest.executeCommand(".uno:Sidebar")
+
+ panels = [ "TextPropertyPanel", "StyleListPanel", "GalleryPanel",
+ "SwNavigatorPanel", "PageFormatPanel", "InspectorTextPanel", "SwManageChangesPanel" ]
+
+ for panel in panels:
+ xEdit.executeAction("SIDEBAR", mkPropertyValues({"PANEL": panel}))
+
+ self.xUITest.executeCommand(".uno:Sidebar")
# vim: set shiftwidth=4 softtabstop=4 expandtab: