diff options
Diffstat (limited to 'addon-sdk/source/lib/sdk/content/worker-child.js')
-rw-r--r-- | addon-sdk/source/lib/sdk/content/worker-child.js | 158 |
1 files changed, 0 insertions, 158 deletions
diff --git a/addon-sdk/source/lib/sdk/content/worker-child.js b/addon-sdk/source/lib/sdk/content/worker-child.js deleted file mode 100644 index dbf65a933..000000000 --- a/addon-sdk/source/lib/sdk/content/worker-child.js +++ /dev/null @@ -1,158 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -'use strict'; - -const { merge } = require('../util/object'); -const { Class } = require('../core/heritage'); -const { emit } = require('../event/core'); -const { EventTarget } = require('../event/target'); -const { getInnerId, getByInnerId } = require('../window/utils'); -const { instanceOf, isObject } = require('../lang/type'); -const system = require('../system/events'); -const { when } = require('../system/unload'); -const { WorkerSandbox } = require('./sandbox'); -const { Ci } = require('chrome'); -const { process, frames } = require('../remote/child'); - -const EVENTS = { - 'chrome-page-shown': 'pageshow', - 'content-page-shown': 'pageshow', - 'chrome-page-hidden': 'pagehide', - 'content-page-hidden': 'pagehide', - 'inner-window-destroyed': 'detach', -} - -// The parent Worker must have been created (or an async message sent to spawn -// its creation) before creating the WorkerChild or messages from the content -// script to the parent will get lost. -const WorkerChild = Class({ - implements: [EventTarget], - - initialize(options) { - merge(this, options); - keepAlive.set(this.id, this); - - this.windowId = getInnerId(this.window); - if (this.contentScriptOptions) - this.contentScriptOptions = JSON.parse(this.contentScriptOptions); - - this.port = EventTarget(); - this.port.on('*', this.send.bind(this, 'event')); - this.on('*', this.send.bind(this)); - - this.observe = this.observe.bind(this); - - for (let topic in EVENTS) - system.on(topic, this.observe); - - this.receive = this.receive.bind(this); - process.port.on('sdk/worker/message', this.receive); - - this.sandbox = WorkerSandbox(this, this.window); - - // If the document has an unexpected readyState, its worker-child instance is initialized - // as frozen until one of the known readyState is reached. - let initialDocumentReadyState = this.window.document.readyState; - this.frozen = [ - "loading", "interactive", "complete" - ].includes(initialDocumentReadyState) ? false : true; - - if (this.frozen) { - console.warn("SDK worker-child started as frozen on unexpected initial document.readyState", { - initialDocumentReadyState, windowLocation: this.window.location.href, - }); - } - - this.frozenMessages = []; - this.on('pageshow', () => { - this.frozen = false; - this.frozenMessages.forEach(args => this.sandbox.emit(...args)); - this.frozenMessages = []; - }); - this.on('pagehide', () => { - this.frozen = true; - }); - }, - - // messages - receive(process, id, args) { - if (id !== this.id) - return; - args = JSON.parse(args); - - if (this.frozen) - this.frozenMessages.push(args); - else - this.sandbox.emit(...args); - - if (args[0] === 'detach') - this.destroy(args[1]); - }, - - send(...args) { - process.port.emit('sdk/worker/event', this.id, JSON.stringify(args, exceptions)); - }, - - // notifications - observe({ type, subject }) { - if (!this.sandbox) - return; - - if (subject.defaultView && getInnerId(subject.defaultView) === this.windowId) { - this.sandbox.emitSync(EVENTS[type]); - emit(this, EVENTS[type]); - } - - if (type === 'inner-window-destroyed' && - subject.QueryInterface(Ci.nsISupportsPRUint64).data === this.windowId) { - this.destroy(); - } - }, - - get frame() { - return frames.getFrameForWindow(this.window.top); - }, - - // detach/destroy: unload and release the sandbox - destroy(reason) { - if (!this.sandbox) - return; - - for (let topic in EVENTS) - system.off(topic, this.observe); - process.port.off('sdk/worker/message', this.receive); - - this.sandbox.destroy(reason); - this.sandbox = null; - keepAlive.delete(this.id); - - this.send('detach'); - } -}) -exports.WorkerChild = WorkerChild; - -// Error instances JSON poorly -function exceptions(key, value) { - if (!isObject(value) || !instanceOf(value, Error)) - return value; - let _errorType = value.constructor.name; - let { message, fileName, lineNumber, stack, name } = value; - return { _errorType, message, fileName, lineNumber, stack, name }; -} - -// workers for windows in this tab -var keepAlive = new Map(); - -process.port.on('sdk/worker/create', (process, options, cpows) => { - options.window = cpows.window; - let worker = new WorkerChild(options); - - let frame = frames.getFrameForWindow(options.window.top); - frame.port.emit('sdk/worker/connect', options.id, options.window.location.href); -}); - -when(reason => { - for (let worker of keepAlive.values()) - worker.destroy(reason); -}); |