1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
6 * @fileoverview Provides a representation of a web request sender, and
7 * utility functions for creating them.
14 * tlsChannelId: (string|undefined),
15 * tabId: (number|undefined)
21 * Creates an object representing the sender's origin, and, if available,
23 * @param {MessageSender} messageSender The message sender.
24 * @return {?WebRequestSender} The sender's origin and tab, or null if the
27 function createSenderFromMessageSender(messageSender
) {
28 var origin
= getOriginFromUrl(/** @type {string} */ (messageSender
.url
));
35 if (messageSender
.tlsChannelId
) {
36 sender
.tlsChannelId
= messageSender
.tlsChannelId
;
38 if (messageSender
.tab
) {
39 sender
.tabId
= messageSender
.tab
.id
;
45 * Checks whether the given tab could have sent a message from the given
47 * @param {Tab} tab The tab to match
48 * @param {string} origin The origin to check.
49 * @return {Promise} A promise resolved with the tab id if it the tab could,
50 * have sent the request, and rejected if it can't.
52 function tabMatchesOrigin(tab
, origin
) {
53 // If the tab's origin matches, trust that the request came from this tab.
54 if (getOriginFromUrl(tab
.url
) == origin
) {
55 return Promise
.resolve(tab
.id
);
57 return Promise
.reject(false);
61 * Attempts to ensure that the tabId of the sender is set, using chrome.tabs
63 * @param {WebRequestSender} sender The request sender.
64 * @return {Promise} A promise resolved once the tabId retrieval is done.
65 * The promise is rejected if the tabId is untrustworthy, e.g. if the
66 * user rapidly switched tabs.
68 function getTabIdWhenPossible(sender
) {
70 // Already got it? Done.
71 return Promise
.resolve(true);
72 } else if (!chrome
.tabs
) {
73 // Can't get it? Done. (This happens to packaged apps, which can't access
75 return Promise
.resolve(true);
77 return new Promise(function(resolve
, reject
) {
78 chrome
.tabs
.query({active
: true, lastFocusedWindow
: true},
86 tabMatchesOrigin(tab
, sender
.origin
).then(function(tabId
) {
90 // Didn't match? Check if the debugger is open.
91 if (tab
.url
.indexOf('chrome-devtools://') != 0) {
95 // Debugger active: find first tab with the sender's origin.
96 chrome
.tabs
.query({active
: true}, function(tabs
) {
103 for (var i
= 0; i
< tabs
.length
; i
++) {
105 tabMatchesOrigin(tab
, sender
.origin
).then(function(tabId
) {
106 sender
.tabId
= tabId
;
109 if (++numRejected
>= tabs
.length
) {
110 // None matches: reject.
123 * Checks whether the given tab is in the foreground, i.e. is the active tab
124 * of the focused window.
125 * @param {number} tabId The tab id to check.
126 * @return {Promise<boolean>} A promise for the result of the check.
128 function tabInForeground(tabId
) {
129 return new Promise(function(resolve
, reject
) {
130 if (!chrome
.tabs
|| !chrome
.tabs
.get) {
134 if (!chrome
.windows
|| !chrome
.windows
.get) {
138 chrome
.tabs
.get(tabId
, function(tab
) {
139 if (chrome
.runtime
.lastError
) {
147 chrome
.windows
.get(tab
.windowId
, function(aWindow
) {
148 resolve(aWindow
&& aWindow
.focused
);