1
0
mirror of https://github.com/chinchang/web-maker.git synced 2025-05-04 17:46:42 +02:00

Merge pull request #14 from chinchang/preprocessors

Preprocessors
This commit is contained in:
Kushagra Gour 2016-07-15 03:03:44 +05:30 committed by GitHub
commit 35658fcd17
31 changed files with 3585 additions and 2133 deletions

View File

@ -99,7 +99,7 @@
"no-implicit-coercion": "error",
"no-implicit-globals": "off",
"no-implied-eval": "error",
"no-inline-comments": "error",
"no-inline-comments": "off",
"no-inner-declarations": [
"error",
"functions"
@ -118,7 +118,7 @@
"no-multiple-empty-lines": "error",
"no-native-reassign": "error",
"no-negated-condition": "off",
"no-nested-ternary": "error",
"no-nested-ternary": "off",
"no-new": "error",
"no-new-func": "error",
"no-new-object": "error",
@ -178,9 +178,9 @@
"no-with": "error",
"object-curly-spacing": [
"error",
"never"
"always"
],
"object-property-newline": "error",
"object-property-newline": "off",
"object-shorthand": "off",
"one-var": "off",
"one-var-declaration-per-line": "error",
@ -195,7 +195,7 @@
"padded-blocks": "off",
"prefer-arrow-callback": "off",
"prefer-const": "error",
"prefer-reflect": "error",
"prefer-reflect": "off",
"prefer-rest-params": "off",
"prefer-spread": "error",
"prefer-template": "off",
@ -235,7 +235,7 @@
"error",
"never"
],
"valid-jsdoc": "error",
"valid-jsdoc": "off",
"vars-on-top": "off",
"wrap-regex": "error",
"yield-star-spacing": "error",
@ -248,6 +248,17 @@
"chrome": true,
"CodeMirror": true,
"Split": true,
"emmetCodeMirror": true
"emmetCodeMirror": true,
"deferred": true,
"$": true,
"$all": true,
"CoffeeScript": true,
"Babel": true,
"Sass": true,
"less": true,
"marked": true,
"jade": true,
"loadJS": true,
"Promise": true
}
}

BIN
src/Inconsolata-Regular.ttf Executable file

Binary file not shown.

12
src/deferred.js Normal file
View File

@ -0,0 +1,12 @@
(function() {
window.deferred = function () {
var d = {};
var promise = new Promise(function (resolve, reject) {
d.resolve = resolve;
d.reject = reject;
});
d.promise = promise;
return Object.assign(d, promise);
};
})();

30
src/dropdown.js Normal file
View File

@ -0,0 +1,30 @@
// Dropdown.js
(function($all) {
var openDropdown;
// Closes all dropdowns except the passed one.
function closeOpenDropdown(except) {
if (openDropdown && (!except || except !== openDropdown)) {
openDropdown.classList.remove('open');
openDropdown = null;
}
}
function init() {
var dropdowns = [].slice.call($all('[dropdown]'));
dropdowns.forEach(function (dropdown) {
dropdown.addEventListener('click', function (e) {
closeOpenDropdown(e.currentTarget);
e.currentTarget.classList.toggle('open');
openDropdown = e.currentTarget;
e.stopPropagation();
});
});
document.addEventListener('click', function () {
closeOpenDropdown();
});
}
init();
})($all);

View File

@ -5,8 +5,15 @@
<link rel="stylesheet" href="lib/codemirror/lib/codemirror.css">
<link rel="stylesheet" href="lib/codemirror/theme/monokai.css">
<link rel="stylesheet" href="lib/hint.min.css">
<style>
@font-face {
font-family: 'Inconsolata';
font-style: normal;
font-weight: 400;
src: local('Inconsolata'), url(../Inconsolata-Regular.ttf) format('truetype');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
}
body {
margin: 0;
padding: 0;
@ -29,6 +36,16 @@
.fr {
float: right;
}
.caret {
display: inline-block;
width: 0;
height: 0;
border: 6px solid transparent;
border-top-color: currentColor;
position: relative;
top: 5px;
margin-left: 7px;
}
.main-container {
position: absolute;
left: 0; right: 0;
@ -59,9 +76,9 @@
height: 33%;
overflow: hidden;
position: relative;
animation: pop-in 0.4s cubic-bezier(.71,1.7,.77,1.24) forwards 0.2s;
animation: pop-in 0.4s ease forwards 0.2s;
opacity: 0;
/*animation: pop-in 0.4s cubic-bezier(.71,1.7,.77,1.24) forwards 0.2s;*/
/*animation: pop-in 0.4s ease forwards 0.2s;*/
/*opacity: 0;*/
}
.layout-2 .code-wrap {
height: auto;
@ -74,17 +91,12 @@
animation-delay: 0.4s;
}
.code-wrap:after {
content: attr(data-type);
text-transform: uppercase;
font-size: 65px;
display: block;
position: absolute;
top: 4px;
color: rgba(255,255,255,0.04);
left: 52px;
z-index: 3;
pointer-events: none;
.code-wrap__header {
padding: 5px 20px;
background: rgba(0,0,0,0.55);
color: #888;
border-bottom: 1px solid rgba(0,0,0,0.3);
font-weight: bold;
}
@keyframes pop-in {
from { transform: scale(0.9); opacity: 0; }
@ -94,9 +106,12 @@
/* Codemirror */
.Codemirror {
width: 100%;
height: 100%;
height: calc(100% - 25px); /* 25px for header */
font-size: 16px;
}
.Codemirror pre {
font-family: 'Inconsolata', monospace;
}
.cm-s-monokai .CodeMirror-linenumber {
color:rgba(255,255,255,0.2);
}
@ -167,6 +182,9 @@
.mode-btn.selected svg {
fill: rgba(255, 255, 255, 0.45);
}
.gutter {
background: rgba(0,0,0,0.2);
}
.gutter-horizontal {
cursor: ew-resize;
}
@ -274,6 +292,49 @@
top: 2px;
left: 2px;
}
.btn-group {
position: relative;
}
.btn-group {
cursor: pointer;
}
.dropdown__menu {
position: absolute;
top: 100%;
left: 0;
padding: 0;
margin: 0;
min-width: 200px;
display: block;
list-style: none;
border-radius: 4px;
overflow: hidden;
opacity: 0;
visibility: hidden;
transition: 0.25s ease;
transform: translateY(10px);
z-index: 5;
background: white;
}
.dropdown__menu > li > a {
display: block;
padding: 15px;
color: #333;
cursor: pointer;
}
.dropdown__menu > li > a:hover {
background: #ff8c00;
color: white;
}
.dropdown__menu > li:not(:last-child) {
border-bottom: 1px solid rgba(0,0,0,0.05);
}
.open .dropdown__menu {
opacity: 1;
visibility: visible;
transform: translateY(0);
}
</style>
</head>
@ -281,9 +342,42 @@
<div class="main-container">
<div class="content-wrap flex flex-grow">
<div class="code-side" id="js-code-side">
<div id="js-html-code" data-type="html" class="code-wrap"></div>
<div id="js-css-code" data-type="css" class="code-wrap"></div>
<div id="js-js-code" data-type="js" class="code-wrap"></div>
<div id="js-html-code" data-type="html" class="code-wrap">
<div class="code-wrap__header">
<div class="btn-group" dropdown>
<span id="js-html-mode-label">HTML</span><span class="caret"></span>
<ul class="js-modes-menu dropdown__menu">
<li><a data-type="html" data-mode="html">HTML</a></li>
<li><a data-type="html" data-mode="markdown">Markdown</a></li>
<li><a data-type="html" data-mode="jade">Jade</a></li>
</ul>
</div>
</div>
</div>
<div id="js-css-code" data-type="css" class="code-wrap">
<div class="code-wrap__header">
<div class="btn-group" dropdown>
<span id="js-css-mode-label">CSS</span><span class="caret"></span>
<ul class="js-modes-menu dropdown__menu">
<li><a data-type="css" data-mode="css">CSS</a></li>
<li><a data-type="css" data-mode="scss">SCSS</a></li>
<li><a data-type="css" data-mode="less">LESS</a></li>
</ul>
</div>
</div>
</div>
<div id="js-js-code" data-type="js" class="code-wrap">
<div class="code-wrap__header">
<div class="btn-group" dropdown>
<span id="js-js-mode-label">JS</span><span class="caret"></span>
<ul class="js-modes-menu dropdown__menu">
<li><a data-type="js" data-mode="js">JS</a></li>
<li><a data-type="js" data-mode="coffee">CoffeeScript</a></li>
<li><a data-type="js" data-mode="es6">ES6 (Babel)</a></li>
</ul>
</div>
</div>
</div>
</div>
<div class="demo-side" id="js-demo-side">
<iframe src="about://blank" frameborder="0" id="demo-frame"></iframe>
@ -421,6 +515,8 @@
<script src="lib/codemirror/addon/edit/matchbrackets.js"></script>
<script src="lib/codemirror/addon/edit/closebrackets.js"></script>
<script src="lib/codemirror/addon/edit/closetag.js"></script>
<script src="lib/codemirror/addon/comment/comment.js"></script>
<script src="lib/codemirror/addon/mode/loadmode.js"></script>
<script src="lib/codemirror/mode/xml/xml.js"></script>
<script src="lib/codemirror/mode/javascript/javascript.js"></script>
@ -430,7 +526,11 @@
<script src="lib/emmet.js"></script>
<script src="lib/split.js"></script>
<script src="deferred.js"></script>
<script src="loader.js"></script>
<script src="script.js"></script>
<script src="dropdown.js"></script>
</body>
</html>

32
src/lib/babel.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -1,740 +0,0 @@
<!doctype html>
<title>CodeMirror: CoffeeScript mode</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../../doc/docs.css">
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="coffeescript.js"></script>
<style>.CodeMirror {border-top: 1px solid silver; border-bottom: 1px solid silver;}</style>
<div id=nav>
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<ul>
<li><a href="../../index.html">Home</a>
<li><a href="../../doc/manual.html">Manual</a>
<li><a href="https://github.com/codemirror/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="#">CoffeeScript</a>
</ul>
</div>
<article>
<h2>CoffeeScript mode</h2>
<form><textarea id="code" name="code">
# CoffeeScript mode for CodeMirror
# Copyright (c) 2011 Jeff Pickhardt, released under
# the MIT License.
#
# Modified from the Python CodeMirror mode, which also is
# under the MIT License Copyright (c) 2010 Timothy Farrell.
#
# The following script, Underscore.coffee, is used to
# demonstrate CoffeeScript mode for CodeMirror.
#
# To download CoffeeScript mode for CodeMirror, go to:
# https://github.com/pickhardt/coffeescript-codemirror-mode
# **Underscore.coffee
# (c) 2011 Jeremy Ashkenas, DocumentCloud Inc.**
# Underscore is freely distributable under the terms of the
# [MIT license](http://en.wikipedia.org/wiki/MIT_License).
# Portions of Underscore are inspired by or borrowed from
# [Prototype.js](http://prototypejs.org/api), Oliver Steele's
# [Functional](http://osteele.com), and John Resig's
# [Micro-Templating](http://ejohn.org).
# For all details and documentation:
# http://documentcloud.github.com/underscore/
# Baseline setup
# --------------
# Establish the root object, `window` in the browser, or `global` on the server.
root = this
# Save the previous value of the `_` variable.
previousUnderscore = root._
### Multiline
comment
###
# Establish the object that gets thrown to break out of a loop iteration.
# `StopIteration` is SOP on Mozilla.
breaker = if typeof(StopIteration) is 'undefined' then '__break__' else StopIteration
#### Docco style single line comment (title)
# Helper function to escape **RegExp** contents, because JS doesn't have one.
escapeRegExp = (string) -> string.replace(/([.*+?^${}()|[\]\/\\])/g, '\\$1')
# Save bytes in the minified (but not gzipped) version:
ArrayProto = Array.prototype
ObjProto = Object.prototype
# Create quick reference variables for speed access to core prototypes.
slice = ArrayProto.slice
unshift = ArrayProto.unshift
toString = ObjProto.toString
hasOwnProperty = ObjProto.hasOwnProperty
propertyIsEnumerable = ObjProto.propertyIsEnumerable
# All **ECMA5** native implementations we hope to use are declared here.
nativeForEach = ArrayProto.forEach
nativeMap = ArrayProto.map
nativeReduce = ArrayProto.reduce
nativeReduceRight = ArrayProto.reduceRight
nativeFilter = ArrayProto.filter
nativeEvery = ArrayProto.every
nativeSome = ArrayProto.some
nativeIndexOf = ArrayProto.indexOf
nativeLastIndexOf = ArrayProto.lastIndexOf
nativeIsArray = Array.isArray
nativeKeys = Object.keys
# Create a safe reference to the Underscore object for use below.
_ = (obj) -> new wrapper(obj)
# Export the Underscore object for **CommonJS**.
if typeof(exports) != 'undefined' then exports._ = _
# Export Underscore to global scope.
root._ = _
# Current version.
_.VERSION = '1.1.0'
# Collection Functions
# --------------------
# The cornerstone, an **each** implementation.
# Handles objects implementing **forEach**, arrays, and raw objects.
_.each = (obj, iterator, context) ->
try
if nativeForEach and obj.forEach is nativeForEach
obj.forEach iterator, context
else if _.isNumber obj.length
iterator.call context, obj[i], i, obj for i in [0...obj.length]
else
iterator.call context, val, key, obj for own key, val of obj
catch e
throw e if e isnt breaker
obj
# Return the results of applying the iterator to each element. Use JavaScript
# 1.6's version of **map**, if possible.
_.map = (obj, iterator, context) ->
return obj.map(iterator, context) if nativeMap and obj.map is nativeMap
results = []
_.each obj, (value, index, list) ->
results.push iterator.call context, value, index, list
results
# **Reduce** builds up a single result from a list of values. Also known as
# **inject**, or **foldl**. Uses JavaScript 1.8's version of **reduce**, if possible.
_.reduce = (obj, iterator, memo, context) ->
if nativeReduce and obj.reduce is nativeReduce
iterator = _.bind iterator, context if context
return obj.reduce iterator, memo
_.each obj, (value, index, list) ->
memo = iterator.call context, memo, value, index, list
memo
# The right-associative version of **reduce**, also known as **foldr**. Uses
# JavaScript 1.8's version of **reduceRight**, if available.
_.reduceRight = (obj, iterator, memo, context) ->
if nativeReduceRight and obj.reduceRight is nativeReduceRight
iterator = _.bind iterator, context if context
return obj.reduceRight iterator, memo
reversed = _.clone(_.toArray(obj)).reverse()
_.reduce reversed, iterator, memo, context
# Return the first value which passes a truth test.
_.detect = (obj, iterator, context) ->
result = null
_.each obj, (value, index, list) ->
if iterator.call context, value, index, list
result = value
_.breakLoop()
result
# Return all the elements that pass a truth test. Use JavaScript 1.6's
# **filter**, if it exists.
_.filter = (obj, iterator, context) ->
return obj.filter iterator, context if nativeFilter and obj.filter is nativeFilter
results = []
_.each obj, (value, index, list) ->
results.push value if iterator.call context, value, index, list
results
# Return all the elements for which a truth test fails.
_.reject = (obj, iterator, context) ->
results = []
_.each obj, (value, index, list) ->
results.push value if not iterator.call context, value, index, list
results
# Determine whether all of the elements match a truth test. Delegate to
# JavaScript 1.6's **every**, if it is present.
_.every = (obj, iterator, context) ->
iterator ||= _.identity
return obj.every iterator, context if nativeEvery and obj.every is nativeEvery
result = true
_.each obj, (value, index, list) ->
_.breakLoop() unless (result = result and iterator.call(context, value, index, list))
result
# Determine if at least one element in the object matches a truth test. Use
# JavaScript 1.6's **some**, if it exists.
_.some = (obj, iterator, context) ->
iterator ||= _.identity
return obj.some iterator, context if nativeSome and obj.some is nativeSome
result = false
_.each obj, (value, index, list) ->
_.breakLoop() if (result = iterator.call(context, value, index, list))
result
# Determine if a given value is included in the array or object,
# based on `===`.
_.include = (obj, target) ->
return _.indexOf(obj, target) isnt -1 if nativeIndexOf and obj.indexOf is nativeIndexOf
return true for own key, val of obj when val is target
false
# Invoke a method with arguments on every item in a collection.
_.invoke = (obj, method) ->
args = _.rest arguments, 2
(if method then val[method] else val).apply(val, args) for val in obj
# Convenience version of a common use case of **map**: fetching a property.
_.pluck = (obj, key) ->
_.map(obj, (val) -> val[key])
# Return the maximum item or (item-based computation).
_.max = (obj, iterator, context) ->
return Math.max.apply(Math, obj) if not iterator and _.isArray(obj)
result = computed: -Infinity
_.each obj, (value, index, list) ->
computed = if iterator then iterator.call(context, value, index, list) else value
computed >= result.computed and (result = {value: value, computed: computed})
result.value
# Return the minimum element (or element-based computation).
_.min = (obj, iterator, context) ->
return Math.min.apply(Math, obj) if not iterator and _.isArray(obj)
result = computed: Infinity
_.each obj, (value, index, list) ->
computed = if iterator then iterator.call(context, value, index, list) else value
computed < result.computed and (result = {value: value, computed: computed})
result.value
# Sort the object's values by a criterion produced by an iterator.
_.sortBy = (obj, iterator, context) ->
_.pluck(((_.map obj, (value, index, list) ->
{value: value, criteria: iterator.call(context, value, index, list)}
).sort((left, right) ->
a = left.criteria; b = right.criteria
if a < b then -1 else if a > b then 1 else 0
)), 'value')
# Use a comparator function to figure out at what index an object should
# be inserted so as to maintain order. Uses binary search.
_.sortedIndex = (array, obj, iterator) ->
iterator ||= _.identity
low = 0
high = array.length
while low < high
mid = (low + high) >> 1
if iterator(array[mid]) < iterator(obj) then low = mid + 1 else high = mid
low
# Convert anything iterable into a real, live array.
_.toArray = (iterable) ->
return [] if (!iterable)
return iterable.toArray() if (iterable.toArray)
return iterable if (_.isArray(iterable))
return slice.call(iterable) if (_.isArguments(iterable))
_.values(iterable)
# Return the number of elements in an object.
_.size = (obj) -> _.toArray(obj).length
# Array Functions
# ---------------
# Get the first element of an array. Passing `n` will return the first N
# values in the array. Aliased as **head**. The `guard` check allows it to work
# with **map**.
_.first = (array, n, guard) ->
if n and not guard then slice.call(array, 0, n) else array[0]
# Returns everything but the first entry of the array. Aliased as **tail**.
# Especially useful on the arguments object. Passing an `index` will return
# the rest of the values in the array from that index onward. The `guard`
# check allows it to work with **map**.
_.rest = (array, index, guard) ->
slice.call(array, if _.isUndefined(index) or guard then 1 else index)
# Get the last element of an array.
_.last = (array) -> array[array.length - 1]
# Trim out all falsy values from an array.
_.compact = (array) -> item for item in array when item
# Return a completely flattened version of an array.
_.flatten = (array) ->
_.reduce array, (memo, value) ->
return memo.concat(_.flatten(value)) if _.isArray value
memo.push value
memo
, []
# Return a version of the array that does not contain the specified value(s).
_.without = (array) ->
values = _.rest arguments
val for val in _.toArray(array) when not _.include values, val
# Produce a duplicate-free version of the array. If the array has already
# been sorted, you have the option of using a faster algorithm.
_.uniq = (array, isSorted) ->
memo = []
for el, i in _.toArray array
memo.push el if i is 0 || (if isSorted is true then _.last(memo) isnt el else not _.include(memo, el))
memo
# Produce an array that contains every item shared between all the
# passed-in arrays.
_.intersect = (array) ->
rest = _.rest arguments
_.select _.uniq(array), (item) ->
_.all rest, (other) ->
_.indexOf(other, item) >= 0
# Zip together multiple lists into a single array -- elements that share
# an index go together.
_.zip = ->
length = _.max _.pluck arguments, 'length'
results = new Array length
for i in [0...length]
results[i] = _.pluck arguments, String i
results
# If the browser doesn't supply us with **indexOf** (I'm looking at you, MSIE),
# we need this function. Return the position of the first occurrence of an
# item in an array, or -1 if the item is not included in the array.
_.indexOf = (array, item) ->
return array.indexOf item if nativeIndexOf and array.indexOf is nativeIndexOf
i = 0; l = array.length
while l - i
if array[i] is item then return i else i++
-1
# Provide JavaScript 1.6's **lastIndexOf**, delegating to the native function,
# if possible.
_.lastIndexOf = (array, item) ->
return array.lastIndexOf(item) if nativeLastIndexOf and array.lastIndexOf is nativeLastIndexOf
i = array.length
while i
if array[i] is item then return i else i--
-1
# Generate an integer Array containing an arithmetic progression. A port of
# [the native Python **range** function](http://docs.python.org/library/functions.html#range).
_.range = (start, stop, step) ->
a = arguments
solo = a.length <= 1
i = start = if solo then 0 else a[0]
stop = if solo then a[0] else a[1]
step = a[2] or 1
len = Math.ceil((stop - start) / step)
return [] if len <= 0
range = new Array len
idx = 0
loop
return range if (if step > 0 then i - stop else stop - i) >= 0
range[idx] = i
idx++
i+= step
# Function Functions
# ------------------
# Create a function bound to a given object (assigning `this`, and arguments,
# optionally). Binding with arguments is also known as **curry**.
_.bind = (func, obj) ->
args = _.rest arguments, 2
-> func.apply obj or root, args.concat arguments
# Bind all of an object's methods to that object. Useful for ensuring that
# all callbacks defined on an object belong to it.
_.bindAll = (obj) ->
funcs = if arguments.length > 1 then _.rest(arguments) else _.functions(obj)
_.each funcs, (f) -> obj[f] = _.bind obj[f], obj
obj
# Delays a function for the given number of milliseconds, and then calls
# it with the arguments supplied.
_.delay = (func, wait) ->
args = _.rest arguments, 2
setTimeout((-> func.apply(func, args)), wait)
# Memoize an expensive function by storing its results.
_.memoize = (func, hasher) ->
memo = {}
hasher or= _.identity
->
key = hasher.apply this, arguments
return memo[key] if key of memo
memo[key] = func.apply this, arguments
# Defers a function, scheduling it to run after the current call stack has
# cleared.
_.defer = (func) ->
_.delay.apply _, [func, 1].concat _.rest arguments
# Returns the first function passed as an argument to the second,
# allowing you to adjust arguments, run code before and after, and
# conditionally execute the original function.
_.wrap = (func, wrapper) ->
-> wrapper.apply wrapper, [func].concat arguments
# Returns a function that is the composition of a list of functions, each
# consuming the return value of the function that follows.
_.compose = ->
funcs = arguments
->
args = arguments
for i in [funcs.length - 1..0] by -1
args = [funcs[i].apply(this, args)]
args[0]
# Object Functions
# ----------------
# Retrieve the names of an object's properties.
_.keys = nativeKeys or (obj) ->
return _.range 0, obj.length if _.isArray(obj)
key for key, val of obj
# Retrieve the values of an object's properties.
_.values = (obj) ->
_.map obj, _.identity
# Return a sorted list of the function names available in Underscore.
_.functions = (obj) ->
_.filter(_.keys(obj), (key) -> _.isFunction(obj[key])).sort()
# Extend a given object with all of the properties in a source object.
_.extend = (obj) ->
for source in _.rest(arguments)
obj[key] = val for key, val of source
obj
# Create a (shallow-cloned) duplicate of an object.
_.clone = (obj) ->
return obj.slice 0 if _.isArray obj
_.extend {}, obj
# Invokes interceptor with the obj, and then returns obj.
# The primary purpose of this method is to "tap into" a method chain,
# in order to perform operations on intermediate results within
the chain.
_.tap = (obj, interceptor) ->
interceptor obj
obj
# Perform a deep comparison to check if two objects are equal.
_.isEqual = (a, b) ->
# Check object identity.
return true if a is b
# Different types?
atype = typeof(a); btype = typeof(b)
return false if atype isnt btype
# Basic equality test (watch out for coercions).
return true if `a == b`
# One is falsy and the other truthy.
return false if (!a and b) or (a and !b)
# One of them implements an `isEqual()`?
return a.isEqual(b) if a.isEqual
# Check dates' integer values.
return a.getTime() is b.getTime() if _.isDate(a) and _.isDate(b)
# Both are NaN?
return false if _.isNaN(a) and _.isNaN(b)
# Compare regular expressions.
if _.isRegExp(a) and _.isRegExp(b)
return a.source is b.source and
a.global is b.global and
a.ignoreCase is b.ignoreCase and
a.multiline is b.multiline
# If a is not an object by this point, we can't handle it.
return false if atype isnt 'object'
# Check for different array lengths before comparing contents.
return false if a.length and (a.length isnt b.length)
# Nothing else worked, deep compare the contents.
aKeys = _.keys(a); bKeys = _.keys(b)
# Different object sizes?
return false if aKeys.length isnt bKeys.length
# Recursive comparison of contents.
return false for key, val of a when !(key of b) or !_.isEqual(val, b[key])
true
# Is a given array or object empty?
_.isEmpty = (obj) ->
return obj.length is 0 if _.isArray(obj) or _.isString(obj)
return false for own key of obj
true
# Is a given value a DOM element?
_.isElement = (obj) -> obj and obj.nodeType is 1
# Is a given value an array?
_.isArray = nativeIsArray or (obj) -> !!(obj and obj.concat and obj.unshift and not obj.callee)
# Is a given variable an arguments object?
_.isArguments = (obj) -> obj and obj.callee
# Is the given value a function?
_.isFunction = (obj) -> !!(obj and obj.constructor and obj.call and obj.apply)
# Is the given value a string?
_.isString = (obj) -> !!(obj is '' or (obj and obj.charCodeAt and obj.substr))
# Is a given value a number?
_.isNumber = (obj) -> (obj is +obj) or toString.call(obj) is '[object Number]'
# Is a given value a boolean?
_.isBoolean = (obj) -> obj is true or obj is false
# Is a given value a Date?
_.isDate = (obj) -> !!(obj and obj.getTimezoneOffset and obj.setUTCFullYear)
# Is the given value a regular expression?
_.isRegExp = (obj) -> !!(obj and obj.exec and (obj.ignoreCase or obj.ignoreCase is false))
# Is the given value NaN -- this one is interesting. `NaN != NaN`, and
# `isNaN(undefined) == true`, so we make sure it's a number first.
_.isNaN = (obj) -> _.isNumber(obj) and window.isNaN(obj)
# Is a given value equal to null?
_.isNull = (obj) -> obj is null
# Is a given variable undefined?
_.isUndefined = (obj) -> typeof obj is 'undefined'
# Utility Functions
# -----------------
# Run Underscore.js in noConflict mode, returning the `_` variable to its
# previous owner. Returns a reference to the Underscore object.
_.noConflict = ->
root._ = previousUnderscore
this
# Keep the identity function around for default iterators.
_.identity = (value) -> value
# Run a function `n` times.
_.times = (n, iterator, context) ->
iterator.call context, i for i in [0...n]
# Break out of the middle of an iteration.
_.breakLoop = -> throw breaker
# Add your own custom functions to the Underscore object, ensuring that
# they're correctly added to the OOP wrapper as well.
_.mixin = (obj) ->
for name in _.functions(obj)
addToWrapper name, _[name] = obj[name]
# Generate a unique integer id (unique within the entire client session).
# Useful for temporary DOM ids.
idCounter = 0
_.uniqueId = (prefix) ->
(prefix or '') + idCounter++
# By default, Underscore uses **ERB**-style template delimiters, change the
# following template settings to use alternative delimiters.
_.templateSettings = {
start: '<%'
end: '%>'
interpolate: /<%=(.+?)%>/g
}
# JavaScript templating a-la **ERB**, pilfered from John Resig's
# *Secrets of the JavaScript Ninja*, page 83.
# Single-quote fix from Rick Strahl.
# With alterations for arbitrary delimiters, and to preserve whitespace.
_.template = (str, data) ->
c = _.templateSettings
endMatch = new RegExp("'(?=[^"+c.end.substr(0, 1)+"]*"+escapeRegExp(c.end)+")","g")
fn = new Function 'obj',
'var p=[],print=function(){p.push.apply(p,arguments);};' +
'with(obj||{}){p.push(\'' +
str.replace(/\r/g, '\\r')
.replace(/\n/g, '\\n')
.replace(/\t/g, '\\t')
.replace(endMatch,"<22><><EFBFBD>")
.split("'").join("\\'")
.split("<22><><EFBFBD>").join("'")
.replace(c.interpolate, "',$1,'")
.split(c.start).join("');")
.split(c.end).join("p.push('") +
"');}return p.join('');"
if data then fn(data) else fn
# Aliases
# -------
_.forEach = _.each
_.foldl = _.inject = _.reduce
_.foldr = _.reduceRight
_.select = _.filter
_.all = _.every
_.any = _.some
_.contains = _.include
_.head = _.first
_.tail = _.rest
_.methods = _.functions
# Setup the OOP Wrapper
# ---------------------
# If Underscore is called as a function, it returns a wrapped object that
# can be used OO-style. This wrapper holds altered versions of all the
# underscore functions. Wrapped objects may be chained.
wrapper = (obj) ->
this._wrapped = obj
this
# Helper function to continue chaining intermediate results.
result = (obj, chain) ->
if chain then _(obj).chain() else obj
# A method to easily add functions to the OOP wrapper.
addToWrapper = (name, func) ->
wrapper.prototype[name] = ->
args = _.toArray arguments
unshift.call args, this._wrapped
result func.apply(_, args), this._chain
# Add all ofthe Underscore functions to the wrapper object.
_.mixin _
# Add all mutator Array functions to the wrapper.
_.each ['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], (name) ->
method = Array.prototype[name]
wrapper.prototype[name] = ->
method.apply(this._wrapped, arguments)
result(this._wrapped, this._chain)
# Add all accessor Array functions to the wrapper.
_.each ['concat', 'join', 'slice'], (name) ->
method = Array.prototype[name]
wrapper.prototype[name] = ->
result(method.apply(this._wrapped, arguments), this._chain)
# Start chaining a wrapped Underscore object.
wrapper::chain = ->
this._chain = true
this
# Extracts the result from a wrapped and chained object.
wrapper::value = -> this._wrapped
</textarea></form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {});
</script>
<p><strong>MIME types defined:</strong> <code>text/x-coffeescript</code>.</p>
<p>The CoffeeScript mode was written by Jeff Pickhardt.</p>
</article>

View File

@ -1,75 +0,0 @@
<!doctype html>
<title>CodeMirror: CSS mode</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../../doc/docs.css">
<link rel="stylesheet" href="../../lib/codemirror.css">
<link rel="stylesheet" href="../../addon/hint/show-hint.css">
<script src="../../lib/codemirror.js"></script>
<script src="css.js"></script>
<script src="../../addon/hint/show-hint.js"></script>
<script src="../../addon/hint/css-hint.js"></script>
<style>.CodeMirror {background: #f8f8f8;}</style>
<div id=nav>
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<ul>
<li><a href="../../index.html">Home</a>
<li><a href="../../doc/manual.html">Manual</a>
<li><a href="https://github.com/codemirror/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="#">CSS</a>
</ul>
</div>
<article>
<h2>CSS mode</h2>
<form><textarea id="code" name="code">
/* Some example CSS */
@import url("something.css");
body {
margin: 0;
padding: 3em 6em;
font-family: tahoma, arial, sans-serif;
color: #000;
}
#navigation a {
font-weight: bold;
text-decoration: none !important;
}
h1 {
font-size: 2.5em;
}
h2 {
font-size: 1.7em;
}
h1:before, h2:before {
content: "::";
}
code {
font-family: courier, monospace;
font-size: 80%;
color: #418A8A;
}
</textarea></form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
extraKeys: {"Ctrl-Space": "autocomplete"},
});
</script>
<p><strong>MIME types defined:</strong> <code>text/css</code>, <code>text/x-scss</code> (<a href="scss.html">demo</a>), <code>text/x-less</code> (<a href="less.html">demo</a>).</p>
<p><strong>Parsing/Highlighting Tests:</strong> <a href="../../test/index.html#css_*">normal</a>, <a href="../../test/index.html#verbose,css_*">verbose</a>.</p>
</article>

View File

@ -1,54 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function() {
"use strict";
var mode = CodeMirror.getMode({indentUnit: 2}, "text/x-less");
function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1), "less"); }
MT("variable",
"[variable-2 @base]: [atom #f04615];",
"[qualifier .class] {",
" [property width]: [variable percentage]([number 0.5]); [comment // returns `50%`]",
" [property color]: [variable saturate]([variable-2 @base], [number 5%]);",
"}");
MT("amp",
"[qualifier .child], [qualifier .sibling] {",
" [qualifier .parent] [atom &] {",
" [property color]: [keyword black];",
" }",
" [atom &] + [atom &] {",
" [property color]: [keyword red];",
" }",
"}");
MT("mixin",
"[qualifier .mixin] ([variable dark]; [variable-2 @color]) {",
" [property color]: [atom darken]([variable-2 @color], [number 10%]);",
"}",
"[qualifier .mixin] ([variable light]; [variable-2 @color]) {",
" [property color]: [atom lighten]([variable-2 @color], [number 10%]);",
"}",
"[qualifier .mixin] ([variable-2 @_]; [variable-2 @color]) {",
" [property display]: [atom block];",
"}",
"[variable-2 @switch]: [variable light];",
"[qualifier .class] {",
" [qualifier .mixin]([variable-2 @switch]; [atom #888]);",
"}");
MT("nest",
"[qualifier .one] {",
" [def @media] ([property width]: [number 400px]) {",
" [property font-size]: [number 1.2em];",
" [def @media] [attribute print] [keyword and] [property color] {",
" [property color]: [keyword blue];",
" }",
" }",
"}");
MT("interpolation", ".@{[variable foo]} { [property font-weight]: [atom bold]; }");
})();

View File

@ -1,110 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function() {
var mode = CodeMirror.getMode({indentUnit: 2}, "text/x-scss");
function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1), "scss"); }
MT('url_with_quotation',
"[tag foo] { [property background]:[atom url]([string test.jpg]) }");
MT('url_with_double_quotes',
"[tag foo] { [property background]:[atom url]([string \"test.jpg\"]) }");
MT('url_with_single_quotes',
"[tag foo] { [property background]:[atom url]([string \'test.jpg\']) }");
MT('string',
"[def @import] [string \"compass/css3\"]");
MT('important_keyword',
"[tag foo] { [property background]:[atom url]([string \'test.jpg\']) [keyword !important] }");
MT('variable',
"[variable-2 $blue]:[atom #333]");
MT('variable_as_attribute',
"[tag foo] { [property color]:[variable-2 $blue] }");
MT('numbers',
"[tag foo] { [property padding]:[number 10px] [number 10] [number 10em] [number 8in] }");
MT('number_percentage',
"[tag foo] { [property width]:[number 80%] }");
MT('selector',
"[builtin #hello][qualifier .world]{}");
MT('singleline_comment',
"[comment // this is a comment]");
MT('multiline_comment',
"[comment /*foobar*/]");
MT('attribute_with_hyphen',
"[tag foo] { [property font-size]:[number 10px] }");
MT('string_after_attribute',
"[tag foo] { [property content]:[string \"::\"] }");
MT('directives',
"[def @include] [qualifier .mixin]");
MT('basic_structure',
"[tag p] { [property background]:[keyword red]; }");
MT('nested_structure',
"[tag p] { [tag a] { [property color]:[keyword red]; } }");
MT('mixin',
"[def @mixin] [tag table-base] {}");
MT('number_without_semicolon',
"[tag p] {[property width]:[number 12]}",
"[tag a] {[property color]:[keyword red];}");
MT('atom_in_nested_block',
"[tag p] { [tag a] { [property color]:[atom #000]; } }");
MT('interpolation_in_property',
"[tag foo] { #{[variable-2 $hello]}:[number 2]; }");
MT('interpolation_in_selector',
"[tag foo]#{[variable-2 $hello]} { [property color]:[atom #000]; }");
MT('interpolation_error',
"[tag foo]#{[variable foo]} { [property color]:[atom #000]; }");
MT("divide_operator",
"[tag foo] { [property width]:[number 4] [operator /] [number 2] }");
MT('nested_structure_with_id_selector',
"[tag p] { [builtin #hello] { [property color]:[keyword red]; } }");
MT('indent_mixin',
"[def @mixin] [tag container] (",
" [variable-2 $a]: [number 10],",
" [variable-2 $b]: [number 10])",
"{}");
MT('indent_nested',
"[tag foo] {",
" [tag bar] {",
" }",
"}");
MT('indent_parentheses',
"[tag foo] {",
" [property color]: [atom darken]([variable-2 $blue],",
" [number 9%]);",
"}");
MT('indent_vardef',
"[variable-2 $name]:",
" [string 'val'];",
"[tag tag] {",
" [tag inner] {",
" [property margin]: [number 3px];",
" }",
"}");
})();

View File

@ -1,200 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function() {
var mode = CodeMirror.getMode({indentUnit: 2}, "css");
function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }
// Error, because "foobarhello" is neither a known type or property, but
// property was expected (after "and"), and it should be in parentheses.
MT("atMediaUnknownType",
"[def @media] [attribute screen] [keyword and] [error foobarhello] { }");
// Soft error, because "foobarhello" is not a known property or type.
MT("atMediaUnknownProperty",
"[def @media] [attribute screen] [keyword and] ([error foobarhello]) { }");
// Make sure nesting works with media queries
MT("atMediaMaxWidthNested",
"[def @media] [attribute screen] [keyword and] ([property max-width]: [number 25px]) { [tag foo] { } }");
MT("atMediaFeatureValueKeyword",
"[def @media] ([property orientation]: [keyword landscape]) { }");
MT("atMediaUnknownFeatureValueKeyword",
"[def @media] ([property orientation]: [error upsidedown]) { }");
MT("tagSelector",
"[tag foo] { }");
MT("classSelector",
"[qualifier .foo-bar_hello] { }");
MT("idSelector",
"[builtin #foo] { [error #foo] }");
MT("tagSelectorUnclosed",
"[tag foo] { [property margin]: [number 0] } [tag bar] { }");
MT("tagStringNoQuotes",
"[tag foo] { [property font-family]: [variable hello] [variable world]; }");
MT("tagStringDouble",
"[tag foo] { [property font-family]: [string \"hello world\"]; }");
MT("tagStringSingle",
"[tag foo] { [property font-family]: [string 'hello world']; }");
MT("tagColorKeyword",
"[tag foo] {",
" [property color]: [keyword black];",
" [property color]: [keyword navy];",
" [property color]: [keyword yellow];",
"}");
MT("tagColorHex3",
"[tag foo] { [property background]: [atom #fff]; }");
MT("tagColorHex4",
"[tag foo] { [property background]: [atom #ffff]; }");
MT("tagColorHex6",
"[tag foo] { [property background]: [atom #ffffff]; }");
MT("tagColorHex8",
"[tag foo] { [property background]: [atom #ffffffff]; }");
MT("tagColorHex5Invalid",
"[tag foo] { [property background]: [atom&error #fffff]; }");
MT("tagColorHexInvalid",
"[tag foo] { [property background]: [atom&error #ffg]; }");
MT("tagNegativeNumber",
"[tag foo] { [property margin]: [number -5px]; }");
MT("tagPositiveNumber",
"[tag foo] { [property padding]: [number 5px]; }");
MT("tagVendor",
"[tag foo] { [meta -foo-][property box-sizing]: [meta -foo-][atom border-box]; }");
MT("tagBogusProperty",
"[tag foo] { [property&error barhelloworld]: [number 0]; }");
MT("tagTwoProperties",
"[tag foo] { [property margin]: [number 0]; [property padding]: [number 0]; }");
MT("tagTwoPropertiesURL",
"[tag foo] { [property background]: [atom url]([string //example.com/foo.png]); [property padding]: [number 0]; }");
MT("indent_tagSelector",
"[tag strong], [tag em] {",
" [property background]: [atom rgba](",
" [number 255], [number 255], [number 0], [number .2]",
" );",
"}");
MT("indent_atMedia",
"[def @media] {",
" [tag foo] {",
" [property color]:",
" [keyword yellow];",
" }",
"}");
MT("indent_comma",
"[tag foo] {",
" [property font-family]: [variable verdana],",
" [atom sans-serif];",
"}");
MT("indent_parentheses",
"[tag foo]:[variable-3 before] {",
" [property background]: [atom url](",
"[string blahblah]",
"[string etc]",
"[string ]) [keyword !important];",
"}");
MT("font_face",
"[def @font-face] {",
" [property font-family]: [string 'myfont'];",
" [error nonsense]: [string 'abc'];",
" [property src]: [atom url]([string http://blah]),",
" [atom url]([string http://foo]);",
"}");
MT("empty_url",
"[def @import] [atom url]() [attribute screen];");
MT("parens",
"[qualifier .foo] {",
" [property background-image]: [variable fade]([atom #000], [number 20%]);",
" [property border-image]: [atom linear-gradient](",
" [atom to] [atom bottom],",
" [variable fade]([atom #000], [number 20%]) [number 0%],",
" [variable fade]([atom #000], [number 20%]) [number 100%]",
" );",
"}");
MT("css_variable",
":[variable-3 root] {",
" [variable-2 --main-color]: [atom #06c];",
"}",
"[tag h1][builtin #foo] {",
" [property color]: [atom var]([variable-2 --main-color]);",
"}");
MT("supports",
"[def @supports] ([keyword not] (([property text-align-last]: [atom justify]) [keyword or] ([meta -moz-][property text-align-last]: [atom justify])) {",
" [property text-align-last]: [atom justify];",
"}");
MT("document",
"[def @document] [tag url]([string http://blah]),",
" [tag url-prefix]([string https://]),",
" [tag domain]([string blah.com]),",
" [tag regexp]([string \".*blah.+\"]) {",
" [builtin #id] {",
" [property background-color]: [keyword white];",
" }",
" [tag foo] {",
" [property font-family]: [variable Verdana], [atom sans-serif];",
" }",
"}");
MT("document_url",
"[def @document] [tag url]([string http://blah]) { [qualifier .class] { } }");
MT("document_urlPrefix",
"[def @document] [tag url-prefix]([string https://]) { [builtin #id] { } }");
MT("document_domain",
"[def @document] [tag domain]([string blah.com]) { [tag foo] { } }");
MT("document_regexp",
"[def @document] [tag regexp]([string \".*blah.+\"]) { [builtin #id] { } }");
MT("counter-style",
"[def @counter-style] [variable binary] {",
" [property system]: [atom numeric];",
" [property symbols]: [number 0] [number 1];",
" [property suffix]: [string \".\"];",
" [property range]: [atom infinite];",
" [property speak-as]: [atom numeric];",
"}");
MT("counter-style-additive-symbols",
"[def @counter-style] [variable simple-roman] {",
" [property system]: [atom additive];",
" [property additive-symbols]: [number 10] [variable X], [number 5] [variable V], [number 1] [variable I];",
" [property range]: [number 1] [number 49];",
"}");
MT("counter-style-use",
"[tag ol][qualifier .roman] { [property list-style]: [variable simple-roman]; }");
MT("counter-style-symbols",
"[tag ol] { [property list-style]: [atom symbols]([atom cyclic] [string \"*\"] [string \"\\2020\"] [string \"\\2021\"] [string \"\\A7\"]); }");
})();

View File

@ -1,79 +0,0 @@
<!doctype html>
<title>CodeMirror: HAML mode</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../../doc/docs.css">
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="../xml/xml.js"></script>
<script src="../htmlmixed/htmlmixed.js"></script>
<script src="../javascript/javascript.js"></script>
<script src="../ruby/ruby.js"></script>
<script src="haml.js"></script>
<style>.CodeMirror {background: #f8f8f8;}</style>
<div id=nav>
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<ul>
<li><a href="../../index.html">Home</a>
<li><a href="../../doc/manual.html">Manual</a>
<li><a href="https://github.com/codemirror/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="#">HAML</a>
</ul>
</div>
<article>
<h2>HAML mode</h2>
<form><textarea id="code" name="code">
!!!
#content
.left.column(title="title"){:href => "/hello", :test => "#{hello}_#{world}"}
<!-- This is a comment -->
%h2 Welcome to our site!
%p= puts "HAML MODE"
.right.column
= render :partial => "sidebar"
.container
.row
.span8
%h1.title= @page_title
%p.title= @page_title
%p
/
The same as HTML comment
Hello multiline comment
-# haml comment
This wont be displayed
nor will this
Date/Time:
- now = DateTime.now
%strong= now
- if now > DateTime.parse("December 31, 2006")
= "Happy new " + "year!"
%title
= @title
\= @title
<h1>Title</h1>
<h1 title="HELLO">
Title
</h1>
</textarea></form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
mode: "text/x-haml"
});
</script>
<p><strong>MIME types defined:</strong> <code>text/x-haml</code>.</p>
<p><strong>Parsing/Highlighting Tests:</strong> <a href="../../test/index.html#haml_*">normal</a>, <a href="../../test/index.html#verbose,haml_*">verbose</a>.</p>
</article>

View File

@ -1,97 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function() {
var mode = CodeMirror.getMode({tabSize: 4, indentUnit: 2}, "haml");
function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }
// Requires at least one media query
MT("elementName",
"[tag %h1] Hey There");
MT("oneElementPerLine",
"[tag %h1] Hey There %h2");
MT("idSelector",
"[tag %h1][attribute #test] Hey There");
MT("classSelector",
"[tag %h1][attribute .hello] Hey There");
MT("docType",
"[tag !!! XML]");
MT("comment",
"[comment / Hello WORLD]");
MT("notComment",
"[tag %h1] This is not a / comment ");
MT("attributes",
"[tag %a]([variable title][operator =][string \"test\"]){[atom :title] [operator =>] [string \"test\"]}");
MT("htmlCode",
"[tag&bracket <][tag h1][tag&bracket >]Title[tag&bracket </][tag h1][tag&bracket >]");
MT("rubyBlock",
"[operator =][variable-2 @item]");
MT("selectorRubyBlock",
"[tag %a.selector=] [variable-2 @item]");
MT("nestedRubyBlock",
"[tag %a]",
" [operator =][variable puts] [string \"test\"]");
MT("multilinePlaintext",
"[tag %p]",
" Hello,",
" World");
MT("multilineRuby",
"[tag %p]",
" [comment -# this is a comment]",
" [comment and this is a comment too]",
" Date/Time",
" [operator -] [variable now] [operator =] [tag DateTime][operator .][property now]",
" [tag %strong=] [variable now]",
" [operator -] [keyword if] [variable now] [operator >] [tag DateTime][operator .][property parse]([string \"December 31, 2006\"])",
" [operator =][string \"Happy\"]",
" [operator =][string \"Belated\"]",
" [operator =][string \"Birthday\"]");
MT("multilineComment",
"[comment /]",
" [comment Multiline]",
" [comment Comment]");
MT("hamlComment",
"[comment -# this is a comment]");
MT("multilineHamlComment",
"[comment -# this is a comment]",
" [comment and this is a comment too]");
MT("multilineHTMLComment",
"[comment <!--]",
" [comment what a comment]",
" [comment -->]");
MT("hamlAfterRubyTag",
"[attribute .block]",
" [tag %strong=] [variable now]",
" [attribute .test]",
" [operator =][variable now]",
" [attribute .right]");
MT("stretchedRuby",
"[operator =] [variable puts] [string \"Hello\"],",
" [string \"World\"]");
MT("interpolationInHashAttribute",
//"[tag %div]{[atom :id] [operator =>] [string \"#{][variable test][string }_#{][variable ting][string }\"]} test");
"[tag %div]{[atom :id] [operator =>] [string \"#{][variable test][string }_#{][variable ting][string }\"]} test");
MT("interpolationInHTMLAttribute",
"[tag %div]([variable title][operator =][string \"#{][variable test][string }_#{][variable ting]()[string }\"]) Test");
})();

View File

@ -1,59 +0,0 @@
<!doctype html>
<title>CodeMirror: Html Embedded Scripts mode</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../../doc/docs.css">
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="../xml/xml.js"></script>
<script src="../javascript/javascript.js"></script>
<script src="../css/css.js"></script>
<script src="../htmlmixed/htmlmixed.js"></script>
<script src="../../addon/mode/multiplex.js"></script>
<script src="htmlembedded.js"></script>
<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
<div id=nav>
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<ul>
<li><a href="../../index.html">Home</a>
<li><a href="../../doc/manual.html">Manual</a>
<li><a href="https://github.com/codemirror/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="#">Html Embedded Scripts</a>
</ul>
</div>
<article>
<h2>Html Embedded Scripts mode</h2>
<form><textarea id="code" name="code">
<%
function hello(who) {
return "Hello " + who;
}
%>
This is an example of EJS (embedded javascript)
<p>The program says <%= hello("world") %>.</p>
<script>
alert("And here is some normal JS code"); // also colored
</script>
</textarea></form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
mode: "application/x-ejs",
indentUnit: 4,
indentWithTabs: true
});
</script>
<p>Mode for html embedded scripts like JSP and ASP.NET. Depends on HtmlMixed which in turn depends on
JavaScript, CSS and XML.<br />Other dependencies include those of the scripting language chosen.</p>
<p><strong>MIME types defined:</strong> <code>application/x-aspx</code> (ASP.NET),
<code>application/x-ejs</code> (Embedded Javascript), <code>application/x-jsp</code> (JavaServer Pages)</p>
</article>

View File

@ -1,89 +0,0 @@
<!doctype html>
<title>CodeMirror: HTML mixed mode</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../../doc/docs.css">
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="../../addon/selection/selection-pointer.js"></script>
<script src="../xml/xml.js"></script>
<script src="../javascript/javascript.js"></script>
<script src="../css/css.js"></script>
<script src="../vbscript/vbscript.js"></script>
<script src="htmlmixed.js"></script>
<style>.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
<div id=nav>
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<ul>
<li><a href="../../index.html">Home</a>
<li><a href="../../doc/manual.html">Manual</a>
<li><a href="https://github.com/codemirror/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="#">HTML mixed</a>
</ul>
</div>
<article>
<h2>HTML mixed mode</h2>
<form><textarea id="code" name="code">
<html style="color: green">
<!-- this is a comment -->
<head>
<title>Mixed HTML Example</title>
<style type="text/css">
h1 {font-family: comic sans; color: #f0f;}
div {background: yellow !important;}
body {
max-width: 50em;
margin: 1em 2em 1em 5em;
}
</style>
</head>
<body>
<h1>Mixed HTML Example</h1>
<script>
function jsFunc(arg1, arg2) {
if (arg1 && arg2) document.body.innerHTML = "achoo";
}
</script>
</body>
</html>
</textarea></form>
<script>
// Define an extended mixed-mode that understands vbscript and
// leaves mustache/handlebars embedded templates in html mode
var mixedMode = {
name: "htmlmixed",
scriptTypes: [{matches: /\/x-handlebars-template|\/x-mustache/i,
mode: null},
{matches: /(text|application)\/(x-)?vb(a|script)/i,
mode: "vbscript"}]
};
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
mode: mixedMode,
selectionPointer: true
});
</script>
<p>The HTML mixed mode depends on the XML, JavaScript, and CSS modes.</p>
<p>It takes an optional mode configuration
option, <code>scriptTypes</code>, which can be used to add custom
behavior for specific <code>&lt;script type="..."></code> tags. If
given, it should hold an array of <code>{matches, mode}</code>
objects, where <code>matches</code> is a string or regexp that
matches the script type, and <code>mode</code> is
either <code>null</code>, for script types that should stay in
HTML mode, or a <a href="../../doc/manual.html#option_mode">mode
spec</a> corresponding to the mode that should be used for the
script.</p>
<p><strong>MIME types defined:</strong> <code>text/html</code>
(redefined, only takes effect if you load this parser after the
XML parser).</p>
</article>

View File

@ -1,70 +0,0 @@
<!doctype html>
<title>CodeMirror: Jade Templating Mode</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../../doc/docs.css">
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="../javascript/javascript.js"></script>
<script src="../css/css.js"></script>
<script src="../xml/xml.js"></script>
<script src="../htmlmixed/htmlmixed.js"></script>
<script src="jade.js"></script>
<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
<div id=nav>
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<ul>
<li><a href="../../index.html">Home</a>
<li><a href="../../doc/manual.html">Manual</a>
<li><a href="https://github.com/codemirror/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="#">Jade Templating Mode</a>
</ul>
</div>
<article>
<h2>Jade Templating Mode</h2>
<form><textarea id="code" name="code">
doctype html
html
head
title= "Jade Templating CodeMirror Mode Example"
link(rel='stylesheet', href='/css/bootstrap.min.css')
link(rel='stylesheet', href='/css/index.css')
script(type='text/javascript', src='/js/jquery-1.9.1.min.js')
script(type='text/javascript', src='/js/bootstrap.min.js')
body
div.header
h1 Welcome to this Example
div.spots
if locals.spots
each spot in spots
div.spot.well
div
if spot.logo
img.img-rounded.logo(src=spot.logo)
else
img.img-rounded.logo(src="img/placeholder.png")
h3
a(href=spot.hash) ##{spot.hash}
if spot.title
span.title #{spot.title}
if spot.desc
div #{spot.desc}
else
h3 There are no spots currently available.
</textarea></form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
mode: {name: "jade", alignCDATA: true},
lineNumbers: true
});
</script>
<h3>The Jade Templating Mode</h3>
<p> Created by Forbes Lindesay. Managed as part of a Brackets extension at <a href="https://github.com/ForbesLindesay/jade-brackets">https://github.com/ForbesLindesay/jade-brackets</a>.</p>
<p><strong>MIME type defined:</strong> <code>text/x-jade</code>.</p>
</article>

View File

@ -1,114 +0,0 @@
<!doctype html>
<title>CodeMirror: JavaScript mode</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../../doc/docs.css">
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="../../addon/edit/matchbrackets.js"></script>
<script src="../../addon/comment/continuecomment.js"></script>
<script src="../../addon/comment/comment.js"></script>
<script src="javascript.js"></script>
<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
<div id=nav>
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<ul>
<li><a href="../../index.html">Home</a>
<li><a href="../../doc/manual.html">Manual</a>
<li><a href="https://github.com/codemirror/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="#">JavaScript</a>
</ul>
</div>
<article>
<h2>JavaScript mode</h2>
<div><textarea id="code" name="code">
// Demo code (the actual new parser character stream implementation)
function StringStream(string) {
this.pos = 0;
this.string = string;
}
StringStream.prototype = {
done: function() {return this.pos >= this.string.length;},
peek: function() {return this.string.charAt(this.pos);},
next: function() {
if (this.pos &lt; this.string.length)
return this.string.charAt(this.pos++);
},
eat: function(match) {
var ch = this.string.charAt(this.pos);
if (typeof match == "string") var ok = ch == match;
else var ok = ch &amp;&amp; match.test ? match.test(ch) : match(ch);
if (ok) {this.pos++; return ch;}
},
eatWhile: function(match) {
var start = this.pos;
while (this.eat(match));
if (this.pos > start) return this.string.slice(start, this.pos);
},
backUp: function(n) {this.pos -= n;},
column: function() {return this.pos;},
eatSpace: function() {
var start = this.pos;
while (/\s/.test(this.string.charAt(this.pos))) this.pos++;
return this.pos - start;
},
match: function(pattern, consume, caseInsensitive) {
if (typeof pattern == "string") {
function cased(str) {return caseInsensitive ? str.toLowerCase() : str;}
if (cased(this.string).indexOf(cased(pattern), this.pos) == this.pos) {
if (consume !== false) this.pos += str.length;
return true;
}
}
else {
var match = this.string.slice(this.pos).match(pattern);
if (match &amp;&amp; consume !== false) this.pos += match[0].length;
return match;
}
}
};
</textarea></div>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
matchBrackets: true,
continueComments: "Enter",
extraKeys: {"Ctrl-Q": "toggleComment"}
});
</script>
<p>
JavaScript mode supports several configuration options:
<ul>
<li><code>json</code> which will set the mode to expect JSON
data rather than a JavaScript program.</li>
<li><code>jsonld</code> which will set the mode to expect
<a href="http://json-ld.org">JSON-LD</a> linked data rather
than a JavaScript program (<a href="json-ld.html">demo</a>).</li>
<li><code>typescript</code> which will activate additional
syntax highlighting and some other things for TypeScript code
(<a href="typescript.html">demo</a>).</li>
<li><code>statementIndent</code> which (given a number) will
determine the amount of indentation to use for statements
continued on a new line.</li>
<li><code>wordCharacters</code>, a regexp that indicates which
characters should be considered part of an identifier.
Defaults to <code>/[\w$]/</code>, which does not handle
non-ASCII identifiers. Can be set to something more elaborate
to improve Unicode support.</li>
</ul>
</p>
<p><strong>MIME types defined:</strong> <code>text/javascript</code>, <code>application/json</code>, <code>application/ld+json</code>, <code>text/typescript</code>, <code>application/typescript</code>.</p>
</article>

View File

@ -1,210 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function() {
var mode = CodeMirror.getMode({indentUnit: 2}, "javascript");
function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }
MT("locals",
"[keyword function] [def foo]([def a], [def b]) { [keyword var] [def c] [operator =] [number 10]; [keyword return] [variable-2 a] [operator +] [variable-2 c] [operator +] [variable d]; }");
MT("comma-and-binop",
"[keyword function](){ [keyword var] [def x] [operator =] [number 1] [operator +] [number 2], [def y]; }");
MT("destructuring",
"([keyword function]([def a], [[[def b], [def c] ]]) {",
" [keyword let] {[def d], [property foo]: [def c][operator =][number 10], [def x]} [operator =] [variable foo]([variable-2 a]);",
" [[[variable-2 c], [variable y] ]] [operator =] [variable-2 c];",
"})();");
MT("destructure_trailing_comma",
"[keyword let] {[def a], [def b],} [operator =] [variable foo];",
"[keyword let] [def c];"); // Parser still in good state?
MT("class_body",
"[keyword class] [def Foo] {",
" [property constructor]() {}",
" [property sayName]() {",
" [keyword return] [string-2 `foo${][variable foo][string-2 }oo`];",
" }",
"}");
MT("class",
"[keyword class] [def Point] [keyword extends] [variable SuperThing] {",
" [property get] [property prop]() { [keyword return] [number 24]; }",
" [property constructor]([def x], [def y]) {",
" [keyword super]([string 'something']);",
" [keyword this].[property x] [operator =] [variable-2 x];",
" }",
"}");
MT("import",
"[keyword function] [def foo]() {",
" [keyword import] [def $] [keyword from] [string 'jquery'];",
" [keyword import] { [def encrypt], [def decrypt] } [keyword from] [string 'crypto'];",
"}");
MT("const",
"[keyword function] [def f]() {",
" [keyword const] [[ [def a], [def b] ]] [operator =] [[ [number 1], [number 2] ]];",
"}");
MT("for/of",
"[keyword for]([keyword let] [def of] [keyword of] [variable something]) {}");
MT("generator",
"[keyword function*] [def repeat]([def n]) {",
" [keyword for]([keyword var] [def i] [operator =] [number 0]; [variable-2 i] [operator <] [variable-2 n]; [operator ++][variable-2 i])",
" [keyword yield] [variable-2 i];",
"}");
MT("quotedStringAddition",
"[keyword let] [def f] [operator =] [variable a] [operator +] [string 'fatarrow'] [operator +] [variable c];");
MT("quotedFatArrow",
"[keyword let] [def f] [operator =] [variable a] [operator +] [string '=>'] [operator +] [variable c];");
MT("fatArrow",
"[variable array].[property filter]([def a] [operator =>] [variable-2 a] [operator +] [number 1]);",
"[variable a];", // No longer in scope
"[keyword let] [def f] [operator =] ([[ [def a], [def b] ]], [def c]) [operator =>] [variable-2 a] [operator +] [variable-2 c];",
"[variable c];");
MT("spread",
"[keyword function] [def f]([def a], [meta ...][def b]) {",
" [variable something]([variable-2 a], [meta ...][variable-2 b]);",
"}");
MT("comprehension",
"[keyword function] [def f]() {",
" [[([variable x] [operator +] [number 1]) [keyword for] ([keyword var] [def x] [keyword in] [variable y]) [keyword if] [variable pred]([variable-2 x]) ]];",
" ([variable u] [keyword for] ([keyword var] [def u] [keyword of] [variable generateValues]()) [keyword if] ([variable-2 u].[property color] [operator ===] [string 'blue']));",
"}");
MT("quasi",
"[variable re][string-2 `fofdlakj${][variable x] [operator +] ([variable re][string-2 `foo`]) [operator +] [number 1][string-2 }fdsa`] [operator +] [number 2]");
MT("quasi_no_function",
"[variable x] [operator =] [string-2 `fofdlakj${][variable x] [operator +] [string-2 `foo`] [operator +] [number 1][string-2 }fdsa`] [operator +] [number 2]");
MT("indent_statement",
"[keyword var] [def x] [operator =] [number 10]",
"[variable x] [operator +=] [variable y] [operator +]",
" [atom Infinity]",
"[keyword debugger];");
MT("indent_if",
"[keyword if] ([number 1])",
" [keyword break];",
"[keyword else] [keyword if] ([number 2])",
" [keyword continue];",
"[keyword else]",
" [number 10];",
"[keyword if] ([number 1]) {",
" [keyword break];",
"} [keyword else] [keyword if] ([number 2]) {",
" [keyword continue];",
"} [keyword else] {",
" [number 10];",
"}");
MT("indent_for",
"[keyword for] ([keyword var] [def i] [operator =] [number 0];",
" [variable i] [operator <] [number 100];",
" [variable i][operator ++])",
" [variable doSomething]([variable i]);",
"[keyword debugger];");
MT("indent_c_style",
"[keyword function] [def foo]()",
"{",
" [keyword debugger];",
"}");
MT("indent_else",
"[keyword for] (;;)",
" [keyword if] ([variable foo])",
" [keyword if] ([variable bar])",
" [number 1];",
" [keyword else]",
" [number 2];",
" [keyword else]",
" [number 3];");
MT("indent_funarg",
"[variable foo]([number 10000],",
" [keyword function]([def a]) {",
" [keyword debugger];",
"};");
MT("indent_below_if",
"[keyword for] (;;)",
" [keyword if] ([variable foo])",
" [number 1];",
"[number 2];");
MT("multilinestring",
"[keyword var] [def x] [operator =] [string 'foo\\]",
"[string bar'];");
MT("scary_regexp",
"[string-2 /foo[[/]]bar/];");
MT("indent_strange_array",
"[keyword var] [def x] [operator =] [[",
" [number 1],,",
" [number 2],",
"]];",
"[number 10];");
MT("param_default",
"[keyword function] [def foo]([def x] [operator =] [string-2 `foo${][number 10][string-2 }bar`]) {",
" [keyword return] [variable-2 x];",
"}");
MT("new_target",
"[keyword function] [def F]([def target]) {",
" [keyword if] ([variable-2 target] [operator &&] [keyword new].[keyword target].[property name]) {",
" [keyword return] [keyword new]",
" .[keyword target];",
" }",
"}");
var jsonld_mode = CodeMirror.getMode(
{indentUnit: 2},
{name: "javascript", jsonld: true}
);
function LD(name) {
test.mode(name, jsonld_mode, Array.prototype.slice.call(arguments, 1));
}
LD("json_ld_keywords",
'{',
' [meta "@context"]: {',
' [meta "@base"]: [string "http://example.com"],',
' [meta "@vocab"]: [string "http://xmlns.com/foaf/0.1/"],',
' [property "likesFlavor"]: {',
' [meta "@container"]: [meta "@list"]',
' [meta "@reverse"]: [string "@beFavoriteOf"]',
' },',
' [property "nick"]: { [meta "@container"]: [meta "@set"] },',
' [property "nick"]: { [meta "@container"]: [meta "@index"] }',
' },',
' [meta "@graph"]: [[ {',
' [meta "@id"]: [string "http://dbpedia.org/resource/John_Lennon"],',
' [property "name"]: [string "John Lennon"],',
' [property "modified"]: {',
' [meta "@value"]: [string "2010-05-29T14:17:39+02:00"],',
' [meta "@type"]: [string "http://www.w3.org/2001/XMLSchema#dateTime"]',
' }',
' } ]]',
'}');
LD("json_ld_fake",
'{',
' [property "@fake"]: [string "@fake"],',
' [property "@contextual"]: [string "@identifier"],',
' [property "user@domain.com"]: [string "@graphical"],',
' [property "@ID"]: [string "@@ID"]',
'}');
})();

View File

@ -0,0 +1,797 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("../xml/xml"), require("../meta"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "../xml/xml", "../meta"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
var htmlMode = CodeMirror.getMode(cmCfg, "text/html");
var htmlModeMissing = htmlMode.name == "null"
function getMode(name) {
if (CodeMirror.findModeByName) {
var found = CodeMirror.findModeByName(name);
if (found) name = found.mime || found.mimes[0];
}
var mode = CodeMirror.getMode(cmCfg, name);
return mode.name == "null" ? null : mode;
}
// Should characters that affect highlighting be highlighted separate?
// Does not include characters that will be output (such as `1.` and `-` for lists)
if (modeCfg.highlightFormatting === undefined)
modeCfg.highlightFormatting = false;
// Maximum number of nested blockquotes. Set to 0 for infinite nesting.
// Excess `>` will emit `error` token.
if (modeCfg.maxBlockquoteDepth === undefined)
modeCfg.maxBlockquoteDepth = 0;
// Should underscores in words open/close em/strong?
if (modeCfg.underscoresBreakWords === undefined)
modeCfg.underscoresBreakWords = true;
// Use `fencedCodeBlocks` to configure fenced code blocks. false to
// disable, string to specify a precise regexp that the fence should
// match, and true to allow three or more backticks or tildes (as
// per CommonMark).
// Turn on task lists? ("- [ ] " and "- [x] ")
if (modeCfg.taskLists === undefined) modeCfg.taskLists = false;
// Turn on strikethrough syntax
if (modeCfg.strikethrough === undefined)
modeCfg.strikethrough = false;
// Allow token types to be overridden by user-provided token types.
if (modeCfg.tokenTypeOverrides === undefined)
modeCfg.tokenTypeOverrides = {};
var tokenTypes = {
header: "header",
code: "comment",
quote: "quote",
list1: "variable-2",
list2: "variable-3",
list3: "keyword",
hr: "hr",
image: "tag",
formatting: "formatting",
linkInline: "link",
linkEmail: "link",
linkText: "link",
linkHref: "string",
em: "em",
strong: "strong",
strikethrough: "strikethrough"
};
for (var tokenType in tokenTypes) {
if (tokenTypes.hasOwnProperty(tokenType) && modeCfg.tokenTypeOverrides[tokenType]) {
tokenTypes[tokenType] = modeCfg.tokenTypeOverrides[tokenType];
}
}
var hrRE = /^([*\-_])(?:\s*\1){2,}\s*$/
, ulRE = /^[*\-+]\s+/
, olRE = /^[0-9]+([.)])\s+/
, taskListRE = /^\[(x| )\](?=\s)/ // Must follow ulRE or olRE
, atxHeaderRE = modeCfg.allowAtxHeaderWithoutSpace ? /^(#+)/ : /^(#+)(?: |$)/
, setextHeaderRE = /^ *(?:\={1,}|-{1,})\s*$/
, textRE = /^[^#!\[\]*_\\<>` "'(~]+/
, fencedCodeRE = new RegExp("^(" + (modeCfg.fencedCodeBlocks === true ? "~~~+|```+" : modeCfg.fencedCodeBlocks) +
")[ \\t]*([\\w+#\-]*)");
function switchInline(stream, state, f) {
state.f = state.inline = f;
return f(stream, state);
}
function switchBlock(stream, state, f) {
state.f = state.block = f;
return f(stream, state);
}
function lineIsEmpty(line) {
return !line || !/\S/.test(line.string)
}
// Blocks
function blankLine(state) {
// Reset linkTitle state
state.linkTitle = false;
// Reset EM state
state.em = false;
// Reset STRONG state
state.strong = false;
// Reset strikethrough state
state.strikethrough = false;
// Reset state.quote
state.quote = 0;
// Reset state.indentedCode
state.indentedCode = false;
if (htmlModeMissing && state.f == htmlBlock) {
state.f = inlineNormal;
state.block = blockNormal;
}
// Reset state.trailingSpace
state.trailingSpace = 0;
state.trailingSpaceNewLine = false;
// Mark this line as blank
state.prevLine = state.thisLine
state.thisLine = null
return null;
}
function blockNormal(stream, state) {
var sol = stream.sol();
var prevLineIsList = state.list !== false,
prevLineIsIndentedCode = state.indentedCode;
state.indentedCode = false;
if (prevLineIsList) {
if (state.indentationDiff >= 0) { // Continued list
if (state.indentationDiff < 4) { // Only adjust indentation if *not* a code block
state.indentation -= state.indentationDiff;
}
state.list = null;
} else if (state.indentation > 0) {
state.list = null;
} else { // No longer a list
state.list = false;
}
}
var match = null;
if (state.indentationDiff >= 4) {
stream.skipToEnd();
if (prevLineIsIndentedCode || lineIsEmpty(state.prevLine)) {
state.indentation -= 4;
state.indentedCode = true;
return tokenTypes.code;
} else {
return null;
}
} else if (stream.eatSpace()) {
return null;
} else if ((match = stream.match(atxHeaderRE)) && match[1].length <= 6) {
state.header = match[1].length;
if (modeCfg.highlightFormatting) state.formatting = "header";
state.f = state.inline;
return getType(state);
} else if (!lineIsEmpty(state.prevLine) && !state.quote && !prevLineIsList &&
!prevLineIsIndentedCode && (match = stream.match(setextHeaderRE))) {
state.header = match[0].charAt(0) == '=' ? 1 : 2;
if (modeCfg.highlightFormatting) state.formatting = "header";
state.f = state.inline;
return getType(state);
} else if (stream.eat('>')) {
state.quote = sol ? 1 : state.quote + 1;
if (modeCfg.highlightFormatting) state.formatting = "quote";
stream.eatSpace();
return getType(state);
} else if (stream.peek() === '[') {
return switchInline(stream, state, footnoteLink);
} else if (stream.match(hrRE, true)) {
state.hr = true;
return tokenTypes.hr;
} else if ((lineIsEmpty(state.prevLine) || prevLineIsList) && (stream.match(ulRE, false) || stream.match(olRE, false))) {
var listType = null;
if (stream.match(ulRE, true)) {
listType = 'ul';
} else {
stream.match(olRE, true);
listType = 'ol';
}
state.indentation = stream.column() + stream.current().length;
state.list = true;
// While this list item's marker's indentation
// is less than the deepest list item's content's indentation,
// pop the deepest list item indentation off the stack.
while (state.listStack && stream.column() < state.listStack[state.listStack.length - 1]) {
state.listStack.pop();
}
// Add this list item's content's indentation to the stack
state.listStack.push(state.indentation);
if (modeCfg.taskLists && stream.match(taskListRE, false)) {
state.taskList = true;
}
state.f = state.inline;
if (modeCfg.highlightFormatting) state.formatting = ["list", "list-" + listType];
return getType(state);
} else if (modeCfg.fencedCodeBlocks && (match = stream.match(fencedCodeRE, true))) {
state.fencedChars = match[1]
// try switching mode
state.localMode = getMode(match[2]);
if (state.localMode) state.localState = CodeMirror.startState(state.localMode);
state.f = state.block = local;
if (modeCfg.highlightFormatting) state.formatting = "code-block";
state.code = -1
return getType(state);
}
return switchInline(stream, state, state.inline);
}
function htmlBlock(stream, state) {
var style = htmlMode.token(stream, state.htmlState);
if (!htmlModeMissing) {
var inner = CodeMirror.innerMode(htmlMode, state.htmlState)
if ((inner.mode.name == "xml" && inner.state.tagStart === null &&
(!inner.state.context && inner.state.tokenize.isInText)) ||
(state.md_inside && stream.current().indexOf(">") > -1)) {
state.f = inlineNormal;
state.block = blockNormal;
state.htmlState = null;
}
}
return style;
}
function local(stream, state) {
if (state.fencedChars && stream.match(state.fencedChars, false)) {
state.localMode = state.localState = null;
state.f = state.block = leavingLocal;
return null;
} else if (state.localMode) {
return state.localMode.token(stream, state.localState);
} else {
stream.skipToEnd();
return tokenTypes.code;
}
}
function leavingLocal(stream, state) {
stream.match(state.fencedChars);
state.block = blockNormal;
state.f = inlineNormal;
state.fencedChars = null;
if (modeCfg.highlightFormatting) state.formatting = "code-block";
state.code = 1
var returnType = getType(state);
state.code = 0
return returnType;
}
// Inline
function getType(state) {
var styles = [];
if (state.formatting) {
styles.push(tokenTypes.formatting);
if (typeof state.formatting === "string") state.formatting = [state.formatting];
for (var i = 0; i < state.formatting.length; i++) {
styles.push(tokenTypes.formatting + "-" + state.formatting[i]);
if (state.formatting[i] === "header") {
styles.push(tokenTypes.formatting + "-" + state.formatting[i] + "-" + state.header);
}
// Add `formatting-quote` and `formatting-quote-#` for blockquotes
// Add `error` instead if the maximum blockquote nesting depth is passed
if (state.formatting[i] === "quote") {
if (!modeCfg.maxBlockquoteDepth || modeCfg.maxBlockquoteDepth >= state.quote) {
styles.push(tokenTypes.formatting + "-" + state.formatting[i] + "-" + state.quote);
} else {
styles.push("error");
}
}
}
}
if (state.taskOpen) {
styles.push("meta");
return styles.length ? styles.join(' ') : null;
}
if (state.taskClosed) {
styles.push("property");
return styles.length ? styles.join(' ') : null;
}
if (state.linkHref) {
styles.push(tokenTypes.linkHref, "url");
} else { // Only apply inline styles to non-url text
if (state.strong) { styles.push(tokenTypes.strong); }
if (state.em) { styles.push(tokenTypes.em); }
if (state.strikethrough) { styles.push(tokenTypes.strikethrough); }
if (state.linkText) { styles.push(tokenTypes.linkText); }
if (state.code) { styles.push(tokenTypes.code); }
}
if (state.header) { styles.push(tokenTypes.header, tokenTypes.header + "-" + state.header); }
if (state.quote) {
styles.push(tokenTypes.quote);
// Add `quote-#` where the maximum for `#` is modeCfg.maxBlockquoteDepth
if (!modeCfg.maxBlockquoteDepth || modeCfg.maxBlockquoteDepth >= state.quote) {
styles.push(tokenTypes.quote + "-" + state.quote);
} else {
styles.push(tokenTypes.quote + "-" + modeCfg.maxBlockquoteDepth);
}
}
if (state.list !== false) {
var listMod = (state.listStack.length - 1) % 3;
if (!listMod) {
styles.push(tokenTypes.list1);
} else if (listMod === 1) {
styles.push(tokenTypes.list2);
} else {
styles.push(tokenTypes.list3);
}
}
if (state.trailingSpaceNewLine) {
styles.push("trailing-space-new-line");
} else if (state.trailingSpace) {
styles.push("trailing-space-" + (state.trailingSpace % 2 ? "a" : "b"));
}
return styles.length ? styles.join(' ') : null;
}
function handleText(stream, state) {
if (stream.match(textRE, true)) {
return getType(state);
}
return undefined;
}
function inlineNormal(stream, state) {
var style = state.text(stream, state);
if (typeof style !== 'undefined')
return style;
if (state.list) { // List marker (*, +, -, 1., etc)
state.list = null;
return getType(state);
}
if (state.taskList) {
var taskOpen = stream.match(taskListRE, true)[1] !== "x";
if (taskOpen) state.taskOpen = true;
else state.taskClosed = true;
if (modeCfg.highlightFormatting) state.formatting = "task";
state.taskList = false;
return getType(state);
}
state.taskOpen = false;
state.taskClosed = false;
if (state.header && stream.match(/^#+$/, true)) {
if (modeCfg.highlightFormatting) state.formatting = "header";
return getType(state);
}
// Get sol() value now, before character is consumed
var sol = stream.sol();
var ch = stream.next();
// Matches link titles present on next line
if (state.linkTitle) {
state.linkTitle = false;
var matchCh = ch;
if (ch === '(') {
matchCh = ')';
}
matchCh = (matchCh+'').replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
var regex = '^\\s*(?:[^' + matchCh + '\\\\]+|\\\\\\\\|\\\\.)' + matchCh;
if (stream.match(new RegExp(regex), true)) {
return tokenTypes.linkHref;
}
}
// If this block is changed, it may need to be updated in GFM mode
if (ch === '`') {
var previousFormatting = state.formatting;
if (modeCfg.highlightFormatting) state.formatting = "code";
stream.eatWhile('`');
var count = stream.current().length
if (state.code == 0) {
state.code = count
return getType(state)
} else if (count == state.code) { // Must be exact
var t = getType(state)
state.code = 0
return t
} else {
state.formatting = previousFormatting
return getType(state)
}
} else if (state.code) {
return getType(state);
}
if (ch === '\\') {
stream.next();
if (modeCfg.highlightFormatting) {
var type = getType(state);
var formattingEscape = tokenTypes.formatting + "-escape";
return type ? type + " " + formattingEscape : formattingEscape;
}
}
if (ch === '!' && stream.match(/\[[^\]]*\] ?(?:\(|\[)/, false)) {
stream.match(/\[[^\]]*\]/);
state.inline = state.f = linkHref;
return tokenTypes.image;
}
if (ch === '[' && stream.match(/[^\]]*\](\(.*\)| ?\[.*?\])/, false)) {
state.linkText = true;
if (modeCfg.highlightFormatting) state.formatting = "link";
return getType(state);
}
if (ch === ']' && state.linkText && stream.match(/\(.*?\)| ?\[.*?\]/, false)) {
if (modeCfg.highlightFormatting) state.formatting = "link";
var type = getType(state);
state.linkText = false;
state.inline = state.f = linkHref;
return type;
}
if (ch === '<' && stream.match(/^(https?|ftps?):\/\/(?:[^\\>]|\\.)+>/, false)) {
state.f = state.inline = linkInline;
if (modeCfg.highlightFormatting) state.formatting = "link";
var type = getType(state);
if (type){
type += " ";
} else {
type = "";
}
return type + tokenTypes.linkInline;
}
if (ch === '<' && stream.match(/^[^> \\]+@(?:[^\\>]|\\.)+>/, false)) {
state.f = state.inline = linkInline;
if (modeCfg.highlightFormatting) state.formatting = "link";
var type = getType(state);
if (type){
type += " ";
} else {
type = "";
}
return type + tokenTypes.linkEmail;
}
if (ch === '<' && stream.match(/^(!--|\w)/, false)) {
var end = stream.string.indexOf(">", stream.pos);
if (end != -1) {
var atts = stream.string.substring(stream.start, end);
if (/markdown\s*=\s*('|"){0,1}1('|"){0,1}/.test(atts)) state.md_inside = true;
}
stream.backUp(1);
state.htmlState = CodeMirror.startState(htmlMode);
return switchBlock(stream, state, htmlBlock);
}
if (ch === '<' && stream.match(/^\/\w*?>/)) {
state.md_inside = false;
return "tag";
}
var ignoreUnderscore = false;
if (!modeCfg.underscoresBreakWords) {
if (ch === '_' && stream.peek() !== '_' && stream.match(/(\w)/, false)) {
var prevPos = stream.pos - 2;
if (prevPos >= 0) {
var prevCh = stream.string.charAt(prevPos);
if (prevCh !== '_' && prevCh.match(/(\w)/, false)) {
ignoreUnderscore = true;
}
}
}
}
if (ch === '*' || (ch === '_' && !ignoreUnderscore)) {
if (sol && stream.peek() === ' ') {
// Do nothing, surrounded by newline and space
} else if (state.strong === ch && stream.eat(ch)) { // Remove STRONG
if (modeCfg.highlightFormatting) state.formatting = "strong";
var t = getType(state);
state.strong = false;
return t;
} else if (!state.strong && stream.eat(ch)) { // Add STRONG
state.strong = ch;
if (modeCfg.highlightFormatting) state.formatting = "strong";
return getType(state);
} else if (state.em === ch) { // Remove EM
if (modeCfg.highlightFormatting) state.formatting = "em";
var t = getType(state);
state.em = false;
return t;
} else if (!state.em) { // Add EM
state.em = ch;
if (modeCfg.highlightFormatting) state.formatting = "em";
return getType(state);
}
} else if (ch === ' ') {
if (stream.eat('*') || stream.eat('_')) { // Probably surrounded by spaces
if (stream.peek() === ' ') { // Surrounded by spaces, ignore
return getType(state);
} else { // Not surrounded by spaces, back up pointer
stream.backUp(1);
}
}
}
if (modeCfg.strikethrough) {
if (ch === '~' && stream.eatWhile(ch)) {
if (state.strikethrough) {// Remove strikethrough
if (modeCfg.highlightFormatting) state.formatting = "strikethrough";
var t = getType(state);
state.strikethrough = false;
return t;
} else if (stream.match(/^[^\s]/, false)) {// Add strikethrough
state.strikethrough = true;
if (modeCfg.highlightFormatting) state.formatting = "strikethrough";
return getType(state);
}
} else if (ch === ' ') {
if (stream.match(/^~~/, true)) { // Probably surrounded by space
if (stream.peek() === ' ') { // Surrounded by spaces, ignore
return getType(state);
} else { // Not surrounded by spaces, back up pointer
stream.backUp(2);
}
}
}
}
if (ch === ' ') {
if (stream.match(/ +$/, false)) {
state.trailingSpace++;
} else if (state.trailingSpace) {
state.trailingSpaceNewLine = true;
}
}
return getType(state);
}
function linkInline(stream, state) {
var ch = stream.next();
if (ch === ">") {
state.f = state.inline = inlineNormal;
if (modeCfg.highlightFormatting) state.formatting = "link";
var type = getType(state);
if (type){
type += " ";
} else {
type = "";
}
return type + tokenTypes.linkInline;
}
stream.match(/^[^>]+/, true);
return tokenTypes.linkInline;
}
function linkHref(stream, state) {
// Check if space, and return NULL if so (to avoid marking the space)
if(stream.eatSpace()){
return null;
}
var ch = stream.next();
if (ch === '(' || ch === '[') {
state.f = state.inline = getLinkHrefInside(ch === "(" ? ")" : "]", 0);
if (modeCfg.highlightFormatting) state.formatting = "link-string";
state.linkHref = true;
return getType(state);
}
return 'error';
}
var linkRE = {
")": /^(?:[^\\\(\)]|\\.|\((?:[^\\\(\)]|\\.)*\))*?(?=\))/,
"]": /^(?:[^\\\[\]]|\\.|\[(?:[^\\\[\\]]|\\.)*\])*?(?=\])/
}
function getLinkHrefInside(endChar) {
return function(stream, state) {
var ch = stream.next();
if (ch === endChar) {
state.f = state.inline = inlineNormal;
if (modeCfg.highlightFormatting) state.formatting = "link-string";
var returnState = getType(state);
state.linkHref = false;
return returnState;
}
stream.match(linkRE[endChar])
state.linkHref = true;
return getType(state);
};
}
function footnoteLink(stream, state) {
if (stream.match(/^([^\]\\]|\\.)*\]:/, false)) {
state.f = footnoteLinkInside;
stream.next(); // Consume [
if (modeCfg.highlightFormatting) state.formatting = "link";
state.linkText = true;
return getType(state);
}
return switchInline(stream, state, inlineNormal);
}
function footnoteLinkInside(stream, state) {
if (stream.match(/^\]:/, true)) {
state.f = state.inline = footnoteUrl;
if (modeCfg.highlightFormatting) state.formatting = "link";
var returnType = getType(state);
state.linkText = false;
return returnType;
}
stream.match(/^([^\]\\]|\\.)+/, true);
return tokenTypes.linkText;
}
function footnoteUrl(stream, state) {
// Check if space, and return NULL if so (to avoid marking the space)
if(stream.eatSpace()){
return null;
}
// Match URL
stream.match(/^[^\s]+/, true);
// Check for link title
if (stream.peek() === undefined) { // End of line, set flag to check next line
state.linkTitle = true;
} else { // More content on line, check if link title
stream.match(/^(?:\s+(?:"(?:[^"\\]|\\\\|\\.)+"|'(?:[^'\\]|\\\\|\\.)+'|\((?:[^)\\]|\\\\|\\.)+\)))?/, true);
}
state.f = state.inline = inlineNormal;
return tokenTypes.linkHref + " url";
}
var mode = {
startState: function() {
return {
f: blockNormal,
prevLine: null,
thisLine: null,
block: blockNormal,
htmlState: null,
indentation: 0,
inline: inlineNormal,
text: handleText,
formatting: false,
linkText: false,
linkHref: false,
linkTitle: false,
code: 0,
em: false,
strong: false,
header: 0,
hr: false,
taskList: false,
list: false,
listStack: [],
quote: 0,
trailingSpace: 0,
trailingSpaceNewLine: false,
strikethrough: false,
fencedChars: null
};
},
copyState: function(s) {
return {
f: s.f,
prevLine: s.prevLine,
thisLine: s.thisLine,
block: s.block,
htmlState: s.htmlState && CodeMirror.copyState(htmlMode, s.htmlState),
indentation: s.indentation,
localMode: s.localMode,
localState: s.localMode ? CodeMirror.copyState(s.localMode, s.localState) : null,
inline: s.inline,
text: s.text,
formatting: false,
linkTitle: s.linkTitle,
code: s.code,
em: s.em,
strong: s.strong,
strikethrough: s.strikethrough,
header: s.header,
hr: s.hr,
taskList: s.taskList,
list: s.list,
listStack: s.listStack.slice(0),
quote: s.quote,
indentedCode: s.indentedCode,
trailingSpace: s.trailingSpace,
trailingSpaceNewLine: s.trailingSpaceNewLine,
md_inside: s.md_inside,
fencedChars: s.fencedChars
};
},
token: function(stream, state) {
// Reset state.formatting
state.formatting = false;
if (stream != state.thisLine) {
var forceBlankLine = state.header || state.hr;
// Reset state.header and state.hr
state.header = 0;
state.hr = false;
if (stream.match(/^\s*$/, true) || forceBlankLine) {
blankLine(state);
if (!forceBlankLine) return null
state.prevLine = null
}
state.prevLine = state.thisLine
state.thisLine = stream
// Reset state.taskList
state.taskList = false;
// Reset state.trailingSpace
state.trailingSpace = 0;
state.trailingSpaceNewLine = false;
state.f = state.block;
var indentation = stream.match(/^\s*/, true)[0].replace(/\t/g, ' ').length;
state.indentationDiff = Math.min(indentation - state.indentation, 4);
state.indentation = state.indentation + state.indentationDiff;
if (indentation > 0) return null;
}
return state.f(stream, state);
},
innerMode: function(state) {
if (state.block == htmlBlock) return {state: state.htmlState, mode: htmlMode};
if (state.localState) return {state: state.localState, mode: state.localMode};
return {state: state, mode: mode};
},
blankLine: blankLine,
getType: getType,
fold: "markdown"
};
return mode;
}, "xml");
CodeMirror.defineMIME("text/x-markdown", "markdown");
});

View File

@ -1,66 +0,0 @@
<!doctype html>
<title>CodeMirror: Sass mode</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../../doc/docs.css">
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="../../addon/edit/matchbrackets.js"></script>
<script src="sass.js"></script>
<style>.CodeMirror {border: 1px solid #ddd; font-size:12px; height: 400px}</style>
<div id=nav>
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<ul>
<li><a href="../../index.html">Home</a>
<li><a href="../../doc/manual.html">Manual</a>
<li><a href="https://github.com/codemirror/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="#">Sass</a>
</ul>
</div>
<article>
<h2>Sass mode</h2>
<form><textarea id="code" name="code">// Variable Definitions
$page-width: 800px
$sidebar-width: 200px
$primary-color: #eeeeee
// Global Attributes
body
font:
family: sans-serif
size: 30em
weight: bold
// Scoped Styles
#contents
width: $page-width
#sidebar
float: right
width: $sidebar-width
#main
width: $page-width - $sidebar-width
background: $primary-color
h2
color: blue
#footer
height: 200px
</textarea></form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers : true,
matchBrackets : true
});
</script>
<p><strong>MIME types defined:</strong> <code>text/x-sass</code>.</p>
</article>

View File

@ -1,61 +0,0 @@
<!doctype html>
<title>CodeMirror: XML mode</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../../doc/docs.css">
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="xml.js"></script>
<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
<div id=nav>
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<ul>
<li><a href="../../index.html">Home</a>
<li><a href="../../doc/manual.html">Manual</a>
<li><a href="https://github.com/codemirror/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class=active href="#">XML</a>
</ul>
</div>
<article>
<h2>XML mode</h2>
<form><textarea id="code" name="code">
&lt;html style="color: green"&gt;
&lt;!-- this is a comment --&gt;
&lt;head&gt;
&lt;title&gt;HTML Example&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
The indentation tries to be &lt;em&gt;somewhat &amp;quot;do what
I mean&amp;quot;&lt;/em&gt;... but might not match your style.
&lt;/body&gt;
&lt;/html&gt;
</textarea></form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
mode: "text/html",
lineNumbers: true
});
</script>
<p>The XML mode supports these configuration parameters:</p>
<dl>
<dt><code>htmlMode (boolean)</code></dt>
<dd>This switches the mode to parse HTML instead of XML. This
means attributes do not have to be quoted, and some elements
(such as <code>br</code>) do not require a closing tag.</dd>
<dt><code>matchClosing (boolean)</code></dt>
<dd>Controls whether the mode checks that close tags match the
corresponding opening tag, and highlights mismatches as errors.
Defaults to true.</dd>
<dt><code>alignCDATA (boolean)</code></dt>
<dd>Setting this to true will force the opening tag of CDATA
blocks to not be indented.</dd>
</dl>
<p><strong>MIME types defined:</strong> <code>application/xml</code>, <code>text/html</code>.</p>
</article>

View File

@ -1,51 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function() {
var mode = CodeMirror.getMode({indentUnit: 2}, "xml"), mname = "xml";
function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1), mname); }
MT("matching",
"[tag&bracket <][tag top][tag&bracket >]",
" text",
" [tag&bracket <][tag inner][tag&bracket />]",
"[tag&bracket </][tag top][tag&bracket >]");
MT("nonmatching",
"[tag&bracket <][tag top][tag&bracket >]",
" [tag&bracket <][tag inner][tag&bracket />]",
" [tag&bracket </][tag&error tip][tag&bracket&error >]");
MT("doctype",
"[meta <!doctype foobar>]",
"[tag&bracket <][tag top][tag&bracket />]");
MT("cdata",
"[tag&bracket <][tag top][tag&bracket >]",
" [atom <![CDATA[foo]",
"[atom barbazguh]]]]>]",
"[tag&bracket </][tag top][tag&bracket >]");
// HTML tests
mode = CodeMirror.getMode({indentUnit: 2}, "text/html");
MT("selfclose",
"[tag&bracket <][tag html][tag&bracket >]",
" [tag&bracket <][tag link] [attribute rel]=[string stylesheet] [attribute href]=[string \"/foobar\"][tag&bracket >]",
"[tag&bracket </][tag html][tag&bracket >]");
MT("list",
"[tag&bracket <][tag ol][tag&bracket >]",
" [tag&bracket <][tag li][tag&bracket >]one",
" [tag&bracket <][tag li][tag&bracket >]two",
"[tag&bracket </][tag ol][tag&bracket >]");
MT("valueless",
"[tag&bracket <][tag input] [attribute type]=[string checkbox] [attribute checked][tag&bracket />]");
MT("pThenArticle",
"[tag&bracket <][tag p][tag&bracket >]",
" foo",
"[tag&bracket <][tag article][tag&bracket >]bar");
})();

12
src/lib/coffee-script.js Normal file

File diff suppressed because one or more lines are too long

9
src/lib/jade.js Normal file

File diff suppressed because one or more lines are too long

23
src/lib/less.min.js vendored Normal file

File diff suppressed because one or more lines are too long

1285
src/lib/marked.js Normal file

File diff suppressed because it is too large Load Diff

202
src/lib/sass.js Normal file
View File

@ -0,0 +1,202 @@
/*! sass.js - v0.9.10 (9a781bf) - built 2016-04-24
providing libsass 3.3.6 (3ae9a20)
via emscripten 1.36.1 (d5085ed)
*/
(function (root, factory) {
'use strict';
if (typeof define === 'function' && define.amd) {
define([], factory);
} else if (typeof exports === 'object') {
module.exports = factory();
} else {
root.Sass = factory();
}
}(this, function () {/*global document*/
// identify the path sass.js is located at in case we're loaded by a simple
// <script src="path/to/sass.js"></script>
// this path can be used to identify the location of
// * sass.worker.js from sass.js
// * libsass.js.mem from sass.sync.js
// see https://github.com/medialize/sass.js/pull/32#issuecomment-103142214
// see https://github.com/medialize/sass.js/issues/33
var SASSJS_RELATIVE_PATH = (function() {
'use strict';
// in Node things are rather simple
if (typeof __dirname !== 'undefined') {
return __dirname;
}
// we can only run this test in the browser,
// so make sure we actually have a DOM to work with.
if (typeof document === 'undefined' || !document.getElementsByTagName) {
return null;
}
// http://www.2ality.com/2014/05/current-script.html
var currentScript = document.currentScript || (function() {
var scripts = document.getElementsByTagName('script');
return scripts[scripts.length - 1];
})();
var path = currentScript && currentScript.src;
if (!path) {
return null;
}
// [worker] make sure we're not running in some concatenated thing
if (path.slice(-8) === '/sass.js') {
return path.slice(0, -8);
}
// [sync] make sure we're not running in some concatenated thing
if (path.slice(-13) === '/sass.sync.js') {
return path.slice(0, -13);
}
return null;
})() || '.';
/*global Worker, SASSJS_RELATIVE_PATH*/
'use strict';
var noop = function(){};
var slice = [].slice;
// defined upon first Sass.initialize() call
var globalWorkerUrl;
function Sass(workerUrl) {
if (!workerUrl && !globalWorkerUrl) {
/*jshint laxbreak:true */
throw new Error(
'Sass needs to be initialized with the URL of sass.worker.js - '
+ 'either via Sass.setWorkerUrl(url) or by new Sass(url)'
);
/*jshint laxbreak:false */
}
if (!globalWorkerUrl) {
globalWorkerUrl = workerUrl;
}
// bind all functions
// we're doing this because we used to have a single hard-wired instance that allowed
// [].map(Sass.removeFile) and we need to maintain that for now (at least until 1.0.0)
for (var key in this) {
if (typeof this[key] === 'function') {
this[key] = this[key].bind(this);
}
}
this._callbacks = {};
this._worker = new Worker(workerUrl || globalWorkerUrl);
this._worker.addEventListener('message', this._handleWorkerMessage, false);
}
// allow setting the workerUrl before the first Sass instance is initialized,
// where registering the global workerUrl would've happened automatically
Sass.setWorkerUrl = function(workerUrl) {
globalWorkerUrl = workerUrl;
};
Sass.style = {
nested: 0,
expanded: 1,
compact: 2,
compressed: 3
};
Sass.comments = {
'none': 0,
'default': 1
};
Sass.prototype = {
style: Sass.style,
comments: Sass.comments,
destroy: function() {
this._worker && this._worker.terminate();
this._worker = null;
this._callbacks = {};
this._importer = null;
},
_handleWorkerMessage: function(event) {
if (event.data.command) {
this[event.data.command](event.data.args);
}
this._callbacks[event.data.id] && this._callbacks[event.data.id](event.data.result);
delete this._callbacks[event.data.id];
},
_dispatch: function(options, callback) {
if (!this._worker) {
throw new Error('Sass worker has been terminated');
}
options.id = 'cb' + Date.now() + Math.random();
this._callbacks[options.id] = callback;
this._worker.postMessage(options);
},
_importerInit: function(args) {
// importer API done callback pushing results
// back to the worker
var done = function done(result) {
this._worker.postMessage({
command: '_importerFinish',
args: [result]
});
}.bind(this);
try {
this._importer(args[0], done);
} catch(e) {
done({ error: e.message });
throw e;
}
},
importer: function(importerCallback, callback) {
if (typeof importerCallback !== 'function' && importerCallback !== null) {
throw new Error('importer callback must either be a function or null');
}
// callback is executed in the main EventLoop
this._importer = importerCallback;
// tell worker to activate importer callback
this._worker.postMessage({
command: 'importer',
args: [Boolean(importerCallback)]
});
callback && callback();
},
};
var commands = 'writeFile readFile listFiles removeFile clearFiles lazyFiles preloadFiles options compile compileFile';
commands.split(' ').forEach(function(command) {
Sass.prototype[command] = function() {
var callback = slice.call(arguments, -1)[0];
var args = slice.call(arguments, 0, -1);
if (typeof callback !== 'function') {
args.push(callback);
callback = noop;
}
this._dispatch({
command: command,
args: args
}, callback);
};
});
// automatically set the workerUrl in case we're loaded by a simple
// <script src="path/to/sass.js"></script>
// see https://github.com/medialize/sass.js/pull/32#issuecomment-103142214
Sass.setWorkerUrl(SASSJS_RELATIVE_PATH + '/sass.worker.js');
return Sass;
}));

813
src/lib/sass.worker.js Normal file

File diff suppressed because one or more lines are too long

16
src/loader.js Normal file
View File

@ -0,0 +1,16 @@
(function(w) {
window.loadJS = function(src) {
var d = deferred();
var ref = w.document.getElementsByTagName("script")[0];
var script = w.document.createElement("script");
script.src = src;
script.async = true;
ref.parentNode.insertBefore(script, ref);
script.onload = function () {
d.resolve();
};
return d.promise;
};
})(window);

View File

@ -8,6 +8,7 @@
"storage",
"tabs"
],
"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'",
"options_ui": {
"page": "options.html",
"chrome_style": true

View File

@ -5,13 +5,44 @@
var editur = window.editur || {};
var version = '1.6.0';
var $ = document.querySelector.bind(document);
var $all = document.querySelectorAll.bind(document);
window.$ = document.querySelector.bind(document);
window.$all = document.querySelectorAll.bind(document);
var HtmlModes = {
HTML: 'html',
MARKDOWN: 'markdown',
JADE: 'jade' // unsafe eval is put in manifest for this file
};
var CssModes = {
CSS: 'css',
SCSS: 'scss',
LESS: 'less'
};
var JsModes = {
JS: 'js',
ES6: 'es6',
COFFEESCRIPT: 'coffee'
};
var modes = {};
modes[HtmlModes.HTML] = { label: 'HTML', cmMode: 'htmlmixed', codepenVal: 'none' };
modes[HtmlModes.MARKDOWN] = { label: 'Markdown', cmMode: 'markdown', codepenVal: 'markdown' };
modes[HtmlModes.JADE] = { label: 'Jade', cmMode: 'jade', codepenVal: 'jade' };
modes[JsModes.JS] = { label: 'JS', cmMode: 'javascript', codepenVal: 'none' };
modes[JsModes.COFFEESCRIPT] = { label: 'CoffeeScript', cmMode: 'coffeescript', codepenVal: 'coffeescript' };
modes[JsModes.ES6] = { label: 'ES6 (Babel)', cmMode: 'javascript', codepenVal: 'babel' };
modes[CssModes.CSS] = { label: 'CSS', cmMode: 'css', codepenVal: 'none' };
modes[CssModes.SCSS] = { label: 'SCSS', cmMode: 'sass', codepenVal: 'scss' };
modes[CssModes.LESS] = { label: 'LESS', cmMode: 'text/x-less', codepenVal: 'less' };
var updateTimer
, updateDelay = 500
, currentLayoutMode
, hasSeenNotifications = true
, htmlMode = HtmlModes.HTML
, jsMode = JsModes.JS
, cssMode = CssModes.CSS
, sass
, frame = $('#demo-frame')
, htmlCode = $('#js-html-code')
, cssCode = $('#js-css-code')
@ -27,6 +58,9 @@
, settingsBtn = $('#js-settings-btn')
, notificationsBtn = $('#js-notifications-btn')
, notificationsModal = $('#js-notifications-modal')
, htmlModelLabel = $('#js-html-mode-label')
, cssModelLabel = $('#js-css-mode-label')
, jsModelLabel = $('#js-js-mode-label')
;
editur.cm = {};
@ -59,10 +93,14 @@
$('#js-demo-side').setAttribute('style', '');
Split(['#js-html-code', '#js-css-code', '#js-js-code'], {
direction: (currentLayoutMode === 2 ? 'horizontal' : 'vertical')
direction: (currentLayoutMode === 2 ? 'horizontal' : 'vertical'),
minSize: 34,
gutterSize: 6
});
Split(['#js-code-side', '#js-demo-side' ], {
direction: (currentLayoutMode === 2 ? 'vertical' : 'horizontal')
direction: (currentLayoutMode === 2 ? 'vertical' : 'horizontal'),
minSize: 34,
gutterSize: 6
});
}
function toggleLayout(mode) {
@ -95,26 +133,124 @@
saveSetting('code', code);
}
/**
* Loaded the code comiler based on the mode selected
*/
function handleModeRequirements(mode) {
// Exit if already loaded
if (modes[mode].hasLoaded) { return; }
function setLoadedFlag() {
modes[mode].hasLoaded = true;
}
if (mode === HtmlModes.JADE) {
loadJS('lib/jade.js').then(setLoadedFlag);
} else if (mode === HtmlModes.MARKDOWN) {
loadJS('lib/marked.js').then(setLoadedFlag);
} else if (mode === CssModes.LESS) {
loadJS('lib/less.min.js').then(setLoadedFlag);
} else if (mode === CssModes.SCSS) {
loadJS('lib/sass.js').then(function () {
sass = new Sass('lib/sass.worker.js');
setLoadedFlag();
});
} else if (mode === JsModes.COFFEESCRIPT) {
loadJS('lib/coffee-script.js').then(setLoadedFlag);
} else if (mode === JsModes.ES6) {
loadJS('lib/babel.min.js').then(setLoadedFlag);
}
}
function updateHtmlMode(value) {
htmlMode = value;
htmlModelLabel.textContent = modes[value].label;
handleModeRequirements(value);
CodeMirror.autoLoadMode(editur.cm.html, modes[value].cmMode);
chrome.storage.sync.set({
htmlMode: value
}, function () {});
}
function updateCssMode(value) {
cssMode = value;
cssModelLabel.textContent = modes[value].label;
handleModeRequirements(value);
CodeMirror.autoLoadMode(editur.cm.css, modes[value].cmMode);
chrome.storage.sync.set({
cssMode: value
}, function () {});
}
function updateJsMode(value) {
jsMode = value;
jsModelLabel.textContent = modes[value].label;
handleModeRequirements(value);
CodeMirror.autoLoadMode(editur.cm.js, modes[value].cmMode);
chrome.storage.sync.set({
jsMode: value
}, function () {});
}
// computeHtml, computeCss & computeJs evaluate the final code according
// to whatever mode is selected and resolve the returned promise with the code.
function computeHtml() {
var d = deferred();
var code = editur.cm.html.getValue();
if (htmlMode === HtmlModes.HTML) {
d.resolve(code);
} else if (htmlMode === HtmlModes.MARKDOWN) {
d.resolve(marked(code));
} else if (htmlMode === HtmlModes.JADE) {
d.resolve(jade.render(code));
}
return d.promise;
}
function computeCss() {
var d = deferred();
var code = editur.cm.css.getValue();
if (cssMode === CssModes.CSS) {
d.resolve(code);
} else if (cssMode === CssModes.SCSS) {
sass.compile(code, function(result) {
d.resolve(result.text);
});
} else if (cssMode === CssModes.LESS) {
less.render(code).then(function (result) {
d.resolve(result.css);
});
}
return d.promise;
}
function computeJs() {
var d = deferred();
var code = editur.cm.js.getValue();
if (jsMode === JsModes.JS) {
d.resolve(code);
} else if (jsMode === JsModes.COFFEESCRIPT) {
d.resolve(CoffeeScript.compile(code, { bare: true }));
} else if (jsMode === JsModes.ES6) {
d.resolve(Babel.transform(editur.cm.js.getValue(), { presets: ['es2015'] }).code);
}
return d.promise;
}
window.onunload = function () {
saveCode();
};
editur.setPreviewContent = function () {
var html = editur.cm.html.getValue();
var css = editur.cm.css.getValue();
var js = editur.cm.js.getValue();
html = '<html>\n<head>\n<style>\n' + css + '\n</style>\n</head>\n<body>\n' + html + '\n<script>\n' + js + '\n</script></body>\n</html>';
function createPreviewFile(html, css, js) {
var contents = '<html>\n<head>\n<style>\n' + css + '\n</style>\n</head>\n<body>\n' + html + '\n<script>\n' + js + '\n</script></body>\n</html>';
var fileWritten = false;
var blob = new Blob([ html ], {type: "text/plain;charset=UTF-8"});
var blob = new Blob([ contents ], { type: "text/plain;charset=UTF-8" });
function errorHandler() { console.log(arguments); }
window.webkitRequestFileSystem(window.TEMPORARY, 1024 * 1024 * 5, function(fs){
fs.root.getFile('preview.html', {create: true}, function(fileEntry) {
fs.root.getFile('preview.html', { create: true }, function(fileEntry) {
fileEntry.createWriter(function(fileWriter) {
function onWriteComplete() {
if (fileWritten) {
@ -131,29 +267,43 @@
}, errorHandler);
}, errorHandler);
}, errorHandler);
}
editur.setPreviewContent = function () {
var htmlPromise = computeHtml();
var cssPromise = computeCss();
var jsPromise = computeJs();
Promise.all([htmlPromise, cssPromise, jsPromise]).then(function (result) {
createPreviewFile(result[0], result[1], result[2]);
});
};
function saveFile() {
var html = editur.cm.html.getValue();
var css = editur.cm.css.getValue();
var js = editur.cm.js.getValue();
var htmlPromise = computeHtml();
var cssPromise = computeCss();
var jsPromise = computeJs();
Promise.all([htmlPromise, cssPromise, jsPromise]).then(function (result) {
var html = result[0],
css = result[1],
js = result[2];
var fileContent = '<html><head>\n<style>\n'
+ css + '\n</style>\n</head>\n<body>\n'
+ html + '\n<script>\n' + js + '\n</script>\n\n</body>\n</html>';
var fileContent = '<html><head>\n<style>\n'
+ css + '\n</style>\n</head>\n<body>\n'
+ html + '\n<script>\n' + js + '\n</script>\n\n</body>\n</html>';
var d = new Date();
var fileName = [ 'web-maker', d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes(), d.getSeconds() ].join('-');
fileName += '.html';
var d = new Date();
var fileName = [ 'web-maker', d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes(), d.getSeconds() ].join('-');
fileName += '.html';
var a = document.createElement('a');
var blob = new Blob([ fileContent ], {type: "text/html;charset=UTF-8"});
a.href = window.URL.createObjectURL(blob);
a.download = fileName;
a.style.display = 'none';
document.body.appendChild(a);
a.click();
a.remove();
var a = document.createElement('a');
var blob = new Blob([ fileContent ], { type: "text/html;charset=UTF-8" });
a.href = window.URL.createObjectURL(blob);
a.download = fileName;
a.style.display = 'none';
document.body.appendChild(a);
a.click();
a.remove();
});
}
function initEditor(element, options) {
@ -194,6 +344,8 @@
function init () {
var lastCode;
CodeMirror.modeURL = "lib/codemirror/mode/%N/%N.js";
layoutBtn1.addEventListener('click', function () { saveSetting('layoutMode', 1); toggleLayout(1); return false; });
layoutBtn2.addEventListener('click', function () { saveSetting('layoutMode', 2); toggleLayout(2); return false; });
layoutBtn3.addEventListener('click', function () { saveSetting('layoutMode', 3); toggleLayout(3); return false; });
@ -220,7 +372,14 @@
title: 'A Web Maker experiment',
html: editur.cm.html.getValue(),
css: editur.cm.css.getValue(),
js: editur.cm.js.getValue()
js: editur.cm.js.getValue(),
/* eslint-disable camelcase */
html_pre_processor: modes[htmlMode].codepenVal,
css_pre_processor: modes[cssMode].codepenVal,
js_pre_processor: modes[jsMode].codepenVal
/* eslint-enable camelcase */
};
json = JSON.stringify(json)
.replace(/"/g, "&quot;")
@ -234,6 +393,25 @@
saveFile();
});
// Attach listeners on mode change menu items
var modeItems = [].slice.call($all('.js-modes-menu a'));
modeItems.forEach(function (item) {
item.addEventListener('click', function (e) {
var mode = e.currentTarget.dataset.mode;
var type = e.currentTarget.dataset.type;
var currentMode = type === 'html' ? htmlMode : (type === 'css' ? cssMode : jsMode);
if (currentMode !== mode) {
if (type === 'html') {
updateHtmlMode(mode);
} else if (type === 'js') {
updateJsMode(mode);
} else if (type === 'css') {
updateCssMode(mode);
}
}
});
});
window.addEventListener('keydown', function (event) {
if ((event.ctrlKey || event.metaKey) && (event.keyCode === 83)){
event.preventDefault();
@ -277,7 +455,10 @@
// Get synced `preserveLastCode` setting to get back last code (or not).
chrome.storage.sync.get({
preserveLastCode: true
preserveLastCode: true,
htmlMode: 'html',
jsMode: 'js',
cssMode: 'css'
}, function syncGetCallback(result) {
if (result.preserveLastCode && lastCode) {
editur.cm.html.setValue(lastCode.html);
@ -287,6 +468,9 @@
editur.cm.css.refresh();
editur.cm.js.refresh();
}
updateHtmlMode(result.htmlMode);
updateJsMode(result.jsMode);
updateCssMode(result.cssMode);
});
// Check for new version notifications