From 605fde2bb102ecd0922e9c1458608cf5cae2a4c2 Mon Sep 17 00:00:00 2001 From: roytam1 Date: Mon, 4 Dec 2023 22:00:13 +0800 Subject: [PATCH] import changes from `dev' branch of rmottola/Arctic-Fox: - Bug 1236120: [ffmpeg] Use demuxed dimensions to determine picture size and offset. r=gerald (f336c84d0d) - Bug 851530: Part 1 - Added support for decoding uLaw and aLaw enconded wave files. r=jya (72683b69f2) - Bug 851530: Part 2 - Added test cases for uLaw and aLaw wave files. r=jya (ddf431bd28) - Bug 524109 - Added support for 24 bit wav files. r=cpearce (ebfac16a20) - Bug 864780 - Changed handling of the format chunk to skip any extension. r=cpearce (40903839a8) - Bug 1229742: P1. Only clear EOS flag if we have new data. r=gerald (83e69375e4) - Bug 1229742: P2. Don't reject data promise if new data is pending. r=gerald (89d8222809) - Bug 1237809: P2. Detect change of display size. r=cpearce (ec529e2732) - Bug 1237809: [h264] P1. Ensure correct video dimensions are passed to the decoder. r=cpearce (eb241cad10) - Bug 1237809: P3. Ensure element dimensions are up to date. r=jwwang (541e6e74d7) - Bug 1244639: P1. Don't assume MP3 decoding always starts at 0. r=cpearce (b62c27bd04) - Bug 1244639: P2. Don't clamp audio time to seek time if there's no video track. r=cpearce (4720bacc24) - Bug 1205927 - Part 1: [MediaEncoder] Support *.3g2 with EVRC audio format. r=ayang (bbd8aff9d9) - Bug 1205927 - Part 2: Add audio-capture:3gpp2 perimission for certificated and privileged application. r=ayang (63b337e2ab) - Bug 1198157 - Call |NotifyEndOfStream| if the encoder can't been initialized after 30 seconds. r=jwwang (2c21203d36) - minor NL (14d757753b) - Bug 1182426 - Add some asserts to VP8TrackEncoder for sanity. r=roc (79ff4869ca) - Bug 1154213 - Handle timestamps of video/webm vorbis track encoding. r=mreavy, r=rjesup (a9897e4873) - Bug 1137151: Marked destructor of |MuxerOperation| as protected, r=sotaro (94fdcf6457) - Bug 1210232 - Let MP4Decoder handle 3GPP files on B2G. r=cpearce (95a77023ad) - Bug 1227790 - Update GMP API to include new MediaKeyStatus types. r=jwwang (1a6933f2df) - bits of Bug 1186375 - Add GMP EME (6b99660146) - Bug 1221825: Fix logging arguments. r=cpearce (5261e34713) - Bug 1244442 - Warn about Proxy.create and Proxy.createFunction. r=Waldo (718aa94f5b) - fix spaces (720e2114f7) - re-apply Bug 1231224 part 7 - Fix some more places to handle OOM. r=jonco (a4af46894b) - Bug 1246122 - Don't crash in InvokeInterruptCallback if there are no JS scripts on the stack. r=shu (9702df89bc) - Bug 1246607: Recover from OOM in AddClearDefiniteGetterSetterForPrototypeChain; r=jandem (d83c6c6c9b) - Bug 1236546 - Don't deoptimize in ObjectGroup::defaultNewGroup when we have a null proto. r=bhackett (1c2ecc3d09) - Bug 1249588 - Remove unnecessary type information from RegExpObject. r=jandem (9126e17d94) - Bug 1245965 - Fix an OOM in ObjectGroup::newPlainObject; r=till (5192c25b53) - Bug 1240527: Fix tracing of RegExpStaticsObject; r=nbp (b37f2167a5) - Bug 1248094 - Followup to fix a typo; r=fitzgen (8afec429d9) - Bug 1248726 - Simplify PCLocationMap even further; r=fitzgen (39f0b54a04) - Bug 1241311 - Pre-tenure SavedFrame objects. r=terrence (b703f3d78e) - Bug 1241249 - Add an SPS pseudo entry for JS stack capturing; r=shu (c2ae4ee5c2) - Bug 1247299 - Force SavedFrame columns to be 0 in JS_MORE_DETERMINISTIC builds; r=sfink (09b9038448) - Bug 1241701 - Add about:memory reporting for js::SavedStacks::pcLocationMap. r=njn (b663d911fc) - Bug 1166234 - Throw on accessing optimized out values when using Debugger.Frame.prototype.eval. (r=jimb) (19b43b137b) - Bug 1232655 - Fix DebugScopeProxy::has to not lookup .this on non-function scopes. r=shu (3959e98752) - Bug 1216261 - Fix OOM handling of DebugScopes. (r=jonco) (0f8b856ee6) - reorder after mispatch (c292050275) - Bug 1235656 - Followup: Allow extended functions with guessed atoms in self-hosted code. (rs=arai) (a67286cd52) - Bug 1245048: Check call to GetPrototype; r=till (35dbbdc025) - Bug 1132630 - Renumber steps in Function.prototype.bind. r=till (9f11a5a086) - Bug 1246131 - Provide 'dbg(msg)' debug printing utility function for self-hosted code. r=jandem (f436eeb481) - Bug 1246131 - Part 2: Let opt builds compile again, even on a CLOSED TREE. r=bustage (8483b77541) - Bug 1247934 - Handle receiving unboxed exports array from self hosted module code r=shu (fb9c296909) - Bug 1246134 - Fix loading of external self-hosted JS using MOZ_SELFHOSTEDJS. r=efaust (c96059b40a) - Bug 1220502 - ignore not visible text nodes for tree update, r=tbsaunde, roc (eed078abc6) - Bug 1242989 - keep content insertions in a hash, r=tbsaunde (d58fc948a6) - bug 1228400 - null check tabChild before notifying the parent process about new child documents r=davidb (09512e6287) - Bug 1239051 - Labels should expose labeled controllers action. r=tbsaunde (c0d4d801a9) - bug 1243077 - make xpcAccessible::GetFirstChild() work with proxies r=davidb (f539fafe93) - bug 1243077 - make xpcAccessible::GetLastChild() work with proxied accessibles r=davidb (13716f7cc0) - bug 1243077 - implement xpcAccessible::GetChildCount() for proxied accessibles (b8f4598834) - bug 1243077 - make xpcAccessible::GetChildAt() work with proxied accessibles r=davidb (cce0924f7b) - bug 1243077 - make xpcAccessible::GetChildren() work with proxied accessibles r=davidb (a9ec2b1588) - bug 1243077 - remove an unnecessary AddRef() from xpcAccessible::GetChildren() (89a58ac2e0) - bug 1243077 - support proxied accessibles in xpcAccessible::GetRole() r=davidb (2d2a2926c7) - Bug 1246768 - part 1: argument conversion for Atomics.isLockFree in runtime. r=bbouvier (17f3498b84) - Bug 1246750 - fix argument ordering to futexWakeOrRequeue + test cases. r=bbouvier (31825e7096) - Bug 1238911 - initialize canWait with false from constructor, avoid using the variable without initialization. r=lhansen (f4657b3950) - Bug 1235373 - Add an assert to check validity of pointers: mElement->GetPrimaryFrame() and frame. r=surkov (18023f9238) - Bug 1241534 - Use TraceRoot for InterpreterFrame fields. r=terrence (98996dc497) - Bug 1246112 - Fix a bogus assert in InterpreterFrame::initExecuteFrame. r=su (2093ba8a44) - Bug 1243241 - Make RDTSC monotonic. r=jandem (1450a97a94) - Bug 1243242 - Don't make structured cloning O(n**2) in the size of the transferables array. r=sfink (aa38dee282) --- accessible/base/NotificationController.cpp | 106 ++++++---------- accessible/base/NotificationController.h | 53 ++------ accessible/base/StyleInfo.cpp | 2 + accessible/base/nsCoreUtils.cpp | 11 ++ accessible/base/nsCoreUtils.h | 5 + accessible/generic/BaseAccessibles.cpp | 25 ++-- accessible/generic/BaseAccessibles.h | 3 +- accessible/html/HTMLElementAccessibles.cpp | 26 ++++ accessible/html/HTMLElementAccessibles.h | 5 + .../tests/mochitest/actions/test_general.html | 16 +++ .../tests/mochitest/actions/test_general.xul | 11 ++ accessible/xpcom/xpcAccessible.cpp | 32 ++--- dom/apps/PermissionsTable.jsm | 5 + dom/media/DecoderTraits.cpp | 4 +- dom/media/MP3Demuxer.h | 5 - dom/media/MediaDecoder.cpp | 7 +- dom/media/MediaDecoderStateMachine.cpp | 8 +- dom/media/MediaFormatReader.cpp | 28 +++-- dom/media/MediaRecorder.cpp | 12 +- dom/media/MediaRecorder.h | 2 +- dom/media/encoder/EncodedFrameContainer.h | 2 + dom/media/encoder/MediaEncoder.cpp | 8 ++ dom/media/encoder/OmxTrackEncoder.cpp | 45 ++++++- dom/media/encoder/OmxTrackEncoder.h | 16 +++ dom/media/encoder/OpusTrackEncoder.cpp | 1 + dom/media/encoder/TrackEncoder.cpp | 32 ++++- dom/media/encoder/TrackEncoder.h | 4 +- dom/media/encoder/TrackMetadataBase.h | 1 + dom/media/encoder/VP8TrackEncoder.cpp | 6 +- dom/media/encoder/VorbisTrackEncoder.cpp | 2 + dom/media/encoder/fmp4_muxer/EVRCBox.cpp | 84 +++++++++++++ dom/media/encoder/fmp4_muxer/EVRCBox.h | 50 ++++++++ dom/media/encoder/fmp4_muxer/ISOControl.cpp | 8 +- .../encoder/fmp4_muxer/ISOMediaBoxes.cpp | 14 +++ .../encoder/fmp4_muxer/ISOMediaWriter.cpp | 7 +- dom/media/encoder/fmp4_muxer/ISOMediaWriter.h | 4 + .../encoder/fmp4_muxer/ISOTrackMetadata.h | 27 ++++ dom/media/encoder/fmp4_muxer/MuxerOperation.h | 1 + dom/media/encoder/fmp4_muxer/moz.build | 1 + dom/media/fmp4/MP4Decoder.cpp | 21 ++-- dom/media/gmp/GMPDecryptorParent.cpp | 2 +- dom/media/gmp/gmp-api/gmp-decryption.h | 12 +- dom/media/omx/OMXCodecWrapper.cpp | 32 +++++ dom/media/omx/OMXCodecWrapper.h | 5 + dom/media/platforms/agnostic/WAVDecoder.cpp | 65 ++++++++-- .../android/AndroidDecoderModule.cpp | 2 + .../platforms/ffmpeg/FFmpegH264Decoder.cpp | 20 ++- .../platforms/ffmpeg/FFmpegH264Decoder.h | 6 +- .../platforms/wrappers/H264Converter.cpp | 5 + dom/media/platforms/wrappers/H264Converter.h | 2 +- dom/media/test/16bit_wave_extrametadata.wav | Bin 0 -> 97814 bytes .../16bit_wave_extrametadata.wav^headers^ | 1 + dom/media/test/can_play_type_wave.js | 2 + dom/media/test/manifest.js | 8 ++ dom/media/test/mochitest.ini | 8 ++ dom/media/test/wavedata_alaw.wav | Bin 0 -> 11067 bytes dom/media/test/wavedata_alaw.wav^headers^ | 1 + dom/media/test/wavedata_s24.wav | Bin 0 -> 33071 bytes dom/media/test/wavedata_s24.wav^headers^ | 1 + dom/media/test/wavedata_ulaw.wav | Bin 0 -> 11067 bytes dom/media/test/wavedata_ulaw.wav^headers^ | 1 + dom/media/wave/WaveDecoder.cpp | 5 +- dom/media/wave/WaveReader.cpp | 70 +++++++---- dom/media/wave/WaveReader.h | 3 +- dom/media/webm/EbmlComposer.cpp | 23 ++-- js/src/builtin/AtomicsObject.cpp | 23 ++-- js/src/builtin/Function.js | 22 ++-- js/src/builtin/ModuleObject.cpp | 27 ++-- js/src/builtin/ModuleObject.h | 6 +- js/src/builtin/Utilities.js | 8 +- js/src/jit-test/tests/atomics/basic-tests.js | 33 +++++ js/src/jit-test/tests/debug/bug1216261.js | 15 +++ js/src/jit-test/tests/debug/bug1232655.js | 5 + .../jit-test/tests/debug/optimized-out-03.js | 31 +++++ js/src/jit-test/tests/gc/bug-1240527.js | 14 +++ js/src/jit-test/tests/gc/bug1246607.js | 16 +++ js/src/jit-test/tests/modules/bug-1247934.js | 11 ++ js/src/js.msg | 3 +- js/src/proxy/ScriptedIndirectProxyHandler.cpp | 10 ++ .../extensions/clone-many-transferables.js | 25 ++++ js/src/tests/shell/futex-apis.js | 118 ++++++++++++++++++ js/src/vm/GlobalObject.h | 18 ++- js/src/vm/HelperThreads.cpp | 6 +- js/src/vm/ObjectGroup.cpp | 14 +-- js/src/vm/RegExpStatics.cpp | 5 +- js/src/vm/Runtime.cpp | 2 +- js/src/vm/SavedStacks.cpp | 29 +++-- js/src/vm/SavedStacks.h | 14 ++- js/src/vm/ScopeObject.cpp | 55 +++++--- js/src/vm/SelfHosting.cpp | 107 ++++++++++------ js/src/vm/Stack.cpp | 51 ++++---- js/src/vm/Stack.h | 5 +- js/src/vm/Stopwatch.cpp | 35 ++++-- js/src/vm/Stopwatch.h | 16 ++- js/src/vm/StructuredClone.cpp | 51 +++++--- js/src/vm/TypeInference.cpp | 9 +- js/src/vm/Xdr.h | 4 +- layout/generic/nsTextFrame.cpp | 4 +- netwerk/mime/nsMimeTypes.h | 1 + tools/profiler/tests/test_saved_stacks.js | 69 ++++++++++ tools/profiler/tests/xpcshell.ini | 1 + .../exthandler/nsExternalHelperAppService.cpp | 1 + 102 files changed, 1395 insertions(+), 443 deletions(-) create mode 100644 dom/media/encoder/fmp4_muxer/EVRCBox.cpp create mode 100644 dom/media/encoder/fmp4_muxer/EVRCBox.h create mode 100644 dom/media/test/16bit_wave_extrametadata.wav create mode 100644 dom/media/test/16bit_wave_extrametadata.wav^headers^ create mode 100644 dom/media/test/wavedata_alaw.wav create mode 100644 dom/media/test/wavedata_alaw.wav^headers^ create mode 100644 dom/media/test/wavedata_s24.wav create mode 100644 dom/media/test/wavedata_s24.wav^headers^ create mode 100644 dom/media/test/wavedata_ulaw.wav create mode 100644 dom/media/test/wavedata_ulaw.wav^headers^ create mode 100644 js/src/jit-test/tests/debug/bug1216261.js create mode 100644 js/src/jit-test/tests/debug/bug1232655.js create mode 100644 js/src/jit-test/tests/debug/optimized-out-03.js create mode 100644 js/src/jit-test/tests/gc/bug-1240527.js create mode 100644 js/src/jit-test/tests/gc/bug1246607.js create mode 100644 js/src/jit-test/tests/modules/bug-1247934.js create mode 100644 js/src/tests/js1_8_5/extensions/clone-many-transferables.js create mode 100644 js/src/tests/shell/futex-apis.js create mode 100644 tools/profiler/tests/test_saved_stacks.js diff --git a/accessible/base/NotificationController.cpp b/accessible/base/NotificationController.cpp index 77f161048c..ef024cb333 100644 --- a/accessible/base/NotificationController.cpp +++ b/accessible/base/NotificationController.cpp @@ -52,7 +52,16 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(NotificationController) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mHangingChildDocuments) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mContentInsertions) + for (auto it = tmp->mContentInsertions.ConstIter(); !it.Done(); it.Next()) { + NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mContentInsertions key"); + cb.NoteXPCOMChild(it.Key()); + nsTArray>* list = it.UserData(); + for (uint32_t i = 0; i < list->Length(); i++) { + NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, + "mContentInsertions value item"); + cb.NoteXPCOMChild(list->ElementAt(i)); + } + } NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEvents) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRelocations) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END @@ -103,10 +112,23 @@ NotificationController::ScheduleContentInsertion(Accessible* aContainer, nsIContent* aStartChildNode, nsIContent* aEndChildNode) { - RefPtr insertion = new ContentInsertion(mDocument, - aContainer); - if (insertion && insertion->InitChildList(aStartChildNode, aEndChildNode) && - mContentInsertions.AppendElement(insertion)) { + nsTArray>* list = + mContentInsertions.LookupOrAdd(aContainer); + + bool needsProcessing = false; + nsIContent* node = aStartChildNode; + while (node != aEndChildNode) { + // Notification triggers for content insertion even if no content was + // actually inserted, check if the given content has a frame to discard + // this case early. + if (node->GetPrimaryFrame()) { + if (list->AppendElement(node)) + needsProcessing = true; + } + node = node->GetNextSibling(); + } + + if (needsProcessing) { ScheduleProcessing(); } } @@ -130,7 +152,7 @@ NotificationController::IsUpdatePending() { return mPresShell->IsLayoutFlushObserver() || mObservingState == eRefreshProcessingForUpdate || - mContentInsertions.Length() != 0 || mNotifications.Length() != 0 || + mContentInsertions.Count() != 0 || mNotifications.Length() != 0 || mTextHash.Count() != 0 || !mDocument->HasLoadState(DocAccessible::eTreeConstructed); } @@ -178,7 +200,7 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime) mDocument->DoInitialUpdate(); - NS_ASSERTION(mContentInsertions.Length() == 0, + NS_ASSERTION(mContentInsertions.Count() == 0, "Pending content insertions while initial accessible tree isn't created!"); } @@ -196,15 +218,13 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime) // document accessible. // Process only currently queued content inserted notifications. - nsTArray > contentInsertions; - contentInsertions.SwapElements(mContentInsertions); - - uint32_t insertionCount = contentInsertions.Length(); - for (uint32_t idx = 0; idx < insertionCount; idx++) { - contentInsertions[idx]->Process(); - if (!mDocument) + for (auto iter = mContentInsertions.ConstIter(); !iter.Done(); iter.Next()) { + mDocument->ProcessContentInserted(iter.Key(), iter.UserData()); + if (!mDocument) { return; + } } + mContentInsertions.Clear(); // Process rendered text change notifications. for (auto iter = mTextHash.Iter(); !iter.Done(); iter.Next()) { @@ -390,8 +410,10 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime) childDoc->SetIPCDoc(ipcDoc); nsCOMPtr tabChild = do_GetInterface(mDocument->DocumentNode()->GetDocShell()); - static_cast(tabChild.get())-> - SendPDocAccessibleConstructor(ipcDoc, parentIPCDoc, id); + if (tabChild) { + static_cast(tabChild.get())-> + SendPDocAccessibleConstructor(ipcDoc, parentIPCDoc, id); + } } } @@ -401,7 +423,7 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime) // Stop further processing if there are no new notifications of any kind or // events and document load is processed. - if (mContentInsertions.IsEmpty() && mNotifications.IsEmpty() && + if (mContentInsertions.Count() == 0 && mNotifications.IsEmpty() && mEvents.IsEmpty() && mTextHash.Count() == 0 && mHangingChildDocuments.IsEmpty() && mDocument->HasLoadState(DocAccessible::eCompletelyLoaded) && @@ -409,53 +431,3 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime) mObservingState = eNotObservingRefresh; } } - -//////////////////////////////////////////////////////////////////////////////// -// NotificationController: content inserted notification - -NotificationController::ContentInsertion:: - ContentInsertion(DocAccessible* aDocument, Accessible* aContainer) : - mDocument(aDocument), mContainer(aContainer) -{ -} - -bool -NotificationController::ContentInsertion:: - InitChildList(nsIContent* aStartChildNode, nsIContent* aEndChildNode) -{ - bool haveToUpdate = false; - - nsIContent* node = aStartChildNode; - while (node != aEndChildNode) { - // Notification triggers for content insertion even if no content was - // actually inserted, check if the given content has a frame to discard - // this case early. - if (node->GetPrimaryFrame()) { - if (mInsertedContent.AppendElement(node)) - haveToUpdate = true; - } - - node = node->GetNextSibling(); - } - - return haveToUpdate; -} - -NS_IMPL_CYCLE_COLLECTION(NotificationController::ContentInsertion, - mContainer) - -NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(NotificationController::ContentInsertion, - AddRef) -NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(NotificationController::ContentInsertion, - Release) - -void -NotificationController::ContentInsertion::Process() -{ - mDocument->ProcessContentInserted(mContainer, &mInsertedContent); - - mDocument = nullptr; - mContainer = nullptr; - mInsertedContent.Clear(); -} - diff --git a/accessible/base/NotificationController.h b/accessible/base/NotificationController.h index 9ae6f7e6aa..666ddcc4a3 100644 --- a/accessible/base/NotificationController.h +++ b/accessible/base/NotificationController.h @@ -122,8 +122,15 @@ public: */ inline void ScheduleTextUpdate(nsIContent* aTextNode) { - if (mTextHash.PutEntry(aTextNode)) - ScheduleProcessing(); + // Make sure we are not called with a node that is not in the DOM tree or + // not visible. + MOZ_ASSERT(aTextNode->GetParentNode(), "A text node is not in DOM"); + MOZ_ASSERT(aTextNode->GetPrimaryFrame(), "A text node doesn't have a frame"); + MOZ_ASSERT(aTextNode->GetPrimaryFrame()->StyleVisibility()->IsVisible(), + "A text node is not visible"); + + mTextHash.PutEntry(aTextNode); + ScheduleProcessing(); } /** @@ -240,44 +247,10 @@ private: nsTArray > mHangingChildDocuments; /** - * Storage for content inserted notification information. + * Pending accessible tree update notifications for content insertions. */ - class ContentInsertion - { - public: - ContentInsertion(DocAccessible* aDocument, Accessible* aContainer); - - NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(ContentInsertion) - NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(ContentInsertion) - - bool InitChildList(nsIContent* aStartChildNode, nsIContent* aEndChildNode); - void Process(); - - protected: - virtual ~ContentInsertion() { mDocument = nullptr; } - - private: - ContentInsertion(); - ContentInsertion(const ContentInsertion&); - ContentInsertion& operator = (const ContentInsertion&); - - // The document used to process content insertion, matched to document of - // the notification controller that this notification belongs to, therefore - // it's ok to keep it as weak ref. - DocAccessible* mDocument; - - // The container accessible that content insertion occurs within. - RefPtr mContainer; - - // Array of inserted contents. - nsTArray > mInsertedContent; - }; - - /** - * A pending accessible tree update notifications for content insertions. - * Don't make this an AutoTArray; we use SwapElements() on it. - */ - nsTArray > mContentInsertions; + nsClassHashtable, + nsTArray>> mContentInsertions; template class nsCOMPtrHashKey : public PLDHashEntryHdr @@ -304,7 +277,7 @@ private: }; /** - * A pending accessible tree update notifications for rendered text changes. + * Pending accessible tree update notifications for rendered text changes. */ nsTHashtable > mTextHash; diff --git a/accessible/base/StyleInfo.cpp b/accessible/base/StyleInfo.cpp index c4e2203ffa..51291ed09b 100644 --- a/accessible/base/StyleInfo.cpp +++ b/accessible/base/StyleInfo.cpp @@ -58,6 +58,7 @@ StyleInfo::TextIndent(nsAString& aValue) case eStyleUnit_Percent: { nsIFrame* frame = mElement->GetPrimaryFrame(); + MOZ_ASSERT(frame, "frame must be a valid pointer."); nsIFrame* containerFrame = frame->GetContainingBlock(); nscoord percentageBase = containerFrame->GetContentRect().width; coordVal = NSCoordSaturatingMultiply(percentageBase, @@ -88,6 +89,7 @@ StyleInfo::TextIndent(nsAString& aValue) void StyleInfo::Margin(css::Side aSide, nsAString& aValue) { + MOZ_ASSERT(mElement->GetPrimaryFrame(), " mElement->GetPrimaryFrame() needs to be valid pointer"); aValue.Truncate(); nscoord coordVal = mElement->GetPrimaryFrame()->GetUsedMargin().Side(aSide); diff --git a/accessible/base/nsCoreUtils.cpp b/accessible/base/nsCoreUtils.cpp index 8b12a5196f..6262caecd6 100644 --- a/accessible/base/nsCoreUtils.cpp +++ b/accessible/base/nsCoreUtils.cpp @@ -36,6 +36,7 @@ #include "nsITreeBoxObject.h" #include "nsITreeColumns.h" #include "mozilla/dom/Element.h" +#include "mozilla/dom/HTMLLabelElement.h" using namespace mozilla; @@ -43,6 +44,16 @@ using namespace mozilla; // nsCoreUtils //////////////////////////////////////////////////////////////////////////////// +bool +nsCoreUtils::IsLabelWithControl(nsIContent* aContent) +{ + dom::HTMLLabelElement* label = dom::HTMLLabelElement::FromContent(aContent); + if (label && label->GetControl()) + return true; + + return false; +} + bool nsCoreUtils::HasClickListener(nsIContent *aContent) { diff --git a/accessible/base/nsCoreUtils.h b/accessible/base/nsCoreUtils.h index 78fa99e282..c8660dc46c 100644 --- a/accessible/base/nsCoreUtils.h +++ b/accessible/base/nsCoreUtils.h @@ -29,6 +29,11 @@ class nsIWidget; class nsCoreUtils { public: + /** + * Return true if the given node is a label of a control. + */ + static bool IsLabelWithControl(nsIContent *aContent); + /** * Return true if the given node has registered click, mousedown or mouseup * event listeners. diff --git a/accessible/generic/BaseAccessibles.cpp b/accessible/generic/BaseAccessibles.cpp index 6e79fa8156..04c31d39bb 100644 --- a/accessible/generic/BaseAccessibles.cpp +++ b/accessible/generic/BaseAccessibles.cpp @@ -115,13 +115,14 @@ LinkableAccessible::Value(nsString& aValue) uint8_t LinkableAccessible::ActionCount() { - bool isLink, isOnclick; - ActionWalk(&isLink, &isOnclick); - return (isLink || isOnclick) ? 1 : 0; + bool isLink, isOnclick, isLabelWithControl; + ActionWalk(&isLink, &isOnclick, &isLabelWithControl); + return (isLink || isOnclick || isLabelWithControl) ? 1 : 0; } Accessible* -LinkableAccessible::ActionWalk(bool* aIsLink, bool* aIsOnclick) +LinkableAccessible::ActionWalk(bool* aIsLink, bool* aIsOnclick, + bool* aIsLabelWithControl) { if (aIsOnclick) { *aIsOnclick = false; @@ -129,6 +130,9 @@ LinkableAccessible::ActionWalk(bool* aIsLink, bool* aIsOnclick) if (aIsLink) { *aIsLink = false; } + if (aIsLabelWithControl) { + *aIsLabelWithControl = false; + } if (nsCoreUtils::HasClickListener(mContent)) { if (aIsOnclick) { @@ -155,6 +159,13 @@ LinkableAccessible::ActionWalk(bool* aIsLink, bool* aIsOnclick) } return walkUpAcc; } + + if (nsCoreUtils::IsLabelWithControl(walkUpAcc->GetContent())) { + if (aIsLabelWithControl) { + *aIsLabelWithControl = true; + } + return walkUpAcc; + } } return nullptr; } @@ -166,11 +177,11 @@ LinkableAccessible::ActionNameAt(uint8_t aIndex, nsAString& aName) // Action 0 (default action): Jump to link if (aIndex == eAction_Jump) { - bool isOnclick, isLink; - ActionWalk(&isLink, &isOnclick); + bool isOnclick, isLink, isLabelWithControl; + ActionWalk(&isLink, &isOnclick, &isLabelWithControl); if (isLink) { aName.AssignLiteral("jump"); - } else if (isOnclick) { + } else if (isOnclick || isLabelWithControl) { aName.AssignLiteral("click"); } } diff --git a/accessible/generic/BaseAccessibles.h b/accessible/generic/BaseAccessibles.h index 5e3c20e346..71e932949b 100644 --- a/accessible/generic/BaseAccessibles.h +++ b/accessible/generic/BaseAccessibles.h @@ -76,7 +76,8 @@ public: // ActionAccessible helpers Accessible* ActionWalk(bool* aIsLink = nullptr, - bool* aIsOnclick = nullptr); + bool* aIsOnclick = nullptr, + bool* aIsLabelWithControl = nullptr); // HyperLinkAccessible virtual already_AddRefed AnchorURIAt(uint32_t aAnchorIndex) override; diff --git a/accessible/html/HTMLElementAccessibles.cpp b/accessible/html/HTMLElementAccessibles.cpp index 02f31017d1..fa2cc4d350 100644 --- a/accessible/html/HTMLElementAccessibles.cpp +++ b/accessible/html/HTMLElementAccessibles.cpp @@ -75,6 +75,32 @@ HTMLLabelAccessible::RelationByType(RelationType aType) return rel; } +uint8_t +HTMLLabelAccessible::ActionCount() +{ + return nsCoreUtils::IsLabelWithControl(mContent) ? 1 : 0; +} + +void +HTMLLabelAccessible::ActionNameAt(uint8_t aIndex, nsAString& aName) +{ + if (aIndex == 0) { + if (nsCoreUtils::IsLabelWithControl(mContent)) + aName.AssignLiteral("click"); + } +} + +bool +HTMLLabelAccessible::DoAction(uint8_t aIndex) +{ + if (aIndex != 0) + return false; + + DoCommand(); + return true; +} + + //////////////////////////////////////////////////////////////////////////////// // nsHTMLOuputAccessible //////////////////////////////////////////////////////////////////////////////// diff --git a/accessible/html/HTMLElementAccessibles.h b/accessible/html/HTMLElementAccessibles.h index 8dfffd6f72..a1a4a8a9c4 100644 --- a/accessible/html/HTMLElementAccessibles.h +++ b/accessible/html/HTMLElementAccessibles.h @@ -62,6 +62,11 @@ public: // Accessible virtual Relation RelationByType(RelationType aType) override; + // ActionAccessible + virtual uint8_t ActionCount() override; + virtual void ActionNameAt(uint8_t aIndex, nsAString& aName) override; + virtual bool DoAction(uint8_t aIndex) override; + protected: virtual ~HTMLLabelAccessible() {} virtual ENameValueFlag NativeName(nsString& aName) override; diff --git a/accessible/tests/mochitest/actions/test_general.html b/accessible/tests/mochitest/actions/test_general.html index 1d312df302..5b9a18dab5 100644 --- a/accessible/tests/mochitest/actions/test_general.html +++ b/accessible/tests/mochitest/actions/test_general.html @@ -39,11 +39,19 @@ ID: "onclick_img", actionName: "click", events: CLICK_EVENTS + }, + { + ID: "label1", + actionName: "click", + events: CLICK_EVENTS } + ]; testActions(actionsArray); + is(getAccessible("label1").firstChild.actionCount, 1, "label text should have 1 action"); + getAccessible("onclick_img").takeFocus(); is(getAccessible("link1").actionCount, 1, "links should have one action"); is(getAccessible("link2").actionCount, 1, "link with onclick handler should have 1 action"); @@ -87,5 +95,13 @@ linkable textleaf accessible
linkable textleaf accessible
+ +
+ + +
+ diff --git a/accessible/tests/mochitest/actions/test_general.xul b/accessible/tests/mochitest/actions/test_general.xul index fac49f1bbb..bb27767a38 100644 --- a/accessible/tests/mochitest/actions/test_general.xul +++ b/accessible/tests/mochitest/actions/test_general.xul @@ -60,6 +60,11 @@ actionName: "press", events: CLICK_EVENTS }, + { + ID: "name_entry_label", + actionName: "click", + events: CLICK_EVENTS + }, { ID: "labelWithPopup", actionName: "click", @@ -72,6 +77,8 @@ }*/ ]; + is(getAccessible("name_entry_label").firstChild.actionCount, 1, "label text should have 1 action"); + testActions(actionsArray); } @@ -125,6 +132,10 @@