Skip to content

Instantly share code, notes, and snippets.

@tkatochin
Last active June 6, 2018 06:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tkatochin/e502335ddf2fb64e7d1018f1434e0df0 to your computer and use it in GitHub Desktop.
Save tkatochin/e502335ddf2fb64e7d1018f1434e0df0 to your computer and use it in GitHub Desktop.
Content ScriptからBackground Script内の関数を直接呼びだす(ように見せる) ref: https://qiita.com/tkatochin/items/30e077f7a8f94d39d714
/**
* バックグラウンドにRPCする呼び出し側の実装(manifestのcontent_scriptsに記述して配備すること)
*/
'use strict';
(function(){
function createAsyncRpcFunction(methodName) {
return async function() {
const req = {
method: methodName,
args: [].slice.apply(arguments)
};
return new Promise((resolve, reject)=>{
chrome.runtime.sendMessage(req, function(res){
if (res && ["OK","ERROR"].includes(res.status)) {
if (res.status == "OK") {
if (!res.data) {
res.data = undefined;
}
try {
resolve(res.data);
} catch(e) {
console.error(`then-callback call failure!! ${e}`);
reject(e);
}
return;
} else {
console.error(`RPC ${methodName} result ERROR!! ${JSON.stringify(res)}`);
reject(res);
}
} else {
console.error(`RPC return value of ${methodName} is no reply or unknown status!! ${res}`);
reject(res);
}
});
});
}
}
/**
* RPCの仕掛け。
*/
window.bg = new Proxy({}, {
get: function(target, methodName){
if (methodName in target) {
return target[methodName];
}
return target[methodName] = createAsyncRpcFunction(methodName);
}
});
})();
/**
* RPCされる側の実装(manifestのbackground/scriptsに記述して配備すること)
*/
'use strict';
window.bg = window.bg || {};
(function(){
chrome.runtime.onMessage.addListener(function(req, sender, sendResponse) {
if (req.method in bg && bg[req.method] instanceof Function) {
let func = bg[req.method];
try {
var result = func.apply(func, req.args || []);
if (!(result instanceof Promise)) {
let trueResult = result;
result = new Promise((resolve,reject)=>{
try {
resolve(trueResult);
} catch(e) {
reject(e);
}
});
}
result.then(result=>sendResponse({
status: "OK",
data: result
})
).catch(e=>sendResponse({
status: "ERROR",
error: e.toString()
})
);
} catch(e) {
sendResponse({
status: "ERROR",
error: e.toString()
});
}
} else {
sendResponse({
status: "ERROR",
error: `method not found - ${req.method}`
});
}
return true;
});
})();
var result = await bg.myMethod(param1, param2);
bg.myMethod = function(param1, param2) {
var result = ...;
...
return result;
}
bg.myMethod = function() {
return new Promise((resolve, reject)=>{
needCallbackLogic(function (result){
resolve(result);
}, function(error){
reject(error);
});
});
}
bg.myMethod = async function() {
return await needCallbackLogic();
}
function createAsyncRpcFunction(methodName) {
return async function() {
const req = {
method: methodName,
args: [].slice.apply(arguments)
};
return new Promise((resolve, reject)=>{
chrome.runtime.sendMessage(req, function(res){
if (res && ["OK","ERROR"].includes(res.status)) {
if (res.status == "OK") {
if (!res.data) {
res.data = undefined;
}
try {
resolve(res.data);
} catch(e) {
console.error(`then-callback call failure!! ${e}`);
reject(e);
}
return;
} else {
console.error(`RPC ${methodName} result ERROR!! ${JSON.stringify(res)}`);
reject(res);
}
} else {
console.error(`RPC return value of ${methodName} is no reply or unknown status!! ${res}`);
reject(res);
}
});
});
}
}
/**
* RPCの仕掛け。
*/
window.bg = new Proxy({}, {
get: function(target, methodName){
if (methodName in target) {
return target[methodName];
}
return target[methodName] = createAsyncRpcFunction(methodName);
}
});
const constants = new Proxy({},{get:function(target,name){return chrome.i18n.getMessage(name);}});
const constants = new Proxy({},{get:function(target,name){return chrome.i18n.getMessage(name);}});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment