Bug 983920 - Port window.sidebar and window.external to WebIDL; r=bzbarsky

This commit is contained in:
Ehsan Akhgari 2014-03-28 00:03:03 -04:00
parent ad9b3c4609
commit 0f3af82c2d
19 changed files with 135 additions and 79 deletions

View File

@ -10,9 +10,6 @@ const DEBUG = false; /* set to false to suppress debug messages */
const SIDEBAR_CONTRACTID = "@mozilla.org/sidebar;1";
const SIDEBAR_CID = Components.ID("{22117140-9c6e-11d3-aaf1-00805f8a4905}");
const nsISidebar = Components.interfaces.nsISidebar;
const nsISidebarExternal = Components.interfaces.nsISidebarExternal;
const nsIClassInfo = Components.interfaces.nsIClassInfo;
// File extension for Sherlock search plugin description files
const SHERLOCK_FILE_EXT_REGEXP = /\.src$/i;
@ -119,13 +116,7 @@ function (aSearchURL)
return 0;
}
nsSidebar.prototype.classInfo = XPCOMUtils.generateCI({classID: SIDEBAR_CID,
contractID: SIDEBAR_CONTRACTID,
classDescription: "Sidebar",
interfaces: [nsISidebar, nsISidebarExternal],
flags: nsIClassInfo.DOM_OBJECT});
nsSidebar.prototype.QueryInterface = XPCOMUtils.generateQI([nsISidebar, nsISidebarExternal]);
nsSidebar.prototype.QueryInterface = XPCOMUtils.generateQI([Components.interfaces.nsISupports]);
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([nsSidebar]);

View File

@ -1,4 +1,2 @@
component {22117140-9c6e-11d3-aaf1-00805f8a4905} nsSidebar.js
contract @mozilla.org/sidebar;1 {22117140-9c6e-11d3-aaf1-00805f8a4905}
category JavaScript-global-property sidebar @mozilla.org/sidebar;1
category JavaScript-global-property external @mozilla.org/sidebar;1

View File

@ -69,7 +69,6 @@ Sidebar.prototype = {
return true;
},
// =========================== nsISidebar ===========================
// The suggestedTitle and suggestedCategory parameters are ignored, but remain
// for backward compatibility.
addSearchEngine: function addSearchEngine(engineURL, iconURL, suggestedTitle,
@ -92,7 +91,6 @@ Sidebar.prototype = {
Services.search.addEngine(engineURL, dataType, iconURL, true);
},
// =========================== nsISidebarExternal ===========================
// This function exists to implement window.external.AddSearchProvider(),
// to match other browsers' APIs. The capitalization, although nonstandard here,
// is therefore important.
@ -122,17 +120,8 @@ Sidebar.prototype = {
return 0;
},
// =========================== nsIClassInfo ===========================
classInfo: XPCOMUtils.generateCI({classID: SIDEBAR_CID,
contractID: SIDEBAR_CONTRACTID,
interfaces: [Ci.nsISidebar,
Ci.nsISidebarExternal],
flags: Ci.nsIClassInfo.DOM_OBJECT,
classDescription: "Sidebar"}),
// =========================== nsISupports ===========================
QueryInterface: XPCOMUtils.generateQI([Ci.nsISidebar,
Ci.nsISidebarExternal]),
QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports]),
// XPCOMUtils stuff
classID: SIDEBAR_CID,

View File

@ -22,8 +22,6 @@ category xpcom-directory-providers browser-directory-provider @mozilla.org/brows
# Sidebar.js
component {22117140-9c6e-11d3-aaf1-00805f8a4905} Sidebar.js
contract @mozilla.org/sidebar;1 {22117140-9c6e-11d3-aaf1-00805f8a4905}
category JavaScript-global-property sidebar @mozilla.org/sidebar;1
category JavaScript-global-property external @mozilla.org/sidebar;1
category wakeup-request Sidebar @mozilla.org/sidebar;1,nsISidebarExternal,getService,Sidebar:AddSearchProvider
# SessionStore.js

View File

@ -174,3 +174,6 @@ LOCAL_INCLUDES += [
for var in ('MOZ_JSDEBUGGER', 'MOZ_B2G_RIL', 'MOZ_B2G_FM'):
if CONFIG[var]:
DEFINES[var] = True
if CONFIG['MOZ_BUILD_APP'] in ['browser', 'mobile/android', 'xulrunner']:
DEFINES['HAVE_SIDEBAR'] = True

View File

@ -216,6 +216,9 @@
#include "nsITabChild.h"
#include "mozilla/dom/MediaQueryList.h"
#include "mozilla/dom/ScriptSettings.h"
#ifdef HAVE_SIDEBAR
#include "mozilla/dom/ExternalBinding.h"
#endif
#ifdef MOZ_WEBSPEECH
#include "mozilla/dom/SpeechSynthesis.h"
@ -1446,6 +1449,8 @@ nsGlobalWindow::CleanUp()
mConsole = nullptr;
mExternal = nullptr;
mPerformance = nullptr;
#ifdef MOZ_WEBSPEECH
@ -1761,6 +1766,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsGlobalWindow)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mScrollbars)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCrypto)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mConsole)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mExternal)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGlobalWindow)
@ -1819,6 +1825,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGlobalWindow)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mScrollbars)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mCrypto)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mConsole)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mExternal)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
#ifdef DEBUG
@ -13497,6 +13504,54 @@ nsGlobalWindow::GetConsole(ErrorResult& aRv)
return mConsole;
}
already_AddRefed<External>
nsGlobalWindow::GetExternal(ErrorResult& aRv)
{
FORWARD_TO_INNER_OR_THROW(GetExternal, (aRv), aRv, nullptr);
#ifdef HAVE_SIDEBAR
if (!mExternal) {
AutoJSContext cx;
JS::Rooted<JSObject*> jsImplObj(cx);
ConstructJSImplementation(cx, "@mozilla.org/sidebar;1",
this, &jsImplObj, aRv);
if (aRv.Failed()) {
return nullptr;
}
mExternal = new External(jsImplObj, this);
}
nsRefPtr<External> external = static_cast<External*>(mExternal.get());
return external.forget();
#else
aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
return nullptr;
#endif
}
void
nsGlobalWindow::GetSidebar(OwningExternalOrWindowProxy& aResult,
ErrorResult& aRv)
{
FORWARD_TO_INNER_OR_THROW(GetSidebar, (aResult, aRv), aRv, );
#ifdef HAVE_SIDEBAR
// First check for a named frame named "sidebar"
nsCOMPtr<nsIDOMWindow> domWindow = GetChildWindow(NS_LITERAL_STRING("sidebar"));
if (domWindow) {
aResult.SetAsWindowProxy() = domWindow.forget();
return;
}
nsRefPtr<External> external = GetExternal(aRv);
if (external) {
aResult.SetAsExternal() = external;
}
#else
aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
#endif
}
#ifdef MOZ_B2G
void
nsGlobalWindow::EnableNetworkEvent(uint32_t aType)

View File

@ -107,10 +107,12 @@ class Selection;
namespace dom {
class BarProp;
class Console;
class External;
class Function;
class Gamepad;
class MediaQueryList;
class Navigator;
class OwningExternalOrWindowProxy;
class SpeechSynthesis;
class WakeLock;
namespace indexedDB {
@ -823,6 +825,10 @@ public:
mozilla::dom::Console* GetConsole(mozilla::ErrorResult& aRv);
void GetSidebar(mozilla::dom::OwningExternalOrWindowProxy& aResult,
mozilla::ErrorResult& aRv);
already_AddRefed<mozilla::dom::External> GetExternal(mozilla::ErrorResult& aRv);
protected:
bool AlertOrConfirm(bool aAlert, const nsAString& aMessage,
mozilla::ErrorResult& aError);
@ -1455,6 +1461,11 @@ protected:
nsGlobalWindowObserver* mObserver; // Inner windows only.
nsCOMPtr<nsIDOMCrypto> mCrypto;
nsRefPtr<mozilla::dom::Console> mConsole;
// We need to store an nsISupports pointer to this object because the
// mozilla::dom::External class doesn't exist on b2g and using the type
// forward declared here means that ~nsGlobalWindow wouldn't compile because
// it wouldn't see the ~External function's declaration.
nsCOMPtr<nsISupports> mExternal;
nsCOMPtr<nsIDOMStorage> mLocalStorage;
nsCOMPtr<nsIDOMStorage> mSessionStorage;

View File

@ -1988,6 +1988,20 @@ ConstructJSImplementation(JSContext* aCx, const char* aContractId,
return nullptr;
}
ConstructJSImplementation(aCx, aContractId, window, aObject, aRv);
if (aRv.Failed()) {
return nullptr;
}
return window.forget();
}
void
ConstructJSImplementation(JSContext* aCx, const char* aContractId,
nsPIDOMWindow* aWindow,
JS::MutableHandle<JSObject*> aObject,
ErrorResult& aRv)
{
// Make sure to divorce ourselves from the calling JS while creating and
// initializing the object, so exceptions from that will get reported
// properly, since those are never exceptions that a spec wants to be thrown.
@ -1999,17 +2013,17 @@ ConstructJSImplementation(JSContext* aCx, const char* aContractId,
if (!implISupports) {
NS_WARNING("Failed to get JS implementation for contract");
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
return;
}
// Initialize the object, if it implements nsIDOMGlobalPropertyInitializer.
nsCOMPtr<nsIDOMGlobalPropertyInitializer> gpi =
do_QueryInterface(implISupports);
if (gpi) {
JS::Rooted<JS::Value> initReturn(aCx);
nsresult rv = gpi->Init(window, &initReturn);
nsresult rv = gpi->Init(aWindow, &initReturn);
if (NS_FAILED(rv)) {
aRv.Throw(rv);
return nullptr;
return;
}
// With JS-implemented WebIDL, the return value of init() is not used to determine
// if init() failed, so init() should only return undefined. Any kind of permission
@ -2025,16 +2039,13 @@ ConstructJSImplementation(JSContext* aCx, const char* aContractId,
MOZ_ASSERT(implWrapped, "Failed to get wrapped JS from XPCOM component.");
if (!implWrapped) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
return;
}
aObject.set(implWrapped->GetJSObject());
if (!aObject) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
}
return window.forget();
}
bool

View File

@ -2293,6 +2293,12 @@ bool
GetWindowForJSImplementedObject(JSContext* cx, JS::Handle<JSObject*> obj,
nsPIDOMWindow** window);
void
ConstructJSImplementation(JSContext* aCx, const char* aContractId,
nsPIDOMWindow* aWindow,
JS::MutableHandle<JSObject*> aObject,
ErrorResult& aRv);
already_AddRefed<nsPIDOMWindow>
ConstructJSImplementation(JSContext* aCx, const char* aContractId,
const GlobalObject& aGlobal,

View File

@ -90,3 +90,7 @@ FINAL_LIBRARY = 'xul'
SPHINX_TREES['webidl'] = 'docs'
SPHINX_PYTHON_PACKAGE_DIRS += ['mozwebidlcodegen']
if CONFIG['MOZ_BUILD_APP'] in ['browser', 'mobile/android', 'xulrunner']:
# This is needed for Window.webidl
DEFINES['HAVE_SIDEBAR'] = True

View File

@ -5,7 +5,6 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
XPIDL_SOURCES += [
'nsISidebar.idl',
'nsIWebContentHandlerRegistrar.idl',
]

View File

@ -1,29 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsISupports.idl"
[scriptable, uuid(351887ca-56b2-4458-96fc-88baeb57b6e7)]
interface nsISidebar : nsISupports
{
void addSearchEngine(in DOMString engineURL, in DOMString iconURL,
in DOMString suggestedTitle, in DOMString suggestedCategory);
};
[scriptable, uuid(5895076f-e28e-434a-9fdb-a69f94eb323f)]
interface nsISidebarExternal : nsISupports
{
void AddSearchProvider(in DOMString aDescriptionURL);
unsigned long IsSearchProviderInstalled(in DOMString aSearchURL);
};
%{ C++
// {577CB744-8CAF-11d3-AAEF-00805F8A4905}
#define NS_SIDEBAR_CID \
{ 0x577cb744, 0x8caf, 0x11d3, { 0xaa, 0xef, 0x0, 0x80, 0x5f, 0x8a, 0x49, 0x5 } }
#define NS_SIDEBAR_CONTRACTID "@mozilla.org/sidebar;1"
%}

View File

@ -16,7 +16,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=857555
addLoadEvent(function() {
is(content, $("t").contentWindow, "'content' as iframe name should work");
is(sidebar, $("u").contentWindow, "'sidebar' as iframe name should work");
is(external, $("v").contentWindow, "'external' as iframe name should work");
SimpleTest.finish();
});
</script>
@ -27,7 +26,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=857555
<div id="content" style="display: none">
<iframe name="content" id="t"></iframe>
<iframe name="sidebar" id="u"></iframe>
<iframe name="external" id="v"></iframe>
</div>
<pre id="test">
</pre>

View File

@ -347,6 +347,8 @@ var interfaceNamesInGlobalScope =
"EventSource",
// IMPORTANT: Do not change this list without review from a DOM peer!
"EventTarget",
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "External", b2g: false},
// IMPORTANT: Do not change this list without review from a DOM peer!
"File",
// IMPORTANT: Do not change this list without review from a DOM peer!

View File

@ -0,0 +1,18 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
[JSImplementation="@mozilla.org/sidebar;1"]
interface External
{
void AddSearchProvider(DOMString aDescriptionURL);
unsigned long IsSearchProviderInstalled(DOMString aSearchURL);
};
// Mozilla extension
partial interface External {
void addSearchEngine(DOMString engineURL, DOMString iconURL,
DOMString suggestedTitle, DOMString suggestedCategory);
};

View File

@ -65,7 +65,9 @@ typedef any Transferable;
// the user agent
[Throws] readonly attribute Navigator navigator;
//(Not implemented)readonly attribute External external;
#ifdef HAVE_SIDEBAR
[Replaceable, Throws] readonly attribute External external;
#endif
[Throws] readonly attribute ApplicationCache applicationCache;
// user prompts
@ -348,6 +350,13 @@ partial interface Window {
readonly attribute Console console;
};
#ifdef HAVE_SIDEBAR
// Mozilla extension
partial interface Window {
[Replaceable, Throws]
readonly attribute (External or WindowProxy) sidebar;
};
#endif
[ChromeOnly] interface ChromeWindow {
[Func="nsGlobalWindow::IsChromeWindow"]

View File

@ -621,3 +621,8 @@ if CONFIG['MOZ_BUILD_APP'] in ['browser', 'xulrunner']:
WEBIDL_FILES += [
'BrowserFeedWriter.webidl',
]
if CONFIG['MOZ_BUILD_APP'] in ['browser', 'mobile/android', 'xulrunner']:
WEBIDL_FILES += [
'External.webidl',
]

View File

@ -27,8 +27,6 @@ category xpcom-directory-providers browser-directory-provider @mozilla.org/brows
# Sidebar.js
component {22117140-9c6e-11d3-aaf1-00805f8a4905} Sidebar.js
contract @mozilla.org/sidebar;1 {22117140-9c6e-11d3-aaf1-00805f8a4905}
category JavaScript-global-property sidebar @mozilla.org/sidebar;1
category JavaScript-global-property external @mozilla.org/sidebar;1
category wakeup-request Sidebar @mozilla.org/sidebar;1,nsISidebarExternal,getService,Sidebar:AddSearchProvider
# SessionStore.js

View File

@ -91,7 +91,6 @@ Sidebar.prototype = {
Services.search.addEngine(engineURL, dataType, iconURL, true);
},
// =========================== nsISidebarExternal ===========================
// This function exists to implement window.external.AddSearchProvider(),
// to match other browsers' APIs. The capitalization, although nonstandard here,
// is therefore important.
@ -121,17 +120,8 @@ Sidebar.prototype = {
return 0;
},
// =========================== nsIClassInfo ===========================
classInfo: XPCOMUtils.generateCI({classID: SIDEBAR_CID,
contractID: SIDEBAR_CONTRACTID,
interfaces: [Ci.nsISidebar,
Ci.nsISidebarExternal],
flags: Ci.nsIClassInfo.DOM_OBJECT,
classDescription: "Sidebar"}),
// =========================== nsISupports ===========================
QueryInterface: XPCOMUtils.generateQI([Ci.nsISidebar,
Ci.nsISidebarExternal]),
QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports]),
// XPCOMUtils stuff
classID: SIDEBAR_CID,