summaryrefslogtreecommitdiffstats
path: root/chrome/browser/resources
diff options
context:
space:
mode:
authorscherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-15 00:47:17 +0000
committerscherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-15 00:47:17 +0000
commit5d4a8eb1c49b9a08ef4fd9f540a47e348307672f (patch)
treefd251326fdb8265b00fa2ded269973c2b1ce67a5 /chrome/browser/resources
parent12774990ee4f8f9c6bb2d9ccd032f9000a97b04a (diff)
downloadchromium_src-5d4a8eb1c49b9a08ef4fd9f540a47e348307672f.zip
chromium_src-5d4a8eb1c49b9a08ef4fd9f540a47e348307672f.tar.gz
chromium_src-5d4a8eb1c49b9a08ef4fd9f540a47e348307672f.tar.bz2
Reworked extension to leverage magic iframes for speedy load times
and modified communication with chat engine for increased reliability. Patch by seh@chromium.org: http://codereview.chromium.org/2065004/show BUG=none TEST=none Review URL: http://codereview.chromium.org/2094007 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@47349 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/resources')
-rw-r--r--chrome/browser/resources/chat_manager/background.html207
-rw-r--r--chrome/browser/resources/chat_manager/central_roster.html75
-rw-r--r--chrome/browser/resources/chat_manager/central_roster_viewer.html27
-rw-r--r--chrome/browser/resources/chat_manager/js/centralrosterhook.js12
-rw-r--r--chrome/browser/resources/chat_manager/js/chatbridgeeventtypes.js4
-rw-r--r--chrome/browser/resources/chat_manager/js/chatbridgehook.js64
-rw-r--r--chrome/browser/resources/chat_manager/js/gmailbridgehook.js63
-rw-r--r--chrome/browser/resources/chat_manager/manifest.json19
8 files changed, 324 insertions, 147 deletions
diff --git a/chrome/browser/resources/chat_manager/background.html b/chrome/browser/resources/chat_manager/background.html
index 06a0c96..05b4b61 100644
--- a/chrome/browser/resources/chat_manager/background.html
+++ b/chrome/browser/resources/chat_manager/background.html
@@ -12,126 +12,139 @@ to route both incoming and outgoing chats through this central roster.
-->
<body>
-<style>
- .talk_roster {
- position: fixed;
- left: 0px;
- top: 0px;
- }
- .talk_iframe {
- width: 100%;
- height: 100%;
- border: none;
- overflow-x: hidden;
- overflow-y: hidden;
- }
-</style>
-<script>
- var args = {
- 'host': 'talkgadget.google.com',
- 'jsmode': 'pre',
- 'hl': 'en',
- };
- // Read args.
- var urlParts = window.location.href.split(/[?&#]/);
- for (var i = 1; i < urlParts.length; i++) {
- var argParts = urlParts[i].split('=');
- if (argParts.length == 2) {
- args[argParts[0]] = argParts[1];
- }
- }
- document.write('<script src="https://' + args['host'] +
- '/talkgadget/notifier-js?silent=true&host=https://' + args['host'] +
- '/talkgadget/notifier-js' +
- (args['jsmode'] != '' ? ('&jsmode=' + args['jsmode']) : '') +
- '"></scr' + 'ipt>');
-</script>
+ <iframe
+ id='centralRoster'
+ src='central_roster.html'>Central Roster</iframe>
<script src="js/chatbridgeeventtypes.js"></script>
<script>
- var chatClient = null;
- if (window.GTalkNotifier) {
- chatClient = new GTalkNotifier(
- 'http://' + args['host'] + '/talkgadget/',
- 'notifierclient' +
- (args['jsmode'] != '' ? ('?jsmode=' + args['jsmode']) : ''),
- 'ifpc_relay',
- 'ifpc.js',
- 'Google Talk',
- {
- hostCallback: function(){},
- xpcRelay: 'xpc_relay',
- xpcBlank: 'xpc_blank',
- locale: args['hl'],
- isCentralRoster: true,
- hideProfileCard: true
+ var centralRosterWindow;
+ var centralRosterJid;
+ var centralRosterPort;
+ var centralJidListenerPorts = [];
+
+ // On loading central roster, reparent roster to viewer window.
+ function reparentCentralRosterToWindow() {
+ var backgroundDocument = centralRosterWindow.backgroundDocument;
+ if (backgroundDocument) {
+ var iframe = backgroundDocument.getElementById('centralRoster');
+ if (iframe) {
+ var windowDocument = centralRosterWindow.document;
+ if (windowDocument) {
+ if (windowDocument.adoptNode) {
+ windowDocument.adoptNode(iframe);
+ }
+ windowDocument.body.appendChild(iframe);
}
- );
- } else {
- document.write(
- '<div class="talk_roster"><b>GTalkNotifier undefined</b></div>');
+ }
+ }
}
- var centralRosterJid;
- var tabIdToGmPort = {};
- // Notify all open Gmail pages of updated central roster jid.
- function forwardCentralRosterJidToGmPorts() {
- for (var tabId in tabIdToGmPort) {
- var port = tabIdToGmPort[tabId];
- if (port != null) {
- port.postMessage({jid: centralRosterJid});
+ // On unloading central roster, reparent roster to background.
+ function reparentCenterRosterToBackground(event) {
+ var windowDocument = centralRosterWindow.document;
+ if (windowDocument) {
+ var iframe = windowDocument.getElementById('centralRoster');
+ if (iframe) {
+ var backgroundDocument = centralRosterWindow.backgroundDocument;
+ if (backgroundDocument) {
+ if (backgroundDocument.adoptNode) {
+ backgroundDocument.adoptNode(iframe);
+ }
+ backgroundDocument.body.appendChild(iframe);
+ }
}
}
+ centralRosterWindow = null;
}
- // Observe all tab closures. Clear the corresponding Gmail tracking entry.
- chrome.tabs.onRemoved.addListener(function(tabId) {
- if (tabIdToGmPort[tabId] != null) {
- delete tabIdToGmPort[tabId];
+ // Open central roster or give it focus.
+ function openCentralRosterWindow() {
+ if (!centralRosterWindow) {
+ centralRosterWindow = window.open(
+ chrome.extension.getURL('central_roster_viewer.html'),
+ 'centralRosterWindow',
+ 'width=300,height=360,resizable=0,menubar=0,scrollbars=0');
+ centralRosterWindow.backgroundDocument = document;
+ centralRosterWindow.onload = reparentCentralRosterToWindow;
+ centralRosterWindow.onbeforeunload = reparentCenterRosterToBackground;
+ } else {
+ centralRosterWindow.focus();
}
- });
+ }
+
+ // Notify all port listeners of updated central roster jid.
+ function forwardCentralRosterJidToPortListeners() {
+ for (var listenerPort in centralJidListenerPorts) {
+ listenerPort.postMessage({jid: centralRosterJid});
+ }
+ }
+
+ // Central roster jid changed. Notify all listeners.
+ function centralJidUpdate(msg) {
+ if (centralRosterJid != msg.jid) {
+ centralRosterJid = msg.jid;
+ forwardCentralRosterJidToPortListeners();
+ }
+ }
- // Listen for content script connections with Gmail pages and add a
- // corresponding tracking entry.
+ // Listen for content script connections.
chrome.extension.onConnect.addListener(function(port) {
- if (port.name == 'centralJidWatcher') {
- tabIdToGmPort[port.sender.tab.id] = port;
+ // New central jid listener.
+ // Update with current central roster jid, and add to tracking array.
+ if (port.name == 'centralJidListener') {
+ port.postMessage({jid: centralRosterJid});
+ centralJidListenerPorts.push(port);
+
+ // Clear tracking array entry when content script closes.
+ port.onDisconnect.addListener(function(port) {
+ for (var index = 0; index < centralJidListenerPorts.length; ++index) {
+ var listenerPort = centralJidListenerPorts[index];
+ if (listenerPort == port) {
+ centralJidListenerPorts.splice(index, 1);
+ break;
+ }
+ }
+ });
+ // New central jid broadcaster.
+ // Add listener for jid changes, and track port for forwarding chats.
+ } else if (port.name == 'centralJidBroadcaster') {
+ if (centralRosterPort != port) {
+ if (centralRosterPort) {
+ centralRosterPort.onMessage.removeListener(centralJidUpdate);
+ }
+ centralRosterPort = port;
+ centralRosterPort.onMessage.addListener(centralJidUpdate);
+
+ // Clear listener and central roster jid when content script closes
+ centralRosterPort.onDisconnect.addListener(function(port) {
+ if (centralRosterPort) {
+ centralRosterPort.onMessage.removeListener(centralJidUpdate);
+ centralRosterPort = null;
+ centralJidUpdate({jid: null});
+ }
+ });
+ }
}
});
// Listen for requests from our content scripts.
chrome.extension.onRequest.addListener(function(request, sender) {
switch (request.msg) {
- // For new initiated chats, forward to this page's GTalk client.
+ // For new initiated chats, forward to the central roster port.
case ChatBridgeEventTypes.SHOW_CHAT:
- if (chatClient != null) {
- chatClient._showChat(request.jid);
- }
- break;
case ChatBridgeEventTypes.START_VIDEO:
- if (chatClient != null) {
- chatClient._startVideoChat(request.jid);
- }
- break;
case ChatBridgeEventTypes.START_VOICE:
- if (chatClient != null) {
- chatClient._startVoiceChat(request.jid);
- }
- break;
- // For changes in the central roster, forward to all Gmail pages.
- case ChatBridgeEventTypes.CENTRAL_USER_UPDATE:
- if (centralRosterJid != request.jid) {
- centralRosterJid = request.jid;
- forwardCentralRosterJidToGmPorts();
+ if (centralRosterPort) {
+ centralRosterPort.postMessage(
+ {chatType: request.msg, jid: request.jid});
+ } else {
+ // We should not have been forwarded this message. Make sure our
+ // listeners are updated with the current central roster jid.
+ forwardCentralRosterJidToPortListeners();
}
break;
- // For a request of the latest central roster jid, respond back to the
- // requesting port.
- case ChatBridgeEventTypes.REQUEST_CENTRAL_USER:
- var tabId = sender.tab.id;
- var port = tabIdToGmPort[tabId];
- if (port != null) {
- port.postMessage({jid: centralRosterJid});
- }
+ case ChatBridgeEventTypes.OPEN_CENTRAL_ROSTER:
+ openCentralRosterWindow();
break;
}
});
diff --git a/chrome/browser/resources/chat_manager/central_roster.html b/chrome/browser/resources/chat_manager/central_roster.html
new file mode 100644
index 0000000..41df51e
--- /dev/null
+++ b/chrome/browser/resources/chat_manager/central_roster.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html>
+<!--
+
+Copyright (c) 2010 The Chromium Authors. All rights reserved.
+Use of this source code is governed by a BSD-style license that can be
+found in the LICENSE file.
+
+Central roster: hosting all Google Talk chats in ChromeOS.
+
+-->
+<body>
+<style>
+ .talk_roster {
+ position: fixed;
+ left: 0px;
+ top: 0px;
+ }
+ .talk_iframe {
+ width: 100%;
+ height: 100%;
+ border: none;
+ overflow-x: hidden;
+ overflow-y: hidden;
+ }
+</style>
+<script>
+ var args = {
+ 'protocol': 'https',
+ 'host': 'talkgadget.google.com',
+ 'jsmode': 'pre',
+ 'hl': 'en',
+ };
+ // Read args.
+ var urlParts = window.location.href.split(/[?&#]/);
+ for (var i = 1; i < urlParts.length; i++) {
+ var argParts = urlParts[i].split('=');
+ if (argParts.length == 2) {
+ args[argParts[0]] = argParts[1];
+ }
+ }
+ document.write('<script src="' +
+ args['protocol'] + '://' + args['host'] +
+ '/talkgadget/notifier-js?silent=true&host=' +
+ args['protocol'] + '://' + args['host'] +
+ '/talkgadget/notifier-js' +
+ (args['jsmode'] != '' ? ('&jsmode=' + args['jsmode']) : '') +
+ '"></scr' + 'ipt>');
+</script>
+<script>
+ var chatClient = null;
+ if (window.GTalkNotifier) {
+ chatClient = new GTalkNotifier(
+ args['protocol'] + '://' + args['host'] + '/talkgadget/',
+ 'notifierclient' +
+ (args['jsmode'] != '' ? ('?jsmode=' + args['jsmode']) : ''),
+ 'ifpc_relay',
+ 'ifpc.js',
+ 'Google Talk',
+ {
+ hostCallback: function(){},
+ xpcRelay: 'xpc_relay',
+ xpcBlank: 'xpc_blank',
+ locale: args['hl'],
+ isCentralRoster: true,
+ hideProfileCard: true
+ }
+ );
+ } else {
+ document.write(
+ '<div class="talk_roster"><b>GTalkNotifier undefined</b></div>');
+ }
+</script>
+</body>
+</html>
diff --git a/chrome/browser/resources/chat_manager/central_roster_viewer.html b/chrome/browser/resources/chat_manager/central_roster_viewer.html
new file mode 100644
index 0000000..2f18b7b
--- /dev/null
+++ b/chrome/browser/resources/chat_manager/central_roster_viewer.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<!--
+
+Copyright (c) 2010 The Chromium Authors. All rights reserved.
+Use of this source code is governed by a BSD-style license that can be
+found in the LICENSE file.
+
+-->
+ <head>
+ <title>Online friends</title>
+ <!-- Set height to 98% to get around bug in css calculation that triggers
+ a vertical scroll bar. -->
+ <style>
+ iframe {
+ border: 0px;
+ margin: 0px;
+ padding: 0px;
+ width: 100%;
+ height: 98%;
+ }
+ </style>
+ </head>
+ <body topmargin='0' leftmargin='0'>
+ <!-- Place for central roster -->
+ </body>
+</html>
diff --git a/chrome/browser/resources/chat_manager/js/centralrosterhook.js b/chrome/browser/resources/chat_manager/js/centralrosterhook.js
new file mode 100644
index 0000000..d9c70e7
--- /dev/null
+++ b/chrome/browser/resources/chat_manager/js/centralrosterhook.js
@@ -0,0 +1,12 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Search for communication channel div.
+var divOpenerHandler = document.getElementById('central_roster_opener');
+if (divOpenerHandler) {
+ divOpenerHandler.addEventListener(ChatBridgeEventTypes.OPEN_CENTRAL_ROSTER,
+ function(event) {
+ chrome.extension.sendRequest({msg: 'openCentralRoster'});
+ }, false);
+}
diff --git a/chrome/browser/resources/chat_manager/js/chatbridgeeventtypes.js b/chrome/browser/resources/chat_manager/js/chatbridgeeventtypes.js
index e2d6223..7563917 100644
--- a/chrome/browser/resources/chat_manager/js/chatbridgeeventtypes.js
+++ b/chrome/browser/resources/chat_manager/js/chatbridgeeventtypes.js
@@ -10,6 +10,8 @@ var ChatBridgeEventTypes = {
SHOW_CHAT: 'showChat',
START_VIDEO: 'startVideo',
START_VOICE: 'startVoice',
+ CENTRAL_USER_SET: 'centralJidSet',
CENTRAL_USER_UPDATE: 'centralJidUpdate',
- REQUEST_CENTRAL_USER: 'getCentralJid'
+ CENTRAL_USER_WATCHER: 'getCentralJid',
+ OPEN_CENTRAL_ROSTER: 'openCentralRoster'
};
diff --git a/chrome/browser/resources/chat_manager/js/chatbridgehook.js b/chrome/browser/resources/chat_manager/js/chatbridgehook.js
index 5e3854c..aae422f 100644
--- a/chrome/browser/resources/chat_manager/js/chatbridgehook.js
+++ b/chrome/browser/resources/chat_manager/js/chatbridgehook.js
@@ -2,23 +2,63 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// Port used for:
+// 1. forwarding updated central user from the chat page to the background.
+// 2. forwarding chats from the background to the chat page we're attached to.
+var centralJidBroadcasterPort;
+
+// Port used for:
+// 1. forwarding central user requests from the chat page to the background.
+// 2. forwarding the central user from the background to the chat page.
+var centralJidListenerChatPort;
+
+// The chat page div used to funnel events through.
+var divRosterHandler;
+
/**
- * Central user update listener triggered by a change in Chrome chat code.
- * @param {MessageEvent} event the user update event.
+ * Manage two-way communication with the central roster. Updated jid's are
+ * forwarded to the background, while chats are forwarded to the page.
+ * @param {MessageEvent} event the new central roster jid event.
*/
-function centralUserUpdate(event) {
+function centralRosterHandler(event) {
+ if (!centralJidBroadcasterPort) {
+ centralJidBroadcasterPort = chrome.extension.connect(
+ {name: 'centralJidBroadcaster'});
+ centralJidBroadcasterPort.onMessage.addListener(function(msg) {
+ var chatJid = msg.jid;
+ var showChatEvent = document.createEvent('MessageEvent');
+ showChatEvent.initMessageEvent(msg.chatType, true, true, chatJid);
+ divRosterHandler.dispatchEvent(showChatEvent);
+ });
+ }
var centralRosterJid = event.data;
- chrome.extension.sendRequest(
- {
- msg: ChatBridgeEventTypes.CENTRAL_USER_UPDATE,
- jid: centralRosterJid
- }
- );
+ centralJidBroadcasterPort.postMessage({jid: centralRosterJid});
+}
+
+/**
+ * Setup central roster jid listener.
+ * @param {MessageEvent} event the event.
+ */
+function setupCentralRosterJidListener(event) {
+ if (!centralJidListenerChatPort) {
+ centralJidListenerChatPort = chrome.extension.connect(
+ {name: 'centralJidListener'});
+ centralJidListenerChatPort.onMessage.addListener(function(msg) {
+ var centralRosterJid = msg.jid;
+ var outgoingChatEvent = document.createEvent('MessageEvent');
+ outgoingChatEvent.initMessageEvent(
+ ChatBridgeEventTypes.CENTRAL_USER_UPDATE,
+ true, true, centralRosterJid);
+ divRosterHandler.dispatchEvent(outgoingChatEvent);
+ });
+ }
}
// Search for communication channel div.
-var divRosterHandler = document.getElementById('roster_comm_link');
+divRosterHandler = document.getElementById('roster_comm_link');
if (divRosterHandler) {
- divRosterHandler.addEventListener(ChatBridgeEventTypes.CENTRAL_USER_UPDATE,
- centralUserUpdate, false);
+ divRosterHandler.addEventListener(ChatBridgeEventTypes.CENTRAL_USER_SET,
+ centralRosterHandler, false);
+ divRosterHandler.addEventListener(ChatBridgeEventTypes.CENTRAL_USER_WATCHER,
+ setupCentralRosterJidListener, false);
}
diff --git a/chrome/browser/resources/chat_manager/js/gmailbridgehook.js b/chrome/browser/resources/chat_manager/js/gmailbridgehook.js
index c1c4583..54b9b2f 100644
--- a/chrome/browser/resources/chat_manager/js/gmailbridgehook.js
+++ b/chrome/browser/resources/chat_manager/js/gmailbridgehook.js
@@ -2,6 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// Port used for:
+// 1. forwarding central user requests from the gmail page to the background.
+// 2. forwarding the central user from the background to the gmail page.
+var centralJidListenerGmailPort;
+
+// The gmail page div used to funnel events through.
+var divGmailHandler;
+
/**
* Triggered on a user initiated chat request. Forward to extension to be
* processed by the Chrome central roster.
@@ -13,42 +21,33 @@ function forwardChatEvent(event) {
}
/**
- * Triggered by Gmail on startup to request the current central roster jid.
- * @param {MessageEvent} event the central roster jid request event.
+ * Setup central roster jid listener.
+ * @param {MessageEvent} event the event.
*/
-function requestCentralUserJid(event) {
- chrome.extension.sendRequest(
- {msg: ChatBridgeEventTypes.REQUEST_CENTRAL_USER});
+function setupCentralRosterJidListener(event) {
+ if (!centralJidListenerGmailPort) {
+ centralJidListenerGmailPort = chrome.extension.connect(
+ {name: 'centralJidListener'});
+ centralJidListenerGmailPort.onMessage.addListener(function(msg) {
+ var centralRosterJid = msg.jid;
+ var outgoingChatEvent = document.createEvent('MessageEvent');
+ outgoingChatEvent.initMessageEvent(
+ ChatBridgeEventTypes.CENTRAL_USER_UPDATE,
+ true, true, centralRosterJid);
+ divGmailHandler.dispatchEvent(outgoingChatEvent);
+ });
+ }
}
-/**
- * Initialize a communication channel with a Gmail chat component and the
- * Chrome extension background logic.
- * @param {HTMLElement} divHandler the div element used to communicate.
- */
-function attachToDivGmHandler(divHandler) {
- divHandler.addEventListener(ChatBridgeEventTypes.SHOW_CHAT,
+// Search for communication channel div.
+divGmailHandler = document.getElementById('mainElement');
+if (divGmailHandler) {
+ divGmailHandler.addEventListener(ChatBridgeEventTypes.SHOW_CHAT,
forwardChatEvent, false);
- divHandler.addEventListener(ChatBridgeEventTypes.START_VIDEO,
+ divGmailHandler.addEventListener(ChatBridgeEventTypes.START_VIDEO,
forwardChatEvent, false);
- divHandler.addEventListener(ChatBridgeEventTypes.START_VOICE,
+ divGmailHandler.addEventListener(ChatBridgeEventTypes.START_VOICE,
forwardChatEvent, false);
- divHandler.addEventListener(ChatBridgeEventTypes.REQUEST_CENTRAL_USER,
- requestCentralUserJid, false);
- // Set up a direct channel with the extension to forward updated central
- // roster jid's.
- var port = chrome.extension.connect({name: 'centralJidWatcher'});
- port.onMessage.addListener(function(msg) {
- var centralRosterJid = msg.jid;
- var outgoingChatEvent = document.createEvent('MessageEvent');
- outgoingChatEvent.initMessageEvent(
- ChatBridgeEventTypes.CENTRAL_USER_UPDATE, true, true, centralRosterJid);
- divHandler.dispatchEvent(outgoingChatEvent);
- });
-}
-
-// Search for communication channel div.
-var divGmailHandler = document.getElementById('mainElement');
-if (divGmailHandler) {
- attachToDivGmHandler(divGmailHandler);
+ divGmailHandler.addEventListener(ChatBridgeEventTypes.CENTRAL_USER_WATCHER,
+ setupCentralRosterJidListener, false);
}
diff --git a/chrome/browser/resources/chat_manager/manifest.json b/chrome/browser/resources/chat_manager/manifest.json
index 9d55ad4..baa6ddc 100644
--- a/chrome/browser/resources/chat_manager/manifest.json
+++ b/chrome/browser/resources/chat_manager/manifest.json
@@ -1,8 +1,8 @@
{
"key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDDrlwvcbUtVrbQvI7EPV1BTa63N8YkbBToHzxlMl0IzSBwOV+TUOsHE8vRq0HZWuwMAGeH8WdWVC3HRNdES8lScjlzxb1TsTQJAsF+hLXgcjgCUSSSGCfFzypvuvKsRQTx0d02yfWKJa47o0Ws5wL72NVtc7c51HujwWYg+Mz01wIDAQAB",
- "name": "Gmail to Chrome chat bridge (by Google)",
+ "name": "Chrome chat manager (by Google)",
"version": "1.0",
- "description": "Gmail to Chrome chat bridge",
+ "description": "Chrome chat manager",
"background_page": "background.html",
"content_scripts": [ {
"js": [
@@ -25,12 +25,21 @@
"https://mail.google.com/*"
],
"run_at": "document_end"
+ }, {
+ "js": [
+ "js/chatbridgeeventtypes.js",
+ "js/centralrosterhook.js"
+ ],
+ "matches": [
+ "file:///*/*",
+ "http://*/*",
+ "https://*/*"
+ ],
+ "run_at": "document_end"
}],
"permissions": [
"tabs",
"http://talkgadget.google.com/*",
- "https://talkgadget.google.com/*",
- "http://mail.google.com/*",
- "https://mail.google.com/*"
+ "https://talkgadget.google.com/*"
]
}