diff --git a/css/content.css b/css/content.css new file mode 100644 index 0000000..c20acc5 --- /dev/null +++ b/css/content.css @@ -0,0 +1,5 @@ + +html.crx-webcomponents-active .crx-webcomponents-component { + outline: 1px dashed red !important; + background-color: rgba(255,0,0,0.1) !important; +} diff --git a/img/logo_19x19_gs.png b/img/logo_19x19_gs.png new file mode 100644 index 0000000..d1e676f Binary files /dev/null and b/img/logo_19x19_gs.png differ diff --git a/js/background.js b/js/background.js index 3733ac3..84d0eeb 100644 --- a/js/background.js +++ b/js/background.js @@ -1,30 +1,42 @@ 'use strict'; -var port; -var toggle = false; - -chrome.runtime.onConnect.addListener(function(p) { - port = p; - - // Listens to messages from content.js - port.onMessage.addListener(function(msg) { - // Shows the icon if there's a custom element - if (msg.hasElements) { - chrome.tabs.query({active: true, currentWindow: true}, function(tabs) { - chrome.pageAction.show(tabs[0].id); - }); + /* + * Listens for content script messages + * message : + * .isActive : whether pageAction icon should be in active state + * .count : number of deteced web component elements + * sender : Chrome Sender object + */ +var onMessage = function (message, sender) { + + /* Show pageAction icon if at least on web component was found */ + if (message.count > 0) { + chrome.pageAction.show(sender.tab.id); + } else { + chrome.pageAction.hide(sender.tab.id); } - }); -}); - -// Sends a message when the icon is clicked -chrome.pageAction.onClicked.addListener(function(tab) { - if (!toggle) { - toggle = true; - } - else { - toggle = false; - } - - port.postMessage({open: toggle}); -}); + + chrome.pageAction.setTitle({ + tabId: sender.tab.id, + title: message.count + ' web components found' + }); + + chrome.pageAction.setIcon({ + tabId: sender.tab.id, + path: message.isActive ? 'img/logo_19x19.png' : 'img/logo_19x19_gs.png' + }); + }, + + /* + * Listens for icon clicks + * tab : Chrome Tab object + */ + onClicked = function (tab) { + + chrome.tabs.sendMessage(tab.id, {clicked: true}); + }; + + +/* Bind listeners */ +chrome.runtime.onMessage.addListener(onMessage); +chrome.pageAction.onClicked.addListener(onClicked); diff --git a/js/content.js b/js/content.js index 131eee0..ecd7da0 100644 --- a/js/content.js +++ b/js/content.js @@ -1,41 +1,78 @@ 'use strict'; -// Opens a port to communicate messages -var port = chrome.runtime.connect({name: "channel"}); - -// Filters all custom elements in the DOM -var allElements = document.all; - -allElements = Array.prototype.slice.call(allElements).filter(function(el) { - return el.localName.indexOf('-') != -1 || el.getAttribute('is'); -}); - -// Detects if there's >=1 custom elements -var hasElements = !!allElements.length; - -// Stores the element's default style -var originalOutline = []; -var originalBackground = []; - -allElements.forEach(function(element, i) { - originalOutline[i] = element.style.outline; - originalBackground[i] = element.style.backgroundColor; -}); - -// Sends a message to background.js -port.postMessage({hasElements: hasElements}); - -// Listens to messages from background.js -port.onMessage.addListener(function(msg) { - // Toggles highlight in all custom elements - allElements.forEach(function(element, i) { - if (msg.open) { - element.style.outline = '1px dashed red'; - element.style.backgroundColor = 'rgba(255,0,0,0.1)'; + +var html = document.getElementsByTagName("html")[0], + + /* + * Marker Classes + * classActive: to mark element, if state is active + * classComponent: to mark all matched web components (might be more fine grained in future) + */ + classActive = 'crx-webcomponents-active', + classComponent = 'crx-webcomponents-component', + + /* + * Marks web components + * returns : all matched and marked elements + */ + markComponents = function () { + + return Array.prototype.slice.call(document.all).filter(function (element) { + + if (element.localName.indexOf('-') >= 0 || element.getAttribute('is')) { + element.classList.add(classComponent); + return true; + } + }); + }, + + /* + * Current State + * isActive : highlight web components if true + * components : all matched and marked elements + */ + isActive = false, + components = markComponents(), + + /* + * Updates visible state and pageAction icon to reflect internal state + */ + update = function () { + + /* uncomment next line to mark web components on each update (dynamic DOM...) */ + // components = markComponents(); + + /* update element styles based on current state */ + if (isActive) { + html.classList.add(classActive); + } else { + html.classList.remove(classActive); } - else { - element.style.outline = originalOutline[i]; - element.style.backgroundColor = originalBackground[i]; + + /* send current state to background script to update pageAction icon */ + chrome.runtime.sendMessage({ + isActive: isActive, + count: components.length + }); + }, + + /* + * Listens for background script messages + * message : + * .clicked : whether pageAction icon was clicked + */ + onMessage = function (message) { + + if (message.clicked) { + /* toggle state and update */ + isActive = !isActive; + update(); } - }); -}); + }; + + +/* + * Bind message listener and run initial update + */ +chrome.runtime.onMessage.addListener(onMessage); +update(); diff --git a/manifest.json b/manifest.json index e9863d2..d53dc26 100644 --- a/manifest.json +++ b/manifest.json @@ -25,6 +25,9 @@ "http://*/*", "https://*/*" ], + "css": [ + "css/content.css" + ], "js": [ "js/content.js" ],