liquid_cms 0.3.0.1 → 0.3.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.rdoc +5 -1
- data/Gemfile.lock +1 -1
- data/README.rdoc +5 -1
- data/app/helpers/cms/common_helper.rb +1 -0
- data/app/views/cms/pages/_page.html.erb +2 -1
- data/app/views/layouts/cms.html.erb +2 -1
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/LICENSE +2 -2
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/css/csscolors.css +12 -8
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/css/docs.css +123 -29
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/csstest.html +1 -1
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/htmltest.html +1 -1
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/index.html +232 -179
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/js/codemirror.js +211 -65
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/js/editor.js +360 -194
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/js/mirrorframe.js +1 -1
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/js/parsecss.js +11 -7
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/js/parsejavascript.js +14 -5
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/js/parsesparql.js +1 -1
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/js/select.js +140 -87
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/js/stringstream.js +5 -0
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/js/tokenizejavascript.js +1 -1
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/js/undo.js +7 -7
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/manual.html +148 -52
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/story.html +631 -614
- data/lib/generators/liquid_cms/templates/public/cms/stylesheets/styles.css +7 -7
- data/lib/liquid_cms/version.rb +1 -1
- metadata +4 -26
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/contrib/lua/LICENSE +0 -32
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/contrib/lua/css/luacolors.css +0 -63
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/contrib/lua/index.html +0 -68
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/contrib/lua/js/parselua.js +0 -253
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/contrib/php/LICENSE +0 -37
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/contrib/php/css/phpcolors.css +0 -114
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/contrib/php/index.html +0 -292
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/contrib/php/js/parsephp.js +0 -371
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/contrib/php/js/parsephphtmlmixed.js +0 -90
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/contrib/php/js/tokenizephp.js +0 -1006
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/contrib/plsql/LICENSE +0 -22
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/contrib/plsql/css/plsqlcolors.css +0 -57
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/contrib/plsql/index.html +0 -67
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/contrib/plsql/js/parseplsql.js +0 -233
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/contrib/python/LICENSE +0 -32
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/contrib/python/css/pythoncolors.css +0 -58
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/contrib/python/index.html +0 -141
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/contrib/python/js/parsepython.js +0 -542
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/contrib/sql/LICENSE +0 -22
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/contrib/sql/css/sqlcolors.css +0 -57
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/contrib/sql/index.html +0 -56
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/contrib/sql/js/parsesql.js +0 -211
@@ -1,292 +0,0 @@
|
|
1
|
-
<!--
|
2
|
-
Copyright (c) 2008-2009 Yahoo! Inc. All rights reserved.
|
3
|
-
The copyrights embodied in the content of this file are licensed by
|
4
|
-
Yahoo! Inc. under the BSD (revised) open source license
|
5
|
-
|
6
|
-
@author Dan Vlad Dascalescu <dandv@yahoo-inc.com>
|
7
|
-
|
8
|
-
-->
|
9
|
-
|
10
|
-
|
11
|
-
<html xmlns="http://www.w3.org/1999/xhtml">
|
12
|
-
<head>
|
13
|
-
<script src="../../js/codemirror.js" type="text/javascript"></script>
|
14
|
-
<title>CodeMirror: PHP+HTML+JavaScript+CSS mixed-mode demonstration</title>
|
15
|
-
<link rel="stylesheet" type="text/css" href="../../css/docs.css"/>
|
16
|
-
</head>
|
17
|
-
<body style="padding: 20px;">
|
18
|
-
|
19
|
-
<p>This is a complex demonstration of the <b>PHP+HTML+JavaScript+CSS mixed-mode
|
20
|
-
syntax highlight</b> capabilities of <a href="../../index.html">CodeMirror</a>.
|
21
|
-
<?php ... ?> tags use the PHP parser, <script> tags use the JavaScript
|
22
|
-
parser, and <style> tags use the CSS parser. The rest of the content is
|
23
|
-
parsed using the XML parser in HTML mode.</p>
|
24
|
-
|
25
|
-
<p>Features of the PHP parser:
|
26
|
-
<ul>
|
27
|
-
<li>special "deprecated" style for PHP4 keywords like 'var'
|
28
|
-
<li>support for PHP 5.3 keywords: 'namespace', 'use'
|
29
|
-
<li>911 predefined constants, 1301 predefined functions, 105 predeclared classes
|
30
|
-
from a typical PHP installation in a LAMP environment
|
31
|
-
<li>new feature: syntax error flagging, thus enabling strict parsing of:
|
32
|
-
<ol>
|
33
|
-
<li>function definitions with explicitly or implicitly typed arguments and default values
|
34
|
-
<li>modifiers (public, static etc.) applied to method and member definitions
|
35
|
-
<li>foreach(array_expression as $key [=> $value]) loops
|
36
|
-
</ol>
|
37
|
-
<li>differentiation between single-quoted strings and double-quoted interpolating strings
|
38
|
-
</ul>
|
39
|
-
</p>
|
40
|
-
|
41
|
-
<div style="border: 1px solid black; padding: 3px; background-color: #F8F8F8">
|
42
|
-
<textarea id="code" cols="120" rows="30">
|
43
|
-
The "root" parser is XML in HTML mode.
|
44
|
-
Next, we can switch into PHP mode, for example. This is
|
45
|
-
<?php echo 'text output by';
|
46
|
-
?>
|
47
|
-
PHP. </b>
|
48
|
-
On the line above, we just had an XML syntax error due to the </b> tag not being opened.
|
49
|
-
|
50
|
-
<?xml version='1.0' encoding='UTF-8' standalone='yes'?> HTML text will follow
|
51
|
-
<html>
|
52
|
-
<head>
|
53
|
-
<title>Similarly, the 'script' tag will switch to the JavaScript parser:</title>
|
54
|
-
<script type="text/javascript">
|
55
|
-
// Press enter inside the object and your new line will be suitably
|
56
|
-
// indented.
|
57
|
-
var keyBindings = {
|
58
|
-
enter: "newline-and-indent",
|
59
|
-
tab: "reindent-selection",
|
60
|
-
ctrl_enter: "reparse-buffer",
|
61
|
-
ctrl_z: "undo",
|
62
|
-
ctrl_y: "redo",
|
63
|
-
ctrl_backspace: "undo-for-safari-which-stupidly-enough-blocks-ctrl-z"
|
64
|
-
};
|
65
|
-
|
66
|
-
// Press tab on the next line and the wrong indentation will be fixed.
|
67
|
-
var regex = /foo|bar/i;
|
68
|
-
|
69
|
-
function example(x) {
|
70
|
-
// Local variables get a different colour than global ones.
|
71
|
-
var y = 44.4;
|
72
|
-
return x + y - z;
|
73
|
-
}
|
74
|
-
</script>
|
75
|
-
<style>
|
76
|
-
/* Some example CSS */
|
77
|
-
|
78
|
-
@import url("something.css");
|
79
|
-
|
80
|
-
body {
|
81
|
-
margin: 0;
|
82
|
-
padding: 3em 6em;
|
83
|
-
font-family: tahoma, arial, sans-serif;
|
84
|
-
color: #000;
|
85
|
-
}
|
86
|
-
|
87
|
-
#navigation a {
|
88
|
-
font-weight: bold;
|
89
|
-
text-decoration: none !important;
|
90
|
-
}
|
91
|
-
|
92
|
-
h1 {
|
93
|
-
font-size: 2.5em;
|
94
|
-
}
|
95
|
-
|
96
|
-
h1:before, h2:before {
|
97
|
-
content: "::";
|
98
|
-
}
|
99
|
-
|
100
|
-
code {
|
101
|
-
font-family: courier, monospace;
|
102
|
-
font-size: 80%;
|
103
|
-
color: #418A8A;
|
104
|
-
}
|
105
|
-
</style>
|
106
|
-
</head>
|
107
|
-
|
108
|
-
<body>
|
109
|
-
|
110
|
-
The PHP code below contains some deliberate errors. Play with the editor by fixing them
|
111
|
-
and observing how the highlight changes.
|
112
|
-
|
113
|
-
<?php
|
114
|
-
namespace A;
|
115
|
-
namespace A::B::C;
|
116
|
-
namespace A::::B;
|
117
|
-
namespace A::B::C::;
|
118
|
-
namespace A::B::C::D x;
|
119
|
-
self::range($row['lft'], $row['rgt'])); // error: extra ')'
|
120
|
-
$a = (b() + 4) 5 foo; // error: missing operators
|
121
|
-
self::$var;
|
122
|
-
$parent = self::range($max + 1, $max + 1);
|
123
|
-
$row[attributes][$attribute_name] = $attribute_value;
|
124
|
-
$row[attributes()][$attribute_name] = $attribute_value;
|
125
|
-
$row[attributes(5)][$attribute_name] = $attribute_value;
|
126
|
-
$row[$attributes()][$attribute_name] = $attribute_value;
|
127
|
-
abstract class 5 extends foo implements echo {
|
128
|
-
private function domainObjectBuilder() {
|
129
|
-
return $this->use_domain_object_builder
|
130
|
-
? $this->domain()->objectBuilder()
|
131
|
-
: null;
|
132
|
-
}
|
133
|
-
|
134
|
-
const $myconst = 'some string';
|
135
|
-
$array[myconst] = 4;
|
136
|
-
// this is a single-line C++-style comment
|
137
|
-
# this is a single-line shell-style comment
|
138
|
-
private var $a = __FILE__;
|
139
|
-
protected static $b = timezone_transitions_get('some parameter here');
|
140
|
-
global $g = isset("string");
|
141
|
-
static $s = hash_update_file; // warning: predefined function non-call
|
142
|
-
function mike ($var) $foo;
|
143
|
-
mike(A::func(param));
|
144
|
-
func($b $c); // error: function parameters must be comma-separated
|
145
|
-
foo bar; // error: no operator
|
146
|
-
$baz $quux; // error: no operator
|
147
|
-
public abstract function loadPageXML(util_FilePath $filename, $merge=0+$foo, $x, $y=3) {
|
148
|
-
$newrow[$key] = $val;
|
149
|
-
$newresult[] = $row;
|
150
|
-
$state = $row['c'] == 1;
|
151
|
-
$attribute_values[$attribute_name] = null;
|
152
|
-
$row['attributes'][$attribute_name] = $attribute_value;
|
153
|
-
$result[$row['element']][$row['attribute']] = $row['value'];
|
154
|
-
$sql = "multiline string
|
155
|
-
line2 is special - it'll interpolate variables like $state and method calls
|
156
|
-
{$this->cache->add($key, 5)} and maybe \"more\"
|
157
|
-
|
158
|
-
line5";
|
159
|
-
$sql = 'multiline string
|
160
|
-
single quoting means no \'interpolation\' like "$start" or method call
|
161
|
-
{$this->cache->add($key, 5)} will happen
|
162
|
-
|
163
|
-
line5';
|
164
|
-
$bitpattern = 1 << 2;
|
165
|
-
$bitpattern <<= 3;
|
166
|
-
$incorrect = <<< 5 EOSTRING // FIXME: CodeMirror update bug: add a letter before 5 and notice that syntax is not updated until EOF, even with continuousScanning: 500
|
167
|
-
error: the identifier must conform to the identifier rules
|
168
|
-
EOSTRING;
|
169
|
-
$sql = <<< EOSQL
|
170
|
-
SELECT attribute, element, value
|
171
|
-
FROM attribute_values
|
172
|
-
WHERE dimension = ?
|
173
|
-
EOSQL;
|
174
|
-
$this->lr_cache->add($key, self::range($row['lft'], $row['rgt']));
|
175
|
-
$composite_string = <<<EOSTRING
|
176
|
-
some lines here
|
177
|
-
EOSTRING
|
178
|
-
. 'something extra';
|
179
|
-
$page_lft = ($domain->name() == 'page') ? $start + 1 : $page_start + 1;
|
180
|
-
echo "This is class foo";
|
181
|
-
echo "a = ".$this ->a[2+3*$array["foo"]]."";
|
182
|
-
echo "b = {$this->b}"; // FIXME: highlight interpolation in strings
|
183
|
-
}
|
184
|
-
final function makecoffee error($types = array("cappuccino"), $coffeeMaker = NULL) {
|
185
|
-
$out_of_way_amount = $max - $child->left() + 1;
|
186
|
-
$absolute_pos = $child->left() - $move->width();
|
187
|
-
$varfunc(1, 'x');
|
188
|
-
$varfunc(1, 'x') + foo() - 5;
|
189
|
-
$funcarray[$i]('param1', $param2);
|
190
|
-
$lr[$domain_name] = $this->get_left_and_right($domain,
|
191
|
-
$dimension_name,
|
192
|
-
$element_name);
|
193
|
-
$domain_list = is_null($domain) ?
|
194
|
-
r3_Domain::names() :
|
195
|
-
array($domain->name());
|
196
|
-
foreach (r3_Domain::names() as $domain_name) {
|
197
|
-
$placeholders = 'distance LIKE '
|
198
|
-
. implode(array_fill(1, $num_distances, '?'),
|
199
|
-
' OR distance LIKE ');
|
200
|
-
|
201
|
-
}
|
202
|
-
return $this->target*$this->trans+myfunc(__METHOD__);
|
203
|
-
/*
|
204
|
-
echo 'This is a test'; /* This comment will cause a problem */
|
205
|
-
*/
|
206
|
-
}
|
207
|
-
switch( $type ) {
|
208
|
-
case "r3core_AddTemplateToTargetEvent":
|
209
|
-
$this->notifyAddTemplateToTarget( $genevent );
|
210
|
-
break;
|
211
|
-
case "r3core_GenerateTargetEvent" $this:
|
212
|
-
for($i=0; $i<=this->method(); $i++) {
|
213
|
-
echo 'Syntax "highlighting"';
|
214
|
-
}
|
215
|
-
try {
|
216
|
-
foreach($array xor $loader->parse_fn($filename) as $key => value) {
|
217
|
-
namespace r3;
|
218
|
-
}
|
219
|
-
} catch( Exception $e ) {
|
220
|
-
/** restore the backup
|
221
|
-
*/
|
222
|
-
$this->loadAll($tmp, $event, true);
|
223
|
-
// `php -l` doesn't complain at all at this (it assumes string constants):
|
224
|
-
this + makes * no - sense;
|
225
|
-
}
|
226
|
-
|
227
|
-
break;
|
228
|
-
|
229
|
-
default moo:
|
230
|
-
throw new r3_util_Exception( get_class( $genevent ) . " does not map" );
|
231
|
-
}
|
232
|
-
|
233
|
-
|
234
|
-
};
|
235
|
-
|
236
|
-
?>
|
237
|
-
|
238
|
-
<r3:cphp>
|
239
|
-
php("works", $here, 2);
|
240
|
-
</r3:cphp>
|
241
|
-
|
242
|
-
<r4:cphp>
|
243
|
-
class foo {
|
244
|
-
// a comment
|
245
|
-
var $a;
|
246
|
-
var $b;
|
247
|
-
};
|
248
|
-
</r4:cphp>
|
249
|
-
|
250
|
-
<h1>This is an <?php # echo 'simple';?> example.</h1>
|
251
|
-
<p>The header above will say 'This is an example'.</p>
|
252
|
-
<h1>This is an <?php // echo 'simple';?> example.</h1>
|
253
|
-
|
254
|
-
<?php echo; ?>
|
255
|
-
<body>
|
256
|
-
|
257
|
-
<?php echo "<html>
|
258
|
-
<head>
|
259
|
-
<script>
|
260
|
-
var foo = 'bar';
|
261
|
-
</script>
|
262
|
-
<style>
|
263
|
-
span.test {font-family: arial, 'lucida console', sans-serif}
|
264
|
-
</style>
|
265
|
-
</head>
|
266
|
-
<body>
|
267
|
-
<!-- comment -->
|
268
|
-
</body>
|
269
|
-
</html>"; ?>
|
270
|
-
|
271
|
-
</body>
|
272
|
-
</html>
|
273
|
-
|
274
|
-
|
275
|
-
</textarea>
|
276
|
-
</div>
|
277
|
-
|
278
|
-
<script type="text/javascript">
|
279
|
-
var editor = CodeMirror.fromTextArea('code', {
|
280
|
-
height: "350px",
|
281
|
-
parserfile: ["parsexml.js", "parsecss.js", "tokenizejavascript.js", "parsejavascript.js",
|
282
|
-
"../contrib/php/js/tokenizephp.js", "../contrib/php/js/parsephp.js",
|
283
|
-
"../contrib/php/js/parsephphtmlmixed.js"],
|
284
|
-
stylesheet: ["../../css/xmlcolors.css", "../../css/jscolors.css", "../../css/csscolors.css", "css/phpcolors.css"],
|
285
|
-
path: "../../js/",
|
286
|
-
continuousScanning: 500
|
287
|
-
});
|
288
|
-
</script>
|
289
|
-
|
290
|
-
|
291
|
-
</body>
|
292
|
-
</html>
|
@@ -1,371 +0,0 @@
|
|
1
|
-
/*
|
2
|
-
Copyright (c) 2008-2009 Yahoo! Inc. All rights reserved.
|
3
|
-
The copyrights embodied in the content of this file are licensed by
|
4
|
-
Yahoo! Inc. under the BSD (revised) open source license
|
5
|
-
|
6
|
-
@author Dan Vlad Dascalescu <dandv@yahoo-inc.com>
|
7
|
-
|
8
|
-
|
9
|
-
Parse function for PHP. Makes use of the tokenizer from tokenizephp.js.
|
10
|
-
Based on parsejavascript.js by Marijn Haverbeke.
|
11
|
-
|
12
|
-
|
13
|
-
Features:
|
14
|
-
+ special "deprecated" style for PHP4 keywords like 'var'
|
15
|
-
+ support for PHP 5.3 keywords: 'namespace', 'use'
|
16
|
-
+ 911 predefined constants, 1301 predefined functions, 105 predeclared classes
|
17
|
-
from a typical PHP installation in a LAMP environment
|
18
|
-
+ new feature: syntax error flagging, thus enabling strict parsing of:
|
19
|
-
+ function definitions with explicitly or implicitly typed arguments and default values
|
20
|
-
+ modifiers (public, static etc.) applied to method and member definitions
|
21
|
-
+ foreach(array_expression as $key [=> $value]) loops
|
22
|
-
+ differentiation between single-quoted strings and double-quoted interpolating strings
|
23
|
-
|
24
|
-
*/
|
25
|
-
|
26
|
-
|
27
|
-
// add the Array.indexOf method for JS engines that don't support it (e.g. IE)
|
28
|
-
// code from https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Global_Objects/Array/IndexOf
|
29
|
-
if (!Array.prototype.indexOf)
|
30
|
-
{
|
31
|
-
Array.prototype.indexOf = function(elt /*, from*/)
|
32
|
-
{
|
33
|
-
var len = this.length;
|
34
|
-
|
35
|
-
var from = Number(arguments[1]) || 0;
|
36
|
-
from = (from < 0)
|
37
|
-
? Math.ceil(from)
|
38
|
-
: Math.floor(from);
|
39
|
-
if (from < 0)
|
40
|
-
from += len;
|
41
|
-
|
42
|
-
for (; from < len; from++)
|
43
|
-
{
|
44
|
-
if (from in this &&
|
45
|
-
this[from] === elt)
|
46
|
-
return from;
|
47
|
-
}
|
48
|
-
return -1;
|
49
|
-
};
|
50
|
-
}
|
51
|
-
|
52
|
-
|
53
|
-
var PHPParser = Editor.Parser = (function() {
|
54
|
-
// Token types that can be considered to be atoms, part of operator expressions
|
55
|
-
var atomicTypes = {
|
56
|
-
"atom": true, "number": true, "variable": true, "string": true
|
57
|
-
};
|
58
|
-
// Constructor for the lexical context objects.
|
59
|
-
function PHPLexical(indented, column, type, align, prev, info) {
|
60
|
-
// indentation at start of this line
|
61
|
-
this.indented = indented;
|
62
|
-
// column at which this scope was opened
|
63
|
-
this.column = column;
|
64
|
-
// type of scope ('stat' (statement), 'form' (special form), '[', '{', or '(')
|
65
|
-
this.type = type;
|
66
|
-
// '[', '{', or '(' blocks that have any text after their opening
|
67
|
-
// character are said to be 'aligned' -- any lines below are
|
68
|
-
// indented all the way to the opening character.
|
69
|
-
if (align != null)
|
70
|
-
this.align = align;
|
71
|
-
// Parent scope, if any.
|
72
|
-
this.prev = prev;
|
73
|
-
this.info = info;
|
74
|
-
}
|
75
|
-
|
76
|
-
// PHP indentation rules
|
77
|
-
function indentPHP(lexical) {
|
78
|
-
return function(firstChars) {
|
79
|
-
var firstChar = firstChars && firstChars.charAt(0), type = lexical.type;
|
80
|
-
var closing = firstChar == type;
|
81
|
-
if (type == "form" && firstChar == "{")
|
82
|
-
return lexical.indented;
|
83
|
-
else if (type == "stat" || type == "form")
|
84
|
-
return lexical.indented + indentUnit;
|
85
|
-
else if (lexical.info == "switch" && !closing)
|
86
|
-
return lexical.indented + (/^(?:case|default)\b/.test(firstChars) ? indentUnit : 2 * indentUnit);
|
87
|
-
else if (lexical.align)
|
88
|
-
return lexical.column - (closing ? 1 : 0);
|
89
|
-
else
|
90
|
-
return lexical.indented + (closing ? 0 : indentUnit);
|
91
|
-
};
|
92
|
-
}
|
93
|
-
|
94
|
-
// The parser-iterator-producing function itself.
|
95
|
-
function parsePHP(input, basecolumn) {
|
96
|
-
// Wrap the input in a token stream
|
97
|
-
var tokens = tokenizePHP(input);
|
98
|
-
// The parser state. cc is a stack of actions that have to be
|
99
|
-
// performed to finish the current statement. For example we might
|
100
|
-
// know that we still need to find a closing parenthesis and a
|
101
|
-
// semicolon. Actions at the end of the stack go first. It is
|
102
|
-
// initialized with an infinitely looping action that consumes
|
103
|
-
// whole statements.
|
104
|
-
var cc = [statements];
|
105
|
-
// The lexical scope, used mostly for indentation.
|
106
|
-
var lexical = new PHPLexical((basecolumn || 0) - indentUnit, 0, "block", false);
|
107
|
-
// Current column, and the indentation at the start of the current
|
108
|
-
// line. Used to create lexical scope objects.
|
109
|
-
var column = 0;
|
110
|
-
var indented = 0;
|
111
|
-
// Variables which are used by the mark, cont, and pass functions
|
112
|
-
// below to communicate with the driver loop in the 'next' function.
|
113
|
-
var consume, marked;
|
114
|
-
|
115
|
-
// The iterator object.
|
116
|
-
var parser = {next: next, copy: copy};
|
117
|
-
|
118
|
-
// parsing is accomplished by calling next() repeatedly
|
119
|
-
function next(){
|
120
|
-
// Start by performing any 'lexical' actions (adjusting the
|
121
|
-
// lexical variable), or the operations below will be working
|
122
|
-
// with the wrong lexical state.
|
123
|
-
while(cc[cc.length - 1].lex)
|
124
|
-
cc.pop()();
|
125
|
-
|
126
|
-
// Fetch the next token.
|
127
|
-
var token = tokens.next();
|
128
|
-
|
129
|
-
// Adjust column and indented.
|
130
|
-
if (token.type == "whitespace" && column == 0)
|
131
|
-
indented = token.value.length;
|
132
|
-
column += token.value.length;
|
133
|
-
if (token.content == "\n"){
|
134
|
-
indented = column = 0;
|
135
|
-
// If the lexical scope's align property is still undefined at
|
136
|
-
// the end of the line, it is an un-aligned scope.
|
137
|
-
if (!("align" in lexical))
|
138
|
-
lexical.align = false;
|
139
|
-
// Newline tokens get an indentation function associated with
|
140
|
-
// them.
|
141
|
-
token.indentation = indentPHP(lexical);
|
142
|
-
}
|
143
|
-
// No more processing for meaningless tokens.
|
144
|
-
if (token.type == "whitespace" || token.type == "comment"
|
145
|
-
|| token.type == "string_not_terminated" )
|
146
|
-
return token;
|
147
|
-
// When a meaningful token is found and the lexical scope's
|
148
|
-
// align is undefined, it is an aligned scope.
|
149
|
-
if (!("align" in lexical))
|
150
|
-
lexical.align = true;
|
151
|
-
|
152
|
-
// Execute actions until one 'consumes' the token and we can
|
153
|
-
// return it. 'marked' is used to change the style of the current token.
|
154
|
-
while(true) {
|
155
|
-
consume = marked = false;
|
156
|
-
// Take and execute the topmost action.
|
157
|
-
var action = cc.pop();
|
158
|
-
action(token);
|
159
|
-
|
160
|
-
if (consume){
|
161
|
-
if (marked)
|
162
|
-
token.style = marked;
|
163
|
-
// Here we differentiate between local and global variables.
|
164
|
-
return token;
|
165
|
-
}
|
166
|
-
}
|
167
|
-
return 1; // Firebug workaround for http://code.google.com/p/fbug/issues/detail?id=1239#c1
|
168
|
-
}
|
169
|
-
|
170
|
-
// This makes a copy of the parser state. It stores all the
|
171
|
-
// stateful variables in a closure, and returns a function that
|
172
|
-
// will restore them when called with a new input stream. Note
|
173
|
-
// that the cc array has to be copied, because it is contantly
|
174
|
-
// being modified. Lexical objects are not mutated, so they can
|
175
|
-
// be shared between runs of the parser.
|
176
|
-
function copy(){
|
177
|
-
var _lexical = lexical, _cc = cc.concat([]), _tokenState = tokens.state;
|
178
|
-
|
179
|
-
return function copyParser(input){
|
180
|
-
lexical = _lexical;
|
181
|
-
cc = _cc.concat([]); // copies the array
|
182
|
-
column = indented = 0;
|
183
|
-
tokens = tokenizePHP(input, _tokenState);
|
184
|
-
return parser;
|
185
|
-
};
|
186
|
-
}
|
187
|
-
|
188
|
-
// Helper function for pushing a number of actions onto the cc
|
189
|
-
// stack in reverse order.
|
190
|
-
function push(fs){
|
191
|
-
for (var i = fs.length - 1; i >= 0; i--)
|
192
|
-
cc.push(fs[i]);
|
193
|
-
}
|
194
|
-
// cont and pass are used by the action functions to add other
|
195
|
-
// actions to the stack. cont will cause the current token to be
|
196
|
-
// consumed, pass will leave it for the next action.
|
197
|
-
function cont(){
|
198
|
-
push(arguments);
|
199
|
-
consume = true;
|
200
|
-
}
|
201
|
-
function pass(){
|
202
|
-
push(arguments);
|
203
|
-
consume = false;
|
204
|
-
}
|
205
|
-
// Used to change the style of the current token.
|
206
|
-
function mark(style){
|
207
|
-
marked = style;
|
208
|
-
}
|
209
|
-
// Add a lyer of style to the current token, for example syntax-error
|
210
|
-
function mark_add(style){
|
211
|
-
marked = marked + ' ' + style;
|
212
|
-
}
|
213
|
-
|
214
|
-
// Push a new lexical context of the given type.
|
215
|
-
function pushlex(type, info) {
|
216
|
-
var result = function pushlexing() {
|
217
|
-
lexical = new PHPLexical(indented, column, type, null, lexical, info)
|
218
|
-
};
|
219
|
-
result.lex = true;
|
220
|
-
return result;
|
221
|
-
}
|
222
|
-
// Pop off the current lexical context.
|
223
|
-
function poplex(){
|
224
|
-
lexical = lexical.prev;
|
225
|
-
}
|
226
|
-
poplex.lex = true;
|
227
|
-
// The 'lex' flag on these actions is used by the 'next' function
|
228
|
-
// to know they can (and have to) be ran before moving on to the
|
229
|
-
// next token.
|
230
|
-
|
231
|
-
// Creates an action that discards tokens until it finds one of
|
232
|
-
// the given type. This will ignore (and recover from) syntax errors.
|
233
|
-
function expect(wanted){
|
234
|
-
return function expecting(token){
|
235
|
-
if (token.type == wanted) cont(); // consume the token
|
236
|
-
else {
|
237
|
-
cont(arguments.callee); // continue expecting() - call itself
|
238
|
-
}
|
239
|
-
};
|
240
|
-
}
|
241
|
-
|
242
|
-
// Require a specific token type, or one of the tokens passed in the 'wanted' array
|
243
|
-
// Used to detect blatant syntax errors. 'execute' is used to pass extra code
|
244
|
-
// to be executed if the token is matched. For example, a '(' match could
|
245
|
-
// 'execute' a cont( compasep(funcarg), require(")") )
|
246
|
-
function require(wanted, execute){
|
247
|
-
return function requiring(token){
|
248
|
-
var ok;
|
249
|
-
var type = token.type;
|
250
|
-
if (typeof(wanted) == "string")
|
251
|
-
ok = (type == wanted) -1;
|
252
|
-
else
|
253
|
-
ok = wanted.indexOf(type);
|
254
|
-
if (ok >= 0) {
|
255
|
-
if (execute && typeof(execute[ok]) == "function")
|
256
|
-
execute[ok](token);
|
257
|
-
cont(); // just consume the token
|
258
|
-
}
|
259
|
-
else {
|
260
|
-
if (!marked) mark(token.style);
|
261
|
-
mark_add("syntax-error");
|
262
|
-
cont(arguments.callee);
|
263
|
-
}
|
264
|
-
};
|
265
|
-
}
|
266
|
-
|
267
|
-
// Looks for a statement, and then calls itself.
|
268
|
-
function statements(token){
|
269
|
-
return pass(statement, statements);
|
270
|
-
}
|
271
|
-
// Dispatches various types of statements based on the type of the current token.
|
272
|
-
function statement(token){
|
273
|
-
var type = token.type;
|
274
|
-
if (type == "keyword a") cont(pushlex("form"), expression, statement, poplex);
|
275
|
-
else if (type == "keyword b") cont(pushlex("form"), statement, poplex);
|
276
|
-
else if (type == "{") cont(pushlex("}"), block, poplex);
|
277
|
-
else if (type == "function") funcdef();
|
278
|
-
// technically, "class implode {...}" is correct, but we'll flag that as an error because it overrides a predefined function
|
279
|
-
else if (type == "class") cont(require("t_string"), expect("{"), pushlex("}"), block, poplex);
|
280
|
-
else if (type == "foreach") cont(pushlex("form"), require("("), pushlex(")"), expression, require("as"), require("variable"), /* => $value */ expect(")"), poplex, statement, poplex);
|
281
|
-
else if (type == "for") cont(pushlex("form"), require("("), pushlex(")"), expression, require(";"), expression, require(";"), expression, require(")"), poplex, statement, poplex);
|
282
|
-
// public final function foo(), protected static $bar;
|
283
|
-
else if (type == "modifier") cont(require(["modifier", "variable", "function"], [null, null, funcdef]));
|
284
|
-
else if (type == "switch") cont(pushlex("form"), require("("), expression, require(")"), pushlex("}", "switch"), require([":", "{"]), block, poplex, poplex);
|
285
|
-
else if (type == "case") cont(expression, require(":"));
|
286
|
-
else if (type == "default") cont(require(":"));
|
287
|
-
else if (type == "catch") cont(pushlex("form"), require("("), require("t_string"), require("variable"), require(")"), statement, poplex);
|
288
|
-
else if (type == "const") cont(require("t_string")); // 'const static x=5' is a syntax error
|
289
|
-
// technically, "namespace implode {...}" is correct, but we'll flag that as an error because it overrides a predefined function
|
290
|
-
else if (type == "namespace") cont(namespacedef, require(";"));
|
291
|
-
// $variables may be followed by operators, () for variable function calls, or [] subscripts
|
292
|
-
else pass(pushlex("stat"), expression, require(";"), poplex);
|
293
|
-
}
|
294
|
-
// Dispatch expression types.
|
295
|
-
function expression(token){
|
296
|
-
var type = token.type;
|
297
|
-
if (atomicTypes.hasOwnProperty(type)) cont(maybeoperator);
|
298
|
-
else if (type == "<<<") cont(require("string"), maybeoperator); // heredoc/nowdoc
|
299
|
-
else if (type == "t_string") cont(maybe_double_colon, maybeoperator);
|
300
|
-
else if (type == "keyword c") cont(expression);
|
301
|
-
// function call or parenthesized expression: $a = ($b + 1) * 2;
|
302
|
-
else if (type == "(") cont(pushlex(")"), commasep(expression), require(")"), poplex, maybeoperator);
|
303
|
-
else if (type == "operator") cont(expression);
|
304
|
-
}
|
305
|
-
// Called for places where operators, function calls, or subscripts are
|
306
|
-
// valid. Will skip on to the next action if none is found.
|
307
|
-
function maybeoperator(token){
|
308
|
-
var type = token.type;
|
309
|
-
if (type == "operator") {
|
310
|
-
if (token.content == "?") cont(expression, require(":"), expression); // ternary operator
|
311
|
-
else cont(expression);
|
312
|
-
}
|
313
|
-
else if (type == "(") cont(pushlex(")"), expression, commasep(expression), require(")"), poplex, maybeoperator /* $varfunc() + 3 */);
|
314
|
-
else if (type == "[") cont(pushlex("]"), expression, require("]"), maybeoperator /* for multidimensional arrays, or $func[$i]() */, poplex);
|
315
|
-
}
|
316
|
-
// A regular use of the double colon to specify a class, as in self::func() or myclass::$var;
|
317
|
-
// Differs from `namespace` or `use` in that only one class can be the parent; chains (A::B::$var) are a syntax error.
|
318
|
-
function maybe_double_colon(token) {
|
319
|
-
if (token.type == "t_double_colon")
|
320
|
-
// A::$var, A::func(), A::const
|
321
|
-
cont(require(["t_string", "variable"]), maybeoperator);
|
322
|
-
else {
|
323
|
-
// a t_string wasn't followed by ::, such as in a function call: foo()
|
324
|
-
pass(expression)
|
325
|
-
}
|
326
|
-
}
|
327
|
-
// the declaration or definition of a function
|
328
|
-
function funcdef() {
|
329
|
-
cont(require("t_string"), require("("), pushlex(")"), commasep(funcarg), require(")"), poplex, block);
|
330
|
-
}
|
331
|
-
// Parses a comma-separated list of the things that are recognized
|
332
|
-
// by the 'what' argument.
|
333
|
-
function commasep(what){
|
334
|
-
function proceed(token) {
|
335
|
-
if (token.type == ",") cont(what, proceed);
|
336
|
-
}
|
337
|
-
return function commaSeparated() {
|
338
|
-
pass(what, proceed);
|
339
|
-
};
|
340
|
-
}
|
341
|
-
// Look for statements until a closing brace is found.
|
342
|
-
function block(token) {
|
343
|
-
if (token.type == "}") cont();
|
344
|
-
else pass(statement, block);
|
345
|
-
}
|
346
|
-
function maybedefaultparameter(token){
|
347
|
-
if (token.content == "=") cont(expression);
|
348
|
-
}
|
349
|
-
// support for default arguments: http://us.php.net/manual/en/functions.arguments.php#functions.arguments.default
|
350
|
-
function funcarg(token){
|
351
|
-
// function foo(myclass $obj) {...}
|
352
|
-
if (token.type == "t_string") cont(require("variable"), maybedefaultparameter);
|
353
|
-
// function foo($string) {...}
|
354
|
-
else if (token.type == "variable") cont(maybedefaultparameter);
|
355
|
-
}
|
356
|
-
|
357
|
-
// A namespace definition or use
|
358
|
-
function maybe_double_colon_def(token) {
|
359
|
-
if (token.type == "t_double_colon")
|
360
|
-
cont(namespacedef);
|
361
|
-
}
|
362
|
-
function namespacedef(token) {
|
363
|
-
pass(require("t_string"), maybe_double_colon_def);
|
364
|
-
}
|
365
|
-
|
366
|
-
return parser;
|
367
|
-
}
|
368
|
-
|
369
|
-
return {make: parsePHP, electricChars: "{}:"};
|
370
|
-
|
371
|
-
})();
|