From 7ffec405aa274469099c8b646d5a1998a2e9a24c Mon Sep 17 00:00:00 2001 From: Erik Gustafsson Date: Mon, 19 Sep 2016 19:06:00 +0200 Subject: [PATCH 1/7] Added FileManager for offline use --- examples/full.html | 1 + js/FileManager.js | 156 +++++++++++++++++++++++++++++++++++++++++++++ js/RibbonPanel.js | 4 +- js/SharedJS.js | 15 +++++ 4 files changed, 174 insertions(+), 2 deletions(-) create mode 100644 js/FileManager.js diff --git a/examples/full.html b/examples/full.html index c2605a96..25de1190 100644 --- a/examples/full.html +++ b/examples/full.html @@ -117,6 +117,7 @@ + diff --git a/js/FileManager.js b/js/FileManager.js new file mode 100644 index 00000000..6aeb6a72 --- /dev/null +++ b/js/FileManager.js @@ -0,0 +1,156 @@ +var InsightMakerFileExtension = ".InsightMaker"; + +// Append file extension to file (if not already there) +function append_file_extension(filename,extension) { + var extension_position=filename.length-extension.length; + var current_extension=filename.substring(extension_position,filename.length); + if(current_extension.toLowerCase()!=extension.toLowerCase()) { + filename+=extension; + } + return filename; +} + +// Set the title to include the model name +function set_title(filename) { + var title; + if(filename!=null) { + title = filename+"|InsightMaker"; + + } else { + title = "InsightMaker"; + } + window.parent.document.title = title; +} + +// Get xml data for the current model +function get_model_xml() { + var enc = new mxCodec(); + var graph_dom=enc.encode(graph.getModel()); + var xml_data=""+graph_dom.innerHTML+""; + return xml_data; +} + +// Makes a new model +function newModel() { + clearModel(); +} + +// Class for uploading and downloading files from javascript +var WebFileIO = new function() { + var upload_handler; + function readfile(event) { + var file = event.target.files[0]; + + if (file) { + var reader = new FileReader(); + reader.onload = function(reader_event) { + var filedata = reader_event.target.result; + upload_handler(file.name, filedata); + } + reader.readAsText(file); + } + } + + this.upload = function(tupload_handler, accepttype) { + var uploader = document.body.appendChild(document.createElement("input")); + uploader.addEventListener('change', readfile, false); + uploader.type="file"; + if(accepttype!==undefined) { + // accepttype is file extension that we should show + // E.g. ".txt" + // If none is specified all file extensions are shown + uploader.accept=accepttype; + } + upload_handler = tupload_handler; + + uploader.click(); + uploader.parentElement.removeChild(uploader); + }; + + this.download = function(filename, content) { + var downloadlink = document.body.appendChild(document.createElement("a")); + downloadlink.download = filename; + + downloadlink.href = "data:text/plain;base64," + btoa(content); + downloadlink.click(); + downloadlink.parentElement.removeChild(downloadlink); + }; +} + +// High-level File manager. Does save and load of models +var FileManagerWeb = new function() { + var self = this; + var filename = null; + + this.set_filename = function(filename) { + self.filename=filename; + set_title(filename); + } + + this.saveModel = function() { + var xml_data = get_model_xml(); + + + + var model_name=prompt("Enter name of model"); + if(model_name==null) { + return; + } + model_name=append_file_extension(model_name,InsightMakerFileExtension); + self.set_filename(model_name); + WebFileIO.download(model_name,xml_data); + }; + + this.loadModel = function() { + WebFileIO.upload(function(filename,model_data) { + importMXGraph(model_data); + self.set_filename(filename); + },InsightMakerFileExtension); + }; + + this.newModel = function() { + self.set_filename(null); + newModel(); + } +}; + +// FileMenu for environment.WebOffline +var FileMenuWeb = { +text: getText('File'), +itemId: "filegroup", +glyph: 0xf15b, +menu: [ + { + glyph: 0xf016, + text: getText('New'), + tooltip: getText('New model'), + handler: FileManagerWeb.newModel, + scope: this + }, + { + glyph: 0xf115, /*0xf115 alternative icon we could have used */ + text: getText('Load'), + tooltip: getText('Load model'), + handler: FileManagerWeb.loadModel, + scope: this + }, + { + glyph: 0xf0c7, + text: getText('Save'), + tooltip: getText('Save model'), + handler: FileManagerWeb.saveModel, + scope: this + } +] +}; + +// Get the correct FileMenu depending on the environment +var FileMenu; +switch(viewConfig.environment) { + case environment.InsightMakerOnline: + FileMenu = []; + break; + case environment.WebOffline: + FileMenu = [FileMenuWeb]; + break; +} diff --git a/js/RibbonPanel.js b/js/RibbonPanel.js index a2aeebe5..05778e51 100755 --- a/js/RibbonPanel.js +++ b/js/RibbonPanel.js @@ -1087,7 +1087,7 @@ var RibbonPanel = function(graph, mainPanel, configPanel) { collapsible: false, tbar: new Ext.toolbar.Toolbar({ enableOverflow: true, - items: [ + items: FileMenu.concat([ { hidden: (!viewConfig.primitiveGroup), @@ -1641,7 +1641,7 @@ var RibbonPanel = function(graph, mainPanel, configPanel) { } - ] + ]) }) }); diff --git a/js/SharedJS.js b/js/SharedJS.js index 861494e6..9aebe7c1 100755 --- a/js/SharedJS.js +++ b/js/SharedJS.js @@ -8,7 +8,22 @@ terms of the Insight Maker Public License (https://InsightMaker.com/impl). */ +var environment = { + InsightMakerOnline: 1, + WebOffline: 2, + NodeWebKit: 3 /* Not yet implmented. Suggestion for future */ +} + +function environmentAutoDetect() { + if(location.hostname.match("insightmaker.com")!=null) { + return environment.InsightMakerOnline; + } else { + return environment.WebOffline; + } +} + var viewConfig = { + environment: environmentAutoDetect(), showTopLinks: true, sideBarWidth: 330, referenceBarWidth: 240, From 1ba60c8d8473ac78d9bfc69200979938b0a69c3a Mon Sep 17 00:00:00 2001 From: Erik Gustafsson Date: Tue, 20 Sep 2016 11:21:30 +0200 Subject: [PATCH 2/7] Corrected title field --- js/FileManager.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/FileManager.js b/js/FileManager.js index 6aeb6a72..31a837bb 100644 --- a/js/FileManager.js +++ b/js/FileManager.js @@ -14,7 +14,7 @@ function append_file_extension(filename,extension) { function set_title(filename) { var title; if(filename!=null) { - title = filename+"|InsightMaker"; + title = filename+"| Insight Maker"; } else { title = "InsightMaker"; From 188bf50032a84683f24d606d4557bab1936e769a Mon Sep 17 00:00:00 2001 From: Erik Gustafsson Date: Tue, 20 Sep 2016 11:22:21 +0200 Subject: [PATCH 3/7] More correction of title field --- js/FileManager.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/FileManager.js b/js/FileManager.js index 31a837bb..db938a3d 100644 --- a/js/FileManager.js +++ b/js/FileManager.js @@ -17,7 +17,7 @@ function set_title(filename) { title = filename+"| Insight Maker"; } else { - title = "InsightMaker"; + title = "Insight Maker"; } window.parent.document.title = title; } From fde69cd1c5d23f3fd8e44bd24b142c20340ea15f Mon Sep 17 00:00:00 2001 From: Erik Gustafsson Date: Wed, 21 Sep 2016 15:53:53 +0200 Subject: [PATCH 4/7] Changed to chamelCase and introduced slice in appendFileExtension --- js/FileManager.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/js/FileManager.js b/js/FileManager.js index db938a3d..4b1955a7 100644 --- a/js/FileManager.js +++ b/js/FileManager.js @@ -1,9 +1,9 @@ var InsightMakerFileExtension = ".InsightMaker"; // Append file extension to file (if not already there) -function append_file_extension(filename,extension) { +function appendFileExtension(filename,extension) { var extension_position=filename.length-extension.length; - var current_extension=filename.substring(extension_position,filename.length); + var current_extension=filename.slice(extension_position); if(current_extension.toLowerCase()!=extension.toLowerCase()) { filename+=extension; } @@ -11,7 +11,7 @@ function append_file_extension(filename,extension) { } // Set the title to include the model name -function set_title(filename) { +function setTitle(filename) { var title; if(filename!=null) { title = filename+"| Insight Maker"; @@ -23,7 +23,7 @@ function set_title(filename) { } // Get xml data for the current model -function get_model_xml() { +function getModelXML() { var enc = new mxCodec(); var graph_dom=enc.encode(graph.getModel()); var xml_data=""+graph_dom.innerHTML+""; @@ -84,11 +84,11 @@ var FileManagerWeb = new function() { this.set_filename = function(filename) { self.filename=filename; - set_title(filename); + setTitle(filename); } this.saveModel = function() { - var xml_data = get_model_xml(); + var xml_data = getModelXML(); @@ -96,7 +96,7 @@ var FileManagerWeb = new function() { if(model_name==null) { return; } - model_name=append_file_extension(model_name,InsightMakerFileExtension); + model_name=appendFileExtension(model_name,InsightMakerFileExtension); self.set_filename(model_name); WebFileIO.download(model_name,xml_data); }; From 62427bf48c899c1cefb0ad7d7e020ed227c7df89 Mon Sep 17 00:00:00 2001 From: Erik Gustafsson Date: Wed, 21 Sep 2016 16:11:42 +0200 Subject: [PATCH 5/7] Changed to extjs prompt --- js/FileManager.js | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/js/FileManager.js b/js/FileManager.js index 4b1955a7..228970d6 100644 --- a/js/FileManager.js +++ b/js/FileManager.js @@ -13,7 +13,7 @@ function appendFileExtension(filename,extension) { // Set the title to include the model name function setTitle(filename) { var title; - if(filename!=null) { + if(filename) { title = filename+"| Insight Maker"; } else { @@ -23,7 +23,7 @@ function setTitle(filename) { } // Get xml data for the current model -function getModelXML() { +function getModelXML2() { var enc = new mxCodec(); var graph_dom=enc.encode(graph.getModel()); var xml_data=""+graph_dom.innerHTML+""; @@ -70,7 +70,6 @@ var WebFileIO = new function() { this.download = function(filename, content) { var downloadlink = document.body.appendChild(document.createElement("a")); downloadlink.download = filename; - downloadlink.href = "data:text/plain;base64," + btoa(content); downloadlink.click(); downloadlink.parentElement.removeChild(downloadlink); @@ -88,17 +87,18 @@ var FileManagerWeb = new function() { } this.saveModel = function() { - var xml_data = getModelXML(); - + Ext.MessageBox.prompt('Model name', 'Enter name of model', function(btn, model_name){ + if(btn=='cancel') { + return; + } + if (btn == 'ok'){ + var xml_data = getModelXML2(); + model_name=appendFileExtension(model_name,InsightMakerFileExtension); + self.set_filename(model_name); + WebFileIO.download(model_name,xml_data); + } + }); - - var model_name=prompt("Enter name of model"); - if(model_name==null) { - return; - } - model_name=appendFileExtension(model_name,InsightMakerFileExtension); - self.set_filename(model_name); - WebFileIO.download(model_name,xml_data); }; this.loadModel = function() { From 2fc433c98ffb941989e518de6b8b6c32233cfc27 Mon Sep 17 00:00:00 2001 From: Erik Gustafsson Date: Wed, 21 Sep 2016 16:26:41 +0200 Subject: [PATCH 6/7] Made file loader use openFile --- js/FileManager.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/js/FileManager.js b/js/FileManager.js index 228970d6..020b35bf 100644 --- a/js/FileManager.js +++ b/js/FileManager.js @@ -102,10 +102,15 @@ var FileManagerWeb = new function() { }; this.loadModel = function() { - WebFileIO.upload(function(filename,model_data) { - importMXGraph(model_data); - self.set_filename(filename); - },InsightMakerFileExtension); + openFile({ + read: "text", + multiple: false, + accept: InsightMakerFileExtension, + onCompleted: function(model) { + importMXGraph(model.contents); + self.set_filename(model.name); + } + }); }; this.newModel = function() { From 78b2e727ad1a47cc15d0bf65e6002f00ad715044 Mon Sep 17 00:00:00 2001 From: Erik Gustafsson Date: Wed, 21 Sep 2016 16:34:24 +0200 Subject: [PATCH 7/7] Made the filemanager use downloadWebFile --- js/FileManager.js | 51 ++++++++++------------------------------------- 1 file changed, 10 insertions(+), 41 deletions(-) diff --git a/js/FileManager.js b/js/FileManager.js index 020b35bf..05bdb754 100644 --- a/js/FileManager.js +++ b/js/FileManager.js @@ -35,46 +35,15 @@ function newModel() { clearModel(); } -// Class for uploading and downloading files from javascript -var WebFileIO = new function() { - var upload_handler; - function readfile(event) { - var file = event.target.files[0]; - - if (file) { - var reader = new FileReader(); - reader.onload = function(reader_event) { - var filedata = reader_event.target.result; - upload_handler(file.name, filedata); - } - reader.readAsText(file); - } - } - - this.upload = function(tupload_handler, accepttype) { - var uploader = document.body.appendChild(document.createElement("input")); - uploader.addEventListener('change', readfile, false); - uploader.type="file"; - if(accepttype!==undefined) { - // accepttype is file extension that we should show - // E.g. ".txt" - // If none is specified all file extensions are shown - uploader.accept=accepttype; - } - upload_handler = tupload_handler; - - uploader.click(); - uploader.parentElement.removeChild(uploader); - }; - - this.download = function(filename, content) { - var downloadlink = document.body.appendChild(document.createElement("a")); - downloadlink.download = filename; - downloadlink.href = "data:text/plain;base64," + btoa(content); - downloadlink.click(); - downloadlink.parentElement.removeChild(downloadlink); - }; -} +function downloadWebFile(filename, content) { + // There is already a downloadFile in API.js + // But it does not appear to work in Firefox + var downloadlink = document.body.appendChild(document.createElement("a")); + downloadlink.download = filename; + downloadlink.href = "data:text/plain;base64," + btoa(content); + downloadlink.click(); + downloadlink.parentElement.removeChild(downloadlink); +}; // High-level File manager. Does save and load of models var FileManagerWeb = new function() { @@ -95,7 +64,7 @@ var FileManagerWeb = new function() { var xml_data = getModelXML2(); model_name=appendFileExtension(model_name,InsightMakerFileExtension); self.set_filename(model_name); - WebFileIO.download(model_name,xml_data); + downloadWebFile(model_name,xml_data); } });