mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 481603: Add a way to unload JS modules loaded with Components.utils.import. r=mrbkap
This commit is contained in:
parent
6d98f14885
commit
508ce88566
@ -48,14 +48,14 @@ struct JSObject;
|
||||
|
||||
[ptr] native JSObjectPtr(JSObject);
|
||||
|
||||
[scriptable, uuid(89da3673-e699-4f26-9ed7-11a528011434)]
|
||||
[scriptable, uuid(3f945a8e-58ca-47ba-a789-82d022e837fd)]
|
||||
interface xpcIJSModuleLoader : nsISupports
|
||||
{
|
||||
/**
|
||||
* To be called from JavaScript only.
|
||||
*
|
||||
* Synchronously loads and evaluates the js file located at
|
||||
* 'registryLocation' with a new, fully privileged global object.
|
||||
* aResourceURI with a new, fully privileged global object.
|
||||
*
|
||||
* If 'targetObj' is specified and equal to null, returns the
|
||||
* module's global object. Otherwise (if 'targetObj' is not
|
||||
@ -85,11 +85,19 @@ interface xpcIJSModuleLoader : nsISupports
|
||||
/* , [optional] in JSObject targetObj */);
|
||||
|
||||
/**
|
||||
* Imports the JS module at 'registryLocation' to the JS object
|
||||
* Imports the JS module at aResourceURI to the JS object
|
||||
* 'targetObj' (if != null) as described for importModule() and
|
||||
* returns the module's global object.
|
||||
*/
|
||||
[noscript] JSObjectPtr importInto(in AUTF8String aResourceURI,
|
||||
in JSObjectPtr targetObj,
|
||||
in nsAXPCNativeCallContextPtr cc);
|
||||
|
||||
/**
|
||||
* Unloads the JS module at aResourceURI. Existing references to the module
|
||||
* will continue to work but any subsequent import of the module will
|
||||
* reload it and give new reference. If the JS module hasn't yet been imported
|
||||
* then this method will do nothing.
|
||||
*/
|
||||
void unload(in AUTF8String aResourceURI);
|
||||
};
|
||||
|
@ -123,7 +123,7 @@ interface nsIXPCComponents_utils_Sandbox : nsISupports
|
||||
/**
|
||||
* interface of Components.utils
|
||||
*/
|
||||
[scriptable, uuid(c1d616fa-1875-49ba-b7b8-5861dab31a42)]
|
||||
[scriptable, uuid(5f0acf45-135a-48d1-976c-082ce3b24ead)]
|
||||
interface nsIXPCComponents_Utils : nsISupports
|
||||
{
|
||||
|
||||
@ -204,6 +204,16 @@ interface nsIXPCComponents_Utils : nsISupports
|
||||
void /* JSObject */ import(in AUTF8String registryLocation
|
||||
/*, [optional] in JSObject targetObj */);
|
||||
|
||||
/*
|
||||
* Unloads the JS module at 'registryLocation'. Existing references to the
|
||||
* module will continue to work but any subsequent import of the module will
|
||||
* reload it and give new reference. If the JS module hasn't yet been
|
||||
* imported then this method will do nothing.
|
||||
*
|
||||
* @param resourceURI A resource:// URI string to unload the module from.
|
||||
*/
|
||||
void unload(in AUTF8String registryLocation);
|
||||
|
||||
/*
|
||||
* To be called from JS only.
|
||||
*
|
||||
|
@ -1601,6 +1601,76 @@ mozJSComponentLoader::ImportInto(const nsACString & aLocation,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
mozJSComponentLoader::Unload(const nsACString & aLocation)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if (!mInitialized) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIIOService> ioService = do_GetIOService(&rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Get the URI.
|
||||
nsCOMPtr<nsIURI> resURI;
|
||||
rv = ioService->NewURI(aLocation, nsnull, nsnull, getter_AddRefs(resURI));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// figure out the resolved URI
|
||||
nsCOMPtr<nsIChannel> scriptChannel;
|
||||
rv = ioService->NewChannelFromURI(resURI, getter_AddRefs(scriptChannel));
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_INVALID_ARG);
|
||||
|
||||
nsCOMPtr<nsIURI> resolvedURI;
|
||||
rv = scriptChannel->GetURI(getter_AddRefs(resolvedURI));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// get the JAR if there is one
|
||||
nsCOMPtr<nsIJARURI> jarURI;
|
||||
jarURI = do_QueryInterface(resolvedURI, &rv);
|
||||
nsCOMPtr<nsIFileURL> baseFileURL;
|
||||
nsCAutoString jarEntry;
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCOMPtr<nsIURI> baseURI;
|
||||
rv = jarURI->GetJARFile(getter_AddRefs(baseURI));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
baseFileURL = do_QueryInterface(baseURI, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
jarURI->GetJAREntry(jarEntry);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
} else {
|
||||
baseFileURL = do_QueryInterface(resolvedURI, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIFile> sourceFile;
|
||||
rv = baseFileURL->GetFile(getter_AddRefs(sourceFile));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsILocalFile> sourceLocalFile;
|
||||
sourceLocalFile = do_QueryInterface(sourceFile, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoString key;
|
||||
if (jarEntry.IsEmpty()) {
|
||||
rv = FileKey(sourceLocalFile, key);
|
||||
} else {
|
||||
rv = JarKey(sourceLocalFile, jarEntry, key);
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
ModuleEntry* mod;
|
||||
if (mImports.Get(key, &mod)) {
|
||||
mImports.Remove(key);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
mozJSComponentLoader::Observe(nsISupports *subject, const char *topic,
|
||||
const PRUnichar *data)
|
||||
|
@ -3725,6 +3725,18 @@ nsXPCComponents_Utils::Import(const nsACString & registryLocation)
|
||||
return moduleloader->Import(registryLocation);
|
||||
}
|
||||
|
||||
/* unload (in AUTF8String registryLocation);
|
||||
*/
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_Utils::Unload(const nsACString & registryLocation)
|
||||
{
|
||||
nsCOMPtr<xpcIJSModuleLoader> moduleloader =
|
||||
do_GetService(MOZJSCOMPONENTLOADER_CONTRACTID);
|
||||
if (!moduleloader)
|
||||
return NS_ERROR_FAILURE;
|
||||
return moduleloader->Unload(registryLocation);
|
||||
}
|
||||
|
||||
/* xpcIJSWeakReference getWeakReference (); */
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_Utils::GetWeakReference(xpcIJSWeakReference **_retval)
|
||||
|
65
js/src/xpconnect/tests/unit/test_unload.js
Normal file
65
js/src/xpconnect/tests/unit/test_unload.js
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Dave Townsend <dtownsend@oxymoronical.com> (original author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
function run_test() {
|
||||
var scope1 = {};
|
||||
var global1 = Components.utils.import("resource://gre/modules/NetUtil.jsm", scope1);
|
||||
|
||||
var scope2 = {};
|
||||
var global2 = Components.utils.import("resource://gre/modules/NetUtil.jsm", scope2);
|
||||
|
||||
do_check_true(global1 === global2);
|
||||
do_check_true(scope1.NetUtil === scope2.NetUtil);
|
||||
|
||||
Components.utils.unload("resource://gre/modules/NetUtil.jsm");
|
||||
|
||||
var scope3 = {};
|
||||
var global3 = Components.utils.import("resource://gre/modules/NetUtil.jsm", scope3);
|
||||
|
||||
do_check_false(global1 === global3);
|
||||
do_check_false(scope1.NetUtil === scope3.NetUtil);
|
||||
|
||||
// Both instances should work
|
||||
uri1 = scope1.NetUtil.newURI("http://www.example.com");
|
||||
do_check_true(uri1 instanceof Components.interfaces.nsIURL);
|
||||
|
||||
var uri3 = scope3.NetUtil.newURI("http://www.example.com");
|
||||
do_check_true(uri3 instanceof Components.interfaces.nsIURL);
|
||||
|
||||
do_check_true(uri1.equals(uri3));
|
||||
}
|
@ -15,3 +15,4 @@ tail =
|
||||
[test_localeCompare.js]
|
||||
[test_recursive_import.js]
|
||||
[test_xpcomutils.js]
|
||||
[test_unload.js]
|
||||
|
Loading…
Reference in New Issue
Block a user