Spaces:
Build error
Build error
File size: 3,635 Bytes
30c32c8 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
/* eslint-env worker */
const ScratchCommon = require('./tw-extension-api-common');
const createScratchX = require('./tw-scratchx-compatibility-layer');
const dispatch = require('../dispatch/worker-dispatch');
const log = require('../util/log');
const {isWorker} = require('./tw-extension-worker-context');
const createTranslate = require('./tw-l10n');
const translate = createTranslate(null);
const loadScripts = url => {
if (isWorker) {
importScripts(url);
} else {
return new Promise((resolve, reject) => {
const script = document.createElement('script');
script.onload = () => resolve();
script.onerror = () => {
reject(new Error(`Error in sandboxed script: ${url}. Check the console for more information.`));
};
script.src = url;
document.body.appendChild(script);
});
}
};
class ExtensionWorker {
constructor () {
this.nextExtensionId = 0;
this.initialRegistrations = [];
this.firstRegistrationPromise = new Promise(resolve => {
this.firstRegistrationCallback = resolve;
});
dispatch.waitForConnection.then(() => {
dispatch.call('extensions', 'allocateWorker').then(async x => {
const [id, extension] = x;
this.workerId = id;
try {
await loadScripts(extension);
await this.firstRegistrationPromise;
const initialRegistrations = this.initialRegistrations;
this.initialRegistrations = null;
Promise.all(initialRegistrations).then(() => dispatch.call('extensions', 'onWorkerInit', id));
} catch (e) {
log.error(e);
dispatch.call('extensions', 'onWorkerInit', id, `${e}`);
}
});
});
this.extensions = [];
}
register (extensionObject) {
const extensionId = this.nextExtensionId++;
this.extensions.push(extensionObject);
const serviceName = `extension.${this.workerId}.${extensionId}`;
const promise = dispatch.setService(serviceName, extensionObject)
.then(() => dispatch.call('extensions', 'registerExtensionService', serviceName));
if (this.initialRegistrations) {
this.firstRegistrationCallback();
this.initialRegistrations.push(promise);
}
return promise;
}
}
global.Scratch = global.Scratch || {};
Object.assign(global.Scratch, ScratchCommon, {
canFetch: () => Promise.resolve(true),
fetch: (url, options) => fetch(url, options),
canOpenWindow: () => Promise.resolve(false),
openWindow: () => Promise.reject(new Error('Scratch.openWindow not supported in sandboxed extensions')),
canRedirect: () => Promise.resolve(false),
redirect: () => Promise.reject(new Error('Scratch.redirect not supported in sandboxed extensions')),
canRecordAudio: () => Promise.resolve(false),
canRecordVideo: () => Promise.resolve(false),
canReadClipboard: () => Promise.resolve(false),
canNotify: () => Promise.resolve(false),
canGeolocate: () => Promise.resolve(false),
canEmbed: () => Promise.resolve(false),
canUnsandbox: () => Promise.resolve(false),
translate
});
/**
* Expose only specific parts of the worker to extensions.
*/
const extensionWorker = new ExtensionWorker();
global.Scratch.extensions = {
register: extensionWorker.register.bind(extensionWorker)
};
global.ScratchExtensions = createScratchX(global.Scratch);
|