Compare commits

...

130 Commits

Author SHA1 Message Date
382e563590 new release: 0.8.8-beta 2020-02-23 14:45:45 +01:00
ca61a7cc21 audit: don't pop password as its censored already 2020-02-23 14:43:33 +01:00
fa2870afe0 sources: remove policies as they are not used currently 2020-02-23 14:40:06 +01:00
0f46207ea4 admin: fix provider list not having pagination 2020-02-23 14:29:21 +01:00
1e7d912144 actions: build :<branch-name> on push 2020-02-23 13:54:19 +01:00
f4a676e2fb sources/oauth: slugify provider type instead of just lowercase 2020-02-23 13:53:16 +01:00
b2c10e2387 ui: add missing discord and twitter icons 2020-02-23 13:47:21 +01:00
8c329dca7d core: add migration to fix null fields in core.application 2020-02-22 19:26:34 +01:00
83da175749 policies/expression: add pb_client_ip field 2020-02-22 19:26:16 +01:00
995c87938f core: fix default Null causing issues in translation 2020-02-21 23:10:00 +01:00
40678b2f84 new release: 0.8.7-beta 2020-02-21 22:17:11 +01:00
8dbbe9102b ui: fix application grid icons, fix SAML Authorize 2020-02-21 22:16:58 +01:00
2f51f354de ui: fix app icon not showing 2020-02-21 22:02:44 +01:00
04b815a33e admin: show object usage count instead of list 2020-02-21 22:02:03 +01:00
2a4d68911b helm: change static healthcheck and port 2020-02-21 21:50:16 +01:00
4d5a2d61ff new release: 0.8.6-beta 2020-02-21 21:36:04 +01:00
efd88c27ad audit: *crit* fix audit log not being protected correctly 2020-02-21 21:33:42 +01:00
80d361ccd2 audit: fix failed login events not being logged 2020-02-21 21:27:25 +01:00
6ed4501615 ui: fix branding viewport 2020-02-21 21:18:55 +01:00
8d34faa28e Merge pull request #5 from BeryJu/pf4
PatternFly v4
2020-02-21 21:03:48 +01:00
a3ae827839 ui: centrally load CodeMirror and init via data tag 2020-02-21 21:02:03 +01:00
88c1ad4c1c providers/saml: fix 500 when SAML Provider not assigned to application 2020-02-21 20:54:00 +01:00
1147c4901b ui: clean up some more remaining templates 2020-02-21 20:40:40 +01:00
063181d7a7 ui: use compact templates 2020-02-21 20:24:02 +01:00
1285ba6fbb ui: include font-awesome 2020-02-21 18:00:09 +01:00
a09a1793ec ui: update templates for jinja2-related fields 2020-02-21 15:36:37 +01:00
50caa3ac3e ui: update static docker image to download NPM modules 2020-02-21 15:33:54 +01:00
9440d24358 static: use codemirror from npm 2020-02-21 15:18:13 +01:00
26bf6fd22f all: add more helpful help_text to models 2020-02-21 15:12:16 +01:00
e2f836feae all: fix left over references to error templates 2020-02-21 15:05:32 +01:00
b6326f399c ui: clean up more generic forms, remove is_login everywhere 2020-02-21 15:00:45 +01:00
ea6a1422f7 ui: rewrite admin templates to pf4, add some helper scripts 2020-02-21 14:20:16 +01:00
8fd86a28ff ui: fixup minor issues, add static app 2020-02-21 11:20:55 +01:00
d88283a7a9 Merge branch 'master' into pf4
# Conflicts:
#	passbook/core/static/img/logos/discord.svg
#	passbook/core/static/js/passbook.js
#	passbook/core/templates/login/with_sources.html
#	passbook/core/templates/overview/index.html
#	passbook/core/views/authentication.py
2020-02-21 09:05:40 +01:00
32a15f84c0 root: run bandit as part of pre-commit 2020-02-21 09:03:59 +01:00
93ba4b7f62 root: use defusedxml's defuse_stdlib globally 2020-02-21 09:00:28 +01:00
187780dab2 new release: 0.8.5-beta 2020-02-20 21:39:13 +01:00
d988f37afc lib: add SentryIgnoredException, to easily ignore exceptions from sentry 2020-02-20 21:38:53 +01:00
295c0bae3f sources/saml: validate SAMLResponse signature 2020-02-20 21:34:25 +01:00
38a22ddf13 providers/saml: cleanup encoding 2020-02-20 21:33:10 +01:00
d06f1abb89 providers/saml: add POST binding support to Metadata 2020-02-20 17:38:42 +01:00
027a64fad2 providers/saml: change default NameID Format to emailAddress 2020-02-20 17:37:09 +01:00
84fc54ddaa sources/saml: entity_id -> issuer 2020-02-20 17:23:27 +01:00
0b5caa85f5 all: sort imports and cleanup 2020-02-20 17:23:05 +01:00
14e0a17dbc ui: don't remove dashes when auto generating slug 2020-02-20 17:13:50 +01:00
3c04afa31f root: use different cookie names for dev instance 2020-02-20 17:08:11 +01:00
40a2a26904 sources/saml: fix Metadata cert including PEM header 2020-02-20 17:05:11 +01:00
c8b3c6e51a sources/saml: fix build_full_url using incorrect URL parameter 2020-02-20 17:04:54 +01:00
e0272a6422 providers/saml: Show error message when trying to get metadata without assigning application 2020-02-20 17:04:20 +01:00
b290bbf6d7 new release: 0.8.4-beta 2020-02-20 16:17:23 +01:00
8d875cb01d providers/saml: fix /login/ pointing to wrong view 2020-02-20 16:13:55 +01:00
36b1f8ba36 new release: 0.8.3-beta 2020-02-20 15:14:49 +01:00
6c889eff27 core: fix application icons not loading, fix with_sources being broken 2020-02-20 14:30:06 +01:00
9d8675e54b new release: 0.8.2-beta 2020-02-20 13:57:46 +01:00
22ae986c0b root: add logger name to log output 2020-02-20 13:52:14 +01:00
2bef5f3911 policies: struct -> types to match core 2020-02-20 13:52:05 +01:00
3c2b8e5ee1 all: prefix all UI related methods with ui_, switch to property and return dataclass 2020-02-20 13:51:41 +01:00
c96571bdba core: fix discord logo being hard to see 2020-02-20 13:50:05 +01:00
2dfd93afb1 core: add more fields for metadata of applications 2020-02-20 13:45:22 +01:00
f1d77d475c ui: start patternfly v4 migration 2020-02-19 21:03:39 +01:00
1d22e30c70 lib: sentry ignore Redis and OSError 2020-02-19 17:13:44 +01:00
07b7951390 sources/ldap: handle user_sync errors better, show warning when user exists already 2020-02-19 16:20:33 +01:00
995615d0a0 policies/expression: Return False if Policy returns Undefined and log warning 2020-02-19 16:19:02 +01:00
ac273aab75 core: raise PropertyMappingExpressionException when PropertyMapping returns Undefined 2020-02-19 16:18:31 +01:00
44cd03654d core: base set maximum-scale to 1 2020-02-19 15:11:25 +01:00
3e2375f970 new release: 0.8.1-beta 2020-02-19 11:31:05 +01:00
38ad8e5fd3 policies/expression: fix pb_is_sso_flow 2020-02-19 11:01:20 +01:00
c481558a46 helm: fix error that FLUSHDB Command is not available 2020-02-19 10:57:57 +01:00
e27a05a7fc lib/sentry: ignore django validation error 2020-02-19 10:54:29 +01:00
e4886f0c6f new release: 0.8.0-beta 2020-02-19 10:29:52 +01:00
8b2ce5476a policies/expression: add annotation to update docs, name jinja filters/funcs more clearly 2020-02-19 10:23:42 +01:00
1b82283a20 docs: update policy types, add docs for expression policies 2020-02-19 10:21:28 +01:00
7f3d0113c2 policies: remove redundant policies which can be easily implemented with expressions 2020-02-19 09:51:15 +01:00
0f6dd33a6b api: add expression policy to API URLs 2020-02-19 09:49:57 +01:00
5b79b3fd22 policies/expression: move evaluation code into separate class 2020-02-19 09:49:38 +01:00
d68c72f1fa lib: remove method_decorator Mixins 2020-02-18 22:28:47 +01:00
9267d0c1dd all: general maintenance, prepare for pyright 2020-02-18 22:12:51 +01:00
865abc005a sources/oauth: remove leading spaces in default URLs 2020-02-18 21:49:53 +01:00
a2725d5b82 sources/oauth: remove redundant OAuth2Clients 2020-02-18 21:49:40 +01:00
4a05bc6e02 sources/oauth: improve default OAuth2 Client, send access_token as Bearer Authz 2020-02-18 21:49:23 +01:00
4e8238603a all: cleanup logging to be structured 2020-02-18 21:35:58 +01:00
ff25c1c057 admin: load custom policy templates 2020-02-18 21:35:21 +01:00
78cddca0d7 admin: fix user object being overwritten when deleting a user 2020-02-18 21:35:06 +01:00
4742ee1d93 docs: add aws integration 2020-02-18 20:14:54 +01:00
0c2dc309e7 providers/saml: fix metadata URLs using incorrect params 2020-02-18 20:14:28 +01:00
144935d10f docs: add ansible tower/awx integration guide 2020-02-18 17:33:31 +01:00
74ad1b6759 factors: strip port for domain check 2020-02-18 17:05:30 +01:00
591d2f89a1 audit: log event creation on save 2020-02-18 17:05:11 +01:00
7c353f9297 sources/oauth: remove supervisr 2020-02-18 17:01:08 +01:00
cd1af15c56 core: sort applications by name 2020-02-18 17:00:56 +01:00
878169ea2e core: only show icon on login page if defined 2020-02-18 17:00:26 +01:00
38dfb03668 new release: 0.7.17-beta 2020-02-18 16:29:23 +01:00
e2631cec0e factors/view: show concise error message when domain is mis-configured 2020-02-18 16:29:04 +01:00
5dad853f8a docs: use note blocks instead of code blocks for product description 2020-02-18 15:34:41 +01:00
9f00843441 policies/expression: add Expression based policy 2020-02-18 15:12:50 +01:00
f31cd7dec6 core: check PropertyMapping's expression syntax before save 2020-02-18 15:12:05 +01:00
1c1afca31f providers/saml: fix linting error 2020-02-18 11:34:04 +01:00
fbd4bdef33 providers/saml: add modal to show metadata without download 2020-02-18 10:57:43 +01:00
5b22f9b6c3 providers/saml: transition to dataclass from dict, cleanup unused templates, add missing autosubmit_form 2020-02-18 10:57:30 +01:00
083e317028 lib: add helper method for 400 response with message 2020-02-18 10:13:53 +01:00
95416623b3 sources/ldap: better handle property mapping evaluation errors 2020-02-18 10:13:05 +01:00
813b2676de providers/saml: better handle PropertyMapping evaluation errors 2020-02-18 10:12:42 +01:00
aeca66a288 providers/saml: change assertion_valid_not_before default to -5 minutes 2020-02-17 21:32:23 +01:00
04a5428148 new release: 0.7.16-beta 2020-02-17 21:02:54 +01:00
73b173b92a admin: fix form missing on update pages 2020-02-17 21:02:47 +01:00
7cbf20a71c admin: fix CodeMirror field not loading correctly 2020-02-17 21:02:35 +01:00
7a98e6d92b new release: 0.7.15-beta 2020-02-17 20:45:56 +01:00
49e915f98b Merge pull request #4 from BeryJu/propertymapping-jinja
PropertyMappings using Jinja
2020-02-17 20:45:04 +01:00
3aa2f1e892 *: propertymapping template -> expression 2020-02-17 20:38:14 +01:00
bc4b7ef44d providers/saml: add custom help text for templates, add docs for User Object reference 2020-02-17 20:30:14 +01:00
9400b01a55 admin: parameterise generic from's base template 2020-02-17 20:29:41 +01:00
e57da71dcf sources/ldap: update LDAP source to use new property mappings 2020-02-17 17:55:48 +01:00
7268afaaf9 providers/saml: update to new PropertyMappings 2020-02-17 17:50:11 +01:00
205183445c admin: add support for template field and Jinja2 highlighting 2020-02-17 17:48:53 +01:00
a08bdfdbcd root: remove prospector from Pipfile as it causes lock issues, install in CI 2020-02-17 17:48:18 +01:00
e6c47fee26 core: add template field to PropertyMapping 2020-02-17 17:47:51 +01:00
a5629c5155 providers/saml: add changeable signature and digest algorithm 2020-02-17 16:28:18 +01:00
41689fe3ce sources/* add missing migrations 2020-02-17 16:27:35 +01:00
8e84208e2c new release: 0.7.14-beta 2020-02-17 15:42:14 +01:00
32a48fa07a providers/saml: more typehints 2020-02-17 15:40:49 +01:00
773a9c0692 policies/engine: fix cached policy results being ignored 2020-02-17 15:37:51 +01:00
8808e3afe0 policies/engine: set mp start method to fork to fix issues under macOS 2020-02-17 15:20:30 +01:00
ecea85f8ca lib/config: remove autoreload handler as this API is gone in django 3 2020-02-17 15:20:11 +01:00
5dfa141e35 root/wsgi: log requests with event name of request 2020-02-16 14:36:31 +01:00
447e81d0b8 providers/saml: handle uncompressed SAML AuthNRequest 2020-02-16 14:08:35 +01:00
e138076e1d sources/saml: move labels from forms to models 2020-02-16 12:34:46 +01:00
721d133dc3 sources/oauth: move labels from form to models 2020-02-16 12:34:33 +01:00
75b687ecbe sources/ldap: move labels from form to models 2020-02-16 12:30:45 +01:00
bdd1863177 providers/saml: move field labels from Form into models 2020-02-16 12:30:26 +01:00
e5b85e8e6a providers/saml: move default saml properties to DB 2020-02-16 12:29:53 +01:00
782 changed files with 4327 additions and 273306 deletions

View File

@ -1,5 +1,5 @@
[bumpversion]
current_version = 0.7.13-beta
current_version = 0.8.8-beta
tag = True
commit = True
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)\-(?P<release>.*)

View File

@ -3,3 +3,4 @@ helm
passbook-ui
static
*.env.yml
node_modules/

View File

@ -56,7 +56,7 @@ jobs:
restore-keys: |
${{ runner.os }}-pipenv-
- name: Install dependencies
run: pip install -U pip pipenv && pipenv install --dev
run: pip install -U pip pipenv && pipenv install --dev && pipenv install --dev prospector --skip-lock
- name: Lint with prospector
run: pipenv run prospector
bandit:
@ -145,3 +145,73 @@ jobs:
run: pip install -U pip pipenv && pipenv install --dev
- name: Run coverage
run: pipenv run ./scripts/coverage.sh
# Build
build-server:
needs:
- migrations
- coverage
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Docker Login Registry
env:
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
run: docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD
- name: Building Docker Image
run: docker build
--no-cache
-t beryju/passbook:${GITHUB_REF##*/}
-f Dockerfile .
- name: Push Docker Container to Registry
run: docker push beryju/passbook:${GITHUB_REF##*/}
build-gatekeeper:
needs:
- migrations
- coverage
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Docker Login Registry
env:
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
run: docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD
- name: Building Docker Image
run: |
cd gatekeeper
docker build \
--no-cache \
-t beryju/passbook-gatekeeper:${GITHUB_REF##*/} \
-f Dockerfile .
- name: Push Docker Container to Registry
run: docker push beryju/passbook-gatekeeper:${GITHUB_REF##*/}
build-static:
needs:
- migrations
- coverage
runs-on: ubuntu-latest
services:
postgres:
image: postgres:latest
env:
POSTGRES_DB: passbook
POSTGRES_USER: passbook
POSTGRES_PASSWORD: "EK-5jnKfjrGRm<77"
redis:
image: redis:latest
steps:
- uses: actions/checkout@v1
- name: Docker Login Registry
env:
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
run: docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD
- name: Building Docker Image
run: docker build
--no-cache
--network=$(docker network ls | grep github | awk '{print $1}')
-t beryju/passbook-static:${GITHUB_REF##*/}
-f static.Dockerfile .
- name: Push Docker Container to Registry
run: docker push beryju/passbook-static:${GITHUB_REF##*/}

View File

@ -16,11 +16,11 @@ jobs:
- name: Building Docker Image
run: docker build
--no-cache
-t beryju/passbook:0.7.13-beta
-t beryju/passbook:0.8.8-beta
-t beryju/passbook:latest
-f Dockerfile .
- name: Push Docker Container to Registry (versioned)
run: docker push beryju/passbook:0.7.13-beta
run: docker push beryju/passbook:0.8.8-beta
- name: Push Docker Container to Registry (latest)
run: docker push beryju/passbook:latest
build-gatekeeper:
@ -37,11 +37,11 @@ jobs:
cd gatekeeper
docker build \
--no-cache \
-t beryju/passbook-gatekeeper:0.7.13-beta \
-t beryju/passbook-gatekeeper:0.8.8-beta \
-t beryju/passbook-gatekeeper:latest \
-f Dockerfile .
- name: Push Docker Container to Registry (versioned)
run: docker push beryju/passbook-gatekeeper:0.7.13-beta
run: docker push beryju/passbook-gatekeeper:0.8.8-beta
- name: Push Docker Container to Registry (latest)
run: docker push beryju/passbook-gatekeeper:latest
build-static:
@ -66,11 +66,11 @@ jobs:
run: docker build
--no-cache
--network=$(docker network ls | grep github | awk '{print $1}')
-t beryju/passbook-static:0.7.13-beta
-t beryju/passbook-static:0.8.8-beta
-t beryju/passbook-static:latest
-f static.Dockerfile .
- name: Push Docker Container to Registry (versioned)
run: docker push beryju/passbook-static:0.7.13-beta
run: docker push beryju/passbook-static:0.8.8-beta
- name: Push Docker Container to Registry (latest)
run: docker push beryju/passbook-static:latest
test-release:

View File

@ -40,6 +40,7 @@ signxml = "*"
structlog = "*"
swagger-spec-validator = "*"
urllib3 = {extras = ["secure"],version = "*"}
jinja2 = "*"
[requires]
python_version = "3.8"
@ -51,7 +52,6 @@ bumpversion = "*"
colorama = "*"
coverage = "*"
django-debug-toolbar = "*"
prospector = "*"
pylint = "*"
pylint-django = "*"
unittest-xml-reporting = "*"

324
Pipfile.lock generated
View File

@ -1,7 +1,7 @@
{
"_meta": {
"hash": {
"sha256": "3693ac70f66ada5c8c8784e6e2d5c2f0ee75219e7141dde1075347234366e314"
"sha256": "c9232d99b062ee14eda43d176481f16da78ce53f912c844db3f33f1b3e8a47b7"
},
"pipfile-spec": 6,
"requires": {
@ -23,6 +23,13 @@
],
"version": "==2.5.2"
},
"asgiref": {
"hashes": [
"sha256:7e06d934a7718bf3975acbf87780ba678957b87c7adc056f13b6215d610695a0",
"sha256:ea448f92fc35a0ef4b1508f53a04c4670255a3f33d22a81c8fc9c872036adbe5"
],
"version": "==3.2.3"
},
"asn1crypto": {
"hashes": [
"sha256:5a215cb8dc12f892244e3a113fe05397ee23c5c4ca7a69cd6e69811755efc42d",
@ -46,18 +53,18 @@
},
"boto3": {
"hashes": [
"sha256:7aaccacc199cd633b5ac14f0d544c9d592c53275a79cf4d230a9f66215331665",
"sha256:ca36aabfa5e7fa9ee8f84f82c3faffb4ffe078923f935f572f70dc49154ef6a0"
"sha256:33462a79d57c9c4a215e075472509537d03545f54566fc4f776fb0f4cfa616f6",
"sha256:34f9a04f529dc849f0e427782d6f3c6b62f7fb734d8f4859b17e5dee0855323e"
],
"index": "pypi",
"version": "==1.11.5"
"version": "==1.12.0"
},
"botocore": {
"hashes": [
"sha256:2538065f9f5023eae3607e78fc5d8c595c9173ec02bc92410652078617c44ac1",
"sha256:554231b1690c8521e05a41e50184e43d62941fdf9351e658aea894649b879985"
"sha256:055da4826f6c9158e4a61549d57a2ce449c27d44ce34ab4c96c7bb7b5c993efc",
"sha256:1f7cecfcd38c7cac17b5386014eb04626d1c7559ee8d8ec1526058cd23f6d1d4"
],
"version": "==1.14.15"
"version": "==1.15.0"
},
"celery": {
"hashes": [
@ -164,11 +171,11 @@
},
"django": {
"hashes": [
"sha256:1226168be1b1c7efd0e66ee79b0e0b58b2caa7ed87717909cd8a57bb13a7079a",
"sha256:9a4635813e2d498a3c01b10c701fe4a515d76dd290aaa792ccb65ca4ccb6b038"
"sha256:2f1ba1db8648484dd5c238fb62504777b7ad090c81c5f1fd8d5eb5ec21b5f283",
"sha256:c91c91a7ad6ef67a874a4f76f58ba534f9208412692a840e1d125eb5c279cb0a"
],
"index": "pypi",
"version": "==2.2.10"
"version": "==3.0.3"
},
"django-cors-middleware": {
"hashes": [
@ -195,11 +202,11 @@
},
"django-guardian": {
"hashes": [
"sha256:8cf4efd67a863eb32beafd4335a38ffb083630f8ab2045212d27f8f9c3abe5a6",
"sha256:e638c9a23eeac534bb68b133975539ed8782f733ab6f35c0b23b4c39cd06b1bb"
"sha256:8cacf49ebcc1e545f0a8997971eec0fe109f5ed31fc2a569a7bf5615453696e2",
"sha256:ac81e88372fdf1795d84ba065550e739b42e9c6d07cdf201cf5bbf9efa7f396c"
],
"index": "pypi",
"version": "==2.1.0"
"version": "==2.2.0"
},
"django-model-utils": {
"hashes": [
@ -225,27 +232,26 @@
},
"django-otp": {
"hashes": [
"sha256:1f16c2b93fe484706ff16ac6f5e64ecc73dd240318c333e0560384ba548d3837",
"sha256:cd4975539be478417033561e9832a1a69a583189f680e92a649f412c661f90aa"
"sha256:523a87f8d0c52ce9a9f0a5e248c59dab3e85cdda5bbcd106cf49138a8f3f3209",
"sha256:ad3206e4a6f461c8968a2366a7cccfb340b93294e604b278aa9ab8b26f1017a1"
],
"index": "pypi",
"version": "==0.7.5"
"version": "==0.8.1"
},
"django-prometheus": {
"hashes": [
"sha256:f0657d4b887309086b71b55f6aa4a95f967b35fe115128b501f95422c423b12c",
"sha256:f645016ae5270ac2025a70788cd2bd636244a0c5705b323cc086994bf828181e"
"sha256:362ea45e5ee26bdba85ce978aeb370659ca6bbc0d6bac69868a055179e053bd1",
"sha256:facaa677386899303ea26c45552371cc43f476e42a81c081011a49cb5564af0b"
],
"index": "pypi",
"version": "==2.0.0.dev124"
"version": "==2.1.0.dev5"
},
"django-recaptcha": {
"hashes": [
"sha256:3b19b9d972ca802b683eed5fd51ed84b0798f2a52f8d057a912eb7d99cff3779",
"sha256:b6ce959cd7c0af7501698fab5f52ca1bcb6d9402cb3b8b42a4c4cb13d89cfbfa"
"sha256:567784963fd5400feaf92e8951d8dbbbdb4b4c48a76e225d4baa63a2c9d2cd8c"
],
"index": "pypi",
"version": "==2.0.5"
"version": "==2.0.6"
},
"django-redis": {
"hashes": [
@ -264,11 +270,11 @@
},
"django-storages": {
"hashes": [
"sha256:0a9b7e620e969fb0797523695329ed223bf540bbfdf6cd163b061fc11dab2d1c",
"sha256:9322ab74ba6371e2e0fccc350c741686ade829e43085597b26b07ae8955a0a00"
"sha256:3103991c2ee8cef8a2ff096709973ffe7106183d211a79f22cf855f33533d924",
"sha256:a59e9923cbce7068792f75344ed7727021ee4ac20f227cf17297d0d03d141e91"
],
"index": "pypi",
"version": "==1.8"
"version": "==1.9.1"
},
"djangorestframework": {
"hashes": [
@ -295,11 +301,11 @@
},
"drf-yasg": {
"hashes": [
"sha256:4cfec631880ae527a91ec7cd3241aea2f82189f59e2f089119aa687761afb227",
"sha256:504cce09035cf1bace63b84d9d778b772f86bb37d8a71ed6f723346362e633b2"
"sha256:5572e9d5baab9f6b49318169df9789f7399d0e3c7bdac8fdb8dfccf1d5d2b1ca",
"sha256:7d7af27ad16e18507e9392b2afd6b218fbffc432ec8dbea053099a2241e184ff"
],
"index": "pypi",
"version": "==1.17.0"
"version": "==1.17.1"
},
"eight": {
"hashes": [
@ -338,6 +344,7 @@
"sha256:c10142f819c2d22bdcd17548c46fa9b77cf4fda45097854c689666bf425e7484",
"sha256:c922560ac46888d47384de1dbdc3daaa2ea993af4b26a436dec31fa2c19ec668"
],
"index": "pypi",
"version": "==3.0.0a1"
},
"jmespath": {
@ -372,35 +379,36 @@
},
"lxml": {
"hashes": [
"sha256:00ac0d64949fef6b3693813fe636a2d56d97a5a49b5bbb86e4cc4cc50ebc9ea2",
"sha256:0571e607558665ed42e450d7bf0e2941d542c18e117b1ebbf0ba72f287ad841c",
"sha256:0e3f04a7615fdac0be5e18b2406529521d6dbdb0167d2a690ee328bef7807487",
"sha256:13cf89be53348d1c17b453867da68704802966c433b2bb4fa1f970daadd2ef70",
"sha256:217262fcf6a4c2e1c7cb1efa08bd9ebc432502abc6c255c4abab611e8be0d14d",
"sha256:223e544828f1955daaf4cefbb4853bc416b2ec3fd56d4f4204a8b17007c21250",
"sha256:277cb61fede2f95b9c61912fefb3d43fbd5f18bf18a14fae4911b67984486f5d",
"sha256:3213f753e8ae86c396e0e066866e64c6b04618e85c723b32ecb0909885211f74",
"sha256:4690984a4dee1033da0af6df0b7a6bde83f74e1c0c870623797cec77964de34d",
"sha256:4fcc472ef87f45c429d3b923b925704aa581f875d65bac80f8ab0c3296a63f78",
"sha256:61409bd745a265a742f2693e4600e4dbd45cc1daebe1d5fad6fcb22912d44145",
"sha256:678f1963f755c5d9f5f6968dded7b245dd1ece8cf53c1aa9d80e6734a8c7f41d",
"sha256:6c6d03549d4e2734133badb9ab1c05d9f0ef4bcd31d83e5d2b4747c85cfa21da",
"sha256:6e74d5f4d6ecd6942375c52ffcd35f4318a61a02328f6f1bd79fcb4ffedf969e",
"sha256:7b4fc7b1ecc987ca7aaf3f4f0e71bbfbd81aaabf87002558f5bc95da3a865bcd",
"sha256:7ed386a40e172ddf44c061ad74881d8622f791d9af0b6f5be20023029129bc85",
"sha256:8f54f0924d12c47a382c600c880770b5ebfc96c9fd94cf6f6bdc21caf6163ea7",
"sha256:ad9b81351fdc236bda538efa6879315448411a81186c836d4b80d6ca8217cdb9",
"sha256:bbd00e21ea17f7bcc58dccd13869d68441b32899e89cf6cfa90d624a9198ce85",
"sha256:c3c289762cc09735e2a8f8a49571d0e8b4f57ea831ea11558247b5bdea0ac4db",
"sha256:cf4650942de5e5685ad308e22bcafbccfe37c54aa7c0e30cd620c2ee5c93d336",
"sha256:cfcbc33c9c59c93776aa41ab02e55c288a042211708b72fdb518221cc803abc8",
"sha256:e301055deadfedbd80cf94f2f65ff23126b232b0d1fea28f332ce58137bcdb18",
"sha256:ebbfe24df7f7b5c6c7620702496b6419f6a9aa2fd7f005eb731cc80d7b4692b9",
"sha256:eff69ddbf3ad86375c344339371168640951c302450c5d3e9936e98d6459db06",
"sha256:f6ed60a62c5f1c44e789d2cf14009423cb1646b44a43e40a9cf6a21f077678a1"
"sha256:06d4e0bbb1d62e38ae6118406d7cdb4693a3fa34ee3762238bcb96c9e36a93cd",
"sha256:0701f7965903a1c3f6f09328c1278ac0eee8f56f244e66af79cb224b7ef3801c",
"sha256:1f2c4ec372bf1c4a2c7e4bb20845e8bcf8050365189d86806bad1e3ae473d081",
"sha256:4235bc124fdcf611d02047d7034164897ade13046bda967768836629bc62784f",
"sha256:5828c7f3e615f3975d48f40d4fe66e8a7b25f16b5e5705ffe1d22e43fb1f6261",
"sha256:585c0869f75577ac7a8ff38d08f7aac9033da2c41c11352ebf86a04652758b7a",
"sha256:5d467ce9c5d35b3bcc7172c06320dddb275fea6ac2037f72f0a4d7472035cea9",
"sha256:63dbc21efd7e822c11d5ddbedbbb08cd11a41e0032e382a0fd59b0b08e405a3a",
"sha256:7bc1b221e7867f2e7ff1933165c0cec7153dce93d0cdba6554b42a8beb687bdb",
"sha256:8620ce80f50d023d414183bf90cc2576c2837b88e00bea3f33ad2630133bbb60",
"sha256:8a0ebda56ebca1a83eb2d1ac266649b80af8dd4b4a3502b2c1e09ac2f88fe128",
"sha256:90ed0e36455a81b25b7034038e40880189169c308a3df360861ad74da7b68c1a",
"sha256:95e67224815ef86924fbc2b71a9dbd1f7262384bca4bc4793645794ac4200717",
"sha256:afdb34b715daf814d1abea0317b6d672476b498472f1e5aacbadc34ebbc26e89",
"sha256:b4b2c63cc7963aedd08a5f5a454c9f67251b1ac9e22fd9d72836206c42dc2a72",
"sha256:d068f55bda3c2c3fcaec24bd083d9e2eede32c583faf084d6e4b9daaea77dde8",
"sha256:d5b3c4b7edd2e770375a01139be11307f04341ec709cf724e0f26ebb1eef12c3",
"sha256:deadf4df349d1dcd7b2853a2c8796593cc346600726eff680ed8ed11812382a7",
"sha256:df533af6f88080419c5a604d0d63b2c33b1c0c4409aba7d0cb6de305147ea8c8",
"sha256:e4aa948eb15018a657702fee0b9db47e908491c64d36b4a90f59a64741516e77",
"sha256:e5d842c73e4ef6ed8c1bd77806bf84a7cb535f9c0cf9b2c74d02ebda310070e1",
"sha256:ebec08091a22c2be870890913bdadd86fcd8e9f0f22bcb398abd3af914690c15",
"sha256:edc15fcfd77395e24543be48871c251f38132bb834d9fdfdad756adb6ea37679",
"sha256:f2b74784ed7e0bc2d02bd53e48ad6ba523c9b36c194260b7a5045071abbb1012",
"sha256:fa071559f14bd1e92077b1b5f6c22cf09756c6de7139370249eb372854ce51e6",
"sha256:fd52e796fee7171c4361d441796b64df1acfceb51f29e545e812f16d023c4bbc",
"sha256:fe976a0f1ef09b3638778024ab9fb8cde3118f203364212c198f71341c0715ca"
],
"index": "pypi",
"version": "==4.4.2"
"version": "==4.5.0"
},
"markupsafe": {
"hashes": [
@ -450,11 +458,11 @@
},
"packaging": {
"hashes": [
"sha256:aec3fdbb8bc9e4bb65f0634b9f551ced63983a529d6a8931817d52fdd0816ddb",
"sha256:fe1d8331dfa7cc0a883b49d75fc76380b2ab2734b220fbb87d774e4fd4b851f8"
"sha256:170748228214b70b672c581a3dd610ee51f733018650740e98c7df862a583f73",
"sha256:e665345f9eef0c621aa0bf2f8d78cf6d21904eef16a93f020240b704a57f1334"
],
"index": "pypi",
"version": "==20.0"
"version": "==20.1"
},
"prometheus-client": {
"hashes": [
@ -522,41 +530,39 @@
},
"pycryptodome": {
"hashes": [
"sha256:042ae873baadd0c33b4d699a5c5b976ade3233a979d972f98ca82314632d868c",
"sha256:0502876279772b1384b660ccc91563d04490d562799d8e2e06b411e2d81128a9",
"sha256:2de33ed0a95855735d5a0fc0c39603314df9e78ee8bbf0baa9692fb46b3b8bbb",
"sha256:319e568baf86620b419d53063b18c216abf924875966efdfe06891b987196a45",
"sha256:4372ec7518727172e1605c0843cdc5375d4771e447b8148c787b860260aae151",
"sha256:48821950ffb9c836858d8fa09d7840b6df52eadd387a3c5acece55cb387743f9",
"sha256:4b9533d4166ca07abdd49ce9d516666b1df944997fe135d4b21ac376aa624aff",
"sha256:54456cf85130e01674d21fb1ab89ffccacb138a8ade88d72fa2b0ac898d2798b",
"sha256:56fdd0e425f1b8fd3a00b6d96351f86226674974814c50534864d0124d48871f",
"sha256:57b1b707363490c495ad0eeb38bd1b0e1697c497af25fad78d3a1ebf0477fd5b",
"sha256:5c485ed6e9718ebcaa81138fa70ace9c563d202b56a8cee119b4085b023931f5",
"sha256:63c103a22cbe9752f6ea9f1a0de129995bad91c4d03a66c67cffcf6ee0c9f1e1",
"sha256:68fab8455efcbfe87c5d75015476f9b606227ffe244d57bfd66269451706e899",
"sha256:6c2720696b10ae356040e888bde1239b8957fe18885ccf5e7b4e8dec882f0856",
"sha256:72166c2ac520a5dbd2d90208b9c279161ec0861662a621892bd52fb6ca13ab91",
"sha256:7c52308ac5b834331b2f107a490b2c27de024a229b61df4cdc5c131d563dfe98",
"sha256:87d8d85b4792ca5e730fb7a519fbc3ed976c59dcf79c5204589c59afd56b9926",
"sha256:896e9b6fd0762aa07b203c993fbbee7a1f1a4674c6886afd7bfa86f3d1be98a8",
"sha256:8a799bea3c6617736e914a2e77c409f52893d382f619f088f8a80e2e21f573c1",
"sha256:9d9945ac8375d5d8e60bd2a2e1df5882eaa315522eedf3ca868b1546dfa34eba",
"sha256:9ef966c727de942de3e41aa8462c4b7b4bca70f19af5a3f99e31376589c11aac",
"sha256:a168e73879619b467072509a223282a02c8047d932a48b74fbd498f27224aa04",
"sha256:a30f501bbb32e01a49ef9e09ca1260e5ab49bf33a257080ec553e08997acc487",
"sha256:a8ca2450394d3699c9f15ef25e8de9a24b401933716a1e39d37fa01f5fe3c58b",
"sha256:aec4d42deb836b8fb3ba32f2ba1ef0d33dd3dc9d430b1479ee7a914490d15b5e",
"sha256:b4af098f2a50f8d048ab12cabb59456585c0acf43d90ee79782d2d6d0ed59dba",
"sha256:b55c60c321ac91945c60a40ac9896ac7a3d432bb3e8c14006dfd82ad5871c331",
"sha256:c53348358408d94869059e16fba5ff3bef8c52c25b18421472aba272b9bb450f",
"sha256:cbfd97f9e060f0d30245cd29fa267a9a84de9da97559366fca0a3f7655acc63f",
"sha256:d3fe3f33ad52bf0c19ee6344b695ba44ffbfa16f3c29ca61116b48d97bd970fb",
"sha256:e3a79a30d15d9c7c284a7734036ee8abdb5ca3a6f5774d293cdc9e1358c1dc10",
"sha256:eec0689509389f19875f66ae8dedd59f982240cdab31b9f78a8dc266011df93a"
"sha256:012ca77c2105600e3c6aef43188101ac1d95052c633a4ae8fbebffab20c25f8a",
"sha256:05b4d865710f9a6378d3ada28195ff78e52642d3ecffe6fa9d379d870b9bf29d",
"sha256:07daddb98f98f771ba027f8f835bdb675aeb84effe41ed5221f520b267429354",
"sha256:09bf05a489fe10f9280a5e0163f195e7b9630cafb15f7d72fb9c8f5eb2afa84f",
"sha256:0a8d5f2dbb4bbe830ace54286b829bfa529f0853bedaab6225fcb2e6d1f7e356",
"sha256:1259b8ca49662b8a941177357f08147d858595c0042e63ff81e9628e925b5c9d",
"sha256:238d8b6dd27bd1a04816a68aa90a739e6dd23b192fcd83b50f9360958bff192a",
"sha256:2a57daef18a2022a5e4b6f7376c9ddd0c2d946e4b1f1e59b837f5bf295be7380",
"sha256:39e5ca2f66d1eac7abcba5ce1a03370d123dc6085620f1cd532dfee27e650178",
"sha256:3d516df693c195b8da3795e381429bd420e87081b7e6c2871c62c9897c812cda",
"sha256:3e486c5b7228e864665fc479e9f596b2547b5fe29c6f5c8ed3807784d06faed7",
"sha256:5029c46b0d41dfb763c3981c0af68eab029f06fe2b94f2299112fc18cf9e8d6d",
"sha256:5817c0b3c263025d851da96b90cbc7e95348008f88b990e90d10683dba376666",
"sha256:79320f1fc5c9ca682869087c565bb29ca6f334692e940d7365771e9a94382e12",
"sha256:887d08beca6368d3d70dc75126607ad76317a9fd07fe61323d8c3cb42add12b6",
"sha256:9163fec630495c10c767991e3f8dab32f4427bfb2dfeaa59bb28fe3e52ba66f2",
"sha256:95d324e603c5cec5d89e8595236bbf59ade5fe3a72d100ce61eebb323d598750",
"sha256:9927aa8a8cb4af681279b6f28a1dcb14e0eb556c1aea8413a1e27608a8516e0c",
"sha256:9948c2d5c5c0ee45ed44cee0e2eba2ce60a03be006ed3074521f3da3be162e72",
"sha256:a719bd708207fa219fcbf4c8ebbcbc52846045f78179d00445b429fdabdbc1c4",
"sha256:bc22ced26ebc46546798fa0141f4418f1db116dec517f0aeaecec87cf7b2416c",
"sha256:c41b7e10b72cef00cd63410f31fe50e72dc3a40eafbd146e288384fbe4208064",
"sha256:cdb0ad83a5d6bac986a37fcb7562bcbef0aabae8ea19505bab5cf83c4d18af12",
"sha256:d8e480f65ac7105cbc288eec2417dc61eaac6ed6e75595aa15b8c7c77c53a68b",
"sha256:da2d581da279bc7408d38e16ff77754f5448c4352f2acfe530a5d14d8fc6934a",
"sha256:de61091dd68326b600422cf731eb4810c4c6363f18a65bccd6061784b7454f5b",
"sha256:ec7d39589f9cfc2a8b83b1d2fc673441757c99d43283e97b2dd46e0e23730db8",
"sha256:f3204006869ab037604b1d9f045c4e84882ddd365e4ee8caa5eb1ff47a59188e",
"sha256:f4d2174e168d0eabd1fffaf88b4f62c2b6f30a67b8816f31024b8e48be3e2d75",
"sha256:fcff8c9d88d58880f7eda2139c7c444552a38f98a9e77ba5970b6e78f54ac358"
],
"index": "pypi",
"version": "==3.9.4"
"version": "==3.9.6"
},
"pycryptodomex": {
"hashes": [
@ -714,10 +720,10 @@
},
"ruamel.yaml": {
"hashes": [
"sha256:ee3264b83c3309b4ae7978afa185da6a1d278e3abc9fb942f1a0b57c622092f8",
"sha256:fd16843ff0ba45fa5e1ea9ea7038428b4a46f2c39deea9aa67f9eaa34823dc11"
"sha256:0962fd7999e064c4865f96fb1e23079075f4a2a14849bcdc5cdba53a24f9759b",
"sha256:099c644a778bf72ffa00524f78dd0b6476bca94a1da344130f4bf3381ce5b954"
],
"version": "==0.16.9"
"version": "==0.16.10"
},
"ruamel.yaml.clib": {
"hashes": [
@ -753,11 +759,11 @@
},
"sentry-sdk": {
"hashes": [
"sha256:8e2d38dc58dc992280487e553ec3d97a424e4d179f4fad802ef3b08f64ccf4d8",
"sha256:9b59e155229ea7d46a52b5c025d8c3c6d591e9dd9bb5f5f47310b2bb430038a8"
"sha256:b06dd27391fd11fb32f84fe054e6a64736c469514a718a99fb5ce1dff95d6b28",
"sha256:e023da07cfbead3868e1e2ba994160517885a32dfd994fc455b118e37989479b"
],
"index": "pypi",
"version": "==0.14.0"
"version": "==0.14.1"
},
"service-identity": {
"hashes": [
@ -791,11 +797,11 @@
},
"structlog": {
"hashes": [
"sha256:4287058cf4ce1a59bc5dea290d6386d37f29a37529c9a51cdf7387e51710152b",
"sha256:6640e6690fc31d5949bc614c1a630464d3aaa625284aeb7c6e486c3010d73e12"
"sha256:7a48375db6274ed1d0ae6123c486472aa1d0890b08d314d2b016f3aa7f35990b",
"sha256:8a672be150547a93d90a7d74229a29e765be05bd156a35cdcc527ebf68e9af92"
],
"index": "pypi",
"version": "==19.2.0"
"version": "==20.1.0"
},
"swagger-spec-validator": {
"hashes": [
@ -817,12 +823,12 @@
"secure"
],
"hashes": [
"sha256:a8a318824cc77d1fd4b2bec2ded92646630d7fe8619497b142c84a9e6f5a7293",
"sha256:f3c5fd51747d450d4dcf6f923c81f78f811aab8205fda64b0aba34a4e48b0745"
"sha256:2f3db8b19923a873b3e5256dc9c2dedfa883e33d87c690d9c7913e1f40673cdc",
"sha256:87716c2d2a7121198ebcb7ce7cccf6ce5e9ba539041cfbaeecfb641dc0bf6acc"
],
"index": "pypi",
"markers": null,
"version": "==1.25.7"
"version": "==1.25.8"
},
"vine": {
"hashes": [
@ -863,10 +869,10 @@
},
"autopep8": {
"hashes": [
"sha256:4d8eec30cc81bc5617dbf1218201d770dc35629363547f17577c61683ccfb3ee"
"sha256:0f592a0447acea0c2b0a9602be1e4e3d86db52badd2e3c84f0193bfd89fd3a43"
],
"index": "pypi",
"version": "==1.4.4"
"version": "==1.5"
},
"bandit": {
"hashes": [
@ -946,40 +952,33 @@
},
"django": {
"hashes": [
"sha256:1226168be1b1c7efd0e66ee79b0e0b58b2caa7ed87717909cd8a57bb13a7079a",
"sha256:9a4635813e2d498a3c01b10c701fe4a515d76dd290aaa792ccb65ca4ccb6b038"
"sha256:2f1ba1db8648484dd5c238fb62504777b7ad090c81c5f1fd8d5eb5ec21b5f283",
"sha256:c91c91a7ad6ef67a874a4f76f58ba534f9208412692a840e1d125eb5c279cb0a"
],
"index": "pypi",
"version": "==2.2.10"
"version": "==3.0.3"
},
"django-debug-toolbar": {
"hashes": [
"sha256:24c157bc6c0e1648e0a6587511ecb1b007a00a354ce716950bff2de12693e7a8",
"sha256:77cfba1d6e91b9bc3d36dc7dc74a9bb80be351948db5f880f2562a0cbf20b6c5"
"sha256:eabbefe89881bbe4ca7c980ff102e3c35c8e8ad6eb725041f538988f2f39a943",
"sha256:ff94725e7aae74b133d0599b9bf89bd4eb8f5d2c964106e61d11750228c8774c"
],
"index": "pypi",
"version": "==2.1"
},
"dodgy": {
"hashes": [
"sha256:28323cbfc9352139fdd3d316fa17f325cc0e9ac74438cbba51d70f9b48f86c3a",
"sha256:51f54c0fd886fa3854387f354b19f429d38c04f984f38bc572558b703c0542a6"
],
"version": "==0.2.1"
"version": "==2.2"
},
"gitdb2": {
"hashes": [
"sha256:1b6df1433567a51a4a9c1a5a0de977aa351a405cc56d7d35f3388bad1f630350",
"sha256:96bbb507d765a7f51eb802554a9cfe194a174582f772e0d89f4e87288c288b7b"
"sha256:0375d983fd887d03c8942e81b1b0abc6c320cfb500cd3fe0d9c0eac87fbf2b52",
"sha256:b2b3a67090c17dc61f8407ca485e79ae811225ab5ebcd98ac5ee01448e8987b5"
],
"version": "==2.0.6"
"version": "==3.0.2"
},
"gitpython": {
"hashes": [
"sha256:99c77677f31f255e130f3fed4c8e0eebb35f1a09df98ff965fff6774f71688cf",
"sha256:99cd0403cecd8a13b95d2e045b9fcaa7837137fcc5ec3105f2c413305d82c143"
"sha256:620b3c729bbc143b498cfea77e302999deedc55faec5b1067086c9ef90e101bc",
"sha256:a43a5d88a5bbc3cf32bb5223e4b4e68fd716db5e9996cad6e561bbfee6e5f4af"
],
"version": "==3.0.7"
"version": "==3.0.8"
},
"isort": {
"hashes": [
@ -1035,40 +1034,12 @@
],
"version": "==5.4.4"
},
"pep8-naming": {
"hashes": [
"sha256:1b419fa45b68b61cd8c5daf4e0c96d28915ad14d3d5f35fcc1e7e95324a33a2e",
"sha256:4eedfd4c4b05e48796f74f5d8628c068ff788b9c2b08471ad408007fc6450e5a"
],
"version": "==0.4.1"
},
"prospector": {
"hashes": [
"sha256:ea910794b53cfefcb5dfb6b4eb0323e42d1a88132e165b85b016cc7f0b6ae635"
],
"index": "pypi",
"version": "==1.2.0"
},
"pycodestyle": {
"hashes": [
"sha256:cbc619d09254895b0d12c2c691e237b2e91e9b2ecf5e84c26b35400f93dcfb83",
"sha256:cbfca99bd594a10f674d0cd97a3d802a1fdef635d4361e1a2658de47ed261e3a"
"sha256:95a2219d12372f05704562a14ec30bc76b05a5b297b21a5dfe3f6fac3491ae56",
"sha256:e40a936c9a450ad81df37f549d676d127b1b66000a6c500caa2b085bc0ca976c"
],
"version": "==2.4.0"
},
"pydocstyle": {
"hashes": [
"sha256:da7831660b7355307b32778c4a0dbfb137d89254ef31a2b2978f50fc0b4d7586",
"sha256:f4f5d210610c2d153fae39093d44224c17429e2ad7da12a8b419aba5c2f614b5"
],
"version": "==5.0.2"
},
"pyflakes": {
"hashes": [
"sha256:17dbeb2e3f4d772725c777fabc446d5634d1038f234e77343108ce445ea69ce0",
"sha256:d976835886f8c5b31d47970ed689944a0262b5f3afa00a5a7b4dc81e5449f8a2"
],
"version": "==2.1.1"
"version": "==2.5.0"
},
"pylint": {
"hashes": [
@ -1078,25 +1049,13 @@
"index": "pypi",
"version": "==2.4.4"
},
"pylint-celery": {
"hashes": [
"sha256:41e32094e7408d15c044178ea828dd524beedbdbe6f83f712c5e35bde1de4beb"
],
"version": "==0.3"
},
"pylint-django": {
"hashes": [
"sha256:9bdb0e022b19881218a25ffb8ad05e83b83bc5cdbc58e5ee8ffbe99965193f6c",
"sha256:9eea6a026eaa5ecfad5fed7a33faf77ef55a43cc78afbcaf2f6ddd071156b3f8"
"sha256:440beb814464928aedd2e21196bb6e47a83b63e2cbe886a701ba0f4a64206bbb",
"sha256:d5d113605a64cf0e638b707d4cb42106e626f8851bc30a44d5b22bd698ad8483"
],
"index": "pypi",
"version": "==2.0.12"
},
"pylint-flask": {
"hashes": [
"sha256:f4d97de2216bf7bfce07c9c08b166e978fe9f2725de2a50a9845a97de7e31517"
],
"version": "==0.6"
"version": "==2.0.13"
},
"pylint-plugin-utils": {
"hashes": [
@ -1155,18 +1114,6 @@
],
"version": "==2020.1.8"
},
"requirements-detector": {
"hashes": [
"sha256:9fbc4b24e8b7c3663aff32e3eba34596848c6b91bd425079b386973bd8d08931"
],
"version": "==0.6"
},
"setoptconf": {
"hashes": [
"sha256:5b0b5d8e0077713f5d5152d4f63be6f048d9a1bb66be15d089a11c898c3cf49c"
],
"version": "==0.2.0"
},
"six": {
"hashes": [
"sha256:236bdbdce46e6e6a3d61a337c0f8b763ca1e8717c03b369e87a7ec7ce1319c0a",
@ -1181,13 +1128,6 @@
],
"version": "==2.0.5"
},
"snowballstemmer": {
"hashes": [
"sha256:209f257d7533fdb3cb73bdbd24f436239ca3b2fa67d56f6ff88e86be08cc5ef0",
"sha256:df3bac3df4c2c01363f3dd2cfa78cce2840a79b9f1c2d2de9ce8d31683992f52"
],
"version": "==2.0.0"
},
"sqlparse": {
"hashes": [
"sha256:40afe6b8d4b1117e7dff5504d7a8ce07d9a1b15aeeade8a2d10f130a834f8177",
@ -1237,11 +1177,11 @@
},
"unittest-xml-reporting": {
"hashes": [
"sha256:358bbdaf24a26d904cc1c26ef3078bca7fc81541e0a54c8961693cc96a6f35e0",
"sha256:9d28ddf6524cf0ff9293f61bd12e792de298f8561a5c945acea63fb437789e0e"
"sha256:6584562cde8226fc79fa29e38903c669a02799074a563bb0b70fcd3a8e87829c",
"sha256:dd8046a64dc62f3d30301523a54992e0be75a945194491e0a3b718130cb429e0"
],
"index": "pypi",
"version": "==2.5.2"
"version": "==3.0.1"
},
"wrapt": {
"hashes": [

View File

@ -7,4 +7,4 @@ threads = 2
enable-threads = true
uid = passbook
gid = passbook
disable-logging=True
disable-logging = True

View File

@ -0,0 +1,32 @@
# Amazon Web Services Integration
## What is AWS
!!! note ""
Amazon Web Services (AWS) is the worlds most comprehensive and broadly adopted cloud platform, offering over 175 fully featured services from data centers globally. Millions of customers—including the fastest-growing startups, largest enterprises, and leading government agencies—are using AWS to lower costs, become more agile, and innovate faster.
## Preparation
The following placeholders will be used:
- `passbook.company` is the FQDN of the passbook Install
Create an application in passbook and note the slug, as this will be used later. Create a SAML Provider with the following Parameters:
- ACS URL: `https://signin.aws.amazon.com/saml`
- Audience: `urn:amazon:webservices`
- Issuer: `passbook`
You can of course use a custom Signing Certificate, and adjust durations.
## AWS
Create a Role with the Permissions you desire, and note the ARN.
AWS requires two custom PropertyMappings; `Role` and `RoleSessionName`. Create them as following:
![](./property-mapping-role.png)
![](./property-mapping-role-session-name.png)
Afterwards export the Metadata from passbook, and create an Identity Provider [here](https://console.aws.amazon.com/iam/home#/providers).

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

View File

@ -4,9 +4,8 @@
From https://about.gitlab.com/what-is-gitlab/
```
GitLab is a complete DevOps platform, delivered as a single application. This makes GitLab unique and makes Concurrent DevOps possible, unlocking your organization from the constraints of a pieced together toolchain. Join us for a live Q&A to learn how GitLab can give you unmatched visibility and higher levels of efficiency in a single application across the DevOps lifecycle.
```
!!! note ""
GitLab is a complete DevOps platform, delivered as a single application. This makes GitLab unique and makes Concurrent DevOps possible, unlocking your organization from the constraints of a pieced together toolchain. Join us for a live Q&A to learn how GitLab can give you unmatched visibility and higher levels of efficiency in a single application across the DevOps lifecycle.
## Preparation
@ -21,7 +20,7 @@ Create an application in passbook and note the slug, as this will be used later.
- Audience: `https://gitlab.company`
- Issuer: `https://gitlab.company`
You can of course use a custom Signing Certificate, and adjust the Assertion Length. To get the value for `idp_cert_fingerprint`, you can use a tool like [this](https://www.samltool.com/fingerprint.php).
You can of course use a custom Signing Certificate, and adjust durations. To get the value for `idp_cert_fingerprint`, you can use a tool like [this](https://www.samltool.com/fingerprint.php).
## GitLab Configuration

View File

@ -4,9 +4,8 @@
From https://goharbor.io
```
Harbor is an open source container image registry that secures images with role-based access control, scans images for vulnerabilities, and signs images as trusted. A CNCF Incubating project, Harbor delivers compliance, performance, and interoperability to help you consistently and securely manage images across cloud native compute platforms like Kubernetes and Docker.
```
!!! note ""
Harbor is an open source container image registry that secures images with role-based access control, scans images for vulnerabilities, and signs images as trusted. A CNCF Incubating project, Harbor delivers compliance, performance, and interoperability to help you consistently and securely manage images across cloud native compute platforms like Kubernetes and Docker.
## Preparation

View File

@ -4,10 +4,9 @@
From https://rancher.com/products/rancher
```
An Enterprise Platform for Managing Kubernetes Everywhere
Rancher is a platform built to address the needs of the DevOps teams deploying applications with Kubernetes, and the IT staff responsible for delivering an enterprise-critical service.
```
!!! note ""
An Enterprise Platform for Managing Kubernetes Everywhere
Rancher is a platform built to address the needs of the DevOps teams deploying applications with Kubernetes, and the IT staff responsible for delivering an enterprise-critical service.
## Preparation
@ -22,7 +21,7 @@ Create an application in passbook and note the slug, as this will be used later.
- Audience: `https://rancher.company/v1-saml/adfs/saml/metadata`
- Issuer: `passbook`
You can of course use a custom Signing Certificate, and adjust the Assertion Length.
You can of course use a custom Signing Certificate, and adjust durations.
## Rancher

View File

@ -4,13 +4,12 @@
From https://sentry.io
```
Sentry provides self-hosted and cloud-based error monitoring that helps all software
teams discover, triage, and prioritize errors in real-time.
!!! note ""
Sentry provides self-hosted and cloud-based error monitoring that helps all software
teams discover, triage, and prioritize errors in real-time.
One million developers at over fifty thousand companies already ship
better software faster with Sentry. Wont you join them?
```
One million developers at over fifty thousand companies already ship
better software faster with Sentry. Wont you join them?
## Preparation

View File

@ -0,0 +1,74 @@
# Ansible Tower / AWX Integration
## What is Tower
From https://docs.ansible.com/ansible/2.5/reference_appendices/tower.html
!!! note ""
Ansible Tower (formerly AWX) is a web-based solution that makes Ansible even more easy to use for IT teams of all kinds. Its designed to be the hub for all of your automation tasks.
Tower allows you to control access to who can access what, even allowing sharing of SSH credentials without someone being able to transfer those credentials. Inventory can be graphically managed or synced with a wide variety of cloud sources. It logs all of your jobs, integrates well with LDAP, and has an amazing browsable REST API. Command line tools are available for easy integration with Jenkins as well. Provisioning callbacks provide great support for autoscaling topologies.
!!! note
AWX is the Open-Source version of Tower, and AWX will be used interchangeably throughout this document.
## Preparation
The following placeholders will be used:
- `awx.company` is the FQDN of the AWX/Tower Install
- `passbook.company` is the FQDN of the passbook Install
Create an application in passbook and note the slug, as this will be used later. Create a SAML Provider with the following Parameters:
- ACS URL: `https://awx.company/sso/complete/saml/`
- Audience: `awx`
- Issuer: `https://awx.company/sso/metadata/saml/`
You can of course use a custom Signing Certificate, and adjust durations.
## AWX Configuration
Navigate to `https://awx.company/#/settings/auth` to configure SAML. Set the Field `SAML SERVICE PROVIDER ENTITY ID` to `awx`.
For the fields `SAML SERVICE PROVIDER PUBLIC CERTIFICATE` and `SAML SERVICE PROVIDER PRIVATE KEY`, you can either use custom Certificates, or use the self-signed Pair generated by Passbook.
Provide Metadata in the `SAML Service Provider Organization Info` Field:
```json
{
"en-US": {
"name": "passbook",
"url": "https://passbook.company",
"displayname": "passbook"
}
}
```
Provide Metadata in the `SAML Service Provider Technical Contact` and `SAML Service Provider Technical Contact` Fields:
```json
{
"givenName": "Admin Name",
"emailAddress": "admin@company"
}
```
In the `SAML Enabled Identity Providers` paste the following configuration:
```json
{
"passbook": {
"attr_username": "urn:oid:2.16.840.1.113730.3.1.241",
"attr_user_permanent_id": "urn:oid:0.9.2342.19200300.100.1.1",
"x509cert": "MIIDEjCCAfqgAwIBAgIRAJZ9pOZ1g0xjiHtQAAejsMEwDQYJKoZIhvcNAQELBQAwMDEuMCwGA1UEAwwlcGFzc2Jvb2sgU2VsZi1zaWduZWQgU0FNTCBDZXJ0aWZpY2F0ZTAeFw0xOTEyMjYyMDEwNDFaFw0yMDEyMjYyMDEwNDFaMFkxLjAsBgNVBAMMJXBhc3Nib29rIFNlbGYtc2lnbmVkIFNBTUwgQ2VydGlmaWNhdGUxETAPBgNVBAoMCHBhc3Nib29rMRQwEgYDVQQLDAtTZWxmLXNpZ25lZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAO/ktBYZkY9xAijF4acvzX6Q1K8KoIZeyde8fVgcWBz4L5FgDQ4/dni4k2YAcPdwteGL4nKVzetUzjbRCBUNuO6lqU4J4WNNX4Xg4Ir7XLRoAQeo+omTPBdpJ1p02HjtN5jT01umN3bK2yto1e37CJhK6WJiaXqRewPxh4lI4aqdj3BhFkJ3I3r2qxaWOAXQ6X7fg3w/ny7QP53//ouZo7hSLY3GIcRKgvdjjVM3OW5C3WLpOq5Dez5GWVJ17aeFCfGQ8bwFKde6qfYqyGcU9xHB36TtVHB9hSFP/tUFhkiSOxtsrYwCgCyXm4UTSpP+wiNyjKfFw7qGLBvA2hGTNw8CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAh9PeAqPRQk1/SSygIFADZBi08O/DPCshFwEHvJATIcTzcDD8UGAjXh+H5OlkDyX7KyrcaNvYaafCUo63A+WprdtdY5Ty6SBEwTYyiQyQfwM9BfK+imCoif1Ai7xAelD7p9lNazWq7JU+H/Ep7U7Q7LvpxAbK0JArt+IWTb2NcMb3OWE1r0gFbs44O1l6W9UbJTbyLMzbGbe5i+NHlgnwPwuhtRMh0NUYabGHKcHbhwyFhfGAQv2dAp5KF1E5gu6ZzCiFePzc0FrqXQyb2zpFYcJHXquiqaOeG7cZxRHYcjrl10Vxzki64XVA9BpdELgKSnupDGUEJsRUt3WVOmvZuA==",
"url": "https://passbook.company/application/saml/awx/login/",
"attr_last_name": "User.LastName",
"entity_id": "https://awx.company/sso/metadata/saml/",
"attr_email": "urn:oid:0.9.2342.19200300.100.1.3",
"attr_first_name": "urn:oid:2.5.4.3"
}
}
```
`x509cert` is the Certificate configured in passbook. Remove the --BEGIN CERTIFICATE-- and --END CERTIFICATE-- headers, then enter the cert as one non-breaking string.

View File

@ -0,0 +1,21 @@
# Expression Policy
Expression Policies allows you to write custom Policy Logic using Jinja2 Templating language.
For a language reference, see [here](https://jinja.palletsprojects.com/en/2.11.x/templates/).
The following objects are passed into the variable:
- `request`: A PolicyRequest object, which has the following properties:
- `request.user`: The current User, which the Policy is applied against. ([ref](../../property-mappings/reference/user-object.md))
- `request.http_request`: The Django HTTP Request, as documented [here](https://docs.djangoproject.com/en/3.0/ref/request-response/#httprequest-objects).
- `request.obj`: A Django Model instance. This is only set if the Policy is ran against an object.
- `pb_is_sso_flow`: Boolean which is true if request was initiated by authenticating through an external Provider.
- `pb_is_group_member(user, group_name)`: Function which checks if `user` is member of a Group with Name `gorup_name`.
- `pb_logger`: Standard Python Logger Object, which can be used to debug expressions.
- `pb_client_ip`: Client's IP Address.
There are also the following custom filters available:
- `regex_match(regex)`: Return True if value matches `regex`
- `regex_replace(regex, repl)`: Replace string matched by `regex` with `repl`

View File

@ -18,27 +18,9 @@ passbook keeps track of failed login attempts by Source IP and Attempted Usernam
This policy can be used to for example prompt Clients with a low score to pass a Captcha before they can continue.
### Field matcher Policy
## Expression Policy
This policy allows you to evaluate arbitrary comparisons against the User instance. Currently supported fields are:
- Username
- E-Mail
- Name
- Is_active
- Date joined
Any of the following operations are supported:
- Starts with
- Ends with
- Contains
- Regexp (standard Python engine)
- Exact
### SSO Policy
This policy evaluates to True if the current Authentication Flow has been initiated through an external Source, like OAuth and SAML.
See [Expression Policy](expression/index.md).
### Webhook Policy

View File

@ -0,0 +1,20 @@
# Passbook User Object
The User object has the following attributes:
- `username`: User's Username
- `email` User's E-Mail
- `name` User's Display Name
- `is_staff` Boolean field if user is staff
- `is_active` Boolean field if user is active
- `date_joined` Date User joined/was created
- `password_change_date` Date Password was last changed
- `attributes` Dynamic Attributes
## Examples
List all the User's Group Names
```jinja2
[{% for group in user.groups.all() %}'{{ group.name }}',{% endfor %}]
```

View File

@ -13,11 +13,5 @@ The API exposes Username, E-Mail, Name and Groups in a GitHub-compatible format.
## SAML Provider
This provider allows you to integrate Enterprise Software using the SAML2 Protocol. It supports signed Requests. This Provider also has [Property Mappings](property-mappings.md#saml-property-mapping), which allows you to expose Vendor-specific Fields.
Default fields are:
- `eduPersonPrincipalName`: User's E-Mail
- `cn`: User's Full Name
- `mail`: User's E-Mail
- `displayName`: User's Username
- `uid`: User Unique Identifier
This provider allows you to integrate Enterprise Software using the SAML2 Protocol. It supports signed Requests. This Provider uses [Property Mappings](property-mappings/index.md#saml-property-mapping) to determine which fields are exposed and what values they return. This makes it possible to expose Vendor-specific Fields.
Default fields are exposed through Auto-generated Property Mappings, which are prefixed with "Autogenerated..."

View File

@ -36,4 +36,4 @@ This source allows you to import Users and Groups from an LDAP Server
- Object uniqueness field: Field which contains a unique Identifier.
- Sync groups: Enable/disable Group synchronization. Groups are synced in the background every 5 minutes.
- Sync parent group: Optionally set this Group as parent Group for all synced Groups (allows you to, for example, import AD Groups under a root `imported-from-ad` group.)
- Property mappings: Define which LDAP Properties map to which passbook Properties. The default set of Property Mappings is generated for Active Directory. See also [LDAP Property Mappings](property-mappings.md#ldap-property-mapping)
- Property mappings: Define which LDAP Properties map to which passbook Properties. The default set of Property Mappings is generated for Active Directory. See also [LDAP Property Mappings](property-mappings/index.md#ldap-property-mapping)

View File

@ -1,6 +1,6 @@
apiVersion: v1
appVersion: "0.7.13-beta"
appVersion: "0.8.8-beta"
description: A Helm chart for passbook.
name: passbook
version: "0.7.13-beta"
version: "0.8.8-beta"
icon: https://git.beryju.org/uploads/-/system/project/avatar/108/logo.png

View File

@ -25,19 +25,19 @@ spec:
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 8080
containerPort: 80
protocol: TCP
livenessProbe:
initialDelaySeconds: 10
timeoutSeconds: 5
httpGet:
path: /-/ping
path: /
port: http
readinessProbe:
initialDelaySeconds: 10
timeoutSeconds: 5
httpGet:
path: /-/ping
path: /
port: http
resources:
requests:

View File

@ -11,7 +11,7 @@ metadata:
spec:
type: ClusterIP
ports:
- port: 8080
- port: 80
targetPort: http
protocol: TCP
name: http

View File

@ -2,7 +2,7 @@
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
image:
tag: 0.7.13-beta
tag: 0.8.8-beta
nameOverride: ""
@ -42,3 +42,5 @@ redis:
master:
persistence:
enabled: false
# https://stackoverflow.com/a/59189742
disableCommands: []

View File

@ -2,6 +2,9 @@
"""Django manage.py"""
import os
import sys
from defusedxml import defuse_stdlib
defuse_stdlib()
if __name__ == '__main__':
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'passbook.root.settings')

View File

@ -10,15 +10,22 @@ nav:
- Kubernetes: installation/kubernetes.md
- Sources: sources.md
- Providers: providers.md
- Property Mappings: property-mappings.md
- Property Mappings:
- Overview: property-mappings/index.md
- Reference:
- User Object: property-mappings/reference/user-object.md
- Factors: factors.md
- Policies: policies.md
- Policies:
- Overview: policies/index.md
- Expression: policies/expression/index.md
- Integrations:
- as Provider:
- Amazon Web Services: integrations/services/aws/index.md
- GitLab: integrations/services/gitlab/index.md
- Rancher: integrations/services/rancher/index.md
- Harbor: integrations/services/harbor/index.md
- Sentry: integrations/services/sentry/index.md
- Ansible Tower/AWX: integrations/services/tower-awx/index.md
repo_name: "BeryJu.org/passbook"
repo_url: https://github.com/BeryJu/passbook
@ -29,3 +36,4 @@ theme:
markdown_extensions:
- toc:
permalink: "¶"
- admonition

View File

@ -1,2 +1,2 @@
"""passbook"""
__version__ = "0.7.13-beta"
__version__ = "0.8.8-beta"

View File

@ -1,7 +1,4 @@
"""passbook core source form fields"""
# from django import forms
SOURCE_FORM_FIELDS = ["name", "slug", "enabled", "policies"]
SOURCE_SERIALIZER_FIELDS = ["pk", "name", "slug", "enabled", "policies"]
# class SourceForm(forms.Form)
SOURCE_FORM_FIELDS = ["name", "slug", "enabled"]
SOURCE_SERIALIZER_FIELDS = ["pk", "name", "slug", "enabled"]

View File

@ -1,209 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
var noOptions = {};
var nonWS = /[^\s\u00a0]/;
var Pos = CodeMirror.Pos;
function firstNonWS(str) {
var found = str.search(nonWS);
return found == -1 ? 0 : found;
}
CodeMirror.commands.toggleComment = function(cm) {
cm.toggleComment();
};
CodeMirror.defineExtension("toggleComment", function(options) {
if (!options) options = noOptions;
var cm = this;
var minLine = Infinity, ranges = this.listSelections(), mode = null;
for (var i = ranges.length - 1; i >= 0; i--) {
var from = ranges[i].from(), to = ranges[i].to();
if (from.line >= minLine) continue;
if (to.line >= minLine) to = Pos(minLine, 0);
minLine = from.line;
if (mode == null) {
if (cm.uncomment(from, to, options)) mode = "un";
else { cm.lineComment(from, to, options); mode = "line"; }
} else if (mode == "un") {
cm.uncomment(from, to, options);
} else {
cm.lineComment(from, to, options);
}
}
});
// Rough heuristic to try and detect lines that are part of multi-line string
function probablyInsideString(cm, pos, line) {
return /\bstring\b/.test(cm.getTokenTypeAt(Pos(pos.line, 0))) && !/^[\'\"\`]/.test(line)
}
function getMode(cm, pos) {
var mode = cm.getMode()
return mode.useInnerComments === false || !mode.innerMode ? mode : cm.getModeAt(pos)
}
CodeMirror.defineExtension("lineComment", function(from, to, options) {
if (!options) options = noOptions;
var self = this, mode = getMode(self, from);
var firstLine = self.getLine(from.line);
if (firstLine == null || probablyInsideString(self, from, firstLine)) return;
var commentString = options.lineComment || mode.lineComment;
if (!commentString) {
if (options.blockCommentStart || mode.blockCommentStart) {
options.fullLines = true;
self.blockComment(from, to, options);
}
return;
}
var end = Math.min(to.ch != 0 || to.line == from.line ? to.line + 1 : to.line, self.lastLine() + 1);
var pad = options.padding == null ? " " : options.padding;
var blankLines = options.commentBlankLines || from.line == to.line;
self.operation(function() {
if (options.indent) {
var baseString = null;
for (var i = from.line; i < end; ++i) {
var line = self.getLine(i);
var whitespace = line.slice(0, firstNonWS(line));
if (baseString == null || baseString.length > whitespace.length) {
baseString = whitespace;
}
}
for (var i = from.line; i < end; ++i) {
var line = self.getLine(i), cut = baseString.length;
if (!blankLines && !nonWS.test(line)) continue;
if (line.slice(0, cut) != baseString) cut = firstNonWS(line);
self.replaceRange(baseString + commentString + pad, Pos(i, 0), Pos(i, cut));
}
} else {
for (var i = from.line; i < end; ++i) {
if (blankLines || nonWS.test(self.getLine(i)))
self.replaceRange(commentString + pad, Pos(i, 0));
}
}
});
});
CodeMirror.defineExtension("blockComment", function(from, to, options) {
if (!options) options = noOptions;
var self = this, mode = getMode(self, from);
var startString = options.blockCommentStart || mode.blockCommentStart;
var endString = options.blockCommentEnd || mode.blockCommentEnd;
if (!startString || !endString) {
if ((options.lineComment || mode.lineComment) && options.fullLines != false)
self.lineComment(from, to, options);
return;
}
if (/\bcomment\b/.test(self.getTokenTypeAt(Pos(from.line, 0)))) return
var end = Math.min(to.line, self.lastLine());
if (end != from.line && to.ch == 0 && nonWS.test(self.getLine(end))) --end;
var pad = options.padding == null ? " " : options.padding;
if (from.line > end) return;
self.operation(function() {
if (options.fullLines != false) {
var lastLineHasText = nonWS.test(self.getLine(end));
self.replaceRange(pad + endString, Pos(end));
self.replaceRange(startString + pad, Pos(from.line, 0));
var lead = options.blockCommentLead || mode.blockCommentLead;
if (lead != null) for (var i = from.line + 1; i <= end; ++i)
if (i != end || lastLineHasText)
self.replaceRange(lead + pad, Pos(i, 0));
} else {
self.replaceRange(endString, to);
self.replaceRange(startString, from);
}
});
});
CodeMirror.defineExtension("uncomment", function(from, to, options) {
if (!options) options = noOptions;
var self = this, mode = getMode(self, from);
var end = Math.min(to.ch != 0 || to.line == from.line ? to.line : to.line - 1, self.lastLine()), start = Math.min(from.line, end);
// Try finding line comments
var lineString = options.lineComment || mode.lineComment, lines = [];
var pad = options.padding == null ? " " : options.padding, didSomething;
lineComment: {
if (!lineString) break lineComment;
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 && nonWS.test(line)) break lineComment;
if (found > -1 && nonWS.test(line.slice(0, found))) break lineComment;
lines.push(line);
}
self.operation(function() {
for (var i = start; i <= end; ++i) {
var line = lines[i - start];
var pos = line.indexOf(lineString), endPos = pos + lineString.length;
if (pos < 0) continue;
if (line.slice(endPos, endPos + pad.length) == pad) endPos += pad.length;
didSomething = true;
self.replaceRange("", Pos(i, pos), Pos(i, endPos));
}
});
if (didSomething) return true;
}
// Try block comments
var startString = options.blockCommentStart || mode.blockCommentStart;
var endString = options.blockCommentEnd || mode.blockCommentEnd;
if (!startString || !endString) return false;
var lead = options.blockCommentLead || mode.blockCommentLead;
var startLine = self.getLine(start), open = startLine.indexOf(startString)
if (open == -1) return false
var endLine = end == start ? startLine : self.getLine(end)
var close = endLine.indexOf(endString, end == start ? open + startString.length : 0);
var insideStart = Pos(start, open + 1), insideEnd = Pos(end, close + 1)
if (close == -1 ||
!/comment/.test(self.getTokenTypeAt(insideStart)) ||
!/comment/.test(self.getTokenTypeAt(insideEnd)) ||
self.getRange(insideStart, insideEnd, "\n").indexOf(endString) > -1)
return false;
// Avoid killing block comments completely outside the selection.
// Positions of the last startString before the start of the selection, and the first endString after it.
var lastStart = startLine.lastIndexOf(startString, from.ch);
var firstEnd = lastStart == -1 ? -1 : startLine.slice(0, from.ch).indexOf(endString, lastStart + startString.length);
if (lastStart != -1 && firstEnd != -1 && firstEnd + endString.length != from.ch) return false;
// Positions of the first endString after the end of the selection, and the last startString before it.
firstEnd = endLine.indexOf(endString, to.ch);
var almostLastStart = endLine.slice(to.ch).lastIndexOf(startString, firstEnd - to.ch);
lastStart = (firstEnd == -1 || almostLastStart == -1) ? -1 : to.ch + almostLastStart;
if (firstEnd != -1 && lastStart != -1 && lastStart != to.ch) return false;
self.operation(function() {
self.replaceRange("", Pos(end, close - (pad && endLine.slice(close - pad.length, close) == pad ? pad.length : 0)),
Pos(end, close + endString.length));
var openEnd = open + startString.length;
if (pad && startLine.slice(openEnd, openEnd + pad.length) == pad) openEnd += pad.length;
self.replaceRange("", Pos(start, open), Pos(start, openEnd));
if (lead) for (var i = start + 1; i <= end; ++i) {
var line = self.getLine(i), found = line.indexOf(lead);
if (found == -1 || nonWS.test(line.slice(0, found))) continue;
var foundEnd = found + lead.length;
if (pad && line.slice(foundEnd, foundEnd + pad.length) == pad) foundEnd += pad.length;
self.replaceRange("", Pos(i, found), Pos(i, foundEnd));
}
});
return true;
});
});

View File

@ -1,78 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
function continueComment(cm) {
if (cm.getOption("disableInput")) return CodeMirror.Pass;
var ranges = cm.listSelections(), mode, inserts = [];
for (var i = 0; i < ranges.length; i++) {
var pos = ranges[i].head
if (!/\bcomment\b/.test(cm.getTokenTypeAt(pos))) return CodeMirror.Pass;
var modeHere = cm.getModeAt(pos)
if (!mode) mode = modeHere;
else if (mode != modeHere) return CodeMirror.Pass;
var insert = null;
if (mode.blockCommentStart && mode.blockCommentContinue) {
var line = cm.getLine(pos.line).slice(0, pos.ch)
var end = line.lastIndexOf(mode.blockCommentEnd), found
if (end != -1 && end == pos.ch - mode.blockCommentEnd.length) {
// Comment ended, don't continue it
} else if ((found = line.lastIndexOf(mode.blockCommentStart)) > -1 && found > end) {
insert = line.slice(0, found)
if (/\S/.test(insert)) {
insert = ""
for (var j = 0; j < found; ++j) insert += " "
}
} else if ((found = line.indexOf(mode.blockCommentContinue)) > -1 && !/\S/.test(line.slice(0, found))) {
insert = line.slice(0, found)
}
if (insert != null) insert += mode.blockCommentContinue
}
if (insert == null && mode.lineComment && continueLineCommentEnabled(cm)) {
var line = cm.getLine(pos.line), found = line.indexOf(mode.lineComment);
if (found > -1) {
insert = line.slice(0, found);
if (/\S/.test(insert)) insert = null;
else insert += mode.lineComment + line.slice(found + mode.lineComment.length).match(/^\s*/)[0];
}
}
if (insert == null) return CodeMirror.Pass;
inserts[i] = "\n" + insert;
}
cm.operation(function() {
for (var i = ranges.length - 1; i >= 0; i--)
cm.replaceRange(inserts[i], ranges[i].from(), ranges[i].to(), "+insert");
});
}
function continueLineCommentEnabled(cm) {
var opt = cm.getOption("continueComments");
if (opt && typeof opt == "object")
return opt.continueLineComment !== false;
return true;
}
CodeMirror.defineOption("continueComments", null, function(cm, val, prev) {
if (prev && prev != CodeMirror.Init)
cm.removeKeyMap("continueComment");
if (val) {
var key = "Enter";
if (typeof val == "string")
key = val;
else if (typeof val == "object" && val.key)
key = val.key;
var map = {name: "continueComment"};
map[key] = continueComment;
cm.addKeyMap(map);
}
});
});

View File

@ -1,32 +0,0 @@
.CodeMirror-dialog {
position: absolute;
left: 0; right: 0;
background: inherit;
z-index: 15;
padding: .1em .8em;
overflow: hidden;
color: inherit;
}
.CodeMirror-dialog-top {
border-bottom: 1px solid #eee;
top: 0;
}
.CodeMirror-dialog-bottom {
border-top: 1px solid #eee;
bottom: 0;
}
.CodeMirror-dialog input {
border: none;
outline: none;
background: transparent;
width: 20em;
color: inherit;
font-family: monospace;
}
.CodeMirror-dialog button {
font-size: 70%;
}

View File

@ -1,161 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
// Open simple dialogs on top of an editor. Relies on dialog.css.
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
function dialogDiv(cm, template, bottom) {
var wrap = cm.getWrapperElement();
var dialog;
dialog = wrap.appendChild(document.createElement("div"));
if (bottom)
dialog.className = "CodeMirror-dialog CodeMirror-dialog-bottom";
else
dialog.className = "CodeMirror-dialog CodeMirror-dialog-top";
if (typeof template == "string") {
dialog.innerHTML = template;
} else { // Assuming it's a detached DOM element.
dialog.appendChild(template);
}
CodeMirror.addClass(wrap, 'dialog-opened');
return dialog;
}
function closeNotification(cm, newVal) {
if (cm.state.currentNotificationClose)
cm.state.currentNotificationClose();
cm.state.currentNotificationClose = newVal;
}
CodeMirror.defineExtension("openDialog", function(template, callback, options) {
if (!options) options = {};
closeNotification(this, null);
var dialog = dialogDiv(this, template, options.bottom);
var closed = false, me = this;
function close(newVal) {
if (typeof newVal == 'string') {
inp.value = newVal;
} else {
if (closed) return;
closed = true;
CodeMirror.rmClass(dialog.parentNode, 'dialog-opened');
dialog.parentNode.removeChild(dialog);
me.focus();
if (options.onClose) options.onClose(dialog);
}
}
var inp = dialog.getElementsByTagName("input")[0], button;
if (inp) {
inp.focus();
if (options.value) {
inp.value = options.value;
if (options.selectValueOnOpen !== false) {
inp.select();
}
}
if (options.onInput)
CodeMirror.on(inp, "input", function(e) { options.onInput(e, inp.value, close);});
if (options.onKeyUp)
CodeMirror.on(inp, "keyup", function(e) {options.onKeyUp(e, inp.value, close);});
CodeMirror.on(inp, "keydown", function(e) {
if (options && options.onKeyDown && options.onKeyDown(e, inp.value, close)) { return; }
if (e.keyCode == 27 || (options.closeOnEnter !== false && e.keyCode == 13)) {
inp.blur();
CodeMirror.e_stop(e);
close();
}
if (e.keyCode == 13) callback(inp.value, e);
});
if (options.closeOnBlur !== false) CodeMirror.on(inp, "blur", close);
} else if (button = dialog.getElementsByTagName("button")[0]) {
CodeMirror.on(button, "click", function() {
close();
me.focus();
});
if (options.closeOnBlur !== false) CodeMirror.on(button, "blur", close);
button.focus();
}
return close;
});
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;
function close() {
if (closed) return;
closed = true;
CodeMirror.rmClass(dialog.parentNode, 'dialog-opened');
dialog.parentNode.removeChild(dialog);
me.focus();
}
buttons[0].focus();
for (var i = 0; i < buttons.length; ++i) {
var b = buttons[i];
(function(callback) {
CodeMirror.on(b, "click", function(e) {
CodeMirror.e_preventDefault(e);
close();
if (callback) callback(me);
});
})(callbacks[i]);
CodeMirror.on(b, "blur", function() {
--blurring;
setTimeout(function() { if (blurring <= 0) close(); }, 200);
});
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 closed = false, doneTimer;
var duration = options && typeof options.duration !== "undefined" ? options.duration : 5000;
function close() {
if (closed) return;
closed = true;
clearTimeout(doneTimer);
CodeMirror.rmClass(dialog.parentNode, 'dialog-opened');
dialog.parentNode.removeChild(dialog);
}
CodeMirror.on(dialog, 'click', function(e) {
CodeMirror.e_preventDefault(e);
close();
});
if (duration)
doneTimer = setTimeout(close, duration);
return close;
});
});

View File

@ -1,47 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"))
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod)
else // Plain browser env
mod(CodeMirror)
})(function(CodeMirror) {
"use strict"
CodeMirror.defineOption("autoRefresh", false, function(cm, val) {
if (cm.state.autoRefresh) {
stopListening(cm, cm.state.autoRefresh)
cm.state.autoRefresh = null
}
if (val && cm.display.wrapper.offsetHeight == 0)
startListening(cm, cm.state.autoRefresh = {delay: val.delay || 250})
})
function startListening(cm, state) {
function check() {
if (cm.display.wrapper.offsetHeight) {
stopListening(cm, state)
if (cm.display.lastWrapHeight != cm.display.wrapper.clientHeight)
cm.refresh()
} else {
state.timeout = setTimeout(check, state.delay)
}
}
state.timeout = setTimeout(check, state.delay)
state.hurry = function() {
clearTimeout(state.timeout)
state.timeout = setTimeout(check, 50)
}
CodeMirror.on(window, "mouseup", state.hurry)
CodeMirror.on(window, "keyup", state.hurry)
}
function stopListening(_cm, state) {
clearTimeout(state.timeout)
CodeMirror.off(window, "mouseup", state.hurry)
CodeMirror.off(window, "keyup", state.hurry)
}
});

View File

@ -1,6 +0,0 @@
.CodeMirror-fullscreen {
position: fixed;
top: 0; left: 0; right: 0; bottom: 0;
height: auto;
z-index: 9;
}

View File

@ -1,41 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.defineOption("fullScreen", false, function(cm, val, old) {
if (old == CodeMirror.Init) old = false;
if (!old == !val) return;
if (val) setFullscreen(cm);
else setNormal(cm);
});
function setFullscreen(cm) {
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 = "auto";
wrap.className += " CodeMirror-fullscreen";
document.documentElement.style.overflow = "hidden";
cm.refresh();
}
function setNormal(cm) {
var wrap = cm.getWrapperElement();
wrap.className = wrap.className.replace(/\s*CodeMirror-fullscreen\b/, "");
document.documentElement.style.overflow = "";
var info = cm.state.fullScreenRestore;
wrap.style.width = info.width; wrap.style.height = info.height;
window.scrollTo(info.scrollLeft, info.scrollTop);
cm.refresh();
}
});

View File

@ -1,127 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
CodeMirror.defineExtension("addPanel", function(node, options) {
options = options || {};
if (!this.state.panels) initPanels(this);
var info = this.state.panels;
var wrapper = info.wrapper;
var cmWrapper = this.getWrapperElement();
var replace = options.replace instanceof Panel && !options.replace.cleared;
if (options.after instanceof Panel && !options.after.cleared) {
wrapper.insertBefore(node, options.before.node.nextSibling);
} else if (options.before instanceof Panel && !options.before.cleared) {
wrapper.insertBefore(node, options.before.node);
} else if (replace) {
wrapper.insertBefore(node, options.replace.node);
info.panels++;
options.replace.clear();
} else if (options.position == "bottom") {
wrapper.appendChild(node);
} else if (options.position == "before-bottom") {
wrapper.insertBefore(node, cmWrapper.nextSibling);
} else if (options.position == "after-top") {
wrapper.insertBefore(node, cmWrapper);
} else {
wrapper.insertBefore(node, wrapper.firstChild);
}
var height = (options && options.height) || node.offsetHeight;
this._setSize(null, info.heightLeft -= height);
if (!replace) {
info.panels++;
}
if (options.stable && isAtTop(this, node))
this.scrollTo(null, this.getScrollInfo().top + height)
return new Panel(this, node, options, height);
});
function Panel(cm, node, options, height) {
this.cm = cm;
this.node = node;
this.options = options;
this.height = height;
this.cleared = false;
}
Panel.prototype.clear = function() {
if (this.cleared) return;
this.cleared = true;
var info = this.cm.state.panels;
this.cm._setSize(null, info.heightLeft += this.height);
if (this.options.stable && isAtTop(this.cm, this.node))
this.cm.scrollTo(null, this.cm.getScrollInfo().top - this.height)
info.wrapper.removeChild(this.node);
if (--info.panels == 0) removePanels(this.cm);
};
Panel.prototype.changed = function(height) {
var newHeight = height == null ? this.node.offsetHeight : height;
var info = this.cm.state.panels;
this.cm._setSize(null, info.heightLeft -= (newHeight - this.height));
this.height = newHeight;
};
function initPanels(cm) {
var wrap = cm.getWrapperElement();
var style = window.getComputedStyle ? window.getComputedStyle(wrap) : wrap.currentStyle;
var height = parseInt(style.height);
var info = cm.state.panels = {
setHeight: wrap.style.height,
heightLeft: height,
panels: 0,
wrapper: document.createElement("div")
};
wrap.parentNode.insertBefore(info.wrapper, wrap);
var hasFocus = cm.hasFocus();
info.wrapper.appendChild(wrap);
if (hasFocus) cm.focus();
cm._setSize = cm.setSize;
if (height != null) cm.setSize = function(width, newHeight) {
if (newHeight == null) return this._setSize(width, newHeight);
info.setHeight = newHeight;
if (typeof newHeight != "number") {
var px = /^(\d+\.?\d*)px$/.exec(newHeight);
if (px) {
newHeight = Number(px[1]);
} else {
info.wrapper.style.height = newHeight;
newHeight = info.wrapper.offsetHeight;
info.wrapper.style.height = "";
}
}
cm._setSize(width, info.heightLeft += (newHeight - height));
height = newHeight;
};
}
function removePanels(cm) {
var info = cm.state.panels;
cm.state.panels = null;
var wrap = cm.getWrapperElement();
info.wrapper.parentNode.replaceChild(wrap, info.wrapper);
wrap.style.height = info.setHeight;
cm.setSize = cm._setSize;
cm.setSize();
}
function isAtTop(cm, dom) {
for (var sibling = dom.nextSibling; sibling; sibling = sibling.nextSibling)
if (sibling == cm.getWrapperElement()) return true
return false
}
});

View File

@ -1,63 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
CodeMirror.defineOption("placeholder", "", function(cm, val, old) {
var prev = old && old != CodeMirror.Init;
if (val && !prev) {
cm.on("blur", onBlur);
cm.on("change", onChange);
cm.on("swapDoc", onChange);
onChange(cm);
} else if (!val && prev) {
cm.off("blur", onBlur);
cm.off("change", onChange);
cm.off("swapDoc", onChange);
clearPlaceholder(cm);
var wrapper = cm.getWrapperElement();
wrapper.className = wrapper.className.replace(" CodeMirror-empty", "");
}
if (val && !cm.hasFocus()) onBlur(cm);
});
function clearPlaceholder(cm) {
if (cm.state.placeholder) {
cm.state.placeholder.parentNode.removeChild(cm.state.placeholder);
cm.state.placeholder = null;
}
}
function setPlaceholder(cm) {
clearPlaceholder(cm);
var elt = cm.state.placeholder = document.createElement("pre");
elt.style.cssText = "height: 0; overflow: visible";
elt.style.direction = cm.getOption("direction");
elt.className = "CodeMirror-placeholder CodeMirror-line-like";
var placeHolder = cm.getOption("placeholder")
if (typeof placeHolder == "string") placeHolder = document.createTextNode(placeHolder)
elt.appendChild(placeHolder)
cm.display.lineSpace.insertBefore(elt, cm.display.lineSpace.firstChild);
}
function onBlur(cm) {
if (isEmpty(cm)) setPlaceholder(cm);
}
function onChange(cm) {
var wrapper = cm.getWrapperElement(), empty = isEmpty(cm);
wrapper.className = wrapper.className.replace(" CodeMirror-empty", "") + (empty ? " CodeMirror-empty" : "");
if (empty) setPlaceholder(cm);
else clearPlaceholder(cm);
}
function isEmpty(cm) {
return (cm.lineCount() === 1) && (cm.getLine(0) === "");
}
});

View File

@ -1,51 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.defineOption("rulers", false, function(cm, val) {
if (cm.state.rulerDiv) {
cm.state.rulerDiv.parentElement.removeChild(cm.state.rulerDiv)
cm.state.rulerDiv = null
cm.off("refresh", drawRulers)
}
if (val && val.length) {
cm.state.rulerDiv = cm.display.lineSpace.parentElement.insertBefore(document.createElement("div"), cm.display.lineSpace)
cm.state.rulerDiv.className = "CodeMirror-rulers"
drawRulers(cm)
cm.on("refresh", drawRulers)
}
});
function drawRulers(cm) {
cm.state.rulerDiv.textContent = ""
var val = cm.getOption("rulers");
var cw = cm.defaultCharWidth();
var left = cm.charCoords(CodeMirror.Pos(cm.firstLine(), 0), "div").left;
cm.state.rulerDiv.style.minHeight = (cm.display.scroller.offsetHeight + 30) + "px";
for (var i = 0; i < val.length; i++) {
var elt = document.createElement("div");
elt.className = "CodeMirror-ruler";
var col, conf = val[i];
if (typeof conf == "number") {
col = conf;
} else {
col = conf.column;
if (conf.className) elt.className += " " + conf.className;
if (conf.color) elt.style.borderColor = conf.color;
if (conf.lineStyle) elt.style.borderLeftStyle = conf.lineStyle;
if (conf.width) elt.style.borderLeftWidth = conf.width;
}
elt.style.left = (left + col * cw) + "px";
cm.state.rulerDiv.appendChild(elt)
}
}
});

View File

@ -1,191 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
var defaults = {
pairs: "()[]{}''\"\"",
closeBefore: ")]}'\":;>",
triples: "",
explode: "[]{}"
};
var Pos = CodeMirror.Pos;
CodeMirror.defineOption("autoCloseBrackets", false, function(cm, val, old) {
if (old && old != CodeMirror.Init) {
cm.removeKeyMap(keyMap);
cm.state.closeBrackets = null;
}
if (val) {
ensureBound(getOption(val, "pairs"))
cm.state.closeBrackets = val;
cm.addKeyMap(keyMap);
}
});
function getOption(conf, name) {
if (name == "pairs" && typeof conf == "string") return conf;
if (typeof conf == "object" && conf[name] != null) return conf[name];
return defaults[name];
}
var keyMap = {Backspace: handleBackspace, Enter: handleEnter};
function ensureBound(chars) {
for (var i = 0; i < chars.length; i++) {
var ch = chars.charAt(i), key = "'" + ch + "'"
if (!keyMap[key]) keyMap[key] = handler(ch)
}
}
ensureBound(defaults.pairs + "`")
function handler(ch) {
return function(cm) { return handleChar(cm, ch); };
}
function getConfig(cm) {
var deflt = cm.state.closeBrackets;
if (!deflt || deflt.override) return deflt;
var mode = cm.getModeAt(cm.getCursor());
return mode.closeBrackets || deflt;
}
function handleBackspace(cm) {
var conf = getConfig(cm);
if (!conf || cm.getOption("disableInput")) return CodeMirror.Pass;
var pairs = getOption(conf, "pairs");
var ranges = cm.listSelections();
for (var i = 0; i < ranges.length; i++) {
if (!ranges[i].empty()) return CodeMirror.Pass;
var around = charsAround(cm, ranges[i].head);
if (!around || pairs.indexOf(around) % 2 != 0) return CodeMirror.Pass;
}
for (var i = ranges.length - 1; i >= 0; i--) {
var cur = ranges[i].head;
cm.replaceRange("", Pos(cur.line, cur.ch - 1), Pos(cur.line, cur.ch + 1), "+delete");
}
}
function handleEnter(cm) {
var conf = getConfig(cm);
var explode = conf && getOption(conf, "explode");
if (!explode || cm.getOption("disableInput")) return CodeMirror.Pass;
var ranges = cm.listSelections();
for (var i = 0; i < ranges.length; i++) {
if (!ranges[i].empty()) return CodeMirror.Pass;
var around = charsAround(cm, ranges[i].head);
if (!around || explode.indexOf(around) % 2 != 0) return CodeMirror.Pass;
}
cm.operation(function() {
var linesep = cm.lineSeparator() || "\n";
cm.replaceSelection(linesep + linesep, null);
cm.execCommand("goCharLeft");
ranges = cm.listSelections();
for (var i = 0; i < ranges.length; i++) {
var line = ranges[i].head.line;
cm.indentLine(line, null, true);
cm.indentLine(line + 1, null, true);
}
});
}
function contractSelection(sel) {
var inverted = CodeMirror.cmpPos(sel.anchor, sel.head) > 0;
return {anchor: new Pos(sel.anchor.line, sel.anchor.ch + (inverted ? -1 : 1)),
head: new Pos(sel.head.line, sel.head.ch + (inverted ? 1 : -1))};
}
function handleChar(cm, ch) {
var conf = getConfig(cm);
if (!conf || cm.getOption("disableInput")) return CodeMirror.Pass;
var pairs = getOption(conf, "pairs");
var pos = pairs.indexOf(ch);
if (pos == -1) return CodeMirror.Pass;
var closeBefore = getOption(conf,"closeBefore");
var triples = getOption(conf, "triples");
var identical = pairs.charAt(pos + 1) == ch;
var ranges = cm.listSelections();
var opening = pos % 2 == 0;
var type;
for (var i = 0; i < ranges.length; i++) {
var range = ranges[i], cur = range.head, curType;
var next = cm.getRange(cur, Pos(cur.line, cur.ch + 1));
if (opening && !range.empty()) {
curType = "surround";
} else if ((identical || !opening) && next == ch) {
if (identical && stringStartsAfter(cm, cur))
curType = "both";
else if (triples.indexOf(ch) >= 0 && cm.getRange(cur, Pos(cur.line, cur.ch + 3)) == ch + ch + ch)
curType = "skipThree";
else
curType = "skip";
} else if (identical && cur.ch > 1 && triples.indexOf(ch) >= 0 &&
cm.getRange(Pos(cur.line, cur.ch - 2), cur) == ch + ch) {
if (cur.ch > 2 && /\bstring/.test(cm.getTokenTypeAt(Pos(cur.line, cur.ch - 2)))) return CodeMirror.Pass;
curType = "addFour";
} else if (identical) {
var prev = cur.ch == 0 ? " " : cm.getRange(Pos(cur.line, cur.ch - 1), cur)
if (!CodeMirror.isWordChar(next) && prev != ch && !CodeMirror.isWordChar(prev)) curType = "both";
else return CodeMirror.Pass;
} else if (opening && (next.length === 0 || /\s/.test(next) || closeBefore.indexOf(next) > -1)) {
curType = "both";
} else {
return CodeMirror.Pass;
}
if (!type) type = curType;
else if (type != curType) return CodeMirror.Pass;
}
var left = pos % 2 ? pairs.charAt(pos - 1) : ch;
var right = pos % 2 ? ch : pairs.charAt(pos + 1);
cm.operation(function() {
if (type == "skip") {
cm.execCommand("goCharRight");
} else if (type == "skipThree") {
for (var i = 0; i < 3; i++)
cm.execCommand("goCharRight");
} else if (type == "surround") {
var sels = cm.getSelections();
for (var i = 0; i < sels.length; i++)
sels[i] = left + sels[i] + right;
cm.replaceSelections(sels, "around");
sels = cm.listSelections().slice();
for (var i = 0; i < sels.length; i++)
sels[i] = contractSelection(sels[i]);
cm.setSelections(sels);
} else if (type == "both") {
cm.replaceSelection(left + right, null);
cm.triggerElectric(left + right);
cm.execCommand("goCharLeft");
} else if (type == "addFour") {
cm.replaceSelection(left + left + left + left, "before");
cm.execCommand("goCharRight");
}
});
}
function charsAround(cm, pos) {
var str = cm.getRange(Pos(pos.line, pos.ch - 1),
Pos(pos.line, pos.ch + 1));
return str.length == 2 ? str : null;
}
function stringStartsAfter(cm, pos) {
var token = cm.getTokenAt(Pos(pos.line, pos.ch + 1))
return /\bstring/.test(token.type) && token.start == pos.ch &&
(pos.ch == 0 || !/\bstring/.test(cm.getTokenTypeAt(pos)))
}
});

View File

@ -1,184 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
/**
* Tag-closer extension for CodeMirror.
*
* This extension adds an "autoCloseTags" option that can be set to
* either true to get the default behavior, or an object to further
* configure its behavior.
*
* These are supported options:
*
* `whenClosing` (default true)
* Whether to autoclose when the '/' of a closing tag is typed.
* `whenOpening` (default true)
* Whether to autoclose the tag when the final '>' of an opening
* tag is typed.
* `dontCloseTags` (default is empty tags for HTML, none for XML)
* An array of tag names that should not be autoclosed.
* `indentTags` (default is block tags for HTML, none for XML)
* An array of tag names that should, when opened, cause a
* blank line to be added inside the tag, and the blank line and
* closing line to be indented.
* `emptyTags` (default is none)
* An array of XML tag names that should be autoclosed with '/>'.
*
* See demos/closetag.html for a usage example.
*/
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("../fold/xml-fold"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "../fold/xml-fold"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
CodeMirror.defineOption("autoCloseTags", false, function(cm, val, 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",
"source", "track", "wbr"];
var htmlIndent = ["applet", "blockquote", "body", "button", "div", "dl", "fieldset", "form", "frameset", "h1", "h2", "h3", "h4",
"h5", "h6", "head", "html", "iframe", "layer", "legend", "object", "ol", "p", "select", "table", "ul"];
function autoCloseGT(cm) {
if (cm.getOption("disableInput")) return CodeMirror.Pass;
var ranges = cm.listSelections(), replacements = [];
var opt = cm.getOption("autoCloseTags");
for (var i = 0; i < ranges.length; i++) {
if (!ranges[i].empty()) return CodeMirror.Pass;
var pos = ranges[i].head, tok = cm.getTokenAt(pos);
var inner = CodeMirror.innerMode(cm.getMode(), tok.state), state = inner.state;
var tagInfo = inner.mode.xmlCurrentTag && inner.mode.xmlCurrentTag(state)
var tagName = tagInfo && tagInfo.name
if (!tagName) return CodeMirror.Pass
var html = inner.mode.configuration == "html";
var dontCloseTags = (typeof opt == "object" && opt.dontCloseTags) || (html && htmlDontClose);
var indentTags = (typeof opt == "object" && opt.indentTags) || (html && htmlIndent);
if (tok.end > pos.ch) tagName = tagName.slice(0, tagName.length - tok.end + pos.ch);
var lowerTagName = tagName.toLowerCase();
// Don't process the '>' at the end of an end-tag or self-closing tag
if (!tagName ||
tok.type == "string" && (tok.end != pos.ch || !/[\"\']/.test(tok.string.charAt(tok.string.length - 1)) || tok.string.length == 1) ||
tok.type == "tag" && tagInfo.close ||
tok.string.indexOf("/") == (tok.string.length - 1) || // match something like <someTagName />
dontCloseTags && indexOf(dontCloseTags, lowerTagName) > -1 ||
closingTagExists(cm, inner.mode.xmlCurrentContext && inner.mode.xmlCurrentContext(state) || [], tagName, pos, true))
return CodeMirror.Pass;
var emptyTags = typeof opt == "object" && opt.emptyTags;
if (emptyTags && indexOf(emptyTags, tagName) > -1) {
replacements[i] = { text: "/>", newPos: CodeMirror.Pos(pos.line, pos.ch + 2) };
continue;
}
var indent = indentTags && indexOf(indentTags, lowerTagName) > -1;
replacements[i] = {indent: indent,
text: ">" + (indent ? "\n\n" : "") + "</" + tagName + ">",
newPos: indent ? CodeMirror.Pos(pos.line + 1, 0) : CodeMirror.Pos(pos.line, pos.ch + 1)};
}
var dontIndentOnAutoClose = (typeof opt == "object" && opt.dontIndentOnAutoClose);
for (var i = ranges.length - 1; i >= 0; i--) {
var info = replacements[i];
cm.replaceRange(info.text, ranges[i].head, ranges[i].anchor, "+insert");
var sel = cm.listSelections().slice(0);
sel[i] = {head: info.newPos, anchor: info.newPos};
cm.setSelections(sel);
if (!dontIndentOnAutoClose && info.indent) {
cm.indentLine(info.newPos.line, null, true);
cm.indentLine(info.newPos.line + 1, null, true);
}
}
}
function autoCloseCurrent(cm, typingSlash) {
var ranges = cm.listSelections(), replacements = [];
var head = typingSlash ? "/" : "</";
var opt = cm.getOption("autoCloseTags");
var dontIndentOnAutoClose = (typeof opt == "object" && opt.dontIndentOnSlash);
for (var i = 0; i < ranges.length; i++) {
if (!ranges[i].empty()) return CodeMirror.Pass;
var pos = ranges[i].head, tok = cm.getTokenAt(pos);
var inner = CodeMirror.innerMode(cm.getMode(), tok.state), state = inner.state;
if (typingSlash && (tok.type == "string" || tok.string.charAt(0) != "<" ||
tok.start != pos.ch - 1))
return CodeMirror.Pass;
// Kludge to get around the fact that we are not in XML mode
// when completing in JS/CSS snippet in htmlmixed mode. Does not
// work for other XML embedded languages (there is no general
// way to go from a mixed mode to its current XML state).
var replacement, mixed = inner.mode.name != "xml" && cm.getMode().name == "htmlmixed"
if (mixed && inner.mode.name == "javascript") {
replacement = head + "script";
} else if (mixed && inner.mode.name == "css") {
replacement = head + "style";
} else {
var context = inner.mode.xmlCurrentContext && inner.mode.xmlCurrentContext(state)
if (!context || (context.length && closingTagExists(cm, context, context[context.length - 1], pos)))
return CodeMirror.Pass;
replacement = head + context[context.length - 1]
}
if (cm.getLine(pos.line).charAt(tok.end) != ">") replacement += ">";
replacements[i] = replacement;
}
cm.replaceSelections(replacements);
ranges = cm.listSelections();
if (!dontIndentOnAutoClose) {
for (var i = 0; i < ranges.length; i++)
if (i == ranges.length - 1 || ranges[i].head.line < ranges[i + 1].head.line)
cm.indentLine(ranges[i].head.line);
}
}
function autoCloseSlash(cm) {
if (cm.getOption("disableInput")) return CodeMirror.Pass;
return autoCloseCurrent(cm, true);
}
CodeMirror.commands.closeTag = function(cm) { return autoCloseCurrent(cm); };
function indexOf(collection, elt) {
if (collection.indexOf) return collection.indexOf(elt);
for (var i = 0, e = collection.length; i < e; ++i)
if (collection[i] == elt) return i;
return -1;
}
// If xml-fold is loaded, we use its functionality to try and verify
// whether a given tag is actually unclosed.
function closingTagExists(cm, context, tagName, pos, newTag) {
if (!CodeMirror.scanForClosingTag) return false;
var end = Math.min(cm.lastLine() + 1, pos.line + 500);
var nextClose = CodeMirror.scanForClosingTag(cm, pos, null, end);
if (!nextClose || nextClose.tag != tagName) return false;
// If the immediate wrapping context contains onCx instances of
// the same tag, a closing tag only exists if there are at least
// that many closing tags of that type following.
var onCx = newTag ? 1 : 0
for (var i = context.length - 1; i >= 0; i--) {
if (context[i] == tagName) ++onCx
else break
}
pos = nextClose.to;
for (var i = 1; i < onCx; i++) {
var next = CodeMirror.scanForClosingTag(cm, pos, null, end);
if (!next || next.tag != tagName) return false;
pos = next.to;
}
return true;
}
});

View File

@ -1,99 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
var listRE = /^(\s*)(>[> ]*|[*+-] \[[x ]\]\s|[*+-]\s|(\d+)([.)]))(\s*)/,
emptyListRE = /^(\s*)(>[> ]*|[*+-] \[[x ]\]|[*+-]|(\d+)[.)])(\s*)$/,
unorderedListRE = /[*+-]\s/;
CodeMirror.commands.newlineAndIndentContinueMarkdownList = function(cm) {
if (cm.getOption("disableInput")) return CodeMirror.Pass;
var ranges = cm.listSelections(), replacements = [];
for (var i = 0; i < ranges.length; i++) {
var pos = ranges[i].head;
// If we're not in Markdown mode, fall back to normal newlineAndIndent
var eolState = cm.getStateAfter(pos.line);
var inner = CodeMirror.innerMode(cm.getMode(), eolState);
if (inner.mode.name !== "markdown") {
cm.execCommand("newlineAndIndent");
return;
} else {
eolState = inner.state;
}
var inList = eolState.list !== false;
var inQuote = eolState.quote !== 0;
var line = cm.getLine(pos.line), match = listRE.exec(line);
var cursorBeforeBullet = /^\s*$/.test(line.slice(0, pos.ch));
if (!ranges[i].empty() || (!inList && !inQuote) || !match || cursorBeforeBullet) {
cm.execCommand("newlineAndIndent");
return;
}
if (emptyListRE.test(line)) {
if (!/>\s*$/.test(line)) cm.replaceRange("", {
line: pos.line, ch: 0
}, {
line: pos.line, ch: pos.ch + 1
});
replacements[i] = "\n";
} else {
var indent = match[1], after = match[5];
var numbered = !(unorderedListRE.test(match[2]) || match[2].indexOf(">") >= 0);
var bullet = numbered ? (parseInt(match[3], 10) + 1) + match[4] : match[2].replace("x", " ");
replacements[i] = "\n" + indent + bullet + after;
if (numbered) incrementRemainingMarkdownListNumbers(cm, pos);
}
}
cm.replaceSelections(replacements);
};
// Auto-updating Markdown list numbers when a new item is added to the
// middle of a list
function incrementRemainingMarkdownListNumbers(cm, pos) {
var startLine = pos.line, lookAhead = 0, skipCount = 0;
var startItem = listRE.exec(cm.getLine(startLine)), startIndent = startItem[1];
do {
lookAhead += 1;
var nextLineNumber = startLine + lookAhead;
var nextLine = cm.getLine(nextLineNumber), nextItem = listRE.exec(nextLine);
if (nextItem) {
var nextIndent = nextItem[1];
var newNumber = (parseInt(startItem[3], 10) + lookAhead - skipCount);
var nextNumber = (parseInt(nextItem[3], 10)), itemNumber = nextNumber;
if (startIndent === nextIndent && !isNaN(nextNumber)) {
if (newNumber === nextNumber) itemNumber = nextNumber + 1;
if (newNumber > nextNumber) itemNumber = newNumber + 1;
cm.replaceRange(
nextLine.replace(listRE, nextIndent + itemNumber + nextItem[4] + nextItem[5]),
{
line: nextLineNumber, ch: 0
}, {
line: nextLineNumber, ch: nextLine.length
});
} else {
if (startIndent.length > nextIndent.length) return;
// This doesn't run if the next line immediatley indents, as it is
// not clear of the users intention (new indented item or same level)
if ((startIndent.length < nextIndent.length) && (lookAhead === 1)) return;
skipCount += 1;
}
}
} while (nextItem);
}
});

View File

@ -1,150 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
var ie_lt8 = /MSIE \d/.test(navigator.userAgent) &&
(document.documentMode == null || document.documentMode < 8);
var Pos = CodeMirror.Pos;
var matching = {"(": ")>", ")": "(<", "[": "]>", "]": "[<", "{": "}>", "}": "{<", "<": ">>", ">": "<<"};
function bracketRegex(config) {
return config && config.bracketRegex || /[(){}[\]]/
}
function findMatchingBracket(cm, where, config) {
var line = cm.getLineHandle(where.line), pos = where.ch - 1;
var afterCursor = config && config.afterCursor
if (afterCursor == null)
afterCursor = /(^| )cm-fat-cursor($| )/.test(cm.getWrapperElement().className)
var re = bracketRegex(config)
// A cursor is defined as between two characters, but in in vim command mode
// (i.e. not insert mode), the cursor is visually represented as a
// highlighted box on top of the 2nd character. Otherwise, we allow matches
// from before or after the cursor.
var match = (!afterCursor && pos >= 0 && re.test(line.text.charAt(pos)) && matching[line.text.charAt(pos)]) ||
re.test(line.text.charAt(pos + 1)) && matching[line.text.charAt(++pos)];
if (!match) return null;
var dir = match.charAt(1) == ">" ? 1 : -1;
if (config && config.strict && (dir > 0) != (pos == where.ch)) return null;
var style = cm.getTokenTypeAt(Pos(where.line, pos + 1));
var found = scanForBracket(cm, Pos(where.line, pos + (dir > 0 ? 1 : 0)), dir, style || null, config);
if (found == null) return null;
return {from: Pos(where.line, pos), to: found && found.pos,
match: found && found.ch == match.charAt(0), forward: dir > 0};
}
// bracketRegex is used to specify which type of bracket to scan
// should be a regexp, e.g. /[[\]]/
//
// Note: If "where" is on an open bracket, then this bracket is ignored.
//
// Returns false when no bracket was found, null when it reached
// maxScanLines and gave up
function scanForBracket(cm, where, dir, style, config) {
var maxScanLen = (config && config.maxScanLineLength) || 10000;
var maxScanLines = (config && config.maxScanLines) || 1000;
var stack = [];
var re = bracketRegex(config)
var lineEnd = dir > 0 ? Math.min(where.line + maxScanLines, cm.lastLine() + 1)
: Math.max(cm.firstLine() - 1, where.line - maxScanLines);
for (var lineNo = where.line; lineNo != lineEnd; lineNo += dir) {
var line = cm.getLine(lineNo);
if (!line) continue;
var pos = dir > 0 ? 0 : line.length - 1, end = dir > 0 ? line.length : -1;
if (line.length > maxScanLen) continue;
if (lineNo == where.line) pos = where.ch - (dir < 0 ? 1 : 0);
for (; pos != end; pos += dir) {
var ch = line.charAt(pos);
if (re.test(ch) && (style === undefined || cm.getTokenTypeAt(Pos(lineNo, pos + 1)) == style)) {
var match = matching[ch];
if (match && (match.charAt(1) == ">") == (dir > 0)) stack.push(ch);
else if (!stack.length) return {pos: Pos(lineNo, pos), ch: ch};
else stack.pop();
}
}
}
return lineNo - dir == (dir > 0 ? cm.lastLine() : cm.firstLine()) ? false : null;
}
function matchBrackets(cm, autoclear, config) {
// Disable brace matching in long lines, since it'll cause hugely slow updates
var maxHighlightLen = cm.state.matchBrackets.maxHighlightLineLength || 1000;
var marks = [], ranges = cm.listSelections();
for (var i = 0; i < ranges.length; i++) {
var match = ranges[i].empty() && findMatchingBracket(cm, ranges[i].head, config);
if (match && cm.getLine(match.from.line).length <= maxHighlightLen) {
var style = match.match ? "CodeMirror-matchingbracket" : "CodeMirror-nonmatchingbracket";
marks.push(cm.markText(match.from, Pos(match.from.line, match.from.ch + 1), {className: style}));
if (match.to && cm.getLine(match.to.line).length <= maxHighlightLen)
marks.push(cm.markText(match.to, Pos(match.to.line, match.to.ch + 1), {className: style}));
}
}
if (marks.length) {
// Kludge to work around the IE bug from issue #1193, where text
// input stops going to the textare whever this fires.
if (ie_lt8 && cm.state.focused) cm.focus();
var clear = function() {
cm.operation(function() {
for (var i = 0; i < marks.length; i++) marks[i].clear();
});
};
if (autoclear) setTimeout(clear, 800);
else return clear;
}
}
function doMatchBrackets(cm) {
cm.operation(function() {
if (cm.state.matchBrackets.currentlyHighlighted) {
cm.state.matchBrackets.currentlyHighlighted();
cm.state.matchBrackets.currentlyHighlighted = null;
}
cm.state.matchBrackets.currentlyHighlighted = matchBrackets(cm, false, cm.state.matchBrackets);
});
}
CodeMirror.defineOption("matchBrackets", false, function(cm, val, old) {
if (old && old != CodeMirror.Init) {
cm.off("cursorActivity", doMatchBrackets);
if (cm.state.matchBrackets && cm.state.matchBrackets.currentlyHighlighted) {
cm.state.matchBrackets.currentlyHighlighted();
cm.state.matchBrackets.currentlyHighlighted = null;
}
}
if (val) {
cm.state.matchBrackets = typeof val == "object" ? val : {};
cm.on("cursorActivity", doMatchBrackets);
}
});
CodeMirror.defineExtension("matchBrackets", function() {matchBrackets(this, true);});
CodeMirror.defineExtension("findMatchingBracket", function(pos, config, oldConfig){
// Backwards-compatibility kludge
if (oldConfig || typeof config == "boolean") {
if (!oldConfig) {
config = config ? {strict: true} : null
} else {
oldConfig.strict = config
config = oldConfig
}
}
return findMatchingBracket(this, pos, config)
});
CodeMirror.defineExtension("scanForBracket", function(pos, dir, style, config){
return scanForBracket(this, pos, dir, style, config);
});
});

View File

@ -1,66 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("../fold/xml-fold"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "../fold/xml-fold"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.defineOption("matchTags", false, function(cm, val, old) {
if (old && old != CodeMirror.Init) {
cm.off("cursorActivity", doMatchTags);
cm.off("viewportChange", maybeUpdateMatch);
clear(cm);
}
if (val) {
cm.state.matchBothTags = typeof val == "object" && val.bothTags;
cm.on("cursorActivity", doMatchTags);
cm.on("viewportChange", maybeUpdateMatch);
doMatchTags(cm);
}
});
function clear(cm) {
if (cm.state.tagHit) cm.state.tagHit.clear();
if (cm.state.tagOther) cm.state.tagOther.clear();
cm.state.tagHit = cm.state.tagOther = null;
}
function doMatchTags(cm) {
cm.state.failedTagMatch = false;
cm.operation(function() {
clear(cm);
if (cm.somethingSelected()) return;
var cur = cm.getCursor(), range = cm.getViewport();
range.from = Math.min(range.from, cur.line); range.to = Math.max(cur.line + 1, range.to);
var match = CodeMirror.findMatchingTag(cm, cur, range);
if (!match) return;
if (cm.state.matchBothTags) {
var hit = match.at == "open" ? match.open : match.close;
if (hit) cm.state.tagHit = cm.markText(hit.from, hit.to, {className: "CodeMirror-matchingtag"});
}
var other = match.at == "close" ? match.open : match.close;
if (other)
cm.state.tagOther = cm.markText(other.from, other.to, {className: "CodeMirror-matchingtag"});
else
cm.state.failedTagMatch = true;
});
}
function maybeUpdateMatch(cm) {
if (cm.state.failedTagMatch) doMatchTags(cm);
}
CodeMirror.commands.toMatchingTag = function(cm) {
var found = CodeMirror.findMatchingTag(cm, cm.getCursor());
if (found) {
var other = found.at == "close" ? found.open : found.close;
if (other) cm.extendSelection(other.to, other.from);
}
};
});

View File

@ -1,27 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
CodeMirror.defineOption("showTrailingSpace", false, function(cm, val, prev) {
if (prev == CodeMirror.Init) prev = false;
if (prev && !val)
cm.removeOverlay("trailingspace");
else if (!prev && val)
cm.addOverlay({
token: function(stream) {
for (var l = stream.string.length, i = l; i && /\s/.test(stream.string.charAt(i - 1)); --i) {}
if (i > stream.pos) { stream.pos = i; return null; }
stream.pos = l;
return "trailingspace";
},
name: "trailingspace"
});
});
});

View File

@ -1,105 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.registerHelper("fold", "brace", function(cm, start) {
var line = start.line, lineText = cm.getLine(line);
var tokenType;
function findOpening(openCh) {
for (var at = start.ch, pass = 0;;) {
var found = at <= 0 ? -1 : lineText.lastIndexOf(openCh, at - 1);
if (found == -1) {
if (pass == 1) break;
pass = 1;
at = lineText.length;
continue;
}
if (pass == 1 && found < start.ch) break;
tokenType = cm.getTokenTypeAt(CodeMirror.Pos(line, found + 1));
if (!/^(comment|string)/.test(tokenType)) return found + 1;
at = found - 1;
}
}
var startToken = "{", endToken = "}", startCh = findOpening("{");
if (startCh == null) {
startToken = "[", endToken = "]";
startCh = findOpening("[");
}
if (startCh == null) return;
var count = 1, lastLine = cm.lastLine(), end, endCh;
outer: for (var i = line; i <= lastLine; ++i) {
var text = cm.getLine(i), pos = i == line ? startCh : 0;
for (;;) {
var nextOpen = text.indexOf(startToken, pos), nextClose = text.indexOf(endToken, pos);
if (nextOpen < 0) nextOpen = text.length;
if (nextClose < 0) nextClose = text.length;
pos = Math.min(nextOpen, nextClose);
if (pos == text.length) break;
if (cm.getTokenTypeAt(CodeMirror.Pos(i, pos + 1)) == tokenType) {
if (pos == nextOpen) ++count;
else if (!--count) { end = i; endCh = pos; break outer; }
}
++pos;
}
}
if (end == null || line == end) return;
return {from: CodeMirror.Pos(line, startCh),
to: CodeMirror.Pos(end, endCh)};
});
CodeMirror.registerHelper("fold", "import", function(cm, start) {
function hasImport(line) {
if (line < cm.firstLine() || line > cm.lastLine()) return null;
var start = cm.getTokenAt(CodeMirror.Pos(line, 1));
if (!/\S/.test(start.string)) start = cm.getTokenAt(CodeMirror.Pos(line, start.end + 1));
if (start.type != "keyword" || start.string != "import") return null;
// Now find closing semicolon, return its position
for (var i = line, e = Math.min(cm.lastLine(), line + 10); i <= e; ++i) {
var text = cm.getLine(i), semi = text.indexOf(";");
if (semi != -1) return {startCh: start.end, end: CodeMirror.Pos(i, semi)};
}
}
var startLine = start.line, has = hasImport(startLine), prev;
if (!has || hasImport(startLine - 1) || ((prev = hasImport(startLine - 2)) && prev.end.line == startLine - 1))
return null;
for (var end = has.end;;) {
var next = hasImport(end.line + 1);
if (next == null) break;
end = next.end;
}
return {from: cm.clipPos(CodeMirror.Pos(startLine, has.startCh + 1)), to: end};
});
CodeMirror.registerHelper("fold", "include", function(cm, start) {
function hasInclude(line) {
if (line < cm.firstLine() || line > cm.lastLine()) return null;
var start = cm.getTokenAt(CodeMirror.Pos(line, 1));
if (!/\S/.test(start.string)) start = cm.getTokenAt(CodeMirror.Pos(line, start.end + 1));
if (start.type == "meta" && start.string.slice(0, 8) == "#include") return start.start + 8;
}
var startLine = start.line, has = hasInclude(startLine);
if (has == null || hasInclude(startLine - 1) != null) return null;
for (var end = startLine;;) {
var next = hasInclude(end + 1);
if (next == null) break;
++end;
}
return {from: CodeMirror.Pos(startLine, has + 1),
to: cm.clipPos(CodeMirror.Pos(end))};
});
});

View File

@ -1,59 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
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))) &&
(found == 0 || lineText.slice(found - endToken.length, found) == endToken ||
!/comment/.test(cm.getTokenTypeAt(CodeMirror.Pos(line, found))))) {
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)};
});
});

View File

@ -1,152 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
function doFold(cm, pos, options, force) {
if (options && options.call) {
var finder = options;
options = null;
} else {
var finder = getOption(cm, options, "rangeFinder");
}
if (typeof pos == "number") pos = CodeMirror.Pos(pos, 0);
var minSize = getOption(cm, options, "minFoldSize");
function getRange(allowFolded) {
var range = finder(cm, pos);
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 && force !== "fold") {
if (!allowFolded) return null;
range.cleared = true;
marks[i].clear();
}
}
return range;
}
var range = getRange(true);
if (getOption(cm, options, "scanUp")) while (!range && pos.line > cm.firstLine()) {
pos = CodeMirror.Pos(pos.line - 1, 0);
range = getRange(false);
}
if (!range || range.cleared || force === "unfold") return;
var myWidget = makeWidget(cm, options);
CodeMirror.on(myWidget, "mousedown", function(e) {
myRange.clear();
CodeMirror.e_preventDefault(e);
});
var myRange = cm.markText(range.from, range.to, {
replacedWith: myWidget,
clearOnEnter: getOption(cm, options, "clearOnEnter"),
__isFold: true
});
myRange.on("clear", function(from, to) {
CodeMirror.signal(cm, "unfold", cm, from, to);
});
CodeMirror.signal(cm, "fold", cm, range.from, range.to);
}
function makeWidget(cm, options) {
var widget = getOption(cm, options, "widget");
if (typeof widget == "string") {
var text = document.createTextNode(widget);
widget = document.createElement("span");
widget.appendChild(text);
widget.className = "CodeMirror-foldmarker";
} else if (widget) {
widget = widget.cloneNode(true)
}
return widget;
}
// Clumsy backwards-compatible interface
CodeMirror.newFoldFunction = function(rangeFinder, widget) {
return function(cm, pos) { doFold(cm, pos, {rangeFinder: rangeFinder, widget: widget}); };
};
// New-style interface
CodeMirror.defineExtension("foldCode", function(pos, options, force) {
doFold(this, pos, options, force);
});
CodeMirror.defineExtension("isFolded", function(pos) {
var marks = this.findMarksAt(pos);
for (var i = 0; i < marks.length; ++i)
if (marks[i].__isFold) return true;
});
CodeMirror.commands.toggleFold = function(cm) {
cm.foldCode(cm.getCursor());
};
CodeMirror.commands.fold = function(cm) {
cm.foldCode(cm.getCursor(), null, "fold");
};
CodeMirror.commands.unfold = function(cm) {
cm.foldCode(cm.getCursor(), null, "unfold");
};
CodeMirror.commands.foldAll = function(cm) {
cm.operation(function() {
for (var i = cm.firstLine(), e = cm.lastLine(); i <= e; i++)
cm.foldCode(CodeMirror.Pos(i, 0), null, "fold");
});
};
CodeMirror.commands.unfoldAll = function(cm) {
cm.operation(function() {
for (var i = cm.firstLine(), e = cm.lastLine(); i <= e; i++)
cm.foldCode(CodeMirror.Pos(i, 0), null, "unfold");
});
};
CodeMirror.registerHelper("fold", "combine", function() {
var funcs = Array.prototype.slice.call(arguments, 0);
return function(cm, start) {
for (var i = 0; i < funcs.length; ++i) {
var found = funcs[i](cm, start);
if (found) return found;
}
};
});
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;
}
});
var defaultOptions = {
rangeFinder: CodeMirror.fold.auto,
widget: "\u2194",
minFoldSize: 0,
scanUp: false,
clearOnEnter: true
};
CodeMirror.defineOption("foldOptions", null);
function getOption(cm, options, name) {
if (options && options[name] !== undefined)
return options[name];
var editorOptions = cm.options.foldOptions;
if (editorOptions && editorOptions[name] !== undefined)
return editorOptions[name];
return defaultOptions[name];
}
CodeMirror.defineExtension("foldOption", function(options, name) {
return getOption(this, options, name);
});
});

View File

@ -1,20 +0,0 @@
.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 {
cursor: pointer;
}
.CodeMirror-foldgutter-open:after {
content: "\25BE";
}
.CodeMirror-foldgutter-folded:after {
content: "\25B8";
}

View File

@ -1,151 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("./foldcode"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "./foldcode"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"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("changes", onChange);
cm.off("viewportChange", onViewportChange);
cm.off("fold", onFold);
cm.off("unfold", onFold);
cm.off("swapDoc", onChange);
}
if (val) {
cm.state.foldGutter = new State(parseOptions(val));
updateInViewport(cm);
cm.on("gutterClick", onGutterClick);
cm.on("changes", onChange);
cm.on("viewportChange", onViewportChange);
cm.on("fold", onFold);
cm.on("unfold", onFold);
cm.on("swapDoc", onChange);
}
});
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.findMarks(Pos(line, 0), Pos(line + 1, 0));
for (var i = 0; i < marks.length; ++i) {
if (marks[i].__isFold) {
var fromPos = marks[i].find(-1);
if (fromPos && fromPos.line === line)
return marks[i];
}
}
}
function marker(spec) {
if (typeof spec == "string") {
var elt = document.createElement("div");
elt.className = spec + " CodeMirror-guttermarker-subtle";
return elt;
} else {
return spec.cloneNode(true);
}
}
function updateFoldInfo(cm, from, to) {
var opts = cm.state.foldGutter.options, cur = from;
var minSize = cm.foldOption(opts, "minFoldSize");
var func = cm.foldOption(opts, "rangeFinder");
cm.eachLine(from, to, function(line) {
var mark = null;
if (isFolded(cm, cur)) {
mark = marker(opts.indicatorFolded);
} else {
var pos = Pos(cur, 0);
var range = func && func(cm, pos);
if (range && range.to.line - range.from.line >= minSize)
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 state = cm.state.foldGutter;
if (!state) return;
var opts = state.options;
if (gutter != opts.gutter) return;
var folded = isFolded(cm, line);
if (folded) folded.clear();
else cm.foldCode(Pos(line, 0), opts);
}
function onChange(cm) {
var state = cm.state.foldGutter;
if (!state) return;
var opts = state.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;
if (!state) return;
var opts = state.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;
if (!state) return;
var line = from.line;
if (line >= state.from && line < state.to)
updateFoldInfo(cm, line, line + 1);
}
});

View File

@ -1,48 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
function lineIndent(cm, lineNo) {
var text = cm.getLine(lineNo)
var spaceTo = text.search(/\S/)
if (spaceTo == -1 || /\bcomment\b/.test(cm.getTokenTypeAt(CodeMirror.Pos(lineNo, spaceTo + 1))))
return -1
return CodeMirror.countColumn(text, null, cm.getOption("tabSize"))
}
CodeMirror.registerHelper("fold", "indent", function(cm, start) {
var myIndent = lineIndent(cm, start.line)
if (myIndent < 0) return
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 indent = lineIndent(cm, i)
if (indent == -1) {
} else if (indent > myIndent) {
// Lines with a greater indent are considered part of the block.
lastLineInFold = i;
} else {
// If this line has non-space, non-comment content, and is
// indented less or equal to the start line, it is the start of
// another block.
break;
}
}
if (lastLineInFold) return {
from: CodeMirror.Pos(start.line, cm.getLine(start.line).length),
to: CodeMirror.Pos(lastLineInFold, cm.getLine(lastLineInFold).length)
};
});
});

View File

@ -1,49 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.registerHelper("fold", "markdown", function(cm, start) {
var maxDepth = 100;
function isHeader(lineNo) {
var tokentype = cm.getTokenTypeAt(CodeMirror.Pos(lineNo, 0));
return tokentype && /\bheader\b/.test(tokentype);
}
function headerLevel(lineNo, line, nextLine) {
var match = line && line.match(/^#+/);
if (match && isHeader(lineNo)) return match[0].length;
match = nextLine && nextLine.match(/^[=\-]+\s*$/);
if (match && isHeader(lineNo + 1)) return nextLine[0] == "=" ? 1 : 2;
return maxDepth;
}
var firstLine = cm.getLine(start.line), nextLine = cm.getLine(start.line + 1);
var level = headerLevel(start.line, firstLine, nextLine);
if (level === maxDepth) return undefined;
var lastLineNo = cm.lastLine();
var end = start.line, nextNextLine = cm.getLine(end + 2);
while (end < lastLineNo) {
if (headerLevel(end + 1, nextLine, nextNextLine) <= level) break;
++end;
nextLine = nextNextLine;
nextNextLine = cm.getLine(end + 2);
}
return {
from: CodeMirror.Pos(start.line, firstLine.length),
to: CodeMirror.Pos(end, cm.getLine(end).length)
};
});
});

View File

@ -1,184 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
var Pos = CodeMirror.Pos;
function cmp(a, b) { return a.line - b.line || a.ch - b.ch; }
var nameStartChar = "A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD";
var nameChar = nameStartChar + "\-\:\.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040";
var xmlTagStart = new RegExp("<(/?)([" + nameStartChar + "][" + nameChar + "]*)", "g");
function Iter(cm, line, ch, range) {
this.line = line; this.ch = ch;
this.cm = cm; this.text = cm.getLine(line);
this.min = range ? Math.max(range.from, cm.firstLine()) : cm.firstLine();
this.max = range ? Math.min(range.to - 1, cm.lastLine()) : cm.lastLine();
}
function tagAt(iter, ch) {
var type = iter.cm.getTokenTypeAt(Pos(iter.line, ch));
return type && /\btag\b/.test(type);
}
function nextLine(iter) {
if (iter.line >= iter.max) return;
iter.ch = 0;
iter.text = iter.cm.getLine(++iter.line);
return true;
}
function prevLine(iter) {
if (iter.line <= iter.min) return;
iter.text = iter.cm.getLine(--iter.line);
iter.ch = iter.text.length;
return true;
}
function toTagEnd(iter) {
for (;;) {
var gt = iter.text.indexOf(">", iter.ch);
if (gt == -1) { if (nextLine(iter)) continue; else return; }
if (!tagAt(iter, gt + 1)) { iter.ch = gt + 1; continue; }
var lastSlash = iter.text.lastIndexOf("/", gt);
var selfClose = lastSlash > -1 && !/\S/.test(iter.text.slice(lastSlash + 1, gt));
iter.ch = gt + 1;
return selfClose ? "selfClose" : "regular";
}
}
function toTagStart(iter) {
for (;;) {
var lt = iter.ch ? iter.text.lastIndexOf("<", iter.ch - 1) : -1;
if (lt == -1) { if (prevLine(iter)) continue; else return; }
if (!tagAt(iter, lt + 1)) { iter.ch = lt; continue; }
xmlTagStart.lastIndex = lt;
iter.ch = lt;
var match = xmlTagStart.exec(iter.text);
if (match && match.index == lt) return match;
}
}
function toNextTag(iter) {
for (;;) {
xmlTagStart.lastIndex = iter.ch;
var found = xmlTagStart.exec(iter.text);
if (!found) { if (nextLine(iter)) continue; else return; }
if (!tagAt(iter, found.index + 1)) { iter.ch = found.index + 1; continue; }
iter.ch = found.index + found[0].length;
return found;
}
}
function toPrevTag(iter) {
for (;;) {
var gt = iter.ch ? iter.text.lastIndexOf(">", iter.ch - 1) : -1;
if (gt == -1) { if (prevLine(iter)) continue; else return; }
if (!tagAt(iter, gt + 1)) { iter.ch = gt; continue; }
var lastSlash = iter.text.lastIndexOf("/", gt);
var selfClose = lastSlash > -1 && !/\S/.test(iter.text.slice(lastSlash + 1, gt));
iter.ch = gt + 1;
return selfClose ? "selfClose" : "regular";
}
}
function findMatchingClose(iter, tag) {
var stack = [];
for (;;) {
var next = toNextTag(iter), end, startLine = iter.line, startCh = iter.ch - (next ? next[0].length : 0);
if (!next || !(end = toTagEnd(iter))) return;
if (end == "selfClose") continue;
if (next[1]) { // closing tag
for (var i = stack.length - 1; i >= 0; --i) if (stack[i] == next[2]) {
stack.length = i;
break;
}
if (i < 0 && (!tag || tag == next[2])) return {
tag: next[2],
from: Pos(startLine, startCh),
to: Pos(iter.line, iter.ch)
};
} else { // opening tag
stack.push(next[2]);
}
}
}
function findMatchingOpen(iter, tag) {
var stack = [];
for (;;) {
var prev = toPrevTag(iter);
if (!prev) return;
if (prev == "selfClose") { toTagStart(iter); continue; }
var endLine = iter.line, endCh = iter.ch;
var start = toTagStart(iter);
if (!start) return;
if (start[1]) { // closing tag
stack.push(start[2]);
} else { // opening tag
for (var i = stack.length - 1; i >= 0; --i) if (stack[i] == start[2]) {
stack.length = i;
break;
}
if (i < 0 && (!tag || tag == start[2])) return {
tag: start[2],
from: Pos(iter.line, iter.ch),
to: Pos(endLine, endCh)
};
}
}
}
CodeMirror.registerHelper("fold", "xml", function(cm, start) {
var iter = new Iter(cm, start.line, 0);
for (;;) {
var openTag = toNextTag(iter)
if (!openTag || iter.line != start.line) return
var end = toTagEnd(iter)
if (!end) return
if (!openTag[1] && end != "selfClose") {
var startPos = Pos(iter.line, iter.ch);
var endPos = findMatchingClose(iter, openTag[2]);
return endPos && cmp(endPos.from, startPos) > 0 ? {from: startPos, to: endPos.from} : null
}
}
});
CodeMirror.findMatchingTag = function(cm, pos, range) {
var iter = new Iter(cm, pos.line, pos.ch, range);
if (iter.text.indexOf(">") == -1 && iter.text.indexOf("<") == -1) return;
var end = toTagEnd(iter), to = end && Pos(iter.line, iter.ch);
var start = end && toTagStart(iter);
if (!end || !start || cmp(iter, pos) > 0) return;
var here = {from: Pos(iter.line, iter.ch), to: to, tag: start[2]};
if (end == "selfClose") return {open: here, close: null, at: "open"};
if (start[1]) { // closing tag
return {open: findMatchingOpen(iter, start[2]), close: here, at: "close"};
} else { // opening tag
iter = new Iter(cm, to.line, to.ch, range);
return {open: here, close: findMatchingClose(iter, start[2]), at: "open"};
}
};
CodeMirror.findEnclosingTag = function(cm, pos, range, tag) {
var iter = new Iter(cm, pos.line, pos.ch, range);
for (;;) {
var open = findMatchingOpen(iter, tag);
if (!open) break;
var forward = new Iter(cm, pos.line, pos.ch, range);
var close = findMatchingClose(forward, open.tag);
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);
};
});

View File

@ -1,41 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
var WORD = /[\w$]+/, RANGE = 500;
CodeMirror.registerHelper("hint", "anyword", function(editor, options) {
var word = options && options.word || WORD;
var range = options && options.range || RANGE;
var cur = editor.getCursor(), curLine = editor.getLine(cur.line);
var end = cur.ch, start = end;
while (start && word.test(curLine.charAt(start - 1))) --start;
var curWord = start != end && curLine.slice(start, end);
var list = options && options.list || [], seen = {};
var re = new RegExp(word.source, "g");
for (var dir = -1; dir <= 1; dir += 2) {
var line = cur.line, endLine = Math.min(Math.max(line + dir * range, editor.firstLine()), editor.lastLine()) + dir;
for (; line != endLine; line += dir) {
var text = editor.getLine(line), m;
while (m = re.exec(text)) {
if (line == cur.line && m[0] === curWord) continue;
if ((!curWord || m[0].lastIndexOf(curWord, 0) == 0) && !Object.prototype.hasOwnProperty.call(seen, m[0])) {
seen[m[0]] = true;
list.push(m[0]);
}
}
}
}
return {list: list, from: CodeMirror.Pos(cur.line, start), to: CodeMirror.Pos(cur.line, end)};
});
});

View File

@ -1,60 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("../../mode/css/css"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "../../mode/css/css"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
var pseudoClasses = {link: 1, visited: 1, active: 1, hover: 1, focus: 1,
"first-letter": 1, "first-line": 1, "first-child": 1,
before: 1, after: 1, lang: 1};
CodeMirror.registerHelper("hint", "css", function(cm) {
var cur = cm.getCursor(), token = cm.getTokenAt(cur);
var inner = CodeMirror.innerMode(cm.getMode(), token.state);
if (inner.mode.name != "css") return;
if (token.type == "keyword" && "!important".indexOf(token.string) == 0)
return {list: ["!important"], from: CodeMirror.Pos(cur.line, token.start),
to: CodeMirror.Pos(cur.line, token.end)};
var start = token.start, end = cur.ch, word = token.string.slice(0, end - start);
if (/[^\w$_-]/.test(word)) {
word = ""; start = end = cur.ch;
}
var spec = CodeMirror.resolveMode("text/css");
var result = [];
function add(keywords) {
for (var name in keywords)
if (!word || name.lastIndexOf(word, 0) == 0)
result.push(name);
}
var st = inner.state.state;
if (st == "pseudo" || token.type == "variable-3") {
add(pseudoClasses);
} else if (st == "block" || st == "maybeprop") {
add(spec.propertyKeywords);
} else if (st == "prop" || st == "parens" || st == "at" || st == "params") {
add(spec.valueKeywords);
add(spec.colorKeywords);
} else if (st == "media" || st == "media_parens") {
add(spec.mediaTypes);
add(spec.mediaFeatures);
}
if (result.length) return {
list: result,
from: CodeMirror.Pos(cur.line, start),
to: CodeMirror.Pos(cur.line, end)
};
});
});

View File

@ -1,350 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("./xml-hint"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "./xml-hint"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
var langs = "ab aa af ak sq am ar an hy as av ae ay az bm ba eu be bn bh bi bs br bg my ca ch ce ny zh cv kw co cr hr cs da dv nl dz en eo et ee fo fj fi fr ff gl ka de el gn gu ht ha he hz hi ho hu ia id ie ga ig ik io is it iu ja jv kl kn kr ks kk km ki rw ky kv kg ko ku kj la lb lg li ln lo lt lu lv gv mk mg ms ml mt mi mr mh mn na nv nb nd ne ng nn no ii nr oc oj cu om or os pa pi fa pl ps pt qu rm rn ro ru sa sc sd se sm sg sr gd sn si sk sl so st es su sw ss sv ta te tg th ti bo tk tl tn to tr ts tt tw ty ug uk ur uz ve vi vo wa cy wo fy xh yi yo za zu".split(" ");
var targets = ["_blank", "_self", "_top", "_parent"];
var charsets = ["ascii", "utf-8", "utf-16", "latin1", "latin1"];
var methods = ["get", "post", "put", "delete"];
var encs = ["application/x-www-form-urlencoded", "multipart/form-data", "text/plain"];
var media = ["all", "screen", "print", "embossed", "braille", "handheld", "print", "projection", "screen", "tty", "tv", "speech",
"3d-glasses", "resolution [>][<][=] [X]", "device-aspect-ratio: X/Y", "orientation:portrait",
"orientation:landscape", "device-height: [X]", "device-width: [X]"];
var s = { attrs: {} }; // Simple tag, reused for a whole lot of tags
var data = {
a: {
attrs: {
href: null, ping: null, type: null,
media: media,
target: targets,
hreflang: langs
}
},
abbr: s,
acronym: s,
address: s,
applet: s,
area: {
attrs: {
alt: null, coords: null, href: null, target: null, ping: null,
media: media, hreflang: langs, type: null,
shape: ["default", "rect", "circle", "poly"]
}
},
article: s,
aside: s,
audio: {
attrs: {
src: null, mediagroup: null,
crossorigin: ["anonymous", "use-credentials"],
preload: ["none", "metadata", "auto"],
autoplay: ["", "autoplay"],
loop: ["", "loop"],
controls: ["", "controls"]
}
},
b: s,
base: { attrs: { href: null, target: targets } },
basefont: s,
bdi: s,
bdo: s,
big: s,
blockquote: { attrs: { cite: null } },
body: s,
br: s,
button: {
attrs: {
form: null, formaction: null, name: null, value: null,
autofocus: ["", "autofocus"],
disabled: ["", "autofocus"],
formenctype: encs,
formmethod: methods,
formnovalidate: ["", "novalidate"],
formtarget: targets,
type: ["submit", "reset", "button"]
}
},
canvas: { attrs: { width: null, height: null } },
caption: s,
center: s,
cite: s,
code: s,
col: { attrs: { span: null } },
colgroup: { attrs: { span: null } },
command: {
attrs: {
type: ["command", "checkbox", "radio"],
label: null, icon: null, radiogroup: null, command: null, title: null,
disabled: ["", "disabled"],
checked: ["", "checked"]
}
},
data: { attrs: { value: null } },
datagrid: { attrs: { disabled: ["", "disabled"], multiple: ["", "multiple"] } },
datalist: { attrs: { data: null } },
dd: s,
del: { attrs: { cite: null, datetime: null } },
details: { attrs: { open: ["", "open"] } },
dfn: s,
dir: s,
div: s,
dl: s,
dt: s,
em: s,
embed: { attrs: { src: null, type: null, width: null, height: null } },
eventsource: { attrs: { src: null } },
fieldset: { attrs: { disabled: ["", "disabled"], form: null, name: null } },
figcaption: s,
figure: s,
font: s,
footer: s,
form: {
attrs: {
action: null, name: null,
"accept-charset": charsets,
autocomplete: ["on", "off"],
enctype: encs,
method: methods,
novalidate: ["", "novalidate"],
target: targets
}
},
frame: s,
frameset: s,
h1: s, h2: s, h3: s, h4: s, h5: s, h6: s,
head: {
attrs: {},
children: ["title", "base", "link", "style", "meta", "script", "noscript", "command"]
},
header: s,
hgroup: s,
hr: s,
html: {
attrs: { manifest: null },
children: ["head", "body"]
},
i: s,
iframe: {
attrs: {
src: null, srcdoc: null, name: null, width: null, height: null,
sandbox: ["allow-top-navigation", "allow-same-origin", "allow-forms", "allow-scripts"],
seamless: ["", "seamless"]
}
},
img: {
attrs: {
alt: null, src: null, ismap: null, usemap: null, width: null, height: null,
crossorigin: ["anonymous", "use-credentials"]
}
},
input: {
attrs: {
alt: null, dirname: null, form: null, formaction: null,
height: null, list: null, max: null, maxlength: null, min: null,
name: null, pattern: null, placeholder: null, size: null, src: null,
step: null, value: null, width: null,
accept: ["audio/*", "video/*", "image/*"],
autocomplete: ["on", "off"],
autofocus: ["", "autofocus"],
checked: ["", "checked"],
disabled: ["", "disabled"],
formenctype: encs,
formmethod: methods,
formnovalidate: ["", "novalidate"],
formtarget: targets,
multiple: ["", "multiple"],
readonly: ["", "readonly"],
required: ["", "required"],
type: ["hidden", "text", "search", "tel", "url", "email", "password", "datetime", "date", "month",
"week", "time", "datetime-local", "number", "range", "color", "checkbox", "radio",
"file", "submit", "image", "reset", "button"]
}
},
ins: { attrs: { cite: null, datetime: null } },
kbd: s,
keygen: {
attrs: {
challenge: null, form: null, name: null,
autofocus: ["", "autofocus"],
disabled: ["", "disabled"],
keytype: ["RSA"]
}
},
label: { attrs: { "for": null, form: null } },
legend: s,
li: { attrs: { value: null } },
link: {
attrs: {
href: null, type: null,
hreflang: langs,
media: media,
sizes: ["all", "16x16", "16x16 32x32", "16x16 32x32 64x64"]
}
},
map: { attrs: { name: null } },
mark: s,
menu: { attrs: { label: null, type: ["list", "context", "toolbar"] } },
meta: {
attrs: {
content: null,
charset: charsets,
name: ["viewport", "application-name", "author", "description", "generator", "keywords"],
"http-equiv": ["content-language", "content-type", "default-style", "refresh"]
}
},
meter: { attrs: { value: null, min: null, low: null, high: null, max: null, optimum: null } },
nav: s,
noframes: s,
noscript: s,
object: {
attrs: {
data: null, type: null, name: null, usemap: null, form: null, width: null, height: null,
typemustmatch: ["", "typemustmatch"]
}
},
ol: { attrs: { reversed: ["", "reversed"], start: null, type: ["1", "a", "A", "i", "I"] } },
optgroup: { attrs: { disabled: ["", "disabled"], label: null } },
option: { attrs: { disabled: ["", "disabled"], label: null, selected: ["", "selected"], value: null } },
output: { attrs: { "for": null, form: null, name: null } },
p: s,
param: { attrs: { name: null, value: null } },
pre: s,
progress: { attrs: { value: null, max: null } },
q: { attrs: { cite: null } },
rp: s,
rt: s,
ruby: s,
s: s,
samp: s,
script: {
attrs: {
type: ["text/javascript"],
src: null,
async: ["", "async"],
defer: ["", "defer"],
charset: charsets
}
},
section: s,
select: {
attrs: {
form: null, name: null, size: null,
autofocus: ["", "autofocus"],
disabled: ["", "disabled"],
multiple: ["", "multiple"]
}
},
small: s,
source: { attrs: { src: null, type: null, media: null } },
span: s,
strike: s,
strong: s,
style: {
attrs: {
type: ["text/css"],
media: media,
scoped: null
}
},
sub: s,
summary: s,
sup: s,
table: s,
tbody: s,
td: { attrs: { colspan: null, rowspan: null, headers: null } },
textarea: {
attrs: {
dirname: null, form: null, maxlength: null, name: null, placeholder: null,
rows: null, cols: null,
autofocus: ["", "autofocus"],
disabled: ["", "disabled"],
readonly: ["", "readonly"],
required: ["", "required"],
wrap: ["soft", "hard"]
}
},
tfoot: s,
th: { attrs: { colspan: null, rowspan: null, headers: null, scope: ["row", "col", "rowgroup", "colgroup"] } },
thead: s,
time: { attrs: { datetime: null } },
title: s,
tr: s,
track: {
attrs: {
src: null, label: null, "default": null,
kind: ["subtitles", "captions", "descriptions", "chapters", "metadata"],
srclang: langs
}
},
tt: s,
u: s,
ul: s,
"var": s,
video: {
attrs: {
src: null, poster: null, width: null, height: null,
crossorigin: ["anonymous", "use-credentials"],
preload: ["auto", "metadata", "none"],
autoplay: ["", "autoplay"],
mediagroup: ["movie"],
muted: ["", "muted"],
controls: ["", "controls"]
}
},
wbr: s
};
var globalAttrs = {
accesskey: ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"],
"class": null,
contenteditable: ["true", "false"],
contextmenu: null,
dir: ["ltr", "rtl", "auto"],
draggable: ["true", "false", "auto"],
dropzone: ["copy", "move", "link", "string:", "file:"],
hidden: ["hidden"],
id: null,
inert: ["inert"],
itemid: null,
itemprop: null,
itemref: null,
itemscope: ["itemscope"],
itemtype: null,
lang: ["en", "es"],
spellcheck: ["true", "false"],
autocorrect: ["true", "false"],
autocapitalize: ["true", "false"],
style: null,
tabindex: ["1", "2", "3", "4", "5", "6", "7", "8", "9"],
title: null,
translate: ["yes", "no"],
onclick: null,
rel: ["stylesheet", "alternate", "author", "bookmark", "help", "license", "next", "nofollow", "noreferrer", "prefetch", "prev", "search", "tag"]
};
function populate(obj) {
for (var attr in globalAttrs) if (globalAttrs.hasOwnProperty(attr))
obj.attrs[attr] = globalAttrs[attr];
}
populate(s);
for (var tag in data) if (data.hasOwnProperty(tag) && data[tag] != s)
populate(data[tag]);
CodeMirror.htmlSchema = data;
function htmlHint(cm, options) {
var local = {schemaInfo: data};
if (options) for (var opt in options) local[opt] = options[opt];
return CodeMirror.hint.xml(cm, local);
}
CodeMirror.registerHelper("hint", "html", htmlHint);
});

View File

@ -1,157 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
var Pos = CodeMirror.Pos;
function forEach(arr, f) {
for (var i = 0, e = arr.length; i < e; ++i) f(arr[i]);
}
function arrayContains(arr, item) {
if (!Array.prototype.indexOf) {
var i = arr.length;
while (i--) {
if (arr[i] === item) {
return true;
}
}
return false;
}
return arr.indexOf(item) != -1;
}
function scriptHint(editor, keywords, getToken, options) {
// Find the token at the cursor
var cur = editor.getCursor(), token = getToken(editor, cur);
if (/\b(?:string|comment)\b/.test(token.type)) return;
var innerMode = CodeMirror.innerMode(editor.getMode(), token.state);
if (innerMode.mode.helperType === "json") return;
token.state = innerMode.state;
// If it's not a 'word-style' token, ignore the token.
if (!/^[\w$_]*$/.test(token.string)) {
token = {start: cur.ch, end: cur.ch, string: "", state: token.state,
type: token.string == "." ? "property" : null};
} else if (token.end > cur.ch) {
token.end = cur.ch;
token.string = token.string.slice(0, cur.ch - token.start);
}
var tprop = token;
// If it is a property, find out what it is a property of.
while (tprop.type == "property") {
tprop = getToken(editor, Pos(cur.line, tprop.start));
if (tprop.string != ".") return;
tprop = getToken(editor, Pos(cur.line, tprop.start));
if (!context) var context = [];
context.push(tprop);
}
return {list: getCompletions(token, context, keywords, options),
from: Pos(cur.line, token.start),
to: Pos(cur.line, token.end)};
}
function javascriptHint(editor, options) {
return scriptHint(editor, javascriptKeywords,
function (e, cur) {return e.getTokenAt(cur);},
options);
};
CodeMirror.registerHelper("hint", "javascript", javascriptHint);
function getCoffeeScriptToken(editor, cur) {
// This getToken, it is for coffeescript, imitates the behavior of
// getTokenAt method in javascript.js, that is, returning "property"
// type and treat "." as indepenent token.
var token = editor.getTokenAt(cur);
if (cur.ch == token.start + 1 && token.string.charAt(0) == '.') {
token.end = token.start;
token.string = '.';
token.type = "property";
}
else if (/^\.[\w$_]*$/.test(token.string)) {
token.type = "property";
token.start++;
token.string = token.string.replace(/\./, '');
}
return token;
}
function coffeescriptHint(editor, options) {
return scriptHint(editor, coffeescriptKeywords, getCoffeeScriptToken, options);
}
CodeMirror.registerHelper("hint", "coffeescript", coffeescriptHint);
var stringProps = ("charAt charCodeAt indexOf lastIndexOf substring substr slice trim trimLeft trimRight " +
"toUpperCase toLowerCase split concat match replace search").split(" ");
var arrayProps = ("length concat join splice push pop shift unshift slice reverse sort indexOf " +
"lastIndexOf every some filter forEach map reduce reduceRight ").split(" ");
var funcProps = "prototype apply call bind".split(" ");
var javascriptKeywords = ("break case catch class const continue debugger default delete do else export extends false finally for function " +
"if in import instanceof new null return super switch this throw true try typeof var void while with yield").split(" ");
var coffeescriptKeywords = ("and break catch class continue delete do else extends false finally for " +
"if in instanceof isnt new no not null of off on or return switch then throw true try typeof until void while with yes").split(" ");
function forAllProps(obj, callback) {
if (!Object.getOwnPropertyNames || !Object.getPrototypeOf) {
for (var name in obj) callback(name)
} else {
for (var o = obj; o; o = Object.getPrototypeOf(o))
Object.getOwnPropertyNames(o).forEach(callback)
}
}
function getCompletions(token, context, keywords, options) {
var found = [], start = token.string, global = options && options.globalScope || window;
function maybeAdd(str) {
if (str.lastIndexOf(start, 0) == 0 && !arrayContains(found, str)) found.push(str);
}
function gatherCompletions(obj) {
if (typeof obj == "string") forEach(stringProps, maybeAdd);
else if (obj instanceof Array) forEach(arrayProps, maybeAdd);
else if (obj instanceof Function) forEach(funcProps, maybeAdd);
forAllProps(obj, maybeAdd)
}
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 && obj.type.indexOf("variable") === 0) {
if (options && options.additionalContext)
base = options.additionalContext[obj.string];
if (!options || options.useGlobalScope !== false)
base = base || global[obj.string];
} else if (obj.type == "string") {
base = "";
} else if (obj.type == "atom") {
base = 1;
} else if (obj.type == "function") {
if (global.jQuery != null && (obj.string == '$' || obj.string == 'jQuery') &&
(typeof global.jQuery == 'function'))
base = global.jQuery();
else if (global._ != null && (obj.string == '_') && (typeof global._ == 'function'))
base = global._();
}
while (base != null && context.length)
base = base[context.pop().string];
if (base != null) gatherCompletions(base);
} else {
// If not, just look in the global 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);
for (var v = token.state.globalVars; v; v = v.next) maybeAdd(v.name);
if (!options || options.useGlobalScope !== false)
gatherCompletions(global);
forEach(keywords, maybeAdd);
}
return found;
}
});

View File

@ -1,36 +0,0 @@
.CodeMirror-hints {
position: absolute;
z-index: 10;
overflow: hidden;
list-style: none;
margin: 0;
padding: 2px;
-webkit-box-shadow: 2px 3px 5px rgba(0,0,0,.2);
-moz-box-shadow: 2px 3px 5px rgba(0,0,0,.2);
box-shadow: 2px 3px 5px rgba(0,0,0,.2);
border-radius: 3px;
border: 1px solid silver;
background: white;
font-size: 90%;
font-family: monospace;
max-height: 20em;
overflow-y: auto;
}
.CodeMirror-hint {
margin: 0;
padding: 0 4px;
border-radius: 2px;
white-space: pre;
color: black;
cursor: pointer;
}
li.CodeMirror-hint-active {
background: #08f;
color: white;
}

View File

@ -1,460 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
var HINT_ELEMENT_CLASS = "CodeMirror-hint";
var ACTIVE_HINT_ELEMENT_CLASS = "CodeMirror-hint-active";
// This is the old interface, kept around for now to stay
// backwards-compatible.
CodeMirror.showHint = function(cm, getHints, options) {
if (!getHints) return cm.showHint(options);
if (options && options.async) getHints.async = true;
var newOpts = {hint: getHints};
if (options) for (var prop in options) newOpts[prop] = options[prop];
return cm.showHint(newOpts);
};
CodeMirror.defineExtension("showHint", function(options) {
options = parseOptions(this, this.getCursor("start"), options);
var selections = this.listSelections()
if (selections.length > 1) return;
// By default, don't allow completion when something is selected.
// A hint function can have a `supportsSelection` property to
// indicate that it can handle selections.
if (this.somethingSelected()) {
if (!options.hint.supportsSelection) return;
// Don't try with cross-line selections
for (var i = 0; i < selections.length; i++)
if (selections[i].head.line != selections[i].anchor.line) return;
}
if (this.state.completionActive) this.state.completionActive.close();
var completion = this.state.completionActive = new Completion(this, options);
if (!completion.options.hint) return;
CodeMirror.signal(this, "startCompletion", this);
completion.update(true);
});
CodeMirror.defineExtension("closeHint", function() {
if (this.state.completionActive) this.state.completionActive.close()
})
function Completion(cm, options) {
this.cm = cm;
this.options = options;
this.widget = null;
this.debounce = 0;
this.tick = 0;
this.startPos = this.cm.getCursor("start");
this.startLen = this.cm.getLine(this.startPos.line).length - this.cm.getSelection().length;
var self = this;
cm.on("cursorActivity", this.activityFunc = function() { self.cursorActivity(); });
}
var requestAnimationFrame = window.requestAnimationFrame || function(fn) {
return setTimeout(fn, 1000/60);
};
var cancelAnimationFrame = window.cancelAnimationFrame || clearTimeout;
Completion.prototype = {
close: function() {
if (!this.active()) return;
this.cm.state.completionActive = null;
this.tick = null;
this.cm.off("cursorActivity", this.activityFunc);
if (this.widget && this.data) CodeMirror.signal(this.data, "close");
if (this.widget) this.widget.close();
CodeMirror.signal(this.cm, "endCompletion", this.cm);
},
active: function() {
return this.cm.state.completionActive == this;
},
pick: function(data, i) {
var completion = data.list[i];
if (completion.hint) completion.hint(this.cm, data, completion);
else this.cm.replaceRange(getText(completion), completion.from || data.from,
completion.to || data.to, "complete");
CodeMirror.signal(data, "pick", completion);
this.close();
},
cursorActivity: function() {
if (this.debounce) {
cancelAnimationFrame(this.debounce);
this.debounce = 0;
}
var pos = this.cm.getCursor(), line = this.cm.getLine(pos.line);
if (pos.line != this.startPos.line || line.length - pos.ch != this.startLen - this.startPos.ch ||
pos.ch < this.startPos.ch || this.cm.somethingSelected() ||
(!pos.ch || this.options.closeCharacters.test(line.charAt(pos.ch - 1)))) {
this.close();
} else {
var self = this;
this.debounce = requestAnimationFrame(function() {self.update();});
if (this.widget) this.widget.disable();
}
},
update: function(first) {
if (this.tick == null) return
var self = this, myTick = ++this.tick
fetchHints(this.options.hint, this.cm, this.options, function(data) {
if (self.tick == myTick) self.finishUpdate(data, first)
})
},
finishUpdate: function(data, first) {
if (this.data) CodeMirror.signal(this.data, "update");
var picked = (this.widget && this.widget.picked) || (first && this.options.completeSingle);
if (this.widget) this.widget.close();
this.data = data;
if (data && data.list.length) {
if (picked && data.list.length == 1) {
this.pick(data, 0);
} else {
this.widget = new Widget(this, data);
CodeMirror.signal(data, "shown");
}
}
}
};
function parseOptions(cm, pos, options) {
var editor = cm.options.hintOptions;
var out = {};
for (var prop in defaultOptions) out[prop] = defaultOptions[prop];
if (editor) for (var prop in editor)
if (editor[prop] !== undefined) out[prop] = editor[prop];
if (options) for (var prop in options)
if (options[prop] !== undefined) out[prop] = options[prop];
if (out.hint.resolve) out.hint = out.hint.resolve(cm, pos)
return out;
}
function getText(completion) {
if (typeof completion == "string") return completion;
else return completion.text;
}
function buildKeyMap(completion, handle) {
var baseMap = {
Up: function() {handle.moveFocus(-1);},
Down: function() {handle.moveFocus(1);},
PageUp: function() {handle.moveFocus(-handle.menuSize() + 1, true);},
PageDown: function() {handle.moveFocus(handle.menuSize() - 1, true);},
Home: function() {handle.setFocus(0);},
End: function() {handle.setFocus(handle.length - 1);},
Enter: handle.pick,
Tab: handle.pick,
Esc: handle.close
};
var mac = /Mac/.test(navigator.platform);
if (mac) {
baseMap["Ctrl-P"] = function() {handle.moveFocus(-1);};
baseMap["Ctrl-N"] = function() {handle.moveFocus(1);};
}
var custom = completion.options.customKeys;
var ourMap = custom ? {} : baseMap;
function addBinding(key, val) {
var bound;
if (typeof val != "string")
bound = function(cm) { return val(cm, handle); };
// This mechanism is deprecated
else if (baseMap.hasOwnProperty(val))
bound = baseMap[val];
else
bound = val;
ourMap[key] = bound;
}
if (custom)
for (var key in custom) if (custom.hasOwnProperty(key))
addBinding(key, custom[key]);
var extra = completion.options.extraKeys;
if (extra)
for (var key in extra) if (extra.hasOwnProperty(key))
addBinding(key, extra[key]);
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;
this.picked = false;
var widget = this, cm = completion.cm;
var ownerDocument = cm.getInputField().ownerDocument;
var parentWindow = ownerDocument.defaultView || ownerDocument.parentWindow;
var hints = this.hints = ownerDocument.createElement("ul");
var theme = completion.cm.options.theme;
hints.className = "CodeMirror-hints " + theme;
this.selectedHint = data.selectedHint || 0;
var completions = data.list;
for (var i = 0; i < completions.length; ++i) {
var elt = hints.appendChild(ownerDocument.createElement("li")), cur = completions[i];
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);
else elt.appendChild(ownerDocument.createTextNode(cur.displayText || getText(cur)));
elt.hintId = i;
}
var container = completion.options.container || ownerDocument.body;
var pos = cm.cursorCoords(completion.options.alignWithWord ? data.from : null);
var left = pos.left, top = pos.bottom, below = true;
var offsetLeft = 0, offsetTop = 0;
if (container !== ownerDocument.body) {
// We offset the cursor position because left and top are relative to the offsetParent's top left corner.
var isContainerPositioned = ['absolute', 'relative', 'fixed'].indexOf(parentWindow.getComputedStyle(container).position) !== -1;
var offsetParent = isContainerPositioned ? container : container.offsetParent;
var offsetParentPosition = offsetParent.getBoundingClientRect();
var bodyPosition = ownerDocument.body.getBoundingClientRect();
offsetLeft = (offsetParentPosition.left - bodyPosition.left - offsetParent.scrollLeft);
offsetTop = (offsetParentPosition.top - bodyPosition.top - offsetParent.scrollTop);
}
hints.style.left = (left - offsetLeft) + "px";
hints.style.top = (top - offsetTop) + "px";
// If we're at the edge of the screen, then we want the menu to appear on the left of the cursor.
var winW = parentWindow.innerWidth || Math.max(ownerDocument.body.offsetWidth, ownerDocument.documentElement.offsetWidth);
var winH = parentWindow.innerHeight || Math.max(ownerDocument.body.offsetHeight, ownerDocument.documentElement.offsetHeight);
container.appendChild(hints);
var box = hints.getBoundingClientRect(), overlapY = box.bottom - winH;
var scrolls = hints.scrollHeight > hints.clientHeight + 1
var startScroll = cm.getScrollInfo();
if (overlapY > 0) {
var height = box.bottom - box.top, curTop = pos.top - (pos.bottom - box.top);
if (curTop - height > 0) { // Fits above cursor
hints.style.top = (top = pos.top - height - offsetTop) + "px";
below = false;
} else if (height > winH) {
hints.style.height = (winH - 5) + "px";
hints.style.top = (top = pos.bottom - box.top - offsetTop) + "px";
var cursor = cm.getCursor();
if (data.from.ch != cursor.ch) {
pos = cm.cursorCoords(cursor);
hints.style.left = (left = pos.left - offsetLeft) + "px";
box = hints.getBoundingClientRect();
}
}
}
var overlapX = box.right - winW;
if (overlapX > 0) {
if (box.right - box.left > winW) {
hints.style.width = (winW - 5) + "px";
overlapX -= (box.right - box.left) - winW;
}
hints.style.left = (left = pos.left - overlapX - offsetLeft) + "px";
}
if (scrolls) for (var node = hints.firstChild; node; node = node.nextSibling)
node.style.paddingRight = cm.display.nativeBarWidth + "px"
cm.addKeyMap(this.keyMap = buildKeyMap(completion, {
moveFocus: function(n, avoidWrap) { widget.changeActive(widget.selectedHint + n, avoidWrap); },
setFocus: function(n) { widget.changeActive(n); },
menuSize: function() { return widget.screenAmount(); },
length: completions.length,
close: function() { completion.close(); },
pick: function() { widget.pick(); },
data: data
}));
if (completion.options.closeOnUnfocus) {
var closingOnBlur;
cm.on("blur", this.onBlur = function() { closingOnBlur = setTimeout(function() { completion.close(); }, 100); });
cm.on("focus", this.onFocus = function() { clearTimeout(closingOnBlur); });
}
cm.on("scroll", this.onScroll = function() {
var curScroll = cm.getScrollInfo(), editor = cm.getWrapperElement().getBoundingClientRect();
var newTop = top + startScroll.top - curScroll.top;
var point = newTop - (parentWindow.pageYOffset || (ownerDocument.documentElement || ownerDocument.body).scrollTop);
if (!below) point += hints.offsetHeight;
if (point <= editor.top || point >= editor.bottom) return completion.close();
hints.style.top = newTop + "px";
hints.style.left = (left + startScroll.left - curScroll.left) + "px";
});
CodeMirror.on(hints, "dblclick", function(e) {
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 = getHintElement(hints, e.target || e.srcElement);
if (t && t.hintId != null) {
widget.changeActive(t.hintId);
if (completion.options.completeOnSingleClick) widget.pick();
}
});
CodeMirror.on(hints, "mousedown", function() {
setTimeout(function(){cm.focus();}, 20);
});
CodeMirror.signal(data, "select", completions[this.selectedHint], hints.childNodes[this.selectedHint]);
return true;
}
Widget.prototype = {
close: function() {
if (this.completion.widget != this) return;
this.completion.widget = null;
this.hints.parentNode.removeChild(this.hints);
this.completion.cm.removeKeyMap(this.keyMap);
var cm = this.completion.cm;
if (this.completion.options.closeOnUnfocus) {
cm.off("blur", this.onBlur);
cm.off("focus", this.onFocus);
}
cm.off("scroll", this.onScroll);
},
disable: function() {
this.completion.cm.removeKeyMap(this.keyMap);
var widget = this;
this.keyMap = {Enter: function() { widget.picked = true; }};
this.completion.cm.addKeyMap(this.keyMap);
},
pick: function() {
this.completion.pick(this.data, this.selectedHint);
},
changeActive: function(i, avoidWrap) {
if (i >= this.data.list.length)
i = avoidWrap ? this.data.list.length - 1 : 0;
else if (i < 0)
i = avoidWrap ? 0 : this.data.list.length - 1;
if (this.selectedHint == i) return;
var node = this.hints.childNodes[this.selectedHint];
if (node) node.className = node.className.replace(" " + ACTIVE_HINT_ELEMENT_CLASS, "");
node = this.hints.childNodes[this.selectedHint = i];
node.className += " " + ACTIVE_HINT_ELEMENT_CLASS;
if (node.offsetTop < this.hints.scrollTop)
this.hints.scrollTop = node.offsetTop - 3;
else if (node.offsetTop + node.offsetHeight > this.hints.scrollTop + this.hints.clientHeight)
this.hints.scrollTop = node.offsetTop + node.offsetHeight - this.hints.clientHeight + 3;
CodeMirror.signal(this.data, "select", this.data.list[this.selectedHint], node);
},
screenAmount: function() {
return Math.floor(this.hints.clientHeight / this.hints.firstChild.offsetHeight) || 1;
}
};
function applicableHelpers(cm, helpers) {
if (!cm.somethingSelected()) return helpers
var result = []
for (var i = 0; i < helpers.length; i++)
if (helpers[i].supportsSelection) result.push(helpers[i])
return result
}
function fetchHints(hint, cm, options, callback) {
if (hint.async) {
hint(cm, callback, options)
} else {
var result = hint(cm, options)
if (result && result.then) result.then(callback)
else callback(result)
}
}
function resolveAutoHints(cm, pos) {
var helpers = cm.getHelpers(pos, "hint"), words
if (helpers.length) {
var resolved = function(cm, callback, options) {
var app = applicableHelpers(cm, helpers);
function run(i) {
if (i == app.length) return callback(null)
fetchHints(app[i], cm, options, function(result) {
if (result && result.list.length > 0) callback(result)
else run(i + 1)
})
}
run(0)
}
resolved.async = true
resolved.supportsSelection = true
return resolved
} else if (words = cm.getHelper(cm.getCursor(), "hintWords")) {
return function(cm) { return CodeMirror.hint.fromList(cm, {words: words}) }
} else if (CodeMirror.hint.anyword) {
return function(cm, options) { return CodeMirror.hint.anyword(cm, options) }
} else {
return function() {}
}
}
CodeMirror.registerHelper("hint", "auto", {
resolve: resolveAutoHints
});
CodeMirror.registerHelper("hint", "fromList", function(cm, options) {
var cur = cm.getCursor(), token = cm.getTokenAt(cur)
var term, from = CodeMirror.Pos(cur.line, token.start), to = cur
if (token.start < cur.ch && /\w/.test(token.string.charAt(cur.ch - token.start - 1))) {
term = token.string.substr(0, cur.ch - token.start)
} else {
term = ""
from = cur
}
var found = [];
for (var i = 0; i < options.words.length; i++) {
var word = options.words[i];
if (word.slice(0, term.length) == term)
found.push(word);
}
if (found.length) return {list: found, from: from, to: to};
});
CodeMirror.commands.autocomplete = CodeMirror.showHint;
var defaultOptions = {
hint: CodeMirror.hint.auto,
completeSingle: true,
alignWithWord: true,
closeCharacters: /[\s()\[\]{};:>,]/,
closeOnUnfocus: true,
completeOnSingleClick: true,
container: null,
customKeys: null,
extraKeys: null
};
CodeMirror.defineOption("hintOptions", null);
});

View File

@ -1,304 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("../../mode/sql/sql"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "../../mode/sql/sql"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
var tables;
var defaultTable;
var keywords;
var identifierQuote;
var CONS = {
QUERY_DIV: ";",
ALIAS_KEYWORD: "AS"
};
var Pos = CodeMirror.Pos, cmpPos = CodeMirror.cmpPos;
function isArray(val) { return Object.prototype.toString.call(val) == "[object Array]" }
function getKeywords(editor) {
var mode = editor.doc.modeOption;
if (mode === "sql") mode = "text/x-sql";
return CodeMirror.resolveMode(mode).keywords;
}
function getIdentifierQuote(editor) {
var mode = editor.doc.modeOption;
if (mode === "sql") mode = "text/x-sql";
return CodeMirror.resolveMode(mode).identifierQuote || "`";
}
function getText(item) {
return typeof item == "string" ? item : item.text;
}
function wrapTable(name, value) {
if (isArray(value)) value = {columns: value}
if (!value.text) value.text = name
return value
}
function parseTables(input) {
var result = {}
if (isArray(input)) {
for (var i = input.length - 1; i >= 0; i--) {
var item = input[i]
result[getText(item).toUpperCase()] = wrapTable(getText(item), item)
}
} else if (input) {
for (var name in input)
result[name.toUpperCase()] = wrapTable(name, input[name])
}
return result
}
function getTable(name) {
return tables[name.toUpperCase()]
}
function shallowClone(object) {
var result = {};
for (var key in object) if (object.hasOwnProperty(key))
result[key] = object[key];
return result;
}
function match(string, word) {
var len = string.length;
var sub = getText(word).substr(0, len);
return string.toUpperCase() === sub.toUpperCase();
}
function addMatches(result, search, wordlist, formatter) {
if (isArray(wordlist)) {
for (var i = 0; i < wordlist.length; i++)
if (match(search, wordlist[i])) result.push(formatter(wordlist[i]))
} else {
for (var word in wordlist) if (wordlist.hasOwnProperty(word)) {
var val = wordlist[word]
if (!val || val === true)
val = word
else
val = val.displayText ? {text: val.text, displayText: val.displayText} : val.text
if (match(search, val)) result.push(formatter(val))
}
}
}
function cleanName(name) {
// Get rid name from identifierQuote and preceding dot(.)
if (name.charAt(0) == ".") {
name = name.substr(1);
}
// replace doublicated identifierQuotes with single identifierQuotes
// and remove single identifierQuotes
var nameParts = name.split(identifierQuote+identifierQuote);
for (var i = 0; i < nameParts.length; i++)
nameParts[i] = nameParts[i].replace(new RegExp(identifierQuote,"g"), "");
return nameParts.join(identifierQuote);
}
function insertIdentifierQuotes(name) {
var nameParts = getText(name).split(".");
for (var i = 0; i < nameParts.length; i++)
nameParts[i] = identifierQuote +
// doublicate identifierQuotes
nameParts[i].replace(new RegExp(identifierQuote,"g"), identifierQuote+identifierQuote) +
identifierQuote;
var escaped = nameParts.join(".");
if (typeof name == "string") return escaped;
name = shallowClone(name);
name.text = escaped;
return name;
}
function nameCompletion(cur, token, result, editor) {
// Try to complete table, column names and return start position of completion
var useIdentifierQuotes = false;
var nameParts = [];
var start = token.start;
var cont = true;
while (cont) {
cont = (token.string.charAt(0) == ".");
useIdentifierQuotes = useIdentifierQuotes || (token.string.charAt(0) == identifierQuote);
start = token.start;
nameParts.unshift(cleanName(token.string));
token = editor.getTokenAt(Pos(cur.line, token.start));
if (token.string == ".") {
cont = true;
token = editor.getTokenAt(Pos(cur.line, token.start));
}
}
// Try to complete table names
var string = nameParts.join(".");
addMatches(result, string, tables, function(w) {
return useIdentifierQuotes ? insertIdentifierQuotes(w) : w;
});
// Try to complete columns from defaultTable
addMatches(result, string, defaultTable, function(w) {
return useIdentifierQuotes ? insertIdentifierQuotes(w) : w;
});
// Try to complete columns
string = nameParts.pop();
var table = nameParts.join(".");
var alias = false;
var aliasTable = table;
// Check if table is available. If not, find table by Alias
if (!getTable(table)) {
var oldTable = table;
table = findTableByAlias(table, editor);
if (table !== oldTable) alias = true;
}
var columns = getTable(table);
if (columns && columns.columns)
columns = columns.columns;
if (columns) {
addMatches(result, string, columns, function(w) {
var tableInsert = table;
if (alias == true) tableInsert = aliasTable;
if (typeof w == "string") {
w = tableInsert + "." + w;
} else {
w = shallowClone(w);
w.text = tableInsert + "." + w.text;
}
return useIdentifierQuotes ? insertIdentifierQuotes(w) : w;
});
}
return start;
}
function eachWord(lineText, f) {
var words = lineText.split(/\s+/)
for (var i = 0; i < words.length; i++)
if (words[i]) f(words[i].replace(/[,;]/g, ''))
}
function findTableByAlias(alias, editor) {
var doc = editor.doc;
var fullQuery = doc.getValue();
var aliasUpperCase = alias.toUpperCase();
var previousWord = "";
var table = "";
var separator = [];
var validRange = {
start: Pos(0, 0),
end: Pos(editor.lastLine(), editor.getLineHandle(editor.lastLine()).length)
};
//add separator
var indexOfSeparator = fullQuery.indexOf(CONS.QUERY_DIV);
while(indexOfSeparator != -1) {
separator.push(doc.posFromIndex(indexOfSeparator));
indexOfSeparator = fullQuery.indexOf(CONS.QUERY_DIV, indexOfSeparator+1);
}
separator.unshift(Pos(0, 0));
separator.push(Pos(editor.lastLine(), editor.getLineHandle(editor.lastLine()).text.length));
//find valid range
var prevItem = null;
var current = editor.getCursor()
for (var i = 0; i < separator.length; i++) {
if ((prevItem == null || cmpPos(current, prevItem) > 0) && cmpPos(current, separator[i]) <= 0) {
validRange = {start: prevItem, end: separator[i]};
break;
}
prevItem = separator[i];
}
if (validRange.start) {
var query = doc.getRange(validRange.start, validRange.end, false);
for (var i = 0; i < query.length; i++) {
var lineText = query[i];
eachWord(lineText, function(word) {
var wordUpperCase = word.toUpperCase();
if (wordUpperCase === aliasUpperCase && getTable(previousWord))
table = previousWord;
if (wordUpperCase !== CONS.ALIAS_KEYWORD)
previousWord = word;
});
if (table) break;
}
}
return table;
}
CodeMirror.registerHelper("hint", "sql", function(editor, options) {
tables = parseTables(options && options.tables)
var defaultTableName = options && options.defaultTable;
var disableKeywords = options && options.disableKeywords;
defaultTable = defaultTableName && getTable(defaultTableName);
keywords = getKeywords(editor);
identifierQuote = getIdentifierQuote(editor);
if (defaultTableName && !defaultTable)
defaultTable = findTableByAlias(defaultTableName, editor);
defaultTable = defaultTable || [];
if (defaultTable.columns)
defaultTable = defaultTable.columns;
var cur = editor.getCursor();
var result = [];
var token = editor.getTokenAt(cur), start, end, search;
if (token.end > cur.ch) {
token.end = cur.ch;
token.string = token.string.slice(0, cur.ch - token.start);
}
if (token.string.match(/^[.`"\w@]\w*$/)) {
search = token.string;
start = token.start;
end = token.end;
} else {
start = end = cur.ch;
search = "";
}
if (search.charAt(0) == "." || search.charAt(0) == identifierQuote) {
start = nameCompletion(cur, token, result, editor);
} else {
var objectOrClass = function(w, className) {
if (typeof w === "object") {
w.className = className;
} else {
w = { text: w, className: className };
}
return w;
};
addMatches(result, search, defaultTable, function(w) {
return objectOrClass(w, "CodeMirror-hint-table CodeMirror-hint-default-table");
});
addMatches(
result,
search,
tables, function(w) {
return objectOrClass(w, "CodeMirror-hint-table");
}
);
if (!disableKeywords)
addMatches(result, search, keywords, function(w) {
return objectOrClass(w.toUpperCase(), "CodeMirror-hint-keyword");
});
}
return {list: result, from: Pos(cur.line, start), to: Pos(cur.line, end)};
});
});

View File

@ -1,123 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
var Pos = CodeMirror.Pos;
function matches(hint, typed, matchInMiddle) {
if (matchInMiddle) return hint.indexOf(typed) >= 0;
else return hint.lastIndexOf(typed, 0) == 0;
}
function getHints(cm, options) {
var tags = options && options.schemaInfo;
var quote = (options && options.quoteChar) || '"';
var matchInMiddle = options && options.matchInMiddle;
if (!tags) return;
var cur = cm.getCursor(), token = cm.getTokenAt(cur);
if (token.end > cur.ch) {
token.end = cur.ch;
token.string = token.string.slice(0, cur.ch - token.start);
}
var inner = CodeMirror.innerMode(cm.getMode(), token.state);
if (!inner.mode.xmlCurrentTag) return
var result = [], replaceToken = false, prefix;
var tag = /\btag\b/.test(token.type) && !/>$/.test(token.string);
var tagName = tag && /^\w/.test(token.string), tagStart;
if (tagName) {
var before = cm.getLine(cur.line).slice(Math.max(0, token.start - 2), token.start);
var tagType = /<\/$/.test(before) ? "close" : /<$/.test(before) ? "open" : null;
if (tagType) tagStart = token.start - (tagType == "close" ? 2 : 1);
} else if (tag && token.string == "<") {
tagType = "open";
} else if (tag && token.string == "</") {
tagType = "close";
}
var tagInfo = inner.mode.xmlCurrentTag(inner.state)
if (!tag && !tagInfo || tagType) {
if (tagName)
prefix = token.string;
replaceToken = tagType;
var context = inner.mode.xmlCurrentContext ? inner.mode.xmlCurrentContext(inner.state) : []
var inner = context.length && context[context.length - 1]
var curTag = inner && tags[inner]
var childList = inner ? curTag && curTag.children : tags["!top"];
if (childList && tagType != "close") {
for (var i = 0; i < childList.length; ++i) if (!prefix || matches(childList[i], prefix, matchInMiddle))
result.push("<" + childList[i]);
} else if (tagType != "close") {
for (var name in tags)
if (tags.hasOwnProperty(name) && name != "!top" && name != "!attrs" && (!prefix || matches(name, prefix, matchInMiddle)))
result.push("<" + name);
}
if (inner && (!prefix || tagType == "close" && matches(inner, prefix, matchInMiddle)))
result.push("</" + inner + ">");
} else {
// Attribute completion
var curTag = tagInfo && tags[tagInfo.name], attrs = curTag && curTag.attrs;
var globalAttrs = tags["!attrs"];
if (!attrs && !globalAttrs) return;
if (!attrs) {
attrs = globalAttrs;
} else if (globalAttrs) { // Combine tag-local and global attributes
var set = {};
for (var nm in globalAttrs) if (globalAttrs.hasOwnProperty(nm)) set[nm] = globalAttrs[nm];
for (var nm in attrs) if (attrs.hasOwnProperty(nm)) set[nm] = attrs[nm];
attrs = set;
}
if (token.type == "string" || token.string == "=") { // A value
var before = cm.getRange(Pos(cur.line, Math.max(0, cur.ch - 60)),
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;
var n = 0;
if (/['"]/.test(token.string.charAt(0))) {
quote = token.string.charAt(0);
prefix = token.string.slice(1);
n++;
}
var len = token.string.length;
if (/['"]/.test(token.string.charAt(len - 1))) {
quote = token.string.charAt(len - 1);
prefix = token.string.substr(n, len - 2);
}
if (n) { // an opening quote
var line = cm.getLine(cur.line);
if (line.length > token.end && line.charAt(token.end) == quote) token.end++; // include a closing quote
}
replaceToken = true;
}
for (var i = 0; i < atValues.length; ++i) if (!prefix || matches(atValues[i], prefix, matchInMiddle))
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 || matches(attr, prefix, matchInMiddle)))
result.push(attr);
}
}
return {
list: result,
from: replaceToken ? Pos(cur.line, tagStart == null ? token.start : tagStart) : cur,
to: replaceToken ? Pos(cur.line, token.end) : cur
};
}
CodeMirror.registerHelper("hint", "xml", getHints);
});

View File

@ -1,47 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
// Depends on coffeelint.js from http://www.coffeelint.org/js/coffeelint.js
// declare global: coffeelint
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.registerHelper("lint", "coffeescript", function(text) {
var found = [];
if (!window.coffeelint) {
if (window.console) {
window.console.error("Error: window.coffeelint not defined, CodeMirror CoffeeScript linting cannot run.");
}
return found;
}
var parseError = function(err) {
var loc = err.lineNumber;
found.push({from: CodeMirror.Pos(loc-1, 0),
to: CodeMirror.Pos(loc, 0),
severity: err.level,
message: err.message});
};
try {
var res = coffeelint.lint(text);
for(var i = 0; i < res.length; i++) {
parseError(res[i]);
}
} catch(e) {
found.push({from: CodeMirror.Pos(e.location.first_line, 0),
to: CodeMirror.Pos(e.location.last_line, e.location.last_column),
severity: 'error',
message: e.message});
}
return found;
});
});

View File

@ -1,40 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
// Depends on csslint.js from https://github.com/stubbornella/csslint
// declare global: CSSLint
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.registerHelper("lint", "css", function(text, options) {
var found = [];
if (!window.CSSLint) {
if (window.console) {
window.console.error("Error: window.CSSLint not defined, CodeMirror CSS linting cannot run.");
}
return found;
}
var results = CSSLint.verify(text, options), messages = results.messages, message = null;
for ( var i = 0; i < messages.length; i++) {
message = messages[i];
var startLine = message.line -1, endLine = message.line -1, startCol = message.col -1, endCol = message.col;
found.push({
from: CodeMirror.Pos(startLine, startCol),
to: CodeMirror.Pos(endLine, endCol),
message: message.message,
severity : message.type
});
}
return found;
});
});

View File

@ -1,59 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
// Depends on htmlhint.js from http://htmlhint.com/js/htmlhint.js
// declare global: HTMLHint
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("htmlhint"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "htmlhint"], mod);
else // Plain browser env
mod(CodeMirror, window.HTMLHint);
})(function(CodeMirror, HTMLHint) {
"use strict";
var defaultRules = {
"tagname-lowercase": true,
"attr-lowercase": true,
"attr-value-double-quotes": true,
"doctype-first": false,
"tag-pair": true,
"spec-char-escape": true,
"id-unique": true,
"src-not-empty": true,
"attr-no-duplication": true
};
CodeMirror.registerHelper("lint", "html", function(text, options) {
var found = [];
if (HTMLHint && !HTMLHint.verify) {
if(typeof HTMLHint.default !== 'undefined') {
HTMLHint = HTMLHint.default;
} else {
HTMLHint = HTMLHint.HTMLHint;
}
}
if (!HTMLHint) HTMLHint = window.HTMLHint;
if (!HTMLHint) {
if (window.console) {
window.console.error("Error: HTMLHint not found, not defined on window, or not available through define/require, CodeMirror HTML linting cannot run.");
}
return found;
}
var messages = HTMLHint.verify(text, options && options.rules || defaultRules);
for (var i = 0; i < messages.length; i++) {
var message = messages[i];
var startLine = message.line - 1, endLine = message.line - 1, startCol = message.col - 1, endCol = message.col;
found.push({
from: CodeMirror.Pos(startLine, startCol),
to: CodeMirror.Pos(endLine, endCol),
message: message.message,
severity : message.type
});
}
return found;
});
});

View File

@ -1,63 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
// declare global: JSHINT
function validator(text, options) {
if (!window.JSHINT) {
if (window.console) {
window.console.error("Error: window.JSHINT not defined, CodeMirror JavaScript linting cannot run.");
}
return [];
}
if (!options.indent) // JSHint error.character actually is a column index, this fixes underlining on lines using tabs for indentation
options.indent = 1; // JSHint default value is 4
JSHINT(text, options, options.globals);
var errors = JSHINT.data().errors, result = [];
if (errors) parseErrors(errors, result);
return result;
}
CodeMirror.registerHelper("lint", "javascript", validator);
function parseErrors(errors, output) {
for ( var i = 0; i < errors.length; i++) {
var error = errors[i];
if (error) {
if (error.line <= 0) {
if (window.console) {
window.console.warn("Cannot display JSHint error (invalid line " + error.line + ")", error);
}
continue;
}
var start = error.character - 1, end = start + 1;
if (error.evidence) {
var index = error.evidence.substring(start).search(/.\b/);
if (index > -1) {
end += index;
}
}
// Convert to format expected by validation service
var hint = {
message: error.reason,
severity: error.code ? (error.code.startsWith('W') ? "warning" : "error") : "error",
from: CodeMirror.Pos(error.line - 1, start),
to: CodeMirror.Pos(error.line - 1, end)
};
output.push(hint);
}
}
}
});

View File

@ -1,40 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
// Depends on jsonlint.js from https://github.com/zaach/jsonlint
// declare global: jsonlint
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.registerHelper("lint", "json", function(text) {
var found = [];
if (!window.jsonlint) {
if (window.console) {
window.console.error("Error: window.jsonlint not defined, CodeMirror JSON linting cannot run.");
}
return found;
}
// for jsonlint's web dist jsonlint is exported as an object with a single property parser, of which parseError
// is a subproperty
var jsonlint = window.jsonlint.parser || window.jsonlint
jsonlint.parseError = function(str, hash) {
var loc = hash.loc;
found.push({from: CodeMirror.Pos(loc.first_line - 1, loc.first_column),
to: CodeMirror.Pos(loc.last_line - 1, loc.last_column),
message: str});
};
try { jsonlint.parse(text); }
catch(e) {}
return found;
});
});

View File

@ -1,73 +0,0 @@
/* The lint marker gutter */
.CodeMirror-lint-markers {
width: 16px;
}
.CodeMirror-lint-tooltip {
background-color: #ffd;
border: 1px solid black;
border-radius: 4px 4px 4px 4px;
color: black;
font-family: monospace;
font-size: 10pt;
overflow: hidden;
padding: 2px 5px;
position: fixed;
white-space: pre;
white-space: pre-wrap;
z-index: 100;
max-width: 600px;
opacity: 0;
transition: opacity .4s;
-moz-transition: opacity .4s;
-webkit-transition: opacity .4s;
-o-transition: opacity .4s;
-ms-transition: opacity .4s;
}
.CodeMirror-lint-mark-error, .CodeMirror-lint-mark-warning {
background-position: left bottom;
background-repeat: repeat-x;
}
.CodeMirror-lint-mark-error {
background-image:
url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAYAAAC09K7GAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sJDw4cOCW1/KIAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAHElEQVQI12NggIL/DAz/GdA5/xkY/qPKMDAwAADLZwf5rvm+LQAAAABJRU5ErkJggg==")
;
}
.CodeMirror-lint-mark-warning {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAYAAAC09K7GAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sJFhQXEbhTg7YAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAMklEQVQI12NkgIIvJ3QXMjAwdDN+OaEbysDA4MPAwNDNwMCwiOHLCd1zX07o6kBVGQEAKBANtobskNMAAAAASUVORK5CYII=");
}
.CodeMirror-lint-marker-error, .CodeMirror-lint-marker-warning {
background-position: center center;
background-repeat: no-repeat;
cursor: pointer;
display: inline-block;
height: 16px;
width: 16px;
vertical-align: middle;
position: relative;
}
.CodeMirror-lint-message-error, .CodeMirror-lint-message-warning {
padding-left: 18px;
background-position: top left;
background-repeat: no-repeat;
}
.CodeMirror-lint-marker-error, .CodeMirror-lint-message-error {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAHlBMVEW7AAC7AACxAAC7AAC7AAAAAAC4AAC5AAD///+7AAAUdclpAAAABnRSTlMXnORSiwCK0ZKSAAAATUlEQVR42mWPOQ7AQAgDuQLx/z8csYRmPRIFIwRGnosRrpamvkKi0FTIiMASR3hhKW+hAN6/tIWhu9PDWiTGNEkTtIOucA5Oyr9ckPgAWm0GPBog6v4AAAAASUVORK5CYII=");
}
.CodeMirror-lint-marker-warning, .CodeMirror-lint-message-warning {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAANlBMVEX/uwDvrwD/uwD/uwD/uwD/uwD/uwD/uwD/uwD6twD/uwAAAADurwD2tQD7uAD+ugAAAAD/uwDhmeTRAAAADHRSTlMJ8mN1EYcbmiixgACm7WbuAAAAVklEQVR42n3PUQqAIBBFUU1LLc3u/jdbOJoW1P08DA9Gba8+YWJ6gNJoNYIBzAA2chBth5kLmG9YUoG0NHAUwFXwO9LuBQL1giCQb8gC9Oro2vp5rncCIY8L8uEx5ZkAAAAASUVORK5CYII=");
}
.CodeMirror-lint-marker-multiple {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAMAAADzjKfhAAAACVBMVEUAAAAAAAC/v7914kyHAAAAAXRSTlMAQObYZgAAACNJREFUeNo1ioEJAAAIwmz/H90iFFSGJgFMe3gaLZ0od+9/AQZ0ADosbYraAAAAAElFTkSuQmCC");
background-repeat: no-repeat;
background-position: right bottom;
width: 100%; height: 100%;
}

View File

@ -1,252 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
var GUTTER_ID = "CodeMirror-lint-markers";
function showTooltip(e, content) {
var tt = document.createElement("div");
tt.className = "CodeMirror-lint-tooltip";
tt.appendChild(content.cloneNode(true));
document.body.appendChild(tt);
function position(e) {
if (!tt.parentNode) return CodeMirror.off(document, "mousemove", position);
tt.style.top = Math.max(0, e.clientY - tt.offsetHeight - 5) + "px";
tt.style.left = (e.clientX + 5) + "px";
}
CodeMirror.on(document, "mousemove", position);
position(e);
if (tt.style.opacity != null) tt.style.opacity = 1;
return tt;
}
function rm(elt) {
if (elt.parentNode) elt.parentNode.removeChild(elt);
}
function hideTooltip(tt) {
if (!tt.parentNode) return;
if (tt.style.opacity == null) rm(tt);
tt.style.opacity = 0;
setTimeout(function() { rm(tt); }, 600);
}
function showTooltipFor(e, content, node) {
var tooltip = showTooltip(e, content);
function hide() {
CodeMirror.off(node, "mouseout", hide);
if (tooltip) { hideTooltip(tooltip); tooltip = null; }
}
var poll = setInterval(function() {
if (tooltip) for (var n = node;; n = n.parentNode) {
if (n && n.nodeType == 11) n = n.host;
if (n == document.body) return;
if (!n) { hide(); break; }
}
if (!tooltip) return clearInterval(poll);
}, 400);
CodeMirror.on(node, "mouseout", hide);
}
function LintState(cm, options, hasGutter) {
this.marked = [];
this.options = options;
this.timeout = null;
this.hasGutter = hasGutter;
this.onMouseOver = function(e) { onMouseOver(cm, e); };
this.waitingFor = 0
}
function parseOptions(_cm, options) {
if (options instanceof Function) return {getAnnotations: options};
if (!options || options === true) options = {};
return options;
}
function clearMarks(cm) {
var state = cm.state.lint;
if (state.hasGutter) cm.clearGutter(GUTTER_ID);
for (var i = 0; i < state.marked.length; ++i)
state.marked[i].clear();
state.marked.length = 0;
}
function makeMarker(labels, severity, multiple, tooltips) {
var marker = document.createElement("div"), inner = marker;
marker.className = "CodeMirror-lint-marker-" + severity;
if (multiple) {
inner = marker.appendChild(document.createElement("div"));
inner.className = "CodeMirror-lint-marker-multiple";
}
if (tooltips != false) CodeMirror.on(inner, "mouseover", function(e) {
showTooltipFor(e, labels, inner);
});
return marker;
}
function getMaxSeverity(a, b) {
if (a == "error") return a;
else return b;
}
function groupByLine(annotations) {
var lines = [];
for (var i = 0; i < annotations.length; ++i) {
var ann = annotations[i], line = ann.from.line;
(lines[line] || (lines[line] = [])).push(ann);
}
return lines;
}
function annotationTooltip(ann) {
var severity = ann.severity;
if (!severity) severity = "error";
var tip = document.createElement("div");
tip.className = "CodeMirror-lint-message-" + severity;
if (typeof ann.messageHTML != 'undefined') {
tip.innerHTML = ann.messageHTML;
} else {
tip.appendChild(document.createTextNode(ann.message));
}
return tip;
}
function lintAsync(cm, getAnnotations, passOptions) {
var state = cm.state.lint
var id = ++state.waitingFor
function abort() {
id = -1
cm.off("change", abort)
}
cm.on("change", abort)
getAnnotations(cm.getValue(), function(annotations, arg2) {
cm.off("change", abort)
if (state.waitingFor != id) return
if (arg2 && annotations instanceof CodeMirror) annotations = arg2
cm.operation(function() {updateLinting(cm, annotations)})
}, passOptions, cm);
}
function startLinting(cm) {
var state = cm.state.lint, options = state.options;
/*
* Passing rules in `options` property prevents JSHint (and other linters) from complaining
* about unrecognized rules like `onUpdateLinting`, `delay`, `lintOnChange`, etc.
*/
var passOptions = options.options || options;
var getAnnotations = options.getAnnotations || cm.getHelper(CodeMirror.Pos(0, 0), "lint");
if (!getAnnotations) return;
if (options.async || getAnnotations.async) {
lintAsync(cm, getAnnotations, passOptions)
} else {
var annotations = getAnnotations(cm.getValue(), passOptions, cm);
if (!annotations) return;
if (annotations.then) annotations.then(function(issues) {
cm.operation(function() {updateLinting(cm, issues)})
});
else cm.operation(function() {updateLinting(cm, annotations)})
}
}
function updateLinting(cm, annotationsNotSorted) {
clearMarks(cm);
var state = cm.state.lint, options = state.options;
var annotations = groupByLine(annotationsNotSorted);
for (var line = 0; line < annotations.length; ++line) {
var anns = annotations[line];
if (!anns) continue;
var maxSeverity = null;
var tipLabel = state.hasGutter && document.createDocumentFragment();
for (var i = 0; i < anns.length; ++i) {
var ann = anns[i];
var severity = ann.severity;
if (!severity) severity = "error";
maxSeverity = getMaxSeverity(maxSeverity, severity);
if (options.formatAnnotation) ann = options.formatAnnotation(ann);
if (state.hasGutter) tipLabel.appendChild(annotationTooltip(ann));
if (ann.to) state.marked.push(cm.markText(ann.from, ann.to, {
className: "CodeMirror-lint-mark-" + severity,
__annotation: ann
}));
}
if (state.hasGutter)
cm.setGutterMarker(line, GUTTER_ID, makeMarker(tipLabel, maxSeverity, anns.length > 1,
state.options.tooltips));
}
if (options.onUpdateLinting) options.onUpdateLinting(annotationsNotSorted, annotations, cm);
}
function onChange(cm) {
var state = cm.state.lint;
if (!state) return;
clearTimeout(state.timeout);
state.timeout = setTimeout(function(){startLinting(cm);}, state.options.delay || 500);
}
function popupTooltips(annotations, e) {
var target = e.target || e.srcElement;
var tooltip = document.createDocumentFragment();
for (var i = 0; i < annotations.length; i++) {
var ann = annotations[i];
tooltip.appendChild(annotationTooltip(ann));
}
showTooltipFor(e, tooltip, target);
}
function onMouseOver(cm, e) {
var target = e.target || e.srcElement;
if (!/\bCodeMirror-lint-mark-/.test(target.className)) return;
var box = target.getBoundingClientRect(), x = (box.left + box.right) / 2, y = (box.top + box.bottom) / 2;
var spans = cm.findMarksAt(cm.coordsChar({left: x, top: y}, "client"));
var annotations = [];
for (var i = 0; i < spans.length; ++i) {
var ann = spans[i].__annotation;
if (ann) annotations.push(ann);
}
if (annotations.length) popupTooltips(annotations, e);
}
CodeMirror.defineOption("lint", false, function(cm, val, old) {
if (old && old != CodeMirror.Init) {
clearMarks(cm);
if (cm.state.lint.options.lintOnChange !== false)
cm.off("change", onChange);
CodeMirror.off(cm.getWrapperElement(), "mouseover", cm.state.lint.onMouseOver);
clearTimeout(cm.state.lint.timeout);
delete cm.state.lint;
}
if (val) {
var gutters = cm.getOption("gutters"), hasLintGutter = false;
for (var i = 0; i < gutters.length; ++i) if (gutters[i] == GUTTER_ID) hasLintGutter = true;
var state = cm.state.lint = new LintState(cm, parseOptions(cm, val), hasLintGutter);
if (state.options.lintOnChange !== false)
cm.on("change", onChange);
if (state.options.tooltips != false && state.options.tooltips != "gutter")
CodeMirror.on(cm.getWrapperElement(), "mouseover", state.onMouseOver);
startLinting(cm);
}
});
CodeMirror.defineExtension("performLint", function() {
if (this.state.lint) startLinting(this);
});
});

View File

@ -1,41 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
// Depends on js-yaml.js from https://github.com/nodeca/js-yaml
// declare global: jsyaml
CodeMirror.registerHelper("lint", "yaml", function(text) {
var found = [];
if (!window.jsyaml) {
if (window.console) {
window.console.error("Error: window.jsyaml not defined, CodeMirror YAML linting cannot run.");
}
return found;
}
try { jsyaml.loadAll(text); }
catch(e) {
var loc = e.mark,
// js-yaml YAMLException doesn't always provide an accurate lineno
// e.g., when there are multiple yaml docs
// ---
// ---
// foo:bar
from = loc ? CodeMirror.Pos(loc.line, loc.column) : CodeMirror.Pos(0, 0),
to = from;
found.push({ from: from, to: to, message: e.message });
}
return found;
});
});

View File

@ -1,119 +0,0 @@
.CodeMirror-merge {
position: relative;
border: 1px solid #ddd;
white-space: pre;
}
.CodeMirror-merge, .CodeMirror-merge .CodeMirror {
height: 350px;
}
.CodeMirror-merge-2pane .CodeMirror-merge-pane { width: 47%; }
.CodeMirror-merge-2pane .CodeMirror-merge-gap { width: 6%; }
.CodeMirror-merge-3pane .CodeMirror-merge-pane { width: 31%; }
.CodeMirror-merge-3pane .CodeMirror-merge-gap { width: 3.5%; }
.CodeMirror-merge-pane {
display: inline-block;
white-space: normal;
vertical-align: top;
}
.CodeMirror-merge-pane-rightmost {
position: absolute;
right: 0px;
z-index: 1;
}
.CodeMirror-merge-gap {
z-index: 2;
display: inline-block;
height: 100%;
-moz-box-sizing: border-box;
box-sizing: border-box;
overflow: hidden;
border-left: 1px solid #ddd;
border-right: 1px solid #ddd;
position: relative;
background: #f8f8f8;
}
.CodeMirror-merge-scrolllock-wrap {
position: absolute;
bottom: 0; left: 50%;
}
.CodeMirror-merge-scrolllock {
position: relative;
left: -50%;
cursor: pointer;
color: #555;
line-height: 1;
}
.CodeMirror-merge-scrolllock:after {
content: "\21db\00a0\00a0\21da";
}
.CodeMirror-merge-scrolllock.CodeMirror-merge-scrolllock-enabled:after {
content: "\21db\21da";
}
.CodeMirror-merge-copybuttons-left, .CodeMirror-merge-copybuttons-right {
position: absolute;
left: 0; top: 0;
right: 0; bottom: 0;
line-height: 1;
}
.CodeMirror-merge-copy {
position: absolute;
cursor: pointer;
color: #44c;
z-index: 3;
}
.CodeMirror-merge-copy-reverse {
position: absolute;
cursor: pointer;
color: #44c;
}
.CodeMirror-merge-copybuttons-left .CodeMirror-merge-copy { left: 2px; }
.CodeMirror-merge-copybuttons-right .CodeMirror-merge-copy { right: 2px; }
.CodeMirror-merge-r-inserted, .CodeMirror-merge-l-inserted {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAACCAYAAACddGYaAAAAGUlEQVQI12MwuCXy3+CWyH8GBgYGJgYkAABZbAQ9ELXurwAAAABJRU5ErkJggg==);
background-position: bottom left;
background-repeat: repeat-x;
}
.CodeMirror-merge-r-deleted, .CodeMirror-merge-l-deleted {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAACCAYAAACddGYaAAAAGUlEQVQI12M4Kyb2/6yY2H8GBgYGJgYkAABURgPz6Ks7wQAAAABJRU5ErkJggg==);
background-position: bottom left;
background-repeat: repeat-x;
}
.CodeMirror-merge-r-chunk { background: #ffffe0; }
.CodeMirror-merge-r-chunk-start { border-top: 1px solid #ee8; }
.CodeMirror-merge-r-chunk-end { border-bottom: 1px solid #ee8; }
.CodeMirror-merge-r-connect { fill: #ffffe0; stroke: #ee8; stroke-width: 1px; }
.CodeMirror-merge-l-chunk { background: #eef; }
.CodeMirror-merge-l-chunk-start { border-top: 1px solid #88e; }
.CodeMirror-merge-l-chunk-end { border-bottom: 1px solid #88e; }
.CodeMirror-merge-l-connect { fill: #eef; stroke: #88e; stroke-width: 1px; }
.CodeMirror-merge-l-chunk.CodeMirror-merge-r-chunk { background: #dfd; }
.CodeMirror-merge-l-chunk-start.CodeMirror-merge-r-chunk-start { border-top: 1px solid #4e4; }
.CodeMirror-merge-l-chunk-end.CodeMirror-merge-r-chunk-end { border-bottom: 1px solid #4e4; }
.CodeMirror-merge-collapsed-widget:before {
content: "(...)";
}
.CodeMirror-merge-collapsed-widget {
cursor: pointer;
color: #88b;
background: #eef;
border: 1px solid #ddf;
font-size: 90%;
padding: 0 3px;
border-radius: 4px;
}
.CodeMirror-merge-collapsed-line .CodeMirror-gutter-elt { display: none; }

File diff suppressed because it is too large Load Diff

View File

@ -1,64 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), "cjs");
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], function(CM) { mod(CM, "amd"); });
else // Plain browser env
mod(CodeMirror, "plain");
})(function(CodeMirror, env) {
if (!CodeMirror.modeURL) CodeMirror.modeURL = "../mode/%N/%N.js";
var loading = {};
function splitCallback(cont, n) {
var countDown = n;
return function() { if (--countDown == 0) cont(); };
}
function ensureDeps(mode, cont) {
var deps = CodeMirror.modes[mode].dependencies;
if (!deps) return cont();
var missing = [];
for (var i = 0; i < deps.length; ++i) {
if (!CodeMirror.modes.hasOwnProperty(deps[i]))
missing.push(deps[i]);
}
if (!missing.length) return cont();
var split = splitCallback(cont, missing.length);
for (var i = 0; i < missing.length; ++i)
CodeMirror.requireMode(missing[i], split);
}
CodeMirror.requireMode = function(mode, cont) {
if (typeof mode != "string") mode = mode.name;
if (CodeMirror.modes.hasOwnProperty(mode)) return ensureDeps(mode, cont);
if (loading.hasOwnProperty(mode)) return loading[mode].push(cont);
var file = CodeMirror.modeURL.replace(/%N/g, mode);
if (env == "plain") {
var script = document.createElement("script");
script.src = file;
var others = document.getElementsByTagName("script")[0];
var list = loading[mode] = [cont];
CodeMirror.on(script, "load", function() {
ensureDeps(mode, function() {
for (var i = 0; i < list.length; ++i) list[i]();
});
});
others.parentNode.insertBefore(script, others);
} else if (env == "cjs") {
require(file);
cont();
} else if (env == "amd") {
requirejs([file], cont);
}
};
CodeMirror.autoLoadMode = function(instance, mode) {
if (!CodeMirror.modes.hasOwnProperty(mode))
CodeMirror.requireMode(mode, function() {
instance.setOption("mode", instance.getOption("mode"));
});
};
});

View File

@ -1,131 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.multiplexingMode = function(outer /*, others */) {
// Others should be {open, close, mode [, delimStyle] [, innerStyle]} objects
var others = Array.prototype.slice.call(arguments, 1);
function indexOf(string, pattern, from, returnEnd) {
if (typeof pattern == "string") {
var found = string.indexOf(pattern, from);
return returnEnd && found > -1 ? found + pattern.length : found;
}
var m = pattern.exec(from ? string.slice(from) : string);
return m ? m.index + from + (returnEnd ? m[0].length : 0) : -1;
}
return {
startState: function() {
return {
outer: CodeMirror.startState(outer),
innerActive: null,
inner: null
};
},
copyState: function(state) {
return {
outer: CodeMirror.copyState(outer, state.outer),
innerActive: state.innerActive,
inner: state.innerActive && CodeMirror.copyState(state.innerActive.mode, state.inner)
};
},
token: function(stream, state) {
if (!state.innerActive) {
var cutOff = Infinity, oldContent = stream.string;
for (var i = 0; i < others.length; ++i) {
var other = others[i];
var found = indexOf(oldContent, other.open, stream.pos);
if (found == stream.pos) {
if (!other.parseDelimiters) stream.match(other.open);
state.innerActive = other;
// Get the outer indent, making sure to handle CodeMirror.Pass
var outerIndent = 0;
if (outer.indent) {
var possibleOuterIndent = outer.indent(state.outer, "", "");
if (possibleOuterIndent !== CodeMirror.Pass) outerIndent = possibleOuterIndent;
}
state.inner = CodeMirror.startState(other.mode, outerIndent);
return other.delimStyle && (other.delimStyle + " " + other.delimStyle + "-open");
} else if (found != -1 && found < cutOff) {
cutOff = found;
}
}
if (cutOff != Infinity) stream.string = oldContent.slice(0, cutOff);
var outerToken = outer.token(stream, state.outer);
if (cutOff != Infinity) stream.string = oldContent;
return outerToken;
} else {
var curInner = state.innerActive, oldContent = stream.string;
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, curInner.parseDelimiters) : -1;
if (found == stream.pos && !curInner.parseDelimiters) {
stream.match(curInner.close);
state.innerActive = state.inner = null;
return curInner.delimStyle && (curInner.delimStyle + " " + curInner.delimStyle + "-close");
}
if (found > -1) stream.string = oldContent.slice(0, found);
var innerToken = curInner.mode.token(stream, state.inner);
if (found > -1) stream.string = oldContent;
if (found == stream.pos && curInner.parseDelimiters)
state.innerActive = state.inner = null;
if (curInner.innerStyle) {
if (innerToken) innerToken = innerToken + " " + curInner.innerStyle;
else innerToken = curInner.innerStyle;
}
return innerToken;
}
},
indent: function(state, textAfter, line) {
var mode = state.innerActive ? state.innerActive.mode : outer;
if (!mode.indent) return CodeMirror.Pass;
return mode.indent(state.innerActive ? state.inner : state.outer, textAfter, line);
},
blankLine: function(state) {
var mode = state.innerActive ? state.innerActive.mode : outer;
if (mode.blankLine) {
mode.blankLine(state.innerActive ? state.inner : state.outer);
}
if (!state.innerActive) {
for (var i = 0; i < others.length; ++i) {
var other = others[i];
if (other.open === "\n") {
state.innerActive = other;
state.inner = CodeMirror.startState(other.mode, mode.indent ? mode.indent(state.outer, "", "") : 0);
}
}
} else if (state.innerActive.close === "\n") {
state.innerActive = state.inner = null;
}
},
electricChars: outer.electricChars,
innerMode: function(state) {
return state.inner ? {state: state.inner, mode: state.innerActive.mode} : {state: state.outer, mode: outer};
}
};
};
});

View File

@ -1,33 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function() {
CodeMirror.defineMode("markdown_with_stex", function(){
var inner = CodeMirror.getMode({}, "stex");
var outer = CodeMirror.getMode({}, "markdown");
var innerOptions = {
open: '$',
close: '$',
mode: inner,
delimStyle: 'delim',
innerStyle: 'inner'
};
return CodeMirror.multiplexingMode(outer, innerOptions);
});
var mode = CodeMirror.getMode({}, "markdown_with_stex");
function MT(name) {
test.mode(
name,
mode,
Array.prototype.slice.call(arguments, 1),
'multiplexing');
}
MT(
"stexInsideMarkdown",
"[strong **Equation:**] [delim&delim-open $][inner&tag \\pi][delim&delim-close $]");
})();

View File

@ -1,90 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
// Utility function that allows modes to be combined. The mode given
// as the base argument takes care of most of the normal mode
// functionality, but a second (typically simple) mode is used, which
// can override the style of text. Both modes get to parse all of the
// text, but when both assign a non-null style to a piece of code, the
// overlay wins, unless the combine argument was true and not overridden,
// or state.overlay.combineTokens was true, in which case the styles are
// combined.
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.overlayMode = function(base, overlay, combine) {
return {
startState: function() {
return {
base: CodeMirror.startState(base),
overlay: CodeMirror.startState(overlay),
basePos: 0, baseCur: null,
overlayPos: 0, overlayCur: null,
streamSeen: null
};
},
copyState: function(state) {
return {
base: CodeMirror.copyState(base, state.base),
overlay: CodeMirror.copyState(overlay, state.overlay),
basePos: state.basePos, baseCur: null,
overlayPos: state.overlayPos, overlayCur: null
};
},
token: function(stream, state) {
if (stream != state.streamSeen ||
Math.min(state.basePos, state.overlayPos) < stream.start) {
state.streamSeen = stream;
state.basePos = state.overlayPos = stream.start;
}
if (stream.start == state.basePos) {
state.baseCur = base.token(stream, state.base);
state.basePos = stream.pos;
}
if (stream.start == state.overlayPos) {
stream.pos = stream.start;
state.overlayCur = overlay.token(stream, state.overlay);
state.overlayPos = stream.pos;
}
stream.pos = Math.min(state.basePos, state.overlayPos);
// state.overlay.combineTokens always takes precedence over combine,
// unless set to null
if (state.overlayCur == null) return state.baseCur;
else if (state.baseCur != null &&
state.overlay.combineTokens ||
combine && state.overlay.combineTokens == null)
return state.baseCur + " " + state.overlayCur;
else return state.overlayCur;
},
indent: base.indent && function(state, textAfter, line) {
return base.indent(state.base, textAfter, line);
},
electricChars: base.electricChars,
innerMode: function(state) { return {state: state.base, mode: base}; },
blankLine: function(state) {
var baseToken, overlayToken;
if (base.blankLine) baseToken = base.blankLine(state.base);
if (overlay.blankLine) overlayToken = overlay.blankLine(state.overlay);
return overlayToken == null ?
baseToken :
(combine && baseToken != null ? baseToken + " " + overlayToken : overlayToken);
}
};
};
});

View File

@ -1,216 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.defineSimpleMode = function(name, states) {
CodeMirror.defineMode(name, function(config) {
return CodeMirror.simpleMode(config, states);
});
};
CodeMirror.simpleMode = function(config, states) {
ensureState(states, "start");
var states_ = {}, meta = states.meta || {}, hasIndentation = false;
for (var state in states) if (state != meta && states.hasOwnProperty(state)) {
var list = states_[state] = [], orig = states[state];
for (var i = 0; i < orig.length; i++) {
var data = orig[i];
list.push(new Rule(data, states));
if (data.indent || data.dedent) hasIndentation = true;
}
}
var mode = {
startState: function() {
return {state: "start", pending: null,
local: null, localState: null,
indent: hasIndentation ? [] : null};
},
copyState: function(state) {
var s = {state: state.state, pending: state.pending,
local: state.local, localState: null,
indent: state.indent && state.indent.slice(0)};
if (state.localState)
s.localState = CodeMirror.copyState(state.local.mode, state.localState);
if (state.stack)
s.stack = state.stack.slice(0);
for (var pers = state.persistentStates; pers; pers = pers.next)
s.persistentStates = {mode: pers.mode,
spec: pers.spec,
state: pers.state == state.localState ? s.localState : CodeMirror.copyState(pers.mode, pers.state),
next: s.persistentStates};
return s;
},
token: tokenFunction(states_, config),
innerMode: function(state) { return state.local && {mode: state.local.mode, state: state.localState}; },
indent: indentFunction(states_, meta)
};
if (meta) for (var prop in meta) if (meta.hasOwnProperty(prop))
mode[prop] = meta[prop];
return mode;
};
function ensureState(states, name) {
if (!states.hasOwnProperty(name))
throw new Error("Undefined state " + name + " in simple mode");
}
function toRegex(val, caret) {
if (!val) return /(?:)/;
var flags = "";
if (val instanceof RegExp) {
if (val.ignoreCase) flags = "i";
val = val.source;
} else {
val = String(val);
}
return new RegExp((caret === false ? "" : "^") + "(?:" + val + ")", flags);
}
function asToken(val) {
if (!val) return null;
if (val.apply) return val
if (typeof val == "string") return val.replace(/\./g, " ");
var result = [];
for (var i = 0; i < val.length; i++)
result.push(val[i] && val[i].replace(/\./g, " "));
return result;
}
function Rule(data, states) {
if (data.next || data.push) ensureState(states, data.next || data.push);
this.regex = toRegex(data.regex);
this.token = asToken(data.token);
this.data = data;
}
function tokenFunction(states, config) {
return function(stream, state) {
if (state.pending) {
var pend = state.pending.shift();
if (state.pending.length == 0) state.pending = null;
stream.pos += pend.text.length;
return pend.token;
}
if (state.local) {
if (state.local.end && stream.match(state.local.end)) {
var tok = state.local.endToken || null;
state.local = state.localState = null;
return tok;
} else {
var tok = state.local.mode.token(stream, state.localState), m;
if (state.local.endScan && (m = state.local.endScan.exec(stream.current())))
stream.pos = stream.start + m.index;
return tok;
}
}
var curState = states[state.state];
for (var i = 0; i < curState.length; i++) {
var rule = curState[i];
var matches = (!rule.data.sol || stream.sol()) && stream.match(rule.regex);
if (matches) {
if (rule.data.next) {
state.state = rule.data.next;
} else if (rule.data.push) {
(state.stack || (state.stack = [])).push(state.state);
state.state = rule.data.push;
} else if (rule.data.pop && state.stack && state.stack.length) {
state.state = state.stack.pop();
}
if (rule.data.mode)
enterLocalMode(config, state, rule.data.mode, rule.token);
if (rule.data.indent)
state.indent.push(stream.indentation() + config.indentUnit);
if (rule.data.dedent)
state.indent.pop();
var token = rule.token
if (token && token.apply) token = token(matches)
if (matches.length > 2 && rule.token && typeof rule.token != "string") {
state.pending = [];
for (var j = 2; j < matches.length; j++)
if (matches[j])
state.pending.push({text: matches[j], token: rule.token[j - 1]});
stream.backUp(matches[0].length - (matches[1] ? matches[1].length : 0));
return token[0];
} else if (token && token.join) {
return token[0];
} else {
return token;
}
}
}
stream.next();
return null;
};
}
function cmp(a, b) {
if (a === b) return true;
if (!a || typeof a != "object" || !b || typeof b != "object") return false;
var props = 0;
for (var prop in a) if (a.hasOwnProperty(prop)) {
if (!b.hasOwnProperty(prop) || !cmp(a[prop], b[prop])) return false;
props++;
}
for (var prop in b) if (b.hasOwnProperty(prop)) props--;
return props == 0;
}
function enterLocalMode(config, state, spec, token) {
var pers;
if (spec.persistent) for (var p = state.persistentStates; p && !pers; p = p.next)
if (spec.spec ? cmp(spec.spec, p.spec) : spec.mode == p.mode) pers = p;
var mode = pers ? pers.mode : spec.mode || CodeMirror.getMode(config, spec.spec);
var lState = pers ? pers.state : CodeMirror.startState(mode);
if (spec.persistent && !pers)
state.persistentStates = {mode: mode, spec: spec.spec, state: lState, next: state.persistentStates};
state.localState = lState;
state.local = {mode: mode,
end: spec.end && toRegex(spec.end),
endScan: spec.end && spec.forceEnd !== false && toRegex(spec.end, false),
endToken: token && token.join ? token[token.length - 1] : token};
}
function indexOf(val, arr) {
for (var i = 0; i < arr.length; i++) if (arr[i] === val) return true;
}
function indentFunction(states, meta) {
return function(state, textAfter, line) {
if (state.local && state.local.mode.indent)
return state.local.mode.indent(state.localState, textAfter, line);
if (state.indent == null || state.local || meta.dontIndentStates && indexOf(state.state, meta.dontIndentStates) > -1)
return CodeMirror.Pass;
var pos = state.indent.length - 1, rules = states[state.state];
scan: for (;;) {
for (var i = 0; i < rules.length; i++) {
var rule = rules[i];
if (rule.data.dedent && rule.data.dedentIfLineStart !== false) {
var m = rule.regex.exec(textAfter);
if (m && m[0]) {
pos--;
if (rule.next || rule.push) rules = states[rule.next || rule.push];
textAfter = textAfter.slice(m[0].length);
continue scan;
}
}
}
break;
}
return pos < 0 ? 0 : state.indent[pos];
};
}
});

View File

@ -1,40 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("./runmode"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "./runmode"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
var isBlock = /^(p|li|div|h\\d|pre|blockquote|td)$/;
function textContent(node, out) {
if (node.nodeType == 3) return out.push(node.nodeValue);
for (var ch = node.firstChild; ch; ch = ch.nextSibling) {
textContent(ch, out);
if (isBlock.test(node.nodeType)) out.push("\n");
}
}
CodeMirror.colorize = function(collection, defaultMode) {
if (!collection) collection = document.body.getElementsByTagName("pre");
for (var i = 0; i < collection.length; ++i) {
var node = collection[i];
var mode = node.getAttribute("data-lang") || defaultMode;
if (!mode) continue;
var text = [];
textContent(node, text);
node.innerHTML = "";
CodeMirror.runMode(text.join(""), mode, node);
node.className += " cm-s-default";
}
};
});

View File

@ -1,158 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
window.CodeMirror = {};
(function() {
"use strict";
function splitLines(string){ return string.split(/\r?\n|\r/); };
function StringStream(string) {
this.pos = this.start = 0;
this.string = string;
this.lineStart = 0;
}
StringStream.prototype = {
eol: function() {return this.pos >= this.string.length;},
sol: function() {return this.pos == 0;},
peek: function() {return this.string.charAt(this.pos) || null;},
next: function() {
if (this.pos < this.string.length)
return this.string.charAt(this.pos++);
},
eat: function(match) {
var ch = this.string.charAt(this.pos);
if (typeof match == "string") var ok = ch == match;
else var ok = ch && (match.test ? match.test(ch) : match(ch));
if (ok) {++this.pos; return ch;}
},
eatWhile: function(match) {
var start = this.pos;
while (this.eat(match)){}
return this.pos > start;
},
eatSpace: function() {
var start = this.pos;
while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos;
return this.pos > start;
},
skipToEnd: function() {this.pos = this.string.length;},
skipTo: function(ch) {
var found = this.string.indexOf(ch, this.pos);
if (found > -1) {this.pos = found; return true;}
},
backUp: function(n) {this.pos -= n;},
column: function() {return this.start - this.lineStart;},
indentation: function() {return 0;},
match: function(pattern, consume, caseInsensitive) {
if (typeof pattern == "string") {
var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;};
var substr = this.string.substr(this.pos, pattern.length);
if (cased(substr) == cased(pattern)) {
if (consume !== false) this.pos += pattern.length;
return true;
}
} else {
var match = this.string.slice(this.pos).match(pattern);
if (match && match.index > 0) return null;
if (match && consume !== false) this.pos += match[0].length;
return match;
}
},
current: function(){return this.string.slice(this.start, this.pos);},
hideFirstChars: function(n, inner) {
this.lineStart += n;
try { return inner(); }
finally { this.lineStart -= n; }
},
lookAhead: function() { return null }
};
CodeMirror.StringStream = StringStream;
CodeMirror.startState = function (mode, a1, a2) {
return mode.startState ? mode.startState(a1, a2) : true;
};
var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.mimeModes = {};
CodeMirror.defineMode = function (name, mode) {
if (arguments.length > 2)
mode.dependencies = Array.prototype.slice.call(arguments, 2);
modes[name] = mode;
};
CodeMirror.defineMIME = function (mime, spec) { mimeModes[mime] = spec; };
CodeMirror.resolveMode = function(spec) {
if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) {
spec = mimeModes[spec];
} else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) {
spec = mimeModes[spec.name];
}
if (typeof spec == "string") return {name: spec};
else return spec || {name: "null"};
};
CodeMirror.getMode = function (options, spec) {
spec = CodeMirror.resolveMode(spec);
var mfactory = modes[spec.name];
if (!mfactory) throw new Error("Unknown mode: " + spec);
return mfactory(options, spec);
};
CodeMirror.registerHelper = CodeMirror.registerGlobalHelper = Math.min;
CodeMirror.defineMode("null", function() {
return {token: function(stream) {stream.skipToEnd();}};
});
CodeMirror.defineMIME("text/plain", "null");
CodeMirror.runMode = function (string, modespec, callback, options) {
var mode = CodeMirror.getMode({ indentUnit: 2 }, modespec);
if (callback.nodeType == 1) {
var tabSize = (options && options.tabSize) || 4;
var node = callback, col = 0;
node.innerHTML = "";
callback = function (text, style) {
if (text == "\n") {
node.appendChild(document.createElement("br"));
col = 0;
return;
}
var content = "";
// replace tabs
for (var pos = 0; ;) {
var idx = text.indexOf("\t", pos);
if (idx == -1) {
content += text.slice(pos);
col += text.length - pos;
break;
} else {
col += idx - pos;
content += text.slice(pos, idx);
var size = tabSize - col % tabSize;
col += size;
for (var i = 0; i < size; ++i) content += " ";
pos = idx + 1;
}
}
if (style) {
var sp = node.appendChild(document.createElement("span"));
sp.className = "cm-" + style.replace(/ +/g, " cm-");
sp.appendChild(document.createTextNode(content));
} else {
node.appendChild(document.createTextNode(content));
}
};
}
var lines = splitLines(string), state = (options && options.state) || CodeMirror.startState(mode);
for (var i = 0, e = lines.length; i < e; ++i) {
if (i) callback("\n");
var stream = new CodeMirror.StringStream(lines[i]);
if (!stream.string && mode.blankLine) mode.blankLine(state);
while (!stream.eol()) {
var style = mode.token(stream, state);
callback(stream.current(), style, i, stream.start, state);
stream.start = stream.pos;
}
}
};
})();

View File

@ -1,72 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.runMode = function(string, modespec, callback, options) {
var mode = CodeMirror.getMode(CodeMirror.defaults, modespec);
var ie = /MSIE \d/.test(navigator.userAgent);
var ie_lt9 = ie && (document.documentMode == null || document.documentMode < 9);
if (callback.appendChild) {
var tabSize = (options && options.tabSize) || CodeMirror.defaults.tabSize;
var node = callback, col = 0;
node.innerHTML = "";
callback = function(text, style) {
if (text == "\n") {
// Emitting LF or CRLF on IE8 or earlier results in an incorrect display.
// Emitting a carriage return makes everything ok.
node.appendChild(document.createTextNode(ie_lt9 ? '\r' : text));
col = 0;
return;
}
var content = "";
// replace tabs
for (var pos = 0;;) {
var idx = text.indexOf("\t", pos);
if (idx == -1) {
content += text.slice(pos);
col += text.length - pos;
break;
} else {
col += idx - pos;
content += text.slice(pos, idx);
var size = tabSize - col % tabSize;
col += size;
for (var i = 0; i < size; ++i) content += " ";
pos = idx + 1;
}
}
if (style) {
var sp = node.appendChild(document.createElement("span"));
sp.className = "cm-" + style.replace(/ +/g, " cm-");
sp.appendChild(document.createTextNode(content));
} else {
node.appendChild(document.createTextNode(content));
}
};
}
var lines = CodeMirror.splitLines(string), state = (options && options.state) || CodeMirror.startState(mode);
for (var i = 0, e = lines.length; i < e; ++i) {
if (i) callback("\n");
var stream = new CodeMirror.StringStream(lines[i]);
if (!stream.string && mode.blankLine) mode.blankLine(state);
while (!stream.eol()) {
var style = mode.token(stream, state);
callback(stream.current(), style, i, stream.start, state);
stream.start = stream.pos;
}
}
};
});

View File

@ -1,197 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
/* Just enough of CodeMirror to run runMode under node.js */
function splitLines(string){return string.split(/\r\n?|\n/);};
// Counts the column offset in a string, taking tabs into account.
// Used mostly to find indentation.
var countColumn = exports.countColumn = function(string, end, tabSize, startIndex, startValue) {
if (end == null) {
end = string.search(/[^\s\u00a0]/);
if (end == -1) end = string.length;
}
for (var i = startIndex || 0, n = startValue || 0;;) {
var nextTab = string.indexOf("\t", i);
if (nextTab < 0 || nextTab >= end)
return n + (end - i);
n += nextTab - i;
n += tabSize - (n % tabSize);
i = nextTab + 1;
}
};
function StringStream(string, tabSize, context) {
this.pos = this.start = 0;
this.string = string;
this.tabSize = tabSize || 8;
this.lastColumnPos = this.lastColumnValue = 0;
this.lineStart = 0;
this.context = context
};
StringStream.prototype = {
eol: function() {return this.pos >= this.string.length;},
sol: function() {return this.pos == this.lineStart;},
peek: function() {return this.string.charAt(this.pos) || undefined;},
next: function() {
if (this.pos < this.string.length)
return this.string.charAt(this.pos++);
},
eat: function(match) {
var ch = this.string.charAt(this.pos);
if (typeof match == "string") var ok = ch == match;
else var ok = ch && (match.test ? match.test(ch) : match(ch));
if (ok) {++this.pos; return ch;}
},
eatWhile: function(match) {
var start = this.pos;
while (this.eat(match)){}
return this.pos > start;
},
eatSpace: function() {
var start = this.pos;
while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos;
return this.pos > start;
},
skipToEnd: function() {this.pos = this.string.length;},
skipTo: function(ch) {
var found = this.string.indexOf(ch, this.pos);
if (found > -1) {this.pos = found; return true;}
},
backUp: function(n) {this.pos -= n;},
column: function() {
if (this.lastColumnPos < this.start) {
this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue);
this.lastColumnPos = this.start;
}
return this.lastColumnValue - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0);
},
indentation: function() {
return countColumn(this.string, null, this.tabSize) -
(this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0);
},
match: function(pattern, consume, caseInsensitive) {
if (typeof pattern == "string") {
var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;};
var substr = this.string.substr(this.pos, pattern.length);
if (cased(substr) == cased(pattern)) {
if (consume !== false) this.pos += pattern.length;
return true;
}
} else {
var match = this.string.slice(this.pos).match(pattern);
if (match && match.index > 0) return null;
if (match && consume !== false) this.pos += match[0].length;
return match;
}
},
current: function(){return this.string.slice(this.start, this.pos);},
hideFirstChars: function(n, inner) {
this.lineStart += n;
try { return inner(); }
finally { this.lineStart -= n; }
},
lookAhead: function(n) {
var line = this.context.line + n
return line >= this.context.lines.length ? null : this.context.lines[line]
}
};
exports.StringStream = StringStream;
exports.startState = function(mode, a1, a2) {
return mode.startState ? mode.startState(a1, a2) : true;
};
var modes = exports.modes = {}, mimeModes = exports.mimeModes = {};
exports.defineMode = function(name, mode) {
if (arguments.length > 2)
mode.dependencies = Array.prototype.slice.call(arguments, 2);
modes[name] = mode;
};
exports.defineMIME = function(mime, spec) { mimeModes[mime] = spec; };
exports.defineMode("null", function() {
return {token: function(stream) {stream.skipToEnd();}};
});
exports.defineMIME("text/plain", "null");
exports.resolveMode = function(spec) {
if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) {
spec = mimeModes[spec];
} else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) {
spec = mimeModes[spec.name];
}
if (typeof spec == "string") return {name: spec};
else return spec || {name: "null"};
};
function copyObj(obj, target, overwrite) {
if (!target) target = {};
for (var prop in obj)
if (obj.hasOwnProperty(prop) && (overwrite !== false || !target.hasOwnProperty(prop)))
target[prop] = obj[prop];
return target;
}
// This can be used to attach properties to mode objects from
// outside the actual mode definition.
var modeExtensions = exports.modeExtensions = {};
exports.extendMode = function(mode, properties) {
var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {});
copyObj(properties, exts);
};
exports.getMode = function(options, spec) {
var spec = exports.resolveMode(spec);
var mfactory = modes[spec.name];
if (!mfactory) return exports.getMode(options, "text/plain");
var modeObj = mfactory(options, spec);
if (modeExtensions.hasOwnProperty(spec.name)) {
var exts = modeExtensions[spec.name];
for (var prop in exts) {
if (!exts.hasOwnProperty(prop)) continue;
if (modeObj.hasOwnProperty(prop)) modeObj["_" + prop] = modeObj[prop];
modeObj[prop] = exts[prop];
}
}
modeObj.name = spec.name;
if (spec.helperType) modeObj.helperType = spec.helperType;
if (spec.modeProps) for (var prop in spec.modeProps)
modeObj[prop] = spec.modeProps[prop];
return modeObj;
};
exports.innerMode = function(mode, state) {
var info;
while (mode.innerMode) {
info = mode.innerMode(state);
if (!info || info.mode == mode) break;
state = info.state;
mode = info.mode;
}
return info || {mode: mode, state: state};
}
exports.registerHelper = exports.registerGlobalHelper = Math.min;
exports.runMode = function(string, modespec, callback, options) {
var mode = exports.getMode({indentUnit: 2}, modespec);
var lines = splitLines(string), state = (options && options.state) || exports.startState(mode);
var context = {lines: lines, line: 0}
for (var i = 0, e = lines.length; i < e; ++i, ++context.line) {
if (i) callback("\n");
var stream = new exports.StringStream(lines[i], 4, context);
if (!stream.string && mode.blankLine) mode.blankLine(state);
while (!stream.eol()) {
var style = mode.token(stream, state);
callback(stream.current(), style, i, stream.start, state);
stream.start = stream.pos;
}
}
};
require.cache[require.resolve("../../lib/codemirror")] = require.cache[require.resolve("./runmode.node")];
require.cache[require.resolve("../../addon/runmode/runmode")] = require.cache[require.resolve("./runmode.node")];

View File

@ -1,122 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.defineExtension("annotateScrollbar", function(options) {
if (typeof options == "string") options = {className: options};
return new Annotation(this, options);
});
CodeMirror.defineOption("scrollButtonHeight", 0);
function Annotation(cm, options) {
this.cm = cm;
this.options = options;
this.buttonHeight = options.scrollButtonHeight || cm.getOption("scrollButtonHeight");
this.annotations = [];
this.doRedraw = this.doUpdate = null;
this.div = cm.getWrapperElement().appendChild(document.createElement("div"));
this.div.style.cssText = "position: absolute; right: 0; top: 0; z-index: 7; pointer-events: none";
this.computeScale();
function scheduleRedraw(delay) {
clearTimeout(self.doRedraw);
self.doRedraw = setTimeout(function() { self.redraw(); }, delay);
}
var self = this;
cm.on("refresh", this.resizeHandler = function() {
clearTimeout(self.doUpdate);
self.doUpdate = setTimeout(function() {
if (self.computeScale()) scheduleRedraw(20);
}, 100);
});
cm.on("markerAdded", this.resizeHandler);
cm.on("markerCleared", this.resizeHandler);
if (options.listenForChanges !== false)
cm.on("changes", this.changeHandler = function() {
scheduleRedraw(250);
});
}
Annotation.prototype.computeScale = function() {
var cm = this.cm;
var hScale = (cm.getWrapperElement().clientHeight - cm.display.barHeight - this.buttonHeight * 2) /
cm.getScrollerElement().scrollHeight
if (hScale != this.hScale) {
this.hScale = hScale;
return true;
}
};
Annotation.prototype.update = function(annotations) {
this.annotations = annotations;
this.redraw();
};
Annotation.prototype.redraw = function(compute) {
if (compute !== false) this.computeScale();
var cm = this.cm, hScale = this.hScale;
var frag = document.createDocumentFragment(), anns = this.annotations;
var wrapping = cm.getOption("lineWrapping");
var singleLineH = wrapping && cm.defaultTextHeight() * 1.5;
var curLine = null, curLineObj = null;
function getY(pos, top) {
if (curLine != pos.line) {
curLine = pos.line;
curLineObj = cm.getLineHandle(curLine);
}
if ((curLineObj.widgets && curLineObj.widgets.length) ||
(wrapping && curLineObj.height > singleLineH))
return cm.charCoords(pos, "local")[top ? "top" : "bottom"];
var topY = cm.heightAtLine(curLineObj, "local");
return topY + (top ? 0 : curLineObj.height);
}
var lastLine = cm.lastLine()
if (cm.display.barWidth) for (var i = 0, nextTop; i < anns.length; i++) {
var ann = anns[i];
if (ann.to.line > lastLine) continue;
var top = nextTop || getY(ann.from, true) * hScale;
var bottom = getY(ann.to, false) * hScale;
while (i < anns.length - 1) {
if (anns[i + 1].to.line > lastLine) break;
nextTop = getY(anns[i + 1].from, true) * hScale;
if (nextTop > bottom + .9) break;
ann = anns[++i];
bottom = getY(ann.to, false) * hScale;
}
if (bottom == top) continue;
var height = Math.max(bottom - top, 3);
var elt = frag.appendChild(document.createElement("div"));
elt.style.cssText = "position: absolute; right: 0px; width: " + Math.max(cm.display.barWidth - 1, 2) + "px; top: "
+ (top + this.buttonHeight) + "px; height: " + height + "px";
elt.className = this.options.className;
if (ann.id) {
elt.setAttribute("annotation-id", ann.id);
}
}
this.div.textContent = "";
this.div.appendChild(frag);
};
Annotation.prototype.clear = function() {
this.cm.off("refresh", this.resizeHandler);
this.cm.off("markerAdded", this.resizeHandler);
this.cm.off("markerCleared", this.resizeHandler);
if (this.changeHandler) this.cm.off("changes", this.changeHandler);
this.div.parentNode.removeChild(this.div);
};
});

View File

@ -1,48 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.defineOption("scrollPastEnd", false, function(cm, val, old) {
if (old && old != CodeMirror.Init) {
cm.off("change", onChange);
cm.off("refresh", updateBottomMargin);
cm.display.lineSpace.parentNode.style.paddingBottom = "";
cm.state.scrollPastEndPadding = null;
}
if (val) {
cm.on("change", onChange);
cm.on("refresh", updateBottomMargin);
updateBottomMargin(cm);
}
});
function onChange(cm, change) {
if (CodeMirror.changeEnd(change).line == cm.lastLine())
updateBottomMargin(cm);
}
function updateBottomMargin(cm) {
var padding = "";
if (cm.lineCount() > 1) {
var totalH = cm.display.scroller.clientHeight - 30,
lastLineH = cm.getLineHandle(cm.lastLine()).height;
padding = (totalH - lastLineH) + "px";
}
if (cm.state.scrollPastEndPadding != padding) {
cm.state.scrollPastEndPadding = padding;
cm.display.lineSpace.parentNode.style.paddingBottom = padding;
cm.off("refresh", updateBottomMargin);
cm.setSize();
cm.on("refresh", updateBottomMargin);
}
}
});

View File

@ -1,66 +0,0 @@
.CodeMirror-simplescroll-horizontal div, .CodeMirror-simplescroll-vertical div {
position: absolute;
background: #ccc;
-moz-box-sizing: border-box;
box-sizing: border-box;
border: 1px solid #bbb;
border-radius: 2px;
}
.CodeMirror-simplescroll-horizontal, .CodeMirror-simplescroll-vertical {
position: absolute;
z-index: 6;
background: #eee;
}
.CodeMirror-simplescroll-horizontal {
bottom: 0; left: 0;
height: 8px;
}
.CodeMirror-simplescroll-horizontal div {
bottom: 0;
height: 100%;
}
.CodeMirror-simplescroll-vertical {
right: 0; top: 0;
width: 8px;
}
.CodeMirror-simplescroll-vertical div {
right: 0;
width: 100%;
}
.CodeMirror-overlayscroll .CodeMirror-scrollbar-filler, .CodeMirror-overlayscroll .CodeMirror-gutter-filler {
display: none;
}
.CodeMirror-overlayscroll-horizontal div, .CodeMirror-overlayscroll-vertical div {
position: absolute;
background: #bcd;
border-radius: 3px;
}
.CodeMirror-overlayscroll-horizontal, .CodeMirror-overlayscroll-vertical {
position: absolute;
z-index: 6;
}
.CodeMirror-overlayscroll-horizontal {
bottom: 0; left: 0;
height: 6px;
}
.CodeMirror-overlayscroll-horizontal div {
bottom: 0;
height: 100%;
}
.CodeMirror-overlayscroll-vertical {
right: 0; top: 0;
width: 6px;
}
.CodeMirror-overlayscroll-vertical div {
right: 0;
width: 100%;
}

View File

@ -1,152 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
function Bar(cls, orientation, scroll) {
this.orientation = orientation;
this.scroll = scroll;
this.screen = this.total = this.size = 1;
this.pos = 0;
this.node = document.createElement("div");
this.node.className = cls + "-" + orientation;
this.inner = this.node.appendChild(document.createElement("div"));
var self = this;
CodeMirror.on(this.inner, "mousedown", function(e) {
if (e.which != 1) return;
CodeMirror.e_preventDefault(e);
var axis = self.orientation == "horizontal" ? "pageX" : "pageY";
var start = e[axis], startpos = self.pos;
function done() {
CodeMirror.off(document, "mousemove", move);
CodeMirror.off(document, "mouseup", done);
}
function move(e) {
if (e.which != 1) return done();
self.moveTo(startpos + (e[axis] - start) * (self.total / self.size));
}
CodeMirror.on(document, "mousemove", move);
CodeMirror.on(document, "mouseup", done);
});
CodeMirror.on(this.node, "click", function(e) {
CodeMirror.e_preventDefault(e);
var innerBox = self.inner.getBoundingClientRect(), where;
if (self.orientation == "horizontal")
where = e.clientX < innerBox.left ? -1 : e.clientX > innerBox.right ? 1 : 0;
else
where = e.clientY < innerBox.top ? -1 : e.clientY > innerBox.bottom ? 1 : 0;
self.moveTo(self.pos + where * self.screen);
});
function onWheel(e) {
var moved = CodeMirror.wheelEventPixels(e)[self.orientation == "horizontal" ? "x" : "y"];
var oldPos = self.pos;
self.moveTo(self.pos + moved);
if (self.pos != oldPos) CodeMirror.e_preventDefault(e);
}
CodeMirror.on(this.node, "mousewheel", onWheel);
CodeMirror.on(this.node, "DOMMouseScroll", onWheel);
}
Bar.prototype.setPos = function(pos, force) {
if (pos < 0) pos = 0;
if (pos > this.total - this.screen) pos = this.total - this.screen;
if (!force && pos == this.pos) return false;
this.pos = pos;
this.inner.style[this.orientation == "horizontal" ? "left" : "top"] =
(pos * (this.size / this.total)) + "px";
return true
};
Bar.prototype.moveTo = function(pos) {
if (this.setPos(pos)) this.scroll(pos, this.orientation);
}
var minButtonSize = 10;
Bar.prototype.update = function(scrollSize, clientSize, barSize) {
var sizeChanged = this.screen != clientSize || this.total != scrollSize || this.size != barSize
if (sizeChanged) {
this.screen = clientSize;
this.total = scrollSize;
this.size = barSize;
}
var buttonSize = this.screen * (this.size / this.total);
if (buttonSize < minButtonSize) {
this.size -= minButtonSize - buttonSize;
buttonSize = minButtonSize;
}
this.inner.style[this.orientation == "horizontal" ? "width" : "height"] =
buttonSize + "px";
this.setPos(this.pos, sizeChanged);
};
function SimpleScrollbars(cls, place, scroll) {
this.addClass = cls;
this.horiz = new Bar(cls, "horizontal", scroll);
place(this.horiz.node);
this.vert = new Bar(cls, "vertical", scroll);
place(this.vert.node);
this.width = null;
}
SimpleScrollbars.prototype.update = function(measure) {
if (this.width == null) {
var style = window.getComputedStyle ? window.getComputedStyle(this.horiz.node) : this.horiz.node.currentStyle;
if (style) this.width = parseInt(style.height);
}
var width = this.width || 0;
var needsH = measure.scrollWidth > measure.clientWidth + 1;
var needsV = measure.scrollHeight > measure.clientHeight + 1;
this.vert.node.style.display = needsV ? "block" : "none";
this.horiz.node.style.display = needsH ? "block" : "none";
if (needsV) {
this.vert.update(measure.scrollHeight, measure.clientHeight,
measure.viewHeight - (needsH ? width : 0));
this.vert.node.style.bottom = needsH ? width + "px" : "0";
}
if (needsH) {
this.horiz.update(measure.scrollWidth, measure.clientWidth,
measure.viewWidth - (needsV ? width : 0) - measure.barLeft);
this.horiz.node.style.right = needsV ? width + "px" : "0";
this.horiz.node.style.left = measure.barLeft + "px";
}
return {right: needsV ? width : 0, bottom: needsH ? width : 0};
};
SimpleScrollbars.prototype.setScrollTop = function(pos) {
this.vert.setPos(pos);
};
SimpleScrollbars.prototype.setScrollLeft = function(pos) {
this.horiz.setPos(pos);
};
SimpleScrollbars.prototype.clear = function() {
var parent = this.horiz.node.parentNode;
parent.removeChild(this.horiz.node);
parent.removeChild(this.vert.node);
};
CodeMirror.scrollbarModel.simple = function(place, scroll) {
return new SimpleScrollbars("CodeMirror-simplescroll", place, scroll);
};
CodeMirror.scrollbarModel.overlay = function(place, scroll) {
return new SimpleScrollbars("CodeMirror-overlayscroll", place, scroll);
};
});

View File

@ -1,50 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
// Defines jumpToLine command. Uses dialog.js if present.
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("../dialog/dialog"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "../dialog/dialog"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
function dialog(cm, text, shortText, deflt, f) {
if (cm.openDialog) cm.openDialog(text, f, {value: deflt, selectValueOnOpen: true});
else f(prompt(shortText, deflt));
}
function getJumpDialog(cm) {
return cm.phrase("Jump to line:") + ' <input type="text" style="width: 10em" class="CodeMirror-search-field"/> <span style="color: #888" class="CodeMirror-search-hint">' + cm.phrase("(Use line:column or scroll% syntax)") + '</span>';
}
function interpretLine(cm, string) {
var num = Number(string)
if (/^[-+]/.test(string)) return cm.getCursor().line + num
else return num - 1
}
CodeMirror.commands.jumpToLine = function(cm) {
var cur = cm.getCursor();
dialog(cm, getJumpDialog(cm), cm.phrase("Jump to line:"), (cur.line + 1) + ":" + cur.ch, function(posStr) {
if (!posStr) return;
var match;
if (match = /^\s*([\+\-]?\d+)\s*\:\s*(\d+)\s*$/.exec(posStr)) {
cm.setCursor(interpretLine(cm, match[1]), Number(match[2]))
} else if (match = /^\s*([\+\-]?\d+(\.\d+)?)\%\s*/.exec(posStr)) {
var line = Math.round(cm.lineCount() * Number(match[1]) / 100);
if (/^[-+]/.test(match[1])) line = cur.line + line + 1;
cm.setCursor(line - 1, cur.ch);
} else if (match = /^\s*\:?\s*([\+\-]?\d+)\s*/.exec(posStr)) {
cm.setCursor(interpretLine(cm, match[1]), cur.ch);
}
});
};
CodeMirror.keyMap["default"]["Alt-G"] = "jumpToLine";
});

View File

@ -1,165 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
// Highlighting text that matches the selection
//
// Defines an option highlightSelectionMatches, which, when enabled,
// will style strings that match the selection throughout the
// document.
//
// The option can be set to true to simply enable it, or to a
// {minChars, style, wordsOnly, showToken, delay} object to explicitly
// configure it. minChars is the minimum amount of characters that should be
// selected for the behavior to occur, and style is the token style to
// apply to the matches. This will be prefixed by "cm-" to create an
// actual CSS class name. If wordsOnly is enabled, the matches will be
// highlighted only if the selected text is a word. showToken, when enabled,
// will cause the current token to be highlighted when nothing is selected.
// delay is used to specify how much time to wait, in milliseconds, before
// highlighting the matches. If annotateScrollbar is enabled, the occurences
// will be highlighted on the scrollbar via the matchesonscrollbar addon.
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("./matchesonscrollbar"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "./matchesonscrollbar"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
var defaults = {
style: "matchhighlight",
minChars: 2,
delay: 100,
wordsOnly: false,
annotateScrollbar: false,
showToken: false,
trim: true
}
function State(options) {
this.options = {}
for (var name in defaults)
this.options[name] = (options && options.hasOwnProperty(name) ? options : defaults)[name]
this.overlay = this.timeout = null;
this.matchesonscroll = null;
this.active = false;
}
CodeMirror.defineOption("highlightSelectionMatches", false, function(cm, val, old) {
if (old && old != CodeMirror.Init) {
removeOverlay(cm);
clearTimeout(cm.state.matchHighlighter.timeout);
cm.state.matchHighlighter = null;
cm.off("cursorActivity", cursorActivity);
cm.off("focus", onFocus)
}
if (val) {
var state = cm.state.matchHighlighter = new State(val);
if (cm.hasFocus()) {
state.active = true
highlightMatches(cm)
} else {
cm.on("focus", onFocus)
}
cm.on("cursorActivity", cursorActivity);
}
});
function cursorActivity(cm) {
var state = cm.state.matchHighlighter;
if (state.active || cm.hasFocus()) scheduleHighlight(cm, state)
}
function onFocus(cm) {
var state = cm.state.matchHighlighter
if (!state.active) {
state.active = true
scheduleHighlight(cm, state)
}
}
function scheduleHighlight(cm, state) {
clearTimeout(state.timeout);
state.timeout = setTimeout(function() {highlightMatches(cm);}, state.options.delay);
}
function addOverlay(cm, query, hasBoundary, style) {
var state = cm.state.matchHighlighter;
cm.addOverlay(state.overlay = makeOverlay(query, hasBoundary, style));
if (state.options.annotateScrollbar && cm.showMatchesOnScrollbar) {
var searchFor = hasBoundary ? new RegExp("\\b" + query.replace(/[\\\[.+*?(){|^$]/g, "\\$&") + "\\b") : query;
state.matchesonscroll = cm.showMatchesOnScrollbar(searchFor, false,
{className: "CodeMirror-selection-highlight-scrollbar"});
}
}
function removeOverlay(cm) {
var state = cm.state.matchHighlighter;
if (state.overlay) {
cm.removeOverlay(state.overlay);
state.overlay = null;
if (state.matchesonscroll) {
state.matchesonscroll.clear();
state.matchesonscroll = null;
}
}
}
function highlightMatches(cm) {
cm.operation(function() {
var state = cm.state.matchHighlighter;
removeOverlay(cm);
if (!cm.somethingSelected() && state.options.showToken) {
var re = state.options.showToken === true ? /[\w$]/ : state.options.showToken;
var cur = cm.getCursor(), line = cm.getLine(cur.line), start = cur.ch, end = start;
while (start && re.test(line.charAt(start - 1))) --start;
while (end < line.length && re.test(line.charAt(end))) ++end;
if (start < end)
addOverlay(cm, line.slice(start, end), re, state.options.style);
return;
}
var from = cm.getCursor("from"), to = cm.getCursor("to");
if (from.line != to.line) return;
if (state.options.wordsOnly && !isWord(cm, from, to)) return;
var selection = cm.getRange(from, to)
if (state.options.trim) selection = selection.replace(/^\s+|\s+$/g, "")
if (selection.length >= state.options.minChars)
addOverlay(cm, selection, false, state.options.style);
});
}
function isWord(cm, from, to) {
var str = cm.getRange(from, to);
if (str.match(/^\w+$/) !== null) {
if (from.ch > 0) {
var pos = {line: from.line, ch: from.ch - 1};
var chr = cm.getRange(pos, from);
if (chr.match(/\W/) === null) return false;
}
if (to.ch < cm.getLine(from.line).length) {
var pos = {line: to.line, ch: to.ch + 1};
var chr = cm.getRange(to, pos);
if (chr.match(/\W/) === null) return false;
}
return true;
} else return false;
}
function boundariesAround(stream, re) {
return (!stream.start || !re.test(stream.string.charAt(stream.start - 1))) &&
(stream.pos == stream.string.length || !re.test(stream.string.charAt(stream.pos)));
}
function makeOverlay(query, hasBoundary, style) {
return {token: function(stream) {
if (stream.match(query) &&
(!hasBoundary || boundariesAround(stream, hasBoundary)))
return style;
stream.next();
stream.skipTo(query.charAt(0)) || stream.skipToEnd();
}};
}
});

View File

@ -1,8 +0,0 @@
.CodeMirror-search-match {
background: gold;
border-top: 1px solid orange;
border-bottom: 1px solid orange;
-moz-box-sizing: border-box;
box-sizing: border-box;
opacity: .5;
}

View File

@ -1,97 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("./searchcursor"), require("../scroll/annotatescrollbar"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "./searchcursor", "../scroll/annotatescrollbar"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.defineExtension("showMatchesOnScrollbar", function(query, caseFold, options) {
if (typeof options == "string") options = {className: options};
if (!options) options = {};
return new SearchAnnotation(this, query, caseFold, options);
});
function SearchAnnotation(cm, query, caseFold, options) {
this.cm = cm;
this.options = options;
var annotateOptions = {listenForChanges: false};
for (var prop in options) annotateOptions[prop] = options[prop];
if (!annotateOptions.className) annotateOptions.className = "CodeMirror-search-match";
this.annotation = cm.annotateScrollbar(annotateOptions);
this.query = query;
this.caseFold = caseFold;
this.gap = {from: cm.firstLine(), to: cm.lastLine() + 1};
this.matches = [];
this.update = null;
this.findMatches();
this.annotation.update(this.matches);
var self = this;
cm.on("change", this.changeHandler = function(_cm, change) { self.onChange(change); });
}
var MAX_MATCHES = 1000;
SearchAnnotation.prototype.findMatches = function() {
if (!this.gap) return;
for (var i = 0; i < this.matches.length; i++) {
var match = this.matches[i];
if (match.from.line >= this.gap.to) break;
if (match.to.line >= this.gap.from) this.matches.splice(i--, 1);
}
var cursor = this.cm.getSearchCursor(this.query, CodeMirror.Pos(this.gap.from, 0), {caseFold: this.caseFold, multiline: this.options.multiline});
var maxMatches = this.options && this.options.maxMatches || MAX_MATCHES;
while (cursor.findNext()) {
var match = {from: cursor.from(), to: cursor.to()};
if (match.from.line >= this.gap.to) break;
this.matches.splice(i++, 0, match);
if (this.matches.length > maxMatches) break;
}
this.gap = null;
};
function offsetLine(line, changeStart, sizeChange) {
if (line <= changeStart) return line;
return Math.max(changeStart, line + sizeChange);
}
SearchAnnotation.prototype.onChange = function(change) {
var startLine = change.from.line;
var endLine = CodeMirror.changeEnd(change).line;
var sizeChange = endLine - change.to.line;
if (this.gap) {
this.gap.from = Math.min(offsetLine(this.gap.from, startLine, sizeChange), change.from.line);
this.gap.to = Math.max(offsetLine(this.gap.to, startLine, sizeChange), change.from.line);
} else {
this.gap = {from: change.from.line, to: endLine + 1};
}
if (sizeChange) for (var i = 0; i < this.matches.length; i++) {
var match = this.matches[i];
var newFrom = offsetLine(match.from.line, startLine, sizeChange);
if (newFrom != match.from.line) match.from = CodeMirror.Pos(newFrom, match.from.ch);
var newTo = offsetLine(match.to.line, startLine, sizeChange);
if (newTo != match.to.line) match.to = CodeMirror.Pos(newTo, match.to.ch);
}
clearTimeout(this.update);
var self = this;
this.update = setTimeout(function() { self.updateAfterChange(); }, 250);
};
SearchAnnotation.prototype.updateAfterChange = function() {
this.findMatches();
this.annotation.update(this.matches);
};
SearchAnnotation.prototype.clear = function() {
this.cm.off("change", this.changeHandler);
this.annotation.clear();
};
});

View File

@ -1,260 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
// Define search commands. Depends on dialog.js or another
// implementation of the openDialog method.
// Replace works a little oddly -- it will do the replace on the next
// Ctrl-G (or whatever is bound to findNext) press. You prevent a
// replace by making sure the match is no longer selected when hitting
// Ctrl-G.
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("./searchcursor"), require("../dialog/dialog"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "./searchcursor", "../dialog/dialog"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
function searchOverlay(query, caseInsensitive) {
if (typeof query == "string")
query = new RegExp(query.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"), caseInsensitive ? "gi" : "g");
else if (!query.global)
query = new RegExp(query.source, query.ignoreCase ? "gi" : "g");
return {token: function(stream) {
query.lastIndex = stream.pos;
var match = query.exec(stream.string);
if (match && match.index == stream.pos) {
stream.pos += match[0].length || 1;
return "searching";
} else if (match) {
stream.pos = match.index;
} else {
stream.skipToEnd();
}
}};
}
function SearchState() {
this.posFrom = this.posTo = this.lastQuery = this.query = null;
this.overlay = null;
}
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, {caseFold: queryCaseInsensitive(query), multiline: true});
}
function persistentDialog(cm, text, deflt, onEnter, onKeyDown) {
cm.openDialog(text, onEnter, {
value: deflt,
selectValueOnOpen: true,
closeOnEnter: false,
onClose: function() { clearSearch(cm); },
onKeyDown: onKeyDown
});
}
function dialog(cm, text, shortText, deflt, f) {
if (cm.openDialog) cm.openDialog(text, f, {value: deflt, selectValueOnOpen: true});
else f(prompt(shortText, deflt));
}
function confirmDialog(cm, text, shortText, fs) {
if (cm.openConfirm) cm.openConfirm(text, fs);
else if (confirm(shortText)) fs[0]();
}
function parseString(string) {
return string.replace(/\\([nrt\\])/g, function(match, ch) {
if (ch == "n") return "\n"
if (ch == "r") return "\r"
if (ch == "t") return "\t"
if (ch == "\\") return "\\"
return match
})
}
function parseQuery(query) {
var isRE = query.match(/^\/(.*)\/([a-z]*)$/);
if (isRE) {
try { query = new RegExp(isRE[1], isRE[2].indexOf("i") == -1 ? "" : "i"); }
catch(e) {} // Not a regular expression after all, do a string search
} else {
query = parseString(query)
}
if (typeof query == "string" ? query == "" : query.test(""))
query = /x^/;
return query;
}
function startSearch(cm, state, query) {
state.queryText = query;
state.query = parseQuery(query);
cm.removeOverlay(state.overlay, queryCaseInsensitive(state.query));
state.overlay = searchOverlay(state.query, queryCaseInsensitive(state.query));
cm.addOverlay(state.overlay);
if (cm.showMatchesOnScrollbar) {
if (state.annotate) { state.annotate.clear(); state.annotate = null; }
state.annotate = cm.showMatchesOnScrollbar(state.query, queryCaseInsensitive(state.query));
}
}
function doSearch(cm, rev, persistent, immediate) {
var state = getSearchState(cm);
if (state.query) return findNext(cm, rev);
var q = cm.getSelection() || state.lastQuery;
if (q instanceof RegExp && q.source == "x^") q = null
if (persistent && cm.openDialog) {
var hiding = null
var searchNext = function(query, event) {
CodeMirror.e_stop(event);
if (!query) return;
if (query != state.queryText) {
startSearch(cm, state, query);
state.posFrom = state.posTo = cm.getCursor();
}
if (hiding) hiding.style.opacity = 1
findNext(cm, event.shiftKey, function(_, to) {
var dialog
if (to.line < 3 && document.querySelector &&
(dialog = cm.display.wrapper.querySelector(".CodeMirror-dialog")) &&
dialog.getBoundingClientRect().bottom - 4 > cm.cursorCoords(to, "window").top)
(hiding = dialog).style.opacity = .4
})
};
persistentDialog(cm, getQueryDialog(cm), q, searchNext, function(event, query) {
var keyName = CodeMirror.keyName(event)
var extra = cm.getOption('extraKeys'), cmd = (extra && extra[keyName]) || CodeMirror.keyMap[cm.getOption("keyMap")][keyName]
if (cmd == "findNext" || cmd == "findPrev" ||
cmd == "findPersistentNext" || cmd == "findPersistentPrev") {
CodeMirror.e_stop(event);
startSearch(cm, getSearchState(cm), query);
cm.execCommand(cmd);
} else if (cmd == "find" || cmd == "findPersistent") {
CodeMirror.e_stop(event);
searchNext(query, event);
}
});
if (immediate && q) {
startSearch(cm, state, q);
findNext(cm, rev);
}
} else {
dialog(cm, getQueryDialog(cm), "Search for:", q, function(query) {
if (query && !state.query) cm.operation(function() {
startSearch(cm, state, query);
state.posFrom = state.posTo = cm.getCursor();
findNext(cm, rev);
});
});
}
}
function findNext(cm, rev, callback) {cm.operation(function() {
var state = getSearchState(cm);
var cursor = getSearchCursor(cm, state.query, rev ? state.posFrom : state.posTo);
if (!cursor.find(rev)) {
cursor = getSearchCursor(cm, state.query, rev ? CodeMirror.Pos(cm.lastLine()) : CodeMirror.Pos(cm.firstLine(), 0));
if (!cursor.find(rev)) return;
}
cm.setSelection(cursor.from(), cursor.to());
cm.scrollIntoView({from: cursor.from(), to: cursor.to()}, 20);
state.posFrom = cursor.from(); state.posTo = cursor.to();
if (callback) callback(cursor.from(), cursor.to())
});}
function clearSearch(cm) {cm.operation(function() {
var state = getSearchState(cm);
state.lastQuery = state.query;
if (!state.query) return;
state.query = state.queryText = null;
cm.removeOverlay(state.overlay);
if (state.annotate) { state.annotate.clear(); state.annotate = null; }
});}
function getQueryDialog(cm) {
return '<span class="CodeMirror-search-label">' + cm.phrase("Search:") + '</span> <input type="text" style="width: 10em" class="CodeMirror-search-field"/> <span style="color: #888" class="CodeMirror-search-hint">' + cm.phrase("(Use /re/ syntax for regexp search)") + '</span>';
}
function getReplaceQueryDialog(cm) {
return ' <input type="text" style="width: 10em" class="CodeMirror-search-field"/> <span style="color: #888" class="CodeMirror-search-hint">' + cm.phrase("(Use /re/ syntax for regexp search)") + '</span>';
}
function getReplacementQueryDialog(cm) {
return '<span class="CodeMirror-search-label">' + cm.phrase("With:") + '</span> <input type="text" style="width: 10em" class="CodeMirror-search-field"/>';
}
function getDoReplaceConfirm(cm) {
return '<span class="CodeMirror-search-label">' + cm.phrase("Replace?") + '</span> <button>' + cm.phrase("Yes") + '</button> <button>' + cm.phrase("No") + '</button> <button>' + cm.phrase("All") + '</button> <button>' + cm.phrase("Stop") + '</button> ';
}
function replaceAll(cm, query, text) {
cm.operation(function() {
for (var cursor = getSearchCursor(cm, query); cursor.findNext();) {
if (typeof query != "string") {
var match = cm.getRange(cursor.from(), cursor.to()).match(query);
cursor.replace(text.replace(/\$(\d)/g, function(_, i) {return match[i];}));
} else cursor.replace(text);
}
});
}
function replace(cm, all) {
if (cm.getOption("readOnly")) return;
var query = cm.getSelection() || getSearchState(cm).lastQuery;
var dialogText = '<span class="CodeMirror-search-label">' + (all ? cm.phrase("Replace all:") : cm.phrase("Replace:")) + '</span>';
dialog(cm, dialogText + getReplaceQueryDialog(cm), dialogText, query, function(query) {
if (!query) return;
query = parseQuery(query);
dialog(cm, getReplacementQueryDialog(cm), cm.phrase("Replace with:"), "", function(text) {
text = parseString(text)
if (all) {
replaceAll(cm, query, text)
} else {
clearSearch(cm);
var cursor = getSearchCursor(cm, query, cm.getCursor("from"));
var advance = function() {
var start = cursor.from(), match;
if (!(match = cursor.findNext())) {
cursor = getSearchCursor(cm, query);
if (!(match = cursor.findNext()) ||
(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, getDoReplaceConfirm(cm), cm.phrase("Replace?"),
[function() {doReplace(match);}, advance,
function() {replaceAll(cm, query, text)}]);
};
var doReplace = function(match) {
cursor.replace(typeof query == "string" ? text :
text.replace(/\$(\d)/g, function(_, i) {return match[i];}));
advance();
};
advance();
}
});
});
}
CodeMirror.commands.find = function(cm) {clearSearch(cm); doSearch(cm);};
CodeMirror.commands.findPersistent = function(cm) {clearSearch(cm); doSearch(cm, false, true);};
CodeMirror.commands.findPersistentNext = function(cm) {doSearch(cm, false, true, true);};
CodeMirror.commands.findPersistentPrev = function(cm) {doSearch(cm, true, true, true);};
CodeMirror.commands.findNext = doSearch;
CodeMirror.commands.findPrev = function(cm) {doSearch(cm, true);};
CodeMirror.commands.clearSearch = clearSearch;
CodeMirror.commands.replace = replace;
CodeMirror.commands.replaceAll = function(cm) {replace(cm, true);};
});

View File

@ -1,293 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"))
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod)
else // Plain browser env
mod(CodeMirror)
})(function(CodeMirror) {
"use strict"
var Pos = CodeMirror.Pos
function regexpFlags(regexp) {
var flags = regexp.flags
return flags != null ? flags : (regexp.ignoreCase ? "i" : "")
+ (regexp.global ? "g" : "")
+ (regexp.multiline ? "m" : "")
}
function ensureFlags(regexp, flags) {
var current = regexpFlags(regexp), target = current
for (var i = 0; i < flags.length; i++) if (target.indexOf(flags.charAt(i)) == -1)
target += flags.charAt(i)
return current == target ? regexp : new RegExp(regexp.source, target)
}
function maybeMultiline(regexp) {
return /\\s|\\n|\n|\\W|\\D|\[\^/.test(regexp.source)
}
function searchRegexpForward(doc, regexp, start) {
regexp = ensureFlags(regexp, "g")
for (var line = start.line, ch = start.ch, last = doc.lastLine(); line <= last; line++, ch = 0) {
regexp.lastIndex = ch
var string = doc.getLine(line), match = regexp.exec(string)
if (match)
return {from: Pos(line, match.index),
to: Pos(line, match.index + match[0].length),
match: match}
}
}
function searchRegexpForwardMultiline(doc, regexp, start) {
if (!maybeMultiline(regexp)) return searchRegexpForward(doc, regexp, start)
regexp = ensureFlags(regexp, "gm")
var string, chunk = 1
for (var line = start.line, last = doc.lastLine(); line <= last;) {
// This grows the search buffer in exponentially-sized chunks
// between matches, so that nearby matches are fast and don't
// require concatenating the whole document (in case we're
// searching for something that has tons of matches), but at the
// same time, the amount of retries is limited.
for (var i = 0; i < chunk; i++) {
if (line > last) break
var curLine = doc.getLine(line++)
string = string == null ? curLine : string + "\n" + curLine
}
chunk = chunk * 2
regexp.lastIndex = start.ch
var match = regexp.exec(string)
if (match) {
var before = string.slice(0, match.index).split("\n"), inside = match[0].split("\n")
var startLine = start.line + before.length - 1, startCh = before[before.length - 1].length
return {from: Pos(startLine, startCh),
to: Pos(startLine + inside.length - 1,
inside.length == 1 ? startCh + inside[0].length : inside[inside.length - 1].length),
match: match}
}
}
}
function lastMatchIn(string, regexp) {
var cutOff = 0, match
for (;;) {
regexp.lastIndex = cutOff
var newMatch = regexp.exec(string)
if (!newMatch) return match
match = newMatch
cutOff = match.index + (match[0].length || 1)
if (cutOff == string.length) return match
}
}
function searchRegexpBackward(doc, regexp, start) {
regexp = ensureFlags(regexp, "g")
for (var line = start.line, ch = start.ch, first = doc.firstLine(); line >= first; line--, ch = -1) {
var string = doc.getLine(line)
if (ch > -1) string = string.slice(0, ch)
var match = lastMatchIn(string, regexp)
if (match)
return {from: Pos(line, match.index),
to: Pos(line, match.index + match[0].length),
match: match}
}
}
function searchRegexpBackwardMultiline(doc, regexp, start) {
regexp = ensureFlags(regexp, "gm")
var string, chunk = 1
for (var line = start.line, first = doc.firstLine(); line >= first;) {
for (var i = 0; i < chunk; i++) {
var curLine = doc.getLine(line--)
string = string == null ? curLine.slice(0, start.ch) : curLine + "\n" + string
}
chunk *= 2
var match = lastMatchIn(string, regexp)
if (match) {
var before = string.slice(0, match.index).split("\n"), inside = match[0].split("\n")
var startLine = line + before.length, startCh = before[before.length - 1].length
return {from: Pos(startLine, startCh),
to: Pos(startLine + inside.length - 1,
inside.length == 1 ? startCh + inside[0].length : inside[inside.length - 1].length),
match: match}
}
}
}
var doFold, noFold
if (String.prototype.normalize) {
doFold = function(str) { return str.normalize("NFD").toLowerCase() }
noFold = function(str) { return str.normalize("NFD") }
} else {
doFold = function(str) { return str.toLowerCase() }
noFold = function(str) { return str }
}
// 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, foldFunc) {
if (orig.length == folded.length) return pos
for (var min = 0, max = pos + Math.max(0, orig.length - folded.length);;) {
if (min == max) return min
var mid = (min + max) >> 1
var len = foldFunc(orig.slice(0, mid)).length
if (len == pos) return mid
else if (len > pos) max = mid
else min = mid + 1
}
}
function searchStringForward(doc, query, start, caseFold) {
// Empty string would match anything and never progress, so we
// define it to match nothing instead.
if (!query.length) return null
var fold = caseFold ? doFold : noFold
var lines = fold(query).split(/\r|\n\r?/)
search: for (var line = start.line, ch = start.ch, last = doc.lastLine() + 1 - lines.length; line <= last; line++, ch = 0) {
var orig = doc.getLine(line).slice(ch), string = fold(orig)
if (lines.length == 1) {
var found = string.indexOf(lines[0])
if (found == -1) continue search
var start = adjustPos(orig, string, found, fold) + ch
return {from: Pos(line, adjustPos(orig, string, found, fold) + ch),
to: Pos(line, adjustPos(orig, string, found + lines[0].length, fold) + ch)}
} else {
var cutFrom = string.length - lines[0].length
if (string.slice(cutFrom) != lines[0]) continue search
for (var i = 1; i < lines.length - 1; i++)
if (fold(doc.getLine(line + i)) != lines[i]) continue search
var end = doc.getLine(line + lines.length - 1), endString = fold(end), lastLine = lines[lines.length - 1]
if (endString.slice(0, lastLine.length) != lastLine) continue search
return {from: Pos(line, adjustPos(orig, string, cutFrom, fold) + ch),
to: Pos(line + lines.length - 1, adjustPos(end, endString, lastLine.length, fold))}
}
}
}
function searchStringBackward(doc, query, start, caseFold) {
if (!query.length) return null
var fold = caseFold ? doFold : noFold
var lines = fold(query).split(/\r|\n\r?/)
search: for (var line = start.line, ch = start.ch, first = doc.firstLine() - 1 + lines.length; line >= first; line--, ch = -1) {
var orig = doc.getLine(line)
if (ch > -1) orig = orig.slice(0, ch)
var string = fold(orig)
if (lines.length == 1) {
var found = string.lastIndexOf(lines[0])
if (found == -1) continue search
return {from: Pos(line, adjustPos(orig, string, found, fold)),
to: Pos(line, adjustPos(orig, string, found + lines[0].length, fold))}
} else {
var lastLine = lines[lines.length - 1]
if (string.slice(0, lastLine.length) != lastLine) continue search
for (var i = 1, start = line - lines.length + 1; i < lines.length - 1; i++)
if (fold(doc.getLine(start + i)) != lines[i]) continue search
var top = doc.getLine(line + 1 - lines.length), topString = fold(top)
if (topString.slice(topString.length - lines[0].length) != lines[0]) continue search
return {from: Pos(line + 1 - lines.length, adjustPos(top, topString, top.length - lines[0].length, fold)),
to: Pos(line, adjustPos(orig, string, lastLine.length, fold))}
}
}
}
function SearchCursor(doc, query, pos, options) {
this.atOccurrence = false
this.doc = doc
pos = pos ? doc.clipPos(pos) : Pos(0, 0)
this.pos = {from: pos, to: pos}
var caseFold
if (typeof options == "object") {
caseFold = options.caseFold
} else { // Backwards compat for when caseFold was the 4th argument
caseFold = options
options = null
}
if (typeof query == "string") {
if (caseFold == null) caseFold = false
this.matches = function(reverse, pos) {
return (reverse ? searchStringBackward : searchStringForward)(doc, query, pos, caseFold)
}
} else {
query = ensureFlags(query, "gm")
if (!options || options.multiline !== false)
this.matches = function(reverse, pos) {
return (reverse ? searchRegexpBackwardMultiline : searchRegexpForwardMultiline)(doc, query, pos)
}
else
this.matches = function(reverse, pos) {
return (reverse ? searchRegexpBackward : searchRegexpForward)(doc, query, pos)
}
}
}
SearchCursor.prototype = {
findNext: function() {return this.find(false)},
findPrevious: function() {return this.find(true)},
find: function(reverse) {
var result = this.matches(reverse, this.doc.clipPos(reverse ? this.pos.from : this.pos.to))
// Implements weird auto-growing behavior on null-matches for
// backwards-compatiblity with the vim code (unfortunately)
while (result && CodeMirror.cmpPos(result.from, result.to) == 0) {
if (reverse) {
if (result.from.ch) result.from = Pos(result.from.line, result.from.ch - 1)
else if (result.from.line == this.doc.firstLine()) result = null
else result = this.matches(reverse, this.doc.clipPos(Pos(result.from.line - 1)))
} else {
if (result.to.ch < this.doc.getLine(result.to.line).length) result.to = Pos(result.to.line, result.to.ch + 1)
else if (result.to.line == this.doc.lastLine()) result = null
else result = this.matches(reverse, Pos(result.to.line + 1, 0))
}
}
if (result) {
this.pos = result
this.atOccurrence = true
return this.pos.match || true
} else {
var end = Pos(reverse ? this.doc.firstLine() : this.doc.lastLine() + 1, 0)
this.pos = {from: end, to: end}
return this.atOccurrence = false
}
},
from: function() {if (this.atOccurrence) return this.pos.from},
to: function() {if (this.atOccurrence) return this.pos.to},
replace: function(newText, origin) {
if (!this.atOccurrence) return
var lines = CodeMirror.splitLines(newText)
this.doc.replaceRange(lines, this.pos.from, this.pos.to, origin)
this.pos.to = Pos(this.pos.from.line + lines.length - 1,
lines[lines.length - 1].length + (lines.length == 1 ? this.pos.from.ch : 0))
}
}
CodeMirror.defineExtension("getSearchCursor", function(query, pos, caseFold) {
return new SearchCursor(this.doc, query, pos, caseFold)
})
CodeMirror.defineDocExtension("getSearchCursor", function(query, pos, caseFold) {
return new SearchCursor(this, query, pos, caseFold)
})
CodeMirror.defineExtension("selectMatches", function(query, caseFold) {
var ranges = []
var cur = this.getSearchCursor(query, this.getCursor("from"), caseFold)
while (cur.findNext()) {
if (CodeMirror.cmpPos(cur.to(), this.getCursor("to")) > 0) break
ranges.push({anchor: cur.from(), head: cur.to()})
}
if (ranges.length)
this.setSelections(ranges, 0)
})
});

View File

@ -1,72 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
var WRAP_CLASS = "CodeMirror-activeline";
var BACK_CLASS = "CodeMirror-activeline-background";
var GUTT_CLASS = "CodeMirror-activeline-gutter";
CodeMirror.defineOption("styleActiveLine", false, function(cm, val, old) {
var prev = old == CodeMirror.Init ? false : old;
if (val == prev) return
if (prev) {
cm.off("beforeSelectionChange", selectionChange);
clearActiveLines(cm);
delete cm.state.activeLines;
}
if (val) {
cm.state.activeLines = [];
updateActiveLines(cm, cm.listSelections());
cm.on("beforeSelectionChange", selectionChange);
}
});
function clearActiveLines(cm) {
for (var i = 0; i < cm.state.activeLines.length; i++) {
cm.removeLineClass(cm.state.activeLines[i], "wrap", WRAP_CLASS);
cm.removeLineClass(cm.state.activeLines[i], "background", BACK_CLASS);
cm.removeLineClass(cm.state.activeLines[i], "gutter", GUTT_CLASS);
}
}
function sameArray(a, b) {
if (a.length != b.length) return false;
for (var i = 0; i < a.length; i++)
if (a[i] != b[i]) return false;
return true;
}
function updateActiveLines(cm, ranges) {
var active = [];
for (var i = 0; i < ranges.length; i++) {
var range = ranges[i];
var option = cm.getOption("styleActiveLine");
if (typeof option == "object" && option.nonEmpty ? range.anchor.line != range.head.line : !range.empty())
continue
var line = cm.getLineHandleVisualStart(range.head.line);
if (active[active.length - 1] != line) active.push(line);
}
if (sameArray(cm.state.activeLines, active)) return;
cm.operation(function() {
clearActiveLines(cm);
for (var i = 0; i < active.length; i++) {
cm.addLineClass(active[i], "wrap", WRAP_CLASS);
cm.addLineClass(active[i], "background", BACK_CLASS);
cm.addLineClass(active[i], "gutter", GUTT_CLASS);
}
cm.state.activeLines = active;
});
}
function selectionChange(cm, sel) {
updateActiveLines(cm, sel.ranges);
}
});

View File

@ -1,119 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
// Because sometimes you need to mark the selected *text*.
//
// Adds an option 'styleSelectedText' which, when enabled, gives
// selected text the CSS class given as option value, or
// "CodeMirror-selectedtext" when the value is not a string.
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.defineOption("styleSelectedText", false, function(cm, val, old) {
var prev = old && old != CodeMirror.Init;
if (val && !prev) {
cm.state.markedSelection = [];
cm.state.markedSelectionStyle = typeof val == "string" ? val : "CodeMirror-selectedtext";
reset(cm);
cm.on("cursorActivity", onCursorActivity);
cm.on("change", onChange);
} else if (!val && prev) {
cm.off("cursorActivity", onCursorActivity);
cm.off("change", onChange);
clear(cm);
cm.state.markedSelection = cm.state.markedSelectionStyle = null;
}
});
function onCursorActivity(cm) {
if (cm.state.markedSelection)
cm.operation(function() { update(cm); });
}
function onChange(cm) {
if (cm.state.markedSelection && cm.state.markedSelection.length)
cm.operation(function() { clear(cm); });
}
var CHUNK_SIZE = 8;
var Pos = CodeMirror.Pos;
var cmp = CodeMirror.cmpPos;
function coverRange(cm, from, to, addAt) {
if (cmp(from, to) == 0) return;
var array = cm.state.markedSelection;
var cls = cm.state.markedSelectionStyle;
for (var line = from.line;;) {
var start = line == from.line ? from : Pos(line, 0);
var endLine = line + CHUNK_SIZE, atEnd = endLine >= to.line;
var end = atEnd ? to : Pos(endLine, 0);
var mark = cm.markText(start, end, {className: cls});
if (addAt == null) array.push(mark);
else array.splice(addAt++, 0, mark);
if (atEnd) break;
line = endLine;
}
}
function clear(cm) {
var array = cm.state.markedSelection;
for (var i = 0; i < array.length; ++i) array[i].clear();
array.length = 0;
}
function reset(cm) {
clear(cm);
var ranges = cm.listSelections();
for (var i = 0; i < ranges.length; i++)
coverRange(cm, ranges[i].from(), ranges[i].to());
}
function update(cm) {
if (!cm.somethingSelected()) return clear(cm);
if (cm.listSelections().length > 1) return reset(cm);
var from = cm.getCursor("start"), to = cm.getCursor("end");
var array = cm.state.markedSelection;
if (!array.length) return coverRange(cm, from, to);
var coverStart = array[0].find(), coverEnd = array[array.length - 1].find();
if (!coverStart || !coverEnd || to.line - from.line <= CHUNK_SIZE ||
cmp(from, coverEnd.to) >= 0 || cmp(to, coverStart.from) <= 0)
return reset(cm);
while (cmp(from, coverStart.from) > 0) {
array.shift().clear();
coverStart = array[0].find();
}
if (cmp(from, coverStart.from) < 0) {
if (coverStart.to.line - from.line < CHUNK_SIZE) {
array.shift().clear();
coverRange(cm, from, coverStart.to, 0);
} else {
coverRange(cm, from, coverStart.from, 0);
}
}
while (cmp(to, coverEnd.to) < 0) {
array.pop().clear();
coverEnd = array[array.length - 1].find();
}
if (cmp(to, coverEnd.to) > 0) {
if (to.line - coverEnd.from.line < CHUNK_SIZE) {
array.pop().clear();
coverRange(cm, coverEnd.from, to);
} else {
coverRange(cm, coverEnd.to, to);
}
}
}
});

View File

@ -1,98 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.defineOption("selectionPointer", false, function(cm, val) {
var data = cm.state.selectionPointer;
if (data) {
CodeMirror.off(cm.getWrapperElement(), "mousemove", data.mousemove);
CodeMirror.off(cm.getWrapperElement(), "mouseout", data.mouseout);
CodeMirror.off(window, "scroll", data.windowScroll);
cm.off("cursorActivity", reset);
cm.off("scroll", reset);
cm.state.selectionPointer = null;
cm.display.lineDiv.style.cursor = "";
}
if (val) {
data = cm.state.selectionPointer = {
value: typeof val == "string" ? val : "default",
mousemove: function(event) { mousemove(cm, event); },
mouseout: function(event) { mouseout(cm, event); },
windowScroll: function() { reset(cm); },
rects: null,
mouseX: null, mouseY: null,
willUpdate: false
};
CodeMirror.on(cm.getWrapperElement(), "mousemove", data.mousemove);
CodeMirror.on(cm.getWrapperElement(), "mouseout", data.mouseout);
CodeMirror.on(window, "scroll", data.windowScroll);
cm.on("cursorActivity", reset);
cm.on("scroll", reset);
}
});
function mousemove(cm, event) {
var data = cm.state.selectionPointer;
if (event.buttons == null ? event.which : event.buttons) {
data.mouseX = data.mouseY = null;
} else {
data.mouseX = event.clientX;
data.mouseY = event.clientY;
}
scheduleUpdate(cm);
}
function mouseout(cm, event) {
if (!cm.getWrapperElement().contains(event.relatedTarget)) {
var data = cm.state.selectionPointer;
data.mouseX = data.mouseY = null;
scheduleUpdate(cm);
}
}
function reset(cm) {
cm.state.selectionPointer.rects = null;
scheduleUpdate(cm);
}
function scheduleUpdate(cm) {
if (!cm.state.selectionPointer.willUpdate) {
cm.state.selectionPointer.willUpdate = true;
setTimeout(function() {
update(cm);
cm.state.selectionPointer.willUpdate = false;
}, 50);
}
}
function update(cm) {
var data = cm.state.selectionPointer;
if (!data) return;
if (data.rects == null && data.mouseX != null) {
data.rects = [];
if (cm.somethingSelected()) {
for (var sel = cm.display.selectionDiv.firstChild; sel; sel = sel.nextSibling)
data.rects.push(sel.getBoundingClientRect());
}
}
var inside = false;
if (data.mouseX != null) for (var i = 0; i < data.rects.length; i++) {
var rect = data.rects[i];
if (rect.left <= data.mouseX && rect.right >= data.mouseX &&
rect.top <= data.mouseY && rect.bottom >= data.mouseY)
inside = true;
}
var cursor = inside ? data.value : "";
if (cm.display.lineDiv.style.cursor != cursor)
cm.display.lineDiv.style.cursor = cursor;
}
});

View File

@ -1,87 +0,0 @@
.CodeMirror-Tern-completion {
padding-left: 22px;
position: relative;
line-height: 1.5;
}
.CodeMirror-Tern-completion:before {
position: absolute;
left: 2px;
bottom: 2px;
border-radius: 50%;
font-size: 12px;
font-weight: bold;
height: 15px;
width: 15px;
line-height: 16px;
text-align: center;
color: white;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.CodeMirror-Tern-completion-unknown:before {
content: "?";
background: #4bb;
}
.CodeMirror-Tern-completion-object:before {
content: "O";
background: #77c;
}
.CodeMirror-Tern-completion-fn:before {
content: "F";
background: #7c7;
}
.CodeMirror-Tern-completion-array:before {
content: "A";
background: #c66;
}
.CodeMirror-Tern-completion-number:before {
content: "1";
background: #999;
}
.CodeMirror-Tern-completion-string:before {
content: "S";
background: #999;
}
.CodeMirror-Tern-completion-bool:before {
content: "B";
background: #999;
}
.CodeMirror-Tern-completion-guess {
color: #999;
}
.CodeMirror-Tern-tooltip {
border: 1px solid silver;
border-radius: 3px;
color: #444;
padding: 2px 5px;
font-size: 90%;
font-family: monospace;
background-color: white;
white-space: pre-wrap;
max-width: 40em;
position: absolute;
z-index: 10;
-webkit-box-shadow: 2px 3px 5px rgba(0,0,0,.2);
-moz-box-shadow: 2px 3px 5px rgba(0,0,0,.2);
box-shadow: 2px 3px 5px rgba(0,0,0,.2);
transition: opacity 1s;
-moz-transition: opacity 1s;
-webkit-transition: opacity 1s;
-o-transition: opacity 1s;
-ms-transition: opacity 1s;
}
.CodeMirror-Tern-hint-doc {
max-width: 25em;
margin-top: -3px;
}
.CodeMirror-Tern-fname { color: black; }
.CodeMirror-Tern-farg { color: #70a; }
.CodeMirror-Tern-farg-current { text-decoration: underline; }
.CodeMirror-Tern-type { color: #07c; }
.CodeMirror-Tern-fhint-guess { opacity: .7; }

View File

@ -1,718 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
// Glue code between CodeMirror and Tern.
//
// Create a CodeMirror.TernServer to wrap an actual Tern server,
// register open documents (CodeMirror.Doc instances) with it, and
// call its methods to activate the assisting functions that Tern
// provides.
//
// Options supported (all optional):
// * defs: An array of JSON definition data structures.
// * plugins: An object mapping plugin names to configuration
// options.
// * getFile: A function(name, c) that can be used to access files in
// the project that haven't been loaded yet. Simply do c(null) to
// indicate that a file is not available.
// * fileFilter: A function(value, docName, doc) that will be applied
// to documents before passing them on to Tern.
// * switchToDoc: A function(name, doc) that should, when providing a
// multi-file view, switch the view or focus to the named file.
// * showError: A function(editor, message) that can be used to
// override the way errors are displayed.
// * completionTip: Customize the content in tooltips for completions.
// Is passed a single argument—the completion's data as returned by
// Tern—and may return a string, DOM node, or null to indicate that
// no tip should be shown. By default the docstring is shown.
// * typeTip: Like completionTip, but for the tooltips shown for type
// queries.
// * responseFilter: A function(doc, query, request, error, data) that
// will be applied to the Tern responses before treating them
//
//
// It is possible to run the Tern server in a web worker by specifying
// these additional options:
// * useWorker: Set to true to enable web worker mode. You'll probably
// want to feature detect the actual value you use here, for example
// !!window.Worker.
// * workerScript: The main script of the worker. Point this to
// wherever you are hosting worker.js from this directory.
// * workerDeps: An array of paths pointing (relative to workerScript)
// to the Acorn and Tern libraries and any Tern plugins you want to
// load. Or, if you minified those into a single script and included
// them in the workerScript, simply leave this undefined.
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
// declare global: tern
CodeMirror.TernServer = function(options) {
var self = this;
this.options = options || {};
var plugins = this.options.plugins || (this.options.plugins = {});
if (!plugins.doc_comment) plugins.doc_comment = true;
this.docs = Object.create(null);
if (this.options.useWorker) {
this.server = new WorkerServer(this);
} else {
this.server = new tern.Server({
getFile: function(name, c) { return getFile(self, name, c); },
async: true,
defs: this.options.defs || [],
plugins: plugins
});
}
this.trackChange = function(doc, change) { trackChange(self, doc, change); };
this.cachedArgHints = null;
this.activeArgHints = null;
this.jumpStack = [];
this.getHint = function(cm, c) { return hint(self, cm, c); };
this.getHint.async = true;
};
CodeMirror.TernServer.prototype = {
addDoc: function(name, doc) {
var data = {doc: doc, name: name, changed: null};
this.server.addFile(name, docValue(this, data));
CodeMirror.on(doc, "change", this.trackChange);
return this.docs[name] = data;
},
delDoc: function(id) {
var found = resolveDoc(this, id);
if (!found) return;
CodeMirror.off(found.doc, "change", this.trackChange);
delete this.docs[found.name];
this.server.delFile(found.name);
},
hideDoc: function(id) {
closeArgHints(this);
var found = resolveDoc(this, id);
if (found && found.changed) sendDoc(this, found);
},
complete: function(cm) {
cm.showHint({hint: this.getHint});
},
showType: function(cm, pos, c) { showContextInfo(this, cm, pos, "type", c); },
showDocs: function(cm, pos, c) { showContextInfo(this, cm, pos, "documentation", c); },
updateArgHints: function(cm) { updateArgHints(this, cm); },
jumpToDef: function(cm) { jumpToDef(this, cm); },
jumpBack: function(cm) { jumpBack(this, cm); },
rename: function(cm) { rename(this, cm); },
selectName: function(cm) { selectName(this, cm); },
request: function (cm, query, c, pos) {
var self = this;
var doc = findDoc(this, cm.getDoc());
var request = buildRequest(this, doc, query, pos);
var extraOptions = request.query && this.options.queryOptions && this.options.queryOptions[request.query.type]
if (extraOptions) for (var prop in extraOptions) request.query[prop] = extraOptions[prop];
this.server.request(request, function (error, data) {
if (!error && self.options.responseFilter)
data = self.options.responseFilter(doc, query, request, error, data);
c(error, data);
});
},
destroy: function () {
closeArgHints(this)
if (this.worker) {
this.worker.terminate();
this.worker = null;
}
}
};
var Pos = CodeMirror.Pos;
var cls = "CodeMirror-Tern-";
var bigDoc = 250;
function getFile(ts, name, c) {
var buf = ts.docs[name];
if (buf)
c(docValue(ts, buf));
else if (ts.options.getFile)
ts.options.getFile(name, c);
else
c(null);
}
function findDoc(ts, doc, name) {
for (var n in ts.docs) {
var cur = ts.docs[n];
if (cur.doc == doc) return cur;
}
if (!name) for (var i = 0;; ++i) {
n = "[doc" + (i || "") + "]";
if (!ts.docs[n]) { name = n; break; }
}
return ts.addDoc(name, doc);
}
function resolveDoc(ts, id) {
if (typeof id == "string") return ts.docs[id];
if (id instanceof CodeMirror) id = id.getDoc();
if (id instanceof CodeMirror.Doc) return findDoc(ts, id);
}
function trackChange(ts, doc, change) {
var data = findDoc(ts, doc);
var argHints = ts.cachedArgHints;
if (argHints && argHints.doc == doc && cmpPos(argHints.start, change.to) >= 0)
ts.cachedArgHints = null;
var changed = data.changed;
if (changed == null)
data.changed = changed = {from: change.from.line, to: change.from.line};
var end = change.from.line + (change.text.length - 1);
if (change.from.line < changed.to) changed.to = changed.to - (change.to.line - end);
if (end >= changed.to) changed.to = end + 1;
if (changed.from > change.from.line) changed.from = change.from.line;
if (doc.lineCount() > bigDoc && change.to - changed.from > 100) setTimeout(function() {
if (data.changed && data.changed.to - data.changed.from > 100) sendDoc(ts, data);
}, 200);
}
function sendDoc(ts, doc) {
ts.server.request({files: [{type: "full", name: doc.name, text: docValue(ts, doc)}]}, function(error) {
if (error) window.console.error(error);
else doc.changed = null;
});
}
// Completion
function hint(ts, cm, c) {
ts.request(cm, {type: "completions", types: true, docs: true, urls: true}, function(error, data) {
if (error) return showError(ts, cm, error);
var completions = [], after = "";
var from = data.start, to = data.end;
if (cm.getRange(Pos(from.line, from.ch - 2), from) == "[\"" &&
cm.getRange(to, Pos(to.line, to.ch + 2)) != "\"]")
after = "\"]";
for (var i = 0; i < data.completions.length; ++i) {
var completion = data.completions[i], className = typeToIcon(completion.type);
if (data.guess) className += " " + cls + "guess";
completions.push({text: completion.name + after,
displayText: completion.displayName || completion.name,
className: className,
data: completion});
}
var obj = {from: from, to: to, list: completions};
var tooltip = null;
CodeMirror.on(obj, "close", function() { remove(tooltip); });
CodeMirror.on(obj, "update", function() { remove(tooltip); });
CodeMirror.on(obj, "select", function(cur, node) {
remove(tooltip);
var content = ts.options.completionTip ? ts.options.completionTip(cur.data) : cur.data.doc;
if (content) {
tooltip = makeTooltip(node.parentNode.getBoundingClientRect().right + window.pageXOffset,
node.getBoundingClientRect().top + window.pageYOffset, content);
tooltip.className += " " + cls + "hint-doc";
}
});
c(obj);
});
}
function typeToIcon(type) {
var suffix;
if (type == "?") suffix = "unknown";
else if (type == "number" || type == "string" || type == "bool") suffix = type;
else if (/^fn\(/.test(type)) suffix = "fn";
else if (/^\[/.test(type)) suffix = "array";
else suffix = "object";
return cls + "completion " + cls + "completion-" + suffix;
}
// Type queries
function showContextInfo(ts, cm, pos, queryName, c) {
ts.request(cm, queryName, function(error, data) {
if (error) return showError(ts, cm, error);
if (ts.options.typeTip) {
var tip = ts.options.typeTip(data);
} else {
var tip = elt("span", null, elt("strong", null, data.type || "not found"));
if (data.doc)
tip.appendChild(document.createTextNode(" — " + data.doc));
if (data.url) {
tip.appendChild(document.createTextNode(" "));
var child = tip.appendChild(elt("a", null, "[docs]"));
child.href = data.url;
child.target = "_blank";
}
}
tempTooltip(cm, tip, ts);
if (c) c();
}, pos);
}
// Maintaining argument hints
function updateArgHints(ts, cm) {
closeArgHints(ts);
if (cm.somethingSelected()) return;
var state = cm.getTokenAt(cm.getCursor()).state;
var inner = CodeMirror.innerMode(cm.getMode(), state);
if (inner.mode.name != "javascript") return;
var lex = inner.state.lexical;
if (lex.info != "call") return;
var ch, argPos = lex.pos || 0, tabSize = cm.getOption("tabSize");
for (var line = cm.getCursor().line, e = Math.max(0, line - 9), found = false; line >= e; --line) {
var str = cm.getLine(line), extra = 0;
for (var pos = 0;;) {
var tab = str.indexOf("\t", pos);
if (tab == -1) break;
extra += tabSize - (tab + extra) % tabSize - 1;
pos = tab + 1;
}
ch = lex.column - extra;
if (str.charAt(ch) == "(") {found = true; break;}
}
if (!found) return;
var start = Pos(line, ch);
var cache = ts.cachedArgHints;
if (cache && cache.doc == cm.getDoc() && cmpPos(start, cache.start) == 0)
return showArgHints(ts, cm, argPos);
ts.request(cm, {type: "type", preferFunction: true, end: start}, function(error, data) {
if (error || !data.type || !(/^fn\(/).test(data.type)) return;
ts.cachedArgHints = {
start: start,
type: parseFnType(data.type),
name: data.exprName || data.name || "fn",
guess: data.guess,
doc: cm.getDoc()
};
showArgHints(ts, cm, argPos);
});
}
function showArgHints(ts, cm, pos) {
closeArgHints(ts);
var cache = ts.cachedArgHints, tp = cache.type;
var tip = elt("span", cache.guess ? cls + "fhint-guess" : null,
elt("span", cls + "fname", cache.name), "(");
for (var i = 0; i < tp.args.length; ++i) {
if (i) tip.appendChild(document.createTextNode(", "));
var arg = tp.args[i];
tip.appendChild(elt("span", cls + "farg" + (i == pos ? " " + cls + "farg-current" : ""), arg.name || "?"));
if (arg.type != "?") {
tip.appendChild(document.createTextNode(":\u00a0"));
tip.appendChild(elt("span", cls + "type", arg.type));
}
}
tip.appendChild(document.createTextNode(tp.rettype ? ") ->\u00a0" : ")"));
if (tp.rettype) tip.appendChild(elt("span", cls + "type", tp.rettype));
var place = cm.cursorCoords(null, "page");
var tooltip = ts.activeArgHints = makeTooltip(place.right + 1, place.bottom, tip)
setTimeout(function() {
tooltip.clear = onEditorActivity(cm, function() {
if (ts.activeArgHints == tooltip) closeArgHints(ts) })
}, 20)
}
function parseFnType(text) {
var args = [], pos = 3;
function skipMatching(upto) {
var depth = 0, start = pos;
for (;;) {
var next = text.charAt(pos);
if (upto.test(next) && !depth) return text.slice(start, pos);
if (/[{\[\(]/.test(next)) ++depth;
else if (/[}\]\)]/.test(next)) --depth;
++pos;
}
}
// Parse arguments
if (text.charAt(pos) != ")") for (;;) {
var name = text.slice(pos).match(/^([^, \(\[\{]+): /);
if (name) {
pos += name[0].length;
name = name[1];
}
args.push({name: name, type: skipMatching(/[\),]/)});
if (text.charAt(pos) == ")") break;
pos += 2;
}
var rettype = text.slice(pos).match(/^\) -> (.*)$/);
return {args: args, rettype: rettype && rettype[1]};
}
// Moving to the definition of something
function jumpToDef(ts, cm) {
function inner(varName) {
var req = {type: "definition", variable: varName || null};
var doc = findDoc(ts, cm.getDoc());
ts.server.request(buildRequest(ts, doc, req), function(error, data) {
if (error) return showError(ts, cm, error);
if (!data.file && data.url) { window.open(data.url); return; }
if (data.file) {
var localDoc = ts.docs[data.file], found;
if (localDoc && (found = findContext(localDoc.doc, data))) {
ts.jumpStack.push({file: doc.name,
start: cm.getCursor("from"),
end: cm.getCursor("to")});
moveTo(ts, doc, localDoc, found.start, found.end);
return;
}
}
showError(ts, cm, "Could not find a definition.");
});
}
if (!atInterestingExpression(cm))
dialog(cm, "Jump to variable", function(name) { if (name) inner(name); });
else
inner();
}
function jumpBack(ts, cm) {
var pos = ts.jumpStack.pop(), doc = pos && ts.docs[pos.file];
if (!doc) return;
moveTo(ts, findDoc(ts, cm.getDoc()), doc, pos.start, pos.end);
}
function moveTo(ts, curDoc, doc, start, end) {
doc.doc.setSelection(start, end);
if (curDoc != doc && ts.options.switchToDoc) {
closeArgHints(ts);
ts.options.switchToDoc(doc.name, doc.doc);
}
}
// The {line,ch} representation of positions makes this rather awkward.
function findContext(doc, data) {
var before = data.context.slice(0, data.contextOffset).split("\n");
var startLine = data.start.line - (before.length - 1);
var start = Pos(startLine, (before.length == 1 ? data.start.ch : doc.getLine(startLine).length) - before[0].length);
var text = doc.getLine(startLine).slice(start.ch);
for (var cur = startLine + 1; cur < doc.lineCount() && text.length < data.context.length; ++cur)
text += "\n" + doc.getLine(cur);
if (text.slice(0, data.context.length) == data.context) return data;
var cursor = doc.getSearchCursor(data.context, 0, false);
var nearest, nearestDist = Infinity;
while (cursor.findNext()) {
var from = cursor.from(), dist = Math.abs(from.line - start.line) * 10000;
if (!dist) dist = Math.abs(from.ch - start.ch);
if (dist < nearestDist) { nearest = from; nearestDist = dist; }
}
if (!nearest) return null;
if (before.length == 1)
nearest.ch += before[0].length;
else
nearest = Pos(nearest.line + (before.length - 1), before[before.length - 1].length);
if (data.start.line == data.end.line)
var end = Pos(nearest.line, nearest.ch + (data.end.ch - data.start.ch));
else
var end = Pos(nearest.line + (data.end.line - data.start.line), data.end.ch);
return {start: nearest, end: end};
}
function atInterestingExpression(cm) {
var pos = cm.getCursor("end"), tok = cm.getTokenAt(pos);
if (tok.start < pos.ch && tok.type == "comment") return false;
return /[\w)\]]/.test(cm.getLine(pos.line).slice(Math.max(pos.ch - 1, 0), pos.ch + 1));
}
// Variable renaming
function rename(ts, cm) {
var token = cm.getTokenAt(cm.getCursor());
if (!/\w/.test(token.string)) return showError(ts, cm, "Not at a variable");
dialog(cm, "New name for " + token.string, function(newName) {
ts.request(cm, {type: "rename", newName: newName, fullDocs: true}, function(error, data) {
if (error) return showError(ts, cm, error);
applyChanges(ts, data.changes);
});
});
}
function selectName(ts, cm) {
var name = findDoc(ts, cm.doc).name;
ts.request(cm, {type: "refs"}, function(error, data) {
if (error) return showError(ts, cm, error);
var ranges = [], cur = 0;
var curPos = cm.getCursor();
for (var i = 0; i < data.refs.length; i++) {
var ref = data.refs[i];
if (ref.file == name) {
ranges.push({anchor: ref.start, head: ref.end});
if (cmpPos(curPos, ref.start) >= 0 && cmpPos(curPos, ref.end) <= 0)
cur = ranges.length - 1;
}
}
cm.setSelections(ranges, cur);
});
}
var nextChangeOrig = 0;
function applyChanges(ts, changes) {
var perFile = Object.create(null);
for (var i = 0; i < changes.length; ++i) {
var ch = changes[i];
(perFile[ch.file] || (perFile[ch.file] = [])).push(ch);
}
for (var file in perFile) {
var known = ts.docs[file], chs = perFile[file];;
if (!known) continue;
chs.sort(function(a, b) { return cmpPos(b.start, a.start); });
var origin = "*rename" + (++nextChangeOrig);
for (var i = 0; i < chs.length; ++i) {
var ch = chs[i];
known.doc.replaceRange(ch.text, ch.start, ch.end, origin);
}
}
}
// Generic request-building helper
function buildRequest(ts, doc, query, pos) {
var files = [], offsetLines = 0, allowFragments = !query.fullDocs;
if (!allowFragments) delete query.fullDocs;
if (typeof query == "string") query = {type: query};
query.lineCharPositions = true;
if (query.end == null) {
query.end = pos || doc.doc.getCursor("end");
if (doc.doc.somethingSelected())
query.start = doc.doc.getCursor("start");
}
var startPos = query.start || query.end;
if (doc.changed) {
if (doc.doc.lineCount() > bigDoc && allowFragments !== false &&
doc.changed.to - doc.changed.from < 100 &&
doc.changed.from <= startPos.line && doc.changed.to > query.end.line) {
files.push(getFragmentAround(doc, startPos, query.end));
query.file = "#0";
var offsetLines = files[0].offsetLines;
if (query.start != null) query.start = Pos(query.start.line - -offsetLines, query.start.ch);
query.end = Pos(query.end.line - offsetLines, query.end.ch);
} else {
files.push({type: "full",
name: doc.name,
text: docValue(ts, doc)});
query.file = doc.name;
doc.changed = null;
}
} else {
query.file = doc.name;
}
for (var name in ts.docs) {
var cur = ts.docs[name];
if (cur.changed && cur != doc) {
files.push({type: "full", name: cur.name, text: docValue(ts, cur)});
cur.changed = null;
}
}
return {query: query, files: files};
}
function getFragmentAround(data, start, end) {
var doc = data.doc;
var minIndent = null, minLine = null, endLine, tabSize = 4;
for (var p = start.line - 1, min = Math.max(0, p - 50); p >= min; --p) {
var line = doc.getLine(p), fn = line.search(/\bfunction\b/);
if (fn < 0) continue;
var indent = CodeMirror.countColumn(line, null, tabSize);
if (minIndent != null && minIndent <= indent) continue;
minIndent = indent;
minLine = p;
}
if (minLine == null) minLine = min;
var max = Math.min(doc.lastLine(), end.line + 20);
if (minIndent == null || minIndent == CodeMirror.countColumn(doc.getLine(start.line), null, tabSize))
endLine = max;
else for (endLine = end.line + 1; endLine < max; ++endLine) {
var indent = CodeMirror.countColumn(doc.getLine(endLine), null, tabSize);
if (indent <= minIndent) break;
}
var from = Pos(minLine, 0);
return {type: "part",
name: data.name,
offsetLines: from.line,
text: doc.getRange(from, Pos(endLine, end.line == endLine ? null : 0))};
}
// Generic utilities
var cmpPos = CodeMirror.cmpPos;
function elt(tagname, cls /*, ... elts*/) {
var e = document.createElement(tagname);
if (cls) e.className = cls;
for (var i = 2; i < arguments.length; ++i) {
var elt = arguments[i];
if (typeof elt == "string") elt = document.createTextNode(elt);
e.appendChild(elt);
}
return e;
}
function dialog(cm, text, f) {
if (cm.openDialog)
cm.openDialog(text + ": <input type=text>", f);
else
f(prompt(text, ""));
}
// Tooltips
function tempTooltip(cm, content, ts) {
if (cm.state.ternTooltip) remove(cm.state.ternTooltip);
var where = cm.cursorCoords();
var tip = cm.state.ternTooltip = makeTooltip(where.right + 1, where.bottom, content);
function maybeClear() {
old = true;
if (!mouseOnTip) clear();
}
function clear() {
cm.state.ternTooltip = null;
if (tip.parentNode) fadeOut(tip)
clearActivity()
}
var mouseOnTip = false, old = false;
CodeMirror.on(tip, "mousemove", function() { mouseOnTip = true; });
CodeMirror.on(tip, "mouseout", function(e) {
var related = e.relatedTarget || e.toElement
if (!related || !CodeMirror.contains(tip, related)) {
if (old) clear();
else mouseOnTip = false;
}
});
setTimeout(maybeClear, ts.options.hintDelay ? ts.options.hintDelay : 1700);
var clearActivity = onEditorActivity(cm, clear)
}
function onEditorActivity(cm, f) {
cm.on("cursorActivity", f)
cm.on("blur", f)
cm.on("scroll", f)
cm.on("setDoc", f)
return function() {
cm.off("cursorActivity", f)
cm.off("blur", f)
cm.off("scroll", f)
cm.off("setDoc", f)
}
}
function makeTooltip(x, y, content) {
var node = elt("div", cls + "tooltip", content);
node.style.left = x + "px";
node.style.top = y + "px";
document.body.appendChild(node);
return node;
}
function remove(node) {
var p = node && node.parentNode;
if (p) p.removeChild(node);
}
function fadeOut(tooltip) {
tooltip.style.opacity = "0";
setTimeout(function() { remove(tooltip); }, 1100);
}
function showError(ts, cm, msg) {
if (ts.options.showError)
ts.options.showError(cm, msg);
else
tempTooltip(cm, String(msg), ts);
}
function closeArgHints(ts) {
if (ts.activeArgHints) {
if (ts.activeArgHints.clear) ts.activeArgHints.clear()
remove(ts.activeArgHints)
ts.activeArgHints = null
}
}
function docValue(ts, doc) {
var val = doc.doc.getValue();
if (ts.options.fileFilter) val = ts.options.fileFilter(val, doc.name, doc.doc);
return val;
}
// Worker wrapper
function WorkerServer(ts) {
var worker = ts.worker = new Worker(ts.options.workerScript);
worker.postMessage({type: "init",
defs: ts.options.defs,
plugins: ts.options.plugins,
scripts: ts.options.workerDeps});
var msgId = 0, pending = {};
function send(data, c) {
if (c) {
data.id = ++msgId;
pending[msgId] = c;
}
worker.postMessage(data);
}
worker.onmessage = function(e) {
var data = e.data;
if (data.type == "getFile") {
getFile(ts, data.name, function(err, text) {
send({type: "getFile", err: String(err), text: text, id: data.id});
});
} else if (data.type == "debug") {
window.console.log(data.message);
} else if (data.id && pending[data.id]) {
pending[data.id](data.err, data.body);
delete pending[data.id];
}
};
worker.onerror = function(e) {
for (var id in pending) pending[id](e);
pending = {};
};
this.addFile = function(name, text) { send({type: "add", name: name, text: text}); };
this.delFile = function(name) { send({type: "del", name: name}); };
this.request = function(body, c) { send({type: "req", body: body}, c); };
}
});

View File

@ -1,44 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
// declare global: tern, server
var server;
this.onmessage = function(e) {
var data = e.data;
switch (data.type) {
case "init": return startServer(data.defs, data.plugins, data.scripts);
case "add": return server.addFile(data.name, data.text);
case "del": return server.delFile(data.name);
case "req": return server.request(data.body, function(err, reqData) {
postMessage({id: data.id, body: reqData, err: err && String(err)});
});
case "getFile":
var c = pending[data.id];
delete pending[data.id];
return c(data.err, data.text);
default: throw new Error("Unknown message type: " + data.type);
}
};
var nextId = 0, pending = {};
function getFile(file, c) {
postMessage({type: "getFile", name: file, id: ++nextId});
pending[nextId] = c;
}
function startServer(defs, plugins, scripts) {
if (scripts) importScripts.apply(null, scripts);
server = new tern.Server({
getFile: getFile,
async: true,
defs: defs,
plugins: plugins
});
}
this.console = {
log: function(v) { postMessage({type: "debug", message: v}); }
};

View File

@ -1,145 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
var Pos = CodeMirror.Pos;
function findParagraph(cm, pos, options) {
var startRE = options.paragraphStart || cm.getHelper(pos, "paragraphStart");
for (var start = pos.line, first = cm.firstLine(); start > first; --start) {
var line = cm.getLine(start);
if (startRE && startRE.test(line)) break;
if (!/\S/.test(line)) { ++start; break; }
}
var endRE = options.paragraphEnd || cm.getHelper(pos, "paragraphEnd");
for (var end = pos.line + 1, last = cm.lastLine(); end <= last; ++end) {
var line = cm.getLine(end);
if (endRE && endRE.test(line)) { ++end; break; }
if (!/\S/.test(line)) break;
}
return {from: start, to: end};
}
function findBreakPoint(text, column, wrapOn, killTrailingSpace) {
var at = column
while (at < text.length && text.charAt(at) == " ") at++
for (; at > 0; --at)
if (wrapOn.test(text.slice(at - 1, at + 1))) break;
for (var first = true;; first = false) {
var endOfText = at;
if (killTrailingSpace)
while (text.charAt(endOfText - 1) == " ") --endOfText;
if (endOfText == 0 && first) at = column;
else return {from: endOfText, to: at};
}
}
function wrapRange(cm, from, to, options) {
from = cm.clipPos(from); to = cm.clipPos(to);
var column = options.column || 80;
var wrapOn = options.wrapOn || /\s\S|-[^\.\d]/;
var killTrailing = options.killTrailingSpace !== false;
var changes = [], curLine = "", curNo = from.line;
var lines = cm.getRange(from, to, false);
if (!lines.length) return null;
var leadingSpace = lines[0].match(/^[ \t]*/)[0];
if (leadingSpace.length >= column) column = leadingSpace.length + 1
for (var i = 0; i < lines.length; ++i) {
var text = lines[i], oldLen = curLine.length, spaceInserted = 0;
if (curLine && text && !wrapOn.test(curLine.charAt(curLine.length - 1) + text.charAt(0))) {
curLine += " ";
spaceInserted = 1;
}
var spaceTrimmed = "";
if (i) {
spaceTrimmed = text.match(/^\s*/)[0];
text = text.slice(spaceTrimmed.length);
}
curLine += text;
if (i) {
var firstBreak = curLine.length > column && leadingSpace == spaceTrimmed &&
findBreakPoint(curLine, column, wrapOn, killTrailing);
// If this isn't broken, or is broken at a different point, remove old break
if (!firstBreak || firstBreak.from != oldLen || firstBreak.to != oldLen + spaceInserted) {
changes.push({text: [spaceInserted ? " " : ""],
from: Pos(curNo, oldLen),
to: Pos(curNo + 1, spaceTrimmed.length)});
} else {
curLine = leadingSpace + text;
++curNo;
}
}
while (curLine.length > column) {
var bp = findBreakPoint(curLine, column, wrapOn, killTrailing);
changes.push({text: ["", leadingSpace],
from: Pos(curNo, bp.from),
to: Pos(curNo, bp.to)});
curLine = leadingSpace + curLine.slice(bp.to);
++curNo;
}
}
if (changes.length) cm.operation(function() {
for (var i = 0; i < changes.length; ++i) {
var change = changes[i];
if (change.text || CodeMirror.cmpPos(change.from, change.to))
cm.replaceRange(change.text, change.from, change.to);
}
});
return changes.length ? {from: changes[0].from, to: CodeMirror.changeEnd(changes[changes.length - 1])} : null;
}
CodeMirror.defineExtension("wrapParagraph", function(pos, options) {
options = options || {};
if (!pos) pos = this.getCursor();
var para = findParagraph(this, pos, options);
return wrapRange(this, Pos(para.from, 0), Pos(para.to - 1), options);
});
CodeMirror.commands.wrapLines = function(cm) {
cm.operation(function() {
var ranges = cm.listSelections(), at = cm.lastLine() + 1;
for (var i = ranges.length - 1; i >= 0; i--) {
var range = ranges[i], span;
if (range.empty()) {
var para = findParagraph(cm, range.head, {});
span = {from: Pos(para.from, 0), to: Pos(para.to - 1)};
} else {
span = {from: range.from(), to: range.to()};
}
if (span.to.line >= at) continue;
at = span.from.line;
wrapRange(cm, span.from, span.to, {});
}
});
};
CodeMirror.defineExtension("wrapRange", function(from, to, options) {
return wrapRange(this, from, to, options || {});
});
CodeMirror.defineExtension("wrapParagraphsInRange", function(from, to, options) {
options = options || {};
var cm = this, paras = [];
for (var line = from.line; line <= to.line;) {
var para = findParagraph(cm, Pos(line, 0), options);
paras.push(para);
line = para.to;
}
var madeChange = false;
if (paras.length) cm.operation(function() {
for (var i = paras.length - 1; i >= 0; --i)
madeChange = madeChange || wrapRange(cm, Pos(paras[i].from, 0), Pos(paras[i].to - 1), options);
});
return madeChange;
});
});

View File

@ -1,349 +0,0 @@
/* BASICS */
.CodeMirror {
/* Set height, width, borders, and global font properties here */
font-family: monospace;
height: 300px;
color: black;
direction: ltr;
}
/* PADDING */
.CodeMirror-lines {
padding: 4px 0; /* Vertical padding around content */
}
.CodeMirror pre.CodeMirror-line,
.CodeMirror pre.CodeMirror-line-like {
padding: 0 4px; /* Horizontal padding of content */
}
.CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
background-color: white; /* The little square between H and V scrollbars */
}
/* GUTTER */
.CodeMirror-gutters {
border-right: 1px solid #ddd;
background-color: #f7f7f7;
white-space: nowrap;
}
.CodeMirror-linenumbers {}
.CodeMirror-linenumber {
padding: 0 3px 0 5px;
min-width: 20px;
text-align: right;
color: #999;
white-space: nowrap;
}
.CodeMirror-guttermarker { color: black; }
.CodeMirror-guttermarker-subtle { color: #999; }
/* CURSOR */
.CodeMirror-cursor {
border-left: 1px solid black;
border-right: none;
width: 0;
}
/* Shown when moving in bi-directional text */
.CodeMirror div.CodeMirror-secondarycursor {
border-left: 1px solid silver;
}
.cm-fat-cursor .CodeMirror-cursor {
width: auto;
border: 0 !important;
background: #7e7;
}
.cm-fat-cursor div.CodeMirror-cursors {
z-index: 1;
}
.cm-fat-cursor-mark {
background-color: rgba(20, 255, 20, 0.5);
-webkit-animation: blink 1.06s steps(1) infinite;
-moz-animation: blink 1.06s steps(1) infinite;
animation: blink 1.06s steps(1) infinite;
}
.cm-animate-fat-cursor {
width: auto;
border: 0;
-webkit-animation: blink 1.06s steps(1) infinite;
-moz-animation: blink 1.06s steps(1) infinite;
animation: blink 1.06s steps(1) infinite;
background-color: #7e7;
}
@-moz-keyframes blink {
0% {}
50% { background-color: transparent; }
100% {}
}
@-webkit-keyframes blink {
0% {}
50% { background-color: transparent; }
100% {}
}
@keyframes blink {
0% {}
50% { background-color: transparent; }
100% {}
}
/* Can style cursor different in overwrite (non-insert) mode */
.CodeMirror-overwrite .CodeMirror-cursor {}
.cm-tab { display: inline-block; text-decoration: inherit; }
.CodeMirror-rulers {
position: absolute;
left: 0; right: 0; top: -50px; bottom: 0;
overflow: hidden;
}
.CodeMirror-ruler {
border-left: 1px solid #ccc;
top: 0; bottom: 0;
position: absolute;
}
/* DEFAULT THEME */
.cm-s-default .cm-header {color: blue;}
.cm-s-default .cm-quote {color: #090;}
.cm-negative {color: #d44;}
.cm-positive {color: #292;}
.cm-header, .cm-strong {font-weight: bold;}
.cm-em {font-style: italic;}
.cm-link {text-decoration: underline;}
.cm-strikethrough {text-decoration: line-through;}
.cm-s-default .cm-keyword {color: #708;}
.cm-s-default .cm-atom {color: #219;}
.cm-s-default .cm-number {color: #164;}
.cm-s-default .cm-def {color: #00f;}
.cm-s-default .cm-variable,
.cm-s-default .cm-punctuation,
.cm-s-default .cm-property,
.cm-s-default .cm-operator {}
.cm-s-default .cm-variable-2 {color: #05a;}
.cm-s-default .cm-variable-3, .cm-s-default .cm-type {color: #085;}
.cm-s-default .cm-comment {color: #a50;}
.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-qualifier {color: #555;}
.cm-s-default .cm-builtin {color: #30a;}
.cm-s-default .cm-bracket {color: #997;}
.cm-s-default .cm-tag {color: #170;}
.cm-s-default .cm-attribute {color: #00c;}
.cm-s-default .cm-hr {color: #999;}
.cm-s-default .cm-link {color: #00c;}
.cm-s-default .cm-error {color: #f00;}
.cm-invalidchar {color: #f00;}
.CodeMirror-composing { border-bottom: 2px solid; }
/* Default styles for common addons */
div.CodeMirror span.CodeMirror-matchingbracket {color: #0b0;}
div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #a22;}
.CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); }
.CodeMirror-activeline-background {background: #e8f2ff;}
/* STOP */
/* The rest of this file contains styles related to the mechanics of
the editor. You probably shouldn't touch them. */
.CodeMirror {
position: relative;
overflow: hidden;
background: white;
}
.CodeMirror-scroll {
overflow: scroll !important; /* Things will break if this is overridden */
/* 30px is the magic margin used to hide the element's real scrollbars */
/* See overflow: hidden in .CodeMirror */
margin-bottom: -30px; margin-right: -30px;
padding-bottom: 30px;
height: 100%;
outline: none; /* Prevent dragging from highlighting the element */
position: relative;
}
.CodeMirror-sizer {
position: relative;
border-right: 30px solid transparent;
}
/* The fake, visible scrollbars. Used to force redraw during scrolling
before actual scrolling happens, thus preventing shaking and
flickering artifacts. */
.CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
position: absolute;
z-index: 6;
display: none;
}
.CodeMirror-vscrollbar {
right: 0; top: 0;
overflow-x: hidden;
overflow-y: scroll;
}
.CodeMirror-hscrollbar {
bottom: 0; left: 0;
overflow-y: hidden;
overflow-x: scroll;
}
.CodeMirror-scrollbar-filler {
right: 0; bottom: 0;
}
.CodeMirror-gutter-filler {
left: 0; bottom: 0;
}
.CodeMirror-gutters {
position: absolute; left: 0; top: 0;
min-height: 100%;
z-index: 3;
}
.CodeMirror-gutter {
white-space: normal;
height: 100%;
display: inline-block;
vertical-align: top;
margin-bottom: -30px;
}
.CodeMirror-gutter-wrapper {
position: absolute;
z-index: 4;
background: none !important;
border: none !important;
}
.CodeMirror-gutter-background {
position: absolute;
top: 0; bottom: 0;
z-index: 4;
}
.CodeMirror-gutter-elt {
position: absolute;
cursor: default;
z-index: 4;
}
.CodeMirror-gutter-wrapper ::selection { background-color: transparent }
.CodeMirror-gutter-wrapper ::-moz-selection { background-color: transparent }
.CodeMirror-lines {
cursor: text;
min-height: 1px; /* prevents collapsing before first draw */
}
.CodeMirror pre.CodeMirror-line,
.CodeMirror pre.CodeMirror-line-like {
/* Reset some styles that the rest of the page might have set */
-moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0;
border-width: 0;
background: transparent;
font-family: inherit;
font-size: inherit;
margin: 0;
white-space: pre;
word-wrap: normal;
line-height: inherit;
color: inherit;
z-index: 2;
position: relative;
overflow: visible;
-webkit-tap-highlight-color: transparent;
-webkit-font-variant-ligatures: contextual;
font-variant-ligatures: contextual;
}
.CodeMirror-wrap pre.CodeMirror-line,
.CodeMirror-wrap pre.CodeMirror-line-like {
word-wrap: break-word;
white-space: pre-wrap;
word-break: normal;
}
.CodeMirror-linebackground {
position: absolute;
left: 0; right: 0; top: 0; bottom: 0;
z-index: 0;
}
.CodeMirror-linewidget {
position: relative;
z-index: 2;
padding: 0.1px; /* Force widget margins to stay inside of the container */
}
.CodeMirror-widget {}
.CodeMirror-rtl pre { direction: rtl; }
.CodeMirror-code {
outline: none;
}
/* Force content-box sizing for the elements where we expect it */
.CodeMirror-scroll,
.CodeMirror-sizer,
.CodeMirror-gutter,
.CodeMirror-gutters,
.CodeMirror-linenumber {
-moz-box-sizing: content-box;
box-sizing: content-box;
}
.CodeMirror-measure {
position: absolute;
width: 100%;
height: 0;
overflow: hidden;
visibility: hidden;
}
.CodeMirror-cursor {
position: absolute;
pointer-events: none;
}
.CodeMirror-measure pre { position: static; }
div.CodeMirror-cursors {
visibility: hidden;
position: relative;
z-index: 3;
}
div.CodeMirror-dragcursors {
visibility: visible;
}
.CodeMirror-focused div.CodeMirror-cursors {
visibility: visible;
}
.CodeMirror-selected { background: #d9d9d9; }
.CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
.CodeMirror-crosshair { cursor: crosshair; }
.CodeMirror-line::selection, .CodeMirror-line > span::selection, .CodeMirror-line > span > span::selection { background: #d7d4f0; }
.CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; }
.cm-searching {
background-color: #ffa;
background-color: rgba(255, 255, 0, .4);
}
/* Used to force a border model for a node */
.cm-force-border { padding-right: .1px; }
@media print {
/* Hide the cursor when printing */
.CodeMirror div.CodeMirror-cursors {
visibility: hidden;
}
}
/* See issue #2901 */
.cm-tab-wrap-hack:after { content: ''; }
/* Help users use markselection to safely style text background */
span.CodeMirror-selectedtext { background: none; }

File diff suppressed because it is too large Load Diff

View File

@ -1,174 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.defineMode("apl", function() {
var builtInOps = {
".": "innerProduct",
"\\": "scan",
"/": "reduce",
"⌿": "reduce1Axis",
"⍀": "scan1Axis",
"¨": "each",
"⍣": "power"
};
var builtInFuncs = {
"+": ["conjugate", "add"],
"": ["negate", "subtract"],
"×": ["signOf", "multiply"],
"÷": ["reciprocal", "divide"],
"⌈": ["ceiling", "greaterOf"],
"⌊": ["floor", "lesserOf"],
"": ["absolute", "residue"],
"": ["indexGenerate", "indexOf"],
"?": ["roll", "deal"],
"⋆": ["exponentiate", "toThePowerOf"],
"⍟": ["naturalLog", "logToTheBase"],
"○": ["piTimes", "circularFuncs"],
"!": ["factorial", "binomial"],
"⌹": ["matrixInverse", "matrixDivide"],
"<": [null, "lessThan"],
"≤": [null, "lessThanOrEqual"],
"=": [null, "equals"],
">": [null, "greaterThan"],
"≥": [null, "greaterThanOrEqual"],
"≠": [null, "notEqual"],
"≡": ["depth", "match"],
"≢": [null, "notMatch"],
"∈": ["enlist", "membership"],
"⍷": [null, "find"],
"": ["unique", "union"],
"∩": [null, "intersection"],
"": ["not", "without"],
"": [null, "or"],
"∧": [null, "and"],
"⍱": [null, "nor"],
"⍲": [null, "nand"],
"": ["shapeOf", "reshape"],
",": ["ravel", "catenate"],
"⍪": [null, "firstAxisCatenate"],
"⌽": ["reverse", "rotate"],
"⊖": ["axis1Reverse", "axis1Rotate"],
"⍉": ["transpose", null],
"↑": ["first", "take"],
"↓": [null, "drop"],
"⊂": ["enclose", "partitionWithAxis"],
"⊃": ["diclose", "pick"],
"⌷": [null, "index"],
"⍋": ["gradeUp", null],
"⍒": ["gradeDown", null],
"": ["encode", null],
"⊥": ["decode", null],
"⍕": ["format", "formatByExample"],
"⍎": ["execute", null],
"⊣": ["stop", "left"],
"⊢": ["pass", "right"]
};
var isOperator = /[\.\/⌿⍀¨⍣]/;
var isNiladic = /⍬/;
var isFunction = /[\+−×÷⌈⌊∣⍳\?⋆⍟○!⌹<≤=>≥≠≡≢∈⍷∪∩∼∨∧⍱⍲⍴,⍪⌽⊖⍉↑↓⊂⊃⌷⍋⍒⊤⊥⍕⍎⊣⊢]/;
var isArrow = /←/;
var isComment = /[⍝#].*$/;
var stringEater = function(type) {
var prev;
prev = false;
return function(c) {
prev = c;
if (c === type) {
return prev === "\\";
}
return true;
};
};
return {
startState: function() {
return {
prev: false,
func: false,
op: false,
string: false,
escape: false
};
},
token: function(stream, state) {
var ch, funcName;
if (stream.eatSpace()) {
return null;
}
ch = stream.next();
if (ch === '"' || ch === "'") {
stream.eatWhile(stringEater(ch));
stream.next();
state.prev = true;
return "string";
}
if (/[\[{\(]/.test(ch)) {
state.prev = false;
return null;
}
if (/[\]}\)]/.test(ch)) {
state.prev = true;
return null;
}
if (isNiladic.test(ch)) {
state.prev = false;
return "niladic";
}
if (/[¯\d]/.test(ch)) {
if (state.func) {
state.func = false;
state.prev = false;
} else {
state.prev = true;
}
stream.eatWhile(/[\w\.]/);
return "number";
}
if (isOperator.test(ch)) {
return "operator apl-" + builtInOps[ch];
}
if (isArrow.test(ch)) {
return "apl-arrow";
}
if (isFunction.test(ch)) {
funcName = "apl-";
if (builtInFuncs[ch] != null) {
if (state.prev) {
funcName += builtInFuncs[ch][1];
} else {
funcName += builtInFuncs[ch][0];
}
}
state.func = true;
state.prev = false;
return "function " + funcName;
}
if (isComment.test(ch)) {
stream.skipToEnd();
return "comment";
}
if (ch === "∘" && stream.peek() === ".") {
stream.next();
return "function jot-dot";
}
stream.eatWhile(/[\w\$_]/);
state.prev = true;
return "keyword";
}
};
});
CodeMirror.defineMIME("text/apl", "apl");
});

Some files were not shown because too many files have changed in this diff Show More