From 649b7a0b75b1cf8b7258e9f4f9725b7ce752132f Mon Sep 17 00:00:00 2001 From: Pascal Rettig Date: Mon, 19 Sep 2011 08:11:41 -0400 Subject: [PATCH 1/2] Added templates --- js/deck.coder.js | 33 ++++++++++++----------- sample.html | 70 ++++++++++-------------------------------------- 2 files changed, 32 insertions(+), 71 deletions(-) diff --git a/js/deck.coder.js b/js/deck.coder.js index 961329a..6f298b7 100644 --- a/js/deck.coder.js +++ b/js/deck.coder.js @@ -43,7 +43,7 @@ This module adds a code editor that shows up in individual slides code = "\n" + code + "\n"; } - var tmpl = $("#coderdeck-default").html(); + var tmpl = $(template ? "#" + template : "#coderdeck-default").html(); code = "" + tmpl.replace(/END/,'').replace(/CODE/,code); @@ -129,6 +129,10 @@ This module adds a code editor that shows up in individual slides var html = element.html().replace(/SCRIPT/g,' - -
-

HTML5 Workshop #6

-

Putting it all together
- http://bit.ly/html5workshop6

-
- -
-

What we've learned

-
    -
  1. HTML5 Basics & Semantic Structure

  2. -
  3. The Perfect Chop & Layout basics

  4. -
  5. CSS styling & Responsive Design

  6. -
  7. Javascript & jQuery

  8. -
  9. More Javascript, Events, Ajax & JS Templates

  10. -
-
- -
-

Mashup Time

-

Friend Explorer with Facebook API

-
- -
-

The Plan

-
    -
  1. Connect to facebook API

  2. -
  3. Pull a list of your friends

  4. -
  5. Find a list of all the things your friends like.

  6. -
- -
- + +
+

CoderDeck sample

- +

Show our name

Hide the login button when a user log's in, show a "Logging in", then the user's name once they are in.

From 409b56db3fc6c1c04422e11bd0b170e4110e3544 Mon Sep 17 00:00:00 2001 From: Pascal Rettig Date: Wed, 28 Sep 2011 20:39:24 -0400 Subject: [PATCH 2/2] Sample file --- .gitignore | 1 + .gitmodules | 6 + MIT-LICENSE.txt | 20 + Makefile | 128 + build/jslint-check.js | 36 + build/lib/jslint.js | 5504 +++++++++++++++++ build/lib/parse-js.js | 1315 ++++ build/lib/process.js | 1666 +++++ build/lib/squeeze-more.js | 22 + build/post-compile.js | 20 + build/release-notes.js | 54 + build/release-notes.txt | 27 + build/release.js | 169 + build/sizer.js | 36 + build/uglify.js | 285 + fonts/museosans_500-webfont.eot | Bin 49680 -> 0 bytes fonts/museosans_500-webfont.svg | 247 - fonts/museosans_500-webfont.ttf | Bin 49516 -> 0 bytes fonts/museosans_500-webfont.woff | Bin 26976 -> 0 bytes js/codedeck.js | 104 - js/codemirror/codemirror.css | 68 - js/codemirror/codemirror.js | 2164 ------- js/codemirror/mode/clike/clike.js | 247 - js/codemirror/mode/clike/index.html | 102 - js/codemirror/mode/clojure/clojure.js | 207 - js/codemirror/mode/clojure/index.html | 85 - js/codemirror/mode/coffeescript/LICENSE | 22 - .../mode/coffeescript/coffeescript.js | 325 - js/codemirror/mode/coffeescript/index.html | 722 --- js/codemirror/mode/css/css.js | 124 - js/codemirror/mode/css/index.html | 56 - js/codemirror/mode/diff/diff.css | 3 - js/codemirror/mode/diff/diff.js | 13 - js/codemirror/mode/diff/index.html | 99 - js/codemirror/mode/haskell/haskell.js | 242 - js/codemirror/mode/haskell/index.html | 60 - js/codemirror/mode/htmlmixed/htmlmixed.js | 79 - js/codemirror/mode/htmlmixed/index.html | 52 - js/codemirror/mode/javascript/index.html | 78 - js/codemirror/mode/javascript/javascript.js | 352 -- js/codemirror/mode/jinja2/index.html | 38 - js/codemirror/mode/jinja2/jinja2.js | 42 - js/codemirror/mode/lua/index.html | 72 - js/codemirror/mode/lua/lua.js | 140 - js/codemirror/mode/markdown/index.html | 340 - js/codemirror/mode/markdown/markdown.css | 10 - js/codemirror/mode/markdown/markdown.js | 230 - js/codemirror/mode/php/index.html | 49 - js/codemirror/mode/php/php.js | 115 - js/codemirror/mode/plsql/index.html | 63 - js/codemirror/mode/plsql/plsql.js | 217 - js/codemirror/mode/python/LICENSE.txt | 21 - js/codemirror/mode/python/index.html | 123 - js/codemirror/mode/python/python.js | 321 - js/codemirror/mode/r/LICENSE | 24 - js/codemirror/mode/r/index.html | 74 - js/codemirror/mode/r/r.js | 141 - js/codemirror/mode/rst/index.html | 526 -- js/codemirror/mode/rst/rst.css | 75 - js/codemirror/mode/rst/rst.js | 333 - js/codemirror/mode/ruby/LICENSE | 24 - js/codemirror/mode/ruby/index.html | 172 - js/codemirror/mode/ruby/ruby.js | 195 - js/codemirror/mode/scheme/index.html | 65 - js/codemirror/mode/scheme/scheme.js | 202 - js/codemirror/mode/smalltalk/index.html | 56 - js/codemirror/mode/smalltalk/smalltalk.js | 122 - js/codemirror/mode/sparql/index.html | 41 - js/codemirror/mode/sparql/sparql.js | 143 - js/codemirror/mode/stex/index.html | 96 - js/codemirror/mode/stex/stex.js | 167 - js/codemirror/mode/velocity/index.html | 103 - js/codemirror/mode/velocity/velocity.js | 146 - js/codemirror/mode/xml/index.html | 42 - js/codemirror/mode/xml/xml.js | 231 - js/codemirror/mode/xmlpure/index.html | 60 - js/codemirror/mode/xmlpure/xmlpure.js | 481 -- js/codemirror/mode/yaml/index.html | 68 - js/codemirror/mode/yaml/yaml.js | 95 - js/codemirror/overlay.js | 51 - js/codemirror/runmode.js | 27 - js/codemirror/theme/cobalt.css | 17 - js/codemirror/theme/default.css | 19 - js/codemirror/theme/elegant.css | 9 - js/codemirror/theme/neat.css | 8 - js/codemirror/theme/night.css | 20 - js/deck.core.js | 364 -- js/deck.goto.js | 110 - js/deck.hash.js | 110 - js/deck.menu.js | 84 - js/deck.navigation.js | 72 - js/deck.status.js | 42 - sample.html | 205 +- {js => src}/.DS_Store | Bin src/codemirror | 1 + {js => src}/deck.coder.js | 87 +- src/deck.js | 1 + {js => src}/jquery.min.js | 0 {js => src}/jquery.tmpl.min.js | 0 {js => src}/modernizr.js | 0 {js => src}/prettify.js | 0 version.txt | 1 + 102 files changed, 9451 insertions(+), 11980 deletions(-) create mode 100644 .gitignore create mode 100644 .gitmodules create mode 100644 MIT-LICENSE.txt create mode 100644 Makefile create mode 100644 build/jslint-check.js create mode 100644 build/lib/jslint.js create mode 100644 build/lib/parse-js.js create mode 100644 build/lib/process.js create mode 100644 build/lib/squeeze-more.js create mode 100644 build/post-compile.js create mode 100644 build/release-notes.js create mode 100644 build/release-notes.txt create mode 100644 build/release.js create mode 100644 build/sizer.js create mode 100644 build/uglify.js delete mode 100644 fonts/museosans_500-webfont.eot delete mode 100644 fonts/museosans_500-webfont.svg delete mode 100644 fonts/museosans_500-webfont.ttf delete mode 100644 fonts/museosans_500-webfont.woff delete mode 100644 js/codedeck.js delete mode 100644 js/codemirror/codemirror.css delete mode 100644 js/codemirror/codemirror.js delete mode 100644 js/codemirror/mode/clike/clike.js delete mode 100644 js/codemirror/mode/clike/index.html delete mode 100644 js/codemirror/mode/clojure/clojure.js delete mode 100644 js/codemirror/mode/clojure/index.html delete mode 100644 js/codemirror/mode/coffeescript/LICENSE delete mode 100644 js/codemirror/mode/coffeescript/coffeescript.js delete mode 100644 js/codemirror/mode/coffeescript/index.html delete mode 100644 js/codemirror/mode/css/css.js delete mode 100644 js/codemirror/mode/css/index.html delete mode 100644 js/codemirror/mode/diff/diff.css delete mode 100644 js/codemirror/mode/diff/diff.js delete mode 100644 js/codemirror/mode/diff/index.html delete mode 100644 js/codemirror/mode/haskell/haskell.js delete mode 100644 js/codemirror/mode/haskell/index.html delete mode 100644 js/codemirror/mode/htmlmixed/htmlmixed.js delete mode 100644 js/codemirror/mode/htmlmixed/index.html delete mode 100644 js/codemirror/mode/javascript/index.html delete mode 100644 js/codemirror/mode/javascript/javascript.js delete mode 100644 js/codemirror/mode/jinja2/index.html delete mode 100644 js/codemirror/mode/jinja2/jinja2.js delete mode 100644 js/codemirror/mode/lua/index.html delete mode 100644 js/codemirror/mode/lua/lua.js delete mode 100644 js/codemirror/mode/markdown/index.html delete mode 100644 js/codemirror/mode/markdown/markdown.css delete mode 100644 js/codemirror/mode/markdown/markdown.js delete mode 100644 js/codemirror/mode/php/index.html delete mode 100644 js/codemirror/mode/php/php.js delete mode 100644 js/codemirror/mode/plsql/index.html delete mode 100644 js/codemirror/mode/plsql/plsql.js delete mode 100644 js/codemirror/mode/python/LICENSE.txt delete mode 100644 js/codemirror/mode/python/index.html delete mode 100644 js/codemirror/mode/python/python.js delete mode 100644 js/codemirror/mode/r/LICENSE delete mode 100644 js/codemirror/mode/r/index.html delete mode 100644 js/codemirror/mode/r/r.js delete mode 100644 js/codemirror/mode/rst/index.html delete mode 100644 js/codemirror/mode/rst/rst.css delete mode 100644 js/codemirror/mode/rst/rst.js delete mode 100644 js/codemirror/mode/ruby/LICENSE delete mode 100644 js/codemirror/mode/ruby/index.html delete mode 100644 js/codemirror/mode/ruby/ruby.js delete mode 100644 js/codemirror/mode/scheme/index.html delete mode 100644 js/codemirror/mode/scheme/scheme.js delete mode 100644 js/codemirror/mode/smalltalk/index.html delete mode 100644 js/codemirror/mode/smalltalk/smalltalk.js delete mode 100644 js/codemirror/mode/sparql/index.html delete mode 100644 js/codemirror/mode/sparql/sparql.js delete mode 100644 js/codemirror/mode/stex/index.html delete mode 100644 js/codemirror/mode/stex/stex.js delete mode 100644 js/codemirror/mode/velocity/index.html delete mode 100644 js/codemirror/mode/velocity/velocity.js delete mode 100644 js/codemirror/mode/xml/index.html delete mode 100644 js/codemirror/mode/xml/xml.js delete mode 100644 js/codemirror/mode/xmlpure/index.html delete mode 100644 js/codemirror/mode/xmlpure/xmlpure.js delete mode 100644 js/codemirror/mode/yaml/index.html delete mode 100644 js/codemirror/mode/yaml/yaml.js delete mode 100644 js/codemirror/overlay.js delete mode 100644 js/codemirror/runmode.js delete mode 100644 js/codemirror/theme/cobalt.css delete mode 100644 js/codemirror/theme/default.css delete mode 100644 js/codemirror/theme/elegant.css delete mode 100644 js/codemirror/theme/neat.css delete mode 100644 js/codemirror/theme/night.css delete mode 100644 js/deck.core.js delete mode 100644 js/deck.goto.js delete mode 100644 js/deck.hash.js delete mode 100644 js/deck.menu.js delete mode 100644 js/deck.navigation.js delete mode 100644 js/deck.status.js rename {js => src}/.DS_Store (100%) create mode 160000 src/codemirror rename {js => src}/deck.coder.js (76%) create mode 160000 src/deck.js rename {js => src}/jquery.min.js (100%) rename {js => src}/jquery.tmpl.min.js (100%) rename {js => src}/modernizr.js (100%) rename {js => src}/prettify.js (100%) create mode 100644 version.txt diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1521c8b --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +dist diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..4c3571f --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "src/deck.js"] + path = src/deck.js + url = https://github.com/imakewebthings/deck.js.git +[submodule "src/codemirror"] + path = src/codemirror + url = https://github.com/marijnh/CodeMirror2.git diff --git a/MIT-LICENSE.txt b/MIT-LICENSE.txt new file mode 100644 index 0000000..72997a4 --- /dev/null +++ b/MIT-LICENSE.txt @@ -0,0 +1,20 @@ +Copyright (c) 2011 Cykod LLC, http://coderdeck.com/ + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..01f7c02 --- /dev/null +++ b/Makefile @@ -0,0 +1,128 @@ +SRC_DIR = src +TEST_DIR = test +BUILD_DIR = build + +PREFIX = . +DIST_DIR = ${PREFIX}/dist + +JS_ENGINE ?= `which node nodejs` +COMPILER = ${JS_ENGINE} ${BUILD_DIR}/uglify.js --unsafe +POST_COMPILER = ${JS_ENGINE} ${BUILD_DIR}/post-compile.js + +BASE_FILES = ${SRC_DIR}/jquery.js\ + ${SRC_DIR}/callbacks.js\ + ${SRC_DIR}/deferred.js\ + ${SRC_DIR}/support.js\ + ${SRC_DIR}/data.js\ + ${SRC_DIR}/queue.js\ + ${SRC_DIR}/attributes.js\ + ${SRC_DIR}/event.js\ + ${SRC_DIR}/selector.js\ + ${SRC_DIR}/traversing.js\ + ${SRC_DIR}/manipulation.js\ + ${SRC_DIR}/css.js\ + ${SRC_DIR}/ajax.js\ + ${SRC_DIR}/ajax/jsonp.js\ + ${SRC_DIR}/ajax/script.js\ + ${SRC_DIR}/ajax/xhr.js\ + ${SRC_DIR}/effects.js\ + ${SRC_DIR}/offset.js\ + ${SRC_DIR}/dimensions.js + +MODULES = ${SRC_DIR}/intro.js\ + ${BASE_FILES}\ + ${SRC_DIR}/outro.js + +JQ = ${DIST_DIR}/jquery.js +JQ_MIN = ${DIST_DIR}/jquery.min.js + +SIZZLE_DIR = ${SRC_DIR}/sizzle + +JQ_VER = $(shell cat version.txt) +VER = sed "s/@VERSION/${JQ_VER}/" + +DATE=$(shell git log -1 --pretty=format:%ad) + +all: update_submodules core + +core: jquery min lint size + @@echo "jQuery build complete." + +${DIST_DIR}: + @@mkdir -p ${DIST_DIR} + +jquery: ${JQ} + +${JQ}: ${MODULES} | ${DIST_DIR} + @@echo "Building" ${JQ} + + @@cat ${MODULES} | \ + sed 's/.function..jQuery...{//' | \ + sed 's/}...jQuery..;//' | \ + sed 's/@DATE/'"${DATE}"'/' | \ + ${VER} > ${JQ}; + +${SRC_DIR}/selector.js: ${SIZZLE_DIR}/sizzle.js + @@echo "Building selector code from Sizzle" + @@sed '/EXPOSE/r src/sizzle-jquery.js' ${SIZZLE_DIR}/sizzle.js | grep -v window.Sizzle > ${SRC_DIR}/selector.js + +lint: jquery + @@if test ! -z ${JS_ENGINE}; then \ + echo "Checking jQuery against JSLint..."; \ + ${JS_ENGINE} build/jslint-check.js; \ + else \ + echo "You must have NodeJS installed in order to test jQuery against JSLint."; \ + fi + +size: jquery min + @@if test ! -z ${JS_ENGINE}; then \ + gzip -c ${JQ_MIN} > ${JQ_MIN}.gz; \ + wc -c ${JQ} ${JQ_MIN} ${JQ_MIN}.gz | ${JS_ENGINE} ${BUILD_DIR}/sizer.js; \ + rm ${JQ_MIN}.gz; \ + else \ + echo "You must have NodeJS installed in order to size jQuery."; \ + fi + +min: jquery ${JQ_MIN} + +${JQ_MIN}: ${JQ} + @@if test ! -z ${JS_ENGINE}; then \ + echo "Minifying jQuery" ${JQ_MIN}; \ + ${COMPILER} ${JQ} > ${JQ_MIN}.tmp; \ + ${POST_COMPILER} ${JQ_MIN}.tmp > ${JQ_MIN}; \ + rm -f ${JQ_MIN}.tmp; \ + else \ + echo "You must have NodeJS installed in order to minify jQuery."; \ + fi + +clean: + @@echo "Removing Distribution directory:" ${DIST_DIR} + @@rm -rf ${DIST_DIR} + + @@echo "Removing built copy of Sizzle" + @@rm -f src/selector.js + +distclean: clean + @@echo "Removing submodules" + @@rm -rf test/qunit src/sizzle + +# change pointers for submodules and update them to what is specified in jQuery +# --merge doesn't work when doing an initial clone, thus test if we have non-existing +# submodules, then do an real update +update_submodules: + @@if [ -d .git ]; then \ + if git submodule status | grep -q -E '^-'; then \ + git submodule update --init --recursive; \ + else \ + git submodule update --init --recursive --merge; \ + fi; \ + fi; + +# update the submodules to the latest at the most logical branch +pull_submodules: + @@git submodule foreach "git pull \$$(git config remote.origin.url)" + @@git submodule summary + +pull: pull_submodules + @@git pull ${REMOTE} ${BRANCH} + diff --git a/build/jslint-check.js b/build/jslint-check.js new file mode 100644 index 0000000..72d6701 --- /dev/null +++ b/build/jslint-check.js @@ -0,0 +1,36 @@ +var JSLINT = require("./lib/jslint").JSLINT, + print = require("sys").print, + src = require("fs").readFileSync("dist/jquery.js", "utf8"); + +JSLINT(src, { evil: true, forin: true, maxerr: 100 }); + +// All of the following are known issues that we think are 'ok' +// (in contradiction with JSLint) more information here: +// http://docs.jquery.com/JQuery_Core_Style_Guidelines +var ok = { + "Expected an identifier and instead saw 'undefined' (a reserved word).": true, + "Use '===' to compare with 'null'.": true, + "Use '!==' to compare with 'null'.": true, + "Expected an assignment or function call and instead saw an expression.": true, + "Expected a 'break' statement before 'case'.": true, + "'e' is already defined.": true +}; + +var e = JSLINT.errors, found = 0, w; + +for ( var i = 0; i < e.length; i++ ) { + w = e[i]; + + if ( !ok[ w.reason ] ) { + found++; + print( "\n" + w.evidence + "\n" ); + print( " Problem at line " + w.line + " character " + w.character + ": " + w.reason ); + } +} + +if ( found > 0 ) { + print( "\n" + found + " Error(s) found.\n" ); + +} else { + print( "JSLint check passed.\n" ); +} diff --git a/build/lib/jslint.js b/build/lib/jslint.js new file mode 100644 index 0000000..f563292 --- /dev/null +++ b/build/lib/jslint.js @@ -0,0 +1,5504 @@ +// jslint.js +// 2010-02-20 + +/* +Copyright (c) 2002 Douglas Crockford (www.JSLint.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +The Software shall be used for Good, not Evil. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +/* + JSLINT is a global function. It takes two parameters. + + var myResult = JSLINT(source, option); + + The first parameter is either a string or an array of strings. If it is a + string, it will be split on '\n' or '\r'. If it is an array of strings, it + is assumed that each string represents one line. The source can be a + JavaScript text, or HTML text, or a Konfabulator text. + + The second parameter is an optional object of options which control the + operation of JSLINT. Most of the options are booleans: They are all are + optional and have a default value of false. + + If it checks out, JSLINT returns true. Otherwise, it returns false. + + If false, you can inspect JSLINT.errors to find out the problems. + JSLINT.errors is an array of objects containing these members: + + { + line : The line (relative to 0) at which the lint was found + character : The character (relative to 0) at which the lint was found + reason : The problem + evidence : The text line in which the problem occurred + raw : The raw message before the details were inserted + a : The first detail + b : The second detail + c : The third detail + d : The fourth detail + } + + If a fatal error was found, a null will be the last element of the + JSLINT.errors array. + + You can request a Function Report, which shows all of the functions + and the parameters and vars that they use. This can be used to find + implied global variables and other problems. The report is in HTML and + can be inserted in an HTML . + + var myReport = JSLINT.report(limited); + + If limited is true, then the report will be limited to only errors. + + You can request a data structure which contains JSLint's results. + + var myData = JSLINT.data(); + + It returns a structure with this form: + + { + errors: [ + { + line: NUMBER, + character: NUMBER, + reason: STRING, + evidence: STRING + } + ], + functions: [ + name: STRING, + line: NUMBER, + last: NUMBER, + param: [ + STRING + ], + closure: [ + STRING + ], + var: [ + STRING + ], + exception: [ + STRING + ], + outer: [ + STRING + ], + unused: [ + STRING + ], + global: [ + STRING + ], + label: [ + STRING + ] + ], + globals: [ + STRING + ], + member: { + STRING: NUMBER + }, + unuseds: [ + { + name: STRING, + line: NUMBER + } + ], + implieds: [ + { + name: STRING, + line: NUMBER + } + ], + urls: [ + STRING + ], + json: BOOLEAN + } + + Empty arrays will not be included. + +*/ + +/*jslint + evil: true, nomen: false, onevar: false, regexp: false, strict: true +*/ + +/*members "\b", "\t", "\n", "\f", "\r", "!=", "!==", "\"", "%", + "(begin)", "(breakage)", "(context)", "(error)", "(global)", + "(identifier)", "(last)", "(line)", "(loopage)", "(name)", "(onevar)", + "(params)", "(scope)", "(verb)", "*", "+", "++", "-", "--", "\/", + "<", "<=", "==", "===", ">", ">=", ADSAFE, Array, Boolean, + COM, Canvas, CustomAnimation, Date, Debug, E, Error, EvalError, + FadeAnimation, Flash, FormField, Frame, Function, HotKey, Image, JSON, + LN10, LN2, LOG10E, LOG2E, MAX_VALUE, MIN_VALUE, Math, MenuItem, + MoveAnimation, NEGATIVE_INFINITY, Number, Object, Option, PI, + POSITIVE_INFINITY, Point, RangeError, Rectangle, ReferenceError, RegExp, + ResizeAnimation, RotateAnimation, SQRT1_2, SQRT2, ScrollBar, String, + Style, SyntaxError, System, Text, TextArea, Timer, TypeError, URIError, + URL, Web, Window, XMLDOM, XMLHttpRequest, "\\", a, abbr, acronym, + addEventListener, address, adsafe, alert, aliceblue, animator, + antiquewhite, appleScript, applet, apply, approved, aqua, aquamarine, + area, arguments, arity, autocomplete, azure, b, background, + "background-attachment", "background-color", "background-image", + "background-position", "background-repeat", base, bdo, beep, beige, big, + bisque, bitwise, black, blanchedalmond, block, blockquote, blue, + blueviolet, blur, body, border, "border-bottom", "border-bottom-color", + "border-bottom-style", "border-bottom-width", "border-collapse", + "border-color", "border-left", "border-left-color", "border-left-style", + "border-left-width", "border-right", "border-right-color", + "border-right-style", "border-right-width", "border-spacing", + "border-style", "border-top", "border-top-color", "border-top-style", + "border-top-width", "border-width", bottom, br, brown, browser, + burlywood, button, bytesToUIString, c, cadetblue, call, callee, caller, + canvas, cap, caption, "caption-side", cases, center, charAt, charCodeAt, + character, chartreuse, chocolate, chooseColor, chooseFile, chooseFolder, + cite, clear, clearInterval, clearTimeout, clip, close, closeWidget, + closed, closure, cm, code, col, colgroup, color, comment, condition, + confirm, console, constructor, content, convertPathToHFS, + convertPathToPlatform, coral, cornflowerblue, cornsilk, + "counter-increment", "counter-reset", create, crimson, css, cursor, + cyan, d, darkblue, darkcyan, darkgoldenrod, darkgray, darkgreen, + darkkhaki, darkmagenta, darkolivegreen, darkorange, darkorchid, darkred, + darksalmon, darkseagreen, darkslateblue, darkslategray, darkturquoise, + darkviolet, data, dd, debug, decodeURI, decodeURIComponent, deeppink, + deepskyblue, defaultStatus, defineClass, del, deserialize, devel, dfn, + dimension, dimgray, dir, direction, display, div, dl, document, + dodgerblue, dt, edition, else, em, embed, empty, "empty-cells", + encodeURI, encodeURIComponent, entityify, eqeqeq, errors, escape, eval, + event, evidence, evil, ex, exception, exec, exps, fieldset, filesystem, + firebrick, first, float, floor, floralwhite, focus, focusWidget, font, + "font-face", "font-family", "font-size", "font-size-adjust", + "font-stretch", "font-style", "font-variant", "font-weight", + forestgreen, forin, form, fragment, frame, frames, frameset, from, + fromCharCode, fuchsia, fud, funct, function, functions, g, gainsboro, + gc, getComputedStyle, ghostwhite, global, globals, gold, goldenrod, + gray, green, greenyellow, h1, h2, h3, h4, h5, h6, hasOwnProperty, head, + height, help, history, honeydew, hotpink, hr, html, i, iTunes, id, + identifier, iframe, img, immed, implieds, in, include, indent, indexOf, + indianred, indigo, init, input, ins, isAlpha, isApplicationRunning, + isDigit, isFinite, isNaN, ivory, join, jslint, json, kbd, khaki, + konfabulatorVersion, label, labelled, lang, last, lavender, + lavenderblush, lawngreen, laxbreak, lbp, led, left, legend, + lemonchiffon, length, "letter-spacing", li, lib, lightblue, lightcoral, + lightcyan, lightgoldenrodyellow, lightgreen, lightpink, lightsalmon, + lightseagreen, lightskyblue, lightslategray, lightsteelblue, + lightyellow, lime, limegreen, line, "line-height", linen, link, + "list-style", "list-style-image", "list-style-position", + "list-style-type", load, loadClass, location, log, m, magenta, map, + margin, "margin-bottom", "margin-left", "margin-right", "margin-top", + "marker-offset", maroon, match, "max-height", "max-width", maxerr, maxlen, + md5, media, mediumaquamarine, mediumblue, mediumorchid, mediumpurple, + mediumseagreen, mediumslateblue, mediumspringgreen, mediumturquoise, + mediumvioletred, member, menu, message, meta, midnightblue, + "min-height", "min-width", mintcream, mistyrose, mm, moccasin, moveBy, + moveTo, name, navajowhite, navigator, navy, new, newcap, noframes, + nomen, noscript, nud, object, ol, oldlace, olive, olivedrab, on, + onbeforeunload, onblur, onerror, onevar, onfocus, onload, onresize, + onunload, opacity, open, openURL, opener, opera, optgroup, option, + orange, orangered, orchid, outer, outline, "outline-color", + "outline-style", "outline-width", overflow, "overflow-x", "overflow-y", + p, padding, "padding-bottom", "padding-left", "padding-right", + "padding-top", page, "page-break-after", "page-break-before", + palegoldenrod, palegreen, paleturquoise, palevioletred, papayawhip, + param, parent, parseFloat, parseInt, passfail, pc, peachpuff, peru, + pink, play, plum, plusplus, pop, popupMenu, position, powderblue, pre, + predef, preferenceGroups, preferences, print, prompt, prototype, pt, + purple, push, px, q, quit, quotes, random, range, raw, reach, readFile, + readUrl, reason, red, regexp, reloadWidget, removeEventListener, + replace, report, reserved, resizeBy, resizeTo, resolvePath, + resumeUpdates, rhino, right, rosybrown, royalblue, runCommand, + runCommandInBg, saddlebrown, safe, salmon, samp, sandybrown, saveAs, + savePreferences, screen, script, scroll, scrollBy, scrollTo, seagreen, + seal, search, seashell, select, serialize, setInterval, setTimeout, + shift, showWidgetPreferences, sidebar, sienna, silver, skyblue, + slateblue, slategray, sleep, slice, small, snow, sort, span, spawn, + speak, split, springgreen, src, status, steelblue, strict, strong, + style, styleproperty, sub, substr, sup, supplant, suppressUpdates, sync, + system, table, "table-layout", tan, tbody, td, teal, tellWidget, test, + "text-align", "text-decoration", "text-indent", "text-shadow", + "text-transform", textarea, tfoot, th, thead, thistle, title, + toLowerCase, toString, toUpperCase, toint32, token, tomato, top, tr, tt, + turquoise, type, u, ul, undef, unescape, "unicode-bidi", unused, + unwatch, updateNow, urls, value, valueOf, var, version, + "vertical-align", violet, visibility, watch, wheat, white, + "white-space", whitesmoke, widget, width, "word-spacing", "word-wrap", + yahooCheckLogin, yahooLogin, yahooLogout, yellow, yellowgreen, + "z-index" +*/ + + +// We build the application inside a function so that we produce only a single +// global variable. The function will be invoked, its return value is the JSLINT +// application itself. + +"use strict"; + +var JSLINT = (function () { + var adsafe_id, // The widget's ADsafe id. + adsafe_may, // The widget may load approved scripts. + adsafe_went, // ADSAFE.go has been called. + anonname, // The guessed name for anonymous functions. + approved, // ADsafe approved urls. + + atrule = { + media : true, + 'font-face': true, + page : true + }, + +// These are operators that should not be used with the ! operator. + + bang = { + '<': true, + '<=': true, + '==': true, + '===': true, + '!==': true, + '!=': true, + '>': true, + '>=': true, + '+': true, + '-': true, + '*': true, + '/': true, + '%': true + }, + +// These are members that should not be permitted in the safe subset. + + banned = { // the member names that ADsafe prohibits. + 'arguments' : true, + callee : true, + caller : true, + constructor : true, + 'eval' : true, + prototype : true, + unwatch : true, + valueOf : true, + watch : true + }, + + +// These are the JSLint boolean options. + + boolOptions = { + adsafe : true, // if ADsafe should be enforced + bitwise : true, // if bitwise operators should not be allowed + browser : true, // if the standard browser globals should be predefined + cap : true, // if upper case HTML should be allowed + css : true, // if CSS workarounds should be tolerated + debug : true, // if debugger statements should be allowed + devel : true, // if logging should be allowed (console, alert, etc.) + eqeqeq : true, // if === should be required + evil : true, // if eval should be allowed + forin : true, // if for in statements must filter + fragment : true, // if HTML fragments should be allowed + immed : true, // if immediate invocations must be wrapped in parens + laxbreak : true, // if line breaks should not be checked + newcap : true, // if constructor names must be capitalized + nomen : true, // if names should be checked + on : true, // if HTML event handlers should be allowed + onevar : true, // if only one var statement per function should be allowed + passfail : true, // if the scan should stop on first error + plusplus : true, // if increment/decrement should not be allowed + regexp : true, // if the . should not be allowed in regexp literals + rhino : true, // if the Rhino environment globals should be predefined + undef : true, // if variables should be declared before used + safe : true, // if use of some browser features should be restricted + sidebar : true, // if the System object should be predefined + strict : true, // require the "use strict"; pragma + sub : true, // if all forms of subscript notation are tolerated + white : true, // if strict whitespace rules apply + widget : true // if the Yahoo Widgets globals should be predefined + }, + +// browser contains a set of global names which are commonly provided by a +// web browser environment. + + browser = { + addEventListener: false, + blur : false, + clearInterval : false, + clearTimeout : false, + close : false, + closed : false, + defaultStatus : false, + document : false, + event : false, + focus : false, + frames : false, + getComputedStyle: false, + history : false, + Image : false, + length : false, + location : false, + moveBy : false, + moveTo : false, + name : false, + navigator : false, + onbeforeunload : true, + onblur : true, + onerror : true, + onfocus : true, + onload : true, + onresize : true, + onunload : true, + open : false, + opener : false, + Option : false, + parent : false, + print : false, + removeEventListener: false, + resizeBy : false, + resizeTo : false, + screen : false, + scroll : false, + scrollBy : false, + scrollTo : false, + setInterval : false, + setTimeout : false, + status : false, + top : false, + XMLHttpRequest : false + }, + + cssAttributeData, + cssAny, + + cssColorData = { + "aliceblue" : true, + "antiquewhite" : true, + "aqua" : true, + "aquamarine" : true, + "azure" : true, + "beige" : true, + "bisque" : true, + "black" : true, + "blanchedalmond" : true, + "blue" : true, + "blueviolet" : true, + "brown" : true, + "burlywood" : true, + "cadetblue" : true, + "chartreuse" : true, + "chocolate" : true, + "coral" : true, + "cornflowerblue" : true, + "cornsilk" : true, + "crimson" : true, + "cyan" : true, + "darkblue" : true, + "darkcyan" : true, + "darkgoldenrod" : true, + "darkgray" : true, + "darkgreen" : true, + "darkkhaki" : true, + "darkmagenta" : true, + "darkolivegreen" : true, + "darkorange" : true, + "darkorchid" : true, + "darkred" : true, + "darksalmon" : true, + "darkseagreen" : true, + "darkslateblue" : true, + "darkslategray" : true, + "darkturquoise" : true, + "darkviolet" : true, + "deeppink" : true, + "deepskyblue" : true, + "dimgray" : true, + "dodgerblue" : true, + "firebrick" : true, + "floralwhite" : true, + "forestgreen" : true, + "fuchsia" : true, + "gainsboro" : true, + "ghostwhite" : true, + "gold" : true, + "goldenrod" : true, + "gray" : true, + "green" : true, + "greenyellow" : true, + "honeydew" : true, + "hotpink" : true, + "indianred" : true, + "indigo" : true, + "ivory" : true, + "khaki" : true, + "lavender" : true, + "lavenderblush" : true, + "lawngreen" : true, + "lemonchiffon" : true, + "lightblue" : true, + "lightcoral" : true, + "lightcyan" : true, + "lightgoldenrodyellow" : true, + "lightgreen" : true, + "lightpink" : true, + "lightsalmon" : true, + "lightseagreen" : true, + "lightskyblue" : true, + "lightslategray" : true, + "lightsteelblue" : true, + "lightyellow" : true, + "lime" : true, + "limegreen" : true, + "linen" : true, + "magenta" : true, + "maroon" : true, + "mediumaquamarine" : true, + "mediumblue" : true, + "mediumorchid" : true, + "mediumpurple" : true, + "mediumseagreen" : true, + "mediumslateblue" : true, + "mediumspringgreen" : true, + "mediumturquoise" : true, + "mediumvioletred" : true, + "midnightblue" : true, + "mintcream" : true, + "mistyrose" : true, + "moccasin" : true, + "navajowhite" : true, + "navy" : true, + "oldlace" : true, + "olive" : true, + "olivedrab" : true, + "orange" : true, + "orangered" : true, + "orchid" : true, + "palegoldenrod" : true, + "palegreen" : true, + "paleturquoise" : true, + "palevioletred" : true, + "papayawhip" : true, + "peachpuff" : true, + "peru" : true, + "pink" : true, + "plum" : true, + "powderblue" : true, + "purple" : true, + "red" : true, + "rosybrown" : true, + "royalblue" : true, + "saddlebrown" : true, + "salmon" : true, + "sandybrown" : true, + "seagreen" : true, + "seashell" : true, + "sienna" : true, + "silver" : true, + "skyblue" : true, + "slateblue" : true, + "slategray" : true, + "snow" : true, + "springgreen" : true, + "steelblue" : true, + "tan" : true, + "teal" : true, + "thistle" : true, + "tomato" : true, + "turquoise" : true, + "violet" : true, + "wheat" : true, + "white" : true, + "whitesmoke" : true, + "yellow" : true, + "yellowgreen" : true + }, + + cssBorderStyle, + cssBreak, + + cssLengthData = { + '%': true, + 'cm': true, + 'em': true, + 'ex': true, + 'in': true, + 'mm': true, + 'pc': true, + 'pt': true, + 'px': true + }, + + cssOverflow, + + devel = { + alert : false, + confirm : false, + console : false, + Debug : false, + opera : false, + prompt : false + }, + + escapes = { + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + '"' : '\\"', + '/' : '\\/', + '\\': '\\\\' + }, + + funct, // The current function + + functionicity = [ + 'closure', 'exception', 'global', 'label', + 'outer', 'unused', 'var' + ], + + functions, // All of the functions + + global, // The global scope + htmltag = { + a: {}, + abbr: {}, + acronym: {}, + address: {}, + applet: {}, + area: {empty: true, parent: ' map '}, + b: {}, + base: {empty: true, parent: ' head '}, + bdo: {}, + big: {}, + blockquote: {}, + body: {parent: ' html noframes '}, + br: {empty: true}, + button: {}, + canvas: {parent: ' body p div th td '}, + caption: {parent: ' table '}, + center: {}, + cite: {}, + code: {}, + col: {empty: true, parent: ' table colgroup '}, + colgroup: {parent: ' table '}, + dd: {parent: ' dl '}, + del: {}, + dfn: {}, + dir: {}, + div: {}, + dl: {}, + dt: {parent: ' dl '}, + em: {}, + embed: {}, + fieldset: {}, + font: {}, + form: {}, + frame: {empty: true, parent: ' frameset '}, + frameset: {parent: ' html frameset '}, + h1: {}, + h2: {}, + h3: {}, + h4: {}, + h5: {}, + h6: {}, + head: {parent: ' html '}, + html: {parent: '*'}, + hr: {empty: true}, + i: {}, + iframe: {}, + img: {empty: true}, + input: {empty: true}, + ins: {}, + kbd: {}, + label: {}, + legend: {parent: ' fieldset '}, + li: {parent: ' dir menu ol ul '}, + link: {empty: true, parent: ' head '}, + map: {}, + menu: {}, + meta: {empty: true, parent: ' head noframes noscript '}, + noframes: {parent: ' html body '}, + noscript: {parent: ' body head noframes '}, + object: {}, + ol: {}, + optgroup: {parent: ' select '}, + option: {parent: ' optgroup select '}, + p: {}, + param: {empty: true, parent: ' applet object '}, + pre: {}, + q: {}, + samp: {}, + script: {empty: true, parent: ' body div frame head iframe p pre span '}, + select: {}, + small: {}, + span: {}, + strong: {}, + style: {parent: ' head ', empty: true}, + sub: {}, + sup: {}, + table: {}, + tbody: {parent: ' table '}, + td: {parent: ' tr '}, + textarea: {}, + tfoot: {parent: ' table '}, + th: {parent: ' tr '}, + thead: {parent: ' table '}, + title: {parent: ' head '}, + tr: {parent: ' table tbody thead tfoot '}, + tt: {}, + u: {}, + ul: {}, + 'var': {} + }, + + ids, // HTML ids + implied, // Implied globals + inblock, + indent, + jsonmode, + lines, + lookahead, + member, + membersOnly, + nexttoken, + noreach, + option, + predefined, // Global variables defined by option + prereg, + prevtoken, + + rhino = { + defineClass : false, + deserialize : false, + gc : false, + help : false, + load : false, + loadClass : false, + print : false, + quit : false, + readFile : false, + readUrl : false, + runCommand : false, + seal : false, + serialize : false, + spawn : false, + sync : false, + toint32 : false, + version : false + }, + + scope, // The current scope + + sidebar = { + System : false + }, + + src, + stack, + +// standard contains the global names that are provided by the +// ECMAScript standard. + + standard = { + Array : false, + Boolean : false, + Date : false, + decodeURI : false, + decodeURIComponent : false, + encodeURI : false, + encodeURIComponent : false, + Error : false, + 'eval' : false, + EvalError : false, + Function : false, + hasOwnProperty : false, + isFinite : false, + isNaN : false, + JSON : false, + Math : false, + Number : false, + Object : false, + parseInt : false, + parseFloat : false, + RangeError : false, + ReferenceError : false, + RegExp : false, + String : false, + SyntaxError : false, + TypeError : false, + URIError : false + }, + + standard_member = { + E : true, + LN2 : true, + LN10 : true, + LOG2E : true, + LOG10E : true, + PI : true, + SQRT1_2 : true, + SQRT2 : true, + MAX_VALUE : true, + MIN_VALUE : true, + NEGATIVE_INFINITY : true, + POSITIVE_INFINITY : true + }, + + strict_mode, + syntax = {}, + tab, + token, + urls, + warnings, + +// widget contains the global names which are provided to a Yahoo +// (fna Konfabulator) widget. + + widget = { + alert : true, + animator : true, + appleScript : true, + beep : true, + bytesToUIString : true, + Canvas : true, + chooseColor : true, + chooseFile : true, + chooseFolder : true, + closeWidget : true, + COM : true, + convertPathToHFS : true, + convertPathToPlatform : true, + CustomAnimation : true, + escape : true, + FadeAnimation : true, + filesystem : true, + Flash : true, + focusWidget : true, + form : true, + FormField : true, + Frame : true, + HotKey : true, + Image : true, + include : true, + isApplicationRunning : true, + iTunes : true, + konfabulatorVersion : true, + log : true, + md5 : true, + MenuItem : true, + MoveAnimation : true, + openURL : true, + play : true, + Point : true, + popupMenu : true, + preferenceGroups : true, + preferences : true, + print : true, + prompt : true, + random : true, + Rectangle : true, + reloadWidget : true, + ResizeAnimation : true, + resolvePath : true, + resumeUpdates : true, + RotateAnimation : true, + runCommand : true, + runCommandInBg : true, + saveAs : true, + savePreferences : true, + screen : true, + ScrollBar : true, + showWidgetPreferences : true, + sleep : true, + speak : true, + Style : true, + suppressUpdates : true, + system : true, + tellWidget : true, + Text : true, + TextArea : true, + Timer : true, + unescape : true, + updateNow : true, + URL : true, + Web : true, + widget : true, + Window : true, + XMLDOM : true, + XMLHttpRequest : true, + yahooCheckLogin : true, + yahooLogin : true, + yahooLogout : true + }, + +// xmode is used to adapt to the exceptions in html parsing. +// It can have these states: +// false .js script file +// html +// outer +// script +// style +// scriptstring +// styleproperty + + xmode, + xquote, + +// unsafe comment or string + ax = /@cc|<\/?|script|\]*s\]|<\s*!|</i, +// unsafe characters that are silently deleted by one or more browsers + cx = /[\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/, +// token + tx = /^\s*([(){}\[.,:;'"~\?\]#@]|==?=?|\/(\*(jslint|members?|global)?|=|\/)?|\*[\/=]?|\+[+=]?|-[\-=]?|%=?|&[&=]?|\|[|=]?|>>?>?=?|<([\/=!]|\!(\[|--)?|<=?)?|\^=?|\!=?=?|[a-zA-Z_$][a-zA-Z0-9_$]*|[0-9]+([xX][0-9a-fA-F]+|\.[0-9]*)?([eE][+\-]?[0-9]+)?)/, +// html token +//////// hx = /^\s*(['"=>\/&#]|<(?:\/|\!(?:--)?)?|[a-zA-Z][a-zA-Z0-9_\-]*|[0-9]+|--|.)/, + hx = /^\s*(['"=>\/&#]|<(?:\/|\!(?:--)?)?|[a-zA-Z][a-zA-Z0-9_\-]*|[0-9]+|--)/, +// characters in strings that need escapement + nx = /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/, + nxg = /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, +// outer html token + ox = /[>&]|<[\/!]?|--/, +// star slash + lx = /\*\/|\/\*/, +// identifier + ix = /^([a-zA-Z_$][a-zA-Z0-9_$]*)$/, +// javascript url + jx = /^(?:javascript|jscript|ecmascript|vbscript|mocha|livescript)\s*:/i, +// url badness + ux = /&|\+|\u00AD|\.\.|\/\*|%[^;]|base64|url|expression|data|mailto/i, +// style + sx = /^\s*([{:#%.=,>+\[\]@()"';]|\*=?|\$=|\|=|\^=|~=|[a-zA-Z_][a-zA-Z0-9_\-]*|[0-9]+|<\/|\/\*)/, + ssx = /^\s*([@#!"'};:\-%.=,+\[\]()*_]|[a-zA-Z][a-zA-Z0-9._\-]*|\/\*?|\d+(?:\.\d+)?|<\/)/, +// attributes characters + qx = /[^a-zA-Z0-9-_\/ ]/, +// query characters for ids + dx = /[\[\]\/\\"'*<>.&:(){}+=#]/, + + rx = { + outer: hx, + html: hx, + style: sx, + styleproperty: ssx + }; + + function F() {} + + if (typeof Object.create !== 'function') { + Object.create = function (o) { + F.prototype = o; + return new F(); + }; + } + + + function is_own(object, name) { + return Object.prototype.hasOwnProperty.call(object, name); + } + + + function combine(t, o) { + var n; + for (n in o) { + if (is_own(o, n)) { + t[n] = o[n]; + } + } + } + + String.prototype.entityify = function () { + return this. + replace(/&/g, '&'). + replace(//g, '>'); + }; + + String.prototype.isAlpha = function () { + return (this >= 'a' && this <= 'z\uffff') || + (this >= 'A' && this <= 'Z\uffff'); + }; + + + String.prototype.isDigit = function () { + return (this >= '0' && this <= '9'); + }; + + + String.prototype.supplant = function (o) { + return this.replace(/\{([^{}]*)\}/g, function (a, b) { + var r = o[b]; + return typeof r === 'string' || typeof r === 'number' ? r : a; + }); + }; + + String.prototype.name = function () { + +// If the string looks like an identifier, then we can return it as is. +// If the string contains no control characters, no quote characters, and no +// backslash characters, then we can simply slap some quotes around it. +// Otherwise we must also replace the offending characters with safe +// sequences. + + if (ix.test(this)) { + return this; + } + if (nx.test(this)) { + return '"' + this.replace(nxg, function (a) { + var c = escapes[a]; + if (c) { + return c; + } + return '\\u' + ('0000' + a.charCodeAt().toString(16)).slice(-4); + }) + '"'; + } + return '"' + this + '"'; + }; + + + function assume() { + if (!option.safe) { + if (option.rhino) { + combine(predefined, rhino); + } + if (option.devel) { + combine(predefined, devel); + } + if (option.browser || option.sidebar) { + combine(predefined, browser); + } + if (option.sidebar) { + combine(predefined, sidebar); + } + if (option.widget) { + combine(predefined, widget); + } + } + } + + +// Produce an error warning. + + function quit(m, l, ch) { + throw { + name: 'JSLintError', + line: l, + character: ch, + message: m + " (" + Math.floor((l / lines.length) * 100) + + "% scanned)." + }; + } + + function warning(m, t, a, b, c, d) { + var ch, l, w; + t = t || nexttoken; + if (t.id === '(end)') { // `~ + t = token; + } + l = t.line || 0; + ch = t.from || 0; + w = { + id: '(error)', + raw: m, + evidence: lines[l - 1] || '', + line: l, + character: ch, + a: a, + b: b, + c: c, + d: d + }; + w.reason = m.supplant(w); + JSLINT.errors.push(w); + if (option.passfail) { + quit('Stopping. ', l, ch); + } + warnings += 1; + if (warnings >= option.maxerr) { + quit("Too many errors.", l, ch); + } + return w; + } + + function warningAt(m, l, ch, a, b, c, d) { + return warning(m, { + line: l, + from: ch + }, a, b, c, d); + } + + function error(m, t, a, b, c, d) { + var w = warning(m, t, a, b, c, d); + quit("Stopping, unable to continue.", w.line, w.character); + } + + function errorAt(m, l, ch, a, b, c, d) { + return error(m, { + line: l, + from: ch + }, a, b, c, d); + } + + + +// lexical analysis + + var lex = (function lex() { + var character, from, line, s; + +// Private lex methods + + function nextLine() { + var at; + if (line >= lines.length) { + return false; + } + character = 1; + s = lines[line]; + line += 1; + at = s.search(/ \t/); + if (at >= 0) { + warningAt("Mixed spaces and tabs.", line, at + 1); + } + s = s.replace(/\t/g, tab); + at = s.search(cx); + if (at >= 0) { + warningAt("Unsafe character.", line, at); + } + if (option.maxlen && option.maxlen < s.length) { + warningAt("Line too long.", line, s.length); + } + return true; + } + +// Produce a token object. The token inherits from a syntax symbol. + + function it(type, value) { + var i, t; + if (type === '(color)') { + t = {type: type}; + } else if (type === '(punctuator)' || + (type === '(identifier)' && is_own(syntax, value))) { + t = syntax[value] || syntax['(error)']; + } else { + t = syntax[type]; + } + t = Object.create(t); + if (type === '(string)' || type === '(range)') { + if (jx.test(value)) { + warningAt("Script URL.", line, from); + } + } + if (type === '(identifier)') { + t.identifier = true; + if (value === '__iterator__' || value === '__proto__') { + errorAt("Reserved name '{a}'.", + line, from, value); + } else if (option.nomen && + (value.charAt(0) === '_' || + value.charAt(value.length - 1) === '_')) { + warningAt("Unexpected {a} in '{b}'.", line, from, + "dangling '_'", value); + } + } + t.value = value; + t.line = line; + t.character = character; + t.from = from; + i = t.id; + if (i !== '(endline)') { + prereg = i && + (('(,=:[!&|?{};'.indexOf(i.charAt(i.length - 1)) >= 0) || + i === 'return'); + } + return t; + } + +// Public lex methods + + return { + init: function (source) { + if (typeof source === 'string') { + lines = source. + replace(/\r\n/g, '\n'). + replace(/\r/g, '\n'). + split('\n'); + } else { + lines = source; + } + line = 0; + nextLine(); + from = 1; + }, + + range: function (begin, end) { + var c, value = ''; + from = character; + if (s.charAt(0) !== begin) { + errorAt("Expected '{a}' and instead saw '{b}'.", + line, character, begin, s.charAt(0)); + } + for (;;) { + s = s.slice(1); + character += 1; + c = s.charAt(0); + switch (c) { + case '': + errorAt("Missing '{a}'.", line, character, c); + break; + case end: + s = s.slice(1); + character += 1; + return it('(range)', value); + case xquote: + case '\\': + warningAt("Unexpected '{a}'.", line, character, c); + } + value += c; + } + + }, + +// token -- this is called by advance to get the next token. + + token: function () { + var b, c, captures, d, depth, high, i, l, low, q, t; + + function match(x) { + var r = x.exec(s), r1; + if (r) { + l = r[0].length; + r1 = r[1]; + c = r1.charAt(0); + s = s.substr(l); + from = character + l - r1.length; + character += l; + return r1; + } + } + + function string(x) { + var c, j, r = ''; + + if (jsonmode && x !== '"') { + warningAt("Strings must use doublequote.", + line, character); + } + + if (xquote === x || (xmode === 'scriptstring' && !xquote)) { + return it('(punctuator)', x); + } + + function esc(n) { + var i = parseInt(s.substr(j + 1, n), 16); + j += n; + if (i >= 32 && i <= 126 && + i !== 34 && i !== 92 && i !== 39) { + warningAt("Unnecessary escapement.", line, character); + } + character += n; + c = String.fromCharCode(i); + } + j = 0; + for (;;) { + while (j >= s.length) { + j = 0; + if (xmode !== 'html' || !nextLine()) { + errorAt("Unclosed string.", line, from); + } + } + c = s.charAt(j); + if (c === x) { + character += 1; + s = s.substr(j + 1); + return it('(string)', r, x); + } + if (c < ' ') { + if (c === '\n' || c === '\r') { + break; + } + warningAt("Control character in string: {a}.", + line, character + j, s.slice(0, j)); + } else if (c === xquote) { + warningAt("Bad HTML string", line, character + j); + } else if (c === '<') { + if (option.safe && xmode === 'html') { + warningAt("ADsafe string violation.", + line, character + j); + } else if (s.charAt(j + 1) === '/' && (xmode || option.safe)) { + warningAt("Expected '<\\/' and instead saw ' 0) { + character += 1; + s = s.slice(i); + break; + } else { + if (!nextLine()) { + return it('(end)', ''); + } + } + } +// t = match(rx[xmode] || tx); +// if (!t) { +// if (xmode === 'html') { +// return it('(error)', s.charAt(0)); +// } else { +// t = ''; +// c = ''; +// while (s && s < '!') { +// s = s.substr(1); +// } +// if (s) { +// errorAt("Unexpected '{a}'.", +// line, character, s.substr(0, 1)); +// } +// } + t = match(rx[xmode] || tx); + if (!t) { + t = ''; + c = ''; + while (s && s < '!') { + s = s.substr(1); + } + if (s) { + if (xmode === 'html') { + return it('(error)', s.charAt(0)); + } else { + errorAt("Unexpected '{a}'.", + line, character, s.substr(0, 1)); + } + } + } else { + + // identifier + + if (c.isAlpha() || c === '_' || c === '$') { + return it('(identifier)', t); + } + + // number + + if (c.isDigit()) { + if (xmode !== 'style' && !isFinite(Number(t))) { + warningAt("Bad number '{a}'.", + line, character, t); + } + if (xmode !== 'style' && + xmode !== 'styleproperty' && + s.substr(0, 1).isAlpha()) { + warningAt("Missing space after '{a}'.", + line, character, t); + } + if (c === '0') { + d = t.substr(1, 1); + if (d.isDigit()) { + if (token.id !== '.' && xmode !== 'styleproperty') { + warningAt("Don't use extra leading zeros '{a}'.", + line, character, t); + } + } else if (jsonmode && (d === 'x' || d === 'X')) { + warningAt("Avoid 0x-. '{a}'.", + line, character, t); + } + } + if (t.substr(t.length - 1) === '.') { + warningAt( + "A trailing decimal point can be confused with a dot '{a}'.", + line, character, t); + } + return it('(number)', t); + } + switch (t) { + + // string + + case '"': + case "'": + return string(t); + + // // comment + + case '//': + if (src || (xmode && xmode !== 'script')) { + warningAt("Unexpected comment.", line, character); + } else if (xmode === 'script' && /<\s*\//i.test(s)) { + warningAt("Unexpected <\/ in comment.", line, character); + } else if ((option.safe || xmode === 'script') && ax.test(s)) { + warningAt("Dangerous comment.", line, character); + } + s = ''; + token.comment = true; + break; + + // /* comment + + case '/*': + if (src || (xmode && xmode !== 'script' && xmode !== 'style' && xmode !== 'styleproperty')) { + warningAt("Unexpected comment.", line, character); + } + if (option.safe && ax.test(s)) { + warningAt("ADsafe comment violation.", line, character); + } + for (;;) { + i = s.search(lx); + if (i >= 0) { + break; + } + if (!nextLine()) { + errorAt("Unclosed comment.", line, character); + } else { + if (option.safe && ax.test(s)) { + warningAt("ADsafe comment violation.", line, character); + } + } + } + character += i + 2; + if (s.substr(i, 1) === '/') { + errorAt("Nested comment.", line, character); + } + s = s.substr(i + 2); + token.comment = true; + break; + + // /*members /*jslint /*global + + case '/*members': + case '/*member': + case '/*jslint': + case '/*global': + case '*/': + return { + value: t, + type: 'special', + line: line, + character: character, + from: from + }; + + case '': + break; + // / + case '/': + if (token.id === '/=') { + errorAt( +"A regular expression literal can be confused with '/='.", line, from); + } + if (prereg) { + depth = 0; + captures = 0; + l = 0; + for (;;) { + b = true; + c = s.charAt(l); + l += 1; + switch (c) { + case '': + errorAt("Unclosed regular expression.", line, from); + return; + case '/': + if (depth > 0) { + warningAt("Unescaped '{a}'.", line, from + l, '/'); + } + c = s.substr(0, l - 1); + q = { + g: true, + i: true, + m: true + }; + while (q[s.charAt(l)] === true) { + q[s.charAt(l)] = false; + l += 1; + } + character += l; + s = s.substr(l); + q = s.charAt(0); + if (q === '/' || q === '*') { + errorAt("Confusing regular expression.", line, from); + } + return it('(regexp)', c); + case '\\': + c = s.charAt(l); + if (c < ' ') { + warningAt("Unexpected control character in regular expression.", line, from + l); + } else if (c === '<') { + warningAt("Unexpected escaped character '{a}' in regular expression.", line, from + l, c); + } + l += 1; + break; + case '(': + depth += 1; + b = false; + if (s.charAt(l) === '?') { + l += 1; + switch (s.charAt(l)) { + case ':': + case '=': + case '!': + l += 1; + break; + default: + warningAt("Expected '{a}' and instead saw '{b}'.", line, from + l, ':', s.charAt(l)); + } + } else { + captures += 1; + } + break; + case '|': + b = false; + break; + case ')': + if (depth === 0) { + warningAt("Unescaped '{a}'.", line, from + l, ')'); + } else { + depth -= 1; + } + break; + case ' ': + q = 1; + while (s.charAt(l) === ' ') { + l += 1; + q += 1; + } + if (q > 1) { + warningAt("Spaces are hard to count. Use {{a}}.", line, from + l, q); + } + break; + case '[': + c = s.charAt(l); + if (c === '^') { + l += 1; + if (option.regexp) { + warningAt("Insecure '{a}'.", line, from + l, c); + } + } + q = false; + if (c === ']') { + warningAt("Empty class.", line, from + l - 1); + q = true; + } + klass: do { + c = s.charAt(l); + l += 1; + switch (c) { + case '[': + case '^': + warningAt("Unescaped '{a}'.", line, from + l, c); + q = true; + break; + case '-': + if (q) { + q = false; + } else { + warningAt("Unescaped '{a}'.", line, from + l, '-'); + q = true; + } + break; + case ']': + if (!q) { + warningAt("Unescaped '{a}'.", line, from + l - 1, '-'); + } + break klass; + case '\\': + c = s.charAt(l); + if (c < ' ') { + warningAt("Unexpected control character in regular expression.", line, from + l); + } else if (c === '<') { + warningAt("Unexpected escaped character '{a}' in regular expression.", line, from + l, c); + } + l += 1; + q = true; + break; + case '/': + warningAt("Unescaped '{a}'.", line, from + l - 1, '/'); + q = true; + break; + case '<': + if (xmode === 'script') { + c = s.charAt(l); + if (c === '!' || c === '/') { + warningAt("HTML confusion in regular expression '<{a}'.", line, from + l, c); + } + } + q = true; + break; + default: + q = true; + } + } while (c); + break; + case '.': + if (option.regexp) { + warningAt("Insecure '{a}'.", line, from + l, c); + } + break; + case ']': + case '?': + case '{': + case '}': + case '+': + case '*': + warningAt("Unescaped '{a}'.", line, from + l, c); + break; + case '<': + if (xmode === 'script') { + c = s.charAt(l); + if (c === '!' || c === '/') { + warningAt("HTML confusion in regular expression '<{a}'.", line, from + l, c); + } + } + } + if (b) { + switch (s.charAt(l)) { + case '?': + case '+': + case '*': + l += 1; + if (s.charAt(l) === '?') { + l += 1; + } + break; + case '{': + l += 1; + c = s.charAt(l); + if (c < '0' || c > '9') { + warningAt("Expected a number and instead saw '{a}'.", line, from + l, c); + } + l += 1; + low = +c; + for (;;) { + c = s.charAt(l); + if (c < '0' || c > '9') { + break; + } + l += 1; + low = +c + (low * 10); + } + high = low; + if (c === ',') { + l += 1; + high = Infinity; + c = s.charAt(l); + if (c >= '0' && c <= '9') { + l += 1; + high = +c; + for (;;) { + c = s.charAt(l); + if (c < '0' || c > '9') { + break; + } + l += 1; + high = +c + (high * 10); + } + } + } + if (s.charAt(l) !== '}') { + warningAt("Expected '{a}' and instead saw '{b}'.", line, from + l, '}', c); + } else { + l += 1; + } + if (s.charAt(l) === '?') { + l += 1; + } + if (low > high) { + warningAt("'{a}' should not be greater than '{b}'.", line, from + l, low, high); + } + } + } + } + c = s.substr(0, l - 1); + character += l; + s = s.substr(l); + return it('(regexp)', c); + } + return it('(punctuator)', t); + + // punctuator + + case '.", line, character); + } + character += 3; + s = s.slice(i + 3); + break; + case '#': + if (xmode === 'html' || xmode === 'styleproperty') { + for (;;) { + c = s.charAt(0); + if ((c < '0' || c > '9') && + (c < 'a' || c > 'f') && + (c < 'A' || c > 'F')) { + break; + } + character += 1; + s = s.substr(1); + t += c; + } + if (t.length !== 4 && t.length !== 7) { + warningAt("Bad hex color '{a}'.", line, + from + l, t); + } + return it('(color)', t); + } + return it('(punctuator)', t); + default: + if (xmode === 'outer' && c === '&') { + character += 1; + s = s.substr(1); + for (;;) { + c = s.charAt(0); + character += 1; + s = s.substr(1); + if (c === ';') { + break; + } + if (!((c >= '0' && c <= '9') || + (c >= 'a' && c <= 'z') || + c === '#')) { + errorAt("Bad entity", line, from + l, + character); + } + } + break; + } + return it('(punctuator)', t); + } + } + } + } + }; + }()); + + + function addlabel(t, type) { + + if (option.safe && funct['(global)'] && typeof predefined[t] !== 'boolean') { + warning('ADsafe global: ' + t + '.', token); + } else if (t === 'hasOwnProperty') { + warning("'hasOwnProperty' is a really bad name."); + } + +// Define t in the current function in the current scope. + + if (is_own(funct, t) && !funct['(global)']) { + warning(funct[t] === true ? + "'{a}' was used before it was defined." : + "'{a}' is already defined.", + nexttoken, t); + } + funct[t] = type; + if (funct['(global)']) { + global[t] = funct; + if (is_own(implied, t)) { + warning("'{a}' was used before it was defined.", nexttoken, t); + delete implied[t]; + } + } else { + scope[t] = funct; + } + } + + + function doOption() { + var b, obj, filter, o = nexttoken.value, t, v; + switch (o) { + case '*/': + error("Unbegun comment."); + break; + case '/*members': + case '/*member': + o = '/*members'; + if (!membersOnly) { + membersOnly = {}; + } + obj = membersOnly; + break; + case '/*jslint': + if (option.safe) { + warning("ADsafe restriction."); + } + obj = option; + filter = boolOptions; + break; + case '/*global': + if (option.safe) { + warning("ADsafe restriction."); + } + obj = predefined; + break; + default: + } + t = lex.token(); +loop: for (;;) { + for (;;) { + if (t.type === 'special' && t.value === '*/') { + break loop; + } + if (t.id !== '(endline)' && t.id !== ',') { + break; + } + t = lex.token(); + } + if (t.type !== '(string)' && t.type !== '(identifier)' && + o !== '/*members') { + error("Bad option.", t); + } + v = lex.token(); + if (v.id === ':') { + v = lex.token(); + if (obj === membersOnly) { + error("Expected '{a}' and instead saw '{b}'.", + t, '*/', ':'); + } + if (t.value === 'indent' && o === '/*jslint') { + b = +v.value; + if (typeof b !== 'number' || !isFinite(b) || b <= 0 || + Math.floor(b) !== b) { + error("Expected a small integer and instead saw '{a}'.", + v, v.value); + } + obj.white = true; + obj.indent = b; + } else if (t.value === 'maxerr' && o === '/*jslint') { + b = +v.value; + if (typeof b !== 'number' || !isFinite(b) || b <= 0 || + Math.floor(b) !== b) { + error("Expected a small integer and instead saw '{a}'.", + v, v.value); + } + obj.maxerr = b; + } else if (t.value === 'maxlen' && o === '/*jslint') { + b = +v.value; + if (typeof b !== 'number' || !isFinite(b) || b <= 0 || + Math.floor(b) !== b) { + error("Expected a small integer and instead saw '{a}'.", + v, v.value); + } + obj.maxlen = b; + } else if (v.value === 'true') { + obj[t.value] = true; + } else if (v.value === 'false') { + obj[t.value] = false; + } else { + error("Bad option value.", v); + } + t = lex.token(); + } else { + if (o === '/*jslint') { + error("Missing option value.", t); + } + obj[t.value] = false; + t = v; + } + } + if (filter) { + assume(); + } + } + + +// We need a peek function. If it has an argument, it peeks that much farther +// ahead. It is used to distinguish +// for ( var i in ... +// from +// for ( var i = ... + + function peek(p) { + var i = p || 0, j = 0, t; + + while (j <= i) { + t = lookahead[j]; + if (!t) { + t = lookahead[j] = lex.token(); + } + j += 1; + } + return t; + } + + + +// Produce the next token. It looks for programming errors. + + function advance(id, t) { + switch (token.id) { + case '(number)': + if (nexttoken.id === '.') { + warning( +"A dot following a number can be confused with a decimal point.", token); + } + break; + case '-': + if (nexttoken.id === '-' || nexttoken.id === '--') { + warning("Confusing minusses."); + } + break; + case '+': + if (nexttoken.id === '+' || nexttoken.id === '++') { + warning("Confusing plusses."); + } + break; + } + if (token.type === '(string)' || token.identifier) { + anonname = token.value; + } + + if (id && nexttoken.id !== id) { + if (t) { + if (nexttoken.id === '(end)') { + warning("Unmatched '{a}'.", t, t.id); + } else { + warning("Expected '{a}' to match '{b}' from line {c} and instead saw '{d}'.", + nexttoken, id, t.id, t.line, nexttoken.value); + } + } else if (nexttoken.type !== '(identifier)' || + nexttoken.value !== id) { + warning("Expected '{a}' and instead saw '{b}'.", + nexttoken, id, nexttoken.value); + } + } + prevtoken = token; + token = nexttoken; + for (;;) { + nexttoken = lookahead.shift() || lex.token(); + if (nexttoken.id === '(end)' || nexttoken.id === '(error)') { + return; + } + if (nexttoken.type === 'special') { + doOption(); + } else { + if (nexttoken.id !== '(endline)') { + break; + } + } + } + } + + +// This is the heart of JSLINT, the Pratt parser. In addition to parsing, it +// is looking for ad hoc lint patterns. We add to Pratt's model .fud, which is +// like nud except that it is only used on the first token of a statement. +// Having .fud makes it much easier to define JavaScript. I retained Pratt's +// nomenclature. + +// .nud Null denotation +// .fud First null denotation +// .led Left denotation +// lbp Left binding power +// rbp Right binding power + +// They are key to the parsing method called Top Down Operator Precedence. + + function parse(rbp, initial) { + var left; + if (nexttoken.id === '(end)') { + error("Unexpected early end of program.", token); + } + advance(); + if (option.safe && typeof predefined[token.value] === 'boolean' && + (nexttoken.id !== '(' && nexttoken.id !== '.')) { + warning('ADsafe violation.', token); + } + if (initial) { + anonname = 'anonymous'; + funct['(verb)'] = token.value; + } + if (initial === true && token.fud) { + left = token.fud(); + } else { + if (token.nud) { + left = token.nud(); + } else { + if (nexttoken.type === '(number)' && token.id === '.') { + warning( +"A leading decimal point can be confused with a dot: '.{a}'.", + token, nexttoken.value); + advance(); + return token; + } else { + error("Expected an identifier and instead saw '{a}'.", + token, token.id); + } + } + while (rbp < nexttoken.lbp) { + advance(); + if (token.led) { + left = token.led(left); + } else { + error("Expected an operator and instead saw '{a}'.", + token, token.id); + } + } + } + return left; + } + + +// Functions for conformance of style. + + function adjacent(left, right) { + left = left || token; + right = right || nexttoken; + if (option.white || xmode === 'styleproperty' || xmode === 'style') { + if (left.character !== right.from && left.line === right.line) { + warning("Unexpected space after '{a}'.", right, left.value); + } + } + } + + function nospace(left, right) { + left = left || token; + right = right || nexttoken; + if (option.white && !left.comment) { + if (left.line === right.line) { + adjacent(left, right); + } + } + } + + + function nonadjacent(left, right) { + if (option.white) { + left = left || token; + right = right || nexttoken; + if (left.line === right.line && left.character === right.from) { + warning("Missing space after '{a}'.", + nexttoken, left.value); + } + } + } + + function nobreaknonadjacent(left, right) { + left = left || token; + right = right || nexttoken; + if (!option.laxbreak && left.line !== right.line) { + warning("Bad line breaking before '{a}'.", right, right.id); + } else if (option.white) { + left = left || token; + right = right || nexttoken; + if (left.character === right.from) { + warning("Missing space after '{a}'.", + nexttoken, left.value); + } + } + } + + function indentation(bias) { + var i; + if (option.white && nexttoken.id !== '(end)') { + i = indent + (bias || 0); + if (nexttoken.from !== i) { + warning("Expected '{a}' to have an indentation at {b} instead at {c}.", + nexttoken, nexttoken.value, i, nexttoken.from); + } + } + } + + function nolinebreak(t) { + t = t || token; + if (t.line !== nexttoken.line) { + warning("Line breaking error '{a}'.", t, t.value); + } + } + + + function comma() { + if (token.line !== nexttoken.line) { + if (!option.laxbreak) { + warning("Bad line breaking before '{a}'.", token, nexttoken.id); + } + } else if (token.character !== nexttoken.from && option.white) { + warning("Unexpected space after '{a}'.", nexttoken, token.value); + } + advance(','); + nonadjacent(token, nexttoken); + } + + +// Functional constructors for making the symbols that will be inherited by +// tokens. + + function symbol(s, p) { + var x = syntax[s]; + if (!x || typeof x !== 'object') { + syntax[s] = x = { + id: s, + lbp: p, + value: s + }; + } + return x; + } + + + function delim(s) { + return symbol(s, 0); + } + + + function stmt(s, f) { + var x = delim(s); + x.identifier = x.reserved = true; + x.fud = f; + return x; + } + + + function blockstmt(s, f) { + var x = stmt(s, f); + x.block = true; + return x; + } + + + function reserveName(x) { + var c = x.id.charAt(0); + if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) { + x.identifier = x.reserved = true; + } + return x; + } + + + function prefix(s, f) { + var x = symbol(s, 150); + reserveName(x); + x.nud = (typeof f === 'function') ? f : function () { + this.right = parse(150); + this.arity = 'unary'; + if (this.id === '++' || this.id === '--') { + if (option.plusplus) { + warning("Unexpected use of '{a}'.", this, this.id); + } else if ((!this.right.identifier || this.right.reserved) && + this.right.id !== '.' && this.right.id !== '[') { + warning("Bad operand.", this); + } + } + return this; + }; + return x; + } + + + function type(s, f) { + var x = delim(s); + x.type = s; + x.nud = f; + return x; + } + + + function reserve(s, f) { + var x = type(s, f); + x.identifier = x.reserved = true; + return x; + } + + + function reservevar(s, v) { + return reserve(s, function () { + if (this.id === 'this' || this.id === 'arguments') { + if (strict_mode && funct['(global)']) { + warning("Strict violation.", this); + } else if (option.safe) { + warning("ADsafe violation.", this); + } + } + return this; + }); + } + + + function infix(s, f, p, w) { + var x = symbol(s, p); + reserveName(x); + x.led = function (left) { + if (!w) { + nobreaknonadjacent(prevtoken, token); + nonadjacent(token, nexttoken); + } + if (typeof f === 'function') { + return f(left, this); + } else { + this.left = left; + this.right = parse(p); + return this; + } + }; + return x; + } + + + function relation(s, f) { + var x = symbol(s, 100); + x.led = function (left) { + nobreaknonadjacent(prevtoken, token); + nonadjacent(token, nexttoken); + var right = parse(100); + if ((left && left.id === 'NaN') || (right && right.id === 'NaN')) { + warning("Use the isNaN function to compare with NaN.", this); + } else if (f) { + f.apply(this, [left, right]); + } + if (left.id === '!') { + warning("Confusing use of '{a}'.", left, '!'); + } + if (right.id === '!') { + warning("Confusing use of '{a}'.", left, '!'); + } + this.left = left; + this.right = right; + return this; + }; + return x; + } + + + function isPoorRelation(node) { + return node && + ((node.type === '(number)' && +node.value === 0) || + (node.type === '(string)' && node.value === ' ') || + node.type === 'true' || + node.type === 'false' || + node.type === 'undefined' || + node.type === 'null'); + } + + + function assignop(s, f) { + symbol(s, 20).exps = true; + return infix(s, function (left, that) { + var l; + that.left = left; + if (predefined[left.value] === false && + scope[left.value]['(global)'] === true) { + warning('Read only.', left); + } + if (option.safe) { + l = left; + do { + if (typeof predefined[l.value] === 'boolean') { + warning('ADsafe violation.', l); + } + l = l.left; + } while (l); + } + if (left) { + if (left.id === '.' || left.id === '[') { + if (!left.left || left.left.value === 'arguments') { + warning('Bad assignment.', that); + } + that.right = parse(19); + return that; + } else if (left.identifier && !left.reserved) { + if (funct[left.value] === 'exception') { + warning("Do not assign to the exception parameter.", left); + } + that.right = parse(19); + return that; + } + if (left === syntax['function']) { + warning( +"Expected an identifier in an assignment and instead saw a function invocation.", + token); + } + } + error("Bad assignment.", that); + }, 20); + } + + function bitwise(s, f, p) { + var x = symbol(s, p); + reserveName(x); + x.led = (typeof f === 'function') ? f : function (left) { + if (option.bitwise) { + warning("Unexpected use of '{a}'.", this, this.id); + } + this.left = left; + this.right = parse(p); + return this; + }; + return x; + } + + function bitwiseassignop(s) { + symbol(s, 20).exps = true; + return infix(s, function (left, that) { + if (option.bitwise) { + warning("Unexpected use of '{a}'.", that, that.id); + } + nonadjacent(prevtoken, token); + nonadjacent(token, nexttoken); + if (left) { + if (left.id === '.' || left.id === '[' || + (left.identifier && !left.reserved)) { + parse(19); + return that; + } + if (left === syntax['function']) { + warning( +"Expected an identifier in an assignment, and instead saw a function invocation.", + token); + } + return that; + } + error("Bad assignment.", that); + }, 20); + } + + + function suffix(s, f) { + var x = symbol(s, 150); + x.led = function (left) { + if (option.plusplus) { + warning("Unexpected use of '{a}'.", this, this.id); + } else if ((!left.identifier || left.reserved) && left.id !== '.' && left.id !== '[') { + warning("Bad operand.", this); + } + this.left = left; + return this; + }; + return x; + } + + + function optionalidentifier() { + if (nexttoken.reserved) { + warning("Expected an identifier and instead saw '{a}' (a reserved word).", + nexttoken, nexttoken.id); + } + if (nexttoken.identifier) { + advance(); + return token.value; + } + } + + + function identifier() { + var i = optionalidentifier(); + if (i) { + return i; + } + if (token.id === 'function' && nexttoken.id === '(') { + warning("Missing name in function statement."); + } else { + error("Expected an identifier and instead saw '{a}'.", + nexttoken, nexttoken.value); + } + } + + function reachable(s) { + var i = 0, t; + if (nexttoken.id !== ';' || noreach) { + return; + } + for (;;) { + t = peek(i); + if (t.reach) { + return; + } + if (t.id !== '(endline)') { + if (t.id === 'function') { + warning( +"Inner functions should be listed at the top of the outer function.", t); + break; + } + warning("Unreachable '{a}' after '{b}'.", t, t.value, s); + break; + } + i += 1; + } + } + + + function statement(noindent) { + var i = indent, r, s = scope, t = nexttoken; + +// We don't like the empty statement. + + if (t.id === ';') { + warning("Unnecessary semicolon.", t); + advance(';'); + return; + } + +// Is this a labelled statement? + + if (t.identifier && !t.reserved && peek().id === ':') { + advance(); + advance(':'); + scope = Object.create(s); + addlabel(t.value, 'label'); + if (!nexttoken.labelled) { + warning("Label '{a}' on {b} statement.", + nexttoken, t.value, nexttoken.value); + } + if (jx.test(t.value + ':')) { + warning("Label '{a}' looks like a javascript url.", + t, t.value); + } + nexttoken.label = t.value; + t = nexttoken; + } + +// Parse the statement. + + if (!noindent) { + indentation(); + } + r = parse(0, true); + +// Look for the final semicolon. + + if (!t.block) { + if (!r || !r.exps) { + warning( +"Expected an assignment or function call and instead saw an expression.", + token); + } else if (r.id === '(' && r.left.id === 'new') { + warning("Do not use 'new' for side effects."); + } + if (nexttoken.id !== ';') { + warningAt("Missing semicolon.", token.line, + token.from + token.value.length); + } else { + adjacent(token, nexttoken); + advance(';'); + nonadjacent(token, nexttoken); + } + } + +// Restore the indentation. + + indent = i; + scope = s; + return r; + } + + + function use_strict() { + if (nexttoken.value === 'use strict') { + advance(); + advance(';'); + strict_mode = true; + return true; + } else { + return false; + } + } + + + function statements(begin) { + var a = [], f, p; + if (begin && !use_strict() && option.strict) { + warning('Missing "use strict" statement.', nexttoken); + } + if (option.adsafe) { + switch (begin) { + case 'script': + if (!adsafe_may) { + if (nexttoken.value !== 'ADSAFE' || + peek(0).id !== '.' || + (peek(1).value !== 'id' && + peek(1).value !== 'go')) { + error('ADsafe violation: Missing ADSAFE.id or ADSAFE.go.', + nexttoken); + } + } + if (nexttoken.value === 'ADSAFE' && + peek(0).id === '.' && + peek(1).value === 'id') { + if (adsafe_may) { + error('ADsafe violation.', nexttoken); + } + advance('ADSAFE'); + advance('.'); + advance('id'); + advance('('); + if (nexttoken.value !== adsafe_id) { + error('ADsafe violation: id does not match.', nexttoken); + } + advance('(string)'); + advance(')'); + advance(';'); + adsafe_may = true; + } + break; + case 'lib': + if (nexttoken.value === 'ADSAFE') { + advance('ADSAFE'); + advance('.'); + advance('lib'); + advance('('); + advance('(string)'); + comma(); + f = parse(0); + if (f.id !== 'function') { + error('The second argument to lib must be a function.', f); + } + p = f.funct['(params)']; + p = p && p.join(', '); + if (p && p !== 'lib') { + error("Expected '{a}' and instead saw '{b}'.", + f, '(lib)', '(' + p + ')'); + } + advance(')'); + advance(';'); + return a; + } else { + error("ADsafe lib violation."); + } + } + } + while (!nexttoken.reach && nexttoken.id !== '(end)') { + if (nexttoken.id === ';') { + warning("Unnecessary semicolon."); + advance(';'); + } else { + a.push(statement()); + } + } + return a; + } + + + function block(f) { + var a, b = inblock, old_indent = indent, s = scope, t; + inblock = f; + scope = Object.create(scope); + nonadjacent(token, nexttoken); + t = nexttoken; + if (nexttoken.id === '{') { + advance('{'); + if (nexttoken.id !== '}' || token.line !== nexttoken.line) { + indent += option.indent; + while (!f && nexttoken.from > indent) { + indent += option.indent; + } + if (!f) { + use_strict(); + } + a = statements(); + indent -= option.indent; + indentation(); + } + advance('}', t); + indent = old_indent; + } else { + warning("Expected '{a}' and instead saw '{b}'.", + nexttoken, '{', nexttoken.value); + noreach = true; + a = [statement()]; + noreach = false; + } + funct['(verb)'] = null; + scope = s; + inblock = b; + return a; + } + + +// An identity function, used by string and number tokens. + + function idValue() { + return this; + } + + + function countMember(m) { + if (membersOnly && typeof membersOnly[m] !== 'boolean') { + warning("Unexpected /*member '{a}'.", token, m); + } + if (typeof member[m] === 'number') { + member[m] += 1; + } else { + member[m] = 1; + } + } + + + function note_implied(token) { + var name = token.value, line = token.line, a = implied[name]; + if (typeof a === 'function') { + a = false; + } + if (!a) { + a = [line]; + implied[name] = a; + } else if (a[a.length - 1] !== line) { + a.push(line); + } + } + +// CSS parsing. + + + function cssName() { + if (nexttoken.identifier) { + advance(); + return true; + } + } + + function cssNumber() { + if (nexttoken.id === '-') { + advance('-'); + adjacent(); + nolinebreak(); + } + if (nexttoken.type === '(number)') { + advance('(number)'); + return true; + } + } + + function cssString() { + if (nexttoken.type === '(string)') { + advance(); + return true; + } + } + + function cssColor() { + var i, number, value; + if (nexttoken.identifier) { + value = nexttoken.value; + if (value === 'rgb' || value === 'rgba') { + advance(); + advance('('); + for (i = 0; i < 3; i += 1) { + if (i) { + advance(','); + } + number = nexttoken.value; + if (nexttoken.type !== '(number)' || number < 0) { + warning("Expected a positive number and instead saw '{a}'", + nexttoken, number); + advance(); + } else { + advance(); + if (nexttoken.id === '%') { + advance('%'); + if (number > 100) { + warning("Expected a percentage and instead saw '{a}'", + token, number); + } + } else { + if (number > 255) { + warning("Expected a small number and instead saw '{a}'", + token, number); + } + } + } + } + if (value === 'rgba') { + advance(','); + number = +nexttoken.value; + if (nexttoken.type !== '(number)' || number < 0 || number > 1) { + warning("Expected a number between 0 and 1 and instead saw '{a}'", + nexttoken, number); + } + advance(); + if (nexttoken.id === '%') { + warning("Unexpected '%'."); + advance('%'); + } + } + advance(')'); + return true; + } else if (cssColorData[nexttoken.value] === true) { + advance(); + return true; + } + } else if (nexttoken.type === '(color)') { + advance(); + return true; + } + return false; + } + + function cssLength() { + if (nexttoken.id === '-') { + advance('-'); + adjacent(); + nolinebreak(); + } + if (nexttoken.type === '(number)') { + advance(); + if (nexttoken.type !== '(string)' && + cssLengthData[nexttoken.value] === true) { + adjacent(); + advance(); + } else if (+token.value !== 0) { + warning("Expected a linear unit and instead saw '{a}'.", + nexttoken, nexttoken.value); + } + return true; + } + return false; + } + + function cssLineHeight() { + if (nexttoken.id === '-') { + advance('-'); + adjacent(); + } + if (nexttoken.type === '(number)') { + advance(); + if (nexttoken.type !== '(string)' && + cssLengthData[nexttoken.value] === true) { + adjacent(); + advance(); + } + return true; + } + return false; + } + + function cssWidth() { + if (nexttoken.identifier) { + switch (nexttoken.value) { + case 'thin': + case 'medium': + case 'thick': + advance(); + return true; + } + } else { + return cssLength(); + } + } + + function cssMargin() { + if (nexttoken.identifier) { + if (nexttoken.value === 'auto') { + advance(); + return true; + } + } else { + return cssLength(); + } + } + + function cssAttr() { + if (nexttoken.identifier && nexttoken.value === 'attr') { + advance(); + advance('('); + if (!nexttoken.identifier) { + warning("Expected a name and instead saw '{a}'.", + nexttoken, nexttoken.value); + } + advance(); + advance(')'); + return true; + } + return false; + } + + function cssCommaList() { + while (nexttoken.id !== ';') { + if (!cssName() && !cssString()) { + warning("Expected a name and instead saw '{a}'.", + nexttoken, nexttoken.value); + } + if (nexttoken.id !== ',') { + return true; + } + comma(); + } + } + + function cssCounter() { + if (nexttoken.identifier && nexttoken.value === 'counter') { + advance(); + advance('('); + if (!nexttoken.identifier) { + } + advance(); + if (nexttoken.id === ',') { + comma(); + if (nexttoken.type !== '(string)') { + warning("Expected a string and instead saw '{a}'.", + nexttoken, nexttoken.value); + } + advance(); + } + advance(')'); + return true; + } + if (nexttoken.identifier && nexttoken.value === 'counters') { + advance(); + advance('('); + if (!nexttoken.identifier) { + warning("Expected a name and instead saw '{a}'.", + nexttoken, nexttoken.value); + } + advance(); + if (nexttoken.id === ',') { + comma(); + if (nexttoken.type !== '(string)') { + warning("Expected a string and instead saw '{a}'.", + nexttoken, nexttoken.value); + } + advance(); + } + if (nexttoken.id === ',') { + comma(); + if (nexttoken.type !== '(string)') { + warning("Expected a string and instead saw '{a}'.", + nexttoken, nexttoken.value); + } + advance(); + } + advance(')'); + return true; + } + return false; + } + + + function cssShape() { + var i; + if (nexttoken.identifier && nexttoken.value === 'rect') { + advance(); + advance('('); + for (i = 0; i < 4; i += 1) { + if (!cssLength()) { + warning("Expected a number and instead saw '{a}'.", + nexttoken, nexttoken.value); + break; + } + } + advance(')'); + return true; + } + return false; + } + + function cssUrl() { + var c, url; + if (nexttoken.identifier && nexttoken.value === 'url') { + nexttoken = lex.range('(', ')'); + url = nexttoken.value; + c = url.charAt(0); + if (c === '"' || c === '\'') { + if (url.slice(-1) !== c) { + warning("Bad url string."); + } else { + url = url.slice(1, -1); + if (url.indexOf(c) >= 0) { + warning("Bad url string."); + } + } + } + if (!url) { + warning("Missing url."); + } + advance(); + if (option.safe && ux.test(url)) { + error("ADsafe URL violation."); + } + urls.push(url); + return true; + } + return false; + } + + cssAny = [cssUrl, function () { + for (;;) { + if (nexttoken.identifier) { + switch (nexttoken.value.toLowerCase()) { + case 'url': + cssUrl(); + break; + case 'expression': + warning("Unexpected expression '{a}'.", + nexttoken, nexttoken.value); + advance(); + break; + default: + advance(); + } + } else { + if (nexttoken.id === ';' || nexttoken.id === '!' || + nexttoken.id === '(end)' || nexttoken.id === '}') { + return true; + } + advance(); + } + } + }]; + + cssBorderStyle = [ + 'none', 'hidden', 'dotted', 'dashed', 'solid', 'double', 'ridge', + 'inset', 'outset' + ]; + + cssBreak = [ + 'auto', 'always', 'avoid', 'left', 'right' + ]; + + cssOverflow = [ + 'auto', 'hidden', 'scroll', 'visible' + ]; + + cssAttributeData = { + background: [ + true, 'background-attachment', 'background-color', + 'background-image', 'background-position', 'background-repeat' + ], + 'background-attachment': ['scroll', 'fixed'], + 'background-color': ['transparent', cssColor], + 'background-image': ['none', cssUrl], + 'background-position': [ + 2, [cssLength, 'top', 'bottom', 'left', 'right', 'center'] + ], + 'background-repeat': [ + 'repeat', 'repeat-x', 'repeat-y', 'no-repeat' + ], + 'border': [true, 'border-color', 'border-style', 'border-width'], + 'border-bottom': [ + true, 'border-bottom-color', 'border-bottom-style', + 'border-bottom-width' + ], + 'border-bottom-color': cssColor, + 'border-bottom-style': cssBorderStyle, + 'border-bottom-width': cssWidth, + 'border-collapse': ['collapse', 'separate'], + 'border-color': ['transparent', 4, cssColor], + 'border-left': [ + true, 'border-left-color', 'border-left-style', 'border-left-width' + ], + 'border-left-color': cssColor, + 'border-left-style': cssBorderStyle, + 'border-left-width': cssWidth, + 'border-right': [ + true, 'border-right-color', 'border-right-style', + 'border-right-width' + ], + 'border-right-color': cssColor, + 'border-right-style': cssBorderStyle, + 'border-right-width': cssWidth, + 'border-spacing': [2, cssLength], + 'border-style': [4, cssBorderStyle], + 'border-top': [ + true, 'border-top-color', 'border-top-style', 'border-top-width' + ], + 'border-top-color': cssColor, + 'border-top-style': cssBorderStyle, + 'border-top-width': cssWidth, + 'border-width': [4, cssWidth], + bottom: [cssLength, 'auto'], + 'caption-side' : ['bottom', 'left', 'right', 'top'], + clear: ['both', 'left', 'none', 'right'], + clip: [cssShape, 'auto'], + color: cssColor, + content: [ + 'open-quote', 'close-quote', 'no-open-quote', 'no-close-quote', + cssString, cssUrl, cssCounter, cssAttr + ], + 'counter-increment': [ + cssName, 'none' + ], + 'counter-reset': [ + cssName, 'none' + ], + cursor: [ + cssUrl, 'auto', 'crosshair', 'default', 'e-resize', 'help', 'move', + 'n-resize', 'ne-resize', 'nw-resize', 'pointer', 's-resize', + 'se-resize', 'sw-resize', 'w-resize', 'text', 'wait' + ], + direction: ['ltr', 'rtl'], + display: [ + 'block', 'compact', 'inline', 'inline-block', 'inline-table', + 'list-item', 'marker', 'none', 'run-in', 'table', 'table-caption', + 'table-cell', 'table-column', 'table-column-group', + 'table-footer-group', 'table-header-group', 'table-row', + 'table-row-group' + ], + 'empty-cells': ['show', 'hide'], + 'float': ['left', 'none', 'right'], + font: [ + 'caption', 'icon', 'menu', 'message-box', 'small-caption', + 'status-bar', true, 'font-size', 'font-style', 'font-weight', + 'font-family' + ], + 'font-family': cssCommaList, + 'font-size': [ + 'xx-small', 'x-small', 'small', 'medium', 'large', 'x-large', + 'xx-large', 'larger', 'smaller', cssLength + ], + 'font-size-adjust': ['none', cssNumber], + 'font-stretch': [ + 'normal', 'wider', 'narrower', 'ultra-condensed', + 'extra-condensed', 'condensed', 'semi-condensed', + 'semi-expanded', 'expanded', 'extra-expanded' + ], + 'font-style': [ + 'normal', 'italic', 'oblique' + ], + 'font-variant': [ + 'normal', 'small-caps' + ], + 'font-weight': [ + 'normal', 'bold', 'bolder', 'lighter', cssNumber + ], + height: [cssLength, 'auto'], + left: [cssLength, 'auto'], + 'letter-spacing': ['normal', cssLength], + 'line-height': ['normal', cssLineHeight], + 'list-style': [ + true, 'list-style-image', 'list-style-position', 'list-style-type' + ], + 'list-style-image': ['none', cssUrl], + 'list-style-position': ['inside', 'outside'], + 'list-style-type': [ + 'circle', 'disc', 'square', 'decimal', 'decimal-leading-zero', + 'lower-roman', 'upper-roman', 'lower-greek', 'lower-alpha', + 'lower-latin', 'upper-alpha', 'upper-latin', 'hebrew', 'katakana', + 'hiragana-iroha', 'katakana-oroha', 'none' + ], + margin: [4, cssMargin], + 'margin-bottom': cssMargin, + 'margin-left': cssMargin, + 'margin-right': cssMargin, + 'margin-top': cssMargin, + 'marker-offset': [cssLength, 'auto'], + 'max-height': [cssLength, 'none'], + 'max-width': [cssLength, 'none'], + 'min-height': cssLength, + 'min-width': cssLength, + opacity: cssNumber, + outline: [true, 'outline-color', 'outline-style', 'outline-width'], + 'outline-color': ['invert', cssColor], + 'outline-style': [ + 'dashed', 'dotted', 'double', 'groove', 'inset', 'none', + 'outset', 'ridge', 'solid' + ], + 'outline-width': cssWidth, + overflow: cssOverflow, + 'overflow-x': cssOverflow, + 'overflow-y': cssOverflow, + padding: [4, cssLength], + 'padding-bottom': cssLength, + 'padding-left': cssLength, + 'padding-right': cssLength, + 'padding-top': cssLength, + 'page-break-after': cssBreak, + 'page-break-before': cssBreak, + position: ['absolute', 'fixed', 'relative', 'static'], + quotes: [8, cssString], + right: [cssLength, 'auto'], + 'table-layout': ['auto', 'fixed'], + 'text-align': ['center', 'justify', 'left', 'right'], + 'text-decoration': [ + 'none', 'underline', 'overline', 'line-through', 'blink' + ], + 'text-indent': cssLength, + 'text-shadow': ['none', 4, [cssColor, cssLength]], + 'text-transform': ['capitalize', 'uppercase', 'lowercase', 'none'], + top: [cssLength, 'auto'], + 'unicode-bidi': ['normal', 'embed', 'bidi-override'], + 'vertical-align': [ + 'baseline', 'bottom', 'sub', 'super', 'top', 'text-top', 'middle', + 'text-bottom', cssLength + ], + visibility: ['visible', 'hidden', 'collapse'], + 'white-space': [ + 'normal', 'nowrap', 'pre', 'pre-line', 'pre-wrap', 'inherit' + ], + width: [cssLength, 'auto'], + 'word-spacing': ['normal', cssLength], + 'word-wrap': ['break-word', 'normal'], + 'z-index': ['auto', cssNumber] + }; + + function styleAttribute() { + var v; + while (nexttoken.id === '*' || nexttoken.id === '#' || + nexttoken.value === '_') { + if (!option.css) { + warning("Unexpected '{a}'.", nexttoken, nexttoken.value); + } + advance(); + } + if (nexttoken.id === '-') { + if (!option.css) { + warning("Unexpected '{a}'.", nexttoken, nexttoken.value); + } + advance('-'); + if (!nexttoken.identifier) { + warning( +"Expected a non-standard style attribute and instead saw '{a}'.", + nexttoken, nexttoken.value); + } + advance(); + return cssAny; + } else { + if (!nexttoken.identifier) { + warning("Excepted a style attribute, and instead saw '{a}'.", + nexttoken, nexttoken.value); + } else { + if (is_own(cssAttributeData, nexttoken.value)) { + v = cssAttributeData[nexttoken.value]; + } else { + v = cssAny; + if (!option.css) { + warning("Unrecognized style attribute '{a}'.", + nexttoken, nexttoken.value); + } + } + } + advance(); + return v; + } + } + + function styleValue(v) { + var i = 0, + n, + once, + match, + round, + start = 0, + vi; + switch (typeof v) { + case 'function': + return v(); + case 'string': + if (nexttoken.identifier && nexttoken.value === v) { + advance(); + return true; + } + return false; + } + for (;;) { + if (i >= v.length) { + return false; + } + vi = v[i]; + i += 1; + if (vi === true) { + break; + } else if (typeof vi === 'number') { + n = vi; + vi = v[i]; + i += 1; + } else { + n = 1; + } + match = false; + while (n > 0) { + if (styleValue(vi)) { + match = true; + n -= 1; + } else { + break; + } + } + if (match) { + return true; + } + } + start = i; + once = []; + for (;;) { + round = false; + for (i = start; i < v.length; i += 1) { + if (!once[i]) { + if (styleValue(cssAttributeData[v[i]])) { + match = true; + round = true; + once[i] = true; + break; + } + } + } + if (!round) { + return match; + } + } + } + + function styleChild() { + if (nexttoken.id === '(number)') { + advance(); + if (nexttoken.value === 'n' && nexttoken.identifier) { + adjacent(); + advance(); + if (nexttoken.id === '+') { + adjacent(); + advance('+'); + adjacent(); + advance('(number)'); + } + } + return; + } else { + switch (nexttoken.value) { + case 'odd': + case 'even': + if (nexttoken.identifier) { + advance(); + return; + } + } + } + warning("Unexpected token '{a}'.", nexttoken, nexttoken.value); + } + + function substyle() { + var v; + for (;;) { + if (nexttoken.id === '}' || nexttoken.id === '(end)' || + xquote && nexttoken.id === xquote) { + return; + } + while (nexttoken.id === ';') { + warning("Misplaced ';'."); + advance(';'); + } + v = styleAttribute(); + advance(':'); + if (nexttoken.identifier && nexttoken.value === 'inherit') { + advance(); + } else { + if (!styleValue(v)) { + warning("Unexpected token '{a}'.", nexttoken, + nexttoken.value); + advance(); + } + } + if (nexttoken.id === '!') { + advance('!'); + adjacent(); + if (nexttoken.identifier && nexttoken.value === 'important') { + advance(); + } else { + warning("Expected '{a}' and instead saw '{b}'.", + nexttoken, 'important', nexttoken.value); + } + } + if (nexttoken.id === '}' || nexttoken.id === xquote) { + warning("Missing '{a}'.", nexttoken, ';'); + } else { + advance(';'); + } + } + } + + function styleSelector() { + if (nexttoken.identifier) { + if (!is_own(htmltag, nexttoken.value)) { + warning("Expected a tagName, and instead saw {a}.", + nexttoken, nexttoken.value); + } + advance(); + } else { + switch (nexttoken.id) { + case '>': + case '+': + advance(); + styleSelector(); + break; + case ':': + advance(':'); + switch (nexttoken.value) { + case 'active': + case 'after': + case 'before': + case 'checked': + case 'disabled': + case 'empty': + case 'enabled': + case 'first-child': + case 'first-letter': + case 'first-line': + case 'first-of-type': + case 'focus': + case 'hover': + case 'last-of-type': + case 'link': + case 'only-of-type': + case 'root': + case 'target': + case 'visited': + advance(); + break; + case 'lang': + advance(); + advance('('); + if (!nexttoken.identifier) { + warning("Expected a lang code, and instead saw :{a}.", + nexttoken, nexttoken.value); + } + advance(')'); + break; + case 'nth-child': + case 'nth-last-child': + case 'nth-last-of-type': + case 'nth-of-type': + advance(); + advance('('); + styleChild(); + advance(')'); + break; + case 'not': + advance(); + advance('('); + if (nexttoken.id === ':' && peek(0).value === 'not') { + warning("Nested not."); + } + styleSelector(); + advance(')'); + break; + default: + warning("Expected a pseudo, and instead saw :{a}.", + nexttoken, nexttoken.value); + } + break; + case '#': + advance('#'); + if (!nexttoken.identifier) { + warning("Expected an id, and instead saw #{a}.", + nexttoken, nexttoken.value); + } + advance(); + break; + case '*': + advance('*'); + break; + case '.': + advance('.'); + if (!nexttoken.identifier) { + warning("Expected a class, and instead saw #.{a}.", + nexttoken, nexttoken.value); + } + advance(); + break; + case '[': + advance('['); + if (!nexttoken.identifier) { + warning("Expected an attribute, and instead saw [{a}].", + nexttoken, nexttoken.value); + } + advance(); + if (nexttoken.id === '=' || nexttoken.value === '~=' || + nexttoken.value === '$=' || + nexttoken.value === '|=' || + nexttoken.id === '*=' || + nexttoken.id === '^=') { + advance(); + if (nexttoken.type !== '(string)') { + warning("Expected a string, and instead saw {a}.", + nexttoken, nexttoken.value); + } + advance(); + } + advance(']'); + break; + default: + error("Expected a CSS selector, and instead saw {a}.", + nexttoken, nexttoken.value); + } + } + } + + function stylePattern() { + var name; + if (nexttoken.id === '{') { + warning("Expected a style pattern, and instead saw '{a}'.", nexttoken, + nexttoken.id); + } else if (nexttoken.id === '@') { + advance('@'); + name = nexttoken.value; + if (nexttoken.identifier && atrule[name] === true) { + advance(); + return name; + } + warning("Expected an at-rule, and instead saw @{a}.", nexttoken, name); + } + for (;;) { + styleSelector(); + if (nexttoken.id === ' fragments and .js files.", token); + } + if (option.fragment) { + if (n !== 'div') { + error("ADsafe violation: Wrap the widget in a div.", token); + } + } else { + error("Use the fragment option.", token); + } + } + option.browser = true; + assume(); + } + + function doAttribute(n, a, v) { + var u, x; + if (a === 'id') { + u = typeof v === 'string' ? v.toUpperCase() : ''; + if (ids[u] === true) { + warning("Duplicate id='{a}'.", nexttoken, v); + } + if (!/^[A-Za-z][A-Za-z0-9._:\-]*$/.test(v)) { + warning("Bad id: '{a}'.", nexttoken, v); + } else if (option.adsafe) { + if (adsafe_id) { + if (v.slice(0, adsafe_id.length) !== adsafe_id) { + warning("ADsafe violation: An id must have a '{a}' prefix", + nexttoken, adsafe_id); + } else if (!/^[A-Z]+_[A-Z]+$/.test(v)) { + warning("ADSAFE violation: bad id."); + } + } else { + adsafe_id = v; + if (!/^[A-Z]+_$/.test(v)) { + warning("ADSAFE violation: bad id."); + } + } + } + x = v.search(dx); + if (x >= 0) { + warning("Unexpected character '{a}' in {b}.", token, v.charAt(x), a); + } + ids[u] = true; + } else if (a === 'class' || a === 'type' || a === 'name') { + x = v.search(qx); + if (x >= 0) { + warning("Unexpected character '{a}' in {b}.", token, v.charAt(x), a); + } + ids[u] = true; + } else if (a === 'href' || a === 'background' || + a === 'content' || a === 'data' || + a.indexOf('src') >= 0 || a.indexOf('url') >= 0) { + if (option.safe && ux.test(v)) { + error("ADsafe URL violation."); + } + urls.push(v); + } else if (a === 'for') { + if (option.adsafe) { + if (adsafe_id) { + if (v.slice(0, adsafe_id.length) !== adsafe_id) { + warning("ADsafe violation: An id must have a '{a}' prefix", + nexttoken, adsafe_id); + } else if (!/^[A-Z]+_[A-Z]+$/.test(v)) { + warning("ADSAFE violation: bad id."); + } + } else { + warning("ADSAFE violation: bad id."); + } + } + } else if (a === 'name') { + if (option.adsafe && v.indexOf('_') >= 0) { + warning("ADsafe name violation."); + } + } + } + + function doTag(n, a) { + var i, t = htmltag[n], x; + src = false; + if (!t) { + error("Unrecognized tag '<{a}>'.", + nexttoken, + n === n.toLowerCase() ? n : + n + ' (capitalization error)'); + } + if (stack.length > 0) { + if (n === 'html') { + error("Too many tags.", token); + } + x = t.parent; + if (x) { + if (x.indexOf(' ' + stack[stack.length - 1].name + ' ') < 0) { + error("A '<{a}>' must be within '<{b}>'.", + token, n, x); + } + } else if (!option.adsafe && !option.fragment) { + i = stack.length; + do { + if (i <= 0) { + error("A '<{a}>' must be within '<{b}>'.", + token, n, 'body'); + } + i -= 1; + } while (stack[i].name !== 'body'); + } + } + switch (n) { + case 'div': + if (option.adsafe && stack.length === 1 && !adsafe_id) { + warning("ADSAFE violation: missing ID_."); + } + break; + case 'script': + xmode = 'script'; + advance('>'); + indent = nexttoken.from; + if (a.lang) { + warning("lang is deprecated.", token); + } + if (option.adsafe && stack.length !== 1) { + warning("ADsafe script placement violation.", token); + } + if (a.src) { + if (option.adsafe && (!adsafe_may || !approved[a.src])) { + warning("ADsafe unapproved script source.", token); + } + if (a.type) { + warning("type is unnecessary.", token); + } + } else { + if (adsafe_went) { + error("ADsafe script violation.", token); + } + statements('script'); + } + xmode = 'html'; + advance(''); + styles(); + xmode = 'html'; + advance(''; + } + + function html() { + var a, attributes, e, n, q, t, v, w = option.white, wmode; + xmode = 'html'; + xquote = ''; + stack = null; + for (;;) { + switch (nexttoken.value) { + case '<': + xmode = 'html'; + advance('<'); + attributes = {}; + t = nexttoken; + if (!t.identifier) { + warning("Bad identifier {a}.", t, t.value); + } + n = t.value; + if (option.cap) { + n = n.toLowerCase(); + } + t.name = n; + advance(); + if (!stack) { + stack = []; + doBegin(n); + } + v = htmltag[n]; + if (typeof v !== 'object') { + error("Unrecognized tag '<{a}>'.", t, n); + } + e = v.empty; + t.type = n; + for (;;) { + if (nexttoken.id === '/') { + advance('/'); + if (nexttoken.id !== '>') { + warning("Expected '{a}' and instead saw '{b}'.", + nexttoken, '>', nexttoken.value); + } + break; + } + if (nexttoken.id && nexttoken.id.substr(0, 1) === '>') { + break; + } + if (!nexttoken.identifier) { + if (nexttoken.id === '(end)' || nexttoken.id === '(error)') { + error("Missing '>'.", nexttoken); + } + warning("Bad identifier."); + } + option.white = true; + nonadjacent(token, nexttoken); + a = nexttoken.value; + option.white = w; + advance(); + if (!option.cap && a !== a.toLowerCase()) { + warning("Attribute '{a}' not all lower case.", nexttoken, a); + } + a = a.toLowerCase(); + xquote = ''; + if (is_own(attributes, a)) { + warning("Attribute '{a}' repeated.", nexttoken, a); + } + if (a.slice(0, 2) === 'on') { + if (!option.on) { + warning("Avoid HTML event handlers."); + } + xmode = 'scriptstring'; + advance('='); + q = nexttoken.id; + if (q !== '"' && q !== "'") { + error("Missing quote."); + } + xquote = q; + wmode = option.white; + option.white = false; + advance(q); + statements('on'); + option.white = wmode; + if (nexttoken.id !== q) { + error("Missing close quote on script attribute."); + } + xmode = 'html'; + xquote = ''; + advance(q); + v = false; + } else if (a === 'style') { + xmode = 'scriptstring'; + advance('='); + q = nexttoken.id; + if (q !== '"' && q !== "'") { + error("Missing quote."); + } + xmode = 'styleproperty'; + xquote = q; + advance(q); + substyle(); + xmode = 'html'; + xquote = ''; + advance(q); + v = false; + } else { + if (nexttoken.id === '=') { + advance('='); + v = nexttoken.value; + if (!nexttoken.identifier && + nexttoken.id !== '"' && + nexttoken.id !== '\'' && + nexttoken.type !== '(string)' && + nexttoken.type !== '(number)' && + nexttoken.type !== '(color)') { + warning("Expected an attribute value and instead saw '{a}'.", token, a); + } + advance(); + } else { + v = true; + } + } + attributes[a] = v; + doAttribute(n, a, v); + } + doTag(n, attributes); + if (!e) { + stack.push(t); + } + xmode = 'outer'; + advance('>'); + break; + case '') { + error("Missing '{a}'.", nexttoken, '>'); + } + xmode = 'outer'; + advance('>'); + break; + case '' || nexttoken.id === '(end)') { + break; + } + if (nexttoken.value.indexOf('--') >= 0) { + warning("Unexpected --."); + } + if (nexttoken.value.indexOf('<') >= 0) { + warning("Unexpected <."); + } + if (nexttoken.value.indexOf('>') >= 0) { + warning("Unexpected >."); + } + } + xmode = 'outer'; + advance('>'); + break; + case '(end)': + return; + default: + if (nexttoken.id === '(end)') { + error("Missing '{a}'.", nexttoken, + ''); + } else { + advance(); + } + } + if (stack && stack.length === 0 && (option.adsafe || + !option.fragment || nexttoken.id === '(end)')) { + break; + } + } + if (nexttoken.id !== '(end)') { + error("Unexpected material after the end."); + } + } + + +// Build the syntax table by declaring the syntactic elements of the language. + + type('(number)', idValue); + type('(string)', idValue); + + syntax['(identifier)'] = { + type: '(identifier)', + lbp: 0, + identifier: true, + nud: function () { + var v = this.value, + s = scope[v], + f; + if (typeof s === 'function') { + s = undefined; + } else if (typeof s === 'boolean') { + f = funct; + funct = functions[0]; + addlabel(v, 'var'); + s = funct; + funct = f; + } + +// The name is in scope and defined in the current function. + + if (funct === s) { + +// Change 'unused' to 'var', and reject labels. + + switch (funct[v]) { + case 'unused': + funct[v] = 'var'; + break; + case 'label': + warning("'{a}' is a statement label.", token, v); + break; + } + +// The name is not defined in the function. If we are in the global scope, +// then we have an undefined variable. + + } else if (funct['(global)']) { + if (option.undef && predefined[v] !== 'boolean') { + warning("'{a}' is not defined.", token, v); + } + note_implied(token); + +// If the name is already defined in the current +// function, but not as outer, then there is a scope error. + + } else { + switch (funct[v]) { + case 'closure': + case 'function': + case 'var': + case 'unused': + warning("'{a}' used out of scope.", token, v); + break; + case 'label': + warning("'{a}' is a statement label.", token, v); + break; + case 'outer': + case 'global': + break; + default: + +// If the name is defined in an outer function, make an outer entry, and if +// it was unused, make it var. + + if (s === true) { + funct[v] = true; + } else if (s === null) { + warning("'{a}' is not allowed.", token, v); + note_implied(token); + } else if (typeof s !== 'object') { + if (option.undef) { + warning("'{a}' is not defined.", token, v); + } else { + funct[v] = true; + } + note_implied(token); + } else { + switch (s[v]) { + case 'function': + case 'var': + case 'unused': + s[v] = 'closure'; + funct[v] = s['(global)'] ? 'global' : 'outer'; + break; + case 'closure': + case 'parameter': + funct[v] = s['(global)'] ? 'global' : 'outer'; + break; + case 'label': + warning("'{a}' is a statement label.", token, v); + } + } + } + } + return this; + }, + led: function () { + error("Expected an operator and instead saw '{a}'.", + nexttoken, nexttoken.value); + } + }; + + type('(regexp)', function () { + return this; + }); + + delim('(endline)'); + delim('(begin)'); + delim('(end)').reach = true; + delim(''); + delim('(error)').reach = true; + delim('}').reach = true; + delim(')'); + delim(']'); + delim('"').reach = true; + delim("'").reach = true; + delim(';'); + delim(':').reach = true; + delim(','); + delim('#'); + delim('@'); + reserve('else'); + reserve('case').reach = true; + reserve('catch'); + reserve('default').reach = true; + reserve('finally'); + reservevar('arguments'); + reservevar('eval'); + reservevar('false'); + reservevar('Infinity'); + reservevar('NaN'); + reservevar('null'); + reservevar('this'); + reservevar('true'); + reservevar('undefined'); + assignop('=', 'assign', 20); + assignop('+=', 'assignadd', 20); + assignop('-=', 'assignsub', 20); + assignop('*=', 'assignmult', 20); + assignop('/=', 'assigndiv', 20).nud = function () { + error("A regular expression literal can be confused with '/='."); + }; + assignop('%=', 'assignmod', 20); + bitwiseassignop('&=', 'assignbitand', 20); + bitwiseassignop('|=', 'assignbitor', 20); + bitwiseassignop('^=', 'assignbitxor', 20); + bitwiseassignop('<<=', 'assignshiftleft', 20); + bitwiseassignop('>>=', 'assignshiftright', 20); + bitwiseassignop('>>>=', 'assignshiftrightunsigned', 20); + infix('?', function (left, that) { + that.left = left; + that.right = parse(10); + advance(':'); + that['else'] = parse(10); + return that; + }, 30); + + infix('||', 'or', 40); + infix('&&', 'and', 50); + bitwise('|', 'bitor', 70); + bitwise('^', 'bitxor', 80); + bitwise('&', 'bitand', 90); + relation('==', function (left, right) { + if (option.eqeqeq) { + warning("Expected '{a}' and instead saw '{b}'.", + this, '===', '=='); + } else if (isPoorRelation(left)) { + warning("Use '{a}' to compare with '{b}'.", + this, '===', left.value); + } else if (isPoorRelation(right)) { + warning("Use '{a}' to compare with '{b}'.", + this, '===', right.value); + } + return this; + }); + relation('==='); + relation('!=', function (left, right) { + if (option.eqeqeq) { + warning("Expected '{a}' and instead saw '{b}'.", + this, '!==', '!='); + } else if (isPoorRelation(left)) { + warning("Use '{a}' to compare with '{b}'.", + this, '!==', left.value); + } else if (isPoorRelation(right)) { + warning("Use '{a}' to compare with '{b}'.", + this, '!==', right.value); + } + return this; + }); + relation('!=='); + relation('<'); + relation('>'); + relation('<='); + relation('>='); + bitwise('<<', 'shiftleft', 120); + bitwise('>>', 'shiftright', 120); + bitwise('>>>', 'shiftrightunsigned', 120); + infix('in', 'in', 120); + infix('instanceof', 'instanceof', 120); + infix('+', function (left, that) { + var right = parse(130); + if (left && right && left.id === '(string)' && right.id === '(string)') { + left.value += right.value; + left.character = right.character; + if (jx.test(left.value)) { + warning("JavaScript URL.", left); + } + return left; + } + that.left = left; + that.right = right; + return that; + }, 130); + prefix('+', 'num'); + infix('-', 'sub', 130); + prefix('-', 'neg'); + infix('*', 'mult', 140); + infix('/', 'div', 140); + infix('%', 'mod', 140); + + suffix('++', 'postinc'); + prefix('++', 'preinc'); + syntax['++'].exps = true; + + suffix('--', 'postdec'); + prefix('--', 'predec'); + syntax['--'].exps = true; + prefix('delete', function () { + var p = parse(0); + if (!p || (p.id !== '.' && p.id !== '[')) { + warning("Expected '{a}' and instead saw '{b}'.", + nexttoken, '.', nexttoken.value); + } + this.first = p; + return this; + }).exps = true; + + + prefix('~', function () { + if (option.bitwise) { + warning("Unexpected '{a}'.", this, '~'); + } + parse(150); + return this; + }); + prefix('!', function () { + this.right = parse(150); + this.arity = 'unary'; + if (bang[this.right.id] === true) { + warning("Confusing use of '{a}'.", this, '!'); + } + return this; + }); + prefix('typeof', 'typeof'); + prefix('new', function () { + var c = parse(155), i; + if (c && c.id !== 'function') { + if (c.identifier) { + c['new'] = true; + switch (c.value) { + case 'Object': + warning("Use the object literal notation {}.", token); + break; + case 'Array': + if (nexttoken.id !== '(') { + warning("Use the array literal notation [].", token); + } else { + advance('('); + if (nexttoken.id === ')') { + warning("Use the array literal notation [].", token); + } else { + i = parse(0); + c.dimension = i; + if ((i.id === '(number)' && /[.+\-Ee]/.test(i.value)) || + (i.id === '-' && !i.right) || + i.id === '(string)' || i.id === '[' || + i.id === '{' || i.id === 'true' || + i.id === 'false' || + i.id === 'null' || i.id === 'undefined' || + i.id === 'Infinity') { + warning("Use the array literal notation [].", token); + } + if (nexttoken.id !== ')') { + error("Use the array literal notation [].", token); + } + } + advance(')'); + } + this.first = c; + return this; + case 'Number': + case 'String': + case 'Boolean': + case 'Math': + case 'JSON': + warning("Do not use {a} as a constructor.", token, c.value); + break; + case 'Function': + if (!option.evil) { + warning("The Function constructor is eval."); + } + break; + case 'Date': + case 'RegExp': + break; + default: + if (c.id !== 'function') { + i = c.value.substr(0, 1); + if (option.newcap && (i < 'A' || i > 'Z')) { + warning( + "A constructor name should start with an uppercase letter.", + token); + } + } + } + } else { + if (c.id !== '.' && c.id !== '[' && c.id !== '(') { + warning("Bad constructor.", token); + } + } + } else { + warning("Weird construction. Delete 'new'.", this); + } + adjacent(token, nexttoken); + if (nexttoken.id !== '(') { + warning("Missing '()' invoking a constructor."); + } + this.first = c; + return this; + }); + syntax['new'].exps = true; + + infix('.', function (left, that) { + adjacent(prevtoken, token); + var m = identifier(); + if (typeof m === 'string') { + countMember(m); + } + that.left = left; + that.right = m; + if (!option.evil && left && left.value === 'document' && + (m === 'write' || m === 'writeln')) { + warning("document.write can be a form of eval.", left); + } else if (option.adsafe) { + if (left && left.value === 'ADSAFE') { + if (m === 'id' || m === 'lib') { + warning("ADsafe violation.", that); + } else if (m === 'go') { + if (xmode !== 'script') { + warning("ADsafe violation.", that); + } else if (adsafe_went || nexttoken.id !== '(' || + peek(0).id !== '(string)' || + peek(0).value !== adsafe_id || + peek(1).id !== ',') { + error("ADsafe violation: go.", that); + } + adsafe_went = true; + adsafe_may = false; + } + } + } + if (!option.evil && (m === 'eval' || m === 'execScript')) { + warning('eval is evil.'); + } else if (option.safe) { + for (;;) { + if (banned[m] === true) { + warning("ADsafe restricted word '{a}'.", token, m); + } + if (typeof predefined[left.value] !== 'boolean' || + nexttoken.id === '(') { + break; + } + if (standard_member[m] === true) { + if (nexttoken.id === '.') { + warning("ADsafe violation.", that); + } + break; + } + if (nexttoken.id !== '.') { + warning("ADsafe violation.", that); + break; + } + advance('.'); + token.left = that; + token.right = m; + that = token; + m = identifier(); + if (typeof m === 'string') { + countMember(m); + } + } + } + return that; + }, 160, true); + + infix('(', function (left, that) { + adjacent(prevtoken, token); + nospace(); + var n = 0, + p = []; + if (left) { + if (left.type === '(identifier)') { + if (left.value.match(/^[A-Z]([A-Z0-9_$]*[a-z][A-Za-z0-9_$]*)?$/)) { + if (left.value !== 'Number' && left.value !== 'String' && + left.value !== 'Boolean' && + left.value !== 'Date') { + if (left.value === 'Math') { + warning("Math is not a function.", left); + } else if (option.newcap) { + warning( +"Missing 'new' prefix when invoking a constructor.", left); + } + } + } + } else if (left.id === '.') { + if (option.safe && left.left.value === 'Math' && + left.right === 'random') { + warning("ADsafe violation.", left); + } + } + } + if (nexttoken.id !== ')') { + for (;;) { + p[p.length] = parse(10); + n += 1; + if (nexttoken.id !== ',') { + break; + } + comma(); + } + } + advance(')'); + if (option.immed && left.id === 'function' && nexttoken.id !== ')') { + warning("Wrap the entire immediate function invocation in parens.", + that); + } + nospace(prevtoken, token); + if (typeof left === 'object') { + if (left.value === 'parseInt' && n === 1) { + warning("Missing radix parameter.", left); + } + if (!option.evil) { + if (left.value === 'eval' || left.value === 'Function' || + left.value === 'execScript') { + warning("eval is evil.", left); + } else if (p[0] && p[0].id === '(string)' && + (left.value === 'setTimeout' || + left.value === 'setInterval')) { + warning( + "Implied eval is evil. Pass a function instead of a string.", left); + } + } + if (!left.identifier && left.id !== '.' && left.id !== '[' && + left.id !== '(' && left.id !== '&&' && left.id !== '||' && + left.id !== '?') { + warning("Bad invocation.", left); + } + } + that.left = left; + return that; + }, 155, true).exps = true; + + prefix('(', function () { + nospace(); + var v = parse(0); + advance(')', this); + nospace(prevtoken, token); + if (option.immed && v.id === 'function') { + if (nexttoken.id === '(') { + warning( +"Move the invocation into the parens that contain the function.", nexttoken); + } else { + warning( +"Do not wrap function literals in parens unless they are to be immediately invoked.", + this); + } + } + return v; + }); + + infix('[', function (left, that) { + nospace(); + var e = parse(0), s; + if (e && e.type === '(string)') { + if (option.safe && banned[e.value] === true) { + warning("ADsafe restricted word '{a}'.", that, e.value); + } else if (!option.evil && + (e.value === 'eval' || e.value === 'execScript')) { + warning("eval is evil.", that); + } else if (option.safe && + (e.value.charAt(0) === '_' || e.value.charAt(0) === '-')) { + warning("ADsafe restricted subscript '{a}'.", that, e.value); + } + countMember(e.value); + if (!option.sub && ix.test(e.value)) { + s = syntax[e.value]; + if (!s || !s.reserved) { + warning("['{a}'] is better written in dot notation.", + e, e.value); + } + } + } else if (!e || e.type !== '(number)' || e.value < 0) { + if (option.safe) { + warning('ADsafe subscripting.'); + } + } + advance(']', that); + nospace(prevtoken, token); + that.left = left; + that.right = e; + return that; + }, 160, true); + + prefix('[', function () { + var b = token.line !== nexttoken.line; + this.first = []; + if (b) { + indent += option.indent; + if (nexttoken.from === indent + option.indent) { + indent += option.indent; + } + } + while (nexttoken.id !== '(end)') { + while (nexttoken.id === ',') { + warning("Extra comma."); + advance(','); + } + if (nexttoken.id === ']') { + break; + } + if (b && token.line !== nexttoken.line) { + indentation(); + } + this.first.push(parse(10)); + if (nexttoken.id === ',') { + comma(); + if (nexttoken.id === ']') { + warning("Extra comma.", token); + break; + } + } else { + break; + } + } + if (b) { + indent -= option.indent; + indentation(); + } + advance(']', this); + return this; + }, 160); + + (function (x) { + x.nud = function () { + var b, i, s, seen = {}; + b = token.line !== nexttoken.line; + if (b) { + indent += option.indent; + if (nexttoken.from === indent + option.indent) { + indent += option.indent; + } + } + for (;;) { + if (nexttoken.id === '}') { + break; + } + if (b) { + indentation(); + } + i = optionalidentifier(true); + if (!i) { + if (nexttoken.id === '(string)') { + i = nexttoken.value; + if (ix.test(i)) { + s = syntax[i]; + } + advance(); + } else if (nexttoken.id === '(number)') { + i = nexttoken.value.toString(); + advance(); + } else { + error("Expected '{a}' and instead saw '{b}'.", + nexttoken, '}', nexttoken.value); + } + } + if (seen[i] === true) { + warning("Duplicate member '{a}'.", nexttoken, i); + } + seen[i] = true; + countMember(i); + advance(':'); + nonadjacent(token, nexttoken); + parse(10); + if (nexttoken.id === ',') { + comma(); + if (nexttoken.id === ',' || nexttoken.id === '}') { + warning("Extra comma.", token); + } + } else { + break; + } + } + if (b) { + indent -= option.indent; + indentation(); + } + advance('}', this); + return this; + }; + x.fud = function () { + error("Expected to see a statement and instead saw a block.", token); + }; + }(delim('{'))); + + + function varstatement(prefix) { + +// JavaScript does not have block scope. It only has function scope. So, +// declaring a variable in a block can have unexpected consequences. + + var id, name, value; + + if (funct['(onevar)'] && option.onevar) { + warning("Too many var statements."); + } else if (!funct['(global)']) { + funct['(onevar)'] = true; + } + this.first = []; + for (;;) { + nonadjacent(token, nexttoken); + id = identifier(); + if (funct['(global)'] && predefined[id] === false) { + warning("Redefinition of '{a}'.", token, id); + } + addlabel(id, 'unused'); + if (prefix) { + break; + } + name = token; + this.first.push(token); + if (nexttoken.id === '=') { + nonadjacent(token, nexttoken); + advance('='); + nonadjacent(token, nexttoken); + if (nexttoken.id === 'undefined') { + warning("It is not necessary to initialize '{a}' to 'undefined'.", token, id); + } + if (peek(0).id === '=' && nexttoken.identifier) { + error("Variable {a} was not declared correctly.", + nexttoken, nexttoken.value); + } + value = parse(0); + name.first = value; + } + if (nexttoken.id !== ',') { + break; + } + comma(); + } + return this; + } + + + stmt('var', varstatement).exps = true; + + + function functionparams() { + var i, t = nexttoken, p = []; + advance('('); + nospace(); + if (nexttoken.id === ')') { + advance(')'); + nospace(prevtoken, token); + return; + } + for (;;) { + i = identifier(); + p.push(i); + addlabel(i, 'parameter'); + if (nexttoken.id === ',') { + comma(); + } else { + advance(')', t); + nospace(prevtoken, token); + return p; + } + } + } + + function doFunction(i) { + var s = scope; + scope = Object.create(s); + funct = { + '(name)' : i || '"' + anonname + '"', + '(line)' : nexttoken.line, + '(context)' : funct, + '(breakage)': 0, + '(loopage)' : 0, + '(scope)' : scope + }; + token.funct = funct; + functions.push(funct); + if (i) { + addlabel(i, 'function'); + } + funct['(params)'] = functionparams(); + + block(false); + scope = s; + funct['(last)'] = token.line; + funct = funct['(context)']; + } + + + blockstmt('function', function () { + if (inblock) { + warning( +"Function statements cannot be placed in blocks. Use a function expression or move the statement to the top of the outer function.", token); + + } + var i = identifier(); + adjacent(token, nexttoken); + addlabel(i, 'unused'); + doFunction(i); + if (nexttoken.id === '(' && nexttoken.line === token.line) { + error( +"Function statements are not invocable. Wrap the whole function invocation in parens."); + } + return this; + }); + + prefix('function', function () { + var i = optionalidentifier(); + if (i) { + adjacent(token, nexttoken); + } else { + nonadjacent(token, nexttoken); + } + doFunction(i); + if (funct['(loopage)']) { + warning("Don't make functions within a loop."); + } + return this; + }); + + blockstmt('if', function () { + var t = nexttoken; + advance('('); + nonadjacent(this, t); + nospace(); + parse(20); + if (nexttoken.id === '=') { + warning("Expected a conditional expression and instead saw an assignment."); + advance('='); + parse(20); + } + advance(')', t); + nospace(prevtoken, token); + block(true); + if (nexttoken.id === 'else') { + nonadjacent(token, nexttoken); + advance('else'); + if (nexttoken.id === 'if' || nexttoken.id === 'switch') { + statement(true); + } else { + block(true); + } + } + return this; + }); + + blockstmt('try', function () { + var b, e, s; + if (option.adsafe) { + warning("ADsafe try violation.", this); + } + block(false); + if (nexttoken.id === 'catch') { + advance('catch'); + nonadjacent(token, nexttoken); + advance('('); + s = scope; + scope = Object.create(s); + e = nexttoken.value; + if (nexttoken.type !== '(identifier)') { + warning("Expected an identifier and instead saw '{a}'.", + nexttoken, e); + } else { + addlabel(e, 'exception'); + } + advance(); + advance(')'); + block(false); + b = true; + scope = s; + } + if (nexttoken.id === 'finally') { + advance('finally'); + block(false); + return; + } else if (!b) { + error("Expected '{a}' and instead saw '{b}'.", + nexttoken, 'catch', nexttoken.value); + } + return this; + }); + + blockstmt('while', function () { + var t = nexttoken; + funct['(breakage)'] += 1; + funct['(loopage)'] += 1; + advance('('); + nonadjacent(this, t); + nospace(); + parse(20); + if (nexttoken.id === '=') { + warning("Expected a conditional expression and instead saw an assignment."); + advance('='); + parse(20); + } + advance(')', t); + nospace(prevtoken, token); + block(true); + funct['(breakage)'] -= 1; + funct['(loopage)'] -= 1; + return this; + }).labelled = true; + + reserve('with'); + + blockstmt('switch', function () { + var t = nexttoken, + g = false; + funct['(breakage)'] += 1; + advance('('); + nonadjacent(this, t); + nospace(); + this.condition = parse(20); + advance(')', t); + nospace(prevtoken, token); + nonadjacent(token, nexttoken); + t = nexttoken; + advance('{'); + nonadjacent(token, nexttoken); + indent += option.indent; + this.cases = []; + for (;;) { + switch (nexttoken.id) { + case 'case': + switch (funct['(verb)']) { + case 'break': + case 'case': + case 'continue': + case 'return': + case 'switch': + case 'throw': + break; + default: + warning( + "Expected a 'break' statement before 'case'.", + token); + } + indentation(-option.indent); + advance('case'); + this.cases.push(parse(20)); + g = true; + advance(':'); + funct['(verb)'] = 'case'; + break; + case 'default': + switch (funct['(verb)']) { + case 'break': + case 'continue': + case 'return': + case 'throw': + break; + default: + warning( + "Expected a 'break' statement before 'default'.", + token); + } + indentation(-option.indent); + advance('default'); + g = true; + advance(':'); + break; + case '}': + indent -= option.indent; + indentation(); + advance('}', t); + if (this.cases.length === 1 || this.condition.id === 'true' || + this.condition.id === 'false') { + warning("This 'switch' should be an 'if'.", this); + } + funct['(breakage)'] -= 1; + funct['(verb)'] = undefined; + return; + case '(end)': + error("Missing '{a}'.", nexttoken, '}'); + return; + default: + if (g) { + switch (token.id) { + case ',': + error("Each value should have its own case label."); + return; + case ':': + statements(); + break; + default: + error("Missing ':' on a case clause.", token); + } + } else { + error("Expected '{a}' and instead saw '{b}'.", + nexttoken, 'case', nexttoken.value); + } + } + } + }).labelled = true; + + stmt('debugger', function () { + if (!option.debug) { + warning("All 'debugger' statements should be removed."); + } + return this; + }).exps = true; + + (function () { + var x = stmt('do', function () { + funct['(breakage)'] += 1; + funct['(loopage)'] += 1; + this.first = block(true); + advance('while'); + var t = nexttoken; + nonadjacent(token, t); + advance('('); + nospace(); + parse(20); + if (nexttoken.id === '=') { + warning("Expected a conditional expression and instead saw an assignment."); + advance('='); + parse(20); + } + advance(')', t); + nospace(prevtoken, token); + funct['(breakage)'] -= 1; + funct['(loopage)'] -= 1; + return this; + }); + x.labelled = true; + x.exps = true; + }()); + + blockstmt('for', function () { + var f = option.forin, s, t = nexttoken; + funct['(breakage)'] += 1; + funct['(loopage)'] += 1; + advance('('); + nonadjacent(this, t); + nospace(); + if (peek(nexttoken.id === 'var' ? 1 : 0).id === 'in') { + if (nexttoken.id === 'var') { + advance('var'); + varstatement(true); + } else { + switch (funct[nexttoken.value]) { + case 'unused': + funct[nexttoken.value] = 'var'; + break; + case 'var': + break; + default: + warning("Bad for in variable '{a}'.", + nexttoken, nexttoken.value); + } + advance(); + } + advance('in'); + parse(20); + advance(')', t); + s = block(true); + if (!f && (s.length > 1 || typeof s[0] !== 'object' || + s[0].value !== 'if')) { + warning("The body of a for in should be wrapped in an if statement to filter unwanted properties from the prototype.", this); + } + funct['(breakage)'] -= 1; + funct['(loopage)'] -= 1; + return this; + } else { + if (nexttoken.id !== ';') { + if (nexttoken.id === 'var') { + advance('var'); + varstatement(); + } else { + for (;;) { + parse(0, 'for'); + if (nexttoken.id !== ',') { + break; + } + comma(); + } + } + } + nolinebreak(token); + advance(';'); + if (nexttoken.id !== ';') { + parse(20); + if (nexttoken.id === '=') { + warning("Expected a conditional expression and instead saw an assignment."); + advance('='); + parse(20); + } + } + nolinebreak(token); + advance(';'); + if (nexttoken.id === ';') { + error("Expected '{a}' and instead saw '{b}'.", + nexttoken, ')', ';'); + } + if (nexttoken.id !== ')') { + for (;;) { + parse(0, 'for'); + if (nexttoken.id !== ',') { + break; + } + comma(); + } + } + advance(')', t); + nospace(prevtoken, token); + block(true); + funct['(breakage)'] -= 1; + funct['(loopage)'] -= 1; + return this; + } + }).labelled = true; + + + stmt('break', function () { + var v = nexttoken.value; + if (funct['(breakage)'] === 0) { + warning("Unexpected '{a}'.", nexttoken, this.value); + } + nolinebreak(this); + if (nexttoken.id !== ';') { + if (token.line === nexttoken.line) { + if (funct[v] !== 'label') { + warning("'{a}' is not a statement label.", nexttoken, v); + } else if (scope[v] !== funct) { + warning("'{a}' is out of scope.", nexttoken, v); + } + this.first = nexttoken; + advance(); + } + } + reachable('break'); + return this; + }).exps = true; + + + stmt('continue', function () { + var v = nexttoken.value; + if (funct['(breakage)'] === 0) { + warning("Unexpected '{a}'.", nexttoken, this.value); + } + nolinebreak(this); + if (nexttoken.id !== ';') { + if (token.line === nexttoken.line) { + if (funct[v] !== 'label') { + warning("'{a}' is not a statement label.", nexttoken, v); + } else if (scope[v] !== funct) { + warning("'{a}' is out of scope.", nexttoken, v); + } + this.first = nexttoken; + advance(); + } + } else if (!funct['(loopage)']) { + warning("Unexpected '{a}'.", nexttoken, this.value); + } + reachable('continue'); + return this; + }).exps = true; + + + stmt('return', function () { + nolinebreak(this); + if (nexttoken.id === '(regexp)') { + warning("Wrap the /regexp/ literal in parens to disambiguate the slash operator."); + } + if (nexttoken.id !== ';' && !nexttoken.reach) { + nonadjacent(token, nexttoken); + this.first = parse(20); + } + reachable('return'); + return this; + }).exps = true; + + + stmt('throw', function () { + nolinebreak(this); + nonadjacent(token, nexttoken); + this.first = parse(20); + reachable('throw'); + return this; + }).exps = true; + + reserve('void'); + +// Superfluous reserved words + + reserve('class'); + reserve('const'); + reserve('enum'); + reserve('export'); + reserve('extends'); + reserve('import'); + reserve('super'); + + reserve('let'); + reserve('yield'); + reserve('implements'); + reserve('interface'); + reserve('package'); + reserve('private'); + reserve('protected'); + reserve('public'); + reserve('static'); + + function jsonValue() { + + function jsonObject() { + var o = {}, t = nexttoken; + advance('{'); + if (nexttoken.id !== '}') { + for (;;) { + if (nexttoken.id === '(end)') { + error("Missing '}' to match '{' from line {a}.", + nexttoken, t.line); + } else if (nexttoken.id === '}') { + warning("Unexpected comma.", token); + break; + } else if (nexttoken.id === ',') { + error("Unexpected comma.", nexttoken); + } else if (nexttoken.id !== '(string)') { + warning("Expected a string and instead saw {a}.", + nexttoken, nexttoken.value); + } + if (o[nexttoken.value] === true) { + warning("Duplicate key '{a}'.", + nexttoken, nexttoken.value); + } else if (nexttoken.value === '__proto__') { + warning("Stupid key '{a}'.", + nexttoken, nexttoken.value); + } else { + o[nexttoken.value] = true; + } + advance(); + advance(':'); + jsonValue(); + if (nexttoken.id !== ',') { + break; + } + advance(','); + } + } + advance('}'); + } + + function jsonArray() { + var t = nexttoken; + advance('['); + if (nexttoken.id !== ']') { + for (;;) { + if (nexttoken.id === '(end)') { + error("Missing ']' to match '[' from line {a}.", + nexttoken, t.line); + } else if (nexttoken.id === ']') { + warning("Unexpected comma.", token); + break; + } else if (nexttoken.id === ',') { + error("Unexpected comma.", nexttoken); + } + jsonValue(); + if (nexttoken.id !== ',') { + break; + } + advance(','); + } + } + advance(']'); + } + + switch (nexttoken.id) { + case '{': + jsonObject(); + break; + case '[': + jsonArray(); + break; + case 'true': + case 'false': + case 'null': + case '(number)': + case '(string)': + advance(); + break; + case '-': + advance('-'); + if (token.character !== nexttoken.from) { + warning("Unexpected space after '-'.", token); + } + adjacent(token, nexttoken); + advance('(number)'); + break; + default: + error("Expected a JSON value.", nexttoken); + } + } + + +// The actual JSLINT function itself. + + var itself = function (s, o) { + var a, i; + JSLINT.errors = []; + predefined = Object.create(standard); + if (o) { + a = o.predef; + if (a instanceof Array) { + for (i = 0; i < a.length; i += 1) { + predefined[a[i]] = true; + } + } + if (o.adsafe) { + o.safe = true; + } + if (o.safe) { + o.browser = false; + o.css = false; + o.debug = false; + o.devel = false; + o.eqeqeq = true; + o.evil = false; + o.forin = false; + o.nomen = true; + o.on = false; + o.rhino = false; + o.safe = true; + o.sidebar = false; + o.strict = true; + o.sub = false; + o.undef = true; + o.widget = false; + predefined.Date = null; + predefined['eval'] = null; + predefined.Function = null; + predefined.Object = null; + predefined.ADSAFE = false; + predefined.lib = false; + } + option = o; + } else { + option = {}; + } + option.indent = option.indent || 4; + option.maxerr = option.maxerr || 50; + adsafe_id = ''; + adsafe_may = false; + adsafe_went = false; + approved = {}; + if (option.approved) { + for (i = 0; i < option.approved.length; i += 1) { + approved[option.approved[i]] = option.approved[i]; + } + } else { + approved.test = 'test'; + } + tab = ''; + for (i = 0; i < option.indent; i += 1) { + tab += ' '; + } + indent = 1; + global = Object.create(predefined); + scope = global; + funct = { + '(global)': true, + '(name)': '(global)', + '(scope)': scope, + '(breakage)': 0, + '(loopage)': 0 + }; + functions = [funct]; + ids = {}; + urls = []; + src = false; + xmode = false; + stack = null; + member = {}; + membersOnly = null; + implied = {}; + inblock = false; + lookahead = []; + jsonmode = false; + warnings = 0; + lex.init(s); + prereg = true; + strict_mode = false; + + prevtoken = token = nexttoken = syntax['(begin)']; + assume(); + + try { + advance(); + if (nexttoken.value.charAt(0) === '<') { + html(); + if (option.adsafe && !adsafe_went) { + warning("ADsafe violation: Missing ADSAFE.go.", this); + } + } else { + switch (nexttoken.id) { + case '{': + case '[': + option.laxbreak = true; + jsonmode = true; + jsonValue(); + break; + case '@': + case '*': + case '#': + case '.': + case ':': + xmode = 'style'; + advance(); + if (token.id !== '@' || !nexttoken.identifier || + nexttoken.value !== 'charset' || token.line !== 1 || + token.from !== 1) { + error('A css file should begin with @charset "UTF-8";'); + } + advance(); + if (nexttoken.type !== '(string)' && + nexttoken.value !== 'UTF-8') { + error('A css file should begin with @charset "UTF-8";'); + } + advance(); + advance(';'); + styles(); + break; + + default: + if (option.adsafe && option.fragment) { + error("Expected '{a}' and instead saw '{b}'.", + nexttoken, '
', nexttoken.value); + } + statements('lib'); + } + } + advance('(end)'); + } catch (e) { + if (e) { + JSLINT.errors.push({ + reason : e.message, + line : e.line || nexttoken.line, + character : e.character || nexttoken.from + }, null); + } + } + return JSLINT.errors.length === 0; + }; + + function is_array(o) { + return Object.prototype.toString.apply(o) === '[object Array]'; + } + + function to_array(o) { + var a = [], k; + for (k in o) { + if (is_own(o, k)) { + a.push(k); + } + } + return a; + } + +// Data summary. + + itself.data = function () { + + var data = {functions: []}, fu, globals, implieds = [], f, i, j, + members = [], n, unused = [], v; + if (itself.errors.length) { + data.errors = itself.errors; + } + + if (jsonmode) { + data.json = true; + } + + for (n in implied) { + if (is_own(implied, n)) { + implieds.push({ + name: n, + line: implied[n] + }); + } + } + if (implieds.length > 0) { + data.implieds = implieds; + } + + if (urls.length > 0) { + data.urls = urls; + } + + globals = to_array(scope); + if (globals.length > 0) { + data.globals = globals; + } + + for (i = 1; i < functions.length; i += 1) { + f = functions[i]; + fu = {}; + for (j = 0; j < functionicity.length; j += 1) { + fu[functionicity[j]] = []; + } + for (n in f) { + if (is_own(f, n) && n.charAt(0) !== '(') { + v = f[n]; + if (is_array(fu[v])) { + fu[v].push(n); + if (v === 'unused') { + unused.push({ + name: n, + line: f['(line)'], + 'function': f['(name)'] + }); + } + } + } + } + for (j = 0; j < functionicity.length; j += 1) { + if (fu[functionicity[j]].length === 0) { + delete fu[functionicity[j]]; + } + } + fu.name = f['(name)']; + fu.param = f['(params)']; + fu.line = f['(line)']; + fu.last = f['(last)']; + data.functions.push(fu); + } + + if (unused.length > 0) { + data.unused = unused; + } + + members = []; + for (n in member) { + if (typeof member[n] === 'number') { + data.member = member; + break; + } + } + + return data; + }; + + itself.report = function (option) { + var data = itself.data(); + + var a = [], c, e, err, f, i, k, l, m = '', n, o = [], s; + + function detail(h, array) { + var b, i, singularity; + if (array) { + o.push('
' + h + ' '); + array = array.sort(); + for (i = 0; i < array.length; i += 1) { + if (array[i] !== singularity) { + singularity = array[i]; + o.push((b ? ', ' : '') + singularity); + b = true; + } + } + o.push('
'); + } + } + + + if (data.errors || data.implieds || data.unused) { + err = true; + o.push('
Error:'); + if (data.errors) { + for (i = 0; i < data.errors.length; i += 1) { + c = data.errors[i]; + if (c) { + e = c.evidence || ''; + o.push('

Problem' + (isFinite(c.line) ? ' at line ' + + c.line + ' character ' + c.character : '') + + ': ' + c.reason.entityify() + + '

' + + (e && (e.length > 80 ? e.slice(0, 77) + '...' : + e).entityify()) + '

'); + } + } + } + + if (data.implieds) { + s = []; + for (i = 0; i < data.implieds.length; i += 1) { + s[i] = '' + data.implieds[i].name + ' ' + + data.implieds[i].line + ''; + } + o.push('

Implied global: ' + s.join(', ') + '

'); + } + + if (data.unused) { + s = []; + for (i = 0; i < data.unused.length; i += 1) { + s[i] = '' + data.unused[i].name + ' ' + + data.unused[i].line + ' ' + + data.unused[i]['function'] + ''; + } + o.push('

Unused variable: ' + s.join(', ') + '

'); + } + if (data.json) { + o.push('

JSON: bad.

'); + } + o.push('
'); + } + + if (!option) { + + o.push('
'); + + if (data.urls) { + detail("URLs
", data.urls, '
'); + } + + if (xmode === 'style') { + o.push('

CSS.

'); + } else if (data.json && !err) { + o.push('

JSON: good.

'); + } else if (data.globals) { + o.push('
Global ' + + data.globals.sort().join(', ') + '
'); + } else { + o.push('
No new global variables introduced.
'); + } + + for (i = 0; i < data.functions.length; i += 1) { + f = data.functions[i]; + + o.push('
' + f.line + '-' + + f.last + ' ' + (f.name || '') + '(' + + (f.param ? f.param.join(', ') : '') + ')
'); + detail('Unused', f.unused); + detail('Closure', f.closure); + detail('Variable', f['var']); + detail('Exception', f.exception); + detail('Outer', f.outer); + detail('Global', f.global); + detail('Label', f.label); + } + + if (data.member) { + a = to_array(data.member); + if (a.length) { + a = a.sort(); + m = '
/*members ';
+                    l = 10;
+                    for (i = 0; i < a.length; i += 1) {
+                        k = a[i];
+                        n = k.name();
+                        if (l + n.length > 72) {
+                            o.push(m + '
'); + m = ' '; + l = 1; + } + l += n.length + 2; + if (data.member[k] === 1) { + n = '' + n + ''; + } + if (i < a.length - 1) { + n += ', '; + } + m += n; + } + o.push(m + '
*/
'); + } + o.push('
'); + } + } + return o.join(''); + }; + itself.jslint = itself; + + itself.edition = '2010-02-20'; + + if (typeof exports !== "undefined") { + exports.JSLINT = itself; + } + + return itself; + +}()); diff --git a/build/lib/parse-js.js b/build/lib/parse-js.js new file mode 100644 index 0000000..8edecb7 --- /dev/null +++ b/build/lib/parse-js.js @@ -0,0 +1,1315 @@ +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + + This version is suitable for Node.js. With minimal changes (the + exports stuff) it should work on any JS platform. + + This file contains the tokenizer/parser. It is a port to JavaScript + of parse-js [1], a JavaScript parser library written in Common Lisp + by Marijn Haverbeke. Thank you Marijn! + + [1] http://marijn.haverbeke.nl/parse-js/ + + Exported functions: + + - tokenizer(code) -- returns a function. Call the returned + function to fetch the next token. + + - parse(code) -- returns an AST of the given JavaScript code. + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2010 (c) Mihai Bazon + Based on parse-js (http://marijn.haverbeke.nl/parse-js/). + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + + ***********************************************************************/ + +/* -----[ Tokenizer (constants) ]----- */ + +var KEYWORDS = array_to_hash([ + "break", + "case", + "catch", + "const", + "continue", + "default", + "delete", + "do", + "else", + "finally", + "for", + "function", + "if", + "in", + "instanceof", + "new", + "return", + "switch", + "throw", + "try", + "typeof", + "var", + "void", + "while", + "with" +]); + +var RESERVED_WORDS = array_to_hash([ + "abstract", + "boolean", + "byte", + "char", + "class", + "debugger", + "double", + "enum", + "export", + "extends", + "final", + "float", + "goto", + "implements", + "import", + "int", + "interface", + "long", + "native", + "package", + "private", + "protected", + "public", + "short", + "static", + "super", + "synchronized", + "throws", + "transient", + "volatile" +]); + +var KEYWORDS_BEFORE_EXPRESSION = array_to_hash([ + "return", + "new", + "delete", + "throw", + "else", + "case" +]); + +var KEYWORDS_ATOM = array_to_hash([ + "false", + "null", + "true", + "undefined" +]); + +var OPERATOR_CHARS = array_to_hash(characters("+-*&%=<>!?|~^")); + +var RE_HEX_NUMBER = /^0x[0-9a-f]+$/i; +var RE_OCT_NUMBER = /^0[0-7]+$/; +var RE_DEC_NUMBER = /^\d*\.?\d*(?:e[+-]?\d*(?:\d\.?|\.?\d)\d*)?$/i; + +var OPERATORS = array_to_hash([ + "in", + "instanceof", + "typeof", + "new", + "void", + "delete", + "++", + "--", + "+", + "-", + "!", + "~", + "&", + "|", + "^", + "*", + "/", + "%", + ">>", + "<<", + ">>>", + "<", + ">", + "<=", + ">=", + "==", + "===", + "!=", + "!==", + "?", + "=", + "+=", + "-=", + "/=", + "*=", + "%=", + ">>=", + "<<=", + ">>>=", + "|=", + "^=", + "&=", + "&&", + "||" +]); + +var WHITESPACE_CHARS = array_to_hash(characters(" \n\r\t\u200b")); + +var PUNC_BEFORE_EXPRESSION = array_to_hash(characters("[{}(,.;:")); + +var PUNC_CHARS = array_to_hash(characters("[]{}(),;:")); + +var REGEXP_MODIFIERS = array_to_hash(characters("gmsiy")); + +/* -----[ Tokenizer ]----- */ + +// regexps adapted from http://xregexp.com/plugins/#unicode +var UNICODE = { + letter: new RegExp("[\\u0041-\\u005A\\u0061-\\u007A\\u00AA\\u00B5\\u00BA\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0370-\\u0374\\u0376\\u0377\\u037A-\\u037D\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u048A-\\u0523\\u0531-\\u0556\\u0559\\u0561-\\u0587\\u05D0-\\u05EA\\u05F0-\\u05F2\\u0621-\\u064A\\u066E\\u066F\\u0671-\\u06D3\\u06D5\\u06E5\\u06E6\\u06EE\\u06EF\\u06FA-\\u06FC\\u06FF\\u0710\\u0712-\\u072F\\u074D-\\u07A5\\u07B1\\u07CA-\\u07EA\\u07F4\\u07F5\\u07FA\\u0904-\\u0939\\u093D\\u0950\\u0958-\\u0961\\u0971\\u0972\\u097B-\\u097F\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BD\\u09CE\\u09DC\\u09DD\\u09DF-\\u09E1\\u09F0\\u09F1\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AD0\\u0AE0\\u0AE1\\u0B05-\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B3D\\u0B5C\\u0B5D\\u0B5F-\\u0B61\\u0B71\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BD0\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C33\\u0C35-\\u0C39\\u0C3D\\u0C58\\u0C59\\u0C60\\u0C61\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBD\\u0CDE\\u0CE0\\u0CE1\\u0D05-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D28\\u0D2A-\\u0D39\\u0D3D\\u0D60\\u0D61\\u0D7A-\\u0D7F\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0E01-\\u0E30\\u0E32\\u0E33\\u0E40-\\u0E46\\u0E81\\u0E82\\u0E84\\u0E87\\u0E88\\u0E8A\\u0E8D\\u0E94-\\u0E97\\u0E99-\\u0E9F\\u0EA1-\\u0EA3\\u0EA5\\u0EA7\\u0EAA\\u0EAB\\u0EAD-\\u0EB0\\u0EB2\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EDC\\u0EDD\\u0F00\\u0F40-\\u0F47\\u0F49-\\u0F6C\\u0F88-\\u0F8B\\u1000-\\u102A\\u103F\\u1050-\\u1055\\u105A-\\u105D\\u1061\\u1065\\u1066\\u106E-\\u1070\\u1075-\\u1081\\u108E\\u10A0-\\u10C5\\u10D0-\\u10FA\\u10FC\\u1100-\\u1159\\u115F-\\u11A2\\u11A8-\\u11F9\\u1200-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u1380-\\u138F\\u13A0-\\u13F4\\u1401-\\u166C\\u166F-\\u1676\\u1681-\\u169A\\u16A0-\\u16EA\\u1700-\\u170C\\u170E-\\u1711\\u1720-\\u1731\\u1740-\\u1751\\u1760-\\u176C\\u176E-\\u1770\\u1780-\\u17B3\\u17D7\\u17DC\\u1820-\\u1877\\u1880-\\u18A8\\u18AA\\u1900-\\u191C\\u1950-\\u196D\\u1970-\\u1974\\u1980-\\u19A9\\u19C1-\\u19C7\\u1A00-\\u1A16\\u1B05-\\u1B33\\u1B45-\\u1B4B\\u1B83-\\u1BA0\\u1BAE\\u1BAF\\u1C00-\\u1C23\\u1C4D-\\u1C4F\\u1C5A-\\u1C7D\\u1D00-\\u1DBF\\u1E00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2071\\u207F\\u2090-\\u2094\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2183\\u2184\\u2C00-\\u2C2E\\u2C30-\\u2C5E\\u2C60-\\u2C6F\\u2C71-\\u2C7D\\u2C80-\\u2CE4\\u2D00-\\u2D25\\u2D30-\\u2D65\\u2D6F\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2E2F\\u3005\\u3006\\u3031-\\u3035\\u303B\\u303C\\u3041-\\u3096\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312D\\u3131-\\u318E\\u31A0-\\u31B7\\u31F0-\\u31FF\\u3400\\u4DB5\\u4E00\\u9FC3\\uA000-\\uA48C\\uA500-\\uA60C\\uA610-\\uA61F\\uA62A\\uA62B\\uA640-\\uA65F\\uA662-\\uA66E\\uA67F-\\uA697\\uA717-\\uA71F\\uA722-\\uA788\\uA78B\\uA78C\\uA7FB-\\uA801\\uA803-\\uA805\\uA807-\\uA80A\\uA80C-\\uA822\\uA840-\\uA873\\uA882-\\uA8B3\\uA90A-\\uA925\\uA930-\\uA946\\uAA00-\\uAA28\\uAA40-\\uAA42\\uAA44-\\uAA4B\\uAC00\\uD7A3\\uF900-\\uFA2D\\uFA30-\\uFA6A\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40\\uFB41\\uFB43\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF21-\\uFF3A\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC]"), + non_spacing_mark: new RegExp("[\\u0300-\\u036F\\u0483-\\u0487\\u0591-\\u05BD\\u05BF\\u05C1\\u05C2\\u05C4\\u05C5\\u05C7\\u0610-\\u061A\\u064B-\\u065E\\u0670\\u06D6-\\u06DC\\u06DF-\\u06E4\\u06E7\\u06E8\\u06EA-\\u06ED\\u0711\\u0730-\\u074A\\u07A6-\\u07B0\\u07EB-\\u07F3\\u0816-\\u0819\\u081B-\\u0823\\u0825-\\u0827\\u0829-\\u082D\\u0900-\\u0902\\u093C\\u0941-\\u0948\\u094D\\u0951-\\u0955\\u0962\\u0963\\u0981\\u09BC\\u09C1-\\u09C4\\u09CD\\u09E2\\u09E3\\u0A01\\u0A02\\u0A3C\\u0A41\\u0A42\\u0A47\\u0A48\\u0A4B-\\u0A4D\\u0A51\\u0A70\\u0A71\\u0A75\\u0A81\\u0A82\\u0ABC\\u0AC1-\\u0AC5\\u0AC7\\u0AC8\\u0ACD\\u0AE2\\u0AE3\\u0B01\\u0B3C\\u0B3F\\u0B41-\\u0B44\\u0B4D\\u0B56\\u0B62\\u0B63\\u0B82\\u0BC0\\u0BCD\\u0C3E-\\u0C40\\u0C46-\\u0C48\\u0C4A-\\u0C4D\\u0C55\\u0C56\\u0C62\\u0C63\\u0CBC\\u0CBF\\u0CC6\\u0CCC\\u0CCD\\u0CE2\\u0CE3\\u0D41-\\u0D44\\u0D4D\\u0D62\\u0D63\\u0DCA\\u0DD2-\\u0DD4\\u0DD6\\u0E31\\u0E34-\\u0E3A\\u0E47-\\u0E4E\\u0EB1\\u0EB4-\\u0EB9\\u0EBB\\u0EBC\\u0EC8-\\u0ECD\\u0F18\\u0F19\\u0F35\\u0F37\\u0F39\\u0F71-\\u0F7E\\u0F80-\\u0F84\\u0F86\\u0F87\\u0F90-\\u0F97\\u0F99-\\u0FBC\\u0FC6\\u102D-\\u1030\\u1032-\\u1037\\u1039\\u103A\\u103D\\u103E\\u1058\\u1059\\u105E-\\u1060\\u1071-\\u1074\\u1082\\u1085\\u1086\\u108D\\u109D\\u135F\\u1712-\\u1714\\u1732-\\u1734\\u1752\\u1753\\u1772\\u1773\\u17B7-\\u17BD\\u17C6\\u17C9-\\u17D3\\u17DD\\u180B-\\u180D\\u18A9\\u1920-\\u1922\\u1927\\u1928\\u1932\\u1939-\\u193B\\u1A17\\u1A18\\u1A56\\u1A58-\\u1A5E\\u1A60\\u1A62\\u1A65-\\u1A6C\\u1A73-\\u1A7C\\u1A7F\\u1B00-\\u1B03\\u1B34\\u1B36-\\u1B3A\\u1B3C\\u1B42\\u1B6B-\\u1B73\\u1B80\\u1B81\\u1BA2-\\u1BA5\\u1BA8\\u1BA9\\u1C2C-\\u1C33\\u1C36\\u1C37\\u1CD0-\\u1CD2\\u1CD4-\\u1CE0\\u1CE2-\\u1CE8\\u1CED\\u1DC0-\\u1DE6\\u1DFD-\\u1DFF\\u20D0-\\u20DC\\u20E1\\u20E5-\\u20F0\\u2CEF-\\u2CF1\\u2DE0-\\u2DFF\\u302A-\\u302F\\u3099\\u309A\\uA66F\\uA67C\\uA67D\\uA6F0\\uA6F1\\uA802\\uA806\\uA80B\\uA825\\uA826\\uA8C4\\uA8E0-\\uA8F1\\uA926-\\uA92D\\uA947-\\uA951\\uA980-\\uA982\\uA9B3\\uA9B6-\\uA9B9\\uA9BC\\uAA29-\\uAA2E\\uAA31\\uAA32\\uAA35\\uAA36\\uAA43\\uAA4C\\uAAB0\\uAAB2-\\uAAB4\\uAAB7\\uAAB8\\uAABE\\uAABF\\uAAC1\\uABE5\\uABE8\\uABED\\uFB1E\\uFE00-\\uFE0F\\uFE20-\\uFE26]"), + space_combining_mark: new RegExp("[\\u0903\\u093E-\\u0940\\u0949-\\u094C\\u094E\\u0982\\u0983\\u09BE-\\u09C0\\u09C7\\u09C8\\u09CB\\u09CC\\u09D7\\u0A03\\u0A3E-\\u0A40\\u0A83\\u0ABE-\\u0AC0\\u0AC9\\u0ACB\\u0ACC\\u0B02\\u0B03\\u0B3E\\u0B40\\u0B47\\u0B48\\u0B4B\\u0B4C\\u0B57\\u0BBE\\u0BBF\\u0BC1\\u0BC2\\u0BC6-\\u0BC8\\u0BCA-\\u0BCC\\u0BD7\\u0C01-\\u0C03\\u0C41-\\u0C44\\u0C82\\u0C83\\u0CBE\\u0CC0-\\u0CC4\\u0CC7\\u0CC8\\u0CCA\\u0CCB\\u0CD5\\u0CD6\\u0D02\\u0D03\\u0D3E-\\u0D40\\u0D46-\\u0D48\\u0D4A-\\u0D4C\\u0D57\\u0D82\\u0D83\\u0DCF-\\u0DD1\\u0DD8-\\u0DDF\\u0DF2\\u0DF3\\u0F3E\\u0F3F\\u0F7F\\u102B\\u102C\\u1031\\u1038\\u103B\\u103C\\u1056\\u1057\\u1062-\\u1064\\u1067-\\u106D\\u1083\\u1084\\u1087-\\u108C\\u108F\\u109A-\\u109C\\u17B6\\u17BE-\\u17C5\\u17C7\\u17C8\\u1923-\\u1926\\u1929-\\u192B\\u1930\\u1931\\u1933-\\u1938\\u19B0-\\u19C0\\u19C8\\u19C9\\u1A19-\\u1A1B\\u1A55\\u1A57\\u1A61\\u1A63\\u1A64\\u1A6D-\\u1A72\\u1B04\\u1B35\\u1B3B\\u1B3D-\\u1B41\\u1B43\\u1B44\\u1B82\\u1BA1\\u1BA6\\u1BA7\\u1BAA\\u1C24-\\u1C2B\\u1C34\\u1C35\\u1CE1\\u1CF2\\uA823\\uA824\\uA827\\uA880\\uA881\\uA8B4-\\uA8C3\\uA952\\uA953\\uA983\\uA9B4\\uA9B5\\uA9BA\\uA9BB\\uA9BD-\\uA9C0\\uAA2F\\uAA30\\uAA33\\uAA34\\uAA4D\\uAA7B\\uABE3\\uABE4\\uABE6\\uABE7\\uABE9\\uABEA\\uABEC]"), + connector_punctuation: new RegExp("[\\u005F\\u203F\\u2040\\u2054\\uFE33\\uFE34\\uFE4D-\\uFE4F\\uFF3F]") +}; + +function is_letter(ch) { + return UNICODE.letter.test(ch); +}; + +function is_digit(ch) { + ch = ch.charCodeAt(0); + return ch >= 48 && ch <= 57; //XXX: find out if "UnicodeDigit" means something else than 0..9 +}; + +function is_alphanumeric_char(ch) { + return is_digit(ch) || is_letter(ch); +}; + +function is_unicode_combining_mark(ch) { + return UNICODE.non_spacing_mark.test(ch) || UNICODE.space_combining_mark.test(ch); +}; + +function is_unicode_connector_punctuation(ch) { + return UNICODE.connector_punctuation.test(ch); +}; + +function is_identifier_start(ch) { + return ch == "$" || ch == "_" || is_letter(ch); +}; + +function is_identifier_char(ch) { + return is_identifier_start(ch) + || is_unicode_combining_mark(ch) + || is_digit(ch) + || is_unicode_connector_punctuation(ch) + || ch == "\u200c" // zero-width non-joiner + || ch == "\u200d" // zero-width joiner (in my ECMA-262 PDF, this is also 200c) + ; +}; + +function parse_js_number(num) { + if (RE_HEX_NUMBER.test(num)) { + return parseInt(num.substr(2), 16); + } else if (RE_OCT_NUMBER.test(num)) { + return parseInt(num.substr(1), 8); + } else if (RE_DEC_NUMBER.test(num)) { + return parseFloat(num); + } +}; + +function JS_Parse_Error(message, line, col, pos) { + this.message = message; + this.line = line; + this.col = col; + this.pos = pos; + try { + ({})(); + } catch(ex) { + this.stack = ex.stack; + }; +}; + +JS_Parse_Error.prototype.toString = function() { + return this.message + " (line: " + this.line + ", col: " + this.col + ", pos: " + this.pos + ")" + "\n\n" + this.stack; +}; + +function js_error(message, line, col, pos) { + throw new JS_Parse_Error(message, line, col, pos); +}; + +function is_token(token, type, val) { + return token.type == type && (val == null || token.value == val); +}; + +var EX_EOF = {}; + +function tokenizer($TEXT) { + + var S = { + text : $TEXT.replace(/\r\n?|[\n\u2028\u2029]/g, "\n").replace(/^\uFEFF/, ''), + pos : 0, + tokpos : 0, + line : 0, + tokline : 0, + col : 0, + tokcol : 0, + newline_before : false, + regex_allowed : false, + comments_before : [] + }; + + function peek() { return S.text.charAt(S.pos); }; + + function next(signal_eof) { + var ch = S.text.charAt(S.pos++); + if (signal_eof && !ch) + throw EX_EOF; + if (ch == "\n") { + S.newline_before = true; + ++S.line; + S.col = 0; + } else { + ++S.col; + } + return ch; + }; + + function eof() { + return !S.peek(); + }; + + function find(what, signal_eof) { + var pos = S.text.indexOf(what, S.pos); + if (signal_eof && pos == -1) throw EX_EOF; + return pos; + }; + + function start_token() { + S.tokline = S.line; + S.tokcol = S.col; + S.tokpos = S.pos; + }; + + function token(type, value, is_comment) { + S.regex_allowed = ((type == "operator" && !HOP(UNARY_POSTFIX, value)) || + (type == "keyword" && HOP(KEYWORDS_BEFORE_EXPRESSION, value)) || + (type == "punc" && HOP(PUNC_BEFORE_EXPRESSION, value))); + var ret = { + type : type, + value : value, + line : S.tokline, + col : S.tokcol, + pos : S.tokpos, + nlb : S.newline_before + }; + if (!is_comment) { + ret.comments_before = S.comments_before; + S.comments_before = []; + } + S.newline_before = false; + return ret; + }; + + function skip_whitespace() { + while (HOP(WHITESPACE_CHARS, peek())) + next(); + }; + + function read_while(pred) { + var ret = "", ch = peek(), i = 0; + while (ch && pred(ch, i++)) { + ret += next(); + ch = peek(); + } + return ret; + }; + + function parse_error(err) { + js_error(err, S.tokline, S.tokcol, S.tokpos); + }; + + function read_num(prefix) { + var has_e = false, after_e = false, has_x = false, has_dot = prefix == "."; + var num = read_while(function(ch, i){ + if (ch == "x" || ch == "X") { + if (has_x) return false; + return has_x = true; + } + if (!has_x && (ch == "E" || ch == "e")) { + if (has_e) return false; + return has_e = after_e = true; + } + if (ch == "-") { + if (after_e || (i == 0 && !prefix)) return true; + return false; + } + if (ch == "+") return after_e; + after_e = false; + if (ch == ".") { + if (!has_dot && !has_x) + return has_dot = true; + return false; + } + return is_alphanumeric_char(ch); + }); + if (prefix) + num = prefix + num; + var valid = parse_js_number(num); + if (!isNaN(valid)) { + return token("num", valid); + } else { + parse_error("Invalid syntax: " + num); + } + }; + + function read_escaped_char() { + var ch = next(true); + switch (ch) { + case "n" : return "\n"; + case "r" : return "\r"; + case "t" : return "\t"; + case "b" : return "\b"; + case "v" : return "\v"; + case "f" : return "\f"; + case "0" : return "\0"; + case "x" : return String.fromCharCode(hex_bytes(2)); + case "u" : return String.fromCharCode(hex_bytes(4)); + default : return ch; + } + }; + + function hex_bytes(n) { + var num = 0; + for (; n > 0; --n) { + var digit = parseInt(next(true), 16); + if (isNaN(digit)) + parse_error("Invalid hex-character pattern in string"); + num = (num << 4) | digit; + } + return num; + }; + + function read_string() { + return with_eof_error("Unterminated string constant", function(){ + var quote = next(), ret = ""; + for (;;) { + var ch = next(true); + if (ch == "\\") ch = read_escaped_char(); + else if (ch == quote) break; + ret += ch; + } + return token("string", ret); + }); + }; + + function read_line_comment() { + next(); + var i = find("\n"), ret; + if (i == -1) { + ret = S.text.substr(S.pos); + S.pos = S.text.length; + } else { + ret = S.text.substring(S.pos, i); + S.pos = i; + } + return token("comment1", ret, true); + }; + + function read_multiline_comment() { + next(); + return with_eof_error("Unterminated multiline comment", function(){ + var i = find("*/", true), + text = S.text.substring(S.pos, i), + tok = token("comment2", text, true); + S.pos = i + 2; + S.line += text.split("\n").length - 1; + S.newline_before = text.indexOf("\n") >= 0; + + // https://github.com/mishoo/UglifyJS/issues/#issue/100 + if (/^@cc_on/i.test(text)) { + warn("WARNING: at line " + S.line); + warn("*** Found \"conditional comment\": " + text); + warn("*** UglifyJS DISCARDS ALL COMMENTS. This means your code might no longer work properly in Internet Explorer."); + } + + return tok; + }); + }; + + function read_name() { + var backslash = false, name = "", ch; + while ((ch = peek()) != null) { + if (!backslash) { + if (ch == "\\") backslash = true, next(); + else if (is_identifier_char(ch)) name += next(); + else break; + } + else { + if (ch != "u") parse_error("Expecting UnicodeEscapeSequence -- uXXXX"); + ch = read_escaped_char(); + if (!is_identifier_char(ch)) parse_error("Unicode char: " + ch.charCodeAt(0) + " is not valid in identifier"); + name += ch; + backslash = false; + } + } + return name; + }; + + function read_regexp() { + return with_eof_error("Unterminated regular expression", function(){ + var prev_backslash = false, regexp = "", ch, in_class = false; + while ((ch = next(true))) if (prev_backslash) { + regexp += "\\" + ch; + prev_backslash = false; + } else if (ch == "[") { + in_class = true; + regexp += ch; + } else if (ch == "]" && in_class) { + in_class = false; + regexp += ch; + } else if (ch == "/" && !in_class) { + break; + } else if (ch == "\\") { + prev_backslash = true; + } else { + regexp += ch; + } + var mods = read_name(); + return token("regexp", [ regexp, mods ]); + }); + }; + + function read_operator(prefix) { + function grow(op) { + if (!peek()) return op; + var bigger = op + peek(); + if (HOP(OPERATORS, bigger)) { + next(); + return grow(bigger); + } else { + return op; + } + }; + return token("operator", grow(prefix || next())); + }; + + function handle_slash() { + next(); + var regex_allowed = S.regex_allowed; + switch (peek()) { + case "/": + S.comments_before.push(read_line_comment()); + S.regex_allowed = regex_allowed; + return next_token(); + case "*": + S.comments_before.push(read_multiline_comment()); + S.regex_allowed = regex_allowed; + return next_token(); + } + return S.regex_allowed ? read_regexp() : read_operator("/"); + }; + + function handle_dot() { + next(); + return is_digit(peek()) + ? read_num(".") + : token("punc", "."); + }; + + function read_word() { + var word = read_name(); + return !HOP(KEYWORDS, word) + ? token("name", word) + : HOP(OPERATORS, word) + ? token("operator", word) + : HOP(KEYWORDS_ATOM, word) + ? token("atom", word) + : token("keyword", word); + }; + + function with_eof_error(eof_error, cont) { + try { + return cont(); + } catch(ex) { + if (ex === EX_EOF) parse_error(eof_error); + else throw ex; + } + }; + + function next_token(force_regexp) { + if (force_regexp) + return read_regexp(); + skip_whitespace(); + start_token(); + var ch = peek(); + if (!ch) return token("eof"); + if (is_digit(ch)) return read_num(); + if (ch == '"' || ch == "'") return read_string(); + if (HOP(PUNC_CHARS, ch)) return token("punc", next()); + if (ch == ".") return handle_dot(); + if (ch == "/") return handle_slash(); + if (HOP(OPERATOR_CHARS, ch)) return read_operator(); + if (ch == "\\" || is_identifier_start(ch)) return read_word(); + parse_error("Unexpected character '" + ch + "'"); + }; + + next_token.context = function(nc) { + if (nc) S = nc; + return S; + }; + + return next_token; + +}; + +/* -----[ Parser (constants) ]----- */ + +var UNARY_PREFIX = array_to_hash([ + "typeof", + "void", + "delete", + "--", + "++", + "!", + "~", + "-", + "+" +]); + +var UNARY_POSTFIX = array_to_hash([ "--", "++" ]); + +var ASSIGNMENT = (function(a, ret, i){ + while (i < a.length) { + ret[a[i]] = a[i].substr(0, a[i].length - 1); + i++; + } + return ret; +})( + ["+=", "-=", "/=", "*=", "%=", ">>=", "<<=", ">>>=", "|=", "^=", "&="], + { "=": true }, + 0 +); + +var PRECEDENCE = (function(a, ret){ + for (var i = 0, n = 1; i < a.length; ++i, ++n) { + var b = a[i]; + for (var j = 0; j < b.length; ++j) { + ret[b[j]] = n; + } + } + return ret; +})( + [ + ["||"], + ["&&"], + ["|"], + ["^"], + ["&"], + ["==", "===", "!=", "!=="], + ["<", ">", "<=", ">=", "in", "instanceof"], + [">>", "<<", ">>>"], + ["+", "-"], + ["*", "/", "%"] + ], + {} +); + +var STATEMENTS_WITH_LABELS = array_to_hash([ "for", "do", "while", "switch" ]); + +var ATOMIC_START_TOKEN = array_to_hash([ "atom", "num", "string", "regexp", "name" ]); + +/* -----[ Parser ]----- */ + +function NodeWithToken(str, start, end) { + this.name = str; + this.start = start; + this.end = end; +}; + +NodeWithToken.prototype.toString = function() { return this.name; }; + +function parse($TEXT, exigent_mode, embed_tokens) { + + var S = { + input : typeof $TEXT == "string" ? tokenizer($TEXT, true) : $TEXT, + token : null, + prev : null, + peeked : null, + in_function : 0, + in_loop : 0, + labels : [] + }; + + S.token = next(); + + function is(type, value) { + return is_token(S.token, type, value); + }; + + function peek() { return S.peeked || (S.peeked = S.input()); }; + + function next() { + S.prev = S.token; + if (S.peeked) { + S.token = S.peeked; + S.peeked = null; + } else { + S.token = S.input(); + } + return S.token; + }; + + function prev() { + return S.prev; + }; + + function croak(msg, line, col, pos) { + var ctx = S.input.context(); + js_error(msg, + line != null ? line : ctx.tokline, + col != null ? col : ctx.tokcol, + pos != null ? pos : ctx.tokpos); + }; + + function token_error(token, msg) { + croak(msg, token.line, token.col); + }; + + function unexpected(token) { + if (token == null) + token = S.token; + token_error(token, "Unexpected token: " + token.type + " (" + token.value + ")"); + }; + + function expect_token(type, val) { + if (is(type, val)) { + return next(); + } + token_error(S.token, "Unexpected token " + S.token.type + ", expected " + type); + }; + + function expect(punc) { return expect_token("punc", punc); }; + + function can_insert_semicolon() { + return !exigent_mode && ( + S.token.nlb || is("eof") || is("punc", "}") + ); + }; + + function semicolon() { + if (is("punc", ";")) next(); + else if (!can_insert_semicolon()) unexpected(); + }; + + function as() { + return slice(arguments); + }; + + function parenthesised() { + expect("("); + var ex = expression(); + expect(")"); + return ex; + }; + + function add_tokens(str, start, end) { + return str instanceof NodeWithToken ? str : new NodeWithToken(str, start, end); + }; + + function maybe_embed_tokens(parser) { + if (embed_tokens) return function() { + var start = S.token; + var ast = parser.apply(this, arguments); + ast[0] = add_tokens(ast[0], start, prev()); + return ast; + }; + else return parser; + }; + + var statement = maybe_embed_tokens(function() { + if (is("operator", "/")) { + S.peeked = null; + S.token = S.input(true); // force regexp + } + switch (S.token.type) { + case "num": + case "string": + case "regexp": + case "operator": + case "atom": + return simple_statement(); + + case "name": + return is_token(peek(), "punc", ":") + ? labeled_statement(prog1(S.token.value, next, next)) + : simple_statement(); + + case "punc": + switch (S.token.value) { + case "{": + return as("block", block_()); + case "[": + case "(": + return simple_statement(); + case ";": + next(); + return as("block"); + default: + unexpected(); + } + + case "keyword": + switch (prog1(S.token.value, next)) { + case "break": + return break_cont("break"); + + case "continue": + return break_cont("continue"); + + case "debugger": + semicolon(); + return as("debugger"); + + case "do": + return (function(body){ + expect_token("keyword", "while"); + return as("do", prog1(parenthesised, semicolon), body); + })(in_loop(statement)); + + case "for": + return for_(); + + case "function": + return function_(true); + + case "if": + return if_(); + + case "return": + if (S.in_function == 0) + croak("'return' outside of function"); + return as("return", + is("punc", ";") + ? (next(), null) + : can_insert_semicolon() + ? null + : prog1(expression, semicolon)); + + case "switch": + return as("switch", parenthesised(), switch_block_()); + + case "throw": + return as("throw", prog1(expression, semicolon)); + + case "try": + return try_(); + + case "var": + return prog1(var_, semicolon); + + case "const": + return prog1(const_, semicolon); + + case "while": + return as("while", parenthesised(), in_loop(statement)); + + case "with": + return as("with", parenthesised(), statement()); + + default: + unexpected(); + } + } + }); + + function labeled_statement(label) { + S.labels.push(label); + var start = S.token, stat = statement(); + if (exigent_mode && !HOP(STATEMENTS_WITH_LABELS, stat[0])) + unexpected(start); + S.labels.pop(); + return as("label", label, stat); + }; + + function simple_statement() { + return as("stat", prog1(expression, semicolon)); + }; + + function break_cont(type) { + var name = is("name") ? S.token.value : null; + if (name != null) { + next(); + if (!member(name, S.labels)) + croak("Label " + name + " without matching loop or statement"); + } + else if (S.in_loop == 0) + croak(type + " not inside a loop or switch"); + semicolon(); + return as(type, name); + }; + + function for_() { + expect("("); + var init = null; + if (!is("punc", ";")) { + init = is("keyword", "var") + ? (next(), var_(true)) + : expression(true, true); + if (is("operator", "in")) + return for_in(init); + } + return regular_for(init); + }; + + function regular_for(init) { + expect(";"); + var test = is("punc", ";") ? null : expression(); + expect(";"); + var step = is("punc", ")") ? null : expression(); + expect(")"); + return as("for", init, test, step, in_loop(statement)); + }; + + function for_in(init) { + var lhs = init[0] == "var" ? as("name", init[1][0]) : init; + next(); + var obj = expression(); + expect(")"); + return as("for-in", init, lhs, obj, in_loop(statement)); + }; + + var function_ = maybe_embed_tokens(function(in_statement) { + var name = is("name") ? prog1(S.token.value, next) : null; + if (in_statement && !name) + unexpected(); + expect("("); + return as(in_statement ? "defun" : "function", + name, + // arguments + (function(first, a){ + while (!is("punc", ")")) { + if (first) first = false; else expect(","); + if (!is("name")) unexpected(); + a.push(S.token.value); + next(); + } + next(); + return a; + })(true, []), + // body + (function(){ + ++S.in_function; + var loop = S.in_loop; + S.in_loop = 0; + var a = block_(); + --S.in_function; + S.in_loop = loop; + return a; + })()); + }); + + function if_() { + var cond = parenthesised(), body = statement(), belse; + if (is("keyword", "else")) { + next(); + belse = statement(); + } + return as("if", cond, body, belse); + }; + + function block_() { + expect("{"); + var a = []; + while (!is("punc", "}")) { + if (is("eof")) unexpected(); + a.push(statement()); + } + next(); + return a; + }; + + var switch_block_ = curry(in_loop, function(){ + expect("{"); + var a = [], cur = null; + while (!is("punc", "}")) { + if (is("eof")) unexpected(); + if (is("keyword", "case")) { + next(); + cur = []; + a.push([ expression(), cur ]); + expect(":"); + } + else if (is("keyword", "default")) { + next(); + expect(":"); + cur = []; + a.push([ null, cur ]); + } + else { + if (!cur) unexpected(); + cur.push(statement()); + } + } + next(); + return a; + }); + + function try_() { + var body = block_(), bcatch, bfinally; + if (is("keyword", "catch")) { + next(); + expect("("); + if (!is("name")) + croak("Name expected"); + var name = S.token.value; + next(); + expect(")"); + bcatch = [ name, block_() ]; + } + if (is("keyword", "finally")) { + next(); + bfinally = block_(); + } + if (!bcatch && !bfinally) + croak("Missing catch/finally blocks"); + return as("try", body, bcatch, bfinally); + }; + + function vardefs(no_in) { + var a = []; + for (;;) { + if (!is("name")) + unexpected(); + var name = S.token.value; + next(); + if (is("operator", "=")) { + next(); + a.push([ name, expression(false, no_in) ]); + } else { + a.push([ name ]); + } + if (!is("punc", ",")) + break; + next(); + } + return a; + }; + + function var_(no_in) { + return as("var", vardefs(no_in)); + }; + + function const_() { + return as("const", vardefs()); + }; + + function new_() { + var newexp = expr_atom(false), args; + if (is("punc", "(")) { + next(); + args = expr_list(")"); + } else { + args = []; + } + return subscripts(as("new", newexp, args), true); + }; + + var expr_atom = maybe_embed_tokens(function(allow_calls) { + if (is("operator", "new")) { + next(); + return new_(); + } + if (is("operator") && HOP(UNARY_PREFIX, S.token.value)) { + return make_unary("unary-prefix", + prog1(S.token.value, next), + expr_atom(allow_calls)); + } + if (is("punc")) { + switch (S.token.value) { + case "(": + next(); + return subscripts(prog1(expression, curry(expect, ")")), allow_calls); + case "[": + next(); + return subscripts(array_(), allow_calls); + case "{": + next(); + return subscripts(object_(), allow_calls); + } + unexpected(); + } + if (is("keyword", "function")) { + next(); + return subscripts(function_(false), allow_calls); + } + if (HOP(ATOMIC_START_TOKEN, S.token.type)) { + var atom = S.token.type == "regexp" + ? as("regexp", S.token.value[0], S.token.value[1]) + : as(S.token.type, S.token.value); + return subscripts(prog1(atom, next), allow_calls); + } + unexpected(); + }); + + function expr_list(closing, allow_trailing_comma, allow_empty) { + var first = true, a = []; + while (!is("punc", closing)) { + if (first) first = false; else expect(","); + if (allow_trailing_comma && is("punc", closing)) break; + if (is("punc", ",") && allow_empty) { + a.push([ "atom", "undefined" ]); + } else { + a.push(expression(false)); + } + } + next(); + return a; + }; + + function array_() { + return as("array", expr_list("]", !exigent_mode, true)); + }; + + function object_() { + var first = true, a = []; + while (!is("punc", "}")) { + if (first) first = false; else expect(","); + if (!exigent_mode && is("punc", "}")) + // allow trailing comma + break; + var type = S.token.type; + var name = as_property_name(); + if (type == "name" && (name == "get" || name == "set") && !is("punc", ":")) { + a.push([ as_name(), function_(false), name ]); + } else { + expect(":"); + a.push([ name, expression(false) ]); + } + } + next(); + return as("object", a); + }; + + function as_property_name() { + switch (S.token.type) { + case "num": + case "string": + return prog1(S.token.value, next); + } + return as_name(); + }; + + function as_name() { + switch (S.token.type) { + case "name": + case "operator": + case "keyword": + case "atom": + return prog1(S.token.value, next); + default: + unexpected(); + } + }; + + function subscripts(expr, allow_calls) { + if (is("punc", ".")) { + next(); + return subscripts(as("dot", expr, as_name()), allow_calls); + } + if (is("punc", "[")) { + next(); + return subscripts(as("sub", expr, prog1(expression, curry(expect, "]"))), allow_calls); + } + if (allow_calls && is("punc", "(")) { + next(); + return subscripts(as("call", expr, expr_list(")")), true); + } + if (allow_calls && is("operator") && HOP(UNARY_POSTFIX, S.token.value)) { + return prog1(curry(make_unary, "unary-postfix", S.token.value, expr), + next); + } + return expr; + }; + + function make_unary(tag, op, expr) { + if ((op == "++" || op == "--") && !is_assignable(expr)) + croak("Invalid use of " + op + " operator"); + return as(tag, op, expr); + }; + + function expr_op(left, min_prec, no_in) { + var op = is("operator") ? S.token.value : null; + if (op && op == "in" && no_in) op = null; + var prec = op != null ? PRECEDENCE[op] : null; + if (prec != null && prec > min_prec) { + next(); + var right = expr_op(expr_atom(true), prec, no_in); + return expr_op(as("binary", op, left, right), min_prec, no_in); + } + return left; + }; + + function expr_ops(no_in) { + return expr_op(expr_atom(true), 0, no_in); + }; + + function maybe_conditional(no_in) { + var expr = expr_ops(no_in); + if (is("operator", "?")) { + next(); + var yes = expression(false); + expect(":"); + return as("conditional", expr, yes, expression(false, no_in)); + } + return expr; + }; + + function is_assignable(expr) { + if (!exigent_mode) return true; + switch (expr[0]) { + case "dot": + case "sub": + case "new": + case "call": + return true; + case "name": + return expr[1] != "this"; + } + }; + + function maybe_assign(no_in) { + var left = maybe_conditional(no_in), val = S.token.value; + if (is("operator") && HOP(ASSIGNMENT, val)) { + if (is_assignable(left)) { + next(); + return as("assign", ASSIGNMENT[val], left, maybe_assign(no_in)); + } + croak("Invalid assignment"); + } + return left; + }; + + var expression = maybe_embed_tokens(function(commas, no_in) { + if (arguments.length == 0) + commas = true; + var expr = maybe_assign(no_in); + if (commas && is("punc", ",")) { + next(); + return as("seq", expr, expression(true, no_in)); + } + return expr; + }); + + function in_loop(cont) { + try { + ++S.in_loop; + return cont(); + } finally { + --S.in_loop; + } + }; + + return as("toplevel", (function(a){ + while (!is("eof")) + a.push(statement()); + return a; + })([])); + +}; + +/* -----[ Utilities ]----- */ + +function curry(f) { + var args = slice(arguments, 1); + return function() { return f.apply(this, args.concat(slice(arguments))); }; +}; + +function prog1(ret) { + if (ret instanceof Function) + ret = ret(); + for (var i = 1, n = arguments.length; --n > 0; ++i) + arguments[i](); + return ret; +}; + +function array_to_hash(a) { + var ret = {}; + for (var i = 0; i < a.length; ++i) + ret[a[i]] = true; + return ret; +}; + +function slice(a, start) { + return Array.prototype.slice.call(a, start == null ? 0 : start); +}; + +function characters(str) { + return str.split(""); +}; + +function member(name, array) { + for (var i = array.length; --i >= 0;) + if (array[i] === name) + return true; + return false; +}; + +function HOP(obj, prop) { + return Object.prototype.hasOwnProperty.call(obj, prop); +}; + +var warn = function() {}; + +/* -----[ Exports ]----- */ + +exports.tokenizer = tokenizer; +exports.parse = parse; +exports.slice = slice; +exports.curry = curry; +exports.member = member; +exports.array_to_hash = array_to_hash; +exports.PRECEDENCE = PRECEDENCE; +exports.KEYWORDS_ATOM = KEYWORDS_ATOM; +exports.RESERVED_WORDS = RESERVED_WORDS; +exports.KEYWORDS = KEYWORDS; +exports.ATOMIC_START_TOKEN = ATOMIC_START_TOKEN; +exports.OPERATORS = OPERATORS; +exports.is_alphanumeric_char = is_alphanumeric_char; +exports.set_logger = function(logger) { + warn = logger; +}; diff --git a/build/lib/process.js b/build/lib/process.js new file mode 100644 index 0000000..3878c8d --- /dev/null +++ b/build/lib/process.js @@ -0,0 +1,1666 @@ +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + + This version is suitable for Node.js. With minimal changes (the + exports stuff) it should work on any JS platform. + + This file implements some AST processors. They work on data built + by parse-js. + + Exported functions: + + - ast_mangle(ast, options) -- mangles the variable/function names + in the AST. Returns an AST. + + - ast_squeeze(ast) -- employs various optimizations to make the + final generated code even smaller. Returns an AST. + + - gen_code(ast, options) -- generates JS code from the AST. Pass + true (or an object, see the code for some options) as second + argument to get "pretty" (indented) code. + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2010 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + + ***********************************************************************/ + +var jsp = require("./parse-js"), + slice = jsp.slice, + member = jsp.member, + PRECEDENCE = jsp.PRECEDENCE, + OPERATORS = jsp.OPERATORS; + +/* -----[ helper for AST traversal ]----- */ + +function ast_walker(ast) { + function _vardefs(defs) { + return [ this[0], MAP(defs, function(def){ + var a = [ def[0] ]; + if (def.length > 1) + a[1] = walk(def[1]); + return a; + }) ]; + }; + function _block(statements) { + var out = [ this[0] ]; + if (statements != null) + out.push(MAP(statements, walk)); + return out; + }; + var walkers = { + "string": function(str) { + return [ this[0], str ]; + }, + "num": function(num) { + return [ this[0], num ]; + }, + "name": function(name) { + return [ this[0], name ]; + }, + "toplevel": function(statements) { + return [ this[0], MAP(statements, walk) ]; + }, + "block": _block, + "splice": _block, + "var": _vardefs, + "const": _vardefs, + "try": function(t, c, f) { + return [ + this[0], + MAP(t, walk), + c != null ? [ c[0], MAP(c[1], walk) ] : null, + f != null ? MAP(f, walk) : null + ]; + }, + "throw": function(expr) { + return [ this[0], walk(expr) ]; + }, + "new": function(ctor, args) { + return [ this[0], walk(ctor), MAP(args, walk) ]; + }, + "switch": function(expr, body) { + return [ this[0], walk(expr), MAP(body, function(branch){ + return [ branch[0] ? walk(branch[0]) : null, + MAP(branch[1], walk) ]; + }) ]; + }, + "break": function(label) { + return [ this[0], label ]; + }, + "continue": function(label) { + return [ this[0], label ]; + }, + "conditional": function(cond, t, e) { + return [ this[0], walk(cond), walk(t), walk(e) ]; + }, + "assign": function(op, lvalue, rvalue) { + return [ this[0], op, walk(lvalue), walk(rvalue) ]; + }, + "dot": function(expr) { + return [ this[0], walk(expr) ].concat(slice(arguments, 1)); + }, + "call": function(expr, args) { + return [ this[0], walk(expr), MAP(args, walk) ]; + }, + "function": function(name, args, body) { + return [ this[0], name, args.slice(), MAP(body, walk) ]; + }, + "defun": function(name, args, body) { + return [ this[0], name, args.slice(), MAP(body, walk) ]; + }, + "if": function(conditional, t, e) { + return [ this[0], walk(conditional), walk(t), walk(e) ]; + }, + "for": function(init, cond, step, block) { + return [ this[0], walk(init), walk(cond), walk(step), walk(block) ]; + }, + "for-in": function(vvar, key, hash, block) { + return [ this[0], walk(vvar), walk(key), walk(hash), walk(block) ]; + }, + "while": function(cond, block) { + return [ this[0], walk(cond), walk(block) ]; + }, + "do": function(cond, block) { + return [ this[0], walk(cond), walk(block) ]; + }, + "return": function(expr) { + return [ this[0], walk(expr) ]; + }, + "binary": function(op, left, right) { + return [ this[0], op, walk(left), walk(right) ]; + }, + "unary-prefix": function(op, expr) { + return [ this[0], op, walk(expr) ]; + }, + "unary-postfix": function(op, expr) { + return [ this[0], op, walk(expr) ]; + }, + "sub": function(expr, subscript) { + return [ this[0], walk(expr), walk(subscript) ]; + }, + "object": function(props) { + return [ this[0], MAP(props, function(p){ + return p.length == 2 + ? [ p[0], walk(p[1]) ] + : [ p[0], walk(p[1]), p[2] ]; // get/set-ter + }) ]; + }, + "regexp": function(rx, mods) { + return [ this[0], rx, mods ]; + }, + "array": function(elements) { + return [ this[0], MAP(elements, walk) ]; + }, + "stat": function(stat) { + return [ this[0], walk(stat) ]; + }, + "seq": function() { + return [ this[0] ].concat(MAP(slice(arguments), walk)); + }, + "label": function(name, block) { + return [ this[0], name, walk(block) ]; + }, + "with": function(expr, block) { + return [ this[0], walk(expr), walk(block) ]; + }, + "atom": function(name) { + return [ this[0], name ]; + } + }; + + var user = {}; + var stack = []; + function walk(ast) { + if (ast == null) + return null; + try { + stack.push(ast); + var type = ast[0]; + var gen = user[type]; + if (gen) { + var ret = gen.apply(ast, ast.slice(1)); + if (ret != null) + return ret; + } + gen = walkers[type]; + return gen.apply(ast, ast.slice(1)); + } finally { + stack.pop(); + } + }; + + function with_walkers(walkers, cont){ + var save = {}, i; + for (i in walkers) if (HOP(walkers, i)) { + save[i] = user[i]; + user[i] = walkers[i]; + } + var ret = cont(); + for (i in save) if (HOP(save, i)) { + if (!save[i]) delete user[i]; + else user[i] = save[i]; + } + return ret; + }; + + return { + walk: walk, + with_walkers: with_walkers, + parent: function() { + return stack[stack.length - 2]; // last one is current node + }, + stack: function() { + return stack; + } + }; +}; + +/* -----[ Scope and mangling ]----- */ + +function Scope(parent) { + this.names = {}; // names defined in this scope + this.mangled = {}; // mangled names (orig.name => mangled) + this.rev_mangled = {}; // reverse lookup (mangled => orig.name) + this.cname = -1; // current mangled name + this.refs = {}; // names referenced from this scope + this.uses_with = false; // will become TRUE if with() is detected in this or any subscopes + this.uses_eval = false; // will become TRUE if eval() is detected in this or any subscopes + this.parent = parent; // parent scope + this.children = []; // sub-scopes + if (parent) { + this.level = parent.level + 1; + parent.children.push(this); + } else { + this.level = 0; + } +}; + +var base54 = (function(){ + var DIGITS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_"; + return function(num) { + var ret = ""; + do { + ret = DIGITS.charAt(num % 54) + ret; + num = Math.floor(num / 54); + } while (num > 0); + return ret; + }; +})(); + +Scope.prototype = { + has: function(name) { + for (var s = this; s; s = s.parent) + if (HOP(s.names, name)) + return s; + }, + has_mangled: function(mname) { + for (var s = this; s; s = s.parent) + if (HOP(s.rev_mangled, mname)) + return s; + }, + toJSON: function() { + return { + names: this.names, + uses_eval: this.uses_eval, + uses_with: this.uses_with + }; + }, + + next_mangled: function() { + // we must be careful that the new mangled name: + // + // 1. doesn't shadow a mangled name from a parent + // scope, unless we don't reference the original + // name from this scope OR from any sub-scopes! + // This will get slow. + // + // 2. doesn't shadow an original name from a parent + // scope, in the event that the name is not mangled + // in the parent scope and we reference that name + // here OR IN ANY SUBSCOPES! + // + // 3. doesn't shadow a name that is referenced but not + // defined (possibly global defined elsewhere). + for (;;) { + var m = base54(++this.cname), prior; + + // case 1. + prior = this.has_mangled(m); + if (prior && this.refs[prior.rev_mangled[m]] === prior) + continue; + + // case 2. + prior = this.has(m); + if (prior && prior !== this && this.refs[m] === prior && !prior.has_mangled(m)) + continue; + + // case 3. + if (HOP(this.refs, m) && this.refs[m] == null) + continue; + + // I got "do" once. :-/ + if (!is_identifier(m)) + continue; + + return m; + } + }, + get_mangled: function(name, newMangle) { + if (this.uses_eval || this.uses_with) return name; // no mangle if eval or with is in use + var s = this.has(name); + if (!s) return name; // not in visible scope, no mangle + if (HOP(s.mangled, name)) return s.mangled[name]; // already mangled in this scope + if (!newMangle) return name; // not found and no mangling requested + + var m = s.next_mangled(); + s.rev_mangled[m] = name; + return s.mangled[name] = m; + }, + define: function(name) { + if (name != null) + return this.names[name] = name; + } +}; + +function ast_add_scope(ast) { + + var current_scope = null; + var w = ast_walker(), walk = w.walk; + var having_eval = []; + + function with_new_scope(cont) { + current_scope = new Scope(current_scope); + var ret = current_scope.body = cont(); + ret.scope = current_scope; + current_scope = current_scope.parent; + return ret; + }; + + function define(name) { + return current_scope.define(name); + }; + + function reference(name) { + current_scope.refs[name] = true; + }; + + function _lambda(name, args, body) { + var is_defun = this[0] == "defun"; + return [ this[0], is_defun ? define(name) : name, args, with_new_scope(function(){ + if (!is_defun) define(name); + MAP(args, define); + return MAP(body, walk); + })]; + }; + + return with_new_scope(function(){ + // process AST + var ret = w.with_walkers({ + "function": _lambda, + "defun": _lambda, + "with": function(expr, block) { + for (var s = current_scope; s; s = s.parent) + s.uses_with = true; + }, + "var": function(defs) { + MAP(defs, function(d){ define(d[0]) }); + }, + "const": function(defs) { + MAP(defs, function(d){ define(d[0]) }); + }, + "try": function(t, c, f) { + if (c != null) return [ + this[0], + MAP(t, walk), + [ define(c[0]), MAP(c[1], walk) ], + f != null ? MAP(f, walk) : null + ]; + }, + "name": function(name) { + if (name == "eval") + having_eval.push(current_scope); + reference(name); + } + }, function(){ + return walk(ast); + }); + + // the reason why we need an additional pass here is + // that names can be used prior to their definition. + + // scopes where eval was detected and their parents + // are marked with uses_eval, unless they define the + // "eval" name. + MAP(having_eval, function(scope){ + if (!scope.has("eval")) while (scope) { + scope.uses_eval = true; + scope = scope.parent; + } + }); + + // for referenced names it might be useful to know + // their origin scope. current_scope here is the + // toplevel one. + function fixrefs(scope, i) { + // do children first; order shouldn't matter + for (i = scope.children.length; --i >= 0;) + fixrefs(scope.children[i]); + for (i in scope.refs) if (HOP(scope.refs, i)) { + // find origin scope and propagate the reference to origin + for (var origin = scope.has(i), s = scope; s; s = s.parent) { + s.refs[i] = origin; + if (s === origin) break; + } + } + }; + fixrefs(current_scope); + + return ret; + }); + +}; + +/* -----[ mangle names ]----- */ + +function ast_mangle(ast, options) { + var w = ast_walker(), walk = w.walk, scope; + options = options || {}; + + function get_mangled(name, newMangle) { + if (!options.toplevel && !scope.parent) return name; // don't mangle toplevel + if (options.except && member(name, options.except)) + return name; + return scope.get_mangled(name, newMangle); + }; + + function get_define(name) { + // we always lookup a defined symbol for the current scope FIRST, so declared + // vars trump a DEFINE symbol, but if no such var is found, then match a DEFINE value + if (!scope.has(name)) { + if (HOP(options.defines, name)) { + return options.defines[name]; + } + } + return null; + }; + + function _lambda(name, args, body) { + var is_defun = this[0] == "defun"; + if (is_defun && name) name = get_mangled(name); + body = with_scope(body.scope, function(){ + if (!is_defun && name) name = get_mangled(name); + args = MAP(args, function(name){ return get_mangled(name) }); + return MAP(body, walk); + }); + return [ this[0], name, args, body ]; + }; + + function with_scope(s, cont) { + var _scope = scope; + scope = s; + for (var i in s.names) if (HOP(s.names, i)) { + get_mangled(i, true); + } + var ret = cont(); + ret.scope = s; + scope = _scope; + return ret; + }; + + function _vardefs(defs) { + return [ this[0], MAP(defs, function(d){ + return [ get_mangled(d[0]), walk(d[1]) ]; + }) ]; + }; + + return w.with_walkers({ + "function": _lambda, + "defun": function() { + // move function declarations to the top when + // they are not in some block. + var ast = _lambda.apply(this, arguments); + switch (w.parent()[0]) { + case "toplevel": + case "function": + case "defun": + return MAP.at_top(ast); + } + return ast; + }, + "var": _vardefs, + "const": _vardefs, + "name": function(name) { + return get_define(name) || [ this[0], get_mangled(name) ]; + }, + "try": function(t, c, f) { + return [ this[0], + MAP(t, walk), + c != null ? [ get_mangled(c[0]), MAP(c[1], walk) ] : null, + f != null ? MAP(f, walk) : null ]; + }, + "toplevel": function(body) { + var self = this; + return with_scope(self.scope, function(){ + return [ self[0], MAP(body, walk) ]; + }); + } + }, function() { + return walk(ast_add_scope(ast)); + }); +}; + +/* -----[ + - compress foo["bar"] into foo.bar, + - remove block brackets {} where possible + - join consecutive var declarations + - various optimizations for IFs: + - if (cond) foo(); else bar(); ==> cond?foo():bar(); + - if (cond) foo(); ==> cond&&foo(); + - if (foo) return bar(); else return baz(); ==> return foo?bar():baz(); // also for throw + - if (foo) return bar(); else something(); ==> {if(foo)return bar();something()} + ]----- */ + +var warn = function(){}; + +function best_of(ast1, ast2) { + return gen_code(ast1).length > gen_code(ast2[0] == "stat" ? ast2[1] : ast2).length ? ast2 : ast1; +}; + +function last_stat(b) { + if (b[0] == "block" && b[1] && b[1].length > 0) + return b[1][b[1].length - 1]; + return b; +} + +function aborts(t) { + if (t) { + t = last_stat(t); + if (t[0] == "return" || t[0] == "break" || t[0] == "continue" || t[0] == "throw") + return true; + } +}; + +function boolean_expr(expr) { + return ( (expr[0] == "unary-prefix" + && member(expr[1], [ "!", "delete" ])) || + + (expr[0] == "binary" + && member(expr[1], [ "in", "instanceof", "==", "!=", "===", "!==", "<", "<=", ">=", ">" ])) || + + (expr[0] == "binary" + && member(expr[1], [ "&&", "||" ]) + && boolean_expr(expr[2]) + && boolean_expr(expr[3])) || + + (expr[0] == "conditional" + && boolean_expr(expr[2]) + && boolean_expr(expr[3])) || + + (expr[0] == "assign" + && expr[1] === true + && boolean_expr(expr[3])) || + + (expr[0] == "seq" + && boolean_expr(expr[expr.length - 1])) + ); +}; + +function make_conditional(c, t, e) { + var make_real_conditional = function() { + if (c[0] == "unary-prefix" && c[1] == "!") { + return e ? [ "conditional", c[2], e, t ] : [ "binary", "||", c[2], t ]; + } else { + return e ? [ "conditional", c, t, e ] : [ "binary", "&&", c, t ]; + } + }; + // shortcut the conditional if the expression has a constant value + return when_constant(c, function(ast, val){ + warn_unreachable(val ? e : t); + return (val ? t : e); + }, make_real_conditional); +}; + +function empty(b) { + return !b || (b[0] == "block" && (!b[1] || b[1].length == 0)); +}; + +function is_string(node) { + return (node[0] == "string" || + node[0] == "unary-prefix" && node[1] == "typeof" || + node[0] == "binary" && node[1] == "+" && + (is_string(node[2]) || is_string(node[3]))); +}; + +var when_constant = (function(){ + + var $NOT_CONSTANT = {}; + + // this can only evaluate constant expressions. If it finds anything + // not constant, it throws $NOT_CONSTANT. + function evaluate(expr) { + switch (expr[0]) { + case "string": + case "num": + return expr[1]; + case "name": + case "atom": + switch (expr[1]) { + case "true": return true; + case "false": return false; + } + break; + case "unary-prefix": + switch (expr[1]) { + case "!": return !evaluate(expr[2]); + case "typeof": return typeof evaluate(expr[2]); + case "~": return ~evaluate(expr[2]); + case "-": return -evaluate(expr[2]); + case "+": return +evaluate(expr[2]); + } + break; + case "binary": + var left = expr[2], right = expr[3]; + switch (expr[1]) { + case "&&" : return evaluate(left) && evaluate(right); + case "||" : return evaluate(left) || evaluate(right); + case "|" : return evaluate(left) | evaluate(right); + case "&" : return evaluate(left) & evaluate(right); + case "^" : return evaluate(left) ^ evaluate(right); + case "+" : return evaluate(left) + evaluate(right); + case "*" : return evaluate(left) * evaluate(right); + case "/" : return evaluate(left) / evaluate(right); + case "-" : return evaluate(left) - evaluate(right); + case "<<" : return evaluate(left) << evaluate(right); + case ">>" : return evaluate(left) >> evaluate(right); + case ">>>" : return evaluate(left) >>> evaluate(right); + case "==" : return evaluate(left) == evaluate(right); + case "===" : return evaluate(left) === evaluate(right); + case "!=" : return evaluate(left) != evaluate(right); + case "!==" : return evaluate(left) !== evaluate(right); + case "<" : return evaluate(left) < evaluate(right); + case "<=" : return evaluate(left) <= evaluate(right); + case ">" : return evaluate(left) > evaluate(right); + case ">=" : return evaluate(left) >= evaluate(right); + case "in" : return evaluate(left) in evaluate(right); + case "instanceof" : return evaluate(left) instanceof evaluate(right); + } + } + throw $NOT_CONSTANT; + }; + + return function(expr, yes, no) { + try { + var val = evaluate(expr), ast; + switch (typeof val) { + case "string": ast = [ "string", val ]; break; + case "number": ast = [ "num", val ]; break; + case "boolean": ast = [ "name", String(val) ]; break; + default: throw new Error("Can't handle constant of type: " + (typeof val)); + } + return yes.call(expr, ast, val); + } catch(ex) { + if (ex === $NOT_CONSTANT) { + if (expr[0] == "binary" + && (expr[1] == "===" || expr[1] == "!==") + && ((is_string(expr[2]) && is_string(expr[3])) + || (boolean_expr(expr[2]) && boolean_expr(expr[3])))) { + expr[1] = expr[1].substr(0, 2); + } + else if (no && expr[0] == "binary" + && (expr[1] == "||" || expr[1] == "&&")) { + // the whole expression is not constant but the lval may be... + try { + var lval = evaluate(expr[2]); + expr = ((expr[1] == "&&" && (lval ? expr[3] : lval)) || + (expr[1] == "||" && (lval ? lval : expr[3])) || + expr); + } catch(ex2) { + // IGNORE... lval is not constant + } + } + return no ? no.call(expr, expr) : null; + } + else throw ex; + } + }; + +})(); + +function warn_unreachable(ast) { + if (!empty(ast)) + warn("Dropping unreachable code: " + gen_code(ast, true)); +}; + +function ast_squeeze(ast, options) { + options = defaults(options, { + make_seqs : true, + dead_code : true, + keep_comps : true, + no_warnings : false + }); + + var w = ast_walker(), walk = w.walk, scope; + + function negate(c) { + var not_c = [ "unary-prefix", "!", c ]; + switch (c[0]) { + case "unary-prefix": + return c[1] == "!" && boolean_expr(c[2]) ? c[2] : not_c; + case "seq": + c = slice(c); + c[c.length - 1] = negate(c[c.length - 1]); + return c; + case "conditional": + return best_of(not_c, [ "conditional", c[1], negate(c[2]), negate(c[3]) ]); + case "binary": + var op = c[1], left = c[2], right = c[3]; + if (!options.keep_comps) switch (op) { + case "<=" : return [ "binary", ">", left, right ]; + case "<" : return [ "binary", ">=", left, right ]; + case ">=" : return [ "binary", "<", left, right ]; + case ">" : return [ "binary", "<=", left, right ]; + } + switch (op) { + case "==" : return [ "binary", "!=", left, right ]; + case "!=" : return [ "binary", "==", left, right ]; + case "===" : return [ "binary", "!==", left, right ]; + case "!==" : return [ "binary", "===", left, right ]; + case "&&" : return best_of(not_c, [ "binary", "||", negate(left), negate(right) ]); + case "||" : return best_of(not_c, [ "binary", "&&", negate(left), negate(right) ]); + } + break; + } + return not_c; + }; + + function with_scope(s, cont) { + var _scope = scope; + scope = s; + var ret = cont(); + ret.scope = s; + scope = _scope; + return ret; + }; + + function rmblock(block) { + if (block != null && block[0] == "block" && block[1]) { + if (block[1].length == 1) + block = block[1][0]; + else if (block[1].length == 0) + block = [ "block" ]; + } + return block; + }; + + function _lambda(name, args, body) { + var is_defun = this[0] == "defun"; + body = with_scope(body.scope, function(){ + var ret = tighten(MAP(body, walk), "lambda"); + if (!is_defun && name && !HOP(scope.refs, name)) + name = null; + return ret; + }); + return [ this[0], name, args, body ]; + }; + + // we get here for blocks that have been already transformed. + // this function does a few things: + // 1. discard useless blocks + // 2. join consecutive var declarations + // 3. remove obviously dead code + // 4. transform consecutive statements using the comma operator + // 5. if block_type == "lambda" and it detects constructs like if(foo) return ... - rewrite like if (!foo) { ... } + function tighten(statements, block_type) { + statements = statements.reduce(function(a, stat){ + if (stat[0] == "block") { + if (stat[1]) { + a.push.apply(a, stat[1]); + } + } else { + a.push(stat); + } + return a; + }, []); + + statements = (function(a, prev){ + statements.forEach(function(cur){ + if (prev && ((cur[0] == "var" && prev[0] == "var") || + (cur[0] == "const" && prev[0] == "const"))) { + prev[1] = prev[1].concat(cur[1]); + } else { + a.push(cur); + prev = cur; + } + }); + return a; + })([]); + + if (options.dead_code) statements = (function(a, has_quit){ + statements.forEach(function(st){ + if (has_quit) { + if (member(st[0], [ "function", "defun" , "var", "const" ])) { + a.push(st); + } + else if (!options.no_warnings) + warn_unreachable(st); + } + else { + a.push(st); + if (member(st[0], [ "return", "throw", "break", "continue" ])) + has_quit = true; + } + }); + return a; + })([]); + + if (options.make_seqs) statements = (function(a, prev) { + statements.forEach(function(cur){ + if (prev && prev[0] == "stat" && cur[0] == "stat") { + prev[1] = [ "seq", prev[1], cur[1] ]; + } else { + a.push(cur); + prev = cur; + } + }); + return a; + })([]); + + if (block_type == "lambda") statements = (function(i, a, stat){ + while (i < statements.length) { + stat = statements[i++]; + if (stat[0] == "if" && !stat[3]) { + if (stat[2][0] == "return" && stat[2][1] == null) { + a.push(make_if(negate(stat[1]), [ "block", statements.slice(i) ])); + break; + } + var last = last_stat(stat[2]); + if (last[0] == "return" && last[1] == null) { + a.push(make_if(stat[1], [ "block", stat[2][1].slice(0, -1) ], [ "block", statements.slice(i) ])); + break; + } + } + a.push(stat); + } + return a; + })(0, []); + + return statements; + }; + + function make_if(c, t, e) { + return when_constant(c, function(ast, val){ + if (val) { + warn_unreachable(e); + return t; + } else { + warn_unreachable(t); + return e; + } + }, function() { + return make_real_if(c, t, e); + }); + }; + + function make_real_if(c, t, e) { + c = walk(c); + t = walk(t); + e = walk(e); + + if (empty(t)) { + c = negate(c); + t = e; + e = null; + } else if (empty(e)) { + e = null; + } else { + // if we have both else and then, maybe it makes sense to switch them? + (function(){ + var a = gen_code(c); + var n = negate(c); + var b = gen_code(n); + if (b.length < a.length) { + var tmp = t; + t = e; + e = tmp; + c = n; + } + })(); + } + if (empty(e) && empty(t)) + return [ "stat", c ]; + var ret = [ "if", c, t, e ]; + if (t[0] == "if" && empty(t[3]) && empty(e)) { + ret = best_of(ret, walk([ "if", [ "binary", "&&", c, t[1] ], t[2] ])); + } + else if (t[0] == "stat") { + if (e) { + if (e[0] == "stat") { + ret = best_of(ret, [ "stat", make_conditional(c, t[1], e[1]) ]); + } + } + else { + ret = best_of(ret, [ "stat", make_conditional(c, t[1]) ]); + } + } + else if (e && t[0] == e[0] && (t[0] == "return" || t[0] == "throw") && t[1] && e[1]) { + ret = best_of(ret, [ t[0], make_conditional(c, t[1], e[1] ) ]); + } + else if (e && aborts(t)) { + ret = [ [ "if", c, t ] ]; + if (e[0] == "block") { + if (e[1]) ret = ret.concat(e[1]); + } + else { + ret.push(e); + } + ret = walk([ "block", ret ]); + } + else if (t && aborts(e)) { + ret = [ [ "if", negate(c), e ] ]; + if (t[0] == "block") { + if (t[1]) ret = ret.concat(t[1]); + } else { + ret.push(t); + } + ret = walk([ "block", ret ]); + } + return ret; + }; + + function _do_while(cond, body) { + return when_constant(cond, function(cond, val){ + if (!val) { + warn_unreachable(body); + return [ "block" ]; + } else { + return [ "for", null, null, null, walk(body) ]; + } + }); + }; + + return w.with_walkers({ + "sub": function(expr, subscript) { + if (subscript[0] == "string") { + var name = subscript[1]; + if (is_identifier(name)) + return [ "dot", walk(expr), name ]; + else if (/^[1-9][0-9]*$/.test(name) || name === "0") + return [ "sub", walk(expr), [ "num", parseInt(name, 10) ] ]; + } + }, + "if": make_if, + "toplevel": function(body) { + return [ "toplevel", with_scope(this.scope, function(){ + return tighten(MAP(body, walk)); + }) ]; + }, + "switch": function(expr, body) { + var last = body.length - 1; + return [ "switch", walk(expr), MAP(body, function(branch, i){ + var block = tighten(MAP(branch[1], walk)); + if (i == last && block.length > 0) { + var node = block[block.length - 1]; + if (node[0] == "break" && !node[1]) + block.pop(); + } + return [ branch[0] ? walk(branch[0]) : null, block ]; + }) ]; + }, + "function": _lambda, + "defun": _lambda, + "block": function(body) { + if (body) return rmblock([ "block", tighten(MAP(body, walk)) ]); + }, + "binary": function(op, left, right) { + return when_constant([ "binary", op, walk(left), walk(right) ], function yes(c){ + return best_of(walk(c), this); + }, function no() { + return this; + }); + }, + "conditional": function(c, t, e) { + return make_conditional(walk(c), walk(t), walk(e)); + }, + "try": function(t, c, f) { + return [ + "try", + tighten(MAP(t, walk)), + c != null ? [ c[0], tighten(MAP(c[1], walk)) ] : null, + f != null ? tighten(MAP(f, walk)) : null + ]; + }, + "unary-prefix": function(op, expr) { + expr = walk(expr); + var ret = [ "unary-prefix", op, expr ]; + if (op == "!") + ret = best_of(ret, negate(expr)); + return when_constant(ret, function(ast, val){ + return walk(ast); // it's either true or false, so minifies to !0 or !1 + }, function() { return ret }); + }, + "name": function(name) { + switch (name) { + case "true": return [ "unary-prefix", "!", [ "num", 0 ]]; + case "false": return [ "unary-prefix", "!", [ "num", 1 ]]; + } + }, + "new": function(ctor, args) { + if (ctor[0] == "name" && ctor[1] == "Array" && !scope.has("Array")) { + if (args.length != 1) { + return [ "array", args ]; + } else { + return [ "call", [ "name", "Array" ], args ]; + } + } + }, + "call": function(expr, args) { + if (expr[0] == "name" && expr[1] == "Array" && args.length != 1 && !scope.has("Array")) { + return [ "array", args ]; + } + }, + "while": _do_while, + "do": _do_while + }, function() { + return walk(ast_add_scope(ast)); + }); +}; + +/* -----[ re-generate code from the AST ]----- */ + +var DOT_CALL_NO_PARENS = jsp.array_to_hash([ + "name", + "array", + "object", + "string", + "dot", + "sub", + "call", + "regexp" +]); + +function make_string(str, ascii_only) { + var dq = 0, sq = 0; + str = str.replace(/[\\\b\f\n\r\t\x22\x27\u2028\u2029]/g, function(s){ + switch (s) { + case "\\": return "\\\\"; + case "\b": return "\\b"; + case "\f": return "\\f"; + case "\n": return "\\n"; + case "\r": return "\\r"; + case "\t": return "\\t"; + case "\u2028": return "\\u2028"; + case "\u2029": return "\\u2029"; + case '"': ++dq; return '"'; + case "'": ++sq; return "'"; + } + return s; + }); + if (ascii_only) str = to_ascii(str); + if (dq > sq) return "'" + str.replace(/\x27/g, "\\'") + "'"; + else return '"' + str.replace(/\x22/g, '\\"') + '"'; +}; + +function to_ascii(str) { + return str.replace(/[\u0080-\uffff]/g, function(ch) { + var code = ch.charCodeAt(0).toString(16); + while (code.length < 4) code = "0" + code; + return "\\u" + code; + }); +}; + +var SPLICE_NEEDS_BRACKETS = jsp.array_to_hash([ "if", "while", "do", "for", "for-in", "with" ]); + +function gen_code(ast, options) { + options = defaults(options, { + indent_start : 0, + indent_level : 4, + quote_keys : false, + space_colon : false, + beautify : false, + ascii_only : false + }); + var beautify = !!options.beautify; + var indentation = 0, + newline = beautify ? "\n" : "", + space = beautify ? " " : ""; + + function encode_string(str) { + return make_string(str, options.ascii_only); + }; + + function make_name(name) { + name = name.toString(); + if (options.ascii_only) + name = to_ascii(name); + return name; + }; + + function indent(line) { + if (line == null) + line = ""; + if (beautify) + line = repeat_string(" ", options.indent_start + indentation * options.indent_level) + line; + return line; + }; + + function with_indent(cont, incr) { + if (incr == null) incr = 1; + indentation += incr; + try { return cont.apply(null, slice(arguments, 1)); } + finally { indentation -= incr; } + }; + + function add_spaces(a) { + if (beautify) + return a.join(" "); + var b = []; + for (var i = 0; i < a.length; ++i) { + var next = a[i + 1]; + b.push(a[i]); + if (next && + ((/[a-z0-9_\x24]$/i.test(a[i].toString()) && /^[a-z0-9_\x24]/i.test(next.toString())) || + (/[\+\-]$/.test(a[i].toString()) && /^[\+\-]/.test(next.toString())))) { + b.push(" "); + } + } + return b.join(""); + }; + + function add_commas(a) { + return a.join("," + space); + }; + + function parenthesize(expr) { + var gen = make(expr); + for (var i = 1; i < arguments.length; ++i) { + var el = arguments[i]; + if ((el instanceof Function && el(expr)) || expr[0] == el) + return "(" + gen + ")"; + } + return gen; + }; + + function best_of(a) { + if (a.length == 1) { + return a[0]; + } + if (a.length == 2) { + var b = a[1]; + a = a[0]; + return a.length <= b.length ? a : b; + } + return best_of([ a[0], best_of(a.slice(1)) ]); + }; + + function needs_parens(expr) { + if (expr[0] == "function" || expr[0] == "object") { + // dot/call on a literal function requires the + // function literal itself to be parenthesized + // only if it's the first "thing" in a + // statement. This means that the parent is + // "stat", but it could also be a "seq" and + // we're the first in this "seq" and the + // parent is "stat", and so on. Messy stuff, + // but it worths the trouble. + var a = slice($stack), self = a.pop(), p = a.pop(); + while (p) { + if (p[0] == "stat") return true; + if (((p[0] == "seq" || p[0] == "call" || p[0] == "dot" || p[0] == "sub" || p[0] == "conditional") && p[1] === self) || + ((p[0] == "binary" || p[0] == "assign" || p[0] == "unary-postfix") && p[2] === self)) { + self = p; + p = a.pop(); + } else { + return false; + } + } + } + return !HOP(DOT_CALL_NO_PARENS, expr[0]); + }; + + function make_num(num) { + var str = num.toString(10), a = [ str.replace(/^0\./, ".") ], m; + if (Math.floor(num) === num) { + a.push("0x" + num.toString(16).toLowerCase(), // probably pointless + "0" + num.toString(8)); // same. + if ((m = /^(.*?)(0+)$/.exec(num))) { + a.push(m[1] + "e" + m[2].length); + } + } else if ((m = /^0?\.(0+)(.*)$/.exec(num))) { + a.push(m[2] + "e-" + (m[1].length + m[2].length), + str.substr(str.indexOf("."))); + } + return best_of(a); + }; + + var generators = { + "string": encode_string, + "num": make_num, + "name": make_name, + "toplevel": function(statements) { + return make_block_statements(statements) + .join(newline + newline); + }, + "splice": function(statements) { + var parent = $stack[$stack.length - 2][0]; + if (HOP(SPLICE_NEEDS_BRACKETS, parent)) { + // we need block brackets in this case + return make_block.apply(this, arguments); + } else { + return MAP(make_block_statements(statements, true), + function(line, i) { + // the first line is already indented + return i > 0 ? indent(line) : line; + }).join(newline); + } + }, + "block": make_block, + "var": function(defs) { + return "var " + add_commas(MAP(defs, make_1vardef)) + ";"; + }, + "const": function(defs) { + return "const " + add_commas(MAP(defs, make_1vardef)) + ";"; + }, + "try": function(tr, ca, fi) { + var out = [ "try", make_block(tr) ]; + if (ca) out.push("catch", "(" + ca[0] + ")", make_block(ca[1])); + if (fi) out.push("finally", make_block(fi)); + return add_spaces(out); + }, + "throw": function(expr) { + return add_spaces([ "throw", make(expr) ]) + ";"; + }, + "new": function(ctor, args) { + args = args.length > 0 ? "(" + add_commas(MAP(args, make)) + ")" : ""; + return add_spaces([ "new", parenthesize(ctor, "seq", "binary", "conditional", "assign", function(expr){ + var w = ast_walker(), has_call = {}; + try { + w.with_walkers({ + "call": function() { throw has_call }, + "function": function() { return this } + }, function(){ + w.walk(expr); + }); + } catch(ex) { + if (ex === has_call) + return true; + throw ex; + } + }) + args ]); + }, + "switch": function(expr, body) { + return add_spaces([ "switch", "(" + make(expr) + ")", make_switch_block(body) ]); + }, + "break": function(label) { + var out = "break"; + if (label != null) + out += " " + make_name(label); + return out + ";"; + }, + "continue": function(label) { + var out = "continue"; + if (label != null) + out += " " + make_name(label); + return out + ";"; + }, + "conditional": function(co, th, el) { + return add_spaces([ parenthesize(co, "assign", "seq", "conditional"), "?", + parenthesize(th, "seq"), ":", + parenthesize(el, "seq") ]); + }, + "assign": function(op, lvalue, rvalue) { + if (op && op !== true) op += "="; + else op = "="; + return add_spaces([ make(lvalue), op, parenthesize(rvalue, "seq") ]); + }, + "dot": function(expr) { + var out = make(expr), i = 1; + if (expr[0] == "num") { + if (!/\./.test(expr[1])) + out += "."; + } else if (needs_parens(expr)) + out = "(" + out + ")"; + while (i < arguments.length) + out += "." + make_name(arguments[i++]); + return out; + }, + "call": function(func, args) { + var f = make(func); + if (needs_parens(func)) + f = "(" + f + ")"; + return f + "(" + add_commas(MAP(args, function(expr){ + return parenthesize(expr, "seq"); + })) + ")"; + }, + "function": make_function, + "defun": make_function, + "if": function(co, th, el) { + var out = [ "if", "(" + make(co) + ")", el ? make_then(th) : make(th) ]; + if (el) { + out.push("else", make(el)); + } + return add_spaces(out); + }, + "for": function(init, cond, step, block) { + var out = [ "for" ]; + init = (init != null ? make(init) : "").replace(/;*\s*$/, ";" + space); + cond = (cond != null ? make(cond) : "").replace(/;*\s*$/, ";" + space); + step = (step != null ? make(step) : "").replace(/;*\s*$/, ""); + var args = init + cond + step; + if (args == "; ; ") args = ";;"; + out.push("(" + args + ")", make(block)); + return add_spaces(out); + }, + "for-in": function(vvar, key, hash, block) { + return add_spaces([ "for", "(" + + (vvar ? make(vvar).replace(/;+$/, "") : make(key)), + "in", + make(hash) + ")", make(block) ]); + }, + "while": function(condition, block) { + return add_spaces([ "while", "(" + make(condition) + ")", make(block) ]); + }, + "do": function(condition, block) { + return add_spaces([ "do", make(block), "while", "(" + make(condition) + ")" ]) + ";"; + }, + "return": function(expr) { + var out = [ "return" ]; + if (expr != null) out.push(make(expr)); + return add_spaces(out) + ";"; + }, + "binary": function(operator, lvalue, rvalue) { + var left = make(lvalue), right = make(rvalue); + // XXX: I'm pretty sure other cases will bite here. + // we need to be smarter. + // adding parens all the time is the safest bet. + if (member(lvalue[0], [ "assign", "conditional", "seq" ]) || + lvalue[0] == "binary" && PRECEDENCE[operator] > PRECEDENCE[lvalue[1]]) { + left = "(" + left + ")"; + } + if (member(rvalue[0], [ "assign", "conditional", "seq" ]) || + rvalue[0] == "binary" && PRECEDENCE[operator] >= PRECEDENCE[rvalue[1]] && + !(rvalue[1] == operator && member(operator, [ "&&", "||", "*" ]))) { + right = "(" + right + ")"; + } + return add_spaces([ left, operator, right ]); + }, + "unary-prefix": function(operator, expr) { + var val = make(expr); + if (!(expr[0] == "num" || (expr[0] == "unary-prefix" && !HOP(OPERATORS, operator + expr[1])) || !needs_parens(expr))) + val = "(" + val + ")"; + return operator + (jsp.is_alphanumeric_char(operator.charAt(0)) ? " " : "") + val; + }, + "unary-postfix": function(operator, expr) { + var val = make(expr); + if (!(expr[0] == "num" || (expr[0] == "unary-postfix" && !HOP(OPERATORS, operator + expr[1])) || !needs_parens(expr))) + val = "(" + val + ")"; + return val + operator; + }, + "sub": function(expr, subscript) { + var hash = make(expr); + if (needs_parens(expr)) + hash = "(" + hash + ")"; + return hash + "[" + make(subscript) + "]"; + }, + "object": function(props) { + if (props.length == 0) + return "{}"; + return "{" + newline + with_indent(function(){ + return MAP(props, function(p){ + if (p.length == 3) { + // getter/setter. The name is in p[0], the arg.list in p[1][2], the + // body in p[1][3] and type ("get" / "set") in p[2]. + return indent(make_function(p[0], p[1][2], p[1][3], p[2])); + } + var key = p[0], val = make(p[1]); + if (options.quote_keys) { + key = encode_string(key); + } else if ((typeof key == "number" || !beautify && +key + "" == key) + && parseFloat(key) >= 0) { + key = make_num(+key); + } else if (!is_identifier(key)) { + key = encode_string(key); + } + return indent(add_spaces(beautify && options.space_colon + ? [ key, ":", val ] + : [ key + ":", val ])); + }).join("," + newline); + }) + newline + indent("}"); + }, + "regexp": function(rx, mods) { + return "/" + rx + "/" + mods; + }, + "array": function(elements) { + if (elements.length == 0) return "[]"; + return add_spaces([ "[", add_commas(MAP(elements, function(el){ + if (!beautify && el[0] == "atom" && el[1] == "undefined") return ""; + return parenthesize(el, "seq"); + })), "]" ]); + }, + "stat": function(stmt) { + return make(stmt).replace(/;*\s*$/, ";"); + }, + "seq": function() { + return add_commas(MAP(slice(arguments), make)); + }, + "label": function(name, block) { + return add_spaces([ make_name(name), ":", make(block) ]); + }, + "with": function(expr, block) { + return add_spaces([ "with", "(" + make(expr) + ")", make(block) ]); + }, + "atom": function(name) { + return make_name(name); + } + }; + + // The squeezer replaces "block"-s that contain only a single + // statement with the statement itself; technically, the AST + // is correct, but this can create problems when we output an + // IF having an ELSE clause where the THEN clause ends in an + // IF *without* an ELSE block (then the outer ELSE would refer + // to the inner IF). This function checks for this case and + // adds the block brackets if needed. + function make_then(th) { + if (th[0] == "do") { + // https://github.com/mishoo/UglifyJS/issues/#issue/57 + // IE croaks with "syntax error" on code like this: + // if (foo) do ... while(cond); else ... + // we need block brackets around do/while + return make([ "block", [ th ]]); + } + var b = th; + while (true) { + var type = b[0]; + if (type == "if") { + if (!b[3]) + // no else, we must add the block + return make([ "block", [ th ]]); + b = b[3]; + } + else if (type == "while" || type == "do") b = b[2]; + else if (type == "for" || type == "for-in") b = b[4]; + else break; + } + return make(th); + }; + + function make_function(name, args, body, keyword) { + var out = keyword || "function"; + if (name) { + out += " " + make_name(name); + } + out += "(" + add_commas(MAP(args, make_name)) + ")"; + return add_spaces([ out, make_block(body) ]); + }; + + function make_block_statements(statements, noindent) { + for (var a = [], last = statements.length - 1, i = 0; i <= last; ++i) { + var stat = statements[i]; + var code = make(stat); + if (code != ";") { + if (!beautify && i == last) { + if ((stat[0] == "while" && empty(stat[2])) || + (member(stat[0], [ "for", "for-in"] ) && empty(stat[4])) || + (stat[0] == "if" && empty(stat[2]) && !stat[3]) || + (stat[0] == "if" && stat[3] && empty(stat[3]))) { + code = code.replace(/;*\s*$/, ";"); + } else { + code = code.replace(/;+\s*$/, ""); + } + } + a.push(code); + } + } + return noindent ? a : MAP(a, indent); + }; + + function make_switch_block(body) { + var n = body.length; + if (n == 0) return "{}"; + return "{" + newline + MAP(body, function(branch, i){ + var has_body = branch[1].length > 0, code = with_indent(function(){ + return indent(branch[0] + ? add_spaces([ "case", make(branch[0]) + ":" ]) + : "default:"); + }, 0.5) + (has_body ? newline + with_indent(function(){ + return make_block_statements(branch[1]).join(newline); + }) : ""); + if (!beautify && has_body && i < n - 1) + code += ";"; + return code; + }).join(newline) + newline + indent("}"); + }; + + function make_block(statements) { + if (!statements) return ";"; + if (statements.length == 0) return "{}"; + return "{" + newline + with_indent(function(){ + return make_block_statements(statements).join(newline); + }) + newline + indent("}"); + }; + + function make_1vardef(def) { + var name = def[0], val = def[1]; + if (val != null) + name = add_spaces([ make_name(name), "=", parenthesize(val, "seq") ]); + return name; + }; + + var $stack = []; + + function make(node) { + var type = node[0]; + var gen = generators[type]; + if (!gen) + throw new Error("Can't find generator for \"" + type + "\""); + $stack.push(node); + var ret = gen.apply(type, node.slice(1)); + $stack.pop(); + return ret; + }; + + return make(ast); +}; + +function split_lines(code, max_line_length) { + var splits = [ 0 ]; + jsp.parse(function(){ + var next_token = jsp.tokenizer(code); + var last_split = 0; + var prev_token; + function current_length(tok) { + return tok.pos - last_split; + }; + function split_here(tok) { + last_split = tok.pos; + splits.push(last_split); + }; + function custom(){ + var tok = next_token.apply(this, arguments); + out: { + if (prev_token) { + if (prev_token.type == "keyword") break out; + } + if (current_length(tok) > max_line_length) { + switch (tok.type) { + case "keyword": + case "atom": + case "name": + case "punc": + split_here(tok); + break out; + } + } + } + prev_token = tok; + return tok; + }; + custom.context = function() { + return next_token.context.apply(this, arguments); + }; + return custom; + }()); + return splits.map(function(pos, i){ + return code.substring(pos, splits[i + 1] || code.length); + }).join("\n"); +}; + +/* -----[ Utilities ]----- */ + +function repeat_string(str, i) { + if (i <= 0) return ""; + if (i == 1) return str; + var d = repeat_string(str, i >> 1); + d += d; + if (i & 1) d += str; + return d; +}; + +function defaults(args, defs) { + var ret = {}; + if (args === true) + args = {}; + for (var i in defs) if (HOP(defs, i)) { + ret[i] = (args && HOP(args, i)) ? args[i] : defs[i]; + } + return ret; +}; + +function is_identifier(name) { + return /^[a-z_$][a-z0-9_$]*$/i.test(name) + && name != "this" + && !HOP(jsp.KEYWORDS_ATOM, name) + && !HOP(jsp.RESERVED_WORDS, name) + && !HOP(jsp.KEYWORDS, name); +}; + +function HOP(obj, prop) { + return Object.prototype.hasOwnProperty.call(obj, prop); +}; + +// some utilities + +var MAP; + +(function(){ + MAP = function(a, f, o) { + var ret = []; + for (var i = 0; i < a.length; ++i) { + var val = f.call(o, a[i], i); + if (val instanceof AtTop) ret.unshift(val.v); + else ret.push(val); + } + return ret; + }; + MAP.at_top = function(val) { return new AtTop(val) }; + function AtTop(val) { this.v = val }; +})(); + +/* -----[ Exports ]----- */ + +exports.ast_walker = ast_walker; +exports.ast_mangle = ast_mangle; +exports.ast_squeeze = ast_squeeze; +exports.gen_code = gen_code; +exports.ast_add_scope = ast_add_scope; +exports.set_logger = function(logger) { warn = logger }; +exports.make_string = make_string; +exports.split_lines = split_lines; +exports.MAP = MAP; + +// keep this last! +exports.ast_squeeze_more = require("./squeeze-more").ast_squeeze_more; diff --git a/build/lib/squeeze-more.js b/build/lib/squeeze-more.js new file mode 100644 index 0000000..12380af --- /dev/null +++ b/build/lib/squeeze-more.js @@ -0,0 +1,22 @@ +var jsp = require("./parse-js"), + pro = require("./process"), + slice = jsp.slice, + member = jsp.member, + PRECEDENCE = jsp.PRECEDENCE, + OPERATORS = jsp.OPERATORS; + +function ast_squeeze_more(ast) { + var w = pro.ast_walker(), walk = w.walk; + return w.with_walkers({ + "call": function(expr, args) { + if (expr[0] == "dot" && expr[2] == "toString" && args.length == 0) { + // foo.toString() ==> foo+"" + return [ "binary", "+", expr[1], [ "string", "" ]]; + } + } + }, function() { + return walk(ast); + }); +}; + +exports.ast_squeeze_more = ast_squeeze_more; diff --git a/build/post-compile.js b/build/post-compile.js new file mode 100644 index 0000000..f5136d1 --- /dev/null +++ b/build/post-compile.js @@ -0,0 +1,20 @@ +#!/usr/bin/env node + +var print = require( "sys" ).print, + fs = require( "fs" ), + src = fs.readFileSync( process.argv[2], "utf8" ), + version = fs.readFileSync( "version.txt", "utf8" ), + // License Template + license = "/*! CoderDeck @VERSION http://coderdeck.com/ | http://coderdeck.com/license */"; + + +// Previously done in sed but reimplemented here due to portability issues +src = src.replace( /^(\s*\*\/)(.+)/m, "$1\n$2" ) + ";"; + +// Set minimal license block var +license = license.replace( "@VERSION", version ); + +// Replace license block with minimal license +src = src.replace( /\/\/.*?\/?\*.+?(?=\n|\r|$)|\/\*[\s\S]*?\/\/[\s\S]*?\*\//, license ); + +print( src ); diff --git a/build/release-notes.js b/build/release-notes.js new file mode 100644 index 0000000..e3325ae --- /dev/null +++ b/build/release-notes.js @@ -0,0 +1,54 @@ +#!/usr/bin/env node +/* + * jQuery Release Note Generator + */ + +var fs = require("fs"), + http = require("http"), + tmpl = require("mustache"), + extract = /(.*?)<[^"]+"component">\s*(\S+)/g; + +var opts = { + version: "1.6.3 RC 1", + short_version: "1.6.3rc1", + final_version: "1.6.3", + categories: [] +}; + +http.request({ + host: "bugs.jquery.com", + port: 80, + method: "GET", + path: "/query?status=closed&resolution=fixed&component=!web&order=component&milestone=" + opts.final_version +}, function (res) { + var data = []; + + res.on( "data", function( chunk ) { + data.push( chunk ); + }); + + res.on( "end", function() { + var match, + file = data.join(""), + cur; + + while ( (match = extract.exec( file )) ) { + if ( "#" + match[1] !== match[2] ) { + var cat = match[3]; + + if ( !cur || cur.name !== cat ) { + cur = { name: match[3], niceName: match[3].replace(/^./, function(a){ return a.toUpperCase(); }), bugs: [] }; + opts.categories.push( cur ); + } + + cur.bugs.push({ ticket: match[1], title: match[2] }); + } + } + + buildNotes(); + }); +}).end(); + +function buildNotes() { + console.log( tmpl.to_html( fs.readFileSync("release-notes.txt", "utf8"), opts ) ); +} diff --git a/build/release-notes.txt b/build/release-notes.txt new file mode 100644 index 0000000..1d0ae74 --- /dev/null +++ b/build/release-notes.txt @@ -0,0 +1,27 @@ +

jQuery {{version}} Released

+ +

This is a preview release of jQuery. We're releasing it so that everyone can start testing the code in their applications, making sure that there are no major problems.

+ +

You can get the code from the jQuery CDN:

+ +
+ +

You can help us by dropping that code into your existing application and letting us know that if anything no longer works. Please file a bug and be sure to mention that you're testing against jQuery {{version}}.

+ +

We want to encourage everyone from the community to try and get involved in contributing back to jQuery core. We've set up a full page of information dedicated towards becoming more involved with the team. The team is here and ready to help you help us!

+ +

jQuery {{version}} Change Log

+ +

The current change log of the {{version}} release.

+ +{{#categories}} +

{{niceName}}

+ + +{{/categories}} diff --git a/build/release.js b/build/release.js new file mode 100644 index 0000000..7a42f99 --- /dev/null +++ b/build/release.js @@ -0,0 +1,169 @@ +#!/usr/bin/env node +/* + * jQuery Release Management + */ + +var fs = require("fs"), + child = require("child_process"), + debug = false; + +var scpURL = "jqadmin@code.origin.jquery.com:/var/www/html/code.jquery.com/", + cdnURL = "http://code.origin.jquery.com/", + + version = /^[\d.]+(?:(?:a|b|rc)\d+|pre)?$/, + versionFile = "version.txt", + + file = "dist/jquery.js", + minFile = "dist/jquery.min.js", + + files = { + "jquery-VER.js": file, + "jquery-VER.min.js": minFile + }, + + finalFiles = { + "jquery.js": file, + "jquery-latest.js": file, + "jquery.min.js": minFile, + "jquery-latest.min.js": minFile + }; + +exec( "git pull && git status", function( error, stdout, stderr ) { + if ( /Changes to be committed/i.test( stdout ) ) { + exit( "Please commit changed files before attemping to push a release." ); + + } else if ( /Changes not staged for commit/i.test( stdout ) ) { + exit( "Please stash files before attempting to push a release." ); + + } else { + setVersion(); + } +}); + +function setVersion() { + var oldVersion = fs.readFileSync( versionFile, "utf8" ); + + prompt( "New Version (was " + oldVersion + "): ", function( data ) { + if ( data && version.test( data ) ) { + fs.writeFileSync( versionFile, data ); + + exec( "git commit -a -m 'Tagging the " + data + " release.' && git push && " + + "git tag " + data + " && git push origin " + data, function() { + make( data ); + }); + + } else { + console.error( "Malformed version number, please try again." ); + setVersion(); + } + }); +} + +function make( newVersion ) { + exec( "make clean && make", function( error, stdout, stderr ) { + // TODO: Verify JSLint + + Object.keys( files ).forEach(function( oldName ) { + var value = files[ oldName ], name = oldName.replace( /VER/g, newVersion ); + + copy( value, name ); + + delete files[ oldName ]; + files[ name ] = value; + }); + + exec( "scp " + Object.keys( files ).join( " " ) + " " + scpURL, function() { + setNextVersion( newVersion ); + }); + }); +} + +function setNextVersion( newVersion ) { + var isFinal = false; + + if ( /(?:a|b|rc)\d+$/.test( newVersion ) ) { + newVersion = newVersion.replace( /(?:a|b|rc)\d+$/, "pre" ); + + } else if ( /^\d+\.\d+\.?(\d*)$/.test( newVersion ) ) { + newVersion = newVersion.replace( /^(\d+\.\d+\.?)(\d*)$/, function( all, pre, num ) { + return pre + (pre.charAt( pre.length - 1 ) !== "." ? "." : "") + (num ? parseFloat( num ) + 1 : 1) + "pre"; + }); + + isFinal = true; + } + + prompt( "Next Version [" + newVersion + "]: ", function( data ) { + if ( !data ) { + data = newVersion; + } + + if ( version.test( data ) ) { + fs.writeFileSync( versionFile, data ); + + exec( "git commit -a -m 'Updating the source version to " + data + "' && git push", function() { + if ( isFinal ) { + makeFinal( newVersion ); + } + }); + + } else { + console.error( "Malformed version number, please try again." ); + setNextVersion( newVersion ); + } + }); +} + +function makeFinal( newVersion ) { + var all = Object.keys( finalFiles ); + + // Copy all the files + all.forEach(function( name ) { + copy( finalFiles[ name ], name ); + }); + + // Upload files to CDN + exec( "scp " + all.join( " " ) + " " + scpURL, function() { + exec( "curl '" + cdnURL + "{" + all.join( "," ) + "}?reload'", function() { + console.log( "Done." ); + }); + }); +} + +function copy( oldFile, newFile ) { + if ( debug ) { + console.log( "Copying " + oldFile + " to " + newFile ); + + } else { + fs.writeFileSync( newFile, fs.readFileSync( oldFile, "utf8" ) ); + } +} + +function prompt( msg, callback ) { + process.stdout.write( msg ); + + process.stdin.resume(); + process.stdin.setEncoding( "utf8" ); + + process.stdin.once( "data", function( chunk ) { + process.stdin.pause(); + callback( chunk.replace( /\n*$/g, "" ) ); + }); +} + +function exec( cmd, fn ) { + if ( debug ) { + console.log( cmd ); + fn(); + + } else { + child.exec( cmd, fn ); + } +} + +function exit( msg ) { + if ( msg ) { + console.error( "\nError: " + msg ); + } + + process.exit( 1 ); +} diff --git a/build/sizer.js b/build/sizer.js new file mode 100644 index 0000000..2372b5f --- /dev/null +++ b/build/sizer.js @@ -0,0 +1,36 @@ +var fs = require( "fs" ), + stdin = process.openStdin(), + rsize = /(\d+).*?(jquery\S+)/g, + oldsizes = {}, + sizes = {}; + +try { + oldsizes = JSON.parse( fs.readFileSync( __dirname + "/.sizecache.json", "utf8" ) ); +} catch(e) { + oldsizes = {}; +}; + +stdin.on( "data" , function( chunk ) { + var match; + + while ( match = rsize.exec( chunk ) ) { + sizes[ match[2] ] = parseInt( match[1], 10 ); + } +}); + +function lpad( str, len, chr ) { + return ( Array(len+1).join( chr || " ") + str ).substr( -len ); +} + +stdin.on( "end", function() { + console.log( "jQuery Size - compared to last make" ); + fs.writeFileSync( __dirname + "/.sizecache.json", JSON.stringify( sizes, true ), "utf8" ); + for ( var key in sizes ) { + var diff = oldsizes[ key ] && ( sizes[ key ] - oldsizes[ key ] ); + if ( diff > 0 ) { + diff = "+" + diff; + } + console.log( "%s %s %s", lpad( sizes[ key ], 8 ), lpad( diff ? "(" + diff + ")" : "(-)", 8 ), key ); + } + process.exit(); +}); \ No newline at end of file diff --git a/build/uglify.js b/build/uglify.js new file mode 100644 index 0000000..aad18e8 --- /dev/null +++ b/build/uglify.js @@ -0,0 +1,285 @@ +#! /usr/bin/env node +// -*- js -*- + +global.sys = require(/^v0\.[012]/.test(process.version) ? "sys" : "util"); +var fs = require("fs"); +var jsp = require("./lib/parse-js"), + pro = require("./lib/process"); + +var options = { + ast: false, + mangle: true, + mangle_toplevel: false, + squeeze: true, + make_seqs: true, + dead_code: true, + verbose: false, + show_copyright: true, + out_same_file: false, + max_line_length: 32 * 1024, + unsafe: false, + reserved_names: null, + defines: { }, + codegen_options: { + ascii_only: false, + beautify: false, + indent_level: 4, + indent_start: 0, + quote_keys: false, + space_colon: false + }, + output: true // stdout +}; + +var args = jsp.slice(process.argv, 2); +var filename; + +out: while (args.length > 0) { + var v = args.shift(); + switch (v) { + case "-b": + case "--beautify": + options.codegen_options.beautify = true; + break; + case "-i": + case "--indent": + options.codegen_options.indent_level = args.shift(); + break; + case "-q": + case "--quote-keys": + options.codegen_options.quote_keys = true; + break; + case "-mt": + case "--mangle-toplevel": + options.mangle_toplevel = true; + break; + case "--no-mangle": + case "-nm": + options.mangle = false; + break; + case "--no-squeeze": + case "-ns": + options.squeeze = false; + break; + case "--no-seqs": + options.make_seqs = false; + break; + case "--no-dead-code": + options.dead_code = false; + break; + case "--no-copyright": + case "-nc": + options.show_copyright = false; + break; + case "-o": + case "--output": + options.output = args.shift(); + break; + case "--overwrite": + options.out_same_file = true; + break; + case "-v": + case "--verbose": + options.verbose = true; + break; + case "--ast": + options.ast = true; + break; + case "--unsafe": + options.unsafe = true; + break; + case "--max-line-len": + options.max_line_length = parseInt(args.shift(), 10); + break; + case "--reserved-names": + options.reserved_names = args.shift().split(","); + break; + case "-d": + case "--define": + var defarg = args.shift(); + try { + var defsym = function(sym) { + // KEYWORDS_ATOM doesn't include NaN or Infinity - should we check + // for them too ?? We don't check reserved words and the like as the + // define values are only substituted AFTER parsing + if (jsp.KEYWORDS_ATOM.hasOwnProperty(sym)) { + throw "Don't define values for inbuilt constant '"+sym+"'"; + } + return sym; + }, + defval = function(v) { + if (v.match(/^"(.*)"$/) || v.match(/^'(.*)'$/)) { + return [ "string", RegExp.$1 ]; + } + else if (!isNaN(parseFloat(v))) { + return [ "num", parseFloat(v) ]; + } + else if (v.match(/^[a-z\$_][a-z\$_0-9]*$/i)) { + return [ "name", v ]; + } + else if (!v.match(/"/)) { + return [ "string", v ]; + } + else if (!v.match(/'/)) { + return [ "string", v ]; + } + throw "Can't understand the specified value: "+v; + }; + if (defarg.match(/^([a-z_\$][a-z_\$0-9]*)(=(.*))?$/i)) { + var sym = defsym(RegExp.$1), + val = RegExp.$2 ? defval(RegExp.$2.substr(1)) : [ 'name', 'true' ]; + options.defines[sym] = val; + } + else { + throw "The --define option expects SYMBOL[=value]"; + } + } catch(ex) { + sys.print("ERROR: In option --define "+defarg+"\n"+ex+"\n"); + process.exit(1); + } + break; + case "--define-from-module": + var defmodarg = args.shift(), + defmodule = require(defmodarg), + sym, + val; + for (sym in defmodule) { + if (defmodule.hasOwnProperty(sym)) { + options.defines[sym] = function(val) { + if (typeof val == "string") + return [ "string", val ]; + if (typeof val == "number") + return [ "num", val ]; + if (val === true) + return [ 'name', 'true' ]; + if (val === false) + return [ 'name', 'false' ]; + if (val === null) + return [ 'name', 'null' ]; + if (val === undefined) + return [ 'name', 'undefined' ]; + sys.print("ERROR: In option --define-from-module "+defmodarg+"\n"); + sys.print("ERROR: Unknown object type for: "+sym+"="+val+"\n"); + process.exit(1); + return null; + }(defmodule[sym]); + } + } + break; + case "--ascii": + options.codegen_options.ascii_only = true; + break; + default: + filename = v; + break out; + } +} + +if (options.verbose) { + pro.set_logger(function(msg){ + sys.debug(msg); + }); +} + +jsp.set_logger(function(msg){ + sys.debug(msg); +}); + +if (filename) { + fs.readFile(filename, "utf8", function(err, text){ + if (err) throw err; + output(squeeze_it(text)); + }); +} else { + var stdin = process.openStdin(); + stdin.setEncoding("utf8"); + var text = ""; + stdin.on("data", function(chunk){ + text += chunk; + }); + stdin.on("end", function() { + output(squeeze_it(text)); + }); +} + +function output(text) { + var out; + if (options.out_same_file && filename) + options.output = filename; + if (options.output === true) { + out = process.stdout; + } else { + out = fs.createWriteStream(options.output, { + flags: "w", + encoding: "utf8", + mode: 0644 + }); + } + out.write(text); + if (options.output !== true) { + out.end(); + } +}; + +// --------- main ends here. + +function show_copyright(comments) { + var ret = ""; + for (var i = 0; i < comments.length; ++i) { + var c = comments[i]; + if (c.type == "comment1") { + ret += "//" + c.value + "\n"; + } else { + ret += "/*" + c.value + "*/"; + } + } + return ret; +}; + +function squeeze_it(code) { + var result = ""; + if (options.show_copyright) { + var tok = jsp.tokenizer(code), c; + c = tok(); + result += show_copyright(c.comments_before); + } + try { + var ast = time_it("parse", function(){ return jsp.parse(code); }); + if (options.mangle) ast = time_it("mangle", function(){ + return pro.ast_mangle(ast, { + toplevel: options.mangle_toplevel, + defines: options.defines, + except: options.reserved_names + }); + }); + if (options.squeeze) ast = time_it("squeeze", function(){ + ast = pro.ast_squeeze(ast, { + make_seqs : options.make_seqs, + dead_code : options.dead_code, + keep_comps : !options.unsafe + }); + if (options.unsafe) + ast = pro.ast_squeeze_more(ast); + return ast; + }); + if (options.ast) + return sys.inspect(ast, null, null); + result += time_it("generate", function(){ return pro.gen_code(ast, options.codegen_options) }); + if (!options.codegen_options.beautify && options.max_line_length) { + result = time_it("split", function(){ return pro.split_lines(result, options.max_line_length) }); + } + return result; + } catch(ex) { + sys.debug(ex.stack); + sys.debug(sys.inspect(ex)); + sys.debug(JSON.stringify(ex)); + } +}; + +function time_it(name, cont) { + if (!options.verbose) + return cont(); + var t1 = new Date().getTime(); + try { return cont(); } + finally { sys.debug("// " + name + ": " + ((new Date().getTime() - t1) / 1000).toFixed(3) + " sec."); } +}; diff --git a/fonts/museosans_500-webfont.eot b/fonts/museosans_500-webfont.eot deleted file mode 100644 index ad7dfaddbc2bc81d08bff95d5bd4410157ba8bbe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49680 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 Ko9W(!;{OAGv%9na diff --git a/fonts/museosans_500-webfont.svg b/fonts/museosans_500-webfont.svg deleted file mode 100644 index 41769a8..0000000 --- a/fonts/museosans_500-webfont.svg +++ /dev/null @@ -1,247 +0,0 @@ - - - - -This is a custom SVG webfont generated by Font Squirrel. -Copyright : Copyright c 2008 by Jos Buivenga All rights reserved -Designer : Jos Buivenga -Foundry : Jos Buivenga -Foundry URL : httpwwwjosbuivengademonnl - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/fonts/museosans_500-webfont.ttf b/fonts/museosans_500-webfont.ttf deleted file mode 100644 index 2fd90435e48c5a3a5f467177229bac3247940572..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49516 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 diff --git a/fonts/museosans_500-webfont.woff b/fonts/museosans_500-webfont.woff deleted file mode 100644 index 5e9ef5c797c957026086124f4975f5092705a5d0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26976 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 WAVshPD?|aX1t3MR11m&XuoNq$;C$); diff --git a/js/codedeck.js b/js/codedeck.js deleted file mode 100644 index ed8b33d..0000000 --- a/js/codedeck.js +++ /dev/null @@ -1,104 +0,0 @@ - -function runCode(element) { - iframe = document.createElement("IFRAME"); - iframe.style.width = ($(element).width()-2) + "px"; - iframe.style.height = ($(element).height()-2) + "px"; - iframe.style.overflow = 'auto'; - iframe.style.border ="none"; - - var dest = $(element).attr('data-target'); - var destination = $("#" + dest ); - $(destination).html("").append(iframe); - - var editor = $(element).data('editor'); - var code = editor.getValue(); - - var language = $(element).attr('data-language'); - - if(language == 'js') { - code = "\n" + code + "\n"; - } - - code = "" + code + ''; - - writeIFrame(iframe,code); -} - -function writeIFrame(iframe,code) { - iframe = (iframe.contentWindow) ? iframe.contentWindow : (iframe.contentDocument.document) ? iframe.contentDocument.document : iframe.contentDocument; - iframe.document.open(); - iframe.document.write(code); - iframe.document.close(); -} - - - -$(document).ready(function() { - - $("a").attr('target','_blank'); - - function focusCallback() { - disableKeyboardEvents = true; - } - - function blurCallback() { - disableKeyboardEvents = false; - } - - $("article").each(function(idx) { - var slide = $(this); - - slide.find(".code-editor").attr({ - 'id': 'editor-' + idx, - 'data-target' : 'destination-' + idx - }).wrapAll("

").css('position','static'); - slide.find(".destination").attr('id','destination-' + idx); - var solution = slide.find("script[type=codedeck]")[0] - if(solution) { - $(solution).attr({ 'id' : 'solution-' + idx }); - slide.find(".code-editor").attr({ 'data-solution' : 'solution-' + idx }); - } - - }); - - $(document).bind('slideleave',function(e) { - $('.destination').html(""); - - }); - - $(document).bind("slideenter",function(e) { - var current = $(".current"); - current.find(".code-editor").each(function() { - if(!$(this).hasClass('codeEditor')) { - var element = this; - $(this).css('visibility','visible'); - var editor = CodeMirror.fromTextArea(this); - $(this).addClass('codeEditor'); - - if($(this).attr('data-script')) { - var html = $("#" + $(this).attr('data-script')).html().replace(/SCRIPT/g,' - - - - - - -

CodeMirror 2: C-like mode

- -
- - - -

Simple mode that tries to handle C-like languages as well as it - can. Takes two configuration parameters: keywords, an - object whose property names are the keywords in the language, - and useCPP, which determines whether C preprocessor - directives are recognized.

- -

MIME types defined: text/x-csrc - (C code), text/x-c++src (C++ - code), text/x-java (Java - code), text/x-groovy (Groovy code).

- - diff --git a/js/codemirror/mode/clojure/clojure.js b/js/codemirror/mode/clojure/clojure.js deleted file mode 100644 index a951589..0000000 --- a/js/codemirror/mode/clojure/clojure.js +++ /dev/null @@ -1,207 +0,0 @@ -/** - * Author: Hans Engel - * Branched from CodeMirror's Scheme mode (by Koh Zi Han, based on implementation by Koh Zi Chun) - */ -CodeMirror.defineMode("clojure", function (config, mode) { - var BUILTIN = "builtin", COMMENT = "comment", STRING = "string", TAG = "tag", - ATOM = "atom", NUMBER = "number", BRACKET = "bracket", KEYWORD="keyword"; - var INDENT_WORD_SKIP = 2, KEYWORDS_SKIP = 1; - - function makeKeywords(str) { - var obj = {}, words = str.split(" "); - for (var i = 0; i < words.length; ++i) obj[words[i]] = true; - return obj; - } - - var atoms = makeKeywords("true false nil"); - - var keywords = makeKeywords( - // Control structures - "defn defn- def def- defonce defmulti defmethod defmacro defstruct deftype defprotocol defrecord deftest slice defalias defhinted defmacro- defn-memo defnk defnk defonce- defunbound defunbound- defvar defvar- let letfn do case cond condp for loop recur when when-not when-let when-first if if-let if-not . .. -> ->> doto and or dosync doseq dotimes dorun doall load import unimport ns in-ns refer try catch finally throw with-open with-local-vars binding gen-class gen-and-load-class gen-and-save-class handler-case handle" + - - // Built-ins - "* *1 *2 *3 *agent* *allow-unresolved-vars* *assert *clojure-version* *command-line-args* *compile-files* *compile-path* *e *err* *file* *flush-on-newline* *in* *macro-meta* *math-context* *ns* *out* *print-dup* *print-length* *print-level* *print-meta* *print-readably* *read-eval* *source-path* *use-context-classloader* *warn-on-reflection* + - / < <= = == > >= accessor aclone agent agent-errors aget alength alias all-ns alter alter-meta! alter-var-root amap ancestors and apply areduce array-map aset aset-boolean aset-byte aset-char aset-double aset-float aset-int aset-long aset-short assert assoc assoc! assoc-in associative? atom await await-for await1 bases bean bigdec bigint binding bit-and bit-and-not bit-clear bit-flip bit-not bit-or bit-set bit-shift-left bit-shift-right bit-test bit-xor boolean boolean-array booleans bound-fn bound-fn* butlast byte byte-array bytes case cast char char-array char-escape-string char-name-string char? chars chunk chunk-append chunk-buffer chunk-cons chunk-first chunk-next chunk-rest chunked-seq? class class? clear-agent-errors clojure-version coll? comment commute comp comparator compare compare-and-set! compile complement concat cond condp conj conj! cons constantly construct-proxy contains? count counted? create-ns create-struct cycle dec decimal? declare definline defmacro defmethod defmulti defn defn- defonce defstruct delay delay? deliver deref derive descendants destructure disj disj! dissoc dissoc! distinct distinct? doall doc dorun doseq dosync dotimes doto double double-array doubles drop drop-last drop-while empty empty? ensure enumeration-seq eval even? every? extend extend-protocol extend-type extends? extenders false? ffirst file-seq filter find find-doc find-ns find-var first float float-array float? floats flush fn fn? fnext for force format future future-call future-cancel future-cancelled? future-done? future? gen-class gen-interface gensym get get-in get-method get-proxy-class get-thread-bindings get-validator hash hash-map hash-set identical? identity if-let if-not ifn? import in-ns inc init-proxy instance? int int-array integer? interleave intern interpose into into-array ints io! isa? iterate iterator-seq juxt key keys keyword keyword? last lazy-cat lazy-seq let letfn line-seq list list* list? load load-file load-reader load-string loaded-libs locking long long-array longs loop macroexpand macroexpand-1 make-array make-hierarchy map map? mapcat max max-key memfn memoize merge merge-with meta method-sig methods min min-key mod name namespace neg? newline next nfirst nil? nnext not not-any? not-empty not-every? not= ns ns-aliases ns-imports ns-interns ns-map ns-name ns-publics ns-refers ns-resolve ns-unalias ns-unmap nth nthnext num number? odd? or parents partial partition pcalls peek persistent! pmap pop pop! pop-thread-bindings pos? pr pr-str prefer-method prefers primitives-classnames print print-ctor print-doc print-dup print-method print-namespace-doc print-simple print-special-doc print-str printf println println-str prn prn-str promise proxy proxy-call-with-super proxy-mappings proxy-name proxy-super push-thread-bindings pvalues quot rand rand-int range ratio? rational? rationalize re-find re-groups re-matcher re-matches re-pattern re-seq read read-line read-string reify reduce ref ref-history-count ref-max-history ref-min-history ref-set refer refer-clojure release-pending-sends rem remove remove-method remove-ns repeat repeatedly replace replicate require reset! reset-meta! resolve rest resultset-seq reverse reversible? rseq rsubseq satisfies? second select-keys send send-off seq seq? seque sequence sequential? set set-validator! set? short short-array shorts shutdown-agents slurp some sort sort-by sorted-map sorted-map-by sorted-set sorted-set-by sorted? special-form-anchor special-symbol? split-at split-with str stream? string? struct struct-map subs subseq subvec supers swap! symbol symbol? sync syntax-symbol-anchor take take-last take-nth take-while test the-ns time to-array to-array-2d trampoline transient tree-seq true? type unchecked-add unchecked-dec unchecked-divide unchecked-inc unchecked-multiply unchecked-negate unchecked-remainder unchecked-subtract underive unquote unquote-splicing update-in update-proxy use val vals var-get var-set var? vary-meta vec vector vector? when when-first when-let when-not while with-bindings with-bindings* with-in-str with-loading-context with-local-vars with-meta with-open with-out-str with-precision xml-seq"); - - var indentKeys = makeKeywords( - // Built-ins - "ns fn def defn defmethod bound-fn if if-not case condp when while when-not when-first do future comment doto locking proxy with-open with-precision reify deftype defrecord defprotocol extend extend-protocol extend-type try catch" + - - // Binding forms - "let letfn binding loop for doseq dotimes when-let if-let" + - - // Data structures - "defstruct struct-map assoc" + - - // clojure.test - "testing deftest" + - - // contrib - "handler-case handle dotrace deftrace"); - - var tests = { - digit: /\d/, - digit_or_colon: /[\d:]/, - hex: /[0-9a-fA-F]/, - sign: /[+-]/, - exponent: /[eE]/, - keyword_char: /[^\s\(\[\;\)\]]/, - basic: /[\w\$_\-]/, - lang_keyword: /[\w*+!\-_?:\/]/ - }; - - function stateStack(indent, type, prev) { // represents a state stack object - this.indent = indent; - this.type = type; - this.prev = prev; - } - - function pushStack(state, indent, type) { - state.indentStack = new stateStack(indent, type, state.indentStack); - } - - function popStack(state) { - state.indentStack = state.indentStack.prev; - } - - function isNumber(ch, stream){ - // hex - if ( ch === '0' && 'x' == stream.peek().toLowerCase() ) { - stream.eat('x'); - stream.eatWhile(tests.hex); - return true; - } - - // leading sign - if ( ch == '+' || ch == '-' ) { - stream.eat(tests.sign); - ch = stream.next(); - } - - if ( tests.digit.test(ch) ) { - stream.eat(ch); - stream.eatWhile(tests.digit); - - if ( '.' == stream.peek() ) { - stream.eat('.'); - stream.eatWhile(tests.digit); - } - - if ( 'e' == stream.peek().toLowerCase() ) { - stream.eat(tests.exponent); - stream.eat(tests.sign); - stream.eatWhile(tests.digit); - } - - return true; - } - - return false; - } - - return { - startState: function () { - return { - indentStack: null, - indentation: 0, - mode: false, - }; - }, - - token: function (stream, state) { - if (state.indentStack == null && stream.sol()) { - // update indentation, but only if indentStack is empty - state.indentation = stream.indentation(); - } - - // skip spaces - if (stream.eatSpace()) { - return null; - } - var returnType = null; - - switch(state.mode){ - case "string": // multi-line string parsing mode - var next, escaped = false; - while ((next = stream.next()) != null) { - if (next == "\"" && !escaped) { - - state.mode = false; - break; - } - escaped = !escaped && next == "\\"; - } - returnType = STRING; // continue on in string mode - break; - default: // default parsing mode - var ch = stream.next(); - - if (ch == "\"") { - state.mode = "string"; - returnType = STRING; - } else if (ch == "'" && !( tests.digit_or_colon.test(stream.peek()) )) { - returnType = ATOM; - } else if (ch == ";") { // comment - stream.skipToEnd(); // rest of the line is a comment - returnType = COMMENT; - } else if (isNumber(ch,stream)){ - returnType = NUMBER; - } else if (ch == "(" || ch == "[") { - var keyWord = ''; var indentTemp = stream.column(); - /** - Either - (indent-word .. - (non-indent-word .. - (;something else, bracket, etc. - */ - - while ((letter = stream.eat(tests.keyword_char)) != null) { - keyWord += letter; - } - - if (keyWord.length > 0 && indentKeys.propertyIsEnumerable(keyWord)) { // indent-word - - pushStack(state, indentTemp + INDENT_WORD_SKIP, ch); - } else { // non-indent word - // we continue eating the spaces - stream.eatSpace(); - if (stream.eol() || stream.peek() == ";") { - // nothing significant after - // we restart indentation 1 space after - pushStack(state, indentTemp + 1, ch); - } else { - pushStack(state, indentTemp + stream.current().length, ch); // else we match - } - } - stream.backUp(stream.current().length - 1); // undo all the eating - - returnType = BRACKET; - } else if (ch == ")" || ch == "]") { - returnType = BRACKET; - if (state.indentStack != null && state.indentStack.type == (ch == ")" ? "(" : "[")) { - popStack(state); - } - } else if ( ch == ":" ) { - stream.eatWhile(tests.lang_keyword); - return TAG; - } else { - stream.eatWhile(tests.basic); - - if (keywords && keywords.propertyIsEnumerable(stream.current())) { - returnType = BUILTIN; - } else if ( atoms && atoms.propertyIsEnumerable(stream.current()) ) { - returnType = ATOM; - } else returnType = null; - } - } - - return returnType; - }, - - indent: function (state, textAfter) { - if (state.indentStack == null) return state.indentation; - return state.indentStack.indent; - } - }; -}); - -CodeMirror.defineMIME("text/x-clojure", "clojure"); diff --git a/js/codemirror/mode/clojure/index.html b/js/codemirror/mode/clojure/index.html deleted file mode 100644 index e9cc3e7..0000000 --- a/js/codemirror/mode/clojure/index.html +++ /dev/null @@ -1,85 +0,0 @@ - - - - CodeMirror 2: Clojure mode - - - - - - - - -

CodeMirror 2: Clojure mode

-
- - -

MIME types defined: text/x-clojure.

- - - diff --git a/js/codemirror/mode/coffeescript/LICENSE b/js/codemirror/mode/coffeescript/LICENSE deleted file mode 100644 index 977e284..0000000 --- a/js/codemirror/mode/coffeescript/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License - -Copyright (c) 2011 Jeff Pickhardt -Modified from the Python CodeMirror mode, Copyright (c) 2010 Timothy Farrell - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. \ No newline at end of file diff --git a/js/codemirror/mode/coffeescript/coffeescript.js b/js/codemirror/mode/coffeescript/coffeescript.js deleted file mode 100644 index d4d5723..0000000 --- a/js/codemirror/mode/coffeescript/coffeescript.js +++ /dev/null @@ -1,325 +0,0 @@ -/** - * Link to the project's GitHub page: - * https://github.com/pickhardt/coffeescript-codemirror-mode - */ -CodeMirror.defineMode('coffeescript', function(conf) { - var ERRORCLASS = 'error'; - - function wordRegexp(words) { - return new RegExp("^((" + words.join(")|(") + "))\\b"); - } - - var singleOperators = new RegExp("^[\\+\\-\\*/%&|\\^~<>!\?]"); - var singleDelimiters = new RegExp('^[\\(\\)\\[\\]\\{\\}@,:`=;\\.]'); - var doubleOperators = new RegExp("^((\->)|(\=>)|(\\+\\+)|(\\+\\=)|(\\-\\-)|(\\-\\=)|(\\*\\*)|(\\*\\=)|(\\/\\/)|(\\/\\=)|(==)|(!=)|(<=)|(>=)|(<>)|(<<)|(>>)|(//))"); - var doubleDelimiters = new RegExp("^((\\.\\.)|(\\+=)|(\\-=)|(\\*=)|(%=)|(/=)|(&=)|(\\|=)|(\\^=))"); - var tripleDelimiters = new RegExp("^((\\.\\.\\.)|(//=)|(>>=)|(<<=)|(\\*\\*=))"); - var identifiers = new RegExp("^[_A-Za-z][_A-Za-z0-9]*"); - - var wordOperators = wordRegexp(['and', 'or', 'not', - 'is', 'isnt', 'in', - 'instanceof', 'typeof']); - var indentKeywords = ['for', 'while', 'loop', 'if', 'unless', 'else', - 'switch', 'try', 'catch', 'finally', 'class']; - var commonKeywords = ['break', 'by', 'continue', 'debugger', 'delete', - 'do', 'in', 'of', 'new', 'return', 'then', - 'this', 'throw', 'when', 'until']; - - var keywords = wordRegexp(indentKeywords.concat(commonKeywords)); - - indentKeywords = wordRegexp(indentKeywords); - - - var stringPrefixes = new RegExp("^('{3}|\"{3}|['\"])"); - var regexPrefixes = new RegExp("^(/{3}|/)"); - var commonConstants = ['Infinity', 'NaN', 'undefined', 'null', 'true', 'false', 'on', 'off', 'yes', 'no']; - var constants = wordRegexp(commonConstants); - - // Tokenizers - function tokenBase(stream, state) { - // Handle scope changes - if (stream.sol()) { - var scopeOffset = state.scopes[0].offset; - if (stream.eatSpace()) { - var lineOffset = stream.indentation(); - if (lineOffset > scopeOffset) { - return 'indent'; - } else if (lineOffset < scopeOffset) { - return 'dedent'; - } - return null; - } else { - if (scopeOffset > 0) { - dedent(stream, state); - } - } - } - if (stream.eatSpace()) { - return null; - } - - var ch = stream.peek(); - - // Handle comments - if (ch === '#') { - stream.skipToEnd(); - return 'comment'; - } - - // Handle number literals - if (stream.match(/^-?[0-9\.]/, false)) { - var floatLiteral = false; - // Floats - if (stream.match(/^-?\d*\.\d+(e[\+\-]?\d+)?/i)) { - floatLiteral = true; - } - if (stream.match(/^-?\d+\.\d*/)) { - floatLiteral = true; - } - if (stream.match(/^-?\.\d+/)) { - floatLiteral = true; - } - if (floatLiteral) { - return 'number'; - } - // Integers - var intLiteral = false; - // Hex - if (stream.match(/^-?0x[0-9a-f]+/i)) { - intLiteral = true; - } - // Decimal - if (stream.match(/^-?[1-9]\d*(e[\+\-]?\d+)?/)) { - intLiteral = true; - } - // Zero by itself with no other piece of number. - if (stream.match(/^-?0(?![\dx])/i)) { - intLiteral = true; - } - if (intLiteral) { - return 'number'; - } - } - - // Handle strings - if (stream.match(stringPrefixes)) { - state.tokenize = tokenFactory(stream.current(), 'string'); - return state.tokenize(stream, state); - } - // Handle regex literals - if (stream.match(regexPrefixes)) { - if (stream.current() != '/' || stream.match(/^.*\//, false)) { // prevent highlight of division - state.tokenize = tokenFactory(stream.current(), 'string-2'); - return state.tokenize(stream, state); - } else { - stream.backUp(1); - } - } - - // Handle operators and delimiters - if (stream.match(tripleDelimiters) || stream.match(doubleDelimiters)) { - return 'punctuation'; - } - if (stream.match(doubleOperators) - || stream.match(singleOperators) - || stream.match(wordOperators)) { - return 'operator'; - } - if (stream.match(singleDelimiters)) { - return 'punctuation'; - } - - if (stream.match(constants)) { - return 'atom'; - } - - if (stream.match(keywords)) { - return 'keyword'; - } - - if (stream.match(identifiers)) { - return 'variable'; - } - - // Handle non-detected items - stream.next(); - return ERRORCLASS; - } - - function tokenFactory(delimiter, outclass) { - var delim_re = new RegExp(delimiter); - var singleline = delimiter.length == 1; - - return function tokenString(stream, state) { - while (!stream.eol()) { - stream.eatWhile(/[^'"\/\\]/); - if (stream.eat('\\')) { - stream.next(); - if (singleline && stream.eol()) { - return outclass; - } - } else if (stream.match(delim_re)) { - state.tokenize = tokenBase; - return outclass; - } else { - stream.eat(/['"\/]/); - } - } - if (singleline) { - if (conf.mode.singleLineStringErrors) { - outclass = ERRORCLASS - } else { - state.tokenize = tokenBase; - } - } - return outclass; - }; - } - - function indent(stream, state, type) { - type = type || 'coffee'; - var indentUnit = 0; - if (type === 'coffee') { - for (var i = 0; i < state.scopes.length; i++) { - if (state.scopes[i].type === 'coffee') { - indentUnit = state.scopes[i].offset + conf.indentUnit; - break; - } - } - } else { - indentUnit = stream.column() + stream.current().length; - } - state.scopes.unshift({ - offset: indentUnit, - type: type - }); - } - - function dedent(stream, state) { - if (state.scopes.length == 1) return; - if (state.scopes[0].type === 'coffee') { - var _indent = stream.indentation(); - var _indent_index = -1; - for (var i = 0; i < state.scopes.length; ++i) { - if (_indent === state.scopes[i].offset) { - _indent_index = i; - break; - } - } - if (_indent_index === -1) { - return true; - } - while (state.scopes[0].offset !== _indent) { - state.scopes.shift(); - } - return false - } else { - state.scopes.shift(); - return false; - } - } - - function tokenLexer(stream, state) { - var style = state.tokenize(stream, state); - var current = stream.current(); - - // Handle '.' connected identifiers - if (current === '.') { - style = state.tokenize(stream, state); - current = stream.current(); - if (style === 'variable') { - return 'variable'; - } else { - return ERRORCLASS; - } - } - - // Handle properties - if (current === '@') { - style = state.tokenize(stream, state); - current = stream.current(); - if (style === 'variable') { - return 'variable-2'; - } else { - return ERRORCLASS; - } - } - - // Handle scope changes. - if (current === 'return') { - state.dedent += 1; - } - if (((current === '->' || current === '=>') && - !state.lambda && - state.scopes[0].type == 'coffee' && - stream.peek() === '') - || style === 'indent') { - indent(stream, state); - } - var delimiter_index = '[({'.indexOf(current); - if (delimiter_index !== -1) { - indent(stream, state, '])}'.slice(delimiter_index, delimiter_index+1)); - } - if (indentKeywords.exec(current)){ - indent(stream, state); - } - if (current == 'then'){ - dedent(stream, state); - } - - - if (style === 'dedent') { - if (dedent(stream, state)) { - return ERRORCLASS; - } - } - delimiter_index = '])}'.indexOf(current); - if (delimiter_index !== -1) { - if (dedent(stream, state)) { - return ERRORCLASS; - } - } - if (state.dedent > 0 && stream.eol() && state.scopes[0].type == 'coffee') { - if (state.scopes.length > 1) state.scopes.shift(); - state.dedent -= 1; - } - - return style; - } - - var external = { - startState: function(basecolumn) { - return { - tokenize: tokenBase, - scopes: [{offset:basecolumn || 0, type:'coffee'}], - lastToken: null, - lambda: false, - dedent: 0 - }; - }, - - token: function(stream, state) { - var style = tokenLexer(stream, state); - - state.lastToken = {style:style, content: stream.current()}; - - if (stream.eol() && stream.lambda) { - state.lambda = false; - } - - return style; - }, - - indent: function(state, textAfter) { - if (state.tokenize != tokenBase) { - return 0; - } - - return state.scopes[0].offset; - } - - }; - return external; -}); - -CodeMirror.defineMIME('text/x-coffeescript', 'coffeescript'); diff --git a/js/codemirror/mode/coffeescript/index.html b/js/codemirror/mode/coffeescript/index.html deleted file mode 100644 index c1984df..0000000 --- a/js/codemirror/mode/coffeescript/index.html +++ /dev/null @@ -1,722 +0,0 @@ - - - - CodeMirror 2: CoffeeScript mode - - - - - - - - -

CodeMirror 2: CoffeeScript mode

-
- - -

MIME types defined: text/x-coffeescript.

- -

The CoffeeScript mode was written by Jeff Pickhardt (license).

- - - diff --git a/js/codemirror/mode/css/css.js b/js/codemirror/mode/css/css.js deleted file mode 100644 index 45170a3..0000000 --- a/js/codemirror/mode/css/css.js +++ /dev/null @@ -1,124 +0,0 @@ -CodeMirror.defineMode("css", function(config) { - var indentUnit = config.indentUnit, type; - function ret(style, tp) {type = tp; return style;} - - function tokenBase(stream, state) { - var ch = stream.next(); - if (ch == "@") {stream.eatWhile(/[\w\\\-]/); return ret("meta", stream.current());} - else if (ch == "/" && stream.eat("*")) { - state.tokenize = tokenCComment; - return tokenCComment(stream, state); - } - else if (ch == "<" && stream.eat("!")) { - state.tokenize = tokenSGMLComment; - return tokenSGMLComment(stream, state); - } - else if (ch == "=") ret(null, "compare"); - else if ((ch == "~" || ch == "|") && stream.eat("=")) return ret(null, "compare"); - else if (ch == "\"" || ch == "'") { - state.tokenize = tokenString(ch); - return state.tokenize(stream, state); - } - else if (ch == "#") { - stream.eatWhile(/[\w\\\-]/); - return ret("atom", "hash"); - } - else if (ch == "!") { - stream.match(/^\s*\w*/); - return ret("keyword", "important"); - } - else if (/\d/.test(ch)) { - stream.eatWhile(/[\w.%]/); - return ret("number", "unit"); - } - else if (/[,.+>*\/]/.test(ch)) { - return ret(null, "select-op"); - } - else if (/[;{}:\[\]]/.test(ch)) { - return ret(null, ch); - } - else { - stream.eatWhile(/[\w\\\-]/); - return ret("variable", "variable"); - } - } - - function tokenCComment(stream, state) { - var maybeEnd = false, ch; - while ((ch = stream.next()) != null) { - if (maybeEnd && ch == "/") { - state.tokenize = tokenBase; - break; - } - maybeEnd = (ch == "*"); - } - return ret("comment", "comment"); - } - - function tokenSGMLComment(stream, state) { - var dashes = 0, ch; - while ((ch = stream.next()) != null) { - if (dashes >= 2 && ch == ">") { - state.tokenize = tokenBase; - break; - } - dashes = (ch == "-") ? dashes + 1 : 0; - } - return ret("comment", "comment"); - } - - function tokenString(quote) { - return function(stream, state) { - var escaped = false, ch; - while ((ch = stream.next()) != null) { - if (ch == quote && !escaped) - break; - escaped = !escaped && ch == "\\"; - } - if (!escaped) state.tokenize = tokenBase; - return ret("string", "string"); - }; - } - - return { - startState: function(base) { - return {tokenize: tokenBase, - baseIndent: base || 0, - stack: []}; - }, - - token: function(stream, state) { - if (stream.eatSpace()) return null; - var style = state.tokenize(stream, state); - - var context = state.stack[state.stack.length-1]; - if (type == "hash" && context == "rule") style = "atom"; - else if (style == "variable") { - if (context == "rule") style = "number"; - else if (!context || context == "@media{") style = "tag"; - } - - if (context == "rule" && /^[\{\};]$/.test(type)) - state.stack.pop(); - if (type == "{") { - if (context == "@media") state.stack[state.stack.length-1] = "@media{"; - else state.stack.push("{"); - } - else if (type == "}") state.stack.pop(); - else if (type == "@media") state.stack.push("@media"); - else if (context == "{" && type != "comment") state.stack.push("rule"); - return style; - }, - - indent: function(state, textAfter) { - var n = state.stack.length; - if (/^\}/.test(textAfter)) - n -= state.stack[state.stack.length-1] == "rule" ? 2 : 1; - return state.baseIndent + n * indentUnit; - }, - - electricChars: "}" - }; -}); - -CodeMirror.defineMIME("text/css", "css"); diff --git a/js/codemirror/mode/css/index.html b/js/codemirror/mode/css/index.html deleted file mode 100644 index 7d01e36..0000000 --- a/js/codemirror/mode/css/index.html +++ /dev/null @@ -1,56 +0,0 @@ - - - - CodeMirror 2: CSS mode - - - - - - - - -

CodeMirror 2: CSS mode

-
- - -

MIME types defined: text/css.

- - - diff --git a/js/codemirror/mode/diff/diff.css b/js/codemirror/mode/diff/diff.css deleted file mode 100644 index 16f8d33..0000000 --- a/js/codemirror/mode/diff/diff.css +++ /dev/null @@ -1,3 +0,0 @@ -.cm-s-default span.cm-rangeinfo {color: #a0b;} -.cm-s-default span.cm-minus {color: #a22;} -.cm-s-default span.cm-plus {color: #2b2;} diff --git a/js/codemirror/mode/diff/diff.js b/js/codemirror/mode/diff/diff.js deleted file mode 100644 index 725bb2c..0000000 --- a/js/codemirror/mode/diff/diff.js +++ /dev/null @@ -1,13 +0,0 @@ -CodeMirror.defineMode("diff", function() { - return { - token: function(stream) { - var ch = stream.next(); - stream.skipToEnd(); - if (ch == "+") return "plus"; - if (ch == "-") return "minus"; - if (ch == "@") return "rangeinfo"; - } - }; -}); - -CodeMirror.defineMIME("text/x-diff", "diff"); diff --git a/js/codemirror/mode/diff/index.html b/js/codemirror/mode/diff/index.html deleted file mode 100644 index 2748f2f..0000000 --- a/js/codemirror/mode/diff/index.html +++ /dev/null @@ -1,99 +0,0 @@ - - - - CodeMirror 2: Diff mode - - - - - - - - -

CodeMirror 2: Diff mode

-
- - -

MIME types defined: text/x-diff.

- - - diff --git a/js/codemirror/mode/haskell/haskell.js b/js/codemirror/mode/haskell/haskell.js deleted file mode 100644 index aac5041..0000000 --- a/js/codemirror/mode/haskell/haskell.js +++ /dev/null @@ -1,242 +0,0 @@ -CodeMirror.defineMode("haskell", function(cmCfg, modeCfg) { - - function switchState(source, setState, f) { - setState(f); - return f(source, setState); - } - - // These should all be Unicode extended, as per the Haskell 2010 report - var smallRE = /[a-z_]/; - var largeRE = /[A-Z]/; - var digitRE = /[0-9]/; - var hexitRE = /[0-9A-Fa-f]/; - var octitRE = /[0-7]/; - var idRE = /[a-z_A-Z0-9']/; - var symbolRE = /[-!#$%&*+.\/<=>?@\\^|~:]/; - var specialRE = /[(),;[\]`{}]/; - var whiteCharRE = /[ \t\v\f]/; // newlines are handled in tokenizer - - function normal(source, setState) { - if (source.eatWhile(whiteCharRE)) { - return null; - } - - var ch = source.next(); - if (specialRE.test(ch)) { - if (ch == '{' && source.eat('-')) { - var t = "comment"; - if (source.eat('#')) { - t = "meta"; - } - return switchState(source, setState, ncomment(t, 1)); - } - return null; - } - - if (ch == '\'') { - if (source.eat('\\')) { - source.next(); // should handle other escapes here - } - else { - source.next(); - } - if (source.eat('\'')) { - return "string"; - } - return "error"; - } - - if (ch == '"') { - return switchState(source, setState, stringLiteral); - } - - if (largeRE.test(ch)) { - source.eatWhile(idRE); - if (source.eat('.')) { - return "qualifier"; - } - return "variable-2"; - } - - if (smallRE.test(ch)) { - source.eatWhile(idRE); - return "variable"; - } - - if (digitRE.test(ch)) { - if (ch == '0') { - if (source.eat(/[xX]/)) { - source.eatWhile(hexitRE); // should require at least 1 - return "integer"; - } - if (source.eat(/[oO]/)) { - source.eatWhile(octitRE); // should require at least 1 - return "number"; - } - } - source.eatWhile(digitRE); - var t = "number"; - if (source.eat('.')) { - t = "number"; - source.eatWhile(digitRE); // should require at least 1 - } - if (source.eat(/[eE]/)) { - t = "number"; - source.eat(/[-+]/); - source.eatWhile(digitRE); // should require at least 1 - } - return t; - } - - if (symbolRE.test(ch)) { - if (ch == '-' && source.eat(/-/)) { - source.eatWhile(/-/); - if (!source.eat(symbolRE)) { - source.skipToEnd(); - return "comment"; - } - } - var t = "variable"; - if (ch == ':') { - t = "variable-2"; - } - source.eatWhile(symbolRE); - return t; - } - - return "error"; - } - - function ncomment(type, nest) { - if (nest == 0) { - return normal; - } - return function(source, setState) { - var currNest = nest; - while (!source.eol()) { - var ch = source.next(); - if (ch == '{' && source.eat('-')) { - ++currNest; - } - else if (ch == '-' && source.eat('}')) { - --currNest; - if (currNest == 0) { - setState(normal); - return type; - } - } - } - setState(ncomment(type, currNest)); - return type; - } - } - - function stringLiteral(source, setState) { - while (!source.eol()) { - var ch = source.next(); - if (ch == '"') { - setState(normal); - return "string"; - } - if (ch == '\\') { - if (source.eol() || source.eat(whiteCharRE)) { - setState(stringGap); - return "string"; - } - if (source.eat('&')) { - } - else { - source.next(); // should handle other escapes here - } - } - } - setState(normal); - return "error"; - } - - function stringGap(source, setState) { - if (source.eat('\\')) { - return switchState(source, setState, stringLiteral); - } - source.next(); - setState(normal); - return "error"; - } - - - var wellKnownWords = (function() { - var wkw = {}; - function setType(t) { - return function () { - for (var i = 0; i < arguments.length; i++) - wkw[arguments[i]] = t; - } - } - - setType("keyword")( - "case", "class", "data", "default", "deriving", "do", "else", "foreign", - "if", "import", "in", "infix", "infixl", "infixr", "instance", "let", - "module", "newtype", "of", "then", "type", "where", "_"); - - setType("keyword")( - "\.\.", ":", "::", "=", "\\", "\"", "<-", "->", "@", "~", "=>"); - - setType("builtin")( - "!!", "$!", "$", "&&", "+", "++", "-", ".", "/", "/=", "<", "<=", "=<<", - "==", ">", ">=", ">>", ">>=", "^", "^^", "||", "*", "**"); - - setType("builtin")( - "Bool", "Bounded", "Char", "Double", "EQ", "Either", "Enum", "Eq", - "False", "FilePath", "Float", "Floating", "Fractional", "Functor", "GT", - "IO", "IOError", "Int", "Integer", "Integral", "Just", "LT", "Left", - "Maybe", "Monad", "Nothing", "Num", "Ord", "Ordering", "Rational", "Read", - "ReadS", "Real", "RealFloat", "RealFrac", "Right", "Show", "ShowS", - "String", "True"); - - setType("builtin")( - "abs", "acos", "acosh", "all", "and", "any", "appendFile", "asTypeOf", - "asin", "asinh", "atan", "atan2", "atanh", "break", "catch", "ceiling", - "compare", "concat", "concatMap", "const", "cos", "cosh", "curry", - "cycle", "decodeFloat", "div", "divMod", "drop", "dropWhile", "either", - "elem", "encodeFloat", "enumFrom", "enumFromThen", "enumFromThenTo", - "enumFromTo", "error", "even", "exp", "exponent", "fail", "filter", - "flip", "floatDigits", "floatRadix", "floatRange", "floor", "fmap", - "foldl", "foldl1", "foldr", "foldr1", "fromEnum", "fromInteger", - "fromIntegral", "fromRational", "fst", "gcd", "getChar", "getContents", - "getLine", "head", "id", "init", "interact", "ioError", "isDenormalized", - "isIEEE", "isInfinite", "isNaN", "isNegativeZero", "iterate", "last", - "lcm", "length", "lex", "lines", "log", "logBase", "lookup", "map", - "mapM", "mapM_", "max", "maxBound", "maximum", "maybe", "min", "minBound", - "minimum", "mod", "negate", "not", "notElem", "null", "odd", "or", - "otherwise", "pi", "pred", "print", "product", "properFraction", - "putChar", "putStr", "putStrLn", "quot", "quotRem", "read", "readFile", - "readIO", "readList", "readLn", "readParen", "reads", "readsPrec", - "realToFrac", "recip", "rem", "repeat", "replicate", "return", "reverse", - "round", "scaleFloat", "scanl", "scanl1", "scanr", "scanr1", "seq", - "sequence", "sequence_", "show", "showChar", "showList", "showParen", - "showString", "shows", "showsPrec", "significand", "signum", "sin", - "sinh", "snd", "span", "splitAt", "sqrt", "subtract", "succ", "sum", - "tail", "take", "takeWhile", "tan", "tanh", "toEnum", "toInteger", - "toRational", "truncate", "uncurry", "undefined", "unlines", "until", - "unwords", "unzip", "unzip3", "userError", "words", "writeFile", "zip", - "zip3", "zipWith", "zipWith3"); - - return wkw; - })(); - - - - return { - startState: function () { return { f: normal }; }, - copyState: function (s) { return { f: s.f }; }, - - token: function(stream, state) { - var t = state.f(stream, function(s) { state.f = s; }); - var w = stream.current(); - return (w in wellKnownWords) ? wellKnownWords[w] : t; - } - }; - -}); - -CodeMirror.defineMIME("text/x-haskell", "haskell"); diff --git a/js/codemirror/mode/haskell/index.html b/js/codemirror/mode/haskell/index.html deleted file mode 100644 index 6ea7f5e..0000000 --- a/js/codemirror/mode/haskell/index.html +++ /dev/null @@ -1,60 +0,0 @@ - - - - CodeMirror 2: Haskell mode - - - - - - - - -

CodeMirror 2: Haskell mode

- -
- - - -

MIME types defined: text/x-haskell.

- - diff --git a/js/codemirror/mode/htmlmixed/htmlmixed.js b/js/codemirror/mode/htmlmixed/htmlmixed.js deleted file mode 100644 index fa30a13..0000000 --- a/js/codemirror/mode/htmlmixed/htmlmixed.js +++ /dev/null @@ -1,79 +0,0 @@ -CodeMirror.defineMode("htmlmixed", function(config, parserConfig) { - var htmlMode = CodeMirror.getMode(config, {name: "xml", htmlMode: true}); - var jsMode = CodeMirror.getMode(config, "javascript"); - var cssMode = CodeMirror.getMode(config, "css"); - - function html(stream, state) { - var style = htmlMode.token(stream, state.htmlState); - if (style == "tag" && stream.current() == ">" && state.htmlState.context) { - if (/^script$/i.test(state.htmlState.context.tagName)) { - state.token = javascript; - state.localState = jsMode.startState(htmlMode.indent(state.htmlState, "")); - state.mode = "javascript"; - } - else if (/^style$/i.test(state.htmlState.context.tagName)) { - state.token = css; - state.localState = cssMode.startState(htmlMode.indent(state.htmlState, "")); - state.mode = "css"; - } - } - return style; - } - function maybeBackup(stream, pat, style) { - var cur = stream.current(); - var close = cur.search(pat); - if (close > -1) stream.backUp(cur.length - close); - return style; - } - function javascript(stream, state) { - if (stream.match(/^<\/\s*script\s*>/i, false)) { - state.token = html; - state.curState = null; - state.mode = "html"; - return html(stream, state); - } - return maybeBackup(stream, /<\/\s*script\s*>/, - jsMode.token(stream, state.localState)); - } - function css(stream, state) { - if (stream.match(/^<\/\s*style\s*>/i, false)) { - state.token = html; - state.localState = null; - state.mode = "html"; - return html(stream, state); - } - return maybeBackup(stream, /<\/\s*style\s*>/, - cssMode.token(stream, state.localState)); - } - - return { - startState: function() { - var state = htmlMode.startState(); - return {token: html, localState: null, mode: "html", htmlState: state}; - }, - - copyState: function(state) { - if (state.localState) - var local = CodeMirror.copyState(state.token == css ? cssMode : jsMode, state.localState); - return {token: state.token, localState: local, mode: state.mode, - htmlState: CodeMirror.copyState(htmlMode, state.htmlState)}; - }, - - token: function(stream, state) { - return state.token(stream, state); - }, - - indent: function(state, textAfter) { - if (state.token == html || /^\s*<\//.test(textAfter)) - return htmlMode.indent(state.htmlState, textAfter); - else if (state.token == javascript) - return jsMode.indent(state.localState, textAfter); - else - return cssMode.indent(state.localState, textAfter); - }, - - electricChars: "/{}:" - } -}); - -CodeMirror.defineMIME("text/html", "htmlmixed"); diff --git a/js/codemirror/mode/htmlmixed/index.html b/js/codemirror/mode/htmlmixed/index.html deleted file mode 100644 index 6d62b35..0000000 --- a/js/codemirror/mode/htmlmixed/index.html +++ /dev/null @@ -1,52 +0,0 @@ - - - - CodeMirror 2: HTML mixed mode - - - - - - - - - - - -

CodeMirror 2: HTML mixed mode

-
- - -

The HTML mixed mode depends on the XML, JavaScript, and CSS modes.

- -

MIME types defined: text/html - (redefined, only takes effect if you load this parser after the - XML parser).

- - - diff --git a/js/codemirror/mode/javascript/index.html b/js/codemirror/mode/javascript/index.html deleted file mode 100644 index 2454c81..0000000 --- a/js/codemirror/mode/javascript/index.html +++ /dev/null @@ -1,78 +0,0 @@ - - - - CodeMirror 2: JavaScript mode - - - - - - - - -

CodeMirror 2: JavaScript mode

- -
- - - -

JavaScript mode supports a single configuration - option, json, which will set the mode to expect JSON - data rather than a JavaScript program.

- -

MIME types defined: text/javascript, application/json.

- - diff --git a/js/codemirror/mode/javascript/javascript.js b/js/codemirror/mode/javascript/javascript.js deleted file mode 100644 index d3f9289..0000000 --- a/js/codemirror/mode/javascript/javascript.js +++ /dev/null @@ -1,352 +0,0 @@ -CodeMirror.defineMode("javascript", function(config, parserConfig) { - var indentUnit = config.indentUnit; - var jsonMode = parserConfig.json; - - // Tokenizer - - var keywords = function(){ - function kw(type) {return {type: type, style: "keyword"};} - var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c"); - var operator = kw("operator"), atom = {type: "atom", style: "atom"}; - return { - "if": A, "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B, - "return": C, "break": C, "continue": C, "new": C, "delete": C, "throw": C, - "var": kw("var"), "function": kw("function"), "catch": kw("catch"), - "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"), - "in": operator, "typeof": operator, "instanceof": operator, - "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom - }; - }(); - - var isOperatorChar = /[+\-*&%=<>!?|]/; - - function chain(stream, state, f) { - state.tokenize = f; - return f(stream, state); - } - - function nextUntilUnescaped(stream, end) { - var escaped = false, next; - while ((next = stream.next()) != null) { - if (next == end && !escaped) - return false; - escaped = !escaped && next == "\\"; - } - return escaped; - } - - // Used as scratch variables to communicate multiple values without - // consing up tons of objects. - var type, content; - function ret(tp, style, cont) { - type = tp; content = cont; - return style; - } - - function jsTokenBase(stream, state) { - var ch = stream.next(); - if (ch == '"' || ch == "'") - return chain(stream, state, jsTokenString(ch)); - else if (/[\[\]{}\(\),;\:\.]/.test(ch)) - return ret(ch); - else if (ch == "0" && stream.eat(/x/i)) { - stream.eatWhile(/[\da-f]/i); - return ret("number", "number"); - } - else if (/\d/.test(ch)) { - stream.match(/^\d*(?:\.\d*)?(?:e[+\-]?\d+)?/); - return ret("number", "number"); - } - else if (ch == "/") { - if (stream.eat("*")) { - return chain(stream, state, jsTokenComment); - } - else if (stream.eat("/")) { - stream.skipToEnd(); - return ret("comment", "comment"); - } - else if (state.reAllowed) { - nextUntilUnescaped(stream, "/"); - stream.eatWhile(/[gimy]/); // 'y' is "sticky" option in Mozilla - return ret("regexp", "string"); - } - else { - stream.eatWhile(isOperatorChar); - return ret("operator", null, stream.current()); - } - } - else if (ch == "#") { - stream.skipToEnd(); - return ret("error", "error"); - } - else if (isOperatorChar.test(ch)) { - stream.eatWhile(isOperatorChar); - return ret("operator", null, stream.current()); - } - else { - stream.eatWhile(/[\w\$_]/); - var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word]; - return known ? ret(known.type, known.style, word) : - ret("variable", "variable", word); - } - } - - function jsTokenString(quote) { - return function(stream, state) { - if (!nextUntilUnescaped(stream, quote)) - state.tokenize = jsTokenBase; - return ret("string", "string"); - }; - } - - function jsTokenComment(stream, state) { - var maybeEnd = false, ch; - while (ch = stream.next()) { - if (ch == "/" && maybeEnd) { - state.tokenize = jsTokenBase; - break; - } - maybeEnd = (ch == "*"); - } - return ret("comment", "comment"); - } - - // Parser - - var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true}; - - function JSLexical(indented, column, type, align, prev, info) { - this.indented = indented; - this.column = column; - this.type = type; - this.prev = prev; - this.info = info; - if (align != null) this.align = align; - } - - function inScope(state, varname) { - for (var v = state.localVars; v; v = v.next) - if (v.name == varname) return true; - } - - function parseJS(state, style, type, content, stream) { - var cc = state.cc; - // Communicate our context to the combinators. - // (Less wasteful than consing up a hundred closures on every call.) - cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc; - - if (!state.lexical.hasOwnProperty("align")) - state.lexical.align = true; - - while(true) { - var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement; - if (combinator(type, content)) { - while(cc.length && cc[cc.length - 1].lex) - cc.pop()(); - if (cx.marked) return cx.marked; - if (type == "variable" && inScope(state, content)) return "variable-2"; - return style; - } - } - } - - // Combinator utils - - var cx = {state: null, column: null, marked: null, cc: null}; - function pass() { - for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]); - } - function cont() { - pass.apply(null, arguments); - return true; - } - function register(varname) { - var state = cx.state; - if (state.context) { - cx.marked = "def"; - for (var v = state.localVars; v; v = v.next) - if (v.name == varname) return; - state.localVars = {name: varname, next: state.localVars}; - } - } - - // Combinators - - var defaultVars = {name: "this", next: {name: "arguments"}}; - function pushcontext() { - if (!cx.state.context) cx.state.localVars = defaultVars; - cx.state.context = {prev: cx.state.context, vars: cx.state.localVars}; - } - function popcontext() { - cx.state.localVars = cx.state.context.vars; - cx.state.context = cx.state.context.prev; - } - function pushlex(type, info) { - var result = function() { - var state = cx.state; - state.lexical = new JSLexical(state.indented, cx.stream.column(), type, null, state.lexical, info) - }; - result.lex = true; - return result; - } - function poplex() { - var state = cx.state; - if (state.lexical.prev) { - if (state.lexical.type == ")") - state.indented = state.lexical.indented; - state.lexical = state.lexical.prev; - } - } - poplex.lex = true; - - function expect(wanted) { - return function expecting(type) { - if (type == wanted) return cont(); - else if (wanted == ";") return pass(); - else return cont(arguments.callee); - }; - } - - function statement(type) { - if (type == "var") return cont(pushlex("vardef"), vardef1, expect(";"), poplex); - if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex); - if (type == "keyword b") return cont(pushlex("form"), statement, poplex); - if (type == "{") return cont(pushlex("}"), block, poplex); - if (type == ";") return cont(); - if (type == "function") return cont(functiondef); - if (type == "for") return cont(pushlex("form"), expect("("), pushlex(")"), forspec1, expect(")"), - poplex, statement, poplex); - if (type == "variable") return cont(pushlex("stat"), maybelabel); - if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"), - block, poplex, poplex); - if (type == "case") return cont(expression, expect(":")); - if (type == "default") return cont(expect(":")); - if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"), - statement, poplex, popcontext); - return pass(pushlex("stat"), expression, expect(";"), poplex); - } - function expression(type) { - if (atomicTypes.hasOwnProperty(type)) return cont(maybeoperator); - if (type == "function") return cont(functiondef); - if (type == "keyword c") return cont(expression); - if (type == "(") return cont(pushlex(")"), expression, expect(")"), poplex, maybeoperator); - if (type == "operator") return cont(expression); - if (type == "[") return cont(pushlex("]"), commasep(expression, "]"), poplex, maybeoperator); - if (type == "{") return cont(pushlex("}"), commasep(objprop, "}"), poplex, maybeoperator); - return cont(); - } - function maybeoperator(type, value) { - if (type == "operator" && /\+\+|--/.test(value)) return cont(maybeoperator); - if (type == "operator") return cont(expression); - if (type == ";") return; - if (type == "(") return cont(pushlex(")"), commasep(expression, ")"), poplex, maybeoperator); - if (type == ".") return cont(property, maybeoperator); - if (type == "[") return cont(pushlex("]"), expression, expect("]"), poplex, maybeoperator); - } - function maybelabel(type) { - if (type == ":") return cont(poplex, statement); - return pass(maybeoperator, expect(";"), poplex); - } - function property(type) { - if (type == "variable") {cx.marked = "property"; return cont();} - } - function objprop(type) { - if (type == "variable") cx.marked = "property"; - if (atomicTypes.hasOwnProperty(type)) return cont(expect(":"), expression); - } - function commasep(what, end) { - function proceed(type) { - if (type == ",") return cont(what, proceed); - if (type == end) return cont(); - return cont(expect(end)); - } - return function commaSeparated(type) { - if (type == end) return cont(); - else return pass(what, proceed); - }; - } - function block(type) { - if (type == "}") return cont(); - return pass(statement, block); - } - function vardef1(type, value) { - if (type == "variable"){register(value); return cont(vardef2);} - return cont(); - } - function vardef2(type, value) { - if (value == "=") return cont(expression, vardef2); - if (type == ",") return cont(vardef1); - } - function forspec1(type) { - if (type == "var") return cont(vardef1, forspec2); - if (type == ";") return pass(forspec2); - if (type == "variable") return cont(formaybein); - return pass(forspec2); - } - function formaybein(type, value) { - if (value == "in") return cont(expression); - return cont(maybeoperator, forspec2); - } - function forspec2(type, value) { - if (type == ";") return cont(forspec3); - if (value == "in") return cont(expression); - return cont(expression, expect(";"), forspec3); - } - function forspec3(type) { - if (type != ")") cont(expression); - } - function functiondef(type, value) { - if (type == "variable") {register(value); return cont(functiondef);} - if (type == "(") return cont(pushlex(")"), pushcontext, commasep(funarg, ")"), poplex, statement, popcontext); - } - function funarg(type, value) { - if (type == "variable") {register(value); return cont();} - } - - // Interface - - return { - startState: function(basecolumn) { - return { - tokenize: jsTokenBase, - reAllowed: true, - cc: [], - lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false), - localVars: null, - context: null, - indented: 0 - }; - }, - - token: function(stream, state) { - if (stream.sol()) { - if (!state.lexical.hasOwnProperty("align")) - state.lexical.align = false; - state.indented = stream.indentation(); - } - if (stream.eatSpace()) return null; - var style = state.tokenize(stream, state); - if (type == "comment") return style; - state.reAllowed = type == "operator" || type == "keyword c" || type.match(/^[\[{}\(,;:]$/); - return parseJS(state, style, type, content, stream); - }, - - indent: function(state, textAfter) { - if (state.tokenize != jsTokenBase) return 0; - var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical, - type = lexical.type, closing = firstChar == type; - if (type == "vardef") return lexical.indented + 4; - else if (type == "form" && firstChar == "{") return lexical.indented; - else if (type == "stat" || type == "form") return lexical.indented + indentUnit; - else if (lexical.info == "switch" && !closing) - return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit); - else if (lexical.align) return lexical.column + (closing ? 0 : 1); - else return lexical.indented + (closing ? 0 : indentUnit); - }, - - electricChars: ":{}" - }; -}); - -CodeMirror.defineMIME("text/javascript", "javascript"); -CodeMirror.defineMIME("application/json", {name: "javascript", json: true}); diff --git a/js/codemirror/mode/jinja2/index.html b/js/codemirror/mode/jinja2/index.html deleted file mode 100644 index ffb06e8..0000000 --- a/js/codemirror/mode/jinja2/index.html +++ /dev/null @@ -1,38 +0,0 @@ - - - - CodeMirror 2: Jinja2 mode - - - - - - - - -

CodeMirror 2: Jinja2 mode

-
- - - diff --git a/js/codemirror/mode/jinja2/jinja2.js b/js/codemirror/mode/jinja2/jinja2.js deleted file mode 100644 index 75419d8..0000000 --- a/js/codemirror/mode/jinja2/jinja2.js +++ /dev/null @@ -1,42 +0,0 @@ -CodeMirror.defineMode("jinja2", function(config, parserConf) { - var keywords = ["block", "endblock", "for", "endfor", "in", "true", "false", - "loop", "none", "self", "super", "if", "as", "not", "and", - "else", "import", "with", "without", "context"]; - keywords = new RegExp("^((" + keywords.join(")|(") + "))\\b"); - - function tokenBase (stream, state) { - var ch = stream.next(); - if (ch == "{") { - if (ch = stream.eat(/\{|%|#/)) { - stream.eat("-"); - state.tokenize = inTag(ch); - return "tag"; - } - } - } - function inTag (close) { - if (close == "{") { - close = "}"; - } - return function (stream, state) { - var ch = stream.next(); - if ((ch == close || (ch == "-" && stream.eat(close))) - && stream.eat("}")) { - state.tokenize = tokenBase; - return "tag"; - } - if (stream.match(keywords)) { - return "keyword"; - } - return close == "#" ? "comment" : "string"; - }; - } - return { - startState: function () { - return {tokenize: tokenBase}; - }, - token: function (stream, state) { - return state.tokenize(stream, state); - } - }; -}); diff --git a/js/codemirror/mode/lua/index.html b/js/codemirror/mode/lua/index.html deleted file mode 100644 index 532973a..0000000 --- a/js/codemirror/mode/lua/index.html +++ /dev/null @@ -1,72 +0,0 @@ - - - - CodeMirror 2: Lua mode - - - - - - - - -

CodeMirror 2: Lua mode

-
- - -

Loosely based on Franciszek - Wawrzak's CodeMirror - 1 mode. One configuration parameter is - supported, specials, to which you can provide an - array of strings to have those identifiers highlighted with - the lua-special style.

-

MIME types defined: text/x-lua.

- - - diff --git a/js/codemirror/mode/lua/lua.js b/js/codemirror/mode/lua/lua.js deleted file mode 100644 index f96737a..0000000 --- a/js/codemirror/mode/lua/lua.js +++ /dev/null @@ -1,140 +0,0 @@ -// LUA mode. Ported to CodeMirror 2 from Franciszek Wawrzak's -// CodeMirror 1 mode. -// highlights keywords, strings, comments (no leveling supported! ("[==[")), tokens, basic indenting - -CodeMirror.defineMode("lua", function(config, parserConfig) { - var indentUnit = config.indentUnit; - - function prefixRE(words) { - return new RegExp("^(?:" + words.join("|") + ")", "i"); - } - function wordRE(words) { - return new RegExp("^(?:" + words.join("|") + ")$", "i"); - } - var specials = wordRE(parserConfig.specials || []); - - // long list of standard functions from lua manual - var builtins = wordRE([ - "_G","_VERSION","assert","collectgarbage","dofile","error","getfenv","getmetatable","ipairs","load", - "loadfile","loadstring","module","next","pairs","pcall","print","rawequal","rawget","rawset","require", - "select","setfenv","setmetatable","tonumber","tostring","type","unpack","xpcall", - - "coroutine.create","coroutine.resume","coroutine.running","coroutine.status","coroutine.wrap","coroutine.yield", - - "debug.debug","debug.getfenv","debug.gethook","debug.getinfo","debug.getlocal","debug.getmetatable", - "debug.getregistry","debug.getupvalue","debug.setfenv","debug.sethook","debug.setlocal","debug.setmetatable", - "debug.setupvalue","debug.traceback", - - "close","flush","lines","read","seek","setvbuf","write", - - "io.close","io.flush","io.input","io.lines","io.open","io.output","io.popen","io.read","io.stderr","io.stdin", - "io.stdout","io.tmpfile","io.type","io.write", - - "math.abs","math.acos","math.asin","math.atan","math.atan2","math.ceil","math.cos","math.cosh","math.deg", - "math.exp","math.floor","math.fmod","math.frexp","math.huge","math.ldexp","math.log","math.log10","math.max", - "math.min","math.modf","math.pi","math.pow","math.rad","math.random","math.randomseed","math.sin","math.sinh", - "math.sqrt","math.tan","math.tanh", - - "os.clock","os.date","os.difftime","os.execute","os.exit","os.getenv","os.remove","os.rename","os.setlocale", - "os.time","os.tmpname", - - "package.cpath","package.loaded","package.loaders","package.loadlib","package.path","package.preload", - "package.seeall", - - "string.byte","string.char","string.dump","string.find","string.format","string.gmatch","string.gsub", - "string.len","string.lower","string.match","string.rep","string.reverse","string.sub","string.upper", - - "table.concat","table.insert","table.maxn","table.remove","table.sort" - ]); - var keywords = wordRE(["and","break","elseif","false","nil","not","or","return", - "true","function", "end", "if", "then", "else", "do", - "while", "repeat", "until", "for", "in", "local" ]); - - var indentTokens = wordRE(["function", "if","repeat","for","while", "\\(", "{"]); - var dedentTokens = wordRE(["end", "until", "\\)", "}"]); - var dedentPartial = prefixRE(["end", "until", "\\)", "}", "else", "elseif"]); - - function readBracket(stream) { - var level = 0; - while (stream.eat("=")) ++level; - stream.eat("["); - return level; - } - - function normal(stream, state) { - var ch = stream.next(); - if (ch == "-" && stream.eat("-")) { - if (stream.eat("[")) - return (state.cur = bracketed(readBracket(stream), "comment"))(stream, state); - stream.skipToEnd(); - return "comment"; - } - if (ch == "\"" || ch == "'") - return (state.cur = string(ch))(stream, state); - if (ch == "[" && /[\[=]/.test(stream.peek())) - return (state.cur = bracketed(readBracket(stream), "string"))(stream, state); - if (/\d/.test(ch)) { - stream.eatWhile(/[\w.%]/); - return "number"; - } - if (/[\w_]/.test(ch)) { - stream.eatWhile(/[\w\\\-_.]/); - return "variable"; - } - return null; - } - - function bracketed(level, style) { - return function(stream, state) { - var curlev = null, ch; - while ((ch = stream.next()) != null) { - if (curlev == null) {if (ch == "]") curlev = 0;} - else if (ch == "=") ++curlev; - else if (ch == "]" && curlev == level) { state.cur = normal; break; } - else curlev = null; - } - return style; - }; - } - - function string(quote) { - return function(stream, state) { - var escaped = false, ch; - while ((ch = stream.next()) != null) { - if (ch == quote && !escaped) break; - escaped = !escaped && ch == "\\"; - } - if (!escaped) state.cur = normal; - return "string"; - }; - } - - return { - startState: function(basecol) { - return {basecol: basecol || 0, indentDepth: 0, cur: normal}; - }, - - token: function(stream, state) { - if (stream.eatSpace()) return null; - var style = state.cur(stream, state); - var word = stream.current(); - if (style == "variable") { - if (keywords.test(word)) style = "keyword"; - else if (builtins.test(word)) style = "builtin"; - else if (specials.test(word)) style = "variable-2"; - } - if ((style != "lua-comment") && (style != "lua-string")){ - if (indentTokens.test(word)) ++state.indentDepth; - else if (dedentTokens.test(word)) --state.indentDepth; - } - return style; - }, - - indent: function(state, textAfter) { - var closing = dedentPartial.test(textAfter); - return state.basecol + indentUnit * (state.indentDepth - (closing ? 1 : 0)); - } - }; -}); - -CodeMirror.defineMIME("text/x-lua", "lua"); diff --git a/js/codemirror/mode/markdown/index.html b/js/codemirror/mode/markdown/index.html deleted file mode 100644 index 106b545..0000000 --- a/js/codemirror/mode/markdown/index.html +++ /dev/null @@ -1,340 +0,0 @@ - - - - CodeMirror 2: Markdown mode - - - - - - - - - - -

CodeMirror 2: Markdown mode

- - -
- - - -

MIME types defined: text/x-markdown.

- - - diff --git a/js/codemirror/mode/markdown/markdown.css b/js/codemirror/mode/markdown/markdown.css deleted file mode 100644 index c053e3f..0000000 --- a/js/codemirror/mode/markdown/markdown.css +++ /dev/null @@ -1,10 +0,0 @@ -.cm-s-default span.cm-header {color: #2f2f4f; font-weight:bold;} -.cm-s-default span.cm-code {color: #666;} -.cm-s-default span.cm-quote {color: #090;} -.cm-s-default span.cm-list {color: #a50;} -.cm-s-default span.cm-hr {color: #999;} -.cm-s-default span.cm-linktext {color: #00c; text-decoration: underline;} -.cm-s-default span.cm-linkhref {color: #00c;} -.cm-s-default span.cm-em {font-style: italic;} -.cm-s-default span.cm-strong {font-weight: bold;} -.cm-s-default span.cm-emstrong {font-style: italic; font-weight: bold;} diff --git a/js/codemirror/mode/markdown/markdown.js b/js/codemirror/mode/markdown/markdown.js deleted file mode 100644 index 75f0a63..0000000 --- a/js/codemirror/mode/markdown/markdown.js +++ /dev/null @@ -1,230 +0,0 @@ -CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) { - - var htmlMode = CodeMirror.getMode(cmCfg, { name: 'xml', htmlMode: true }); - - var header = 'header' - , code = 'code' - , quote = 'quote' - , list = 'list' - , hr = 'hr' - , linktext = 'linktext' - , linkhref = 'linkhref' - , em = 'em' - , strong = 'strong' - , emstrong = 'emstrong'; - - var hrRE = /^[*-=_]/ - , ulRE = /^[*-+]\s+/ - , olRE = /^[0-9]\.\s+/ - , headerRE = /^(?:\={3,}|-{3,})$/ - , codeRE = /^(k:\t|\s{4,})/ - , textRE = /^[^\[*_\\<>`]+/; - - function switchInline(stream, state, f) { - state.f = state.inline = f; - return f(stream, state); - } - - function switchBlock(stream, state, f) { - state.f = state.block = f; - return f(stream, state); - } - - - // Blocks - - function blockNormal(stream, state) { - if (stream.match(codeRE)) { - stream.skipToEnd(); - return code; - } - - if (stream.eatSpace()) { - return null; - } - - if (stream.peek() === '#' || stream.match(headerRE)) { - stream.skipToEnd(); - return header; - } - if (stream.eat('>')) { - state.indentation++; - return quote; - } - if (stream.peek() === '<') { - return switchBlock(stream, state, htmlBlock); - } - if (stream.peek() === '[') { - return switchInline(stream, state, footnoteLink); - } - if (hrRE.test(stream.peek())) { - var re = new RegExp('(?:\s*['+stream.peek()+']){3,}$'); - if (stream.match(re, true)) { - return hr; - } - } - - var match; - if (match = stream.match(ulRE, true) || stream.match(olRE, true)) { - state.indentation += match[0].length; - return list; - } - - return switchInline(stream, state, state.inline); - } - - function htmlBlock(stream, state) { - var type = htmlMode.token(stream, state.htmlState); - if (stream.eol() && !state.htmlState.context) { - state.block = blockNormal; - } - return type; - } - - - // Inline - - function inlineNormal(stream, state) { - function getType() { - return state.strong ? (state.em ? emstrong : strong) - : (state.em ? em : null); - } - - if (stream.match(textRE, true)) { - return getType(); - } - - var ch = stream.next(); - - if (ch === '\\') { - stream.next(); - return getType(); - } - if (ch === '`') { - return switchInline(stream, state, inlineElement(code, '`')); - } - if (ch === '<') { - return switchInline(stream, state, inlineElement(linktext, '>')); - } - if (ch === '[') { - return switchInline(stream, state, linkText); - } - - var t = getType(); - if (ch === '*' || ch === '_') { - if (stream.eat(ch)) { - return (state.strong = !state.strong) ? getType() : t; - } - return (state.em = !state.em) ? getType() : t; - } - - return getType(); - } - - function linkText(stream, state) { - while (!stream.eol()) { - var ch = stream.next(); - if (ch === '\\') stream.next(); - if (ch === ']') { - state.inline = state.f = linkHref; - return linktext; - } - } - return linktext; - } - - function linkHref(stream, state) { - stream.eatSpace(); - var ch = stream.next(); - if (ch === '(' || ch === '[') { - return switchInline(stream, state, inlineElement(linkhref, ch === '(' ? ')' : ']')); - } - return 'error'; - } - - function footnoteLink(stream, state) { - if (stream.match(/^[^\]]*\]:/, true)) { - state.f = footnoteUrl; - return linktext; - } - return switchInline(stream, state, inlineNormal); - } - - function footnoteUrl(stream, state) { - stream.eatSpace(); - stream.match(/^[^\s]+/, true); - state.f = state.inline = inlineNormal; - return linkhref; - } - - function inlineElement(type, endChar, next) { - next = next || inlineNormal; - return function(stream, state) { - while (!stream.eol()) { - var ch = stream.next(); - if (ch === '\\') stream.next(); - if (ch === endChar) { - state.inline = state.f = next; - return type; - } - } - return type; - }; - } - - return { - startState: function() { - return { - f: blockNormal, - - block: blockNormal, - htmlState: htmlMode.startState(), - indentation: 0, - - inline: inlineNormal, - em: false, - strong: false - }; - }, - - copyState: function(s) { - return { - f: s.f, - - block: s.block, - htmlState: CodeMirror.copyState(htmlMode, s.htmlState), - indentation: s.indentation, - - inline: s.inline, - em: s.em, - strong: s.strong - }; - }, - - token: function(stream, state) { - if (stream.sol()) { - state.f = state.block; - var previousIndentation = state.indentation - , currentIndentation = 0; - while (previousIndentation > 0) { - if (stream.eat(' ')) { - previousIndentation--; - currentIndentation++; - } else if (previousIndentation >= 4 && stream.eat('\t')) { - previousIndentation -= 4; - currentIndentation += 4; - } else { - break; - } - } - state.indentation = currentIndentation; - - if (currentIndentation > 0) return null; - } - return state.f(stream, state); - } - }; - -}); - -CodeMirror.defineMIME("text/x-markdown", "markdown"); diff --git a/js/codemirror/mode/php/index.html b/js/codemirror/mode/php/index.html deleted file mode 100644 index 9e545c9..0000000 --- a/js/codemirror/mode/php/index.html +++ /dev/null @@ -1,49 +0,0 @@ - - - - CodeMirror 2: PHP mode - - - - - - - - - - - - -

CodeMirror 2: PHP mode

- -
- - - -

Simple HTML/PHP mode based on - the C-like mode. Depends on XML, - JavaScript, CSS, and C-like modes.

- -

MIME types defined: application/x-httpd-php (HTML with PHP code), text/x-php (plain, non-wrapped PHP code).

- - diff --git a/js/codemirror/mode/php/php.js b/js/codemirror/mode/php/php.js deleted file mode 100644 index bfa5229..0000000 --- a/js/codemirror/mode/php/php.js +++ /dev/null @@ -1,115 +0,0 @@ -(function() { - function keywords(str) { - var obj = {}, words = str.split(" "); - for (var i = 0; i < words.length; ++i) obj[words[i]] = true; - return obj; - } - function heredoc(delim) { - return function(stream, state) { - if (stream.match(delim)) state.tokenize = null; - else stream.skipToEnd(); - return "string"; - } - } - var phpConfig = { - name: "clike", - keywords: keywords("abstract and array as break case catch cfunction class clone const continue declare " + - "default do else elseif enddeclare endfor endforeach endif endswitch endwhile extends " + - "final for foreach function global goto if implements interface instanceof namespace " + - "new or private protected public static switch throw try use var while xor return"), - blockKeywords: keywords("catch do else elseif for foreach if switch try while"), - atoms: keywords("true false null"), - multiLineStrings: true, - hooks: { - "$": function(stream, state) { - stream.eatWhile(/[\w\$_]/); - return "variable-2"; - }, - "<": function(stream, state) { - if (stream.match(/</; - state.mode = 'php'; - } - else if (style == "tag" && stream.current() == ">" && state.curState.context) { - if (/^script$/i.test(state.curState.context.tagName)) { - state.curMode = jsMode; - state.curState = jsMode.startState(htmlMode.indent(state.curState, "")); - state.curClose = /^<\/\s*script\s*>/i; - state.mode = 'javascript'; - } - else if (/^style$/i.test(state.curState.context.tagName)) { - state.curMode = cssMode; - state.curState = cssMode.startState(htmlMode.indent(state.curState, "")); - state.curClose = /^<\/\s*style\s*>/i; - state.mode = 'css'; - } - } - return style; - } - else if (stream.match(state.curClose, false)) { - state.curMode = htmlMode; - state.curState = state.html; - state.curClose = null; - state.mode = 'html'; - return dispatch(stream, state); - } - else return state.curMode.token(stream, state.curState); - } - - return { - startState: function() { - var html = htmlMode.startState(); - return {html: html, - php: phpMode.startState(), - curMode: parserConfig.startOpen ? phpMode : htmlMode, - curState: parserConfig.startOpen ? phpMode.startState() : html, - curClose: parserConfig.startOpen ? /^\?>/ : null, - mode: parserConfig.startOpen ? 'php' : 'html'} - }, - - copyState: function(state) { - var html = state.html, htmlNew = CodeMirror.copyState(htmlMode, html), - php = state.php, phpNew = CodeMirror.copyState(phpMode, php), cur; - if (state.curState == html) cur = htmlNew; - else if (state.curState == php) cur = phpNew; - else cur = CodeMirror.copyState(state.curMode, state.curState); - return {html: htmlNew, php: phpNew, curMode: state.curMode, curState: cur, curClose: state.curClose}; - }, - - token: dispatch, - - indent: function(state, textAfter) { - if ((state.curMode != phpMode && /^\s*<\//.test(textAfter)) || - (state.curMode == phpMode && /^\?>/.test(textAfter))) - return htmlMode.indent(state.html, textAfter); - return state.curMode.indent(state.curState, textAfter); - }, - - electricChars: "/{}:" - } - }); - CodeMirror.defineMIME("application/x-httpd-php", "php"); - CodeMirror.defineMIME("application/x-httpd-php-open", {name: "php", startOpen: true}); - CodeMirror.defineMIME("text/x-php", phpConfig); -})(); diff --git a/js/codemirror/mode/plsql/index.html b/js/codemirror/mode/plsql/index.html deleted file mode 100644 index 8c7bf7c..0000000 --- a/js/codemirror/mode/plsql/index.html +++ /dev/null @@ -1,63 +0,0 @@ - - - - CodeMirror 2: Oracle PL/SQL mode - - - - - - - - -

CodeMirror 2: Oracle PL/SQL mode

- -
- - - -

- Simple mode that handles Oracle PL/SQL language (and Oracle SQL, of course). -

- -

MIME type defined: text/x-plsql - (PLSQL code) - diff --git a/js/codemirror/mode/plsql/plsql.js b/js/codemirror/mode/plsql/plsql.js deleted file mode 100644 index a2ac2e8..0000000 --- a/js/codemirror/mode/plsql/plsql.js +++ /dev/null @@ -1,217 +0,0 @@ -CodeMirror.defineMode("plsql", function(config, parserConfig) { - var indentUnit = config.indentUnit, - keywords = parserConfig.keywords, - functions = parserConfig.functions, - types = parserConfig.types, - sqlplus = parserConfig.sqlplus, - multiLineStrings = parserConfig.multiLineStrings; - var isOperatorChar = /[+\-*&%=<>!?:\/|]/; - function chain(stream, state, f) { - state.tokenize = f; - return f(stream, state); - } - - var type; - function ret(tp, style) { - type = tp; - return style; - } - - function tokenBase(stream, state) { - var ch = stream.next(); - // start of string? - if (ch == '"' || ch == "'") - return chain(stream, state, tokenString(ch)); - // is it one of the special signs []{}().,;? Seperator? - else if (/[\[\]{}\(\),;\.]/.test(ch)) - return ret(ch); - // start of a number value? - else if (/\d/.test(ch)) { - stream.eatWhile(/[\w\.]/); - return ret("number", "number"); - } - // multi line comment or simple operator? - else if (ch == "/") { - if (stream.eat("*")) { - return chain(stream, state, tokenComment); - } - else { - stream.eatWhile(isOperatorChar); - return ret("operator", "operator"); - } - } - // single line comment or simple operator? - else if (ch == "-") { - if (stream.eat("-")) { - stream.skipToEnd(); - return ret("comment", "comment"); - } - else { - stream.eatWhile(isOperatorChar); - return ret("operator", "operator"); - } - } - // pl/sql variable? - else if (ch == "@" || ch == "$") { - stream.eatWhile(/[\w\d\$_]/); - return ret("word", "variable"); - } - // is it a operator? - else if (isOperatorChar.test(ch)) { - stream.eatWhile(isOperatorChar); - return ret("operator", "operator"); - } - else { - // get the whole word - stream.eatWhile(/[\w\$_]/); - // is it one of the listed keywords? - if (keywords && keywords.propertyIsEnumerable(stream.current().toLowerCase())) return ret("keyword", "keyword"); - // is it one of the listed functions? - if (functions && functions.propertyIsEnumerable(stream.current().toLowerCase())) return ret("keyword", "builtin"); - // is it one of the listed types? - if (types && types.propertyIsEnumerable(stream.current().toLowerCase())) return ret("keyword", "variable-2"); - // is it one of the listed sqlplus keywords? - if (sqlplus && sqlplus.propertyIsEnumerable(stream.current().toLowerCase())) return ret("keyword", "variable-3"); - // default: just a "word" - return ret("word", "plsql-word"); - } - } - - function tokenString(quote) { - return function(stream, state) { - var escaped = false, next, end = false; - while ((next = stream.next()) != null) { - if (next == quote && !escaped) {end = true; break;} - escaped = !escaped && next == "\\"; - } - if (end || !(escaped || multiLineStrings)) - state.tokenize = tokenBase; - return ret("string", "plsql-string"); - }; - } - - function tokenComment(stream, state) { - var maybeEnd = false, ch; - while (ch = stream.next()) { - if (ch == "/" && maybeEnd) { - state.tokenize = tokenBase; - break; - } - maybeEnd = (ch == "*"); - } - return ret("comment", "plsql-comment"); - } - - // Interface - - return { - startState: function(basecolumn) { - return { - tokenize: tokenBase, - startOfLine: true - }; - }, - - token: function(stream, state) { - if (stream.eatSpace()) return null; - var style = state.tokenize(stream, state); - return style; - } - }; -}); - -(function() { - function keywords(str) { - var obj = {}, words = str.split(" "); - for (var i = 0; i < words.length; ++i) obj[words[i]] = true; - return obj; - } - var cKeywords = "abort accept access add all alter and any array arraylen as asc assert assign at attributes audit " + - "authorization avg " + - "base_table begin between binary_integer body boolean by " + - "case cast char char_base check close cluster clusters colauth column comment commit compress connect " + - "connected constant constraint crash create current currval cursor " + - "data_base database date dba deallocate debugoff debugon decimal declare default definition delay delete " + - "desc digits dispose distinct do drop " + - "else elsif enable end entry escape exception exception_init exchange exclusive exists exit external " + - "fast fetch file for force form from function " + - "generic goto grant group " + - "having " + - "identified if immediate in increment index indexes indicator initial initrans insert interface intersect " + - "into is " + - "key " + - "level library like limited local lock log logging long loop " + - "master maxextents maxtrans member minextents minus mislabel mode modify multiset " + - "new next no noaudit nocompress nologging noparallel not nowait number_base " + - "object of off offline on online only open option or order out " + - "package parallel partition pctfree pctincrease pctused pls_integer positive positiven pragma primary prior " + - "private privileges procedure public " + - "raise range raw read rebuild record ref references refresh release rename replace resource restrict return " + - "returning reverse revoke rollback row rowid rowlabel rownum rows run " + - "savepoint schema segment select separate session set share snapshot some space split sql start statement " + - "storage subtype successful synonym " + - "tabauth table tables tablespace task terminate then to trigger truncate type " + - "union unique unlimited unrecoverable unusable update use using " + - "validate value values variable view views " + - "when whenever where while with work"; - - var cFunctions = "abs acos add_months ascii asin atan atan2 average " + - "bfilename " + - "ceil chartorowid chr concat convert cos cosh count " + - "decode deref dual dump dup_val_on_index " + - "empty error exp " + - "false floor found " + - "glb greatest " + - "hextoraw " + - "initcap instr instrb isopen " + - "last_day least lenght lenghtb ln lower lpad ltrim lub " + - "make_ref max min mod months_between " + - "new_time next_day nextval nls_charset_decl_len nls_charset_id nls_charset_name nls_initcap nls_lower " + - "nls_sort nls_upper nlssort no_data_found notfound null nvl " + - "others " + - "power " + - "rawtohex reftohex round rowcount rowidtochar rpad rtrim " + - "sign sin sinh soundex sqlcode sqlerrm sqrt stddev substr substrb sum sysdate " + - "tan tanh to_char to_date to_label to_multi_byte to_number to_single_byte translate true trunc " + - "uid upper user userenv " + - "variance vsize"; - - var cTypes = "bfile blob " + - "character clob " + - "dec " + - "float " + - "int integer " + - "mlslabel " + - "natural naturaln nchar nclob number numeric nvarchar2 " + - "real rowtype " + - "signtype smallint string " + - "varchar varchar2"; - - var cSqlplus = "appinfo arraysize autocommit autoprint autorecovery autotrace " + - "blockterminator break btitle " + - "cmdsep colsep compatibility compute concat copycommit copytypecheck " + - "define describe " + - "echo editfile embedded escape exec execute " + - "feedback flagger flush " + - "heading headsep " + - "instance " + - "linesize lno loboffset logsource long longchunksize " + - "markup " + - "native newpage numformat numwidth " + - "pagesize pause pno " + - "recsep recsepchar release repfooter repheader " + - "serveroutput shiftinout show showmode size spool sqlblanklines sqlcase sqlcode sqlcontinue sqlnumber " + - "sqlpluscompatibility sqlprefix sqlprompt sqlterminator suffix " + - "tab term termout time timing trimout trimspool ttitle " + - "underline " + - "verify version " + - "wrap"; - - CodeMirror.defineMIME("text/x-plsql", { - name: "plsql", - keywords: keywords(cKeywords), - functions: keywords(cFunctions), - types: keywords(cTypes), - sqlplus: keywords(cSqlplus) - }); -}()); diff --git a/js/codemirror/mode/python/LICENSE.txt b/js/codemirror/mode/python/LICENSE.txt deleted file mode 100644 index 918866b..0000000 --- a/js/codemirror/mode/python/LICENSE.txt +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License - -Copyright (c) 2010 Timothy Farrell - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. \ No newline at end of file diff --git a/js/codemirror/mode/python/index.html b/js/codemirror/mode/python/index.html deleted file mode 100644 index 1c36643..0000000 --- a/js/codemirror/mode/python/index.html +++ /dev/null @@ -1,123 +0,0 @@ - - - - CodeMirror 2: Python mode - - - - - - - - -

CodeMirror 2: Python mode

- -
- -

Configuration Options:

-
    -
  • version - 2/3 - The version of Python to recognize. Default is 2.
  • -
  • singleLineStringErrors - true/false - If you have a single-line string that is not terminated at the end of the line, this will show subsequent lines as errors if true, otherwise it will consider the newline as the end of the string. Default is false.
  • -
- -

MIME types defined: text/x-python.

- - diff --git a/js/codemirror/mode/python/python.js b/js/codemirror/mode/python/python.js deleted file mode 100644 index 330bfda..0000000 --- a/js/codemirror/mode/python/python.js +++ /dev/null @@ -1,321 +0,0 @@ -CodeMirror.defineMode("python", function(conf, parserConf) { - var ERRORCLASS = 'error'; - - function wordRegexp(words) { - return new RegExp("^((" + words.join(")|(") + "))\\b"); - } - - var singleOperators = new RegExp("^[\\+\\-\\*/%&|\\^~<>!]"); - var singleDelimiters = new RegExp('^[\\(\\)\\[\\]\\{\\}@,:`=;\\.]'); - var doubleOperators = new RegExp("^((==)|(!=)|(<=)|(>=)|(<>)|(<<)|(>>)|(//)|(\\*\\*))"); - var doubleDelimiters = new RegExp("^((\\+=)|(\\-=)|(\\*=)|(%=)|(/=)|(&=)|(\\|=)|(\\^=))"); - var tripleDelimiters = new RegExp("^((//=)|(>>=)|(<<=)|(\\*\\*=))"); - var identifiers = new RegExp("^[_A-Za-z][_A-Za-z0-9]*"); - - var wordOperators = wordRegexp(['and', 'or', 'not', 'is', 'in']); - var commonkeywords = ['as', 'assert', 'break', 'class', 'continue', - 'def', 'del', 'elif', 'else', 'except', 'finally', - 'for', 'from', 'global', 'if', 'import', - 'lambda', 'pass', 'raise', 'return', - 'try', 'while', 'with', 'yield']; - var commontypes = ['bool', 'classmethod', 'complex', 'dict', 'enumerate', - 'float', 'frozenset', 'int', 'list', 'object', - 'property', 'reversed', 'set', 'slice', 'staticmethod', - 'str', 'super', 'tuple', 'type']; - var py2 = {'types': ['basestring', 'buffer', 'file', 'long', 'unicode', - 'xrange'], - 'keywords': ['exec', 'print']}; - var py3 = {'types': ['bytearray', 'bytes', 'filter', 'map', 'memoryview', - 'open', 'range', 'zip'], - 'keywords': ['nonlocal']}; - - if (!!parserConf.version && parseInt(parserConf.version, 10) === 3) { - commonkeywords = commonkeywords.concat(py3.keywords); - commontypes = commontypes.concat(py3.types); - var stringPrefixes = new RegExp("^(([rb]|(br))?('{3}|\"{3}|['\"]))", "i"); - } else { - commonkeywords = commonkeywords.concat(py2.keywords); - commontypes = commontypes.concat(py2.types); - var stringPrefixes = new RegExp("^(([rub]|(ur)|(br))?('{3}|\"{3}|['\"]))", "i"); - } - var keywords = wordRegexp(commonkeywords); - var types = wordRegexp(commontypes); - - var indentInfo = null; - - // tokenizers - function tokenBase(stream, state) { - // Handle scope changes - if (stream.sol()) { - var scopeOffset = state.scopes[0].offset; - if (stream.eatSpace()) { - var lineOffset = stream.indentation(); - if (lineOffset > scopeOffset) { - indentInfo = 'indent'; - } else if (lineOffset < scopeOffset) { - indentInfo = 'dedent'; - } - return null; - } else { - if (scopeOffset > 0) { - dedent(stream, state); - } - } - } - if (stream.eatSpace()) { - return null; - } - - var ch = stream.peek(); - - // Handle Comments - if (ch === '#') { - stream.skipToEnd(); - return 'comment'; - } - - // Handle Number Literals - if (stream.match(/^[0-9\.]/, false)) { - var floatLiteral = false; - // Floats - if (stream.match(/^\d*\.\d+(e[\+\-]?\d+)?/i)) { floatLiteral = true; } - if (stream.match(/^\d+\.\d*/)) { floatLiteral = true; } - if (stream.match(/^\.\d+/)) { floatLiteral = true; } - if (floatLiteral) { - // Float literals may be "imaginary" - stream.eat(/J/i); - return 'number'; - } - // Integers - var intLiteral = false; - // Hex - if (stream.match(/^0x[0-9a-f]+/i)) { intLiteral = true; } - // Binary - if (stream.match(/^0b[01]+/i)) { intLiteral = true; } - // Octal - if (stream.match(/^0o[0-7]+/i)) { intLiteral = true; } - // Decimal - if (stream.match(/^[1-9]\d*(e[\+\-]?\d+)?/)) { - // Decimal literals may be "imaginary" - stream.eat(/J/i); - // TODO - Can you have imaginary longs? - intLiteral = true; - } - // Zero by itself with no other piece of number. - if (stream.match(/^0(?![\dx])/i)) { intLiteral = true; } - if (intLiteral) { - // Integer literals may be "long" - stream.eat(/L/i); - return 'number'; - } - } - - // Handle Strings - if (stream.match(stringPrefixes)) { - state.tokenize = tokenStringFactory(stream.current()); - return state.tokenize(stream, state); - } - - // Handle operators and Delimiters - if (stream.match(tripleDelimiters) || stream.match(doubleDelimiters)) { - return null; - } - if (stream.match(doubleOperators) - || stream.match(singleOperators) - || stream.match(wordOperators)) { - return 'operator'; - } - if (stream.match(singleDelimiters)) { - return null; - } - - if (stream.match(types)) { - return 'builtin'; - } - - if (stream.match(keywords)) { - return 'keyword'; - } - - if (stream.match(identifiers)) { - return 'variable'; - } - - // Handle non-detected items - stream.next(); - return ERRORCLASS; - } - - function tokenStringFactory(delimiter) { - while ('rub'.indexOf(delimiter.charAt(0).toLowerCase()) >= 0) { - delimiter = delimiter.substr(1); - } - var delim_re = new RegExp(delimiter); - var singleline = delimiter.length == 1; - var OUTCLASS = 'string'; - - return function tokenString(stream, state) { - while (!stream.eol()) { - stream.eatWhile(/[^'"\\]/); - if (stream.eat('\\')) { - stream.next(); - if (singleline && stream.eol()) { - return OUTCLASS; - } - } else if (stream.match(delim_re)) { - state.tokenize = tokenBase; - return OUTCLASS; - } else { - stream.eat(/['"]/); - } - } - if (singleline) { - if (parserConf.singleLineStringErrors) { - return ERRORCLASS; - } else { - state.tokenize = tokenBase; - } - } - return OUTCLASS; - }; - } - - function indent(stream, state, type) { - type = type || 'py'; - var indentUnit = 0; - if (type === 'py') { - for (var i = 0; i < state.scopes.length; ++i) { - if (state.scopes[i].type === 'py') { - indentUnit = state.scopes[i].offset + conf.indentUnit; - break; - } - } - } else { - indentUnit = stream.column() + stream.current().length; - } - state.scopes.unshift({ - offset: indentUnit, - type: type - }); - } - - function dedent(stream, state) { - if (state.scopes.length == 1) return; - if (state.scopes[0].type === 'py') { - var _indent = stream.indentation(); - var _indent_index = -1; - for (var i = 0; i < state.scopes.length; ++i) { - if (_indent === state.scopes[i].offset) { - _indent_index = i; - break; - } - } - if (_indent_index === -1) { - return true; - } - while (state.scopes[0].offset !== _indent) { - state.scopes.shift(); - } - return false - } else { - state.scopes.shift(); - return false; - } - } - - function tokenLexer(stream, state) { - indentInfo = null; - var style = state.tokenize(stream, state); - var current = stream.current(); - - // Handle '.' connected identifiers - if (current === '.') { - style = state.tokenize(stream, state); - current = stream.current(); - if (style === 'variable') { - return 'variable'; - } else { - return ERRORCLASS; - } - } - - // Handle decorators - if (current === '@') { - style = state.tokenize(stream, state); - current = stream.current(); - if (style === 'variable' - || current === '@staticmethod' - || current === '@classmethod') { - return 'meta'; - } else { - return ERRORCLASS; - } - } - - // Handle scope changes. - if (current === 'pass' || current === 'return') { - state.dedent += 1; - } - if ((current === ':' && !state.lambda && state.scopes[0].type == 'py') - || indentInfo === 'indent') { - indent(stream, state); - } - var delimiter_index = '[({'.indexOf(current); - if (delimiter_index !== -1) { - indent(stream, state, '])}'.slice(delimiter_index, delimiter_index+1)); - } - if (indentInfo === 'dedent') { - if (dedent(stream, state)) { - return ERRORCLASS; - } - } - delimiter_index = '])}'.indexOf(current); - if (delimiter_index !== -1) { - if (dedent(stream, state)) { - return ERRORCLASS; - } - } - if (state.dedent > 0 && stream.eol() && state.scopes[0].type == 'py') { - if (state.scopes.length > 1) state.scopes.shift(); - state.dedent -= 1; - } - - return style; - } - - var external = { - startState: function(basecolumn) { - return { - tokenize: tokenBase, - scopes: [{offset:basecolumn || 0, type:'py'}], - lastToken: null, - lambda: false, - dedent: 0 - }; - }, - - token: function(stream, state) { - var style = tokenLexer(stream, state); - - state.lastToken = {style:style, content: stream.current()}; - - if (stream.eol() && stream.lambda) { - state.lambda = false; - } - - return style; - }, - - indent: function(state, textAfter) { - if (state.tokenize != tokenBase) { - return 0; - } - - return state.scopes[0].offset; - } - - }; - return external; -}); - -CodeMirror.defineMIME("text/x-python", "python"); diff --git a/js/codemirror/mode/r/LICENSE b/js/codemirror/mode/r/LICENSE deleted file mode 100644 index 2510ae1..0000000 --- a/js/codemirror/mode/r/LICENSE +++ /dev/null @@ -1,24 +0,0 @@ -Copyright (c) 2011, Ubalo, Inc. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of the Ubalo, Inc nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL UBALO, INC BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/js/codemirror/mode/r/index.html b/js/codemirror/mode/r/index.html deleted file mode 100644 index 8ba3ef1..0000000 --- a/js/codemirror/mode/r/index.html +++ /dev/null @@ -1,74 +0,0 @@ - - - - CodeMirror 2: R mode - - - - - - - - -

CodeMirror 2: R mode

-
- - -

MIME types defined: text/x-rsrc.

- -

Development of the CodeMirror R mode was kindly sponsored - by Ubalo, who hold - the license.

- - - diff --git a/js/codemirror/mode/r/r.js b/js/codemirror/mode/r/r.js deleted file mode 100644 index 53647f2..0000000 --- a/js/codemirror/mode/r/r.js +++ /dev/null @@ -1,141 +0,0 @@ -CodeMirror.defineMode("r", function(config) { - function wordObj(str) { - var words = str.split(" "), res = {}; - for (var i = 0; i < words.length; ++i) res[words[i]] = true; - return res; - } - var atoms = wordObj("NULL NA Inf NaN NA_integer_ NA_real_ NA_complex_ NA_character_"); - var builtins = wordObj("list quote bquote eval return call parse deparse"); - var keywords = wordObj("if else repeat while function for in next break"); - var blockkeywords = wordObj("if else repeat while function for"); - var opChars = /[+\-*\/^<>=!&|~$:]/; - var curPunc; - - function tokenBase(stream, state) { - curPunc = null; - var ch = stream.next(); - if (ch == "#") { - stream.skipToEnd(); - return "comment"; - } else if (ch == "0" && stream.eat("x")) { - stream.eatWhile(/[\da-f]/i); - return "number"; - } else if (ch == "." && stream.eat(/\d/)) { - stream.match(/\d*(?:e[+\-]?\d+)?/); - return "number"; - } else if (/\d/.test(ch)) { - stream.match(/\d*(?:\.\d+)?(?:e[+\-]\d+)?L?/); - return "number"; - } else if (ch == "'" || ch == '"') { - state.tokenize = tokenString(ch); - return "string"; - } else if (ch == "." && stream.match(/.[.\d]+/)) { - return "keyword"; - } else if (/[\w\.]/.test(ch) && ch != "_") { - stream.eatWhile(/[\w\.]/); - var word = stream.current(); - if (atoms.propertyIsEnumerable(word)) return "atom"; - if (keywords.propertyIsEnumerable(word)) { - if (blockkeywords.propertyIsEnumerable(word)) curPunc = "block"; - return "keyword"; - } - if (builtins.propertyIsEnumerable(word)) return "builtin"; - return "variable"; - } else if (ch == "%") { - if (stream.skipTo("%")) stream.next(); - return "variable-2"; - } else if (ch == "<" && stream.eat("-")) { - return "arrow"; - } else if (ch == "=" && state.ctx.argList) { - return "arg-is"; - } else if (opChars.test(ch)) { - if (ch == "$") return "dollar"; - stream.eatWhile(opChars); - return "operator"; - } else if (/[\(\){}\[\];]/.test(ch)) { - curPunc = ch; - if (ch == ";") return "semi"; - return null; - } else { - return null; - } - } - - function tokenString(quote) { - return function(stream, state) { - if (stream.eat("\\")) { - var ch = stream.next(); - if (ch == "x") stream.match(/^[a-f0-9]{2}/i); - else if ((ch == "u" || ch == "U") && stream.eat("{") && stream.skipTo("}")) stream.next(); - else if (ch == "u") stream.match(/^[a-f0-9]{4}/i); - else if (ch == "U") stream.match(/^[a-f0-9]{8}/i); - else if (/[0-7]/.test(ch)) stream.match(/^[0-7]{1,2}/); - return "string-2"; - } else { - var next; - while ((next = stream.next()) != null) { - if (next == quote) { state.tokenize = tokenBase; break; } - if (next == "\\") { stream.backUp(1); break; } - } - return "string"; - } - }; - } - - function push(state, type, stream) { - state.ctx = {type: type, - indent: state.indent, - align: null, - column: stream.column(), - prev: state.ctx}; - } - function pop(state) { - state.indent = state.ctx.indent; - state.ctx = state.ctx.prev; - } - - return { - startState: function(base) { - return {tokenize: tokenBase, - ctx: {type: "top", - indent: -config.indentUnit, - align: false}, - indent: 0, - afterIdent: false}; - }, - - token: function(stream, state) { - if (stream.sol()) { - if (state.ctx.align == null) state.ctx.align = false; - state.indent = stream.indentation(); - } - if (stream.eatSpace()) return null; - var style = state.tokenize(stream, state); - if (style != "comment" && state.ctx.align == null) state.ctx.align = true; - - var ctype = state.ctx.type; - if ((curPunc == ";" || curPunc == "{" || curPunc == "}") && ctype == "block") pop(state); - if (curPunc == "{") push(state, "}", stream); - else if (curPunc == "(") { - push(state, ")", stream); - if (state.afterIdent) state.ctx.argList = true; - } - else if (curPunc == "[") push(state, "]", stream); - else if (curPunc == "block") push(state, "block", stream); - else if (curPunc == ctype) pop(state); - state.afterIdent = style == "variable" || style == "keyword"; - return style; - }, - - indent: function(state, textAfter) { - if (state.tokenize != tokenBase) return 0; - var firstChar = textAfter && textAfter.charAt(0), ctx = state.ctx, - closing = firstChar == ctx.type; - if (ctx.type == "block") return ctx.indent + (firstChar == "{" ? 0 : config.indentUnit); - else if (ctx.align) return ctx.column + (closing ? 0 : 1); - else return ctx.indent + (closing ? 0 : config.indentUnit); - } - }; -}); - -CodeMirror.defineMIME("text/x-rsrc", "r"); diff --git a/js/codemirror/mode/rst/index.html b/js/codemirror/mode/rst/index.html deleted file mode 100644 index 0831dff..0000000 --- a/js/codemirror/mode/rst/index.html +++ /dev/null @@ -1,526 +0,0 @@ - - - - CodeMirror 2: reStructuredText mode - - - - - - - - -

CodeMirror 2: reStructuredText mode

- -
- - -

The reStructuredText mode supports one configuration parameter:

-
-
verbatim (string)
-
A name or MIME type of a mode that will be used for highlighting - verbatim blocks. By default, reStructuredText mode uses uniform color - for whole block of verbatim text if no mode is given.
-
-

If python mode is available (not a part of CodeMirror 2 yet), - it will be used for highlighting blocks containing Python/IPython terminal - sessions (blocks starting with >>> (for Python) or - In [num]: (for IPython). - -

MIME types defined: text/x-rst.

- - - diff --git a/js/codemirror/mode/rst/rst.css b/js/codemirror/mode/rst/rst.css deleted file mode 100644 index 235a5d8..0000000 --- a/js/codemirror/mode/rst/rst.css +++ /dev/null @@ -1,75 +0,0 @@ -.cm-s-default span.cm-emphasis { - font-style: italic; -} - -.cm-s-default span.cm-strong { - font-weight: bold; -} - -.cm-s-default span.cm-interpreted { - color: #33cc66; -} - -.cm-s-default span.cm-inline { - color: #3399cc; -} - -.cm-s-default span.cm-role { - color: #666699; -} - -.cm-s-default span.cm-list { - color: #cc0099; - font-weight: bold; -} - -.cm-s-default span.cm-body { - color: #6699cc; -} - -.cm-s-default span.cm-verbatim { - color: #3366ff; -} - -.cm-s-default span.cm-comment { - color: #aa7700; -} - -.cm-s-default span.cm-directive { - font-weight: bold; - color: #3399ff; -} - -.cm-s-default span.cm-hyperlink { - font-weight: bold; - color: #3366ff; -} - -.cm-s-default span.cm-footnote { - font-weight: bold; - color: #3333ff; -} - -.cm-s-default span.cm-citation { - font-weight: bold; - color: #3300ff; -} - -.cm-s-default span.cm-replacement { - color: #9933cc; -} - -.cm-s-default span.cm-section { - font-weight: bold; - color: #cc0099; -} - -.cm-s-default span.cm-directive-marker { - font-weight: bold; - color: #3399ff; -} - -.cm-s-default span.cm-verbatim-marker { - font-weight: bold; - color: #9900ff; -} diff --git a/js/codemirror/mode/rst/rst.js b/js/codemirror/mode/rst/rst.js deleted file mode 100644 index eecc5be..0000000 --- a/js/codemirror/mode/rst/rst.js +++ /dev/null @@ -1,333 +0,0 @@ -CodeMirror.defineMode('rst', function(config, options) { - function setState(state, fn, ctx) { - state.fn = fn; - setCtx(state, ctx); - } - - function setCtx(state, ctx) { - state.ctx = ctx || {}; - } - - function setNormal(state, ch) { - if (ch && (typeof ch !== 'string')) { - var str = ch.current(); - ch = str[str.length-1]; - } - - setState(state, normal, {back: ch}); - } - - function hasMode(mode) { - if (mode) { - var modes = CodeMirror.listModes(); - - for (var i in modes) { - if (modes[i] == mode) { - return true; - } - } - } - - return false; - } - - function getMode(mode) { - if (hasMode(mode)) { - return CodeMirror.getMode(config, mode); - } else { - return null; - } - } - - var verbatimMode = getMode(options.verbatim); - var pythonMode = getMode('python'); - - var reSection = /^[!"#$%&'()*+,-./:;<=>?@[\\\]^_`{|}~]/; - var reDirective = /^\s*\w([-:.\w]*\w)?::(\s|$)/; - var reHyperlink = /^\s*_[\w-]+:(\s|$)/; - var reFootnote = /^\s*\[(\d+|#)\](\s|$)/; - var reCitation = /^\s*\[[A-Za-z][\w-]*\](\s|$)/; - var reFootnoteRef = /^\[(\d+|#)\]_/; - var reCitationRef = /^\[[A-Za-z][\w-]*\]_/; - var reDirectiveMarker = /^\.\.(\s|$)/; - var reVerbatimMarker = /^::\s*$/; - var rePreInline = /^[-\s"([{/:.,;!?\\_]/; - var reEnumeratedList = /^\s*((\d+|[A-Za-z#])[.)]|\((\d+|[A-Z-a-z#])\))\s/; - var reBulletedList = /^\s*[-\+\*]\s/; - var reExamples = /^\s+(>>>|In \[\d+\]:)\s/; - - function normal(stream, state) { - var ch, sol, i; - - if (stream.eat(/\\/)) { - ch = stream.next(); - setNormal(state, ch); - return null; - } - - sol = stream.sol(); - - if (sol && (ch = stream.eat(reSection))) { - for (i = 0; stream.eat(ch); i++); - - if (i >= 3 && stream.match(/^\s*$/)) { - setNormal(state, null); - return 'section'; - } else { - stream.backUp(i + 1); - } - } - - if (sol && stream.match(reDirectiveMarker)) { - if (!stream.eol()) { - setState(state, directive); - } - - return 'directive-marker'; - } - - if (stream.match(reVerbatimMarker)) { - if (!verbatimMode) { - setState(state, verbatim); - } else { - var mode = verbatimMode; - - setState(state, verbatim, { - mode: mode, - local: mode.startState() - }); - } - - return 'verbatim-marker'; - } - - if (sol && stream.match(reExamples, false)) { - if (!pythonMode) { - setState(state, verbatim); - return 'verbatim-marker'; - } else { - var mode = pythonMode; - - setState(state, verbatim, { - mode: mode, - local: mode.startState() - }); - - return null; - } - } - - if (sol && (stream.match(reEnumeratedList) || - stream.match(reBulletedList))) { - setNormal(state, stream); - return 'list'; - } - - function testBackward(re) { - return sol || !state.ctx.back || re.test(state.ctx.back); - } - - function testForward(re) { - return stream.eol() || stream.match(re, false); - } - - function testInline(re) { - return stream.match(re) && testBackward(/\W/) && testForward(/\W/); - } - - if (testInline(reFootnoteRef)) { - setNormal(state, stream); - return 'footnote'; - } - - if (testInline(reCitationRef)) { - setNormal(state, stream); - return 'citation'; - } - - ch = stream.next(); - - if (testBackward(rePreInline)) { - if ((ch === ':' || ch === '|') && stream.eat(/\S/)) { - var token; - - if (ch === ':') { - token = 'role'; - } else { - token = 'replacement'; - } - - setState(state, inline, { - ch: ch, - wide: false, - prev: null, - token: token - }); - - return token; - } - - if (ch === '*' || ch === '`') { - var orig = ch, - wide = false; - - ch = stream.next(); - - if (ch == orig) { - wide = true; - ch = stream.next(); - } - - if (ch && !/\s/.test(ch)) { - var token; - - if (orig === '*') { - token = wide ? 'strong' : 'emphasis'; - } else { - token = wide ? 'inline' : 'interpreted'; - } - - setState(state, inline, { - ch: orig, // inline() has to know what to search for - wide: wide, // are we looking for `ch` or `chch` - prev: null, // terminator must not be preceeded with whitespace - token: token // I don't want to recompute this all the time - }); - - return token; - } - } - } - - setNormal(state, ch); - return null; - } - - function inline(stream, state) { - var ch = stream.next(), - token = state.ctx.token; - - function finish(ch) { - state.ctx.prev = ch; - return token; - } - - if (ch != state.ctx.ch) { - return finish(ch); - } - - if (/\s/.test(state.ctx.prev)) { - return finish(ch); - } - - if (state.ctx.wide) { - ch = stream.next(); - - if (ch != state.ctx.ch) { - return finish(ch); - } - } - - if (!stream.eol() && !rePostInline.test(stream.peek())) { - if (state.ctx.wide) { - stream.backUp(1); - } - - return finish(ch); - } - - setState(state, normal); - setNormal(state, ch); - - return token; - } - - function directive(stream, state) { - var token = null; - - if (stream.match(reDirective)) { - token = 'directive'; - } else if (stream.match(reHyperlink)) { - token = 'hyperlink'; - } else if (stream.match(reFootnote)) { - token = 'footnote'; - } else if (stream.match(reCitation)) { - token = 'citation'; - } else { - stream.eatSpace(); - - if (stream.eol()) { - setNormal(state, stream); - return null; - } else { - stream.skipToEnd(); - setState(state, comment); - return 'comment'; - } - } - - setState(state, body, {start: true}); - return token; - } - - function body(stream, state) { - var token = 'body'; - - if (!state.ctx.start || stream.sol()) { - return block(stream, state, token); - } - - stream.skipToEnd(); - setCtx(state); - - return token; - } - - function comment(stream, state) { - return block(stream, state, 'comment'); - } - - function verbatim(stream, state) { - if (!verbatimMode) { - return block(stream, state, 'verbatim'); - } else { - if (stream.sol()) { - if (!stream.eatSpace()) { - setNormal(state, stream); - } - - return null; - } - - return verbatimMode.token(stream, state.ctx.local); - } - } - - function block(stream, state, token) { - if (stream.eol() || stream.eatSpace()) { - stream.skipToEnd(); - return token; - } else { - setNormal(state, stream); - return null; - } - } - - return { - startState: function() { - return {fn: normal, ctx: {}}; - }, - - copyState: function(state) { - return {fn: state.fn, ctx: state.ctx}; - }, - - token: function(stream, state) { - var token = state.fn(stream, state); - return token; - } - }; -}); - -CodeMirror.defineMIME("text/x-rst", "rst"); diff --git a/js/codemirror/mode/ruby/LICENSE b/js/codemirror/mode/ruby/LICENSE deleted file mode 100644 index ac09fc4..0000000 --- a/js/codemirror/mode/ruby/LICENSE +++ /dev/null @@ -1,24 +0,0 @@ -Copyright (c) 2011, Ubalo, Inc. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of the Ubalo, Inc. nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL UBALO, INC BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/js/codemirror/mode/ruby/index.html b/js/codemirror/mode/ruby/index.html deleted file mode 100644 index babc37e..0000000 --- a/js/codemirror/mode/ruby/index.html +++ /dev/null @@ -1,172 +0,0 @@ - - - - CodeMirror 2: Ruby mode - - - - - - - - -

CodeMirror 2: Ruby mode

-
- - -

MIME types defined: text/x-ruby.

- -

Development of the CodeMirror Ruby mode was kindly sponsored - by Ubalo, who hold - the license.

- - - diff --git a/js/codemirror/mode/ruby/ruby.js b/js/codemirror/mode/ruby/ruby.js deleted file mode 100644 index ddc1a65..0000000 --- a/js/codemirror/mode/ruby/ruby.js +++ /dev/null @@ -1,195 +0,0 @@ -CodeMirror.defineMode("ruby", function(config, parserConfig) { - function wordObj(words) { - var o = {}; - for (var i = 0, e = words.length; i < e; ++i) o[words[i]] = true; - return o; - } - var keywords = wordObj([ - "alias", "and", "BEGIN", "begin", "break", "case", "class", "def", "defined?", "do", "else", - "elsif", "END", "end", "ensure", "false", "for", "if", "in", "module", "next", "not", "or", - "redo", "rescue", "retry", "return", "self", "super", "then", "true", "undef", "unless", - "until", "when", "while", "yield", "nil", "raise", "throw", "catch", "fail", "loop", "callcc", - "caller", "lambda", "proc", "public", "protected", "private", "require", "load", - "require_relative", "extend", "autoload" - ]); - var indentWords = wordObj(["def", "class", "case", "for", "while", "do", "module", "then", - "unless", "catch", "loop", "proc"]); - var dedentWords = wordObj(["end", "until"]); - var matching = {"[": "]", "{": "}", "(": ")"}; - var curPunc; - - function chain(newtok, stream, state) { - state.tokenize.push(newtok); - return newtok(stream, state); - } - - function tokenBase(stream, state) { - curPunc = null; - if (stream.sol() && stream.match("=begin") && stream.eol()) { - state.tokenize.push(readBlockComment); - return "comment"; - } - if (stream.eatSpace()) return null; - var ch = stream.next(); - if (ch == "`" || ch == "'" || ch == '"' || ch == "/") { - return chain(readQuoted(ch, "string", ch == '"'), stream, state); - } else if (ch == "%") { - var style, embed = false; - if (stream.eat("s")) style = "atom"; - else if (stream.eat(/[WQ]/)) { style = "string"; embed = true; } - else if (stream.eat(/[wxqr]/)) style = "string"; - var delim = stream.eat(/[^\w\s]/); - if (!delim) return "operator"; - if (matching.propertyIsEnumerable(delim)) delim = matching[delim]; - return chain(readQuoted(delim, style, embed, true), stream, state); - } else if (ch == "#") { - stream.skipToEnd(); - return "comment"; - } else if (ch == "<" && stream.eat("<")) { - stream.eat("-"); - stream.eat(/[\'\"\`]/); - var match = stream.match(/^\w+/); - stream.eat(/[\'\"\`]/); - if (match) return chain(readHereDoc(match[0]), stream, state); - return null; - } else if (ch == "0") { - if (stream.eat("x")) stream.eatWhile(/[\da-fA-F]/); - else if (stream.eat("b")) stream.eatWhile(/[01]/); - else stream.eatWhile(/[0-7]/); - return "number"; - } else if (/\d/.test(ch)) { - stream.match(/^[\d_]*(?:\.[\d_]+)?(?:[eE][+\-]?[\d_]+)?/); - return "number"; - } else if (ch == "?") { - while (stream.match(/^\\[CM]-/)) {} - if (stream.eat("\\")) stream.eatWhile(/\w/); - else stream.next(); - return "string"; - } else if (ch == ":") { - if (stream.eat("'")) return chain(readQuoted("'", "atom", false), stream, state); - if (stream.eat('"')) return chain(readQuoted('"', "atom", true), stream, state); - stream.eatWhile(/[\w\?]/); - return "atom"; - } else if (ch == "@") { - stream.eat("@"); - stream.eatWhile(/[\w\?]/); - return "variable-2"; - } else if (ch == "$") { - stream.next(); - stream.eatWhile(/[\w\?]/); - return "variable-3"; - } else if (/\w/.test(ch)) { - stream.eatWhile(/[\w\?]/); - if (stream.eat(":")) return "atom"; - return "ident"; - } else if (ch == "|" && (state.varList || state.lastTok == "{" || state.lastTok == "do")) { - curPunc = "|"; - return null; - } else if (/[\(\)\[\]{}\\;]/.test(ch)) { - curPunc = ch; - return null; - } else if (ch == "-" && stream.eat(">")) { - return "arrow"; - } else if (/[=+\-\/*:\.^%<>~|]/.test(ch)) { - stream.eatWhile(/[=+\-\/*:\.^%<>~|]/); - return "operator"; - } else { - return null; - } - } - - function tokenBaseUntilBrace() { - var depth = 1; - return function(stream, state) { - if (stream.peek() == "}") { - depth--; - if (depth == 0) { - state.tokenize.pop(); - return state.tokenize[state.tokenize.length-1](stream, state); - } - } else if (stream.peek() == "{") { - depth++; - } - return tokenBase(stream, state); - }; - } - function readQuoted(quote, style, embed, unescaped) { - return function(stream, state) { - var escaped = false, ch; - while ((ch = stream.next()) != null) { - if (ch == quote && (unescaped || !escaped)) { - state.tokenize.pop(); - break; - } - if (embed && ch == "#" && !escaped && stream.eat("{")) { - state.tokenize.push(tokenBaseUntilBrace(arguments.callee)); - break; - } - escaped = !escaped && ch == "\\"; - } - return style; - }; - } - function readHereDoc(phrase) { - return function(stream, state) { - if (stream.match(phrase)) state.tokenize.pop(); - else stream.skipToEnd(); - return "string"; - }; - } - function readBlockComment(stream, state) { - if (stream.sol() && stream.match("=end") && stream.eol()) - state.tokenize.pop(); - stream.skipToEnd(); - return "comment"; - } - - return { - startState: function() { - return {tokenize: [tokenBase], - indented: 0, - context: {type: "top", indented: -config.indentUnit}, - continuedLine: false, - lastTok: null, - varList: false}; - }, - - token: function(stream, state) { - if (stream.sol()) state.indented = stream.indentation(); - var style = state.tokenize[state.tokenize.length-1](stream, state), kwtype; - if (style == "ident") { - var word = stream.current(); - style = keywords.propertyIsEnumerable(stream.current()) ? "keyword" - : /^[A-Z]/.test(word) ? "tag" - : (state.lastTok == "def" || state.lastTok == "class" || state.varList) ? "def" - : "variable"; - if (indentWords.propertyIsEnumerable(word)) kwtype = "indent"; - else if (dedentWords.propertyIsEnumerable(word)) kwtype = "dedent"; - else if (word == "if" && stream.column() == stream.indentation()) kwtype = "indent"; - } - if (curPunc || (style && style != "comment")) state.lastTok = word || curPunc || style; - if (curPunc == "|") state.varList = !state.varList; - - if (kwtype == "indent" || /[\(\[\{]/.test(curPunc)) - state.context = {prev: state.context, type: curPunc || style, indented: state.indented}; - else if ((kwtype == "dedent" || /[\)\]\}]/.test(curPunc)) && state.context.prev) - state.context = state.context.prev; - - if (stream.eol()) - state.continuedLine = (curPunc == "\\" || style == "operator"); - return style; - }, - - indent: function(state, textAfter) { - if (state.tokenize[state.tokenize.length-1] != tokenBase) return 0; - var firstChar = textAfter && textAfter.charAt(0); - var ct = state.context; - var closing = ct.type == matching[firstChar] || - ct.type == "keyword" && /^(?:end|until|else|elsif|when)\b/.test(textAfter); - return ct.indented + (closing ? 0 : config.indentUnit) + - (state.continuedLine ? config.indentUnit : 0); - } - }; -}); - -CodeMirror.defineMIME("text/x-ruby", "ruby"); diff --git a/js/codemirror/mode/scheme/index.html b/js/codemirror/mode/scheme/index.html deleted file mode 100644 index 3240232..0000000 --- a/js/codemirror/mode/scheme/index.html +++ /dev/null @@ -1,65 +0,0 @@ - - - - CodeMirror 2: Scheme mode - - - - - - - - -

CodeMirror 2: Scheme mode

-
- - -

MIME types defined: text/x-scheme.

- - - diff --git a/js/codemirror/mode/scheme/scheme.js b/js/codemirror/mode/scheme/scheme.js deleted file mode 100644 index caf78db..0000000 --- a/js/codemirror/mode/scheme/scheme.js +++ /dev/null @@ -1,202 +0,0 @@ -/** - * Author: Koh Zi Han, based on implementation by Koh Zi Chun - */ -CodeMirror.defineMode("scheme", function (config, mode) { - var BUILTIN = "builtin", COMMENT = "comment", STRING = "string", - ATOM = "atom", NUMBER = "number", BRACKET = "bracket", KEYWORD="keyword"; - var INDENT_WORD_SKIP = 2, KEYWORDS_SKIP = 1; - - function makeKeywords(str) { - var obj = {}, words = str.split(" "); - for (var i = 0; i < words.length; ++i) obj[words[i]] = true; - return obj; - } - - var keywords = makeKeywords("λ case-lambda call/cc class define-class exit-handler field import inherit init-field interface let*-values let-values let/ec mixin opt-lambda override protect provide public rename require require-for-syntax syntax syntax-case syntax-error unit/sig unless when with-syntax and begin call-with-current-continuation call-with-input-file call-with-output-file case cond define define-syntax delay do dynamic-wind else for-each if lambda let let* let-syntax letrec letrec-syntax map or syntax-rules abs acos angle append apply asin assoc assq assv atan boolean? caar cadr call-with-input-file call-with-output-file call-with-values car cdddar cddddr cdr ceiling char->integer char-alphabetic? char-ci<=? char-ci=? char-ci>? char-downcase char-lower-case? char-numeric? char-ready? char-upcase char-upper-case? char-whitespace? char<=? char=? char>? char? close-input-port close-output-port complex? cons cos current-input-port current-output-port denominator display eof-object? eq? equal? eqv? eval even? exact->inexact exact? exp expt #f floor force gcd imag-part inexact->exact inexact? input-port? integer->char integer? interaction-environment lcm length list list->string list->vector list-ref list-tail list? load log magnitude make-polar make-rectangular make-string make-vector max member memq memv min modulo negative? newline not null-environment null? number->string number? numerator odd? open-input-file open-output-file output-port? pair? peek-char port? positive? procedure? quasiquote quote quotient rational? rationalize read read-char real-part real? remainder reverse round scheme-report-environment set! set-car! set-cdr! sin sqrt string string->list string->number string->symbol string-append string-ci<=? string-ci=? string-ci>? string-copy string-fill! string-length string-ref string-set! string<=? string=? string>? string? substring symbol->string symbol? #t tan transcript-off transcript-on truncate values vector vector->list vector-fill! vector-length vector-ref vector-set! with-input-from-file with-output-to-file write write-char zero?"); - var indentKeys = makeKeywords("define let letrec let* lambda"); - - - function stateStack(indent, type, prev) { // represents a state stack object - this.indent = indent; - this.type = type; - this.prev = prev; - } - - function pushStack(state, indent, type) { - state.indentStack = new stateStack(indent, type, state.indentStack); - } - - function popStack(state) { - state.indentStack = state.indentStack.prev; - } - - /** - * Scheme numbers are complicated unfortunately. - * Checks if we're looking at a number, which might be possibly a fraction. - * Also checks that it is not part of a longer identifier. Returns true/false accordingly. - */ - function isNumber(ch, stream){ - if(/[0-9]/.exec(ch) != null){ - stream.eatWhile(/[0-9]/); - stream.eat(/\//); - stream.eatWhile(/[0-9]/); - if (stream.eol() || !(/[a-zA-Z\-\_\/]/.exec(stream.peek()))) return true; - stream.backUp(stream.current().length - 1); // undo all the eating - } - return false; - } - - return { - startState: function () { - return { - indentStack: null, - indentation: 0, - mode: false, - sExprComment: false - }; - }, - - token: function (stream, state) { - if (state.indentStack == null && stream.sol()) { - // update indentation, but only if indentStack is empty - state.indentation = stream.indentation(); - } - - // skip spaces - if (stream.eatSpace()) { - return null; - } - var returnType = null; - - switch(state.mode){ - case "string": // multi-line string parsing mode - var next, escaped = false; - while ((next = stream.next()) != null) { - if (next == "\"" && !escaped) { - - state.mode = false; - break; - } - escaped = !escaped && next == "\\"; - } - returnType = STRING; // continue on in scheme-string mode - break; - case "comment": // comment parsing mode - var next, maybeEnd = false; - while ((next = stream.next()) != null) { - if (next == "#" && maybeEnd) { - - state.mode = false; - break; - } - maybeEnd = (next == "|"); - } - returnType = COMMENT; - break; - case "s-expr-comment": // s-expr commenting mode - state.mode = false; - if(stream.peek() == "(" || stream.peek() == "["){ - // actually start scheme s-expr commenting mode - state.sExprComment = 0; - }else{ - // if not we just comment the entire of the next token - stream.eatWhile(/[^/s]/); // eat non spaces - returnType = COMMENT; - break; - } - default: // default parsing mode - var ch = stream.next(); - - if (ch == "\"") { - state.mode = "string"; - returnType = STRING; - - } else if (ch == "'") { - returnType = ATOM; - } else if (ch == '#') { - if (stream.eat("|")) { // Multi-line comment - state.mode = "comment"; // toggle to comment mode - returnType = COMMENT; - } else if (stream.eat(/[tf]/)) { // #t/#f (atom) - returnType = ATOM; - } else if (stream.eat(';')) { // S-Expr comment - state.mode = "s-expr-comment"; - returnType = COMMENT; - } - - } else if (ch == ";") { // comment - stream.skipToEnd(); // rest of the line is a comment - returnType = COMMENT; - } else if (ch == "-"){ - - if(!isNaN(parseInt(stream.peek()))){ - stream.eatWhile(/[\/0-9]/); - returnType = NUMBER; - }else{ - returnType = null; - } - } else if (isNumber(ch,stream)){ - returnType = NUMBER; - } else if (ch == "(" || ch == "[") { - var keyWord = ''; var indentTemp = stream.column(); - /** - Either - (indent-word .. - (non-indent-word .. - (;something else, bracket, etc. - */ - - while ((letter = stream.eat(/[^\s\(\[\;\)\]]/)) != null) { - keyWord += letter; - } - - if (keyWord.length > 0 && indentKeys.propertyIsEnumerable(keyWord)) { // indent-word - - pushStack(state, indentTemp + INDENT_WORD_SKIP, ch); - } else { // non-indent word - // we continue eating the spaces - stream.eatSpace(); - if (stream.eol() || stream.peek() == ";") { - // nothing significant after - // we restart indentation 1 space after - pushStack(state, indentTemp + 1, ch); - } else { - pushStack(state, indentTemp + stream.current().length, ch); // else we match - } - } - stream.backUp(stream.current().length - 1); // undo all the eating - - if(typeof state.sExprComment == "number") state.sExprComment++; - - returnType = BRACKET; - } else if (ch == ")" || ch == "]") { - returnType = BRACKET; - if (state.indentStack != null && state.indentStack.type == (ch == ")" ? "(" : "[")) { - popStack(state); - - if(typeof state.sExprComment == "number"){ - if(--state.sExprComment == 0){ - returnType = COMMENT; // final closing bracket - state.sExprComment = false; // turn off s-expr commenting mode - } - } - } - } else { - stream.eatWhile(/[\w\$_\-]/); - - if (keywords && keywords.propertyIsEnumerable(stream.current())) { - returnType = BUILTIN; - }else returnType = null; - } - } - return (typeof state.sExprComment == "number") ? COMMENT : returnType; - }, - - indent: function (state, textAfter) { - if (state.indentStack == null) return state.indentation; - return state.indentStack.indent; - } - }; -}); - -CodeMirror.defineMIME("text/x-scheme", "scheme"); \ No newline at end of file diff --git a/js/codemirror/mode/smalltalk/index.html b/js/codemirror/mode/smalltalk/index.html deleted file mode 100644 index 67cb22b..0000000 --- a/js/codemirror/mode/smalltalk/index.html +++ /dev/null @@ -1,56 +0,0 @@ - - - - CodeMirror 2: Smalltalk mode - - - - - - - - -

CodeMirror 2: Smalltalk mode

- -
- - - -

Simple Smalltalk mode.

- -

MIME types defined: text/x-stsrc.

- - diff --git a/js/codemirror/mode/smalltalk/smalltalk.js b/js/codemirror/mode/smalltalk/smalltalk.js deleted file mode 100644 index a5b14e1..0000000 --- a/js/codemirror/mode/smalltalk/smalltalk.js +++ /dev/null @@ -1,122 +0,0 @@ -CodeMirror.defineMode("smalltalk", function(config, parserConfig) { - var keywords = {"true": 1, "false": 1, nil: 1, self: 1, "super": 1, thisContext: 1}; - var indentUnit = config.indentUnit; - - function chain(stream, state, f) { - state.tokenize = f; - return f(stream, state); - } - - var type; - function ret(tp, style) { - type = tp; - return style; - } - - function tokenBase(stream, state) { - var ch = stream.next(); - if (ch == '"') - return chain(stream, state, tokenComment(ch)); - else if (ch == "'") - return chain(stream, state, tokenString(ch)); - else if (ch == "#") { - stream.eatWhile(/[\w\$_]/); - return ret("string", "string"); - } - else if (/\d/.test(ch)) { - stream.eatWhile(/[\w\.]/) - return ret("number", "number"); - } - else if (/[\[\]()]/.test(ch)) { - return ret(ch, null); - } - else { - stream.eatWhile(/[\w\$_]/); - if (keywords && keywords.propertyIsEnumerable(stream.current())) return ret("keyword", "keyword"); - return ret("word", "variable"); - } - } - - function tokenString(quote) { - return function(stream, state) { - var escaped = false, next, end = false; - while ((next = stream.next()) != null) { - if (next == quote && !escaped) {end = true; break;} - escaped = !escaped && next == "\\"; - } - if (end || !(escaped)) - state.tokenize = tokenBase; - return ret("string", "string"); - }; - } - - function tokenComment(quote) { - return function(stream, state) { - var next, end = false; - while ((next = stream.next()) != null) { - if (next == quote) {end = true; break;} - } - if (end) - state.tokenize = tokenBase; - return ret("comment", "comment"); - }; - } - - function Context(indented, column, type, align, prev) { - this.indented = indented; - this.column = column; - this.type = type; - this.align = align; - this.prev = prev; - } - - function pushContext(state, col, type) { - return state.context = new Context(state.indented, col, type, null, state.context); - } - function popContext(state) { - return state.context = state.context.prev; - } - - // Interface - - return { - startState: function(basecolumn) { - return { - tokenize: tokenBase, - context: new Context((basecolumn || 0) - indentUnit, 0, "top", false), - indented: 0, - startOfLine: true - }; - }, - - token: function(stream, state) { - var ctx = state.context; - if (stream.sol()) { - if (ctx.align == null) ctx.align = false; - state.indented = stream.indentation(); - state.startOfLine = true; - } - if (stream.eatSpace()) return null; - var style = state.tokenize(stream, state); - if (type == "comment") return style; - if (ctx.align == null) ctx.align = true; - - if (type == "[") pushContext(state, stream.column(), "]"); - else if (type == "(") pushContext(state, stream.column(), ")"); - else if (type == ctx.type) popContext(state); - state.startOfLine = false; - return style; - }, - - indent: function(state, textAfter) { - if (state.tokenize != tokenBase) return 0; - var firstChar = textAfter && textAfter.charAt(0), ctx = state.context, closing = firstChar == ctx.type; - if (ctx.align) return ctx.column + (closing ? 0 : 1); - else return ctx.indented + (closing ? 0 : indentUnit); - }, - - electricChars: "]" - }; -}); - -CodeMirror.defineMIME("text/x-stsrc", {name: "smalltalk"}); diff --git a/js/codemirror/mode/sparql/index.html b/js/codemirror/mode/sparql/index.html deleted file mode 100644 index a0e2f4e..0000000 --- a/js/codemirror/mode/sparql/index.html +++ /dev/null @@ -1,41 +0,0 @@ - - - - CodeMirror 2: SPARQL mode - - - - - - - - -

CodeMirror 2: SPARQL mode

-
- - -

MIME types defined: application/x-sparql-query.

- - - diff --git a/js/codemirror/mode/sparql/sparql.js b/js/codemirror/mode/sparql/sparql.js deleted file mode 100644 index ceb5294..0000000 --- a/js/codemirror/mode/sparql/sparql.js +++ /dev/null @@ -1,143 +0,0 @@ -CodeMirror.defineMode("sparql", function(config) { - var indentUnit = config.indentUnit; - var curPunc; - - function wordRegexp(words) { - return new RegExp("^(?:" + words.join("|") + ")$", "i"); - } - var ops = wordRegexp(["str", "lang", "langmatches", "datatype", "bound", "sameterm", "isiri", "isuri", - "isblank", "isliteral", "union", "a"]); - var keywords = wordRegexp(["base", "prefix", "select", "distinct", "reduced", "construct", "describe", - "ask", "from", "named", "where", "order", "limit", "offset", "filter", "optional", - "graph", "by", "asc", "desc"]); - var operatorChars = /[*+\-<>=&|]/; - - function tokenBase(stream, state) { - var ch = stream.next(); - curPunc = null; - if (ch == "$" || ch == "?") { - stream.match(/^[\w\d]*/); - return "variable-2"; - } - else if (ch == "<" && !stream.match(/^[\s\u00a0=]/, false)) { - stream.match(/^[^\s\u00a0>]*>?/); - return "atom"; - } - else if (ch == "\"" || ch == "'") { - state.tokenize = tokenLiteral(ch); - return state.tokenize(stream, state); - } - else if (/[{}\(\),\.;\[\]]/.test(ch)) { - curPunc = ch; - return null; - } - else if (ch == "#") { - stream.skipToEnd(); - return "comment"; - } - else if (operatorChars.test(ch)) { - stream.eatWhile(operatorChars); - return null; - } - else if (ch == ":") { - stream.eatWhile(/[\w\d\._\-]/); - return "atom"; - } - else { - stream.eatWhile(/[_\w\d]/); - if (stream.eat(":")) { - stream.eatWhile(/[\w\d_\-]/); - return "atom"; - } - var word = stream.current(), type; - if (ops.test(word)) - return null; - else if (keywords.test(word)) - return "keyword"; - else - return "variable"; - } - } - - function tokenLiteral(quote) { - return function(stream, state) { - var escaped = false, ch; - while ((ch = stream.next()) != null) { - if (ch == quote && !escaped) { - state.tokenize = tokenBase; - break; - } - escaped = !escaped && ch == "\\"; - } - return "string"; - }; - } - - function pushContext(state, type, col) { - state.context = {prev: state.context, indent: state.indent, col: col, type: type}; - } - function popContext(state) { - state.indent = state.context.indent; - state.context = state.context.prev; - } - - return { - startState: function(base) { - return {tokenize: tokenBase, - context: null, - indent: 0, - col: 0}; - }, - - token: function(stream, state) { - if (stream.sol()) { - if (state.context && state.context.align == null) state.context.align = false; - state.indent = stream.indentation(); - } - if (stream.eatSpace()) return null; - var style = state.tokenize(stream, state); - - if (style != "comment" && state.context && state.context.align == null && state.context.type != "pattern") { - state.context.align = true; - } - - if (curPunc == "(") pushContext(state, ")", stream.column()); - else if (curPunc == "[") pushContext(state, "]", stream.column()); - else if (curPunc == "{") pushContext(state, "}", stream.column()); - else if (/[\]\}\)]/.test(curPunc)) { - while (state.context && state.context.type == "pattern") popContext(state); - if (state.context && curPunc == state.context.type) popContext(state); - } - else if (curPunc == "." && state.context && state.context.type == "pattern") popContext(state); - else if (/atom|string|variable/.test(style) && state.context) { - if (/[\}\]]/.test(state.context.type)) - pushContext(state, "pattern", stream.column()); - else if (state.context.type == "pattern" && !state.context.align) { - state.context.align = true; - state.context.col = stream.column(); - } - } - - return style; - }, - - indent: function(state, textAfter) { - var firstChar = textAfter && textAfter.charAt(0); - var context = state.context; - if (/[\]\}]/.test(firstChar)) - while (context && context.type == "pattern") context = context.prev; - - var closing = context && firstChar == context.type; - if (!context) - return 0; - else if (context.type == "pattern") - return context.col; - else if (context.align) - return context.col + (closing ? 0 : 1); - else - return context.indent + (closing ? 0 : indentUnit); - } - }; -}); - -CodeMirror.defineMIME("application/x-sparql-query", "sparql"); diff --git a/js/codemirror/mode/stex/index.html b/js/codemirror/mode/stex/index.html deleted file mode 100644 index 7a27d11..0000000 --- a/js/codemirror/mode/stex/index.html +++ /dev/null @@ -1,96 +0,0 @@ - - - - CodeMirror 2: sTeX mode - - - - - - - - -

CodeMirror 2: sTeX mode

-
- - -

MIME types defined: text/stex.

- - - diff --git a/js/codemirror/mode/stex/stex.js b/js/codemirror/mode/stex/stex.js deleted file mode 100644 index bb47fb4..0000000 --- a/js/codemirror/mode/stex/stex.js +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Author: Constantin Jucovschi (c.jucovschi@jacobs-university.de) - * Licence: MIT - */ - -CodeMirror.defineMode("stex", function(cmCfg, modeCfg) -{ - function pushCommand(state, command) { - state.cmdState.push(command); - } - - function peekCommand(state) { - if (state.cmdState.length>0) - return state.cmdState[state.cmdState.length-1]; - else - return null; - } - - function popCommand(state) { - if (state.cmdState.length>0) { - var plug = state.cmdState.pop(); - plug.closeBracket(); - } - } - - function applyMostPowerful(state) { - var context = state.cmdState; - for (var i = context.length - 1; i >= 0; i--) { - var plug = context[i]; - if (plug.name=="DEFAULT") - continue; - return plug.styleIdentifier(); - } - return null; - } - - function addPluginPattern(pluginName, cmdStyle, brackets, styles) { - return function () { - this.name=pluginName; - this.bracketNo = 0; - this.style=cmdStyle; - this.styles = styles; - this.brackets = brackets; - - this.styleIdentifier = function(content) { - if (this.bracketNo<=this.styles.length) - return this.styles[this.bracketNo-1]; - else - return null; - }; - this.openBracket = function(content) { - this.bracketNo++; - return "bracket"; - }; - this.closeBracket = function(content) { - }; - } - } - - var plugins = new Array(); - - plugins["importmodule"] = addPluginPattern("importmodule", "tag", "{[", ["string", "builtin"]); - plugins["documentclass"] = addPluginPattern("documentclass", "tag", "{[", ["", "atom"]); - plugins["usepackage"] = addPluginPattern("documentclass", "tag", "[", ["atom"]); - plugins["begin"] = addPluginPattern("documentclass", "tag", "[", ["atom"]); - plugins["end"] = addPluginPattern("documentclass", "tag", "[", ["atom"]); - - plugins["DEFAULT"] = function () { - this.name="DEFAULT"; - this.style="tag"; - - this.styleIdentifier = function(content) { - }; - this.openBracket = function(content) { - }; - this.closeBracket = function(content) { - }; - }; - - function setState(state, f) { - state.f = f; - } - - function normal(source, state) { - if (source.match(/^\\[a-z]+/)) { - var cmdName = source.current(); - cmdName = cmdName.substr(1, cmdName.length-1); - var plug = plugins[cmdName]; - if (typeof(plug) == 'undefined') { - plug = plugins["DEFAULT"]; - } - plug = new plug(); - pushCommand(state, plug); - setState(state, beginParams); - return plug.style; - } - - var ch = source.next(); - if (ch == "%") { - setState(state, inCComment); - return "comment"; - } - else if (ch=='}' || ch==']') { - plug = peekCommand(state); - if (plug) { - plug.closeBracket(ch); - setState(state, beginParams); - } else - return "error"; - return "bracket"; - } else if (ch=='{' || ch=='[') { - plug = plugins["DEFAULT"]; - plug = new plug(); - pushCommand(state, plug); - return "bracket"; - } - else if (/\d/.test(ch)) { - source.eatWhile(/[\w.%]/); - return "atom"; - } - else { - source.eatWhile(/[\w-_]/); - return applyMostPowerful(state); - } - } - - function inCComment(source, state) { - source.skipToEnd(); - setState(state, normal); - return "comment"; - } - - function beginParams(source, state) { - var ch = source.peek(); - if (ch == '{' || ch == '[') { - var lastPlug = peekCommand(state); - var style = lastPlug.openBracket(ch); - source.eat(ch); - setState(state, normal); - return "bracket"; - } - if (/[ \t\r]/.test(ch)) { - source.eat(ch); - return null; - } - setState(state, normal); - lastPlug = peekCommand(state); - if (lastPlug) { - popCommand(state); - } - return normal(source, state); - } - - return { - startState: function() { return { f:normal, cmdState:[] }; }, - copyState: function(s) { return { f: s.f, cmdState: s.cmdState.slice(0, s.cmdState.length) }; }, - - token: function(stream, state) { - var t = state.f(stream, state); - var w = stream.current(); - return t; - } - }; -}); - - -CodeMirror.defineMIME("text/x-stex", "stex"); diff --git a/js/codemirror/mode/velocity/index.html b/js/codemirror/mode/velocity/index.html deleted file mode 100644 index 7ab63ec..0000000 --- a/js/codemirror/mode/velocity/index.html +++ /dev/null @@ -1,103 +0,0 @@ - - - - CodeMirror 2: Velocity mode - - - - - - - - -

CodeMirror 2: Velocity mode

-
- - -

MIME types defined: text/velocity.

- - - diff --git a/js/codemirror/mode/velocity/velocity.js b/js/codemirror/mode/velocity/velocity.js deleted file mode 100644 index 0b80c75..0000000 --- a/js/codemirror/mode/velocity/velocity.js +++ /dev/null @@ -1,146 +0,0 @@ -CodeMirror.defineMode("velocity", function(config) { - function parseWords(str) { - var obj = {}, words = str.split(" "); - for (var i = 0; i < words.length; ++i) obj[words[i]] = true; - return obj; - } - - var indentUnit = config.indentUnit - var keywords = parseWords("#end #else #break #stop #[[ #]] " + - "#{end} #{else} #{break} #{stop}"); - var functions = parseWords("#if #elseif #foreach #set #include #parse #macro #define #evaluate " + - "#{if} #{elseif} #{foreach} #{set} #{include} #{parse} #{macro} #{define} #{evaluate}"); - var specials = parseWords("$foreach.count $foreach.hasNext $foreach.first $foreach.last $foreach.topmost $foreach.parent $velocityCount"); - var isOperatorChar = /[+\-*&%=<>!?:\/|]/; - var multiLineStrings =true; - - function chain(stream, state, f) { - state.tokenize = f; - return f(stream, state); - } - function tokenBase(stream, state) { - var beforeParams = state.beforeParams; - state.beforeParams = false; - var ch = stream.next(); - // start of string? - if ((ch == '"' || ch == "'") && state.inParams) - return chain(stream, state, tokenString(ch)); - // is it one of the special signs []{}().,;? Seperator? - else if (/[\[\]{}\(\),;\.]/.test(ch)) { - if (ch == "(" && beforeParams) state.inParams = true; - else if (ch == ")") state.inParams = false; - return null; - } - // start of a number value? - else if (/\d/.test(ch)) { - stream.eatWhile(/[\w\.]/); - return "number"; - } - // multi line comment? - else if (ch == "#" && stream.eat("*")) { - return chain(stream, state, tokenComment); - } - // unparsed content? - else if (ch == "#" && stream.match(/ *\[ *\[/)) { - return chain(stream, state, tokenUnparsed); - } - // single line comment? - else if (ch == "#" && stream.eat("#")) { - stream.skipToEnd(); - return "comment"; - } - // variable? - else if (ch == "$") { - stream.eatWhile(/[\w\d\$_\.{}]/); - // is it one of the specials? - if (specials && specials.propertyIsEnumerable(stream.current().toLowerCase())) { - return "keyword"; - } - else { - state.beforeParams = true; - return "builtin"; - } - } - // is it a operator? - else if (isOperatorChar.test(ch)) { - stream.eatWhile(isOperatorChar); - return "operator"; - } - else { - // get the whole word - stream.eatWhile(/[\w\$_{}]/); - var word = stream.current().toLowerCase(); - // is it one of the listed keywords? - if (keywords && keywords.propertyIsEnumerable(word)) - return "keyword"; - // is it one of the listed functions? - if (functions && functions.propertyIsEnumerable(word) || - stream.current().match(/^#[a-z0-9_]+ *$/i) && stream.peek()=="(") { - state.beforeParams = true; - return "keyword"; - } - // default: just a "word" - return null; - } - } - - function tokenString(quote) { - return function(stream, state) { - var escaped = false, next, end = false; - while ((next = stream.next()) != null) { - if (next == quote && !escaped) { - end = true; - break; - } - escaped = !escaped && next == "\\"; - } - if (end) state.tokenize = tokenBase; - return "string"; - }; - } - - function tokenComment(stream, state) { - var maybeEnd = false, ch; - while (ch = stream.next()) { - if (ch == "#" && maybeEnd) { - state.tokenize = tokenBase; - break; - } - maybeEnd = (ch == "*"); - } - return "comment"; - } - - function tokenUnparsed(stream, state) { - var maybeEnd = 0, ch; - while (ch = stream.next()) { - if (ch == "#" && maybeEnd == 2) { - state.tokenize = tokenBase; - break; - } - if (ch == "]") - maybeEnd++; - else if (ch != " ") - maybeEnd = 0; - } - return "meta"; - } - // Interface - - return { - startState: function(basecolumn) { - return { - tokenize: tokenBase, - beforeParams: false, - inParams: false - }; - }, - - token: function(stream, state) { - if (stream.eatSpace()) return null; - return state.tokenize(stream, state); - } - }; -}); - -CodeMirror.defineMIME("text/velocity", "velocity"); diff --git a/js/codemirror/mode/xml/index.html b/js/codemirror/mode/xml/index.html deleted file mode 100644 index 122848a..0000000 --- a/js/codemirror/mode/xml/index.html +++ /dev/null @@ -1,42 +0,0 @@ - - - - CodeMirror 2: XML mode - - - - - - - - -

CodeMirror 2: XML mode

-
- -

The XML mode supports two configuration parameters:

-
-
htmlMode (boolean)
-
This switches the mode to parse HTML instead of XML. This - means attributes do not have to be quoted, and some elements - (such as br) do not require a closing tag.
-
alignCDATA (boolean)
-
Setting this to true will force the opening tag of CDATA - blocks to not be indented.
-
- -

MIME types defined: application/xml, text/html.

- - diff --git a/js/codemirror/mode/xml/xml.js b/js/codemirror/mode/xml/xml.js deleted file mode 100644 index cb7cf97..0000000 --- a/js/codemirror/mode/xml/xml.js +++ /dev/null @@ -1,231 +0,0 @@ -CodeMirror.defineMode("xml", function(config, parserConfig) { - var indentUnit = config.indentUnit; - var Kludges = parserConfig.htmlMode ? { - autoSelfClosers: {"br": true, "img": true, "hr": true, "link": true, "input": true, - "meta": true, "col": true, "frame": true, "base": true, "area": true}, - doNotIndent: {"pre": true, "!cdata": true}, - allowUnquoted: true - } : {autoSelfClosers: {}, doNotIndent: {"!cdata": true}, allowUnquoted: false}; - var alignCDATA = parserConfig.alignCDATA; - - // Return variables for tokenizers - var tagName, type; - - function inText(stream, state) { - function chain(parser) { - state.tokenize = parser; - return parser(stream, state); - } - - var ch = stream.next(); - if (ch == "<") { - if (stream.eat("!")) { - if (stream.eat("[")) { - if (stream.match("CDATA[")) return chain(inBlock("atom", "]]>")); - else return null; - } - else if (stream.match("--")) return chain(inBlock("comment", "-->")); - else if (stream.match("DOCTYPE", true, true)) { - stream.eatWhile(/[\w\._\-]/); - return chain(inBlock("meta", ">")); - } - else return null; - } - else if (stream.eat("?")) { - stream.eatWhile(/[\w\._\-]/); - state.tokenize = inBlock("meta", "?>"); - return "meta"; - } - else { - type = stream.eat("/") ? "closeTag" : "openTag"; - stream.eatSpace(); - tagName = ""; - var c; - while ((c = stream.eat(/[^\s\u00a0=<>\"\'\/?]/))) tagName += c; - state.tokenize = inTag; - return "tag"; - } - } - else if (ch == "&") { - stream.eatWhile(/[^;]/); - stream.eat(";"); - return "atom"; - } - else { - stream.eatWhile(/[^&<]/); - return null; - } - } - - function inTag(stream, state) { - var ch = stream.next(); - if (ch == ">" || (ch == "/" && stream.eat(">"))) { - state.tokenize = inText; - type = ch == ">" ? "endTag" : "selfcloseTag"; - return "tag"; - } - else if (ch == "=") { - type = "equals"; - return null; - } - else if (/[\'\"]/.test(ch)) { - state.tokenize = inAttribute(ch); - return state.tokenize(stream, state); - } - else { - stream.eatWhile(/[^\s\u00a0=<>\"\'\/?]/); - return "word"; - } - } - - function inAttribute(quote) { - return function(stream, state) { - while (!stream.eol()) { - if (stream.next() == quote) { - state.tokenize = inTag; - break; - } - } - return "string"; - }; - } - - function inBlock(style, terminator) { - return function(stream, state) { - while (!stream.eol()) { - if (stream.match(terminator)) { - state.tokenize = inText; - break; - } - stream.next(); - } - return style; - }; - } - - var curState, setStyle; - function pass() { - for (var i = arguments.length - 1; i >= 0; i--) curState.cc.push(arguments[i]); - } - function cont() { - pass.apply(null, arguments); - return true; - } - - function pushContext(tagName, startOfLine) { - var noIndent = Kludges.doNotIndent.hasOwnProperty(tagName) || (curState.context && curState.context.noIndent); - curState.context = { - prev: curState.context, - tagName: tagName, - indent: curState.indented, - startOfLine: startOfLine, - noIndent: noIndent - }; - } - function popContext() { - if (curState.context) curState.context = curState.context.prev; - } - - function element(type) { - if (type == "openTag") {curState.tagName = tagName; return cont(attributes, endtag(curState.startOfLine));} - else if (type == "closeTag") { - var err = false; - if (curState.context) { - err = curState.context.tagName != tagName; - } else { - err = true; - } - if (err) setStyle = "error"; - return cont(endclosetag(err)); - } - else if (type == "string") { - if (!curState.context || curState.context.name != "!cdata") pushContext("!cdata"); - if (curState.tokenize == inText) popContext(); - return cont(); - } - else return cont(); - } - function endtag(startOfLine) { - return function(type) { - if (type == "selfcloseTag" || - (type == "endTag" && Kludges.autoSelfClosers.hasOwnProperty(curState.tagName.toLowerCase()))) - return cont(); - if (type == "endTag") {pushContext(curState.tagName, startOfLine); return cont();} - return cont(); - }; - } - function endclosetag(err) { - return function(type) { - if (err) setStyle = "error"; - if (type == "endTag") { popContext(); return cont(); } - setStyle = "error"; - return cont(arguments.callee); - } - } - - function attributes(type) { - if (type == "word") {setStyle = "attribute"; return cont(attributes);} - if (type == "equals") return cont(attvalue, attributes); - return pass(); - } - function attvalue(type) { - if (type == "word" && Kludges.allowUnquoted) {setStyle = "string"; return cont();} - if (type == "string") return cont(attvaluemaybe); - return pass(); - } - function attvaluemaybe(type) { - if (type == "string") return cont(attvaluemaybe); - else return pass(); - } - - return { - startState: function() { - return {tokenize: inText, cc: [], indented: 0, startOfLine: true, tagName: null, context: null}; - }, - - token: function(stream, state) { - if (stream.sol()) { - state.startOfLine = true; - state.indented = stream.indentation(); - } - if (stream.eatSpace()) return null; - - setStyle = type = tagName = null; - var style = state.tokenize(stream, state); - if ((style || type) && style != "comment") { - curState = state; - while (true) { - var comb = state.cc.pop() || element; - if (comb(type || style)) break; - } - } - state.startOfLine = false; - return setStyle || style; - }, - - indent: function(state, textAfter) { - var context = state.context; - if (context && context.noIndent) return 0; - if (alignCDATA && / - - - CodeMirror 2: Pure XML mode - - - - - - - - -

CodeMirror 2: XML mode

-
- - -

This is my XML parser, based on the original:

-
    -
  • No html mode - this is pure xml
  • -
  • Illegal attributes and element names are errors
  • -
  • Attributes must have a value
  • -
  • XML declaration supported (e.g.: <?xml version="1.0" encoding="utf-8" standalone="no" ?>)
  • -
  • CDATA and comment blocks are not indented (except for their start-tag)
  • -
  • Better handling of errors per line with the state object - provides good infrastructure for extending it
  • -
- -

What's missing:

-
    -
  • Make sure only a single root element exists at the document level
  • -
  • Multi-line attributes should NOT indent
  • -
  • Start tags are not painted red when they have no matching end tags (is this really wrong?)
  • -
- -

MIME types defined: application/xml, text/xml.

- -

@author: Dror BG (deebug dot dev at gmail dot com)
-

@date: August, 2011
-

@github: https://github.com/deebugger/CodeMirror2

- -

MIME types defined: application/xml, text/xml.

- - diff --git a/js/codemirror/mode/xmlpure/xmlpure.js b/js/codemirror/mode/xmlpure/xmlpure.js deleted file mode 100644 index c55a717..0000000 --- a/js/codemirror/mode/xmlpure/xmlpure.js +++ /dev/null @@ -1,481 +0,0 @@ -/** - * xmlpure.js - * - * Building upon and improving the CodeMirror 2 XML parser - * @author: Dror BG (deebug.dev@gmail.com) - * @date: August, 2011 - */ - -CodeMirror.defineMode("xmlpure", function(config, parserConfig) { - // constants - var STYLE_ERROR = "error"; - var STYLE_INSTRUCTION = "comment"; - var STYLE_COMMENT = "comment"; - var STYLE_ELEMENT_NAME = "tag"; - var STYLE_ATTRIBUTE = "attribute"; - var STYLE_WORD = "string"; - var STYLE_TEXT = "atom"; - - var TAG_INSTRUCTION = "!instruction"; - var TAG_CDATA = "!cdata"; - var TAG_COMMENT = "!comment"; - var TAG_TEXT = "!text"; - - var doNotIndent = { - "!cdata": true, - "!comment": true, - "!text": true, - "!instruction": true - }; - - // options - var indentUnit = config.indentUnit; - - /////////////////////////////////////////////////////////////////////////// - // helper functions - - // chain a parser to another parser - function chain(stream, state, parser) { - state.tokenize = parser; - return parser(stream, state); - } - - // parse a block (comment, CDATA or text) - function inBlock(style, terminator, nextTokenize) { - return function(stream, state) { - while (!stream.eol()) { - if (stream.match(terminator)) { - popContext(state); - state.tokenize = nextTokenize; - break; - } - stream.next(); - } - return style; - }; - } - - // go down a level in the document - // (hint: look at who calls this function to know what the contexts are) - function pushContext(state, tagName) { - var noIndent = doNotIndent.hasOwnProperty(tagName) || (state.context && state.context.doIndent); - var newContext = { - tagName: tagName, - prev: state.context, - indent: state.context ? state.context.indent + indentUnit : 0, - lineNumber: state.lineNumber, - indented: state.indented, - noIndent: noIndent - }; - state.context = newContext; - } - - // go up a level in the document - function popContext(state) { - if (state.context) { - var oldContext = state.context; - state.context = oldContext.prev; - return oldContext; - } - - // we shouldn't be here - it means we didn't have a context to pop - return null; - } - - // return true if the current token is seperated from the tokens before it - // which means either this is the start of the line, or there is at least - // one space or tab character behind the token - // otherwise returns false - function isTokenSeparated(stream) { - return stream.sol() || - stream.string.charAt(stream.start - 1) == " " || - stream.string.charAt(stream.start - 1) == "\t"; - } - - /////////////////////////////////////////////////////////////////////////// - // context: document - // - // an XML document can contain: - // - a single declaration (if defined, it must be the very first line) - // - exactly one root element - // @todo try to actually limit the number of root elements to 1 - // - zero or more comments - function parseDocument(stream, state) { - if(stream.eat("<")) { - if(stream.eat("?")) { - // processing instruction - pushContext(state, TAG_INSTRUCTION); - state.tokenize = parseProcessingInstructionStartTag; - return STYLE_INSTRUCTION; - } else if(stream.match("!--")) { - // new context: comment - pushContext(state, TAG_COMMENT); - return chain(stream, state, inBlock(STYLE_COMMENT, "-->", parseDocument)); - } else if(stream.eatSpace() || stream.eol() ) { - stream.skipToEnd(); - return STYLE_ERROR; - } else { - // element - state.tokenize = parseElementTagName; - return STYLE_ELEMENT_NAME; - } - } - - // error on line - stream.skipToEnd(); - return STYLE_ERROR; - } - - /////////////////////////////////////////////////////////////////////////// - // context: XML element start-tag or end-tag - // - // - element start-tag can contain attributes - // - element start-tag may self-close (or start an element block if it doesn't) - // - element end-tag can contain only the tag name - function parseElementTagName(stream, state) { - // get the name of the tag - var startPos = stream.pos; - if(stream.match(/^[a-zA-Z_:][-a-zA-Z0-9_:.]*/)) { - // element start-tag - var tagName = stream.string.substring(startPos, stream.pos); - pushContext(state, tagName); - state.tokenize = parseElement; - return STYLE_ELEMENT_NAME; - } else if(stream.match(/^\/[a-zA-Z_:][-a-zA-Z0-9_:.]*( )*>/)) { - // element end-tag - var endTagName = stream.string.substring(startPos + 1, stream.pos - 1).trim(); - var oldContext = popContext(state); - state.tokenize = state.context == null ? parseDocument : parseElementBlock; - if(oldContext == null || endTagName != oldContext.tagName) { - // the start and end tag names should match - error - return STYLE_ERROR; - } - return STYLE_ELEMENT_NAME; - } else { - // no tag name - error - state.tokenize = state.context == null ? parseDocument : parseElementBlock; - stream.eatWhile(/[^>]/); - stream.eat(">"); - return STYLE_ERROR; - } - - stream.skipToEnd(); - return null; - } - - function parseElement(stream, state) { - if(stream.match(/^\/>/)) { - // self-closing tag - popContext(state); - state.tokenize = state.context == null ? parseDocument : parseElementBlock; - return STYLE_ELEMENT_NAME; - } else if(stream.eat(/^>/)) { - state.tokenize = parseElementBlock; - return STYLE_ELEMENT_NAME; - } else if(isTokenSeparated(stream) && stream.match(/^[a-zA-Z_:][-a-zA-Z0-9_:.]*( )*=/)) { - // attribute - state.tokenize = parseAttribute; - return STYLE_ATTRIBUTE; - } - - // no other options - this is an error - state.tokenize = state.context == null ? parseDocument : parseDocument; - stream.eatWhile(/[^>]/); - stream.eat(">"); - return STYLE_ERROR; - } - - /////////////////////////////////////////////////////////////////////////// - // context: attribute - // - // attribute values may contain everything, except: - // - the ending quote (with ' or ") - this marks the end of the value - // - the character "<" - should never appear - // - ampersand ("&") - unless it starts a reference: a string that ends with a semi-colon (";") - // ---> note: this parser is lax in what may be put into a reference string, - // ---> consult http://www.w3.org/TR/REC-xml/#NT-Reference if you want to make it tighter - function parseAttribute(stream, state) { - var quote = stream.next(); - if(quote != "\"" && quote != "'") { - // attribute must be quoted - stream.skipToEnd(); - state.tokenize = parseElement; - return STYLE_ERROR; - } - - state.tokParams.quote = quote; - state.tokenize = parseAttributeValue; - return STYLE_WORD; - } - - // @todo: find out whether this attribute value spans multiple lines, - // and if so, push a context for it in order not to indent it - // (or something of the sort..) - function parseAttributeValue(stream, state) { - var ch = ""; - while(!stream.eol()) { - ch = stream.next(); - if(ch == state.tokParams.quote) { - // end quote found - state.tokenize = parseElement; - return STYLE_WORD; - } else if(ch == "<") { - // can't have less-than signs in an attribute value, ever - stream.skipToEnd() - state.tokenize = parseElement; - return STYLE_ERROR; - } else if(ch == "&") { - // reference - look for a semi-colon, or return error if none found - ch = stream.next(); - - // make sure that semi-colon isn't right after the ampersand - if(ch == ';') { - stream.skipToEnd() - state.tokenize = parseElement; - return STYLE_ERROR; - } - - // make sure no less-than characters slipped in - while(!stream.eol() && ch != ";") { - if(ch == "<") { - // can't have less-than signs in an attribute value, ever - stream.skipToEnd() - state.tokenize = parseElement; - return STYLE_ERROR; - } - ch = stream.next(); - } - if(stream.eol() && ch != ";") { - // no ampersand found - error - stream.skipToEnd(); - state.tokenize = parseElement; - return STYLE_ERROR; - } - } - } - - // attribute value continues to next line - return STYLE_WORD; - } - - /////////////////////////////////////////////////////////////////////////// - // context: element block - // - // a block can contain: - // - elements - // - text - // - CDATA sections - // - comments - function parseElementBlock(stream, state) { - if(stream.eat("<")) { - if(stream.match("?")) { - pushContext(state, TAG_INSTRUCTION); - state.tokenize = parseProcessingInstructionStartTag; - return STYLE_INSTRUCTION; - } else if(stream.match("!--")) { - // new context: comment - pushContext(state, TAG_COMMENT); - return chain(stream, state, inBlock(STYLE_COMMENT, "-->", - state.context == null ? parseDocument : parseElementBlock)); - } else if(stream.match("![CDATA[")) { - // new context: CDATA section - pushContext(state, TAG_CDATA); - return chain(stream, state, inBlock(STYLE_TEXT, "]]>", - state.context == null ? parseDocument : parseElementBlock)); - } else if(stream.eatSpace() || stream.eol() ) { - stream.skipToEnd(); - return STYLE_ERROR; - } else { - // element - state.tokenize = parseElementTagName; - return STYLE_ELEMENT_NAME; - } - } else { - // new context: text - pushContext(state, TAG_TEXT); - state.tokenize = parseText; - return null; - } - - state.tokenize = state.context == null ? parseDocument : parseElementBlock; - stream.skipToEnd(); - return null; - } - - function parseText(stream, state) { - stream.eatWhile(/[^<]/); - if(!stream.eol()) { - // we cannot possibly be in the document context, - // just inside an element block - popContext(state); - state.tokenize = parseElementBlock; - } - return STYLE_TEXT; - } - - /////////////////////////////////////////////////////////////////////////// - // context: XML processing instructions - // - // XML processing instructions (PIs) allow documents to contain instructions for applications. - // PI format: - // - 'name' can be anything other than 'xml' (case-insensitive) - // - 'data' can be anything which doesn't contain '?>' - // XML declaration is a special PI (see XML declaration context below) - function parseProcessingInstructionStartTag(stream, state) { - if(stream.match("xml", true, true)) { - // xml declaration - if(state.lineNumber > 1 || stream.pos > 5) { - state.tokenize = parseDocument; - stream.skipToEnd(); - return STYLE_ERROR; - } else { - state.tokenize = parseDeclarationVersion; - return STYLE_INSTRUCTION; - } - } - - // regular processing instruction - if(isTokenSeparated(stream) || stream.match("?>")) { - // we have a space after the start-tag, or nothing but the end-tag - // either way - error! - state.tokenize = parseDocument; - stream.skipToEnd(); - return STYLE_ERROR; - } - - state.tokenize = parseProcessingInstructionBody; - return STYLE_INSTRUCTION; - } - - function parseProcessingInstructionBody(stream, state) { - stream.eatWhile(/[^?]/); - if(stream.eat("?")) { - if(stream.eat(">")) { - popContext(state); - state.tokenize = state.context == null ? parseDocument : parseElementBlock; - } - } - return STYLE_INSTRUCTION; - } - - - /////////////////////////////////////////////////////////////////////////// - // context: XML declaration - // - // XML declaration is of the following format: - // - // - must start at the first character of the first line - // - may span multiple lines - // - must include 'version' - // - may include 'encoding' and 'standalone' (in that order after 'version') - // - attribute names must be lowercase - // - cannot contain anything else on the line - function parseDeclarationVersion(stream, state) { - state.tokenize = parseDeclarationEncoding; - - if(isTokenSeparated(stream) && stream.match(/^version( )*=( )*"([a-zA-Z0-9_.:]|\-)+"/)) { - return STYLE_INSTRUCTION; - } - stream.skipToEnd(); - return STYLE_ERROR; - } - - function parseDeclarationEncoding(stream, state) { - state.tokenize = parseDeclarationStandalone; - - if(isTokenSeparated(stream) && stream.match(/^encoding( )*=( )*"[A-Za-z]([A-Za-z0-9._]|\-)*"/)) { - return STYLE_INSTRUCTION; - } - return null; - } - - function parseDeclarationStandalone(stream, state) { - state.tokenize = parseDeclarationEndTag; - - if(isTokenSeparated(stream) && stream.match(/^standalone( )*=( )*"(yes|no)"/)) { - return STYLE_INSTRUCTION; - } - return null; - } - - function parseDeclarationEndTag(stream, state) { - state.tokenize = parseDocument; - - if(stream.match("?>") && stream.eol()) { - popContext(state); - return STYLE_INSTRUCTION; - } - stream.skipToEnd(); - return STYLE_ERROR; - } - - /////////////////////////////////////////////////////////////////////////// - // returned object - return { - electricChars: "/", - - startState: function() { - return { - tokenize: parseDocument, - tokParams: {}, - lineNumber: 0, - lineError: false, - context: null, - indented: 0 - }; - }, - - token: function(stream, state) { - if(stream.sol()) { - // initialize a new line - state.lineNumber++; - state.lineError = false; - state.indented = stream.indentation(); - } - - // eat all (the spaces) you can - if(stream.eatSpace()) return null; - - // run the current tokenize function, according to the state - var style = state.tokenize(stream, state); - - // is there an error somewhere in the line? - state.lineError = (state.lineError || style == "error"); - - return style; - }, - - blankLine: function(state) { - // blank lines are lines too! - state.lineNumber++; - state.lineError = false; - }, - - indent: function(state, textAfter) { - if(state.context) { - if(state.context.noIndent == true) { - // do not indent - no return value at all - return; - } - if(textAfter.match(/^<\/.*/)) { - // eng-tag - indent back to last context - return state.context.indent; - } - // indent to last context + regular indent unit - return state.context.indent + indentUnit; - } - return 0; - }, - - compareStates: function(a, b) { - if (a.indented != b.indented) return false; - for (var ca = a.context, cb = b.context; ; ca = ca.prev, cb = cb.prev) { - if (!ca || !cb) return ca == cb; - if (ca.tagName != cb.tagName) return false; - } - } - }; -}); - -CodeMirror.defineMIME("application/xml", "purexml"); -CodeMirror.defineMIME("text/xml", "purexml"); diff --git a/js/codemirror/mode/yaml/index.html b/js/codemirror/mode/yaml/index.html deleted file mode 100644 index e8d04d1..0000000 --- a/js/codemirror/mode/yaml/index.html +++ /dev/null @@ -1,68 +0,0 @@ - - - - CodeMirror 2: YAML mode - - - - - - - - -

CodeMirror 2: YAML mode

-
- - -

MIME types defined: text/x-yaml.

- - - diff --git a/js/codemirror/mode/yaml/yaml.js b/js/codemirror/mode/yaml/yaml.js deleted file mode 100644 index 59e2641..0000000 --- a/js/codemirror/mode/yaml/yaml.js +++ /dev/null @@ -1,95 +0,0 @@ -CodeMirror.defineMode("yaml", function() { - - var cons = ['true', 'false', 'on', 'off', 'yes', 'no']; - var keywordRegex = new RegExp("\\b(("+cons.join(")|(")+"))$", 'i'); - - return { - token: function(stream, state) { - var ch = stream.peek(); - var esc = state.escaped; - state.escaped = false; - /* comments */ - if (ch == "#") { stream.skipToEnd(); return "comment"; } - if (state.literal && stream.indentation() > state.keyCol) { - stream.skipToEnd(); return "string"; - } else if (state.literal) { state.literal = false; } - if (stream.sol()) { - state.keyCol = 0; - state.pair = false; - state.pairStart = false; - /* document start */ - if(stream.match(/---/)) { return "def"; } - /* document end */ - if (stream.match(/\.\.\./)) { return "def"; } - /* array list item */ - if (stream.match(/\s*-\s+/)) { return 'meta'; } - } - /* pairs (associative arrays) -> key */ - if (!state.pair && stream.match(/^\s*([a-z0-9\._-])+(?=\s*:)/i)) { - state.pair = true; - state.keyCol = stream.indentation(); - return "atom"; - } - if (state.pair && stream.match(/^:\s*/)) { state.pairStart = true; return 'meta'; } - - /* inline pairs/lists */ - if (stream.match(/^(\{|\}|\[|\])/)) { - if (ch == '{') - state.inlinePairs++; - else if (ch == '}') - state.inlinePairs--; - else if (ch == '[') - state.inlineList++; - else - state.inlineList--; - return 'meta'; - } - - /* list seperator */ - if (state.inlineList > 0 && !esc && ch == ',') { - stream.next(); - return 'meta'; - } - /* pairs seperator */ - if (state.inlinePairs > 0 && !esc && ch == ',') { - state.keyCol = 0; - state.pair = false; - state.pairStart = false; - stream.next(); - return 'meta'; - } - - /* start of value of a pair */ - if (state.pairStart) { - /* block literals */ - if (stream.match(/^\s*(\||\>)\s*/)) { state.literal = true; return 'meta'; }; - /* references */ - if (stream.match(/^\s*(\&|\*)[a-z0-9\._-]+\b/i)) { return 'variable-2'; } - /* numbers */ - if (state.inlinePairs == 0 && stream.match(/^\s*-?[0-9\.\,]+\s?$/)) { return 'number'; } - if (state.inlinePairs > 0 && stream.match(/^\s*-?[0-9\.\,]+\s?(?=(,|}))/)) { return 'number'; } - /* keywords */ - if (stream.match(keywordRegex)) { return 'keyword'; } - } - - /* nothing found, continue */ - state.pairStart = false; - state.escaped = (ch == '\\'); - stream.next(); - return null; - }, - startState: function() { - return { - pair: false, - pairStart: false, - keyCol: 0, - inlinePairs: 0, - inlineList: 0, - literal: false, - escaped: false - }; - } - }; -}); - -CodeMirror.defineMIME("text/x-yaml", "yaml"); diff --git a/js/codemirror/overlay.js b/js/codemirror/overlay.js deleted file mode 100644 index c4cdf9f..0000000 --- a/js/codemirror/overlay.js +++ /dev/null @@ -1,51 +0,0 @@ -// 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, in which case -// the styles are combined. - -CodeMirror.overlayParser = function(base, overlay, combine) { - return { - startState: function() { - return { - base: CodeMirror.startState(base), - overlay: CodeMirror.startState(overlay), - basePos: 0, baseCur: null, - overlayPos: 0, overlayCur: 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.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); - if (stream.eol()) state.basePos = state.overlayPos = 0; - - if (state.overlayCur == null) return state.baseCur; - if (state.baseCur != null && combine) return state.baseCur + " " + state.overlayCur; - else return state.overlayCur; - }, - - indent: function(state, textAfter) { - return base.indent(state.base, textAfter); - }, - electricChars: base.electricChars - }; -}; diff --git a/js/codemirror/runmode.js b/js/codemirror/runmode.js deleted file mode 100644 index 163e720..0000000 --- a/js/codemirror/runmode.js +++ /dev/null @@ -1,27 +0,0 @@ -CodeMirror.runMode = function(string, modespec, callback) { - var mode = CodeMirror.getMode({indentUnit: 2}, modespec); - var isNode = callback.nodeType == 1; - if (isNode) { - var node = callback, accum = []; - callback = function(string, style) { - if (string == "\n") - accum.push("
"); - else if (style) - accum.push("" + CodeMirror.htmlEscape(string) + ""); - else - accum.push(CodeMirror.htmlEscape(string)); - } - } - var lines = CodeMirror.splitLines(string), 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]); - while (!stream.eol()) { - var style = mode.token(stream, state); - callback(stream.current(), style); - stream.start = stream.pos; - } - } - if (isNode) - node.innerHTML = accum.join(""); -}; diff --git a/js/codemirror/theme/cobalt.css b/js/codemirror/theme/cobalt.css deleted file mode 100644 index ba47da8..0000000 --- a/js/codemirror/theme/cobalt.css +++ /dev/null @@ -1,17 +0,0 @@ -.cm-s-cobalt { background: #002240; color: white; } -.cm-s-cobalt span.CodeMirror-selected { background: #b36539 !important; } -.cm-s-cobalt .CodeMirror-gutter { background: #002240; border-right: 1px solid #aaa; } -.cm-s-cobalt .CodeMirror-gutter-text { color: #d0d0d0; } -.cm-s-cobalt .CodeMirror-cursor { border-left: 1px solid white !important; } - -.cm-s-cobalt span.cm-comment { color: #08f; } -.cm-s-cobalt span.cm-atom { color: #845dc4; } -.cm-s-cobalt span.cm-number, .cm-s-cobalt span.cm-attribute { color: #ff80e1; } -.cm-s-cobalt span.cm-keyword { color: #ffee80; } -.cm-s-cobalt span.cm-string { color: #3ad900; } -.cm-s-cobalt span.cm-meta { color: #ff9d00; } -.cm-s-cobalt span.cm-variable-2, .cm-s-cobalt span.cm-tag { color: #9effff; } -.cm-s-cobalt span.cm-variable-3, .cm-s-cobalt span.cm-def { color: white; } -.cm-s-cobalt span.cm-error { color: #9d1e15; } -.cm-s-cobalt span.cm-bracket { color: #d8d8d8; } -.cm-s-cobalt span.cm-builtin, .cm-s-cobalt span.cm-special { color: #ff9e59; } diff --git a/js/codemirror/theme/default.css b/js/codemirror/theme/default.css deleted file mode 100644 index e68f0fb..0000000 --- a/js/codemirror/theme/default.css +++ /dev/null @@ -1,19 +0,0 @@ -.cm-s-default span.cm-keyword {color: #708;} -.cm-s-default span.cm-atom {color: #219;} -.cm-s-default span.cm-number {color: #164;} -.cm-s-default span.cm-def {color: #00f;} -.cm-s-default span.cm-variable {color: black;} -.cm-s-default span.cm-variable-2 {color: #05a;} -.cm-s-default span.cm-variable-3 {color: #0a5;} -.cm-s-default span.cm-property {color: black;} -.cm-s-default span.cm-operator {color: black;} -.cm-s-default span.cm-comment {color: #a50;} -.cm-s-default span.cm-string {color: #a11;} -.cm-s-default span.cm-string-2 {color: #f50;} -.cm-s-default span.cm-meta {color: #555;} -.cm-s-default span.cm-error {color: #f00;} -.cm-s-default span.cm-qualifier {color: #555;} -.cm-s-default span.cm-builtin {color: #30a;} -.cm-s-default span.cm-bracket {color: #cc7;} -.cm-s-default span.cm-tag {color: #170;} -.cm-s-default span.cm-attribute {color: #00c;} diff --git a/js/codemirror/theme/elegant.css b/js/codemirror/theme/elegant.css deleted file mode 100644 index 171683f..0000000 --- a/js/codemirror/theme/elegant.css +++ /dev/null @@ -1,9 +0,0 @@ -.cm-s-elegant span.cm-number, .cm-s-elegant span.cm-string, .cm-s-elegant span.cm-atom {color: #762;} -.cm-s-elegant span.cm-comment {color: #262;font-style: italic;} -.cm-s-elegant span.cm-meta {color: #555;font-style: italic;} -.cm-s-elegant span.cm-variable {color: black;} -.cm-s-elegant span.cm-variable-2 {color: #b11;} -.cm-s-elegant span.cm-qualifier {color: #555;} -.cm-s-elegant span.cm-keyword {color: #730;} -.cm-s-elegant span.cm-builtin {color: #30a;} -.cm-s-elegant span.cm-error {background-color: #fdd;} diff --git a/js/codemirror/theme/neat.css b/js/codemirror/theme/neat.css deleted file mode 100644 index 10d22c9..0000000 --- a/js/codemirror/theme/neat.css +++ /dev/null @@ -1,8 +0,0 @@ -.cm-s-neat span.cm-comment { color: #a86; } -.cm-s-neat span.cm-keyword { font-weight: bold; color: blue; } -.cm-s-neat span.cm-string { color: #a22; } -.cm-s-neat span.cm-builtin { font-weight: bold; color: #077; } -.cm-s-neat span.cm-special { font-weight: bold; color: #0aa; } -.cm-s-neat span.cm-variable { color: black; } -.cm-s-neat span.cm-number, .cm-s-neat span.cm-atom { color: #3a3; } -.cm-s-neat span.cm-meta {color: #555;} diff --git a/js/codemirror/theme/night.css b/js/codemirror/theme/night.css deleted file mode 100644 index a84ec4f..0000000 --- a/js/codemirror/theme/night.css +++ /dev/null @@ -1,20 +0,0 @@ -/* Loosely based on the Midnight Textmate theme */ - -.cm-s-night { background: #0a001f; color: #f8f8f8; } -.cm-s-night span.CodeMirror-selected { background: #a8f !important; } -.cm-s-night .CodeMirror-gutter { background: #0a001f; border-right: 1px solid #aaa; } -.cm-s-night .CodeMirror-gutter-text { color: #f8f8f8; } -.cm-s-night .CodeMirror-cursor { border-left: 1px solid white !important; } - -.cm-s-night span.cm-comment { color: #6900a1; } -.cm-s-night span.cm-atom { color: #845dc4; } -.cm-s-night span.cm-number, .cm-s-night span.cm-attribute { color: #ffd500; } -.cm-s-night span.cm-keyword { color: #599eff; } -.cm-s-night span.cm-string { color: #37f14a; } -.cm-s-night span.cm-meta { color: #7678e2; } -.cm-s-night span.cm-variable-2, .cm-s-night span.cm-tag { color: #99b2ff; } -.cm-s-night span.cm-variable-3, .cm-s-night span.cm-def { color: white; } -.cm-s-night span.cm-error { color: #9d1e15; } -.cm-s-night span.cm-bracket { color: #8da6ce; } -.cm-s-night span.cm-comment { color: #6900a1; } -.cm-s-night span.cm-builtin, .cm-s-night span.cm-special { color: #ff9e59; } diff --git a/js/deck.core.js b/js/deck.core.js deleted file mode 100644 index e777ba3..0000000 --- a/js/deck.core.js +++ /dev/null @@ -1,364 +0,0 @@ -/*! -Deck JS - deck.core - v1.0 -Copyright (c) 2011 Caleb Troughton -Dual licensed under the MIT license and GPL license. -https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt -https://github.com/imakewebthings/deck.js/blob/master/GPL-license.txt -*/ - -/* -The deck.core module provides all the basic functionality for creating and -moving through a deck. It does so by applying classes to indicate the state of -the deck and its slides, allowing CSS to take care of the visual representation -of each state. It also provides methods for navigating the deck and inspecting -its state, as well as basic key bindings for going to the next and previous -slides. More functionality is provided by wholly separate extension modules -that use the API provided by core. -*/ -(function($, deck, document, undefined) { - var slides, // Array of all the uh, slides... - current, // Array index of the current slide - - events = { - /* - This event fires whenever the current slide changes, whether by way of - next, prev, or go. The callback function is passed two parameters, from - and to, equal to the indices of the old slide and the new slide - respectively. - - $(document).bind('deck.change', function(event, from, to) { - alert('Moving from slide ' + from + ' to ' + to); - }); - */ - change: 'deck.change', - - /* - This event fires at the end of deck initialization. Extensions should - implement any code that relies on user extensible options (key bindings, - element selectors, classes) within a handler for this event. Native - events associated with Deck JS should be scoped under a .deck event - namespace, as with the example below: - - var $d = $(document); - $.deck.defaults.keys.myExtensionKeycode = 70; // 'h' - $d.bind('deck.init', function() { - $d.bind('keydown.deck', function(event) { - if (event.which == $.deck.getOptions().keys.myExtensionKeycode) { - // Rock out - } - }); - }); - */ - initialize: 'deck.init' - }, - - options = {}, - $d = $(document), - - /* - Internal function. Updates slide and container classes based on which - slide is the current slide. - */ - updateStates = function() { - var oc = options.classes, - osc = options.selectors.container, - $container = $(osc), - old = $container.data('onSlide'), - $all = $(); - - // Container state - $container.removeClass(oc.onPrefix + old) - .addClass(oc.onPrefix + current) - .data('onSlide', current); - - // Remove and re-add child-current classes for nesting - $('.' + oc.current).parentsUntil(osc).removeClass(oc.childCurrent); - slides[current].parentsUntil(osc).addClass(oc.childCurrent); - - // Remove previous states - $.each(slides, function(i, el) { - $all = $all.add(el); - }); - $all.removeClass([ - oc.before, - oc.previous, - oc.current, - oc.next, - oc.after - ].join(" ")); - - // Add new states back in - slides[current].addClass(oc.current); - if (current > 0) { - slides[current-1].addClass(oc.previous); - } - if (current + 1 < slides.length) { - slides[current+1].addClass(oc.next); - } - if (current > 1) { - $.each(slides.slice(0, current - 1), function(i, el) { - el.addClass(oc.before); - }); - } - if (current + 2 < slides.length) { - $.each(slides.slice(current+2), function(i, el) { - el.addClass(oc.after); - }); - } - }, - - /* Methods exposed in the jQuery.deck namespace */ - methods = { - - /* - jQuery.deck(selector, options) - - selector: string | jQuery | array - options: object, optional - - Initializes the deck, using each element matched by selector as a slide. - May also be passed an array of string selectors or jQuery objects, in - which case each selector in the array is considered a slide. The second - parameter is an optional options object which will extend the default - values. - - $.deck('.slide'); - - or - - $.deck([ - '#first-slide', - '#second-slide', - '#etc' - ]); - */ - init: function(elements, opts) { - options = $.extend(true, {}, $[deck].defaults, opts); - slides = []; - current = 0; - - // Fill slides array depending on parameter type - if ($.isArray(elements)) { - $.each(elements, function(i, e) { - slides.push($(e)); - }); - } - else { - $(elements).each(function(i, e) { - slides.push($(e)); - }); - } - - /* Remove any previous bindings, and rebind key events */ - $d.unbind('keydown.deck').bind('keydown.deck', function(e) { - switch (e.which) { - case options.keys.next: - methods.next(); - e.preventDefault(); - break; - case options.keys.previous: - methods.prev(); - e.preventDefault(); - break; - } - }); - - /* - Kick iframe videos, which dont like to redraw w/ transforms. - Remove this if Webkit ever fixes it. - */ - $.each(slides, function(i, $el) { - $el.unbind('webkitTransitionEnd').bind('webkitTransitionEnd', - function(event) { - var embeds = $(this).find('iframe').css('opacity', 0); - window.setTimeout(function() { - embeds.css('opacity', 1); - }, 100); - }); - }); - - updateStates(); - $d.trigger(events.initialize); - }, - - /* - jQuery.deck('go', index) - - index: integer - - Moves to the slide at the specified index. Index is 0-based, so - $.deck('go', 0); will move to the first slide. If index is out of bounds - or not a number the call is ignored. - */ - go: function(index) { - if (typeof index != 'number' || index < 0 || index >= slides.length) return; - - $d.trigger(events.change, [current, index]); - current = index; - updateStates(); - }, - - /* - jQuery.deck('next') - - Moves to the next slide. If the last slide is already active, the call - is ignored. - */ - next: function() { - methods.go(current+1); - }, - - /* - jQuery.deck('prev') - - Moves to the previous slide. If the first slide is already active, the - call is ignored. - */ - prev: function() { - methods.go(current-1); - }, - - /* - jQuery.deck('getSlide', index) - - index: integer, optional - - Returns a jQuery object containing the slide at index. If index is not - specified, the current slide is returned. - */ - getSlide: function(index) { - var i = typeof index !== 'undefined' ? index : current; - if (typeof i != 'number' || i < 0 || i >= slides.length) return null; - return slides[i]; - }, - - /* - jQuery.deck('getSlides') - - Returns all slides as an array of jQuery objects. - */ - getSlides: function() { - return slides; - }, - - /* - jQuery.deck('getContainer') - - Returns a jQuery object containing the deck container as defined by the - container option. - */ - getContainer: function() { - return $(options.selectors.container); - }, - - /* - jQuery.deck('getOptions') - - Returns the options object for the deck, including any overrides that - were defined at initialization. - */ - getOptions: function() { - return options; - }, - - /* - jQuery.deck('extend', name, method) - - name: string - method: function - - Adds method to the deck namespace with the key of name. This doesn’t - give access to any private member data — public methods must still be - used within method — but lets extension authors piggyback on the deck - namespace rather than pollute jQuery. - - $.deck('extend', 'alert', function(msg) { - alert(msg); - }); - - // Alerts 'boom' - $.deck('alert', 'boom'); - */ - extend: function(name, method) { - methods[name] = method; - } - }; - - /* jQuery extension */ - $[deck] = function(method, arg) { - if (methods[method]) { - return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); - } - else { - return methods.init(method, arg); - } - }; - - /* - The default settings object for a deck. All deck extensions should extend - this object to add defaults for any of their options. - - options.classes.after - This class is added to all slides that appear after the 'next' slide. - - options.classes.before - This class is added to all slides that appear before the 'previous' - slide. - - options.classes.childCurrent - This class is added to all elements in the DOM tree between the - 'current' slide and the deck container. For standard slides, this is - mostly seen and used for nested slides. - - options.classes.current - This class is added to the current slide. - - options.classes.next - This class is added to the slide immediately following the 'current' - slide. - - options.classes.onPrefix - This prefix, concatenated with the current slide index, is added to the - deck container as you change slides. - - options.classes.previous - This class is added to the slide immediately preceding the 'current' - slide. - - options.selectors.container - Elements matched by this CSS selector will be considered the deck - container. The deck container is used to scope certain states of the - deck, as with the onPrefix option, or with extensions such as deck.goto - and deck.menu. - - options.keys.next - The numeric keycode used to go to the next slide. - - options.keys.previous - The numeric keycode used to go to the previous slide. - */ - $[deck].defaults = { - classes: { - after: 'deck-after', - before: 'deck-before', - childCurrent: 'deck-child-current', - current: 'deck-current', - next: 'deck-next', - onPrefix: 'on-slide-', - previous: 'deck-previous' - }, - - selectors: { - container: '.deck-container' - }, - - keys: { - next: 39, // right arrow key - previous: 37 // left arrow key - } - }; - - $d.ready(function() { - $('html').addClass('ready'); - }); -})(jQuery, 'deck', document); \ No newline at end of file diff --git a/js/deck.goto.js b/js/deck.goto.js deleted file mode 100644 index f948628..0000000 --- a/js/deck.goto.js +++ /dev/null @@ -1,110 +0,0 @@ -/*! -Deck JS - deck.goto - v1.0 -Copyright (c) 2011 Caleb Troughton -Dual licensed under the MIT license and GPL license. -https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt -https://github.com/imakewebthings/deck.js/blob/master/GPL-license.txt -*/ - -/* -This module adds the necessary methods and key bindings to show and hide a form -for jumping to any slide number in the deck (and processes that form -accordingly). The form-showing state is indicated by the presence of a class on -the deck container. -*/ -(function($, deck, undefined) { - var $d = $(document); - - /* - Extends defaults/options. - - options.classes.goto - This class is added to the deck container when showing the Go To Slide - form. - - options.selectors.gotoForm - The element that matches this selector is the form that is submitted - when a user hits enter after typing a slide number in the gotoInput - element. - - options.selectors.gotoInput - The element that matches this selector is the text input field for - entering a slide number in the Go To Slide form. - - options.keys.goto - The numeric keycode used to toggle between showing and hiding the Go To - Slide form. - */ - $.extend(true, $[deck].defaults, { - classes: { - goto: 'deck-goto' - }, - - selectors: { - gotoForm: '.goto-form', - gotoInput: '#goto-slide' - }, - - keys: { - goto: 71 // g - } - }); - - /* - jQuery.deck('showGoTo') - - Shows the Go To Slide form by adding the class specified by the goto class - option to the deck container. - */ - $[deck]('extend', 'showGoTo', function() { - $[deck]('getContainer').addClass($[deck]('getOptions').classes.goto); - $($[deck]('getOptions').selectors.gotoInput).focus(); - }); - - /* - jQuery.deck('hideGoTo') - - Hides the Go To Slide form by removing the class specified by the goto class - option from the deck container. - */ - $[deck]('extend', 'hideGoTo', function() { - $[deck]('getContainer').removeClass($[deck]('getOptions').classes.goto); - $($[deck]('getOptions').selectors.gotoInput).blur(); - }); - - /* - jQuery.deck('toggleGoTo') - - Toggles between showing and hiding the Go To Slide form. - */ - $[deck]('extend', 'toggleGoTo', function() { - $[deck]($[deck]('getContainer').hasClass($[deck]('getOptions').classes.goto) ? 'hideGoTo' : 'showGoTo'); - }); - - $d.bind('deck.init', function() { - // Bind key events - $d.bind('keydown.deck', function(e) { - if (e.which == $[deck]('getOptions').keys.goto) { - e.preventDefault(); - $[deck]('toggleGoTo'); - } - }); - - // Process form submittal, go to the slide entered - $($[deck]('getOptions').selectors.gotoForm) - .unbind('submit.deck') - .bind('submit.deck', function(e) { - var $field = ($($[deck]('getOptions').selectors.gotoInput)), - i = parseInt($field.val(), 10); - - if (!($.isNaN(i) || i < 1 || i > $[deck]('getSlides').length)) { - $[deck]('go', i - 1); - $[deck]('hideGoTo'); - $field.val(''); - } - - e.preventDefault(); - }); - }); -})(jQuery, 'deck'); - diff --git a/js/deck.hash.js b/js/deck.hash.js deleted file mode 100644 index 24bab75..0000000 --- a/js/deck.hash.js +++ /dev/null @@ -1,110 +0,0 @@ -/*! -Deck JS - deck.hash - v1.0 -Copyright (c) 2011 Caleb Troughton -Dual licensed under the MIT license and GPL license. -https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt -https://github.com/imakewebthings/deck.js/blob/master/GPL-license.txt -*/ - -/* -This module adds deep linking to individual slides, enables internal links -to slides within decks, and updates the address bar with the hash as the user -moves through the deck. A permalink anchor is also updated. Standard themes -hide this link in browsers that support the History API, and show it for -those that do not. Slides that do not have an id are assigned one according to -the hashPrefix option. -*/ -(function ($, deck, window, undefined) { - var $d = $(document), - $window = $(window), - - /* Collection of internal fragment links in the deck */ - $internals, - - /* - Internal only function. Given a string, extracts the id from the hash, - matches it to the appropriate slide, and navigates there. - */ - goByHash = function(str) { - var id = str.substr(str.indexOf("#") + 1), - slides = $[deck]('getSlides'); - - $.each(slides, function(i, $el) { - if ($el.attr('id') === id) { - $[deck]('go', i); - return false; - } - }); - }; - - /* - Extends defaults/options. - - options.selectors.hashLink - The element matching this selector has its href attribute updated to - the hash of the current slide as the user navigates through the deck. - - options.hashPrefix - Every slide that does not have an id is assigned one at initialization. - Assigned ids take the form of hashPrefix + slideIndex, e.g., slide-0, - slide-12, etc. - */ - $.extend(true, $[deck].defaults, { - selectors: { - hashLink: '.deck-permalink' - }, - - hashPrefix: 'slide-' - }); - - - $d.bind('deck.init', function() { - $internals = $(); - - $.each($[deck]('getSlides'), function(i, $el) { - var hash; - - /* Hand out ids to the unfortunate slides born without them */ - if (!$el.attr('id')) { - $el.attr('id', $[deck]('getOptions').hashPrefix + i); - } - - hash ='#' + $el.attr('id'); - - /* Deep link to slides on init */ - if (hash === window.location.hash) { - $[deck]('go', i); - } - - /* Add internal links to this slide */ - $internals = $internals.add('a[href="' + hash + '"]'); - }); - - if (!Modernizr.hashchange) { - /* Set up internal links using click for the poor browsers - without a hashchange event. */ - $internals.bind('click.deck', function(e) { - goByHash($(this).attr('href')); - }); - } - }) - /* Update permalink and address bar on a slide change */ - .bind('deck.change', function(e, from, to) { - var hash = '#' + $[deck]('getSlide', to).attr('id'); - - $($[deck]('getOptions').selectors.hashLink).attr('href', hash); - if (Modernizr.history) { - window.history.replaceState({}, "", hash); - } - }); - - /* Deals with internal links in modern browsers */ - $window.bind('hashchange.deck', function(e) { - if (e.originalEvent.newURL) { - goByHash(e.originalEvent.newURL); - } - else { - goByHash(window.location.hash); - } - }); -})(jQuery, 'deck', this); \ No newline at end of file diff --git a/js/deck.menu.js b/js/deck.menu.js deleted file mode 100644 index 0e7309f..0000000 --- a/js/deck.menu.js +++ /dev/null @@ -1,84 +0,0 @@ -/*! -Deck JS - deck.menu - v1.0 -Copyright (c) 2011 Caleb Troughton -Dual licensed under the MIT license and GPL license. -https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt -https://github.com/imakewebthings/deck.js/blob/master/GPL-license.txt -*/ - -/* -This module adds the methods and key binding to show and hide a menu of all -slides in the deck. The deck menu state is indicated by the presence of a class -on the deck container. -*/ -(function($, deck, undefined) { - var $d = $(document); - - /* - Extends defaults/options. - - options.classes.menu - This class is added to the deck container when showing the slide menu. - - options.keys.menu - The numeric keycode used to toggle between showing and hiding the slide - menu. - */ - $.extend(true, $[deck].defaults, { - classes: { - menu: 'deck-menu' - }, - - keys: { - menu: 77 // m - } - }); - - /* - jQuery.deck('showMenu') - - Shows the slide menu by adding the class specified by the menu class option - to the deck container. - */ - $[deck]('extend', 'showMenu', function() { - $[deck]('getContainer').addClass($[deck]('getOptions').classes.menu); - $[deck]('getContainer').scrollTop($[deck]('getSlide').offset().top); - }); - - /* - jQuery.deck('hideMenu') - - Hides the slide menu by removing the class specified by the menu class - option from the deck container. - */ - $[deck]('extend', 'hideMenu', function() { - $[deck]('getContainer').removeClass($[deck]('getOptions').classes.menu); - $[deck]('getContainer').scrollTop(0); - }); - - /* - jQuery.deck('toggleMenu') - - Toggles between showing and hiding the slide menu. - */ - $[deck]('extend', 'toggleMenu', function() { - $[deck]('getContainer').hasClass($[deck]('getOptions').classes.menu) ? - $[deck]('hideMenu') : $[deck]('showMenu'); - }); - - $d.bind('deck.init', function() { - // Bind key events - $d.bind('keydown.deck', function(e) { - if (e.which == $[deck]('getOptions').keys.menu) { - $[deck]('toggleMenu'); - } - }); - }) - .bind('deck.change', function(e, from, to) { - var container = $[deck]('getContainer'); - if (container.hasClass($[deck]('getOptions').classes.menu)) { - container.scrollTop($[deck]('getSlide', to).offset().top); - } - }); -})(jQuery, 'deck'); - diff --git a/js/deck.navigation.js b/js/deck.navigation.js deleted file mode 100644 index b2c8109..0000000 --- a/js/deck.navigation.js +++ /dev/null @@ -1,72 +0,0 @@ -/*! -Deck JS - deck.navigation - v1.0 -Copyright (c) 2011 Caleb Troughton -Dual licensed under the MIT license and GPL license. -https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt -https://github.com/imakewebthings/deck.js/blob/master/GPL-license.txt -*/ - -/* -This module adds clickable previous and next links to the deck. -*/ -(function($, deck, undefined) { - var $d = $(document); - - /* - Extends defaults/options. - - options.classes.navDisabled - This class is added to a navigation link when that action is disabled. - It is added to the previous link when on the first slide, and to the - next link when on the last slide. - - options.selectors.nextLink - The elements that match this selector will move the deck to the next - slide when clicked. - - options.selectors.previousLink - The elements that match this selector will move to deck to the previous - slide when clicked. - */ - $.extend(true, $[deck].defaults, { - classes: { - navDisabled: 'deck-nav-disabled' - }, - - selectors: { - nextLink: '.deck-next-link', - previousLink: '.deck-prev-link' - } - }); - - $d.bind('deck.init', function() { - var opts = $[deck]('getOptions'); - - // Setup prev/next link events - $(opts.selectors.previousLink) - .unbind('click.deck') - .bind('click.deck', function(e) { - $[deck]('prev'); - e.preventDefault(); - }); - - $(opts.selectors.nextLink) - .unbind('click.deck') - .bind('click.deck', function(e) { - $[deck]('next'); - e.preventDefault(); - }); - - // Start on first slide, previous link is disabled - $(opts.selectors.previousLink).addClass(opts.classes.navDisabled); - }) - /* Update disabled states on deck change if last/first slide */ - .bind('deck.change', function(e, from, to) { - var opts = $[deck]('getOptions'), - last = $[deck]('getSlides').length - 1; - - $(opts.selectors.previousLink).toggleClass(opts.classes.navDisabled, !to); - $(opts.selectors.nextLink).toggleClass(opts.classes.navDisabled, to == last); - }); -})(jQuery, 'deck'); - diff --git a/js/deck.status.js b/js/deck.status.js deleted file mode 100644 index 0ed90a0..0000000 --- a/js/deck.status.js +++ /dev/null @@ -1,42 +0,0 @@ -/*! -Deck JS - deck.status - v1.0 -Copyright (c) 2011 Caleb Troughton -Dual licensed under the MIT license and GPL license. -https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt -https://github.com/imakewebthings/deck.js/blob/master/GPL-license.txt -*/ - -/* -This module adds a (current)/(total) style status indicator to the deck. -*/ -(function($, deck, undefined) { - var $d = $(document); - - /* - Extends defaults/options. - - options.selectors.statusCurrent - The element matching this selector displays the current slide number. - - options.selectors.statusTotal - The element matching this selector displays the total number of slides. - */ - $.extend(true, $[deck].defaults, { - selectors: { - statusCurrent: '.deck-status-current', - statusTotal: '.deck-status-total' - } - }); - - $d.bind('deck.init', function() { - // Start on first slide - $($[deck]('getOptions').selectors.statusCurrent).text(1); - // Set total slides once - $($[deck]('getOptions').selectors.statusTotal).text($[deck]('getSlides').length); - }) - /* Update current slide number with each change event */ - .bind('deck.change', function(e, from, to) { - $($[deck]('getOptions').selectors.statusCurrent).text(to + 1); - }); -})(jQuery, 'deck'); - diff --git a/sample.html b/sample.html index 305f3c6..1461048 100644 --- a/sample.html +++ b/sample.html @@ -2,7 +2,7 @@ - HTML5 Workshop #6 + CoderDeck Sample @@ -18,15 +18,20 @@ + + + - + + + - +

CoderDeck sample

- +
-

Show our name

-

Hide the login button when a user log's in, show a "Logging in", then the user's name once they are in.

- - +
- self.login = function() { - FB.login(function(response) { - if (response.authResponse) { - self.loggedIn(); - } - }); - }; + +
+

Full Page Code Editor

+

Basic full page code editor is created by adding a class of "coder-editor-full" along with "coder-editor" to a textarea. + Press run, then press "back", then modify some code and press "run" again

+ + +
- self.loggedIn = function() { - FB.api('/me', function(response) { - self.me = response; - FB.api('/me/friends', function(response) { - friends = response.data; - self.displayFriends(); - }); - }); - }; + +
+

Custom template and custom language

+

Basic full page code editor is created by adding a class of "coder-editor-full" along with "coder-editor" to a textarea. + Press run, then press "back", then modify some code and press "run" again

+ + +
- self.displayFriends = function() { - } + +
+

Instant Update Sample

+

Try modifying any of the HTML on the left, the right side should updated periodically as you type. This is done by adding a class of "coder-editor-instant" to the textarea

+ + +
- return self; -})(jQuery,window) - -parent.window.likeMaster = likeMaster; -</script> + +
+

Javascript/jQuery Example

+

Try modifying any of the HTML on the left, the right side should updated periodically as you type. This is done by adding a class of "coder-editor-instant" to the textarea

-<div style='text-align:center'> -<h1>Login to the LikeMaster™</h1> -<a href='javascript:void(0);' class='btn large primary' onclick='likeMaster.login();'>Click Me to Login!</a> -</div> + +
+ -
- - - + + - - - - + + + + + - - - - - + + + + -