Commit 2e2dfd2b authored by lukas.niegsch's avatar lukas.niegsch

wip: started implementing application with jio/rsvp/renderjs

parent 5ffd21aa
class RequestHandler
{
constructor()
{
this.buffer = ["https://www.example.com", "https://www.nexedi.com/"]
}
hasNextRequest()
{
return this.buffer.length != 0
}
getNextRequest()
{
return this.buffer.pop()
}
publishResults(name, data)
{
var a = document.createElement("a");
a.href = "data:application/pdf;base64," + data;
a.download = `${name}.pdf`;
a.click();
}
}
\ No newline at end of file
<!-- todo: implement (empty) gadget that can convert html to pdf -->
<!---idea: use this gadget inside erp5 later, but test it here as standalone -->
\ No newline at end of file
/* BASICS */
.CodeMirror {
/* Set height, width, borders, and global font properties here */
font-family: monospace;
height: 300px;
color: black;
direction: ltr;
}
/* PADDING */
.CodeMirror-lines {
padding: 4px 0; /* Vertical padding around content */
}
.CodeMirror pre.CodeMirror-line,
.CodeMirror pre.CodeMirror-line-like {
padding: 0 4px; /* Horizontal padding of content */
}
.CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
background-color: white; /* The little square between H and V scrollbars */
}
/* GUTTER */
.CodeMirror-gutters {
border-right: 1px solid #ddd;
background-color: #f7f7f7;
white-space: nowrap;
}
.CodeMirror-linenumbers {}
.CodeMirror-linenumber {
padding: 0 3px 0 5px;
min-width: 20px;
text-align: right;
color: #999;
white-space: nowrap;
}
.CodeMirror-guttermarker { color: black; }
.CodeMirror-guttermarker-subtle { color: #999; }
/* CURSOR */
.CodeMirror-cursor {
border-left: 1px solid black;
border-right: none;
width: 0;
}
/* Shown when moving in bi-directional text */
.CodeMirror div.CodeMirror-secondarycursor {
border-left: 1px solid silver;
}
.cm-fat-cursor .CodeMirror-cursor {
width: auto;
border: 0 !important;
background: #7e7;
}
.cm-fat-cursor div.CodeMirror-cursors {
z-index: 1;
}
.cm-fat-cursor .CodeMirror-line::selection,
.cm-fat-cursor .CodeMirror-line > span::selection,
.cm-fat-cursor .CodeMirror-line > span > span::selection { background: transparent; }
.cm-fat-cursor .CodeMirror-line::-moz-selection,
.cm-fat-cursor .CodeMirror-line > span::-moz-selection,
.cm-fat-cursor .CodeMirror-line > span > span::-moz-selection { background: transparent; }
.cm-fat-cursor { caret-color: transparent; }
@-moz-keyframes blink {
0% {}
50% { background-color: transparent; }
100% {}
}
@-webkit-keyframes blink {
0% {}
50% { background-color: transparent; }
100% {}
}
@keyframes blink {
0% {}
50% { background-color: transparent; }
100% {}
}
/* Can style cursor different in overwrite (non-insert) mode */
.CodeMirror-overwrite .CodeMirror-cursor {}
.cm-tab { display: inline-block; text-decoration: inherit; }
.CodeMirror-rulers {
position: absolute;
left: 0; right: 0; top: -50px; bottom: 0;
overflow: hidden;
}
.CodeMirror-ruler {
border-left: 1px solid #ccc;
top: 0; bottom: 0;
position: absolute;
}
/* DEFAULT THEME */
.cm-s-default .cm-header {color: blue;}
.cm-s-default .cm-quote {color: #090;}
.cm-negative {color: #d44;}
.cm-positive {color: #292;}
.cm-header, .cm-strong {font-weight: bold;}
.cm-em {font-style: italic;}
.cm-link {text-decoration: underline;}
.cm-strikethrough {text-decoration: line-through;}
.cm-s-default .cm-keyword {color: #708;}
.cm-s-default .cm-atom {color: #219;}
.cm-s-default .cm-number {color: #164;}
.cm-s-default .cm-def {color: #00f;}
.cm-s-default .cm-variable,
.cm-s-default .cm-punctuation,
.cm-s-default .cm-property,
.cm-s-default .cm-operator {}
.cm-s-default .cm-variable-2 {color: #05a;}
.cm-s-default .cm-variable-3, .cm-s-default .cm-type {color: #085;}
.cm-s-default .cm-comment {color: #a50;}
.cm-s-default .cm-string {color: #a11;}
.cm-s-default .cm-string-2 {color: #f50;}
.cm-s-default .cm-meta {color: #555;}
.cm-s-default .cm-qualifier {color: #555;}
.cm-s-default .cm-builtin {color: #30a;}
.cm-s-default .cm-bracket {color: #997;}
.cm-s-default .cm-tag {color: #170;}
.cm-s-default .cm-attribute {color: #00c;}
.cm-s-default .cm-hr {color: #999;}
.cm-s-default .cm-link {color: #00c;}
.cm-s-default .cm-error {color: #f00;}
.cm-invalidchar {color: #f00;}
.CodeMirror-composing { border-bottom: 2px solid; }
/* Default styles for common addons */
div.CodeMirror span.CodeMirror-matchingbracket {color: #0b0;}
div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #a22;}
.CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); }
.CodeMirror-activeline-background {background: #e8f2ff;}
/* STOP */
/* The rest of this file contains styles related to the mechanics of
the editor. You probably shouldn't touch them. */
.CodeMirror {
position: relative;
overflow: hidden;
background: white;
}
.CodeMirror-scroll {
overflow: scroll !important; /* Things will break if this is overridden */
/* 50px is the magic margin used to hide the element's real scrollbars */
/* See overflow: hidden in .CodeMirror */
margin-bottom: -50px; margin-right: -50px;
padding-bottom: 50px;
height: 100%;
outline: none; /* Prevent dragging from highlighting the element */
position: relative;
z-index: 0;
}
.CodeMirror-sizer {
position: relative;
border-right: 50px solid transparent;
}
/* The fake, visible scrollbars. Used to force redraw during scrolling
before actual scrolling happens, thus preventing shaking and
flickering artifacts. */
.CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
position: absolute;
z-index: 6;
display: none;
outline: none;
}
.CodeMirror-vscrollbar {
right: 0; top: 0;
overflow-x: hidden;
overflow-y: scroll;
}
.CodeMirror-hscrollbar {
bottom: 0; left: 0;
overflow-y: hidden;
overflow-x: scroll;
}
.CodeMirror-scrollbar-filler {
right: 0; bottom: 0;
}
.CodeMirror-gutter-filler {
left: 0; bottom: 0;
}
.CodeMirror-gutters {
position: absolute; left: 0; top: 0;
min-height: 100%;
z-index: 3;
}
.CodeMirror-gutter {
white-space: normal;
height: 100%;
display: inline-block;
vertical-align: top;
margin-bottom: -50px;
}
.CodeMirror-gutter-wrapper {
position: absolute;
z-index: 4;
background: none !important;
border: none !important;
}
.CodeMirror-gutter-background {
position: absolute;
top: 0; bottom: 0;
z-index: 4;
}
.CodeMirror-gutter-elt {
position: absolute;
cursor: default;
z-index: 4;
}
.CodeMirror-gutter-wrapper ::selection { background-color: transparent }
.CodeMirror-gutter-wrapper ::-moz-selection { background-color: transparent }
.CodeMirror-lines {
cursor: text;
min-height: 1px; /* prevents collapsing before first draw */
}
.CodeMirror pre.CodeMirror-line,
.CodeMirror pre.CodeMirror-line-like {
/* Reset some styles that the rest of the page might have set */
-moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0;
border-width: 0;
background: transparent;
font-family: inherit;
font-size: inherit;
margin: 0;
white-space: pre;
word-wrap: normal;
line-height: inherit;
color: inherit;
z-index: 2;
position: relative;
overflow: visible;
-webkit-tap-highlight-color: transparent;
-webkit-font-variant-ligatures: contextual;
font-variant-ligatures: contextual;
}
.CodeMirror-wrap pre.CodeMirror-line,
.CodeMirror-wrap pre.CodeMirror-line-like {
word-wrap: break-word;
white-space: pre-wrap;
word-break: normal;
}
.CodeMirror-linebackground {
position: absolute;
left: 0; right: 0; top: 0; bottom: 0;
z-index: 0;
}
.CodeMirror-linewidget {
position: relative;
z-index: 2;
padding: 0.1px; /* Force widget margins to stay inside of the container */
}
.CodeMirror-widget {}
.CodeMirror-rtl pre { direction: rtl; }
.CodeMirror-code {
outline: none;
}
/* Force content-box sizing for the elements where we expect it */
.CodeMirror-scroll,
.CodeMirror-sizer,
.CodeMirror-gutter,
.CodeMirror-gutters,
.CodeMirror-linenumber {
-moz-box-sizing: content-box;
box-sizing: content-box;
}
.CodeMirror-measure {
position: absolute;
width: 100%;
height: 0;
overflow: hidden;
visibility: hidden;
}
.CodeMirror-cursor {
position: absolute;
pointer-events: none;
}
.CodeMirror-measure pre { position: static; }
div.CodeMirror-cursors {
visibility: hidden;
position: relative;
z-index: 3;
}
div.CodeMirror-dragcursors {
visibility: visible;
}
.CodeMirror-focused div.CodeMirror-cursors {
visibility: visible;
}
.CodeMirror-selected { background: #d9d9d9; }
.CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
.CodeMirror-crosshair { cursor: crosshair; }
.CodeMirror-line::selection, .CodeMirror-line > span::selection, .CodeMirror-line > span > span::selection { background: #d7d4f0; }
.CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; }
.cm-searching {
background-color: #ffa;
background-color: rgba(255, 255, 0, .4);
}
/* Used to force a border model for a node */
.cm-force-border { padding-right: .1px; }
@media print {
/* Hide the cursor when printing */
.CodeMirror div.CodeMirror-cursors {
visibility: hidden;
}
}
/* See issue #2901 */
.cm-tab-wrap-hack:after { content: ''; }
/* Help users use markselection to safely style text background */
span.CodeMirror-selectedtext { background: none; }
This source diff could not be displayed because it is too large. You can view the blob instead.
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/5/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.defineMode("css", function(config, parserConfig) {
var inline = parserConfig.inline
if (!parserConfig.propertyKeywords) parserConfig = CodeMirror.resolveMode("text/css");
var indentUnit = config.indentUnit,
tokenHooks = parserConfig.tokenHooks,
documentTypes = parserConfig.documentTypes || {},
mediaTypes = parserConfig.mediaTypes || {},
mediaFeatures = parserConfig.mediaFeatures || {},
mediaValueKeywords = parserConfig.mediaValueKeywords || {},
propertyKeywords = parserConfig.propertyKeywords || {},
nonStandardPropertyKeywords = parserConfig.nonStandardPropertyKeywords || {},
fontProperties = parserConfig.fontProperties || {},
counterDescriptors = parserConfig.counterDescriptors || {},
colorKeywords = parserConfig.colorKeywords || {},
valueKeywords = parserConfig.valueKeywords || {},
allowNested = parserConfig.allowNested,
lineComment = parserConfig.lineComment,
supportsAtComponent = parserConfig.supportsAtComponent === true,
highlightNonStandardPropertyKeywords = config.highlightNonStandardPropertyKeywords !== false;
var type, override;
function ret(style, tp) { type = tp; return style; }
// Tokenizers
function tokenBase(stream, state) {
var ch = stream.next();
if (tokenHooks[ch]) {
var result = tokenHooks[ch](stream, state);
if (result !== false) return result;
}
if (ch == "@") {
stream.eatWhile(/[\w\\\-]/);
return ret("def", stream.current());
} else if (ch == "=" || (ch == "~" || ch == "|") && stream.eat("=")) {
return ret(null, "compare");
} else if (ch == "\"" || ch == "'") {
state.tokenize = tokenString(ch);
return state.tokenize(stream, state);
} else if (ch == "#") {
stream.eatWhile(/[\w\\\-]/);
return ret("atom", "hash");
} else if (ch == "!") {
stream.match(/^\s*\w*/);
return ret("keyword", "important");
} else if (/\d/.test(ch) || ch == "." && stream.eat(/\d/)) {
stream.eatWhile(/[\w.%]/);
return ret("number", "unit");
} else if (ch === "-") {
if (/[\d.]/.test(stream.peek())) {
stream.eatWhile(/[\w.%]/);
return ret("number", "unit");
} else if (stream.match(/^-[\w\\\-]*/)) {
stream.eatWhile(/[\w\\\-]/);
if (stream.match(/^\s*:/, false))
return ret("variable-2", "variable-definition");
return ret("variable-2", "variable");
} else if (stream.match(/^\w+-/)) {
return ret("meta", "meta");
}
} else if (/[,+>*\/]/.test(ch)) {
return ret(null, "select-op");
} else if (ch == "." && stream.match(/^-?[_a-z][_a-z0-9-]*/i)) {
return ret("qualifier", "qualifier");
} else if (/[:;{}\[\]\(\)]/.test(ch)) {
return ret(null, ch);
} else if (stream.match(/^[\w-.]+(?=\()/)) {
if (/^(url(-prefix)?|domain|regexp)$/i.test(stream.current())) {
state.tokenize = tokenParenthesized;
}
return ret("variable callee", "variable");
} else if (/[\w\\\-]/.test(ch)) {
stream.eatWhile(/[\w\\\-]/);
return ret("property", "word");
} else {
return ret(null, null);
}
}
function tokenString(quote) {
return function(stream, state) {
var escaped = false, ch;
while ((ch = stream.next()) != null) {
if (ch == quote && !escaped) {
if (quote == ")") stream.backUp(1);
break;
}
escaped = !escaped && ch == "\\";
}
if (ch == quote || !escaped && quote != ")") state.tokenize = null;
return ret("string", "string");
};
}
function tokenParenthesized(stream, state) {
stream.next(); // Must be '('
if (!stream.match(/^\s*[\"\')]/, false))
state.tokenize = tokenString(")");
else
state.tokenize = null;
return ret(null, "(");
}
// Context management
function Context(type, indent, prev) {
this.type = type;
this.indent = indent;
this.prev = prev;
}
function pushContext(state, stream, type, indent) {
state.context = new Context(type, stream.indentation() + (indent === false ? 0 : indentUnit), state.context);
return type;
}
function popContext(state) {
if (state.context.prev)
state.context = state.context.prev;
return state.context.type;
}
function pass(type, stream, state) {
return states[state.context.type](type, stream, state);
}
function popAndPass(type, stream, state, n) {
for (var i = n || 1; i > 0; i--)
state.context = state.context.prev;
return pass(type, stream, state);
}
// Parser
function wordAsValue(stream) {
var word = stream.current().toLowerCase();
if (valueKeywords.hasOwnProperty(word))
override = "atom";
else if (colorKeywords.hasOwnProperty(word))
override = "keyword";
else
override = "variable";
}
var states = {};
states.top = function(type, stream, state) {
if (type == "{") {
return pushContext(state, stream, "block");
} else if (type == "}" && state.context.prev) {
return popContext(state);
} else if (supportsAtComponent && /@component/i.test(type)) {
return pushContext(state, stream, "atComponentBlock");
} else if (/^@(-moz-)?document$/i.test(type)) {
return pushContext(state, stream, "documentTypes");
} else if (/^@(media|supports|(-moz-)?document|import)$/i.test(type)) {
return pushContext(state, stream, "atBlock");
} else if (/^@(font-face|counter-style)/i.test(type)) {
state.stateArg = type;
return "restricted_atBlock_before";
} else if (/^@(-(moz|ms|o|webkit)-)?keyframes$/i.test(type)) {
return "keyframes";
} else if (type && type.charAt(0) == "@") {
return pushContext(state, stream, "at");
} else if (type == "hash") {
override = "builtin";
} else if (type == "word") {
override = "tag";
} else if (type == "variable-definition") {
return "maybeprop";
} else if (type == "interpolation") {
return pushContext(state, stream, "interpolation");
} else if (type == ":") {
return "pseudo";
} else if (allowNested && type == "(") {
return pushContext(state, stream, "parens");
}
return state.context.type;
};
states.block = function(type, stream, state) {
if (type == "word") {
var word = stream.current().toLowerCase();
if (propertyKeywords.hasOwnProperty(word)) {
override = "property";
return "maybeprop";
} else if (nonStandardPropertyKeywords.hasOwnProperty(word)) {
override = highlightNonStandardPropertyKeywords ? "string-2" : "property";
return "maybeprop";
} else if (allowNested) {
override = stream.match(/^\s*:(?:\s|$)/, false) ? "property" : "tag";
return "block";
} else {
override += " error";
return "maybeprop";
}
} else if (type == "meta") {
return "block";
} else if (!allowNested && (type == "hash" || type == "qualifier")) {
override = "error";
return "block";
} else {
return states.top(type, stream, state);
}
};
states.maybeprop = function(type, stream, state) {
if (type == ":") return pushContext(state, stream, "prop");
return pass(type, stream, state);
};
states.prop = function(type, stream, state) {
if (type == ";") return popContext(state);
if (type == "{" && allowNested) return pushContext(state, stream, "propBlock");
if (type == "}" || type == "{") return popAndPass(type, stream, state);
if (type == "(") return pushContext(state, stream, "parens");
if (type == "hash" && !/^#([0-9a-fA-f]{3,4}|[0-9a-fA-f]{6}|[0-9a-fA-f]{8})$/.test(stream.current())) {
override += " error";
} else if (type == "word") {
wordAsValue(stream);
} else if (type == "interpolation") {
return pushContext(state, stream, "interpolation");
}
return "prop";
};
states.propBlock = function(type, _stream, state) {
if (type == "}") return popContext(state);
if (type == "word") { override = "property"; return "maybeprop"; }
return state.context.type;
};
states.parens = function(type, stream, state) {
if (type == "{" || type == "}") return popAndPass(type, stream, state);
if (type == ")") return popContext(state);
if (type == "(") return pushContext(state, stream, "parens");
if (type == "interpolation") return pushContext(state, stream, "interpolation");
if (type == "word") wordAsValue(stream);
return "parens";
};
states.pseudo = function(type, stream, state) {
if (type == "meta") return "pseudo";
if (type == "word") {
override = "variable-3";
return state.context.type;
}
return pass(type, stream, state);
};
states.documentTypes = function(type, stream, state) {
if (type == "word" && documentTypes.hasOwnProperty(stream.current())) {
override = "tag";
return state.context.type;
} else {
return states.atBlock(type, stream, state);
}
};
states.atBlock = function(type, stream, state) {
if (type == "(") return pushContext(state, stream, "atBlock_parens");
if (type == "}" || type == ";") return popAndPass(type, stream, state);
if (type == "{") return popContext(state) && pushContext(state, stream, allowNested ? "block" : "top");
if (type == "interpolation") return pushContext(state, stream, "interpolation");
if (type == "word") {
var word = stream.current().toLowerCase();
if (word == "only" || word == "not" || word == "and" || word == "or")
override = "keyword";
else if (mediaTypes.hasOwnProperty(word))
override = "attribute";
else if (mediaFeatures.hasOwnProperty(word))
override = "property";
else if (mediaValueKeywords.hasOwnProperty(word))
override = "keyword";
else if (propertyKeywords.hasOwnProperty(word))
override = "property";
else if (nonStandardPropertyKeywords.hasOwnProperty(word))
override = highlightNonStandardPropertyKeywords ? "string-2" : "property";
else if (valueKeywords.hasOwnProperty(word))
override = "atom";
else if (colorKeywords.hasOwnProperty(word))
override = "keyword";
else
override = "error";
}
return state.context.type;
};
states.atComponentBlock = function(type, stream, state) {
if (type == "}")
return popAndPass(type, stream, state);
if (type == "{")
return popContext(state) && pushContext(state, stream, allowNested ? "block" : "top", false);
if (type == "word")
override = "error";
return state.context.type;
};
states.atBlock_parens = function(type, stream, state) {
if (type == ")") return popContext(state);
if (type == "{" || type == "}") return popAndPass(type, stream, state, 2);
return states.atBlock(type, stream, state);
};
states.restricted_atBlock_before = function(type, stream, state) {
if (type == "{")
return pushContext(state, stream, "restricted_atBlock");
if (type == "word" && state.stateArg == "@counter-style") {
override = "variable";
return "restricted_atBlock_before";
}
return pass(type, stream, state);
};
states.restricted_atBlock = function(type, stream, state) {
if (type == "}") {
state.stateArg = null;
return popContext(state);
}
if (type == "word") {
if ((state.stateArg == "@font-face" && !fontProperties.hasOwnProperty(stream.current().toLowerCase())) ||
(state.stateArg == "@counter-style" && !counterDescriptors.hasOwnProperty(stream.current().toLowerCase())))
override = "error";
else
override = "property";
return "maybeprop";
}
return "restricted_atBlock";
};
states.keyframes = function(type, stream, state) {
if (type == "word") { override = "variable"; return "keyframes"; }
if (type == "{") return pushContext(state, stream, "top");
return pass(type, stream, state);
};
states.at = function(type, stream, state) {
if (type == ";") return popContext(state);
if (type == "{" || type == "}") return popAndPass(type, stream, state);
if (type == "word") override = "tag";
else if (type == "hash") override = "builtin";
return "at";
};
states.interpolation = function(type, stream, state) {
if (type == "}") return popContext(state);
if (type == "{" || type == ";") return popAndPass(type, stream, state);
if (type == "word") override = "variable";
else if (type != "variable" && type != "(" && type != ")") override = "error";
return "interpolation";
};
return {
startState: function(base) {
return {tokenize: null,
state: inline ? "block" : "top",
stateArg: null,
context: new Context(inline ? "block" : "top", base || 0, null)};
},
token: function(stream, state) {
if (!state.tokenize && stream.eatSpace()) return null;
var style = (state.tokenize || tokenBase)(stream, state);
if (style && typeof style == "object") {
type = style[1];
style = style[0];
}
override = style;
if (type != "comment")
state.state = states[state.state](type, stream, state);
return override;
},
indent: function(state, textAfter) {
var cx = state.context, ch = textAfter && textAfter.charAt(0);
var indent = cx.indent;
if (cx.type == "prop" && (ch == "}" || ch == ")")) cx = cx.prev;
if (cx.prev) {
if (ch == "}" && (cx.type == "block" || cx.type == "top" ||
cx.type == "interpolation" || cx.type == "restricted_atBlock")) {
// Resume indentation from parent context.
cx = cx.prev;
indent = cx.indent;
} else if (ch == ")" && (cx.type == "parens" || cx.type == "atBlock_parens") ||
ch == "{" && (cx.type == "at" || cx.type == "atBlock")) {
// Dedent relative to current context.
indent = Math.max(0, cx.indent - indentUnit);
}
}
return indent;
},
electricChars: "}",
blockCommentStart: "/*",
blockCommentEnd: "*/",
blockCommentContinue: " * ",
lineComment: lineComment,
fold: "brace"
};
});
function keySet(array) {
var keys = {};
for (var i = 0; i < array.length; ++i) {
keys[array[i].toLowerCase()] = true;
}
return keys;
}
var documentTypes_ = [
"domain", "regexp", "url", "url-prefix"
], documentTypes = keySet(documentTypes_);
var mediaTypes_ = [
"all", "aural", "braille", "handheld", "print", "projection", "screen",
"tty", "tv", "embossed"
], mediaTypes = keySet(mediaTypes_);
var mediaFeatures_ = [
"width", "min-width", "max-width", "height", "min-height", "max-height",
"device-width", "min-device-width", "max-device-width", "device-height",
"min-device-height", "max-device-height", "aspect-ratio",
"min-aspect-ratio", "max-aspect-ratio", "device-aspect-ratio",
"min-device-aspect-ratio", "max-device-aspect-ratio", "color", "min-color",
"max-color", "color-index", "min-color-index", "max-color-index",
"monochrome", "min-monochrome", "max-monochrome", "resolution",
"min-resolution", "max-resolution", "scan", "grid", "orientation",
"device-pixel-ratio", "min-device-pixel-ratio", "max-device-pixel-ratio",
"pointer", "any-pointer", "hover", "any-hover", "prefers-color-scheme",
"dynamic-range", "video-dynamic-range"
], mediaFeatures = keySet(mediaFeatures_);
var mediaValueKeywords_ = [
"landscape", "portrait", "none", "coarse", "fine", "on-demand", "hover",
"interlace", "progressive",
"dark", "light",
"standard", "high"
], mediaValueKeywords = keySet(mediaValueKeywords_);
var propertyKeywords_ = [
"align-content", "align-items", "align-self", "alignment-adjust",
"alignment-baseline", "all", "anchor-point", "animation", "animation-delay",
"animation-direction", "animation-duration", "animation-fill-mode",
"animation-iteration-count", "animation-name", "animation-play-state",
"animation-timing-function", "appearance", "azimuth", "backdrop-filter",
"backface-visibility", "background", "background-attachment",
"background-blend-mode", "background-clip", "background-color",
"background-image", "background-origin", "background-position",
"background-position-x", "background-position-y", "background-repeat",
"background-size", "baseline-shift", "binding", "bleed", "block-size",
"bookmark-label", "bookmark-level", "bookmark-state", "bookmark-target",
"border", "border-bottom", "border-bottom-color", "border-bottom-left-radius",
"border-bottom-right-radius", "border-bottom-style", "border-bottom-width",
"border-collapse", "border-color", "border-image", "border-image-outset",
"border-image-repeat", "border-image-slice", "border-image-source",
"border-image-width", "border-left", "border-left-color", "border-left-style",
"border-left-width", "border-radius", "border-right", "border-right-color",
"border-right-style", "border-right-width", "border-spacing", "border-style",
"border-top", "border-top-color", "border-top-left-radius",
"border-top-right-radius", "border-top-style", "border-top-width",
"border-width", "bottom", "box-decoration-break", "box-shadow", "box-sizing",
"break-after", "break-before", "break-inside", "caption-side", "caret-color",
"clear", "clip", "color", "color-profile", "column-count", "column-fill",
"column-gap", "column-rule", "column-rule-color", "column-rule-style",
"column-rule-width", "column-span", "column-width", "columns", "contain",
"content", "counter-increment", "counter-reset", "crop", "cue", "cue-after",
"cue-before", "cursor", "direction", "display", "dominant-baseline",
"drop-initial-after-adjust", "drop-initial-after-align",
"drop-initial-before-adjust", "drop-initial-before-align", "drop-initial-size",
"drop-initial-value", "elevation", "empty-cells", "fit", "fit-content", "fit-position",
"flex", "flex-basis", "flex-direction", "flex-flow", "flex-grow",
"flex-shrink", "flex-wrap", "float", "float-offset", "flow-from", "flow-into",
"font", "font-family", "font-feature-settings", "font-kerning",
"font-language-override", "font-optical-sizing", "font-size",
"font-size-adjust", "font-stretch", "font-style", "font-synthesis",
"font-variant", "font-variant-alternates", "font-variant-caps",
"font-variant-east-asian", "font-variant-ligatures", "font-variant-numeric",
"font-variant-position", "font-variation-settings", "font-weight", "gap",
"grid", "grid-area", "grid-auto-columns", "grid-auto-flow", "grid-auto-rows",
"grid-column", "grid-column-end", "grid-column-gap", "grid-column-start",
"grid-gap", "grid-row", "grid-row-end", "grid-row-gap", "grid-row-start",
"grid-template", "grid-template-areas", "grid-template-columns",
"grid-template-rows", "hanging-punctuation", "height", "hyphens", "icon",
"image-orientation", "image-rendering", "image-resolution", "inline-box-align",
"inset", "inset-block", "inset-block-end", "inset-block-start", "inset-inline",
"inset-inline-end", "inset-inline-start", "isolation", "justify-content",
"justify-items", "justify-self", "left", "letter-spacing", "line-break",
"line-height", "line-height-step", "line-stacking", "line-stacking-ruby",
"line-stacking-shift", "line-stacking-strategy", "list-style",
"list-style-image", "list-style-position", "list-style-type", "margin",
"margin-bottom", "margin-left", "margin-right", "margin-top", "marks",
"marquee-direction", "marquee-loop", "marquee-play-count", "marquee-speed",
"marquee-style", "mask-clip", "mask-composite", "mask-image", "mask-mode",
"mask-origin", "mask-position", "mask-repeat", "mask-size","mask-type",
"max-block-size", "max-height", "max-inline-size",
"max-width", "min-block-size", "min-height", "min-inline-size", "min-width",
"mix-blend-mode", "move-to", "nav-down", "nav-index", "nav-left", "nav-right",
"nav-up", "object-fit", "object-position", "offset", "offset-anchor",
"offset-distance", "offset-path", "offset-position", "offset-rotate",
"opacity", "order", "orphans", "outline", "outline-color", "outline-offset",
"outline-style", "outline-width", "overflow", "overflow-style",
"overflow-wrap", "overflow-x", "overflow-y", "padding", "padding-bottom",
"padding-left", "padding-right", "padding-top", "page", "page-break-after",
"page-break-before", "page-break-inside", "page-policy", "pause",
"pause-after", "pause-before", "perspective", "perspective-origin", "pitch",
"pitch-range", "place-content", "place-items", "place-self", "play-during",
"position", "presentation-level", "punctuation-trim", "quotes",
"region-break-after", "region-break-before", "region-break-inside",
"region-fragment", "rendering-intent", "resize", "rest", "rest-after",
"rest-before", "richness", "right", "rotate", "rotation", "rotation-point",
"row-gap", "ruby-align", "ruby-overhang", "ruby-position", "ruby-span",
"scale", "scroll-behavior", "scroll-margin", "scroll-margin-block",
"scroll-margin-block-end", "scroll-margin-block-start", "scroll-margin-bottom",
"scroll-margin-inline", "scroll-margin-inline-end",
"scroll-margin-inline-start", "scroll-margin-left", "scroll-margin-right",
"scroll-margin-top", "scroll-padding", "scroll-padding-block",
"scroll-padding-block-end", "scroll-padding-block-start",
"scroll-padding-bottom", "scroll-padding-inline", "scroll-padding-inline-end",
"scroll-padding-inline-start", "scroll-padding-left", "scroll-padding-right",
"scroll-padding-top", "scroll-snap-align", "scroll-snap-type",
"shape-image-threshold", "shape-inside", "shape-margin", "shape-outside",
"size", "speak", "speak-as", "speak-header", "speak-numeral",
"speak-punctuation", "speech-rate", "stress", "string-set", "tab-size",
"table-layout", "target", "target-name", "target-new", "target-position",
"text-align", "text-align-last", "text-combine-upright", "text-decoration",
"text-decoration-color", "text-decoration-line", "text-decoration-skip",
"text-decoration-skip-ink", "text-decoration-style", "text-emphasis",
"text-emphasis-color", "text-emphasis-position", "text-emphasis-style",
"text-height", "text-indent", "text-justify", "text-orientation",
"text-outline", "text-overflow", "text-rendering", "text-shadow",
"text-size-adjust", "text-space-collapse", "text-transform",
"text-underline-position", "text-wrap", "top", "touch-action", "transform", "transform-origin",
"transform-style", "transition", "transition-delay", "transition-duration",
"transition-property", "transition-timing-function", "translate",
"unicode-bidi", "user-select", "vertical-align", "visibility", "voice-balance",
"voice-duration", "voice-family", "voice-pitch", "voice-range", "voice-rate",
"voice-stress", "voice-volume", "volume", "white-space", "widows", "width",
"will-change", "word-break", "word-spacing", "word-wrap", "writing-mode", "z-index",
// SVG-specific
"clip-path", "clip-rule", "mask", "enable-background", "filter", "flood-color",
"flood-opacity", "lighting-color", "stop-color", "stop-opacity", "pointer-events",
"color-interpolation", "color-interpolation-filters",
"color-rendering", "fill", "fill-opacity", "fill-rule", "image-rendering",
"marker", "marker-end", "marker-mid", "marker-start", "paint-order", "shape-rendering", "stroke",
"stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin",
"stroke-miterlimit", "stroke-opacity", "stroke-width", "text-rendering",
"baseline-shift", "dominant-baseline", "glyph-orientation-horizontal",
"glyph-orientation-vertical", "text-anchor", "writing-mode",
], propertyKeywords = keySet(propertyKeywords_);
var nonStandardPropertyKeywords_ = [
"accent-color", "aspect-ratio", "border-block", "border-block-color", "border-block-end",
"border-block-end-color", "border-block-end-style", "border-block-end-width",
"border-block-start", "border-block-start-color", "border-block-start-style",
"border-block-start-width", "border-block-style", "border-block-width",
"border-inline", "border-inline-color", "border-inline-end",
"border-inline-end-color", "border-inline-end-style",
"border-inline-end-width", "border-inline-start", "border-inline-start-color",
"border-inline-start-style", "border-inline-start-width",
"border-inline-style", "border-inline-width", "content-visibility", "margin-block",
"margin-block-end", "margin-block-start", "margin-inline", "margin-inline-end",
"margin-inline-start", "overflow-anchor", "overscroll-behavior", "padding-block", "padding-block-end",
"padding-block-start", "padding-inline", "padding-inline-end",
"padding-inline-start", "scroll-snap-stop", "scrollbar-3d-light-color",
"scrollbar-arrow-color", "scrollbar-base-color", "scrollbar-dark-shadow-color",
"scrollbar-face-color", "scrollbar-highlight-color", "scrollbar-shadow-color",
"scrollbar-track-color", "searchfield-cancel-button", "searchfield-decoration",
"searchfield-results-button", "searchfield-results-decoration", "shape-inside", "zoom"
], nonStandardPropertyKeywords = keySet(nonStandardPropertyKeywords_);
var fontProperties_ = [
"font-display", "font-family", "src", "unicode-range", "font-variant",
"font-feature-settings", "font-stretch", "font-weight", "font-style"
], fontProperties = keySet(fontProperties_);
var counterDescriptors_ = [
"additive-symbols", "fallback", "negative", "pad", "prefix", "range",
"speak-as", "suffix", "symbols", "system"
], counterDescriptors = keySet(counterDescriptors_);
var colorKeywords_ = [
"aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige",
"bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown",
"burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue",
"cornsilk", "crimson", "cyan", "darkblue", "darkcyan", "darkgoldenrod",
"darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen",
"darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen",
"darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet",
"deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "firebrick",
"floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite",
"gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew",
"hotpink", "indianred", "indigo", "ivory", "khaki", "lavender",
"lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral",
"lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink",
"lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey",
"lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta",
"maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple",
"mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise",
"mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin",
"navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered",
"orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred",
"papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue",
"purple", "rebeccapurple", "red", "rosybrown", "royalblue", "saddlebrown",
"salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue",
"slateblue", "slategray", "slategrey", "snow", "springgreen", "steelblue", "tan",
"teal", "thistle", "tomato", "turquoise", "violet", "wheat", "white",
"whitesmoke", "yellow", "yellowgreen"
], colorKeywords = keySet(colorKeywords_);
var valueKeywords_ = [
"above", "absolute", "activeborder", "additive", "activecaption", "afar",
"after-white-space", "ahead", "alias", "all", "all-scroll", "alphabetic", "alternate",
"always", "amharic", "amharic-abegede", "antialiased", "appworkspace",
"arabic-indic", "armenian", "asterisks", "attr", "auto", "auto-flow", "avoid", "avoid-column", "avoid-page",
"avoid-region", "axis-pan", "background", "backwards", "baseline", "below", "bidi-override", "binary",
"bengali", "blink", "block", "block-axis", "blur", "bold", "bolder", "border", "border-box",
"both", "bottom", "break", "break-all", "break-word", "brightness", "bullets", "button",
"buttonface", "buttonhighlight", "buttonshadow", "buttontext", "calc", "cambodian",
"capitalize", "caps-lock-indicator", "caption", "captiontext", "caret",
"cell", "center", "checkbox", "circle", "cjk-decimal", "cjk-earthly-branch",
"cjk-heavenly-stem", "cjk-ideographic", "clear", "clip", "close-quote",
"col-resize", "collapse", "color", "color-burn", "color-dodge", "column", "column-reverse",
"compact", "condensed", "conic-gradient", "contain", "content", "contents",
"content-box", "context-menu", "continuous", "contrast", "copy", "counter", "counters", "cover", "crop",
"cross", "crosshair", "cubic-bezier", "currentcolor", "cursive", "cyclic", "darken", "dashed", "decimal",
"decimal-leading-zero", "default", "default-button", "dense", "destination-atop",
"destination-in", "destination-out", "destination-over", "devanagari", "difference",
"disc", "discard", "disclosure-closed", "disclosure-open", "document",
"dot-dash", "dot-dot-dash",
"dotted", "double", "down", "drop-shadow", "e-resize", "ease", "ease-in", "ease-in-out", "ease-out",
"element", "ellipse", "ellipsis", "embed", "end", "ethiopic", "ethiopic-abegede",
"ethiopic-abegede-am-et", "ethiopic-abegede-gez", "ethiopic-abegede-ti-er",
"ethiopic-abegede-ti-et", "ethiopic-halehame-aa-er",
"ethiopic-halehame-aa-et", "ethiopic-halehame-am-et",
"ethiopic-halehame-gez", "ethiopic-halehame-om-et",
"ethiopic-halehame-sid-et", "ethiopic-halehame-so-et",
"ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et", "ethiopic-halehame-tig",
"ethiopic-numeric", "ew-resize", "exclusion", "expanded", "extends", "extra-condensed",
"extra-expanded", "fantasy", "fast", "fill", "fill-box", "fixed", "flat", "flex", "flex-end", "flex-start", "footnotes",
"forwards", "from", "geometricPrecision", "georgian", "grayscale", "graytext", "grid", "groove",
"gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hard-light", "hebrew",
"help", "hidden", "hide", "higher", "highlight", "highlighttext",
"hiragana", "hiragana-iroha", "horizontal", "hsl", "hsla", "hue", "hue-rotate", "icon", "ignore",
"inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite",
"infobackground", "infotext", "inherit", "initial", "inline", "inline-axis",
"inline-block", "inline-flex", "inline-grid", "inline-table", "inset", "inside", "intrinsic", "invert",
"italic", "japanese-formal", "japanese-informal", "justify", "kannada",
"katakana", "katakana-iroha", "keep-all", "khmer",
"korean-hangul-formal", "korean-hanja-formal", "korean-hanja-informal",
"landscape", "lao", "large", "larger", "left", "level", "lighter", "lighten",
"line-through", "linear", "linear-gradient", "lines", "list-item", "listbox", "listitem",
"local", "logical", "loud", "lower", "lower-alpha", "lower-armenian",
"lower-greek", "lower-hexadecimal", "lower-latin", "lower-norwegian",
"lower-roman", "lowercase", "ltr", "luminosity", "malayalam", "manipulation", "match", "matrix", "matrix3d",
"media-play-button", "media-slider", "media-sliderthumb",
"media-volume-slider", "media-volume-sliderthumb", "medium",
"menu", "menulist", "menulist-button",
"menutext", "message-box", "middle", "min-intrinsic",
"mix", "mongolian", "monospace", "move", "multiple", "multiple_mask_images", "multiply", "myanmar", "n-resize",
"narrower", "ne-resize", "nesw-resize", "no-close-quote", "no-drop",
"no-open-quote", "no-repeat", "none", "normal", "not-allowed", "nowrap",
"ns-resize", "numbers", "numeric", "nw-resize", "nwse-resize", "oblique", "octal", "opacity", "open-quote",
"optimizeLegibility", "optimizeSpeed", "oriya", "oromo", "outset",
"outside", "outside-shape", "overlay", "overline", "padding", "padding-box",
"painted", "page", "paused", "persian", "perspective", "pinch-zoom", "plus-darker", "plus-lighter",
"pointer", "polygon", "portrait", "pre", "pre-line", "pre-wrap", "preserve-3d",
"progress", "push-button", "radial-gradient", "radio", "read-only",
"read-write", "read-write-plaintext-only", "rectangle", "region",
"relative", "repeat", "repeating-linear-gradient", "repeating-radial-gradient",
"repeating-conic-gradient", "repeat-x", "repeat-y", "reset", "reverse",
"rgb", "rgba", "ridge", "right", "rotate", "rotate3d", "rotateX", "rotateY",
"rotateZ", "round", "row", "row-resize", "row-reverse", "rtl", "run-in", "running",
"s-resize", "sans-serif", "saturate", "saturation", "scale", "scale3d", "scaleX", "scaleY", "scaleZ", "screen",
"scroll", "scrollbar", "scroll-position", "se-resize", "searchfield",
"searchfield-cancel-button", "searchfield-decoration",
"searchfield-results-button", "searchfield-results-decoration", "self-start", "self-end",
"semi-condensed", "semi-expanded", "separate", "sepia", "serif", "show", "sidama",
"simp-chinese-formal", "simp-chinese-informal", "single",
"skew", "skewX", "skewY", "skip-white-space", "slide", "slider-horizontal",
"slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow",
"small", "small-caps", "small-caption", "smaller", "soft-light", "solid", "somali",
"source-atop", "source-in", "source-out", "source-over", "space", "space-around", "space-between", "space-evenly", "spell-out", "square",
"square-button", "start", "static", "status-bar", "stretch", "stroke", "stroke-box", "sub",
"subpixel-antialiased", "svg_masks", "super", "sw-resize", "symbolic", "symbols", "system-ui", "table",
"table-caption", "table-cell", "table-column", "table-column-group",
"table-footer-group", "table-header-group", "table-row", "table-row-group",
"tamil",
"telugu", "text", "text-bottom", "text-top", "textarea", "textfield", "thai",
"thick", "thin", "threeddarkshadow", "threedface", "threedhighlight",
"threedlightshadow", "threedshadow", "tibetan", "tigre", "tigrinya-er",
"tigrinya-er-abegede", "tigrinya-et", "tigrinya-et-abegede", "to", "top",
"trad-chinese-formal", "trad-chinese-informal", "transform",
"translate", "translate3d", "translateX", "translateY", "translateZ",
"transparent", "ultra-condensed", "ultra-expanded", "underline", "unidirectional-pan", "unset", "up",
"upper-alpha", "upper-armenian", "upper-greek", "upper-hexadecimal",
"upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url",
"var", "vertical", "vertical-text", "view-box", "visible", "visibleFill", "visiblePainted",
"visibleStroke", "visual", "w-resize", "wait", "wave", "wider",
"window", "windowframe", "windowtext", "words", "wrap", "wrap-reverse", "x-large", "x-small", "xor",
"xx-large", "xx-small"
], valueKeywords = keySet(valueKeywords_);
var allWords = documentTypes_.concat(mediaTypes_).concat(mediaFeatures_).concat(mediaValueKeywords_)
.concat(propertyKeywords_).concat(nonStandardPropertyKeywords_).concat(colorKeywords_)
.concat(valueKeywords_);
CodeMirror.registerHelper("hintWords", "css", allWords);
function tokenCComment(stream, state) {
var maybeEnd = false, ch;
while ((ch = stream.next()) != null) {
if (maybeEnd && ch == "/") {
state.tokenize = null;
break;
}
maybeEnd = (ch == "*");
}
return ["comment", "comment"];
}
CodeMirror.defineMIME("text/css", {
documentTypes: documentTypes,
mediaTypes: mediaTypes,
mediaFeatures: mediaFeatures,
mediaValueKeywords: mediaValueKeywords,
propertyKeywords: propertyKeywords,
nonStandardPropertyKeywords: nonStandardPropertyKeywords,
fontProperties: fontProperties,
counterDescriptors: counterDescriptors,
colorKeywords: colorKeywords,
valueKeywords: valueKeywords,
tokenHooks: {
"/": function(stream, state) {
if (!stream.eat("*")) return false;
state.tokenize = tokenCComment;
return tokenCComment(stream, state);
}
},
name: "css"
});
CodeMirror.defineMIME("text/x-scss", {
mediaTypes: mediaTypes,
mediaFeatures: mediaFeatures,
mediaValueKeywords: mediaValueKeywords,
propertyKeywords: propertyKeywords,
nonStandardPropertyKeywords: nonStandardPropertyKeywords,
colorKeywords: colorKeywords,
valueKeywords: valueKeywords,
fontProperties: fontProperties,
allowNested: true,
lineComment: "//",
tokenHooks: {
"/": function(stream, state) {
if (stream.eat("/")) {
stream.skipToEnd();
return ["comment", "comment"];
} else if (stream.eat("*")) {
state.tokenize = tokenCComment;
return tokenCComment(stream, state);
} else {
return ["operator", "operator"];
}
},
":": function(stream) {
if (stream.match(/^\s*\{/, false))
return [null, null]
return false;
},
"$": function(stream) {
stream.match(/^[\w-]+/);
if (stream.match(/^\s*:/, false))
return ["variable-2", "variable-definition"];
return ["variable-2", "variable"];
},
"#": function(stream) {
if (!stream.eat("{")) return false;
return [null, "interpolation"];
}
},
name: "css",
helperType: "scss"
});
CodeMirror.defineMIME("text/x-less", {
mediaTypes: mediaTypes,
mediaFeatures: mediaFeatures,
mediaValueKeywords: mediaValueKeywords,
propertyKeywords: propertyKeywords,
nonStandardPropertyKeywords: nonStandardPropertyKeywords,
colorKeywords: colorKeywords,
valueKeywords: valueKeywords,
fontProperties: fontProperties,
allowNested: true,
lineComment: "//",
tokenHooks: {
"/": function(stream, state) {
if (stream.eat("/")) {
stream.skipToEnd();
return ["comment", "comment"];
} else if (stream.eat("*")) {
state.tokenize = tokenCComment;
return tokenCComment(stream, state);
} else {
return ["operator", "operator"];
}
},
"@": function(stream) {
if (stream.eat("{")) return [null, "interpolation"];
if (stream.match(/^(charset|document|font-face|import|(-(moz|ms|o|webkit)-)?keyframes|media|namespace|page|supports)\b/i, false)) return false;
stream.eatWhile(/[\w\\\-]/);
if (stream.match(/^\s*:/, false))
return ["variable-2", "variable-definition"];
return ["variable-2", "variable"];
},
"&": function() {
return ["atom", "atom"];
}
},
name: "css",
helperType: "less"
});
CodeMirror.defineMIME("text/x-gss", {
documentTypes: documentTypes,
mediaTypes: mediaTypes,
mediaFeatures: mediaFeatures,
propertyKeywords: propertyKeywords,
nonStandardPropertyKeywords: nonStandardPropertyKeywords,
fontProperties: fontProperties,
counterDescriptors: counterDescriptors,
colorKeywords: colorKeywords,
valueKeywords: valueKeywords,
supportsAtComponent: true,
tokenHooks: {
"/": function(stream, state) {
if (!stream.eat("*")) return false;
state.tokenize = tokenCComment;
return tokenCComment(stream, state);
}
},
name: "css",
helperType: "gss"
});
});
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/5/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../lib/codemirror"), require("./xml"), require("./javascript"), require("./css"));
else if (typeof define == "function" && define.amd) // AMD
define(["../lib/codemirror", "./xml", "./javascript", "./css"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
var defaultTags = {
script: [
["lang", /(javascript|babel)/i, "javascript"],
["type", /^(?:text|application)\/(?:x-)?(?:java|ecma)script$|^module$|^$/i, "javascript"],
["type", /./, "text/plain"],
[null, null, "javascript"]
],
style: [
["lang", /^css$/i, "css"],
["type", /^(text\/)?(x-)?(stylesheet|css)$/i, "css"],
["type", /./, "text/plain"],
[null, null, "css"]
]
};
function maybeBackup(stream, pat, style) {
var cur = stream.current(), close = cur.search(pat);
if (close > -1) {
stream.backUp(cur.length - close);
} else if (cur.match(/<\/?$/)) {
stream.backUp(cur.length);
if (!stream.match(pat, false)) stream.match(cur);
}
return style;
}
var attrRegexpCache = {};
function getAttrRegexp(attr) {
var regexp = attrRegexpCache[attr];
if (regexp) return regexp;
return attrRegexpCache[attr] = new RegExp("\\s+" + attr + "\\s*=\\s*('|\")?([^'\"]+)('|\")?\\s*");
}
function getAttrValue(text, attr) {
var match = text.match(getAttrRegexp(attr))
return match ? /^\s*(.*?)\s*$/.exec(match[2])[1] : ""
}
function getTagRegexp(tagName, anchored) {
return new RegExp((anchored ? "^" : "") + "<\/\\s*" + tagName + "\\s*>", "i");
}
function addTags(from, to) {
for (var tag in from) {
var dest = to[tag] || (to[tag] = []);
var source = from[tag];
for (var i = source.length - 1; i >= 0; i--)
dest.unshift(source[i])
}
}
function findMatchingMode(tagInfo, tagText) {
for (var i = 0; i < tagInfo.length; i++) {
var spec = tagInfo[i];
if (!spec[0] || spec[1].test(getAttrValue(tagText, spec[0]))) return spec[2];
}
}
CodeMirror.defineMode("htmlmixed", function (config, parserConfig) {
var htmlMode = CodeMirror.getMode(config, {
name: "xml",
htmlMode: true,
multilineTagIndentFactor: parserConfig.multilineTagIndentFactor,
multilineTagIndentPastTag: parserConfig.multilineTagIndentPastTag,
allowMissingTagName: parserConfig.allowMissingTagName,
});
var tags = {};
var configTags = parserConfig && parserConfig.tags, configScript = parserConfig && parserConfig.scriptTypes;
addTags(defaultTags, tags);
if (configTags) addTags(configTags, tags);
if (configScript) for (var i = configScript.length - 1; i >= 0; i--)
tags.script.unshift(["type", configScript[i].matches, configScript[i].mode])
function html(stream, state) {
var style = htmlMode.token(stream, state.htmlState), tag = /\btag\b/.test(style), tagName
if (tag && !/[<>\s\/]/.test(stream.current()) &&
(tagName = state.htmlState.tagName && state.htmlState.tagName.toLowerCase()) &&
tags.hasOwnProperty(tagName)) {
state.inTag = tagName + " "
} else if (state.inTag && tag && />$/.test(stream.current())) {
var inTag = /^([\S]+) (.*)/.exec(state.inTag)
state.inTag = null
var modeSpec = stream.current() == ">" && findMatchingMode(tags[inTag[1]], inTag[2])
var mode = CodeMirror.getMode(config, modeSpec)
var endTagA = getTagRegexp(inTag[1], true), endTag = getTagRegexp(inTag[1], false);
state.token = function (stream, state) {
if (stream.match(endTagA, false)) {
state.token = html;
state.localState = state.localMode = null;
return null;
}
return maybeBackup(stream, endTag, state.localMode.token(stream, state.localState));
};
state.localMode = mode;
state.localState = CodeMirror.startState(mode, htmlMode.indent(state.htmlState, "", ""));
} else if (state.inTag) {
state.inTag += stream.current()
if (stream.eol()) state.inTag += " "
}
return style;
};
return {
startState: function () {
var state = CodeMirror.startState(htmlMode);
return {token: html, inTag: null, localMode: null, localState: null, htmlState: state};
},
copyState: function (state) {
var local;
if (state.localState) {
local = CodeMirror.copyState(state.localMode, state.localState);
}
return {token: state.token, inTag: state.inTag,
localMode: state.localMode, localState: local,
htmlState: CodeMirror.copyState(htmlMode, state.htmlState)};
},
token: function (stream, state) {
return state.token(stream, state);
},
indent: function (state, textAfter, line) {
if (!state.localMode || /^\s*<\//.test(textAfter))
return htmlMode.indent(state.htmlState, textAfter, line);
else if (state.localMode.indent)
return state.localMode.indent(state.localState, textAfter, line);
else
return CodeMirror.Pass;
},
innerMode: function (state) {
return {state: state.localState || state.htmlState, mode: state.localMode || htmlMode};
}
};
}, "xml", "javascript", "css");
CodeMirror.defineMIME("text/html", "htmlmixed");
});
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/5/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.defineMode("javascript", function(config, parserConfig) {
var indentUnit = config.indentUnit;
var statementIndent = parserConfig.statementIndent;
var jsonldMode = parserConfig.jsonld;
var jsonMode = parserConfig.json || jsonldMode;
var trackScope = parserConfig.trackScope !== false
var isTS = parserConfig.typescript;
var wordRE = parserConfig.wordCharacters || /[\w$\xa1-\uffff]/;
// Tokenizer
var keywords = function(){
function kw(type) {return {type: type, style: "keyword"};}
var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c"), D = kw("keyword d");
var operator = kw("operator"), atom = {type: "atom", style: "atom"};
return {
"if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B,
"return": D, "break": D, "continue": D, "new": kw("new"), "delete": C, "void": C, "throw": C,
"debugger": kw("debugger"), "var": kw("var"), "const": kw("var"), "let": kw("var"),
"function": kw("function"), "catch": kw("catch"),
"for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
"in": operator, "typeof": operator, "instanceof": operator,
"true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom,
"this": kw("this"), "class": kw("class"), "super": kw("atom"),
"yield": C, "export": kw("export"), "import": kw("import"), "extends": C,
"await": C
};
}();
var isOperatorChar = /[+\-*&%=<>!?|~^@]/;
var isJsonldKeyword = /^@(context|id|value|language|type|container|list|set|reverse|index|base|vocab|graph)"/;
function readRegexp(stream) {
var escaped = false, next, inSet = false;
while ((next = stream.next()) != null) {
if (!escaped) {
if (next == "/" && !inSet) return;
if (next == "[") inSet = true;
else if (inSet && next == "]") inSet = false;
}
escaped = !escaped && next == "\\";
}
}
// Used as scratch variables to communicate multiple values without
// consing up tons of objects.
var type, content;
function ret(tp, style, cont) {
type = tp; content = cont;
return style;
}
function tokenBase(stream, state) {
var ch = stream.next();
if (ch == '"' || ch == "'") {
state.tokenize = tokenString(ch);
return state.tokenize(stream, state);
} else if (ch == "." && stream.match(/^\d[\d_]*(?:[eE][+\-]?[\d_]+)?/)) {
return ret("number", "number");
} else if (ch == "." && stream.match("..")) {
return ret("spread", "meta");
} else if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
return ret(ch);
} else if (ch == "=" && stream.eat(">")) {
return ret("=>", "operator");
} else if (ch == "0" && stream.match(/^(?:x[\dA-Fa-f_]+|o[0-7_]+|b[01_]+)n?/)) {
return ret("number", "number");
} else if (/\d/.test(ch)) {
stream.match(/^[\d_]*(?:n|(?:\.[\d_]*)?(?:[eE][+\-]?[\d_]+)?)?/);
return ret("number", "number");
} else if (ch == "/") {
if (stream.eat("*")) {
state.tokenize = tokenComment;
return tokenComment(stream, state);
} else if (stream.eat("/")) {
stream.skipToEnd();
return ret("comment", "comment");
} else if (expressionAllowed(stream, state, 1)) {
readRegexp(stream);
stream.match(/^\b(([gimyus])(?![gimyus]*\2))+\b/);
return ret("regexp", "string-2");
} else {
stream.eat("=");
return ret("operator", "operator", stream.current());
}
} else if (ch == "`") {
state.tokenize = tokenQuasi;
return tokenQuasi(stream, state);
} else if (ch == "#" && stream.peek() == "!") {
stream.skipToEnd();
return ret("meta", "meta");
} else if (ch == "#" && stream.eatWhile(wordRE)) {
return ret("variable", "property")
} else if (ch == "<" && stream.match("!--") ||
(ch == "-" && stream.match("->") && !/\S/.test(stream.string.slice(0, stream.start)))) {
stream.skipToEnd()
return ret("comment", "comment")
} else if (isOperatorChar.test(ch)) {
if (ch != ">" || !state.lexical || state.lexical.type != ">") {
if (stream.eat("=")) {
if (ch == "!" || ch == "=") stream.eat("=")
} else if (/[<>*+\-|&?]/.test(ch)) {
stream.eat(ch)
if (ch == ">") stream.eat(ch)
}
}
if (ch == "?" && stream.eat(".")) return ret(".")
return ret("operator", "operator", stream.current());
} else if (wordRE.test(ch)) {
stream.eatWhile(wordRE);
var word = stream.current()
if (state.lastType != ".") {
if (keywords.propertyIsEnumerable(word)) {
var kw = keywords[word]
return ret(kw.type, kw.style, word)
}
if (word == "async" && stream.match(/^(\s|\/\*([^*]|\*(?!\/))*?\*\/)*[\[\(\w]/, false))
return ret("async", "keyword", word)
}
return ret("variable", "variable", word)
}
}
function tokenString(quote) {
return function(stream, state) {
var escaped = false, next;
if (jsonldMode && stream.peek() == "@" && stream.match(isJsonldKeyword)){
state.tokenize = tokenBase;
return ret("jsonld-keyword", "meta");
}
while ((next = stream.next()) != null) {
if (next == quote && !escaped) break;
escaped = !escaped && next == "\\";
}
if (!escaped) state.tokenize = tokenBase;
return ret("string", "string");
};
}
function tokenComment(stream, state) {
var maybeEnd = false, ch;
while (ch = stream.next()) {
if (ch == "/" && maybeEnd) {
state.tokenize = tokenBase;
break;
}
maybeEnd = (ch == "*");
}
return ret("comment", "comment");
}
function tokenQuasi(stream, state) {
var escaped = false, next;
while ((next = stream.next()) != null) {
if (!escaped && (next == "`" || next == "$" && stream.eat("{"))) {
state.tokenize = tokenBase;
break;
}
escaped = !escaped && next == "\\";
}
return ret("quasi", "string-2", stream.current());
}
var brackets = "([{}])";
// This is a crude lookahead trick to try and notice that we're
// parsing the argument patterns for a fat-arrow function before we
// actually hit the arrow token. It only works if the arrow is on
// the same line as the arguments and there's no strange noise
// (comments) in between. Fallback is to only notice when we hit the
// arrow, and not declare the arguments as locals for the arrow
// body.
function findFatArrow(stream, state) {
if (state.fatArrowAt) state.fatArrowAt = null;
var arrow = stream.string.indexOf("=>", stream.start);
if (arrow < 0) return;
if (isTS) { // Try to skip TypeScript return type declarations after the arguments
var m = /:\s*(?:\w+(?:<[^>]*>|\[\])?|\{[^}]*\})\s*$/.exec(stream.string.slice(stream.start, arrow))
if (m) arrow = m.index
}
var depth = 0, sawSomething = false;
for (var pos = arrow - 1; pos >= 0; --pos) {
var ch = stream.string.charAt(pos);
var bracket = brackets.indexOf(ch);
if (bracket >= 0 && bracket < 3) {
if (!depth) { ++pos; break; }
if (--depth == 0) { if (ch == "(") sawSomething = true; break; }
} else if (bracket >= 3 && bracket < 6) {
++depth;
} else if (wordRE.test(ch)) {
sawSomething = true;
} else if (/["'\/`]/.test(ch)) {
for (;; --pos) {
if (pos == 0) return
var next = stream.string.charAt(pos - 1)
if (next == ch && stream.string.charAt(pos - 2) != "\\") { pos--; break }
}
} else if (sawSomething && !depth) {
++pos;
break;
}
}
if (sawSomething && !depth) state.fatArrowAt = pos;
}
// Parser
var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true,
"regexp": true, "this": true, "import": true, "jsonld-keyword": true};
function JSLexical(indented, column, type, align, prev, info) {
this.indented = indented;
this.column = column;
this.type = type;
this.prev = prev;
this.info = info;
if (align != null) this.align = align;
}
function inScope(state, varname) {
if (!trackScope) return false
for (var v = state.localVars; v; v = v.next)
if (v.name == varname) return true;
for (var cx = state.context; cx; cx = cx.prev) {
for (var v = cx.vars; v; v = v.next)
if (v.name == varname) return true;
}
}
function parseJS(state, style, type, content, stream) {
var cc = state.cc;
// Communicate our context to the combinators.
// (Less wasteful than consing up a hundred closures on every call.)
cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc; cx.style = style;
if (!state.lexical.hasOwnProperty("align"))
state.lexical.align = true;
while(true) {
var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement;
if (combinator(type, content)) {
while(cc.length && cc[cc.length - 1].lex)
cc.pop()();
if (cx.marked) return cx.marked;
if (type == "variable" && inScope(state, content)) return "variable-2";
return style;
}
}
}
// Combinator utils
var cx = {state: null, column: null, marked: null, cc: null};
function pass() {
for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]);
}
function cont() {
pass.apply(null, arguments);
return true;
}
function inList(name, list) {
for (var v = list; v; v = v.next) if (v.name == name) return true
return false;
}
function register(varname) {
var state = cx.state;
cx.marked = "def";
if (!trackScope) return
if (state.context) {
if (state.lexical.info == "var" && state.context && state.context.block) {
// FIXME function decls are also not block scoped
var newContext = registerVarScoped(varname, state.context)
if (newContext != null) {
state.context = newContext
return
}
} else if (!inList(varname, state.localVars)) {
state.localVars = new Var(varname, state.localVars)
return
}
}
// Fall through means this is global
if (parserConfig.globalVars && !inList(varname, state.globalVars))
state.globalVars = new Var(varname, state.globalVars)
}
function registerVarScoped(varname, context) {
if (!context) {
return null
} else if (context.block) {
var inner = registerVarScoped(varname, context.prev)
if (!inner) return null
if (inner == context.prev) return context
return new Context(inner, context.vars, true)
} else if (inList(varname, context.vars)) {
return context
} else {
return new Context(context.prev, new Var(varname, context.vars), false)
}
}
function isModifier(name) {
return name == "public" || name == "private" || name == "protected" || name == "abstract" || name == "readonly"
}
// Combinators
function Context(prev, vars, block) { this.prev = prev; this.vars = vars; this.block = block }
function Var(name, next) { this.name = name; this.next = next }
var defaultVars = new Var("this", new Var("arguments", null))
function pushcontext() {
cx.state.context = new Context(cx.state.context, cx.state.localVars, false)
cx.state.localVars = defaultVars
}
function pushblockcontext() {
cx.state.context = new Context(cx.state.context, cx.state.localVars, true)
cx.state.localVars = null
}
pushcontext.lex = pushblockcontext.lex = true
function popcontext() {
cx.state.localVars = cx.state.context.vars
cx.state.context = cx.state.context.prev
}
popcontext.lex = true
function pushlex(type, info) {
var result = function() {
var state = cx.state, indent = state.indented;
if (state.lexical.type == "stat") indent = state.lexical.indented;
else for (var outer = state.lexical; outer && outer.type == ")" && outer.align; outer = outer.prev)
indent = outer.indented;
state.lexical = new JSLexical(indent, cx.stream.column(), type, null, state.lexical, info);
};
result.lex = true;
return result;
}
function poplex() {
var state = cx.state;
if (state.lexical.prev) {
if (state.lexical.type == ")")
state.indented = state.lexical.indented;
state.lexical = state.lexical.prev;
}
}
poplex.lex = true;
function expect(wanted) {
function exp(type) {
if (type == wanted) return cont();
else if (wanted == ";" || type == "}" || type == ")" || type == "]") return pass();
else return cont(exp);
};
return exp;
}
function statement(type, value) {
if (type == "var") return cont(pushlex("vardef", value), vardef, expect(";"), poplex);
if (type == "keyword a") return cont(pushlex("form"), parenExpr, statement, poplex);
if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
if (type == "keyword d") return cx.stream.match(/^\s*$/, false) ? cont() : cont(pushlex("stat"), maybeexpression, expect(";"), poplex);
if (type == "debugger") return cont(expect(";"));
if (type == "{") return cont(pushlex("}"), pushblockcontext, block, poplex, popcontext);
if (type == ";") return cont();
if (type == "if") {
if (cx.state.lexical.info == "else" && cx.state.cc[cx.state.cc.length - 1] == poplex)
cx.state.cc.pop()();
return cont(pushlex("form"), parenExpr, statement, poplex, maybeelse);
}
if (type == "function") return cont(functiondef);
if (type == "for") return cont(pushlex("form"), pushblockcontext, forspec, statement, popcontext, poplex);
if (type == "class" || (isTS && value == "interface")) {
cx.marked = "keyword"
return cont(pushlex("form", type == "class" ? type : value), className, poplex)
}
if (type == "variable") {
if (isTS && value == "declare") {
cx.marked = "keyword"
return cont(statement)
} else if (isTS && (value == "module" || value == "enum" || value == "type") && cx.stream.match(/^\s*\w/, false)) {
cx.marked = "keyword"
if (value == "enum") return cont(enumdef);
else if (value == "type") return cont(typename, expect("operator"), typeexpr, expect(";"));
else return cont(pushlex("form"), pattern, expect("{"), pushlex("}"), block, poplex, poplex)
} else if (isTS && value == "namespace") {
cx.marked = "keyword"
return cont(pushlex("form"), expression, statement, poplex)
} else if (isTS && value == "abstract") {
cx.marked = "keyword"
return cont(statement)
} else {
return cont(pushlex("stat"), maybelabel);
}
}
if (type == "switch") return cont(pushlex("form"), parenExpr, expect("{"), pushlex("}", "switch"), pushblockcontext,
block, poplex, poplex, popcontext);
if (type == "case") return cont(expression, expect(":"));
if (type == "default") return cont(expect(":"));
if (type == "catch") return cont(pushlex("form"), pushcontext, maybeCatchBinding, statement, poplex, popcontext);
if (type == "export") return cont(pushlex("stat"), afterExport, poplex);
if (type == "import") return cont(pushlex("stat"), afterImport, poplex);
if (type == "async") return cont(statement)
if (value == "@") return cont(expression, statement)
return pass(pushlex("stat"), expression, expect(";"), poplex);
}
function maybeCatchBinding(type) {
if (type == "(") return cont(funarg, expect(")"))
}
function expression(type, value) {
return expressionInner(type, value, false);
}
function expressionNoComma(type, value) {
return expressionInner(type, value, true);
}
function parenExpr(type) {
if (type != "(") return pass()
return cont(pushlex(")"), maybeexpression, expect(")"), poplex)
}
function expressionInner(type, value, noComma) {
if (cx.state.fatArrowAt == cx.stream.start) {
var body = noComma ? arrowBodyNoComma : arrowBody;
if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, expect("=>"), body, popcontext);
else if (type == "variable") return pass(pushcontext, pattern, expect("=>"), body, popcontext);
}
var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma;
if (atomicTypes.hasOwnProperty(type)) return cont(maybeop);
if (type == "function") return cont(functiondef, maybeop);
if (type == "class" || (isTS && value == "interface")) { cx.marked = "keyword"; return cont(pushlex("form"), classExpression, poplex); }
if (type == "keyword c" || type == "async") return cont(noComma ? expressionNoComma : expression);
if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeop);
if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression);
if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop);
if (type == "{") return contCommasep(objprop, "}", null, maybeop);
if (type == "quasi") return pass(quasi, maybeop);
if (type == "new") return cont(maybeTarget(noComma));
return cont();
}
function maybeexpression(type) {
if (type.match(/[;\}\)\],]/)) return pass();
return pass(expression);
}
function maybeoperatorComma(type, value) {
if (type == ",") return cont(maybeexpression);
return maybeoperatorNoComma(type, value, false);
}
function maybeoperatorNoComma(type, value, noComma) {
var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma;
var expr = noComma == false ? expression : expressionNoComma;
if (type == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext);
if (type == "operator") {
if (/\+\+|--/.test(value) || isTS && value == "!") return cont(me);
if (isTS && value == "<" && cx.stream.match(/^([^<>]|<[^<>]*>)*>\s*\(/, false))
return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, me);
if (value == "?") return cont(expression, expect(":"), expr);
return cont(expr);
}
if (type == "quasi") { return pass(quasi, me); }
if (type == ";") return;
if (type == "(") return contCommasep(expressionNoComma, ")", "call", me);
if (type == ".") return cont(property, me);
if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), poplex, me);
if (isTS && value == "as") { cx.marked = "keyword"; return cont(typeexpr, me) }
if (type == "regexp") {
cx.state.lastType = cx.marked = "operator"
cx.stream.backUp(cx.stream.pos - cx.stream.start - 1)
return cont(expr)
}
}
function quasi(type, value) {
if (type != "quasi") return pass();
if (value.slice(value.length - 2) != "${") return cont(quasi);
return cont(maybeexpression, continueQuasi);
}
function continueQuasi(type) {
if (type == "}") {
cx.marked = "string-2";
cx.state.tokenize = tokenQuasi;
return cont(quasi);
}
}
function arrowBody(type) {
findFatArrow(cx.stream, cx.state);
return pass(type == "{" ? statement : expression);
}
function arrowBodyNoComma(type) {
findFatArrow(cx.stream, cx.state);
return pass(type == "{" ? statement : expressionNoComma);
}
function maybeTarget(noComma) {
return function(type) {
if (type == ".") return cont(noComma ? targetNoComma : target);
else if (type == "variable" && isTS) return cont(maybeTypeArgs, noComma ? maybeoperatorNoComma : maybeoperatorComma)
else return pass(noComma ? expressionNoComma : expression);
};
}
function target(_, value) {
if (value == "target") { cx.marked = "keyword"; return cont(maybeoperatorComma); }
}
function targetNoComma(_, value) {
if (value == "target") { cx.marked = "keyword"; return cont(maybeoperatorNoComma); }
}
function maybelabel(type) {
if (type == ":") return cont(poplex, statement);
return pass(maybeoperatorComma, expect(";"), poplex);
}
function property(type) {
if (type == "variable") {cx.marked = "property"; return cont();}
}
function objprop(type, value) {
if (type == "async") {
cx.marked = "property";
return cont(objprop);
} else if (type == "variable" || cx.style == "keyword") {
cx.marked = "property";
if (value == "get" || value == "set") return cont(getterSetter);
var m // Work around fat-arrow-detection complication for detecting typescript typed arrow params
if (isTS && cx.state.fatArrowAt == cx.stream.start && (m = cx.stream.match(/^\s*:\s*/, false)))
cx.state.fatArrowAt = cx.stream.pos + m[0].length
return cont(afterprop);
} else if (type == "number" || type == "string") {
cx.marked = jsonldMode ? "property" : (cx.style + " property");
return cont(afterprop);
} else if (type == "jsonld-keyword") {
return cont(afterprop);
} else if (isTS && isModifier(value)) {
cx.marked = "keyword"
return cont(objprop)
} else if (type == "[") {
return cont(expression, maybetype, expect("]"), afterprop);
} else if (type == "spread") {
return cont(expressionNoComma, afterprop);
} else if (value == "*") {
cx.marked = "keyword";
return cont(objprop);
} else if (type == ":") {
return pass(afterprop)
}
}
function getterSetter(type) {
if (type != "variable") return pass(afterprop);
cx.marked = "property";
return cont(functiondef);
}
function afterprop(type) {
if (type == ":") return cont(expressionNoComma);
if (type == "(") return pass(functiondef);
}
function commasep(what, end, sep) {
function proceed(type, value) {
if (sep ? sep.indexOf(type) > -1 : type == ",") {
var lex = cx.state.lexical;
if (lex.info == "call") lex.pos = (lex.pos || 0) + 1;
return cont(function(type, value) {
if (type == end || value == end) return pass()
return pass(what)
}, proceed);
}
if (type == end || value == end) return cont();
if (sep && sep.indexOf(";") > -1) return pass(what)
return cont(expect(end));
}
return function(type, value) {
if (type == end || value == end) return cont();
return pass(what, proceed);
};
}
function contCommasep(what, end, info) {
for (var i = 3; i < arguments.length; i++)
cx.cc.push(arguments[i]);
return cont(pushlex(end, info), commasep(what, end), poplex);
}
function block(type) {
if (type == "}") return cont();
return pass(statement, block);
}
function maybetype(type, value) {
if (isTS) {
if (type == ":") return cont(typeexpr);
if (value == "?") return cont(maybetype);
}
}
function maybetypeOrIn(type, value) {
if (isTS && (type == ":" || value == "in")) return cont(typeexpr)
}
function mayberettype(type) {
if (isTS && type == ":") {
if (cx.stream.match(/^\s*\w+\s+is\b/, false)) return cont(expression, isKW, typeexpr)
else return cont(typeexpr)
}
}
function isKW(_, value) {
if (value == "is") {
cx.marked = "keyword"
return cont()
}
}
function typeexpr(type, value) {
if (value == "keyof" || value == "typeof" || value == "infer" || value == "readonly") {
cx.marked = "keyword"
return cont(value == "typeof" ? expressionNoComma : typeexpr)
}
if (type == "variable" || value == "void") {
cx.marked = "type"
return cont(afterType)
}
if (value == "|" || value == "&") return cont(typeexpr)
if (type == "string" || type == "number" || type == "atom") return cont(afterType);
if (type == "[") return cont(pushlex("]"), commasep(typeexpr, "]", ","), poplex, afterType)
if (type == "{") return cont(pushlex("}"), typeprops, poplex, afterType)
if (type == "(") return cont(commasep(typearg, ")"), maybeReturnType, afterType)
if (type == "<") return cont(commasep(typeexpr, ">"), typeexpr)
if (type == "quasi") { return pass(quasiType, afterType); }
}
function maybeReturnType(type) {
if (type == "=>") return cont(typeexpr)
}
function typeprops(type) {
if (type.match(/[\}\)\]]/)) return cont()
if (type == "," || type == ";") return cont(typeprops)
return pass(typeprop, typeprops)
}
function typeprop(type, value) {
if (type == "variable" || cx.style == "keyword") {
cx.marked = "property"
return cont(typeprop)
} else if (value == "?" || type == "number" || type == "string") {
return cont(typeprop)
} else if (type == ":") {
return cont(typeexpr)
} else if (type == "[") {
return cont(expect("variable"), maybetypeOrIn, expect("]"), typeprop)
} else if (type == "(") {
return pass(functiondecl, typeprop)
} else if (!type.match(/[;\}\)\],]/)) {
return cont()
}
}
function quasiType(type, value) {
if (type != "quasi") return pass();
if (value.slice(value.length - 2) != "${") return cont(quasiType);
return cont(typeexpr, continueQuasiType);
}
function continueQuasiType(type) {
if (type == "}") {
cx.marked = "string-2";
cx.state.tokenize = tokenQuasi;
return cont(quasiType);
}
}
function typearg(type, value) {
if (type == "variable" && cx.stream.match(/^\s*[?:]/, false) || value == "?") return cont(typearg)
if (type == ":") return cont(typeexpr)
if (type == "spread") return cont(typearg)
return pass(typeexpr)
}
function afterType(type, value) {
if (value == "<") return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, afterType)
if (value == "|" || type == "." || value == "&") return cont(typeexpr)
if (type == "[") return cont(typeexpr, expect("]"), afterType)
if (value == "extends" || value == "implements") { cx.marked = "keyword"; return cont(typeexpr) }
if (value == "?") return cont(typeexpr, expect(":"), typeexpr)
}
function maybeTypeArgs(_, value) {
if (value == "<") return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, afterType)
}
function typeparam() {
return pass(typeexpr, maybeTypeDefault)
}
function maybeTypeDefault(_, value) {
if (value == "=") return cont(typeexpr)
}
function vardef(_, value) {
if (value == "enum") {cx.marked = "keyword"; return cont(enumdef)}
return pass(pattern, maybetype, maybeAssign, vardefCont);
}
function pattern(type, value) {
if (isTS && isModifier(value)) { cx.marked = "keyword"; return cont(pattern) }
if (type == "variable") { register(value); return cont(); }
if (type == "spread") return cont(pattern);
if (type == "[") return contCommasep(eltpattern, "]");
if (type == "{") return contCommasep(proppattern, "}");
}
function proppattern(type, value) {
if (type == "variable" && !cx.stream.match(/^\s*:/, false)) {
register(value);
return cont(maybeAssign);
}
if (type == "variable") cx.marked = "property";
if (type == "spread") return cont(pattern);
if (type == "}") return pass();
if (type == "[") return cont(expression, expect(']'), expect(':'), proppattern);
return cont(expect(":"), pattern, maybeAssign);
}
function eltpattern() {
return pass(pattern, maybeAssign)
}
function maybeAssign(_type, value) {
if (value == "=") return cont(expressionNoComma);
}
function vardefCont(type) {
if (type == ",") return cont(vardef);
}
function maybeelse(type, value) {
if (type == "keyword b" && value == "else") return cont(pushlex("form", "else"), statement, poplex);
}
function forspec(type, value) {
if (value == "await") return cont(forspec);
if (type == "(") return cont(pushlex(")"), forspec1, poplex);
}
function forspec1(type) {
if (type == "var") return cont(vardef, forspec2);
if (type == "variable") return cont(forspec2);
return pass(forspec2)
}
function forspec2(type, value) {
if (type == ")") return cont()
if (type == ";") return cont(forspec2)
if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression, forspec2) }
return pass(expression, forspec2)
}
function functiondef(type, value) {
if (value == "*") {cx.marked = "keyword"; return cont(functiondef);}
if (type == "variable") {register(value); return cont(functiondef);}
if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, mayberettype, statement, popcontext);
if (isTS && value == "<") return cont(pushlex(">"), commasep(typeparam, ">"), poplex, functiondef)
}
function functiondecl(type, value) {
if (value == "*") {cx.marked = "keyword"; return cont(functiondecl);}
if (type == "variable") {register(value); return cont(functiondecl);}
if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, mayberettype, popcontext);
if (isTS && value == "<") return cont(pushlex(">"), commasep(typeparam, ">"), poplex, functiondecl)
}
function typename(type, value) {
if (type == "keyword" || type == "variable") {
cx.marked = "type"
return cont(typename)
} else if (value == "<") {
return cont(pushlex(">"), commasep(typeparam, ">"), poplex)
}
}
function funarg(type, value) {
if (value == "@") cont(expression, funarg)
if (type == "spread") return cont(funarg);
if (isTS && isModifier(value)) { cx.marked = "keyword"; return cont(funarg); }
if (isTS && type == "this") return cont(maybetype, maybeAssign)
return pass(pattern, maybetype, maybeAssign);
}
function classExpression(type, value) {
// Class expressions may have an optional name.
if (type == "variable") return className(type, value);
return classNameAfter(type, value);
}
function className(type, value) {
if (type == "variable") {register(value); return cont(classNameAfter);}
}
function classNameAfter(type, value) {
if (value == "<") return cont(pushlex(">"), commasep(typeparam, ">"), poplex, classNameAfter)
if (value == "extends" || value == "implements" || (isTS && type == ",")) {
if (value == "implements") cx.marked = "keyword";
return cont(isTS ? typeexpr : expression, classNameAfter);
}
if (type == "{") return cont(pushlex("}"), classBody, poplex);
}
function classBody(type, value) {
if (type == "async" ||
(type == "variable" &&
(value == "static" || value == "get" || value == "set" || (isTS && isModifier(value))) &&
cx.stream.match(/^\s+[\w$\xa1-\uffff]/, false))) {
cx.marked = "keyword";
return cont(classBody);
}
if (type == "variable" || cx.style == "keyword") {
cx.marked = "property";
return cont(classfield, classBody);
}
if (type == "number" || type == "string") return cont(classfield, classBody);
if (type == "[")
return cont(expression, maybetype, expect("]"), classfield, classBody)
if (value == "*") {
cx.marked = "keyword";
return cont(classBody);
}
if (isTS && type == "(") return pass(functiondecl, classBody)
if (type == ";" || type == ",") return cont(classBody);
if (type == "}") return cont();
if (value == "@") return cont(expression, classBody)
}
function classfield(type, value) {
if (value == "!") return cont(classfield)
if (value == "?") return cont(classfield)
if (type == ":") return cont(typeexpr, maybeAssign)
if (value == "=") return cont(expressionNoComma)
var context = cx.state.lexical.prev, isInterface = context && context.info == "interface"
return pass(isInterface ? functiondecl : functiondef)
}
function afterExport(type, value) {
if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";")); }
if (value == "default") { cx.marked = "keyword"; return cont(expression, expect(";")); }
if (type == "{") return cont(commasep(exportField, "}"), maybeFrom, expect(";"));
return pass(statement);
}
function exportField(type, value) {
if (value == "as") { cx.marked = "keyword"; return cont(expect("variable")); }
if (type == "variable") return pass(expressionNoComma, exportField);
}
function afterImport(type) {
if (type == "string") return cont();
if (type == "(") return pass(expression);
if (type == ".") return pass(maybeoperatorComma);
return pass(importSpec, maybeMoreImports, maybeFrom);
}
function importSpec(type, value) {
if (type == "{") return contCommasep(importSpec, "}");
if (type == "variable") register(value);
if (value == "*") cx.marked = "keyword";
return cont(maybeAs);
}
function maybeMoreImports(type) {
if (type == ",") return cont(importSpec, maybeMoreImports)
}
function maybeAs(_type, value) {
if (value == "as") { cx.marked = "keyword"; return cont(importSpec); }
}
function maybeFrom(_type, value) {
if (value == "from") { cx.marked = "keyword"; return cont(expression); }
}
function arrayLiteral(type) {
if (type == "]") return cont();
return pass(commasep(expressionNoComma, "]"));
}
function enumdef() {
return pass(pushlex("form"), pattern, expect("{"), pushlex("}"), commasep(enummember, "}"), poplex, poplex)
}
function enummember() {
return pass(pattern, maybeAssign);
}
function isContinuedStatement(state, textAfter) {
return state.lastType == "operator" || state.lastType == "," ||
isOperatorChar.test(textAfter.charAt(0)) ||
/[,.]/.test(textAfter.charAt(0));
}
function expressionAllowed(stream, state, backUp) {
return state.tokenize == tokenBase &&
/^(?:operator|sof|keyword [bcd]|case|new|export|default|spread|[\[{}\(,;:]|=>)$/.test(state.lastType) ||
(state.lastType == "quasi" && /\{\s*$/.test(stream.string.slice(0, stream.pos - (backUp || 0))))
}
// Interface
return {
startState: function(basecolumn) {
var state = {
tokenize: tokenBase,
lastType: "sof",
cc: [],
lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
localVars: parserConfig.localVars,
context: parserConfig.localVars && new Context(null, null, false),
indented: basecolumn || 0
};
if (parserConfig.globalVars && typeof parserConfig.globalVars == "object")
state.globalVars = parserConfig.globalVars;
return state;
},
token: function(stream, state) {
if (stream.sol()) {
if (!state.lexical.hasOwnProperty("align"))
state.lexical.align = false;
state.indented = stream.indentation();
findFatArrow(stream, state);
}
if (state.tokenize != tokenComment && stream.eatSpace()) return null;
var style = state.tokenize(stream, state);
if (type == "comment") return style;
state.lastType = type == "operator" && (content == "++" || content == "--") ? "incdec" : type;
return parseJS(state, style, type, content, stream);
},
indent: function(state, textAfter) {
if (state.tokenize == tokenComment || state.tokenize == tokenQuasi) return CodeMirror.Pass;
if (state.tokenize != tokenBase) return 0;
var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical, top
// Kludge to prevent 'maybelse' from blocking lexical scope pops
if (!/^\s*else\b/.test(textAfter)) for (var i = state.cc.length - 1; i >= 0; --i) {
var c = state.cc[i];
if (c == poplex) lexical = lexical.prev;
else if (c != maybeelse && c != popcontext) break;
}
while ((lexical.type == "stat" || lexical.type == "form") &&
(firstChar == "}" || ((top = state.cc[state.cc.length - 1]) &&
(top == maybeoperatorComma || top == maybeoperatorNoComma) &&
!/^[,\.=+\-*:?[\(]/.test(textAfter))))
lexical = lexical.prev;
if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat")
lexical = lexical.prev;
var type = lexical.type, closing = firstChar == type;
if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? lexical.info.length + 1 : 0);
else if (type == "form" && firstChar == "{") return lexical.indented;
else if (type == "form") return lexical.indented + indentUnit;
else if (type == "stat")
return lexical.indented + (isContinuedStatement(state, textAfter) ? statementIndent || indentUnit : 0);
else if (lexical.info == "switch" && !closing && parserConfig.doubleIndentSwitch != false)
return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit);
else if (lexical.align) return lexical.column + (closing ? 0 : 1);
else return lexical.indented + (closing ? 0 : indentUnit);
},
electricInput: /^\s*(?:case .*?:|default:|\{|\})$/,
blockCommentStart: jsonMode ? null : "/*",
blockCommentEnd: jsonMode ? null : "*/",
blockCommentContinue: jsonMode ? null : " * ",
lineComment: jsonMode ? null : "//",
fold: "brace",
closeBrackets: "()[]{}''\"\"``",
helperType: jsonMode ? "json" : "javascript",
jsonldMode: jsonldMode,
jsonMode: jsonMode,
expressionAllowed: expressionAllowed,
skipExpression: function(state) {
parseJS(state, "atom", "atom", "true", new CodeMirror.StringStream("", 2, null))
}
};
});
CodeMirror.registerHelper("wordChars", "javascript", /[\w$]/);
CodeMirror.defineMIME("text/javascript", "javascript");
CodeMirror.defineMIME("text/ecmascript", "javascript");
CodeMirror.defineMIME("application/javascript", "javascript");
CodeMirror.defineMIME("application/x-javascript", "javascript");
CodeMirror.defineMIME("application/ecmascript", "javascript");
CodeMirror.defineMIME("application/json", { name: "javascript", json: true });
CodeMirror.defineMIME("application/x-json", { name: "javascript", json: true });
CodeMirror.defineMIME("application/manifest+json", { name: "javascript", json: true })
CodeMirror.defineMIME("application/ld+json", { name: "javascript", jsonld: true });
CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true });
CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript: true });
});
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/5/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
var htmlConfig = {
autoSelfClosers: {'area': true, 'base': true, 'br': true, 'col': true, 'command': true,
'embed': true, 'frame': true, 'hr': true, 'img': true, 'input': true,
'keygen': true, 'link': true, 'meta': true, 'param': true, 'source': true,
'track': true, 'wbr': true, 'menuitem': true},
implicitlyClosed: {'dd': true, 'li': true, 'optgroup': true, 'option': true, 'p': true,
'rp': true, 'rt': true, 'tbody': true, 'td': true, 'tfoot': true,
'th': true, 'tr': true},
contextGrabbers: {
'dd': {'dd': true, 'dt': true},
'dt': {'dd': true, 'dt': true},
'li': {'li': true},
'option': {'option': true, 'optgroup': true},
'optgroup': {'optgroup': true},
'p': {'address': true, 'article': true, 'aside': true, 'blockquote': true, 'dir': true,
'div': true, 'dl': true, 'fieldset': true, 'footer': true, 'form': true,
'h1': true, 'h2': true, 'h3': true, 'h4': true, 'h5': true, 'h6': true,
'header': true, 'hgroup': true, 'hr': true, 'menu': true, 'nav': true, 'ol': true,
'p': true, 'pre': true, 'section': true, 'table': true, 'ul': true},
'rp': {'rp': true, 'rt': true},
'rt': {'rp': true, 'rt': true},
'tbody': {'tbody': true, 'tfoot': true},
'td': {'td': true, 'th': true},
'tfoot': {'tbody': true},
'th': {'td': true, 'th': true},
'thead': {'tbody': true, 'tfoot': true},
'tr': {'tr': true}
},
doNotIndent: {"pre": true},
allowUnquoted: true,
allowMissing: true,
caseFold: true
}
var xmlConfig = {
autoSelfClosers: {},
implicitlyClosed: {},
contextGrabbers: {},
doNotIndent: {},
allowUnquoted: false,
allowMissing: false,
allowMissingTagName: false,
caseFold: false
}
CodeMirror.defineMode("xml", function(editorConf, config_) {
var indentUnit = editorConf.indentUnit
var config = {}
var defaults = config_.htmlMode ? htmlConfig : xmlConfig
for (var prop in defaults) config[prop] = defaults[prop]
for (var prop in config_) config[prop] = config_[prop]
// Return variables for tokenizers
var type, setStyle;
function inText(stream, state) {
function chain(parser) {
state.tokenize = parser;
return parser(stream, state);
}
var ch = stream.next();
if (ch == "<") {
if (stream.eat("!")) {
if (stream.eat("[")) {
if (stream.match("CDATA[")) return chain(inBlock("atom", "]]>"));
else return null;
} else if (stream.match("--")) {
return chain(inBlock("comment", "-->"));
} else if (stream.match("DOCTYPE", true, true)) {
stream.eatWhile(/[\w\._\-]/);
return chain(doctype(1));
} else {
return null;
}
} else if (stream.eat("?")) {
stream.eatWhile(/[\w\._\-]/);
state.tokenize = inBlock("meta", "?>");
return "meta";
} else {
type = stream.eat("/") ? "closeTag" : "openTag";
state.tokenize = inTag;
return "tag bracket";
}
} else if (ch == "&") {
var ok;
if (stream.eat("#")) {
if (stream.eat("x")) {
ok = stream.eatWhile(/[a-fA-F\d]/) && stream.eat(";");
} else {
ok = stream.eatWhile(/[\d]/) && stream.eat(";");
}
} else {
ok = stream.eatWhile(/[\w\.\-:]/) && stream.eat(";");
}
return ok ? "atom" : "error";
} else {
stream.eatWhile(/[^&<]/);
return null;
}
}
inText.isInText = true;
function inTag(stream, state) {
var ch = stream.next();
if (ch == ">" || (ch == "/" && stream.eat(">"))) {
state.tokenize = inText;
type = ch == ">" ? "endTag" : "selfcloseTag";
return "tag bracket";
} else if (ch == "=") {
type = "equals";
return null;
} else if (ch == "<") {
state.tokenize = inText;
state.state = baseState;
state.tagName = state.tagStart = null;
var next = state.tokenize(stream, state);
return next ? next + " tag error" : "tag error";
} else if (/[\'\"]/.test(ch)) {
state.tokenize = inAttribute(ch);
state.stringStartCol = stream.column();
return state.tokenize(stream, state);
} else {
stream.match(/^[^\s\u00a0=<>\"\']*[^\s\u00a0=<>\"\'\/]/);
return "word";
}
}
function inAttribute(quote) {
var closure = function(stream, state) {
while (!stream.eol()) {
if (stream.next() == quote) {
state.tokenize = inTag;
break;
}
}
return "string";
};
closure.isInAttribute = true;
return closure;
}
function inBlock(style, terminator) {
return function(stream, state) {
while (!stream.eol()) {
if (stream.match(terminator)) {
state.tokenize = inText;
break;
}
stream.next();
}
return style;
}
}
function doctype(depth) {
return function(stream, state) {
var ch;
while ((ch = stream.next()) != null) {
if (ch == "<") {
state.tokenize = doctype(depth + 1);
return state.tokenize(stream, state);
} else if (ch == ">") {
if (depth == 1) {
state.tokenize = inText;
break;
} else {
state.tokenize = doctype(depth - 1);
return state.tokenize(stream, state);
}
}
}
return "meta";
};
}
function lower(tagName) {
return tagName && tagName.toLowerCase();
}
function Context(state, tagName, startOfLine) {
this.prev = state.context;
this.tagName = tagName || "";
this.indent = state.indented;
this.startOfLine = startOfLine;
if (config.doNotIndent.hasOwnProperty(tagName) || (state.context && state.context.noIndent))
this.noIndent = true;
}
function popContext(state) {
if (state.context) state.context = state.context.prev;
}
function maybePopContext(state, nextTagName) {
var parentTagName;
while (true) {
if (!state.context) {
return;
}
parentTagName = state.context.tagName;
if (!config.contextGrabbers.hasOwnProperty(lower(parentTagName)) ||
!config.contextGrabbers[lower(parentTagName)].hasOwnProperty(lower(nextTagName))) {
return;
}
popContext(state);
}
}
function baseState(type, stream, state) {
if (type == "openTag") {
state.tagStart = stream.column();
return tagNameState;
} else if (type == "closeTag") {
return closeTagNameState;
} else {
return baseState;
}
}
function tagNameState(type, stream, state) {
if (type == "word") {
state.tagName = stream.current();
setStyle = "tag";
return attrState;
} else if (config.allowMissingTagName && type == "endTag") {
setStyle = "tag bracket";
return attrState(type, stream, state);
} else {
setStyle = "error";
return tagNameState;
}
}
function closeTagNameState(type, stream, state) {
if (type == "word") {
var tagName = stream.current();
if (state.context && state.context.tagName != tagName &&
config.implicitlyClosed.hasOwnProperty(lower(state.context.tagName)))
popContext(state);
if ((state.context && state.context.tagName == tagName) || config.matchClosing === false) {
setStyle = "tag";
return closeState;
} else {
setStyle = "tag error";
return closeStateErr;
}
} else if (config.allowMissingTagName && type == "endTag") {
setStyle = "tag bracket";
return closeState(type, stream, state);
} else {
setStyle = "error";
return closeStateErr;
}
}
function closeState(type, _stream, state) {
if (type != "endTag") {
setStyle = "error";
return closeState;
}
popContext(state);
return baseState;
}
function closeStateErr(type, stream, state) {
setStyle = "error";
return closeState(type, stream, state);
}
function attrState(type, _stream, state) {
if (type == "word") {
setStyle = "attribute";
return attrEqState;
} else if (type == "endTag" || type == "selfcloseTag") {
var tagName = state.tagName, tagStart = state.tagStart;
state.tagName = state.tagStart = null;
if (type == "selfcloseTag" ||
config.autoSelfClosers.hasOwnProperty(lower(tagName))) {
maybePopContext(state, tagName);
} else {
maybePopContext(state, tagName);
state.context = new Context(state, tagName, tagStart == state.indented);
}
return baseState;
}
setStyle = "error";
return attrState;
}
function attrEqState(type, stream, state) {
if (type == "equals") return attrValueState;
if (!config.allowMissing) setStyle = "error";
return attrState(type, stream, state);
}
function attrValueState(type, stream, state) {
if (type == "string") return attrContinuedState;
if (type == "word" && config.allowUnquoted) {setStyle = "string"; return attrState;}
setStyle = "error";
return attrState(type, stream, state);
}
function attrContinuedState(type, stream, state) {
if (type == "string") return attrContinuedState;
return attrState(type, stream, state);
}
return {
startState: function(baseIndent) {
var state = {tokenize: inText,
state: baseState,
indented: baseIndent || 0,
tagName: null, tagStart: null,
context: null}
if (baseIndent != null) state.baseIndent = baseIndent
return state
},
token: function(stream, state) {
if (!state.tagName && stream.sol())
state.indented = stream.indentation();
if (stream.eatSpace()) return null;
type = null;
var style = state.tokenize(stream, state);
if ((style || type) && style != "comment") {
setStyle = null;
state.state = state.state(type || style, stream, state);
if (setStyle)
style = setStyle == "error" ? style + " error" : setStyle;
}
return style;
},
indent: function(state, textAfter, fullLine) {
var context = state.context;
// Indent multi-line strings (e.g. css).
if (state.tokenize.isInAttribute) {
if (state.tagStart == state.indented)
return state.stringStartCol + 1;
else
return state.indented + indentUnit;
}
if (context && context.noIndent) return CodeMirror.Pass;
if (state.tokenize != inTag && state.tokenize != inText)
return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0;
// Indent the starts of attribute names.
if (state.tagName) {
if (config.multilineTagIndentPastTag !== false)
return state.tagStart + state.tagName.length + 2;
else
return state.tagStart + indentUnit * (config.multilineTagIndentFactor || 1);
}
if (config.alignCDATA && /<!\[CDATA\[/.test(textAfter)) return 0;
var tagAfter = textAfter && /^<(\/)?([\w_:\.-]*)/.exec(textAfter);
if (tagAfter && tagAfter[1]) { // Closing tag spotted
while (context) {
if (context.tagName == tagAfter[2]) {
context = context.prev;
break;
} else if (config.implicitlyClosed.hasOwnProperty(lower(context.tagName))) {
context = context.prev;
} else {
break;
}
}
} else if (tagAfter) { // Opening tag spotted
while (context) {
var grabbers = config.contextGrabbers[lower(context.tagName)];
if (grabbers && grabbers.hasOwnProperty(lower(tagAfter[2])))
context = context.prev;
else
break;
}
}
while (context && context.prev && !context.startOfLine)
context = context.prev;
if (context) return context.indent + indentUnit;
else return state.baseIndent || 0;
},
electricInput: /<\/[\s\w:]+>$/,
blockCommentStart: "<!--",
blockCommentEnd: "-->",
configuration: config.htmlMode ? "html" : "xml",
helperType: config.htmlMode ? "html" : "xml",
skipAttribute: function(state) {
if (state.state == attrValueState)
state.state = attrState
},
xmlCurrentTag: function(state) {
return state.tagName ? {name: state.tagName, close: state.type == "closeTag"} : null
},
xmlCurrentContext: function(state) {
var context = []
for (var cx = state.context; cx; cx = cx.prev)
context.push(cx.tagName)
return context.reverse()
}
};
});
CodeMirror.defineMIME("text/xml", "xml");
CodeMirror.defineMIME("application/xml", "xml");
if (!CodeMirror.mimeModes.hasOwnProperty("text/html"))
CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: true});
});
/*
MDN-LIKE Theme - Mozilla
Ported to CodeMirror by Peter Kroon <plakroon@gmail.com>
Report bugs/issues here: https://github.com/codemirror/CodeMirror/issues
GitHub: @peterkroon
The mdn-like theme is inspired on the displayed code examples at: https://developer.mozilla.org/en-US/docs/Web/CSS/animation
*/
.cm-s-mdn-like.CodeMirror { color: #999; background-color: #fff; }
.cm-s-mdn-like div.CodeMirror-selected { background: #cfc; }
.cm-s-mdn-like .CodeMirror-line::selection, .cm-s-mdn-like .CodeMirror-line > span::selection, .cm-s-mdn-like .CodeMirror-line > span > span::selection { background: #cfc; }
.cm-s-mdn-like .CodeMirror-line::-moz-selection, .cm-s-mdn-like .CodeMirror-line > span::-moz-selection, .cm-s-mdn-like .CodeMirror-line > span > span::-moz-selection { background: #cfc; }
.cm-s-mdn-like .CodeMirror-gutters { background: #f8f8f8; border-left: 6px solid rgba(0,83,159,0.65); color: #333; }
.cm-s-mdn-like .CodeMirror-linenumber { color: #aaa; padding-left: 8px; }
.cm-s-mdn-like .CodeMirror-cursor { border-left: 2px solid #222; }
.cm-s-mdn-like .cm-keyword { color: #6262FF; }
.cm-s-mdn-like .cm-atom { color: #F90; }
.cm-s-mdn-like .cm-number { color: #ca7841; }
.cm-s-mdn-like .cm-def { color: #8DA6CE; }
.cm-s-mdn-like span.cm-variable-2, .cm-s-mdn-like span.cm-tag { color: #690; }
.cm-s-mdn-like span.cm-variable-3, .cm-s-mdn-like span.cm-def, .cm-s-mdn-like span.cm-type { color: #07a; }
.cm-s-mdn-like .cm-variable { color: #07a; }
.cm-s-mdn-like .cm-property { color: #905; }
.cm-s-mdn-like .cm-qualifier { color: #690; }
.cm-s-mdn-like .cm-operator { color: #cda869; }
.cm-s-mdn-like .cm-comment { color:#777; font-weight:normal; }
.cm-s-mdn-like .cm-string { color:#07a; font-style:italic; }
.cm-s-mdn-like .cm-string-2 { color:#bd6b18; } /*?*/
.cm-s-mdn-like .cm-meta { color: #000; } /*?*/
.cm-s-mdn-like .cm-builtin { color: #9B7536; } /*?*/
.cm-s-mdn-like .cm-tag { color: #997643; }
.cm-s-mdn-like .cm-attribute { color: #d6bb6d; } /*?*/
.cm-s-mdn-like .cm-header { color: #FF6400; }
.cm-s-mdn-like .cm-hr { color: #AEAEAE; }
.cm-s-mdn-like .cm-link { color:#ad9361; font-style:italic; text-decoration:none; }
.cm-s-mdn-like .cm-error { border-bottom: 1px solid red; }
div.cm-s-mdn-like .CodeMirror-activeline-background { background: #efefff; }
div.cm-s-mdn-like span.CodeMirror-matchingbracket { outline:1px solid grey; color: inherit; }
.cm-s-mdn-like.CodeMirror { background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFcAAAAyCAYAAAAp8UeFAAAHvklEQVR42s2b63bcNgyEQZCSHCdt2vd/0tWF7I+Q6XgMXiTtuvU5Pl57ZQKkKHzEAOtF5KeIJBGJ8uvL599FRFREZhFx8DeXv8trn68RuGaC8TRfo3SNp9dlDDHedyLyTUTeRWStXKPZrjtpZxaRw5hPqozRs1N8/enzIiQRWcCgy4MUA0f+XWliDhyL8Lfyvx7ei/Ae3iQFHyw7U/59pQVIMEEPEz0G7XiwdRjzSfC3UTtz9vchIntxvry5iMgfIhJoEflOz2CQr3F5h/HfeFe+GTdLaKcu9L8LTeQb/R/7GgbsfKedyNdoHsN31uRPWrfZ5wsj/NzzRQHuToIdU3ahwnsKPxXCjJITuOsi7XLc7SG/v5GdALs7wf8JjTFiB5+QvTEfRyGOfX3Lrx8wxyQi3sNq46O7QahQiCsRFgqddjBouVEHOKDgXAQHD9gJCr5sMKkEdjwsarG/ww3BMHBU7OBjXnzdyY7SfCxf5/z6ATccrwlKuwC/jhznnPF4CgVzhhVf4xp2EixcBActO75iZ8/fM9zAs2OMzKdslgXWJ9XG8PQoOAMA5fGcsvORgv0doBXyHrCwfLJAOwo71QLNkb8n2Pl6EWiR7OCibtkPaz4Kc/0NNAze2gju3zOwekALDaCFPI5vjPFmgGY5AZqyGEvH1x7QfIb8YtxMnA/b+QQ0aQDAwc6JMFg8CbQZ4qoYEEHbRwNojuK3EHwd7VALSgq+MNDKzfT58T8qdpADrgW0GmgcAS1lhzztJmkAzcPNOQbsWEALBDSlMKUG0Eq4CLAQWvEVQ9WU57gZJwZtgPO3r9oBTQ9WO8TjqXINx8R0EYpiZEUWOF3FxkbJkgU9B2f41YBrIj5ZfsQa0M5kTgiAAqM3ShXLgu8XMqcrQBvJ0CL5pnTsfMB13oB8athpAq2XOQmcGmoACCLydx7nToa23ATaSIY2ichfOdPTGxlasXMLaL0MLZAOwAKIM+y8CmicobGdCcbbK9DzN+yYGVoNNI5iUKTMyYOjPse4A8SM1MmcXgU0toOq1yO/v8FOxlASyc7TgeYaAMBJHcY1CcCwGI/TK4AmDbDyKYBBtFUkRwto8gygiQEaByFgJ00BH2M8JWwQS1nafDXQCidWyOI8AcjDCSjCLk8ngObuAm3JAHAdubAmOaK06V8MNEsKPJOhobSprwQa6gD7DclRQdqcwL4zxqgBrQcabUiBLclRDKAlWp+etPkBaNMA0AKlrHwTdEByZAA4GM+SNluSY6wAzcMNewxmgig5Ks0nkrSpBvSaQHMdKTBAnLojOdYyGpQ254602ZILPdTD1hdlggdIm74jbTp8vDwF5ZYUeLWGJpWsh6XNyXgcYwVoJQTEhhTYkxzZjiU5npU2TaB979TQehlaAVq4kaGpiPwwwLkYUuBbQwocyQTv1tA0+1UFWoJF3iv1oq+qoSk8EQdJmwHkziIF7oOZk14EGitibAdjLYYK78H5vZOhtWpoI0ATGHs0Q8OMb4Ey+2bU2UYztCtA0wFAs7TplGLRVQCcqaFdGSPCeTI1QNIC52iWNzof6Uib7xjEp07mNNoUYmVosVItHrHzRlLgBn9LFyRHaQCtVUMbtTNhoXWiTOO9k/V8BdAc1Oq0ArSQs6/5SU0hckNy9NnXqQY0PGYo5dWJ7nINaN6o958FWin27aBaWRka1r5myvLOAm0j30eBJqCxHLReVclxhxOEN2JfDWjxBtAC7MIH1fVaGdoOp4qJYDgKtKPSFNID2gSnGldrCqkFZ+5UeQXQBIRrSwocbdZYQT/2LwRahBPBXoHrB8nxaGROST62DKUbQOMMzZIC9abkuELfQzQALWTnDNAm8KHWFOJgJ5+SHIvTPcmx1xQyZRhNL5Qci689aXMEaN/uNIWkEwDAvFpOZmgsBaaGnbs1NPa1Jm32gBZAIh1pCtG7TSH4aE0y1uVY4uqoFPisGlpP2rSA5qTecWn5agK6BzSpgAyD+wFaqhnYoSZ1Vwr8CmlTQbrcO3ZaX0NAEyMbYaAlyquFoLKK3SPby9CeVUPThrSJmkCAE0CrKUQadi4DrdSlWhmah0YL9z9vClH59YGbHx1J8VZTyAjQepJjmXwAKTDQI3omc3p1U4gDUf6RfcdYfrUp5ClAi2J3Ba6UOXGo+K+bQrjjssitG2SJzshaLwMtXgRagUNpYYoVkMSBLM+9GGiJZMvduG6DRZ4qc04DMPtQQxOjEtACmhO7K1AbNbQDEggZyJwscFpAGwENhoBeUwh3bWolhe8BTYVKxQEWrSUn/uhcM5KhvUu/+eQu0Lzhi+VrK0PrZZNDQKs9cpYUuFYgMVpD4/NxenJTiMCNqdUEUf1qZWjppLT5qSkkUZbCwkbZMSuVnu80hfSkzRbQeqCZSAh6huR4VtoM2gHAlLf72smuWgE+VV7XpE25Ab2WFDgyhnSuKbs4GuGzCjR+tIoUuMFg3kgcWKLTwRqanJQ2W00hAsenfaApRC42hbCvK1SlE0HtE9BGgneJO+ELamitD1YjjOYnNYVcraGhtKkW0EqVVeDx733I2NH581k1NNxNLG0i0IJ8/NjVaOZ0tYZ2Vtr0Xv7tPV3hkWp9EFkgS/J0vosngTaSoaG06WHi+xObQkaAdlbanP8B2+2l0f90LmUAAAAASUVORK5CYII=); }
html, body {
margin: 0px;
height: 100%;
width: 100%;
}
.CodeMirror {
border-right: 1px solid rgb(0, 0, 0);
margin: 0, auto;
width: 50%;
height: 100%;
font-size: 14px;
}
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
(function(globals) {
var define, requireModule;
(function() {
var registry = {}, seen = {};
define = function(name, deps, callback) {
registry[name] = { deps: deps, callback: callback };
};
requireModule = function(name) {
if (seen[name]) { return seen[name]; }
seen[name] = {};
var mod = registry[name];
if (!mod) {
throw new Error("Module '" + name + "' not found.");
}
var deps = mod.deps,
callback = mod.callback,
reified = [],
exports;
for (var i=0, l=deps.length; i<l; i++) {
if (deps[i] === 'exports') {
reified.push(exports = {});
} else {
reified.push(requireModule(deps[i]));
}
}
var value = callback.apply(this, reified);
return seen[name] = exports || value;
};
})();
define("rsvp/all",
["rsvp/promise","exports"],
function(__dependency1__, __exports__) {
"use strict";
var Promise = __dependency1__.Promise;
/* global toString */
function promiseAtLeast(expected_count, promises) {
if (Object.prototype.toString.call(promises) !== "[object Array]") {
throw new TypeError('You must pass an array to all.');
}
function canceller(msg) {
var promise;
for (var i = 0; i < promises.length; i++) {
promise = promises[i];
if (promise && typeof promise.then === 'function' &&
typeof promise.cancel === 'function') {
promise.cancel(msg);
}
}
}
return new Promise(function(resolve, reject) {
var results = [], remaining = promises.length,
promise, remaining_count = promises.length - expected_count;
if (remaining === 0) {
if (expected_count === 1) {
resolve();
} else {
resolve([]);
}
}
function resolver(index) {
return function(value) {
resolveAll(index, value);
};
}
function resolveAll(index, value) {
results[index] = value;
if (--remaining === remaining_count) {
if (remaining_count === 0) {
resolve(results);
} else {
resolve(value);
canceller();
}
}
}
function cancelAll(rejectionValue) {
reject(rejectionValue);
canceller();
}
for (var i = 0; i < promises.length; i++) {
promise = promises[i];
if (promise && typeof promise.then === 'function') {
promise.then(resolver(i), cancelAll);
} else {
resolveAll(i, promise);
}
}
}, canceller
);
}
function all(promises) {
return promiseAtLeast(promises.length, promises);
}
function any(promises) {
return promiseAtLeast(1, promises);
}
__exports__.all = all;
__exports__.any = any;
});
define("rsvp/async",
["exports"],
function(__exports__) {
"use strict";
var browserGlobal = (typeof window !== 'undefined') ? window : {};
var BrowserMutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver;
var async;
var local = (typeof global !== 'undefined') ? global : this;
function checkNativePromise() {
if (typeof Promise === "function" &&
typeof Promise.resolve === "function") {
try {
/* global Promise */
var promise = new Promise(function(){});
if ({}.toString.call(promise) === "[object Promise]") {
return true;
}
} catch (e) {}
}
return false;
}
function useNativePromise() {
var nativePromise = Promise.resolve();
return function(callback, arg) {
nativePromise.then(function () {
callback(arg);
});
};
}
// old node
function useNextTick() {
return function(callback, arg) {
process.nextTick(function() {
callback(arg);
});
};
}
// node >= 0.10.x
function useSetImmediate() {
return function(callback, arg) {
/* global setImmediate */
setImmediate(function(){
callback(arg);
});
};
}
function useMutationObserver() {
var queue = [];
var observer = new BrowserMutationObserver(function() {
var toProcess = queue.slice();
queue = [];
toProcess.forEach(function(tuple) {
var callback = tuple[0], arg= tuple[1];
callback(arg);
});
});
var element = document.createElement('div');
observer.observe(element, { attributes: true });
// Chrome Memory Leak: https://bugs.webkit.org/show_bug.cgi?id=93661
window.addEventListener('unload', function(){
observer.disconnect();
observer = null;
}, false);
return function(callback, arg) {
queue.push([callback, arg]);
element.setAttribute('drainQueue', 'drainQueue');
};
}
function useSetTimeout() {
return function(callback, arg) {
local.setTimeout(function() {
callback(arg);
}, 1);
};
}
if (checkNativePromise()) {
async = useNativePromise();
} else if (typeof setImmediate === 'function') {
async = useSetImmediate();
} else if (typeof process !== 'undefined' && {}.toString.call(process) === '[object process]') {
async = useNextTick();
} else if (BrowserMutationObserver) {
async = useMutationObserver();
} else {
async = useSetTimeout();
}
__exports__.async = async;
});
define("rsvp/cancellation_error",
["exports"],
function(__exports__) {
"use strict";
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error
function CancellationError(message) {
this.name = "cancel";
if ((message !== undefined) && (typeof message !== "string")) {
throw new TypeError('You must pass a string.');
}
this.message = message || "Default Message";
}
CancellationError.prototype = new Error();
CancellationError.prototype.constructor = CancellationError;
__exports__.CancellationError = CancellationError;
});
define("rsvp/config",
["rsvp/async","exports"],
function(__dependency1__, __exports__) {
"use strict";
var async = __dependency1__.async;
var config = {};
config.async = async;
__exports__.config = config;
});
define("rsvp/defer",
["rsvp/promise","exports"],
function(__dependency1__, __exports__) {
"use strict";
var Promise = __dependency1__.Promise;
function defer() {
var deferred = {
// pre-allocate shape
resolve: undefined,
reject: undefined,
promise: undefined
};
deferred.promise = new Promise(function(resolve, reject) {
deferred.resolve = resolve;
deferred.reject = reject;
});
return deferred;
}
__exports__.defer = defer;
});
define("rsvp/events",
["exports"],
function(__exports__) {
"use strict";
var Event = function(type, options) {
this.type = type;
for (var option in options) {
if (!options.hasOwnProperty(option)) { continue; }
this[option] = options[option];
}
};
var indexOf = function(callbacks, callback) {
for (var i=0, l=callbacks.length; i<l; i++) {
if (callbacks[i][0] === callback) { return i; }
}
return -1;
};
var callbacksFor = function(object) {
var callbacks = object._promiseCallbacks;
if (!callbacks) {
callbacks = object._promiseCallbacks = {};
}
return callbacks;
};
var EventTarget = {
mixin: function(object) {
object.on = this.on;
object.off = this.off;
object.trigger = this.trigger;
return object;
},
on: function(eventNames, callback, binding) {
var allCallbacks = callbacksFor(this), callbacks, eventName;
eventNames = eventNames.split(/\s+/);
binding = binding || this;
while (eventName = eventNames.shift()) {
callbacks = allCallbacks[eventName];
if (!callbacks) {
callbacks = allCallbacks[eventName] = [];
}
if (indexOf(callbacks, callback) === -1) {
callbacks.push([callback, binding]);
}
}
},
off: function(eventNames, callback) {
var allCallbacks = callbacksFor(this), callbacks, eventName, index;
eventNames = eventNames.split(/\s+/);
while (eventName = eventNames.shift()) {
if (!callback) {
allCallbacks[eventName] = [];
continue;
}
callbacks = allCallbacks[eventName];
index = indexOf(callbacks, callback);
if (index !== -1) { callbacks.splice(index, 1); }
}
},
trigger: function(eventName, options) {
var allCallbacks = callbacksFor(this),
callbacks, callbackTuple, callback, binding, event;
if (callbacks = allCallbacks[eventName]) {
// Don't cache the callbacks.length since it may grow
for (var i=0; i<callbacks.length; i++) {
callbackTuple = callbacks[i];
callback = callbackTuple[0];
binding = callbackTuple[1];
if (typeof options !== 'object') {
options = { detail: options };
}
event = new Event(eventName, options);
callback.call(binding, event);
}
}
}
};
__exports__.EventTarget = EventTarget;
});
define("rsvp/hash",
["rsvp/promise","exports"],
function(__dependency1__, __exports__) {
"use strict";
var Promise = __dependency1__.Promise;
function size(object) {
var s = 0;
for (var prop in object) {
s++;
}
return s;
}
function hash(promises) {
function canceller(msg) {
var promise,
key;
for (key in promises) {
if (promises.hasOwnProperty(key)) {
promise = promises[key];
if (promise && typeof promise.then === 'function' &&
typeof promise.cancel === 'function') {
promise.cancel(msg);
}
}
}
}
return new Promise(function(resolve, reject) {
var results = {}, remaining = size(promises),
promise;
if (remaining === 0) {
resolve(results);
}
function resolver(key) {
return function(value) {
resolveAll(key, value);
};
}
function resolveAll(key, value) {
results[key] = value;
if (--remaining === 0) {
resolve(results);
}
}
function cancelAll(rejectionValue) {
reject(rejectionValue);
canceller();
}
for (var prop in promises) {
promise = promises[prop];
if (promise && typeof promise.then === 'function') {
promise.then(resolver(prop), cancelAll);
} else {
resolveAll(prop, promise);
}
}
}, canceller
);
}
__exports__.hash = hash;
});
define("rsvp/node",
["rsvp/promise","rsvp/all","exports"],
function(__dependency1__, __dependency2__, __exports__) {
"use strict";
var Promise = __dependency1__.Promise;
var all = __dependency2__.all;
function makeNodeCallbackFor(resolve, reject) {
return function (error, value) {
if (error) {
reject(error);
} else if (arguments.length > 2) {
resolve(Array.prototype.slice.call(arguments, 1));
} else {
resolve(value);
}
};
}
function denodeify(nodeFunc) {
return function() {
var nodeArgs = Array.prototype.slice.call(arguments), resolve, reject;
var thisArg = this;
var promise = new Promise(function(nodeResolve, nodeReject) {
resolve = nodeResolve;
reject = nodeReject;
});
all(nodeArgs).then(function(nodeArgs) {
nodeArgs.push(makeNodeCallbackFor(resolve, reject));
try {
nodeFunc.apply(thisArg, nodeArgs);
} catch(e) {
reject(e);
}
});
return promise;
};
}
__exports__.denodeify = denodeify;
});
define("rsvp/promise",
["rsvp/config","rsvp/events","rsvp/cancellation_error","exports"],
function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
"use strict";
var config = __dependency1__.config;
var EventTarget = __dependency2__.EventTarget;
var CancellationError = __dependency3__.CancellationError;
function objectOrFunction(x) {
return isFunction(x) || (typeof x === "object" && x !== null);
}
function isFunction(x){
return typeof x === "function";
}
var Promise = function(resolver, canceller) {
var promise = this,
resolved = false;
if (typeof resolver !== 'function') {
throw new TypeError('You must pass a resolver function as the sole argument to the promise constructor');
}
if ((canceller !== undefined) && (typeof canceller !== 'function')) {
throw new TypeError('You can only pass a canceller function' +
' as the second argument to the promise constructor');
}
if (!(promise instanceof Promise)) {
return new Promise(resolver, canceller);
}
var resolvePromise = function(value) {
if (resolved) { return; }
resolved = true;
resolve(promise, value);
};
var rejectPromise = function(value) {
if (resolved) { return; }
resolved = true;
reject(promise, value);
};
this.on('promise:failed', function(event) {
this.trigger('error', { detail: event.detail });
}, this);
this.on('error', onerror);
this.cancel = function (msg) {
// For now, simply reject the promise and does not propagate the cancel
// to parent or children
if (resolved) { return; }
promise.isCancelled = true;
if (canceller !== undefined) {
try {
canceller(msg);
} catch (e) {
rejectPromise(e);
return;
}
}
// Trigger cancel?
rejectPromise(new CancellationError(msg));
};
try {
resolver(resolvePromise, rejectPromise);
} catch(e) {
rejectPromise(e);
}
};
function onerror(event) {
if (config.onerror) {
config.onerror(event.detail);
}
}
var invokeCallback = function(type, promise, callback, event) {
var hasCallback = isFunction(callback),
value, error, succeeded, failed;
if (promise.isFulfilled) { return; }
if (promise.isRejected) { return; }
if (promise.isCancelled) { return; }
if (hasCallback) {
try {
value = callback(event.detail);
succeeded = true;
} catch(e) {
failed = true;
error = e;
}
} else {
value = event.detail;
succeeded = true;
}
if (handleThenable(promise, value)) {
return;
} else if (hasCallback && succeeded) {
resolve(promise, value);
} else if (failed) {
reject(promise, error);
} else if (type === 'resolve') {
resolve(promise, value);
} else if (type === 'reject') {
reject(promise, value);
}
};
Promise.prototype = {
constructor: Promise,
isCancelled: undefined,
isRejected: undefined,
isFulfilled: undefined,
rejectedReason: undefined,
fulfillmentValue: undefined,
then: function(done, fail) {
this.off('error', onerror);
var thenPromise = new this.constructor(function() {},
function (msg) {
thenPromise.trigger('promise:cancelled', { msg: msg});
});
if (this.isFulfilled) {
config.async(function(promise) {
invokeCallback('resolve', thenPromise, done, { detail: promise.fulfillmentValue });
}, this);
}
if (this.isRejected) {
config.async(function(promise) {
invokeCallback('reject', thenPromise, fail, { detail: promise.rejectedReason });
}, this);
}
this.on('promise:resolved', function(event) {
invokeCallback('resolve', thenPromise, done, event);
});
this.on('promise:failed', function(event) {
invokeCallback('reject', thenPromise, fail, event);
});
return thenPromise;
},
fail: function(fail) {
return this.then(null, fail);
},
always: function(fail) {
return this.then(fail, fail);
}
};
EventTarget.mixin(Promise.prototype);
function resolve(promise, value) {
if (promise === value) {
fulfill(promise, value);
} else if (!handleThenable(promise, value)) {
fulfill(promise, value);
}
}
function handleThenable(promise, value) {
var then = null,
resolved;
try {
if (promise === value) {
throw new TypeError("A promises callback cannot return that same promise.");
}
if (objectOrFunction(value)) {
then = value.then;
if (isFunction(then)) {
promise.on('promise:cancelled', function(event) {
if (isFunction(value.cancel)) {
value.cancel(event.msg);
}
});
then.call(value, function(val) {
if (resolved) { return true; }
resolved = true;
if (value !== val) {
resolve(promise, val);
} else {
fulfill(promise, val);
}
}, function(val) {
if (resolved) { return true; }
resolved = true;
reject(promise, val);
});
return true;
}
}
} catch (error) {
reject(promise, error);
return true;
}
return false;
}
function fulfill(promise, value) {
config.async(function() {
if (promise.isFulfilled) { return; }
if (promise.isRejected) { return; }
promise.trigger('promise:resolved', { detail: value });
promise.isFulfilled = true;
promise.fulfillmentValue = value;
});
}
function reject(promise, value) {
config.async(function() {
if (promise.isFulfilled) { return; }
if (promise.isRejected) { return; }
promise.trigger('promise:failed', { detail: value });
promise.isRejected = true;
promise.rejectedReason = value;
});
}
__exports__.Promise = Promise;
});
define("rsvp/queue",
["rsvp/promise","rsvp/resolve","exports"],
function(__dependency1__, __dependency2__, __exports__) {
"use strict";
var Promise = __dependency1__.Promise;
var resolve = __dependency2__.resolve;
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error
function ResolvedQueueError(message) {
this.name = "resolved";
if ((message !== undefined) && (typeof message !== "string")) {
throw new TypeError('You must pass a string.');
}
this.message = message || "Default Message";
}
ResolvedQueueError.prototype = new Error();
ResolvedQueueError.prototype.constructor = ResolvedQueueError;
var Queue = function(thenable) {
var queue = this,
promise_list = [],
promise,
fulfill,
reject,
resolved;
if (!(this instanceof Queue)) {
return new Queue(thenable);
}
function canceller(msg) {
for (var i = promise_list.length; i > 0; i--) {
promise_list[i - 1].cancel(msg);
}
}
function checkPromise(next_promise) {
promise_list.push(next_promise);
// Handle pop
promise_list.push(next_promise.then(function (fulfillmentValue) {
promise_list.splice(0, 2);
if (promise_list.length === 0) {
fulfill(fulfillmentValue);
} else {
return fulfillmentValue;
}
}, function (rejectedReason) {
promise_list.splice(0, 2);
if (promise_list.length === 0) {
reject(rejectedReason);
} else {
throw rejectedReason;
}
}));
}
promise = new Promise(function(done, fail) {
fulfill = function (fulfillmentValue) {
if (resolved) {return;}
queue.isFulfilled = true;
queue.fulfillmentValue = fulfillmentValue;
resolved = true;
return done(fulfillmentValue);
};
reject = function (rejectedReason) {
if (resolved) {return;}
queue.isRejected = true;
queue.rejectedReason = rejectedReason ;
resolved = true;
return fail(rejectedReason);
};
}, canceller);
checkPromise(resolve(thenable));
queue.cancel = function (msg) {
if (resolved) {return;}
resolved = true;
promise.cancel(msg);
promise.fail(function (rejectedReason) {
queue.isRejected = true;
queue.rejectedReason = rejectedReason;
});
};
queue.then = function () {
return promise.then.apply(promise, arguments);
};
queue.push = function(done, fail) {
var last_promise = promise_list[promise_list.length - 1],
next_promise;
if (resolved) {
throw new ResolvedQueueError();
}
// Handle pop
checkPromise(last_promise.then(done, fail));
return this;
};
};
Queue.prototype = Object.create(Promise.prototype);
Queue.prototype.constructor = Queue;
__exports__.Queue = Queue;
__exports__.ResolvedQueueError = ResolvedQueueError;
});
define("rsvp/reject",
["rsvp/promise","exports"],
function(__dependency1__, __exports__) {
"use strict";
var Promise = __dependency1__.Promise;
function reject(reason) {
return new Promise(function (resolve, reject) {
reject(reason);
});
}
__exports__.reject = reject;
});
define("rsvp/resolve",
["rsvp/promise","exports"],
function(__dependency1__, __exports__) {
"use strict";
var Promise = __dependency1__.Promise;
function resolve(thenable) {
return new Promise(function(resolve, reject) {
if (typeof thenable === "object" && thenable !== null) {
var then = thenable.then;
if ((then !== undefined) && (typeof then === "function")) {
return then.apply(thenable, [resolve, reject]);
}
}
return resolve(thenable);
}, function (msg) {
if ((thenable !== undefined) && (thenable.cancel !== undefined)) {
thenable.cancel(msg);
}
});
}
__exports__.resolve = resolve;
});
define("rsvp/rethrow",
["exports"],
function(__exports__) {
"use strict";
var local = (typeof global === "undefined") ? this : global;
function rethrow(reason) {
local.setTimeout(function() {
throw reason;
});
throw reason;
}
__exports__.rethrow = rethrow;
});
define("rsvp/timeout",
["rsvp/promise","exports"],
function(__dependency1__, __exports__) {
"use strict";
var Promise = __dependency1__.Promise;
function promiseSetTimeout(millisecond, should_reject, message) {
var timeout_id;
function resolver(resolve, reject) {
timeout_id = setTimeout(function () {
if (should_reject) {
reject(message);
} else {
resolve(message);
}
}, millisecond);
}
function canceller() {
clearTimeout(timeout_id);
}
return new Promise(resolver, canceller);
}
function delay(millisecond, message) {
return promiseSetTimeout(millisecond, false, message);
}
function timeout(millisecond) {
return promiseSetTimeout(millisecond, true,
"Timed out after " + millisecond + " ms");
}
Promise.prototype.delay = function(millisecond) {
return this.then(function (fulfillmentValue) {
return delay(millisecond, fulfillmentValue);
});
};
__exports__.delay = delay;
__exports__.timeout = timeout;
});
define("rsvp",
["rsvp/events","rsvp/cancellation_error","rsvp/promise","rsvp/node","rsvp/all","rsvp/queue","rsvp/timeout","rsvp/hash","rsvp/rethrow","rsvp/defer","rsvp/config","rsvp/resolve","rsvp/reject","exports"],
function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __dependency9__, __dependency10__, __dependency11__, __dependency12__, __dependency13__, __exports__) {
"use strict";
var EventTarget = __dependency1__.EventTarget;
var CancellationError = __dependency2__.CancellationError;
var Promise = __dependency3__.Promise;
var denodeify = __dependency4__.denodeify;
var all = __dependency5__.all;
var any = __dependency5__.any;
var Queue = __dependency6__.Queue;
var ResolvedQueueError = __dependency6__.ResolvedQueueError;
var delay = __dependency7__.delay;
var timeout = __dependency7__.timeout;
var hash = __dependency8__.hash;
var rethrow = __dependency9__.rethrow;
var defer = __dependency10__.defer;
var config = __dependency11__.config;
var resolve = __dependency12__.resolve;
var reject = __dependency13__.reject;
function configure(name, value) {
config[name] = value;
}
__exports__.CancellationError = CancellationError;
__exports__.Promise = Promise;
__exports__.EventTarget = EventTarget;
__exports__.all = all;
__exports__.any = any;
__exports__.Queue = Queue;
__exports__.ResolvedQueueError = ResolvedQueueError;
__exports__.delay = delay;
__exports__.timeout = timeout;
__exports__.hash = hash;
__exports__.rethrow = rethrow;
__exports__.defer = defer;
__exports__.denodeify = denodeify;
__exports__.configure = configure;
__exports__.resolve = resolve;
__exports__.reject = reject;
});
window.RSVP = requireModule("rsvp");
})(window);
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<title>HTML to PDF</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>html-to-pdf</title>
<script src="include/nexedi/rsvp.js"></script>
<script src="include/nexedi/renderjs.js"></script>
<script src="include/nexedi/jio.js"></script>
<script src="include/codemirror/lib/codemirror.js"></script>
<script src="include/codemirror/mode/javascript.js"></script>
<script src="include/codemirror/mode/xml.js"></script>
<script src="include/codemirror/mode/css.js"></script>
<script src="include/codemirror/mode/htmlmixed.js"></script>
<link rel="stylesheet" href="include/codemirror/lib/codemirror.css">
<link rel="stylesheet" href="include/codemirror/theme/mdn-like.css">
<link rel="stylesheet" href="include/index.css">
<script src="index.js"></script>
</head>
<body>
<script src="connection.js"></script>
<script src="chromium.js"></script>
<script>
function mm2inches (mm)
{
return mm / 25.4
}
/*
Options for printing:
https://chromedevtools.github.io/devtools-protocol/1-3/Page/#method-printToPDF
*/
var optionsForPrintToPdf =
{
landscape: true,
displayHeaderFooter: false,
printBackground: true,
scale: 1,
paperWidth: mm2inches(297 /* millimetre */),
paperHeight: mm2inches(210 /* millimetre */),
marginTop: mm2inches(10 /* millimetre */),
marginBottom: mm2inches(10 /* millimetre */),
marginLeft: mm2inches(10 /* millimetre */),
marginRight: mm2inches(10 /* millimetre */),
pageRanges: "",
headerTemplate: "",
footerTemplate: "",
preferCSSPageSize: false
}
/*
Usage: Start google chromium with the following command line flags.
--headless
--remote-debugging-port=9222
--disable-web-security
--user-data-dir=/var/tmp/chrome
The last two flags can be ommited if we find another way to enable
Cross-Origin Resource Sharing. Then load this page with a browser
search param:
http://localhost:8080/?browser=http://localhost:9222
*/
var searchParams = (new URL(window.location.href)).searchParams
var browser = new HeadlessChromium(searchParams.get("browser"))
var handler = new RequestHandler()
async function html2pdf(url)
{
var page = await browser.openNewPage(url)
await browser.enablePage(page)
var pdf = await browser.printToPdf(page, optionsForPrintToPdf)
await browser.closePage(page)
return pdf
}
async function mainloop()
{
if (!handler.hasNextRequest())
{
setTimeout(mainloop, 30 /* seconds */ * 1000)
return
}
var url = handler.getNextRequest()
var pdf = await html2pdf(url)
var name = (new URL(url)).hostname
handler.publishResults(name, pdf)
setTimeout(mainloop, 3 /* seconds */ * 1000)
}
mainloop()
</script>
<textarea id="editor"></textarea>
<div id="viewer" style="display: none;">Placeholder PDF Viewer</div>
<div
data-gadget-url="gadget_converter.html"
data-gadget-scope="converter"
data-gadget-sandbox="public">
</div>
</body>
</html>
</html>
\ No newline at end of file
(function (window, rJS) {
"use strict";
rJS(window)
.setState({
update: false
})
.declareService(function () {
var gadget = this;
CodeMirror.fromTextArea(document.getElementById("editor"), {
mode: {
name: "htmlmixed",
tags: {
style: [["type", /^text\/(x-)?scss$/, "text/x-scss"],
[null, null, "css"]]
}
},
theme: "mdn-like",
lineNumbers: true,
smartIndent: true,
indentWithTabs: true,
indentUnit: 4,
tabsize: 4
});
return gadget.changeState({update: true});
})
.onStateChange(function (ignored) {
var gadget = this;
var editor = document.querySelector(".CodeMirror").CodeMirror;
var viewer = document.getElementById("viewer")
var converter;
return gadget.getDeclaredGadget("converter")
.push(function (subgadget) {
converter = subgadget;
let html = editor.getValue();
// return converter.convert(html);
})
.push(function (base64data) {
// todo: implement this function + pdf viewer (maybe use PDF.js)
})
})
}(window, rJS));
\ No newline at end of file
class RequestHandler
{
constructor()
{
this.buffer = ["https://www.example.com", "https://www.nexedi.com/"]
}
hasNextRequest()
{
return this.buffer.length != 0
}
getNextRequest()
{
return this.buffer.pop()
}
publishResults(name, data)
{
var a = document.createElement("a");
a.href = "data:application/pdf;base64," + data;
a.download = `${name}.pdf`;
a.click();
}
}
class HeadlessChromium
{
constructor(url)
......@@ -118,3 +144,70 @@ class HeadlessChromium
return response.data //atob(response.data)
}
}
function mm2inches (mm)
{
return mm / 25.4
}
/*
Options for printing:
https://chromedevtools.github.io/devtools-protocol/1-3/Page/#method-printToPDF
*/
var optionsForPrintToPdf =
{
landscape: true,
displayHeaderFooter: false,
printBackground: true,
scale: 1,
paperWidth: mm2inches(297 /* millimetre */),
paperHeight: mm2inches(210 /* millimetre */),
marginTop: mm2inches(10 /* millimetre */),
marginBottom: mm2inches(10 /* millimetre */),
marginLeft: mm2inches(10 /* millimetre */),
marginRight: mm2inches(10 /* millimetre */),
pageRanges: "",
headerTemplate: "",
footerTemplate: "",
preferCSSPageSize: false
}
/*
Usage: Start google chromium with the following command line flags.
--headless
--remote-debugging-port=9222
--disable-web-security
--user-data-dir=/var/tmp/chrome
The last two flags can be ommited if we find another way to enable
Cross-Origin Resource Sharing. Then load this page with a browser
search param:
http://localhost:8080/?browser=http://localhost:9222
*/
var searchParams = (new URL(window.location.href)).searchParams
var browser = new HeadlessChromium(searchParams.get("browser"))
var handler = new RequestHandler()
async function html2pdf(url)
{
var page = await browser.openNewPage(url)
await browser.enablePage(page)
var pdf = await browser.printToPdf(page, optionsForPrintToPdf)
await browser.closePage(page)
return pdf
}
async function mainloop()
{
if (!handler.hasNextRequest())
{
setTimeout(mainloop, 30 /* seconds */ * 1000)
return
}
var url = handler.getNextRequest()
var pdf = await html2pdf(url)
var name = (new URL(url)).hostname
handler.publishResults(name, pdf)
setTimeout(mainloop, 3 /* seconds */ * 1000)
}
mainloop()
\ No newline at end of file
HTML to PDF
===========
Standalone version of the html to pdf convertion tool for ERP5.
Usage:
Create an http-server for the current directory.
python -m http.server -b localhost 8080
Open localhost:8080 inside any browsers (some might not work).
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment