Commit b96c6493 authored by Cédric Le Ninivin's avatar Cédric Le Ninivin

Remove Unecessary Files from Crib

parent 659eeb0d
* Use Indexeddb to save URL list in service worker
* Improve storage organisation (breaks compatibility)
* Provide Diff Tool for collaboration
nav.navbar-default {
background-color: none;
}
\ No newline at end of file
This diff is collapsed.
html body nav.navbar-default {
background-color: transparent;
}
html body .navbar-default .navbar-nav>li>a {
color: #337ab7;
}
html body .navbar-default .navbar-brand {
color: #337ab7;
}
\ No newline at end of file
nav.navbar-default {
background-color: none;
}
\ No newline at end of file
/*globals window, document, RSVP, rJS, Handlebars, console*/
/*jslint indent: 2, maxlen: 80*/
(function (RSVP, rJS, Handlebars) {
"use strict";
function callCribSWGadget(gadget, method, param_list) {
var called = false;
return new RSVP.Queue()
.push(function () {
return gadget.getDeclaredGadget("crib_sw_gadget");
})
.push(function (crib_sw_gadget) {
return crib_sw_gadget[method].apply(crib_sw_gadget, param_list);
})
.push(function (result) {
return result;
}, function (error) {
throw error;
});
}
rJS(window)
.ready(function (g) {
g.props = {};
return g.getElement()
.push(function (element) {
g.props.element = element;
});
})
.allowPublicAcquisition("crib_sw_allDocs", function (param_list) {
return callCribSWGadget(this, "allDocs", param_list);
})
.allowPublicAcquisition("crib_sw_remove", function (param_list) {
return callCribSWGadget(this, "remove", param_list);
})
.allowPublicAcquisition("crib_sw_put", function (param_list) {
return callCribSWGadget(this, "put", param_list);
})
.allowPublicAcquisition("crib_sw_get", function (param_list) {
return callCribSWGadget(this, "get", param_list);
})
.declareMethod('render', function (options) {
var promise_list = [],
gadget = this;
gadget.props.options = options;
// Add promise for list Cache content
// promise to use dav storage for jIO
return RSVP.Queue()
.push(function () {
return gadget.getDeclaredGadget('crib_ide_gadget');
})
.push(function (crib_ide_gadget) {
return crib_ide_gadget.render();
});
});
}(RSVP, rJS, Handlebars));
\ No newline at end of file
html body nav.navbar-default {
background-color: transparent;
}
/*Test*/
html body .navbar-default .navbar-nav>li>a {
color: #337ab7;
}
html body .navbar-default .navbar-brand {
color: #337ab7;
}
iframe {
width: 100%;
height: 100%;
top: 0;
bottom: 0;
position: fixed;
}
.cm-trailingspace {
background-color: #cd0000;
}
This diff is collapsed.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width">
<link rel="stylesheet" href="../lib/bootstrap/bootstrap.min.css">
<link rel="stylesheet" href="../crib-editor3/cribjs.css">
<title>CribJS</title>
<script src="../lib/rsvp.js"></script>
<script src="../lib/jio-latest.js"></script>
<script src="../lib/renderjs.js"></script>
<script src="../gadget/gadget_global.js"></script>
<script src="./cribjs_launcher.js"></script>
</head>
<body>
<div data-gadget-url="../gadget/gadget_jio.html"
data-gadget-scope="setting_gadget"
data-gadget-sandbox="public"></div>
<div data-gadget-url="../gadget/gadget_cribjs_router.html"
data-gadget-scope="router"
data-gadget-sandbox="public"></div>
<div data-gadget-url="../gadget/gadget_cribjs_header.html"
data-gadget-scope="header"
data-gadget-sandbox="public"></div>
<div data-gadget-url="../gadget/crib-sw-gadget.html"
data-gadget-scope="crib_sw_gadget"
data-gadget-sandbox="public"></div>
<div data-gadget-url="../gadget/gadget_jio.html"
data-gadget-scope="jio_gadget"
data-gadget-sandbox="public"></div>
<div role="main" class="ui-content gadget-content"></div>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Codemirror</title>
<script src="../lib/rsvp.js"></script>
<script src="../lib/renderjs.js"></script>
<script src="../lib/codemirror.js"></script>
<link rel="stylesheet" href="../lib/codemirror.css" />
<!--script src="../lib/codemirror/mode/&dtml-mode;/&dtml-mode;.js"></script-->
<script src="../lib/codemirror/addon/cm_edit/matchbrackets.js"></script>
<!-- Trailing spaces -->
<script src="../lib/codemirror/addon/cm_edit/trailingspace.js"></script>
<!-- Rulers -->
<script src="../lib/codemirror/addon/display/rulers.js"></script>
<!-- Search addons -->
<link rel="stylesheet" href="../lib/codemirror/addon/dialog/dialog.css">
<script src="../lib/codemirror/addon/dialog/dialog.js"></script>
<script src="../lib/codemirror/addon/search/searchcursor.js"></script>
<script src="../lib/codemirror/addon/search/search.js"></script>
<script src="../lib/codemirror/addon/search/jump-to-line.js"></script>
<script src="../lib/codemirror/addon/selection/active-line.js"></script>
<!-- Python autocomplete (Ctrl-Space, see below)
TODO-arnau: Add ERP5 autocompletion?
-->
<link rel="stylesheet" href="../lib/codemirror/addon/hint/show-hint.css" />
<script src="../lib/codemirror/addon/hint/show-hint.js"></script>
<script src="../lib/codemirror/addon/hint/anyword-hint.js"></script>
<!-- Code folding -->
<link rel="stylesheet" href="../lib/codemirror/addon/fold/foldgutter.css" />
<script src="../lib/codemirror/addon/fold/foldcode.js"></script>
<script src="../lib/codemirror/addon/fold/foldgutter.js"></script>
<script src="../lib/codemirror/addon/fold/indent-fold.js"></script>
<script src="../lib/codemirror/addon/fold/comment-fold.js"></script>
<script src="../lib/codemirror/addon/fold/xml-fold.js"></script>
<script src="../lib/codemirror/addon/cm_edit/matchtags.js"></script>
<!-- Merge -->
<link rel="stylesheet" href="../lib/codemirror/addon/merge/merge.css" />
<!-- script src="diff_match_patch/javascript/diff_match_patch_uncompressed.js"></script -->
<script src="../lib/codemirror/addon/merge/merge.js"></script>
<!-- Linter -->
<link rel="stylesheet" href="../lib/codemirror/addon/lint/lint.css" />
<script src="../lib/codemirror/addon/lint/lint.js"></script>
<script type="text/javascript" src="../lib/jshint.js"></script>
<script type="text/javascript" src="../lib/codemirror/addon/lint/javascript-lint.js"></script>
<script type="text/javascript" src="../lib/csslint.js"></script>
<script type="text/javascript" src="../lib/codemirror/addon/lint/css-lint.js"></script>
<script type="text/javascript" src="../lib/codemirror/mode/xml/xml.js"></script>
<script type="text/javascript" src="../lib/codemirror/mode/javascript/javascript.js"></script>
<script type="text/javascript" src="../lib/codemirror/mode/python/python.js"></script>
<script type="text/javascript" src="../lib/codemirror/mode/css/css.js"></script>
<script type="text/javascript" src="../lib/codemirror/mode/htmlmixed/htmlmixed.js"></script>
<link rel="stylesheet" href="../lib/codemirror/addon/display/fullscreen.css" />
<script src="../lib/codemirror/addon/display/fullscreen.js"></script>
<script src="codemirror.gadget.js"></script>
</head>
<body>
<div class="codemirror_gadget"><textarea name="code"></textarea></div>
</body>
</html>
/*jslint nomen: true, indent: 2 */
/*global window, rJS, CodeMirror*/
(function (window, rJS, CodeMirror) {
"use strict";
rJS(window)
.declareAcquiredMethod("notifySubmit", "notifySubmit")
.declareJob("deferNotifySubmit", function () {
// Ensure error will be correctly handled
return this.notifySubmit();
})
.declareAcquiredMethod("notifyChange", "notifyChange")
.declareJob("deferNotifyChange", function () {
// Ensure error will be correctly handled
return this.notifyChange();
})
.ready(function () {
var context = this;
//context.deferNotifyChangeBinded = context.deferNotifyChange.bind(context);
this.editor = CodeMirror.fromTextArea(
this.element.querySelector('textarea'),
{
// mode: mode,
// fullScreen: true,
lineNumbers: true,
styleActiveLine: true,
showTrailingSpace: true,
tabSize: 2,
indentWithTabs: false,
matchBrackets: true,
matchTags: {bothTags: true},
//rulers: [{
// column: 80,
// color: "#bbb",
// lineStyle: "dashed"
//}],
extraKeys: {
"Ctrl-Space": "autocomplete",
"Alt-Space": "autocomplete",
"Ctrl-Q": function (cm) {
cm.foldCode(cm.getCursor());
},
"Tab": function (cm) {
// We want to insert spaces, not tab, and we also want to keep the behaviour of indenting selection.
if (cm.getSelection()) {
return cm.execCommand("defaultTab");
}
var spaces = new Array(cm.getOption("indentUnit") + 1).join(" ");
cm.replaceSelection(spaces);
},
"Ctrl-I": "indentAuto",
"Shift-Tab": "indentLess",
"Ctrl-S": context.deferNotifySubmit.bind(context),
"Ctrl-R": function () {
// Disable page refresh to prevent data lose
return;
}
},
foldGutter: false,
lineWrapping: true,
gutters: ["CodeMirror-lint-markers",
"CodeMirror-linenumbers",
"CodeMirror-foldgutter"],
lint: true
}
);
//this.editor.on('changes', this.deferNotifyChangeBinded);
})
.declareMethod('render', function (options) {
var mode = 'text',
state_dict = {
key: options.key,
editable: options.editable === undefined ? true : options.editable
};
if (options.portal_type === 'Web Page') {
mode = 'htmlmixed';
} else if (options.portal_type === 'Web Script') {
mode = 'javascript';
} else if (options.portal_type === 'Web Style') {
mode = 'css';
} else if ((options.portal_type === 'Python Script') ||
(options.portal_type === 'Test Component') ||
(options.portal_type === 'Extension Component')) {
mode = 'python';
}
state_dict.mode = options.mode || "htmlmixed";
state_dict.value = options.value || "";
this.element.querySelector('.CodeMirror').setAttribute('style', 'height: calc(100vh - 270px);');
this.editor.refresh();
return this.changeState(state_dict);
})
.onStateChange(function (modification_dict) {
if (modification_dict.hasOwnProperty('value')) {
// Do not notify the UI when value is set
this.editor.off('changes', this.deferNotifyChangeBinded);
this.editor.setValue(this.state.value);
this.editor.on('changes', this.deferNotifyChangeBinded);
}
if (modification_dict.hasOwnProperty('mode')) {
this.editor.setOption("mode", this.state.mode);
}
this.editor.refresh();
})
.declareService(function () {
this.editor.refresh();
this.editor.focus();
})
.declareMethod('getContent', function () {
var form_data = {};
if (this.state.editable) {
form_data[this.state.key] = this.editor.getValue();
// Change the value state in place
// This will prevent the gadget to be changed if
// its parent call render with the same value
// (as ERP5 does in case of formulator error)
this.state.value = form_data[this.state.key];
}
return form_data;
});
}(window, rJS, CodeMirror));
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, user-scalable=no" />
<title>OfficeJS Header</title>
<!-- renderjs -->
<script src="../lib/rsvp.js" type="text/javascript"></script>
<script src="../lib/renderjs.js" type="text/javascript"></script>
<script src="../lib/handlebars.js" type="text/javascript"></script>
<script src="./gadget_global.js" type="text/javascript"></script>
<!-- custom script -->
<script src="./gadget_cribjs_header.js" type="text/javascript"></script>
<script id="header-title-link-template" type="text/x-handlebars-template"><a data-i18n="{{title}}" class="ui-btn ui-btn-icon-left ui-icon-arrow-down" href="{{url}}">{{title}}</a></script>
<script id="header-title-template" type="text/x-handlebars-template"><span data-i18n="{{title}}">{{title}}</span></script>
<script id="header-link-template" type="text/x-handlebars-template">
<a role="button" data-i18n="{{title}}" href="{{url}}" class="responsive ui-btn ui-icon-{{icon}} ui-btn-icon-left ui-first-child ui-last-child {{class}}">{{title}}</a>
</script>
<script id="header-button-template" type="text/x-handlebars-template">
<form><button name='{{name}}' data-i18n="{{title}}" type='submit' class='responsive ui-btn ui-icon-{{icon}} ui-btn-icon-left ui-first-child ui-last-child {{class}}'>{{title}}</button></form>
</script>
</head>
<body>
<!--div data-role="header" data-theme="a" class="ui-header ui-bar-a" data-position="fixed" data-tap-toggle="false">
<div data-role="header" data-theme="a" class="ui-header ui-bar-a" data-tap-toggle="false">
<div class="ui-controlgroup ui-controlgroup-horizontal ui-btn-left">
<div class="ui-controlgroup-controls">
</div>
</div>
<h1 class="ui-title"></h1>
<div class="ui-controlgroup ui-controlgroup-horizontal ui-btn-right">
<div class="ui-controlgroup-controls">
</div>
</div>
</div-->
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand cribjs_home" href="#page=cribjs_home">CribJS</a>
</div>
<div class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li><a class="select_site" href="#page=select_site">Select Site to Edit</a></li>
<li><a class="url_list" href="#page=url_list">URL List</a></li>
<li><a class="editor" href="#page=editor">Editor</a></li>
<li><a class="save_load" href="#page=save_load">Export/Import</a></li>
<li><a class="tools" href="#page=tools">Tools</a></li>
<li><a class="mass_remove" href="#page=mass_remove">Remove</a></li>
</ul>
</div>
</div>
</nav>
</body>
</html>
\ No newline at end of file
/*jslint nomen: true, indent: 2, maxerr: 3 */
/*global window, rJS, Handlebars, document, loopEventListener, RSVP */
(function (rJS, Handlebars, loopEventListener, RSVP) {
"use strict";
/////////////////////////////////////////////////////////////////
// Handlebars
/////////////////////////////////////////////////////////////////
// Precompile the templates while loading the first gadget instance
var gadget_klass = rJS(window),
header_title_source = gadget_klass.__template_element
.getElementById("header-title-template")
.innerHTML,
header_title_template = Handlebars.compile(header_title_source),
header_title_link_source = gadget_klass.__template_element
.getElementById("header-title-link-template")
.innerHTML,
header_title_link_template = Handlebars.compile(header_title_link_source),
header_button_source = gadget_klass.__template_element
.getElementById("header-button-template")
.innerHTML,
header_button_template = Handlebars.compile(header_button_source),
header_link_source = gadget_klass.__template_element
.getElementById("header-link-template")
.innerHTML,
header_link_template = Handlebars.compile(header_link_source);
gadget_klass
/////////////////////////////////////////////////////////////////
// ready
/////////////////////////////////////////////////////////////////
// Init local properties
.ready(function (g) {
g.props = {};
g.stats = {
loaded: false,
modified: false,
submitted: true,
error: false,
options: {}
};
})
// Assign the element to a variable
.ready(function (g) {
return g.getElement()
.push(function (element) {
g.props.element = element;
g.props.left_link = element.querySelector(".ui-btn-left > div");
g.props.right_link = element.querySelector(".ui-btn-right > div");
g.props.title_element = element.querySelector("h1");
});
})
//////////////////////////////////////////////
// acquired methods
//////////////////////////////////////////////
.declareAcquiredMethod("translateHtml", "translateHtml")
.declareAcquiredMethod("getUrlFor", "getUrlFor")
.declareAcquiredMethod("triggerSubmit", "triggerSubmit")
.declareAcquiredMethod("triggerPanel", "triggerPanel")
/////////////////////////////////////////////////////////////////
// declared methods
/////////////////////////////////////////////////////////////////
.declareMethod('notifyLoading', function () {
if (this.stats.loaded) {
this.stats.loaded = false;
return this.render(this.stats.options);
}
})
.declareMethod('notifyLoaded', function () {
if (!this.stats.loaded) {
this.stats.loaded = true;
return this.render(this.stats.options);
}
})
.declareMethod('render', function (options) {
var gadget = this,
page_list = ["cribjs_home", "select_site", "url_list", "editor", "save_load", "tools", "mass_remove"],
promise_list = [];
gadget.stats.options = options;
page_list.forEach(function (page) {
promise_list.push(gadget.getUrlFor({page: page}));
});
// Handle main title
return new RSVP.Queue()
.push(function () {
return RSVP.all(promise_list);
})
.push(function (link_list) {
for (var i = 0; i < link_list.length; i++) {
gadget.props.element.querySelector("." + page_list[i]).href = link_list[i];
}
});
})
//////////////////////////////////////////////
// handle button click
//////////////////////////////////////////////
.declareService(function () {
var form_gadget = this;
function formSubmit(evt) {
var button = evt.target[0],
name = button.getAttribute("name");
if (name === "panel") {
return form_gadget.triggerPanel();
}
if (name === "submit") {
return form_gadget.triggerSubmit();
}
throw new Error("Unsupported button " + name);
}
// Listen to form submit
return loopEventListener(
form_gadget.props.element,
'submit',
false,
formSubmit
);
});
}(rJS, Handlebars, loopEventListener, RSVP));
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, user-scalable=no" />
<!-- renderjs -->
<script src="../lib/rsvp.js" type="text/javascript"></script>
<script src="../lib/renderjs.js" type="text/javascript"></script>
<!-- custom script -->
<script src="./gadget_cribjs_page_cribjs_home.js" type="text/javascript"></script>
<title>CribJS Header</title>
</head>
<body>
<div class="nav_content cribjs container">
<h1>CribJS: have a taste of your web</h1>
<p>Developed to bring the free software idea to the web,
CribJS offer to you the possibility to create your version of the web application you are using.
Make your copy of the web from here: learn, modify, improve, share.</p>
<p>As this application is a place to develop web applications, it can edit itself.
See how it is made, modify it, improve it.
Start developping your own way. Feel free to make this place your own crib.</p>
<ul>
<li>1. Browse the <a class="url_list" href="#page=url_list">list of URLs</a> you wish to edit</li>
<li>2. Edit and add files in your <a class="editor" href="#page=editor">Editor</a></li>
<li>3. <a class="save_load" href="#page=save_load">Export and Import</a> your copy of the web locally and remotly</li>
<li>4. <a class="mass_remove" href="#page=mass_remove">Remove</a> uncessary URLs</li>
</ul>
<p>Have fun building the web :), here is your <a href="../crib-editor/todo.txt">TODO list</a>.</p>
</div>
</body>
</html>
\ No newline at end of file
/*jslint nomen: true, indent: 2, maxerr: 3 */
/*global window, rJS, Handlebars, document, loopEventListener, RSVP */
(function (window, rJS, document, RSVP) {
"use strict";
rJS(window)
/////////////////////////////////////////////////////////////////
// ready
/////////////////////////////////////////////////////////////////
// Assign the element to a variable
.ready(function (g) {
g.props = {};
return g.getElement()
.push(function (element) {
g.props.element = element;
});
})
//////////////////////////////////////////////
// acquired methods
//////////////////////////////////////////////
.declareAcquiredMethod("getUrlFor", "getUrlFor")
.declareMethod('render', function (options) {
var gadget = this,
page_list = ["url_list", "editor", "save_load", "mass_remove"],
promise_list = [];
page_list.forEach(function (page) {
promise_list.push(gadget.getUrlFor({page: page}));
});
// Handle main title
return new RSVP.Queue()
.push(function () {
return RSVP.all(promise_list);
})
.push(function (link_list) {
for (var i = 0; i < link_list.length; i++) {
gadget.props.element.querySelector("." + page_list[i]).href = link_list[i];
}
});
});
}(window, rJS, document, RSVP));
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, user-scalable=no" />
<title>CribJS Header</title>
<!-- renderjs -->
<script src="../lib/rsvp.js" type="text/javascript"></script>
<script src="../lib/renderjs.js" type="text/javascript"></script>
<script src="../lib/jio-latest.js" type="text/javascript"></script>
<script src="./gadget_global.js" type="text/javascript"></script>
<!-- Custom -->
<script src="./gadget_cribjs_page_editor.js" type="text/javascript"></script>
</head>
<body>
<div class="nav_content editor">
<div class="container">
<div class="row">
<form class="crib-editor-get form-inline">
<h3>Edit</h3>
<div class="form-group">
<label>URL:
<input name="url" class="url form-control" type="text" size="50" value=""></label>
</div>
<button type="submit" name="get" class="btn btn-default">Load</button>
</form>
</div>
<div class="row">
<form class="crib-editor-save form-inline">
<div class="form-group">
<label>Mimetype:
<input class="mimetype form-control" name="mimetype" type="text" size="50" value="text/html">
</label>
</div>
<div class="form-group">
<button name="add" type="submit" class="btn btn-primary">Save</button>
</div>
</form>
</div>
<div class="row">
<table class="table">
<tr>
<td class="success"><span class="crib-editor-save-status"></span></td>
</tr>
</table>
</div>
</div>
<div class="container-fluid">
<div data-gadget-url="./codemirror.gadget.html"
data-gadget-scope="codeeditor"
data-gadget-sandbox="public"></div>
</div>
</div>
</body>
</html>
\ No newline at end of file
/*global window, RSVP */
/*jslint nomen: true, indent: 2, maxerr: 3*/
(function (window, rJS, loopEventListener, jIO) {
"use strict";
var CODE_CONTENT_KEY = "text_content";
function saveTextContent(gadget, event) {
var content,
url = gadget.props.element.querySelector("form.crib-editor-get .url").value,
mimetype = gadget.props.element.querySelector("form.crib-editor-save .mimetype").value;
return new RSVP.Queue()
.push(function () {
return gadget.getDeclaredGadget('codeeditor');
})
.push(function (code_editor_gadget) {
return code_editor_gadget.getContent();
})
.push(function (data) {
content = data[CODE_CONTENT_KEY] || "";
return gadget.crib_sw_put(url, {content: content, type: mimetype});
})
.push(function () {
gadget.props.element.querySelector(".crib-editor-save-status")
.textContent = "Saved " + url + " files at " + Date();
});
}
function getUrlTextContent(gadget, event, url) {
var type;
return new RSVP.Queue()
.push(function () {
return gadget.crib_sw_get(url);
})
.push(function (data) {
type = data.type;
return jIO.util.readBlobAsText(data, type);
})
.push(function (evt) {
return RSVP.all([
evt.target.result,
gadget.getDeclaredGadget('codeeditor')
]);
})
.push(function (data_list) {
gadget.props.element.querySelector("form.crib-editor-save .mimetype").value = type;
return data_list[1].render({
key: CODE_CONTENT_KEY,
value: data_list[0],
mode: type
});
});
}
rJS(window)
.ready(function (g) {
g.props = {};
return g.getElement()
.push(function (element) {
g.props.element = element;
g.props.start_deferred = RSVP.defer();
});
})
.allowPublicAcquisition("notifySubmit", function () {
return saveTextContent(this, undefined);
})
.allowPublicAcquisition("notifyChange", function () {
return;
})
.declareAcquiredMethod("crib_sw_get", "crib_sw_get")
.declareAcquiredMethod("crib_sw_put", "crib_sw_put")
.declareAcquiredMethod("setSetting", "setSetting")
.declareAcquiredMethod("getUrlFor", "getUrlFor")
.declareMethod('render', function (options) {
var gadget = this;
if (options === undefined)
options = {};
gadget.props.options = options;
return new RSVP.Queue()
.push(function () {
if (gadget.props.options.crib_enable_url !== undefined) {
return gadget.setSetting("site_editor_gadget_url", gadget.props.options.crib_enable_url);
}
return;
})
.push(function () {
if (options.url !== undefined) {
gadget.props.element.querySelector("form.crib-editor-get .url").value = options.url;
return getUrlTextContent(gadget, undefined, options.url);
}
})
.push(function () {
return gadget.props.start_deferred.resolve();
});
})
.declareService(function () {
var gadget = this;
return new RSVP.Queue()
.push(function () {
return gadget.props.start_deferred.promise;
})
.push(function () {
var promise_list = [];
// promise to get content from URL
promise_list.push(loopEventListener(
gadget.props.element.querySelector(".crib-editor-get"),
'submit',
false,
function (event) {
var url = gadget.props.element.querySelector("form.crib-editor-get .url").value;
return getUrlTextContent(gadget, event, url);
}
));
// promise to save content
promise_list.push(loopEventListener(
gadget.props.element.querySelector(".crib-editor-save"),
'submit',
false,
function (event) {saveTextContent(gadget, event); }
));
return RSVP.all(promise_list);
});
});
}(window, rJS, loopEventListener, jIO));
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, user-scalable=no" />
<title>CribJS Header</title>
<!-- renderjs -->
<script src="../lib/rsvp.js" type="text/javascript"></script>
<script src="../lib/renderjs.js" type="text/javascript"></script>
<script src="./gadget_global.js" type="text/javascript"></script>
<script type="text/javascript" src="../lib/jshint.js"></script>
<!-- Custom -->
<script src="./gadget_cribjs_page_jslint.js" type="text/javascript"></script>
</head>
<body>
<div class="nav_content url_list container">
<form class="crib-url-list-content">
<h3>URL List</h3>
<button type="submit" name="list-contents" class="btn btn-default">Refresh</button>
<table class="table table-striped table-condensed">
<thead>
<tr>
<th>JSLint</th>
<th>Url</th>
<th>Go</th>
</tr>
</thead>
<tfoot>
</tfoot>
<tbody>
</tbody>
</table>
<div>
<button type="submit" name="list-contents" class="btn btn-default">Refresh</button>
</div>
</form>
</div>
</body>
</html>
\ No newline at end of file
/*global window, rJS, JSHINT, RSVP, jIO, document, loopEventListener */
/*jslint nomen: true, indent: 2, maxerr: 3*/
(function (window, rJS, JSHINT, jIO, loopEventListener) {
"use strict";
function getURLContentAsText(gadget, url) {
return new RSVP.Queue()
.push(function () {
return gadget.crib_sw_get(url);
})
.push(function (data) {
var type;
type = data.type;
return jIO.util.readBlobAsText(data, type);
})
.push(function (event) {
return event.target.result;
});
}
function displayURLList(gadget, event) {
var url_list = [];
return new RSVP.Queue()
.push(function () {
return gadget.crib_sw_allDocs();
})
.push(function (data) {
var promise_list = [],
tmp_url_list = [],
url;
if (data.hasOwnProperty("urls")) {
tmp_url_list = data.urls;
} else {
tmp_url_list = data;
}
for (url in tmp_url_list) {
if (tmp_url_list.hasOwnProperty(url)) {
if (url.endsWith(".js")) {
url_list.push(url);
promise_list.push(RSVP.all([
gadget.getUrlFor({page: 'editor', url: url}),
getURLContentAsText(gadget, url)
]));
}
}
}
return RSVP.all(promise_list);
})
.push(function (result_list) {
var contentsElement = gadget.props.element.querySelector('.crib-url-list-content tbody'),
footer_element = gadget.props.element.querySelector('.crib-url-list-content tfoot'),
url_number, error_number = 0,
url, trElement, tdElement;
// Clear out the existing items from the list.
while (contentsElement.firstChild) {
contentsElement.removeChild(contentsElement.firstChild);
}
// Add each cached URL to the list, one by one.
for (url_number = 0; url_number < url_list.length; url_number++) {
url = url_list[url_number];
var element;
JSHINT(result_list[url_number][1]);
trElement = document.createElement('tr');
tdElement = document.createElement('td');
tdElement.innerHTML = (JSHINT.data().errors ? "<span>&#x274C;</span>" : "");
trElement.appendChild(tdElement);
tdElement = document.createElement('td');
element = document.createElement('a');
element.setAttribute('href', result_list[url_number][0]);
element.textContent = url;
tdElement.appendChild(element);
trElement.appendChild(tdElement);
tdElement = document.createElement('td');
element = document.createElement('a');
element.textContent = "Go";
element.setAttribute('href', url);
element.setAttribute('target', "_blank");
element.setAttribute("class", "btn btn-primary btn-xs");
tdElement.appendChild(element);
trElement.appendChild(tdElement);
contentsElement.appendChild(trElement);
error_number = JSHINT.data().errors ? error_number + 1 : error_number;
}
while (footer_element.firstChild) {
footer_element.removeChild(footer_element.firstChild);
}
trElement = document.createElement('tr');
tdElement = document.createElement('td');
tdElement.innerHTML = "<span>" + error_number + " &#x274C;</span>";
trElement.appendChild(tdElement);
tdElement = document.createElement('td');
tdElement.innerHTML = url_number + " URLs";
trElement.appendChild(tdElement);
tdElement = document.createElement('td');
trElement.appendChild(tdElement);
footer_element.appendChild(trElement);
});
}
rJS(window)
.ready(function (g) {
g.props = {};
return g.getElement()
.push(function (element) {
g.props.element = element;
g.props.start_deferred = RSVP.defer();
});
})
.declareAcquiredMethod("crib_sw_allDocs", "crib_sw_allDocs")
.declareAcquiredMethod("crib_sw_get", "crib_sw_get")
.declareAcquiredMethod("getUrlFor", "getUrlFor")
.declareMethod('render', function (options) {
var gadget = this;
if (options === undefined)
options = {};
gadget.props.options = options;
return new RSVP.Queue()
.push(function () {
return displayURLList(gadget, undefined);
})
.push(function () {
return gadget.props.start_deferred.resolve();
});
})
.declareService(function () {
var gadget = this;
return new RSVP.Queue()
.push(function () {
return gadget.props.start_deferred.promise;
})
.push(function () {
return loopEventListener(
gadget.props.element.querySelector(".crib-url-list-content"),
'submit',
false,
function (event) {displayURLList(gadget, event); }
);
});
});
}(window, rJS, JSHINT, jIO, loopEventListener));
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, user-scalable=no" />
<title>CribJS Header</title>
<!-- renderjs -->
<script src="../lib/rsvp.js" type="text/javascript"></script>
<script src="../lib/renderjs.js" type="text/javascript"></script>
<script src="./gadget_global.js" type="text/javascript"></script>
<!-- Custom -->
<script src="./gadget_cribjs_page_mass_remove.js" type="text/javascript"></script>
</head>
<body>
<div class="nav_content mass_remove container">
<form class="crib-mass-remove">
<h3>Mass removal</h3>
<div class="form-group">
<textarea name="mass-remove-list" cols="35" wrap="soft" class="form-control"></textarea>
</div>
<button type="submit" class="mass-remove btn btn-danger" name="mass-remove">Mass remove from Cache</button>
<div><span class="crib-mass-remove-status"></span></div>
</form>
</div>
</body>
</html>
\ No newline at end of file
/*global window, rJS, loopEventListener, RSVP, console */
/*jslint nomen: true, indent: 2, maxerr: 3*/
(function (window, rJS, loopEventListener) {
"use strict";
function massRemoveFromCache(gadget, event) {
var url_list = gadget.props.element.querySelector("form.crib-mass-remove textarea").value.match(/[^\r\n]+/g),
url_list_length = url_list.length;
return new RSVP.Queue()
.push(function () {
var i,
promise_list = [];
for (i = 0; i < url_list_length; i += 1) {
promise_list.push(gadget.crib_sw_remove(url_list[i]));
}
return RSVP.all(promise_list);
})
.push(function () {
gadget.props.element.querySelector(".crib-mass-remove-status")
.textContent = "Removed " + url_list.length + " files at " + Date();
})
.fail(function (error) {
gadget.props.element.querySelector(".crib-mass-remove-status").textContent = error;
console.log(error);
});
}
rJS(window)
.ready(function (g) {
g.props = {};
return g.getElement()
.push(function (element) {
g.props.element = element;
g.props.start_deferred = RSVP.defer();
});
})
.declareAcquiredMethod("crib_sw_remove", "crib_sw_remove")
.declareMethod('render', function (options) {
var gadget = this;
if (options === undefined)
options = {};
gadget.props.options = options;
return new RSVP.Queue()
.push(function () {
return gadget.props.start_deferred.resolve();
});
})
.declareService(function () {
var gadget = this;
return new RSVP.Queue()
.push(function () {
return gadget.props.start_deferred.promise;
})
.push(function () {
var promise_list = [];
// promise to remove content from cache
promise_list.push(loopEventListener(
gadget.props.element.querySelector(".crib-mass-remove"),
'submit',
false,
function (event) {massRemoveFromCache(gadget, event); }
));
return RSVP.all(promise_list);
});
});
}(window, rJS, loopEventListener));
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, user-scalable=no" />
<title>CribJS Header</title>
<!-- renderjs -->
<script src="../lib/rsvp.js" type="text/javascript"></script>
<script src="../lib/renderjs.js" type="text/javascript"></script>
<script src="../lib/jszip.js" type="text/javascript"></script>
<script src="../lib/FileSaver.js" type="text/javascript"></script>
<script src="./gadget_global.js" type="text/javascript"></script>
<!-- Custom -->
<script src="./gadget_cribjs_page_save_load.js" type="text/javascript"></script>
</head>
<body>
<div class="nav_content save_load container">
<h3>Storage</h3>
<form class="crib-save-to-zip form-inline">
<h3>Export to Zip</h3>
<div class="form-group">
<label>Export to zip:
<input class="save-zip-path form-control" name="save-zip-path" type="text" size="30" value=""></label>
</div>
<div class="form-group">
<label> to:
<input name="save-zip-id" class="save-zip-id form-control" type="text" size="30" value="cribjs.zip"></label>
</div>
<button name="save-zip-contents" type="submit" class="btn btn-default">Export to Zip</button>
</form>
<div><span class="info crib-save-to-zip-status"></span></div>
<form class="crib-load-from-zip form-inline">
<h3>Import from zip</h3>
<div class="form-group">
<label>Import from zip:
<input name="load-zip-file" class="load-zip-file form-control" type="file" size="30"></label>
</div>
<div class="form-group">
<label> to path:
<input name="load-zip-path" class="load-zip-path form-control" type="text" size="30" value="cribeditor/v1.1">
</label>
</div>
<button name="load-zip-contents" class="load-zip-contents btn btn-default" type="submit">Import from zip</button>
</form>
<div><span class="crib-load-from-zip-status"></span></div>
</div>
<div data-gadget-url="./gadget_jio.html"
data-gadget-scope="jio_gadget"
data-gadget-sandbox="public"></div>
</body>
</html>
\ No newline at end of file
/*global window, rJS, loopEventListener, RSVP, console, document, saveAs */
/*jslint nomen: true, indent: 2, maxerr: 3*/
(function (window, rJS, loopEventListener, JSZip, FileSaver) {
"use strict";
function getExtension(url) {
var extension = url.split('.').pop();
if (extension.endsWith('/')) {
return ".html";
}
return "." + extension;
}
// Zip Methods
function saveContentToZIP(gadget, event) {
var path_to_save, path_to_save_length, application_id, crib_sw_gadget,
jio_gadget, url_list = [], saved_number = 0, zip;
path_to_save = gadget.props.element.querySelector('form.crib-save-to-zip .save-zip-path').value;
application_id = gadget.props.element.querySelector('form.crib-save-to-zip .save-zip-id').value;
path_to_save_length = path_to_save.length;
return new RSVP.Queue()
.push(function () {
return RSVP.all([
gadget.getDeclaredGadget('jio_gadget')
]);
})
.push(function (gadget_list) {
jio_gadget = gadget_list[0];
return gadget.crib_sw_allDocs({cached_only: true});
})
.push(function (data) {
var promise_list = [],
i, i_len, url;
if (data.hasOwnProperty("urls")) {
data = data.urls;
} else {
data = data;
}
if (Array.isArray(data)) {
url_list = data;
} else {
url_list = Object.keys(data);
}
for (i = 0, i_len = url_list.length; i < i_len; i += 1) {
url = String(url_list[i]);
if (url.indexOf(path_to_save) === 0) {
saved_number += 1;
promise_list.push(gadget.crib_sw_get(url));
}
}
return RSVP.all(promise_list);
})
.push(function (response_list) {
var promise_list = [],
i, i_len, url, response, extension, zip;
zip = new JSZip();
for (i = 0, i_len = response_list.length; i < i_len; i += 1) {
response = response_list[i];
url = url_list[i].substr(path_to_save_length);
if (url.endsWith("//")) {
url = url.substr(0, url.length - 1);
}
if (url.endsWith("/./")) {
url = url.substr(0, url.length - 2);
}
if (url.endsWith("/")) {
url = url + "index.html";
}
if (url.startsWith("./")) {
url = url.substr(1);
}
zip.file(url, response);
}
return zip.generateAsync({type: "blob"});
})
.push(function (content) {
return saveAs(content, application_id);
})
.push(function () {
gadget.props.element.querySelector(".crib-save-to-zip-status")
.textContent = "Saved " + saved_number + " files at " + Date();
})
.push(console.log, console.log);
}
function loadContentFromZIP(gadget, event) {
var path_to_load, path_to_load_length, file_list, crib_sw_gadget,
jio_gadget, url_list = [], file, url_number = 0;
path_to_load = gadget.props.element.querySelector('form.crib-load-from-zip .load-zip-path').value;
file_list = gadget.props.element.querySelector('form.crib-load-from-zip .load-zip-file').files;
if (file_list.length === 0) {
gadget.props.element.querySelector(".crib-load-from-zip-status")
.textContent = "Please put a Zip at " + Date();
return;
}
path_to_load_length = path_to_load.length;
file = file_list[0];
return new RSVP.Queue()
.push(function () {
return JSZip.loadAsync(file);
})
.push(function (zip) {
var promise_list = [];
zip.forEach(function (relativePath, zipEntry) {
var end_url;
url_number += 1;
if (zipEntry.dir) {
return;
}
if (!relativePath.startsWith("/") && !path_to_load.endsWith("/")) {
end_url = path_to_load + "/" + relativePath;
} else if (relativePath.startsWith("/") && path_to_load.endsWith("/")) {
end_url = path_to_load + relativePath.substring(1);
} else {
end_url = path_to_load + relativePath;
}
promise_list.push(
new RSVP.Queue()
.push(function () {
return zipEntry.async('blob');
})
.push(function (result) {
if (end_url.endsWith(".js")) {
// This is a ugly hack as mimetype needs to be correct for JS
result = result.slice(0, result.size, "application/javascript");
} else if (end_url.endsWith(".html")) {
// This is a ugly hack as mimetype needs to be correct for JS
result = result.slice(0, result.size, "text/html");
} else if (end_url.endsWith(".css")) {
// This is a ugly hack as mimetype needs to be correct for JS
result = result.slice(0, result.size, "text/css");
}
return gadget.crib_sw_put(end_url, {blob: result});
})
);
});
return RSVP.all(promise_list);
})
.push(function () {
gadget.props.element.querySelector(".crib-load-from-zip-status")
.textContent = "Loaded " + url_number + " files at " + Date();
})
.push(console.log, console.log);
}
rJS(window)
.ready(function (g) {
g.props = {};
return g.getElement()
.push(function (element) {
g.props.element = element;
g.props.start_deferred = RSVP.defer();
});
})
.declareAcquiredMethod("crib_sw_allDocs", "crib_sw_allDocs")
.declareAcquiredMethod("crib_sw_get", "crib_sw_get")
.declareAcquiredMethod("crib_sw_put", "crib_sw_put")
.declareAcquiredMethod("getUrlFor", "getUrlFor")
.declareMethod('render', function (options) {
var gadget = this;
if (options === undefined)
options = {};
gadget.props.options = options;
gadget.props.element.querySelector('form.crib-save-to-zip .save-zip-path').value = document.location.origin;
return new RSVP.Queue()
.push(function () {
return gadget.props.start_deferred.resolve();
});
})
.declareService(function () {
var gadget = this;
return new RSVP.Queue()
.push(function () {
return gadget.props.start_deferred.promise;
})
.push(function () {
var promise_list = [];
// promise to save content to ZIP
promise_list.push(loopEventListener(
gadget.props.element.querySelector(".crib-save-to-zip"),
'submit',
false,
function (event) {saveContentToZIP(gadget, event); }
));
// promise to load content from ZIP
promise_list.push(loopEventListener(
gadget.props.element.querySelector(".crib-load-from-zip"),
'submit',
false,
function (event) {loadContentFromZIP(gadget, event); }
));
return RSVP.all(promise_list);
});
});
}(window, rJS, loopEventListener, JSZip, FileSaver));
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, user-scalable=no" />
<title>CribJS Header</title>
<!-- renderjs -->
<script src="../lib/rsvp.js" type="text/javascript"></script>
<script src="../lib/renderjs.js" type="text/javascript"></script>
<script src="../lib/jszip.js" type="text/javascript"></script>
<script src="../lib/FileSaver.js" type="text/javascript"></script>
<script src="./gadget_global.js" type="text/javascript"></script>
<!-- Custom -->
<script src="./gadget_cribjs_page_select_site.js" type="text/javascript"></script>
</head>
<body>
<div class="nav_content save_load container">
<h3>Site Editor Gadget URL</h3>
<p>Enter the URL of the Crib Gadget from the site you want to edit. If you want to edit this site use:
"/crib-enable.html"</p>
<div class="row">
<table class="table">
<tr>
<td class="success"><span class="crib-site-save-status"></span></td>
</tr>
</table>
</div>
<div class="row">
<form class="form-horizontal site-editor-gadget-url">
<div class="form-group">
<label for="url" class="col-sm-2 control-label">URL</label>
<div class="col-sm-10">
<input type="text" class="form-control url" id="url" value="/crib-enable.html">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-default set-site-gadget-url">Set Site to edit</button>
</div>
</div>
</form>
</div>
</div>
<div data-gadget-url="./gadget_jio.html"
data-gadget-scope="jio_gadget"
data-gadget-sandbox="public"></div>
</body>
</html>
\ No newline at end of file
/*global window, rJS, loopEventListener, RSVP */
/*jslint nomen: true, indent: 2, maxerr: 3*/
(function (window, rJS, loopEventListener) {
"use strict";
function setSiteGadgetUrl(gadget, event) {
var site_editor_gadget_url;
site_editor_gadget_url = gadget.props.element.querySelector('form.site-editor-gadget-url .url').value;
return gadget.setSetting("site_editor_gadget_url", site_editor_gadget_url)
.push(function () {
gadget.props.element.querySelector(".crib-site-save-status")
.textContent = "Saved " + site_editor_gadget_url + " files at " + Date();
});
}
rJS(window)
.ready(function (g) {
g.props = {};
return g.getElement()
.push(function (element) {
g.props.element = element;
g.props.start_deferred = RSVP.defer();
});
})
.declareAcquiredMethod("getSetting", "getSetting")
.declareAcquiredMethod("setSetting", "setSetting")
.declareMethod('render', function (options) {
var gadget = this;
if (options === undefined)
options = {};
gadget.props.options = options;
return new RSVP.Queue()
.push(function () {
var getURL = window.location;
return gadget.getSetting(
"site_editor_gadget_url",
getURL.protocol + "//" + getURL.host + "/crib-enable.html"
);
})
.push(function (site_editor_gadget_url) {
gadget.props.element.querySelector('form.site-editor-gadget-url .url').value = site_editor_gadget_url;
return gadget.props.start_deferred.resolve();
});
})
.declareService(function () {
var gadget = this;
return new RSVP.Queue()
.push(function () {
return gadget.props.start_deferred.promise;
})
.push(function () {
var promise_list = [];
// promise to set Site to Edit
promise_list.push(loopEventListener(
gadget.props.element.querySelector(".site-editor-gadget-url"),
'submit',
false,
function (event) {setSiteGadgetUrl(gadget, event); }
));
return RSVP.all(promise_list);
});
});
}(window, rJS, loopEventListener));
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, user-scalable=no" />
<!-- renderjs -->
<script src="../lib/rsvp.js" type="text/javascript"></script>
<script src="../lib/renderjs.js" type="text/javascript"></script>
<!-- custom script -->
<script src="./gadget_cribjs_page_tools.js" type="text/javascript"></script>
<title>CribJS Header</title>
</head>
<body>
<div class="nav_content cribjs container">
<ul>
<li>Check <a class="jslint" href="#page=jslint">JSLint</a></li>
<li><a class="mass_remove" href="#page=mass_remove">Remove</a> uncessary URLs</li>
</ul>
</div>
</body>
</html>
\ No newline at end of file
/*jslint nomen: true, indent: 2, maxerr: 3 */
/*global window, rJS, Handlebars, document, loopEventListener, RSVP */
(function (window, rJS, document, RSVP) {
"use strict";
rJS(window)
/////////////////////////////////////////////////////////////////
// ready
/////////////////////////////////////////////////////////////////
// Assign the element to a variable
.ready(function (g) {
g.props = {};
return g.getElement()
.push(function (element) {
g.props.element = element;
});
})
//////////////////////////////////////////////
// acquired methods
//////////////////////////////////////////////
.declareAcquiredMethod("getUrlFor", "getUrlFor")
.declareMethod('render', function (options) {
var gadget = this,
page_list = ["jslint", "mass_remove"],
promise_list = [];
page_list.forEach(function (page) {
promise_list.push(gadget.getUrlFor({page: page}));
});
// Handle main title
return new RSVP.Queue()
.push(function () {
return RSVP.all(promise_list);
})
.push(function (link_list) {
for (var i = 0; i < link_list.length; i++) {
gadget.props.element.querySelector("." + page_list[i]).href = link_list[i];
}
});
});
}(window, rJS, document, RSVP));
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, user-scalable=no" />
<title>CribJS Header</title>
<!-- renderjs -->
<script src="../lib/rsvp.js" type="text/javascript"></script>
<script src="../lib/renderjs.js" type="text/javascript"></script>
<script src="./gadget_global.js" type="text/javascript"></script>
<!-- Custom -->
<script src="./gadget_cribjs_page_url_list.js" type="text/javascript"></script>
</head>
<body>
<div class="nav_content url_list container">
<form class="crib-url-list-content">
<h3>URL List</h3>
<button type="submit" name="list-contents" class="btn btn-default">Refresh</button>
<table class="table table-striped table-condensed">
<thead>
<tr>
<th>Cached</th>
<th>Url</th>
<th>Go</th>
</tr>
</thead>
<tfoot>
</tfoot>
<tbody>
</tbody>
</table>
<div>
<button type="submit" name="list-contents" class="btn btn-default">Refresh</button>
</div>
</form>
</div>
</body>
</html>
\ No newline at end of file
/*global window, rJS, loopEventListener, RSVP, console, document */
/*jslint nomen: true, indent: 2, maxerr: 3*/
(function (window, rJS, loopEventListener) {
"use strict";
function displayURLList(gadget, event) {
var url_list;
return new RSVP.Queue()
.push(function () {
return gadget.crib_sw_allDocs();
})
.push(function (data) {
var promise_list = [],
url;
if (data.hasOwnProperty("urls")) {
url_list = data.urls;
} else {
url_list = data;
}
for (url in url_list) {
if (url_list.hasOwnProperty(url)) {
promise_list.push(gadget.getUrlFor({page: 'editor', url: url}));
}
}
return RSVP.all(promise_list);
})
.push(function (url_link_list) {
var contentsElement = gadget.props.element.querySelector('.crib-url-list-content tbody'),
footer_element = gadget.props.element.querySelector('.crib-url-list-content tfoot'),
url_number = 0, cached_number = 0,
url, trElement, tdElement;
// Clear out the existing items from the list.
while (contentsElement.firstChild) {
contentsElement.removeChild(contentsElement.firstChild);
}
console.log(url_list);
// Add each cached URL to the list, one by one.
for (url in url_list) {
if (url_list.hasOwnProperty(url)) {
var element;
trElement = document.createElement('tr');
tdElement = document.createElement('td');
tdElement.innerHTML = (url_list[url].cached ? "<span>&#x2713;</span>" : "");
trElement.appendChild(tdElement);
tdElement = document.createElement('td');
element = document.createElement('a');
element.setAttribute('href', url_link_list[url_number]);
element.textContent = url;
tdElement.appendChild(element);
trElement.appendChild(tdElement);
tdElement = document.createElement('td');
element = document.createElement('a');
element.textContent = "Go";
element.setAttribute('href', url);
element.setAttribute('target', "_blank");
element.setAttribute("class", "btn btn-primary btn-xs");
tdElement.appendChild(element);
trElement.appendChild(tdElement);
contentsElement.appendChild(trElement);
cached_number = url_list[url].cached ? cached_number + 1 : cached_number;
url_number += 1;
}
}
while (footer_element.firstChild) {
footer_element.removeChild(footer_element.firstChild);
}
trElement = document.createElement('tr');
tdElement = document.createElement('td');
tdElement.innerHTML = "<span>" + cached_number + " &#x2713;</span>";
trElement.appendChild(tdElement);
tdElement = document.createElement('td');
tdElement.innerHTML = url_number + " URLs";
trElement.appendChild(tdElement);
tdElement = document.createElement('td');
trElement.appendChild(tdElement);
footer_element.appendChild(trElement);
});
}
rJS(window)
.ready(function (g) {
g.props = {};
return g.getElement()
.push(function (element) {
g.props.element = element;
g.props.start_deferred = RSVP.defer();
});
})
.declareAcquiredMethod("crib_sw_allDocs", "crib_sw_allDocs")
.declareAcquiredMethod("getUrlFor", "getUrlFor")
.declareMethod('render', function (options) {
var gadget = this;
if (options === undefined)
options = {};
gadget.props.options = options;
return new RSVP.Queue()
.push(function () {
return displayURLList(gadget, undefined);
})
.push(function () {
return gadget.props.start_deferred.resolve();
});
})
.declareService(function () {
var gadget = this;
return new RSVP.Queue()
.push(function () {
return gadget.props.start_deferred.promise;
})
.push(function () {
return loopEventListener(
gadget.props.element.querySelector(".crib-url-list-content"),
'submit',
false,
function (event) {displayURLList(gadget, event); }
);
});
});
}(window, rJS, loopEventListener));
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, user-scalable=no" />
<title>CribSJ Router Gadget</title>
<!-- renderjs -->
<script src="../lib/rsvp.js" type="text/javascript"></script>
<script src="../lib/renderjs.js" type="text/javascript"></script>
<!-- custom script -->
<script src="./gadget_cribjs_router.js" type="text/javascript"></script>
</head>
<body>
</body>
</html>
\ No newline at end of file
/*global window, rJS, document, RSVP */
/*jslint nomen: true, indent: 2, maxerr: 3*/
(function (window, rJS, loopEventListener) {
"use strict";
var gadget_klass = rJS(window),
MAIN_PAGE_PREFIX = "/gadget/gadget_cribjs_",
DEFAULT_PAGE = "cribjs_home",
REDIRECT_TIMEOUT = 5000;
function listenHashChange(gadget) {
function extractHashAndDispatch(evt) {
var hash = (evt.newURL || window.location.toString()).split('#')[1],
subhashes,
subhash,
keyvalue,
index,
args = {};
if (hash !== undefined) {
subhashes = hash.split('&');
for (index in subhashes) {
if (subhashes.hasOwnProperty(index)) {
subhash = subhashes[index];
if (subhash !== '') {
keyvalue = subhash.split('=');
if (keyvalue.length === 2) {
args[decodeURIComponent(keyvalue[0])] = decodeURIComponent(keyvalue[1]);
}
}
}
}
}
return gadget.renderApplication({
args: args
});
}
var result = loopEventListener(window, 'hashchange', false,
extractHashAndDispatch),
event = document.createEvent("Event");
event.initEvent('hashchange', true, true);
event.newURL = window.location.toString();
window.dispatchEvent(event);
return result;
}
gadget_klass
.ready(function (gadget) {
gadget.props = {
start_deferred: RSVP.defer()
};
})
.declareMethod("getCommandUrlFor", function (options) {
var prefix = '',
result,
key;
result = "#";
for (key in options) {
if (options.hasOwnProperty(key) && options[key] !== undefined) {
// Don't keep empty values
result += prefix + encodeURIComponent(key) + "=" + encodeURIComponent(options[key]);
prefix = '&';
}
}
return result;
})
.declareMethod('redirect', function (options) {
if (options !== undefined && options.toExternal) {
window.location.replace(options.url);
return RSVP.timeout(REDIRECT_TIMEOUT); // timeout if not redirected
}
else {
return this.getCommandUrlFor(options)
.push(function (hash) {
window.location.replace(hash);
// prevent returning unexpected response
// wait for the hash change to occur
// fail if nothing happens
return RSVP.timeout(REDIRECT_TIMEOUT);
});
}
})
.declareMethod('route', function (options) {
var gadget = this,
args = options.args;
gadget.options = options;
if (args.jio_key === undefined || args.jio_key === '') {
if (args.page === undefined || args.page === '' || args.page === "document_list") {
args.page = DEFAULT_PAGE;
}
return {
url: MAIN_PAGE_PREFIX + "page_" + args.page + ".html",
options: args
};
}
return gadget.jio_get(args.jio_key)
.push(function (doc) {
var sub_options = {},
base_portal_type = doc.portal_type.toLowerCase().replace(/\s/g, "_");
sub_options = {
doc: doc,
jio_key: args.jio_key,
search: args.search
};
if (base_portal_type.search(/_temp$/) >= 0) {
//Remove "_temp"
base_portal_type = base_portal_type.substr(
0,
base_portal_type.length - 5
);
}
return {
url: MAIN_PAGE_PREFIX + "jio_" +
base_portal_type +
"_" + args.page + ".html",
options: sub_options
};
});
})
.declareAcquiredMethod('jio_get', 'jio_get')
.declareAcquiredMethod('renderApplication', 'renderApplication')
.declareMethod('start', function () {
this.props.start_deferred.resolve();
})
.declareService(function () {
var gadget = this;
return new RSVP.Queue()
.push(function () {
return gadget.props.start_deferred.promise;
})
.push(function () {
return listenHashChange(gadget);
});
});
}(window, rJS, loopEventListener));
\ 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-mark {
background-color: rgba(20, 255, 20, 0.5);
-webkit-animation: blink 1.06s steps(1) infinite;
-moz-animation: blink 1.06s steps(1) infinite;
animation: blink 1.06s steps(1) infinite;
}
.cm-animate-fat-cursor {
width: auto;
border: 0;
-webkit-animation: blink 1.06s steps(1) infinite;
-moz-animation: blink 1.06s steps(1) infinite;
animation: blink 1.06s steps(1) infinite;
background-color: #7e7;
}
@-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;
}
.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;
}
.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; }
\ No newline at end of file
This diff is collapsed.
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/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) {
var defaults = {
pairs: "()[]{}''\"\"",
closeBefore: ")]}'\":;>",
triples: "",
explode: "[]{}"
};
var Pos = CodeMirror.Pos;
CodeMirror.defineOption("autoCloseBrackets", false, function(cm, val, old) {
if (old && old != CodeMirror.Init) {
cm.removeKeyMap(keyMap);
cm.state.closeBrackets = null;
}
if (val) {
ensureBound(getOption(val, "pairs"))
cm.state.closeBrackets = val;
cm.addKeyMap(keyMap);
}
});
function getOption(conf, name) {
if (name == "pairs" && typeof conf == "string") return conf;
if (typeof conf == "object" && conf[name] != null) return conf[name];
return defaults[name];
}
var keyMap = {Backspace: handleBackspace, Enter: handleEnter};
function ensureBound(chars) {
for (var i = 0; i < chars.length; i++) {
var ch = chars.charAt(i), key = "'" + ch + "'"
if (!keyMap[key]) keyMap[key] = handler(ch)
}
}
ensureBound(defaults.pairs + "`")
function handler(ch) {
return function(cm) { return handleChar(cm, ch); };
}
function getConfig(cm) {
var deflt = cm.state.closeBrackets;
if (!deflt || deflt.override) return deflt;
var mode = cm.getModeAt(cm.getCursor());
return mode.closeBrackets || deflt;
}
function handleBackspace(cm) {
var conf = getConfig(cm);
if (!conf || cm.getOption("disableInput")) return CodeMirror.Pass;
var pairs = getOption(conf, "pairs");
var ranges = cm.listSelections();
for (var i = 0; i < ranges.length; i++) {
if (!ranges[i].empty()) return CodeMirror.Pass;
var around = charsAround(cm, ranges[i].head);
if (!around || pairs.indexOf(around) % 2 != 0) return CodeMirror.Pass;
}
for (var i = ranges.length - 1; i >= 0; i--) {
var cur = ranges[i].head;
cm.replaceRange("", Pos(cur.line, cur.ch - 1), Pos(cur.line, cur.ch + 1), "+delete");
}
}
function handleEnter(cm) {
var conf = getConfig(cm);
var explode = conf && getOption(conf, "explode");
if (!explode || cm.getOption("disableInput")) return CodeMirror.Pass;
var ranges = cm.listSelections();
for (var i = 0; i < ranges.length; i++) {
if (!ranges[i].empty()) return CodeMirror.Pass;
var around = charsAround(cm, ranges[i].head);
if (!around || explode.indexOf(around) % 2 != 0) return CodeMirror.Pass;
}
cm.operation(function() {
var linesep = cm.lineSeparator() || "\n";
cm.replaceSelection(linesep + linesep, null);
cm.execCommand("goCharLeft");
ranges = cm.listSelections();
for (var i = 0; i < ranges.length; i++) {
var line = ranges[i].head.line;
cm.indentLine(line, null, true);
cm.indentLine(line + 1, null, true);
}
});
}
function contractSelection(sel) {
var inverted = CodeMirror.cmpPos(sel.anchor, sel.head) > 0;
return {anchor: new Pos(sel.anchor.line, sel.anchor.ch + (inverted ? -1 : 1)),
head: new Pos(sel.head.line, sel.head.ch + (inverted ? 1 : -1))};
}
function handleChar(cm, ch) {
var conf = getConfig(cm);
if (!conf || cm.getOption("disableInput")) return CodeMirror.Pass;
var pairs = getOption(conf, "pairs");
var pos = pairs.indexOf(ch);
if (pos == -1) return CodeMirror.Pass;
var closeBefore = getOption(conf,"closeBefore");
var triples = getOption(conf, "triples");
var identical = pairs.charAt(pos + 1) == ch;
var ranges = cm.listSelections();
var opening = pos % 2 == 0;
var type;
for (var i = 0; i < ranges.length; i++) {
var range = ranges[i], cur = range.head, curType;
var next = cm.getRange(cur, Pos(cur.line, cur.ch + 1));
if (opening && !range.empty()) {
curType = "surround";
} else if ((identical || !opening) && next == ch) {
if (identical && stringStartsAfter(cm, cur))
curType = "both";
else if (triples.indexOf(ch) >= 0 && cm.getRange(cur, Pos(cur.line, cur.ch + 3)) == ch + ch + ch)
curType = "skipThree";
else
curType = "skip";
} else if (identical && cur.ch > 1 && triples.indexOf(ch) >= 0 &&
cm.getRange(Pos(cur.line, cur.ch - 2), cur) == ch + ch) {
if (cur.ch > 2 && /\bstring/.test(cm.getTokenTypeAt(Pos(cur.line, cur.ch - 2)))) return CodeMirror.Pass;
curType = "addFour";
} else if (identical) {
var prev = cur.ch == 0 ? " " : cm.getRange(Pos(cur.line, cur.ch - 1), cur)
if (!CodeMirror.isWordChar(next) && prev != ch && !CodeMirror.isWordChar(prev)) curType = "both";
else return CodeMirror.Pass;
} else if (opening && (next.length === 0 || /\s/.test(next) || closeBefore.indexOf(next) > -1)) {
curType = "both";
} else {
return CodeMirror.Pass;
}
if (!type) type = curType;
else if (type != curType) return CodeMirror.Pass;
}
var left = pos % 2 ? pairs.charAt(pos - 1) : ch;
var right = pos % 2 ? ch : pairs.charAt(pos + 1);
cm.operation(function() {
if (type == "skip") {
cm.execCommand("goCharRight");
} else if (type == "skipThree") {
for (var i = 0; i < 3; i++)
cm.execCommand("goCharRight");
} else if (type == "surround") {
var sels = cm.getSelections();
for (var i = 0; i < sels.length; i++)
sels[i] = left + sels[i] + right;
cm.replaceSelections(sels, "around");
sels = cm.listSelections().slice();
for (var i = 0; i < sels.length; i++)
sels[i] = contractSelection(sels[i]);
cm.setSelections(sels);
} else if (type == "both") {
cm.replaceSelection(left + right, null);
cm.triggerElectric(left + right);
cm.execCommand("goCharLeft");
} else if (type == "addFour") {
cm.replaceSelection(left + left + left + left, "before");
cm.execCommand("goCharRight");
}
});
}
function charsAround(cm, pos) {
var str = cm.getRange(Pos(pos.line, pos.ch - 1),
Pos(pos.line, pos.ch + 1));
return str.length == 2 ? str : null;
}
function stringStartsAfter(cm, pos) {
var token = cm.getTokenAt(Pos(pos.line, pos.ch + 1))
return /\bstring/.test(token.type) && token.start == pos.ch &&
(pos.ch == 0 || !/\bstring/.test(cm.getTokenTypeAt(pos)))
}
});
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
/**
* Tag-closer extension for CodeMirror.
*
* This extension adds an "autoCloseTags" option that can be set to
* either true to get the default behavior, or an object to further
* configure its behavior.
*
* These are supported options:
*
* `whenClosing` (default true)
* Whether to autoclose when the '/' of a closing tag is typed.
* `whenOpening` (default true)
* Whether to autoclose the tag when the final '>' of an opening
* tag is typed.
* `dontCloseTags` (default is empty tags for HTML, none for XML)
* An array of tag names that should not be autoclosed.
* `indentTags` (default is block tags for HTML, none for XML)
* An array of tag names that should, when opened, cause a
* blank line to be added inside the tag, and the blank line and
* closing line to be indented.
* `emptyTags` (default is none)
* An array of XML tag names that should be autoclosed with '/>'.
*
* See demos/closetag.html for a usage example.
*/
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("../fold/xml-fold"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "../fold/xml-fold"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
CodeMirror.defineOption("autoCloseTags", false, function(cm, val, old) {
if (old != CodeMirror.Init && old)
cm.removeKeyMap("autoCloseTags");
if (!val) return;
var map = {name: "autoCloseTags"};
if (typeof val != "object" || val.whenClosing)
map["'/'"] = function(cm) { return autoCloseSlash(cm); };
if (typeof val != "object" || val.whenOpening)
map["'>'"] = function(cm) { return autoCloseGT(cm); };
cm.addKeyMap(map);
});
var htmlDontClose = ["area", "base", "br", "col", "command", "embed", "hr", "img", "input", "keygen", "link", "meta", "param",
"source", "track", "wbr"];
var htmlIndent = ["applet", "blockquote", "body", "button", "div", "dl", "fieldset", "form", "frameset", "h1", "h2", "h3", "h4",
"h5", "h6", "head", "html", "iframe", "layer", "legend", "object", "ol", "p", "select", "table", "ul"];
function autoCloseGT(cm) {
if (cm.getOption("disableInput")) return CodeMirror.Pass;
var ranges = cm.listSelections(), replacements = [];
var opt = cm.getOption("autoCloseTags");
for (var i = 0; i < ranges.length; i++) {
if (!ranges[i].empty()) return CodeMirror.Pass;
var pos = ranges[i].head, tok = cm.getTokenAt(pos);
var inner = CodeMirror.innerMode(cm.getMode(), tok.state), state = inner.state;
var tagInfo = inner.mode.xmlCurrentTag && inner.mode.xmlCurrentTag(state)
var tagName = tagInfo && tagInfo.name
if (!tagName) return CodeMirror.Pass
var html = inner.mode.configuration == "html";
var dontCloseTags = (typeof opt == "object" && opt.dontCloseTags) || (html && htmlDontClose);
var indentTags = (typeof opt == "object" && opt.indentTags) || (html && htmlIndent);
if (tok.end > pos.ch) tagName = tagName.slice(0, tagName.length - tok.end + pos.ch);
var lowerTagName = tagName.toLowerCase();
// Don't process the '>' at the end of an end-tag or self-closing tag
if (!tagName ||
tok.type == "string" && (tok.end != pos.ch || !/[\"\']/.test(tok.string.charAt(tok.string.length - 1)) || tok.string.length == 1) ||
tok.type == "tag" && tagInfo.close ||
tok.string.indexOf("/") == (pos.ch - tok.start - 1) || // match something like <someTagName />
dontCloseTags && indexOf(dontCloseTags, lowerTagName) > -1 ||
closingTagExists(cm, inner.mode.xmlCurrentContext && inner.mode.xmlCurrentContext(state) || [], tagName, pos, true))
return CodeMirror.Pass;
var emptyTags = typeof opt == "object" && opt.emptyTags;
if (emptyTags && indexOf(emptyTags, tagName) > -1) {
replacements[i] = { text: "/>", newPos: CodeMirror.Pos(pos.line, pos.ch + 2) };
continue;
}
var indent = indentTags && indexOf(indentTags, lowerTagName) > -1;
replacements[i] = {indent: indent,
text: ">" + (indent ? "\n\n" : "") + "</" + tagName + ">",
newPos: indent ? CodeMirror.Pos(pos.line + 1, 0) : CodeMirror.Pos(pos.line, pos.ch + 1)};
}
var dontIndentOnAutoClose = (typeof opt == "object" && opt.dontIndentOnAutoClose);
for (var i = ranges.length - 1; i >= 0; i--) {
var info = replacements[i];
cm.replaceRange(info.text, ranges[i].head, ranges[i].anchor, "+insert");
var sel = cm.listSelections().slice(0);
sel[i] = {head: info.newPos, anchor: info.newPos};
cm.setSelections(sel);
if (!dontIndentOnAutoClose && info.indent) {
cm.indentLine(info.newPos.line, null, true);
cm.indentLine(info.newPos.line + 1, null, true);
}
}
}
function autoCloseCurrent(cm, typingSlash) {
var ranges = cm.listSelections(), replacements = [];
var head = typingSlash ? "/" : "</";
var opt = cm.getOption("autoCloseTags");
var dontIndentOnAutoClose = (typeof opt == "object" && opt.dontIndentOnSlash);
for (var i = 0; i < ranges.length; i++) {
if (!ranges[i].empty()) return CodeMirror.Pass;
var pos = ranges[i].head, tok = cm.getTokenAt(pos);
var inner = CodeMirror.innerMode(cm.getMode(), tok.state), state = inner.state;
if (typingSlash && (tok.type == "string" || tok.string.charAt(0) != "<" ||
tok.start != pos.ch - 1))
return CodeMirror.Pass;
// Kludge to get around the fact that we are not in XML mode
// when completing in JS/CSS snippet in htmlmixed mode. Does not
// work for other XML embedded languages (there is no general
// way to go from a mixed mode to its current XML state).
var replacement, mixed = inner.mode.name != "xml" && cm.getMode().name == "htmlmixed"
if (mixed && inner.mode.name == "javascript") {
replacement = head + "script";
} else if (mixed && inner.mode.name == "css") {
replacement = head + "style";
} else {
var context = inner.mode.xmlCurrentContext && inner.mode.xmlCurrentContext(state)
if (!context || (context.length && closingTagExists(cm, context, context[context.length - 1], pos)))
return CodeMirror.Pass;
replacement = head + context[context.length - 1]
}
if (cm.getLine(pos.line).charAt(tok.end) != ">") replacement += ">";
replacements[i] = replacement;
}
cm.replaceSelections(replacements);
ranges = cm.listSelections();
if (!dontIndentOnAutoClose) {
for (var i = 0; i < ranges.length; i++)
if (i == ranges.length - 1 || ranges[i].head.line < ranges[i + 1].head.line)
cm.indentLine(ranges[i].head.line);
}
}
function autoCloseSlash(cm) {
if (cm.getOption("disableInput")) return CodeMirror.Pass;
return autoCloseCurrent(cm, true);
}
CodeMirror.commands.closeTag = function(cm) { return autoCloseCurrent(cm); };
function indexOf(collection, elt) {
if (collection.indexOf) return collection.indexOf(elt);
for (var i = 0, e = collection.length; i < e; ++i)
if (collection[i] == elt) return i;
return -1;
}
// If xml-fold is loaded, we use its functionality to try and verify
// whether a given tag is actually unclosed.
function closingTagExists(cm, context, tagName, pos, newTag) {
if (!CodeMirror.scanForClosingTag) return false;
var end = Math.min(cm.lastLine() + 1, pos.line + 500);
var nextClose = CodeMirror.scanForClosingTag(cm, pos, null, end);
if (!nextClose || nextClose.tag != tagName) return false;
// If the immediate wrapping context contains onCx instances of
// the same tag, a closing tag only exists if there are at least
// that many closing tags of that type following.
var onCx = newTag ? 1 : 0
for (var i = context.length - 1; i >= 0; i--) {
if (context[i] == tagName) ++onCx
else break
}
pos = nextClose.to;
for (var i = 1; i < onCx; i++) {
var next = CodeMirror.scanForClosingTag(cm, pos, null, end);
if (!next || next.tag != tagName) return false;
pos = next.to;
}
return true;
}
});
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/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 listRE = /^(\s*)(>[> ]*|[*+-] \[[x ]\]\s|[*+-]\s|(\d+)([.)]))(\s*)/,
emptyListRE = /^(\s*)(>[> ]*|[*+-] \[[x ]\]|[*+-]|(\d+)[.)])(\s*)$/,
unorderedListRE = /[*+-]\s/;
CodeMirror.commands.newlineAndIndentContinueMarkdownList = function(cm) {
if (cm.getOption("disableInput")) return CodeMirror.Pass;
var ranges = cm.listSelections(), replacements = [];
for (var i = 0; i < ranges.length; i++) {
var pos = ranges[i].head;
// If we're not in Markdown mode, fall back to normal newlineAndIndent
var eolState = cm.getStateAfter(pos.line);
var inner = CodeMirror.innerMode(cm.getMode(), eolState);
if (inner.mode.name !== "markdown") {
cm.execCommand("newlineAndIndent");
return;
} else {
eolState = inner.state;
}
var inList = eolState.list !== false;
var inQuote = eolState.quote !== 0;
var line = cm.getLine(pos.line), match = listRE.exec(line);
var cursorBeforeBullet = /^\s*$/.test(line.slice(0, pos.ch));
if (!ranges[i].empty() || (!inList && !inQuote) || !match || cursorBeforeBullet) {
cm.execCommand("newlineAndIndent");
return;
}
if (emptyListRE.test(line)) {
var endOfQuote = inQuote && />\s*$/.test(line)
var endOfList = !/>\s*$/.test(line)
if (endOfQuote || endOfList) cm.replaceRange("", {
line: pos.line, ch: 0
}, {
line: pos.line, ch: pos.ch + 1
});
replacements[i] = "\n";
} else {
var indent = match[1], after = match[5];
var numbered = !(unorderedListRE.test(match[2]) || match[2].indexOf(">") >= 0);
var bullet = numbered ? (parseInt(match[3], 10) + 1) + match[4] : match[2].replace("x", " ");
replacements[i] = "\n" + indent + bullet + after;
if (numbered) incrementRemainingMarkdownListNumbers(cm, pos);
}
}
cm.replaceSelections(replacements);
};
// Auto-updating Markdown list numbers when a new item is added to the
// middle of a list
function incrementRemainingMarkdownListNumbers(cm, pos) {
var startLine = pos.line, lookAhead = 0, skipCount = 0;
var startItem = listRE.exec(cm.getLine(startLine)), startIndent = startItem[1];
do {
lookAhead += 1;
var nextLineNumber = startLine + lookAhead;
var nextLine = cm.getLine(nextLineNumber), nextItem = listRE.exec(nextLine);
if (nextItem) {
var nextIndent = nextItem[1];
var newNumber = (parseInt(startItem[3], 10) + lookAhead - skipCount);
var nextNumber = (parseInt(nextItem[3], 10)), itemNumber = nextNumber;
if (startIndent === nextIndent && !isNaN(nextNumber)) {
if (newNumber === nextNumber) itemNumber = nextNumber + 1;
if (newNumber > nextNumber) itemNumber = newNumber + 1;
cm.replaceRange(
nextLine.replace(listRE, nextIndent + itemNumber + nextItem[4] + nextItem[5]),
{
line: nextLineNumber, ch: 0
}, {
line: nextLineNumber, ch: nextLine.length
});
} else {
if (startIndent.length > nextIndent.length) return;
// This doesn't run if the next line immediatley indents, as it is
// not clear of the users intention (new indented item or same level)
if ((startIndent.length < nextIndent.length) && (lookAhead === 1)) return;
skipCount += 1;
}
}
} while (nextItem);
}
});
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/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) {
var ie_lt8 = /MSIE \d/.test(navigator.userAgent) &&
(document.documentMode == null || document.documentMode < 8);
var Pos = CodeMirror.Pos;
var matching = {"(": ")>", ")": "(<", "[": "]>", "]": "[<", "{": "}>", "}": "{<", "<": ">>", ">": "<<"};
function bracketRegex(config) {
return config && config.bracketRegex || /[(){}[\]]/
}
function findMatchingBracket(cm, where, config) {
var line = cm.getLineHandle(where.line), pos = where.ch - 1;
var afterCursor = config && config.afterCursor
if (afterCursor == null)
afterCursor = /(^| )cm-fat-cursor($| )/.test(cm.getWrapperElement().className)
var re = bracketRegex(config)
// A cursor is defined as between two characters, but in in vim command mode
// (i.e. not insert mode), the cursor is visually represented as a
// highlighted box on top of the 2nd character. Otherwise, we allow matches
// from before or after the cursor.
var match = (!afterCursor && pos >= 0 && re.test(line.text.charAt(pos)) && matching[line.text.charAt(pos)]) ||
re.test(line.text.charAt(pos + 1)) && matching[line.text.charAt(++pos)];
if (!match) return null;
var dir = match.charAt(1) == ">" ? 1 : -1;
if (config && config.strict && (dir > 0) != (pos == where.ch)) return null;
var style = cm.getTokenTypeAt(Pos(where.line, pos + 1));
var found = scanForBracket(cm, Pos(where.line, pos + (dir > 0 ? 1 : 0)), dir, style || null, config);
if (found == null) return null;
return {from: Pos(where.line, pos), to: found && found.pos,
match: found && found.ch == match.charAt(0), forward: dir > 0};
}
// bracketRegex is used to specify which type of bracket to scan
// should be a regexp, e.g. /[[\]]/
//
// Note: If "where" is on an open bracket, then this bracket is ignored.
//
// Returns false when no bracket was found, null when it reached
// maxScanLines and gave up
function scanForBracket(cm, where, dir, style, config) {
var maxScanLen = (config && config.maxScanLineLength) || 10000;
var maxScanLines = (config && config.maxScanLines) || 1000;
var stack = [];
var re = bracketRegex(config)
var lineEnd = dir > 0 ? Math.min(where.line + maxScanLines, cm.lastLine() + 1)
: Math.max(cm.firstLine() - 1, where.line - maxScanLines);
for (var lineNo = where.line; lineNo != lineEnd; lineNo += dir) {
var line = cm.getLine(lineNo);
if (!line) continue;
var pos = dir > 0 ? 0 : line.length - 1, end = dir > 0 ? line.length : -1;
if (line.length > maxScanLen) continue;
if (lineNo == where.line) pos = where.ch - (dir < 0 ? 1 : 0);
for (; pos != end; pos += dir) {
var ch = line.charAt(pos);
if (re.test(ch) && (style === undefined || cm.getTokenTypeAt(Pos(lineNo, pos + 1)) == style)) {
var match = matching[ch];
if (match && (match.charAt(1) == ">") == (dir > 0)) stack.push(ch);
else if (!stack.length) return {pos: Pos(lineNo, pos), ch: ch};
else stack.pop();
}
}
}
return lineNo - dir == (dir > 0 ? cm.lastLine() : cm.firstLine()) ? false : null;
}
function matchBrackets(cm, autoclear, config) {
// Disable brace matching in long lines, since it'll cause hugely slow updates
var maxHighlightLen = cm.state.matchBrackets.maxHighlightLineLength || 1000;
var marks = [], ranges = cm.listSelections();
for (var i = 0; i < ranges.length; i++) {
var match = ranges[i].empty() && findMatchingBracket(cm, ranges[i].head, config);
if (match && cm.getLine(match.from.line).length <= maxHighlightLen) {
var style = match.match ? "CodeMirror-matchingbracket" : "CodeMirror-nonmatchingbracket";
marks.push(cm.markText(match.from, Pos(match.from.line, match.from.ch + 1), {className: style}));
if (match.to && cm.getLine(match.to.line).length <= maxHighlightLen)
marks.push(cm.markText(match.to, Pos(match.to.line, match.to.ch + 1), {className: style}));
}
}
if (marks.length) {
// Kludge to work around the IE bug from issue #1193, where text
// input stops going to the textare whever this fires.
if (ie_lt8 && cm.state.focused) cm.focus();
var clear = function() {
cm.operation(function() {
for (var i = 0; i < marks.length; i++) marks[i].clear();
});
};
if (autoclear) setTimeout(clear, 800);
else return clear;
}
}
function doMatchBrackets(cm) {
cm.operation(function() {
if (cm.state.matchBrackets.currentlyHighlighted) {
cm.state.matchBrackets.currentlyHighlighted();
cm.state.matchBrackets.currentlyHighlighted = null;
}
cm.state.matchBrackets.currentlyHighlighted = matchBrackets(cm, false, cm.state.matchBrackets);
});
}
CodeMirror.defineOption("matchBrackets", false, function(cm, val, old) {
function clear(cm) {
if (cm.state.matchBrackets && cm.state.matchBrackets.currentlyHighlighted) {
cm.state.matchBrackets.currentlyHighlighted();
cm.state.matchBrackets.currentlyHighlighted = null;
}
}
if (old && old != CodeMirror.Init) {
cm.off("cursorActivity", doMatchBrackets);
cm.off("focus", doMatchBrackets)
cm.off("blur", clear)
clear(cm);
}
if (val) {
cm.state.matchBrackets = typeof val == "object" ? val : {};
cm.on("cursorActivity", doMatchBrackets);
cm.on("focus", doMatchBrackets)
cm.on("blur", clear)
}
});
CodeMirror.defineExtension("matchBrackets", function() {matchBrackets(this, true);});
CodeMirror.defineExtension("findMatchingBracket", function(pos, config, oldConfig){
// Backwards-compatibility kludge
if (oldConfig || typeof config == "boolean") {
if (!oldConfig) {
config = config ? {strict: true} : null
} else {
oldConfig.strict = config
config = oldConfig
}
}
return findMatchingBracket(this, pos, config)
});
CodeMirror.defineExtension("scanForBracket", function(pos, dir, style, config){
return scanForBracket(this, pos, dir, style, config);
});
});
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"), require("../fold/xml-fold"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "../fold/xml-fold"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.defineOption("matchTags", false, function(cm, val, old) {
if (old && old != CodeMirror.Init) {
cm.off("cursorActivity", doMatchTags);
cm.off("viewportChange", maybeUpdateMatch);
clear(cm);
}
if (val) {
cm.state.matchBothTags = typeof val == "object" && val.bothTags;
cm.on("cursorActivity", doMatchTags);
cm.on("viewportChange", maybeUpdateMatch);
doMatchTags(cm);
}
});
function clear(cm) {
if (cm.state.tagHit) cm.state.tagHit.clear();
if (cm.state.tagOther) cm.state.tagOther.clear();
cm.state.tagHit = cm.state.tagOther = null;
}
function doMatchTags(cm) {
cm.state.failedTagMatch = false;
cm.operation(function() {
clear(cm);
if (cm.somethingSelected()) return;
var cur = cm.getCursor(), range = cm.getViewport();
range.from = Math.min(range.from, cur.line); range.to = Math.max(cur.line + 1, range.to);
var match = CodeMirror.findMatchingTag(cm, cur, range);
if (!match) return;
if (cm.state.matchBothTags) {
var hit = match.at == "open" ? match.open : match.close;
if (hit) cm.state.tagHit = cm.markText(hit.from, hit.to, {className: "CodeMirror-matchingtag"});
}
var other = match.at == "close" ? match.open : match.close;
if (other)
cm.state.tagOther = cm.markText(other.from, other.to, {className: "CodeMirror-matchingtag"});
else
cm.state.failedTagMatch = true;
});
}
function maybeUpdateMatch(cm) {
if (cm.state.failedTagMatch) doMatchTags(cm);
}
CodeMirror.commands.toMatchingTag = function(cm) {
var found = CodeMirror.findMatchingTag(cm, cm.getCursor());
if (found) {
var other = found.at == "close" ? found.open : found.close;
if (other) cm.extendSelection(other.to, other.from);
}
};
});
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/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) {
CodeMirror.defineOption("showTrailingSpace", false, function(cm, val, prev) {
if (prev == CodeMirror.Init) prev = false;
if (prev && !val)
cm.removeOverlay("trailingspace");
else if (!prev && val)
cm.addOverlay({
token: function(stream) {
for (var l = stream.string.length, i = l; i && /\s/.test(stream.string.charAt(i - 1)); --i) {}
if (i > stream.pos) { stream.pos = i; return null; }
stream.pos = l;
return "trailingspace";
},
name: "trailingspace"
});
});
});
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/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 noOptions = {};
var nonWS = /[^\s\u00a0]/;
var Pos = CodeMirror.Pos;
function firstNonWS(str) {
var found = str.search(nonWS);
return found == -1 ? 0 : found;
}
CodeMirror.commands.toggleComment = function(cm) {
cm.toggleComment();
};
CodeMirror.defineExtension("toggleComment", function(options) {
if (!options) options = noOptions;
var cm = this;
var minLine = Infinity, ranges = this.listSelections(), mode = null;
for (var i = ranges.length - 1; i >= 0; i--) {
var from = ranges[i].from(), to = ranges[i].to();
if (from.line >= minLine) continue;
if (to.line >= minLine) to = Pos(minLine, 0);
minLine = from.line;
if (mode == null) {
if (cm.uncomment(from, to, options)) mode = "un";
else { cm.lineComment(from, to, options); mode = "line"; }
} else if (mode == "un") {
cm.uncomment(from, to, options);
} else {
cm.lineComment(from, to, options);
}
}
});
// Rough heuristic to try and detect lines that are part of multi-line string
function probablyInsideString(cm, pos, line) {
return /\bstring\b/.test(cm.getTokenTypeAt(Pos(pos.line, 0))) && !/^[\'\"\`]/.test(line)
}
function getMode(cm, pos) {
var mode = cm.getMode()
return mode.useInnerComments === false || !mode.innerMode ? mode : cm.getModeAt(pos)
}
CodeMirror.defineExtension("lineComment", function(from, to, options) {
if (!options) options = noOptions;
var self = this, mode = getMode(self, from);
var firstLine = self.getLine(from.line);
if (firstLine == null || probablyInsideString(self, from, firstLine)) return;
var commentString = options.lineComment || mode.lineComment;
if (!commentString) {
if (options.blockCommentStart || mode.blockCommentStart) {
options.fullLines = true;
self.blockComment(from, to, options);
}
return;
}
var end = Math.min(to.ch != 0 || to.line == from.line ? to.line + 1 : to.line, self.lastLine() + 1);
var pad = options.padding == null ? " " : options.padding;
var blankLines = options.commentBlankLines || from.line == to.line;
self.operation(function() {
if (options.indent) {
var baseString = null;
for (var i = from.line; i < end; ++i) {
var line = self.getLine(i);
var whitespace = line.slice(0, firstNonWS(line));
if (baseString == null || baseString.length > whitespace.length) {
baseString = whitespace;
}
}
for (var i = from.line; i < end; ++i) {
var line = self.getLine(i), cut = baseString.length;
if (!blankLines && !nonWS.test(line)) continue;
if (line.slice(0, cut) != baseString) cut = firstNonWS(line);
self.replaceRange(baseString + commentString + pad, Pos(i, 0), Pos(i, cut));
}
} else {
for (var i = from.line; i < end; ++i) {
if (blankLines || nonWS.test(self.getLine(i)))
self.replaceRange(commentString + pad, Pos(i, 0));
}
}
});
});
CodeMirror.defineExtension("blockComment", function(from, to, options) {
if (!options) options = noOptions;
var self = this, mode = getMode(self, from);
var startString = options.blockCommentStart || mode.blockCommentStart;
var endString = options.blockCommentEnd || mode.blockCommentEnd;
if (!startString || !endString) {
if ((options.lineComment || mode.lineComment) && options.fullLines != false)
self.lineComment(from, to, options);
return;
}
if (/\bcomment\b/.test(self.getTokenTypeAt(Pos(from.line, 0)))) return
var end = Math.min(to.line, self.lastLine());
if (end != from.line && to.ch == 0 && nonWS.test(self.getLine(end))) --end;
var pad = options.padding == null ? " " : options.padding;
if (from.line > end) return;
self.operation(function() {
if (options.fullLines != false) {
var lastLineHasText = nonWS.test(self.getLine(end));
self.replaceRange(pad + endString, Pos(end));
self.replaceRange(startString + pad, Pos(from.line, 0));
var lead = options.blockCommentLead || mode.blockCommentLead;
if (lead != null) for (var i = from.line + 1; i <= end; ++i)
if (i != end || lastLineHasText)
self.replaceRange(lead + pad, Pos(i, 0));
} else {
self.replaceRange(endString, to);
self.replaceRange(startString, from);
}
});
});
CodeMirror.defineExtension("uncomment", function(from, to, options) {
if (!options) options = noOptions;
var self = this, mode = getMode(self, from);
var end = Math.min(to.ch != 0 || to.line == from.line ? to.line : to.line - 1, self.lastLine()), start = Math.min(from.line, end);
// Try finding line comments
var lineString = options.lineComment || mode.lineComment, lines = [];
var pad = options.padding == null ? " " : options.padding, didSomething;
lineComment: {
if (!lineString) break lineComment;
for (var i = start; i <= end; ++i) {
var line = self.getLine(i);
var found = line.indexOf(lineString);
if (found > -1 && !/comment/.test(self.getTokenTypeAt(Pos(i, found + 1)))) found = -1;
if (found == -1 && nonWS.test(line)) break lineComment;
if (found > -1 && nonWS.test(line.slice(0, found))) break lineComment;
lines.push(line);
}
self.operation(function() {
for (var i = start; i <= end; ++i) {
var line = lines[i - start];
var pos = line.indexOf(lineString), endPos = pos + lineString.length;
if (pos < 0) continue;
if (line.slice(endPos, endPos + pad.length) == pad) endPos += pad.length;
didSomething = true;
self.replaceRange("", Pos(i, pos), Pos(i, endPos));
}
});
if (didSomething) return true;
}
// Try block comments
var startString = options.blockCommentStart || mode.blockCommentStart;
var endString = options.blockCommentEnd || mode.blockCommentEnd;
if (!startString || !endString) return false;
var lead = options.blockCommentLead || mode.blockCommentLead;
var startLine = self.getLine(start), open = startLine.indexOf(startString)
if (open == -1) return false
var endLine = end == start ? startLine : self.getLine(end)
var close = endLine.indexOf(endString, end == start ? open + startString.length : 0);
var insideStart = Pos(start, open + 1), insideEnd = Pos(end, close + 1)
if (close == -1 ||
!/comment/.test(self.getTokenTypeAt(insideStart)) ||
!/comment/.test(self.getTokenTypeAt(insideEnd)) ||
self.getRange(insideStart, insideEnd, "\n").indexOf(endString) > -1)
return false;
// Avoid killing block comments completely outside the selection.
// Positions of the last startString before the start of the selection, and the first endString after it.
var lastStart = startLine.lastIndexOf(startString, from.ch);
var firstEnd = lastStart == -1 ? -1 : startLine.slice(0, from.ch).indexOf(endString, lastStart + startString.length);
if (lastStart != -1 && firstEnd != -1 && firstEnd + endString.length != from.ch) return false;
// Positions of the first endString after the end of the selection, and the last startString before it.
firstEnd = endLine.indexOf(endString, to.ch);
var almostLastStart = endLine.slice(to.ch).lastIndexOf(startString, firstEnd - to.ch);
lastStart = (firstEnd == -1 || almostLastStart == -1) ? -1 : to.ch + almostLastStart;
if (firstEnd != -1 && lastStart != -1 && lastStart != to.ch) return false;
self.operation(function() {
self.replaceRange("", Pos(end, close - (pad && endLine.slice(close - pad.length, close) == pad ? pad.length : 0)),
Pos(end, close + endString.length));
var openEnd = open + startString.length;
if (pad && startLine.slice(openEnd, openEnd + pad.length) == pad) openEnd += pad.length;
self.replaceRange("", Pos(start, open), Pos(start, openEnd));
if (lead) for (var i = start + 1; i <= end; ++i) {
var line = self.getLine(i), found = line.indexOf(lead);
if (found == -1 || nonWS.test(line.slice(0, found))) continue;
var foundEnd = found + lead.length;
if (pad && line.slice(foundEnd, foundEnd + pad.length) == pad) foundEnd += pad.length;
self.replaceRange("", Pos(i, found), Pos(i, foundEnd));
}
});
return true;
});
});
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/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) {
var nonspace = /\S/g;
var repeat = String.prototype.repeat || function (n) { return Array(n + 1).join(this); };
function continueComment(cm) {
if (cm.getOption("disableInput")) return CodeMirror.Pass;
var ranges = cm.listSelections(), mode, inserts = [];
for (var i = 0; i < ranges.length; i++) {
var pos = ranges[i].head
if (!/\bcomment\b/.test(cm.getTokenTypeAt(pos))) return CodeMirror.Pass;
var modeHere = cm.getModeAt(pos)
if (!mode) mode = modeHere;
else if (mode != modeHere) return CodeMirror.Pass;
var insert = null, line, found;
var blockStart = mode.blockCommentStart, lineCmt = mode.lineComment;
if (blockStart && mode.blockCommentContinue) {
line = cm.getLine(pos.line);
var end = line.lastIndexOf(mode.blockCommentEnd, pos.ch - mode.blockCommentEnd.length);
// 1. if this block comment ended
// 2. if this is actually inside a line comment
if (end != -1 && end == pos.ch - mode.blockCommentEnd.length ||
lineCmt && (found = line.lastIndexOf(lineCmt, pos.ch - 1)) > -1 &&
/\bcomment\b/.test(cm.getTokenTypeAt({line: pos.line, ch: found + 1}))) {
// ...then don't continue it
} else if (pos.ch >= blockStart.length &&
(found = line.lastIndexOf(blockStart, pos.ch - blockStart.length)) > -1 &&
found > end) {
// reuse the existing leading spaces/tabs/mixed
// or build the correct indent using CM's tab/indent options
if (nonspaceAfter(0, line) >= found) {
insert = line.slice(0, found);
} else {
var tabSize = cm.options.tabSize, numTabs;
found = CodeMirror.countColumn(line, found, tabSize);
insert = !cm.options.indentWithTabs ? repeat.call(" ", found) :
repeat.call("\t", (numTabs = Math.floor(found / tabSize))) +
repeat.call(" ", found - tabSize * numTabs);
}
} else if ((found = line.indexOf(mode.blockCommentContinue)) > -1 &&
found <= pos.ch &&
found <= nonspaceAfter(0, line)) {
insert = line.slice(0, found);
}
if (insert != null) insert += mode.blockCommentContinue
}
if (insert == null && lineCmt && continueLineCommentEnabled(cm)) {
if (line == null) line = cm.getLine(pos.line);
found = line.indexOf(lineCmt);
// cursor at pos 0, line comment also at pos 0 => shift it down, don't continue
if (!pos.ch && !found) insert = "";
// continue only if the line starts with an optional space + line comment
else if (found > -1 && nonspaceAfter(0, line) >= found) {
// don't continue if there's only space(s) after cursor or the end of the line
insert = nonspaceAfter(pos.ch, line) > -1;
// but always continue if the next line starts with a line comment too
if (!insert) {
var next = cm.getLine(pos.line + 1) || '',
nextFound = next.indexOf(lineCmt);
insert = nextFound > -1 && nonspaceAfter(0, next) >= nextFound || null;
}
if (insert) {
insert = line.slice(0, found) + lineCmt +
line.slice(found + lineCmt.length).match(/^\s*/)[0];
}
}
}
if (insert == null) return CodeMirror.Pass;
inserts[i] = "\n" + insert;
}
cm.operation(function() {
for (var i = ranges.length - 1; i >= 0; i--)
cm.replaceRange(inserts[i], ranges[i].from(), ranges[i].to(), "+insert");
});
}
function nonspaceAfter(ch, str) {
nonspace.lastIndex = ch;
var m = nonspace.exec(str);
return m ? m.index : -1;
}
function continueLineCommentEnabled(cm) {
var opt = cm.getOption("continueComments");
if (opt && typeof opt == "object")
return opt.continueLineComment !== false;
return true;
}
CodeMirror.defineOption("continueComments", null, function(cm, val, prev) {
if (prev && prev != CodeMirror.Init)
cm.removeKeyMap("continueComment");
if (val) {
var key = "Enter";
if (typeof val == "string")
key = val;
else if (typeof val == "object" && val.key)
key = val.key;
var map = {name: "continueComment"};
map[key] = continueComment;
cm.addKeyMap(map);
}
});
});
.CodeMirror-dialog {
position: absolute;
left: 0; right: 0;
background: inherit;
z-index: 15;
padding: .1em .8em;
overflow: hidden;
color: inherit;
}
.CodeMirror-dialog-top {
border-bottom: 1px solid #eee;
top: 0;
}
.CodeMirror-dialog-bottom {
border-top: 1px solid #eee;
bottom: 0;
}
.CodeMirror-dialog input {
border: none;
outline: none;
background: transparent;
width: 20em;
color: inherit;
font-family: monospace;
}
.CodeMirror-dialog button {
font-size: 70%;
}
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
// Open simple dialogs on top of an editor. Relies on dialog.css.
(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) {
function dialogDiv(cm, template, bottom) {
var wrap = cm.getWrapperElement();
var dialog;
dialog = wrap.appendChild(document.createElement("div"));
if (bottom)
dialog.className = "CodeMirror-dialog CodeMirror-dialog-bottom";
else
dialog.className = "CodeMirror-dialog CodeMirror-dialog-top";
if (typeof template == "string") {
dialog.innerHTML = template;
} else { // Assuming it's a detached DOM element.
dialog.appendChild(template);
}
CodeMirror.addClass(wrap, 'dialog-opened');
return dialog;
}
function closeNotification(cm, newVal) {
if (cm.state.currentNotificationClose)
cm.state.currentNotificationClose();
cm.state.currentNotificationClose = newVal;
}
CodeMirror.defineExtension("openDialog", function(template, callback, options) {
if (!options) options = {};
closeNotification(this, null);
var dialog = dialogDiv(this, template, options.bottom);
var closed = false, me = this;
function close(newVal) {
if (typeof newVal == 'string') {
inp.value = newVal;
} else {
if (closed) return;
closed = true;
CodeMirror.rmClass(dialog.parentNode, 'dialog-opened');
dialog.parentNode.removeChild(dialog);
me.focus();
if (options.onClose) options.onClose(dialog);
}
}
var inp = dialog.getElementsByTagName("input")[0], button;
if (inp) {
inp.focus();
if (options.value) {
inp.value = options.value;
if (options.selectValueOnOpen !== false) {
inp.select();
}
}
if (options.onInput)
CodeMirror.on(inp, "input", function(e) { options.onInput(e, inp.value, close);});
if (options.onKeyUp)
CodeMirror.on(inp, "keyup", function(e) {options.onKeyUp(e, inp.value, close);});
CodeMirror.on(inp, "keydown", function(e) {
if (options && options.onKeyDown && options.onKeyDown(e, inp.value, close)) { return; }
if (e.keyCode == 27 || (options.closeOnEnter !== false && e.keyCode == 13)) {
inp.blur();
CodeMirror.e_stop(e);
close();
}
if (e.keyCode == 13) callback(inp.value, e);
});
if (options.closeOnBlur !== false) CodeMirror.on(dialog, "focusout", function (evt) {
if (evt.relatedTarget !== null) close();
});
} else if (button = dialog.getElementsByTagName("button")[0]) {
CodeMirror.on(button, "click", function() {
close();
me.focus();
});
if (options.closeOnBlur !== false) CodeMirror.on(button, "blur", close);
button.focus();
}
return close;
});
CodeMirror.defineExtension("openConfirm", function(template, callbacks, options) {
closeNotification(this, null);
var dialog = dialogDiv(this, template, options && options.bottom);
var buttons = dialog.getElementsByTagName("button");
var closed = false, me = this, blurring = 1;
function close() {
if (closed) return;
closed = true;
CodeMirror.rmClass(dialog.parentNode, 'dialog-opened');
dialog.parentNode.removeChild(dialog);
me.focus();
}
buttons[0].focus();
for (var i = 0; i < buttons.length; ++i) {
var b = buttons[i];
(function(callback) {
CodeMirror.on(b, "click", function(e) {
CodeMirror.e_preventDefault(e);
close();
if (callback) callback(me);
});
})(callbacks[i]);
CodeMirror.on(b, "blur", function() {
--blurring;
setTimeout(function() { if (blurring <= 0) close(); }, 200);
});
CodeMirror.on(b, "focus", function() { ++blurring; });
}
});
/*
* openNotification
* Opens a notification, that can be closed with an optional timer
* (default 5000ms timer) and always closes on click.
*
* If a notification is opened while another is opened, it will close the
* currently opened one and open the new one immediately.
*/
CodeMirror.defineExtension("openNotification", function(template, options) {
closeNotification(this, close);
var dialog = dialogDiv(this, template, options && options.bottom);
var closed = false, doneTimer;
var duration = options && typeof options.duration !== "undefined" ? options.duration : 5000;
function close() {
if (closed) return;
closed = true;
clearTimeout(doneTimer);
CodeMirror.rmClass(dialog.parentNode, 'dialog-opened');
dialog.parentNode.removeChild(dialog);
}
CodeMirror.on(dialog, 'click', function(e) {
CodeMirror.e_preventDefault(e);
close();
});
if (duration)
doneTimer = setTimeout(close, duration);
return close;
});
});
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/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.defineOption("autoRefresh", false, function(cm, val) {
if (cm.state.autoRefresh) {
stopListening(cm, cm.state.autoRefresh)
cm.state.autoRefresh = null
}
if (val && cm.display.wrapper.offsetHeight == 0)
startListening(cm, cm.state.autoRefresh = {delay: val.delay || 250})
})
function startListening(cm, state) {
function check() {
if (cm.display.wrapper.offsetHeight) {
stopListening(cm, state)
if (cm.display.lastWrapHeight != cm.display.wrapper.clientHeight)
cm.refresh()
} else {
state.timeout = setTimeout(check, state.delay)
}
}
state.timeout = setTimeout(check, state.delay)
state.hurry = function() {
clearTimeout(state.timeout)
state.timeout = setTimeout(check, 50)
}
CodeMirror.on(window, "mouseup", state.hurry)
CodeMirror.on(window, "keyup", state.hurry)
}
function stopListening(_cm, state) {
clearTimeout(state.timeout)
CodeMirror.off(window, "mouseup", state.hurry)
CodeMirror.off(window, "keyup", state.hurry)
}
});
.CodeMirror-fullscreen {
position: fixed;
top: 0; left: 0; right: 0; bottom: 0;
height: auto;
z-index: 9;
}
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/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.defineOption("fullScreen", false, function(cm, val, old) {
if (old == CodeMirror.Init) old = false;
if (!old == !val) return;
if (val) setFullscreen(cm);
else setNormal(cm);
});
function setFullscreen(cm) {
var wrap = cm.getWrapperElement();
cm.state.fullScreenRestore = {scrollTop: window.pageYOffset, scrollLeft: window.pageXOffset,
width: wrap.style.width, height: wrap.style.height};
wrap.style.width = "";
wrap.style.height = "auto";
wrap.className += " CodeMirror-fullscreen";
document.documentElement.style.overflow = "hidden";
cm.refresh();
}
function setNormal(cm) {
var wrap = cm.getWrapperElement();
wrap.className = wrap.className.replace(/\s*CodeMirror-fullscreen\b/, "");
document.documentElement.style.overflow = "";
var info = cm.state.fullScreenRestore;
wrap.style.width = info.width; wrap.style.height = info.height;
window.scrollTo(info.scrollLeft, info.scrollTop);
cm.refresh();
}
});
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/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) {
CodeMirror.defineExtension("addPanel", function (node, options) {
options = options || {};
if (!this.state.panels) initPanels(this);
var info = this.state.panels;
var wrapper = info.wrapper;
var cmWrapper = this.getWrapperElement();
var replace = options.replace instanceof Panel && !options.replace.cleared;
if (options.after instanceof Panel && !options.after.cleared) {
wrapper.insertBefore(node, options.before.node.nextSibling);
} else if (options.before instanceof Panel && !options.before.cleared) {
wrapper.insertBefore(node, options.before.node);
} else if (replace) {
wrapper.insertBefore(node, options.replace.node);
options.replace.clear(true);
} else if (options.position == "bottom") {
wrapper.appendChild(node);
} else if (options.position == "before-bottom") {
wrapper.insertBefore(node, cmWrapper.nextSibling);
} else if (options.position == "after-top") {
wrapper.insertBefore(node, cmWrapper);
} else {
wrapper.insertBefore(node, wrapper.firstChild);
}
var height = (options && options.height) || node.offsetHeight;
var panel = new Panel(this, node, options, height);
info.panels.push(panel);
this.setSize();
if (options.stable && isAtTop(this, node))
this.scrollTo(null, this.getScrollInfo().top + height);
return panel;
});
function Panel(cm, node, options, height) {
this.cm = cm;
this.node = node;
this.options = options;
this.height = height;
this.cleared = false;
}
/* when skipRemove is true, clear() was called from addPanel().
* Thus removePanels() should not be called (issue 5518) */
Panel.prototype.clear = function (skipRemove) {
if (this.cleared) return;
this.cleared = true;
var info = this.cm.state.panels;
info.panels.splice(info.panels.indexOf(this), 1);
this.cm.setSize();
if (this.options.stable && isAtTop(this.cm, this.node))
this.cm.scrollTo(null, this.cm.getScrollInfo().top - this.height)
info.wrapper.removeChild(this.node);
if (info.panels.length == 0 && !skipRemove) removePanels(this.cm);
};
Panel.prototype.changed = function () {
this.height = this.node.getBoundingClientRect().height;
this.cm.setSize();
};
function initPanels(cm) {
var wrap = cm.getWrapperElement();
var style = window.getComputedStyle ? window.getComputedStyle(wrap) : wrap.currentStyle;
var height = parseInt(style.height);
var info = cm.state.panels = {
setHeight: wrap.style.height,
panels: [],
wrapper: document.createElement("div")
};
wrap.parentNode.insertBefore(info.wrapper, wrap);
var hasFocus = cm.hasFocus();
info.wrapper.appendChild(wrap);
if (hasFocus) cm.focus();
cm._setSize = cm.setSize;
if (height != null) cm.setSize = function (width, newHeight) {
if (!newHeight) newHeight = info.wrapper.offsetHeight;
info.setHeight = newHeight;
if (typeof newHeight != "number") {
var px = /^(\d+\.?\d*)px$/.exec(newHeight);
if (px) {
newHeight = Number(px[1]);
} else {
info.wrapper.style.height = newHeight;
newHeight = info.wrapper.offsetHeight;
}
}
var editorheight = newHeight - info.panels
.map(function (p) { return p.node.getBoundingClientRect().height; })
.reduce(function (a, b) { return a + b; }, 0);
cm._setSize(width, editorheight);
height = newHeight;
};
}
function removePanels(cm) {
var info = cm.state.panels;
cm.state.panels = null;
var wrap = cm.getWrapperElement();
info.wrapper.parentNode.replaceChild(wrap, info.wrapper);
wrap.style.height = info.setHeight;
cm.setSize = cm._setSize;
cm.setSize();
}
function isAtTop(cm, dom) {
for (var sibling = dom.nextSibling; sibling; sibling = sibling.nextSibling)
if (sibling == cm.getWrapperElement()) return true
return false
}
});
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/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) {
CodeMirror.defineOption("placeholder", "", function(cm, val, old) {
var prev = old && old != CodeMirror.Init;
if (val && !prev) {
cm.on("blur", onBlur);
cm.on("change", onChange);
cm.on("swapDoc", onChange);
onChange(cm);
} else if (!val && prev) {
cm.off("blur", onBlur);
cm.off("change", onChange);
cm.off("swapDoc", onChange);
clearPlaceholder(cm);
var wrapper = cm.getWrapperElement();
wrapper.className = wrapper.className.replace(" CodeMirror-empty", "");
}
if (val && !cm.hasFocus()) onBlur(cm);
});
function clearPlaceholder(cm) {
if (cm.state.placeholder) {
cm.state.placeholder.parentNode.removeChild(cm.state.placeholder);
cm.state.placeholder = null;
}
}
function setPlaceholder(cm) {
clearPlaceholder(cm);
var elt = cm.state.placeholder = document.createElement("pre");
elt.style.cssText = "height: 0; overflow: visible";
elt.style.direction = cm.getOption("direction");
elt.className = "CodeMirror-placeholder CodeMirror-line-like";
var placeHolder = cm.getOption("placeholder")
if (typeof placeHolder == "string") placeHolder = document.createTextNode(placeHolder)
elt.appendChild(placeHolder)
cm.display.lineSpace.insertBefore(elt, cm.display.lineSpace.firstChild);
}
function onBlur(cm) {
if (isEmpty(cm)) setPlaceholder(cm);
}
function onChange(cm) {
var wrapper = cm.getWrapperElement(), empty = isEmpty(cm);
wrapper.className = wrapper.className.replace(" CodeMirror-empty", "") + (empty ? " CodeMirror-empty" : "");
if (empty) setPlaceholder(cm);
else clearPlaceholder(cm);
}
function isEmpty(cm) {
return (cm.lineCount() === 1) && (cm.getLine(0) === "");
}
});
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/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.defineOption("rulers", false, function(cm, val) {
if (cm.state.rulerDiv) {
cm.state.rulerDiv.parentElement.removeChild(cm.state.rulerDiv)
cm.state.rulerDiv = null
cm.off("refresh", drawRulers)
}
if (val && val.length) {
cm.state.rulerDiv = cm.display.lineSpace.parentElement.insertBefore(document.createElement("div"), cm.display.lineSpace)
cm.state.rulerDiv.className = "CodeMirror-rulers"
drawRulers(cm)
cm.on("refresh", drawRulers)
}
});
function drawRulers(cm) {
cm.state.rulerDiv.textContent = ""
var val = cm.getOption("rulers");
var cw = cm.defaultCharWidth();
var left = cm.charCoords(CodeMirror.Pos(cm.firstLine(), 0), "div").left;
cm.state.rulerDiv.style.minHeight = (cm.display.scroller.offsetHeight + 30) + "px";
for (var i = 0; i < val.length; i++) {
var elt = document.createElement("div");
elt.className = "CodeMirror-ruler";
var col, conf = val[i];
if (typeof conf == "number") {
col = conf;
} else {
col = conf.column;
if (conf.className) elt.className += " " + conf.className;
if (conf.color) elt.style.borderColor = conf.color;
if (conf.lineStyle) elt.style.borderLeftStyle = conf.lineStyle;
if (conf.width) elt.style.borderLeftWidth = conf.width;
}
elt.style.left = (left + col * cw) + "px";
cm.state.rulerDiv.appendChild(elt)
}
}
});
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/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.registerHelper("fold", "brace", function(cm, start) {
var line = start.line, lineText = cm.getLine(line);
var tokenType;
function findOpening(openCh) {
for (var at = start.ch, pass = 0;;) {
var found = at <= 0 ? -1 : lineText.lastIndexOf(openCh, at - 1);
if (found == -1) {
if (pass == 1) break;
pass = 1;
at = lineText.length;
continue;
}
if (pass == 1 && found < start.ch) break;
tokenType = cm.getTokenTypeAt(CodeMirror.Pos(line, found + 1));
if (!/^(comment|string)/.test(tokenType)) return found + 1;
at = found - 1;
}
}
var startToken = "{", endToken = "}", startCh = findOpening("{");
if (startCh == null) {
startToken = "[", endToken = "]";
startCh = findOpening("[");
}
if (startCh == null) return;
var count = 1, lastLine = cm.lastLine(), end, endCh;
outer: for (var i = line; i <= lastLine; ++i) {
var text = cm.getLine(i), pos = i == line ? startCh : 0;
for (;;) {
var nextOpen = text.indexOf(startToken, pos), nextClose = text.indexOf(endToken, pos);
if (nextOpen < 0) nextOpen = text.length;
if (nextClose < 0) nextClose = text.length;
pos = Math.min(nextOpen, nextClose);
if (pos == text.length) break;
if (cm.getTokenTypeAt(CodeMirror.Pos(i, pos + 1)) == tokenType) {
if (pos == nextOpen) ++count;
else if (!--count) { end = i; endCh = pos; break outer; }
}
++pos;
}
}
if (end == null || line == end) return;
return {from: CodeMirror.Pos(line, startCh),
to: CodeMirror.Pos(end, endCh)};
});
CodeMirror.registerHelper("fold", "import", function(cm, start) {
function hasImport(line) {
if (line < cm.firstLine() || line > cm.lastLine()) return null;
var start = cm.getTokenAt(CodeMirror.Pos(line, 1));
if (!/\S/.test(start.string)) start = cm.getTokenAt(CodeMirror.Pos(line, start.end + 1));
if (start.type != "keyword" || start.string != "import") return null;
// Now find closing semicolon, return its position
for (var i = line, e = Math.min(cm.lastLine(), line + 10); i <= e; ++i) {
var text = cm.getLine(i), semi = text.indexOf(";");
if (semi != -1) return {startCh: start.end, end: CodeMirror.Pos(i, semi)};
}
}
var startLine = start.line, has = hasImport(startLine), prev;
if (!has || hasImport(startLine - 1) || ((prev = hasImport(startLine - 2)) && prev.end.line == startLine - 1))
return null;
for (var end = has.end;;) {
var next = hasImport(end.line + 1);
if (next == null) break;
end = next.end;
}
return {from: cm.clipPos(CodeMirror.Pos(startLine, has.startCh + 1)), to: end};
});
CodeMirror.registerHelper("fold", "include", function(cm, start) {
function hasInclude(line) {
if (line < cm.firstLine() || line > cm.lastLine()) return null;
var start = cm.getTokenAt(CodeMirror.Pos(line, 1));
if (!/\S/.test(start.string)) start = cm.getTokenAt(CodeMirror.Pos(line, start.end + 1));
if (start.type == "meta" && start.string.slice(0, 8) == "#include") return start.start + 8;
}
var startLine = start.line, has = hasInclude(startLine);
if (has == null || hasInclude(startLine - 1) != null) return null;
for (var end = startLine;;) {
var next = hasInclude(end + 1);
if (next == null) break;
++end;
}
return {from: CodeMirror.Pos(startLine, has + 1),
to: cm.clipPos(CodeMirror.Pos(end))};
});
});
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/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.registerGlobalHelper("fold", "comment", function(mode) {
return mode.blockCommentStart && mode.blockCommentEnd;
}, function(cm, start) {
var mode = cm.getModeAt(start), startToken = mode.blockCommentStart, endToken = mode.blockCommentEnd;
if (!startToken || !endToken) return;
var line = start.line, lineText = cm.getLine(line);
var startCh;
for (var at = start.ch, pass = 0;;) {
var found = at <= 0 ? -1 : lineText.lastIndexOf(startToken, at - 1);
if (found == -1) {
if (pass == 1) return;
pass = 1;
at = lineText.length;
continue;
}
if (pass == 1 && found < start.ch) return;
if (/comment/.test(cm.getTokenTypeAt(CodeMirror.Pos(line, found + 1))) &&
(found == 0 || lineText.slice(found - endToken.length, found) == endToken ||
!/comment/.test(cm.getTokenTypeAt(CodeMirror.Pos(line, found))))) {
startCh = found + startToken.length;
break;
}
at = found - 1;
}
var depth = 1, lastLine = cm.lastLine(), end, endCh;
outer: for (var i = line; i <= lastLine; ++i) {
var text = cm.getLine(i), pos = i == line ? startCh : 0;
for (;;) {
var nextOpen = text.indexOf(startToken, pos), nextClose = text.indexOf(endToken, pos);
if (nextOpen < 0) nextOpen = text.length;
if (nextClose < 0) nextClose = text.length;
pos = Math.min(nextOpen, nextClose);
if (pos == text.length) break;
if (pos == nextOpen) ++depth;
else if (!--depth) { end = i; endCh = pos; break outer; }
++pos;
}
}
if (end == null || line == end && endCh == startCh) return;
return {from: CodeMirror.Pos(line, startCh),
to: CodeMirror.Pos(end, endCh)};
});
});
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/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";
function doFold(cm, pos, options, force) {
if (options && options.call) {
var finder = options;
options = null;
} else {
var finder = getOption(cm, options, "rangeFinder");
}
if (typeof pos == "number") pos = CodeMirror.Pos(pos, 0);
var minSize = getOption(cm, options, "minFoldSize");
function getRange(allowFolded) {
var range = finder(cm, pos);
if (!range || range.to.line - range.from.line < minSize) return null;
var marks = cm.findMarksAt(range.from);
for (var i = 0; i < marks.length; ++i) {
if (marks[i].__isFold && force !== "fold") {
if (!allowFolded) return null;
range.cleared = true;
marks[i].clear();
}
}
return range;
}
var range = getRange(true);
if (getOption(cm, options, "scanUp")) while (!range && pos.line > cm.firstLine()) {
pos = CodeMirror.Pos(pos.line - 1, 0);
range = getRange(false);
}
if (!range || range.cleared || force === "unfold") return;
var myWidget = makeWidget(cm, options, range);
CodeMirror.on(myWidget, "mousedown", function(e) {
myRange.clear();
CodeMirror.e_preventDefault(e);
});
var myRange = cm.markText(range.from, range.to, {
replacedWith: myWidget,
clearOnEnter: getOption(cm, options, "clearOnEnter"),
__isFold: true
});
myRange.on("clear", function(from, to) {
CodeMirror.signal(cm, "unfold", cm, from, to);
});
CodeMirror.signal(cm, "fold", cm, range.from, range.to);
}
function makeWidget(cm, options, range) {
var widget = getOption(cm, options, "widget");
if (typeof widget == "function") {
widget = widget(range.from, range.to);
}
if (typeof widget == "string") {
var text = document.createTextNode(widget);
widget = document.createElement("span");
widget.appendChild(text);
widget.className = "CodeMirror-foldmarker";
} else if (widget) {
widget = widget.cloneNode(true)
}
return widget;
}
// Clumsy backwards-compatible interface
CodeMirror.newFoldFunction = function(rangeFinder, widget) {
return function(cm, pos) { doFold(cm, pos, {rangeFinder: rangeFinder, widget: widget}); };
};
// New-style interface
CodeMirror.defineExtension("foldCode", function(pos, options, force) {
doFold(this, pos, options, force);
});
CodeMirror.defineExtension("isFolded", function(pos) {
var marks = this.findMarksAt(pos);
for (var i = 0; i < marks.length; ++i)
if (marks[i].__isFold) return true;
});
CodeMirror.commands.toggleFold = function(cm) {
cm.foldCode(cm.getCursor());
};
CodeMirror.commands.fold = function(cm) {
cm.foldCode(cm.getCursor(), null, "fold");
};
CodeMirror.commands.unfold = function(cm) {
cm.foldCode(cm.getCursor(), null, "unfold");
};
CodeMirror.commands.foldAll = function(cm) {
cm.operation(function() {
for (var i = cm.firstLine(), e = cm.lastLine(); i <= e; i++)
cm.foldCode(CodeMirror.Pos(i, 0), null, "fold");
});
};
CodeMirror.commands.unfoldAll = function(cm) {
cm.operation(function() {
for (var i = cm.firstLine(), e = cm.lastLine(); i <= e; i++)
cm.foldCode(CodeMirror.Pos(i, 0), null, "unfold");
});
};
CodeMirror.registerHelper("fold", "combine", function() {
var funcs = Array.prototype.slice.call(arguments, 0);
return function(cm, start) {
for (var i = 0; i < funcs.length; ++i) {
var found = funcs[i](cm, start);
if (found) return found;
}
};
});
CodeMirror.registerHelper("fold", "auto", function(cm, start) {
var helpers = cm.getHelpers(start, "fold");
for (var i = 0; i < helpers.length; i++) {
var cur = helpers[i](cm, start);
if (cur) return cur;
}
});
var defaultOptions = {
rangeFinder: CodeMirror.fold.auto,
widget: "\u2194",
minFoldSize: 0,
scanUp: false,
clearOnEnter: true
};
CodeMirror.defineOption("foldOptions", null);
function getOption(cm, options, name) {
if (options && options[name] !== undefined)
return options[name];
var editorOptions = cm.options.foldOptions;
if (editorOptions && editorOptions[name] !== undefined)
return editorOptions[name];
return defaultOptions[name];
}
CodeMirror.defineExtension("foldOption", function(options, name) {
return getOption(this, options, name);
});
});
.CodeMirror-foldmarker {
color: blue;
text-shadow: #b9f 1px 1px 2px, #b9f -1px -1px 2px, #b9f 1px -1px 2px, #b9f -1px 1px 2px;
font-family: arial;
line-height: .3;
cursor: pointer;
}
.CodeMirror-foldgutter {
width: .7em;
}
.CodeMirror-foldgutter-open,
.CodeMirror-foldgutter-folded {
cursor: pointer;
}
.CodeMirror-foldgutter-open:after {
content: "\25BE";
}
.CodeMirror-foldgutter-folded:after {
content: "\25B8";
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
.CodeMirror-search-match {
background: gold;
border-top: 1px solid orange;
border-bottom: 1px solid orange;
-moz-box-sizing: border-box;
box-sizing: border-box;
opacity: .5;
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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