diff --git a/src/assets/options.css b/src/assets/options.css
deleted file mode 100644
index cbaae76..0000000
--- a/src/assets/options.css
+++ /dev/null
@@ -1,477 +0,0 @@
-#out {
- padding: 0px 10px;
- font-size: 13px;
- line-height: 26px;
- font-family: Monaco, consolas;
- white-space: pre-wrap;
-}
-
-#options {
- font-size: 15px;
- color: #595959;
- font-family: consolas, monaco, "微软雅黑";
- padding-bottom: 30px;
-}
-
-#options * {
- box-sizing: border-box;
-}
-
-#options .switch-btn {
- position: relative;
- display: inline-block;
- vertical-align: top;
- width: 80px;
- height: 30px;
- border-radius: 5px;
- cursor: pointer;
- zoom: 0.7;
-}
-
-#options .checked-switch {
- position: absolute;
- top: 0;
- left: 0;
- opacity: 0;
-}
-
-#options .text-switch {
- background-color: #cccccc;
- border: 1px solid #dddddd;
- border-radius: inherit;
- color: #fff;
- display: block;
- font-size: 15px;
- width: 60px;
- height: inherit;
- position: relative;
- text-transform: uppercase;
-}
-
-#options .text-switch:before,
-#options .text-switch:after {
- position: absolute;
- top: 50%;
- margin-top: -.5em;
- line-height: 1;
- -webkit-transition: inherit;
- -moz-transition: inherit;
- -o-transition: inherit;
- transition: inherit;
-}
-
-#options .text-switch:before {
- content: 'OF';
- right: 6px;
-}
-
-#options .text-switch:after {
- content: 'ON';
- left: 6px;
- color: #FFFFFF;
- opacity: 0;
-}
-
-#options .checked-switch:checked~.text-switch {
- background-color: #00af2c;
- border: 1px solid #068506;
-}
-
-#options .checked-switch:disabled~.text-switch {
- cursor: no-drop;
-}
-
-#options .checked-switch:disabled~.text-switch~.toggle-btn {
- cursor: no-drop;
-}
-
-#options .checked-switch:disabled~.text-switch:before {
- content: '▬';
- right: 11px;
-}
-
-#options .checked-switch:checked~.text-switch:before {
- opacity: 0;
-}
-
-#options .checked-switch:checked~.text-switch:after {
- opacity: 1;
-}
-
-#options .toggle-btn {
- background: linear-gradient(#eee, #fafafa);
- border-radius: 5px;
- height: 28px;
- left: 1px;
- position: absolute;
- top: 1px;
- width: 28px;
-}
-
-#options .checked-switch:checked~.toggle-btn {
- left: 30px;
-}
-
-#options .text-switch,
-#options .toggle-btn {
- transition: All 0.3s ease;
- -webkit-transition: All 0.3s ease;
- -moz-transition: All 0.3s ease;
- -o-transition: All 0.3s ease;
-}
-
-#options .no-radius,
-#options .no-radius .toggle-btn {
- border-radius: 0;
-}
-
-#options .circle-style .toggle-btn::before {
- background: linear-gradient(#dedede, #cacaca);
- border-radius: 50%;
- content: "";
- height: 14px;
- margin-top: 6px;
- padding: 0;
- width: 14px;
-}
-
-#options table {
- border-collapse: collapse;
- table-layout:fixed;
- width: 100%;
-}
-
-#options table td {
- border-collapse: collapse;
- padding: 3px;
- margin-right: 15px;
- word-break:keep-all;
- white-space:nowrap;
- overflow:hidden;
- text-overflow:ellipsis;
-}
-
-#options table tr:nth-child(odd) {
- background-color: #fff !important;
-}
-
-#options table tr:nth-child(even) {
- background-color: #f8f8f8 !important;
-}
-
-#options .keyword {
- display: inline-block;
- font-size: 14px;
- color: #333;
- border: 1px solid #eee;
- border-radius: 12px;
- height: 24px;
- line-height: 22px;
- padding: 0 10px;
- background-color: #f3f3f3;
- margin-right: 5px;
-}
-
-#options .keyword.re {
- color: rgb(105, 40, 97);
-}
-
-#options .keyword.win {
- color: rgb(48, 21, 122);
-}
-
-#options .logo {
- width: 32px;
-}
-
-#options #customize .keys{
- width: 16%;
-}
-
-#options #customize .robot.footBtn{
- background:#3085d6;
- float: none;
-}
-
-#options #customize .robot.footBtn:hover{
- background:#55aafa;
-}
-
-#options .footBtn {
- /* right: 5px;
- bottom: 2px; */
- float: right;
- background: #00af2c;
- border-radius: 4px;
- color: white;
- padding: 2px 5px;
- margin: 0px 5px;
- cursor: pointer;
-}
-
-#options .footBtn.danger {
- float: left;
- /* right: 5px;
- bottom: 2px; */
- border-radius: 4px;
- background: #df3f54;
- color: white;
- padding: 2px 5px;
- margin: 0px 5px;
- cursor: pointer;
-}
-
-#options .footBtn:hover {
- background: #068506;
- transition: 0.5s;
-}
-
-#options .footBtn.danger:hover {
- background: #b32033;
- transition: 0.5s;
-}
-
-#options .foot {
- position: fixed;
- height: 30px;
- right: 0px;
- bottom: 0px;
- left: 0px;
- background: #f3f3f3;
- box-shadow: 0px 0px 9px 0px #00000030;
- padding: 3px;
-}
-
-#options td span {
- margin-right: 10px;
-}
-
-#options span.Btn {
- font-size: 16px;
- cursor: pointer;
-}
-
-#options span.Btn img {
- height: 20px;
-}
-
-#options span.editBtn {
- color: #00af2c;
-}
-
-#options span.exportBtn {
- color: #407abf;
-}
-
-#options span.delBtn {
- color: #ed5b49
-}
-
-#options span.editBtn:hover {
- color: #057205;
-}
-
-#options span.exportBtn:hover {
- color: #2d5586;
-}
-
-#options span.delBtn:hover {
- color: #bd3523;
-}
-
-#options #customize input.customscript {
- margin-left: 5px;
- width: 20%;
- display: none;
-}
-
-#options #customize {
- position: fixed;
- z-index: 999;
- height: 100%;
- top: 100%;
- left: 0;
- right: 0;
- padding: 0px 30px;
- box-shadow: 0px 0px 9px 0px #00000030;
- color: black;
- background: white;
-}
-
-#options .varoutput{
- display: none;
-}
-
-#options #customize p {
- line-height: 1.25rem;
-}
-
-#options #customize .word {
- color: #2196F3;
- display: inline-block;
- font-size: 14px;
- border: 1px solid #1E88E5;
- height: 24px;
- line-height: 22px;
- padding: 0 5px;
- background-color: #E3F2FD;
-}
-
-#options #customize input {
- width: 90%;
- height: 25px;
- border-bottom: 1px solid #dbdbdb;
- border-top: 0px;
- border-left: 0px;
- border-right: 0px;
- font-size: 15px;
- margin-left: 13px
-}
-
-#options #customize input#rule {
- width: 40%;
-}
-
-#options #customize input:hover {
- border-bottom-color: #9e9e9ec7;
- transition: 0.25s;
-}
-
-#options #customize input:focus {
- outline: none;
- border-bottom-color: #0277BD;
- transition: 0.5s;
-}
-
-input::-webkit-input-placeholder {
- color: #999;
- font-size: 15px
-}
-
-#options #customize .CodeMirror {
- font-size: 13px;
- font-family: "Monaco", "consolas";
- width: 100%;
- height: 23rem;
- border: 1px solid #dbdbdb;
- border-radius: 3px;
-}
-
-
-#options #customize .CodeMirror:hover {
- border: 1px solid #9e9e9ec7;
- transition: 0.25s;
-}
-
-#options #customize .CodeMirror-focused {
- border: 1px solid #0277BD !important;
- box-shadow: 0px 0px 2px 0px #0277BD;
- transition: 0.25s;
-}
-
-#options #customize .CodeMirror-placeholder {
- color: #999;
- font-size: 15px
-}
-
-#options #customize select {
- width: 40%;
- height: 25px;
- margin-left: 3px;
- border-bottom: 1px solid #dbdbdb;
- border-top: 0px;
- border-left: 0px;
- border-right: 0px;
- background-color: #ffffff;
- border-radius: 0px;
- outline: none;
- font-size: 15px;
- background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAJAgMAAAB71iXHAAAADFBMVEUAAAAqPz8rN0csOEgGlpD7AAAAA3RSTlMABvwYJ91vAAAAGklEQVQI12OAgQNAaMDMwMAjw8DAVAAWgAEAPFADDsXseo4AAAAASUVORK5CYII=") no-repeat scroll right center transparent;
- -webkit-appearance: none
-}
-
-#options #customize select:hover {
- border-bottom-color: #9e9e9ec7;
- transition: 0.25s;
-}
-
-#options #customize select:focus {
- border-bottom-color: #0277BD;
- transition: 0.5s;
-}
-
-#options #customize select#vars,#action {
- color: #999;
-}
-
-#options #customize select option {
- color: black;
-}
-
-#options #customize select option.var {
- display: none;
- color: rgb(129, 76, 226);
-}
-
-#options #customize input#iconame {
- width: 35%;
- cursor: pointer;
-}
-
-#options #customize #icon {
- float: right;
- width: 28px;
- cursor: pointer;
-}
-
-#options #customize .selectBtn {
- padding: 4px 10px;
- font-size: 11px;
- color: #1E88C7;
- background: #D0EEFF;
- border: 1px solid #99D3F5;
- border-radius: 4px;
- cursor: pointer;
-}
-
-#options #customize .selectBtn:hover {
- background: #AADFFD;
- border-color: #78C3F3;
- color: #004974;
- transition: 0.5s;
-}
-
-#options #customize button {
- width: 150px;
- height: 30px;
- border-width: 0px;
- border-radius: 3px;
- cursor: pointer;
- outline: none;
- color: white;
-}
-
-#options #customize button.cancelBtn {
- float: right;
- margin-right: 30px;
- background: #808080c9;
-}
-
-#options #customize button.saveBtn {
- float: right;
- background: #1E90FF;
-}
-
-#options #customize button.saveBtn:hover {
- background: #5599FF;
- transition: 0.5s;
-}
-
-#options #customize button.cancelBtn:hover {
- background: #a5a2a2c9;
- transition: 0.5s;
-}
-
-::-webkit-scrollbar {
- height: 0;
-}
\ No newline at end of file
diff --git a/src/codemirror/.editorconfig b/src/assets/plugins/codemirror/.editorconfig
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/.editorconfig
rename to src/assets/plugins/codemirror/.editorconfig
diff --git a/src/codemirror/.gitattributes b/src/assets/plugins/codemirror/.gitattributes
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/.gitattributes
rename to src/assets/plugins/codemirror/.gitattributes
diff --git a/src/codemirror/.npmignore b/src/assets/plugins/codemirror/.npmignore
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/.npmignore
rename to src/assets/plugins/codemirror/.npmignore
diff --git a/src/codemirror/.travis.yml b/src/assets/plugins/codemirror/.travis.yml
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/.travis.yml
rename to src/assets/plugins/codemirror/.travis.yml
diff --git a/src/codemirror/AUTHORS b/src/assets/plugins/codemirror/AUTHORS
old mode 100755
new mode 100644
similarity index 92%
rename from src/codemirror/AUTHORS
rename to src/assets/plugins/codemirror/AUTHORS
index 0e4c895..f5b5d7a
--- a/src/codemirror/AUTHORS
+++ b/src/assets/plugins/codemirror/AUTHORS
@@ -20,6 +20,7 @@ aeroson
Ahmad Amireh
Ahmad M. Zawawi
ahoward
+Ajin Abraham
Akeksandr Motsjonov
Alasdair Smith
AlbertHilb
@@ -31,6 +32,7 @@ Alexander Schepanovski
Alexander Shvets
Alexander Solovyov
Alexandre Bique
+Alex Churchill
alexey-k
Alex Piggott
Aliaksei Chapyzhenka
@@ -72,11 +74,13 @@ anthonygego
Anthony Gégo
Anthony Grimes
Anton Kovalyov
+antosarho
Apollo Zhu
AQNOUCH Mohammed
Aram Shatakhtsyan
areos
Arnab Bose
+Arnoud Buzing
Arsène von Wyss
Arthur Müller
Arun Narasani
@@ -95,6 +99,9 @@ Bastian Müller
belhaj
Bem Jones-Bey
benbro
+Benedikt Meurer
+benhormann
+Ben Hormann
Beni Cherniavsky-Paskin
Benjamin DeCoste
Benjamin Young
@@ -115,21 +122,26 @@ Bo
boomyjee
Bo Peng
borawjm
+Boris K
Brad Metcalf
Brandon Frohs
Brandon Wamboldt
Bret Little
Brett Zamir
Brian Grinstead
+BrianHung
Brian Sletten
brrd
Bruce Mitchener
+Bruno Logerfo
+Bryan Gin-ge Chen
Bryan Massoth
Caitlin Potter
Calin Barbat
callodacity
Camilo Roca
Casey Klebba
+cBiscuit87
César González Íñiguez
Chad Jolly
Chandra Sekhar Pydi
@@ -156,6 +168,7 @@ Christopher Pfohl
Christopher Wallis
Chunliang Lyu
ciaranj
+clone-it
clso
CodeAnimal
CodeBitt
@@ -165,6 +178,7 @@ ComFreek
Cristian Prieto
Curran Kelleher
Curtis Gagliardi
+d8888
dagsta
daines
Dale Jung
@@ -192,16 +206,20 @@ David Barnett
David H. Bronke
David Mignot
David Pathakjee
+David Rodrigues
David Santana
David Vázquez
David Whittington
deebugger
Deep Thought
+Denis Ovsienko
Devin Abbott
Devon Carew
Dick Choi
+Diego Fernandez
dignifiedquire
Dimage Sapelkin
+Dinindu D. Wanniarachchi
dmaclach
Dmitry Kiselyov
domagoj412
@@ -214,12 +232,15 @@ Drew Hintz
Drew Khoury
Drini Cami
Dror BG
+Duncan Lilley
duralog
dwelle
eborden
+edoroshenko
edsharp
ekhaled
Elisée
+elpnt
Emmanuel Schanzer
Enam Mijbah Noor
Eric Allam
@@ -227,6 +248,7 @@ Eric Bogard
Erik Demaine
Erik Welander
eustas
+Evan Minsk
Fabien Dubosson
Fabien O'Carroll
Fabio Zendhi Nagao
@@ -243,11 +265,13 @@ Filype Pereira
finalfantasia
flack
Florian Felten
+Fons van der Plas
Forbes Lindesay
ForbesLindesay
Ford_Lawnmower
Forrest Oliphant
Franco Catena
+Frank Seifferth
Frank Wiegand
fraxx001
Fredrik Borg
@@ -278,20 +302,24 @@ Grant Skinner
greengiant
Gregory Koberger
Grzegorz Mazur
+Guang Li
Guan Gui
Guillaume Massé
Guillaume Massé
guraga
Gustavo Rodrigues
Hakan Tunc
+Hanno Fellmann
Hans Engel
Hanzhao Deng
Harald Schilly
Hardest
Harshvardhan Gupta
+Hasan Delibaş
Hasan Karahan
Heanes
Hector Oswaldo Caballero
+Hein Htat
Hélio
Hendrik Wallbaum
Henrik Haugbølle
@@ -304,13 +332,17 @@ Hugues Malphettes
Ian Beck
Ian Davies
Ian Dickinson
+ianhi
Ian Rose
Ian Wehrman
Ian Wetherbee
Ice White
ICHIKAWA, Yuji
idleberg
+Igor Petruk
ilvalle
+Ilya Kharlamov
+Ilya Zverev
Ingo Richter
Irakli Gozalishvili
Ivan Kurnosov
@@ -322,6 +354,7 @@ Jakob Miland
Jakub Vrana
Jakub Vrána
James Campos
+James Cockshull
James Howard
James Thorne
Jamie Hill
@@ -344,6 +377,7 @@ Jason Johnston
Jason San Jose
Jason Siefken
Jayaprabhakar
+Jay Contonio
Jaydeep Solanki
Jean Boussier
Jeff Blaisdell
@@ -363,10 +397,13 @@ Joel Einbinder
joelpinheiro
joewalsh
Johan Ask
+Johannes
+John Chen
John Connor
John-David Dalton
John Engler
John Lees-Miller
+John Ryan
John Snelson
John Van Der Loo
Jon Ander Peñalba
@@ -379,6 +416,7 @@ Jon Gacnik
jongalloway
Jon Malmaud
Jon Sangster
+Joo
Joost-Wim Boekesteijn
Joseph Pecoraro
Josh Barnes
@@ -403,6 +441,7 @@ karevn
Karol
Kayur Patel
Kazuhito Hokamura
+kcwiakala
Kees de Kooter
Kenan Christian Dimas
Ken Newman
@@ -422,6 +461,7 @@ koops
Kris Ciccarello
ks-ifware
kubelsmieci
+kvncp
KwanEsq
Kyle Kelley
KyleMcNutt
@@ -430,6 +470,7 @@ Lanfei
Lanny
laobubu
Laszlo Vidacs
+leaf
leaf corcoran
Lemmon
Leo Baschy
@@ -443,6 +484,7 @@ Lior Shub
LloydMilligan
LM
lochel
+Lonnie Abelbeck
Lorenzo Simionato
Lorenzo Stoakes
Louis Mauchet
@@ -473,6 +515,7 @@ Mário Gonçalves
Mario Pietsch
Mark Anderson
Mark Dalgleish
+Mark Hamstra
Mark Lentczner
Marko Bonaci
Mark Peace
@@ -491,11 +534,13 @@ mats cronqvist
Matt Gaide
Matthew Bauer
Matthew Beale
+Matthew Casperson
matthewhayes
Matthew Rathbone
Matthew Suozzo
Matthias Bussonnier
Matthias BUSSONNIER
+Mattia Astorino
Matt MacPherson
Matt McDonald
Matt Pass
@@ -505,10 +550,12 @@ Maximilian Hils
Maxim Kraev
Max Kirsch
Max Schaefer
+Max Wu
Max Xiantu
mbarkhau
McBrainy
mce2
+Mélanie Chauvel
melpon
meshuamam
Metatheos
@@ -576,14 +623,20 @@ Nikita Vasilyev
Nikolaj Kappler
Nikolay Kostov
nilp0inter
+Nils Knappmeier
Nisarg Jhaveri
nlwillia
noragrossman
Norman Rzepka
+Nouzbe
Oleksandr Yakovenko
+Olivia Ytterbrink
+Opender Singh
opl-
Oreoluwa Onatemowo
+oscar.lofwenhamn
Oskar Segersvärd
+ossdev
overdodactyl
pablo
pabloferz
@@ -596,6 +649,7 @@ paris
Paris
Paris Kasidiaris
Patil Arpith
+Patrick Kettner
Patrick Stoica
Patrick Strawderman
Paul Garvin
@@ -611,6 +665,7 @@ peter
Peter Flynn
peterkroon
Peter Kroon
+Peter László
Philipp A
Philipp Markovics
Philip Stadermann
@@ -621,6 +676,7 @@ Pontus Melke
prasanthj
Prasanth J
Prayag Verma
+prendota
Prendota
Qiang Li
Radek Piórkowski
@@ -634,6 +690,7 @@ Randy Luecke
Raphael Amorim
Rasmus Erik Voel Jensen
Rasmus Schultz
+raymondf
Raymond Hill
ray ratchup
Ray Ratchup
@@ -649,10 +706,14 @@ Robert Crossfield
Robert Martin
Roberto Abdelkader Martínez Pérez
robertop23
+Roberto Vidal
Robert Plummer
+Roman Janusz
Rrandom
Rrrandom
Ruslan Osmanov
+rvalavicius
+Ryan Pangrle
Ryan Petrello
Ryan Prior
ryu-sato
@@ -667,6 +728,7 @@ Sander Verweij
santec
Sarah McAlear and Wenlin Zhang
Sascha Peilicke
+Sasha Varlamov
satamas
satchmorun
sathyamoorthi
@@ -676,6 +738,7 @@ SCLINIC\jdecker
Scott Aikin
Scott Feeney
Scott Goodhew
+Seb35
Sebastian Wilzbach
Sebastian Zaha
Seren D
@@ -714,6 +777,7 @@ Stephen Lavelle
Steve Champagne
Steve Hoover
Steve O'Hara
+stockiNail
stoskov
Stryder Crown
Stu Kennedy
@@ -725,7 +789,9 @@ Tako Schotanus
Takuji Shimokawa
Takuya Matsuyama
Tarmil
+T. Brandon Ashley
TDaglis
+Teja
tel
Tentone
tfjgeorge
@@ -741,9 +807,11 @@ thomasmaclean
Thomas Schmid
Tim Alby
Tim Baumann
+Tim Gates
Timothy Farrell
Timothy Gu
Timothy Hatcher
+Tim van der Lippe
Tobias Bertelsen
TobiasBg
Todd Berman
@@ -765,9 +833,11 @@ TSUYUSATO Kitsune
Tugrul Elmas
twifkak
Tyler Long
+Tyler Makaro
Vadim Dyachenko
Vadzim Ramanenka
Vaibhav Sagar
+vamshi.revu
VapidWorx
Vestimir Markov
vf
@@ -791,6 +861,7 @@ Wojtek Ptak
wonderboyjon
Wu Cheng-Han
Xavier Mendez
+Yang Guo
Yassin N. Hassan
YNH Webdev
yoongu
@@ -802,5 +873,6 @@ Zachary Dremann
Zeno Rocha
Zhang Hao
Ziv
+zoobestik
zziuni
魏鹏刚
diff --git a/src/codemirror/CHANGELOG.md b/src/assets/plugins/codemirror/CHANGELOG.md
old mode 100755
new mode 100644
similarity index 91%
rename from src/codemirror/CHANGELOG.md
rename to src/assets/plugins/codemirror/CHANGELOG.md
index fb64003..a445dd9
--- a/src/codemirror/CHANGELOG.md
+++ b/src/assets/plugins/codemirror/CHANGELOG.md
@@ -1,3 +1,223 @@
+## 5.54.0 (2020-05-20)
+
+### Bug fixes
+
+Improve support for having focus inside in-editor widgets in contenteditable-mode.
+
+Fix issue where the scroll position could jump when clicking on a selection in Chrome.
+
+[python mode](https://codemirror.net/mode/python/): Better format string support.
+
+[javascript mode](https://codemirror.net/mode/javascript/): Improve parsing of private properties and class fields.
+
+[matchbrackets addon](https://codemirror.net/doc/manual.html#addon_matchbrackets): Disable highlighting when the editor doesn't have focus.
+
+### New features
+
+[runmode addon](https://codemirror.net/doc/manual.html#addon_runmode): Properly support for cross-line lookahead.
+
+[vim bindings](https://codemirror.net/demo/vim.html): Allow Ex-Commands with non-word names.
+
+[gfm mode](https://codemirror.net/mode/gfm/): Add a `fencedCodeBlockDefaultMode` option.
+
+## 5.53.2 (2020-04-21)
+
+### Bug fixes
+
+[show-hint addon](https://codemirror.net/doc/manual.html#addon_show-hint): Fix a regression that broke completion picking.
+
+## 5.53.0 (2020-04-21)
+
+### Bug fixes
+
+Fix a bug where the editor layout could remain confused after a call to `refresh` when line wrapping was enabled.
+
+[dialog addon](https://codemirror.net/doc/manual.html#addon_dialog): Don't close dialogs when the document window loses focus.
+
+[merge addon](https://codemirror.net/doc/manual.html#addon_merge): Compensate for editor top position when aligning lines.
+
+[vim bindings](https://codemirror.net/demo/vim.html): Improve EOL handling.
+
+[emacs bindings](https://codemirror.net/demo/emacs.html): Include default keymap as a fallback.
+
+[julia mode](https://codemirror.net/mode/julia/): Fix an infinite loop bug.
+
+[show-hint addon](https://codemirror.net/doc/manual.html#addon_show-hint): Scroll cursor into view when picking a completion.
+
+### New features
+
+New option: [`screenReaderLabel`](https://codemirror.net/doc/manual.html#option_screenReaderLabel) to add a label to the editor.
+
+New mode: [wast](https://codemirror.net/mode/wast/).
+
+## 5.52.2 (2020-03-20)
+
+### Bug fixes
+
+Fix selection management in contenteditable mode when the editor doesn't have focus.
+
+Fix a bug that would cause the editor to get confused about the visible viewport in some situations in line-wrapping mode.
+
+[markdown mode](https://codemirror.net/mode/markdown/): Don't treat single dashes as setext header markers.
+
+[zenburn theme](https://codemirror.net/demo/theme.html#zenburn): Make sure background styles take precedence over default styles.
+
+[css mode](https://codemirror.net/mode/css/): Recognize a number of new properties.
+
+## 5.52.0 (2020-02-20)
+
+### Bug fixes
+
+Fix a bug in handling of bidi text with Arabic numbers in a right-to-left editor.
+
+Fix a crash when combining file drop with a `"beforeChange"` filter.
+
+Prevent issue when passing negative coordinates to `scrollTo`.
+
+### New features
+
+[lint](https://codemirror.net/doc/manual.html#addon_lint) and [tern](https://codemirror.net/demo/tern.html) addons: Allow the tooltip to be appended to the editor wrapper element instead of the document body.
+
+## 5.51.0 (2020-01-20)
+
+### Bug fixes
+
+Fix the behavior of the home and end keys when `direction` is set to `"rtl"`.
+
+When dropping multiple files, don't abort the drop of the valid files when there's an invalid or binary file among them.
+
+Make sure `clearHistory` clears the history in all linked docs with a shared history.
+
+[vim bindings](https://codemirror.net/demo/vim.html): Fix behavior of `'` and `` ` `` marks, fix `R` in visual mode.
+
+### New features
+
+[vim bindings](https://codemirror.net/demo/vim.html): Support `gi`, `gI`, and `gJ`.
+
+## 5.50.2 (2020-01-01)
+
+### Bug fixes
+
+Fix bug that broke removal of line widgets.
+
+## 5.50.0 (2019-12-20)
+
+### Bug fixes
+
+Make Shift-Delete to cut work on Firefox.
+
+[closetag addon](https://codemirror.net/demo/closetag.html): Properly handle self-closing tags.
+
+[handlebars mode](https://codemirror.net/mode/handlebars/): Fix triple-brace support.
+
+[searchcursor addon](https://codemirror.net/doc/manual.html#addon_searchcursor): Support mathing `$` in reverse regexp search.
+
+[panel addon](https://codemirror.net/doc/manual.html#addon_panel): Don't get confused by changing panel sizes.
+
+[javascript-hint addon](https://codemirror.net/doc/manual.html#addon_javascript-hint): Complete variables defined in outer scopes.
+
+[sublime bindings](https://codemirror.net/demo/sublime.html): Make by-subword motion more consistent with Sublime Text.
+
+[julia mode](https://codemirror.net/mode/julia/): Don't break on zero-prefixed integers.
+
+[elm mode](https://codemirror.net/mode/elm/): Sync with upstream version.
+
+[sql mode](https://codemirror.net/mode/sql/): Support Postgres-style backslash-escaped string literals.
+
+### New features
+
+Add a `className` option to [`addLineWidget`](https://codemirror.net/doc/manual.html#addLineWidget).
+
+[foldcode addon](https://codemirror.net/doc/manual.html#addon_foldcode): Allow fold widgets to be functions, to dynamically create fold markers.
+
+New themes: [ayu-dark](https://codemirror.net/demo/theme.html#ayu-dark) and [ayu-mirage](https://codemirror.net/demo/theme.html#ayu-mirage).
+
+## 5.49.2 (2019-10-21)
+
+### Bug fixes
+
+[sublime bindings](https://codemirror.net/demo/sublime.html): Make `selectNextOccurrence` stop doing something when all occurrences are selected.
+
+[continuecomment addon](https://codemirror.net/doc/manual.html#addon_continuecomment): Respect `indentWithTabs` option.
+
+[foldgutter addon](https://codemirror.net/doc/manual.html#addon_foldgutter): Optimize by reusing DOM when possible.
+
+[markdown mode](https://codemirror.net/mode/markdown/): Don't reset inline styles at the start of a continued list item line.
+
+[clike mode](https://codemirror.net/mode/clike/): Add a configuration for Objective-C++.
+
+## 5.49.0 (2019-09-20)
+
+### Bug fixes
+
+[octave mode](https://codemirror.net/mode/octave/index.html): Don't mark common punctuation as error.
+
+[clike mode](https://codemirror.net/mode/clike/): Support nested comments and properly indent lambdas in Kotlin.
+
+[foldgutter](https://codemirror.net/doc/manual.html#addon_foldgutter) and [annotatescrollbar](https://codemirror.net/doc/manual.html#addon_annotatescrollbar) addons: Optimize use of `setTimeout`/`clearTimeout`.
+
+### New features
+
+New themes: [moxer](https://codemirror.net/demo/theme.html#moxer), [material-darker](https://codemirror.net/demo/theme.html#material-darker), [material-palenight](https://codemirror.net/demo/theme.html#material-palenight), [material-ocean](https://codemirror.net/demo/theme.html#material-ocean).
+
+[xml mode](https://codemirror.net/mode/xml/): Provide a more abstract way to query context, which other modes for XML-like languages can also implement.
+
+## 5.48.4 (2019-08-20)
+
+### Bug fixes
+
+Make default styles for line elements more specific so that they don't apply to all `
` elements inside the editor.
+
+Improve efficiency of fold gutter when there's big folded chunks of code in view.
+
+Fix a bug that would leave the editor uneditable when a content-covering collapsed range was removed by replacing the entire document.
+
+[julia mode](https://codemirror.net/mode/julia/): Support number separators.
+
+[asterisk mode](https://codemirror.net/mode/asterisk/): Improve comment support.
+
+[handlebars mode](https://codemirror.net/mode/handlebars/): Support triple-brace tags.
+
+## 5.48.2 (2019-07-20)
+
+### Bug fixes
+
+[vim bindings](https://codemirror.net/demo/vim.html): Adjust char escape substitution to match vim, support `&/$0`.
+
+[search addon](https://codemirror.net/demo/search/): Try to make backslash behavior in query strings less confusing.
+
+[javascript mode](https://codemirror.net/mode/javascript/): Handle numeric separators, strings in arrow parameter defaults, and TypeScript `in` operator in index types.
+
+[sparql mode](https://codemirror.net/mode/sparql/index.html): Allow non-ASCII identifier characters.
+
+## 5.48.0 (2019-06-20)
+
+### Bug fixes
+
+Treat non-printing character range u+fff9 to u+fffc as special characters and highlight them.
+
+[show-hint addon](https://codemirror.net/doc/manual.html#addon_show-hint): Fix positioning when the dialog is placed in a scrollable container.
+
+### New features
+
+Add [`selectLeft`](https://codemirror.net/doc/manual.html#mark_selectLeft)/[`selectRight`](https://codemirror.net/doc/manual.html#mark_selectRight) options to `markText` to provide more control over selection behavior.
+
+## 5.47.0 (2019-05-21)
+
+### Bug fixes
+
+[python mode](https://codemirror.net/mode/python/): Properly handle `...` syntax.
+
+[ruby mode](https://codemirror.net/mode/ruby): Fix indenting before closing brackets.
+
+[vim bindings](https://codemirror.net/demo/vim.html): Fix repeat for `C-v I`, fix handling of fat cursor `C-v c Esc` and `0`, fix `@@`, fix block-wise yank.
+
+### New features
+
+[vim bindings](https://codemirror.net/demo/vim.html): Add support for `` ` `` text object.
+
+## 5.46.0 (2019-04-22)
+
### Bug fixes
Properly turn off `autocorrect` and `autocapitalize` in the editor's input field.
@@ -12,7 +232,7 @@ Remove a legacy key code for delete that is used for F16 on keyboards that have
### New features
-Allow [gutters](https://codemirror.net/doc/manual.html#option_gutters) to specify direct CSS stings.
+Allow [gutters](https://codemirror.net/doc/manual.html#option_gutters) to specify direct CSS strings.
## 5.45.0 (2019-03-20)
diff --git a/src/codemirror/CONTRIBUTING.md b/src/assets/plugins/codemirror/CONTRIBUTING.md
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/CONTRIBUTING.md
rename to src/assets/plugins/codemirror/CONTRIBUTING.md
diff --git a/src/codemirror/LICENSE b/src/assets/plugins/codemirror/LICENSE
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/LICENSE
rename to src/assets/plugins/codemirror/LICENSE
diff --git a/src/codemirror/README.md b/src/assets/plugins/codemirror/README.md
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/README.md
rename to src/assets/plugins/codemirror/README.md
diff --git a/src/codemirror/addon/comment/comment.js b/src/assets/plugins/codemirror/addon/comment/comment.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/addon/comment/comment.js
rename to src/assets/plugins/codemirror/addon/comment/comment.js
diff --git a/src/assets/plugins/codemirror/addon/comment/continuecomment.js b/src/assets/plugins/codemirror/addon/comment/continuecomment.js
new file mode 100644
index 0000000..7ca1b4a
--- /dev/null
+++ b/src/assets/plugins/codemirror/addon/comment/continuecomment.js
@@ -0,0 +1,114 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: https://codemirror.net/LICENSE
+
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
+ mod(require("../../lib/codemirror"));
+ else if (typeof define == "function" && define.amd) // AMD
+ define(["../../lib/codemirror"], mod);
+ else // Plain browser env
+ mod(CodeMirror);
+})(function(CodeMirror) {
+ var nonspace = /\S/g;
+ var repeat = String.prototype.repeat || function (n) { return Array(n + 1).join(this); };
+ function continueComment(cm) {
+ if (cm.getOption("disableInput")) return CodeMirror.Pass;
+ var ranges = cm.listSelections(), mode, inserts = [];
+ for (var i = 0; i < ranges.length; i++) {
+ var pos = ranges[i].head
+ if (!/\bcomment\b/.test(cm.getTokenTypeAt(pos))) return CodeMirror.Pass;
+ var modeHere = cm.getModeAt(pos)
+ if (!mode) mode = modeHere;
+ else if (mode != modeHere) return CodeMirror.Pass;
+
+ var insert = null, line, found;
+ var blockStart = mode.blockCommentStart, lineCmt = mode.lineComment;
+ if (blockStart && mode.blockCommentContinue) {
+ line = cm.getLine(pos.line);
+ var end = line.lastIndexOf(mode.blockCommentEnd, pos.ch - mode.blockCommentEnd.length);
+ // 1. if this block comment ended
+ // 2. if this is actually inside a line comment
+ if (end != -1 && end == pos.ch - mode.blockCommentEnd.length ||
+ lineCmt && (found = line.lastIndexOf(lineCmt, pos.ch - 1)) > -1 &&
+ /\bcomment\b/.test(cm.getTokenTypeAt({line: pos.line, ch: found + 1}))) {
+ // ...then don't continue it
+ } else if (pos.ch >= blockStart.length &&
+ (found = line.lastIndexOf(blockStart, pos.ch - blockStart.length)) > -1 &&
+ found > end) {
+ // reuse the existing leading spaces/tabs/mixed
+ // or build the correct indent using CM's tab/indent options
+ if (nonspaceAfter(0, line) >= found) {
+ insert = line.slice(0, found);
+ } else {
+ var tabSize = cm.options.tabSize, numTabs;
+ found = CodeMirror.countColumn(line, found, tabSize);
+ insert = !cm.options.indentWithTabs ? repeat.call(" ", found) :
+ repeat.call("\t", (numTabs = Math.floor(found / tabSize))) +
+ repeat.call(" ", found - tabSize * numTabs);
+ }
+ } else if ((found = line.indexOf(mode.blockCommentContinue)) > -1 &&
+ found <= pos.ch &&
+ found <= nonspaceAfter(0, line)) {
+ insert = line.slice(0, found);
+ }
+ if (insert != null) insert += mode.blockCommentContinue
+ }
+ if (insert == null && lineCmt && continueLineCommentEnabled(cm)) {
+ if (line == null) line = cm.getLine(pos.line);
+ found = line.indexOf(lineCmt);
+ // cursor at pos 0, line comment also at pos 0 => shift it down, don't continue
+ if (!pos.ch && !found) insert = "";
+ // continue only if the line starts with an optional space + line comment
+ else if (found > -1 && nonspaceAfter(0, line) >= found) {
+ // don't continue if there's only space(s) after cursor or the end of the line
+ insert = nonspaceAfter(pos.ch, line) > -1;
+ // but always continue if the next line starts with a line comment too
+ if (!insert) {
+ var next = cm.getLine(pos.line + 1) || '',
+ nextFound = next.indexOf(lineCmt);
+ insert = nextFound > -1 && nonspaceAfter(0, next) >= nextFound || null;
+ }
+ if (insert) {
+ insert = line.slice(0, found) + lineCmt +
+ line.slice(found + lineCmt.length).match(/^\s*/)[0];
+ }
+ }
+ }
+ if (insert == null) return CodeMirror.Pass;
+ inserts[i] = "\n" + insert;
+ }
+
+ cm.operation(function() {
+ for (var i = ranges.length - 1; i >= 0; i--)
+ cm.replaceRange(inserts[i], ranges[i].from(), ranges[i].to(), "+insert");
+ });
+ }
+
+ function nonspaceAfter(ch, str) {
+ nonspace.lastIndex = ch;
+ var m = nonspace.exec(str);
+ return m ? m.index : -1;
+ }
+
+ function continueLineCommentEnabled(cm) {
+ var opt = cm.getOption("continueComments");
+ if (opt && typeof opt == "object")
+ return opt.continueLineComment !== false;
+ return true;
+ }
+
+ CodeMirror.defineOption("continueComments", null, function(cm, val, prev) {
+ if (prev && prev != CodeMirror.Init)
+ cm.removeKeyMap("continueComment");
+ if (val) {
+ var key = "Enter";
+ if (typeof val == "string")
+ key = val;
+ else if (typeof val == "object" && val.key)
+ key = val.key;
+ var map = {name: "continueComment"};
+ map[key] = continueComment;
+ cm.addKeyMap(map);
+ }
+ });
+});
diff --git a/src/codemirror/addon/dialog/dialog.css b/src/assets/plugins/codemirror/addon/dialog/dialog.css
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/addon/dialog/dialog.css
rename to src/assets/plugins/codemirror/addon/dialog/dialog.css
diff --git a/src/codemirror/addon/dialog/dialog.js b/src/assets/plugins/codemirror/addon/dialog/dialog.js
old mode 100755
new mode 100644
similarity index 97%
rename from src/codemirror/addon/dialog/dialog.js
rename to src/assets/plugins/codemirror/addon/dialog/dialog.js
index 23b06a8..5f1f4aa
--- a/src/codemirror/addon/dialog/dialog.js
+++ b/src/assets/plugins/codemirror/addon/dialog/dialog.js
@@ -82,7 +82,9 @@
if (e.keyCode == 13) callback(inp.value, e);
});
- if (options.closeOnBlur !== false) CodeMirror.on(inp, "blur", close);
+ if (options.closeOnBlur !== false) CodeMirror.on(dialog, "focusout", function (evt) {
+ if (evt.relatedTarget !== null) close();
+ });
} else if (button = dialog.getElementsByTagName("button")[0]) {
CodeMirror.on(button, "click", function() {
close();
diff --git a/src/codemirror/addon/display/autorefresh.js b/src/assets/plugins/codemirror/addon/display/autorefresh.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/addon/display/autorefresh.js
rename to src/assets/plugins/codemirror/addon/display/autorefresh.js
diff --git a/src/codemirror/addon/display/fullscreen.css b/src/assets/plugins/codemirror/addon/display/fullscreen.css
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/addon/display/fullscreen.css
rename to src/assets/plugins/codemirror/addon/display/fullscreen.css
diff --git a/src/codemirror/addon/display/fullscreen.js b/src/assets/plugins/codemirror/addon/display/fullscreen.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/addon/display/fullscreen.js
rename to src/assets/plugins/codemirror/addon/display/fullscreen.js
diff --git a/src/codemirror/addon/display/panel.js b/src/assets/plugins/codemirror/addon/display/panel.js
old mode 100755
new mode 100644
similarity index 74%
rename from src/codemirror/addon/display/panel.js
rename to src/assets/plugins/codemirror/addon/display/panel.js
index 5faf1d5..4c9f2c0
--- a/src/codemirror/addon/display/panel.js
+++ b/src/assets/plugins/codemirror/addon/display/panel.js
@@ -1,15 +1,15 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
-(function(mod) {
+(function (mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
-})(function(CodeMirror) {
- CodeMirror.defineExtension("addPanel", function(node, options) {
+})(function (CodeMirror) {
+ CodeMirror.defineExtension("addPanel", function (node, options) {
options = options || {};
if (!this.state.panels) initPanels(this);
@@ -25,8 +25,7 @@
wrapper.insertBefore(node, options.before.node);
} else if (replace) {
wrapper.insertBefore(node, options.replace.node);
- info.panels++;
- options.replace.clear();
+ options.replace.clear(true);
} else if (options.position == "bottom") {
wrapper.appendChild(node);
} else if (options.position == "before-bottom") {
@@ -38,14 +37,15 @@
}
var height = (options && options.height) || node.offsetHeight;
- this._setSize(null, info.heightLeft -= height);
- if (!replace) {
- info.panels++;
- }
- if (options.stable && isAtTop(this, node))
- this.scrollTo(null, this.getScrollInfo().top + height)
- return new Panel(this, node, options, height);
+ var panel = new Panel(this, node, options, height);
+ info.panels.push(panel);
+
+ this.setSize();
+ if (options.stable && isAtTop(this, node))
+ this.scrollTo(null, this.getScrollInfo().top + height);
+
+ return panel;
});
function Panel(cm, node, options, height) {
@@ -56,22 +56,23 @@
this.cleared = false;
}
- Panel.prototype.clear = function() {
+ /* when skipRemove is true, clear() was called from addPanel().
+ * Thus removePanels() should not be called (issue 5518) */
+ Panel.prototype.clear = function (skipRemove) {
if (this.cleared) return;
this.cleared = true;
var info = this.cm.state.panels;
- this.cm._setSize(null, info.heightLeft += this.height);
+ info.panels.splice(info.panels.indexOf(this), 1);
+ this.cm.setSize();
if (this.options.stable && isAtTop(this.cm, this.node))
this.cm.scrollTo(null, this.cm.getScrollInfo().top - this.height)
info.wrapper.removeChild(this.node);
- if (--info.panels == 0) removePanels(this.cm);
+ if (info.panels.length == 0 && !skipRemove) removePanels(this.cm);
};
- Panel.prototype.changed = function(height) {
- var newHeight = height == null ? this.node.offsetHeight : height;
- var info = this.cm.state.panels;
- this.cm._setSize(null, info.heightLeft -= (newHeight - this.height));
- this.height = newHeight;
+ Panel.prototype.changed = function () {
+ this.height = this.node.getBoundingClientRect().height;
+ this.cm.setSize();
};
function initPanels(cm) {
@@ -80,8 +81,7 @@
var height = parseInt(style.height);
var info = cm.state.panels = {
setHeight: wrap.style.height,
- heightLeft: height,
- panels: 0,
+ panels: [],
wrapper: document.createElement("div")
};
wrap.parentNode.insertBefore(info.wrapper, wrap);
@@ -90,8 +90,8 @@
if (hasFocus) cm.focus();
cm._setSize = cm.setSize;
- if (height != null) cm.setSize = function(width, newHeight) {
- if (newHeight == null) return this._setSize(width, newHeight);
+ if (height != null) cm.setSize = function (width, newHeight) {
+ if (!newHeight) newHeight = info.wrapper.offsetHeight;
info.setHeight = newHeight;
if (typeof newHeight != "number") {
var px = /^(\d+\.?\d*)px$/.exec(newHeight);
@@ -100,10 +100,12 @@
} else {
info.wrapper.style.height = newHeight;
newHeight = info.wrapper.offsetHeight;
- info.wrapper.style.height = "";
}
}
- cm._setSize(width, info.heightLeft += (newHeight - height));
+ var editorheight = newHeight - info.panels
+ .map(function (p) { return p.node.getBoundingClientRect().height; })
+ .reduce(function (a, b) { return a + b; }, 0);
+ cm._setSize(width, editorheight);
height = newHeight;
};
}
diff --git a/src/codemirror/addon/display/placeholder.js b/src/assets/plugins/codemirror/addon/display/placeholder.js
old mode 100755
new mode 100644
similarity index 96%
rename from src/codemirror/addon/display/placeholder.js
rename to src/assets/plugins/codemirror/addon/display/placeholder.js
index 1a3fa33..4eabe3d
--- a/src/codemirror/addon/display/placeholder.js
+++ b/src/assets/plugins/codemirror/addon/display/placeholder.js
@@ -39,7 +39,7 @@
var elt = cm.state.placeholder = document.createElement("pre");
elt.style.cssText = "height: 0; overflow: visible";
elt.style.direction = cm.getOption("direction");
- elt.className = "CodeMirror-placeholder";
+ elt.className = "CodeMirror-placeholder CodeMirror-line-like";
var placeHolder = cm.getOption("placeholder")
if (typeof placeHolder == "string") placeHolder = document.createTextNode(placeHolder)
elt.appendChild(placeHolder)
diff --git a/src/codemirror/addon/display/rulers.js b/src/assets/plugins/codemirror/addon/display/rulers.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/addon/display/rulers.js
rename to src/assets/plugins/codemirror/addon/display/rulers.js
diff --git a/src/codemirror/addon/edit/closebrackets.js b/src/assets/plugins/codemirror/addon/edit/closebrackets.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/addon/edit/closebrackets.js
rename to src/assets/plugins/codemirror/addon/edit/closebrackets.js
diff --git a/src/codemirror/addon/edit/closetag.js b/src/assets/plugins/codemirror/addon/edit/closetag.js
old mode 100755
new mode 100644
similarity index 86%
rename from src/codemirror/addon/edit/closetag.js
rename to src/assets/plugins/codemirror/addon/edit/closetag.js
index e5e83bc..b8cbf95
--- a/src/codemirror/addon/edit/closetag.js
+++ b/src/assets/plugins/codemirror/addon/edit/closetag.js
@@ -60,22 +60,23 @@
if (!ranges[i].empty()) return CodeMirror.Pass;
var pos = ranges[i].head, tok = cm.getTokenAt(pos);
var inner = CodeMirror.innerMode(cm.getMode(), tok.state), state = inner.state;
- if (inner.mode.name != "xml" || !state.tagName) return CodeMirror.Pass;
+ var tagInfo = inner.mode.xmlCurrentTag && inner.mode.xmlCurrentTag(state)
+ var tagName = tagInfo && tagInfo.name
+ if (!tagName) return CodeMirror.Pass
var html = inner.mode.configuration == "html";
var dontCloseTags = (typeof opt == "object" && opt.dontCloseTags) || (html && htmlDontClose);
var indentTags = (typeof opt == "object" && opt.indentTags) || (html && htmlIndent);
- var tagName = state.tagName;
if (tok.end > pos.ch) tagName = tagName.slice(0, tagName.length - tok.end + pos.ch);
var lowerTagName = tagName.toLowerCase();
// Don't process the '>' at the end of an end-tag or self-closing tag
if (!tagName ||
tok.type == "string" && (tok.end != pos.ch || !/[\"\']/.test(tok.string.charAt(tok.string.length - 1)) || tok.string.length == 1) ||
- tok.type == "tag" && state.type == "closeTag" ||
- tok.string.indexOf("/") == (tok.string.length - 1) || // match something like
+ tok.type == "tag" && tagInfo.close ||
+ tok.string.indexOf("/") == (pos.ch - tok.start - 1) || // match something like
dontCloseTags && indexOf(dontCloseTags, lowerTagName) > -1 ||
- closingTagExists(cm, tagName, pos, state, true))
+ closingTagExists(cm, inner.mode.xmlCurrentContext && inner.mode.xmlCurrentContext(state) || [], tagName, pos, true))
return CodeMirror.Pass;
var emptyTags = typeof opt == "object" && opt.emptyTags;
@@ -120,19 +121,16 @@
// when completing in JS/CSS snippet in htmlmixed mode. Does not
// work for other XML embedded languages (there is no general
// way to go from a mixed mode to its current XML state).
- var replacement;
- if (inner.mode.name != "xml") {
- if (cm.getMode().name == "htmlmixed" && inner.mode.name == "javascript")
- replacement = head + "script";
- else if (cm.getMode().name == "htmlmixed" && inner.mode.name == "css")
- replacement = head + "style";
- else
- return CodeMirror.Pass;
+ var replacement, mixed = inner.mode.name != "xml" && cm.getMode().name == "htmlmixed"
+ if (mixed && inner.mode.name == "javascript") {
+ replacement = head + "script";
+ } else if (mixed && inner.mode.name == "css") {
+ replacement = head + "style";
} else {
- if (!state.context || !state.context.tagName ||
- closingTagExists(cm, state.context.tagName, pos, state))
+ var context = inner.mode.xmlCurrentContext && inner.mode.xmlCurrentContext(state)
+ if (!context || (context.length && closingTagExists(cm, context, context[context.length - 1], pos)))
return CodeMirror.Pass;
- replacement = head + state.context.tagName;
+ replacement = head + context[context.length - 1]
}
if (cm.getLine(pos.line).charAt(tok.end) != ">") replacement += ">";
replacements[i] = replacement;
@@ -162,16 +160,19 @@
// If xml-fold is loaded, we use its functionality to try and verify
// whether a given tag is actually unclosed.
- function closingTagExists(cm, tagName, pos, state, newTag) {
+ function closingTagExists(cm, context, tagName, pos, newTag) {
if (!CodeMirror.scanForClosingTag) return false;
var end = Math.min(cm.lastLine() + 1, pos.line + 500);
var nextClose = CodeMirror.scanForClosingTag(cm, pos, null, end);
if (!nextClose || nextClose.tag != tagName) return false;
- var cx = state.context;
// If the immediate wrapping context contains onCx instances of
// the same tag, a closing tag only exists if there are at least
// that many closing tags of that type following.
- for (var onCx = newTag ? 1 : 0; cx && cx.tagName == tagName; cx = cx.prev) ++onCx;
+ var onCx = newTag ? 1 : 0
+ for (var i = context.length - 1; i >= 0; i--) {
+ if (context[i] == tagName) ++onCx
+ else break
+ }
pos = nextClose.to;
for (var i = 1; i < onCx; i++) {
var next = CodeMirror.scanForClosingTag(cm, pos, null, end);
diff --git a/src/codemirror/addon/edit/continuelist.js b/src/assets/plugins/codemirror/addon/edit/continuelist.js
old mode 100755
new mode 100644
similarity index 95%
rename from src/codemirror/addon/edit/continuelist.js
rename to src/assets/plugins/codemirror/addon/edit/continuelist.js
index fb5f037..2e5625a
--- a/src/codemirror/addon/edit/continuelist.js
+++ b/src/assets/plugins/codemirror/addon/edit/continuelist.js
@@ -41,7 +41,9 @@
return;
}
if (emptyListRE.test(line)) {
- if (!/>\s*$/.test(line)) cm.replaceRange("", {
+ var endOfQuote = inQuote && />\s*$/.test(line)
+ var endOfList = !/>\s*$/.test(line)
+ if (endOfQuote || endOfList) cm.replaceRange("", {
line: pos.line, ch: 0
}, {
line: pos.line, ch: pos.ch + 1
diff --git a/src/codemirror/addon/edit/matchbrackets.js b/src/assets/plugins/codemirror/addon/edit/matchbrackets.js
old mode 100755
new mode 100644
similarity index 97%
rename from src/codemirror/addon/edit/matchbrackets.js
rename to src/assets/plugins/codemirror/addon/edit/matchbrackets.js
index 2a14728..2c47e07
--- a/src/codemirror/addon/edit/matchbrackets.js
+++ b/src/assets/plugins/codemirror/addon/edit/matchbrackets.js
@@ -118,16 +118,24 @@
}
CodeMirror.defineOption("matchBrackets", false, function(cm, val, old) {
- if (old && old != CodeMirror.Init) {
- cm.off("cursorActivity", doMatchBrackets);
+ function clear(cm) {
if (cm.state.matchBrackets && cm.state.matchBrackets.currentlyHighlighted) {
cm.state.matchBrackets.currentlyHighlighted();
cm.state.matchBrackets.currentlyHighlighted = null;
}
}
+
+ if (old && old != CodeMirror.Init) {
+ cm.off("cursorActivity", doMatchBrackets);
+ cm.off("focus", doMatchBrackets)
+ cm.off("blur", clear)
+ clear(cm);
+ }
if (val) {
cm.state.matchBrackets = typeof val == "object" ? val : {};
cm.on("cursorActivity", doMatchBrackets);
+ cm.on("focus", doMatchBrackets)
+ cm.on("blur", clear)
}
});
diff --git a/src/codemirror/addon/edit/matchtags.js b/src/assets/plugins/codemirror/addon/edit/matchtags.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/addon/edit/matchtags.js
rename to src/assets/plugins/codemirror/addon/edit/matchtags.js
diff --git a/src/codemirror/addon/edit/trailingspace.js b/src/assets/plugins/codemirror/addon/edit/trailingspace.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/addon/edit/trailingspace.js
rename to src/assets/plugins/codemirror/addon/edit/trailingspace.js
diff --git a/src/codemirror/addon/fold/brace-fold.js b/src/assets/plugins/codemirror/addon/fold/brace-fold.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/addon/fold/brace-fold.js
rename to src/assets/plugins/codemirror/addon/fold/brace-fold.js
diff --git a/src/codemirror/addon/fold/comment-fold.js b/src/assets/plugins/codemirror/addon/fold/comment-fold.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/addon/fold/comment-fold.js
rename to src/assets/plugins/codemirror/addon/fold/comment-fold.js
diff --git a/src/codemirror/addon/fold/foldcode.js b/src/assets/plugins/codemirror/addon/fold/foldcode.js
old mode 100755
new mode 100644
similarity index 96%
rename from src/codemirror/addon/fold/foldcode.js
rename to src/assets/plugins/codemirror/addon/fold/foldcode.js
index e146fb9..887df3f
--- a/src/codemirror/addon/fold/foldcode.js
+++ b/src/assets/plugins/codemirror/addon/fold/foldcode.js
@@ -42,7 +42,7 @@
}
if (!range || range.cleared || force === "unfold") return;
- var myWidget = makeWidget(cm, options);
+ var myWidget = makeWidget(cm, options, range);
CodeMirror.on(myWidget, "mousedown", function(e) {
myRange.clear();
CodeMirror.e_preventDefault(e);
@@ -58,8 +58,13 @@
CodeMirror.signal(cm, "fold", cm, range.from, range.to);
}
- function makeWidget(cm, options) {
+ function makeWidget(cm, options, range) {
var widget = getOption(cm, options, "widget");
+
+ if (typeof widget == "function") {
+ widget = widget(range.from, range.to);
+ }
+
if (typeof widget == "string") {
var text = document.createTextNode(widget);
widget = document.createElement("span");
diff --git a/src/codemirror/addon/fold/foldgutter.css b/src/assets/plugins/codemirror/addon/fold/foldgutter.css
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/addon/fold/foldgutter.css
rename to src/assets/plugins/codemirror/addon/fold/foldgutter.css
diff --git a/src/codemirror/addon/fold/foldgutter.js b/src/assets/plugins/codemirror/addon/fold/foldgutter.js
old mode 100755
new mode 100644
similarity index 80%
rename from src/codemirror/addon/fold/foldgutter.js
rename to src/assets/plugins/codemirror/addon/fold/foldgutter.js
index 988c67c..7d46a60
--- a/src/codemirror/addon/fold/foldgutter.js
+++ b/src/assets/plugins/codemirror/addon/fold/foldgutter.js
@@ -16,7 +16,7 @@
cm.clearGutter(cm.state.foldGutter.options.gutter);
cm.state.foldGutter = null;
cm.off("gutterClick", onGutterClick);
- cm.off("change", onChange);
+ cm.off("changes", onChange);
cm.off("viewportChange", onViewportChange);
cm.off("fold", onFold);
cm.off("unfold", onFold);
@@ -26,7 +26,7 @@
cm.state.foldGutter = new State(parseOptions(val));
updateInViewport(cm);
cm.on("gutterClick", onGutterClick);
- cm.on("change", onChange);
+ cm.on("changes", onChange);
cm.on("viewportChange", onViewportChange);
cm.on("fold", onFold);
cm.on("unfold", onFold);
@@ -51,8 +51,13 @@
function isFolded(cm, line) {
var marks = cm.findMarks(Pos(line, 0), Pos(line + 1, 0));
- for (var i = 0; i < marks.length; ++i)
- if (marks[i].__isFold && marks[i].find().from.line == line) return marks[i];
+ for (var i = 0; i < marks.length; ++i) {
+ if (marks[i].__isFold) {
+ var fromPos = marks[i].find(-1);
+ if (fromPos && fromPos.line === line)
+ return marks[i];
+ }
+ }
}
function marker(spec) {
@@ -66,24 +71,36 @@
}
function updateFoldInfo(cm, from, to) {
- var opts = cm.state.foldGutter.options, cur = from;
+ var opts = cm.state.foldGutter.options, cur = from - 1;
var minSize = cm.foldOption(opts, "minFoldSize");
var func = cm.foldOption(opts, "rangeFinder");
+ // we can reuse the built-in indicator element if its className matches the new state
+ var clsFolded = typeof opts.indicatorFolded == "string" && classTest(opts.indicatorFolded);
+ var clsOpen = typeof opts.indicatorOpen == "string" && classTest(opts.indicatorOpen);
cm.eachLine(from, to, function(line) {
+ ++cur;
var mark = null;
+ var old = line.gutterMarkers;
+ if (old) old = old[opts.gutter];
if (isFolded(cm, cur)) {
+ if (clsFolded && old && clsFolded.test(old.className)) return;
mark = marker(opts.indicatorFolded);
} else {
var pos = Pos(cur, 0);
var range = func && func(cm, pos);
- if (range && range.to.line - range.from.line >= minSize)
+ if (range && range.to.line - range.from.line >= minSize) {
+ if (clsOpen && old && clsOpen.test(old.className)) return;
mark = marker(opts.indicatorOpen);
+ }
}
+ if (!mark && !old) return;
cm.setGutterMarker(line, opts.gutter, mark);
- ++cur;
});
}
+ // copied from CodeMirror/src/util/dom.js
+ function classTest(cls) { return new RegExp("(^|\\s)" + cls + "(?:$|\\s)\\s*") }
+
function updateInViewport(cm) {
var vp = cm.getViewport(), state = cm.state.foldGutter;
if (!state) return;
@@ -100,7 +117,7 @@
if (gutter != opts.gutter) return;
var folded = isFolded(cm, line);
if (folded) folded.clear();
- else cm.foldCode(Pos(line, 0), opts.rangeFinder);
+ else cm.foldCode(Pos(line, 0), opts);
}
function onChange(cm) {
diff --git a/src/codemirror/addon/fold/indent-fold.js b/src/assets/plugins/codemirror/addon/fold/indent-fold.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/addon/fold/indent-fold.js
rename to src/assets/plugins/codemirror/addon/fold/indent-fold.js
diff --git a/src/codemirror/addon/fold/markdown-fold.js b/src/assets/plugins/codemirror/addon/fold/markdown-fold.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/addon/fold/markdown-fold.js
rename to src/assets/plugins/codemirror/addon/fold/markdown-fold.js
diff --git a/src/codemirror/addon/fold/xml-fold.js b/src/assets/plugins/codemirror/addon/fold/xml-fold.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/addon/fold/xml-fold.js
rename to src/assets/plugins/codemirror/addon/fold/xml-fold.js
diff --git a/src/codemirror/addon/hint/anyword-hint.js b/src/assets/plugins/codemirror/addon/hint/anyword-hint.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/addon/hint/anyword-hint.js
rename to src/assets/plugins/codemirror/addon/hint/anyword-hint.js
diff --git a/src/codemirror/addon/hint/css-hint.js b/src/assets/plugins/codemirror/addon/hint/css-hint.js
old mode 100755
new mode 100644
similarity index 76%
rename from src/codemirror/addon/hint/css-hint.js
rename to src/assets/plugins/codemirror/addon/hint/css-hint.js
index 6cdf728..980d119
--- a/src/codemirror/addon/hint/css-hint.js
+++ b/src/assets/plugins/codemirror/addon/hint/css-hint.js
@@ -11,9 +11,15 @@
})(function(CodeMirror) {
"use strict";
- var pseudoClasses = {link: 1, visited: 1, active: 1, hover: 1, focus: 1,
- "first-letter": 1, "first-line": 1, "first-child": 1,
- before: 1, after: 1, lang: 1};
+ var pseudoClasses = {"active":1, "after":1, "before":1, "checked":1, "default":1,
+ "disabled":1, "empty":1, "enabled":1, "first-child":1, "first-letter":1,
+ "first-line":1, "first-of-type":1, "focus":1, "hover":1, "in-range":1,
+ "indeterminate":1, "invalid":1, "lang":1, "last-child":1, "last-of-type":1,
+ "link":1, "not":1, "nth-child":1, "nth-last-child":1, "nth-last-of-type":1,
+ "nth-of-type":1, "only-of-type":1, "only-child":1, "optional":1, "out-of-range":1,
+ "placeholder":1, "read-only":1, "read-write":1, "required":1, "root":1,
+ "selection":1, "target":1, "valid":1, "visited":1
+ };
CodeMirror.registerHelper("hint", "css", function(cm) {
var cur = cm.getCursor(), token = cm.getTokenAt(cur);
diff --git a/src/codemirror/addon/hint/html-hint.js b/src/assets/plugins/codemirror/addon/hint/html-hint.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/addon/hint/html-hint.js
rename to src/assets/plugins/codemirror/addon/hint/html-hint.js
diff --git a/src/codemirror/addon/hint/javascript-hint.js b/src/assets/plugins/codemirror/addon/hint/javascript-hint.js
old mode 100755
new mode 100644
similarity index 94%
rename from src/codemirror/addon/hint/javascript-hint.js
rename to src/assets/plugins/codemirror/addon/hint/javascript-hint.js
index 96a7fe0..6d09e6b
--- a/src/codemirror/addon/hint/javascript-hint.js
+++ b/src/assets/plugins/codemirror/addon/hint/javascript-hint.js
@@ -144,10 +144,15 @@
base = base[context.pop().string];
if (base != null) gatherCompletions(base);
} else {
- // If not, just look in the global object and any local scope
+ // If not, just look in the global object, any local scope, and optional additional-context
// (reading into JS mode internals to get at the local and global variables)
for (var v = token.state.localVars; v; v = v.next) maybeAdd(v.name);
+ for (var c = token.state.context; c; c = c.prev)
+ for (var v = c.vars; v; v = v.next) maybeAdd(v.name)
for (var v = token.state.globalVars; v; v = v.next) maybeAdd(v.name);
+ if (options && options.additionalContext != null)
+ for (var key in options.additionalContext)
+ maybeAdd(key);
if (!options || options.useGlobalScope !== false)
gatherCompletions(global);
forEach(keywords, maybeAdd);
diff --git a/src/codemirror/addon/hint/show-hint.css b/src/assets/plugins/codemirror/addon/hint/show-hint.css
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/addon/hint/show-hint.css
rename to src/assets/plugins/codemirror/addon/hint/show-hint.css
diff --git a/src/codemirror/addon/hint/show-hint.js b/src/assets/plugins/codemirror/addon/hint/show-hint.js
old mode 100755
new mode 100644
similarity index 87%
rename from src/codemirror/addon/hint/show-hint.js
rename to src/assets/plugins/codemirror/addon/hint/show-hint.js
index e3cd209..c55deab
--- a/src/codemirror/addon/hint/show-hint.js
+++ b/src/assets/plugins/codemirror/addon/hint/show-hint.js
@@ -85,11 +85,16 @@
},
pick: function(data, i) {
- var completion = data.list[i];
- if (completion.hint) completion.hint(this.cm, data, completion);
- else this.cm.replaceRange(getText(completion), completion.from || data.from,
- completion.to || data.to, "complete");
- CodeMirror.signal(data, "pick", completion);
+ var completion = data.list[i], self = this;
+ this.cm.operation(function() {
+ if (completion.hint)
+ completion.hint(self.cm, data, completion);
+ else
+ self.cm.replaceRange(getText(completion), completion.from || data.from,
+ completion.to || data.to, "complete");
+ CodeMirror.signal(data, "pick", completion);
+ self.cm.scrollIntoView();
+ })
this.close();
},
@@ -99,9 +104,14 @@
this.debounce = 0;
}
+ var identStart = this.startPos;
+ if(this.data) {
+ identStart = this.data.from;
+ }
+
var pos = this.cm.getCursor(), line = this.cm.getLine(pos.line);
if (pos.line != this.startPos.line || line.length - pos.ch != this.startLen - this.startPos.ch ||
- pos.ch < this.startPos.ch || this.cm.somethingSelected() ||
+ pos.ch < identStart.ch || this.cm.somethingSelected() ||
(!pos.ch || this.options.closeCharacters.test(line.charAt(pos.ch - 1)))) {
this.close();
} else {
@@ -229,14 +239,26 @@
elt.hintId = i;
}
+ var container = completion.options.container || ownerDocument.body;
var pos = cm.cursorCoords(completion.options.alignWithWord ? data.from : null);
var left = pos.left, top = pos.bottom, below = true;
- hints.style.left = left + "px";
- hints.style.top = top + "px";
+ var offsetLeft = 0, offsetTop = 0;
+ if (container !== ownerDocument.body) {
+ // We offset the cursor position because left and top are relative to the offsetParent's top left corner.
+ var isContainerPositioned = ['absolute', 'relative', 'fixed'].indexOf(parentWindow.getComputedStyle(container).position) !== -1;
+ var offsetParent = isContainerPositioned ? container : container.offsetParent;
+ var offsetParentPosition = offsetParent.getBoundingClientRect();
+ var bodyPosition = ownerDocument.body.getBoundingClientRect();
+ offsetLeft = (offsetParentPosition.left - bodyPosition.left - offsetParent.scrollLeft);
+ offsetTop = (offsetParentPosition.top - bodyPosition.top - offsetParent.scrollTop);
+ }
+ hints.style.left = (left - offsetLeft) + "px";
+ hints.style.top = (top - offsetTop) + "px";
+
// If we're at the edge of the screen, then we want the menu to appear on the left of the cursor.
var winW = parentWindow.innerWidth || Math.max(ownerDocument.body.offsetWidth, ownerDocument.documentElement.offsetWidth);
var winH = parentWindow.innerHeight || Math.max(ownerDocument.body.offsetHeight, ownerDocument.documentElement.offsetHeight);
- (completion.options.container || ownerDocument.body).appendChild(hints);
+ container.appendChild(hints);
var box = hints.getBoundingClientRect(), overlapY = box.bottom - winH;
var scrolls = hints.scrollHeight > hints.clientHeight + 1
var startScroll = cm.getScrollInfo();
@@ -244,15 +266,15 @@
if (overlapY > 0) {
var height = box.bottom - box.top, curTop = pos.top - (pos.bottom - box.top);
if (curTop - height > 0) { // Fits above cursor
- hints.style.top = (top = pos.top - height) + "px";
+ hints.style.top = (top = pos.top - height - offsetTop) + "px";
below = false;
} else if (height > winH) {
hints.style.height = (winH - 5) + "px";
- hints.style.top = (top = pos.bottom - box.top) + "px";
+ hints.style.top = (top = pos.bottom - box.top - offsetTop) + "px";
var cursor = cm.getCursor();
if (data.from.ch != cursor.ch) {
pos = cm.cursorCoords(cursor);
- hints.style.left = (left = pos.left) + "px";
+ hints.style.left = (left = pos.left - offsetLeft) + "px";
box = hints.getBoundingClientRect();
}
}
@@ -263,7 +285,7 @@
hints.style.width = (winW - 5) + "px";
overlapX -= (box.right - box.left) - winW;
}
- hints.style.left = (left = pos.left - overlapX) + "px";
+ hints.style.left = (left = pos.left - overlapX - offsetLeft) + "px";
}
if (scrolls) for (var node = hints.firstChild; node; node = node.nextSibling)
node.style.paddingRight = cm.display.nativeBarWidth + "px"
@@ -310,6 +332,7 @@
CodeMirror.on(hints, "mousedown", function() {
setTimeout(function(){cm.focus();}, 20);
});
+ this.scrollToActive()
CodeMirror.signal(data, "select", completions[this.selectedHint], hints.childNodes[this.selectedHint]);
return true;
@@ -351,13 +374,19 @@
if (node) node.className = node.className.replace(" " + ACTIVE_HINT_ELEMENT_CLASS, "");
node = this.hints.childNodes[this.selectedHint = i];
node.className += " " + ACTIVE_HINT_ELEMENT_CLASS;
- if (node.offsetTop < this.hints.scrollTop)
- this.hints.scrollTop = node.offsetTop - 3;
- else if (node.offsetTop + node.offsetHeight > this.hints.scrollTop + this.hints.clientHeight)
- this.hints.scrollTop = node.offsetTop + node.offsetHeight - this.hints.clientHeight + 3;
+ this.scrollToActive()
CodeMirror.signal(this.data, "select", this.data.list[this.selectedHint], node);
},
+ scrollToActive: function() {
+ var node = this.hints.childNodes[this.selectedHint]
+ var firstNode = this.hints.firstChild;
+ if (node.offsetTop < this.hints.scrollTop)
+ this.hints.scrollTop = node.offsetTop - firstNode.offsetTop;
+ else if (node.offsetTop + node.offsetHeight > this.hints.scrollTop + this.hints.clientHeight)
+ this.hints.scrollTop = node.offsetTop + node.offsetHeight - this.hints.clientHeight + firstNode.offsetTop;
+ },
+
screenAmount: function() {
return Math.floor(this.hints.clientHeight / this.hints.firstChild.offsetHeight) || 1;
}
diff --git a/src/codemirror/addon/hint/sql-hint.js b/src/assets/plugins/codemirror/addon/hint/sql-hint.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/addon/hint/sql-hint.js
rename to src/assets/plugins/codemirror/addon/hint/sql-hint.js
diff --git a/src/codemirror/addon/hint/xml-hint.js b/src/assets/plugins/codemirror/addon/hint/xml-hint.js
old mode 100755
new mode 100644
similarity index 88%
rename from src/codemirror/addon/hint/xml-hint.js
rename to src/assets/plugins/codemirror/addon/hint/xml-hint.js
index 106ba4f..7575b37
--- a/src/codemirror/addon/hint/xml-hint.js
+++ b/src/assets/plugins/codemirror/addon/hint/xml-hint.js
@@ -29,7 +29,7 @@
token.string = token.string.slice(0, cur.ch - token.start);
}
var inner = CodeMirror.innerMode(cm.getMode(), token.state);
- if (inner.mode.name != "xml") return;
+ if (!inner.mode.xmlCurrentTag) return
var result = [], replaceToken = false, prefix;
var tag = /\btag\b/.test(token.type) && !/>$/.test(token.string);
var tagName = tag && /^\w/.test(token.string), tagStart;
@@ -44,12 +44,15 @@
tagType = "close";
}
- if (!tag && !inner.state.tagName || tagType) {
+ var tagInfo = inner.mode.xmlCurrentTag(inner.state)
+ if (!tag && !tagInfo || tagType) {
if (tagName)
prefix = token.string;
replaceToken = tagType;
- var cx = inner.state.context, curTag = cx && tags[cx.tagName];
- var childList = cx ? curTag && curTag.children : tags["!top"];
+ var context = inner.mode.xmlCurrentContext ? inner.mode.xmlCurrentContext(inner.state) : []
+ var inner = context.length && context[context.length - 1]
+ var curTag = inner && tags[inner]
+ var childList = inner ? curTag && curTag.children : tags["!top"];
if (childList && tagType != "close") {
for (var i = 0; i < childList.length; ++i) if (!prefix || matches(childList[i], prefix, matchInMiddle))
result.push("<" + childList[i]);
@@ -58,11 +61,11 @@
if (tags.hasOwnProperty(name) && name != "!top" && name != "!attrs" && (!prefix || matches(name, prefix, matchInMiddle)))
result.push("<" + name);
}
- if (cx && (!prefix || tagType == "close" && matches(cx.tagName, prefix, matchInMiddle)))
- result.push("" + cx.tagName + ">");
+ if (inner && (!prefix || tagType == "close" && matches(inner, prefix, matchInMiddle)))
+ result.push("" + inner + ">");
} else {
// Attribute completion
- var curTag = tags[inner.state.tagName], attrs = curTag && curTag.attrs;
+ var curTag = tagInfo && tags[tagInfo.name], attrs = curTag && curTag.attrs;
var globalAttrs = tags["!attrs"];
if (!attrs && !globalAttrs) return;
if (!attrs) {
diff --git a/src/codemirror/addon/lint/coffeescript-lint.js b/src/assets/plugins/codemirror/addon/lint/coffeescript-lint.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/addon/lint/coffeescript-lint.js
rename to src/assets/plugins/codemirror/addon/lint/coffeescript-lint.js
diff --git a/src/codemirror/addon/lint/css-lint.js b/src/assets/plugins/codemirror/addon/lint/css-lint.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/addon/lint/css-lint.js
rename to src/assets/plugins/codemirror/addon/lint/css-lint.js
diff --git a/src/codemirror/addon/lint/html-lint.js b/src/assets/plugins/codemirror/addon/lint/html-lint.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/addon/lint/html-lint.js
rename to src/assets/plugins/codemirror/addon/lint/html-lint.js
diff --git a/src/codemirror/addon/lint/javascript-lint.js b/src/assets/plugins/codemirror/addon/lint/javascript-lint.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/addon/lint/javascript-lint.js
rename to src/assets/plugins/codemirror/addon/lint/javascript-lint.js
diff --git a/src/codemirror/addon/lint/json-lint.js b/src/assets/plugins/codemirror/addon/lint/json-lint.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/addon/lint/json-lint.js
rename to src/assets/plugins/codemirror/addon/lint/json-lint.js
diff --git a/src/codemirror/addon/lint/lint.css b/src/assets/plugins/codemirror/addon/lint/lint.css
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/addon/lint/lint.css
rename to src/assets/plugins/codemirror/addon/lint/lint.css
diff --git a/src/codemirror/addon/lint/lint.js b/src/assets/plugins/codemirror/addon/lint/lint.js
old mode 100755
new mode 100644
similarity index 90%
rename from src/codemirror/addon/lint/lint.js
rename to src/assets/plugins/codemirror/addon/lint/lint.js
index aa75ba0..5bc1af1
--- a/src/codemirror/addon/lint/lint.js
+++ b/src/assets/plugins/codemirror/addon/lint/lint.js
@@ -12,11 +12,14 @@
"use strict";
var GUTTER_ID = "CodeMirror-lint-markers";
- function showTooltip(e, content) {
+ function showTooltip(cm, e, content) {
var tt = document.createElement("div");
- tt.className = "CodeMirror-lint-tooltip";
+ tt.className = "CodeMirror-lint-tooltip cm-s-" + cm.options.theme;
tt.appendChild(content.cloneNode(true));
- document.body.appendChild(tt);
+ if (cm.state.lint.options.selfContain)
+ cm.getWrapperElement().appendChild(tt);
+ else
+ document.body.appendChild(tt);
function position(e) {
if (!tt.parentNode) return CodeMirror.off(document, "mousemove", position);
@@ -38,8 +41,8 @@
setTimeout(function() { rm(tt); }, 600);
}
- function showTooltipFor(e, content, node) {
- var tooltip = showTooltip(e, content);
+ function showTooltipFor(cm, e, content, node) {
+ var tooltip = showTooltip(cm, e, content);
function hide() {
CodeMirror.off(node, "mouseout", hide);
if (tooltip) { hideTooltip(tooltip); tooltip = null; }
@@ -78,7 +81,7 @@
state.marked.length = 0;
}
- function makeMarker(labels, severity, multiple, tooltips) {
+ function makeMarker(cm, labels, severity, multiple, tooltips) {
var marker = document.createElement("div"), inner = marker;
marker.className = "CodeMirror-lint-marker-" + severity;
if (multiple) {
@@ -87,7 +90,7 @@
}
if (tooltips != false) CodeMirror.on(inner, "mouseover", function(e) {
- showTooltipFor(e, labels, inner);
+ showTooltipFor(cm, e, labels, inner);
});
return marker;
@@ -113,9 +116,9 @@
var tip = document.createElement("div");
tip.className = "CodeMirror-lint-message-" + severity;
if (typeof ann.messageHTML != 'undefined') {
- tip.innerHTML = ann.messageHTML;
+ tip.innerHTML = ann.messageHTML;
} else {
- tip.appendChild(document.createTextNode(ann.message));
+ tip.appendChild(document.createTextNode(ann.message));
}
return tip;
}
@@ -186,7 +189,7 @@
}
if (state.hasGutter)
- cm.setGutterMarker(line, GUTTER_ID, makeMarker(tipLabel, maxSeverity, anns.length > 1,
+ cm.setGutterMarker(line, GUTTER_ID, makeMarker(cm, tipLabel, maxSeverity, anns.length > 1,
state.options.tooltips));
}
if (options.onUpdateLinting) options.onUpdateLinting(annotationsNotSorted, annotations, cm);
@@ -199,14 +202,14 @@
state.timeout = setTimeout(function(){startLinting(cm);}, state.options.delay || 500);
}
- function popupTooltips(annotations, e) {
+ function popupTooltips(cm, annotations, e) {
var target = e.target || e.srcElement;
var tooltip = document.createDocumentFragment();
for (var i = 0; i < annotations.length; i++) {
var ann = annotations[i];
tooltip.appendChild(annotationTooltip(ann));
}
- showTooltipFor(e, tooltip, target);
+ showTooltipFor(cm, e, tooltip, target);
}
function onMouseOver(cm, e) {
@@ -220,7 +223,7 @@
var ann = spans[i].__annotation;
if (ann) annotations.push(ann);
}
- if (annotations.length) popupTooltips(annotations, e);
+ if (annotations.length) popupTooltips(cm, annotations, e);
}
CodeMirror.defineOption("lint", false, function(cm, val, old) {
diff --git a/src/codemirror/addon/lint/yaml-lint.js b/src/assets/plugins/codemirror/addon/lint/yaml-lint.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/addon/lint/yaml-lint.js
rename to src/assets/plugins/codemirror/addon/lint/yaml-lint.js
diff --git a/src/codemirror/addon/merge/merge.css b/src/assets/plugins/codemirror/addon/merge/merge.css
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/addon/merge/merge.css
rename to src/assets/plugins/codemirror/addon/merge/merge.css
diff --git a/src/codemirror/addon/merge/merge.js b/src/assets/plugins/codemirror/addon/merge/merge.js
old mode 100755
new mode 100644
similarity index 98%
rename from src/codemirror/addon/merge/merge.js
rename to src/assets/plugins/codemirror/addon/merge/merge.js
index 63373f7..827edb7
--- a/src/codemirror/addon/merge/merge.js
+++ b/src/assets/plugins/codemirror/addon/merge/merge.js
@@ -443,22 +443,26 @@
aligners[i].clear();
aligners.length = 0;
- var cm = [dv.edit, dv.orig], scroll = [];
+ var cm = [dv.edit, dv.orig], scroll = [], offset = []
if (other) cm.push(other.orig);
- for (var i = 0; i < cm.length; i++)
+ for (var i = 0; i < cm.length; i++) {
scroll.push(cm[i].getScrollInfo().top);
+ offset.push(-cm[i].getScrollerElement().getBoundingClientRect().top)
+ }
+ if (offset[0] != offset[1] || cm.length == 3 && offset[1] != offset[2])
+ alignLines(cm, offset, [0, 0, 0], aligners)
for (var ln = 0; ln < linesToAlign.length; ln++)
- alignLines(cm, linesToAlign[ln], aligners);
+ alignLines(cm, offset, linesToAlign[ln], aligners);
for (var i = 0; i < cm.length; i++)
cm[i].scrollTo(null, scroll[i]);
}
- function alignLines(cm, lines, aligners) {
- var maxOffset = 0, offset = [];
+ function alignLines(cm, cmOffset, lines, aligners) {
+ var maxOffset = -1e8, offset = [];
for (var i = 0; i < cm.length; i++) if (lines[i] != null) {
- var off = cm[i].heightAtLine(lines[i], "local");
+ var off = cm[i].heightAtLine(lines[i], "local") - cmOffset[i];
offset[i] = off;
maxOffset = Math.max(maxOffset, off);
}
@@ -918,7 +922,7 @@
hasMarker: function(n) {
var handle = this.cm.getLineHandle(n)
if (handle.markedSpans) for (var i = 0; i < handle.markedSpans.length; i++)
- if (handle.markedSpans[i].mark.collapsed && handle.markedSpans[i].to != null)
+ if (handle.markedSpans[i].marker.collapsed && handle.markedSpans[i].to != null)
return true
return false
},
diff --git a/src/codemirror/addon/mode/loadmode.js b/src/assets/plugins/codemirror/addon/mode/loadmode.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/addon/mode/loadmode.js
rename to src/assets/plugins/codemirror/addon/mode/loadmode.js
diff --git a/src/codemirror/addon/mode/multiplex.js b/src/assets/plugins/codemirror/addon/mode/multiplex.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/addon/mode/multiplex.js
rename to src/assets/plugins/codemirror/addon/mode/multiplex.js
diff --git a/src/codemirror/addon/mode/multiplex_test.js b/src/assets/plugins/codemirror/addon/mode/multiplex_test.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/addon/mode/multiplex_test.js
rename to src/assets/plugins/codemirror/addon/mode/multiplex_test.js
diff --git a/src/codemirror/addon/mode/overlay.js b/src/assets/plugins/codemirror/addon/mode/overlay.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/addon/mode/overlay.js
rename to src/assets/plugins/codemirror/addon/mode/overlay.js
diff --git a/src/codemirror/addon/mode/simple.js b/src/assets/plugins/codemirror/addon/mode/simple.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/addon/mode/simple.js
rename to src/assets/plugins/codemirror/addon/mode/simple.js
diff --git a/src/codemirror/addon/runmode/colorize.js b/src/assets/plugins/codemirror/addon/runmode/colorize.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/addon/runmode/colorize.js
rename to src/assets/plugins/codemirror/addon/runmode/colorize.js
diff --git a/src/codemirror/addon/runmode/runmode-standalone.js b/src/assets/plugins/codemirror/addon/runmode/runmode-standalone.js
old mode 100755
new mode 100644
similarity index 88%
rename from src/codemirror/addon/runmode/runmode-standalone.js
rename to src/assets/plugins/codemirror/addon/runmode/runmode-standalone.js
index 745eaf8..f47af3f
--- a/src/codemirror/addon/runmode/runmode-standalone.js
+++ b/src/assets/plugins/codemirror/addon/runmode/runmode-standalone.js
@@ -1,16 +1,19 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
-window.CodeMirror = {};
+var root = typeof globalThis !== 'undefined' ? globalThis : window;
+root.CodeMirror = {};
(function() {
"use strict";
function splitLines(string){ return string.split(/\r?\n|\r/); };
-function StringStream(string) {
+function StringStream(strings, i) {
this.pos = this.start = 0;
- this.string = string;
+ this.string = strings[i];
+ this.strings = strings
+ this.i = i
this.lineStart = 0;
}
StringStream.prototype = {
@@ -66,7 +69,7 @@ StringStream.prototype = {
try { return inner(); }
finally { this.lineStart -= n; }
},
- lookAhead: function() { return null }
+ lookAhead: function(n) { return this.strings[this.i + n] }
};
CodeMirror.StringStream = StringStream;
@@ -104,14 +107,18 @@ CodeMirror.defineMIME("text/plain", "null");
CodeMirror.runMode = function (string, modespec, callback, options) {
var mode = CodeMirror.getMode({ indentUnit: 2 }, modespec);
+ var ie = /MSIE \d/.test(navigator.userAgent);
+ var ie_lt9 = ie && (document.documentMode == null || document.documentMode < 9);
- if (callback.nodeType == 1) {
+ if (callback.appendChild) {
var tabSize = (options && options.tabSize) || 4;
var node = callback, col = 0;
node.innerHTML = "";
callback = function (text, style) {
if (text == "\n") {
- node.appendChild(document.createElement("br"));
+ // Emitting LF or CRLF on IE8 or earlier results in an incorrect display.
+ // Emitting a carriage return makes everything ok.
+ node.appendChild(document.createTextNode(ie_lt9 ? '\r' : text));
col = 0;
return;
}
@@ -146,7 +153,7 @@ CodeMirror.runMode = function (string, modespec, callback, options) {
var lines = splitLines(string), state = (options && options.state) || CodeMirror.startState(mode);
for (var i = 0, e = lines.length; i < e; ++i) {
if (i) callback("\n");
- var stream = new CodeMirror.StringStream(lines[i]);
+ var stream = new CodeMirror.StringStream(lines, i);
if (!stream.string && mode.blankLine) mode.blankLine(state);
while (!stream.eol()) {
var style = mode.token(stream, state);
diff --git a/src/codemirror/addon/runmode/runmode.js b/src/assets/plugins/codemirror/addon/runmode/runmode.js
old mode 100755
new mode 100644
similarity index 94%
rename from src/codemirror/addon/runmode/runmode.js
rename to src/assets/plugins/codemirror/addon/runmode/runmode.js
index eb4cadf..ca8d9a9
--- a/src/codemirror/addon/runmode/runmode.js
+++ b/src/assets/plugins/codemirror/addon/runmode/runmode.js
@@ -59,7 +59,10 @@ CodeMirror.runMode = function(string, modespec, callback, options) {
var lines = CodeMirror.splitLines(string), state = (options && options.state) || CodeMirror.startState(mode);
for (var i = 0, e = lines.length; i < e; ++i) {
if (i) callback("\n");
- var stream = new CodeMirror.StringStream(lines[i]);
+ var stream = new CodeMirror.StringStream(lines[i], null, {
+ lookAhead: function(n) { return lines[i + n] },
+ baseToken: function() {}
+ });
if (!stream.string && mode.blankLine) mode.blankLine(state);
while (!stream.eol()) {
var style = mode.token(stream, state);
diff --git a/src/codemirror/addon/runmode/runmode.node.js b/src/assets/plugins/codemirror/addon/runmode/runmode.node.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/addon/runmode/runmode.node.js
rename to src/assets/plugins/codemirror/addon/runmode/runmode.node.js
diff --git a/src/codemirror/addon/scroll/annotatescrollbar.js b/src/assets/plugins/codemirror/addon/scroll/annotatescrollbar.js
old mode 100755
new mode 100644
similarity index 97%
rename from src/codemirror/addon/scroll/annotatescrollbar.js
rename to src/assets/plugins/codemirror/addon/scroll/annotatescrollbar.js
index 3566258..9fe61ec
--- a/src/codemirror/addon/scroll/annotatescrollbar.js
+++ b/src/assets/plugins/codemirror/addon/scroll/annotatescrollbar.js
@@ -43,7 +43,7 @@
cm.on("markerAdded", this.resizeHandler);
cm.on("markerCleared", this.resizeHandler);
if (options.listenForChanges !== false)
- cm.on("change", this.changeHandler = function() {
+ cm.on("changes", this.changeHandler = function() {
scheduleRedraw(250);
});
}
@@ -116,7 +116,7 @@
this.cm.off("refresh", this.resizeHandler);
this.cm.off("markerAdded", this.resizeHandler);
this.cm.off("markerCleared", this.resizeHandler);
- if (this.changeHandler) this.cm.off("change", this.changeHandler);
+ if (this.changeHandler) this.cm.off("changes", this.changeHandler);
this.div.parentNode.removeChild(this.div);
};
});
diff --git a/src/codemirror/addon/scroll/scrollpastend.js b/src/assets/plugins/codemirror/addon/scroll/scrollpastend.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/addon/scroll/scrollpastend.js
rename to src/assets/plugins/codemirror/addon/scroll/scrollpastend.js
diff --git a/src/codemirror/addon/scroll/simplescrollbars.css b/src/assets/plugins/codemirror/addon/scroll/simplescrollbars.css
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/addon/scroll/simplescrollbars.css
rename to src/assets/plugins/codemirror/addon/scroll/simplescrollbars.css
diff --git a/src/codemirror/addon/scroll/simplescrollbars.js b/src/assets/plugins/codemirror/addon/scroll/simplescrollbars.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/addon/scroll/simplescrollbars.js
rename to src/assets/plugins/codemirror/addon/scroll/simplescrollbars.js
diff --git a/src/codemirror/addon/search/jump-to-line.js b/src/assets/plugins/codemirror/addon/search/jump-to-line.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/addon/search/jump-to-line.js
rename to src/assets/plugins/codemirror/addon/search/jump-to-line.js
diff --git a/src/codemirror/addon/search/match-highlighter.js b/src/assets/plugins/codemirror/addon/search/match-highlighter.js
old mode 100755
new mode 100644
similarity index 95%
rename from src/codemirror/addon/search/match-highlighter.js
rename to src/assets/plugins/codemirror/addon/search/match-highlighter.js
index b344ac7..3a4a7de
--- a/src/codemirror/addon/search/match-highlighter.js
+++ b/src/assets/plugins/codemirror/addon/search/match-highlighter.js
@@ -90,7 +90,9 @@
var state = cm.state.matchHighlighter;
cm.addOverlay(state.overlay = makeOverlay(query, hasBoundary, style));
if (state.options.annotateScrollbar && cm.showMatchesOnScrollbar) {
- var searchFor = hasBoundary ? new RegExp("\\b" + query.replace(/[\\\[.+*?(){|^$]/g, "\\$&") + "\\b") : query;
+ var searchFor = hasBoundary ? new RegExp((/\w/.test(query.charAt(0)) ? "\\b" : "") +
+ query.replace(/[\\\[.+*?(){|^$]/g, "\\$&") +
+ (/\w/.test(query.charAt(query.length - 1)) ? "\\b" : "")) : query;
state.matchesonscroll = cm.showMatchesOnScrollbar(searchFor, false,
{className: "CodeMirror-selection-highlight-scrollbar"});
}
diff --git a/src/codemirror/addon/search/matchesonscrollbar.css b/src/assets/plugins/codemirror/addon/search/matchesonscrollbar.css
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/addon/search/matchesonscrollbar.css
rename to src/assets/plugins/codemirror/addon/search/matchesonscrollbar.css
diff --git a/src/codemirror/addon/search/matchesonscrollbar.js b/src/assets/plugins/codemirror/addon/search/matchesonscrollbar.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/addon/search/matchesonscrollbar.js
rename to src/assets/plugins/codemirror/addon/search/matchesonscrollbar.js
diff --git a/src/codemirror/addon/search/search.js b/src/assets/plugins/codemirror/addon/search/search.js
old mode 100755
new mode 100644
similarity index 98%
rename from src/codemirror/addon/search/search.js
rename to src/assets/plugins/codemirror/addon/search/search.js
index 5c2559c..cecdd52
--- a/src/codemirror/addon/search/search.js
+++ b/src/assets/plugins/codemirror/addon/search/search.js
@@ -78,10 +78,12 @@
}
function parseString(string) {
- return string.replace(/\\(.)/g, function(_, ch) {
+ return string.replace(/\\([nrt\\])/g, function(match, ch) {
if (ch == "n") return "\n"
if (ch == "r") return "\r"
- return ch
+ if (ch == "t") return "\t"
+ if (ch == "\\") return "\\"
+ return match
})
}
diff --git a/src/codemirror/addon/search/searchcursor.js b/src/assets/plugins/codemirror/addon/search/searchcursor.js
old mode 100755
new mode 100644
similarity index 92%
rename from src/codemirror/addon/search/searchcursor.js
rename to src/assets/plugins/codemirror/addon/search/searchcursor.js
index aae36df..d586957
--- a/src/codemirror/addon/search/searchcursor.js
+++ b/src/assets/plugins/codemirror/addon/search/searchcursor.js
@@ -72,24 +72,26 @@
}
}
- function lastMatchIn(string, regexp) {
- var cutOff = 0, match
- for (;;) {
- regexp.lastIndex = cutOff
+ function lastMatchIn(string, regexp, endMargin) {
+ var match, from = 0
+ while (from <= string.length) {
+ regexp.lastIndex = from
var newMatch = regexp.exec(string)
- if (!newMatch) return match
- match = newMatch
- cutOff = match.index + (match[0].length || 1)
- if (cutOff == string.length) return match
+ if (!newMatch) break
+ var end = newMatch.index + newMatch[0].length
+ if (end > string.length - endMargin) break
+ if (!match || end > match.index + match[0].length)
+ match = newMatch
+ from = newMatch.index + 1
}
+ return match
}
function searchRegexpBackward(doc, regexp, start) {
regexp = ensureFlags(regexp, "g")
for (var line = start.line, ch = start.ch, first = doc.firstLine(); line >= first; line--, ch = -1) {
var string = doc.getLine(line)
- if (ch > -1) string = string.slice(0, ch)
- var match = lastMatchIn(string, regexp)
+ var match = lastMatchIn(string, regexp, ch < 0 ? 0 : string.length - ch)
if (match)
return {from: Pos(line, match.index),
to: Pos(line, match.index + match[0].length),
@@ -98,16 +100,17 @@
}
function searchRegexpBackwardMultiline(doc, regexp, start) {
+ if (!maybeMultiline(regexp)) return searchRegexpBackward(doc, regexp, start)
regexp = ensureFlags(regexp, "gm")
- var string, chunk = 1
+ var string, chunkSize = 1, endMargin = doc.getLine(start.line).length - start.ch
for (var line = start.line, first = doc.firstLine(); line >= first;) {
- for (var i = 0; i < chunk; i++) {
+ for (var i = 0; i < chunkSize && line >= first; i++) {
var curLine = doc.getLine(line--)
- string = string == null ? curLine.slice(0, start.ch) : curLine + "\n" + string
+ string = string == null ? curLine : curLine + "\n" + string
}
- chunk *= 2
+ chunkSize *= 2
- var match = lastMatchIn(string, regexp)
+ var match = lastMatchIn(string, regexp, endMargin)
if (match) {
var before = string.slice(0, match.index).split("\n"), inside = match[0].split("\n")
var startLine = line + before.length, startCh = before[before.length - 1].length
@@ -237,7 +240,7 @@
var result = this.matches(reverse, this.doc.clipPos(reverse ? this.pos.from : this.pos.to))
// Implements weird auto-growing behavior on null-matches for
- // backwards-compatiblity with the vim code (unfortunately)
+ // backwards-compatibility with the vim code (unfortunately)
while (result && CodeMirror.cmpPos(result.from, result.to) == 0) {
if (reverse) {
if (result.from.ch) result.from = Pos(result.from.line, result.from.ch - 1)
diff --git a/src/codemirror/addon/selection/active-line.js b/src/assets/plugins/codemirror/addon/selection/active-line.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/addon/selection/active-line.js
rename to src/assets/plugins/codemirror/addon/selection/active-line.js
diff --git a/src/codemirror/addon/selection/mark-selection.js b/src/assets/plugins/codemirror/addon/selection/mark-selection.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/addon/selection/mark-selection.js
rename to src/assets/plugins/codemirror/addon/selection/mark-selection.js
diff --git a/src/codemirror/addon/selection/selection-pointer.js b/src/assets/plugins/codemirror/addon/selection/selection-pointer.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/addon/selection/selection-pointer.js
rename to src/assets/plugins/codemirror/addon/selection/selection-pointer.js
diff --git a/src/codemirror/addon/tern/tern.css b/src/assets/plugins/codemirror/addon/tern/tern.css
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/addon/tern/tern.css
rename to src/assets/plugins/codemirror/addon/tern/tern.css
diff --git a/src/codemirror/addon/tern/tern.js b/src/assets/plugins/codemirror/addon/tern/tern.js
old mode 100755
new mode 100644
similarity index 98%
rename from src/codemirror/addon/tern/tern.js
rename to src/assets/plugins/codemirror/addon/tern/tern.js
index 253309d..7be3681
--- a/src/codemirror/addon/tern/tern.js
+++ b/src/assets/plugins/codemirror/addon/tern/tern.js
@@ -231,7 +231,7 @@
var content = ts.options.completionTip ? ts.options.completionTip(cur.data) : cur.data.doc;
if (content) {
tooltip = makeTooltip(node.parentNode.getBoundingClientRect().right + window.pageXOffset,
- node.getBoundingClientRect().top + window.pageYOffset, content);
+ node.getBoundingClientRect().top + window.pageYOffset, content, cm);
tooltip.className += " " + cls + "hint-doc";
}
});
@@ -334,7 +334,7 @@
tip.appendChild(document.createTextNode(tp.rettype ? ") ->\u00a0" : ")"));
if (tp.rettype) tip.appendChild(elt("span", cls + "type", tp.rettype));
var place = cm.cursorCoords(null, "page");
- var tooltip = ts.activeArgHints = makeTooltip(place.right + 1, place.bottom, tip)
+ var tooltip = ts.activeArgHints = makeTooltip(place.right + 1, place.bottom, tip, cm)
setTimeout(function() {
tooltip.clear = onEditorActivity(cm, function() {
if (ts.activeArgHints == tooltip) closeArgHints(ts) })
@@ -601,7 +601,7 @@
function tempTooltip(cm, content, ts) {
if (cm.state.ternTooltip) remove(cm.state.ternTooltip);
var where = cm.cursorCoords();
- var tip = cm.state.ternTooltip = makeTooltip(where.right + 1, where.bottom, content);
+ var tip = cm.state.ternTooltip = makeTooltip(where.right + 1, where.bottom, content, cm);
function maybeClear() {
old = true;
if (!mouseOnTip) clear();
@@ -637,11 +637,12 @@
}
}
- function makeTooltip(x, y, content) {
+ function makeTooltip(x, y, content, cm) {
var node = elt("div", cls + "tooltip", content);
node.style.left = x + "px";
node.style.top = y + "px";
- document.body.appendChild(node);
+ var container = ((cm.options || {}).hintOptions || {}).container || document.body;
+ container.appendChild(node);
return node;
}
diff --git a/src/codemirror/addon/tern/worker.js b/src/assets/plugins/codemirror/addon/tern/worker.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/addon/tern/worker.js
rename to src/assets/plugins/codemirror/addon/tern/worker.js
diff --git a/src/codemirror/addon/wrap/hardwrap.js b/src/assets/plugins/codemirror/addon/wrap/hardwrap.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/addon/wrap/hardwrap.js
rename to src/assets/plugins/codemirror/addon/wrap/hardwrap.js
diff --git a/src/codemirror/bin/authors.sh b/src/assets/plugins/codemirror/bin/authors.sh
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/bin/authors.sh
rename to src/assets/plugins/codemirror/bin/authors.sh
diff --git a/src/codemirror/bin/lint b/src/assets/plugins/codemirror/bin/lint
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/bin/lint
rename to src/assets/plugins/codemirror/bin/lint
diff --git a/src/codemirror/bin/release b/src/assets/plugins/codemirror/bin/release
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/bin/release
rename to src/assets/plugins/codemirror/bin/release
diff --git a/src/codemirror/bin/source-highlight b/src/assets/plugins/codemirror/bin/source-highlight
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/bin/source-highlight
rename to src/assets/plugins/codemirror/bin/source-highlight
diff --git a/src/codemirror/bin/upload-release.js b/src/assets/plugins/codemirror/bin/upload-release.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/bin/upload-release.js
rename to src/assets/plugins/codemirror/bin/upload-release.js
diff --git a/src/codemirror/doc/activebookmark.js b/src/assets/plugins/codemirror/doc/activebookmark.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/doc/activebookmark.js
rename to src/assets/plugins/codemirror/doc/activebookmark.js
diff --git a/src/codemirror/doc/docs.css b/src/assets/plugins/codemirror/doc/docs.css
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/doc/docs.css
rename to src/assets/plugins/codemirror/doc/docs.css
diff --git a/src/codemirror/doc/internals.html b/src/assets/plugins/codemirror/doc/internals.html
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/doc/internals.html
rename to src/assets/plugins/codemirror/doc/internals.html
diff --git a/src/codemirror/doc/logo.png b/src/assets/plugins/codemirror/doc/logo.png
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/doc/logo.png
rename to src/assets/plugins/codemirror/doc/logo.png
diff --git a/src/codemirror/doc/logo.svg b/src/assets/plugins/codemirror/doc/logo.svg
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/doc/logo.svg
rename to src/assets/plugins/codemirror/doc/logo.svg
diff --git a/src/codemirror/doc/manual.html b/src/assets/plugins/codemirror/doc/manual.html
old mode 100755
new mode 100644
similarity index 96%
rename from src/codemirror/doc/manual.html
rename to src/assets/plugins/codemirror/doc/manual.html
index f7271e2..e8acb01
--- a/src/codemirror/doc/manual.html
+++ b/src/assets/plugins/codemirror/doc/manual.html
@@ -69,7 +69,7 @@
User manual and reference guide
- version 5.46.0
+ version 5.54.0
CodeMirror is a code-editor component that can be embedded in
@@ -223,9 +223,10 @@
first mode that was loaded. It may be a string, which either
simply names the mode or is
a MIME type
- associated with the mode. Alternatively, it may be an object
- containing configuration options for the mode, with
- a name property that names the mode (for
+ associated with the mode. The value "null"
+ indicates no highlighting should be applied. Alternatively, it
+ may be an object containing configuration options for the mode,
+ with a name property that names the mode (for
example {name: "javascript", json: true}). The demo
pages for each mode contain information about what configuration
parameters the mode supports. You can ask CodeMirror which modes
@@ -284,7 +285,7 @@
should be replaced by a
special placeholder.
Mostly useful for non-printing special characters. The default
- is /[\u0000-\u001f\u007f-\u009f\u00ad\u061c\u200b-\u200f\u2028\u2029\ufeff]/.
+ is /[\u0000-\u001f\u007f-\u009f\u00ad\u061c\u200b-\u200f\u2028\u2029\ufeff\ufff9-\ufffc]/.
specialCharPlaceholder: function(char) → Element
A function that, given a special character identified by
the specialChars
@@ -420,6 +421,10 @@
simply true), focusing of the editor is also
disallowed.
+
screenReaderLabel: string
+
This label is read by the screenreaders when CodeMirror text area is focused. This
+ is helpful for accessibility.
+
showCursorWhenSelecting: boolean
Whether the cursor should be drawn when a selection is
active. Defaults to false.
@@ -557,13 +562,13 @@
always rendered, and thus the browser's text search works on it.
This will have bad effects on performance of big
documents.
-
+
spellcheck: boolean
Specifies whether or not spellcheck will be enabled on the input.
-
+
autocorrect: boolean
Specifies whether or not autocorrect will be enabled on the input.
-
+
autocapitalize: boolean
Specifies whether or not autocapitalization will be enabled on the input.
For atomic ranges, determines whether the cursor is allowed
+ to be placed directly to the left of the range. Has no effect on
+ non-atomic ranges.
+
selectRight: boolean
+
Like selectLeft,
+ but for the right side.
atomic: boolean
Atomic ranges act as a single unit when cursor movement is
concerned—i.e. it is impossible to place the cursor inside of
- them. In atomic ranges, inclusiveLeft
- and inclusiveRight have a different meaning—they
- will prevent the cursor from being placed respectively
- directly before and directly after the range.
+ them. You can control whether the cursor is allowed to be placed
+ directly before or after them using selectLeft
+ or selectRight. If selectLeft
+ (or right) is not provided, then inclusiveLeft (or
+ right) will control this behavior.
collapsed: boolean
Collapsed ranges do not show up in the display. Setting a
range to be collapsed will automatically make it atomic.
@@ -1872,6 +1885,9 @@ editor.setOption("extraKeys", {
position (zero for the top, N to put it after the Nth other
widget). Note that this only has effect once, when the
widget is created.
+
className: string
+
Add an extra CSS class name to the wrapper element
+ created for the widget.
Note that the widget node will become a descendant of nodes with
CodeMirror-specific CSS classes, and those classes might in some
@@ -2555,10 +2571,14 @@ editor.setOption("extraKeys", {
and CodeMirror.fold.xml, for XML-style languages,
and CodeMirror.fold.comment, for folding comment
blocks.
-
widget: string|Element
+
widget: string | Element | fn(from: Pos, to: Pos) → string|Element
The widget to show for folded ranges. Can be either a
string, in which case it'll become a span with
- class CodeMirror-foldmarker, or a DOM node.
+ class CodeMirror-foldmarker, or a DOM node.
+ To dynamically generate the widget, this can be a function
+ that returns a string or DOM node, which will then render
+ as described. The function will be invoked with parameters
+ identifying the range to be folded.
scanUp: boolean
When true (default is false), the addon will try to find
foldable ranges on the lines above the current one if there
@@ -2895,6 +2915,7 @@ editor.setOption("extraKeys", {
will only be executed when the promise resolves.
By default, the linter will run (debounced) whenever the document is changed.
You can pass a lintOnChange: false option to disable that.
+ You can pass a selfContain: true option to render the tooltip inside the editor instance.
Depends on addon/lint/lint.css. A demo can be
found here.
Provides integration with
- the Tern JavaScript analysis
+ the Tern JavaScript analysis
engine, for completion, definition finding, and minor
refactoring help. See the demo
for a very simple integration. For more involved scenarios, see
the comments at the top of
the addon and the
implementation of the
- (multi-file) demonstration
+ (multi-file) demonstration
on the Tern website.
@@ -3509,6 +3530,26 @@ editor.setOption("extraKeys", {
extras.isEdit is applicable only to actions,
determining whether it is recorded for replay for the
. single-repeat command.
+
+
unmap(lhs: string, ctx: string)
+
+ Remove the command lhs if it is a user defined command.
+ If the command is an Ex to Ex or Ex to key mapping then the context
+ must be undefined or false.
+
+
+
mapclear(ctx: string)
+
+ Remove all user-defined mappings for the provided context.
+
+ Non-recursive map function. This will not create mappings to key maps
+ that aren't present in the default key map.
+ If no context is provided then the mapping will be applied to each of
+ normal, insert, and visual mode.
+
Extending VIM
@@ -3574,7 +3615,74 @@ editor.setOption("extraKeys", {
command was prefixed with a
line range,
params.line and params.lineEnd will
- be set.
+ be set.
+
+
getRegisterController()
+
Returns the RegisterController that manages the state of registers
+ used by vim mode. For the RegisterController api see its
+ defintion here.
+
+
+
buildKeyMap()
+
+ Not currently implemented. If you would like to contribute this please open
+ a pull request on Github.
+
+
+
defineRegister()
+
Defines an external register. The name should be a single character
+ that will be used to reference the register. The register should support
+ setText, pushText, clear, and toString.
+ See Register for a reference implementation.
+
+
+
getVimGlobalState_()
+
+ Return a reference to the VimGlobalState.
+
+
+
resetVimGlobalState_()
+
+ Reset the default values of the VimGlobalState to fresh values. Any options
+ set with setOption will also be applied to the reset global state.
+
+
+
maybeInitVimState_(cm: CodeMirror)
+
+ Initialize cm.state.vim if it does not exist. Returns cm.state.vim.
+
+ This is the outermost function called by CodeMirror, after keys have
+ been mapped to their Vim equivalents. Finds a command based on the key
+ (and cached keys if there is a multi-key sequence). Returns undefined
+ if no key is matched, a noop function if a partial match is found (multi-key),
+ and a function to execute the bound command if a a key is matched. The
+ function always returns true.
+
+
+
suppressErrorLogging: boolean
+
Whether to use suppress the use of console.log when catching an
+ error in the function returned by findKey.
+ Defaults to false.
Exit visual mode. If moveHead is set to false, the CodeMirror selection
+ will not be touched. The caller assumes the responsibility of putting
+ the cursor in the right place.
+
+
+
exitInsertMode(cm: CodeMirror)
+
+ Exit insert mode.
+
diff --git a/src/codemirror/doc/realworld.html b/src/assets/plugins/codemirror/doc/realworld.html
old mode 100755
new mode 100644
similarity index 95%
rename from src/codemirror/doc/realworld.html
rename to src/assets/plugins/codemirror/doc/realworld.html
index 8d4e07a..152b557
--- a/src/codemirror/doc/realworld.html
+++ b/src/assets/plugins/codemirror/doc/realworld.html
@@ -26,6 +26,7 @@
diff --git a/src/codemirror/doc/releases.html b/src/assets/plugins/codemirror/doc/releases.html
old mode 100755
new mode 100644
similarity index 91%
rename from src/codemirror/doc/releases.html
rename to src/assets/plugins/codemirror/doc/releases.html
index 6ecaef0..75384de
--- a/src/codemirror/doc/releases.html
+++ b/src/assets/plugins/codemirror/doc/releases.html
@@ -30,6 +30,149 @@
diff --git a/src/codemirror/doc/reporting.html b/src/assets/plugins/codemirror/doc/reporting.html
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/doc/reporting.html
rename to src/assets/plugins/codemirror/doc/reporting.html
diff --git a/src/codemirror/doc/upgrade_v2.2.html b/src/assets/plugins/codemirror/doc/upgrade_v2.2.html
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/doc/upgrade_v2.2.html
rename to src/assets/plugins/codemirror/doc/upgrade_v2.2.html
diff --git a/src/codemirror/doc/upgrade_v3.html b/src/assets/plugins/codemirror/doc/upgrade_v3.html
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/doc/upgrade_v3.html
rename to src/assets/plugins/codemirror/doc/upgrade_v3.html
diff --git a/src/codemirror/doc/upgrade_v4.html b/src/assets/plugins/codemirror/doc/upgrade_v4.html
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/doc/upgrade_v4.html
rename to src/assets/plugins/codemirror/doc/upgrade_v4.html
diff --git a/src/codemirror/doc/yinyang.png b/src/assets/plugins/codemirror/doc/yinyang.png
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/doc/yinyang.png
rename to src/assets/plugins/codemirror/doc/yinyang.png
diff --git a/src/codemirror/index.html b/src/assets/plugins/codemirror/index.html
old mode 100755
new mode 100644
similarity index 69%
rename from src/codemirror/index.html
rename to src/assets/plugins/codemirror/index.html
index 4e4f164..59cac74
--- a/src/codemirror/index.html
+++ b/src/assets/plugins/codemirror/index.html
@@ -99,7 +99,7 @@
- Get the current version: 5.46.0.
+ Get the current version: 5.54.0.
You can see the code,
read the release notes,
or study the user manual.
@@ -195,4 +195,19 @@
pretty well.
+
+
+
+
Sponsors
+
These companies support development of this project:
+
+
+
+
+
+
diff --git a/src/codemirror/keymap/emacs.js b/src/assets/plugins/codemirror/keymap/emacs.js
old mode 100755
new mode 100644
similarity index 99%
rename from src/codemirror/keymap/emacs.js
rename to src/assets/plugins/codemirror/keymap/emacs.js
index d96a6fb..fe4882e
--- a/src/codemirror/keymap/emacs.js
+++ b/src/assets/plugins/codemirror/keymap/emacs.js
@@ -369,6 +369,7 @@
"Ctrl-/": repeated("undo"), "Shift-Ctrl--": repeated("undo"),
"Ctrl-Z": repeated("undo"), "Cmd-Z": repeated("undo"),
+ "Shift-Ctrl-Z": "redo",
"Shift-Alt-,": "goDocStart", "Shift-Alt-.": "goDocEnd",
"Ctrl-S": "findPersistentNext", "Ctrl-R": "findPersistentPrev", "Ctrl-G": quit, "Shift-Alt-5": "replace",
"Alt-/": "autocomplete",
@@ -403,7 +404,8 @@
"Ctrl-X H": "selectAll",
"Ctrl-Q Tab": repeated("insertTab"),
- "Ctrl-U": addPrefixMap
+ "Ctrl-U": addPrefixMap,
+ "fallthrough": "default"
});
var prefixMap = {"Ctrl-G": clearPrefix};
diff --git a/src/codemirror/keymap/sublime.js b/src/assets/plugins/codemirror/keymap/sublime.js
old mode 100755
new mode 100644
similarity index 94%
rename from src/codemirror/keymap/sublime.js
rename to src/assets/plugins/codemirror/keymap/sublime.js
index 799641a..7edf172
--- a/src/codemirror/keymap/sublime.js
+++ b/src/assets/plugins/codemirror/keymap/sublime.js
@@ -22,17 +22,21 @@
if (dir < 0 && start.ch == 0) return doc.clipPos(Pos(start.line - 1));
var line = doc.getLine(start.line);
if (dir > 0 && start.ch >= line.length) return doc.clipPos(Pos(start.line + 1, 0));
- var state = "start", type;
- for (var pos = start.ch, e = dir < 0 ? 0 : line.length, i = 0; pos != e; pos += dir, i++) {
+ var state = "start", type, startPos = start.ch;
+ for (var pos = startPos, e = dir < 0 ? 0 : line.length, i = 0; pos != e; pos += dir, i++) {
var next = line.charAt(dir < 0 ? pos - 1 : pos);
var cat = next != "_" && CodeMirror.isWordChar(next) ? "w" : "o";
if (cat == "w" && next.toUpperCase() == next) cat = "W";
if (state == "start") {
if (cat != "o") { state = "in"; type = cat; }
+ else startPos = pos + dir
} else if (state == "in") {
if (type != cat) {
if (type == "w" && cat == "W" && dir < 0) pos--;
- if (type == "W" && cat == "w" && dir > 0) { type = "w"; continue; }
+ if (type == "W" && cat == "w" && dir > 0) { // From uppercase to lowercase
+ if (pos == startPos + 1) { type = "w"; continue; }
+ else pos--;
+ }
break;
}
}
@@ -144,14 +148,24 @@
cur = cm.getSearchCursor(query, Pos(cm.firstLine(), 0));
found = cur.findNext();
}
- if (!found || isSelectedRange(cm.listSelections(), cur.from(), cur.to()))
- return CodeMirror.Pass
+ if (!found || isSelectedRange(cm.listSelections(), cur.from(), cur.to())) return
cm.addSelection(cur.from(), cur.to());
}
if (fullWord)
cm.state.sublimeFindFullWord = cm.doc.sel;
};
+ cmds.skipAndSelectNextOccurrence = function(cm) {
+ var prevAnchor = cm.getCursor("anchor"), prevHead = cm.getCursor("head");
+ cmds.selectNextOccurrence(cm);
+ if (CodeMirror.cmpPos(prevAnchor, prevHead) != 0) {
+ cm.doc.setSelections(cm.doc.listSelections()
+ .filter(function (sel) {
+ return sel.anchor != prevAnchor || sel.head != prevHead;
+ }));
+ }
+ }
+
function addCursorToSelection(cm, dir) {
var ranges = cm.listSelections(), newRanges = [];
for (var i = 0; i < ranges.length; i++) {
@@ -175,7 +189,8 @@
function isSelectedRange(ranges, from, to) {
for (var i = 0; i < ranges.length; i++)
- if (ranges[i].from() == from && ranges[i].to() == to) return true
+ if (CodeMirror.cmpPos(ranges[i].from(), from) == 0 &&
+ CodeMirror.cmpPos(ranges[i].to(), to) == 0) return true
return false
}
@@ -213,11 +228,15 @@
if (!selectBetweenBrackets(cm)) return CodeMirror.Pass;
};
+ function puncType(type) {
+ return !type ? null : /\bpunctuation\b/.test(type) ? type : undefined
+ }
+
cmds.goToBracket = function(cm) {
cm.extendSelectionsBy(function(range) {
- var next = cm.scanForBracket(range.head, 1);
+ var next = cm.scanForBracket(range.head, 1, puncType(cm.getTokenTypeAt(range.head)));
if (next && CodeMirror.cmpPos(next.pos, range.head) != 0) return next.pos;
- var prev = cm.scanForBracket(range.head, -1);
+ var prev = cm.scanForBracket(range.head, -1, puncType(cm.getTokenTypeAt(Pos(range.head.line, range.head.ch + 1))));
return prev && Pos(prev.pos.line, prev.pos.ch + 1) || range.head;
});
};
@@ -597,6 +616,7 @@
"Shift-Cmd-F2": "clearBookmarks",
"Alt-F2": "selectBookmarks",
"Backspace": "smartBackspace",
+ "Cmd-K Cmd-D": "skipAndSelectNextOccurrence",
"Cmd-K Cmd-K": "delLineRight",
"Cmd-K Cmd-U": "upcaseAtCursor",
"Cmd-K Cmd-L": "downcaseAtCursor",
@@ -608,6 +628,7 @@
"Cmd-K Cmd-C": "showInCenter",
"Cmd-K Cmd-G": "clearBookmarks",
"Cmd-K Cmd-Backspace": "delLineLeft",
+ "Cmd-K Cmd-1": "foldAll",
"Cmd-K Cmd-0": "unfoldAll",
"Cmd-K Cmd-J": "unfoldAll",
"Ctrl-Shift-Up": "addCursorToPrevLine",
@@ -657,6 +678,7 @@
"Shift-Ctrl-F2": "clearBookmarks",
"Alt-F2": "selectBookmarks",
"Backspace": "smartBackspace",
+ "Ctrl-K Ctrl-D": "skipAndSelectNextOccurrence",
"Ctrl-K Ctrl-K": "delLineRight",
"Ctrl-K Ctrl-U": "upcaseAtCursor",
"Ctrl-K Ctrl-L": "downcaseAtCursor",
@@ -668,6 +690,7 @@
"Ctrl-K Ctrl-C": "showInCenter",
"Ctrl-K Ctrl-G": "clearBookmarks",
"Ctrl-K Ctrl-Backspace": "delLineLeft",
+ "Ctrl-K Ctrl-1": "foldAll",
"Ctrl-K Ctrl-0": "unfoldAll",
"Ctrl-K Ctrl-J": "unfoldAll",
"Ctrl-Alt-Up": "addCursorToPrevLine",
diff --git a/src/codemirror/keymap/vim.js b/src/assets/plugins/codemirror/keymap/vim.js
old mode 100755
new mode 100644
similarity index 96%
rename from src/codemirror/keymap/vim.js
rename to src/assets/plugins/codemirror/keymap/vim.js
index 5758823..b5be59c
--- a/src/codemirror/keymap/vim.js
+++ b/src/assets/plugins/codemirror/keymap/vim.js
@@ -164,7 +164,9 @@
{ keys: 'A', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'eol' }, context: 'normal' },
{ keys: 'A', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'endOfSelectedArea' }, context: 'visual' },
{ keys: 'i', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'inplace' }, context: 'normal' },
+ { keys: 'gi', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'lastEdit' }, context: 'normal' },
{ keys: 'I', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'firstNonBlank'}, context: 'normal' },
+ { keys: 'gI', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'bol'}, context: 'normal' },
{ keys: 'I', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'startOfSelectedArea' }, context: 'visual' },
{ keys: 'o', type: 'action', action: 'newLineAndEnterInsertMode', isEdit: true, interlaceInsertRepeat: true, actionArgs: { after: true }, context: 'normal' },
{ keys: 'O', type: 'action', action: 'newLineAndEnterInsertMode', isEdit: true, interlaceInsertRepeat: true, actionArgs: { after: false }, context: 'normal' },
@@ -174,13 +176,15 @@
{ keys: '', type: 'action', action: 'toggleVisualMode', actionArgs: { blockwise: true }},
{ keys: 'gv', type: 'action', action: 'reselectLastSelection' },
{ keys: 'J', type: 'action', action: 'joinLines', isEdit: true },
+ { keys: 'gJ', type: 'action', action: 'joinLines', actionArgs: { keepSpaces: true }, isEdit: true },
{ keys: 'p', type: 'action', action: 'paste', isEdit: true, actionArgs: { after: true, isEdit: true }},
{ keys: 'P', type: 'action', action: 'paste', isEdit: true, actionArgs: { after: false, isEdit: true }},
{ keys: 'r', type: 'action', action: 'replace', isEdit: true },
{ keys: '@', type: 'action', action: 'replayMacro' },
{ keys: 'q', type: 'action', action: 'enterMacroRecordMode' },
// Handle Replace-mode as a special case of insert mode.
- { keys: 'R', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { replace: true }},
+ { keys: 'R', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { replace: true }, context: 'normal'},
+ { keys: 'R', type: 'operator', operator: 'change', operatorArgs: { linewise: true, fullLine: true }, context: 'visual', exitVisualBlock: true},
{ keys: 'u', type: 'action', action: 'undo', context: 'normal' },
{ keys: 'u', type: 'operator', operator: 'changeCase', operatorArgs: {toLower: true}, context: 'visual', isEdit: true },
{ keys: 'U', type: 'operator', operator: 'changeCase', operatorArgs: {toLower: false}, context: 'visual', isEdit: true },
@@ -230,7 +234,6 @@
{ name: 'undo', shortName: 'u' },
{ name: 'redo', shortName: 'red' },
{ name: 'set', shortName: 'se' },
- { name: 'set', shortName: 'se' },
{ name: 'setlocal', shortName: 'setl' },
{ name: 'setglobal', shortName: 'setg' },
{ name: 'sort', shortName: 'sor' },
@@ -286,41 +289,44 @@
enterVimMode(cm);
}
- function fatCursorMarks(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]
+ var range = ranges[i];
if (range.empty()) {
- if (range.anchor.ch < cm.getLine(range.anchor.line).length) {
+ var lineLength = cm.getLine(range.anchor.line).length;
+ if (range.anchor.ch < lineLength) {
result.push(cm.markText(range.anchor, Pos(range.anchor.line, range.anchor.ch + 1),
- {className: "cm-fat-cursor-mark"}))
+ {className: "cm-fat-cursor-mark"}));
} else {
- var widget = document.createElement("span")
- widget.textContent = "\u00a0"
- widget.className = "cm-fat-cursor-mark"
- result.push(cm.setBookmark(range.anchor, {widget: widget}))
+ result.push(cm.markText(Pos(range.anchor.line, lineLength - 1),
+ Pos(range.anchor.line, lineLength),
+ {className: "cm-fat-cursor-mark"}));
}
}
}
- return result
+ cm.state.fatCursorMarks = result;
}
- function updateFatCursorMark(cm) {
- var marks = cm.state.fatCursorMarks
- if (marks) for (var i = 0; i < marks.length; i++) marks[i].clear()
- cm.state.fatCursorMarks = fatCursorMarks(cm)
+ 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 = fatCursorMarks(cm)
+ cm.state.fatCursorMarks = [];
+ updateFatCursorMark(cm)
cm.on("cursorActivity", updateFatCursorMark)
}
function disableFatCursorMark(cm) {
- var marks = cm.state.fatCursorMarks
- if (marks) for (var i = 0; i < marks.length; i++) marks[i].clear()
- cm.state.fatCursorMarks = null
- cm.off("cursorActivity", updateFatCursorMark)
+ 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.
@@ -591,9 +597,16 @@
}
return mark;
}
+ function find(cm, offset) {
+ var oldPointer = pointer;
+ var mark = move(cm, offset);
+ pointer = oldPointer;
+ return mark && mark.find();
+ }
return {
cachedCursor: undefined, //used for # and * jumps
add: add,
+ find: find,
move: move
};
};
@@ -1290,6 +1303,10 @@
}
inputState.operator = command.operator;
inputState.operatorArgs = copyArgs(command.operatorArgs);
+ if (command.exitVisualBlock) {
+ vim.visualBlock = false;
+ updateCmSelection(cm);
+ }
if (vim.visualMode) {
// Operating on a selection in visual mode. We don't need a motion.
this.evalInput(cm, vim);
@@ -1585,10 +1602,10 @@
}
if (vim.visualMode) {
if (!(vim.visualBlock && newHead.ch === Infinity)) {
- newHead = clipCursorToContent(cm, newHead, vim.visualBlock);
+ newHead = clipCursorToContent(cm, newHead);
}
if (newAnchor) {
- newAnchor = clipCursorToContent(cm, newAnchor, true);
+ newAnchor = clipCursorToContent(cm, newAnchor);
}
newAnchor = newAnchor || oldAnchor;
sel.anchor = newAnchor;
@@ -1714,6 +1731,7 @@
vim.lastEditActionCommand = actionCommand;
macroModeState.lastInsertModeChanges.changes = [];
macroModeState.lastInsertModeChanges.expectCursorActivityForChange = false;
+ macroModeState.lastInsertModeChanges.visualBlock = vim.visualBlock ? vim.sel.head.line - vim.sel.anchor.line : 0;
}
};
@@ -1839,12 +1857,18 @@
var line = motionArgs.forward ? cur.line + repeat : cur.line - repeat;
var first = cm.firstLine();
var last = cm.lastLine();
+ var posV = cm.findPosV(cur, (motionArgs.forward ? repeat : -repeat), 'line', vim.lastHSPos);
+ var hasMarkedText = motionArgs.forward ? posV.line > line : posV.line < line;
+ if (hasMarkedText) {
+ line = posV.line;
+ endCh = posV.ch;
+ }
// Vim go to line begin or line end when cursor at first/last line and
// move to previous/next line is triggered.
if (line < first && cur.line == first){
return this.moveToStartOfLine(cm, head, motionArgs, vim);
}else if (line > last && cur.line == last){
- return this.moveToEol(cm, head, motionArgs, vim);
+ return this.moveToEol(cm, head, motionArgs, vim, true);
}
if (motionArgs.toFirstChar){
endCh=findFirstNonWhiteSpaceCharacter(cm.getLine(line));
@@ -1946,13 +1970,15 @@
vim.lastHSPos = cm.charCoords(head,'div').left;
return moveToColumn(cm, repeat);
},
- moveToEol: function(cm, head, motionArgs, vim) {
+ moveToEol: function(cm, head, motionArgs, vim, keepHPos) {
var cur = head;
- vim.lastHPos = Infinity;
var retval= Pos(cur.line + motionArgs.repeat - 1, Infinity);
var end=cm.clipPos(retval);
end.ch--;
- vim.lastHSPos = cm.charCoords(end,'div').left;
+ if (!keepHPos) {
+ vim.lastHPos = Infinity;
+ vim.lastHSPos = cm.charCoords(end,'div').left;
+ }
return retval;
},
moveToFirstNonWhiteSpaceCharacter: function(cm, head) {
@@ -2004,7 +2030,7 @@
'{': '}', '}': '{',
'[': ']', ']': '[',
'<': '>', '>': '<'};
- var selfPaired = {'\'': true, '"': true};
+ var selfPaired = {'\'': true, '"': true, '`': true};
var character = motionArgs.selectedCharacter;
// 'b' refers to '()' block.
@@ -2092,10 +2118,9 @@
change: function(cm, args, ranges) {
var finalHead, text;
var vim = cm.state.vim;
- vimGlobalState.macroModeState.lastInsertModeChanges.inVisualBlock = vim.visualBlock;
+ var anchor = ranges[0].anchor,
+ head = ranges[0].head;
if (!vim.visualMode) {
- var anchor = ranges[0].anchor,
- head = ranges[0].head;
text = cm.getRange(anchor, head);
var lastState = vim.lastEditInputState || {};
if (lastState.motion == "moveByWords" && !isWhiteSpaceString(text)) {
@@ -2123,6 +2148,13 @@
anchor.ch = Number.MAX_VALUE;
}
finalHead = anchor;
+ } else if (args.fullLine) {
+ head.ch = Number.MAX_VALUE;
+ head.line--;
+ cm.setSelection(anchor, head)
+ text = cm.getSelection();
+ cm.replaceSelection("");
+ finalHead = anchor;
} else {
text = cm.getSelection();
var replacement = fillArray('', ranges.length);
@@ -2167,8 +2199,7 @@
vimGlobalState.registerController.pushText(
args.registerName, 'delete', text,
args.linewise, vim.visualBlock);
- var includeLineBreak = vim.insertMode
- return clipCursorToContent(cm, finalHead, includeLineBreak);
+ return clipCursorToContent(cm, finalHead);
},
indent: function(cm, args, ranges) {
var vim = cm.state.vim;
@@ -2315,6 +2346,8 @@
var macroModeState = vimGlobalState.macroModeState;
if (registerName == '@') {
registerName = macroModeState.latestRegister;
+ } else {
+ macroModeState.latestRegister = registerName;
}
while(repeat--){
executeMacroRegister(cm, vim, macroModeState, registerName);
@@ -2348,11 +2381,15 @@
var height = cm.listSelections().length;
if (insertAt == 'eol') {
head = Pos(head.line, lineLength(cm, head.line));
+ } else if (insertAt == 'bol') {
+ head = Pos(head.line, 0);
} else if (insertAt == 'charAfter') {
head = offsetCursor(head, 0, 1);
} else if (insertAt == 'firstNonBlank') {
head = motions.moveToFirstNonWhiteSpaceCharacter(cm, head);
} else if (insertAt == 'startOfSelectedArea') {
+ if (!vim.visualMode)
+ return;
if (!vim.visualBlock) {
if (sel.head.line < sel.anchor.line) {
head = sel.head;
@@ -2366,6 +2403,8 @@
height = Math.abs(sel.head.line - sel.anchor.line) + 1;
}
} else if (insertAt == 'endOfSelectedArea') {
+ if (!vim.visualMode)
+ return;
if (!vim.visualBlock) {
if (sel.head.line >= sel.anchor.line) {
head = offsetCursor(sel.head, 0, 1);
@@ -2382,6 +2421,8 @@
if (vim.visualMode){
return;
}
+ } else if (insertAt == 'lastEdit') {
+ head = getLastEditPos(cm) || head;
}
cm.setOption('disableInput', false);
if (actionArgs && actionArgs.replace) {
@@ -2417,8 +2458,7 @@
vim.visualLine = !!actionArgs.linewise;
vim.visualBlock = !!actionArgs.blockwise;
head = clipCursorToContent(
- cm, Pos(anchor.line, anchor.ch + repeat - 1),
- true /** includeLineBreak */);
+ cm, Pos(anchor.line, anchor.ch + repeat - 1));
vim.sel = {
anchor: anchor,
head: head
@@ -2490,7 +2530,9 @@
var tmp = Pos(curStart.line + 1,
lineLength(cm, curStart.line + 1));
var text = cm.getRange(curStart, tmp);
- text = text.replace(/\n\s*/g, ' ');
+ text = actionArgs.keepSpaces
+ ? text.replace(/\n\r?/g, '')
+ : text.replace(/\n\s*/g, ' ');
cm.replaceRange(text, curStart, tmp);
}
var curFinalPos = Pos(curStart.line, finalCh);
@@ -2559,7 +2601,17 @@
}
var linewise = register.linewise;
var blockwise = register.blockwise;
- if (linewise) {
+ if (blockwise) {
+ text = text.split('\n');
+ if (linewise) {
+ text.pop();
+ }
+ for (var i = 0; i < text.length; i++) {
+ text[i] = (text[i] == '') ? ' ' : text[i];
+ }
+ cur.ch += actionArgs.after ? 1 : 0;
+ cur.ch = Math.min(lineLength(cm, cur.line), cur.ch);
+ } else if (linewise) {
if(vim.visualMode) {
text = vim.visualLine ? text.slice(0, -1) : '\n' + text.slice(0, text.length - 1) + '\n';
} else if (actionArgs.after) {
@@ -2571,12 +2623,6 @@
cur.ch = 0;
}
} else {
- if (blockwise) {
- text = text.split('\n');
- for (var i = 0; i < text.length; i++) {
- text[i] = (text[i] == '') ? ' ' : text[i];
- }
- }
cur.ch += actionArgs.after ? 1 : 0;
}
var curPosFinal;
@@ -2788,10 +2834,11 @@
* Clips cursor to ensure that line is within the buffer's range
* If includeLineBreak is true, then allow cur.ch == lineLength.
*/
- function clipCursorToContent(cm, cur, includeLineBreak) {
+ function clipCursorToContent(cm, cur) {
+ var vim = cm.state.vim;
+ var includeLineBreak = vim.insertMode || vim.visualMode;
var line = Math.min(Math.max(cm.firstLine(), cur.line), cm.lastLine() );
- var maxCh = lineLength(cm, line) - 1;
- maxCh = (includeLineBreak) ? maxCh + 1 : maxCh;
+ var maxCh = lineLength(cm, line) - 1 + !!includeLineBreak;
var ch = Math.min(Math.max(0, cur.ch), maxCh);
return Pos(line, ch);
}
@@ -2811,12 +2858,6 @@
}
return Pos(cur.line + offsetLine, cur.ch + offsetCh);
}
- function getOffset(anchor, head) {
- return {
- line: head.line - anchor.line,
- ch: head.line - anchor.line
- };
- }
function commandMatches(keys, keyMap, context, inputState) {
// Partial matches are not applied. They inform the key handler
// that the current key sequence is a subsequence of a valid key
@@ -3163,9 +3204,7 @@
vim.visualLine = false;
vim.visualBlock = false;
CodeMirror.signal(cm, "vim-mode-change", {mode: "normal"});
- if (vim.fakeCursor) {
- vim.fakeCursor.clear();
- }
+ clearFakeCursor(vim);
}
// Remove any trailing newlines from the selection. For
@@ -4064,7 +4103,7 @@
}
// Unescape \ and / in the replace part, for PCRE mode.
- var unescapes = {'\\/': '/', '\\\\': '\\', '\\n': '\n', '\\r': '\r', '\\t': '\t'};
+ var unescapes = {'\\/': '/', '\\\\': '\\', '\\n': '\n', '\\r': '\r', '\\t': '\t', '\\&':'&'};
function unescapeRegexReplace(str) {
var stream = new CodeMirror.StringStream(str);
var output = [];
@@ -4143,7 +4182,8 @@
}
function makePrompt(prefix, desc) {
var raw = '' +
- (prefix || "") + '';
+ (prefix || "") + '';
if (desc)
raw += ' ' + desc + '';
return raw;
@@ -4220,23 +4260,27 @@
query: query
};
}
+ var highlightTimeout = 0;
function highlightSearchMatches(cm, query) {
- var searchState = getSearchState(cm);
- var overlay = searchState.getOverlay();
- if (!overlay || query != overlay.query) {
- if (overlay) {
- cm.removeOverlay(overlay);
- }
- overlay = searchOverlay(query);
- cm.addOverlay(overlay);
- if (cm.showMatchesOnScrollbar) {
- if (searchState.getScrollbarAnnotate()) {
- searchState.getScrollbarAnnotate().clear();
+ clearTimeout(highlightTimeout);
+ highlightTimeout = setTimeout(function() {
+ var searchState = getSearchState(cm);
+ var overlay = searchState.getOverlay();
+ if (!overlay || query != overlay.query) {
+ if (overlay) {
+ cm.removeOverlay(overlay);
}
- searchState.setScrollbarAnnotate(cm.showMatchesOnScrollbar(query));
+ overlay = searchOverlay(query);
+ cm.addOverlay(overlay);
+ if (cm.showMatchesOnScrollbar) {
+ if (searchState.getScrollbarAnnotate()) {
+ searchState.getScrollbarAnnotate().clear();
+ }
+ searchState.setScrollbarAnnotate(cm.showMatchesOnScrollbar(query));
+ }
+ searchState.setOverlay(overlay);
}
- searchState.setOverlay(overlay);
- }
+ }, 50);
}
function findNext(cm, prev, query, repeat) {
if (repeat === undefined) { repeat = 1; }
@@ -4305,25 +4349,25 @@
}
function getMarkPos(cm, vim, markName) {
- if (markName == '\'') {
- var history = cm.doc.history.done;
- var event = history[history.length - 2];
- return event && event.ranges && event.ranges[0].head;
+ if (markName == '\'' || markName == '`') {
+ return vimGlobalState.jumpList.find(cm, -1) || Pos(0, 0);
} else if (markName == '.') {
- if (cm.doc.history.lastModTime == 0) {
- return // If no changes, bail out; don't bother to copy or reverse history array.
- } else {
- var changeHistory = cm.doc.history.done.filter(function(el){ if (el.changes !== undefined) { return el } });
- changeHistory.reverse();
- var lastEditPos = changeHistory[0].changes[0].to;
- }
- return lastEditPos;
+ return getLastEditPos(cm);
}
var mark = vim.marks[markName];
return mark && mark.find();
}
+ function getLastEditPos(cm) {
+ var done = cm.doc.history.done;
+ for (var i = done.length; i--;) {
+ if (done[i].changes) {
+ return copyCursor(done[i].changes[0].to);
+ }
+ }
+ }
+
var ExCommandDispatcher = function() {
this.buildCommandMap_();
};
@@ -4412,7 +4456,7 @@
}
// Parse command name.
- var commandMatch = inputStream.match(/^(\w+)/);
+ var commandMatch = inputStream.match(/^(\w+|!!|@@|[!#&*<=>@~])/);
if (commandMatch) {
result.commandName = commandMatch[1];
} else {
@@ -4848,6 +4892,9 @@
var global = false; // True to replace all instances on a line, false to replace only 1.
if (tokens.length) {
regexPart = tokens[0];
+ if (getOption('pcre') && regexPart !== '') {
+ regexPart = new RegExp(regexPart).source; //normalize not escaped characters
+ }
replacePart = tokens[1];
if (regexPart && regexPart[regexPart.length - 1] === '$') {
regexPart = regexPart.slice(0, regexPart.length - 1) + '\\n';
@@ -4855,7 +4902,7 @@
}
if (replacePart !== undefined) {
if (getOption('pcre')) {
- replacePart = unescapeRegexReplace(replacePart);
+ replacePart = unescapeRegexReplace(replacePart.replace(/([^\\])&/g,"$1$$&"));
} else {
replacePart = translateRegexReplace(replacePart);
}
@@ -4886,7 +4933,11 @@
global = true;
flagsPart.replace('g', '');
}
- regexPart = regexPart.replace(/\//g, "\\/") + '/' + flagsPart;
+ if (getOption('pcre')) {
+ regexPart = regexPart + '/' + flagsPart;
+ } else {
+ regexPart = regexPart.replace(/\//g, "\\/") + '/' + flagsPart;
+ }
}
}
if (regexPart) {
@@ -5303,14 +5354,34 @@
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 = document.createElement("span");
+ widget.textContent = "\u00a0";
+ widget.className = className;
+ vim.fakeCursorBookmark = cm.setBookmark(from, {widget: widget});
+ } else {
+ vim.fakeCursor = cm.markText(from, to, {className: className});
+ }
+ }
+ function clearFakeCursor(vim) {
if (vim.fakeCursor) {
vim.fakeCursor.clear();
+ vim.fakeCursor = null;
+ }
+ if (vim.fakeCursorBookmark) {
+ vim.fakeCursorBookmark.clear();
+ vim.fakeCursorBookmark = null;
}
- vim.fakeCursor = cm.markText(from, to, {className: 'cm-animate-fat-cursor'});
}
function handleExternalSelection(cm, vim) {
var anchor = cm.getCursor('anchor');
@@ -5436,18 +5507,15 @@
return true;
}
var head = cm.getCursor('head');
- var inVisualBlock = vimGlobalState.macroModeState.lastInsertModeChanges.inVisualBlock;
- if (inVisualBlock) {
+ var visualBlock = vimGlobalState.macroModeState.lastInsertModeChanges.visualBlock;
+ if (visualBlock) {
// Set up block selection again for repeating the changes.
- var vim = cm.state.vim;
- var lastSel = vim.lastSelection;
- var offset = getOffset(lastSel.anchor, lastSel.head);
- selectForInsert(cm, head, offset.line + 1);
+ selectForInsert(cm, head, visualBlock + 1);
repeat = cm.listSelections().length;
cm.setCursor(head);
}
for (var i = 0; i < repeat; i++) {
- if (inVisualBlock) {
+ if (visualBlock) {
cm.setCursor(offsetCursor(head, i, 0));
}
for (var j = 0; j < changes.length; j++) {
@@ -5464,7 +5532,7 @@
}
}
}
- if (inVisualBlock) {
+ if (visualBlock) {
cm.setCursor(offsetCursor(head, 0, 1));
}
}
diff --git a/src/codemirror/lib/codemirror.css b/src/assets/plugins/codemirror/lib/codemirror.css
old mode 100755
new mode 100644
similarity index 94%
rename from src/codemirror/lib/codemirror.css
rename to src/assets/plugins/codemirror/lib/codemirror.css
index c7a8ae7..5689650
--- a/src/codemirror/lib/codemirror.css
+++ b/src/assets/plugins/codemirror/lib/codemirror.css
@@ -13,7 +13,8 @@
.CodeMirror-lines {
padding: 4px 0; /* Vertical padding around content */
}
-.CodeMirror pre {
+.CodeMirror pre.CodeMirror-line,
+.CodeMirror pre.CodeMirror-line-like {
padding: 0 4px; /* Horizontal padding of content */
}
@@ -96,7 +97,7 @@
.CodeMirror-rulers {
position: absolute;
- left: 0; right: 0; top: -50px; bottom: -20px;
+ left: 0; right: 0; top: -50px; bottom: 0;
overflow: hidden;
}
.CodeMirror-ruler {
@@ -163,17 +164,17 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #a22;}
.CodeMirror-scroll {
overflow: scroll !important; /* Things will break if this is overridden */
- /* 30px is the magic margin used to hide the element's real scrollbars */
+ /* 50px is the magic margin used to hide the element's real scrollbars */
/* See overflow: hidden in .CodeMirror */
- margin-bottom: -30px; margin-right: -30px;
- padding-bottom: 30px;
+ margin-bottom: -50px; margin-right: -50px;
+ padding-bottom: 50px;
height: 100%;
outline: none; /* Prevent dragging from highlighting the element */
position: relative;
}
.CodeMirror-sizer {
position: relative;
- border-right: 30px solid transparent;
+ border-right: 50px solid transparent;
}
/* The fake, visible scrollbars. Used to force redraw during scrolling
@@ -211,7 +212,7 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #a22;}
height: 100%;
display: inline-block;
vertical-align: top;
- margin-bottom: -30px;
+ margin-bottom: -50px;
}
.CodeMirror-gutter-wrapper {
position: absolute;
@@ -236,7 +237,8 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #a22;}
cursor: text;
min-height: 1px; /* prevents collapsing before first draw */
}
-.CodeMirror pre {
+.CodeMirror pre.CodeMirror-line,
+.CodeMirror pre.CodeMirror-line-like {
/* Reset some styles that the rest of the page might have set */
-moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0;
border-width: 0;
@@ -255,7 +257,8 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #a22;}
-webkit-font-variant-ligatures: contextual;
font-variant-ligatures: contextual;
}
-.CodeMirror-wrap pre {
+.CodeMirror-wrap pre.CodeMirror-line,
+.CodeMirror-wrap pre.CodeMirror-line-like {
word-wrap: break-word;
white-space: pre-wrap;
word-break: normal;
diff --git a/src/codemirror/lib/codemirror.js b/src/assets/plugins/codemirror/lib/codemirror.js
old mode 100755
new mode 100644
similarity index 98%
rename from src/codemirror/lib/codemirror.js
rename to src/assets/plugins/codemirror/lib/codemirror.js
index 6d8bd9f..375fa2a
--- a/src/codemirror/lib/codemirror.js
+++ b/src/assets/plugins/codemirror/lib/codemirror.js
@@ -173,10 +173,28 @@
}
}
- var Delayed = function() {this.id = null;};
+ var Delayed = function() {
+ this.id = null;
+ this.f = null;
+ this.time = 0;
+ this.handler = bind(this.onTimeout, this);
+ };
+ Delayed.prototype.onTimeout = function (self) {
+ self.id = 0;
+ if (self.time <= +new Date) {
+ self.f();
+ } else {
+ setTimeout(self.handler, self.time - +new Date);
+ }
+ };
Delayed.prototype.set = function (ms, f) {
- clearTimeout(this.id);
- this.id = setTimeout(f, ms);
+ this.f = f;
+ var time = +new Date + ms;
+ if (!this.id || time < this.time) {
+ clearTimeout(this.id);
+ this.id = setTimeout(this.handler, ms);
+ this.time = time;
+ }
};
function indexOf(array, elt) {
@@ -186,7 +204,7 @@
}
// Number of pixels added to scroller and sizer to hide scrollbar
- var scrollerGap = 30;
+ var scrollerGap = 50;
// Returned or thrown by various protocols to signal 'I'm not
// handling this'.
@@ -467,14 +485,15 @@
for (++i$7; i$7 < len && countsAsLeft.test(types[i$7]); ++i$7) {}
order.push(new BidiSpan(0, start, i$7));
} else {
- var pos = i$7, at = order.length;
+ var pos = i$7, at = order.length, isRTL = direction == "rtl" ? 1 : 0;
for (++i$7; i$7 < len && types[i$7] != "L"; ++i$7) {}
for (var j$2 = pos; j$2 < i$7;) {
if (countsAsNum.test(types[j$2])) {
- if (pos < j$2) { order.splice(at, 0, new BidiSpan(1, pos, j$2)); }
+ if (pos < j$2) { order.splice(at, 0, new BidiSpan(1, pos, j$2)); at += isRTL; }
var nstart = j$2;
for (++j$2; j$2 < i$7 && countsAsNum.test(types[j$2]); ++j$2) {}
order.splice(at, 0, new BidiSpan(2, nstart, j$2));
+ at += isRTL;
pos = j$2;
} else { ++j$2; }
}
@@ -1186,7 +1205,7 @@
var prop = lineClass[1] ? "bgClass" : "textClass";
if (output[prop] == null)
{ output[prop] = lineClass[2]; }
- else if (!(new RegExp("(?:^|\s)" + lineClass[2] + "(?:$|\s)")).test(output[prop]))
+ else if (!(new RegExp("(?:^|\\s)" + lineClass[2] + "(?:$|\\s)")).test(output[prop]))
{ output[prop] += " " + lineClass[2]; }
} }
return type
@@ -2191,10 +2210,10 @@
function updateLineWidgets(cm, lineView, dims) {
if (lineView.alignable) { lineView.alignable = null; }
+ var isWidget = classTest("CodeMirror-linewidget");
for (var node = lineView.node.firstChild, next = (void 0); node; node = next) {
next = node.nextSibling;
- if (node.className == "CodeMirror-linewidget")
- { lineView.node.removeChild(node); }
+ if (isWidget.test(node.className)) { lineView.node.removeChild(node); }
}
insertLineWidgets(cm, lineView, dims);
}
@@ -2224,7 +2243,7 @@
if (!line.widgets) { return }
var wrap = ensureLineWrapped(lineView);
for (var i = 0, ws = line.widgets; i < ws.length; ++i) {
- var widget = ws[i], node = elt("div", [widget.node], "CodeMirror-linewidget");
+ var widget = ws[i], node = elt("div", [widget.node], "CodeMirror-linewidget" + (widget.className ? " " + widget.className : ""));
if (!widget.handleMouseEvents) { node.setAttribute("cm-ignore-events", "true"); }
positionLineWidget(widget, node, lineView, dims);
cm.display.input.setUneditable(node);
@@ -2284,7 +2303,7 @@
function paddingVert(display) {return display.mover.offsetHeight - display.lineSpace.offsetHeight}
function paddingH(display) {
if (display.cachedPaddingH) { return display.cachedPaddingH }
- var e = removeChildrenAndAdd(display.measure, elt("pre", "x"));
+ var e = removeChildrenAndAdd(display.measure, elt("pre", "x", "CodeMirror-line-like"));
var style = window.getComputedStyle ? window.getComputedStyle(e) : e.currentStyle;
var data = {left: parseInt(style.paddingLeft), right: parseInt(style.paddingRight)};
if (!isNaN(data.left) && !isNaN(data.right)) { display.cachedPaddingH = data; }
@@ -2678,7 +2697,7 @@
function PosWithInfo(line, ch, sticky, outside, xRel) {
var pos = Pos(line, ch, sticky);
pos.xRel = xRel;
- if (outside) { pos.outside = true; }
+ if (outside) { pos.outside = outside; }
return pos
}
@@ -2687,16 +2706,16 @@
function coordsChar(cm, x, y) {
var doc = cm.doc;
y += cm.display.viewOffset;
- if (y < 0) { return PosWithInfo(doc.first, 0, null, true, -1) }
+ if (y < 0) { return PosWithInfo(doc.first, 0, null, -1, -1) }
var lineN = lineAtHeight(doc, y), last = doc.first + doc.size - 1;
if (lineN > last)
- { return PosWithInfo(doc.first + doc.size - 1, getLine(doc, last).text.length, null, true, 1) }
+ { return PosWithInfo(doc.first + doc.size - 1, getLine(doc, last).text.length, null, 1, 1) }
if (x < 0) { x = 0; }
var lineObj = getLine(doc, lineN);
for (;;) {
var found = coordsCharInner(cm, lineObj, lineN, x, y);
- var collapsed = collapsedSpanAround(lineObj, found.ch + (found.xRel > 0 ? 1 : 0));
+ var collapsed = collapsedSpanAround(lineObj, found.ch + (found.xRel > 0 || found.outside > 0 ? 1 : 0));
if (!collapsed) { return found }
var rangeEnd = collapsed.find(1);
if (rangeEnd.line == lineN) { return rangeEnd }
@@ -2784,7 +2803,7 @@
// base X position
var coords = cursorCoords(cm, Pos(lineNo$$1, ch, sticky), "line", lineObj, preparedMeasure);
baseX = coords.left;
- outside = y < coords.top || y >= coords.bottom;
+ outside = y < coords.top ? -1 : y >= coords.bottom ? 1 : 0;
}
ch = skipExtendingChars(lineObj.text, ch, 1);
@@ -2853,7 +2872,7 @@
function textHeight(display) {
if (display.cachedTextHeight != null) { return display.cachedTextHeight }
if (measureText == null) {
- measureText = elt("pre");
+ measureText = elt("pre", null, "CodeMirror-line-like");
// Measure a bunch of lines, for browsers that compute
// fractional heights.
for (var i = 0; i < 49; ++i) {
@@ -2873,7 +2892,7 @@
function charWidth(display) {
if (display.cachedCharWidth != null) { return display.cachedCharWidth }
var anchor = elt("span", "xxxxxxxxxx");
- var pre = elt("pre", [anchor]);
+ var pre = elt("pre", [anchor], "CodeMirror-line-like");
removeChildrenAndAdd(display.measure, pre);
var rect = anchor.getBoundingClientRect(), width = (rect.right - rect.left) / 10;
if (width > 2) { display.cachedCharWidth = width; }
@@ -2947,7 +2966,7 @@
try { x = e.clientX - space.left; y = e.clientY - space.top; }
catch (e) { return null }
var coords = coordsChar(cm, x, y), line;
- if (forRect && coords.xRel == 1 && (line = getLine(cm.doc, coords.line).text).length == coords.ch) {
+ if (forRect && coords.xRel > 0 && (line = getLine(cm.doc, coords.line).text).length == coords.ch) {
var colDiff = countColumn(line, line.length, cm.options.tabSize) - line.length;
coords = Pos(coords.line, Math.max(0, Math.round((x - paddingH(cm.display).left) / charWidth(cm.display)) - colDiff));
}
@@ -3536,7 +3555,7 @@
}
function setScrollTop(cm, val, forceScroll) {
- val = Math.min(cm.display.scroller.scrollHeight - cm.display.scroller.clientHeight, val);
+ val = Math.max(0, Math.min(cm.display.scroller.scrollHeight - cm.display.scroller.clientHeight, val));
if (cm.display.scroller.scrollTop == val && !forceScroll) { return }
cm.doc.scrollTop = val;
cm.display.scrollbars.setScrollTop(val);
@@ -3546,7 +3565,7 @@
// Sync scroller and scrollbar, ensure the gutter elements are
// aligned.
function setScrollLeft(cm, val, isScroller, forceScroll) {
- val = Math.min(val, cm.display.scroller.scrollWidth - cm.display.scroller.clientWidth);
+ val = Math.max(0, Math.min(val, cm.display.scroller.scrollWidth - cm.display.scroller.clientWidth));
if ((isScroller ? val == cm.doc.scrollLeft : Math.abs(cm.doc.scrollLeft - val) < 2) && !forceScroll) { return }
cm.doc.scrollLeft = val;
alignHorizontally(cm);
@@ -4037,7 +4056,8 @@
function restoreSelection(snapshot) {
if (!snapshot || !snapshot.activeElt || snapshot.activeElt == activeElt()) { return }
snapshot.activeElt.focus();
- if (snapshot.anchorNode && contains(document.body, snapshot.anchorNode) && contains(document.body, snapshot.focusNode)) {
+ if (!/^(INPUT|TEXTAREA)$/.test(snapshot.activeElt.nodeName) &&
+ snapshot.anchorNode && contains(document.body, snapshot.anchorNode) && contains(document.body, snapshot.focusNode)) {
var sel = window.getSelection(), range$$1 = document.createRange();
range$$1.setEnd(snapshot.anchorNode, snapshot.anchorOffset);
range$$1.collapse(false);
@@ -4135,6 +4155,8 @@
update.visible = visibleLines(cm.display, cm.doc, viewport);
if (update.visible.from >= cm.display.viewFrom && update.visible.to <= cm.display.viewTo)
{ break }
+ } else if (first) {
+ update.visible = visibleLines(cm.display, cm.doc, viewport);
}
if (!updateDisplayIfNeeded(cm, update)) { break }
updateHeightsInViewport(cm);
@@ -5147,8 +5169,15 @@
var line = getLine(doc, pos.line);
if (line.markedSpans) { for (var i = 0; i < line.markedSpans.length; ++i) {
var sp = line.markedSpans[i], m = sp.marker;
- if ((sp.from == null || (m.inclusiveLeft ? sp.from <= pos.ch : sp.from < pos.ch)) &&
- (sp.to == null || (m.inclusiveRight ? sp.to >= pos.ch : sp.to > pos.ch))) {
+
+ // Determine if we should prevent the cursor being placed to the left/right of an atomic marker
+ // Historically this was determined using the inclusiveLeft/Right option, but the new way to control it
+ // is with selectLeft/Right
+ var preventCursorLeft = ("selectLeft" in m) ? !m.selectLeft : m.inclusiveLeft;
+ var preventCursorRight = ("selectRight" in m) ? !m.selectRight : m.inclusiveRight;
+
+ if ((sp.from == null || (preventCursorLeft ? sp.from <= pos.ch : sp.from < pos.ch)) &&
+ (sp.to == null || (preventCursorRight ? sp.to >= pos.ch : sp.to > pos.ch))) {
if (mayClear) {
signal(m, "beforeCursorEnter");
if (m.explicitlyCleared) {
@@ -5160,14 +5189,14 @@
if (oldPos) {
var near = m.find(dir < 0 ? 1 : -1), diff = (void 0);
- if (dir < 0 ? m.inclusiveRight : m.inclusiveLeft)
+ if (dir < 0 ? preventCursorRight : preventCursorLeft)
{ near = movePos(doc, near, -dir, near && near.line == pos.line ? line : null); }
if (near && near.line == pos.line && (diff = cmp(near, oldPos)) && (dir < 0 ? diff < 0 : diff > 0))
{ return skipAtomicInner(doc, near, pos, dir, mayClear) }
}
var far = m.find(dir < 0 ? -1 : 1);
- if (dir < 0 ? m.inclusiveLeft : m.inclusiveRight)
+ if (dir < 0 ? preventCursorLeft : preventCursorRight)
{ far = movePos(doc, far, dir, far.line == pos.line ? line : null); }
return far ? skipAtomicInner(doc, far, pos, dir, mayClear) : null
}
@@ -5396,6 +5425,9 @@
if (doc.cm) { makeChangeSingleDocInEditor(doc.cm, change, spans); }
else { updateDoc(doc, change, spans); }
setSelectionNoUndo(doc, selAfter, sel_dontScroll);
+
+ if (doc.cantEdit && skipAtomic(doc, Pos(doc.firstLine(), 0)))
+ { doc.cantEdit = false; }
}
// Handle the interaction of a change to a document with the editor
@@ -6257,7 +6289,12 @@
for (var i$1 = 0; i$1 < hist.undone.length; i$1++) { if (!hist.undone[i$1].ranges) { ++undone; } }
return {undo: done, redo: undone}
},
- clearHistory: function() {this.history = new History(this.history.maxGeneration);},
+ clearHistory: function() {
+ var this$1 = this;
+
+ this.history = new History(this.history.maxGeneration);
+ linkedDocs(this, function (doc) { return doc.history = this$1.history; }, true);
+ },
markClean: function() {
this.cleanGeneration = this.changeGeneration(true);
@@ -6510,28 +6547,39 @@
// and insert it.
if (files && files.length && window.FileReader && window.File) {
var n = files.length, text = Array(n), read = 0;
- var loadFile = function (file, i) {
- if (cm.options.allowDropFileTypes &&
- indexOf(cm.options.allowDropFileTypes, file.type) == -1)
- { return }
-
- var reader = new FileReader;
- reader.onload = operation(cm, function () {
- var content = reader.result;
- if (/[\x00-\x08\x0e-\x1f]{2}/.test(content)) { content = ""; }
- text[i] = content;
- if (++read == n) {
+ var markAsReadAndPasteIfAllFilesAreRead = function () {
+ if (++read == n) {
+ operation(cm, function () {
pos = clipPos(cm.doc, pos);
var change = {from: pos, to: pos,
- text: cm.doc.splitLines(text.join(cm.doc.lineSeparator())),
+ text: cm.doc.splitLines(
+ text.filter(function (t) { return t != null; }).join(cm.doc.lineSeparator())),
origin: "paste"};
makeChange(cm.doc, change);
- setSelectionReplaceHistory(cm.doc, simpleSelection(pos, changeEnd(change)));
+ setSelectionReplaceHistory(cm.doc, simpleSelection(clipPos(cm.doc, pos), clipPos(cm.doc, changeEnd(change))));
+ })();
+ }
+ };
+ var readTextFromFile = function (file, i) {
+ if (cm.options.allowDropFileTypes &&
+ indexOf(cm.options.allowDropFileTypes, file.type) == -1) {
+ markAsReadAndPasteIfAllFilesAreRead();
+ return
+ }
+ var reader = new FileReader;
+ reader.onerror = function () { return markAsReadAndPasteIfAllFilesAreRead(); };
+ reader.onload = function () {
+ var content = reader.result;
+ if (/[\x00-\x08\x0e-\x1f]{2}/.test(content)) {
+ markAsReadAndPasteIfAllFilesAreRead();
+ return
}
- });
+ text[i] = content;
+ markAsReadAndPasteIfAllFilesAreRead();
+ };
reader.readAsText(file);
};
- for (var i = 0; i < n; ++i) { loadFile(files[i], i); }
+ for (var i = 0; i < files.length; i++) { readTextFromFile(files[i], i); }
} else { // Normal drop
// Don't do a replace if the drop happened inside of the selected text.
if (cm.state.draggingText && cm.doc.sel.contains(pos) > -1) {
@@ -6841,6 +6889,7 @@
function endOfLine(visually, cm, lineObj, lineNo, dir) {
if (visually) {
+ if (cm.doc.direction == "rtl") { dir = -dir; }
var order = getOrder(lineObj, cm.doc.direction);
if (order) {
var part = dir < 0 ? lst(order) : order[0];
@@ -7095,7 +7144,7 @@
var line = getLine(cm.doc, start.line);
var order = getOrder(line, cm.doc.direction);
if (!order || order[0].level == 0) {
- var firstNonWS = Math.max(0, line.text.search(/\S/));
+ var firstNonWS = Math.max(start.ch, line.text.search(/\S/));
var inWS = pos.line == start.line && pos.ch <= firstNonWS && pos.ch;
return Pos(start.line, inWS ? 0 : firstNonWS, start.sticky)
}
@@ -7198,6 +7247,7 @@
var lastStoppedKey = null;
function onKeyDown(e) {
var cm = this;
+ if (e.target && e.target != cm.display.input.getField()) { return }
cm.curOp.focus = activeElt();
if (signalDOMEvent(cm, e)) { return }
// IE does strange things with escape.
@@ -7211,6 +7261,8 @@
if (!handled && code == 88 && !hasCopyEvent && (mac ? e.metaKey : e.ctrlKey))
{ cm.replaceSelection("", null, "cut"); }
}
+ if (gecko && !mac && !handled && code == 46 && e.shiftKey && !e.ctrlKey && document.execCommand)
+ { document.execCommand("cut"); }
// Turn mouse into crosshair when Alt is held on Mac.
if (code == 18 && !/\bCodeMirror-crosshair\b/.test(cm.display.lineDiv.className))
@@ -7239,6 +7291,7 @@
function onKeyPress(e) {
var cm = this;
+ if (e.target && e.target != cm.display.input.getField()) { return }
if (eventInWidget(cm.display, e) || signalDOMEvent(cm, e) || e.ctrlKey && !e.altKey || mac && e.metaKey) { return }
var keyCode = e.keyCode, charCode = e.charCode;
if (presto && keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return}
@@ -7387,8 +7440,8 @@
if (!behavior.addNew)
{ extendSelection(cm.doc, pos, null, null, behavior.extend); }
// Work around unexplainable focus problem in IE9 (#2127) and Chrome (#3081)
- if (webkit || ie && ie_version == 9)
- { setTimeout(function () {display.wrapper.ownerDocument.body.focus(); display.input.focus();}, 20); }
+ if ((webkit && !safari) || ie && ie_version == 9)
+ { setTimeout(function () {display.wrapper.ownerDocument.body.focus({preventScroll: true}); display.input.focus();}, 20); }
else
{ display.input.focus(); }
}
@@ -7700,7 +7753,7 @@
for (var i = newBreaks.length - 1; i >= 0; i--)
{ replaceRange(cm.doc, val, newBreaks[i], Pos(newBreaks[i].line, newBreaks[i].ch + val.length)); }
});
- option("specialChars", /[\u0000-\u001f\u007f-\u009f\u00ad\u061c\u200b-\u200f\u2028\u2029\ufeff]/g, function (cm, val, old) {
+ option("specialChars", /[\u0000-\u001f\u007f-\u009f\u00ad\u061c\u200b-\u200f\u2028\u2029\ufeff\ufff9-\ufffc]/g, function (cm, val, old) {
cm.state.specialChars = new RegExp(val.source + (val.test("\t") ? "" : "|\t"), "g");
if (old != Init) { cm.refresh(); }
});
@@ -7764,6 +7817,12 @@
}
cm.display.input.readOnlyChanged(val);
});
+
+ option("screenReaderLabel", null, function (cm, val) {
+ val = (val === '') ? null : val;
+ cm.display.input.screenReaderLabelChanged(val);
+ });
+
option("disableInput", false, function (cm, val) {if (!val) { cm.display.input.reset(); }}, true);
option("dragDrop", true, dragDropChanged);
option("allowDropFileTypes", null);
@@ -7916,6 +7975,9 @@
// which point we can't mess with it anymore. Context menu is
// handled in onMouseDown for these browsers.
on(d.scroller, "contextmenu", function (e) { return onContextMenu(cm, e); });
+ on(d.input.getField(), "contextmenu", function (e) {
+ if (!d.scroller.contains(e.target)) { onContextMenu(cm, e); }
+ });
// Used to suppress mouse event handling when a touch happens
var touchFinished, prevTouch = {end: 0};
@@ -8602,7 +8664,7 @@
clearCaches(this);
scrollToCoords(this, this.doc.scrollLeft, this.doc.scrollTop);
updateGutterSpace(this.display);
- if (oldHeight == null || Math.abs(oldHeight - textHeight(this.display)) > .5)
+ if (oldHeight == null || Math.abs(oldHeight - textHeight(this.display)) > .5 || this.options.lineWrapping)
{ estimateLineHeights(this); }
signal(this, "refresh", this);
}),
@@ -8656,8 +8718,9 @@
var oldPos = pos;
var origDir = dir;
var lineObj = getLine(doc, pos.line);
+ var lineDir = visually && doc.direction == "rtl" ? -dir : dir;
function findNextLine() {
- var l = pos.line + dir;
+ var l = pos.line + lineDir;
if (l < doc.first || l >= doc.first + doc.size) { return false }
pos = new Pos(l, pos.ch, pos.sticky);
return lineObj = getLine(doc, l)
@@ -8671,7 +8734,7 @@
}
if (next == null) {
if (!boundToLine && findNextLine())
- { pos = endOfLine(visually, doc.cm, lineObj, pos.line, dir); }
+ { pos = endOfLine(visually, doc.cm, lineObj, pos.line, lineDir); }
else
{ return false }
} else {
@@ -8750,8 +8813,16 @@
var div = input.div = display.lineDiv;
disableBrowserMagic(div, cm.options.spellcheck, cm.options.autocorrect, cm.options.autocapitalize);
+ function belongsToInput(e) {
+ for (var t = e.target; t; t = t.parentNode) {
+ if (t == div) { return true }
+ if (/\bCodeMirror-(?:line)?widget\b/.test(t.className)) { break }
+ }
+ return false
+ }
+
on(div, "paste", function (e) {
- if (signalDOMEvent(cm, e) || handlePaste(e, cm)) { return }
+ if (!belongsToInput(e) || signalDOMEvent(cm, e) || handlePaste(e, cm)) { return }
// IE doesn't fire input events, so we schedule a read for the pasted content in this way
if (ie_version <= 11) { setTimeout(operation(cm, function () { return this$1.updateFromDOM(); }), 20); }
});
@@ -8776,7 +8847,7 @@
});
function onCopyCut(e) {
- if (signalDOMEvent(cm, e)) { return }
+ if (!belongsToInput(e) || signalDOMEvent(cm, e)) { return }
if (cm.somethingSelected()) {
setLastCopied({lineWise: false, text: cm.getSelections()});
if (e.type == "cut") { cm.replaceSelection("", null, "cut"); }
@@ -8818,9 +8889,18 @@
on(div, "cut", onCopyCut);
};
+ ContentEditableInput.prototype.screenReaderLabelChanged = function (label) {
+ // Label for screenreaders, accessibility
+ if(label) {
+ this.div.setAttribute('aria-label', label);
+ } else {
+ this.div.removeAttribute('aria-label');
+ }
+ };
+
ContentEditableInput.prototype.prepareSelection = function () {
var result = prepareSelection(this.cm, false);
- result.focus = this.cm.state.focused;
+ result.focus = document.activeElement == this.div;
return result
};
@@ -8916,7 +8996,7 @@
ContentEditableInput.prototype.focus = function () {
if (this.cm.options.readOnly != "nocursor") {
- if (!this.selectionInEditor())
+ if (!this.selectionInEditor() || document.activeElement != this.div)
{ this.showSelection(this.prepareSelection(), true); }
this.div.focus();
}
@@ -9358,6 +9438,15 @@
this.textarea = this.wrapper.firstChild;
};
+ TextareaInput.prototype.screenReaderLabelChanged = function (label) {
+ // Label for screenreaders, accessibility
+ if(label) {
+ this.textarea.setAttribute('aria-label', label);
+ } else {
+ this.textarea.removeAttribute('aria-label');
+ }
+ };
+
TextareaInput.prototype.prepareSelection = function () {
// Redraw the selection and/or cursor
var cm = this.cm, display = cm.display, doc = cm.doc;
@@ -9649,7 +9738,7 @@
textarea.style.display = "";
if (textarea.form) {
off(textarea.form, "submit", save);
- if (typeof textarea.form.submit == "function")
+ if (!options.leaveSubmitMethodAlone && typeof textarea.form.submit == "function")
{ textarea.form.submit = realSubmit; }
}
};
@@ -9748,7 +9837,7 @@
addLegacyProps(CodeMirror);
- CodeMirror.version = "5.46.0";
+ CodeMirror.version = "5.54.0";
return CodeMirror;
diff --git a/src/codemirror/mode/clike/clike.js b/src/assets/plugins/codemirror/mode/clike/clike.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/mode/clike/clike.js
rename to src/assets/plugins/codemirror/mode/clike/clike.js
diff --git a/src/codemirror/mode/clike/index.html b/src/assets/plugins/codemirror/mode/clike/index.html
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/mode/clike/index.html
rename to src/assets/plugins/codemirror/mode/clike/index.html
diff --git a/src/codemirror/mode/clike/scala.html b/src/assets/plugins/codemirror/mode/clike/scala.html
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/mode/clike/scala.html
rename to src/assets/plugins/codemirror/mode/clike/scala.html
diff --git a/src/codemirror/mode/clike/test.js b/src/assets/plugins/codemirror/mode/clike/test.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/mode/clike/test.js
rename to src/assets/plugins/codemirror/mode/clike/test.js
diff --git a/src/assets/plugins/codemirror/mode/coffeescript/coffeescript.js b/src/assets/plugins/codemirror/mode/coffeescript/coffeescript.js
new file mode 100644
index 0000000..a54e9d5
--- /dev/null
+++ b/src/assets/plugins/codemirror/mode/coffeescript/coffeescript.js
@@ -0,0 +1,359 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: https://codemirror.net/LICENSE
+
+/**
+ * Link to the project's GitHub page:
+ * https://github.com/pickhardt/coffeescript-codemirror-mode
+ */
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
+ mod(require("../../lib/codemirror"));
+ else if (typeof define == "function" && define.amd) // AMD
+ define(["../../lib/codemirror"], mod);
+ else // Plain browser env
+ mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("coffeescript", function(conf, parserConf) {
+ var ERRORCLASS = "error";
+
+ function wordRegexp(words) {
+ return new RegExp("^((" + words.join(")|(") + "))\\b");
+ }
+
+ var operators = /^(?:->|=>|\+[+=]?|-[\-=]?|\*[\*=]?|\/[\/=]?|[=!]=|<[><]?=?|>>?=?|%=?|&=?|\|=?|\^=?|\~|!|\?|(or|and|\|\||&&|\?)=)/;
+ var delimiters = /^(?:[()\[\]{},:`=;]|\.\.?\.?)/;
+ var identifiers = /^[_A-Za-z$][_A-Za-z$0-9]*/;
+ var atProp = /^@[_A-Za-z$][_A-Za-z$0-9]*/;
+
+ var wordOperators = wordRegexp(["and", "or", "not",
+ "is", "isnt", "in",
+ "instanceof", "typeof"]);
+ var indentKeywords = ["for", "while", "loop", "if", "unless", "else",
+ "switch", "try", "catch", "finally", "class"];
+ var commonKeywords = ["break", "by", "continue", "debugger", "delete",
+ "do", "in", "of", "new", "return", "then",
+ "this", "@", "throw", "when", "until", "extends"];
+
+ var keywords = wordRegexp(indentKeywords.concat(commonKeywords));
+
+ indentKeywords = wordRegexp(indentKeywords);
+
+
+ var stringPrefixes = /^('{3}|\"{3}|['\"])/;
+ var regexPrefixes = /^(\/{3}|\/)/;
+ var commonConstants = ["Infinity", "NaN", "undefined", "null", "true", "false", "on", "off", "yes", "no"];
+ var constants = wordRegexp(commonConstants);
+
+ // Tokenizers
+ function tokenBase(stream, state) {
+ // Handle scope changes
+ if (stream.sol()) {
+ if (state.scope.align === null) state.scope.align = false;
+ var scopeOffset = state.scope.offset;
+ if (stream.eatSpace()) {
+ var lineOffset = stream.indentation();
+ if (lineOffset > scopeOffset && state.scope.type == "coffee") {
+ return "indent";
+ } else if (lineOffset < scopeOffset) {
+ return "dedent";
+ }
+ return null;
+ } else {
+ if (scopeOffset > 0) {
+ dedent(stream, state);
+ }
+ }
+ }
+ if (stream.eatSpace()) {
+ return null;
+ }
+
+ var ch = stream.peek();
+
+ // Handle docco title comment (single line)
+ if (stream.match("####")) {
+ stream.skipToEnd();
+ return "comment";
+ }
+
+ // Handle multi line comments
+ if (stream.match("###")) {
+ state.tokenize = longComment;
+ return state.tokenize(stream, state);
+ }
+
+ // Single line comment
+ if (ch === "#") {
+ stream.skipToEnd();
+ return "comment";
+ }
+
+ // Handle number literals
+ if (stream.match(/^-?[0-9\.]/, false)) {
+ var floatLiteral = false;
+ // Floats
+ if (stream.match(/^-?\d*\.\d+(e[\+\-]?\d+)?/i)) {
+ floatLiteral = true;
+ }
+ if (stream.match(/^-?\d+\.\d*/)) {
+ floatLiteral = true;
+ }
+ if (stream.match(/^-?\.\d+/)) {
+ floatLiteral = true;
+ }
+
+ if (floatLiteral) {
+ // prevent from getting extra . on 1..
+ if (stream.peek() == "."){
+ stream.backUp(1);
+ }
+ return "number";
+ }
+ // Integers
+ var intLiteral = false;
+ // Hex
+ if (stream.match(/^-?0x[0-9a-f]+/i)) {
+ intLiteral = true;
+ }
+ // Decimal
+ if (stream.match(/^-?[1-9]\d*(e[\+\-]?\d+)?/)) {
+ intLiteral = true;
+ }
+ // Zero by itself with no other piece of number.
+ if (stream.match(/^-?0(?![\dx])/i)) {
+ intLiteral = true;
+ }
+ if (intLiteral) {
+ return "number";
+ }
+ }
+
+ // Handle strings
+ if (stream.match(stringPrefixes)) {
+ state.tokenize = tokenFactory(stream.current(), false, "string");
+ return state.tokenize(stream, state);
+ }
+ // Handle regex literals
+ if (stream.match(regexPrefixes)) {
+ if (stream.current() != "/" || stream.match(/^.*\//, false)) { // prevent highlight of division
+ state.tokenize = tokenFactory(stream.current(), true, "string-2");
+ return state.tokenize(stream, state);
+ } else {
+ stream.backUp(1);
+ }
+ }
+
+
+
+ // Handle operators and delimiters
+ if (stream.match(operators) || stream.match(wordOperators)) {
+ return "operator";
+ }
+ if (stream.match(delimiters)) {
+ return "punctuation";
+ }
+
+ if (stream.match(constants)) {
+ return "atom";
+ }
+
+ if (stream.match(atProp) || state.prop && stream.match(identifiers)) {
+ return "property";
+ }
+
+ if (stream.match(keywords)) {
+ return "keyword";
+ }
+
+ if (stream.match(identifiers)) {
+ return "variable";
+ }
+
+ // Handle non-detected items
+ stream.next();
+ return ERRORCLASS;
+ }
+
+ function tokenFactory(delimiter, singleline, outclass) {
+ return function(stream, state) {
+ while (!stream.eol()) {
+ stream.eatWhile(/[^'"\/\\]/);
+ if (stream.eat("\\")) {
+ stream.next();
+ if (singleline && stream.eol()) {
+ return outclass;
+ }
+ } else if (stream.match(delimiter)) {
+ state.tokenize = tokenBase;
+ return outclass;
+ } else {
+ stream.eat(/['"\/]/);
+ }
+ }
+ if (singleline) {
+ if (parserConf.singleLineStringErrors) {
+ outclass = ERRORCLASS;
+ } else {
+ state.tokenize = tokenBase;
+ }
+ }
+ return outclass;
+ };
+ }
+
+ function longComment(stream, state) {
+ while (!stream.eol()) {
+ stream.eatWhile(/[^#]/);
+ if (stream.match("###")) {
+ state.tokenize = tokenBase;
+ break;
+ }
+ stream.eatWhile("#");
+ }
+ return "comment";
+ }
+
+ function indent(stream, state, type) {
+ type = type || "coffee";
+ var offset = 0, align = false, alignOffset = null;
+ for (var scope = state.scope; scope; scope = scope.prev) {
+ if (scope.type === "coffee" || scope.type == "}") {
+ offset = scope.offset + conf.indentUnit;
+ break;
+ }
+ }
+ if (type !== "coffee") {
+ align = null;
+ alignOffset = stream.column() + stream.current().length;
+ } else if (state.scope.align) {
+ state.scope.align = false;
+ }
+ state.scope = {
+ offset: offset,
+ type: type,
+ prev: state.scope,
+ align: align,
+ alignOffset: alignOffset
+ };
+ }
+
+ function dedent(stream, state) {
+ if (!state.scope.prev) return;
+ if (state.scope.type === "coffee") {
+ var _indent = stream.indentation();
+ var matched = false;
+ for (var scope = state.scope; scope; scope = scope.prev) {
+ if (_indent === scope.offset) {
+ matched = true;
+ break;
+ }
+ }
+ if (!matched) {
+ return true;
+ }
+ while (state.scope.prev && state.scope.offset !== _indent) {
+ state.scope = state.scope.prev;
+ }
+ return false;
+ } else {
+ state.scope = state.scope.prev;
+ return false;
+ }
+ }
+
+ function tokenLexer(stream, state) {
+ var style = state.tokenize(stream, state);
+ var current = stream.current();
+
+ // Handle scope changes.
+ if (current === "return") {
+ state.dedent = true;
+ }
+ if (((current === "->" || current === "=>") && stream.eol())
+ || style === "indent") {
+ indent(stream, state);
+ }
+ var delimiter_index = "[({".indexOf(current);
+ if (delimiter_index !== -1) {
+ indent(stream, state, "])}".slice(delimiter_index, delimiter_index+1));
+ }
+ if (indentKeywords.exec(current)){
+ indent(stream, state);
+ }
+ if (current == "then"){
+ dedent(stream, state);
+ }
+
+
+ if (style === "dedent") {
+ if (dedent(stream, state)) {
+ return ERRORCLASS;
+ }
+ }
+ delimiter_index = "])}".indexOf(current);
+ if (delimiter_index !== -1) {
+ while (state.scope.type == "coffee" && state.scope.prev)
+ state.scope = state.scope.prev;
+ if (state.scope.type == current)
+ state.scope = state.scope.prev;
+ }
+ if (state.dedent && stream.eol()) {
+ if (state.scope.type == "coffee" && state.scope.prev)
+ state.scope = state.scope.prev;
+ state.dedent = false;
+ }
+
+ return style;
+ }
+
+ var external = {
+ startState: function(basecolumn) {
+ return {
+ tokenize: tokenBase,
+ scope: {offset:basecolumn || 0, type:"coffee", prev: null, align: false},
+ prop: false,
+ dedent: 0
+ };
+ },
+
+ token: function(stream, state) {
+ var fillAlign = state.scope.align === null && state.scope;
+ if (fillAlign && stream.sol()) fillAlign.align = false;
+
+ var style = tokenLexer(stream, state);
+ if (style && style != "comment") {
+ if (fillAlign) fillAlign.align = true;
+ state.prop = style == "punctuation" && stream.current() == "."
+ }
+
+ return style;
+ },
+
+ indent: function(state, text) {
+ if (state.tokenize != tokenBase) return 0;
+ var scope = state.scope;
+ var closer = text && "])}".indexOf(text.charAt(0)) > -1;
+ if (closer) while (scope.type == "coffee" && scope.prev) scope = scope.prev;
+ var closes = closer && scope.type === text.charAt(0);
+ if (scope.align)
+ return scope.alignOffset - (closes ? 1 : 0);
+ else
+ return (closes ? scope.prev : scope).offset;
+ },
+
+ lineComment: "#",
+ fold: "indent"
+ };
+ return external;
+});
+
+// IANA registered media type
+// https://www.iana.org/assignments/media-types/
+CodeMirror.defineMIME("application/vnd.coffeescript", "coffeescript");
+
+CodeMirror.defineMIME("text/x-coffeescript", "coffeescript");
+CodeMirror.defineMIME("text/coffeescript", "coffeescript");
+
+});
diff --git a/src/assets/plugins/codemirror/mode/coffeescript/index.html b/src/assets/plugins/codemirror/mode/coffeescript/index.html
new file mode 100644
index 0000000..6d51aab
--- /dev/null
+++ b/src/assets/plugins/codemirror/mode/coffeescript/index.html
@@ -0,0 +1,740 @@
+
+
+CodeMirror: CoffeeScript mode
+
+
+
+
+
+
+
+
Home
diff --git a/src/codemirror/mode/htmlmixed/htmlmixed.js b/src/assets/plugins/codemirror/mode/htmlmixed/htmlmixed.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/mode/htmlmixed/htmlmixed.js
rename to src/assets/plugins/codemirror/mode/htmlmixed/htmlmixed.js
diff --git a/src/codemirror/mode/htmlmixed/index.html b/src/assets/plugins/codemirror/mode/htmlmixed/index.html
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/mode/htmlmixed/index.html
rename to src/assets/plugins/codemirror/mode/htmlmixed/index.html
diff --git a/src/codemirror/mode/index.html b/src/assets/plugins/codemirror/mode/index.html
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/mode/index.html
rename to src/assets/plugins/codemirror/mode/index.html
diff --git a/src/codemirror/mode/javascript/index.html b/src/assets/plugins/codemirror/mode/javascript/index.html
old mode 100755
new mode 100644
similarity index 99%
rename from src/codemirror/mode/javascript/index.html
rename to src/assets/plugins/codemirror/mode/javascript/index.html
index 4eff2e2..d1f7f68
--- a/src/codemirror/mode/javascript/index.html
+++ b/src/assets/plugins/codemirror/mode/javascript/index.html
@@ -12,7 +12,7 @@
Home
diff --git a/src/codemirror/mode/lua/index.html b/src/assets/plugins/codemirror/mode/lua/index.html
old mode 100755
new mode 100644
similarity index 98%
rename from src/codemirror/mode/lua/index.html
rename to src/assets/plugins/codemirror/mode/lua/index.html
index 59f4df3..05c9446
--- a/src/codemirror/mode/lua/index.html
+++ b/src/assets/plugins/codemirror/mode/lua/index.html
@@ -11,7 +11,7 @@
Home
diff --git a/src/codemirror/mode/perl/perl.js b/src/assets/plugins/codemirror/mode/perl/perl.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/mode/perl/perl.js
rename to src/assets/plugins/codemirror/mode/perl/perl.js
diff --git a/src/codemirror/mode/php/index.html b/src/assets/plugins/codemirror/mode/php/index.html
old mode 100755
new mode 100644
similarity index 97%
rename from src/codemirror/mode/php/index.html
rename to src/assets/plugins/codemirror/mode/php/index.html
index 6897641..0de6ae6
--- a/src/codemirror/mode/php/index.html
+++ b/src/assets/plugins/codemirror/mode/php/index.html
@@ -15,7 +15,7 @@
Home
diff --git a/src/codemirror/mode/php/php.js b/src/assets/plugins/codemirror/mode/php/php.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/mode/php/php.js
rename to src/assets/plugins/codemirror/mode/php/php.js
diff --git a/src/codemirror/mode/php/test.js b/src/assets/plugins/codemirror/mode/php/test.js
old mode 100755
new mode 100644
similarity index 100%
rename from src/codemirror/mode/php/test.js
rename to src/assets/plugins/codemirror/mode/php/test.js
diff --git a/src/codemirror/mode/powershell/index.html b/src/assets/plugins/codemirror/mode/powershell/index.html
old mode 100755
new mode 100644
similarity index 99%
rename from src/codemirror/mode/powershell/index.html
rename to src/assets/plugins/codemirror/mode/powershell/index.html
index 6bb7bab..fae0298
--- a/src/codemirror/mode/powershell/index.html
+++ b/src/assets/plugins/codemirror/mode/powershell/index.html
@@ -28,6 +28,10 @@