mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1005818 - Part 2: Only limited browser API are available to a widget. r=kanru
1. Add |ownerIsWidget| in nsIFrameLoader.idl 2. Add |GetReallyIsWidget| in nsIMozBrowserFrame.idl 3. Hide the methods of browser API of a widget 4. Hide security-sensitive mozbrowser events of a widget
This commit is contained in:
parent
7c8c44b873
commit
012e6ed0a7
@ -112,7 +112,7 @@ interface nsIContentViewManager : nsISupports
|
||||
readonly attribute nsIContentView rootContentView;
|
||||
};
|
||||
|
||||
[scriptable, builtinclass, uuid(d52ca6a8-8237-4ae0-91d7-7be4f1db24ef)]
|
||||
[scriptable, builtinclass, uuid(55a772b8-855a-4c5f-b4a1-284b6b3bec28)]
|
||||
interface nsIFrameLoader : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -291,6 +291,13 @@ interface nsIFrameLoader : nsISupports
|
||||
* Especially, a widget frame is regarded as an app frame.
|
||||
*/
|
||||
readonly attribute boolean ownerIsBrowserOrAppFrame;
|
||||
|
||||
/**
|
||||
* Find out whether the owner content really is a widget. If this attribute
|
||||
* returns true, |ownerIsBrowserOrAppFrame| must return true.
|
||||
*/
|
||||
readonly attribute boolean ownerIsWidget;
|
||||
|
||||
};
|
||||
|
||||
%{C++
|
||||
|
@ -1474,6 +1474,22 @@ nsFrameLoader::GetOwnerIsBrowserOrAppFrame(bool* aResult)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
nsFrameLoader::OwnerIsWidget()
|
||||
{
|
||||
nsCOMPtr<nsIMozBrowserFrame> browserFrame = do_QueryInterface(mOwnerContent);
|
||||
return browserFrame ? browserFrame->GetReallyIsWidget() : false;
|
||||
}
|
||||
|
||||
|
||||
// The xpcom getter version
|
||||
NS_IMETHODIMP
|
||||
nsFrameLoader::GetOwnerIsWidget(bool* aResult)
|
||||
{
|
||||
*aResult = OwnerIsWidget();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
nsFrameLoader::OwnerIsAppFrame()
|
||||
{
|
||||
|
@ -333,6 +333,12 @@ private:
|
||||
*/
|
||||
bool OwnerIsBrowserOrAppFrame();
|
||||
|
||||
/**
|
||||
* Is this a frameloader for a bona fide <iframe mozwidget>? (I.e., does the
|
||||
* frame return true for nsIMozBrowserFrame::GetReallyIsWidget()?)
|
||||
*/
|
||||
bool OwnerIsWidget();
|
||||
|
||||
/**
|
||||
* Is this a frameloader for a bona fide <iframe mozapp>? (I.e., does the
|
||||
* frame return true for nsIMozBrowserFrame::GetReallyIsApp()?)
|
||||
|
@ -319,6 +319,44 @@ nsGenericHTMLFrameElement::GetReallyIsApp(bool *aOut)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
bool WidgetsEnabled()
|
||||
{
|
||||
static bool sMozWidgetsEnabled = false;
|
||||
static bool sBoolVarCacheInitialized = false;
|
||||
|
||||
if (!sBoolVarCacheInitialized) {
|
||||
sBoolVarCacheInitialized = true;
|
||||
Preferences::AddBoolVarCache(&sMozWidgetsEnabled,
|
||||
"dom.enable_widgets");
|
||||
}
|
||||
|
||||
return sMozWidgetsEnabled;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
/* [infallible] */ NS_IMETHODIMP
|
||||
nsGenericHTMLFrameElement::GetReallyIsWidget(bool *aOut)
|
||||
{
|
||||
*aOut = false;
|
||||
if (!WidgetsEnabled()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsAutoString appManifestURL;
|
||||
GetManifestURLByType(nsGkAtoms::mozapp, appManifestURL);
|
||||
bool isApp = !appManifestURL.IsEmpty();
|
||||
|
||||
nsAutoString widgetManifestURL;
|
||||
GetManifestURLByType(nsGkAtoms::mozwidget, widgetManifestURL);
|
||||
bool isWidget = !widgetManifestURL.IsEmpty();
|
||||
|
||||
*aOut = isWidget && !isApp;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* [infallible] */ NS_IMETHODIMP
|
||||
nsGenericHTMLFrameElement::GetIsExpectingSystemMessage(bool *aOut)
|
||||
{
|
||||
@ -404,7 +442,7 @@ nsGenericHTMLFrameElement::GetAppManifestURL(nsAString& aOut)
|
||||
|
||||
GetManifestURLByType(nsGkAtoms::mozapp, appManifestURL);
|
||||
|
||||
if (Preferences::GetBool("dom.enable_widgets")) {
|
||||
if (WidgetsEnabled()) {
|
||||
GetManifestURLByType(nsGkAtoms::mozwidget, widgetManifestURL);
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,7 @@ function handleRequest(request, response) {
|
||||
|
||||
// Get the app type.
|
||||
var apptype = query.apptype;
|
||||
if (apptype != 'hosted' && apptype != 'cached' && apptype != 'widget')
|
||||
if (apptype != 'hosted' && apptype != 'cached' && apptype != 'widget' && apptype != 'invalidWidget')
|
||||
throw "Invalid app type: " + apptype;
|
||||
|
||||
// Get the version from server state and handle the etag.
|
||||
@ -83,7 +83,7 @@ function handleRequest(request, response) {
|
||||
response.write(makeResource(gAppcacheTemplatePath, version, apptype));
|
||||
return;
|
||||
}
|
||||
else if (apptype == 'widget')
|
||||
else if (apptype == 'widget' || apptype == 'invalidWidget')
|
||||
{
|
||||
response.setHeader("Content-Type", "text/html", false);
|
||||
response.write(makeResource(gWidgetTemplatePath, version, apptype));
|
||||
|
11
dom/apps/tests/file_invalidWidget_app.template.webapp
Normal file
11
dom/apps/tests/file_invalidWidget_app.template.webapp
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "Really Rapid Release (invalid widget)",
|
||||
"description": "Updated even faster than <a href='http://mozilla.org'>Firefox</a>, just to annoy slashdotters.",
|
||||
"launch_path": "/tests/dom/apps/tests/file_app.sjs?apptype=invalidWidget",
|
||||
"icons": {
|
||||
"128": "ICONTOKEN"
|
||||
},
|
||||
"widgetPages": [
|
||||
"/tests/dom/apps/tests/file_app.sjs?apptype=widget"
|
||||
]
|
||||
}
|
@ -1,68 +1,8 @@
|
||||
<html>
|
||||
<head>
|
||||
<script>
|
||||
|
||||
function sendMessage(msg) {
|
||||
alert(msg);
|
||||
}
|
||||
|
||||
function ok(p, msg) {
|
||||
if (p)
|
||||
sendMessage("OK: " + msg);
|
||||
else
|
||||
sendMessage("KO: " + msg);
|
||||
}
|
||||
|
||||
function is(a, b, msg) {
|
||||
if (a == b)
|
||||
sendMessage("OK: " + a + " == " + b + " - " + msg);
|
||||
else
|
||||
sendMessage("KO: " + a + " != " + b + " - " + msg);
|
||||
}
|
||||
|
||||
function installed(p) {
|
||||
if (p)
|
||||
sendMessage("IS_INSTALLED");
|
||||
else
|
||||
sendMessage("NOT_INSTALLED");
|
||||
}
|
||||
|
||||
function finish() {
|
||||
sendMessage("VERSION: MyWebApp vVERSIONTOKEN");
|
||||
sendMessage("DONE");
|
||||
}
|
||||
|
||||
function cbError() {
|
||||
ok(false, "Error callback invoked");
|
||||
finish();
|
||||
}
|
||||
|
||||
function go() {
|
||||
ok(true, "Launched app");
|
||||
var request = window.navigator.mozApps.getSelf();
|
||||
request.onsuccess = function() {
|
||||
var widget = request.result;
|
||||
ok(widget,"Should be a widget");
|
||||
checkWidget(widget);
|
||||
}
|
||||
request.onerror = cbError;
|
||||
}
|
||||
|
||||
function checkWidget(widget) {
|
||||
// If the widget is installed, |widget| will be non-null. If it is, verify its state.
|
||||
installed(!!widget);
|
||||
if (widget) {
|
||||
var widgetName = "Really Rapid Release (APPTYPETOKEN)";
|
||||
var manifest = SpecialPowers.wrap(widget.manifest);
|
||||
is(manifest.name, widgetName, "Manifest name should be correct");
|
||||
is(widget.origin, "http://test", "Widget origin should be correct");
|
||||
is(widget.installOrigin, "http://mochi.test:8888", "Install origin should be correct");
|
||||
}
|
||||
finish();
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body onload="go();">
|
||||
<body>
|
||||
App Body. Version: VERSIONTOKEN
|
||||
</body></html>
|
||||
<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />
|
||||
</body>
|
||||
</html>
|
||||
|
@ -7,6 +7,7 @@ support-files =
|
||||
file_cached_app.template.appcache
|
||||
file_cached_app.template.webapp
|
||||
file_hosted_app.template.webapp
|
||||
file_invalidWidget_app.template.webapp
|
||||
file_packaged_app.sjs
|
||||
file_packaged_app.template.html
|
||||
file_packaged_app.template.webapp
|
||||
|
@ -11,16 +11,17 @@
|
||||
<script type="application/javascript;version=1.7">
|
||||
|
||||
var gWidgetManifestURL = 'http://test/tests/dom/apps/tests/file_app.sjs?apptype=widget&getmanifest=true';
|
||||
var gInvalidWidgetManifestURL = 'http://test/tests/dom/apps/tests/file_app.sjs?apptype=invalidWidget&getmanifest=true';
|
||||
var gApp;
|
||||
|
||||
function cbError() {
|
||||
function onError() {
|
||||
ok(false, "Error callback invoked");
|
||||
finish();
|
||||
}
|
||||
|
||||
function installApp() {
|
||||
var request = navigator.mozApps.install(gWidgetManifestURL);
|
||||
request.onerror = cbError;
|
||||
function installApp(path) {
|
||||
var request = navigator.mozApps.install(path);
|
||||
request.onerror = onError;
|
||||
request.onsuccess = function() {
|
||||
gApp = request.result;
|
||||
|
||||
@ -31,40 +32,134 @@
|
||||
function uninstallApp() {
|
||||
// Uninstall the app.
|
||||
var request = navigator.mozApps.mgmt.uninstall(gApp);
|
||||
request.onerror = cbError;
|
||||
request.onerror = onError;
|
||||
request.onsuccess = function() {
|
||||
// All done.
|
||||
info("All done");
|
||||
|
||||
runTest();
|
||||
}
|
||||
}
|
||||
|
||||
function testApp() {
|
||||
function testApp(isValidWidget) {
|
||||
info("Test widget feature. IsValidWidget: " + isValidWidget);
|
||||
|
||||
var ifr = document.createElement('iframe');
|
||||
ifr.setAttribute('mozbrowser', 'true');
|
||||
ifr.setAttribute('mozwidget', gApp.manifestURL);
|
||||
ifr.setAttribute('src', gApp.origin+gApp.manifest.launch_path);
|
||||
|
||||
var domParent = document.getElementById('container');
|
||||
domParent.appendChild(ifr);
|
||||
|
||||
// Set us up to listen for messages from the app.
|
||||
var listener = function(e) {
|
||||
var message = e.detail.message;
|
||||
if (/^OK/.exec(message)) {
|
||||
ok(true, "Message from widget: " + message);
|
||||
} else if (/KO/.exec(message)) {
|
||||
ok(false, "Message from widget: " + message);
|
||||
} else if (/DONE/.exec(message)) {
|
||||
ok(true, "Message from widget complete");
|
||||
ifr.removeEventListener('mozbrowsershowmodalprompt', listener);
|
||||
domParent.removeChild(ifr);
|
||||
runTest();
|
||||
var mm = SpecialPowers.getBrowserFrameMessageManager(ifr);
|
||||
mm.addMessageListener('OK', function(msg) {
|
||||
ok(isValidWidget, "Message from widget: " + SpecialPowers.wrap(msg).json);
|
||||
});
|
||||
mm.addMessageListener('KO', function(msg) {
|
||||
ok(!isValidWidget, "Message from widget: " + SpecialPowers.wrap(msg).json);
|
||||
});
|
||||
mm.addMessageListener('DONE', function(msg) {
|
||||
ok(true, "Message from widget complete: "+SpecialPowers.wrap(msg).json);
|
||||
domParent.removeChild(ifr);
|
||||
runTest();
|
||||
});
|
||||
|
||||
ifr.addEventListener('mozbrowserloadend', function() {
|
||||
ok(true, "receive mozbrowserloadend");
|
||||
|
||||
// Test limited browser API feature only for valid widget case
|
||||
if (isValidWidget) {
|
||||
testLimitedBrowserAPI(ifr);
|
||||
}
|
||||
SimpleTest.executeSoon(()=>loadFrameScript(mm));
|
||||
}, false);
|
||||
|
||||
// Test limited browser API feature only for valid widget case
|
||||
if (!isValidWidget) {
|
||||
return;
|
||||
}
|
||||
|
||||
// This event is triggered when the app calls "alert".
|
||||
ifr.addEventListener('mozbrowsershowmodalprompt', listener, false);
|
||||
domParent.appendChild(ifr);
|
||||
[
|
||||
'mozbrowsertitlechange',
|
||||
'mozbrowseropenwindow',
|
||||
'mozbrowserscroll',
|
||||
'mozbrowserasyncscroll'
|
||||
].forEach( function(topic) {
|
||||
ifr.addEventListener(topic, function() {
|
||||
ok(false, topic + " should be hidden");
|
||||
}, false);
|
||||
});
|
||||
}
|
||||
|
||||
function testLimitedBrowserAPI(ifr) {
|
||||
var securitySensitiveCalls = [
|
||||
'sendMouseEvent',
|
||||
'sendTouchEvent',
|
||||
'goBack',
|
||||
'goForward',
|
||||
'reload',
|
||||
'stop',
|
||||
'download',
|
||||
'purgeHistory',
|
||||
'getScreenshot',
|
||||
'zoom',
|
||||
'getCanGoBack',
|
||||
'getCanGoForward'
|
||||
];
|
||||
securitySensitiveCalls.forEach( function(call) {
|
||||
is(typeof ifr[call], "undefined", call + " should be hidden for widget");
|
||||
});
|
||||
}
|
||||
|
||||
function loadFrameScript(mm) {
|
||||
var script = 'data:,\
|
||||
function ok(p, msg) { \
|
||||
if (p) { \
|
||||
sendAsyncMessage("OK", msg); \
|
||||
} else { \
|
||||
sendAsyncMessage("KO", msg); \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
function is(a, b, msg) { \
|
||||
if (a == b) { \
|
||||
sendAsyncMessage("OK", a + " == " + b + " - " + msg); \
|
||||
} else { \
|
||||
sendAsyncMessage("KO", a + " != " + b + " - " + msg); \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
function finish() { \
|
||||
sendAsyncMessage("DONE",""); \
|
||||
} \
|
||||
\
|
||||
function onError() { \
|
||||
ok(false, "Error callback invoked"); \
|
||||
finish(); \
|
||||
} \
|
||||
\
|
||||
function checkWidget(widget) { \
|
||||
/*For invalid widget case, ignore the following check*/\
|
||||
if (widget) { \
|
||||
var widgetName = "Really Rapid Release (APPTYPETOKEN)"; \
|
||||
is(widget.origin, "http://test", "Widget origin should be correct"); \
|
||||
is(widget.installOrigin, "http://mochi.test:8888", "Install origin should be correct"); \
|
||||
} \
|
||||
finish(); \
|
||||
} \
|
||||
\
|
||||
var request = content.window.navigator.mozApps.getSelf(); \
|
||||
request.onsuccess = function() { \
|
||||
var widget = request.result; \
|
||||
ok(widget,"Should be a widget"); \
|
||||
checkWidget(widget); \
|
||||
}; \
|
||||
request.onerror = onError; \
|
||||
content.window.open("about:blank"); /*test mozbrowseropenwindow*/ \
|
||||
content.window.scrollTo(4000, 4000); /*test mozbrowser(async)scroll*/ \
|
||||
';
|
||||
mm.loadFrameScript(script, /* allowDelayedLoad = */ false);
|
||||
}
|
||||
|
||||
var tests = [
|
||||
@ -93,10 +188,19 @@
|
||||
},
|
||||
|
||||
// Installing the app
|
||||
installApp,
|
||||
()=>installApp(gWidgetManifestURL),
|
||||
|
||||
// Run tests in app
|
||||
testApp,
|
||||
()=>testApp(true),
|
||||
|
||||
// Uninstall the app
|
||||
uninstallApp,
|
||||
|
||||
// Installing the app for invalid widget case
|
||||
()=>installApp(gInvalidWidgetManifestURL),
|
||||
|
||||
// Run tests in app for invalid widget case
|
||||
()=>testApp(false),
|
||||
|
||||
// Uninstall the app
|
||||
uninstallApp
|
||||
|
@ -164,6 +164,13 @@ BrowserElementParent::DispatchOpenWindowEvent(Element* aOpenerFrameElement,
|
||||
return BrowserElementParent::OPEN_WINDOW_IGNORED;
|
||||
}
|
||||
|
||||
// Do not dispatch a mozbrowseropenwindow event of a widget to its embedder
|
||||
nsCOMPtr<nsIMozBrowserFrame> browserFrame =
|
||||
do_QueryInterface(aOpenerFrameElement);
|
||||
if (browserFrame && browserFrame->GetReallyIsWidget()) {
|
||||
return BrowserElementParent::OPEN_WINDOW_CANCELLED;
|
||||
}
|
||||
|
||||
nsEventStatus status;
|
||||
bool dispatchSucceeded =
|
||||
DispatchCustomDOMEvent(aOpenerFrameElement,
|
||||
@ -349,6 +356,14 @@ BrowserElementParent::DispatchAsyncScrollEvent(TabParent* aTabParent,
|
||||
const CSSRect& aContentRect,
|
||||
const CSSSize& aContentSize)
|
||||
{
|
||||
// Do not dispatch a mozbrowserasyncscroll event of a widget to its embedder
|
||||
nsCOMPtr<Element> frameElement = aTabParent->GetOwnerElement();
|
||||
NS_ENSURE_TRUE(frameElement, false);
|
||||
nsCOMPtr<nsIMozBrowserFrame> browserFrame = do_QueryInterface(frameElement);
|
||||
if (browserFrame && browserFrame->GetReallyIsWidget()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsRefPtr<DispatchAsyncScrollEventRunnable> runnable =
|
||||
new DispatchAsyncScrollEventRunnable(aTabParent, aContentRect,
|
||||
aContentSize);
|
||||
|
@ -116,24 +116,30 @@ function BrowserElementParent(frameLoader, hasRemoteFrame, isPendingFrame) {
|
||||
// Define methods on the frame element.
|
||||
defineNoReturnMethod('setVisible', this._setVisible);
|
||||
defineDOMRequestMethod('getVisible', 'get-visible');
|
||||
defineNoReturnMethod('sendMouseEvent', this._sendMouseEvent);
|
||||
|
||||
// 0 = disabled, 1 = enabled, 2 - auto detect
|
||||
if (getIntPref(TOUCH_EVENTS_ENABLED_PREF, 0) != 0) {
|
||||
defineNoReturnMethod('sendTouchEvent', this._sendTouchEvent);
|
||||
// Not expose security sensitive browser API for widgets
|
||||
if (!this._frameLoader.QueryInterface(Ci.nsIFrameLoader).ownerIsWidget) {
|
||||
defineNoReturnMethod('sendMouseEvent', this._sendMouseEvent);
|
||||
|
||||
// 0 = disabled, 1 = enabled, 2 - auto detect
|
||||
if (getIntPref(TOUCH_EVENTS_ENABLED_PREF, 0) != 0) {
|
||||
defineNoReturnMethod('sendTouchEvent', this._sendTouchEvent);
|
||||
}
|
||||
defineNoReturnMethod('goBack', this._goBack);
|
||||
defineNoReturnMethod('goForward', this._goForward);
|
||||
defineNoReturnMethod('reload', this._reload);
|
||||
defineNoReturnMethod('stop', this._stop);
|
||||
defineMethod('download', this._download);
|
||||
defineDOMRequestMethod('purgeHistory', 'purge-history');
|
||||
defineMethod('getScreenshot', this._getScreenshot);
|
||||
defineNoReturnMethod('zoom', this._zoom);
|
||||
|
||||
defineDOMRequestMethod('getCanGoBack', 'get-can-go-back');
|
||||
defineDOMRequestMethod('getCanGoForward', 'get-can-go-forward');
|
||||
}
|
||||
defineNoReturnMethod('goBack', this._goBack);
|
||||
defineNoReturnMethod('goForward', this._goForward);
|
||||
defineNoReturnMethod('reload', this._reload);
|
||||
defineNoReturnMethod('stop', this._stop);
|
||||
defineNoReturnMethod('zoom', this._zoom);
|
||||
defineMethod('download', this._download);
|
||||
defineDOMRequestMethod('purgeHistory', 'purge-history');
|
||||
defineMethod('getScreenshot', this._getScreenshot);
|
||||
|
||||
defineMethod('addNextPaintListener', this._addNextPaintListener);
|
||||
defineMethod('removeNextPaintListener', this._removeNextPaintListener);
|
||||
defineDOMRequestMethod('getCanGoBack', 'get-can-go-back');
|
||||
defineDOMRequestMethod('getCanGoForward', 'get-can-go-forward');
|
||||
|
||||
let principal = this._frameElement.ownerDocument.nodePrincipal;
|
||||
let perm = Services.perms
|
||||
@ -217,6 +223,9 @@ BrowserElementParent.prototype = {
|
||||
_setupMessageListener: function() {
|
||||
this._mm = this._frameLoader.messageManager;
|
||||
let self = this;
|
||||
let isWidget = this._frameLoader
|
||||
.QueryInterface(Ci.nsIFrameLoader)
|
||||
.ownerIsWidget;
|
||||
|
||||
// Messages we receive are handed to functions which take a (data) argument,
|
||||
// where |data| is the message manager's data object.
|
||||
@ -224,26 +233,14 @@ BrowserElementParent.prototype = {
|
||||
// on data.msg_name
|
||||
let mmCalls = {
|
||||
"hello": this._recvHello,
|
||||
"contextmenu": this._fireCtxMenuEvent,
|
||||
"locationchange": this._fireEventFromMsg,
|
||||
"loadstart": this._fireProfiledEventFromMsg,
|
||||
"loadend": this._fireProfiledEventFromMsg,
|
||||
"titlechange": this._fireProfiledEventFromMsg,
|
||||
"iconchange": this._fireEventFromMsg,
|
||||
"manifestchange": this._fireEventFromMsg,
|
||||
"metachange": this._fireEventFromMsg,
|
||||
"close": this._fireEventFromMsg,
|
||||
"resize": this._fireEventFromMsg,
|
||||
"activitydone": this._fireEventFromMsg,
|
||||
"opensearch": this._fireEventFromMsg,
|
||||
"securitychange": this._fireEventFromMsg,
|
||||
"error": this._fireEventFromMsg,
|
||||
"scroll": this._fireEventFromMsg,
|
||||
"firstpaint": this._fireProfiledEventFromMsg,
|
||||
"documentfirstpaint": this._fireProfiledEventFromMsg,
|
||||
"nextpaint": this._recvNextPaint,
|
||||
"keyevent": this._fireKeyEvent,
|
||||
"showmodalprompt": this._handleShowModalPrompt,
|
||||
"got-purge-history": this._gotDOMRequestResult,
|
||||
"got-screenshot": this._gotDOMRequestResult,
|
||||
"got-can-go-back": this._gotDOMRequestResult,
|
||||
@ -257,9 +254,31 @@ BrowserElementParent.prototype = {
|
||||
"selectionchange": this._handleSelectionChange
|
||||
};
|
||||
|
||||
let mmSecuritySensitiveCalls = {
|
||||
"showmodalprompt": this._handleShowModalPrompt,
|
||||
"contextmenu": this._fireCtxMenuEvent,
|
||||
"securitychange": this._fireEventFromMsg,
|
||||
"locationchange": this._fireEventFromMsg,
|
||||
"iconchange": this._fireEventFromMsg,
|
||||
"titlechange": this._fireProfiledEventFromMsg,
|
||||
"opensearch": this._fireEventFromMsg,
|
||||
"manifestchange": this._fireEventFromMsg,
|
||||
"metachange": this._fireEventFromMsg,
|
||||
"resize": this._fireEventFromMsg,
|
||||
"activitydone": this._fireEventFromMsg,
|
||||
"scroll": this._fireEventFromMsg
|
||||
};
|
||||
|
||||
this._mm.addMessageListener('browser-element-api:call', function(aMsg) {
|
||||
if (self._isAlive() && (aMsg.data.msg_name in mmCalls)) {
|
||||
if (!self._isAlive()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (aMsg.data.msg_name in mmCalls) {
|
||||
return mmCalls[aMsg.data.msg_name].apply(self, arguments);
|
||||
} else if (!isWidget && aMsg.data.msg_name in mmSecuritySensitiveCalls) {
|
||||
return mmSecuritySensitiveCalls[aMsg.data.msg_name]
|
||||
.apply(self, arguments);
|
||||
}
|
||||
});
|
||||
},
|
||||
@ -294,26 +313,29 @@ BrowserElementParent.prototype = {
|
||||
}
|
||||
};
|
||||
|
||||
if (authDetail.isOnlyPassword) {
|
||||
// We don't handle password-only prompts, so just cancel it.
|
||||
// 1. We don't handle password-only prompts.
|
||||
// 2. We don't handle for widget case because of security concern.
|
||||
if (authDetail.isOnlyPassword ||
|
||||
this._frameLoader.QueryInterface(Ci.nsIFrameLoader).ownerIsWidget) {
|
||||
cancelCallback();
|
||||
return;
|
||||
} else { /* username and password */
|
||||
let detail = {
|
||||
host: authDetail.host,
|
||||
realm: authDetail.realm
|
||||
};
|
||||
|
||||
evt = this._createEvent('usernameandpasswordrequired', detail,
|
||||
/* cancelable */ true);
|
||||
Cu.exportFunction(function(username, password) {
|
||||
if (callbackCalled)
|
||||
return;
|
||||
callbackCalled = true;
|
||||
callback(true, username, password);
|
||||
}, evt.detail, { defineAs: 'authenticate' });
|
||||
}
|
||||
|
||||
/* username and password */
|
||||
let detail = {
|
||||
host: authDetail.host,
|
||||
realm: authDetail.realm
|
||||
};
|
||||
|
||||
evt = this._createEvent('usernameandpasswordrequired', detail,
|
||||
/* cancelable */ true);
|
||||
Cu.exportFunction(function(username, password) {
|
||||
if (callbackCalled)
|
||||
return;
|
||||
callbackCalled = true;
|
||||
callback(true, username, password);
|
||||
}, evt.detail, { defineAs: 'authenticate' });
|
||||
|
||||
Cu.exportFunction(cancelCallback, evt.detail, { defineAs: 'cancel' });
|
||||
|
||||
this._frameElement.dispatchEvent(evt);
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
interface nsITabParent;
|
||||
|
||||
[scriptable, builtinclass, uuid(929AED00-3E15-49B7-8CA2-75003715B7E7)]
|
||||
[scriptable, builtinclass, uuid(0c0a862c-1a47-43c0-ae9e-d51835e3e1a6)]
|
||||
interface nsIMozBrowserFrame : nsIDOMMozBrowserFrame
|
||||
{
|
||||
/**
|
||||
@ -33,6 +33,16 @@ interface nsIMozBrowserFrame : nsIDOMMozBrowserFrame
|
||||
*/
|
||||
[infallible] readonly attribute boolean reallyIsApp;
|
||||
|
||||
/**
|
||||
* Gets whether this frame really is a widget frame.
|
||||
*
|
||||
* In order to really be a frame, this frame must really be a browser
|
||||
* frame (this requirement will go away eventually), the frame's mozwidget
|
||||
* attribute must point to the manifest of a valid app, and the src should
|
||||
* be in the |widgetPages| specified by the manifest.
|
||||
*/
|
||||
[infallible] readonly attribute boolean reallyIsWidget;
|
||||
|
||||
/**
|
||||
* This corresponds to the expecting-system-message attribute, which tells us
|
||||
* whether we should expect that this frame will receive a system message once
|
||||
|
Loading…
Reference in New Issue
Block a user