[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[tor-commits] [Git][tpo/applications/tor-browser][tor-browser-153.7.0esr-16.0-1] 6 commits: Bug 1991276 - Only fill based on the currently focused node r=geckoview-reviewers,owlish



Title: GitLab

ma1 pushed to branch tor-browser-153.7.0esr-16.0-1 at The Tor Project / Applications / Tor Browser

Commits:

  • 6d061535
    by Jeff Boek at 2026-11-06T13:18:14+01:00
    Bug 1991276 - Only fill based on the currently focused node r=geckoview-reviewers,owlish
    
    Differential Revision: https://phabricator.services.mozilla.com/D272949
    
  • 90a9d586
    by pollymce at 2026-11-09T08:10:18+01:00
    Bug 2074123 - show recording notification for custom tabs as well as regular tabs. r=android-reviewers,mcarare
    
    Differential Revision: https://phabricator.services.mozilla.com/D332436
    
  • e9ef14c9
    by Emilio Cobos Álvarez at 2026-11-09T08:17:50+01:00
    Bug 2077035 - Remove untested and dubious visitedWeight target radius. r=masayuki
    
    I don't think it's worth it. It's pretty dubious to favor a visited link
    in that way anyway, specially in the modern web where lots of links are
    used as buttons and so on.
    
    It's also totally untested.
    
    Differential Revision: https://phabricator.services.mozilla.com/D332153
    
  • 864b6ec4
    by Nicolas Silva at 2026-11-09T08:38:49+01:00
    Bug 2081249 - Handle empty profile shmems from child processes in nsProfiler::StartGathering. r=profiler-reviewers,canova
    
    Differential Revision: https://phabricator.services.mozilla.com/D333246
    
  • ab75d018
    by Nicolas Silva at 2026-11-09T08:39:32+01:00
    Bug 2081249 - Bound the time CanvasTranslator::CheckAndSignalWriter waits for the writer to leave the AboutToWait state. r=gfx-reviewers,gw
    
    Differential Revision: https://phabricator.services.mozilla.com/D333248
    
  • 5290963f
    by Emilio Cobos Álvarez at 2026-11-09T08:43:48+01:00
    Bug 2083733. r=arai
    
    Differential Revision: https://phabricator.services.mozilla.com/D335409
    

17 changed files:

Changes:

  • gfx/layers/ipc/CanvasTranslator.cpp
    ... ... @@ -660,6 +660,8 @@ void CanvasTranslator::BlockCanvas() {
    660 660
     }
    
    661 661
     
    
    662 662
     void CanvasTranslator::CheckAndSignalWriter() {
    
    663
    +  uint32_t spinCount = mMaxSpinCount;
    
    664
    +  TimeStamp deadline;
    
    663 665
       do {
    
    664 666
         switch (mHeader->writerState) {
    
    665 667
           case State::Processing:
    
    ... ... @@ -672,6 +674,20 @@ void CanvasTranslator::CheckAndSignalWriter() {
    672 674
             if (mIPDLClosed) {
    
    673 675
               return;
    
    674 676
             }
    
    677
    +        if (spinCount > 0) {
    
    678
    +          --spinCount;
    
    679
    +          continue;
    
    680
    +        }
    
    681
    +        // The writer only stays in this state for a few instructions, so if it
    
    682
    +        // does not move on in a reasonable time it is misbehaving.
    
    683
    +        if (deadline.IsNull()) {
    
    684
    +          deadline = TimeStamp::Now() + TimeDuration::FromSeconds(1);
    
    685
    +        } else if (TimeStamp::Now() > deadline) {
    
    686
    +          gfxCriticalNote << "CanvasTranslator writer stuck in AboutToWait";
    
    687
    +          Deactivate();
    
    688
    +          return;
    
    689
    +        }
    
    690
    +        PR_Sleep(PR_INTERVAL_NO_WAIT);
    
    675 691
             continue;
    
    676 692
           case State::Waiting:
    
    677 693
             if (mHeader->processedCount >= mHeader->writerWaitCount) {
    

  • layout/base/PositionedEventTargeting.cpp
    ... ... @@ -104,8 +104,7 @@ enum class SearchType {
    104 104
     };
    
    105 105
     
    
    106 106
     struct EventRadiusPrefs {
    
    107
    -  bool mEnabled;            // other fields are valid iff this field is true
    
    108
    -  uint32_t mVisitedWeight;  // in percent, i.e. default is 100
    
    107
    +  bool mEnabled;  // other fields are valid iff this field is true
    
    109 108
       uint32_t mRadiusTopmm;
    
    110 109
       uint32_t mRadiusRightmm;
    
    111 110
       uint32_t mRadiusBottommm;
    
    ... ... @@ -117,7 +116,6 @@ struct EventRadiusPrefs {
    117 116
       explicit EventRadiusPrefs(WidgetGUIEvent* aMouseOrTouchEvent) {
    
    118 117
         if (aMouseOrTouchEvent->mClass == eTouchEventClass) {
    
    119 118
           mEnabled = StaticPrefs::ui_touch_radius_enabled();
    
    120
    -      mVisitedWeight = StaticPrefs::ui_touch_radius_visitedWeight();
    
    121 119
           mRadiusTopmm = StaticPrefs::ui_touch_radius_topmm();
    
    122 120
           mRadiusRightmm = StaticPrefs::ui_touch_radius_rightmm();
    
    123 121
           mRadiusBottommm = StaticPrefs::ui_touch_radius_bottommm();
    
    ... ... @@ -138,7 +136,6 @@ struct EventRadiusPrefs {
    138 136
     
    
    139 137
         } else if (aMouseOrTouchEvent->mClass == eMouseEventClass) {
    
    140 138
           mEnabled = StaticPrefs::ui_mouse_radius_enabled();
    
    141
    -      mVisitedWeight = StaticPrefs::ui_mouse_radius_visitedWeight();
    
    142 139
           mRadiusTopmm = StaticPrefs::ui_mouse_radius_topmm();
    
    143 140
           mRadiusRightmm = StaticPrefs::ui_mouse_radius_rightmm();
    
    144 141
           mRadiusBottommm = StaticPrefs::ui_mouse_radius_bottommm();
    
    ... ... @@ -149,7 +146,6 @@ struct EventRadiusPrefs {
    149 146
     
    
    150 147
         } else {
    
    151 148
           mEnabled = false;
    
    152
    -      mVisitedWeight = 0;
    
    153 149
           mRadiusTopmm = 0;
    
    154 150
           mRadiusRightmm = 0;
    
    155 151
           mRadiusBottommm = 0;
    
    ... ... @@ -697,17 +693,6 @@ static nsIFrame* GetClosest(RelativeTo aRoot,
    697 693
         // distance is in appunit
    
    698 694
         double distance =
    
    699 695
             ComputeDistanceFromRegion(aPointRelativeToRootFrame, region);
    
    700
    -    nsIContent* content = f->GetContent();
    
    701
    -    // XXX Well, some users may want to tap unvisited link, however, some other
    
    702
    -    // users may not.  For example, click a link, and go back, then, want to go
    
    703
    -    // forward, but click the visited link instead. This scenario may occur if
    
    704
    -    // clicking the link is easier to do "go forward" and I think it's true for
    
    705
    -    // the most users. So, it might be better to do this.
    
    706
    -    if (content && content->IsElement() &&
    
    707
    -        content->AsElement()->State().HasState(
    
    708
    -            ElementState(ElementState::VISITED))) {
    
    709
    -      distance *= aPrefs.mVisitedWeight / 100.0;
    
    710
    -    }
    
    711 696
         // XXX When we look for a touchable or clickable target, should we give
    
    712 697
         // lower weight for clickable target?
    
    713 698
         if (distance < bestDistance) {
    

  • layout/base/tests/test_event_target_radius.html
    ... ... @@ -122,8 +122,8 @@ function startTest() {
    122 122
                                          ["ui.mouse.radius.leftmm", 12],
    
    123 123
                                          ["ui.mouse.radius.topmm", 4],
    
    124 124
                                          ["ui.mouse.radius.rightmm", 4],
    
    125
    -                                     ["ui.mouse.radius.bottommm", 4],
    
    126
    -                                     ["ui.mouse.radius.visitedweight", 50]]}, runTest);
    
    125
    +                                     ["ui.mouse.radius.bottommm", 4]
    
    126
    +                                     ]}, runTest);
    
    127 127
     }
    
    128 128
     
    
    129 129
     
    
    ... ... @@ -484,7 +484,6 @@ function test3() {
    484 484
       setShowing("t3_6", false);
    
    485 485
     
    
    486 486
       // Not yet tested:
    
    487
    -  // -- visited link weight
    
    488 487
       // -- "Closest" using Euclidean distance
    
    489 488
     
    
    490 489
     
    
    ... ... @@ -493,8 +492,8 @@ function test3() {
    493 492
                                          ["ui.touch.radius.leftmm", 12],
    
    494 493
                                          ["ui.touch.radius.topmm", 4],
    
    495 494
                                          ["ui.touch.radius.rightmm", 4],
    
    496
    -                                     ["ui.touch.radius.bottommm", 4],
    
    497
    -                                     ["ui.touch.radius.visitedweight", 50]]}, testTouchable);
    
    495
    +                                     ["ui.touch.radius.bottommm", 4]
    
    496
    +                                     ]}, testTouchable);
    
    498 497
     }
    
    499 498
     
    
    500 499
     async function testTouchable() {
    

  • layout/style/Loader.cpp
    ... ... @@ -1548,14 +1548,13 @@ Loader::Completed Loader::ParseSheet(
    1548 1548
     
    
    1549 1549
     void Loader::AddPerformanceEntryForCachedSheet(SheetLoadData& aLoadData) {
    
    1550 1550
       MOZ_ASSERT(aLoadData.mURI);
    
    1551
    -
    
    1552
    -  if (!aLoadData.mNetworkMetadata) {
    
    1551
    +  if (!mDocument || !aLoadData.mNetworkMetadata) {
    
    1553 1552
         return;
    
    1554 1553
       }
    
    1555
    -  if (!mDocument) {
    
    1554
    +  if (aLoadData.mParentData &&
    
    1555
    +      !aLoadData.mParentData->mSheet->IsOriginClean()) {
    
    1556 1556
         return;
    
    1557 1557
       }
    
    1558
    -
    
    1559 1558
       nsAutoCString name;
    
    1560 1559
       aLoadData.mURI->GetSpec(name);
    
    1561 1560
       NS_ConvertUTF8toUTF16 entryName(name);
    

  • mobile/android/android-components/components/feature/media/src/main/java/mozilla/components/feature/media/middleware/RecordingDevicesMiddleware.kt
    ... ... @@ -70,11 +70,12 @@ class RecordingDevicesMiddleware(
    70 70
             store: Store<BrowserState, BrowserAction>,
    
    71 71
             isReminder: Boolean,
    
    72 72
         ) {
    
    73
    -        val devices = store.state.tabs
    
    74
    -            .map { tab -> tab.content.recordingDevices }
    
    75
    -            .flatten()
    
    76
    -            .filter { device -> device.status == RecordingDevice.Status.RECORDING }
    
    77
    -            .distinctBy { device -> device.type }
    
    73
    +        val devices =
    
    74
    +            (store.state.tabs + store.state.customTabs)
    
    75
    +                .map { tab -> tab.content.recordingDevices }
    
    76
    +                .flatten()
    
    77
    +                .filter { device -> device.status == RecordingDevice.Status.RECORDING }
    
    78
    +                .distinctBy { device -> device.type }
    
    78 79
     
    
    79 80
             val isUsingCamera = devices.find { it.type == RecordingDevice.Type.CAMERA } != null
    
    80 81
             val isUsingMicrophone = devices.find { it.type == RecordingDevice.Type.MICROPHONE } != null
    

  • mobile/android/android-components/components/feature/media/src/test/java/mozilla/components/feature/media/middleware/RecordingDevicesMiddlewareTest.kt
    ... ... @@ -12,7 +12,9 @@ import android.content.IntentFilter
    12 12
     import androidx.core.app.NotificationManagerCompat
    
    13 13
     import androidx.test.ext.junit.runners.AndroidJUnit4
    
    14 14
     import mozilla.components.browser.state.action.ContentAction
    
    15
    +import mozilla.components.browser.state.action.CustomTabListAction
    
    15 16
     import mozilla.components.browser.state.state.BrowserState
    
    17
    +import mozilla.components.browser.state.state.createCustomTab
    
    16 18
     import mozilla.components.browser.state.state.createTab
    
    17 19
     import mozilla.components.browser.state.store.BrowserStore
    
    18 20
     import mozilla.components.concept.engine.media.RecordingDevice
    
    ... ... @@ -131,4 +133,65 @@ class RecordingDevicesMiddlewareTest {
    131 133
     
    
    132 134
             assertEquals(0, notificationManager.size())
    
    133 135
         }
    
    136
    +
    
    137
    +    @Test
    
    138
    +    fun `middleware shows notification when custom tab has a recording device then hides when recording devices become inactive`() {
    
    139
    +        val realNotificationManager = testContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
    
    140
    +        val notificationManager = Shadows.shadowOf(realNotificationManager)
    
    141
    +
    
    142
    +        val middleware = RecordingDevicesMiddleware(testContext, notificationsDelegate)
    
    143
    +        val store =
    
    144
    +            BrowserStore(
    
    145
    +                initialState =
    
    146
    +                    BrowserState(customTabs = listOf(createCustomTab("https://www.mozilla.org", id = "mozilla"))),
    
    147
    +                middleware = listOf(middleware),
    
    148
    +            )
    
    149
    +
    
    150
    +        assertEquals(0, notificationManager.size())
    
    151
    +
    
    152
    +        store.dispatch(
    
    153
    +            ContentAction.SetRecordingDevices(
    
    154
    +                sessionId = "mozilla",
    
    155
    +                devices = listOf(RecordingDevice(RecordingDevice.Type.MICROPHONE, RecordingDevice.Status.RECORDING)),
    
    156
    +            )
    
    157
    +        )
    
    158
    +
    
    159
    +        assertEquals(1, notificationManager.size())
    
    160
    +
    
    161
    +        store.dispatch(
    
    162
    +            ContentAction.SetRecordingDevices(
    
    163
    +                sessionId = "mozilla",
    
    164
    +                devices = emptyList(),
    
    165
    +            )
    
    166
    +        )
    
    167
    +
    
    168
    +        assertEquals(0, notificationManager.size())
    
    169
    +    }
    
    170
    +
    
    171
    +    @Test
    
    172
    +    fun `middleware hides notification when a recording custom tab is removed`() {
    
    173
    +        val realNotificationManager = testContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
    
    174
    +        val notificationManager = Shadows.shadowOf(realNotificationManager)
    
    175
    +
    
    176
    +        val middleware = RecordingDevicesMiddleware(testContext, notificationsDelegate)
    
    177
    +        val store =
    
    178
    +            BrowserStore(
    
    179
    +                initialState =
    
    180
    +                    BrowserState(customTabs = listOf(createCustomTab("https://www.mozilla.org", id = "mozilla"))),
    
    181
    +                middleware = listOf(middleware),
    
    182
    +            )
    
    183
    +
    
    184
    +        store.dispatch(
    
    185
    +            ContentAction.SetRecordingDevices(
    
    186
    +                sessionId = "mozilla",
    
    187
    +                devices = listOf(RecordingDevice(RecordingDevice.Type.MICROPHONE, RecordingDevice.Status.RECORDING)),
    
    188
    +            )
    
    189
    +        )
    
    190
    +
    
    191
    +        assertEquals(1, notificationManager.size())
    
    192
    +
    
    193
    +        store.dispatch(CustomTabListAction.RemoveCustomTabAction(tabId = "mozilla"))
    
    194
    +
    
    195
    +        assertEquals(0, notificationManager.size())
    
    196
    +    }
    
    134 197
     }

  • mobile/android/geckoview/src/androidTest/assets/www/forms_iframe.html
    ... ... @@ -52,6 +52,10 @@
    52 52
     
    
    53 53
         window.addEventListener("message", async event => {
    
    54 54
           const { data, source, origin } = event;
    
    55
    +      if (data.type == "getValue") {
    
    56
    +        source.postMessage(document.querySelector(data.key).value, origin);
    
    57
    +        return;
    
    58
    +      }
    
    55 59
           source.postMessage(await getData(data.key, data.value), origin);
    
    56 60
         });
    
    57 61
       </script>
    

  • mobile/android/geckoview/src/androidTest/assets/www/forms_xorigin.html
    ... ... @@ -73,5 +73,15 @@
    73 73
           data.push(getData(key, value));
    
    74 74
           return Promise.all(data);
    
    75 75
         };
    
    76
    +
    
    77
    +    window.getIframeValue = function (key) {
    
    78
    +      const value = new Promise(resolve =>
    
    79
    +        window.addEventListener("message", event => resolve(event.data), {
    
    80
    +          once: true,
    
    81
    +        })
    
    82
    +      );
    
    83
    +      iframe.postMessage({ type: "getValue", key }, "*");
    
    84
    +      return value;
    
    85
    +    };
    
    76 86
       </script>
    
    77 87
     </html>

  • mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/GeckoViewTest.kt
    ... ... @@ -336,21 +336,24 @@ class GeckoViewTest : BaseSessionTest() {
    336 336
             val autofills =
    
    337 337
                 mapOf(
    
    338 338
                     "#user1" to "username@xxxxxxxxxxx",
    
    339
    -                "#user2" to "username@xxxxxxxxxxx",
    
    340 339
                     "#pass1" to "test-password",
    
    341
    -                "#pass2" to "test-password",
    
    342 340
                 )
    
    341
    +        val notFilled = listOf("#user2", "#pass2")
    
    342
    +
    
    343
    +        // Only the form containing the focused field is filled.
    
    344
    +        val promises = autofills.map { entry ->
    
    345
    +            mainSession.evaluatePromiseJS(
    
    346
    +                """
    
    347
    +                getData('${entry.key}', '${entry.value}')
    
    348
    +                """
    
    349
    +            )
    
    350
    +        }
    
    343 351
     
    
    344
    -        // Set up promises to monitor the values changing.
    
    345
    -        val promises =
    
    346
    -            autofills.map { entry ->
    
    347
    -                // Repeat each test with both the top document and the iframe document.
    
    348
    -                mainSession.evaluatePromiseJS(
    
    349
    -                    """
    
    350
    -                window.getDataForAllFrames('${entry.key}', '${entry.value}')
    
    351
    -                """,
    
    352
    -                )
    
    353
    -            }
    
    352
    +        mainSession.evaluateJS("document.querySelector('#user1').focus()")
    
    353
    +        UiThreadUtils.waitForCondition(
    
    354
    +            { mainSession.autofillSession.focused != null },
    
    355
    +            env.defaultTimeoutMillis,
    
    356
    +        )
    
    354 357
     
    
    355 358
             activityRule.scenario.onActivity {
    
    356 359
                 val root = MockViewStructure(View.NO_ID)
    
    ... ... @@ -374,19 +377,33 @@ class GeckoViewTest : BaseSessionTest() {
    374 377
                 it.view.setSession(session)
    
    375 378
     
    
    376 379
                 // Wait on the promises and check for correct values.
    
    377
    -            for (values in promises.map { p -> p.value.asJsonArray() }) {
    
    378
    -                for (i in 0 until values.length()) {
    
    379
    -                    val (key, actual, expected, eventInterface) = values.get(i).asJSList<String>()
    
    380
    -
    
    381
    -                    assertThat("Auto-filled value must match ($key)", actual, equalTo(expected))
    
    382
    -                    assertThat(
    
    383
    -                        "input event should be dispatched with InputEvent interface",
    
    384
    -                        eventInterface,
    
    385
    -                        equalTo("InputEvent"),
    
    386
    -                    )
    
    387
    -                }
    
    380
    +            for (values in promises.map { p -> p.value.asJSList<String>() }) {
    
    381
    +                val (key, actual, expected, eventInterface) = values
    
    382
    +
    
    383
    +                assertThat("Auto-filled value must match ($key)", actual, equalTo(expected))
    
    384
    +                assertThat(
    
    385
    +                    "input event should be dispatched with InputEvent interface",
    
    386
    +                    eventInterface,
    
    387
    +                    equalTo("InputEvent"),
    
    388
    +                )
    
    388 389
                 }
    
    389 390
             }
    
    391
    +
    
    392
    +        for (key in autofills.keys + notFilled) {
    
    393
    +            assertThat(
    
    394
    +                "Field in the unfocused iframe must not be filled ($key)",
    
    395
    +                mainSession.evaluatePromiseJS("window.getIframeValue('$key')").value as String,
    
    396
    +                equalTo("foo"),
    
    397
    +            )
    
    398
    +        }
    
    399
    +
    
    400
    +        for (key in notFilled) {
    
    401
    +            assertThat(
    
    402
    +                "Field outside the focused form must not be filled ($key)",
    
    403
    +                mainSession.evaluateJS("document.querySelector('$key').value") as String,
    
    404
    +                equalTo("foo"),
    
    405
    +            )
    
    406
    +        }
    
    390 407
         }
    
    391 408
     
    
    392 409
         @Test
    

  • mobile/android/geckoview/src/main/java/org/mozilla/geckoview/Autofill.java
    ... ... @@ -466,7 +466,9 @@ public class Autofill {
    466 466
         public void fillViewStructure(
    
    467 467
             @NonNull final View view, @NonNull final ViewStructure structure, final int flags) {
    
    468 468
           ThreadUtils.assertOnUiThread();
    
    469
    -      fillViewStructure(getRoot(), view, structure, flags);
    
    469
    +      final Node focused = getFocused();
    
    470
    +      final Node root = focused != null ? focused.getRoot() : null;
    
    471
    +      fillViewStructure(root != null ? root : getRoot(), view, structure, flags);
    
    470 472
         }
    
    471 473
     
    
    472 474
         /**
    

  • modules/libpref/init/StaticPrefList.yaml
    ... ... @@ -19594,10 +19594,6 @@
    19594 19594
     # dispatched to nearby elements that are sensitive to the event. See
    
    19595 19595
     # PositionedEventTargeting.cpp. The 'mm' prefs define a rectangle around the
    
    19596 19596
     # nominal event target point within which we will search for suitable elements.
    
    19597
    -# 'visitedWeight' is a percentage weight; a value > 100 makes a visited link be
    
    19598
    -# treated as further away from the event target than it really is, while a
    
    19599
    -# value < 100 makes a visited link be treated as closer to the event target
    
    19600
    -# than it really is.
    
    19601 19597
     
    
    19602 19598
     - name: ui.touch.radius.enabled
    
    19603 19599
       type: bool
    
    ... ... @@ -19647,11 +19643,6 @@
    19647 19643
       value: true
    
    19648 19644
       mirror: always
    
    19649 19645
     
    
    19650
    -- name: ui.touch.radius.visitedWeight
    
    19651
    -  type: uint32_t
    
    19652
    -  value: 120
    
    19653
    -  mirror: always
    
    19654
    -
    
    19655 19646
     - name: ui.mouse.radius.enabled
    
    19656 19647
       type: bool
    
    19657 19648
       value: @IS_ANDROID@
    
    ... ... @@ -19693,11 +19684,6 @@
    19693 19684
     #endif
    
    19694 19685
       mirror: always
    
    19695 19686
     
    
    19696
    -- name: ui.mouse.radius.visitedWeight
    
    19697
    -  type: uint32_t
    
    19698
    -  value: 120
    
    19699
    -  mirror: always
    
    19700
    -
    
    19701 19687
     - name: ui.mouse.radius.reposition
    
    19702 19688
       type: bool
    
    19703 19689
       value: @IS_ANDROID@
    

  • testing/web-platform/tests/resource-timing/no-entries-for-cached-import-of-cross-origin-css.html
    1
    +<!DOCTYPE HTML>
    
    2
    +<meta charset=utf-8>
    
    3
    +<title>Resource timing entries for cached @import children of stylesheets</title>
    
    4
    +<link rel="help" href="">"https://bugzilla.mozilla.org/show_bug.cgi?id=2083733">
    
    5
    +<script src="">"/resources/testharness.js"></script>
    
    6
    +<script src="">"/resources/testharnessreport.js"></script>
    
    7
    +<script src="">"/common/get-host-info.sub.js"></script>
    
    8
    +<script src="">"/common/utils.js"></script>
    
    9
    +<body>
    
    10
    +<script>
    
    11
    +const {ORIGIN, HTTP_REMOTE_ORIGIN} = get_host_info();
    
    12
    +const RESOURCES = "/resource-timing/resources/";
    
    13
    +
    
    14
    +async function loadInFrame(t, href) {
    
    15
    +  const iframe = document.createElement("iframe");
    
    16
    +  iframe.srcdoc = `<link rel="stylesheet" href=""p">${href}">`;
    
    17
    +  await new Promise(resolve => {
    
    18
    +    iframe.onload = resolve;
    
    19
    +    document.body.appendChild(iframe);
    
    20
    +  });
    
    21
    +  t.add_cleanup(() => iframe.remove());
    
    22
    +  return iframe.contentWindow;
    
    23
    +}
    
    24
    +
    
    25
    +// The first load caches the child stylesheet, but not the parent, which is
    
    26
    +// no-store, so the second load re-parses the parent and gets the child from
    
    27
    +// the cache.
    
    28
    +async function loadTwice(t, parentOrigin, childOrigin) {
    
    29
    +  const id = token();
    
    30
    +  const child = `${childOrigin}${RESOURCES}cacheable-import-child.css?${id}`;
    
    31
    +  const parent = v =>
    
    32
    +    `${parentOrigin}${RESOURCES}no-store-importer.sub.css?import=${encodeURIComponent(child)}&v=${v}`;
    
    33
    +  await loadInFrame(t, parent(1));
    
    34
    +  const win = await loadInFrame(t, parent(2));
    
    35
    +  await new Promise(resolve => t.step_timeout(resolve, 0));
    
    36
    +  assert_equals(win.performance.getEntriesByName(parent(2)).length, 1,
    
    37
    +                "Parent stylesheet should be in the timeline");
    
    38
    +  return win.performance.getEntriesByName(child).length;
    
    39
    +}
    
    40
    +
    
    41
    +promise_test(async t => {
    
    42
    +  assert_equals(await loadTwice(t, HTTP_REMOTE_ORIGIN, HTTP_REMOTE_ORIGIN), 0);
    
    43
    +}, "Cached @import children of cross-origin stylesheets are not in the timeline");
    
    44
    +
    
    45
    +promise_test(async t => {
    
    46
    +  assert_equals(await loadTwice(t, ORIGIN, ORIGIN), 1);
    
    47
    +}, "Cached same-origin @import children of same-origin stylesheets are in the timeline");
    
    48
    +
    
    49
    +promise_test(async t => {
    
    50
    +  assert_equals(await loadTwice(t, ORIGIN, HTTP_REMOTE_ORIGIN), 1);
    
    51
    +}, "Cached cross-origin @import children of same-origin stylesheets are in the timeline");
    
    52
    +</script>
    
    53
    +</body>

  • testing/web-platform/tests/resource-timing/resources/cacheable-import-child.css
    1
    +.child { color: blue }

  • testing/web-platform/tests/resource-timing/resources/cacheable-import-child.css.headers
    1
    +Content-Type: text/css
    
    2
    +Cache-Control: max-age=600

  • testing/web-platform/tests/resource-timing/resources/no-store-importer.sub.css
    1
    +@import "{{GET[import]}}";

  • testing/web-platform/tests/resource-timing/resources/no-store-importer.sub.css.headers
    1
    +Content-Type: text/css
    
    2
    +Cache-Control: no-store

  • tools/profiler/gecko/nsProfiler.cpp
    ... ... @@ -1320,8 +1320,11 @@ RefPtr<nsProfiler::GatheringPromise> nsProfiler::StartGathering(
    1320 1320
                     aEvent.append(Json::Value::UInt64(childPid));
    
    1321 1321
                     aEvent.append(Json::Value::UInt64{profileShmem.Size<char>()});
    
    1322 1322
                   });
    
    1323
    +              const size_t profileLength =
    
    1324
    +                  profileShmem.Size<char>() > 0 ? profileShmem.Size<char>() - 1
    
    1325
    +                                                : 0;
    
    1323 1326
                   const nsDependentCSubstring profileString(
    
    1324
    -                  profileShmem.get<char>(), profileShmem.Size<char>() - 1);
    
    1327
    +                  profileShmem.get<char>(), profileLength);
    
    1325 1328
                   if (profileString.IsEmpty() || profileString[0] != '*') {
    
    1326 1329
                     self->GatheredOOPProfile(
    
    1327 1330
                         childPid, profileString,
    

  • _______________________________________________
    tor-commits mailing list -- tor-commits@xxxxxxxxxxxxxxxxxxxx
    To unsubscribe send an email to tor-commits-leave@xxxxxxxxxxxxxxxxxxxx