forked from mirrors/gecko-dev
105 lines
3.2 KiB
JavaScript
105 lines
3.2 KiB
JavaScript
/* 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';
|
|
|
|
module.metadata = {
|
|
'stability': 'unstable'
|
|
};
|
|
|
|
var { merge } = require('../util/object');
|
|
var { data } = require('../self');
|
|
var assetsURI = data.url();
|
|
var isArray = Array.isArray;
|
|
var method = require('../../method/core');
|
|
var { uuid } = require('../util/uuid');
|
|
|
|
const isAddonContent = ({ contentURL }) =>
|
|
contentURL && data.url(contentURL).startsWith(assetsURI);
|
|
|
|
exports.isAddonContent = isAddonContent;
|
|
|
|
function hasContentScript({ contentScript, contentScriptFile }) {
|
|
return (isArray(contentScript) ? contentScript.length > 0 :
|
|
!!contentScript) ||
|
|
(isArray(contentScriptFile) ? contentScriptFile.length > 0 :
|
|
!!contentScriptFile);
|
|
}
|
|
exports.hasContentScript = hasContentScript;
|
|
|
|
function requiresAddonGlobal(model) {
|
|
return model.injectInDocument || (isAddonContent(model) && !hasContentScript(model));
|
|
}
|
|
exports.requiresAddonGlobal = requiresAddonGlobal;
|
|
|
|
function getAttachEventType(model) {
|
|
if (!model) return null;
|
|
let when = model.contentScriptWhen;
|
|
return requiresAddonGlobal(model) ? 'document-element-inserted' :
|
|
when === 'start' ? 'document-element-inserted' :
|
|
when === 'ready' ? 'DOMContentLoaded' :
|
|
when === 'end' ? 'load' :
|
|
null;
|
|
}
|
|
exports.getAttachEventType = getAttachEventType;
|
|
|
|
var attach = method('worker-attach');
|
|
exports.attach = attach;
|
|
|
|
var connect = method('worker-connect');
|
|
exports.connect = connect;
|
|
|
|
var detach = method('worker-detach');
|
|
exports.detach = detach;
|
|
|
|
var destroy = method('worker-destroy');
|
|
exports.destroy = destroy;
|
|
|
|
function WorkerHost (workerFor) {
|
|
// Define worker properties that just proxy to underlying worker
|
|
return ['postMessage', 'port', 'url', 'tab'].reduce(function(proto, name) {
|
|
// Use descriptor properties instead so we can call
|
|
// the worker function in the context of the worker so we
|
|
// don't have to create new functions with `fn.bind(worker)`
|
|
let descriptorProp = {
|
|
value: function (...args) {
|
|
let worker = workerFor(this);
|
|
return worker[name].apply(worker, args);
|
|
}
|
|
};
|
|
|
|
let accessorProp = {
|
|
get: function () { return workerFor(this)[name]; },
|
|
set: function (value) { workerFor(this)[name] = value; }
|
|
};
|
|
|
|
Object.defineProperty(proto, name, merge({
|
|
enumerable: true,
|
|
configurable: false,
|
|
}, isDescriptor(name) ? descriptorProp : accessorProp));
|
|
return proto;
|
|
}, {});
|
|
|
|
function isDescriptor (prop) {
|
|
return ~['postMessage'].indexOf(prop);
|
|
}
|
|
}
|
|
exports.WorkerHost = WorkerHost;
|
|
|
|
function makeChildOptions(options) {
|
|
function makeStringArray(arrayOrValue) {
|
|
if (!arrayOrValue)
|
|
return [];
|
|
return [].concat(arrayOrValue).map(String);
|
|
}
|
|
|
|
return {
|
|
id: String(uuid()),
|
|
contentScript: makeStringArray(options.contentScript),
|
|
contentScriptFile: makeStringArray(options.contentScriptFile),
|
|
contentScriptOptions: options.contentScriptOptions ?
|
|
JSON.stringify(options.contentScriptOptions) :
|
|
null,
|
|
}
|
|
}
|
|
exports.makeChildOptions = makeChildOptions;
|