| 
									
										
										
										
											2018-03-25 20:52:38 -04:00
										 |  |  | //import messagingService from './messaging.js';
 | 
					
						
							|  |  |  | //import ScriptContext from './script_context.js';
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | function reloadApp() { | 
					
						
							|  |  |  |     window.location.reload(true); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function showMessage(message) { | 
					
						
							|  |  |  |     console.log(now(), "message: ", message); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $.notify({ | 
					
						
							|  |  |  |         // options
 | 
					
						
							|  |  |  |         message: message | 
					
						
							|  |  |  |     }, { | 
					
						
							|  |  |  |         // settings
 | 
					
						
							|  |  |  |         type: 'success', | 
					
						
							|  |  |  |         delay: 3000 | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function showError(message, delay = 10000) { | 
					
						
							|  |  |  |     console.log(now(), "error: ", message); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $.notify({ | 
					
						
							|  |  |  |         // options
 | 
					
						
							|  |  |  |         message: message | 
					
						
							|  |  |  |     }, { | 
					
						
							|  |  |  |         // settings
 | 
					
						
							|  |  |  |         type: 'danger', | 
					
						
							|  |  |  |         delay: delay | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function throwError(message) { | 
					
						
							| 
									
										
										
										
											2018-03-25 13:41:29 -04:00
										 |  |  |     messagingService.logError(message); | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     throw new Error(message); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function parseDate(str) { | 
					
						
							|  |  |  |     try { | 
					
						
							|  |  |  |         return new Date(Date.parse(str)); | 
					
						
							| 
									
										
										
										
											2018-03-24 23:37:55 -04:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  |     catch (e) { | 
					
						
							|  |  |  |         throw new Error("Can't parse date from " + str + ": " + e.stack); | 
					
						
							| 
									
										
										
										
											2018-03-24 23:37:55 -04:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2018-03-24 23:37:55 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  | function padNum(num) { | 
					
						
							|  |  |  |     return (num <= 9 ? "0" : "") + num; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2018-03-24 23:37:55 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  | function formatTime(date) { | 
					
						
							|  |  |  |     return padNum(date.getHours()) + ":" + padNum(date.getMinutes()); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2018-03-24 23:37:55 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  | function formatTimeWithSeconds(date) { | 
					
						
							|  |  |  |     return padNum(date.getHours()) + ":" + padNum(date.getMinutes()) + ":" + padNum(date.getSeconds()); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2017-12-23 11:02:38 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  | function formatDate(date) { | 
					
						
							|  |  |  |     return padNum(date.getDate()) + ". " + padNum(date.getMonth() + 1) + ". " + date.getFullYear(); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2017-12-23 12:19:15 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  | function formatDateISO(date) { | 
					
						
							|  |  |  |     return date.getFullYear() + "-" + padNum(date.getMonth() + 1) + "-" + padNum(date.getDate()); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2017-12-23 12:19:15 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  | function formatDateTime(date) { | 
					
						
							|  |  |  |     return formatDate(date) + " " + formatTime(date); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2017-12-28 19:00:31 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  | function now() { | 
					
						
							|  |  |  |     return formatTimeWithSeconds(new Date()); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2018-01-22 23:18:08 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  | function isElectron() { | 
					
						
							|  |  |  |     return window && window.process && window.process.type; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2018-01-25 23:49:03 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  | function assertArguments() { | 
					
						
							|  |  |  |     for (const i in arguments) { | 
					
						
							|  |  |  |         if (!arguments[i]) { | 
					
						
							|  |  |  |             throwError(`Argument idx#${i} should not be falsy: ${arguments[i]}`); | 
					
						
							| 
									
										
										
										
											2018-03-24 23:37:55 -04:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2018-03-06 23:04:35 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  | function assert(expr, message) { | 
					
						
							|  |  |  |     if (!expr) { | 
					
						
							|  |  |  |         throwError(message); | 
					
						
							| 
									
										
										
										
											2018-03-24 23:37:55 -04:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2018-02-04 20:23:30 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  | function isTopLevelNode(node) { | 
					
						
							|  |  |  |     return isRootNode(node.getParent()); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2018-03-24 23:37:55 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  | function isRootNode(node) { | 
					
						
							|  |  |  |     return node.key === "root_1"; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2018-03-24 23:37:55 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  | function escapeHtml(str) { | 
					
						
							|  |  |  |     return $('<div/>').text(str).html(); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2018-03-24 23:37:55 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  | async function stopWatch(what, func) { | 
					
						
							|  |  |  |     const start = new Date(); | 
					
						
							| 
									
										
										
										
											2018-03-24 23:37:55 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  |     const ret = await func(); | 
					
						
							| 
									
										
										
										
											2018-02-04 20:23:30 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  |     const tookMs = new Date().getTime() - start.getTime(); | 
					
						
							| 
									
										
										
										
											2018-02-04 20:23:30 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  |     console.log(`${what} took ${tookMs}ms`); | 
					
						
							| 
									
										
										
										
											2018-02-04 20:23:30 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  |     return ret; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2018-02-19 22:02:03 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  | async function executeBundle(bundle) { | 
					
						
							|  |  |  |     const apiContext = ScriptContext(bundle.note, bundle.allNotes); | 
					
						
							| 
									
										
										
										
											2018-02-19 22:02:03 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  |     return await (function () { | 
					
						
							|  |  |  |         return eval(`const apiContext = this; (async function() { ${bundle.script}\r\n})()`); | 
					
						
							|  |  |  |     }.call(apiContext)); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2018-02-20 23:24:55 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  | function formatValueWithWhitespace(val) { | 
					
						
							|  |  |  |     return /[^\w_-]/.test(val) ? '"' + val + '"' : val; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2018-02-21 20:30:15 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  | function formatLabel(attr) { | 
					
						
							|  |  |  |     let str = "@" + formatValueWithWhitespace(attr.name); | 
					
						
							| 
									
										
										
										
											2018-03-24 23:37:55 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  |     if (attr.value !== "") { | 
					
						
							|  |  |  |         str += "=" + formatValueWithWhitespace(attr.value); | 
					
						
							| 
									
										
										
										
											2018-02-19 22:02:03 -05:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  |     return str; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const CKEDITOR = {"js": ["libraries/ckeditor/ckeditor.js"]}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const CODE_MIRROR = { | 
					
						
							|  |  |  |     js: [ | 
					
						
							|  |  |  |         "libraries/codemirror/codemirror.js", | 
					
						
							|  |  |  |         "libraries/codemirror/addon/mode/loadmode.js", | 
					
						
							|  |  |  |         "libraries/codemirror/addon/fold/xml-fold.js", | 
					
						
							|  |  |  |         "libraries/codemirror/addon/edit/matchbrackets.js", | 
					
						
							|  |  |  |         "libraries/codemirror/addon/edit/matchtags.js", | 
					
						
							|  |  |  |         "libraries/codemirror/addon/search/match-highlighter.js", | 
					
						
							|  |  |  |         "libraries/codemirror/mode/meta.js", | 
					
						
							|  |  |  |         "libraries/codemirror/addon/lint/lint.js", | 
					
						
							|  |  |  |         "libraries/codemirror/addon/lint/eslint.js" | 
					
						
							|  |  |  |     ], | 
					
						
							|  |  |  |     css: [ | 
					
						
							|  |  |  |         "libraries/codemirror/codemirror.css", | 
					
						
							|  |  |  |         "libraries/codemirror/addon/lint/lint.css" | 
					
						
							|  |  |  |     ] | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const ESLINT = {js: ["libraries/eslint.js"]}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | async function requireLibrary(library) { | 
					
						
							|  |  |  |     if (library.css) { | 
					
						
							|  |  |  |         library.css.map(cssUrl => requireCss(cssUrl)); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-03-24 23:37:55 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  |     if (library.js) { | 
					
						
							|  |  |  |         for (const scriptUrl of library.js) { | 
					
						
							|  |  |  |             await requireScript(scriptUrl); | 
					
						
							| 
									
										
										
										
											2018-02-19 22:02:03 -05:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2018-02-19 22:02:03 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  | const dynamicallyLoadedScripts = []; | 
					
						
							| 
									
										
										
										
											2018-02-21 20:30:15 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  | async function requireScript(url) { | 
					
						
							|  |  |  |     if (!dynamicallyLoadedScripts.includes(url)) { | 
					
						
							|  |  |  |         dynamicallyLoadedScripts.push(url); | 
					
						
							| 
									
										
										
										
											2018-02-19 22:02:03 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  |         return await $.ajax({ | 
					
						
							|  |  |  |             url: url, | 
					
						
							|  |  |  |             dataType: "script", | 
					
						
							|  |  |  |             cache: true | 
					
						
							|  |  |  |         }) | 
					
						
							| 
									
										
										
										
											2018-02-19 22:02:03 -05:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2018-02-19 22:02:03 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  | async function requireCss(url) { | 
					
						
							|  |  |  |     const css = Array | 
					
						
							| 
									
										
										
										
											2018-03-25 20:52:38 -04:00
										 |  |  |         .from(document.querySelectorAll('link')) | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  |         .map(scr => scr.href); | 
					
						
							| 
									
										
										
										
											2018-02-19 22:02:03 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  |     if (!css.includes(url)) { | 
					
						
							|  |  |  |         $('head').append($('<link rel="stylesheet" type="text/css" />').attr('href', url)); | 
					
						
							| 
									
										
										
										
											2018-02-19 22:02:03 -05:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2018-02-25 10:55:21 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  | function getHost() { | 
					
						
							|  |  |  |     const url = new URL(window.location.href); | 
					
						
							|  |  |  |     return url.protocol + "//" + url.hostname + ":" + url.port; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2018-02-25 10:55:21 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  | function download(url) { | 
					
						
							|  |  |  |     if (isElectron()) { | 
					
						
							|  |  |  |         const remote = require('electron').remote; | 
					
						
							| 
									
										
										
										
											2018-02-25 10:55:21 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  |         remote.getCurrentWebContents().downloadURL(url); | 
					
						
							| 
									
										
										
										
											2018-02-25 10:55:21 -05:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  |     else { | 
					
						
							|  |  |  |         window.location.href = url; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2018-03-04 23:28:26 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  | function toObject(array, fn) { | 
					
						
							|  |  |  |     const obj = {}; | 
					
						
							| 
									
										
										
										
											2018-03-04 23:28:26 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  |     for (const item of array) { | 
					
						
							|  |  |  |         const ret = fn(item); | 
					
						
							| 
									
										
										
										
											2018-03-24 23:37:55 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  |         obj[ret[0]] = ret[1]; | 
					
						
							| 
									
										
										
										
											2018-03-04 23:28:26 -05:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  |     return obj; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2018-03-12 23:27:21 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  | function randomString(len) { | 
					
						
							|  |  |  |     let text = ""; | 
					
						
							|  |  |  |     const possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; | 
					
						
							| 
									
										
										
										
											2018-03-12 23:27:21 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  |     for (let i = 0; i < len; i++) { | 
					
						
							|  |  |  |         text += possible.charAt(Math.floor(Math.random() * possible.length)); | 
					
						
							| 
									
										
										
										
											2018-03-12 23:27:21 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  |     return text; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 19:49:33 -04:00
										 |  |  | function bindShortcut(keyboardShortcut, handler) { | 
					
						
							|  |  |  |     $(document).bind('keydown', keyboardShortcut, e => { | 
					
						
							|  |  |  |         handler(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         e.preventDefault(); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  | export default { | 
					
						
							|  |  |  |     reloadApp, | 
					
						
							|  |  |  |     showMessage, | 
					
						
							|  |  |  |     showError, | 
					
						
							|  |  |  |     throwError, | 
					
						
							|  |  |  |     parseDate, | 
					
						
							|  |  |  |     padNum, | 
					
						
							|  |  |  |     formatTime, | 
					
						
							|  |  |  |     formatTimeWithSeconds, | 
					
						
							|  |  |  |     formatDate, | 
					
						
							|  |  |  |     formatDateISO, | 
					
						
							|  |  |  |     formatDateTime, | 
					
						
							|  |  |  |     now, | 
					
						
							|  |  |  |     isElectron, | 
					
						
							|  |  |  |     assertArguments, | 
					
						
							|  |  |  |     assert, | 
					
						
							|  |  |  |     isTopLevelNode, | 
					
						
							|  |  |  |     isRootNode, | 
					
						
							|  |  |  |     escapeHtml, | 
					
						
							|  |  |  |     stopWatch, | 
					
						
							|  |  |  |     executeBundle, | 
					
						
							|  |  |  |     formatValueWithWhitespace, | 
					
						
							|  |  |  |     formatLabel, | 
					
						
							|  |  |  |     requireLibrary, | 
					
						
							|  |  |  |     CKEDITOR, | 
					
						
							|  |  |  |     CODE_MIRROR, | 
					
						
							|  |  |  |     ESLINT, | 
					
						
							|  |  |  |     getHost, | 
					
						
							|  |  |  |     download, | 
					
						
							|  |  |  |     toObject, | 
					
						
							| 
									
										
										
										
											2018-03-25 19:49:33 -04:00
										 |  |  |     randomString, | 
					
						
							|  |  |  |     bindShortcut | 
					
						
							| 
									
										
										
										
											2018-03-25 11:09:17 -04:00
										 |  |  | }; |