javascript - google - how to do a chrome extension
¿Chrome.runtime admite la publicación de mensajes con objetos transferibles? (1)
Estoy aprendiendo sobre objetos transferibles: http://updates.html5rocks.com/2011/12/Transferable-Objects-Lightning- Fast
Parecen bastante increíbles y me gustaría usarlos en mi extensión para acelerar la transferencia de datos desde dentro de un iframe a fuera de un iframe.
Tengo este código de ejemplo funcionando, pero usa un Trabajador web:
var s = document.createElement("script");
s.type = "text/js-worker";
s.innerHTML = ''console.log("i ran!");'';
document.body.appendChild(s);
var blob = new Blob(Array.prototype.map.call(document.querySelectorAll("script[type=/"text//js-worker/"]"), function (oScript) {
return oScript.textContent;
}), { type: "text/javascript" });
var worker = new Worker(window.URL.createObjectURL(blob));
var arrayBuffer = new ArrayBuffer(1);
worker.onmessage = function (oEvent) {
console.log("Called back by the worker!/n");
};
console.log("worker:", worker);
worker.postMessage(arrayBuffer, [arrayBuffer]);
if (arrayBuffer.byteLength) {
console.error("nope");
} else {
console.log("it worked");
}
¿Alguien tiene información sobre soporte o una línea de tiempo para soporte de / a crbug para usar un puerto como:
var port = chrome.runtime.connect({
name: ''youTubeIFrameConnectRequest''
});
//port.postMessage -- transferrable object.
No veo ningún apoyo para eso ni nada para apoyarlo, ¡pero parece realmente extraño!
Los mensajes que pasan por el mensaje de extensión que pasa las API siempre tienen una serialización JSON. Este formato no solo se usa para pasar mensajes entre la página de fondo y las secuencias de comandos de contenido, sino también con aplicaciones nativas . Entonces, supongo que no es muy probable que el mensaje que pasa las API sea compatible con más elementos.
Ya en 2012 se solicitó el algoritmo de clonación estructurado (más potente que la serialización JSON, menos potente que los transferibles) ( Cromium issue 112163 ). El problema sigue abierto alguien ha sugerido usar un SharedWorker
como un "trampolín".
SharedWorker
se ve afectado por la misma política de origen, por lo que los llamantes deben residir en el mismo origen. Para lograr esto, puede agregar una página a web_accessible_resources
e incrustar esta página en un marco.
Al final de esta respuesta, adjunté una implementación simple de un trampolín. Crea una extensión con estos archivos. Luego, abre una pestaña. Esta pestaña contendrá el marco incrustado y la demostración enviará un mensaje al trabajador compartido. Este mensaje será transportado a la página de fondo, solo verá la consola de la página de fondo para ver estos mensajes.
La demostración es mínima, debe implementar la administración del puerto (destrucción) usted mismo.
La demostración no utiliza el envío de mensajes transferibles (aún), porque es una implementación general que permite múltiples puertos. Si se asegura que al menos dos puertos existen al mismo tiempo, puede cambiar el código para usar transferibles (los transferibles solo tienen sentido cuando hay uno recibido y un remitente, porque la propiedad del objeto también se transfiere).
Caso especial: Mismo proceso
Si todo su código se ejecuta en el mismo proceso, puede usar un enfoque más simple sin SharedWorker
s.
La misma política de origen prohíbe el acceso directo desde / hacia el marco y la extensión, por lo que usará parent.postMessage
para cruzar este puente. Luego, en el evento onmessage de la página, puede usar chrome.extension.getViews
para obtener una referencia directa al objeto de window
de una de sus páginas de extensión (por ejemplo, página emergente, página de opciones, ...).
Desde las otras páginas, chrome.extension.getBackgroundPage()
da una referencia al objeto de window
de la página de fondo (para una página de evento , use chrome.runtime.getBackroundPage(callback)
).
Si desea conectar dos marcos, utilice la API de mensajería de canal (consulte la especificación whatwg y el artículo de desarrollo de Opera ). Con este método, establecerá una conexión directa entre los marcos, ¡incluso si están ubicados en orígenes diferentes!
Ejemplo: trampolín
worker.js
var ports = [];
onconnect = function(event) {
var port = event.ports[0];
ports.push(port);
port.start();
port.onmessage = function(event) {
for (var i = 0; i < ports.length; ++i) {
if (ports[i] != port) {
ports[i].postMessage(event.data);
}
}
};
};
trampoline.js
var worker = new SharedWorker(chrome.runtime.getURL(''worker.js''));
worker.port.start();
// Demo: Print the message to the console, and remember the last result
worker.port.onmessage = function(event) {
console.log(''Received message'', event.data);
window.lastMessage = event.data;
};
// Demo: send a message
worker.port.postMessage(''Hello'');
trampoline.html
<script src="trampoline.js"></script>
contentscript.js
var f = document.createElement(''iframe'');
f.src = chrome.runtime.getURL(''trampoline.html'');
f.hidden = true;
(document.body || document.documentElement).appendChild(f);
manifest.json
Nota: puse trampoline.js
como script de fondo para ahorrar espacio en esta respuesta. Desde la perspectiva del trabajador web, no importa quién inició el mensaje, por lo que he reutilizado el código para enviar y recibir mensajes (después de todo, ¡es una demostración simple!).
{
"name": "Trampoline demo",
"version": "1",
"manifest_version": 2,
"background": {
"scripts": ["trampoline.js"],
"persistent": true
},
"content_scripts": [{
"js": ["contentscript.js"],
"matches": ["<all_urls>"]
}],
"web_accessible_resources": [
"trampoline.html"
]
}