Compare commits
490 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2802e29945 | |||
| e9eb8cbfc7 | |||
| d343d8380c | |||
| 02906fa39f | |||
| c1e797fe24 | |||
| d7a42d8445 | |||
| 4f82bed52e | |||
| 84365f6721 | |||
| e209dcc8d3 | |||
| cd15a0f983 | |||
| eb435e785c | |||
| f03e521120 | |||
| 883909af4b | |||
| 13d66433e7 | |||
| c44cfcb27c | |||
| c14e5cbae5 | |||
| f09e0b4205 | |||
| ad72cea9a6 | |||
| c289bc4239 | |||
| 733fa01b7e | |||
| 4d03460944 | |||
| b3ba5d9eaa | |||
| 9e8ef3585e | |||
| 5c9cf44720 | |||
| 05a0d19ee9 | |||
| d38adbe6ca | |||
| 871981cec7 | |||
| 8a54001e11 | |||
| 1e59f6e8be | |||
| 0e1eb5b56e | |||
| e43df945b4 | |||
| c23706b794 | |||
| 98cd10c6f5 | |||
| 55b92e854c | |||
| 0c926d60b8 | |||
| d4d91fd003 | |||
| 89c4efbac3 | |||
| 3a5a34da0a | |||
| cf3992545d | |||
| 0b7f663d43 | |||
| abd72f8df0 | |||
| 1abdf72a04 | |||
| 7c536b66d0 | |||
| cc1c019216 | |||
| d20f231b34 | |||
| 8b03bf5fd9 | |||
| af4025731a | |||
| 77bbb405fb | |||
| 7592cd2fe0 | |||
| c5b996c8b1 | |||
| ae0749d6b8 | |||
| 666a389718 | |||
| 6cd2bf9fea | |||
| 3ad7ea6df8 | |||
| cb75a96e2c | |||
| 70965f4b69 | |||
| 29042f08a1 | |||
| 379db55111 | |||
| 4a65e773ce | |||
| 2829a91ff7 | |||
| 083e75bfb1 | |||
| 8f95e6ebb3 | |||
| 6b1826e8da | |||
| f76598232a | |||
| 193149abac | |||
| 8c155d9f76 | |||
| 2061cc3674 | |||
| 832d6c2e97 | |||
| e0870bbdb2 | |||
| 297983f411 | |||
| 1e9872c015 | |||
| 7ddf0af81b | |||
| 359bae6d30 | |||
| d01add8f2b | |||
| 752a1c7df6 | |||
| 0d24d1e0d2 | |||
| 31fcf51506 | |||
| f3c5ed8ee6 | |||
| 76d77439b7 | |||
| 2b428c7eb9 | |||
| 106d4be274 | |||
| 8e5d6bc467 | |||
| e21aca045a | |||
| a359afb799 | |||
| 41fb55cb01 | |||
| f8cc65dfae | |||
| e94368a356 | |||
| 2c8f2173a3 | |||
| 65eb1e9cb7 | |||
| 69ecbdfecc | |||
| 6c622b4100 | |||
| 59b645c399 | |||
| 134723a54b | |||
| c482fed2c9 | |||
| f60846ea2e | |||
| cb23f8635a | |||
| 19f8f6bf3c | |||
| b036cb04ff | |||
| 050efa339d | |||
| faeff098fe | |||
| 4e298ed7d8 | |||
| c810e4491a | |||
| edbf45e542 | |||
| caee53e778 | |||
| 55281650e2 | |||
| ff17b551b4 | |||
| 4c3ab339cd | |||
| 99d64722a1 | |||
| 1b12bcb5d9 | |||
| 7a083865dd | |||
| 794b6bcb7b | |||
| 64ccd9043e | |||
| 18af4e92b0 | |||
| cfbae50248 | |||
| 20576684dd | |||
| 1c2bdd1654 | |||
| 93aa1a13c6 | |||
| 4cd86a397c | |||
| efcb203dd9 | |||
| c859785edc | |||
| 41a4de081f | |||
| 82a8d41ac6 | |||
| d274389a33 | |||
| faecb124cc | |||
| ce2d958f9a | |||
| e37c8ff87f | |||
| fd2136875e | |||
| 35d56ec3f0 | |||
| 310528ea10 | |||
| 98ee81606b | |||
| 6731eb9b2d | |||
| e833783fb0 | |||
| 9d13d297cb | |||
| 2967969add | |||
| 060eddf812 | |||
| 473d2d5d09 | |||
| 13cc8df4be | |||
| 39edd4679d | |||
| 4cd45abfdd | |||
| cc297a06d3 | |||
| 341a5e0c40 | |||
| d967e23791 | |||
| 98610df1d4 | |||
| 7dd99cf3a1 | |||
| 9434baba11 | |||
| 4cbdf612af | |||
| 0c6eaf536a | |||
| 48870b1dd1 | |||
| 56121a9c9d | |||
| 0e0ae1b5be | |||
| e956d83aa2 | |||
| bfce480a91 | |||
| 3df446c306 | |||
| e10fd68f90 | |||
| cfd5842538 | |||
| 56e95fd640 | |||
| 52cf0dd147 | |||
| 311404d03c | |||
| 5900b3f1c7 | |||
| 45bc26f5eb | |||
| 45fc08e4a4 | |||
| e3aa776f5a | |||
| 7101762082 | |||
| 34bbb376be | |||
| 391bdf5cd4 | |||
| 1e4f533008 | |||
| dfd35b1a62 | |||
| c7f6545f8a | |||
| 71c6343aab | |||
| 65005ef93a | |||
| 7d59bcab72 | |||
| 3f200c245c | |||
| 378a696bfe | |||
| 200a953849 | |||
| 0e95fba28d | |||
| 907525efd7 | |||
| d490b794db | |||
| f04cc69abe | |||
| c93ce5dbab | |||
| 23c65eb518 | |||
| 2cf0e4a7ff | |||
| c2a23d03c2 | |||
| 09fb170a83 | |||
| 20e2d9aa57 | |||
| 4192405444 | |||
| 6bbafc5920 | |||
| 1caf7b5140 | |||
| 10e0ff71bf | |||
| 5a0aec5b1d | |||
| 9964add97c | |||
| d5f04551f2 | |||
| 8ba8eb58ed | |||
| 14cacefa96 | |||
| 6d6a4d3d33 | |||
| e19f280e1b | |||
| 40e5e42ecc | |||
| 1741a59d3a | |||
| 7787317d06 | |||
| 76b3906ade | |||
| efcf8c0c95 | |||
| 12bb4a8d93 | |||
| e56e376894 | |||
| 4b4ada4137 | |||
| eb94780cd4 | |||
| 750f963796 | |||
| 08639e6691 | |||
| 1a959baa72 | |||
| 227930e25b | |||
| 88ce19d99f | |||
| 257733e0cc | |||
| e0b147ead0 | |||
| 24283e7eeb | |||
| afe3f306e7 | |||
| c4a68e9e5a | |||
| 67c35e5327 | |||
| 53f4408652 | |||
| d72d5c64e2 | |||
| 9ca4b48f95 | |||
| 338331aa54 | |||
| 42c0b7b0fa | |||
| 28b9d322a2 | |||
| 38de99fc9c | |||
| a4416bd11f | |||
| 27cbd242b2 | |||
| c790b79393 | |||
| 7646dc11fe | |||
| 104ec5ba73 | |||
| 53a0718a78 | |||
| 892f123975 | |||
| 461daca00e | |||
| 09c0069b43 | |||
| 42de43d052 | |||
| 6ce51fa099 | |||
| 51728fb192 | |||
| d438b510df | |||
| 2d669a50b2 | |||
| 4aabf3c69c | |||
| 69f9cf28df | |||
| 81cb51bb8d | |||
| 371f97e050 | |||
| 3204447a74 | |||
| 36303e338d | |||
| b0b2fd7804 | |||
| a37206e259 | |||
| ff94a22826 | |||
| 8244472cb2 | |||
| 15dd46a91a | |||
| c379b00918 | |||
| 9bf856f6e6 | |||
| 37df0a9338 | |||
| e6aaca1728 | |||
| bbbee21b0d | |||
| 6fb6f441d5 | |||
| cda7c66637 | |||
| 53122bfa9f | |||
| 1fecd35bb7 | |||
| 85058bd847 | |||
| 40c02651ae | |||
| 8d72dc7bc4 | |||
| 46d630a2c0 | |||
| 7e040a4177 | |||
| 483de0fc30 | |||
| 09277868d2 | |||
| 86a19c25a8 | |||
| 1715b0c378 | |||
| 3599863304 | |||
| 91dc4f1d03 | |||
| 4b124cc214 | |||
| 0ed01e5a21 | |||
| b7192d706c | |||
| 557e4892b0 | |||
| b61b0bf3ad | |||
| 3a6a8af9f6 | |||
| 5b7167436b | |||
| 8d4b4430de | |||
| 9d4cb09fdf | |||
| 14bcad629e | |||
| 645c3b10dd | |||
| 16f9222847 | |||
| b7e7c8caf2 | |||
| 15cedc0269 | |||
| b14831613e | |||
| b673593683 | |||
| 7703d959ef | |||
| cb47024f2b | |||
| 55cbc1830a | |||
| 3f61d725c4 | |||
| bc8bc03fd2 | |||
| cbc20782ae | |||
| af290117d4 | |||
| 42a662a7ad | |||
| 2ead96313b | |||
| fcd9e0d5c6 | |||
| 593540e467 | |||
| f66d0e1200 | |||
| fa1c719c96 | |||
| 77b66d6015 | |||
| 8c14ba01f7 | |||
| ad87d196e5 | |||
| aac892364c | |||
| 64b670fd8f | |||
| a55c6777d3 | |||
| f9e16557c4 | |||
| 165b682e01 | |||
| 92ab6dc635 | |||
| 0385ce6eb2 | |||
| 5ba6e8fea2 | |||
| 8979c0919f | |||
| b9048b6d65 | |||
| 3592dba7f5 | |||
| a7defed64c | |||
| ff2f11a706 | |||
| 84cc47920b | |||
| f57d96d64d | |||
| c310627d1b | |||
| be66f53c7e | |||
| 77f32a8f4b | |||
| 9b8a24eeb9 | |||
| c87bf553f6 | |||
| 2361eb4a84 | |||
| 4f4cc8f98f | |||
| 5f1caf668b | |||
| 054152f162 | |||
| 78cf9df6ef | |||
| 2924b20c92 | |||
| f6318ae86c | |||
| e57907de35 | |||
| df2f9e7119 | |||
| 23d7eb7a43 | |||
| 99a6dbeac2 | |||
| b05daddc5c | |||
| 6868ddeed5 | |||
| 8de6bff2fb | |||
| 9028ec9857 | |||
| 8696a01eda | |||
| f8f91c6a6a | |||
| 97739e9e8a | |||
| 16b68572cd | |||
| d6e63b4d7c | |||
| a6e8111484 | |||
| bdc214f45b | |||
| a91570768e | |||
| d35321c6c6 | |||
| e482cba237 | |||
| c7cf13f8ea | |||
| e0329ce59a | |||
| de7848ba21 | |||
| d6f5a5684f | |||
| 9883590a91 | |||
| b11bdddfe2 | |||
| 623cd515de | |||
| f53da87f6f | |||
| ff7ef47cc7 | |||
| 108b24abdd | |||
| 2d309c6e81 | |||
| 07f0cdadcd | |||
| 7c8c9bc3af | |||
| 948e0b1f43 | |||
| be9027f36f | |||
| 9bb4155460 | |||
| ad877b2305 | |||
| fb9ad028f8 | |||
| 833694229d | |||
| d6a8a3d410 | |||
| 4e9d228a60 | |||
| db0d31260e | |||
| 9178b23473 | |||
| 40d5e5dfe9 | |||
| f95476c51e | |||
| 73ab77ad8b | |||
| e6f84c45b9 | |||
| 58c22b8ed0 | |||
| ee1de04544 | |||
| 9977aa571a | |||
| 65b883749a | |||
| 5cee4f8876 | |||
| 3aec2c4568 | |||
| 3defd7d7b1 | |||
| ac97332393 | |||
| 62bda4b917 | |||
| cb6857c16b | |||
| 643e945540 | |||
| b52b639eed | |||
| e0ea9b78f8 | |||
| 8e4f92ac64 | |||
| 350bd25404 | |||
| 6d3fe6cf89 | |||
| a3bf95e423 | |||
| fc72cdf3d0 | |||
| b619bd3db7 | |||
| b1631ae2b3 | |||
| a01aa78f36 | |||
| 975bc64fd0 | |||
| 231fa489cb | |||
| 123f0f8269 | |||
| a6223cc319 | |||
| 8bdc5f20e7 | |||
| bb4f3d6e1a | |||
| 25f54356d4 | |||
| 5b3b5b6821 | |||
| 1474a4fe79 | |||
| c89ed53be1 | |||
| e692beafba | |||
| 850ef39bf7 | |||
| 1bbb99b548 | |||
| 7675d605ea | |||
| 7d5cdb9220 | |||
| 78089bc0c4 | |||
| eb9d7bf5c3 | |||
| 8ce53e8dfa | |||
| 0f2b2daeab | |||
| 68ccf6510d | |||
| d960513ef2 | |||
| 1865c0b1dd | |||
| af412e7e24 | |||
| a74b1dd1bf | |||
| 7d9c853eeb | |||
| 7caf1c0794 | |||
| 70b3edcbeb | |||
| 50543724d4 | |||
| ad81e641b3 | |||
| 429ee8e423 | |||
| 604795d6fc | |||
| 6599e08d32 | |||
| 94ddb6c11f | |||
| a514060402 | |||
| fec5ddd150 | |||
| 811a44fd14 | |||
| 1c5bad24f3 | |||
| 17b4de18d7 | |||
| 290cb2f1a7 | |||
| ff7cb99bfe | |||
| 339de2fa41 | |||
| cafab17ee0 | |||
| 9fa1757ffb | |||
| e94921c002 | |||
| d30098d646 | |||
| fba11869b6 | |||
| 453412fa0c | |||
| 607897a1b0 | |||
| 221fdc51ba | |||
| 37551a8517 | |||
| 8877eab977 | |||
| 2d0205714c | |||
| 49111345d1 | |||
| 570564b0c4 | |||
| 22dd63d77b | |||
| 736311ff9a | |||
| 34b377522a | |||
| 9f846dbe3c | |||
| 845694beb6 | |||
| 665f728946 | |||
| d879e4a560 | |||
| 8e1a68d461 | |||
| 2738d12e0f | |||
| 25148d06fe | |||
| 4870b197de | |||
| 12377794a6 | |||
| bf27623756 | |||
| 9afdf01430 | |||
| 80f16dadde | |||
| a68ac4fc02 | |||
| 3dde465427 | |||
| f77232740c | |||
| 56f251ca0c | |||
| 9282bfcc60 | |||
| 8d0bbbc9f1 | |||
| ee33f2a4a8 | |||
| ab313c2d4d | |||
| 4c1de287cd | |||
| 9ea9f828bc | |||
| 58e4cd91cc | |||
| b5f17b1acb | |||
| e9c884d674 | |||
| 492953c7f0 | |||
| dd8d9d9d8d | |||
| 9ff32ed9cd | |||
| c9b0c4547a | |||
| 037b499cb2 | |||
| f4fc987597 | |||
| 580bc6fd6e | |||
| c91e6160fe | |||
| 13c6c1ad37 | |||
| 0faa7d3174 | |||
| cfe7c65987 | |||
| c5a2706c1b | |||
| a379d7020e | |||
| a74a16cfba | |||
| 37e0e1c384 | |||
| 62061ae737 |
+20
-1
@@ -1,7 +1,6 @@
|
||||
language: python
|
||||
|
||||
python:
|
||||
- '2.5'
|
||||
- '2.6'
|
||||
- '2.7'
|
||||
- 'pypy'
|
||||
@@ -11,6 +10,9 @@ env:
|
||||
- DB=sqlite:memory
|
||||
- DB=mysql://root:@localhost/test_w2p
|
||||
- DB=postgres://postgres:@localhost/test_w2p
|
||||
- DB=google:datastore
|
||||
- DB=mongodb://mongodb:mongodb@localhost/test_w2p
|
||||
- DB=imap://imap:imap@localhost:993
|
||||
before_script:
|
||||
- if [[ $TRAVIS_PYTHON_VERSION != '2.7' ]]; then pip install unittest2; fi
|
||||
- if [[ $TRAVIS_PYTHON_VERSION == '2.7' ]]; then pip install coverage; fi;
|
||||
@@ -19,6 +21,15 @@ before_script:
|
||||
- if [[ $TRAVIS_PYTHON_VERSION == '2.5' ]]; then pip install pysqlite; fi
|
||||
- if [[ $DB == mysql* ]]; then mysql -e 'create database test_w2p;'; fi
|
||||
- if [[ $DB == postgres* ]]; then psql -c 'create database test_w2p;' -U postgres; fi
|
||||
|
||||
# Install last sdk for app engine (update only whenever a new release is available)
|
||||
- if [[ $DB == google* ]]; then wget http://googleappengine.googlecode.com/files/google_appengine_1.8.9.zip -nv; fi
|
||||
- if [[ $DB == google* ]]; then unzip -q google_appengine_1.8.9.zip; fi
|
||||
- if [[ $DB == google* ]]; then mv -f ./google_appengine/google ./google; fi
|
||||
|
||||
- if [[ $DB == mongodb* ]]; then pip install pymongo; fi
|
||||
- if [[ $DB == mongodb* ]]; then mongo test_w2p --eval 'db.addUser("mongodb", "mongodb");'; fi
|
||||
|
||||
#Temporal solution to travis issue #155
|
||||
- sudo chmod 777 /dev/shm
|
||||
- sudo rm -rf /dev/shm && sudo ln -s /run/shm /dev/shm
|
||||
@@ -28,6 +39,11 @@ matrix:
|
||||
env: DB=postgres://postgres:@localhost/test_w2p
|
||||
- python: 'pypy'
|
||||
env: DB=mysql://root:@localhost/test_w2p
|
||||
- python: 'pypy'
|
||||
env: DB=google:datastore
|
||||
- python: '2.6'
|
||||
env: DB=google:datastore
|
||||
|
||||
|
||||
script: export COVERAGE_PROCESS_START=gluon/tests/coverage.ini; ./web2py.py --run_system_tests --with_coverage
|
||||
after_success:
|
||||
@@ -36,3 +52,6 @@ after_success:
|
||||
|
||||
notifications:
|
||||
email: true
|
||||
|
||||
services: mongodb
|
||||
|
||||
|
||||
@@ -1,3 +1,43 @@
|
||||
## 2.9.1 - 2.9.5
|
||||
|
||||
- many small but important bug fixes
|
||||
- jquery 1.11
|
||||
- codemirror 3.21, thanks Paolo Valleri
|
||||
- fixed security issue with sessions in database, thanks Nathan Humphreys
|
||||
- fixed security issue with persistant data in session, thanks Kiran
|
||||
- fixed security issue with redirect after expired login, thanks André Kablu
|
||||
- cleaner DAL and rname integration, thanks niphlod and Michele
|
||||
- added mongodb and imap tests for dal, thanks Alan
|
||||
- NoSQL dal tests, thanks Alan
|
||||
- better docstrings, thanks Niphlod
|
||||
- allow URL(...,language=...) with parametric router, thanks Jonathan
|
||||
- allow non-expiration of gae-memcache, thanks crimsoncantab
|
||||
- MARKMIN(...,_class='...'), thanks Luca
|
||||
- better transliteration in building slugs
|
||||
- autolink emails
|
||||
- new Janrain API, thanks PeterQ2
|
||||
- enable admin app for GAE (experimental), thanks Alan
|
||||
- many bug fixes
|
||||
- invalidate function in web2py.js, thanks Paolo
|
||||
- DAL(...,adapter_args=dict(engine='MyISAM'))
|
||||
- todolist panel in admin editor, thanks Paolo Valleri
|
||||
|
||||
## 2.8.1
|
||||
|
||||
- no more winservice (use nssm instead)
|
||||
- better imap support in DAL
|
||||
- db().select().as_tree()
|
||||
- bootstrap 2.3.2
|
||||
- codemirror 3.19
|
||||
- improved mongoDB support, thanks Alan
|
||||
- support for wiki custom render function
|
||||
- Wiki(...groups=['x','y']) allows bypassing default permissions
|
||||
- fixed websocket_messaging.py to support newer Tornado
|
||||
- NDB support for GAE, thanks Quint
|
||||
- fixed major concurrecy issue with MEMDB
|
||||
- blocked generic.jsonp for security reasons
|
||||
- many bug fixes, thanks Niphlod, Michele, Anthony, Tim, and many others.
|
||||
|
||||
## 2.7.1 - 2.7.4
|
||||
|
||||
- jQuery 1.10.2
|
||||
|
||||
@@ -30,7 +30,7 @@ update:
|
||||
echo "remember that pymysql was tweaked"
|
||||
src:
|
||||
### Use semantic versioning
|
||||
echo 'Version 2.7.4-stable+timestamp.'`date +%Y.%m.%d.%H.%M.%S` > VERSION
|
||||
echo 'Version 2.9.5-stable+timestamp.'`date +%Y.%m.%d.%H.%M.%S` > VERSION
|
||||
### rm -f all junk files
|
||||
make clean
|
||||
### clean up baisc apps
|
||||
|
||||
@@ -1 +1 @@
|
||||
Version 2.7.4-stable+timestamp.2013.10.14.10.13.57
|
||||
Version 2.9.5-stable+timestamp.2014.03.15.21.24.06
|
||||
|
||||
@@ -16,6 +16,8 @@ try:
|
||||
except ImportError:
|
||||
pgv = None
|
||||
|
||||
is_gae = request.env.web2py_runtime_gae or False
|
||||
|
||||
# ## critical --- make a copy of the environment
|
||||
|
||||
global_env = copy.copy(globals())
|
||||
@@ -186,6 +188,10 @@ def select():
|
||||
import re
|
||||
db = get_database(request)
|
||||
dbname = request.args[0]
|
||||
try:
|
||||
is_imap = db._uri.startswith("imap://")
|
||||
except (KeyError, AttributeError, TypeError):
|
||||
is_imap = False
|
||||
regex = re.compile('(?P<table>\w+)\.(?P<field>\w+)=(?P<value>\d+)')
|
||||
if len(request.args) > 1 and hasattr(db[request.args[1]], '_primarykey'):
|
||||
regex = re.compile('(?P<table>\w+)\.(?P<field>\w+)=(?P<value>.+)')
|
||||
@@ -203,7 +209,15 @@ def select():
|
||||
else:
|
||||
start = 0
|
||||
nrows = 0
|
||||
stop = start + 100
|
||||
|
||||
step = 100
|
||||
fields = []
|
||||
|
||||
if is_imap:
|
||||
step = 3
|
||||
|
||||
stop = start + step
|
||||
|
||||
table = None
|
||||
rows = []
|
||||
orderby = request.vars.orderby
|
||||
@@ -235,21 +249,27 @@ def select():
|
||||
if match:
|
||||
table = match.group('table')
|
||||
try:
|
||||
nrows = db(query).count()
|
||||
nrows = db(query, ignore_common_filters=True).count()
|
||||
if form.vars.update_check and form.vars.update_fields:
|
||||
db(query).update(**eval_in_global_env('dict(%s)'
|
||||
% form.vars.update_fields))
|
||||
db(query, ignore_common_filters=True).update(
|
||||
**eval_in_global_env('dict(%s)' % form.vars.update_fields))
|
||||
response.flash = T('%s %%{row} updated', nrows)
|
||||
elif form.vars.delete_check:
|
||||
db(query).delete()
|
||||
db(query, ignore_common_filters=True).delete()
|
||||
response.flash = T('%s %%{row} deleted', nrows)
|
||||
nrows = db(query).count()
|
||||
nrows = db(query, ignore_common_filters=True).count()
|
||||
|
||||
if is_imap:
|
||||
fields = [db[table][name] for name in
|
||||
("id", "uid", "created", "to",
|
||||
"sender", "subject")]
|
||||
if orderby:
|
||||
rows = db(query, ignore_common_filters=True).select(limitby=(
|
||||
start, stop), orderby=eval_in_global_env(orderby))
|
||||
rows = db(query, ignore_common_filters=True).select(
|
||||
*fields, limitby=(start, stop),
|
||||
orderby=eval_in_global_env(orderby))
|
||||
else:
|
||||
rows = db(query, ignore_common_filters=True).select(
|
||||
limitby=(start, stop))
|
||||
*fields, limitby=(start, stop))
|
||||
except Exception, e:
|
||||
import traceback
|
||||
tb = traceback.format_exc()
|
||||
@@ -278,11 +298,12 @@ def select():
|
||||
table=table,
|
||||
start=start,
|
||||
stop=stop,
|
||||
step=step,
|
||||
nrows=nrows,
|
||||
rows=rows,
|
||||
query=request.vars.query,
|
||||
formcsv=formcsv,
|
||||
tb=tb,
|
||||
tb=tb
|
||||
)
|
||||
|
||||
|
||||
@@ -340,36 +361,43 @@ def state():
|
||||
|
||||
|
||||
def ccache():
|
||||
cache.ram.initialize()
|
||||
cache.disk.initialize()
|
||||
if is_gae:
|
||||
form = FORM(
|
||||
P(TAG.BUTTON(T("Clear CACHE?"), _type="submit", _name="yes", _value="yes")))
|
||||
else:
|
||||
cache.ram.initialize()
|
||||
cache.disk.initialize()
|
||||
|
||||
form = FORM(
|
||||
P(TAG.BUTTON(
|
||||
T("Clear CACHE?"), _type="submit", _name="yes", _value="yes")),
|
||||
P(TAG.BUTTON(
|
||||
T("Clear RAM"), _type="submit", _name="ram", _value="ram")),
|
||||
P(TAG.BUTTON(
|
||||
T("Clear DISK"), _type="submit", _name="disk", _value="disk")),
|
||||
)
|
||||
form = FORM(
|
||||
P(TAG.BUTTON(
|
||||
T("Clear CACHE?"), _type="submit", _name="yes", _value="yes")),
|
||||
P(TAG.BUTTON(
|
||||
T("Clear RAM"), _type="submit", _name="ram", _value="ram")),
|
||||
P(TAG.BUTTON(
|
||||
T("Clear DISK"), _type="submit", _name="disk", _value="disk")),
|
||||
)
|
||||
|
||||
if form.accepts(request.vars, session):
|
||||
clear_ram = False
|
||||
clear_disk = False
|
||||
session.flash = ""
|
||||
if request.vars.yes:
|
||||
clear_ram = clear_disk = True
|
||||
if request.vars.ram:
|
||||
clear_ram = True
|
||||
if request.vars.disk:
|
||||
clear_disk = True
|
||||
|
||||
if clear_ram:
|
||||
cache.ram.clear()
|
||||
session.flash += T("Ram Cleared")
|
||||
if clear_disk:
|
||||
cache.disk.clear()
|
||||
session.flash += T("Disk Cleared")
|
||||
|
||||
if is_gae:
|
||||
if request.vars.yes:
|
||||
cache.ram.clear()
|
||||
session.flash += T("Cache Cleared")
|
||||
else:
|
||||
clear_ram = False
|
||||
clear_disk = False
|
||||
if request.vars.yes:
|
||||
clear_ram = clear_disk = True
|
||||
if request.vars.ram:
|
||||
clear_ram = True
|
||||
if request.vars.disk:
|
||||
clear_disk = True
|
||||
if clear_ram:
|
||||
cache.ram.clear()
|
||||
session.flash += T("Ram Cleared")
|
||||
if clear_disk:
|
||||
cache.disk.clear()
|
||||
session.flash += T("Disk Cleared")
|
||||
redirect(URL(r=request))
|
||||
|
||||
try:
|
||||
@@ -395,6 +423,7 @@ def ccache():
|
||||
'oldest': time.time(),
|
||||
'keys': []
|
||||
}
|
||||
|
||||
disk = copy.copy(ram)
|
||||
total = copy.copy(ram)
|
||||
disk['keys'] = []
|
||||
@@ -409,72 +438,81 @@ def ccache():
|
||||
|
||||
return (hours, minutes, seconds)
|
||||
|
||||
for key, value in cache.ram.storage.iteritems():
|
||||
if isinstance(value, dict):
|
||||
ram['hits'] = value['hit_total'] - value['misses']
|
||||
ram['misses'] = value['misses']
|
||||
try:
|
||||
ram['ratio'] = ram['hits'] * 100 / value['hit_total']
|
||||
except (KeyError, ZeroDivisionError):
|
||||
ram['ratio'] = 0
|
||||
else:
|
||||
if hp:
|
||||
ram['bytes'] += hp.iso(value[1]).size
|
||||
ram['objects'] += hp.iso(value[1]).count
|
||||
ram['entries'] += 1
|
||||
if value[0] < ram['oldest']:
|
||||
ram['oldest'] = value[0]
|
||||
ram['keys'].append((key, GetInHMS(time.time() - value[0])))
|
||||
folder = os.path.join(request.folder,'cache')
|
||||
if not os.path.exists(folder):
|
||||
os.mkdir(folder)
|
||||
locker = open(os.path.join(folder, 'cache.lock'), 'a')
|
||||
portalocker.lock(locker, portalocker.LOCK_EX)
|
||||
disk_storage = shelve.open(
|
||||
os.path.join(folder, 'cache.shelve'))
|
||||
try:
|
||||
for key, value in disk_storage.items():
|
||||
if is_gae:
|
||||
gae_stats = cache.ram.client.get_stats()
|
||||
try:
|
||||
gae_stats['ratio'] = ((gae_stats['hits'] * 100) /
|
||||
(gae_stats['hits'] + gae_stats['misses']))
|
||||
except ZeroDivisionError:
|
||||
gae_stats['ratio'] = T("?")
|
||||
gae_stats['oldest'] = GetInHMS(time.time() - gae_stats['oldest_item_age'])
|
||||
total.update(gae_stats)
|
||||
else:
|
||||
for key, value in cache.ram.storage.iteritems():
|
||||
if isinstance(value, dict):
|
||||
disk['hits'] = value['hit_total'] - value['misses']
|
||||
disk['misses'] = value['misses']
|
||||
ram['hits'] = value['hit_total'] - value['misses']
|
||||
ram['misses'] = value['misses']
|
||||
try:
|
||||
disk['ratio'] = disk['hits'] * 100 / value['hit_total']
|
||||
ram['ratio'] = ram['hits'] * 100 / value['hit_total']
|
||||
except (KeyError, ZeroDivisionError):
|
||||
disk['ratio'] = 0
|
||||
ram['ratio'] = 0
|
||||
else:
|
||||
if hp:
|
||||
disk['bytes'] += hp.iso(value[1]).size
|
||||
disk['objects'] += hp.iso(value[1]).count
|
||||
disk['entries'] += 1
|
||||
if value[0] < disk['oldest']:
|
||||
disk['oldest'] = value[0]
|
||||
disk['keys'].append((key, GetInHMS(time.time() - value[0])))
|
||||
ram['bytes'] += hp.iso(value[1]).size
|
||||
ram['objects'] += hp.iso(value[1]).count
|
||||
ram['entries'] += 1
|
||||
if value[0] < ram['oldest']:
|
||||
ram['oldest'] = value[0]
|
||||
ram['keys'].append((key, GetInHMS(time.time() - value[0])))
|
||||
folder = os.path.join(request.folder,'cache')
|
||||
if not os.path.exists(folder):
|
||||
os.mkdir(folder)
|
||||
locker = open(os.path.join(folder, 'cache.lock'), 'a')
|
||||
portalocker.lock(locker, portalocker.LOCK_EX)
|
||||
disk_storage = shelve.open(
|
||||
os.path.join(folder, 'cache.shelve'))
|
||||
try:
|
||||
for key, value in disk_storage.items():
|
||||
if isinstance(value, dict):
|
||||
disk['hits'] = value['hit_total'] - value['misses']
|
||||
disk['misses'] = value['misses']
|
||||
try:
|
||||
disk['ratio'] = disk['hits'] * 100 / value['hit_total']
|
||||
except (KeyError, ZeroDivisionError):
|
||||
disk['ratio'] = 0
|
||||
else:
|
||||
if hp:
|
||||
disk['bytes'] += hp.iso(value[1]).size
|
||||
disk['objects'] += hp.iso(value[1]).count
|
||||
disk['entries'] += 1
|
||||
if value[0] < disk['oldest']:
|
||||
disk['oldest'] = value[0]
|
||||
disk['keys'].append((key, GetInHMS(time.time() - value[0])))
|
||||
finally:
|
||||
portalocker.unlock(locker)
|
||||
locker.close()
|
||||
disk_storage.close()
|
||||
|
||||
finally:
|
||||
portalocker.unlock(locker)
|
||||
locker.close()
|
||||
disk_storage.close()
|
||||
|
||||
total['entries'] = ram['entries'] + disk['entries']
|
||||
total['bytes'] = ram['bytes'] + disk['bytes']
|
||||
total['objects'] = ram['objects'] + disk['objects']
|
||||
total['hits'] = ram['hits'] + disk['hits']
|
||||
total['misses'] = ram['misses'] + disk['misses']
|
||||
total['keys'] = ram['keys'] + disk['keys']
|
||||
try:
|
||||
total['ratio'] = total['hits'] * 100 / (total['hits'] +
|
||||
total['entries'] = ram['entries'] + disk['entries']
|
||||
total['bytes'] = ram['bytes'] + disk['bytes']
|
||||
total['objects'] = ram['objects'] + disk['objects']
|
||||
total['hits'] = ram['hits'] + disk['hits']
|
||||
total['misses'] = ram['misses'] + disk['misses']
|
||||
total['keys'] = ram['keys'] + disk['keys']
|
||||
try:
|
||||
total['ratio'] = total['hits'] * 100 / (total['hits'] +
|
||||
total['misses'])
|
||||
except (KeyError, ZeroDivisionError):
|
||||
total['ratio'] = 0
|
||||
except (KeyError, ZeroDivisionError):
|
||||
total['ratio'] = 0
|
||||
|
||||
if disk['oldest'] < ram['oldest']:
|
||||
total['oldest'] = disk['oldest']
|
||||
else:
|
||||
total['oldest'] = ram['oldest']
|
||||
if disk['oldest'] < ram['oldest']:
|
||||
total['oldest'] = disk['oldest']
|
||||
else:
|
||||
total['oldest'] = ram['oldest']
|
||||
|
||||
ram['oldest'] = GetInHMS(time.time() - ram['oldest'])
|
||||
disk['oldest'] = GetInHMS(time.time() - disk['oldest'])
|
||||
total['oldest'] = GetInHMS(time.time() - total['oldest'])
|
||||
ram['oldest'] = GetInHMS(time.time() - ram['oldest'])
|
||||
disk['oldest'] = GetInHMS(time.time() - disk['oldest'])
|
||||
total['oldest'] = GetInHMS(time.time() - total['oldest'])
|
||||
|
||||
def key_table(keys):
|
||||
return TABLE(
|
||||
@@ -483,9 +521,10 @@ def ccache():
|
||||
**dict(_class='cache-keys',
|
||||
_style="border-collapse: separate; border-spacing: .5em;"))
|
||||
|
||||
ram['keys'] = key_table(ram['keys'])
|
||||
disk['keys'] = key_table(disk['keys'])
|
||||
total['keys'] = key_table(total['keys'])
|
||||
if not is_gae:
|
||||
ram['keys'] = key_table(ram['keys'])
|
||||
disk['keys'] = key_table(disk['keys'])
|
||||
total['keys'] = key_table(total['keys'])
|
||||
|
||||
return dict(form=form, total=total,
|
||||
ram=ram, disk=disk, object_stats=hp != False)
|
||||
|
||||
@@ -54,9 +54,13 @@ def interact():
|
||||
filename = web_debugger.filename
|
||||
lineno = web_debugger.lineno
|
||||
if filename:
|
||||
# prevent IOError 2 on some circuntances (EAFP instead of os.access)
|
||||
try:
|
||||
lines = open(filename).readlines()
|
||||
except:
|
||||
lines = ""
|
||||
lines = dict([(i + 1, l) for (i, l) in enumerate(
|
||||
[l.strip("\n").strip("\r") for l
|
||||
in open(filename).readlines()])])
|
||||
[l.strip("\n").strip("\r") for l in lines])])
|
||||
filename = os.path.basename(filename)
|
||||
else:
|
||||
lines = {}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# coding: utf8
|
||||
|
||||
EXPERIMENTAL_STUFF = True
|
||||
MAXNFILES = 1000
|
||||
|
||||
if EXPERIMENTAL_STUFF:
|
||||
if is_mobile:
|
||||
@@ -12,6 +13,7 @@ from gluon.admin import *
|
||||
from gluon.fileutils import abspath, read_file, write_file
|
||||
from gluon.utils import web2py_uuid
|
||||
from gluon.tools import Config
|
||||
from gluon.compileapp import find_exposed_functions
|
||||
from glob import glob
|
||||
import shutil
|
||||
import platform
|
||||
@@ -29,10 +31,18 @@ from gluon.languages import (read_possible_languages, read_dict, write_dict,
|
||||
read_plural_dict, write_plural_dict)
|
||||
|
||||
|
||||
if DEMO_MODE and request.function in ['change_password', 'pack', 'pack_custom','pack_plugin', 'upgrade_web2py', 'uninstall', 'cleanup', 'compile_app', 'remove_compiled_app', 'delete', 'delete_plugin', 'create_file', 'upload_file', 'update_languages', 'reload_routes', 'git_push', 'git_pull']:
|
||||
if DEMO_MODE and request.function in ['change_password', 'pack',
|
||||
'pack_custom','pack_plugin', 'upgrade_web2py', 'uninstall',
|
||||
'cleanup', 'compile_app', 'remove_compiled_app', 'delete',
|
||||
'delete_plugin', 'create_file', 'upload_file', 'update_languages',
|
||||
'reload_routes', 'git_push', 'git_pull', 'install_plugin']:
|
||||
session.flash = T('disabled in demo mode')
|
||||
redirect(URL('site'))
|
||||
|
||||
if is_gae and request.function in ('edit', 'edit_language',
|
||||
'edit_plurals', 'update_languages', 'create_file', 'install_plugin'):
|
||||
session.flash = T('disabled in GAE mode')
|
||||
redirect(URL('site'))
|
||||
|
||||
if not is_manager() and request.function in ['change_password', 'upgrade_web2py']:
|
||||
session.flash = T('disabled in multi user mode')
|
||||
@@ -62,10 +72,12 @@ def log_progress(app, mode='EDIT', filename=None, progress=0):
|
||||
|
||||
|
||||
def safe_open(a, b):
|
||||
if DEMO_MODE and ('w' in b or 'a' in b):
|
||||
if (DEMO_MODE or is_gae) and ('w' in b or 'a' in b):
|
||||
class tmp:
|
||||
def write(self, data):
|
||||
pass
|
||||
def close(self):
|
||||
pass
|
||||
return tmp()
|
||||
return open(a, b)
|
||||
|
||||
@@ -230,7 +242,7 @@ def site():
|
||||
redirect(URL('design', args=appname))
|
||||
else:
|
||||
session.flash = \
|
||||
DIV(T('unable to create application "%s"' % appname),
|
||||
DIV(T('unable to create application "%s"', appname),
|
||||
PRE(error))
|
||||
redirect(URL(r=request))
|
||||
|
||||
@@ -341,7 +353,7 @@ def pack():
|
||||
response.headers['Content-Disposition'] = disposition
|
||||
return safe_read(filename, 'rb')
|
||||
else:
|
||||
session.flash = T('internal error: %s' % e)
|
||||
session.flash = T('internal error: %s', e)
|
||||
redirect(URL('site'))
|
||||
|
||||
def pack_plugin():
|
||||
@@ -375,7 +387,7 @@ def pack_custom():
|
||||
response.headers['Content-Disposition'] = disposition
|
||||
return safe_read(filename, 'rb')
|
||||
else:
|
||||
session.flash = T('internal error: %s' % e)
|
||||
session.flash = T('internal error: %s', e)
|
||||
redirect(URL(args=request.args))
|
||||
def ignore(fs):
|
||||
return [f for f in fs if not (
|
||||
@@ -563,36 +575,30 @@ def edit():
|
||||
# Load json only if it is ajax edited...
|
||||
app = get_app(request.vars.app)
|
||||
app_path = apath(app, r=request)
|
||||
editor_defaults={'theme':'web2py', 'editor': 'default', 'closetag': 'true'}
|
||||
preferences={'theme':'web2py', 'editor': 'default', 'closetag': 'true', 'codefolding': 'false', 'tabwidth':'4', 'indentwithtabs':'false', 'linenumbers':'true', 'highlightline':'true'}
|
||||
config = Config(os.path.join(request.folder, 'settings.cfg'),
|
||||
section='editor', default_values=editor_defaults)
|
||||
preferences = config.read()
|
||||
section='editor', default_values={})
|
||||
preferences.update(config.read())
|
||||
|
||||
if not(request.ajax):
|
||||
if not(request.ajax) and not(is_mobile):
|
||||
# return the scaffolding, the rest will be through ajax requests
|
||||
response.title = T('Editing %s') % app
|
||||
editarea_preferences = {}
|
||||
editarea_preferences['FONT_SIZE'] = '10'
|
||||
editarea_preferences['FULL_SCREEN'] = 'false'
|
||||
editarea_preferences['ALLOW_TOGGLE'] = 'true'
|
||||
editarea_preferences['REPLACE_TAB_BY_SPACES'] = '4'
|
||||
editarea_preferences['DISPLAY'] = 'onload'
|
||||
for key in editarea_preferences:
|
||||
if key in globals():
|
||||
editarea_preferences[key] = globals()[key]
|
||||
return response.render ('default/edit.html', dict(app=request.args[0], editor_settings=preferences, editarea_preferences=editarea_preferences))
|
||||
return response.render ('default/edit.html', dict(app=app, editor_settings=preferences))
|
||||
|
||||
# show settings tab and save prefernces
|
||||
if 'settings' in request.vars:
|
||||
if request.post_vars: #save new preferences
|
||||
if config.save(request.post_vars.items()):
|
||||
post_vars = request.post_vars.items()
|
||||
# Since unchecked checkbox are not serialized, we must set them as false by hand to store the correct preference in the settings
|
||||
post_vars+= [(opt, 'false') for opt in preferences if opt not in request.post_vars ]
|
||||
if config.save(post_vars):
|
||||
response.headers["web2py-component-flash"] = T('Preferences saved correctly')
|
||||
else:
|
||||
response.headers["web2py-component-flash"] = T('Preferences saved on session only')
|
||||
response.headers["web2py-component-command"] = "update_editor('%s', '%s', '%s');jQuery('a[href=#editor_settings] button.close').click();" % (config.read()['theme'], config.read()['editor'], config.read()['closetag'])
|
||||
response.headers["web2py-component-command"] = "update_editor(%s);$('a[href=#editor_settings] button.close').click();" % response.json(config.read())
|
||||
return
|
||||
else:
|
||||
details = {'filename':'settings', 'id':'editor_settings', 'force': False}
|
||||
details = {'realfilename':'settings', 'filename':'settings', 'id':'editor_settings', 'force': False}
|
||||
details['plain_html'] = response.render('default/editor_settings.html', {'editor_settings':preferences})
|
||||
return response.json(details)
|
||||
|
||||
@@ -600,7 +606,7 @@ def edit():
|
||||
# Load json only if it is ajax edited...
|
||||
app = get_app(request.vars.app)
|
||||
filename = '/'.join(request.args)
|
||||
response.title = request.args[-1]
|
||||
realfilename = request.args[-1]
|
||||
if request.vars.app:
|
||||
path = abspath(filename)
|
||||
else:
|
||||
@@ -615,7 +621,7 @@ def edit():
|
||||
elif filename[-4:] == '.css':
|
||||
filetype = 'css'
|
||||
elif filename[-3:] == '.js':
|
||||
filetype = 'js'
|
||||
filetype = 'javascript'
|
||||
else:
|
||||
filetype = 'html'
|
||||
|
||||
@@ -747,7 +753,7 @@ def edit():
|
||||
|
||||
if len(request.args) > 2 and request.args[1] == 'controllers':
|
||||
controller = (request.args[2])[:-3]
|
||||
functions = regex_expose.findall(data)
|
||||
functions = find_exposed_functions(data)
|
||||
else:
|
||||
(controller, functions) = (None, None)
|
||||
|
||||
@@ -755,7 +761,10 @@ def edit():
|
||||
return response.json({'file_hash': file_hash, 'saved_on': saved_on, 'functions': functions, 'controller': controller, 'application': request.args[0], 'highlight': highlight})
|
||||
else:
|
||||
file_details = dict(app=request.args[0],
|
||||
lineno=request.vars.lineno or 1,
|
||||
editor_settings=preferences,
|
||||
filename=filename,
|
||||
realfilename=realfilename,
|
||||
filetype=filetype,
|
||||
data=data,
|
||||
edit_controller=edit_controller,
|
||||
@@ -766,11 +775,61 @@ def edit():
|
||||
view_link=view_link,
|
||||
editviewlinks=editviewlinks,
|
||||
id=IS_SLUG()(filename)[0],
|
||||
force= True if (request.vars.restore or request.vars.revert) else False)
|
||||
force= True if (request.vars.restore or
|
||||
request.vars.revert) else False)
|
||||
plain_html = response.render('default/edit_js.html', file_details)
|
||||
file_details['plain_html'] = plain_html
|
||||
return response.json(file_details)
|
||||
if is_mobile:
|
||||
return response.render('default.mobile/edit.html',
|
||||
file_details, editor_settings=preferences)
|
||||
else:
|
||||
return response.json(file_details)
|
||||
|
||||
def todolist():
|
||||
""" Returns all TODO of the requested app
|
||||
"""
|
||||
app = request.vars.app or ''
|
||||
app_path = apath('%(app)s' % {'app':app}, r=request)
|
||||
dirs=['models', 'controllers', 'modules', 'private' ]
|
||||
def listfiles(app, dir, regexp='.*\.py$'):
|
||||
files = sorted( listdir(apath('%(app)s/%(dir)s/' % {'app':app, 'dir':dir}, r=request), regexp))
|
||||
files = [x.replace(os.path.sep, '/') for x in files if not x.endswith('.bak')]
|
||||
return files
|
||||
|
||||
pattern = '#\s*(todo)+\s+(.*)'
|
||||
regex = re.compile(pattern, re.IGNORECASE)
|
||||
|
||||
output = []
|
||||
for d in dirs:
|
||||
for f in listfiles(app, d):
|
||||
matches = []
|
||||
filename= apath(os.path.join(app, d, f), r=request)
|
||||
with open(filename, 'r') as f_s:
|
||||
src = f_s.read()
|
||||
for m in regex.finditer(src):
|
||||
start = m.start()
|
||||
lineno = src.count('\n', 0, start) + 1
|
||||
matches.append({'text':m.group(0), 'lineno':lineno})
|
||||
if len(matches) != 0:
|
||||
output.append({'filename':f,'matches':matches, 'dir':d})
|
||||
|
||||
return {'todo':output, 'app': app}
|
||||
|
||||
def editor_sessions():
|
||||
config = Config(os.path.join(request.folder, 'settings.cfg'),
|
||||
section='editor_sessions', default_values={})
|
||||
preferences = config.read()
|
||||
|
||||
if request.vars.session_name and request.vars.files:
|
||||
session_name = request.vars.session_name
|
||||
files = request.vars.files
|
||||
preferences.update({session_name:','.join(files)})
|
||||
if config.save(preferences.items()):
|
||||
response.headers["web2py-component-flash"] = T('Session saved correctly')
|
||||
else:
|
||||
response.headers["web2py-component-flash"] = T('Session saved on session only')
|
||||
|
||||
return response.render('default/editor_sessions.html', {'editor_sessions':preferences})
|
||||
|
||||
def resolve():
|
||||
"""
|
||||
@@ -1007,7 +1066,7 @@ def design():
|
||||
functions = {}
|
||||
for c in controllers:
|
||||
data = safe_read(apath('%s/controllers/%s' % (app, c), r=request))
|
||||
items = regex_expose.findall(data)
|
||||
items = find_exposed_functions(data)
|
||||
functions[c] = items
|
||||
|
||||
# Get all views
|
||||
@@ -1037,9 +1096,9 @@ def design():
|
||||
privates.sort()
|
||||
|
||||
# Get all static files
|
||||
MAXNFILES = 1000
|
||||
statics = listdir(apath('%s/static/' % app, r=request), '[^\.#].*')
|
||||
statics = [x.replace('\\', '/') for x in statics[:MAXNFILES]]
|
||||
statics = listdir(apath('%s/static/' % app, r=request), '[^\.#].*',
|
||||
maxnum = MAXNFILES)
|
||||
statics = [x.replace(os.path.sep, '/') for x in statics]
|
||||
statics.sort()
|
||||
|
||||
# Get all languages
|
||||
@@ -1051,11 +1110,12 @@ def design():
|
||||
|
||||
#Get crontab
|
||||
cronfolder = apath('%s/cron' % app, r=request)
|
||||
if not os.path.exists(cronfolder):
|
||||
os.mkdir(cronfolder)
|
||||
crontab = apath('%s/cron/crontab' % app, r=request)
|
||||
if not os.path.exists(crontab):
|
||||
safe_write(crontab, '#crontab')
|
||||
if not is_gae:
|
||||
if not os.path.exists(cronfolder):
|
||||
os.mkdir(cronfolder)
|
||||
if not os.path.exists(crontab):
|
||||
safe_write(crontab, '#crontab')
|
||||
|
||||
plugins = []
|
||||
|
||||
@@ -1144,7 +1204,7 @@ def plugin():
|
||||
functions = {}
|
||||
for c in controllers:
|
||||
data = safe_read(apath('%s/controllers/%s' % (app, c), r=request))
|
||||
items = regex_expose.findall(data)
|
||||
items = find_exposed_functions(data)
|
||||
functions[c] = items
|
||||
|
||||
# Get all views
|
||||
@@ -1173,8 +1233,9 @@ def plugin():
|
||||
privates.sort()
|
||||
|
||||
# Get all static files
|
||||
statics = listdir(apath('%s/static/' % app, r=request), '[^\.#].*')
|
||||
statics = [x.replace('\\', '/') for x in statics]
|
||||
statics = listdir(apath('%s/static/' % app, r=request), '[^\.#].*',
|
||||
maxnum = MAXNFILES)
|
||||
statics = [x.replace(os.path.sep, '/') for x in statics]
|
||||
statics.sort()
|
||||
|
||||
# Get all languages
|
||||
@@ -1206,7 +1267,6 @@ def plugin():
|
||||
languages=languages,
|
||||
crontab=crontab)
|
||||
|
||||
|
||||
def create_file():
|
||||
""" Create files handler """
|
||||
if request.vars and not request.vars.token == session.token:
|
||||
@@ -1217,6 +1277,8 @@ def create_file():
|
||||
app = get_app(request.vars.app)
|
||||
path = abspath(request.vars.location)
|
||||
else:
|
||||
if request.vars.dir:
|
||||
request.vars.location += request.vars.dir + '/'
|
||||
app = get_app(name=request.vars.location.split('/')[0])
|
||||
path = apath(request.vars.location, r=request)
|
||||
filename = re.sub('[^\w./-]+', '_', request.vars.filename)
|
||||
@@ -1325,7 +1387,8 @@ def create_file():
|
||||
from gluon import *\n""")[1:]
|
||||
|
||||
elif (path[-8:] == '/static/') or (path[-9:] == '/private/'):
|
||||
if request.vars.plugin and not filename.startswith('plugin_%s/' % request.vars.plugin):
|
||||
if (request.vars.plugin and
|
||||
not filename.startswith('plugin_%s/' % request.vars.plugin)):
|
||||
filename = 'plugin_%s/%s' % (request.vars.plugin, filename)
|
||||
text = ''
|
||||
|
||||
@@ -1343,7 +1406,11 @@ def create_file():
|
||||
|
||||
safe_write(full_filename, text)
|
||||
log_progress(app, 'CREATE', filename)
|
||||
session.flash = T('file "%(filename)s" created',
|
||||
if request.vars.dir:
|
||||
result = T('file "%(filename)s" created',
|
||||
dict(filename=full_filename[len(path):]))
|
||||
else:
|
||||
session.flash = T('file "%(filename)s" created',
|
||||
dict(filename=full_filename[len(path):]))
|
||||
vars = {}
|
||||
if request.vars.id:
|
||||
@@ -1352,13 +1419,51 @@ def create_file():
|
||||
vars['app'] = request.vars.app
|
||||
redirect(URL('edit',
|
||||
args=[os.path.join(request.vars.location, filename)], vars=vars))
|
||||
|
||||
except Exception, e:
|
||||
if not isinstance(e, HTTP):
|
||||
session.flash = T('cannot create file')
|
||||
|
||||
redirect(request.vars.sender + anchor)
|
||||
if request.vars.dir:
|
||||
response.flash = result
|
||||
response.headers['web2py-component-content'] = 'append'
|
||||
response.headers['web2py-component-command'] = """
|
||||
$.web2py.invalidate('#files_menu');
|
||||
load_file('%s');
|
||||
$.web2py.enableElement($('#form form').find($.web2py.formInputClickSelector));
|
||||
""" % URL('edit', args=[app,request.vars.dir,filename])
|
||||
return ''
|
||||
else:
|
||||
redirect(request.vars.sender + anchor)
|
||||
|
||||
|
||||
def listfiles(app, dir, regexp='.*\.py$'):
|
||||
files = sorted(
|
||||
listdir(apath('%(app)s/%(dir)s/' % {'app':app, 'dir':dir}, r=request), regexp))
|
||||
files = [x.replace('\\', '/') for x in files if not x.endswith('.bak')]
|
||||
return files
|
||||
|
||||
def editfile(path,file,vars={}, app = None):
|
||||
args=(path,file) if 'app' in vars else (app,path,file)
|
||||
url = URL('edit', args=args, vars=vars)
|
||||
return A(file, _class='editor_filelink', _href=url, _style='word-wrap: nowrap;')
|
||||
|
||||
def files_menu():
|
||||
app = request.vars.app or 'welcome'
|
||||
dirs=[{'name':'models', 'reg':'.*\.py$'},
|
||||
{'name':'controllers', 'reg':'.*\.py$'},
|
||||
{'name':'views', 'reg':'[\w/\-]+(\.\w+)+$'},
|
||||
{'name':'modules', 'reg':'.*\.py$'},
|
||||
{'name':'static', 'reg': '[^\.#].*'}]
|
||||
result_files = []
|
||||
for dir in dirs:
|
||||
result_files.append(TAG[''](LI(dir['name'], _class="nav-header component", _onclick="collapse('" + dir['name'] + "_files');"),
|
||||
LI(UL(*[LI(editfile(dir['name'], f, dict(id=dir['name'] + f.replace('.','__')), app), _style="overflow:hidden", _id=dir['name']+"__"+f.replace('.','__'))
|
||||
for f in listfiles(app, dir['name'], regexp=dir['reg'])],
|
||||
_class="nav nav-list small-font"),
|
||||
_id=dir['name'] + '_files', _style="display: none;")))
|
||||
return dict(result_files = result_files)
|
||||
|
||||
def upload_file():
|
||||
""" File uploading handler """
|
||||
if request.vars and not request.vars.token == session.token:
|
||||
@@ -1418,8 +1523,11 @@ def errors():
|
||||
import hashlib
|
||||
|
||||
app = get_app()
|
||||
|
||||
method = request.args(1) or 'new'
|
||||
if is_gae:
|
||||
method = 'dbold' if ('old' in
|
||||
(request.args(1) or '')) else 'dbnew'
|
||||
else:
|
||||
method = request.args(1) or 'new'
|
||||
db_ready = {}
|
||||
db_ready['status'] = get_ticket_storage(app)
|
||||
db_ready['errmessage'] = T(
|
||||
@@ -1486,32 +1594,30 @@ def errors():
|
||||
for fn in tk_db(tk_table.id > 0).select():
|
||||
try:
|
||||
error = pickle.loads(fn.ticket_data)
|
||||
except AttributeError:
|
||||
hash = hashlib.md5(error['traceback']).hexdigest()
|
||||
|
||||
if hash in delete_hashes:
|
||||
tk_db(tk_table.id == fn.id).delete()
|
||||
tk_db.commit()
|
||||
else:
|
||||
try:
|
||||
hash2error[hash]['count'] += 1
|
||||
except KeyError:
|
||||
error_lines = error['traceback'].split("\n")
|
||||
last_line = error_lines[-2]
|
||||
error_causer = os.path.split(error['layer'])[1]
|
||||
hash2error[hash] = dict(count=1,
|
||||
pickel=error, causer=error_causer,
|
||||
last_line=last_line, hash=hash,
|
||||
ticket=fn.ticket_id)
|
||||
except AttributeError, e:
|
||||
tk_db(tk_table.id == fn.id).delete()
|
||||
tk_db.commit()
|
||||
|
||||
hash = hashlib.md5(error['traceback']).hexdigest()
|
||||
|
||||
if hash in delete_hashes:
|
||||
tk_db(tk_table.id == fn.id).delete()
|
||||
tk_db.commit()
|
||||
else:
|
||||
try:
|
||||
hash2error['hash']['count'] += 1
|
||||
except KeyError:
|
||||
error_lines = error['traceback'].split("\n")
|
||||
last_line = error_lines[-2]
|
||||
error_causer = os.path.split(error['layer'])[1]
|
||||
hash2error[hash] = dict(count=1, pickel=error,
|
||||
causer=error_causer,
|
||||
last_line=last_line,
|
||||
hash=hash, ticket=fn.ticket_id)
|
||||
|
||||
decorated = [(x['count'], x) for x in hash2error.values()]
|
||||
|
||||
decorated.sort(key=operator.itemgetter(0), reverse=True)
|
||||
|
||||
return dict(errors=[x[1] for x in decorated], app=app, method=method)
|
||||
return dict(errors=[x[1] for x in decorated], app=app,
|
||||
method=method, db_ready=db_ready)
|
||||
|
||||
elif method == 'dbold':
|
||||
tk_db, tk_table = get_ticket_storage(app)
|
||||
@@ -1519,16 +1625,18 @@ def errors():
|
||||
if item[:7] == 'delete_':
|
||||
tk_db(tk_table.ticket_id == item[7:]).delete()
|
||||
tk_db.commit()
|
||||
tickets_ = tk_db(tk_table.id > 0).select(tk_table.ticket_id, tk_table.created_datetime, orderby=~tk_table.created_datetime)
|
||||
tickets_ = tk_db(tk_table.id > 0).select(tk_table.ticket_id,
|
||||
tk_table.created_datetime,
|
||||
orderby=~tk_table.created_datetime)
|
||||
tickets = [row.ticket_id for row in tickets_]
|
||||
times = dict(
|
||||
[(row.ticket_id, row.created_datetime) for row in tickets_])
|
||||
|
||||
return dict(app=app, tickets=tickets, method=method, times=times)
|
||||
times = dict([(row.ticket_id, row.created_datetime) for
|
||||
row in tickets_])
|
||||
return dict(app=app, tickets=tickets, method=method,
|
||||
times=times, db_ready=db_ready)
|
||||
|
||||
else:
|
||||
for item in request.vars:
|
||||
# delete_all} rows doesn't contain any ticket
|
||||
# delete_all rows doesn't contain any ticket
|
||||
# Remove anything else as requested
|
||||
if item[:7] == 'delete_' and (not item == "delete_all}"):
|
||||
os.unlink(apath('%s/errors/%s' % (app, item[7:]), r=request))
|
||||
@@ -1548,6 +1656,9 @@ def get_ticket_storage(app):
|
||||
if os.path.exists(ticket_file):
|
||||
db_string = open(ticket_file).read()
|
||||
db_string = db_string.strip().replace('\r', '').replace('\n', '')
|
||||
elif is_gae:
|
||||
# use Datastore as fallback if there is no ticket_file
|
||||
db_string = "google:datastore"
|
||||
else:
|
||||
return False
|
||||
tickets_table = 'web2py_ticket'
|
||||
@@ -1791,3 +1902,42 @@ def git_push():
|
||||
session.flash = T("Push failed, there are unmerged entries in the cache. Resolve merge issues manually and try again.")
|
||||
redirect(URL('site'))
|
||||
return dict(app=app, form=form)
|
||||
|
||||
def plugins():
|
||||
app = request.args(0)
|
||||
from serializers import loads_json
|
||||
if not session.plugins:
|
||||
try:
|
||||
rawlist = urllib.urlopen("http://www.web2pyslices.com/" +
|
||||
"public/api.json/action/list/content/Package?package" +
|
||||
"_type=plugin&search_index=false").read()
|
||||
session.plugins = loads_json(rawlist)
|
||||
except:
|
||||
response.flash = T('Unable to download the list of plugins')
|
||||
session.plugins = []
|
||||
return dict(plugins=session.plugins["results"], app=request.args(0))
|
||||
|
||||
def install_plugin():
|
||||
app = request.args(0)
|
||||
source = request.vars.source
|
||||
plugin = request.vars.plugin
|
||||
if not (source and app):
|
||||
raise HTTP(500, T("Invalid request"))
|
||||
form = SQLFORM.factory()
|
||||
result = None
|
||||
if form.process().accepted:
|
||||
# get w2p plugin
|
||||
if "web2py.plugin." in source:
|
||||
filename = "web2py.plugin.%s.w2p" % \
|
||||
source.split("web2py.plugin.")[-1].split(".w2p")[0]
|
||||
else:
|
||||
filename = "web2py.plugin.%s.w2p" % cleanpath(plugin)
|
||||
if plugin_install(app, urllib.urlopen(source),
|
||||
request, filename):
|
||||
session.flash = T('New plugin installed: %s', filename)
|
||||
else:
|
||||
session.flash = \
|
||||
T('unable to install plugin "%s"', filename)
|
||||
redirect(URL(f="plugins", args=[app,]))
|
||||
return dict(form=form, app=app, plugin=plugin, source=source)
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ import cStringIO
|
||||
import gluon.contrib.shell
|
||||
import code
|
||||
import thread
|
||||
import cgi
|
||||
from gluon.shell import env
|
||||
|
||||
if DEMO_MODE or MULTI_USER_MODE:
|
||||
@@ -40,7 +41,7 @@ def callback():
|
||||
k = len(session['commands:' + app]) - 1
|
||||
#output = PRE(output)
|
||||
#return TABLE(TR('In[%i]:'%k,PRE(command)),TR('Out[%i]:'%k,output))
|
||||
return 'In [%i] : %s%s\n' % (k + 1, command, output)
|
||||
return cgi.escape('In [%i] : %s%s\n' % (k + 1, command, output))
|
||||
|
||||
|
||||
def reset():
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# coding: utf8
|
||||
# -*- coding: utf-8 -*-
|
||||
{
|
||||
'!langcode!': 'es',
|
||||
'!langname!': 'Español',
|
||||
@@ -9,8 +9,10 @@
|
||||
'%Y-%m-%d %H:%M:%S': '%Y-%m-%d %H:%M:%S',
|
||||
'(requires internet access, experimental)': '(requiere acceso a internet, experimental)',
|
||||
'(something like "it-it")': '(algo como "it-it")',
|
||||
'(version %s)': '(version %s)',
|
||||
'@markmin\x01(file **gluon/contrib/plural_rules/%s.py** is not found)': '(file **gluon/contrib/plural_rules/%s.py** is not found)',
|
||||
'@markmin\x01An error occured, please [[reload %s]] the page': 'An error occured, please [[reload %s]] the page',
|
||||
'@markmin\x01Number of entries: **%s**': 'Number of entries: **%s**',
|
||||
'@markmin\x01Searching: **%s** %%{file}': 'Searching: **%s** files',
|
||||
'A new version of web2py is available': 'Hay una nueva versión de web2py disponible',
|
||||
'A new version of web2py is available: %s': 'Hay una nueva versión de web2py disponible: %s',
|
||||
@@ -29,11 +31,13 @@
|
||||
'An error occured, please %s the page': 'Ha ocurrido un error, por favor %s la página',
|
||||
'and rename it (required):': 'y renombrela (requerido):',
|
||||
'and rename it:': ' y renombrelo:',
|
||||
'App does not exist or you are not authorized': 'App does not exist or you are not authorized',
|
||||
'appadmin': 'appadmin',
|
||||
'appadmin is disabled because insecure channel': 'admin deshabilitado, el canal no es seguro',
|
||||
'application "%s" uninstalled': 'aplicación "%s" desinstalada',
|
||||
'application %(appname)s installed with md5sum: %(digest)s': 'application %(appname)s installed with md5sum: %(digest)s',
|
||||
'application compiled': 'aplicación compilada',
|
||||
'Application exists already': 'Application exists already',
|
||||
'application is compiled and cannot be designed': 'la aplicación está compilada y no puede ser modificada',
|
||||
'Application name:': 'Nombre de la aplicación:',
|
||||
'are not used': 'are not used',
|
||||
@@ -44,6 +48,7 @@
|
||||
'Are you sure you want to uninstall application "%s"': '¿Está seguro que desea desinstalar la aplicación "%s"',
|
||||
'Are you sure you want to uninstall application "%s"?': '¿Está seguro que desea desinstalar la aplicación "%s"?',
|
||||
'Are you sure you want to upgrade web2py now?': '¿Está seguro que desea actualizar web2py ahora?',
|
||||
'Are you sure?': 'Are you sure?',
|
||||
'arguments': 'argumentos',
|
||||
'at char %s': 'en el caracter %s',
|
||||
'at line %s': 'en la línea %s',
|
||||
@@ -53,13 +58,17 @@
|
||||
'Autocomplete': 'Autocomplete',
|
||||
'Autocomplete Python Code': 'Autocompletar código Python',
|
||||
'Available databases and tables': 'Bases de datos y tablas disponibles',
|
||||
'Available Databases and Tables': 'Available Databases and Tables',
|
||||
'back': 'atrás',
|
||||
'Back to the plugins list': 'Back to the plugins list',
|
||||
'breakpoint': 'breakpoint',
|
||||
'breakpoints': 'breakpoints',
|
||||
'browse': 'buscar',
|
||||
'Cache': 'Cache',
|
||||
'cache': 'cache',
|
||||
'cache, errors and sessions cleaned': 'cache, errores y sesiones eliminados',
|
||||
'can be a git repo': 'puede ser un repositorio git',
|
||||
'Cancel': 'Cancel',
|
||||
'Cannot be empty': 'No puede estar vacío',
|
||||
'Cannot compile: there are errors in your app. Debug it, correct errors and try again.': 'No se puede compilar: hay errores en su aplicación. Depure, corrija errores y vuelva a intentarlo.',
|
||||
'Cannot compile: there are errors in your app:': 'No se puede compilar: hay errores en su aplicación:',
|
||||
@@ -73,6 +82,9 @@
|
||||
'Check to delete': 'Marque para eliminar',
|
||||
'Checking for upgrades...': 'Buscando actulizaciones...',
|
||||
'Clean': 'limpiar',
|
||||
'Clear CACHE?': 'Clear CACHE?',
|
||||
'Clear DISK': 'Clear DISK',
|
||||
'Clear RAM': 'Clear RAM',
|
||||
'click here for online examples': 'haga clic aquí para ver ejemplos en línea',
|
||||
'click here for the administrative interface': 'haga clic aquí para usar la interfaz administrativa',
|
||||
'Click row to expand traceback': 'Click row to expand traceback',
|
||||
@@ -107,6 +119,7 @@
|
||||
'database': 'base de datos',
|
||||
'database %s select': 'selección en base de datos %s',
|
||||
'database administration': 'administración base de datos',
|
||||
'Database Administration (appadmin)': 'Database Administration (appadmin)',
|
||||
'Date and Time': 'Fecha y Hora',
|
||||
'db': 'db',
|
||||
'Debug': 'Debug',
|
||||
@@ -117,6 +130,7 @@
|
||||
'delete plugin': 'eliminar plugin',
|
||||
'Delete this file (you will be asked to confirm deletion)': 'Elimine este fichero (se le pedirá confirmación)',
|
||||
'Delete:': 'Elimine:',
|
||||
'Demo': 'Demo',
|
||||
'Deploy': 'Deploy',
|
||||
'Deploy on Google App Engine': 'Instale en Google App Engine',
|
||||
'Deploy to OpenShift': 'Instale en OpenShift',
|
||||
@@ -128,7 +142,10 @@
|
||||
'details': 'detalles',
|
||||
'direction: ltr': 'direction: ltr',
|
||||
'Disable': 'Deshabilitar',
|
||||
'DISK': 'DISK',
|
||||
'docs': 'docs',
|
||||
'Docs': 'Docs',
|
||||
'Done!': 'Done!',
|
||||
'done!': 'listo!',
|
||||
'Download': 'Descargar',
|
||||
'download files via http:': 'descargar archivos via http:',
|
||||
@@ -151,12 +168,14 @@
|
||||
'Editing myemail': 'Editing myemail',
|
||||
'Editing rbare': 'Editing rbare',
|
||||
'Editing ul': 'Editing ul',
|
||||
'Enable': 'Enable',
|
||||
'Enterprise Web Framework': 'Armazón Empresarial para Internet',
|
||||
'Error': 'Error',
|
||||
'Error logs for "%(app)s"': 'Bitácora de errores en "%(app)s"',
|
||||
'Error snapshot': 'Error snapshot',
|
||||
'Error ticket': 'Error ticket',
|
||||
'Errors': 'errores',
|
||||
'Errors in form, please check it out.': 'Errors in form, please check it out.',
|
||||
'Exception instance attributes': 'Atributos de la instancia de Excepción',
|
||||
'Exit Fullscreen': 'Exit Fullscreen',
|
||||
'Expand Abbreviation': 'Expand Abbreviation',
|
||||
@@ -183,30 +202,38 @@
|
||||
'First name': 'Nombre',
|
||||
'Frames': 'Frames',
|
||||
'Functions with no doctests will result in [passed] tests.': 'Funciones sin doctests equivalen a pruebas [aceptadas].',
|
||||
'Git Pull': 'Git Pull',
|
||||
'Git Push': 'Git Push',
|
||||
'Globals##debug': 'Globals',
|
||||
'graph model': 'graph model',
|
||||
'Group ID': 'ID de Grupo',
|
||||
'Hello World': 'Hola Mundo',
|
||||
'Help': 'ayuda',
|
||||
'here': 'here',
|
||||
'htmledit': 'htmledit',
|
||||
'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'Si el reporte anterior contiene un número de tiquete este indica un falla en la ejecución del controlador, antes de cualquier intento de ejecutat doctests. Esto generalmente se debe a un error en la indentación o un error por fuera del código de la función.\r\nUn titulo verde indica que todas las pruebas pasaron (si existen). En dicho caso los resultados no se muestran.',
|
||||
'Image': 'Image',
|
||||
'Import/Export': 'Importar/Exportar',
|
||||
'includes': 'incluye',
|
||||
'insert new': 'inserte nuevo',
|
||||
'insert new %s': 'inserte nuevo %s',
|
||||
'inspect attributes': 'inspect attributes',
|
||||
'Install': 'instalar',
|
||||
'Installation of %(plugin)s for %(app)s': 'Installation of %(plugin)s for %(app)s',
|
||||
'Installation of %(plugin)s for %(app)s app': 'Installation of %(plugin)s for %(app)s app',
|
||||
'Installed applications': 'Aplicaciones instaladas',
|
||||
'Interaction at %s line %s': 'Interaction at %s line %s',
|
||||
'Interactive console': 'Interactive console',
|
||||
'internal error': 'error interno',
|
||||
'Internal State': 'Estado Interno',
|
||||
'Invalid action': 'Acción inválida',
|
||||
'Invalid application name': 'Invalid application name',
|
||||
'Invalid email': 'Correo inválido',
|
||||
'invalid password': 'contraseña inválida',
|
||||
'invalid password.': 'invalid password.',
|
||||
'Invalid Query': 'Consulta inválida',
|
||||
'invalid request': 'solicitud inválida',
|
||||
'Invalid request': 'Invalid request',
|
||||
'invalid ticket': 'tiquete inválido',
|
||||
'Key bindings': 'Key bindings',
|
||||
'Key bindings for ZenCoding Plugin': 'Key bindings for ZenCoding Plugin',
|
||||
@@ -218,6 +245,8 @@
|
||||
'Last name': 'Apellido',
|
||||
'Last saved on:': 'Guardado en:',
|
||||
'License for': 'Licencia para',
|
||||
'License:': 'License:',
|
||||
'lists by ticket': 'lists by ticket',
|
||||
'loading...': 'cargando...',
|
||||
'locals': 'locals',
|
||||
'Locals##debug': 'Locals',
|
||||
@@ -228,6 +257,7 @@
|
||||
'Lost Password': 'Contraseña perdida',
|
||||
'manage': 'gestionar',
|
||||
'Manage': 'Gestionar',
|
||||
'Manage Cache': 'Manage Cache',
|
||||
'merge': 'combinar',
|
||||
'Models': 'Modelos',
|
||||
'models': 'modelos',
|
||||
@@ -237,6 +267,11 @@
|
||||
'new application "%s" created': 'nueva aplicación "%s" creada',
|
||||
'New application wizard': 'Asistente para nueva aplicación',
|
||||
'new plugin installed': 'nuevo plugin instalado',
|
||||
'New plugin installed: %s': 'New plugin installed: %s',
|
||||
'New plugin installed: web2py.plugin.attachment.w2p': 'New plugin installed: web2py.plugin.attachment.w2p',
|
||||
'New plugin installed: web2py.plugin.dialog.w2p': 'New plugin installed: web2py.plugin.dialog.w2p',
|
||||
'New plugin installed: web2py.plugin.math2py.w2p': 'New plugin installed: web2py.plugin.math2py.w2p',
|
||||
'New plugin installed: web2py.plugin.timezone.w2p': 'New plugin installed: web2py.plugin.timezone.w2p',
|
||||
'New Record': 'Registro nuevo',
|
||||
'new record inserted': 'nuevo registro insertado',
|
||||
'New simple application': 'Nueva aplicación',
|
||||
@@ -256,6 +291,7 @@
|
||||
'or provide application url:': 'o provea URL de la aplicación:',
|
||||
'Origin': 'Origen',
|
||||
'Original/Translation': 'Original/Traducción',
|
||||
'Overview': 'Overview',
|
||||
'Overwrite installed app': 'sobreescriba la aplicación instalada',
|
||||
'Pack all': 'empaquetar todo',
|
||||
'Pack compiled': 'empaquete compiladas',
|
||||
@@ -266,8 +302,10 @@
|
||||
'password changed': 'contraseña cambiada',
|
||||
'Peeking at file': 'Visualizando archivo',
|
||||
'Please': 'Please',
|
||||
'Plugin': 'Plugin',
|
||||
'plugin "%(plugin)s" deleted': 'plugin "%(plugin)s" eliminado',
|
||||
'Plugin "%s" in application': 'Plugin "%s" en aplicación',
|
||||
'Plugin page': 'Plugin page',
|
||||
'plugins': 'plugins',
|
||||
'Plugins': 'Plugins',
|
||||
'Plural-Forms:': 'Plural-Forms:',
|
||||
@@ -275,7 +313,9 @@
|
||||
'previous 100 rows': '100 filas anteriores',
|
||||
'Private files': 'Archivos privados',
|
||||
'private files': 'archivos privados',
|
||||
'Project Progress': 'Project Progress',
|
||||
'Query:': 'Consulta:',
|
||||
'RAM': 'RAM',
|
||||
'Rapid Search': 'Rapid Search',
|
||||
'record': 'registro',
|
||||
'record does not exist': 'el registro no existe',
|
||||
@@ -290,6 +330,8 @@
|
||||
'Removed Breakpoint on %s at line %s': 'Eliminado punto de ruptura en %s en la línea %s',
|
||||
'Replace': 'Reemplazar',
|
||||
'Replace All': 'Reemplazar todos',
|
||||
'Repository (%s)': 'Repository (%s)',
|
||||
'Repository: %s': 'Repository: %s',
|
||||
'request': 'request',
|
||||
'Resolve Conflict file': 'archivo Resolución de Conflicto',
|
||||
'response': 'response',
|
||||
@@ -309,6 +351,8 @@
|
||||
'Save file: %s': 'Guardar: %s',
|
||||
'Save via Ajax': 'Guardar via Ajax',
|
||||
'Saved file hash:': 'Hash del archivo guardado:',
|
||||
'Screenshot %s': 'Screenshot %s',
|
||||
'Screenshots': 'Screenshots',
|
||||
'selected': 'seleccionado(s)',
|
||||
'session': 'session',
|
||||
'session expired': 'sesión expirada',
|
||||
@@ -316,25 +360,29 @@
|
||||
'shell': 'shell',
|
||||
'Site': 'sitio',
|
||||
'some files could not be removed': 'algunos archivos no pudieron ser removidos',
|
||||
'source : filesystem': 'source : filesystem',
|
||||
'Start searching': 'Iniciar búsqueda',
|
||||
'Start wizard': 'Iniciar asistente',
|
||||
'state': 'estado',
|
||||
'Static': 'Static',
|
||||
'static': 'estáticos',
|
||||
'Static files': 'Archivos estáticos',
|
||||
'Statistics': 'Statistics',
|
||||
'step': 'step',
|
||||
'stop': 'stop',
|
||||
'submit': 'enviar',
|
||||
'Submit': 'Submit',
|
||||
'Success!': 'Success!',
|
||||
'successful': 'exitoso',
|
||||
'Sure you want to delete this object?': '¿Está seguro que desea eliminar este objeto?',
|
||||
'switch to : db': 'switch to : db',
|
||||
'table': 'tabla',
|
||||
'Table name': 'Nombre de la tabla',
|
||||
'test': 'probar',
|
||||
'Testing application': 'Probando aplicación',
|
||||
'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': 'La "consulta" es una condición como "db.tabla1.campo1==\'valor\'". Algo como "db.tabla1.campo1==db.tabla2.campo2" resulta en un JOIN SQL.',
|
||||
'the application logic, each URL path is mapped in one exposed function in the controller': 'la lógica de la aplicación, cada ruta URL se mapea en una función expuesta en el controlador',
|
||||
'The application logic, each URL path is mapped in one exposed function in the controller': 'La lógica de la aplicación, cada ruta URL se mapea en una función expuesta en el controlador',
|
||||
'the application logic, each URL path is mapped in one exposed function in the controller': 'la lógica de la aplicación, cada ruta URL se mapea en una función expuesta en el controlador',
|
||||
'the data representation, define database tables and sets': 'la representación de datos, define tablas y conjuntos de base de datos',
|
||||
'The data representation, define database tables and sets': 'La representación de datos, define tablas y conjuntos de base de datos',
|
||||
'The presentations layer, views are also known as templates': 'La capa de presentación, las vistas también son llamadas plantillas',
|
||||
@@ -361,6 +409,7 @@
|
||||
'To emulate a breakpoint programatically, write:': 'To emulate a breakpoint programatically, write:',
|
||||
'to use the debugger!': 'to use the debugger!',
|
||||
'toggle breakpoint': 'alternar punto de ruptura',
|
||||
'Toggle comment': 'Toggle comment',
|
||||
'Toggle Fullscreen': 'Alternar pantalla completa',
|
||||
'Traceback': 'Traceback',
|
||||
'translation strings for the application': 'cadenas de caracteres de traducción para la aplicación',
|
||||
@@ -412,6 +461,8 @@
|
||||
'web2py upgraded; please restart it': 'web2py actualizado; favor reiniciar',
|
||||
'Welcome to web2py': 'Bienvenido a web2py',
|
||||
'YES': 'SI',
|
||||
'Yes': 'Yes',
|
||||
'You are going to install': 'You are going to install',
|
||||
'You need to set up and reach a': 'You need to set up and reach a',
|
||||
'Your application will be blocked until you click an action button (next, step, continue, etc.)': 'Your application will be blocked until you click an action button (next, step, continue, etc.)',
|
||||
'Your can inspect variables using the console below': 'Your can inspect variables using the console below',
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# coding: utf8
|
||||
# -*- coding: utf-8 -*-
|
||||
{
|
||||
'!langcode!': 'it',
|
||||
'!langname!': 'Italiano',
|
||||
@@ -303,6 +303,7 @@
|
||||
'to previous version.': 'torna a versione precedente',
|
||||
'To create a plugin, name a file/folder plugin_[name]': 'Per creare un plugin, chiamare un file o cartella plugin_[nome]',
|
||||
'toggle breakpoint': 'toggle breakpoint',
|
||||
'Toggle comment': 'Toggle comment',
|
||||
'Toggle Fullscreen': 'Toggle Fullscreen',
|
||||
'Traceback': 'Traceback',
|
||||
'translation strings for the application': "stringhe di traduzioni per l'applicazione",
|
||||
|
||||
@@ -185,8 +185,8 @@
|
||||
'Invalid Query': 'Неверный запрос',
|
||||
'invalid request': 'неверный запрос',
|
||||
'invalid ticket': 'неверный тикет',
|
||||
'Key bindings': 'Связываник клавиш',
|
||||
'Key bindings for ZenConding Plugin': 'Связывание клавиш для плагина ZenConding',
|
||||
'Key bindings': 'Комбинации клавиш',
|
||||
'Key bindings for ZenConding Plugin': 'Комбинации клавиш для плагина ZenConding',
|
||||
'language file "%(filename)s" created/updated': 'Языковой файл "%(filename)s" создан/обновлен',
|
||||
'Language files (static strings) updated': 'Языковые файлы (статичные строки) обновлены',
|
||||
'languages': 'языки',
|
||||
@@ -204,7 +204,7 @@
|
||||
'Login to the Administrative Interface': 'Вход в интерфейс администратора',
|
||||
'Logout': 'выход',
|
||||
'Lost Password': 'Забыли пароль',
|
||||
'lost password?': 'Пароль утерен?',
|
||||
'lost password?': 'Пароль утерян?',
|
||||
'Main Menu': 'Главное меню',
|
||||
'Match Pair': 'Найти пару',
|
||||
'Menu Model': 'Модель меню',
|
||||
|
||||
@@ -0,0 +1,426 @@
|
||||
# coding: utf-8
|
||||
{
|
||||
'!langcode!': 'tr',
|
||||
'!langname!': 'Türkçe',
|
||||
'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"güncelleme" ("update") "field1 = \'yenideğer\'" gibi seçeneğe bağlı bir ifadedir. JOIN sonuçlarını silemez veya silemezsiniz.',
|
||||
'%s %%{row} deleted': '%s %%{row} silindi',
|
||||
'%s %%{row} updated': '%s %%{row} güncellendi',
|
||||
'%Y-%m-%d': '%d-%m-%Y',
|
||||
'%Y-%m-%d %H:%M:%S': '%d-%m-%Y %H:%M:%S',
|
||||
'(requires internet access)': '(Internet erişimi gerekir)',
|
||||
'(requires internet access, experimental)': '(internet erişimi gerekir, deneysel)',
|
||||
'(something like "it-it")': '("it-it" şeklinde birşeyler) ',
|
||||
'1: Setting Parameters': '1: Parametrelerin Yapılandırılması',
|
||||
'@markmin\x01An error occured, please [[reload %s]] the page': '@markmin\x01Bir hata oluştu, lütfen sayfayı [[reload %s]]',
|
||||
"@markmin\x01Mercurial Version Control System Interface[[NEWLINE]]for application '%s'": "'%s' uygulaması için[[NEWLINE]]Mercurial Sürüm Kontrol Sistemi Arayüzü",
|
||||
'@markmin\x01Searching: **%s** %%{file}': '@markmin\x01Aranıyor: **%s** %%{file}',
|
||||
'A new version of web2py is available: %s': "web2py'nin yeni sürümü mevcut: %s ",
|
||||
'A new version of web2py is available: Version 1.68.2 (2009-10-21 09:59:29)\n': "web2py'nin yeni sürümü mevcut: Sürüm 1.68.2 (2009-10-21 09:59:29)\r\n",
|
||||
'About': 'Hakkında',
|
||||
'About application': 'Uygulama hakkında',
|
||||
'Add breakpoint': 'Kesme noktası ekle',
|
||||
'additional code for your application': 'uygulamanız için fazladan kod',
|
||||
'Additional code for your application': 'Uygulamanız için fazladan kod',
|
||||
'Admin design page': 'Yönetici tasarım sayfası',
|
||||
'admin disabled because no admin password': 'yönetici parolası olmadığından admin etkinsiz',
|
||||
'admin disabled because not supported on google app engine': 'Google App Motoru tafaından desteklenmediğinden admin etkinsizleştirildi',
|
||||
'admin disabled because unable to access password file': 'parola dosyasına erişielemdiğinden admin etkinsizleştirildi',
|
||||
'Admin is disabled because insecure channel': 'güvenzis kanal olduğundan admin etkinsizleştirildi',
|
||||
'Admin language': 'Admin dilleri',
|
||||
'Admin versioning page': 'Yönetici sürümleme sayfası',
|
||||
'administrative interface': 'yönetsel arayüz',
|
||||
'Administrator Password:': 'Yönetici Parolası:',
|
||||
'and rename it (required):': 've yeniden adlandır (gerekli):',
|
||||
'and rename it:': 'yeniden adlandır:',
|
||||
'appadmin': 'appadmin',
|
||||
'appadmin is disabled because insecure channel': 'güvenzis kanal olduğundan admin etkinsizleştirildi',
|
||||
'Application': 'Uygulama',
|
||||
'application "%s" uninstalled': '"%s" uygulaması kaldırıldı',
|
||||
'application %(appname)s installed with md5sum: %(digest)s': '%(appname)s uygulaması md5sum %(digest)s ile kuruldu',
|
||||
'application compiled': 'uygulama derlendi',
|
||||
'application is compiled and cannot be designed': 'uygulama derlenmiş ve tasarlanamaz',
|
||||
'Application name:': 'Uygulama adı:',
|
||||
'are not used': 'kullanılamıyor',
|
||||
'are not used yet': 'şimdilik kullanılamıyor',
|
||||
'Are you sure you want to delete file "%s"?': '«%s» dosyasını silmek istediğinize emin misiniz?',
|
||||
'Are you sure you want to delete plugin "%s"?': '"%s" eklentisini kaldırmak istediğinizden emin misiniz?',
|
||||
'Are you sure you want to delete this object?': 'Bu nesneyi silmek istediğinizden emin misiniz?',
|
||||
'Are you sure you want to uninstall application "%s"?': '«%s» uygulamasını kaldırmak istediğinizden emin misiniz?',
|
||||
'Are you sure you want to upgrade web2py now?': "web2py'yi güncellemek istediğinizden emin misiniz?",
|
||||
'arguments': 'argümanlar',
|
||||
'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.': 'UYARI: Giriş günceli bağlantı (HTTPS) gerektirmekte veya yerel makinada çalışılmalıdır.',
|
||||
'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': 'UYARI: ÇOKLU TEST GÜVENLİ DEĞİL. BİRDEN ÇOK TESTİ AYNI ANDA YAPMAYIN.',
|
||||
'ATTENTION: you cannot edit the running application!': 'UYARI: çalışan uygulamayı düzenleyemezsiniz!',
|
||||
'Autocomplete Python Code': 'Python Kodlarını Otomatik Tamamla',
|
||||
'Available databases and tables': 'Kullanılabilir veritabanları ve tablolar',
|
||||
'back': 'geri',
|
||||
'Back to wizard': 'Sihirbaza geri dön',
|
||||
'Basics': 'Temeller',
|
||||
'Begin': 'Başla',
|
||||
'breakpoint': 'kesme noktası',
|
||||
'Breakpoints': 'Kesme Noktaları',
|
||||
'breakpoints': 'kesme noktaları',
|
||||
'cache': 'zula',
|
||||
'cache, errors and sessions cleaned': 'zula, hatalar ve oturumlar temizlendi',
|
||||
'can be a git repo': 'git deposu olabilir',
|
||||
'Cancel': 'Vazgeç',
|
||||
'Cannot be empty': 'Boş olamaz',
|
||||
'Cannot compile: there are errors in your app. Debug it, correct errors and try again.': 'Derlenemiyor: uygulamanızda hata(lar) var. Hataları düzeltin ve tekrar deneyin.',
|
||||
'Cannot compile: there are errors in your app:': 'Derlenemiyor: uygulamanızda hata(lar) var:',
|
||||
'cannot create file': 'dosya oluşturulamıyor',
|
||||
'cannot upload file "%(filename)s"': '"%(filename)s" dosyalarını yükleyemiyor',
|
||||
'Change admin password': 'admin parolasını değiştir',
|
||||
'change editor settings': 'düzenleyici ayarlarını değiştir',
|
||||
'check all': 'tümünü kontrol et',
|
||||
'Check for upgrades': 'Güncellemeleri kontrol et',
|
||||
'Check to delete': 'Silmek için kontrok et',
|
||||
'Checking for upgrades...': 'Güncellemeler denetleniyor ... ',
|
||||
'Clean': 'Temizle',
|
||||
'Click row to expand traceback': 'Takibi genişletmek için satır üzerine tıkla',
|
||||
'click to check for upgrades': 'güncellemeleri denetlemek için tıklayın',
|
||||
'code': 'kod',
|
||||
'collapse/expand all': 'sıkıştır/tümünü aç',
|
||||
'Comment:': 'Yorum:',
|
||||
'Commit': 'Öneri',
|
||||
'Commit form': 'Tarafından öneri',
|
||||
'Compile': 'Derle',
|
||||
'compiled application removed': 'derlenmiş uygulama kaldırıldı',
|
||||
'Condition': 'Durum',
|
||||
'Controllers': 'Denetçiler',
|
||||
'controllers': 'denetçiler',
|
||||
'Count': 'Sayı',
|
||||
'Create': 'Oluştur',
|
||||
'create file with filename:': 'dosya adı ile dosya oluştur:',
|
||||
'create new application:': 'yeni uygulama oluştur:',
|
||||
'Create new simple application': 'Yeni basit uygulama oluştur',
|
||||
'Create/Upload': 'Oluştur/Yükle',
|
||||
'created by': 'yazan:',
|
||||
'crontab': 'krontab',
|
||||
'Current request': 'Şimdiki istek',
|
||||
'Current response': 'Şimdiki yanıt',
|
||||
'Current session': 'Şimdiki oturum',
|
||||
'currently running': 'şimdiki çalışan',
|
||||
'currently saved or': 'şimdiki kaydedilen veya',
|
||||
'data uploaded': 'veri yüklendi',
|
||||
'database': 'veritabı',
|
||||
'database %s select': '%s veritabanı seçildi',
|
||||
'Database administration': 'Veritabanı yönetimi',
|
||||
'database administration': 'veritabı yönetimi',
|
||||
'Date and Time': 'Tarih ve Zaman',
|
||||
'db': 'db',
|
||||
'Debug': 'Hata Ayıkla',
|
||||
'defines tables': 'tablolar tanımlı',
|
||||
'Delete': 'Sil',
|
||||
'delete': 'sil',
|
||||
'delete all checked': 'tüm kontrol edilenleri sil',
|
||||
'delete plugin': ' eklentiyi sil',
|
||||
'Delete this file (you will be asked to confirm deletion)': 'Bu dosyayı sil (silmek için onay istenecek)',
|
||||
'Delete:': 'Sil:',
|
||||
'deleted after first hit': 'ilk vuruşta silinir',
|
||||
'Deploy': 'Yayımla',
|
||||
'Deploy on Google App Engine': 'Google App Motorunda Yayınla',
|
||||
'Deploy to OpenShift': "OpenShift'e Yayınla ",
|
||||
'Deployment form': 'Yayınlama formu',
|
||||
'design': 'tadarla',
|
||||
'Detailed traceback description': 'Ayrıntılı nedenin bulma tanımı',
|
||||
'direction: ltr': 'yön: ltr',
|
||||
'Disable': 'Devre Dışı',
|
||||
'docs': 'dokümanlar',
|
||||
'done!': 'bitti!',
|
||||
'Download .w2p': '.w2p İndir',
|
||||
'download layouts': 'düzenleri indir',
|
||||
'download plugins': 'eklentileri indir',
|
||||
'EDIT': 'DÜZENLE',
|
||||
'Edit': 'Düzenle',
|
||||
'edit all': 'tümünü düzenle',
|
||||
'Edit application': 'Uygulamayı düzenle',
|
||||
'edit controller': 'denetçiyi düzenle',
|
||||
'edit controller:': 'denetçiyi düzenle:',
|
||||
'Edit current record': 'Şimdiki kaydı düzenle',
|
||||
'edit views:': 'görünümleri düzenle:',
|
||||
'Editing %s': '%s Düzenleniyor',
|
||||
'Editing file': 'Dosya düzenleniyor',
|
||||
'Editing file "%s"': '"%s" dosyası düzenleniyor ',
|
||||
'Editing Language file': 'Dil dosyası düzenleniyor',
|
||||
'Enable': 'Etkinleştir',
|
||||
'enter a valid email address': 'geçerli e-posta adresi girin',
|
||||
'enter a value': 'bir değer girin',
|
||||
'enter only letters, numbers, and underscore': 'sadece harf, sayı ve alt çizgi giriniz',
|
||||
'Enterprise Web Framework': 'Enterprise Web Çatısı',
|
||||
'Error': 'Hata',
|
||||
'Error logs for "%(app)s"': '"%(app)s" uygulaması için hata kayıtları',
|
||||
'Error snapshot': 'Hata resmi',
|
||||
'Error ticket': 'Hata bileti',
|
||||
'Errors': 'Hatalar',
|
||||
'Exception instance attributes': 'Hata durumu özellikleri',
|
||||
'Exit Fullscreen': 'Tam Ekrandan Çık',
|
||||
'Expand Abbreviation': 'Kısıtlamayı Aç',
|
||||
'export as csv file': 'CSV olarak dışa ver',
|
||||
'exposes': 'sergileniyor',
|
||||
'exposes:': 'sergile:',
|
||||
'extends': 'genişlet',
|
||||
'failed to reload module': 'modül yüklenemedi',
|
||||
'failed to reload module because:': 'modü yüklenemedi çünkü:',
|
||||
'File': 'Dosya',
|
||||
'file "%(filename)s" created': '"%(filename)s" dosyaları oluşturuldu',
|
||||
'file "%(filename)s" deleted': '"%(filename)s" dosyaları silindi',
|
||||
'file "%(filename)s" uploaded': '"%(filename)s" dosyaları yüklendi',
|
||||
'file "%s" of %s restored': '"%s" dosyasının %s kısmı geri alındı',
|
||||
'file changed on disk': 'dosya disk üzerinde değişti',
|
||||
'file does not exist': 'dosya bulunamıyor',
|
||||
'file not found': 'dosya bulanamadı',
|
||||
'file saved on %(time)s': 'dosyası %(time)s zamanında kaydedildi',
|
||||
'file saved on %s': 'dosyası kaydedildi: %s',
|
||||
'Filename': 'Dosya adı',
|
||||
'filter': 'filtre',
|
||||
'Find Next': 'Sonrakini Bul',
|
||||
'Find Previous': 'Öncekini Bul',
|
||||
'Frames': 'Çerçeveler',
|
||||
'Functions with no doctests will result in [passed] tests.': '[passed] testlerdeki işlevlerde doctest yok',
|
||||
'GAE Email': 'GAE E-postası',
|
||||
'GAE Password': 'GAE Parolası',
|
||||
'Generate': 'Oluştur',
|
||||
'Git Pull': 'Git Çek',
|
||||
'Git Push': 'Git İtele',
|
||||
'Globals##debug': 'Geneller',
|
||||
'go!': 'git!',
|
||||
'Google App Engine Deployment Interface': 'Google App Motoru Yayınlama Arayüzü',
|
||||
'Google Application Id': 'Google Uygulama Id',
|
||||
'Goto': 'Git',
|
||||
'graph model': 'grafik modeli',
|
||||
'Help': 'Yardım',
|
||||
'Hide/Show Translated strings': 'Çevrilmiş cümleleri Gizle/Görüntüle',
|
||||
'Hits': 'Vuruşlar',
|
||||
'Home': 'Anasayfa',
|
||||
'honored only if the expression evaluates to true': 'sadece deyim doğru sonucunu verirse',
|
||||
'htmledit': 'html dğzenleyici',
|
||||
'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'Doküman testi yapılmadan önce, eğer yukarıdaki rapor bir bilet numarası içeriyorsa bu denetleyici çalıştırılırken bir hata oluşturğunu gösterir. Bu genellikle girinti/çıkıntı (indentation) hatası veya işlev dışındaki bir hatadan kaynaklanır.\nYeşil başlık geçilen tüm testleri (eğer tanımlanmışsa) gösterir. Bu durumda test sonuçları görüntülenmez.',
|
||||
'Import/Export': 'İçe/Dışa Aktarıcı',
|
||||
'includes': 'içerir',
|
||||
'index': 'indeks',
|
||||
'insert new': 'yeni ekle',
|
||||
'insert new %s': '%s yeni ekle',
|
||||
'inspect attributes': 'özellikleri denetleyin',
|
||||
'Install': 'Kurucu',
|
||||
'Installed applications': 'Kurulu uygulamalar',
|
||||
'internal error': 'dahili hata',
|
||||
'Internal State': 'Dahili Durum',
|
||||
'Invalid action': 'Geçersiz eylem',
|
||||
'invalid expression': 'geçersiz ifade',
|
||||
'invalid password': 'Parola geçersiz',
|
||||
'invalid password.': 'geçersiz parola.',
|
||||
'Invalid Query': 'Geçersiz Sorgu',
|
||||
'invalid request': 'geçersiz istek',
|
||||
'invalid ticket': 'geçersiz bilet',
|
||||
'Key bindings': 'Anahtarlar',
|
||||
'Key bindings for ZenCoding Plugin': 'ZenCoding Eklentisi için anahtarlar',
|
||||
'language file "%(filename)s" created/updated': '"%(filename)s" dil dosyası/dosyaları güncellendi',
|
||||
'Language files (static strings) updated': 'Dil dosyası (statik cümleler) güncellendi',
|
||||
'languages': 'diller',
|
||||
'Languages': 'Diller',
|
||||
'Last saved on:': 'Son kaydedilme:',
|
||||
'License for': 'için lisanslanmış',
|
||||
'Line Nr': 'Satır Nr',
|
||||
'Line number': 'Satır numarası',
|
||||
'lists by exception': 'istisnaya göre sırala',
|
||||
'lists by ticket': 'bilete göre sırala',
|
||||
'loading...': 'yükleniyor ...',
|
||||
'locals': 'yereller',
|
||||
'Locals##debug': 'Yereller',
|
||||
'Login': 'Giriş',
|
||||
'login': 'giriş',
|
||||
'Login to the Administrative Interface': 'Yönetsel Arayüze Giriş\t',
|
||||
'Logout': 'Çıkış',
|
||||
'Manage': 'Yönet',
|
||||
'merge': 'birleştir',
|
||||
'Models': 'Modeller',
|
||||
'models': 'modeller',
|
||||
'Modules': 'Modüller',
|
||||
'modules': 'modüller',
|
||||
'new application "%s" created': 'yeni uygulama "%s" oluşturuldu',
|
||||
'New Application Wizard': 'Yeni Uygulama Sihirbazı',
|
||||
'New application wizard': 'Yeni uygulama sihirbazı',
|
||||
'new plugin installed': 'yeni eklenti kuruldu',
|
||||
'New Record': 'Yeni Kayıt',
|
||||
'new record inserted': 'yeni kayıt eklendi',
|
||||
'New simple application': 'Yeni basit uygulama',
|
||||
'next 100 rows': 'sonraki 100 satır',
|
||||
'NO': 'HAYIR',
|
||||
'No databases in this application': 'Bu uygulamada veritabanı yok',
|
||||
'No Interaction yet': 'Henüz etkileşim yok',
|
||||
'no match': 'eşlenen yok',
|
||||
'no package selected': 'hiç paket seçilmemiş',
|
||||
'No ticket_storage.txt found under /private folder': '/private dizininde ticket_storage.txt dosyası bulunamadı',
|
||||
'Note: If you receive an error with github status code of 128, ensure the system and account you are deploying from has a cooresponding ssh key configured in the openshift account.': 'Not: Eğer github hata kodu 128 durumunu bildiren bir ileti alırsanız, OpenShift hesabınızı ait ssh anahtarının doğru yapılandırıldığından emin olun.',
|
||||
'online designer': 'çevirimiçi tasarlayıcı',
|
||||
'Open new app in new window': 'Yeni pencerede yeni uygualama aç',
|
||||
'OpenShift Deployment Interface': 'OpenShift Yayınlama Arayüzü',
|
||||
'or alternatively': 'veya seçenek olarak',
|
||||
'Or Get from URL:': 'Veya şu URL den alın:',
|
||||
'or import from csv file': 'veya CSV dsoyasından içerin',
|
||||
'or provide app url:': "veya uygulama URL'si verin:",
|
||||
'or provide application url:': "veya uygulama URL'si verin:",
|
||||
'Original/Translation': 'Orjinal / Çeviri',
|
||||
'Overwrite installed app': 'Kurulu uygulama üzerine yaz',
|
||||
'Pack all': 'Tümünü paketle',
|
||||
'Pack compiled': 'Derlenenleri paketle',
|
||||
'Pack custom': 'Tercihli paketle',
|
||||
'pack plugin': 'eklentiyi paketle',
|
||||
'PAM authenticated user, cannot change password here': 'PAM onaylı kullanıcı, parola buradan değiştirilemiyor',
|
||||
'password changed': 'parola değiştirilidi',
|
||||
'Path to appcfg.py': 'appcfg.py dosyasının patikası',
|
||||
'Path to local openshift repo root.': 'Yerel openshift repo kökünün patikası.',
|
||||
'Peeking at file': 'Dosya gözetleniyor',
|
||||
'Please': 'Lütfen',
|
||||
'plugin "%(plugin)s" deleted': '"%(plugin)s" eklentisi silindi',
|
||||
'Plugin "%s" in application': '"%s" uygulamasında eklenti',
|
||||
'plugins': 'eklentiler',
|
||||
'Plugins': 'Eklentiler',
|
||||
'Plural-Forms:': 'Çoğul-Kipler:',
|
||||
'Powered by': 'Yazılım Temeli:',
|
||||
'previous 100 rows': 'önceki 100 satır',
|
||||
'Private files': 'Özel dosyalar',
|
||||
'private files': 'özel dosyalar',
|
||||
'Project Progress': 'Proje İlerlemesi',
|
||||
'pygraphviz library not found': 'pygraphviz kütüphanesi yok',
|
||||
'Query:': 'Sorgu: ',
|
||||
'Rapid Search': 'Hızlı Arama',
|
||||
'record': 'kayıt',
|
||||
'record does not exist': 'kayıt bulunamıyor',
|
||||
'record id': 'kayıt id',
|
||||
'refresh': 'yeniden yükle',
|
||||
'Reload routes': 'Yönelendirmeyi yeniden yükle',
|
||||
'Remove compiled': 'Derlemeyi kaldır',
|
||||
'Removed Breakpoint on %s at line %s': ' %s üzerindeki kesme noktası %s satırında değiştrildi.',
|
||||
'Replace': 'Değiştir',
|
||||
'Replace All': 'Tümünü değiştir',
|
||||
'request': 'istek',
|
||||
'requires python-git, but not installed': 'python-git gerekyior, fakat kurulu değil',
|
||||
'Resolve Conflict file': 'Dosyadaki çakışmayı çöz',
|
||||
'response': 'tepki',
|
||||
'restart': 'yeniden başla',
|
||||
'restore': 'geri al',
|
||||
'revert': 'geri al',
|
||||
'Rows in table': 'Tablosundaki satırlar',
|
||||
'Rows selected': 'Seçilen satırlar',
|
||||
"Run tests in this file (to run all files, you may also use the button labelled 'test')": "Bu dosyadaki testleri çalıştırır (tüm dosyaları çalıştırmak için, 'test' etiketli düğmeyi kullanabilirsiniz)",
|
||||
'Running on %s': '%s üzerinde çalışıyor',
|
||||
'Save': 'Kaydet',
|
||||
'save': 'kaydet',
|
||||
'Save file:': 'Dosyayı kaydet:',
|
||||
'Save file: %s': 'Dosyayı farklı kaydet: %s',
|
||||
'Save via Ajax': 'Ajax üzerinden kaydet',
|
||||
'Saved file hash:': 'Kaydedilen dosyanın parmak izi:',
|
||||
'Select Files to Package': 'Paketlenecek Dosyaları Seç',
|
||||
'selected': 'seçildi',
|
||||
'session': 'oturum',
|
||||
'session expired': 'oturum zamanaşımına uğradı',
|
||||
'Set Breakpoint on %s at line %s: %s': "%s'nin %s satırındaki kesme noktasını: %s yap",
|
||||
'shell': 'kabuk',
|
||||
'Site': 'Site',
|
||||
'skip to generate': 'oluşturmak için atla',
|
||||
'some files could not be removed': 'bazı dosyalar kaldırılamadı',
|
||||
'source : filesystem': 'kaynak : dosyasistemi',
|
||||
'Start a new app': 'Yeni uygualama başla',
|
||||
'Start searching': 'Aramaya başla',
|
||||
'Start wizard': 'Başlatma sihirbazı',
|
||||
'state': 'durum',
|
||||
'static': 'statik',
|
||||
'Static': 'Statik',
|
||||
'Static files': 'Statik dosyalar',
|
||||
'Step': 'Basamak',
|
||||
'Submit': 'Gönder',
|
||||
'submit': 'gönder',
|
||||
'successful': 'başarılı',
|
||||
'Sure you want to delete this object?': 'Bu nesneyi silmek istediğinizden emin misiniz? ',
|
||||
'switch to : db': 'geç : db',
|
||||
'table': 'tablo',
|
||||
'Temporary': 'Geçici',
|
||||
'test': 'test',
|
||||
'Testing application': 'Uygulama test ediliyor',
|
||||
'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': '"sorgulama" "db.table1.field1==\'değer\'" şeklinde bir durumu ifade eder. SQL birleştirmede (JOIN) "db.table1.field1==db.table2.field2" şeklindedir.',
|
||||
'the application logic, each URL path is mapped in one exposed function in the controller': 'uygulama mantığı: her URL denetleyicideki bir işleve eşlenir',
|
||||
'The application logic, each URL path is mapped in one exposed function in the controller': 'Uygulama mantığı: her URL denetleyicideki bir işleve eşlenir',
|
||||
'the data representation, define database tables and sets': 'veri gösterimi, veritabanı tablolarını ve setlerini tanımla',
|
||||
'The data representation, define database tables and sets': 'Veri gösterimi, veritabanı tablolarını ve setlerini tanımla',
|
||||
'The presentations layer, views are also known as templates': 'Sunum katmanı, görünümler şablon olarakda biliniyor.',
|
||||
'the presentations layer, views are also known as templates': 'sunum katmanı, görünümler şablon olarakda biliniyor.',
|
||||
'There are no controllers': 'Denetçiler yok',
|
||||
'There are no models': 'Modeller yok',
|
||||
'There are no modules': 'Modüller yok',
|
||||
'There are no plugins': 'Eklentiler yok',
|
||||
'There are no private files': 'Özel dosyalar yok',
|
||||
'There are no static files': 'Statik dosyalar yok',
|
||||
'There are no translators, only default language is supported': 'Çeviriler, sadeceön tanmlı dil destekleniyor.',
|
||||
'There are no views': 'Görünümler yok',
|
||||
'These files are not served, they are only available from within your app': 'Bu dosyalar servis yapılmıyor, bunlar sadece uygulamanız içerisinden erişilebilir.',
|
||||
'These files are served without processing, your images go here': 'Bu dosyalarda işlem yapılmadan kaydedildi, resimler buraya gidiyor:',
|
||||
'these files are served without processing, your images go here': 'bu dosyalarda işlem yapılmadan kaydedildi, resimler buraya gidiyor:',
|
||||
'This is the %(filename)s template': 'Bu şablonlar %(filename)s: ',
|
||||
"This page can commit your changes to an openshift app repo and push them to your cloud instance. This assumes that you've already created the application instance using the web2py skeleton and have that repo somewhere on a filesystem that this web2py instance can access. This functionality requires GitPython installed and on the python path of the runtime that web2py is operating in.": "Bu sayfa uygulamanızı OpenShif uygulama reposuna koyar. Uygulamanızın web2py iskeleti ile oluşturulduğunuz ve web2py dosya sisteminizdeki ropoya erişilebileceği varsayılmıştır. Bu işlev web2py'nin çalıştığı ortamda GitPython'e ihtiyaç duyar.",
|
||||
'This page can upload your application to the Google App Engine computing cloud. Mind that you must first create indexes locally and this is done by installing the Google appserver and running the app locally with it once, or there will be errors when selecting records. Attention: deployment may take long time, depending on the network speed. Attention: it will overwrite your app.yaml. DO NOT SUBMIT TWICE.': 'Bu sayfa uygulamanızı Google App Motoru bilişim bulutuna yükleyecektir. İndeksleri yerel olarak oluştırmanız gerektiğini aklınızda tutun, Google uygulama sunucusunu yerel olarak kurup çalıştırın, aksi halde bazı kayıtlarda hatalar olacaktır. Uyarı: yayınlama ağ hızınıza bağlı olarak uzun zaman alabilir. Uyarı: bu sizin app.yaml dosyasını yeniden yazar. LÜTFEN BİRDEN FAZLA GÖNDERMEYİN.',
|
||||
'this page to see if a breakpoint was hit and debug interaction is required.': 'bu sayfayı, kesme noktasına geldiğini görmek için ve hata ayıklama etkileşmesi gerekiyor..',
|
||||
'Ticket': 'Bilet',
|
||||
'Ticket ID': 'Bile ID\'si',
|
||||
'TM': 'TM',
|
||||
'to previous version.': 'önceki sürüme.',
|
||||
'To create a plugin, name a file/folder plugin_[name]': 'Eklenti oluşturmak için dosyayı dosya/klasör plugin_[isim] şeklinde isimlendir. ',
|
||||
'To emulate a breakpoint programatically, write:': 'Program ile kesme noktasını öykünmek için, yazın:',
|
||||
'to use the debugger!': 'hata ayıklayıcısını kullanmak için!',
|
||||
'toggle breakpoint': 'kesme noktasını değiştir',
|
||||
'Toggle Fullscreen': 'Tam Ekrana Geç',
|
||||
'Traceback': 'Nedenin bul',
|
||||
'translation strings for the application': 'uygulama için çeviri cümleleri',
|
||||
'Translation strings for the application': 'Uygulama için çeviri cümleleri',
|
||||
'try': 'dene',
|
||||
'try something like': 'gibi birşey dene',
|
||||
'Try the mobile interface': 'Mobil arayüzü dene',
|
||||
'try view': 'görünümü dene',
|
||||
'Unable to check for upgrades': 'Güncellemeler denetlenemiyor',
|
||||
'unable to create application "%s"': '"%s" uygulaması oluşturulamıyor',
|
||||
'unable to delete file "%(filename)s"': '"%(filename)s" dosylaları silinemiyor',
|
||||
'unable to delete file plugin "%(plugin)s"': '"%(plugin)s" eklenti dosyasyaları silenemiyor',
|
||||
'Unable to download': 'İndirilemiyor',
|
||||
'Unable to download app': 'Uygulamanız indirilemiyor',
|
||||
'Unable to download app because:': 'Uygulamanız indirilemiyor çünkü:',
|
||||
'Unable to download because': 'İndirilemiyor çünkü:',
|
||||
'unable to parse csv file': "impossible d'analyser les fichiers CSV",
|
||||
'unable to uninstall "%s"': 'kladıramıyor çünkü "%s"',
|
||||
'unable to upgrade because "%s"': 'güncelleyemiyor çünkü "%s"',
|
||||
'uncheck all': 'tümünü kladır',
|
||||
'Uninstall': 'Kaldır',
|
||||
'update': 'güncelle',
|
||||
'update all languages': 'tüm delleri yükle',
|
||||
'Update:': 'Güncelle:',
|
||||
'upgrade now': 'şimdi güncelle',
|
||||
'upgrade web2py now': "web2py'yi güncelle",
|
||||
'upload': 'yükle',
|
||||
'Upload': 'Yükle',
|
||||
'Upload & install packed application': 'Paketlenmiş uygulamayı yükle ve kur',
|
||||
'Upload a package:': 'Paket yükle:',
|
||||
'Upload and install packed application': 'Paketlenmiş uygulamayı yükle ve kur',
|
||||
'upload application:': 'uygulamayı yükle:',
|
||||
'Upload existing application': 'Var olan uygulamayı yükle',
|
||||
'upload file:': 'dosyayı yükle:',
|
||||
'upload plugin file:': 'eklenti dosyasını yükle:',
|
||||
'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Karmaşık sorgularda Ve (AND) için (...)&(...) kullanın, Veya (OR) için (...)|(...) kullanın ve DEĞİL (NOT) için ~(...) kullanın. ',
|
||||
'Use an url:': "Url'yi kullan:",
|
||||
'user': 'kullanıcı',
|
||||
'variables': 'değişkenler',
|
||||
'Version': 'Sürüm',
|
||||
'versioning': 'sürümleme',
|
||||
'Versioning': 'Sürümleme',
|
||||
'view': 'görüntü',
|
||||
'Views': 'Görüntüler',
|
||||
'views': 'görüntüler',
|
||||
'Web Framework': 'Web Çatısı',
|
||||
'web2py apps to deploy': 'Yayınlanacak web2py uygulaması',
|
||||
'web2py is up to date': 'web2py güncel',
|
||||
'web2py online debugger': 'çevirimiçi web2py hata ayıklayıcı',
|
||||
'web2py Recent Tweets': 'web2py Son Twitler',
|
||||
'web2py upgraded; please restart it': 'web2py güncellendi, lütfen yeniden başlatın',
|
||||
'WSGI reference name': 'WSGI referans ismi',
|
||||
'YES': 'EVET',
|
||||
'You can also set and remove breakpoint in the edit window, using the Toggle Breakpoint button': '"kesme noktaları" düğmesini kullanarak düzenleme penceresine geçebilir ve kesme nokatalarını hem ekeleyebilir hemde kaldırabilirsiniz',
|
||||
'You need to set up and reach a': 'Gelinceye kadar kurmalısınız',
|
||||
}
|
||||
@@ -8,42 +8,6 @@ WEB2PY_VERSION_URL = WEB2PY_URL + '/examples/default/version'
|
||||
# the user-interface feature that allows you to edit files in your web
|
||||
# browser.
|
||||
|
||||
## Default editor (to change editor you need web2py.admin.editors.zip)
|
||||
## old editors like 'ace' or 'edit_area' or 'amy' are no longer supported
|
||||
TEXT_EDITOR = 'codemirror'
|
||||
|
||||
## Editor Color scheme (only for ace)
|
||||
TEXT_EDITOR_THEME = (
|
||||
"chrome", "clouds", "clouds_midnight", "cobalt", "crimson_editor", "dawn",
|
||||
"dreamweaver", "eclipse", "idle_fingers", "kr_theme", "merbivore",
|
||||
"merbivore_soft", "monokai", "mono_industrial", "pastel_on_dark",
|
||||
"solarized_dark", "solarized_light", "textmate", "tomorrow",
|
||||
"tomorrow_night", "tomorrow_night_blue", "tomorrow_night_bright",
|
||||
"tomorrow_night_eighties", "twilight", "vibrant_ink")[0]
|
||||
|
||||
## Editor Keyboard bindings (only for ace and codemirror)
|
||||
TEXT_EDITOR_KEYBINDING = '' # 'emacs' or 'vi'
|
||||
|
||||
### edit_area only
|
||||
# The default font size, measured in 'points'. The value must be an integer > 0
|
||||
FONT_SIZE = 10
|
||||
|
||||
# Displays the editor in full screen mode. The value must be 'true' or 'false'
|
||||
FULL_SCREEN = 'false'
|
||||
|
||||
# Display a check box under the editor to allow the user to switch
|
||||
# between the editor and a simple
|
||||
# HTML text area. The value must be 'true' or 'false'
|
||||
ALLOW_TOGGLE = 'true'
|
||||
|
||||
# Replaces tab characters with space characters.
|
||||
# The value can be 'false' (meaning that tabs are not replaced),
|
||||
# or an integer > 0 that specifies the number of spaces to replace a tab with.
|
||||
REPLACE_TAB_BY_SPACES = 4
|
||||
|
||||
# Toggle on/off the code editor instead of textarea on startup
|
||||
DISPLAY = "onload" or "later"
|
||||
|
||||
# if demo mode is True then admin works readonly and does not require login
|
||||
DEMO_MODE = False
|
||||
|
||||
@@ -81,4 +45,4 @@ if 'adminLanguage' in request.cookies and not (request.cookies['adminLanguage']
|
||||
T.force(request.cookies['adminLanguage'].value)
|
||||
|
||||
#set static_version
|
||||
response.static_version = '2.7.3'
|
||||
response.static_version = open('VERSION').read().split(' ',1)[1].split('-')[0]
|
||||
|
||||
@@ -144,7 +144,7 @@ if session.is_mobile == 'true':
|
||||
elif session.is_mobile == 'false':
|
||||
is_mobile = False
|
||||
else:
|
||||
is_mobile = request.user_agent().is_mobile
|
||||
is_mobile = request.user_agent().get('is_mobile',False)
|
||||
|
||||
if DEMO_MODE:
|
||||
session.authorized = True
|
||||
|
||||
@@ -24,7 +24,7 @@ def button_enable(href, app):
|
||||
return A(label, _class='button btn', _id=id, callback=href, target=id)
|
||||
|
||||
def sp_button(href, label):
|
||||
if request.user_agent().is_mobile:
|
||||
if request.user_agent().get('is_mobile'):
|
||||
ret = A_button(SPAN(label), _href=href)
|
||||
else:
|
||||
ret = A(SPAN(label), _class='button special btn btn-inverse', _href=href)
|
||||
@@ -37,4 +37,4 @@ def searchbox(elementid):
|
||||
return SPAN(LABEL(IMG(_id="search_start", _src=URL('static', 'images/search.png'), _alt=T('filter')),
|
||||
_class='icon', _for=elementid), ' ',
|
||||
INPUT(_id=elementid, _type='text', _size=12, _class="input-medium"),
|
||||
_class="searchbox")
|
||||
_class="searchbox")
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
response.files.append(URL('static','plugin_statebutton/js/bootstrap-switch.js'))
|
||||
response.files.append(URL('static','plugin_statebutton/css/bootstrap-switch.css'))
|
||||
|
||||
def stateWidget(field, value, data={'on-label':'Enabled', 'off-label':'Disabled', 'on':"primary", 'off':"default" }):
|
||||
try:
|
||||
fieldName = str(field).split('.')[1]
|
||||
except:
|
||||
fieldName = field
|
||||
|
||||
div = DIV(INPUT( _type='checkbox', _name='%s' % fieldName, _checked= 'checked' if value == 'true' else None, _value='true'),
|
||||
_class='make-bootstrap-switch',
|
||||
data=data)
|
||||
script = SCRIPT("""
|
||||
jQuery(".make-bootstrap-switch input[name='%s']").parent().bootstrapSwitch();
|
||||
""" % fieldName)
|
||||
return DIV(div, script)
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
[DEFAULT]
|
||||
theme = web2py
|
||||
closetag = true
|
||||
editor = default
|
||||
|
||||
[editor]
|
||||
theme = web2py
|
||||
editor = default
|
||||
closetag = true
|
||||
|
||||
[editor_sessions]
|
||||
welcome = welcome/models/db.py,welcome/controllers/default.py,welcome/views/default/index.html
|
||||
|
||||
|
||||
@@ -96,8 +96,9 @@
|
||||
for (var i = start; i <= end; ++i) {
|
||||
var line = self.getLine(i);
|
||||
var found = line.indexOf(lineString);
|
||||
if (found > -1 && !/comment/.test(self.getTokenTypeAt(Pos(i, found + 1)))) found = -1;
|
||||
if (found == -1 && (i != end || i == start) && nonWS.test(line)) break lineComment;
|
||||
if (i != start && found > -1 && nonWS.test(line.slice(0, found))) break lineComment;
|
||||
if (found > -1 && nonWS.test(line.slice(0, found))) break lineComment;
|
||||
lines.push(line);
|
||||
}
|
||||
self.operation(function() {
|
||||
@@ -124,7 +125,10 @@
|
||||
endLine = self.getLine(--end);
|
||||
close = endLine.lastIndexOf(endString);
|
||||
}
|
||||
if (open == -1 || close == -1) return false;
|
||||
if (open == -1 || close == -1 ||
|
||||
!/comment/.test(self.getTokenTypeAt(Pos(start, open + 1))) ||
|
||||
!/comment/.test(self.getTokenTypeAt(Pos(end, close + 1))))
|
||||
return false;
|
||||
|
||||
self.operation(function() {
|
||||
self.replaceRange("", Pos(end, close - (pad && endLine.slice(close - pad.length, close) == pad ? pad.length : 0)),
|
||||
|
||||
+43
-1
@@ -10,11 +10,22 @@
|
||||
} else {
|
||||
dialog.className = "CodeMirror-dialog CodeMirror-dialog-top";
|
||||
}
|
||||
dialog.innerHTML = template;
|
||||
if (typeof template == "string") {
|
||||
dialog.innerHTML = template;
|
||||
} else { // Assuming it's a detached DOM element.
|
||||
dialog.appendChild(template);
|
||||
}
|
||||
return dialog;
|
||||
}
|
||||
|
||||
function closeNotification(cm, newVal) {
|
||||
if (cm.state.currentNotificationClose)
|
||||
cm.state.currentNotificationClose();
|
||||
cm.state.currentNotificationClose = newVal;
|
||||
}
|
||||
|
||||
CodeMirror.defineExtension("openDialog", function(template, callback, options) {
|
||||
closeNotification(this, null);
|
||||
var dialog = dialogDiv(this, template, options && options.bottom);
|
||||
var closed = false, me = this;
|
||||
function close() {
|
||||
@@ -24,6 +35,7 @@
|
||||
}
|
||||
var inp = dialog.getElementsByTagName("input")[0], button;
|
||||
if (inp) {
|
||||
if (options && options.value) inp.value = options.value;
|
||||
CodeMirror.on(inp, "keydown", function(e) {
|
||||
if (options && options.onKeyDown && options.onKeyDown(e, inp.value, close)) { return; }
|
||||
if (e.keyCode == 13 || e.keyCode == 27) {
|
||||
@@ -51,6 +63,7 @@
|
||||
});
|
||||
|
||||
CodeMirror.defineExtension("openConfirm", function(template, callbacks, options) {
|
||||
closeNotification(this, null);
|
||||
var dialog = dialogDiv(this, template, options && options.bottom);
|
||||
var buttons = dialog.getElementsByTagName("button");
|
||||
var closed = false, me = this, blurring = 1;
|
||||
@@ -77,4 +90,33 @@
|
||||
CodeMirror.on(b, "focus", function() { ++blurring; });
|
||||
}
|
||||
});
|
||||
|
||||
/*
|
||||
* openNotification
|
||||
* Opens a notification, that can be closed with an optional timer
|
||||
* (default 5000ms timer) and always closes on click.
|
||||
*
|
||||
* If a notification is opened while another is opened, it will close the
|
||||
* currently opened one and open the new one immediately.
|
||||
*/
|
||||
CodeMirror.defineExtension("openNotification", function(template, options) {
|
||||
closeNotification(this, close);
|
||||
var dialog = dialogDiv(this, template, options && options.bottom);
|
||||
var duration = options && (options.duration === undefined ? 5000 : options.duration);
|
||||
var closed = false, doneTimer;
|
||||
|
||||
function close() {
|
||||
if (closed) return;
|
||||
closed = true;
|
||||
clearTimeout(doneTimer);
|
||||
dialog.parentNode.removeChild(dialog);
|
||||
}
|
||||
|
||||
CodeMirror.on(dialog, 'click', function(e) {
|
||||
CodeMirror.e_preventDefault(e);
|
||||
close();
|
||||
});
|
||||
if (duration)
|
||||
doneTimer = setTimeout(close, options.duration);
|
||||
});
|
||||
})();
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
var wrap = cm.getWrapperElement();
|
||||
cm.state.fullScreenRestore = {scrollTop: window.pageYOffset, scrollLeft: window.pageXOffset,
|
||||
width: wrap.style.width, height: wrap.style.height};
|
||||
wrap.style.width = wrap.style.height = "";
|
||||
wrap.style.width = "";
|
||||
wrap.style.height = "auto";
|
||||
wrap.className += " CodeMirror-fullscreen";
|
||||
document.documentElement.style.overflow = "hidden";
|
||||
cm.refresh();
|
||||
|
||||
@@ -2,12 +2,10 @@
|
||||
CodeMirror.defineOption("placeholder", "", function(cm, val, old) {
|
||||
var prev = old && old != CodeMirror.Init;
|
||||
if (val && !prev) {
|
||||
cm.on("focus", onFocus);
|
||||
cm.on("blur", onBlur);
|
||||
cm.on("change", onChange);
|
||||
onChange(cm);
|
||||
} else if (!val && prev) {
|
||||
cm.off("focus", onFocus);
|
||||
cm.off("blur", onBlur);
|
||||
cm.off("change", onChange);
|
||||
clearPlaceholder(cm);
|
||||
@@ -33,9 +31,6 @@
|
||||
cm.display.lineSpace.insertBefore(elt, cm.display.lineSpace.firstChild);
|
||||
}
|
||||
|
||||
function onFocus(cm) {
|
||||
clearPlaceholder(cm);
|
||||
}
|
||||
function onBlur(cm) {
|
||||
if (isEmpty(cm)) setPlaceholder(cm);
|
||||
}
|
||||
@@ -43,7 +38,6 @@
|
||||
var wrapper = cm.getWrapperElement(), empty = isEmpty(cm);
|
||||
wrapper.className = wrapper.className.replace(" CodeMirror-empty", "") + (empty ? " CodeMirror-empty" : "");
|
||||
|
||||
if (cm.hasFocus()) return;
|
||||
if (empty) setPlaceholder(cm);
|
||||
else clearPlaceholder(cm);
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
var map = {
|
||||
name : "autoCloseBrackets",
|
||||
Backspace: function(cm) {
|
||||
if (cm.somethingSelected()) return CodeMirror.Pass;
|
||||
if (cm.somethingSelected() || cm.getOption("disableInput")) return CodeMirror.Pass;
|
||||
var cur = cm.getCursor(), around = charsAround(cm, cur);
|
||||
if (around && pairs.indexOf(around) % 2 == 0)
|
||||
cm.replaceRange("", CodeMirror.Pos(cur.line, cur.ch - 1), CodeMirror.Pos(cur.line, cur.ch + 1));
|
||||
@@ -49,7 +49,8 @@
|
||||
else cm.execCommand("goCharRight");
|
||||
}
|
||||
map["'" + left + "'"] = function(cm) {
|
||||
if (left == "'" && cm.getTokenAt(cm.getCursor()).type == "comment")
|
||||
if (left == "'" && cm.getTokenAt(cm.getCursor()).type == "comment" ||
|
||||
cm.getOption("disableInput"))
|
||||
return CodeMirror.Pass;
|
||||
if (cm.somethingSelected()) return surround(cm);
|
||||
if (left == right && maybeOverwrite(cm) != CodeMirror.Pass) return;
|
||||
@@ -70,7 +71,8 @@
|
||||
function buildExplodeHandler(pairs) {
|
||||
return function(cm) {
|
||||
var cur = cm.getCursor(), around = charsAround(cm, cur);
|
||||
if (!around || pairs.indexOf(around) % 2 != 0) return CodeMirror.Pass;
|
||||
if (!around || pairs.indexOf(around) % 2 != 0 || cm.getOption("disableInput"))
|
||||
return CodeMirror.Pass;
|
||||
cm.operation(function() {
|
||||
var newPos = CodeMirror.Pos(cur.line + 1, 0);
|
||||
cm.replaceSelection("\n\n", {anchor: newPos, head: newPos}, "+input");
|
||||
|
||||
+21
-15
@@ -24,16 +24,15 @@
|
||||
|
||||
(function() {
|
||||
CodeMirror.defineOption("autoCloseTags", false, function(cm, val, old) {
|
||||
if (val && (old == CodeMirror.Init || !old)) {
|
||||
var map = {name: "autoCloseTags"};
|
||||
if (typeof val != "object" || val.whenClosing)
|
||||
map["'/'"] = function(cm) { return autoCloseSlash(cm); };
|
||||
if (typeof val != "object" || val.whenOpening)
|
||||
map["'>'"] = function(cm) { return autoCloseGT(cm); };
|
||||
cm.addKeyMap(map);
|
||||
} else if (!val && (old != CodeMirror.Init && old)) {
|
||||
if (old != CodeMirror.Init && old)
|
||||
cm.removeKeyMap("autoCloseTags");
|
||||
}
|
||||
if (!val) return;
|
||||
var map = {name: "autoCloseTags"};
|
||||
if (typeof val != "object" || val.whenClosing)
|
||||
map["'/'"] = function(cm) { return autoCloseSlash(cm); };
|
||||
if (typeof val != "object" || val.whenOpening)
|
||||
map["'>'"] = function(cm) { return autoCloseGT(cm); };
|
||||
cm.addKeyMap(map);
|
||||
});
|
||||
|
||||
var htmlDontClose = ["area", "base", "br", "col", "command", "embed", "hr", "img", "input", "keygen", "link", "meta", "param",
|
||||
@@ -44,7 +43,7 @@
|
||||
function autoCloseGT(cm) {
|
||||
var pos = cm.getCursor(), tok = cm.getTokenAt(pos);
|
||||
var inner = CodeMirror.innerMode(cm.getMode(), tok.state), state = inner.state;
|
||||
if (inner.mode.name != "xml" || !state.tagName) return CodeMirror.Pass;
|
||||
if (inner.mode.name != "xml" || !state.tagName || cm.getOption("disableInput")) return CodeMirror.Pass;
|
||||
|
||||
var opt = cm.getOption("autoCloseTags"), html = inner.mode.configuration == "html";
|
||||
var dontCloseTags = (typeof opt == "object" && opt.dontCloseTags) || (html && htmlDontClose);
|
||||
@@ -54,9 +53,13 @@
|
||||
if (tok.end > pos.ch) tagName = tagName.slice(0, tagName.length - tok.end + pos.ch);
|
||||
var lowerTagName = tagName.toLowerCase();
|
||||
// Don't process the '>' at the end of an end-tag or self-closing tag
|
||||
if (tok.type == "tag" && state.type == "closeTag" ||
|
||||
if (!tagName ||
|
||||
tok.type == "string" && (tok.end != pos.ch || !/[\"\']/.test(tok.string.charAt(tok.string.length - 1)) || tok.string.length == 1) ||
|
||||
tok.type == "tag" && state.type == "closeTag" ||
|
||||
tok.string.indexOf("/") == (tok.string.length - 1) || // match something like <someTagName />
|
||||
dontCloseTags && indexOf(dontCloseTags, lowerTagName) > -1)
|
||||
dontCloseTags && indexOf(dontCloseTags, lowerTagName) > -1 ||
|
||||
CodeMirror.scanForClosingTag && CodeMirror.scanForClosingTag(cm, pos, tagName,
|
||||
Math.min(cm.lastLine() + 1, pos.line + 50)))
|
||||
return CodeMirror.Pass;
|
||||
|
||||
var doIndent = indentTags && indexOf(indentTags, lowerTagName) > -1;
|
||||
@@ -64,15 +67,18 @@
|
||||
cm.replaceSelection(">" + (doIndent ? "\n\n" : "") + "</" + tagName + ">",
|
||||
{head: curPos, anchor: curPos});
|
||||
if (doIndent) {
|
||||
cm.indentLine(pos.line + 1);
|
||||
cm.indentLine(pos.line + 2);
|
||||
cm.indentLine(pos.line + 1, null, true);
|
||||
cm.indentLine(pos.line + 2, null);
|
||||
}
|
||||
}
|
||||
|
||||
function autoCloseSlash(cm) {
|
||||
var pos = cm.getCursor(), tok = cm.getTokenAt(pos);
|
||||
var inner = CodeMirror.innerMode(cm.getMode(), tok.state), state = inner.state;
|
||||
if (tok.string.charAt(0) != "<" || inner.mode.name != "xml") return CodeMirror.Pass;
|
||||
if (tok.type == "string" || tok.string.charAt(0) != "<" ||
|
||||
tok.start != pos.ch - 1 || inner.mode.name != "xml" ||
|
||||
cm.getOption("disableInput"))
|
||||
return CodeMirror.Pass;
|
||||
|
||||
var tagName = state.context && state.context.tagName;
|
||||
if (tagName) cm.replaceSelection("/" + tagName + ">", "end");
|
||||
|
||||
@@ -5,8 +5,10 @@
|
||||
unorderedBullets = '*+-';
|
||||
|
||||
CodeMirror.commands.newlineAndIndentContinueMarkdownList = function(cm) {
|
||||
if (cm.getOption("disableInput")) return CodeMirror.Pass;
|
||||
|
||||
var pos = cm.getCursor(),
|
||||
inList = cm.getStateAfter(pos.line).list,
|
||||
inList = cm.getStateAfter(pos.line).list !== false,
|
||||
match;
|
||||
|
||||
if (!inList || !(match = cm.getLine(pos.line).match(listRE))) {
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
function findMatchingBracket(cm, where, strict) {
|
||||
var state = cm.state.matchBrackets;
|
||||
var maxScanLen = (state && state.maxScanLineLength) || 10000;
|
||||
var maxScanLines = (state && state.maxScanLines) || 100;
|
||||
|
||||
var cur = where || cm.getCursor(), line = cm.getLineHandle(cur.line), pos = cur.ch - 1;
|
||||
var match = (pos >= 0 && matching[line.text.charAt(pos)]) || matching[line.text.charAt(++pos)];
|
||||
@@ -32,7 +33,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
for (var i = cur.line, found, e = forward ? Math.min(i + 100, cm.lineCount()) : Math.max(-1, i - 100); i != e; i+=d) {
|
||||
for (var i = cur.line, found, e = forward ? Math.min(i + maxScanLines, cm.lineCount()) : Math.max(-1, i - maxScanLines); i != e; i+=d) {
|
||||
if (i == cur.line) found = scan(line, i, pos);
|
||||
else found = scan(cm.getLineHandle(i), i);
|
||||
if (found) break;
|
||||
@@ -53,7 +54,7 @@
|
||||
var one = cm.markText(found.from, Pos(found.from.line, found.from.ch + 1), {className: style});
|
||||
var two = found.to && cm.markText(found.to, Pos(found.to.line, found.to.ch + 1), {className: style});
|
||||
// Kludge to work around the IE bug from issue #1193, where text
|
||||
// input stops going to the textare whever this fires.
|
||||
// input stops going to the textarea whenever this fires.
|
||||
if (ie_lt8 && cm.state.focused) cm.display.input.focus();
|
||||
var clear = function() {
|
||||
cm.operation(function() { one.clear(); two && two.clear(); });
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
CodeMirror.registerGlobalHelper("fold", "comment", function(mode) {
|
||||
return mode.blockCommentStart && mode.blockCommentEnd;
|
||||
}, function(cm, start) {
|
||||
var mode = cm.getModeAt(start), startToken = mode.blockCommentStart, endToken = mode.blockCommentEnd;
|
||||
if (!startToken || !endToken) return;
|
||||
var line = start.line, lineText = cm.getLine(line);
|
||||
|
||||
var startCh;
|
||||
for (var at = start.ch, pass = 0;;) {
|
||||
var found = at <= 0 ? -1 : lineText.lastIndexOf(startToken, at - 1);
|
||||
if (found == -1) {
|
||||
if (pass == 1) return;
|
||||
pass = 1;
|
||||
at = lineText.length;
|
||||
continue;
|
||||
}
|
||||
if (pass == 1 && found < start.ch) return;
|
||||
if (/comment/.test(cm.getTokenTypeAt(CodeMirror.Pos(line, found + 1)))) {
|
||||
startCh = found + startToken.length;
|
||||
break;
|
||||
}
|
||||
at = found - 1;
|
||||
}
|
||||
|
||||
var depth = 1, lastLine = cm.lastLine(), end, endCh;
|
||||
outer: for (var i = line; i <= lastLine; ++i) {
|
||||
var text = cm.getLine(i), pos = i == line ? startCh : 0;
|
||||
for (;;) {
|
||||
var nextOpen = text.indexOf(startToken, pos), nextClose = text.indexOf(endToken, pos);
|
||||
if (nextOpen < 0) nextOpen = text.length;
|
||||
if (nextClose < 0) nextClose = text.length;
|
||||
pos = Math.min(nextOpen, nextClose);
|
||||
if (pos == text.length) break;
|
||||
if (pos == nextOpen) ++depth;
|
||||
else if (!--depth) { end = i; endCh = pos; break outer; }
|
||||
++pos;
|
||||
}
|
||||
}
|
||||
if (end == null || line == end && endCh == startCh) return;
|
||||
return {from: CodeMirror.Pos(line, startCh),
|
||||
to: CodeMirror.Pos(end, endCh)};
|
||||
});
|
||||
+19
-6
@@ -1,10 +1,9 @@
|
||||
(function() {
|
||||
"use strict";
|
||||
|
||||
function doFold(cm, pos, options) {
|
||||
function doFold(cm, pos, options, force) {
|
||||
var finder = options && (options.call ? options : options.rangeFinder);
|
||||
if (!finder) finder = cm.getHelper(pos, "fold");
|
||||
if (!finder) return;
|
||||
if (!finder) finder = CodeMirror.fold.auto;
|
||||
if (typeof pos == "number") pos = CodeMirror.Pos(pos, 0);
|
||||
var minSize = options && options.minFoldSize || 0;
|
||||
|
||||
@@ -13,7 +12,7 @@
|
||||
if (!range || range.to.line - range.from.line < minSize) return null;
|
||||
var marks = cm.findMarksAt(range.from);
|
||||
for (var i = 0; i < marks.length; ++i) {
|
||||
if (marks[i].__isFold) {
|
||||
if (marks[i].__isFold && force !== "fold") {
|
||||
if (!allowFolded) return null;
|
||||
range.cleared = true;
|
||||
marks[i].clear();
|
||||
@@ -27,7 +26,7 @@
|
||||
pos = CodeMirror.Pos(pos.line - 1, 0);
|
||||
range = getRange(false);
|
||||
}
|
||||
if (!range || range.cleared) return;
|
||||
if (!range || range.cleared || force === "unfold") return;
|
||||
|
||||
var myWidget = makeWidget(options);
|
||||
CodeMirror.on(myWidget, "mousedown", function() { myRange.clear(); });
|
||||
@@ -59,7 +58,13 @@
|
||||
};
|
||||
|
||||
// New-style interface
|
||||
CodeMirror.defineExtension("foldCode", function(pos, options) { doFold(this, pos, options); });
|
||||
CodeMirror.defineExtension("foldCode", function(pos, options, force) {
|
||||
doFold(this, pos, options, force);
|
||||
});
|
||||
|
||||
CodeMirror.commands.fold = function(cm) {
|
||||
cm.foldCode(cm.getCursor());
|
||||
};
|
||||
|
||||
CodeMirror.registerHelper("fold", "combine", function() {
|
||||
var funcs = Array.prototype.slice.call(arguments, 0);
|
||||
@@ -70,4 +75,12 @@
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
CodeMirror.registerHelper("fold", "auto", function(cm, start) {
|
||||
var helpers = cm.getHelpers(start, "fold");
|
||||
for (var i = 0; i < helpers.length; i++) {
|
||||
var cur = helpers[i](cm, start);
|
||||
if (cur) return cur;
|
||||
}
|
||||
});
|
||||
})();
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
.CodeMirror-foldmarker {
|
||||
color: blue;
|
||||
text-shadow: #b9f 1px 1px 2px, #b9f -1px -1px 2px, #b9f 1px -1px 2px, #b9f -1px 1px 2px;
|
||||
font-family: arial;
|
||||
line-height: .3;
|
||||
cursor: pointer;
|
||||
}
|
||||
.CodeMirror-foldgutter {
|
||||
width: .7em;
|
||||
}
|
||||
.CodeMirror-foldgutter-open,
|
||||
.CodeMirror-foldgutter-folded {
|
||||
color: #555;
|
||||
cursor: pointer;
|
||||
}
|
||||
.CodeMirror-foldgutter-open:after {
|
||||
content: "\25BE";
|
||||
}
|
||||
.CodeMirror-foldgutter-folded:after {
|
||||
content: "\25B8";
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
(function() {
|
||||
"use strict";
|
||||
|
||||
CodeMirror.defineOption("foldGutter", false, function(cm, val, old) {
|
||||
if (old && old != CodeMirror.Init) {
|
||||
cm.clearGutter(cm.state.foldGutter.options.gutter);
|
||||
cm.state.foldGutter = null;
|
||||
cm.off("gutterClick", onGutterClick);
|
||||
cm.off("change", onChange);
|
||||
cm.off("viewportChange", onViewportChange);
|
||||
cm.off("fold", onFold);
|
||||
cm.off("unfold", onFold);
|
||||
cm.off("swapDoc", updateInViewport);
|
||||
}
|
||||
if (val) {
|
||||
cm.state.foldGutter = new State(parseOptions(val));
|
||||
updateInViewport(cm);
|
||||
cm.on("gutterClick", onGutterClick);
|
||||
cm.on("change", onChange);
|
||||
cm.on("viewportChange", onViewportChange);
|
||||
cm.on("fold", onFold);
|
||||
cm.on("unfold", onFold);
|
||||
cm.on("swapDoc", updateInViewport);
|
||||
}
|
||||
});
|
||||
|
||||
var Pos = CodeMirror.Pos;
|
||||
|
||||
function State(options) {
|
||||
this.options = options;
|
||||
this.from = this.to = 0;
|
||||
}
|
||||
|
||||
function parseOptions(opts) {
|
||||
if (opts === true) opts = {};
|
||||
if (opts.gutter == null) opts.gutter = "CodeMirror-foldgutter";
|
||||
if (opts.indicatorOpen == null) opts.indicatorOpen = "CodeMirror-foldgutter-open";
|
||||
if (opts.indicatorFolded == null) opts.indicatorFolded = "CodeMirror-foldgutter-folded";
|
||||
return opts;
|
||||
}
|
||||
|
||||
function isFolded(cm, line) {
|
||||
var marks = cm.findMarksAt(Pos(line));
|
||||
for (var i = 0; i < marks.length; ++i)
|
||||
if (marks[i].__isFold && marks[i].find().from.line == line) return true;
|
||||
}
|
||||
|
||||
function marker(spec) {
|
||||
if (typeof spec == "string") {
|
||||
var elt = document.createElement("div");
|
||||
elt.className = spec;
|
||||
return elt;
|
||||
} else {
|
||||
return spec.cloneNode(true);
|
||||
}
|
||||
}
|
||||
|
||||
function updateFoldInfo(cm, from, to) {
|
||||
var opts = cm.state.foldGutter.options, cur = from;
|
||||
cm.eachLine(from, to, function(line) {
|
||||
var mark = null;
|
||||
if (isFolded(cm, cur)) {
|
||||
mark = marker(opts.indicatorFolded);
|
||||
} else {
|
||||
var pos = Pos(cur, 0), func = opts.rangeFinder || CodeMirror.fold.auto;
|
||||
var range = func && func(cm, pos);
|
||||
if (range && range.from.line + 1 < range.to.line)
|
||||
mark = marker(opts.indicatorOpen);
|
||||
}
|
||||
cm.setGutterMarker(line, opts.gutter, mark);
|
||||
++cur;
|
||||
});
|
||||
}
|
||||
|
||||
function updateInViewport(cm) {
|
||||
var vp = cm.getViewport(), state = cm.state.foldGutter;
|
||||
if (!state) return;
|
||||
cm.operation(function() {
|
||||
updateFoldInfo(cm, vp.from, vp.to);
|
||||
});
|
||||
state.from = vp.from; state.to = vp.to;
|
||||
}
|
||||
|
||||
function onGutterClick(cm, line, gutter) {
|
||||
var opts = cm.state.foldGutter.options;
|
||||
if (gutter != opts.gutter) return;
|
||||
cm.foldCode(Pos(line, 0), opts.rangeFinder);
|
||||
}
|
||||
|
||||
function onChange(cm) {
|
||||
var state = cm.state.foldGutter, opts = cm.state.foldGutter.options;
|
||||
state.from = state.to = 0;
|
||||
clearTimeout(state.changeUpdate);
|
||||
state.changeUpdate = setTimeout(function() { updateInViewport(cm); }, opts.foldOnChangeTimeSpan || 600);
|
||||
}
|
||||
|
||||
function onViewportChange(cm) {
|
||||
var state = cm.state.foldGutter, opts = cm.state.foldGutter.options;
|
||||
clearTimeout(state.changeUpdate);
|
||||
state.changeUpdate = setTimeout(function() {
|
||||
var vp = cm.getViewport();
|
||||
if (state.from == state.to || vp.from - state.to > 20 || state.from - vp.to > 20) {
|
||||
updateInViewport(cm);
|
||||
} else {
|
||||
cm.operation(function() {
|
||||
if (vp.from < state.from) {
|
||||
updateFoldInfo(cm, vp.from, state.from);
|
||||
state.from = vp.from;
|
||||
}
|
||||
if (vp.to > state.to) {
|
||||
updateFoldInfo(cm, state.to, vp.to);
|
||||
state.to = vp.to;
|
||||
}
|
||||
});
|
||||
}
|
||||
}, opts.updateViewportTimeSpan || 400);
|
||||
}
|
||||
|
||||
function onFold(cm, from) {
|
||||
var state = cm.state.foldGutter, line = from.line;
|
||||
if (line >= state.from && line < state.to)
|
||||
updateFoldInfo(cm, line, line + 1);
|
||||
}
|
||||
})();
|
||||
@@ -1,12 +1,30 @@
|
||||
CodeMirror.registerHelper("fold", "indent", function(cm, start) {
|
||||
var tabSize = cm.getOption("tabSize"), firstLine = cm.getLine(start.line);
|
||||
var myIndent = CodeMirror.countColumn(firstLine, null, tabSize);
|
||||
for (var i = start.line + 1, end = cm.lineCount(); i < end; ++i) {
|
||||
if (!/\S/.test(firstLine)) return;
|
||||
var getIndent = function(line) {
|
||||
return CodeMirror.countColumn(line, null, tabSize);
|
||||
};
|
||||
var myIndent = getIndent(firstLine);
|
||||
var lastLineInFold = null;
|
||||
// Go through lines until we find a line that definitely doesn't belong in
|
||||
// the block we're folding, or to the end.
|
||||
for (var i = start.line + 1, end = cm.lastLine(); i <= end; ++i) {
|
||||
var curLine = cm.getLine(i);
|
||||
if (CodeMirror.countColumn(curLine, null, tabSize) < myIndent &&
|
||||
CodeMirror.countColumn(cm.getLine(i-1), null, tabSize) > myIndent)
|
||||
return {from: CodeMirror.Pos(start.line, firstLine.length),
|
||||
to: CodeMirror.Pos(i, curLine.length)};
|
||||
var curIndent = getIndent(curLine);
|
||||
if (curIndent > myIndent) {
|
||||
// Lines with a greater indent are considered part of the block.
|
||||
lastLineInFold = i;
|
||||
} else if (!/\S/.test(curLine)) {
|
||||
// Empty lines might be breaks within the block we're trying to fold.
|
||||
} else {
|
||||
// A non-empty line at an indent equal to or less than ours marks the
|
||||
// start of another block.
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (lastLineInFold) return {
|
||||
from: CodeMirror.Pos(start.line, firstLine.length),
|
||||
to: CodeMirror.Pos(lastLineInFold, cm.getLine(lastLineInFold).length)
|
||||
};
|
||||
});
|
||||
CodeMirror.indentRangeFinder = CodeMirror.fold.indent; // deprecated
|
||||
|
||||
@@ -164,4 +164,10 @@
|
||||
if (close) return {open: open, close: close};
|
||||
}
|
||||
};
|
||||
|
||||
// Used by addon/edit/closetag.js
|
||||
CodeMirror.scanForClosingTag = function(cm, pos, name, end) {
|
||||
var iter = new Iter(cm, pos.line, pos.ch, end ? {from: 0, to: end} : null);
|
||||
return !!findMatchingClose(iter, name);
|
||||
};
|
||||
})();
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
function scriptHint(editor, keywords, getToken, options) {
|
||||
// Find the token at the cursor
|
||||
var cur = editor.getCursor(), token = getToken(editor, cur), tprop = token;
|
||||
if (/\b(?:string|comment)\b/.test(token.type)) return;
|
||||
token.state = CodeMirror.innerMode(editor.getMode(), token.state).state;
|
||||
|
||||
// If it's not a 'word-style' token, ignore the token.
|
||||
@@ -33,21 +34,6 @@
|
||||
tprop = getToken(editor, Pos(cur.line, tprop.start));
|
||||
if (tprop.string != ".") return;
|
||||
tprop = getToken(editor, Pos(cur.line, tprop.start));
|
||||
if (tprop.string == ')') {
|
||||
var level = 1;
|
||||
do {
|
||||
tprop = getToken(editor, Pos(cur.line, tprop.start));
|
||||
switch (tprop.string) {
|
||||
case ')': level++; break;
|
||||
case '(': level--; break;
|
||||
default: break;
|
||||
}
|
||||
} while (level > 0);
|
||||
tprop = getToken(editor, Pos(cur.line, tprop.start));
|
||||
if (tprop.type.indexOf("variable") === 0)
|
||||
tprop.type = "function";
|
||||
else return; // no clue
|
||||
}
|
||||
if (!context) var context = [];
|
||||
context.push(tprop);
|
||||
}
|
||||
@@ -101,7 +87,7 @@
|
||||
function getCompletions(token, context, keywords, options) {
|
||||
var found = [], start = token.string;
|
||||
function maybeAdd(str) {
|
||||
if (str.indexOf(start) == 0 && !arrayContains(found, str)) found.push(str);
|
||||
if (str.lastIndexOf(start, 0) == 0 && !arrayContains(found, str)) found.push(str);
|
||||
}
|
||||
function gatherCompletions(obj) {
|
||||
if (typeof obj == "string") forEach(stringProps, maybeAdd);
|
||||
@@ -110,11 +96,11 @@
|
||||
for (var name in obj) maybeAdd(name);
|
||||
}
|
||||
|
||||
if (context) {
|
||||
if (context && context.length) {
|
||||
// If this is a property, see if it belongs to some object we can
|
||||
// find in the current environment.
|
||||
var obj = context.pop(), base;
|
||||
if (obj.type.indexOf("variable") === 0) {
|
||||
if (obj.type && obj.type.indexOf("variable") === 0) {
|
||||
if (options && options.additionalContext)
|
||||
base = options.additionalContext[obj.string];
|
||||
base = base || window[obj.string];
|
||||
@@ -132,8 +118,7 @@
|
||||
while (base != null && context.length)
|
||||
base = base[context.pop().string];
|
||||
if (base != null) gatherCompletions(base);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// If not, just look in the window object and any local scope
|
||||
// (reading into JS mode internals to get at the local and global variables)
|
||||
for (var v = token.state.localVars; v; v = v.next) maybeAdd(v.name);
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
function getCompletions(token, context) {
|
||||
var found = [], start = token.string;
|
||||
function maybeAdd(str) {
|
||||
if (str.indexOf(start) == 0 && !arrayContains(found, str)) found.push(str);
|
||||
if (str.lastIndexOf(start, 0) == 0 && !arrayContains(found, str)) found.push(str);
|
||||
}
|
||||
|
||||
function gatherCompletions(obj) {
|
||||
|
||||
@@ -31,10 +31,6 @@
|
||||
|
||||
var completionList = getCompletions(token, context);
|
||||
completionList = completionList.sort();
|
||||
//prevent autocomplete for last word, instead show dropdown with one word
|
||||
if(completionList.length == 1) {
|
||||
completionList.push(" ");
|
||||
}
|
||||
|
||||
return {list: completionList,
|
||||
from: CodeMirror.Pos(cur.line, token.start),
|
||||
@@ -66,7 +62,7 @@
|
||||
function getCompletions(token, context) {
|
||||
var found = [], start = token.string;
|
||||
function maybeAdd(str) {
|
||||
if (str.indexOf(start) == 0 && !arrayContains(found, str)) found.push(str);
|
||||
if (str.lastIndexOf(start, 0) == 0 && !arrayContains(found, str)) found.push(str);
|
||||
}
|
||||
|
||||
function gatherCompletions(_obj) {
|
||||
|
||||
+74
-13
@@ -1,11 +1,16 @@
|
||||
(function() {
|
||||
"use strict";
|
||||
|
||||
var HINT_ELEMENT_CLASS = "CodeMirror-hint";
|
||||
var ACTIVE_HINT_ELEMENT_CLASS = "CodeMirror-hint-active";
|
||||
|
||||
CodeMirror.showHint = function(cm, getHints, options) {
|
||||
// We want a single cursor position.
|
||||
if (cm.somethingSelected()) return;
|
||||
if (getHints == null) getHints = cm.getHelper(cm.getCursor(), "hint");
|
||||
if (getHints == null) return;
|
||||
if (getHints == null) {
|
||||
if (options && options.async) return;
|
||||
else getHints = CodeMirror.hint.auto;
|
||||
}
|
||||
|
||||
if (cm.state.completionActive) cm.state.completionActive.close();
|
||||
|
||||
@@ -42,6 +47,7 @@
|
||||
var completion = data.list[i];
|
||||
if (completion.hint) completion.hint(this.cm, data, completion);
|
||||
else this.cm.replaceRange(getText(completion), data.from, data.to);
|
||||
CodeMirror.signal(data, "pick", completion);
|
||||
this.close();
|
||||
},
|
||||
|
||||
@@ -58,10 +64,15 @@
|
||||
this.widget = new Widget(this, data);
|
||||
CodeMirror.signal(data, "shown");
|
||||
|
||||
var debounce = null, completion = this, finished;
|
||||
var debounce = 0, completion = this, finished;
|
||||
var closeOn = this.options.closeCharacters || /[\s()\[\]{};:>,]/;
|
||||
var startPos = this.cm.getCursor(), startLen = this.cm.getLine(startPos.line).length;
|
||||
|
||||
var requestAnimationFrame = window.requestAnimationFrame || function(fn) {
|
||||
return setTimeout(fn, 1000/60);
|
||||
};
|
||||
var cancelAnimationFrame = window.cancelAnimationFrame || clearTimeout;
|
||||
|
||||
function done() {
|
||||
if (finished) return;
|
||||
finished = true;
|
||||
@@ -85,15 +96,22 @@
|
||||
completion.widget = new Widget(completion, data);
|
||||
}
|
||||
|
||||
function clearDebounce() {
|
||||
if (debounce) {
|
||||
cancelAnimationFrame(debounce);
|
||||
debounce = 0;
|
||||
}
|
||||
}
|
||||
|
||||
function activity() {
|
||||
clearTimeout(debounce);
|
||||
clearDebounce();
|
||||
var pos = completion.cm.getCursor(), line = completion.cm.getLine(pos.line);
|
||||
if (pos.line != startPos.line || line.length - pos.ch != startLen - startPos.ch ||
|
||||
pos.ch < startPos.ch || completion.cm.somethingSelected() ||
|
||||
(pos.ch && closeOn.test(line.charAt(pos.ch - 1)))) {
|
||||
completion.close();
|
||||
} else {
|
||||
debounce = setTimeout(update, 170);
|
||||
debounce = requestAnimationFrame(update);
|
||||
if (completion.widget) completion.widget.close();
|
||||
}
|
||||
}
|
||||
@@ -140,6 +158,13 @@
|
||||
return ourMap;
|
||||
}
|
||||
|
||||
function getHintElement(hintsElement, el) {
|
||||
while (el && el != hintsElement) {
|
||||
if (el.nodeName.toUpperCase() === "LI" && el.parentNode == hintsElement) return el;
|
||||
el = el.parentNode;
|
||||
}
|
||||
}
|
||||
|
||||
function Widget(completion, data) {
|
||||
this.completion = completion;
|
||||
this.data = data;
|
||||
@@ -147,12 +172,12 @@
|
||||
|
||||
var hints = this.hints = document.createElement("ul");
|
||||
hints.className = "CodeMirror-hints";
|
||||
this.selectedHint = 0;
|
||||
this.selectedHint = options.getDefaultSelection ? options.getDefaultSelection(cm,options,data) : 0;
|
||||
|
||||
var completions = data.list;
|
||||
for (var i = 0; i < completions.length; ++i) {
|
||||
var elt = hints.appendChild(document.createElement("li")), cur = completions[i];
|
||||
var className = "CodeMirror-hint" + (i ? "" : " CodeMirror-hint-active");
|
||||
var className = HINT_ELEMENT_CLASS + (i != this.selectedHint ? "" : " " + ACTIVE_HINT_ELEMENT_CLASS);
|
||||
if (cur.className != null) className = cur.className + " " + className;
|
||||
elt.className = className;
|
||||
if (cur.render) cur.render(elt, data, cur);
|
||||
@@ -216,13 +241,18 @@
|
||||
});
|
||||
|
||||
CodeMirror.on(hints, "dblclick", function(e) {
|
||||
var t = e.target || e.srcElement;
|
||||
if (t.hintId != null) {widget.changeActive(t.hintId); widget.pick();}
|
||||
var t = getHintElement(hints, e.target || e.srcElement);
|
||||
if (t && t.hintId != null) {widget.changeActive(t.hintId); widget.pick();}
|
||||
});
|
||||
|
||||
CodeMirror.on(hints, "click", function(e) {
|
||||
var t = e.target || e.srcElement;
|
||||
if (t.hintId != null) widget.changeActive(t.hintId);
|
||||
var t = getHintElement(hints, e.target || e.srcElement);
|
||||
if (t && t.hintId != null) {
|
||||
widget.changeActive(t.hintId);
|
||||
if (options.completeOnSingleClick) widget.pick();
|
||||
}
|
||||
});
|
||||
|
||||
CodeMirror.on(hints, "mousedown", function() {
|
||||
setTimeout(function(){cm.focus();}, 20);
|
||||
});
|
||||
@@ -257,9 +287,9 @@
|
||||
i = avoidWrap ? 0 : this.data.list.length - 1;
|
||||
if (this.selectedHint == i) return;
|
||||
var node = this.hints.childNodes[this.selectedHint];
|
||||
node.className = node.className.replace(" CodeMirror-hint-active", "");
|
||||
node.className = node.className.replace(" " + ACTIVE_HINT_ELEMENT_CLASS, "");
|
||||
node = this.hints.childNodes[this.selectedHint = i];
|
||||
node.className += " CodeMirror-hint-active";
|
||||
node.className += " " + ACTIVE_HINT_ELEMENT_CLASS;
|
||||
if (node.offsetTop < this.hints.scrollTop)
|
||||
this.hints.scrollTop = node.offsetTop - 3;
|
||||
else if (node.offsetTop + node.offsetHeight > this.hints.scrollTop + this.hints.clientHeight)
|
||||
@@ -271,4 +301,35 @@
|
||||
return Math.floor(this.hints.clientHeight / this.hints.firstChild.offsetHeight) || 1;
|
||||
}
|
||||
};
|
||||
|
||||
CodeMirror.registerHelper("hint", "auto", function(cm, options) {
|
||||
var helpers = cm.getHelpers(cm.getCursor(), "hint");
|
||||
if (helpers.length) {
|
||||
for (var i = 0; i < helpers.length; i++) {
|
||||
var cur = helpers[i](cm, options);
|
||||
if (cur && cur.list.length) return cur;
|
||||
}
|
||||
} else {
|
||||
var words = cm.getHelper(cm.getCursor(), "hintWords");
|
||||
if (words) return CodeMirror.hint.fromList(cm, {words: words});
|
||||
}
|
||||
});
|
||||
|
||||
CodeMirror.registerHelper("hint", "fromList", function(cm, options) {
|
||||
var cur = cm.getCursor(), token = cm.getTokenAt(cur);
|
||||
var found = [];
|
||||
for (var i = 0; i < options.words.length; i++) {
|
||||
var word = options.words[i];
|
||||
if (word.slice(0, token.string.length) == token.string)
|
||||
found.push(word);
|
||||
}
|
||||
|
||||
if (found.length) return {
|
||||
list: found,
|
||||
from: CodeMirror.Pos(cur.line, token.start),
|
||||
to: CodeMirror.Pos(cur.line, token.end)
|
||||
};
|
||||
});
|
||||
|
||||
CodeMirror.commands.autocomplete = CodeMirror.showHint;
|
||||
})();
|
||||
|
||||
@@ -20,13 +20,13 @@
|
||||
var cx = inner.state.context, curTag = cx && tags[cx.tagName];
|
||||
var childList = cx ? curTag && curTag.children : tags["!top"];
|
||||
if (childList) {
|
||||
for (var i = 0; i < childList.length; ++i) if (!prefix || childList[i].indexOf(prefix) == 0)
|
||||
for (var i = 0; i < childList.length; ++i) if (!prefix || childList[i].lastIndexOf(prefix, 0) == 0)
|
||||
result.push("<" + childList[i]);
|
||||
} else {
|
||||
for (var name in tags) if (tags.hasOwnProperty(name) && name != "!top" && (!prefix || name.indexOf(prefix) == 0))
|
||||
for (var name in tags) if (tags.hasOwnProperty(name) && name != "!top" && (!prefix || name.lastIndexOf(prefix, 0) == 0))
|
||||
result.push("<" + name);
|
||||
}
|
||||
if (cx && (!prefix || ("/" + cx.tagName).indexOf(prefix) == 0))
|
||||
if (cx && (!prefix || ("/" + cx.tagName).lastIndexOf(prefix, 0) == 0))
|
||||
result.push("</" + cx.tagName + ">");
|
||||
} else {
|
||||
// Attribute completion
|
||||
@@ -37,6 +37,7 @@
|
||||
Pos(cur.line, token.type == "string" ? token.start : token.end));
|
||||
var atName = before.match(/([^\s\u00a0=<>\"\']+)=$/), atValues;
|
||||
if (!atName || !attrs.hasOwnProperty(atName[1]) || !(atValues = attrs[atName[1]])) return;
|
||||
if (typeof atValues == 'function') atValues = atValues.call(this, cm); // Functions can be used to supply values for autocomplete widget
|
||||
if (token.type == "string") {
|
||||
prefix = token.string;
|
||||
if (/['"]/.test(token.string.charAt(0))) {
|
||||
@@ -45,14 +46,14 @@
|
||||
}
|
||||
replaceToken = true;
|
||||
}
|
||||
for (var i = 0; i < atValues.length; ++i) if (!prefix || atValues[i].indexOf(prefix) == 0)
|
||||
for (var i = 0; i < atValues.length; ++i) if (!prefix || atValues[i].lastIndexOf(prefix, 0) == 0)
|
||||
result.push(quote + atValues[i] + quote);
|
||||
} else { // An attribute name
|
||||
if (token.type == "attribute") {
|
||||
prefix = token.string;
|
||||
replaceToken = true;
|
||||
}
|
||||
for (var attr in attrs) if (attrs.hasOwnProperty(attr) && (!prefix || attr.indexOf(prefix) == 0))
|
||||
for (var attr in attrs) if (attrs.hasOwnProperty(attr) && (!prefix || attr.lastIndexOf(prefix, 0) == 0))
|
||||
result.push(attr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
padding: 2px 5px;
|
||||
position: fixed;
|
||||
white-space: pre;
|
||||
white-space: pre-wrap;
|
||||
z-index: 100;
|
||||
max-width: 600px;
|
||||
opacity: 0;
|
||||
|
||||
+1
-1
@@ -112,7 +112,7 @@
|
||||
if (options.async)
|
||||
options.getAnnotations(cm, updateLinting, options);
|
||||
else
|
||||
updateLinting(cm, options.getAnnotations(cm.getValue(), options));
|
||||
updateLinting(cm, options.getAnnotations(cm.getValue(), options.options));
|
||||
}
|
||||
|
||||
function updateLinting(cm, annotationsNotSorted) {
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
this.edit = this.mv.edit;
|
||||
this.orig = CodeMirror(pane, copyObj({value: orig, readOnly: true}, copyObj(options)));
|
||||
|
||||
this.diff = getDiff(orig, options.value);
|
||||
this.diff = getDiff(asString(orig), asString(options.value));
|
||||
this.diffOutOfDate = false;
|
||||
|
||||
this.showDifferences = options.showDifferences !== false;
|
||||
@@ -352,6 +352,11 @@
|
||||
}
|
||||
};
|
||||
|
||||
function asString(obj) {
|
||||
if (typeof obj == "string") return obj;
|
||||
else return obj.getValue();
|
||||
}
|
||||
|
||||
// Operations on diffs
|
||||
|
||||
var dmp = new diff_match_patch();
|
||||
|
||||
@@ -47,7 +47,11 @@ CodeMirror.multiplexingMode = function(outer /*, others */) {
|
||||
return outerToken;
|
||||
} else {
|
||||
var curInner = state.innerActive, oldContent = stream.string;
|
||||
var found = indexOf(oldContent, curInner.close, stream.pos);
|
||||
if (!curInner.close && stream.sol()) {
|
||||
state.innerActive = state.inner = null;
|
||||
return this.token(stream, state);
|
||||
}
|
||||
var found = curInner.close ? indexOf(oldContent, curInner.close, stream.pos) : -1;
|
||||
if (found == stream.pos) {
|
||||
stream.match(curInner.close);
|
||||
state.innerActive = state.inner = null;
|
||||
@@ -56,8 +60,6 @@ CodeMirror.multiplexingMode = function(outer /*, others */) {
|
||||
if (found > -1) stream.string = oldContent.slice(0, found);
|
||||
var innerToken = curInner.mode.token(stream, state.inner);
|
||||
if (found > -1) stream.string = oldContent;
|
||||
var cur = stream.current(), found = cur.indexOf(curInner.close);
|
||||
if (found > -1) stream.backUp(cur.length - found);
|
||||
|
||||
if (curInner.innerStyle) {
|
||||
if (innerToken) innerToken = innerToken + ' ' + curInner.innerStyle;
|
||||
|
||||
@@ -10,6 +10,7 @@ function splitLines(string){ return string.split(/\r?\n|\r/); };
|
||||
function StringStream(string) {
|
||||
this.pos = this.start = 0;
|
||||
this.string = string;
|
||||
this.lineStart = 0;
|
||||
}
|
||||
StringStream.prototype = {
|
||||
eol: function() {return this.pos >= this.string.length;},
|
||||
@@ -41,7 +42,7 @@ StringStream.prototype = {
|
||||
if (found > -1) {this.pos = found; return true;}
|
||||
},
|
||||
backUp: function(n) {this.pos -= n;},
|
||||
column: function() {return this.start;},
|
||||
column: function() {return this.start - this.lineStart;},
|
||||
indentation: function() {return 0;},
|
||||
match: function(pattern, consume, caseInsensitive) {
|
||||
if (typeof pattern == "string") {
|
||||
@@ -58,7 +59,12 @@ StringStream.prototype = {
|
||||
return match;
|
||||
}
|
||||
},
|
||||
current: function(){return this.string.slice(this.start, this.pos);}
|
||||
current: function(){return this.string.slice(this.start, this.pos);},
|
||||
hideFirstChars: function(n, inner) {
|
||||
this.lineStart += n;
|
||||
try { return inner(); }
|
||||
finally { this.lineStart -= n; }
|
||||
}
|
||||
};
|
||||
CodeMirror.StringStream = StringStream;
|
||||
|
||||
@@ -69,17 +75,26 @@ CodeMirror.startState = function (mode, a1, a2) {
|
||||
var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.mimeModes = {};
|
||||
CodeMirror.defineMode = function (name, mode) { modes[name] = mode; };
|
||||
CodeMirror.defineMIME = function (mime, spec) { mimeModes[mime] = spec; };
|
||||
CodeMirror.getMode = function (options, spec) {
|
||||
if (typeof spec == "string" && mimeModes.hasOwnProperty(spec))
|
||||
CodeMirror.resolveMode = function(spec) {
|
||||
if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) {
|
||||
spec = mimeModes[spec];
|
||||
if (typeof spec == "string")
|
||||
var mname = spec, config = {};
|
||||
else if (spec != null)
|
||||
var mname = spec.name, config = spec;
|
||||
var mfactory = modes[mname];
|
||||
if (!mfactory) throw new Error("Unknown mode: " + spec);
|
||||
return mfactory(options, config || {});
|
||||
} else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) {
|
||||
spec = mimeModes[spec.name];
|
||||
}
|
||||
if (typeof spec == "string") return {name: spec};
|
||||
else return spec || {name: "null"};
|
||||
};
|
||||
CodeMirror.getMode = function (options, spec) {
|
||||
spec = CodeMirror.resolveMode(spec);
|
||||
var mfactory = modes[spec.name];
|
||||
if (!mfactory) throw new Error("Unknown mode: " + spec);
|
||||
return mfactory(options, spec);
|
||||
};
|
||||
CodeMirror.registerHelper = CodeMirror.registerGlobalHelper = Math.min;
|
||||
CodeMirror.defineMode("null", function() {
|
||||
return {token: function(stream) {stream.skipToEnd();}};
|
||||
});
|
||||
CodeMirror.defineMIME("text/plain", "null");
|
||||
|
||||
CodeMirror.runMode = function (string, modespec, callback, options) {
|
||||
var mode = CodeMirror.getMode({ indentUnit: 2 }, modespec);
|
||||
@@ -122,7 +137,7 @@ CodeMirror.runMode = function (string, modespec, callback, options) {
|
||||
};
|
||||
}
|
||||
|
||||
var lines = splitLines(string), state = CodeMirror.startState(mode);
|
||||
var lines = splitLines(string), state = (options && options.state) || CodeMirror.startState(mode);
|
||||
for (var i = 0, e = lines.length; i < e; ++i) {
|
||||
if (i) callback("\n");
|
||||
var stream = new CodeMirror.StringStream(lines[i]);
|
||||
|
||||
@@ -43,7 +43,7 @@ CodeMirror.runMode = function(string, modespec, callback, options) {
|
||||
};
|
||||
}
|
||||
|
||||
var lines = CodeMirror.splitLines(string), state = CodeMirror.startState(mode);
|
||||
var lines = CodeMirror.splitLines(string), state = (options && options.state) || CodeMirror.startState(mode);
|
||||
for (var i = 0, e = lines.length; i < e; ++i) {
|
||||
if (i) callback("\n");
|
||||
var stream = new CodeMirror.StringStream(lines[i]);
|
||||
|
||||
@@ -5,6 +5,7 @@ function splitLines(string){ return string.split(/\r?\n|\r/); };
|
||||
function StringStream(string) {
|
||||
this.pos = this.start = 0;
|
||||
this.string = string;
|
||||
this.lineStart = 0;
|
||||
}
|
||||
StringStream.prototype = {
|
||||
eol: function() {return this.pos >= this.string.length;},
|
||||
@@ -36,7 +37,7 @@ StringStream.prototype = {
|
||||
if (found > -1) {this.pos = found; return true;}
|
||||
},
|
||||
backUp: function(n) {this.pos -= n;},
|
||||
column: function() {return this.start;},
|
||||
column: function() {return this.start - this.lineStart;},
|
||||
indentation: function() {return 0;},
|
||||
match: function(pattern, consume, caseInsensitive) {
|
||||
if (typeof pattern == "string") {
|
||||
@@ -53,7 +54,12 @@ StringStream.prototype = {
|
||||
return match;
|
||||
}
|
||||
},
|
||||
current: function(){return this.string.slice(this.start, this.pos);}
|
||||
current: function(){return this.string.slice(this.start, this.pos);},
|
||||
hideFirstChars: function(n, inner) {
|
||||
this.lineStart += n;
|
||||
try { return inner(); }
|
||||
finally { this.lineStart -= n; }
|
||||
}
|
||||
};
|
||||
exports.StringStream = StringStream;
|
||||
|
||||
@@ -76,21 +82,26 @@ exports.defineMode("null", function() {
|
||||
});
|
||||
exports.defineMIME("text/plain", "null");
|
||||
|
||||
exports.getMode = function(options, spec) {
|
||||
if (typeof spec == "string" && mimeModes.hasOwnProperty(spec))
|
||||
exports.resolveMode = function(spec) {
|
||||
if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) {
|
||||
spec = mimeModes[spec];
|
||||
if (typeof spec == "string")
|
||||
var mname = spec, config = {};
|
||||
else if (spec != null)
|
||||
var mname = spec.name, config = spec;
|
||||
var mfactory = modes[mname];
|
||||
if (!mfactory) throw new Error("Unknown mode: " + spec);
|
||||
return mfactory(options, config || {});
|
||||
} else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) {
|
||||
spec = mimeModes[spec.name];
|
||||
}
|
||||
if (typeof spec == "string") return {name: spec};
|
||||
else return spec || {name: "null"};
|
||||
};
|
||||
exports.getMode = function(options, spec) {
|
||||
spec = exports.resolveMode(mimeModes[spec]);
|
||||
var mfactory = modes[spec.name];
|
||||
if (!mfactory) throw new Error("Unknown mode: " + spec);
|
||||
return mfactory(options, spec);
|
||||
};
|
||||
exports.registerHelper = exports.registerGlobalHelper = Math.min;
|
||||
|
||||
exports.runMode = function(string, modespec, callback) {
|
||||
var mode = exports.getMode({indentUnit: 2}, modespec);
|
||||
var lines = splitLines(string), state = exports.startState(mode);
|
||||
var lines = splitLines(string), state = (options && options.state) || exports.startState(mode);
|
||||
for (var i = 0, e = lines.length; i < e; ++i) {
|
||||
if (i) callback("\n");
|
||||
var stream = new exports.StringStream(lines[i]);
|
||||
|
||||
+24
-9
@@ -7,7 +7,15 @@
|
||||
// Ctrl-G.
|
||||
|
||||
(function() {
|
||||
function searchOverlay(query) {
|
||||
function searchOverlay(query, caseInsensitive) {
|
||||
var startChar;
|
||||
if (typeof query == "string") {
|
||||
startChar = query.charAt(0);
|
||||
query = new RegExp("^" + query.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"),
|
||||
caseInsensitive ? "i" : "");
|
||||
} else {
|
||||
query = new RegExp("^(?:" + query.source + ")", query.ignoreCase ? "i" : "");
|
||||
}
|
||||
if (typeof query == "string") return {token: function(stream) {
|
||||
if (stream.match(query)) return "searching";
|
||||
stream.next();
|
||||
@@ -17,6 +25,8 @@
|
||||
if (stream.match(query)) return "searching";
|
||||
while (!stream.eol()) {
|
||||
stream.next();
|
||||
if (startChar)
|
||||
stream.skipTo(startChar) || stream.skipToEnd();
|
||||
if (stream.match(query, false)) break;
|
||||
}
|
||||
}};
|
||||
@@ -29,13 +39,16 @@
|
||||
function getSearchState(cm) {
|
||||
return cm.state.search || (cm.state.search = new SearchState());
|
||||
}
|
||||
function queryCaseInsensitive(query) {
|
||||
return typeof query == "string" && query == query.toLowerCase();
|
||||
}
|
||||
function getSearchCursor(cm, query, pos) {
|
||||
// Heuristic: if the query string is all lowercase, do a case insensitive search.
|
||||
return cm.getSearchCursor(query, pos, typeof query == "string" && query == query.toLowerCase());
|
||||
return cm.getSearchCursor(query, pos, queryCaseInsensitive(query));
|
||||
}
|
||||
function dialog(cm, text, shortText, f) {
|
||||
if (cm.openDialog) cm.openDialog(text, f);
|
||||
else f(prompt(shortText, ""));
|
||||
function dialog(cm, text, shortText, deflt, f) {
|
||||
if (cm.openDialog) cm.openDialog(text, f, {value: deflt});
|
||||
else f(prompt(shortText, deflt));
|
||||
}
|
||||
function confirmDialog(cm, text, shortText, fs) {
|
||||
if (cm.openConfirm) cm.openConfirm(text, fs);
|
||||
@@ -50,11 +63,11 @@
|
||||
function doSearch(cm, rev) {
|
||||
var state = getSearchState(cm);
|
||||
if (state.query) return findNext(cm, rev);
|
||||
dialog(cm, queryDialog, "Search for:", function(query) {
|
||||
dialog(cm, queryDialog, "Search for:", cm.getSelection(), function(query) {
|
||||
cm.operation(function() {
|
||||
if (!query || state.query) return;
|
||||
state.query = parseQuery(query);
|
||||
cm.removeOverlay(state.overlay);
|
||||
cm.removeOverlay(state.overlay, queryCaseInsensitive(state.query));
|
||||
state.overlay = searchOverlay(state.query);
|
||||
cm.addOverlay(state.overlay);
|
||||
state.posFrom = state.posTo = cm.getCursor();
|
||||
@@ -70,6 +83,7 @@
|
||||
if (!cursor.find(rev)) return;
|
||||
}
|
||||
cm.setSelection(cursor.from(), cursor.to());
|
||||
cm.scrollIntoView({from: cursor.from(), to: cursor.to()});
|
||||
state.posFrom = cursor.from(); state.posTo = cursor.to();
|
||||
});}
|
||||
function clearSearch(cm) {cm.operation(function() {
|
||||
@@ -84,10 +98,10 @@
|
||||
var replacementQueryDialog = 'With: <input type="text" style="width: 10em"/>';
|
||||
var doReplaceConfirm = "Replace? <button>Yes</button> <button>No</button> <button>Stop</button>";
|
||||
function replace(cm, all) {
|
||||
dialog(cm, replaceQueryDialog, "Replace:", function(query) {
|
||||
dialog(cm, replaceQueryDialog, "Replace:", cm.getSelection(), function(query) {
|
||||
if (!query) return;
|
||||
query = parseQuery(query);
|
||||
dialog(cm, replacementQueryDialog, "Replace with:", function(text) {
|
||||
dialog(cm, replacementQueryDialog, "Replace with:", "", function(text) {
|
||||
if (all) {
|
||||
cm.operation(function() {
|
||||
for (var cursor = getSearchCursor(cm, query); cursor.findNext();) {
|
||||
@@ -108,6 +122,7 @@
|
||||
(start && cursor.from().line == start.line && cursor.from().ch == start.ch)) return;
|
||||
}
|
||||
cm.setSelection(cursor.from(), cursor.to());
|
||||
cm.scrollIntoView({from: cursor.from(), to: cursor.to()});
|
||||
confirmDialog(cm, doReplaceConfirm, "Replace?",
|
||||
[function() {doReplace(match);}, advance]);
|
||||
};
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
match: match};
|
||||
};
|
||||
} else { // String query
|
||||
var origQuery = query;
|
||||
if (caseFold) query = query.toLowerCase();
|
||||
var fold = caseFold ? function(str){return str.toLowerCase();} : function(str){return str;};
|
||||
var target = query.split("\n");
|
||||
@@ -58,33 +59,45 @@
|
||||
this.matches = function() {};
|
||||
} else {
|
||||
this.matches = function(reverse, pos) {
|
||||
var line = fold(doc.getLine(pos.line)), 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: Pos(pos.line, match),
|
||||
to: Pos(pos.line, match + len)};
|
||||
if (reverse) {
|
||||
var orig = doc.getLine(pos.line).slice(0, pos.ch), line = fold(orig);
|
||||
var match = line.lastIndexOf(query);
|
||||
if (match > -1) {
|
||||
match = adjustPos(orig, line, match);
|
||||
return {from: Pos(pos.line, match), to: Pos(pos.line, match + origQuery.length)};
|
||||
}
|
||||
} else {
|
||||
var orig = doc.getLine(pos.line).slice(pos.ch), line = fold(orig);
|
||||
var match = line.indexOf(query);
|
||||
if (match > -1) {
|
||||
match = adjustPos(orig, line, match) + pos.ch;
|
||||
return {from: Pos(pos.line, match), to: Pos(pos.line, match + origQuery.length)};
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
} else {
|
||||
var origTarget = origQuery.split("\n");
|
||||
this.matches = function(reverse, pos) {
|
||||
var ln = pos.line, idx = (reverse ? target.length - 1 : 0), match = target[idx], line = fold(doc.getLine(ln));
|
||||
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 == doc.lineCount() - 1) return;
|
||||
line = fold(doc.getLine(ln += reverse ? -1 : 1));
|
||||
match = target[reverse ? --idx : ++idx];
|
||||
if (idx > 0 && idx < target.length - 1) {
|
||||
if (line != match) return;
|
||||
else continue;
|
||||
}
|
||||
var offsetB = (reverse ? line.lastIndexOf(match) : line.indexOf(match) + match.length);
|
||||
if (reverse ? offsetB != line.length - match.length : offsetB != match.length)
|
||||
return;
|
||||
var start = Pos(pos.line, offsetA), end = Pos(ln, offsetB);
|
||||
return {from: reverse ? end : start, to: reverse ? start : end};
|
||||
var last = target.length - 1;
|
||||
if (reverse) {
|
||||
if (pos.line - (target.length - 1) < doc.firstLine()) return;
|
||||
if (fold(doc.getLine(pos.line).slice(0, origTarget[last].length)) != target[target.length - 1]) return;
|
||||
var to = Pos(pos.line, origTarget[last].length);
|
||||
for (var ln = pos.line - 1, i = last - 1; i >= 1; --i, --ln)
|
||||
if (target[i] != fold(doc.getLine(ln))) return;
|
||||
var line = doc.getLine(ln), cut = line.length - origTarget[0].length;
|
||||
if (fold(line.slice(cut)) != target[0]) return;
|
||||
return {from: Pos(ln, cut), to: to};
|
||||
} else {
|
||||
if (pos.line + (target.length - 1) > doc.lastLine()) return;
|
||||
var line = doc.getLine(pos.line), cut = line.length - origTarget[0].length;
|
||||
if (fold(line.slice(cut)) != target[0]) return;
|
||||
var from = Pos(pos.line, cut);
|
||||
for (var ln = pos.line + 1, i = 1; i < last; ++i, ++ln)
|
||||
if (target[i] != fold(doc.getLine(ln))) return;
|
||||
if (doc.getLine(ln).slice(0, origTarget[last].length) != target[last]) return;
|
||||
return {from: from, to: Pos(ln, origTarget[last].length)};
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -106,7 +119,6 @@
|
||||
|
||||
for (;;) {
|
||||
if (this.pos = this.matches(reverse, pos)) {
|
||||
if (!this.pos.from || !this.pos.to) { console.log(this.matches, this.pos); }
|
||||
this.atOccurrence = true;
|
||||
return this.pos.match || true;
|
||||
}
|
||||
@@ -134,6 +146,18 @@
|
||||
}
|
||||
};
|
||||
|
||||
// Maps a position in a case-folded line back to a position in the original line
|
||||
// (compensating for codepoints increasing in number during folding)
|
||||
function adjustPos(orig, folded, pos) {
|
||||
if (orig.length == folded.length) return pos;
|
||||
for (var pos1 = Math.min(pos, orig.length);;) {
|
||||
var len1 = orig.slice(0, pos1).toLowerCase().length;
|
||||
if (len1 < pos) ++pos1;
|
||||
else if (len1 > pos) --pos1;
|
||||
else return pos1;
|
||||
}
|
||||
}
|
||||
|
||||
CodeMirror.defineExtension("getSearchCursor", function(query, pos, caseFold) {
|
||||
return new SearchCursor(this.doc, query, pos, caseFold);
|
||||
});
|
||||
|
||||
@@ -12,10 +12,10 @@
|
||||
CodeMirror.defineOption("styleActiveLine", false, function(cm, val, old) {
|
||||
var prev = old && old != CodeMirror.Init;
|
||||
if (val && !prev) {
|
||||
updateActiveLine(cm);
|
||||
cm.on("cursorActivity", updateActiveLine);
|
||||
updateActiveLine(cm, cm.getCursor().line);
|
||||
cm.on("beforeSelectionChange", selectionChange);
|
||||
} else if (!val && prev) {
|
||||
cm.off("cursorActivity", updateActiveLine);
|
||||
cm.off("beforeSelectionChange", selectionChange);
|
||||
clearActiveLine(cm);
|
||||
delete cm.state.activeLine;
|
||||
}
|
||||
@@ -28,12 +28,18 @@
|
||||
}
|
||||
}
|
||||
|
||||
function updateActiveLine(cm) {
|
||||
var line = cm.getLineHandleVisualStart(cm.getCursor().line);
|
||||
function updateActiveLine(cm, selectedLine) {
|
||||
var line = cm.getLineHandleVisualStart(selectedLine);
|
||||
if (cm.state.activeLine == line) return;
|
||||
clearActiveLine(cm);
|
||||
cm.addLineClass(line, "wrap", WRAP_CLASS);
|
||||
cm.addLineClass(line, "background", BACK_CLASS);
|
||||
cm.state.activeLine = line;
|
||||
cm.operation(function() {
|
||||
clearActiveLine(cm);
|
||||
cm.addLineClass(line, "wrap", WRAP_CLASS);
|
||||
cm.addLineClass(line, "background", BACK_CLASS);
|
||||
cm.state.activeLine = line;
|
||||
});
|
||||
}
|
||||
|
||||
function selectionChange(cm, sel) {
|
||||
updateActiveLine(cm, sel.head.line);
|
||||
}
|
||||
})();
|
||||
|
||||
+12
-1
@@ -201,6 +201,11 @@
|
||||
cm.on("change", function() { cm.setExtending(false); });
|
||||
}
|
||||
|
||||
function clearMark(cm) {
|
||||
cm.setExtending(false);
|
||||
cm.setCursor(cm.getCursor());
|
||||
}
|
||||
|
||||
function getInput(cm, msg, f) {
|
||||
if (cm.openDialog)
|
||||
cm.openDialog(msg + ": <input type=\"text\" style=\"width: 10em\"/>", f, {bottom: true});
|
||||
@@ -234,6 +239,11 @@
|
||||
}
|
||||
}
|
||||
|
||||
function quit(cm) {
|
||||
cm.execCommand("clearSearch");
|
||||
clearMark(cm);
|
||||
}
|
||||
|
||||
// Actual keymap
|
||||
|
||||
var keyMap = CodeMirror.keyMap.emacs = {
|
||||
@@ -249,6 +259,7 @@
|
||||
}),
|
||||
"Alt-W": function(cm) {
|
||||
addToRing(cm.getSelection());
|
||||
clearMark(cm);
|
||||
},
|
||||
"Ctrl-Y": function(cm) {
|
||||
var start = cm.getCursor();
|
||||
@@ -334,7 +345,7 @@
|
||||
"Ctrl-/": repeated("undo"), "Shift-Ctrl--": repeated("undo"),
|
||||
"Ctrl-Z": repeated("undo"), "Cmd-Z": repeated("undo"),
|
||||
"Shift-Alt-,": "goDocStart", "Shift-Alt-.": "goDocEnd",
|
||||
"Ctrl-S": "findNext", "Ctrl-R": "findPrev", "Ctrl-G": "clearSearch", "Shift-Alt-5": "replace",
|
||||
"Ctrl-S": "findNext", "Ctrl-R": "findPrev", "Ctrl-G": quit, "Shift-Alt-5": "replace",
|
||||
"Alt-/": "autocomplete",
|
||||
"Ctrl-J": "newlineAndIndent", "Enter": false, "Tab": "indentAuto",
|
||||
|
||||
|
||||
+165
-46
@@ -76,12 +76,15 @@
|
||||
{ keys: ['<C-p>'], type: 'keyToKey', toKeys: ['k'] },
|
||||
{ keys: ['C-['], type: 'keyToKey', toKeys: ['<Esc>'] },
|
||||
{ keys: ['<C-c>'], type: 'keyToKey', toKeys: ['<Esc>'] },
|
||||
{ keys: ['s'], type: 'keyToKey', toKeys: ['c', 'l'] },
|
||||
{ keys: ['S'], type: 'keyToKey', toKeys: ['c', 'c'] },
|
||||
{ keys: ['s'], type: 'keyToKey', toKeys: ['c', 'l'], context: 'normal' },
|
||||
{ keys: ['s'], type: 'keyToKey', toKeys: ['x', 'i'], context: 'visual'},
|
||||
{ keys: ['S'], type: 'keyToKey', toKeys: ['c', 'c'], context: 'normal' },
|
||||
{ keys: ['S'], type: 'keyToKey', toKeys: ['d', 'c', 'c'], context: 'visual' },
|
||||
{ keys: ['<Home>'], type: 'keyToKey', toKeys: ['0'] },
|
||||
{ keys: ['<End>'], type: 'keyToKey', toKeys: ['$'] },
|
||||
{ keys: ['<PageUp>'], type: 'keyToKey', toKeys: ['<C-b>'] },
|
||||
{ keys: ['<PageDown>'], type: 'keyToKey', toKeys: ['<C-f>'] },
|
||||
{ keys: ['<CR>'], type: 'keyToKey', toKeys: ['j', '^'], context: 'normal' },
|
||||
// Motions
|
||||
{ keys: ['H'], type: 'motion',
|
||||
motion: 'moveToTopLine',
|
||||
@@ -245,6 +248,12 @@
|
||||
actionArgs: { forward: true }},
|
||||
{ keys: ['<C-o>'], type: 'action', action: 'jumpListWalk',
|
||||
actionArgs: { forward: false }},
|
||||
{ keys: ['<C-e>'], type: 'action',
|
||||
action: 'scroll',
|
||||
actionArgs: { forward: true, linewise: true }},
|
||||
{ keys: ['<C-y>'], type: 'action',
|
||||
action: 'scroll',
|
||||
actionArgs: { forward: false, linewise: true }},
|
||||
{ keys: ['a'], type: 'action', action: 'enterInsertMode', isEdit: true,
|
||||
actionArgs: { insertAt: 'charAfter' }},
|
||||
{ keys: ['A'], type: 'action', action: 'enterInsertMode', isEdit: true,
|
||||
@@ -322,12 +331,16 @@
|
||||
CodeMirror.defineOption('vimMode', false, function(cm, val) {
|
||||
if (val) {
|
||||
cm.setOption('keyMap', 'vim');
|
||||
cm.setOption('disableInput', true);
|
||||
CodeMirror.signal(cm, "vim-mode-change", {mode: "normal"});
|
||||
cm.on('beforeSelectionChange', beforeSelectionChange);
|
||||
maybeInitVimState(cm);
|
||||
CodeMirror.on(cm.getInputField(), 'paste', getOnPasteFn(cm));
|
||||
} else if (cm.state.vim) {
|
||||
cm.setOption('keyMap', 'default');
|
||||
cm.setOption('disableInput', false);
|
||||
cm.off('beforeSelectionChange', beforeSelectionChange);
|
||||
CodeMirror.off(cm.getInputField(), 'paste', getOnPasteFn(cm));
|
||||
cm.state.vim = null;
|
||||
}
|
||||
});
|
||||
@@ -340,6 +353,18 @@
|
||||
head.ch--;
|
||||
}
|
||||
}
|
||||
function getOnPasteFn(cm) {
|
||||
var vim = cm.state.vim;
|
||||
if (!vim.onPasteFn) {
|
||||
vim.onPasteFn = function() {
|
||||
if (!vim.insertMode) {
|
||||
cm.setCursor(offsetCursor(cm.getCursor(), 0, 1));
|
||||
actions.enterInsertMode(cm, {}, vim);
|
||||
}
|
||||
};
|
||||
}
|
||||
return vim.onPasteFn;
|
||||
}
|
||||
|
||||
var numberRegex = /[\d]/;
|
||||
var wordRegexp = [(/\w/), (/[^\w\s]/)], bigWordRegexp = [(/\S/)];
|
||||
@@ -547,9 +572,9 @@
|
||||
maybeInitVimState_: maybeInitVimState,
|
||||
|
||||
InsertModeKey: InsertModeKey,
|
||||
map: function(lhs, rhs) {
|
||||
map: function(lhs, rhs, ctx) {
|
||||
// Add user defined key bindings.
|
||||
exCommandDispatcher.map(lhs, rhs);
|
||||
exCommandDispatcher.map(lhs, rhs, ctx);
|
||||
},
|
||||
defineEx: function(name, prefix, func){
|
||||
if (name.indexOf(prefix) !== 0) {
|
||||
@@ -609,6 +634,9 @@
|
||||
}
|
||||
commandDispatcher.processCommand(cm, vim, command);
|
||||
}
|
||||
},
|
||||
handleEx: function(cm, input) {
|
||||
exCommandDispatcher.processCommand(cm, input);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -695,6 +723,9 @@
|
||||
if (linewise && text.charAt(0) == '\n') {
|
||||
text = text.slice(1) + '\n';
|
||||
}
|
||||
if(linewise && text.charAt(text.length - 1) !== '\n'){
|
||||
text += '\n';
|
||||
}
|
||||
// Lowercase and uppercase registers refer to the same register.
|
||||
// Uppercase just means append.
|
||||
var register = this.isValidRegister(registerName) ?
|
||||
@@ -766,44 +797,80 @@
|
||||
matchCommand: function(key, keyMap, vim) {
|
||||
var inputState = vim.inputState;
|
||||
var keys = inputState.keyBuffer.concat(key);
|
||||
var matchedCommands = [];
|
||||
var selectedCharacter;
|
||||
for (var i = 0; i < keyMap.length; i++) {
|
||||
var command = keyMap[i];
|
||||
if (matchKeysPartial(keys, command.keys)) {
|
||||
if (keys.length < command.keys.length) {
|
||||
// Matches part of a multi-key command. Buffer and wait for next
|
||||
// stroke.
|
||||
inputState.keyBuffer.push(key);
|
||||
return null;
|
||||
}
|
||||
if (inputState.operator && command.type == 'action') {
|
||||
// Ignore matched action commands after an operator. Operators
|
||||
// only operate on motions. This check is really for text
|
||||
// objects since aW, a[ etcs conflicts with a.
|
||||
continue;
|
||||
}
|
||||
// Matches whole comand. Return the command.
|
||||
// Match commands that take <character> as an argument.
|
||||
if (command.keys[keys.length - 1] == 'character') {
|
||||
inputState.selectedCharacter = keys[keys.length - 1];
|
||||
if(inputState.selectedCharacter.length>1){
|
||||
switch(inputState.selectedCharacter){
|
||||
selectedCharacter = keys[keys.length - 1];
|
||||
if(selectedCharacter.length>1){
|
||||
switch(selectedCharacter){
|
||||
case '<CR>':
|
||||
inputState.selectedCharacter='\n';
|
||||
selectedCharacter='\n';
|
||||
break;
|
||||
case '<Space>':
|
||||
inputState.selectedCharacter=' ';
|
||||
selectedCharacter=' ';
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Add the command to the list of matched commands. Choose the best
|
||||
// command later.
|
||||
matchedCommands.push(command);
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the command if it is a full match, or null if not.
|
||||
function getFullyMatchedCommandOrNull(command) {
|
||||
if (keys.length < command.keys.length) {
|
||||
// Matches part of a multi-key command. Buffer and wait for next
|
||||
// stroke.
|
||||
inputState.keyBuffer.push(key);
|
||||
return null;
|
||||
} else {
|
||||
if (command.keys[keys.length - 1] == 'character') {
|
||||
inputState.selectedCharacter = selectedCharacter;
|
||||
}
|
||||
// Clear the buffer since a full match was found.
|
||||
inputState.keyBuffer = [];
|
||||
return command;
|
||||
}
|
||||
}
|
||||
// Clear the buffer since there are no partial matches.
|
||||
inputState.keyBuffer = [];
|
||||
return null;
|
||||
|
||||
if (!matchedCommands.length) {
|
||||
// Clear the buffer since there were no matches.
|
||||
inputState.keyBuffer = [];
|
||||
return null;
|
||||
} else if (matchedCommands.length == 1) {
|
||||
return getFullyMatchedCommandOrNull(matchedCommands[0]);
|
||||
} else {
|
||||
// Find the best match in the list of matchedCommands.
|
||||
var context = vim.visualMode ? 'visual' : 'normal';
|
||||
var bestMatch; // Default to first in the list.
|
||||
for (var i = 0; i < matchedCommands.length; i++) {
|
||||
var current = matchedCommands[i];
|
||||
if (current.context == context) {
|
||||
bestMatch = current;
|
||||
break;
|
||||
} else if (!bestMatch && !current.context) {
|
||||
// Only set an imperfect match to best match if no best match is
|
||||
// set and the imperfect match is not restricted to another
|
||||
// context.
|
||||
bestMatch = current;
|
||||
}
|
||||
}
|
||||
return getFullyMatchedCommandOrNull(bestMatch);
|
||||
}
|
||||
},
|
||||
processCommand: function(cm, vim, command) {
|
||||
vim.inputState.repeatOverride = command.repeatOverride;
|
||||
@@ -1598,6 +1665,43 @@
|
||||
markPos = markPos ? markPos : cm.getCursor();
|
||||
cm.setCursor(markPos);
|
||||
},
|
||||
scroll: function(cm, actionArgs, vim) {
|
||||
if (vim.visualMode) {
|
||||
return;
|
||||
}
|
||||
var repeat = actionArgs.repeat || 1;
|
||||
var lineHeight = cm.defaultTextHeight();
|
||||
var top = cm.getScrollInfo().top;
|
||||
var delta = lineHeight * repeat;
|
||||
var newPos = actionArgs.forward ? top + delta : top - delta;
|
||||
var cursor = cm.getCursor();
|
||||
var cursorCoords = cm.charCoords(cursor, 'local');
|
||||
if (actionArgs.forward) {
|
||||
if (newPos > cursorCoords.top) {
|
||||
cursor.line += (newPos - cursorCoords.top) / lineHeight;
|
||||
cursor.line = Math.ceil(cursor.line);
|
||||
cm.setCursor(cursor);
|
||||
cursorCoords = cm.charCoords(cursor, 'local');
|
||||
cm.scrollTo(null, cursorCoords.top);
|
||||
} else {
|
||||
// Cursor stays within bounds. Just reposition the scroll window.
|
||||
cm.scrollTo(null, newPos);
|
||||
}
|
||||
} else {
|
||||
var newBottom = newPos + cm.getScrollInfo().clientHeight;
|
||||
if (newBottom < cursorCoords.bottom) {
|
||||
cursor.line -= (cursorCoords.bottom - newBottom) / lineHeight;
|
||||
cursor.line = Math.floor(cursor.line);
|
||||
cm.setCursor(cursor);
|
||||
cursorCoords = cm.charCoords(cursor, 'local');
|
||||
cm.scrollTo(
|
||||
null, cursorCoords.bottom - cm.getScrollInfo().clientHeight);
|
||||
} else {
|
||||
// Cursor stays within bounds. Just reposition the scroll window.
|
||||
cm.scrollTo(null, newPos);
|
||||
}
|
||||
}
|
||||
},
|
||||
scrollToCursor: function(cm, actionArgs) {
|
||||
var lineNum = cm.getCursor().line;
|
||||
var charCoords = cm.charCoords({line: lineNum, ch: 0}, 'local');
|
||||
@@ -1653,6 +1757,7 @@
|
||||
cm.setCursor(motions.moveToFirstNonWhiteSpaceCharacter(cm));
|
||||
}
|
||||
cm.setOption('keyMap', 'vim-insert');
|
||||
cm.setOption('disableInput', false);
|
||||
if (actionArgs && actionArgs.replace) {
|
||||
// Handle Replace-mode as a special case of insert mode.
|
||||
cm.toggleOverwrite(true);
|
||||
@@ -2688,10 +2793,9 @@
|
||||
return regexp;
|
||||
}
|
||||
function showConfirm(cm, text) {
|
||||
if (cm.openConfirm) {
|
||||
cm.openConfirm('<span style="color: red">' + text +
|
||||
'</span> <button type="button">OK</button>', function() {},
|
||||
{bottom: true});
|
||||
if (cm.openNotification) {
|
||||
cm.openNotification('<span style="color: red">' + text + '</span>',
|
||||
{bottom: true, duration: 5000});
|
||||
} else {
|
||||
alert(text);
|
||||
}
|
||||
@@ -2859,14 +2963,16 @@
|
||||
// pair of commands that have a shared prefix, at least one of their
|
||||
// shortNames must not match the prefix of the other command.
|
||||
var defaultExCommandMap = [
|
||||
{ name: 'map', type: 'builtIn' },
|
||||
{ name: 'write', shortName: 'w', type: 'builtIn' },
|
||||
{ name: 'undo', shortName: 'u', type: 'builtIn' },
|
||||
{ name: 'redo', shortName: 'red', type: 'builtIn' },
|
||||
{ name: 'sort', shortName: 'sor', type: 'builtIn'},
|
||||
{ name: 'substitute', shortName: 's', type: 'builtIn'},
|
||||
{ name: 'nohlsearch', shortName: 'noh', type: 'builtIn'},
|
||||
{ name: 'delmarks', shortName: 'delm', type: 'builtin'}
|
||||
{ name: 'map' },
|
||||
{ name: 'nmap', shortName: 'nm' },
|
||||
{ name: 'vmap', shortName: 'vm' },
|
||||
{ name: 'write', shortName: 'w' },
|
||||
{ name: 'undo', shortName: 'u' },
|
||||
{ name: 'redo', shortName: 'red' },
|
||||
{ name: 'sort', shortName: 'sor' },
|
||||
{ name: 'substitute', shortName: 's' },
|
||||
{ name: 'nohlsearch', shortName: 'noh' },
|
||||
{ name: 'delmarks', shortName: 'delm' }
|
||||
];
|
||||
Vim.ExCommandDispatcher = function() {
|
||||
this.buildCommandMap_();
|
||||
@@ -2918,6 +3024,7 @@
|
||||
exCommands[commandName](cm, params);
|
||||
} catch(e) {
|
||||
showConfirm(cm, e);
|
||||
throw e;
|
||||
}
|
||||
},
|
||||
parseInput_: function(cm, inputStream, result) {
|
||||
@@ -3000,8 +3107,9 @@
|
||||
this.commandMap_[key] = command;
|
||||
}
|
||||
},
|
||||
map: function(lhs, rhs) {
|
||||
map: function(lhs, rhs, ctx) {
|
||||
if (lhs != ':' && lhs.charAt(0) == ':') {
|
||||
if (ctx) { throw Error('Mode not supported for ex mappings'); }
|
||||
var commandName = lhs.substring(1);
|
||||
if (rhs != ':' && rhs.charAt(0) == ':') {
|
||||
// Ex to Ex mapping
|
||||
@@ -3021,17 +3129,21 @@
|
||||
} else {
|
||||
if (rhs != ':' && rhs.charAt(0) == ':') {
|
||||
// Key to Ex mapping.
|
||||
defaultKeymap.unshift({
|
||||
var mapping = {
|
||||
keys: parseKeyString(lhs),
|
||||
type: 'keyToEx',
|
||||
exArgs: { input: rhs.substring(1) }});
|
||||
exArgs: { input: rhs.substring(1) }};
|
||||
if (ctx) { mapping.context = ctx; }
|
||||
defaultKeymap.unshift(mapping);
|
||||
} else {
|
||||
// Key to key mapping
|
||||
defaultKeymap.unshift({
|
||||
var mapping = {
|
||||
keys: parseKeyString(lhs),
|
||||
type: 'keyToKey',
|
||||
toKeys: parseKeyString(rhs)
|
||||
});
|
||||
};
|
||||
if (ctx) { mapping.context = ctx; }
|
||||
defaultKeymap.unshift(mapping);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3053,7 +3165,7 @@
|
||||
}
|
||||
|
||||
var exCommands = {
|
||||
map: function(cm, params) {
|
||||
map: function(cm, params, ctx) {
|
||||
var mapArgs = params.args;
|
||||
if (!mapArgs || mapArgs.length < 2) {
|
||||
if (cm) {
|
||||
@@ -3061,8 +3173,10 @@
|
||||
}
|
||||
return;
|
||||
}
|
||||
exCommandDispatcher.map(mapArgs[0], mapArgs[1], cm);
|
||||
exCommandDispatcher.map(mapArgs[0], mapArgs[1], ctx);
|
||||
},
|
||||
nmap: function(cm, params) { this.map(cm, params, 'normal'); },
|
||||
vmap: function(cm, params) { this.map(cm, params, 'visual'); },
|
||||
move: function(cm, params) {
|
||||
commandDispatcher.processCommand(cm, cm.state.vim, {
|
||||
type: 'motion',
|
||||
@@ -3078,7 +3192,7 @@
|
||||
var args = new CodeMirror.StringStream(params.argString);
|
||||
if (args.eat('!')) { reverse = true; }
|
||||
if (args.eol()) { return; }
|
||||
if (!args.eatSpace()) { throw new Error('invalid arguments ' + args.match(/.*/)[0]); }
|
||||
if (!args.eatSpace()) { return 'Invalid arguments'; }
|
||||
var opts = args.match(/[a-z]+/);
|
||||
if (opts) {
|
||||
opts = opts[0];
|
||||
@@ -3087,13 +3201,17 @@
|
||||
var decimal = opts.indexOf('d') != -1 && 1;
|
||||
var hex = opts.indexOf('x') != -1 && 1;
|
||||
var octal = opts.indexOf('o') != -1 && 1;
|
||||
if (decimal + hex + octal > 1) { throw new Error('invalid arguments'); }
|
||||
if (decimal + hex + octal > 1) { return 'Invalid arguments'; }
|
||||
number = decimal && 'decimal' || hex && 'hex' || octal && 'octal';
|
||||
}
|
||||
if (args.eatSpace() && args.match(/\/.*\//)) { throw new Error('patterns not supported'); }
|
||||
if (args.eatSpace() && args.match(/\/.*\//)) { 'patterns not supported'; }
|
||||
}
|
||||
}
|
||||
parseArgs();
|
||||
var err = parseArgs();
|
||||
if (err) {
|
||||
showConfirm(cm, err + ': ' + params.argString);
|
||||
return;
|
||||
}
|
||||
var lineStart = params.line || cm.firstLine();
|
||||
var lineEnd = params.lineEnd || params.line || cm.lastLine();
|
||||
if (lineStart == lineEnd) { return; }
|
||||
@@ -3214,13 +3332,13 @@
|
||||
clearSearchHighlight(cm);
|
||||
},
|
||||
delmarks: function(cm, params) {
|
||||
if (!params.argString || !params.argString.trim()) {
|
||||
if (!params.argString || !trim(params.argString)) {
|
||||
showConfirm(cm, 'Argument required');
|
||||
return;
|
||||
}
|
||||
|
||||
var state = cm.state.vim;
|
||||
var stream = new CodeMirror.StringStream(params.argString.trim());
|
||||
var stream = new CodeMirror.StringStream(trim(params.argString));
|
||||
while (!stream.eol()) {
|
||||
stream.eatSpace();
|
||||
|
||||
@@ -3357,7 +3475,8 @@
|
||||
// Actually do replace.
|
||||
next();
|
||||
if (done) {
|
||||
throw new Error('No matches for ' + query.source);
|
||||
showConfirm(cm, 'No matches for ' + query.source);
|
||||
return;
|
||||
}
|
||||
if (!confirm) {
|
||||
replaceAll();
|
||||
@@ -3408,7 +3527,6 @@
|
||||
|
||||
var cmToVimKeymap = {
|
||||
'nofallthrough': true,
|
||||
'disableInput': true,
|
||||
'style': 'fat-cursor'
|
||||
};
|
||||
function bindKeys(keys, modifier) {
|
||||
@@ -3455,6 +3573,7 @@
|
||||
cm.setCursor(cm.getCursor().line, cm.getCursor().ch-1, true);
|
||||
vim.insertMode = false;
|
||||
cm.setOption('keyMap', 'vim');
|
||||
cm.setOption('disableInput', true);
|
||||
cm.toggleOverwrite(false); // exit replace mode if we were in it.
|
||||
CodeMirror.signal(cm, "vim-mode-change", {mode: "normal"});
|
||||
}
|
||||
|
||||
+1
-1
@@ -74,7 +74,6 @@
|
||||
.cm-s-default .cm-string {color: #a11;}
|
||||
.cm-s-default .cm-string-2 {color: #f50;}
|
||||
.cm-s-default .cm-meta {color: #555;}
|
||||
.cm-s-default .cm-error {color: #f00;}
|
||||
.cm-s-default .cm-qualifier {color: #555;}
|
||||
.cm-s-default .cm-builtin {color: #30a;}
|
||||
.cm-s-default .cm-bracket {color: #997;}
|
||||
@@ -91,6 +90,7 @@
|
||||
.cm-em {font-style: italic;}
|
||||
.cm-link {text-decoration: underline;}
|
||||
|
||||
.cm-s-default .cm-error {color: #f00;}
|
||||
.cm-invalidchar {color: #f00;}
|
||||
|
||||
div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}
|
||||
|
||||
+333
-171
File diff suppressed because it is too large
Load Diff
+346
-290
@@ -4,86 +4,79 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
||||
if (!parserConfig.propertyKeywords) parserConfig = CodeMirror.resolveMode("text/css");
|
||||
|
||||
var indentUnit = config.indentUnit,
|
||||
hooks = parserConfig.hooks || {},
|
||||
atMediaTypes = parserConfig.atMediaTypes || {},
|
||||
atMediaFeatures = parserConfig.atMediaFeatures || {},
|
||||
tokenHooks = parserConfig.tokenHooks,
|
||||
mediaTypes = parserConfig.mediaTypes || {},
|
||||
mediaFeatures = parserConfig.mediaFeatures || {},
|
||||
propertyKeywords = parserConfig.propertyKeywords || {},
|
||||
colorKeywords = parserConfig.colorKeywords || {},
|
||||
valueKeywords = parserConfig.valueKeywords || {},
|
||||
allowNested = !!parserConfig.allowNested,
|
||||
type = null;
|
||||
fontProperties = parserConfig.fontProperties || {},
|
||||
allowNested = parserConfig.allowNested;
|
||||
|
||||
var type, override;
|
||||
function ret(style, tp) { type = tp; return style; }
|
||||
|
||||
// Tokenizers
|
||||
|
||||
function tokenBase(stream, state) {
|
||||
var ch = stream.next();
|
||||
if (hooks[ch]) {
|
||||
// result[0] is style and result[1] is type
|
||||
var result = hooks[ch](stream, state);
|
||||
if (tokenHooks[ch]) {
|
||||
var result = tokenHooks[ch](stream, state);
|
||||
if (result !== false) return result;
|
||||
}
|
||||
if (ch == "@") {stream.eatWhile(/[\w\\\-]/); return ret("def", stream.current());}
|
||||
else if (ch == "=") ret(null, "compare");
|
||||
else if ((ch == "~" || ch == "|") && stream.eat("=")) return ret(null, "compare");
|
||||
else if (ch == "\"" || ch == "'") {
|
||||
if (ch == "@") {
|
||||
stream.eatWhile(/[\w\\\-]/);
|
||||
return ret("def", stream.current());
|
||||
} else if (ch == "=" || (ch == "~" || ch == "|") && stream.eat("=")) {
|
||||
return ret(null, "compare");
|
||||
} else if (ch == "\"" || ch == "'") {
|
||||
state.tokenize = tokenString(ch);
|
||||
return state.tokenize(stream, state);
|
||||
}
|
||||
else if (ch == "#") {
|
||||
} else if (ch == "#") {
|
||||
stream.eatWhile(/[\w\\\-]/);
|
||||
return ret("atom", "hash");
|
||||
}
|
||||
else if (ch == "!") {
|
||||
} else if (ch == "!") {
|
||||
stream.match(/^\s*\w*/);
|
||||
return ret("keyword", "important");
|
||||
}
|
||||
else if (/\d/.test(ch) || ch == "." && stream.eat(/\d/)) {
|
||||
} else if (/\d/.test(ch) || ch == "." && stream.eat(/\d/)) {
|
||||
stream.eatWhile(/[\w.%]/);
|
||||
return ret("number", "unit");
|
||||
}
|
||||
else if (ch === "-") {
|
||||
if (/\d/.test(stream.peek())) {
|
||||
} else if (ch === "-") {
|
||||
if (/[\d.]/.test(stream.peek())) {
|
||||
stream.eatWhile(/[\w.%]/);
|
||||
return ret("number", "unit");
|
||||
} else if (stream.match(/^[^-]+-/)) {
|
||||
return ret("meta", "meta");
|
||||
}
|
||||
}
|
||||
else if (/[,+>*\/]/.test(ch)) {
|
||||
} else if (/[,+>*\/]/.test(ch)) {
|
||||
return ret(null, "select-op");
|
||||
}
|
||||
else if (ch == "." && stream.match(/^-?[_a-z][_a-z0-9-]*/i)) {
|
||||
} else if (ch == "." && stream.match(/^-?[_a-z][_a-z0-9-]*/i)) {
|
||||
return ret("qualifier", "qualifier");
|
||||
}
|
||||
else if (ch == ":") {
|
||||
return ret("operator", ch);
|
||||
}
|
||||
else if (/[;{}\[\]\(\)]/.test(ch)) {
|
||||
} else if (/[:;{}\[\]\(\)]/.test(ch)) {
|
||||
return ret(null, ch);
|
||||
}
|
||||
else if (ch == "u" && stream.match("rl(")) {
|
||||
} else if (ch == "u" && stream.match("rl(")) {
|
||||
stream.backUp(1);
|
||||
state.tokenize = tokenParenthesized;
|
||||
return ret("property", "variable");
|
||||
}
|
||||
else {
|
||||
return ret("property", "word");
|
||||
} else if (/[\w\\\-]/.test(ch)) {
|
||||
stream.eatWhile(/[\w\\\-]/);
|
||||
return ret("property", "variable");
|
||||
return ret("property", "word");
|
||||
} else {
|
||||
return ret(null, null);
|
||||
}
|
||||
}
|
||||
|
||||
function tokenString(quote, nonInclusive) {
|
||||
function tokenString(quote) {
|
||||
return function(stream, state) {
|
||||
var escaped = false, ch;
|
||||
while ((ch = stream.next()) != null) {
|
||||
if (ch == quote && !escaped)
|
||||
if (ch == quote && !escaped) {
|
||||
if (quote == ")") stream.backUp(1);
|
||||
break;
|
||||
}
|
||||
escaped = !escaped && ch == "\\";
|
||||
}
|
||||
if (!escaped) {
|
||||
if (nonInclusive) stream.backUp(1);
|
||||
state.tokenize = tokenBase;
|
||||
}
|
||||
if (ch == quote || !escaped && quote != ")") state.tokenize = null;
|
||||
return ret("string", "string");
|
||||
};
|
||||
}
|
||||
@@ -91,211 +84,238 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
||||
function tokenParenthesized(stream, state) {
|
||||
stream.next(); // Must be '('
|
||||
if (!stream.match(/\s*[\"\']/, false))
|
||||
state.tokenize = tokenString(")", true);
|
||||
state.tokenize = tokenString(")");
|
||||
else
|
||||
state.tokenize = tokenBase;
|
||||
state.tokenize = null;
|
||||
return ret(null, "(");
|
||||
}
|
||||
|
||||
// Context management
|
||||
|
||||
function Context(type, indent, prev) {
|
||||
this.type = type;
|
||||
this.indent = indent;
|
||||
this.prev = prev;
|
||||
}
|
||||
|
||||
function pushContext(state, stream, type) {
|
||||
state.context = new Context(type, stream.indentation() + indentUnit, state.context);
|
||||
return type;
|
||||
}
|
||||
|
||||
function popContext(state) {
|
||||
state.context = state.context.prev;
|
||||
return state.context.type;
|
||||
}
|
||||
|
||||
function pass(type, stream, state) {
|
||||
return states[state.context.type](type, stream, state);
|
||||
}
|
||||
function popAndPass(type, stream, state, n) {
|
||||
for (var i = n || 1; i > 0; i--)
|
||||
state.context = state.context.prev;
|
||||
return pass(type, stream, state);
|
||||
}
|
||||
|
||||
// Parser
|
||||
|
||||
function wordAsValue(stream) {
|
||||
var word = stream.current().toLowerCase();
|
||||
if (valueKeywords.hasOwnProperty(word))
|
||||
override = "atom";
|
||||
else if (colorKeywords.hasOwnProperty(word))
|
||||
override = "keyword";
|
||||
else
|
||||
override = "variable";
|
||||
}
|
||||
|
||||
var states = {};
|
||||
|
||||
states.top = function(type, stream, state) {
|
||||
if (type == "{") {
|
||||
return pushContext(state, stream, "block");
|
||||
} else if (type == "}" && state.context.prev) {
|
||||
return popContext(state);
|
||||
} else if (type == "@media") {
|
||||
return pushContext(state, stream, "media");
|
||||
} else if (type == "@font-face") {
|
||||
return "font_face_before";
|
||||
} else if (type && type.charAt(0) == "@") {
|
||||
return pushContext(state, stream, "at");
|
||||
} else if (type == "hash") {
|
||||
override = "builtin";
|
||||
} else if (type == "word") {
|
||||
override = "tag";
|
||||
} else if (type == "variable-definition") {
|
||||
return "maybeprop";
|
||||
} else if (type == "interpolation") {
|
||||
return pushContext(state, stream, "interpolation");
|
||||
} else if (type == ":") {
|
||||
return "pseudo";
|
||||
} else if (allowNested && type == "(") {
|
||||
return pushContext(state, stream, "params");
|
||||
}
|
||||
return state.context.type;
|
||||
};
|
||||
|
||||
states.block = function(type, stream, state) {
|
||||
if (type == "word") {
|
||||
if (propertyKeywords.hasOwnProperty(stream.current().toLowerCase())) {
|
||||
override = "property";
|
||||
return "maybeprop";
|
||||
} else if (allowNested) {
|
||||
override = stream.match(/^\s*:/, false) ? "property" : "tag";
|
||||
return "block";
|
||||
} else {
|
||||
override += " error";
|
||||
return "maybeprop";
|
||||
}
|
||||
} else if (type == "meta") {
|
||||
return "block";
|
||||
} else if (!allowNested && (type == "hash" || type == "qualifier")) {
|
||||
override = "error";
|
||||
return "block";
|
||||
} else {
|
||||
return states.top(type, stream, state);
|
||||
}
|
||||
};
|
||||
|
||||
states.maybeprop = function(type, stream, state) {
|
||||
if (type == ":") return pushContext(state, stream, "prop");
|
||||
return pass(type, stream, state);
|
||||
};
|
||||
|
||||
states.prop = function(type, stream, state) {
|
||||
if (type == ";") return popContext(state);
|
||||
if (type == "{" && allowNested) return pushContext(state, stream, "propBlock");
|
||||
if (type == "}" || type == "{") return popAndPass(type, stream, state);
|
||||
if (type == "(") return pushContext(state, stream, "parens");
|
||||
|
||||
if (type == "hash" && !/^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/.test(stream.current())) {
|
||||
override += " error";
|
||||
} else if (type == "word") {
|
||||
wordAsValue(stream);
|
||||
} else if (type == "interpolation") {
|
||||
return pushContext(state, stream, "interpolation");
|
||||
}
|
||||
return "prop";
|
||||
};
|
||||
|
||||
states.propBlock = function(type, _stream, state) {
|
||||
if (type == "}") return popContext(state);
|
||||
if (type == "word") { override = "property"; return "maybeprop"; }
|
||||
return state.context.type;
|
||||
};
|
||||
|
||||
states.parens = function(type, stream, state) {
|
||||
if (type == "{" || type == "}") return popAndPass(type, stream, state);
|
||||
if (type == ")") return popContext(state);
|
||||
return "parens";
|
||||
};
|
||||
|
||||
states.pseudo = function(type, stream, state) {
|
||||
if (type == "word") {
|
||||
override = "variable-3";
|
||||
return state.context.type;
|
||||
}
|
||||
return pass(type, stream, state);
|
||||
};
|
||||
|
||||
states.media = function(type, stream, state) {
|
||||
if (type == "(") return pushContext(state, stream, "media_parens");
|
||||
if (type == "}") return popAndPass(type, stream, state);
|
||||
if (type == "{") return popContext(state) && pushContext(state, stream, allowNested ? "block" : "top");
|
||||
|
||||
if (type == "word") {
|
||||
var word = stream.current().toLowerCase();
|
||||
if (word == "only" || word == "not" || word == "and")
|
||||
override = "keyword";
|
||||
else if (mediaTypes.hasOwnProperty(word))
|
||||
override = "attribute";
|
||||
else if (mediaFeatures.hasOwnProperty(word))
|
||||
override = "property";
|
||||
else
|
||||
override = "error";
|
||||
}
|
||||
return state.context.type;
|
||||
};
|
||||
|
||||
states.media_parens = function(type, stream, state) {
|
||||
if (type == ")") return popContext(state);
|
||||
if (type == "{" || type == "}") return popAndPass(type, stream, state, 2);
|
||||
return states.media(type, stream, state);
|
||||
};
|
||||
|
||||
states.font_face_before = function(type, stream, state) {
|
||||
if (type == "{")
|
||||
return pushContext(state, stream, "font_face");
|
||||
return pass(type, stream, state);
|
||||
};
|
||||
|
||||
states.font_face = function(type, stream, state) {
|
||||
if (type == "}") return popContext(state);
|
||||
if (type == "word") {
|
||||
if (!fontProperties.hasOwnProperty(stream.current().toLowerCase()))
|
||||
override = "error";
|
||||
else
|
||||
override = "property";
|
||||
return "maybeprop";
|
||||
}
|
||||
return "font_face";
|
||||
};
|
||||
|
||||
states.at = function(type, stream, state) {
|
||||
if (type == ";") return popContext(state);
|
||||
if (type == "{" || type == "}") return popAndPass(type, stream, state);
|
||||
if (type == "word") override = "tag";
|
||||
else if (type == "hash") override = "builtin";
|
||||
return "at";
|
||||
};
|
||||
|
||||
states.interpolation = function(type, stream, state) {
|
||||
if (type == "}") return popContext(state);
|
||||
if (type == "{" || type == ";") return popAndPass(type, stream, state);
|
||||
if (type != "variable") override = "error";
|
||||
return "interpolation";
|
||||
};
|
||||
|
||||
states.params = function(type, stream, state) {
|
||||
if (type == ")") return popContext(state);
|
||||
if (type == "{" || type == "}") return popAndPass(type, stream, state);
|
||||
if (type == "word") wordAsValue(stream);
|
||||
return "params";
|
||||
};
|
||||
|
||||
return {
|
||||
startState: function(base) {
|
||||
return {tokenize: tokenBase,
|
||||
baseIndent: base || 0,
|
||||
stack: [],
|
||||
lastToken: null};
|
||||
return {tokenize: null,
|
||||
state: "top",
|
||||
context: new Context("top", base || 0, null)};
|
||||
},
|
||||
|
||||
token: function(stream, state) {
|
||||
|
||||
// Use these terms when applicable (see http://www.xanthir.com/blog/b4E50)
|
||||
//
|
||||
// rule** or **ruleset:
|
||||
// A selector + braces combo, or an at-rule.
|
||||
//
|
||||
// declaration block:
|
||||
// A sequence of declarations.
|
||||
//
|
||||
// declaration:
|
||||
// A property + colon + value combo.
|
||||
//
|
||||
// property value:
|
||||
// The entire value of a property.
|
||||
//
|
||||
// component value:
|
||||
// A single piece of a property value. Like the 5px in
|
||||
// text-shadow: 0 0 5px blue;. Can also refer to things that are
|
||||
// multiple terms, like the 1-4 terms that make up the background-size
|
||||
// portion of the background shorthand.
|
||||
//
|
||||
// term:
|
||||
// The basic unit of author-facing CSS, like a single number (5),
|
||||
// dimension (5px), string ("foo"), or function. Officially defined
|
||||
// by the CSS 2.1 grammar (look for the 'term' production)
|
||||
//
|
||||
//
|
||||
// simple selector:
|
||||
// A single atomic selector, like a type selector, an attr selector, a
|
||||
// class selector, etc.
|
||||
//
|
||||
// compound selector:
|
||||
// One or more simple selectors without a combinator. div.example is
|
||||
// compound, div > .example is not.
|
||||
//
|
||||
// complex selector:
|
||||
// One or more compound selectors chained with combinators.
|
||||
//
|
||||
// combinator:
|
||||
// The parts of selectors that express relationships. There are four
|
||||
// currently - the space (descendant combinator), the greater-than
|
||||
// bracket (child combinator), the plus sign (next sibling combinator),
|
||||
// and the tilda (following sibling combinator).
|
||||
//
|
||||
// sequence of selectors:
|
||||
// One or more of the named type of selector chained with commas.
|
||||
|
||||
state.tokenize = state.tokenize || tokenBase;
|
||||
if (state.tokenize == tokenBase && stream.eatSpace()) return null;
|
||||
var style = state.tokenize(stream, state);
|
||||
if (style && typeof style != "string") style = ret(style[0], style[1]);
|
||||
|
||||
// Changing style returned based on context
|
||||
var context = state.stack[state.stack.length-1];
|
||||
if (style == "variable") {
|
||||
if (type == "variable-definition") state.stack.push("propertyValue");
|
||||
return state.lastToken = "variable-2";
|
||||
} else if (style == "property") {
|
||||
var word = stream.current().toLowerCase();
|
||||
if (context == "propertyValue") {
|
||||
if (valueKeywords.hasOwnProperty(word)) {
|
||||
style = "string-2";
|
||||
} else if (colorKeywords.hasOwnProperty(word)) {
|
||||
style = "keyword";
|
||||
} else {
|
||||
style = "variable-2";
|
||||
}
|
||||
} else if (context == "rule") {
|
||||
if (!propertyKeywords.hasOwnProperty(word)) {
|
||||
style += " error";
|
||||
}
|
||||
} else if (context == "block") {
|
||||
// if a value is present in both property, value, or color, the order
|
||||
// of preference is property -> color -> value
|
||||
if (propertyKeywords.hasOwnProperty(word)) {
|
||||
style = "property";
|
||||
} else if (colorKeywords.hasOwnProperty(word)) {
|
||||
style = "keyword";
|
||||
} else if (valueKeywords.hasOwnProperty(word)) {
|
||||
style = "string-2";
|
||||
} else {
|
||||
style = "tag";
|
||||
}
|
||||
} else if (!context || context == "@media{") {
|
||||
style = "tag";
|
||||
} else if (context == "@media") {
|
||||
if (atMediaTypes[stream.current()]) {
|
||||
style = "attribute"; // Known attribute
|
||||
} else if (/^(only|not)$/.test(word)) {
|
||||
style = "keyword";
|
||||
} else if (word == "and") {
|
||||
style = "error"; // "and" is only allowed in @mediaType
|
||||
} else if (atMediaFeatures.hasOwnProperty(word)) {
|
||||
style = "error"; // Known property, should be in @mediaType(
|
||||
} else {
|
||||
// Unknown, expecting keyword or attribute, assuming attribute
|
||||
style = "attribute error";
|
||||
}
|
||||
} else if (context == "@mediaType") {
|
||||
if (atMediaTypes.hasOwnProperty(word)) {
|
||||
style = "attribute";
|
||||
} else if (word == "and") {
|
||||
style = "operator";
|
||||
} else if (/^(only|not)$/.test(word)) {
|
||||
style = "error"; // Only allowed in @media
|
||||
} else {
|
||||
// Unknown attribute or property, but expecting property (preceded
|
||||
// by "and"). Should be in parentheses
|
||||
style = "error";
|
||||
}
|
||||
} else if (context == "@mediaType(") {
|
||||
if (propertyKeywords.hasOwnProperty(word)) {
|
||||
// do nothing, remains "property"
|
||||
} else if (atMediaTypes.hasOwnProperty(word)) {
|
||||
style = "error"; // Known property, should be in parentheses
|
||||
} else if (word == "and") {
|
||||
style = "operator";
|
||||
} else if (/^(only|not)$/.test(word)) {
|
||||
style = "error"; // Only allowed in @media
|
||||
} else {
|
||||
style += " error";
|
||||
}
|
||||
} else if (context == "@import") {
|
||||
style = "tag";
|
||||
} else {
|
||||
style = "error";
|
||||
}
|
||||
} else if (style == "atom") {
|
||||
if(!context || context == "@media{" || context == "block") {
|
||||
style = "builtin";
|
||||
} else if (context == "propertyValue") {
|
||||
if (!/^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/.test(stream.current())) {
|
||||
style += " error";
|
||||
}
|
||||
} else {
|
||||
style = "error";
|
||||
}
|
||||
} else if (context == "@media" && type == "{") {
|
||||
style = "error";
|
||||
if (!state.tokenize && stream.eatSpace()) return null;
|
||||
var style = (state.tokenize || tokenBase)(stream, state);
|
||||
if (style && typeof style == "object") {
|
||||
type = style[1];
|
||||
style = style[0];
|
||||
}
|
||||
|
||||
// Push/pop context stack
|
||||
if (type == "{") {
|
||||
if (context == "@media" || context == "@mediaType") {
|
||||
state.stack[state.stack.length-1] = "@media{";
|
||||
}
|
||||
else {
|
||||
var newContext = allowNested ? "block" : "rule";
|
||||
state.stack.push(newContext);
|
||||
}
|
||||
}
|
||||
else if (type == "}") {
|
||||
if (context == "interpolation") style = "operator";
|
||||
state.stack.pop();
|
||||
if (context == "propertyValue") state.stack.pop();
|
||||
}
|
||||
else if (type == "interpolation") state.stack.push("interpolation");
|
||||
else if (type == "@media") state.stack.push("@media");
|
||||
else if (type == "@import") state.stack.push("@import");
|
||||
else if (context == "@media" && /\b(keyword|attribute)\b/.test(style))
|
||||
state.stack[state.stack.length-1] = "@mediaType";
|
||||
else if (context == "@mediaType" && stream.current() == ",")
|
||||
state.stack[state.stack.length-1] = "@media";
|
||||
else if (type == "(") {
|
||||
if (context == "@media" || context == "@mediaType") {
|
||||
// Make sure @mediaType is used to avoid error on {
|
||||
state.stack[state.stack.length-1] = "@mediaType";
|
||||
state.stack.push("@mediaType(");
|
||||
}
|
||||
else state.stack.push("(");
|
||||
}
|
||||
else if (type == ")") {
|
||||
if (context == "propertyValue") {
|
||||
// In @mediaType( without closing ; after propertyValue
|
||||
state.stack.pop();
|
||||
}
|
||||
state.stack.pop();
|
||||
}
|
||||
else if (type == ":" && state.lastToken == "property") state.stack.push("propertyValue");
|
||||
else if (context == "propertyValue" && type == ";") state.stack.pop();
|
||||
else if (context == "@import" && type == ";") state.stack.pop();
|
||||
|
||||
return state.lastToken = style;
|
||||
override = style;
|
||||
state.state = states[state.state](type, stream, state);
|
||||
return override;
|
||||
},
|
||||
|
||||
indent: function(state, textAfter) {
|
||||
var n = state.stack.length;
|
||||
if (/^\}/.test(textAfter))
|
||||
n -= state.stack[n-1] == "propertyValue" ? 2 : 1;
|
||||
return state.baseIndent + n * indentUnit;
|
||||
var cx = state.context, ch = textAfter && textAfter.charAt(0);
|
||||
var indent = cx.indent;
|
||||
if (cx.prev &&
|
||||
(ch == "}" && (cx.type == "block" || cx.type == "top" || cx.type == "interpolation" || cx.type == "font_face") ||
|
||||
ch == ")" && (cx.type == "parens" || cx.type == "params" || cx.type == "media_parens") ||
|
||||
ch == "{" && (cx.type == "at" || cx.type == "media"))) {
|
||||
indent = cx.indent - indentUnit;
|
||||
cx = cx.prev;
|
||||
}
|
||||
return indent;
|
||||
},
|
||||
|
||||
electricChars: "}",
|
||||
@@ -314,12 +334,12 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
||||
return keys;
|
||||
}
|
||||
|
||||
var atMediaTypes = keySet([
|
||||
var mediaTypes_ = [
|
||||
"all", "aural", "braille", "handheld", "print", "projection", "screen",
|
||||
"tty", "tv", "embossed"
|
||||
]);
|
||||
], mediaTypes = keySet(mediaTypes_);
|
||||
|
||||
var atMediaFeatures = keySet([
|
||||
var mediaFeatures_ = [
|
||||
"width", "min-width", "max-width", "height", "min-height", "max-height",
|
||||
"device-width", "min-device-width", "max-device-width", "device-height",
|
||||
"min-device-height", "max-device-height", "aspect-ratio",
|
||||
@@ -328,9 +348,9 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
||||
"max-color", "color-index", "min-color-index", "max-color-index",
|
||||
"monochrome", "min-monochrome", "max-monochrome", "resolution",
|
||||
"min-resolution", "max-resolution", "scan", "grid"
|
||||
]);
|
||||
], mediaFeatures = keySet(mediaFeatures_);
|
||||
|
||||
var propertyKeywords = keySet([
|
||||
var propertyKeywords_ = [
|
||||
"align-content", "align-items", "align-self", "alignment-adjust",
|
||||
"alignment-baseline", "anchor-point", "animation", "animation-delay",
|
||||
"animation-direction", "animation-duration", "animation-iteration-count",
|
||||
@@ -418,9 +438,9 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
||||
"stroke-miterlimit", "stroke-opacity", "stroke-width", "text-rendering",
|
||||
"baseline-shift", "dominant-baseline", "glyph-orientation-horizontal",
|
||||
"glyph-orientation-vertical", "kerning", "text-anchor", "writing-mode"
|
||||
]);
|
||||
], propertyKeywords = keySet(propertyKeywords_);
|
||||
|
||||
var colorKeywords = keySet([
|
||||
var colorKeywords_ = [
|
||||
"aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige",
|
||||
"bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown",
|
||||
"burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue",
|
||||
@@ -447,9 +467,9 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
||||
"slateblue", "slategray", "snow", "springgreen", "steelblue", "tan",
|
||||
"teal", "thistle", "tomato", "turquoise", "violet", "wheat", "white",
|
||||
"whitesmoke", "yellow", "yellowgreen"
|
||||
]);
|
||||
], colorKeywords = keySet(colorKeywords_);
|
||||
|
||||
var valueKeywords = keySet([
|
||||
var valueKeywords_ = [
|
||||
"above", "absolute", "activeborder", "activecaption", "afar",
|
||||
"after-white-space", "ahead", "alias", "all", "all-scroll", "alternate",
|
||||
"always", "amharic", "amharic-abegede", "antialiased", "appworkspace",
|
||||
@@ -532,7 +552,15 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
||||
"visibleStroke", "visual", "w-resize", "wait", "wave", "wider",
|
||||
"window", "windowframe", "windowtext", "x-large", "x-small", "xor",
|
||||
"xx-large", "xx-small"
|
||||
]);
|
||||
], valueKeywords = keySet(valueKeywords_);
|
||||
|
||||
var fontProperties_ = [
|
||||
"font-family", "src", "unicode-range", "font-variant", "font-feature-settings",
|
||||
"font-stretch", "font-weight", "font-style"
|
||||
], fontProperties = keySet(fontProperties_);
|
||||
|
||||
var allWords = mediaTypes_.concat(mediaFeatures_).concat(propertyKeywords_).concat(colorKeywords_).concat(valueKeywords_);
|
||||
CodeMirror.registerHelper("hintWords", "css", allWords);
|
||||
|
||||
function tokenCComment(stream, state) {
|
||||
var maybeEnd = false, ch;
|
||||
@@ -546,62 +574,47 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
||||
return ["comment", "comment"];
|
||||
}
|
||||
|
||||
function tokenSGMLComment(stream, state) {
|
||||
if (stream.skipTo("-->")) {
|
||||
stream.match("-->");
|
||||
state.tokenize = null;
|
||||
} else {
|
||||
stream.skipToEnd();
|
||||
}
|
||||
return ["comment", "comment"];
|
||||
}
|
||||
|
||||
CodeMirror.defineMIME("text/css", {
|
||||
atMediaTypes: atMediaTypes,
|
||||
atMediaFeatures: atMediaFeatures,
|
||||
mediaTypes: mediaTypes,
|
||||
mediaFeatures: mediaFeatures,
|
||||
propertyKeywords: propertyKeywords,
|
||||
colorKeywords: colorKeywords,
|
||||
valueKeywords: valueKeywords,
|
||||
hooks: {
|
||||
fontProperties: fontProperties,
|
||||
tokenHooks: {
|
||||
"<": function(stream, state) {
|
||||
function tokenSGMLComment(stream, state) {
|
||||
var dashes = 0, ch;
|
||||
while ((ch = stream.next()) != null) {
|
||||
if (dashes >= 2 && ch == ">") {
|
||||
state.tokenize = null;
|
||||
break;
|
||||
}
|
||||
dashes = (ch == "-") ? dashes + 1 : 0;
|
||||
}
|
||||
return ["comment", "comment"];
|
||||
}
|
||||
if (stream.eat("!")) {
|
||||
state.tokenize = tokenSGMLComment;
|
||||
return tokenSGMLComment(stream, state);
|
||||
}
|
||||
if (!stream.match("!--")) return false;
|
||||
state.tokenize = tokenSGMLComment;
|
||||
return tokenSGMLComment(stream, state);
|
||||
},
|
||||
"/": function(stream, state) {
|
||||
if (stream.eat("*")) {
|
||||
state.tokenize = tokenCComment;
|
||||
return tokenCComment(stream, state);
|
||||
}
|
||||
return false;
|
||||
if (!stream.eat("*")) return false;
|
||||
state.tokenize = tokenCComment;
|
||||
return tokenCComment(stream, state);
|
||||
}
|
||||
},
|
||||
name: "css"
|
||||
});
|
||||
|
||||
CodeMirror.defineMIME("text/x-scss", {
|
||||
atMediaTypes: atMediaTypes,
|
||||
atMediaFeatures: atMediaFeatures,
|
||||
mediaTypes: mediaTypes,
|
||||
mediaFeatures: mediaFeatures,
|
||||
propertyKeywords: propertyKeywords,
|
||||
colorKeywords: colorKeywords,
|
||||
valueKeywords: valueKeywords,
|
||||
fontProperties: fontProperties,
|
||||
allowNested: true,
|
||||
hooks: {
|
||||
":": function(stream) {
|
||||
if (stream.match(/\s*{/)) {
|
||||
return [null, "{"];
|
||||
}
|
||||
return false;
|
||||
},
|
||||
"$": function(stream) {
|
||||
stream.match(/^[\w-]+/);
|
||||
if (stream.peek() == ":") {
|
||||
return ["variable", "variable-definition"];
|
||||
}
|
||||
return ["variable", "variable"];
|
||||
},
|
||||
tokenHooks: {
|
||||
"/": function(stream, state) {
|
||||
if (stream.eat("/")) {
|
||||
stream.skipToEnd();
|
||||
@@ -613,15 +626,58 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
||||
return ["operator", "operator"];
|
||||
}
|
||||
},
|
||||
":": function(stream) {
|
||||
if (stream.match(/\s*{/))
|
||||
return [null, "{"];
|
||||
return false;
|
||||
},
|
||||
"$": function(stream) {
|
||||
stream.match(/^[\w-]+/);
|
||||
if (stream.match(/^\s*:/, false))
|
||||
return ["variable-2", "variable-definition"];
|
||||
return ["variable-2", "variable"];
|
||||
},
|
||||
"#": function(stream) {
|
||||
if (stream.eat("{")) {
|
||||
return ["operator", "interpolation"];
|
||||
} else {
|
||||
stream.eatWhile(/[\w\\\-]/);
|
||||
return ["atom", "hash"];
|
||||
}
|
||||
if (!stream.eat("{")) return false;
|
||||
return [null, "interpolation"];
|
||||
}
|
||||
},
|
||||
name: "css"
|
||||
name: "css",
|
||||
helperType: "scss"
|
||||
});
|
||||
|
||||
CodeMirror.defineMIME("text/x-less", {
|
||||
mediaTypes: mediaTypes,
|
||||
mediaFeatures: mediaFeatures,
|
||||
propertyKeywords: propertyKeywords,
|
||||
colorKeywords: colorKeywords,
|
||||
valueKeywords: valueKeywords,
|
||||
fontProperties: fontProperties,
|
||||
allowNested: true,
|
||||
tokenHooks: {
|
||||
"/": function(stream, state) {
|
||||
if (stream.eat("/")) {
|
||||
stream.skipToEnd();
|
||||
return ["comment", "comment"];
|
||||
} else if (stream.eat("*")) {
|
||||
state.tokenize = tokenCComment;
|
||||
return tokenCComment(stream, state);
|
||||
} else {
|
||||
return ["operator", "operator"];
|
||||
}
|
||||
},
|
||||
"@": function(stream) {
|
||||
if (stream.match(/^(charset|document|font-face|import|keyframes|media|namespace|page|supports)\b/, false)) return false;
|
||||
stream.eatWhile(/[\w\\\-]/);
|
||||
if (stream.match(/^\s*:/, false))
|
||||
return ["variable-2", "variable-definition"];
|
||||
return ["variable-2", "variable"];
|
||||
},
|
||||
"&": function() {
|
||||
return ["atom", "atom"];
|
||||
}
|
||||
},
|
||||
name: "css",
|
||||
helperType: "less"
|
||||
});
|
||||
})();
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: CSS mode</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../../lib/codemirror.css">
|
||||
<script src="../../lib/codemirror.js"></script>
|
||||
<script src="css.js"></script>
|
||||
<style>.CodeMirror {background: #f8f8f8;}</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../../index.html">Home</a>
|
||||
<li><a href="../../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/marijnh/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a href="../index.html">Language modes</a>
|
||||
<li><a class=active href="#">CSS</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>CSS mode</h2>
|
||||
<form><textarea id="code" name="code">
|
||||
/* Some example CSS */
|
||||
|
||||
@import url("something.css");
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 3em 6em;
|
||||
font-family: tahoma, arial, sans-serif;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
#navigation a {
|
||||
font-weight: bold;
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2.5em;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.7em;
|
||||
}
|
||||
|
||||
h1:before, h2:before {
|
||||
content: "::";
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: courier, monospace;
|
||||
font-size: 80%;
|
||||
color: #418A8A;
|
||||
}
|
||||
</textarea></form>
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {});
|
||||
</script>
|
||||
|
||||
<p><strong>MIME types defined:</strong> <code>text/css</code>.</p>
|
||||
|
||||
<p><strong>Parsing/Highlighting Tests:</strong> <a href="../../test/index.html#css_*">normal</a>, <a href="../../test/index.html#verbose,css_*">verbose</a>.</p>
|
||||
|
||||
</article>
|
||||
+1
-1
@@ -150,7 +150,7 @@ code {
|
||||
});
|
||||
</script>
|
||||
|
||||
<p><strong>MIME types defined:</strong> <code>text/scss</code>.</p>
|
||||
<p>The SCSS mode is a sub-mode of the <a href="index.html">CSS mode</a> (defined in <code>css.js</code>.</p>
|
||||
|
||||
<p><strong>Parsing/Highlighting Tests:</strong> <a href="../../test/index.html#scss_*">normal</a>, <a href="../../test/index.html#verbose,scss_*">verbose</a>.</p>
|
||||
|
||||
|
||||
+48
-21
@@ -1,33 +1,33 @@
|
||||
(function() {
|
||||
var mode = CodeMirror.getMode({tabSize: 4}, "text/x-scss");
|
||||
var mode = CodeMirror.getMode({indentUnit: 2}, "text/x-scss");
|
||||
function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1), "scss"); }
|
||||
|
||||
MT('url_with_quotation',
|
||||
"[tag foo] { [property background][operator :][string-2 url]([string test.jpg]) }");
|
||||
"[tag foo] { [property background]:[atom url]([string test.jpg]) }");
|
||||
|
||||
MT('url_with_double_quotes',
|
||||
"[tag foo] { [property background][operator :][string-2 url]([string \"test.jpg\"]) }");
|
||||
"[tag foo] { [property background]:[atom url]([string \"test.jpg\"]) }");
|
||||
|
||||
MT('url_with_single_quotes',
|
||||
"[tag foo] { [property background][operator :][string-2 url]([string \'test.jpg\']) }");
|
||||
"[tag foo] { [property background]:[atom url]([string \'test.jpg\']) }");
|
||||
|
||||
MT('string',
|
||||
"[def @import] [string \"compass/css3\"]");
|
||||
|
||||
MT('important_keyword',
|
||||
"[tag foo] { [property background][operator :][string-2 url]([string \'test.jpg\']) [keyword !important] }");
|
||||
"[tag foo] { [property background]:[atom url]([string \'test.jpg\']) [keyword !important] }");
|
||||
|
||||
MT('variable',
|
||||
"[variable-2 $blue][operator :][atom #333]");
|
||||
"[variable-2 $blue]:[atom #333]");
|
||||
|
||||
MT('variable_as_attribute',
|
||||
"[tag foo] { [property color][operator :][variable-2 $blue] }");
|
||||
"[tag foo] { [property color]:[variable-2 $blue] }");
|
||||
|
||||
MT('numbers',
|
||||
"[tag foo] { [property padding][operator :][number 10px] [number 10] [number 10em] [number 8in] }");
|
||||
"[tag foo] { [property padding]:[number 10px] [number 10] [number 10em] [number 8in] }");
|
||||
|
||||
MT('number_percentage',
|
||||
"[tag foo] { [property width][operator :][number 80%] }");
|
||||
"[tag foo] { [property width]:[number 80%] }");
|
||||
|
||||
MT('selector',
|
||||
"[builtin #hello][qualifier .world]{}");
|
||||
@@ -39,42 +39,69 @@
|
||||
"[comment /*foobar*/]");
|
||||
|
||||
MT('attribute_with_hyphen',
|
||||
"[tag foo] { [property font-size][operator :][number 10px] }");
|
||||
"[tag foo] { [property font-size]:[number 10px] }");
|
||||
|
||||
MT('string_after_attribute',
|
||||
"[tag foo] { [property content][operator :][string \"::\"] }");
|
||||
"[tag foo] { [property content]:[string \"::\"] }");
|
||||
|
||||
MT('directives',
|
||||
"[def @include] [qualifier .mixin]");
|
||||
|
||||
MT('basic_structure',
|
||||
"[tag p] { [property background][operator :][keyword red]; }");
|
||||
"[tag p] { [property background]:[keyword red]; }");
|
||||
|
||||
MT('nested_structure',
|
||||
"[tag p] { [tag a] { [property color][operator :][keyword red]; } }");
|
||||
"[tag p] { [tag a] { [property color]:[keyword red]; } }");
|
||||
|
||||
MT('mixin',
|
||||
"[def @mixin] [tag table-base] {}");
|
||||
|
||||
MT('number_without_semicolon',
|
||||
"[tag p] {[property width][operator :][number 12]}",
|
||||
"[tag a] {[property color][operator :][keyword red];}");
|
||||
"[tag p] {[property width]:[number 12]}",
|
||||
"[tag a] {[property color]:[keyword red];}");
|
||||
|
||||
MT('atom_in_nested_block',
|
||||
"[tag p] { [tag a] { [property color][operator :][atom #000]; } }");
|
||||
"[tag p] { [tag a] { [property color]:[atom #000]; } }");
|
||||
|
||||
MT('interpolation_in_property',
|
||||
"[tag foo] { [operator #{][variable-2 $hello][operator }:][number 2]; }");
|
||||
"[tag foo] { #{[variable-2 $hello]}:[number 2]; }");
|
||||
|
||||
MT('interpolation_in_selector',
|
||||
"[tag foo][operator #{][variable-2 $hello][operator }] { [property color][operator :][atom #000]; }");
|
||||
"[tag foo]#{[variable-2 $hello]} { [property color]:[atom #000]; }");
|
||||
|
||||
MT('interpolation_error',
|
||||
"[tag foo][operator #{][error foo][operator }] { [property color][operator :][atom #000]; }");
|
||||
"[tag foo]#{[error foo]} { [property color]:[atom #000]; }");
|
||||
|
||||
MT("divide_operator",
|
||||
"[tag foo] { [property width][operator :][number 4] [operator /] [number 2] }");
|
||||
"[tag foo] { [property width]:[number 4] [operator /] [number 2] }");
|
||||
|
||||
MT('nested_structure_with_id_selector',
|
||||
"[tag p] { [builtin #hello] { [property color][operator :][keyword red]; } }");
|
||||
"[tag p] { [builtin #hello] { [property color]:[keyword red]; } }");
|
||||
|
||||
MT('indent_mixin',
|
||||
"[def @mixin] [tag container] (",
|
||||
" [variable-2 $a]: [number 10],",
|
||||
" [variable-2 $b]: [number 10])",
|
||||
"{}");
|
||||
|
||||
MT('indent_nested',
|
||||
"[tag foo] {",
|
||||
" [tag bar] {",
|
||||
" }",
|
||||
"}");
|
||||
|
||||
MT('indent_parentheses',
|
||||
"[tag foo] {",
|
||||
" [property color]: [variable darken]([variable-2 $blue],",
|
||||
" [number 9%]);",
|
||||
"}");
|
||||
|
||||
MT('indent_vardef',
|
||||
"[variable-2 $name]:",
|
||||
" [string 'val'];",
|
||||
"[tag tag] {",
|
||||
" [tag inner] {",
|
||||
" [property margin]: [number 3px];",
|
||||
" }",
|
||||
"}");
|
||||
})();
|
||||
|
||||
+64
-71
@@ -1,67 +1,19 @@
|
||||
(function() {
|
||||
var mode = CodeMirror.getMode({tabSize: 4}, "css");
|
||||
var mode = CodeMirror.getMode({indentUnit: 2}, "css");
|
||||
function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }
|
||||
|
||||
// Requires at least one media query
|
||||
MT("atMediaEmpty",
|
||||
"[def @media] [error {] }");
|
||||
|
||||
MT("atMediaMultiple",
|
||||
"[def @media] [keyword not] [attribute screen] [operator and] ([property color]), [keyword not] [attribute print] [operator and] ([property color]) { }");
|
||||
|
||||
MT("atMediaCheckStack",
|
||||
"[def @media] [attribute screen] { } [tag foo] { }");
|
||||
|
||||
MT("atMediaCheckStack",
|
||||
"[def @media] [attribute screen] ([property color]) { } [tag foo] { }");
|
||||
|
||||
MT("atMediaPropertyOnly",
|
||||
"[def @media] ([property color]) { } [tag foo] { }");
|
||||
|
||||
MT("atMediaCheckStackInvalidAttribute",
|
||||
"[def @media] [attribute&error foobarhello] { [tag foo] { } }");
|
||||
|
||||
MT("atMediaCheckStackInvalidAttribute",
|
||||
"[def @media] [attribute&error foobarhello] { } [tag foo] { }");
|
||||
|
||||
// Error, because "and" is only allowed immediately preceding a media expression
|
||||
MT("atMediaInvalidAttribute",
|
||||
"[def @media] [attribute&error foobarhello] { }");
|
||||
|
||||
// Error, because "and" is only allowed immediately preceding a media expression
|
||||
MT("atMediaInvalidAnd",
|
||||
"[def @media] [error and] [attribute screen] { }");
|
||||
|
||||
// Error, because "not" is only allowed as the first item in each media query
|
||||
MT("atMediaInvalidNot",
|
||||
"[def @media] [attribute screen] [error not] ([error not]) { }");
|
||||
|
||||
// Error, because "only" is only allowed as the first item in each media query
|
||||
MT("atMediaInvalidOnly",
|
||||
"[def @media] [attribute screen] [error only] ([error only]) { }");
|
||||
|
||||
// Error, because "foobarhello" is neither a known type or property, but
|
||||
// property was expected (after "and"), and it should be in parenthese.
|
||||
MT("atMediaUnknownType",
|
||||
"[def @media] [attribute screen] [operator and] [error foobarhello] { }");
|
||||
|
||||
// Error, because "color" is not a known type, but is a known property, and
|
||||
// should be in parentheses.
|
||||
MT("atMediaInvalidType",
|
||||
"[def @media] [attribute screen] [operator and] [error color] { }");
|
||||
|
||||
// Error, because "print" is not a known property, but is a known type,
|
||||
// and should not be in parenthese.
|
||||
MT("atMediaInvalidProperty",
|
||||
"[def @media] [attribute screen] [operator and] ([error print]) { }");
|
||||
"[def @media] [attribute screen] [keyword and] [error foobarhello] { }");
|
||||
|
||||
// Soft error, because "foobarhello" is not a known property or type.
|
||||
MT("atMediaUnknownProperty",
|
||||
"[def @media] [attribute screen] [operator and] ([property&error foobarhello]) { }");
|
||||
"[def @media] [attribute screen] [keyword and] ([error foobarhello]) { }");
|
||||
|
||||
// Make sure nesting works with media queries
|
||||
MT("atMediaMaxWidthNested",
|
||||
"[def @media] [attribute screen] [operator and] ([property max-width][operator :] [number 25px]) { [tag foo] { } }");
|
||||
"[def @media] [attribute screen] [keyword and] ([property max-width]: [number 25px]) { [tag foo] { } }");
|
||||
|
||||
MT("tagSelector",
|
||||
"[tag foo] { }");
|
||||
@@ -73,54 +25,95 @@
|
||||
"[builtin #foo] { [error #foo] }");
|
||||
|
||||
MT("tagSelectorUnclosed",
|
||||
"[tag foo] { [property margin][operator :] [number 0] } [tag bar] { }");
|
||||
"[tag foo] { [property margin]: [number 0] } [tag bar] { }");
|
||||
|
||||
MT("tagStringNoQuotes",
|
||||
"[tag foo] { [property font-family][operator :] [variable-2 hello] [variable-2 world]; }");
|
||||
"[tag foo] { [property font-family]: [variable hello] [variable world]; }");
|
||||
|
||||
MT("tagStringDouble",
|
||||
"[tag foo] { [property font-family][operator :] [string \"hello world\"]; }");
|
||||
"[tag foo] { [property font-family]: [string \"hello world\"]; }");
|
||||
|
||||
MT("tagStringSingle",
|
||||
"[tag foo] { [property font-family][operator :] [string 'hello world']; }");
|
||||
"[tag foo] { [property font-family]: [string 'hello world']; }");
|
||||
|
||||
MT("tagColorKeyword",
|
||||
"[tag foo] {" +
|
||||
"[property color][operator :] [keyword black];" +
|
||||
"[property color][operator :] [keyword navy];" +
|
||||
"[property color][operator :] [keyword yellow];" +
|
||||
"}");
|
||||
"[tag foo] {",
|
||||
" [property color]: [keyword black];",
|
||||
" [property color]: [keyword navy];",
|
||||
" [property color]: [keyword yellow];",
|
||||
"}");
|
||||
|
||||
MT("tagColorHex3",
|
||||
"[tag foo] { [property background][operator :] [atom #fff]; }");
|
||||
"[tag foo] { [property background]: [atom #fff]; }");
|
||||
|
||||
MT("tagColorHex6",
|
||||
"[tag foo] { [property background][operator :] [atom #ffffff]; }");
|
||||
"[tag foo] { [property background]: [atom #ffffff]; }");
|
||||
|
||||
MT("tagColorHex4",
|
||||
"[tag foo] { [property background][operator :] [atom&error #ffff]; }");
|
||||
"[tag foo] { [property background]: [atom&error #ffff]; }");
|
||||
|
||||
MT("tagColorHexInvalid",
|
||||
"[tag foo] { [property background][operator :] [atom&error #ffg]; }");
|
||||
"[tag foo] { [property background]: [atom&error #ffg]; }");
|
||||
|
||||
MT("tagNegativeNumber",
|
||||
"[tag foo] { [property margin][operator :] [number -5px]; }");
|
||||
"[tag foo] { [property margin]: [number -5px]; }");
|
||||
|
||||
MT("tagPositiveNumber",
|
||||
"[tag foo] { [property padding][operator :] [number 5px]; }");
|
||||
"[tag foo] { [property padding]: [number 5px]; }");
|
||||
|
||||
MT("tagVendor",
|
||||
"[tag foo] { [meta -foo-][property box-sizing][operator :] [meta -foo-][string-2 border-box]; }");
|
||||
"[tag foo] { [meta -foo-][property box-sizing]: [meta -foo-][atom border-box]; }");
|
||||
|
||||
MT("tagBogusProperty",
|
||||
"[tag foo] { [property&error barhelloworld][operator :] [number 0]; }");
|
||||
"[tag foo] { [property&error barhelloworld]: [number 0]; }");
|
||||
|
||||
MT("tagTwoProperties",
|
||||
"[tag foo] { [property margin][operator :] [number 0]; [property padding][operator :] [number 0]; }");
|
||||
"[tag foo] { [property margin]: [number 0]; [property padding]: [number 0]; }");
|
||||
|
||||
MT("tagTwoPropertiesURL",
|
||||
"[tag foo] { [property background][operator :] [string-2 url]([string //example.com/foo.png]); [property padding][operator :] [number 0]; }");
|
||||
"[tag foo] { [property background]: [atom url]([string //example.com/foo.png]); [property padding]: [number 0]; }");
|
||||
|
||||
MT("commentSGML",
|
||||
"[comment <!--comment-->]");
|
||||
|
||||
MT("commentSGML2",
|
||||
"[comment <!--comment]",
|
||||
"[comment -->] [tag div] {}");
|
||||
|
||||
MT("indent_tagSelector",
|
||||
"[tag strong], [tag em] {",
|
||||
" [property background]: [atom rgba](",
|
||||
" [number 255], [number 255], [number 0], [number .2]",
|
||||
" );",
|
||||
"}");
|
||||
|
||||
MT("indent_atMedia",
|
||||
"[def @media] {",
|
||||
" [tag foo] {",
|
||||
" [property color]:",
|
||||
" [keyword yellow];",
|
||||
" }",
|
||||
"}");
|
||||
|
||||
MT("indent_comma",
|
||||
"[tag foo] {",
|
||||
" [property font-family]: [variable verdana],",
|
||||
" [atom sans-serif];",
|
||||
"}");
|
||||
|
||||
MT("indent_parentheses",
|
||||
"[tag foo]:[variable-3 before] {",
|
||||
" [property background]: [atom url](",
|
||||
"[string blahblah]",
|
||||
"[string etc]",
|
||||
"[string ]) [keyword !important];",
|
||||
"}");
|
||||
|
||||
MT("font_face",
|
||||
"[def @font-face] {",
|
||||
" [property font-family]: [string 'myfont'];",
|
||||
" [error nonsense]: [string 'abc'];",
|
||||
" [property src]: [atom url]([string http://blah]),",
|
||||
" [atom url]([string http://foo]);",
|
||||
"}");
|
||||
})();
|
||||
|
||||
@@ -58,8 +58,6 @@ CodeMirror.defineMode("htmlembedded", function(config, parserConfig) {
|
||||
};
|
||||
},
|
||||
|
||||
electricChars: "/{}:",
|
||||
|
||||
innerMode: function(state) {
|
||||
if (state.token == scriptingDispatch) return {state: state.scriptState, mode: scriptingMode};
|
||||
else return {state: state.htmlState, mode: htmlMixedMode};
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Html Embedded Scripts mode</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../../lib/codemirror.css">
|
||||
<script src="../../lib/codemirror.js"></script>
|
||||
<script src="../xml/xml.js"></script>
|
||||
<script src="../javascript/javascript.js"></script>
|
||||
<script src="../css/css.js"></script>
|
||||
<script src="../htmlmixed/htmlmixed.js"></script>
|
||||
<script src="htmlembedded.js"></script>
|
||||
<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../../index.html">Home</a>
|
||||
<li><a href="../../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/marijnh/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a href="../index.html">Language modes</a>
|
||||
<li><a class=active href="#">Html Embedded Scripts</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>Html Embedded Scripts mode</h2>
|
||||
<form><textarea id="code" name="code">
|
||||
<%
|
||||
function hello(who) {
|
||||
return "Hello " + who;
|
||||
}
|
||||
%>
|
||||
This is an example of EJS (embedded javascript)
|
||||
<p>The program says <%= hello("world") %>.</p>
|
||||
<script>
|
||||
alert("And here is some normal JS code"); // also colored
|
||||
</script>
|
||||
</textarea></form>
|
||||
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
lineNumbers: true,
|
||||
mode: "application/x-ejs",
|
||||
indentUnit: 4,
|
||||
indentWithTabs: true,
|
||||
enterMode: "keep",
|
||||
tabMode: "shift"
|
||||
});
|
||||
</script>
|
||||
|
||||
<p>Mode for html embedded scripts like JSP and ASP.NET. Depends on HtmlMixed which in turn depends on
|
||||
JavaScript, CSS and XML.<br />Other dependancies include those of the scriping language chosen.</p>
|
||||
|
||||
<p><strong>MIME types defined:</strong> <code>application/x-aspx</code> (ASP.NET),
|
||||
<code>application/x-ejs</code> (Embedded Javascript), <code>application/x-jsp</code> (JavaServer Pages)</p>
|
||||
</article>
|
||||
@@ -44,7 +44,7 @@ CodeMirror.defineMode("htmlmixed", function(config, parserConfig) {
|
||||
if (close > -1) stream.backUp(cur.length - close);
|
||||
else if (m = cur.match(/<\/?$/)) {
|
||||
stream.backUp(cur.length);
|
||||
if (!stream.match(pat, false)) stream.match(cur[0]);
|
||||
if (!stream.match(pat, false)) stream.match(cur);
|
||||
}
|
||||
return style;
|
||||
}
|
||||
@@ -93,8 +93,6 @@ CodeMirror.defineMode("htmlmixed", function(config, parserConfig) {
|
||||
return CodeMirror.Pass;
|
||||
},
|
||||
|
||||
electricChars: "/{}:",
|
||||
|
||||
innerMode: function(state) {
|
||||
return {state: state.localState || state.htmlState, mode: state.localMode || htmlMode};
|
||||
}
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: HTML mixed mode</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../../lib/codemirror.css">
|
||||
<script src="../../lib/codemirror.js"></script>
|
||||
<script src="../xml/xml.js"></script>
|
||||
<script src="../javascript/javascript.js"></script>
|
||||
<script src="../css/css.js"></script>
|
||||
<script src="../vbscript/vbscript.js"></script>
|
||||
<script src="htmlmixed.js"></script>
|
||||
<style>.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../../index.html">Home</a>
|
||||
<li><a href="../../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/marijnh/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a href="../index.html">Language modes</a>
|
||||
<li><a class=active href="#">HTML mixed</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>HTML mixed mode</h2>
|
||||
<form><textarea id="code" name="code">
|
||||
<html style="color: green">
|
||||
<!-- this is a comment -->
|
||||
<head>
|
||||
<title>Mixed HTML Example</title>
|
||||
<style type="text/css">
|
||||
h1 {font-family: comic sans; color: #f0f;}
|
||||
div {background: yellow !important;}
|
||||
body {
|
||||
max-width: 50em;
|
||||
margin: 1em 2em 1em 5em;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Mixed HTML Example</h1>
|
||||
<script>
|
||||
function jsFunc(arg1, arg2) {
|
||||
if (arg1 && arg2) document.body.innerHTML = "achoo";
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
</textarea></form>
|
||||
<script>
|
||||
// Define an extended mixed-mode that understands vbscript and
|
||||
// leaves mustache/handlebars embedded templates in html mode
|
||||
var mixedMode = {
|
||||
name: "htmlmixed",
|
||||
scriptTypes: [{matches: /\/x-handlebars-template|\/x-mustache/i,
|
||||
mode: null},
|
||||
{matches: /(text|application)\/(x-)?vb(a|script)/i,
|
||||
mode: "vbscript"}]
|
||||
};
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {mode: mixedMode, tabMode: "indent"});
|
||||
</script>
|
||||
|
||||
<p>The HTML mixed mode depends on the XML, JavaScript, and CSS modes.</p>
|
||||
|
||||
<p>It takes an optional mode configuration
|
||||
option, <code>scriptTypes</code>, which can be used to add custom
|
||||
behavior for specific <code><script type="..."></code> tags. If
|
||||
given, it should hold an array of <code>{matches, mode}</code>
|
||||
objects, where <code>matches</code> is a string or regexp that
|
||||
matches the script type, and <code>mode</code> is
|
||||
either <code>null</code>, for script types that should stay in
|
||||
HTML mode, or a <a href="../../doc/manual.html#option_mode">mode
|
||||
spec</a> corresponding to the mode that should be used for the
|
||||
script.</p>
|
||||
|
||||
<p><strong>MIME types defined:</strong> <code>text/html</code>
|
||||
(redefined, only takes effect if you load this parser after the
|
||||
XML parser).</p>
|
||||
|
||||
</article>
|
||||
@@ -1,107 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: JavaScript mode</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../../lib/codemirror.css">
|
||||
<script src="../../lib/codemirror.js"></script>
|
||||
<script src="../../addon/edit/matchbrackets.js"></script>
|
||||
<script src="../../addon/comment/continuecomment.js"></script>
|
||||
<script src="../../addon/comment/comment.js"></script>
|
||||
<script src="javascript.js"></script>
|
||||
<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../../index.html">Home</a>
|
||||
<li><a href="../../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/marijnh/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a href="../index.html">Language modes</a>
|
||||
<li><a class=active href="#">JavaScript</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>JavaScript mode</h2>
|
||||
|
||||
|
||||
<div><textarea id="code" name="code">
|
||||
// Demo code (the actual new parser character stream implementation)
|
||||
|
||||
function StringStream(string) {
|
||||
this.pos = 0;
|
||||
this.string = string;
|
||||
}
|
||||
|
||||
StringStream.prototype = {
|
||||
done: function() {return this.pos >= this.string.length;},
|
||||
peek: function() {return this.string.charAt(this.pos);},
|
||||
next: function() {
|
||||
if (this.pos < this.string.length)
|
||||
return this.string.charAt(this.pos++);
|
||||
},
|
||||
eat: function(match) {
|
||||
var ch = this.string.charAt(this.pos);
|
||||
if (typeof match == "string") var ok = ch == match;
|
||||
else var ok = ch && match.test ? match.test(ch) : match(ch);
|
||||
if (ok) {this.pos++; return ch;}
|
||||
},
|
||||
eatWhile: function(match) {
|
||||
var start = this.pos;
|
||||
while (this.eat(match));
|
||||
if (this.pos > start) return this.string.slice(start, this.pos);
|
||||
},
|
||||
backUp: function(n) {this.pos -= n;},
|
||||
column: function() {return this.pos;},
|
||||
eatSpace: function() {
|
||||
var start = this.pos;
|
||||
while (/\s/.test(this.string.charAt(this.pos))) this.pos++;
|
||||
return this.pos - start;
|
||||
},
|
||||
match: function(pattern, consume, caseInsensitive) {
|
||||
if (typeof pattern == "string") {
|
||||
function cased(str) {return caseInsensitive ? str.toLowerCase() : str;}
|
||||
if (cased(this.string).indexOf(cased(pattern), this.pos) == this.pos) {
|
||||
if (consume !== false) this.pos += str.length;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
var match = this.string.slice(this.pos).match(pattern);
|
||||
if (match && consume !== false) this.pos += match[0].length;
|
||||
return match;
|
||||
}
|
||||
}
|
||||
};
|
||||
</textarea></div>
|
||||
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
lineNumbers: true,
|
||||
matchBrackets: true,
|
||||
continueComments: "Enter",
|
||||
extraKeys: {"Ctrl-Q": "toggleComment"}
|
||||
});
|
||||
</script>
|
||||
|
||||
<p>
|
||||
JavaScript mode supports a two configuration
|
||||
options:
|
||||
<ul>
|
||||
<li><code>json</code> which will set the mode to expect JSON
|
||||
data rather than a JavaScript program.</li>
|
||||
<li><code>typescript</code> which will activate additional
|
||||
syntax highlighting and some other things for TypeScript code
|
||||
(<a href="typescript.html">demo</a>).</li>
|
||||
<li><code>statementIndent</code> which (given a number) will
|
||||
determine the amount of indentation to use for statements
|
||||
continued on a new line.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<p><strong>MIME types defined:</strong> <code>text/javascript</code>, <code>application/json</code>, <code>text/typescript</code>, <code>application/typescript</code>.</p>
|
||||
</article>
|
||||
+238
-88
@@ -15,13 +15,14 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||
|
||||
var jsKeywords = {
|
||||
"if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B,
|
||||
"return": C, "break": C, "continue": C, "new": C, "delete": C, "throw": C,
|
||||
"return": C, "break": C, "continue": C, "new": C, "delete": C, "throw": C, "debugger": C,
|
||||
"var": kw("var"), "const": kw("var"), "let": kw("var"),
|
||||
"function": kw("function"), "catch": kw("catch"),
|
||||
"for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
|
||||
"in": operator, "typeof": operator, "instanceof": operator,
|
||||
"true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom,
|
||||
"this": kw("this")
|
||||
"this": kw("this"), "module": kw("module"), "class": kw("class"), "super": kw("atom"),
|
||||
"yield": C, "export": kw("export"), "import": kw("import"), "extends": C
|
||||
};
|
||||
|
||||
// Extend the 'normal' keywords with the TypeScript language extensions
|
||||
@@ -30,7 +31,6 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||
var tsKeywords = {
|
||||
// object-like things
|
||||
"interface": kw("interface"),
|
||||
"class": kw("class"),
|
||||
"extends": kw("extends"),
|
||||
"constructor": kw("constructor"),
|
||||
|
||||
@@ -40,8 +40,6 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||
"protected": kw("protected"),
|
||||
"static": kw("static"),
|
||||
|
||||
"super": kw("super"),
|
||||
|
||||
// types
|
||||
"string": type, "number": type, "bool": type, "any": type
|
||||
};
|
||||
@@ -56,19 +54,16 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||
|
||||
var isOperatorChar = /[+\-*&%=<>!?|~^]/;
|
||||
|
||||
function chain(stream, state, f) {
|
||||
state.tokenize = f;
|
||||
return f(stream, state);
|
||||
}
|
||||
|
||||
function nextUntilUnescaped(stream, end) {
|
||||
var escaped = false, next;
|
||||
function readRegexp(stream) {
|
||||
var escaped = false, next, inSet = false;
|
||||
while ((next = stream.next()) != null) {
|
||||
if (next == end && !escaped)
|
||||
return false;
|
||||
if (!escaped) {
|
||||
if (next == "/" && !inSet) return;
|
||||
if (next == "[") inSet = true;
|
||||
else if (inSet && next == "]") inSet = false;
|
||||
}
|
||||
escaped = !escaped && next == "\\";
|
||||
}
|
||||
return escaped;
|
||||
}
|
||||
|
||||
// Used as scratch variables to communicate multiple values without
|
||||
@@ -78,50 +73,51 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||
type = tp; content = cont;
|
||||
return style;
|
||||
}
|
||||
function jsTokenBase(stream, state) {
|
||||
function tokenBase(stream, state) {
|
||||
var ch = stream.next();
|
||||
if (ch == '"' || ch == "'")
|
||||
return chain(stream, state, jsTokenString(ch));
|
||||
else if (ch == "." && stream.match(/^\d+(?:[eE][+\-]?\d+)?/))
|
||||
if (ch == '"' || ch == "'") {
|
||||
state.tokenize = tokenString(ch);
|
||||
return state.tokenize(stream, state);
|
||||
} else if (ch == "." && stream.match(/^\d+(?:[eE][+\-]?\d+)?/)) {
|
||||
return ret("number", "number");
|
||||
else if (/[\[\]{}\(\),;\:\.]/.test(ch))
|
||||
} else if (ch == "." && stream.match("..")) {
|
||||
return ret("spread", "meta");
|
||||
} else if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
|
||||
return ret(ch);
|
||||
else if (ch == "0" && stream.eat(/x/i)) {
|
||||
} else if (ch == "=" && stream.eat(">")) {
|
||||
return ret("=>", "operator");
|
||||
} else if (ch == "0" && stream.eat(/x/i)) {
|
||||
stream.eatWhile(/[\da-f]/i);
|
||||
return ret("number", "number");
|
||||
}
|
||||
else if (/\d/.test(ch)) {
|
||||
} else if (/\d/.test(ch)) {
|
||||
stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);
|
||||
return ret("number", "number");
|
||||
}
|
||||
else if (ch == "/") {
|
||||
} else if (ch == "/") {
|
||||
if (stream.eat("*")) {
|
||||
return chain(stream, state, jsTokenComment);
|
||||
}
|
||||
else if (stream.eat("/")) {
|
||||
state.tokenize = tokenComment;
|
||||
return tokenComment(stream, state);
|
||||
} else if (stream.eat("/")) {
|
||||
stream.skipToEnd();
|
||||
return ret("comment", "comment");
|
||||
}
|
||||
else if (state.lastType == "operator" || state.lastType == "keyword c" ||
|
||||
/^[\[{}\(,;:]$/.test(state.lastType)) {
|
||||
nextUntilUnescaped(stream, "/");
|
||||
} else if (state.lastType == "operator" || state.lastType == "keyword c" ||
|
||||
state.lastType == "sof" || /^[\[{}\(,;:]$/.test(state.lastType)) {
|
||||
readRegexp(stream);
|
||||
stream.eatWhile(/[gimy]/); // 'y' is "sticky" option in Mozilla
|
||||
return ret("regexp", "string-2");
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
stream.eatWhile(isOperatorChar);
|
||||
return ret("operator", null, stream.current());
|
||||
return ret("operator", "operator", stream.current());
|
||||
}
|
||||
}
|
||||
else if (ch == "#") {
|
||||
} else if (ch == "`") {
|
||||
state.tokenize = tokenQuasi;
|
||||
return tokenQuasi(stream, state);
|
||||
} else if (ch == "#") {
|
||||
stream.skipToEnd();
|
||||
return ret("error", "error");
|
||||
}
|
||||
else if (isOperatorChar.test(ch)) {
|
||||
} else if (isOperatorChar.test(ch)) {
|
||||
stream.eatWhile(isOperatorChar);
|
||||
return ret("operator", null, stream.current());
|
||||
}
|
||||
else {
|
||||
return ret("operator", "operator", stream.current());
|
||||
} else {
|
||||
stream.eatWhile(/[\w\$_]/);
|
||||
var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word];
|
||||
return (known && state.lastType != ".") ? ret(known.type, known.style, word) :
|
||||
@@ -129,19 +125,23 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||
}
|
||||
}
|
||||
|
||||
function jsTokenString(quote) {
|
||||
function tokenString(quote) {
|
||||
return function(stream, state) {
|
||||
if (!nextUntilUnescaped(stream, quote))
|
||||
state.tokenize = jsTokenBase;
|
||||
var escaped = false, next;
|
||||
while ((next = stream.next()) != null) {
|
||||
if (next == quote && !escaped) break;
|
||||
escaped = !escaped && next == "\\";
|
||||
}
|
||||
if (!escaped) state.tokenize = tokenBase;
|
||||
return ret("string", "string");
|
||||
};
|
||||
}
|
||||
|
||||
function jsTokenComment(stream, state) {
|
||||
function tokenComment(stream, state) {
|
||||
var maybeEnd = false, ch;
|
||||
while (ch = stream.next()) {
|
||||
if (ch == "/" && maybeEnd) {
|
||||
state.tokenize = jsTokenBase;
|
||||
state.tokenize = tokenBase;
|
||||
break;
|
||||
}
|
||||
maybeEnd = (ch == "*");
|
||||
@@ -149,6 +149,50 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||
return ret("comment", "comment");
|
||||
}
|
||||
|
||||
function tokenQuasi(stream, state) {
|
||||
var escaped = false, next;
|
||||
while ((next = stream.next()) != null) {
|
||||
if (!escaped && (next == "`" || next == "$" && stream.eat("{"))) {
|
||||
state.tokenize = tokenBase;
|
||||
break;
|
||||
}
|
||||
escaped = !escaped && next == "\\";
|
||||
}
|
||||
return ret("quasi", "string-2", stream.current());
|
||||
}
|
||||
|
||||
var brackets = "([{}])";
|
||||
// This is a crude lookahead trick to try and notice that we're
|
||||
// parsing the argument patterns for a fat-arrow function before we
|
||||
// actually hit the arrow token. It only works if the arrow is on
|
||||
// the same line as the arguments and there's no strange noise
|
||||
// (comments) in between. Fallback is to only notice when we hit the
|
||||
// arrow, and not declare the arguments as locals for the arrow
|
||||
// body.
|
||||
function findFatArrow(stream, state) {
|
||||
if (state.fatArrowAt) state.fatArrowAt = null;
|
||||
var arrow = stream.string.indexOf("=>", stream.start);
|
||||
if (arrow < 0) return;
|
||||
|
||||
var depth = 0, sawSomething = false;
|
||||
for (var pos = arrow - 1; pos >= 0; --pos) {
|
||||
var ch = stream.string.charAt(pos);
|
||||
var bracket = brackets.indexOf(ch);
|
||||
if (bracket >= 0 && bracket < 3) {
|
||||
if (!depth) { ++pos; break; }
|
||||
if (--depth == 0) break;
|
||||
} else if (bracket >= 3 && bracket < 6) {
|
||||
++depth;
|
||||
} else if (/[$\w]/.test(ch)) {
|
||||
sawSomething = true;
|
||||
} else if (sawSomething && !depth) {
|
||||
++pos;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (sawSomething && !depth) state.fatArrowAt = pos;
|
||||
}
|
||||
|
||||
// Parser
|
||||
|
||||
var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true, "this": true};
|
||||
@@ -165,6 +209,10 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||
function inScope(state, varname) {
|
||||
for (var v = state.localVars; v; v = v.next)
|
||||
if (v.name == varname) return true;
|
||||
for (var cx = state.context; cx; cx = cx.prev) {
|
||||
for (var v = cx.vars; v; v = v.next)
|
||||
if (v.name == varname) return true;
|
||||
}
|
||||
}
|
||||
|
||||
function parseJS(state, style, type, content, stream) {
|
||||
@@ -211,7 +259,8 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||
state.localVars = {name: varname, next: state.localVars};
|
||||
} else {
|
||||
if (inList(state.globalVars)) return;
|
||||
state.globalVars = {name: varname, next: state.globalVars};
|
||||
if (parserConfig.globalVars)
|
||||
state.globalVars = {name: varname, next: state.globalVars};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -253,16 +302,15 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||
};
|
||||
}
|
||||
|
||||
function statement(type) {
|
||||
if (type == "var") return cont(pushlex("vardef"), vardef1, expect(";"), poplex);
|
||||
function statement(type, value) {
|
||||
if (type == "var") return cont(pushlex("vardef", value.length), vardef, expect(";"), poplex);
|
||||
if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex);
|
||||
if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
|
||||
if (type == "{") return cont(pushlex("}"), block, poplex);
|
||||
if (type == ";") return cont();
|
||||
if (type == "if") return cont(pushlex("form"), expression, statement, poplex, maybeelse);
|
||||
if (type == "function") return cont(functiondef);
|
||||
if (type == "for") return cont(pushlex("form"), expect("("), pushlex(")"), forspec1, expect(")"),
|
||||
poplex, statement, poplex);
|
||||
if (type == "for") return cont(pushlex("form"), forspec, statement, poplex);
|
||||
if (type == "variable") return cont(pushlex("stat"), maybelabel);
|
||||
if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"),
|
||||
block, poplex, poplex);
|
||||
@@ -270,6 +318,10 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||
if (type == "default") return cont(expect(":"));
|
||||
if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
|
||||
statement, poplex, popcontext);
|
||||
if (type == "module") return cont(pushlex("form"), pushcontext, afterModule, popcontext, poplex);
|
||||
if (type == "class") return cont(pushlex("form"), className, objlit, poplex);
|
||||
if (type == "export") return cont(pushlex("form"), afterExport, poplex);
|
||||
if (type == "import") return cont(pushlex("form"), afterImport, poplex);
|
||||
return pass(pushlex("stat"), expression, expect(";"), poplex);
|
||||
}
|
||||
function expression(type) {
|
||||
@@ -279,14 +331,20 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||
return expressionInner(type, true);
|
||||
}
|
||||
function expressionInner(type, noComma) {
|
||||
if (cx.state.fatArrowAt == cx.stream.start) {
|
||||
var body = noComma ? arrowBodyNoComma : arrowBody;
|
||||
if (type == "(") return cont(pushcontext, pushlex(")"), commasep(pattern, ")"), poplex, expect("=>"), body, popcontext);
|
||||
else if (type == "variable") return pass(pushcontext, pattern, expect("=>"), body, popcontext);
|
||||
}
|
||||
|
||||
var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma;
|
||||
if (atomicTypes.hasOwnProperty(type)) return cont(maybeop);
|
||||
if (type == "function") return cont(functiondef);
|
||||
if (type == "keyword c") return cont(noComma ? maybeexpressionNoComma : maybeexpression);
|
||||
if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeop);
|
||||
if (type == "operator") return cont(noComma ? expressionNoComma : expression);
|
||||
if (type == "[") return cont(pushlex("]"), commasep(expressionNoComma, "]"), poplex, maybeop);
|
||||
if (type == "{") return cont(pushlex("}"), commasep(objprop, "}"), poplex, maybeop);
|
||||
if (type == "(") return cont(pushlex(")"), maybeexpression, comprehension, expect(")"), poplex, maybeop);
|
||||
if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression);
|
||||
if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop);
|
||||
if (type == "{") return contCommasep(objprop, "}", null, maybeop);
|
||||
return cont();
|
||||
}
|
||||
function maybeexpression(type) {
|
||||
@@ -305,16 +363,39 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||
function maybeoperatorNoComma(type, value, noComma) {
|
||||
var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma;
|
||||
var expr = noComma == false ? expression : expressionNoComma;
|
||||
if (value == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext);
|
||||
if (type == "operator") {
|
||||
if (/\+\+|--/.test(value)) return cont(me);
|
||||
if (value == "?") return cont(expression, expect(":"), expr);
|
||||
return cont(expr);
|
||||
}
|
||||
if (type == "quasi") { cx.cc.push(me); return quasi(value); }
|
||||
if (type == ";") return;
|
||||
if (type == "(") return cont(pushlex(")", "call"), commasep(expressionNoComma, ")"), poplex, me);
|
||||
if (type == "(") return contCommasep(expressionNoComma, ")", "call", me);
|
||||
if (type == ".") return cont(property, me);
|
||||
if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), poplex, me);
|
||||
}
|
||||
function quasi(value) {
|
||||
if (value.slice(value.length - 2) != "${") return cont();
|
||||
return cont(expression, continueQuasi);
|
||||
}
|
||||
function continueQuasi(type) {
|
||||
if (type == "}") {
|
||||
cx.marked = "string-2";
|
||||
cx.state.tokenize = tokenQuasi;
|
||||
return cont();
|
||||
}
|
||||
}
|
||||
function arrowBody(type) {
|
||||
findFatArrow(cx.stream, cx.state);
|
||||
if (type == "{") return pass(statement);
|
||||
return pass(expression);
|
||||
}
|
||||
function arrowBodyNoComma(type) {
|
||||
findFatArrow(cx.stream, cx.state);
|
||||
if (type == "{") return pass(statement);
|
||||
return pass(expressionNoComma);
|
||||
}
|
||||
function maybelabel(type) {
|
||||
if (type == ":") return cont(poplex, statement);
|
||||
return pass(maybeoperatorComma, expect(";"), poplex);
|
||||
@@ -328,15 +409,20 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||
if (value == "get" || value == "set") return cont(getterSetter);
|
||||
} else if (type == "number" || type == "string") {
|
||||
cx.marked = type + " property";
|
||||
} else if (type == "[") {
|
||||
return cont(expression, expect("]"), afterprop);
|
||||
}
|
||||
if (atomicTypes.hasOwnProperty(type)) return cont(expect(":"), expressionNoComma);
|
||||
if (atomicTypes.hasOwnProperty(type)) return cont(afterprop);
|
||||
}
|
||||
function getterSetter(type) {
|
||||
if (type == ":") return cont(expression);
|
||||
if (type != "variable") return cont(expect(":"), expression);
|
||||
if (type != "variable") return pass(afterprop);
|
||||
cx.marked = "property";
|
||||
return cont(functiondef);
|
||||
}
|
||||
function afterprop(type) {
|
||||
if (type == ":") return cont(expressionNoComma);
|
||||
if (type == "(") return pass(functiondef);
|
||||
}
|
||||
function commasep(what, end) {
|
||||
function proceed(type) {
|
||||
if (type == ",") {
|
||||
@@ -349,75 +435,138 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||
}
|
||||
return function(type) {
|
||||
if (type == end) return cont();
|
||||
else return pass(what, proceed);
|
||||
return pass(what, proceed);
|
||||
};
|
||||
}
|
||||
function contCommasep(what, end, info) {
|
||||
for (var i = 3; i < arguments.length; i++)
|
||||
cx.cc.push(arguments[i]);
|
||||
return cont(pushlex(end, info), commasep(what, end), poplex);
|
||||
}
|
||||
function block(type) {
|
||||
if (type == "}") return cont();
|
||||
return pass(statement, block);
|
||||
}
|
||||
function maybetype(type) {
|
||||
if (type == ":") return cont(typedef);
|
||||
return pass();
|
||||
if (isTS && type == ":") return cont(typedef);
|
||||
}
|
||||
function typedef(type) {
|
||||
if (type == "variable"){cx.marked = "variable-3"; return cont();}
|
||||
return pass();
|
||||
}
|
||||
function vardef1(type, value) {
|
||||
if (type == "variable") {
|
||||
function vardef() {
|
||||
return pass(pattern, maybetype, maybeAssign, vardefCont);
|
||||
}
|
||||
function pattern(type, value) {
|
||||
if (type == "variable") { register(value); return cont(); }
|
||||
if (type == "[") return contCommasep(pattern, "]");
|
||||
if (type == "{") return contCommasep(proppattern, "}");
|
||||
}
|
||||
function proppattern(type, value) {
|
||||
if (type == "variable" && !cx.stream.match(/^\s*:/, false)) {
|
||||
register(value);
|
||||
return isTS ? cont(maybetype, vardef2) : cont(vardef2);
|
||||
return cont(maybeAssign);
|
||||
}
|
||||
return pass();
|
||||
if (type == "variable") cx.marked = "property";
|
||||
return cont(expect(":"), pattern, maybeAssign);
|
||||
}
|
||||
function vardef2(type, value) {
|
||||
if (value == "=") return cont(expressionNoComma, vardef2);
|
||||
if (type == ",") return cont(vardef1);
|
||||
function maybeAssign(_type, value) {
|
||||
if (value == "=") return cont(expressionNoComma);
|
||||
}
|
||||
function vardefCont(type) {
|
||||
if (type == ",") return cont(vardef);
|
||||
}
|
||||
function maybeelse(type, value) {
|
||||
if (type == "keyword b" && value == "else") return cont(pushlex("form"), statement, poplex);
|
||||
}
|
||||
function forspec(type) {
|
||||
if (type == "(") return cont(pushlex(")"), forspec1, expect(")"), poplex);
|
||||
}
|
||||
function forspec1(type) {
|
||||
if (type == "var") return cont(vardef1, expect(";"), forspec2);
|
||||
if (type == "var") return cont(vardef, expect(";"), forspec2);
|
||||
if (type == ";") return cont(forspec2);
|
||||
if (type == "variable") return cont(formaybein);
|
||||
if (type == "variable") return cont(formaybeinof);
|
||||
return pass(expression, expect(";"), forspec2);
|
||||
}
|
||||
function formaybein(_type, value) {
|
||||
if (value == "in") return cont(expression);
|
||||
function formaybeinof(_type, value) {
|
||||
if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); }
|
||||
return cont(maybeoperatorComma, forspec2);
|
||||
}
|
||||
function forspec2(type, value) {
|
||||
if (type == ";") return cont(forspec3);
|
||||
if (value == "in") return cont(expression);
|
||||
if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); }
|
||||
return pass(expression, expect(";"), forspec3);
|
||||
}
|
||||
function forspec3(type) {
|
||||
if (type != ")") cont(expression);
|
||||
}
|
||||
function functiondef(type, value) {
|
||||
if (value == "*") {cx.marked = "keyword"; return cont(functiondef);}
|
||||
if (type == "variable") {register(value); return cont(functiondef);}
|
||||
if (type == "(") return cont(pushlex(")"), pushcontext, commasep(funarg, ")"), poplex, statement, popcontext);
|
||||
if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, statement, popcontext);
|
||||
}
|
||||
function funarg(type, value) {
|
||||
if (type == "variable") {register(value); return isTS ? cont(maybetype) : cont();}
|
||||
function funarg(type) {
|
||||
if (type == "spread") return cont(funarg);
|
||||
return pass(pattern, maybetype);
|
||||
}
|
||||
function className(type, value) {
|
||||
if (type == "variable") {register(value); return cont(classNameAfter);}
|
||||
}
|
||||
function classNameAfter(_type, value) {
|
||||
if (value == "extends") return cont(expression);
|
||||
}
|
||||
function objlit(type) {
|
||||
if (type == "{") return contCommasep(objprop, "}");
|
||||
}
|
||||
function afterModule(type, value) {
|
||||
if (type == "string") return cont(statement);
|
||||
if (type == "variable") { register(value); return cont(maybeFrom); }
|
||||
}
|
||||
function afterExport(_type, value) {
|
||||
if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";")); }
|
||||
if (value == "default") { cx.marked = "keyword"; return cont(expression, expect(";")); }
|
||||
return pass(statement);
|
||||
}
|
||||
function afterImport(type) {
|
||||
if (type == "string") return cont();
|
||||
return pass(importSpec, maybeFrom);
|
||||
}
|
||||
function importSpec(type, value) {
|
||||
if (type == "{") return contCommasep(importSpec, "}");
|
||||
if (type == "variable") register(value);
|
||||
return cont();
|
||||
}
|
||||
function maybeFrom(_type, value) {
|
||||
if (value == "from") { cx.marked = "keyword"; return cont(expression); }
|
||||
}
|
||||
function arrayLiteral(type) {
|
||||
if (type == "]") return cont();
|
||||
return pass(expressionNoComma, maybeArrayComprehension);
|
||||
}
|
||||
function maybeArrayComprehension(type) {
|
||||
if (type == "for") return pass(comprehension, expect("]"));
|
||||
if (type == ",") return cont(commasep(expressionNoComma, "]"));
|
||||
return pass(commasep(expressionNoComma, "]"));
|
||||
}
|
||||
function comprehension(type) {
|
||||
if (type == "for") return cont(forspec, comprehension);
|
||||
if (type == "if") return cont(expression, comprehension);
|
||||
}
|
||||
|
||||
// Interface
|
||||
|
||||
return {
|
||||
startState: function(basecolumn) {
|
||||
return {
|
||||
tokenize: jsTokenBase,
|
||||
lastType: null,
|
||||
var state = {
|
||||
tokenize: tokenBase,
|
||||
lastType: "sof",
|
||||
cc: [],
|
||||
lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
|
||||
localVars: parserConfig.localVars,
|
||||
globalVars: parserConfig.globalVars,
|
||||
context: parserConfig.localVars && {vars: parserConfig.localVars},
|
||||
indented: 0
|
||||
};
|
||||
if (parserConfig.globalVars) state.globalVars = parserConfig.globalVars;
|
||||
return state;
|
||||
},
|
||||
|
||||
token: function(stream, state) {
|
||||
@@ -425,8 +574,9 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||
if (!state.lexical.hasOwnProperty("align"))
|
||||
state.lexical.align = false;
|
||||
state.indented = stream.indentation();
|
||||
findFatArrow(stream, state);
|
||||
}
|
||||
if (state.tokenize != jsTokenComment && stream.eatSpace()) return null;
|
||||
if (state.tokenize != tokenComment && stream.eatSpace()) return null;
|
||||
var style = state.tokenize(stream, state);
|
||||
if (type == "comment") return style;
|
||||
state.lastType = type == "operator" && (content == "++" || content == "--") ? "incdec" : type;
|
||||
@@ -434,21 +584,21 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||
},
|
||||
|
||||
indent: function(state, textAfter) {
|
||||
if (state.tokenize == jsTokenComment) return CodeMirror.Pass;
|
||||
if (state.tokenize != jsTokenBase) return 0;
|
||||
if (state.tokenize == tokenComment) return CodeMirror.Pass;
|
||||
if (state.tokenize != tokenBase) return 0;
|
||||
var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical;
|
||||
// Kludge to prevent 'maybelse' from blocking lexical scope pops
|
||||
for (var i = state.cc.length - 1; i >= 0; --i) {
|
||||
var c = state.cc[i];
|
||||
if (c == poplex) lexical = lexical.prev;
|
||||
else if (c != maybeelse || /^else\b/.test(textAfter)) break;
|
||||
else if (c != maybeelse) break;
|
||||
}
|
||||
if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev;
|
||||
if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat")
|
||||
lexical = lexical.prev;
|
||||
var type = lexical.type, closing = firstChar == type;
|
||||
|
||||
if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? 4 : 0);
|
||||
if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? lexical.info + 1 : 0);
|
||||
else if (type == "form" && firstChar == "{") return lexical.indented;
|
||||
else if (type == "form") return lexical.indented + indentUnit;
|
||||
else if (type == "stat")
|
||||
|
||||
+8
-3
@@ -15,11 +15,14 @@ CodeMirror.modeInfo = [
|
||||
{name: 'diff', mime: 'text/x-diff', mode: 'diff'},
|
||||
{name: 'DTD', mime: 'application/xml-dtd', mode: 'dtd'},
|
||||
{name: 'ECL', mime: 'text/x-ecl', mode: 'ecl'},
|
||||
{name: 'Eiffel', mime: 'text/x-eiffel', mode: 'eiffel'},
|
||||
{name: 'Erlang', mime: 'text/x-erlang', mode: 'erlang'},
|
||||
{name: 'Fortran', mime: 'text/x-fortran', mode: 'fortran'},
|
||||
{name: 'F#', mime: 'text/x-fsharp', mode: 'mllike'},
|
||||
{name: 'Gas', mime: 'text/x-gas', mode: 'gas'},
|
||||
{name: 'Gherkin', mime: 'text/x-feature', mode: 'gherkin'},
|
||||
{name: 'GitHub Flavored Markdown', mime: 'text/x-gfm', mode: 'gfm'},
|
||||
{name: 'GO', mime: 'text/x-go', mode: 'go'},
|
||||
{name: 'Go', mime: 'text/x-go', mode: 'go'},
|
||||
{name: 'Groovy', mime: 'text/x-groovy', mode: 'groovy'},
|
||||
{name: 'HAML', mime: 'text/x-haml', mode: 'haml'},
|
||||
{name: 'Haskell', mime: 'text/x-haskell', mode: 'haskell'},
|
||||
@@ -34,7 +37,8 @@ CodeMirror.modeInfo = [
|
||||
{name: 'JSON', mime: 'application/x-json', mode: 'javascript'},
|
||||
{name: 'JSON', mime: 'application/json', mode: 'javascript'},
|
||||
{name: 'TypeScript', mime: 'application/typescript', mode: 'javascript'},
|
||||
{name: 'Jinja2', mime: 'jinja2', mode: 'jinja2'},
|
||||
{name: 'Jinja2', mime: null, mode: 'jinja2'},
|
||||
{name: 'Julia', mime: 'text/x-julia', mode: 'julia'},
|
||||
{name: 'LESS', mime: 'text/x-less', mode: 'less'},
|
||||
{name: 'LiveScript', mime: 'text/x-livescript', mode: 'livescript'},
|
||||
{name: 'Lua', mime: 'text/x-lua', mode: 'lua'},
|
||||
@@ -42,9 +46,10 @@ CodeMirror.modeInfo = [
|
||||
{name: 'mIRC', mime: 'text/mirc', mode: 'mirc'},
|
||||
{name: 'Nginx', mime: 'text/x-nginx-conf', mode: 'nginx'},
|
||||
{name: 'NTriples', mime: 'text/n-triples', mode: 'ntriples'},
|
||||
{name: 'OCaml', mime: 'text/x-ocaml', mode: 'ocaml'},
|
||||
{name: 'OCaml', mime: 'text/x-ocaml', mode: 'mllike'},
|
||||
{name: 'Octave', mime: 'text/x-octave', mode: 'octave'},
|
||||
{name: 'Pascal', mime: 'text/x-pascal', mode: 'pascal'},
|
||||
{name: 'PEG.js', mime: null, mode: 'pegjs'},
|
||||
{name: 'Perl', mime: 'text/x-perl', mode: 'perl'},
|
||||
{name: 'PHP', mime: 'text/x-php', mode: 'php'},
|
||||
{name: 'PHP(HTML)', mime: 'application/x-httpd-php', mode: 'php'},
|
||||
|
||||
@@ -1,187 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Python mode</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../../lib/codemirror.css">
|
||||
<script src="../../lib/codemirror.js"></script>
|
||||
<script src="../../addon/edit/matchbrackets.js"></script>
|
||||
<script src="python.js"></script>
|
||||
<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../../index.html">Home</a>
|
||||
<li><a href="../../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/marijnh/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a href="../index.html">Language modes</a>
|
||||
<li><a class=active href="#">Python</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>Python mode</h2>
|
||||
|
||||
<div><textarea id="code" name="code">
|
||||
# Literals
|
||||
1234
|
||||
0.0e101
|
||||
.123
|
||||
0b01010011100
|
||||
0o01234567
|
||||
0x0987654321abcdef
|
||||
7
|
||||
2147483647
|
||||
3L
|
||||
79228162514264337593543950336L
|
||||
0x100000000L
|
||||
79228162514264337593543950336
|
||||
0xdeadbeef
|
||||
3.14j
|
||||
10.j
|
||||
10j
|
||||
.001j
|
||||
1e100j
|
||||
3.14e-10j
|
||||
|
||||
|
||||
# String Literals
|
||||
'For\''
|
||||
"God\""
|
||||
"""so loved
|
||||
the world"""
|
||||
'''that he gave
|
||||
his only begotten\' '''
|
||||
'that whosoever believeth \
|
||||
in him'
|
||||
''
|
||||
|
||||
# Identifiers
|
||||
__a__
|
||||
a.b
|
||||
a.b.c
|
||||
|
||||
# Operators
|
||||
+ - * / % & | ^ ~ < >
|
||||
== != <= >= <> << >> // **
|
||||
and or not in is
|
||||
|
||||
# Delimiters
|
||||
() [] {} , : ` = ; @ . # Note that @ and . require the proper context.
|
||||
+= -= *= /= %= &= |= ^=
|
||||
//= >>= <<= **=
|
||||
|
||||
# Keywords
|
||||
as assert break class continue def del elif else except
|
||||
finally for from global if import lambda pass raise
|
||||
return try while with yield
|
||||
|
||||
# Python 2 Keywords (otherwise Identifiers)
|
||||
exec print
|
||||
|
||||
# Python 3 Keywords (otherwise Identifiers)
|
||||
nonlocal
|
||||
|
||||
# Types
|
||||
bool classmethod complex dict enumerate float frozenset int list object
|
||||
property reversed set slice staticmethod str super tuple type
|
||||
|
||||
# Python 2 Types (otherwise Identifiers)
|
||||
basestring buffer file long unicode xrange
|
||||
|
||||
# Python 3 Types (otherwise Identifiers)
|
||||
bytearray bytes filter map memoryview open range zip
|
||||
|
||||
# Some Example code
|
||||
import os
|
||||
from package import ParentClass
|
||||
|
||||
@nonsenseDecorator
|
||||
def doesNothing():
|
||||
pass
|
||||
|
||||
class ExampleClass(ParentClass):
|
||||
@staticmethod
|
||||
def example(inputStr):
|
||||
a = list(inputStr)
|
||||
a.reverse()
|
||||
return ''.join(a)
|
||||
|
||||
def __init__(self, mixin = 'Hello'):
|
||||
self.mixin = mixin
|
||||
|
||||
</textarea></div>
|
||||
|
||||
|
||||
<h2>Cython mode</h2>
|
||||
|
||||
<div><textarea id="code-cython" name="code-cython">
|
||||
|
||||
import numpy as np
|
||||
cimport cython
|
||||
from libc.math cimport sqrt
|
||||
|
||||
@cython.boundscheck(False)
|
||||
@cython.wraparound(False)
|
||||
def pairwise_cython(double[:, ::1] X):
|
||||
cdef int M = X.shape[0]
|
||||
cdef int N = X.shape[1]
|
||||
cdef double tmp, d
|
||||
cdef double[:, ::1] D = np.empty((M, M), dtype=np.float64)
|
||||
for i in range(M):
|
||||
for j in range(M):
|
||||
d = 0.0
|
||||
for k in range(N):
|
||||
tmp = X[i, k] - X[j, k]
|
||||
d += tmp * tmp
|
||||
D[i, j] = sqrt(d)
|
||||
return np.asarray(D)
|
||||
|
||||
</textarea></div>
|
||||
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
mode: {name: "python",
|
||||
version: 2,
|
||||
singleLineStringErrors: false},
|
||||
lineNumbers: true,
|
||||
indentUnit: 4,
|
||||
tabMode: "shift",
|
||||
matchBrackets: true
|
||||
});
|
||||
|
||||
CodeMirror.fromTextArea(document.getElementById("code-cython"), {
|
||||
mode: {name: "text/x-cython",
|
||||
version: 2,
|
||||
singleLineStringErrors: false},
|
||||
lineNumbers: true,
|
||||
indentUnit: 4,
|
||||
tabMode: "shift",
|
||||
matchBrackets: true
|
||||
});
|
||||
</script>
|
||||
<h2>Configuration Options for Python mode:</h2>
|
||||
<ul>
|
||||
<li>version - 2/3 - The version of Python to recognize. Default is 2.</li>
|
||||
<li>singleLineStringErrors - true/false - If you have a single-line string that is not terminated at the end of the line, this will show subsequent lines as errors if true, otherwise it will consider the newline as the end of the string. Default is false.</li>
|
||||
</ul>
|
||||
<h2>Advanced Configuration Options:</h2>
|
||||
<p>Usefull for superset of python syntax like Enthought enaml, IPython magics and questionmark help</p>
|
||||
<ul>
|
||||
<li>singleOperators - RegEx - Regular Expression for single operator matching, default : <pre>^[\\+\\-\\*/%&|\\^~<>!]</pre></li>
|
||||
<li>singleDelimiters - RegEx - Regular Expression for single delimiter matching, default : <pre>^[\\(\\)\\[\\]\\{\\}@,:`=;\\.]</pre></li>
|
||||
<li>doubleOperators - RegEx - Regular Expression for double operators matching, default : <pre>^((==)|(!=)|(<=)|(>=)|(<>)|(<<)|(>>)|(//)|(\\*\\*))</pre></li>
|
||||
<li>doubleDelimiters - RegEx - Regular Expressoin for double delimiters matching, default : <pre>^((\\+=)|(\\-=)|(\\*=)|(%=)|(/=)|(&=)|(\\|=)|(\\^=))</pre></li>
|
||||
<li>tripleDelimiters - RegEx - Regular Expression for triple delimiters matching, default : <pre>^((//=)|(>>=)|(<<=)|(\\*\\*=))</pre></li>
|
||||
<li>identifiers - RegEx - Regular Expression for identifier, default : <pre>^[_A-Za-z][_A-Za-z0-9]*</pre></li>
|
||||
<li>extra_keywords - list of string - List of extra words ton consider as keywords</li>
|
||||
<li>extra_builtins - list of string - List of extra words ton consider as builtins</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<p><strong>MIME types defined:</strong> <code>text/x-python</code> and <code>text/x-cython</code>.</p>
|
||||
</article>
|
||||
@@ -11,6 +11,7 @@ CodeMirror.defineMode("python", function(conf, parserConf) {
|
||||
var doubleDelimiters = parserConf.doubleDelimiters || new RegExp("^((\\+=)|(\\-=)|(\\*=)|(%=)|(/=)|(&=)|(\\|=)|(\\^=))");
|
||||
var tripleDelimiters = parserConf.tripleDelimiters || new RegExp("^((//=)|(>>=)|(<<=)|(\\*\\*=))");
|
||||
var identifiers = parserConf.identifiers|| new RegExp("^[_A-Za-z][_A-Za-z0-9]*");
|
||||
var hangingIndent = parserConf.hangingIndent || parserConf.indentUnit;
|
||||
|
||||
var wordOperators = wordRegexp(['and', 'or', 'not', 'is', 'in']);
|
||||
var commonkeywords = ['as', 'assert', 'break', 'class', 'continue',
|
||||
@@ -211,6 +212,11 @@ CodeMirror.defineMode("python", function(conf, parserConf) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (stream.match(/\s*($|#)/, false)) {
|
||||
// An open paren/bracket/brace with only space or comments after it
|
||||
// on the line will indent the next line a fixed amount, to make it
|
||||
// easier to put arguments, list items, etc. on their own lines.
|
||||
indentUnit = stream.indentation() + hangingIndent;
|
||||
} else {
|
||||
indentUnit = stream.column() + stream.current().length;
|
||||
}
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: XML mode</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../../lib/codemirror.css">
|
||||
<script src="../../lib/codemirror.js"></script>
|
||||
<script src="xml.js"></script>
|
||||
<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><img id=logo src="../../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../../index.html">Home</a>
|
||||
<li><a href="../../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/marijnh/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a href="../index.html">Language modes</a>
|
||||
<li><a class=active href="#">XML</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>XML mode</h2>
|
||||
<form><textarea id="code" name="code">
|
||||
<html style="color: green">
|
||||
<!-- this is a comment -->
|
||||
<head>
|
||||
<title>HTML Example</title>
|
||||
</head>
|
||||
<body>
|
||||
The indentation tries to be <em>somewhat &quot;do what
|
||||
I mean&quot;</em>... but might not match your style.
|
||||
</body>
|
||||
</html>
|
||||
</textarea></form>
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
mode: {name: "xml", alignCDATA: true},
|
||||
lineNumbers: true
|
||||
});
|
||||
</script>
|
||||
<p>The XML mode supports two configuration parameters:</p>
|
||||
<dl>
|
||||
<dt><code>htmlMode (boolean)</code></dt>
|
||||
<dd>This switches the mode to parse HTML instead of XML. This
|
||||
means attributes do not have to be quoted, and some elements
|
||||
(such as <code>br</code>) do not require a closing tag.</dd>
|
||||
<dt><code>alignCDATA (boolean)</code></dt>
|
||||
<dd>Setting this to true will force the opening tag of CDATA
|
||||
blocks to not be indented.</dd>
|
||||
</dl>
|
||||
|
||||
<p><strong>MIME types defined:</strong> <code>application/xml</code>, <code>text/html</code>.</p>
|
||||
</article>
|
||||
+93
-102
@@ -45,7 +45,7 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
|
||||
var alignCDATA = parserConfig.alignCDATA;
|
||||
|
||||
// Return variables for tokenizers
|
||||
var tagName, type;
|
||||
var tagName, type, setStyle;
|
||||
|
||||
function inText(stream, state) {
|
||||
function chain(parser) {
|
||||
@@ -76,7 +76,7 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
|
||||
tagName = "";
|
||||
var c;
|
||||
while ((c = stream.eat(/[^\s\u00a0=<>\"\'\/?]/))) tagName += c;
|
||||
if (!tagName) return "error";
|
||||
if (!tagName) return "tag error";
|
||||
type = isClose ? "closeTag" : "openTag";
|
||||
state.tokenize = inTag;
|
||||
return "tag";
|
||||
@@ -109,7 +109,11 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
|
||||
type = "equals";
|
||||
return null;
|
||||
} else if (ch == "<") {
|
||||
return "error";
|
||||
state.tokenize = inText;
|
||||
state.state = baseState;
|
||||
state.tagName = state.tagStart = null;
|
||||
var next = state.tokenize(stream, state);
|
||||
return next ? next + " error" : "error";
|
||||
} else if (/[\'\"]/.test(ch)) {
|
||||
state.tokenize = inAttribute(ch);
|
||||
state.stringStartCol = stream.column();
|
||||
@@ -167,138 +171,125 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
|
||||
};
|
||||
}
|
||||
|
||||
var curState, curStream, setStyle;
|
||||
function pass() {
|
||||
for (var i = arguments.length - 1; i >= 0; i--) curState.cc.push(arguments[i]);
|
||||
function Context(state, tagName, startOfLine) {
|
||||
this.prev = state.context;
|
||||
this.tagName = tagName;
|
||||
this.indent = state.indented;
|
||||
this.startOfLine = startOfLine;
|
||||
if (Kludges.doNotIndent.hasOwnProperty(tagName) || (state.context && state.context.noIndent))
|
||||
this.noIndent = true;
|
||||
}
|
||||
function cont() {
|
||||
pass.apply(null, arguments);
|
||||
return true;
|
||||
function popContext(state) {
|
||||
if (state.context) state.context = state.context.prev;
|
||||
}
|
||||
function maybePopContext(state, nextTagName) {
|
||||
var parentTagName;
|
||||
while (true) {
|
||||
if (!state.context) {
|
||||
return;
|
||||
}
|
||||
parentTagName = state.context.tagName.toLowerCase();
|
||||
if (!Kludges.contextGrabbers.hasOwnProperty(parentTagName) ||
|
||||
!Kludges.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) {
|
||||
return;
|
||||
}
|
||||
popContext(state);
|
||||
}
|
||||
}
|
||||
|
||||
function pushContext(tagName, startOfLine) {
|
||||
var noIndent = Kludges.doNotIndent.hasOwnProperty(tagName) || (curState.context && curState.context.noIndent);
|
||||
curState.context = {
|
||||
prev: curState.context,
|
||||
tagName: tagName,
|
||||
indent: curState.indented,
|
||||
startOfLine: startOfLine,
|
||||
noIndent: noIndent
|
||||
};
|
||||
}
|
||||
function popContext() {
|
||||
if (curState.context) curState.context = curState.context.prev;
|
||||
}
|
||||
|
||||
function element(type) {
|
||||
function baseState(type, stream, state) {
|
||||
if (type == "openTag") {
|
||||
curState.tagName = tagName;
|
||||
curState.tagStart = curStream.column();
|
||||
return cont(attributes, endtag(curState.startOfLine));
|
||||
state.tagName = tagName;
|
||||
state.tagStart = stream.column();
|
||||
return attrState;
|
||||
} else if (type == "closeTag") {
|
||||
var err = false;
|
||||
if (curState.context) {
|
||||
if (curState.context.tagName != tagName) {
|
||||
if (Kludges.implicitlyClosed.hasOwnProperty(curState.context.tagName.toLowerCase())) {
|
||||
popContext();
|
||||
}
|
||||
err = !curState.context || curState.context.tagName != tagName;
|
||||
if (state.context) {
|
||||
if (state.context.tagName != tagName) {
|
||||
if (Kludges.implicitlyClosed.hasOwnProperty(state.context.tagName.toLowerCase()))
|
||||
popContext(state);
|
||||
err = !state.context || state.context.tagName != tagName;
|
||||
}
|
||||
} else {
|
||||
err = true;
|
||||
}
|
||||
if (err) setStyle = "error";
|
||||
return cont(endclosetag(err));
|
||||
return err ? closeStateErr : closeState;
|
||||
} else {
|
||||
return baseState;
|
||||
}
|
||||
return cont();
|
||||
}
|
||||
function endtag(startOfLine) {
|
||||
return function(type) {
|
||||
var tagName = curState.tagName;
|
||||
curState.tagName = curState.tagStart = null;
|
||||
if (type == "selfcloseTag" ||
|
||||
(type == "endTag" && Kludges.autoSelfClosers.hasOwnProperty(tagName.toLowerCase()))) {
|
||||
maybePopContext(tagName.toLowerCase());
|
||||
return cont();
|
||||
}
|
||||
if (type == "endTag") {
|
||||
maybePopContext(tagName.toLowerCase());
|
||||
pushContext(tagName, startOfLine);
|
||||
return cont();
|
||||
}
|
||||
return cont();
|
||||
};
|
||||
}
|
||||
function endclosetag(err) {
|
||||
return function(type) {
|
||||
if (err) setStyle = "error";
|
||||
if (type == "endTag") { popContext(); return cont(); }
|
||||
function closeState(type, _stream, state) {
|
||||
if (type != "endTag") {
|
||||
setStyle = "error";
|
||||
return cont(arguments.callee);
|
||||
};
|
||||
}
|
||||
function maybePopContext(nextTagName) {
|
||||
var parentTagName;
|
||||
while (true) {
|
||||
if (!curState.context) {
|
||||
return;
|
||||
}
|
||||
parentTagName = curState.context.tagName.toLowerCase();
|
||||
if (!Kludges.contextGrabbers.hasOwnProperty(parentTagName) ||
|
||||
!Kludges.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) {
|
||||
return;
|
||||
}
|
||||
popContext();
|
||||
return closeState;
|
||||
}
|
||||
popContext(state);
|
||||
return baseState;
|
||||
}
|
||||
function closeStateErr(type, stream, state) {
|
||||
setStyle = "error";
|
||||
return closeState(type, stream, state);
|
||||
}
|
||||
|
||||
function attributes(type) {
|
||||
if (type == "word") {setStyle = "attribute"; return cont(attribute, attributes);}
|
||||
if (type == "endTag" || type == "selfcloseTag") return pass();
|
||||
function attrState(type, _stream, state) {
|
||||
if (type == "word") {
|
||||
setStyle = "attribute";
|
||||
return attrEqState;
|
||||
} else if (type == "endTag" || type == "selfcloseTag") {
|
||||
var tagName = state.tagName, tagStart = state.tagStart;
|
||||
state.tagName = state.tagStart = null;
|
||||
if (type == "selfcloseTag" ||
|
||||
Kludges.autoSelfClosers.hasOwnProperty(tagName.toLowerCase())) {
|
||||
maybePopContext(state, tagName.toLowerCase());
|
||||
} else {
|
||||
maybePopContext(state, tagName.toLowerCase());
|
||||
state.context = new Context(state, tagName, tagStart == state.indented);
|
||||
}
|
||||
return baseState;
|
||||
}
|
||||
setStyle = "error";
|
||||
return cont(attributes);
|
||||
return attrState;
|
||||
}
|
||||
function attribute(type) {
|
||||
if (type == "equals") return cont(attvalue, attributes);
|
||||
function attrEqState(type, stream, state) {
|
||||
if (type == "equals") return attrValueState;
|
||||
if (!Kludges.allowMissing) setStyle = "error";
|
||||
else if (type == "word") {setStyle = "attribute"; return cont(attribute, attributes);}
|
||||
return (type == "endTag" || type == "selfcloseTag") ? pass() : cont();
|
||||
return attrState(type, stream, state);
|
||||
}
|
||||
function attvalue(type) {
|
||||
if (type == "string") return cont(attvaluemaybe);
|
||||
if (type == "word" && Kludges.allowUnquoted) {setStyle = "string"; return cont();}
|
||||
function attrValueState(type, stream, state) {
|
||||
if (type == "string") return attrContinuedState;
|
||||
if (type == "word" && Kludges.allowUnquoted) {setStyle = "string"; return attrState;}
|
||||
setStyle = "error";
|
||||
return (type == "endTag" || type == "selfCloseTag") ? pass() : cont();
|
||||
return attrState(type, stream, state);
|
||||
}
|
||||
function attvaluemaybe(type) {
|
||||
if (type == "string") return cont(attvaluemaybe);
|
||||
else return pass();
|
||||
function attrContinuedState(type, stream, state) {
|
||||
if (type == "string") return attrContinuedState;
|
||||
return attrState(type, stream, state);
|
||||
}
|
||||
|
||||
return {
|
||||
startState: function() {
|
||||
return {tokenize: inText, cc: [], indented: 0, startOfLine: true, tagName: null, tagStart: null, context: null};
|
||||
return {tokenize: inText,
|
||||
state: baseState,
|
||||
indented: 0,
|
||||
tagName: null, tagStart: null,
|
||||
context: null};
|
||||
},
|
||||
|
||||
token: function(stream, state) {
|
||||
if (!state.tagName && stream.sol()) {
|
||||
state.startOfLine = true;
|
||||
if (!state.tagName && stream.sol())
|
||||
state.indented = stream.indentation();
|
||||
}
|
||||
if (stream.eatSpace()) return null;
|
||||
|
||||
setStyle = type = tagName = null;
|
||||
if (stream.eatSpace()) return null;
|
||||
tagName = type = null;
|
||||
var style = state.tokenize(stream, state);
|
||||
state.type = type;
|
||||
if ((style || type) && style != "comment") {
|
||||
curState = state; curStream = stream;
|
||||
while (true) {
|
||||
var comb = state.cc.pop() || element;
|
||||
if (comb(type || style)) break;
|
||||
}
|
||||
setStyle = null;
|
||||
state.state = state.state(type || style, stream, state);
|
||||
if (setStyle)
|
||||
style = setStyle == "error" ? style + " error" : setStyle;
|
||||
}
|
||||
state.startOfLine = false;
|
||||
return setStyle || style;
|
||||
return style;
|
||||
},
|
||||
|
||||
indent: function(state, textAfter, fullLine) {
|
||||
@@ -307,8 +298,8 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
|
||||
if (state.tokenize.isInAttribute) {
|
||||
return state.stringStartCol + 1;
|
||||
}
|
||||
if ((state.tokenize != inTag && state.tokenize != inText) ||
|
||||
context && context.noIndent)
|
||||
if (context && context.noIndent) return CodeMirror.Pass;
|
||||
if (state.tokenize != inTag && state.tokenize != inText)
|
||||
return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0;
|
||||
// Indent the starts of attribute names.
|
||||
if (state.tagName) {
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
{
|
||||
"name": "codemirror",
|
||||
"version":"3.18.0",
|
||||
"main": "lib/codemirror.js",
|
||||
"description": "In-browser code editing made bearable",
|
||||
"licenses": [{"type": "MIT",
|
||||
"url": "http://codemirror.net/LICENSE"}],
|
||||
"directories": {"lib": "./lib"},
|
||||
"scripts": {"test": "node ./test/run.js"},
|
||||
"devDependencies": {"node-static": "0.6.0"},
|
||||
"bugs": "http://github.com/marijnh/CodeMirror/issues",
|
||||
"keywords": ["JavaScript", "CodeMirror", "Editor"],
|
||||
"homepage": "http://codemirror.net",
|
||||
"maintainers":[{"name": "Marijn Haverbeke",
|
||||
"email": "marijnh@gmail.com",
|
||||
"web": "http://marijnhaverbeke.nl"}],
|
||||
"repository": {"type": "git",
|
||||
"url": "http://marijnhaverbeke.nl/git/codemirror"}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
|
||||
Name: 3024 day
|
||||
Author: Jan T. Sott (http://github.com/idleberg)
|
||||
|
||||
CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror)
|
||||
Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16)
|
||||
|
||||
*/
|
||||
|
||||
.cm-s-3024-day.CodeMirror {background: #f7f7f7; color: #3a3432;}
|
||||
.cm-s-3024-day div.CodeMirror-selected {background: #d6d5d4 !important;}
|
||||
.cm-s-3024-day .CodeMirror-gutters {background: #f7f7f7; border-right: 0px;}
|
||||
.cm-s-3024-day .CodeMirror-linenumber {color: #807d7c;}
|
||||
.cm-s-3024-day .CodeMirror-cursor {border-left: 1px solid #5c5855 !important;}
|
||||
|
||||
.cm-s-3024-day span.cm-comment {color: #cdab53;}
|
||||
.cm-s-3024-day span.cm-atom {color: #a16a94;}
|
||||
.cm-s-3024-day span.cm-number {color: #a16a94;}
|
||||
|
||||
.cm-s-3024-day span.cm-property, .cm-s-3024-day span.cm-attribute {color: #01a252;}
|
||||
.cm-s-3024-day span.cm-keyword {color: #db2d20;}
|
||||
.cm-s-3024-day span.cm-string {color: #fded02;}
|
||||
|
||||
.cm-s-3024-day span.cm-variable {color: #01a252;}
|
||||
.cm-s-3024-day span.cm-variable-2 {color: #01a0e4;}
|
||||
.cm-s-3024-day span.cm-def {color: #e8bbd0;}
|
||||
.cm-s-3024-day span.cm-bracket {color: #3a3432;}
|
||||
.cm-s-3024-day span.cm-tag {color: #db2d20;}
|
||||
.cm-s-3024-day span.cm-link {color: #a16a94;}
|
||||
.cm-s-3024-day span.cm-error {background: #db2d20; color: #5c5855;}
|
||||
|
||||
.cm-s-3024-day .CodeMirror-activeline-background {background: #e8f2ff !important;}
|
||||
.cm-s-3024-day .CodeMirror-matchingbracket { text-decoration: underline; color: white !important;}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
|
||||
Name: 3024 night
|
||||
Author: Jan T. Sott (http://github.com/idleberg)
|
||||
|
||||
CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror)
|
||||
Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16)
|
||||
|
||||
*/
|
||||
|
||||
.cm-s-3024-night.CodeMirror {background: #090300; color: #d6d5d4;}
|
||||
.cm-s-3024-night div.CodeMirror-selected {background: #3a3432 !important;}
|
||||
.cm-s-3024-night .CodeMirror-gutters {background: #090300; border-right: 0px;}
|
||||
.cm-s-3024-night .CodeMirror-linenumber {color: #5c5855;}
|
||||
.cm-s-3024-night .CodeMirror-cursor {border-left: 1px solid #807d7c !important;}
|
||||
|
||||
.cm-s-3024-night span.cm-comment {color: #cdab53;}
|
||||
.cm-s-3024-night span.cm-atom {color: #a16a94;}
|
||||
.cm-s-3024-night span.cm-number {color: #a16a94;}
|
||||
|
||||
.cm-s-3024-night span.cm-property, .cm-s-3024-night span.cm-attribute {color: #01a252;}
|
||||
.cm-s-3024-night span.cm-keyword {color: #db2d20;}
|
||||
.cm-s-3024-night span.cm-string {color: #fded02;}
|
||||
|
||||
.cm-s-3024-night span.cm-variable {color: #01a252;}
|
||||
.cm-s-3024-night span.cm-variable-2 {color: #01a0e4;}
|
||||
.cm-s-3024-night span.cm-def {color: #e8bbd0;}
|
||||
.cm-s-3024-night span.cm-bracket {color: #d6d5d4;}
|
||||
.cm-s-3024-night span.cm-tag {color: #db2d20;}
|
||||
.cm-s-3024-night span.cm-link {color: #a16a94;}
|
||||
.cm-s-3024-night span.cm-error {background: #db2d20; color: #807d7c;}
|
||||
|
||||
.cm-s-3024-night .CodeMirror-activeline-background {background: #2F2F2F !important;}
|
||||
.cm-s-3024-night .CodeMirror-matchingbracket { text-decoration: underline; color: white !important;}
|
||||
+2
-2
@@ -15,7 +15,6 @@
|
||||
.cm-s-ambiance .cm-string { color: #8f9d6a; }
|
||||
.cm-s-ambiance .cm-string-2 { color: #9d937c; }
|
||||
.cm-s-ambiance .cm-meta { color: #D2A8A1; }
|
||||
.cm-s-ambiance .cm-error { color: #AF2018; }
|
||||
.cm-s-ambiance .cm-qualifier { color: yellow; }
|
||||
.cm-s-ambiance .cm-builtin { color: #9999cc; }
|
||||
.cm-s-ambiance .cm-bracket { color: #24C2C7; }
|
||||
@@ -26,6 +25,7 @@
|
||||
.cm-s-ambiance .cm-hr { color: pink; }
|
||||
.cm-s-ambiance .cm-link { color: #F4C20B; }
|
||||
.cm-s-ambiance .cm-special { color: #FF9D00; }
|
||||
.cm-s-ambiance .cm-error { color: #AF2018; }
|
||||
|
||||
.cm-s-ambiance .CodeMirror-matchingbracket { color: #0f0; }
|
||||
.cm-s-ambiance .CodeMirror-nonmatchingbracket { color: #f22; }
|
||||
@@ -33,7 +33,7 @@
|
||||
.cm-s-ambiance .CodeMirror-selected {
|
||||
background: rgba(255, 255, 255, 0.15);
|
||||
}
|
||||
.cm-s-ambiance .CodeMirror-focused .CodeMirror-selected {
|
||||
.cm-s-ambiance.CodeMirror-focused .CodeMirror-selected {
|
||||
background: rgba(255, 255, 255, 0.10);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
|
||||
Name: Base16 Default Dark
|
||||
Author: Chris Kempson (http://chriskempson.com)
|
||||
|
||||
CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-chrome-devtools)
|
||||
Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16)
|
||||
|
||||
*/
|
||||
|
||||
.cm-s-base16-dark.CodeMirror {background: #151515; color: #e0e0e0;}
|
||||
.cm-s-base16-dark div.CodeMirror-selected {background: #202020 !important;}
|
||||
.cm-s-base16-dark .CodeMirror-gutters {background: #151515; border-right: 0px;}
|
||||
.cm-s-base16-dark .CodeMirror-linenumber {color: #505050;}
|
||||
.cm-s-base16-dark .CodeMirror-cursor {border-left: 1px solid #b0b0b0 !important;}
|
||||
|
||||
.cm-s-base16-dark span.cm-comment {color: #8f5536;}
|
||||
.cm-s-base16-dark span.cm-atom {color: #aa759f;}
|
||||
.cm-s-base16-dark span.cm-number {color: #aa759f;}
|
||||
|
||||
.cm-s-base16-dark span.cm-property, .cm-s-base16-dark span.cm-attribute {color: #90a959;}
|
||||
.cm-s-base16-dark span.cm-keyword {color: #ac4142;}
|
||||
.cm-s-base16-dark span.cm-string {color: #f4bf75;}
|
||||
|
||||
.cm-s-base16-dark span.cm-variable {color: #90a959;}
|
||||
.cm-s-base16-dark span.cm-variable-2 {color: #6a9fb5;}
|
||||
.cm-s-base16-dark span.cm-def {color: #d28445;}
|
||||
.cm-s-base16-dark span.cm-bracket {color: #e0e0e0;}
|
||||
.cm-s-base16-dark span.cm-tag {color: #ac4142;}
|
||||
.cm-s-base16-dark span.cm-link {color: #aa759f;}
|
||||
.cm-s-base16-dark span.cm-error {background: #ac4142; color: #b0b0b0;}
|
||||
|
||||
.cm-s-base16-dark .CodeMirror-activeline-background {background: #2F2F2F !important;}
|
||||
.cm-s-base16-dark .CodeMirror-matchingbracket { text-decoration: underline; color: white !important;}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
|
||||
Name: Base16 Default Light
|
||||
Author: Chris Kempson (http://chriskempson.com)
|
||||
|
||||
CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-chrome-devtools)
|
||||
Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16)
|
||||
|
||||
*/
|
||||
|
||||
.cm-s-base16-light.CodeMirror {background: #f5f5f5; color: #202020;}
|
||||
.cm-s-base16-light div.CodeMirror-selected {background: #e0e0e0 !important;}
|
||||
.cm-s-base16-light .CodeMirror-gutters {background: #f5f5f5; border-right: 0px;}
|
||||
.cm-s-base16-light .CodeMirror-linenumber {color: #b0b0b0;}
|
||||
.cm-s-base16-light .CodeMirror-cursor {border-left: 1px solid #505050 !important;}
|
||||
|
||||
.cm-s-base16-light span.cm-comment {color: #8f5536;}
|
||||
.cm-s-base16-light span.cm-atom {color: #aa759f;}
|
||||
.cm-s-base16-light span.cm-number {color: #aa759f;}
|
||||
|
||||
.cm-s-base16-light span.cm-property, .cm-s-base16-light span.cm-attribute {color: #90a959;}
|
||||
.cm-s-base16-light span.cm-keyword {color: #ac4142;}
|
||||
.cm-s-base16-light span.cm-string {color: #f4bf75;}
|
||||
|
||||
.cm-s-base16-light span.cm-variable {color: #90a959;}
|
||||
.cm-s-base16-light span.cm-variable-2 {color: #6a9fb5;}
|
||||
.cm-s-base16-light span.cm-def {color: #d28445;}
|
||||
.cm-s-base16-light span.cm-bracket {color: #202020;}
|
||||
.cm-s-base16-light span.cm-tag {color: #ac4142;}
|
||||
.cm-s-base16-light span.cm-link {color: #aa759f;}
|
||||
.cm-s-base16-light span.cm-error {background: #ac4142; color: #505050;}
|
||||
|
||||
.cm-s-base16-light .CodeMirror-activeline-background {background: #DDDCDC !important;}
|
||||
.cm-s-base16-light .CodeMirror-matchingbracket { text-decoration: underline; color: white !important;}
|
||||
@@ -16,13 +16,13 @@
|
||||
.cm-s-blackboard .cm-string { color: #61CE3C; }
|
||||
.cm-s-blackboard .cm-string-2 { color: #61CE3C; }
|
||||
.cm-s-blackboard .cm-meta { color: #D8FA3C; }
|
||||
.cm-s-blackboard .cm-error { background: #9D1E15; color: #F8F8F8; }
|
||||
.cm-s-blackboard .cm-builtin { color: #8DA6CE; }
|
||||
.cm-s-blackboard .cm-tag { color: #8DA6CE; }
|
||||
.cm-s-blackboard .cm-attribute { color: #8DA6CE; }
|
||||
.cm-s-blackboard .cm-header { color: #FF6400; }
|
||||
.cm-s-blackboard .cm-hr { color: #AEAEAE; }
|
||||
.cm-s-blackboard .cm-link { color: #8DA6CE; }
|
||||
.cm-s-blackboard .cm-error { background: #9D1E15; color: #F8F8F8; }
|
||||
|
||||
.cm-s-blackboard .CodeMirror-activeline-background {background: #3C3636 !important;}
|
||||
.cm-s-blackboard .CodeMirror-matchingbracket {outline:1px solid grey;color:white !important}
|
||||
+1
-1
@@ -12,10 +12,10 @@
|
||||
.cm-s-cobalt span.cm-meta { color: #ff9d00; }
|
||||
.cm-s-cobalt span.cm-variable-2, .cm-s-cobalt span.cm-tag { color: #9effff; }
|
||||
.cm-s-cobalt span.cm-variable-3, .cm-s-cobalt span.cm-def { color: white; }
|
||||
.cm-s-cobalt span.cm-error { color: #9d1e15; }
|
||||
.cm-s-cobalt span.cm-bracket { color: #d8d8d8; }
|
||||
.cm-s-cobalt span.cm-builtin, .cm-s-cobalt span.cm-special { color: #ff9e59; }
|
||||
.cm-s-cobalt span.cm-link { color: #845dc4; }
|
||||
.cm-s-cobalt span.cm-error { color: #9d1e15; }
|
||||
|
||||
.cm-s-cobalt .CodeMirror-activeline-background {background: #002D57 !important;}
|
||||
.cm-s-cobalt .CodeMirror-matchingbracket {outline:1px solid grey;color:white !important}
|
||||
|
||||
+1
-1
@@ -11,13 +11,13 @@
|
||||
.cm-s-eclipse span.cm-comment {color: #3F7F5F;}
|
||||
.cm-s-eclipse span.cm-string {color: #2A00FF;}
|
||||
.cm-s-eclipse span.cm-string-2 {color: #f50;}
|
||||
.cm-s-eclipse span.cm-error {color: #f00;}
|
||||
.cm-s-eclipse span.cm-qualifier {color: #555;}
|
||||
.cm-s-eclipse span.cm-builtin {color: #30a;}
|
||||
.cm-s-eclipse span.cm-bracket {color: #cc7;}
|
||||
.cm-s-eclipse span.cm-tag {color: #170;}
|
||||
.cm-s-eclipse span.cm-attribute {color: #00c;}
|
||||
.cm-s-eclipse span.cm-link {color: #219;}
|
||||
.cm-s-eclipse span.cm-error {color: #f00;}
|
||||
|
||||
.cm-s-eclipse .CodeMirror-activeline-background {background: #e8f2ff !important;}
|
||||
.cm-s-eclipse .CodeMirror-matchingbracket {outline:1px solid grey; color:black !important;}
|
||||
|
||||
+1
-1
@@ -6,8 +6,8 @@
|
||||
.cm-s-elegant span.cm-qualifier {color: #555;}
|
||||
.cm-s-elegant span.cm-keyword {color: #730;}
|
||||
.cm-s-elegant span.cm-builtin {color: #30a;}
|
||||
.cm-s-elegant span.cm-error {background-color: #fdd;}
|
||||
.cm-s-elegant span.cm-link {color: #762;}
|
||||
.cm-s-elegant span.cm-error {background-color: #fdd;}
|
||||
|
||||
.cm-s-elegant .CodeMirror-activeline-background {background: #e8f2ff !important;}
|
||||
.cm-s-elegant .CodeMirror-matchingbracket {outline:1px solid grey; color:black !important;}
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
.cm-s-erlang-dark span.cm-builtin { color: #eaa; }
|
||||
.cm-s-erlang-dark span.cm-comment { color: #77f; }
|
||||
.cm-s-erlang-dark span.cm-def { color: #e7a; }
|
||||
.cm-s-erlang-dark span.cm-error { color: #9d1e15; }
|
||||
.cm-s-erlang-dark span.cm-keyword { color: #ffee80; }
|
||||
.cm-s-erlang-dark span.cm-meta { color: #50fefe; }
|
||||
.cm-s-erlang-dark span.cm-number { color: #ffd0d0; }
|
||||
@@ -25,6 +24,7 @@
|
||||
.cm-s-erlang-dark span.cm-variable { color: #50fe50; }
|
||||
.cm-s-erlang-dark span.cm-variable-2 { color: #e0e; }
|
||||
.cm-s-erlang-dark span.cm-variable-3 { color: #ccc; }
|
||||
.cm-s-erlang-dark span.cm-error { color: #9d1e15; }
|
||||
|
||||
.cm-s-erlang-dark .CodeMirror-activeline-background {background: #013461 !important;}
|
||||
.cm-s-erlang-dark .CodeMirror-matchingbracket {outline:1px solid grey; color:white !important;}
|
||||
|
||||
@@ -32,7 +32,6 @@ Ported to CodeMirror by Peter Kroon
|
||||
.cm-s-lesser-dark span.cm-string { color: #BCD279; }
|
||||
.cm-s-lesser-dark span.cm-string-2 {color: #f50;}
|
||||
.cm-s-lesser-dark span.cm-meta { color: #738C73; }
|
||||
.cm-s-lesser-dark span.cm-error { color: #9d1e15; }
|
||||
.cm-s-lesser-dark span.cm-qualifier {color: #555;}
|
||||
.cm-s-lesser-dark span.cm-builtin { color: #ff9e59; }
|
||||
.cm-s-lesser-dark span.cm-bracket { color: #EBEFE7; }
|
||||
@@ -42,6 +41,7 @@ Ported to CodeMirror by Peter Kroon
|
||||
.cm-s-lesser-dark span.cm-quote {color: #090;}
|
||||
.cm-s-lesser-dark span.cm-hr {color: #999;}
|
||||
.cm-s-lesser-dark span.cm-link {color: #00c;}
|
||||
.cm-s-lesser-dark span.cm-error { color: #9d1e15; }
|
||||
|
||||
.cm-s-lesser-dark .CodeMirror-activeline-background {background: #3C3A3A !important;}
|
||||
.cm-s-lesser-dark .CodeMirror-matchingbracket {outline:1px solid grey; color:white !important;}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/* Based on mbonaci's Brackets mbo theme */
|
||||
|
||||
.cm-s-mbo.CodeMirror {background: #2c2c2c; color: #ffffe9;}
|
||||
.cm-s-mbo div.CodeMirror-selected {background: #716C62 !important;}
|
||||
.cm-s-mbo .CodeMirror-gutters {background: #4e4e4e; border-right: 0px;}
|
||||
.cm-s-mbo .CodeMirror-linenumber {color: #dadada;}
|
||||
.cm-s-mbo .CodeMirror-cursor {border-left: 1px solid #ffffec !important;}
|
||||
|
||||
.cm-s-mbo span.cm-comment {color: #95958a;}
|
||||
.cm-s-mbo span.cm-atom {color: #00a8c6;}
|
||||
.cm-s-mbo span.cm-number {color: #00a8c6;}
|
||||
|
||||
.cm-s-mbo span.cm-property, .cm-s-mbo span.cm-attribute {color: #9ddfe9;}
|
||||
.cm-s-mbo span.cm-keyword {color: #ffb928;}
|
||||
.cm-s-mbo span.cm-string {color: #ffcf6c;}
|
||||
|
||||
.cm-s-mbo span.cm-variable {color: #ffffec;}
|
||||
.cm-s-mbo span.cm-variable-2 {color: #00a8c6;}
|
||||
.cm-s-mbo span.cm-def {color: #ffffec;}
|
||||
.cm-s-mbo span.cm-bracket {color: #fffffc; font-weight: bold;}
|
||||
.cm-s-mbo span.cm-tag {color: #9ddfe9;}
|
||||
.cm-s-mbo span.cm-link {color: #f54b07;}
|
||||
.cm-s-mbo span.cm-error {background: #636363; color: #ffffec;}
|
||||
|
||||
.cm-s-mbo .CodeMirror-activeline-background {background: #494b41 !important;}
|
||||
.cm-s-mbo .CodeMirror-matchingbracket {
|
||||
text-decoration: underline;
|
||||
color: #f5e107 !important;
|
||||
}
|
||||
|
||||
.cm-s-mbo .CodeMirror-matchingtag {background: #4e4e4e;}
|
||||
|
||||
.cm-s-mbo span.cm-searching {
|
||||
background-color: none;
|
||||
background: none;
|
||||
box-shadow: 0 0 0 1px #ffffec;
|
||||
}
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
/* Based on the theme at http://bonsaiden.github.com/JavaScript-Garden */
|
||||
|
||||
/*<!--match-->*/
|
||||
.cm-s-midnight span.CodeMirror-matchhighlight { background: #494949 }
|
||||
.cm-s-midnight span.CodeMirror-matchhighlight { background: #494949; }
|
||||
.cm-s-midnight.CodeMirror-focused span.CodeMirror-matchhighlight { background: #314D67 !important; }
|
||||
|
||||
/*<!--activeline-->*/
|
||||
@@ -32,10 +32,10 @@
|
||||
.cm-s-midnight span.cm-variable {color: #FFAA3E;}
|
||||
.cm-s-midnight span.cm-variable-2 {color: #FFAA3E;}
|
||||
.cm-s-midnight span.cm-def {color: #4DD;}
|
||||
.cm-s-midnight span.cm-error {background: #F92672; color: #F8F8F0;}
|
||||
.cm-s-midnight span.cm-bracket {color: #D1EDFF;}
|
||||
.cm-s-midnight span.cm-tag {color: #449;}
|
||||
.cm-s-midnight span.cm-link {color: #AE81FF;}
|
||||
.cm-s-midnight span.cm-error {background: #F92672; color: #F8F8F0;}
|
||||
|
||||
.cm-s-midnight .CodeMirror-matchingbracket {
|
||||
text-decoration: underline;
|
||||
|
||||
+1
-1
@@ -17,10 +17,10 @@
|
||||
.cm-s-monokai span.cm-variable {color: #a6e22e;}
|
||||
.cm-s-monokai span.cm-variable-2 {color: #9effff;}
|
||||
.cm-s-monokai span.cm-def {color: #fd971f;}
|
||||
.cm-s-monokai span.cm-error {background: #f92672; color: #f8f8f0;}
|
||||
.cm-s-monokai span.cm-bracket {color: #f8f8f2;}
|
||||
.cm-s-monokai span.cm-tag {color: #f92672;}
|
||||
.cm-s-monokai span.cm-link {color: #ae81ff;}
|
||||
.cm-s-monokai span.cm-error {background: #f92672; color: #f8f8f0;}
|
||||
|
||||
.cm-s-monokai .CodeMirror-activeline-background {background: #373831 !important;}
|
||||
.cm-s-monokai .CodeMirror-matchingbracket {
|
||||
|
||||
+1
-1
@@ -14,11 +14,11 @@
|
||||
.cm-s-night span.cm-meta { color: #7678e2; }
|
||||
.cm-s-night span.cm-variable-2, .cm-s-night span.cm-tag { color: #99b2ff; }
|
||||
.cm-s-night span.cm-variable-3, .cm-s-night span.cm-def { color: white; }
|
||||
.cm-s-night span.cm-error { color: #9d1e15; }
|
||||
.cm-s-night span.cm-bracket { color: #8da6ce; }
|
||||
.cm-s-night span.cm-comment { color: #6900a1; }
|
||||
.cm-s-night span.cm-builtin, .cm-s-night span.cm-special { color: #ff9e59; }
|
||||
.cm-s-night span.cm-link { color: #845dc4; }
|
||||
.cm-s-night span.cm-error { color: #9d1e15; }
|
||||
|
||||
.cm-s-night .CodeMirror-activeline-background {background: #1C005A !important;}
|
||||
.cm-s-night .CodeMirror-matchingbracket {outline:1px solid grey; color:white !important;}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
|
||||
Name: Paraíso (Dark)
|
||||
Author: Jan T. Sott
|
||||
|
||||
Color scheme by Jan T. Sott (https://github.com/idleberg/Paraiso-CodeMirror)
|
||||
Inspired by the art of Rubens LP (http://www.rubenslp.com.br)
|
||||
|
||||
*/
|
||||
|
||||
.cm-s-paraiso-dark.CodeMirror {background: #2f1e2e; color: #b9b6b0;}
|
||||
.cm-s-paraiso-dark div.CodeMirror-selected {background: #41323f !important;}
|
||||
.cm-s-paraiso-dark .CodeMirror-gutters {background: #2f1e2e; border-right: 0px;}
|
||||
.cm-s-paraiso-dark .CodeMirror-linenumber {color: #776e71;}
|
||||
.cm-s-paraiso-dark .CodeMirror-cursor {border-left: 1px solid #8d8687 !important;}
|
||||
|
||||
.cm-s-paraiso-dark span.cm-comment {color: #e96ba8;}
|
||||
.cm-s-paraiso-dark span.cm-atom {color: #815ba4;}
|
||||
.cm-s-paraiso-dark span.cm-number {color: #815ba4;}
|
||||
|
||||
.cm-s-paraiso-dark span.cm-property, .cm-s-paraiso-dark span.cm-attribute {color: #48b685;}
|
||||
.cm-s-paraiso-dark span.cm-keyword {color: #ef6155;}
|
||||
.cm-s-paraiso-dark span.cm-string {color: #fec418;}
|
||||
|
||||
.cm-s-paraiso-dark span.cm-variable {color: #48b685;}
|
||||
.cm-s-paraiso-dark span.cm-variable-2 {color: #06b6ef;}
|
||||
.cm-s-paraiso-dark span.cm-def {color: #f99b15;}
|
||||
.cm-s-paraiso-dark span.cm-bracket {color: #b9b6b0;}
|
||||
.cm-s-paraiso-dark span.cm-tag {color: #ef6155;}
|
||||
.cm-s-paraiso-dark span.cm-link {color: #815ba4;}
|
||||
.cm-s-paraiso-dark span.cm-error {background: #ef6155; color: #8d8687;}
|
||||
|
||||
.cm-s-paraiso-dark .CodeMirror-activeline-background {background: #4D344A !important;}
|
||||
.cm-s-paraiso-dark .CodeMirror-matchingbracket { text-decoration: underline; color: white !important;}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
|
||||
Name: Paraíso (Light)
|
||||
Author: Jan T. Sott
|
||||
|
||||
Color scheme by Jan T. Sott (https://github.com/idleberg/Paraiso-CodeMirror)
|
||||
Inspired by the art of Rubens LP (http://www.rubenslp.com.br)
|
||||
|
||||
*/
|
||||
|
||||
.cm-s-paraiso-light.CodeMirror {background: #e7e9db; color: #41323f;}
|
||||
.cm-s-paraiso-light div.CodeMirror-selected {background: #b9b6b0 !important;}
|
||||
.cm-s-paraiso-light .CodeMirror-gutters {background: #e7e9db; border-right: 0px;}
|
||||
.cm-s-paraiso-light .CodeMirror-linenumber {color: #8d8687;}
|
||||
.cm-s-paraiso-light .CodeMirror-cursor {border-left: 1px solid #776e71 !important;}
|
||||
|
||||
.cm-s-paraiso-light span.cm-comment {color: #e96ba8;}
|
||||
.cm-s-paraiso-light span.cm-atom {color: #815ba4;}
|
||||
.cm-s-paraiso-light span.cm-number {color: #815ba4;}
|
||||
|
||||
.cm-s-paraiso-light span.cm-property, .cm-s-paraiso-light span.cm-attribute {color: #48b685;}
|
||||
.cm-s-paraiso-light span.cm-keyword {color: #ef6155;}
|
||||
.cm-s-paraiso-light span.cm-string {color: #fec418;}
|
||||
|
||||
.cm-s-paraiso-light span.cm-variable {color: #48b685;}
|
||||
.cm-s-paraiso-light span.cm-variable-2 {color: #06b6ef;}
|
||||
.cm-s-paraiso-light span.cm-def {color: #f99b15;}
|
||||
.cm-s-paraiso-light span.cm-bracket {color: #41323f;}
|
||||
.cm-s-paraiso-light span.cm-tag {color: #ef6155;}
|
||||
.cm-s-paraiso-light span.cm-link {color: #815ba4;}
|
||||
.cm-s-paraiso-light span.cm-error {background: #ef6155; color: #776e71;}
|
||||
|
||||
.cm-s-paraiso-light .CodeMirror-activeline-background {background: #CFD1C4 !important;}
|
||||
.cm-s-paraiso-light .CodeMirror-matchingbracket { text-decoration: underline; color: white !important;}
|
||||
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* Pastel On Dark theme ported from ACE editor
|
||||
* @license MIT
|
||||
* @copyright AtomicPages LLC 2014
|
||||
* @author Dennis Thompson, AtomicPages LLC
|
||||
* @version 1.1
|
||||
* @source https://github.com/atomicpages/codemirror-pastel-on-dark-theme
|
||||
*/
|
||||
|
||||
.cm-s-pastel-on-dark.CodeMirror {
|
||||
background: #2c2827;
|
||||
color: #8F938F;
|
||||
line-height: 1.5;
|
||||
font-family: consolas, Courier, monospace;
|
||||
font-size: 14px;
|
||||
}
|
||||
.cm-s-pastel-on-dark div.CodeMirror-selected { background: rgba(221,240,255,0.2) !important; }
|
||||
.cm-s-pastel-on-dark .CodeMirror-gutters {
|
||||
background: #34302f;
|
||||
border-right: 0px;
|
||||
padding: 0 3px;
|
||||
}
|
||||
.cm-s-pastel-on-dark .CodeMirror-linenumber { color: #8F938F; }
|
||||
.cm-s-pastel-on-dark .CodeMirror-cursor { border-left: 1px solid #A7A7A7 !important; }
|
||||
.cm-s-pastel-on-dark span.cm-comment { color: #A6C6FF; }
|
||||
.cm-s-pastel-on-dark span.cm-atom { color: #DE8E30; }
|
||||
.cm-s-pastel-on-dark span.cm-number { color: #CCCCCC; }
|
||||
.cm-s-pastel-on-dark span.cm-property { color: #8F938F; }
|
||||
.cm-s-pastel-on-dark span.cm-attribute { color: #a6e22e; }
|
||||
.cm-s-pastel-on-dark span.cm-keyword { color: #AEB2F8; }
|
||||
.cm-s-pastel-on-dark span.cm-string { color: #66A968; }
|
||||
.cm-s-pastel-on-dark span.cm-variable { color: #AEB2F8; }
|
||||
.cm-s-pastel-on-dark span.cm-variable-2 { color: #BEBF55; }
|
||||
.cm-s-pastel-on-dark span.cm-variable-3 { color: #DE8E30; }
|
||||
.cm-s-pastel-on-dark span.cm-def { color: #757aD8; }
|
||||
.cm-s-pastel-on-dark span.cm-bracket { color: #f8f8f2; }
|
||||
.cm-s-pastel-on-dark span.cm-tag { color: #C1C144; }
|
||||
.cm-s-pastel-on-dark span.cm-link { color: #ae81ff; }
|
||||
.cm-s-pastel-on-dark span.cm-qualifier,.cm-s-pastel-on-dark span.cm-builtin { color: #C1C144; }
|
||||
.cm-s-pastel-on-dark span.cm-error {
|
||||
background: #757aD8;
|
||||
color: #f8f8f0;
|
||||
}
|
||||
.cm-s-pastel-on-dark .CodeMirror-activeline-background { background: rgba(255, 255, 255, 0.031) !important; }
|
||||
.cm-s-pastel-on-dark .CodeMirror-matchingbracket {
|
||||
border: 1px solid rgba(255,255,255,0.25);
|
||||
color: #8F938F !important;
|
||||
margin: -1px -1px 0 -1px;
|
||||
}
|
||||
+1
-1
@@ -14,10 +14,10 @@
|
||||
.cm-s-rubyblue span.cm-meta { color: #F0F; }
|
||||
.cm-s-rubyblue span.cm-variable-2, .cm-s-rubyblue span.cm-tag { color: #7BD827; }
|
||||
.cm-s-rubyblue span.cm-variable-3, .cm-s-rubyblue span.cm-def { color: white; }
|
||||
.cm-s-rubyblue span.cm-error { color: #AF2018; }
|
||||
.cm-s-rubyblue span.cm-bracket { color: #F0F; }
|
||||
.cm-s-rubyblue span.cm-link { color: #F4C20B; }
|
||||
.cm-s-rubyblue span.CodeMirror-matchingbracket { color:#F0F !important; }
|
||||
.cm-s-rubyblue span.cm-builtin, .cm-s-rubyblue span.cm-special { color: #FF9D00; }
|
||||
.cm-s-rubyblue span.cm-error { color: #AF2018; }
|
||||
|
||||
.cm-s-rubyblue .CodeMirror-activeline-background {background: #173047 !important;}
|
||||
|
||||
@@ -67,11 +67,6 @@ http://ethanschoonover.com/solarized/img/solarized-palette.png
|
||||
.cm-s-solarized .cm-string-2 { color: #b58900; }
|
||||
|
||||
.cm-s-solarized .cm-meta { color: #859900; }
|
||||
.cm-s-solarized .cm-error,
|
||||
.cm-s-solarized .cm-invalidchar {
|
||||
color: #586e75;
|
||||
border-bottom: 1px dotted #dc322f;
|
||||
}
|
||||
.cm-s-solarized .cm-qualifier { color: #b58900; }
|
||||
.cm-s-solarized .cm-builtin { color: #d33682; }
|
||||
.cm-s-solarized .cm-bracket { color: #cb4b16; }
|
||||
@@ -98,6 +93,11 @@ http://ethanschoonover.com/solarized/img/solarized-palette.png
|
||||
content: "➤"; /*visualize tab character*/
|
||||
color: #586e75;
|
||||
}
|
||||
.cm-s-solarized .cm-error,
|
||||
.cm-s-solarized .cm-invalidchar {
|
||||
color: #586e75;
|
||||
border-bottom: 1px dotted #dc322f;
|
||||
}
|
||||
|
||||
.cm-s-solarized.cm-s-dark .CodeMirror-selected {
|
||||
background: #073642;
|
||||
@@ -165,10 +165,10 @@ Active line. Negative margin compensates left padding of the text in the
|
||||
view-port
|
||||
*/
|
||||
.cm-s-solarized.cm-s-dark .CodeMirror-activeline-background {
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
background: rgba(255, 255, 255, 0.10);
|
||||
}
|
||||
.cm-s-solarized.cm-s-light .CodeMirror-activeline-background {
|
||||
background: rgba(0, 0, 0, 0.05);
|
||||
background: rgba(0, 0, 0, 0.10);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
.cm-s-the-matrix.CodeMirror { background: #000000; color: #00FF00; }
|
||||
.cm-s-the-matrix div.CodeMirror-selected { background: #2D2D2D !important; }
|
||||
.cm-s-the-matrix .CodeMirror-gutters { background: #060; border-right: 2px solid #00FF00; }
|
||||
.cm-s-the-matrix .CodeMirror-linenumber { color: #FFFFFF; }
|
||||
.cm-s-the-matrix .CodeMirror-cursor { border-left: 1px solid #00FF00 !important; }
|
||||
|
||||
.cm-s-the-matrix span.cm-keyword {color: #008803; font-weight: bold;}
|
||||
.cm-s-the-matrix span.cm-atom {color: #3FF;}
|
||||
.cm-s-the-matrix span.cm-number {color: #FFB94F;}
|
||||
.cm-s-the-matrix span.cm-def {color: #99C;}
|
||||
.cm-s-the-matrix span.cm-variable {color: #F6C;}
|
||||
.cm-s-the-matrix span.cm-variable-2 {color: #C6F;}
|
||||
.cm-s-the-matrix span.cm-variable-3 {color: #96F;}
|
||||
.cm-s-the-matrix span.cm-property {color: #62FFA0;}
|
||||
.cm-s-the-matrix span.cm-operator {color: #999}
|
||||
.cm-s-the-matrix span.cm-comment {color: #CCCCCC;}
|
||||
.cm-s-the-matrix span.cm-string {color: #39C;}
|
||||
.cm-s-the-matrix span.cm-meta {color: #C9F;}
|
||||
.cm-s-the-matrix span.cm-qualifier {color: #FFF700;}
|
||||
.cm-s-the-matrix span.cm-builtin {color: #30a;}
|
||||
.cm-s-the-matrix span.cm-bracket {color: #cc7;}
|
||||
.cm-s-the-matrix span.cm-tag {color: #FFBD40;}
|
||||
.cm-s-the-matrix span.cm-attribute {color: #FFF700;}
|
||||
.cm-s-the-matrix span.cm-error {color: #FF0000;}
|
||||
|
||||
.cm-s-the-matrix .CodeMirror-activeline-background {background: #040;}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
|
||||
Name: Tomorrow Night - Eighties
|
||||
Author: Chris Kempson
|
||||
|
||||
CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror)
|
||||
Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16)
|
||||
|
||||
*/
|
||||
|
||||
.cm-s-tomorrow-night-eighties.CodeMirror {background: #000000; color: #CCCCCC;}
|
||||
.cm-s-tomorrow-night-eighties div.CodeMirror-selected {background: #2D2D2D !important;}
|
||||
.cm-s-tomorrow-night-eighties .CodeMirror-gutters {background: #000000; border-right: 0px;}
|
||||
.cm-s-tomorrow-night-eighties .CodeMirror-linenumber {color: #515151;}
|
||||
.cm-s-tomorrow-night-eighties .CodeMirror-cursor {border-left: 1px solid #6A6A6A !important;}
|
||||
|
||||
.cm-s-tomorrow-night-eighties span.cm-comment {color: #d27b53;}
|
||||
.cm-s-tomorrow-night-eighties span.cm-atom {color: #a16a94;}
|
||||
.cm-s-tomorrow-night-eighties span.cm-number {color: #a16a94;}
|
||||
|
||||
.cm-s-tomorrow-night-eighties span.cm-property, .cm-s-tomorrow-night-eighties span.cm-attribute {color: #99cc99;}
|
||||
.cm-s-tomorrow-night-eighties span.cm-keyword {color: #f2777a;}
|
||||
.cm-s-tomorrow-night-eighties span.cm-string {color: #ffcc66;}
|
||||
|
||||
.cm-s-tomorrow-night-eighties span.cm-variable {color: #99cc99;}
|
||||
.cm-s-tomorrow-night-eighties span.cm-variable-2 {color: #6699cc;}
|
||||
.cm-s-tomorrow-night-eighties span.cm-def {color: #f99157;}
|
||||
.cm-s-tomorrow-night-eighties span.cm-bracket {color: #CCCCCC;}
|
||||
.cm-s-tomorrow-night-eighties span.cm-tag {color: #f2777a;}
|
||||
.cm-s-tomorrow-night-eighties span.cm-link {color: #a16a94;}
|
||||
.cm-s-tomorrow-night-eighties span.cm-error {background: #f2777a; color: #6A6A6A;}
|
||||
|
||||
.cm-s-tomorrow-night-eighties .CodeMirror-activeline-background {background: #343600 !important;}
|
||||
.cm-s-tomorrow-night-eighties .CodeMirror-matchingbracket { text-decoration: underline; color: white !important;}
|
||||
+1
-1
@@ -16,13 +16,13 @@
|
||||
.cm-s-twilight .cm-string { color:#8f9d6a; font-style:italic; } /**/
|
||||
.cm-s-twilight .cm-string-2 { color:#bd6b18 } /*?*/
|
||||
.cm-s-twilight .cm-meta { background-color:#141414; color:#f7f7f7; } /*?*/
|
||||
.cm-s-twilight .cm-error { border-bottom: 1px solid red; }
|
||||
.cm-s-twilight .cm-builtin { color: #cda869; } /*?*/
|
||||
.cm-s-twilight .cm-tag { color: #997643; } /**/
|
||||
.cm-s-twilight .cm-attribute { color: #d6bb6d; } /*?*/
|
||||
.cm-s-twilight .cm-header { color: #FF6400; }
|
||||
.cm-s-twilight .cm-hr { color: #AEAEAE; }
|
||||
.cm-s-twilight .cm-link { color:#ad9361; font-style:italic; text-decoration:none; } /**/
|
||||
.cm-s-twilight .cm-error { border-bottom: 1px solid red; }
|
||||
|
||||
.cm-s-twilight .CodeMirror-activeline-background {background: #27282E !important;}
|
||||
.cm-s-twilight .CodeMirror-matchingbracket {outline:1px solid grey; color:white !important;}
|
||||
|
||||
@@ -18,13 +18,13 @@
|
||||
.cm-s-vibrant-ink .cm-string { color: #A5C25C }
|
||||
.cm-s-vibrant-ink .cm-string-2 { color: red }
|
||||
.cm-s-vibrant-ink .cm-meta { color: #D8FA3C; }
|
||||
.cm-s-vibrant-ink .cm-error { border-bottom: 1px solid red; }
|
||||
.cm-s-vibrant-ink .cm-builtin { color: #8DA6CE; }
|
||||
.cm-s-vibrant-ink .cm-tag { color: #8DA6CE; }
|
||||
.cm-s-vibrant-ink .cm-attribute { color: #8DA6CE; }
|
||||
.cm-s-vibrant-ink .cm-header { color: #FF6400; }
|
||||
.cm-s-vibrant-ink .cm-hr { color: #AEAEAE; }
|
||||
.cm-s-vibrant-ink .cm-link { color: blue; }
|
||||
.cm-s-vibrant-ink .cm-error { border-bottom: 1px solid red; }
|
||||
|
||||
.cm-s-vibrant-ink .CodeMirror-activeline-background {background: #27282E !important;}
|
||||
.cm-s-vibrant-ink .CodeMirror-matchingbracket {outline:1px solid grey; color:white !important;}
|
||||
|
||||
+1
-1
@@ -38,12 +38,12 @@ THE SOFTWARE.
|
||||
.cm-s-xq-dark span.cm-comment {color: gray;}
|
||||
.cm-s-xq-dark span.cm-string {color: #9FEE00;}
|
||||
.cm-s-xq-dark span.cm-meta {color: yellow;}
|
||||
.cm-s-xq-dark span.cm-error {color: #f00;}
|
||||
.cm-s-xq-dark span.cm-qualifier {color: #FFF700;}
|
||||
.cm-s-xq-dark span.cm-builtin {color: #30a;}
|
||||
.cm-s-xq-dark span.cm-bracket {color: #cc7;}
|
||||
.cm-s-xq-dark span.cm-tag {color: #FFBD40;}
|
||||
.cm-s-xq-dark span.cm-attribute {color: #FFF700;}
|
||||
.cm-s-xq-dark span.cm-error {color: #f00;}
|
||||
|
||||
.cm-s-xq-dark .CodeMirror-activeline-background {background: #27282E !important;}
|
||||
.cm-s-xq-dark .CodeMirror-matchingbracket {outline:1px solid grey; color:white !important;}
|
||||
+1
-1
@@ -32,12 +32,12 @@ THE SOFTWARE.
|
||||
.cm-s-xq-light span.cm-comment {color: #0080FF; font-style: italic;}
|
||||
.cm-s-xq-light span.cm-string {color: red;}
|
||||
.cm-s-xq-light span.cm-meta {color: yellow;}
|
||||
.cm-s-xq-light span.cm-error {color: #f00;}
|
||||
.cm-s-xq-light span.cm-qualifier {color: grey}
|
||||
.cm-s-xq-light span.cm-builtin {color: #7EA656;}
|
||||
.cm-s-xq-light span.cm-bracket {color: #cc7;}
|
||||
.cm-s-xq-light span.cm-tag {color: #3F7F7F;}
|
||||
.cm-s-xq-light span.cm-attribute {color: #7F007F;}
|
||||
.cm-s-xq-light span.cm-error {color: #f00;}
|
||||
|
||||
.cm-s-xq-light .CodeMirror-activeline-background {background: #e8f2ff !important;}
|
||||
.cm-s-xq-light .CodeMirror-matchingbracket {outline:1px solid grey;color:black !important;background:yellow;}
|
||||
File diff suppressed because one or more lines are too long
+4
-4
File diff suppressed because one or more lines are too long
@@ -1,7 +1,13 @@
|
||||
/* TODO rename this file as web2py-editor.css */
|
||||
/* Fullscreen */
|
||||
.CodeMirror-fullscreen {
|
||||
z-index: 1030;
|
||||
}
|
||||
.CodeMirror {
|
||||
border-top: 1px solid #ddd;
|
||||
/*border-left: 1px solid #ddd;*/
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
|
||||
/* BREAKPOINTS */
|
||||
|
||||
@@ -16,3 +22,45 @@
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
|
||||
/* Close button on tab*/
|
||||
.nav-tabs li a > .close {
|
||||
font-size: 18px;
|
||||
padding-left: 5px;
|
||||
float: right;
|
||||
margin-right: -10px;
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
.nav-tabs>li>a {
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
word-wrap: normal;
|
||||
-o-text-overflow: ellipsis;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
/*.nav-tabs>li {
|
||||
min-width: 100px;
|
||||
}*/
|
||||
|
||||
#windows_divs > div {
|
||||
position: fixed;
|
||||
height: 30%;
|
||||
left: 0;
|
||||
background: white;
|
||||
right: 0;
|
||||
bottom: 41px;
|
||||
z-index: 1030;
|
||||
overflow: inherit;
|
||||
border-top: 1px solid #ddd;
|
||||
}
|
||||
|
||||
#editor_main {
|
||||
margin-top:40px;
|
||||
margin-bottom:40px;
|
||||
}
|
||||
|
||||
#editform {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
var template_js = '<p class="repo-name">{{{a_tag}}}</p><small>{{address}}</small>';
|
||||
|
||||
function prepareDataForSave(name, data) {
|
||||
var obj = new Object();
|
||||
obj.Name = name;
|
||||
@@ -22,8 +24,8 @@ function prepareMultiPartPOST(data) {
|
||||
}
|
||||
|
||||
function on_error() {
|
||||
jQuery("input[name='saved_on']").attr('style', 'background-color:red');
|
||||
jQuery("input[name='saved_on']").val('communication error');
|
||||
$("input[name='saved_on']").attr('style', 'background-color:red');
|
||||
$("input[name='saved_on']").val('communication error');
|
||||
}
|
||||
|
||||
function doHighlight(highlight) {
|
||||
@@ -36,24 +38,24 @@ function doHighlight(highlight) {
|
||||
|
||||
|
||||
function doClickSave() {
|
||||
var currentTabID = '#' + jQuery('#edit_placeholder div.tab-pane.active').attr('id');
|
||||
var editor = jQuery(currentTabID + ' textarea').data('editor');
|
||||
var currentTabID = '#' + $('#edit_placeholder div.tab-pane.active').attr('id');
|
||||
var editor = $(currentTabID + ' textarea').data('editor');
|
||||
var data = editor.getValue();
|
||||
var dataForPost = prepareMultiPartPOST(new Array(
|
||||
prepareDataForSave('data', data),
|
||||
prepareDataForSave('file_hash',
|
||||
jQuery(currentTabID + " input[name='file_hash']").val()),
|
||||
$(currentTabID + " input[name='file_hash']").val()),
|
||||
prepareDataForSave('saved_on',
|
||||
jQuery(currentTabID + " input[name='saved_on']").val()),
|
||||
$(currentTabID + " input[name='saved_on']").val()),
|
||||
prepareDataForSave('saved_on',
|
||||
jQuery(currentTabID + " input[name='saved_on']").val()),
|
||||
$(currentTabID + " input[name='saved_on']").val()),
|
||||
prepareDataForSave('from_ajax', 'true')));
|
||||
// console.info(area.textarea.value);
|
||||
jQuery(currentTabID + " input[name='saved_on']").attr('style',
|
||||
$(currentTabID + " input[name='saved_on']").attr('style',
|
||||
'background-color:yellow');
|
||||
jQuery(currentTabID + " input[name='saved_on']").val('saving now...')
|
||||
currentUrl = jQuery(currentTabID + ' form').attr('action');
|
||||
jQuery.ajax({
|
||||
$(currentTabID + " input[name='saved_on']").val('saving now...')
|
||||
currentUrl = $(currentTabID + ' form').attr('action');
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
contentType: 'multipart/form-data;boundary="' + dataForPost[1] + '"',
|
||||
url: currentUrl,
|
||||
@@ -67,38 +69,38 @@ function doClickSave() {
|
||||
'doClickSave');
|
||||
},
|
||||
success: function (json, text, xhr) {
|
||||
jQuery(editor).data('saved', true); // Set as saved
|
||||
$(editor).data('saved', true); // Set as saved
|
||||
editor.on("change", store_changes_function); // Re-enable change watcher
|
||||
// reenable disabled submit button
|
||||
var t = jQuery("input[name='save']");
|
||||
var t = $("input[name='save']");
|
||||
t.attr('class', '');
|
||||
t.attr('disabled', '');
|
||||
var flash = xhr.getResponseHeader('web2py-component-flash');
|
||||
if(flash) {
|
||||
jQuery('.flash').html(decodeURIComponent(flash))
|
||||
$('.flash').html(decodeURIComponent(flash))
|
||||
.append('<a href="#" class="close">×</a>')
|
||||
.slideDown();
|
||||
} else jQuery('.flash').hide();
|
||||
} else $('.flash').hide();
|
||||
try {
|
||||
if(json.error) {
|
||||
window.location.href = json.redirect;
|
||||
} else {
|
||||
// console.info( json.file_hash );
|
||||
jQuery(currentTabID + " input[name='file_hash']").val(json.file_hash);
|
||||
jQuery(currentTabID + " input[name='saved_on']").val(json.saved_on);
|
||||
$(currentTabID + " input[name='file_hash']").val(json.file_hash);
|
||||
$(currentTabID + " input[name='saved_on']").val(json.saved_on);
|
||||
if(json.highlight) {
|
||||
doHighlight(json.highlight);
|
||||
} else {
|
||||
jQuery(currentTabID + " input[name='saved_on']").attr('style', 'background-color:#99FF99');
|
||||
//jQuery(".flash").delay(1000).fadeOut('slow');
|
||||
$(currentTabID + " input[name='saved_on']").attr('style', 'background-color:#99FF99');
|
||||
//$(".flash").delay(1000).fadeOut('slow');
|
||||
}
|
||||
// console.info(jQuery("input[name='file_hash']").val());
|
||||
// console.info($("input[name='file_hash']").val());
|
||||
var output = '<b>exposes:</b> ';
|
||||
for(var i in json.functions) {
|
||||
output += ' <a target="_blank" href="/' + json.application + '/' + json.controller + '/' + json.functions[i] + '">' + json.functions[i] + '</a>,';
|
||||
}
|
||||
if(output != '<b>exposes:</b> ') {
|
||||
jQuery(currentTabID + " .exposed").html(output.substring(0, output.length - 1));
|
||||
$(currentTabID + " .exposed").html(output.substring(0, output.length - 1));
|
||||
}
|
||||
}
|
||||
} catch(e) {
|
||||
@@ -113,8 +115,8 @@ function doClickSave() {
|
||||
}
|
||||
|
||||
function getActiveEditor() {
|
||||
var currentTabID = '#' + jQuery('#edit_placeholder div.tab-pane.active').attr('id');
|
||||
var editor = jQuery(currentTabID + ' textarea').data('editor');
|
||||
var currentTabID = '#' + $('#edit_placeholder div.tab-pane.active').attr('id');
|
||||
var editor = $(currentTabID + ' textarea').data('editor');
|
||||
return editor;
|
||||
}
|
||||
|
||||
@@ -139,7 +141,7 @@ function doToggleBreakpoint(filename, url, sel) {
|
||||
prepareDataForSave('sel_start', sel["start"]),
|
||||
prepareDataForSave('sel_end', sel["end"]),
|
||||
prepareDataForSave('data', sel['data'])));
|
||||
jQuery.ajax({
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
contentType: 'multipart/form-data;boundary="' + dataForPost[1] + '"',
|
||||
url: url,
|
||||
@@ -156,10 +158,10 @@ function doToggleBreakpoint(filename, url, sel) {
|
||||
// show flash message (if any)
|
||||
var flash = xhr.getResponseHeader('web2py-component-flash');
|
||||
if(flash) {
|
||||
jQuery('.flash').html(decodeURIComponent(flash))
|
||||
$('.flash').html(decodeURIComponent(flash))
|
||||
.append('<a href="#" class="close">×</a>')
|
||||
.slideDown();
|
||||
} else jQuery('.flash').hide();
|
||||
} else $('.flash').hide();
|
||||
try {
|
||||
if(json.error) {
|
||||
window.location.href = json.redirect;
|
||||
@@ -189,7 +191,7 @@ function doListBreakpoints(filename, url, editor) {
|
||||
var dataForPost = prepareMultiPartPOST(new Array(
|
||||
prepareDataForSave('filename', filename)
|
||||
));
|
||||
jQuery.ajax({
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
contentType: 'multipart/form-data;boundary="' + dataForPost[1] + '"',
|
||||
url: url,
|
||||
@@ -235,7 +237,7 @@ function makeMarker() {
|
||||
|
||||
|
||||
function keepalive(url) {
|
||||
jQuery.ajax({
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
url: url,
|
||||
timeout: 1000,
|
||||
@@ -246,8 +248,8 @@ function keepalive(url) {
|
||||
});
|
||||
}
|
||||
|
||||
function load_file(url) {
|
||||
jQuery.ajax({
|
||||
function load_file(url, lineno) {
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
contentType: 'application/json',
|
||||
cache: false,
|
||||
@@ -256,18 +258,18 @@ function load_file(url) {
|
||||
timeout: 1000,
|
||||
success: function (json) {
|
||||
if(typeof (json['plain_html']) !== undefined) {
|
||||
if(jQuery('#' + json['id']).length === 0 || json['force'] === true) {
|
||||
if($('#' + json['id']).length === 0 || json['force'] === true) {
|
||||
// Create a tab and put the code in it
|
||||
var tab_header = '<li><a href="#' + json['id'] + '" data-toggle="tab">' + json['filename'] + '<button type="button" class="close">×</button></a></li>';
|
||||
var tab_header = '<li><a title="'+ json['filename'] +'" data-path="' + json['filename'] + '" href="#' + json['id'] + '" data-toggle="tab"><button type="button" class="close">×</button>' + json['realfilename'] + '</a></li>';
|
||||
var tab_body = '<div id="' + json['id'] + '" class="tab-pane fade in " >' + json['plain_html'] + '</div>';
|
||||
if(json['force'] === false) {
|
||||
jQuery('#filesTab').append(jQuery(tab_header));
|
||||
jQuery('#myTabContent').append(jQuery(tab_body));
|
||||
$('#myTabContent').append($(tab_body)); // First load the body
|
||||
$('#filesTab').append($(tab_header)); // Then load the header which trigger the shown event
|
||||
} else {
|
||||
jQuery('#' + json['id']).html(jQuery(tab_body));
|
||||
$('#' + json['id']).html($(tab_body));
|
||||
}
|
||||
}
|
||||
jQuery("a[href='#" + json['id'] + "']").click();
|
||||
$("a[href='#" + json['id'] + "']").trigger('click', lineno);
|
||||
}
|
||||
},
|
||||
error: function (x) {
|
||||
@@ -279,11 +281,11 @@ function load_file(url) {
|
||||
function set_font(editor, incr) {
|
||||
var fontSize = '';
|
||||
if(incr !== 0) {
|
||||
fontSize = parseInt(jQuery(editor.getWrapperElement()).css('font-size'));
|
||||
fontSize = parseInt($(editor.getWrapperElement()).css('font-size'));
|
||||
fontSize = fontSize + incr + "px";
|
||||
}
|
||||
jQuery(editor.getWrapperElement()).css('font-size', fontSize);
|
||||
$(editor.getWrapperElement()).css('font-size', fontSize);
|
||||
editor.refresh();
|
||||
}
|
||||
|
||||
var template_js = '<p class="repo-name">{{{a_tag}}}</p><small>{{address}}</small>';
|
||||
|
||||
|
||||
+2
-2
File diff suppressed because one or more lines are too long
@@ -167,10 +167,12 @@
|
||||
else t.fadeOut();
|
||||
});
|
||||
doc.on('keyup', 'input.integer', function () {
|
||||
this.value = this.value.reverse().replace(/[^0-9\-]|\-(?=.)/g, '').reverse();
|
||||
var nvalue = this.value.reverse().replace(/[^0-9\-]|\-(?=.)/g, '').reverse();
|
||||
if(this.value!=nvalue) this.value = nvalue;
|
||||
});
|
||||
doc.on('keyup', 'input.double, input.decimal', function () {
|
||||
this.value = this.value.reverse().replace(/[^0-9\-\.,]|[\-](?=.)|[\.,](?=[0-9]*[\.,])/g, '').reverse();
|
||||
var nvalue = this.value.reverse().replace(/[^0-9\-\.,]|[\-](?=.)|[\.,](?=[0-9]*[\.,])/g, '').reverse();
|
||||
if(this.value!=nvalue) this.value = nvalue;
|
||||
});
|
||||
var confirm_message = (typeof w2p_ajax_confirm_message != 'undefined') ? w2p_ajax_confirm_message : "Are you sure you want to delete this object?";
|
||||
doc.on('click', "input[type='checkbox'].delete", function () {
|
||||
@@ -248,22 +250,33 @@
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
trap_form: function (action, target) {
|
||||
/* traps any LOADed form */
|
||||
$('#' + target + ' form').each(function (i) {
|
||||
var form = $(this);
|
||||
form.attr('data-w2p_target', target);
|
||||
if(!form.hasClass('no_trap')) {
|
||||
/* should be there by default */
|
||||
form.submit(function (e) {
|
||||
web2py.disableElement(form.find(web2py.formInputClickSelector));
|
||||
web2py.hide_flash();
|
||||
web2py.ajax_page('post', action, form.serialize(), target, form);
|
||||
e.preventDefault();
|
||||
});
|
||||
if (form.hasClass('no_trap')) {
|
||||
return;
|
||||
}
|
||||
|
||||
form.attr('data-w2p_target', target);
|
||||
var url = form.attr('action');
|
||||
|
||||
if ((url === "") || (url === "#")) {
|
||||
/* form has no action. Use component url. */
|
||||
url = action;
|
||||
}
|
||||
|
||||
form.submit(function (e) {
|
||||
web2py.disableElement(form.find(web2py.formInputClickSelector));
|
||||
web2py.hide_flash();
|
||||
web2py.ajax_page('post', url, form.serialize(), target, form);
|
||||
e.preventDefault();
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
ajax_page: function (method, action, data, target, element) {
|
||||
/* element is a new parameter, but should be put be put in front */
|
||||
if(element == undefined) element = $(document);
|
||||
@@ -295,7 +308,7 @@
|
||||
},
|
||||
'complete': function (xhr, status) {
|
||||
web2py.fire(element, 'ajax:complete', [xhr, status], target);
|
||||
web2py.updatePage(xhr, target); /* Parse and load the html received */
|
||||
web2py.updatePage(xhr, target); /* Parse and load the html received */
|
||||
web2py.trap_form(action, target);
|
||||
web2py.ajax_init('#' + target);
|
||||
web2py.after_ajax(xhr);
|
||||
@@ -445,8 +458,8 @@
|
||||
} else return false; /* not supported */
|
||||
},
|
||||
/* new from here */
|
||||
/* Form input elements bound by jquery-uj */
|
||||
formInputClickSelector: 'input[type=submit], input[type=image], button[type=submit], button:not([type])',
|
||||
/* Form input elements bound by web2py.js */
|
||||
formInputClickSelector: 'input[type=submit]:not([name]), input[type=image]:not([name]), button[type=submit]:not([name]), button:not([type]):not([name])',
|
||||
/* Form input elements disabled during form submission */
|
||||
disableSelector: 'input, button, textarea, select',
|
||||
/* Form input elements re-enabled after form submission */
|
||||
@@ -472,8 +485,10 @@
|
||||
el.addClass('disabled');
|
||||
var method = el.prop('type') == 'submit' ? 'val' : 'html';
|
||||
var disable_with_message = (typeof w2p_ajax_disable_with_message != 'undefined') ? w2p_ajax_disable_with_message : "Working...";
|
||||
/*store enabled state*/
|
||||
el.data('w2p:enable-with', el[method]());
|
||||
/*store enabled state if not already disabled */
|
||||
if (el.data('w2p:enable-with') === undefined) {
|
||||
el.data('w2p:enable-with', el[method]());
|
||||
}
|
||||
/*if you don't want to see "working..." on buttons, replace the following
|
||||
* two lines with this one
|
||||
* el.data('w2p_disable_with', el[method]());
|
||||
@@ -513,7 +528,7 @@
|
||||
if(flash.html()) flash.append('<span id="closeflash"> × </span>').slideDown();
|
||||
},
|
||||
hide_flash: function () {
|
||||
$('.flash').hide().html('');
|
||||
$('.flash').fadeOut(0).html('');
|
||||
},
|
||||
show_if_handler: function (target) {
|
||||
var triggers = {};
|
||||
@@ -620,7 +635,9 @@
|
||||
if(disable_with == undefined) {
|
||||
element.data('w2p_disable_with', element[method]())
|
||||
}
|
||||
element.data('w2p:enable-with', element[method]());
|
||||
if (element.data('w2p:enable-with') === undefined) {
|
||||
element.data('w2p:enable-with', element[method]());
|
||||
}
|
||||
element[method](element.data('w2p_disable_with'));
|
||||
element.prop('disabled', true);
|
||||
});
|
||||
@@ -634,7 +651,10 @@
|
||||
form.find(web2py.enableSelector).each(function () {
|
||||
var element = $(this),
|
||||
method = element.is('button') ? 'html' : 'val';
|
||||
if(element.data('w2p:enable-with')) element[method](element.data('w2p:enable-with'));
|
||||
if(element.data('w2p:enable-with')) {
|
||||
element[method](element.data('w2p:enable-with'));
|
||||
element.removeData('w2p:enable-with');
|
||||
}
|
||||
element.prop('disabled', false);
|
||||
});
|
||||
},
|
||||
@@ -646,7 +666,18 @@
|
||||
el.on('ajax:complete', 'form[data-w2p_target]', function (e) {
|
||||
web2py.enableFormElements($(this));
|
||||
});
|
||||
}
|
||||
},
|
||||
/* Invalidate and force reload of a web2py component
|
||||
*/
|
||||
invalidate: function(target) {
|
||||
$('div[data-w2p_remote]', target).each(function () {
|
||||
var el = $('#' + $(this).attr('id')).get(0);
|
||||
if (el.timing !== undefined) { // Block triggering regular routines
|
||||
clearInterval(el.timing);
|
||||
}
|
||||
});
|
||||
$.web2py.component_handler(target);
|
||||
},
|
||||
}
|
||||
|
||||
/*end of functions */
|
||||
@@ -666,7 +697,7 @@
|
||||
/* compatibility code - start */
|
||||
ajax = jQuery.web2py.ajax;
|
||||
web2py_component = jQuery.web2py.component;
|
||||
web2py_websocket = jQuery.web2py.websocket;
|
||||
web2py_websocket = jQuery.web2py.web2py_websocket;
|
||||
web2py_ajax_page = jQuery.web2py.ajax_page;
|
||||
/*needed for IS_STRONG(entropy)*/
|
||||
web2py_validate_entropy = jQuery.web2py.validate_entropy;
|
||||
|
||||
@@ -20,14 +20,14 @@ jQuery(function(){
|
||||
function hoverMenu(){
|
||||
jQuery('ul.nav a.dropdown-toggle').parent().hover(function(){
|
||||
adjust_height_of_collapsed_nav();
|
||||
mi = jQuery(this).addClass('open');
|
||||
var mi = jQuery(this).addClass('open');
|
||||
mi.children('.dropdown-menu').stop(true, true).delay(200).fadeIn(400);
|
||||
}, function(){
|
||||
mi = jQuery(this);
|
||||
var mi = jQuery(this);
|
||||
mi.children('.dropdown-menu').stop(true, true).delay(200).fadeOut(function(){mi.removeClass('open')});
|
||||
});
|
||||
}
|
||||
hoverMenu(); // first page load
|
||||
jQuery(window).resize(hoverMenu); // on resize event
|
||||
jQuery('ul.nav li.dropdown a').click(function(){window.location=jQuery(this).attr('href');});
|
||||
});
|
||||
});
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user