- 1 :
/**
- 2 :
* A helper for working with the Voyant Notebook app.
- 3 :
* @memberof Spyral
- 4 :
*/
- 5 :
class Notebook {
- 6 :
- 7 :
/**
- 8 :
*
- 9 :
* @param {*} contents
- 10 :
* @param {*} config
- 11 :
* @static
- 12 :
*/
- 13 :
static show(contents, config) {
- 14 :
var contents = Spyral.Util.toString(contents);
- 15 :
if (contents instanceof Promise) {
- 16 :
contents.then(c => Spyral.Util.show(c))
- 17 :
} else {
- 18 :
Spyral.Util.show(contents);
- 19 :
}
- 20 :
}
- 21 :
/**
- 22 :
* Returns the first DIV element that's a child of the document body. If none exists then one will be created.
- 23 :
* @returns {element}
- 24 :
* @static
- 25 :
*/
- 26 :
static getTarget() {
- 27 :
if (document.body.firstElementChild !== null && document.body.firstElementChild.nodeName === 'DIV') {
- 28 :
return document.body.firstElementChild
- 29 :
}
- 30 :
const target = document.createElement("div");
- 31 :
document.body.appendChild(target);
- 32 :
return target;
- 33 :
}
- 34 :
- 35 :
/**
- 36 :
* Returns a new promise
- 37 :
* @returns {Promise} A promise
- 38 :
* @static
- 39 :
*/
- 40 :
static getPromise() {
- 41 :
return new Promise();
- 42 :
}
- 43 :
- 44 :
/**
- 45 :
* Fetch and return the content of a notebook or a particular cell in a notebook
- 46 :
* @param {string} url The URL of the notebook to import
- 47 :
* @param {number} [cellIndex] The index of the cell to import
- 48 :
* @static
- 49 :
*/
- 50 :
static async import(url, cellIndex=undefined) {
- 51 :
const urlHasHash = url.indexOf('#') !== -1;
- 52 :
const isAbsoluteUrl = url.indexOf('http') === 0;
- 53 :
- 54 :
let notebookId = '';
- 55 :
let cellId = undefined;
- 56 :
if (isAbsoluteUrl) {
- 57 :
const urlParts = url.match(/\/[\w-]+/g);
- 58 :
if (urlParts !== null) {
- 59 :
notebookId = urlParts[urlParts.length-1].replace('/', '');
- 60 :
} else {
- 61 :
return;
- 62 :
}
- 63 :
if (urlHasHash) {
- 64 :
cellId = url.split('#')[1];
- 65 :
}
- 66 :
} else {
- 67 :
if (urlHasHash) {
- 68 :
[notebookId, cellId] = url.split('#');
- 69 :
} else {
- 70 :
notebookId = url;
- 71 :
}
- 72 :
}
- 73 :
- 74 :
let json;
- 75 :
try {
- 76 :
json = await Spyral.Load.trombone({
- 77 :
tool: 'notebook.GitNotebookManager',
- 78 :
action: 'load',
- 79 :
id: notebookId,
- 80 :
noCache: 1
- 81 :
})
- 82 :
} catch (e) {
- 83 :
throw new Error('There was an error importing the notebook. Please ensure the URL and ID are correct.');
- 84 :
}
- 85 :
- 86 :
const notebook = JSON.parse(json.notebook.data);
- 87 :
- 88 :
function getCodeStringForDataCell(dataCellContent) {
- 89 :
let code = '';
- 90 :
switch(dataCellContent.mode) {
- 91 :
case 'text':
- 92 :
code = dataCellContent.dataName+'=`'+dataCellContent.input+'`';
- 93 :
break;
- 94 :
case 'json':
- 95 :
code = dataCellContent.dataName+'= JSON.parse(`'+dataCellContent.input+'`)';
- 96 :
break;
- 97 :
case 'xml':
- 98 :
code = dataCellContent.dataName+'= new DOMParser().parseFromString(`'+dataCellContent.input+'`, "application/xml")';
- 99 :
break;
- 100 :
case 'html':
- 101 :
code = dataCellContent.dataName+'= new DOMParser().parseFromString(`'+dataCellContent.input+'`, "application/xml")';
- 102 :
break;
- 103 :
}
- 104 :
return code;
- 105 :
}
- 106 :
- 107 :
const cells2import = notebook.cells.filter((cell, index) => {
- 108 :
if (cell.type === 'code' || cell.type === 'data') {
- 109 :
if (cellId === undefined && cellIndex === undefined) {
- 110 :
return true;
- 111 :
} else if (cell.cellId === cellId) {
- 112 :
return true;
- 113 :
} else if (cellIndex !== undefined && cellIndex === index+1) { // the index shown notebook counter is one-based
- 114 :
return true;
- 115 :
}
- 116 :
}
- 117 :
});
- 118 :
- 119 :
const importedCode = cells2import.map((cell) => {
- 120 :
if (cell.type === 'data') {
- 121 :
return getCodeStringForDataCell(cell.content);
- 122 :
} else {
- 123 :
return cell.content.input;
- 124 :
}
- 125 :
})
- 126 :
- 127 :
console.log('imported:', importedCode);
- 128 :
- 129 :
async function __doRun(code) {
- 130 :
// console.log('running:',code);
- 131 :
try {
- 132 :
const result = eval.call(window, code);
- 133 :
const prResult = await Promise.resolve(result);
- 134 :
if (importedCode.length > 0) {
- 135 :
return __doRun(importedCode.shift());
- 136 :
} else {
- 137 :
return prResult;
- 138 :
}
- 139 :
} catch(e) {
- 140 :
throw new Error('There was an error importing the notebook: '+e.message);
- 141 :
}
- 142 :
}
- 143 :
- 144 :
if (importedCode.length > 0) {
- 145 :
return __doRun(importedCode.shift());
- 146 :
} else {
- 147 :
throw new Error('There was an error importing the notebook. No code found for the specified '+ (cellId === undefined && cellIndex === undefined ? 'notebook' : 'cell')+'.');
- 148 :
}
- 149 :
}
- 150 :
}
- 151 :
- 152 :
export default Notebook