Mercurial
comparison .cms/lib/codemirror/mode/coffeescript/index.html @ 0:78edf6b517a0 draft
24.10
author | Coffee CMS <info@coffee-cms.ru> |
---|---|
date | Fri, 11 Oct 2024 22:40:23 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:78edf6b517a0 |
---|---|
1 <!doctype html> | |
2 | |
3 <title>CodeMirror: CoffeeScript mode</title> | |
4 <meta charset="utf-8"/> | |
5 <link rel=stylesheet href="../../doc/docs.css"> | |
6 | |
7 <link rel="stylesheet" href="../../lib/codemirror.css"> | |
8 <script src="../../lib/codemirror.js"></script> | |
9 <script src="coffeescript.js"></script> | |
10 <style>.CodeMirror {border-top: 1px solid silver; border-bottom: 1px solid silver;}</style> | |
11 <div id=nav> | |
12 <a href="https://codemirror.net/5"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt=""></a> | |
13 | |
14 <ul> | |
15 <li><a href="../../index.html">Home</a> | |
16 <li><a href="../../doc/manual.html">Manual</a> | |
17 <li><a href="https://github.com/codemirror/codemirror5">Code</a> | |
18 </ul> | |
19 <ul> | |
20 <li><a href="../index.html">Language modes</a> | |
21 <li><a class=active href="#">CoffeeScript</a> | |
22 </ul> | |
23 </div> | |
24 | |
25 <article> | |
26 <h2>CoffeeScript mode</h2> | |
27 <form><textarea id="code" name="code"> | |
28 # CoffeeScript mode for CodeMirror | |
29 # Copyright (c) 2011 Jeff Pickhardt, released under | |
30 # the MIT License. | |
31 # | |
32 # Modified from the Python CodeMirror mode, which also is | |
33 # under the MIT License Copyright (c) 2010 Timothy Farrell. | |
34 # | |
35 # The following script, Underscore.coffee, is used to | |
36 # demonstrate CoffeeScript mode for CodeMirror. | |
37 # | |
38 # To download CoffeeScript mode for CodeMirror, go to: | |
39 # https://github.com/pickhardt/coffeescript-codemirror-mode | |
40 | |
41 # **Underscore.coffee | |
42 # (c) 2011 Jeremy Ashkenas, DocumentCloud Inc.** | |
43 # Underscore is freely distributable under the terms of the | |
44 # [MIT license](http://en.wikipedia.org/wiki/MIT_License). | |
45 # Portions of Underscore are inspired by or borrowed from | |
46 # [Prototype.js](http://prototypejs.org/api), Oliver Steele's | |
47 # [Functional](http://osteele.com), and John Resig's | |
48 # [Micro-Templating](http://ejohn.org). | |
49 # For all details and documentation: | |
50 # http://documentcloud.github.com/underscore/ | |
51 | |
52 | |
53 # Baseline setup | |
54 # -------------- | |
55 | |
56 # Establish the root object, `window` in the browser, or `global` on the server. | |
57 root = this | |
58 | |
59 | |
60 # Save the previous value of the `_` variable. | |
61 previousUnderscore = root._ | |
62 | |
63 ### Multiline | |
64 comment | |
65 ### | |
66 | |
67 # Establish the object that gets thrown to break out of a loop iteration. | |
68 # `StopIteration` is SOP on Mozilla. | |
69 breaker = if typeof(StopIteration) is 'undefined' then '__break__' else StopIteration | |
70 | |
71 | |
72 #### Docco style single line comment (title) | |
73 | |
74 | |
75 # Helper function to escape **RegExp** contents, because JS doesn't have one. | |
76 escapeRegExp = (string) -> string.replace(/([.*+?^${}()|[\]\/\\])/g, '\\$1') | |
77 | |
78 | |
79 # Save bytes in the minified (but not gzipped) version: | |
80 ArrayProto = Array.prototype | |
81 ObjProto = Object.prototype | |
82 | |
83 | |
84 # Create quick reference variables for speed access to core prototypes. | |
85 slice = ArrayProto.slice | |
86 unshift = ArrayProto.unshift | |
87 toString = ObjProto.toString | |
88 hasOwnProperty = ObjProto.hasOwnProperty | |
89 propertyIsEnumerable = ObjProto.propertyIsEnumerable | |
90 | |
91 | |
92 # All **ECMA5** native implementations we hope to use are declared here. | |
93 nativeForEach = ArrayProto.forEach | |
94 nativeMap = ArrayProto.map | |
95 nativeReduce = ArrayProto.reduce | |
96 nativeReduceRight = ArrayProto.reduceRight | |
97 nativeFilter = ArrayProto.filter | |
98 nativeEvery = ArrayProto.every | |
99 nativeSome = ArrayProto.some | |
100 nativeIndexOf = ArrayProto.indexOf | |
101 nativeLastIndexOf = ArrayProto.lastIndexOf | |
102 nativeIsArray = Array.isArray | |
103 nativeKeys = Object.keys | |
104 | |
105 | |
106 # Create a safe reference to the Underscore object for use below. | |
107 _ = (obj) -> new wrapper(obj) | |
108 | |
109 | |
110 # Export the Underscore object for **CommonJS**. | |
111 if typeof(exports) != 'undefined' then exports._ = _ | |
112 | |
113 | |
114 # Export Underscore to global scope. | |
115 root._ = _ | |
116 | |
117 | |
118 # Current version. | |
119 _.VERSION = '1.1.0' | |
120 | |
121 | |
122 # Collection Functions | |
123 # -------------------- | |
124 | |
125 # The cornerstone, an **each** implementation. | |
126 # Handles objects implementing **forEach**, arrays, and raw objects. | |
127 _.each = (obj, iterator, context) -> | |
128 try | |
129 if nativeForEach and obj.forEach is nativeForEach | |
130 obj.forEach iterator, context | |
131 else if _.isNumber obj.length | |
132 iterator.call context, obj[i], i, obj for i in [0...obj.length] | |
133 else | |
134 iterator.call context, val, key, obj for own key, val of obj | |
135 catch e | |
136 throw e if e isnt breaker | |
137 obj | |
138 | |
139 | |
140 # Return the results of applying the iterator to each element. Use JavaScript | |
141 # 1.6's version of **map**, if possible. | |
142 _.map = (obj, iterator, context) -> | |
143 return obj.map(iterator, context) if nativeMap and obj.map is nativeMap | |
144 results = [] | |
145 _.each obj, (value, index, list) -> | |
146 results.push iterator.call context, value, index, list | |
147 results | |
148 | |
149 | |
150 # **Reduce** builds up a single result from a list of values. Also known as | |
151 # **inject**, or **foldl**. Uses JavaScript 1.8's version of **reduce**, if possible. | |
152 _.reduce = (obj, iterator, memo, context) -> | |
153 if nativeReduce and obj.reduce is nativeReduce | |
154 iterator = _.bind iterator, context if context | |
155 return obj.reduce iterator, memo | |
156 _.each obj, (value, index, list) -> | |
157 memo = iterator.call context, memo, value, index, list | |
158 memo | |
159 | |
160 | |
161 # The right-associative version of **reduce**, also known as **foldr**. Uses | |
162 # JavaScript 1.8's version of **reduceRight**, if available. | |
163 _.reduceRight = (obj, iterator, memo, context) -> | |
164 if nativeReduceRight and obj.reduceRight is nativeReduceRight | |
165 iterator = _.bind iterator, context if context | |
166 return obj.reduceRight iterator, memo | |
167 reversed = _.clone(_.toArray(obj)).reverse() | |
168 _.reduce reversed, iterator, memo, context | |
169 | |
170 | |
171 # Return the first value which passes a truth test. | |
172 _.detect = (obj, iterator, context) -> | |
173 result = null | |
174 _.each obj, (value, index, list) -> | |
175 if iterator.call context, value, index, list | |
176 result = value | |
177 _.breakLoop() | |
178 result | |
179 | |
180 | |
181 # Return all the elements that pass a truth test. Use JavaScript 1.6's | |
182 # **filter**, if it exists. | |
183 _.filter = (obj, iterator, context) -> | |
184 return obj.filter iterator, context if nativeFilter and obj.filter is nativeFilter | |
185 results = [] | |
186 _.each obj, (value, index, list) -> | |
187 results.push value if iterator.call context, value, index, list | |
188 results | |
189 | |
190 | |
191 # Return all the elements for which a truth test fails. | |
192 _.reject = (obj, iterator, context) -> | |
193 results = [] | |
194 _.each obj, (value, index, list) -> | |
195 results.push value if not iterator.call context, value, index, list | |
196 results | |
197 | |
198 | |
199 # Determine whether all of the elements match a truth test. Delegate to | |
200 # JavaScript 1.6's **every**, if it is present. | |
201 _.every = (obj, iterator, context) -> | |
202 iterator ||= _.identity | |
203 return obj.every iterator, context if nativeEvery and obj.every is nativeEvery | |
204 result = true | |
205 _.each obj, (value, index, list) -> | |
206 _.breakLoop() unless (result = result and iterator.call(context, value, index, list)) | |
207 result | |
208 | |
209 | |
210 # Determine if at least one element in the object matches a truth test. Use | |
211 # JavaScript 1.6's **some**, if it exists. | |
212 _.some = (obj, iterator, context) -> | |
213 iterator ||= _.identity | |
214 return obj.some iterator, context if nativeSome and obj.some is nativeSome | |
215 result = false | |
216 _.each obj, (value, index, list) -> | |
217 _.breakLoop() if (result = iterator.call(context, value, index, list)) | |
218 result | |
219 | |
220 | |
221 # Determine if a given value is included in the array or object, | |
222 # based on `===`. | |
223 _.include = (obj, target) -> | |
224 return _.indexOf(obj, target) isnt -1 if nativeIndexOf and obj.indexOf is nativeIndexOf | |
225 return true for own key, val of obj when val is target | |
226 false | |
227 | |
228 | |
229 # Invoke a method with arguments on every item in a collection. | |
230 _.invoke = (obj, method) -> | |
231 args = _.rest arguments, 2 | |
232 (if method then val[method] else val).apply(val, args) for val in obj | |
233 | |
234 | |
235 # Convenience version of a common use case of **map**: fetching a property. | |
236 _.pluck = (obj, key) -> | |
237 _.map(obj, (val) -> val[key]) | |
238 | |
239 | |
240 # Return the maximum item or (item-based computation). | |
241 _.max = (obj, iterator, context) -> | |
242 return Math.max.apply(Math, obj) if not iterator and _.isArray(obj) | |
243 result = computed: -Infinity | |
244 _.each obj, (value, index, list) -> | |
245 computed = if iterator then iterator.call(context, value, index, list) else value | |
246 computed >= result.computed and (result = {value: value, computed: computed}) | |
247 result.value | |
248 | |
249 | |
250 # Return the minimum element (or element-based computation). | |
251 _.min = (obj, iterator, context) -> | |
252 return Math.min.apply(Math, obj) if not iterator and _.isArray(obj) | |
253 result = computed: Infinity | |
254 _.each obj, (value, index, list) -> | |
255 computed = if iterator then iterator.call(context, value, index, list) else value | |
256 computed < result.computed and (result = {value: value, computed: computed}) | |
257 result.value | |
258 | |
259 | |
260 # Sort the object's values by a criterion produced by an iterator. | |
261 _.sortBy = (obj, iterator, context) -> | |
262 _.pluck(((_.map obj, (value, index, list) -> | |
263 {value: value, criteria: iterator.call(context, value, index, list)} | |
264 ).sort((left, right) -> | |
265 a = left.criteria; b = right.criteria | |
266 if a < b then -1 else if a > b then 1 else 0 | |
267 )), 'value') | |
268 | |
269 | |
270 # Use a comparator function to figure out at what index an object should | |
271 # be inserted so as to maintain order. Uses binary search. | |
272 _.sortedIndex = (array, obj, iterator) -> | |
273 iterator ||= _.identity | |
274 low = 0 | |
275 high = array.length | |
276 while low < high | |
277 mid = (low + high) >> 1 | |
278 if iterator(array[mid]) < iterator(obj) then low = mid + 1 else high = mid | |
279 low | |
280 | |
281 | |
282 # Convert anything iterable into a real, live array. | |
283 _.toArray = (iterable) -> | |
284 return [] if (!iterable) | |
285 return iterable.toArray() if (iterable.toArray) | |
286 return iterable if (_.isArray(iterable)) | |
287 return slice.call(iterable) if (_.isArguments(iterable)) | |
288 _.values(iterable) | |
289 | |
290 | |
291 # Return the number of elements in an object. | |
292 _.size = (obj) -> _.toArray(obj).length | |
293 | |
294 | |
295 # Array Functions | |
296 # --------------- | |
297 | |
298 # Get the first element of an array. Passing `n` will return the first N | |
299 # values in the array. Aliased as **head**. The `guard` check allows it to work | |
300 # with **map**. | |
301 _.first = (array, n, guard) -> | |
302 if n and not guard then slice.call(array, 0, n) else array[0] | |
303 | |
304 | |
305 # Returns everything but the first entry of the array. Aliased as **tail**. | |
306 # Especially useful on the arguments object. Passing an `index` will return | |
307 # the rest of the values in the array from that index onward. The `guard` | |
308 # check allows it to work with **map**. | |
309 _.rest = (array, index, guard) -> | |
310 slice.call(array, if _.isUndefined(index) or guard then 1 else index) | |
311 | |
312 | |
313 # Get the last element of an array. | |
314 _.last = (array) -> array[array.length - 1] | |
315 | |
316 | |
317 # Trim out all falsy values from an array. | |
318 _.compact = (array) -> item for item in array when item | |
319 | |
320 | |
321 # Return a completely flattened version of an array. | |
322 _.flatten = (array) -> | |
323 _.reduce array, (memo, value) -> | |
324 return memo.concat(_.flatten(value)) if _.isArray value | |
325 memo.push value | |
326 memo | |
327 , [] | |
328 | |
329 | |
330 # Return a version of the array that does not contain the specified value(s). | |
331 _.without = (array) -> | |
332 values = _.rest arguments | |
333 val for val in _.toArray(array) when not _.include values, val | |
334 | |
335 | |
336 # Produce a duplicate-free version of the array. If the array has already | |
337 # been sorted, you have the option of using a faster algorithm. | |
338 _.uniq = (array, isSorted) -> | |
339 memo = [] | |
340 for el, i in _.toArray array | |
341 memo.push el if i is 0 || (if isSorted is true then _.last(memo) isnt el else not _.include(memo, el)) | |
342 memo | |
343 | |
344 | |
345 # Produce an array that contains every item shared between all the | |
346 # passed-in arrays. | |
347 _.intersect = (array) -> | |
348 rest = _.rest arguments | |
349 _.select _.uniq(array), (item) -> | |
350 _.all rest, (other) -> | |
351 _.indexOf(other, item) >= 0 | |
352 | |
353 | |
354 # Zip together multiple lists into a single array -- elements that share | |
355 # an index go together. | |
356 _.zip = -> | |
357 length = _.max _.pluck arguments, 'length' | |
358 results = new Array length | |
359 for i in [0...length] | |
360 results[i] = _.pluck arguments, String i | |
361 results | |
362 | |
363 | |
364 # If the browser doesn't supply us with **indexOf** (I'm looking at you, MSIE), | |
365 # we need this function. Return the position of the first occurrence of an | |
366 # item in an array, or -1 if the item is not included in the array. | |
367 _.indexOf = (array, item) -> | |
368 return array.indexOf item if nativeIndexOf and array.indexOf is nativeIndexOf | |
369 i = 0; l = array.length | |
370 while l - i | |
371 if array[i] is item then return i else i++ | |
372 -1 | |
373 | |
374 | |
375 # Provide JavaScript 1.6's **lastIndexOf**, delegating to the native function, | |
376 # if possible. | |
377 _.lastIndexOf = (array, item) -> | |
378 return array.lastIndexOf(item) if nativeLastIndexOf and array.lastIndexOf is nativeLastIndexOf | |
379 i = array.length | |
380 while i | |
381 if array[i] is item then return i else i-- | |
382 -1 | |
383 | |
384 | |
385 # Generate an integer Array containing an arithmetic progression. A port of | |
386 # [the native Python **range** function](http://docs.python.org/library/functions.html#range). | |
387 _.range = (start, stop, step) -> | |
388 a = arguments | |
389 solo = a.length <= 1 | |
390 i = start = if solo then 0 else a[0] | |
391 stop = if solo then a[0] else a[1] | |
392 step = a[2] or 1 | |
393 len = Math.ceil((stop - start) / step) | |
394 return [] if len <= 0 | |
395 range = new Array len | |
396 idx = 0 | |
397 loop | |
398 return range if (if step > 0 then i - stop else stop - i) >= 0 | |
399 range[idx] = i | |
400 idx++ | |
401 i+= step | |
402 | |
403 | |
404 # Function Functions | |
405 # ------------------ | |
406 | |
407 # Create a function bound to a given object (assigning `this`, and arguments, | |
408 # optionally). Binding with arguments is also known as **curry**. | |
409 _.bind = (func, obj) -> | |
410 args = _.rest arguments, 2 | |
411 -> func.apply obj or root, args.concat arguments | |
412 | |
413 | |
414 # Bind all of an object's methods to that object. Useful for ensuring that | |
415 # all callbacks defined on an object belong to it. | |
416 _.bindAll = (obj) -> | |
417 funcs = if arguments.length > 1 then _.rest(arguments) else _.functions(obj) | |
418 _.each funcs, (f) -> obj[f] = _.bind obj[f], obj | |
419 obj | |
420 | |
421 | |
422 # Delays a function for the given number of milliseconds, and then calls | |
423 # it with the arguments supplied. | |
424 _.delay = (func, wait) -> | |
425 args = _.rest arguments, 2 | |
426 setTimeout((-> func.apply(func, args)), wait) | |
427 | |
428 | |
429 # Memoize an expensive function by storing its results. | |
430 _.memoize = (func, hasher) -> | |
431 memo = {} | |
432 hasher or= _.identity | |
433 -> | |
434 key = hasher.apply this, arguments | |
435 return memo[key] if key of memo | |
436 memo[key] = func.apply this, arguments | |
437 | |
438 | |
439 # Defers a function, scheduling it to run after the current call stack has | |
440 # cleared. | |
441 _.defer = (func) -> | |
442 _.delay.apply _, [func, 1].concat _.rest arguments | |
443 | |
444 | |
445 # Returns the first function passed as an argument to the second, | |
446 # allowing you to adjust arguments, run code before and after, and | |
447 # conditionally execute the original function. | |
448 _.wrap = (func, wrapper) -> | |
449 -> wrapper.apply wrapper, [func].concat arguments | |
450 | |
451 | |
452 # Returns a function that is the composition of a list of functions, each | |
453 # consuming the return value of the function that follows. | |
454 _.compose = -> | |
455 funcs = arguments | |
456 -> | |
457 args = arguments | |
458 for i in [funcs.length - 1..0] by -1 | |
459 args = [funcs[i].apply(this, args)] | |
460 args[0] | |
461 | |
462 | |
463 # Object Functions | |
464 # ---------------- | |
465 | |
466 # Retrieve the names of an object's properties. | |
467 _.keys = nativeKeys or (obj) -> | |
468 return _.range 0, obj.length if _.isArray(obj) | |
469 key for key, val of obj | |
470 | |
471 | |
472 # Retrieve the values of an object's properties. | |
473 _.values = (obj) -> | |
474 _.map obj, _.identity | |
475 | |
476 | |
477 # Return a sorted list of the function names available in Underscore. | |
478 _.functions = (obj) -> | |
479 _.filter(_.keys(obj), (key) -> _.isFunction(obj[key])).sort() | |
480 | |
481 | |
482 # Extend a given object with all of the properties in a source object. | |
483 _.extend = (obj) -> | |
484 for source in _.rest(arguments) | |
485 obj[key] = val for key, val of source | |
486 obj | |
487 | |
488 | |
489 # Create a (shallow-cloned) duplicate of an object. | |
490 _.clone = (obj) -> | |
491 return obj.slice 0 if _.isArray obj | |
492 _.extend {}, obj | |
493 | |
494 | |
495 # Invokes interceptor with the obj, and then returns obj. | |
496 # The primary purpose of this method is to "tap into" a method chain, | |
497 # in order to perform operations on intermediate results within | |
498 the chain. | |
499 _.tap = (obj, interceptor) -> | |
500 interceptor obj | |
501 obj | |
502 | |
503 | |
504 # Perform a deep comparison to check if two objects are equal. | |
505 _.isEqual = (a, b) -> | |
506 # Check object identity. | |
507 return true if a is b | |
508 # Different types? | |
509 atype = typeof(a); btype = typeof(b) | |
510 return false if atype isnt btype | |
511 # Basic equality test (watch out for coercions). | |
512 return true if `a == b` | |
513 # One is falsy and the other truthy. | |
514 return false if (!a and b) or (a and !b) | |
515 # One of them implements an `isEqual()`? | |
516 return a.isEqual(b) if a.isEqual | |
517 # Check dates' integer values. | |
518 return a.getTime() is b.getTime() if _.isDate(a) and _.isDate(b) | |
519 # Both are NaN? | |
520 return false if _.isNaN(a) and _.isNaN(b) | |
521 # Compare regular expressions. | |
522 if _.isRegExp(a) and _.isRegExp(b) | |
523 return a.source is b.source and | |
524 a.global is b.global and | |
525 a.ignoreCase is b.ignoreCase and | |
526 a.multiline is b.multiline | |
527 # If a is not an object by this point, we can't handle it. | |
528 return false if atype isnt 'object' | |
529 # Check for different array lengths before comparing contents. | |
530 return false if a.length and (a.length isnt b.length) | |
531 # Nothing else worked, deep compare the contents. | |
532 aKeys = _.keys(a); bKeys = _.keys(b) | |
533 # Different object sizes? | |
534 return false if aKeys.length isnt bKeys.length | |
535 # Recursive comparison of contents. | |
536 return false for key, val of a when !(key of b) or !_.isEqual(val, b[key]) | |
537 true | |
538 | |
539 | |
540 # Is a given array or object empty? | |
541 _.isEmpty = (obj) -> | |
542 return obj.length is 0 if _.isArray(obj) or _.isString(obj) | |
543 return false for own key of obj | |
544 true | |
545 | |
546 | |
547 # Is a given value a DOM element? | |
548 _.isElement = (obj) -> obj and obj.nodeType is 1 | |
549 | |
550 | |
551 # Is a given value an array? | |
552 _.isArray = nativeIsArray or (obj) -> !!(obj and obj.concat and obj.unshift and not obj.callee) | |
553 | |
554 | |
555 # Is a given variable an arguments object? | |
556 _.isArguments = (obj) -> obj and obj.callee | |
557 | |
558 | |
559 # Is the given value a function? | |
560 _.isFunction = (obj) -> !!(obj and obj.constructor and obj.call and obj.apply) | |
561 | |
562 | |
563 # Is the given value a string? | |
564 _.isString = (obj) -> !!(obj is '' or (obj and obj.charCodeAt and obj.substr)) | |
565 | |
566 | |
567 # Is a given value a number? | |
568 _.isNumber = (obj) -> (obj is +obj) or toString.call(obj) is '[object Number]' | |
569 | |
570 | |
571 # Is a given value a boolean? | |
572 _.isBoolean = (obj) -> obj is true or obj is false | |
573 | |
574 | |
575 # Is a given value a Date? | |
576 _.isDate = (obj) -> !!(obj and obj.getTimezoneOffset and obj.setUTCFullYear) | |
577 | |
578 | |
579 # Is the given value a regular expression? | |
580 _.isRegExp = (obj) -> !!(obj and obj.exec and (obj.ignoreCase or obj.ignoreCase is false)) | |
581 | |
582 | |
583 # Is the given value NaN -- this one is interesting. `NaN != NaN`, and | |
584 # `isNaN(undefined) == true`, so we make sure it's a number first. | |
585 _.isNaN = (obj) -> _.isNumber(obj) and window.isNaN(obj) | |
586 | |
587 | |
588 # Is a given value equal to null? | |
589 _.isNull = (obj) -> obj is null | |
590 | |
591 | |
592 # Is a given variable undefined? | |
593 _.isUndefined = (obj) -> typeof obj is 'undefined' | |
594 | |
595 | |
596 # Utility Functions | |
597 # ----------------- | |
598 | |
599 # Run Underscore.js in noConflict mode, returning the `_` variable to its | |
600 # previous owner. Returns a reference to the Underscore object. | |
601 _.noConflict = -> | |
602 root._ = previousUnderscore | |
603 this | |
604 | |
605 | |
606 # Keep the identity function around for default iterators. | |
607 _.identity = (value) -> value | |
608 | |
609 | |
610 # Run a function `n` times. | |
611 _.times = (n, iterator, context) -> | |
612 iterator.call context, i for i in [0...n] | |
613 | |
614 | |
615 # Break out of the middle of an iteration. | |
616 _.breakLoop = -> throw breaker | |
617 | |
618 | |
619 # Add your own custom functions to the Underscore object, ensuring that | |
620 # they're correctly added to the OOP wrapper as well. | |
621 _.mixin = (obj) -> | |
622 for name in _.functions(obj) | |
623 addToWrapper name, _[name] = obj[name] | |
624 | |
625 | |
626 # Generate a unique integer id (unique within the entire client session). | |
627 # Useful for temporary DOM ids. | |
628 idCounter = 0 | |
629 _.uniqueId = (prefix) -> | |
630 (prefix or '') + idCounter++ | |
631 | |
632 | |
633 # By default, Underscore uses **ERB**-style template delimiters, change the | |
634 # following template settings to use alternative delimiters. | |
635 _.templateSettings = { | |
636 start: '<%' | |
637 end: '%>' | |
638 interpolate: /<%=(.+?)%>/g | |
639 } | |
640 | |
641 | |
642 # JavaScript templating a-la **ERB**, pilfered from John Resig's | |
643 # *Secrets of the JavaScript Ninja*, page 83. | |
644 # Single-quote fix from Rick Strahl. | |
645 # With alterations for arbitrary delimiters, and to preserve whitespace. | |
646 _.template = (str, data) -> | |
647 c = _.templateSettings | |
648 endMatch = new RegExp("'(?=[^"+c.end.substr(0, 1)+"]*"+escapeRegExp(c.end)+")","g") | |
649 fn = new Function 'obj', | |
650 'var p=[],print=function(){p.push.apply(p,arguments);};' + | |
651 'with(obj||{}){p.push(\'' + | |
652 str.replace(/\r/g, '\\r') | |
653 .replace(/\n/g, '\\n') | |
654 .replace(/\t/g, '\\t') | |
655 .replace(endMatch,"���") | |
656 .split("'").join("\\'") | |
657 .split("���").join("'") | |
658 .replace(c.interpolate, "',$1,'") | |
659 .split(c.start).join("');") | |
660 .split(c.end).join("p.push('") + | |
661 "');}return p.join('');" | |
662 if data then fn(data) else fn | |
663 | |
664 | |
665 # Aliases | |
666 # ------- | |
667 | |
668 _.forEach = _.each | |
669 _.foldl = _.inject = _.reduce | |
670 _.foldr = _.reduceRight | |
671 _.select = _.filter | |
672 _.all = _.every | |
673 _.any = _.some | |
674 _.contains = _.include | |
675 _.head = _.first | |
676 _.tail = _.rest | |
677 _.methods = _.functions | |
678 | |
679 | |
680 # Setup the OOP Wrapper | |
681 # --------------------- | |
682 | |
683 # If Underscore is called as a function, it returns a wrapped object that | |
684 # can be used OO-style. This wrapper holds altered versions of all the | |
685 # underscore functions. Wrapped objects may be chained. | |
686 wrapper = (obj) -> | |
687 this._wrapped = obj | |
688 this | |
689 | |
690 | |
691 # Helper function to continue chaining intermediate results. | |
692 result = (obj, chain) -> | |
693 if chain then _(obj).chain() else obj | |
694 | |
695 | |
696 # A method to easily add functions to the OOP wrapper. | |
697 addToWrapper = (name, func) -> | |
698 wrapper.prototype[name] = -> | |
699 args = _.toArray arguments | |
700 unshift.call args, this._wrapped | |
701 result func.apply(_, args), this._chain | |
702 | |
703 | |
704 # Add all ofthe Underscore functions to the wrapper object. | |
705 _.mixin _ | |
706 | |
707 | |
708 # Add all mutator Array functions to the wrapper. | |
709 _.each ['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], (name) -> | |
710 method = Array.prototype[name] | |
711 wrapper.prototype[name] = -> | |
712 method.apply(this._wrapped, arguments) | |
713 result(this._wrapped, this._chain) | |
714 | |
715 | |
716 # Add all accessor Array functions to the wrapper. | |
717 _.each ['concat', 'join', 'slice'], (name) -> | |
718 method = Array.prototype[name] | |
719 wrapper.prototype[name] = -> | |
720 result(method.apply(this._wrapped, arguments), this._chain) | |
721 | |
722 | |
723 # Start chaining a wrapped Underscore object. | |
724 wrapper::chain = -> | |
725 this._chain = true | |
726 this | |
727 | |
728 | |
729 # Extracts the result from a wrapped and chained object. | |
730 wrapper::value = -> this._wrapped | |
731 </textarea></form> | |
732 <script> | |
733 var editor = CodeMirror.fromTextArea(document.getElementById("code"), {}); | |
734 </script> | |
735 | |
736 <p><strong>MIME types defined:</strong> <code>application/vnd.coffeescript</code>, <code>text/coffeescript</code>, <code>text/x-coffeescript</code>.</p> | |
737 | |
738 <p>The CoffeeScript mode was written by Jeff Pickhardt.</p> | |
739 | |
740 </article> |