Chrome已经位居现代浏览器榜首,其中一个重要原因就是插件丰富,开发一款自己的专属插件也比较容易入手。做一个跳转小温之家前后台和书签管理的页面。记录下大致的操作吧。
【wenqyChromeExt】这是当前扩展插件根目录,运行tree -f
命令查看目录结构。
文章目录
Mainfest.json
看下Mainfest.json核心入口文件
- {
- “update_url”: “https://wenqy.com/crx”,
- // 描述
- “name”: “小温之家-行走在猿类世界”,
- “description”: “小温之家-行走在猿类世界,记下你的世界,做自己最真实的友人!”,
- “version”: “1.0.0”,
- “permissions”: [
- “*://*/*”,
- “activeTab”,
- “tabs”,
- “contextMenus”, // 右键菜单
- “webRequest”,
- “webRequestBlocking”,
- “storage”
- ],
- // 图标
- “icons”:
- {
- “16”: “imgs/map/icon16.png”,
- “48”: “imgs/map/icon48.png”,
- “128”: “imgs/map/icon128.png”
- },
- “background”: {
- “page”: “background.html”
- },
- // 默认语言
- “default_locale”: “zh_CN”,
- // 引入脚本
- “content_scripts”: [
- {
- // 匹配时使用脚本、样式
- “matches”: [“https://*/*”, “http://*/*”],
- “exclude_matches”: [],
- “css” : [“css/wenqy.css”],
- “js”: [“js/wenqy.js”],
- // 运行 文档加载结束
- “run_at”: “document_end”
- }
- ],
- “browser_action”: {
- “default_title”: “点击进入小温之家”,
- “default_icon”: “imgs/map/icon48.png”,
- “default_popup”: “popup.html”
- },
- // 选项页
- “options_page”: “options.html”,
- // 默认策略限制
- // “content_security_policy”: “script-src ‘self’; object-src ‘self'”,
- //”web_accessible_resources”: [
- // “imgs/map/*.png”
- //],
- “manifest_version”: 2
- }
popup.html
popup.html 点击chrome浏览器插件图标后的弹出层,与用户交互界面。
- <body id=“yc-baidu-translate”>
- <div class=“container”>
- <div class=“header”>
- <div class=“jumbotron”>
- <button class=“” id=“wenqy-page”><img title=“前往小温之家” src=“imgs/map/arrow_down_nomal.png” />登录小温之家</button>
- </div>
- </div>
- <div class=“main”>
- <div class=“select-l translate-from” data-click=“no-click”>
- <div class=“selected-l”>
- <span class=“selected-l-text” value=“”><img title=“前往小温之家” src=“imgs/map/right-arrow.png” />站点书签</span>
- </div>
- </div>
- </div>
- <div class=“row”>
- <select id=“select_sites” style=“width:100%”>
- <option value=“”>请搜索书签</option>
- </select>
- </div>
- <div class=“yc-baidu-translate-footer”>
- <div class=“icon_options”>
- <a href=“javascript:;” id=“icon_options_home” class=“icon_options_item”>
- <img title=“前往小温之家” id=“icon_options_home_img” src=“imgs/map/home.png”>
- </a>
- <a href=“javascript:;” id=“icon_options_setting” class=“icon_options_item”>
- <img title=“插件设置” id=“icon_options_setting_img” src=“imgs/map/setup.png”>
- </a>
- <a href=“javascript:;” id=“icon_options_help” class=“icon_options_item”>
- <img title=“帮助和反馈” id=“icon_options_help_img” src=“imgs/map/help.png”>
- </a>
- </div>
- </div>
- </div>
- </body>
popup.js
popup.js popup.html引用的外部js文件,行为操作层
- var haitao_sites = {
- ‘www.wenqy.com’: ‘小温之家’,
- ‘www.baidu.com’: ‘百度’
- };
- function parseURL(url) {
- var domain;
- if (url.indexOf(“/”) >= 0) {
- domain = url.substr(0, url.indexOf(“/”));
- } else {
- domain = url;
- }
- var domainName, port;
- var idx = domain.indexOf(“:”);
- if (idx > 0) {
- domainName = domain.substr(0, idx);
- port = domain.substr(idx + 1);
- } else {
- domainName = domain;
- }
- var shortName = domainName.substr(url.indexOf(“.”) + 1);
- if (shortName.indexOf(“.”) < 0) {
- shortName = domainName;
- }
- var tmp2 = url.substr(url.indexOf(“/”) + 1);
- var webContext = tmp2.substr(0, tmp2.indexOf(‘/’));
- var uri = tmp2.substr(tmp2.indexOf(‘/’));
- return {
- domainName: domainName,
- shortName: shortName,
- port: port,
- webContext: webContext,
- uri: uri
- }
- }
- function restore_options() {
- chrome.storage.local.get(null, function(items) {
- // console.log(‘items’, items);
- if (items[‘custom_sites’] && items[‘custom_sites’].length > 0) {
- var selectText = “”;
- for (var i in items[‘custom_sites’]) {
- var input_obj = parseURL(items[‘custom_sites’][i]);
- var name = haitao_sites[input_obj.domainName] ? haitao_sites[input_obj.domainName] : input_obj.shortName;
- selectText += ‘<option value=’+items[‘custom_sites’][i]+’>’+name+'<option>’;
- }
- $(“#select_sites”).empty().append(selectText);
- }
- })
- }
- restore_options();
- $(document).ready(function() {
- $(“#select_sites”).select2();
- $(“#select_sites”).change(function(event) {
- window.open(“http://” +$(“#select_sites option:selected”).val());
- });
- $(“#icon_options_setting”).click(function() {
- window.open(‘options.html’);
- });
- $(“#icon_options_setting”).hover(function() {
- $(“#icon_options_setting_img”).attr(‘src’, ‘imgs/map/setuphover.png’);
- }, function() {
- $(“#icon_options_setting_img”).attr(‘src’, ‘imgs/map/setup.png’);
- });
- $(‘#wenqy-page’).click(function() {
- window.open(‘http://wenqy.com/wp-login.php’);
- });
- $(“#icon_options_home”).click(function() {
- window.open(‘http://wenqy.com/’);
- });
- $(‘#icon_options_home’).hover(function () {
- $(‘#icon_options_home_img’).attr(‘src’, ‘imgs/map/home_hover.png’);
- }, function () {
- $(‘#icon_options_home_img’).attr(‘src’, ‘imgs/map/home.png’);
- });
- $(‘#icon_options_help’).click(function () {
- window.open(‘http://wenqy.com’);
- });
- $(‘#icon_options_help’).hover(function () {
- $(‘#icon_options_help_img’).attr(‘src’, ‘imgs/map/help_hover.png’);
- }, function () {
- $(‘#icon_options_help_img’).attr(‘src’, ‘imgs/map/help.png’);
- });
- });
options.html
options.html 扩展插件的设置界面
- <body>
- <h1 style=“text-align:center;”>小温之家| 自定义设置</h1>
- <h2>喜欢的颜色:</h2>
- <h2 style=“text-align:center;” id=“status”></h2>
- <br>
- </br>
- <div class=“autoTranslate”>
- <div class=“autoTranslate-switch”>
- <h2>喜欢的颜色:</h2>
- <table id=“custom-head” class=“table”>
- <tr>
- <td id=“thead-tip”>
- <select id=“color”>
- <option value=“”></option>
- <option value=“red”>red</option>
- <option value=“green”>green</option>
- <option value=“blue”>blue</option>
- <option value=“yellow”>yellow</option>
- <option value=“white”>white</option>
- </select>
- </td>
- <td>
- <a href=“#” id=“saveOptions”>保存</a>
- </td>
- </tr>
- </table>
- <h2>书签管理</h2>
- <table id=“custom-head” class=“table”>
- <tr>
- <td id=“thead-tip”>
- 书签
- </td>
- <td>
- <a href=“#” id=“add”>+添加站点</a>
- </td>
- </tr>
- </table>
- </div>
- <div class=“table-container”>
- <table id=“custom” class=“table-custom”>
- </table>
- </div>
- </div>
- </body>
wenqy.js
wenqy.js options.html 设置界面引用的外部行为操作层
- function save_options() {
- custom_sites = [];
- $(‘.site’).each(function() {
- if ($(this).text() != ” && custom_sites.indexOf($(this).text()) == -1) {
- custom_sites.push($(this).text());
- }
- })
- chrome.storage.local.set({
- ‘custom_sites’: custom_sites,
- }, function() {
- location.reload();
- });
- }
- function restore_options() {
- chrome.storage.local.get(null, function(items) {
- // console.log(‘items’, items);
- if (items[‘custom_sites’] && items[‘custom_sites’].length > 0) {
- $(“#custom”).addClass(“table-custom-padding”);
- for (var i in items[‘custom_sites’]) {
- var input_obj = parseURL(items[‘custom_sites’][i]);
- var name = haitao_sites[input_obj.domainName] ? haitao_sites[input_obj.domainName] : input_obj.shortName;
- $(“#custom”).append(‘\
- <tr>\
- <td class=“site”><a href=“http://’ + items[‘custom_sites’][i] + ‘” target=“_blank”>’ + items[‘custom_sites’][i] + ‘</a></td>\
- <td class=“site-name”>’ + name + ‘</td>\
- <td class=“site-remove”><a href=“#” class=“remove”>移除</a></td>\
- </tr>’);
- $(“.remove”).click(function() {
- $(this).parent().parent().remove();
- save_options();
- });
- }
- } else {
- $(“#custom”).append(‘\
- <tr id=“blank”>\
- <td class=“custom-nothing”>无</td>\
- </tr>’);
- }
- })
- }
- restore_options();
- /**
- * @author wenqy.com
- *
- *
- */
- $(function(){
- // Saves options to localStorage.
- function save_options_test() {
- var select = $(“#color option:selected”).val();
- localStorage[“favorite_color”] = select;
- // Update status to let user know options were saved.
- $(“#status”).text(“选项已保存”);
- console.log(“select->”+select);
- $(“body”).css(“background-color”,select);
- setTimeout(function() {
- $(“#status”).text(“”);
- }, 750);
- }
- // Restores select box state to saved value from localStorage.
- function restore_options_test() {
- var favorite = localStorage[“favorite_color”];
- if (!favorite) {
- return;
- }
- $(“#color”).val(favorite);
- $(“body”).css(“background-color”,favorite);
- }
- restore_options_test();
- $(“#saveOptions”).click(save_options_test);
- var url_expression = /[-a-zA-Z0-9@:%_\+.~#?&//=]{2,256}\.[a-z]{2,4}\b(\/[-a-zA-Z0-9@:%_\+.~#?&//=]*)?/gi;
- var url_regex = new RegExp(url_expression);
- var c_id = 0;
- $(“#add”).on(‘click’, function() {
- if ($(‘.add-tr’).length <= 0 ) {
- if (!$(“#custom”).hasClass(“table-custom-padding”)) {
- $(“#custom”).addClass(“table-custom-padding”);
- }
- $(“#custom”).before(‘\
- <table id=“‘ + c_id + ‘” class=“add-table”>\
- <tr class=“add-tr”>\
- <td class=“td-add-input”>\
- <input type=“text” class=“form-control site” placeholder=“请输入网站地址,如: www.wenqy.com” required>\
- </td>\
- <td class=“td-add-button”>\
- <button type=“button” class=“switch-open add-confirm” style=“width:79px;float: none;margin-left:16px;”>添加</button>\
- </td>\
- <td class=“td-add-remove-button”>\
- <button type=“button” class=“switch-close add-remove” style=“width:79px;float: none;”>取消</button>\
- </td>\
- </tr>\
- <tr><td class=“fail”></td></tr>\
- </table>’);
- $(“.add-remove”).on(‘click’, function() {
- $(this).parent().parent().parent().parent().remove();
- if ($(“.site”).length <= 0) {
- $(“#custom”).removeClass(“table-custom-padding”);
- }
- });
- $(“#” + c_id + ” .add-confirm”).on(‘click’, function() {
- var input_valid = true;
- var url_input = $(this).parent().prev().children(‘input’).val().replace(‘。’, ‘.’).replace(‘http://’, ”).replace(‘https://’, ”);
- if (url_input == “”) {
- $(‘.fail’).text(‘输入内容不能为空’);
- $(‘.fail’).show();
- input_valid = false;
- } else if (!url_input.match(url_regex)) {
- $(‘.fail’).text(‘无效网址’);
- $(‘.fail’).show();
- input_valid = false;
- }
- if (input_valid) {
- var input_obj = parseURL(url_input);
- var name = haitao_sites[input_obj.domainName] ? haitao_sites[input_obj.domainName] : input_obj.shortName;
- $(“#custom #blank”).remove();
- $(“#custom”).prepend(‘\
- <tr>\
- <td class=“site”><a href=“http://’ + url_input + ‘” target=“_blank”>’ + url_input + ‘</a></td>\
- <td class=“site-name”>’ + name + ‘</td>\
- <td class=“site-remove”><a href=“#” class=“remove”>移除</a></td>\
- </tr>’);
- $(this).parent().parent().remove();
- $(“.remove”).on(‘click’, function() {
- $(this).parent().parent().remove();
- save_options();
- });
- save_options();
- }
- });
- c_id += 1;
- }
- });
- });
直接将百度翻译的插件进行改造,阉割了。。。
该开始编写样例的时候报错,扩展页面动态绑定JS事件提示错误
Refused to execute inline event handler because it violates the following Content Security Policy directive: "script-src 'self' blob: filesystem: chrome-extension-resource:". Either the 'unsafe-inline' keyword, a hash ('sha256-...'), or a nonce ('nonce-...') is required to enable inline execution.
JavaScript事件都用外部引入的方式就可以了
Chrome插件安装
Chrome浏览器中输入URL:chrome://extensions
,进行【扩展程序】管理页面,当然也可以在【设置】里找,选择【加载已解压的扩展程序】,选中扩展插件的目录即可。当然也可以把扩展插件的目录打包,打包成.crx后缀结尾的扩展插件。
安装扩展后,如图所示:
点击【登录小温之家】,跳转到小温之家的后台登录界面;点击主页图标,跳转到小温之家首页,点击帮助图标也是;点击设置图标,跳转到站点管理页面。
添加站点后,就可以搜索选择啦,选择站点后,跳转到站点页面。
Console效果
- var str = “WENQY”;
- var mode = “stereo”; // 平面
- if (mode === ‘planar’) {
- var character = character_planar;
- }
- if (mode === ‘stereo’) { // 立体
- var character = character_stereo;
- }
- var result = ‘\n’;
- var strArr = str.split(‘\n’);
- for (var k = 0; k < strArr.length; k++) {
- for (var j = 0; j < 7; j++) {
- for (var i = 0, length = strArr[k].length; i < length; i++) {
- result = result + character[strArr[k][i]][j];
- }
- result = result + ‘\n’;
- }
- }
- console.group(“Info”);
- console.log(result);
- console.log(“welcome to http://wenqy.com”);
- console.log(” …..∵ ∴★.∴∵∴ ╭ ╯╭ ╯╭ ╯╭ ╯∴∵∴∵∴ “);
- console.log(“.☆.∵∴∵.∴∵∴▍▍ ▍▍ ▍▍ ▍▍☆ ★∵∴ “);
- console.log(“▍.∴∵∴∵.∴▅███████████☆ ★∵ “);
- console.log(“◥█▅▅▅▅███▅█▅█▅█▅█▅█▅███◤ “);
- console.log(“. ◥███████████████████◤ “);
- console.log(“....◥████████████████■◤”);
- console.log(“.. .. .. .. .. .. .. .”);
- console.log(“.. .. .. .. . “);
- console.log(“…友谊的巨轮向你驶来”);
- console.groupEnd();
- console.group(“Reference”);
- console.log(“https://github.com/starkwang”);
- console.log(“http://www.fuhaodq.com/fuhaotuan/1215.html”);
- console.log(“http://www.cnblogs.com/tinyTea/p/6072618.html”);
- console.log(“http://www.cnblogs.com/zhongxinWang/p/4121111.html”);
- console.groupEnd();
- );
效果图:
第一版自定义插件算是入门啦,当然存在痛点了,插件卸载后,重新安装并没有保存原先添加的站点记录,也没有为这些站点定义名称字段方便记忆和管理,话说还会再改吗?姑且记之吧。
参考
http://open.chrome.360.cn/extension_dev/overview.html
http://open.chrome.360.cn/extension_dev/manifest.html
发表评论