/* * Copyright (C) 2015 Actor LLC. <https://actor.im> */ package im.actor.runtime.js.threading; import com.google.gwt.core.client.JavaScriptObject; /** * setInterval/setTimeout implementation * that work in background tabs */ public class JsSecureInterval extends JavaScriptObject { public static native JsSecureInterval create(boolean allowWorkers, Runnable runnable)/*-{ console.warn("Create jsSecureInterval") try { if (allowWorkers && typeof(Worker) !== "undefined") { var code = "var timerId;\n" + "\n" + "self.addEventListener('message', function(e){\n" + " switch (e.data.message) {\n" + " case 'schedule':\n" + " if (timerId) {\n" + " clearTimeout(timerId);\n" + " timerId = null;\n" + " }\n" + " timerId = setTimeout(function(){\n" + " self.postMessage('doSchedule');\n" + " }, e.data.delay);\n" + " break;\n" + " case 'cancel':\n" + " if (timerId) {\n" + " clearTimeout(timerId);\n" + " timerId = null;\n" + " }\n" + " break;\n" + " };\n" + "});\n" var codeBlob = new Blob([code]); var codeBlobURL = window.URL.createObjectURL(codeBlob); var worker = new Worker(codeBlobURL); var _runnable = runnable; worker.addEventListener('error', function() { console.warn("Worker error") }, false); worker.onmessage = function() { _runnable.@java.lang.Runnable::run()(); }; return {runnable: runnable, useWebWorker: true, worker: worker}; } } catch (e) { // Ignore } return {runnable: runnable, useWebWorker: false}; }-*/; protected JsSecureInterval() { } public final void scheduleNow() { schedule(0); } public native final void schedule(int msec)/*-{ if (this.useWebWorker) { this.worker.postMessage({message: "schedule", delay: msec}); } else { if (this.timerId) { clearTimeout(this.timerId); this.timerId = null; } var _runnable = this.runnable this.timerId = setTimeout(function() { _runnable.@java.lang.Runnable::run()(); }, msec); } }-*/; public native final void cancel()/*-{ if (this.useWebWorker) { this.worker.postMessage({message: "cancel"}); } else { if (this.timerId) { clearTimeout(this.timerId); this.timerId = null; } } }-*/; }