WebApps with LocalStorage and AppCache/Load

In this learning step we will consider the package LoadFile4DOM that creates a Load Dialog to load files into browser. Basic WebApps are created for this learning resource to see the basic workflow as example.

Basic AppLSAC with Browser as Runtime Environment
AppLSAC-1: WebApp is loaded from Server - Data is loaded into the browser from local filesystem, processed in browser and stored results again on local storage - NO processing of data on the remote server.
AppLSAC-2: A HTML file with Javascript is loaded from the local file system and not from a remote server. AppLSAC on level 2 has two privacy friendly aspects. Data is processed locally and HTML/Javascript WebApp is loaded from local filesystem.
Screenshot of Demo Loader in LoadFile4DOM WebApp, that loads files with LoadFile4DOM and creates a ZIP with JSZip and stores the file with FileSaver
LOAD DATA: Demos LoadFile4DOM

Demos on GitLab are created for this learning resource. This learning resource is based on the Open Community Approach.

Basic Concept for Load Dialogs for WebApps edit

  • (Analogy - Load in Desktop Applications) In standard desktop application like LibreOffice users are able to load files and process/edit the document. LoadFile4DOM does the same for WebApps and loads data (e.g. text files) into the browser runtime environment for processing or editing with the WebApp (which is defined by HTML, CSS and Javascript-Code). LoadFile4DOM provides Load Dialog and programmers define withn onload handlers, what to do with the uploaded file (see example).
  • (Processing) Processing is the core task that will be performed within the browser (and not on a remote server).
  • (File Access to Local Filesystem) For security reason browsers are not allowed to access the local file system. On the other hand sending user data to a remote server can be avoided by processing the data in the browser without submitting the data to a remote server.a first example, in which users can load a textfile into textarea.you have the text in the textarea you can process the content in the browser and show the results to the user in the textarea.

The library was designed to used in a browser (WebApp). So use the installation for your browser by using a bundle dist/loadfile4dom.js (see example https://niehausbert.gitlab.io/loadfile4dom).

History of Learning Resource edit

LoadFile4DOM is a library that is created especially for this learning resource and allows to load files into an application that run completely in a browser without the need to submit data to a server for processing. With this library the users are able load files into your browser application and process the data in the browser and provide the output to the user, without submitting any data to a server.

Learning Task edit

Installation edit

Use a Git ZIP file with Demos edit

For this learning resource some demos with different load methods was collected in a Git repository for you to play with (see LoadFile4DOM Demo Repository[1]. If you want to test them offline in your browser and desktop computer just download the ZIP File open the file

Installation for Browsers edit

If you want to use the library loadfile4dom.js in a browser, please copy the file dist/loadfile4dom.js into your library folder of WebApp that you want to test with a browser (e.g. js/loadfile4dom.js). If you want expand existing examples check the basic example in docs/index.html first and play around with that HTML-file. If you want to import the library with script-tag do it in the standard way with:

<script src="js/loadfile4dom.js"></script>

Now it is possible to use the constructor of LoadFile4DOM

var  lf4d = new LoadFile4DOM();

Now we define a hash that contains the options for the init()-call.

var vOptions = {
  'debug': false
};
lf4d.init(doccument, vOptions);

After the init() call the loaders are defined (see section about Usage). debug=true shows the holder and the <input type="file" ...> elements in the browser view of the HTML page. Default settings is false.

Keep in mind that injection of the Load Dialogs must be performed when the document was loaded, so we need to call the create() method when the onload event was triggered by the browser. This is done by:

<body onload="lf4d.create()">

NodeJS - Update LoadFile4DOM with new Features edit

This sections is for developers that want to extend or modify the features of LoadFile4DOM. Assume that you want to provide a ZIP handler with the loader type zip.

Assume you want to expand the file handler for zip-files to return a JSZip instance instead of the raw binary of the zip-file. So we update the method handle_myzip().

  • (required) installed NodeJS on your computer,
  • (required) installed git on your computer,
  • create a new repository e.g. on GitLab with the NPM name loadfile4myzip in the package.json,
  • clone the new git repository to you local computer with git clone [url] as version you work on. If your username is itsme and the new repository name will be loadfile4myzip the git call for GitLab will be:
    git clone https://gitlab.com/itsme/loadfile4myzip.git
  • install LoadFile4DOM in Node NPM use the following NPM call: npm install loadfile4dom --save.
    // require all the modules you need for the new browserified library ...
    const JSZip = require('jszip');
    const  LoadFile4MyZIP = require('loadfile4dom');
    LoadFile4MyZIP.prototype.handle_myzip = function (...) {
      // write a new ZIP file handler e.g. using JSZip
      //
    }
    
    //... export the Javascript class
    module.exports = LoadFile4MyZIP
    

If you use the extended module you need to browserify your new module.

Due to the fact that the library was designed for WebApps that run a regular browser, the library requires Document Object Model (DOM) to create a dialog for loading files in a browser as runtime environment for an AppLSAC. If you want to create a ElectronJS application with the same code base, replace the LoadFile4DOM module by file dialogs provide by ElectronJS.

NodeJS Testing Library LoadFile4DOM with JSDom edit

In order to test new feature we require in test-script the library jsdom.

To test and expand the Library with additional feature we create in test-scripts like tests/test.js as a DOM content. Wit jsdom module we can analyse if the library properly inject the required HTML elements into the DOM of browser without for testing the modification of the code with the HTML file docs/index.html and an appropriate script-tag <script src="js/loadfile4dom.js"></script> in the browser.

The following code shows the test script tests/test.js that can be executed with node tests/test.js of with npm run buildtest.

// emulate the DOM with 'jsdom'
const jsdom = require('jsdom');
const { JSDOM } = jsdom;

const  LoadFile4DOM = require('../src/main.js');
let  lf4d = new LoadFile4DOM();
// define options for LoadFile4DOM holder in the DOM

We need to feed a DOM content, that LoadFile4DOM works with. The sample DOM tree in the test script tests/test.js was defined as. Modify the content according to your test settings.

const vDOM = new JSDOM(`<!DOCTYPE html>
<html>
  <body>
    <textarea id="mytxtfile" row="5" cols="80"></textarea>
    <div id="myloaderid" style="display:none">
    </div>
  <body>
</html>`);
// create a reference for the window.document
let doc = vDOM.window.document;

Now we have an emulated DOM with the reference to the document object, that allows the test the DOM element injection.

let vOptions = {
  'id4loadfile': 'myloaderid',
  'debug': true
};
lf4d.init(doc, vOptions)
  • (optional) 'debug':true shows the injected <input type='file' ...> that are injected into the DOM tree by LoadFile4DOM.
  • (optional) 'id4loadfile': 'myloaderid' the ID of the div element to which the all loaders (e.g. for text, images, json, zip are injected.
  • All loaders are created by one instance of LoadFile4DOM to assure a conflict free ID management of generated <input type='file' ...> elements in the DOM.
  • if you have an iframe in your DOM it has an own document object. You might want to create another instance for injecting loaders in the iFrame document as well.

Remark: Keep in mind that you should create an instance of LoadFile4DOM every different document object you are injecting Load Dialog to. In general one instance should be sufficient in most use-cases for LoadFile4DOM.

Quick Start for Library-Users edit

See LoadFile4DOM demos and download the loadfile4dom.zip from GitLab[3]. Just copy the docs/-folder, rename the folder to name of your choice (e.g. myloadfile4dom) and adapt the examples to your needs.

Usage edit

You can have one or more LoadFile4DOM nodes in your webbased application. The following code shows how to create LoadFile4DOM node

var lf4d = new LoadFile4DOM();
var options = {
  "id4loadfile": "allmyloaddialogs"
};
lf4d.init(document,options);
var txtfile = lf4dom.get_options("mytxtfile","text");
// set the onload handler for the loaded files
txtfile.onload = function (data,err) {
  if (err) {
    console.error(err);
  } else {
    // do something with the file content in data e.g. store  in a HTML textarea (e.g. <textarea id="mytextarea" ...>
    document.getElementById("mytextarea").value = data;
  }
}
lf4d.create_load_dialog(txtfile);

The Load Dialogs are created with the onload event handler in the body tag of your HTML file.

   <body onload="lf4d.create()">

Now you can define an onclick event in a button to open the load menu similar to the upload feature of web sites.

<input type="button" onclick="lf4d.open_dialog('mytxtfile')" value="Load TXT File">

or with a button-tag with

<button onclick="lf4d.open_dialog('myhtmlfile')"> Load HTML File</button>

Furthermore you can open the menu with an onclick event on a link by

This is a <a href="#" onclick="lf4d.open_dialog('myhtmlfile')">link to open the menu</a> in a HTML file.

Wikiversity edit

This piece of software was created on GitLab as support material for the learning resource about privacy-friendly webbased applications AppLSAC](https://en.wikiversity.org/wiki/AppLSAC) on Wikiversity. An AppLSAC run completely in the browser without the need to submit any user generated data to a server. This package LoadFile4DOM is designed to learn about the first step:

  • (Load) Load File into a browser for processing with an HTML5-WebApp (AppLSAC-1 or AppLSAC-2). The library LoadFile4DOM serves to cover the loading feature.
  • (Process) Processing data can be done with any Javascript-libraries of your choice that can perform its task without submission of user generated data to a remote server. HandleBars4Code processes a JSON as input (UML for Javascript) to generate the JavaScript library or the README.md documentation for a package.
  • (Save) If users want to save the processed results, it is recommended to look at the FileSaver.js library provided by Eli Grey.

Build Process of npm run build edit

The build process is called by npm run build which in turn call build.js. If you want to call the build process of build.js separately just call build.js with node build.js from the shell/console.

The templates for building the output are stored in the folder src/.

After the build process the README.md is generated and if you want to have the table of contents in the file for the concatenation of files in src/readme/ listed in files4build.js then you must run the DocToc generator for README.md by doctoc README.md from the shell to update the table of contents in README.md.

Define Filename for build in package.json edit

In package.json defines the filename for the automated build for * README.md for readme for the repository (parts in src/readme), * index.html for the web demo (parts in src/html), * main.css for the style sheet (part in src/css) and * ./src/main.js is generated from the parts in src/libs the sources in src/. To specify these filenames add the following build section to the package.json:

"build": {
  "readme": "README.md",
  "html": "docs/index.html",
  "css": "docs/css/main.css"
}

If you want to edit the generated file check the files that are selected for including into the generated files (see files4build.js) and set the files to a preliminary build name (e.g. like index_build.html instead of index.html to compare generated file index_build.html with the older version index.html for debugging

Browserify after Build edit

After building (concat the file parts) and replacement of package variables (e.g. like _``__PKG_NAME__``_ for package name) in the generated documents the module is browserified by the command

 browserify ./src/main.js  > dist/loadfile4dom.js

This command is called and defined in the script section of the package.json.

API for LoadFile4DOM edit

The documentation for API of LoadFile4DOM is provided on GitLab.

Acknowledgement edit

Special thanks to the following individual developers and teams of OpenSource JavaScript projects:

  • HandleBars the code generation in Javascript was implemented
  • JSON-Editor by Jeremy Dorn. The JSON Editor takes a JSON Schema and uses it to generate an HTML form. The JSON-Editor is partially used to edit JSON file of the JavascriptClassCreator Project JSCC. The JSON-Editor of Jeremy Dorn has full support for JSON Schema version 3 and 4 and can integrate with several popular CSS frameworks (bootstrap, foundation, and jQueryUI). This would lead to major code reduction of JSCC . Refactoring of JSCC would make more use of the JSON-Editor features. Check out an interactive demo (demo.html): http://jeremydorn.com/json-editor/
  • Developer Mihai Bazon create UglifyJS, a great tool to handle and parse Javascript Code and minify the Javascript code (see Source Code of UglifyJS).
  • The wrapper for UglifyJS is written Dan Wolff. His UglifyJS-Online example is used to minify/compress the exported Javascript code of generated JS Classes (For Online Example of the UglifyJS-Wrapper see source code on https://github.com/Skalman/UglifyJS-online for the Online-Version of the Wrapper.
  • Developers of ACE Code Editor https://ace.c9.io (Javascript Editing uses the Editor)
  • FileSaver.js Developer Eli Grey provided the FileSaver.js that is used to store created JSCC files to the local filesystem. JSCC uses the same mechanism of browsers, that allows a Save as... in the context menu of a web pages or image. So not uncontrolled write access to your file system is implemented, because users have to select the locations in which the user whats to store the file (e.g. JSON, Javascript or HTML).
  • JointJS JointJS is a JavaScript diagramming library. It can be used to create either static diagrams. JointJS is used in this project to create UML-diagrams, that are interactive diagramming in conjunction and application builder in Javascript.
  • Inheritage for JavaScript with protoypes by Gavin Kistner
  • 3 ways to define a JavaScript class by Stoyan Stefanov
  • JQuery is used for the theme and standard operations in the Document Object Model (DOM) of HTML-pages. The JQuery-Themeroller was used to create a JQuery theme for JSCC.

Libraries required for LoadFile4DOM edit

The following libraries are necessary for loadfile4dom.js:

NPM Library Information edit

  • Exported Module Variable: LoadFile4DOM
  • Package: loadfile4dom
  • Homepage: https://gitlab.com/niehausbert/loadfile4dom#readme
  • License: MIT
  • Require Module with:

    const LoadFile4DOM = require('loadfile4dom');
    
  • JSHint: installation can be performed with npm install jshint -g

References edit

  1. 1.0 1.1 1.2 LoadFile4DOM Git Repository (2019) Git Repository for this learning resource - URL: https://www.gitlab.com/niehausbert/loadfile4dom (2021/10/05)
  2. 2.0 2.1 Demo Files LoadFile4DOM - GitHub Repository (2021) Git Repository with just the demo files for this learning resource without the node development environment - designed as intro to programming course for this learning resource - URL: https://www.github.com/niebert/loadfile4dom-demo (2021/10/05)
  3. Cite error: Invalid <ref> tag; no text was provided for refs named load1