Skip to content

Instantly share code, notes, and snippets.

@ivershuo
Last active July 7, 2021 09:43
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save ivershuo/ecc1b0f22967f9ab19c084aab5d6831e to your computer and use it in GitHub Desktop.
Save ivershuo/ecc1b0f22967f9ab19c084aab5d6831e to your computer and use it in GitHub Desktop.
ReaderView SDK

外部插件调用

ReaderView.Message.send(msg).then(function(ret){console.log(ret)}).catch(function(err){console.log('err',err)});

msg 可选:

  • "ping":检测插件间数据连通性
  • "getPageData":获取readerview格式化后的文章数据
  • "getMainContentClass":获取readerview添加的正文容器className
  • "showPanel":打开阅读模式界面
  • "hidePanel":隐藏阅读模式界面

页面添加readerview支持meta标签

<meta name="readerview" content="article">

content属性中可指定阅读模式中展示的主要dom selector,一般情况下不需要设置,在设置的情况下会优先从指定的dom中获取主要内容。

(function(){
"use strict";
/*Reader View插件id*/
const RV_EXT_ID = 'iibolhpkjjmoepndefdmdlmbpfhlgjpl';
const MSG_PRE = 'ReaderView.';
/**
* 插件与插件间、插件与插件页面脚本间数据通信
**/
var Message = (function(){
var EventCallbacks = {};
var apiAllowMethods = ['apiNotAllowed'];
var _fmtMethods = function(methods){
var _methods = {};
Array.prototype.slice.call(methods, 0).forEach(function(method){
if(Array.isArray(method)){
method.forEach(function(method){
_methods[method] = true;
});
} else {
_methods[method] = true;
}
});
return Object.keys(_methods);
}
var MsgError = function(message){
if(!(this instanceof MsgError)){
return new MsgError(message);
}
this.name = 'MsgError';
this.message = message || 'Message Error';
}
MsgError.prototype = Object.create(Error.prototype);
MsgError.prototype.constructor = MsgError;
var msgObj = {
Error : MsgError,
send : function(tabIdOrExtensionId, type, data, cb){
var sendTo,
argv=[];
if(/^\d+$/.test(tabIdOrExtensionId) && chrome.tabs){
sendTo = 'tabs';
argv.push(tabIdOrExtensionId);
} else if(/^[a-z]{32}$/.test(tabIdOrExtensionId)){
sendTo = 'runtime';
argv.push(tabIdOrExtensionId);
} else {
sendTo = 'runtime';
cb = data;
data = type;
type = tabIdOrExtensionId;
}
if(typeof data == 'function'){
cb = data,
data = null;
}
return new Promise(function(resolve, reject){
argv = argv.concat([{
type : type,
data : data
}, function(retData){
var err;
if(retData instanceof MsgError || (retData && typeof retData == 'object' && retData.name == 'MsgError')){
err = MsgError(retData.message);
}
err = err || chrome.runtime.lastError;
if(err){
reject(err);
cb && cb(err);
} else {
resolve(retData);
cb && cb(null, retData);
}
}]);
chrome[sendTo].sendMessage.apply(chrome[sendTo], argv);
});
},
on : function(type, func){
if(!EventCallbacks[type]){
EventCallbacks[type] = [];
}
EventCallbacks[type].push(func);
},
addApiAllowMethods : function(methods){
methods = _fmtMethods(arguments);
methods.forEach(function(method){
if(apiAllowMethods.indexOf(method) === -1){
apiAllowMethods.push(method);
}
});
return apiAllowMethods;
},
rmApiAllowMethods : function(methods){
methods = _fmtMethods(arguments);
methods.forEach(function(method){
var idx = apiAllowMethods.indexOf(method);
if(idx !== -1){
apiAllowMethods.splice(idx, 1);
}
});
return apiAllowMethods;
}
}
function onMessage(data, sender, sendResponse){
var type = data.type;
if(type && EventCallbacks[type]){
var ret = false,
cbs = EventCallbacks[type],
l = cbs.length - 1,
cbDatas = {
str : '',
_onlyStr : true
};
cbs.forEach(function(cb, idx){
ret = cb(data.data, sender, function(data){
if(data instanceof MsgError || (data && typeof data == 'object' && data.name == 'MsgError')){
sendResponse(MsgError(data.message));
return;
}
if(!data || typeof data !== 'object'){
cbDatas.str = data;
} else {
for(var key in data){
cbDatas[key] = data[key];
}
}
if(idx === l){
var keys = Object.keys(cbDatas);
if(keys.length == 1 && keys[0] == 'str'){
cbDatas = cbDatas.str;
}
sendResponse(cbDatas);
}
}) || ret;
});
return ret;
}
}
chrome.runtime.onMessage.addListener(onMessage);
if(chrome.runtime.onMessageExternal){
chrome.runtime.onMessageExternal.addListener(function(data, sender, sendResponse){
var type = data && data.type;
if(apiAllowMethods.indexOf(type) == -1){
msgObj.send(sender.id, 'apiNotAllowed', {
'method' : type || null
}).catch(function(e){});
sendResponse(MsgError('This api method is not allowed.'));
return;
}
return onMessage(data, sender, sendResponse);
});
}
return msgObj;
})();
/**
* Reader View SDK
*/
var ReaderViewSDK = {
get : (function(){
var pinged = false;
return function(method, data, cb){
if(typeof data == 'function'){
cb = data;
data = null;
}
return (pinged ? Promise.resolve('pone') : Message.send(RV_EXT_ID, MSG_PRE + 'ping')).then(function(pingRet){
if(pingRet == 'pone'){
pinged = true;
return Message.send(RV_EXT_ID, MSG_PRE + method, data, cb);
} else {
Promise.reject();
}
});
}
})(),
on : function(type, cb){
Message.on(MSG_PRE + type, function(data, sender){
if(sender.id === RV_EXT_ID){
cb && cb(data, sender);
}
});
}
}
Object.defineProperties(ReaderViewSDK, {
'extId' : {
__proto__ : null,
enumerable : true,
value : RV_EXT_ID
},
'Message' : {
__proto__ : null,
enumerable : true,
value : Message
}
});
Message.addApiAllowMethods('ReaderView.error');
window.ReaderView = Object.freeze(ReaderViewSDK);
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment