diff --git a/accessible/atk/nsMaiInterfaceText.cpp b/accessible/atk/nsMaiInterfaceText.cpp index b6d80a30a5..b22ecdfd46 100644 --- a/accessible/atk/nsMaiInterfaceText.cpp +++ b/accessible/atk/nsMaiInterfaceText.cpp @@ -330,12 +330,17 @@ static gint getCharacterCountCB(AtkText *aText) { AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText)); - if (!accWrap) - return 0; + if (accWrap) { + HyperTextAccessible* textAcc = accWrap->AsHyperText(); + return + textAcc->IsDefunct() ? 0 : static_cast(textAcc->CharacterCount()); + } - HyperTextAccessible* textAcc = accWrap->AsHyperText(); - return textAcc->IsDefunct() ? - 0 : static_cast(textAcc->CharacterCount()); + if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) { + return proxy->CharacterCount(); + } + + return 0; } static gint @@ -362,14 +367,20 @@ static gint getTextSelectionCountCB(AtkText *aText) { AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText)); - if (!accWrap) - return 0; + if (accWrap) { + HyperTextAccessible* text = accWrap->AsHyperText(); + if (!text || !text->IsTextRole()) { + return 0; + } - HyperTextAccessible* text = accWrap->AsHyperText(); - if (!text || !text->IsTextRole()) - return 0; + return text->SelectionCount(); + } - return text->SelectionCount(); + if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) { + return proxy->SelectionCount(); + } + + return 0; } static gchar* diff --git a/accessible/ipc/DocAccessibleChild.cpp b/accessible/ipc/DocAccessibleChild.cpp index bf3672a926..5a28648a84 100644 --- a/accessible/ipc/DocAccessibleChild.cpp +++ b/accessible/ipc/DocAccessibleChild.cpp @@ -207,6 +207,22 @@ DocAccessibleChild::RecvRelations(const uint64_t& aID, return true; } +bool +DocAccessibleChild::RecvCharacterCount(const uint64_t& aID, int32_t* aCount) +{ + HyperTextAccessible* acc = IdToHyperTextAccessible(aID); + *aCount = acc ? acc->CharacterCount() : 0; + return true; +} + +bool +DocAccessibleChild::RecvSelectionCount(const uint64_t& aID, int32_t* aCount) +{ + HyperTextAccessible* acc = IdToHyperTextAccessible(aID); + *aCount = acc ? acc->SelectionCount() : 0; + return true; +} + bool DocAccessibleChild::RecvTextSubstring(const uint64_t& aID, const int32_t& aStartOffset, diff --git a/accessible/ipc/DocAccessibleChild.h b/accessible/ipc/DocAccessibleChild.h index b6d17729e5..35feb4c573 100644 --- a/accessible/ipc/DocAccessibleChild.h +++ b/accessible/ipc/DocAccessibleChild.h @@ -63,6 +63,12 @@ public: virtual bool RecvAttributes(const uint64_t& aID, nsTArray *aAttributes) override; + + virtual bool RecvCharacterCount(const uint64_t& aID, int32_t* aCount) + override; + virtual bool RecvSelectionCount(const uint64_t& aID, int32_t* aCount) + override; + virtual bool RecvTextSubstring(const uint64_t& aID, const int32_t& aStartOffset, const int32_t& aEndOffset, nsString* aText) diff --git a/accessible/ipc/PDocAccessible.ipdl b/accessible/ipc/PDocAccessible.ipdl index 7464787cd2..21be62a092 100644 --- a/accessible/ipc/PDocAccessible.ipdl +++ b/accessible/ipc/PDocAccessible.ipdl @@ -65,6 +65,8 @@ child: // AccessibleText // TextSubstring is getText in IDL. + prio(high) sync CharacterCount(uint64_t aID) returns(int32_t aCount); + prio(high) sync SelectionCount(uint64_t aID) returns(int32_t aCount); prio(high) sync TextSubstring(uint64_t aID, int32_t aStartOffset, int32_t aEndOffset) returns(nsString aText); prio(high) sync GetTextAfterOffset(uint64_t aID, int32_t aOffset, int32_t aBoundaryType) diff --git a/accessible/ipc/ProxyAccessible.cpp b/accessible/ipc/ProxyAccessible.cpp index 8dd034c505..3ef225ff06 100644 --- a/accessible/ipc/ProxyAccessible.cpp +++ b/accessible/ipc/ProxyAccessible.cpp @@ -149,6 +149,22 @@ ProxyAccessible::Relations(nsTArray* aTypes, } } +int32_t +ProxyAccessible::CharacterCount() +{ + int32_t count = 0; + unused << mDoc->SendCharacterCount(mID, &count); + return count; +} + +int32_t +ProxyAccessible::SelectionCount() +{ + int32_t count = 0; + unused << mDoc->SendSelectionCount(mID, &count); + return count; +} + void ProxyAccessible::TextSubstring(int32_t aStartOffset, int32_t aEndOfset, nsString& aText) const diff --git a/accessible/ipc/ProxyAccessible.h b/accessible/ipc/ProxyAccessible.h index 83fae3b889..7c89f3dd85 100644 --- a/accessible/ipc/ProxyAccessible.h +++ b/accessible/ipc/ProxyAccessible.h @@ -99,6 +99,9 @@ public: void Relations(nsTArray* aTypes, nsTArray>* aTargetSets) const; + int32_t CharacterCount(); + int32_t SelectionCount(); + /** * Get the text between the given offsets. */ diff --git a/dom/base/nsCCUncollectableMarker.cpp b/dom/base/nsCCUncollectableMarker.cpp index 55b78a7f0b..3b61bda4c0 100644 --- a/dom/base/nsCCUncollectableMarker.cpp +++ b/dom/base/nsCCUncollectableMarker.cpp @@ -16,6 +16,7 @@ #include "nsISHistory.h" #include "nsISHEntry.h" #include "nsISHContainer.h" +#include "nsITabChild.h" #include "nsIWindowWatcher.h" #include "mozilla/Services.h" #include "nsIXULWindow.h" @@ -297,6 +298,15 @@ MarkWindowList(nsISimpleEnumerator* aWindowList, bool aCleanupJS, nsCOMPtr rootDocShell = window->GetDocShell(); MarkDocShell(rootDocShell, aCleanupJS, aPrepareForCC); + + nsCOMPtr tabChild = do_GetInterface(rootDocShell); + if (tabChild) { + nsCOMPtr mm; + tabChild->GetMessageManager(getter_AddRefs(mm)); + if (mm) { + mm->MarkForCC(); + } + } } } } diff --git a/dom/base/nsRange.h b/dom/base/nsRange.h index 25eec6471d..432b33f242 100644 --- a/dom/base/nsRange.h +++ b/dom/base/nsRange.h @@ -327,13 +327,14 @@ protected: int32_t mStartOffset; int32_t mEndOffset; - bool mIsPositioned; - bool mIsDetached; - bool mMaySpanAnonymousSubtrees; - bool mIsGenerated; - bool mStartOffsetWasIncremented; - bool mEndOffsetWasIncremented; - bool mEnableGravitationOnElementRemoval; + bool mIsPositioned : 1; + bool mIsDetached : 1; + bool mMaySpanAnonymousSubtrees : 1; + bool mInSelection : 1; + bool mIsGenerated : 1; + bool mStartOffsetWasIncremented : 1; + bool mEndOffsetWasIncremented : 1; + bool mEnableGravitationOnElementRemoval : 1; #ifdef DEBUG int32_t mAssertNextInsertOrAppendIndex; nsINode* mAssertNextInsertOrAppendNode; diff --git a/dom/base/nsXMLHttpRequest.cpp b/dom/base/nsXMLHttpRequest.cpp index 6417f23294..732df6f3e1 100644 --- a/dom/base/nsXMLHttpRequest.cpp +++ b/dom/base/nsXMLHttpRequest.cpp @@ -3023,13 +3023,18 @@ nsXMLHttpRequest::Send(nsIVariant* aVariant, const Nullable& aBody) if (method.EqualsLiteral("POST")) { AddLoadFlags(mChannel, nsIRequest::LOAD_BYPASS_CACHE | nsIRequest::INHIBIT_CACHING); - } - // When we are sync loading, we need to bypass the local cache when it would - // otherwise block us waiting for exclusive access to the cache. If we don't - // do this, then we could dead lock in some cases (see bug 309424). - else if (!(mState & XML_HTTP_REQUEST_ASYNC)) { + } else { + // When we are sync loading, we need to bypass the local cache when it would + // otherwise block us waiting for exclusive access to the cache. If we don't + // do this, then we could dead lock in some cases (see bug 309424). + // + // Also don't block on the cache entry on async if it is busy - favoring parallelism + // over cache hit rate for xhr. This does not disable the cache everywhere - + // only in cases where more than one channel for the same URI is accessed + // simultanously. + AddLoadFlags(mChannel, - nsICachingChannel::LOAD_BYPASS_LOCAL_CACHE_IF_BUSY); + nsICachingChannel::LOAD_BYPASS_LOCAL_CACHE_IF_BUSY); } // Since we expect XML data, set the type hint accordingly diff --git a/dom/base/test/unit/test_error_codes.js b/dom/base/test/unit/test_error_codes.js index 737241a751..c4f488f189 100644 --- a/dom/base/test/unit/test_error_codes.js +++ b/dom/base/test/unit/test_error_codes.js @@ -6,6 +6,9 @@ var gExpectedStatus = null; var gNextTestFunc = null; +var prefs = Components.classes["@mozilla.org/preferences-service;1"]. + getService(Components.interfaces.nsIPrefBranch); + var asyncXHR = { load: function() { var request = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"] @@ -39,6 +42,7 @@ function run_test_pt1() { catch (e) { } ioService.offline = true; + prefs.setBoolPref("network.dns.offline-localhost", false); gExpectedStatus = Components.results.NS_ERROR_OFFLINE; gNextTestFunc = run_test_pt2; @@ -51,6 +55,7 @@ function run_test_pt2() { var ioService = Components.classes["@mozilla.org/network/io-service;1"] .getService(Components.interfaces.nsIIOService); ioService.offline = false; + prefs.clearUserPref("network.dns.offline-localhost"); gExpectedStatus = Components.results.NS_ERROR_CONNECTION_REFUSED; gNextTestFunc = end_test; diff --git a/dom/media/webaudio/AnalyserNode.cpp b/dom/media/webaudio/AnalyserNode.cpp index a185436315..d6adbcfcf8 100644 --- a/dom/media/webaudio/AnalyserNode.cpp +++ b/dom/media/webaudio/AnalyserNode.cpp @@ -66,9 +66,21 @@ public: MutexAutoLock lock(NodeMutex()); - if (Node() && - aInput.mChannelData.Length() > 0) { - nsRefPtr transfer = new TransferBuffer(aStream, aInput); + if (Node()) { + // If the input is silent, we sill need to send a silent buffer + if (aOutput->IsNull()) { + AllocateAudioBlock(1, aOutput); + float* samples = static_cast( + const_cast(aOutput->mChannelData[0])); + PodZero(samples, WEBAUDIO_BLOCK_SIZE); + } + uint32_t channelCount = aOutput->mChannelData.Length(); + for (uint32_t channel = 0; channel < channelCount; ++channel) { + float* samples = static_cast( + const_cast(aOutput->mChannelData[channel])); + AudioBlockInPlaceScale(samples, aOutput->mVolume); + } + nsRefPtr transfer = new TransferBuffer(aStream, *aOutput); NS_DispatchToMainThread(transfer); } } diff --git a/dom/media/webaudio/test/mochitest.ini b/dom/media/webaudio/test/mochitest.ini index 088a30dfae..7dd6f2de91 100644 --- a/dom/media/webaudio/test/mochitest.ini +++ b/dom/media/webaudio/test/mochitest.ini @@ -26,6 +26,7 @@ support-files = webaudio.js [test_analyserNode.html] +[test_analyserScale.html] [test_analyserNodeOutput.html] [test_analyserNodePassThrough.html] [test_AudioBuffer.html] diff --git a/dom/media/webaudio/test/test_analyserScale.html b/dom/media/webaudio/test/test_analyserScale.html new file mode 100644 index 0000000000..3aec8d22b2 --- /dev/null +++ b/dom/media/webaudio/test/test_analyserScale.html @@ -0,0 +1,59 @@ + + + + Test AnalyserNode when the input is scaled + + + + + +
+
+
+ + diff --git a/dom/promise/Promise.cpp b/dom/promise/Promise.cpp index 7dcd07690e..4674ee2b92 100644 --- a/dom/promise/Promise.cpp +++ b/dom/promise/Promise.cpp @@ -283,6 +283,32 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(Promise) NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER NS_IMPL_CYCLE_COLLECTION_TRACE_END +NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(Promise) + if (tmp->IsBlack()) { + if (tmp->mResult.isObject()) { + JS::ExposeObjectToActiveJS(&(tmp->mResult.toObject())); + } + if (tmp->mAllocationStack) { + JS::ExposeObjectToActiveJS(tmp->mAllocationStack); + } + if (tmp->mRejectionStack) { + JS::ExposeObjectToActiveJS(tmp->mRejectionStack); + } + if (tmp->mFullfillmentStack) { + JS::ExposeObjectToActiveJS(tmp->mFullfillmentStack); + } + return true; + } +NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_END + +NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_BEGIN(Promise) + return tmp->IsBlackAndDoesNotNeedTracing(tmp); +NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_END + +NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_BEGIN(Promise) + return tmp->IsBlack(); +NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_END + NS_IMPL_CYCLE_COLLECTING_ADDREF(Promise) NS_IMPL_CYCLE_COLLECTING_RELEASE(Promise) diff --git a/dom/promise/Promise.h b/dom/promise/Promise.h index bfce3809eb..61896a5b48 100644 --- a/dom/promise/Promise.h +++ b/dom/promise/Promise.h @@ -75,7 +75,7 @@ class Promise : public nsISupports, public: NS_DECLARE_STATIC_IID_ACCESSOR(NS_PROMISE_IID) NS_DECL_CYCLE_COLLECTING_ISUPPORTS - NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(Promise) + NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS(Promise) MOZ_DECLARE_WEAKREFERENCE_TYPENAME(Promise) // Promise creation tries to create a JS reflector for the Promise, so is diff --git a/js/src/builtin/Object.cpp b/js/src/builtin/Object.cpp index 03e351ab23..dafbe7178e 100644 --- a/js/src/builtin/Object.cpp +++ b/js/src/builtin/Object.cpp @@ -1061,7 +1061,6 @@ static const JSFunctionSpec object_static_methods[] = { JS_FN("getPrototypeOf", obj_getPrototypeOf, 1,0), JS_FN("setPrototypeOf", obj_setPrototypeOf, 2,0), JS_FN("getOwnPropertyDescriptor", obj_getOwnPropertyDescriptor,2,0), - JS_SELF_HOSTED_FN("getOwnPropertyDescriptors", "ObjectGetOwnPropertyDescriptors", 1,JSPROP_DEFINE_LATE), JS_FN("keys", obj_keys, 1,0), JS_SELF_HOSTED_FN("values", "ObjectValues", 1,JSPROP_DEFINE_LATE), JS_SELF_HOSTED_FN("entries", "ObjectEntries", 1,JSPROP_DEFINE_LATE), diff --git a/js/src/builtin/Object.js b/js/src/builtin/Object.js index eb5a4abe02..2d96ddd170 100644 --- a/js/src/builtin/Object.js +++ b/js/src/builtin/Object.js @@ -41,33 +41,6 @@ function ObjectStaticAssign(target, firstSource) { return to; } -// ES stage 4 proposal -function ObjectGetOwnPropertyDescriptors(O) { - // Step 1. - var obj = ToObject(O); - - // Step 2. - var keys = OwnPropertyKeys(obj, JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS); - - // Step 3. - var descriptors = {}; - - // Step 4. - for (var index = 0, len = keys.length; index < len; index++) { - var key = keys[index]; - - // Steps 4.a-b. - var desc = std_Object_getOwnPropertyDescriptor(obj, key); - - // Step 4.c. - if (typeof desc !== "undefined") - _DefineDataProperty(descriptors, key, desc); - } - - // Step 5. - return descriptors; -} - function ObjectDefineSetter(name, setter) { var object; if (this === null || this === undefined) diff --git a/js/src/jit-test/tests/basic/bug1135718.js b/js/src/jit-test/tests/basic/bug1135718.js new file mode 100644 index 0000000000..312c2ce35d --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1135718.js @@ -0,0 +1,13 @@ + +setJitCompilerOption("ion.warmup.trigger", 30); +function ArrayCallback(state) + this.state = state; +ArrayCallback.prototype.isUpperCase = function(v, index, array) { + return this.state ? true : (v == v.toUpperCase()); +}; +strings = ['hello', 'Array', 'WORLD']; +obj = new ArrayCallback(false); +strings.filter(obj.isUpperCase, obj) +obj = new ArrayCallback(true); +strings.filter(obj.isUpperCase, obj) +obj.__proto__ = {}; diff --git a/js/src/jit/Lowering.cpp b/js/src/jit/Lowering.cpp index b112200592..ce78f6f0c4 100644 --- a/js/src/jit/Lowering.cpp +++ b/js/src/jit/Lowering.cpp @@ -2535,9 +2535,12 @@ LIRGenerator::visitNot(MNot* ins) } void -LIRGenerator::visitBoundsCheck(MBoundsCheck* ins) +LIRGenerator::visitBoundsCheck(MBoundsCheck *ins) { - LInstruction* check; + if (!ins->fallible()) + return; + + LInstruction *check; if (ins->minimum() || ins->maximum()) { check = new(alloc()) LBoundsCheckRange(useRegisterOrConstant(ins->index()), useAny(ins->length()), diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h index c3bbed3f8b..1142b66e8b 100644 --- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -6887,6 +6887,9 @@ class MCheckOverRecursed static MCheckOverRecursed* New(TempAllocator& alloc) { return new(alloc) MCheckOverRecursed(); } + AliasSet getAliasSet() const override { + return AliasSet::None(); + } }; // Check whether we need to fire the interrupt handler. @@ -8000,9 +8003,10 @@ class MBoundsCheck // Range over which to perform the bounds check, may be modified by GVN. int32_t minimum_; int32_t maximum_; + bool fallible_; - MBoundsCheck(MDefinition* index, MDefinition* length) - : MBinaryInstruction(index, length), minimum_(0), maximum_(0) + MBoundsCheck(MDefinition *index, MDefinition *length) + : MBinaryInstruction(index, length), minimum_(0), maximum_(0), fallible_(true) { setGuard(); setMovable(); @@ -8049,7 +8053,11 @@ class MBoundsCheck virtual AliasSet getAliasSet() const override { return AliasSet::None(); } - void computeRange(TempAllocator& alloc) override; + void computeRange(TempAllocator &alloc) override; + bool fallible() const { + return fallible_; + } + void collectRangeInfoPreTrunc() override; ALLOW_CLONE(MBoundsCheck) }; diff --git a/js/src/jit/RangeAnalysis.cpp b/js/src/jit/RangeAnalysis.cpp index 247a272eb7..783e3eded4 100644 --- a/js/src/jit/RangeAnalysis.cpp +++ b/js/src/jit/RangeAnalysis.cpp @@ -3172,6 +3172,26 @@ MToInt32::collectRangeInfoPreTrunc() canBeNegativeZero_ = false; } +void +MBoundsCheck::collectRangeInfoPreTrunc() +{ + Range indexRange(index()); + Range lengthRange(length()); + if (!indexRange.hasInt32LowerBound() || !indexRange.hasInt32UpperBound()) + return; + if (!lengthRange.hasInt32LowerBound() || lengthRange.canBeNaN()) + return; + + int64_t indexLower = indexRange.lower(); + int64_t indexUpper = indexRange.upper(); + int64_t lengthLower = lengthRange.lower(); + int64_t min = minimum(); + int64_t max = maximum(); + + if (indexLower + min >= 0 && indexUpper + max < lengthLower) + fallible_ = false; +} + void MBoundsCheckLower::collectRangeInfoPreTrunc() { diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp index 1045c4560c..5447ca6c7f 100644 --- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -3060,6 +3060,11 @@ js::SetPrototype(JSContext *cx, HandleObject obj, HandleObject proto, JS::Object return false; } + // Convert unboxed objects to their native representations before changing + // their prototype/group, as they depend on the group for their layout. + if (obj->is() && !UnboxedPlainObject::convertToNative(cx, obj)) + return false; + Rooted taggedProto(cx, TaggedProto(proto)); if (!SetClassAndProto(cx, obj, obj->getClass(), taggedProto)) return false; diff --git a/js/src/tests/test262/built-ins/Object/getOwnPropertyDescriptors/duplicate-keys.js b/js/src/tests/test262/built-ins/Object/getOwnPropertyDescriptors/duplicate-keys.js deleted file mode 100644 index 371c6c1da7..0000000000 --- a/js/src/tests/test262/built-ins/Object/getOwnPropertyDescriptors/duplicate-keys.js +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (C) 2016 Jordan Harband. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -description: Object.getOwnPropertyDescriptors on a proxy with duplicate ownKeys should work -esid: pending -author: Jordan Harband -features: [Proxy] ----*/ - -var i = 0; -var descriptors = [ - { enumerable: false, value: "A1", writable: true, configurable: true }, - { enumerable: true, value: "A2", writable: true, configurable: true } -]; -var log = ''; -var proxy = new Proxy({}, { - ownKeys() { - log += 'ownKeys|'; - return ['DUPLICATE', 'DUPLICATE', 'DUPLICATE']; - }, - getOwnPropertyDescriptor(t, name) { - log += 'getOwnPropertyDescriptor:' + name + '|'; - return descriptors[i++]; - } -}); - -var result = Object.getOwnPropertyDescriptors(proxy); -assert.sameValue(result.hasOwnProperty('DUPLICATE'), true); - -var lastDescriptor = descriptors[descriptors.length - 1]; -assert.notSameValue(result.DUPLICATE, lastDescriptor); -assert.sameValue(result.DUPLICATE.enumerable, lastDescriptor.enumerable); -assert.sameValue(result.DUPLICATE.configurable, lastDescriptor.configurable); -assert.sameValue(result.DUPLICATE.value, lastDescriptor.value); -assert.sameValue(result.DUPLICATE.writable, lastDescriptor.writable); - -assert.sameValue(log, 'ownKeys|getOwnPropertyDescriptor:DUPLICATE|getOwnPropertyDescriptor:DUPLICATE|getOwnPropertyDescriptor:DUPLICATE|'); diff --git a/js/src/tests/test262/built-ins/Object/getOwnPropertyDescriptors/exception-not-object-coercible.js b/js/src/tests/test262/built-ins/Object/getOwnPropertyDescriptors/exception-not-object-coercible.js deleted file mode 100644 index 0bfc62bd4c..0000000000 --- a/js/src/tests/test262/built-ins/Object/getOwnPropertyDescriptors/exception-not-object-coercible.js +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (C) 2016 Jordan Harband. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -description: Object.getOwnPropertyDescriptors should fail if given a null or undefined value -esid: pending -author: Jordan Harband ----*/ - -assert.throws(TypeError, function () { - Object.getOwnPropertyDescriptors(null); -}); - -assert.throws(TypeError, function () { - Object.getOwnPropertyDescriptors(undefined); -}); diff --git a/js/src/tests/test262/built-ins/Object/getOwnPropertyDescriptors/function-length.js b/js/src/tests/test262/built-ins/Object/getOwnPropertyDescriptors/function-length.js deleted file mode 100644 index af96f51d91..0000000000 --- a/js/src/tests/test262/built-ins/Object/getOwnPropertyDescriptors/function-length.js +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (C) 2016 Jordan Harband. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -description: Object.getOwnPropertyDescriptors should have length 1 -esid: pending -author: Jordan Harband -includes: [propertyHelper.js] ----*/ - -assert.sameValue(Object.getOwnPropertyDescriptors.length, 1, 'Expected Object.getOwnPropertyDescriptors.length to be 1'); - -var desc = Object.getOwnPropertyDescriptor(Object.getOwnPropertyDescriptors, 'length'); -assertEq(desc.enumerable, false); -assertEq(desc.writable, false); -assertEq(desc.configurable, true); diff --git a/js/src/tests/test262/built-ins/Object/getOwnPropertyDescriptors/function-name.js b/js/src/tests/test262/built-ins/Object/getOwnPropertyDescriptors/function-name.js deleted file mode 100644 index 553ef7eba0..0000000000 --- a/js/src/tests/test262/built-ins/Object/getOwnPropertyDescriptors/function-name.js +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (C) 2016 Jordan Harband. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -description: Object.getOwnPropertyDescriptors should have name property with value 'getOwnPropertyDescriptors' -esid: pending -author: Jordan Harband -includes: [propertyHelper.js] ----*/ - -assert.sameValue( - Object.getOwnPropertyDescriptors.name, - 'getOwnPropertyDescriptors', - 'Expected Object.getOwnPropertyDescriptors.name to be "getOwnPropertyDescriptors"' -); - -var desc = Object.getOwnPropertyDescriptor(Object.getOwnPropertyDescriptors, 'name'); -assertEq(desc.enumerable, false); -assertEq(desc.writable, false); -assertEq(desc.configurable, true); diff --git a/js/src/tests/test262/built-ins/Object/getOwnPropertyDescriptors/function-property-descriptor.js b/js/src/tests/test262/built-ins/Object/getOwnPropertyDescriptors/function-property-descriptor.js deleted file mode 100644 index b71f054a04..0000000000 --- a/js/src/tests/test262/built-ins/Object/getOwnPropertyDescriptors/function-property-descriptor.js +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (C) 2016 Jordan Harband. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -description: Object.getOwnPropertyDescriptors should be writable, non-enumerable, and configurable -esid: pending -author: Jordan Harband -includes: [propertyHelper.js] ----*/ - -var desc = Object.getOwnPropertyDescriptor(Object, 'getOwnPropertyDescriptors'); -assertEq(desc.enumerable, false); -assertEq(desc.writable, true); -assertEq(desc.configurable, true); diff --git a/js/src/tests/test262/built-ins/Object/getOwnPropertyDescriptors/inherited-properties-omitted.js b/js/src/tests/test262/built-ins/Object/getOwnPropertyDescriptors/inherited-properties-omitted.js deleted file mode 100644 index c19d40c59a..0000000000 --- a/js/src/tests/test262/built-ins/Object/getOwnPropertyDescriptors/inherited-properties-omitted.js +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (C) 2016 Jordan Harband. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -description: Object.getOwnPropertyDescriptors does not see inherited properties. -esid: pending -author: Jordan Harband ----*/ - -var F = function () {}; -F.prototype.a = {}; -F.prototype.b = {}; - -var f = new F(); -var bValue = {}; -f.b = bValue; // shadow the prototype -Object.defineProperty(f, 'c', { - enumerable: false, - configurable: true, - writable: false, - value: {} -}); // solely an own property - -var result = Object.getOwnPropertyDescriptors(f); - -assert.sameValue(!!result.b, true, 'b has a descriptor'); -assert.sameValue(!!result.c, true, 'c has a descriptor'); - -assert.sameValue(result.b.enumerable, true, 'b is enumerable'); -assert.sameValue(result.b.configurable, true, 'b is configurable'); -assert.sameValue(result.b.writable, true, 'b is writable'); -assert.sameValue(result.b.value, bValue, 'b’s value is `bValue`'); - -assert.sameValue(result.c.enumerable, false, 'c is enumerable'); -assert.sameValue(result.c.configurable, true, 'c is configurable'); -assert.sameValue(result.c.writable, false, 'c is writable'); -assert.sameValue(result.c.value, f.c, 'c’s value is `f.c`'); - -assert.sameValue( - Object.keys(result).length, - 2, - 'result has same number of own property names as f' -); diff --git a/js/src/tests/test262/built-ins/Object/getOwnPropertyDescriptors/normal-object.js b/js/src/tests/test262/built-ins/Object/getOwnPropertyDescriptors/normal-object.js deleted file mode 100644 index 8ef7f8c5c2..0000000000 --- a/js/src/tests/test262/built-ins/Object/getOwnPropertyDescriptors/normal-object.js +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (C) 2016 Jordan Harband. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -description: Object.getOwnPropertyDescriptors should produce a normal object inheriting from Object.prototype -esid: pending -author: Jordan Harband ----*/ - -assert.sameValue( - Object.getPrototypeOf(Object.getOwnPropertyDescriptors({})), - Object.prototype -); diff --git a/js/src/tests/test262/built-ins/Object/getOwnPropertyDescriptors/observable-operations.js b/js/src/tests/test262/built-ins/Object/getOwnPropertyDescriptors/observable-operations.js deleted file mode 100644 index c1211613d3..0000000000 --- a/js/src/tests/test262/built-ins/Object/getOwnPropertyDescriptors/observable-operations.js +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (C) 2016 Jordan Harband. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -description: Object.getOwnPropertyDescriptors should perform observable operations in the correct order -esid: pending -author: Jordan Harband -features: [Proxy] -includes: [proxyTrapsHelper.js] ----*/ - -var log = ""; -var object = { a: 0, b: 0, c: 0 }; -var handler = { - getOwnPropertyDescriptor: function (target, propertyKey) { - assert.sameValue(target, object, "getOwnPropertyDescriptor"); - log += "|getOwnPropertyDescriptor:" + propertyKey; - return Object.getOwnPropertyDescriptor(target, propertyKey); - }, - ownKeys: function (target) { - assert.sameValue(target, object, "ownKeys"); - log += "|ownKeys"; - return Object.getOwnPropertyNames(target); - } -}; -var check = { - get: function (target, propertyKey, receiver) { - assertEq(propertyKey in target, true, "handler check: " + propertyKey); - return target[propertyKey]; - } -}; -var proxy = new Proxy(object, new Proxy(handler, check)); -var result = Object.getOwnPropertyDescriptors(proxy); -assert.sameValue(log, "|ownKeys|getOwnPropertyDescriptor:a|getOwnPropertyDescriptor:b|getOwnPropertyDescriptor:c", 'log'); diff --git a/js/src/tests/test262/built-ins/Object/getOwnPropertyDescriptors/primitive-booleans.js b/js/src/tests/test262/built-ins/Object/getOwnPropertyDescriptors/primitive-booleans.js deleted file mode 100644 index 899aaa0e58..0000000000 --- a/js/src/tests/test262/built-ins/Object/getOwnPropertyDescriptors/primitive-booleans.js +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (C) 2016 Jordan Harband. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -description: Object.getOwnPropertyDescriptors accepts boolean primitives. -esid: pending -author: Jordan Harband ----*/ - -var trueResult = Object.getOwnPropertyDescriptors(true); - -assert.sameValue(Object.keys(trueResult).length, 0, 'trueResult has 0 items'); - -var falseResult = Object.getOwnPropertyDescriptors(false); - -assert.sameValue(Object.keys(falseResult).length, 0, 'falseResult has 0 items'); diff --git a/js/src/tests/test262/built-ins/Object/getOwnPropertyDescriptors/primitive-numbers.js b/js/src/tests/test262/built-ins/Object/getOwnPropertyDescriptors/primitive-numbers.js deleted file mode 100644 index 495796ae4d..0000000000 --- a/js/src/tests/test262/built-ins/Object/getOwnPropertyDescriptors/primitive-numbers.js +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (C) 2016 Jordan Harband. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -description: Object.getOwnPropertyDescriptors accepts number primitives. -esid: pending -author: Jordan Harband ----*/ - -assert.sameValue(Object.keys(Object.getOwnPropertyDescriptors(0)).length, 0, '0 has zero descriptors'); -assert.sameValue(Object.keys(Object.getOwnPropertyDescriptors(-0)).length, 0, '-0 has zero descriptors'); -assert.sameValue(Object.keys(Object.getOwnPropertyDescriptors(Infinity)).length, 0, 'Infinity has zero descriptors'); -assert.sameValue(Object.keys(Object.getOwnPropertyDescriptors(-Infinity)).length, 0, '-Infinity has zero descriptors'); -assert.sameValue(Object.keys(Object.getOwnPropertyDescriptors(NaN)).length, 0, 'NaN has zero descriptors'); -assert.sameValue(Object.keys(Object.getOwnPropertyDescriptors(Math.PI)).length, 0, 'Math.PI has zero descriptors'); diff --git a/js/src/tests/test262/built-ins/Object/getOwnPropertyDescriptors/primitive-strings.js b/js/src/tests/test262/built-ins/Object/getOwnPropertyDescriptors/primitive-strings.js deleted file mode 100644 index c8d3be9ec7..0000000000 --- a/js/src/tests/test262/built-ins/Object/getOwnPropertyDescriptors/primitive-strings.js +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (C) 2016 Jordan Harband. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -description: Object.getOwnPropertyDescriptors accepts string primitives. -esid: pending -author: Jordan Harband ----*/ - -var result = Object.getOwnPropertyDescriptors('abc'); - -assert.sameValue(Object.keys(result).length, 4, 'string has 4 descriptors'); - -assert.sameValue(result.length.configurable, false, 'length is not configurable'); -assert.sameValue(result.length.enumerable, false, 'length is not enumerable'); -assert.sameValue(result.length.writable, false, 'length is not writable'); -assert.sameValue(result.length.value, 3, 'length is 3'); - -assert.sameValue(result[0].configurable, false, 'index 0 is not configurable'); -assert.sameValue(result[0].enumerable, true, 'index 0 is enumerable'); -assert.sameValue(result[0].writable, false, 'index 0 is not writable'); -assert.sameValue(result[0].value, 'a', 'index 0 is "a"'); - -assert.sameValue(result[1].configurable, false, 'index 1 is not configurable'); -assert.sameValue(result[1].enumerable, true, 'index 1 is enumerable'); -assert.sameValue(result[1].writable, false, 'index 1 is not writable'); -assert.sameValue(result[1].value, 'b', 'index 1 is "b"'); - -assert.sameValue(result[2].configurable, false, 'index 2 is not configurable'); -assert.sameValue(result[2].enumerable, true, 'index 2 is enumerable'); -assert.sameValue(result[2].writable, false, 'index 2 is not writable'); -assert.sameValue(result[2].value, 'c', 'index 2 is "c"'); - diff --git a/js/src/tests/test262/built-ins/Object/getOwnPropertyDescriptors/primitive-symbols.js b/js/src/tests/test262/built-ins/Object/getOwnPropertyDescriptors/primitive-symbols.js deleted file mode 100644 index d30fa3f464..0000000000 --- a/js/src/tests/test262/built-ins/Object/getOwnPropertyDescriptors/primitive-symbols.js +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (C) 2016 Jordan Harband. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -description: Object.getOwnPropertyDescriptors accepts Symbol primitives. -esid: pending -author: Jordan Harband -features: [Symbol] ----*/ - -var result = Object.getOwnPropertyDescriptors(Symbol()); - -assert.sameValue(Object.keys(result).length, 0, 'symbol primitive has no descriptors'); diff --git a/js/src/tests/test262/built-ins/Object/getOwnPropertyDescriptors/shell.js b/js/src/tests/test262/built-ins/Object/getOwnPropertyDescriptors/shell.js deleted file mode 100644 index 6ed766e941..0000000000 --- a/js/src/tests/test262/built-ins/Object/getOwnPropertyDescriptors/shell.js +++ /dev/null @@ -1,27 +0,0 @@ -var assert = { - sameValue: assertEq, - notSameValue(a, b, msg) { - try { - assertEq(a, b); - throw "equal" - } catch (e) { - if (e === "equal") - throw new Error("Assertion failed: expected different values, got " + a); - } - }, - throws(ctor, f) { - var fullmsg; - try { - f(); - } catch (exc) { - if (exc instanceof ctor) - return; - fullmsg = "Assertion failed: expected exception " + ctor.name + ", got " + exc; - } - if (fullmsg === undefined) - fullmsg = "Assertion failed: expected exception " + ctor.name + ", no exception thrown"; - if (msg !== undefined) - fullmsg += " - " + msg; - throw new Error(fullmsg); - } -} diff --git a/js/src/tests/test262/built-ins/Object/getOwnPropertyDescriptors/symbols-included.js b/js/src/tests/test262/built-ins/Object/getOwnPropertyDescriptors/symbols-included.js deleted file mode 100644 index 5b3241126d..0000000000 --- a/js/src/tests/test262/built-ins/Object/getOwnPropertyDescriptors/symbols-included.js +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (C) 2016 Jordan Harband. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -description: Object.getOwnPropertyDescriptors includes Symbol keys. -esid: pending -author: Jordan Harband -features: [Symbol] ----*/ - -var value = {}; -var enumSym = Symbol('enum'); -var nonEnumSym = Symbol('nonenum'); -var symValue = Symbol('value'); - -var obj = { key: symValue }; -obj[enumSym] = value; -Object.defineProperty(obj, nonEnumSym, { writable: true, enumerable: false, configurable: true, value: value }); - -var result = Object.getOwnPropertyDescriptors(obj); - -assert.sameValue(Object.keys(result).length, 1, 'obj has 1 string-keyed descriptor'); -assert.sameValue(Object.getOwnPropertySymbols(result).length, 2, 'obj has 2 symbol-keyed descriptors'); - -assert.sameValue(result.key.configurable, true, 'result.key is configurable'); -assert.sameValue(result.key.enumerable, true, 'result.key is enumerable'); -assert.sameValue(result.key.writable, true, 'result.key is writable'); -assert.sameValue(result.key.value, symValue, 'result.key has value symValue'); - -assert.sameValue(result[enumSym].configurable, true, 'result[enumSym] is configurable'); -assert.sameValue(result[enumSym].enumerable, true, 'result[enumSym] is enumerable'); -assert.sameValue(result[enumSym].writable, true, 'result[enumSym] is writable'); -assert.sameValue(result[enumSym].value, value, 'result[enumSym] has value `value`'); - -assert.sameValue(result[nonEnumSym].configurable, true, 'result[nonEnumSym] is configurable'); -assert.sameValue(result[nonEnumSym].enumerable, false, 'result[nonEnumSym] is not enumerable'); -assert.sameValue(result[nonEnumSym].writable, true, 'result[nonEnumSym] is writable'); -assert.sameValue(result[nonEnumSym].value, value, 'result[nonEnumSym] has value `value`'); diff --git a/js/src/tests/test262/built-ins/Object/getOwnPropertyDescriptors/tamper-with-global-object.js b/js/src/tests/test262/built-ins/Object/getOwnPropertyDescriptors/tamper-with-global-object.js deleted file mode 100644 index a76b5ba2a5..0000000000 --- a/js/src/tests/test262/built-ins/Object/getOwnPropertyDescriptors/tamper-with-global-object.js +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (C) 2016 Jordan Harband. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -description: > - Object.getOwnPropertyDescriptors should not have its behavior impacted by modifications to the global property Object -esid: pending -author: Jordan Harband ----*/ - -function fakeObject() { - $ERROR('The overriden version of Object was called!'); -} -fakeObject.getOwnPropertyDescriptors = Object.getOwnPropertyDescriptors; -fakeObject.keys = Object.keys; - -var global = this; -global.Object = fakeObject; - -assert.sameValue(Object, fakeObject, 'Sanity check failed: could not modify the global Object'); -assert.sameValue(Object.keys(Object.getOwnPropertyDescriptors('a')).length, 2, 'Expected string primitive to have 2 descriptors'); diff --git a/js/src/tests/test262/built-ins/Object/getOwnPropertyDescriptors/tamper-with-object-keys.js b/js/src/tests/test262/built-ins/Object/getOwnPropertyDescriptors/tamper-with-object-keys.js deleted file mode 100644 index 1f4d698936..0000000000 --- a/js/src/tests/test262/built-ins/Object/getOwnPropertyDescriptors/tamper-with-object-keys.js +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (C) 2016 Jordan Harband. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -description: > - Object.getOwnPropertyDescriptors should not have its behavior impacted by modifications to Object.getOwnPropertyDescriptor -esid: pending -author: Jordan Harband ----*/ - -function fakeObjectGetOwnPropertyDescriptor() { - $ERROR('The overriden version of Object.getOwnPropertyDescriptor was called!'); -} -Object.getOwnPropertyDescriptor = fakeObjectGetOwnPropertyDescriptor; - -assert.sameValue( - Object.getOwnPropertyDescriptor, - fakeObjectGetOwnPropertyDescriptor, - 'Sanity check failed: could not modify the global Object.getOwnPropertyDescriptor' -); - -assert.sameValue(Object.keys(Object.getOwnPropertyDescriptors({ a: 1 })).length, 1, 'Expected object with 1 key to have 1 descriptor'); diff --git a/js/src/tests/test262/built-ins/Object/shell.js b/js/src/tests/test262/built-ins/Object/shell.js deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/js/src/tests/test262/built-ins/shell.js b/js/src/tests/test262/built-ins/shell.js deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index 19c19290a7..98b7742f67 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -5991,6 +5991,30 @@ nsDisplayTransform::WriteDebugInfo(std::stringstream& aStream) AppendToString(aStream, GetTransform()); } +nsDisplayItemGeometry* +nsCharClipDisplayItem::AllocateGeometry(nsDisplayListBuilder* aBuilder) +{ + return new nsCharClipGeometry(this, aBuilder); +} + +void +nsCharClipDisplayItem::ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder, + const nsDisplayItemGeometry* aGeometry, + nsRegion* aInvalidRegion) +{ + const nsCharClipGeometry* geometry = static_cast(aGeometry); + + bool snap; + nsRect newRect = geometry->mBounds; + nsRect oldRect = GetBounds(aBuilder, &snap); + if (mLeftEdge != geometry->mLeftEdge || + mRightEdge != geometry->mRightEdge || + !oldRect.IsEqualInterior(newRect) || + !geometry->mBorderRect.IsEqualInterior(GetBorderRect())) { + aInvalidRegion->Or(oldRect, newRect); + } +} + nsDisplaySVGEffects::nsDisplaySVGEffects(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, nsDisplayList* aList) : nsDisplayWrapList(aBuilder, aFrame, aList), diff --git a/layout/base/nsDisplayList.h b/layout/base/nsDisplayList.h index cecaa7308f..3f6f7e0cd2 100644 --- a/layout/base/nsDisplayList.h +++ b/layout/base/nsDisplayList.h @@ -3703,6 +3703,12 @@ public: explicit nsCharClipDisplayItem(nsIFrame* aFrame) : nsDisplayItem(aFrame) {} + virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) override; + + virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder, + const nsDisplayItemGeometry* aGeometry, + nsRegion* aInvalidRegion) override; + struct ClipEdges { ClipEdges(const nsDisplayItem& aItem, nscoord aLeftEdge, nscoord aRightEdge) { diff --git a/layout/base/nsDisplayListInvalidation.cpp b/layout/base/nsDisplayListInvalidation.cpp index 85ed5da559..6205cb13a3 100644 --- a/layout/base/nsDisplayListInvalidation.cpp +++ b/layout/base/nsDisplayListInvalidation.cpp @@ -115,3 +115,9 @@ nsDisplaySVGEffectsGeometry::MoveBy(const nsPoint& aOffset) mBounds.MoveBy(aOffset); mFrameOffsetToReferenceFrame += aOffset; } + +nsCharClipGeometry::nsCharClipGeometry(nsCharClipDisplayItem* aItem, nsDisplayListBuilder* aBuilder) + : nsDisplayItemGenericGeometry(aItem, aBuilder) + , mLeftEdge(aItem->mLeftEdge) + , mRightEdge(aItem->mRightEdge) +{} diff --git a/layout/base/nsDisplayListInvalidation.h b/layout/base/nsDisplayListInvalidation.h index 07c94f3056..d570d4c995 100644 --- a/layout/base/nsDisplayListInvalidation.h +++ b/layout/base/nsDisplayListInvalidation.h @@ -13,6 +13,7 @@ #include "nsColor.h" #include "gfxRect.h" +class nsCharClipDisplayItem; class nsDisplayItem; class nsDisplayListBuilder; class nsDisplayBackgroundImage; @@ -248,4 +249,13 @@ public: nsPoint mFrameOffsetToReferenceFrame; }; +class nsCharClipGeometry : public nsDisplayItemGenericGeometry +{ +public: + nsCharClipGeometry(nsCharClipDisplayItem* aItem, nsDisplayListBuilder* aBuilder); + + nscoord mLeftEdge; + nscoord mRightEdge; +}; + #endif /*NSDISPLAYLISTINVALIDATION_H_*/ diff --git a/layout/generic/crashtests/1134531.html b/layout/generic/crashtests/1134531.html new file mode 100644 index 0000000000..35ddbb0606 --- /dev/null +++ b/layout/generic/crashtests/1134531.html @@ -0,0 +1,4 @@ + + +
b
+ diff --git a/layout/generic/crashtests/crashtests.list b/layout/generic/crashtests/crashtests.list index c476c8d965..ccf1d0d491 100644 --- a/layout/generic/crashtests/crashtests.list +++ b/layout/generic/crashtests/crashtests.list @@ -576,6 +576,7 @@ load 1039454-1.html load 1042489.html load 1054010-1.html load 1058954-1.html +load 1134531.html load 1134667.html load 1222783.xhtml load details-display-none-summary-1.html diff --git a/layout/generic/nsTextFrame.cpp b/layout/generic/nsTextFrame.cpp index 1bd029abaf..028988ddba 100644 --- a/layout/generic/nsTextFrame.cpp +++ b/layout/generic/nsTextFrame.cpp @@ -4567,26 +4567,11 @@ nsTextFrame::CharacterDataChanged(CharacterDataChangeInfo* aInfo) return NS_OK; } -/* virtual */ void -nsTextFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext) -{ - // A belt-and-braces check just in case we never get the - // MarkIntrinsicISizesDirty call from the style system. - if (StyleText()->mTextTransform == NS_STYLE_TEXT_TRANSFORM_CAPITALIZE && - mTextRun && - !(mTextRun->GetFlags() & nsTextFrameUtils::TEXT_IS_TRANSFORMED)) { - NS_ERROR("the current textrun doesn't match the style"); - // The current textrun is now of the wrong type. - ClearTextRuns(); - } - nsFrame::DidSetStyleContext(aOldStyleContext); -} - -class nsDisplayTextGeometry : public nsDisplayItemGenericGeometry +class nsDisplayTextGeometry : public nsCharClipGeometry { public: - nsDisplayTextGeometry(nsDisplayItem* aItem, nsDisplayListBuilder* aBuilder) - : nsDisplayItemGenericGeometry(aItem, aBuilder) + nsDisplayTextGeometry(nsCharClipDisplayItem* aItem, nsDisplayListBuilder* aBuilder) + : nsCharClipGeometry(aItem, aBuilder) { nsTextFrame* f = static_cast(aItem->Frame()); f->GetTextDecorations(f->PresContext(), nsTextFrame::eResolvedColors, mDecorations); @@ -4657,6 +4642,8 @@ public: nsRect newRect = geometry->mBounds; nsRect oldRect = GetBounds(aBuilder, &snap); if (decorations != geometry->mDecorations || + mLeftEdge != geometry->mLeftEdge || + mRightEdge != geometry->mRightEdge || !oldRect.IsEqualInterior(newRect) || !geometry->mBorderRect.IsEqualInterior(GetBorderRect())) { aInvalidRegion->Or(oldRect, newRect); diff --git a/layout/generic/nsTextFrame.h b/layout/generic/nsTextFrame.h index 1b5e55c645..2924377394 100644 --- a/layout/generic/nsTextFrame.h +++ b/layout/generic/nsTextFrame.h @@ -75,8 +75,6 @@ public: virtual nsresult CharacterDataChanged(CharacterDataChangeInfo* aInfo) override; - virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) override; - virtual nsIFrame* GetNextContinuation() const override { return mNextContinuation; } diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index 164c13703e..5cdde40e27 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -1897,6 +1897,9 @@ pref("network.dnsCacheExpirationGracePeriod", 300); // This preference can be used to turn off DNS prefetch. pref("network.dns.disablePrefetch", true); +// Contols whether or not "localhost" should resolve when offline +pref("network.dns.offline-localhost", true); + // This preference controls whether or not URLs with UTF-8 characters are // escaped. Set this preference to TRUE for strict RFC2396 conformance. pref("network.standard-url.escape-utf8", true); diff --git a/netwerk/dns/nsDNSService2.cpp b/netwerk/dns/nsDNSService2.cpp index 393bb388b3..19ad829891 100644 --- a/netwerk/dns/nsDNSService2.cpp +++ b/netwerk/dns/nsDNSService2.cpp @@ -50,6 +50,7 @@ static const char kPrefIPv4OnlyDomains[] = "network.dns.ipv4OnlyDomains"; static const char kPrefDisableIPv6[] = "network.dns.disableIPv6"; static const char kPrefDisablePrefetch[] = "network.dns.disablePrefetch"; static const char kPrefDnsLocalDomains[] = "network.dns.localDomains"; +static const char kPrefDnsOfflineLocalhost[] = "network.dns.offline-localhost"; static const char kPrefDnsNotifyResolution[] = "network.dns.notifyResolution"; //----------------------------------------------------------------------------- @@ -535,12 +536,12 @@ nsDNSService::Init() if (mResolver) return NS_OK; NS_ENSURE_TRUE(!mResolver, NS_ERROR_ALREADY_INITIALIZED); - // prefs uint32_t maxCacheEntries = 400; uint32_t defaultCacheLifetime = 120; // seconds uint32_t defaultGracePeriod = 60; // seconds bool disableIPv6 = false; + bool offlineLocalhost = true; bool disablePrefetch = false; int proxyType = nsIProtocolProxyService::PROXYCONFIG_DIRECT; bool notifyResolution = false; @@ -563,6 +564,7 @@ nsDNSService::Init() prefs->GetBoolPref(kPrefDisableIPv6, &disableIPv6); prefs->GetCharPref(kPrefIPv4OnlyDomains, getter_Copies(ipv4OnlyDomains)); prefs->GetCharPref(kPrefDnsLocalDomains, getter_Copies(localDomains)); + prefs->GetBoolPref(kPrefDnsOfflineLocalhost, &offlineLocalhost); prefs->GetBoolPref(kPrefDisablePrefetch, &disablePrefetch); // If a manual proxy is in use, disable prefetch implicitly @@ -581,6 +583,7 @@ nsDNSService::Init() prefs->AddObserver(kPrefIPv4OnlyDomains, this, false); prefs->AddObserver(kPrefDnsLocalDomains, this, false); prefs->AddObserver(kPrefDisableIPv6, this, false); + prefs->AddObserver(kPrefDnsOfflineLocalhost, this, false); prefs->AddObserver(kPrefDisablePrefetch, this, false); prefs->AddObserver(kPrefDnsNotifyResolution, this, false); @@ -621,6 +624,7 @@ nsDNSService::Init() mResolver = res; mIDN = idn; mIPv4OnlyDomains = ipv4OnlyDomains; // exchanges buffer ownership + mOfflineLocalhost = offlineLocalhost; mDisableIPv6 = disableIPv6; // Disable prefetching either by explicit preference or if a manual proxy is configured @@ -753,13 +757,15 @@ nsDNSService::AsyncResolveExtended(const nsACString &aHostname, if (!res) return NS_ERROR_OFFLINE; - if (mOffline) - flags |= RESOLVE_OFFLINE; - nsCString hostname; if (!PreprocessHostname(localDomain, aHostname, idn, hostname)) return NS_ERROR_FAILURE; + if (mOffline && + (!mOfflineLocalhost || !hostname.LowerCaseEqualsASCII("localhost"))) { + flags |= RESOLVE_OFFLINE; + } + // make sure JS callers get notification on the main thread nsCOMPtr wrappedListener = do_QueryInterface(listener); if (wrappedListener && !target) { @@ -867,13 +873,15 @@ nsDNSService::Resolve(const nsACString &aHostname, NS_ENSURE_TRUE(res, NS_ERROR_OFFLINE); - if (mOffline) - flags |= RESOLVE_OFFLINE; - nsCString hostname; if (!PreprocessHostname(localDomain, aHostname, idn, hostname)) return NS_ERROR_FAILURE; + if (mOffline && + (!mOfflineLocalhost || !hostname.LowerCaseEqualsASCII("localhost"))) { + flags |= RESOLVE_OFFLINE; + } + // // sync resolve: since the host resolver only works asynchronously, we need // to use a mutex and a condvar to wait for the result. however, since the diff --git a/netwerk/dns/nsDNSService2.h b/netwerk/dns/nsDNSService2.h index b5c4f5d8c9..39add3d4e5 100644 --- a/netwerk/dns/nsDNSService2.h +++ b/netwerk/dns/nsDNSService2.h @@ -60,6 +60,7 @@ private: bool mFirstTime; bool mOffline; bool mNotifyResolution; + bool mOfflineLocalhost; nsMainThreadPtrHandle mObserverService; nsTHashtable mLocalDomains; }; diff --git a/netwerk/test/unit/test_dns_offline.js b/netwerk/test/unit/test_dns_offline.js new file mode 100644 index 0000000000..87a9ad8b1e --- /dev/null +++ b/netwerk/test/unit/test_dns_offline.js @@ -0,0 +1,74 @@ +var dns = Cc["@mozilla.org/network/dns-service;1"].getService(Ci.nsIDNSService); +var ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService); +var prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch); +var threadManager = Cc["@mozilla.org/thread-manager;1"].getService(Ci.nsIThreadManager); +var mainThread = threadManager.currentThread; + +var listener1 = { + onLookupComplete: function(inRequest, inRecord, inStatus) { + do_check_eq(inStatus, Cr.NS_ERROR_OFFLINE); + test2(); + do_test_finished(); + } +}; + +var listener2 = { + onLookupComplete: function(inRequest, inRecord, inStatus) { + do_check_eq(inStatus, Cr.NS_OK); + var answer = inRecord.getNextAddrAsString(); + do_check_true(answer == "127.0.0.1" || answer == "::1"); + test3(); + do_test_finished(); + } +}; + +var listener3 = { + onLookupComplete: function(inRequest, inRecord, inStatus) { + do_check_eq(inStatus, Cr.NS_OK); + var answer = inRecord.getNextAddrAsString(); + do_check_true(answer == "127.0.0.1" || answer == "::1"); + cleanup(); + do_test_finished(); + } +}; + +function run_test() { + do_test_pending(); + prefs.setBoolPref("network.dns.offline-localhost", false); + ioService.offline = true; + try { + dns.asyncResolve("localhost", 0, listener1, mainThread); + } catch (e) { + do_check_eq(e.result, Cr.NS_ERROR_OFFLINE); + test2(); + do_test_finished(); + } +} + +function test2() { + do_test_pending(); + prefs.setBoolPref("network.dns.offline-localhost", true); + ioService.offline = false; + ioService.offline = true; + // we need to let the main thread run and apply the changes + do_timeout(0, test2Continued); +} + +function test2Continued() { + dns.asyncResolve("localhost", 0, listener2, mainThread); +} + +function test3() { + do_test_pending(); + ioService.offline = false; + // we need to let the main thread run and apply the changes + do_timeout(0, test3Continued); +} + +function test3Continued() { + dns.asyncResolve("localhost", 0, listener3, mainThread); +} + +function cleanup() { + prefs.clearUserPref("network.dns.offline-localhost"); +} diff --git a/netwerk/test/unit/xpcshell.ini b/netwerk/test/unit/xpcshell.ini index b1182f3ea9..8fbba9f629 100644 --- a/netwerk/test/unit/xpcshell.ini +++ b/netwerk/test/unit/xpcshell.ini @@ -177,6 +177,7 @@ skip-if = bits != 32 [test_dns_per_interface.js] [test_data_protocol.js] [test_dns_service.js] +[test_dns_offline.js] [test_dns_localredirect.js] [test_dns_proxy_bypass.js] [test_duplicate_headers.js] diff --git a/services/sync/tests/unit/test_errorhandler_sync_checkServerError.js b/services/sync/tests/unit/test_errorhandler_sync_checkServerError.js index 18cea2ccee..6a3882b5cb 100644 --- a/services/sync/tests/unit/test_errorhandler_sync_checkServerError.js +++ b/services/sync/tests/unit/test_errorhandler_sync_checkServerError.js @@ -200,6 +200,7 @@ add_identity_test(this, function test_service_offline() { let deferred = Promise.defer(); server.stop(() => { Services.io.offline = true; + Services.prefs.setBoolPref("network.dns.offline-localhost", false); try { do_check_eq(Status.sync, SYNC_SUCCEEDED); @@ -214,6 +215,7 @@ add_identity_test(this, function test_service_offline() { Service.startOver(); } Services.io.offline = false; + Services.prefs.clearUserPref("network.dns.offline-localhost"); deferred.resolve(); }); yield deferred.promise; diff --git a/widget/cocoa/nsChildView.mm b/widget/cocoa/nsChildView.mm index 9ad619dc8b..e990325d68 100644 --- a/widget/cocoa/nsChildView.mm +++ b/widget/cocoa/nsChildView.mm @@ -239,27 +239,6 @@ static uint32_t gNumberOfWidgetsNeedingEventThread = 0; #pragma mark - -/* Convenience routine to go from a Goanna rect to Cocoa NSRect. - * - * Goanna rects (nsRect) contain an origin (x,y) in a coordinate - * system with (0,0) in the top-left of the screen. Cocoa rects - * (NSRect) contain an origin (x,y) in a coordinate system with - * (0,0) in the bottom-left of the screen. Both nsRect and NSRect - * contain width/height info, with no difference in their use. - * If a Cocoa rect is from a flipped view, there is no need to - * convert coordinate systems. - */ -#ifndef __LP64__ -static inline void -ConvertGoannaRectToMacRect(const nsIntRect& aRect, Rect& outMacRect) -{ - outMacRect.left = aRect.x; - outMacRect.top = aRect.y; - outMacRect.right = aRect.x + aRect.width; - outMacRect.bottom = aRect.y + aRect.height; -} -#endif - // Flips a screen coordinate from a point in the cocoa coordinate system (bottom-left rect) to a point // that is a "flipped" cocoa coordinate system (starts in the top-left). static inline void diff --git a/xpcom/build/PoisonIOInterposerMac.cpp b/xpcom/build/PoisonIOInterposerMac.cpp index df4149ca39..9ca59eacd5 100644 --- a/xpcom/build/PoisonIOInterposerMac.cpp +++ b/xpcom/build/PoisonIOInterposerMac.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #ifdef MOZ_REPLACE_MALLOC #include "replace_malloc_bridge.h"