diff --git a/browser/base/content/test/general/browser.ini b/browser/base/content/test/general/browser.ini index 5cbe3e973d47..e8e37c162a22 100644 --- a/browser/base/content/test/general/browser.ini +++ b/browser/base/content/test/general/browser.ini @@ -263,7 +263,6 @@ skip-if = true # disabled until the tree view is added # it ever is (bug 480169) [browser_save_link-perwindowpb.js] [browser_save_private_link_perwindowpb.js] -skip-if = os == "linux" # bug 857427 [browser_save_video.js] [browser_scope.js] [browser_selectTabAtIndex.js] diff --git a/browser/base/content/test/general/browser_save_private_link_perwindowpb.js b/browser/base/content/test/general/browser_save_private_link_perwindowpb.js index 893256beb31a..218531ea0157 100644 --- a/browser/base/content/test/general/browser_save_private_link_perwindowpb.js +++ b/browser/base/content/test/general/browser_save_private_link_perwindowpb.js @@ -36,45 +36,13 @@ function test() { storage.asyncVisitStorage(new Visitor(), true /* Do walk entries */); } - function contextMenuOpened(aWindow, event) { - cache.clear(); - - event.currentTarget.removeEventListener("popupshown", contextMenuOpened); - - // Create the folder the image will be saved into. - var destDir = createTemporarySaveDirectory(); - var destFile = destDir.clone(); - - MockFilePicker.displayDirectory = destDir; - MockFilePicker.showCallback = function(fp) { - fileName = fp.defaultString; - destFile.append (fileName); - MockFilePicker.returnFiles = [destFile]; - MockFilePicker.filterIndex = 1; // kSaveAsType_URL - }; - - mockTransferCallback = onTransferComplete; - mockTransferRegisterer.register(); - - registerCleanupFunction(function () { - mockTransferRegisterer.unregister(); - MockFilePicker.cleanup(); - destDir.remove(true); - }); - - // Select "Save Image As" option from context menu - var saveVideoCommand = aWindow.document.getElementById("context-saveimage"); - saveVideoCommand.doCommand(); - - event.target.hidePopup(); - } - function onTransferComplete(downloadSuccess) { ok(downloadSuccess, "Image file should have been downloaded successfully"); // Give the request a chance to finish and create a cache entry executeSoon(function() { checkDiskCacheFor(fileName, finish); + mockTransferCallback = null; }); } @@ -89,6 +57,39 @@ function test() { } function doTest(aIsPrivateMode, aWindow, aCallback) { + function contextMenuOpened(event) { + cache.clear(); + + aWindow.document.removeEventListener("popupshown", contextMenuOpened); + + // Create the folder the image will be saved into. + var destDir = createTemporarySaveDirectory(); + var destFile = destDir.clone(); + + MockFilePicker.displayDirectory = destDir; + MockFilePicker.showCallback = function(fp) { + fileName = fp.defaultString; + destFile.append (fileName); + MockFilePicker.returnFiles = [destFile]; + MockFilePicker.filterIndex = 1; // kSaveAsType_URL + }; + + mockTransferCallback = onTransferComplete; + mockTransferRegisterer.register(); + + registerCleanupFunction(function () { + mockTransferRegisterer.unregister(); + MockFilePicker.cleanup(); + destDir.remove(true); + }); + + // Select "Save Image As" option from context menu + var saveVideoCommand = aWindow.document.getElementById("context-saveimage"); + saveVideoCommand.doCommand(); + + event.target.hidePopup(); + } + aWindow.gBrowser.addEventListener("pageshow", function pageShown(event) { // If data: -url PAC file isn't loaded soon enough, we may get about:privatebrowsing loaded if (event.target.location == "about:blank" || @@ -98,14 +99,13 @@ function test() { } aWindow.gBrowser.removeEventListener("pageshow", pageShown); - executeSoon(function () { - aWindow.document.addEventListener("popupshown", - function(e) contextMenuOpened(aWindow, e), false); + waitForFocus(function () { + aWindow.document.addEventListener("popupshown", contextMenuOpened, false); var img = aWindow.gBrowser.selectedBrowser.contentDocument.getElementById("img"); EventUtils.synthesizeMouseAtCenter(img, { type: "contextmenu", button: 2 }, aWindow.gBrowser.contentWindow); - }); + }, aWindow.gBrowser.selectedBrowser.contentWindow); }); } diff --git a/content/canvas/public/nsICanvasRenderingContextInternal.h b/content/canvas/public/nsICanvasRenderingContextInternal.h index 3f496534b65a..a1a1fc28e72c 100644 --- a/content/canvas/public/nsICanvasRenderingContextInternal.h +++ b/content/canvas/public/nsICanvasRenderingContextInternal.h @@ -97,6 +97,7 @@ public: // dst alpha is always 1.0. If this is never called, the context // defaults to false (not opaque). NS_IMETHOD SetIsOpaque(bool isOpaque) = 0; + virtual bool GetIsOpaque() = 0; // Invalidate this context and release any held resources, in preperation // for possibly reinitializing with SetDimensions/InitializeWithSurface. diff --git a/content/canvas/src/CanvasRenderingContext2D.cpp b/content/canvas/src/CanvasRenderingContext2D.cpp index ee62d8db5503..2631b6b01f2f 100755 --- a/content/canvas/src/CanvasRenderingContext2D.cpp +++ b/content/canvas/src/CanvasRenderingContext2D.cpp @@ -988,6 +988,10 @@ CanvasRenderingContext2D::SetIsOpaque(bool isOpaque) ClearTarget(); } + if (mOpaque) { + EnsureTarget(); + } + return NS_OK; } @@ -1062,6 +1066,10 @@ CanvasRenderingContext2D::SetContextOptions(JSContext* aCx, JS::HandleSnapshot(); } NS_IMETHOD SetIsOpaque(bool isOpaque) MOZ_OVERRIDE; + bool GetIsOpaque() MOZ_OVERRIDE { return mOpaque; } NS_IMETHOD Reset() MOZ_OVERRIDE; already_AddRefed GetCanvasLayer(nsDisplayListBuilder* aBuilder, CanvasLayer *aOldLayer, diff --git a/content/canvas/src/WebGLContext.h b/content/canvas/src/WebGLContext.h index 8933bfe01d0f..2c56966b44dc 100644 --- a/content/canvas/src/WebGLContext.h +++ b/content/canvas/src/WebGLContext.h @@ -178,6 +178,7 @@ public: mozilla::TemporaryRef GetSurfaceSnapshot() MOZ_OVERRIDE; NS_IMETHOD SetIsOpaque(bool b) MOZ_OVERRIDE { return NS_OK; }; + bool GetIsOpaque() MOZ_OVERRIDE { return false; } NS_IMETHOD SetContextOptions(JSContext* aCx, JS::Handle aOptions) MOZ_OVERRIDE; diff --git a/content/canvas/test/test_canvas.html b/content/canvas/test/test_canvas.html index c73a4ac20032..7142bfaf796a 100644 --- a/content/canvas/test/test_canvas.html +++ b/content/canvas/test/test_canvas.html @@ -21577,6 +21577,24 @@ function test_linedash() { } +

Canvas test: test_opaque

+ + + + + + + + + + + + + diff --git a/dom/webidl/CanvasRenderingContext2D.webidl b/dom/webidl/CanvasRenderingContext2D.webidl index 18598cee1828..6b1b375c562c 100644 --- a/dom/webidl/CanvasRenderingContext2D.webidl +++ b/dom/webidl/CanvasRenderingContext2D.webidl @@ -16,6 +16,8 @@ enum CanvasWindingRule { "nonzero", "evenodd" }; dictionary ContextAttributes2D { // whether or not we're planning to do a lot of readback operations boolean willReadFrequently = false; + // signal if the canvas contains an alpha channel + boolean alpha = true; }; dictionary HitRegionOptions { diff --git a/js/src/builtin/TypeRepresentation.cpp b/js/src/builtin/TypeRepresentation.cpp index 786eb5a6061d..77ee3de3ef75 100644 --- a/js/src/builtin/TypeRepresentation.cpp +++ b/js/src/builtin/TypeRepresentation.cpp @@ -309,9 +309,9 @@ StructTypeRepresentation::init(JSContext *cx, // We compute alignment into the field `align_` directly in the // loop below, but not `size_` because we have to very careful - // about overflow. For now, we always use a uint32_t for + // about overflow. For now, we always use a int32_t for // consistency across build environments. - uint32_t totalSize = 0; + int32_t totalSize = 0; // These will be adjusted in the loop below: alignment_ = 1; @@ -324,7 +324,7 @@ StructTypeRepresentation::init(JSContext *cx, if (fieldTypeRepr->opaque()) opaque_ = true; - uint32_t alignedSize = alignTo(totalSize, fieldTypeRepr->alignment()); + int32_t alignedSize = alignTo(totalSize, fieldTypeRepr->alignment()); if (alignedSize < totalSize) { JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_TYPEDOBJECT_TOO_BIG); @@ -335,7 +335,7 @@ StructTypeRepresentation::init(JSContext *cx, fieldTypeRepr, alignedSize); alignment_ = js::Max(alignment_, fieldTypeRepr->alignment()); - uint32_t incrementedSize = alignedSize + fieldTypeRepr->size(); + int32_t incrementedSize = alignedSize + fieldTypeRepr->size(); if (incrementedSize < alignedSize) { JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_TYPEDOBJECT_TOO_BIG); @@ -345,7 +345,7 @@ StructTypeRepresentation::init(JSContext *cx, totalSize = incrementedSize; } - uint32_t alignedSize = alignTo(totalSize, alignment_); + int32_t alignedSize = alignTo(totalSize, alignment_); if (alignedSize < totalSize) { JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_TYPEDOBJECT_TOO_BIG); diff --git a/js/src/builtin/TypedObject.cpp b/js/src/builtin/TypedObject.cpp index 2d07bcfc510d..9878936c92b6 100644 --- a/js/src/builtin/TypedObject.cpp +++ b/js/src/builtin/TypedObject.cpp @@ -2301,6 +2301,12 @@ TypedObject::constructSized(JSContext *cx, unsigned int argc, Value *vp) Rooted buffer(cx); buffer = &args[0].toObject().as(); + if (buffer->isNeutered()) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, + nullptr, JSMSG_TYPEDOBJECT_BAD_ARGS); + return false; + } + int32_t offset; if (args.length() >= 2 && !args[1].isUndefined()) { if (!args[1].isInt32()) { @@ -2407,6 +2413,12 @@ TypedObject::constructUnsized(JSContext *cx, unsigned int argc, Value *vp) Rooted buffer(cx); buffer = &args[0].toObject().as(); + if (buffer->isNeutered()) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, + nullptr, JSMSG_TYPEDOBJECT_BAD_ARGS); + return false; + } + int32_t offset; if (args.length() >= 2 && !args[1].isUndefined()) { if (!args[1].isInt32()) { diff --git a/js/src/jit-test/tests/TypedObject/atopneuteredbuffer.js b/js/src/jit-test/tests/TypedObject/atopneuteredbuffer.js new file mode 100644 index 000000000000..f6fd73badaca --- /dev/null +++ b/js/src/jit-test/tests/TypedObject/atopneuteredbuffer.js @@ -0,0 +1,23 @@ +// Bug 976697. Check for various quirks when instantiating a typed +// object atop an already neutered buffer. + +if (typeof TypedObject === "undefined") + quit(); + +load(libdir + "asserts.js") + +var {StructType, uint32, Object, Any, storage, objectType} = TypedObject; + +function main() { // once a C programmer, always a C programmer. + var Uints = uint32.array(); + var Unit = new StructType({}); // Empty struct type + var buffer = new ArrayBuffer(0); // Empty buffer + var p = new Unit(buffer); // OK + neuter(buffer); + assertThrowsInstanceOf(() => new Unit(buffer), TypeError, + "Able to instantiate atop neutered buffer"); + assertThrowsInstanceOf(() => new Uints(buffer, 0), TypeError, + "Able to instantiate atop neutered buffer"); +} + +main(); diff --git a/js/src/jit-test/tests/TypedObject/bug976530.js b/js/src/jit-test/tests/TypedObject/bug976530.js new file mode 100644 index 000000000000..650a260402fe --- /dev/null +++ b/js/src/jit-test/tests/TypedObject/bug976530.js @@ -0,0 +1,10 @@ +// |jit-test| error:Error + +// Test that we don't permit structs whose fields exceed 32 bits. + +if (!this.hasOwnProperty("TypedObject")) + throw new Error(); + +var Vec3u16Type = TypedObject.uint16.array((1073741823)); +var PairVec3u16Type = new TypedObject.StructType({ fst: Vec3u16Type, snd: Vec3u16Type }); +new PairVec3u16Type(); diff --git a/js/src/jit-test/tests/TypedObject/bug976697.js b/js/src/jit-test/tests/TypedObject/bug976697.js new file mode 100644 index 000000000000..4775ccae02bd --- /dev/null +++ b/js/src/jit-test/tests/TypedObject/bug976697.js @@ -0,0 +1,13 @@ +// Test that instantiating a typed array on top of a neutered buffer +// doesn't trip any asserts. +// +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +if (!this.hasOwnProperty("TypedObject")) + quit(); + +x = ArrayBuffer(); +neuter(x); +Uint32Array(x); +gc(); diff --git a/js/src/jit/arm/Assembler-arm.cpp b/js/src/jit/arm/Assembler-arm.cpp index 391c1e87e168..ebab67ce4faa 100644 --- a/js/src/jit/arm/Assembler-arm.cpp +++ b/js/src/jit/arm/Assembler-arm.cpp @@ -1807,11 +1807,6 @@ Assembler::placeConstantPoolBarrier(int offset) // this is still an active path, however, we do not hit it in the test // suite at all. MOZ_ASSUME_UNREACHABLE("ARMAssembler holdover"); -#if 0 - offset = (offset - sizeof(ARMWord)) >> 2; - ASSERT((offset <= BOFFSET_MAX && offset >= BOFFSET_MIN)); - return AL | B | (offset & BRANCH_MASK); -#endif } // Control flow stuff: diff --git a/js/src/jit/arm/Bailouts-arm.cpp b/js/src/jit/arm/Bailouts-arm.cpp index 1eb868ab8274..03fe75157b7b 100644 --- a/js/src/jit/arm/Bailouts-arm.cpp +++ b/js/src/jit/arm/Bailouts-arm.cpp @@ -13,54 +13,6 @@ using namespace js; using namespace js::jit; -#if 0 -// no clue what these asserts should be. -JS_STATIC_ASSERT(sizeof(BailoutStack) == - sizeof(uintptr_t) + - sizeof(double) * 8 + - sizeof(uintptr_t) * 8 + - sizeof(uintptr_t)); - -JS_STATIC_ASSERT(sizeof(ExtendedBailoutStack) == - sizeof(BailoutStack) + - sizeof(uintptr_t)); - -#endif -#if 0 -BailoutEnvironment::BailoutEnvironment(JitCompartment *ion, void **sp) - : sp_(sp) -{ - bailout_ = reinterpret_cast(sp); - - if (bailout_->frameClass() != FrameSizeClass::None()) { - frameSize_ = bailout_->frameSize(); - frame_ = &sp_[sizeof(BailoutStack) / sizeof(void *)]; - - // Compute the bailout ID. - JitCode *code = ion->getBailoutTable(bailout_->frameClass()); - uintptr_t tableOffset = bailout_->tableOffset(); - uintptr_t tableStart = reinterpret_cast(code->raw()); - - JS_ASSERT(tableOffset >= tableStart && - tableOffset < tableStart + code->instructionsSize()); - JS_ASSERT((tableOffset - tableStart) % BAILOUT_TABLE_ENTRY_SIZE == 0); - - bailoutId_ = ((tableOffset - tableStart) / BAILOUT_TABLE_ENTRY_SIZE) - 1; - JS_ASSERT(bailoutId_ < BAILOUT_TABLE_SIZE); - } else { - frameSize_ = bailout_->frameSize(); - frame_ = &sp_[sizeof(ExtendedBailoutStack) / sizeof(void *)]; - } -} - -IonFramePrefix * -BailoutEnvironment::top() const -{ - return (IonFramePrefix *)&frame_[frameSize_ / sizeof(void *)]; -} - -#endif - namespace js { namespace jit { diff --git a/js/src/jit/arm/CodeGenerator-arm.cpp b/js/src/jit/arm/CodeGenerator-arm.cpp index b850916f88e8..37e544657855 100644 --- a/js/src/jit/arm/CodeGenerator-arm.cpp +++ b/js/src/jit/arm/CodeGenerator-arm.cpp @@ -242,23 +242,8 @@ CodeGeneratorARM::bailoutFrom(Label *label, LSnapshot *snapshot) // isn't properly aligned to the static frame size. JS_ASSERT_IF(frameClass_ != FrameSizeClass::None(), frameClass_.frameSize() == masm.framePushed()); - // This involves retargeting a label, which I've declared is always going - // to be a pc-relative branch to an absolute address! - // With no assurance that this is going to be a local branch, I am wary to - // implement this. Moreover, If it isn't a local branch, it will be large - // and possibly slow. I believe that the correct way to handle this is to - // subclass label into a fatlabel, where we generate enough room for a load - // before the branch -#if 0 - if (assignBailoutId(snapshot)) { - uint8_t *code = deoptTable_->raw() + snapshot->bailoutId() * BAILOUT_TABLE_ENTRY_SIZE; - masm.retarget(label, code, Relocation::HARDCODED); - return true; - } -#endif - // We could not use a jump table, either because all bailout IDs were - // reserved, or a jump table is not optimal for this frame size or - // platform. Whatever, we will generate a lazy bailout. + + // On ARM we don't use a bailout table. OutOfLineBailout *ool = new(alloc()) OutOfLineBailout(snapshot, masm.framePushed()); if (!addOutOfLineCode(ool)) { return false; @@ -1661,14 +1646,6 @@ CodeGeneratorARM::visitNotD(LNotD *ins) masm.ma_mov(Imm32(0), dest); masm.ma_mov(Imm32(1), dest, NoSetCond, Assembler::Equal); masm.ma_mov(Imm32(1), dest, NoSetCond, Assembler::Overflow); -#if 0 - masm.as_vmrs(ToRegister(dest)); - // Mask out just the two bits we care about. If neither bit is set, - // the dest is already zero - masm.ma_and(Imm32(0x50000000), dest, dest, Assembler::SetCond); - // If it is non-zero, then force it to be 1. - masm.ma_mov(Imm32(1), dest, NoSetCond, Assembler::NotEqual); -#endif } return true; } @@ -1698,14 +1675,6 @@ CodeGeneratorARM::visitNotF(LNotF *ins) masm.ma_mov(Imm32(0), dest); masm.ma_mov(Imm32(1), dest, NoSetCond, Assembler::Equal); masm.ma_mov(Imm32(1), dest, NoSetCond, Assembler::Overflow); -#if 0 - masm.as_vmrs(ToRegister(dest)); - // Mask out just the two bits we care about. If neither bit is set, - // the dest is already zero - masm.ma_and(Imm32(0x50000000), dest, dest, Assembler::SetCond); - // If it is non-zero, then force it to be 1. - masm.ma_mov(Imm32(1), dest, NoSetCond, Assembler::NotEqual); -#endif } return true; } diff --git a/js/src/jit/arm/Trampoline-arm.cpp b/js/src/jit/arm/Trampoline-arm.cpp index c202c98b3b42..577ba6e70e68 100644 --- a/js/src/jit/arm/Trampoline-arm.cpp +++ b/js/src/jit/arm/Trampoline-arm.cpp @@ -148,18 +148,6 @@ JitRuntime::generateEnterJIT(JSContext *cx, EnterJitType type) masm.loadPtr(slot_vp, r10); masm.unboxInt32(Address(r10, 0), r10); -#if 0 - // This is in case we want to go back to using frames that - // aren't 8 byte alinged - // there are r1 2-word arguments to the js code - // we want 2 word alignment, so this shouldn't matter. - // After the arguments have been pushed, we want to push an additional 3 words of - // data, so in all, we want to decrease sp by 4 if it is currently aligned to - // 8, and not touch it otherwise - aasm->as_sub(sp, sp, Imm8(4)); - aasm->as_orr(sp, sp, Imm8(4)); -#endif - // Subtract off the size of the arguments from the stack pointer, store elsewhere aasm->as_sub(r4, sp, O2RegImmShift(r1, LSL, 3)); //r4 = sp - argc*8 // Get the final position of the stack pointer into the stack pointer diff --git a/js/src/vm/ArrayBufferObject.cpp b/js/src/vm/ArrayBufferObject.cpp index f41051315239..aa53c73b86d2 100644 --- a/js/src/vm/ArrayBufferObject.cpp +++ b/js/src/vm/ArrayBufferObject.cpp @@ -303,6 +303,7 @@ static ObjectElements * AllocateArrayBufferContents(JSContext *maybecx, uint32_t nbytes, void *oldptr = nullptr) { uint32_t size = nbytes + sizeof(ObjectElements); + JS_ASSERT(size > nbytes); // be wary of rollover ObjectElements *newheader; // if oldptr is given, then we need to do a realloc diff --git a/js/src/vm/ArrayBufferObject.h b/js/src/vm/ArrayBufferObject.h index f59f9de9cb59..f40dc579c421 100644 --- a/js/src/vm/ArrayBufferObject.h +++ b/js/src/vm/ArrayBufferObject.h @@ -302,7 +302,14 @@ InitArrayBufferViewDataPointer(ArrayBufferViewObject *obj, ArrayBufferObject *bu * private data rather than a slot to avoid alignment restrictions * on private Values. */ - obj->initPrivate(buffer->dataPointer() + byteOffset); + + if (buffer->isNeutered()) { + JS_ASSERT(byteOffset == 0); + obj->initPrivate(nullptr); + } else { + obj->initPrivate(buffer->dataPointer() + byteOffset); + } + PostBarrierTypedArrayObject(obj); } diff --git a/js/src/vm/TypedArrayObject.cpp b/js/src/vm/TypedArrayObject.cpp index 3e7dc77fc455..444fa2717c4b 100644 --- a/js/src/vm/TypedArrayObject.cpp +++ b/js/src/vm/TypedArrayObject.cpp @@ -362,7 +362,7 @@ class TypedArrayObjectTemplate : public TypedArrayObject uint32_t bufferByteLength = buffer->byteLength(); uint32_t arrayByteLength = obj->byteLength(); uint32_t arrayByteOffset = obj->byteOffset(); - JS_ASSERT(buffer->dataPointer() <= obj->viewData()); + JS_ASSERT_IF(!buffer->isNeutered(), buffer->dataPointer() <= obj->viewData()); JS_ASSERT(bufferByteLength - arrayByteOffset >= arrayByteLength); JS_ASSERT(arrayByteOffset <= bufferByteLength); diff --git a/toolkit/components/passwordmgr/test/test_privbrowsing_perwindowpb.html b/toolkit/components/passwordmgr/test/test_privbrowsing_perwindowpb.html index 0449e153dae7..6409caf60c39 100644 --- a/toolkit/components/passwordmgr/test/test_privbrowsing_perwindowpb.html +++ b/toolkit/components/passwordmgr/test/test_privbrowsing_perwindowpb.html @@ -24,6 +24,8 @@ const Ci = SpecialPowers.Ci; const Cc = SpecialPowers.Cc; const Cr = SpecialPowers.Cr; +Components.utils.import("resource://gre/modules/Services.jsm"); + var testpath = "/tests/toolkit/components/passwordmgr/test/"; var prefix = "http://test2.example.com" + testpath; var subtests = [ @@ -191,24 +193,35 @@ var mainWindow = window.QueryInterface(Ci.nsIInterfaceRequestor) var contentPage = "http://mochi.test:8888/tests/toolkit/components/passwordmgr/test/privbrowsing_perwindowpb_iframe.html"; var testWindows = []; +function whenDelayedStartupFinished(aWindow, aCallback) { + Services.obs.addObserver(function observer(aSubject, aTopic) { + if (aWindow == aSubject) { + Services.obs.removeObserver(observer, aTopic); + setTimeout(aCallback, 0); + } + }, "browser-delayed-startup-finished", false); +} + function testOnWindow(aIsPrivate, aCallback) { var win = mainWindow.OpenBrowserWindow({private: aIsPrivate}); win.addEventListener("load", function onLoad() { win.removeEventListener("load", onLoad, false); - win.addEventListener("DOMContentLoaded", function onInnerLoad() { - if (win.content.location.href != contentPage) { - win.gBrowser.loadURI(contentPage); - return; - } - win.removeEventListener("DOMContentLoaded", onInnerLoad, true); + whenDelayedStartupFinished(win, function() { + win.addEventListener("DOMContentLoaded", function onInnerLoad() { + if (win.content.location.href != contentPage) { + win.gBrowser.loadURI(contentPage); + return; + } + win.removeEventListener("DOMContentLoaded", onInnerLoad, true); - win.content.addEventListener('load', function innerLoad2() { - win.content.removeEventListener('load', innerLoad2, false); - testWindows.push(win); - SimpleTest.executeSoon(function() { aCallback(win); }); - }, false, true); - }, true); - SimpleTest.executeSoon(function() { win.gBrowser.loadURI(contentPage); }); + win.content.addEventListener('load', function innerLoad2() { + win.content.removeEventListener('load', innerLoad2, false); + testWindows.push(win); + SimpleTest.executeSoon(function() { aCallback(win); }); + }, false, true); + }, true); + SimpleTest.executeSoon(function() { win.gBrowser.loadURI(contentPage); }); + }); }, true); } diff --git a/toolkit/content/tests/chrome/test_dialogfocus.xul b/toolkit/content/tests/chrome/test_dialogfocus.xul index 32596cdf8fc4..80474e2b91a3 100644 --- a/toolkit/content/tests/chrome/test_dialogfocus.xul +++ b/toolkit/content/tests/chrome/test_dialogfocus.xul @@ -24,6 +24,7 @@ expected.length || (!fullKeyboardAccess && step == 2)) { + info("finishing"); SimpleTest.finish(); return; } @@ -55,11 +59,14 @@ function runTest() function checkDialogFocus(event) { + info("checkDialogFocus()"); // if full keyboard access is not on, just skip the tests var match = false; if (fullKeyboardAccess) { - if (!(event.target instanceof Element)) + if (!(event.target instanceof Element)) { + info("target not an Element"); return; + } if (expectedFocus == "textbox-yes") match = (win.document.activeElement == win.document.getElementById(expectedFocus).inputField); @@ -67,11 +74,13 @@ function runTest() match = (win.document.activeElement.dlgType == expectedFocus.substring(1)); else match = (win.document.activeElement.id == expectedFocus); + info("match = " + match); if (!match) return; } else { match = (win.document.activeElement == win.document.documentElement); + info("match = " + match); } win.removeEventListener("focus", checkDialogFocus, true);