-
+
-
\ No newline at end of file
+
diff --git a/cms/init.php b/cms/init.php
new file mode 100644
index 0000000..22c7bef
--- /dev/null
+++ b/cms/init.php
@@ -0,0 +1,56 @@
+ "password",
+ "editor" => "password",
+];
+
+/**
+ * DO NOT CHANGE ANYTHING BENEATH THIS LINE - IT WILL BUGGER STUFF UP
+ */
+session_start();
+require_once "neoCMSCore.php";
+
+if (empty($_SESSION["core"])) {
+ $_SESSION["core"] = new neoCMSCore();
+ $_SESSION["core"]->users = $authentication;
+}
+if (!$_SESSION["core"]->isLoggedIn() && stripos($_SERVER['REQUEST_URI'], "/login") === FALSE) {
+ header('Location: /cms/login');
+ die("Redirecting to login..");
+}
+
+
+// str_starts_with compatibility for php 7
+if (!function_exists('str_starts_with')) {
+ function str_starts_with($haystack, $needle)
+ {
+ //str_starts_with(string $haystack, string $needle): bool
+
+ $strlen_needle = mb_strlen($needle);
+ if (mb_substr($haystack, 0, $strlen_needle) == $needle) {
+ return true;
+ }
+ return false;
+ }
+}
+
+//str_ends_with compatibility for php 7
+if (!function_exists('str_ends_with')) {
+ function str_ends_with($haystack, $needle)
+ {
+ //str_starts_with(string $haystack, string $needle): bool
+
+ $strlen_needle = mb_strlen($needle);
+ if (mb_substr($haystack, -$strlen_needle, $strlen_needle) == $needle) {
+ return true;
+ }
+ return false;
+ }
+}
+
+$_SESSION["core"]->version = '2.00';
+
diff --git a/cms/js/cms.js b/cms/js/cms.js
new file mode 100644
index 0000000..151aa1c
--- /dev/null
+++ b/cms/js/cms.js
@@ -0,0 +1,81 @@
+$(document).ready(function () {
+
+ var currentDiv;
+ var iframeDoc;
+
+ $('#frameContainer').on('load', function () {
+
+ // Get the iframe document
+ var iframe = document.getElementById('frameContainer');
+ iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
+
+ // Set up click handler on divs with class 'editable' in the iframe
+ $(iframeDoc).find('.editable').css('cursor', 'pointer').click(function (event) {
+ event.preventDefault();
+
+ currentDiv = $(this);
+
+ // Get the content of the div
+ var content = currentDiv.html();
+
+ // Set the content in TinyMCE
+ $('#editor').val(content);
+
+ // Open the modal
+ $('#editModal').modal('show');
+
+ // Initialize TinyMCE when the modal is shown
+ $('#editModal').on('shown.bs.modal', function () {
+ tinymce.init({
+ promotion: false,
+ branding: false,
+ selector: '#editor',
+ height: 300,
+ plugins: 'print preview paste importcss searchreplace autolink autosave save directionality code visualblocks visualchars fullscreen image link media template codesample table charmap hr pagebreak nonbreaking anchor toc insertdatetime advlist lists wordcount textpattern noneditable help charmap quickbars emoticons',
+ toolbar: 'undo redo | bold italic underline strikethrough | fontselect fontsizeselect formatselect | alignleft aligncenter alignright alignjustify | outdent indent | numlist bullist | forecolor backcolor removeformat | pagebreak | charmap emoticons | fullscreen preview save print | insertfile image media template link anchor codesample | ltr rtl',
+ images_upload_url: '/cms/image_upload.php', // URL of your server-side script
+ automatic_uploads: true,
+ images_reuse_filename: false,
+ images_upload_credentials: true,
+ force_br_newlines: false,
+ force_p_newlines: false,
+ forced_root_block: '',
+ setup: function (editor) {
+ editor.on('init', function (e) {
+ editor.setContent(content);
+ });
+ }
+ });
+ });
+
+ });
+ });
+
+ $('#saveBtn').click(function () {
+ // Get the data from TinyMCE
+ var data = tinymce.get('editor').getContent();
+
+ // Set the data back to the div in the iframe
+ $(currentDiv).html(data);
+
+ // Close the modal
+ $('#editModal').modal('hide');
+ });
+
+ // Clean up TinyMCE when modal is closed
+ $('#editModal').on('hidden.bs.modal', function () {
+ if (tinymce.get('editor')) {
+ tinymce.get('editor').remove();
+ }
+ });
+
+ $('#savePage').click(() => {
+ $.post("./controller/", {
+ action: "save",
+ uri: $('#frameContainer').contents().get(0).location.pathname,
+ content: new XMLSerializer().serializeToString($('#frameContainer').contents().get(0))
+ }, function (data) {
+ alert(data)
+ });
+ });
+});
\ No newline at end of file
diff --git a/cms/js/codemirror/css/csscolors.css b/cms/js/codemirror/css/csscolors.css
deleted file mode 100644
index 42010a2..0000000
--- a/cms/js/codemirror/css/csscolors.css
+++ /dev/null
@@ -1,47 +0,0 @@
-.editbox {
- margin: .4em;
- padding: 0;
- font-family: monospace;
- font-size: 10pt;
- color: black;
-}
-
-pre.code, .editbox {
- color: #666666;
-}
-
-.editbox p {
- margin: 0;
-}
-
-span.css-at {
- color: #770088;
-}
-
-span.css-unit {
- color: #228811;
-}
-
-span.css-value {
- color: #770088;
-}
-
-span.css-identifier {
- color: black;
-}
-
-span.css-important {
- color: #0000FF;
-}
-
-span.css-colorcode {
- color: #004499;
-}
-
-span.css-comment {
- color: #AA7700;
-}
-
-span.css-string {
- color: #AA2222;
-}
diff --git a/cms/js/codemirror/css/jscolors.css b/cms/js/codemirror/css/jscolors.css
deleted file mode 100644
index 17773b3..0000000
--- a/cms/js/codemirror/css/jscolors.css
+++ /dev/null
@@ -1,55 +0,0 @@
-.editbox {
- margin: .4em;
- padding: 0;
- font-family: monospace;
- font-size: 10pt;
- color: black;
-}
-
-pre.code, .editbox {
- color: #666666;
-}
-
-.editbox p {
- margin: 0;
-}
-
-span.js-punctuation {
- color: #666666;
-}
-
-span.js-operator {
- color: #666666;
-}
-
-span.js-keyword {
- color: #770088;
-}
-
-span.js-atom {
- color: #228811;
-}
-
-span.js-variable {
- color: black;
-}
-
-span.js-variabledef {
- color: #0000FF;
-}
-
-span.js-localvariable {
- color: #004499;
-}
-
-span.js-property {
- color: black;
-}
-
-span.js-comment {
- color: #AA7700;
-}
-
-span.js-string {
- color: #AA2222;
-}
diff --git a/cms/js/codemirror/css/xmlcolors.css b/cms/js/codemirror/css/xmlcolors.css
deleted file mode 100644
index 8cb95bc..0000000
--- a/cms/js/codemirror/css/xmlcolors.css
+++ /dev/null
@@ -1,51 +0,0 @@
-.editbox {
- margin: .4em;
- padding: 0;
- font-family: monospace;
- font-size: 10pt;
- color: black;
-}
-
-.editbox p {
- margin: 0;
-}
-
-span.xml-tagname {
- color: #A0B;
-}
-
-span.xml-attribute {
- color: #281;
-}
-
-span.xml-punctuation {
- color: black;
-}
-
-span.xml-attname {
- color: #00F;
-}
-
-span.xml-comment {
- color: #A70;
-}
-
-span.xml-cdata {
- color: #48A;
-}
-
-span.xml-processing {
- color: #999;
-}
-
-span.xml-entity {
- color: #A22;
-}
-
-span.xml-error {
- color: #F00;
-}
-
-span.xml-text {
- color: black;
-}
diff --git a/cms/js/codemirror/js/codemirror.js b/cms/js/codemirror/js/codemirror.js
deleted file mode 100644
index 329f296..0000000
--- a/cms/js/codemirror/js/codemirror.js
+++ /dev/null
@@ -1,474 +0,0 @@
-/* CodeMirror main module
- *
- * Implements the CodeMirror constructor and prototype, which take care
- * of initializing the editor frame, and providing the outside interface.
- */
-
-// The CodeMirrorConfig object is used to specify a default
-// configuration. If you specify such an object before loading this
-// file, the values you put into it will override the defaults given
-// below. You can also assign to it after loading.
-var CodeMirrorConfig = window.CodeMirrorConfig || {};
-
-var CodeMirror = (function () {
- function setDefaults(object, defaults) {
- for (var option in defaults) {
- if (!object.hasOwnProperty(option))
- object[option] = defaults[option];
- }
- }
-
- function forEach(array, action) {
- for (var i = 0; i < array.length; i++)
- action(array[i]);
- }
-
- // These default options can be overridden by passing a set of
- // options to a specific CodeMirror constructor. See manual.html for
- // their meaning.
- setDefaults(CodeMirrorConfig, {
- stylesheet: "",
- path: "",
- parserfile: [],
- basefiles: ["util.js", "stringstream.js", "select.js", "undo.js", "editor.js", "tokenize.js"],
- iframeClass: null,
- passDelay: 200,
- passTime: 50,
- lineNumberDelay: 200,
- lineNumberTime: 50,
- continuousScanning: false,
- saveFunction: null,
- onChange: null,
- undoDepth: 50,
- undoDelay: 800,
- disableSpellcheck: true,
- textWrapping: true,
- readOnly: false,
- width: "",
- height: "300px",
- autoMatchParens: false,
- parserConfig: null,
- tabMode: "indent", // or "spaces", "default", "shift"
- reindentOnLoad: false,
- activeTokens: null,
- cursorActivity: null,
- lineNumbers: false,
- indentUnit: 2
- });
-
- function addLineNumberDiv(container) {
- var nums = document.createElement("DIV"),
- scroller = document.createElement("DIV");
- nums.style.position = "absolute";
- nums.style.height = "100%";
- if (nums.style.setExpression) {
- try {
- nums.style.setExpression("height", "this.previousSibling.offsetHeight + 'px'");
- } catch (e) {
- } // Seems to throw 'Not Implemented' on some IE8 versions
- }
- nums.style.top = "0px";
- nums.style.overflow = "hidden";
- container.appendChild(nums);
- scroller.className = "CodeMirror-line-numbers";
- nums.appendChild(scroller);
- return nums;
- }
-
- function CodeMirror(place, options) {
- // Backward compatibility for deprecated options.
- if (options.dumbTabs) options.tabMode = "spaces";
- else if (options.normalTab) options.tabMode = "default";
-
- // Use passed options, if any, to override defaults.
- this.options = options = options || {};
- setDefaults(options, CodeMirrorConfig);
-
- var frame = this.frame = document.createElement("IFRAME");
- if (options.iframeClass) frame.className = options.iframeClass;
- frame.frameBorder = 0;
- frame.src = "javascript:false;";
- frame.style.border = "0";
- frame.style.width = '100%';
- frame.style.height = '100%';
- // display: block occasionally suppresses some Firefox bugs, so we
- // always add it, redundant as it sounds.
- frame.style.display = "block";
-
- var div = this.wrapping = document.createElement("DIV");
- div.style.position = "relative";
- div.className = "CodeMirror-wrapping";
- div.style.width = options.width;
- div.style.height = options.height;
-
- if (place.appendChild) place.appendChild(div);
- else place(div);
- div.appendChild(frame);
- if (options.lineNumbers) this.lineNumbers = addLineNumberDiv(div);
-
- // Link back to this object, so that the editor can fetch options
- // and add a reference to itself.
- frame.CodeMirror = this;
- this.win = frame.contentWindow;
-
- if (typeof options.parserfile == "string")
- options.parserfile = [options.parserfile];
- if (typeof options.stylesheet == "string")
- options.stylesheet = [options.stylesheet];
-
- var html = [""];
- // Hack to work around a bunch of IE8-specific problems.
- html.push("");
- forEach(options.stylesheet, function (file) {
- html.push("");
- });
- forEach(options.basefiles.concat(options.parserfile), function (file) {
- html.push("= 0; i--)
- cc.push(fs[i]);
- }
-
- // cont and pass are used by the action core to add other
- // actions to the stack. cont will cause the current token to be
- // consumed, pass will leave it for the next action.
- function cont() {
- push(arguments);
- consume = true;
- }
-
- function pass() {
- push(arguments);
- consume = false;
- }
-
- // Used to change the style of the current token.
- function mark(style) {
- marked = style;
- }
-
- // Push a new scope. Will automatically link the current scope.
- function pushcontext() {
- context = {prev: context, vars: {"this": true, "arguments": true}};
- }
-
- // Pop off the current scope.
- function popcontext() {
- context = context.prev;
- }
-
- // Register a variable in the current scope.
- function register(varname) {
- if (context) {
- mark("js-variabledef");
- context.vars[varname] = true;
- }
- }
-
- // Check whether a variable is defined in the current scope.
- function inScope(varname) {
- var cursor = context;
- while (cursor) {
- if (cursor.vars[varname])
- return true;
- cursor = cursor.prev;
- }
- return false;
- }
-
- // Push a new lexical context of the given type.
- function pushlex(type, info) {
- var result = function () {
- lexical = new JSLexical(indented, column, type, null, lexical, info)
- };
- result.lex = true;
- return result;
- }
-
- // Pop off the current lexical context.
- function poplex() {
- lexical = lexical.prev;
- }
-
- poplex.lex = true;
- // The 'lex' flag on these actions is used by the 'next' function
- // to know they can (and have to) be ran before moving on to the
- // next token.
-
- // Creates an action that discards tokens until it finds one of
- // the given type.
- function expect(wanted) {
- return function expecting(type) {
- if (type == wanted) cont();
- else cont(arguments.callee);
- };
- }
-
- // Looks for a statement, and then calls itself.
- function statements(type) {
- return pass(statement, statements);
- }
-
- // Dispatches various types of statements based on the type of the
- // current token.
- function statement(type) {
- if (type == "var") cont(pushlex("vardef"), vardef1, expect(";"), poplex);
- else if (type == "keyword a") cont(pushlex("form"), expression, statement, poplex);
- else if (type == "keyword b") cont(pushlex("form"), statement, poplex);
- else if (type == "{" && json) cont(pushlex("}"), commasep(objprop, "}"), poplex);
- else if (type == "{") cont(pushlex("}"), block, poplex);
- else if (type == "function") cont(functiondef);
- else if (type == "for") cont(pushlex("form"), expect("("), pushlex(")"), forspec1, expect(")"), poplex, statement, poplex);
- else if (type == "variable") cont(pushlex("stat"), maybelabel);
- else if (type == "switch") cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"), block, poplex, poplex);
- else if (type == "case") cont(expression, expect(":"));
- else if (type == "default") cont(expect(":"));
- else if (type == "catch") cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"), statement, poplex, popcontext);
- else pass(pushlex("stat"), expression, expect(";"), poplex);
- }
-
- // Dispatch expression types.
- function expression(type) {
- if (atomicTypes.hasOwnProperty(type)) cont(maybeoperator);
- else if (type == "function") cont(functiondef);
- else if (type == "keyword c") cont(expression);
- else if (type == "(") cont(pushlex(")"), expression, expect(")"), poplex, maybeoperator);
- else if (type == "operator") cont(expression);
- else if (type == "[") cont(pushlex("]"), commasep(expression, "]"), poplex, maybeoperator);
- else if (type == "{") cont(pushlex("}"), commasep(objprop, "}"), poplex, maybeoperator);
- }
-
- // Called for places where operators, function calls, or
- // subscripts are valid. Will skip on to the next action if none
- // is found.
- function maybeoperator(type) {
- if (type == "operator") cont(expression);
- else if (type == "(") cont(pushlex(")"), expression, commasep(expression, ")"), poplex, maybeoperator);
- else if (type == ".") cont(property, maybeoperator);
- else if (type == "[") cont(pushlex("]"), expression, expect("]"), poplex, maybeoperator);
- }
-
- // When a statement starts with a variable name, it might be a
- // label. If no colon follows, it's a regular statement.
- function maybelabel(type) {
- if (type == ":") cont(poplex, statement);
- else pass(maybeoperator, expect(";"), poplex);
- }
-
- // Property names need to have their style adjusted -- the
- // tokenizer thinks they are variables.
- function property(type) {
- if (type == "variable") {
- mark("js-property");
- cont();
- }
- }
-
- // This parses a property and its value in an object literal.
- function objprop(type) {
- if (type == "variable") mark("js-property");
- if (atomicTypes.hasOwnProperty(type)) cont(expect(":"), expression);
- }
-
- // Parses a comma-separated list of the things that are recognised
- // by the 'what' argument.
- function commasep(what, end) {
- function proceed(type) {
- if (type == ",") cont(what, proceed);
- else if (type == end) cont();
- else cont(expect(end));
- };
- return function commaSeparated(type) {
- if (type == end) cont();
- else pass(what, proceed);
- };
- }
-
- // Look for statements until a closing brace is found.
- function block(type) {
- if (type == "}") cont();
- else pass(statement, block);
- }
-
- // Variable definitions are split into two actions -- 1 looks for
- // a name or the end of the definition, 2 looks for an '=' sign or
- // a comma.
- function vardef1(type, value) {
- if (type == "variable") {
- register(value);
- cont(vardef2);
- } else cont();
- }
-
- function vardef2(type, value) {
- if (value == "=") cont(expression, vardef2);
- else if (type == ",") cont(vardef1);
- }
-
- // For loops.
- function forspec1(type) {
- if (type == "var") cont(vardef1, forspec2);
- else if (type == ";") pass(forspec2);
- else if (type == "variable") cont(formaybein);
- else pass(forspec2);
- }
-
- function formaybein(type, value) {
- if (value == "in") cont(expression);
- else cont(maybeoperator, forspec2);
- }
-
- function forspec2(type, value) {
- if (type == ";") cont(forspec3);
- else if (value == "in") cont(expression);
- else cont(expression, expect(";"), forspec3);
- }
-
- function forspec3(type) {
- if (type == ")") pass();
- else cont(expression);
- }
-
- // A function definition creates a new context, and the variables
- // in its argument list have to be added to this context.
- function functiondef(type, value) {
- if (type == "variable") {
- register(value);
- cont(functiondef);
- } else if (type == "(") cont(pushcontext, commasep(funarg, ")"), statement, popcontext);
- }
-
- function funarg(type, value) {
- if (type == "variable") {
- register(value);
- cont();
- }
- }
-
- return parser;
- }
-
- return {
- make: parseJS,
- electricChars: "{}:",
- configure: function (obj) {
- if (obj.json != null) json = obj.json;
- }
- };
-})();
diff --git a/cms/js/codemirror/js/parsesparql.js b/cms/js/codemirror/js/parsesparql.js
deleted file mode 100644
index 16dbf40..0000000
--- a/cms/js/codemirror/js/parsesparql.js
+++ /dev/null
@@ -1,153 +0,0 @@
-var SparqlParser = Editor.Parser = (function () {
- function wordRegexp(words) {
- return new RegExp("^(?:" + words.join("|") + ")$", "i");
- }
-
- var ops = wordRegexp(["str", "lang", "langmatches", "datatype", "bound", "sameterm", "isiri", "isuri",
- "isblank", "isliteral", "union", "a"]);
- var keywords = wordRegexp(["base", "prefix", "select", "distinct", "reduced", "construct", "describe",
- "ask", "from", "named", "where", "order", "limit", "offset", "filter", "optional",
- "graph", "by", "asc", "desc",]);
- var operatorChars = /[*+\-<>=&|]/;
-
- var tokenizeSparql = (function () {
- function normal(source, setState) {
- var ch = source.next();
- if (ch == "$" || ch == "?") {
- source.nextWhileMatches(/[\w\d]/);
- return "sp-var";
- } else if (ch == "<" && !source.matches(/[\s\u00a0=]/)) {
- source.nextWhileMatches(/[^\s\u00a0>]/);
- if (source.equals(">")) source.next();
- return "sp-uri";
- } else if (ch == "\"" || ch == "'") {
- setState(inLiteral(ch));
- return null;
- } else if (/[{}\(\),\.;\[\]]/.test(ch)) {
- return "sp-punc";
- } else if (ch == "#") {
- while (!source.endOfLine()) source.next();
- return "sp-comment";
- } else if (operatorChars.test(ch)) {
- source.nextWhileMatches(operatorChars);
- return "sp-operator";
- } else if (ch == ":") {
- source.nextWhileMatches(/[\w\d\._\-]/);
- return "sp-prefixed";
- } else {
- source.nextWhileMatches(/[_\w\d]/);
- if (source.equals(":")) {
- source.next();
- source.nextWhileMatches(/[\w\d_\-]/);
- return "sp-prefixed";
- }
- var word = source.get(), type;
- if (ops.test(word))
- type = "sp-operator";
- else if (keywords.test(word))
- type = "sp-keyword";
- else
- type = "sp-word";
- return {style: type, content: word};
- }
- }
-
- function inLiteral(quote) {
- return function (source, setState) {
- var escaped = false;
- while (!source.endOfLine()) {
- var ch = source.next();
- if (ch == quote && !escaped) {
- setState(normal);
- break;
- }
- escaped = !escaped && ch == "\\";
- }
- return "sp-literal";
- };
- }
-
- return function (source, startState) {
- return tokenizer(source, startState || normal);
- };
- })();
-
- function indentSparql(context) {
- return function (nextChars) {
- var firstChar = nextChars && nextChars.charAt(0);
- if (/[\]\}]/.test(firstChar))
- while (context && context.type == "pattern") context = context.prev;
-
- var closing = context && firstChar == matching[context.type];
- if (!context)
- return 0;
- else if (context.type == "pattern")
- return context.col;
- else if (context.align)
- return context.col - (closing ? context.width : 0);
- else
- return context.indent + (closing ? 0 : indentUnit);
- }
- }
-
- function parseSparql(source) {
- var tokens = tokenizeSparql(source);
- var context = null, indent = 0, col = 0;
-
- function pushContext(type, width) {
- context = {prev: context, indent: indent, col: col, type: type, width: width};
- }
-
- function popContext() {
- context = context.prev;
- }
-
- var iter = {
- next: function () {
- var token = tokens.next(), type = token.style, content = token.content, width = token.value.length;
-
- if (content == "\n") {
- token.indentation = indentSparql(context);
- indent = col = 0;
- if (context && context.align == null) context.align = false;
- } else if (type == "whitespace" && col == 0) {
- indent = width;
- } else if (type != "sp-comment" && context && context.align == null) {
- context.align = true;
- }
-
- if (content != "\n") col += width;
-
- if (/[\[\{\(]/.test(content)) {
- pushContext(content, width);
- } else if (/[\]\}\)]/.test(content)) {
- while (context && context.type == "pattern")
- popContext();
- if (context && content == matching[context.type])
- popContext();
- } else if (content == "." && context && context.type == "pattern") {
- popContext();
- } else if ((type == "sp-word" || type == "sp-prefixed" || type == "sp-uri" || type == "sp-var" || type == "sp-literal") &&
- context && /[\{\[]/.test(context.type)) {
- pushContext("pattern", width);
- }
-
- return token;
- },
-
- copy: function () {
- var _context = context, _indent = indent, _col = col, _tokenState = tokens.state;
- return function (source) {
- tokens = tokenizeSparql(source, _tokenState);
- context = _context;
- indent = _indent;
- col = _col;
- return iter;
- };
- }
- };
- return iter;
- }
-
- return {make: parseSparql, electricChars: "}]"};
-})();
diff --git a/cms/js/codemirror/js/parsexml.js b/cms/js/codemirror/js/parsexml.js
deleted file mode 100644
index 7bc4006..0000000
--- a/cms/js/codemirror/js/parsexml.js
+++ /dev/null
@@ -1,295 +0,0 @@
-/* This file defines an XML parser, with a few kludges to make it
- * useable for HTML. autoSelfClosers defines a set of tag names that
- * are expected to not have a closing tag, and doNotIndent specifies
- * the tags inside of which no indentation should happen (see Config
- * object). These can be disabled by passing the editor an object like
- * {useHTMLKludges: false} as parserConfig option.
- */
-
-var XMLParser = Editor.Parser = (function () {
- var Kludges = {
- autoSelfClosers: {
- "br": true, "img": true, "hr": true, "link": true, "input": true,
- "meta": true, "col": true, "frame": true, "base": true, "area": true
- },
- doNotIndent: {"pre": true, "!cdata": true}
- };
- var NoKludges = {autoSelfClosers: {}, doNotIndent: {"!cdata": true}};
- var UseKludges = Kludges;
- var alignCDATA = false;
-
- // Simple stateful tokenizer for XML documents. Returns a
- // MochiKit-style iterator, with a state property that contains a
- // function encapsulating the current state. See tokenize.js.
- var tokenizeXML = (function () {
- function inText(source, setState) {
- var ch = source.next();
- if (ch == "<") {
- if (source.equals("!")) {
- source.next();
- if (source.equals("[")) {
- if (source.lookAhead("[CDATA[", true)) {
- setState(inBlock("xml-cdata", "]]>"));
- return null;
- } else {
- return "xml-text";
- }
- } else if (source.lookAhead("--", true)) {
- setState(inBlock("xml-comment", "-->"));
- return null;
- } else {
- return "xml-text";
- }
- } else if (source.equals("?")) {
- source.next();
- source.nextWhileMatches(/[\w\._\-]/);
- setState(inBlock("xml-processing", "?>"));
- return "xml-processing";
- } else {
- if (source.equals("/")) source.next();
- setState(inTag);
- return "xml-punctuation";
- }
- } else if (ch == "&") {
- while (!source.endOfLine()) {
- if (source.next() == ";")
- break;
- }
- return "xml-entity";
- } else {
- source.nextWhileMatches(/[^&<\n]/);
- return "xml-text";
- }
- }
-
- function inTag(source, setState) {
- var ch = source.next();
- if (ch == ">") {
- setState(inText);
- return "xml-punctuation";
- } else if (/[?\/]/.test(ch) && source.equals(">")) {
- source.next();
- setState(inText);
- return "xml-punctuation";
- } else if (ch == "=") {
- return "xml-punctuation";
- } else if (/[\'\"]/.test(ch)) {
- setState(inAttribute(ch));
- return null;
- } else {
- source.nextWhileMatches(/[^\s\u00a0=<>\"\'\/?]/);
- return "xml-name";
- }
- }
-
- function inAttribute(quote) {
- return function (source, setState) {
- while (!source.endOfLine()) {
- if (source.next() == quote) {
- setState(inTag);
- break;
- }
- }
- return "xml-attribute";
- };
- }
-
- function inBlock(style, terminator) {
- return function (source, setState) {
- while (!source.endOfLine()) {
- if (source.lookAhead(terminator, true)) {
- setState(inText);
- break;
- }
- source.next();
- }
- return style;
- };
- }
-
- return function (source, startState) {
- return tokenizer(source, startState || inText);
- };
- })();
-
- // The parser. The structure of this function largely follows that of
- // parseJavaScript in parsejavascript.js (there is actually a bit more
- // shared code than I'd like), but it is quite a bit simpler.
- function parseXML(source) {
- var tokens = tokenizeXML(source);
- var cc = [base];
- var tokenNr = 0, indented = 0;
- var currentTag = null, context = null;
- var consume, marked;
-
- function push(fs) {
- for (var i = fs.length - 1; i >= 0; i--)
- cc.push(fs[i]);
- }
-
- function cont() {
- push(arguments);
- consume = true;
- }
-
- function pass() {
- push(arguments);
- consume = false;
- }
-
- function mark(style) {
- marked = style;
- }
-
- function expect(text) {
- return function (style, content) {
- if (content == text) cont();
- else mark("xml-error") || cont(arguments.callee);
- };
- }
-
- function pushContext(tagname, startOfLine) {
- var noIndent = UseKludges.doNotIndent.hasOwnProperty(tagname) || (context && context.noIndent);
- context = {prev: context, name: tagname, indent: indented, startOfLine: startOfLine, noIndent: noIndent};
- }
-
- function popContext() {
- context = context.prev;
- }
-
- function computeIndentation(baseContext) {
- return function (nextChars, current) {
- var context = baseContext;
- if (context && context.noIndent)
- return current;
- if (alignCDATA && /"));
- else if (style == "xml-cdata") {
- if (!context || context.name != "!cdata") pushContext("!cdata");
- if (/\]\]>$/.test(content)) popContext();
- cont();
- } else if (harmlessTokens.hasOwnProperty(style)) cont();
- else mark("xml-error") || cont();
- }
-
- function tagname(style, content) {
- if (style == "xml-name") {
- currentTag = content.toLowerCase();
- mark("xml-tagname");
- cont();
- } else {
- currentTag = null;
- pass();
- }
- }
-
- function closetagname(style, content) {
- if (style == "xml-name" && context && content.toLowerCase() == context.name) {
- popContext();
- mark("xml-tagname");
- } else {
- mark("xml-error");
- }
- cont();
- }
-
- function endtag(startOfLine) {
- return function (style, content) {
- if (content == "/>" || (content == ">" && UseKludges.autoSelfClosers.hasOwnProperty(currentTag))) cont();
- else if (content == ">") pushContext(currentTag, startOfLine) || cont();
- else mark("xml-error") || cont(arguments.callee);
- };
- }
-
- function attributes(style) {
- if (style == "xml-name") mark("xml-attname") || cont(attribute, attributes);
- else pass();
- }
-
- function attribute(style, content) {
- if (content == "=") cont(value);
- else if (content == ">" || content == "/>") pass(endtag);
- else pass();
- }
-
- function value(style) {
- if (style == "xml-attribute") cont(value);
- else pass();
- }
-
- return {
- indentation: function () {
- return indented;
- },
-
- next: function () {
- var token = tokens.next();
- if (token.style == "whitespace" && tokenNr == 0)
- indented = token.value.length;
- else
- tokenNr++;
- if (token.content == "\n") {
- indented = tokenNr = 0;
- token.indentation = computeIndentation(context);
- }
-
- if (token.style == "whitespace" || token.type == "xml-comment")
- return token;
-
- while (true) {
- consume = marked = false;
- cc.pop()(token.style, token.content);
- if (consume) {
- if (marked)
- token.style = marked;
- return token;
- }
- }
- },
-
- copy: function () {
- var _cc = cc.concat([]), _tokenState = tokens.state, _context = context;
- var parser = this;
-
- return function (input) {
- cc = _cc.concat([]);
- tokenNr = indented = 0;
- context = _context;
- tokens = tokenizeXML(input, _tokenState);
- return parser;
- };
- }
- };
- }
-
- return {
- make: parseXML,
- electricChars: "/",
- configure: function (config) {
- if (config.useHTMLKludges != null)
- UseKludges = config.useHTMLKludges ? Kludges : NoKludges;
- if (config.alignCDATA)
- alignCDATA = config.alignCDATA;
- }
- };
-})();
diff --git a/cms/js/codemirror/js/select.js b/cms/js/codemirror/js/select.js
deleted file mode 100644
index 0710b81..0000000
--- a/cms/js/codemirror/js/select.js
+++ /dev/null
@@ -1,612 +0,0 @@
-/* Functionality for finding, storing, and restoring selections
- *
- * This does not provide a generic API, just the minimal functionality
- * required by the CodeMirror system.
- */
-
-// Namespace object.
-var select = {};
-
-(function () {
- select.ie_selection = document.selection && document.selection.createRangeCollection;
-
- // Find the 'top-level' (defined as 'a direct child of the node
- // passed as the top argument') node that the given node is
- // contained in. Return null if the given node is not inside the top
- // node.
- function topLevelNodeAt(node, top) {
- while (node && node.parentNode != top)
- node = node.parentNode;
- return node;
- }
-
- // Find the top-level node that contains the node before this one.
- function topLevelNodeBefore(node, top) {
- while (!node.previousSibling && node.parentNode != top)
- node = node.parentNode;
- return topLevelNodeAt(node.previousSibling, top);
- }
-
- var fourSpaces = "\u00a0\u00a0\u00a0\u00a0";
-
- select.scrollToNode = function (element) {
- if (!element) return;
- var doc = element.ownerDocument, body = doc.body,
- win = (doc.defaultView || doc.parentWindow),
- html = doc.documentElement,
- atEnd = !element.nextSibling || !element.nextSibling.nextSibling
- || !element.nextSibling.nextSibling.nextSibling;
- // In Opera (and recent Webkit versions), BR elements *always*
- // have a offsetTop property of zero.
- var compensateHack = 0;
- while (element && !element.offsetTop) {
- compensateHack++;
- element = element.previousSibling;
- }
- // atEnd is another kludge for these browsers -- if the cursor is
- // at the end of the document, and the node doesn't have an
- // offset, just scroll to the end.
- if (compensateHack == 0) atEnd = false;
-
- var y = compensateHack * (element ? element.offsetHeight : 0), x = 0, pos = element;
- while (pos && pos.offsetParent) {
- y += pos.offsetTop;
- // Don't count X offset for nodes
- if (!isBR(pos))
- x += pos.offsetLeft;
- pos = pos.offsetParent;
- }
-
- var scroll_x = body.scrollLeft || html.scrollLeft || 0,
- scroll_y = body.scrollTop || html.scrollTop || 0,
- screen_x = x - scroll_x, screen_y = y - scroll_y, scroll = false;
-
- if (screen_x < 0 || screen_x > (win.innerWidth || html.clientWidth || 0)) {
- scroll_x = x;
- scroll = true;
- }
- if (screen_y < 0 || atEnd || screen_y > (win.innerHeight || html.clientHeight || 0) - 50) {
- scroll_y = atEnd ? 1e6 : y;
- scroll = true;
- }
- if (scroll) win.scrollTo(scroll_x, scroll_y);
- };
-
- select.scrollToCursor = function (container) {
- select.scrollToNode(select.selectionTopNode(container, true) || container.firstChild);
- };
-
- // Used to prevent restoring a selection when we do not need to.
- var currentSelection = null;
-
- select.snapshotChanged = function () {
- if (currentSelection) currentSelection.changed = true;
- };
-
- // This is called by the code in editor.js whenever it is replacing
- // a text node. The function sees whether the given oldNode is part
- // of the current selection, and updates this selection if it is.
- // Because nodes are often only partially replaced, the length of
- // the part that gets replaced has to be taken into account -- the
- // selection might stay in the oldNode if the newNode is smaller
- // than the selection's offset. The offset argument is needed in
- // case the selection does move to the new object, and the given
- // length is not the whole length of the new node (part of it might
- // have been used to replace another node).
- select.snapshotReplaceNode = function (from, to, length, offset) {
- if (!currentSelection) return;
-
- function replace(point) {
- if (from == point.node) {
- currentSelection.changed = true;
- if (length && point.offset > length) {
- point.offset -= length;
- } else {
- point.node = to;
- point.offset += (offset || 0);
- }
- }
- }
-
- replace(currentSelection.start);
- replace(currentSelection.end);
- };
-
- select.snapshotMove = function (from, to, distance, relative, ifAtStart) {
- if (!currentSelection) return;
-
- function move(point) {
- if (from == point.node && (!ifAtStart || point.offset == 0)) {
- currentSelection.changed = true;
- point.node = to;
- if (relative) point.offset = Math.max(0, point.offset + distance);
- else point.offset = distance;
- }
- }
-
- move(currentSelection.start);
- move(currentSelection.end);
- };
-
- // Most core are defined in two ways, one for the IE selection
- // model, one for the W3C one.
- if (select.ie_selection) {
- function selectionNode(win, start) {
- var range = win.document.selection.createRange();
- range.collapse(start);
-
- function nodeAfter(node) {
- var found = null;
- while (!found && node) {
- found = node.nextSibling;
- node = node.parentNode;
- }
- return nodeAtStartOf(found);
- }
-
- function nodeAtStartOf(node) {
- while (node && node.firstChild) node = node.firstChild;
- return {node: node, offset: 0};
- }
-
- var containing = range.parentElement();
- if (!isAncestor(win.document.body, containing)) return null;
- if (!containing.firstChild) return nodeAtStartOf(containing);
-
- var working = range.duplicate();
- working.moveToElementText(containing);
- working.collapse(true);
- for (var cur = containing.firstChild; cur; cur = cur.nextSibling) {
- if (cur.nodeType == 3) {
- var size = cur.nodeValue.length;
- working.move("character", size);
- } else {
- working.moveToElementText(cur);
- working.collapse(false);
- }
-
- var dir = range.compareEndPoints("StartToStart", working);
- if (dir == 0) return nodeAfter(cur);
- if (dir == 1) continue;
- if (cur.nodeType != 3) return nodeAtStartOf(cur);
-
- working.setEndPoint("StartToEnd", range);
- return {node: cur, offset: size - working.text.length};
- }
- return nodeAfter(containing);
- }
-
- select.markSelection = function (win) {
- currentSelection = null;
- var sel = win.document.selection;
- if (!sel) return;
- var start = selectionNode(win, true),
- end = selectionNode(win, false);
- if (!start || !end) return;
- currentSelection = {start: start, end: end, window: win, changed: false};
- };
-
- select.selectMarked = function () {
- if (!currentSelection || !currentSelection.changed) return;
- var win = currentSelection.window, doc = win.document;
-
- function makeRange(point) {
- var range = doc.body.createTextRange(),
- node = point.node;
- if (!node) {
- range.moveToElementText(currentSelection.window.document.body);
- range.collapse(false);
- } else if (node.nodeType == 3) {
- range.moveToElementText(node.parentNode);
- var offset = point.offset;
- while (node.previousSibling) {
- node = node.previousSibling;
- offset += (node.innerText || "").length;
- }
- range.move("character", offset);
- } else {
- range.moveToElementText(node);
- range.collapse(true);
- }
- return range;
- }
-
- var start = makeRange(currentSelection.start), end = makeRange(currentSelection.end);
- start.setEndPoint("StartToEnd", end);
- start.select();
- };
-
- // Get the top-level node that one end of the cursor is inside or
- // after. Note that this returns false for 'no cursor', and null
- // for 'start of document'.
- select.selectionTopNode = function (container, start) {
- var selection = container.ownerDocument.selection;
- if (!selection) return false;
-
- var range = selection.createRange(), range2 = range.duplicate();
- range.collapse(start);
- var around = range.parentElement();
- if (around && isAncestor(container, around)) {
- // Only use this node if the selection is not at its start.
- range2.moveToElementText(around);
- if (range.compareEndPoints("StartToStart", range2) == 1)
- return topLevelNodeAt(around, container);
- }
-
- // Move the start of a range to the start of a node,
- // compensating for the fact that you can't call
- // moveToElementText with text nodes.
- function moveToNodeStart(range, node) {
- if (node.nodeType == 3) {
- var count = 0, cur = node.previousSibling;
- while (cur && cur.nodeType == 3) {
- count += cur.nodeValue.length;
- cur = cur.previousSibling;
- }
- if (cur) {
- try {
- range.moveToElementText(cur);
- } catch (e) {
- return false;
- }
- range.collapse(false);
- } else range.moveToElementText(node.parentNode);
- if (count) range.move("character", count);
- } else {
- try {
- range.moveToElementText(node);
- } catch (e) {
- return false;
- }
- }
- return true;
- }
-
- // Do a binary search through the container object, comparing
- // the start of each node to the selection
- var start = 0, end = container.childNodes.length - 1;
- while (start < end) {
- var middle = Math.ceil((end + start) / 2), node = container.childNodes[middle];
- if (!node) return false; // Don't ask. IE6 manages this sometimes.
- if (!moveToNodeStart(range2, node)) return false;
- if (range.compareEndPoints("StartToStart", range2) == 1)
- start = middle;
- else
- end = middle - 1;
- }
- return container.childNodes[start] || null;
- };
-
- // Place the cursor after this.start. This is only useful when
- // manually moving the cursor instead of restoring it to its old
- // position.
- select.focusAfterNode = function (node, container) {
- var range = container.ownerDocument.body.createTextRange();
- range.moveToElementText(node || container);
- range.collapse(!node);
- range.select();
- };
-
- select.somethingSelected = function (win) {
- var sel = win.document.selection;
- return sel && (sel.createRange().text != "");
- };
-
- function insertAtCursor(window, html) {
- var selection = window.document.selection;
- if (selection) {
- var range = selection.createRange();
- range.pasteHTML(html);
- range.collapse(false);
- range.select();
- }
- }
-
- // Used to normalise the effect of the enter key, since browsers
- // do widely different things when pressing enter in designMode.
- select.insertNewlineAtCursor = function (window) {
- insertAtCursor(window, " ");
- };
-
- select.insertTabAtCursor = function (window) {
- insertAtCursor(window, fourSpaces);
- };
-
- // Get the BR node at the start of the line on which the cursor
- // currently is, and the offset into the line. Returns null as
- // node if cursor is on first line.
- select.cursorPos = function (container, start) {
- var selection = container.ownerDocument.selection;
- if (!selection) return null;
-
- var topNode = select.selectionTopNode(container, start);
- while (topNode && !isBR(topNode))
- topNode = topNode.previousSibling;
-
- var range = selection.createRange(), range2 = range.duplicate();
- range.collapse(start);
- if (topNode) {
- range2.moveToElementText(topNode);
- range2.collapse(false);
- } else {
- // When nothing is selected, we can get all kinds of funky errors here.
- try {
- range2.moveToElementText(container);
- } catch (e) {
- return null;
- }
- range2.collapse(true);
- }
- range.setEndPoint("StartToStart", range2);
-
- return {node: topNode, offset: range.text.length};
- };
-
- select.setCursorPos = function (container, from, to) {
- function rangeAt(pos) {
- var range = container.ownerDocument.body.createTextRange();
- if (!pos.node) {
- range.moveToElementText(container);
- range.collapse(true);
- } else {
- range.moveToElementText(pos.node);
- range.collapse(false);
- }
- range.move("character", pos.offset);
- return range;
- }
-
- var range = rangeAt(from);
- if (to && to != from)
- range.setEndPoint("EndToEnd", rangeAt(to));
- range.select();
- }
-
- // Some hacks for storing and re-storing the selection when the editor loses and regains focus.
- select.getBookmark = function (container) {
- var from = select.cursorPos(container, true), to = select.cursorPos(container, false);
- if (from && to) return {from: from, to: to};
- };
-
- // Restore a stored selection.
- select.setBookmark = function (container, mark) {
- if (!mark) return;
- select.setCursorPos(container, mark.from, mark.to);
- };
- }
- // W3C model
- else {
- // Store start and end nodes, and offsets within these, and refer
- // back to the selection object from those nodes, so that this
- // object can be updated when the nodes are replaced before the
- // selection is restored.
- select.markSelection = function (win) {
- var selection = win.getSelection();
- if (!selection || selection.rangeCount == 0)
- return (currentSelection = null);
- var range = selection.getRangeAt(0);
-
- currentSelection = {
- start: {node: range.startContainer, offset: range.startOffset},
- end: {node: range.endContainer, offset: range.endOffset},
- window: win,
- changed: false
- };
-
- // We want the nodes right at the cursor, not one of their
- // ancestors with a suitable offset. This goes down the DOM tree
- // until a 'leaf' is reached (or is it *up* the DOM tree?).
- function normalise(point) {
- while (point.node.nodeType != 3 && !isBR(point.node)) {
- var newNode = point.node.childNodes[point.offset] || point.node.nextSibling;
- point.offset = 0;
- while (!newNode && point.node.parentNode) {
- point.node = point.node.parentNode;
- newNode = point.node.nextSibling;
- }
- point.node = newNode;
- if (!newNode)
- break;
- }
- }
-
- normalise(currentSelection.start);
- normalise(currentSelection.end);
- };
-
- select.selectMarked = function () {
- var cs = currentSelection;
- if (!(cs && (cs.changed || (webkit && cs.start.node == cs.end.node)))) return;
- var win = cs.window, range = win.document.createRange();
-
- function setPoint(point, which) {
- if (point.node) {
- // Some magic to generalize the setting of the start and end
- // of a range.
- if (point.offset == 0)
- range["set" + which + "Before"](point.node);
- else
- range["set" + which](point.node, point.offset);
- } else {
- range.setStartAfter(win.document.body.lastChild || win.document.body);
- }
- }
-
- setPoint(cs.end, "End");
- setPoint(cs.start, "Start");
- selectRange(range, win);
- };
-
- // Helper for selecting a range object.
- function selectRange(range, window) {
- var selection = window.getSelection();
- selection.removeAllRanges();
- selection.addRange(range);
- };
-
- function selectionRange(window) {
- var selection = window.getSelection();
- if (!selection || selection.rangeCount == 0)
- return false;
- else
- return selection.getRangeAt(0);
- }
-
- // Finding the top-level node at the cursor in the W3C is, as you
- // can see, quite an involved process.
- select.selectionTopNode = function (container, start) {
- var range = selectionRange(container.ownerDocument.defaultView);
- if (!range) return false;
-
- var node = start ? range.startContainer : range.endContainer;
- var offset = start ? range.startOffset : range.endOffset;
- // Work around (yet another) bug in Opera's selection model.
- if (window.opera && !start && range.endContainer == container && range.endOffset == range.startOffset + 1 &&
- container.childNodes[range.startOffset] && isBR(container.childNodes[range.startOffset]))
- offset--;
-
- // For text nodes, we look at the node itself if the cursor is
- // inside, or at the node before it if the cursor is at the
- // start.
- if (node.nodeType == 3) {
- if (offset > 0)
- return topLevelNodeAt(node, container);
- else
- return topLevelNodeBefore(node, container);
- }
- // Occasionally, browsers will return the HTML node as
- // selection. If the offset is 0, we take the start of the frame
- // ('after null'), otherwise, we take the last node.
- else if (node.nodeName.toUpperCase() == "HTML") {
- return (offset == 1 ? null : container.lastChild);
- }
- // If the given node is our 'container', we just look up the
- // correct node by using the offset.
- else if (node == container) {
- return (offset == 0) ? null : node.childNodes[offset - 1];
- }
- // In any other case, we have a regular node. If the cursor is
- // at the end of the node, we use the node itself, if it is at
- // the start, we use the node before it, and in any other
- // case, we look up the child before the cursor and use that.
- else {
- if (offset == node.childNodes.length)
- return topLevelNodeAt(node, container);
- else if (offset == 0)
- return topLevelNodeBefore(node, container);
- else
- return topLevelNodeAt(node.childNodes[offset - 1], container);
- }
- };
-
- select.focusAfterNode = function (node, container) {
- var win = container.ownerDocument.defaultView,
- range = win.document.createRange();
- range.setStartBefore(container.firstChild || container);
- // In Opera, setting the end of a range at the end of a line
- // (before a BR) will cause the cursor to appear on the next
- // line, so we set the end inside of the start node when
- // possible.
- if (node && !node.firstChild)
- range.setEndAfter(node);
- else if (node)
- range.setEnd(node, node.childNodes.length);
- else
- range.setEndBefore(container.firstChild || container);
- range.collapse(false);
- selectRange(range, win);
- };
-
- select.somethingSelected = function (win) {
- var range = selectionRange(win);
- return range && !range.collapsed;
- };
-
- function insertNodeAtCursor(window, node) {
- var range = selectionRange(window);
- if (!range) return;
-
- range.deleteContents();
- range.insertNode(node);
- webkitLastLineHack(window.document.body);
- range = window.document.createRange();
- range.selectNode(node);
- range.collapse(false);
- selectRange(range, window);
- }
-
- select.insertNewlineAtCursor = function (window) {
- insertNodeAtCursor(window, window.document.createElement("BR"));
- };
-
- select.insertTabAtCursor = function (window) {
- insertNodeAtCursor(window, window.document.createTextNode(fourSpaces));
- };
-
- select.cursorPos = function (container, start) {
- var range = selectionRange(window);
- if (!range) return;
-
- var topNode = select.selectionTopNode(container, start);
- while (topNode && !isBR(topNode))
- topNode = topNode.previousSibling;
-
- range = range.cloneRange();
- range.collapse(start);
- if (topNode)
- range.setStartAfter(topNode);
- else
- range.setStartBefore(container);
- return {node: topNode, offset: range.toString().length};
- };
-
- select.setCursorPos = function (container, from, to) {
- var win = container.ownerDocument.defaultView,
- range = win.document.createRange();
-
- function setPoint(node, offset, side) {
- if (!node)
- node = container.firstChild;
- else
- node = node.nextSibling;
-
- if (!node)
- return;
-
- if (offset == 0) {
- range["set" + side + "Before"](node);
- return true;
- }
-
- var backlog = []
-
- function decompose(node) {
- if (node.nodeType == 3)
- backlog.push(node);
- else
- forEach(node.childNodes, decompose);
- }
-
- while (true) {
- while (node && !backlog.length) {
- decompose(node);
- node = node.nextSibling;
- }
- var cur = backlog.shift();
- if (!cur) return false;
-
- var length = cur.nodeValue.length;
- if (length >= offset) {
- range["set" + side](cur, offset);
- return true;
- }
- offset -= length;
- }
- }
-
- to = to || from;
- if (setPoint(to.node, to.offset, "End") && setPoint(from.node, from.offset, "Start"))
- selectRange(range, win);
- };
- }
-})();
diff --git a/cms/js/codemirror/js/stringstream.js b/cms/js/codemirror/js/stringstream.js
deleted file mode 100644
index 60684eb..0000000
--- a/cms/js/codemirror/js/stringstream.js
+++ /dev/null
@@ -1,146 +0,0 @@
-/* String streams are the things fed to parsers (which can feed them
- * to a tokenizer if they want). They provide peek and next methods
- * for looking at the current character (next 'consumes' this
- * character, peek does not), and a get method for retrieving all the
- * text that was consumed since the last time get was called.
- *
- * An easy mistake to make is to let a StopIteration exception finish
- * the token stream while there are still characters pending in the
- * string stream (hitting the end of the buffer while parsing a
- * token). To make it easier to detect such errors, the stringstreams
- * throw an exception when this happens.
- */
-
-// Make a stringstream stream out of an iterator that returns strings.
-// This is applied to the result of traverseDOM (see codemirror.js),
-// and the resulting stream is fed to the parser.
-window.stringStream = function (source) {
- // String that's currently being iterated over.
- var current = "";
- // Position in that string.
- var pos = 0;
- // Accumulator for strings that have been iterated over but not
- // get()-ed yet.
- var accum = "";
- // Make sure there are more characters ready, or throw
- // StopIteration.
- function ensureChars() {
- while (pos == current.length) {
- accum += current;
- current = ""; // In case source.next() throws
- pos = 0;
- try {
- current = source.next();
- } catch (e) {
- if (e != StopIteration) throw e;
- else return false;
- }
- }
- return true;
- }
-
- return {
- // Return the next character in the stream.
- peek: function () {
- if (!ensureChars()) return null;
- return current.charAt(pos);
- },
- // Get the next character, throw StopIteration if at end, check
- // for unused content.
- next: function () {
- if (!ensureChars()) {
- if (accum.length > 0)
- throw "End of stringstream reached without emptying buffer ('" + accum + "').";
- else
- throw StopIteration;
- }
- return current.charAt(pos++);
- },
- // Return the characters iterated over since the last call to
- // .get().
- get: function () {
- var temp = accum;
- accum = "";
- if (pos > 0) {
- temp += current.slice(0, pos);
- current = current.slice(pos);
- pos = 0;
- }
- return temp;
- },
- // Push a string back into the stream.
- push: function (str) {
- current = current.slice(0, pos) + str + current.slice(pos);
- },
- lookAhead: function (str, consume, skipSpaces, caseInsensitive) {
- function cased(str) {
- return caseInsensitive ? str.toLowerCase() : str;
- }
-
- str = cased(str);
- var found = false;
-
- var _accum = accum, _pos = pos;
- if (skipSpaces) this.nextWhileMatches(/[\s\u00a0]/);
-
- while (true) {
- var end = pos + str.length, left = current.length - pos;
- if (end <= current.length) {
- found = str == cased(current.slice(pos, end));
- pos = end;
- break;
- } else if (str.slice(0, left) == cased(current.slice(pos))) {
- accum += current;
- current = "";
- try {
- current = source.next();
- } catch (e) {
- break;
- }
- pos = 0;
- str = str.slice(left);
- } else {
- break;
- }
- }
-
- if (!(found && consume)) {
- current = accum.slice(_accum.length) + current;
- pos = _pos;
- accum = _accum;
- }
-
- return found;
- },
-
- // Utils built on top of the above
- more: function () {
- return this.peek() !== null;
- },
- applies: function (test) {
- var next = this.peek();
- return (next !== null && test(next));
- },
- nextWhile: function (test) {
- var next;
- while ((next = this.peek()) !== null && test(next))
- this.next();
- },
- matches: function (re) {
- var next = this.peek();
- return (next !== null && re.test(next));
- },
- nextWhileMatches: function (re) {
- var next;
- while ((next = this.peek()) !== null && re.test(next))
- this.next();
- },
- equals: function (ch) {
- return ch === this.peek();
- },
- endOfLine: function () {
- var next = this.peek();
- return next == null || next == "\n";
- }
- };
-};
diff --git a/cms/js/codemirror/js/tokenize.js b/cms/js/codemirror/js/tokenize.js
deleted file mode 100644
index bd552b1..0000000
--- a/cms/js/codemirror/js/tokenize.js
+++ /dev/null
@@ -1,59 +0,0 @@
-// A framework for simple tokenizers. Takes care of newlines and
-// white-space, and of getting the text from the source stream into
-// the token object. A state is a function of two arguments -- a
-// string stream and a setState function. The second can be used to
-// change the tokenizer's state, and can be ignored for stateless
-// tokenizers. This function should advance the stream over a token
-// and return a string or object containing information about the next
-// token, or null to pass and have the (new) state be called to finish
-// the token. When a string is given, it is wrapped in a {style, type}
-// object. In the resulting object, the characters consumed are stored
-// under the content property. Any whitespace following them is also
-// automatically consumed, and added to the value property. (Thus,
-// content is the actual meaningful part of the token, while value
-// contains all the text it spans.)
-
-function tokenizer(source, state) {
- // Newlines are always a separate token.
- function isWhiteSpace(ch) {
- // The messy regexp is because IE's regexp matcher is of the
- // opinion that non-breaking spaces are no whitespace.
- return ch != "\n" && /^[\s\u00a0]*$/.test(ch);
- }
-
- var tokenizer = {
- state: state,
-
- take: function (type) {
- if (typeof (type) == "string")
- type = {style: type, type: type};
-
- type.content = (type.content || "") + source.get();
- if (!/\n$/.test(type.content))
- source.nextWhile(isWhiteSpace);
- type.value = type.content + source.get();
- return type;
- },
-
- next: function () {
- if (!source.more()) throw StopIteration;
-
- var type;
- if (source.equals("\n")) {
- source.next();
- return this.take("whitespace");
- }
-
- if (source.applies(isWhiteSpace))
- type = "whitespace";
- else
- while (!type)
- type = this.state(source, function (s) {
- tokenizer.state = s;
- });
-
- return this.take(type);
- }
- };
- return tokenizer;
-}
diff --git a/cms/js/codemirror/js/tokenizejavascript.js b/cms/js/codemirror/js/tokenizejavascript.js
deleted file mode 100644
index 233e108..0000000
--- a/cms/js/codemirror/js/tokenizejavascript.js
+++ /dev/null
@@ -1,205 +0,0 @@
-/* Tokenizer for JavaScript code */
-
-var tokenizeJavaScript = (function () {
- // Advance the stream until the given character (not preceded by a
- // backslash) is encountered, or the end of the line is reached.
- function nextUntilUnescaped(source, end) {
- var escaped = false;
- var next;
- while (!source.endOfLine()) {
- var next = source.next();
- if (next == end && !escaped)
- return false;
- escaped = !escaped && next == "\\";
- }
- return escaped;
- }
-
- // A map of JavaScript's keywords. The a/b/c keyword distinction is
- // very rough, but it gives the parser enough information to parse
- // correct code correctly (we don't care that much how we parse
- // incorrect code). The style information included in these objects
- // is used by the highlighter to pick the correct CSS style for a
- // token.
- var keywords = function () {
- function result(type, style) {
- return {type: type, style: "js-" + style};
- }
-
- // keywords that take a parenthised expression, and then a
- // statement (if)
- var keywordA = result("keyword a", "keyword");
- // keywords that take just a statement (else)
- var keywordB = result("keyword b", "keyword");
- // keywords that optionally take an expression, and form a
- // statement (return)
- var keywordC = result("keyword c", "keyword");
- var operator = result("operator", "keyword");
- var atom = result("atom", "atom");
- return {
- "if": keywordA,
- "while": keywordA,
- "with": keywordA,
- "else": keywordB,
- "do": keywordB,
- "try": keywordB,
- "finally": keywordB,
- "return": keywordC,
- "break": keywordC,
- "continue": keywordC,
- "new": keywordC,
- "delete": keywordC,
- "throw": keywordC,
- "in": operator,
- "typeof": operator,
- "instanceof": operator,
- "var": result("var", "keyword"),
- "function": result("function", "keyword"),
- "catch": result("catch", "keyword"),
- "for": result("for", "keyword"),
- "switch": result("switch", "keyword"),
- "case": result("case", "keyword"),
- "default": result("default", "keyword"),
- "true": atom,
- "false": atom,
- "null": atom,
- "undefined": atom,
- "NaN": atom,
- "Infinity": atom
- };
- }();
-
- // Some helper regexps
- var isOperatorChar = /[+\-*&%=<>!?|]/;
- var isHexDigit = /[0-9A-Fa-f]/;
- var isWordChar = /[\w\$_]/;
-
- // Wrapper around jsToken that helps maintain parser state (whether
- // we are inside of a multi-line comment and whether the next token
- // could be a regular expression).
- function jsTokenState(inside, regexp) {
- return function (source, setState) {
- var newInside = inside;
- var type = jsToken(inside, regexp, source, function (c) {
- newInside = c;
- });
- var newRegexp = type.type == "operator" || type.type == "keyword c" || type.type.match(/^[\[{}\(,;:]$/);
- if (newRegexp != regexp || newInside != inside)
- setState(jsTokenState(newInside, newRegexp));
- return type;
- };
- }
-
- // The token reader, inteded to be used by the tokenizer from
- // tokenize.js (through jsTokenState). Advances the source stream
- // over a token, and returns an object containing the type and style
- // of that token.
- function jsToken(inside, regexp, source, setInside) {
- function readHexNumber() {
- source.next(); // skip the 'x'
- source.nextWhileMatches(isHexDigit);
- return {type: "number", style: "js-atom"};
- }
-
- function readNumber() {
- source.nextWhileMatches(/[0-9]/);
- if (source.equals(".")) {
- source.next();
- source.nextWhileMatches(/[0-9]/);
- }
- if (source.equals("e") || source.equals("E")) {
- source.next();
- if (source.equals("-"))
- source.next();
- source.nextWhileMatches(/[0-9]/);
- }
- return {type: "number", style: "js-atom"};
- }
-
- // Read a word, look it up in keywords. If not found, it is a
- // variable, otherwise it is a keyword of the type found.
- function readWord() {
- source.nextWhileMatches(isWordChar);
- var word = source.get();
- var known = keywords.hasOwnProperty(word) && keywords.propertyIsEnumerable(word) && keywords[word];
- return known ? {type: known.type, style: known.style, content: word} :
- {type: "variable", style: "js-variable", content: word};
- }
-
- function readRegexp() {
- nextUntilUnescaped(source, "/");
- source.nextWhileMatches(/[gi]/);
- return {type: "regexp", style: "js-string"};
- }
-
- // Mutli-line comments are tricky. We want to return the newlines
- // embedded in them as regular newline tokens, and then continue
- // returning a comment token for every line of the comment. So
- // some state has to be saved (inside) to indicate whether we are
- // inside a /* */ sequence.
- function readMultilineComment(start) {
- var newInside = "/*";
- var maybeEnd = (start == "*");
- while (true) {
- if (source.endOfLine())
- break;
- var next = source.next();
- if (next == "/" && maybeEnd) {
- newInside = null;
- break;
- }
- maybeEnd = (next == "*");
- }
- setInside(newInside);
- return {type: "comment", style: "js-comment"};
- }
-
- function readOperator() {
- source.nextWhileMatches(isOperatorChar);
- return {type: "operator", style: "js-operator"};
- }
-
- function readString(quote) {
- var endBackSlash = nextUntilUnescaped(source, quote);
- setInside(endBackSlash ? quote : null);
- return {type: "string", style: "js-string"};
- }
-
- // Fetch the next token. Dispatches on first character in the
- // stream, or first two characters when the first is a slash.
- if (inside == "\"" || inside == "'")
- return readString(inside);
- var ch = source.next();
- if (inside == "/*")
- return readMultilineComment(ch);
- else if (ch == "\"" || ch == "'")
- return readString(ch);
- // with punctuation, the type of the token is the symbol itself
- else if (/[\[\]{}\(\),;\:\.]/.test(ch))
- return {type: ch, style: "js-punctuation"};
- else if (ch == "0" && (source.equals("x") || source.equals("X")))
- return readHexNumber();
- else if (/[0-9]/.test(ch))
- return readNumber();
- else if (ch == "/") {
- if (source.equals("*")) {
- source.next();
- return readMultilineComment(ch);
- } else if (source.equals("/")) {
- nextUntilUnescaped(source, null);
- return {type: "comment", style: "js-comment"};
- } else if (regexp)
- return readRegexp();
- else
- return readOperator();
- } else if (isOperatorChar.test(ch))
- return readOperator();
- else
- return readWord();
- }
-
- // The external interface to the tokenizer.
- return function (source, startState) {
- return tokenizer(source, startState || jsTokenState(false, true));
- };
-})();
diff --git a/cms/js/codemirror/js/undo.js b/cms/js/codemirror/js/undo.js
deleted file mode 100644
index 3e9c77f..0000000
--- a/cms/js/codemirror/js/undo.js
+++ /dev/null
@@ -1,423 +0,0 @@
-/**
- * Storage and control for undo information within a CodeMirror
- * editor. 'Why on earth is such a complicated mess required for
- * that?', I hear you ask. The goal, in implementing this, was to make
- * the complexity of storing and reverting undo information depend
- * only on the size of the edited or restored content, not on the size
- * of the whole document. This makes it necessary to use a kind of
- * 'diff' system, which, when applied to a DOM tree, causes some
- * complexity and hackery.
- *
- * In short, the editor 'touches' BR elements as it parses them, and
- * the History stores these. When nothing is touched in commitDelay
- * milliseconds, the changes are committed: It goes over all touched
- * nodes, throws out the ones that did not change since last commit or
- * are no longer in the document, and assembles the rest into zero or
- * more 'chains' -- arrays of adjacent lines. Links back to these
- * chains are added to the BR nodes, while the chain that previously
- * spanned these nodes is added to the undo history. Undoing a change
- * means taking such a chain off the undo history, restoring its
- * content (text is saved per line) and linking it back into the
- * document.
- */
-
-// A history object needs to know about the DOM container holding the
-// document, the maximum amount of undo levels it should store, the
-// delay (of no input) after which it commits a set of changes, and,
-// unfortunately, the 'parent' window -- a window that is not in
-// designMode, and on which setTimeout works in every browser.
-function History(container, maxDepth, commitDelay, editor) {
- this.container = container;
- this.maxDepth = maxDepth;
- this.commitDelay = commitDelay;
- this.editor = editor;
- this.parent = editor.parent;
- // This line object represents the initial, empty editor.
- var initial = {text: "", from: null, to: null};
- // As the borders between lines are represented by BR elements, the
- // start of the first line and the end of the last one are
- // represented by null. Since you can not store any properties
- // (links to line objects) in null, these properties are used in
- // those cases.
- this.first = initial;
- this.last = initial;
- // Similarly, a 'historyTouched' property is added to the BR in
- // front of lines that have already been touched, and 'firstTouched'
- // is used for the first line.
- this.firstTouched = false;
- // History is the set of committed changes, touched is the set of
- // nodes touched since the last commit.
- this.history = [];
- this.redoHistory = [];
- this.touched = [];
-}
-
-History.prototype = {
- // Schedule a commit (if no other touches come in for commitDelay
- // milliseconds).
- scheduleCommit: function () {
- var self = this;
- this.parent.clearTimeout(this.commitTimeout);
- this.commitTimeout = this.parent.setTimeout(function () {
- self.tryCommit();
- }, this.commitDelay);
- },
-
- // Mark a node as touched. Null is a valid argument.
- touch: function (node) {
- this.setTouched(node);
- this.scheduleCommit();
- },
-
- // Undo the last change.
- undo: function () {
- // Make sure pending changes have been committed.
- this.commit();
-
- if (this.history.length) {
- // Take the top diff from the history, apply it, and store its
- // shadow in the redo history.
- var item = this.history.pop();
- this.redoHistory.push(this.updateTo(item, "applyChain"));
- this.notifyEnvironment();
- return this.chainNode(item);
- }
- },
-
- // Redo the last undone change.
- redo: function () {
- this.commit();
- if (this.redoHistory.length) {
- // The inverse of undo, basically.
- var item = this.redoHistory.pop();
- this.addUndoLevel(this.updateTo(item, "applyChain"));
- this.notifyEnvironment();
- return this.chainNode(item);
- }
- },
-
- clear: function () {
- this.history = [];
- this.redoHistory = [];
- },
-
- // Ask for the size of the un/redo histories.
- historySize: function () {
- return {undo: this.history.length, redo: this.redoHistory.length};
- },
-
- // Push a changeset into the document.
- push: function (from, to, lines) {
- var chain = [];
- for (var i = 0; i < lines.length; i++) {
- var end = (i == lines.length - 1) ? to : this.container.ownerDocument.createElement("BR");
- chain.push({from: from, to: end, text: cleanText(lines[i])});
- from = end;
- }
- this.pushChains([chain], from == null && to == null);
- this.notifyEnvironment();
- },
-
- pushChains: function (chains, doNotHighlight) {
- this.commit(doNotHighlight);
- this.addUndoLevel(this.updateTo(chains, "applyChain"));
- this.redoHistory = [];
- },
-
- // Retrieve a DOM node from a chain (for scrolling to it after undo/redo).
- chainNode: function (chains) {
- for (var i = 0; i < chains.length; i++) {
- var start = chains[i][0], node = start && (start.from || start.to);
- if (node) return node;
- }
- },
-
- // Clear the undo history, make the current document the start
- // position.
- reset: function () {
- this.history = [];
- this.redoHistory = [];
- },
-
- textAfter: function (br) {
- return this.after(br).text;
- },
-
- nodeAfter: function (br) {
- return this.after(br).to;
- },
-
- nodeBefore: function (br) {
- return this.before(br).from;
- },
-
- // Commit unless there are pending dirty nodes.
- tryCommit: function () {
- if (!window.History) return; // Stop when frame has been unloaded
- if (this.editor.highlightDirty()) this.commit(true);
- else this.scheduleCommit();
- },
-
- // Check whether the touched nodes hold any changes, if so, commit
- // them.
- commit: function (doNotHighlight) {
- this.parent.clearTimeout(this.commitTimeout);
- // Make sure there are no pending dirty nodes.
- if (!doNotHighlight) this.editor.highlightDirty(true);
- // Build set of chains.
- var chains = this.touchedChains(), self = this;
-
- if (chains.length) {
- this.addUndoLevel(this.updateTo(chains, "linkChain"));
- this.redoHistory = [];
- this.notifyEnvironment();
- }
- },
-
- // [ end of public interface ]
-
- // Update the document with a given set of chains, return its
- // shadow. updateFunc should be "applyChain" or "linkChain". In the
- // second case, the chains are taken to correspond the the current
- // document, and only the state of the line data is updated. In the
- // first case, the content of the chains is also pushed iinto the
- // document.
- updateTo: function (chains, updateFunc) {
- var shadows = [], dirty = [];
- for (var i = 0; i < chains.length; i++) {
- shadows.push(this.shadowChain(chains[i]));
- dirty.push(this[updateFunc](chains[i]));
- }
- if (updateFunc == "applyChain")
- this.notifyDirty(dirty);
- return shadows;
- },
-
- // Notify the editor that some nodes have changed.
- notifyDirty: function (nodes) {
- forEach(nodes, method(this.editor, "addDirtyNode"))
- this.editor.scheduleHighlight();
- },
-
- notifyEnvironment: function () {
- // Used by the line-wrapping line-numbering code.
- if (window.frameElement && window.frameElement.CodeMirror.updateNumbers)
- window.frameElement.CodeMirror.updateNumbers();
- if (this.onChange) this.onChange();
- },
-
- // Link a chain into the DOM nodes (or the first/last links for null
- // nodes).
- linkChain: function (chain) {
- for (var i = 0; i < chain.length; i++) {
- var line = chain[i];
- if (line.from) line.from.historyAfter = line;
- else this.first = line;
- if (line.to) line.to.historyBefore = line;
- else this.last = line;
- }
- },
-
- // Get the line object after/before a given node.
- after: function (node) {
- return node ? node.historyAfter : this.first;
- },
- before: function (node) {
- return node ? node.historyBefore : this.last;
- },
-
- // Mark a node as touched if it has not already been marked.
- setTouched: function (node) {
- if (node) {
- if (!node.historyTouched) {
- this.touched.push(node);
- node.historyTouched = true;
- }
- } else {
- this.firstTouched = true;
- }
- },
-
- // Store a new set of undo info, throw away info if there is more of
- // it than allowed.
- addUndoLevel: function (diffs) {
- this.history.push(diffs);
- if (this.history.length > this.maxDepth)
- this.history.shift();
- },
-
- // Build chains from a set of touched nodes.
- touchedChains: function () {
- var self = this;
-
- // The temp system is a crummy hack to speed up determining
- // whether a (currently touched) node has a line object associated
- // with it. nullTemp is used to store the object for the first
- // line, other nodes get it stored in their historyTemp property.
- var nullTemp = null;
-
- function temp(node) {
- return node ? node.historyTemp : nullTemp;
- }
-
- function setTemp(node, line) {
- if (node) node.historyTemp = line;
- else nullTemp = line;
- }
-
- function buildLine(node) {
- var text = [];
- for (var cur = node ? node.nextSibling : self.container.firstChild;
- cur && !isBR(cur); cur = cur.nextSibling)
- if (cur.currentText) text.push(cur.currentText);
- return {from: node, to: cur, text: cleanText(text.join(""))};
- }
-
- // Filter out unchanged lines and nodes that are no longer in the
- // document. Build up line objects for remaining nodes.
- var lines = [];
- if (self.firstTouched) self.touched.push(null);
- forEach(self.touched, function (node) {
- if (node && node.parentNode != self.container) return;
-
- if (node) node.historyTouched = false;
- else self.firstTouched = false;
-
- var line = buildLine(node), shadow = self.after(node);
- if (!shadow || shadow.text != line.text || shadow.to != line.to) {
- lines.push(line);
- setTemp(node, line);
- }
- });
-
- // Get the BR element after/before the given node.
- function nextBR(node, dir) {
- var link = dir + "Sibling", search = node[link];
- while (search && !isBR(search))
- search = search[link];
- return search;
- }
-
- // Assemble line objects into chains by scanning the DOM tree
- // around them.
- var chains = [];
- self.touched = [];
- forEach(lines, function (line) {
- // Note that this makes the loop skip line objects that have
- // been pulled into chains by lines before them.
- if (!temp(line.from)) return;
-
- var chain = [], curNode = line.from, safe = true;
- // Put any line objects (referred to by temp info) before this
- // one on the front of the array.
- while (true) {
- var curLine = temp(curNode);
- if (!curLine) {
- if (safe) break;
- else curLine = buildLine(curNode);
- }
- chain.unshift(curLine);
- setTemp(curNode, null);
- if (!curNode) break;
- safe = self.after(curNode);
- curNode = nextBR(curNode, "previous");
- }
- curNode = line.to;
- safe = self.before(line.from);
- // Add lines after this one at end of array.
- while (true) {
- if (!curNode) break;
- var curLine = temp(curNode);
- if (!curLine) {
- if (safe) break;
- else curLine = buildLine(curNode);
- }
- chain.push(curLine);
- setTemp(curNode, null);
- safe = self.before(curNode);
- curNode = nextBR(curNode, "next");
- }
- chains.push(chain);
- });
-
- return chains;
- },
-
- // Find the 'shadow' of a given chain by following the links in the
- // DOM nodes at its start and end.
- shadowChain: function (chain) {
- var shadows = [], next = this.after(chain[0].from), end = chain[chain.length - 1].to;
- while (true) {
- shadows.push(next);
- var nextNode = next.to;
- if (!nextNode || nextNode == end)
- break;
- else
- next = nextNode.historyAfter || this.before(end);
- // (The this.before(end) is a hack -- FF sometimes removes
- // properties from BR nodes, in which case the best we can hope
- // for is to not break.)
- }
- return shadows;
- },
-
- // Update the DOM tree to contain the lines specified in a given
- // chain, link this chain into the DOM nodes.
- applyChain: function (chain) {
- // Some attempt is made to prevent the cursor from jumping
- // randomly when an undo or redo happens. It still behaves a bit
- // strange sometimes.
- var cursor = select.cursorPos(this.container, false), self = this;
-
- // Remove all nodes in the DOM tree between from and to (null for
- // start/end of container).
- function removeRange(from, to) {
- var pos = from ? from.nextSibling : self.container.firstChild;
- while (pos != to) {
- var temp = pos.nextSibling;
- removeElement(pos);
- pos = temp;
- }
- }
-
- var start = chain[0].from, end = chain[chain.length - 1].to;
- // Clear the space where this change has to be made.
- removeRange(start, end);
-
- // Insert the content specified by the chain into the DOM tree.
- for (var i = 0; i < chain.length; i++) {
- var line = chain[i];
- // The start and end of the space are already correct, but BR
- // tags inside it have to be put back.
- if (i > 0)
- self.container.insertBefore(line.from, end);
-
- // Add the text.
- var node = makePartSpan(fixSpaces(line.text), this.container.ownerDocument);
- self.container.insertBefore(node, end);
- // See if the cursor was on this line. Put it back, adjusting
- // for changed line length, if it was.
- if (cursor && cursor.node == line.from) {
- var cursordiff = 0;
- var prev = this.after(line.from);
- if (prev && i == chain.length - 1) {
- // Only adjust if the cursor is after the unchanged part of
- // the line.
- for (var match = 0; match < cursor.offset &&
- line.text.charAt(match) == prev.text.charAt(match); match++) ;
- if (cursor.offset > match)
- cursordiff = line.text.length - prev.text.length;
- }
- select.setCursorPos(this.container, {node: line.from, offset: Math.max(0, cursor.offset + cursordiff)});
- }
- // Cursor was in removed line, this is last new line.
- else if (cursor && (i == chain.length - 1) && cursor.node && cursor.node.parentNode != this.container) {
- select.setCursorPos(this.container, {node: line.from, offset: line.text.length});
- }
- }
-
- // Anchor the chain in the DOM tree.
- this.linkChain(chain);
- return start;
- }
-};
diff --git a/cms/js/codemirror/js/util.js b/cms/js/codemirror/js/util.js
deleted file mode 100644
index c4471a1..0000000
--- a/cms/js/codemirror/js/util.js
+++ /dev/null
@@ -1,157 +0,0 @@
-/* A few useful utility core. */
-
-var internetExplorer = document.selection && window.ActiveXObject && /MSIE/.test(navigator.userAgent);
-var webkit = /AppleWebKit/.test(navigator.userAgent);
-var safari = /Apple Computers, Inc/.test(navigator.vendor);
-
-// Capture a method on an object.
-function method(obj, name) {
- return function () {
- obj[name].apply(obj, arguments);
- };
-}
-
-// The value used to signal the end of a sequence in iterators.
-var StopIteration = {
- toString: function () {
- return "StopIteration"
- }
-};
-
-// Apply a function to each element in a sequence.
-function forEach(iter, f) {
- if (iter.next) {
- try {
- while (true) f(iter.next());
- } catch (e) {
- if (e != StopIteration) throw e;
- }
- } else {
- for (var i = 0; i < iter.length; i++)
- f(iter[i]);
- }
-}
-
-// Map a function over a sequence, producing an array of results.
-function map(iter, f) {
- var accum = [];
- forEach(iter, function (val) {
- accum.push(f(val));
- });
- return accum;
-}
-
-// Create a predicate function that tests a string againsts a given
-// regular expression. No longer used but might be used by 3rd party
-// parsers.
-function matcher(regexp) {
- return function (value) {
- return regexp.test(value);
- };
-}
-
-// Test whether a DOM node has a certain CSS class. Much faster than
-// the MochiKit equivalent, for some reason.
-function hasClass(element, className) {
- var classes = element.className;
- return classes && new RegExp("(^| )" + className + "($| )").test(classes);
-}
-
-// Insert a DOM node after another node.
-function insertAfter(newNode, oldNode) {
- var parent = oldNode.parentNode;
- parent.insertBefore(newNode, oldNode.nextSibling);
- return newNode;
-}
-
-function removeElement(node) {
- if (node.parentNode)
- node.parentNode.removeChild(node);
-}
-
-function clearElement(node) {
- while (node.firstChild)
- node.removeChild(node.firstChild);
-}
-
-// Check whether a node is contained in another one.
-function isAncestor(node, child) {
- while (child = child.parentNode) {
- if (node == child)
- return true;
- }
- return false;
-}
-
-// The non-breaking space character.
-var nbsp = "\u00a0";
-var matching = {
- "{": "}", "[": "]", "(": ")",
- "}": "{", "]": "[", ")": "("
-};
-
-// Standardize a few unportable event properties.
-function normaliseEvent(event) {
- if (!event.stopPropagation) {
- event.stopPropagation = function () {
- this.cancelBubble = true;
- };
- event.preventDefault = function () {
- this.returnValue = false;
- };
- }
- if (!event.stop) {
- event.stop = function () {
- this.stopPropagation();
- this.preventDefault();
- };
- }
-
- if (event.type == "keypress") {
- event.code = (event.charCode == null) ? event.keyCode : event.charCode;
- event.character = String.fromCharCode(event.code);
- }
- return event;
-}
-
-// Portably register event handlers.
-function addEventHandler(node, type, handler, removeFunc) {
- function wrapHandler(event) {
- handler(normaliseEvent(event || window.event));
- }
-
- if (typeof node.addEventListener == "function") {
- node.addEventListener(type, wrapHandler, false);
- if (removeFunc) return function () {
- node.removeEventListener(type, wrapHandler, false);
- };
- } else {
- node.attachEvent("on" + type, wrapHandler);
- if (removeFunc) return function () {
- node.detachEvent("on" + type, wrapHandler);
- };
- }
-}
-
-function nodeText(node) {
- return node.textContent || node.innerText || node.nodeValue || "";
-}
-
-function nodeTop(node) {
- var top = 0;
- while (node.offsetParent) {
- top += node.offsetTop;
- node = node.offsetParent;
- }
- return top;
-}
-
-function isBR(node) {
- var nn = node.nodeName;
- return nn == "BR" || nn == "br";
-}
-
-function isSpan(node) {
- var nn = node.nodeName;
- return nn == "SPAN" || nn == "span";
-}
diff --git a/cms/js/dash.js b/cms/js/dash.js
deleted file mode 100644
index 0f04d89..0000000
--- a/cms/js/dash.js
+++ /dev/null
@@ -1,204 +0,0 @@
-var neoCMSGlobalPath = null, neoCMSPath = null, neoCMSHTMLEdit = null, neoCMSFiles = null, neoCMSFilePath = null,
- neoCMSImagePath = null;
-$(function () {
- neocmsSetup();
- $(window).bind('resize', windowResize);
- $('#logout a').bind('click', logout);
- $('#neoCMSPrefBtn').bind('click', savePrefs);
- $('#neoCMSFTPBtn').bind('click', saveFTP);
- $('#neoCMSFTPClearBtn').bind('click', clearFTPPrompt);
- $('#neoCMSNewUserLink').bind('click', newUser);
- $('#neoCMSNewUserCancel').bind('click', newUserCancel);
- $('#neoCMSDashScrollWrap').height($(window).height() - 60);
- $('#neoCMSAutoUpdate').bind('click', autoUpdatePrompt);
- $('#neoCMSMessage').bind('keyup', function () {
- if (getNoLines(this) > parseInt(this.rows)) this.rows = '' + Math.round((parseInt(this.rows) * 1.2))
- })
-});
-neocmsSetup = function () {
- $('#neoCMSTopBanner').css('background', 'url(../images/loading.gif) repeat-x bottom');
- var prefsIframe;
- try {
- prefsIframe = document.createElement('