Skip to content
This repository has been archived by the owner on Dec 3, 2017. It is now read-only.

Commit

Permalink
Define Chrome's tabs.Tab type for onClicked event
Browse files Browse the repository at this point in the history
  • Loading branch information
Rob--W committed Aug 9, 2013
1 parent 1225652 commit 45d6282
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 10 deletions.
7 changes: 4 additions & 3 deletions docs/browser-action.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ The `browserAction` module is modelled after the [`chrome.browserAction`](https:
There are only a few differences between this Jetpack module and the `chrome.browserAction` API:

1. Tab-specific behavior cannot be defined, because the chrome.tabs API is not emulated in Firefox.
Consequently, all `tabId` parameters are ignored, and the `browserAction.onClicked` is triggered
without any parameters.
Consequently, all `tabId` parameters are ignored.
2. The `setIcon` method does not support the `imageData` parameter.
3. A new method, `destroy` has been added to remove the badge.
4. `browserAction.sendMessage` and `browserAction.onMessage` are added. These are similar to
Expand All @@ -26,7 +25,7 @@ There are only a few differences between this Jetpack module and the `chrome.bro
default_title: 'Badge title' // optional; shown in tooltip
});
// Set badge text to x on click
badge.onClicked.addListener(function() {
badge.onClicked.addListener(function(tab) {
badge.setBadgeText({
text: 'x'
});
Expand Down Expand Up @@ -213,6 +212,8 @@ Creates a new badge. The badge is immediately added to the toolbar.
<api name="onClicked">
@event
Fired when a browser action icon is clicked. This event will not fire if the browser action has a popup.
@argument {tabs.Tab}
Object with details about the tab associated with the click. The object follows Chrome's [`tabs.Tab`](https://developer.chrome.com/extensions/tabs.html#type-Tab) format.
</api>

</api>
7 changes: 5 additions & 2 deletions lib/browserAction.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
// This module is modeled after the chrome.browserAction API of Chrome 26
// Everything is implemented, except for:
// - All `details` parameter types ignore the `tabId` property.
// - The `onClicked` event does not receive any arguments (Chrome passes a tabs.Tab type)
// - The `setIcon` method does not support details.imageData
// New methods:
// - Use `destroy` to remove the browser action.
Expand All @@ -32,6 +31,9 @@ const { createMessageChannel, messageContentScriptFile } = require('messaging');
const { EventTarget } = require('sdk/event/target');
const EventEmitter = require('sdk/event/core');

const tabs = require('sdk/tabs');
const chromeTabs = require('chrome-tabs-api');


function RESOURCE(path) {
if (typeof path == 'string' && path && !~path.indexOf(':'))
Expand Down Expand Up @@ -169,7 +171,8 @@ function createBadge(browserAction, badgeState) {
onClick: function() {
if (badgeState.enabled && !badgeState.popupPath) {
// Trigger click event iff a popup is not attached
browserAction.onClicked.dispatch();
let chromeTab = chromeTabs.toChromeTab(tabs.activeTab);
browserAction.onClicked.dispatch(chromeTab);
}
}
});
Expand Down
41 changes: 41 additions & 0 deletions lib/chrome-tabs-api.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/**
* (c) 2013 Rob Wu <[email protected]>
* Conversion between Chrome tabs.Tab type and Firefox's addon SDK's Tab type
* Distributed under the MIT license.
*/

'use strict';
const tabs = require('sdk/tabs');
const { isPrivate } = require('sdk/private-browsing');

// Convert SDK's tab type to Chrome's
function sdkTabToChrome(sdkTab) {
return {
id: sdkTab.id,
index: sdkTab.index,
// windowId:
// openerTabId:
highlighted: false,
active: sdkTab.window.tabs.activeTab === sdkTab,
pinned: sdkTab.isPinned,
url: sdkTab.url,
title: sdkTab.title,
faviconUrl: sdkTab.favicon,
// status:
incognito: isPrivate(sdkTab)
};
}

// Get the SDK's tab for a given Chrome tab.
function chromeTabToSdk(chromeTab) {
var chromeTabId = chromeTab.id;
for each (var sdkTab in tabs) {
if (sdkTab.id === chromeTabId) {
return sdkTab;
}
}
return null;
}

exports.toChromeTab = sdkTabToChrome;
exports.toFirefoxTab = chromeTabToSdk;
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
"name": "browser-action",
"description": "Create a browser action badge using the chrome.browserAction API syntax.",
"keywords": ["browser-action", "badge", "toolbarwidget", "widget", "ui"],
"author": "Rob Wu (https://rob.lekensteyn.nl/) <[email protected]>",
"author": "Rob Wu (https://robwu.nl/) <[email protected]>",
"dependencies": ["toolbarwidget"],
"version": "0.1.4",
"version": "0.1.5",
"license": "MIT"
}
2 changes: 1 addition & 1 deletion test/test-browserAction.js
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ exports['test onClicked / enable / disable'] = function(assert, done) {
let badge = BrowserAction({});
const WAIT_TIMEOUT = 150;
let onClicked;
badge.onClicked.addListener(function() onClicked());
badge.onClicked.addListener(function(tab) onClicked(tab));
let simulateClick = function() {
let doc = getBadgeDocument();
let MouseEvent = doc.defaultView.MouseEvent;
Expand Down
25 changes: 25 additions & 0 deletions test/test-chrome-tabs-api.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
'use strict';
const tabs = require('sdk/tabs');
const chromeTabs = require('chrome-tabs-api');

exports['test '] = function(assert, done) {
var url = 'data:text/html,' + encodeURIComponent('<title>Test</title>');
tabs.open({
url: url,
onReady: function(tab) {
assert.ok(tab, 'SDK Tab exists'); // Pre-requisite
testSdkTab(tab);
testSdkTab = function() {}; // Run once
}
});
function testSdkTab(tab) {
var chromeTab = chromeTabs.toChromeTab(tab);
assert.equal(tab.url, chromeTab.url, 'Tab\'s "url" property must be equal');
assert.equal(false, chromeTab.pinned, 'Tab\'s "pinned" property must be false');
var ffTab = chromeTabs.toFirefoxTab(chromeTab);
assert.equal(tab, ffTab, 'toFirefoxTab(toChromeTab(tab)) === tab');
done();
}
};

require('sdk/test').run(exports);
4 changes: 2 additions & 2 deletions test/test-messaging.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,13 @@ function testFactory(isEndAtPage, assert, done) {
} + ')();';
let throwIfExtensionIsDefined = 'if(typeof extension == "object") throw new Error("Unexpected global object \'extension\'!")';
let pageCode = isEndAtPage ? code : throwIfExtensionIsDefined;
let html = '<!DOCTYPE><html><head><title></title></head><body><script>' + pageCode + '</script></body></html>';
let html = '<!--messagingtest--><!DOCTYPE><html><head><title></title></head><body><script>' + pageCode + '</script></body></html>';
let data_url = 'data:text/html,' + encodeURIComponent(html);
let setDelayedException = function(i) setTimeout(function() {
throw new Error('onMessage not triggered (' + i +')!');
}, 2000);
let pageMod = PageMod({
include: 'data:text/html*',
include: 'data:text/html,%3C!--messagingtest*',
contentScriptWhen: 'start',
contentScriptFile: [messageContentScriptFile],
contentScript: isEndAtPage ? throwIfExtensionIsDefined : code,
Expand Down

0 comments on commit 45d6282

Please sign in to comment.