Git
Threads by month
- ----- 2025 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- 13 participants
- 38624 discussions

[Phpmyadmin-git] [SCM] phpMyAdmin branch, master, updated. RELEASE_3_5_0BETA1-238-ge64d33b
by Michal Čihař 27 Jan '12
by Michal Čihař 27 Jan '12
27 Jan '12
The branch, master has been updated
via e64d33bba3b7355f25dbf637de9732367ed8a24e (commit)
via 3ef4b37f447469b51e3842a26f15e864798354ff (commit)
via 9f3e5f46028a5f6e30915f5c547a348b7942ed5c (commit)
via fa57bf1b7cd2061ae0bd3c548af7673246e63ecb (commit)
via 0a6ae4b26077674e12364d38caa7f469044eb65f (commit)
via 24e8aacd051dce33a9db0e44ce1c6c388baaf5b9 (commit)
via ced6716d71a2943875912a9875e9073510e0bc84 (commit)
via 4301ed2ab948cb90ceb1a6fe3a5cfa055e9ec5d3 (commit)
via 61c2348201746bac0c332131683a3938b450df40 (commit)
via 8ae4e415546a722d898ed0a3291562f52ded3873 (commit)
via 64d4d0e7d2f7e8a51f1a3480eeec1f076765612c (commit)
via cf8118c0906d5f3cbb8f2a908042d671eecc2972 (commit)
via b2b31f9b892d27174c2b99228ce1bc7a2f4ea39b (commit)
via ec1ab93652d9ece93d4bd6a2e437cae99bc06e3d (commit)
via a64923acac18759ee90a7acc453aa29814f5f534 (commit)
via 39919646625e9d562cfdf01eda82f25f6fc68177 (commit)
via 0052f63c632bbcd78de5fec9d5730bfc0a5992c8 (commit)
via e4d110b4d489e19380059289bce572fa73d2b2a8 (commit)
via e79d0bc1de688b843a7ebc8caea068a9278ddee6 (commit)
via 760fe8de1b711b86584a98432c09ddb93beb9b48 (commit)
via e66f23fcae4bff5b13a464c980b03fb41d423c0a (commit)
via dda8dc59745d90612476bc0d09630b21cd03188c (commit)
from a8e38f8cdbe331ba2092c6efa45bfadfca82df11 (commit)
- Log -----------------------------------------------------------------
-----------------------------------------------------------------------
Summary of changes:
po/cs.po | 40 +++++++++++++++++++++++++++++++---------
po/ko.po | 28 ++++++++--------------------
2 files changed, 39 insertions(+), 29 deletions(-)
diff --git a/po/cs.po b/po/cs.po
index e6cd5ba..7c39b20 100644
--- a/po/cs.po
+++ b/po/cs.po
@@ -5,7 +5,7 @@ msgstr ""
"Project-Id-Version: phpMyAdmin 3.5.0-beta2\n"
"Report-Msgid-Bugs-To: phpmyadmin-devel(a)lists.sourceforge.net\n"
"POT-Creation-Date: 2012-01-25 17:45+0100\n"
-"PO-Revision-Date: 2012-01-24 21:07+0200\n"
+"PO-Revision-Date: 2012-01-27 14:58+0200\n"
"Last-Translator: Michal Čihař <michal(a)cihar.com>\n"
"Language-Team: czech <cs(a)li.org>\n"
"Language: cs\n"
@@ -12398,11 +12398,15 @@ msgid ""
"This means that joins are doing full table scans. Adding indexes for the "
"columns being used in the join conditions will greatly speed up table joins"
msgstr ""
+"To znamená, že spojení tabulek musí často procházet celou tabulku. Přidáním "
+"klíčů na sloupce použité při slučování můžete tuto operaci značně urychlit."
#: po/advisory_rules.php:128
#, php-format
msgid "Table joins average: %s, this value should be less than 1 per hour"
msgstr ""
+"Průměrně sloučeno tabulek: %s, tato hodnota by měla být menší než 1 za "
+"hodinu"
#: po/advisory_rules.php:130
msgid "Rate of reading first index entry"
@@ -12426,6 +12430,8 @@ msgstr ""
#, php-format
msgid "Index scans average: %s, this value should be less than 1 per hour"
msgstr ""
+"Průměrně procházeno klíčů: %s, tato hodnota by měla být menší než 1 za "
+"hodinu"
#: po/advisory_rules.php:135
msgid "Rate of reading fixed position"
@@ -12448,6 +12454,8 @@ msgid ""
"Rate of reading fixed position average: %s, this value should be less than 1 "
"per hour"
msgstr ""
+"Četnost čtení na pevné pozici: %s, tato hodnota by měla být menší než 1 za "
+"hodinu"
#: po/advisory_rules.php:140
msgid "Rate of reading next table row"
@@ -12468,6 +12476,8 @@ msgstr ""
msgid ""
"Rate of reading next table row: %s, this value should be less than 1 per hour"
msgstr ""
+"Četnost čtení dalšího řádku tabulky: %s, tato hodnota by měla být menší než "
+"1 za hodinu"
#: po/advisory_rules.php:145
msgid "tmp_table_size vs. max_heap_table_size"
@@ -12541,6 +12551,8 @@ msgid ""
"Rate of temporary tables being written to disk: %s, this value should be "
"less than 1 per hour"
msgstr ""
+"Četnost dočasného ukládání na disk: %s, tato hodnota by měla být menší než 1 "
+"za hodinu"
#: po/advisory_rules.php:160
msgid "MyISAM key buffer size"
@@ -12633,6 +12645,8 @@ msgstr ""
#, php-format
msgid "Opened table rate: %s, this value should be less than 10 per hour"
msgstr ""
+"Četnost otevírání tabulek: %s, tato hodnota by měla být menší než 10 za "
+"hodinu"
#: po/advisory_rules.php:185
#, fuzzy
@@ -12659,10 +12673,9 @@ msgid ""
msgstr ""
#: po/advisory_rules.php:190
-#, fuzzy
#| msgid "Format of imported file"
msgid "Rate of open files"
-msgstr "Formát importovaného souboru"
+msgstr "Četnost otevírání souborů"
#: po/advisory_rules.php:191
#, fuzzy
@@ -12674,6 +12687,8 @@ msgstr "Počet nevyřízených synchronizací logovacích souborů."
#, php-format
msgid "Opened files rate: %s, this value should be less than 5 per hour"
msgstr ""
+"Četnost otevírání souborů: %s, tato hodnota by měla být menší než 5 za "
+"hodinu"
#: po/advisory_rules.php:195
#, php-format
@@ -12697,12 +12712,14 @@ msgstr ""
#: po/advisory_rules.php:200
msgid "Table lock wait rate"
-msgstr ""
+msgstr "Četnost čekání na zámek tabulky"
#: po/advisory_rules.php:203
#, php-format
msgid "Table lock wait rate: %s, this value should be less than 1 per hour"
msgstr ""
+"Četnost čekání na zámek tabulky: %s, tato hodnota by měla být menší než 1 za "
+"hodinu"
#: po/advisory_rules.php:205
#, fuzzy
@@ -12746,19 +12763,20 @@ msgstr ""
#: po/advisory_rules.php:215
msgid "Threads that are slow to launch"
-msgstr ""
+msgstr "Vlákna se spouštějí příliš dlouho"
#: po/advisory_rules.php:216
-#, fuzzy
#| msgid "The number of threads that are not sleeping."
msgid "There are too many threads that are slow to launch."
-msgstr "Počet vláken, která nespí."
+msgstr "Je příliš mnoho vláken, která se spouštějí dlouho."
#: po/advisory_rules.php:217
msgid ""
"This generally happens in case of general system overload as it is pretty "
"simple operations. You might want to monitor your system load carefully."
msgstr ""
+"K tomuto obvykle dochází v případě přetížení systému, protože se jedná o "
+"velmi jednoduchou operaci. Je vhodné podrobně sledovat zatížení systému."
#: po/advisory_rules.php:218
#, php-format
@@ -12839,6 +12857,8 @@ msgstr "Trvalé připojení"
msgid ""
"Aborted connections rate is at %s, this value should be less than 1 per hour"
msgstr ""
+"Četnost přerušených spojení je %s, tato hodnota by měla být menší než 1 za "
+"hodinu"
#: po/advisory_rules.php:240
msgid "Percentage of aborted clients"
@@ -12870,10 +12890,12 @@ msgstr "Formát importovaného souboru"
#, php-format
msgid "Aborted client rate is at %s, this value should be less than 1 per hour"
msgstr ""
+"Četnost přerušených klientů: %s, tato hodnota by měla být menší než 1 za "
+"hodinu"
#: po/advisory_rules.php:250
msgid "Is InnoDB disabled?"
-msgstr ""
+msgstr "InnoDB je vypnuto?"
#: po/advisory_rules.php:251
msgid "You do not have InnoDB enabled."
@@ -12881,7 +12903,7 @@ msgstr "Máte zakázané InnoDB."
#: po/advisory_rules.php:252
msgid "InnoDB is usually the better choice for table engines."
-msgstr ""
+msgstr "InnoDB je obvykle nejlepší volba úložiště tabulky."
#: po/advisory_rules.php:253
msgid "have_innodb is set to 'value'"
diff --git a/po/ko.po b/po/ko.po
index 3b66495..1405a21 100644
--- a/po/ko.po
+++ b/po/ko.po
@@ -5,7 +5,7 @@ msgstr ""
"Report-Msgid-Bugs-To: phpmyadmin-devel(a)lists.sourceforge.net\n"
"POT-Creation-Date: 2012-01-25 17:45+0100\n"
"PO-Revision-Date: 2012-01-27 08:18+0200\n"
-"Last-Translator: manyfun <manyfun7(a)gmail.com>\n"
+"Last-Translator: minsung kang <manyfun7(a)gmail.com>\n"
"Language-Team: korean <ko(a)li.org>\n"
"Language: ko\n"
"MIME-Version: 1.0\n"
@@ -806,25 +806,22 @@ msgid "ENUM/SET editor"
msgstr "ENUM/SET 수정"
#: enum_editor.php:28 js/messages.php:268
-#, fuzzy
#| msgid "Values for the column \"%s\""
msgid "Values for a new column"
msgstr "새로운 열의 값"
#: enum_editor.php:30 js/messages.php:267
-#, fuzzy, php-format
+#, php-format
#| msgid "Values for the column \"%s\""
msgid "Values for column %s"
msgstr "\"%s\" 열의 값"
#: enum_editor.php:34 js/messages.php:269
-#, fuzzy
#| msgid "Enter each value in a separate field."
msgid "Enter each value in a separate field"
msgstr "각각의 필드에 값을 입력하세요"
#: enum_editor.php:123
-#, fuzzy
msgid "Add a value"
msgstr "값을 추가"
@@ -941,7 +938,6 @@ msgid "Add an inner ring"
msgstr "내부 링 추가"
#: gis_data_editor.php:266 js/messages.php:322
-#, fuzzy
msgid "Polygon"
msgstr "폴리곤"
@@ -1103,7 +1099,6 @@ msgid "This is not a number!"
msgstr "은 숫자가 아닙니다!"
#: js/messages.php:46
-#, fuzzy
#| msgid "Add index"
msgid "Add Index"
msgstr "인덱스 추가"
@@ -1114,7 +1109,7 @@ msgid "Edit Index"
msgstr "인덱스 수정"
#: js/messages.php:48 tbl_indexes.php:293
-#, fuzzy, php-format
+#, php-format
msgid "Add %d column(s) to index"
msgstr "인덱스에 %d 열 추가"
@@ -1249,7 +1244,6 @@ msgid "Local monitor configuration incompatible"
msgstr "호환되지 않는 로컬 모니터 설정입니다."
#: js/messages.php:95
-#, fuzzy
msgid ""
"The chart arrangement configuration in your browsers local storage is not "
"compatible anymore to the newer version of the monitor dialog. It is very "
@@ -1373,11 +1367,11 @@ msgid "EiB"
msgstr "EB"
#: js/messages.php:132
-#, fuzzy, php-format
+#, php-format
#| msgid "%s table"
#| msgid_plural "%s tables"
msgid "%d table(s)"
-msgstr "%s개 테이블 "
+msgstr "%d개 테이블 "
#. l10n: Questions is the name of a MySQL Status variable
#: js/messages.php:135
@@ -1480,7 +1474,7 @@ msgstr "로그 출력을 %s로 설정"
#. l10n: Enable in this context means setting a status variable to ON
#: js/messages.php:159
-#, fuzzy, php-format
+#, php-format
#| msgid "Enabled"
msgid "Enable %s"
msgstr "%s 사용가능"
@@ -1515,7 +1509,6 @@ msgid "Current settings"
msgstr "현재 설정"
#: js/messages.php:168 server_status.php:1640
-#, fuzzy
#| msgid "Import files"
msgid "Chart Title"
msgstr "차트 제목"
@@ -1606,7 +1599,6 @@ msgid "Profiling results"
msgstr "프로파일링"
#: js/messages.php:191
-#, fuzzy
#| msgid "Table"
msgctxt "Display format"
msgid "Table"
@@ -1686,7 +1678,6 @@ msgstr ""
#: libraries/db_links.inc.php:82 libraries/display_import.lib.php:126
#: libraries/server_links.inc.php:69 libraries/tbl_links.inc.php:89
#: prefs_manage.php:229 server_status.php:1595 setup/frames/menu.inc.php:20
-#, fuzzy
msgid "Import"
msgstr "가져오기"
@@ -1708,7 +1699,6 @@ msgid "Issue"
msgstr ""
#: js/messages.php:221
-#, fuzzy
#| msgid "Documentation"
msgid "Recommendation"
msgstr "추천"
@@ -1836,12 +1826,11 @@ msgid "The definition of a stored function must contain a RETURN statement!"
msgstr "저장 함수의 정의는 RETURN문을 포함해야 합니다!"
#: js/messages.php:270
-#, fuzzy, php-format
+#, php-format
msgid "Add %d value(s)"
msgstr "%d 값 추가"
#: js/messages.php:273
-#, fuzzy
msgid ""
"Note: If the file contains multiple tables, they will be combined into one"
msgstr "참고: 파일에 여러 테이블이 포함되어 있다면, 하나로 결합됩니다."
@@ -1891,6 +1880,7 @@ msgid "Zoom Search"
msgstr "검색"
#: js/messages.php:293
+#, fuzzy
msgid "Each point represents a data row."
msgstr "각 포인트는 데이터 행을 나타냅니다."
@@ -3608,7 +3598,6 @@ msgid "Server name template"
msgstr "서버명 템플릿"
#: libraries/config/messages.inc.php:89
-#, fuzzy
msgid "Table name template"
msgstr "파일명 템플릿"
@@ -4506,7 +4495,6 @@ msgid "Query window height"
msgstr "질의 창"
#: libraries/config/messages.inc.php:348
-#, fuzzy
#| msgid "Query window"
msgid "Query window width (in pixels)"
msgstr "질의 창"
hooks/post-receive
--
phpMyAdmin
1
0

[Phpmyadmin-git] [SCM] phpMyAdmin branch, QA_3_5, updated. RELEASE_3_5_0BETA1-256-g8cef483
by Michal Čihař 27 Jan '12
by Michal Čihař 27 Jan '12
27 Jan '12
The branch, QA_3_5 has been updated
via 8cef483dfe3452b235f0f18a398b4060f1db39a2 (commit)
via 4bd24a9b97d3f723206dd06ee6ebcbcb3078e888 (commit)
via 8bd33decfdf80bebdd1a2229517b7314a2eccbc0 (commit)
via 760aac415549c1d646b331b91c0dd6d4e5121fb9 (commit)
via 71cb4f0a804bce4621071eb187ec8a7550a920ac (commit)
via b1577c2b1945670d9bfadbcf0513e36fc7bdfae4 (commit)
via 697cbf9c0d9c65ed5c9a46aa0175c8168b967a1f (commit)
via 736678caa62ebd16821dab2eaa9b62972cbab729 (commit)
via 832192feece91e0813906689dba1e2d0b0e828f4 (commit)
via 4c3e985c2dffc27190a591eac8d3484c23473241 (commit)
via e8070b5488fbcf9d26e0d2e2fdd68f2123050e2d (commit)
via f213940834ddf7b4a431120075ef48c6785cec45 (commit)
via d23a10933a0df83d21b2379aacc00b44a1f8335d (commit)
via f597c6c5b8e4b12a25b6f7bcade9cba604779427 (commit)
via 51ae6e7e4d90ef25287feafdadf2c8f9d7d66bf5 (commit)
via a5c32db3091509d9e06f3dd6346055bc8a56be73 (commit)
via 1d23dc8747085e5add63b90fdc66c743ac944667 (commit)
via a078318ef53b48320dd537870e7a11e20e23c52b (commit)
from e64d33bba3b7355f25dbf637de9732367ed8a24e (commit)
- Log -----------------------------------------------------------------
commit 8cef483dfe3452b235f0f18a398b4060f1db39a2
Merge: e64d33b 4bd24a9
Author: Michal Čihař <mcihar(a)suse.cz>
Date: Fri Jan 27 14:13:57 2012 +0100
Merge remote-tracking branch 'pootle/master' into QA_3_5
commit 4bd24a9b97d3f723206dd06ee6ebcbcb3078e888
Author: Michal Čihař <michal(a)cihar.com>
Date: Fri Jan 27 15:10:38 2012 +0200
Translation update done using Pootle.
commit 8bd33decfdf80bebdd1a2229517b7314a2eccbc0
Author: Michal Čihař <michal(a)cihar.com>
Date: Fri Jan 27 15:08:28 2012 +0200
Translation update done using Pootle.
commit 760aac415549c1d646b331b91c0dd6d4e5121fb9
Author: Michal Čihař <michal(a)cihar.com>
Date: Fri Jan 27 15:08:04 2012 +0200
Translation update done using Pootle.
commit 71cb4f0a804bce4621071eb187ec8a7550a920ac
Author: Michal Čihař <michal(a)cihar.com>
Date: Fri Jan 27 15:08:00 2012 +0200
Translation update done using Pootle.
commit b1577c2b1945670d9bfadbcf0513e36fc7bdfae4
Author: Michal Čihař <michal(a)cihar.com>
Date: Fri Jan 27 15:07:55 2012 +0200
Translation update done using Pootle.
commit 697cbf9c0d9c65ed5c9a46aa0175c8168b967a1f
Author: Michal Čihař <michal(a)cihar.com>
Date: Fri Jan 27 15:07:10 2012 +0200
Translation update done using Pootle.
commit 736678caa62ebd16821dab2eaa9b62972cbab729
Author: Michal Čihař <michal(a)cihar.com>
Date: Fri Jan 27 15:06:44 2012 +0200
Translation update done using Pootle.
commit 832192feece91e0813906689dba1e2d0b0e828f4
Author: Michal Čihař <michal(a)cihar.com>
Date: Fri Jan 27 15:06:34 2012 +0200
Translation update done using Pootle.
commit 4c3e985c2dffc27190a591eac8d3484c23473241
Author: Michal Čihař <michal(a)cihar.com>
Date: Fri Jan 27 15:06:23 2012 +0200
Translation update done using Pootle.
commit e8070b5488fbcf9d26e0d2e2fdd68f2123050e2d
Author: Michal Čihař <michal(a)cihar.com>
Date: Fri Jan 27 15:06:08 2012 +0200
Translation update done using Pootle.
commit f213940834ddf7b4a431120075ef48c6785cec45
Author: Michal Čihař <michal(a)cihar.com>
Date: Fri Jan 27 15:05:35 2012 +0200
Translation update done using Pootle.
commit d23a10933a0df83d21b2379aacc00b44a1f8335d
Author: Michal Čihař <michal(a)cihar.com>
Date: Fri Jan 27 15:05:20 2012 +0200
Translation update done using Pootle.
commit f597c6c5b8e4b12a25b6f7bcade9cba604779427
Author: Michal Čihař <michal(a)cihar.com>
Date: Fri Jan 27 15:04:50 2012 +0200
Translation update done using Pootle.
commit 51ae6e7e4d90ef25287feafdadf2c8f9d7d66bf5
Author: Michal Čihař <michal(a)cihar.com>
Date: Fri Jan 27 15:04:33 2012 +0200
Translation update done using Pootle.
commit a5c32db3091509d9e06f3dd6346055bc8a56be73
Author: Michal Čihař <michal(a)cihar.com>
Date: Fri Jan 27 15:04:15 2012 +0200
Translation update done using Pootle.
commit 1d23dc8747085e5add63b90fdc66c743ac944667
Author: Michal Čihař <michal(a)cihar.com>
Date: Fri Jan 27 15:01:39 2012 +0200
Translation update done using Pootle.
commit a078318ef53b48320dd537870e7a11e20e23c52b
Author: Michal Čihař <michal(a)cihar.com>
Date: Fri Jan 27 15:01:34 2012 +0200
Translation update done using Pootle.
-----------------------------------------------------------------------
Summary of changes:
po/cs.po | 45 ++++++++++++++++++++++-----------------------
1 files changed, 22 insertions(+), 23 deletions(-)
diff --git a/po/cs.po b/po/cs.po
index 7c39b20..f92afe4 100644
--- a/po/cs.po
+++ b/po/cs.po
@@ -5,7 +5,7 @@ msgstr ""
"Project-Id-Version: phpMyAdmin 3.5.0-beta2\n"
"Report-Msgid-Bugs-To: phpmyadmin-devel(a)lists.sourceforge.net\n"
"POT-Creation-Date: 2012-01-25 17:45+0100\n"
-"PO-Revision-Date: 2012-01-27 14:58+0200\n"
+"PO-Revision-Date: 2012-01-27 15:08+0200\n"
"Last-Translator: Michal Čihař <michal(a)cihar.com>\n"
"Language-Team: czech <cs(a)li.org>\n"
"Language: cs\n"
@@ -806,7 +806,7 @@ msgstr "Sledovat tabulku"
#: db_tracking.php:227
msgid "Database Log"
-msgstr "Historie databáze"
+msgstr "Záznam databáze"
#: enum_editor.php:23 js/messages.php:266
#: libraries/rte/rte_routines.lib.php:690
@@ -1495,7 +1495,7 @@ msgid ""
"You can't change these variables. Please log in as root or contact your "
"database administrator."
msgstr ""
-"Nemůžete změnit uvedené proměnné. Prosím přihlašte se jako root nebo "
+"Nemůžete změnit uvedené proměnné. Prosím přihlaste se jako root nebo "
"kontaktujte vašeho správce databáze."
#: js/messages.php:165
@@ -1526,11 +1526,11 @@ msgstr "Jednotka"
#: js/messages.php:174
msgid "From slow log"
-msgstr "Ze zánamu pomalých dotazů"
+msgstr "Ze záznamu pomalých dotazů"
#: js/messages.php:175
msgid "From general log"
-msgstr "Z obecného zánamu dotazů"
+msgstr "Z obecného záznamu dotazů"
#: js/messages.php:176
msgid "Analysing & loading logs. This may take a while."
@@ -1608,7 +1608,7 @@ msgstr "Graf"
#. l10n: A collection of available filters
#: js/messages.php:195
msgid "Log table filter options"
-msgstr "Nastavení filtrování logovacích tabulek"
+msgstr "Nastavení filtrování záznamových tabulek"
#. l10n: Filter as in "Start Filtering"
#: js/messages.php:197
@@ -4597,9 +4597,9 @@ msgid ""
"Leave blank for no [a@http://wiki.phpmyadmin.net/pma/bookmark]bookmark[/a] "
"support, suggested: [kbd]pma_bookmark[/kbd]"
msgstr ""
-"Nechte prázdné pro žádnou podporu Leave blank for no [a@http://wiki."
-"phpmyadmin.net/pma/bookmark]záložek[/a] výchozí nastavení: [kbd]"
-"pma_bookmarks[/kbd]"
+"Nechte prázdné pro vypnutí podpory "
+"[a@http://wiki.phpmyadmin.net/pma/bookmark]záložek[/a], doporučené "
+"nastavení: [kbd]pma_bookmarks[/kbd]"
#: libraries/config/messages.inc.php:375
msgid "Bookmark table"
@@ -6168,13 +6168,13 @@ msgstr ""
#: libraries/engines/pbms.lib.php:30
msgid "Garbage Threshold"
-msgstr "Práh velikosti odpadu (garbage)"
+msgstr "Hranice odpadu"
#: libraries/engines/pbms.lib.php:31
msgid "The percentage of garbage in a repository file before it is compacted."
msgstr ""
-"Procentuální podíl odpadu (garbage) v souboru datového logu předtím, než je "
-"soubor stlačen."
+"Procentuální podíl odpadu v souboru datového logu předtím, než je soubor "
+"zhuštěn."
#: libraries/engines/pbms.lib.php:35 libraries/replication_gui.lib.php:70
#: server_synchronize.php:1261
@@ -6191,7 +6191,7 @@ msgstr ""
#: libraries/engines/pbms.lib.php:40
msgid "Repository Threshold"
-msgstr "Práh velikosti skladiště"
+msgstr "Hranice skladiště"
#: libraries/engines/pbms.lib.php:41
msgid ""
@@ -6216,7 +6216,7 @@ msgstr ""
#: libraries/engines/pbms.lib.php:50
msgid "Temp Log Threshold"
-msgstr "Práh velikosti dočasného logového souboru"
+msgstr "Hranice dočasného záznanového souboru"
#: libraries/engines/pbms.lib.php:51
msgid ""
@@ -6314,7 +6314,7 @@ msgstr ""
#: libraries/engines/pbxt.lib.php:37
msgid "Log file threshold"
-msgstr "Prahová hodnota logového souboru"
+msgstr "Hranice záznamového souboru"
#: libraries/engines/pbxt.lib.php:38
msgid ""
@@ -6350,7 +6350,7 @@ msgstr ""
#: libraries/engines/pbxt.lib.php:52
msgid "Data log threshold"
-msgstr "Nejvyšší velikost datového logu"
+msgstr "Hranice datového záznamu"
#: libraries/engines/pbxt.lib.php:53
msgid ""
@@ -6366,16 +6366,15 @@ msgstr ""
#: libraries/engines/pbxt.lib.php:57
msgid "Garbage threshold"
-msgstr "Největší velikost odpadu (garbage)"
+msgstr "Hranice odpadu"
#: libraries/engines/pbxt.lib.php:58
msgid ""
"The percentage of garbage in a data log file before it is compacted. This is "
"a value between 1 and 99. The default is 50."
msgstr ""
-"Procentuální podíl odpadu (garbage) v souboru datového logu předtím, než je "
-"soubor stlačen. Tato hodnota se může pohybovat mezi 1 a 99. Výchozí hodnota "
-"je 50."
+"Procentuální podíl odpadu v souboru datového logu předtím, než je soubor "
+"zhuštěn. Tato hodnota se může pohybovat mezi 1 a 99. Výchozí hodnota je 50."
#: libraries/engines/pbxt.lib.php:62
msgid "Log buffer size"
@@ -7196,7 +7195,7 @@ msgid ""
"Please see the documentation on how to update your column_comments table"
msgstr ""
"Podívejte se prosím do dokumentace, jak aktualizovat tabulku s informacemi "
-"o polích (tabulka column_comments)"
+"o polích v tabulce column_comments"
#: libraries/relation.lib.php:124 libraries/sql_query_form.lib.php:376
msgid "Bookmarked SQL query"
@@ -12378,7 +12377,7 @@ msgid ""
msgstr ""
"Na řazení není nic špatného, ale ujistěte se, že dotazy, které hojně "
"využívají řazení používají klíče ve frázi ORDER BY, protože toto zajistí "
-"rychlejší řazení."
+"rychlejší řazení"
#: po/advisory_rules.php:123
#, php-format
@@ -12399,7 +12398,7 @@ msgid ""
"columns being used in the join conditions will greatly speed up table joins"
msgstr ""
"To znamená, že spojení tabulek musí často procházet celou tabulku. Přidáním "
-"klíčů na sloupce použité při slučování můžete tuto operaci značně urychlit."
+"klíčů na sloupce použité při slučování můžete tuto operaci značně urychlit"
#: po/advisory_rules.php:128
#, php-format
hooks/post-receive
--
phpMyAdmin
1
0

[Phpmyadmin-git] [SCM] phpMyAdmin branch, QA_3_5, updated. RELEASE_3_5_0BETA1-238-ge64d33b
by Michal Čihař 27 Jan '12
by Michal Čihař 27 Jan '12
27 Jan '12
The branch, QA_3_5 has been updated
via e64d33bba3b7355f25dbf637de9732367ed8a24e (commit)
via 3ef4b37f447469b51e3842a26f15e864798354ff (commit)
via 9f3e5f46028a5f6e30915f5c547a348b7942ed5c (commit)
via fa57bf1b7cd2061ae0bd3c548af7673246e63ecb (commit)
via 0a6ae4b26077674e12364d38caa7f469044eb65f (commit)
via 24e8aacd051dce33a9db0e44ce1c6c388baaf5b9 (commit)
via ced6716d71a2943875912a9875e9073510e0bc84 (commit)
via 4301ed2ab948cb90ceb1a6fe3a5cfa055e9ec5d3 (commit)
via 61c2348201746bac0c332131683a3938b450df40 (commit)
via 8ae4e415546a722d898ed0a3291562f52ded3873 (commit)
via 64d4d0e7d2f7e8a51f1a3480eeec1f076765612c (commit)
via cf8118c0906d5f3cbb8f2a908042d671eecc2972 (commit)
via b2b31f9b892d27174c2b99228ce1bc7a2f4ea39b (commit)
via ec1ab93652d9ece93d4bd6a2e437cae99bc06e3d (commit)
via a64923acac18759ee90a7acc453aa29814f5f534 (commit)
via 39919646625e9d562cfdf01eda82f25f6fc68177 (commit)
via 0052f63c632bbcd78de5fec9d5730bfc0a5992c8 (commit)
via e4d110b4d489e19380059289bce572fa73d2b2a8 (commit)
via e79d0bc1de688b843a7ebc8caea068a9278ddee6 (commit)
via 760fe8de1b711b86584a98432c09ddb93beb9b48 (commit)
via e66f23fcae4bff5b13a464c980b03fb41d423c0a (commit)
via dda8dc59745d90612476bc0d09630b21cd03188c (commit)
from a8e38f8cdbe331ba2092c6efa45bfadfca82df11 (commit)
- Log -----------------------------------------------------------------
commit e64d33bba3b7355f25dbf637de9732367ed8a24e
Author: Michal Čihař <mcihar(a)suse.cz>
Date: Fri Jan 27 14:00:21 2012 +0100
Fix format string
commit 3ef4b37f447469b51e3842a26f15e864798354ff
Merge: a8e38f8 9f3e5f4
Author: Michal Čihař <mcihar(a)suse.cz>
Date: Fri Jan 27 13:59:55 2012 +0100
Merge remote-tracking branch 'pootle/master' into QA_3_5
commit 9f3e5f46028a5f6e30915f5c547a348b7942ed5c
Author: Michal Čihař <michal(a)cihar.com>
Date: Fri Jan 27 14:59:17 2012 +0200
Translation update done using Pootle.
commit fa57bf1b7cd2061ae0bd3c548af7673246e63ecb
Author: Michal Čihař <michal(a)cihar.com>
Date: Fri Jan 27 14:58:53 2012 +0200
Translation update done using Pootle.
commit 0a6ae4b26077674e12364d38caa7f469044eb65f
Author: Michal Čihař <michal(a)cihar.com>
Date: Fri Jan 27 14:58:39 2012 +0200
Translation update done using Pootle.
commit 24e8aacd051dce33a9db0e44ce1c6c388baaf5b9
Author: Michal Čihař <michal(a)cihar.com>
Date: Fri Jan 27 14:58:22 2012 +0200
Translation update done using Pootle.
commit ced6716d71a2943875912a9875e9073510e0bc84
Author: Michal Čihař <michal(a)cihar.com>
Date: Fri Jan 27 14:57:50 2012 +0200
Translation update done using Pootle.
commit 4301ed2ab948cb90ceb1a6fe3a5cfa055e9ec5d3
Author: Michal Čihař <michal(a)cihar.com>
Date: Fri Jan 27 14:56:59 2012 +0200
Translation update done using Pootle.
commit 61c2348201746bac0c332131683a3938b450df40
Author: Michal Čihař <michal(a)cihar.com>
Date: Fri Jan 27 14:56:45 2012 +0200
Translation update done using Pootle.
commit 8ae4e415546a722d898ed0a3291562f52ded3873
Author: Michal Čihař <michal(a)cihar.com>
Date: Fri Jan 27 14:56:21 2012 +0200
Translation update done using Pootle.
commit 64d4d0e7d2f7e8a51f1a3480eeec1f076765612c
Author: Michal Čihař <michal(a)cihar.com>
Date: Fri Jan 27 14:55:46 2012 +0200
Translation update done using Pootle.
commit cf8118c0906d5f3cbb8f2a908042d671eecc2972
Author: Michal Čihař <michal(a)cihar.com>
Date: Fri Jan 27 14:55:28 2012 +0200
Translation update done using Pootle.
commit b2b31f9b892d27174c2b99228ce1bc7a2f4ea39b
Author: Michal Čihař <michal(a)cihar.com>
Date: Fri Jan 27 14:55:14 2012 +0200
Translation update done using Pootle.
commit ec1ab93652d9ece93d4bd6a2e437cae99bc06e3d
Author: Michal Čihař <michal(a)cihar.com>
Date: Fri Jan 27 14:54:57 2012 +0200
Translation update done using Pootle.
commit a64923acac18759ee90a7acc453aa29814f5f534
Author: Michal Čihař <michal(a)cihar.com>
Date: Fri Jan 27 14:54:31 2012 +0200
Translation update done using Pootle.
commit 39919646625e9d562cfdf01eda82f25f6fc68177
Author: Michal Čihař <michal(a)cihar.com>
Date: Fri Jan 27 14:54:02 2012 +0200
Translation update done using Pootle.
commit 0052f63c632bbcd78de5fec9d5730bfc0a5992c8
Author: Michal Čihař <michal(a)cihar.com>
Date: Fri Jan 27 14:53:44 2012 +0200
Translation update done using Pootle.
commit e4d110b4d489e19380059289bce572fa73d2b2a8
Author: Michal Čihař <michal(a)cihar.com>
Date: Fri Jan 27 14:53:25 2012 +0200
Translation update done using Pootle.
commit e79d0bc1de688b843a7ebc8caea068a9278ddee6
Author: Michal Čihař <michal(a)cihar.com>
Date: Fri Jan 27 14:52:46 2012 +0200
Translation update done using Pootle.
commit 760fe8de1b711b86584a98432c09ddb93beb9b48
Author: Michal Čihař <michal(a)cihar.com>
Date: Fri Jan 27 14:51:58 2012 +0200
Translation update done using Pootle.
commit e66f23fcae4bff5b13a464c980b03fb41d423c0a
Merge: dda8dc5 5d00fdf
Author: Pootle server <pootle(a)cihar.com>
Date: Fri Jan 27 12:40:12 2012 +0100
Merge remote-tracking branch 'origin/master'
commit dda8dc59745d90612476bc0d09630b21cd03188c
Author: Pootle server <noreply(a)l10n.cihar.com>
Date: Fri Jan 27 10:39:08 2012 +0200
Translation update done using Pootle.
-----------------------------------------------------------------------
Summary of changes:
po/cs.po | 40 +++++++++++++++++++++++++++++++---------
po/ko.po | 28 ++++++++--------------------
2 files changed, 39 insertions(+), 29 deletions(-)
diff --git a/po/cs.po b/po/cs.po
index e6cd5ba..7c39b20 100644
--- a/po/cs.po
+++ b/po/cs.po
@@ -5,7 +5,7 @@ msgstr ""
"Project-Id-Version: phpMyAdmin 3.5.0-beta2\n"
"Report-Msgid-Bugs-To: phpmyadmin-devel(a)lists.sourceforge.net\n"
"POT-Creation-Date: 2012-01-25 17:45+0100\n"
-"PO-Revision-Date: 2012-01-24 21:07+0200\n"
+"PO-Revision-Date: 2012-01-27 14:58+0200\n"
"Last-Translator: Michal Čihař <michal(a)cihar.com>\n"
"Language-Team: czech <cs(a)li.org>\n"
"Language: cs\n"
@@ -12398,11 +12398,15 @@ msgid ""
"This means that joins are doing full table scans. Adding indexes for the "
"columns being used in the join conditions will greatly speed up table joins"
msgstr ""
+"To znamená, že spojení tabulek musí často procházet celou tabulku. Přidáním "
+"klíčů na sloupce použité při slučování můžete tuto operaci značně urychlit."
#: po/advisory_rules.php:128
#, php-format
msgid "Table joins average: %s, this value should be less than 1 per hour"
msgstr ""
+"Průměrně sloučeno tabulek: %s, tato hodnota by měla být menší než 1 za "
+"hodinu"
#: po/advisory_rules.php:130
msgid "Rate of reading first index entry"
@@ -12426,6 +12430,8 @@ msgstr ""
#, php-format
msgid "Index scans average: %s, this value should be less than 1 per hour"
msgstr ""
+"Průměrně procházeno klíčů: %s, tato hodnota by měla být menší než 1 za "
+"hodinu"
#: po/advisory_rules.php:135
msgid "Rate of reading fixed position"
@@ -12448,6 +12454,8 @@ msgid ""
"Rate of reading fixed position average: %s, this value should be less than 1 "
"per hour"
msgstr ""
+"Četnost čtení na pevné pozici: %s, tato hodnota by měla být menší než 1 za "
+"hodinu"
#: po/advisory_rules.php:140
msgid "Rate of reading next table row"
@@ -12468,6 +12476,8 @@ msgstr ""
msgid ""
"Rate of reading next table row: %s, this value should be less than 1 per hour"
msgstr ""
+"Četnost čtení dalšího řádku tabulky: %s, tato hodnota by měla být menší než "
+"1 za hodinu"
#: po/advisory_rules.php:145
msgid "tmp_table_size vs. max_heap_table_size"
@@ -12541,6 +12551,8 @@ msgid ""
"Rate of temporary tables being written to disk: %s, this value should be "
"less than 1 per hour"
msgstr ""
+"Četnost dočasného ukládání na disk: %s, tato hodnota by měla být menší než 1 "
+"za hodinu"
#: po/advisory_rules.php:160
msgid "MyISAM key buffer size"
@@ -12633,6 +12645,8 @@ msgstr ""
#, php-format
msgid "Opened table rate: %s, this value should be less than 10 per hour"
msgstr ""
+"Četnost otevírání tabulek: %s, tato hodnota by měla být menší než 10 za "
+"hodinu"
#: po/advisory_rules.php:185
#, fuzzy
@@ -12659,10 +12673,9 @@ msgid ""
msgstr ""
#: po/advisory_rules.php:190
-#, fuzzy
#| msgid "Format of imported file"
msgid "Rate of open files"
-msgstr "Formát importovaného souboru"
+msgstr "Četnost otevírání souborů"
#: po/advisory_rules.php:191
#, fuzzy
@@ -12674,6 +12687,8 @@ msgstr "Počet nevyřízených synchronizací logovacích souborů."
#, php-format
msgid "Opened files rate: %s, this value should be less than 5 per hour"
msgstr ""
+"Četnost otevírání souborů: %s, tato hodnota by měla být menší než 5 za "
+"hodinu"
#: po/advisory_rules.php:195
#, php-format
@@ -12697,12 +12712,14 @@ msgstr ""
#: po/advisory_rules.php:200
msgid "Table lock wait rate"
-msgstr ""
+msgstr "Četnost čekání na zámek tabulky"
#: po/advisory_rules.php:203
#, php-format
msgid "Table lock wait rate: %s, this value should be less than 1 per hour"
msgstr ""
+"Četnost čekání na zámek tabulky: %s, tato hodnota by měla být menší než 1 za "
+"hodinu"
#: po/advisory_rules.php:205
#, fuzzy
@@ -12746,19 +12763,20 @@ msgstr ""
#: po/advisory_rules.php:215
msgid "Threads that are slow to launch"
-msgstr ""
+msgstr "Vlákna se spouštějí příliš dlouho"
#: po/advisory_rules.php:216
-#, fuzzy
#| msgid "The number of threads that are not sleeping."
msgid "There are too many threads that are slow to launch."
-msgstr "Počet vláken, která nespí."
+msgstr "Je příliš mnoho vláken, která se spouštějí dlouho."
#: po/advisory_rules.php:217
msgid ""
"This generally happens in case of general system overload as it is pretty "
"simple operations. You might want to monitor your system load carefully."
msgstr ""
+"K tomuto obvykle dochází v případě přetížení systému, protože se jedná o "
+"velmi jednoduchou operaci. Je vhodné podrobně sledovat zatížení systému."
#: po/advisory_rules.php:218
#, php-format
@@ -12839,6 +12857,8 @@ msgstr "Trvalé připojení"
msgid ""
"Aborted connections rate is at %s, this value should be less than 1 per hour"
msgstr ""
+"Četnost přerušených spojení je %s, tato hodnota by měla být menší než 1 za "
+"hodinu"
#: po/advisory_rules.php:240
msgid "Percentage of aborted clients"
@@ -12870,10 +12890,12 @@ msgstr "Formát importovaného souboru"
#, php-format
msgid "Aborted client rate is at %s, this value should be less than 1 per hour"
msgstr ""
+"Četnost přerušených klientů: %s, tato hodnota by měla být menší než 1 za "
+"hodinu"
#: po/advisory_rules.php:250
msgid "Is InnoDB disabled?"
-msgstr ""
+msgstr "InnoDB je vypnuto?"
#: po/advisory_rules.php:251
msgid "You do not have InnoDB enabled."
@@ -12881,7 +12903,7 @@ msgstr "Máte zakázané InnoDB."
#: po/advisory_rules.php:252
msgid "InnoDB is usually the better choice for table engines."
-msgstr ""
+msgstr "InnoDB je obvykle nejlepší volba úložiště tabulky."
#: po/advisory_rules.php:253
msgid "have_innodb is set to 'value'"
diff --git a/po/ko.po b/po/ko.po
index 3b66495..1405a21 100644
--- a/po/ko.po
+++ b/po/ko.po
@@ -5,7 +5,7 @@ msgstr ""
"Report-Msgid-Bugs-To: phpmyadmin-devel(a)lists.sourceforge.net\n"
"POT-Creation-Date: 2012-01-25 17:45+0100\n"
"PO-Revision-Date: 2012-01-27 08:18+0200\n"
-"Last-Translator: manyfun <manyfun7(a)gmail.com>\n"
+"Last-Translator: minsung kang <manyfun7(a)gmail.com>\n"
"Language-Team: korean <ko(a)li.org>\n"
"Language: ko\n"
"MIME-Version: 1.0\n"
@@ -806,25 +806,22 @@ msgid "ENUM/SET editor"
msgstr "ENUM/SET 수정"
#: enum_editor.php:28 js/messages.php:268
-#, fuzzy
#| msgid "Values for the column \"%s\""
msgid "Values for a new column"
msgstr "새로운 열의 값"
#: enum_editor.php:30 js/messages.php:267
-#, fuzzy, php-format
+#, php-format
#| msgid "Values for the column \"%s\""
msgid "Values for column %s"
msgstr "\"%s\" 열의 값"
#: enum_editor.php:34 js/messages.php:269
-#, fuzzy
#| msgid "Enter each value in a separate field."
msgid "Enter each value in a separate field"
msgstr "각각의 필드에 값을 입력하세요"
#: enum_editor.php:123
-#, fuzzy
msgid "Add a value"
msgstr "값을 추가"
@@ -941,7 +938,6 @@ msgid "Add an inner ring"
msgstr "내부 링 추가"
#: gis_data_editor.php:266 js/messages.php:322
-#, fuzzy
msgid "Polygon"
msgstr "폴리곤"
@@ -1103,7 +1099,6 @@ msgid "This is not a number!"
msgstr "은 숫자가 아닙니다!"
#: js/messages.php:46
-#, fuzzy
#| msgid "Add index"
msgid "Add Index"
msgstr "인덱스 추가"
@@ -1114,7 +1109,7 @@ msgid "Edit Index"
msgstr "인덱스 수정"
#: js/messages.php:48 tbl_indexes.php:293
-#, fuzzy, php-format
+#, php-format
msgid "Add %d column(s) to index"
msgstr "인덱스에 %d 열 추가"
@@ -1249,7 +1244,6 @@ msgid "Local monitor configuration incompatible"
msgstr "호환되지 않는 로컬 모니터 설정입니다."
#: js/messages.php:95
-#, fuzzy
msgid ""
"The chart arrangement configuration in your browsers local storage is not "
"compatible anymore to the newer version of the monitor dialog. It is very "
@@ -1373,11 +1367,11 @@ msgid "EiB"
msgstr "EB"
#: js/messages.php:132
-#, fuzzy, php-format
+#, php-format
#| msgid "%s table"
#| msgid_plural "%s tables"
msgid "%d table(s)"
-msgstr "%s개 테이블 "
+msgstr "%d개 테이블 "
#. l10n: Questions is the name of a MySQL Status variable
#: js/messages.php:135
@@ -1480,7 +1474,7 @@ msgstr "로그 출력을 %s로 설정"
#. l10n: Enable in this context means setting a status variable to ON
#: js/messages.php:159
-#, fuzzy, php-format
+#, php-format
#| msgid "Enabled"
msgid "Enable %s"
msgstr "%s 사용가능"
@@ -1515,7 +1509,6 @@ msgid "Current settings"
msgstr "현재 설정"
#: js/messages.php:168 server_status.php:1640
-#, fuzzy
#| msgid "Import files"
msgid "Chart Title"
msgstr "차트 제목"
@@ -1606,7 +1599,6 @@ msgid "Profiling results"
msgstr "프로파일링"
#: js/messages.php:191
-#, fuzzy
#| msgid "Table"
msgctxt "Display format"
msgid "Table"
@@ -1686,7 +1678,6 @@ msgstr ""
#: libraries/db_links.inc.php:82 libraries/display_import.lib.php:126
#: libraries/server_links.inc.php:69 libraries/tbl_links.inc.php:89
#: prefs_manage.php:229 server_status.php:1595 setup/frames/menu.inc.php:20
-#, fuzzy
msgid "Import"
msgstr "가져오기"
@@ -1708,7 +1699,6 @@ msgid "Issue"
msgstr ""
#: js/messages.php:221
-#, fuzzy
#| msgid "Documentation"
msgid "Recommendation"
msgstr "추천"
@@ -1836,12 +1826,11 @@ msgid "The definition of a stored function must contain a RETURN statement!"
msgstr "저장 함수의 정의는 RETURN문을 포함해야 합니다!"
#: js/messages.php:270
-#, fuzzy, php-format
+#, php-format
msgid "Add %d value(s)"
msgstr "%d 값 추가"
#: js/messages.php:273
-#, fuzzy
msgid ""
"Note: If the file contains multiple tables, they will be combined into one"
msgstr "참고: 파일에 여러 테이블이 포함되어 있다면, 하나로 결합됩니다."
@@ -1891,6 +1880,7 @@ msgid "Zoom Search"
msgstr "검색"
#: js/messages.php:293
+#, fuzzy
msgid "Each point represents a data row."
msgstr "각 포인트는 데이터 행을 나타냅니다."
@@ -3608,7 +3598,6 @@ msgid "Server name template"
msgstr "서버명 템플릿"
#: libraries/config/messages.inc.php:89
-#, fuzzy
msgid "Table name template"
msgstr "파일명 템플릿"
@@ -4506,7 +4495,6 @@ msgid "Query window height"
msgstr "질의 창"
#: libraries/config/messages.inc.php:348
-#, fuzzy
#| msgid "Query window"
msgid "Query window width (in pixels)"
msgstr "질의 창"
hooks/post-receive
--
phpMyAdmin
1
0

[Phpmyadmin-git] [SCM] phpMyAdmin branch, master, updated. RELEASE_3_5_0BETA1-216-ga8e38f8
by Michal Čihař 27 Jan '12
by Michal Čihař 27 Jan '12
27 Jan '12
The branch, master has been updated
via a8e38f8cdbe331ba2092c6efa45bfadfca82df11 (commit)
from 5d00fdf3da118fbbffc78b4eeda5e9cd48bf2bf1 (commit)
- Log -----------------------------------------------------------------
-----------------------------------------------------------------------
Summary of changes:
test/classes/PMA_File_test.php | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)
diff --git a/test/classes/PMA_File_test.php b/test/classes/PMA_File_test.php
index 5115650..9760618 100644
--- a/test/classes/PMA_File_test.php
+++ b/test/classes/PMA_File_test.php
@@ -1,4 +1,3 @@
-
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
hooks/post-receive
--
phpMyAdmin
1
0

[Phpmyadmin-git] [SCM] phpMyAdmin branch, QA_3_5, updated. RELEASE_3_5_0BETA1-216-ga8e38f8
by Michal Čihař 27 Jan '12
by Michal Čihař 27 Jan '12
27 Jan '12
The branch, QA_3_5 has been updated
via a8e38f8cdbe331ba2092c6efa45bfadfca82df11 (commit)
from 5d00fdf3da118fbbffc78b4eeda5e9cd48bf2bf1 (commit)
- Log -----------------------------------------------------------------
commit a8e38f8cdbe331ba2092c6efa45bfadfca82df11
Author: Michal Čihař <mcihar(a)suse.cz>
Date: Fri Jan 27 13:47:03 2012 +0100
Prevent output from this test
-----------------------------------------------------------------------
Summary of changes:
test/classes/PMA_File_test.php | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)
diff --git a/test/classes/PMA_File_test.php b/test/classes/PMA_File_test.php
index 5115650..9760618 100644
--- a/test/classes/PMA_File_test.php
+++ b/test/classes/PMA_File_test.php
@@ -1,4 +1,3 @@
-
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
hooks/post-receive
--
phpMyAdmin
1
0

[Phpmyadmin-git] [SCM] phpMyAdmin branch, master, updated. RELEASE_3_5_0BETA1-215-g5d00fdf
by Michal Čihař 27 Jan '12
by Michal Čihař 27 Jan '12
27 Jan '12
The branch, master has been updated
via 5d00fdf3da118fbbffc78b4eeda5e9cd48bf2bf1 (commit)
via 952a181f1fcf1fbcc0ff301111be4ce335f282d7 (commit)
via bda9be54eb9d3d7c6fe052903bcfa945c7f35cb8 (commit)
via ad29ef2de567d2c2a4f2ba155e93ee4a926b8a9a (commit)
via 9b9d3e5cbc59def734181a4bd40a48205651d83b (commit)
from 8e30c72834a64dfa9f984466abe0071208dc6bd9 (commit)
- Log -----------------------------------------------------------------
-----------------------------------------------------------------------
Summary of changes:
js/codemirror/lib/codemirror.js | 1525 ++++++++++++++++++++++---------
js/functions.js | 16 +-
themes/original/css/theme_right.css.php | 17 +-
themes/pmahomme/css/theme_right.css.php | 15 +
4 files changed, 1125 insertions(+), 448 deletions(-)
diff --git a/js/codemirror/lib/codemirror.js b/js/codemirror/lib/codemirror.js
index 27bec72..8e9a34e 100644
--- a/js/codemirror/lib/codemirror.js
+++ b/js/codemirror/lib/codemirror.js
@@ -1,3 +1,5 @@
+// CodeMirror v2.18
+
// All functions that need access to the editor's state live inside
// the CodeMirror function. Below that, at the bottom of the file,
// some utilities are defined.
@@ -16,18 +18,19 @@ var CodeMirror = (function() {
var targetDocument = options["document"];
// The element in which the editor lives.
var wrapper = targetDocument.createElement("div");
- wrapper.className = "CodeMirror";
+ wrapper.className = "CodeMirror" + (options.lineWrapping ? " CodeMirror-wrap" : "");
// This mess creates the base DOM structure for the editor.
wrapper.innerHTML =
'<div style="overflow: hidden; position: relative; width: 1px; height: 0px;">' + // Wraps and hides input textarea
- '<textarea style="position: absolute; width: 2px;" wrap="off"></textarea></div>' +
+ '<textarea style="position: absolute; width: 10000px;" wrap="off" ' +
+ 'autocorrect="off" autocapitalize="off"></textarea></div>' +
'<div class="CodeMirror-scroll cm-s-' + options.theme + '">' +
'<div style="position: relative">' + // Set to the height of the text, causes scrolling
- '<div style="position: absolute; height: 0; width: 0; overflow: hidden;"></div>' +
'<div style="position: relative">' + // Moved around its parent to cover visible view
'<div class="CodeMirror-gutter"><div class="CodeMirror-gutter-text"></div></div>' +
// Provides positioning relative to (visible) text origin
'<div class="CodeMirror-lines"><div style="position: relative">' +
+ '<div style="position: absolute; width: 100%; height: 0; overflow: hidden; visibility: hidden"></div>' +
'<pre class="CodeMirror-cursor"> </pre>' + // Absolutely positioned blinky cursor
'<div></div>' + // This DIV contains the actual code
'</div></div></div></div></div>';
@@ -35,21 +38,29 @@ var CodeMirror = (function() {
// I've never seen more elegant code in my life.
var inputDiv = wrapper.firstChild, input = inputDiv.firstChild,
scroller = wrapper.lastChild, code = scroller.firstChild,
- measure = code.firstChild, mover = measure.nextSibling,
- gutter = mover.firstChild, gutterText = gutter.firstChild,
- lineSpace = gutter.nextSibling.firstChild,
- cursor = lineSpace.firstChild, lineDiv = cursor.nextSibling;
+ mover = code.firstChild, gutter = mover.firstChild, gutterText = gutter.firstChild,
+ lineSpace = gutter.nextSibling.firstChild, measure = lineSpace.firstChild,
+ cursor = measure.nextSibling, lineDiv = cursor.nextSibling;
+ if (!webkit) lineSpace.draggable = true;
if (options.tabindex != null) input.tabindex = options.tabindex;
if (!options.gutter && !options.lineNumbers) gutter.style.display = "none";
+ // Check for problem with IE innerHTML not working when we have a
+ // P (or similar) parent node.
+ try { stringWidth("x"); }
+ catch (e) {
+ if (e.message.match(/unknown runtime/i))
+ e = new Error("A CodeMirror inside a P-style element does not work in Internet Explorer. (innerHTML bug)");
+ throw e;
+ }
+
// Delayed object wrap timeouts, making sure only one is active. blinker holds an interval.
var poll = new Delayed(), highlight = new Delayed(), blinker;
- // mode holds a mode API object. lines an array of Line objects
- // (see Line constructor), work an array of lines that should be
- // parsed, and history the undo history (instance of History
- // constructor).
- var mode, lines = [new Line("")], work, history = new History(), focused;
+ // mode holds a mode API object. doc is the tree of Line objects,
+ // work an array of lines that should be parsed, and history the
+ // undo history (instance of History constructor).
+ var mode, doc = new BranchChunk([new LeafChunk([new Line("")])]), work, focused;
loadMode();
// The selection. These are always maintained to point at valid
// positions. Inverted is used to remember that the user is
@@ -59,12 +70,12 @@ var CodeMirror = (function() {
// whether the user is holding shift. reducedSelection is a hack
// to get around the fact that we can't create inverted
// selections. See below.
- var shiftSelecting, reducedSelection, lastDoubleClick;
+ var shiftSelecting, reducedSelection, lastClick, lastDoubleClick, draggingText;
// Variables used by startOperation/endOperation to track what
// happened during the operation.
- var updateInput, changes, textChanged, selectionChanged, leaveInputAlone;
+ var updateInput, changes, textChanged, selectionChanged, leaveInputAlone, gutterDirty;
// Current visible range (may be bigger than the view window).
- var showingFrom = 0, showingTo = 0, lastHeight = 0, curKeyId = null;
+ var displayOffset = 0, showingFrom = 0, showingTo = 0, lastHeight = 0, curKeyId = null;
// editing will hold an object describing the things we put in the
// textarea, to help figure out whether something changed.
// bracketHighlighted is used to remember that a backet has been
@@ -76,17 +87,33 @@ var CodeMirror = (function() {
// Initialize the content.
operation(function(){setValue(options.value || ""); updateInput = false;})();
+ var history = new History();
+
+ var slowPollInterval = 2000;
+ // Gecko and Opera Linux do not reliably fire any event when starting an IME compose
+ var alwaysPollForIME = (!win && !mac) && (gecko || window.opera);
+ if (options.pollForIME && alwaysPollForIME) slowPollInterval = 50;
+ function keyMightStartIME(keyCode) {
+ return (win && ((gecko && keyCode == 229) || (window.opera && keyCode == 197))) || (mac && gecko);
+ }
// Register our event handlers.
connect(scroller, "mousedown", operation(onMouseDown));
+ connect(scroller, "dblclick", operation(onDoubleClick));
+ connect(lineSpace, "dragstart", onDragStart);
+ connect(lineSpace, "selectstart", e_preventDefault);
// Gecko browsers fire contextmenu *after* opening the menu, at
// which point we can't mess with it anymore. Context menu is
// handled in onMouseDown for Gecko.
if (!gecko) connect(scroller, "contextmenu", onContextMenu);
- connect(code, "dblclick", operation(onDblClick));
- connect(scroller, "scroll", function() {updateDisplay([]); if (options.onScroll) options.onScroll(instance);});
+ connect(scroller, "scroll", function() {
+ updateDisplay([]);
+ if (options.fixedGutter) gutter.style.left = scroller.scrollLeft + "px";
+ if (options.onScroll) options.onScroll(instance);
+ });
connect(window, "resize", function() {updateDisplay(true);});
connect(input, "keyup", operation(onKeyUp));
+ connect(input, "input", function() {fastPoll(curKeyId);});
connect(input, "keydown", operation(onKeyDown));
connect(input, "keypress", operation(onKeyPress));
connect(input, "focus", onFocus);
@@ -98,44 +125,51 @@ var CodeMirror = (function() {
connect(scroller, "paste", function(){focusInput(); fastPoll();});
connect(input, "paste", function(){fastPoll();});
connect(input, "cut", function(){fastPoll();});
-
- // IE throws unspecified error in certain cases, when
+
+ // IE throws unspecified error in certain cases, when
// trying to access activeElement before onload
var hasFocus; try { hasFocus = (targetDocument.activeElement == input); } catch(e) { }
if (hasFocus) setTimeout(onFocus, 20);
else onBlur();
- function isLine(l) {return l >= 0 && l < lines.length;}
+ function isLine(l) {return l >= 0 && l < doc.size;}
// The instance object that we'll return. Mostly calls out to
// local functions in the CodeMirror function. Some do some extra
// range checking and/or clipping. operation is used to wrap the
// call so that changes it makes are tracked, and the display is
// updated afterwards.
- var instance = {
+ var instance = wrapper.CodeMirror = {
getValue: getValue,
setValue: operation(setValue),
getSelection: getSelection,
replaceSelection: operation(replaceSelection),
focus: function(){focusInput(); onFocus(); fastPoll();},
setOption: function(option, value) {
+ var oldVal = options[option];
options[option] = value;
- if (option == "lineNumbers" || option == "gutter") gutterChanged();
- else if (option == "mode" || option == "indentUnit") loadMode();
+ if (option == "mode" || option == "indentUnit") loadMode();
else if (option == "readOnly" && value == "nocursor") input.blur();
else if (option == "theme") scroller.className = scroller.className.replace(/cm-s-\w+/, "cm-s-" + value);
+ else if (option == "lineWrapping" && oldVal != value) operation(wrappingChanged)();
+ else if (option == "pollForIME" && alwaysPollForIME) slowPollInterval = value ? 50 : 2000;
+ if (option == "lineNumbers" || option == "gutter" || option == "firstLineNumber" || option == "theme")
+ operation(gutterChanged)();
},
getOption: function(option) {return options[option];},
undo: operation(undo),
redo: operation(redo),
- indentLine: operation(function(n) {if (isLine(n)) indentLine(n, "smart");}),
+ indentLine: operation(function(n, dir) {
+ if (isLine(n)) indentLine(n, dir == null ? "smart" : dir ? "add" : "subtract");
+ }),
historySize: function() {return {undo: history.done.length, redo: history.undone.length};},
+ clearHistory: function() {history = new History();},
matchBrackets: operation(function(){matchBrackets(true);}),
- getTokenAt: function(pos) {
+ getTokenAt: operation(function(pos) {
pos = clipPos(pos);
- return lines[pos.line].getTokenAt(mode, getStateBefore(pos.line), pos.ch);
- },
+ return getLine(pos.line).getTokenAt(mode, getStateBefore(pos.line), pos.ch);
+ }),
getStateAfter: function(line) {
- line = clipLine(line == null ? lines.length - 1: line);
+ line = clipLine(line == null ? doc.size - 1: line);
return getStateBefore(line + 1);
},
cursorCoords: function(start){
@@ -145,24 +179,25 @@ var CodeMirror = (function() {
charCoords: function(pos){return pageCoords(clipPos(pos));},
coordsChar: function(coords) {
var off = eltOffset(lineSpace);
- var line = clipLine(Math.min(lines.length - 1, showingFrom + Math.floor((coords.y - off.top) / lineHeight())));
- return clipPos({line: line, ch: charFromX(clipLine(line), coords.x - off.left)});
+ return coordsChar(coords.x - off.left, coords.y - off.top);
},
getSearchCursor: function(query, pos, caseFold) {return new SearchCursor(query, pos, caseFold);},
- markText: operation(function(a, b, c){return operation(markText(a, b, c));}),
- setMarker: addGutterMarker,
- clearMarker: removeGutterMarker,
+ markText: operation(markText),
+ setBookmark: setBookmark,
+ setMarker: operation(addGutterMarker),
+ clearMarker: operation(removeGutterMarker),
setLineClass: operation(setLineClass),
+ hideLine: operation(function(h) {return setLineHidden(h, true);}),
+ showLine: operation(function(h) {return setLineHidden(h, false);}),
lineInfo: lineInfo,
- addWidget: function(pos, node, scroll, where) {
+ addWidget: function(pos, node, scroll, vert, horiz) {
pos = localCoords(clipPos(pos));
var top = pos.yBot, left = pos.x;
node.style.position = "absolute";
code.appendChild(node);
- node.style.left = left + "px";
- if (where == "over") top = pos.y;
- else if (where == "near") {
- var vspace = Math.max(scroller.offsetHeight, lines.length * lineHeight()),
+ if (vert == "over") top = pos.y;
+ else if (vert == "near") {
+ var vspace = Math.max(scroller.offsetHeight, doc.height * textHeight()),
hspace = Math.max(code.clientWidth, lineSpace.clientWidth) - paddingLeft();
if (pos.yBot + node.offsetHeight > vspace && pos.y > node.offsetHeight)
top = pos.y - node.offsetHeight;
@@ -170,12 +205,20 @@ var CodeMirror = (function() {
left = hspace - node.offsetWidth;
}
node.style.top = (top + paddingTop()) + "px";
- node.style.left = (left + paddingLeft()) + "px";
+ node.style.left = node.style.right = "";
+ if (horiz == "right") {
+ left = code.clientWidth - node.offsetWidth;
+ node.style.right = "0px";
+ } else {
+ if (horiz == "left") left = 0;
+ else if (horiz == "middle") left = (code.clientWidth - node.offsetWidth) / 2;
+ node.style.left = (left + paddingLeft()) + "px";
+ }
if (scroll)
scrollIntoView(left, top, left + node.offsetWidth, top + node.offsetHeight);
},
- lineCount: function() {return lines.length;},
+ lineCount: function() {return doc.size;},
getCursor: function(start) {
if (start == null) start = sel.inverted;
return copyPos(start ? sel.from : sel.to);
@@ -186,9 +229,9 @@ var CodeMirror = (function() {
else setCursor(line, ch);
}),
setSelection: operation(function(from, to) {setSelection(clipPos(from), clipPos(to || from));}),
- getLine: function(line) {if (isLine(line)) return lines[line].text;},
+ getLine: function(line) {if (isLine(line)) return getLine(line).text;},
setLine: operation(function(line, text) {
- if (isLine(line)) replaceRange(text, {line: line, ch: 0}, {line: line, ch: lines[line].text.length});
+ if (isLine(line)) replaceRange(text, {line: line, ch: 0}, {line: line, ch: getLine(line).text.length});
}),
removeLine: operation(function(line) {
if (isLine(line)) replaceRange("", {line: line, ch: 0}, clipPos({line: line+1, ch: 0}));
@@ -196,24 +239,41 @@ var CodeMirror = (function() {
replaceRange: operation(replaceRange),
getRange: function(from, to) {return getRange(clipPos(from), clipPos(to));},
+ coordsFromIndex: function(off) {
+ var lineNo = 0, ch;
+ doc.iter(0, doc.size, function(line) {
+ var sz = line.text.length + 1;
+ if (sz > off) { ch = off; return true; }
+ off -= sz;
+ ++lineNo;
+ });
+ return clipPos({line: lineNo, ch: ch});
+ },
+
operation: function(f){return operation(f)();},
refresh: function(){updateDisplay(true);},
getInputField: function(){return input;},
getWrapperElement: function(){return wrapper;},
- getScrollerElement: function(){return scroller;}
+ getScrollerElement: function(){return scroller;},
+ getGutterElement: function(){return gutter;}
};
+ function getLine(n) { return getLineAt(doc, n); }
+ function updateLineHeight(line, height) {
+ gutterDirty = true;
+ var diff = height - line.height;
+ for (var n = line; n; n = n.parent) n.height += diff;
+ }
+
function setValue(code) {
- history = null;
var top = {line: 0, ch: 0};
- updateLines(top, {line: lines.length - 1, ch: lines[lines.length-1].text.length},
+ updateLines(top, {line: doc.size - 1, ch: getLine(doc.size-1).text.length},
splitLines(code), top, top);
- history = new History();
+ updateInput = true;
}
function getValue(code) {
var text = [];
- for (var i = 0, l = lines.length; i < l; ++i)
- text.push(lines[i].text);
+ doc.iter(0, doc.size, function(line) { text.push(line.text); });
return text.join("\n");
}
@@ -221,17 +281,17 @@ var CodeMirror = (function() {
// Check whether this is a click in a widget
for (var n = e_target(e); n != wrapper; n = n.parentNode)
if (n.parentNode == code && n != mover) return;
- var ld = lastDoubleClick; lastDoubleClick = null;
- // First, see if this is a click in the gutter
+
+ // See if this is a click in the gutter
for (var n = e_target(e); n != wrapper; n = n.parentNode)
if (n.parentNode == gutterText) {
if (options.onGutterClick)
- options.onGutterClick(instance, indexOf(gutterText.childNodes, n) + showingFrom);
+ options.onGutterClick(instance, indexOf(gutterText.childNodes, n) + showingFrom, e);
return e_preventDefault(e);
}
var start = posFromMouse(e);
-
+
switch (e_button(e)) {
case 3:
if (gecko && !mac) onContextMenu(e);
@@ -246,18 +306,39 @@ var CodeMirror = (function() {
if (!start) {if (e_target(e) == scroller) e_preventDefault(e); return;}
if (!focused) onFocus();
- e_preventDefault(e);
- if (ld && +new Date - ld < 400) return selectLine(start.line);
- setCursor(start.line, start.ch, true);
+ var now = +new Date;
+ if (lastDoubleClick && lastDoubleClick.time > now - 400 && posEq(lastDoubleClick.pos, start)) {
+ e_preventDefault(e);
+ setTimeout(focusInput, 20);
+ return selectLine(start.line);
+ } else if (lastClick && lastClick.time > now - 400 && posEq(lastClick.pos, start)) {
+ lastDoubleClick = {time: now, pos: start};
+ e_preventDefault(e);
+ return selectWordAt(start);
+ } else { lastClick = {time: now, pos: start}; }
+
var last = start, going;
- // And then we have to see if it's a drag event, in which case
- // the dragged-over text must be selected.
- function end() {
- focusInput();
- updateInput = true;
- move(); up();
+ if (dragAndDrop && !posEq(sel.from, sel.to) &&
+ !posLess(start, sel.from) && !posLess(sel.to, start)) {
+ // Let the drag handler handle this.
+ if (webkit) lineSpace.draggable = true;
+ var up = connect(targetDocument, "mouseup", operation(function(e2) {
+ if (webkit) lineSpace.draggable = false;
+ draggingText = false;
+ up();
+ if (Math.abs(e.clientX - e2.clientX) + Math.abs(e.clientY - e2.clientY) < 10) {
+ e_preventDefault(e2);
+ setCursor(start.line, start.ch, true);
+ focusInput();
+ }
+ }), true);
+ draggingText = true;
+ return;
}
+ e_preventDefault(e);
+ setCursor(start.line, start.ch, true);
+
function extend(e) {
var cur = posFromMouse(e, true);
if (cur && !posEq(cur, last)) {
@@ -281,15 +362,19 @@ var CodeMirror = (function() {
var cur = posFromMouse(e);
if (cur) setSelectionUser(start, cur);
e_preventDefault(e);
- end();
+ focusInput();
+ updateInput = true;
+ move(); up();
}), true);
}
- function onDblClick(e) {
- var pos = posFromMouse(e);
- if (!pos) return;
- selectWordAt(pos);
+ function onDoubleClick(e) {
+ for (var n = e_target(e); n != wrapper; n = n.parentNode)
+ if (n.parentNode == gutterText) return e_preventDefault(e);
+ var start = posFromMouse(e);
+ if (!start) return;
+ lastDoubleClick = {time: +new Date, pos: start};
e_preventDefault(e);
- lastDoubleClick = +new Date;
+ selectWordAt(start);
}
function onDrop(e) {
e.preventDefault();
@@ -300,7 +385,13 @@ var CodeMirror = (function() {
var reader = new FileReader;
reader.onload = function() {
text[i] = reader.result;
- if (++read == n) replaceRange(text.join(""), clipPos(pos), clipPos(pos));
+ if (++read == n) {
+ pos = clipPos(pos);
+ operation(function() {
+ var end = replaceRange(text.join(""), pos, pos);
+ setSelectionUser(pos, end);
+ })();
+ }
};
reader.readAsText(file);
}
@@ -310,11 +401,24 @@ var CodeMirror = (function() {
else {
try {
var text = e.dataTransfer.getData("Text");
- if (text) replaceRange(text, pos, pos);
+ if (text) {
+ var end = replaceRange(text, pos, pos);
+ var curFrom = sel.from, curTo = sel.to;
+ setSelectionUser(pos, end);
+ if (draggingText) replaceRange("", curFrom, curTo);
+ focusInput();
+ }
}
catch(e){}
}
}
+ function onDragStart(e) {
+ var txt = getSelection();
+ // This will reset escapeElement
+ htmlEscape(txt);
+ e.dataTransfer.setDragImage(escapeElement, 0, 0);
+ e.dataTransfer.setData("Text", txt);
+ }
function onKeyDown(e) {
if (!focused) onFocus();
@@ -340,6 +444,7 @@ var CodeMirror = (function() {
if (mod && code == 90) {undo(); return e_preventDefault(e);} // ctrl-z
if (mod && ((e.shiftKey && code == 90) || code == 89)) {redo(); return e_preventDefault(e);} // ctrl-shift-z, ctrl-y
}
+ if (code == 36) { if (options.smartHome) { smartHome(); return e_preventDefault(e); } }
// Key id to use in the movementKeys map. We also pass it to
// fastPoll in order to 'self learn'. We need this because
@@ -347,15 +452,19 @@ var CodeMirror = (function() {
// its start when it is inverted and a movement key is pressed
// (and later restore it again), shouldn't be used for
// non-movement keys.
- curKeyId = (mod ? "c" : "") + code;
- if (sel.inverted && movementKeys.hasOwnProperty(curKeyId)) {
+ curKeyId = (mod ? "c" : "") + (e.altKey ? "a" : "") + code;
+ if (sel.inverted && movementKeys[curKeyId] === true) {
var range = selRange(input);
if (range) {
reducedSelection = {anchor: range.start};
setSelRange(input, range.start, range.start);
}
}
+ // Don't save the key as a movementkey unless it had a modifier
+ if (!mod && !e.altKey) curKeyId = null;
fastPoll(curKeyId);
+
+ if (options.pollForIME && keyMightStartIME(code)) slowPollInterval = 50;
}
function onKeyUp(e) {
if (options.onKeyEvent && options.onKeyEvent(instance, addStop(e))) return;
@@ -364,6 +473,8 @@ var CodeMirror = (function() {
updateInput = true;
}
if (e.keyCode == 16) shiftSelecting = null;
+
+ if (slowPollInterval < 2000 && !alwaysPollForIME) slowPollInterval = 2000;
}
function onKeyPress(e) {
if (options.onKeyEvent && options.onKeyEvent(instance, addStop(e))) return;
@@ -406,7 +517,7 @@ var CodeMirror = (function() {
function updateLines(from, to, newText, selFrom, selTo) {
if (history) {
var old = [];
- for (var i = from.line, e = to.line + 1; i < e; ++i) old.push(lines[i].text);
+ doc.iter(from.line, to.line + 1, function(line) { old.push(line.text); });
history.addChange(from.line, newText.length, old);
while (history.done.length > options.undoDepth) history.done.shift();
}
@@ -416,11 +527,11 @@ var CodeMirror = (function() {
var change = from.pop();
if (change) {
var replaced = [], end = change.start + change.added;
- for (var i = change.start; i < end; ++i) replaced.push(lines[i].text);
+ doc.iter(change.start, end, function(line) { replaced.push(line.text); });
to.push({start: change.start, added: change.old.length, old: replaced});
var pos = clipPos({line: change.start + change.old.length - 1,
ch: editEnd(replaced[replaced.length-1], change.old[change.old.length-1])});
- updateLinesNoUndo({line: change.start, ch: 0}, {line: end - 1, ch: lines[end-1].text.length}, change.old, pos, pos);
+ updateLinesNoUndo({line: change.start, ch: 0}, {line: end - 1, ch: getLine(end-1).text.length}, change.old, pos, pos);
updateInput = true;
}
}
@@ -429,51 +540,66 @@ var CodeMirror = (function() {
function updateLinesNoUndo(from, to, newText, selFrom, selTo) {
var recomputeMaxLength = false, maxLineLength = maxLine.length;
- for (var i = from.line; i <= to.line; ++i) {
- if (lines[i].text.length == maxLineLength) {recomputeMaxLength = true; break;}
- }
+ if (!options.lineWrapping)
+ doc.iter(from.line, to.line, function(line) {
+ if (line.text.length == maxLineLength) {recomputeMaxLength = true; return true;}
+ });
- var nlines = to.line - from.line, firstLine = lines[from.line], lastLine = lines[to.line];
+ var nlines = to.line - from.line, firstLine = getLine(from.line), lastLine = getLine(to.line);
// First adjust the line structure, taking some care to leave highlighting intact.
if (firstLine == lastLine) {
if (newText.length == 1)
firstLine.replace(from.ch, to.ch, newText[0]);
else {
lastLine = firstLine.split(to.ch, newText[newText.length-1]);
- var spliceargs = [from.line + 1, nlines];
- firstLine.replace(from.ch, firstLine.text.length, newText[0]);
- for (var i = 1, e = newText.length - 1; i < e; ++i) spliceargs.push(new Line(newText[i]));
- spliceargs.push(lastLine);
- lines.splice.apply(lines, spliceargs);
+ firstLine.replace(from.ch, null, newText[0]);
+ firstLine.fixMarkEnds(lastLine);
+ var added = [];
+ for (var i = 1, e = newText.length - 1; i < e; ++i)
+ added.push(Line.inheritMarks(newText[i], firstLine));
+ added.push(lastLine);
+ doc.insert(from.line + 1, added);
}
}
else if (newText.length == 1) {
- firstLine.replace(from.ch, firstLine.text.length, newText[0] + lastLine.text.slice(to.ch));
- lines.splice(from.line + 1, nlines);
+ firstLine.replace(from.ch, null, newText[0]);
+ lastLine.replace(null, to.ch, "");
+ firstLine.append(lastLine);
+ doc.remove(from.line + 1, nlines);
}
else {
- var spliceargs = [from.line + 1, nlines - 1];
- firstLine.replace(from.ch, firstLine.text.length, newText[0]);
- lastLine.replace(0, to.ch, newText[newText.length-1]);
- for (var i = 1, e = newText.length - 1; i < e; ++i) spliceargs.push(new Line(newText[i]));
- lines.splice.apply(lines, spliceargs);
- }
-
-
- for (var i = from.line, e = i + newText.length; i < e; ++i) {
- var l = lines[i].text;
- if (l.length > maxLineLength) {
- maxLine = l; maxLineLength = l.length; maxWidth = null;
- recomputeMaxLength = false;
- }
- }
- if (recomputeMaxLength) {
- maxLineLength = 0; maxLine = ""; maxWidth = null;
- for (var i = 0, e = lines.length; i < e; ++i) {
- var l = lines[i].text;
+ var added = [];
+ firstLine.replace(from.ch, null, newText[0]);
+ lastLine.replace(null, to.ch, newText[newText.length-1]);
+ firstLine.fixMarkEnds(lastLine);
+ for (var i = 1, e = newText.length - 1; i < e; ++i)
+ added.push(Line.inheritMarks(newText[i], firstLine));
+ if (nlines > 1) doc.remove(from.line + 1, nlines - 1);
+ doc.insert(from.line + 1, added);
+ }
+ if (options.lineWrapping) {
+ var perLine = scroller.clientWidth / charWidth() - 3;
+ doc.iter(from.line, from.line + newText.length, function(line) {
+ if (line.hidden) return;
+ var guess = Math.ceil(line.text.length / perLine) || 1;
+ if (guess != line.height) updateLineHeight(line, guess);
+ });
+ } else {
+ doc.iter(from.line, i + newText.length, function(line) {
+ var l = line.text;
if (l.length > maxLineLength) {
- maxLineLength = l.length; maxLine = l;
+ maxLine = l; maxLineLength = l.length; maxWidth = null;
+ recomputeMaxLength = false;
}
+ });
+ if (recomputeMaxLength) {
+ maxLineLength = 0; maxLine = ""; maxWidth = null;
+ doc.iter(0, doc.size, function(line) {
+ var l = line.text;
+ if (l.length > maxLineLength) {
+ maxLineLength = l.length; maxLine = l;
+ }
+ });
}
}
@@ -485,12 +611,9 @@ var CodeMirror = (function() {
if (task < from.line) newWork.push(task);
else if (task > to.line) newWork.push(task + lendiff);
}
- if (newText.length < 5) {
- highlightLines(from.line, from.line + newText.length);
- newWork.push(from.line + newText.length);
- } else {
- newWork.push(from.line);
- }
+ var hlEnd = from.line + Math.min(newText.length, 500);
+ highlightLines(from.line, hlEnd);
+ newWork.push(hlEnd);
work = newWork;
startWorker(100);
// Remember that these lines changed, for updating the display
@@ -502,7 +625,7 @@ var CodeMirror = (function() {
setSelection(selFrom, selTo, updateLine(sel.from.line), updateLine(sel.to.line));
// Make sure the scroll-size div has the correct height.
- code.style.height = (lines.length * lineHeight() + 2 * paddingTop()) + "px";
+ code.style.height = (doc.height * textHeight() + 2 * paddingTop()) + "px";
}
function replaceRange(code, from, to) {
@@ -540,10 +663,10 @@ var CodeMirror = (function() {
function getRange(from, to) {
var l1 = from.line, l2 = to.line;
- if (l1 == l2) return lines[l1].text.slice(from.ch, to.ch);
- var code = [lines[l1].text.slice(from.ch)];
- for (var i = l1 + 1; i < l2; ++i) code.push(lines[i].text);
- code.push(lines[l2].text.slice(0, to.ch));
+ if (l1 == l2) return getLine(l1).text.slice(from.ch, to.ch);
+ var code = [getLine(l1).text.slice(from.ch)];
+ doc.iter(l1 + 1, l2, function(line) { code.push(line.text); });
+ code.push(getLine(l2).text.slice(0, to.ch));
return code.join("\n");
}
function getSelection() {
@@ -553,7 +676,7 @@ var CodeMirror = (function() {
var pollingFast = false; // Ensures slowPoll doesn't cancel fastPoll
function slowPoll() {
if (pollingFast) return;
- poll.set(2000, function() {
+ poll.set(slowPollInterval, function() {
startOperation();
readInput();
if (focused) slowPoll();
@@ -566,7 +689,10 @@ var CodeMirror = (function() {
function p() {
startOperation();
var changed = readInput();
- if (changed == "moved" && keyId) movementKeys[keyId] = true;
+ if (changed && keyId) {
+ if (changed == "moved" && movementKeys[keyId] == null) movementKeys[keyId] = true;
+ if (changed == "changed") movementKeys[keyId] = false;
+ }
if (!changed && !missed) {missed = true; poll.set(80, p);}
else {pollingFast = false; slowPoll();}
endOperation();
@@ -648,14 +774,16 @@ var CodeMirror = (function() {
// editor state.
function prepareInput() {
var text = [];
- var from = Math.max(0, sel.from.line - 1), to = Math.min(lines.length, sel.to.line + 2);
- for (var i = from; i < to; ++i) text.push(lines[i].text);
+ var from = Math.max(0, sel.from.line - 1), to = Math.min(doc.size, sel.to.line + 2);
+ doc.iter(from, to, function(line) { text.push(line.text); });
text = input.value = text.join(lineSep);
var startch = sel.from.ch, endch = sel.to.ch;
- for (var i = from; i < sel.from.line; ++i)
- startch += lineSep.length + lines[i].text.length;
- for (var i = from; i < sel.to.line; ++i)
- endch += lineSep.length + lines[i].text.length;
+ doc.iter(from, sel.from.line, function(line) {
+ startch += lineSep.length + line.text.length;
+ });
+ doc.iter(from, sel.to.line, function(line) {
+ endch += lineSep.length + line.text.length;
+ });
editing = {text: text, from: from, to: to, start: startch, end: endch};
setSelRange(input, startch, reducedSelection ? startch : endch);
}
@@ -663,21 +791,29 @@ var CodeMirror = (function() {
if (options.readOnly != "nocursor") input.focus();
}
+ function scrollEditorIntoView() {
+ if (!cursor.getBoundingClientRect) return;
+ var rect = cursor.getBoundingClientRect();
+ var winH = window.innerHeight || Math.max(document.body.offsetHeight, document.documentElement.offsetHeight);
+ if (rect.top < 0 || rect.bottom > winH) cursor.scrollIntoView();
+ }
function scrollCursorIntoView() {
var cursor = localCoords(sel.inverted ? sel.from : sel.to);
- return scrollIntoView(cursor.x, cursor.y, cursor.x, cursor.yBot);
+ var x = options.lineWrapping ? Math.min(cursor.x, lineSpace.offsetWidth) : cursor.x;
+ return scrollIntoView(x, cursor.y, x, cursor.yBot);
}
function scrollIntoView(x1, y1, x2, y2) {
- var pl = paddingLeft(), pt = paddingTop(), lh = lineHeight();
+ var pl = paddingLeft(), pt = paddingTop(), lh = textHeight();
y1 += pt; y2 += pt; x1 += pl; x2 += pl;
var screen = scroller.clientHeight, screentop = scroller.scrollTop, scrolled = false, result = true;
if (y1 < screentop) {scroller.scrollTop = Math.max(0, y1 - 2*lh); scrolled = true;}
else if (y2 > screentop + screen) {scroller.scrollTop = y2 + lh - screen; scrolled = true;}
var screenw = scroller.clientWidth, screenleft = scroller.scrollLeft;
- if (x1 < screenleft) {
+ var gutterw = options.fixedGutter ? gutter.clientWidth : 0;
+ if (x1 < screenleft + gutterw) {
if (x1 < 50) x1 = 0;
- scroller.scrollLeft = Math.max(0, x1 - 10);
+ scroller.scrollLeft = Math.max(0, x1 - 10 - gutterw);
scrolled = true;
}
else if (x2 > screenw + screenleft) {
@@ -690,32 +826,103 @@ var CodeMirror = (function() {
}
function visibleLines() {
- var lh = lineHeight(), top = scroller.scrollTop - paddingTop();
- return {from: Math.min(lines.length, Math.max(0, Math.floor(top / lh))),
- to: Math.min(lines.length, Math.ceil((top + scroller.clientHeight) / lh))};
+ var lh = textHeight(), top = scroller.scrollTop - paddingTop();
+ var from_height = Math.max(0, Math.floor(top / lh));
+ var to_height = Math.ceil((top + scroller.clientHeight) / lh);
+ return {from: lineAtHeight(doc, from_height),
+ to: lineAtHeight(doc, to_height)};
}
// Uses a set of changes plus the current scroll position to
// determine which DOM updates have to be made, and makes the
// updates.
function updateDisplay(changes) {
if (!scroller.clientWidth) {
- showingFrom = showingTo = 0;
+ showingFrom = showingTo = displayOffset = 0;
return;
}
- // First create a range of theoretically intact lines, and punch
- // holes in that using the change info.
- var intact = changes === true ? [] : [{from: showingFrom, to: showingTo, domStart: 0}];
+ // Compute the new visible window
+ var visible = visibleLines();
+ // Bail out if the visible area is already rendered and nothing changed.
+ if (changes !== true && changes.length == 0 && visible.from >= showingFrom && visible.to <= showingTo) return;
+ var from = Math.max(visible.from - 100, 0), to = Math.min(doc.size, visible.to + 100);
+ if (showingFrom < from && from - showingFrom < 20) from = showingFrom;
+ if (showingTo > to && showingTo - to < 20) to = Math.min(doc.size, showingTo);
+
+ // Create a range of theoretically intact lines, and punch holes
+ // in that using the change info.
+ var intact = changes === true ? [] :
+ computeIntact([{from: showingFrom, to: showingTo, domStart: 0}], changes);
+ // Clip off the parts that won't be visible
+ var intactLines = 0;
+ for (var i = 0; i < intact.length; ++i) {
+ var range = intact[i];
+ if (range.from < from) {range.domStart += (from - range.from); range.from = from;}
+ if (range.to > to) range.to = to;
+ if (range.from >= range.to) intact.splice(i--, 1);
+ else intactLines += range.to - range.from;
+ }
+ if (intactLines == to - from) return;
+ intact.sort(function(a, b) {return a.domStart - b.domStart;});
+
+ var th = textHeight(), gutterDisplay = gutter.style.display;
+ lineDiv.style.display = gutter.style.display = "none";
+ patchDisplay(from, to, intact);
+ lineDiv.style.display = "";
+
+ // Position the mover div to align with the lines it's supposed
+ // to be showing (which will cover the visible display)
+ var different = from != showingFrom || to != showingTo || lastHeight != scroller.clientHeight;
+ if (different) lastHeight = scroller.clientHeight;
+ showingFrom = from; showingTo = to;
+ displayOffset = heightAtLine(doc, from);
+ mover.style.top = (displayOffset * th) + "px";
+ code.style.height = (doc.height * th + 2 * paddingTop()) + "px";
+
+ // Since this is all rather error prone, it is honoured with the
+ // only assertion in the whole file.
+ if (lineDiv.childNodes.length != showingTo - showingFrom)
+ throw new Error("BAD PATCH! " + JSON.stringify(intact) + " size=" + (showingTo - showingFrom) +
+ " nodes=" + lineDiv.childNodes.length);
+
+ if (options.lineWrapping) {
+ maxWidth = scroller.clientWidth;
+ var curNode = lineDiv.firstChild;
+ doc.iter(showingFrom, showingTo, function(line) {
+ if (!line.hidden) {
+ var height = Math.round(curNode.offsetHeight / th) || 1;
+ if (line.height != height) {updateLineHeight(line, height); gutterDirty = true;}
+ }
+ curNode = curNode.nextSibling;
+ });
+ } else {
+ if (maxWidth == null) maxWidth = stringWidth(maxLine);
+ if (maxWidth > scroller.clientWidth) {
+ lineSpace.style.width = maxWidth + "px";
+ // Needed to prevent odd wrapping/hiding of widgets placed in here.
+ code.style.width = "";
+ code.style.width = scroller.scrollWidth + "px";
+ } else {
+ lineSpace.style.width = code.style.width = "";
+ }
+ }
+ gutter.style.display = gutterDisplay;
+ if (different || gutterDirty) updateGutter();
+ updateCursor();
+ }
+
+ function computeIntact(intact, changes) {
for (var i = 0, l = changes.length || 0; i < l; ++i) {
var change = changes[i], intact2 = [], diff = change.diff || 0;
for (var j = 0, l2 = intact.length; j < l2; ++j) {
var range = intact[j];
- if (change.to <= range.from)
- intact2.push({from: range.from + diff, to: range.to + diff, domStart: range.domStart});
- else if (range.to <= change.from)
+ if (change.to <= range.from && change.diff)
+ intact2.push({from: range.from + diff, to: range.to + diff,
+ domStart: range.domStart});
+ else if (change.to <= range.from || change.from >= range.to)
intact2.push(range);
else {
if (change.from > range.from)
- intact2.push({from: range.from, to: change.from, domStart: range.domStart})
+ intact2.push({from: range.from, to: change.from, domStart: range.domStart});
if (change.to < range.to)
intact2.push({from: change.to + diff, to: range.to + diff,
domStart: range.domStart + (change.to - range.from)});
@@ -723,158 +930,90 @@ var CodeMirror = (function() {
}
intact = intact2;
}
+ return intact;
+ }
- // Then, determine which lines we'd want to see, and which
- // updates have to be made to get there.
- var visible = visibleLines();
- var from = Math.min(showingFrom, Math.max(visible.from - 3, 0)),
- to = Math.min(lines.length, Math.max(showingTo, visible.to + 3)),
- updates = [], domPos = 0, domEnd = showingTo - showingFrom, pos = from, changedLines = 0;
-
- for (var i = 0, l = intact.length; i < l; ++i) {
- var range = intact[i];
- if (range.to <= from) continue;
- if (range.from >= to) break;
- if (range.domStart > domPos || range.from > pos) {
- updates.push({from: pos, to: range.from, domSize: range.domStart - domPos, domStart: domPos});
- changedLines += range.from - pos;
+ function patchDisplay(from, to, intact) {
+ // The first pass removes the DOM nodes that aren't intact.
+ if (!intact.length) lineDiv.innerHTML = "";
+ else {
+ function killNode(node) {
+ var tmp = node.nextSibling;
+ node.parentNode.removeChild(node);
+ return tmp;
}
- pos = range.to;
- domPos = range.domStart + (range.to - range.from);
- }
- if (domPos != domEnd || pos != to) {
- changedLines += Math.abs(to - pos);
- updates.push({from: pos, to: to, domSize: domEnd - domPos, domStart: domPos});
- }
-
- if (!updates.length) return;
- lineDiv.style.display = "none";
- // If more than 30% of the screen needs update, just do a full
- // redraw (which is quicker than patching)
- if (changedLines > (visible.to - visible.from) * .3)
- refreshDisplay(from = Math.max(visible.from - 10, 0), to = Math.min(visible.to + 7, lines.length));
- // Otherwise, only update the stuff that needs updating.
- else
- patchDisplay(updates);
- lineDiv.style.display = "";
-
- // Position the mover div to align with the lines it's supposed
- // to be showing (which will cover the visible display)
- var different = from != showingFrom || to != showingTo || lastHeight != scroller.clientHeight;
- showingFrom = from; showingTo = to;
- mover.style.top = (from * lineHeight()) + "px";
- if (different) {
- lastHeight = scroller.clientHeight;
- code.style.height = (lines.length * lineHeight() + 2 * paddingTop()) + "px";
- updateGutter();
- }
-
- if (maxWidth == null) maxWidth = stringWidth(maxLine);
- if (maxWidth > scroller.clientWidth) {
- lineSpace.style.width = maxWidth + "px";
- // Needed to prevent odd wrapping/hiding of widgets placed in here.
- code.style.width = "";
- code.style.width = scroller.scrollWidth + "px";
- } else {
- lineSpace.style.width = code.style.width = "";
+ var domPos = 0, curNode = lineDiv.firstChild, n;
+ for (var i = 0; i < intact.length; ++i) {
+ var cur = intact[i];
+ while (cur.domStart > domPos) {curNode = killNode(curNode); domPos++;}
+ for (var j = 0, e = cur.to - cur.from; j < e; ++j) {curNode = curNode.nextSibling; domPos++;}
+ }
+ while (curNode) curNode = killNode(curNode);
}
-
- // Since this is all rather error prone, it is honoured with the
- // only assertion in the whole file.
- if (lineDiv.childNodes.length != showingTo - showingFrom)
- throw new Error("BAD PATCH! " + JSON.stringify(updates) + " size=" + (showingTo - showingFrom) +
- " nodes=" + lineDiv.childNodes.length);
- updateCursor();
- }
-
- function refreshDisplay(from, to) {
- var html = [], start = {line: from, ch: 0}, inSel = posLess(sel.from, start) && !posLess(sel.to, start);
- for (var i = from; i < to; ++i) {
+ // This pass fills in the lines that actually changed.
+ var nextIntact = intact.shift(), curNode = lineDiv.firstChild, j = from;
+ var sfrom = sel.from.line, sto = sel.to.line, inSel = sfrom < from && sto >= from;
+ var scratch = targetDocument.createElement("div"), newElt;
+ doc.iter(from, to, function(line) {
var ch1 = null, ch2 = null;
if (inSel) {
ch1 = 0;
- if (sel.to.line == i) {inSel = false; ch2 = sel.to.ch;}
- }
- else if (sel.from.line == i) {
- if (sel.to.line == i) {ch1 = sel.from.ch; ch2 = sel.to.ch;}
+ if (sto == j) {inSel = false; ch2 = sel.to.ch;}
+ } else if (sfrom == j) {
+ if (sto == j) {ch1 = sel.from.ch; ch2 = sel.to.ch;}
else {inSel = true; ch1 = sel.from.ch;}
}
- html.push(lines[i].getHTML(ch1, ch2, true));
- }
- lineDiv.innerHTML = html.join("");
- }
- function patchDisplay(updates) {
- // Slightly different algorithm for IE (badInnerHTML), since
- // there .innerHTML on PRE nodes is dumb, and discards
- // whitespace.
- var sfrom = sel.from.line, sto = sel.to.line, off = 0,
- scratch = badInnerHTML && targetDocument.createElement("div");
- for (var i = 0, e = updates.length; i < e; ++i) {
- var rec = updates[i];
- var extra = (rec.to - rec.from) - rec.domSize;
- var nodeAfter = lineDiv.childNodes[rec.domStart + rec.domSize + off] || null;
- if (badInnerHTML)
- for (var j = Math.max(-extra, rec.domSize); j > 0; --j)
- lineDiv.removeChild(nodeAfter ? nodeAfter.previousSibling : lineDiv.lastChild);
- else if (extra) {
- for (var j = Math.max(0, extra); j > 0; --j)
- lineDiv.insertBefore(targetDocument.createElement("pre"), nodeAfter);
- for (var j = Math.max(0, -extra); j > 0; --j)
- lineDiv.removeChild(nodeAfter ? nodeAfter.previousSibling : lineDiv.lastChild);
- }
- var node = lineDiv.childNodes[rec.domStart + off], inSel = sfrom < rec.from && sto >= rec.from;
- for (var j = rec.from; j < rec.to; ++j) {
- var ch1 = null, ch2 = null;
- if (inSel) {
- ch1 = 0;
- if (sto == j) {inSel = false; ch2 = sel.to.ch;}
- }
- else if (sfrom == j) {
- if (sto == j) {ch1 = sel.from.ch; ch2 = sel.to.ch;}
- else {inSel = true; ch1 = sel.from.ch;}
- }
- if (badInnerHTML) {
- scratch.innerHTML = lines[j].getHTML(ch1, ch2, true);
- lineDiv.insertBefore(scratch.firstChild, nodeAfter);
- }
- else {
- node.innerHTML = lines[j].getHTML(ch1, ch2, false);
- node.className = lines[j].className || "";
- node = node.nextSibling;
- }
+ if (nextIntact && nextIntact.to == j) nextIntact = intact.shift();
+ if (!nextIntact || nextIntact.from > j) {
+ if (line.hidden) scratch.innerHTML = "<pre></pre>";
+ else scratch.innerHTML = line.getHTML(ch1, ch2, true);
+ lineDiv.insertBefore(scratch.firstChild, curNode);
+ } else {
+ curNode = curNode.nextSibling;
}
- off += extra;
- }
+ ++j;
+ });
}
function updateGutter() {
if (!options.gutter && !options.lineNumbers) return;
var hText = mover.offsetHeight, hEditor = scroller.clientHeight;
gutter.style.height = (hText - hEditor < 2 ? hEditor : hText) + "px";
- var html = [];
- for (var i = showingFrom; i < Math.max(showingTo, showingFrom + 1); ++i) {
- var marker = lines[i].gutterMarker;
- var text = options.lineNumbers ? i + options.firstLineNumber : null;
- if (marker && marker.text)
- text = marker.text.replace("%N%", text != null ? text : "");
- else if (text == null)
- text = "\u00a0";
- html.push((marker && marker.style ? '<pre class="' + marker.style + '">' : "<pre>"), text, "</pre>");
- }
+ var html = [], i = showingFrom;
+ doc.iter(showingFrom, Math.max(showingTo, showingFrom + 1), function(line) {
+ if (line.hidden) {
+ html.push("<pre></pre>");
+ } else {
+ var marker = line.gutterMarker;
+ var text = options.lineNumbers ? i + options.firstLineNumber : null;
+ if (marker && marker.text)
+ text = marker.text.replace("%N%", text != null ? text : "");
+ else if (text == null)
+ text = "\u00a0";
+ html.push((marker && marker.style ? '<pre class="' + marker.style + '">' : "<pre>"), text);
+ for (var j = 1; j < line.height; ++j) html.push("<br> ");
+ html.push("</pre>");
+ }
+ ++i;
+ });
gutter.style.display = "none";
gutterText.innerHTML = html.join("");
- var minwidth = String(lines.length).length, firstNode = gutterText.firstChild, val = eltText(firstNode), pad = "";
+ var minwidth = String(doc.size).length, firstNode = gutterText.firstChild, val = eltText(firstNode), pad = "";
while (val.length + pad.length < minwidth) pad += "\u00a0";
if (pad) firstNode.insertBefore(targetDocument.createTextNode(pad), firstNode.firstChild);
gutter.style.display = "";
lineSpace.style.marginLeft = gutter.offsetWidth + "px";
+ gutterDirty = false;
}
function updateCursor() {
- var head = sel.inverted ? sel.from : sel.to, lh = lineHeight();
- var x = charX(head.line, head.ch) + "px", y = (head.line - showingFrom) * lh + "px";
- inputDiv.style.top = (head.line * lh - scroller.scrollTop) + "px";
+ var head = sel.inverted ? sel.from : sel.to, lh = textHeight();
+ var pos = localCoords(head, true);
+ var globalY = pos.y + displayOffset * textHeight();
+ inputDiv.style.top = Math.max(Math.min(globalY, scroller.offsetHeight), 0) + "px";
+ inputDiv.style.left = (pos.x - scroller.scrollLeft) + "px";
if (posEq(sel.from, sel.to)) {
- cursor.style.top = y; cursor.style.left = x;
+ cursor.style.top = pos.y + "px";
+ cursor.style.left = (options.lineWrapping ? Math.min(pos.x, lineSpace.offsetWidth) : pos.x) + "px";
cursor.style.display = "";
}
else cursor.style.display = "none";
@@ -892,9 +1031,14 @@ var CodeMirror = (function() {
// updateLines, since they have to be expressed in the line
// numbers before the update.
function setSelection(from, to, oldFrom, oldTo) {
+ if (oldFrom == null) {oldFrom = sel.from.line; oldTo = sel.to.line;}
if (posEq(sel.from, from) && posEq(sel.to, to)) return;
if (posLess(to, from)) {var tmp = to; to = from; from = tmp;}
+ // Skip over hidden lines.
+ if (from.line != oldFrom) from = skipHidden(from, oldFrom, sel.from.ch);
+ if (to.line != oldTo) to = skipHidden(to, oldTo, sel.to.ch);
+
if (posEq(from, to)) sel.inverted = false;
else if (posEq(from, sel.to)) sel.inverted = false;
else if (posEq(to, sel.from)) sel.inverted = true;
@@ -902,7 +1046,6 @@ var CodeMirror = (function() {
// Some ugly logic used to only mark the lines that actually did
// see a change in selection as changed, rather than the whole
// selected range.
- if (oldFrom == null) {oldFrom = sel.from.line; oldTo = sel.to.line;}
if (posEq(from, to)) {
if (!posEq(sel.from, sel.to))
changes.push({from: oldFrom, to: oldTo + 1});
@@ -927,42 +1070,61 @@ var CodeMirror = (function() {
sel.from = from; sel.to = to;
selectionChanged = true;
}
+ function skipHidden(pos, oldLine, oldCh) {
+ function getNonHidden(dir) {
+ var lNo = pos.line + dir, end = dir == 1 ? doc.size : -1;
+ while (lNo != end) {
+ var line = getLine(lNo);
+ if (!line.hidden) {
+ var ch = pos.ch;
+ if (ch > oldCh || ch > line.text.length) ch = line.text.length;
+ return {line: lNo, ch: ch};
+ }
+ lNo += dir;
+ }
+ }
+ var line = getLine(pos.line);
+ if (!line.hidden) return pos;
+ if (pos.line >= oldLine) return getNonHidden(1) || getNonHidden(-1);
+ else return getNonHidden(-1) || getNonHidden(1);
+ }
function setCursor(line, ch, user) {
var pos = clipPos({line: line, ch: ch || 0});
(user ? setSelectionUser : setSelection)(pos, pos);
}
- function clipLine(n) {return Math.max(0, Math.min(n, lines.length-1));}
+ function clipLine(n) {return Math.max(0, Math.min(n, doc.size-1));}
function clipPos(pos) {
if (pos.line < 0) return {line: 0, ch: 0};
- if (pos.line >= lines.length) return {line: lines.length-1, ch: lines[lines.length-1].text.length};
- var ch = pos.ch, linelen = lines[pos.line].text.length;
+ if (pos.line >= doc.size) return {line: doc.size-1, ch: getLine(doc.size-1).text.length};
+ var ch = pos.ch, linelen = getLine(pos.line).text.length;
if (ch == null || ch > linelen) return {line: pos.line, ch: linelen};
else if (ch < 0) return {line: pos.line, ch: 0};
else return pos;
}
function scrollPage(down) {
- var linesPerPage = Math.floor(scroller.clientHeight / lineHeight()), head = sel.inverted ? sel.from : sel.to;
- setCursor(head.line + (Math.max(linesPerPage - 1, 1) * (down ? 1 : -1)), head.ch, true);
+ var linesPerPage = Math.floor(scroller.clientHeight / textHeight()), head = sel.inverted ? sel.from : sel.to;
+ var target = heightAtLine(doc, head.line) + (Math.max(linesPerPage - 1, 1) * (down ? 1 : -1));
+ setCursor(lineAtHeight(doc, target), head.ch, true);
}
function scrollEnd(top) {
- var pos = top ? {line: 0, ch: 0} : {line: lines.length - 1, ch: lines[lines.length-1].text.length};
+ var pos = top ? {line: 0, ch: 0} : {line: doc.size - 1, ch: getLine(doc.size-1).text.length};
setSelectionUser(pos, pos);
}
function selectAll() {
- var endLine = lines.length - 1;
- setSelection({line: 0, ch: 0}, {line: endLine, ch: lines[endLine].text.length});
+ var endLine = doc.size - 1;
+ setSelection({line: 0, ch: 0}, {line: endLine, ch: getLine(endLine).text.length});
}
function selectWordAt(pos) {
- var line = lines[pos.line].text;
+ var line = getLine(pos.line).text;
var start = pos.ch, end = pos.ch;
while (start > 0 && /\w/.test(line.charAt(start - 1))) --start;
while (end < line.length && /\w/.test(line.charAt(end))) ++end;
setSelectionUser({line: pos.line, ch: start}, {line: pos.line, ch: end});
}
function selectLine(line) {
- setSelectionUser({line: line, ch: 0}, {line: line, ch: lines[line].text.length});
+ setSelectionUser({line: line, ch: 0}, {line: line, ch: getLine(line).text.length});
}
function handleEnter() {
replaceSelection("\n", "end");
@@ -994,6 +1156,10 @@ var CodeMirror = (function() {
}
return true;
}
+ function smartHome() {
+ var firstNonWS = Math.max(0, getLine(sel.from.line).text.search(/\S/));
+ setCursor(sel.from.line, sel.from.ch <= firstNonWS && sel.from.ch ? 0 : firstNonWS, true);
+ }
function indentLine(n, how) {
if (how == "smart") {
@@ -1001,9 +1167,9 @@ var CodeMirror = (function() {
else var state = getStateBefore(n);
}
- var line = lines[n], curSpace = line.indentation(), curSpaceString = line.text.match(/^\s*/)[0], indentation;
+ var line = getLine(n), curSpace = line.indentation(), curSpaceString = line.text.match(/^\s*/)[0], indentation;
if (how == "prev") {
- if (n) indentation = lines[n-1].indentation();
+ if (n) indentation = getLine(n-1).indentation();
else indentation = 0;
}
else if (how == "smart") indentation = mode.indent(state, line.text.slice(curSpaceString.length));
@@ -1028,87 +1194,148 @@ var CodeMirror = (function() {
function loadMode() {
mode = CodeMirror.getMode(options, options.mode);
- for (var i = 0, l = lines.length; i < l; ++i)
- lines[i].stateAfter = null;
+ doc.iter(0, doc.size, function(line) { line.stateAfter = null; });
work = [0];
startWorker();
}
function gutterChanged() {
var visible = options.gutter || options.lineNumbers;
gutter.style.display = visible ? "" : "none";
- if (visible) updateGutter();
+ if (visible) gutterDirty = true;
else lineDiv.parentNode.style.marginLeft = 0;
}
+ function wrappingChanged(from, to) {
+ if (options.lineWrapping) {
+ wrapper.className += " CodeMirror-wrap";
+ var perLine = scroller.clientWidth / charWidth() - 3;
+ doc.iter(0, doc.size, function(line) {
+ if (line.hidden) return;
+ var guess = Math.ceil(line.text.length / perLine) || 1;
+ if (guess != 1) updateLineHeight(line, guess);
+ });
+ lineSpace.style.width = code.style.width = "";
+ } else {
+ wrapper.className = wrapper.className.replace(" CodeMirror-wrap", "");
+ maxWidth = null; maxLine = "";
+ doc.iter(0, doc.size, function(line) {
+ if (line.height != 1 && !line.hidden) updateLineHeight(line, 1);
+ if (line.text.length > maxLine.length) maxLine = line.text;
+ });
+ }
+ changes.push({from: 0, to: doc.size});
+ }
+
+ function TextMarker() { this.set = []; }
+ TextMarker.prototype.clear = operation(function() {
+ for (var i = 0, e = this.set.length; i < e; ++i) {
+ var mk = this.set[i].marked;
+ if (!mk) continue;
+ for (var j = 0; j < mk.length; ++j)
+ if (mk[j].set == this.set) mk.splice(j--, 1);
+ }
+ // We don't know the exact lines that changed. Refreshing is
+ // cheaper than finding them.
+ changes.push({from: 0, to: doc.size});
+ });
+ TextMarker.prototype.find = function() {
+ var from, to;
+ for (var i = 0, e = this.set.length; i < e; ++i) {
+ var line = this.set[i], mk = line.marked;
+ for (var j = 0; j < mk.length; ++j) {
+ var mark = mk[j];
+ if (mark.set == this.set) {
+ if (mark.from != null || mark.to != null) {
+ var found = lineNo(line);
+ if (found != null) {
+ if (mark.from != null) from = {line: found, ch: mark.from};
+ if (mark.to != null) to = {line: found, ch: mark.to};
+ }
+ }
+ }
+ }
+ }
+ return {from: from, to: to};
+ };
function markText(from, to, className) {
from = clipPos(from); to = clipPos(to);
- var accum = [];
+ var tm = new TextMarker();
function add(line, from, to, className) {
- var line = lines[line], mark = line.addMark(from, to, className);
- mark.line = line;
- accum.push(mark);
+ mark = getLine(line).addMark(new MarkedText(from, to, className, tm.set));
}
if (from.line == to.line) add(from.line, from.ch, to.ch, className);
else {
add(from.line, from.ch, null, className);
for (var i = from.line + 1, e = to.line; i < e; ++i)
- add(i, 0, null, className);
- add(to.line, 0, to.ch, className);
+ add(i, null, null, className);
+ add(to.line, null, to.ch, className);
}
changes.push({from: from.line, to: to.line + 1});
- return function() {
- var start, end;
- for (var i = 0; i < accum.length; ++i) {
- var mark = accum[i], found = indexOf(lines, mark.line);
- mark.line.removeMark(mark);
- if (found > -1) {
- if (start == null) start = found;
- end = found;
- }
- }
- if (start != null) changes.push({from: start, to: end + 1});
- };
+ return tm;
+ }
+
+ function setBookmark(pos) {
+ pos = clipPos(pos);
+ var bm = new Bookmark(pos.ch);
+ getLine(pos.line).addMark(bm);
+ return bm;
}
function addGutterMarker(line, text, className) {
- if (typeof line == "number") line = lines[clipLine(line)];
+ if (typeof line == "number") line = getLine(clipLine(line));
line.gutterMarker = {text: text, style: className};
- updateGutter();
+ gutterDirty = true;
return line;
}
function removeGutterMarker(line) {
- if (typeof line == "number") line = lines[clipLine(line)];
+ if (typeof line == "number") line = getLine(clipLine(line));
line.gutterMarker = null;
- updateGutter();
+ gutterDirty = true;
}
- function setLineClass(line, className) {
- if (typeof line == "number") {
- var no = line;
- line = lines[clipLine(line)];
- }
- else {
- var no = indexOf(lines, line);
- if (no == -1) return null;
- }
- if (line.className != className) {
- line.className = className;
- changes.push({from: no, to: no + 1});
- }
+
+ function changeLine(handle, op) {
+ var no = handle, line = handle;
+ if (typeof handle == "number") line = getLine(clipLine(handle));
+ else no = lineNo(handle);
+ if (no == null) return null;
+ if (op(line, no)) changes.push({from: no, to: no + 1});
return line;
}
+ function setLineClass(handle, className) {
+ return changeLine(handle, function(line) {
+ if (line.className != className) {
+ line.className = className;
+ return true;
+ }
+ });
+ }
+ function setLineHidden(handle, hidden) {
+ return changeLine(handle, function(line, no) {
+ if (line.hidden != hidden) {
+ line.hidden = hidden;
+ updateLineHeight(line, hidden ? 0 : 1);
+ if (hidden && (sel.from.line == no || sel.to.line == no))
+ setSelection(skipHidden(sel.from, sel.from.line, sel.from.ch),
+ skipHidden(sel.to, sel.to.line, sel.to.ch));
+ return (gutterDirty = true);
+ }
+ });
+ }
function lineInfo(line) {
if (typeof line == "number") {
+ if (!isLine(line)) return null;
var n = line;
- line = lines[line];
+ line = getLine(line);
if (!line) return null;
}
else {
- var n = indexOf(lines, line);
- if (n == -1) return null;
+ var n = lineNo(line);
+ if (n == null) return null;
}
var marker = line.gutterMarker;
- return {line: n, text: line.text, markerText: marker && marker.text, markerClass: marker && marker.style};
+ return {line: n, handle: line, text: line.text, markerText: marker && marker.text,
+ markerClass: marker && marker.style, lineClass: line.className};
}
function stringWidth(str) {
@@ -1118,21 +1345,16 @@ var CodeMirror = (function() {
}
// These are used to go from pixel positions to character
// positions, taking varying character widths into account.
- function charX(line, pos) {
- if (pos == 0) return 0;
- measure.innerHTML = "<pre><span>" + lines[line].getHTML(null, null, false, pos) + "</span></pre>";
- return measure.firstChild.firstChild.offsetWidth;
- }
function charFromX(line, x) {
if (x <= 0) return 0;
- var lineObj = lines[line], text = lineObj.text;
+ var lineObj = getLine(line), text = lineObj.text;
function getX(len) {
measure.innerHTML = "<pre><span>" + lineObj.getHTML(null, null, false, len) + "</span></pre>";
return measure.firstChild.firstChild.offsetWidth;
}
var from = 0, fromX = 0, to = text.length, toX;
// Guess a suitable upper bound for our search.
- var estimated = Math.min(to, Math.ceil(x / stringWidth("x")));
+ var estimated = Math.min(to, Math.ceil(x / charWidth()));
for (;;) {
var estX = getX(estimated);
if (estX <= x && estimated < to) estimated = Math.min(to, Math.ceil(estimated * 1.2));
@@ -1151,20 +1373,93 @@ var CodeMirror = (function() {
}
}
+ var tempId = Math.floor(Math.random() * 0xffffff).toString(16);
+ function measureLine(line, ch) {
+ var extra = "";
+ // Include extra text at the end to make sure the measured line is wrapped in the right way.
+ if (options.lineWrapping) {
+ var end = line.text.indexOf(" ", ch + 2);
+ extra = line.text.slice(ch + 1, end < 0 ? line.text.length : end + (ie ? 5 : 0));
+ }
+ measure.innerHTML = "<pre>" + line.getHTML(null, null, false, ch) +
+ '<span id="CodeMirror-temp-' + tempId + '">' + (line.text.charAt(ch) || " ") + "</span>" +
+ extra + "</pre>";
+ var elt = document.getElementById("CodeMirror-temp-" + tempId);
+ var top = elt.offsetTop, left = elt.offsetLeft;
+ // Older IEs report zero offsets for spans directly after a wrap
+ if (ie && ch && top == 0 && left == 0) {
+ var backup = document.createElement("span");
+ backup.innerHTML = "x";
+ elt.parentNode.insertBefore(backup, elt.nextSibling);
+ top = backup.offsetTop;
+ }
+ return {top: top, left: left};
+ }
function localCoords(pos, inLineWrap) {
- var lh = lineHeight(), line = pos.line - (inLineWrap ? showingFrom : 0);
- return {x: charX(pos.line, pos.ch), y: line * lh, yBot: (line + 1) * lh};
+ var x, lh = textHeight(), y = lh * (heightAtLine(doc, pos.line) - (inLineWrap ? displayOffset : 0));
+ if (pos.ch == 0) x = 0;
+ else {
+ var sp = measureLine(getLine(pos.line), pos.ch);
+ x = sp.left;
+ if (options.lineWrapping) y += Math.max(0, sp.top);
+ }
+ return {x: x, y: y, yBot: y + lh};
+ }
+ // Coords must be lineSpace-local
+ function coordsChar(x, y) {
+ if (y < 0) y = 0;
+ var th = textHeight(), cw = charWidth(), heightPos = displayOffset + Math.floor(y / th);
+ var lineNo = lineAtHeight(doc, heightPos);
+ if (lineNo >= doc.size) return {line: doc.size - 1, ch: 0};
+ var lineObj = getLine(lineNo), text = lineObj.text;
+ var tw = options.lineWrapping, innerOff = tw ? heightPos - heightAtLine(doc, lineNo) : 0;
+ if (x <= 0 && innerOff == 0) return {line: lineNo, ch: 0};
+ function getX(len) {
+ var sp = measureLine(lineObj, len);
+ if (tw) {
+ var off = Math.round(sp.top / th);
+ return Math.max(0, sp.left + (off - innerOff) * scroller.clientWidth);
+ }
+ return sp.left;
+ }
+ var from = 0, fromX = 0, to = text.length, toX;
+ // Guess a suitable upper bound for our search.
+ var estimated = Math.min(to, Math.ceil((x + innerOff * scroller.clientWidth * .9) / cw));
+ for (;;) {
+ var estX = getX(estimated);
+ if (estX <= x && estimated < to) estimated = Math.min(to, Math.ceil(estimated * 1.2));
+ else {toX = estX; to = estimated; break;}
+ }
+ if (x > toX) return {line: lineNo, ch: to};
+ // Try to guess a suitable lower bound as well.
+ estimated = Math.floor(to * 0.8); estX = getX(estimated);
+ if (estX < x) {from = estimated; fromX = estX;}
+ // Do a binary search between these bounds.
+ for (;;) {
+ if (to - from <= 1) return {line: lineNo, ch: (toX - x > x - fromX) ? from : to};
+ var middle = Math.ceil((from + to) / 2), middleX = getX(middle);
+ if (middleX > x) {to = middle; toX = middleX;}
+ else {from = middle; fromX = middleX;}
+ }
}
function pageCoords(pos) {
var local = localCoords(pos, true), off = eltOffset(lineSpace);
return {x: off.left + local.x, y: off.top + local.y, yBot: off.top + local.yBot};
}
- function lineHeight() {
- var nlines = lineDiv.childNodes.length;
- if (nlines) return (lineDiv.offsetHeight / nlines) || 1;
- measure.innerHTML = "<pre>x</pre>";
- return measure.firstChild.offsetHeight || 1;
+ var cachedHeight, cachedFor;
+ function textHeight() {
+ var offsetHeight = lineDiv.offsetHeight;
+ if (offsetHeight == cachedFor) return cachedHeight;
+ cachedFor = offsetHeight;
+ measure.innerHTML = "<pre>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x</pre>";
+ return (cachedHeight = measure.firstChild.offsetHeight / 10 || 1);
+ }
+ var cachedWidth, cachedFor = 0;
+ function charWidth() {
+ if (scroller.clientWidth == cachedFor) return cachedWidth;
+ cachedFor = scroller.clientWidth;
+ return (cachedWidth = stringWidth("x"));
}
function paddingTop() {return lineSpace.offsetTop;}
function paddingLeft() {return lineSpace.offsetLeft;}
@@ -1179,8 +1474,7 @@ var CodeMirror = (function() {
if (!liberal && (x - offW.left > scroller.clientWidth || y - offW.top > scroller.clientHeight))
return null;
var offL = eltOffset(lineSpace, true);
- var line = showingFrom + Math.floor((y - offL.top) / lineHeight());
- return clipPos({line: line, ch: charFromX(clipLine(line), x - offL.left)});
+ return coordsChar(x - offL.left, y - offL.top);
}
function onContextMenu(e) {
var pos = posFromMouse(e);
@@ -1190,8 +1484,8 @@ var CodeMirror = (function() {
var oldCSS = input.style.cssText;
inputDiv.style.position = "absolute";
- input.style.cssText = "position: fixed; width: 30px; height: 30px; top: " + (e_pageY(e) - 1) +
- "px; left: " + (e_pageX(e) - 1) + "px; z-index: 1000; background: white; " +
+ input.style.cssText = "position: fixed; width: 30px; height: 30px; top: " + (e.clientY - 5) +
+ "px; left: " + (e.clientX - 5) + "px; z-index: 1000; background: white; " +
"border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);";
leaveInputAlone = true;
var val = input.value = getSelection();
@@ -1206,7 +1500,7 @@ var CodeMirror = (function() {
prepareInput();
slowPoll();
}
-
+
if (gecko) {
e_stop(e);
var mouseup = connect(window, "mouseup", function() {
@@ -1231,7 +1525,7 @@ var CodeMirror = (function() {
var matching = {"(": ")>", ")": "(<", "[": "]>", "]": "[<", "{": "}>", "}": "{<"};
function matchBrackets(autoclear) {
- var head = sel.inverted ? sel.from : sel.to, line = lines[head.line], pos = head.ch - 1;
+ var head = sel.inverted ? sel.from : sel.to, line = getLine(head.line), pos = head.ch - 1;
var match = (pos >= 0 && matching[line.text.charAt(pos)]) || matching[line.text.charAt(++pos)];
if (!match) return;
var ch = match.charAt(0), forward = match.charAt(1) == ">", d = forward ? 1 : -1, st = line.styles;
@@ -1255,18 +1549,16 @@ var CodeMirror = (function() {
}
}
}
- for (var i = head.line, e = forward ? Math.min(i + 100, lines.length) : Math.max(-1, i - 100); i != e; i+=d) {
- var line = lines[i], first = i == head.line;
+ for (var i = head.line, e = forward ? Math.min(i + 100, doc.size) : Math.max(-1, i - 100); i != e; i+=d) {
+ var line = getLine(i), first = i == head.line;
var found = scan(line, first && forward ? pos + 1 : 0, first && !forward ? pos : line.text.length);
if (found) break;
}
if (!found) found = {pos: null, match: false};
var style = found.match ? "CodeMirror-matchingbracket" : "CodeMirror-nonmatchingbracket";
var one = markText({line: head.line, ch: pos}, {line: head.line, ch: pos+1}, style),
- two = found.pos != null
- ? markText({line: i, ch: found.pos}, {line: i, ch: found.pos + 1}, style)
- : function() {};
- var clear = operation(function(){one(); two();});
+ two = found.pos != null && markText({line: i, ch: found.pos}, {line: i, ch: found.pos + 1}, style);
+ var clear = operation(function(){one.clear(); two && two.clear();});
if (autoclear) setTimeout(clear, 800);
else bracketHighlighted = clear;
}
@@ -1280,66 +1572,69 @@ var CodeMirror = (function() {
var minindent, minline;
for (var search = n, lim = n - 40; search > lim; --search) {
if (search == 0) return 0;
- var line = lines[search-1];
+ var line = getLine(search-1);
if (line.stateAfter) return search;
var indented = line.indentation();
if (minline == null || minindent > indented) {
- minline = search;
+ minline = search - 1;
minindent = indented;
}
}
return minline;
}
function getStateBefore(n) {
- var start = findStartLine(n), state = start && lines[start-1].stateAfter;
+ var start = findStartLine(n), state = start && getLine(start-1).stateAfter;
if (!state) state = startState(mode);
else state = copyState(mode, state);
- for (var i = start; i < n; ++i) {
- var line = lines[i];
+ doc.iter(start, n, function(line) {
line.highlight(mode, state);
line.stateAfter = copyState(mode, state);
- }
- if (n < lines.length && !lines[n].stateAfter) work.push(n);
+ });
+ if (start < n) changes.push({from: start, to: n});
+ if (n < doc.size && !getLine(n).stateAfter) work.push(n);
return state;
}
function highlightLines(start, end) {
var state = getStateBefore(start);
- for (var i = start; i < end; ++i) {
- var line = lines[i];
+ doc.iter(start, end, function(line) {
line.highlight(mode, state);
line.stateAfter = copyState(mode, state);
- }
+ });
}
function highlightWorker() {
var end = +new Date + options.workTime;
var foundWork = work.length;
while (work.length) {
- if (!lines[showingFrom].stateAfter) var task = showingFrom;
+ if (!getLine(showingFrom).stateAfter) var task = showingFrom;
else var task = work.pop();
- if (task >= lines.length) continue;
- var start = findStartLine(task), state = start && lines[start-1].stateAfter;
+ if (task >= doc.size) continue;
+ var start = findStartLine(task), state = start && getLine(start-1).stateAfter;
if (state) state = copyState(mode, state);
else state = startState(mode);
- var unchanged = 0, compare = mode.compareStates;
- for (var i = start, l = lines.length; i < l; ++i) {
- var line = lines[i], hadState = line.stateAfter;
+ var unchanged = 0, compare = mode.compareStates, realChange = false,
+ i = start, bail = false;
+ doc.iter(i, doc.size, function(line) {
+ var hadState = line.stateAfter;
if (+new Date > end) {
work.push(i);
startWorker(options.workDelay);
- changes.push({from: task, to: i + 1});
- return;
+ if (realChange) changes.push({from: task, to: i + 1});
+ return (bail = true);
}
var changed = line.highlight(mode, state);
+ if (changed) realChange = true;
line.stateAfter = copyState(mode, state);
if (compare) {
- if (hadState && compare(hadState, state)) break;
+ if (hadState && compare(hadState, state)) return true;
} else {
- if (changed || !hadState) unchanged = 0;
- else if (++unchanged > 3) break;
+ if (changed !== false || !hadState) unchanged = 0;
+ else if (++unchanged > 3) return true;
}
- }
- changes.push({from: task, to: i + 1});
+ ++i;
+ });
+ if (bail) return;
+ if (realChange) changes.push({from: task, to: i + 1});
}
if (foundWork && options.onHighlightComplete)
options.onHighlightComplete(instance);
@@ -1360,9 +1655,12 @@ var CodeMirror = (function() {
var reScroll = false;
if (selectionChanged) reScroll = !scrollCursorIntoView();
if (changes.length) updateDisplay(changes);
- else if (selectionChanged) updateCursor();
+ else {
+ if (selectionChanged) updateCursor();
+ if (gutterDirty) updateGutter();
+ }
if (reScroll) scrollCursorIntoView();
- if (selectionChanged) restartBlink();
+ if (selectionChanged) {scrollEditorIntoView(); restartBlink();}
// updateInput can be set to a boolean value to force/prevent an
// update.
@@ -1406,7 +1704,7 @@ var CodeMirror = (function() {
if (typeof query != "string") // Regexp match
this.matches = function(reverse, pos) {
if (reverse) {
- var line = lines[pos.line].text.slice(0, pos.ch), match = line.match(query), start = 0;
+ var line = getLine(pos.line).text.slice(0, pos.ch), match = line.match(query), start = 0;
while (match) {
var ind = line.indexOf(match[0]);
start += ind;
@@ -1418,7 +1716,7 @@ var CodeMirror = (function() {
}
}
else {
- var line = lines[pos.line].text.slice(pos.ch), match = line.match(query),
+ var line = getLine(pos.line).text.slice(pos.ch), match = line.match(query),
start = match && pos.ch + line.indexOf(match[0]);
}
if (match)
@@ -1433,7 +1731,7 @@ var CodeMirror = (function() {
// Different methods for single-line and multi-line queries
if (target.length == 1)
this.matches = function(reverse, pos) {
- var line = fold(lines[pos.line].text), len = query.length, match;
+ var line = fold(getLine(pos.line).text), len = query.length, match;
if (reverse ? (pos.ch >= len && (match = line.lastIndexOf(query, pos.ch - len)) != -1)
: (match = line.indexOf(query, pos.ch)) != -1)
return {from: {line: pos.line, ch: match},
@@ -1441,14 +1739,14 @@ var CodeMirror = (function() {
};
else
this.matches = function(reverse, pos) {
- var ln = pos.line, idx = (reverse ? target.length - 1 : 0), match = target[idx], line = fold(lines[ln].text);
+ var ln = pos.line, idx = (reverse ? target.length - 1 : 0), match = target[idx], line = fold(getLine(ln).text);
var offsetA = (reverse ? line.indexOf(match) + match.length : line.lastIndexOf(match));
if (reverse ? offsetA >= pos.ch || offsetA != match.length
: offsetA <= pos.ch || offsetA != line.length - match.length)
return;
for (;;) {
- if (reverse ? !ln : ln == lines.length - 1) return;
- line = fold(lines[ln += reverse ? -1 : 1].text);
+ if (reverse ? !ln : ln == doc.size - 1) return;
+ line = fold(getLine(ln += reverse ? -1 : 1).text);
match = target[reverse ? --idx : ++idx];
if (idx > 0 && idx < target.length - 1) {
if (line != match) return;
@@ -1484,10 +1782,10 @@ var CodeMirror = (function() {
}
if (reverse) {
if (!pos.line) return savePosAndFail(0);
- pos = {line: pos.line-1, ch: lines[pos.line-1].text.length};
+ pos = {line: pos.line-1, ch: getLine(pos.line-1).text.length};
}
else {
- if (pos.line == lines.length - 1) return savePosAndFail(lines.length);
+ if (pos.line == doc.size - 1) return savePosAndFail(doc.size);
pos = {line: pos.line+1, ch: 0};
}
}
@@ -1523,10 +1821,13 @@ var CodeMirror = (function() {
enterMode: "indent",
electricChars: true,
onKeyEvent: null,
+ lineWrapping: false,
lineNumbers: false,
gutter: false,
+ fixedGutter: false,
firstLineNumber: 1,
readOnly: false,
+ smartHome: true,
onChange: null,
onCursorActivity: null,
onGutterClick: null,
@@ -1537,6 +1838,7 @@ var CodeMirror = (function() {
workDelay: 200,
undoDepth: 40,
tabindex: null,
+ pollForIME: false,
document: window.document
};
@@ -1572,7 +1874,7 @@ var CodeMirror = (function() {
CodeMirror.listMIMEs = function() {
var list = [];
for (var m in mimeModes)
- if (mimeModes.propertyIsEnumerable(m)) list.push(m);
+ if (mimeModes.propertyIsEnumerable(m)) list.push({mime: m, mode: mimeModes[m]});
return list;
};
@@ -1634,11 +1936,11 @@ var CodeMirror = (function() {
}
return nstate;
}
- CodeMirror.startState = startState;
+ CodeMirror.copyState = copyState;
function startState(mode, a1, a2) {
return mode.startState ? mode.startState(a1, a2) : true;
}
- CodeMirror.copyState = copyState;
+ CodeMirror.startState = startState;
// The character stream used by a mode's parser.
function StringStream(string) {
@@ -1660,7 +1962,7 @@ var CodeMirror = (function() {
if (ok) {++this.pos; return ch;}
},
eatWhile: function(match) {
- var start = this.start;
+ var start = this.pos;
while (this.eat(match)){}
return this.pos > start;
},
@@ -1695,18 +1997,98 @@ var CodeMirror = (function() {
};
CodeMirror.StringStream = StringStream;
+ function MarkedText(from, to, className, set) {
+ this.from = from; this.to = to; this.style = className; this.set = set;
+ }
+ MarkedText.prototype = {
+ attach: function(line) { this.set.push(line); },
+ detach: function(line) {
+ var ix = indexOf(this.set, line);
+ if (ix > -1) this.set.splice(ix, 1);
+ },
+ split: function(pos, lenBefore) {
+ if (this.to <= pos && this.to != null) return null;
+ var from = this.from < pos || this.from == null ? null : this.from - pos + lenBefore;
+ var to = this.to == null ? null : this.to - pos + lenBefore;
+ return new MarkedText(from, to, this.style, this.set);
+ },
+ dup: function() { return new MarkedText(null, null, this.style, this.set); },
+ clipTo: function(fromOpen, from, toOpen, to, diff) {
+ if (this.from != null && this.from >= from)
+ this.from = Math.max(to, this.from) + diff;
+ if (this.to != null && this.to > from)
+ this.to = to < this.to ? this.to + diff : from;
+ if (fromOpen && to > this.from && (to < this.to || this.to == null))
+ this.from = null;
+ if (toOpen && (from < this.to || this.to == null) && (from > this.from || this.from == null))
+ this.to = null;
+ },
+ isDead: function() { return this.from != null && this.to != null && this.from >= this.to; },
+ sameSet: function(x) { return this.set == x.set; }
+ };
+
+ function Bookmark(pos) {
+ this.from = pos; this.to = pos; this.line = null;
+ }
+ Bookmark.prototype = {
+ attach: function(line) { this.line = line; },
+ detach: function(line) { if (this.line == line) this.line = null; },
+ split: function(pos, lenBefore) {
+ if (pos < this.from) {
+ this.from = this.to = (this.from - pos) + lenBefore;
+ return this;
+ }
+ },
+ isDead: function() { return this.from > this.to; },
+ clipTo: function(fromOpen, from, toOpen, to, diff) {
+ if ((fromOpen || from < this.from) && (toOpen || to > this.to)) {
+ this.from = 0; this.to = -1;
+ } else if (this.from > from) {
+ this.from = this.to = Math.max(to, this.from) + diff;
+ }
+ },
+ sameSet: function(x) { return false; },
+ find: function() {
+ if (!this.line || !this.line.parent) return null;
+ return {line: lineNo(this.line), ch: this.from};
+ },
+ clear: function() {
+ if (this.line) {
+ var found = indexOf(this.line.marked, this);
+ if (found != -1) this.line.marked.splice(found, 1);
+ this.line = null;
+ }
+ }
+ };
+
// Line objects. These hold state related to a line, including
// highlighting info (the styles array).
function Line(text, styles) {
this.styles = styles || [text, null];
- this.stateAfter = null;
this.text = text;
+ this.height = 1;
this.marked = this.gutterMarker = this.className = null;
+ this.stateAfter = this.parent = this.hidden = null;
+ }
+ Line.inheritMarks = function(text, orig) {
+ var ln = new Line(text), mk = orig.marked;
+ if (mk) {
+ for (var i = 0; i < mk.length; ++i) {
+ if (mk[i].to == null && mk[i].style) {
+ var newmk = ln.marked || (ln.marked = []), mark = mk[i];
+ var nmark = mark.dup(); newmk.push(nmark); nmark.attach(ln);
+ }
+ }
+ }
+ return ln;
}
Line.prototype = {
// Replace a piece of a line, keeping the styles around it intact.
- replace: function(from, to, text) {
- var st = [], mk = this.marked;
+ replace: function(from, to_, text) {
+ // Reset line class if the whole text was replaced.
+ if (!from && (to_ == null || to_ == this.text.length))
+ this.className = this.gutterMarker = null;
+ var st = [], mk = this.marked, to = to_ == null ? this.text.length : to_;
copyStyles(0, from, this.styles, st);
if (text) st.push(text, null);
copyStyles(to, this.text.length, this.styles, st);
@@ -1714,34 +2096,79 @@ var CodeMirror = (function() {
this.text = this.text.slice(0, from) + text + this.text.slice(to);
this.stateAfter = null;
if (mk) {
- var diff = text.length - (to - from), end = this.text.length;
- function fix(n) {return n <= Math.min(to, to + diff) ? n : n + diff;}
- for (var i = 0; i < mk.length; ++i) {
- var mark = mk[i], del = false;
- if (mark.from >= end) del = true;
- else {mark.from = fix(mark.from); if (mark.to != null) mark.to = fix(mark.to);}
- if (del || mark.from >= mark.to) {mk.splice(i, 1); i--;}
+ var diff = text.length - (to - from);
+ for (var i = 0, mark = mk[i]; i < mk.length; ++i) {
+ mark.clipTo(from == null, from || 0, to_ == null, to, diff);
+ if (mark.isDead()) {mark.detach(this); mk.splice(i--, 1);}
}
}
},
- // Split a line in two, again keeping styles intact.
+ // Split a part off a line, keeping styles and markers intact.
split: function(pos, textBefore) {
- var st = [textBefore, null];
+ var st = [textBefore, null], mk = this.marked;
copyStyles(pos, this.text.length, this.styles, st);
- return new Line(textBefore + this.text.slice(pos), st);
+ var taken = new Line(textBefore + this.text.slice(pos), st);
+ if (mk) {
+ for (var i = 0; i < mk.length; ++i) {
+ var mark = mk[i];
+ var newmark = mark.split(pos, textBefore.length);
+ if (newmark) {
+ if (!taken.marked) taken.marked = [];
+ taken.marked.push(newmark); newmark.attach(taken);
+ }
+ }
+ }
+ return taken;
},
- addMark: function(from, to, style) {
- var mk = this.marked, mark = {from: from, to: to, style: style};
- if (this.marked == null) this.marked = [];
- this.marked.push(mark);
- this.marked.sort(function(a, b){return a.from - b.from;});
- return mark;
+ append: function(line) {
+ var mylen = this.text.length, mk = line.marked, mymk = this.marked;
+ this.text += line.text;
+ copyStyles(0, line.text.length, line.styles, this.styles);
+ if (mymk) {
+ for (var i = 0; i < mymk.length; ++i)
+ if (mymk[i].to == null) mymk[i].to = mylen;
+ }
+ if (mk && mk.length) {
+ if (!mymk) this.marked = mymk = [];
+ outer: for (var i = 0; i < mk.length; ++i) {
+ var mark = mk[i];
+ if (!mark.from) {
+ for (var j = 0; j < mymk.length; ++j) {
+ var mymark = mymk[j];
+ if (mymark.to == mylen && mymark.sameSet(mark)) {
+ mymark.to = mark.to == null ? null : mark.to + mylen;
+ if (mymark.isDead()) {
+ mymark.detach(this);
+ mk.splice(i--, 1);
+ }
+ continue outer;
+ }
+ }
+ }
+ mymk.push(mark);
+ mark.attach(this);
+ mark.from += mylen;
+ if (mark.to != null) mark.to += mylen;
+ }
+ }
},
- removeMark: function(mark) {
- var mk = this.marked;
+ fixMarkEnds: function(other) {
+ var mk = this.marked, omk = other.marked;
if (!mk) return;
- for (var i = 0; i < mk.length; ++i)
- if (mk[i] == mark) {mk.splice(i, 1); break;}
+ for (var i = 0; i < mk.length; ++i) {
+ var mark = mk[i], close = mark.to == null;
+ if (close && omk) {
+ for (var j = 0; j < omk.length; ++j)
+ if (omk[j].sameSet(mark)) {close = false; break;}
+ }
+ if (close) mark.to = this.text.length;
+ }
+ },
+ addMark: function(mark) {
+ mark.attach(this);
+ if (this.marked == null) this.marked = [];
+ this.marked.push(mark);
+ this.marked.sort(function(a, b){return (a.from || 0) - (b.from || 0);});
},
// Run the given mode's parser over a line, update the styles
// array, which contains alternating fragments of text and CSS
@@ -1769,10 +2196,10 @@ var CodeMirror = (function() {
}
if (st.length != pos) {st.length = pos; changed = true;}
if (pos && st[pos-2] != prevWord) changed = true;
- // Short lines with simple highlights always count as changed,
- // because they are likely to highlight the same way in various
- // contexts.
- return changed || (st.length < 5 && this.text.length < 10);
+ // Short lines with simple highlights return null, and are
+ // counted as changed by the driver because they are likely to
+ // highlight the same way in various contexts.
+ return changed || (st.length < 5 && this.text.length < 10 ? null : false);
},
// Fetch the parser token for a given character. Useful for hacks
// that want to inspect the mode state (say, for completion).
@@ -1792,11 +2219,14 @@ var CodeMirror = (function() {
// Produces an HTML fragment for the line, taking selection,
// marking, and highlighting into account.
getHTML: function(sfrom, sto, includePre, endAt) {
- var html = [];
+ var html = [], first = true;
if (includePre)
html.push(this.className ? '<pre class="' + this.className + '">': "<pre>");
function span(text, style) {
if (!text) return;
+ // Work around a bug where, in some compat modes, IE ignores leading spaces
+ if (first && ie && text.charAt(0) == " ") text = "\u00a0" + text.slice(1);
+ first = false;
if (style) html.push('<span class="', style, '">', htmlEscape(text), "</span>");
else html.push(htmlEscape(text));
}
@@ -1809,10 +2239,10 @@ var CodeMirror = (function() {
span(" ", sfrom != null && sto == null ? "CodeMirror-selected" : null);
else if (!marked && sfrom == null)
for (var i = 0, ch = 0; ch < len; i+=2) {
- var str = st[i], l = str.length;
+ var str = st[i], style = st[i+1], l = str.length;
if (ch + l > len) str = str.slice(0, len - ch);
ch += l;
- span(str, "cm-" + st[i+1]);
+ span(str, style && "cm-" + style);
}
else {
var pos = 0, i = 0, text = "", style, sg = 0;
@@ -1856,6 +2286,11 @@ var CodeMirror = (function() {
}
if (includePre) html.push("</pre>");
return html.join("");
+ },
+ cleanUp: function() {
+ this.parent = null;
+ if (this.marked)
+ for (var i = 0, e = this.marked.length; i < e; ++i) this.marked[i].detach(this);
}
};
// Utility used by replace and split above
@@ -1874,6 +2309,191 @@ var CodeMirror = (function() {
}
}
+ // Data structure that holds the sequence of lines.
+ function LeafChunk(lines) {
+ this.lines = lines;
+ this.parent = null;
+ for (var i = 0, e = lines.length, height = 0; i < e; ++i) {
+ lines[i].parent = this;
+ height += lines[i].height;
+ }
+ this.height = height;
+ }
+ LeafChunk.prototype = {
+ chunkSize: function() { return this.lines.length; },
+ remove: function(at, n) {
+ for (var i = at, e = at + n; i < e; ++i) {
+ var line = this.lines[i];
+ line.cleanUp();
+ this.height -= line.height;
+ }
+ this.lines.splice(at, n);
+ },
+ collapse: function(lines) {
+ lines.splice.apply(lines, [lines.length, 0].concat(this.lines));
+ },
+ insertHeight: function(at, lines, height) {
+ this.height += height;
+ this.lines.splice.apply(this.lines, [at, 0].concat(lines));
+ for (var i = 0, e = lines.length; i < e; ++i) lines[i].parent = this;
+ },
+ iterN: function(at, n, op) {
+ for (var e = at + n; at < e; ++at)
+ if (op(this.lines[at])) return true;
+ }
+ };
+ function BranchChunk(children) {
+ this.children = children;
+ var size = 0, height = 0;
+ for (var i = 0, e = children.length; i < e; ++i) {
+ var ch = children[i];
+ size += ch.chunkSize(); height += ch.height;
+ ch.parent = this;
+ }
+ this.size = size;
+ this.height = height;
+ this.parent = null;
+ }
+ BranchChunk.prototype = {
+ chunkSize: function() { return this.size; },
+ remove: function(at, n) {
+ this.size -= n;
+ for (var i = 0; i < this.children.length; ++i) {
+ var child = this.children[i], sz = child.chunkSize();
+ if (at < sz) {
+ var rm = Math.min(n, sz - at), oldHeight = child.height;
+ child.remove(at, rm);
+ this.height -= oldHeight - child.height;
+ if (sz == rm) { this.children.splice(i--, 1); child.parent = null; }
+ if ((n -= rm) == 0) break;
+ at = 0;
+ } else at -= sz;
+ }
+ if (this.size - n < 25) {
+ var lines = [];
+ this.collapse(lines);
+ this.children = [new LeafChunk(lines)];
+ }
+ },
+ collapse: function(lines) {
+ for (var i = 0, e = this.children.length; i < e; ++i) this.children[i].collapse(lines);
+ },
+ insert: function(at, lines) {
+ var height = 0;
+ for (var i = 0, e = lines.length; i < e; ++i) height += lines[i].height;
+ this.insertHeight(at, lines, height);
+ },
+ insertHeight: function(at, lines, height) {
+ this.size += lines.length;
+ this.height += height;
+ for (var i = 0, e = this.children.length; i < e; ++i) {
+ var child = this.children[i], sz = child.chunkSize();
+ if (at <= sz) {
+ child.insertHeight(at, lines, height);
+ if (child.lines && child.lines.length > 50) {
+ while (child.lines.length > 50) {
+ var spilled = child.lines.splice(child.lines.length - 25, 25);
+ var newleaf = new LeafChunk(spilled);
+ child.height -= newleaf.height;
+ this.children.splice(i + 1, 0, newleaf);
+ newleaf.parent = this;
+ }
+ this.maybeSpill();
+ }
+ break;
+ }
+ at -= sz;
+ }
+ },
+ maybeSpill: function() {
+ if (this.children.length <= 10) return;
+ var me = this;
+ do {
+ var spilled = me.children.splice(me.children.length - 5, 5);
+ var sibling = new BranchChunk(spilled);
+ if (!me.parent) { // Become the parent node
+ var copy = new BranchChunk(me.children);
+ copy.parent = me;
+ me.children = [copy, sibling];
+ me = copy;
+ } else {
+ me.size -= sibling.size;
+ me.height -= sibling.height;
+ var myIndex = indexOf(me.parent.children, me);
+ me.parent.children.splice(myIndex + 1, 0, sibling);
+ }
+ sibling.parent = me.parent;
+ } while (me.children.length > 10);
+ me.parent.maybeSpill();
+ },
+ iter: function(from, to, op) { this.iterN(from, to - from, op); },
+ iterN: function(at, n, op) {
+ for (var i = 0, e = this.children.length; i < e; ++i) {
+ var child = this.children[i], sz = child.chunkSize();
+ if (at < sz) {
+ var used = Math.min(n, sz - at);
+ if (child.iterN(at, used, op)) return true;
+ if ((n -= used) == 0) break;
+ at = 0;
+ } else at -= sz;
+ }
+ }
+ };
+
+ function getLineAt(chunk, n) {
+ for (;;) {
+ for (var i = 0, e = chunk.children.length; i < e; ++i) {
+ var child = chunk.children[i], sz = child.chunkSize();
+ if (n < sz) { chunk = child; break; }
+ n -= sz;
+ }
+ if (chunk.lines) return chunk.lines[n];
+ }
+ }
+ function lineNo(line) {
+ if (line.parent == null) return null;
+ var cur = line.parent, no = indexOf(cur.lines, line);
+ for (var chunk = cur.parent; chunk; cur = chunk, chunk = chunk.parent) {
+ for (var i = 0, e = chunk.children.length; ; ++i) {
+ if (chunk.children[i] == cur) break;
+ no += chunk.children[i].chunkSize();
+ }
+ }
+ return no;
+ }
+ function lineAtHeight(chunk, h) {
+ var n = 0;
+ outer: do {
+ for (var i = 0, e = chunk.children.length; i < e; ++i) {
+ var child = chunk.children[i], ch = child.height;
+ if (h < ch) { chunk = child; continue outer; }
+ h -= ch;
+ n += child.chunkSize();
+ }
+ return n;
+ } while (!chunk.lines);
+ for (var i = 0, e = chunk.lines.length; i < e; ++i) {
+ var line = chunk.lines[i], lh = line.height;
+ if (h < lh) break;
+ h -= lh;
+ }
+ return n + i;
+ }
+ function heightAtLine(chunk, n) {
+ var h = 0;
+ outer: do {
+ for (var i = 0, e = chunk.children.length; i < e; ++i) {
+ var child = chunk.children[i], sz = child.chunkSize();
+ if (n < sz) { chunk = child; continue outer; }
+ n -= sz;
+ h += child.height;
+ }
+ return h;
+ } while (!chunk.lines);
+ for (var i = 0; i < n; ++i) h += chunk.lines[i].height;
+ return h;
+ }
+
// The history object 'chunks' changes that are made close together
// and at almost the same time into bigger undoable units.
function History() {
@@ -1930,16 +2550,6 @@ var CodeMirror = (function() {
else if (e.button & 2) return 3;
else if (e.button & 4) return 2;
}
- function e_pageX(e) {
- if (e.pageX != null) return e.pageX;
- var doc = e_target(e).ownerDocument;
- return e.clientX + doc.body.scrollLeft + doc.documentElement.scrollLeft;
- }
- function e_pageY(e) {
- if (e.pageY != null) return e.pageY;
- var doc = e_target(e).ownerDocument;
- return e.clientY + doc.body.scrollTop + doc.documentElement.scrollTop;
- }
// Event handler registration. If disconnect is true, it'll return a
// function that unregisters the handler.
@@ -1958,16 +2568,18 @@ var CodeMirror = (function() {
function Delayed() {this.id = null;}
Delayed.prototype = {set: function(ms, f) {clearTimeout(this.id); this.id = setTimeout(f, ms);}};
- // Some IE versions don't preserve whitespace when setting the
- // innerHTML of a PRE tag.
- var badInnerHTML = (function() {
- var pre = document.createElement("pre");
- pre.innerHTML = " "; return !pre.innerHTML;
- })();
+ // Detect drag-and-drop
+ var dragAndDrop = function() {
+ // IE8 has ondragstart and ondrop properties, but doesn't seem to
+ // actually support ondragstart the way it's supposed to work.
+ if (/MSIE [1-8]\b/.test(navigator.userAgent)) return false;
+ var div = document.createElement('div');
+ return "draggable" in div;
+ }();
var gecko = /gecko\/\d{7}/i.test(navigator.userAgent);
var ie = /MSIE \d/.test(navigator.userAgent);
- var safari = /Apple Computer/.test(navigator.vendor);
+ var webkit = /WebKit\//.test(navigator.userAgent);
var lineSep = "\n";
// Feature-detect whether newlines in textareas are converted to \r\n
@@ -1979,6 +2591,7 @@ var CodeMirror = (function() {
var tabSize = 8;
var mac = /Mac/.test(navigator.platform);
+ var win = /Win/.test(navigator.platform);
var movementKeys = {};
for (var i = 35; i <= 40; ++i)
movementKeys[i] = movementKeys["c" + i] = true;
@@ -2001,21 +2614,44 @@ var CodeMirror = (function() {
if (elt.currentStyle) return elt.currentStyle;
return window.getComputedStyle(elt, null);
}
+
// Find the position of an element by following the offsetParent chain.
// If screen==true, it returns screen (rather than page) coordinates.
function eltOffset(node, screen) {
- var doc = node.ownerDocument.body;
- var x = 0, y = 0, skipDoc = false;
+ var bod = node.ownerDocument.body;
+ var x = 0, y = 0, skipBody = false;
for (var n = node; n; n = n.offsetParent) {
- x += n.offsetLeft; y += n.offsetTop;
+ var ol = n.offsetLeft, ot = n.offsetTop;
+ // Firefox reports weird inverted offsets when the body has a border.
+ if (n == bod) { x += Math.abs(ol); y += Math.abs(ot); }
+ else { x += ol, y += ot; }
if (screen && computedStyle(n).position == "fixed")
- skipDoc = true;
+ skipBody = true;
}
- var e = screen && !skipDoc ? null : doc;
+ var e = screen && !skipBody ? null : bod;
for (var n = node.parentNode; n != e; n = n.parentNode)
if (n.scrollLeft != null) { x -= n.scrollLeft; y -= n.scrollTop;}
return {left: x, top: y};
}
+ // Use the faster and saner getBoundingClientRect method when possible.
+ if (document.documentElement.getBoundingClientRect != null) eltOffset = function(node, screen) {
+ // Take the parts of bounding client rect that we are interested in so we are able to edit if need be,
+ // since the returned value cannot be changed externally (they are kept in sync as the element moves within the page)
+ try { var box turned value cannot be changed externally (they are kept in sync as the element moves within the page) ; �� �� u�AA�* �
CA�* cA�* ��^B�* Ж�� ��B�* ���� ���� k BA�* 6 � �! �! `��� Ж�� x�^B�* ���� ��AA�* � BA�* `��� `�AA�* ���� ���B�* u�AA�* ��B�* ؤ�B�* ���B�* �
CA�* x�^B�* ���� ���� k BA�* �! �! `��� �� H~>B�* ���� ��AA�* � BA�* `��� `�AA�* ���� ���� ���� 8cA�* �p� �� u�AA�* �
CA�* ���� p��� k BA�* G H I J K M N O P `��� Ж�� H5B�* @��� ��AA�* � BA�* `��� 0��B�* u�AA�* �^B�* �i�A�* ��B�* ؤ�B�* ���B�* �
CA�* H5B�* @��� ���� k BA�* 85B�* @��� ���� k BA�* (5B�* @��� ���� k BA�* 5B�* @��� ��� k BA�* ���B�* u�AA�* ���B�* ���� ���A�* e�AA�* ؤ�B�* ���� y��A�* e�AA�* ��B�* ���� Z��A�* e�AA�* �d�A�* �^B�* �i�A�* ��B�* ��^B�* ؤ�B�* ���B�* �
CA�* 8cA�* -�A�* �� p��A�* ���� `��� k BA�* 5 6 7 8 : <