mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merging mozilla-central with mozilla-inbound.
This commit is contained in:
commit
e87fb91e76
@ -1081,6 +1081,9 @@ let TabItems = {
|
||||
tab._tabViewTabItem.removeTrenches();
|
||||
Items.unsquish(null, tab._tabViewTabItem);
|
||||
|
||||
tab._tabViewTabItem.tab = null;
|
||||
tab._tabViewTabItem.tabCanvas.tab = null;
|
||||
tab._tabViewTabItem.tabCanvas = null;
|
||||
tab._tabViewTabItem = null;
|
||||
Storage.saveTab(tab, null);
|
||||
|
||||
|
@ -1405,6 +1405,7 @@ nsFrameLoader::MaybeCreateDocShell()
|
||||
nsCOMPtr<nsISupports> container =
|
||||
doc->GetContainer();
|
||||
nsCOMPtr<nsIWebNavigation> parentAsWebNav = do_QueryInterface(container);
|
||||
NS_ENSURE_STATE(parentAsWebNav);
|
||||
|
||||
// Create the docshell...
|
||||
mDocShell = do_CreateInstance("@mozilla.org/docshell;1");
|
||||
@ -1457,6 +1458,7 @@ nsFrameLoader::MaybeCreateDocShell()
|
||||
// this some other way..... Not sure how yet.
|
||||
nsCOMPtr<nsIDocShellTreeOwner> parentTreeOwner;
|
||||
parentAsItem->GetTreeOwner(getter_AddRefs(parentTreeOwner));
|
||||
NS_ENSURE_STATE(parentTreeOwner);
|
||||
mIsTopLevelContent =
|
||||
AddTreeItemToTreeOwner(docShellAsItem, mOwnerContent, parentTreeOwner,
|
||||
parentType, parentAsNode);
|
||||
|
@ -657,12 +657,6 @@ struct JSRuntime {
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
/* Function invocation metering. */
|
||||
jsrefcount inlineCalls;
|
||||
jsrefcount nativeCalls;
|
||||
jsrefcount nonInlineCalls;
|
||||
jsrefcount constructs;
|
||||
|
||||
/*
|
||||
* NB: emptyShapes (in JSCompartment) is init'ed iff at least one
|
||||
* of these envars is set:
|
||||
|
@ -295,14 +295,20 @@ IsFunctionObject(const js::Value &v, JSObject **funobj)
|
||||
return v.isObject() && (*funobj = &v.toObject())->isFunction();
|
||||
}
|
||||
|
||||
static JS_ALWAYS_INLINE bool
|
||||
IsFunctionObject(const js::Value &v, JSObject **funobj, JSFunction **fun)
|
||||
{
|
||||
bool b = IsFunctionObject(v, funobj);
|
||||
if (b)
|
||||
*fun = (*funobj)->getFunctionPrivate();
|
||||
return b;
|
||||
}
|
||||
|
||||
static JS_ALWAYS_INLINE bool
|
||||
IsFunctionObject(const js::Value &v, JSFunction **fun)
|
||||
{
|
||||
JSObject *funobj;
|
||||
bool b = IsFunctionObject(v, &funobj);
|
||||
if (b)
|
||||
*fun = funobj->getFunctionPrivate();
|
||||
return b;
|
||||
return IsFunctionObject(v, &funobj, fun);
|
||||
}
|
||||
|
||||
static JS_ALWAYS_INLINE bool
|
||||
|
@ -1212,7 +1212,6 @@ InvokeConstructor(JSContext *cx, const CallArgs &argsRef)
|
||||
return false;
|
||||
|
||||
JS_ASSERT(args.rval().isObject());
|
||||
JS_RUNTIME_METER(cx->runtime, constructs);
|
||||
return true;
|
||||
}
|
||||
if (clasp->construct) {
|
||||
@ -4519,153 +4518,90 @@ BEGIN_CASE(JSOP_ENUMELEM)
|
||||
}
|
||||
END_CASE(JSOP_ENUMELEM)
|
||||
|
||||
{ // begin block around calling opcodes
|
||||
JSFunction *newfun;
|
||||
JSObject *callee;
|
||||
MaybeConstruct construct;
|
||||
CallArgs args;
|
||||
|
||||
BEGIN_CASE(JSOP_NEW)
|
||||
{
|
||||
args = CallArgsFromSp(GET_ARGC(regs.pc), regs.sp);
|
||||
JS_ASSERT(args.base() >= regs.fp()->base());
|
||||
|
||||
if (IsFunctionObject(args.calleev(), &callee)) {
|
||||
newfun = callee->getFunctionPrivate();
|
||||
if (newfun->isInterpretedConstructor()) {
|
||||
if (newfun->script()->isEmpty()) {
|
||||
JSObject *rval = js_CreateThisForFunction(cx, callee);
|
||||
if (!rval)
|
||||
goto error;
|
||||
args.rval().setObject(*rval);
|
||||
regs.sp = args.spAfterCall();
|
||||
goto end_new;
|
||||
}
|
||||
|
||||
construct = CONSTRUCT;
|
||||
goto inline_call;
|
||||
}
|
||||
}
|
||||
|
||||
if (!InvokeConstructor(cx, args))
|
||||
goto error;
|
||||
regs.sp = args.spAfterCall();
|
||||
CHECK_INTERRUPT_HANDLER();
|
||||
TRACE_0(NativeCallComplete);
|
||||
|
||||
end_new:;
|
||||
}
|
||||
END_CASE(JSOP_NEW)
|
||||
|
||||
BEGIN_CASE(JSOP_EVAL)
|
||||
{
|
||||
args = CallArgsFromSp(GET_ARGC(regs.pc), regs.sp);
|
||||
|
||||
if (!IsBuiltinEvalForScope(®s.fp()->scopeChain(), args.calleev()))
|
||||
goto call_using_invoke;
|
||||
|
||||
if (!DirectEval(cx, args))
|
||||
goto error;
|
||||
|
||||
CallArgs args = CallArgsFromSp(GET_ARGC(regs.pc), regs.sp);
|
||||
if (IsBuiltinEvalForScope(®s.fp()->scopeChain(), args.calleev())) {
|
||||
if (!DirectEval(cx, args))
|
||||
goto error;
|
||||
} else {
|
||||
if (!Invoke(cx, args))
|
||||
goto error;
|
||||
}
|
||||
CHECK_INTERRUPT_HANDLER();
|
||||
regs.sp = args.spAfterCall();
|
||||
}
|
||||
END_CASE(JSOP_EVAL)
|
||||
|
||||
BEGIN_CASE(JSOP_NEW)
|
||||
BEGIN_CASE(JSOP_CALL)
|
||||
BEGIN_CASE(JSOP_FUNAPPLY)
|
||||
BEGIN_CASE(JSOP_FUNCALL)
|
||||
BEGIN_CASE(JSOP_FUNAPPLY)
|
||||
{
|
||||
CallArgs args = CallArgsFromSp(GET_ARGC(regs.pc), regs.sp);
|
||||
JS_ASSERT(args.base() >= regs.fp()->base());
|
||||
|
||||
args = CallArgsFromSp(GET_ARGC(regs.pc), regs.sp);
|
||||
MaybeConstruct construct = *regs.pc == JSOP_NEW ? CONSTRUCT : NO_CONSTRUCT;
|
||||
|
||||
if (IsFunctionObject(args.calleev(), &callee)) {
|
||||
newfun = callee->getFunctionPrivate();
|
||||
|
||||
/* Clear frame flag since this is not a constructor call. */
|
||||
construct = NO_CONSTRUCT;
|
||||
if (newfun->isInterpreted())
|
||||
inline_call:
|
||||
{
|
||||
JSScript *newscript = newfun->script();
|
||||
if (JS_UNLIKELY(newscript->isEmpty())) {
|
||||
args.rval().setUndefined();
|
||||
regs.sp = args.spAfterCall();
|
||||
goto end_call;
|
||||
}
|
||||
|
||||
/* Push frame on the stack. */
|
||||
if (!cx->stack.pushInlineFrame(cx, regs, args, *callee, newfun,
|
||||
newscript, construct, OOMCheck())) {
|
||||
JSObject *callee;
|
||||
JSFunction *fun;
|
||||
if (!IsFunctionObject(args.calleev(), &callee, &fun) || !fun->isInterpretedConstructor()) {
|
||||
if (construct) {
|
||||
if (!InvokeConstructor(cx, args))
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Refresh interpreter locals. */
|
||||
script = newscript;
|
||||
pcCounts = script->pcCounters.get(JSRUNMODE_INTERP);
|
||||
argv = regs.fp()->formalArgsEnd() - newfun->nargs;
|
||||
atoms = script->atomMap.vector;
|
||||
|
||||
/* Now that the new frame is rooted, maybe create a call object. */
|
||||
if (newfun->isHeavyweight() && !CreateFunCallObject(cx, regs.fp()))
|
||||
} else {
|
||||
if (!Invoke(cx, args))
|
||||
goto error;
|
||||
|
||||
RESET_USE_METHODJIT();
|
||||
JS_RUNTIME_METER(rt, inlineCalls);
|
||||
|
||||
TRACE_0(EnterFrame);
|
||||
|
||||
CHECK_INTERRUPT_HANDLER();
|
||||
|
||||
#ifdef JS_METHODJIT
|
||||
/* Try to ensure methods are method JIT'd. */
|
||||
mjit::CompileRequest request = (interpMode == JSINTERP_NORMAL)
|
||||
? mjit::CompileRequest_Interpreter
|
||||
: mjit::CompileRequest_JIT;
|
||||
mjit::CompileStatus status = mjit::CanMethodJIT(cx, script, regs.fp(), request);
|
||||
if (status == mjit::Compile_Error)
|
||||
goto error;
|
||||
if (!TRACE_RECORDER(cx) && !TRACE_PROFILER(cx) && status == mjit::Compile_Okay) {
|
||||
interpReturnOK = mjit::JaegerShot(cx);
|
||||
CHECK_INTERRUPT_HANDLER();
|
||||
goto jit_return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!ScriptPrologue(cx, regs.fp()))
|
||||
goto error;
|
||||
|
||||
CHECK_INTERRUPT_HANDLER();
|
||||
|
||||
/* Load first op and dispatch it (safe since JSOP_STOP). */
|
||||
op = (JSOp) *regs.pc;
|
||||
DO_OP();
|
||||
}
|
||||
|
||||
Probes::enterJSFun(cx, newfun, script);
|
||||
JSBool ok = CallJSNative(cx, newfun->u.n.native, args);
|
||||
Probes::exitJSFun(cx, newfun, script);
|
||||
regs.sp = args.spAfterCall();
|
||||
if (!ok)
|
||||
goto error;
|
||||
CHECK_INTERRUPT_HANDLER();
|
||||
TRACE_0(NativeCallComplete);
|
||||
goto end_call;
|
||||
len = JSOP_CALL_LENGTH;
|
||||
DO_NEXT_OP(len);
|
||||
}
|
||||
|
||||
call_using_invoke:
|
||||
bool ok;
|
||||
ok = Invoke(cx, args);
|
||||
regs.sp = args.spAfterCall();
|
||||
CHECK_INTERRUPT_HANDLER();
|
||||
if (!ok)
|
||||
script = fun->script();
|
||||
if (!cx->stack.pushInlineFrame(cx, regs, args, *callee, fun, script, construct, OOMCheck()))
|
||||
goto error;
|
||||
JS_RUNTIME_METER(rt, nonInlineCalls);
|
||||
TRACE_0(NativeCallComplete);
|
||||
|
||||
end_call:;
|
||||
/* Refresh local js::Interpret state. */
|
||||
pcCounts = script->pcCounters.get(JSRUNMODE_INTERP);
|
||||
argv = regs.fp()->formalArgsEnd() - fun->nargs;
|
||||
atoms = script->atomMap.vector;
|
||||
|
||||
/* Only create call object after frame is rooted. */
|
||||
if (fun->isHeavyweight() && !CreateFunCallObject(cx, regs.fp()))
|
||||
goto error;
|
||||
|
||||
RESET_USE_METHODJIT();
|
||||
TRACE_0(EnterFrame);
|
||||
|
||||
#ifdef JS_METHODJIT
|
||||
{
|
||||
/* Try to ensure methods are method JIT'd. */
|
||||
mjit::CompileRequest request = (interpMode == JSINTERP_NORMAL)
|
||||
? mjit::CompileRequest_Interpreter
|
||||
: mjit::CompileRequest_JIT;
|
||||
mjit::CompileStatus status = mjit::CanMethodJIT(cx, script, regs.fp(), request);
|
||||
if (status == mjit::Compile_Error)
|
||||
goto error;
|
||||
if (!TRACE_RECORDER(cx) && !TRACE_PROFILER(cx) && status == mjit::Compile_Okay) {
|
||||
interpReturnOK = mjit::JaegerShot(cx);
|
||||
CHECK_INTERRUPT_HANDLER();
|
||||
goto jit_return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!ScriptPrologue(cx, regs.fp()))
|
||||
goto error;
|
||||
|
||||
CHECK_INTERRUPT_HANDLER();
|
||||
|
||||
/* Load first op and dispatch it (safe since JSOP_STOP). */
|
||||
op = (JSOp) *regs.pc;
|
||||
DO_OP();
|
||||
}
|
||||
END_CASE(JSOP_CALL)
|
||||
|
||||
} // end block around calling opcodes
|
||||
|
||||
BEGIN_CASE(JSOP_SETCALL)
|
||||
{
|
||||
|
@ -371,7 +371,6 @@ ScriptEpilogue(JSContext *cx, StackFrame *fp, bool ok)
|
||||
if (fp->isConstructing() && ok) {
|
||||
if (fp->returnValue().isPrimitive())
|
||||
fp->setReturnValue(ObjectValue(fp->constructorThis()));
|
||||
JS_RUNTIME_METER(cx->runtime, constructs);
|
||||
}
|
||||
|
||||
return ok;
|
||||
|
@ -13672,22 +13672,6 @@ TraceRecorder::createThis(JSObject& ctor, LIns* ctor_ins, LIns** thisobj_insp)
|
||||
JS_REQUIRES_STACK RecordingStatus
|
||||
TraceRecorder::interpretedFunctionCall(Value& fval, JSFunction* fun, uintN argc, bool constructing)
|
||||
{
|
||||
/*
|
||||
* The function's identity (JSFunction and therefore JSScript) is guarded,
|
||||
* so we can optimize away the function call if the corresponding script is
|
||||
* empty. No need to worry about crossing globals or relocating argv, even,
|
||||
* in this case!
|
||||
*/
|
||||
if (fun->script()->isEmpty()) {
|
||||
LIns* rval_ins;
|
||||
if (constructing)
|
||||
CHECK_STATUS(createThis(fval.toObject(), get(&fval), &rval_ins));
|
||||
else
|
||||
rval_ins = w.immiUndefined();
|
||||
stack(-2 - argc, rval_ins);
|
||||
return RECORD_CONTINUE;
|
||||
}
|
||||
|
||||
if (fval.toObject().getGlobal() != globalObj)
|
||||
RETURN_STOP("JSOP_CALL or JSOP_NEW crosses global scopes");
|
||||
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -1479,6 +1479,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]
|
||||
|
@ -82,7 +82,7 @@ DEFINES += -DSHARED_LIBRARY=$(SHARED_LIBRARY) -DNOMINMAX
|
||||
|
||||
ifneq (mobile,$(MOZ_BUILD_APP))
|
||||
_BROWSER_FILES = \
|
||||
browser/aboutcrashes_utils.js \
|
||||
browser/head.js \
|
||||
browser/crashreport.sjs \
|
||||
browser/browser_aboutCrashes.js \
|
||||
browser/browser_bug471404.js \
|
||||
|
@ -1,10 +1,3 @@
|
||||
// load our utility script
|
||||
var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
|
||||
.getService(Components.interfaces.mozIJSSubScriptLoader);
|
||||
|
||||
var rootDir = getRootDirectory(gTestPath);
|
||||
scriptLoader.loadSubScript(rootDir + "aboutcrashes_utils.js", this);
|
||||
|
||||
function check_crash_list(tab, crashes) {
|
||||
let doc = gBrowser.getBrowserForTab(tab).contentDocument;
|
||||
let crashlinks = doc.getElementById("tbody").getElementsByTagName("a");
|
||||
|
@ -1,10 +1,3 @@
|
||||
// load our utility script
|
||||
var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
|
||||
.getService(Components.interfaces.mozIJSSubScriptLoader);
|
||||
|
||||
var rootDir = getRootDirectory(gTestPath);
|
||||
scriptLoader.loadSubScript(rootDir + "aboutcrashes_utils.js", this);
|
||||
|
||||
function cleanup_and_finish() {
|
||||
try {
|
||||
cleanup_fake_appdir();
|
||||
|
@ -1,10 +1,3 @@
|
||||
// load our utility script
|
||||
var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
|
||||
.getService(Components.interfaces.mozIJSSubScriptLoader);
|
||||
|
||||
var rootDir = getRootDirectory(gTestPath);
|
||||
scriptLoader.loadSubScript(rootDir + "aboutcrashes_utils.js", this);
|
||||
|
||||
function check_clear_visible(tab, aVisible) {
|
||||
let doc = gBrowser.getBrowserForTab(tab).contentDocument;
|
||||
let visible = false;
|
||||
|
@ -1,6 +1,3 @@
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
|
||||
function create_subdir(dir, subdirname) {
|
||||
let subdir = dir.clone();
|
||||
subdir.append(subdirname);
|
@ -906,6 +906,33 @@ function loadManifestFromFile(aFile) {
|
||||
return loadManifestFromDir(aFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an nsIURI for a file within another file, either a directory or an XPI
|
||||
* file. If aFile is a directory then this will return a file: URI, if it is an
|
||||
* XPI file then it will return a jar: URI.
|
||||
*
|
||||
* @param aFile
|
||||
* The file containing the resources, must be either a directory or an
|
||||
* XPI file
|
||||
* @param aPath
|
||||
* The path to find the resource at, "/" separated. If aPath is empty
|
||||
* then the uri to the root of the contained files will be returned
|
||||
* @return an nsIURI pointing at the resource
|
||||
*/
|
||||
function getURIForResourceInFile(aFile, aPath) {
|
||||
if (aFile.isDirectory()) {
|
||||
let resource = aFile.clone();
|
||||
if (aPath) {
|
||||
aPath.split("/").forEach(function(aPart) {
|
||||
resource.append(aPart);
|
||||
});
|
||||
}
|
||||
return NetUtil.newURI(resource);
|
||||
}
|
||||
|
||||
return buildJarURI(aFile, aPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a jar: URI for a file inside a ZIP file.
|
||||
*
|
||||
@ -933,6 +960,12 @@ function flushJarCache(aJarFile) {
|
||||
.sendAsyncMessage(MSG_JAR_FLUSH, aJarFile.path);
|
||||
}
|
||||
|
||||
function flushStartupCache() {
|
||||
// Init this, so it will get the notification.
|
||||
Cc["@mozilla.org/xul/xul-prototype-cache;1"].getService(Ci.nsISupports);
|
||||
Services.obs.notifyObservers(null, "startupcache-invalidate", null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and returns a new unique temporary file. The caller should delete
|
||||
* the file when it is no longer needed.
|
||||
@ -1565,9 +1598,7 @@ var XPIProvider = {
|
||||
}
|
||||
|
||||
if (flushCaches) {
|
||||
// Init this, so it will get the notification.
|
||||
let xulPrototypeCache = Cc["@mozilla.org/xul/xul-prototype-cache;1"].getService(Ci.nsISupports);
|
||||
Services.obs.notifyObservers(null, "startupcache-invalidate", null);
|
||||
flushStartupCache();
|
||||
|
||||
// UI displayed early in startup (like the compatibility UI) may have
|
||||
// caused us to cache parts of the skin or locale in memory. These must
|
||||
@ -1989,6 +2020,7 @@ var XPIProvider = {
|
||||
this.callBootstrapMethod(existingAddonID, oldBootstrap.version,
|
||||
existingAddon, "uninstall", uninstallReason);
|
||||
this.unloadBootstrapScope(existingAddonID);
|
||||
flushStartupCache();
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
@ -2259,6 +2291,9 @@ var XPIProvider = {
|
||||
|
||||
// If the new add-on is bootstrapped and active then call its install method
|
||||
if (newAddon.active && newAddon.bootstrap) {
|
||||
// Startup cache must be flushed before calling the bootstrap script
|
||||
flushStartupCache();
|
||||
|
||||
let installReason = Services.vc.compare(aOldAddon.version, newAddon.version) < 0 ?
|
||||
BOOTSTRAP_REASONS.ADDON_UPGRADE :
|
||||
BOOTSTRAP_REASONS.ADDON_DOWNGRADE;
|
||||
@ -2270,7 +2305,6 @@ var XPIProvider = {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Otherwise the caches will need to be invalidated
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2445,9 +2479,7 @@ var XPIProvider = {
|
||||
if (aOldAddon.type == "theme")
|
||||
XPIProvider.enableDefaultTheme();
|
||||
|
||||
// If this was not a bootstrapped add-on then we must force a restart.
|
||||
if (!aOldAddon.bootstrap)
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -2586,10 +2618,16 @@ var XPIProvider = {
|
||||
let oldAddonFile = Cc["@mozilla.org/file/local;1"].
|
||||
createInstance(Ci.nsILocalFile);
|
||||
oldAddonFile.persistentDescriptor = oldBootstrap.descriptor;
|
||||
|
||||
XPIProvider.callBootstrapMethod(newAddon.id, oldBootstrap.version,
|
||||
oldAddonFile, "uninstall",
|
||||
installReason);
|
||||
XPIProvider.unloadBootstrapScope(newAddon.id);
|
||||
|
||||
// If the new add-on is bootstrapped then we must flush the caches
|
||||
// before calling the new bootstrap script
|
||||
if (newAddon.bootstrap)
|
||||
flushStartupCache();
|
||||
}
|
||||
|
||||
if (!newAddon.bootstrap)
|
||||
@ -3355,47 +3393,32 @@ var XPIProvider = {
|
||||
createInstance(Ci.nsIPrincipal);
|
||||
this.bootstrapScopes[aId] = new Components.utils.Sandbox(principal);
|
||||
|
||||
let bootstrap = aFile.clone();
|
||||
let name = aFile.leafName;
|
||||
let spec;
|
||||
|
||||
if (!bootstrap.exists()) {
|
||||
if (!aFile.exists()) {
|
||||
ERROR("Attempted to load bootstrap scope from missing directory " + bootstrap.path);
|
||||
return;
|
||||
}
|
||||
|
||||
if (bootstrap.isDirectory()) {
|
||||
bootstrap.append("bootstrap.js");
|
||||
let uri = Services.io.newFileURI(bootstrap);
|
||||
spec = uri.spec;
|
||||
} else {
|
||||
spec = buildJarURI(bootstrap, "bootstrap.js").spec;
|
||||
}
|
||||
if (bootstrap.exists()) {
|
||||
let loader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
|
||||
createInstance(Ci.mozIJSSubScriptLoader);
|
||||
let loader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
|
||||
createInstance(Ci.mozIJSSubScriptLoader);
|
||||
|
||||
try {
|
||||
// As we don't want our caller to control the JS version used for the
|
||||
// bootstrap file, we run loadSubScript within the context of the
|
||||
// sandbox with the latest JS version set explicitly.
|
||||
this.bootstrapScopes[aId].__SCRIPT_URI_SPEC__ = spec;
|
||||
Components.utils.evalInSandbox(
|
||||
"Components.classes['@mozilla.org/moz/jssubscript-loader;1'] \
|
||||
.createInstance(Components.interfaces.mozIJSSubScriptLoader) \
|
||||
.loadSubScript(__SCRIPT_URI_SPEC__);", this.bootstrapScopes[aId], "ECMAv5");
|
||||
}
|
||||
catch (e) {
|
||||
WARN("Error loading bootstrap.js for " + aId, e);
|
||||
}
|
||||
try {
|
||||
// As we don't want our caller to control the JS version used for the
|
||||
// bootstrap file, we run loadSubScript within the context of the
|
||||
// sandbox with the latest JS version set explicitly.
|
||||
this.bootstrapScopes[aId].__SCRIPT_URI_SPEC__ =
|
||||
getURIForResourceInFile(aFile, "bootstrap.js").spec;
|
||||
Components.utils.evalInSandbox(
|
||||
"Components.classes['@mozilla.org/moz/jssubscript-loader;1'] \
|
||||
.createInstance(Components.interfaces.mozIJSSubScriptLoader) \
|
||||
.loadSubScript(__SCRIPT_URI_SPEC__);", this.bootstrapScopes[aId], "ECMAv5");
|
||||
}
|
||||
catch (e) {
|
||||
WARN("Error loading bootstrap.js for " + aId, e);
|
||||
}
|
||||
|
||||
// Copy the reason values from the global object into the bootstrap scope.
|
||||
for (let name in BOOTSTRAP_REASONS)
|
||||
this.bootstrapScopes[aId][name] = BOOTSTRAP_REASONS[name];
|
||||
}
|
||||
else {
|
||||
WARN("Bootstrap missing for " + aId);
|
||||
}
|
||||
// Copy the reason values from the global object into the bootstrap scope.
|
||||
for (let name in BOOTSTRAP_REASONS)
|
||||
this.bootstrapScopes[aId][name] = BOOTSTRAP_REASONS[name];
|
||||
},
|
||||
|
||||
/**
|
||||
@ -3443,7 +3466,8 @@ var XPIProvider = {
|
||||
let params = {
|
||||
id: aId,
|
||||
version: aVersion,
|
||||
installPath: aFile.clone()
|
||||
installPath: aFile.clone(),
|
||||
resourceURI: getURIForResourceInFile(aFile, "")
|
||||
};
|
||||
|
||||
LOG("Calling bootstrap method " + aMethod + " on " + aId + " version " +
|
||||
@ -3623,9 +3647,11 @@ var XPIProvider = {
|
||||
this.callBootstrapMethod(aAddon.id, aAddon.version, file, "shutdown",
|
||||
BOOTSTRAP_REASONS.ADDON_UNINSTALL);
|
||||
}
|
||||
|
||||
this.callBootstrapMethod(aAddon.id, aAddon.version, file, "uninstall",
|
||||
BOOTSTRAP_REASONS.ADDON_UNINSTALL);
|
||||
this.unloadBootstrapScope(aAddon.id);
|
||||
flushStartupCache();
|
||||
}
|
||||
aAddon._installLocation.uninstallAddon(aAddon.id);
|
||||
XPIDatabase.removeAddonMetadata(aAddon);
|
||||
@ -6216,10 +6242,12 @@ AddonInstall.prototype = {
|
||||
this.existingAddon.version,
|
||||
file, "shutdown", reason);
|
||||
}
|
||||
|
||||
XPIProvider.callBootstrapMethod(this.existingAddon.id,
|
||||
this.existingAddon.version,
|
||||
file, "uninstall", reason);
|
||||
XPIProvider.unloadBootstrapScope(this.existingAddon.id);
|
||||
flushStartupCache();
|
||||
}
|
||||
|
||||
if (!isUpgrade && this.existingAddon.active) {
|
||||
@ -7210,21 +7238,22 @@ function AddonWrapper(aAddon) {
|
||||
return result;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns a URI to the selected resource or to the add-on bundle if aPath
|
||||
* is null. URIs to the bundle will always be file: URIs. URIs to resources
|
||||
* will be file: URIs if the add-on is unpacked or jar: URIs if the add-on is
|
||||
* still an XPI file.
|
||||
*
|
||||
* @param aPath
|
||||
* The path in the add-on to get the URI for or null to get a URI to
|
||||
* the file or directory the add-on is installed as.
|
||||
* @return an nsIURI
|
||||
*/
|
||||
this.getResourceURI = function(aPath) {
|
||||
let bundle = aAddon._sourceBundle.clone();
|
||||
|
||||
if (bundle.isDirectory()) {
|
||||
if (aPath) {
|
||||
aPath.split("/").forEach(function(aPart) {
|
||||
bundle.append(aPart);
|
||||
});
|
||||
}
|
||||
return Services.io.newFileURI(bundle);
|
||||
}
|
||||
|
||||
if (!aPath)
|
||||
return Services.io.newFileURI(bundle);
|
||||
return buildJarURI(bundle, aPath);
|
||||
return NetUtil.newURI(aAddon._sourceBundle);
|
||||
|
||||
return getURIForResourceInFile(aAddon._sourceBundle, aPath);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,13 +1,17 @@
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
function install(data, reason) {
|
||||
Services.prefs.setIntPref("bootstraptest.installed_version", 1);
|
||||
Components.utils.import(data.resourceURI.spec + "version.jsm");
|
||||
Services.prefs.setIntPref("bootstraptest.installed_version", VERSION);
|
||||
Services.prefs.setIntPref("bootstraptest.install_reason", reason);
|
||||
Components.utils.unload(data.resourceURI.spec + "version.jsm");
|
||||
}
|
||||
|
||||
function startup(data, reason) {
|
||||
Services.prefs.setIntPref("bootstraptest.active_version", 1);
|
||||
Components.utils.import(data.resourceURI.spec + "version.jsm");
|
||||
Services.prefs.setIntPref("bootstraptest.active_version", VERSION);
|
||||
Services.prefs.setIntPref("bootstraptest.startup_reason", reason);
|
||||
Components.utils.unload(data.resourceURI.spec + "version.jsm");
|
||||
}
|
||||
|
||||
function shutdown(data, reason) {
|
||||
|
@ -0,0 +1,3 @@
|
||||
var EXPORTED_SYMBOLS = ["VERSION"];
|
||||
|
||||
var VERSION = 1;
|
@ -1,13 +1,17 @@
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
function install(data, reason) {
|
||||
Services.prefs.setIntPref("bootstraptest.installed_version", 2);
|
||||
Components.utils.import(data.resourceURI.spec + "version.jsm");
|
||||
Services.prefs.setIntPref("bootstraptest.installed_version", VERSION);
|
||||
Services.prefs.setIntPref("bootstraptest.install_reason", reason);
|
||||
Components.utils.unload(data.resourceURI.spec + "version.jsm");
|
||||
}
|
||||
|
||||
function startup(data, reason) {
|
||||
Services.prefs.setIntPref("bootstraptest.active_version", 2);
|
||||
Components.utils.import(data.resourceURI.spec + "version.jsm");
|
||||
Services.prefs.setIntPref("bootstraptest.active_version", VERSION);
|
||||
Services.prefs.setIntPref("bootstraptest.startup_reason", reason);
|
||||
Components.utils.unload(data.resourceURI.spec + "version.jsm");
|
||||
}
|
||||
|
||||
function shutdown(data, reason) {
|
||||
|
@ -0,0 +1,3 @@
|
||||
var EXPORTED_SYMBOLS = ["VERSION"];
|
||||
|
||||
var VERSION = 2;
|
@ -1,13 +1,17 @@
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
function install(data, reason) {
|
||||
Services.prefs.setIntPref("bootstraptest.installed_version", 3);
|
||||
Components.utils.import(data.resourceURI.spec + "version.jsm");
|
||||
Services.prefs.setIntPref("bootstraptest.installed_version", VERSION);
|
||||
Services.prefs.setIntPref("bootstraptest.install_reason", reason);
|
||||
Components.utils.unload(data.resourceURI.spec + "version.jsm");
|
||||
}
|
||||
|
||||
function startup(data, reason) {
|
||||
Services.prefs.setIntPref("bootstraptest.active_version", 3);
|
||||
Components.utils.import(data.resourceURI.spec + "version.jsm");
|
||||
Services.prefs.setIntPref("bootstraptest.active_version", VERSION);
|
||||
Services.prefs.setIntPref("bootstraptest.startup_reason", reason);
|
||||
Components.utils.unload(data.resourceURI.spec + "version.jsm");
|
||||
}
|
||||
|
||||
function shutdown(data, reason) {
|
||||
|
@ -0,0 +1,3 @@
|
||||
var EXPORTED_SYMBOLS = ["VERSION"];
|
||||
|
||||
var VERSION = 3;
|
@ -6,7 +6,6 @@
|
||||
* Tests that history navigation works for the add-ons manager.
|
||||
*/
|
||||
|
||||
const PREF_DISCOVERURL = "extensions.webservice.discoverURL";
|
||||
const MAIN_URL = "https://example.com/" + RELATIVE_DIR + "discovery.html";
|
||||
const SECOND_URL = "https://example.com/" + RELATIVE_DIR + "releaseNotes.xhtml";
|
||||
|
||||
@ -58,9 +57,6 @@ function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
Services.prefs.setCharPref(PREF_DISCOVERURL, MAIN_URL);
|
||||
registerCleanupFunction(function() {
|
||||
Services.prefs.clearUserPref(PREF_DISCOVERURL);
|
||||
});
|
||||
|
||||
var gProvider = new MockProvider();
|
||||
gProvider.createAddons([{
|
||||
|
@ -5,7 +5,6 @@
|
||||
// Tests that the discovery view loads properly
|
||||
|
||||
const PREF_GETADDONS_CACHE_ENABLED = "extensions.getAddons.cache.enabled";
|
||||
const PREF_DISCOVERURL = "extensions.webservice.discoverURL";
|
||||
const MAIN_URL = "https://example.com/" + RELATIVE_DIR + "discovery.html";
|
||||
|
||||
var gManagerWindow;
|
||||
@ -36,15 +35,12 @@ var gProgressListener = {
|
||||
};
|
||||
|
||||
function test() {
|
||||
var currentURL = Services.prefs.getCharPref(PREF_DISCOVERURL);
|
||||
|
||||
// Switch to a known url
|
||||
Services.prefs.setCharPref(PREF_DISCOVERURL, MAIN_URL);
|
||||
// Temporarily enable caching
|
||||
Services.prefs.setBoolPref(PREF_GETADDONS_CACHE_ENABLED, true);
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
Services.prefs.setCharPref(PREF_DISCOVERURL, currentURL);
|
||||
Services.prefs.setBoolPref(PREF_GETADDONS_CACHE_ENABLED, false);
|
||||
});
|
||||
|
||||
|
@ -19,6 +19,7 @@ const RELATIVE_DIR = pathParts.slice(4).join("/") + "/";
|
||||
const TESTROOT = "http://example.com/" + RELATIVE_DIR;
|
||||
const TESTROOT2 = "http://example.org/" + RELATIVE_DIR;
|
||||
const CHROMEROOT = pathParts.join("/") + "/";
|
||||
const PREF_DISCOVERURL = "extensions.webservice.discoverURL";
|
||||
|
||||
const MANAGER_URI = "about:addons";
|
||||
const INSTALL_URI = "chrome://mozapps/content/xpinstall/xpinstallConfirm.xul";
|
||||
@ -31,6 +32,8 @@ var gTestStart = null;
|
||||
|
||||
var gUseInContentUI = !gTestInWindow && ("switchToTabHavingURI" in window);
|
||||
|
||||
var gDiscoveryURL = Services.prefs.getCharPref(PREF_DISCOVERURL);
|
||||
|
||||
// Turn logging on for all tests
|
||||
Services.prefs.setBoolPref(PREF_LOGGING_ENABLED, true);
|
||||
// Turn off remote results in searches
|
||||
@ -43,6 +46,8 @@ registerCleanupFunction(function() {
|
||||
catch (e) {
|
||||
}
|
||||
|
||||
Services.prefs.setCharPref(PREF_DISCOVERURL, gDiscoveryURL);
|
||||
|
||||
// Throw an error if the add-ons manager window is open anywhere
|
||||
var windows = Services.wm.getEnumerator("Addons:Manager");
|
||||
if (windows.hasMoreElements())
|
||||
|
@ -1 +1,2 @@
|
||||
Services.prefs.setBoolPref("extensions.alwaysUnpack", true);
|
||||
TEST_UNPACKED = true;
|
||||
|
@ -19,6 +19,8 @@ var gInternalManager = null;
|
||||
var gAppInfo = null;
|
||||
var gAddonsList;
|
||||
|
||||
var TEST_UNPACKED = false;
|
||||
|
||||
function createAppInfo(id, name, version, platformVersion) {
|
||||
gAppInfo = {
|
||||
// nsIXULAppInfo
|
||||
@ -161,7 +163,7 @@ function do_get_addon_root_uri(aProfileDir, aId) {
|
||||
}
|
||||
|
||||
function do_get_expected_addon_name(aId) {
|
||||
if (Services.prefs.getBoolPref("extensions.alwaysUnpack"))
|
||||
if (TEST_UNPACKED)
|
||||
return aId;
|
||||
return aId + ".xpi";
|
||||
}
|
||||
@ -569,7 +571,7 @@ function writeInstallRDFForExtension(aData, aDir, aId, aExtraFile) {
|
||||
|
||||
var dir = aDir.clone();
|
||||
|
||||
if (Services.prefs.getBoolPref("extensions.alwaysUnpack")) {
|
||||
if (TEST_UNPACKED) {
|
||||
dir.append(id);
|
||||
writeInstallRDFToDir(aData, dir, aExtraFile);
|
||||
return dir;
|
||||
|
@ -73,6 +73,46 @@ function getUninstallReason() {
|
||||
return Services.prefs.getIntPref("bootstraptest.uninstall_reason");
|
||||
}
|
||||
|
||||
function manuallyInstall(aXPIFile, aInstallLocation, aID) {
|
||||
if (TEST_UNPACKED) {
|
||||
let dir = aInstallLocation.clone();
|
||||
dir.append(aID);
|
||||
dir.create(AM_Ci.nsIFile.DIRECTORY_TYPE, 0755);
|
||||
let zip = AM_Cc["@mozilla.org/libjar/zip-reader;1"].
|
||||
createInstance(AM_Ci.nsIZipReader);
|
||||
zip.open(aXPIFile);
|
||||
let entries = zip.findEntries(null);
|
||||
while (entries.hasMore()) {
|
||||
let entry = entries.getNext();
|
||||
let target = dir.clone();
|
||||
entry.split("/").forEach(function(aPart) {
|
||||
target.append(aPart);
|
||||
});
|
||||
zip.extract(entry, target);
|
||||
}
|
||||
zip.close();
|
||||
|
||||
return dir;
|
||||
}
|
||||
else {
|
||||
let target = aInstallLocation.clone();
|
||||
target.append(aID + ".xpi");
|
||||
aXPIFile.copyTo(target.parent, target.leafName);
|
||||
return target;
|
||||
}
|
||||
}
|
||||
|
||||
function manuallyUninstall(aInstallLocation, aID) {
|
||||
let file = getFileForAddon(aInstallLocation, aID);
|
||||
|
||||
// In reality because the app is restarted a flush isn't necessary for XPIs
|
||||
// removed outside the app, but for testing we must flush manually.
|
||||
if (file.isFile())
|
||||
Services.obs.notifyObservers(file, "flush-cache-entry", null);
|
||||
|
||||
file.remove(true);
|
||||
}
|
||||
|
||||
function run_test() {
|
||||
do_test_pending();
|
||||
|
||||
@ -369,18 +409,8 @@ function check_test_7() {
|
||||
function run_test_8() {
|
||||
shutdownManager();
|
||||
|
||||
let dir = profileDir.clone();
|
||||
dir.append("bootstrap1@tests.mozilla.org");
|
||||
dir.create(AM_Ci.nsIFile.DIRECTORY_TYPE, 0755);
|
||||
let zip = AM_Cc["@mozilla.org/libjar/zip-reader;1"].
|
||||
createInstance(AM_Ci.nsIZipReader);
|
||||
zip.open(do_get_addon("test_bootstrap1_1"));
|
||||
dir.append("install.rdf");
|
||||
zip.extract("install.rdf", dir);
|
||||
dir = dir.parent;
|
||||
dir.append("bootstrap.js");
|
||||
zip.extract("bootstrap.js", dir);
|
||||
zip.close();
|
||||
manuallyInstall(do_get_addon("test_bootstrap1_1"), profileDir,
|
||||
"bootstrap1@tests.mozilla.org");
|
||||
|
||||
startupManager(false);
|
||||
|
||||
@ -403,9 +433,8 @@ function run_test_8() {
|
||||
function run_test_9() {
|
||||
shutdownManager();
|
||||
|
||||
let dir = profileDir.clone();
|
||||
dir.append("bootstrap1@tests.mozilla.org");
|
||||
dir.remove(true);
|
||||
manuallyUninstall(profileDir, "bootstrap1@tests.mozilla.org");
|
||||
|
||||
startupManager(false);
|
||||
|
||||
AddonManager.getAddonByID("bootstrap1@tests.mozilla.org", function(b1) {
|
||||
@ -548,18 +577,8 @@ function check_test_11() {
|
||||
function run_test_12() {
|
||||
shutdownManager();
|
||||
|
||||
let dir = profileDir.clone();
|
||||
dir.append("bootstrap1@tests.mozilla.org");
|
||||
dir.create(AM_Ci.nsIFile.DIRECTORY_TYPE, 0755);
|
||||
let zip = AM_Cc["@mozilla.org/libjar/zip-reader;1"].
|
||||
createInstance(AM_Ci.nsIZipReader);
|
||||
zip.open(do_get_addon("test_bootstrap1_1"));
|
||||
dir.append("install.rdf");
|
||||
zip.extract("install.rdf", dir);
|
||||
dir = dir.parent;
|
||||
dir.append("bootstrap.js");
|
||||
zip.extract("bootstrap.js", dir);
|
||||
zip.close();
|
||||
manuallyInstall(do_get_addon("test_bootstrap1_1"), profileDir,
|
||||
"bootstrap1@tests.mozilla.org");
|
||||
|
||||
startupManager(true);
|
||||
|
||||
@ -654,18 +673,8 @@ function check_test_13() {
|
||||
function run_test_14() {
|
||||
shutdownManager();
|
||||
|
||||
let dir = profileDir.clone();
|
||||
dir.append("bootstrap1@tests.mozilla.org");
|
||||
dir.create(AM_Ci.nsIFile.DIRECTORY_TYPE, 0755);
|
||||
let zip = AM_Cc["@mozilla.org/libjar/zip-reader;1"].
|
||||
createInstance(AM_Ci.nsIZipReader);
|
||||
zip.open(do_get_addon("test_bootstrap1_3"));
|
||||
dir.append("install.rdf");
|
||||
zip.extract("install.rdf", dir);
|
||||
dir = dir.parent;
|
||||
dir.append("bootstrap.js");
|
||||
zip.extract("bootstrap.js", dir);
|
||||
zip.close();
|
||||
manuallyInstall(do_get_addon("test_bootstrap1_3"), profileDir,
|
||||
"bootstrap1@tests.mozilla.org");
|
||||
|
||||
startupManager(false);
|
||||
|
||||
@ -808,18 +817,8 @@ function run_test_16() {
|
||||
function run_test_17() {
|
||||
shutdownManager();
|
||||
|
||||
let dir = userExtDir.clone();
|
||||
dir.append("bootstrap1@tests.mozilla.org");
|
||||
dir.create(AM_Ci.nsIFile.DIRECTORY_TYPE, 0755);
|
||||
let zip = AM_Cc["@mozilla.org/libjar/zip-reader;1"].
|
||||
createInstance(AM_Ci.nsIZipReader);
|
||||
zip.open(do_get_addon("test_bootstrap1_1"));
|
||||
dir.append("install.rdf");
|
||||
zip.extract("install.rdf", dir);
|
||||
dir = dir.parent;
|
||||
dir.append("bootstrap.js");
|
||||
zip.extract("bootstrap.js", dir);
|
||||
zip.close();
|
||||
manuallyInstall(do_get_addon("test_bootstrap1_1"), userExtDir,
|
||||
"bootstrap1@tests.mozilla.org");
|
||||
|
||||
resetPrefs();
|
||||
startupManager();
|
||||
@ -902,18 +901,8 @@ function run_test_20() {
|
||||
resetPrefs();
|
||||
shutdownManager();
|
||||
|
||||
let dir = profileDir.clone();
|
||||
dir.append("bootstrap1@tests.mozilla.org");
|
||||
dir.create(AM_Ci.nsIFile.DIRECTORY_TYPE, 0755);
|
||||
let zip = AM_Cc["@mozilla.org/libjar/zip-reader;1"].
|
||||
createInstance(AM_Ci.nsIZipReader);
|
||||
zip.open(do_get_addon("test_bootstrap1_2"));
|
||||
dir.append("install.rdf");
|
||||
zip.extract("install.rdf", dir);
|
||||
dir = dir.parent;
|
||||
dir.append("bootstrap.js");
|
||||
zip.extract("bootstrap.js", dir);
|
||||
zip.close();
|
||||
manuallyInstall(do_get_addon("test_bootstrap1_2"), profileDir,
|
||||
"bootstrap1@tests.mozilla.org");
|
||||
|
||||
startupManager();
|
||||
|
||||
@ -939,9 +928,7 @@ function run_test_21() {
|
||||
resetPrefs();
|
||||
shutdownManager();
|
||||
|
||||
let dir = profileDir.clone();
|
||||
dir.append("bootstrap1@tests.mozilla.org");
|
||||
dir.remove(true);
|
||||
manuallyUninstall(profileDir, "bootstrap1@tests.mozilla.org");
|
||||
|
||||
startupManager();
|
||||
|
||||
@ -964,9 +951,7 @@ function run_test_21() {
|
||||
|
||||
do_check_eq(getStartupReason(), APP_STARTUP);
|
||||
|
||||
dir = userExtDir.clone();
|
||||
dir.append("bootstrap1@tests.mozilla.org");
|
||||
dir.remove(true);
|
||||
manuallyUninstall(userExtDir, "bootstrap1@tests.mozilla.org");
|
||||
|
||||
restartManager();
|
||||
|
||||
@ -978,21 +963,11 @@ function run_test_21() {
|
||||
function run_test_22() {
|
||||
shutdownManager();
|
||||
|
||||
let dir = profileDir.clone();
|
||||
dir.append("bootstrap1@tests.mozilla.org");
|
||||
dir.create(AM_Ci.nsIFile.DIRECTORY_TYPE, 0755);
|
||||
let zip = AM_Cc["@mozilla.org/libjar/zip-reader;1"].
|
||||
createInstance(AM_Ci.nsIZipReader);
|
||||
zip.open(do_get_addon("test_bootstrap1_1"));
|
||||
dir.append("install.rdf");
|
||||
zip.extract("install.rdf", dir);
|
||||
dir = dir.parent;
|
||||
dir.append("bootstrap.js");
|
||||
zip.extract("bootstrap.js", dir);
|
||||
zip.close();
|
||||
let file = manuallyInstall(do_get_addon("test_bootstrap1_1"), profileDir,
|
||||
"bootstrap1@tests.mozilla.org");
|
||||
|
||||
// Make it look old so changes are detected
|
||||
setExtensionModifiedTime(dir.parent, dir.parent.lastModifiedTime - 5000);
|
||||
setExtensionModifiedTime(file, file.lastModifiedTime - 5000);
|
||||
|
||||
startupManager();
|
||||
|
||||
@ -1007,18 +982,9 @@ function run_test_22() {
|
||||
resetPrefs();
|
||||
shutdownManager();
|
||||
|
||||
dir = dir.parent;
|
||||
dir.remove(true);
|
||||
dir.create(AM_Ci.nsIFile.DIRECTORY_TYPE, 0755);
|
||||
let zip = AM_Cc["@mozilla.org/libjar/zip-reader;1"].
|
||||
createInstance(AM_Ci.nsIZipReader);
|
||||
zip.open(do_get_addon("test_bootstrap1_2"));
|
||||
dir.append("install.rdf");
|
||||
zip.extract("install.rdf", dir);
|
||||
dir = dir.parent;
|
||||
dir.append("bootstrap.js");
|
||||
zip.extract("bootstrap.js", dir);
|
||||
zip.close();
|
||||
manuallyUninstall(profileDir, "bootstrap1@tests.mozilla.org");
|
||||
manuallyInstall(do_get_addon("test_bootstrap1_2"), profileDir,
|
||||
"bootstrap1@tests.mozilla.org");
|
||||
|
||||
startupManager();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user