From 8d1a041130cb8cf2019a89226543342cb582ca6b Mon Sep 17 00:00:00 2001 From: roytam1 Date: Mon, 21 Aug 2023 10:59:29 +0800 Subject: [PATCH] import changes from `dev' branch of rmottola/Arctic-Fox: - Bug 1209252: add buttons to clear session and signaling logs. r=jib, r=sicking (39d0a4b57d) - Bug 1197673 - Use float type for SetAudioOutputVolume. r=eitan (75eae2f441) - Bug 1188099 - (Part 4) Introduce mochitest coverage for speech global queue. r=smaug r=kdavis (fd4c804c72) - Bug 1226015 - Have child send __delete__ in speech synth request protocol, fixes race. r=smaug (c46532745a) - Bug 1230533 - Cancel speech when controlling window goes away. r=smaug (3dae89ffaf) - Bug 1237176 - skip dom/media/webspeech/synth/test/test_bfcache.html on Linux and Android for frequent timeouts (0d1eabb6fb) - Bug 1237176 - actually disable test_bfcache.html on Android (1558e0bf39) - Bug 1240871 - Don't allow implicit "async" in IPDL (r=mccr8,billm) (1db25ace3c) - Bug 1000040 - Part 2: Implement EthernetManager; r=vicamo (82c01ca9a7) - Bug 1000040 - Part 3: Test cases; r=vicamo (6a967cc5d9) - Bug 1245241 - part 2 - remove TYPE_SYSV Shmems from IPDL. r=billm (6d6a4570ca) - Bug 1245241 - part 3 - remove unused AdoptShmem from IPDL. r=billm (2762a13841) - Bug 1107792: Don't ask for similar if the surface has an error, and more data in crash reports. r=milan (ead5108a93) - Bug 1231881 - Remove NativeSurfaceType::CAIRO_SURFACE. r=bas. (c0f03e02f6) - Bug 1241163 - Replace DrawTarget::CreateSourceSurfaceFromNativeSurface(CAIRO_CONTEXT) with Factory::CreateSourceSurfaceForCairoSurface. r=jrmuizel (06a96cdce6) - Bug 1240177 - part 1 - add helper function to make Skia image info, r=jrmuizel (6a7d05aeb7) - Bug 1240177 - part 2 - cleanups of DrawTargetSkia and SourceSurfaceSkia creation for GPU contexts, r=jrmuizel (3211ea9c0e) - Bug 1240177 - part 3 - make DrawTargetSkia::OptimizeSourceSurface directly upload to GPU textures, r=jrmuizel (743d57a46c) - Bug 1240177 - part 4 - avoid GPU readbacks in SourceSurfaceSkia::DrawTargetWillChange, r=jrmuizel (f568754717) - Bug 1240177 - fix SourceSurfaceSkia::DrawTargetWillChange deepCopyTo usage. r=mattwoodrow (2e53d13ba3) - Bug 1239152 Memset RGBX surfaces to opaque white. r=nical (977c7d5ede) - Bug 1245241 - part 4 - move SharedMemorySysV details into nsShmImage. r=nical (0015d3caac) - Bug 1245241 - Force the main thread to sync with the compositor when it tries to allocate insane amounts of shmems. r=lsalzman (7683d2afa7) - Bug 1245241 - fix SharedMemoryBasic_android CloseHandle to null out handle. r=billm a=kwierso (9fa3f93233) - Bug 1239152 - skip memset since XShm is already initialized to zero. r=mchang (477ecf2d9a) - Bug 1227927 Part 1 - Make nsIFrame::PrincipalChildList a const function. r=bz (d9b690a1bc) - Bug 1214377 - Hack to solve Thunderbird's need to detect style pre-wrap. r=roc a=me (a481ba9020) - Bug 1214377 - Hack to solve Thunderbird's need to detect style pre-wrap. rs=ehsan on a CLOSED TREE (a15dfcaeb3) - Bug 1240372 - Don't OOM crash in nsDocumentEncoder::EncodeToStringWithMaxLength() when the string buffer allocation fails; r=bzbarsky (76bed6a40a) - Bug 1143570 - Part 1: Use an nsBlockInFlowLineIterator to determine whether a BR frame is visible or not; r=roc (99609f6fcd) - Bug 1064843 part 2 - Make nsSubDocumentFrame inherit nsContainerFrame. r=dholbert (070202e396) - Bug 1064843 part 3 - Make nsFormControlFrame inherit nsContainerFrame. r=dholbert (cee5125993) - Bug 1064843 part 4 - Add a placeholder type for top layer. r=roc (e4e564b05b) - Bug 1064843 part 5 - Ensure frames behave properly for unknown child list id passed into SetInitialChildList. r=dholbert (540f3da6a1) - Bug 1064843 part 6 - Add backdrop frame list. r=dholbert (79f91fc815) - Bug 1215365 - Update ua style sheet of fullscreen element. r=heycam (b44060a518) - Bug 1235969 - Unprefix uses of -moz-transform, -moz-transform-origin and -moz-backface-visibility in UA style sheets. r=xidorn (c7a83cdcae) - Bug 1064843 part 7 - Add backdrop pseudo-element and add related UA stylesheet. r=heycam (1d89afa54a) - Bug 1064843 part 8 - Add frame class for backdrop frame. r=dbaron (9146be0073) - Bug 1064843 part 9 - Change nsCSSFrameConstructor::CreatePlaceholderFrameFor to accept parent style context. r=dbaron (bc860e67f8) - Bug 1064843 part 10 - Create and render backdrop frame for top layer frames. r=dbaron (1c6f165769) - Bug 1064843 part 11 - Move checkWindowPureColor helper function from top-layer test to WindowSnapshot.js. r=roc (ef274dec50) - Bug 1064843 part 12 - Add test for ::backdrop of fullscreen. r=dholbert (b978209868) - Bug 1227927 Part 2 - Remove nsIFrame::GetFirstPrincipalChild(). r=mats (3f4ba2ef58) - Bug 1227927 Part 3 - Use ranged-based for-loop to rewrite some simple loops in part 2. r=mats (6b22236653) - Bug 1227927 Part 4 - Add comment to nsFrameList::GetLength() to warn it's O(n). r=mats (a08aa9185e) - Bug 1101817 - Part 1: Remove usages of WeakMap.prototype.clear from Gecko. r=yzen,mak,yoric,gijs,jlongster (a992931bfe) - Bug 1101817 - Part 3: Remove WeakMap.prototype.clear usages from Addons SDK. r=mossop (e81a8c3477) - Bug 1101817 - Part 4: Remove WeakMap.prototype.clear from web-platform test. r=Ms2ger (1be3f645a2) - Bug 1101817 - Part 6: Remove Weak{Map,Set}.prototype.clear. r=evilpie (7a0dbffdc9) - Bug 1235152 - [css-break] Don't apply border/padding twice on inlines with box-decoration-break:clone and direction:rtl. r=roc (e6446262c1) --- accessible/generic/HyperTextAccessible.cpp | 2 +- accessible/ipc/PDocAccessible.ipdl | 34 +- accessible/jsat/EventManager.jsm | 4 +- b2g/installer/package-manifest.in | 2 + browser/base/content/browser-fullZoom.js | 1 - docshell/base/nsAboutRedirector.cpp | 2 +- dom/asmjscache/PAsmJSCacheEntry.ipdl | 10 +- dom/base/nsContentUtils.cpp | 4 +- dom/base/nsDocument.cpp | 7 + dom/base/nsDocumentEncoder.cpp | 129 +++- dom/base/nsGkAtomList.h | 1 + dom/base/nsGlobalWindow.cpp | 17 +- dom/base/nsGlobalWindow.h | 1 + dom/base/nsRange.cpp | 2 +- dom/base/test/test_bug116083.html | 16 + dom/bluetooth/ipc/PBluetooth.ipdl | 18 +- dom/bluetooth/ipc/PBluetoothRequest.ipdl | 2 +- dom/broadcastchannel/PBroadcastChannel.ipdl | 8 +- dom/cache/PCache.ipdl | 8 +- dom/cache/PCacheOp.ipdl | 2 +- dom/cache/PCachePushStream.ipdl | 6 +- dom/cache/PCacheStorage.ipdl | 6 +- dom/cache/PCacheStreamControl.ipdl | 8 +- dom/cellbroadcast/ipc/PCellBroadcast.ipdl | 30 +- dom/devicestorage/PDeviceStorageRequest.ipdl | 2 +- dom/filehandle/PBackgroundFileHandle.ipdl | 12 +- dom/filehandle/PBackgroundFileRequest.ipdl | 6 +- dom/filehandle/PBackgroundMutableFile.ipdl | 6 +- dom/filesystem/PFileSystemRequest.ipdl | 2 +- dom/fmradio/ipc/PFMRadio.ipdl | 24 +- dom/fmradio/ipc/PFMRadioRequest.ipdl | 2 +- dom/html/HTMLInputElement.cpp | 4 +- dom/html/nsGenericHTMLElement.cpp | 2 +- dom/html/nsTextEditorState.cpp | 2 +- dom/html/test/file_fullscreen-backdrop.html | 89 +++ dom/html/test/file_fullscreen-top-layer.html | 21 +- dom/html/test/mochitest.ini | 1 + dom/html/test/test_fullscreen-api.html | 1 + dom/icc/ipc/PIcc.ipdl | 20 +- dom/icc/ipc/PIccRequest.ipdl | 2 +- ...est_WeakMap.prototype-properties.html.json | 1 - .../test_WeakMap.prototype-properties.html | 28 +- dom/indexedDB/PBackgroundIDBCursor.ipdl | 8 +- dom/indexedDB/PBackgroundIDBDatabase.ipdl | 28 +- dom/indexedDB/PBackgroundIDBDatabaseFile.ipdl | 2 +- .../PBackgroundIDBDatabaseRequest.ipdl | 2 +- dom/indexedDB/PBackgroundIDBFactory.ipdl | 12 +- .../PBackgroundIDBFactoryRequest.ipdl | 8 +- dom/indexedDB/PBackgroundIDBRequest.ipdl | 2 +- dom/indexedDB/PBackgroundIDBTransaction.ipdl | 14 +- ...BackgroundIDBVersionChangeTransaction.ipdl | 26 +- .../PIndexedDBPermissionRequest.ipdl | 2 +- dom/ipc/ContentParent.h | 10 +- dom/ipc/PBlob.ipdl | 8 +- dom/ipc/PBlobStream.ipdl | 2 +- dom/ipc/PBrowser.ipdl | 271 ++++---- dom/ipc/PColorPicker.ipdl | 6 +- dom/ipc/PContent.ipdl | 210 +++--- dom/ipc/PContentBridge.ipdl | 4 +- dom/ipc/PContentDialog.ipdl | 2 +- dom/ipc/PContentPermissionRequest.ipdl | 12 +- dom/ipc/PCrashReporter.ipdl | 6 +- dom/ipc/PCycleCollectWithLogs.ipdl | 6 +- dom/ipc/PDocumentRenderer.ipdl | 2 +- dom/ipc/PFilePicker.ipdl | 8 +- dom/ipc/PMemoryReportRequest.ipdl | 4 +- dom/ipc/PScreenManager.ipdl | 2 +- dom/media/gmp/PGMPAudioDecoder.ipdl | 22 +- dom/media/gmp/PGMPDecryptor.ipdl | 86 +-- dom/media/gmp/PGMPStorage.ipdl | 22 +- dom/media/gmp/PGMPTimer.ipdl | 6 +- dom/media/systemservices/PMedia.ipdl | 10 +- dom/media/webrtc/PWebrtcGlobal.ipdl | 16 +- dom/media/webspeech/synth/SpeechSynthesis.cpp | 54 +- dom/media/webspeech/synth/SpeechSynthesis.h | 19 +- .../webspeech/synth/ipc/PSpeechSynthesis.ipdl | 14 +- .../synth/ipc/PSpeechSynthesisRequest.ipdl | 24 +- .../synth/ipc/SpeechSynthesisChild.cpp | 11 +- .../synth/ipc/SpeechSynthesisChild.h | 8 +- .../synth/ipc/SpeechSynthesisParent.cpp | 30 +- .../synth/ipc/SpeechSynthesisParent.h | 4 +- dom/media/webspeech/synth/nsSpeechTask.cpp | 4 +- dom/media/webspeech/synth/nsSpeechTask.h | 2 +- dom/media/webspeech/synth/test/common.js | 31 +- .../synth/test/file_bfcache_frame.html | 28 + .../synth/test/file_global_queue.html | 69 ++ .../synth/test/file_global_queue_cancel.html | 88 +++ .../synth/test/file_global_queue_pause.html | 131 ++++ .../test/file_indirect_service_events.html | 113 +-- .../synth/test/file_speech_cancel.html | 115 +-- .../synth/test/file_speech_error.html | 46 ++ .../synth/test/file_speech_queue.html | 53 +- dom/media/webspeech/synth/test/mochitest.ini | 11 + .../synth/test/nsFakeSynthServices.cpp | 9 +- .../webspeech/synth/test/test_bfcache.html | 47 ++ .../synth/test/test_global_queue.html | 34 + .../synth/test/test_global_queue_cancel.html | 34 + .../synth/test/test_global_queue_pause.html | 34 + .../test/test_indirect_service_events.html | 7 +- .../synth/test/test_speech_cancel.html | 6 +- .../synth/test/test_speech_error.html | 35 + .../synth/test/test_speech_queue.html | 6 +- dom/messagechannel/PMessagePort.ipdl | 16 +- .../ipc/PMobileConnection.ipdl | 28 +- .../ipc/PMobileConnectionRequest.ipdl | 2 +- .../ipc/PMobileMessageCursor.ipdl | 6 +- dom/mobilemessage/ipc/PSms.ipdl | 32 +- dom/mobilemessage/ipc/PSmsRequest.ipdl | 2 +- dom/network/EthernetManager.js | 655 ++++++++++++++++++ dom/network/EthernetManager.manifest | 2 + dom/network/PTCPServerSocket.ipdl | 8 +- dom/network/PTCPSocket.ipdl | 26 +- dom/network/PUDPSocket.ipdl | 26 +- dom/network/interfaces/moz.build | 1 + dom/network/interfaces/nsIEthernetManager.idl | 137 ++++ dom/network/moz.build | 2 + dom/network/tests/marionette/head.js | 552 +++++++++++++++ dom/network/tests/marionette/manifest.ini | 15 + .../marionette/test_ethernet_add_interface.js | 16 + .../test_ethernet_connect_with_dhcp.js | 26 + .../test_ethernet_connect_with_static_ip.js | 33 + .../tests/marionette/test_ethernet_disable.js | 17 + .../marionette/test_ethernet_disconnect.js | 25 + .../tests/marionette/test_ethernet_enable.js | 17 + .../test_ethernet_ip_mode_change.js | 43 ++ .../test_ethernet_reconnect_with_dhcp.js | 29 + .../test_ethernet_reconnect_with_static_ip.js | 36 + .../test_ethernet_remove_interface.js | 16 + .../ipc/PPluginBackgroundDestroyer.ipdl | 2 +- dom/presentation/ipc/PPresentation.ipdl | 26 +- .../ipc/PPresentationRequest.ipdl | 2 +- dom/system/gonk/NetworkManager.js | 79 ++- dom/system/gonk/NetworkManager.manifest | 4 +- dom/system/gonk/nsINetworkInterface.idl | 5 +- dom/system/gonk/nsINetworkManager.idl | 11 +- dom/telephony/ipc/PTelephony.ipdl | 26 +- dom/telephony/ipc/PTelephonyRequest.ipdl | 6 +- dom/voicemail/ipc/PVoicemail.ipdl | 18 +- dom/webidl/WebrtcGlobalInformation.webidl | 6 +- dom/workers/PServiceWorkerManager.ipdl | 28 +- .../printingui/ipc/PPrintProgressDialog.ipdl | 20 +- .../printingui/ipc/PPrintSettingsDialog.ipdl | 2 +- .../components/printingui/ipc/PPrinting.ipdl | 6 +- .../glue/PRemoteSpellcheckEngine.ipdl | 2 +- gfx/2d/2D.h | 2 + gfx/2d/DrawTargetCairo.cpp | 22 +- gfx/2d/DrawTargetSkia.cpp | 199 +++--- gfx/2d/DrawTargetSkia.h | 6 - gfx/2d/Factory.cpp | 16 + gfx/2d/HelpersSkia.h | 21 + gfx/2d/Scale.cpp | 17 +- gfx/2d/SourceSurfaceSkia.cpp | 64 +- gfx/2d/SourceSurfaceSkia.h | 9 +- gfx/2d/Types.h | 1 - gfx/layers/BufferTexture.cpp | 4 +- gfx/layers/basic/X11TextureSourceBasic.cpp | 9 +- gfx/layers/client/ContentClient.cpp | 7 +- gfx/layers/client/TextureClient.cpp | 7 + gfx/layers/client/TextureClient.h | 11 +- gfx/layers/ipc/LayerTransactionParent.h | 2 + gfx/layers/ipc/PLayerTransaction.ipdl | 2 + gfx/layers/ipc/ShadowLayers.cpp | 22 + gfx/thebes/gfxContext.cpp | 21 +- gfx/thebes/gfxPlatform.cpp | 23 +- gfx/thebes/gfxWindowsPlatform.cpp | 27 +- gfx/thebes/gfxXlibNativeRenderer.cpp | 22 +- hal/sandbox/PHal.ipdl | 78 +-- ipc/glue/PBackground.ipdl | 40 +- ipc/glue/PBackgroundTest.ipdl | 2 +- ipc/glue/PFileDescriptorSet.ipdl | 4 +- ipc/glue/ProtocolUtils.h | 1 - ipc/glue/SharedMemory.h | 1 - ipc/glue/SharedMemoryBasic_android.cpp | 3 +- ipc/glue/SharedMemorySysV.h | 162 ----- ipc/glue/Shmem.cpp | 24 - ipc/glue/Shmem.h | 12 +- ipc/glue/moz.build | 1 - ipc/ipdl/ipdl/lower.py | 109 +-- ipc/ipdl/ipdl/parser.py | 8 +- ipc/ipdl/test/cxx/PTestActorPunning.ipdl | 10 +- .../test/cxx/PTestActorPunningPunned.ipdl | 2 +- ipc/ipdl/test/cxx/PTestActorPunningSub.ipdl | 4 +- ipc/ipdl/test/cxx/PTestBadActor.ipdl | 4 +- ipc/ipdl/test/cxx/PTestBadActorSub.ipdl | 2 +- ipc/ipdl/test/cxx/PTestBridgeMain.ipdl | 4 +- ipc/ipdl/test/cxx/PTestBridgeMainSub.ipdl | 6 +- ipc/ipdl/test/cxx/PTestBridgeSub.ipdl | 6 +- ipc/ipdl/test/cxx/PTestCrashCleanup.ipdl | 2 +- ipc/ipdl/test/cxx/PTestDataStructures.ipdl | 6 +- ipc/ipdl/test/cxx/PTestDesc.ipdl | 6 +- ipc/ipdl/test/cxx/PTestDescSub.ipdl | 2 +- .../test/cxx/PTestEndpointBridgeMain.ipdl | 4 +- .../test/cxx/PTestEndpointBridgeMainSub.ipdl | 4 +- ipc/ipdl/test/cxx/PTestEndpointBridgeSub.ipdl | 6 +- ipc/ipdl/test/cxx/PTestEndpointOpens.ipdl | 6 +- .../test/cxx/PTestEndpointOpensOpened.ipdl | 6 +- ipc/ipdl/test/cxx/PTestFailedCtor.ipdl | 2 +- ipc/ipdl/test/cxx/PTestFailedCtorSub.ipdl | 2 +- ipc/ipdl/test/cxx/PTestFailedCtorSubsub.ipdl | 2 +- ipc/ipdl/test/cxx/PTestHandle.ipdl | 2 +- ipc/ipdl/test/cxx/PTestHangs.ipdl | 2 +- .../cxx/PTestIndirectProtocolParamFirst.ipdl | 2 +- .../cxx/PTestIndirectProtocolParamManage.ipdl | 6 +- .../cxx/PTestIndirectProtocolParamSecond.ipdl | 2 +- ipc/ipdl/test/cxx/PTestInterruptRaces.ipdl | 8 +- ipc/ipdl/test/cxx/PTestLatency.ipdl | 14 +- ipc/ipdl/test/cxx/PTestManyChildAllocs.ipdl | 6 +- .../test/cxx/PTestManyChildAllocsSub.ipdl | 4 +- ipc/ipdl/test/cxx/PTestMultiMgrs.ipdl | 10 +- ipc/ipdl/test/cxx/PTestMultiMgrsBottom.ipdl | 2 +- ipc/ipdl/test/cxx/PTestMultiMgrsLeft.ipdl | 4 +- ipc/ipdl/test/cxx/PTestMultiMgrsRight.ipdl | 4 +- ipc/ipdl/test/cxx/PTestNestedLoops.ipdl | 2 +- ipc/ipdl/test/cxx/PTestOpens.ipdl | 4 +- ipc/ipdl/test/cxx/PTestOpensOpened.ipdl | 6 +- ipc/ipdl/test/cxx/PTestRacyReentry.ipdl | 2 +- ipc/ipdl/test/cxx/PTestSanity.ipdl | 6 +- ipc/ipdl/test/cxx/PTestSelfManage.ipdl | 4 +- ipc/ipdl/test/cxx/PTestSelfManageRoot.ipdl | 4 +- ipc/ipdl/test/cxx/PTestShmem.ipdl | 6 +- ipc/ipdl/test/cxx/PTestShutdown.ipdl | 6 +- ipc/ipdl/test/cxx/PTestShutdownSub.ipdl | 2 +- ipc/ipdl/test/cxx/PTestStackHooks.ipdl | 2 +- ipc/ipdl/test/cxx/PTestSyncError.ipdl | 4 +- ipc/ipdl/test/cxx/PTestSyncHang.ipdl | 2 +- ipc/ipdl/test/cxx/PTestSysVShmem.ipdl | 22 - ipc/ipdl/test/cxx/TestSysVShmem.cpp | 120 ---- ipc/ipdl/test/cxx/TestSysVShmem.h | 66 -- ipc/ipdl/test/cxx/moz.build | 6 - ipc/ipdl/test/ipdl/error/DeleteRace.ipdl | 4 +- ipc/ipdl/test/ipdl/error/Nullable.ipdl | 2 +- ipc/ipdl/test/ipdl/error/Nullable2.ipdl | 2 +- .../test/ipdl/error/actorparam_badState.ipdl | 4 +- .../test/ipdl/error/bridgesSubprotocol.ipdl | 2 +- .../test/ipdl/error/cyclecheck_Child.ipdl | 2 +- .../ipdl/error/cyclecheck_Grandchild.ipdl | 2 +- .../test/ipdl/error/cyclecheck_Parent.ipdl | 2 +- .../test/ipdl/error/manageSelfToplevel.ipdl | 2 +- .../test/ipdl/error/messageNoDirection.ipdl | 2 +- ipc/ipdl/test/ipdl/error/multimanDupMgrs.ipdl | 2 +- .../test/ipdl/error/multimanDupMgrsMgr.ipdl | 2 +- .../ipdl/error/multimanNonexistentMgrs.ipdl | 4 +- ipc/ipdl/test/ipdl/error/mutualRecStruct.ipdl | 4 +- .../test/ipdl/error/mutualRecStructUnion.ipdl | 4 +- .../test/ipdl/error/opensSubprotocol.ipdl | 2 +- .../ipdl/error/race_OverlappingMultiOut.ipdl | 10 +- .../ipdl/error/race_ViolateSameDirection.ipdl | 11 +- ipc/ipdl/test/ipdl/error/redeclMessage.ipdl | 4 +- ipc/ipdl/test/ipdl/error/redefState.ipdl | 4 +- .../test/ipdl/error/shmem_access_union.ipdl | 2 +- .../test/ipdl/error/spawnsSubprotocol.ipdl | 2 +- .../test/ipdl/error/trans_WrongDirection.ipdl | 4 +- .../ipdl/error/trans_WrongDirection2.ipdl | 4 +- .../ipdl/error/trans_WrongDirection3.ipdl | 2 +- .../ipdl/error/trans_WrongDirection4.ipdl | 2 +- .../ipdl/error/trans_WrongDirection5.ipdl | 2 +- ipc/ipdl/test/ipdl/error/trans_WrongName.ipdl | 4 +- .../test/ipdl/error/trans_WrongName2.ipdl | 4 +- .../test/ipdl/error/trans_WrongName3.ipdl | 2 +- .../test/ipdl/error/trans_WrongName4.ipdl | 2 +- .../test/ipdl/error/trans_WrongName5.ipdl | 2 +- .../ipdl/error/unreachedDeleteMultiStart.ipdl | 2 +- ipc/ipdl/test/ipdl/ok/Delete.ipdl | 2 +- ipc/ipdl/test/ipdl/ok/Nullable.ipdl | 6 +- ipc/ipdl/test/ipdl/ok/Struct.ipdl | 2 +- ipc/ipdl/test/ipdl/ok/actorparam_state.ipdl | 4 +- ipc/ipdl/test/ipdl/ok/array_Basic.ipdl | 2 +- ipc/ipdl/test/ipdl/ok/array_OfActors.ipdl | 2 +- ipc/ipdl/test/ipdl/ok/compositor.ipdl | 2 +- ipc/ipdl/test/ipdl/ok/content.ipdl | 2 +- ipc/ipdl/test/ipdl/ok/headerProto.ipdl | 2 +- ipc/ipdl/test/ipdl/ok/intrProtocol.ipdl | 2 +- ipc/ipdl/test/ipdl/ok/jetpack.ipdl | 2 +- ipc/ipdl/test/ipdl/ok/jetpackContent.ipdl | 2 +- ipc/ipdl/test/ipdl/ok/manageSelf.ipdl | 2 +- .../test/ipdl/ok/manageSelf_Toplevel.ipdl | 2 +- ipc/ipdl/test/ipdl/ok/managedProtocol.ipdl | 2 +- ipc/ipdl/test/ipdl/ok/media.ipdl | 2 +- ipc/ipdl/test/ipdl/ok/multiManaged.ipdl | 2 +- .../test/ipdl/ok/multipleUsingCxxTypes.ipdl | 2 +- .../test/ipdl/ok/mutualRecStructUnion.ipdl | 4 +- ipc/ipdl/test/ipdl/ok/mutualRecUnion.ipdl | 4 +- ipc/ipdl/test/ipdl/ok/namespace_Basic.ipdl | 2 +- .../test/ipdl/ok/noRedeclCrossMessage.ipdl | 4 +- ipc/ipdl/test/ipdl/ok/plugin.ipdl | 2 +- ipc/ipdl/test/ipdl/ok/race_DiamondRule1.ipdl | 8 +- ipc/ipdl/test/ipdl/ok/race_KitchenSink.ipdl | 8 +- ipc/ipdl/test/ipdl/ok/race_MultiOut.ipdl | 8 +- ipc/ipdl/test/ipdl/ok/race_Stateless.ipdl | 8 +- ipc/ipdl/test/ipdl/ok/selfRecUnion.ipdl | 4 +- ipc/ipdl/test/ipdl/ok/shmem.ipdl | 2 +- ipc/ipdl/test/ipdl/ok/syncProtocol.ipdl | 2 +- ipc/ipdl/test/ipdl/ok/threeDirections.ipdl | 6 +- ipc/ipdl/test/ipdl/ok/union_Namespaced.ipdl | 2 +- ipc/testshell/PTestShell.ipdl | 6 +- ipc/testshell/PTestShellCommand.ipdl | 2 +- js/src/builtin/WeakMapObject.cpp | 22 - js/src/builtin/WeakSet.js | 23 +- js/src/builtin/WeakSetObject.cpp | 1 - .../tests/collections/WeakMap-clear.js | 42 -- .../tests/collections/WeakMap-surfaces.js | 1 - .../tests/collections/WeakSet-clear.js | 50 -- .../tests/collections/WeakSet-delete.js | 7 - .../tests/collections/WeakSet-surface.js | 1 - js/src/jsweakmap.h | 3 - js/src/vm/SelfHosting.cpp | 1 - layout/base/RestyleManager.cpp | 15 +- layout/base/nsBidiPresUtils.cpp | 31 +- layout/base/nsCSSFrameConstructor.cpp | 115 ++- layout/base/nsCSSFrameConstructor.h | 7 +- layout/base/nsCSSRendering.cpp | 2 +- layout/base/nsCaret.cpp | 2 +- layout/base/nsDocumentViewer.cpp | 4 +- layout/base/nsFrameTraversal.cpp | 2 +- layout/base/nsLayoutUtils.cpp | 14 +- layout/base/nsPresShell.cpp | 10 +- layout/forms/nsFieldSetFrame.cpp | 5 +- layout/forms/nsFormControlFrame.cpp | 58 +- layout/forms/nsFormControlFrame.h | 41 +- layout/forms/nsHTMLButtonControlFrame.h | 2 +- layout/forms/nsListControlFrame.cpp | 15 +- layout/forms/nsTextControlFrame.cpp | 9 +- layout/forms/nsTextControlFrame.h | 2 +- layout/generic/FrameChildList.cpp | 1 + layout/generic/RubyUtils.cpp | 6 +- layout/generic/TextOverflow.cpp | 4 +- layout/generic/moz.build | 1 + layout/generic/nsBackdropFrame.cpp | 92 +++ layout/generic/nsBackdropFrame.h | 46 ++ layout/generic/nsBlockFrame.cpp | 22 +- layout/generic/nsBlockReflowContext.cpp | 2 +- layout/generic/nsCanvasFrame.cpp | 3 +- layout/generic/nsColumnSetFrame.cpp | 5 +- layout/generic/nsColumnSetFrame.h | 2 +- layout/generic/nsContainerFrame.cpp | 53 +- layout/generic/nsContainerFrame.h | 1 + layout/generic/nsFirstLetterFrame.cpp | 2 + layout/generic/nsFlexContainerFrame.cpp | 4 +- layout/generic/nsFrame.cpp | 31 +- layout/generic/nsFrameIdList.h | 1 + layout/generic/nsFrameList.h | 8 +- layout/generic/nsFrameStateBits.h | 1 + layout/generic/nsGfxScrollFrame.cpp | 13 +- layout/generic/nsGridContainerFrame.cpp | 2 +- layout/generic/nsHTMLCanvasFrame.h | 2 +- layout/generic/nsHTMLReflowState.cpp | 2 +- layout/generic/nsIFrame.h | 7 +- layout/generic/nsInlineFrame.cpp | 2 +- layout/generic/nsLeafFrame.cpp | 23 +- layout/generic/nsLeafFrame.h | 11 - layout/generic/nsPageFrame.cpp | 2 +- layout/generic/nsPlaceholderFrame.h | 6 +- layout/generic/nsPluginFrame.cpp | 5 +- layout/generic/nsRubyBaseContainerFrame.cpp | 6 +- layout/generic/nsRubyTextContainerFrame.cpp | 4 +- layout/generic/nsSimplePageSequenceFrame.cpp | 6 +- layout/generic/nsSubDocumentFrame.cpp | 40 +- layout/generic/nsSubDocumentFrame.h | 13 +- layout/generic/nsTextFrame.cpp | 2 +- layout/generic/nsViewportFrame.cpp | 16 +- layout/generic/nsViewportFrame.h | 2 - .../tests/test_getCSSPseudoElementNames.html | 1 + layout/mathml/nsMathMLContainerFrame.cpp | 29 +- layout/mathml/nsMathMLTokenFrame.cpp | 15 +- layout/mathml/nsMathMLmencloseFrame.cpp | 2 +- layout/mathml/nsMathMLmfencedFrame.cpp | 7 +- layout/mathml/nsMathMLmmultiscriptsFrame.cpp | 4 +- layout/mathml/nsMathMLmpaddedFrame.cpp | 2 +- layout/mathml/nsMathMLmrowFrame.cpp | 2 +- layout/mathml/nsMathMLmtableFrame.cpp | 12 +- layout/printing/nsPrintEngine.cpp | 16 +- .../box-decoration-break-bug-1235152-ref.html | 57 ++ .../box-decoration-break-bug-1235152.html | 61 ++ layout/reftests/css-break/reftest.list | 1 + layout/style/html.css | 2 +- layout/style/nsCSSPseudoElementList.h | 2 + layout/style/nsComputedDOMStyle.cpp | 4 +- layout/style/ua.css | 22 +- layout/svg/SVGTextFrame.cpp | 34 +- layout/svg/SVGTextFrame.h | 2 +- layout/svg/nsSVGClipPathFrame.cpp | 3 +- layout/svg/nsSVGContainerFrame.cpp | 3 +- layout/svg/nsSVGForeignObjectFrame.cpp | 12 +- layout/svg/nsSVGForeignObjectFrame.h | 2 +- layout/svg/nsSVGMarkerFrame.cpp | 2 +- layout/svg/nsSVGMarkerFrame.h | 6 +- layout/svg/nsSVGOuterSVGFrame.cpp | 27 +- layout/svg/nsSVGOuterSVGFrame.h | 8 +- layout/svg/nsSVGUtils.cpp | 5 +- layout/tables/nsCellMap.cpp | 12 +- layout/tables/nsTableCellFrame.cpp | 6 +- layout/tables/nsTableCellFrame.h | 2 +- layout/tables/nsTableColGroupFrame.cpp | 2 +- layout/tables/nsTableFrame.cpp | 32 +- layout/tables/nsTableOuterFrame.cpp | 18 +- layout/tables/nsTableOuterFrame.h | 2 +- layout/tables/nsTableRowFrame.cpp | 6 +- layout/tables/nsTableRowGroupFrame.cpp | 4 +- layout/xul/BoxObject.cpp | 4 +- layout/xul/nsBox.cpp | 2 +- layout/xul/nsBoxFrame.cpp | 14 +- layout/xul/nsMenuBarFrame.cpp | 2 +- layout/xul/nsMenuFrame.cpp | 6 +- layout/xul/nsMenuPopupFrame.cpp | 7 +- layout/xul/nsProgressMeterFrame.cpp | 2 +- layout/xul/nsRootBoxFrame.cpp | 2 +- layout/xul/nsScrollbarButtonFrame.cpp | 7 +- layout/xul/nsSliderFrame.cpp | 4 +- layout/xul/nsXULPopupManager.cpp | 8 +- layout/xul/tree/nsTreeBodyFrame.cpp | 2 +- layout/xul/tree/nsTreeColumns.cpp | 2 +- media/mtransport/rlogringbuffer.cpp | 5 + media/mtransport/rlogringbuffer.h | 2 +- .../src/peerconnection/WebrtcGlobalChild.h | 2 + .../WebrtcGlobalInformation.cpp | 109 ++- .../peerconnection/WebrtcGlobalInformation.h | 4 + netwerk/cookie/PCookieService.ipdl | 2 +- netwerk/dns/PDNSRequest.ipdl | 8 +- netwerk/ipc/PChannelDiverter.ipdl | 2 +- netwerk/ipc/PDataChannel.ipdl | 2 +- netwerk/ipc/PNecko.ipdl | 78 +-- netwerk/ipc/PRemoteOpenFile.ipdl | 2 +- netwerk/ipc/PRtspChannel.ipdl | 2 +- netwerk/ipc/PRtspController.ipdl | 38 +- netwerk/protocol/ftp/PFTPChannel.ipdl | 48 +- netwerk/protocol/http/PHttpChannel.ipdl | 118 ++-- netwerk/protocol/websocket/PWebSocket.ipdl | 48 +- .../websocket/PWebSocketEventListener.ipdl | 40 +- netwerk/protocol/wyciwyg/PWyciwygChannel.ipdl | 52 +- .../manager/ssl/PPSMContentDownloader.ipdl | 10 +- .../client/marionette/tests/webapi-tests.ini | 1 + .../tests/SimpleTest/WindowSnapshot.js | 11 + .../WeakMap.prototype-properties.html | 30 +- toolkit/commonjs/sdk/lang/weak-set.js | 21 +- toolkit/content/aboutwebrtc/aboutWebrtc.css | 19 +- toolkit/content/aboutwebrtc/aboutWebrtc.html | 21 + toolkit/content/aboutwebrtc/aboutWebrtc.js | 142 +++- toolkit/content/aboutwebrtc/aboutWebrtc.xhtml | 24 - toolkit/content/jar.mn | 2 +- toolkit/devtools/debugger/utils.js | 2 +- .../server/PHeapSnapshotTempFileHelper.ipdl | 2 +- toolkit/devtools/shared/widgets/Tooltip.js | 1 - .../devtools/shared/widgets/VariablesView.jsm | 2 +- .../chrome/global/aboutWebrtc.properties | 1 + uriloader/exthandler/PExternalHelperApp.ipdl | 12 +- uriloader/exthandler/PHandlerService.ipdl | 2 +- uriloader/prefetch/POfflineCacheUpdate.ipdl | 8 +- widget/cocoa/nsNativeThemeCocoa.mm | 5 +- widget/gtk/nsWindow.h | 8 +- widget/nsNativeTheme.cpp | 6 +- widget/nsShmImage.cpp | 219 +++--- widget/nsShmImage.h | 34 +- 452 files changed, 5583 insertions(+), 3021 deletions(-) create mode 100644 dom/html/test/file_fullscreen-backdrop.html create mode 100644 dom/media/webspeech/synth/test/file_bfcache_frame.html create mode 100644 dom/media/webspeech/synth/test/file_global_queue.html create mode 100644 dom/media/webspeech/synth/test/file_global_queue_cancel.html create mode 100644 dom/media/webspeech/synth/test/file_global_queue_pause.html create mode 100644 dom/media/webspeech/synth/test/file_speech_error.html create mode 100644 dom/media/webspeech/synth/test/test_bfcache.html create mode 100644 dom/media/webspeech/synth/test/test_global_queue.html create mode 100644 dom/media/webspeech/synth/test/test_global_queue_cancel.html create mode 100644 dom/media/webspeech/synth/test/test_global_queue_pause.html create mode 100644 dom/media/webspeech/synth/test/test_speech_error.html create mode 100644 dom/network/EthernetManager.js create mode 100644 dom/network/EthernetManager.manifest create mode 100644 dom/network/interfaces/nsIEthernetManager.idl create mode 100644 dom/network/tests/marionette/head.js create mode 100644 dom/network/tests/marionette/manifest.ini create mode 100644 dom/network/tests/marionette/test_ethernet_add_interface.js create mode 100644 dom/network/tests/marionette/test_ethernet_connect_with_dhcp.js create mode 100644 dom/network/tests/marionette/test_ethernet_connect_with_static_ip.js create mode 100644 dom/network/tests/marionette/test_ethernet_disable.js create mode 100644 dom/network/tests/marionette/test_ethernet_disconnect.js create mode 100644 dom/network/tests/marionette/test_ethernet_enable.js create mode 100644 dom/network/tests/marionette/test_ethernet_ip_mode_change.js create mode 100644 dom/network/tests/marionette/test_ethernet_reconnect_with_dhcp.js create mode 100644 dom/network/tests/marionette/test_ethernet_reconnect_with_static_ip.js create mode 100644 dom/network/tests/marionette/test_ethernet_remove_interface.js delete mode 100644 ipc/glue/SharedMemorySysV.h delete mode 100644 ipc/ipdl/test/cxx/PTestSysVShmem.ipdl delete mode 100644 ipc/ipdl/test/cxx/TestSysVShmem.cpp delete mode 100644 ipc/ipdl/test/cxx/TestSysVShmem.h delete mode 100644 js/src/jit-test/tests/collections/WeakMap-clear.js delete mode 100644 js/src/jit-test/tests/collections/WeakSet-clear.js create mode 100644 layout/generic/nsBackdropFrame.cpp create mode 100644 layout/generic/nsBackdropFrame.h create mode 100644 layout/reftests/css-break/box-decoration-break-bug-1235152-ref.html create mode 100644 layout/reftests/css-break/box-decoration-break-bug-1235152.html create mode 100644 toolkit/content/aboutwebrtc/aboutWebrtc.html delete mode 100644 toolkit/content/aboutwebrtc/aboutWebrtc.xhtml diff --git a/accessible/generic/HyperTextAccessible.cpp b/accessible/generic/HyperTextAccessible.cpp index 563ac6fe00..e344599ecd 100644 --- a/accessible/generic/HyperTextAccessible.cpp +++ b/accessible/generic/HyperTextAccessible.cpp @@ -1466,7 +1466,7 @@ HyperTextAccessible::CaretLineNumber() break; // Add lines for the sibling frames before the caret - nsIFrame *sibling = parentFrame->GetFirstPrincipalChild(); + nsIFrame *sibling = parentFrame->PrincipalChildList().FirstChild(); while (sibling && sibling != caretFrame) { nsAutoLineIterator lineIterForSibling = sibling->GetLineIterator(); if (lineIterForSibling) { diff --git a/accessible/ipc/PDocAccessible.ipdl b/accessible/ipc/PDocAccessible.ipdl index 69281b1067..91d8a82448 100644 --- a/accessible/ipc/PDocAccessible.ipdl +++ b/accessible/ipc/PDocAccessible.ipdl @@ -48,28 +48,28 @@ prio(normal upto high) sync protocol PDocAccessible manager PBrowser; parent: - Shutdown(); + async Shutdown(); /* * Notify the parent process the document in the child process is firing an * event. */ - Event(uint64_t aID, uint32_t type); - ShowEvent(ShowEventData data); - HideEvent(uint64_t aRootID); - StateChangeEvent(uint64_t aID, uint64_t aState, bool aEnabled); - CaretMoveEvent(uint64_t aID, int32_t aOffset); - TextChangeEvent(uint64_t aID, nsString aStr, int32_t aStart, uint32_t aLen, - bool aIsInsert, bool aFromUser); + async Event(uint64_t aID, uint32_t type); + async ShowEvent(ShowEventData data); + async HideEvent(uint64_t aRootID); + async StateChangeEvent(uint64_t aID, uint64_t aState, bool aEnabled); + async CaretMoveEvent(uint64_t aID, int32_t aOffset); + async TextChangeEvent(uint64_t aID, nsString aStr, int32_t aStart, uint32_t aLen, + bool aIsInsert, bool aFromUser); /* * Tell the parent document to bind the existing document as a new child * document. */ - BindChildDoc(PDocAccessible aChildDoc, uint64_t aID); + async BindChildDoc(PDocAccessible aChildDoc, uint64_t aID); child: - __delete__(); + async __delete__(); // Accessible prio(high) sync State(uint64_t aID) returns(uint64_t states); @@ -132,13 +132,13 @@ child: prio(high) sync RemoveFromSelection(uint64_t aID, int32_t aSelectionNum) returns(bool aSucceeded); - ScrollSubstringTo(uint64_t aID, int32_t aStartOffset, int32_t aEndOffset, - uint32_t aScrollType); - ScrollSubstringToPoint(uint64_t aID, - int32_t aStartOffset, - int32_t aEndOffset, - uint32_t aCoordinateType, - int32_t aX, int32_t aY); + async ScrollSubstringTo(uint64_t aID, int32_t aStartOffset, int32_t aEndOffset, + uint32_t aScrollType); + async ScrollSubstringToPoint(uint64_t aID, + int32_t aStartOffset, + int32_t aEndOffset, + uint32_t aCoordinateType, + int32_t aX, int32_t aY); prio(high) sync Text(uint64_t aID) returns(nsString aText); prio(high) sync ReplaceText(uint64_t aID, nsString aText); diff --git a/accessible/jsat/EventManager.jsm b/accessible/jsat/EventManager.jsm index c3766ce6cb..18675747c7 100644 --- a/accessible/jsat/EventManager.jsm +++ b/accessible/jsat/EventManager.jsm @@ -77,7 +77,7 @@ this.EventManager.prototype = { Logger.debug('EventManager.stop'); AccessibilityEventObserver.removeListener(this); try { - this._preDialogPosition.clear(); + this._preDialogPosition = new WeakMap(); this.webProgress.removeProgressListener(this); this.removeEventListener('wheel', this, true); this.removeEventListener('scroll', this, true); @@ -618,7 +618,7 @@ const AccessibilityEventObserver = { } Services.obs.removeObserver(this, 'accessible-event'); // Clean up all registered event managers. - this.eventManagers.clear(); + this.eventManagers = new WeakMap(); this.listenerCount = 0; this.started = false; }, diff --git a/b2g/installer/package-manifest.in b/b2g/installer/package-manifest.in index b577b78caf..8ce96b08a4 100644 --- a/b2g/installer/package-manifest.in +++ b/b2g/installer/package-manifest.in @@ -477,6 +477,8 @@ @RESPATH@/components/DOMWifiManager.manifest @RESPATH@/components/DOMWifiP2pManager.js @RESPATH@/components/DOMWifiP2pManager.manifest +@RESPATH@/components/EthernetManager.js +@RESPATH@/components/EthernetManager.manifest @RESPATH@/components/NetworkInterfaceListService.js @RESPATH@/components/NetworkInterfaceListService.manifest @RESPATH@/components/NetworkManager.js diff --git a/browser/base/content/browser-fullZoom.js b/browser/base/content/browser-fullZoom.js index 2b1cd22331..464c028ff6 100644 --- a/browser/base/content/browser-fullZoom.js +++ b/browser/base/content/browser-fullZoom.js @@ -78,7 +78,6 @@ var FullZoom = { } // This should be nulled after initialization. - this._initialLocations.clear(); this._initialLocations = null; }, diff --git a/docshell/base/nsAboutRedirector.cpp b/docshell/base/nsAboutRedirector.cpp index 7f44a067fd..ee2cbf7566 100644 --- a/docshell/base/nsAboutRedirector.cpp +++ b/docshell/base/nsAboutRedirector.cpp @@ -97,7 +97,7 @@ static RedirEntry kRedirMap[] = { nsIAboutModule::ALLOW_SCRIPT }, { - "webrtc", "chrome://global/content/aboutwebrtc/aboutWebrtc.xhtml", + "webrtc", "chrome://global/content/aboutwebrtc/aboutWebrtc.html", nsIAboutModule::ALLOW_SCRIPT }, { diff --git a/dom/asmjscache/PAsmJSCacheEntry.ipdl b/dom/asmjscache/PAsmJSCacheEntry.ipdl index 13ebb9b583..4980650ccb 100644 --- a/dom/asmjscache/PAsmJSCacheEntry.ipdl +++ b/dom/asmjscache/PAsmJSCacheEntry.ipdl @@ -19,18 +19,18 @@ protocol PAsmJSCacheEntry // origin's Metadata so the child process can select the cache entry to open // (based on hash) and notify the parent (via SelectCacheFileToRead). child: - OnOpenMetadataForRead(Metadata metadata); + async OnOpenMetadataForRead(Metadata metadata); parent: - SelectCacheFileToRead(uint32_t moduleIndex); - CacheMiss(); + async SelectCacheFileToRead(uint32_t moduleIndex); + async CacheMiss(); child: // Once the cache file has been opened, the child is notified and sent an // open file descriptor. - OnOpenCacheFile(int64_t fileSize, FileDescriptor fileDesc); + async OnOpenCacheFile(int64_t fileSize, FileDescriptor fileDesc); both: - __delete__(AsmJSCacheResult result); + async __delete__(AsmJSCacheResult result); }; } // namespace asmjscache diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp index 5a212ce063..90a7feb3e8 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -6922,7 +6922,7 @@ nsContentUtils::GetAdjustedOffsetInTextControl(nsIFrame* aOffsetFrame, // has the text frames (containing the content) as its children. This will // be the case if we click to the right of any of the text frames, or at the // bottom of the text area. - nsIFrame* firstChild = aOffsetFrame->GetFirstPrincipalChild(); + nsIFrame* firstChild = aOffsetFrame->PrincipalChildList().FirstChild(); if (firstChild) { // In this case, the passed-in offset is incorrect, and we want the length // of the entire content in the text control frame. @@ -6935,7 +6935,7 @@ nsContentUtils::GetAdjustedOffsetInTextControl(nsIFrame* aOffsetFrame, // frame. Our offset should therefore be the length of the first child of // our parent. int32_t aOutOffset = - aOffsetFrame->GetParent()->GetFirstPrincipalChild()->GetContent()->Length(); + aOffsetFrame->GetParent()->PrincipalChildList().FirstChild()->GetContent()->Length(); return aOutOffset; } diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index 0d59976bf0..737d7e85d6 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -8774,6 +8774,13 @@ nsDocument::CanSavePresentation(nsIRequest *aNewRequest) } } + #ifdef MOZ_WEBSPEECH + nsGlobalWindow* globalWindow = static_cast(win); + if (globalWindow->HasActiveSpeechSynthesis()) { + return false; + } + #endif + return true; } diff --git a/dom/base/nsDocumentEncoder.cpp b/dom/base/nsDocumentEncoder.cpp index 293d03e575..afa9b9137a 100644 --- a/dom/base/nsDocumentEncoder.cpp +++ b/dom/base/nsDocumentEncoder.cpp @@ -49,6 +49,8 @@ #include "mozilla/dom/Element.h" #include "mozilla/dom/ShadowRoot.h" #include "mozilla/dom/EncodingUtils.h" +#include "nsContainerFrame.h" +#include "nsBlockFrame.h" #include "nsComputedDOMStyle.h" using namespace mozilla; @@ -324,7 +326,43 @@ nsDocumentEncoder::IncludeInContext(nsINode *aNode) static bool -IsInvisibleBreak(nsINode *aNode) { +LineHasNonEmptyContentWorker(nsIFrame* aFrame) +{ + // Look for non-empty frames, but ignore inline and br frames. + // For inline frames, descend into the children, if any. + if (aFrame->GetType() == nsGkAtoms::inlineFrame) { + for (nsIFrame* child : aFrame->PrincipalChildList()) { + if (LineHasNonEmptyContentWorker(child)) { + return true; + } + } + } else { + if (aFrame->GetType() != nsGkAtoms::brFrame && + !aFrame->IsEmpty()) { + return true; + } + } + return false; +} + +static +bool +LineHasNonEmptyContent(nsLineBox* aLine) +{ + int32_t count = aLine->GetChildCount(); + for (nsIFrame* frame = aLine->mFirstChild; count > 0; + --count, frame = frame->GetNextSibling()) { + if (LineHasNonEmptyContentWorker(frame)) { + return true; + } + } + return false; +} + +static +bool +IsInvisibleBreak(nsINode *aNode) +{ if (!aNode->IsElement() || !aNode->IsEditable()) { return false; } @@ -333,14 +371,36 @@ IsInvisibleBreak(nsINode *aNode) { return false; } - // If the BRFrame has caused a visible line break, it should have a next - // sibling, or otherwise no siblings (or immediately after a br) and a - // non-zero height. - bool visible = frame->GetNextSibling() || - ((!frame->GetPrevSibling() || - frame->GetPrevSibling()->GetType() == nsGkAtoms::brFrame) && - frame->GetRect().Height() != 0); - return !visible; + nsContainerFrame* f = frame->GetParent(); + while (f && f->IsFrameOfType(nsBox::eLineParticipant)) { + f = f->GetParent(); + } + nsBlockFrame* blockAncestor = do_QueryFrame(f); + if (!blockAncestor) { + // The container frame doesn't support line breaking. + return false; + } + + bool valid = false; + nsBlockInFlowLineIterator iter(blockAncestor, frame, &valid); + if (!valid) { + return false; + } + + bool lineNonEmpty = LineHasNonEmptyContent(iter.GetLine()); + + while (iter.Next()) { + auto currentLine = iter.GetLine(); + // Completely skip empty lines. + if (!currentLine->IsEmpty()) { + // If we come across an inline line, the BR has caused a visible line break. + if (currentLine->IsInline()) { + return false; + } + } + } + + return lineNonEmpty; } nsresult @@ -1047,6 +1107,9 @@ nsDocumentEncoder::EncodeToStringWithMaxLength(uint32_t aMaxLength, static const size_t bufferSize = 2048; if (!mCachedBuffer) { mCachedBuffer = nsStringBuffer::Alloc(bufferSize).take(); + if (NS_WARN_IF(!mCachedBuffer)) { + return NS_ERROR_OUT_OF_MEMORY; + } } NS_ASSERTION(!mCachedBuffer->IsReadonly(), "DocumentEncoder shouldn't keep reference to non-readonly buffer!"); @@ -1374,10 +1437,6 @@ nsHTMLCopyEncoder::SetSelection(nsISelection* aSelection) return NS_ERROR_NULL_POINTER; range->GetCommonAncestorContainer(getter_AddRefs(commonParent)); - // Thunderbird's msg compose code abuses the HTML copy encoder and gets - // confused if mIsTextWidget ends up becoming true, so for now we skip - // this logic in Thunderbird. -#ifndef MOZ_THUNDERBIRD for (nsCOMPtr selContent(do_QueryInterface(commonParent)); selContent; selContent = selContent->GetParent()) @@ -1388,6 +1447,46 @@ nsHTMLCopyEncoder::SetSelection(nsISelection* aSelection) mIsTextWidget = true; break; } +#ifdef MOZ_THUNDERBIRD + else if (selContent->IsHTMLElement(nsGkAtoms::body)) { + // Currently, setting mIsTextWidget to 'true' will result in the selection + // being encoded/copied as pre-formatted plain text. + // This is fine for copying pre-formatted plain text with Firefox, it is + // already not correct for copying pre-formatted "rich" text (bold, colour) + // with Firefox. As long as the serialisers aren't fixed, copying + // pre-formatted text in Firefox is broken. If we set mIsTextWidget, + // pre-formatted plain text is copied, but pre-formatted "rich" text loses + // the "rich" formatting. If we don't set mIsTextWidget, "rich" text + // attributes aren't lost, but white-space is lost. + // So far the story for Firefox. + // + // Thunderbird has two *conflicting* requirements. + // Case 1: + // When selecting and copying text, even pre-formatted text, as a quote + // to be placed into a reply, we *always* expect HTML to be copied. + // Case 2: + // When copying text in a so-called "plain text" message, that is + // one where the body carries style "white-space:pre-wrap", the text should + // be copied as pre-formatted plain text. + // + // Therefore the following code checks for "pre-wrap" on the body. + // This is a terrible hack. + // + // The proper fix would be this: + // For case 1: + // Communicate the fact that HTML is required to EncodeToString(), + // bug 1141786. + // For case 2: + // Wait for Firefox to get fixed to detect pre-formatting correctly, + // bug 1174452. + nsAutoString styleVal; + if (selContent->GetAttr(kNameSpaceID_None, nsGkAtoms::style, styleVal) && + styleVal.Find(NS_LITERAL_STRING("pre-wrap")) != kNotFound) { + mIsTextWidget = true; + break; + } + } +#endif } // normalize selection if we are not in a widget @@ -1397,11 +1496,7 @@ nsHTMLCopyEncoder::SetSelection(nsISelection* aSelection) mMimeType.AssignLiteral("text/plain"); return NS_OK; } -#endif - // XXX For better performance, we should try to get rid of the - // Selection object here. See BMO bug 1245883 - // also consider ourselves in a text widget if we can't find an html document nsCOMPtr htmlDoc = do_QueryInterface(mDocument); if (!(htmlDoc && mDocument->IsHTMLDocument())) { diff --git a/dom/base/nsGkAtomList.h b/dom/base/nsGkAtomList.h index ddcd9a1538..1130d64a86 100644 --- a/dom/base/nsGkAtomList.h +++ b/dom/base/nsGkAtomList.h @@ -126,6 +126,7 @@ GK_ATOM(autoplay, "autoplay") GK_ATOM(autorepeatbutton, "autorepeatbutton") GK_ATOM(axis, "axis") GK_ATOM(b, "b") +GK_ATOM(backdropFrame, "BackdropFrame") GK_ATOM(background, "background") GK_ATOM(base, "base") GK_ATOM(basefont, "basefont") diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index f530757bf0..ec2364b395 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -3820,6 +3820,19 @@ nsGlobalWindow::GetSpeechSynthesis(ErrorResult& aError) return mSpeechSynthesis; } + +bool +nsGlobalWindow::HasActiveSpeechSynthesis() +{ + MOZ_ASSERT(IsInnerWindow()); + + if (mSpeechSynthesis) { + return !mSpeechSynthesis->HasEmptyQueue(); + } + + return false; +} + #endif already_AddRefed @@ -10417,13 +10430,11 @@ static nsCanvasFrame* FindCanvasFrame(nsIFrame* aFrame) return canvasFrame; } - nsIFrame* kid = aFrame->GetFirstPrincipalChild(); - while (kid) { + for (nsIFrame* kid : aFrame->PrincipalChildList()) { canvasFrame = FindCanvasFrame(kid); if (canvasFrame) { return canvasFrame; } - kid = kid->GetNextSibling(); } return nullptr; diff --git a/dom/base/nsGlobalWindow.h b/dom/base/nsGlobalWindow.h index 25f01b4a55..0e431df5f9 100644 --- a/dom/base/nsGlobalWindow.h +++ b/dom/base/nsGlobalWindow.h @@ -1025,6 +1025,7 @@ public: #ifdef MOZ_WEBSPEECH mozilla::dom::SpeechSynthesis* GetSpeechSynthesis(mozilla::ErrorResult& aError); + bool HasActiveSpeechSynthesis(); #endif already_AddRefed GetDefaultComputedStyle(mozilla::dom::Element& aElt, diff --git a/dom/base/nsRange.cpp b/dom/base/nsRange.cpp index 4d1e82a0ef..0b651a451b 100644 --- a/dom/base/nsRange.cpp +++ b/dom/base/nsRange.cpp @@ -3333,7 +3333,7 @@ IsLastNonemptyRowGroupOfTable(nsIFrame* aFrame) } for (nsIFrame* c = aFrame; c; c = c->GetNextContinuation()) { for (nsIFrame* next = c->GetNextSibling(); next; next = next->GetNextSibling()) { - if (next->GetFirstPrincipalChild()) { + if (next->PrincipalChildList().FirstChild()) { return false; } } diff --git a/dom/base/test/test_bug116083.html b/dom/base/test/test_bug116083.html index 68b466f8f7..dfdef8d435 100644 --- a/dom/base/test/test_bug116083.html +++ b/dom/base/test/test_bug116083.html @@ -28,6 +28,22 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=116083
foo
bar

!


baz
foo
bar

!


baz
foo
bar

!


baz
+
foo
bar
baz
qux
+
foo
bar
baz
qux
+
foo

+
foo

+
foo

bar
+
foo

bar
+
foo
bar
+
foo
bar
+
foo
bar
baz
+
foo
bar
baz
+


foo
+


foo
+
foo
bar
+
foo
bar
+
foo
bar
+
foo
bar
foo bar
+ + + + + +
+ + + diff --git a/dom/html/test/file_fullscreen-top-layer.html b/dom/html/test/file_fullscreen-top-layer.html index 9d3e9ef594..cc0ff1053a 100644 --- a/dom/html/test/file_fullscreen-top-layer.html +++ b/dom/html/test/file_fullscreen-top-layer.html @@ -88,23 +88,6 @@ function ok(cond, msg) { opener.ok(cond, "[top-layer] " + msg); } -function generatePureColorCanvas(width, height, color) { - const canvas = document.createElement("canvas"); - canvas.width = width; - canvas.height = height; - const context = canvas.getContext("2d"); - context.fillStyle = color; - context.fillRect(0, 0, width, height); - return canvas; -} - -function checkWindowPureColor(color) { - const snapshot = SpecialPowers.snapshotRect(window); - const pureColor = - generatePureColorCanvas(snapshot.width, snapshot.height, color); - assertSnapshots(snapshot, pureColor, true, null, "snapshot", color); -} - function synthesizeMouseAtWindowCenter() { synthesizeMouseAtPoint(innerWidth / 2, innerHeight / 2, {}); } @@ -129,7 +112,7 @@ function nextTest() { ok(!document.mozFullScreen, "Shouldn't be in fullscreen"); // check window snapshot - checkWindowPureColor("red"); + assertWindowPureColor(window, "red"); // simulate click window.addEventListener("click", firstClick); synthesizeMouseAtWindowCenter(); @@ -145,7 +128,7 @@ function firstClick(evt) { function enterFullscreen() { ok(document.mozFullScreen, "Should now be in fullscreen"); // check window snapshot - checkWindowPureColor("green"); + assertWindowPureColor(window, "green"); // check computed style of #parent const style = getComputedStyle(gParent); for (var prop of gParentProperties) { diff --git a/dom/html/test/mochitest.ini b/dom/html/test/mochitest.ini index 24d80a53dc..1a06aa84e1 100644 --- a/dom/html/test/mochitest.ini +++ b/dom/html/test/mochitest.ini @@ -48,6 +48,7 @@ support-files = file_formSubmission_text.txt file_fullscreen-api-keys.html file_fullscreen-api.html + file_fullscreen-backdrop.html file_fullscreen-denied-inner.html file_fullscreen-denied.html file_fullscreen-esc-context-menu.html diff --git a/dom/html/test/test_fullscreen-api.html b/dom/html/test/test_fullscreen-api.html index 45eb2db1f5..79e62ecee5 100644 --- a/dom/html/test/test_fullscreen-api.html +++ b/dom/html/test/test_fullscreen-api.html @@ -42,6 +42,7 @@ var gTestWindows = [ "file_fullscreen-scrollbar.html", "file_fullscreen-selector.html", "file_fullscreen-top-layer.html", + "file_fullscreen-backdrop.html", "file_fullscreen-nested.html", ]; diff --git a/dom/icc/ipc/PIcc.ipdl b/dom/icc/ipc/PIcc.ipdl index 3a264a102d..fdad3f3e04 100644 --- a/dom/icc/ipc/PIcc.ipdl +++ b/dom/icc/ipc/PIcc.ipdl @@ -94,12 +94,12 @@ child: /** * Notify CardStateChanged with updated CardState. */ - NotifyCardStateChanged(uint32_t aCardState); + async NotifyCardStateChanged(uint32_t aCardState); /** * Notify IccInfoChanged with updated IccInfo. */ - NotifyIccInfoChanged(OptionalIccInfoData aInfoData); + async NotifyIccInfoChanged(OptionalIccInfoData aInfoData); /** * Notify STK proactive command issue by selected UICC. @@ -107,23 +107,23 @@ child: * @param aStkProactiveCmd * a MozStkCommand instance serialized in JSON. */ - NotifyStkCommand(nsString aStkProactiveCmd); + async NotifyStkCommand(nsString aStkProactiveCmd); /** * Notify that STK session is ended by selected UICC. */ - NotifyStkSessionEnd(); + async NotifyStkSessionEnd(); parent: /** * Sent when the child no longer needs to use PIcc. */ - __delete__(); + async __delete__(); /** * Sent when the child makes an asynchronous request to the parent. */ - PIccRequest(IccRequest aRequest); + async PIccRequest(IccRequest aRequest); /** * Send STK response to the selected UICC. @@ -133,17 +133,17 @@ parent: * @param aResponse * a MozStkResponse instance serialized in JSON. */ - StkResponse(nsString aCommand, nsString aResponse); + async StkResponse(nsString aCommand, nsString aResponse); /** * Send STK Menu Selection to the selected UICC. */ - StkMenuSelection(uint16_t aItemIdentifier, bool aHelpRequested); + async StkMenuSelection(uint16_t aItemIdentifier, bool aHelpRequested); /** * Send STK Timer Expiration to the selected UICC. */ - StkTimerExpiration(uint16_t aTimerId, uint32_t aTimerValue); + async StkTimerExpiration(uint16_t aTimerId, uint32_t aTimerValue); /** * Send STK Event Download to the selected UICC. @@ -151,7 +151,7 @@ parent: * @param aEvent * a MozStkXxxEvent instance serialized in JSON. */ - StkEventDownload(nsString aEvent); + async StkEventDownload(nsString aEvent); /** * Sync call to initialize the updated IccInfo/CardState. diff --git a/dom/icc/ipc/PIccRequest.ipdl b/dom/icc/ipc/PIccRequest.ipdl index 5c8ab1f38c..275d23d305 100644 --- a/dom/icc/ipc/PIccRequest.ipdl +++ b/dom/icc/ipc/PIccRequest.ipdl @@ -65,7 +65,7 @@ child: /** * Sent when the asynchronous request has completed. */ - __delete__(IccReply response); + async __delete__(IccReply response); }; } // namespace icc diff --git a/dom/imptests/failures/html/js/builtins/test_WeakMap.prototype-properties.html.json b/dom/imptests/failures/html/js/builtins/test_WeakMap.prototype-properties.html.json index ccaf35e45b..c311eb4110 100644 --- a/dom/imptests/failures/html/js/builtins/test_WeakMap.prototype-properties.html.json +++ b/dom/imptests/failures/html/js/builtins/test_WeakMap.prototype-properties.html.json @@ -1,5 +1,4 @@ { - "WeakMap.prototype.clear.length": true, "WeakMap.prototype.delete.length": true, "WeakMap.prototype.get.length": true, "WeakMap.prototype.has.length": true, diff --git a/dom/imptests/html/js/builtins/test_WeakMap.prototype-properties.html b/dom/imptests/html/js/builtins/test_WeakMap.prototype-properties.html index 6f7c60050c..0bdb6bb86d 100644 --- a/dom/imptests/html/js/builtins/test_WeakMap.prototype-properties.html +++ b/dom/imptests/html/js/builtins/test_WeakMap.prototype-properties.html @@ -55,25 +55,7 @@ test(function() { assert_propdesc(WeakMap.prototype, "constructor", true, false, true); }, "The initial value of WeakMap.prototype.constructor is the built-in WeakMap constructor.") -// 15.15.5.2 WeakMap.prototype.clear () -test(function() { - assert_propdesc(WeakMap.prototype, "clear", true, false, true); - test_length("clear", 0); - // Step 1-3 - test_thisval("clear", null); - // Step 4-5 - test(function() { - var wm = new WeakMap(); - var key = {}; - wm.set(key, "fail"); - assert_true(wm.has(key)); - var res = wm.clear(); - assert_equals(res, undefined); - assert_false(wm.has(key)); - }, "WeakMap.prototype.clear: basic functionality"); -}, "WeakMap.prototype.clear") - -// 15.15.5.3 WeakMap.prototype.delete ( key ) +// 15.15.5.2 WeakMap.prototype.delete ( key ) test(function() { assert_propdesc(WeakMap.prototype, "delete", true, false, true); test_length("delete", 1); @@ -81,7 +63,7 @@ test(function() { test_thisval("delete", [{}]); }, "WeakMap.prototype.delete") -// 15.15.5.4 WeakMap.prototype.get ( key ) +// 15.15.5.3 WeakMap.prototype.get ( key ) test(function() { assert_propdesc(WeakMap.prototype, "get", true, false, true); test_length("get", 1); @@ -97,7 +79,7 @@ test(function() { }, "WeakMap.prototype.get: return undefined"); }, "WeakMap.prototype.get") -// 15.14.5.5 Map.prototype.has ( key ) +// 15.14.5.4 Map.prototype.has ( key ) test(function() { assert_propdesc(WeakMap.prototype, "has", true, false, true); test_length("has", 1); @@ -105,7 +87,7 @@ test(function() { test_thisval("has", [{}]); }, "WeakMap.prototype.has") -// 15.14.5.6 Map.prototype.set ( key , value ) +// 15.14.5.5 Map.prototype.set ( key , value ) test(function() { assert_propdesc(WeakMap.prototype, "set", true, false, true); test_length("set", 2); @@ -113,7 +95,7 @@ test(function() { test_thisval("set", [{}, {}]); }, "WeakMap.prototype.set") -// 15.15.5.7 Map.prototype.@@toStringTag +// 15.15.5.6 Map.prototype.@@toStringTag test(function() { assert_class_string(new WeakMap(), "WeakMap"); assert_class_string(WeakMap.prototype, "WeakMap"); diff --git a/dom/indexedDB/PBackgroundIDBCursor.ipdl b/dom/indexedDB/PBackgroundIDBCursor.ipdl index 5173b2fa0b..255467891a 100644 --- a/dom/indexedDB/PBackgroundIDBCursor.ipdl +++ b/dom/indexedDB/PBackgroundIDBCursor.ipdl @@ -78,14 +78,14 @@ protocol PBackgroundIDBCursor manager PBackgroundIDBTransaction or PBackgroundIDBVersionChangeTransaction; parent: - DeleteMe(); + async DeleteMe(); - Continue(CursorRequestParams params, Key key); + async Continue(CursorRequestParams params, Key key); child: - __delete__(); + async __delete__(); - Response(CursorResponse response); + async Response(CursorResponse response); }; } // namespace indexedDB diff --git a/dom/indexedDB/PBackgroundIDBDatabase.ipdl b/dom/indexedDB/PBackgroundIDBDatabase.ipdl index 6c0fa2052e..dc7d53a83d 100644 --- a/dom/indexedDB/PBackgroundIDBDatabase.ipdl +++ b/dom/indexedDB/PBackgroundIDBDatabase.ipdl @@ -53,31 +53,31 @@ sync protocol PBackgroundIDBDatabase manages PBackgroundMutableFile; parent: - DeleteMe(); + async DeleteMe(); - Blocked(); + async Blocked(); - Close(); + async Close(); - PBackgroundIDBDatabaseFile(PBlob blob); + async PBackgroundIDBDatabaseFile(PBlob blob); - PBackgroundIDBDatabaseRequest(DatabaseRequestParams params); + async PBackgroundIDBDatabaseRequest(DatabaseRequestParams params); - PBackgroundIDBTransaction(nsString[] objectStoreNames, Mode mode); + async PBackgroundIDBTransaction(nsString[] objectStoreNames, Mode mode); child: - __delete__(); + async __delete__(); - VersionChange(uint64_t oldVersion, NullableVersion newVersion); + async VersionChange(uint64_t oldVersion, NullableVersion newVersion); - Invalidate(); + async Invalidate(); - PBackgroundIDBVersionChangeTransaction(uint64_t currentVersion, - uint64_t requestedVersion, - int64_t nextObjectStoreId, - int64_t nextIndexId); + async PBackgroundIDBVersionChangeTransaction(uint64_t currentVersion, + uint64_t requestedVersion, + int64_t nextObjectStoreId, + int64_t nextIndexId); - PBackgroundMutableFile(nsString name, nsString type); + async PBackgroundMutableFile(nsString name, nsString type); }; } // namespace indexedDB diff --git a/dom/indexedDB/PBackgroundIDBDatabaseFile.ipdl b/dom/indexedDB/PBackgroundIDBDatabaseFile.ipdl index db66e77339..e2f7c9f85b 100644 --- a/dom/indexedDB/PBackgroundIDBDatabaseFile.ipdl +++ b/dom/indexedDB/PBackgroundIDBDatabaseFile.ipdl @@ -13,7 +13,7 @@ protocol PBackgroundIDBDatabaseFile manager PBackgroundIDBDatabase; parent: - __delete__(); + async __delete__(); }; } // namespace indexedDB diff --git a/dom/indexedDB/PBackgroundIDBDatabaseRequest.ipdl b/dom/indexedDB/PBackgroundIDBDatabaseRequest.ipdl index ff02bda80c..c3b342048a 100644 --- a/dom/indexedDB/PBackgroundIDBDatabaseRequest.ipdl +++ b/dom/indexedDB/PBackgroundIDBDatabaseRequest.ipdl @@ -25,7 +25,7 @@ protocol PBackgroundIDBDatabaseRequest manager PBackgroundIDBDatabase; child: - __delete__(DatabaseRequestResponse response); + async __delete__(DatabaseRequestResponse response); }; } // namespace indexedDB diff --git a/dom/indexedDB/PBackgroundIDBFactory.ipdl b/dom/indexedDB/PBackgroundIDBFactory.ipdl index ff186eff58..e6c64dca4e 100644 --- a/dom/indexedDB/PBackgroundIDBFactory.ipdl +++ b/dom/indexedDB/PBackgroundIDBFactory.ipdl @@ -49,17 +49,17 @@ sync protocol PBackgroundIDBFactory manages PBackgroundIDBFactoryRequest; parent: - DeleteMe(); + async DeleteMe(); - PBackgroundIDBFactoryRequest(FactoryRequestParams params); + async PBackgroundIDBFactoryRequest(FactoryRequestParams params); - IncrementLoggingRequestSerialNumber(); + async IncrementLoggingRequestSerialNumber(); child: - __delete__(); + async __delete__(); - PBackgroundIDBDatabase(DatabaseSpec spec, - PBackgroundIDBFactoryRequest request); + async PBackgroundIDBDatabase(DatabaseSpec spec, + PBackgroundIDBFactoryRequest request); }; } // namespace indexedDB diff --git a/dom/indexedDB/PBackgroundIDBFactoryRequest.ipdl b/dom/indexedDB/PBackgroundIDBFactoryRequest.ipdl index 1e198fc96b..fc74807fed 100644 --- a/dom/indexedDB/PBackgroundIDBFactoryRequest.ipdl +++ b/dom/indexedDB/PBackgroundIDBFactoryRequest.ipdl @@ -33,14 +33,14 @@ protocol PBackgroundIDBFactoryRequest manager PBackgroundIDBFactory; child: - __delete__(FactoryRequestResponse response); + async __delete__(FactoryRequestResponse response); - PermissionChallenge(PrincipalInfo principalInfo); + async PermissionChallenge(PrincipalInfo principalInfo); - Blocked(uint64_t currentVersion); + async Blocked(uint64_t currentVersion); parent: - PermissionRetry(); + async PermissionRetry(); }; } // namespace indexedDB diff --git a/dom/indexedDB/PBackgroundIDBRequest.ipdl b/dom/indexedDB/PBackgroundIDBRequest.ipdl index 694426c2c2..34a30a8334 100644 --- a/dom/indexedDB/PBackgroundIDBRequest.ipdl +++ b/dom/indexedDB/PBackgroundIDBRequest.ipdl @@ -105,7 +105,7 @@ protocol PBackgroundIDBRequest manager PBackgroundIDBTransaction or PBackgroundIDBVersionChangeTransaction; child: - __delete__(RequestResponse response); + async __delete__(RequestResponse response); }; } // namespace indexedDB diff --git a/dom/indexedDB/PBackgroundIDBTransaction.ipdl b/dom/indexedDB/PBackgroundIDBTransaction.ipdl index ba3faafcab..355f07761c 100644 --- a/dom/indexedDB/PBackgroundIDBTransaction.ipdl +++ b/dom/indexedDB/PBackgroundIDBTransaction.ipdl @@ -22,19 +22,19 @@ protocol PBackgroundIDBTransaction manages PBackgroundIDBRequest; parent: - DeleteMe(); + async DeleteMe(); - Commit(); - Abort(nsresult resultCode); + async Commit(); + async Abort(nsresult resultCode); - PBackgroundIDBCursor(OpenCursorParams params); + async PBackgroundIDBCursor(OpenCursorParams params); - PBackgroundIDBRequest(RequestParams params); + async PBackgroundIDBRequest(RequestParams params); child: - __delete__(); + async __delete__(); - Complete(nsresult result); + async Complete(nsresult result); }; } // namespace indexedDB diff --git a/dom/indexedDB/PBackgroundIDBVersionChangeTransaction.ipdl b/dom/indexedDB/PBackgroundIDBVersionChangeTransaction.ipdl index 766e922b79..1dea599362 100644 --- a/dom/indexedDB/PBackgroundIDBVersionChangeTransaction.ipdl +++ b/dom/indexedDB/PBackgroundIDBVersionChangeTransaction.ipdl @@ -23,27 +23,27 @@ protocol PBackgroundIDBVersionChangeTransaction manages PBackgroundIDBRequest; parent: - DeleteMe(); + async DeleteMe(); - Commit(); - Abort(nsresult resultCode); + async Commit(); + async Abort(nsresult resultCode); - CreateObjectStore(ObjectStoreMetadata metadata); - DeleteObjectStore(int64_t objectStoreId); + async CreateObjectStore(ObjectStoreMetadata metadata); + async DeleteObjectStore(int64_t objectStoreId); - CreateIndex(int64_t objectStoreId, - IndexMetadata metadata); - DeleteIndex(int64_t objectStoreId, - int64_t indexId); + async CreateIndex(int64_t objectStoreId, + IndexMetadata metadata); + async DeleteIndex(int64_t objectStoreId, + int64_t indexId); - PBackgroundIDBCursor(OpenCursorParams params); + async PBackgroundIDBCursor(OpenCursorParams params); - PBackgroundIDBRequest(RequestParams params); + async PBackgroundIDBRequest(RequestParams params); child: - __delete__(); + async __delete__(); - Complete(nsresult result); + async Complete(nsresult result); }; } // namespace indexedDB diff --git a/dom/indexedDB/PIndexedDBPermissionRequest.ipdl b/dom/indexedDB/PIndexedDBPermissionRequest.ipdl index 4eecb2b1c0..779793731e 100644 --- a/dom/indexedDB/PIndexedDBPermissionRequest.ipdl +++ b/dom/indexedDB/PIndexedDBPermissionRequest.ipdl @@ -19,7 +19,7 @@ child: * @param permission * The permission result (see nsIPermissionManager.idl for valid values). */ - __delete__(uint32_t permission); + async __delete__(uint32_t permission); }; } // namespace indexedDB diff --git a/dom/ipc/ContentParent.h b/dom/ipc/ContentParent.h index d7a86691d9..558b558993 100644 --- a/dom/ipc/ContentParent.h +++ b/dom/ipc/ContentParent.h @@ -971,11 +971,11 @@ private: void OnNewProcessCreated(uint32_t aPid, UniquePtr>&& aFds); - virtual bool RecvCreateFakeVolume(const nsString& fsName, - const nsString& mountPoint) override; + virtual bool RecvCreateFakeVolume(const nsString& aFsName, + const nsString& aMountPoint) override; - virtual bool RecvSetFakeVolumeState(const nsString& fsName, - const int32_t& fsState) override; + virtual bool RecvSetFakeVolumeState(const nsString& aFsName, + const int32_t& aFsState) override; virtual bool RecvRemoveFakeVolume(const nsString& fsName) override; @@ -1045,7 +1045,7 @@ private: bool* aResult) override; virtual bool - RecvFlushPendingFileDeletions() override; + RecvFlushPendingFileDeletions() override; virtual PWebrtcGlobalParent* AllocPWebrtcGlobalParent() override; diff --git a/dom/ipc/PBlob.ipdl b/dom/ipc/PBlob.ipdl index 09b78b1630..d2c04d3cdd 100644 --- a/dom/ipc/PBlob.ipdl +++ b/dom/ipc/PBlob.ipdl @@ -26,12 +26,12 @@ sync protocol PBlob manages PBlobStream; both: - __delete__(); + async __delete__(); parent: - PBlobStream(uint64_t begin, uint64_t length); + async PBlobStream(uint64_t begin, uint64_t length); - ResolveMystery(ResolveMysteryParams params); + async ResolveMystery(ResolveMysteryParams params); sync BlobStreamSync(uint64_t begin, uint64_t length) returns (InputStreamParams params, OptionalFileDescriptorSet fds); @@ -49,7 +49,7 @@ parent: child: // This method must be called by the parent when the PBlobParent is fully // created in order to release the known blob. - CreatedFromKnownBlob(); + async CreatedFromKnownBlob(); }; } // namespace dom diff --git a/dom/ipc/PBlobStream.ipdl b/dom/ipc/PBlobStream.ipdl index 03f4f87292..c82304950a 100644 --- a/dom/ipc/PBlobStream.ipdl +++ b/dom/ipc/PBlobStream.ipdl @@ -14,7 +14,7 @@ protocol PBlobStream manager PBlob; child: - __delete__(InputStreamParams params, OptionalFileDescriptorSet fds); + async __delete__(InputStreamParams params, OptionalFileDescriptorSet fds); }; } // namespace dom diff --git a/dom/ipc/PBrowser.ipdl b/dom/ipc/PBrowser.ipdl index a3b1d78cc6..4adc3a562b 100644 --- a/dom/ipc/PBrowser.ipdl +++ b/dom/ipc/PBrowser.ipdl @@ -111,14 +111,14 @@ prio(normal upto urgent) sync protocol PBrowser manages PPluginWidget; both: - AsyncMessage(nsString aMessage, ClonedMessageData aData, CpowEntry[] aCpows, - Principal aPrincipal); + async AsyncMessage(nsString aMessage, ClonedMessageData aData, CpowEntry[] aCpows, + Principal aPrincipal); /** * Create a layout frame (encapsulating a remote layer tree) for * the page that is currently loaded in the . */ - PRenderFrame(); + async PRenderFrame(); parent: /** @@ -127,7 +127,7 @@ parent: * aParentAcc is the id of the accessible in that document the new document * is a child of. */ - PDocAccessible(nullable PDocAccessible aParentDoc, uint64_t aParentAcc); + async PDocAccessible(nullable PDocAccessible aParentDoc, uint64_t aParentAcc); /* * Creates a new remoted nsIWidget connection for windowed plugins @@ -159,9 +159,9 @@ parent: * When child sends this message, parent should move focus to * the next or previous focusable element or document. */ - MoveFocus(bool forward, bool forDocumentNavigation); + async MoveFocus(bool forward, bool forDocumentNavigation); - Event(RemoteDOMEvent aEvent); + async Event(RemoteDOMEvent aEvent); sync SyncMessage(nsString aMessage, ClonedMessageData aData, CpowEntry[] aCpows, Principal aPrincipal) @@ -296,15 +296,15 @@ parent: * Request that the parent process move focus to the browser's frame. If * canRaise is true, the window can be raised if it is inactive. */ - RequestFocus(bool canRaise); + async RequestFocus(bool canRaise); /** * Indicate, based on the current state, that some commands are enabled and * some are disabled. */ - EnableDisableCommands(nsString action, - nsCString[] enabledCommands, - nsCString[] disabledCommands); + async EnableDisableCommands(nsString action, + nsCString[] enabledCommands, + nsCString[] disabledCommands); prio(urgent) sync GetInputContext() returns (int32_t IMEEnabled, int32_t IMEOpen); @@ -342,7 +342,7 @@ parent: * Invalidate any locally cached cursor settings and force an * update. */ - SetCursor(uint32_t value, bool force); + async SetCursor(uint32_t value, bool force); /** * Set the native cursor using a custom image. @@ -364,30 +364,30 @@ parent: * Invalidate any locally cached cursor settings and force an * update. */ - SetCustomCursor(nsCString cursorData, uint32_t width, uint32_t height, - uint32_t stride, uint8_t format, - uint32_t hotspotX, uint32_t hotspotY, bool force); + async SetCustomCursor(nsCString cursorData, uint32_t width, uint32_t height, + uint32_t stride, uint8_t format, + uint32_t hotspotX, uint32_t hotspotY, bool force); /** * Used to set the current text of the status tooltip. * Nowadays this is mainly used for link locations on hover. */ - SetStatus(uint32_t type, nsString status); + async SetStatus(uint32_t type, nsString status); /** * Show/hide a tooltip when the mouse hovers over an element in the content * document. */ - ShowTooltip(uint32_t x, uint32_t y, nsString tooltip); - HideTooltip(); + async ShowTooltip(uint32_t x, uint32_t y, nsString tooltip); + async HideTooltip(); /** * Create an asynchronous color picker on the parent side, * but don't open it yet. */ - PColorPicker(nsString title, nsString initialColor); + async PColorPicker(nsString title, nsString initialColor); - PFilePicker(nsString aTitle, int16_t aMode); + async PFilePicker(nsString aTitle, int16_t aMode); /** * Initiates an asynchronous request for one of the special indexedDB @@ -400,7 +400,7 @@ parent: * principals that can live in the content process should * provided. */ - PIndexedDBPermissionRequest(Principal principal); + async PIndexedDBPermissionRequest(Principal principal); /** * window.open from inside + + +
+
+
+ + diff --git a/dom/media/webspeech/synth/test/file_global_queue_cancel.html b/dom/media/webspeech/synth/test/file_global_queue_cancel.html new file mode 100644 index 0000000000..03b77ba2fc --- /dev/null +++ b/dom/media/webspeech/synth/test/file_global_queue_cancel.html @@ -0,0 +1,88 @@ + + + + + + Test for Bug 1188099: Calling cancel() should work correctly with global queue + + + + +Mozilla Bug 1188099 + + + +
+
+
+ + diff --git a/dom/media/webspeech/synth/test/file_global_queue_pause.html b/dom/media/webspeech/synth/test/file_global_queue_pause.html new file mode 100644 index 0000000000..7fd5621337 --- /dev/null +++ b/dom/media/webspeech/synth/test/file_global_queue_pause.html @@ -0,0 +1,131 @@ + + + + + + Test for Bug 1188099: Calling pause() should work correctly with global queue + + + + +Mozilla Bug 1188099 + + + +
+
+
+ + diff --git a/dom/media/webspeech/synth/test/file_indirect_service_events.html b/dom/media/webspeech/synth/test/file_indirect_service_events.html index a233795ab1..fb4e312444 100644 --- a/dom/media/webspeech/synth/test/file_indirect_service_events.html +++ b/dom/media/webspeech/synth/test/file_indirect_service_events.html @@ -26,66 +26,75 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1155034 /** Test for Bug 1155034 **/ -function test_with_events() { - info('test_with_events'); - var utterance = new SpeechSynthesisUtterance("never end, callback events"); - utterance.lang = 'it-IT-noend'; +function testFunc(done_cb) { + function test_with_events() { + info('test_with_events'); + var utterance = new SpeechSynthesisUtterance("never end, callback events"); + utterance.lang = 'it-IT-noend'; - utterance.addEventListener('start', function(e) { - speechSynthesis.pause(); - // Wait to see if we get some bad events we didn't expect. - }); - - utterance.addEventListener('pause', function(e) { - is(e.charIndex, 1, 'pause event charIndex matches service arguments'); - is(e.elapsedTime, 1.5, 'pause event elapsedTime matches service arguments'); - speechSynthesis.resume(); - }); - - utterance.addEventListener('resume', function(e) { - is(e.charIndex, 1, 'resume event charIndex matches service arguments'); - is(e.elapsedTime, 1.5, 'resume event elapsedTime matches service arguments'); - speechSynthesis.cancel(); - }); - - utterance.addEventListener('end', function(e) { - ok(e.charIndex, 1, 'resume event charIndex matches service arguments'); - ok(e.elapsedTime, 1.5, 'end event elapsedTime matches service arguments'); - test_no_events(); - }); - - speechSynthesis.speak(utterance); -} - -function test_no_events() { - var utterance = new SpeechSynthesisUtterance("never end"); - utterance.lang = "it-IT-noevents-noend"; - utterance.addEventListener('start', function(e) { - speechSynthesis.pause(); + utterance.addEventListener('start', function(e) { + info('start test_with_events'); + speechSynthesis.pause(); // Wait to see if we get some bad events we didn't expect. - setTimeout(function() { - SimpleTest.finish(); - }, 1000); - }); + }); - utterance.addEventListener('pause', function(e) { - ok(false, 'no pause event was explicitly dispatched from the service') - speechSynthesis.resume(); - }); + utterance.addEventListener('pause', function(e) { + is(e.charIndex, 1, 'pause event charIndex matches service arguments'); + is(e.elapsedTime, 1.5, 'pause event elapsedTime matches service arguments'); + speechSynthesis.resume(); + }); - utterance.addEventListener('resume', function(e) { - ok(false, 'no resume event was explicitly dispatched from the service') - speechSynthesis.cancel(); - }); + utterance.addEventListener('resume', function(e) { + is(e.charIndex, 1, 'resume event charIndex matches service arguments'); + is(e.elapsedTime, 1.5, 'resume event elapsedTime matches service arguments'); + speechSynthesis.cancel(); + }); - utterance.addEventListener('end', function(e) { - ok(false, 'no end event was explicitly dispatched from the service') - }); + utterance.addEventListener('end', function(e) { + ok(e.charIndex, 1, 'resume event charIndex matches service arguments'); + ok(e.elapsedTime, 1.5, 'end event elapsedTime matches service arguments'); + test_no_events(); + }); - speechSynthesis.speak(utterance); + info('start speak'); + speechSynthesis.speak(utterance); + } + + function forbiddenEvent(e) { + ok(false, 'no "' + e.type + '" event was explicitly dispatched from the service') + } + + function test_no_events() { + info('test_no_events'); + var utterance = new SpeechSynthesisUtterance("never end"); + utterance.lang = "it-IT-noevents-noend"; + utterance.addEventListener('start', function(e) { + speechSynthesis.pause(); + // Wait to see if we get some bad events we didn't expect. + setTimeout(function() { + ok(true, 'didn\'t get any unwanted events'); + utterance.removeEventListener('end', forbiddenEvent); + SpecialPowers.wrap(speechSynthesis).forceEnd(); + done_cb(); + }, 1000); + }); + + utterance.addEventListener('pause', forbiddenEvent); + utterance.addEventListener('end', forbiddenEvent); + + speechSynthesis.speak(utterance); + } + + test_with_events(); } -test_with_events(); +// Run test with no global queue, and then run it with a global queue. +testFunc(function() { + SpecialPowers.pushPrefEnv( + { set: [['media.webspeech.synth.force_global_queue', true]] }, function() { + testFunc(SimpleTest.finish) + }); +}); diff --git a/dom/media/webspeech/synth/test/file_speech_cancel.html b/dom/media/webspeech/synth/test/file_speech_cancel.html index 293dc76fb2..2ab0e1d0a8 100644 --- a/dom/media/webspeech/synth/test/file_speech_cancel.html +++ b/dom/media/webspeech/synth/test/file_speech_cancel.html @@ -26,62 +26,73 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1150315 /** Test for Bug 1150315 **/ -var gotEndEvent = false; -// A long utterance that we will interrupt. -var utterance = new SpeechSynthesisUtterance("Donec ac nunc feugiat, posuere " + - "mauris id, pharetra velit. Donec fermentum orci nunc, sit amet maximus" + - "dui tincidunt ut. Sed ultricies ac nisi a laoreet. Proin interdum," + - "libero maximus hendrerit posuere, lorem risus egestas nisl, a" + - "ultricies massa justo eu nisi. Duis mattis nibh a ligula tincidunt" + - "tincidunt non eu erat. Sed bibendum varius vulputate. Cras leo magna," + - "ornare ac posuere vel, luctus id metus. Mauris nec quam ac augue" + - "consectetur bibendum. Integer a commodo tortor. Duis semper dolor eu" + - "facilisis facilisis. Etiam venenatis turpis est, quis tincidunt velit" + - "suscipit a. Cras semper orci in sapien rhoncus bibendum. Suspendisse" + - "eu ex lobortis, finibus enim in, condimentum quam. Maecenas eget dui" + - "ipsum. Aliquam tortor leo, interdum eget congue ut, tempor id elit."); -utterance.addEventListener('start', function(e) { - ok(true, 'start utterance 1'); +function testFunc(done_cb) { + var gotEndEvent = false; + // A long utterance that we will interrupt. + var utterance = new SpeechSynthesisUtterance("Donec ac nunc feugiat, posuere " + + "mauris id, pharetra velit. Donec fermentum orci nunc, sit amet maximus" + + "dui tincidunt ut. Sed ultricies ac nisi a laoreet. Proin interdum," + + "libero maximus hendrerit posuere, lorem risus egestas nisl, a" + + "ultricies massa justo eu nisi. Duis mattis nibh a ligula tincidunt" + + "tincidunt non eu erat. Sed bibendum varius vulputate. Cras leo magna," + + "ornare ac posuere vel, luctus id metus. Mauris nec quam ac augue" + + "consectetur bibendum. Integer a commodo tortor. Duis semper dolor eu" + + "facilisis facilisis. Etiam venenatis turpis est, quis tincidunt velit" + + "suscipit a. Cras semper orci in sapien rhoncus bibendum. Suspendisse" + + "eu ex lobortis, finibus enim in, condimentum quam. Maecenas eget dui" + + "ipsum. Aliquam tortor leo, interdum eget congue ut, tempor id elit."); + utterance.addEventListener('start', function(e) { + ok(true, 'start utterance 1'); + speechSynthesis.cancel(); + info('cancel!'); + speechSynthesis.speak(utterance2); + info('speak??'); + }); + + var utterance2 = new SpeechSynthesisUtterance("Proin ornare neque vitae " + + "risus mattis rutrum. Suspendisse a velit ut est convallis aliquet." + + "Nullam ante elit, malesuada vel luctus rutrum, ultricies nec libero." + + "Praesent eu iaculis orci. Sed nisl diam, sodales ac purus et," + + "volutpat interdum tortor. Nullam aliquam porta elit et maximus. Cras" + + "risus lectus, elementum vel sodales vel, ultricies eget lectus." + + "Curabitur velit lacus, mollis vel finibus et, molestie sit amet" + + "sapien. Proin vitae dolor ac augue posuere efficitur ac scelerisque" + + "diam. Nulla sed odio elit."); + utterance2.addEventListener('start', function() { + info('start'); + speechSynthesis.cancel(); + speechSynthesis.speak(utterance3); + }); + utterance2.addEventListener('end', function(e) { + gotEndEvent = true; + }); + + var utterance3 = new SpeechSynthesisUtterance("Hello, world 3!"); + utterance3.addEventListener('start', function() { + ok(gotEndEvent, "didn't get start event for this utterance"); + }); + utterance3.addEventListener('end', done_cb); + + // Speak/cancel while paused (Bug 1187105) + speechSynthesis.pause(); + speechSynthesis.speak(new SpeechSynthesisUtterance("hello.")); + ok(speechSynthesis.pending, "paused speechSynthesis has an utterance queued."); speechSynthesis.cancel(); - speechSynthesis.speak(utterance2); -}); + ok(!speechSynthesis.pending, "paused speechSynthesis has no utterance queued."); + speechSynthesis.resume(); -var utterance2 = new SpeechSynthesisUtterance("Proin ornare neque vitae " + - "risus mattis rutrum. Suspendisse a velit ut est convallis aliquet." + - "Nullam ante elit, malesuada vel luctus rutrum, ultricies nec libero." + - "Praesent eu iaculis orci. Sed nisl diam, sodales ac purus et," + - "volutpat interdum tortor. Nullam aliquam porta elit et maximus. Cras" + - "risus lectus, elementum vel sodales vel, ultricies eget lectus." + - "Curabitur velit lacus, mollis vel finibus et, molestie sit amet" + - "sapien. Proin vitae dolor ac augue posuere efficitur ac scelerisque" + - "diam. Nulla sed odio elit."); -utterance2.addEventListener('start', function() { - speechSynthesis.cancel(); - speechSynthesis.speak(utterance3); -}); -utterance2.addEventListener('end', function(e) { - gotEndEvent = true; -}); + speechSynthesis.speak(utterance); + ok(!speechSynthesis.speaking, "speechSynthesis is not speaking yet."); + ok(speechSynthesis.pending, "speechSynthesis has an utterance queued."); +} -var utterance3 = new SpeechSynthesisUtterance("Hello, world 3!"); -utterance3.addEventListener('start', function() { - ok(gotEndEvent, "didn't get start event for this utterance"); +// Run test with no global queue, and then run it with a global queue. +testFunc(function() { + SpecialPowers.pushPrefEnv( + { set: [['media.webspeech.synth.force_global_queue', true]] }, function() { + testFunc(SimpleTest.finish) + }); }); -utterance3.addEventListener('end', function(e) { - SimpleTest.finish(); -}); - -// Speak/cancel while paused (Bug 1187105) -speechSynthesis.pause(); -speechSynthesis.speak(new SpeechSynthesisUtterance("hello.")); -ok(speechSynthesis.pending, "paused speechSynthesis has an utterance queued."); -speechSynthesis.cancel(); -ok(!speechSynthesis.pending, "paused speechSynthesis has no utterance queued."); -speechSynthesis.resume(); - -speechSynthesis.speak(utterance); -ok(!speechSynthesis.speaking, "speechSynthesis is not speaking yet."); -ok(speechSynthesis.pending, "speechSynthesis has an utterance queued."); diff --git a/dom/media/webspeech/synth/test/file_speech_error.html b/dom/media/webspeech/synth/test/file_speech_error.html new file mode 100644 index 0000000000..a80f0cbf48 --- /dev/null +++ b/dom/media/webspeech/synth/test/file_speech_error.html @@ -0,0 +1,46 @@ + + + + + + Test for Bug 1226015 + + + + +Mozilla Bug 1226015 +

+ +
+
+
+ + diff --git a/dom/media/webspeech/synth/test/file_speech_queue.html b/dom/media/webspeech/synth/test/file_speech_queue.html index a84733b851..12da780375 100644 --- a/dom/media/webspeech/synth/test/file_speech_queue.html +++ b/dom/media/webspeech/synth/test/file_speech_queue.html @@ -44,32 +44,39 @@ ok(langUriMap['en-CA'], 'No English-Canadian voice'); ok(langUriMap['fr-CA'], 'No French-Canadian voice'); ok(langUriMap['es-MX'], 'No Spanish-Mexican voice'); -synthTestQueue( - [[{text: "Hello, world."}, - { uri: langUriMap['en-JM'] }], - [{text: "Bonjour tout le monde .", lang: "fr", rate: 0.5, pitch: 0.75}, - { uri: langUriMap['fr-CA'], rate: 0.5, pitch: 0.75}], - [{text: "How are you doing?", lang: "en-GB"}, - { rate: 1, pitch: 1, uri: langUriMap['en-GB']}], - [{text: "¡hasta mañana!", lang: "es-MX"}, - { uri: langUriMap['es-MX'] }]], - function () { - var test_data = []; - var voices = speechSynthesis.getVoices(); - for (var voice of voices) { - if (voice.voiceURI.indexOf('urn:moz-tts:fake-direct') < 0) { - continue; +function testFunc(done_cb) { + synthTestQueue( + [[{text: "Hello, world."}, + { uri: langUriMap['en-JM'] }], + [{text: "Bonjour tout le monde .", + args: { lang: "fr", rate: 0.5, pitch: 0.75 }}, + { uri: langUriMap['fr-CA'], rate: 0.5, pitch: 0.75}], + [{text: "How are you doing?", args: { lang: "en-GB" } }, + { rate: 1, pitch: 1, uri: langUriMap['en-GB']}], + [{text: "¡hasta mañana!", args: { lang: "es-MX" } }, + { uri: langUriMap['es-MX'] }]], + function () { + var test_data = []; + var voices = speechSynthesis.getVoices(); + for (var voice of voices) { + if (voice.voiceURI.indexOf('urn:moz-tts:fake-direct') < 0) { + continue; + } + test_data.push([{text: "Hello world", args: { voice: voice} }, + {uri: voice.voiceURI}]); } - test_data.push([{text: "Hello world", voice: voice}, - {uri: voice.voiceURI}]); - } - synthTestQueue(test_data, - function () { - SimpleTest.finish(); - }); - }); + synthTestQueue(test_data, done_cb); + }); +} +// Run test with no global queue, and then run it with a global queue. +testFunc(function() { + SpecialPowers.pushPrefEnv( + { set: [['media.webspeech.synth.force_global_queue', true]] }, function() { + testFunc(SimpleTest.finish) + }); +}); diff --git a/dom/media/webspeech/synth/test/mochitest.ini b/dom/media/webspeech/synth/test/mochitest.ini index 7ff189dd92..5a2d480729 100644 --- a/dom/media/webspeech/synth/test/mochitest.ini +++ b/dom/media/webspeech/synth/test/mochitest.ini @@ -2,14 +2,25 @@ tags=msg support-files = common.js + file_bfcache_frame.html file_setup.html file_speech_queue.html file_speech_simple.html file_speech_cancel.html + file_speech_error.html file_indirect_service_events.html + file_global_queue.html + file_global_queue_cancel.html + file_global_queue_pause.html [test_setup.html] [test_speech_queue.html] [test_speech_simple.html] [test_speech_cancel.html] +[test_speech_error.html] [test_indirect_service_events.html] +[test_global_queue.html] +[test_global_queue_cancel.html] +[test_global_queue_pause.html] +[test_bfcache.html] +skip-if = os == 'linux' || os == 'android' # bug 1237176 diff --git a/dom/media/webspeech/synth/test/nsFakeSynthServices.cpp b/dom/media/webspeech/synth/test/nsFakeSynthServices.cpp index 9edf774904..d9e0935aa8 100644 --- a/dom/media/webspeech/synth/test/nsFakeSynthServices.cpp +++ b/dom/media/webspeech/synth/test/nsFakeSynthServices.cpp @@ -30,7 +30,8 @@ StaticRefPtr nsFakeSynthServices::sSingleton; enum VoiceFlags { eSuppressEvents = 1, - eSuppressEnd = 2 + eSuppressEnd = 2, + eFailAtStart = 4 }; struct VoiceDetails @@ -54,6 +55,7 @@ static const VoiceDetails sIndirectVoices[] = { {"urn:moz-tts:fake-indirect:zanetta", "Zanetta Farussi", "it-IT", false, 0}, {"urn:moz-tts:fake-indirect:margherita", "Margherita Durastanti", "it-IT-noevents-noend", false, eSuppressEvents | eSuppressEnd}, {"urn:moz-tts:fake-indirect:teresa", "Teresa Cornelys", "it-IT-noend", false, eSuppressEnd}, + {"urn:moz-tts:fake-indirect:cecilia", "Cecilia Bartoli", "it-IT-error", false, eFailAtStart}, }; // FakeSynthCallback @@ -238,6 +240,11 @@ FakeIndirectAudioSynth::Speak(const nsAString& aText, const nsAString& aUri, } } + if (flags & eFailAtStart) { + aTask->DispatchError(0, 0); + return NS_OK; + } + RefPtr cb = new FakeSynthCallback( (flags & eSuppressEvents) ? nullptr : aTask); diff --git a/dom/media/webspeech/synth/test/test_bfcache.html b/dom/media/webspeech/synth/test/test_bfcache.html new file mode 100644 index 0000000000..c7c147812b --- /dev/null +++ b/dom/media/webspeech/synth/test/test_bfcache.html @@ -0,0 +1,47 @@ + + + + + + Test for Bug 1230533: Test speech is stopped from a window when unloaded + + + + + +Mozilla Bug 1230533 +

+ + +
+
+
+ + diff --git a/dom/media/webspeech/synth/test/test_global_queue.html b/dom/media/webspeech/synth/test/test_global_queue.html new file mode 100644 index 0000000000..8e4093f58b --- /dev/null +++ b/dom/media/webspeech/synth/test/test_global_queue.html @@ -0,0 +1,34 @@ + + + + + + Test for Bug 1188099: Global queue should correctly schedule utterances + + + + + +Mozilla Bug 1188099 +

+ + +
+
+
+ + \ No newline at end of file diff --git a/dom/media/webspeech/synth/test/test_global_queue_cancel.html b/dom/media/webspeech/synth/test/test_global_queue_cancel.html new file mode 100644 index 0000000000..f97382f629 --- /dev/null +++ b/dom/media/webspeech/synth/test/test_global_queue_cancel.html @@ -0,0 +1,34 @@ + + + + + + Test for Bug 1188099: Calling cancel() should work correctly with global queue + + + + + +Mozilla Bug 1188099 +

+ + +
+
+
+ + \ No newline at end of file diff --git a/dom/media/webspeech/synth/test/test_global_queue_pause.html b/dom/media/webspeech/synth/test/test_global_queue_pause.html new file mode 100644 index 0000000000..341d22b58d --- /dev/null +++ b/dom/media/webspeech/synth/test/test_global_queue_pause.html @@ -0,0 +1,34 @@ + + + + + + Test for Bug 1188099: Calling pause() should work correctly with global queue + + + + + +Mozilla Bug 1188099 +

+ + +
+
+
+ + \ No newline at end of file diff --git a/dom/media/webspeech/synth/test/test_indirect_service_events.html b/dom/media/webspeech/synth/test/test_indirect_service_events.html index 7df68b2474..fe9caef982 100644 --- a/dom/media/webspeech/synth/test/test_indirect_service_events.html +++ b/dom/media/webspeech/synth/test/test_indirect_service_events.html @@ -24,8 +24,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1155034 SimpleTest.waitForExplicitFinish(); -SpecialPowers.pushPrefEnv({ set: [['media.webspeech.synth.enabled', true]] }, - function() { document.getElementById("testFrame").src = "file_indirect_service_events.html"; }); +SpecialPowers.pushPrefEnv( + { set: [['media.webspeech.synth.enabled', true], + ['media.webspeech.synth.force_global_queue', false]] }, + function() { document.getElementById("testFrame").src = "file_indirect_service_events.html"; }); + diff --git a/dom/media/webspeech/synth/test/test_speech_cancel.html b/dom/media/webspeech/synth/test/test_speech_cancel.html index c1fbac9786..0a927430b2 100644 --- a/dom/media/webspeech/synth/test/test_speech_cancel.html +++ b/dom/media/webspeech/synth/test/test_speech_cancel.html @@ -24,8 +24,10 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1150315 SimpleTest.waitForExplicitFinish(); -SpecialPowers.pushPrefEnv({ set: [['media.webspeech.synth.enabled', true]] }, - function() { document.getElementById("testFrame").src = "file_speech_cancel.html"; }); +SpecialPowers.pushPrefEnv( + { set: [['media.webspeech.synth.enabled', true], + ['media.webspeech.synth.force_global_queue', false]] }, + function() { document.getElementById("testFrame").src = "file_speech_cancel.html"; }); diff --git a/dom/media/webspeech/synth/test/test_speech_error.html b/dom/media/webspeech/synth/test/test_speech_error.html new file mode 100644 index 0000000000..3a433d8cfb --- /dev/null +++ b/dom/media/webspeech/synth/test/test_speech_error.html @@ -0,0 +1,35 @@ + + + + + + Test for Bug 1150315: Web Speech API check all classes are present + + + + + +Mozilla Bug 1226015 +

+ + +
+
+
+ + diff --git a/dom/media/webspeech/synth/test/test_speech_queue.html b/dom/media/webspeech/synth/test/test_speech_queue.html index 9f83c0f168..34fc0c2f08 100644 --- a/dom/media/webspeech/synth/test/test_speech_queue.html +++ b/dom/media/webspeech/synth/test/test_speech_queue.html @@ -24,8 +24,10 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=525444 SimpleTest.waitForExplicitFinish(); -SpecialPowers.pushPrefEnv({ set: [['media.webspeech.synth.enabled', true]] }, - function() { document.getElementById("testFrame").src = "file_speech_queue.html"; }); +SpecialPowers.pushPrefEnv( + { set: [['media.webspeech.synth.enabled', true], + ['media.webspeech.synth.force_global_queue', false]] }, + function() { document.getElementById("testFrame").src = "file_speech_queue.html"; }); diff --git a/dom/messagechannel/PMessagePort.ipdl b/dom/messagechannel/PMessagePort.ipdl index 299b00fedf..a838c685fe 100644 --- a/dom/messagechannel/PMessagePort.ipdl +++ b/dom/messagechannel/PMessagePort.ipdl @@ -44,17 +44,17 @@ protocol PMessagePort 4. Recv__delete__(); */ parent: - PostMessages(MessagePortMessage[] messages); - Disentangle(MessagePortMessage[] messages); - StopSendingData(); - Close(); + async PostMessages(MessagePortMessage[] messages); + async Disentangle(MessagePortMessage[] messages); + async StopSendingData(); + async Close(); child: - Entangled(MessagePortMessage[] messages); - ReceiveData(MessagePortMessage[] messages); - StopSendingDataConfirmed(); + async Entangled(MessagePortMessage[] messages); + async ReceiveData(MessagePortMessage[] messages); + async StopSendingDataConfirmed(); - __delete__(); + async __delete__(); }; } // namespace dom diff --git a/dom/mobileconnection/ipc/PMobileConnection.ipdl b/dom/mobileconnection/ipc/PMobileConnection.ipdl index ceaa9ad371..5be76a0834 100644 --- a/dom/mobileconnection/ipc/PMobileConnection.ipdl +++ b/dom/mobileconnection/ipc/PMobileConnection.ipdl @@ -18,29 +18,29 @@ sync protocol PMobileConnection manages PMobileConnectionRequest; child: - NotifyVoiceInfoChanged(nsMobileConnectionInfo aInfo); - NotifyDataInfoChanged(nsMobileConnectionInfo aInfo); - NotifyDataError(nsString aMessage); - NotifyCFStateChanged(uint16_t aAction, uint16_t aReason, nsString aNumber, - uint16_t aTimeSeconds, uint16_t aServiceClass); - NotifyEmergencyCbModeChanged(bool aActive, uint32_t aTimeoutMs); - NotifyOtaStatusChanged(nsString aStatus); - NotifyRadioStateChanged(int32_t aRadioState); - NotifyClirModeChanged(uint32_t aMode); - NotifyLastNetworkChanged(nsString aNetwork); - NotifyLastHomeNetworkChanged(nsString aNetwork); - NotifyNetworkSelectionModeChanged(int32_t aMode); + async NotifyVoiceInfoChanged(nsMobileConnectionInfo aInfo); + async NotifyDataInfoChanged(nsMobileConnectionInfo aInfo); + async NotifyDataError(nsString aMessage); + async NotifyCFStateChanged(uint16_t aAction, uint16_t aReason, nsString aNumber, + uint16_t aTimeSeconds, uint16_t aServiceClass); + async NotifyEmergencyCbModeChanged(bool aActive, uint32_t aTimeoutMs); + async NotifyOtaStatusChanged(nsString aStatus); + async NotifyRadioStateChanged(int32_t aRadioState); + async NotifyClirModeChanged(uint32_t aMode); + async NotifyLastNetworkChanged(nsString aNetwork); + async NotifyLastHomeNetworkChanged(nsString aNetwork); + async NotifyNetworkSelectionModeChanged(int32_t aMode); parent: /** * Send when child no longer needs to use PMobileConnection. */ - __delete__(); + async __delete__(); /** * Sent when the child makes an asynchronous request to the parent. */ - PMobileConnectionRequest(MobileConnectionRequest aRequest); + async PMobileConnectionRequest(MobileConnectionRequest aRequest); /** * Sync call only be called once per child actor for initialization. diff --git a/dom/mobileconnection/ipc/PMobileConnectionRequest.ipdl b/dom/mobileconnection/ipc/PMobileConnectionRequest.ipdl index 73c0be9c99..d2c8bdc05c 100644 --- a/dom/mobileconnection/ipc/PMobileConnectionRequest.ipdl +++ b/dom/mobileconnection/ipc/PMobileConnectionRequest.ipdl @@ -19,7 +19,7 @@ child: /** * Send when asynchronous request has completed. */ - __delete__(MobileConnectionReply aResponse); + async __delete__(MobileConnectionReply aResponse); }; /** diff --git a/dom/mobilemessage/ipc/PMobileMessageCursor.ipdl b/dom/mobilemessage/ipc/PMobileMessageCursor.ipdl index cc82fb34e6..c2141204c0 100644 --- a/dom/mobilemessage/ipc/PMobileMessageCursor.ipdl +++ b/dom/mobilemessage/ipc/PMobileMessageCursor.ipdl @@ -17,15 +17,15 @@ protocol PMobileMessageCursor manager PSms; child: - NotifyResult(MobileMessageCursorData aData); + async NotifyResult(MobileMessageCursorData aData); /** * Sent when the asynchronous cursor request has completed. */ - __delete__(int32_t aError); + async __delete__(int32_t aError); parent: - Continue(); + async Continue(); }; } // namespace mobilemessage diff --git a/dom/mobilemessage/ipc/PSms.ipdl b/dom/mobilemessage/ipc/PSms.ipdl index fc9a41b0a6..d402e1872a 100644 --- a/dom/mobilemessage/ipc/PSms.ipdl +++ b/dom/mobilemessage/ipc/PSms.ipdl @@ -111,46 +111,46 @@ sync protocol PSms { manages PMobileMessageCursor; child: - NotifyReceivedMessage(MobileMessageData aMessageData); + async NotifyReceivedMessage(MobileMessageData aMessageData); - NotifyRetrievingMessage(MobileMessageData aMessageData); + async NotifyRetrievingMessage(MobileMessageData aMessageData); - NotifySendingMessage(MobileMessageData aMessageData); + async NotifySendingMessage(MobileMessageData aMessageData); - NotifySentMessage(MobileMessageData aMessageData); + async NotifySentMessage(MobileMessageData aMessageData); - NotifyFailedMessage(MobileMessageData aMessageData); + async NotifyFailedMessage(MobileMessageData aMessageData); - NotifyDeliverySuccessMessage(MobileMessageData aMessageData); + async NotifyDeliverySuccessMessage(MobileMessageData aMessageData); - NotifyDeliveryErrorMessage(MobileMessageData aMessageData); + async NotifyDeliveryErrorMessage(MobileMessageData aMessageData); - NotifyReceivedSilentMessage(MobileMessageData aMessageData); + async NotifyReceivedSilentMessage(MobileMessageData aMessageData); - NotifyReadSuccessMessage(MobileMessageData aMessageData); + async NotifyReadSuccessMessage(MobileMessageData aMessageData); - NotifyReadErrorMessage(MobileMessageData aMessageData); + async NotifyReadErrorMessage(MobileMessageData aMessageData); - NotifyDeletedMessageInfo(DeletedMessageInfoData aDeletedInfo); + async NotifyDeletedMessageInfo(DeletedMessageInfoData aDeletedInfo); parent: /** * Sent when the child no longer needs to use sms. */ - __delete__(); + async __delete__(); /** * Sent when the child makes an asynchronous request to the parent. */ - PSmsRequest(IPCSmsRequest request); + async PSmsRequest(IPCSmsRequest request); /** * Sent when the child makes an asynchronous cursor to the parent. */ - PMobileMessageCursor(IPCMobileMessageCursor request); + async PMobileMessageCursor(IPCMobileMessageCursor request); - AddSilentNumber(nsString aNumber); - RemoveSilentNumber(nsString aNumber); + async AddSilentNumber(nsString aNumber); + async RemoveSilentNumber(nsString aNumber); }; } // namespace mobilemessage diff --git a/dom/mobilemessage/ipc/PSmsRequest.ipdl b/dom/mobilemessage/ipc/PSmsRequest.ipdl index 381ee4b432..72b611a010 100644 --- a/dom/mobilemessage/ipc/PSmsRequest.ipdl +++ b/dom/mobilemessage/ipc/PSmsRequest.ipdl @@ -22,7 +22,7 @@ child: /** * Sent when the asynchronous request has completed. */ - __delete__(MessageReply response); + async __delete__(MessageReply response); }; struct ReplyMessageSend diff --git a/dom/network/EthernetManager.js b/dom/network/EthernetManager.js new file mode 100644 index 0000000000..4b11e56666 --- /dev/null +++ b/dom/network/EthernetManager.js @@ -0,0 +1,655 @@ +/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; + +Cu.import("resource://gre/modules/Services.jsm"); +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); + +const TOPIC_INTERFACE_STATE_CHANGED = "network-interface-state-changed"; + +const ETHERNET_NETWORK_IFACE_PREFIX = "eth"; +const DEFAULT_ETHERNET_NETWORK_IFACE = "eth0"; + +const INTERFACE_IPADDR_NULL = "0.0.0.0"; +const INTERFACE_GATEWAY_NULL = "0.0.0.0"; +const INTERFACE_PREFIX_NULL = 0; +const INTERFACE_MACADDR_NULL = "00:00:00:00:00:00"; + +const NETWORK_INTERFACE_UP = "up"; +const NETWORK_INTERFACE_DOWN = "down"; + +const IP_MODE_DHCP = "dhcp"; +const IP_MODE_STATIC = "static"; + +const PREF_NETWORK_DEBUG_ENABLED = "network.debugging.enabled"; + +XPCOMUtils.defineLazyServiceGetter(this, "gNetworkManager", + "@mozilla.org/network/manager;1", + "nsINetworkManager"); + +XPCOMUtils.defineLazyServiceGetter(this, "gNetworkService", + "@mozilla.org/network/service;1", + "nsINetworkService"); + +let debug; +function updateDebug() { + let debugPref = false; // set default value here. + try { + debugPref = debugPref || Services.prefs.getBoolPref(PREF_NETWORK_DEBUG_ENABLED); + } catch (e) {} + + if (debugPref) { + debug = function(s) { + dump("-*- EthernetManager: " + s + "\n"); + }; + } else { + debug = function(s) {}; + } +} +updateDebug(); + +// nsINetworkInterface + +function EthernetInterface(attr) { + this.info.state = attr.state; + this.info.type = attr.type; + this.info.name = attr.name; + this.info.ipMode = attr.ipMode; + this.info.ips = [attr.ip]; + this.info.prefixLengths = [attr.prefixLength]; + this.info.gateways = [attr.gateway]; + this.info.dnses = attr.dnses; + this.httpProxyHost = ""; + this.httpProxyPort = 0; +} +EthernetInterface.prototype = { + QueryInterface: XPCOMUtils.generateQI([Ci.nsINetworkInterface]), + + updateConfig: function(config) { + debug("Interface " + this.info.name + " updateConfig " + JSON.stringify(config)); + this.info.state = (config.state != undefined) ? + config.state : this.info.state; + this.info.ips = (config.ip != undefined) ? [config.ip] : this.info.ips; + this.info.prefixLengths = (config.prefixLength != undefined) ? + [config.prefixLength] : this.info.prefixLengths; + this.info.gateways = (config.gateway != undefined) ? + [config.gateway] : this.info.gateways; + this.info.dnses = (config.dnses != undefined) ? config.dnses : this.info.dnses; + this.httpProxyHost = (config.httpProxyHost != undefined) ? + config.httpProxyHost : this.httpProxyHost; + this.httpProxyPort = (config.httpProxyPort != undefined) ? + config.httpProxyPort : this.httpProxyPort; + this.info.ipMode = (config.ipMode != undefined) ? + config.ipMode : this.info.ipMode; + }, + + info: { + getAddresses: function(ips, prefixLengths) { + ips.value = this.ips.slice(); + prefixLengths.value = this.prefixLengths.slice(); + + return this.ips.length; + }, + + getGateways: function(count) { + if (count) { + count.value = this.gateways.length; + } + return this.gateways.slice(); + }, + + getDnses: function(count) { + if (count) { + count.value = this.dnses.length; + } + return this.dnses.slice(); + } + } +}; + +// nsIEthernetManager + +/* + * Network state transition diagram + * + * ---------- enable --------- connect ----------- disconnect -------------- + * | Disabled | -----> | Enabled | -------> | Connected | <----------> | Disconnected | + * ---------- --------- ----------- connect -------------- + * ^ | | | + * | disable | | | + * ----------------------------------------------------------------------- + */ + +function EthernetManager() { + debug("EthernetManager start"); + + // Interface list. + this.ethernetInterfaces = {}; + + // Used to memorize last connection information. + this.lastStaticConfig = {}; + + Services.obs.addObserver(this, "xpcom-shutdown", false); +} + +EthernetManager.prototype = { + classID: Components.ID("a96441dd-36b3-4f7f-963b-2c032e28a039"), + QueryInterface: XPCOMUtils.generateQI([Ci.nsIEthernetManager]), + + ethernetInterfaces: null, + lastStaticConfig: null, + + observer: function(subject, topic, data) { + switch (topic) { + case "xpcom-shutdown": + debug("xpcom-shutdown"); + + this._shutdown(); + + Services.obs.removeObserver(this, "xpcom-shutdown"); + break; + } + }, + + _shutdown: function() { + debug("Shuting down"); + (function onRemove(ifnameList) { + if (!ifnameList.length) { + return; + } + + let ifname = ifnameList.shift(); + this.removeInterface(ifname, { notify: onRemove.bind(this, ifnameList) }); + }).call(this, Object.keys(this.ethernetInterfaces)); + }, + + get interfaceList() { + return Object.keys(this.ethernetInterfaces); + }, + + scan: function(callback) { + debug("Scan"); + + gNetworkService.getInterfaces(function(success, list) { + let ethList = []; + + if (!success) { + if (callback) { + callback.notify(ethList); + } + return; + } + + for (let i = 0; i < list.length; i++) { + debug("Found interface " + list[i]); + if (!list[i].startsWith(ETHERNET_NETWORK_IFACE_PREFIX)) { + continue; + } + ethList.push(list[i]); + } + + if (callback) { + callback.notify(ethList); + } + }); + }, + + addInterface: function(ifname, callback) { + debug("Add interface " + ifname); + + if (!ifname || !ifname.startsWith(ETHERNET_NETWORK_IFACE_PREFIX)) { + if (callback) { + callback.notify(false, "Invalid interface."); + } + return; + } + + if (this.ethernetInterfaces[ifname]) { + if (callback) { + callback.notify(true, "Interface already exists."); + } + return; + } + + gNetworkService.getInterfaceConfig(ifname, function(success, result) { + if (!success) { + if (callback) { + callback.notify(false, "Netd error."); + } + return; + } + + // Since the operation may still succeed with an invalid interface name, + // check the mac address as well. + if (result.macAddr == INTERFACE_MACADDR_NULL) { + if (callback) { + callback.notify(false, "Interface not found."); + } + return; + } + + this.ethernetInterfaces[ifname] = new EthernetInterface({ + state: result.link == NETWORK_INTERFACE_UP ? + Ci.nsINetworkInfo.NETWORK_STATE_DISABLED : + Ci.nsINetworkInfo.NETWORK_STATE_ENABLED, + name: ifname, + type: Ci.nsINetworkInfo.NETWORK_TYPE_ETHERNET, + ip: result.ip, + prefixLength: result.prefix, + ipMode: IP_MODE_DHCP + }); + + // Register the interface to NetworkManager. + gNetworkManager.registerNetworkInterface(this.ethernetInterfaces[ifname]); + + debug("Add interface " + ifname + " succeeded with " + + JSON.stringify(this.ethernetInterfaces[ifname])); + + if (callback) { + callback.notify(true, "ok"); + } + }.bind(this)); + }, + + removeInterface: function(ifname, callback) { + debug("Remove interface " + ifname); + + if (!ifname || !ifname.startsWith(ETHERNET_NETWORK_IFACE_PREFIX)) { + if (callback) { + callback.notify(false, "Invalid interface."); + } + return; + } + + if (!this.ethernetInterfaces[ifname]) { + if (callback) { + callback.notify(true, "Interface does not exist."); + } + return; + } + + // Make sure interface is disable before removing. + this.disable(ifname, { notify: function(success, message) { + // Unregister the interface from NetworkManager and also remove it from + // the interface list. + gNetworkManager.unregisterNetworkInterface(this.ethernetInterfaces[ifname]); + delete this.ethernetInterfaces[ifname]; + + debug("Remove interface " + ifname + " succeeded."); + + if (callback) { + callback.notify(true, "ok"); + } + }.bind(this)}); + }, + + updateInterfaceConfig: function(ifname, config, callback) { + debug("Update interface config with " + ifname); + + this._ensureIfname(ifname, callback, function(iface) { + if (!config) { + if (callback) { + callback.notify(false, "No config to update."); + } + return; + } + + // Network state can not be modified externally. + if (config.state) { + delete config.state; + } + + let currentIpMode = iface.info.ipMode; + + // Update config. + this.ethernetInterfaces[iface.info.name].updateConfig(config); + + // Do not automatically re-connect if the interface is not in connected + // state. + if (iface.info.state != Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED) { + if (callback) { + callback.notify(true, "ok"); + } + return; + } + + let newIpMode = this.ethernetInterfaces[iface.info.name].info.ipMode; + + if (newIpMode == IP_MODE_STATIC) { + this._setStaticIP(iface.info.name, callback); + return; + } + if ((currentIpMode == IP_MODE_STATIC) && (newIpMode == IP_MODE_DHCP)) { + gNetworkService.stopDhcp(iface.info.name, function(success) { + if (success) { + debug("DHCP for " + iface.info.name + " stopped."); + } + }); + + // Clear the current network settings before do dhcp request, otherwise + // dhcp settings could fail. + this.disconnect(iface.info.name, { notify: function(success, message) { + if (!success) { + if (callback) { + callback.notify("Disconnect failed."); + } + return; + } + this._runDhcp(iface.info.name, callback); + }.bind(this) }); + return; + } + + if (callback) { + callback.notify(true, "ok"); + } + }.bind(this)); + }, + + enable: function(ifname, callback) { + debug("Enable interface " + ifname); + + this._ensureIfname(ifname, callback, function(iface) { + // Interface can be only enabled in the state of disabled. + if (iface.info.state != Ci.nsINetworkInfo.NETWORK_STATE_DISABLED) { + if (callback) { + callback.notify(true, "Interface already enabled."); + } + return; + } + + let ips = {}; + let prefixLengths = {}; + iface.info.getAddresses(ips, prefixLengths); + let config = { ifname: iface.info.name, + ip: ips.value[0], + prefix: prefixLengths.value[0], + link: NETWORK_INTERFACE_UP }; + gNetworkService.setInterfaceConfig(config, function(success) { + if (!success) { + if (callback) { + callback.notify(false, "Netd Error."); + } + return; + } + + this.ethernetInterfaces[iface.info.name].updateConfig({ + state: Ci.nsINetworkInfo.NETWORK_STATE_ENABLED + }); + + debug("Enable interface " + iface.info.name + " succeeded."); + + if (callback) { + callback.notify(true, "ok"); + } + }.bind(this)); + }.bind(this)); + }, + + disable: function(ifname, callback) { + debug("Disable interface " + ifname); + + this._ensureIfname(ifname, callback, function(iface) { + if (iface.info.state == Ci.nsINetworkInfo.NETWORK_STATE_DISABLED) { + if (callback) { + callback.notify(true, "Interface already disabled."); + } + return; + } + + if (iface.info.state == Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED) { + gNetworkService.stopDhcp(iface.info.name, function(success) { + if (success) { + debug("DHCP for " + iface.info.name + " stopped."); + } + }); + } + + let ips = {}; + let prefixLengths = {}; + iface.info.getAddresses(ips, prefixLengths); + let config = { ifname: iface.info.name, + ip: ips.value[0], + prefix: prefixLengths.value[0], + link: NETWORK_INTERFACE_DOWN }; + gNetworkService.setInterfaceConfig(config, function(success) { + if (!success) { + if (callback) { + callback.notify(false, "Netd Error."); + } + return; + } + + this.ethernetInterfaces[iface.info.name].updateConfig({ + state: Ci.nsINetworkInfo.NETWORK_STATE_DISABLED + }); + + debug("Disable interface " + iface.info.name + " succeeded."); + + if (callback) { + callback.notify(true, "ok"); + } + }.bind(this)); + }.bind(this)); + }, + + connect: function(ifname, callback) { + debug("Connect interface " + ifname); + + this._ensureIfname(ifname, callback, function(iface) { + // Interface can only be connected in the state of enabled or + // disconnected. + if (iface.info.state == Ci.nsINetworkInfo.NETWORK_STATE_DISABLED || + iface.info.state == Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED) { + if (callback) { + callback.notify(true, "Interface " + ifname + " is not available or " + + " already connected."); + } + return; + } + + if (iface.info.ipMode == IP_MODE_DHCP) { + this._runDhcp(iface.info.name, callback); + return; + } + + if (iface.info.ipMode == IP_MODE_STATIC) { + if (this._checkConfigNull(iface) && this.lastStaticConfig[iface.info.name]) { + debug("Connect with lastStaticConfig " + + JSON.stringify(this.lastStaticConfig[iface.info.name])); + this.ethernetInterfaces[iface.info.name].updateConfig( + this.lastStaticConfig[iface.info.name]); + } + this._setStaticIP(iface.info.name, callback); + return; + } + + if (callback) { + callback.notify(false, "IP mode is wrong or not set."); + } + }.bind(this)); + }, + + disconnect: function(ifname, callback) { + debug("Disconnect interface " + ifname); + + this._ensureIfname(ifname, callback, function(iface) { + // Interface can be only disconnected in the state of connected. + if (iface.info.state != Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED) { + if (callback) { + callback.notify(true, "Interface is already disconnected"); + } + return; + } + + let config = { ifname: iface.info.name, + ip: INTERFACE_IPADDR_NULL, + prefix: INTERFACE_PREFIX_NULL, + link: NETWORK_INTERFACE_UP }; + gNetworkService.setInterfaceConfig(config, function(success) { + if (!success) { + if (callback) { + callback.notify(false, "Netd error."); + } + return; + } + + // Stop dhcp daemon. + gNetworkService.stopDhcp(iface.info.name, function(success) { + if (success) { + debug("DHCP for " + iface.info.name + " stopped."); + } + }); + + this.ethernetInterfaces[iface.info.name].updateConfig({ + state: Ci.nsINetworkInfo.NETWORK_STATE_DISCONNECTED, + ip: INTERFACE_IPADDR_NULL, + prefixLength: INTERFACE_PREFIX_NULL, + gateway: INTERFACE_GATEWAY_NULL + }); + + gNetworkManager.updateNetworkInterface(this.ethernetInterfaces[ifname]); + + debug("Disconnect interface " + iface.info.name + " succeeded."); + + if (callback) { + callback.notify(true, "ok"); + } + }.bind(this)); + }.bind(this)); + }, + + _checkConfigNull: function(iface) { + let ips = {}; + let prefixLengths = {}; + let gateways = iface.info.getGateways(); + iface.info.getAddresses(ips, prefixLengths); + + if (ips.value[0] == INTERFACE_IPADDR_NULL && + prefixLengths.value[0] == INTERFACE_PREFIX_NULL && + gateways[0] == INTERFACE_GATEWAY_NULL) { + return true; + } + + return false; + }, + + _ensureIfname: function(ifname, callback, func) { + // If no given ifname, use the default one. + if (!ifname) { + ifname = DEFAULT_ETHERNET_NETWORK_IFACE; + } + + let iface = this.ethernetInterfaces[ifname]; + if (!iface) { + if (callback) { + callback.notify(true, "Interface " + ifname + " is not available."); + } + return; + } + + func.call(this, iface); + }, + + _runDhcp: function(ifname, callback) { + debug("runDhcp with " + ifname); + + if (!this.ethernetInterfaces[ifname]) { + if (callback) { + callback.notify(false, "Invalid interface."); + } + return; + } + + gNetworkService.dhcpRequest(ifname, function(success, result) { + if (!success) { + if (callback) { + callback.notify(false, "DHCP failed."); + } + return; + } + + debug("DHCP succeeded with " + JSON.stringify(result)); + + // Clear last static network information when connecting with dhcp mode. + if (this.lastStaticConfig[ifname]) { + this.lastStaticConfig[ifname] = null; + } + + this.ethernetInterfaces[ifname].updateConfig({ + state: Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED, + ip: result.ipaddr_str, + gateway: result.gateway_str, + prefixLength: result.prefixLength, + dnses: [result.dns1_str, result.dns2_str] + }); + + gNetworkManager.updateNetworkInterface(this.ethernetInterfaces[ifname]); + + debug("Connect interface " + ifname + " with DHCP succeeded."); + + if (callback) { + callback.notify(true, "ok"); + } + }.bind(this)); + }, + + _setStaticIP: function(ifname, callback) { + let iface = this.ethernetInterfaces[ifname]; + if (!iface) { + if (callback) { + callback.notify(false, "Invalid interface."); + } + return; + } + + let ips = {}; + let prefixLengths = {}; + iface.info.getAddresses(ips, prefixLengths); + + let config = { ifname: iface.info.name, + ip: ips.value[0], + prefix: prefixLengths.value[0], + link: NETWORK_INTERFACE_UP }; + gNetworkService.setInterfaceConfig(config, function(success) { + if (!success) { + if (callback) { + callback.notify(false, "Netd Error."); + } + return; + } + + // Keep the lastest static network information. + let ips = {}; + let prefixLengths = {}; + let gateways = iface.info.getGateways(); + iface.info.getAddresses(ips, prefixLengths); + + this.lastStaticConfig[iface.info.name] = { + ip: ips.value[0], + prefixLength: prefixLengths.value[0], + gateway: gateways[0] + }; + + this.ethernetInterfaces[ifname].updateConfig({ + state: Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED, + }); + + gNetworkManager.updateNetworkInterface(this.ethernetInterfaces[ifname]); + + debug("Connect interface " + ifname + " with static ip succeeded."); + + if (callback) { + callback.notify(true, "ok"); + } + }.bind(this)); + }, +} + +this.NSGetFactory = XPCOMUtils.generateNSGetFactory([EthernetManager]); diff --git a/dom/network/EthernetManager.manifest b/dom/network/EthernetManager.manifest new file mode 100644 index 0000000000..d25a069e12 --- /dev/null +++ b/dom/network/EthernetManager.manifest @@ -0,0 +1,2 @@ +component {a96441dd-36b3-4f7f-963b-2c032e28a039} EthernetManager.js +contract @mozilla.org/ethernetManager;1 {a96441dd-36b3-4f7f-963b-2c032e28a039} diff --git a/dom/network/PTCPServerSocket.ipdl b/dom/network/PTCPServerSocket.ipdl index 70503bcc40..fc92f01467 100644 --- a/dom/network/PTCPServerSocket.ipdl +++ b/dom/network/PTCPServerSocket.ipdl @@ -19,12 +19,12 @@ protocol PTCPServerSocket manager PNecko; parent: - Close(); - RequestDelete(); + async Close(); + async RequestDelete(); child: - CallbackAccept(PTCPSocket socket); - __delete__(); + async CallbackAccept(PTCPSocket socket); + async __delete__(); }; } // namespace net diff --git a/dom/network/PTCPSocket.ipdl b/dom/network/PTCPSocket.ipdl index ced62c895c..76193ddd23 100644 --- a/dom/network/PTCPSocket.ipdl +++ b/dom/network/PTCPSocket.ipdl @@ -39,42 +39,42 @@ parent: // Forward calling to child's open() method to parent, expect TCPOptions // is expanded to |useSSL| (from TCPOptions.useSecureTransport) and // |binaryType| (from TCPOption.binaryType). - Open(nsString host, uint16_t port, bool useSSL, bool useArrayBuffers); + async Open(nsString host, uint16_t port, bool useSSL, bool useArrayBuffers); // Ask parent to open a socket and bind the newly-opened socket to a local // address specified in |localAddr| and |localPort|. - OpenBind(nsCString host, uint16_t port, - nsCString localAddr, uint16_t localPort, - bool useSSL, bool aUseArrayBuffers); + async OpenBind(nsCString host, uint16_t port, + nsCString localAddr, uint16_t localPort, + bool useSSL, bool aUseArrayBuffers); // When child's send() is called, this message requrests parent to send // data and update it's trackingNumber. - Data(SendableData data, uint32_t trackingNumber); + async Data(SendableData data, uint32_t trackingNumber); // Forward calling to child's upgradeToSecure() method to parent. - StartTLS(); + async StartTLS(); // Forward calling to child's send() method to parent. - Suspend(); + async Suspend(); // Forward calling to child's resume() method to parent. - Resume(); + async Resume(); // Forward calling to child's close() method to parent. - Close(); + async Close(); child: // Forward events that are dispatched by parent. - Callback(nsString type, CallbackData data, uint32_t readyState); + async Callback(nsString type, CallbackData data, uint32_t readyState); // Update child's bufferedAmount when parent's bufferedAmount is updated. // trackingNumber is also passed back to child to ensure the bufferedAmount // is corresponding the last call to send(). - UpdateBufferedAmount(uint32_t bufferedAmount, uint32_t trackingNumber); + async UpdateBufferedAmount(uint32_t bufferedAmount, uint32_t trackingNumber); both: - RequestDelete(); - __delete__(); + async RequestDelete(); + async __delete__(); }; diff --git a/dom/network/PUDPSocket.ipdl b/dom/network/PUDPSocket.ipdl index c187ee366a..0ead8b6ecd 100644 --- a/dom/network/PUDPSocket.ipdl +++ b/dom/network/PUDPSocket.ipdl @@ -41,25 +41,25 @@ protocol PUDPSocket manager PNecko or PBackground; parent: - Bind(UDPAddressInfo addressInfo, bool addressReuse, bool loopback); - Connect(UDPAddressInfo addressInfo); + async Bind(UDPAddressInfo addressInfo, bool addressReuse, bool loopback); + async Connect(UDPAddressInfo addressInfo); - OutgoingData(UDPData data, UDPSocketAddr addr); + async OutgoingData(UDPData data, UDPSocketAddr addr); - JoinMulticast(nsCString multicastAddress, nsCString iface); - LeaveMulticast(nsCString multicastAddress, nsCString iface); + async JoinMulticast(nsCString multicastAddress, nsCString iface); + async LeaveMulticast(nsCString multicastAddress, nsCString iface); - Close(); + async Close(); - RequestDelete(); + async RequestDelete(); child: - CallbackOpened(UDPAddressInfo addressInfo); - CallbackConnected(UDPAddressInfo addressInfo); - CallbackClosed(); - CallbackReceivedData(UDPAddressInfo addressInfo, uint8_t[] data); - CallbackError(nsCString message, nsCString filename, uint32_t lineNumber); - __delete__(); + async CallbackOpened(UDPAddressInfo addressInfo); + async CallbackConnected(UDPAddressInfo addressInfo); + async CallbackClosed(); + async CallbackReceivedData(UDPAddressInfo addressInfo, uint8_t[] data); + async CallbackError(nsCString message, nsCString filename, uint32_t lineNumber); + async __delete__(); }; diff --git a/dom/network/interfaces/moz.build b/dom/network/interfaces/moz.build index a503f951e8..4b23638405 100644 --- a/dom/network/interfaces/moz.build +++ b/dom/network/interfaces/moz.build @@ -13,6 +13,7 @@ XPIDL_SOURCES += [ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk': XPIDL_SOURCES += [ 'nsIDOMNetworkStatsManager.idl', + 'nsIEthernetManager.idl', 'nsINetworkStatsServiceProxy.idl', ] diff --git a/dom/network/interfaces/nsIEthernetManager.idl b/dom/network/interfaces/nsIEthernetManager.idl new file mode 100644 index 0000000000..2b92dc88f0 --- /dev/null +++ b/dom/network/interfaces/nsIEthernetManager.idl @@ -0,0 +1,137 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsISupports.idl" + +[scriptable, function, uuid(2a3ad56c-edc0-439f-8aae-900b331ddf49)] +interface nsIEthernetManagerCallback : nsISupports +{ + /** + * Callback function used to report the success of different operations. + * + * @param success + * Boolean value indicates the success of an operation. + * @prarm message + * Message reported in the end of operation. + */ + void notify(in boolean success, in DOMString message); +}; + +[scriptable, function, uuid(1746e7dd-92d4-43fa-8ef4-bc13d0b60353)] +interface nsIEthernetManagerScanCallback : nsISupports +{ + /** + * Callback function used to report the result of scan function. + * + * @param list + * List of available ethernet interfaces. + */ + void notify(in jsval list); +}; + +/** + * An internal idl provides control to ethernet interfaces. + */ +[scriptable, uuid(81750c87-bb3b-4724-b955-834eafa53fd1)] +interface nsIEthernetManager : nsISupports +{ + /** + * List of exisiting interface name. + */ + readonly attribute jsval interfaceList; + + /** + * Scan available ethernet interfaces on device. + * + * @param callback + * Callback function. + */ + void scan(in nsIEthernetManagerScanCallback callback); + + /** + * Add a new interface to the interface list. + * + * @param ifname + * Interface name. Should be the form of "eth*". + * @param callback + * Callback function. + */ + void addInterface(in DOMString ifname, + in nsIEthernetManagerCallback callback); + + /** + * Remove an existing interface from the interface list. + * + * @param ifname + * Interface name. + * @param Callback + * Callback function. + */ + void removeInterface(in DOMString ifname, + in nsIEthernetManagerCallback callback); + + /** + * Update a conifg of an existing interface in the interface list. + * + * @param ifname + * Interface name. + * @param config + * .ip: IP address. + * .prefixLength: Mask length. + * .gateway: Gateway. + * .dnses: DNS addresses. + * .httpProxyHost: HTTP proxy host. + * .httpProxyPort: HTTP proxy port. + * .ipMode: IP mode, can be 'dhcp' or 'static'. + * @param callback + * Callback function. + */ + void updateInterfaceConfig(in DOMString ifname, + in jsval config, + in nsIEthernetManagerCallback callback); + + /** + * Enable networking of an existing interface in the interface list. + * + * @param ifname + * Interface name. + * @param callback + * Callback function. + */ + void enable(in DOMString ifname, + in nsIEthernetManagerCallback callback); + + /** + * Disable networking of an existing interface in the interface list. + * + * @param ifname + * Interface name. + * @param callback + * Callback function. + */ + void disable(in DOMString ifname, + in nsIEthernetManagerCallback callback); + + /** + * Make an existing interface connect to network. + * + * @param ifname + * Interface name. + * @param callback + * Callback function. + */ + void connect(in DOMString ifname, + in nsIEthernetManagerCallback callback); + + /** + * Disconnect a connected interface in the interface list. + * + * @param ifname + * Interface name. + * @param callback + * Callback function. + */ + void disconnect(in DOMString ifname, + in nsIEthernetManagerCallback callback); +}; diff --git a/dom/network/moz.build b/dom/network/moz.build index b42c30734f..6a3488d4b8 100644 --- a/dom/network/moz.build +++ b/dom/network/moz.build @@ -51,6 +51,8 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk': if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk': EXTRA_COMPONENTS += [ + 'EthernetManager.js', + 'EthernetManager.manifest', 'NetworkStatsManager.js', 'NetworkStatsManager.manifest', 'NetworkStatsServiceProxy.js', diff --git a/dom/network/tests/marionette/head.js b/dom/network/tests/marionette/head.js new file mode 100644 index 0000000000..edbf2dd853 --- /dev/null +++ b/dom/network/tests/marionette/head.js @@ -0,0 +1,552 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +let Promise = SpecialPowers.Cu.import("resource://gre/modules/Promise.jsm").Promise; + +const ETHERNET_MANAGER_CONTRACT_ID = "@mozilla.org/ethernetManager;1"; + +const INTERFACE_UP = "UP"; +const INTERFACE_DOWN = "DOWN"; + +let gTestSuite = (function() { + let suite = {}; + + // Private member variables of the returned object |suite|. + let ethernetManager = SpecialPowers.Cc[ETHERNET_MANAGER_CONTRACT_ID] + .getService(SpecialPowers.Ci.nsIEthernetManager); + let pendingEmulatorShellCount = 0; + + /** + * Send emulator shell command with safe guard. + * + * We should only call |finish()| after all emulator command transactions + * end, so here comes with the pending counter. Resolve when the emulator + * gives positive response, and reject otherwise. + * + * Fulfill params: an array of emulator response lines. + * Reject params: an array of emulator response lines. + * + * @param command + * A string command to be passed to emulator through its telnet console. + * + * @return A deferred promise. + */ + function runEmulatorShellSafe(command) { + let deferred = Promise.defer(); + + ++pendingEmulatorShellCount; + runEmulatorShell(command, function(aResult) { + --pendingEmulatorShellCount; + + ok(true, "Emulator shell response: " + JSON.stringify(aResult)); + if (Array.isArray(aResult)) { + deferred.resolve(aResult); + } else { + deferred.reject(aResult); + } + }); + + return deferred.promise; + } + + /** + * Get the system network conifg by the given interface name. + * + * Use shell command 'netcfg' to get the list of network cofig. + * + * Fulfill params: An object of { name, flag, ip } + * + * @parm ifname + * Interface name. + * + * @return A deferred promise. + */ + function getNetworkConfig(ifname) { + return runEmulatorShellSafe(['netcfg']) + .then(result => { + // Sample 'netcfg' output: + // + // lo UP 127.0.0.1/8 0x00000049 00:00:00:00:00:00 + // eth0 UP 10.0.2.15/24 0x00001043 52:54:00:12:34:56 + // eth1 DOWN 0.0.0.0/0 0x00001002 52:54:00:12:34:57 + // rmnet1 DOWN 0.0.0.0/0 0x00001002 52:54:00:12:34:59 + + let config; + + for (let i = 0; i < result.length; i++) { + let tokens = result[i].split(/\s+/); + let name = tokens[0]; + let flag = tokens[1]; + let ip = tokens[2].split(/\/+/)[0]; + if (name == ifname) { + config = { name: name, flag: flag, ip: ip }; + break; + } + } + + return config; + }); + } + + /** + * Get the ip assigned by dhcp server of a given interface name. + * + * Get the ip from android property 'dhcp.[ifname].ipaddress'. + * + * Fulfill params: A string of ip address. + * + * @parm ifname + * Interface name. + * + * @return A deferred promise. + */ + function getDhcpIpAddr(ifname) { + return runEmulatorShellSafe(['getprop', 'dhcp.' + ifname + '.ipaddress']) + .then(function(ipAddr) { + return ipAddr[0]; + }); + } + + /** + * Get the gateway assigned by dhcp server of a given interface name. + * + * Get the ip from android property 'dhcp.[ifname].gateway'. + * + * Fulfill params: A string of gateway. + * + * @parm ifname + * Interface name. + * + * @return A deferred promise. + */ + function getDhcpGateway(ifname) { + return runEmulatorShellSafe(['getprop', 'dhcp.' + ifname + '.gateway']) + .then(function(gateway) { + return gateway[0]; + }); + } + + /** + * Get the default route. + * + * Use shell command 'ip route' to get the default of device. + * + * Fulfill params: An array of { name, gateway } + * + * @return A deferred promise. + */ + function getDefaultRoute() { + return runEmulatorShellSafe(['ip', 'route']) + .then(result => { + // Sample 'ip route' output: + // + // 10.0.2.0/24 dev eth0 proto kernel scope link src 10.0.2.15 + // default via 10.0.2.2 dev eth0 metric 2 + + let routeInfo = []; + + for (let i = 0; i < result.length; i++) { + if (!result[i].match('default')) { + continue; + } + + let tokens = result[i].split(/\s+/); + let name = tokens[4]; + let gateway = tokens[2]; + routeInfo.push({ name: name, gateway: gateway }); + } + + return routeInfo; + }); + } + + /** + * Check a specific interface is enabled or not. + * + * @parm ifname + * Interface name. + * @parm enabled + * A boolean value used to check interface is disable or not. + * + * @return A deferred promise. + */ + function checkInterfaceIsEnabled(ifname, enabled) { + return getNetworkConfig(ifname) + .then(function(config) { + if (enabled) { + is(config.flag, INTERFACE_UP, "Interface is enabled as expected."); + } else { + is(config.flag, INTERFACE_DOWN, "Interface is disabled as expected."); + } + }); + } + + /** + * Check the ip of a specific interface is equal to given ip or not. + * + * @parm ifname + * Interface name. + * @parm ip + * Given ip address. + * + * @return A deferred promise. + */ + function checkInterfaceIpAddr(ifname, ip) { + return getNetworkConfig(ifname) + .then(function(config) { + is(config.ip, ip, "IP is right as expected."); + }); + } + + /** + * Check the default gateway of a specific interface is equal to given gateway + * or not. + * + * @parm ifname + * Interface name. + * @parm gateway + * Given gateway. + * + * @return A deferred promise. + */ + function checkDefaultRoute(ifname, gateway) { + return getDefaultRoute() + .then(function(routeInfo) { + for (let i = 0; i < routeInfo.length; i++) { + if (routeInfo[i].name == ifname) { + is(routeInfo[i].gateway, gateway, + "Default gateway is right as expected."); + return true; + } + } + + if (!gateway) { + ok(true, "Default route is cleared."); + return true; + } + + // TODO: should we ok(false, ......) here? + return false; + }); + } + + /** + * Check the length of interface list in EthernetManager is equal to given + * length or not. + * + * @parm length + * Given length. + */ + function checkInterfaceListLength(length) { + let list = ethernetManager.interfaceList; + is(length, list.length, "List length is equal as expected."); + } + + /** + * Check the given interface exists on device or not. + * + * @parm ifname + * Interface name. + * + * @return A deferred promise. + */ + function checkInterfaceExist(ifname) { + return scanInterfaces() + .then(list => { + let index = list.indexOf(ifname); + if (index < 0) { + throw "Interface " + ifname + " not found."; + } + + ok(true, ifname + " exists."); + }); + } + + /** + * Scan for available ethernet interfaces. + * + * Fulfill params: A list of available interfaces found in device. + * + * @return A deferred promise. + */ + function scanInterfaces() { + let deferred = Promise.defer(); + + ethernetManager.scan(function onScan(list) { + deferred.resolve(list); + }); + + return deferred.promise; + } + + /** + * Add an interface into interface list. + * + * Fulfill params: A boolean value indicates success or not. + * + * @param ifname + * Interface name. + * + * @return A deferred promise. + */ + function addInterface(ifname) { + let deferred = Promise.defer(); + + ethernetManager.addInterface(ifname, function onAdd(success, message) { + ok(success, "Add interface " + ifname + " succeeded."); + is(message, "ok", "Message is as expected."); + + deferred.resolve(success); + }); + + return deferred.promise; + } + + /** + * Remove an interface form the interface list. + * + * Fulfill params: A boolean value indicates success or not. + * + * @param ifname + * Interface name. + * + * @return A deferred promise. + */ + function removeInterface(ifname) { + let deferred = Promise.defer(); + + ethernetManager.removeInterface(ifname, function onRemove(success, message) { + ok(success, "Remove interface " + ifname + " succeeded."); + is(message, "ok", "Message is as expected."); + + deferred.resolve(success); + }); + + return deferred.promise; + } + + /** + * Enable networking of an interface in the interface list. + * + * Fulfill params: A boolean value indicates success or not. + * + * @param ifname + * Interface name. + * + * @return A deferred promise. + */ + function enableInterface(ifname) { + let deferred = Promise.defer(); + + ethernetManager.enable(ifname, function onEnable(success, message) { + ok(success, "Enable interface " + ifname + " succeeded."); + is(message, "ok", "Message is as expected."); + + deferred.resolve(success); + }); + + return deferred.promise; + } + + /** + * Disable networking of an interface in the interface list. + * + * Fulfill params: A boolean value indicates success or not. + * + * @param ifname + * Interface name. + * + * @return A deferred promise. + */ + function disableInterface(ifname) { + let deferred = Promise.defer(); + + ethernetManager.disable(ifname, function onDisable(success, message) { + ok(success, "Disable interface " + ifname + " succeeded."); + is(message, "ok", "Message is as expected."); + + deferred.resolve(success); + }); + + return deferred.promise; + } + + /** + * Make an interface connect to network. + * + * Fulfill params: A boolean value indicates success or not. + * + * @param ifname + * Interface name. + * + * @return A deferred promise. + */ + function makeInterfaceConnect(ifname) { + let deferred = Promise.defer(); + + ethernetManager.connect(ifname, function onConnect(success, message) { + ok(success, "Interface " + ifname + " is connected successfully."); + is(message, "ok", "Message is as expected."); + + deferred.resolve(success); + }); + + return deferred.promise; + } + + /** + * Make an interface disconnect to network. + * + * Fulfill params: A boolean value indicates success or not. + * + * @param ifname + * Interface name. + * + * @return A deferred promise. + */ + function makeInterfaceDisconnect(ifname) { + let deferred = Promise.defer(); + + ethernetManager.disconnect(ifname, function onDisconnect(success, message) { + ok(success, "Interface " + ifname + " is disconnected successfully."); + is(message, "ok", "Message is as expected."); + + deferred.resolve(success); + }); + + return deferred.promise; + } + + /** + * Update the config the an interface in the interface list. + * + * @param ifname + * Interface name. + * @param config + * .ip: ip address. + * .prefixLength: mask length. + * .gateway: gateway. + * .dnses: dnses. + * .httpProxyHost: http proxy host. + * .httpProxyPort: http porxy port. + * .usingDhcp: an boolean value indicates using dhcp or not. + * + * @return A deferred promise. + */ + function updateInterfaceConfig(ifname, config) { + let deferred = Promise.defer(); + + ethernetManager.updateInterfaceConfig(ifname, config, + function onUpdated(success, message) { + ok(success, "Interface " + ifname + " config is updated successfully " + + "with " + JSON.stringify(config)); + is(message, "ok", "Message is as expected."); + + deferred.resolve(success); + }); + + return deferred.promise; + } + + /** + * Wait for timeout. + * + * @param timeout + * Time in ms. + * + * @return A deferred promise. + */ + function waitForTimeout(timeout) { + let deferred = Promise.defer(); + + setTimeout(function() { + ok(true, "waitForTimeout " + timeout); + deferred.resolve(); + }, timeout); + + return deferred.promise; + } + + /** + * Wait for default route of a specific interface being set and + * check. + * + * @param ifname + * Interface name. + * @param gateway + * Target gateway. + * + * @return A deferred promise. + */ + function waitForDefaultRouteSet(ifname, gateway) { + return gTestSuite.waitForTimeout(500) + .then(() => gTestSuite.checkDefaultRoute(ifname, gateway)) + .then(success => { + if (success) { + ok(true, "Default route is set as expected." + gateway); + return; + } + + ok(true, "Default route is not set yet, check again. " + success); + return waitForDefaultRouteSet(ifname, gateway); + }); + } + + //--------------------------------------------------- + // Public test suite functions + //--------------------------------------------------- + suite.scanInterfaces = scanInterfaces; + suite.addInterface = addInterface; + suite.removeInterface = removeInterface; + suite.enableInterface = enableInterface; + suite.disableInterface = disableInterface; + suite.makeInterfaceConnect = makeInterfaceConnect; + suite.makeInterfaceDisconnect = makeInterfaceDisconnect; + suite.updateInterfaceConfig = updateInterfaceConfig; + suite.getDhcpIpAddr = getDhcpIpAddr; + suite.getDhcpGateway = getDhcpGateway; + suite.checkInterfaceExist = checkInterfaceExist; + suite.checkInterfaceIsEnabled = checkInterfaceIsEnabled; + suite.checkInterfaceIpAddr = checkInterfaceIpAddr; + suite.checkDefaultRoute = checkDefaultRoute; + suite.checkInterfaceListLength = checkInterfaceListLength; + suite.waitForTimeout = waitForTimeout; + suite.waitForDefaultRouteSet = waitForDefaultRouteSet; + + /** + * End up the test run. + * + * Wait until all pending emulator shell commands are done and then |finish| + * will be called in the end. + */ + function cleanUp() { + waitFor(finish, function() { + return pendingEmulatorShellCount === 0; + }); + } + + /** + * Common test routine. + * + * Start a test with the given test case chain. The test environment will be + * settled down before the test. After the test, all the affected things will + * be restored. + * + * @param aTestCaseChain + * The test case entry point, which can be a function or a promise. + * + * @return A deferred promise. + */ + suite.doTest = function(aTestCaseChain) { + return Promise.resolve() + .then(aTestCaseChain) + .then(function onresolve() { + cleanUp(); + }, function onreject(aReason) { + ok(false, 'Promise rejects during test' + (aReason ? '(' + aReason + ')' : '')); + cleanUp(); + }); + }; + + return suite; +})(); diff --git a/dom/network/tests/marionette/manifest.ini b/dom/network/tests/marionette/manifest.ini new file mode 100644 index 0000000000..2273a34b30 --- /dev/null +++ b/dom/network/tests/marionette/manifest.ini @@ -0,0 +1,15 @@ +[DEFAULT] +b2g = true +browser = false +qemu = true + +[test_ethernet_add_interface.js] +[test_ethernet_remove_interface.js] +[test_ethernet_enable.js] +[test_ethernet_disable.js] +[test_ethernet_connect_with_dhcp.js] +[test_ethernet_connect_with_static_ip.js] +[test_ethernet_reconnect_with_dhcp.js] +[test_ethernet_reconnect_with_static_ip.js] +[test_ethernet_ip_mode_change.js] +[test_ethernet_disconnect.js] diff --git a/dom/network/tests/marionette/test_ethernet_add_interface.js b/dom/network/tests/marionette/test_ethernet_add_interface.js new file mode 100644 index 0000000000..d628e77054 --- /dev/null +++ b/dom/network/tests/marionette/test_ethernet_add_interface.js @@ -0,0 +1,16 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +MARIONETTE_TIMEOUT = 60000; +MARIONETTE_HEAD_JS = 'head.js'; + +const ETHERNET_INTERFACE_NAME = "eth1"; + +gTestSuite.doTest(function() { + return Promise.resolve() + .then(() => gTestSuite.checkInterfaceExist(ETHERNET_INTERFACE_NAME)) + .then(() => gTestSuite.checkInterfaceListLength(0)) + .then(() => gTestSuite.addInterface(ETHERNET_INTERFACE_NAME)) + .then(() => gTestSuite.checkInterfaceListLength(1)) + .then(() => gTestSuite.removeInterface(ETHERNET_INTERFACE_NAME)); +}); \ No newline at end of file diff --git a/dom/network/tests/marionette/test_ethernet_connect_with_dhcp.js b/dom/network/tests/marionette/test_ethernet_connect_with_dhcp.js new file mode 100644 index 0000000000..57c2df9c2e --- /dev/null +++ b/dom/network/tests/marionette/test_ethernet_connect_with_dhcp.js @@ -0,0 +1,26 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +MARIONETTE_TIMEOUT = 60000; +MARIONETTE_HEAD_JS = 'head.js'; + +const ETHERNET_INTERFACE_NAME = "eth1"; + +function checkDhcpResult(ifname) { + return gTestSuite.getDhcpIpAddr(ifname) + .then(ip => gTestSuite.checkInterfaceIpAddr(ifname, ip)) + .then(() => gTestSuite.getDhcpGateway(ifname)) + .then(gateway => gTestSuite.waitForDefaultRouteSet(ifname, gateway)); +} + +gTestSuite.doTest(function() { + return Promise.resolve() + .then(() => gTestSuite.checkInterfaceExist(ETHERNET_INTERFACE_NAME)) + .then(() => gTestSuite.addInterface(ETHERNET_INTERFACE_NAME)) + .then(() => gTestSuite.enableInterface(ETHERNET_INTERFACE_NAME)) + .then(() => gTestSuite.makeInterfaceConnect(ETHERNET_INTERFACE_NAME)) + .then(() => checkDhcpResult(ETHERNET_INTERFACE_NAME)) + .then(() => gTestSuite.makeInterfaceDisconnect(ETHERNET_INTERFACE_NAME)) + .then(() => gTestSuite.disableInterface(ETHERNET_INTERFACE_NAME)) + .then(() => gTestSuite.removeInterface(ETHERNET_INTERFACE_NAME)); +}); \ No newline at end of file diff --git a/dom/network/tests/marionette/test_ethernet_connect_with_static_ip.js b/dom/network/tests/marionette/test_ethernet_connect_with_static_ip.js new file mode 100644 index 0000000000..3adc37b23c --- /dev/null +++ b/dom/network/tests/marionette/test_ethernet_connect_with_static_ip.js @@ -0,0 +1,33 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +MARIONETTE_TIMEOUT = 60000; +MARIONETTE_HEAD_JS = 'head.js'; + +const ETHERNET_INTERFACE_NAME = "eth1"; + +let staticConfig = { + ip: "1.2.3.4", + gateway: "1.2.3.5", + prefixLength: 24, + dnses: ["1.2.3.6"], + ipMode: "static" +}; + +function checkStaticResult(ifname) { + return gTestSuite.checkInterfaceIpAddr(ifname, staticConfig.ip) + .then(() => gTestSuite.checkDefaultRoute(ifname, staticConfig.gateway)); +} + +gTestSuite.doTest(function() { + return Promise.resolve() + .then(() => gTestSuite.checkInterfaceExist(ETHERNET_INTERFACE_NAME)) + .then(() => gTestSuite.addInterface(ETHERNET_INTERFACE_NAME)) + .then(() => gTestSuite.enableInterface(ETHERNET_INTERFACE_NAME)) + .then(() => gTestSuite.updateInterfaceConfig(ETHERNET_INTERFACE_NAME, staticConfig)) + .then(() => gTestSuite.makeInterfaceConnect(ETHERNET_INTERFACE_NAME)) + .then(() => checkStaticResult(ETHERNET_INTERFACE_NAME)) + .then(() => gTestSuite.makeInterfaceDisconnect(ETHERNET_INTERFACE_NAME)) + .then(() => gTestSuite.disableInterface(ETHERNET_INTERFACE_NAME)) + .then(() => gTestSuite.removeInterface(ETHERNET_INTERFACE_NAME)); +}); \ No newline at end of file diff --git a/dom/network/tests/marionette/test_ethernet_disable.js b/dom/network/tests/marionette/test_ethernet_disable.js new file mode 100644 index 0000000000..9c3525faa3 --- /dev/null +++ b/dom/network/tests/marionette/test_ethernet_disable.js @@ -0,0 +1,17 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +MARIONETTE_TIMEOUT = 60000; +MARIONETTE_HEAD_JS = 'head.js'; + +const ETHERNET_INTERFACE_NAME = "eth1"; + +gTestSuite.doTest(function() { + return Promise.resolve() + .then(() => gTestSuite.checkInterfaceExist(ETHERNET_INTERFACE_NAME)) + .then(() => gTestSuite.addInterface(ETHERNET_INTERFACE_NAME)) + .then(() => gTestSuite.enableInterface(ETHERNET_INTERFACE_NAME)) + .then(() => gTestSuite.disableInterface(ETHERNET_INTERFACE_NAME)) + .then(() => gTestSuite.checkInterfaceIsEnabled(ETHERNET_INTERFACE_NAME, false)) + .then(() => gTestSuite.removeInterface(ETHERNET_INTERFACE_NAME)); +}); \ No newline at end of file diff --git a/dom/network/tests/marionette/test_ethernet_disconnect.js b/dom/network/tests/marionette/test_ethernet_disconnect.js new file mode 100644 index 0000000000..73f6aa3c5e --- /dev/null +++ b/dom/network/tests/marionette/test_ethernet_disconnect.js @@ -0,0 +1,25 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +MARIONETTE_TIMEOUT = 60000; +MARIONETTE_HEAD_JS = 'head.js'; + +const ETHERNET_INTERFACE_NAME = "eth1"; +const INTERFACE_IP_NONE = "0.0.0.0"; + +function checkIpAddrIsReset(ifname) { + return gTestSuite.checkInterfaceIpAddr(ifname, INTERFACE_IP_NONE) + .then(() => gTestSuite.checkDefaultRoute(ifname)); +} + +gTestSuite.doTest(function() { + return Promise.resolve() + .then(() => gTestSuite.checkInterfaceExist(ETHERNET_INTERFACE_NAME)) + .then(() => gTestSuite.addInterface(ETHERNET_INTERFACE_NAME)) + .then(() => gTestSuite.enableInterface(ETHERNET_INTERFACE_NAME)) + .then(() => gTestSuite.makeInterfaceConnect(ETHERNET_INTERFACE_NAME)) + .then(() => gTestSuite.makeInterfaceDisconnect(ETHERNET_INTERFACE_NAME)) + .then(() => checkIpAddrIsReset(ETHERNET_INTERFACE_NAME)) + .then(() => gTestSuite.disableInterface(ETHERNET_INTERFACE_NAME)) + .then(() => gTestSuite.removeInterface(ETHERNET_INTERFACE_NAME)); +}); \ No newline at end of file diff --git a/dom/network/tests/marionette/test_ethernet_enable.js b/dom/network/tests/marionette/test_ethernet_enable.js new file mode 100644 index 0000000000..f5578a44f8 --- /dev/null +++ b/dom/network/tests/marionette/test_ethernet_enable.js @@ -0,0 +1,17 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +MARIONETTE_TIMEOUT = 60000; +MARIONETTE_HEAD_JS = 'head.js'; + +const ETHERNET_INTERFACE_NAME = "eth1"; + +gTestSuite.doTest(function() { + return Promise.resolve() + .then(() => gTestSuite.checkInterfaceExist(ETHERNET_INTERFACE_NAME)) + .then(() => gTestSuite.addInterface(ETHERNET_INTERFACE_NAME)) + .then(() => gTestSuite.enableInterface(ETHERNET_INTERFACE_NAME)) + .then(() => gTestSuite.checkInterfaceIsEnabled(ETHERNET_INTERFACE_NAME, true)) + .then(() => gTestSuite.disableInterface(ETHERNET_INTERFACE_NAME)) + .then(() => gTestSuite.removeInterface(ETHERNET_INTERFACE_NAME)); +}); \ No newline at end of file diff --git a/dom/network/tests/marionette/test_ethernet_ip_mode_change.js b/dom/network/tests/marionette/test_ethernet_ip_mode_change.js new file mode 100644 index 0000000000..5db2049bef --- /dev/null +++ b/dom/network/tests/marionette/test_ethernet_ip_mode_change.js @@ -0,0 +1,43 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +MARIONETTE_TIMEOUT = 60000; +MARIONETTE_HEAD_JS = 'head.js'; + +const ETHERNET_INTERFACE_NAME = "eth1"; + +let staticConfig = { + ip: "1.2.3.4", + gateway: "1.2.3.5", + prefixLength: 24, + dnses: ["1.2.3.6"], + ipMode: "static" +}; + +function checkStaticResult(ifname) { + return gTestSuite.checkInterfaceIpAddr(ifname, staticConfig.ip) + .then(() => gTestSuite.waitForDefaultRouteSet(ifname, staticConfig.gateway)); +} + +function checkDhcpResult(ifname) { + return gTestSuite.getDhcpIpAddr(ifname) + .then(ip => gTestSuite.checkInterfaceIpAddr(ifname, ip)) + .then(() => gTestSuite.getDhcpGateway(ifname)) + .then(gateway => gTestSuite.waitForDefaultRouteSet(ifname, gateway)); +} + +gTestSuite.doTest(function() { + return Promise.resolve() + .then(() => gTestSuite.checkInterfaceExist(ETHERNET_INTERFACE_NAME)) + .then(() => gTestSuite.addInterface(ETHERNET_INTERFACE_NAME)) + .then(() => gTestSuite.enableInterface(ETHERNET_INTERFACE_NAME)) + .then(() => gTestSuite.makeInterfaceConnect(ETHERNET_INTERFACE_NAME)) + .then(() => checkDhcpResult(ETHERNET_INTERFACE_NAME)) + .then(() => gTestSuite.updateInterfaceConfig(ETHERNET_INTERFACE_NAME, staticConfig)) + .then(() => checkStaticResult(ETHERNET_INTERFACE_NAME)) + .then(() => gTestSuite.updateInterfaceConfig(ETHERNET_INTERFACE_NAME, { ipMode: "dhcp"})) + .then(() => checkDhcpResult(ETHERNET_INTERFACE_NAME)) + .then(() => gTestSuite.makeInterfaceDisconnect(ETHERNET_INTERFACE_NAME)) + .then(() => gTestSuite.disableInterface(ETHERNET_INTERFACE_NAME)) + .then(() => gTestSuite.removeInterface(ETHERNET_INTERFACE_NAME)); +}); \ No newline at end of file diff --git a/dom/network/tests/marionette/test_ethernet_reconnect_with_dhcp.js b/dom/network/tests/marionette/test_ethernet_reconnect_with_dhcp.js new file mode 100644 index 0000000000..96719c1526 --- /dev/null +++ b/dom/network/tests/marionette/test_ethernet_reconnect_with_dhcp.js @@ -0,0 +1,29 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +MARIONETTE_TIMEOUT = 60000; +MARIONETTE_HEAD_JS = 'head.js'; + +const ETHERNET_INTERFACE_NAME = "eth1"; + +function checkDhcpResult(ifname) { + return gTestSuite.getDhcpIpAddr(ifname) + .then(ip => gTestSuite.checkInterfaceIpAddr(ifname, ip)) + .then(() => gTestSuite.getDhcpGateway(ifname)) + .then(gateway => gTestSuite.waitForDefaultRouteSet(ifname, gateway)); +} + +gTestSuite.doTest(function() { + return Promise.resolve() + .then(() => gTestSuite.checkInterfaceExist(ETHERNET_INTERFACE_NAME)) + .then(() => gTestSuite.addInterface(ETHERNET_INTERFACE_NAME)) + .then(() => gTestSuite.enableInterface(ETHERNET_INTERFACE_NAME)) + .then(() => gTestSuite.makeInterfaceConnect(ETHERNET_INTERFACE_NAME)) + .then(() => checkDhcpResult(ETHERNET_INTERFACE_NAME)) + .then(() => gTestSuite.makeInterfaceDisconnect(ETHERNET_INTERFACE_NAME)) + .then(() => gTestSuite.makeInterfaceConnect(ETHERNET_INTERFACE_NAME)) + .then(() => checkDhcpResult(ETHERNET_INTERFACE_NAME)) + .then(() => gTestSuite.makeInterfaceDisconnect(ETHERNET_INTERFACE_NAME)) + .then(() => gTestSuite.disableInterface(ETHERNET_INTERFACE_NAME)) + .then(() => gTestSuite.removeInterface(ETHERNET_INTERFACE_NAME)); +}); diff --git a/dom/network/tests/marionette/test_ethernet_reconnect_with_static_ip.js b/dom/network/tests/marionette/test_ethernet_reconnect_with_static_ip.js new file mode 100644 index 0000000000..91f25a4710 --- /dev/null +++ b/dom/network/tests/marionette/test_ethernet_reconnect_with_static_ip.js @@ -0,0 +1,36 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +MARIONETTE_TIMEOUT = 60000; +MARIONETTE_HEAD_JS = 'head.js'; + +const ETHERNET_INTERFACE_NAME = "eth1"; + +let staticConfig = { + ip: "1.2.3.4", + gateway: "1.2.3.5", + prefixLength: 24, + dnses: ["1.2.3.6"], + ipMode: "static" +}; + +function checkStaticResult(ifname) { + return gTestSuite.checkInterfaceIpAddr(ifname, staticConfig.ip) + .then(() => gTestSuite.checkDefaultRoute(ifname, staticConfig.gateway)); +} + +gTestSuite.doTest(function() { + return Promise.resolve() + .then(() => gTestSuite.checkInterfaceExist(ETHERNET_INTERFACE_NAME)) + .then(() => gTestSuite.addInterface(ETHERNET_INTERFACE_NAME)) + .then(() => gTestSuite.enableInterface(ETHERNET_INTERFACE_NAME)) + .then(() => gTestSuite.updateInterfaceConfig(ETHERNET_INTERFACE_NAME, staticConfig)) + .then(() => gTestSuite.makeInterfaceConnect(ETHERNET_INTERFACE_NAME)) + .then(() => checkStaticResult(ETHERNET_INTERFACE_NAME)) + .then(() => gTestSuite.makeInterfaceDisconnect(ETHERNET_INTERFACE_NAME)) + .then(() => gTestSuite.makeInterfaceConnect(ETHERNET_INTERFACE_NAME)) + .then(() => checkStaticResult(ETHERNET_INTERFACE_NAME)) + .then(() => gTestSuite.makeInterfaceDisconnect(ETHERNET_INTERFACE_NAME)) + .then(() => gTestSuite.disableInterface(ETHERNET_INTERFACE_NAME)) + .then(() => gTestSuite.removeInterface(ETHERNET_INTERFACE_NAME)); +}); \ No newline at end of file diff --git a/dom/network/tests/marionette/test_ethernet_remove_interface.js b/dom/network/tests/marionette/test_ethernet_remove_interface.js new file mode 100644 index 0000000000..c7fb0e81b8 --- /dev/null +++ b/dom/network/tests/marionette/test_ethernet_remove_interface.js @@ -0,0 +1,16 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +MARIONETTE_TIMEOUT = 60000; +MARIONETTE_HEAD_JS = 'head.js'; + +const ETHERNET_INTERFACE_NAME = "eth1"; + +gTestSuite.doTest(function() { + return Promise.resolve() + .then(() => gTestSuite.checkInterfaceExist(ETHERNET_INTERFACE_NAME)) + .then(() => gTestSuite.addInterface(ETHERNET_INTERFACE_NAME)) + .then(() => gTestSuite.checkInterfaceListLength(1)) + .then(() => gTestSuite.removeInterface(ETHERNET_INTERFACE_NAME)) + .then(() => gTestSuite.checkInterfaceListLength(0)); +}); \ No newline at end of file diff --git a/dom/plugins/ipc/PPluginBackgroundDestroyer.ipdl b/dom/plugins/ipc/PPluginBackgroundDestroyer.ipdl index cbab923235..cc8ff558e0 100644 --- a/dom/plugins/ipc/PPluginBackgroundDestroyer.ipdl +++ b/dom/plugins/ipc/PPluginBackgroundDestroyer.ipdl @@ -27,7 +27,7 @@ protocol PPluginBackgroundDestroyer { // notification that that the background is stale. parent: - __delete__(); + async __delete__(); state DESTROYING: recv __delete__; diff --git a/dom/presentation/ipc/PPresentation.ipdl b/dom/presentation/ipc/PPresentation.ipdl index 94a0714122..3ac6b729c5 100644 --- a/dom/presentation/ipc/PPresentation.ipdl +++ b/dom/presentation/ipc/PPresentation.ipdl @@ -49,26 +49,26 @@ sync protocol PPresentation manages PPresentationRequest; child: - NotifyAvailableChange(bool aAvailable); - NotifySessionStateChange(nsString aSessionId, uint16_t aState); - NotifyMessage(nsString aSessionId, nsCString aData); - NotifySessionConnect(uint64_t aWindowId, nsString aSessionId); + async NotifyAvailableChange(bool aAvailable); + async NotifySessionStateChange(nsString aSessionId, uint16_t aState); + async NotifyMessage(nsString aSessionId, nsCString aData); + async NotifySessionConnect(uint64_t aWindowId, nsString aSessionId); parent: - __delete__(); + async __delete__(); - RegisterAvailabilityHandler(); - UnregisterAvailabilityHandler(); + async RegisterAvailabilityHandler(); + async UnregisterAvailabilityHandler(); - RegisterSessionHandler(nsString aSessionId); - UnregisterSessionHandler(nsString aSessionId); + async RegisterSessionHandler(nsString aSessionId); + async UnregisterSessionHandler(nsString aSessionId); - RegisterRespondingHandler(uint64_t aWindowId); - UnregisterRespondingHandler(uint64_t aWindowId); + async RegisterRespondingHandler(uint64_t aWindowId); + async UnregisterRespondingHandler(uint64_t aWindowId); - PPresentationRequest(PresentationIPCRequest aRequest); + async PPresentationRequest(PresentationIPCRequest aRequest); - NotifyReceiverReady(nsString aSessionId); + async NotifyReceiverReady(nsString aSessionId); }; } // namespace dom diff --git a/dom/presentation/ipc/PPresentationRequest.ipdl b/dom/presentation/ipc/PPresentationRequest.ipdl index 573e6bae8d..9680f9db01 100644 --- a/dom/presentation/ipc/PPresentationRequest.ipdl +++ b/dom/presentation/ipc/PPresentationRequest.ipdl @@ -14,7 +14,7 @@ sync protocol PPresentationRequest manager PPresentation; child: - __delete__(nsresult result); + async __delete__(nsresult result); }; } // namespace dom diff --git a/dom/system/gonk/NetworkManager.js b/dom/system/gonk/NetworkManager.js index 927551e73e..ee75195a92 100644 --- a/dom/system/gonk/NetworkManager.js +++ b/dom/system/gonk/NetworkManager.js @@ -14,9 +14,9 @@ Cu.import("resource://gre/modules/Promise.jsm"); const NETWORKMANAGER_CONTRACTID = "@mozilla.org/network/manager;1"; const NETWORKMANAGER_CID = - Components.ID("{33901e46-33b8-11e1-9869-f46d04d25bcc}"); + Components.ID("{1ba9346b-53b5-4660-9dc6-58f0b258d0a6}"); -const DEFAULT_PREFERRED_NETWORK_TYPE = Ci.nsINetworkInfo.NETWORK_TYPE_WIFI; +const DEFAULT_PREFERRED_NETWORK_TYPE = Ci.nsINetworkInterface.NETWORK_TYPE_ETHERNET; XPCOMUtils.defineLazyGetter(this, "ppmm", function() { return Cc["@mozilla.org/parentprocessmessagemanager;1"] @@ -426,7 +426,8 @@ NetworkManager.prototype = { return this.removeSecondaryDefaultRoute(extNetworkInfo); }) .then(() => { - if (extNetworkInfo.type == Ci.nsINetworkInfo.NETWORK_TYPE_WIFI) { + if (extNetworkInfo.type == Ci.nsINetworkInfo.NETWORK_TYPE_WIFI || + extNetworkInfo.type == Ci.nsINetworkInfo.NETWORK_TYPE_ETHERNET) { // Remove routing table in /proc/net/route return this._resetRoutingTable(extNetworkInfo.name); } @@ -499,6 +500,43 @@ NetworkManager.prototype = { networkInterfaceLinks: null, + _networkTypePriorityList: [Ci.nsINetworkInterface.NETWORK_TYPE_ETHERNET, + Ci.nsINetworkInterface.NETWORK_TYPE_WIFI, + Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE], + get networkTypePriorityList() { + return this._networkTypePriorityList; + }, + set networkTypePriorityList(val) { + if (val.length != this._networkTypePriorityList.length) { + throw "Priority list length should equal to " + + this._networkTypePriorityList.length; + } + + // Check if types in new priority list are valid and also make sure there + // are no duplicate types. + let list = [Ci.nsINetworkInterface.NETWORK_TYPE_ETHERNET, + Ci.nsINetworkInterface.NETWORK_TYPE_WIFI, + Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE]; + while (list.length) { + let type = list.shift(); + if (val.indexOf(type) == -1) { + throw "There is missing network type"; + } + } + + this._networkTypePriorityList = val; + }, + + getPriority: function(type) { + if (this._networkTypePriorityList.indexOf(type) == -1) { + // 0 indicates the lowest priority. + return 0; + } + + return this._networkTypePriorityList.length - + this._networkTypePriorityList.indexOf(type); + }, + get allNetworkInfo() { let allNetworkInfo = {}; @@ -516,8 +554,9 @@ NetworkManager.prototype = { return this._preferredNetworkType; }, set preferredNetworkType(val) { - if ([Ci.nsINetworkInfo.NETWORK_TYPE_WIFI, - Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE].indexOf(val) == -1) { + if ([Ci.nsINetworkInterface.NETWORK_TYPE_WIFI, + Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE, + Ci.nsINetworkInterface.NETWORK_TYPE_ETHERNET].indexOf(val) == -1) { throw "Invalid network type"; } this._preferredNetworkType = val; @@ -532,9 +571,9 @@ NetworkManager.prototype = { _overriddenActive: null, overrideActive: function(network) { - let type = network.info.type; - if ([Ci.nsINetworkInfo.NETWORK_TYPE_WIFI, - Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE].indexOf(type) == -1) { + if ([Ci.nsINetworkInterface.NETWORK_TYPE_WIFI, + Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE, + Ci.nsINetworkInterface.NETWORK_TYPE_ETHERNET].indexOf(val) == -1) { throw "Invalid network type"; } @@ -835,15 +874,28 @@ NetworkManager.prototype = { // Set active only for default connections. if (network.info.type != Ci.nsINetworkInfo.NETWORK_TYPE_WIFI && - network.info.type != Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE) { + network.info.type != Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE && + network.info.type != Ci.nsINetworkInfo.NETWORK_TYPE_ETHERNET) { continue; } - this._activeNetwork = network; if (network.info.type == this.preferredNetworkType) { + this._activeNetwork = network; debug("Found our preferred type of network: " + network.info.name); break; } + + // Initialize the active network with the first connected network. + if (!this._activeNetwork) { + this._activeNetwork = network; + continue; + } + + // Compare the prioriy between two network types. If found incoming + // network with higher priority, replace the active network. + if (this.getPriority(this._activeNetwork.type) < this.getPriority(network.type)) { + this._activeNetwork = network; + } } return Promise.resolve() @@ -927,8 +979,9 @@ NetworkManager.prototype = { // If there is internal interface change (e.g., MOBILE_MMS, MOBILE_SUPL), // the function will return null so that it won't trigger type change event // in NetworkInformation API. - if (aNetworkInfo.type != Ci.nsINetworkInfo.NETWORK_TYPE_WIFI && - aNetworkInfo.type != Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE) { + if (aNetworkInfo.type != Ci.nsINetworkInterface.NETWORK_TYPE_WIFI && + aNetworkInfo.type != Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE && + aNetworkInfo.type != Ci.nsINetworkInterface.NETWORK_TYPE_ETHERNET) { return null; } @@ -941,6 +994,8 @@ NetworkManager.prototype = { return CONNECTION_TYPE_WIFI; case Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE: return CONNECTION_TYPE_CELLULAR; + case Ci.nsINetworkInterface.NETWORK_TYPE_ETHERNET: + return CONNECTION_TYPE_ETHERNET; } }, diff --git a/dom/system/gonk/NetworkManager.manifest b/dom/system/gonk/NetworkManager.manifest index 172af047fa..995fa65598 100644 --- a/dom/system/gonk/NetworkManager.manifest +++ b/dom/system/gonk/NetworkManager.manifest @@ -1,3 +1,3 @@ # NetworkManager.js -component {33901e46-33b8-11e1-9869-f46d04d25bcc} NetworkManager.js -contract @mozilla.org/network/manager;1 {33901e46-33b8-11e1-9869-f46d04d25bcc} +component {1ba9346b-53b5-4660-9dc6-58f0b258d0a6} NetworkManager.js +contract @mozilla.org/network/manager;1 {1ba9346b-53b5-4660-9dc6-58f0b258d0a6} diff --git a/dom/system/gonk/nsINetworkInterface.idl b/dom/system/gonk/nsINetworkInterface.idl index 4e815819c4..bd40e751a1 100644 --- a/dom/system/gonk/nsINetworkInterface.idl +++ b/dom/system/gonk/nsINetworkInterface.idl @@ -4,7 +4,7 @@ #include "nsISupports.idl" -[scriptable, uuid(f439ab5d-64bd-4a6c-8863-30235fa784d2)] +[scriptable, uuid(4816a559-5620-4cb5-8433-ff0b25e6622f)] interface nsINetworkInfo : nsISupports { const long NETWORK_STATE_UNKNOWN = -1; @@ -12,6 +12,8 @@ interface nsINetworkInfo : nsISupports const long NETWORK_STATE_CONNECTED = 1; const long NETWORK_STATE_DISCONNECTING = 2; const long NETWORK_STATE_DISCONNECTED = 3; + const long NETWORK_STATE_ENABLED = 4; + const long NETWORK_STATE_DISABLED = 5; /** * Current network state, one of the NETWORK_STATE_* constants. @@ -30,6 +32,7 @@ interface nsINetworkInfo : nsISupports const long NETWORK_TYPE_MOBILE_IMS = 5; const long NETWORK_TYPE_MOBILE_DUN = 6; const long NETWORK_TYPE_MOBILE_FOTA = 7; + const long NETWORK_TYPE_ETHERNET = 8; /** * Network type. One of the NETWORK_TYPE_* constants. diff --git a/dom/system/gonk/nsINetworkManager.idl b/dom/system/gonk/nsINetworkManager.idl index 1ac0c05ee9..0da1237969 100644 --- a/dom/system/gonk/nsINetworkManager.idl +++ b/dom/system/gonk/nsINetworkManager.idl @@ -10,7 +10,7 @@ interface nsINetworkInterface; /** * Manage network interfaces. */ -[scriptable, uuid(e5ffe335-078e-4b25-87f1-02429bd2e458)] +[scriptable, uuid(1ba9346b-53b5-4660-9dc6-58f0b258d0a6)] interface nsINetworkManager : nsISupports { /** @@ -62,6 +62,15 @@ interface nsINetworkManager : nsISupports */ readonly attribute jsval allNetworkInfo; + /** + * Priority list of network types. An array of + * nsINetworkInterface::NETWORK_TYPE_* constants. + * + * The piror position of the type indicates the higher priority. The priority + * is used to determine route when there are multiple connected networks. + */ + attribute jsval networkTypePriorityList; + /** * The preferred network type. One of the * nsINetworkInterface::NETWORK_TYPE_* constants. diff --git a/dom/telephony/ipc/PTelephony.ipdl b/dom/telephony/ipc/PTelephony.ipdl index 57f559df1a..9660d1dd1b 100644 --- a/dom/telephony/ipc/PTelephony.ipdl +++ b/dom/telephony/ipc/PTelephony.ipdl @@ -125,43 +125,43 @@ sync protocol PTelephony { manages PTelephonyRequest; child: - NotifyCallStateChanged(nsTelephonyCallInfo[] aAllInfo); + async NotifyCallStateChanged(nsTelephonyCallInfo[] aAllInfo); - NotifyCdmaCallWaiting(uint32_t aClientId, IPCCdmaWaitingCallData aData); + async NotifyCdmaCallWaiting(uint32_t aClientId, IPCCdmaWaitingCallData aData); - NotifyConferenceError(nsString aName, nsString aMessage); + async NotifyConferenceError(nsString aName, nsString aMessage); - NotifySupplementaryService(uint32_t aClientId, int32_t aCallIndex, - uint16_t aNotification); + async NotifySupplementaryService(uint32_t aClientId, int32_t aCallIndex, + uint16_t aNotification); parent: /** * Sent when the child no longer needs to use PTelephony. */ - __delete__(); + async __delete__(); /** * Sent when the child makes an asynchronous request to the parent. */ - PTelephonyRequest(IPCTelephonyRequest request); + async PTelephonyRequest(IPCTelephonyRequest request); - RegisterListener(); + async RegisterListener(); - UnregisterListener(); + async UnregisterListener(); - StartTone(uint32_t aClientId, nsString aTone); + async StartTone(uint32_t aClientId, nsString aTone); - StopTone(uint32_t aClientId); + async StopTone(uint32_t aClientId); sync GetMicrophoneMuted() returns (bool aMuted); - SetMicrophoneMuted(bool aMuted); + async SetMicrophoneMuted(bool aMuted); sync GetSpeakerEnabled() returns (bool aEnabled); - SetSpeakerEnabled(bool aEnabled); + async SetSpeakerEnabled(bool aEnabled); }; } /* namespace telephony */ diff --git a/dom/telephony/ipc/PTelephonyRequest.ipdl b/dom/telephony/ipc/PTelephonyRequest.ipdl index 0e4c86a366..7a9755851e 100644 --- a/dom/telephony/ipc/PTelephonyRequest.ipdl +++ b/dom/telephony/ipc/PTelephonyRequest.ipdl @@ -66,14 +66,14 @@ protocol PTelephonyRequest manager PTelephony; child: - NotifyEnumerateCallState(nsTelephonyCallInfo aInfo); + async NotifyEnumerateCallState(nsTelephonyCallInfo aInfo); - NotifyDialMMI(nsString aServiceCode); + async NotifyDialMMI(nsString aServiceCode); /** * Sent when the asynchronous request has completed. */ - __delete__(IPCTelephonyResponse aResponse); + async __delete__(IPCTelephonyResponse aResponse); }; } /* namespace telephony */ diff --git a/dom/voicemail/ipc/PVoicemail.ipdl b/dom/voicemail/ipc/PVoicemail.ipdl index e612d95133..5f37884cc9 100644 --- a/dom/voicemail/ipc/PVoicemail.ipdl +++ b/dom/voicemail/ipc/PVoicemail.ipdl @@ -15,21 +15,21 @@ sync protocol PVoicemail manager PContent; child: - NotifyInfoChanged(uint32_t aServiceId, - nsString aNumber, - nsString aDisplayName); + async NotifyInfoChanged(uint32_t aServiceId, + nsString aNumber, + nsString aDisplayName); - NotifyStatusChanged(uint32_t aServiceId, - bool aHasMessages, - int32_t aMessageCount, - nsString aNumber, - nsString aDisplayName); + async NotifyStatusChanged(uint32_t aServiceId, + bool aHasMessages, + int32_t aMessageCount, + nsString aNumber, + nsString aDisplayName); parent: /** * Send when child no longer needs to use PVoicemail. */ - __delete__(); + async __delete__(); sync GetAttributes(uint32_t aServiceId) returns (nsString aNumber, diff --git a/dom/webidl/WebrtcGlobalInformation.webidl b/dom/webidl/WebrtcGlobalInformation.webidl index 70e021c59d..ace9e71784 100644 --- a/dom/webidl/WebrtcGlobalInformation.webidl +++ b/dom/webidl/WebrtcGlobalInformation.webidl @@ -18,10 +18,14 @@ interface WebrtcGlobalInformation { static void getAllStats(WebrtcGlobalStatisticsCallback callback, optional DOMString pcIdFilter); + static void clearAllStats(); + [Throws] static void getLogging(DOMString pattern, WebrtcGlobalLoggingCallback callback); + static void clearLogging(); + // NSPR WebRTC Trace debug level (0 - 65535) // // Notes: @@ -33,5 +37,3 @@ interface WebrtcGlobalInformation { // WebRTC AEC debugging enable static attribute boolean aecDebug; }; - - diff --git a/dom/workers/PServiceWorkerManager.ipdl b/dom/workers/PServiceWorkerManager.ipdl index 8716815fcd..ff29b84f60 100644 --- a/dom/workers/PServiceWorkerManager.ipdl +++ b/dom/workers/PServiceWorkerManager.ipdl @@ -17,28 +17,28 @@ protocol PServiceWorkerManager manager PBackground; parent: - Register(ServiceWorkerRegistrationData data); + async Register(ServiceWorkerRegistrationData data); - Unregister(PrincipalInfo principalInfo, nsString scope); + async Unregister(PrincipalInfo principalInfo, nsString scope); - PropagateSoftUpdate(OriginAttributes originAttributes, - nsString scope); - PropagateUnregister(PrincipalInfo principalInfo, nsString scope); + async PropagateSoftUpdate(OriginAttributes originAttributes, + nsString scope); + async PropagateUnregister(PrincipalInfo principalInfo, nsString scope); - PropagateRemove(nsCString host); + async PropagateRemove(nsCString host); - PropagateRemoveAll(); + async PropagateRemoveAll(); - Shutdown(); + async Shutdown(); child: - NotifyRegister(ServiceWorkerRegistrationData data); - NotifySoftUpdate(OriginAttributes originAttributes, nsString scope); - NotifyUnregister(PrincipalInfo principalInfo, nsString scope); - NotifyRemove(nsCString host); - NotifyRemoveAll(); + async NotifyRegister(ServiceWorkerRegistrationData data); + async NotifySoftUpdate(OriginAttributes originAttributes, nsString scope); + async NotifyUnregister(PrincipalInfo principalInfo, nsString scope); + async NotifyRemove(nsCString host); + async NotifyRemoveAll(); - __delete__(); + async __delete__(); }; } // namespace dom diff --git a/embedding/components/printingui/ipc/PPrintProgressDialog.ipdl b/embedding/components/printingui/ipc/PPrintProgressDialog.ipdl index 3011f9a63b..1da29ef87c 100644 --- a/embedding/components/printingui/ipc/PPrintProgressDialog.ipdl +++ b/embedding/components/printingui/ipc/PPrintProgressDialog.ipdl @@ -13,22 +13,22 @@ protocol PPrintProgressDialog manager PPrinting; parent: - StateChange(long stateFlags, - nsresult status); + async StateChange(long stateFlags, + nsresult status); - ProgressChange(long curSelfProgress, - long maxSelfProgress, - long curTotalProgress, - long maxTotalProgress); + async ProgressChange(long curSelfProgress, + long maxSelfProgress, + long curTotalProgress, + long maxTotalProgress); - DocTitleChange(nsString newTitle); + async DocTitleChange(nsString newTitle); - DocURLChange(nsString newURL); + async DocURLChange(nsString newURL); - __delete__(); + async __delete__(); child: - DialogOpened(); + async DialogOpened(); }; } // namespace embedding diff --git a/embedding/components/printingui/ipc/PPrintSettingsDialog.ipdl b/embedding/components/printingui/ipc/PPrintSettingsDialog.ipdl index 95868e3e44..3e436892ed 100644 --- a/embedding/components/printingui/ipc/PPrintSettingsDialog.ipdl +++ b/embedding/components/printingui/ipc/PPrintSettingsDialog.ipdl @@ -22,7 +22,7 @@ protocol PPrintSettingsDialog manager PPrinting; child: - __delete__(PrintDataOrNSResult result); + async __delete__(PrintDataOrNSResult result); }; } // namespace embedding diff --git a/embedding/components/printingui/ipc/PPrinting.ipdl b/embedding/components/printingui/ipc/PPrinting.ipdl index 1aee578704..491c3815a0 100644 --- a/embedding/components/printingui/ipc/PPrinting.ipdl +++ b/embedding/components/printingui/ipc/PPrinting.ipdl @@ -31,8 +31,8 @@ parent: PBrowser browser, PrintData settings); - PPrintProgressDialog(); - PPrintSettingsDialog(); + async PPrintProgressDialog(); + async PPrintSettingsDialog(); sync SavePrintSettings(PrintData settings, bool usePrinterNamePrefix, uint32_t flags) @@ -40,7 +40,7 @@ parent: child: async PRemotePrintJob(); - __delete__(); + async __delete__(); }; } // namespace embedding diff --git a/extensions/spellcheck/hunspell/glue/PRemoteSpellcheckEngine.ipdl b/extensions/spellcheck/hunspell/glue/PRemoteSpellcheckEngine.ipdl index 6c724475e4..7fd9183644 100644 --- a/extensions/spellcheck/hunspell/glue/PRemoteSpellcheckEngine.ipdl +++ b/extensions/spellcheck/hunspell/glue/PRemoteSpellcheckEngine.ipdl @@ -10,7 +10,7 @@ sync protocol PRemoteSpellcheckEngine { manager PContent; parent: - __delete__(); + async __delete__(); sync Check(nsString aWord) returns (bool aIsMisspelled); diff --git a/gfx/2d/2D.h b/gfx/2d/2D.h index 2011bc4d0f..a51715138f 100644 --- a/gfx/2d/2D.h +++ b/gfx/2d/2D.h @@ -1240,6 +1240,8 @@ public: static already_AddRefed CreateDrawTargetForCairoSurface(cairo_surface_t* aSurface, const IntSize& aSize, SurfaceFormat* aFormat = nullptr); + static already_AddRefed CreateSourceSurfaceForCairoSurface(cairo_surface_t* aSurface, const IntSize& aSize, SurfaceFormat aFormat); + static already_AddRefed CreateDrawTarget(BackendType aBackend, const IntSize &aSize, SurfaceFormat aFormat); diff --git a/gfx/2d/DrawTargetCairo.cpp b/gfx/2d/DrawTargetCairo.cpp index 3d9f3244a5..3670fe3c60 100644 --- a/gfx/2d/DrawTargetCairo.cpp +++ b/gfx/2d/DrawTargetCairo.cpp @@ -1731,22 +1731,19 @@ DrawTargetCairo::OptimizeSourceSurface(SourceSurface *aSurface) const already_AddRefed DrawTargetCairo::CreateSourceSurfaceFromNativeSurface(const NativeSurface &aSurface) const { - if (aSurface.mType == NativeSurfaceType::CAIRO_SURFACE) { - if (aSurface.mSize.width <= 0 || - aSurface.mSize.height <= 0) { - gfxWarning() << "Can't create a SourceSurface without a valid size"; - return nullptr; - } - cairo_surface_t* surf = static_cast(aSurface.mSurface); - return MakeAndAddRef(surf, aSurface.mSize, aSurface.mFormat); - } - return nullptr; } already_AddRefed DrawTargetCairo::CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const { + if (cairo_surface_status(mSurface)) { + RefPtr target = new DrawTargetCairo(); + if (target->Init(aSize, aFormat)) { + return target.forget(); + } + } + cairo_surface_t* similar = cairo_surface_create_similar(mSurface, GfxFormatToCairoContent(aFormat), aSize.width, aSize.height); @@ -1758,7 +1755,7 @@ DrawTargetCairo::CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFo } } - gfxCriticalError(CriticalLog::DefaultOptions(Factory::ReasonableSurfaceSize(aSize))) << "Failed to create similar cairo surface! Size: " << aSize << " Status: " << cairo_surface_status(similar) << " format " << (int)aFormat; + gfxCriticalError(CriticalLog::DefaultOptions(Factory::ReasonableSurfaceSize(aSize))) << "Failed to create similar cairo surface! Size: " << aSize << " Status: " << cairo_surface_status(similar) << cairo_surface_status(mSurface) << " format " << (int)aFormat; return nullptr; } @@ -1873,9 +1870,6 @@ DrawTargetCairo::Init(unsigned char* aData, const IntSize &aSize, int32_t aStrid void * DrawTargetCairo::GetNativeSurface(NativeSurfaceType aType) { - if (aType == NativeSurfaceType::CAIRO_SURFACE) { - return cairo_get_group_target(mContext); - } if (aType == NativeSurfaceType::CAIRO_CONTEXT) { return mContext; } diff --git a/gfx/2d/DrawTargetSkia.cpp b/gfx/2d/DrawTargetSkia.cpp index 5444c3b249..933f72f76d 100644 --- a/gfx/2d/DrawTargetSkia.cpp +++ b/gfx/2d/DrawTargetSkia.cpp @@ -4,7 +4,6 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "DrawTargetSkia.h" -#include "SourceSurfaceCairo.h" #include "SourceSurfaceSkia.h" #include "ScaledFontBase.h" #include "ScaledFontCairo.h" @@ -23,6 +22,13 @@ #include "DataSurfaceHelpers.h" #include +#ifdef USE_SKIA_GPU +#include "GLDefs.h" +#include "skia/include/gpu/SkGr.h" +#include "skia/include/gpu/GrContext.h" +#include "skia/include/gpu/gl/GrGLInterface.h" +#endif + namespace mozilla { namespace gfx { @@ -103,14 +109,8 @@ GetBitmapForSurface(SourceSurface* aSurface) return bitmap; } - SkAlphaType alphaType = (surf->GetFormat() == SurfaceFormat::B8G8R8X8) ? - kOpaque_SkAlphaType : kPremul_SkAlphaType; - - SkImageInfo info = SkImageInfo::Make(surf->GetSize().width, - surf->GetSize().height, - GfxFormatToSkiaColorType(surf->GetFormat()), - alphaType); - if (!bitmap.installPixels(info, surf->GetData(), surf->Stride(), nullptr, + if (!bitmap.installPixels(MakeSkiaImageInfo(surf->GetSize(), surf->GetFormat()), + surf->GetData(), surf->Stride(), nullptr, ReleaseTemporarySurface, surf)) { gfxDebug() << "Failed installing pixels on Skia bitmap for temporary surface"; } @@ -119,11 +119,7 @@ GetBitmapForSurface(SourceSurface* aSurface) } DrawTargetSkia::DrawTargetSkia() - : -#ifdef USE_SKIA_GPU - mTexture(0), -#endif - mSnapshot(nullptr) + : mSnapshot(nullptr) { } @@ -685,6 +681,15 @@ already_AddRefed DrawTargetSkia::CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const { RefPtr target = new DrawTargetSkia(); +#ifdef USE_SKIA_GPU + if (UsingSkiaGPU()) { + // Try to create a GPU draw target first if we're currently using the GPU. + if (target->InitWithGrContext(mGrContext.get(), aSize, aFormat)) { + return target.forget(); + } + // Otherwise, just fall back to a software draw target. + } +#endif if (!target->Init(aSize, aFormat)) { return nullptr; } @@ -695,7 +700,7 @@ bool DrawTargetSkia::UsingSkiaGPU() const { #ifdef USE_SKIA_GPU - return !!mTexture; + return !!mGrContext; #else return false; #endif @@ -704,56 +709,67 @@ DrawTargetSkia::UsingSkiaGPU() const already_AddRefed DrawTargetSkia::OptimizeSourceSurface(SourceSurface *aSurface) const { +#ifdef USE_SKIA_GPU + if (UsingSkiaGPU()) { + // Check if the underlying SkBitmap already has an associated GrTexture. + if (aSurface->GetType() == SurfaceType::SKIA && + static_cast(aSurface)->GetBitmap().getTexture()) { + RefPtr surface(aSurface); + return surface.forget(); + } + + // Upload the SkBitmap to a GrTexture otherwise. + SkAutoTUnref texture( + GrRefCachedBitmapTexture(mGrContext.get(), + GetBitmapForSurface(aSurface), + GrTextureParams::ClampBilerp())); + + // Create a new SourceSurfaceSkia whose SkBitmap contains the GrTexture. + RefPtr surface = new SourceSurfaceSkia(); + if (surface->InitFromGrTexture(texture, aSurface->GetSize(), aSurface->GetFormat())) { + return surface.forget(); + } + } +#endif + if (aSurface->GetType() == SurfaceType::SKIA) { RefPtr surface(aSurface); return surface.forget(); } - if (!UsingSkiaGPU()) { - // If we're not using skia-gl then drawing doesn't require any - // uploading, so any data surface is fine. Call GetDataSurface - // to trigger any required readback so that it only happens - // once. - return aSurface->GetDataSurface(); - } - - // If we are using skia-gl then we want to copy into a surface that - // will cache the uploaded gl texture. - RefPtr dataSurf = aSurface->GetDataSurface(); - DataSourceSurface::MappedSurface map; - if (!dataSurf->Map(DataSourceSurface::READ, &map)) { - return nullptr; - } - - RefPtr result = CreateSourceSurfaceFromData(map.mData, - dataSurf->GetSize(), - map.mStride, - dataSurf->GetFormat()); - dataSurf->Unmap(); - return result.forget(); + // If we're not using skia-gl then drawing doesn't require any + // uploading, so any data surface is fine. Call GetDataSurface + // to trigger any required readback so that it only happens + // once. + return aSurface->GetDataSurface(); } already_AddRefed DrawTargetSkia::CreateSourceSurfaceFromNativeSurface(const NativeSurface &aSurface) const { - if (aSurface.mType == NativeSurfaceType::CAIRO_SURFACE) { - if (aSurface.mSize.width <= 0 || - aSurface.mSize.height <= 0) { - gfxWarning() << "Can't create a SourceSurface without a valid size"; - return nullptr; - } - cairo_surface_t* surf = static_cast(aSurface.mSurface); - return MakeAndAddRef(surf, aSurface.mSize, aSurface.mFormat); #if USE_SKIA_GPU - } else if (aSurface.mType == NativeSurfaceType::OPENGL_TEXTURE && UsingSkiaGPU()) { + if (aSurface.mType == NativeSurfaceType::OPENGL_TEXTURE && UsingSkiaGPU()) { + // Wrap the OpenGL texture id in a Skia texture handle. + GrBackendTextureDesc texDesc; + texDesc.fWidth = aSurface.mSize.width; + texDesc.fHeight = aSurface.mSize.height; + texDesc.fOrigin = kTopLeft_GrSurfaceOrigin; + texDesc.fConfig = GfxFormatToGrConfig(aSurface.mFormat); + + GrGLTextureInfo texInfo; + texInfo.fTarget = LOCAL_GL_TEXTURE_2D; + texInfo.fID = (GrGLuint)(uintptr_t)aSurface.mSurface; + texDesc.fTextureHandle = reinterpret_cast(&texInfo); + + SkAutoTUnref texture(mGrContext->textureProvider()->wrapBackendTexture(texDesc)); + RefPtr newSurf = new SourceSurfaceSkia(); - unsigned int texture = (unsigned int)((uintptr_t)aSurface.mSurface); - if (newSurf->InitFromTexture((DrawTargetSkia*)this, texture, aSurface.mSize, aSurface.mFormat)) { + if (newSurf->InitFromGrTexture(texture, aSurface.mSize, aSurface.mFormat)) { return newSurf.forget(); } return nullptr; -#endif } +#endif return nullptr; } @@ -799,18 +815,11 @@ DrawTargetSkia::Init(const IntSize &aSize, SurfaceFormat aFormat) return false; } - SkAlphaType alphaType = (aFormat == SurfaceFormat::B8G8R8X8) ? - kOpaque_SkAlphaType : kPremul_SkAlphaType; - - SkImageInfo skiInfo = SkImageInfo::Make( - aSize.width, aSize.height, - GfxFormatToSkiaColorType(aFormat), - alphaType); // we need to have surfaces that have a stride aligned to 4 for interop with cairo int stride = (BytesPerPixel(aFormat)*aSize.width + (4-1)) & -4; SkBitmap bitmap; - bitmap.setInfo(skiInfo, stride); + bitmap.setInfo(MakeSkiaImageInfo(aSize, aFormat), stride); if (!bitmap.tryAllocPixels()) { return false; } @@ -836,30 +845,16 @@ DrawTargetSkia::InitWithGrContext(GrContext* aGrContext, return false; } - mGrContext = aGrContext; - mSize = aSize; - mFormat = aFormat; - - GrSurfaceDesc targetDescriptor; - - targetDescriptor.fFlags = kRenderTarget_GrSurfaceFlag; - targetDescriptor.fWidth = mSize.width; - targetDescriptor.fHeight = mSize.height; - targetDescriptor.fConfig = GfxFormatToGrConfig(mFormat); - targetDescriptor.fOrigin = kBottomLeft_GrSurfaceOrigin; - targetDescriptor.fSampleCnt = 0; - - SkAutoTUnref skiaTexture(mGrContext->textureProvider()->createTexture(targetDescriptor, SkSurface::kNo_Budgeted, nullptr, 0)); - if (!skiaTexture) { - return false; - } - - SkAutoTUnref gpuSurface(SkSurface::NewRenderTargetDirect(skiaTexture->asRenderTarget())); + // Create a GPU rendertarget/texture using the supplied GrContext. + // NewRenderTarget also implicitly clears the underlying texture on creation. + SkAutoTUnref gpuSurface(SkSurface::NewRenderTarget(aGrContext, SkSurface::kNo_Budgeted, MakeSkiaImageInfo(aSize, aFormat))); if (!gpuSurface) { return false; } - mTexture = reinterpret_cast(skiaTexture->getTextureHandle())->fID; + mGrContext = aGrContext; + mSize = aSize; + mFormat = aFormat; mCanvas = gpuSurface->getCanvas(); @@ -868,24 +863,40 @@ DrawTargetSkia::InitWithGrContext(GrContext* aGrContext, #endif +#ifdef DEBUG +bool +VerifyRGBXFormat(uint8_t* aData, const IntSize &aSize, const int32_t aStride, SurfaceFormat aFormat) +{ + // We should've initialized the data to be opaque already + // On debug builds, verify that this is actually true. + int height = aSize.height; + int width = aSize.width; + + for (int row = 0; row < height; ++row) { + for (int column = 0; column < width; column += 4) { +#ifdef IS_BIG_ENDIAN + MOZ_ASSERT(aData[column] == 0xFF); +#else + MOZ_ASSERT(aData[column + 3] == 0xFF); +#endif + } + aData += aStride; + } + + return true; +} +#endif + void DrawTargetSkia::Init(unsigned char* aData, const IntSize &aSize, int32_t aStride, SurfaceFormat aFormat) { - SkAlphaType alphaType = kPremul_SkAlphaType; - if (aFormat == SurfaceFormat::B8G8R8X8) { - // We have to manually set the A channel to be 255 as Skia doesn't understand BGRX - ConvertBGRXToBGRA(aData, aSize, aStride); - alphaType = kOpaque_SkAlphaType; - } + MOZ_ASSERT((aFormat != SurfaceFormat::B8G8R8X8) || + VerifyRGBXFormat(aData, aSize, aStride, aFormat)); SkBitmap bitmap; - - SkImageInfo info = SkImageInfo::Make(aSize.width, - aSize.height, - GfxFormatToSkiaColorType(aFormat), - alphaType); - bitmap.setInfo(info, aStride); + bitmap.setInfo(MakeSkiaImageInfo(aSize, aFormat), aStride); bitmap.setPixels(aData); + mCanvas.adopt(new SkCanvas(bitmap)); mSize = aSize; @@ -906,7 +917,15 @@ DrawTargetSkia::GetNativeSurface(NativeSurfaceType aType) { #ifdef USE_SKIA_GPU if (aType == NativeSurfaceType::OPENGL_TEXTURE) { - return (void*)((uintptr_t)mTexture); + // Get the current texture backing the GPU device. + // Beware - this texture is only guaranteed to valid after a draw target flush. + GrRenderTarget* rt = mCanvas->getDevice()->accessRenderTarget(); + if (rt) { + GrTexture* tex = rt->asTexture(); + if (tex) { + return (void*)(uintptr_t)reinterpret_cast(tex->getTextureHandle())->fID; + } + } } #endif return nullptr; diff --git a/gfx/2d/DrawTargetSkia.h b/gfx/2d/DrawTargetSkia.h index a9c1aff931..9a30786680 100644 --- a/gfx/2d/DrawTargetSkia.h +++ b/gfx/2d/DrawTargetSkia.h @@ -6,11 +6,6 @@ #ifndef _MOZILLA_GFX_SOURCESURFACESKIA_H #define _MOZILLA_GFX_SOURCESURFACESKIA_H -#ifdef USE_SKIA_GPU -#include "skia/include/gpu/GrContext.h" -#include "skia/include/gpu/gl/GrGLInterface.h" -#endif - #include "skia/include/core/SkCanvas.h" #include "2D.h" @@ -168,7 +163,6 @@ private: #ifdef USE_SKIA_GPU RefPtrSkia mGrContext; - GrGLuint mTexture; #endif IntSize mSize; diff --git a/gfx/2d/Factory.cpp b/gfx/2d/Factory.cpp index 703e369d7e..75c43396d0 100644 --- a/gfx/2d/Factory.cpp +++ b/gfx/2d/Factory.cpp @@ -8,6 +8,7 @@ #ifdef USE_CAIRO #include "DrawTargetCairo.h" #include "ScaledFontCairo.h" +#include "SourceSurfaceCairo.h" #endif #ifdef USE_SKIA @@ -863,6 +864,21 @@ Factory::CreateDrawTargetForCairoSurface(cairo_surface_t* aSurface, const IntSiz return retVal.forget(); } +already_AddRefed +Factory::CreateSourceSurfaceForCairoSurface(cairo_surface_t* aSurface, const IntSize& aSize, SurfaceFormat aFormat) +{ + if (aSize.width <= 0 || aSize.height <= 0) { + gfxWarning() << "Can't create a SourceSurface without a valid size"; + return nullptr; + } + +#ifdef USE_CAIRO + return MakeAndAddRef(aSurface, aSize, aFormat); +#else + return nullptr; +#endif +} + #ifdef XP_DARWIN already_AddRefed Factory::CreateDrawTargetForCairoCGContext(CGContextRef cg, const IntSize& aSize) diff --git a/gfx/2d/HelpersSkia.h b/gfx/2d/HelpersSkia.h index 92cb9b4f03..c2e1ddfc4a 100644 --- a/gfx/2d/HelpersSkia.h +++ b/gfx/2d/HelpersSkia.h @@ -55,6 +55,27 @@ SkiaColorTypeToGfxFormat(SkColorType type) } } +static inline SkAlphaType +GfxFormatToSkiaAlphaType(SurfaceFormat format) +{ + switch (format) + { + case SurfaceFormat::B8G8R8X8: + case SurfaceFormat::R5G6B5_UINT16: + return kOpaque_SkAlphaType; + default: + return kPremul_SkAlphaType; + } +} + +static inline SkImageInfo +MakeSkiaImageInfo(const IntSize& aSize, SurfaceFormat aFormat) +{ + return SkImageInfo::Make(aSize.width, aSize.height, + GfxFormatToSkiaColorType(aFormat), + GfxFormatToSkiaAlphaType(aFormat)); +} + #ifdef USE_SKIA_GPU static inline GrPixelConfig GfxFormatToGrConfig(SurfaceFormat format) diff --git a/gfx/2d/Scale.cpp b/gfx/2d/Scale.cpp index 6062c5fcd2..f1fec03d03 100644 --- a/gfx/2d/Scale.cpp +++ b/gfx/2d/Scale.cpp @@ -18,23 +18,12 @@ bool Scale(uint8_t* srcData, int32_t srcWidth, int32_t srcHeight, int32_t srcStr SurfaceFormat format) { #ifdef USE_SKIA - SkAlphaType alphaType; - if (format == SurfaceFormat::B8G8R8A8) { - alphaType = kPremul_SkAlphaType; - } else { - alphaType = kOpaque_SkAlphaType; - } - - SkImageInfo info = SkImageInfo::Make(srcWidth, - srcHeight, - GfxFormatToSkiaColorType(format), - alphaType); - SkBitmap imgSrc; - imgSrc.installPixels(info, srcData, srcStride); + imgSrc.installPixels(MakeSkiaImageInfo(IntSize(srcWidth, srcHeight), format), + srcData, srcStride); // Rescaler is compatible with 32 bpp only. Convert to RGB32 if needed. - if (format != SurfaceFormat::B8G8R8A8) { + if (imgSrc.colorType() != kBGRA_8888_SkColorType) { imgSrc.copyTo(&imgSrc, kBGRA_8888_SkColorType); } diff --git a/gfx/2d/SourceSurfaceSkia.cpp b/gfx/2d/SourceSurfaceSkia.cpp index 9b905462f2..219f24ffdf 100644 --- a/gfx/2d/SourceSurfaceSkia.cpp +++ b/gfx/2d/SourceSurfaceSkia.cpp @@ -13,7 +13,6 @@ #include "DataSurfaceHelpers.h" #ifdef USE_SKIA_GPU -#include "GLDefs.h" #include "skia/include/gpu/SkGrPixelRef.h" #endif @@ -62,24 +61,17 @@ SourceSurfaceSkia::InitFromCanvas(SkCanvas* aCanvas, return true; } -bool +bool SourceSurfaceSkia::InitFromData(unsigned char* aData, const IntSize &aSize, int32_t aStride, SurfaceFormat aFormat) { SkBitmap temp; - SkAlphaType alphaType = (aFormat == SurfaceFormat::B8G8R8X8) ? - kOpaque_SkAlphaType : kPremul_SkAlphaType; - - SkImageInfo info = SkImageInfo::Make(aSize.width, - aSize.height, - GfxFormatToSkiaColorType(aFormat), - alphaType); - temp.setInfo(info, aStride); + temp.setInfo(MakeSkiaImageInfo(aSize, aFormat), aStride); temp.setPixels(aData); - if (!temp.copyTo(&mBitmap, GfxFormatToSkiaColorType(aFormat))) { + if (!temp.copyTo(&mBitmap)) { return false; } @@ -89,39 +81,27 @@ SourceSurfaceSkia::InitFromData(unsigned char* aData, return true; } -bool -SourceSurfaceSkia::InitFromTexture(DrawTargetSkia* aOwner, - unsigned int aTexture, - const IntSize &aSize, - SurfaceFormat aFormat) -{ - MOZ_ASSERT(aOwner, "null GrContext"); #ifdef USE_SKIA_GPU - GrBackendTextureDesc skiaTexGlue; - mSize.width = skiaTexGlue.fWidth = aSize.width; - mSize.height = skiaTexGlue.fHeight = aSize.height; - skiaTexGlue.fFlags = kNone_GrBackendTextureFlag; - skiaTexGlue.fOrigin = kTopLeft_GrSurfaceOrigin; - skiaTexGlue.fConfig = GfxFormatToGrConfig(aFormat); - skiaTexGlue.fSampleCnt = 0; +bool +SourceSurfaceSkia::InitFromGrTexture(GrTexture* aTexture, + const IntSize &aSize, + SurfaceFormat aFormat) +{ + if (!aTexture) { + return false; + } - GrGLTextureInfo texInfo; - texInfo.fTarget = LOCAL_GL_TEXTURE_2D; - texInfo.fID = aTexture; - skiaTexGlue.fTextureHandle = reinterpret_cast(&texInfo); - - GrTexture *skiaTexture = aOwner->mGrContext->textureProvider()->wrapBackendTexture(skiaTexGlue); - SkImageInfo imgInfo = SkImageInfo::Make(aSize.width, aSize.height, GfxFormatToSkiaColorType(aFormat), kOpaque_SkAlphaType); - SkGrPixelRef *texRef = new SkGrPixelRef(imgInfo, skiaTexture); + // Create a GPU pixelref wrapping the texture. + SkImageInfo imgInfo = MakeSkiaImageInfo(aSize, aFormat); mBitmap.setInfo(imgInfo); - mBitmap.setPixelRef(texRef); + mBitmap.setPixelRef(new SkGrPixelRef(imgInfo, aTexture))->unref(); + + mSize = aSize; mFormat = aFormat; mStride = mBitmap.rowBytes(); -#endif - - mDrawTarget = aOwner; return true; } +#endif unsigned char* SourceSurfaceSkia::GetData() @@ -142,9 +122,13 @@ SourceSurfaceSkia::DrawTargetWillChange() MaybeUnlock(); mDrawTarget = nullptr; - SkBitmap temp = mBitmap; - mBitmap.reset(); - temp.copyTo(&mBitmap, temp.colorType()); + + // First try a deep copy to avoid a readback from the GPU. + // If that fails, try the CPU copy. + if (!mBitmap.deepCopyTo(&mBitmap) && + !mBitmap.copyTo(&mBitmap)) { + mBitmap.reset(); + } } } diff --git a/gfx/2d/SourceSurfaceSkia.h b/gfx/2d/SourceSurfaceSkia.h index 567b2e77d1..523cc586ff 100644 --- a/gfx/2d/SourceSurfaceSkia.h +++ b/gfx/2d/SourceSurfaceSkia.h @@ -39,14 +39,15 @@ public: SurfaceFormat aFormat, DrawTargetSkia* aOwner); +#ifdef USE_SKIA_GPU /** * NOTE: While wrapping a Texture for SkiaGL, the texture *must* be created * with the same GLcontext of DrawTargetSkia */ - bool InitFromTexture(DrawTargetSkia* aOwner, - unsigned int aTexture, - const IntSize &aSize, - SurfaceFormat aFormat); + bool InitFromGrTexture(GrTexture* aTexture, + const IntSize &aSize, + SurfaceFormat aFormat); +#endif virtual unsigned char *GetData(); diff --git a/gfx/2d/Types.h b/gfx/2d/Types.h index 6bd2eb9e61..94f4c9b8e0 100644 --- a/gfx/2d/Types.h +++ b/gfx/2d/Types.h @@ -143,7 +143,6 @@ enum class FontType : int8_t { enum class NativeSurfaceType : int8_t { D3D10_TEXTURE, - CAIRO_SURFACE, CAIRO_CONTEXT, CGCONTEXT, CGCONTEXT_ACCELERATED, diff --git a/gfx/layers/BufferTexture.cpp b/gfx/layers/BufferTexture.cpp index 2702a74e3d..1448695762 100644 --- a/gfx/layers/BufferTexture.cpp +++ b/gfx/layers/BufferTexture.cpp @@ -367,9 +367,11 @@ static bool InitBuffer(uint8_t* buf, size_t bufSize, TextureAllocationFlags aAll return false; } - if (aAllocFlags & ALLOC_CLEAR_BUFFER) { + if ((aAllocFlags & ALLOC_CLEAR_BUFFER) || + (aAllocFlags & ALLOC_CLEAR_BUFFER_BLACK)) { memset(buf, 0, bufSize); } + if (aAllocFlags & ALLOC_CLEAR_BUFFER_WHITE) { memset(buf, 0xFF, bufSize); } diff --git a/gfx/layers/basic/X11TextureSourceBasic.cpp b/gfx/layers/basic/X11TextureSourceBasic.cpp index 62b09b4b97..28169067c3 100644 --- a/gfx/layers/basic/X11TextureSourceBasic.cpp +++ b/gfx/layers/basic/X11TextureSourceBasic.cpp @@ -35,12 +35,9 @@ SourceSurface* X11TextureSourceBasic::GetSurface(DrawTarget* aTarget) { if (!mSourceSurface) { - NativeSurface surf; - surf.mFormat = GetFormat(); - surf.mType = NativeSurfaceType::CAIRO_SURFACE; - surf.mSurface = mSurface->CairoSurface(); - surf.mSize = GetSize(); - mSourceSurface = aTarget->CreateSourceSurfaceFromNativeSurface(surf); + mSourceSurface = + Factory::CreateSourceSurfaceForCairoSurface(mSurface->CairoSurface(), + GetSize(), GetFormat()); } return mSourceSurface; } diff --git a/gfx/layers/client/ContentClient.cpp b/gfx/layers/client/ContentClient.cpp index 77f3709726..1accb03cd8 100644 --- a/gfx/layers/client/ContentClient.cpp +++ b/gfx/layers/client/ContentClient.cpp @@ -290,10 +290,15 @@ void ContentClientRemoteBuffer::CreateBackBuffer(const IntRect& aBufferRect) { // gfx::BackendType::NONE means fallback to the content backend + TextureAllocationFlags textureAllocFlags + = (mTextureFlags & TextureFlags::COMPONENT_ALPHA) ? + TextureAllocationFlags::ALLOC_CLEAR_BUFFER_BLACK : + TextureAllocationFlags::ALLOC_CLEAR_BUFFER; + mTextureClient = CreateTextureClientForDrawing( mSurfaceFormat, mSize, BackendSelector::Content, mTextureFlags | ExtraTextureFlags(), - TextureAllocationFlags::ALLOC_CLEAR_BUFFER + textureAllocFlags ); if (!mTextureClient || !AddTextureClient(mTextureClient)) { AbortTextureClientCreation(); diff --git a/gfx/layers/client/TextureClient.cpp b/gfx/layers/client/TextureClient.cpp index 27708f51eb..d4ca10aa13 100644 --- a/gfx/layers/client/TextureClient.cpp +++ b/gfx/layers/client/TextureClient.cpp @@ -784,6 +784,13 @@ TextureClient::CreateForRawBufferAccess(ISurfaceAllocator* aAllocator, return nullptr; } + if (aFormat == SurfaceFormat::B8G8R8X8 && + (aAllocFlags != TextureAllocationFlags::ALLOC_CLEAR_BUFFER_BLACK) && + aMoz2DBackend == gfx::BackendType::SKIA) { + // skia requires alpha component of RGBX textures to be 255. + aAllocFlags = TextureAllocationFlags::ALLOC_CLEAR_BUFFER_WHITE; + } + TextureData* texData = BufferTextureData::Create(aSize, aFormat, aMoz2DBackend, aTextureFlags, aAllocFlags, aAllocator); diff --git a/gfx/layers/client/TextureClient.h b/gfx/layers/client/TextureClient.h index 055689960a..f1f9473aa3 100644 --- a/gfx/layers/client/TextureClient.h +++ b/gfx/layers/client/TextureClient.h @@ -69,15 +69,16 @@ class KeepAlive; */ enum TextureAllocationFlags { - ALLOC_DEFAULT = 0x0, - ALLOC_CLEAR_BUFFER = 0x1, - ALLOC_CLEAR_BUFFER_WHITE = 0x2, - ALLOC_DISALLOW_BUFFERTEXTURECLIENT = 0x4, + ALLOC_DEFAULT = 0, + ALLOC_CLEAR_BUFFER = 1 << 1, // Clear the buffer to whatever is best for the draw target + ALLOC_CLEAR_BUFFER_WHITE = 1 << 2, // explicit all white + ALLOC_CLEAR_BUFFER_BLACK = 1 << 3, // explicit all black + ALLOC_DISALLOW_BUFFERTEXTURECLIENT = 1 << 4, // Allocate the texture for out-of-band content updates. This is mostly for // TextureClientD3D11, which may otherwise choose D3D10 or non-KeyedMutex // surfaces when used on the main thread. - ALLOC_FOR_OUT_OF_BAND_CONTENT = 0x8 + ALLOC_FOR_OUT_OF_BAND_CONTENT = 1 << 5, }; #ifdef XP_WIN diff --git a/gfx/layers/ipc/LayerTransactionParent.h b/gfx/layers/ipc/LayerTransactionParent.h index f1bad89736..59b32b3aba 100644 --- a/gfx/layers/ipc/LayerTransactionParent.h +++ b/gfx/layers/ipc/LayerTransactionParent.h @@ -90,6 +90,8 @@ public: virtual void ReplyRemoveTexture(const OpReplyRemoveTexture& aReply) override; protected: + virtual bool RecvSyncWithCompositor() override { return true; } + virtual bool RecvShutdown() override; virtual bool RecvUpdate(EditArray&& cset, diff --git a/gfx/layers/ipc/PLayerTransaction.ipdl b/gfx/layers/ipc/PLayerTransaction.ipdl index 296278e514..5a2745087e 100644 --- a/gfx/layers/ipc/PLayerTransaction.ipdl +++ b/gfx/layers/ipc/PLayerTransaction.ipdl @@ -121,6 +121,8 @@ parent: async ChildAsyncMessages(AsyncChildMessageData[] aMessages); async Shutdown(); + + sync SyncWithCompositor(); child: async __delete__(); }; diff --git a/gfx/layers/ipc/ShadowLayers.cpp b/gfx/layers/ipc/ShadowLayers.cpp index 6fd94ee82f..15314550f5 100644 --- a/gfx/layers/ipc/ShadowLayers.cpp +++ b/gfx/layers/ipc/ShadowLayers.cpp @@ -39,6 +39,23 @@ class Shmem; namespace layers { +static int sShmemCreationCounter = 0; + +static void ResetShmemCounter() +{ + sShmemCreationCounter = 0; +} + +static void ShmemAllocated(LayerTransactionChild* aProtocol) +{ + sShmemCreationCounter++; + if (sShmemCreationCounter > 256) { + aProtocol->SendSyncWithCompositor(); + ResetShmemCounter(); + MOZ_PERFORMANCE_WARNING("gfx", "The number of shmem allocations is too damn high!"); + } +} + using namespace mozilla::gfx; using namespace mozilla::gl; using namespace mozilla::ipc; @@ -499,6 +516,8 @@ ShadowLayerForwarder::EndTransaction(InfallibleTArray* aReplies, { *aSent = false; + ResetShmemCounter(); + MOZ_ASSERT(aId); PROFILER_LABEL("ShadowLayerForwarder", "EndTransaction", @@ -687,6 +706,8 @@ ShadowLayerForwarder::AllocShmem(size_t aSize, !mShadowManager->IPCOpen()) { return false; } + + ShmemAllocated(mShadowManager); return mShadowManager->AllocShmem(aSize, aType, aShmem); } bool @@ -699,6 +720,7 @@ ShadowLayerForwarder::AllocUnsafeShmem(size_t aSize, !mShadowManager->IPCOpen()) { return false; } + ShmemAllocated(mShadowManager); return mShadowManager->AllocUnsafeShmem(aSize, aType, aShmem); } void diff --git a/gfx/thebes/gfxContext.cpp b/gfx/thebes/gfxContext.cpp index ea8b196117..1aa1859fef 100644 --- a/gfx/thebes/gfxContext.cpp +++ b/gfx/thebes/gfxContext.cpp @@ -112,16 +112,19 @@ already_AddRefed gfxContext::CurrentSurface(gfxFloat *dx, gfxFloat *dy) { if (mDT->GetBackendType() == BackendType::CAIRO) { - cairo_surface_t *s = - (cairo_surface_t*)mDT->GetNativeSurface(NativeSurfaceType::CAIRO_SURFACE); - if (s) { - if (dx && dy) { - double sdx, sdy; - cairo_surface_get_device_offset(s, &sdx, &sdy); - *dx = -CurrentState().deviceOffset.x + sdx; - *dy = -CurrentState().deviceOffset.y + sdy; + cairo_t* ctx = static_cast + (mDT->GetNativeSurface(NativeSurfaceType::CAIRO_CONTEXT)); + if (ctx) { + cairo_surface_t* s = cairo_get_group_target(ctx); + if (s) { + if (dx && dy) { + double sdx, sdy; + cairo_surface_get_device_offset(s, &sdx, &sdy); + *dx = -CurrentState().deviceOffset.x + sdx; + *dy = -CurrentState().deviceOffset.y + sdy; + } + return gfxASurface::Wrap(s); } - return gfxASurface::Wrap(s); } } diff --git a/gfx/thebes/gfxPlatform.cpp b/gfx/thebes/gfxPlatform.cpp index 9fca8c3178..b34c9803ca 100644 --- a/gfx/thebes/gfxPlatform.cpp +++ b/gfx/thebes/gfxPlatform.cpp @@ -898,11 +898,7 @@ gfxPlatform::GetSourceSurfaceForSurface(DrawTarget *aTarget, gfxASurface *aSurfa // readback of aSurface's surface into memory if, for example, aSurface // wraps an xlib cairo surface (which can be important to avoid a major // slowdown). - NativeSurface surf; - surf.mFormat = format; - surf.mType = NativeSurfaceType::CAIRO_SURFACE; - surf.mSurface = aSurface->CairoSurface(); - surf.mSize = aSurface->GetSize(); + // // We return here regardless of whether CreateSourceSurfaceFromNativeSurface // succeeds or not since we don't expect to be able to do any better below // if it fails. @@ -915,7 +911,8 @@ gfxPlatform::GetSourceSurfaceForSurface(DrawTarget *aTarget, gfxASurface *aSurfa // strong reference back to srcBuffer, creating a reference loop and a // memory leak. Not caching is fine since wrapping is cheap enough (no // copying) so we can just wrap again next time we're called. - return aTarget->CreateSourceSurfaceFromNativeSurface(surf); + return Factory::CreateSourceSurfaceForCairoSurface(aSurface->CairoSurface(), + aSurface->GetSize(), format); } RefPtr srcBuffer; @@ -956,18 +953,8 @@ gfxPlatform::GetSourceSurfaceForSurface(DrawTarget *aTarget, gfxASurface *aSurfa // readback), and the OptimizeSourceSurface may well copy again and upload // to the GPU. So, while this code path is rarely hit, hitting it may be // very slow. - NativeSurface surf; - surf.mFormat = format; - surf.mType = NativeSurfaceType::CAIRO_SURFACE; - surf.mSurface = aSurface->CairoSurface(); - surf.mSize = aSurface->GetSize(); - RefPtr drawTarget = - Factory::CreateDrawTarget(BackendType::CAIRO, IntSize(1, 1), format); - if (!drawTarget) { - gfxWarning() << "gfxPlatform::GetSourceSurfaceForSurface failed in CreateDrawTarget"; - return nullptr; - } - srcBuffer = drawTarget->CreateSourceSurfaceFromNativeSurface(surf); + srcBuffer = Factory::CreateSourceSurfaceForCairoSurface(aSurface->CairoSurface(), + aSurface->GetSize(), format); if (srcBuffer) { srcBuffer = aTarget->OptimizeSourceSurface(srcBuffer); } diff --git a/gfx/thebes/gfxWindowsPlatform.cpp b/gfx/thebes/gfxWindowsPlatform.cpp index b4cef3225f..451c683f17 100644 --- a/gfx/thebes/gfxWindowsPlatform.cpp +++ b/gfx/thebes/gfxWindowsPlatform.cpp @@ -86,19 +86,20 @@ DCFromDrawTarget::DCFromDrawTarget(DrawTarget& aDrawTarget) { mDC = nullptr; if (aDrawTarget.GetBackendType() == BackendType::CAIRO) { - cairo_surface_t *surf = (cairo_surface_t*) - aDrawTarget.GetNativeSurface(NativeSurfaceType::CAIRO_SURFACE); - if (surf) { - cairo_surface_type_t surfaceType = cairo_surface_get_type(surf); - if (surfaceType == CAIRO_SURFACE_TYPE_WIN32 || - surfaceType == CAIRO_SURFACE_TYPE_WIN32_PRINTING) { - mDC = cairo_win32_surface_get_dc(surf); - mNeedsRelease = false; - SaveDC(mDC); - cairo_t* ctx = (cairo_t*) - aDrawTarget.GetNativeSurface(NativeSurfaceType::CAIRO_CONTEXT); - cairo_scaled_font_t* scaled = cairo_get_scaled_font(ctx); - cairo_win32_scaled_font_select_font(scaled, mDC); + cairo_t* ctx = static_cast + (aDrawTarget.GetNativeSurface(NativeSurfaceType::CAIRO_CONTEXT)); + if (ctx) { + cairo_surface_t* surf = cairo_get_group_target(ctx); + if (surf) { + cairo_surface_type_t surfaceType = cairo_surface_get_type(surf); + if (surfaceType == CAIRO_SURFACE_TYPE_WIN32 || + surfaceType == CAIRO_SURFACE_TYPE_WIN32_PRINTING) { + mDC = cairo_win32_surface_get_dc(surf); + mNeedsRelease = false; + SaveDC(mDC); + cairo_scaled_font_t* scaled = cairo_get_scaled_font(ctx); + cairo_win32_scaled_font_select_font(scaled, mDC); + } } } } diff --git a/gfx/thebes/gfxXlibNativeRenderer.cpp b/gfx/thebes/gfxXlibNativeRenderer.cpp index b686c4b377..8c36a17bea 100644 --- a/gfx/thebes/gfxXlibNativeRenderer.cpp +++ b/gfx/thebes/gfxXlibNativeRenderer.cpp @@ -531,9 +531,12 @@ gfxXlibNativeRenderer::Draw(gfxContext* ctx, IntSize size, DrawingMethod method; Matrix dtTransform = drawTarget->GetTransform(); gfxPoint deviceTranslation = gfxPoint(dtTransform._31, dtTransform._32); - cairo_surface_t* cairoTarget = static_cast - (drawTarget->GetNativeSurface(NativeSurfaceType::CAIRO_SURFACE)); + cairo_t* cairo = static_cast + (drawTarget->GetNativeSurface(NativeSurfaceType::CAIRO_CONTEXT)); + if (!cairo) + return; + cairo_surface_t* cairoTarget = cairo_get_group_target(cairo); cairo_surface_t* tempXlibSurface = CreateTempXlibSurface(cairoTarget, drawTarget, size, canDrawOverBackground, flags, screen, visual, @@ -572,13 +575,8 @@ gfxXlibNativeRenderer::Draw(gfxContext* ctx, IntSize size, SurfaceFormat::B8G8R8A8 : SurfaceFormat::B8G8R8X8; if (method != eAlphaExtraction) { if (drawTarget) { - NativeSurface native; - native.mFormat = moz2DFormat; - native.mType = NativeSurfaceType::CAIRO_SURFACE; - native.mSurface = tempXlibSurface; - native.mSize = size; RefPtr sourceSurface = - drawTarget->CreateSourceSurfaceFromNativeSurface(native); + Factory::CreateSourceSurfaceForCairoSurface(tempXlibSurface, size, moz2DFormat); if (sourceSurface) { drawTarget->DrawSurface(sourceSurface, Rect(offset.x, offset.y, size.width, size.height), @@ -614,13 +612,9 @@ gfxXlibNativeRenderer::Draw(gfxContext* ctx, IntSize size, gfxASurface* paintSurface = blackImage; if (drawTarget) { - NativeSurface native; - native.mFormat = moz2DFormat; - native.mType = NativeSurfaceType::CAIRO_SURFACE; - native.mSurface = paintSurface->CairoSurface(); - native.mSize = size; RefPtr sourceSurface = - drawTarget->CreateSourceSurfaceFromNativeSurface(native); + Factory::CreateSourceSurfaceForCairoSurface(paintSurface->CairoSurface(), + size, moz2DFormat); if (sourceSurface) { drawTarget->DrawSurface(sourceSurface, Rect(offset.x, offset.y, size.width, size.height), diff --git a/hal/sandbox/PHal.ipdl b/hal/sandbox/PHal.ipdl index f22448f08e..d2594dde88 100644 --- a/hal/sandbox/PHal.ipdl +++ b/hal/sandbox/PHal.ipdl @@ -100,83 +100,83 @@ prio(normal upto urgent) sync protocol PHal { manager PContent; child: - NotifyBatteryChange(BatteryInformation aBatteryInfo); - NotifyNetworkChange(NetworkInformation aNetworkInfo); - NotifyWakeLockChange(WakeLockInformation aWakeLockInfo); - NotifyScreenConfigurationChange(ScreenConfiguration aScreenOrientation); - NotifySwitchChange(SwitchEvent aEvent); - NotifySystemClockChange(int64_t aClockDeltaMS); - NotifySystemTimezoneChange(SystemTimezoneChangeInformation aSystemTimezoneChangeInfo); + async NotifyBatteryChange(BatteryInformation aBatteryInfo); + async NotifyNetworkChange(NetworkInformation aNetworkInfo); + async NotifyWakeLockChange(WakeLockInformation aWakeLockInfo); + async NotifyScreenConfigurationChange(ScreenConfiguration aScreenOrientation); + async NotifySwitchChange(SwitchEvent aEvent); + async NotifySystemClockChange(int64_t aClockDeltaMS); + async NotifySystemTimezoneChange(SystemTimezoneChangeInformation aSystemTimezoneChangeInfo); parent: - Vibrate(uint32_t[] pattern, uint64_t[] id, PBrowser browser); - CancelVibrate(uint64_t[] id, PBrowser browser); + async Vibrate(uint32_t[] pattern, uint64_t[] id, PBrowser browser); + async CancelVibrate(uint64_t[] id, PBrowser browser); - EnableBatteryNotifications(); - DisableBatteryNotifications(); + async EnableBatteryNotifications(); + async DisableBatteryNotifications(); sync GetCurrentBatteryInformation() returns (BatteryInformation aBatteryInfo); - EnableNetworkNotifications(); - DisableNetworkNotifications(); + async EnableNetworkNotifications(); + async DisableNetworkNotifications(); sync GetCurrentNetworkInformation() returns (NetworkInformation aNetworkInfo); sync GetScreenEnabled() returns (bool enabled); - SetScreenEnabled(bool aEnabled); + async SetScreenEnabled(bool aEnabled); sync GetKeyLightEnabled() returns (bool enabled); - SetKeyLightEnabled(bool aEnabled); + async SetKeyLightEnabled(bool aEnabled); sync GetCpuSleepAllowed() returns (bool allowed); - SetCpuSleepAllowed(bool aAllowed); + async SetCpuSleepAllowed(bool aAllowed); sync GetScreenBrightness() returns (double brightness); - SetScreenBrightness(double aBrightness); + async SetScreenBrightness(double aBrightness); - AdjustSystemClock(int64_t aDeltaMilliseconds); - SetTimezone(nsCString aTimezoneSpec); + async AdjustSystemClock(int64_t aDeltaMilliseconds); + async SetTimezone(nsCString aTimezoneSpec); sync GetTimezone() returns (nsCString aTimezoneSpec); sync GetTimezoneOffset() returns (int32_t aTimezoneOffset); - EnableSystemClockChangeNotifications(); - DisableSystemClockChangeNotifications(); - EnableSystemTimezoneChangeNotifications(); - DisableSystemTimezoneChangeNotifications(); + async EnableSystemClockChangeNotifications(); + async DisableSystemClockChangeNotifications(); + async EnableSystemTimezoneChangeNotifications(); + async DisableSystemTimezoneChangeNotifications(); - ModifyWakeLock(nsString aTopic, - WakeLockControl aLockAdjust, - WakeLockControl aHiddenAdjust, - uint64_t aProcessID); - EnableWakeLockNotifications(); - DisableWakeLockNotifications(); + async ModifyWakeLock(nsString aTopic, + WakeLockControl aLockAdjust, + WakeLockControl aHiddenAdjust, + uint64_t aProcessID); + async EnableWakeLockNotifications(); + async DisableWakeLockNotifications(); sync GetWakeLockInfo(nsString aTopic) returns (WakeLockInformation aWakeLockInfo); - EnableScreenConfigurationNotifications(); - DisableScreenConfigurationNotifications(); + async EnableScreenConfigurationNotifications(); + async DisableScreenConfigurationNotifications(); prio(urgent) sync GetCurrentScreenConfiguration() returns (ScreenConfiguration aScreenConfiguration); sync LockScreenOrientation(ScreenOrientationInternal aOrientation) returns (bool allowed); - UnlockScreenOrientation(); + async UnlockScreenOrientation(); - EnableSwitchNotifications(SwitchDevice aDevice); - DisableSwitchNotifications(SwitchDevice aDevice); + async EnableSwitchNotifications(SwitchDevice aDevice); + async DisableSwitchNotifications(SwitchDevice aDevice); sync GetCurrentSwitchState(SwitchDevice aDevice) returns (SwitchState aState); - FactoryReset(nsString aReason); + async FactoryReset(nsString aReason); child: - NotifySensorChange(SensorData aSensorData); + async NotifySensorChange(SensorData aSensorData); parent: - EnableSensorNotifications(SensorType aSensor); - DisableSensorNotifications(SensorType aSensor); + async EnableSensorNotifications(SensorType aSensor); + async DisableSensorNotifications(SensorType aSensor); - __delete__(); + async __delete__(); }; } // namespace hal diff --git a/ipc/glue/PBackground.ipdl b/ipc/glue/PBackground.ipdl index 74af077a26..6c59ba3d7a 100644 --- a/ipc/glue/PBackground.ipdl +++ b/ipc/glue/PBackground.ipdl @@ -56,42 +56,42 @@ sync protocol PBackground parent: // Only called at startup during mochitests to check the basic infrastructure. - PBackgroundTest(nsCString testArg); + async PBackgroundTest(nsCString testArg); - PBackgroundIDBFactory(LoggingInfo loggingInfo); + async PBackgroundIDBFactory(LoggingInfo loggingInfo); - PVsync(); + async PVsync(); - PCameras(); + async PCameras(); - PUDPSocket(OptionalPrincipalInfo pInfo, nsCString filter); - PBroadcastChannel(PrincipalInfo pInfo, nsCString origin, nsString channel, - bool privateBrowsing); + async PUDPSocket(OptionalPrincipalInfo pInfo, nsCString filter); + async PBroadcastChannel(PrincipalInfo pInfo, nsCString origin, nsString channel, + bool privateBrowsing); - PServiceWorkerManager(); + async PServiceWorkerManager(); - ShutdownServiceWorkerRegistrar(); + async ShutdownServiceWorkerRegistrar(); - PCacheStorage(Namespace aNamespace, PrincipalInfo aPrincipalInfo); + async PCacheStorage(Namespace aNamespace, PrincipalInfo aPrincipalInfo); - PMessagePort(nsID uuid, nsID destinationUuid, uint32_t sequenceId); + async PMessagePort(nsID uuid, nsID destinationUuid, uint32_t sequenceId); - PNuwa(); + async PNuwa(); - MessagePortForceClose(nsID uuid, nsID destinationUuid, uint32_t sequenceId); + async MessagePortForceClose(nsID uuid, nsID destinationUuid, uint32_t sequenceId); - PAsmJSCacheEntry(OpenMode openMode, - WriteParams write, - PrincipalInfo principalInfo); + async PAsmJSCacheEntry(OpenMode openMode, + WriteParams write, + PrincipalInfo principalInfo); child: - PCache(); - PCacheStreamControl(); + async PCache(); + async PCacheStreamControl(); both: - PBlob(BlobConstructorParams params); + async PBlob(BlobConstructorParams params); - PFileDescriptorSet(FileDescriptor fd); + async PFileDescriptorSet(FileDescriptor fd); }; } // namespace ipc diff --git a/ipc/glue/PBackgroundTest.ipdl b/ipc/glue/PBackgroundTest.ipdl index c68ac628ca..527cd4ce7d 100644 --- a/ipc/glue/PBackgroundTest.ipdl +++ b/ipc/glue/PBackgroundTest.ipdl @@ -13,7 +13,7 @@ protocol PBackgroundTest manager PBackground; child: - __delete__(nsCString testArg); + async __delete__(nsCString testArg); }; } // namespace ipc diff --git a/ipc/glue/PFileDescriptorSet.ipdl b/ipc/glue/PFileDescriptorSet.ipdl index 4508ce8a6a..ef366494fe 100644 --- a/ipc/glue/PFileDescriptorSet.ipdl +++ b/ipc/glue/PFileDescriptorSet.ipdl @@ -13,9 +13,9 @@ protocol PFileDescriptorSet manager PBackground or PContent; both: - AddFileDescriptor(FileDescriptor fd); + async AddFileDescriptor(FileDescriptor fd); - __delete__(); + async __delete__(); }; } // namespace ipc diff --git a/ipc/glue/ProtocolUtils.h b/ipc/glue/ProtocolUtils.h index 724cd51fbe..88ef93dc28 100644 --- a/ipc/glue/ProtocolUtils.h +++ b/ipc/glue/ProtocolUtils.h @@ -173,7 +173,6 @@ public: virtual Shmem::SharedMemory* CreateSharedMemory( size_t, SharedMemory::SharedMemoryType, bool, int32_t*) = 0; - virtual bool AdoptSharedMemory(Shmem::SharedMemory*, int32_t*) = 0; virtual Shmem::SharedMemory* LookupSharedMemory(int32_t) = 0; virtual bool IsTrackingSharedMemory(Shmem::SharedMemory*) = 0; virtual bool DestroySharedMemory(Shmem&) = 0; diff --git a/ipc/glue/SharedMemory.h b/ipc/glue/SharedMemory.h index 73fc421e35..74f9fc881f 100644 --- a/ipc/glue/SharedMemory.h +++ b/ipc/glue/SharedMemory.h @@ -47,7 +47,6 @@ protected: public: enum SharedMemoryType { TYPE_BASIC, - TYPE_SYSV, TYPE_UNKNOWN }; diff --git a/ipc/glue/SharedMemoryBasic_android.cpp b/ipc/glue/SharedMemoryBasic_android.cpp index eb91794b6e..1f0a5da792 100644 --- a/ipc/glue/SharedMemoryBasic_android.cpp +++ b/ipc/glue/SharedMemoryBasic_android.cpp @@ -130,8 +130,9 @@ SharedMemoryBasic::Unmap() void SharedMemoryBasic::CloseHandle() { - if (mShmFd > 0) { + if (mShmFd != -1) { close(mShmFd); + mShmFd = -1; } } diff --git a/ipc/glue/SharedMemorySysV.h b/ipc/glue/SharedMemorySysV.h deleted file mode 100644 index d853d85c50..0000000000 --- a/ipc/glue/SharedMemorySysV.h +++ /dev/null @@ -1,162 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: sw=2 ts=8 et : - */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_ipc_SharedMemorySysV_h -#define mozilla_ipc_SharedMemorySysV_h - -#if (defined(OS_LINUX) && !defined(ANDROID)) || defined(OS_BSD) - -// SysV shared memory isn't available on Windows, but we define the -// following macro so that #ifdefs are clearer (compared to #ifdef -// OS_LINUX). -#define MOZ_HAVE_SHAREDMEMORYSYSV - -#include "SharedMemory.h" - -#include "nsDebug.h" - -#include -#include -#include -#include -#include -#include - -// -// This is a low-level wrapper around platform shared memory. Don't -// use it directly; use Shmem allocated through IPDL interfaces. -// - -namespace mozilla { -namespace ipc { - - -class SharedMemorySysV : public SharedMemoryCommon -{ -public: - SharedMemorySysV() : - mHandle(-1), - mData(nullptr) - { - } - - virtual ~SharedMemorySysV() - { - shmdt(mData); - mHandle = -1; - mData = nullptr; - } - - virtual bool SetHandle(const Handle& aHandle) override - { - MOZ_ASSERT(mHandle == -1, "already initialized"); - - mHandle = aHandle; - return true; - } - - virtual bool Create(size_t aNbytes) override - { - int id = shmget(IPC_PRIVATE, aNbytes, IPC_CREAT | 0600); - if (id == -1) - return false; - - mHandle = id; - mAllocSize = aNbytes; - Created(aNbytes); - - return Map(aNbytes); - } - - virtual bool Map(size_t nBytes) override - { - // already mapped - if (mData) - return true; - - if (!IsHandleValid(mHandle)) - return false; - - void* mem = shmat(mHandle, nullptr, 0); - if (mem == (void*) -1) { - char warning[256]; - ::snprintf(warning, sizeof(warning)-1, - "shmat(): %s (%d)\n", strerror(errno), errno); - - NS_WARNING(warning); - - return false; - } - - // Mark the handle as deleted so that, should this process go away, the - // segment is cleaned up. - shmctl(mHandle, IPC_RMID, 0); - - mData = mem; - -#ifdef DEBUG - struct shmid_ds info; - if (shmctl(mHandle, IPC_STAT, &info) < 0) - return false; - - MOZ_ASSERT(nBytes <= info.shm_segsz, - "Segment doesn't have enough space!"); -#endif - - Mapped(nBytes); - return true; - } - - virtual void* memory() const override - { - return mData; - } - - virtual SharedMemoryType Type() const override - { - return TYPE_SYSV; - } - - Handle GetHandle() const - { - MOZ_ASSERT(IsHandleValid(mHandle), "invalid handle"); - return mHandle; - } - - static Handle NULLHandle() - { - return -1; - } - - virtual bool IsHandleValid(const Handle& aHandle) const override - { - return aHandle != -1; - } - - virtual void CloseHandle() override - { - } - - virtual bool ShareToProcess(base::ProcessId aProcessId, Handle* aHandle) override { - if (mHandle == -1) { - return false; - } - *aHandle = mHandle; - return true; - } - -private: - Handle mHandle; - void* mData; -}; - -} // namespace ipc -} // namespace mozilla - -#endif // OS_LINUX - -#endif // ifndef mozilla_ipc_SharedMemorySysV_h diff --git a/ipc/glue/Shmem.cpp b/ipc/glue/Shmem.cpp index bb596532e4..2dc4a8a83a 100644 --- a/ipc/glue/Shmem.cpp +++ b/ipc/glue/Shmem.cpp @@ -9,7 +9,6 @@ #include "ProtocolUtils.h" #include "SharedMemoryBasic.h" -#include "SharedMemorySysV.h" #include "mozilla/unused.h" @@ -73,10 +72,6 @@ NewSegment(SharedMemory::SharedMemoryType aType) { if (SharedMemory::TYPE_BASIC == aType) { return new SharedMemoryBasic; -#ifdef MOZ_HAVE_SHAREDMEMORYSYSV - } else if (SharedMemory::TYPE_SYSV == aType) { - return new SharedMemorySysV; -#endif } else { NS_ERROR("unknown Shmem type"); return nullptr; @@ -468,25 +463,6 @@ Shmem::Dealloc(IHadBetterBeIPDLCodeCallingThis_OtherwiseIAmADoodyhead, #endif // if defined(DEBUG) -int -Shmem::GetSysVID() const -{ -#ifdef MOZ_HAVE_SHAREDMEMORYSYSV - AssertInvariants(); - - if (mSegment->Type() != SharedMemory::TYPE_SYSV) { - NS_ERROR("Can't call GetSysVID() on a non-SysV Shmem!"); - return -1; - } - - SharedMemorySysV* seg = static_cast(mSegment); - return seg->GetHandle(); -#else - NS_ERROR("Can't call GetSysVID() with no support for SysV shared memory!"); - return -1; // not reached -#endif -} - IPC::Message* Shmem::ShareTo(IHadBetterBeIPDLCodeCallingThis_OtherwiseIAmADoodyhead, base::ProcessId aTargetPid, diff --git a/ipc/glue/Shmem.h b/ipc/glue/Shmem.h index 6e7cd0f99a..afae28aa04 100644 --- a/ipc/glue/Shmem.h +++ b/ipc/glue/Shmem.h @@ -36,7 +36,7 @@ * means is OS specific.) * * (4a) The child receives the special IPC message, and using the - * |SharedMemory{SysV,Basic}::Handle| it was passed, creates a + * |SharedMemory{Basic}::Handle| it was passed, creates a * |mozilla::ipc::SharedMemory| in the child * process. * @@ -125,13 +125,7 @@ public: bool operator==(const Shmem& aRhs) const { - // need to compare IDs because of AdoptShmem(); two Shmems might - // refer to the same segment but with different IDs for different - // protocol trees. (NB: it's possible for this method to - // spuriously return true if AdoptShmem() gives the same ID for - // two protocol trees, but I don't think that can cause any - // problems since the Shmems really would be indistinguishable.) - return mSegment == aRhs.mSegment && mId == aRhs.mId; + return mSegment == aRhs.mSegment; } // Returns whether this Shmem is writable by you, and thus whether you can @@ -175,8 +169,6 @@ public: return mSize / sizeof(T); } - int GetSysVID() const; - // These shouldn't be used directly, use the IPDL interface instead. id_t Id(IHadBetterBeIPDLCodeCallingThis_OtherwiseIAmADoodyhead) const { return mId; diff --git a/ipc/glue/moz.build b/ipc/glue/moz.build index fd47a99f1a..25db5b17b4 100644 --- a/ipc/glue/moz.build +++ b/ipc/glue/moz.build @@ -31,7 +31,6 @@ EXPORTS.mozilla.ipc += [ 'ScopedXREEmbed.h', 'SharedMemory.h', 'SharedMemoryBasic.h', - 'SharedMemorySysV.h', 'Shmem.h', 'Transport.h', 'URIUtils.h', diff --git a/ipc/ipdl/ipdl/lower.py b/ipc/ipdl/ipdl/lower.py index ebcc9b0c65..d04634df0d 100644 --- a/ipc/ipdl/ipdl/lower.py +++ b/ipc/ipdl/ipdl/lower.py @@ -1120,9 +1120,6 @@ class Protocol(ipdl.ast.Protocol): def createSharedMemory(self): return ExprVar('CreateSharedMemory') - def adoptSharedMemory(self): - return ExprVar('AdoptSharedMemory') - def lookupSharedMemory(self): return ExprVar('LookupSharedMemory') @@ -3674,12 +3671,6 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor): Decl(Type.BOOL, unsafevar.name), Decl(_shmemIdType(ptr=1), idvar.name) ], virtual=1)) - adoptshmem = MethodDefn(MethodDecl( - p.adoptSharedMemory().name, - ret=Type.BOOL, - params=[ Decl(_rawShmemType(ptr=1), rawvar.name), - Decl(_shmemIdType(ptr=1), idvar.name) ], - virtual=1)) lookupshmem = MethodDefn(MethodDecl( p.lookupSharedMemory().name, ret=_rawShmemType(ptr=1), @@ -3796,48 +3787,6 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor): StmtReturn(rawsegmentvar) ]) - # SharedMemory* AdoptSharedMemory(SharedMemory*, id_t*): - # Shmem s(seg, [nextshmemid]); - # Message descriptor; - # if (!s->ShareTo(subprocess, mId, descriptor) || - # !Send(descriptor)) - # return false; - # mShmemMap.Add(seg, id); - # seg->AddRef(); - # return true; - - # XXX this is close to the same code as above, could be - # refactored - descriptorvar = ExprVar('descriptor') - adoptshmem.addstmts([ - StmtDecl( - Decl(_shmemType(), shmemvar.name), - initargs=[ _shmemBackstagePass(), - rawvar, - p.nextShmemIdExpr(self.side) ]), - StmtDecl(Decl(Type('Message', ptr=1), descriptorvar.name), - init=_shmemShareTo(shmemvar, - p.callOtherPid(), - p.routingId())) - ]) - failif = StmtIf(ExprNot(descriptorvar)) - failif.addifstmt(StmtReturn.FALSE) - adoptshmem.addstmt(failif) - - failif = StmtIf(ExprNot(ExprCall( - ExprSelect(p.channelVar(), p.channelSel(), 'Send'), - args=[ descriptorvar ]))) - adoptshmem.addstmt(failif) - - adoptshmem.addstmts([ - StmtExpr(ExprAssn(ExprDeref(idvar), _shmemId(shmemvar))), - StmtExpr(ExprCall( - ExprSelect(p.shmemMapVar(), '.', 'AddWithID'), - args=[ rawvar, ExprDeref(idvar) ])), - StmtExpr(ExprCall(ExprSelect(rawvar, '->', 'AddRef'))), - StmtReturn.TRUE - ]) - # SharedMemory* Lookup(id) lookupshmem.addstmt(StmtReturn(ExprCall( ExprSelect(p.shmemMapVar(), '.', 'Lookup'), @@ -3936,9 +3885,6 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor): createshmem.addstmt(StmtReturn(ExprCall( ExprSelect(p.managerVar(), '->', p.createSharedMemory().name), [ sizevar, typevar, unsafevar, idvar ]))) - adoptshmem.addstmt(StmtReturn(ExprCall( - ExprSelect(p.managerVar(), '->', p.adoptSharedMemory().name), - [ rawvar, idvar ]))) lookupshmem.addstmt(StmtReturn(ExprCall( ExprSelect(p.managerVar(), '->', p.lookupSharedMemory().name), [ idvar ]))) @@ -4091,7 +4037,6 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor): unregister, removemanagee, createshmem, - adoptshmem, lookupshmem, istracking, destroyshmem, @@ -4154,52 +4099,6 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor): # bool AllocUnsafeShmem(size_t size, Type type, Shmem* outmem): allocUnsafeShmem = allocShmemMethod('AllocUnsafeShmem', True) - # bool AdoptShmem(Shmem& aMem, Shmem* aOutmem): - # SharedMemory* rawmem = aMem.Segment(); - # if (!rawmem || IsTrackingSharedMemory(rawmem)) { - # NS_WARNING("bad Shmem"); // or NS_RUNTIMEABORT on child side - # return false; - # } - # id_t id - # if (!AdoptSharedMemory(rawmem, &id)) - # return false - # *aOutmem = Shmem(rawmem, id); - # return true; - adoptShmem = MethodDefn(MethodDecl( - 'AdoptShmem', - params=[ Decl(_shmemType(const=1, ref=1), memvar.name), - Decl(_shmemType(ptr=1), outmemvar.name) ], - ret=Type.BOOL)) - - adoptShmem.addstmt(StmtDecl(Decl(_rawShmemType(ptr=1), rawvar.name), - init=_shmemSegment(memvar))) - ifbad = StmtIf(ExprBinary( - ExprNot(rawvar), '||', - ExprCall(ExprVar('IsTrackingSharedMemory'), args=[ rawvar ]))) - badShmemActions = [] - if (self.side == 'child'): - badShmemActions.append(_runtimeAbort('bad Shmem')); - else: - badShmemActions.append(_printWarningMessage('bad Shmem')); - badShmemActions.append(StmtReturn.FALSE); - ifbad.addifstmts(badShmemActions) - - adoptShmem.addstmt(ifbad) - - ifadoptfails = StmtIf(ExprNot(ExprCall( - p.adoptSharedMemory(), args=[ rawvar, ExprAddrOf(idvar) ]))) - ifadoptfails.addifstmt(StmtReturn.FALSE) - - adoptShmem.addstmts([ - Whitespace.NL, - StmtDecl(Decl(_shmemIdType(), idvar.name)), - ifadoptfails, - Whitespace.NL, - StmtExpr(ExprAssn(ExprDeref(outmemvar), - _shmemCtor(rawvar, idvar))), - StmtReturn.TRUE - ]) - # bool DeallocShmem(Shmem& mem): # bool ok = DestroySharedMemory(mem); ##ifdef DEBUG @@ -4217,6 +4116,12 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor): okvar = ExprVar('ok') ifbad = StmtIf(ExprNot(okvar)) + badShmemActions = [] + if (self.side == 'child'): + badShmemActions.append(_runtimeAbort('bad Shmem')); + else: + badShmemActions.append(_printWarningMessage('bad Shmem')); + badShmemActions.append(StmtReturn.FALSE); ifbad.addifstmts(badShmemActions) deallocShmem.addstmts([ @@ -4235,8 +4140,6 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor): Whitespace.NL, allocUnsafeShmem, Whitespace.NL, - adoptShmem, - Whitespace.NL, deallocShmem, Whitespace.NL ] diff --git a/ipc/ipdl/ipdl/parser.py b/ipc/ipdl/ipdl/parser.py index a0ca80d43b..dc715d5732 100644 --- a/ipc/ipdl/ipdl/parser.py +++ b/ipc/ipdl/ipdl/parser.py @@ -499,7 +499,7 @@ def p_MessageDirectionLabel(p): assert 0 def p_MessageDecl(p): - """MessageDecl : OptionalSendSemanticsQual MessageBody""" + """MessageDecl : SendSemanticsQual MessageBody""" msg = p[2] msg.priority = p[1][0] msg.sendSemantics = p[1][1] @@ -636,12 +636,6 @@ def p_Priority(p): 'urgent': 3} p[0] = prios[p[1]] -def p_OptionalSendSemanticsQual(p): - """OptionalSendSemanticsQual : SendSemanticsQual - | """ - if 2 == len(p): p[0] = p[1] - else: p[0] = [ NORMAL_PRIORITY, ASYNC ] - def p_SendSemanticsQual(p): """SendSemanticsQual : ASYNC | SYNC diff --git a/ipc/ipdl/test/cxx/PTestActorPunning.ipdl b/ipc/ipdl/test/cxx/PTestActorPunning.ipdl index 2c09f30129..54deb277a7 100644 --- a/ipc/ipdl/test/cxx/PTestActorPunning.ipdl +++ b/ipc/ipdl/test/cxx/PTestActorPunning.ipdl @@ -13,13 +13,13 @@ protocol PTestActorPunning { manages PTestActorPunningSub; child: - Start(); + async Start(); parent: - PTestActorPunningPunned(); - PTestActorPunningSub(); - Pun(PTestActorPunningSub a, Bad bad); - __delete__(); + async PTestActorPunningPunned(); + async PTestActorPunningSub(); + async Pun(PTestActorPunningSub a, Bad bad); + async __delete__(); state PING: diff --git a/ipc/ipdl/test/cxx/PTestActorPunningPunned.ipdl b/ipc/ipdl/test/cxx/PTestActorPunningPunned.ipdl index 219dc2b027..a6b875920e 100644 --- a/ipc/ipdl/test/cxx/PTestActorPunningPunned.ipdl +++ b/ipc/ipdl/test/cxx/PTestActorPunningPunned.ipdl @@ -8,7 +8,7 @@ protocol PTestActorPunningPunned { manager PTestActorPunning; child: - __delete__(); + async __delete__(); }; } // namespace mozilla diff --git a/ipc/ipdl/test/cxx/PTestActorPunningSub.ipdl b/ipc/ipdl/test/cxx/PTestActorPunningSub.ipdl index c466d8578e..1441219c38 100644 --- a/ipc/ipdl/test/cxx/PTestActorPunningSub.ipdl +++ b/ipc/ipdl/test/cxx/PTestActorPunningSub.ipdl @@ -8,8 +8,8 @@ protocol PTestActorPunningSub { manager PTestActorPunning; child: - Bad(); - __delete__(); + async Bad(); + async __delete__(); }; } // namespace mozilla diff --git a/ipc/ipdl/test/cxx/PTestBadActor.ipdl b/ipc/ipdl/test/cxx/PTestBadActor.ipdl index 1e9f25e671..841d89ff63 100644 --- a/ipc/ipdl/test/cxx/PTestBadActor.ipdl +++ b/ipc/ipdl/test/cxx/PTestBadActor.ipdl @@ -10,8 +10,8 @@ intr protocol PTestBadActor { manages PTestBadActorSub; child: - PTestBadActorSub(); - __delete__(); + async PTestBadActorSub(); + async __delete__(); }; } // namespace _ipdltest diff --git a/ipc/ipdl/test/cxx/PTestBadActorSub.ipdl b/ipc/ipdl/test/cxx/PTestBadActorSub.ipdl index 6baf777edd..99c78f4ac9 100644 --- a/ipc/ipdl/test/cxx/PTestBadActorSub.ipdl +++ b/ipc/ipdl/test/cxx/PTestBadActorSub.ipdl @@ -10,7 +10,7 @@ child: intr __delete__(); parent: - Ping(); + async Ping(); }; } // namespace _ipdltest diff --git a/ipc/ipdl/test/cxx/PTestBridgeMain.ipdl b/ipc/ipdl/test/cxx/PTestBridgeMain.ipdl index 77b9024bf1..229820b172 100644 --- a/ipc/ipdl/test/cxx/PTestBridgeMain.ipdl +++ b/ipc/ipdl/test/cxx/PTestBridgeMain.ipdl @@ -10,10 +10,10 @@ protocol PTestBridgeMain { child opens PTestBridgeMainSub; child: - Start(); + async Start(); parent: - __delete__(); + async __delete__(); state START: send Start goto DEAD; diff --git a/ipc/ipdl/test/cxx/PTestBridgeMainSub.ipdl b/ipc/ipdl/test/cxx/PTestBridgeMainSub.ipdl index 7f672b56ae..67e50fdd46 100644 --- a/ipc/ipdl/test/cxx/PTestBridgeMainSub.ipdl +++ b/ipc/ipdl/test/cxx/PTestBridgeMainSub.ipdl @@ -10,14 +10,14 @@ intr protocol PTestBridgeMainSub { bridges PTestBridgeMain, PTestBridgeSub; child: - Hi(); + async Hi(); intr HiRpc(); parent: - Hello(); + async Hello(); sync HelloSync(); intr HelloRpc(); - __delete__(); + async __delete__(); state START: recv Hello goto HI; state HI: send Hi goto HELLO_SYNC; diff --git a/ipc/ipdl/test/cxx/PTestBridgeSub.ipdl b/ipc/ipdl/test/cxx/PTestBridgeSub.ipdl index fc2d4f4f00..6c798c84e5 100644 --- a/ipc/ipdl/test/cxx/PTestBridgeSub.ipdl +++ b/ipc/ipdl/test/cxx/PTestBridgeSub.ipdl @@ -6,11 +6,11 @@ namespace _ipdltest { protocol PTestBridgeSub { child: - Ping(); + async Ping(); parent: - BridgeEm(); - __delete__(); + async BridgeEm(); + async __delete__(); state START: send Ping goto BRIDGEEM; diff --git a/ipc/ipdl/test/cxx/PTestCrashCleanup.ipdl b/ipc/ipdl/test/cxx/PTestCrashCleanup.ipdl index d0acda8707..eae428211f 100644 --- a/ipc/ipdl/test/cxx/PTestCrashCleanup.ipdl +++ b/ipc/ipdl/test/cxx/PTestCrashCleanup.ipdl @@ -10,7 +10,7 @@ namespace _ipdltest { intr protocol PTestCrashCleanup { child: intr DIEDIEDIE(); - __delete__(); + async __delete__(); state ALIVE: call DIEDIEDIE goto CRASH; diff --git a/ipc/ipdl/test/cxx/PTestDataStructures.ipdl b/ipc/ipdl/test/cxx/PTestDataStructures.ipdl index b0aacb9913..59bf74652f 100644 --- a/ipc/ipdl/test/cxx/PTestDataStructures.ipdl +++ b/ipc/ipdl/test/cxx/PTestDataStructures.ipdl @@ -10,12 +10,12 @@ sync protocol PTestDataStructures { manages PTestDataStructuresSub; child: - PTestDataStructuresSub(int i); + async PTestDataStructuresSub(int i); - Start(); + async Start(); parent: - __delete__(); + async __delete__(); sync Test1(int[] i1) returns (int[] o1); diff --git a/ipc/ipdl/test/cxx/PTestDesc.ipdl b/ipc/ipdl/test/cxx/PTestDesc.ipdl index fdcc63805b..835c8c62d2 100644 --- a/ipc/ipdl/test/cxx/PTestDesc.ipdl +++ b/ipc/ipdl/test/cxx/PTestDesc.ipdl @@ -9,12 +9,12 @@ intr protocol PTestDesc { child: intr PTestDescSub(nullable PTestDescSubsub dummy); - Test(PTestDescSubsub a); + async Test(PTestDescSubsub a); - __delete__(); + async __delete__(); parent: - Ok(PTestDescSubsub a); + async Ok(PTestDescSubsub a); state CONSTRUCT: diff --git a/ipc/ipdl/test/cxx/PTestDescSub.ipdl b/ipc/ipdl/test/cxx/PTestDescSub.ipdl index c4a70cfcf3..67d4fe1660 100644 --- a/ipc/ipdl/test/cxx/PTestDescSub.ipdl +++ b/ipc/ipdl/test/cxx/PTestDescSub.ipdl @@ -9,7 +9,7 @@ intr protocol PTestDescSub { manages PTestDescSubsub; child: - __delete__(); + async __delete__(); intr PTestDescSubsub(); }; diff --git a/ipc/ipdl/test/cxx/PTestEndpointBridgeMain.ipdl b/ipc/ipdl/test/cxx/PTestEndpointBridgeMain.ipdl index d27757ed12..e8026a0d0f 100644 --- a/ipc/ipdl/test/cxx/PTestEndpointBridgeMain.ipdl +++ b/ipc/ipdl/test/cxx/PTestEndpointBridgeMain.ipdl @@ -12,10 +12,10 @@ protocol PTestEndpointBridgeMain { child spawns PTestEndpointBridgeSub; child: - Start(); + async Start(); parent: - Bridged(Endpoint endpoint); + async Bridged(Endpoint endpoint); }; diff --git a/ipc/ipdl/test/cxx/PTestEndpointBridgeMainSub.ipdl b/ipc/ipdl/test/cxx/PTestEndpointBridgeMainSub.ipdl index d0db5dc170..7364057acc 100644 --- a/ipc/ipdl/test/cxx/PTestEndpointBridgeMainSub.ipdl +++ b/ipc/ipdl/test/cxx/PTestEndpointBridgeMainSub.ipdl @@ -11,11 +11,11 @@ namespace _ipdltest { // they bridge) intr protocol PTestEndpointBridgeMainSub { child: - Hi(); + async Hi(); intr HiRpc(); parent: - Hello(); + async Hello(); sync HelloSync(); intr HelloRpc(); }; diff --git a/ipc/ipdl/test/cxx/PTestEndpointBridgeSub.ipdl b/ipc/ipdl/test/cxx/PTestEndpointBridgeSub.ipdl index 17ba5f2dc2..0bc09b70e1 100644 --- a/ipc/ipdl/test/cxx/PTestEndpointBridgeSub.ipdl +++ b/ipc/ipdl/test/cxx/PTestEndpointBridgeSub.ipdl @@ -9,12 +9,12 @@ namespace _ipdltest { protocol PTestEndpointBridgeSub { child: - Ping(); + async Ping(); - Bridged(Endpoint endpoint); + async Bridged(Endpoint endpoint); parent: - BridgeEm(); + async BridgeEm(); }; diff --git a/ipc/ipdl/test/cxx/PTestEndpointOpens.ipdl b/ipc/ipdl/test/cxx/PTestEndpointOpens.ipdl index 5b87875283..7be99ddd2b 100644 --- a/ipc/ipdl/test/cxx/PTestEndpointOpens.ipdl +++ b/ipc/ipdl/test/cxx/PTestEndpointOpens.ipdl @@ -7,12 +7,12 @@ namespace _ipdltest { protocol PTestEndpointOpens { child: - Start(); + async Start(); parent: - StartSubprotocol(Endpoint endpoint); + async StartSubprotocol(Endpoint endpoint); - __delete__(); + async __delete__(); }; } // namespace mozilla diff --git a/ipc/ipdl/test/cxx/PTestEndpointOpensOpened.ipdl b/ipc/ipdl/test/cxx/PTestEndpointOpensOpened.ipdl index a4bc3f7d01..e14c0cb8a6 100644 --- a/ipc/ipdl/test/cxx/PTestEndpointOpensOpened.ipdl +++ b/ipc/ipdl/test/cxx/PTestEndpointOpensOpened.ipdl @@ -7,14 +7,14 @@ namespace _ipdltest2 { // that opened them) intr protocol PTestEndpointOpensOpened { child: - Hi(); + async Hi(); intr HiRpc(); parent: - Hello(); + async Hello(); sync HelloSync(); intr HelloRpc(); - __delete__(); + async __delete__(); state START: recv Hello goto HI; state HI: send Hi goto HELLO_SYNC; diff --git a/ipc/ipdl/test/cxx/PTestFailedCtor.ipdl b/ipc/ipdl/test/cxx/PTestFailedCtor.ipdl index 1dee1f46d3..94b9da0811 100644 --- a/ipc/ipdl/test/cxx/PTestFailedCtor.ipdl +++ b/ipc/ipdl/test/cxx/PTestFailedCtor.ipdl @@ -7,7 +7,7 @@ intr protocol PTestFailedCtor { manages PTestFailedCtorSub; child: intr PTestFailedCtorSub(); - __delete__(); + async __delete__(); state CONSTRUCT: call PTestFailedCtorSub goto DEAD; diff --git a/ipc/ipdl/test/cxx/PTestFailedCtorSub.ipdl b/ipc/ipdl/test/cxx/PTestFailedCtorSub.ipdl index 42fca11755..b1d18a05fd 100644 --- a/ipc/ipdl/test/cxx/PTestFailedCtorSub.ipdl +++ b/ipc/ipdl/test/cxx/PTestFailedCtorSub.ipdl @@ -11,7 +11,7 @@ intr protocol PTestFailedCtorSub { parent: async PTestFailedCtorSubsub(); sync Sync(); - __delete__(); + async __delete__(); }; } diff --git a/ipc/ipdl/test/cxx/PTestFailedCtorSubsub.ipdl b/ipc/ipdl/test/cxx/PTestFailedCtorSubsub.ipdl index ca272e17b8..654170d976 100644 --- a/ipc/ipdl/test/cxx/PTestFailedCtorSubsub.ipdl +++ b/ipc/ipdl/test/cxx/PTestFailedCtorSubsub.ipdl @@ -8,7 +8,7 @@ intr protocol PTestFailedCtorSubsub { manager PTestFailedCtorSub; parent: - __delete__(); + async __delete__(); }; } diff --git a/ipc/ipdl/test/cxx/PTestHandle.ipdl b/ipc/ipdl/test/cxx/PTestHandle.ipdl index edf8d39637..aad92bae18 100644 --- a/ipc/ipdl/test/cxx/PTestHandle.ipdl +++ b/ipc/ipdl/test/cxx/PTestHandle.ipdl @@ -7,7 +7,7 @@ protocol PTestHandle { manager PTestJSON; child: - __delete__(); + async __delete__(); }; } // namespace mozilla diff --git a/ipc/ipdl/test/cxx/PTestHangs.ipdl b/ipc/ipdl/test/cxx/PTestHangs.ipdl index d32996101d..b1b43fa754 100644 --- a/ipc/ipdl/test/cxx/PTestHangs.ipdl +++ b/ipc/ipdl/test/cxx/PTestHangs.ipdl @@ -12,7 +12,7 @@ parent: child: async Start(); intr Hang(); - __delete__(); + async __delete__(); state START: diff --git a/ipc/ipdl/test/cxx/PTestIndirectProtocolParamFirst.ipdl b/ipc/ipdl/test/cxx/PTestIndirectProtocolParamFirst.ipdl index 4d451e6472..838a701f7e 100644 --- a/ipc/ipdl/test/cxx/PTestIndirectProtocolParamFirst.ipdl +++ b/ipc/ipdl/test/cxx/PTestIndirectProtocolParamFirst.ipdl @@ -12,7 +12,7 @@ sync protocol PTestIndirectProtocolParamFirst { parent: sync Test(IndirectParamUnion actor); both: - __delete__(); + async __delete__(); }; } diff --git a/ipc/ipdl/test/cxx/PTestIndirectProtocolParamManage.ipdl b/ipc/ipdl/test/cxx/PTestIndirectProtocolParamManage.ipdl index a95dc84184..a2fac747fd 100644 --- a/ipc/ipdl/test/cxx/PTestIndirectProtocolParamManage.ipdl +++ b/ipc/ipdl/test/cxx/PTestIndirectProtocolParamManage.ipdl @@ -8,9 +8,9 @@ sync protocol PTestIndirectProtocolParamManage { manages PTestIndirectProtocolParamFirst; manages PTestIndirectProtocolParamSecond; both: - PTestIndirectProtocolParamFirst(); - PTestIndirectProtocolParamSecond(); - __delete__(); + async PTestIndirectProtocolParamFirst(); + async PTestIndirectProtocolParamSecond(); + async __delete__(); }; } diff --git a/ipc/ipdl/test/cxx/PTestIndirectProtocolParamSecond.ipdl b/ipc/ipdl/test/cxx/PTestIndirectProtocolParamSecond.ipdl index a288b5be8a..3eb32949ea 100644 --- a/ipc/ipdl/test/cxx/PTestIndirectProtocolParamSecond.ipdl +++ b/ipc/ipdl/test/cxx/PTestIndirectProtocolParamSecond.ipdl @@ -6,7 +6,7 @@ namespace _ipdltest { sync protocol PTestIndirectProtocolParamSecond { manager PTestIndirectProtocolParamManage; both: - __delete__(); + async __delete__(); }; } diff --git a/ipc/ipdl/test/cxx/PTestInterruptRaces.ipdl b/ipc/ipdl/test/cxx/PTestInterruptRaces.ipdl index 3fb07f1a77..bf71a251c7 100644 --- a/ipc/ipdl/test/cxx/PTestInterruptRaces.ipdl +++ b/ipc/ipdl/test/cxx/PTestInterruptRaces.ipdl @@ -13,11 +13,11 @@ parent: sync GetAnsweredParent() returns (bool answeredParent); child: - Start(); - Wakeup(); - Wakeup3(); + async Start(); + async Wakeup(); + async Wakeup3(); intr Child(); - __delete__(); + async __delete__(); state START: send Start goto TEST1; diff --git a/ipc/ipdl/test/cxx/PTestLatency.ipdl b/ipc/ipdl/test/cxx/PTestLatency.ipdl index 438f2ffa5f..d0c9750d8e 100644 --- a/ipc/ipdl/test/cxx/PTestLatency.ipdl +++ b/ipc/ipdl/test/cxx/PTestLatency.ipdl @@ -6,19 +6,19 @@ namespace _ipdltest { intr protocol PTestLatency { child: - __delete__(); - Ping(); - Ping5(); + async __delete__(); + async Ping(); + async Ping5(); intr Rpc(); - Spam(); + async Spam(); intr Synchro(); - CompressedSpam(uint32_t seqno) compress; + async CompressedSpam(uint32_t seqno) compress; intr Synchro2() returns (uint32_t lastSeqno, uint32_t numMessagesDispatched); parent: - Pong(); - Pong5(); + async Pong(); + async Pong5(); state START: // if the timing resolution is too low, abort the test diff --git a/ipc/ipdl/test/cxx/PTestManyChildAllocs.ipdl b/ipc/ipdl/test/cxx/PTestManyChildAllocs.ipdl index e1a332c795..767af85a20 100644 --- a/ipc/ipdl/test/cxx/PTestManyChildAllocs.ipdl +++ b/ipc/ipdl/test/cxx/PTestManyChildAllocs.ipdl @@ -7,12 +7,12 @@ protocol PTestManyChildAllocs { manages PTestManyChildAllocsSub; child: - Go(); // start allocating + async Go(); // start allocating parent: - Done(); + async Done(); - PTestManyChildAllocsSub(); + async PTestManyChildAllocsSub(); }; } // namespace _ipdltest diff --git a/ipc/ipdl/test/cxx/PTestManyChildAllocsSub.ipdl b/ipc/ipdl/test/cxx/PTestManyChildAllocsSub.ipdl index 44fa7f7f35..e3d9c98df9 100644 --- a/ipc/ipdl/test/cxx/PTestManyChildAllocsSub.ipdl +++ b/ipc/ipdl/test/cxx/PTestManyChildAllocsSub.ipdl @@ -7,10 +7,10 @@ protocol PTestManyChildAllocsSub { manager PTestManyChildAllocs; child: - __delete__(); + async __delete__(); parent: - Hello(); + async Hello(); // empty }; diff --git a/ipc/ipdl/test/cxx/PTestMultiMgrs.ipdl b/ipc/ipdl/test/cxx/PTestMultiMgrs.ipdl index 8c45b397e6..6322bb1a3e 100644 --- a/ipc/ipdl/test/cxx/PTestMultiMgrs.ipdl +++ b/ipc/ipdl/test/cxx/PTestMultiMgrs.ipdl @@ -9,13 +9,13 @@ protocol PTestMultiMgrs { manages PTestMultiMgrsRight; parent: - OK(); + async OK(); child: - PTestMultiMgrsLeft(); - PTestMultiMgrsRight(); - Check(); - __delete__(); + async PTestMultiMgrsLeft(); + async PTestMultiMgrsRight(); + async Check(); + async __delete__(); state START: send PTestMultiMgrsLeft goto CONSTRUCT_RIGHT; diff --git a/ipc/ipdl/test/cxx/PTestMultiMgrsBottom.ipdl b/ipc/ipdl/test/cxx/PTestMultiMgrsBottom.ipdl index 8fbda67da9..9c474f446f 100644 --- a/ipc/ipdl/test/cxx/PTestMultiMgrsBottom.ipdl +++ b/ipc/ipdl/test/cxx/PTestMultiMgrsBottom.ipdl @@ -8,7 +8,7 @@ protocol PTestMultiMgrsBottom { manager PTestMultiMgrsLeft or PTestMultiMgrsRight; child: - __delete__(); + async __delete__(); state DOA: send __delete__; diff --git a/ipc/ipdl/test/cxx/PTestMultiMgrsLeft.ipdl b/ipc/ipdl/test/cxx/PTestMultiMgrsLeft.ipdl index 92454b0f3b..8301762724 100644 --- a/ipc/ipdl/test/cxx/PTestMultiMgrsLeft.ipdl +++ b/ipc/ipdl/test/cxx/PTestMultiMgrsLeft.ipdl @@ -10,8 +10,8 @@ protocol PTestMultiMgrsLeft { manages PTestMultiMgrsBottom; child: - PTestMultiMgrsBottom(); - __delete__(); + async PTestMultiMgrsBottom(); + async __delete__(); state START: send PTestMultiMgrsBottom goto DONE; diff --git a/ipc/ipdl/test/cxx/PTestMultiMgrsRight.ipdl b/ipc/ipdl/test/cxx/PTestMultiMgrsRight.ipdl index 4b004f0fd1..36b0771b77 100644 --- a/ipc/ipdl/test/cxx/PTestMultiMgrsRight.ipdl +++ b/ipc/ipdl/test/cxx/PTestMultiMgrsRight.ipdl @@ -10,8 +10,8 @@ protocol PTestMultiMgrsRight { manages PTestMultiMgrsBottom; child: - PTestMultiMgrsBottom(); - __delete__(); + async PTestMultiMgrsBottom(); + async __delete__(); state START: send PTestMultiMgrsBottom goto DONE; diff --git a/ipc/ipdl/test/cxx/PTestNestedLoops.ipdl b/ipc/ipdl/test/cxx/PTestNestedLoops.ipdl index c8e8c8fe16..f0f067e0b2 100644 --- a/ipc/ipdl/test/cxx/PTestNestedLoops.ipdl +++ b/ipc/ipdl/test/cxx/PTestNestedLoops.ipdl @@ -8,7 +8,7 @@ intr protocol PTestNestedLoops { child: async Start(); intr R(); - __delete__(); + async __delete__(); parent: async Nonce(); diff --git a/ipc/ipdl/test/cxx/PTestOpens.ipdl b/ipc/ipdl/test/cxx/PTestOpens.ipdl index f0562d22ee..2717328faa 100644 --- a/ipc/ipdl/test/cxx/PTestOpens.ipdl +++ b/ipc/ipdl/test/cxx/PTestOpens.ipdl @@ -9,10 +9,10 @@ protocol PTestOpens { child opens PTestOpensOpened; child: - Start(); + async Start(); parent: - __delete__(); + async __delete__(); state START: send Start goto DEAD; diff --git a/ipc/ipdl/test/cxx/PTestOpensOpened.ipdl b/ipc/ipdl/test/cxx/PTestOpensOpened.ipdl index f6cdfeb4ad..04b633634a 100644 --- a/ipc/ipdl/test/cxx/PTestOpensOpened.ipdl +++ b/ipc/ipdl/test/cxx/PTestOpensOpened.ipdl @@ -5,14 +5,14 @@ namespace _ipdltest2 { // that opened them) intr protocol PTestOpensOpened { child: - Hi(); + async Hi(); intr HiRpc(); parent: - Hello(); + async Hello(); sync HelloSync(); intr HelloRpc(); - __delete__(); + async __delete__(); state START: recv Hello goto HI; state HI: send Hi goto HELLO_SYNC; diff --git a/ipc/ipdl/test/cxx/PTestRacyReentry.ipdl b/ipc/ipdl/test/cxx/PTestRacyReentry.ipdl index 6862527398..4dd5fe54fb 100644 --- a/ipc/ipdl/test/cxx/PTestRacyReentry.ipdl +++ b/ipc/ipdl/test/cxx/PTestRacyReentry.ipdl @@ -7,7 +7,7 @@ intr protocol PTestRacyReentry { parent: intr E(); - __delete__(); + async __delete__(); child: async Start(); diff --git a/ipc/ipdl/test/cxx/PTestSanity.ipdl b/ipc/ipdl/test/cxx/PTestSanity.ipdl index e143e3381c..50249b7414 100644 --- a/ipc/ipdl/test/cxx/PTestSanity.ipdl +++ b/ipc/ipdl/test/cxx/PTestSanity.ipdl @@ -6,11 +6,11 @@ namespace _ipdltest { protocol PTestSanity { child: - Ping(int zero, float zeroPtFive, int8_t dummy); - __delete__(); + async Ping(int zero, float zeroPtFive, int8_t dummy); + async __delete__(); parent: - Pong(int one, float zeroPtTwoFive, uint8_t dummy); + async Pong(int one, float zeroPtTwoFive, uint8_t dummy); state PING: diff --git a/ipc/ipdl/test/cxx/PTestSelfManage.ipdl b/ipc/ipdl/test/cxx/PTestSelfManage.ipdl index f0b1e45100..69eb4f55c5 100644 --- a/ipc/ipdl/test/cxx/PTestSelfManage.ipdl +++ b/ipc/ipdl/test/cxx/PTestSelfManage.ipdl @@ -9,8 +9,8 @@ protocol PTestSelfManage { manages PTestSelfManage; child: - PTestSelfManage(); - __delete__(); + async PTestSelfManage(); + async __delete__(); state LIVE: send PTestSelfManage goto LIVE; diff --git a/ipc/ipdl/test/cxx/PTestSelfManageRoot.ipdl b/ipc/ipdl/test/cxx/PTestSelfManageRoot.ipdl index 12dc687bd6..429f8bfc80 100644 --- a/ipc/ipdl/test/cxx/PTestSelfManageRoot.ipdl +++ b/ipc/ipdl/test/cxx/PTestSelfManageRoot.ipdl @@ -8,8 +8,8 @@ protocol PTestSelfManageRoot { manages PTestSelfManage; child: - PTestSelfManage(); - __delete__(); + async PTestSelfManage(); + async __delete__(); state LIVE: send PTestSelfManage goto DEAD; diff --git a/ipc/ipdl/test/cxx/PTestShmem.ipdl b/ipc/ipdl/test/cxx/PTestShmem.ipdl index 19eebaed4f..46a1958e28 100644 --- a/ipc/ipdl/test/cxx/PTestShmem.ipdl +++ b/ipc/ipdl/test/cxx/PTestShmem.ipdl @@ -3,11 +3,11 @@ namespace _ipdltest { protocol PTestShmem { child: - Give(Shmem mem, Shmem unsafe, size_t expectedSize); + async Give(Shmem mem, Shmem unsafe, size_t expectedSize); parent: - Take(Shmem mem, Shmem unsafe, size_t expectedSize); - __delete__(); + async Take(Shmem mem, Shmem unsafe, size_t expectedSize); + async __delete__(); state GIVING: diff --git a/ipc/ipdl/test/cxx/PTestShutdown.ipdl b/ipc/ipdl/test/cxx/PTestShutdown.ipdl index 3f79809d2a..e4d8d0dbeb 100644 --- a/ipc/ipdl/test/cxx/PTestShutdown.ipdl +++ b/ipc/ipdl/test/cxx/PTestShutdown.ipdl @@ -7,19 +7,19 @@ intr protocol PTestShutdown { manages PTestShutdownSub; child: - Start(); + async Start(); parent: // NB: we test deletion and crashing only, not shutdown, because // crashing is the same code path as shutdown, and other IPDL unit // tests check shutdown semantics - PTestShutdownSub(bool expectCrash); + async PTestShutdownSub(bool expectCrash); // Used to synchronize between parent and child, to avoid races // around flushing socket write queues sync Sync(); - __delete__(); + async __delete__(); state START: diff --git a/ipc/ipdl/test/cxx/PTestShutdownSub.ipdl b/ipc/ipdl/test/cxx/PTestShutdownSub.ipdl index 6061d0685a..39d45d9ed8 100644 --- a/ipc/ipdl/test/cxx/PTestShutdownSub.ipdl +++ b/ipc/ipdl/test/cxx/PTestShutdownSub.ipdl @@ -12,7 +12,7 @@ both: intr StackFrame(); parent: - PTestShutdownSubsub(bool expectParentDeleted); + async PTestShutdownSubsub(bool expectParentDeleted); sync __delete__(); state CREATING: diff --git a/ipc/ipdl/test/cxx/PTestStackHooks.ipdl b/ipc/ipdl/test/cxx/PTestStackHooks.ipdl index 3f79d1a5d3..1f3af068fb 100644 --- a/ipc/ipdl/test/cxx/PTestStackHooks.ipdl +++ b/ipc/ipdl/test/cxx/PTestStackHooks.ipdl @@ -18,7 +18,7 @@ both: intr StackFrame(); parent: - __delete__(); + async __delete__(); state START: diff --git a/ipc/ipdl/test/cxx/PTestSyncError.ipdl b/ipc/ipdl/test/cxx/PTestSyncError.ipdl index 0443d7d4d5..05b68ff350 100644 --- a/ipc/ipdl/test/cxx/PTestSyncError.ipdl +++ b/ipc/ipdl/test/cxx/PTestSyncError.ipdl @@ -6,11 +6,11 @@ namespace _ipdltest { sync protocol PTestSyncError { child: - Start(); + async Start(); parent: sync Error(); - __delete__(); + async __delete__(); state START: diff --git a/ipc/ipdl/test/cxx/PTestSyncHang.ipdl b/ipc/ipdl/test/cxx/PTestSyncHang.ipdl index 861825d5c9..eefcf2c5e9 100644 --- a/ipc/ipdl/test/cxx/PTestSyncHang.ipdl +++ b/ipc/ipdl/test/cxx/PTestSyncHang.ipdl @@ -6,7 +6,7 @@ namespace _ipdltest { protocol PTestSyncHang { child: - __delete__(); + async __delete__(); }; diff --git a/ipc/ipdl/test/cxx/PTestSysVShmem.ipdl b/ipc/ipdl/test/cxx/PTestSysVShmem.ipdl deleted file mode 100644 index b5567c7863..0000000000 --- a/ipc/ipdl/test/cxx/PTestSysVShmem.ipdl +++ /dev/null @@ -1,22 +0,0 @@ -namespace mozilla { -namespace _ipdltest { - -protocol PTestSysVShmem { -child: - Give(Shmem mem, Shmem unsafe, size_t expectedSize); - -parent: - Take(Shmem mem, Shmem unsafe, size_t expectedSize); - __delete__(); - - -state GIVING: - send Give goto TAKING; - -state TAKING: - recv Take goto TAKING; - recv __delete__; -}; - -} -} diff --git a/ipc/ipdl/test/cxx/TestSysVShmem.cpp b/ipc/ipdl/test/cxx/TestSysVShmem.cpp deleted file mode 100644 index bd41c1f47a..0000000000 --- a/ipc/ipdl/test/cxx/TestSysVShmem.cpp +++ /dev/null @@ -1,120 +0,0 @@ -#include "TestSysVShmem.h" - -#include "IPDLUnitTests.h" // fail etc. - - -namespace mozilla { -namespace _ipdltest { - -//----------------------------------------------------------------------------- -// Parent - -void -TestSysVShmemParent::Main() -{ - Shmem mem; - Shmem unsafe; - - size_t size = 12345; - if (!AllocShmem(size, SharedMemory::TYPE_SYSV, &mem)) - fail("can't alloc shmem"); - if (!AllocUnsafeShmem(size, SharedMemory::TYPE_SYSV, &unsafe)) - fail("can't alloc shmem"); - - if (0 > mem.GetSysVID()) - fail("invalid shmem ID"); - if (0 > unsafe.GetSysVID()) - fail("invalid shmem ID"); - - if (mem.Size() != size) - fail("shmem is wrong size: expected %lu, got %lu", - size, mem.Size()); - if (unsafe.Size() != size) - fail("shmem is wrong size: expected %lu, got %lu", - size, unsafe.Size()); - - char* ptr = mem.get(); - memcpy(ptr, "Hello!", sizeof("Hello!")); - - char* unsafeptr = unsafe.get(); - memcpy(unsafeptr, "Hello!", sizeof("Hello!")); - - Shmem unsafecopy = unsafe; - if (!SendGive(mem, unsafe, size)) - fail("can't send Give()"); - - // uncomment the following line for a (nondeterministic) surprise! - //char c1 = *ptr; (void)c1; - - // uncomment the following line for a deterministic surprise! - //char c2 = *mem.get(); (void)c2; - - // unsafe shmem gets rid of those checks - char uc1 = *unsafeptr; (void)uc1; - char uc2 = *unsafecopy.get(); (void)uc2; -} - - -bool -TestSysVShmemParent::RecvTake(Shmem&& mem, Shmem&& unsafe, - const size_t& expectedSize) -{ - if (mem.Size() != expectedSize) - fail("expected shmem size %lu, but it has size %lu", - expectedSize, mem.Size()); - if (unsafe.Size() != expectedSize) - fail("expected shmem size %lu, but it has size %lu", - expectedSize, unsafe.Size()); - - if (strcmp(mem.get(), "And yourself!")) - fail("expected message was not written"); - if (strcmp(unsafe.get(), "And yourself!")) - fail("expected message was not written"); - - if (!DeallocShmem(mem)) - fail("DeallocShmem"); - if (!DeallocShmem(unsafe)) - fail("DeallocShmem"); - - Close(); - - return true; -} - -//----------------------------------------------------------------------------- -// Child - -bool -TestSysVShmemChild::RecvGive(Shmem&& mem, Shmem&& unsafe, const size_t& expectedSize) -{ - if (mem.Size() != expectedSize) - fail("expected shmem size %lu, but it has size %lu", - expectedSize, mem.Size()); - if (unsafe.Size() != expectedSize) - fail("expected shmem size %lu, but it has size %lu", - expectedSize, unsafe.Size()); - - if (strcmp(mem.get(), "Hello!")) - fail("expected message was not written"); - if (strcmp(unsafe.get(), "Hello!")) - fail("expected message was not written"); - - char* unsafeptr = unsafe.get(); - - memcpy(mem.get(), "And yourself!", sizeof("And yourself!")); - memcpy(unsafeptr, "And yourself!", sizeof("And yourself!")); - - Shmem unsafecopy = unsafe; - if (!SendTake(mem, unsafe, expectedSize)) - fail("can't send Take()"); - - // these checks also shouldn't fail in the child - char uc1 = *unsafeptr; (void)uc1; - char uc2 = *unsafecopy.get(); (void)uc2; - - return true; -} - - -} // namespace _ipdltest -} // namespace mozilla diff --git a/ipc/ipdl/test/cxx/TestSysVShmem.h b/ipc/ipdl/test/cxx/TestSysVShmem.h deleted file mode 100644 index bbba0a1166..0000000000 --- a/ipc/ipdl/test/cxx/TestSysVShmem.h +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef mozilla__ipdltest_TestSysVShmem_h -#define mozilla__ipdltest_TestSysVShmem_h - -#include "mozilla/_ipdltest/IPDLUnitTests.h" - -#include "mozilla/_ipdltest/PTestSysVShmemParent.h" -#include "mozilla/_ipdltest/PTestSysVShmemChild.h" - -namespace mozilla { -namespace _ipdltest { - - -class TestSysVShmemParent : - public PTestSysVShmemParent -{ -public: - TestSysVShmemParent() { } - virtual ~TestSysVShmemParent() { } - - static bool RunTestInProcesses() { return true; } - static bool RunTestInThreads() { return true; } - - void Main(); - -protected: - virtual bool RecvTake( - Shmem&& mem, - Shmem&& unsafe, - const size_t& expectedSize) override; - - virtual void ActorDestroy(ActorDestroyReason why) override - { - if (NormalShutdown != why) - fail("unexpected destruction!"); - passed("ok"); - QuitParent(); - } -}; - - -class TestSysVShmemChild : - public PTestSysVShmemChild -{ -public: - TestSysVShmemChild() { } - virtual ~TestSysVShmemChild() { } - -protected: - virtual bool RecvGive( - Shmem&& mem, - Shmem&& unsafe, - const size_t& expectedSize) override; - - virtual void ActorDestroy(ActorDestroyReason why) override - { - if (NormalShutdown != why) - fail("unexpected destruction!"); - QuitChild(); - } -}; - - -} // namespace _ipdltest -} // namespace mozilla - -#endif // ifndef mozilla__ipdltest_TestSysVShmem_h diff --git a/ipc/ipdl/test/cxx/moz.build b/ipc/ipdl/test/cxx/moz.build index 42d51de41c..fc04858b42 100644 --- a/ipc/ipdl/test/cxx/moz.build +++ b/ipc/ipdl/test/cxx/moz.build @@ -53,11 +53,6 @@ SOURCES += [ 'TestUrgentHangs.cpp', ] -if CONFIG['OS_ARCH'] == 'Linux': - SOURCES += [ - 'TestSysVShmem.cpp', - ] - SOURCES += [ '!IPDLUnitTests.cpp', 'IPDLUnitTestProcessChild.cpp', @@ -127,7 +122,6 @@ IPDL_SOURCES += [ 'PTestSyncError.ipdl', 'PTestSyncHang.ipdl', 'PTestSyncWakeup.ipdl', - 'PTestSysVShmem.ipdl', 'PTestUrgency.ipdl', 'PTestUrgentHangs.ipdl', ] diff --git a/ipc/ipdl/test/ipdl/error/DeleteRace.ipdl b/ipc/ipdl/test/ipdl/error/DeleteRace.ipdl index 27754e39b6..992bbabdf2 100644 --- a/ipc/ipdl/test/ipdl/error/DeleteRace.ipdl +++ b/ipc/ipdl/test/ipdl/error/DeleteRace.ipdl @@ -3,10 +3,10 @@ // we'll notice, right? protocol DeleteRace { parent: - M1(); + async M1(); child: - __delete__(); + async __delete__(); state START: send __delete__; diff --git a/ipc/ipdl/test/ipdl/error/Nullable.ipdl b/ipc/ipdl/test/ipdl/error/Nullable.ipdl index a7211b0893..cb7097f0e1 100644 --- a/ipc/ipdl/test/ipdl/error/Nullable.ipdl +++ b/ipc/ipdl/test/ipdl/error/Nullable.ipdl @@ -1,4 +1,4 @@ protocol Nullable { child: - Msg(nullable int i); + async Msg(nullable int i); }; diff --git a/ipc/ipdl/test/ipdl/error/Nullable2.ipdl b/ipc/ipdl/test/ipdl/error/Nullable2.ipdl index 4012581403..d572951aea 100644 --- a/ipc/ipdl/test/ipdl/error/Nullable2.ipdl +++ b/ipc/ipdl/test/ipdl/error/Nullable2.ipdl @@ -4,5 +4,5 @@ union Union { protocol Nullable2 { child: - Msg(Union i); + async Msg(Union i); }; diff --git a/ipc/ipdl/test/ipdl/error/actorparam_badState.ipdl b/ipc/ipdl/test/ipdl/error/actorparam_badState.ipdl index f6ac49efac..93b8ba2186 100644 --- a/ipc/ipdl/test/ipdl/error/actorparam_badState.ipdl +++ b/ipc/ipdl/test/ipdl/error/actorparam_badState.ipdl @@ -1,8 +1,8 @@ protocol actorparam_badState { child: - Msg(actorparam_badState:FARGEL p); - __delete__(); + async Msg(actorparam_badState:FARGEL p); + async __delete__(); state S1: send Msg goto S1; diff --git a/ipc/ipdl/test/ipdl/error/bridgesSubprotocol.ipdl b/ipc/ipdl/test/ipdl/error/bridgesSubprotocol.ipdl index 8918a08be1..a07c295d94 100644 --- a/ipc/ipdl/test/ipdl/error/bridgesSubprotocol.ipdl +++ b/ipc/ipdl/test/ipdl/error/bridgesSubprotocol.ipdl @@ -7,7 +7,7 @@ protocol bridgesSubprotocol { child: subprotocolBridges(); - __delete__(); + async __delete__(); state DEAD: send __delete__; }; diff --git a/ipc/ipdl/test/ipdl/error/cyclecheck_Child.ipdl b/ipc/ipdl/test/ipdl/error/cyclecheck_Child.ipdl index b1c15cd90c..2e1b93299a 100644 --- a/ipc/ipdl/test/ipdl/error/cyclecheck_Child.ipdl +++ b/ipc/ipdl/test/ipdl/error/cyclecheck_Child.ipdl @@ -7,6 +7,6 @@ protocol cyclecheck_Child { child: cyclecheck_Grandchild(); - __delete__(); + async __delete__(); }; diff --git a/ipc/ipdl/test/ipdl/error/cyclecheck_Grandchild.ipdl b/ipc/ipdl/test/ipdl/error/cyclecheck_Grandchild.ipdl index f16f2f98b8..d91949de45 100644 --- a/ipc/ipdl/test/ipdl/error/cyclecheck_Grandchild.ipdl +++ b/ipc/ipdl/test/ipdl/error/cyclecheck_Grandchild.ipdl @@ -7,6 +7,6 @@ protocol cyclecheck_Grandchild { child: cyclecheck_Parent(); - __delete__(); + async __delete__(); }; diff --git a/ipc/ipdl/test/ipdl/error/cyclecheck_Parent.ipdl b/ipc/ipdl/test/ipdl/error/cyclecheck_Parent.ipdl index b9f0630e21..666d44c54b 100644 --- a/ipc/ipdl/test/ipdl/error/cyclecheck_Parent.ipdl +++ b/ipc/ipdl/test/ipdl/error/cyclecheck_Parent.ipdl @@ -5,6 +5,6 @@ protocol cyclecheck_Parent { child: cyclecheck_Child(); - __delete__(); + async __delete__(); }; diff --git a/ipc/ipdl/test/ipdl/error/manageSelfToplevel.ipdl b/ipc/ipdl/test/ipdl/error/manageSelfToplevel.ipdl index 9dcf970a83..d708891265 100644 --- a/ipc/ipdl/test/ipdl/error/manageSelfToplevel.ipdl +++ b/ipc/ipdl/test/ipdl/error/manageSelfToplevel.ipdl @@ -4,5 +4,5 @@ protocol manageSelfToplevel { child: manageSelfToplevel(); - __delete__(); + async __delete__(); }; diff --git a/ipc/ipdl/test/ipdl/error/messageNoDirection.ipdl b/ipc/ipdl/test/ipdl/error/messageNoDirection.ipdl index 69a89e7520..a3d9585d4d 100644 --- a/ipc/ipdl/test/ipdl/error/messageNoDirection.ipdl +++ b/ipc/ipdl/test/ipdl/error/messageNoDirection.ipdl @@ -1,3 +1,3 @@ protocol messageNoDirection { - NoDirection(); + async NoDirection(); }; diff --git a/ipc/ipdl/test/ipdl/error/multimanDupMgrs.ipdl b/ipc/ipdl/test/ipdl/error/multimanDupMgrs.ipdl index 7bc9b2cfe4..eb89f77d80 100644 --- a/ipc/ipdl/test/ipdl/error/multimanDupMgrs.ipdl +++ b/ipc/ipdl/test/ipdl/error/multimanDupMgrs.ipdl @@ -4,5 +4,5 @@ protocol multimanDupMgrs { manager multimanDupMgrsMgr or multimanDupMgrsMgr; child: - __delete__(); + async __delete__(); }; diff --git a/ipc/ipdl/test/ipdl/error/multimanDupMgrsMgr.ipdl b/ipc/ipdl/test/ipdl/error/multimanDupMgrsMgr.ipdl index 76248e025f..be8dfbc837 100644 --- a/ipc/ipdl/test/ipdl/error/multimanDupMgrsMgr.ipdl +++ b/ipc/ipdl/test/ipdl/error/multimanDupMgrsMgr.ipdl @@ -5,5 +5,5 @@ protocol multimanDupMgrsMgr { child: multimanDupMgrs(); - __delete__(); + async __delete__(); }; diff --git a/ipc/ipdl/test/ipdl/error/multimanNonexistentMgrs.ipdl b/ipc/ipdl/test/ipdl/error/multimanNonexistentMgrs.ipdl index 80aff22b7a..dd4ba254c9 100644 --- a/ipc/ipdl/test/ipdl/error/multimanNonexistentMgrs.ipdl +++ b/ipc/ipdl/test/ipdl/error/multimanNonexistentMgrs.ipdl @@ -2,6 +2,6 @@ protocol multimanNonexistentManagers { manager Starsky or Hutch; child: - Dummy(); - __delete__(); + async Dummy(); + async __delete__(); }; diff --git a/ipc/ipdl/test/ipdl/error/mutualRecStruct.ipdl b/ipc/ipdl/test/ipdl/error/mutualRecStruct.ipdl index c35282de9a..fd4ee4d18d 100644 --- a/ipc/ipdl/test/ipdl/error/mutualRecStruct.ipdl +++ b/ipc/ipdl/test/ipdl/error/mutualRecStruct.ipdl @@ -15,6 +15,6 @@ struct Z { protocol mutualRecStruct { child: - Test(X x, Y y, Z z); - __delete__(); + async Test(X x, Y y, Z z); + async __delete__(); }; diff --git a/ipc/ipdl/test/ipdl/error/mutualRecStructUnion.ipdl b/ipc/ipdl/test/ipdl/error/mutualRecStructUnion.ipdl index 73ef4470f8..f475952d12 100644 --- a/ipc/ipdl/test/ipdl/error/mutualRecStructUnion.ipdl +++ b/ipc/ipdl/test/ipdl/error/mutualRecStructUnion.ipdl @@ -15,6 +15,6 @@ struct Z { protocol mutualRecStructUnion { child: - Test(X x, Y y, Z z); - __delete__(); + async Test(X x, Y y, Z z); + async __delete__(); }; diff --git a/ipc/ipdl/test/ipdl/error/opensSubprotocol.ipdl b/ipc/ipdl/test/ipdl/error/opensSubprotocol.ipdl index 46e9e42b24..af884a636d 100644 --- a/ipc/ipdl/test/ipdl/error/opensSubprotocol.ipdl +++ b/ipc/ipdl/test/ipdl/error/opensSubprotocol.ipdl @@ -7,7 +7,7 @@ protocol opensSubprotocol { child: subprotocolOpens(); - __delete__(); + async __delete__(); state DEAD: send __delete__; }; diff --git a/ipc/ipdl/test/ipdl/error/race_OverlappingMultiOut.ipdl b/ipc/ipdl/test/ipdl/error/race_OverlappingMultiOut.ipdl index 99e324f72a..8aa8318420 100644 --- a/ipc/ipdl/test/ipdl/error/race_OverlappingMultiOut.ipdl +++ b/ipc/ipdl/test/ipdl/error/race_OverlappingMultiOut.ipdl @@ -1,12 +1,12 @@ protocol race_OverlappingMultiOut { child: - Msg1(); - Msg1_(); - __delete__(); suppressUndeleteableError(); + async Msg1(); + async Msg1_(); + async __delete__(); suppressUndeleteableError(); parent: - Msg2(); - Msg2_(); + async Msg2(); + async Msg2_(); start state _: diff --git a/ipc/ipdl/test/ipdl/error/race_ViolateSameDirection.ipdl b/ipc/ipdl/test/ipdl/error/race_ViolateSameDirection.ipdl index 1b24dd65e9..a1f964ec7c 100644 --- a/ipc/ipdl/test/ipdl/error/race_ViolateSameDirection.ipdl +++ b/ipc/ipdl/test/ipdl/error/race_ViolateSameDirection.ipdl @@ -1,11 +1,12 @@ protocol race_ViolateSameDirection { child: - Msg1(); - Msg1_(); - __delete__(); suppressUndeleteableError(); + async Msg1(); + async Msg1_(); + async __delete__(); + async suppressUndeleteableError(); parent: - Msg2(); - Msg2_(); + async Msg2(); + async Msg2_(); // *** ERROR: state S7 doesn't have all-same-direction start state _: diff --git a/ipc/ipdl/test/ipdl/error/redeclMessage.ipdl b/ipc/ipdl/test/ipdl/error/redeclMessage.ipdl index de3a482eb5..5b2cdcf707 100644 --- a/ipc/ipdl/test/ipdl/error/redeclMessage.ipdl +++ b/ipc/ipdl/test/ipdl/error/redeclMessage.ipdl @@ -3,7 +3,7 @@ protocol redeclMessage { // can't declare two messages with the same name child: - Msg(); - Msg(); + async Msg(); + async Msg(); }; diff --git a/ipc/ipdl/test/ipdl/error/redefState.ipdl b/ipc/ipdl/test/ipdl/error/redefState.ipdl index 7001eb2d44..b9da7212b1 100644 --- a/ipc/ipdl/test/ipdl/error/redefState.ipdl +++ b/ipc/ipdl/test/ipdl/error/redefState.ipdl @@ -2,8 +2,8 @@ protocol redefState { // error: redefining state in state machine child: - Msg(); - __delete__(); + async Msg(); + async __delete__(); state S1: send Msg goto S1; diff --git a/ipc/ipdl/test/ipdl/error/shmem_access_union.ipdl b/ipc/ipdl/test/ipdl/error/shmem_access_union.ipdl index 4170026445..2ed162368d 100644 --- a/ipc/ipdl/test/ipdl/error/shmem_access_union.ipdl +++ b/ipc/ipdl/test/ipdl/error/shmem_access_union.ipdl @@ -4,5 +4,5 @@ union Union { protocol shmem_access_union { child: - Msg(Union u); + async Msg(Union u); }; diff --git a/ipc/ipdl/test/ipdl/error/spawnsSubprotocol.ipdl b/ipc/ipdl/test/ipdl/error/spawnsSubprotocol.ipdl index e5051e9a0e..fc056a2542 100644 --- a/ipc/ipdl/test/ipdl/error/spawnsSubprotocol.ipdl +++ b/ipc/ipdl/test/ipdl/error/spawnsSubprotocol.ipdl @@ -7,7 +7,7 @@ protocol spawnsSubprotocol { child: subprotocolSpawns(); - __delete__(); + async __delete__(); state DEAD: send __delete__; }; diff --git a/ipc/ipdl/test/ipdl/error/trans_WrongDirection.ipdl b/ipc/ipdl/test/ipdl/error/trans_WrongDirection.ipdl index ef129f945c..53c2fd952c 100644 --- a/ipc/ipdl/test/ipdl/error/trans_WrongDirection.ipdl +++ b/ipc/ipdl/test/ipdl/error/trans_WrongDirection.ipdl @@ -1,8 +1,8 @@ protocol trans_WrongDirection { child: - Msg(); - __delete__(); + async Msg(); + async __delete__(); state S1: recv Msg goto S1; diff --git a/ipc/ipdl/test/ipdl/error/trans_WrongDirection2.ipdl b/ipc/ipdl/test/ipdl/error/trans_WrongDirection2.ipdl index c3b737da84..c15dfa5afa 100644 --- a/ipc/ipdl/test/ipdl/error/trans_WrongDirection2.ipdl +++ b/ipc/ipdl/test/ipdl/error/trans_WrongDirection2.ipdl @@ -1,8 +1,8 @@ protocol trans_WrongDirection2 { parent: - Msg(); - __delete__(); + async Msg(); + async __delete__(); state S1: send Msg goto S1; diff --git a/ipc/ipdl/test/ipdl/error/trans_WrongDirection3.ipdl b/ipc/ipdl/test/ipdl/error/trans_WrongDirection3.ipdl index f26e7f5d49..80621ecd18 100644 --- a/ipc/ipdl/test/ipdl/error/trans_WrongDirection3.ipdl +++ b/ipc/ipdl/test/ipdl/error/trans_WrongDirection3.ipdl @@ -2,7 +2,7 @@ sync protocol trans_WrongDirection3 { parent: sync Msg(); - __delete__(); + async __delete__(); state S1: send Msg goto S1; diff --git a/ipc/ipdl/test/ipdl/error/trans_WrongDirection4.ipdl b/ipc/ipdl/test/ipdl/error/trans_WrongDirection4.ipdl index 72ce44b542..c27ad331d2 100644 --- a/ipc/ipdl/test/ipdl/error/trans_WrongDirection4.ipdl +++ b/ipc/ipdl/test/ipdl/error/trans_WrongDirection4.ipdl @@ -2,7 +2,7 @@ intr protocol trans_WrongDirection4 { child: intr Msg(); - __delete__(); + async __delete__(); state S1: answer Msg goto S1; diff --git a/ipc/ipdl/test/ipdl/error/trans_WrongDirection5.ipdl b/ipc/ipdl/test/ipdl/error/trans_WrongDirection5.ipdl index 8fd9e066e7..7997649c8a 100644 --- a/ipc/ipdl/test/ipdl/error/trans_WrongDirection5.ipdl +++ b/ipc/ipdl/test/ipdl/error/trans_WrongDirection5.ipdl @@ -2,7 +2,7 @@ intr protocol trans_WrongDirection5 { parent: intr Msg(); - __delete__() + async __delete__() state S1: call Msg goto S1; diff --git a/ipc/ipdl/test/ipdl/error/trans_WrongName.ipdl b/ipc/ipdl/test/ipdl/error/trans_WrongName.ipdl index 634a0eec8d..a944d58793 100644 --- a/ipc/ipdl/test/ipdl/error/trans_WrongName.ipdl +++ b/ipc/ipdl/test/ipdl/error/trans_WrongName.ipdl @@ -1,8 +1,8 @@ protocol trans_WrongName { child: - Msg(); - __delete__(); + async Msg(); + async __delete__(); state S1: call Msg goto S1; diff --git a/ipc/ipdl/test/ipdl/error/trans_WrongName2.ipdl b/ipc/ipdl/test/ipdl/error/trans_WrongName2.ipdl index 8ee6564074..ece935b7bf 100644 --- a/ipc/ipdl/test/ipdl/error/trans_WrongName2.ipdl +++ b/ipc/ipdl/test/ipdl/error/trans_WrongName2.ipdl @@ -1,8 +1,8 @@ protocol trans_WrongName2 { parent: - Msg(); - __delete__(); + async Msg(); + async __delete__(); state S1: answer Msg goto S1; diff --git a/ipc/ipdl/test/ipdl/error/trans_WrongName3.ipdl b/ipc/ipdl/test/ipdl/error/trans_WrongName3.ipdl index 35b2b319a8..80c54383f0 100644 --- a/ipc/ipdl/test/ipdl/error/trans_WrongName3.ipdl +++ b/ipc/ipdl/test/ipdl/error/trans_WrongName3.ipdl @@ -2,7 +2,7 @@ sync protocol trans_WrongName3 { parent: sync Msg(); - __delete__(); + async __delete__(); state S1: answer Msg goto S1; diff --git a/ipc/ipdl/test/ipdl/error/trans_WrongName4.ipdl b/ipc/ipdl/test/ipdl/error/trans_WrongName4.ipdl index f503d3e91f..f8a9746e4b 100644 --- a/ipc/ipdl/test/ipdl/error/trans_WrongName4.ipdl +++ b/ipc/ipdl/test/ipdl/error/trans_WrongName4.ipdl @@ -2,7 +2,7 @@ intr protocol trans_WrongName4 { child: intr Msg(); - __delete__(); + async __delete__(); state S1: send Msg goto S1; diff --git a/ipc/ipdl/test/ipdl/error/trans_WrongName5.ipdl b/ipc/ipdl/test/ipdl/error/trans_WrongName5.ipdl index 4578151e93..a793905d2c 100644 --- a/ipc/ipdl/test/ipdl/error/trans_WrongName5.ipdl +++ b/ipc/ipdl/test/ipdl/error/trans_WrongName5.ipdl @@ -2,7 +2,7 @@ intr protocol trans_WrongName5 { parent: intr Msg(); - __delete__(); + async __delete__(); state S1: recv Msg goto S1; diff --git a/ipc/ipdl/test/ipdl/error/unreachedDeleteMultiStart.ipdl b/ipc/ipdl/test/ipdl/error/unreachedDeleteMultiStart.ipdl index 2b284f415d..80e28a26d8 100644 --- a/ipc/ipdl/test/ipdl/error/unreachedDeleteMultiStart.ipdl +++ b/ipc/ipdl/test/ipdl/error/unreachedDeleteMultiStart.ipdl @@ -1,6 +1,6 @@ protocol unreachedDeleteMultiStart { child: - M1(); M2(); __delete__(); + async M1(); async M2(); async __delete__(); start state S1: send M1 goto S2; state S2: send __delete__; diff --git a/ipc/ipdl/test/ipdl/ok/Delete.ipdl b/ipc/ipdl/test/ipdl/ok/Delete.ipdl index ef5c8a8841..311d825376 100644 --- a/ipc/ipdl/test/ipdl/ok/Delete.ipdl +++ b/ipc/ipdl/test/ipdl/ok/Delete.ipdl @@ -4,5 +4,5 @@ sync protocol Delete { manages DeleteSub; child: - DeleteSub(); + async DeleteSub(); }; diff --git a/ipc/ipdl/test/ipdl/ok/Nullable.ipdl b/ipc/ipdl/test/ipdl/ok/Nullable.ipdl index 4fd7b043d2..6a81e125d9 100644 --- a/ipc/ipdl/test/ipdl/ok/Nullable.ipdl +++ b/ipc/ipdl/test/ipdl/ok/Nullable.ipdl @@ -5,7 +5,7 @@ union Union { protocol Nullable { child: - Msg(nullable Nullable n); - Msg2(nullable Nullable[] N); - Msg3(Union u); + async Msg(nullable Nullable n); + async Msg2(nullable Nullable[] N); + async Msg3(Union u); }; diff --git a/ipc/ipdl/test/ipdl/ok/Struct.ipdl b/ipc/ipdl/test/ipdl/ok/Struct.ipdl index 5365e292b9..da3ca055a9 100644 --- a/ipc/ipdl/test/ipdl/ok/Struct.ipdl +++ b/ipc/ipdl/test/ipdl/ok/Struct.ipdl @@ -6,5 +6,5 @@ struct S { sync protocol Struct { parent: sync test(S s) returns (S ss); - __delete__(); + async __delete__(); }; diff --git a/ipc/ipdl/test/ipdl/ok/actorparam_state.ipdl b/ipc/ipdl/test/ipdl/ok/actorparam_state.ipdl index df4a672a30..5a3109f5fd 100644 --- a/ipc/ipdl/test/ipdl/ok/actorparam_state.ipdl +++ b/ipc/ipdl/test/ipdl/ok/actorparam_state.ipdl @@ -1,8 +1,8 @@ protocol actorparam_state { child: - Msg(actorparam_state:S1 p); - __delete__(); + async Msg(actorparam_state:S1 p); + async __delete__(); state S1: send Msg goto S1; diff --git a/ipc/ipdl/test/ipdl/ok/array_Basic.ipdl b/ipc/ipdl/test/ipdl/ok/array_Basic.ipdl index 91c3a18cd0..391917708a 100644 --- a/ipc/ipdl/test/ipdl/ok/array_Basic.ipdl +++ b/ipc/ipdl/test/ipdl/ok/array_Basic.ipdl @@ -1,4 +1,4 @@ protocol array_Basic { child: - Msg(int[] array); + async Msg(int[] array); }; diff --git a/ipc/ipdl/test/ipdl/ok/array_OfActors.ipdl b/ipc/ipdl/test/ipdl/ok/array_OfActors.ipdl index 58ce63de43..8d0c7fb6ad 100644 --- a/ipc/ipdl/test/ipdl/ok/array_OfActors.ipdl +++ b/ipc/ipdl/test/ipdl/ok/array_OfActors.ipdl @@ -4,7 +4,7 @@ protocol array_OfActors { manages array_OfActorsSub; child: - Msg(array_OfActorsSub[] p); + async Msg(array_OfActorsSub[] p); array_OfActorsSub(); }; diff --git a/ipc/ipdl/test/ipdl/ok/compositor.ipdl b/ipc/ipdl/test/ipdl/ok/compositor.ipdl index 3ee1dd5910..3f1b163356 100644 --- a/ipc/ipdl/test/ipdl/ok/compositor.ipdl +++ b/ipc/ipdl/test/ipdl/ok/compositor.ipdl @@ -4,7 +4,7 @@ sync protocol compositor { bridges compositor, content; child: - __delete__(); + async __delete__(); state DEAD: send __delete__; diff --git a/ipc/ipdl/test/ipdl/ok/content.ipdl b/ipc/ipdl/test/ipdl/ok/content.ipdl index 33f6fbdfdc..655998bacc 100644 --- a/ipc/ipdl/test/ipdl/ok/content.ipdl +++ b/ipc/ipdl/test/ipdl/ok/content.ipdl @@ -10,7 +10,7 @@ sync protocol content { child opens media; child: - __delete__(); + async __delete__(); state DEAD: send __delete__; diff --git a/ipc/ipdl/test/ipdl/ok/headerProto.ipdl b/ipc/ipdl/test/ipdl/ok/headerProto.ipdl index e2082c8b02..0bccc38344 100644 --- a/ipc/ipdl/test/ipdl/ok/headerProto.ipdl +++ b/ipc/ipdl/test/ipdl/ok/headerProto.ipdl @@ -4,7 +4,7 @@ namespace c { protocol headerProto { child: - __delete__(foo a, baz b, Inner1 c, Inner2 d, X x); + async __delete__(foo a, baz b, Inner1 c, Inner2 d, X x); }; } diff --git a/ipc/ipdl/test/ipdl/ok/intrProtocol.ipdl b/ipc/ipdl/test/ipdl/ok/intrProtocol.ipdl index d0dd8e9bb3..1c9327f013 100644 --- a/ipc/ipdl/test/ipdl/ok/intrProtocol.ipdl +++ b/ipc/ipdl/test/ipdl/ok/intrProtocol.ipdl @@ -2,7 +2,7 @@ intr protocol intrProtocol { // sanity check of Interrupt protocols child: - AsyncMsg(); + async AsyncMsg(); parent: sync SyncMsg(int i) returns (int r); diff --git a/ipc/ipdl/test/ipdl/ok/jetpack.ipdl b/ipc/ipdl/test/ipdl/ok/jetpack.ipdl index 7ce2f8f395..7cdb5c3297 100644 --- a/ipc/ipdl/test/ipdl/ok/jetpack.ipdl +++ b/ipc/ipdl/test/ipdl/ok/jetpack.ipdl @@ -1,6 +1,6 @@ sync protocol jetpack { child: - __delete__(); + async __delete__(); state DEAD: send __delete__; diff --git a/ipc/ipdl/test/ipdl/ok/jetpackContent.ipdl b/ipc/ipdl/test/ipdl/ok/jetpackContent.ipdl index 2957518acd..1e19c541fa 100644 --- a/ipc/ipdl/test/ipdl/ok/jetpackContent.ipdl +++ b/ipc/ipdl/test/ipdl/ok/jetpackContent.ipdl @@ -5,7 +5,7 @@ intr protocol jetpackContent { bridges jetpack, content; child: - __delete__(); + async __delete__(); state DEAD: send __delete__; diff --git a/ipc/ipdl/test/ipdl/ok/manageSelf.ipdl b/ipc/ipdl/test/ipdl/ok/manageSelf.ipdl index e9e2fab14f..b90ad7237a 100644 --- a/ipc/ipdl/test/ipdl/ok/manageSelf.ipdl +++ b/ipc/ipdl/test/ipdl/ok/manageSelf.ipdl @@ -6,5 +6,5 @@ protocol manageSelf { child: manageSelf(); - __delete__(); + async __delete__(); }; diff --git a/ipc/ipdl/test/ipdl/ok/manageSelf_Toplevel.ipdl b/ipc/ipdl/test/ipdl/ok/manageSelf_Toplevel.ipdl index ebbe83b9fc..8788338f39 100644 --- a/ipc/ipdl/test/ipdl/ok/manageSelf_Toplevel.ipdl +++ b/ipc/ipdl/test/ipdl/ok/manageSelf_Toplevel.ipdl @@ -5,5 +5,5 @@ protocol manageSelf_Toplevel { child: manageSelf(); - __delete__(); + async __delete__(); }; diff --git a/ipc/ipdl/test/ipdl/ok/managedProtocol.ipdl b/ipc/ipdl/test/ipdl/ok/managedProtocol.ipdl index e179bc1865..f59ab6651b 100644 --- a/ipc/ipdl/test/ipdl/ok/managedProtocol.ipdl +++ b/ipc/ipdl/test/ipdl/ok/managedProtocol.ipdl @@ -4,5 +4,5 @@ protocol managedProtocol { manager managerProtocol; child: - __delete__(); + async __delete__(); }; diff --git a/ipc/ipdl/test/ipdl/ok/media.ipdl b/ipc/ipdl/test/ipdl/ok/media.ipdl index 3aa209d937..032f7df6f8 100644 --- a/ipc/ipdl/test/ipdl/ok/media.ipdl +++ b/ipc/ipdl/test/ipdl/ok/media.ipdl @@ -1,6 +1,6 @@ sync protocol media { child: - __delete__(); + async __delete__(); state DEAD: send __delete__; diff --git a/ipc/ipdl/test/ipdl/ok/multiManaged.ipdl b/ipc/ipdl/test/ipdl/ok/multiManaged.ipdl index d4ac1d336a..c845d50869 100644 --- a/ipc/ipdl/test/ipdl/ok/multiManaged.ipdl +++ b/ipc/ipdl/test/ipdl/ok/multiManaged.ipdl @@ -5,5 +5,5 @@ protocol multiManaged { manager multiManager1 or multiManager2; child: - __delete__(); + async __delete__(); }; diff --git a/ipc/ipdl/test/ipdl/ok/multipleUsingCxxTypes.ipdl b/ipc/ipdl/test/ipdl/ok/multipleUsingCxxTypes.ipdl index 6bdbd7843e..045d3fa6e3 100644 --- a/ipc/ipdl/test/ipdl/ok/multipleUsingCxxTypes.ipdl +++ b/ipc/ipdl/test/ipdl/ok/multipleUsingCxxTypes.ipdl @@ -3,5 +3,5 @@ using struct mozilla::void_t from "ipc/IPCMessageUtils.h"; protocol multipleUsingCxxTypes { child: - Msg(void_t foo); + async Msg(void_t foo); }; diff --git a/ipc/ipdl/test/ipdl/ok/mutualRecStructUnion.ipdl b/ipc/ipdl/test/ipdl/ok/mutualRecStructUnion.ipdl index 12ced52dae..0891d3e78e 100644 --- a/ipc/ipdl/test/ipdl/ok/mutualRecStructUnion.ipdl +++ b/ipc/ipdl/test/ipdl/ok/mutualRecStructUnion.ipdl @@ -16,6 +16,6 @@ struct Z { protocol mutualRecStructUnion { child: - Test(X x, Y y, Z z); - __delete__(); + async Test(X x, Y y, Z z); + async __delete__(); }; diff --git a/ipc/ipdl/test/ipdl/ok/mutualRecUnion.ipdl b/ipc/ipdl/test/ipdl/ok/mutualRecUnion.ipdl index 88c6f98be7..fcd3649205 100644 --- a/ipc/ipdl/test/ipdl/ok/mutualRecUnion.ipdl +++ b/ipc/ipdl/test/ipdl/ok/mutualRecUnion.ipdl @@ -15,6 +15,6 @@ union Z { protocol mutualRecUnion { child: - Test(X x, Y y, Z z); - __delete__(); + async Test(X x, Y y, Z z); + async __delete__(); }; diff --git a/ipc/ipdl/test/ipdl/ok/namespace_Basic.ipdl b/ipc/ipdl/test/ipdl/ok/namespace_Basic.ipdl index cac963fbaf..4eee5ffd14 100644 --- a/ipc/ipdl/test/ipdl/ok/namespace_Basic.ipdl +++ b/ipc/ipdl/test/ipdl/ok/namespace_Basic.ipdl @@ -5,7 +5,7 @@ namespace basic { protocol namespace_Basic { child: - Msg(); + async Msg(); }; diff --git a/ipc/ipdl/test/ipdl/ok/noRedeclCrossMessage.ipdl b/ipc/ipdl/test/ipdl/ok/noRedeclCrossMessage.ipdl index 4b47dab6ff..578ac82d8c 100644 --- a/ipc/ipdl/test/ipdl/ok/noRedeclCrossMessage.ipdl +++ b/ipc/ipdl/test/ipdl/ok/noRedeclCrossMessage.ipdl @@ -3,7 +3,7 @@ protocol noRedeclCrossMessage { // each message has its own scope for param/return names child: - Msg1(int f); - Msg2(int f); + async Msg1(int f); + async Msg2(int f); }; diff --git a/ipc/ipdl/test/ipdl/ok/plugin.ipdl b/ipc/ipdl/test/ipdl/ok/plugin.ipdl index c8d218fffe..b1e2d24a97 100644 --- a/ipc/ipdl/test/ipdl/ok/plugin.ipdl +++ b/ipc/ipdl/test/ipdl/ok/plugin.ipdl @@ -1,6 +1,6 @@ intr protocol plugin { child: - __delete__(); + async __delete__(); state DEAD: send __delete__; diff --git a/ipc/ipdl/test/ipdl/ok/race_DiamondRule1.ipdl b/ipc/ipdl/test/ipdl/ok/race_DiamondRule1.ipdl index 5b3012a47f..cc1a8b16af 100644 --- a/ipc/ipdl/test/ipdl/ok/race_DiamondRule1.ipdl +++ b/ipc/ipdl/test/ipdl/ok/race_DiamondRule1.ipdl @@ -1,11 +1,11 @@ protocol race_DiamondRule1 { child: - Msg1(); - Msg1_(); + async Msg1(); + async Msg1_(); parent: - Msg2(); - Msg2_(); + async Msg2(); + async Msg2_(); // OK: this state machine is one of the simplest that follows the // Diamond Rule diff --git a/ipc/ipdl/test/ipdl/ok/race_KitchenSink.ipdl b/ipc/ipdl/test/ipdl/ok/race_KitchenSink.ipdl index 3d6304c943..55d674adad 100644 --- a/ipc/ipdl/test/ipdl/ok/race_KitchenSink.ipdl +++ b/ipc/ipdl/test/ipdl/ok/race_KitchenSink.ipdl @@ -1,10 +1,10 @@ protocol race_KitchenSink { child: - Msg1(); - Msg1_(); + async Msg1(); + async Msg1_(); parent: - Msg2(); - Msg2_(); + async Msg2(); + async Msg2_(); // concatenation of a few other state machines, should be OK diff --git a/ipc/ipdl/test/ipdl/ok/race_MultiOut.ipdl b/ipc/ipdl/test/ipdl/ok/race_MultiOut.ipdl index 6925f53ef4..80cffd91c1 100644 --- a/ipc/ipdl/test/ipdl/ok/race_MultiOut.ipdl +++ b/ipc/ipdl/test/ipdl/ok/race_MultiOut.ipdl @@ -1,10 +1,10 @@ protocol race_MultiOut { child: - Msg1(); - Msg1_(); + async Msg1(); + async Msg1_(); parent: - Msg2(); - Msg2_(); + async Msg2(); + async Msg2_(); start state S15: send Msg1 goto S16 or S17; diff --git a/ipc/ipdl/test/ipdl/ok/race_Stateless.ipdl b/ipc/ipdl/test/ipdl/ok/race_Stateless.ipdl index 4d757c9245..6cffe1e7c4 100644 --- a/ipc/ipdl/test/ipdl/ok/race_Stateless.ipdl +++ b/ipc/ipdl/test/ipdl/ok/race_Stateless.ipdl @@ -2,11 +2,11 @@ protocol race_Stateless { // manages Child; child: - Msg1(); - Msg1_(); + async Msg1(); + async Msg1_(); parent: - Msg2(); - Msg2_(); + async Msg2(); + async Msg2_(); // OK: this is trivial stateless protocol, so race-free "by definition" diff --git a/ipc/ipdl/test/ipdl/ok/selfRecUnion.ipdl b/ipc/ipdl/test/ipdl/ok/selfRecUnion.ipdl index 3c49048f52..70f04602c0 100644 --- a/ipc/ipdl/test/ipdl/ok/selfRecUnion.ipdl +++ b/ipc/ipdl/test/ipdl/ok/selfRecUnion.ipdl @@ -6,6 +6,6 @@ union R { protocol selfRecUnion { child: - Test(R r); - __delete__(); + async Test(R r); + async __delete__(); }; diff --git a/ipc/ipdl/test/ipdl/ok/shmem.ipdl b/ipc/ipdl/test/ipdl/ok/shmem.ipdl index f8ce9fee03..8bc44010b9 100644 --- a/ipc/ipdl/test/ipdl/ok/shmem.ipdl +++ b/ipc/ipdl/test/ipdl/ok/shmem.ipdl @@ -5,7 +5,7 @@ union Foo { intr protocol shmem { parent: - Msg(Shmem s, Foo f); + async Msg(Shmem s, Foo f); sync SyncMsg(Shmem s, Foo f) returns (Shmem t, Foo g); intr InterruptMsg(Shmem s, Foo f) diff --git a/ipc/ipdl/test/ipdl/ok/syncProtocol.ipdl b/ipc/ipdl/test/ipdl/ok/syncProtocol.ipdl index a064cdf54d..cfe7760e63 100644 --- a/ipc/ipdl/test/ipdl/ok/syncProtocol.ipdl +++ b/ipc/ipdl/test/ipdl/ok/syncProtocol.ipdl @@ -3,7 +3,7 @@ sync protocol syncProtocol { // sanity check of sync protocols child: - AsyncMsg(); + async AsyncMsg(); parent: sync SyncMsg() returns (int i); diff --git a/ipc/ipdl/test/ipdl/ok/threeDirections.ipdl b/ipc/ipdl/test/ipdl/ok/threeDirections.ipdl index 40c418aeb4..c06f9d56f0 100644 --- a/ipc/ipdl/test/ipdl/ok/threeDirections.ipdl +++ b/ipc/ipdl/test/ipdl/ok/threeDirections.ipdl @@ -2,12 +2,12 @@ protocol threeDirections { // sanity check that the three direction specifiers are being accepted child: - ChildMsg(); + async ChildMsg(); parent: - ParentMsg(); + async ParentMsg(); both: - BothMsg(); + async BothMsg(); }; diff --git a/ipc/ipdl/test/ipdl/ok/union_Namespaced.ipdl b/ipc/ipdl/test/ipdl/ok/union_Namespaced.ipdl index 0bf345771c..02f86f9ded 100644 --- a/ipc/ipdl/test/ipdl/ok/union_Namespaced.ipdl +++ b/ipc/ipdl/test/ipdl/ok/union_Namespaced.ipdl @@ -12,7 +12,7 @@ namespace puppies { protocol union_Namespaced { child: - Msg(Socks s); + async Msg(Socks s); }; } // namespace puppies diff --git a/ipc/testshell/PTestShell.ipdl b/ipc/testshell/PTestShell.ipdl index 26ed4fe74d..db4d7eedcb 100644 --- a/ipc/testshell/PTestShell.ipdl +++ b/ipc/testshell/PTestShell.ipdl @@ -16,11 +16,11 @@ async protocol PTestShell manages PTestShellCommand; child: - __delete__(); + async __delete__(); - ExecuteCommand(nsString aCommand); + async ExecuteCommand(nsString aCommand); - PTestShellCommand(nsString aCommand); + async PTestShellCommand(nsString aCommand); }; } // namespace ipc diff --git a/ipc/testshell/PTestShellCommand.ipdl b/ipc/testshell/PTestShellCommand.ipdl index 47bef5db79..fb6efd99fd 100644 --- a/ipc/testshell/PTestShellCommand.ipdl +++ b/ipc/testshell/PTestShellCommand.ipdl @@ -13,7 +13,7 @@ protocol PTestShellCommand manager PTestShell; parent: - __delete__(nsString aResponse); + async __delete__(nsString aResponse); }; } // namespace ipc diff --git a/js/src/builtin/WeakMapObject.cpp b/js/src/builtin/WeakMapObject.cpp index 7da1347f71..d9caeec08c 100644 --- a/js/src/builtin/WeakMapObject.cpp +++ b/js/src/builtin/WeakMapObject.cpp @@ -49,27 +49,6 @@ js::WeakMap_has(JSContext* cx, unsigned argc, Value* vp) return CallNonGenericMethod(cx, args); } -MOZ_ALWAYS_INLINE bool -WeakMap_clear_impl(JSContext* cx, const CallArgs& args) -{ - MOZ_ASSERT(IsWeakMap(args.thisv())); - - // We can't js_delete the weakmap because the data gathered during GC is - // used by the Cycle Collector. - if (ObjectValueMap* map = args.thisv().toObject().as().getMap()) - map->clear(); - - args.rval().setUndefined(); - return true; -} - -bool -js::WeakMap_clear(JSContext* cx, unsigned argc, Value* vp) -{ - CallArgs args = CallArgsFromVp(argc, vp); - return CallNonGenericMethod(cx, args); -} - MOZ_ALWAYS_INLINE bool WeakMap_get_impl(JSContext* cx, const CallArgs& args) { @@ -427,7 +406,6 @@ static const JSFunctionSpec weak_map_methods[] = { JS_FN("get", WeakMap_get, 1, 0), JS_FN("delete", WeakMap_delete, 1, 0), JS_FN("set", WeakMap_set, 2, 0), - JS_FN("clear", WeakMap_clear, 0, 0), JS_FS_END }; diff --git a/js/src/builtin/WeakSet.js b/js/src/builtin/WeakSet.js index 4152958488..76ec0e8b1f 100644 --- a/js/src/builtin/WeakSet.js +++ b/js/src/builtin/WeakSet.js @@ -25,26 +25,7 @@ function WeakSet_add(value) { return S; } -// 23.4.3.2 -function WeakSet_clear() { - // Step 1-3. - var S = this; - if (!IsObject(S) || !IsWeakSet(S)) - return callFunction(CallWeakSetMethodIfWrapped, this, "WeakSet_clear"); - - // Step 4. - let entries = UnsafeGetReservedSlot(this, WEAKSET_MAP_SLOT); - if (!entries) - ThrowTypeError(JSMSG_INCOMPATIBLE_PROTO, "WeakSet", "clear", typeof S); - - // Step 5. - callFunction(std_WeakMap_clear, entries); - - // Step 6. - return undefined; -} - -// 23.4.3.4 +// 23.4.3.3 function WeakSet_delete(value) { // Steps 1-3. var S = this; @@ -64,7 +45,7 @@ function WeakSet_delete(value) { return callFunction(std_WeakMap_delete, entries, value); } -// 23.4.3.5 +// 23.4.3.4 function WeakSet_has(value) { // Steps 1-3. var S = this; diff --git a/js/src/builtin/WeakSetObject.cpp b/js/src/builtin/WeakSetObject.cpp index 56486ea25d..9b66be7c56 100644 --- a/js/src/builtin/WeakSetObject.cpp +++ b/js/src/builtin/WeakSetObject.cpp @@ -34,7 +34,6 @@ const JSPropertySpec WeakSetObject::properties[] = { const JSFunctionSpec WeakSetObject::methods[] = { JS_SELF_HOSTED_FN("add", "WeakSet_add", 1, 0), - JS_SELF_HOSTED_FN("clear", "WeakSet_clear", 0, 0), JS_SELF_HOSTED_FN("delete", "WeakSet_delete", 1, 0), JS_SELF_HOSTED_FN("has", "WeakSet_has", 1, 0), JS_FS_END diff --git a/js/src/jit-test/tests/collections/WeakMap-clear.js b/js/src/jit-test/tests/collections/WeakMap-clear.js deleted file mode 100644 index 7ceaa6277f..0000000000 --- a/js/src/jit-test/tests/collections/WeakMap-clear.js +++ /dev/null @@ -1,42 +0,0 @@ -var key = {}; -var wm = new WeakMap(); - -assertEq(wm.has(key), false); -// Clearing an already empty WeakMap -wm.clear(); -assertEq(wm.has(key), false); - -// Clearing a WeakMap with a live key -wm.set(key, 42); -assertEq(wm.has(key), true); -wm.clear(); -assertEq(wm.has(key), false); - -// Clearing a WeakMap with keys turned to garbage -wm.set(key, {}); -for (var i = 0; i < 10; i++) - wm.set({}, {}); -assertEq(wm.has(key), true); -wm.clear(); -assertEq(wm.has(key), false); - -// Clearing a WeakMap with keys turned to garbage and after doing a GC -wm.set(key, {}); -for (var i = 0; i < 10; i++) - wm.set({}, {}); -assertEq(wm.has(key), true); -gc(); -assertEq(wm.has(key), true); -wm.clear(); -assertEq(wm.has(key), false); - -// More testing when the key is no longer live -wm.set(key, {}); -key = null; -wm.clear(); -gc(); -var key2 = {}; -wm.set(key2, {}); -key2 = null; -gc(); -wm.clear(); diff --git a/js/src/jit-test/tests/collections/WeakMap-surfaces.js b/js/src/jit-test/tests/collections/WeakMap-surfaces.js index 5feae5f7da..0eee2f2cd6 100644 --- a/js/src/jit-test/tests/collections/WeakMap-surfaces.js +++ b/js/src/jit-test/tests/collections/WeakMap-surfaces.js @@ -30,4 +30,3 @@ checkMethod("get", 1); checkMethod("has", 1); checkMethod("set", 2); checkMethod("delete", 1); -checkMethod("clear", 0); diff --git a/js/src/jit-test/tests/collections/WeakSet-clear.js b/js/src/jit-test/tests/collections/WeakSet-clear.js deleted file mode 100644 index 58ea8d7386..0000000000 --- a/js/src/jit-test/tests/collections/WeakSet-clear.js +++ /dev/null @@ -1,50 +0,0 @@ -var value = {}; -var ws = new WeakSet(); - -assertEq(ws.has(value), false); -// Clearing an already empty WeakSet -assertEq(ws.clear(), undefined); -assertEq(ws.has(value), false); - -// Clearing a WeakSet with a live value -ws.add(value); -assertEq(ws.has(value), true); -ws.clear(); -assertEq(ws.has(value), false); - -// Clearing a WeakSet with values turned to garbage -ws.add(value); -for (var i = 0; i < 10; i++) - ws.add({}); -assertEq(ws.has(value), true); -ws.clear(); -assertEq(ws.has(value), false); - -// Clearing a WeakSet with values turned to garbage and after doing a GC -ws.add(value); -for (var i = 0; i < 10; i++) - ws.add({}); -assertEq(ws.has(value), true); -gc(); -assertEq(ws.has(value), true); -ws.clear(); -assertEq(ws.has(value), false); - -// More testing when the value is no longer live -ws.add(value); -value = null; -ws.clear(); -gc(); -var value2 = {}; -ws.add(value2); -value2 = null; -gc(); -ws.clear(); - -// Clearing a cross-compartment WeakSet with a live value -ws = new (newGlobal().WeakSet); -value = {}; -WeakSet.prototype.add.call(ws, value); -assertEq(WeakSet.prototype.has.call(ws, value), true); -WeakSet.prototype.clear.call(ws); -assertEq(WeakSet.prototype.has.call(ws, value), false); diff --git a/js/src/jit-test/tests/collections/WeakSet-delete.js b/js/src/jit-test/tests/collections/WeakSet-delete.js index 3cc61c9e24..0309ad7131 100644 --- a/js/src/jit-test/tests/collections/WeakSet-delete.js +++ b/js/src/jit-test/tests/collections/WeakSet-delete.js @@ -10,13 +10,6 @@ assertEq(ws.has(value), true); assertEq(ws.delete(value), true); assertEq(ws.has(value), false); -// Delete after clear -ws.add(value); -assertEq(ws.has(value), true); -ws.clear(); -assertEq(ws.delete(value), false); -assertEq(ws.has(value), false); - // Delete non-empty for (var i = 0; i < 10; i++) ws.add({}); diff --git a/js/src/jit-test/tests/collections/WeakSet-surface.js b/js/src/jit-test/tests/collections/WeakSet-surface.js index 1e3f155c58..83c795fd98 100644 --- a/js/src/jit-test/tests/collections/WeakSet-surface.js +++ b/js/src/jit-test/tests/collections/WeakSet-surface.js @@ -29,4 +29,3 @@ function checkMethod(name, arity) { checkMethod("has", 1); checkMethod("add", 1); checkMethod("delete", 1); -checkMethod("clear", 0); diff --git a/js/src/jsweakmap.h b/js/src/jsweakmap.h index 99446a4171..89809eae17 100644 --- a/js/src/jsweakmap.h +++ b/js/src/jsweakmap.h @@ -368,9 +368,6 @@ WeakMap_set(JSContext* cx, unsigned argc, Value* vp); extern bool WeakMap_delete(JSContext* cx, unsigned argc, Value* vp); -extern bool -WeakMap_clear(JSContext* cx, unsigned argc, Value* vp); - extern JSObject* InitWeakMapClass(JSContext* cx, HandleObject obj); diff --git a/js/src/vm/SelfHosting.cpp b/js/src/vm/SelfHosting.cpp index 13c84ce38b..7c752fa14c 100644 --- a/js/src/vm/SelfHosting.cpp +++ b/js/src/vm/SelfHosting.cpp @@ -1593,7 +1593,6 @@ static const JSFunctionSpec intrinsic_functions[] = { JS_FN("std_WeakMap_get", WeakMap_get, 2,0), JS_FN("std_WeakMap_set", WeakMap_set, 2,0), JS_FN("std_WeakMap_delete", WeakMap_delete, 1,0), - JS_FN("std_WeakMap_clear", WeakMap_clear, 0,0), JS_FN("std_SIMD_Int8x16_extractLane", simd_int8x16_extractLane, 2,0), JS_FN("std_SIMD_Int16x8_extractLane", simd_int16x8_extractLane, 2,0), diff --git a/layout/base/RestyleManager.cpp b/layout/base/RestyleManager.cpp index 2ecdc5dac5..8784c95748 100644 --- a/layout/base/RestyleManager.cpp +++ b/layout/base/RestyleManager.cpp @@ -223,13 +223,13 @@ GetFrameForChildrenOnlyTransformHint(nsIFrame *aFrame) // This happens if the root- is fixed positioned, in which case we // can't use aFrame->GetContent() to find the primary frame, since // GetContent() returns nullptr for ViewportFrame. - aFrame = aFrame->GetFirstPrincipalChild(); + aFrame = aFrame->PrincipalChildList().FirstChild(); } // For an nsHTMLScrollFrame, this will get the SVG frame that has the // children-only transforms: aFrame = aFrame->GetContent()->GetPrimaryFrame(); if (aFrame->GetType() == nsGkAtoms::svgOuterSVGFrame) { - aFrame = aFrame->GetFirstPrincipalChild(); + aFrame = aFrame->PrincipalChildList().FirstChild(); MOZ_ASSERT(aFrame->GetType() == nsGkAtoms::svgOuterSVGAnonChildFrame, "Where is the nsSVGOuterSVGFrame's anon child??"); } @@ -327,7 +327,7 @@ DoApplyRenderingChangeToTree(nsIFrame* aFrame, if (aChange & nsChangeHint_ChildrenOnlyTransform) { needInvalidatingPaint = true; nsIFrame* childFrame = - GetFrameForChildrenOnlyTransformHint(aFrame)->GetFirstPrincipalChild(); + GetFrameForChildrenOnlyTransformHint(aFrame)->PrincipalChildList().FirstChild(); for ( ; childFrame; childFrame = childFrame->GetNextSibling()) { ActiveLayerTracker::NotifyRestyle(childFrame, eCSSProperty_transform); } @@ -903,7 +903,7 @@ RestyleManager::ProcessRestyledFrames(nsStyleChangeList& aChangeList) if (hint & nsChangeHint_ChildrenOnlyTransform) { // The overflow areas of the child frames need to be updated: nsIFrame* hintFrame = GetFrameForChildrenOnlyTransformHint(frame); - nsIFrame* childFrame = hintFrame->GetFirstPrincipalChild(); + nsIFrame* childFrame = hintFrame->PrincipalChildList().FirstChild(); NS_ASSERTION(!nsLayoutUtils::GetNextContinuationOrIBSplitSibling(frame), "SVG frames should not have continuations " "or ib-split siblings"); @@ -2331,7 +2331,8 @@ GetNextContinuationWithSameStyle(nsIFrame* aFrame, nsresult RestyleManager::ReparentStyleContext(nsIFrame* aFrame) { - if (nsGkAtoms::placeholderFrame == aFrame->GetType()) { + nsIAtom* frameType = aFrame->GetType(); + if (frameType == nsGkAtoms::placeholderFrame) { // Also reparent the out-of-flow and all its continuations. nsIFrame* outOfFlow = nsPlaceholderFrame::GetRealFrameForPlaceholder(aFrame); @@ -2339,6 +2340,10 @@ RestyleManager::ReparentStyleContext(nsIFrame* aFrame) do { ReparentStyleContext(outOfFlow); } while ((outOfFlow = outOfFlow->GetNextContinuation())); + } else if (frameType == nsGkAtoms::backdropFrame) { + // Style context of backdrop frame has no parent style context, and + // thus we do not need to reparent it. + return NS_OK; } // DO NOT verify the style tree before reparenting. The frame diff --git a/layout/base/nsBidiPresUtils.cpp b/layout/base/nsBidiPresUtils.cpp index 4573c2099d..6a75e48925 100644 --- a/layout/base/nsBidiPresUtils.cpp +++ b/layout/base/nsBidiPresUtils.cpp @@ -464,7 +464,7 @@ IsBidiSplittable(nsIFrame* aFrame) static bool IsBidiLeaf(nsIFrame* aFrame) { - nsIFrame* kid = aFrame->GetFirstPrincipalChild(); + nsIFrame* kid = aFrame->PrincipalChildList().FirstChild(); return !kid || !aFrame->IsFrameOfType(nsIFrame::eBidiInlineContainer); } @@ -670,7 +670,7 @@ nsBidiPresUtils::Resolve(nsBlockFrame* aBlockFrame) block->RemoveStateBits(NS_BLOCK_NEEDS_BIDI_RESOLUTION); nsBlockInFlowLineIterator lineIter(block, block->begin_lines()); bpd.ResetForNewBlock(); - TraverseFrames(aBlockFrame, &lineIter, block->GetFirstPrincipalChild(), &bpd); + TraverseFrames(aBlockFrame, &lineIter, block->PrincipalChildList().FirstChild(), &bpd); nsBlockFrame::FrameLines* overflowLines = block->GetOverflowLines(); if (overflowLines) { nsBlockInFlowLineIterator lineIter(block, overflowLines->mLines.begin(), true); @@ -1188,7 +1188,7 @@ nsBidiPresUtils::TraverseFrames(nsBlockFrame* aBlockFrame, } } else { // For a non-leaf frame, recurse into TraverseFrames - nsIFrame* kid = frame->GetFirstPrincipalChild(); + nsIFrame* kid = frame->PrincipalChildList().FirstChild(); MOZ_ASSERT(!frame->GetChildList(nsIFrame::kOverflowList).FirstChild(), "should have drained the overflow list above"); if (kid) { @@ -1267,7 +1267,7 @@ nsBidiPresUtils::ReorderFrames(nsIFrame* aFirstFrameOnLine, // as the container size. containerSize = aFirstFrameOnLine->GetSize(); - aFirstFrameOnLine = aFirstFrameOnLine->GetFirstPrincipalChild(); + aFirstFrameOnLine = aFirstFrameOnLine->PrincipalChildList().FirstChild(); if (!aFirstFrameOnLine) { return 0; } @@ -1285,7 +1285,7 @@ nsBidiPresUtils::GetFirstLeaf(nsIFrame* aFrame) { nsIFrame* firstLeaf = aFrame; while (!IsBidiLeaf(firstLeaf)) { - nsIFrame* firstChild = firstLeaf->GetFirstPrincipalChild(); + nsIFrame* firstChild = firstLeaf->PrincipalChildList().FirstChild(); nsIFrame* realFrame = nsPlaceholderFrame::GetRealFrameFor(firstChild); firstLeaf = (realFrame->GetType() == nsGkAtoms::letterFrame) ? realFrame : firstChild; @@ -1311,7 +1311,7 @@ nsBidiPresUtils::GetFrameBaseLevel(nsIFrame* aFrame) { nsIFrame* firstLeaf = aFrame; while (!IsBidiLeaf(firstLeaf)) { - firstLeaf = firstLeaf->GetFirstPrincipalChild(); + firstLeaf = firstLeaf->PrincipalChildList().FirstChild(); } return NS_GET_BASE_LEVEL(firstLeaf); } @@ -1571,17 +1571,22 @@ nsBidiPresUtils::RepositionFrame(nsIFrame* aFrame, nscoord frameISize = aFrame->ISize(); LogicalMargin frameMargin = aFrame->GetLogicalUsedMargin(frameWM); LogicalMargin borderPadding = aFrame->GetLogicalUsedBorderAndPadding(frameWM); - // Since the visual order of frame could be different from the - // continuation order, we need to remove any border/padding first, - // so that we can get the correct isize of the current frame. + // Since the visual order of frame could be different from the continuation + // order, we need to remove any inline border/padding [that is already applied + // based on continuation order] and then add it back based on the visual order + // (i.e. isFirst/isLast) to get the correct isize for the current frame. + // We don't need to do that for 'box-decoration-break:clone' because then all + // continuations have border/padding/margin applied. if (aFrame->StyleBorder()->mBoxDecorationBreak == NS_STYLE_BOX_DECORATION_BREAK_SLICE) { + // First remove the border/padding that was applied based on logical order. if (!aFrame->GetPrevContinuation()) { frameISize -= borderPadding.IStart(frameWM); } if (!aFrame->GetNextContinuation()) { frameISize -= borderPadding.IEnd(frameWM); } + // Set margin/border/padding based on visual order. if (!isFirst) { frameMargin.IStart(frameWM) = 0; borderPadding.IStart(frameWM) = 0; @@ -1590,8 +1595,9 @@ nsBidiPresUtils::RepositionFrame(nsIFrame* aFrame, frameMargin.IEnd(frameWM) = 0; borderPadding.IEnd(frameWM) = 0; } + // Add the border/padding which is now based on visual order. + frameISize += borderPadding.IStartEnd(frameWM); } - frameISize += borderPadding.IStartEnd(frameWM); nscoord icoord = 0; if (!IsBidiLeaf(aFrame)) { @@ -1648,10 +1654,7 @@ nsBidiPresUtils::InitContinuationStates(nsIFrame* aFrame, if (!IsBidiLeaf(aFrame) || RubyUtils::IsRubyBox(aFrame->GetType())) { // Continue for child frames - nsIFrame* frame; - for (frame = aFrame->GetFirstPrincipalChild(); - frame; - frame = frame->GetNextSibling()) { + for (nsIFrame* frame : aFrame->PrincipalChildList()) { InitContinuationStates(frame, aContinuationStates); } diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index a9a07cb40b..ff21a5f532 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -90,6 +90,7 @@ #include "nsSimplePageSequenceFrame.h" #include "nsTableOuterFrame.h" #include "nsIScrollableFrame.h" +#include "nsBackdropFrame.h" #include "nsTransitionManager.h" #include "DetailsFrame.h" @@ -364,7 +365,7 @@ static inline nsContainerFrame* GetFieldSetBlockFrame(nsIFrame* aFieldsetFrame) { // Depends on the fieldset child frame order - see ConstructFieldSetFrame() below. - nsIFrame* firstChild = aFieldsetFrame->GetFirstPrincipalChild(); + nsIFrame* firstChild = aFieldsetFrame->PrincipalChildList().FirstChild(); nsIFrame* inner = firstChild && firstChild->GetNextSibling() ? firstChild->GetNextSibling() : firstChild; return inner ? inner->GetContentInsertionFrame() : nullptr; } @@ -495,7 +496,7 @@ GetLastIBSplitSibling(nsIFrame* aFrame, bool aReturnEmptyTrailingInline) for (nsIFrame *frame = aFrame, *next; ; frame = next) { next = GetIBSplitSibling(frame); if (!next || - (!aReturnEmptyTrailingInline && !next->GetFirstPrincipalChild() && + (!aReturnEmptyTrailingInline && !next->PrincipalChildList().FirstChild() && !GetIBSplitSibling(next))) { NS_ASSERTION(!next || !frame->IsInlineOutside(), "Should have a block here!"); @@ -1155,7 +1156,7 @@ nsFrameConstructorState::GetOutOfFlowFrameItems(nsIFrame* aNewFrame, if (aCanBePositioned) { const nsStyleDisplay* disp = aNewFrame->StyleDisplay(); if (disp->mTopLayer != NS_STYLE_TOP_LAYER_NONE) { - *aPlaceholderType = PLACEHOLDER_FOR_FIXEDPOS; + *aPlaceholderType = PLACEHOLDER_FOR_TOPLAYER; return &mTopLayerItems; } if (disp->mPosition == NS_STYLE_POSITION_ABSOLUTE) { @@ -1205,11 +1206,12 @@ nsFrameConstructorState::AddChild(nsIFrame* aNewFrame, if (placeholderType) { NS_ASSERTION(frameItems != &aFrameItems, "Putting frame in-flow _and_ want a placeholder?"); + nsStyleContext* parentContext = aStyleContext->GetParent(); nsIFrame* placeholderFrame = nsCSSFrameConstructor::CreatePlaceholderFrameFor(mPresShell, aContent, aNewFrame, - aStyleContext, + parentContext, aParentFrame, nullptr, placeholderType); @@ -1217,6 +1219,15 @@ nsFrameConstructorState::AddChild(nsIFrame* aNewFrame, placeholderFrame->AddStateBits(mAdditionalStateBits); // Add the placeholder frame to the flow aFrameItems.AddChild(placeholderFrame); + + if (placeholderType == PLACEHOLDER_FOR_TOPLAYER) { + nsIFrame* backdropFrame = nsCSSFrameConstructor:: + CreateBackdropFrameFor(mPresShell, aContent, aNewFrame, + outOfFlowFrameItems->containingBlock); + if (backdropFrame) { + frameItems->AddChild(backdropFrame); + } + } } #ifdef DEBUG else { @@ -1860,9 +1871,9 @@ IsTablePseudo(nsIFrame* aFrame) aFrame->GetParent()->StyleContext()->GetPseudo() == nsCSSAnonBoxes::tableCell) || (pseudoType == nsCSSAnonBoxes::tableOuter && - (aFrame->GetFirstPrincipalChild()->StyleContext()->GetPseudo() == + (aFrame->PrincipalChildList().FirstChild()->StyleContext()->GetPseudo() == nsCSSAnonBoxes::table || - aFrame->GetFirstPrincipalChild()->StyleContext()->GetPseudo() == + aFrame->PrincipalChildList().FirstChild()->StyleContext()->GetPseudo() == nsCSSAnonBoxes::inlineTable))); } @@ -2885,7 +2896,7 @@ nsCSSFrameConstructor::ConstructPageFrame(nsIPresShell* aPresShell, // containing block for fixed elements which are repeated on every page. nsIFrame* prevPageContentFrame = nullptr; if (aPrevPageFrame) { - prevPageContentFrame = aPrevPageFrame->GetFirstPrincipalChild(); + prevPageContentFrame = aPrevPageFrame->PrincipalChildList().FirstChild(); NS_ASSERTION(prevPageContentFrame, "missing page content frame"); } pageContentFrame->Init(nullptr, pageFrame, prevPageContentFrame); @@ -2902,7 +2913,7 @@ nsCSSFrameConstructor::ConstructPageFrame(nsIPresShell* aPresShell, nsIFrame* prevCanvasFrame = nullptr; if (prevPageContentFrame) { - prevCanvasFrame = prevPageContentFrame->GetFirstPrincipalChild(); + prevCanvasFrame = prevPageContentFrame->PrincipalChildList().FirstChild(); NS_ASSERTION(prevCanvasFrame, "missing canvas frame"); } aCanvasFrame->Init(nullptr, pageContentFrame, prevCanvasFrame); @@ -2915,13 +2926,13 @@ nsIFrame* nsCSSFrameConstructor::CreatePlaceholderFrameFor(nsIPresShell* aPresShell, nsIContent* aContent, nsIFrame* aFrame, - nsStyleContext* aStyleContext, + nsStyleContext* aParentStyle, nsContainerFrame* aParentFrame, nsIFrame* aPrevInFlow, nsFrameState aTypeBit) { RefPtr placeholderStyle = aPresShell->StyleSet()-> - ResolveStyleForNonElement(aStyleContext->GetParent()); + ResolveStyleForNonElement(aParentStyle); // The placeholder frame gets a pseudo style context nsPlaceholderFrame* placeholderFrame = @@ -2941,6 +2952,38 @@ nsCSSFrameConstructor::CreatePlaceholderFrameFor(nsIPresShell* aPresShell, return placeholderFrame; } +/* static */ nsIFrame* +nsCSSFrameConstructor::CreateBackdropFrameFor(nsIPresShell* aPresShell, + nsIContent* aContent, + nsIFrame* aFrame, + nsContainerFrame* aParentFrame) +{ + MOZ_ASSERT(aFrame->StyleDisplay()->mTopLayer == NS_STYLE_TOP_LAYER_TOP); + nsContainerFrame* frame = do_QueryFrame(aFrame); + if (!frame) { + NS_WARNING("Cannot create backdrop frame for non-container frame"); + return nullptr; + } + + RefPtr style = aPresShell->StyleSet()-> + ResolvePseudoElementStyle(aContent->AsElement(), + nsCSSPseudoElements::ePseudo_backdrop, + /* aParentStyleContext */ nullptr, + /* aPseudoElement */ nullptr); + nsBackdropFrame* backdropFrame = new (aPresShell) nsBackdropFrame(style); + backdropFrame->Init(aContent, aParentFrame, nullptr); + + nsIFrame* placeholder = CreatePlaceholderFrameFor(aPresShell, aContent, + backdropFrame, + frame->StyleContext(), + frame, nullptr, + PLACEHOLDER_FOR_TOPLAYER); + nsFrameList temp(placeholder, placeholder); + frame->SetInitialChildList(nsIFrame::kBackdropList, temp); + + return backdropFrame; +} + // Clears any lazy bits set in the range [aStartContent, aEndContent). If // aEndContent is null, that means to clear bits in all siblings starting with // aStartContent. aStartContent must not be null unless aEndContent is also @@ -6275,7 +6318,7 @@ FindAppendPrevSibling(nsIFrame* aParentFrame, nsIFrame* aAfterFrame) if (aAfterFrame) { NS_ASSERTION(aAfterFrame->GetParent() == aParentFrame, "Wrong parent"); NS_ASSERTION(aAfterFrame->GetPrevSibling() || - aParentFrame->GetFirstPrincipalChild() == aAfterFrame, + aParentFrame->PrincipalChildList().FirstChild() == aAfterFrame, ":after frame must be on the principal child list here"); return aAfterFrame->GetPrevSibling(); } @@ -6296,7 +6339,7 @@ GetInsertNextSibling(nsIFrame* aParentFrame, nsIFrame* aPrevSibling) return aPrevSibling->GetNextSibling(); } - return aParentFrame->GetFirstPrincipalChild(); + return aParentFrame->PrincipalChildList().FirstChild(); } /** @@ -6313,7 +6356,7 @@ nsCSSFrameConstructor::AppendFramesToParent(nsFrameConstructorState& aStat { NS_PRECONDITION(!IsFramePartOfIBSplit(aParentFrame) || !GetIBSplitSibling(aParentFrame) || - !GetIBSplitSibling(aParentFrame)->GetFirstPrincipalChild(), + !GetIBSplitSibling(aParentFrame)->PrincipalChildList().FirstChild(), "aParentFrame has a ib-split sibling with kids?"); NS_PRECONDITION(!aPrevSibling || aPrevSibling->GetParent() == aParentFrame, "Parent and prevsibling don't match"); @@ -6322,7 +6365,7 @@ nsCSSFrameConstructor::AppendFramesToParent(nsFrameConstructorState& aStat NS_ASSERTION(nextSibling || !aParentFrame->GetNextContinuation() || - !aParentFrame->GetNextContinuation()->GetFirstPrincipalChild() || + !aParentFrame->GetNextContinuation()->PrincipalChildList().FirstChild() || aIsRecursiveCall, "aParentFrame has later continuations with kids?"); NS_ASSERTION(nextSibling || @@ -7841,7 +7884,7 @@ nsCSSFrameConstructor::ContentRangeInserted(nsIContent* aContainer, if (!prevSibling) { // We're inserting the new frames as the first child. See if the // parent has a :before pseudo-element - nsIFrame* firstChild = insertion.mParentFrame->GetFirstPrincipalChild(); + nsIFrame* firstChild = insertion.mParentFrame->PrincipalChildList().FirstChild(); if (firstChild && nsLayoutUtils::IsGeneratedContentFor(container, firstChild, @@ -8186,7 +8229,7 @@ nsCSSFrameConstructor::ContentRemoved(nsIContent* aContainer, if (!aContainer) { nsIFrame* viewport = GetRootFrame(); if (viewport) { - nsIFrame* firstChild = viewport->GetFirstPrincipalChild(); + nsIFrame* firstChild = viewport->PrincipalChildList().FirstChild(); if (firstChild && firstChild->GetContent() == aChild) { isRoot = true; childFrame = firstChild; @@ -8268,7 +8311,7 @@ nsCSSFrameConstructor::ContentRemoved(nsIContent* aContainer, if (grandparentFrame && grandparentFrame->IsBoxFrame() && (grandparentFrame->GetStateBits() & NS_STATE_BOX_WRAPS_KIDS_IN_BLOCK) && // check if this frame is the only one needing wrapping - aChild == AnyKidsNeedBlockParent(parentFrame->GetFirstPrincipalChild()) && + aChild == AnyKidsNeedBlockParent(parentFrame->PrincipalChildList().FirstChild()) && !AnyKidsNeedBlockParent(childFrame->GetNextSibling())) { *aDidReconstruct = true; LAYOUT_PHASE_TEMP_EXIT(); @@ -8662,7 +8705,7 @@ nsCSSFrameConstructor::CreateContinuingOuterTableFrame(nsIPresShell* aPresSh // replicate the caption nsFrameItems newChildFrames; - nsIFrame* childFrame = aFrame->GetFirstPrincipalChild(); + nsIFrame* childFrame = aFrame->PrincipalChildList().FirstChild(); if (childFrame) { nsIFrame* continuingTableFrame = CreateContinuingFrame(aPresContext, childFrame, newFrame); @@ -8690,8 +8733,7 @@ nsCSSFrameConstructor::CreateContinuingTableFrame(nsIPresShell* aPresShell, // Replicate any header/footer frames nsFrameItems childFrames; - nsIFrame* childFrame = aFrame->GetFirstPrincipalChild(); - for ( ; childFrame; childFrame = childFrame->GetNextSibling()) { + for (nsIFrame* childFrame : aFrame->PrincipalChildList()) { // See if it's a header/footer, possibly wrapped in a scroll frame. nsTableRowGroupFrame* rowGroupFrame = static_cast(childFrame); @@ -8813,7 +8855,7 @@ nsCSSFrameConstructor::CreateContinuingFrame(nsPresContext* aPresContext, // Create a continuing frame for each table cell frame nsFrameItems newChildList; - nsIFrame* cellFrame = aFrame->GetFirstPrincipalChild(); + nsIFrame* cellFrame = aFrame->PrincipalChildList().FirstChild(); while (cellFrame) { // See if it's a table cell frame if (IS_TABLE_CELL(cellFrame->GetType())) { @@ -8842,7 +8884,7 @@ nsCSSFrameConstructor::CreateContinuingFrame(nsPresContext* aPresContext, } // Create a continuing area frame - nsIFrame* blockFrame = aFrame->GetFirstPrincipalChild(); + nsIFrame* blockFrame = aFrame->PrincipalChildList().FirstChild(); nsIFrame* continuingBlockFrame = CreateContinuingFrame(aPresContext, blockFrame, static_cast(cellFrame)); @@ -8867,7 +8909,8 @@ nsCSSFrameConstructor::CreateContinuingFrame(nsPresContext* aPresContext, nsIFrame* oofContFrame = CreateContinuingFrame(aPresContext, oofFrame, aParentFrame); newFrame = - CreatePlaceholderFrameFor(shell, content, oofContFrame, styleContext, + CreatePlaceholderFrameFor(shell, content, oofContFrame, + styleContext->GetParent(), aParentFrame, aFrame, aFrame->GetStateBits() & PLACEHOLDER_TYPE_MASK); } else if (nsGkAtoms::fieldSetFrame == frameType) { @@ -8957,8 +9000,8 @@ nsCSSFrameConstructor::ReplicateFixedFrames(nsPageContentFrame* aParentFrame) return NS_OK; } nsContainerFrame* canvasFrame = - do_QueryFrame(aParentFrame->GetFirstPrincipalChild()); - nsIFrame* prevCanvasFrame = prevPageContentFrame->GetFirstPrincipalChild(); + do_QueryFrame(aParentFrame->PrincipalChildList().FirstChild()); + nsIFrame* prevCanvasFrame = prevPageContentFrame->PrincipalChildList().FirstChild(); if (!canvasFrame || !prevCanvasFrame) { // document's root element frame missing return NS_ERROR_UNEXPECTED; @@ -9013,7 +9056,7 @@ nsCSSFrameConstructor::ReplicateFixedFrames(nsPageContentFrame* aParentFrame) // Add the placeholders to our primary child list. // XXXbz this is a little screwed up, since the fixed frames will have // broken auto-positioning. Oh, well. - NS_ASSERTION(!canvasFrame->GetFirstPrincipalChild(), + NS_ASSERTION(!canvasFrame->PrincipalChildList().FirstChild(), "leaking frames; doc root continuation must be empty"); canvasFrame->SetInitialChildList(kPrincipalList, fixedPlaceholders); return NS_OK; @@ -9167,7 +9210,7 @@ IsWhitespaceFrame(nsIFrame* aFrame) static nsIFrame* FindFirstNonWhitespaceChild(nsIFrame* aParentFrame) { - nsIFrame* f = aParentFrame->GetFirstPrincipalChild(); + nsIFrame* f = aParentFrame->PrincipalChildList().FirstChild(); while (f && IsWhitespaceFrame(f)) { f = f->GetNextSibling(); } @@ -9402,7 +9445,7 @@ nsCSSFrameConstructor::MaybeRecreateContainerForFrameRemoval(nsIFrame* aFrame, // If inFlowFrame is not the only in-flow child of |parent|, then removing // it will change nothing about the {ib} split. - if (inFlowFrame != parent->GetFirstPrincipalChild() || + if (inFlowFrame != parent->PrincipalChildList().FirstChild() || inFlowFrame->LastContinuation()->GetNextSibling()) { return false; } @@ -10808,7 +10851,7 @@ nsCSSFrameConstructor::InsertFirstLineFrames( if (!aPrevSibling) { // Insertion will become the first frame. Two cases: we either // already have a first-line frame or we don't. - nsIFrame* firstBlockKid = aBlockFrame->GetFirstPrincipalChild(); + nsIFrame* firstBlockKid = aBlockFrame->PrincipalChildList().FirstChild(); if (firstBlockKid->GetType() == nsGkAtoms::lineFrame) { // We already have a first-line frame nsIFrame* lineFrame = firstBlockKid; @@ -10908,7 +10951,7 @@ nsCSSFrameConstructor::InsertFirstLineFrames( if (!nextLineFrame) { break; } - nsIFrame* kids = nextLineFrame->GetFirstPrincipalChild(); + nsIFrame* kids = nextLineFrame->PrincipalChildList().FirstChild(); } } else { @@ -11212,7 +11255,7 @@ nsCSSFrameConstructor::WrapFramesInFirstLetterFrame( } } else if (IsInlineFrame(frame) && frameType != nsGkAtoms::brFrame) { - nsIFrame* kids = frame->GetFirstPrincipalChild(); + nsIFrame* kids = frame->PrincipalChildList().FirstChild(); WrapFramesInFirstLetterFrame(aBlockFrame, aBlockContinuation, static_cast(frame), kids, aModifiedParent, aTextFrame, @@ -11267,7 +11310,7 @@ nsCSSFrameConstructor::RemoveFloatingFirstLetterFrames( // Take the text frame away from the letter frame (so it isn't // destroyed when we destroy the letter frame). - nsIFrame* textFrame = floatFrame->GetFirstPrincipalChild(); + nsIFrame* textFrame = floatFrame->PrincipalChildList().FirstChild(); if (!textFrame) { return NS_OK; } @@ -11346,12 +11389,12 @@ nsCSSFrameConstructor::RemoveFirstLetterFrames(nsIPresShell* aPresShell, bool* aStopLooking) { nsIFrame* prevSibling = nullptr; - nsIFrame* kid = aFrame->GetFirstPrincipalChild(); + nsIFrame* kid = aFrame->PrincipalChildList().FirstChild(); while (kid) { if (nsGkAtoms::letterFrame == kid->GetType()) { // Bingo. Found it. First steal away the text frame. - nsIFrame* textFrame = kid->GetFirstPrincipalChild(); + nsIFrame* textFrame = kid->PrincipalChildList().FirstChild(); if (!textFrame) { break; } @@ -11458,7 +11501,7 @@ nsCSSFrameConstructor::RecoverLetterFrames(nsContainerFrame* aBlockFrame) // XXX shouldn't this bit be set already (bug 408493), assert instead? continuation->AddStateBits(NS_BLOCK_HAS_FIRST_LETTER_STYLE); WrapFramesInFirstLetterFrame(aBlockFrame, continuation, continuation, - continuation->GetFirstPrincipalChild(), + continuation->PrincipalChildList().FirstChild(), &parentFrame, &textFrame, &prevFrame, letterFrames, &stopLooking); if (stopLooking) { @@ -12176,7 +12219,7 @@ nsCSSFrameConstructor::WipeContainingBlock(nsFrameConstructorState& aState, // Try to find one after all nsIFrame* parentNextCont = aFrame->GetNextContinuation(); while (parentNextCont) { - nextSibling = parentNextCont->GetFirstPrincipalChild(); + nextSibling = parentNextCont->PrincipalChildList().FirstChild(); if (nextSibling) { break; } diff --git a/layout/base/nsCSSFrameConstructor.h b/layout/base/nsCSSFrameConstructor.h index cb6c7781a2..b8807bbf0f 100644 --- a/layout/base/nsCSSFrameConstructor.h +++ b/layout/base/nsCSSFrameConstructor.h @@ -1299,11 +1299,16 @@ protected: static nsIFrame* CreatePlaceholderFrameFor(nsIPresShell* aPresShell, nsIContent* aContent, nsIFrame* aFrame, - nsStyleContext* aStyleContext, + nsStyleContext* aParentStyle, nsContainerFrame* aParentFrame, nsIFrame* aPrevInFlow, nsFrameState aTypeBit); + static nsIFrame* CreateBackdropFrameFor(nsIPresShell* aPresShell, + nsIContent* aContent, + nsIFrame* aFrame, + nsContainerFrame* aParentFrame); + private: // ConstructSelectFrame puts the new frame in aFrameItems and // handles the kids of the select. diff --git a/layout/base/nsCSSRendering.cpp b/layout/base/nsCSSRendering.cpp index 478df79ffc..dc86fbd602 100644 --- a/layout/base/nsCSSRendering.cpp +++ b/layout/base/nsCSSRendering.cpp @@ -3111,7 +3111,7 @@ nsCSSRendering::ComputeBackgroundPositioningArea(nsPresContext* aPresContext, } if (MOZ_UNLIKELY(frameType == nsGkAtoms::canvasFrame)) { - geometryFrame = aForFrame->GetFirstPrincipalChild(); + geometryFrame = aForFrame->PrincipalChildList().FirstChild(); // geometryFrame might be null if this canvas is a page created // as an overflow container (e.g. the in-flow content has already // finished and this page only displays the continuations of diff --git a/layout/base/nsCaret.cpp b/layout/base/nsCaret.cpp index 38a0026b1d..3810ffcb5b 100644 --- a/layout/base/nsCaret.cpp +++ b/layout/base/nsCaret.cpp @@ -62,7 +62,7 @@ CheckForTrailingTextFrameRecursive(nsIFrame* aFrame, nsIFrame* aStopAtFrame) if (!aFrame->IsFrameOfType(nsIFrame::eLineParticipant)) return nullptr; - for (nsIFrame* f = aFrame->GetFirstPrincipalChild(); f; f = f->GetNextSibling()) + for (nsIFrame* f : aFrame->PrincipalChildList()) { nsIFrame* r = CheckForTrailingTextFrameRecursive(f, aStopAtFrame); if (r) diff --git a/layout/base/nsDocumentViewer.cpp b/layout/base/nsDocumentViewer.cpp index 2e4d615cd5..57d6d02e91 100644 --- a/layout/base/nsDocumentViewer.cpp +++ b/layout/base/nsDocumentViewer.cpp @@ -3881,8 +3881,7 @@ nsDocumentViewer::PrintPreviewNavigate(int16_t aType, int32_t aPageNum) // Now, locate the current page we are on and // and the page of the page number - nsIFrame* pageFrame = seqFrame->GetFirstPrincipalChild(); - while (pageFrame != nullptr) { + for (nsIFrame* pageFrame : seqFrame->PrincipalChildList()) { nsRect pageRect = pageFrame->GetRect(); if (pageRect.Contains(pageRect.x, pt.y)) { currentPage = pageFrame; @@ -3892,7 +3891,6 @@ nsDocumentViewer::PrintPreviewNavigate(int16_t aType, int32_t aPageNum) break; } pageNum++; - pageFrame = pageFrame->GetNextSibling(); } if (aType == nsIWebBrowserPrint::PRINTPREVIEW_PREV_PAGE) { diff --git a/layout/base/nsFrameTraversal.cpp b/layout/base/nsFrameTraversal.cpp index 51a30fdadd..6ab455395e 100644 --- a/layout/base/nsFrameTraversal.cpp +++ b/layout/base/nsFrameTraversal.cpp @@ -466,7 +466,7 @@ nsFrameIterator::GetPrevSibling(nsIFrame* aFrame) nsIFrame* nsFrameIterator::GetFirstChildInner(nsIFrame* aFrame) { - return aFrame->GetFirstPrincipalChild(); + return aFrame->PrincipalChildList().FirstChild(); } nsIFrame* diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index e1d7f85fc9..e7f93d65ac 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -1201,7 +1201,7 @@ nsLayoutUtils::LastContinuationWithChild(nsContainerFrame* aFrame) { NS_PRECONDITION(aFrame, "NULL frame pointer"); nsIFrame* f = aFrame->LastContinuation(); - while (!f->GetFirstPrincipalChild() && f->GetPrevContinuation()) { + while (!f->PrincipalChildList().FirstChild() && f->GetPrevContinuation()) { f = f->GetPrevContinuation(); } return static_cast(f); @@ -1329,7 +1329,7 @@ nsLayoutUtils::GetBeforeFrameForContent(nsIFrame* aFrame, // If the first child frame is a pseudo-frame, then try that. // Note that the frame we create for the generated content is also a // pseudo-frame and so don't drill down in that case. - nsIFrame* childFrame = genConParentFrame->GetFirstPrincipalChild(); + nsIFrame* childFrame = genConParentFrame->PrincipalChildList().FirstChild(); if (childFrame && childFrame->IsPseudoFrame(aContent) && !childFrame->IsGeneratedContentFrame()) { @@ -1413,7 +1413,7 @@ nsIFrame* nsLayoutUtils::GetStyleFrame(nsIFrame* aFrame) { if (aFrame->GetType() == nsGkAtoms::tableOuterFrame) { - nsIFrame* inner = aFrame->GetFirstPrincipalChild(); + nsIFrame* inner = aFrame->PrincipalChildList().FirstChild(); NS_ASSERTION(inner, "Outer table must have an inner"); return inner; } @@ -3559,7 +3559,7 @@ AddBoxesForFrame(nsIFrame* aFrame, nsIAtom* pseudoType = aFrame->StyleContext()->GetPseudo(); if (pseudoType == nsCSSAnonBoxes::tableOuter) { - AddBoxesForFrame(aFrame->GetFirstPrincipalChild(), aCallback); + AddBoxesForFrame(aFrame->PrincipalChildList().FirstChild(), aCallback); nsIFrame* kid = aFrame->GetChildList(nsIFrame::kCaptionList).FirstChild(); if (kid) { AddBoxesForFrame(kid, aCallback); @@ -3592,7 +3592,7 @@ nsLayoutUtils::GetFirstNonAnonymousFrame(nsIFrame* aFrame) nsIAtom* pseudoType = aFrame->StyleContext()->GetPseudo(); if (pseudoType == nsCSSAnonBoxes::tableOuter) { - nsIFrame* f = GetFirstNonAnonymousFrame(aFrame->GetFirstPrincipalChild()); + nsIFrame* f = GetFirstNonAnonymousFrame(aFrame->PrincipalChildList().FirstChild()); if (f) { return f; } @@ -5845,7 +5845,7 @@ nsLayoutUtils::GetFirstLinePosition(WritingMode aWM, if (fType == nsGkAtoms::fieldSetFrame) { LinePosition kidPosition; - nsIFrame* kid = aFrame->GetFirstPrincipalChild(); + nsIFrame* kid = aFrame->PrincipalChildList().FirstChild(); // kid might be a legend frame here, but that's ok. if (GetFirstLinePosition(aWM, kid, &kidPosition)) { *aResult = kidPosition + @@ -6761,7 +6761,7 @@ nsLayoutUtils::GetFrameTransparency(nsIFrame* aBackgroundFrame, // doing otherwise breaks window display effects on some platforms, // specifically Vista. (bug 450322) if (aBackgroundFrame->GetType() == nsGkAtoms::viewportFrame && - !aBackgroundFrame->GetFirstPrincipalChild()) { + !aBackgroundFrame->PrincipalChildList().FirstChild()) { return eTransparencyOpaque; } diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index 95ab67ad86..e3ce0374a6 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -2283,7 +2283,7 @@ nsIPresShell::GetRootScrollFrame() const // Ensure root frame is a viewport frame if (!rootFrame || nsGkAtoms::viewportFrame != rootFrame->GetType()) return nullptr; - nsIFrame* theFrame = rootFrame->GetFirstPrincipalChild(); + nsIFrame* theFrame = rootFrame->PrincipalChildList().FirstChild(); if (!theFrame || nsGkAtoms::scrollFrame != theFrame->GetType()) return nullptr; return theFrame; @@ -9618,13 +9618,11 @@ FindTopFrame(nsIFrame* aRoot) } // Try one of the children - nsIFrame* kid = aRoot->GetFirstPrincipalChild(); - while (nullptr != kid) { + for (nsIFrame* kid : aRoot->PrincipalChildList()) { nsIFrame* result = FindTopFrame(kid); if (nullptr != result) { return result; } - kid = kid->GetNextSibling(); } } return nullptr; @@ -10204,10 +10202,8 @@ static void RecurseIndiTotals(nsPresContext* aPresContext, free(name); } - nsIFrame* child = aParentFrame->GetFirstPrincipalChild(); - while (child) { + for (nsIFrame* child : aParentFrame->PrincipalChildList()) { RecurseIndiTotals(aPresContext, aHT, child, aLevel+1); - child = child->GetNextSibling(); } } diff --git a/layout/forms/nsFieldSetFrame.cpp b/layout/forms/nsFieldSetFrame.cpp index d9763ec02f..da2f20a407 100644 --- a/layout/forms/nsFieldSetFrame.cpp +++ b/layout/forms/nsFieldSetFrame.cpp @@ -663,8 +663,9 @@ void nsFieldSetFrame::SetInitialChildList(ChildListID aListID, nsFrameList& aChildList) { - nsContainerFrame::SetInitialChildList(kPrincipalList, aChildList); - MOZ_ASSERT(GetInner()); + nsContainerFrame::SetInitialChildList(aListID, aChildList); + MOZ_ASSERT(aListID != kPrincipalList || GetInner(), + "Setting principal child list should populate our inner frame"); } void nsFieldSetFrame::AppendFrames(ChildListID aListID, diff --git a/layout/forms/nsFormControlFrame.cpp b/layout/forms/nsFormControlFrame.cpp index 464ed40a28..77ef2ec645 100644 --- a/layout/forms/nsFormControlFrame.cpp +++ b/layout/forms/nsFormControlFrame.cpp @@ -18,7 +18,7 @@ using namespace mozilla; //#define FCF_NOISY nsFormControlFrame::nsFormControlFrame(nsStyleContext* aContext) : - nsLeafFrame(aContext) + nsFormControlFrameSuper(aContext) { } @@ -37,12 +37,46 @@ nsFormControlFrame::DestroyFrom(nsIFrame* aDestructRoot) { // Unregister the access key registered in reflow nsFormControlFrame::RegUnRegAccessKey(static_cast(this), false); - nsLeafFrame::DestroyFrom(aDestructRoot); + nsFormControlFrameSuper::DestroyFrom(aDestructRoot); } NS_QUERYFRAME_HEAD(nsFormControlFrame) NS_QUERYFRAME_ENTRY(nsIFormControlFrame) -NS_QUERYFRAME_TAIL_INHERITING(nsLeafFrame) +NS_QUERYFRAME_TAIL_INHERITING(nsFormControlFrameSuper) + +/* virtual */ nscoord +nsFormControlFrame::GetMinISize(nsRenderingContext *aRenderingContext) +{ + nscoord result; + DISPLAY_MIN_WIDTH(this, result); + result = GetIntrinsicISize(); + return result; +} + +/* virtual */ nscoord +nsFormControlFrame::GetPrefISize(nsRenderingContext *aRenderingContext) +{ + nscoord result; + DISPLAY_PREF_WIDTH(this, result); + result = GetIntrinsicISize(); + return result; +} + +/* virtual */ +LogicalSize +nsFormControlFrame::ComputeAutoSize(nsRenderingContext *aRenderingContext, + WritingMode aWM, + const LogicalSize& aCBSize, + nscoord aAvailableISize, + const LogicalSize& aMargin, + const LogicalSize& aBorder, + const LogicalSize& aPadding, + bool aShrinkWrap) +{ + const WritingMode wm = GetWritingMode(); + LogicalSize result(wm, GetIntrinsicISize(), GetIntrinsicBSize()); + return result.ConvertTo(aWM, wm); +} nscoord nsFormControlFrame::GetIntrinsicISize() @@ -80,22 +114,34 @@ nsFormControlFrame::Reflow(nsPresContext* aPresContext, const nsHTMLReflowState& aReflowState, nsReflowStatus& aStatus) { + MarkInReflow(); DO_GLOBAL_REFLOW_COUNT("nsFormControlFrame"); DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus); + NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS, + ("enter nsFormControlFrame::Reflow: aMaxSize=%d,%d", + aReflowState.AvailableWidth(), aReflowState.AvailableHeight())); if (mState & NS_FRAME_FIRST_REFLOW) { RegUnRegAccessKey(static_cast(this), true); } - nsLeafFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus); + aStatus = NS_FRAME_COMPLETE; + aDesiredSize.SetSize(aReflowState.GetWritingMode(), + aReflowState.ComputedSizeWithBorderPadding()); if (nsLayoutUtils::FontSizeInflationEnabled(aPresContext)) { float inflation = nsLayoutUtils::FontSizeInflationFor(this); aDesiredSize.Width() *= inflation; aDesiredSize.Height() *= inflation; - aDesiredSize.UnionOverflowAreasWithDesiredBounds(); - FinishAndStoreOverflow(&aDesiredSize); } + + NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS, + ("exit nsFormControlFrame::Reflow: size=%d,%d", + aDesiredSize.Width(), aDesiredSize.Height())); + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); + + aDesiredSize.SetOverflowAreasToDesiredBounds(); + FinishAndStoreOverflow(&aDesiredSize); } nsresult diff --git a/layout/forms/nsFormControlFrame.h b/layout/forms/nsFormControlFrame.h index b3f2bece0c..9d3a3034bc 100644 --- a/layout/forms/nsFormControlFrame.h +++ b/layout/forms/nsFormControlFrame.h @@ -8,14 +8,17 @@ #include "mozilla/Attributes.h" #include "nsIFormControlFrame.h" -#include "nsLeafFrame.h" +#include "nsAtomicContainerFrame.h" +#include "nsDisplayList.h" + +typedef nsAtomicContainerFrame nsFormControlFrameSuper; /** * nsFormControlFrame is the base class for radio buttons and * checkboxes. It also has two static methods (RegUnRegAccessKey and * GetScreenHeight) that are used by other form controls. */ -class nsFormControlFrame : public nsLeafFrame, +class nsFormControlFrame : public nsFormControlFrameSuper, public nsIFormControlFrame { public: @@ -30,13 +33,41 @@ public: virtual bool IsFrameOfType(uint32_t aFlags) const override { - return nsLeafFrame::IsFrameOfType(aFlags & + return nsFormControlFrameSuper::IsFrameOfType(aFlags & ~(nsIFrame::eReplaced | nsIFrame::eReplacedContainsBlock)); } NS_DECL_QUERYFRAME NS_DECL_ABSTRACT_FRAME(nsFormControlFrame) + // nsIFrame replacements + virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, + const nsDisplayListSet& aLists) override { + DO_GLOBAL_REFLOW_COUNT_DSP("nsFormControlFrame"); + DisplayBorderBackgroundOutline(aBuilder, aLists); + } + + /** + * Both GetMinISize and GetPrefISize will return whatever GetIntrinsicISize + * returns. + */ + virtual nscoord GetMinISize(nsRenderingContext *aRenderingContext) override; + virtual nscoord GetPrefISize(nsRenderingContext *aRenderingContext) override; + + /** + * Our auto size is just intrinsic width and intrinsic height. + */ + virtual mozilla::LogicalSize + ComputeAutoSize(nsRenderingContext *aRenderingContext, + mozilla::WritingMode aWritingMode, + const mozilla::LogicalSize& aCBSize, + nscoord aAvailableISize, + const mozilla::LogicalSize& aMargin, + const mozilla::LogicalSize& aBorder, + const mozilla::LogicalSize& aPadding, + bool aShrinkWrap) override; + /** * Respond to a gui event * @see nsIFrame::HandleEvent @@ -79,8 +110,8 @@ protected: virtual ~nsFormControlFrame(); - virtual nscoord GetIntrinsicISize() override; - virtual nscoord GetIntrinsicBSize() override; + nscoord GetIntrinsicISize(); + nscoord GetIntrinsicBSize(); // //------------------------------------------------------------------------------------- diff --git a/layout/forms/nsHTMLButtonControlFrame.h b/layout/forms/nsHTMLButtonControlFrame.h index 61bbe5e02e..e5784202e0 100644 --- a/layout/forms/nsHTMLButtonControlFrame.h +++ b/layout/forms/nsHTMLButtonControlFrame.h @@ -81,7 +81,7 @@ public: // Inserted child content gets its frames parented by our child block virtual nsContainerFrame* GetContentInsertionFrame() override { - return GetFirstPrincipalChild()->GetContentInsertionFrame(); + return PrincipalChildList().FirstChild()->GetContentInsertionFrame(); } virtual bool IsFrameOfType(uint32_t aFlags) const override diff --git a/layout/forms/nsListControlFrame.cpp b/layout/forms/nsListControlFrame.cpp index 74371953af..a32ebff643 100644 --- a/layout/forms/nsListControlFrame.cpp +++ b/layout/forms/nsListControlFrame.cpp @@ -265,8 +265,7 @@ static nscoord GetMaxOptionBSize(nsIFrame* aContainer, WritingMode aWM) { nscoord result = 0; - for (nsIFrame* option = aContainer->GetFirstPrincipalChild(); - option; option = option->GetNextSibling()) { + for (nsIFrame* option : aContainer->PrincipalChildList()) { nscoord optionBSize; if (nsCOMPtr (do_QueryInterface(option->GetContent()))) { @@ -927,11 +926,13 @@ void nsListControlFrame::SetInitialChildList(ChildListID aListID, nsFrameList& aChildList) { - // First check to see if all the content has been added - mIsAllContentHere = mContent->IsDoneAddingChildren(); - if (!mIsAllContentHere) { - mIsAllFramesHere = false; - mHasBeenInitialized = false; + if (aListID == kPrincipalList) { + // First check to see if all the content has been added + mIsAllContentHere = mContent->IsDoneAddingChildren(); + if (!mIsAllContentHere) { + mIsAllFramesHere = false; + mHasBeenInitialized = false; + } } nsHTMLScrollFrame::SetInitialChildList(aListID, aChildList); diff --git a/layout/forms/nsTextControlFrame.cpp b/layout/forms/nsTextControlFrame.cpp index 99216c4cb6..4fc4aff404 100644 --- a/layout/forms/nsTextControlFrame.cpp +++ b/layout/forms/nsTextControlFrame.cpp @@ -210,7 +210,7 @@ nsTextControlFrame::CalcIntrinsicSize(nsRenderingContext* aRenderingContext, // Add in the size of the scrollbars for textarea if (IsTextArea()) { - nsIFrame* first = GetFirstPrincipalChild(); + nsIFrame* first = PrincipalChildList().FirstChild(); nsIScrollableFrame *scrollableFrame = do_QueryFrame(first); NS_ASSERTION(scrollableFrame, "Child must be scrollable"); @@ -1224,13 +1224,14 @@ nsTextControlFrame::SetInitialChildList(ChildListID aListID, nsFrameList& aChildList) { nsContainerFrame::SetInitialChildList(aListID, aChildList); - - nsIFrame* first = GetFirstPrincipalChild(); + if (aListID != kPrincipalList) { + return; + } // Mark the scroll frame as being a reflow root. This will allow // incremental reflows to be initiated at the scroll frame, rather // than descending from the root frame of the frame hierarchy. - if (first) { + if (nsIFrame* first = PrincipalChildList().FirstChild()) { first->AddStateBits(NS_FRAME_REFLOW_ROOT); nsCOMPtr txtCtrl = do_QueryInterface(GetContent()); diff --git a/layout/forms/nsTextControlFrame.h b/layout/forms/nsTextControlFrame.h index 8b67c7ce28..3b1430c905 100644 --- a/layout/forms/nsTextControlFrame.h +++ b/layout/forms/nsTextControlFrame.h @@ -40,7 +40,7 @@ public: virtual void DestroyFrom(nsIFrame* aDestructRoot) override; virtual nsIScrollableFrame* GetScrollTargetFrame() override { - return do_QueryFrame(GetFirstPrincipalChild()); + return do_QueryFrame(PrincipalChildList().FirstChild()); } virtual nscoord GetMinISize(nsRenderingContext* aRenderingContext) override; diff --git a/layout/generic/FrameChildList.cpp b/layout/generic/FrameChildList.cpp index 32003f5a98..1d2fe25c0e 100644 --- a/layout/generic/FrameChildList.cpp +++ b/layout/generic/FrameChildList.cpp @@ -46,6 +46,7 @@ ChildListName(FrameChildListID aListID) case kFloatList: return "FloatList"; case kBulletList: return "BulletList"; case kPushedFloatsList: return "PushedFloatsList"; + case kBackdropList: return "BackdropList"; case kNoReflowPrincipalList: return "NoReflowPrincipalList"; } diff --git a/layout/generic/RubyUtils.cpp b/layout/generic/RubyUtils.cpp index e99e79f01d..adef88227a 100644 --- a/layout/generic/RubyUtils.cpp +++ b/layout/generic/RubyUtils.cpp @@ -59,7 +59,7 @@ AutoRubyTextContainerArray::AutoRubyTextContainerArray( RubySegmentEnumerator::RubySegmentEnumerator(nsRubyFrame* aRubyFrame) { - nsIFrame* frame = aRubyFrame->GetFirstPrincipalChild(); + nsIFrame* frame = aRubyFrame->PrincipalChildList().FirstChild(); MOZ_ASSERT(!frame || frame->GetType() == nsGkAtoms::rubyBaseContainerFrame); mBaseContainer = static_cast(frame); @@ -84,7 +84,7 @@ RubyColumnEnumerator::RubyColumnEnumerator( const uint32_t rtcCount = aTextContainers.Length(); mFrames.SetCapacity(rtcCount + 1); - nsIFrame* rbFrame = aBaseContainer->GetFirstPrincipalChild(); + nsIFrame* rbFrame = aBaseContainer->PrincipalChildList().FirstChild(); MOZ_ASSERT(!rbFrame || rbFrame->GetType() == nsGkAtoms::rubyBaseFrame); mFrames.AppendElement(static_cast(rbFrame)); for (uint32_t i = 0; i < rtcCount; i++) { @@ -92,7 +92,7 @@ RubyColumnEnumerator::RubyColumnEnumerator( // If the container is for span, leave a nullptr here. // Spans do not take part in pairing. nsIFrame* rtFrame = !container->IsSpanContainer() ? - container->GetFirstPrincipalChild() : nullptr; + container->PrincipalChildList().FirstChild() : nullptr; MOZ_ASSERT(!rtFrame || rtFrame->GetType() == nsGkAtoms::rubyTextFrame); mFrames.AppendElement(static_cast(rtFrame)); } diff --git a/layout/generic/TextOverflow.cpp b/layout/generic/TextOverflow.cpp index afcfa91564..62e64a9345 100644 --- a/layout/generic/TextOverflow.cpp +++ b/layout/generic/TextOverflow.cpp @@ -380,13 +380,11 @@ TextOverflow::ExamineFrameSubtree(nsIFrame* aFrame, return; } - nsIFrame* child = aFrame->GetFirstPrincipalChild(); - while (child) { + for (nsIFrame* child : aFrame->PrincipalChildList()) { ExamineFrameSubtree(child, aContentArea, aInsideMarkersArea, aFramesToHide, aAlignmentEdges, aFoundVisibleTextOrAtomic, aClippedMarkerEdges); - child = child->GetNextSibling(); } } diff --git a/layout/generic/moz.build b/layout/generic/moz.build index c20c96a704..950cc986f3 100644 --- a/layout/generic/moz.build +++ b/layout/generic/moz.build @@ -117,6 +117,7 @@ UNIFIED_SOURCES += [ 'FrameChildList.cpp', 'MathMLTextRunFactory.cpp', 'nsAbsoluteContainingBlock.cpp', + 'nsBackdropFrame.cpp', 'nsBlockFrame.cpp', 'nsBlockReflowContext.cpp', 'nsBlockReflowState.cpp', diff --git a/layout/generic/nsBackdropFrame.cpp b/layout/generic/nsBackdropFrame.cpp new file mode 100644 index 0000000000..135d8e3f48 --- /dev/null +++ b/layout/generic/nsBackdropFrame.cpp @@ -0,0 +1,92 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +// vim:cindent:ts=2:et:sw=2: +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* rendering object for CSS "::backdrop" */ + +#include "nsBackdropFrame.h" + +using namespace mozilla; + +NS_IMPL_FRAMEARENA_HELPERS(nsBackdropFrame) + +/* virtual */ nsIAtom* +nsBackdropFrame::GetType() const +{ + return nsGkAtoms::backdropFrame; +} + +#ifdef DEBUG_FRAME_DUMP +nsresult +nsBackdropFrame::GetFrameName(nsAString& aResult) const +{ + return MakeFrameName(NS_LITERAL_STRING("Backdrop"), aResult); +} +#endif + +/* virtual */ nsStyleContext* +nsBackdropFrame::GetParentStyleContext(nsIFrame** aProviderFrame) const +{ + // Style context of backdrop pseudo-element does not inherit from + // any element, per the Fullscreen API spec. + *aProviderFrame = nullptr; + return nullptr; +} + +/* virtual */ void +nsBackdropFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, + const nsDisplayListSet& aLists) +{ + DO_GLOBAL_REFLOW_COUNT_DSP("nsBackdropFrame"); + // We want this frame to always be there even if its display value is + // none or contents so that we can respond to style change on it. To + // support those values, we skip painting ourselves in those cases. + auto display = StyleDisplay()->mDisplay; + if (display != NS_STYLE_DISPLAY_NONE && + display != NS_STYLE_DISPLAY_CONTENTS) { + DisplayBorderBackgroundOutline(aBuilder, aLists); + } +} + +/* virtual */ LogicalSize +nsBackdropFrame::ComputeAutoSize(nsRenderingContext *aRenderingContext, + WritingMode aWM, + const LogicalSize& aCBSize, + nscoord aAvailableISize, + const LogicalSize& aMargin, + const LogicalSize& aBorder, + const LogicalSize& aPadding, + bool aShrinkWrap) +{ + // Note that this frame is a child of the viewport frame. + LogicalSize result(aWM, 0xdeadbeef, NS_UNCONSTRAINEDSIZE); + if (aShrinkWrap) { + result.ISize(aWM) = 0; + } else { + result.ISize(aWM) = aAvailableISize - aMargin.ISize(aWM) - + aBorder.ISize(aWM) - aPadding.ISize(aWM); + } + return result; +} + +/* virtual */ void +nsBackdropFrame::Reflow(nsPresContext* aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + const nsHTMLReflowState& aReflowState, + nsReflowStatus& aStatus) +{ + MarkInReflow(); + DO_GLOBAL_REFLOW_COUNT("nsBackdropFrame"); + DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus); + + // Note that this frame is a child of the viewport frame. + WritingMode wm = aReflowState.GetWritingMode(); + LogicalMargin borderPadding = aReflowState.ComputedLogicalBorderPadding(); + nscoord isize = aReflowState.ComputedISize() + borderPadding.IStartEnd(wm); + nscoord bsize = aReflowState.ComputedBSize() + borderPadding.BStartEnd(wm); + aDesiredSize.SetSize(wm, LogicalSize(wm, isize, bsize)); + aStatus = NS_FRAME_COMPLETE; +} diff --git a/layout/generic/nsBackdropFrame.h b/layout/generic/nsBackdropFrame.h new file mode 100644 index 0000000000..1babc8dd91 --- /dev/null +++ b/layout/generic/nsBackdropFrame.h @@ -0,0 +1,46 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +// vim:cindent:ts=2:et:sw=2: +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* rendering object for CSS "::backdrop" */ + +#ifndef nsBackdropFrame_h___ +#define nsBackdropFrame_h___ + +#include "nsFrame.h" + +class nsBackdropFrame final : public nsFrame +{ +public: + NS_DECL_FRAMEARENA_HELPERS + + explicit nsBackdropFrame(nsStyleContext* aContext) + : nsFrame(aContext) { } + + // nsIFrame overrides + virtual nsIAtom* GetType() const override; +#ifdef DEBUG_FRAME_DUMP + virtual nsresult GetFrameName(nsAString& aResult) const override; +#endif + virtual nsStyleContext* + GetParentStyleContext(nsIFrame** aProviderFrame) const override; + virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, + const nsDisplayListSet& aLists) override; + virtual LogicalSize ComputeAutoSize(nsRenderingContext *aRenderingContext, + WritingMode aWM, + const LogicalSize& aCBSize, + nscoord aAvailableISize, + const LogicalSize& aMargin, + const LogicalSize& aBorder, + const LogicalSize& aPadding, + bool aShrinkWrap) override; + virtual void Reflow(nsPresContext* aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + const nsHTMLReflowState& aReflowState, + nsReflowStatus& aStatus) override; +}; + +#endif // nsBackdropFrame_h___ diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp index 78dde6104b..0d8eb96c9a 100644 --- a/layout/generic/nsBlockFrame.cpp +++ b/layout/generic/nsBlockFrame.cpp @@ -2408,7 +2408,7 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState) aState.mPresContext->HasPendingInterrupt()) { // Need to make sure to pull overflows from any prev-in-flows for (nsIFrame* inlineKid = line->mFirstChild; inlineKid; - inlineKid = inlineKid->GetFirstPrincipalChild()) { + inlineKid = inlineKid->PrincipalChildList().FirstChild()) { inlineKid->PullOverflowsFromPrevInFlow(); } } @@ -6846,18 +6846,12 @@ void nsBlockFrame::SetInitialChildList(ChildListID aListID, nsFrameList& aChildList) { - NS_ASSERTION(aListID != kPrincipalList || - (GetStateBits() & (NS_BLOCK_FRAME_HAS_INSIDE_BULLET | - NS_BLOCK_FRAME_HAS_OUTSIDE_BULLET)) == 0, - "how can we have a bullet already?"); - - if (kAbsoluteList == aListID) { - nsContainerFrame::SetInitialChildList(aListID, aChildList); - } - else if (kFloatList == aListID) { + if (kFloatList == aListID) { mFloats.SetFrames(aChildList); - } - else { + } else if (kPrincipalList == aListID) { + NS_ASSERTION((GetStateBits() & (NS_BLOCK_FRAME_HAS_INSIDE_BULLET | + NS_BLOCK_FRAME_HAS_OUTSIDE_BULLET)) == 0, + "how can we have a bullet already?"); #ifdef DEBUG // The only times a block that is an anonymous box is allowed to have a @@ -6918,6 +6912,8 @@ nsBlockFrame::SetInitialChildList(ChildListID aListID, style->IsBullet(), styleList->mListStylePosition == NS_STYLE_LIST_STYLE_POSITION_INSIDE); } + } else { + nsContainerFrame::SetInitialChildList(aListID, aChildList); } } @@ -7285,7 +7281,7 @@ nsBlockFrame::DoCollectFloats(nsIFrame* aFrame, nsFrameList& aList, // XXXmats nsInlineFrame's lazy reparenting depends on NOT doing that. } - DoCollectFloats(aFrame->GetFirstPrincipalChild(), aList, true); + DoCollectFloats(aFrame->PrincipalChildList().FirstChild(), aList, true); DoCollectFloats(aFrame->GetChildList(kOverflowList).FirstChild(), aList, true); } if (!aCollectSiblings) diff --git a/layout/generic/nsBlockReflowContext.cpp b/layout/generic/nsBlockReflowContext.cpp index 44aa2f02d1..6a046f2687 100644 --- a/layout/generic/nsBlockReflowContext.cpp +++ b/layout/generic/nsBlockReflowContext.cpp @@ -41,7 +41,7 @@ static nsIFrame* DescendIntoBlockLevelFrame(nsIFrame* aFrame) nsIAtom* type = aFrame->GetType(); if (type == nsGkAtoms::columnSetFrame) { static_cast(aFrame)->DrainOverflowColumns(); - nsIFrame* child = aFrame->GetFirstPrincipalChild(); + nsIFrame* child = aFrame->PrincipalChildList().FirstChild(); if (child) { return DescendIntoBlockLevelFrame(child); } diff --git a/layout/generic/nsCanvasFrame.cpp b/layout/generic/nsCanvasFrame.cpp index d225a48ff0..ba93759e1e 100644 --- a/layout/generic/nsCanvasFrame.cpp +++ b/layout/generic/nsCanvasFrame.cpp @@ -425,8 +425,7 @@ nsCanvasFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, } } - nsIFrame* kid; - for (kid = GetFirstPrincipalChild(); kid; kid = kid->GetNextSibling()) { + for (nsIFrame* kid : PrincipalChildList()) { // Put our child into its own pseudo-stack. BuildDisplayListForChild(aBuilder, kid, aDirtyRect, aLists); } diff --git a/layout/generic/nsColumnSetFrame.cpp b/layout/generic/nsColumnSetFrame.cpp index 1ded814082..3ab608804a 100644 --- a/layout/generic/nsColumnSetFrame.cpp +++ b/layout/generic/nsColumnSetFrame.cpp @@ -1140,9 +1140,8 @@ void nsColumnSetFrame::SetInitialChildList(ChildListID aListID, nsFrameList& aChildList) { - MOZ_ASSERT(aListID == kPrincipalList, "unexpected child list"); - MOZ_ASSERT(aChildList.OnlyChild(), - "initial child list must have exactly one child"); + MOZ_ASSERT(aListID != kPrincipalList || aChildList.OnlyChild(), + "initial principal child list must have exactly one child"); nsContainerFrame::SetInitialChildList(kPrincipalList, aChildList); } diff --git a/layout/generic/nsColumnSetFrame.h b/layout/generic/nsColumnSetFrame.h index 49860624d5..fefb298de5 100644 --- a/layout/generic/nsColumnSetFrame.h +++ b/layout/generic/nsColumnSetFrame.h @@ -45,7 +45,7 @@ public: virtual nscoord GetAvailableContentBSize(const nsHTMLReflowState& aReflowState); virtual nsContainerFrame* GetContentInsertionFrame() override { - nsIFrame* frame = GetFirstPrincipalChild(); + nsIFrame* frame = PrincipalChildList().FirstChild(); // if no children return nullptr if (!frame) diff --git a/layout/generic/nsContainerFrame.cpp b/layout/generic/nsContainerFrame.cpp index 72b5967a6c..6aec5df0da 100644 --- a/layout/generic/nsContainerFrame.cpp +++ b/layout/generic/nsContainerFrame.cpp @@ -27,6 +27,7 @@ #include "nsBoxLayoutState.h" #include "nsCSSFrameConstructor.h" #include "nsBlockFrame.h" +#include "nsPlaceholderFrame.h" #include "mozilla/AutoRestore.h" #include "nsIFrameInlines.h" #include "nsPrintfCString.h" @@ -69,13 +70,37 @@ void nsContainerFrame::SetInitialChildList(ChildListID aListID, nsFrameList& aChildList) { - MOZ_ASSERT(mFrames.IsEmpty(), - "unexpected second call to SetInitialChildList"); - MOZ_ASSERT(aListID == kPrincipalList, "unexpected child list"); #ifdef DEBUG nsFrame::VerifyDirtyBitSet(aChildList); #endif - mFrames.SetFrames(aChildList); + if (aListID == kPrincipalList) { + MOZ_ASSERT(mFrames.IsEmpty(), + "unexpected second call to SetInitialChildList"); + mFrames.SetFrames(aChildList); + } else if (aListID == kBackdropList) { + MOZ_ASSERT(StyleDisplay()->mTopLayer != NS_STYLE_TOP_LAYER_NONE, + "Only top layer frames should have backdrop"); + MOZ_ASSERT(GetStateBits() & NS_FRAME_OUT_OF_FLOW, + "Top layer frames should be out-of-flow"); + MOZ_ASSERT(!Properties().Get(BackdropProperty()), + "We shouldn't have setup backdrop frame list before"); +#ifdef DEBUG + { + nsIFrame* placeholder = aChildList.FirstChild(); + MOZ_ASSERT(aChildList.OnlyChild(), "Should have only one backdrop"); + MOZ_ASSERT(placeholder->GetType() == nsGkAtoms::placeholderFrame, + "The frame to be stored should be a placeholder"); + MOZ_ASSERT(static_cast(placeholder)-> + GetOutOfFlowFrame()->GetType() == nsGkAtoms::backdropFrame, + "The placeholder should points to a backdrop frame"); + } +#endif + nsFrameList* list = + new (PresContext()->PresShell()) nsFrameList(aChildList); + Properties().Set(BackdropProperty(), list); + } else { + MOZ_ASSERT_UNREACHABLE("Unexpected child list"); + } } void @@ -210,12 +235,16 @@ nsContainerFrame::DestroyFrom(nsIFrame* aDestructRoot) !(props->Get(this, nsContainerFrame::OverflowContainersProperty()) || props->Get(this, nsContainerFrame::ExcessOverflowContainersProperty())), "this type of frame should't have overflow containers"); - SafelyDestroyFrameListProp(aDestructRoot, shell, props, OverflowContainersProperty()); SafelyDestroyFrameListProp(aDestructRoot, shell, props, ExcessOverflowContainersProperty()); + MOZ_ASSERT(!props->Get(this, BackdropProperty()) || + StyleDisplay()->mTopLayer != NS_STYLE_TOP_LAYER_NONE, + "only top layer frame may have backdrop"); + SafelyDestroyFrameListProp(aDestructRoot, shell, props, BackdropProperty()); + nsSplittableFrame::DestroyFrom(aDestructRoot); } @@ -225,7 +254,8 @@ nsContainerFrame::DestroyFrom(nsIFrame* aDestructRoot) const nsFrameList& nsContainerFrame::GetChildList(ChildListID aListID) const { - // We only know about the principal child list and the overflow lists. + // We only know about the principal child list, the overflow lists, + // and the backdrop list. switch (aListID) { case kPrincipalList: return mFrames; @@ -242,6 +272,10 @@ nsContainerFrame::GetChildList(ChildListID aListID) const GetPropTableFrames(ExcessOverflowContainersProperty()); return list ? *list : nsFrameList::EmptyList(); } + case kBackdropList: { + nsFrameList* list = GetPropTableFrames(BackdropProperty()); + return list ? *list : nsFrameList::EmptyList(); + } default: return nsSplittableFrame::GetChildList(aListID); } @@ -273,6 +307,13 @@ nsContainerFrame::GetChildLists(nsTArray* aLists) const ::AppendIfNonempty(this, propTable, ExcessOverflowContainersProperty(), aLists, kExcessOverflowContainersList); } + // Bypass BackdropProperty hashtable lookup for any in-flow frames + // since frames in the top layer (only which can have backdrop) are + // definitely out-of-flow. + if (GetStateBits() & NS_FRAME_OUT_OF_FLOW) { + ::AppendIfNonempty(this, propTable, BackdropProperty(), + aLists, kBackdropList); + } nsSplittableFrame::GetChildLists(aLists); } diff --git a/layout/generic/nsContainerFrame.h b/layout/generic/nsContainerFrame.h index 6438d34765..f5c85ae41e 100644 --- a/layout/generic/nsContainerFrame.h +++ b/layout/generic/nsContainerFrame.h @@ -454,6 +454,7 @@ public: NS_DECLARE_FRAME_PROPERTY_FRAMELIST(OverflowProperty) NS_DECLARE_FRAME_PROPERTY_FRAMELIST(OverflowContainersProperty) NS_DECLARE_FRAME_PROPERTY_FRAMELIST(ExcessOverflowContainersProperty) + NS_DECLARE_FRAME_PROPERTY_FRAMELIST(BackdropProperty) #ifdef DEBUG // Use this to suppress the CRAZY_SIZE assertions. diff --git a/layout/generic/nsFirstLetterFrame.cpp b/layout/generic/nsFirstLetterFrame.cpp index bbd1869a0d..98cdc9b9ed 100644 --- a/layout/generic/nsFirstLetterFrame.cpp +++ b/layout/generic/nsFirstLetterFrame.cpp @@ -80,6 +80,8 @@ void nsFirstLetterFrame::SetInitialChildList(ChildListID aListID, nsFrameList& aChildList) { + MOZ_ASSERT(aListID == kPrincipalList, "Principal child list is the only " + "list that nsFirstLetterFrame should set via this function"); RestyleManager* restyleManager = PresContext()->RestyleManager(); for (nsFrameList::Enumerator e(aChildList); !e.AtEnd(); e.Next()) { diff --git a/layout/generic/nsFlexContainerFrame.cpp b/layout/generic/nsFlexContainerFrame.cpp index c13b1cddc6..d0ce1d6a13 100644 --- a/layout/generic/nsFlexContainerFrame.cpp +++ b/layout/generic/nsFlexContainerFrame.cpp @@ -928,7 +928,7 @@ GetFirstNonAnonBoxDescendant(nsIFrame* aFrame) } // USUAL CASE: Descend to the first child in principal list. - aFrame = aFrame->GetFirstPrincipalChild(); + aFrame = aFrame->PrincipalChildList().FirstChild(); } return aFrame; } @@ -2072,7 +2072,7 @@ nsFlexContainerFrame::SanityCheckAnonymousFlexItems() const "two anon flex items in a row (shouldn't happen, unless our " "children have been reordered with the 'order' property)"); - nsIFrame* firstWrappedChild = child->GetFirstPrincipalChild(); + nsIFrame* firstWrappedChild = child->PrincipalChildList().FirstChild(); MOZ_ASSERT(firstWrappedChild, "anonymous flex item is empty (shouldn't happen)"); prevChildWasAnonFlexItem = true; diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index e9d9430db2..85e7f15ce7 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -750,7 +750,7 @@ nsFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext) if (IsSVGText()) { SVGTextFrame* svgTextFrame = static_cast( nsLayoutUtils::GetClosestFrameOfType(this, nsGkAtoms::svgTextFrame)); - nsIFrame* anonBlock = svgTextFrame->GetFirstPrincipalChild(); + nsIFrame* anonBlock = svgTextFrame->PrincipalChildList().FirstChild(); // Just as in SVGTextFrame::DidSetStyleContext, we need to ensure that // any non-display SVGTextFrames get reflowed when a child text frame // gets new style. @@ -2387,12 +2387,9 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder, // dirty rect in child-relative coordinates nsRect dirty = aDirtyRect - child->GetOffsetTo(this); - const nsStyleDisplay* disp; nsIAtom* childType = child->GetType(); nsDisplayListBuilder::OutOfFlowDisplayData* savedOutOfFlowData = nullptr; - if (childType != nsGkAtoms::placeholderFrame) { - disp = child->StyleDisplay(); - } else { + if (childType == nsGkAtoms::placeholderFrame) { nsPlaceholderFrame* placeholder = static_cast(child); child = placeholder->GetOutOfFlowFrame(); NS_ASSERTION(child, "No out of flow frame?"); @@ -2403,13 +2400,12 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder, (child->GetStateBits() & NS_FRAME_IS_PUSHED_FLOAT)) return; MOZ_ASSERT(child->GetStateBits() & NS_FRAME_OUT_OF_FLOW); - disp = child->StyleDisplay(); // If the out-of-flow frame is in the top layer, the viewport frame // will paint it. Skip it here. Note that, only out-of-flow frames // with this property should be skipped, because non-HTML elements // may stop their children from being out-of-flow. Those frames // should still be handled in the normal in-flow path. - if (disp->mTopLayer != NS_STYLE_TOP_LAYER_NONE) { + if (placeholder->GetStateBits() & PLACEHOLDER_FOR_TOPLAYER) { return; } // Make sure that any attempt to use childType below is disappointed. We @@ -2489,6 +2485,7 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder, // Child is composited if it's transformed, partially transparent, or has // SVG effects or a blend mode.. + const nsStyleDisplay* disp = child->StyleDisplay(); const nsStylePosition* pos = child->StylePosition(); bool isVisuallyAtomic = child->HasOpacity() || child->IsTransformed() @@ -3668,7 +3665,7 @@ static FrameTarget DrillDownToSelectionFrame(nsIFrame* aFrame, bool aEndFrame, uint32_t aFlags) { if (SelectionDescendToKids(aFrame)) { nsIFrame* result = nullptr; - nsIFrame *frame = aFrame->GetFirstPrincipalChild(); + nsIFrame *frame = aFrame->PrincipalChildList().FirstChild(); if (!aEndFrame) { while (frame && (!SelfIsSelectable(frame, aFlags) || frame->IsEmpty())) @@ -3851,7 +3848,7 @@ static FrameTarget GetSelectionClosestFrame(nsIFrame* aFrame, nsPoint aPoint, return target; } - nsIFrame *kid = aFrame->GetFirstPrincipalChild(); + nsIFrame *kid = aFrame->PrincipalChildList().FirstChild(); if (kid) { // Go through all the child frames to find the closest one @@ -6629,7 +6626,7 @@ FindBlockFrameOrBR(nsIFrame* aFrame, nsDirection aDirection) child = child->GetPrevSibling(); } } else { // eDirNext - nsIFrame* child = aFrame->GetFirstPrincipalChild(); + nsIFrame* child = aFrame->PrincipalChildList().FirstChild(); while(child && !result.mContent) { result = FindBlockFrameOrBR(child, aDirection); child = child->GetNextSibling(); @@ -6941,7 +6938,7 @@ nsIFrame::PeekOffset(nsPeekOffsetStruct* aPos) if (aPos->mResultFrame->GetType() == nsGkAtoms::tableOuterFrame || aPos->mResultFrame->GetType() == nsGkAtoms::tableCellFrame) { - nsIFrame *frame = aPos->mResultFrame->GetFirstPrincipalChild(); + nsIFrame *frame = aPos->mResultFrame->PrincipalChildList().FirstChild(); //got the table frame now while(frame) //ok time to drill down to find iterator { @@ -6954,7 +6951,7 @@ nsIFrame::PeekOffset(nsPeekOffsetStruct* aPos) break; //while(frame) } result = NS_ERROR_FAILURE; - frame = frame->GetFirstPrincipalChild(); + frame = frame->PrincipalChildList().FirstChild(); } } @@ -7618,7 +7615,7 @@ ComputeAndIncludeOutlineArea(nsIFrame* aFrame, nsOverflowAreas& aOverflowAreas, pseudoType != nsCSSAnonBoxes::mozAnonymousPositionedBlock) break; // If we're done, we really want it and all its later siblings. - frameForArea = frameForArea->GetFirstPrincipalChild(); + frameForArea = frameForArea->PrincipalChildList().FirstChild(); NS_ASSERTION(frameForArea, "anonymous block with no children?"); } while (frameForArea); @@ -8056,7 +8053,7 @@ GetCorrectedParent(const nsIFrame* aFrame) // For a table caption we want the _inner_ table frame (unless it's anonymous) // as the style parent. if (aFrame->IsTableCaption()) { - nsIFrame* innerTable = parent->GetFirstPrincipalChild(); + nsIFrame* innerTable = parent->PrincipalChildList().FirstChild(); if (!innerTable->StyleContext()->GetPseudo()) { return innerTable; } @@ -8067,7 +8064,7 @@ GetCorrectedParent(const nsIFrame* aFrame) // know its parent. So get the pseudo of the inner in that case. nsIAtom* pseudo = aFrame->StyleContext()->GetPseudo(); if (pseudo == nsCSSAnonBoxes::tableOuter) { - pseudo = aFrame->GetFirstPrincipalChild()->StyleContext()->GetPseudo(); + pseudo = aFrame->PrincipalChildList().FirstChild()->StyleContext()->GetPseudo(); } return nsFrame::CorrectStyleParentFrame(parent, pseudo); } @@ -8205,7 +8202,7 @@ nsFrame::GetLastLeaf(nsPresContext* aPresContext, nsIFrame **aFrame) nsIFrame *child = *aFrame; //if we are a block frame then go for the last line of 'this' while (1){ - child = child->GetFirstPrincipalChild(); + child = child->PrincipalChildList().FirstChild(); if (!child) return;//nothing to do nsIFrame* siblingFrame; @@ -8227,7 +8224,7 @@ nsFrame::GetFirstLeaf(nsPresContext* aPresContext, nsIFrame **aFrame) return; nsIFrame *child = *aFrame; while (1){ - child = child->GetFirstPrincipalChild(); + child = child->PrincipalChildList().FirstChild(); if (!child) return;//nothing to do *aFrame = child; diff --git a/layout/generic/nsFrameIdList.h b/layout/generic/nsFrameIdList.h index 480f416291..69593790ef 100644 --- a/layout/generic/nsFrameIdList.h +++ b/layout/generic/nsFrameIdList.h @@ -6,6 +6,7 @@ FRAME_ID(BRFrame) FRAME_ID(DetailsFrame) FRAME_ID(nsAutoRepeatBoxFrame) FRAME_ID(nsBCTableCellFrame) +FRAME_ID(nsBackdropFrame) FRAME_ID(nsBlockFrame) FRAME_ID(nsBox) FRAME_ID(nsBoxFrame) diff --git a/layout/generic/nsFrameList.h b/layout/generic/nsFrameList.h index 7084b677da..98dc009255 100644 --- a/layout/generic/nsFrameList.h +++ b/layout/generic/nsFrameList.h @@ -41,9 +41,10 @@ namespace layout { kFloatList = 0x800, kBulletList = 0x1000, kPushedFloatsList = 0x2000, + kBackdropList = 0x4000, // A special alias for kPrincipalList that suppress the reflow request that // is normally done when manipulating child lists. - kNoReflowPrincipalList = 0x4000 + kNoReflowPrincipalList = 0x8000 }; } // namespace layout } // namespace mozilla @@ -244,6 +245,11 @@ public: bool ContainsFrame(const nsIFrame* aFrame) const; + /** + * Get the number of frames in this list. Note that currently the + * implementation has O(n) time complexity. Do not call it repeatedly in hot + * code. + */ int32_t GetLength() const; /** diff --git a/layout/generic/nsFrameStateBits.h b/layout/generic/nsFrameStateBits.h index 3e721d6ef2..b22a3feaf2 100644 --- a/layout/generic/nsFrameStateBits.h +++ b/layout/generic/nsFrameStateBits.h @@ -549,6 +549,7 @@ FRAME_STATE_BIT(Placeholder, 20, PLACEHOLDER_FOR_FLOAT) FRAME_STATE_BIT(Placeholder, 21, PLACEHOLDER_FOR_ABSPOS) FRAME_STATE_BIT(Placeholder, 22, PLACEHOLDER_FOR_FIXEDPOS) FRAME_STATE_BIT(Placeholder, 23, PLACEHOLDER_FOR_POPUP) +FRAME_STATE_BIT(Placeholder, 24, PLACEHOLDER_FOR_TOPLAYER) // == Frame state bits that apply to table cell frames ======================== diff --git a/layout/generic/nsGfxScrollFrame.cpp b/layout/generic/nsGfxScrollFrame.cpp index 8410488b7d..f519b0eae7 100644 --- a/layout/generic/nsGfxScrollFrame.cpp +++ b/layout/generic/nsGfxScrollFrame.cpp @@ -602,7 +602,7 @@ nsHTMLScrollFrame::GuessVScrollbarNeeded(const ScrollReflowState& aState) return false; if (mHelper.mIsRoot) { - nsIFrame *f = mHelper.mScrolledFrame->GetFirstPrincipalChild(); + nsIFrame *f = mHelper.mScrolledFrame->PrincipalChildList().FirstChild(); if (f && f->GetType() == nsGkAtoms::svgOuterSVGFrame && static_cast(f)->VerticalScrollbarNotNeeded()) { // Common SVG case - avoid a bad guess. @@ -1313,7 +1313,9 @@ nsXULScrollFrame::SetInitialChildList(ChildListID aListID, nsFrameList& aChildList) { nsBoxFrame::SetInitialChildList(aListID, aChildList); - mHelper.ReloadChildFrames(); + if (aListID == kPrincipalList) { + mHelper.ReloadChildFrames(); + } } @@ -3873,8 +3875,7 @@ ScrollFrameHelper::ReloadChildFrames() mScrollCornerBox = nullptr; mResizerBox = nullptr; - nsIFrame* frame = mOuter->GetFirstPrincipalChild(); - while (frame) { + for (nsIFrame* frame : mOuter->PrincipalChildList()) { nsIContent* content = frame->GetContent(); if (content == mOuter->GetContent()) { NS_ASSERTION(!mScrolledFrame, "Already found the scrolled frame"); @@ -3900,8 +3901,6 @@ ScrollFrameHelper::ReloadChildFrames() mScrollCornerBox = frame; } } - - frame = frame->GetNextSibling(); } } @@ -5297,7 +5296,7 @@ ScrollFrameHelper::GetScrolledRectInternal(const nsRect& aScrolledFrameOverflowA // direction set by the text content overrides the direction of the frame if (mScrolledFrame->StyleTextReset()->mUnicodeBidi & NS_STYLE_UNICODE_BIDI_PLAINTEXT) { - nsIFrame* childFrame = mScrolledFrame->GetFirstPrincipalChild(); + nsIFrame* childFrame = mScrolledFrame->PrincipalChildList().FirstChild(); if (childFrame) { frameDir = (nsBidiPresUtils::ParagraphDirection(childFrame) == NSBIDI_LTR) diff --git a/layout/generic/nsGridContainerFrame.cpp b/layout/generic/nsGridContainerFrame.cpp index 5bf9e0bd2f..fe7408300a 100644 --- a/layout/generic/nsGridContainerFrame.cpp +++ b/layout/generic/nsGridContainerFrame.cpp @@ -3554,7 +3554,7 @@ nsGridContainerFrame::SanityCheckAnonymousGridItems() const "children have been reordered with the 'order' property)"); */ MOZ_ASSERT(!prevChildWasAnonGridItem, "two anon grid items in a row"); - nsIFrame* firstWrappedChild = child->GetFirstPrincipalChild(); + nsIFrame* firstWrappedChild = child->PrincipalChildList().FirstChild(); MOZ_ASSERT(firstWrappedChild, "anonymous grid item is empty (shouldn't happen)"); prevChildWasAnonGridItem = true; diff --git a/layout/generic/nsHTMLCanvasFrame.h b/layout/generic/nsHTMLCanvasFrame.h index a783aa36d4..db43654874 100644 --- a/layout/generic/nsHTMLCanvasFrame.h +++ b/layout/generic/nsHTMLCanvasFrame.h @@ -96,7 +96,7 @@ public: // Inserted child content gets its frames parented by our child block virtual nsContainerFrame* GetContentInsertionFrame() override { - return GetFirstPrincipalChild()->GetContentInsertionFrame(); + return PrincipalChildList().FirstChild()->GetContentInsertionFrame(); } protected: diff --git a/layout/generic/nsHTMLReflowState.cpp b/layout/generic/nsHTMLReflowState.cpp index f63a12b55b..ed374be169 100644 --- a/layout/generic/nsHTMLReflowState.cpp +++ b/layout/generic/nsHTMLReflowState.cpp @@ -571,7 +571,7 @@ nsHTMLReflowState::InitResizeFlags(nsPresContext* aPresContext, nsIAtom* aFrameT if (frame->GetType() == nsGkAtoms::svgForeignObjectFrame) { // Foreign object frames use dirty bits in a special way. frame->AddStateBits(NS_FRAME_HAS_DIRTY_CHILDREN); - nsIFrame *kid = frame->GetFirstPrincipalChild(); + nsIFrame *kid = frame->PrincipalChildList().FirstChild(); if (kid) { kid->AddStateBits(NS_FRAME_IS_DIRTY); } diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index 623e43af83..afe02ae0d2 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -1064,7 +1064,7 @@ public: * frame type, an empty list will be returned. */ virtual const nsFrameList& GetChildList(ChildListID aListID) const = 0; - const nsFrameList& PrincipalChildList() { return GetChildList(kPrincipalList); } + const nsFrameList& PrincipalChildList() const { return GetChildList(kPrincipalList); } virtual void GetChildLists(nsTArray* aLists) const = 0; /** @@ -1073,10 +1073,6 @@ public: */ void GetCrossDocChildLists(nsTArray* aLists); - nsIFrame* GetFirstPrincipalChild() const { - return GetChildList(kPrincipalList).FirstChild(); - } - // The individual concrete child lists. static const ChildListID kPrincipalList = mozilla::layout::kPrincipalList; static const ChildListID kAbsoluteList = mozilla::layout::kAbsoluteList; @@ -1092,6 +1088,7 @@ public: static const ChildListID kPopupList = mozilla::layout::kPopupList; static const ChildListID kPushedFloatsList = mozilla::layout::kPushedFloatsList; static const ChildListID kSelectPopupList = mozilla::layout::kSelectPopupList; + static const ChildListID kBackdropList = mozilla::layout::kBackdropList; // A special alias for kPrincipalList that do not request reflow. static const ChildListID kNoReflowPrincipalList = mozilla::layout::kNoReflowPrincipalList; diff --git a/layout/generic/nsInlineFrame.cpp b/layout/generic/nsInlineFrame.cpp index 190e3678b1..f4e9cb2a75 100644 --- a/layout/generic/nsInlineFrame.cpp +++ b/layout/generic/nsInlineFrame.cpp @@ -659,7 +659,7 @@ nsInlineFrame::ReflowFrames(nsPresContext* aPresContext, // so nsFirstLetterFrame::Reflow can destroy them safely (bug 401042). nsIFrame* realFrame = nsPlaceholderFrame::GetRealFrameFor(frame); if (realFrame->GetType() == nsGkAtoms::letterFrame) { - nsIFrame* child = realFrame->GetFirstPrincipalChild(); + nsIFrame* child = realFrame->PrincipalChildList().FirstChild(); if (child) { NS_ASSERTION(child->GetType() == nsGkAtoms::textFrame, "unexpected frame type"); diff --git a/layout/generic/nsLeafFrame.cpp b/layout/generic/nsLeafFrame.cpp index 1650852054..7d8eade4c0 100644 --- a/layout/generic/nsLeafFrame.cpp +++ b/layout/generic/nsLeafFrame.cpp @@ -19,7 +19,6 @@ nsLeafFrame::GetMinISize(nsRenderingContext *aRenderingContext) { nscoord result; DISPLAY_MIN_WIDTH(this, result); - result = GetIntrinsicISize(); return result; } @@ -76,18 +75,15 @@ nsLeafFrame::DoReflow(nsPresContext* aPresContext, { NS_ASSERTION(aReflowState.ComputedWidth() != NS_UNCONSTRAINEDSIZE, "Shouldn't have unconstrained stuff here " - "Thanks to the rules of reflow"); + "thanks to the rules of reflow"); NS_ASSERTION(NS_INTRINSICSIZE != aReflowState.ComputedHeight(), "Shouldn't have unconstrained stuff here " "thanks to ComputeAutoSize"); + // XXX how should border&padding effect baseline alignment? + // => descent = borderPadding.bottom for example WritingMode wm = aReflowState.GetWritingMode(); - LogicalSize finalSize(wm, - aReflowState.ComputedISize(), - aReflowState.ComputedBSize()); - - AddBordersAndPadding(aReflowState, finalSize); - aMetrics.SetSize(wm, finalSize); + aMetrics.SetSize(wm, aReflowState.ComputedSizeWithBorderPadding()); aStatus = NS_FRAME_COMPLETE; @@ -106,17 +102,6 @@ nsLeafFrame::GetIntrinsicBSize() return 0; } -// XXX how should border&padding effect baseline alignment? -// => descent = borderPadding.bottom for example -void -nsLeafFrame::AddBordersAndPadding(const nsHTMLReflowState& aReflowState, - LogicalSize& aSize) -{ - WritingMode wm = aReflowState.GetWritingMode(); - aSize.ISize(wm) += aReflowState.ComputedLogicalBorderPadding().IStartEnd(wm); - aSize.BSize(wm) += aReflowState.ComputedLogicalBorderPadding().BStartEnd(wm); -} - void nsLeafFrame::SizeToAvailSize(const nsHTMLReflowState& aReflowState, nsHTMLReflowMetrics& aDesiredSize) diff --git a/layout/generic/nsLeafFrame.h b/layout/generic/nsLeafFrame.h index 57606b9e0e..23f43d6ad5 100644 --- a/layout/generic/nsLeafFrame.h +++ b/layout/generic/nsLeafFrame.h @@ -84,11 +84,6 @@ protected: * Return the intrinsic isize of the frame's content area. Note that this * should not include borders or padding and should not depend on the applied * styles. - * One exception to this is that the intrinsic (logical) size of an - nsLeafFrame::DoReflow(aPresContext, aDesiredSize, aReflowState, aStatus); + aDesiredSize.SetSize(aReflowState.GetWritingMode(), + aReflowState.ComputedSizeWithBorderPadding()); // "offset" is the offset of our content area from our frame's // top-left corner. @@ -1018,7 +1024,7 @@ nsSubDocumentFrame::DestroyFrom(nsIFrame* aDestructRoot) } } - nsLeafFrame::DestroyFrom(aDestructRoot); + nsSubDocumentFrameSuper::DestroyFrom(aDestructRoot); } CSSIntSize @@ -1297,7 +1303,7 @@ nsSubDocumentFrame::ObtainIntrinsicSizeFrame() if (scrollable) { nsIFrame* scrolled = scrollable->GetScrolledFrame(); if (scrolled) { - subDocRoot = scrolled->GetFirstPrincipalChild(); + subDocRoot = scrolled->PrincipalChildList().FirstChild(); } } } diff --git a/layout/generic/nsSubDocumentFrame.h b/layout/generic/nsSubDocumentFrame.h index 2251ba4dfb..98916cfb99 100644 --- a/layout/generic/nsSubDocumentFrame.h +++ b/layout/generic/nsSubDocumentFrame.h @@ -7,15 +7,17 @@ #define NSSUBDOCUMENTFRAME_H_ #include "mozilla/Attributes.h" -#include "nsLeafFrame.h" +#include "nsAtomicContainerFrame.h" #include "nsIReflowCallback.h" #include "nsFrameLoader.h" #include "Units.h" +typedef nsAtomicContainerFrame nsSubDocumentFrameSuper; + /****************************************************************************** * nsSubDocumentFrame *****************************************************************************/ -class nsSubDocumentFrame : public nsLeafFrame, +class nsSubDocumentFrame : public nsSubDocumentFrameSuper, public nsIReflowCallback { public: @@ -35,8 +37,7 @@ public: virtual bool IsFrameOfType(uint32_t aFlags) const override { - // nsLeafFrame is already eReplacedContainsBlock, but that's somewhat bogus - return nsLeafFrame::IsFrameOfType(aFlags & + return nsSubDocumentFrameSuper::IsFrameOfType(aFlags & ~(nsIFrame::eReplaced | nsIFrame::eReplacedSizing | nsIFrame::eReplacedContainsBlock)); @@ -140,8 +141,8 @@ protected: bool IsInline() { return mIsInline; } - virtual nscoord GetIntrinsicISize() override; - virtual nscoord GetIntrinsicBSize() override; + nscoord GetIntrinsicISize(); + nscoord GetIntrinsicBSize(); // Show our document viewer. The document viewer is hidden via a script // runner, so that we can save and restore the presentation if we're diff --git a/layout/generic/nsTextFrame.cpp b/layout/generic/nsTextFrame.cpp index dea58d888a..27b9b00a8b 100644 --- a/layout/generic/nsTextFrame.cpp +++ b/layout/generic/nsTextFrame.cpp @@ -1146,7 +1146,7 @@ CanTextCrossFrameBoundary(nsIFrame* aFrame, nsIAtom* aType) } } else { if (continuesTextRun) { - result.mFrameToScan = aFrame->GetFirstPrincipalChild(); + result.mFrameToScan = aFrame->PrincipalChildList().FirstChild(); result.mOverflowFrameToScan = aFrame->GetChildList(nsIFrame::kOverflowList).FirstChild(); NS_WARN_IF_FALSE(!result.mOverflowFrameToScan, diff --git a/layout/generic/nsViewportFrame.cpp b/layout/generic/nsViewportFrame.cpp index 15f80eee7a..25466f9092 100644 --- a/layout/generic/nsViewportFrame.cpp +++ b/layout/generic/nsViewportFrame.cpp @@ -141,6 +141,14 @@ ViewportFrame::BuildDisplayListForTopLayer(nsDisplayListBuilder* aBuilder, continue; } MOZ_ASSERT(frame->GetParent() == this); + if (nsIFrame* backdropPh = + frame->GetChildList(kBackdropList).FirstChild()) { + MOZ_ASSERT(backdropPh->GetType() == nsGkAtoms::placeholderFrame); + nsIFrame* backdropFrame = + static_cast(backdropPh)->GetOutOfFlowFrame(); + MOZ_ASSERT(backdropFrame); + BuildDisplayListForTopLayerFrame(aBuilder, backdropFrame, aList); + } BuildDisplayListForTopLayerFrame(aBuilder, frame, aList); } } @@ -156,14 +164,6 @@ ViewportFrame::BuildDisplayListForTopLayer(nsDisplayListBuilder* aBuilder, } #ifdef DEBUG -void -ViewportFrame::SetInitialChildList(ChildListID aListID, - nsFrameList& aChildList) -{ - nsFrame::VerifyDirtyBitSet(aChildList); - nsContainerFrame::SetInitialChildList(aListID, aChildList); -} - void ViewportFrame::AppendFrames(ChildListID aListID, nsFrameList& aFrameList) diff --git a/layout/generic/nsViewportFrame.h b/layout/generic/nsViewportFrame.h index 13b5950454..e56aa68661 100644 --- a/layout/generic/nsViewportFrame.h +++ b/layout/generic/nsViewportFrame.h @@ -48,8 +48,6 @@ public: } #ifdef DEBUG - virtual void SetInitialChildList(ChildListID aListID, - nsFrameList& aChildList) override; virtual void AppendFrames(ChildListID aListID, nsFrameList& aFrameList) override; virtual void InsertFrames(ChildListID aListID, diff --git a/layout/inspector/tests/test_getCSSPseudoElementNames.html b/layout/inspector/tests/test_getCSSPseudoElementNames.html index 6085a018c9..691edfbc4a 100644 --- a/layout/inspector/tests/test_getCSSPseudoElementNames.html +++ b/layout/inspector/tests/test_getCSSPseudoElementNames.html @@ -12,6 +12,7 @@ let expected = new Set([ ":after", ":before", + ":backdrop", ":first-letter", ":first-line", ":-moz-color-swatch", diff --git a/layout/mathml/nsMathMLContainerFrame.cpp b/layout/mathml/nsMathMLContainerFrame.cpp index 149af15161..27326d523a 100644 --- a/layout/mathml/nsMathMLContainerFrame.cpp +++ b/layout/mathml/nsMathMLContainerFrame.cpp @@ -218,7 +218,7 @@ nsMathMLContainerFrame::GetPreferredStretchSize(DrawTarget* aDrawTarget bool firstTime = true; nsBoundingMetrics bm, bmChild; nsIFrame* childFrame = - stretchAll ? GetFirstPrincipalChild() : mPresentationData.baseFrame; + stretchAll ? PrincipalChildList().FirstChild() : mPresentationData.baseFrame; while (childFrame) { // initializations in case this child happens not to be a MathML frame nsIMathMLFrame* mathMLFrame = do_QueryFrame(childFrame); @@ -482,7 +482,7 @@ nsMathMLContainerFrame::FinalizeReflow(DrawTarget* aDrawTarget, // through Stretch() eventually. if (NS_MATHML_HAS_ERROR(mPresentationData.flags) || NS_FAILED(rv)) { GatherAndStoreOverflow(&aDesiredSize); - DidReflowChildren(GetFirstPrincipalChild()); + DidReflowChildren(PrincipalChildList().FirstChild()); return rv; } @@ -531,8 +531,7 @@ nsMathMLContainerFrame::FinalizeReflow(DrawTarget* aDrawTarget, { // The Place() call above didn't request FinishReflowChild(), // so let's check that we eventually did through Stretch(). - nsIFrame* childFrame = GetFirstPrincipalChild(); - for ( ; childFrame; childFrame = childFrame->GetNextSibling()) { + for (nsIFrame* childFrame : PrincipalChildList()) { NS_ASSERTION(!(childFrame->GetStateBits() & NS_FRAME_IN_REFLOW), "DidReflow() was never called"); } @@ -587,11 +586,9 @@ nsMathMLContainerFrame::PropagatePresentationDataFor(nsIFrame* aFrame, } else { // propagate down the subtrees - nsIFrame* childFrame = aFrame->GetFirstPrincipalChild(); - while (childFrame) { + for (nsIFrame* childFrame : aFrame->PrincipalChildList()) { PropagatePresentationDataFor(childFrame, aFlagsValues, aFlagsToUpdate); - childFrame = childFrame->GetNextSibling(); } } } @@ -606,8 +603,7 @@ nsMathMLContainerFrame::PropagatePresentationDataFromChildAt(nsIFrame* aPa if (!aParentFrame || !aFlagsToUpdate) return; int32_t index = 0; - nsIFrame* childFrame = aParentFrame->GetFirstPrincipalChild(); - while (childFrame) { + for (nsIFrame* childFrame : aParentFrame->PrincipalChildList()) { if ((index >= aFirstChildIndex) && ((aLastChildIndex <= 0) || ((aLastChildIndex > 0) && (index <= aLastChildIndex)))) { @@ -615,7 +611,6 @@ nsMathMLContainerFrame::PropagatePresentationDataFromChildAt(nsIFrame* aPa aFlagsValues, aFlagsToUpdate); } index++; - childFrame = childFrame->GetNextSibling(); } } @@ -666,14 +661,12 @@ nsMathMLContainerFrame::RebuildAutomaticDataForChildren(nsIFrame* aParentFrame) // the parent // 2. As we ascend the tree, transmit any specific change that we want // down the subtrees - nsIFrame* childFrame = aParentFrame->GetFirstPrincipalChild(); - while (childFrame) { + for (nsIFrame* childFrame : aParentFrame->PrincipalChildList()) { nsIMathMLFrame* childMathMLFrame = do_QueryFrame(childFrame); if (childMathMLFrame) { childMathMLFrame->InheritAutomaticData(aParentFrame); } RebuildAutomaticDataForChildren(childFrame); - childFrame = childFrame->GetNextSibling(); } nsIMathMLFrame* mathMLFrame = do_QueryFrame(aParentFrame); if (mathMLFrame) { @@ -1375,7 +1368,7 @@ GetInterFrameSpacingFor(int32_t aScriptLevel, nsIFrame* aParentFrame, nsIFrame* aChildFrame) { - nsIFrame* childFrame = aParentFrame->GetFirstPrincipalChild(); + nsIFrame* childFrame = aParentFrame->PrincipalChildList().FirstChild(); if (!childFrame || aChildFrame == childFrame) return 0; @@ -1463,7 +1456,7 @@ nsMathMLContainerFrame::DidReflowChildren(nsIFrame* aFirst, nsIFrame* aStop) NS_ASSERTION(frame, "aStop isn't a sibling"); if (frame->GetStateBits() & NS_FRAME_IN_REFLOW) { // finish off principal descendants, too - nsIFrame* grandchild = frame->GetFirstPrincipalChild(); + nsIFrame* grandchild = frame->PrincipalChildList().FirstChild(); if (grandchild) DidReflowChildren(grandchild, nullptr); @@ -1501,7 +1494,7 @@ nsMathMLContainerFrame::TransmitAutomaticDataForMrowLikeElement() bool embellishedOpFound = false; nsEmbellishData embellishData; - for (childFrame = GetFirstPrincipalChild(); + for (childFrame = PrincipalChildList().FirstChild(); childFrame; childFrame = childFrame->GetNextSibling()) { nsIMathMLFrame* mathMLFrame = do_QueryFrame(childFrame); @@ -1555,10 +1548,8 @@ nsMathMLContainerFrame::PropagateFrameFlagFor(nsIFrame* aFrame, return; aFrame->AddStateBits(aFlags); - nsIFrame* childFrame = aFrame->GetFirstPrincipalChild(); - while (childFrame) { + for (nsIFrame* childFrame : aFrame->PrincipalChildList()) { PropagateFrameFlagFor(childFrame, aFlags); - childFrame = childFrame->GetNextSibling(); } } diff --git a/layout/mathml/nsMathMLTokenFrame.cpp b/layout/mathml/nsMathMLTokenFrame.cpp index 73d58b28e9..dc6b793397 100644 --- a/layout/mathml/nsMathMLTokenFrame.cpp +++ b/layout/mathml/nsMathMLTokenFrame.cpp @@ -64,9 +64,9 @@ nsMathMLTokenFrame::MarkTextFramesAsTokenMathML() // - to force them to trim their leading and trailing whitespaces. // - Indicate which frames are suitable for mathvariant // - flag single character frames for special italic treatment - for (nsIFrame* childFrame = GetFirstPrincipalChild(); childFrame; + for (nsIFrame* childFrame = PrincipalChildList().FirstChild(); childFrame; childFrame = childFrame->GetNextSibling()) { - for (nsIFrame* childFrame2 = childFrame->GetFirstPrincipalChild(); + for (nsIFrame* childFrame2 = childFrame->PrincipalChildList().FirstChild(); childFrame2; childFrame2 = childFrame2->GetNextSibling()) { if (childFrame2->GetType() == nsGkAtoms::textFrame) { childFrame2->AddStateBits(TEXT_IS_IN_TOKEN_MATHML); @@ -132,8 +132,7 @@ nsMathMLTokenFrame::Reflow(nsPresContext* aPresContext, aDesiredSize.SetBlockStartAscent(0); aDesiredSize.mBoundingMetrics = nsBoundingMetrics(); - nsIFrame* childFrame = GetFirstPrincipalChild(); - while (childFrame) { + for (nsIFrame* childFrame : PrincipalChildList()) { // ask our children to compute their bounding metrics nsHTMLReflowMetrics childDesiredSize(aReflowState.GetWritingMode(), aDesiredSize.mFlags @@ -148,8 +147,6 @@ nsMathMLTokenFrame::Reflow(nsPresContext* aPresContext, //NS_ASSERTION(NS_FRAME_IS_COMPLETE(aStatus), "bad status"); SaveReflowAndBoundingMetricsFor(childFrame, childDesiredSize, childDesiredSize.mBoundingMetrics); - - childFrame = childFrame->GetNextSibling(); } // place and size children @@ -168,8 +165,7 @@ nsMathMLTokenFrame::Place(DrawTarget* aDrawTarget, nsHTMLReflowMetrics& aDesiredSize) { mBoundingMetrics = nsBoundingMetrics(); - for (nsIFrame* childFrame = GetFirstPrincipalChild(); childFrame; - childFrame = childFrame->GetNextSibling()) { + for (nsIFrame* childFrame :PrincipalChildList()) { nsHTMLReflowMetrics childSize(aDesiredSize.GetWritingMode()); GetReflowAndBoundingMetricsFor(childFrame, childSize, childSize.mBoundingMetrics, nullptr); @@ -192,8 +188,7 @@ nsMathMLTokenFrame::Place(DrawTarget* aDrawTarget, if (aPlaceOrigin) { nscoord dy, dx = 0; - for (nsIFrame* childFrame = GetFirstPrincipalChild(); childFrame; - childFrame = childFrame->GetNextSibling()) { + for (nsIFrame* childFrame : PrincipalChildList()) { nsHTMLReflowMetrics childSize(aDesiredSize.GetWritingMode()); GetReflowAndBoundingMetricsFor(childFrame, childSize, childSize.mBoundingMetrics); diff --git a/layout/mathml/nsMathMLmencloseFrame.cpp b/layout/mathml/nsMathMLmencloseFrame.cpp index 149e9b5cfc..9dc02df765 100644 --- a/layout/mathml/nsMathMLmencloseFrame.cpp +++ b/layout/mathml/nsMathMLmencloseFrame.cpp @@ -327,7 +327,7 @@ nsMathMLmencloseFrame::PlaceInternal(DrawTarget* aDrawTarget, nsMathMLContainerFrame::Place(aDrawTarget, false, baseSize); if (NS_MATHML_HAS_ERROR(mPresentationData.flags) || NS_FAILED(rv)) { - DidReflowChildren(GetFirstPrincipalChild()); + DidReflowChildren(PrincipalChildList().FirstChild()); return rv; } diff --git a/layout/mathml/nsMathMLmfencedFrame.cpp b/layout/mathml/nsMathMLmfencedFrame.cpp index 56d665f0a8..915e3a05a3 100644 --- a/layout/mathml/nsMathMLmfencedFrame.cpp +++ b/layout/mathml/nsMathMLmfencedFrame.cpp @@ -245,7 +245,7 @@ nsMathMLmfencedFrame::Reflow(nsPresContext* aPresContext, // refactored to use nsMathMLContainerFrame::Reflow() at some stage. nsReflowStatus childStatus; - nsIFrame* firstChild = GetFirstPrincipalChild(); + nsIFrame* firstChild = PrincipalChildList().FirstChild(); nsIFrame* childFrame = firstChild; nscoord ascent = 0, descent = 0; if (firstChild || mOpenChar || mCloseChar || mSeparatorsCount > 0) { @@ -626,8 +626,7 @@ nsMathMLmfencedFrame::GetIntrinsicISizeMetrics(nsRenderingContext* aRenderingCon } int32_t i = 0; - nsIFrame* childFrame = GetFirstPrincipalChild(); - while (childFrame) { + for (nsIFrame* childFrame : PrincipalChildList()) { // XXX This includes margin while Reflow currently doesn't consider // margin, so we may end up with too much space, but, with stretchy // characters, this is an approximation anyway. @@ -641,8 +640,6 @@ nsMathMLmfencedFrame::GetIntrinsicISizeMetrics(nsRenderingContext* aRenderingCon NS_MATHML_OPERATOR_FORM_INFIX, font->mScriptLevel, em); } i++; - - childFrame = childFrame->GetNextSibling(); } if (mCloseChar) { diff --git a/layout/mathml/nsMathMLmmultiscriptsFrame.cpp b/layout/mathml/nsMathMLmmultiscriptsFrame.cpp index e0c8700d83..6c3a349c70 100644 --- a/layout/mathml/nsMathMLmmultiscriptsFrame.cpp +++ b/layout/mathml/nsMathMLmmultiscriptsFrame.cpp @@ -173,7 +173,7 @@ nsMathMLmmultiscriptsFrame::PlaceMultiScript(nsPresContext* aPresContext, // depend only on the current font //////////////////////////////////////// - nsIFrame* baseFrame = aFrame->GetFirstPrincipalChild(); + nsIFrame* baseFrame = aFrame->PrincipalChildList().FirstChild(); if (!baseFrame) { if (tag == nsGkAtoms::mmultiscripts_) @@ -322,7 +322,7 @@ nsMathMLmmultiscriptsFrame::PlaceMultiScript(nsPresContext* aPresContext, // Note that only msup starts with a superscript. bool isSubScript = (tag != nsGkAtoms::msup_); - nsIFrame* childFrame = aFrame->GetFirstPrincipalChild(); + nsIFrame* childFrame = aFrame->PrincipalChildList().FirstChild(); while (childFrame) { if (childFrame->GetContent()->IsMathMLElement(nsGkAtoms::mprescripts_)) { if (tag != nsGkAtoms::mmultiscripts_) { diff --git a/layout/mathml/nsMathMLmpaddedFrame.cpp b/layout/mathml/nsMathMLmpaddedFrame.cpp index aefdabd8e4..b24f93e741 100644 --- a/layout/mathml/nsMathMLmpaddedFrame.cpp +++ b/layout/mathml/nsMathMLmpaddedFrame.cpp @@ -326,7 +326,7 @@ nsMathMLmpaddedFrame::Place(DrawTarget* aDrawTarget, nsresult rv = nsMathMLContainerFrame::Place(aDrawTarget, false, aDesiredSize); if (NS_MATHML_HAS_ERROR(mPresentationData.flags) || NS_FAILED(rv)) { - DidReflowChildren(GetFirstPrincipalChild()); + DidReflowChildren(PrincipalChildList().FirstChild()); return rv; } diff --git a/layout/mathml/nsMathMLmrowFrame.cpp b/layout/mathml/nsMathMLmrowFrame.cpp index 5bdcff1706..65b9e0fd5f 100644 --- a/layout/mathml/nsMathMLmrowFrame.cpp +++ b/layout/mathml/nsMathMLmrowFrame.cpp @@ -43,7 +43,7 @@ nsMathMLmrowFrame::AttributeChanged(int32_t aNameSpaceID, // notification to the real mtable if (mContent->IsMathMLElement(nsGkAtoms::mtable_)) { nsIFrame* frame = mFrames.FirstChild(); - for ( ; frame; frame = frame->GetFirstPrincipalChild()) { + for ( ; frame; frame = frame->PrincipalChildList().FirstChild()) { // drill down to the real mtable if (frame->GetType() == nsGkAtoms::tableOuterFrame) return frame->AttributeChanged(aNameSpaceID, aAttribute, aModType); diff --git a/layout/mathml/nsMathMLmtableFrame.cpp b/layout/mathml/nsMathMLmtableFrame.cpp index b1dbc917dd..8b286823d7 100644 --- a/layout/mathml/nsMathMLmtableFrame.cpp +++ b/layout/mathml/nsMathMLmtableFrame.cpp @@ -577,12 +577,11 @@ MapAllAttributesIntoCSS(nsMathMLmtableFrame* aTableFrame) ParseSpacingAttributes(aTableFrame); // mtable is simple and only has one (pseudo) row-group - nsIFrame* rgFrame = aTableFrame->GetFirstPrincipalChild(); + nsIFrame* rgFrame = aTableFrame->PrincipalChildList().FirstChild(); if (!rgFrame || rgFrame->GetType() != nsGkAtoms::tableRowGroupFrame) return; - nsIFrame* rowFrame = rgFrame->GetFirstPrincipalChild(); - for ( ; rowFrame; rowFrame = rowFrame->GetNextSibling()) { + for (nsIFrame* rowFrame : rgFrame->PrincipalChildList()) { DEBUG_VERIFY_THAT_FRAME_IS(rowFrame, TABLE_ROW); if (rowFrame->GetType() == nsGkAtoms::tableRowFrame) { // Map row rowalign. @@ -590,8 +589,7 @@ MapAllAttributesIntoCSS(nsMathMLmtableFrame* aTableFrame) // Map row columnalign. ParseFrameAttribute(rowFrame, nsGkAtoms::columnalign_, true); - nsIFrame* cellFrame = rowFrame->GetFirstPrincipalChild(); - for ( ; cellFrame; cellFrame = cellFrame->GetNextSibling()) { + for (nsIFrame* cellFrame : rowFrame->PrincipalChildList()) { DEBUG_VERIFY_THAT_FRAME_IS(cellFrame, TABLE_CELL); if (IS_TABLE_CELL(cellFrame->GetType())) { // Map cell rowalign. @@ -725,7 +723,7 @@ nsMathMLmtableOuterFrame::AttributeChanged(int32_t aNameSpaceID, nsIFrame* tableFrame = mFrames.FirstChild(); NS_ASSERTION(tableFrame && tableFrame->GetType() == nsGkAtoms::tableFrame, "should always have an inner table frame"); - nsIFrame* rgFrame = tableFrame->GetFirstPrincipalChild(); + nsIFrame* rgFrame = tableFrame->PrincipalChildList().FirstChild(); if (!rgFrame || rgFrame->GetType() != nsGkAtoms::tableRowGroupFrame) return NS_OK; @@ -798,7 +796,7 @@ nsMathMLmtableOuterFrame::GetRowFrameAt(int32_t aRowIndex) nsIFrame* tableFrame = mFrames.FirstChild(); NS_ASSERTION(tableFrame && tableFrame->GetType() == nsGkAtoms::tableFrame, "should always have an inner table frame"); - nsIFrame* rgFrame = tableFrame->GetFirstPrincipalChild(); + nsIFrame* rgFrame = tableFrame->PrincipalChildList().FirstChild(); if (!rgFrame || rgFrame->GetType() != nsGkAtoms::tableRowGroupFrame) return nullptr; for (nsIFrame* rowFrame : rgFrame->PrincipalChildList()) { diff --git a/layout/printing/nsPrintEngine.cpp b/layout/printing/nsPrintEngine.cpp index de26a45b24..bb708394b5 100644 --- a/layout/printing/nsPrintEngine.cpp +++ b/layout/printing/nsPrintEngine.cpp @@ -2236,11 +2236,7 @@ nsPrintEngine::CalcNumPrintablePages(int32_t& aNumPages) nsIPageSequenceFrame* pageSequence = po->mPresShell->GetPageSequenceFrame(); nsIFrame * seqFrame = do_QueryFrame(pageSequence); if (seqFrame) { - nsIFrame* frame = seqFrame->GetFirstPrincipalChild(); - while (frame) { - aNumPages++; - frame = frame->GetNextSibling(); - } + aNumPages += seqFrame->PrincipalChildList().GetLength(); } } } @@ -2865,7 +2861,7 @@ nsPrintEngine::GetPageRangeForSelection(nsIPageSequenceFrame* aPageSeqFrame, // dump all the pages and their pointers { int32_t pageNum = 1; - nsIFrame* child = seqFrame->GetFirstPrincipalChild(); + nsIFrame* child = seqFrame->PrincipalChildList().FirstChild(); while (child != nullptr) { printf("Page: %d - %p\n", pageNum, child); pageNum++; @@ -2877,8 +2873,7 @@ nsPrintEngine::GetPageRangeForSelection(nsIPageSequenceFrame* aPageSeqFrame, // Now that we have the page frames // find out what the page numbers are for each frame int32_t pageNum = 1; - nsIFrame* page = seqFrame->GetFirstPrincipalChild(); - while (page != nullptr) { + for (nsIFrame* page : seqFrame->PrincipalChildList()) { if (page == startPageFrame) { aStartPageNum = pageNum; } @@ -2886,7 +2881,6 @@ nsPrintEngine::GetPageRangeForSelection(nsIPageSequenceFrame* aPageSeqFrame, aEndPageNum = pageNum; } pageNum++; - page = page->GetNextSibling(); } #ifdef DEBUG_rodsX @@ -3640,7 +3634,7 @@ static void DumpFrames(FILE* out, NS_ASSERTION(aRendContext, "Pointer is null!"); NS_ASSERTION(aFrame, "Pointer is null!"); - nsIFrame* child = aFrame->GetFirstPrincipalChild(); + nsIFrame* child = aFrame->PrincipalChildList().FirstChild(); while (child != nullptr) { for (int32_t i=0;i * aDocList) if (sqf) { break; } - rootFrame = rootFrame->GetFirstPrincipalChild(); + rootFrame = rootFrame->PrincipalChildList().FirstChild(); } } diff --git a/layout/reftests/css-break/box-decoration-break-bug-1235152-ref.html b/layout/reftests/css-break/box-decoration-break-bug-1235152-ref.html new file mode 100644 index 0000000000..ec53798020 --- /dev/null +++ b/layout/reftests/css-break/box-decoration-break-bug-1235152-ref.html @@ -0,0 +1,57 @@ + + + + Testcase for bug 1235152 + + + + +
+ לורם איפסום דולור סיט אמט, קונסקטורר אדיפיסינג אלית קונסקטורר +
+ +
+ לורם איפסום דולור סיט אמט, קונסקטורר אדיפיסינג אלית קונסקטורר +
+ +
+ לורם איפסום דולור סיט אמט, קונסקטורר אדיפיסינג אלית קונסקטורר +
+ +
+ לורם איפסום דולור סיט אמט, קונסקטורר אדיפיסינג אלית קונסקטורר +
+ +
+ לורם איפסום דולור סיט אמט, קונסקטורר אדיפיסינג אלית קונסקטורר +
+ +
+ לורם איפסום דולור סיט אמט, קונסקטורר אדיפיסינג אלית קונסקטורר +
+ + + diff --git a/layout/reftests/css-break/box-decoration-break-bug-1235152.html b/layout/reftests/css-break/box-decoration-break-bug-1235152.html new file mode 100644 index 0000000000..7cb9fc9234 --- /dev/null +++ b/layout/reftests/css-break/box-decoration-break-bug-1235152.html @@ -0,0 +1,61 @@ + + + + Testcase for bug 1235152 + + + + +
+ לורם איפסום דולור סיט אמט, קונסקטורר אדיפיסינג אלית קונסקטורר +
+ +
+ לורם איפסום דולור סיט אמט, קונסקטורר אדיפיסינג אלית קונסקטורר +
+ +
+ לורם איפסום דולור סיט אמט, קונסקטורר אדיפיסינג אלית קונסקטורר +
+ +
+ לורם איפסום דולור סיט אמט, קונסקטורר אדיפיסינג אלית קונסקטורר +
+ +
+ לורם איפסום דולור סיט אמט, קונסקטורר אדיפיסינג אלית קונסקטורר +
+ +
+ לורם איפסום דולור סיט אמט, קונסקטורר אדיפיסינג אלית קונסקטורר +
+ + + diff --git a/layout/reftests/css-break/reftest.list b/layout/reftests/css-break/reftest.list index 0d5a6a3ad5..a6b2f55950 100644 --- a/layout/reftests/css-break/reftest.list +++ b/layout/reftests/css-break/reftest.list @@ -9,3 +9,4 @@ random-if(!gtkWidget) HTTP(..) == box-decoration-break-border-image.html box-dec fuzzy-if(!Android,1,5) fuzzy-if(Android,8,6627) == box-decoration-break-first-letter.html box-decoration-break-first-letter-ref.html == box-decoration-break-bug-1249913.html box-decoration-break-bug-1249913-ref.html == box-decoration-break-with-bidi.html box-decoration-break-with-bidi-ref.html +== box-decoration-break-bug-1235152.html box-decoration-break-bug-1235152-ref.html diff --git a/layout/style/html.css b/layout/style/html.css index 873cd212f6..16f39c847b 100644 --- a/layout/style/html.css +++ b/layout/style/html.css @@ -761,7 +761,7 @@ audio:not([controls]) { *|*::-moz-html-canvas-content { display: block !important; /* we want to be an absolute and fixed container */ - -moz-transform: translate(0) !important; + transform: translate(0) !important; } video > .caption-box { diff --git a/layout/style/nsCSSPseudoElementList.h b/layout/style/nsCSSPseudoElementList.h index 1cfd79d363..5f87fc16cb 100644 --- a/layout/style/nsCSSPseudoElementList.h +++ b/layout/style/nsCSSPseudoElementList.h @@ -28,6 +28,8 @@ CSS_PSEUDO_ELEMENT(after, ":after", CSS_PSEUDO_ELEMENT_IS_CSS2) CSS_PSEUDO_ELEMENT(before, ":before", CSS_PSEUDO_ELEMENT_IS_CSS2) +CSS_PSEUDO_ELEMENT(backdrop, ":backdrop", 0) + CSS_PSEUDO_ELEMENT(firstLetter, ":first-letter", CSS_PSEUDO_ELEMENT_IS_CSS2 | CSS_PSEUDO_ELEMENT_CONTAINS_ELEMENTS) diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp index ac4e66946f..d6a58668d4 100644 --- a/layout/style/nsComputedDOMStyle.cpp +++ b/layout/style/nsComputedDOMStyle.cpp @@ -678,7 +678,7 @@ nsComputedDOMStyle::UpdateCurrentStyleSources(bool aNeedsLayoutFlush) if (type == nsGkAtoms::tableOuterFrame) { // If the frame is an outer table frame then we should get the style // from the inner table frame. - mInnerFrame = mOuterFrame->GetFirstPrincipalChild(); + mInnerFrame = mOuterFrame->PrincipalChildList().FirstChild(); NS_ASSERTION(mInnerFrame, "Outer table must have an inner"); NS_ASSERTION(!mInnerFrame->GetNextSibling(), "Outer table frames should have just one child, " @@ -4838,7 +4838,7 @@ nsComputedDOMStyle::GetAbsoluteOffset(mozilla::css::Side aSide) // the containing block is the viewport, which _does_ include // scrollbars. We have to do some extra work. // the first child in the default frame list is what we want - nsIFrame* scrollingChild = container->GetFirstPrincipalChild(); + nsIFrame* scrollingChild = container->PrincipalChildList().FirstChild(); nsIScrollableFrame *scrollFrame = do_QueryFrame(scrollingChild); if (scrollFrame) { scrollbarSizes = scrollFrame->GetActualScrollbarSizes(); diff --git a/layout/style/ua.css b/layout/style/ua.css index 06ce0e9a21..ba1b4d5363 100644 --- a/layout/style/ua.css +++ b/layout/style/ua.css @@ -43,10 +43,10 @@ justify-self: inherit; order: inherit; /* needed for "order" to work on table flex/grid items */ /* Bug 722777 */ - -moz-transform: inherit; - -moz-transform-origin: inherit; + transform: inherit; + transform-origin: inherit; /* Bug 724750 */ - -moz-backface-visibility: inherit; + backface-visibility: inherit; clip: inherit; } @@ -282,8 +282,6 @@ left: 0 !important; right: 0 !important; bottom: 0 !important; - z-index: 2147483647 !important; - background: black; width: 100% !important; height: 100% !important; margin: 0 !important; @@ -292,6 +290,8 @@ min-height: 0 !important; max-height: none !important; box-sizing: border-box !important; + object-fit: contain !important; + transform: none !important; } /* Selectors here should match the check in @@ -300,6 +300,18 @@ -moz-top-layer: top !important; } +*|*::backdrop { + -moz-top-layer: top !important; + display: block; + position: fixed; + top: 0; left: 0; + right: 0; bottom: 0; +} + +*|*:-moz-full-screen:not(:root)::backdrop { + background: black; +} + /* XML parse error reporting */ parsererror|parsererror { diff --git a/layout/svg/SVGTextFrame.cpp b/layout/svg/SVGTextFrame.cpp index 6326b15193..1f62313dbf 100644 --- a/layout/svg/SVGTextFrame.cpp +++ b/layout/svg/SVGTextFrame.cpp @@ -439,7 +439,7 @@ static SVGTextFrame* FrameIfAnonymousChildReflowed(SVGTextFrame* aFrame) { NS_PRECONDITION(aFrame, "aFrame must not be null"); - nsIFrame* kid = aFrame->GetFirstPrincipalChild(); + nsIFrame* kid = aFrame->PrincipalChildList().FirstChild(); if (NS_SUBTREE_DIRTY(kid)) { MOZ_ASSERT(false, "should have already reflowed the anonymous block child"); return nullptr; @@ -1477,9 +1477,7 @@ TextNodeCorrespondenceRecorder::TraverseAndRecord(nsIFrame* aFrame) // Recursively iterate over the frame tree, for frames that correspond // to text content elements. if (IsTextContentElement(aFrame->GetContent())) { - for (nsIFrame* f = aFrame->GetFirstPrincipalChild(); - f; - f = f->GetNextSibling()) { + for (nsIFrame* f : aFrame->PrincipalChildList()) { TraverseAndRecord(f); } return; @@ -1758,8 +1756,8 @@ private: uint32_t TextFrameIterator::UndisplayedCharacters() const { - MOZ_ASSERT(!(mRootFrame->GetFirstPrincipalChild() && - NS_SUBTREE_DIRTY(mRootFrame->GetFirstPrincipalChild())), + MOZ_ASSERT(!(mRootFrame->PrincipalChildList().FirstChild() && + NS_SUBTREE_DIRTY(mRootFrame->PrincipalChildList().FirstChild())), "should have already reflowed the anonymous block child"); if (!mCurrentFrame) { @@ -1779,7 +1777,7 @@ TextFrameIterator::Next() if (mCurrentFrame) { do { nsIFrame* next = IsTextContentElement(mCurrentFrame->GetContent()) ? - mCurrentFrame->GetFirstPrincipalChild() : + mCurrentFrame->PrincipalChildList().FirstChild() : nullptr; if (next) { // Descend into this frame, and accumulate its position. @@ -3674,7 +3672,7 @@ SVGTextFrame::PaintSVG(gfxContext& aContext, { DrawTarget& aDrawTarget = *aContext.GetDrawTarget(); - nsIFrame* kid = GetFirstPrincipalChild(); + nsIFrame* kid = PrincipalChildList().FirstChild(); if (!kid) return NS_OK; @@ -3815,7 +3813,7 @@ SVGTextFrame::PaintSVG(gfxContext& aContext, nsIFrame* SVGTextFrame::GetFrameForPoint(const gfxPoint& aPoint) { - NS_ASSERTION(GetFirstPrincipalChild(), "must have a child frame"); + NS_ASSERTION(PrincipalChildList().FirstChild(), "must have a child frame"); if (mState & NS_FRAME_IS_NONDISPLAY) { // Text frames inside will never have had ReflowSVG called on @@ -3984,9 +3982,9 @@ SVGBBox SVGTextFrame::GetBBoxContribution(const gfx::Matrix &aToBBoxUserspace, uint32_t aFlags) { - NS_ASSERTION(GetFirstPrincipalChild(), "must have a child frame"); + NS_ASSERTION(PrincipalChildList().FirstChild(), "must have a child frame"); SVGBBox bbox; - nsIFrame* kid = GetFirstPrincipalChild(); + nsIFrame* kid = PrincipalChildList().FirstChild(); if (kid && NS_SUBTREE_DIRTY(kid)) { // Return an empty bbox if our kid's subtree is dirty. This may be called // in that situation, e.g. when we're building a display list after an @@ -4844,7 +4842,7 @@ ShiftAnchoredChunk(nsTArray& aCharPositions, void SVGTextFrame::AdjustChunksForLineBreaks() { - nsBlockFrame* block = nsLayoutUtils::GetAsBlock(GetFirstPrincipalChild()); + nsBlockFrame* block = nsLayoutUtils::GetAsBlock(PrincipalChildList().FirstChild()); NS_ASSERTION(block, "expected block frame"); nsBlockFrame::line_iterator line = block->begin_lines(); @@ -5135,7 +5133,7 @@ SVGTextFrame::DoGlyphPositioning() mPositions.Clear(); RemoveStateBits(NS_STATE_SVG_POSITIONING_DIRTY); - nsIFrame* kid = GetFirstPrincipalChild(); + nsIFrame* kid = PrincipalChildList().FirstChild(); if (kid && NS_SUBTREE_DIRTY(kid)) { MOZ_ASSERT(false, "should have already reflowed the kid"); return; @@ -5204,8 +5202,8 @@ SVGTextFrame::DoGlyphPositioning() double adjustment = 0.0; mLengthAdjustScaleFactor = 1.0f; if (adjustingTextLength) { - nscoord frameLength = vertical ? GetFirstPrincipalChild()->GetRect().height - : GetFirstPrincipalChild()->GetRect().width; + nscoord frameLength = vertical ? PrincipalChildList().FirstChild()->GetRect().height + : PrincipalChildList().FirstChild()->GetRect().width; float actualTextLength = static_cast(presContext->AppUnitsToGfxUnits(frameLength) * factor); @@ -5337,7 +5335,7 @@ SVGTextFrame::NotifyGlyphMetricsChange() void SVGTextFrame::UpdateGlyphPositioning() { - nsIFrame* kid = GetFirstPrincipalChild(); + nsIFrame* kid = PrincipalChildList().FirstChild(); if (!kid) { return; } @@ -5350,7 +5348,7 @@ SVGTextFrame::UpdateGlyphPositioning() void SVGTextFrame::MaybeReflowAnonymousBlockChild() { - nsIFrame* kid = GetFirstPrincipalChild(); + nsIFrame* kid = PrincipalChildList().FirstChild(); if (!kid) return; @@ -5393,7 +5391,7 @@ SVGTextFrame::DoReflow() } nsPresContext *presContext = PresContext(); - nsIFrame* kid = GetFirstPrincipalChild(); + nsIFrame* kid = PrincipalChildList().FirstChild(); if (!kid) return; diff --git a/layout/svg/SVGTextFrame.h b/layout/svg/SVGTextFrame.h index 36769eed94..f94ea570a3 100644 --- a/layout/svg/SVGTextFrame.h +++ b/layout/svg/SVGTextFrame.h @@ -292,7 +292,7 @@ public: virtual nsContainerFrame* GetContentInsertionFrame() override { - return GetFirstPrincipalChild()->GetContentInsertionFrame(); + return PrincipalChildList().FirstChild()->GetContentInsertionFrame(); } virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, diff --git a/layout/svg/nsSVGClipPathFrame.cpp b/layout/svg/nsSVGClipPathFrame.cpp index 7c68e9f831..de306a6e70 100644 --- a/layout/svg/nsSVGClipPathFrame.cpp +++ b/layout/svg/nsSVGClipPathFrame.cpp @@ -313,8 +313,7 @@ nsSVGClipPathFrame::IsValid() nsIAtom *type = kid->GetType(); if (type == nsGkAtoms::svgUseFrame) { - for (nsIFrame* grandKid = kid->GetFirstPrincipalChild(); grandKid; - grandKid = grandKid->GetNextSibling()) { + for (nsIFrame* grandKid : kid->PrincipalChildList()) { nsIAtom *type = grandKid->GetType(); diff --git a/layout/svg/nsSVGContainerFrame.cpp b/layout/svg/nsSVGContainerFrame.cpp index bb93e80832..9f15f89ffb 100644 --- a/layout/svg/nsSVGContainerFrame.cpp +++ b/layout/svg/nsSVGContainerFrame.cpp @@ -112,8 +112,7 @@ nsSVGContainerFrame::ReflowSVGNonDisplayText(nsIFrame* aContainer) !aContainer->IsFrameOfType(nsIFrame::eSVG), "it is wasteful to call ReflowSVGNonDisplayText on a container " "frame that is not NS_FRAME_IS_NONDISPLAY"); - for (nsIFrame* kid = aContainer->GetFirstPrincipalChild(); kid; - kid = kid->GetNextSibling()) { + for (nsIFrame* kid : aContainer->PrincipalChildList()) { nsIAtom* type = kid->GetType(); if (type == nsGkAtoms::svgTextFrame) { static_cast(kid)->ReflowSVGNonDisplayText(); diff --git a/layout/svg/nsSVGForeignObjectFrame.cpp b/layout/svg/nsSVGForeignObjectFrame.cpp index 1f9cca7ea0..cc4262cf19 100644 --- a/layout/svg/nsSVGForeignObjectFrame.cpp +++ b/layout/svg/nsSVGForeignObjectFrame.cpp @@ -210,7 +210,7 @@ nsSVGForeignObjectFrame::PaintSVG(gfxContext& aContext, if (IsDisabled()) return NS_OK; - nsIFrame* kid = GetFirstPrincipalChild(); + nsIFrame* kid = PrincipalChildList().FirstChild(); if (!kid) return NS_OK; @@ -293,7 +293,7 @@ nsSVGForeignObjectFrame::GetFrameForPoint(const gfxPoint& aPoint) if (IsDisabled() || (GetStateBits() & NS_FRAME_IS_NONDISPLAY)) return nullptr; - nsIFrame* kid = GetFirstPrincipalChild(); + nsIFrame* kid = PrincipalChildList().FirstChild(); if (!kid) return nullptr; @@ -359,7 +359,7 @@ nsSVGForeignObjectFrame::ReflowSVG() // Fully mark our kid dirty so that it gets resized if necessary // (NS_FRAME_HAS_DIRTY_CHILDREN isn't enough in that case): - nsIFrame* kid = GetFirstPrincipalChild(); + nsIFrame* kid = PrincipalChildList().FirstChild(); kid->AddStateBits(NS_FRAME_IS_DIRTY); // Make sure to not allow interrupts if we're not being reflown as a root: @@ -509,7 +509,7 @@ void nsSVGForeignObjectFrame::RequestReflow(nsIPresShell::IntrinsicDirty aType) // If we haven't had a ReflowSVG() yet, nothing to do. return; - nsIFrame* kid = GetFirstPrincipalChild(); + nsIFrame* kid = PrincipalChildList().FirstChild(); if (!kid) return; @@ -526,7 +526,7 @@ nsSVGForeignObjectFrame::DoReflow() return; nsPresContext *presContext = PresContext(); - nsIFrame* kid = GetFirstPrincipalChild(); + nsIFrame* kid = PrincipalChildList().FirstChild(); if (!kid) return; @@ -570,7 +570,7 @@ nsSVGForeignObjectFrame::GetInvalidRegion() MOZ_ASSERT(!NS_SVGDisplayListPaintingEnabled(), "Only called by nsDisplayOuterSVG code"); - nsIFrame* kid = GetFirstPrincipalChild(); + nsIFrame* kid = PrincipalChildList().FirstChild(); if (kid->HasInvalidFrameInSubtree()) { gfxRect r(mRect.x, mRect.y, mRect.width, mRect.height); r.Scale(1.0 / nsPresContext::AppUnitsPerCSSPixel()); diff --git a/layout/svg/nsSVGForeignObjectFrame.h b/layout/svg/nsSVGForeignObjectFrame.h index ef3c9d419e..3cd3b03bdf 100644 --- a/layout/svg/nsSVGForeignObjectFrame.h +++ b/layout/svg/nsSVGForeignObjectFrame.h @@ -39,7 +39,7 @@ public: int32_t aModType) override; virtual nsContainerFrame* GetContentInsertionFrame() override { - return GetFirstPrincipalChild()->GetContentInsertionFrame(); + return PrincipalChildList().FirstChild()->GetContentInsertionFrame(); } virtual void Reflow(nsPresContext* aPresContext, diff --git a/layout/svg/nsSVGMarkerFrame.cpp b/layout/svg/nsSVGMarkerFrame.cpp index e5471c644c..46a114e137 100644 --- a/layout/svg/nsSVGMarkerFrame.cpp +++ b/layout/svg/nsSVGMarkerFrame.cpp @@ -95,7 +95,7 @@ nsSVGMarkerFrame::GetCanvasTM() static nsIFrame* GetAnonymousChildFrame(nsIFrame* aFrame) { - nsIFrame* kid = aFrame->GetFirstPrincipalChild(); + nsIFrame* kid = aFrame->PrincipalChildList().FirstChild(); MOZ_ASSERT(kid && kid->GetType() == nsGkAtoms::svgMarkerAnonChildFrame, "expected to find anonymous child of marker frame"); return kid; diff --git a/layout/svg/nsSVGMarkerFrame.h b/layout/svg/nsSVGMarkerFrame.h index d23fb9f7cb..a40c09c510 100644 --- a/layout/svg/nsSVGMarkerFrame.h +++ b/layout/svg/nsSVGMarkerFrame.h @@ -76,11 +76,11 @@ public: virtual nsContainerFrame* GetContentInsertionFrame() override { // Any children must be added to our single anonymous inner frame kid. - MOZ_ASSERT(GetFirstPrincipalChild() && - GetFirstPrincipalChild()->GetType() == + MOZ_ASSERT(PrincipalChildList().FirstChild() && + PrincipalChildList().FirstChild()->GetType() == nsGkAtoms::svgMarkerAnonChildFrame, "Where is our anonymous child?"); - return GetFirstPrincipalChild()->GetContentInsertionFrame(); + return PrincipalChildList().FirstChild()->GetContentInsertionFrame(); } // nsSVGMarkerFrame methods: diff --git a/layout/svg/nsSVGOuterSVGFrame.cpp b/layout/svg/nsSVGOuterSVGFrame.cpp index ad0f433bd5..34f8295745 100644 --- a/layout/svg/nsSVGOuterSVGFrame.cpp +++ b/layout/svg/nsSVGOuterSVGFrame.cpp @@ -366,7 +366,7 @@ nsSVGOuterSVGFrame::Reflow(nsPresContext* aPresContext, SVGSVGElement *svgElem = static_cast(mContent); nsSVGOuterSVGAnonChildFrame *anonKid = - static_cast(GetFirstPrincipalChild()); + static_cast(PrincipalChildList().FirstChild()); if (mState & NS_FRAME_FIRST_REFLOW) { // Initialize @@ -405,10 +405,9 @@ nsSVGOuterSVGFrame::Reflow(nsPresContext* aPresContext, // handled in SVGSVGElement::FlushImageTransformInvalidation. // if (svgElem->HasViewBoxOrSyntheticViewBox()) { - nsIFrame* anonChild = GetFirstPrincipalChild(); + nsIFrame* anonChild = PrincipalChildList().FirstChild(); anonChild->AddStateBits(NS_FRAME_IS_DIRTY); - for (nsIFrame* child = anonChild->GetFirstPrincipalChild(); child; - child = child->GetNextSibling()) { + for (nsIFrame* child : anonChild->PrincipalChildList()) { child->AddStateBits(NS_FRAME_IS_DIRTY); } } @@ -510,7 +509,7 @@ nsSVGOuterSVGFrame::UpdateOverflow() nsOverflowAreas overflowAreas(rect, rect); if (!mIsRootContent) { - nsIFrame *anonKid = GetFirstPrincipalChild(); + nsIFrame *anonKid = PrincipalChildList().FirstChild(); overflowAreas.VisualOverflow().UnionRect( overflowAreas.VisualOverflow(), anonKid->GetVisualOverflowRect() + anonKid->GetPosition()); @@ -571,7 +570,7 @@ nsDisplayOuterSVG::HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect, nsSVGOuterSVGAnonChildFrame *anonKid = static_cast( - outerSVGFrame->GetFirstPrincipalChild()); + outerSVGFrame->PrincipalChildList().FirstChild()); nsIFrame* frame = nsSVGUtils::HitTestChildren(anonKid, svgViewportRelativePoint); @@ -665,7 +664,7 @@ nsSVGOuterSVGFrame::AttributeChanged(int32_t aNameSpaceID, // make sure our cached transform matrix gets (lazily) updated mCanvasTM = nullptr; - nsSVGUtils::NotifyChildrenOfSVGChange(GetFirstPrincipalChild(), + nsSVGUtils::NotifyChildrenOfSVGChange(PrincipalChildList().FirstChild(), aAttribute == nsGkAtoms::viewBox ? TRANSFORM_CHANGED | COORD_CONTEXT_CHANGED : TRANSFORM_CHANGED); @@ -807,7 +806,7 @@ nsSVGOuterSVGFrame::NotifyViewportOrTransformChanged(uint32_t aFlags) } } - nsSVGUtils::NotifyChildrenOfSVGChange(GetFirstPrincipalChild(), aFlags); + nsSVGUtils::NotifyChildrenOfSVGChange(PrincipalChildList().FirstChild(), aFlags); } //---------------------------------------------------------------------- @@ -818,12 +817,12 @@ nsSVGOuterSVGFrame::PaintSVG(gfxContext& aContext, const gfxMatrix& aTransform, const nsIntRect* aDirtyRect) { - NS_ASSERTION(GetFirstPrincipalChild()->GetType() == + NS_ASSERTION(PrincipalChildList().FirstChild()->GetType() == nsGkAtoms::svgOuterSVGAnonChildFrame && - !GetFirstPrincipalChild()->GetNextSibling(), + !PrincipalChildList().FirstChild()->GetNextSibling(), "We should have a single, anonymous, child"); nsSVGOuterSVGAnonChildFrame *anonKid = - static_cast(GetFirstPrincipalChild()); + static_cast(PrincipalChildList().FirstChild()); return anonKid->PaintSVG(aContext, aTransform, aDirtyRect); } @@ -831,14 +830,14 @@ SVGBBox nsSVGOuterSVGFrame::GetBBoxContribution(const gfx::Matrix &aToBBoxUserspace, uint32_t aFlags) { - NS_ASSERTION(GetFirstPrincipalChild()->GetType() == + NS_ASSERTION(PrincipalChildList().FirstChild()->GetType() == nsGkAtoms::svgOuterSVGAnonChildFrame && - !GetFirstPrincipalChild()->GetNextSibling(), + !PrincipalChildList().FirstChild()->GetNextSibling(), "We should have a single, anonymous, child"); // We must defer to our child so that we don't include our // content->PrependLocalTransformsTo() transforms. nsSVGOuterSVGAnonChildFrame *anonKid = - static_cast(GetFirstPrincipalChild()); + static_cast(PrincipalChildList().FirstChild()); return anonKid->GetBBoxContribution(aToBBoxUserspace, aFlags); } diff --git a/layout/svg/nsSVGOuterSVGFrame.h b/layout/svg/nsSVGOuterSVGFrame.h index a3789059fb..5602665e8c 100644 --- a/layout/svg/nsSVGOuterSVGFrame.h +++ b/layout/svg/nsSVGOuterSVGFrame.h @@ -96,11 +96,11 @@ public: virtual nsContainerFrame* GetContentInsertionFrame() override { // Any children must be added to our single anonymous inner frame kid. - MOZ_ASSERT(GetFirstPrincipalChild() && - GetFirstPrincipalChild()->GetType() == + MOZ_ASSERT(PrincipalChildList().FirstChild() && + PrincipalChildList().FirstChild()->GetType() == nsGkAtoms::svgOuterSVGAnonChildFrame, "Where is our anonymous child?"); - return GetFirstPrincipalChild()->GetContentInsertionFrame(); + return PrincipalChildList().FirstChild()->GetContentInsertionFrame(); } virtual bool IsSVGTransformed(Matrix *aOwnTransform, @@ -108,7 +108,7 @@ public: // Our anonymous wrapper performs the transforms. We simply // return whether we are transformed here but don't apply the transforms // themselves. - return GetFirstPrincipalChild()->IsSVGTransformed(); + return PrincipalChildList().FirstChild()->IsSVGTransformed(); } // nsISVGSVGFrame interface: diff --git a/layout/svg/nsSVGUtils.cpp b/layout/svg/nsSVGUtils.cpp index 36e5d2b8a6..6a43530dd0 100644 --- a/layout/svg/nsSVGUtils.cpp +++ b/layout/svg/nsSVGUtils.cpp @@ -432,9 +432,7 @@ nsSVGUtils::GetUserToCanvasTM(nsIFrame *aFrame) void nsSVGUtils::NotifyChildrenOfSVGChange(nsIFrame *aFrame, uint32_t aFlags) { - nsIFrame *kid = aFrame->GetFirstPrincipalChild(); - - while (kid) { + for (nsIFrame* kid : aFrame->PrincipalChildList()) { nsISVGChildFrame* SVGFrame = do_QueryFrame(kid); if (SVGFrame) { SVGFrame->NotifySVGChanged(aFlags); @@ -447,7 +445,6 @@ nsSVGUtils::NotifyChildrenOfSVGChange(nsIFrame *aFrame, uint32_t aFlags) NotifyChildrenOfSVGChange(kid, aFlags); } } - kid = kid->GetNextSibling(); } } diff --git a/layout/tables/nsCellMap.cpp b/layout/tables/nsCellMap.cpp index 7bcebeaa99..2e7fec2f1c 100644 --- a/layout/tables/nsCellMap.cpp +++ b/layout/tables/nsCellMap.cpp @@ -1646,8 +1646,7 @@ bool nsCellMap::CellsSpanOut(nsTArray& aRows) const int32_t numNewRows = aRows.Length(); for (int32_t rowX = 0; rowX < numNewRows; rowX++) { nsIFrame* rowFrame = (nsIFrame *) aRows.ElementAt(rowX); - nsIFrame* childFrame = rowFrame->GetFirstPrincipalChild(); - while (childFrame) { + for (nsIFrame* childFrame : rowFrame->PrincipalChildList()) { nsTableCellFrame *cellFrame = do_QueryFrame(childFrame); if (cellFrame) { bool zeroSpan; @@ -1656,7 +1655,6 @@ bool nsCellMap::CellsSpanOut(nsTArray& aRows) const return true; } } - childFrame = childFrame->GetNextSibling(); } } return false; @@ -1823,15 +1821,13 @@ nsCellMap::ExpandWithRows(nsTableCellMap& aMap, for (int32_t rowX = startRowIndex; rowX <= endRowIndex; rowX++) { nsTableRowFrame* rFrame = aRowFrames.ElementAt(newRowIndex); // append cells - nsIFrame* cFrame = rFrame->GetFirstPrincipalChild(); int32_t colIndex = 0; - while (cFrame) { + for (nsIFrame* cFrame : rFrame->PrincipalChildList()) { nsTableCellFrame *cellFrame = do_QueryFrame(cFrame); if (cellFrame) { AppendCell(aMap, cellFrame, rowX, false, aRgFirstRowIndex, aDamageArea, &colIndex); } - cFrame = cFrame->GetNextSibling(); } newRowIndex++; } @@ -2298,13 +2294,11 @@ nsCellMap::RebuildConsideringRows(nsTableCellMap& aMap, int32_t numNewRows = aRowsToInsert->Length(); for (int32_t newRowX = 0; newRowX < numNewRows; newRowX++) { nsTableRowFrame* rFrame = aRowsToInsert->ElementAt(newRowX); - nsIFrame* cFrame = rFrame->GetFirstPrincipalChild(); - while (cFrame) { + for (nsIFrame* cFrame : rFrame->PrincipalChildList()) { nsTableCellFrame *cellFrame = do_QueryFrame(cFrame); if (cellFrame) { AppendCell(aMap, cellFrame, rowX, false, 0, damageArea); } - cFrame = cFrame->GetNextSibling(); } rowX++; } diff --git a/layout/tables/nsTableCellFrame.cpp b/layout/tables/nsTableCellFrame.cpp index 157e26a833..83f736322a 100644 --- a/layout/tables/nsTableCellFrame.cpp +++ b/layout/tables/nsTableCellFrame.cpp @@ -700,8 +700,7 @@ nsTableCellFrame::CellHasVisibleContent(nscoord height, return true; if (tableFrame->IsBorderCollapse()) return true; - nsIFrame* innerFrame = kidFrame->GetFirstPrincipalChild(); - while(innerFrame) { + for (nsIFrame* innerFrame : kidFrame->PrincipalChildList()) { nsIAtom* frameType = innerFrame->GetType(); if (nsGkAtoms::textFrame == frameType) { nsTextFrame* textFrame = static_cast(innerFrame); @@ -716,8 +715,7 @@ nsTableCellFrame::CellHasVisibleContent(nscoord height, if (floatFrame) return true; } - innerFrame = innerFrame->GetNextSibling(); - } + } return false; } diff --git a/layout/tables/nsTableCellFrame.h b/layout/tables/nsTableCellFrame.h index 7afcead7c1..c950895b18 100644 --- a/layout/tables/nsTableCellFrame.h +++ b/layout/tables/nsTableCellFrame.h @@ -93,7 +93,7 @@ public: #endif virtual nsContainerFrame* GetContentInsertionFrame() override { - return GetFirstPrincipalChild()->GetContentInsertionFrame(); + return PrincipalChildList().FirstChild()->GetContentInsertionFrame(); } virtual nsMargin GetUsedMargin() const override; diff --git a/layout/tables/nsTableColGroupFrame.cpp b/layout/tables/nsTableColGroupFrame.cpp index f5f1827cac..4cc4618af3 100644 --- a/layout/tables/nsTableColGroupFrame.cpp +++ b/layout/tables/nsTableColGroupFrame.cpp @@ -54,7 +54,7 @@ void nsTableColGroupFrame::ResetColIndices(nsIFrame* aFirstColGroup, } nsIFrame* colFrame = aStartColFrame; if (!colFrame || (colIndex != aFirstColIndex)) { - colFrame = colGroupFrame->GetFirstPrincipalChild(); + colFrame = colGroupFrame->PrincipalChildList().FirstChild(); } while (colFrame) { if (nsGkAtoms::tableColFrame == colFrame->GetType()) { diff --git a/layout/tables/nsTableFrame.cpp b/layout/tables/nsTableFrame.cpp index 1f862e2bf9..336de1c31b 100644 --- a/layout/tables/nsTableFrame.cpp +++ b/layout/tables/nsTableFrame.cpp @@ -316,9 +316,13 @@ void nsTableFrame::SetInitialChildList(ChildListID aListID, nsFrameList& aChildList) { + if (aListID != kPrincipalList) { + nsContainerFrame::SetInitialChildList(aListID, aChildList); + return; + } + MOZ_ASSERT(mFrames.IsEmpty() && mColGroups.IsEmpty(), "unexpected second call to SetInitialChildList"); - MOZ_ASSERT(aListID == kPrincipalList, "unexpected child list"); // XXXbz the below code is an icky cesspit that's only needed in its current // form for two reasons: @@ -1000,11 +1004,9 @@ nsTableFrame::CollectRows(nsIFrame* aFrame, { NS_PRECONDITION(aFrame, "null frame"); int32_t numRows = 0; - nsIFrame* childFrame = aFrame->GetFirstPrincipalChild(); - while (childFrame) { + for (nsIFrame* childFrame : aFrame->PrincipalChildList()) { aCollection.AppendElement(static_cast(childFrame)); numRows++; - childFrame = childFrame->GetNextSibling(); } return numRows; } @@ -1218,10 +1220,8 @@ nsTableFrame::GenericTraversal(nsDisplayListBuilder* aBuilder, nsFrame* aFrame, // stacking context, in which case the child won't use its passed-in // BorderBackground list anyway. It does affect cell borders though; this // lets us get cell borders into the nsTableFrame's BorderBackground list. - nsIFrame* kid = aFrame->GetFirstPrincipalChild(); - while (kid) { + for (nsIFrame* kid : aFrame->PrincipalChildList()) { aFrame->BuildDisplayListForChild(aBuilder, kid, aDirtyRect, aLists); - kid = kid->GetNextSibling(); } } @@ -1516,9 +1516,8 @@ nsTableFrame::ProcessRowInserted(nscoord aNewBSize) for (uint32_t rgIdx = 0; rgIdx < rowGroups.Length(); rgIdx++) { nsTableRowGroupFrame* rgFrame = rowGroups[rgIdx]; NS_ASSERTION(rgFrame, "Must have rgFrame here"); - nsIFrame* childFrame = rgFrame->GetFirstPrincipalChild(); // find the row that was inserted first - while (childFrame) { + for (nsIFrame* childFrame : rgFrame->PrincipalChildList()) { nsTableRowFrame *rowFrame = do_QueryFrame(childFrame); if (rowFrame) { if (rowFrame->IsFirstInserted()) { @@ -1530,7 +1529,6 @@ nsTableFrame::ProcessRowInserted(nscoord aNewBSize) return; // found it, so leave } } - childFrame = childFrame->GetNextSibling(); } } } @@ -2451,7 +2449,7 @@ nsTableFrame::HomogenousInsertFrames(ChildListID aListID, aPrevFrame = nullptr; while (pseudoFrame && (parentContent == (content = pseudoFrame->GetContent()))) { - pseudoFrame = pseudoFrame->GetFirstPrincipalChild(); + pseudoFrame = pseudoFrame->PrincipalChildList().FirstChild(); } nsCOMPtr container = content->GetParent(); if (MOZ_LIKELY(container)) { // XXX need this null-check, see bug 411823. @@ -2477,7 +2475,7 @@ nsTableFrame::HomogenousInsertFrames(ChildListID aListID, pseudoFrame = kidFrame; while (pseudoFrame && (parentContent == (content = pseudoFrame->GetContent()))) { - pseudoFrame = pseudoFrame->GetFirstPrincipalChild(); + pseudoFrame = pseudoFrame->PrincipalChildList().FirstChild(); } int32_t index = container->IndexOf(content); if (index > lastIndex && index < newIndex) { @@ -3936,7 +3934,7 @@ nsTableFrame::GetFrameAtOrBefore(nsIFrame* aParentFrame, // aPriorChildFrame is not of type aChildType, so we need start from // the beginnng and find the closest one nsIFrame* lastMatchingFrame = nullptr; - nsIFrame* childFrame = aParentFrame->GetFirstPrincipalChild(); + nsIFrame* childFrame = aParentFrame->PrincipalChildList().FirstChild(); while (childFrame && (childFrame != aPriorChildFrame)) { if (aChildType == childFrame->GetType()) { lastMatchingFrame = childFrame; @@ -3953,28 +3951,24 @@ nsTableFrame::DumpRowGroup(nsIFrame* aKidFrame) if (!aKidFrame) return; - nsIFrame* cFrame = aKidFrame->GetFirstPrincipalChild(); - while (cFrame) { + for (nsIFrame* cFrame : aKidFrame->PrincipalChildList()) { nsTableRowFrame *rowFrame = do_QueryFrame(cFrame); if (rowFrame) { printf("row(%d)=%p ", rowFrame->GetRowIndex(), static_cast(rowFrame)); - nsIFrame* childFrame = cFrame->GetFirstPrincipalChild(); - while (childFrame) { + for (nsIFrame* childFrame : cFrame->PrincipalChildList()) { nsTableCellFrame *cellFrame = do_QueryFrame(childFrame); if (cellFrame) { int32_t colIndex; cellFrame->GetColIndex(colIndex); printf("cell(%d)=%p ", colIndex, static_cast(childFrame)); } - childFrame = childFrame->GetNextSibling(); } printf("\n"); } else { DumpRowGroup(rowFrame); } - cFrame = cFrame->GetNextSibling(); } } diff --git a/layout/tables/nsTableOuterFrame.cpp b/layout/tables/nsTableOuterFrame.cpp index 12a84ef500..2e32b28de0 100644 --- a/layout/tables/nsTableOuterFrame.cpp +++ b/layout/tables/nsTableOuterFrame.cpp @@ -92,20 +92,18 @@ void nsTableOuterFrame::SetInitialChildList(ChildListID aListID, nsFrameList& aChildList) { - MOZ_ASSERT(kCaptionList == aListID || aListID == kPrincipalList, - "unexpected child list"); - MOZ_ASSERT(GetChildList(aListID).IsEmpty(), - "already have child frames in SetInitialChildList"); - if (kCaptionList == aListID) { // the frame constructor already checked for table-caption display type + MOZ_ASSERT(mCaptionFrames.IsEmpty(), + "already have child frames in CaptionList"); mCaptionFrames.SetFrames(aChildList); } else { - MOZ_ASSERT(aChildList.FirstChild() && - aChildList.FirstChild() == aChildList.LastChild() && - nsGkAtoms::tableFrame == aChildList.FirstChild()->GetType(), - "expected a single table frame"); - mFrames.SetFrames(aChildList); + MOZ_ASSERT(kPrincipalList != aListID || + (aChildList.FirstChild() && + aChildList.FirstChild() == aChildList.LastChild() && + nsGkAtoms::tableFrame == aChildList.FirstChild()->GetType()), + "expected a single table frame in principal child list"); + nsContainerFrame::SetInitialChildList(aListID, aChildList); } } diff --git a/layout/tables/nsTableOuterFrame.h b/layout/tables/nsTableOuterFrame.h index eb0453592c..3b67822252 100644 --- a/layout/tables/nsTableOuterFrame.h +++ b/layout/tables/nsTableOuterFrame.h @@ -51,7 +51,7 @@ public: nsIFrame* aOldFrame) override; virtual nsContainerFrame* GetContentInsertionFrame() override { - return GetFirstPrincipalChild()->GetContentInsertionFrame(); + return PrincipalChildList().FirstChild()->GetContentInsertionFrame(); } #ifdef ACCESSIBILITY diff --git a/layout/tables/nsTableRowFrame.cpp b/layout/tables/nsTableRowFrame.cpp index 315ce786a3..fdc4a1a1ba 100644 --- a/layout/tables/nsTableRowFrame.cpp +++ b/layout/tables/nsTableRowFrame.cpp @@ -435,7 +435,7 @@ nscoord nsTableRowFrame::GetRowBaseline(WritingMode aWM) nsSize containerSize = GetSize(); for (nsIFrame* childFrame : mFrames) { if (IS_TABLE_CELL(childFrame->GetType())) { - nsIFrame* firstKid = childFrame->GetFirstPrincipalChild(); + nsIFrame* firstKid = childFrame->PrincipalChildList().FirstChild(); ascent = std::max(ascent, LogicalRect(aWM, firstKid->GetNormalRect(), containerSize).BEnd(aWM)); @@ -546,7 +546,7 @@ nsTableRowFrame::CalcBSize(const nsHTMLReflowState& aReflowState) } // bsize may have changed, adjust descent to absorb any excess difference nscoord ascent; - if (!kidFrame->GetFirstPrincipalChild()->GetFirstPrincipalChild()) + if (!kidFrame->PrincipalChildList().FirstChild()->PrincipalChildList().FirstChild()) ascent = desSize.BSize(wm); else ascent = cellFrame->GetCellBaseline(); @@ -960,7 +960,7 @@ nsTableRowFrame::ReflowChildren(nsPresContext* aPresContext, } // bsize may have changed, adjust descent to absorb any excess difference nscoord ascent; - if (!kidFrame->GetFirstPrincipalChild()->GetFirstPrincipalChild()) { + if (!kidFrame->PrincipalChildList().FirstChild()->PrincipalChildList().FirstChild()) { ascent = desiredSize.BSize(wm); } else { ascent = ((nsTableCellFrame *)kidFrame)->GetCellBaseline(); diff --git a/layout/tables/nsTableRowGroupFrame.cpp b/layout/tables/nsTableRowGroupFrame.cpp index 065120e9f1..9580195f06 100644 --- a/layout/tables/nsTableRowGroupFrame.cpp +++ b/layout/tables/nsTableRowGroupFrame.cpp @@ -197,7 +197,7 @@ DisplayRows(nsDisplayListBuilder* aBuilder, nsFrame* aFrame, // No cursor. Traverse children the hard way and build a cursor while we're at it nsTableRowGroupFrame::FrameCursorData* cursor = f->SetupRowCursor(); - kid = f->GetFirstPrincipalChild(); + kid = f->PrincipalChildList().FirstChild(); while (kid) { f->BuildDisplayListForChild(aBuilder, kid, aDirtyRect, aLists); @@ -1365,7 +1365,7 @@ nsTableRowGroupFrame::Reflow(nsPresContext* aPresContext, // XXXmats The following is just bogus. We leave it here for now because // ReflowChildren should pull up rows from our next-in-flow before returning // a Complete status, but doesn't (bug 804888). - if (GetNextInFlow() && GetNextInFlow()->GetFirstPrincipalChild()) { + if (GetNextInFlow() && GetNextInFlow()->PrincipalChildList().FirstChild()) { NS_FRAME_SET_INCOMPLETE(aStatus); } diff --git a/layout/xul/BoxObject.cpp b/layout/xul/BoxObject.cpp index 516397cc69..50d5e0633e 100644 --- a/layout/xul/BoxObject.cpp +++ b/layout/xul/BoxObject.cpp @@ -382,7 +382,7 @@ BoxObject::GetFirstChild(nsIDOMElement * *aFirstVisibleChild) *aFirstVisibleChild = nullptr; nsIFrame* frame = GetFrame(false); if (!frame) return NS_OK; - nsIFrame* firstFrame = frame->GetFirstPrincipalChild(); + nsIFrame* firstFrame = frame->PrincipalChildList().FirstChild(); if (!firstFrame) return NS_OK; // get the content for the box and query to a dom element nsCOMPtr el = do_QueryInterface(firstFrame->GetContent()); @@ -429,7 +429,7 @@ BoxObject::GetPreviousSibling(nsIFrame* aParentFrame, nsIFrame* aFrame, nsIDOMElement** aResult) { *aResult = nullptr; - nsIFrame* nextFrame = aParentFrame->GetFirstPrincipalChild(); + nsIFrame* nextFrame = aParentFrame->PrincipalChildList().FirstChild(); nsIFrame* prevFrame = nullptr; while (nextFrame) { if (nextFrame == aFrame) diff --git a/layout/xul/nsBox.cpp b/layout/xul/nsBox.cpp index 9696a4095a..4d5bbc7895 100644 --- a/layout/xul/nsBox.cpp +++ b/layout/xul/nsBox.cpp @@ -926,7 +926,7 @@ nsBox::GetChildBox(const nsIFrame* aFrame) { // box layout ends at box-wrapped frames, so don't allow these frames // to report child boxes. - return aFrame->IsBoxFrame() ? aFrame->GetFirstPrincipalChild() : nullptr; + return aFrame->IsBoxFrame() ? aFrame->PrincipalChildList().FirstChild() : nullptr; } /*static*/ nsIFrame* diff --git a/layout/xul/nsBoxFrame.cpp b/layout/xul/nsBoxFrame.cpp index 34e0ab999b..c3085513e7 100644 --- a/layout/xul/nsBoxFrame.cpp +++ b/layout/xul/nsBoxFrame.cpp @@ -148,11 +148,13 @@ nsBoxFrame::SetInitialChildList(ChildListID aListID, nsFrameList& aChildList) { nsContainerFrame::SetInitialChildList(aListID, aChildList); - // initialize our list of infos. - nsBoxLayoutState state(PresContext()); - CheckBoxOrder(); - if (mLayoutManager) - mLayoutManager->ChildrenSet(this, state, mFrames.FirstChild()); + if (aListID == kPrincipalList) { + // initialize our list of infos. + nsBoxLayoutState state(PresContext()); + CheckBoxOrder(); + if (mLayoutManager) + mLayoutManager->ChildrenSet(this, state, mFrames.FirstChild()); + } } /* virtual */ void @@ -1105,7 +1107,7 @@ nsBoxFrame::AppendFrames(ChildListID aListID, nsBoxFrame::GetContentInsertionFrame() { if (GetStateBits() & NS_STATE_BOX_WRAPS_KIDS_IN_BLOCK) - return GetFirstPrincipalChild()->GetContentInsertionFrame(); + return PrincipalChildList().FirstChild()->GetContentInsertionFrame(); return nsContainerFrame::GetContentInsertionFrame(); } diff --git a/layout/xul/nsMenuBarFrame.cpp b/layout/xul/nsMenuBarFrame.cpp index cd09e58a1a..306c80c9a6 100644 --- a/layout/xul/nsMenuBarFrame.cpp +++ b/layout/xul/nsMenuBarFrame.cpp @@ -186,7 +186,7 @@ nsMenuBarFrame::FindMenuWithShortcut(nsIDOMKeyEvent* aKeyEvent) // Find a most preferred accesskey which should be returned. nsIFrame* foundMenu = nullptr; size_t foundIndex = accessKeys.NoIndex; - nsIFrame* currFrame = immediateParent->GetFirstPrincipalChild(); + nsIFrame* currFrame = immediateParent->PrincipalChildList().FirstChild(); while (currFrame) { nsIContent* current = currFrame->GetContent(); diff --git a/layout/xul/nsMenuFrame.cpp b/layout/xul/nsMenuFrame.cpp index 53a4a3090a..9dcc109dc3 100644 --- a/layout/xul/nsMenuFrame.cpp +++ b/layout/xul/nsMenuFrame.cpp @@ -315,8 +315,8 @@ void nsMenuFrame::SetInitialChildList(ChildListID aListID, nsFrameList& aChildList) { - NS_ASSERTION(!HasPopup(), "SetInitialChildList called twice?"); if (aListID == kPrincipalList || aListID == kPopupList) { + NS_ASSERTION(!HasPopup(), "SetInitialChildList called twice?"); SetPopupFrame(aChildList); } nsBoxFrame::SetInitialChildList(aListID, aChildList); @@ -1366,7 +1366,7 @@ nsMenuFrame::SizeToPopup(nsBoxLayoutState& aState, nsSize& aSize) GetBorderAndPadding(borderPadding); // if there is a scroll frame, add the desired width of the scrollbar as well - nsIScrollableFrame* scrollFrame = do_QueryFrame(popupFrame->GetFirstPrincipalChild()); + nsIScrollableFrame* scrollFrame = do_QueryFrame(popupFrame->PrincipalChildList().FirstChild()); nscoord scrollbarWidth = 0; if (scrollFrame) { scrollbarWidth = @@ -1449,7 +1449,7 @@ nsIScrollableFrame* nsMenuFrame::GetScrollTargetFrame() nsMenuPopupFrame* popupFrame = GetPopup(); if (!popupFrame) return nullptr; - nsIFrame* childFrame = popupFrame->GetFirstPrincipalChild(); + nsIFrame* childFrame = popupFrame->PrincipalChildList().FirstChild(); if (childFrame) return popupFrame->GetScrollFrame(childFrame); return nullptr; diff --git a/layout/xul/nsMenuPopupFrame.cpp b/layout/xul/nsMenuPopupFrame.cpp index 09dda12655..25c096725b 100644 --- a/layout/xul/nsMenuPopupFrame.cpp +++ b/layout/xul/nsMenuPopupFrame.cpp @@ -236,7 +236,7 @@ nsMenuPopupFrame::EnsureWidget() { nsView* ourView = GetView(); if (!ourView->HasWidget()) { - NS_ASSERTION(!mGeneratedChildren && !GetFirstPrincipalChild(), + NS_ASSERTION(!mGeneratedChildren && !PrincipalChildList().FirstChild(), "Creating widget for MenuPopupFrame with children"); CreateWidgetForView(ourView); } @@ -387,8 +387,9 @@ nsMenuPopupFrame::SetInitialChildList(ChildListID aListID, nsFrameList& aChildList) { // unless the list is empty, indicate that children have been generated. - if (aChildList.NotEmpty()) + if (aListID == kPrincipalList && aChildList.NotEmpty()) { mGeneratedChildren = true; + } nsBoxFrame::SetInitialChildList(aListID, aChildList); } @@ -1660,7 +1661,7 @@ nsIScrollableFrame* nsMenuPopupFrame::GetScrollFrame(nsIFrame* aStart) // try children currFrame = aStart; do { - nsIFrame* childFrame = currFrame->GetFirstPrincipalChild(); + nsIFrame* childFrame = currFrame->PrincipalChildList().FirstChild(); nsIScrollableFrame* sf = GetScrollFrame(childFrame); if (sf) return sf; diff --git a/layout/xul/nsProgressMeterFrame.cpp b/layout/xul/nsProgressMeterFrame.cpp index 4b84f83cf9..2d46386f67 100644 --- a/layout/xul/nsProgressMeterFrame.cpp +++ b/layout/xul/nsProgressMeterFrame.cpp @@ -135,7 +135,7 @@ nsProgressMeterFrame::AttributeChanged(int32_t aNameSpaceID, if (nsGkAtoms::mode == aAttribute || (!undetermined && (nsGkAtoms::value == aAttribute || nsGkAtoms::max == aAttribute))) { - nsIFrame* barChild = GetFirstPrincipalChild(); + nsIFrame* barChild = PrincipalChildList().FirstChild(); if (!barChild) return NS_OK; nsIFrame* remainderChild = barChild->GetNextSibling(); if (!remainderChild) return NS_OK; diff --git a/layout/xul/nsRootBoxFrame.cpp b/layout/xul/nsRootBoxFrame.cpp index c38cf00f4f..1c0f8cd4f8 100644 --- a/layout/xul/nsRootBoxFrame.cpp +++ b/layout/xul/nsRootBoxFrame.cpp @@ -34,7 +34,7 @@ nsIRootBox::GetRootBox(nsIPresShell* aShell) } if (rootFrame) { - rootFrame = rootFrame->GetFirstPrincipalChild(); + rootFrame = rootFrame->PrincipalChildList().FirstChild(); } nsIRootBox* rootBox = do_QueryFrame(rootFrame); diff --git a/layout/xul/nsScrollbarButtonFrame.cpp b/layout/xul/nsScrollbarButtonFrame.cpp index 8871744867..b610cbccc7 100644 --- a/layout/xul/nsScrollbarButtonFrame.cpp +++ b/layout/xul/nsScrollbarButtonFrame.cpp @@ -233,9 +233,8 @@ nsScrollbarButtonFrame::GetChildWithTag(nsIAtom* atom, nsIFrame* start, nsIFrame*& result) { // recursively search our children - nsIFrame* childFrame = start->GetFirstPrincipalChild(); - while (nullptr != childFrame) - { + for (nsIFrame* childFrame : start->PrincipalChildList()) + { // get the content node nsIContent* child = childFrame->GetContent(); @@ -253,8 +252,6 @@ nsScrollbarButtonFrame::GetChildWithTag(nsIAtom* atom, nsIFrame* start, GetChildWithTag(atom, childFrame, result); if (result != nullptr) return NS_OK; - - childFrame = childFrame->GetNextSibling(); } result = nullptr; diff --git a/layout/xul/nsSliderFrame.cpp b/layout/xul/nsSliderFrame.cpp index 8305fab168..80d524fd60 100644 --- a/layout/xul/nsSliderFrame.cpp +++ b/layout/xul/nsSliderFrame.cpp @@ -891,7 +891,9 @@ nsSliderFrame::SetInitialChildList(ChildListID aListID, nsFrameList& aChildList) { nsBoxFrame::SetInitialChildList(aListID, aChildList); - AddListener(); + if (aListID == kPrincipalList) { + AddListener(); + } } nsresult diff --git a/layout/xul/nsXULPopupManager.cpp b/layout/xul/nsXULPopupManager.cpp index 50652e94c0..0468290346 100644 --- a/layout/xul/nsXULPopupManager.cpp +++ b/layout/xul/nsXULPopupManager.cpp @@ -2314,7 +2314,7 @@ nsXULPopupManager::GetNextMenuItem(nsContainerFrame* aParent, currFrame = aStart->GetParent()->GetNextSibling(); } else - currFrame = immediateParent->GetFirstPrincipalChild(); + currFrame = immediateParent->PrincipalChildList().FirstChild(); while (currFrame) { // See if it's a menu item. @@ -2324,7 +2324,7 @@ nsXULPopupManager::GetNextMenuItem(nsContainerFrame* aParent, } if (currFrameContent->IsXULElement(nsGkAtoms::menugroup) && currFrameContent->GetChildCount() > 0) - currFrame = currFrame->GetFirstPrincipalChild(); + currFrame = currFrame->PrincipalChildList().FirstChild(); else if (!currFrame->GetNextSibling() && currFrame->GetParent()->GetContent()->IsXULElement(nsGkAtoms::menugroup)) currFrame = currFrame->GetParent()->GetNextSibling(); @@ -2332,7 +2332,7 @@ nsXULPopupManager::GetNextMenuItem(nsContainerFrame* aParent, currFrame = currFrame->GetNextSibling(); } - currFrame = immediateParent->GetFirstPrincipalChild(); + currFrame = immediateParent->PrincipalChildList().FirstChild(); // Still don't have anything. Try cycling from the beginning. while (currFrame && currFrame != aStart) { @@ -2343,7 +2343,7 @@ nsXULPopupManager::GetNextMenuItem(nsContainerFrame* aParent, } if (currFrameContent->IsXULElement(nsGkAtoms::menugroup) && currFrameContent->GetChildCount() > 0) - currFrame = currFrame->GetFirstPrincipalChild(); + currFrame = currFrame->PrincipalChildList().FirstChild(); else if (!currFrame->GetNextSibling() && currFrame->GetParent()->GetContent()->IsXULElement(nsGkAtoms::menugroup)) currFrame = currFrame->GetParent()->GetNextSibling(); diff --git a/layout/xul/tree/nsTreeBodyFrame.cpp b/layout/xul/tree/nsTreeBodyFrame.cpp index 684aa9e3f3..86ca9a5fa7 100644 --- a/layout/xul/tree/nsTreeBodyFrame.cpp +++ b/layout/xul/tree/nsTreeBodyFrame.cpp @@ -816,7 +816,7 @@ FindScrollParts(nsIFrame* aCurrFrame, nsTreeBodyFrame::ScrollParts* aResult) return; } - nsIFrame* child = aCurrFrame->GetFirstPrincipalChild(); + nsIFrame* child = aCurrFrame->PrincipalChildList().FirstChild(); while (child && !child->GetContent()->IsRootOfNativeAnonymousSubtree() && (!aResult->mVScrollbar || !aResult->mHScrollbar || diff --git a/layout/xul/tree/nsTreeColumns.cpp b/layout/xul/tree/nsTreeColumns.cpp index 2f0d6980b2..01dace53ab 100644 --- a/layout/xul/tree/nsTreeColumns.cpp +++ b/layout/xul/tree/nsTreeColumns.cpp @@ -737,7 +737,7 @@ nsTreeColumns::EnsureColumns() if (!colFrame) return; - colFrame = colFrame->GetFirstPrincipalChild(); + colFrame = colFrame->PrincipalChildList().FirstChild(); if (!colFrame) return; diff --git a/media/mtransport/rlogringbuffer.cpp b/media/mtransport/rlogringbuffer.cpp index d8ebf2d74f..b263ff08ff 100644 --- a/media/mtransport/rlogringbuffer.cpp +++ b/media/mtransport/rlogringbuffer.cpp @@ -87,6 +87,11 @@ void RLogRingBuffer::DestroyInstance() { delete instance; instance = nullptr; } + +void RLogRingBuffer::Clear() { + OffTheBooksMutexAutoLock lock(mutex_); + log_messages_.clear(); +} void RLogRingBuffer::Filter(const std::string& substring, uint32_t limit, diff --git a/media/mtransport/rlogringbuffer.h b/media/mtransport/rlogringbuffer.h index 3b49be263c..2c6475b396 100644 --- a/media/mtransport/rlogringbuffer.h +++ b/media/mtransport/rlogringbuffer.h @@ -95,8 +95,8 @@ class RLogRingBuffer { } void SetLogLimit(uint32_t new_limit); - void Log(std::string&& log); + void Clear(); private: RLogRingBuffer(); diff --git a/media/webrtc/signaling/src/peerconnection/WebrtcGlobalChild.h b/media/webrtc/signaling/src/peerconnection/WebrtcGlobalChild.h index ed1de43a95..544315a3e9 100644 --- a/media/webrtc/signaling/src/peerconnection/WebrtcGlobalChild.h +++ b/media/webrtc/signaling/src/peerconnection/WebrtcGlobalChild.h @@ -22,8 +22,10 @@ class WebrtcGlobalChild : virtual bool RecvGetStatsRequest(const int& aRequestId, const nsString& aPcIdFilter) override; + virtual bool RecvClearStatsRequest() override; virtual bool RecvGetLogRequest(const int& aReqestId, const nsCString& aPattern) override; + virtual bool RecvClearLogRequest() override; virtual bool RecvSetAecLogging(const bool& aEnable) override; virtual bool RecvSetDebugMode(const int& aLevel) override; diff --git a/media/webrtc/signaling/src/peerconnection/WebrtcGlobalInformation.cpp b/media/webrtc/signaling/src/peerconnection/WebrtcGlobalInformation.cpp index 76310ad5bf..22d707e668 100644 --- a/media/webrtc/signaling/src/peerconnection/WebrtcGlobalInformation.cpp +++ b/media/webrtc/signaling/src/peerconnection/WebrtcGlobalInformation.cpp @@ -292,7 +292,7 @@ GetAllStats_s(WebrtcGlobalChild* aThisChild, nsAutoPtr aQueryList) { MOZ_ASSERT(aQueryList); - // The call to PeerConnetionImpl must happen on the from a runnable + // The call to PeerConnetionImpl must happen from a runnable // dispatched on the STS thread. // Get stats from active connections. @@ -433,6 +433,37 @@ RunStatsQuery( return rv; } +void ClearClosedStats() +{ + PeerConnectionCtx* ctx = GetPeerConnectionCtx(); + + if (ctx) { + ctx->mStatsForClosedPeerConnections.Clear(); + } +} + +void +WebrtcGlobalInformation::ClearAllStats( + const GlobalObject& aGlobal) +{ + if (!NS_IsMainThread()) { + return; + } + + // Chrome-only API + MOZ_ASSERT(XRE_IsParentProcess()); + + if (!WebrtcContentParents::Empty()) { + // Pass on the request to any content process based PeerConnections. + for (auto& cp : WebrtcContentParents::GetAll()) { + Unused << cp->SendClearStatsRequest(); + } + } + + // Flush the history for the chrome process + ClearClosedStats(); +} + void WebrtcGlobalInformation::GetAllStats( const GlobalObject& aGlobal, @@ -448,7 +479,7 @@ WebrtcGlobalInformation::GetAllStats( MOZ_ASSERT(XRE_IsParentProcess()); // CallbackObject does not support threadsafe refcounting, and must be - // destroyed on main. + // used and destroyed on main. StatsRequestCallback callbackHandle( new nsMainThreadPtrHolder(&aStatsCallback)); @@ -457,7 +488,7 @@ WebrtcGlobalInformation::GetAllStats( filter = pcIdFilter.Value(); } - StatsRequest* request = StatsRequest::Create(callbackHandle, filter); + auto* request = StatsRequest::Create(callbackHandle, filter); if (!request) { aRv.Throw(NS_ERROR_FAILURE); @@ -524,6 +555,56 @@ RunLogQuery(const nsCString& aPattern, return rv; } +static void ClearLogs_s() +{ + // Make call off main thread. + RLogRingBuffer* logs = RLogRingBuffer::GetInstance(); + if (logs) { + logs->Clear(); + } +} + +static nsresult +RunLogClear() +{ + nsresult rv; + nsCOMPtr stsThread = + do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv); + + if (NS_FAILED(rv)) { + return rv; + } + if (!stsThread) { + return NS_ERROR_FAILURE; + } + + return RUN_ON_THREAD(stsThread, + WrapRunnableNM(&ClearLogs_s), + NS_DISPATCH_NORMAL); +} + +void +WebrtcGlobalInformation::ClearLogging( + const GlobalObject& aGlobal) +{ + if (!NS_IsMainThread()) { + return; + } + + // Chrome-only API + MOZ_ASSERT(XRE_IsParentProcess()); + + if (!WebrtcContentParents::Empty()) { + // Clear content process signaling logs + for (auto& cp : WebrtcContentParents::GetAll()) { + Unused << cp->SendClearLogRequest(); + } + } + + // Clear chrome process signaling logs + Unused << RunLogClear(); +} + void WebrtcGlobalInformation::GetLogging( const GlobalObject& aGlobal, @@ -746,6 +827,17 @@ WebrtcGlobalChild::RecvGetStatsRequest(const int& aRequestId, return true; } +bool +WebrtcGlobalChild::RecvClearStatsRequest() +{ + if (mShutdown) { + return true; + } + + ClearClosedStats(); + return true; +} + bool WebrtcGlobalChild::RecvGetLogRequest(const int& aRequestId, const nsCString& aPattern) @@ -774,6 +866,17 @@ WebrtcGlobalChild::RecvGetLogRequest(const int& aRequestId, return true; } +bool +WebrtcGlobalChild::RecvClearLogRequest() +{ + if (mShutdown) { + return true; + } + + RunLogClear(); + return true; +} + bool WebrtcGlobalChild::RecvSetAecLogging(const bool& aEnable) { diff --git a/media/webrtc/signaling/src/peerconnection/WebrtcGlobalInformation.h b/media/webrtc/signaling/src/peerconnection/WebrtcGlobalInformation.h index 2725a29a66..fb3789c203 100644 --- a/media/webrtc/signaling/src/peerconnection/WebrtcGlobalInformation.h +++ b/media/webrtc/signaling/src/peerconnection/WebrtcGlobalInformation.h @@ -26,11 +26,15 @@ public: const Optional& pcIdFilter, ErrorResult& aRv); + static void ClearAllStats(const GlobalObject& aGlobal); + static void GetLogging(const GlobalObject& aGlobal, const nsAString& aPattern, WebrtcGlobalLoggingCallback& aLoggingCallback, ErrorResult& aRv); + static void ClearLogging(const GlobalObject& aGlobal); + static void SetDebugLevel(const GlobalObject& aGlobal, int32_t aLevel); static int32_t DebugLevel(const GlobalObject& aGlobal); diff --git a/netwerk/cookie/PCookieService.ipdl b/netwerk/cookie/PCookieService.ipdl index 183a4ff3f9..414b491130 100644 --- a/netwerk/cookie/PCookieService.ipdl +++ b/netwerk/cookie/PCookieService.ipdl @@ -102,7 +102,7 @@ parent: bool fromHttp, SerializedLoadContext loadContext); - __delete__(); + async __delete__(); }; } diff --git a/netwerk/dns/PDNSRequest.ipdl b/netwerk/dns/PDNSRequest.ipdl index 4209405454..2288ab09e5 100644 --- a/netwerk/dns/PDNSRequest.ipdl +++ b/netwerk/dns/PDNSRequest.ipdl @@ -23,12 +23,12 @@ parent: // Pass args here rather than storing them in the parent; they are only // needed if the request is to be canceled. - CancelDNSRequest(nsCString hostName, uint32_t flags, - nsCString networkInterface, nsresult reason); - __delete__(); + async CancelDNSRequest(nsCString hostName, uint32_t flags, + nsCString networkInterface, nsresult reason); + async __delete__(); child: - LookupCompleted(DNSRequestResponse reply); + async LookupCompleted(DNSRequestResponse reply); }; diff --git a/netwerk/ipc/PChannelDiverter.ipdl b/netwerk/ipc/PChannelDiverter.ipdl index dd7aa85d94..12be1f09b4 100644 --- a/netwerk/ipc/PChannelDiverter.ipdl +++ b/netwerk/ipc/PChannelDiverter.ipdl @@ -18,7 +18,7 @@ async protocol PChannelDiverter manager PNecko; child: - __delete__(); + async __delete__(); }; }// namespace net diff --git a/netwerk/ipc/PDataChannel.ipdl b/netwerk/ipc/PDataChannel.ipdl index 17a340cc0d..69eef43aed 100644 --- a/netwerk/ipc/PDataChannel.ipdl +++ b/netwerk/ipc/PDataChannel.ipdl @@ -18,7 +18,7 @@ async protocol PDataChannel parent: // Note: channels are opened during construction, so no open method here: // see PNecko.ipdl - __delete__(); + async __delete__(); }; } // namespace net diff --git a/netwerk/ipc/PNecko.ipdl b/netwerk/ipc/PNecko.ipdl index 2e1f2f5182..c3befb0fee 100644 --- a/netwerk/ipc/PNecko.ipdl +++ b/netwerk/ipc/PNecko.ipdl @@ -58,61 +58,61 @@ prio(normal upto urgent) sync protocol PNecko manages PChannelDiverter; parent: - __delete__(); + async __delete__(); prio(urgent) async PCookieService(); - PHttpChannel(PBrowserOrId browser, - SerializedLoadContext loadContext, - HttpChannelCreationArgs args); - PWyciwygChannel(); - PFTPChannel(PBrowserOrId browser, SerializedLoadContext loadContext, - FTPChannelCreationArgs args); + async PHttpChannel(PBrowserOrId browser, + SerializedLoadContext loadContext, + HttpChannelCreationArgs args); + async PWyciwygChannel(); + async PFTPChannel(PBrowserOrId browser, SerializedLoadContext loadContext, + FTPChannelCreationArgs args); - PWebSocket(PBrowserOrId browser, SerializedLoadContext loadContext, - uint32_t aSerialID); - PTCPServerSocket(uint16_t localPort, uint16_t backlog, bool useArrayBuffers); - PUDPSocket(Principal principal, nsCString filter); + async PWebSocket(PBrowserOrId browser, SerializedLoadContext loadContext, + uint32_t aSerialID); + async PTCPServerSocket(uint16_t localPort, uint16_t backlog, bool useArrayBuffers); + async PUDPSocket(Principal principal, nsCString filter); - PDNSRequest(nsCString hostName, uint32_t flags, nsCString networkInterface); + async PDNSRequest(nsCString hostName, uint32_t flags, nsCString networkInterface); - PWebSocketEventListener(uint64_t aInnerWindowID); + async PWebSocketEventListener(uint64_t aInnerWindowID); /* Predictor Methods */ - PredPredict(OptionalURIParams targetURI, OptionalURIParams sourceURI, - uint32_t reason, SerializedLoadContext loadContext, - bool hasVerifier); - PredLearn(URIParams targetURI, OptionalURIParams sourceURI, - uint32_t reason, SerializedLoadContext loadContext); - PredReset(); + async PredPredict(OptionalURIParams targetURI, OptionalURIParams sourceURI, + uint32_t reason, SerializedLoadContext loadContext, + bool hasVerifier); + async PredLearn(URIParams targetURI, OptionalURIParams sourceURI, + uint32_t reason, SerializedLoadContext loadContext); + async PredReset(); - PRemoteOpenFile(SerializedLoadContext loadContext, - URIParams fileuri, - OptionalURIParams appuri); + async PRemoteOpenFile(SerializedLoadContext loadContext, + URIParams fileuri, + OptionalURIParams appuri); - SpeculativeConnect(URIParams uri, bool anonymous); - HTMLDNSPrefetch(nsString hostname, uint16_t flags); - CancelHTMLDNSPrefetch(nsString hostname, uint16_t flags, nsresult reason); + async SpeculativeConnect(URIParams uri, bool anonymous); + async HTMLDNSPrefetch(nsString hostname, uint16_t flags); + async CancelHTMLDNSPrefetch(nsString hostname, uint16_t flags, nsresult reason); /** * channelId is used to establish a connection between redirect channels in * the parent and the child when we're redirecting to a data: URI. */ - PDataChannel(uint32_t channelId); + async PDataChannel(uint32_t channelId); - PRtspController(); - PRtspChannel(RtspChannelConnectArgs args); - PChannelDiverter(ChannelDiverterArgs channel); + async PRtspController(); + async PRtspChannel(RtspChannelConnectArgs args); + async PChannelDiverter(ChannelDiverterArgs channel); /** * These are called from the child with the results of the auth prompt. * callbackId is the id that was passed in PBrowser::AsyncAuthPrompt, * corresponding to an nsIAuthPromptCallback */ - OnAuthAvailable(uint64_t callbackId, nsString user, - nsString password, nsString domain); - OnAuthCancelled(uint64_t callbackId, bool userCancel); + async OnAuthAvailable(uint64_t callbackId, nsString user, + nsString password, nsString domain); + async OnAuthCancelled(uint64_t callbackId, bool userCancel); - RemoveSchedulingContext(nsCString scid); + async RemoveSchedulingContext(nsCString scid); child: /* @@ -120,20 +120,20 @@ child: * NestedFrameId is the id corresponding to the PBrowser. It is the same id * that was passed to the PBrowserOrId param in to the PHttpChannel constructor */ - AsyncAuthPromptForNestedFrame(TabId nestedFrameId, nsCString uri, - nsString realm, uint64_t callbackId); + async AsyncAuthPromptForNestedFrame(TabId nestedFrameId, nsCString uri, + nsString realm, uint64_t callbackId); // Notifies child that a given app is now offline (or online) - AppOfflineStatus(uint32_t appId, bool offline); + async AppOfflineStatus(uint32_t appId, bool offline); /* Predictor Methods */ - PredOnPredictPreconnect(URIParams uri); - PredOnPredictDNS(URIParams uri); + async PredOnPredictPreconnect(URIParams uri); + async PredOnPredictDNS(URIParams uri); both: // Actually we need PTCPSocket() for parent. But ipdl disallows us having different // signatures on parent and child. So when constructing the parent side object, we just // leave host/port unused. - PTCPSocket(nsString host, uint16_t port); + async PTCPSocket(nsString host, uint16_t port); }; diff --git a/netwerk/ipc/PRemoteOpenFile.ipdl b/netwerk/ipc/PRemoteOpenFile.ipdl index d09c9d37c9..0498d6f87d 100644 --- a/netwerk/ipc/PRemoteOpenFile.ipdl +++ b/netwerk/ipc/PRemoteOpenFile.ipdl @@ -20,7 +20,7 @@ protocol PRemoteOpenFile child: // Your file handle is ready, Sir... - __delete__(FileDescriptor fd); + async __delete__(FileDescriptor fd); }; diff --git a/netwerk/ipc/PRtspChannel.ipdl b/netwerk/ipc/PRtspChannel.ipdl index c8a4bbe1a1..e884cae762 100644 --- a/netwerk/ipc/PRtspChannel.ipdl +++ b/netwerk/ipc/PRtspChannel.ipdl @@ -18,7 +18,7 @@ async protocol PRtspChannel parent: // Note: channels are opened during construction, so no open method here: // see PNecko.ipdl - __delete__(); + async __delete__(); }; } // namespace net diff --git a/netwerk/ipc/PRtspController.ipdl b/netwerk/ipc/PRtspController.ipdl index de74461779..656dbe0b9a 100644 --- a/netwerk/ipc/PRtspController.ipdl +++ b/netwerk/ipc/PRtspController.ipdl @@ -37,27 +37,27 @@ async protocol PRtspController manager PNecko; parent: - AsyncOpen(URIParams aURI); - Play(); - Pause(); - Resume(); - Suspend(); - Seek(uint64_t offset); - Stop(); - PlaybackEnded(); - __delete__(); + async AsyncOpen(URIParams aURI); + async Play(); + async Pause(); + async Resume(); + async Suspend(); + async Seek(uint64_t offset); + async Stop(); + async PlaybackEnded(); + async __delete__(); child: - OnMediaDataAvailable(uint8_t index, - nsCString data, - uint32_t length, - uint32_t offset, - RtspMetadataParam[] meta); - OnConnected(uint8_t index, - RtspMetadataParam[] meta); - OnDisconnected(uint8_t index, - nsresult reason); - AsyncOpenFailed(nsresult reason); + async OnMediaDataAvailable(uint8_t index, + nsCString data, + uint32_t length, + uint32_t offset, + RtspMetadataParam[] meta); + async OnConnected(uint8_t index, + RtspMetadataParam[] meta); + async OnDisconnected(uint8_t index, + nsresult reason); + async AsyncOpenFailed(nsresult reason); }; } //namespace net diff --git a/netwerk/protocol/ftp/PFTPChannel.ipdl b/netwerk/protocol/ftp/PFTPChannel.ipdl index b6b0458896..9793074f6d 100644 --- a/netwerk/protocol/ftp/PFTPChannel.ipdl +++ b/netwerk/protocol/ftp/PFTPChannel.ipdl @@ -26,45 +26,45 @@ parent: // Note: channels are opened during construction, so no open method here: // see PNecko.ipdl - __delete__(); + async __delete__(); - Cancel(nsresult status); - Suspend(); - Resume(); + async Cancel(nsresult status); + async Suspend(); + async Resume(); // Divert OnDataAvailable to the parent. - DivertOnDataAvailable(nsCString data, - uint64_t offset, - uint32_t count); + async DivertOnDataAvailable(nsCString data, + uint64_t offset, + uint32_t count); // Divert OnStopRequest to the parent. - DivertOnStopRequest(nsresult statusCode); + async DivertOnStopRequest(nsresult statusCode); // Child has no more events/messages to divert to the parent. - DivertComplete(); + async DivertComplete(); child: - OnStartRequest(nsresult aChannelStatus, - int64_t aContentLength, - nsCString aContentType, - PRTime aLastModified, - nsCString aEntityID, - URIParams aURI); - OnDataAvailable(nsresult channelStatus, - nsCString data, - uint64_t offset, - uint32_t count); - OnStopRequest(nsresult channelStatus); - FailedAsyncOpen(nsresult statusCode); + async OnStartRequest(nsresult aChannelStatus, + int64_t aContentLength, + nsCString aContentType, + PRTime aLastModified, + nsCString aEntityID, + URIParams aURI); + async OnDataAvailable(nsresult channelStatus, + nsCString data, + uint64_t offset, + uint32_t count); + async OnStopRequest(nsresult channelStatus); + async FailedAsyncOpen(nsresult statusCode); // Parent has been suspended for diversion; no more events to be enqueued. - FlushedForDiversion(); + async FlushedForDiversion(); // Child should resume processing the ChannelEventQueue, i.e. diverting any // OnDataAvailable and OnStopRequest messages in the queue back to the parent. - DivertMessages(); + async DivertMessages(); - DeleteSelf(); + async DeleteSelf(); }; } // namespace net diff --git a/netwerk/protocol/http/PHttpChannel.ipdl b/netwerk/protocol/http/PHttpChannel.ipdl index 0002376bd4..18f93f61fc 100644 --- a/netwerk/protocol/http/PHttpChannel.ipdl +++ b/netwerk/protocol/http/PHttpChannel.ipdl @@ -31,27 +31,27 @@ parent: // Note: channels are opened during construction, so no open method here: // see PNecko.ipdl - SetPriority(uint16_t priority); - SetClassOfService(uint32_t cos); + async SetPriority(uint16_t priority); + async SetClassOfService(uint32_t cos); - SetCacheTokenCachedCharset(nsCString charset); + async SetCacheTokenCachedCharset(nsCString charset); - UpdateAssociatedContentSecurity(int32_t broken, - int32_t no); - Suspend(); - Resume(); + async UpdateAssociatedContentSecurity(int32_t broken, + int32_t no); + async Suspend(); + async Resume(); - Cancel(nsresult status); + async Cancel(nsresult status); // Reports approval/veto of redirect by child process redirect observers - Redirect2Verify(nsresult result, RequestHeaderTuples changedHeaders, - uint32_t loadFlags, OptionalURIParams apiRedirectTo, - OptionalCorsPreflightArgs corsPreflightArgs); + async Redirect2Verify(nsresult result, RequestHeaderTuples changedHeaders, + uint32_t loadFlags, OptionalURIParams apiRedirectTo, + OptionalCorsPreflightArgs corsPreflightArgs); // For document loads we keep this protocol open after child's // OnStopRequest, and send this msg (instead of __delete__) to allow // partial cleanup on parent. - DocumentChannelCleanup(); + async DocumentChannelCleanup(); // This might have to be sync. If this fails we must fail the document load // to avoid endless loop. @@ -66,96 +66,96 @@ parent: // we reload the document to take the effect. If we fail to mark the entry // as foreign, we will end up in the same situation and reload again and // again, indefinitely. - MarkOfflineCacheEntryAsForeign(); + async MarkOfflineCacheEntryAsForeign(); // Divert OnDataAvailable to the parent. - DivertOnDataAvailable(nsCString data, - uint64_t offset, - uint32_t count); + async DivertOnDataAvailable(nsCString data, + uint64_t offset, + uint32_t count); // Divert OnStopRequest to the parent. - DivertOnStopRequest(nsresult statusCode); + async DivertOnStopRequest(nsresult statusCode); // Child has no more events/messages to divert to the parent. - DivertComplete(); + async DivertComplete(); // Child has detected a CORS check failure, so needs to tell the parent // to remove any matching entry from the CORS preflight cache. - RemoveCorsPreflightCacheEntry(URIParams uri, - PrincipalInfo requestingPrincipal); + async RemoveCorsPreflightCacheEntry(URIParams uri, + PrincipalInfo requestingPrincipal); - __delete__(); + async __delete__(); child: - OnStartRequest(nsresult channelStatus, - nsHttpResponseHead responseHead, - bool useResponseHead, - nsHttpHeaderArray requestHeaders, - bool isFromCache, - bool cacheEntryAvailable, - uint32_t cacheExpirationTime, - nsCString cachedCharset, - nsCString securityInfoSerialization, - NetAddr selfAddr, - NetAddr peerAddr, - int16_t redirectCount, - uint32_t cacheKey); + async OnStartRequest(nsresult channelStatus, + nsHttpResponseHead responseHead, + bool useResponseHead, + nsHttpHeaderArray requestHeaders, + bool isFromCache, + bool cacheEntryAvailable, + uint32_t cacheExpirationTime, + nsCString cachedCharset, + nsCString securityInfoSerialization, + NetAddr selfAddr, + NetAddr peerAddr, + int16_t redirectCount, + uint32_t cacheKey); // Combines a single OnDataAvailable and its associated OnProgress & // OnStatus calls into one IPDL message - OnTransportAndData(nsresult channelStatus, - nsresult transportStatus, - uint64_t progress, - uint64_t progressMax, - nsCString data, - uint64_t offset, - uint32_t count); + async OnTransportAndData(nsresult channelStatus, + nsresult transportStatus, + uint64_t progress, + uint64_t progressMax, + nsCString data, + uint64_t offset, + uint32_t count); - OnStopRequest(nsresult channelStatus, ResourceTimingStruct timing); + async OnStopRequest(nsresult channelStatus, ResourceTimingStruct timing); - OnProgress(int64_t progress, int64_t progressMax); + async OnProgress(int64_t progress, int64_t progressMax); - OnStatus(nsresult status); + async OnStatus(nsresult status); // Used to cancel child channel if we hit errors during creating and // AsyncOpen of nsHttpChannel on the parent. - FailedAsyncOpen(nsresult status); + async FailedAsyncOpen(nsresult status); // Called to initiate content channel redirect, starts talking to sinks // on the content process and reports result via Redirect2Verify above - Redirect1Begin(uint32_t newChannelId, - URIParams newUri, - uint32_t redirectFlags, - nsHttpResponseHead responseHead, - nsCString securityInfoSerialization); + async Redirect1Begin(uint32_t newChannelId, + URIParams newUri, + uint32_t redirectFlags, + nsHttpResponseHead responseHead, + nsCString securityInfoSerialization); // Called if redirect successful so that child can complete setup. - Redirect3Complete(); + async Redirect3Complete(); // Associate the child with an application ids - AssociateApplicationCache(nsCString groupID, - nsCString clientID); + async AssociateApplicationCache(nsCString groupID, + nsCString clientID); // Tell the child that tracking protection was disabled for this load. - NotifyTrackingProtectionDisabled(); + async NotifyTrackingProtectionDisabled(); // Parent has been suspended for diversion; no more events to be enqueued. - FlushedForDiversion(); + async FlushedForDiversion(); // Child should resume processing the ChannelEventQueue, i.e. diverting any // OnDataAvailable and OnStopRequest messages in the queue back to the parent. - DivertMessages(); + async DivertMessages(); // Report a security message to the console associated with this // channel. - ReportSecurityMessage(nsString messageTag, nsString messageCategory); + async ReportSecurityMessage(nsString messageTag, nsString messageCategory); // Tell child to delete channel (all IPDL deletes must be done from child to // avoid races: see bug 591708). - DeleteSelf(); + async DeleteSelf(); // Tell the child to issue a deprecation warning. - IssueDeprecationWarning(uint32_t warning, bool asError); + async IssueDeprecationWarning(uint32_t warning, bool asError); }; diff --git a/netwerk/protocol/websocket/PWebSocket.ipdl b/netwerk/protocol/websocket/PWebSocket.ipdl index 82a451b1a1..42eaa74881 100644 --- a/netwerk/protocol/websocket/PWebSocket.ipdl +++ b/netwerk/protocol/websocket/PWebSocket.ipdl @@ -24,35 +24,35 @@ async protocol PWebSocket parent: // Forwarded methods corresponding to methods on nsIWebSocketChannel - AsyncOpen(URIParams aURI, - nsCString aOrigin, - uint64_t aInnerWindowID, - nsCString aProtocol, - bool aSecure, - // ping values only meaningful if client set them - uint32_t aPingInterval, - bool aClientSetPingInterval, - uint32_t aPingTimeout, - bool aClientSetPingTimeout, - OptionalLoadInfoArgs aLoadInfoArgs); - Close(uint16_t code, nsCString reason); - SendMsg(nsCString aMsg); - SendBinaryMsg(nsCString aMsg); - SendBinaryStream(InputStreamParams aStream, uint32_t aLength); + async AsyncOpen(URIParams aURI, + nsCString aOrigin, + uint64_t aInnerWindowID, + nsCString aProtocol, + bool aSecure, + // ping values only meaningful if client set them + uint32_t aPingInterval, + bool aClientSetPingInterval, + uint32_t aPingTimeout, + bool aClientSetPingTimeout, + OptionalLoadInfoArgs aLoadInfoArgs); + async Close(uint16_t code, nsCString reason); + async SendMsg(nsCString aMsg); + async SendBinaryMsg(nsCString aMsg); + async SendBinaryStream(InputStreamParams aStream, uint32_t aLength); - DeleteSelf(); + async DeleteSelf(); child: // Forwarded notifications corresponding to the nsIWebSocketListener interface - OnStart(nsCString aProtocol, nsCString aExtensions, - nsString aEffectiveURL, bool aEncrypted); - OnStop(nsresult aStatusCode); - OnMessageAvailable(nsCString aMsg); - OnBinaryMessageAvailable(nsCString aMsg); - OnAcknowledge(uint32_t aSize); - OnServerClose(uint16_t code, nsCString aReason); + async OnStart(nsCString aProtocol, nsCString aExtensions, + nsString aEffectiveURL, bool aEncrypted); + async OnStop(nsresult aStatusCode); + async OnMessageAvailable(nsCString aMsg); + async OnBinaryMessageAvailable(nsCString aMsg); + async OnAcknowledge(uint32_t aSize); + async OnServerClose(uint16_t code, nsCString aReason); - __delete__(); + async __delete__(); }; diff --git a/netwerk/protocol/websocket/PWebSocketEventListener.ipdl b/netwerk/protocol/websocket/PWebSocketEventListener.ipdl index ef0310d7cb..35a1074578 100644 --- a/netwerk/protocol/websocket/PWebSocketEventListener.ipdl +++ b/netwerk/protocol/websocket/PWebSocketEventListener.ipdl @@ -17,34 +17,34 @@ async protocol PWebSocketEventListener manager PNecko; child: - WebSocketCreated(uint32_t awebSocketSerialID, - nsString aURI, - nsCString aProtocols); + async WebSocketCreated(uint32_t awebSocketSerialID, + nsString aURI, + nsCString aProtocols); - WebSocketOpened(uint32_t awebSocketSerialID, - nsString aEffectiveURI, - nsCString aProtocols, - nsCString aExtensions); + async WebSocketOpened(uint32_t awebSocketSerialID, + nsString aEffectiveURI, + nsCString aProtocols, + nsCString aExtensions); - WebSocketMessageAvailable(uint32_t awebSocketSerialID, - nsCString aData, - uint16_t aMessageType); + async WebSocketMessageAvailable(uint32_t awebSocketSerialID, + nsCString aData, + uint16_t aMessageType); - WebSocketClosed(uint32_t awebSocketSerialID, - bool aWasClean, - uint16_t aCode, - nsString aReason); + async WebSocketClosed(uint32_t awebSocketSerialID, + bool aWasClean, + uint16_t aCode, + nsString aReason); - FrameReceived(uint32_t aWebSocketSerialID, - WebSocketFrameData aFrameData); + async FrameReceived(uint32_t aWebSocketSerialID, + WebSocketFrameData aFrameData); - FrameSent(uint32_t aWebSocketSerialID, - WebSocketFrameData aFrameData); + async FrameSent(uint32_t aWebSocketSerialID, + WebSocketFrameData aFrameData); - __delete__(); + async __delete__(); parent: - Close(); + async Close(); }; } //namespace net diff --git a/netwerk/protocol/wyciwyg/PWyciwygChannel.ipdl b/netwerk/protocol/wyciwyg/PWyciwygChannel.ipdl index 092ed1e804..c3d21c1743 100644 --- a/netwerk/protocol/wyciwyg/PWyciwygChannel.ipdl +++ b/netwerk/protocol/wyciwyg/PWyciwygChannel.ipdl @@ -1,3 +1,5 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set sw=2 ts=8 et tw=80 ft=cpp : */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -19,39 +21,39 @@ protocol PWyciwygChannel manager PNecko; parent: - __delete__(); + async __delete__(); - Init(URIParams uri, - PrincipalInfo requestingPrincipalInfo, - PrincipalInfo triggeringPrincipalInfo, - uint32_t securityFlags, - uint32_t contentPolicyType); - AsyncOpen(URIParams originalURI, - uint32_t loadFlags, - SerializedLoadContext loadContext, - PBrowserOrId browser); - AppData(SerializedLoadContext loadContext, PBrowserOrId browser); + async Init(URIParams uri, + PrincipalInfo requestingPrincipalInfo, + PrincipalInfo triggeringPrincipalInfo, + uint32_t securityFlags, + uint32_t contentPolicyType); + async AsyncOpen(URIParams originalURI, + uint32_t loadFlags, + SerializedLoadContext loadContext, + PBrowserOrId browser); + async AppData(SerializedLoadContext loadContext, PBrowserOrId browser); // methods corresponding to those of nsIWyciwygChannel - WriteToCacheEntry(nsString data); - CloseCacheEntry(nsresult reason); - SetCharsetAndSource(int32_t source, nsCString charset); - SetSecurityInfo(nsCString securityInfo); - Cancel(nsresult status); + async WriteToCacheEntry(nsString data); + async CloseCacheEntry(nsresult reason); + async SetCharsetAndSource(int32_t source, nsCString charset); + async SetSecurityInfo(nsCString securityInfo); + async Cancel(nsresult status); child: - OnStartRequest(nsresult statusCode, - int64_t contentLength, - int32_t source, - nsCString charset, - nsCString securityInfo); + async OnStartRequest(nsresult statusCode, + int64_t contentLength, + int32_t source, + nsCString charset, + nsCString securityInfo); - OnDataAvailable(nsCString data, - uint64_t offset); + async OnDataAvailable(nsCString data, + uint64_t offset); - OnStopRequest(nsresult statusCode); + async OnStopRequest(nsresult statusCode); - CancelEarly(nsresult statusCode); + async CancelEarly(nsresult statusCode); }; diff --git a/security/manager/ssl/PPSMContentDownloader.ipdl b/security/manager/ssl/PPSMContentDownloader.ipdl index ac97d7c444..a9c0fc266e 100644 --- a/security/manager/ssl/PPSMContentDownloader.ipdl +++ b/security/manager/ssl/PPSMContentDownloader.ipdl @@ -14,14 +14,14 @@ protocol PPSMContentDownloader manager PContent; parent: - OnStartRequest(uint32_t contentLength); - OnDataAvailable(nsCString data, uint64_t offset, uint32_t count); - OnStopRequest(nsresult code); + async OnStartRequest(uint32_t contentLength); + async OnDataAvailable(nsCString data, uint64_t offset, uint32_t count); + async OnStopRequest(nsresult code); - DivertToParentUsing(PChannelDiverter diverter); + async DivertToParentUsing(PChannelDiverter diverter); child: - __delete__(); + async __delete__(); }; } // namespace psm diff --git a/testing/marionette/client/marionette/tests/webapi-tests.ini b/testing/marionette/client/marionette/tests/webapi-tests.ini index a0cfcb9461..b6f98ac436 100644 --- a/testing/marionette/client/marionette/tests/webapi-tests.ini +++ b/testing/marionette/client/marionette/tests/webapi-tests.ini @@ -26,3 +26,4 @@ skip = false [include:../../../../../dom/wifi/test/marionette/manifest.ini] [include:../../../../../dom/cellbroadcast/tests/marionette/manifest.ini] [include:../../../../../dom/tethering/tests/marionette/manifest.ini] +[include:../../../../../dom/network/tests/marionette/manifest.ini] diff --git a/testing/mochitest/tests/SimpleTest/WindowSnapshot.js b/testing/mochitest/tests/SimpleTest/WindowSnapshot.js index 6323603c00..a051ad5cff 100644 --- a/testing/mochitest/tests/SimpleTest/WindowSnapshot.js +++ b/testing/mochitest/tests/SimpleTest/WindowSnapshot.js @@ -75,3 +75,14 @@ function assertSnapshots(s1, s2, expectEqual, fuzz, s1name, s2name) { } return passed; } + +function assertWindowPureColor(win, color) { + const snapshot = SpecialPowers.snapshotRect(win); + const canvas = document.createElement("canvas"); + canvas.width = snapshot.width; + canvas.height = snapshot.height; + const context = canvas.getContext("2d"); + context.fillStyle = color; + context.fillRect(0, 0, canvas.width, canvas.height); + assertSnapshots(snapshot, canvas, true, null, "snapshot", color); +} diff --git a/testing/web-platform/tests/js/builtins/WeakMap.prototype-properties.html b/testing/web-platform/tests/js/builtins/WeakMap.prototype-properties.html index c312a83054..ecf4a8e311 100644 --- a/testing/web-platform/tests/js/builtins/WeakMap.prototype-properties.html +++ b/testing/web-platform/tests/js/builtins/WeakMap.prototype-properties.html @@ -50,31 +50,13 @@ test(function() { assert_equals(Object.getPrototypeOf(WeakMap.prototype), Object.prototype); }, "The value of the [[Prototype]] internal property of the WeakMap prototype object is the standard built-in Object prototype object (15.2.4).") -// 15.15.5.1 WeakMap.prototype.constructor +// 23.3.3.1 WeakMap.prototype.constructor test(function() { assert_equals(WeakMap.prototype.constructor, WeakMap); assert_propdesc(WeakMap.prototype, "constructor", true, false, true); }, "The initial value of WeakMap.prototype.constructor is the built-in WeakMap constructor.") -// 15.15.5.2 WeakMap.prototype.clear () -test(function() { - assert_propdesc(WeakMap.prototype, "clear", true, false, true); - test_length("clear", 0); - // Step 1-3 - test_thisval("clear", null); - // Step 4-5 - test(function() { - var wm = new WeakMap(); - var key = {}; - wm.set(key, "fail"); - assert_true(wm.has(key)); - var res = wm.clear(); - assert_equals(res, undefined); - assert_false(wm.has(key)); - }, "WeakMap.prototype.clear: basic functionality"); -}, "WeakMap.prototype.clear") - -// 15.15.5.3 WeakMap.prototype.delete ( key ) +// 23.3.3.2 WeakMap.prototype.delete ( key ) test(function() { assert_propdesc(WeakMap.prototype, "delete", true, false, true); test_length("delete", 1); @@ -82,7 +64,7 @@ test(function() { test_thisval("delete", [{}]); }, "WeakMap.prototype.delete") -// 15.15.5.4 WeakMap.prototype.get ( key ) +// 23.3.3.3 WeakMap.prototype.get ( key ) test(function() { assert_propdesc(WeakMap.prototype, "get", true, false, true); test_length("get", 1); @@ -98,7 +80,7 @@ test(function() { }, "WeakMap.prototype.get: return undefined"); }, "WeakMap.prototype.get") -// 15.14.5.5 Map.prototype.has ( key ) +// 23.3.3.4 Map.prototype.has ( key ) test(function() { assert_propdesc(WeakMap.prototype, "has", true, false, true); test_length("has", 1); @@ -106,7 +88,7 @@ test(function() { test_thisval("has", [{}]); }, "WeakMap.prototype.has") -// 15.14.5.6 Map.prototype.set ( key , value ) +// 23.3.3.5 Map.prototype.set ( key , value ) test(function() { assert_propdesc(WeakMap.prototype, "set", true, false, true); test_length("set", 2); @@ -114,7 +96,7 @@ test(function() { test_thisval("set", [{}, {}]); }, "WeakMap.prototype.set") -// 15.15.5.7 Map.prototype.@@toStringTag +// 23.3.3.6 Map.prototype.@@toStringTag test(function() { assert_class_string(new WeakMap(), "WeakMap"); assert_class_string(WeakMap.prototype, "WeakMap"); diff --git a/toolkit/commonjs/sdk/lang/weak-set.js b/toolkit/commonjs/sdk/lang/weak-set.js index 71c6e58e53..0b81a395b1 100644 --- a/toolkit/commonjs/sdk/lang/weak-set.js +++ b/toolkit/commonjs/sdk/lang/weak-set.js @@ -13,16 +13,21 @@ const { Cu } = require("chrome"); function makeGetterFor(Type) { let cache = new WeakMap(); - return function getFor(target) { - if (!cache.has(target)) - cache.set(target, new Type()); + return { + getFor(target) { + if (!cache.has(target)) + cache.set(target, new Type()); - return cache.get(target); + return cache.get(target); + }, + clearFor(target) { + return cache.delete(target) + } } } -let getLookupFor = makeGetterFor(WeakMap); -let getRefsFor = makeGetterFor(Set); +var {getFor: getLookupFor, clearFor: clearLookupFor} = makeGetterFor(WeakMap); +var {getFor: getRefsFor, clearFor: clearRefsFor} = makeGetterFor(Set); function add(target, value) { if (has(target, value)) @@ -44,8 +49,8 @@ function has(target, value) { exports.has = has; function clear(target) { - getLookupFor(target).clear(); - getRefsFor(target).clear(); + clearLookupFor(target); + clearRefsFor(target); } exports.clear = clear; diff --git a/toolkit/content/aboutwebrtc/aboutWebrtc.css b/toolkit/content/aboutwebrtc/aboutWebrtc.css index b4c99a1313..b9021dde6f 100644 --- a/toolkit/content/aboutwebrtc/aboutWebrtc.css +++ b/toolkit/content/aboutwebrtc/aboutWebrtc.css @@ -33,7 +33,7 @@ html { margin-bottom: 2px; } -#content { +#content > div { padding: 1em 2em; margin: 1em 0; border: 1px solid #afaca9; @@ -41,14 +41,19 @@ html { background: none repeat scroll 0% 0% #fff; } -.peer-connection > h3, -.log > h3 { - background-color: #ddd; +.section-heading * +{ + display: inline-block; } -.peer-connection section { - border: 1px solid #afaca9; - padding: 10px; +.section-heading > button { + margin-left: 1em; + margin-right: 1em; +} + +.peer-connection > h3 +{ + background-color: #ddd; } .peer-connection table { diff --git a/toolkit/content/aboutwebrtc/aboutWebrtc.html b/toolkit/content/aboutwebrtc/aboutWebrtc.html new file mode 100644 index 0000000000..42cda348ef --- /dev/null +++ b/toolkit/content/aboutwebrtc/aboutWebrtc.html @@ -0,0 +1,21 @@ + + + + + + + + about:webrtc + + + + +
+
+ + diff --git a/toolkit/content/aboutwebrtc/aboutWebrtc.js b/toolkit/content/aboutwebrtc/aboutWebrtc.js index 3bf4c43cae..9a6df9549d 100644 --- a/toolkit/content/aboutwebrtc/aboutWebrtc.js +++ b/toolkit/content/aboutwebrtc/aboutWebrtc.js @@ -24,13 +24,20 @@ const formatString = strings.formatStringFromName; const LOGFILE_NAME_DEFAULT = "aboutWebrtc.html"; const WEBRTC_TRACE_ALL = 65535; -var reportsRetrieved = new Promise(resolve => - WebrtcGlobalInformation.getAllStats(stats => resolve(stats)) -); +function getStats() { + return new Promise(resolve => + WebrtcGlobalInformation.getAllStats(stats => resolve(stats))); +} -var logRetrieved = new Promise(resolve => - WebrtcGlobalInformation.getLogging("", log => resolve(log)) -); +function getLog() { + return new Promise(resolve => + WebrtcGlobalInformation.getLogging("", log => resolve(log))); +} + +// Begin initial data queries as page loads. Store returned Promises for +// later use. +var reportsRetrieved = getStats(); +var logRetrieved = getLog(); function onLoad() { document.title = getString("document_title"); @@ -43,23 +50,33 @@ function onLoad() { controls.appendChild(set); } - let content = document.querySelector("#content"); - if (!content) { + let contentElem = document.querySelector("#content"); + if (!contentElem) { return; } + let contentInit = function(data) { + AboutWebRTC.init(onClearStats, onClearLog); + AboutWebRTC.render(contentElem, data); + }; + Promise.all([reportsRetrieved, logRetrieved]) - .then(([stats, log]) => { - AboutWebRTC.init(stats.reports, log); - content.appendChild(AboutWebRTC.render()); - }).catch(error => { - let msg = document.createElement("h3"); - msg.textContent = getString("cannot_retrieve_log"); - content.appendChild(msg); - msg = document.createElement("p"); - msg.innerHTML = `${error.name}: ${error.message}`; - content.appendChild(msg); - }); + .then(([stats, log]) => contentInit({reports: stats.reports, log: log})) + .catch(error => contentInit({error: error})); +} + +function onClearLog() { + WebrtcGlobalInformation.clearLogging(); + getLog() + .then(log => AboutWebRTC.refresh({log: log})) + .catch(error => AboutWebRTC.refresh({logError: error})); +} + +function onClearStats() { + WebrtcGlobalInformation.clearAllStats(); + getStats() + .then(stats => AboutWebRTC.refresh({reports: stats.reports})) + .catch(error => AboutWebRTC.refresh({reportError: error})); } var ControlSet = { @@ -277,20 +294,71 @@ var AboutWebRTC = { _reports: [], _log: [], - init: function(reports, log) { - this._reports = reports || []; - this._log = log || []; + init: function(onClearStats, onClearLog) { + this._onClearStats = onClearStats; + this._onClearLog = onClearLog; }, - render: function() { - let content = document.createDocumentFragment(); - content.appendChild(this.renderPeerConnections()); - content.appendChild(this.renderConnectionLog()); - return content; + render: function(parent, data) { + this._content = parent; + this._setData(data); + + if (data.error) { + let msg = document.createElement("h3"); + msg.textContent = getString("cannot_retrieve_log"); + parent.appendChild(msg); + msg = document.createElement("p"); + msg.innerHTML = `${data.error.name}: ${data.error.message}`; + parent.appendChild(msg); + return; + } + + this._peerConnections = this.renderPeerConnections(); + this._connectionLog = this.renderConnectionLog(); + this._content.appendChild(this._peerConnections); + this._content.appendChild(this._connectionLog); + }, + + _setData: function(data) { + if (data.reports) { + this._reports = data.reports; + } + + if (data.log) { + this._log = data.log; + } + }, + + refresh: function(data) { + this._setData(data); + let pc = this._peerConnections; + this._peerConnections = this.renderPeerConnections(); + let log = this._connectionLog; + this._connectionLog = this.renderConnectionLog(); + this._content.replaceChild(this._peerConnections, pc); + this._content.replaceChild(this._connectionLog, log); }, renderPeerConnections: function() { - let connections = document.createDocumentFragment(); + let connections = document.createElement("div"); + connections.className = "stats"; + + let heading = document.createElement("span"); + heading.className = "section-heading"; + let elem = document.createElement("h3"); + elem.textContent = getString("stats_heading"); + heading.appendChild(elem); + + elem = document.createElement("button"); + elem.textContent = "Clear History"; + elem.className = "no-print"; + elem.onclick = this._onClearStats; + heading.appendChild(elem); + connections.appendChild(heading); + + if (!this._reports || !this._reports.length) { + return connections; + } let reports = [...this._reports]; reports.sort((a, b) => b.timestamp - a.timestamp); @@ -306,13 +374,21 @@ var AboutWebRTC = { let content = document.createElement("div"); content.className = "log"; - if (!this._log.length) { - return content; - } - + let heading = document.createElement("span"); + heading.className = "section-heading"; let elem = document.createElement("h3"); elem.textContent = getString("log_heading"); - content.appendChild(elem); + heading.appendChild(elem); + elem = document.createElement("button"); + elem.textContent = "Clear Log"; + elem.className = "no-print"; + elem.onclick = this._onClearLog; + heading.appendChild(elem); + content.appendChild(heading); + + if (!this._log || !this._log.length) { + return content; + } let div = document.createElement("div"); let sectionCtrl = document.createElement("div"); diff --git a/toolkit/content/aboutwebrtc/aboutWebrtc.xhtml b/toolkit/content/aboutwebrtc/aboutWebrtc.xhtml deleted file mode 100644 index d6077ce9f8..0000000000 --- a/toolkit/content/aboutwebrtc/aboutWebrtc.xhtml +++ /dev/null @@ -1,24 +0,0 @@ - - - - %htmlDTD; -]> - - - - about:webrtc - - - - - -
-
- - diff --git a/toolkit/content/jar.mn b/toolkit/content/jar.mn index 97c66a994c..65c5533112 100644 --- a/toolkit/content/jar.mn +++ b/toolkit/content/jar.mn @@ -27,7 +27,7 @@ toolkit.jar: content/global/aboutServiceWorkers.xhtml content/global/aboutwebrtc/aboutWebrtc.css (aboutwebrtc/aboutWebrtc.css) content/global/aboutwebrtc/aboutWebrtc.js (aboutwebrtc/aboutWebrtc.js) - content/global/aboutwebrtc/aboutWebrtc.xhtml (aboutwebrtc/aboutWebrtc.xhtml) + content/global/aboutwebrtc/aboutWebrtc.html (aboutwebrtc/aboutWebrtc.html) * content/global/aboutSupport.js * content/global/aboutSupport.xhtml * content/global/aboutTelemetry.js diff --git a/toolkit/devtools/debugger/utils.js b/toolkit/devtools/debugger/utils.js index 12238f02b3..5cf1dbd1ba 100644 --- a/toolkit/devtools/debugger/utils.js +++ b/toolkit/devtools/debugger/utils.js @@ -106,7 +106,7 @@ const SourceUtils = { clearCache: function() { this._labelsCache.clear(); this._groupsCache.clear(); - this._minifiedCache.clear(); + this._minifiedCache = new WeakMap(); }, /** diff --git a/toolkit/devtools/server/PHeapSnapshotTempFileHelper.ipdl b/toolkit/devtools/server/PHeapSnapshotTempFileHelper.ipdl index 4f7ad103e7..2576470e25 100644 --- a/toolkit/devtools/server/PHeapSnapshotTempFileHelper.ipdl +++ b/toolkit/devtools/server/PHeapSnapshotTempFileHelper.ipdl @@ -28,7 +28,7 @@ sync protocol PHeapSnapshotTempFileHelper parent: sync OpenHeapSnapshotTempFile() returns (OpenHeapSnapshotTempFileResponse response); - __delete__(); + async __delete__(); }; } // namespace devtools diff --git a/toolkit/devtools/shared/widgets/Tooltip.js b/toolkit/devtools/shared/widgets/Tooltip.js index 76c1cf7264..abd08d97f1 100644 --- a/toolkit/devtools/shared/widgets/Tooltip.js +++ b/toolkit/devtools/shared/widgets/Tooltip.js @@ -1452,7 +1452,6 @@ EventTooltip.prototype = { editor.destroy(); } - this._tooltip.eventEditors.clear(); this._tooltip.eventEditors = null; } diff --git a/toolkit/devtools/shared/widgets/VariablesView.jsm b/toolkit/devtools/shared/widgets/VariablesView.jsm index 4a3243c799..c2f83c09ad 100644 --- a/toolkit/devtools/shared/widgets/VariablesView.jsm +++ b/toolkit/devtools/shared/widgets/VariablesView.jsm @@ -157,7 +157,7 @@ VariablesView.prototype = { } this._store.length = 0; - this._itemsByElement.clear(); + this._itemsByElement = new WeakMap(); this._prevHierarchy = this._currHierarchy; this._currHierarchy = new Map(); // Don't clear, this is just simple swapping. diff --git a/toolkit/locales/en-US/chrome/global/aboutWebrtc.properties b/toolkit/locales/en-US/chrome/global/aboutWebrtc.properties index 444d704956..8ca93661fb 100644 --- a/toolkit/locales/en-US/chrome/global/aboutWebrtc.properties +++ b/toolkit/locales/en-US/chrome/global/aboutWebrtc.properties @@ -96,6 +96,7 @@ save_page_label = Save Page debug_mode_msg_label = Debug Mode debug_mode_off_state_label = Start Debug Mode debug_mode_on_state_label = Stop Debug Mode +stats_heading = Session Statistics log_heading = Connection Log log_show_msg = show log log_hide_msg = hide log diff --git a/uriloader/exthandler/PExternalHelperApp.ipdl b/uriloader/exthandler/PExternalHelperApp.ipdl index 914b7cc2dd..c7d526c19d 100644 --- a/uriloader/exthandler/PExternalHelperApp.ipdl +++ b/uriloader/exthandler/PExternalHelperApp.ipdl @@ -13,15 +13,15 @@ protocol PExternalHelperApp manager PContent; parent: - OnStartRequest(nsCString entityID); - OnDataAvailable(nsCString data, uint64_t offset, uint32_t count); - OnStopRequest(nsresult code); + async OnStartRequest(nsCString entityID); + async OnDataAvailable(nsCString data, uint64_t offset, uint32_t count); + async OnStopRequest(nsresult code); - DivertToParentUsing(PChannelDiverter diverter); + async DivertToParentUsing(PChannelDiverter diverter); child: - Cancel(nsresult aStatus); - __delete__(); + async Cancel(nsresult aStatus); + async __delete__(); }; diff --git a/uriloader/exthandler/PHandlerService.ipdl b/uriloader/exthandler/PHandlerService.ipdl index 7e5cff0faa..bcaab60ac3 100644 --- a/uriloader/exthandler/PHandlerService.ipdl +++ b/uriloader/exthandler/PHandlerService.ipdl @@ -34,7 +34,7 @@ parent: returns (bool exists); sync GetTypeFromExtension(nsCString aFileExtension) returns (nsCString type); - __delete__(); + async __delete__(); }; diff --git a/uriloader/prefetch/POfflineCacheUpdate.ipdl b/uriloader/prefetch/POfflineCacheUpdate.ipdl index d063ac2b0a..e624752522 100644 --- a/uriloader/prefetch/POfflineCacheUpdate.ipdl +++ b/uriloader/prefetch/POfflineCacheUpdate.ipdl @@ -16,12 +16,12 @@ protocol POfflineCacheUpdate manager PContent; parent: - __delete__(); + async __delete__(); child: - NotifyStateEvent(uint32_t stateEvent, uint64_t byteProgress); - AssociateDocuments(nsCString cacheGroupId, nsCString cacheClientId); - Finish(bool succeeded, bool isUpgrade); + async NotifyStateEvent(uint32_t stateEvent, uint64_t byteProgress); + async AssociateDocuments(nsCString cacheGroupId, nsCString cacheClientId); + async Finish(bool succeeded, bool isUpgrade); }; } diff --git a/widget/cocoa/nsNativeThemeCocoa.mm b/widget/cocoa/nsNativeThemeCocoa.mm index 7aada5c607..ba29a166b1 100644 --- a/widget/cocoa/nsNativeThemeCocoa.mm +++ b/widget/cocoa/nsNativeThemeCocoa.mm @@ -2087,10 +2087,7 @@ nsNativeThemeCocoa::GetScrollbarPressStates(nsIFrame* aFrame, }; // Get the state of any scrollbar buttons in our child frames - for (nsIFrame *childFrame = aFrame->GetFirstPrincipalChild(); - childFrame; - childFrame = childFrame->GetNextSibling()) { - + for (nsIFrame *childFrame : aFrame->PrincipalChildList()) { nsIContent *childContent = childFrame->GetContent(); if (!childContent) continue; int32_t attrIndex = childContent->FindAttrValueIn(kNameSpaceID_None, nsGkAtoms::sbattr, diff --git a/widget/gtk/nsWindow.h b/widget/gtk/nsWindow.h index a772a4380f..724fb2852a 100644 --- a/widget/gtk/nsWindow.h +++ b/widget/gtk/nsWindow.h @@ -8,8 +8,6 @@ #ifndef __nsWindow_h__ #define __nsWindow_h__ -#include "mozilla/ipc/SharedMemorySysV.h" - #include "nsAutoPtr.h" #include "mozcontainer.h" @@ -27,6 +25,8 @@ #include #endif /* MOZ_X11 */ +#include "nsShmImage.h" + #ifdef ACCESSIBILITY #include "mozilla/a11y/Accessible.h" #endif @@ -64,10 +64,6 @@ extern PRLogModuleInfo *gWidgetDrawLog; class gfxASurface; class gfxPattern; class nsPluginNativeWindowGtk; -#if defined(MOZ_X11) && defined(MOZ_HAVE_SHAREDMEMORYSYSV) -# define MOZ_HAVE_SHMIMAGE -class nsShmImage; -#endif namespace mozilla { class TimeStamp; diff --git a/widget/nsNativeTheme.cpp b/widget/nsNativeTheme.cpp index e8502e4c1e..b8b2667d92 100644 --- a/widget/nsNativeTheme.cpp +++ b/widget/nsNativeTheme.cpp @@ -486,12 +486,10 @@ nsNativeTheme::IsFirstTab(nsIFrame* aFrame) if (!aFrame) return false; - nsIFrame* first = aFrame->GetParent()->GetFirstPrincipalChild(); - while (first) { + for (nsIFrame* first : aFrame->GetParent()->PrincipalChildList()) { if (first->GetRect().width > 0 && first->GetContent()->IsXULElement(nsGkAtoms::tab)) return (first == aFrame); - first = first->GetNextSibling(); } return false; } @@ -518,7 +516,7 @@ nsNativeTheme::IsNextToSelectedTab(nsIFrame* aFrame, int32_t aOffset) int32_t thisTabIndex = -1, selectedTabIndex = -1; - nsIFrame* currentTab = aFrame->GetParent()->GetFirstPrincipalChild(); + nsIFrame* currentTab = aFrame->GetParent()->PrincipalChildList().FirstChild(); for (int32_t i = 0; currentTab; currentTab = currentTab->GetNextSibling()) { if (currentTab->GetRect().width == 0) continue; diff --git a/widget/nsShmImage.cpp b/widget/nsShmImage.cpp index 87465fa372..47e91cf27a 100644 --- a/widget/nsShmImage.cpp +++ b/widget/nsShmImage.cpp @@ -17,6 +17,14 @@ #endif #ifdef MOZ_HAVE_SHMIMAGE +#include "mozilla/X11Util.h" + +#include "mozilla/ipc/SharedMemory.h" + +#include +#include +#include +#include using namespace mozilla::ipc; using namespace mozilla::gfx; @@ -45,89 +53,141 @@ TrapShmError(Display* aDisplay, XErrorEvent* aEvent) } #endif -already_AddRefed -nsShmImage::Create(const LayoutDeviceIntSize& aSize, - Display* aDisplay, Visual* aVisual, unsigned int aDepth) +bool +nsShmImage::CreateShmSegment() { - RefPtr shm = new nsShmImage(); - shm->mDisplay = aDisplay; - shm->mImage = XShmCreateImage(aDisplay, aVisual, aDepth, - ZPixmap, nullptr, - &(shm->mInfo), - aSize.width, aSize.height); - if (!shm->mImage) { - return nullptr; - } + if (!mImage) { + return false; + } - size_t size = SharedMemory::PageAlignedSize( - shm->mImage->bytes_per_line * shm->mImage->height); - shm->mSegment = new SharedMemorySysV(); - if (!shm->mSegment->Create(size) || !shm->mSegment->Map(size)) { - return nullptr; - } + size_t size = SharedMemory::PageAlignedSize(mImage->bytes_per_line * mImage->height); - shm->mInfo.shmid = shm->mSegment->GetHandle(); - shm->mInfo.shmaddr = - shm->mImage->data = static_cast(shm->mSegment->memory()); - shm->mInfo.readOnly = False; + mInfo.shmid = shmget(IPC_PRIVATE, size, IPC_CREAT | 0600); + if (mInfo.shmid == -1) { + return false; + } -#if defined(MOZ_WIDGET_GTK) - gShmError = 0; - XErrorHandler previousHandler = XSetErrorHandler(TrapShmError); - Status attachOk = XShmAttach(aDisplay, &shm->mInfo); - XSync(aDisplay, False); - XSetErrorHandler(previousHandler); - if (gShmError) { - attachOk = 0; - } -#elif defined(MOZ_WIDGET_QT) - Status attachOk = XShmAttach(aDisplay, &shm->mInfo); + mInfo.shmaddr = (char *)shmat(mInfo.shmid, nullptr, 0); + if (mInfo.shmaddr == (void *)-1) { + nsPrintfCString warning("shmat(): %s (%d)\n", strerror(errno), errno); + NS_WARNING(warning.get()); + return false; + } + + // Mark the handle as deleted so that, should this process go away, the + // segment is cleaned up. + shmctl(mInfo.shmid, IPC_RMID, 0); + +#ifdef DEBUG + struct shmid_ds info; + if (shmctl(mInfo.shmid, IPC_STAT, &info) < 0) { + return false; + } + + MOZ_ASSERT(size <= info.shm_segsz, + "Segment doesn't have enough space!"); #endif - if (!attachOk) { - // Assume XShm isn't available, and don't attempt to use it - // again. - gShmAvailable = false; - return nullptr; - } + mInfo.readOnly = False; - shm->mXAttached = true; - shm->mSize = aSize; - switch (shm->mImage->depth) { - case 32: - if ((shm->mImage->red_mask == 0xff0000) && - (shm->mImage->green_mask == 0xff00) && - (shm->mImage->blue_mask == 0xff)) { - shm->mFormat = SurfaceFormat::B8G8R8A8; - break; - } - goto unsupported; - case 24: - // Only xRGB is supported. - if ((shm->mImage->red_mask == 0xff0000) && - (shm->mImage->green_mask == 0xff00) && - (shm->mImage->blue_mask == 0xff)) { - shm->mFormat = SurfaceFormat::B8G8R8X8; - break; - } - goto unsupported; - case 16: - shm->mFormat = SurfaceFormat::R5G6B5_UINT16; - break; - unsupported: - default: - NS_WARNING("Unsupported XShm Image format!"); - gShmAvailable = false; - return nullptr; + mImage->data = mInfo.shmaddr; + + return true; +} + +void +nsShmImage::DestroyShmSegment() +{ + if (mInfo.shmid != -1) { + shmdt(mInfo.shmaddr); + mInfo.shmid = -1; + } +} + +bool +nsShmImage::CreateImage(const LayoutDeviceIntSize& aSize, + Display* aDisplay, Visual* aVisual, unsigned int aDepth) +{ + mDisplay = aDisplay; + mImage = XShmCreateImage(aDisplay, aVisual, aDepth, + ZPixmap, nullptr, + &mInfo, + aSize.width, aSize.height); + if (!mImage || !CreateShmSegment()) { + return false; + } + +#if defined(MOZ_WIDGET_GTK) + gShmError = 0; + XErrorHandler previousHandler = XSetErrorHandler(TrapShmError); + Status attachOk = XShmAttach(aDisplay, &mInfo); + XSync(aDisplay, False); + XSetErrorHandler(previousHandler); + if (gShmError) { + attachOk = 0; + } +#elif defined(MOZ_WIDGET_QT) + Status attachOk = XShmAttach(aDisplay, &mInfo); +#endif + + if (!attachOk) { + // Assume XShm isn't available, and don't attempt to use it + // again. + gShmAvailable = false; + return false; + } + + mXAttached = true; + mSize = aSize; + mFormat = SurfaceFormat::UNKNOWN; + switch (mImage->depth) { + case 32: + if ((mImage->red_mask == 0xff0000) && + (mImage->green_mask == 0xff00) && + (mImage->blue_mask == 0xff)) { + mFormat = SurfaceFormat::B8G8R8A8; } - return shm.forget(); + break; + case 24: + // Only support the BGRX layout, and report it as BGRA to the compositor. + // The alpha channel will be discarded when we put the image. + if ((mImage->red_mask == 0xff0000) && + (mImage->green_mask == 0xff00) && + (mImage->blue_mask == 0xff)) { + mFormat = SurfaceFormat::B8G8R8A8; + } + break; + case 16: + mFormat = SurfaceFormat::R5G6B5_UINT16; + break; + } + + if (mFormat == SurfaceFormat::UNKNOWN) { + NS_WARNING("Unsupported XShm Image format!"); + gShmAvailable = false; + return false; + } + + return true; +} + +nsShmImage::~nsShmImage() +{ + if (mImage) { + mozilla::FinishX(mDisplay); + if (mXAttached) { + XShmDetach(mDisplay, &mInfo); + } + XDestroyImage(mImage); + } + DestroyShmSegment(); } already_AddRefed nsShmImage::CreateDrawTarget() { return gfxPlatform::GetPlatform()->CreateDrawTargetForData( - static_cast(mSegment->memory()), + reinterpret_cast(mImage->data), mSize.ToUnknownSize(), mImage->bytes_per_line, mFormat); @@ -186,15 +246,18 @@ nsShmImage::EnsureShmImage(const LayoutDeviceIntSize& aSize, Display* aDisplay, Visual* aVisual, unsigned int aDepth, RefPtr& aImage) { - if (!aImage || aImage->Size() != aSize) { - // Because we XSync() after XShmAttach() to trap errors, we - // know that the X server has the old image's memory mapped - // into its address space, so it's OK to destroy the old image - // here even if there are outstanding Puts. The Detach is - // ordered after the Puts. - aImage = nsShmImage::Create(aSize, aDisplay, aVisual, aDepth); + if (!aImage || aImage->Size() != aSize) { + // Because we XSync() after XShmAttach() to trap errors, we + // know that the X server has the old image's memory mapped + // into its address space, so it's OK to destroy the old image + // here even if there are outstanding Puts. The Detach is + // ordered after the Puts. + aImage = new nsShmImage; + if (!aImage->CreateImage(aSize, aDisplay, aVisual, aDepth)) { + aImage = nullptr; } - return !aImage ? nullptr : aImage->CreateDrawTarget(); + } + return !aImage ? nullptr : aImage->CreateDrawTarget(); } -#endif // defined(MOZ_X11) && defined(MOZ_HAVE_SHAREDMEMORYSYSV) +#endif // MOZ_HAVE_SHMIMAGE diff --git a/widget/nsShmImage.h b/widget/nsShmImage.h index a0cd94a22e..27c9d23f55 100644 --- a/widget/nsShmImage.h +++ b/widget/nsShmImage.h @@ -7,9 +7,7 @@ #ifndef __mozilla_widget_nsShmImage_h__ #define __mozilla_widget_nsShmImage_h__ -#include "mozilla/ipc/SharedMemorySysV.h" - -#if defined(MOZ_X11) && defined(MOZ_HAVE_SHAREDMEMORYSYSV) +#if defined(MOZ_X11) # define MOZ_HAVE_SHMIMAGE #endif @@ -19,9 +17,7 @@ #include "nsIWidget.h" #include "nsAutoPtr.h" -#include "mozilla/X11Util.h" #include -#include #include #ifdef MOZ_WIDGET_QT @@ -33,30 +29,13 @@ class nsShmImage { // bug 1168843, compositor thread may create shared memory instances that are destroyed by main thread on shutdown, so this must use thread-safe RC to avoid hitting assertion NS_INLINE_DECL_THREADSAFE_REFCOUNTING(nsShmImage) - typedef mozilla::ipc::SharedMemorySysV SharedMemorySysV; - public: static bool UseShm(); - static already_AddRefed - Create(const mozilla::LayoutDeviceIntSize& aSize, - Display* aDisplay, Visual* aVisual, unsigned int aDepth); static already_AddRefed EnsureShmImage(const mozilla::LayoutDeviceIntSize& aSize, Display* aDisplay, Visual* aVisual, unsigned int aDepth, RefPtr& aImage); -private: - ~nsShmImage() { - if (mImage) { - mozilla::FinishX(mDisplay); - if (mXAttached) { - XShmDetach(mDisplay, &mInfo); - } - XDestroyImage(mImage); - } - } - -public: already_AddRefed CreateDrawTarget(); #ifdef MOZ_WIDGET_GTK @@ -74,9 +53,16 @@ private: , mDisplay(nullptr) , mFormat(mozilla::gfx::SurfaceFormat::UNKNOWN) , mXAttached(false) - { mInfo.shmid = SharedMemorySysV::NULLHandle(); } + { mInfo.shmid = -1; } + + ~nsShmImage(); + + bool CreateShmSegment(); + void DestroyShmSegment(); + + bool CreateImage(const mozilla::LayoutDeviceIntSize& aSize, + Display* aDisplay, Visual* aVisual, unsigned int aDepth); - RefPtr mSegment; XImage* mImage; Display* mDisplay; XShmSegmentInfo mInfo;