diff --git a/demo/_locales/en/messages.json b/demo/_locales/en/messages.json new file mode 100644 index 0000000..37c1894 --- /dev/null +++ b/demo/_locales/en/messages.json @@ -0,0 +1,4 @@ +{ + "pluginDesc": {"message": "A simple chrome extension demo"}, + "helloWorld": {"message": "Hello World!"} +} \ No newline at end of file diff --git a/demo/_locales/zh_CN/messages.json b/demo/_locales/zh_CN/messages.json new file mode 100644 index 0000000..b4a2b9a --- /dev/null +++ b/demo/_locales/zh_CN/messages.json @@ -0,0 +1,4 @@ +{ + "pluginDesc": {"message": "一个简单的Chrome插件demo"}, + "helloWorld": {"message": "你好啊,世界!"} +} \ No newline at end of file diff --git a/demo/background.html b/demo/background.html new file mode 100644 index 0000000..22d2923 --- /dev/null +++ b/demo/background.html @@ -0,0 +1,26 @@ + + + + 背景页 + + + + + +
+

这是背景页

+
+ 跨域演示 +
+
+ + + + \ No newline at end of file diff --git a/demo/css/custom.css b/demo/css/custom.css new file mode 100644 index 0000000..3ab5758 --- /dev/null +++ b/demo/css/custom.css @@ -0,0 +1,71 @@ +.chrome-plugin-demo-panel { + position: fixed; + right: 0; + bottom: 10px; + background: #3385ff; + padding: 10px; + box-shadow: 0px 0px 10px #002761; + border-radius: 3px; + color: white; +} +.chrome-plugin-demo-panel a{ + color: white; + text-decoration: none; + font-size: 16px; +} +.chrome-plugin-demo-panel a:hover{ + text-decoration: underline; + color: #ffee08; +} +.chrome-plugin-simple-tip { + position: fixed; + left: 20px; + padding: 16px 10px; + top: 30px; + color: white; + min-width: 150px; + max-width: 700px; + border-radius: 3px; + text-align: center; + font-size: 16px; + background: #70a800; + background-image: linear-gradient(to bottom, #95cc2a, #70a800); + box-shadow: 0 0 3px rgba(0, 0, 0, .2); + transition: top .4s; +} +.animated { + -webkit-animation-duration: .5s; + animation-duration: .5s; + -webkit-animation-fill-mode: both; + animation-fill-mode: both +} +@-webkit-keyframes slideInLeft { + 0% { + -webkit-transform: translate3d(-100%,0,0); + transform: translate3d(-100%,0,0); + visibility: visible + } + + 100% { + -webkit-transform: translate3d(0,0,0); + transform: translate3d(0,0,0) + } +} + +@keyframes slideInLeft { + 0% { + -webkit-transform: translate3d(-100%,0,0); + transform: translate3d(-100%,0,0); + visibility: visible + } + + 100% { + -webkit-transform: translate3d(0,0,0); + transform: translate3d(0,0,0) + } +} + +.slideInLeft { + -webkit-animation-name: slideInLeft; + animation-name: slideInLeft +} \ No newline at end of file diff --git a/demo/img/sds.png b/demo/img/sds.png new file mode 100644 index 0000000..7581afb Binary files /dev/null and b/demo/img/sds.png differ diff --git a/demo/js/background.js b/demo/js/background.js index fc4c15d..1b12f90 100644 --- a/demo/js/background.js +++ b/demo/js/background.js @@ -19,21 +19,11 @@ chrome.contextMenus.create({ chrome.tabs.create({url: 'https://www.baidu.com/s?ie=utf-8&wd=' + encodeURI(params.selectionText)}); } }); -chrome.contextMenus.create({ - title: "获取当前页面tabId", - onclick: function() { - chrome.tabs.query({active: true, currentWindow: true}, function(tabs) - { - alert('当前tabId:' + (tabs.length ? tabs[0].id : '未知')); - }); - } -}); - //-------------------- badge演示 ------------------------// -(function() +/*(function() { var showBadge = false; var menuId = chrome.contextMenus.create({ @@ -56,6 +46,106 @@ chrome.contextMenus.create({ showBadge = !showBadge; } }); -})(); +})();*/ +// 监听来自content-script的消息 +chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) +{ + console.log('收到来自content-script的消息:'); + console.log(request, sender, sendResponse); + sendResponse('我是后台,我已收到你的消息:' + JSON.stringify(request)); +}); +$('#test_cors').click((e) => { + $.get('https://www.baidu.com', function(html){ + console.log( html); + alert('跨域调用成功!'); + }); +}); + +// 获取当前选项卡ID +function getCurrentTabId(callback) +{ + chrome.tabs.query({active: true, currentWindow: true}, function(tabs) + { + if(callback) callback(tabs.length ? tabs[0].id: null); + }); +} + +// 当前标签打开某个链接 +function openUrlCurrentTab(url) +{ + getCurrentTabId(tabId => { + chrome.tabs.update(tabId, {url: url}); + }) +} + +// 新标签打开某个链接 +function openUrlNewTab(url) +{ + chrome.tabs.create({url: url}); +} + +// omnibox 演示 +chrome.omnibox.onInputChanged.addListener((text, suggest) => { + console.log('inputChanged: ' + text); + if(!text) return; + if(text == '美女') { + suggest([ + {content: '中国' + text, description: '你要找“中国美女”吗?'}, + {content: '日本' + text, description: '你要找“日本美女”吗?'}, + {content: '泰国' + text, description: '你要找“泰国美女或人妖”吗?'}, + {content: '韩国' + text, description: '你要找“韩国美女”吗?'} + ]); + } + else if(text == '微博') { + suggest([ + {content: '新浪' + text, description: '新浪' + text}, + {content: '腾讯' + text, description: '腾讯' + text}, + {content: '搜狐' + text, description: '搜索' + text}, + ]); + } + else { + suggest([ + {content: '百度搜索 ' + text, description: '百度搜索 ' + text}, + {content: '谷歌搜索 ' + text, description: '谷歌搜索 ' + text}, + ]); + } +}); + +// 当用户接收关键字建议时触发 +chrome.omnibox.onInputEntered.addListener((text) => { + console.log('inputEntered: ' + text); + if(!text) return; + var href = ''; + if(text.endsWith('美女')) href = 'http://image.baidu.com/search/index?tn=baiduimage&ie=utf-8&word=' + text; + else if(text.startsWith('百度搜索')) href = 'https://www.baidu.com/s?ie=UTF-8&wd=' + text.replace('百度搜索 ', ''); + else if(text.startsWith('谷歌搜索')) href = 'https://www.google.com.tw/search?q=' + text.replace('谷歌搜索 ', ''); + else href = 'https://www.baidu.com/s?ie=UTF-8&wd=' + text; + openUrlCurrentTab(href); +}); + +// 预留一个方法给popup调用 +function testBackground() { + alert('你好,我是background!'); +} + +// 是否显示图片 +var showImage; +chrome.storage.sync.get({showImage: true}, function(items) { + showImage = items.showImage; +}); +// web请求监听,最后一个参数表示阻塞式,需单独声明权限:webRequestBlocking +chrome.webRequest.onBeforeRequest.addListener(details => { + if(!showImage && details.type == 'image') return {cancel: true}; + // 简单的音视频检测 + // 大部分网站视频的type并不是media,且视频做了防下载处理,所以这里仅仅是为了演示效果,无实际意义 + if(details.type == 'media') { + chrome.notifications.create(null, { + type: 'basic', + iconUrl: 'img/icon.png', + title: '检测到音视频', + message: '音视频地址:' + details.url, + }); + } +}, {urls: [""]}, ["blocking"]); \ No newline at end of file diff --git a/demo/js/content-script.js b/demo/js/content-script.js index 0953148..997a3eb 100644 --- a/demo/js/content-script.js +++ b/demo/js/content-script.js @@ -3,6 +3,8 @@ // 注意,必须设置了run_at=document_start 此段代码才会生效 document.addEventListener('DOMContentLoaded', function() { + // 注入自定义JS + injectCustomJs(); // 给谷歌搜索结果的超链接增加 _target="blank" if(location.host == 'www.google.com.tw') { @@ -17,17 +19,17 @@ document.addEventListener('DOMContentLoaded', function() { function fuckBaiduAD() { + if(document.getElementById('my_custom_css')) return; var temp = document.createElement('style'); temp.id = 'my_custom_css'; (document.head || document.body).appendChild(temp); var css = ` /* 移除百度右侧广告 */ #content_right{display:none;} - [data-click] [data-tuiguang]{display:none;} /* 覆盖整个屏幕的相关推荐 */ .rrecom-btn-parent{display:none;}' /* 难看的按钮 */ - .result-op{display:none !important;}`; + .result-op.xpath-log{display:none !important;}`; temp.innerHTML = css; console.log('已注入自定义CSS!'); // 屏蔽百度推广信息 @@ -40,6 +42,121 @@ document.addEventListener('DOMContentLoaded', function() }); } fuckBaiduAD(); + initCustomPanel(); + initCustomEventListen(); } }); +function initCustomPanel() +{ + var panel = document.createElement('div'); + panel.className = 'chrome-plugin-demo-panel'; + panel.innerHTML = ` +

injected-script操作content-script演示区:

+
+ 通过postMessage发送消息给content-script
+ 通过DOM事件发送消息给content-script
+ 发送消息到后台或者popup
+
+
+
+ `; + document.body.appendChild(panel); +} + +// 向页面注入JS +function injectCustomJs(jsPath) +{ + jsPath = jsPath || 'js/inject.js'; + var temp = document.createElement('script'); + temp.setAttribute('type', 'text/javascript'); + // 获得的地址类似:chrome-extension://ihcokhadfjfchaeagdoclpnjdiokfakg/js/inject.js + temp.src = chrome.extension.getURL(jsPath); + temp.onload = function() + { + // 放在页面不好看,执行完后移除掉 + this.parentNode.removeChild(this); + }; + document.head.appendChild(temp); +} + +// 接收来自后台的消息 +chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) +{ + console.log('收到来自 ' + (sender.tab ? "content-script(" + sender.tab.url + ")" : "popup或者background") + ' 的消息:', request); + if(request.cmd == 'update_font_size') { + var ele = document.createElement('style'); + ele.innerHTML = `* {font-size: ${request.size}px !important;}`; + document.head.appendChild(ele); + } + else { + tip(JSON.stringify(request)); + sendResponse('我收到你的消息了:'+JSON.stringify(request)); + } +}); + +// 主动发送消息给后台 +// 要演示此功能,请打开控制台主动执行sendMessageToBackground() +function sendMessageToBackground(message) { + chrome.runtime.sendMessage({greeting: message || '你好,我是content-script呀,我主动发消息给后台!'}, function(response) { + tip('收到来自后台的回复:' + response); + }); +} + +// 监听长连接 +chrome.runtime.onConnect.addListener(function(port) { + console.log(port); + if(port.name == 'test-connect') { + port.onMessage.addListener(function(msg) { + console.log('收到长连接消息:', msg); + tip('收到长连接消息:' + JSON.stringify(msg)); + if(msg.question == '你是谁啊?') port.postMessage({answer: '我是你爸!'}); + }); + } +}); + +window.addEventListener("message", function(e) +{ + console.log('收到消息:', e.data); + if(e.data && e.data.cmd == 'invoke') { + eval('('+e.data.code+')'); + } + else if(e.data && e.data.cmd == 'message') { + tip(e.data.data); + } +}, false); + + +function initCustomEventListen() { + var hiddenDiv = document.getElementById('myCustomEventDiv'); + if(!hiddenDiv) { + hiddenDiv = document.createElement('div'); + hiddenDiv.style.display = 'none'; + hiddenDiv.id = 'myCustomEventDiv'; + document.body.appendChild(hiddenDiv); + } + hiddenDiv.addEventListener('myCustomEvent', function() { + var eventData = document.getElementById('myCustomEventDiv').innerText; + tip('收到自定义事件:' + eventData); + }); +} + +var tipCount = 0; +// 简单的消息通知 +function tip(info) { + info = info || ''; + var ele = document.createElement('div'); + ele.className = 'chrome-plugin-simple-tip slideInLeft'; + ele.style.top = tipCount * 70 + 20 + 'px'; + ele.innerHTML = `
${info}
`; + document.body.appendChild(ele); + ele.classList.add('animated'); + tipCount++; + setTimeout(() => { + ele.style.top = '-100px'; + setTimeout(() => { + ele.remove(); + tipCount--; + }, 400); + }, 3000); +} \ No newline at end of file diff --git a/demo/js/inject.js b/demo/js/inject.js new file mode 100644 index 0000000..1690158 --- /dev/null +++ b/demo/js/inject.js @@ -0,0 +1,24 @@ +// 通过postMessage调用content-script +function invokeContentScript(code) +{ + window.postMessage({cmd: 'invoke', code: code}, '*'); +} +// 发送普通消息到content-script +function sendMessageToContentScriptByPostMessage(data) +{ + window.postMessage({cmd: 'message', data: data}, '*'); +} + +// 通过DOM事件发送消息给content-script +(function() { + var customEvent = document.createEvent('Event'); + customEvent.initEvent('myCustomEvent', true, true); + // 通过事件发送消息给content-script + function sendMessageToContentScriptByEvent(data) { + data = data || '你好,我是injected-script!'; + var hiddenDiv = document.getElementById('myCustomEventDiv'); + hiddenDiv.innerText = data + hiddenDiv.dispatchEvent(customEvent); + } + window.sendMessageToContentScriptByEvent = sendMessageToContentScriptByEvent; +})(); diff --git a/demo/js/options.js b/demo/js/options.js new file mode 100644 index 0000000..017f04c --- /dev/null +++ b/demo/js/options.js @@ -0,0 +1,21 @@ +document.addEventListener('DOMContentLoaded', function() { + var defaultConfig = {color: 'white', showImage: true}; // 默认配置 + // 读取数据,第一个参数是指定要读取的key以及设置默认值 + chrome.storage.sync.get(defaultConfig, function(items) { + document.getElementById('color').value = items.color; + document.getElementById('show_image').checked = items.showImage; + }); +}); + +document.getElementById('save').addEventListener('click', function() { + var color = document.getElementById('color').value; + var showImage = document.getElementById('show_image').checked; + // 这里貌似会存在刷新不及时的问题 + chrome.extension.getBackgroundPage().showImage = showImage; // 让background即使生效 + chrome.storage.sync.set({color: color, showImage: showImage}, function() { + // 注意新版的options页面alert不生效! + // alert('保存成功!'); + document.getElementById('status').textContent = '保存成功!'; + setTimeout(() => {document.getElementById('status').textContent = '';}, 800); + }); +}); \ No newline at end of file diff --git a/demo/js/popup.js b/demo/js/popup.js new file mode 100644 index 0000000..a767130 --- /dev/null +++ b/demo/js/popup.js @@ -0,0 +1,222 @@ +$(function() { + + // 加载设置 + var defaultConfig = {color: 'white'}; // 默认配置 + chrome.storage.sync.get(defaultConfig, function(items) { + document.body.style.backgroundColor = items.color; + }); + + // 初始化国际化 + $('#test_i18n').html(chrome.i18n.getMessage("helloWorld")); + + +}); + +// 打开后台页 +$('#open_background').click(e => { + window.open(chrome.extension.getURL('background.html')); +}); + +// 调用后台JS +$('#invoke_background_js').click(e => { + var bg = chrome.extension.getBackgroundPage(); + bg.testBackground(); +}); + +// 获取后台页标题 +$('#get_background_title').click(e => { + var bg = chrome.extension.getBackgroundPage(); + alert(bg.document.title); +}); + +// 设置后台页标题 +$('#set_background_title').click(e => { + var title = prompt('请输入background的新标题:', '这是新标题'); + var bg = chrome.extension.getBackgroundPage(); + bg.document.title = title; + alert('修改成功!'); +}); + +// 自定义窗体大小 +$('#custom_window_size').click(() => { + chrome.windows.getCurrent({}, (currentWindow) => { + var startLeft = 10; + chrome.windows.update(currentWindow.id, + { + left: startLeft * 10, + top: 100, + width: 800, + height: 600 + }); + var inteval = setInterval(() => { + if(startLeft >= 40) clearInterval(inteval); + chrome.windows.update(currentWindow.id, {left: (++startLeft) * 10}); + }, 50); + }); +}); + +// 最大化窗口 +$('#max_current_window').click(() => { + chrome.windows.getCurrent({}, (currentWindow) => { + // state: 可选 'minimized', 'maximized' and 'fullscreen' + chrome.windows.update(currentWindow.id, {state: 'maximized'}); + }); +}); + + +// 最小化窗口 +$('#min_current_window').click(() => { + chrome.windows.getCurrent({}, (currentWindow) => { + // state: 可选 'minimized', 'maximized' and 'fullscreen' + chrome.windows.update(currentWindow.id, {state: 'minimized'}); + }); +}); + +// 打开新窗口 +$('#open_new_window').click(() => { + chrome.windows.create({state: 'maximized'}); +}); + +// 关闭全部 +$('#close_current_window').click(() => { + chrome.windows.getCurrent({}, (currentWindow) => { + chrome.windows.remove(currentWindow.id); + }); +}); + +// 新标签打开网页 +$('#open_url_new_tab').click(() => { + chrome.tabs.create({url: 'https://www.baidu.com'}); +}); + +// 当前标签打开网页 +$('#open_url_current_tab').click(() => { + getCurrentTabId(tabId => { + chrome.tabs.update(tabId, {url: 'http://www.so.com'}); + }); +}); + +// 获取当前标签ID +$('#get_current_tab_id').click(() => { + getCurrentTabId(tabId => { + alert('当前标签ID:' + tabId); + }); +}); + +// 高亮tab +$('#highlight_tab').click(() => { + chrome.tabs.highlight({tabs: 0}); +}); + +// popup主动发消息给content-script +$('#send_message_to_content_script').click(() => { + sendMessageToContentScript('你好,我是popup!', (response) => { + if(response) alert('收到来自content-script的回复:'+response); + }); +}); + +// 监听来自content-script的消息 +chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) +{ + console.log('收到来自content-script的消息:'); + console.log(request, sender, sendResponse); + sendResponse('我是popup,我已收到你的消息:' + JSON.stringify(request)); +}); + +// popup与content-script建立长连接 +$('#connect_to_content_script').click(() => { + getCurrentTabId((tabId) => { + var port = chrome.tabs.connect(tabId, {name: 'test-connect'}); + port.postMessage({question: '你是谁啊?'}); + port.onMessage.addListener(function(msg) { + alert('收到长连接消息:'+msg.answer); + if(msg.answer && msg.answer.startsWith('我是')) + { + port.postMessage({question: '哦,原来是你啊!'}); + } + }); + }); +}); + +// 获取当前选项卡ID +function getCurrentTabId(callback) +{ + chrome.tabs.query({active: true, currentWindow: true}, function(tabs) + { + if(callback) callback(tabs.length ? tabs[0].id: null); + }); +} + +// 这2个获取当前选项卡id的方法大部分时候效果都一致,只有少部分时候会不一样 +function getCurrentTabId2() +{ + chrome.windows.getCurrent(function(currentWindow) + { + chrome.tabs.query({active: true, windowId: currentWindow.id}, function(tabs) + { + if(callback) callback(tabs.length ? tabs[0].id: null); + }); + }); +} + +// 向content-script主动发送消息 +function sendMessageToContentScript(message, callback) +{ + getCurrentTabId((tabId) => + { + chrome.tabs.sendMessage(tabId, message, function(response) + { + if(callback) callback(response); + }); + }); +} + +// 向content-script注入JS片段 +function executeScriptToCurrentTab(code) +{ + getCurrentTabId((tabId) => + { + chrome.tabs.executeScript(tabId, {code: code}); + }); +} + + +// 演示2种方式操作DOM + +// 修改背景色 +$('#update_bg_color').click(() => { + executeScriptToCurrentTab('document.body.style.backgroundColor="red";') +}); + +// 修改字体大小 +$('#update_font_size').click(() => { + sendMessageToContentScript({cmd:'update_font_size', size: 42}, function(response){}); +}); + +// 显示badge +$('#show_badge').click(() => { + chrome.browserAction.setBadgeText({text: 'New'}); + chrome.browserAction.setBadgeBackgroundColor({color: [255, 0, 0, 255]}); +}); + +// 隐藏badge +$('#hide_badge').click(() => { + chrome.browserAction.setBadgeText({text: ''}); + chrome.browserAction.setBadgeBackgroundColor({color: [0, 0, 0, 0]}); +}); + +// 显示桌面通知 +$('#show_notification').click(e => { + chrome.notifications.create(null, { + type: 'image', + iconUrl: 'img/icon.png', + title: '祝福', + message: '骚年,祝你圣诞快乐!Merry christmas!', + imageUrl: 'img/sds.png' + }); +}); + +$('#check_media').click(e => { + alert('即将打开一个有视频的网站,届时将自动检测是否存在视频!'); + chrome.tabs.create({url: 'http://www.w3school.com.cn/tiy/t.asp?f=html5_video'}); +}); \ No newline at end of file diff --git a/demo/js/show-image-content-size.js b/demo/js/show-image-content-size.js new file mode 100644 index 0000000..ba8bee7 --- /dev/null +++ b/demo/js/show-image-content-size.js @@ -0,0 +1,8 @@ +// 鉴于浏览器默认不会显示图片的体积大小,每次都需要保存到本地才能查看到大小 +// 故通过插件的方式强行修改图片页的标题 +fetch(location.href).then(resp => resp.blob()).then(blob => { + var size = blob.size; + size = (size / 1024).toFixed(2) + ' kb'; + document.title = '(' + size + ')' + document.title; + console.log(size); +}); diff --git a/demo/manifest.json b/demo/manifest.json index 8a25c06..a0534b6 100644 --- a/demo/manifest.json +++ b/demo/manifest.json @@ -6,7 +6,7 @@ // 插件的版本 "version": "1.0.0", // 插件描述 - "description": "简单的Chrome扩展demo", + "description": "__MSG_pluginDesc__", // 图标,一般偷懒全部用一个尺寸的也没问题 "icons": { @@ -14,10 +14,12 @@ "48": "img/icon.png", "128": "img/icon.png" }, - // 后台JS + // 会一直常驻的后台JS或后台页面 "background": { - "scripts": ["js/background.js"] + // 2种指定方式,如果指定JS,那么会自动生成一个背景页 + "page": "background.html" + //"scripts": ["js/background.js"] }, // 浏览器右上角图标设置,browser_action、page_action、app必须三选一 "browser_action": @@ -38,11 +40,20 @@ "content_scripts": [ { - "matches": ["http://*/*", "https://*/*"], + //"matches": ["http://*/*", "https://*/*"], + // "" 表示匹配所有地址 + "matches": [""], + // 多个JS按顺序注入 "js": ["js/jquery-1.8.3.js", "js/content-script.js"], - "css": [], + // JS的注入可以随便一点,但是CSS的注意就要千万小心了,因为一不小心就可能影响全局样式 + "css": ["css/custom.css"], // 代码注入的时间,可选值: "document_start", "document_end", or "document_idle",最后一个表示页面空闲时,默认document_idle "run_at": "document_start" + }, + // 这里仅仅是为了演示content-script可以配置多个规则 + { + "matches": ["*://*/*.png", "*://*/*.jpg", "*://*/*.gif", "*://*/*.bmp"], + "js": ["js/show-image-content-size.js"] } ], // 权限申请 @@ -51,9 +62,14 @@ "contextMenus", // 右键菜单 "tabs", // 标签 "notifications", // 通知 + "webRequest", // web请求 + "webRequestBlocking", + "storage", // 插件本地存储 "http://*/*", // 可以通过executeScript或者insertCSS访问的网站 "https://*/*" // 可以通过executeScript或者insertCSS访问的网站 ], + // 普通页面能够直接访问的插件资源列表,如果不设置是无法直接访问的 + "web_accessible_resources": ["js/inject.js"], // 插件主页,这个很重要,不要浪费了这个免费广告位 "homepage_url": "https://www.baidu.com", // 覆盖浏览器默认页面 @@ -62,6 +78,19 @@ // 覆盖浏览器默认的新标签页 "newtab": "newtab.html" }, + // Chrome40以前的插件配置页写法 + "options_page": "options.html", + // Chrome40以后的插件配置页写法,如果2个都写,新版Chrome只认后面这一个 + "options_ui": + { + "page": "options.html", + // 添加一些默认的样式,推荐使用 + "chrome_style": true + }, + // 向地址栏注册一个关键字以提供搜索建议,只能设置一个关键字 + "omnibox": { "keyword" : "go" }, + // 默认语言 + "default_locale": "zh_CN", // devtools页面入口,注意只能指向一个HTML文件,不能是JS文件 "devtools_page": "devtools.html" } \ No newline at end of file diff --git a/demo/newtab.html b/demo/newtab.html index 0c174fe..f97a895 100644 --- a/demo/newtab.html +++ b/demo/newtab.html @@ -15,9 +15,17 @@ font-size: 48px; color: #CCC; } + .wrapper { + position: absolute; + top: 0; + left: 0; + padding: 40px; + font-size: 16px; + }

这是一个自定义的新标签页

+ \ No newline at end of file diff --git a/demo/options.html b/demo/options.html new file mode 100644 index 0000000..f51a947 --- /dev/null +++ b/demo/options.html @@ -0,0 +1,32 @@ + + + + + + 插件配置页 + + +

简单的配置页

+

(功能很无聊,纯属演示功能)

+
+ + +
+
+ +
+ 保存配置 +
+ + + + \ No newline at end of file diff --git a/demo/popup.html b/demo/popup.html index e356bf4..5808d7d 100644 --- a/demo/popup.html +++ b/demo/popup.html @@ -10,10 +10,59 @@ width: 500px; min-height: 100px; } + a {margin-right: 10px;}

这是一个popup页面!

+

background

+
+ 打开background + 调用background页JS方法 + 获取background页的标题 + 设置background页标题 + (验证background生命周期和单实例特性) +
+

窗口操作演示

+
+ 新窗口打开百度 + 执行简单的窗口动画 + 将当前窗口最大化 + 将当前窗口最小化 + 关闭当前窗口所有标签(慎点) +
+

标签操作演示

+
+ 新标签打开百度 + 当前标签打开网页 + 获取当前标签页ID + 切换到第一个标签 +
+

popup与content-script交互

+
+ 短连接发送消息到content-script + 长连接发送消息到content-script +
+

DOM交互演示

+
+ 修改页面背景色(通过executeScript实现) + 修改字体大小(通过sendMessage实现) +
+

国际化演示

+
+

(另外请到插件列表页查看描述的变化)

+
+

其它

+
+ 显示badge + 隐藏badge + 显示桌面通知 + 检测网页视频 +
+

更多

+
+ 百度广告,右键菜单,omnibox,图片大小演示,devtools演示,sidebar演示, +
diff --git a/demo/popup.js b/demo/popup.js deleted file mode 100644 index 00618da..0000000 --- a/demo/popup.js +++ /dev/null @@ -1,28 +0,0 @@ -var bg = chrome.extension.getBackgroundPage(); -function add(name,url) -{ - var path=bg.localStorage.path||'[]'; - path=JSON.parse(path); - path.push([name,url]); - bg.localStorage.path=JSON.stringify(path); - return path; -} -function init() -{ - var path=JSON.parse(bg.localStorage.path||'[]'); - var html=''; - for(var i=0;i'+path[i][1]+''; - $('#table').append(html); -} -$(function() -{ - init(); - $('#add').click(function() - { - var name=$('#name').val(),url=$('#url').val(); - add(name,url); - $('#table').append(''+name+''+url+''); - }); -}); - diff --git a/page-action-demo/img/icon.png b/page-action-demo/img/icon.png new file mode 100644 index 0000000..03cd18e Binary files /dev/null and b/page-action-demo/img/icon.png differ diff --git a/page-action-demo/js/background.js b/page-action-demo/js/background.js new file mode 100644 index 0000000..82b7dd4 --- /dev/null +++ b/page-action-demo/js/background.js @@ -0,0 +1,13 @@ +chrome.runtime.onInstalled.addListener(function(){ + chrome.declarativeContent.onPageChanged.removeRules(undefined, function(){ + chrome.declarativeContent.onPageChanged.addRules([ + { + conditions: [ + // 只有打开百度才显示pageAction + new chrome.declarativeContent.PageStateMatcher({pageUrl: {urlContains: 'baidu.com'}}) + ], + actions: [new chrome.declarativeContent.ShowPageAction()] + } + ]); + }); +}); diff --git a/page-action-demo/manifest.json b/page-action-demo/manifest.json new file mode 100644 index 0000000..fd784f0 --- /dev/null +++ b/page-action-demo/manifest.json @@ -0,0 +1,33 @@ +{ + // 清单文件的版本,这个必须写,而且必须是2 + "manifest_version": 2, + // 插件的名称 + "name": "page-action-demo", + // 插件的版本 + "version": "1.0.0", + // 插件描述 + "description": "pageAction演示", + // 图标,一般偷懒全部用一个尺寸的也没问题 + "icons": + { + "16": "img/icon.png", + "48": "img/icon.png", + "128": "img/icon.png" + }, + // 当某些特定页面打开才显示的图标 + "page_action": + { + "default_icon": "img/icon.png", + "default_title": "我是pageAction", + "default_popup": "popup.html" + }, + // 权限申请 + "permissions": + [ + "declarativeContent" + ], + "background": + { + "scripts": ["js/background.js"] + } +} \ No newline at end of file diff --git a/page-action-demo/popup.html b/page-action-demo/popup.html new file mode 100644 index 0000000..7530a84 --- /dev/null +++ b/page-action-demo/popup.html @@ -0,0 +1,20 @@ + + + + popup页 + + + + + +

pageAction演示

+

打开百度pageAction会点亮,打开其它页面pageAction会变灰。

+ + \ No newline at end of file