Commit 1a16ef75 authored by Cédric Le Ninivin's avatar Cédric Le Ninivin

Reduce number of files needed

parent b96c6493
......@@ -37,7 +37,6 @@
0,
window.location.pathname.length - "gadget_jio_crib.html".length
) + "/";
console.log(gadget.state_parameter_dict.default_document);
this.state_parameter_dict.jio_storage = jIO.createJIO({
"type": "indexeddb",
"database": "ojs_source_code"
......@@ -77,8 +76,6 @@
.declareMethod('put', function (url, data_uri) {
var storage = this.state_parameter_dict.jio_storage;
data_uri = jIO.util.dataURItoBlob(data_uri);
console.log(this.state_parameter_dict.default_document);
console.log(url);
return storage.putAttachment(
this.state_parameter_dict.default_document,
url,
......@@ -87,10 +84,8 @@
})
.declareMethod('allDocs', function () {
var storage = this.state_parameter_dict.jio_storage;
console.log(this.state_parameter_dict.default_document);
return storage.allAttachments(this.state_parameter_dict.default_document)
.push(function(result) {
console.log(result);
return result;
})
})
......
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, user-scalable=no" />
<title>Crib SW interface Gadget</title>
<!-- renderjs -->
<script src="../lib/rsvp.js" type="text/javascript"></script>
<script src="../lib/renderjs.js" type="text/javascript"></script>
<script src="../lib/jio-latest.js" type="text/javascript"></script>
<!-- custom script -->
<script src="./crib-sw-gadget.js" type="text/javascript"></script>
</head>
<body>
<div class="storage-access" style="display:none;"></div>
</body>
</html>
\ No newline at end of file
/*global window, rJS, RSVP, Blob, console */
/*jslint indent: 2, maxerr: 3 */
(function (window, rJS, RSVP, jIO) {
"use strict";
function getStorageGadget(gadget) {
var storage_gadget, site_editor_gadget_url, getURL = window.location;
return gadget.getSetting(
"site_editor_gadget_url",
getURL.protocol + "//" + getURL.host + "/crib-enable.html"
)
.push(function (url) {
if (gadget.props.storage_gadget_url == url) {
return gadget.getDeclaredGadget("storage")
.push(undefined, function () {
return gadget.declareGadget(
url,
{
"scope": "storage",
"sandbox": "iframe",
"element": gadget.props.element.querySelector('div')
});
});
} else {
gadget.props.storage_gadget_url = url;
return gadget.dropGadget("storage")
.push(function () {}, function () {})
.push(function () {
return gadget.declareGadget(
url,
{
"scope": "storage",
"sandbox": "iframe",
"element": gadget.props.element.querySelector('div')
});
});
}
})
.push(undefined, function (e) {
// Ugly Hack to reload page and make service worker available
if (e &&
e.indexOf("Please reload this page to allow Service Worker to control this page") > -1) {
console.log("reload");
window.location.reload(false);
throw (e);
} else {
console.log(e);
throw (e);
}
});
}
rJS(window)
.ready(function (g) {
g.props = {};
return g.getElement()
.push(function (element) {
var getURL = window.location;
g.props.element = element;
});
})
.ready(function (gadget) {
// Initialize the gadget local parameters
gadget.state_parameter_dict = {};
return getStorageGadget(gadget);
})
.declareAcquiredMethod("getSetting", "getSetting")
.declareMethod('allDocs', function (params) {
return getStorageGadget(this)
.push(function (storage_gadget) {
return storage_gadget.allDocs(params);
});
})
.declareMethod('get', function (url) {
return getStorageGadget(this)
.push(function (storage_gadget) {
return storage_gadget.get(url);
})
.push(function (result) {
return jIO.util.dataURItoBlob(result);
});
})
.declareMethod('put', function (url, parameter) {
var blob, gadget = this;
if (parameter.blob !== undefined) {
blob = parameter.blob;
} else {
blob = new Blob(
[parameter.content],
{type: parameter.type}
);
}
return RSVP.Queue()
.push(function () {
return RSVP.all([
getStorageGadget(gadget),
jIO.util.readBlobAsDataURL(blob)
]);
})
.push(function (result_list) {
return result_list[0].put(url, result_list[1].target.result);
})
.push(console.log, console.log)
;
})
.declareMethod('remove', function (url) {
return getStorageGadget(this)
.push(function (storage_gadget) {
return storage_gadget.remove(url);
});
});
}(window, rJS, RSVP, jIO));
\ No newline at end of file
/*global window, RSVP, FileReader */
/*jslint indent: 2, maxerr: 3, unparam: true */
(function (window, RSVP, FileReader) {
"use strict";
window.loopEventListener = function (target, type, useCapture, callback,
prevent_default) {
//////////////////////////
// Infinite event listener (promise is never resolved)
// eventListener is removed when promise is cancelled/rejected
//////////////////////////
var handle_event_callback,
callback_promise;
if (prevent_default === undefined) {
prevent_default = true;
}
function cancelResolver() {
if ((callback_promise !== undefined) &&
(typeof callback_promise.cancel === "function")) {
callback_promise.cancel();
}
}
function canceller() {
if (handle_event_callback !== undefined) {
target.removeEventListener(type, handle_event_callback, useCapture);
}
cancelResolver();
}
function itsANonResolvableTrap(resolve, reject) {
var result;
handle_event_callback = function (evt) {
if (prevent_default) {
evt.stopPropagation();
evt.preventDefault();
}
cancelResolver();
try {
result = callback(evt);
} catch (e) {
result = RSVP.reject(e);
}
callback_promise = result;
new RSVP.Queue()
.push(function () {
return result;
})
.push(undefined, function (error) {
if (!(error instanceof RSVP.CancellationError)) {
canceller();
reject(error);
}
});
};
target.addEventListener(type, handle_event_callback, useCapture);
}
return new RSVP.Promise(itsANonResolvableTrap, canceller);
};
window.promiseEventListener = function (target, type, useCapture) {
//////////////////////////
// Resolve the promise as soon as the event is triggered
// eventListener is removed when promise is cancelled/resolved/rejected
//////////////////////////
var handle_event_callback;
function canceller() {
target.removeEventListener(type, handle_event_callback, useCapture);
}
function resolver(resolve) {
handle_event_callback = function (evt) {
canceller();
evt.stopPropagation();
evt.preventDefault();
resolve(evt);
return false;
};
target.addEventListener(type, handle_event_callback, useCapture);
}
return new RSVP.Promise(resolver, canceller);
};
window.promiseReadAsText = function (file) {
return new RSVP.Promise(function (resolve, reject) {
var reader = new FileReader();
reader.onload = function (evt) {
resolve(evt.target.result);
};
reader.onerror = function (evt) {
reject(evt);
};
reader.readAsText(file);
});
};
}(window, RSVP, FileReader));
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, user-scalable=no" />
<title>Jio Gadget</title>
<!-- renderjs -->
<script src="../lib/rsvp.js" type="text/javascript"></script>
<script src="../lib/renderjs.js" type="text/javascript"></script>
<script src="../lib/jio-latest.js" type="text/javascript"></script>
<!-- custom script -->
<script src="./gadget_jio.js" type="text/javascript"></script>
</head>
<body>
</body>
</html>
\ No newline at end of file
/*global window, rJS, jIO */
/*jslint indent: 2, maxerr: 3 */
(function (window, rJS, jIO) {
"use strict";
rJS(window)
.ready(function (gadget) {
// Initialize the gadget local parameters
gadget.state_parameter_dict = {};
})
.declareMethod('createJio', function (jio_options) {
this.state_parameter_dict.jio_storage = jIO.createJIO(jio_options);
})
.declareMethod('allDocs', function () {
var storage = this.state_parameter_dict.jio_storage;
return storage.allDocs.apply(storage, arguments);
})
.declareMethod('allAttachments', function () {
var storage = this.state_parameter_dict.jio_storage;
return storage.allAttachments.apply(storage, arguments);
})
.declareMethod('get', function () {
var storage = this.state_parameter_dict.jio_storage;
return storage.get.apply(storage, arguments);
})
.declareMethod('put', function () {
var storage = this.state_parameter_dict.jio_storage;
return storage.put.apply(storage, arguments);
})
.declareMethod('post', function () {
var storage = this.state_parameter_dict.jio_storage;
return storage.post.apply(storage, arguments);
})
.declareMethod('remove', function () {
var storage = this.state_parameter_dict.jio_storage;
return storage.remove.apply(storage, arguments);
})
.declareMethod('getAttachment', function () {
var storage = this.state_parameter_dict.jio_storage;
return storage.getAttachment.apply(storage, arguments);
})
.declareMethod('putAttachment', function () {
var storage = this.state_parameter_dict.jio_storage;
return storage.putAttachment.apply(storage, arguments);
})
.declareMethod('removeAttachment', function () {
var storage = this.state_parameter_dict.jio_storage;
return storage.removeAttachment.apply(storage, arguments);
})
.declareMethod('repair', function () {
var storage = this.state_parameter_dict.jio_storage;
return storage.repair.apply(storage, arguments);
});
}(window, rJS, jIO));
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width">
<title>CribJS Loader</title>
<script src="../lib/rsvp.js"></script>
<script src="../lib/renderjs.js"></script>
<script src="../lib/jszip.js" type="text/javascript"></script>
<script src="./gadget_landing_cribjs.js"></script>
</head>
<body>
<div data-gadget-url="./crib-sw-gadget.html"
data-gadget-scope="crib_sw_gadget"
data-gadget-sandbox="public"></div>
<div data-gadget-url="./gadget_jio.html"
data-gadget-scope="jio_gadget"
data-gadget-sandbox="public"></div>
</body>
</html>
\ No newline at end of file
/*jslint browser: true, indent: 2, maxlen: 80*/
/*globals RSVP, rJS,
location, console, fetch, Promise*/
(function (window, document, RSVP, rJS, location, console, JSZip) {
"use strict";
function getExtension(url) {
var extension = url.split('.').pop();
if (extension.endsWith('/')) {
return ".html";
}
return "." + extension;
}
function getSetting(gadget, key, default_value) {
if (key === "site_editor_gadget_url") {
return window.location.protocol + "//" + window.location.host +
"/crib-enable.html";
}
return default_value;
}
function loadZipIntoCrib(crib_sw_gadget, zip, from_path, path_to_load) {
var promise_list = [], url_number = 0,
site_url = window.location.protocol + "//" + window.location.host;
zip.forEach(function (relativePath, zipEntry) {
var end_url;
url_number += 1;
if (zipEntry.dir) {
return;
}
if (!relativePath.startsWith(from_path)) {
return;
}
relativePath = relativePath.substring(from_path.length);
console.log(relativePath);
if (relativePath.startsWith("/")) {
end_url = relativePath.substring(1);
} else {
end_url = relativePath;
}
promise_list.push(
new RSVP.Queue()
.push(function () {
return zipEntry.async('blob');
})
.push(function (result) {
if (end_url.endsWith(".js")) {
// This is a ugly hack as mimetype needs to be correct for JS
result = result.slice(0, result.size, "application/javascript");
} else if (end_url.endsWith(".html")) {
// This is a ugly hack as mimetype needs to be correct for JS
result = result.slice(0, result.size, "text/html");
} else if (end_url.endsWith(".css")) {
// This is a ugly hack as mimetype needs to be correct for JS
result = result.slice(0, result.size, "text/css");
}
return crib_sw_gadget.put(end_url, {blob: result});
})
);
});
return RSVP.all(promise_list);
}
function loadContentFromZIPFile(gadget, options) {
var path_to_load = options.to_path,
from_path = options.from_path,
file_list = options.file_list;
if (file_list.length === 0) {
return "No File to Load";
}
return new RSVP.Queue()
.push(function () {
return RSVP.all([
gadget.getDeclaredGadget('crib_sw_gadget'),
JSZip.loadAsync(file_list[0])
]);
})
.push(function (result_list) {
return loadZipIntoCrib(
result_list[0], result_list[1], from_path, path_to_load
);
})
.push(console.log, console.log);
}
function loadContentFromZIPURL(gadget, options) {
var path_to_load = options.to_path, file_list, crib_sw_gadget,
from_path = options.from_path, zip_url = options.zip_url,
jio_gadget, url_list = [], url_number = 0;
return new RSVP.Queue()
.push(function () {
return gadget.getDeclaredGadget('crib_sw_gadget');
})
.push(function (returned_gadget) {
crib_sw_gadget = returned_gadget;
return fetch(zip_url)
.then(function (response) { // 2) filter on 200 OK
if (response.status === 200 || response.status === 0) {
return Promise.resolve(response.blob());
} else {
return Promise.reject(new Error(response.statusText));
}
});
})
.push(JSZip.loadAsync)
.push(function (zip) {
return loadZipIntoCrib(crib_sw_gadget, zip, from_path, path_to_load);
})
.push(console.log, console.log);
}
rJS(window)
.ready(function (g) {
g.props = {};
})
.declareMethod('loadFromZipUrl', function (options) {
return loadContentFromZIPURL(this, options);
})
.declareMethod('loadFromZipFile', function (options) {
return loadContentFromZIPFile(this, options);
})
.allowPublicAcquisition("getSetting", function (argument_list) {
return getSetting(this, argument_list[0], argument_list[1]);
});
}(window, document, RSVP, rJS, location, console, JSZip));
\ No newline at end of file
/*globals window, document, RSVP, rJS, navigator, jIO, URL*/
/*jslint indent: 2, maxlen: 80, nomen: true*/
var repair = false;
(function (window, document, RSVP, rJS, jIO, navigator, URL) {
"use strict";
function createStorage(gadget) {
return jIO.createJIO({
type: "replicate",
parallel_operation_attachment_amount: 10,
parallel_operation_amount: 1,
conflict_handling: 2,
signature_hash_key: 'hash',
check_remote_attachment_modification: true,
check_remote_attachment_creation: true,
check_remote_attachment_deletion: true,
check_remote_deletion: true,
check_local_creation: false,
check_local_deletion: false,
check_local_modification: false,
signature_sub_storage: {
type: "query",
sub_storage: {
type: "indexeddb",
database: "officejs-hash"
}
},
local_sub_storage: {
type: "query",
sub_storage: {
type: "uuid",
sub_storage: {
type: "indexeddb",
database: "ojs_source_code"
}
}
},
remote_sub_storage: {
type: "appcache",
manifest: gadget.props.cache_file,
version: gadget.props.version_url,
take_installer: true
}
});
}
function waitForServiceWorkerActive(registration) {
var serviceWorker;
if (registration.installing) {
serviceWorker = registration.installing;
} else if (registration.waiting) {
serviceWorker = registration.waiting;
} else if (registration.active) {
serviceWorker = registration.active;
}
if (serviceWorker.state !== "activated") {
return RSVP.Promise(function (resolve, reject) {
serviceWorker.addEventListener('statechange', function (e) {
if (e.target.state === "activated") {
resolve();
}
});
RSVP.delay(500).then(function () {
reject(new Error("Timeout service worker install"));
});
});
}
}
rJS(window)
.setState({error_amount: 0})
.ready(function (gadget) {
var i,
element_list =
gadget.element.querySelectorAll('[data-install-configuration]');
gadget.props = {};
for (i = 0; i < element_list.length; i += 1) {
gadget.props[element_list[i].getAttribute(
'data-install-configuration'
)] = element_list[i].textContent;
}
gadget.props.redirect_url = new URL(window.location);
gadget.props.redirect_url.pathname += gadget.props.version_url;
if (gadget.props.redirect_url.hash) {
if (gadget.props.redirect_url.hash.startsWith('#access_token')) {
// This is a bad hack to support dropbox.
gadget.props.redirect_url.hash =
gadget.props.redirect_url.hash.replace(
'#access_token',
'#/?page=ojs_dropbox_configurator&access_token'
);
} else if (gadget.props.redirect_url.hash
.startsWith('#page=settings_configurator')) {
// Make monitoring app still compatible with old instances setup URLs
gadget.props.redirect_url.hash =
gadget.props.redirect_url.hash.replace(
'#page=settings_configurator',
'#/?page=settings_configurator'
);
}
}
})
.declareService(function () {
var gadget = this;
return RSVP.all([
new RSVP.Queue()
.push(function () {
return RSVP.delay(600);
})
.push(function () {
return gadget.changeState({
app_name: gadget.props.app_name,
redirect_url: gadget.props.redirect_url
});
}),
gadget.install()
.push(function () {
window.location.replace(gadget.props.redirect_url);
})
]);
})
.declareMethod('render', function (options) {
var gadget = this;
return new RSVP.Queue()
.push(function () {
var element = gadget.element.querySelector('.presentation');
if (element) {
return gadget.getDeclaredGadget('view');
}
element = document.createElement("div");
element.className = "presentation";
gadget.element.appendChild(element);
return gadget.declareGadget(
"gadget_officejs_bootloader_presentation.html",
{"scope": "view", "element": element}
);
})
.push(function (view_gadget) {
return view_gadget.render(options);
});
})
.onStateChange(function (modification_dict) {
return this.render(modification_dict);
})
.declareMethod("install", function () {
var gadget = this,
storage = createStorage(gadget);
if (navigator.serviceWorker !== undefined) {
return storage.repair()
.push(function () {
return navigator.serviceWorker.register(
"gadget_officejs_bootloader_serviceworker.js"
);
})
.push(function (registration) {
return waitForServiceWorkerActive(registration);
})
.push(undefined, function (error) {
return gadget.changeState({
error_amount: gadget.state.error_amount + 1,
error: error
})
.push(function () {
return RSVP.delay(1000);
})
.push(function () {
return gadget.install();
});
});
}
return;
});
}(window, document, RSVP, rJS, jIO, navigator, URL));
\ No newline at end of file
......@@ -6,79 +6,50 @@
<meta name="viewport" content="width=device-width">
<title>CribJS Loader</title>
<link rel="stylesheet" href="./lib/bootstrap/bootstrap.min.css">
<link rel="stylesheet" href="./landing.css">
<style>
.loader{
border: 16px solid #f3f3f3;
border-radius: 50%;
border-top: 16px solid #3498db;
width: 64px;
height: 64px;
z-index:9999;
animation: spin 1s linear infinite;
-webkit-animation: spin 1s linear infinite;
}
@-webkit-keyframes spin {
0% { -webkit-transform: rotate(0deg); }
100% { -webkit-transform: rotate(360deg); }
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
header{
background-color:#085078;
color: #f8fff3;
padding: 0.6em;
}
.main {
padding-top: 11%;
}
</style>
<script src="./lib/rsvp.js"></script>
<script src="./lib/renderjs.js"></script>
<script src="./gadget/gadget_global.js"></script>
<script src="./lib/jio-latest.js"></script>
<script src="./lib/jszip.js" type="text/javascript"></script>
<script src="./landing.js"></script>
</head>
<body>
<div data-gadget-url="./gadget/gadget_landing_cribjs.html"
data-gadget-scope="jio_cribjs"
data-gadget-sandbox="public"></div>
<div class="nav_content container">
<h1>CribJS Loader</h1>
<p>Load your Crib from here</p>
</div>
<div class="nav_content container">
<h3>Start Editing this Site</h3>
<a class="edit-url btn btn-primary" type="text" size="60" href="">Start Editing This Site Now</a>
</div>
<div class="nav_content container">
<form class="crib-load-from-zip-url form-inline">
<h3>Fill This site from a zip URL</h3>
<div class="form-group">
<label>Zip Url:
<input name="load-zip-url" class="load-zip-url form-control" type="text" size="60"></label>
</div>
<div class="form-group">
<label> Path in Zip:
<input name="load-from-zip-path" class="load-from-zip-path form-control" type="text" size="30" value="/">
</label>
</div>
<div class="form-group">
<label> to path:
<input name="load-zip-to-path" class="load-zip-to-path form-control" type="text" size="30" value="/">
</label>
</div>
<div class="form-group">
<label> And redirect to:
<input name="redirect-url" class="redirect-url form-control" type="text" size="30" value="">
</label>
</div>
<button name="load-zip-contents" class="load-zip-contents btn btn-default" type="submit">Import from URL</button>
</form>
</div>
<div class="nav_content container">
<div><span class="info crib-save-to-zip-status"></span></div>
<form class="crib-load-from-zip-file form-inline">
<h3>Import from zip File</h3>
<div class="form-group">
<label>Zip File:
<input name="load-zip-file" class="load-zip-file form-control" type="file" size="30"></label>
</div>
<div class="form-group">
<label> Path in Zip:
<input name="load-zip-path" class="load-from-zip-path form-control" type="text" size="30" value="/">
</label>
</div>
<div class="form-group">
<label> to path:
<input name="load-zip-to-path" class="load-zip-to-path form-control" type="text" size="30" value="/">
</label>
</div>
<div class="form-group">
<label> And redirect to:
<input name="redirect-url" class="redirect-url form-control" type="text" size="30" value="">
</label>
</div>
<button name="load-zip-contents" class="load-zip-contents btn btn-default" type="submit">Import from File</button>
</form>
</div>
<div class="nav_content container">
<p>You can check where it started, and start a crib from the beginning: <a href="jungle.html">The Jungle :)</a>. This one is a simple editor with no import/export functions. First challenge is to use that to add an import/export function :).</p>
<p>A simple editor can be found <a href="base.html">here</a></p>
<center>
<header> CribJS Bootloader </header>
<div class="main">
<!--img src="officejs_logo.png"-->
<div class="app-name"> Preparing</div>
<div class="loader"></div>
</div>
</center>
<div class="storage-access" style="display:none;"></div>
</body>
</html>
This diff is collapsed.
(function (global, factory) {
if (typeof define === "function" && define.amd) {
define([], factory);
} else if (typeof exports !== "undefined") {
factory();
} else {
var mod = {
exports: {}
};
factory();
global.FileSaver = mod.exports;
}
})(this, function () {
"use strict";
/*
* FileSaver.js
* A saveAs() FileSaver implementation.
*
* By Eli Grey, http://eligrey.com
*
* License : https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md (MIT)
* source : http://purl.eligrey.com/github/FileSaver.js
*/
// The one and only way of getting global scope in all environments
// https://stackoverflow.com/q/3277182/1008999
var _global = typeof window === 'object' && window.window === window ? window : typeof self === 'object' && self.self === self ? self : typeof global === 'object' && global.global === global ? global : void 0;
function bom(blob, opts) {
if (typeof opts === 'undefined') opts = {
autoBom: false
};else if (typeof opts !== 'object') {
console.warn('Deprecated: Expected third argument to be a object');
opts = {
autoBom: !opts
};
} // prepend BOM for UTF-8 XML and text/* types (including HTML)
// note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF
if (opts.autoBom && /^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) {
return new Blob([String.fromCharCode(0xFEFF), blob], {
type: blob.type
});
}
return blob;
}
function download(url, name, opts) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.responseType = 'blob';
xhr.onload = function () {
saveAs(xhr.response, name, opts);
};
xhr.onerror = function () {
console.error('could not download file');
};
xhr.send();
}
function corsEnabled(url) {
var xhr = new XMLHttpRequest(); // use sync to avoid popup blocker
xhr.open('HEAD', url, false);
try {
xhr.send();
} catch (e) {}
return xhr.status >= 200 && xhr.status <= 299;
} // `a.click()` doesn't work for all browsers (#465)
function click(node) {
try {
node.dispatchEvent(new MouseEvent('click'));
} catch (e) {
var evt = document.createEvent('MouseEvents');
evt.initMouseEvent('click', true, true, window, 0, 0, 0, 80, 20, false, false, false, false, 0, null);
node.dispatchEvent(evt);
}
} // Detect WebView inside a native macOS app by ruling out all browsers
// We just need to check for 'Safari' because all other browsers (besides Firefox) include that too
// https://www.whatismybrowser.com/guides/the-latest-user-agent/macos
var isMacOSWebView = /Macintosh/.test(navigator.userAgent) && /AppleWebKit/.test(navigator.userAgent) && !/Safari/.test(navigator.userAgent);
var saveAs = _global.saveAs || ( // probably in some web worker
typeof window !== 'object' || window !== _global ? function saveAs() {}
/* noop */
// Use download attribute first if possible (#193 Lumia mobile) unless this is a macOS WebView
: 'download' in HTMLAnchorElement.prototype && !isMacOSWebView ? function saveAs(blob, name, opts) {
var URL = _global.URL || _global.webkitURL;
var a = document.createElement('a');
name = name || blob.name || 'download';
a.download = name;
a.rel = 'noopener'; // tabnabbing
// TODO: detect chrome extensions & packaged apps
// a.target = '_blank'
if (typeof blob === 'string') {
// Support regular links
a.href = blob;
if (a.origin !== location.origin) {
corsEnabled(a.href) ? download(blob, name, opts) : click(a, a.target = '_blank');
} else {
click(a);
}
} else {
// Support blobs
a.href = URL.createObjectURL(blob);
setTimeout(function () {
URL.revokeObjectURL(a.href);
}, 4E4); // 40s
setTimeout(function () {
click(a);
}, 0);
}
} // Use msSaveOrOpenBlob as a second approach
: 'msSaveOrOpenBlob' in navigator ? function saveAs(blob, name, opts) {
name = name || blob.name || 'download';
if (typeof blob === 'string') {
if (corsEnabled(blob)) {
download(blob, name, opts);
} else {
var a = document.createElement('a');
a.href = blob;
a.target = '_blank';
setTimeout(function () {
click(a);
});
}
} else {
navigator.msSaveOrOpenBlob(bom(blob, opts), name);
}
} // Fallback to using FileReader and a popup
: function saveAs(blob, name, opts, popup) {
// Open a popup immediately do go around popup blocker
// Mostly only available on user interaction and the fileReader is async so...
popup = popup || open('', '_blank');
if (popup) {
popup.document.title = popup.document.body.innerText = 'downloading...';
}
if (typeof blob === 'string') return download(blob, name, opts);
var force = blob.type === 'application/octet-stream';
var isSafari = /constructor/i.test(_global.HTMLElement) || _global.safari;
var isChromeIOS = /CriOS\/[\d]+/.test(navigator.userAgent);
if ((isChromeIOS || force && isSafari || isMacOSWebView) && typeof FileReader !== 'undefined') {
// Safari doesn't allow downloading of blob URLs
var reader = new FileReader();
reader.onloadend = function () {
var url = reader.result;
url = isChromeIOS ? url : url.replace(/^data:[^;]*;/, 'data:attachment/file;');
if (popup) popup.location.href = url;else location = url;
popup = null; // reverse-tabnabbing #460
};
reader.readAsDataURL(blob);
} else {
var URL = _global.URL || _global.webkitURL;
var url = URL.createObjectURL(blob);
if (popup) popup.location = url;else location.href = url;
popup = null; // reverse-tabnabbing #460
setTimeout(function () {
URL.revokeObjectURL(url);
}, 4E4); // 40s
}
});
_global.saveAs = saveAs.saveAs = saveAs;
if (typeof module !== 'undefined') {
module.exports = saveAs;
}
});
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
/*global window, RSVP, FileReader */
/*jslint indent: 2, maxerr: 3, unparam: true */
(function (window, RSVP, FileReader) {
"use strict";
window.loopEventListener = function (target, type, useCapture, callback,
prevent_default) {
//////////////////////////
// Infinite event listener (promise is never resolved)
// eventListener is removed when promise is cancelled/rejected
//////////////////////////
var handle_event_callback,
callback_promise;
if (prevent_default === undefined) {
prevent_default = true;
}
function cancelResolver() {
if ((callback_promise !== undefined) &&
(typeof callback_promise.cancel === "function")) {
callback_promise.cancel();
}
}
function canceller() {
if (handle_event_callback !== undefined) {
target.removeEventListener(type, handle_event_callback, useCapture);
}
cancelResolver();
}
function itsANonResolvableTrap(resolve, reject) {
var result;
handle_event_callback = function (evt) {
if (prevent_default) {
evt.stopPropagation();
evt.preventDefault();
}
cancelResolver();
try {
result = callback(evt);
} catch (e) {
result = RSVP.reject(e);
}
callback_promise = result;
new RSVP.Queue()
.push(function () {
return result;
})
.push(undefined, function (error) {
if (!(error instanceof RSVP.CancellationError)) {
canceller();
reject(error);
}
});
};
target.addEventListener(type, handle_event_callback, useCapture);
}
return new RSVP.Promise(itsANonResolvableTrap, canceller);
};
window.promiseEventListener = function (target, type, useCapture) {
//////////////////////////
// Resolve the promise as soon as the event is triggered
// eventListener is removed when promise is cancelled/resolved/rejected
//////////////////////////
var handle_event_callback;
function canceller() {
target.removeEventListener(type, handle_event_callback, useCapture);
}
function resolver(resolve) {
handle_event_callback = function (evt) {
canceller();
evt.stopPropagation();
evt.preventDefault();
resolve(evt);
return false;
};
target.addEventListener(type, handle_event_callback, useCapture);
}
return new RSVP.Promise(resolver, canceller);
};
window.promiseReadAsText = function (file) {
return new RSVP.Promise(function (resolve, reject) {
var reader = new FileReader();
reader.onload = function (evt) {
resolve(evt.target.result);
};
reader.onerror = function (evt) {
reject(evt);
};
reader.readAsText(file);
});
};
}(window, RSVP, FileReader));
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment