sproutit-narwhal 0.1.106
Sign up to get free protection for your applications and to get access to all the features.
- data/DISTRIBUTION.yml +15 -0
- data/README.md +86 -0
- data/Rakefile +349 -0
- data/VERSION.yml +7 -0
- data/bin/activate +50 -0
- data/bin/activate.bash +50 -0
- data/bin/activate.cmd +3 -0
- data/bin/js +67 -0
- data/bin/json +2 -0
- data/bin/narwhal +67 -0
- data/bin/narwhal.cmd +29 -0
- data/bin/sea +45 -0
- data/bin/sea.cmd +25 -0
- data/bin/tusk +2 -0
- data/bin/tusk.cmd +5 -0
- data/catalog.json +902 -0
- data/docs/available-packages.md +32 -0
- data/docs/browser-api-plan.md +290 -0
- data/docs/browser-api.md +153 -0
- data/docs/download.md +25 -0
- data/docs/engines.md +32 -0
- data/docs/json-tool.md +121 -0
- data/docs/lib/binary.wiki +242 -0
- data/docs/lib/file.wiki +325 -0
- data/docs/lib/os/popen.md +70 -0
- data/docs/modules.md +38 -0
- data/docs/narwhal.md +487 -0
- data/docs/packages-howto.md +32 -0
- data/docs/packages.md +30 -0
- data/docs/posts/2009-07-29-hello-0.1.md +19 -0
- data/docs/quick-start.md +69 -0
- data/docs/sea.md +49 -0
- data/engines/browser/lib/binary.js +2 -0
- data/engines/browser/lib/reactor.js +21 -0
- data/engines/browser/lib/system.js +3 -0
- data/engines/default/lib/array.js +164 -0
- data/engines/default/lib/binary-engine.js +53 -0
- data/engines/default/lib/binary.js +755 -0
- data/engines/default/lib/date.js +8 -0
- data/engines/default/lib/file-engine.js +119 -0
- data/engines/default/lib/function.js +119 -0
- data/engines/default/lib/global.js +11 -0
- data/engines/default/lib/io-engine.js +26 -0
- data/engines/default/lib/json.js +488 -0
- data/engines/default/lib/object.js +69 -0
- data/engines/default/lib/os-engine.js +3 -0
- data/engines/default/lib/reactor.js +12 -0
- data/engines/default/lib/string.js +84 -0
- data/engines/default/lib/system.js +20 -0
- data/engines/default/lib/worker.js +133 -0
- data/engines/jsc/README.md +18 -0
- data/engines/jsc/bootstrap.js +53 -0
- data/engines/jsc/deps/http-parser/LICENSE +77 -0
- data/engines/jsc/deps/http-parser/README.md +145 -0
- data/engines/jsc/deps/http-parser/http_parser.c +6087 -0
- data/engines/jsc/deps/http-parser/http_parser.h +141 -0
- data/engines/jsc/deps/http-parser/http_parser.rl +500 -0
- data/engines/jsc/deps/http-parser/test.c +858 -0
- data/engines/jsc/include/binary-engine.h +11 -0
- data/engines/jsc/include/io-engine.h +23 -0
- data/engines/jsc/include/narwhal.h +427 -0
- data/engines/jsc/lib/file-engine.js +31 -0
- data/engines/jsc/lib/http.js +1 -0
- data/engines/jsc/lib/io-engine.js +202 -0
- data/engines/jsc/lib/os-engine.js +25 -0
- data/engines/jsc/lib/system.js +18 -0
- data/engines/jsc/lib/zip.js +1 -0
- data/engines/jsc/narwhal-jsc.c +273 -0
- data/engines/jsc/narwhal.c +29 -0
- data/engines/jsc/package.json +8 -0
- data/engines/jsc/src/binary-engine.cc +290 -0
- data/engines/jsc/src/file-engine.cc +405 -0
- data/engines/jsc/src/io-engine.cc +423 -0
- data/engines/jsc/src/jack/handler/jill.cc +710 -0
- data/engines/jsc/src/os-engine.cc +210 -0
- data/engines/rhino/bin/narwhal-rhino +68 -0
- data/engines/rhino/bin/narwhal-rhino.cmd +34 -0
- data/engines/rhino/bootstrap.js +119 -0
- data/engines/rhino/jars/jline.jar +0 -0
- data/engines/rhino/jars/jna.jar +0 -0
- data/engines/rhino/jars/js.jar +0 -0
- data/engines/rhino/lib/binary-engine.js +83 -0
- data/engines/rhino/lib/concurrency.js +6 -0
- data/engines/rhino/lib/event-queue.js +18 -0
- data/engines/rhino/lib/file-engine.js +216 -0
- data/engines/rhino/lib/http-client-engine.js +90 -0
- data/engines/rhino/lib/http-engine.js +10 -0
- data/engines/rhino/lib/io-engine.js +347 -0
- data/engines/rhino/lib/md5-engine.js +40 -0
- data/engines/rhino/lib/os-engine.js +150 -0
- data/engines/rhino/lib/packages-engine.js +71 -0
- data/engines/rhino/lib/sandbox-engine.js +70 -0
- data/engines/rhino/lib/system.js +38 -0
- data/engines/rhino/lib/worker-engine.js +23 -0
- data/engines/rhino/lib/zip.js +78 -0
- data/engines/rhino/package.json +4 -0
- data/engines/secure/lib/file.js +6 -0
- data/engines/secure/lib/system.js +6 -0
- data/engines/template/bin/narwhal-engine-name +32 -0
- data/engines/template/bootstrap.js +40 -0
- data/engines/template/lib/file-engine.js +118 -0
- data/engines/template/lib/system.js +17 -0
- data/examples/browser-deployment-jackconfig.js +35 -0
- data/examples/fibonacci-worker.js +35 -0
- data/examples/fibonacci.js +19 -0
- data/examples/hello +2 -0
- data/examples/narwhal +3 -0
- data/examples/not-quite-a-quine.js +1 -0
- data/extconf.rb +44 -0
- data/gem_bin/narwhal +5 -0
- data/gem_bin/sea +4 -0
- data/gem_bin/tusk +4 -0
- data/lib/args.js +849 -0
- data/lib/base16.js +16 -0
- data/lib/base64.js +120 -0
- data/lib/codec/base64.js +8 -0
- data/lib/crc32.js +60 -0
- data/lib/file-bootstrap.js +187 -0
- data/lib/file.js +659 -0
- data/lib/hash.js +28 -0
- data/lib/hashp.js +65 -0
- data/lib/html.js +16 -0
- data/lib/http-client.js +134 -0
- data/lib/http.js +17 -0
- data/lib/io.js +98 -0
- data/lib/jsmin.js +315 -0
- data/lib/jsonpath.js +89 -0
- data/lib/logger.js +55 -0
- data/lib/md4.js +146 -0
- data/lib/md5.js +164 -0
- data/lib/mime.js +166 -0
- data/lib/narwhal.js +102 -0
- data/lib/narwhal/client.js +261 -0
- data/lib/narwhal/compile.js +99 -0
- data/lib/narwhal/env.js +140 -0
- data/lib/narwhal/inline.js +106 -0
- data/lib/narwhal/json.js +324 -0
- data/lib/narwhal/json.md +178 -0
- data/lib/narwhal/repl.js +96 -0
- data/lib/narwhal/server-test.js +6 -0
- data/lib/narwhal/server.js +270 -0
- data/lib/narwhal/tusk.js +170 -0
- data/lib/narwhal/tusk/bin.js +13 -0
- data/lib/narwhal/tusk/bundle.js +0 -0
- data/lib/narwhal/tusk/catalog.js +22 -0
- data/lib/narwhal/tusk/clone.js +66 -0
- data/lib/narwhal/tusk/consolidate.js +25 -0
- data/lib/narwhal/tusk/create-catalog.js +80 -0
- data/lib/narwhal/tusk/engine.js +42 -0
- data/lib/narwhal/tusk/freeze.js +0 -0
- data/lib/narwhal/tusk/init.js +56 -0
- data/lib/narwhal/tusk/install.js +288 -0
- data/lib/narwhal/tusk/list.js +20 -0
- data/lib/narwhal/tusk/orphans.js +0 -0
- data/lib/narwhal/tusk/reheat.js +15 -0
- data/lib/narwhal/tusk/remove.js +15 -0
- data/lib/narwhal/tusk/search.js +145 -0
- data/lib/narwhal/tusk/update.js +21 -0
- data/lib/narwhal/tusk/upgrade.js +0 -0
- data/lib/os.js +33 -0
- data/lib/packages.js +423 -0
- data/lib/printf.js +169 -0
- data/lib/promise.js +352 -0
- data/lib/querystring.js +176 -0
- data/lib/ref-send.js +257 -0
- data/lib/regexp.js +12 -0
- data/lib/sandbox.js +422 -0
- data/lib/sha.js +112 -0
- data/lib/sha256.js +102 -0
- data/lib/struct.js +228 -0
- data/lib/term.js +179 -0
- data/lib/test/assert.js +95 -0
- data/lib/test/equiv.js +188 -0
- data/lib/test/jsdump.js +165 -0
- data/lib/test/runner.js +129 -0
- data/lib/unload.js +13 -0
- data/lib/uri.js +378 -0
- data/lib/url.js +5 -0
- data/lib/utf8.js +64 -0
- data/lib/util.js +985 -0
- data/lib/uuid.js +89 -0
- data/lib/xregexp.js +521 -0
- data/local.json.template +1 -0
- data/narwhal.gemspec +105 -0
- data/narwhal.js +213 -0
- data/package.json +26 -0
- data/packages/readline/engines/default/lib/readline.js +4 -0
- data/packages/readline/engines/rhino/lib/readline.js +6 -0
- data/packages/readline/package.json +5 -0
- data/sources.json +207 -0
- data/tests/all-tests.js +17 -0
- data/tests/args.js +31 -0
- data/tests/args/domain.js +215 -0
- data/tests/args/options.js +36 -0
- data/tests/args/shifting.js +92 -0
- data/tests/args/validation.js +31 -0
- data/tests/base64.js +23 -0
- data/tests/commonjs.js +3 -0
- data/tests/commonjs/all-tests.js +12 -0
- data/tests/commonjs/bytearray-encodings-tests.js +69 -0
- data/tests/commonjs/bytearray-tests.js +465 -0
- data/tests/commonjs/bytestring-encodings-tests.js +89 -0
- data/tests/commonjs/bytestring-tests.js +263 -0
- data/tests/commonjs/es5/all-tests.js +3 -0
- data/tests/commonjs/es5/bind.js +29 -0
- data/tests/commonjs/file-tests.js +315 -0
- data/tests/commonjs/file/dirname.js +31 -0
- data/tests/commonjs/file/extension.js +45 -0
- data/tests/commonjs/file/is-absolute.js +11 -0
- data/tests/commonjs/file/iterator.js +101 -0
- data/tests/commonjs/file/normal.js +27 -0
- data/tests/commonjs/file/path.js +17 -0
- data/tests/commonjs/file/relative.js +42 -0
- data/tests/commonjs/file/resolve.js +44 -0
- data/tests/commonjs/module-tests.js +9 -0
- data/tests/commonjs/modules/absolute/b.js +1 -0
- data/tests/commonjs/modules/absolute/program.js +5 -0
- data/tests/commonjs/modules/absolute/submodule/a.js +3 -0
- data/tests/commonjs/modules/absolute/test.js +9 -0
- data/tests/commonjs/modules/all-tests.js +47 -0
- data/tests/commonjs/modules/config.js +11 -0
- data/tests/commonjs/modules/cyclic/a.js +4 -0
- data/tests/commonjs/modules/cyclic/b.js +4 -0
- data/tests/commonjs/modules/cyclic/program.js +10 -0
- data/tests/commonjs/modules/cyclic/test.js +9 -0
- data/tests/commonjs/modules/determinism/program.js +3 -0
- data/tests/commonjs/modules/determinism/submodule/a.js +8 -0
- data/tests/commonjs/modules/determinism/submodule/b.js +2 -0
- data/tests/commonjs/modules/determinism/test.js +9 -0
- data/tests/commonjs/modules/exactExports/a.js +3 -0
- data/tests/commonjs/modules/exactExports/program.js +4 -0
- data/tests/commonjs/modules/exactExports/test.js +9 -0
- data/tests/commonjs/modules/hasOwnProperty/hasOwnProperty.js +0 -0
- data/tests/commonjs/modules/hasOwnProperty/program.js +3 -0
- data/tests/commonjs/modules/hasOwnProperty/test.js +9 -0
- data/tests/commonjs/modules/hasOwnProperty/toString.js +0 -0
- data/tests/commonjs/modules/method/a.js +12 -0
- data/tests/commonjs/modules/method/program.js +8 -0
- data/tests/commonjs/modules/method/test.js +9 -0
- data/tests/commonjs/modules/missing/program.js +8 -0
- data/tests/commonjs/modules/missing/test.js +9 -0
- data/tests/commonjs/modules/monkeys/a.js +1 -0
- data/tests/commonjs/modules/monkeys/program.js +4 -0
- data/tests/commonjs/modules/monkeys/test.js +9 -0
- data/tests/commonjs/modules/nested/a/b/c/d.js +3 -0
- data/tests/commonjs/modules/nested/program.js +3 -0
- data/tests/commonjs/modules/nested/test.js +9 -0
- data/tests/commonjs/modules/relative/program.js +5 -0
- data/tests/commonjs/modules/relative/submodule/a.js +1 -0
- data/tests/commonjs/modules/relative/submodule/b.js +2 -0
- data/tests/commonjs/modules/relative/test.js +9 -0
- data/tests/commonjs/modules/transitive/a.js +1 -0
- data/tests/commonjs/modules/transitive/b.js +1 -0
- data/tests/commonjs/modules/transitive/c.js +3 -0
- data/tests/commonjs/modules/transitive/program.js +3 -0
- data/tests/commonjs/modules/transitive/test.js +9 -0
- data/tests/file/all-tests.js +61 -0
- data/tests/file/fnmatch.js +102 -0
- data/tests/file/glob.js +466 -0
- data/tests/file/match.js +102 -0
- data/tests/global.js +6 -0
- data/tests/global/array.js +19 -0
- data/tests/hashes.js +94 -0
- data/tests/html.js +13 -0
- data/tests/io/stringio.js +21 -0
- data/tests/os/all-tests.js +4 -0
- data/tests/os/popen.js +41 -0
- data/tests/os/system.js +22 -0
- data/tests/printf.js +123 -0
- data/tests/query-string.js +87 -0
- data/tests/sandbox/byte-io.js +20 -0
- data/tests/sandbox/fileName.js +3 -0
- data/tests/sandbox/foo.js +0 -0
- data/tests/sandbox/reload.js +79 -0
- data/tests/string.js +35 -0
- data/tests/uri.js +41 -0
- data/tests/util/all-tests.js +79 -0
- data/tests/util/array.js +207 -0
- data/tests/util/array/is-arguments.js +29 -0
- data/tests/util/array/is-array-like.js +29 -0
- data/tests/util/case.js +9 -0
- data/tests/util/collection.js +104 -0
- data/tests/util/eq.js +57 -0
- data/tests/util/expand.js +45 -0
- data/tests/util/object.js +125 -0
- data/tests/util/operator.js +25 -0
- data/tests/util/range.js +19 -0
- data/tests/util/repr.js +26 -0
- data/tests/util/string.js +34 -0
- data/tests/util/unique.js +12 -0
- metadata +434 -0
data/lib/uuid.js
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
/*
|
2
|
+
Based on Math.uuid.js 1.4 by Robert Kieffer
|
3
|
+
|
4
|
+
----
|
5
|
+
Copyright (c) 2008, Robert Kieffer
|
6
|
+
All rights reserved.
|
7
|
+
|
8
|
+
Redistribution and use in source and binary forms, with or without
|
9
|
+
modification, are permitted provided that the following conditions are met:
|
10
|
+
|
11
|
+
* Redistributions of source code must retain the above copyright notice,
|
12
|
+
this list of conditions and the following disclaimer.
|
13
|
+
* Redistributions in binary form must reproduce the above copyright
|
14
|
+
notice, this list of conditions and the following disclaimer in the
|
15
|
+
documentation and/or other materials provided with the distribution.
|
16
|
+
* Neither the name of Robert Kieffer nor the names of its contributors
|
17
|
+
may be used to endorse or promote products derived from this software
|
18
|
+
without specific prior written permission.
|
19
|
+
|
20
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
21
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
22
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
23
|
+
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
24
|
+
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
25
|
+
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
26
|
+
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
27
|
+
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
28
|
+
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
29
|
+
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
30
|
+
POSSIBILITY OF SUCH DAMAGE.
|
31
|
+
|
32
|
+
*/
|
33
|
+
|
34
|
+
|
35
|
+
|
36
|
+
/*
|
37
|
+
* Generate a random uuid.
|
38
|
+
*
|
39
|
+
* USAGE: uuid.uuid(length, radix)
|
40
|
+
* length - the desired number of characters
|
41
|
+
* radix - the number of allowable values for each character.
|
42
|
+
*
|
43
|
+
* EXAMPLES:
|
44
|
+
* // No arguments - returns RFC4122, version 4 ID
|
45
|
+
* >>> Math.uuid()
|
46
|
+
* "92329D39-6F5C-4520-ABFC-AAB64544E172"
|
47
|
+
*
|
48
|
+
* // One argument - returns ID of the specified length
|
49
|
+
* >>> Math.uuid(15) // 15 character ID (default base=62)
|
50
|
+
* "VcydxgltxrVZSTV"
|
51
|
+
*
|
52
|
+
* // Two arguments - returns ID of the specified length, and radix. (Radix must be <= 62)
|
53
|
+
* >>> Math.uuid(8, 2) // 8 character ID (base=2)
|
54
|
+
* "01001010"
|
55
|
+
* >>> Math.uuid(8, 10) // 8 character ID (base=10)
|
56
|
+
* "47473046"
|
57
|
+
* >>> Math.uuid(8, 16) // 8 character ID (base=16)
|
58
|
+
* "098F4D35"
|
59
|
+
*/
|
60
|
+
|
61
|
+
|
62
|
+
var CHARS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
|
63
|
+
exports.uuid = function (len, radix) {
|
64
|
+
var chars = CHARS, uuid = [], rnd = Math.random;
|
65
|
+
radix = radix || chars.length;
|
66
|
+
|
67
|
+
if (len) {
|
68
|
+
// Compact form
|
69
|
+
for (var i = 0; i < len; i++) uuid[i] = chars[0 | rnd()*radix];
|
70
|
+
} else {
|
71
|
+
// rfc4122, version 4 form
|
72
|
+
var r;
|
73
|
+
|
74
|
+
// rfc4122 requires these characters
|
75
|
+
uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
|
76
|
+
uuid[14] = '4';
|
77
|
+
|
78
|
+
// Fill in random data. At i==19 set the high bits of clock sequence as
|
79
|
+
// per rfc4122, sec. 4.1.5
|
80
|
+
for (var i = 0; i < 36; i++) {
|
81
|
+
if (!uuid[i]) {
|
82
|
+
r = 0 | rnd()*16;
|
83
|
+
uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r & 0xf];
|
84
|
+
}
|
85
|
+
}
|
86
|
+
}
|
87
|
+
|
88
|
+
return uuid.join('');
|
89
|
+
};
|
data/lib/xregexp.js
ADDED
@@ -0,0 +1,521 @@
|
|
1
|
+
// RegExp
|
2
|
+
|
3
|
+
/** provides an augmented, cross-browser implementation of regular expressions
|
4
|
+
including support for additional modifiers and syntax. several convenience
|
5
|
+
methods and a recursive-construct parser are also included.
|
6
|
+
*/
|
7
|
+
|
8
|
+
/*preamble-steven-levithan
|
9
|
+
XRegExp 0.6.1
|
10
|
+
Copyright (c) 2007-2008 Steven Levithan <http://stevenlevithan.com>
|
11
|
+
MIT license
|
12
|
+
Based on XRegExp 0.5.1
|
13
|
+
*/
|
14
|
+
/*preamble-kris-kowal
|
15
|
+
Copyright (c) 2002-2008 Kris Kowal <http://cixar.com/~kris.kowal>
|
16
|
+
MIT License
|
17
|
+
Migrated to module system
|
18
|
+
*/
|
19
|
+
|
20
|
+
/** provides an augmented, cross-browser implementation of regular expressions
|
21
|
+
including support for additional modifiers and syntax. several convenience
|
22
|
+
methods and a recursive-construct parser are also included.
|
23
|
+
*/
|
24
|
+
|
25
|
+
// copy various native globals for reference. can't use the name ``native``
|
26
|
+
// because it's a reserved JavaScript keyword.
|
27
|
+
var real = {
|
28
|
+
exec: RegExp.prototype.exec,
|
29
|
+
match: String.prototype.match,
|
30
|
+
replace: String.prototype.replace,
|
31
|
+
split: String.prototype.split
|
32
|
+
},
|
33
|
+
/* regex syntax parsing with support for all the necessary cross-
|
34
|
+
browser and context issues (escapings, character classes, etc.) */
|
35
|
+
lib = {
|
36
|
+
part: /(?:[^\\([#\s.]+|\\(?!k<[\w$]+>|[pP]{[^}]+})[\S\s]?|\((?=\?(?!#|<[\w$]+>)))+|(\()(?:\?(?:(#)[^)]*\)|<([$\w]+)>))?|\\(?:k<([\w$]+)>|[pP]{([^}]+)})|(\[\^?)|([\S\s])/g,
|
37
|
+
replaceVar: /(?:[^$]+|\$(?![1-9$&`']|{[$\w]+}))+|\$(?:([1-9]\d*|[$&`'])|{([$\w]+)})/g,
|
38
|
+
extended: /^(?:\s+|#.*)+/,
|
39
|
+
quantifier: /^(?:[?*+]|{\d+(?:,\d*)?})/,
|
40
|
+
classLeft: /&&\[\^?/g,
|
41
|
+
classRight: /]/g
|
42
|
+
},
|
43
|
+
indexOf = function (array, item, from) {
|
44
|
+
for (var i = from || 0; i < array.length; i++)
|
45
|
+
if (array[i] === item) return i;
|
46
|
+
return -1;
|
47
|
+
},
|
48
|
+
brokenExecUndef = /()??/.exec("")[1] !== undefined,
|
49
|
+
plugins = {};
|
50
|
+
|
51
|
+
/*** XRegExp
|
52
|
+
accepts a pattern and flags, returns a new, extended RegExp object.
|
53
|
+
differs from a native regex in that additional flags and syntax are
|
54
|
+
supported and browser inconsistencies are ameliorated.
|
55
|
+
*/
|
56
|
+
XRegExp = function (pattern, flags) {
|
57
|
+
if (pattern instanceof RegExp) {
|
58
|
+
if (flags !== undefined)
|
59
|
+
throw TypeError("can't supply flags when constructing one RegExp from another");
|
60
|
+
return pattern.addFlags(); // new copy
|
61
|
+
}
|
62
|
+
|
63
|
+
var flags = flags || "",
|
64
|
+
singleline = flags.indexOf("s") > -1,
|
65
|
+
extended = flags.indexOf("x") > -1,
|
66
|
+
hasNamedCapture = false,
|
67
|
+
captureNames = [],
|
68
|
+
output = [],
|
69
|
+
part = lib.part,
|
70
|
+
match, cc, len, index, regex;
|
71
|
+
|
72
|
+
part.lastIndex = 0; // in case the last XRegExp compilation threw an error (unbalanced character class)
|
73
|
+
|
74
|
+
while (match = real.exec.call(part, pattern)) {
|
75
|
+
// comment pattern. this check must come before the capturing group check,
|
76
|
+
// because both match[1] and match[2] will be non-empty.
|
77
|
+
if (match[2]) {
|
78
|
+
// keep tokens separated unless the following token is a quantifier
|
79
|
+
if (!lib.quantifier.test(pattern.slice(part.lastIndex)))
|
80
|
+
output.push("(?:)");
|
81
|
+
// capturing group
|
82
|
+
} else if (match[1]) {
|
83
|
+
captureNames.push(match[3] || null);
|
84
|
+
if (match[3])
|
85
|
+
hasNamedCapture = true;
|
86
|
+
output.push("(");
|
87
|
+
// named backreference
|
88
|
+
} else if (match[4]) {
|
89
|
+
index = indexOf(captureNames, match[4]);
|
90
|
+
// keep backreferences separate from subsequent literal numbers
|
91
|
+
// preserve backreferences to named groups that are undefined at this point as literal strings
|
92
|
+
output.push(index > -1 ?
|
93
|
+
"\\" + (index + 1) + (isNaN(pattern.charAt(part.lastIndex)) ? "" : "(?:)") :
|
94
|
+
match[0]
|
95
|
+
);
|
96
|
+
// unicode element (requires plugin)
|
97
|
+
} else if (match[5]) {
|
98
|
+
output.push(plugins.unicode ?
|
99
|
+
plugins.unicode.get(match[5], match[0].charAt(1) === "P") :
|
100
|
+
match[0]
|
101
|
+
);
|
102
|
+
// character class opening delimiter ("[" or "[^")
|
103
|
+
// (non-native unicode elements are not supported within character classes)
|
104
|
+
} else if (match[6]) {
|
105
|
+
if (pattern.charAt(part.lastIndex) === "]") {
|
106
|
+
// for cross-browser compatibility with ECMA-262 v3 behavior,
|
107
|
+
// convert [] to (?!) and [^] to [\S\s].
|
108
|
+
output.push(match[6] === "[" ? "(?!)" : "[\\S\\s]");
|
109
|
+
part.lastIndex++;
|
110
|
+
} else {
|
111
|
+
// parse the character class with support for inner escapes and
|
112
|
+
// ES4's infinitely nesting intersection syntax ([&&[^&&[]]]).
|
113
|
+
cc = XRegExp.matchRecursive("&&" + pattern.slice(match.index), lib.classLeft, lib.classRight, "", {escapeChar: "\\"})[0];
|
114
|
+
output.push(match[6] + cc + "]");
|
115
|
+
part.lastIndex += cc.length + 1;
|
116
|
+
}
|
117
|
+
// dot ("."), pound sign ("#"), or whitespace character
|
118
|
+
} else if (match[7]) {
|
119
|
+
if (singleline && match[7] === ".") {
|
120
|
+
output.push("[\\S\\s]");
|
121
|
+
} else if (extended && lib.extended.test(match[7])) {
|
122
|
+
len = real.exec.call(lib.extended, pattern.slice(part.lastIndex - 1))[0].length;
|
123
|
+
// keep tokens separated unless the following token is a quantifier
|
124
|
+
if (!lib.quantifier.test(pattern.slice(part.lastIndex - 1 + len)))
|
125
|
+
output.push("(?:)");
|
126
|
+
part.lastIndex += len - 1;
|
127
|
+
} else {
|
128
|
+
output.push(match[7]);
|
129
|
+
}
|
130
|
+
} else {
|
131
|
+
output.push(match[0]);
|
132
|
+
}
|
133
|
+
}
|
134
|
+
|
135
|
+
regex = RegExp(output.join(""), real.replace.call(flags, /[sx]+/g, ""));
|
136
|
+
regex._x = {
|
137
|
+
source: pattern,
|
138
|
+
captureNames: hasNamedCapture ? captureNames : null
|
139
|
+
};
|
140
|
+
return regex;
|
141
|
+
};
|
142
|
+
|
143
|
+
// barebones plugin support for now (intentionally undocumented)
|
144
|
+
XRegExp.addPlugin = function (name, o) {
|
145
|
+
plugins[name] = o;
|
146
|
+
};
|
147
|
+
|
148
|
+
/*** RegExp.prototype.exec
|
149
|
+
adds named capture support, with values returned as ``result.name``.
|
150
|
+
also fixes two cross-browser issues, following the ECMA-262 v3 spec:
|
151
|
+
- captured values for non-participating capturing groups should be returned
|
152
|
+
as ``undefined``, rather than the empty string.
|
153
|
+
- the regex's ``lastIndex`` should not be incremented after zero-length
|
154
|
+
matches.
|
155
|
+
*/
|
156
|
+
RegExp.prototype.exec = function (str) {
|
157
|
+
var match = real.exec.call(this, str),
|
158
|
+
name, i, r2;
|
159
|
+
if (match) {
|
160
|
+
// fix browsers whose exec methods don't consistently return
|
161
|
+
// undefined for non-participating capturing groups
|
162
|
+
if (brokenExecUndef && match.length > 1) {
|
163
|
+
// r2 doesn't need /g or /y, but they shouldn't hurt
|
164
|
+
r2 = new RegExp("^" + this.source + "$(?!\\s)", this.getNativeFlags());
|
165
|
+
real.replace.call(match[0], r2, function () {
|
166
|
+
for (i = 1; i < arguments.length - 2; i++) {
|
167
|
+
if (arguments[i] === undefined) match[i] = undefined;
|
168
|
+
}
|
169
|
+
});
|
170
|
+
}
|
171
|
+
// attach named capture properties
|
172
|
+
if (this._x && this._x.captureNames) {
|
173
|
+
for (i = 1; i < match.length; i++) {
|
174
|
+
name = this._x.captureNames[i - 1];
|
175
|
+
if (name) match[name] = match[i];
|
176
|
+
}
|
177
|
+
}
|
178
|
+
// fix browsers that increment lastIndex after zero-length matches
|
179
|
+
if (this.global && this.lastIndex > (match.index + match[0].length))
|
180
|
+
this.lastIndex--;
|
181
|
+
}
|
182
|
+
return match;
|
183
|
+
};
|
184
|
+
|
185
|
+
/*** String.prototype.match
|
186
|
+
run the altered ``exec`` when called with a non-global regex.
|
187
|
+
*/
|
188
|
+
String.prototype.match = function (regex) {
|
189
|
+
if (!(regex instanceof RegExp))
|
190
|
+
regex = new XRegExp(regex);
|
191
|
+
if (regex.global)
|
192
|
+
return real.match.call(this, regex);
|
193
|
+
return regex.exec(this); // run the altered exec
|
194
|
+
};
|
195
|
+
|
196
|
+
/*** String.prototype.replace
|
197
|
+
add named capture support to replacement strings using the syntax
|
198
|
+
``${name}``, and to replacement functions as ``arguments[0].name``.
|
199
|
+
*/
|
200
|
+
String.prototype.replace = function (search, replacement) {
|
201
|
+
var captureNames = (search._x || {}).captureNames;
|
202
|
+
|
203
|
+
// if search is not a regex which uses named capture, use the native replace method
|
204
|
+
if (!(search instanceof RegExp && captureNames))
|
205
|
+
return real.replace.apply(this, arguments);
|
206
|
+
|
207
|
+
if (typeof replacement === "function") {
|
208
|
+
return real.replace.call(this, search, function () {
|
209
|
+
// change the arguments[0] string primitive to a String object which can store properties
|
210
|
+
arguments[0] = new String(arguments[0]);
|
211
|
+
// store named backreferences on arguments[0] before calling replacement
|
212
|
+
for (var i = 0; i < captureNames.length; i++) {
|
213
|
+
if (captureNames[i])
|
214
|
+
arguments[0][captureNames[i]] = arguments[i + 1];
|
215
|
+
}
|
216
|
+
return replacement.apply(window, arguments);
|
217
|
+
});
|
218
|
+
} else {
|
219
|
+
return real.replace.call(this, search, function () {
|
220
|
+
var args = arguments;
|
221
|
+
return real.replace.call(replacement, lib.replaceVar, function ($0, $1, $2) {
|
222
|
+
// numbered backreference or special variable
|
223
|
+
if ($1) {
|
224
|
+
switch ($1) {
|
225
|
+
case "$": return "$";
|
226
|
+
case "&": return args[0];
|
227
|
+
case "`": return args[args.length - 1].slice(0, args[args.length - 2]);
|
228
|
+
case "'": return args[args.length - 1].slice(args[args.length - 2] + args[0].length);
|
229
|
+
// numbered backreference
|
230
|
+
default:
|
231
|
+
/* what does "$10" mean?
|
232
|
+
- backreference 10, if 10 or more capturing groups exist
|
233
|
+
- backreference 1 followed by "0", if 1-9 capturing groups exist
|
234
|
+
- otherwise, it's the string "$10"
|
235
|
+
*/
|
236
|
+
var literalNumbers = "";
|
237
|
+
$1 = +$1; // type-convert
|
238
|
+
while ($1 > captureNames.length) {
|
239
|
+
literalNumbers = real.split.call($1, "").pop() + literalNumbers;
|
240
|
+
$1 = Math.floor($1 / 10); // drop the last digit
|
241
|
+
}
|
242
|
+
return ($1 ? args[$1] : "$") + literalNumbers;
|
243
|
+
}
|
244
|
+
// named backreference
|
245
|
+
} else if ($2) {
|
246
|
+
/* what does "${name}" mean?
|
247
|
+
- backreference to named capture "name", if it exists
|
248
|
+
- otherwise, it's the string "${name}"
|
249
|
+
*/
|
250
|
+
var index = indexOf(captureNames, $2);
|
251
|
+
return index > -1 ? args[index + 1] : $0;
|
252
|
+
} else {
|
253
|
+
return $0;
|
254
|
+
}
|
255
|
+
});
|
256
|
+
});
|
257
|
+
}
|
258
|
+
};
|
259
|
+
|
260
|
+
/*** String.prototype.split
|
261
|
+
a consistent cross-browser, ECMA-262 v3 compliant split method
|
262
|
+
*/
|
263
|
+
String.prototype.split = function (s /* separator */, limit) {
|
264
|
+
// if separator is not a regex, use the native split method
|
265
|
+
if (!(s instanceof RegExp))
|
266
|
+
return real.split.apply(this, arguments);
|
267
|
+
|
268
|
+
var output = [],
|
269
|
+
origLastIndex = s.lastIndex,
|
270
|
+
lastLastIndex = 0,
|
271
|
+
i = 0, match, lastLength;
|
272
|
+
|
273
|
+
/* behavior for limit: if it's...
|
274
|
+
- undefined: no limit
|
275
|
+
- NaN or zero: return an empty array
|
276
|
+
- a positive number: use limit after dropping any decimal
|
277
|
+
- a negative number: no limit
|
278
|
+
- other: type-convert, then use the above rules
|
279
|
+
*/
|
280
|
+
if (limit === undefined || +limit < 0) {
|
281
|
+
limit = false;
|
282
|
+
} else {
|
283
|
+
limit = Math.floor(+limit);
|
284
|
+
if (!limit)
|
285
|
+
return [];
|
286
|
+
}
|
287
|
+
|
288
|
+
if (s.global)
|
289
|
+
s.lastIndex = 0;
|
290
|
+
else
|
291
|
+
s = s.addFlags("g");
|
292
|
+
|
293
|
+
while ((!limit || i++ <= limit) && (match = s.exec(this))) { // run the altered exec!
|
294
|
+
if (s.lastIndex > lastLastIndex) {
|
295
|
+
output = output.concat(this.slice(lastLastIndex, match.index));
|
296
|
+
if (1 < match.length && match.index < this.length)
|
297
|
+
output = output.concat(match.slice(1));
|
298
|
+
lastLength = match[0].length; // only needed if s.lastIndex === this.length
|
299
|
+
lastLastIndex = s.lastIndex;
|
300
|
+
}
|
301
|
+
if (!match[0].length)
|
302
|
+
s.lastIndex++; // avoid an infinite loop
|
303
|
+
}
|
304
|
+
|
305
|
+
// since this uses test(), output must be generated before restoring lastIndex
|
306
|
+
output = lastLastIndex === this.length ?
|
307
|
+
(s.test("") && !lastLength ? output : output.concat("")) :
|
308
|
+
(limit ? output : output.concat(this.slice(lastLastIndex)));
|
309
|
+
s.lastIndex = origLastIndex; // only needed if s.global, else we're working with a copy of the regex
|
310
|
+
return output;
|
311
|
+
};
|
312
|
+
|
313
|
+
// intentionally undocumented
|
314
|
+
RegExp.prototype.getNativeFlags = function () {
|
315
|
+
return (this.global ? "g" : "") +
|
316
|
+
(this.ignoreCase ? "i" : "") +
|
317
|
+
(this.multiline ? "m" : "") +
|
318
|
+
(this.extended ? "x" : "") +
|
319
|
+
(this.sticky ? "y" : "");
|
320
|
+
};
|
321
|
+
|
322
|
+
/*** RegExp.prototype.addFlags
|
323
|
+
accepts flags; returns a new XRegExp object generated by recompiling
|
324
|
+
the regex with the additional flags (may include non-native flags).
|
325
|
+
the original regex object is not altered.
|
326
|
+
*/
|
327
|
+
RegExp.prototype.addFlags = function (flags) {
|
328
|
+
var regex = new XRegExp(this.source, (flags || "") + this.getNativeFlags());
|
329
|
+
if (this._x) {
|
330
|
+
regex._x = {
|
331
|
+
source: this._x.source,
|
332
|
+
captureNames: this._x.captureNames ? this._x.captureNames.slice(0) : null
|
333
|
+
};
|
334
|
+
}
|
335
|
+
return regex;
|
336
|
+
};
|
337
|
+
|
338
|
+
/*** RegExp.prototype.call
|
339
|
+
accepts a context object and string; returns the result of calling
|
340
|
+
``exec`` with the provided string. the context is ignored but is
|
341
|
+
accepted for congruity with ``Function.prototype.call``.
|
342
|
+
*/
|
343
|
+
RegExp.prototype.call = function (context, str) {
|
344
|
+
return this.exec(str);
|
345
|
+
};
|
346
|
+
|
347
|
+
/*** RegExp.prototype.apply
|
348
|
+
accepts a context object and arguments array; returns the result of
|
349
|
+
calling ``exec`` with the first value in the arguments array. the context
|
350
|
+
is ignored but is accepted for congruity with ``Function.prototype.apply``.
|
351
|
+
*/
|
352
|
+
RegExp.prototype.apply = function (context, args) {
|
353
|
+
return this.exec(args[0]);
|
354
|
+
};
|
355
|
+
|
356
|
+
/*** XRegExp.cache
|
357
|
+
accepts a pattern and flags; returns an XRegExp object. if the pattern
|
358
|
+
and flag combination has previously been cached, the cached copy is
|
359
|
+
returned, otherwise the new object is cached.
|
360
|
+
*/
|
361
|
+
XRegExp.cache = function (pattern, flags) {
|
362
|
+
var key = "/" + pattern + "/" + (flags || "");
|
363
|
+
return XRegExp.cache[key] || (XRegExp.cache[key] = new XRegExp(pattern, flags));
|
364
|
+
};
|
365
|
+
|
366
|
+
/*** XRegExp.escape
|
367
|
+
accepts a string; returns the string with regex metacharacters escaped.
|
368
|
+
the returned string can safely be used within a regex to match a literal
|
369
|
+
string. escaped characters are [, ], {, }, (, ), -, *, +, ?, ., \, ^, $,
|
370
|
+
|, #, [comma], and whitespace.
|
371
|
+
*/
|
372
|
+
XRegExp.escape = function (str) {
|
373
|
+
return str.replace(/[-[\]{}()*+?.\\^$|,#\s]/g, "\\$&");
|
374
|
+
};
|
375
|
+
|
376
|
+
/*** XRegExp.matchRecursive
|
377
|
+
accepts a string to search, left and right delimiters as regex pattern
|
378
|
+
strings, optional regex flags (may include non-native s, x, and y flags),
|
379
|
+
and an options object which allows setting an escape character and changing
|
380
|
+
the return format from an array of matches to a two-dimensional array of
|
381
|
+
string parts with extended position data. returns an array of matches
|
382
|
+
(optionally with extended data), allowing nested instances of left and right
|
383
|
+
delimiters. use the g flag to return all matches, otherwise only the first
|
384
|
+
is returned. if delimiters are unbalanced within the subject data, an error
|
385
|
+
is thrown.
|
386
|
+
|
387
|
+
this function admittedly pushes the boundaries of what can be accomplished
|
388
|
+
sensibly without a "real" parser. however, by doing so it provides flexible
|
389
|
+
and powerful recursive parsing capabilities with minimal code weight.
|
390
|
+
|
391
|
+
warning: the ``escapeChar`` option is considered experimental and might be
|
392
|
+
changed or removed in future versions of XRegExp.
|
393
|
+
|
394
|
+
unsupported features:
|
395
|
+
- backreferences within delimiter patterns when using ``escapeChar``.
|
396
|
+
- although providing delimiters as regex objects adds the minor feature of
|
397
|
+
independent delimiter flags, it introduces other limitations and is only
|
398
|
+
intended to be done by the ``XRegExp`` constructor (which can't call
|
399
|
+
itself while building a regex).
|
400
|
+
*/
|
401
|
+
XRegExp.matchRecursive = function (str, left, right, flags, options) {
|
402
|
+
var options = options || {},
|
403
|
+
escapeChar = options.escapeChar,
|
404
|
+
vN = options.valueNames,
|
405
|
+
flags = flags || "",
|
406
|
+
global = flags.indexOf("g") > -1,
|
407
|
+
ignoreCase = flags.indexOf("i") > -1,
|
408
|
+
multiline = flags.indexOf("m") > -1,
|
409
|
+
sticky = flags.indexOf("y") > -1,
|
410
|
+
/* sticky mode has its own handling in this function, which means you
|
411
|
+
can use flag "y" even in browsers which don't support it natively */
|
412
|
+
flags = flags.replace(/y/g, ""),
|
413
|
+
left = left instanceof RegExp ? (left.global ? left : left.addFlags("g")) : new XRegExp(left, "g" + flags),
|
414
|
+
right = right instanceof RegExp ? (right.global ? right : right.addFlags("g")) : new XRegExp(right, "g" + flags),
|
415
|
+
output = [],
|
416
|
+
openTokens = 0,
|
417
|
+
delimStart = 0,
|
418
|
+
delimEnd = 0,
|
419
|
+
lastOuterEnd = 0,
|
420
|
+
outerStart, innerStart, leftMatch, rightMatch, escaped, esc;
|
421
|
+
|
422
|
+
if (escapeChar) {
|
423
|
+
if (escapeChar.length > 1) throw SyntaxError("can't supply more than one escape character");
|
424
|
+
if (multiline) throw TypeError("can't supply escape character when using the multiline flag");
|
425
|
+
escaped = XRegExp.escape(escapeChar);
|
426
|
+
/* Escape pattern modifiers:
|
427
|
+
/g - not needed here
|
428
|
+
/i - included
|
429
|
+
/m - **unsupported**, throws error
|
430
|
+
/s - handled by XRegExp when delimiters are provided as strings
|
431
|
+
/x - handled by XRegExp when delimiters are provided as strings
|
432
|
+
/y - not needed here; supported by other handling in this function
|
433
|
+
*/
|
434
|
+
esc = new RegExp(
|
435
|
+
"^(?:" + escaped + "[\\S\\s]|(?:(?!" + left.source + "|" + right.source + ")[^" + escaped + "])+)+",
|
436
|
+
ignoreCase ? "i" : ""
|
437
|
+
);
|
438
|
+
}
|
439
|
+
|
440
|
+
while (true) {
|
441
|
+
/* advance the starting search position to the end of the last delimiter match.
|
442
|
+
a couple special cases are also covered:
|
443
|
+
- if using an escape character, advance to the next delimiter's starting position,
|
444
|
+
skipping any escaped characters
|
445
|
+
- first time through, reset lastIndex in case delimiters were provided as regexes
|
446
|
+
*/
|
447
|
+
left.lastIndex = right.lastIndex = delimEnd +
|
448
|
+
(escapeChar ? (esc.exec(str.slice(delimEnd)) || [""])[0].length : 0);
|
449
|
+
|
450
|
+
leftMatch = left.exec(str);
|
451
|
+
rightMatch = right.exec(str);
|
452
|
+
|
453
|
+
// only keep the result which matched earlier in the string
|
454
|
+
if (leftMatch && rightMatch) {
|
455
|
+
if (leftMatch.index <= rightMatch.index)
|
456
|
+
rightMatch = null;
|
457
|
+
else leftMatch = null;
|
458
|
+
}
|
459
|
+
|
460
|
+
/* paths*:
|
461
|
+
leftMatch | rightMatch | openTokens | result
|
462
|
+
1 | 0 | 1 | ...
|
463
|
+
1 | 0 | 0 | ...
|
464
|
+
0 | 1 | 1 | ...
|
465
|
+
0 | 1 | 0 | throw
|
466
|
+
0 | 0 | 1 | throw
|
467
|
+
0 | 0 | 0 | break
|
468
|
+
* - does not include the sticky mode special case
|
469
|
+
- the loop ends after the first completed match if not in global mode
|
470
|
+
*/
|
471
|
+
|
472
|
+
if (leftMatch || rightMatch) {
|
473
|
+
delimStart = (leftMatch || rightMatch).index;
|
474
|
+
delimEnd = (leftMatch ? left : right).lastIndex;
|
475
|
+
} else if (!openTokens) {
|
476
|
+
break;
|
477
|
+
}
|
478
|
+
|
479
|
+
if (sticky && !openTokens && delimStart > lastOuterEnd)
|
480
|
+
break;
|
481
|
+
|
482
|
+
if (leftMatch) {
|
483
|
+
if (!openTokens++) {
|
484
|
+
outerStart = delimStart;
|
485
|
+
innerStart = delimEnd;
|
486
|
+
}
|
487
|
+
} else if (rightMatch && openTokens) {
|
488
|
+
if (!--openTokens) {
|
489
|
+
if (vN) {
|
490
|
+
if (vN[0] && outerStart > lastOuterEnd)
|
491
|
+
output.push([vN[0], str.slice(lastOuterEnd, outerStart), lastOuterEnd, outerStart]);
|
492
|
+
if (vN[1]) output.push([vN[1], str.slice(outerStart, innerStart), outerStart, innerStart]);
|
493
|
+
if (vN[2]) output.push([vN[2], str.slice(innerStart, delimStart), innerStart, delimStart]);
|
494
|
+
if (vN[3]) output.push([vN[3], str.slice(delimStart, delimEnd), delimStart, delimEnd]);
|
495
|
+
} else {
|
496
|
+
output.push(str.slice(innerStart, delimStart));
|
497
|
+
}
|
498
|
+
lastOuterEnd = delimEnd;
|
499
|
+
if (!global)
|
500
|
+
break;
|
501
|
+
}
|
502
|
+
} else {
|
503
|
+
// reset lastIndex in case delimiters were provided as regexes
|
504
|
+
left.lastIndex = right.lastIndex = 0;
|
505
|
+
throw Error("subject data contains unbalanced delimiters");
|
506
|
+
}
|
507
|
+
|
508
|
+
// if the delimiter matched an empty string, advance delimEnd to avoid an infinite loop
|
509
|
+
if (delimStart === delimEnd)
|
510
|
+
delimEnd++;
|
511
|
+
}
|
512
|
+
|
513
|
+
if (global && !sticky && vN && vN[0] && str.length > lastOuterEnd)
|
514
|
+
output.push([vN[0], str.slice(lastOuterEnd), lastOuterEnd, str.length]);
|
515
|
+
|
516
|
+
// reset lastIndex in case delimiters were provided as regexes
|
517
|
+
left.lastIndex = right.lastIndex = 0;
|
518
|
+
|
519
|
+
return output;
|
520
|
+
};
|
521
|
+
|