12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607 |
- /* ---- lib/Class.coffee ---- */
- (function() {
- var Class,
- slice = [].slice;
- Class = (function() {
- function Class() {}
- Class.prototype.trace = true;
- Class.prototype.log = function() {
- var args;
- args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
- if (!this.trace) {
- return;
- }
- if (typeof console === 'undefined') {
- return;
- }
- args.unshift("[" + this.constructor.name + "]");
- console.log.apply(console, args);
- return this;
- };
- Class.prototype.logStart = function() {
- var args, name;
- name = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
- if (!this.trace) {
- return;
- }
- this.logtimers || (this.logtimers = {});
- this.logtimers[name] = +(new Date);
- if (args.length > 0) {
- this.log.apply(this, ["" + name].concat(slice.call(args), ["(started)"]));
- }
- return this;
- };
- Class.prototype.logEnd = function() {
- var args, ms, name;
- name = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
- ms = +(new Date) - this.logtimers[name];
- this.log.apply(this, ["" + name].concat(slice.call(args), ["(Done in " + ms + "ms)"]));
- return this;
- };
- return Class;
- })();
- window.Class = Class;
- }).call(this);
- /* ---- lib/Promise.coffee ---- */
- (function() {
- var Promise,
- slice = [].slice;
- Promise = (function() {
- Promise.when = function() {
- var args, fn, i, len, num_uncompleted, promise, task, task_id, tasks;
- tasks = 1 <= arguments.length ? slice.call(arguments, 0) : [];
- num_uncompleted = tasks.length;
- args = new Array(num_uncompleted);
- promise = new Promise();
- fn = function(task_id) {
- return task.then(function() {
- args[task_id] = Array.prototype.slice.call(arguments);
- num_uncompleted--;
- if (num_uncompleted === 0) {
- return promise.complete.apply(promise, args);
- }
- });
- };
- for (task_id = i = 0, len = tasks.length; i < len; task_id = ++i) {
- task = tasks[task_id];
- fn(task_id);
- }
- return promise;
- };
- function Promise() {
- this.resolved = false;
- this.end_promise = null;
- this.result = null;
- this.callbacks = [];
- }
- Promise.prototype.resolve = function() {
- var back, callback, i, len, ref;
- if (this.resolved) {
- return false;
- }
- this.resolved = true;
- this.data = arguments;
- if (!arguments.length) {
- this.data = [true];
- }
- this.result = this.data[0];
- ref = this.callbacks;
- for (i = 0, len = ref.length; i < len; i++) {
- callback = ref[i];
- back = callback.apply(callback, this.data);
- }
- if (this.end_promise) {
- return this.end_promise.resolve(back);
- }
- };
- Promise.prototype.fail = function() {
- return this.resolve(false);
- };
- Promise.prototype.then = function(callback) {
- if (this.resolved === true) {
- callback.apply(callback, this.data);
- return;
- }
- this.callbacks.push(callback);
- return this.end_promise = new Promise();
- };
- return Promise;
- })();
- window.Promise = Promise;
- /*
- s = Date.now()
- log = (text) ->
- console.log Date.now()-s, Array.prototype.slice.call(arguments).join(", ")
-
- log "Started"
-
- cmd = (query) ->
- p = new Promise()
- setTimeout ( ->
- p.resolve query+" Result"
- ), 100
- return p
-
- back = cmd("SELECT * FROM message").then (res) ->
- log res
- return "Return from query"
- .then (res) ->
- log "Back then", res
-
- log "Query started", back
- */
- }).call(this);
- /* ---- lib/Prototypes.coffee ---- */
- (function() {
- String.prototype.startsWith = function(s) {
- return this.slice(0, s.length) === s;
- };
- String.prototype.endsWith = function(s) {
- return s === '' || this.slice(-s.length) === s;
- };
- String.prototype.repeat = function(count) {
- return new Array(count + 1).join(this);
- };
- window.isEmpty = function(obj) {
- var key;
- for (key in obj) {
- return false;
- }
- return true;
- };
- }).call(this);
- /* ---- lib/maquette.js ---- */
- (function (root, factory) {
- if (typeof define === 'function' && define.amd) {
- // AMD. Register as an anonymous module.
- define(['exports'], factory);
- } else if (typeof exports === 'object' && typeof exports.nodeName !== 'string') {
- // CommonJS
- factory(exports);
- } else {
- // Browser globals
- factory(root.maquette = {});
- }
- }(this, function (exports) {
- 'use strict';
- ;
- ;
- ;
- ;
- var NAMESPACE_W3 = 'http://www.w3.org/';
- var NAMESPACE_SVG = NAMESPACE_W3 + '2000/svg';
- var NAMESPACE_XLINK = NAMESPACE_W3 + '1999/xlink';
- // Utilities
- var emptyArray = [];
- var extend = function (base, overrides) {
- var result = {};
- Object.keys(base).forEach(function (key) {
- result[key] = base[key];
- });
- if (overrides) {
- Object.keys(overrides).forEach(function (key) {
- result[key] = overrides[key];
- });
- }
- return result;
- };
- // Hyperscript helper functions
- var same = function (vnode1, vnode2) {
- if (vnode1.vnodeSelector !== vnode2.vnodeSelector) {
- return false;
- }
- if (vnode1.properties && vnode2.properties) {
- if (vnode1.properties.key !== vnode2.properties.key) {
- return false;
- }
- return vnode1.properties.bind === vnode2.properties.bind;
- }
- return !vnode1.properties && !vnode2.properties;
- };
- var toTextVNode = function (data) {
- return {
- vnodeSelector: '',
- properties: undefined,
- children: undefined,
- text: data.toString(),
- domNode: null
- };
- };
- var appendChildren = function (parentSelector, insertions, main) {
- for (var i = 0; i < insertions.length; i++) {
- var item = insertions[i];
- if (Array.isArray(item)) {
- appendChildren(parentSelector, item, main);
- } else {
- if (item !== null && item !== undefined) {
- if (!item.hasOwnProperty('vnodeSelector')) {
- item = toTextVNode(item);
- }
- main.push(item);
- }
- }
- }
- };
- // Render helper functions
- var missingTransition = function () {
- throw new Error('Provide a transitions object to the projectionOptions to do animations');
- };
- var DEFAULT_PROJECTION_OPTIONS = {
- namespace: undefined,
- eventHandlerInterceptor: undefined,
- styleApplyer: function (domNode, styleName, value) {
- // Provides a hook to add vendor prefixes for browsers that still need it.
- domNode.style[styleName] = value;
- },
- transitions: {
- enter: missingTransition,
- exit: missingTransition
- }
- };
- var applyDefaultProjectionOptions = function (projectorOptions) {
- return extend(DEFAULT_PROJECTION_OPTIONS, projectorOptions);
- };
- var checkStyleValue = function (styleValue) {
- if (typeof styleValue !== 'string') {
- throw new Error('Style values must be strings');
- }
- };
- var setProperties = function (domNode, properties, projectionOptions) {
- if (!properties) {
- return;
- }
- var eventHandlerInterceptor = projectionOptions.eventHandlerInterceptor;
- var propNames = Object.keys(properties);
- var propCount = propNames.length;
- for (var i = 0; i < propCount; i++) {
- var propName = propNames[i];
- /* tslint:disable:no-var-keyword: edge case */
- var propValue = properties[propName];
- /* tslint:enable:no-var-keyword */
- if (propName === 'className') {
- throw new Error('Property "className" is not supported, use "class".');
- } else if (propName === 'class') {
- if (domNode.className) {
- // May happen if classes is specified before class
- domNode.className += ' ' + propValue;
- } else {
- domNode.className = propValue;
- }
- } else if (propName === 'classes') {
- // object with string keys and boolean values
- var classNames = Object.keys(propValue);
- var classNameCount = classNames.length;
- for (var j = 0; j < classNameCount; j++) {
- var className = classNames[j];
- if (propValue[className]) {
- domNode.classList.add(className);
- }
- }
- } else if (propName === 'styles') {
- // object with string keys and string (!) values
- var styleNames = Object.keys(propValue);
- var styleCount = styleNames.length;
- for (var j = 0; j < styleCount; j++) {
- var styleName = styleNames[j];
- var styleValue = propValue[styleName];
- if (styleValue) {
- checkStyleValue(styleValue);
- projectionOptions.styleApplyer(domNode, styleName, styleValue);
- }
- }
- } else if (propName === 'key') {
- continue;
- } else if (propValue === null || propValue === undefined) {
- continue;
- } else {
- var type = typeof propValue;
- if (type === 'function') {
- if (propName.lastIndexOf('on', 0) === 0) {
- if (eventHandlerInterceptor) {
- propValue = eventHandlerInterceptor(propName, propValue, domNode, properties); // intercept eventhandlers
- }
- if (propName === 'oninput') {
- (function () {
- // record the evt.target.value, because IE and Edge sometimes do a requestAnimationFrame between changing value and running oninput
- var oldPropValue = propValue;
- propValue = function (evt) {
- evt.target['oninput-value'] = evt.target.value;
- // may be HTMLTextAreaElement as well
- oldPropValue.apply(this, [evt]);
- };
- }());
- }
- domNode[propName] = propValue;
- }
- } else if (type === 'string' && propName !== 'value' && propName !== 'innerHTML') {
- if (projectionOptions.namespace === NAMESPACE_SVG && propName === 'href') {
- domNode.setAttributeNS(NAMESPACE_XLINK, propName, propValue);
- } else {
- domNode.setAttribute(propName, propValue);
- }
- } else {
- domNode[propName] = propValue;
- }
- }
- }
- };
- var updateProperties = function (domNode, previousProperties, properties, projectionOptions) {
- if (!properties) {
- return;
- }
- var propertiesUpdated = false;
- var propNames = Object.keys(properties);
- var propCount = propNames.length;
- for (var i = 0; i < propCount; i++) {
- var propName = propNames[i];
- // assuming that properties will be nullified instead of missing is by design
- var propValue = properties[propName];
- var previousValue = previousProperties[propName];
- if (propName === 'class') {
- if (previousValue !== propValue) {
- throw new Error('"class" property may not be updated. Use the "classes" property for conditional css classes.');
- }
- } else if (propName === 'classes') {
- var classList = domNode.classList;
- var classNames = Object.keys(propValue);
- var classNameCount = classNames.length;
- for (var j = 0; j < classNameCount; j++) {
- var className = classNames[j];
- var on = !!propValue[className];
- var previousOn = !!previousValue[className];
- if (on === previousOn) {
- continue;
- }
- propertiesUpdated = true;
- if (on) {
- classList.add(className);
- } else {
- classList.remove(className);
- }
- }
- } else if (propName === 'styles') {
- var styleNames = Object.keys(propValue);
- var styleCount = styleNames.length;
- for (var j = 0; j < styleCount; j++) {
- var styleName = styleNames[j];
- var newStyleValue = propValue[styleName];
- var oldStyleValue = previousValue[styleName];
- if (newStyleValue === oldStyleValue) {
- continue;
- }
- propertiesUpdated = true;
- if (newStyleValue) {
- checkStyleValue(newStyleValue);
- projectionOptions.styleApplyer(domNode, styleName, newStyleValue);
- } else {
- projectionOptions.styleApplyer(domNode, styleName, '');
- }
- }
- } else {
- if (!propValue && typeof previousValue === 'string') {
- propValue = '';
- }
- if (propName === 'value') {
- if (domNode[propName] !== propValue && domNode['oninput-value'] !== propValue) {
- domNode[propName] = propValue;
- // Reset the value, even if the virtual DOM did not change
- domNode['oninput-value'] = undefined;
- }
- // else do not update the domNode, otherwise the cursor position would be changed
- if (propValue !== previousValue) {
- propertiesUpdated = true;
- }
- } else if (propValue !== previousValue) {
- var type = typeof propValue;
- if (type === 'function') {
- throw new Error('Functions may not be updated on subsequent renders (property: ' + propName + '). Hint: declare event handler functions outside the render() function.');
- }
- if (type === 'string' && propName !== 'innerHTML') {
- if (projectionOptions.namespace === NAMESPACE_SVG && propName === 'href') {
- domNode.setAttributeNS(NAMESPACE_XLINK, propName, propValue);
- } else {
- domNode.setAttribute(propName, propValue);
- }
- } else {
- if (domNode[propName] !== propValue) {
- domNode[propName] = propValue;
- }
- }
- propertiesUpdated = true;
- }
- }
- }
- return propertiesUpdated;
- };
- var findIndexOfChild = function (children, sameAs, start) {
- if (sameAs.vnodeSelector !== '') {
- // Never scan for text-nodes
- for (var i = start; i < children.length; i++) {
- if (same(children[i], sameAs)) {
- return i;
- }
- }
- }
- return -1;
- };
- var nodeAdded = function (vNode, transitions) {
- if (vNode.properties) {
- var enterAnimation = vNode.properties.enterAnimation;
- if (enterAnimation) {
- if (typeof enterAnimation === 'function') {
- enterAnimation(vNode.domNode, vNode.properties);
- } else {
- transitions.enter(vNode.domNode, vNode.properties, enterAnimation);
- }
- }
- }
- };
- var nodeToRemove = function (vNode, transitions) {
- var domNode = vNode.domNode;
- if (vNode.properties) {
- var exitAnimation = vNode.properties.exitAnimation;
- if (exitAnimation) {
- domNode.style.pointerEvents = 'none';
- var removeDomNode = function () {
- if (domNode.parentNode) {
- domNode.parentNode.removeChild(domNode);
- }
- };
- if (typeof exitAnimation === 'function') {
- exitAnimation(domNode, removeDomNode, vNode.properties);
- return;
- } else {
- transitions.exit(vNode.domNode, vNode.properties, exitAnimation, removeDomNode);
- return;
- }
- }
- }
- if (domNode.parentNode) {
- domNode.parentNode.removeChild(domNode);
- }
- };
- var checkDistinguishable = function (childNodes, indexToCheck, parentVNode, operation) {
- var childNode = childNodes[indexToCheck];
- if (childNode.vnodeSelector === '') {
- return; // Text nodes need not be distinguishable
- }
- var properties = childNode.properties;
- var key = properties ? properties.key === undefined ? properties.bind : properties.key : undefined;
- if (!key) {
- for (var i = 0; i < childNodes.length; i++) {
- if (i !== indexToCheck) {
- var node = childNodes[i];
- if (same(node, childNode)) {
- if (operation === 'added') {
- throw new Error(parentVNode.vnodeSelector + ' had a ' + childNode.vnodeSelector + ' child ' + 'added, but there is now more than one. You must add unique key properties to make them distinguishable.');
- } else {
- throw new Error(parentVNode.vnodeSelector + ' had a ' + childNode.vnodeSelector + ' child ' + 'removed, but there were more than one. You must add unique key properties to make them distinguishable.');
- }
- }
- }
- }
- }
- };
- var createDom;
- var updateDom;
- var updateChildren = function (vnode, domNode, oldChildren, newChildren, projectionOptions) {
- if (oldChildren === newChildren) {
- return false;
- }
- oldChildren = oldChildren || emptyArray;
- newChildren = newChildren || emptyArray;
- var oldChildrenLength = oldChildren.length;
- var newChildrenLength = newChildren.length;
- var transitions = projectionOptions.transitions;
- var oldIndex = 0;
- var newIndex = 0;
- var i;
- var textUpdated = false;
- while (newIndex < newChildrenLength) {
- var oldChild = oldIndex < oldChildrenLength ? oldChildren[oldIndex] : undefined;
- var newChild = newChildren[newIndex];
- if (oldChild !== undefined && same(oldChild, newChild)) {
- textUpdated = updateDom(oldChild, newChild, projectionOptions) || textUpdated;
- oldIndex++;
- } else {
- var findOldIndex = findIndexOfChild(oldChildren, newChild, oldIndex + 1);
- if (findOldIndex >= 0) {
- // Remove preceding missing children
- for (i = oldIndex; i < findOldIndex; i++) {
- nodeToRemove(oldChildren[i], transitions);
- checkDistinguishable(oldChildren, i, vnode, 'removed');
- }
- textUpdated = updateDom(oldChildren[findOldIndex], newChild, projectionOptions) || textUpdated;
- oldIndex = findOldIndex + 1;
- } else {
- // New child
- createDom(newChild, domNode, oldIndex < oldChildrenLength ? oldChildren[oldIndex].domNode : undefined, projectionOptions);
- nodeAdded(newChild, transitions);
- checkDistinguishable(newChildren, newIndex, vnode, 'added');
- }
- }
- newIndex++;
- }
- if (oldChildrenLength > oldIndex) {
- // Remove child fragments
- for (i = oldIndex; i < oldChildrenLength; i++) {
- nodeToRemove(oldChildren[i], transitions);
- checkDistinguishable(oldChildren, i, vnode, 'removed');
- }
- }
- return textUpdated;
- };
- var addChildren = function (domNode, children, projectionOptions) {
- if (!children) {
- return;
- }
- for (var i = 0; i < children.length; i++) {
- createDom(children[i], domNode, undefined, projectionOptions);
- }
- };
- var initPropertiesAndChildren = function (domNode, vnode, projectionOptions) {
- addChildren(domNode, vnode.children, projectionOptions);
- // children before properties, needed for value property of <select>.
- if (vnode.text) {
- domNode.textContent = vnode.text;
- }
- setProperties(domNode, vnode.properties, projectionOptions);
- if (vnode.properties && vnode.properties.afterCreate) {
- vnode.properties.afterCreate(domNode, projectionOptions, vnode.vnodeSelector, vnode.properties, vnode.children);
- }
- };
- createDom = function (vnode, parentNode, insertBefore, projectionOptions) {
- var domNode, i, c, start = 0, type, found;
- var vnodeSelector = vnode.vnodeSelector;
- if (vnodeSelector === '') {
- domNode = vnode.domNode = document.createTextNode(vnode.text);
- if (insertBefore !== undefined) {
- parentNode.insertBefore(domNode, insertBefore);
- } else {
- parentNode.appendChild(domNode);
- }
- } else {
- for (i = 0; i <= vnodeSelector.length; ++i) {
- c = vnodeSelector.charAt(i);
- if (i === vnodeSelector.length || c === '.' || c === '#') {
- type = vnodeSelector.charAt(start - 1);
- found = vnodeSelector.slice(start, i);
- if (type === '.') {
- domNode.classList.add(found);
- } else if (type === '#') {
- domNode.id = found;
- } else {
- if (found === 'svg') {
- projectionOptions = extend(projectionOptions, { namespace: NAMESPACE_SVG });
- }
- if (projectionOptions.namespace !== undefined) {
- domNode = vnode.domNode = document.createElementNS(projectionOptions.namespace, found);
- } else {
- domNode = vnode.domNode = document.createElement(found);
- }
- if (insertBefore !== undefined) {
- parentNode.insertBefore(domNode, insertBefore);
- } else {
- parentNode.appendChild(domNode);
- }
- }
- start = i + 1;
- }
- }
- initPropertiesAndChildren(domNode, vnode, projectionOptions);
- }
- };
- updateDom = function (previous, vnode, projectionOptions) {
- var domNode = previous.domNode;
- var textUpdated = false;
- if (previous === vnode) {
- return false; // By contract, VNode objects may not be modified anymore after passing them to maquette
- }
- var updated = false;
- if (vnode.vnodeSelector === '') {
- if (vnode.text !== previous.text) {
- var newVNode = document.createTextNode(vnode.text);
- domNode.parentNode.replaceChild(newVNode, domNode);
- vnode.domNode = newVNode;
- textUpdated = true;
- return textUpdated;
- }
- } else {
- if (vnode.vnodeSelector.lastIndexOf('svg', 0) === 0) {
- projectionOptions = extend(projectionOptions, { namespace: NAMESPACE_SVG });
- }
- if (previous.text !== vnode.text) {
- updated = true;
- if (vnode.text === undefined) {
- domNode.removeChild(domNode.firstChild); // the only textnode presumably
- } else {
- domNode.textContent = vnode.text;
- }
- }
- updated = updateChildren(vnode, domNode, previous.children, vnode.children, projectionOptions) || updated;
- updated = updateProperties(domNode, previous.properties, vnode.properties, projectionOptions) || updated;
- if (vnode.properties && vnode.properties.afterUpdate) {
- vnode.properties.afterUpdate(domNode, projectionOptions, vnode.vnodeSelector, vnode.properties, vnode.children);
- }
- }
- if (updated && vnode.properties && vnode.properties.updateAnimation) {
- vnode.properties.updateAnimation(domNode, vnode.properties, previous.properties);
- }
- vnode.domNode = previous.domNode;
- return textUpdated;
- };
- var createProjection = function (vnode, projectionOptions) {
- return {
- update: function (updatedVnode) {
- if (vnode.vnodeSelector !== updatedVnode.vnodeSelector) {
- throw new Error('The selector for the root VNode may not be changed. (consider using dom.merge and add one extra level to the virtual DOM)');
- }
- updateDom(vnode, updatedVnode, projectionOptions);
- vnode = updatedVnode;
- },
- domNode: vnode.domNode
- };
- };
- ;
- // The other two parameters are not added here, because the Typescript compiler creates surrogate code for desctructuring 'children'.
- exports.h = function (selector) {
- var properties = arguments[1];
- if (typeof selector !== 'string') {
- throw new Error();
- }
- var childIndex = 1;
- if (properties && !properties.hasOwnProperty('vnodeSelector') && !Array.isArray(properties) && typeof properties === 'object') {
- childIndex = 2;
- } else {
- // Optional properties argument was omitted
- properties = undefined;
- }
- var text = undefined;
- var children = undefined;
- var argsLength = arguments.length;
- // Recognize a common special case where there is only a single text node
- if (argsLength === childIndex + 1) {
- var onlyChild = arguments[childIndex];
- if (typeof onlyChild === 'string') {
- text = onlyChild;
- } else if (onlyChild !== undefined && onlyChild.length === 1 && typeof onlyChild[0] === 'string') {
- text = onlyChild[0];
- }
- }
- if (text === undefined) {
- children = [];
- for (; childIndex < arguments.length; childIndex++) {
- var child = arguments[childIndex];
- if (child === null || child === undefined) {
- continue;
- } else if (Array.isArray(child)) {
- appendChildren(selector, child, children);
- } else if (child.hasOwnProperty('vnodeSelector')) {
- children.push(child);
- } else {
- children.push(toTextVNode(child));
- }
- }
- }
- return {
- vnodeSelector: selector,
- properties: properties,
- children: children,
- text: text === '' ? undefined : text,
- domNode: null
- };
- };
- /**
- * Contains simple low-level utility functions to manipulate the real DOM.
- */
- exports.dom = {
- /**
- * Creates a real DOM tree from `vnode`. The [[Projection]] object returned will contain the resulting DOM Node in
- * its [[Projection.domNode|domNode]] property.
- * This is a low-level method. Users wil typically use a [[Projector]] instead.
- * @param vnode - The root of the virtual DOM tree that was created using the [[h]] function. NOTE: [[VNode]]
- * objects may only be rendered once.
- * @param projectionOptions - Options to be used to create and update the projection.
- * @returns The [[Projection]] which also contains the DOM Node that was created.
- */
- create: function (vnode, projectionOptions) {
- projectionOptions = applyDefaultProjectionOptions(projectionOptions);
- createDom(vnode, document.createElement('div'), undefined, projectionOptions);
- return createProjection(vnode, projectionOptions);
- },
- /**
- * Appends a new childnode to the DOM which is generated from a [[VNode]].
- * This is a low-level method. Users wil typically use a [[Projector]] instead.
- * @param parentNode - The parent node for the new childNode.
- * @param vnode - The root of the virtual DOM tree that was created using the [[h]] function. NOTE: [[VNode]]
- * objects may only be rendered once.
- * @param projectionOptions - Options to be used to create and update the [[Projection]].
- * @returns The [[Projection]] that was created.
- */
- append: function (parentNode, vnode, projectionOptions) {
- projectionOptions = applyDefaultProjectionOptions(projectionOptions);
- createDom(vnode, parentNode, undefined, projectionOptions);
- return createProjection(vnode, projectionOptions);
- },
- /**
- * Inserts a new DOM node which is generated from a [[VNode]].
- * This is a low-level method. Users wil typically use a [[Projector]] instead.
- * @param beforeNode - The node that the DOM Node is inserted before.
- * @param vnode - The root of the virtual DOM tree that was created using the [[h]] function.
- * NOTE: [[VNode]] objects may only be rendered once.
- * @param projectionOptions - Options to be used to create and update the projection, see [[createProjector]].
- * @returns The [[Projection]] that was created.
- */
- insertBefore: function (beforeNode, vnode, projectionOptions) {
- projectionOptions = applyDefaultProjectionOptions(projectionOptions);
- createDom(vnode, beforeNode.parentNode, beforeNode, projectionOptions);
- return createProjection(vnode, projectionOptions);
- },
- /**
- * Merges a new DOM node which is generated from a [[VNode]] with an existing DOM Node.
- * This means that the virtual DOM and the real DOM will have one overlapping element.
- * Therefore the selector for the root [[VNode]] will be ignored, but its properties and children will be applied to the Element provided.
- * This is a low-level method. Users wil typically use a [[Projector]] instead.
- * @param domNode - The existing element to adopt as the root of the new virtual DOM. Existing attributes and childnodes are preserved.
- * @param vnode - The root of the virtual DOM tree that was created using the [[h]] function. NOTE: [[VNode]] objects
- * may only be rendered once.
- * @param projectionOptions - Options to be used to create and update the projection, see [[createProjector]].
- * @returns The [[Projection]] that was created.
- */
- merge: function (element, vnode, projectionOptions) {
- projectionOptions = applyDefaultProjectionOptions(projectionOptions);
- vnode.domNode = element;
- initPropertiesAndChildren(element, vnode, projectionOptions);
- return createProjection(vnode, projectionOptions);
- }
- };
- /**
- * Creates a [[CalculationCache]] object, useful for caching [[VNode]] trees.
- * In practice, caching of [[VNode]] trees is not needed, because achieving 60 frames per second is almost never a problem.
- * For more information, see [[CalculationCache]].
- *
- * @param <Result> The type of the value that is cached.
- */
- exports.createCache = function () {
- var cachedInputs = undefined;
- var cachedOutcome = undefined;
- var result = {
- invalidate: function () {
- cachedOutcome = undefined;
- cachedInputs = undefined;
- },
- result: function (inputs, calculation) {
- if (cachedInputs) {
- for (var i = 0; i < inputs.length; i++) {
- if (cachedInputs[i] !== inputs[i]) {
- cachedOutcome = undefined;
- }
- }
- }
- if (!cachedOutcome) {
- cachedOutcome = calculation();
- cachedInputs = inputs;
- }
- return cachedOutcome;
- }
- };
- return result;
- };
- /**
- * Creates a {@link Mapping} instance that keeps an array of result objects synchronized with an array of source objects.
- * See {@link http://maquettejs.org/docs/arrays.html|Working with arrays}.
- *
- * @param <Source> The type of source items. A database-record for instance.
- * @param <Target> The type of target items. A [[Component]] for instance.
- * @param getSourceKey `function(source)` that must return a key to identify each source object. The result must either be a string or a number.
- * @param createResult `function(source, index)` that must create a new result object from a given source. This function is identical
- * to the `callback` argument in `Array.map(callback)`.
- * @param updateResult `function(source, target, index)` that updates a result to an updated source.
- */
- exports.createMapping = function (getSourceKey, createResult, updateResult) {
- var keys = [];
- var results = [];
- return {
- results: results,
- map: function (newSources) {
- var newKeys = newSources.map(getSourceKey);
- var oldTargets = results.slice();
- var oldIndex = 0;
- for (var i = 0; i < newSources.length; i++) {
- var source = newSources[i];
- var sourceKey = newKeys[i];
- if (sourceKey === keys[oldIndex]) {
- results[i] = oldTargets[oldIndex];
- updateResult(source, oldTargets[oldIndex], i);
- oldIndex++;
- } else {
- var found = false;
- for (var j = 1; j < keys.length; j++) {
- var searchIndex = (oldIndex + j) % keys.length;
- if (keys[searchIndex] === sourceKey) {
- results[i] = oldTargets[searchIndex];
- updateResult(newSources[i], oldTargets[searchIndex], i);
- oldIndex = searchIndex + 1;
- found = true;
- break;
- }
- }
- if (!found) {
- results[i] = createResult(source, i);
- }
- }
- }
- results.length = newSources.length;
- keys = newKeys;
- }
- };
- };
- /**
- * Creates a [[Projector]] instance using the provided projectionOptions.
- *
- * For more information, see [[Projector]].
- *
- * @param projectionOptions Options that influence how the DOM is rendered and updated.
- */
- exports.createProjector = function (projectorOptions) {
- var projector;
- var projectionOptions = applyDefaultProjectionOptions(projectorOptions);
- projectionOptions.eventHandlerInterceptor = function (propertyName, eventHandler, domNode, properties) {
- return function () {
- // intercept function calls (event handlers) to do a render afterwards.
- projector.scheduleRender();
- return eventHandler.apply(properties.bind || this, arguments);
- };
- };
- var renderCompleted = true;
- var scheduled;
- var stopped = false;
- var projections = [];
- var renderFunctions = [];
- // matches the projections array
- var doRender = function () {
- scheduled = undefined;
- if (!renderCompleted) {
- return; // The last render threw an error, it should be logged in the browser console.
- }
- renderCompleted = false;
- for (var i = 0; i < projections.length; i++) {
- var updatedVnode = renderFunctions[i]();
- projections[i].update(updatedVnode);
- }
- renderCompleted = true;
- };
- projector = {
- scheduleRender: function () {
- if (!scheduled && !stopped) {
- scheduled = requestAnimationFrame(doRender);
- }
- },
- stop: function () {
- if (scheduled) {
- cancelAnimationFrame(scheduled);
- scheduled = undefined;
- }
- stopped = true;
- },
- resume: function () {
- stopped = false;
- renderCompleted = true;
- projector.scheduleRender();
- },
- append: function (parentNode, renderMaquetteFunction) {
- projections.push(exports.dom.append(parentNode, renderMaquetteFunction(), projectionOptions));
- renderFunctions.push(renderMaquetteFunction);
- },
- insertBefore: function (beforeNode, renderMaquetteFunction) {
- projections.push(exports.dom.insertBefore(beforeNode, renderMaquetteFunction(), projectionOptions));
- renderFunctions.push(renderMaquetteFunction);
- },
- merge: function (domNode, renderMaquetteFunction) {
- projections.push(exports.dom.merge(domNode, renderMaquetteFunction(), projectionOptions));
- renderFunctions.push(renderMaquetteFunction);
- },
- replace: function (domNode, renderMaquetteFunction) {
- var vnode = renderMaquetteFunction();
- createDom(vnode, domNode.parentNode, domNode, projectionOptions);
- domNode.parentNode.removeChild(domNode);
- projections.push(createProjection(vnode, projectionOptions));
- renderFunctions.push(renderMaquetteFunction);
- },
- detach: function (renderMaquetteFunction) {
- for (var i = 0; i < renderFunctions.length; i++) {
- if (renderFunctions[i] === renderMaquetteFunction) {
- renderFunctions.splice(i, 1);
- return projections.splice(i, 1)[0];
- }
- }
- throw new Error('renderMaquetteFunction was not found');
- }
- };
- return projector;
- };
- }));
- /* ---- utils/Animation.coffee ---- */
- (function() {
- var Animation;
- Animation = (function() {
- function Animation() {}
- Animation.prototype.slideDown = function(elem, props) {
- var cstyle, h, margin_bottom, margin_top, padding_bottom, padding_top, transition;
- if (elem.offsetTop > 2000) {
- return;
- }
- h = elem.offsetHeight;
- cstyle = window.getComputedStyle(elem);
- margin_top = cstyle.marginTop;
- margin_bottom = cstyle.marginBottom;
- padding_top = cstyle.paddingTop;
- padding_bottom = cstyle.paddingBottom;
- transition = cstyle.transition;
- elem.style.boxSizing = "border-box";
- elem.style.overflow = "hidden";
- elem.style.transform = "scale(0.6)";
- elem.style.opacity = "0";
- elem.style.height = "0px";
- elem.style.marginTop = "0px";
- elem.style.marginBottom = "0px";
- elem.style.paddingTop = "0px";
- elem.style.paddingBottom = "0px";
- elem.style.transition = "none";
- setTimeout((function() {
- elem.className += " animate-inout";
- elem.style.height = h + "px";
- elem.style.transform = "scale(1)";
- elem.style.opacity = "1";
- elem.style.marginTop = margin_top;
- elem.style.marginBottom = margin_bottom;
- elem.style.paddingTop = padding_top;
- return elem.style.paddingBottom = padding_bottom;
- }), 1);
- return elem.addEventListener("transitionend", function() {
- elem.classList.remove("animate-inout");
- elem.style.transition = elem.style.transform = elem.style.opacity = elem.style.height = null;
- elem.style.boxSizing = elem.style.marginTop = elem.style.marginBottom = null;
- elem.style.paddingTop = elem.style.paddingBottom = elem.style.overflow = null;
- return elem.removeEventListener("transitionend", arguments.callee, false);
- });
- };
- Animation.prototype.slideUp = function(elem, remove_func, props) {
- if (elem.offsetTop > 1000) {
- return remove_func();
- }
- elem.className += " animate-back";
- elem.style.boxSizing = "border-box";
- elem.style.height = elem.offsetHeight + "px";
- elem.style.overflow = "hidden";
- elem.style.transform = "scale(1)";
- elem.style.opacity = "1";
- elem.style.pointerEvents = "none";
- setTimeout((function() {
- elem.style.height = "0px";
- elem.style.marginTop = "0px";
- elem.style.marginBottom = "0px";
- elem.style.paddingTop = "0px";
- elem.style.paddingBottom = "0px";
- elem.style.transform = "scale(0.8)";
- elem.style.borderTopWidth = "0px";
- elem.style.borderBottomWidth = "0px";
- return elem.style.opacity = "0";
- }), 1);
- return elem.addEventListener("transitionend", function(e) {
- if (e.propertyName === "opacity" || e.elapsedTime >= 0.6) {
- elem.removeEventListener("transitionend", arguments.callee, false);
- return remove_func();
- }
- });
- };
- Animation.prototype.slideUpInout = function(elem, remove_func, props) {
- elem.className += " animate-inout";
- elem.style.boxSizing = "border-box";
- elem.style.height = elem.offsetHeight + "px";
- elem.style.overflow = "hidden";
- elem.style.transform = "scale(1)";
- elem.style.opacity = "1";
- elem.style.pointerEvents = "none";
- setTimeout((function() {
- elem.style.height = "0px";
- elem.style.marginTop = "0px";
- elem.style.marginBottom = "0px";
- elem.style.paddingTop = "0px";
- elem.style.paddingBottom = "0px";
- elem.style.transform = "scale(0.8)";
- elem.style.borderTopWidth = "0px";
- elem.style.borderBottomWidth = "0px";
- return elem.style.opacity = "0";
- }), 1);
- return elem.addEventListener("transitionend", function(e) {
- if (e.propertyName === "opacity" || e.elapsedTime >= 0.6) {
- elem.removeEventListener("transitionend", arguments.callee, false);
- return remove_func();
- }
- });
- };
- Animation.prototype.showRight = function(elem, props) {
- elem.className += " animate";
- elem.style.opacity = 0;
- elem.style.transform = "TranslateX(-20px) Scale(1.01)";
- setTimeout((function() {
- elem.style.opacity = 1;
- return elem.style.transform = "TranslateX(0px) Scale(1)";
- }), 1);
- return elem.addEventListener("transitionend", function() {
- elem.classList.remove("animate");
- return elem.style.transform = elem.style.opacity = null;
- });
- };
- Animation.prototype.show = function(elem, props) {
- var delay, ref;
- delay = ((ref = arguments[arguments.length - 2]) != null ? ref.delay : void 0) * 1000 || 1;
- elem.style.opacity = 0;
- setTimeout((function() {
- return elem.className += " animate";
- }), 1);
- setTimeout((function() {
- return elem.style.opacity = 1;
- }), delay);
- return elem.addEventListener("transitionend", function() {
- elem.classList.remove("animate");
- elem.style.opacity = null;
- return elem.removeEventListener("transitionend", arguments.callee, false);
- });
- };
- Animation.prototype.hide = function(elem, remove_func, props) {
- var delay, ref;
- delay = ((ref = arguments[arguments.length - 2]) != null ? ref.delay : void 0) * 1000 || 1;
- elem.className += " animate";
- setTimeout((function() {
- return elem.style.opacity = 0;
- }), delay);
- return elem.addEventListener("transitionend", function(e) {
- if (e.propertyName === "opacity") {
- return remove_func();
- }
- });
- };
- Animation.prototype.addVisibleClass = function(elem, props) {
- return setTimeout(function() {
- return elem.classList.add("visible");
- });
- };
- return Animation;
- })();
- window.Animation = new Animation();
- }).call(this);
- /* ---- utils/Dollar.coffee ---- */
- (function() {
- window.$ = function(selector) {
- if (selector.startsWith("#")) {
- return document.getElementById(selector.replace("#", ""));
- }
- };
- }).call(this);
- /* ---- utils/ZeroFrame.coffee ---- */
- (function() {
- var ZeroFrame,
- bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
- extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
- hasProp = {}.hasOwnProperty;
- ZeroFrame = (function(superClass) {
- extend(ZeroFrame, superClass);
- function ZeroFrame(url) {
- this.onCloseWebsocket = bind(this.onCloseWebsocket, this);
- this.onOpenWebsocket = bind(this.onOpenWebsocket, this);
- this.onRequest = bind(this.onRequest, this);
- this.onMessage = bind(this.onMessage, this);
- this.url = url;
- this.waiting_cb = {};
- this.wrapper_nonce = document.location.href.replace(/.*wrapper_nonce=([A-Za-z0-9]+).*/, "$1");
- this.connect();
- this.next_message_id = 1;
- this.history_state = {};
- this.init();
- }
- ZeroFrame.prototype.init = function() {
- return this;
- };
- ZeroFrame.prototype.connect = function() {
- this.target = window.parent;
- window.addEventListener("message", this.onMessage, false);
- this.cmd("innerReady");
- window.addEventListener("beforeunload", (function(_this) {
- return function(e) {
- _this.log("save scrollTop", window.pageYOffset);
- _this.history_state["scrollTop"] = window.pageYOffset;
- return _this.cmd("wrapperReplaceState", [_this.history_state, null]);
- };
- })(this));
- return this.cmd("wrapperGetState", [], (function(_this) {
- return function(state) {
- if (state != null) {
- _this.history_state = state;
- }
- _this.log("restore scrollTop", state, window.pageYOffset);
- if (window.pageYOffset === 0 && state) {
- return window.scroll(window.pageXOffset, state.scrollTop);
- }
- };
- })(this));
- };
- ZeroFrame.prototype.onMessage = function(e) {
- var cmd, message;
- message = e.data;
- cmd = message.cmd;
- if (cmd === "response") {
- if (this.waiting_cb[message.to] != null) {
- return this.waiting_cb[message.to](message.result);
- } else {
- return this.log("Websocket callback not found:", message);
- }
- } else if (cmd === "wrapperReady") {
- return this.cmd("innerReady");
- } else if (cmd === "ping") {
- return this.response(message.id, "pong");
- } else if (cmd === "wrapperOpenedWebsocket") {
- return this.onOpenWebsocket();
- } else if (cmd === "wrapperClosedWebsocket") {
- return this.onCloseWebsocket();
- } else {
- return this.onRequest(cmd, message.params);
- }
- };
- ZeroFrame.prototype.onRequest = function(cmd, message) {
- return this.log("Unknown request", message);
- };
- ZeroFrame.prototype.response = function(to, result) {
- return this.send({
- "cmd": "response",
- "to": to,
- "result": result
- });
- };
- ZeroFrame.prototype.cmd = function(cmd, params, cb) {
- if (params == null) {
- params = {};
- }
- if (cb == null) {
- cb = null;
- }
- return this.send({
- "cmd": cmd,
- "params": params
- }, cb);
- };
- ZeroFrame.prototype.send = function(message, cb) {
- if (cb == null) {
- cb = null;
- }
- message.wrapper_nonce = this.wrapper_nonce;
- message.id = this.next_message_id;
- this.next_message_id += 1;
- this.target.postMessage(message, "*");
- if (cb) {
- return this.waiting_cb[message.id] = cb;
- }
- };
- ZeroFrame.prototype.onOpenWebsocket = function() {
- return this.log("Websocket open");
- };
- ZeroFrame.prototype.onCloseWebsocket = function() {
- return this.log("Websocket close");
- };
- return ZeroFrame;
- })(Class);
- window.ZeroFrame = ZeroFrame;
- }).call(this);
- /* ---- PluginList.coffee ---- */
- (function() {
- var PluginList,
- bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
- extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
- hasProp = {}.hasOwnProperty;
- PluginList = (function(superClass) {
- extend(PluginList, superClass);
- function PluginList(plugins) {
- this.handleDeleteClick = bind(this.handleDeleteClick, this);
- this.handleUpdateClick = bind(this.handleUpdateClick, this);
- this.handleResetClick = bind(this.handleResetClick, this);
- this.handleCheckboxChange = bind(this.handleCheckboxChange, this);
- this.savePluginStatus = bind(this.savePluginStatus, this);
- this.plugins = plugins;
- }
- PluginList.prototype.savePluginStatus = function(plugin, is_enabled) {
- Page.cmd("pluginConfigSet", [plugin.source, plugin.inner_path, "enabled", is_enabled], (function(_this) {
- return function(res) {
- if (res === "ok") {
- return Page.updatePlugins();
- } else {
- return Page.cmd("wrapperNotification", ["error", res.error]);
- }
- };
- })(this));
- return Page.projector.scheduleRender();
- };
- PluginList.prototype.handleCheckboxChange = function(e) {
- var node, plugin, value;
- node = e.currentTarget;
- plugin = node["data-plugin"];
- node.classList.toggle("checked");
- value = node.classList.contains("checked");
- return this.savePluginStatus(plugin, value);
- };
- PluginList.prototype.handleResetClick = function(e) {
- var node, plugin;
- node = e.currentTarget;
- plugin = node["data-plugin"];
- return this.savePluginStatus(plugin, null);
- };
- PluginList.prototype.handleUpdateClick = function(e) {
- var node, plugin;
- node = e.currentTarget;
- plugin = node["data-plugin"];
- node.classList.add("loading");
- Page.cmd("pluginUpdate", [plugin.source, plugin.inner_path], (function(_this) {
- return function(res) {
- if (res === "ok") {
- Page.cmd("wrapperNotification", ["done", "Plugin " + plugin.name + " updated to latest version"]);
- Page.updatePlugins();
- } else {
- Page.cmd("wrapperNotification", ["error", res.error]);
- }
- return node.classList.remove("loading");
- };
- })(this));
- return false;
- };
- PluginList.prototype.handleDeleteClick = function(e) {
- var node, plugin;
- node = e.currentTarget;
- plugin = node["data-plugin"];
- if (plugin.loaded) {
- Page.cmd("wrapperNotification", ["info", "You can only delete plugin that are not currently active"]);
- return false;
- }
- node.classList.add("loading");
- Page.cmd("wrapperConfirm", ["Delete " + plugin.name + " plugin?", "Delete"], (function(_this) {
- return function(res) {
- if (!res) {
- node.classList.remove("loading");
- return false;
- }
- return Page.cmd("pluginRemove", [plugin.source, plugin.inner_path], function(res) {
- if (res === "ok") {
- Page.cmd("wrapperNotification", ["done", "Plugin " + plugin.name + " deleted"]);
- Page.updatePlugins();
- } else {
- Page.cmd("wrapperNotification", ["error", res.error]);
- }
- return node.classList.remove("loading");
- });
- };
- })(this));
- return false;
- };
- PluginList.prototype.render = function() {
- return h("div.plugins", this.plugins.map((function(_this) {
- return function(plugin) {
- var base, descr, enabled_default, is_changed, is_pending, marker_title, ref, tag_delete, tag_source, tag_update, tag_version;
- if (!plugin.info) {
- return;
- }
- descr = plugin.info.description;
- if ((base = plugin.info)["default"] == null) {
- base["default"] = "enabled";
- }
- if (plugin.info["default"]) {
- descr += " (default: " + plugin.info["default"] + ")";
- }
- tag_version = "";
- tag_source = "";
- tag_delete = "";
- if (plugin.source !== "builtin") {
- tag_update = "";
- if ((ref = plugin.site_info) != null ? ref.rev : void 0) {
- if (plugin.site_info.rev > plugin.info.rev) {
- tag_update = h("a.version-update.button", {
- href: "#Update+plugin",
- onclick: _this.handleUpdateClick,
- "data-plugin": plugin
- }, "Update to rev" + plugin.site_info.rev);
- }
- } else {
- tag_update = h("span.version-missing", "(unable to get latest vesion: update site missing)");
- }
- tag_version = h("span.version", ["rev" + plugin.info.rev + " ", tag_update]);
- tag_source = h("div.source", [
- "Source: ", h("a", {
- "href": "/" + plugin.source,
- "target": "_top"
- }, plugin.site_title ? plugin.site_title : plugin.source), " /" + plugin.inner_path
- ]);
- tag_delete = h("a.delete", {
- "href": "#Delete+plugin",
- onclick: _this.handleDeleteClick,
- "data-plugin": plugin
- }, "Delete plugin");
- }
- enabled_default = plugin.info["default"] === "enabled";
- if (plugin.enabled !== plugin.loaded || plugin.updated) {
- marker_title = "Change pending";
- is_pending = true;
- } else {
- marker_title = "Changed from default status (click to reset to " + plugin.info["default"] + ")";
- is_pending = false;
- }
- is_changed = plugin.enabled !== enabled_default && plugin.owner === "builtin";
- return h("div.plugin", {
- key: plugin.name
- }, [
- h("div.title", [h("h3", [plugin.name, tag_version]), h("div.description", [descr, tag_source, tag_delete])]), h("div.value.value-right", h("div.checkbox", {
- onclick: _this.handleCheckboxChange,
- "data-plugin": plugin,
- classes: {
- checked: plugin.enabled
- }
- }, h("div.checkbox-skin")), h("a.marker", {
- href: "#Reset",
- title: marker_title,
- onclick: _this.handleResetClick,
- "data-plugin": plugin,
- classes: {
- visible: is_pending || is_changed,
- pending: is_pending
- }
- }, "\u2022"))
- ]);
- };
- })(this)));
- };
- return PluginList;
- })(Class);
- window.PluginList = PluginList;
- }).call(this);
- /* ---- UiPluginManager.coffee ---- */
- (function() {
- var UiPluginManager,
- bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
- extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
- hasProp = {}.hasOwnProperty;
- window.h = maquette.h;
- UiPluginManager = (function(superClass) {
- extend(UiPluginManager, superClass);
- function UiPluginManager() {
- this.renderBottomRestart = bind(this.renderBottomRestart, this);
- this.handleRestartClick = bind(this.handleRestartClick, this);
- this.render = bind(this.render, this);
- this.createProjector = bind(this.createProjector, this);
- this.updatePlugins = bind(this.updatePlugins, this);
- this.onOpenWebsocket = bind(this.onOpenWebsocket, this);
- return UiPluginManager.__super__.constructor.apply(this, arguments);
- }
- UiPluginManager.prototype.init = function() {
- this.plugin_list_builtin = new PluginList();
- this.plugin_list_custom = new PluginList();
- this.plugins_changed = null;
- this.need_restart = null;
- return this;
- };
- UiPluginManager.prototype.onOpenWebsocket = function() {
- this.cmd("wrapperSetTitle", "Plugin manager - ZeroNet");
- this.cmd("serverInfo", {}, (function(_this) {
- return function(server_info) {
- return _this.server_info = server_info;
- };
- })(this));
- return this.updatePlugins();
- };
- UiPluginManager.prototype.updatePlugins = function(cb) {
- return this.cmd("pluginList", [], (function(_this) {
- return function(res) {
- var item, plugins_builtin, plugins_custom;
- _this.plugins_changed = (function() {
- var i, len, ref, results;
- ref = res.plugins;
- results = [];
- for (i = 0, len = ref.length; i < len; i++) {
- item = ref[i];
- if (item.enabled !== item.loaded || item.updated) {
- results.push(item);
- }
- }
- return results;
- })();
- plugins_builtin = (function() {
- var i, len, ref, results;
- ref = res.plugins;
- results = [];
- for (i = 0, len = ref.length; i < len; i++) {
- item = ref[i];
- if (item.source === "builtin") {
- results.push(item);
- }
- }
- return results;
- })();
- _this.plugin_list_builtin.plugins = plugins_builtin.sort(function(a, b) {
- return a.name.localeCompare(b.name);
- });
- plugins_custom = (function() {
- var i, len, ref, results;
- ref = res.plugins;
- results = [];
- for (i = 0, len = ref.length; i < len; i++) {
- item = ref[i];
- if (item.source !== "builtin") {
- results.push(item);
- }
- }
- return results;
- })();
- _this.plugin_list_custom.plugins = plugins_custom.sort(function(a, b) {
- return a.name.localeCompare(b.name);
- });
- _this.projector.scheduleRender();
- return typeof cb === "function" ? cb() : void 0;
- };
- })(this));
- };
- UiPluginManager.prototype.createProjector = function() {
- this.projector = maquette.createProjector();
- this.projector.replace($("#content"), this.render);
- return this.projector.replace($("#bottom-restart"), this.renderBottomRestart);
- };
- UiPluginManager.prototype.render = function() {
- var ref;
- if (!this.plugin_list_builtin.plugins) {
- return h("div.content");
- }
- return h("div.content", [h("div.section", [((ref = this.plugin_list_custom.plugins) != null ? ref.length : void 0) ? [h("h2", "Installed third-party plugins"), this.plugin_list_custom.render()] : void 0, h("h2", "Built-in plugins"), this.plugin_list_builtin.render()])]);
- };
- UiPluginManager.prototype.handleRestartClick = function() {
- this.restart_loading = true;
- setTimeout(((function(_this) {
- return function() {
- return Page.cmd("serverShutdown", {
- restart: true
- });
- };
- })(this)), 300);
- Page.projector.scheduleRender();
- return false;
- };
- UiPluginManager.prototype.renderBottomRestart = function() {
- var ref;
- return h("div.bottom.bottom-restart", {
- classes: {
- visible: (ref = this.plugins_changed) != null ? ref.length : void 0
- }
- }, h("div.bottom-content", [
- h("div.title", "Some plugins status has been changed"), h("a.button.button-submit.button-restart", {
- href: "#Restart",
- classes: {
- loading: this.restart_loading
- },
- onclick: this.handleRestartClick
- }, "Restart ZeroNet client")
- ]));
- };
- return UiPluginManager;
- })(ZeroFrame);
- window.Page = new UiPluginManager();
- window.Page.createProjector();
- }).call(this);
|