Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Rewrote lzma.js to not fake web workers and pollute the global scope.

  • Loading branch information...
commit 93ae581d2c9eebb5c5a1a80db68d6fb80b77ef7b 1 parent 5047b72
@nmrugg authored
Showing with 125 additions and 116 deletions.
  1. +125 −116 src/lzma.js
View
241 src/lzma.js
@@ -1,131 +1,140 @@
/// This code is licensed under the MIT License. See LICENSE for more details.
-/// Does the environment support web workers? If not, let's fake it.
-///NOTE: Since web workers don't work when a page is loaded from the local system, we have to fake it there too. (Take that security measures!)
-if (!Worker || (location && location.protocol === "file:")) {
- ///NOTE: IE8 and IE9 needs onmessage to be created first, IE7- do not care.
- ///NOTE: Because IE9 implements part of the Web Worker's spec, postMessage() must be overwritten.
- /*@cc_on
- var onmessage = function () {};
- var postMessage = function () {};
- @*/
-
- /// If this were a regular function statement, IE9 would run it first and therefore make the Worker variable truthy because of hoisting.
- var Worker = function(script) {
- var global_var,
- return_object = {};
-
- /// Determine the global variable (it's called "window" in browsers, "global" in Node.js).
- if (typeof window !== "undefined") {
- global_var = window;
- } else if (global) {
- global_var = global;
+/// Does the environment support web workers? If not, let's load the worker manually (without polluting the global scope).
+if (typeof Worker === "undefined" || (typeof location !== "undefined" && location.protocol === "file:")) {
+ /// Is this Node.js?
+ if (typeof global !== "undefined" && typeof require !== "undefined") {
+ this.LZMA = function (lzma_path) {
+ return require(lzma_path || "./lzma_worker.js").LZMA;
}
-
- /// Is the environment is browser?
- /// If not, create a require() function, if it doesn't have one.
- if (global_var.document && !global_var.require) {
- global_var.require = function (path) {
- var script_tag = document.createElement("script");
- script_tag.type ="text/javascript";
- script_tag.src = path;
- document.getElementsByTagName("head")[0].appendChild(script_tag);
+ /// Is this a browser?
+ } else if (typeof window !== "undefined" && window.document) {
+ (function ()
+ {
+ var that = this,
+ global_var,
+ req = function req(path) {
+ var script_tag = document.createElement("script");
+ script_tag.type ="text/javascript";
+ script_tag.src = path;
+ script_tag.onload = function () {
+ /// Make sure this LZMA variable doesn't get overwritten by the worker's.
+ that.LZMA = non_worker_lzma;
+ };
+ document.getElementsByTagName("head")[0].appendChild(script_tag);
+ };
+
+ /// Determine the global variable (it's called "window" in browsers, "global" in Node.js).
+ if (typeof window !== "undefined") {
+ global_var = window;
+ } else if (global) {
+ global_var = global;
+ }
+
+ function non_worker_lzma(path)
+ {
+ var fake_lzma;
+
+ req(path);
+
+ fake_lzma = {
+ compress: function compress(string, mode, on_finish, on_progress) {
+ if (global_var.LZMA_WORKER) {
+ global_var.LZMA_WORKER.compress(string, mode, on_finish, on_progress);
+ } else {
+ /// Wait
+ setTimeout(function ()
+ {
+ fake_lzma.compress(string, mode, on_finish, on_progress);
+ }, 50);
+ }
+ },
+ decompress: function decompress(byte_arr, on_finish, on_progress) {
+ if (global_var.LZMA_WORKER) {
+ global_var.LZMA_WORKER.decompress(byte_arr, on_finish, on_progress);
+ } else {
+ /// Wait
+ setTimeout(function ()
+ {
+ fake_lzma.decompress(byte_arr, on_finish, on_progress);
+ }, 50);
+ }
+ }
+ };
+
+ return fake_lzma;
};
- }
-
- /// Dummy onmessage() function.
- return_object.onmessage = function () {};
+
+ that.LZMA = non_worker_lzma;
+ }());
+ } else {
+ /// It doesn't seem to be either Node.js or a browser.
+ console.log("Can't load the worker. Sorry.");
+ }
+} else {
+ /// Let's use Web Workers.
+ ///NOTE: The "this" keyword is the global context ("window" variable) if loaded via a <script> tag
+ /// or the function context if loaded as a module (e.g., in Node.js).
+ this.LZMA = function (lzma_path) {
+ var action_compress = 1,
+ action_decompress = 2,
+ action_progress = 3,
+
+ callback_obj = {},
+
+ ///NOTE: Node.js needs something like "./" or "../" at the beginning.
+ lzma_worker = new Worker(lzma_path || "./lzma_worker.js");
- /// This is the function that the main script calls to post a message to the "worker."
- return_object.postMessage = function (message) {
- /// Has the worker script loaded yet?
- if (global_var.onmessage) {
- /// Call the global onmessage() created by the "worker."
- ///NOTE: Wrap the message in an object.
- global_var.onmessage({data: message});
+ lzma_worker.onmessage = function (e) {
+ if (e.data.action === action_progress) {
+ if (callback_obj[e.data.callback_num] && typeof callback_obj[e.data.callback_num].on_progress === "function") {
+ callback_obj[e.data.callback_num].on_progress(e.data.result);
+ }
} else {
- /// Since the script has not yet loaded, wait a moment, and then retry.
- setTimeout(function () {
- return_object.postMessage(message);
- }, 50);
+ if (callback_obj[e.data.callback_num] && typeof callback_obj[e.data.callback_num].on_finish === "function") {
+ callback_obj[e.data.callback_num].on_finish(e.data.result);
+
+ /// Since the (de)compression is complete, the callbacks are no longer needed.
+ delete callback_obj[e.data.callback_num];
+ }
}
};
- /// Create a global postMessage() function for the "worker" to call.
- global_var.postMessage = function (e) {
- ///NOTE: Wrap the message in an object.
- ///TODO: Add more properties.
- return_object.onmessage({data: e, type: "message"});
+ /// Very simple error handling.
+ lzma_worker.onerror = function(event) {
+ throw new Error(event.message + " (" + event.filename + ":" + event.lineno + ")");
};
- require(script);
-
- return return_object;
- };
-}
-
-
-///NOTE: The "this" keyword is the global context ("window" variable) if loaded via a <script> tag
-/// or the function context if loaded as a module (e.g., in Node.js).
-this.LZMA = function (lzma_path) {
- var action_compress = 1,
- action_decompress = 2,
- action_progress = 3,
-
- callback_obj = {},
-
- ///NOTE: Node.js needs something like "./" or "../" at the beginning.
- lzma_worker = new Worker((typeof lzma_path === "undefined" ? "./lzma_worker.js" : lzma_path));
-
- lzma_worker.onmessage = function (e) {
- if (e.data.action === action_progress) {
- if (callback_obj[e.data.callback_num] && typeof callback_obj[e.data.callback_num].on_progress === "function") {
- callback_obj[e.data.callback_num].on_progress(e.data.result);
- }
- } else {
- if (callback_obj[e.data.callback_num] && typeof callback_obj[e.data.callback_num].on_finish === "function") {
- callback_obj[e.data.callback_num].on_finish(e.data.result);
+ return (function () {
+
+ function send_to_worker(action, data, mode, on_finish, on_progress) {
+ var callback_num;
+
+ do {
+ callback_num = Math.floor(Math.random() * (10000000));
+ } while(typeof callback_obj[callback_num] !== "undefined");
- /// Since the (de)compression is complete, the callbacks are no longer needed.
- delete callback_obj[e.data.callback_num];
+ callback_obj[callback_num] = {
+ on_finish: on_finish,
+ on_progress: on_progress
+ };
+
+ lzma_worker.postMessage({
+ action: action,
+ callback_num: callback_num,
+ data: data,
+ mode: mode
+ });
}
- }
- };
-
- /// Very simple error handling.
- lzma_worker.onerror = function(event) {
- throw new Error(event.message + " (" + event.filename + ":" + event.lineno + ")");
- };
-
- return (function () {
-
- function send_to_worker(action, data, mode, on_finish, on_progress) {
- var callback_num;
-
- do {
- callback_num = Math.floor(Math.random() * (10000000));
- } while(typeof callback_obj[callback_num] !== "undefined");
- callback_obj[callback_num] = {
- on_finish: on_finish,
- on_progress: on_progress
+ return {
+ compress: function compress(string, mode, on_finish, on_progress) {
+ send_to_worker(action_compress, String(string), mode, on_finish, on_progress);
+ },
+ decompress: function decompress(byte_arr, on_finish, on_progress) {
+ send_to_worker(action_decompress, byte_arr, false, on_finish, on_progress);
+ }
};
-
- lzma_worker.postMessage({
- action: action,
- callback_num: callback_num,
- data: data,
- mode: mode
- });
- }
-
- return {
- compress: function (string, mode, on_finish, on_progress) {
- send_to_worker(action_compress, String(string), mode, on_finish, on_progress);
- },
- decompress: function (byte_arr, on_finish, on_progress) {
- send_to_worker(action_decompress, byte_arr, false, on_finish, on_progress);
- }
- };
- }());
-};
+ }());
+ };
+}
Please sign in to comment.
Something went wrong with that request. Please try again.