<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE bugzilla SYSTEM "https://bugs.webkit.org/page.cgi?id=bugzilla.dtd">

<bugzilla version="5.0.4.1"
          urlbase="https://bugs.webkit.org/"
          
          maintainer="admin@webkit.org"
>

    <bug>
          <bug_id>248303</bug_id>
          
          <creation_ts>2022-11-24 03:11:37 -0800</creation_ts>
          <short_desc>REGRESSION (iOS 16): popstate events are not fired for swipe-back gesture</short_desc>
          <delta_ts>2024-11-03 01:44:15 -0800</delta_ts>
          <reporter_accessible>1</reporter_accessible>
          <cclist_accessible>1</cclist_accessible>
          <classification_id>1</classification_id>
          <classification>Unclassified</classification>
          <product>WebKit</product>
          <component>DOM</component>
          <version>Safari 16</version>
          <rep_platform>iPhone / iPad</rep_platform>
          <op_sys>iOS 16</op_sys>
          <bug_status>NEW</bug_status>
          <resolution></resolution>
          
          
          <bug_file_loc></bug_file_loc>
          <status_whiteboard></status_whiteboard>
          <keywords>InRadar</keywords>
          <priority>P2</priority>
          <bug_severity>Major</bug_severity>
          <target_milestone>---</target_milestone>
          
          
          <everconfirmed>1</everconfirmed>
          <reporter name="SAKUMA Ryo">r.kato</reporter>
          <assigned_to name="Nobody">webkit-unassigned</assigned_to>
          <cc>achristensen</cc>
    
    <cc>beidson</cc>
    
    <cc>cdumez</cc>
    
    <cc>madsams024</cc>
    
    <cc>mhjacobson</cc>
    
    <cc>mike</cc>
    
    <cc>pp.mizdra</cc>
    
    <cc>simon.fraser</cc>
    
    <cc>thorton</cc>
    
    <cc>webkit-bug-importer</cc>
          

      

      

      

          <comment_sort_order>oldest_to_newest</comment_sort_order>  
          <long_desc isprivate="0" >
    <commentid>1914452</commentid>
    <comment_count>0</comment_count>
    <who name="SAKUMA Ryo">r.kato</who>
    <bug_when>2022-11-24 03:11:37 -0800</bug_when>
    <thetext>My device:
- iOS: 16.1.1
- User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 16_1_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.1 Mobile/15E148 Safari/604.1

Steps to reproduce:
- Open test1.html in iOS 16.1.1 Safari
- Tap &quot;Link&quot; to be navigated to test2.html
- Do swipe-back gesture in test2.html

Actual result:
- alert(1) is not shown

Expected result:
- alert(1) should be shown

Notes:
- This issue is not occurred in iOS 15 (and earlier, maybe)
- popstate events are fired when `history.back()` (you can confirm this by a button in test2.html)</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1914453</commentid>
    <comment_count>1</comment_count>
      <attachid>463703</attachid>
    <who name="SAKUMA Ryo">r.kato</who>
    <bug_when>2022-11-24 03:12:19 -0800</bug_when>
    <thetext>Created attachment 463703
test1.html (test case)</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1914454</commentid>
    <comment_count>2</comment_count>
      <attachid>463704</attachid>
    <who name="SAKUMA Ryo">r.kato</who>
    <bug_when>2022-11-24 03:12:59 -0800</bug_when>
    <thetext>Created attachment 463704
test2.html (test case)</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1914793</commentid>
    <comment_count>3</comment_count>
    <who name="Radar WebKit Bug Importer">webkit-bug-importer</who>
    <bug_when>2022-11-26 14:47:31 -0800</bug_when>
    <thetext>&lt;rdar://problem/102683851&gt;</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1921981</commentid>
    <comment_count>4</comment_count>
    <who name="sideshowbarker">mike</who>
    <bug_when>2022-12-26 23:19:29 -0800</bug_when>
    <thetext>Also been noticed in questions at Stack Overflow https://stackoverflow.com/questions/74233075/popstate-does-not-work-since-safari-16-it-was-working-until-safari-15</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1922633</commentid>
    <comment_count>5</comment_count>
    <who name="Chris Dumez">cdumez</who>
    <bug_when>2023-01-03 09:33:11 -0800</bug_when>
    <thetext>I just tried and can reproduce on macOS too.

I see the alert when clicking the `history.back()` button but not when clicking the back button (or swiping back).

I don&apos;t have an explanation yet for the different in behavior between history.back() and navigating back via the browser UI (though I suspect this is related to some of the back/forward list hijacking prevention work we did).

What I noticed also is that our behavior seems consistent with Chrome. Therefore, if there is a bug, it is not WebKit-specific.

Firefox seems to show the alert consistently, as is expected by the Web developer.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1922635</commentid>
    <comment_count>6</comment_count>
    <who name="Chris Dumez">cdumez</who>
    <bug_when>2023-01-03 09:38:21 -0800</bug_when>
    <thetext>Oh, I just looked at the test case more closely and I understand what is happening now.

Similarly to Chrome, WebKit recently did some security hardening to prevent bad JavaScript from hijacking the back/forward list. This means that history entries added by JS (e.g. via history.pushState()) get skipped on user navigation unless they were added with a user interaction.

In your test case, test2.html calls history.pushState() without a user interaction. As a result, the created history item gets marked with a special flag. If the user swipes back or presses the back button, we will skip this &quot;dummy&quot; history item, and thus not fire a popstate event. This is new intentional behavior, which should be consistent with Blink.

If you do not want your history item to get skipped, then you need a user gesture / activation when calling history.pushState() (e.g. calling history.pushState() as a result of a button getting clicked by the user).</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1939681</commentid>
    <comment_count>7</comment_count>
    <who name="Matt Jacobson">mhjacobson</who>
    <bug_when>2023-03-08 00:06:53 -0800</bug_when>
    <thetext>Hey Chris and WebKit team,

Thanks for the explanation.  For reference, I believe that the change Chris is describing is &lt;https://bugs.webkit.org/show_bug.cgi?id=241885&gt; (&lt;https://commits.webkit.org/251783@main&gt;), plus follow-up fix in &lt;https://bugs.webkit.org/show_bug.cgi?id=242947&gt; (&lt;https://commits.webkit.org/252649@main&gt;).

Now: in my experimentation on an iPhone SE (2nd edition) running iOS 16.3.1 (20D67), the &quot;is history item added by user interaction&quot; detection is rather unpredictable when using the &quot;touchend&quot; event.  Sometimes, a history item added in a &quot;touchend&quot; listener is considered to be &quot;added by user interaction&quot;, and sometimes it isn&apos;t, with little apparent pattern.

However, looking at the WebKit source changes in the commits above, I have a hypothesis.

The core of the &quot;added by user interaction?&quot; logic is (from Document.cpp):

```
bool Document::hasRecentUserInteractionForNavigationFromJS() const
{
    if (UserGestureIndicator::processingUserGesture(this))
        return true;

    static constexpr Seconds maximumItervalForUserGestureForwarding { 10_s };
    return (MonotonicTime::now() - lastHandledUserGestureTimestamp()) &lt;= maximumItervalForUserGestureForwarding;
}
```

That is, we return true if either `processingUserGesture()` returns true or if the time returned by `lastHandledUserGestureTimestamp()` is no more than a second ago.

The return value of `lastHandledUserGestureTimestamp()` is a member updated by calls to `updateLastHandledUserGestureTimestamp()`.  Among other places, the latter is called when a `UserGestureIndicator` object is constructed and creates a new `UserGestureToken`.

Based on context clues, I suspect that `UserGestureToken` is an object that tracks the entire *lifetime* of a touch, not a single touch event.  (Here are the clues: `UserGestureToken` has `startTime` member; &quot;gesture&quot; is the term used in AppKit and UIKit to mean an entire touch-event sequence.)

This might mean that what `hasRecentUserInteractionForNavigationFromJS()` is *really* testing is whether the *beginning* of the last gesture was more than a second ago.

If that&apos;s true, then one downstream effect might be the following: attempting to add a history item in a &quot;touchend&quot; listener might succeed or not based on the duration of the entire gesture.

And in fact, that seems to be sort of what I&apos;m seeing!

I&apos;m not able to measure an exact one-second threshold (from the measurements I&apos;m able to do in JavaScript), but I definitely see that *short* gestures tend to succeed (i.e., add the history item in a way that the back button respects), and *long* gestures tend not to.

(Maybe iOS changes that one-second value to something else?  Maybe there is a race?  I&apos;m not breaking out a disassembler tonight, sorry!  But I&apos;m interested to know what&apos;s going on there.)

I&apos;ll attach a test case that I&apos;m using to demonstrate the above.  Hope this is enough to help you track down the bug.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1939682</commentid>
    <comment_count>8</comment_count>
      <attachid>465356</attachid>
    <who name="Matt Jacobson">mhjacobson</who>
    <bug_when>2023-03-08 00:08:42 -0800</bug_when>
    <thetext>Created attachment 465356
test of the duration-sensitive touchend behavior I described in my comment</thetext>
  </long_desc>
      
          <attachment
              isobsolete="0"
              ispatch="0"
              isprivate="0"
          >
            <attachid>463703</attachid>
            <date>2022-11-24 03:12:19 -0800</date>
            <delta_ts>2022-11-24 03:12:19 -0800</delta_ts>
            <desc>test1.html (test case)</desc>
            <filename>test1.html</filename>
            <type>text/html</type>
            <size>242</size>
            <attacher name="SAKUMA Ryo">r.kato</attacher>
            
              <data encoding="base64">PCFET0NUWVBFIGh0bWw+CjxodG1sIGxhbmc9ImVuIj4KICA8aGVhZD4KICAgIDxtZXRhIGNoYXJz
ZXQ9IlVURi04IiAvPgogICAgPG1ldGEgbmFtZT0idmlld3BvcnQiIGNvbnRlbnQ9IndpZHRoPWRl
dmljZS13aWR0aCwgaW5pdGlhbC1zY2FsZT0xLjAiPgogICAgPHRpdGxlPlRlc3QxPC90aXRsZT4K
ICA8L2hlYWQ+CiAgPGJvZHk+CiAgICA8YSBocmVmPSJ0ZXN0Mi5odG1sIj5MaW5rPC9hPgogIDwv
Ym9keT4KPC9odG1sPgo=
</data>

          </attachment>
          <attachment
              isobsolete="0"
              ispatch="0"
              isprivate="0"
          >
            <attachid>463704</attachid>
            <date>2022-11-24 03:12:59 -0800</date>
            <delta_ts>2022-11-24 03:12:59 -0800</delta_ts>
            <desc>test2.html (test case)</desc>
            <filename>test2.html</filename>
            <type>text/html</type>
            <size>490</size>
            <attacher name="SAKUMA Ryo">r.kato</attacher>
            
              <data encoding="base64">PCFET0NUWVBFIGh0bWw+CjxodG1sIGxhbmc9ImVuIj4KICA8aGVhZD4KICAgIDxtZXRhIGNoYXJz
ZXQ9IlVURi04IiAvPgogICAgPG1ldGEgbmFtZT0idmlld3BvcnQiIGNvbnRlbnQ9IndpZHRoPWRl
dmljZS13aWR0aCwgaW5pdGlhbC1zY2FsZT0xLjAiPgogICAgPHRpdGxlPlRlc3QyPC90aXRsZT4K
ICA8L2hlYWQ+CiAgPGJvZHk+CiAgICA8YnV0dG9uIGlkPSJidG4iPmhpc3RvcnkuYmFjaygpPC9i
dXR0b24+CiAgICA8c2NyaXB0PgogICAgICBoaXN0b3J5LnB1c2hTdGF0ZShudWxsLCBudWxsLCBu
dWxsKQoKICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoInBvcHN0YXRlIiwgXyA9PiBhbGVy
dCgxKSkKCiAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJidG4iKS5hZGRFdmVudExpc3Rl
bmVyKCJjbGljayIsIF8gPT4gewogICAgICAgIGhpc3RvcnkuYmFjaygpCiAgICAgIH0sIGZhbHNl
KQogICAgPC9zY3JpcHQ+CiAgPC9ib2R5Pgo8L2h0bWw+Cg==
</data>

          </attachment>
          <attachment
              isobsolete="0"
              ispatch="0"
              isprivate="0"
          >
            <attachid>465356</attachid>
            <date>2023-03-08 00:08:42 -0800</date>
            <delta_ts>2023-03-08 00:08:42 -0800</delta_ts>
            <desc>test of the duration-sensitive touchend behavior I described in my comment</desc>
            <filename>matt-test.html</filename>
            <type>text/html</type>
            <size>1479</size>
            <attacher name="Matt Jacobson">mhjacobson</attacher>
            
              <data encoding="base64">PCFET0NUWVBFIGh0bWw+CjxodG1sIGxhbmc9ImVuIj4KICA8aGVhZD4KICAgIDxtZXRhIGNoYXJz
ZXQ9IlVURi04IiAvPgogICAgPG1ldGEgbmFtZT0idmlld3BvcnQiIGNvbnRlbnQ9IndpZHRoPWRl
dmljZS13aWR0aCwgaW5pdGlhbC1zY2FsZT0xLjAiIC8+CiAgICA8dGl0bGU+dGVzdCBmb3Igd2Vi
a2l0IGJ1ZyAjMjQ4MzAzPC90aXRsZT4KICAgIDxzdHlsZT4KICAgICAgI2JveCB7CiAgICAgICAg
dHJhbnNpdGlvbi1wcm9wZXJ0eTogbGVmdDsKICAgICAgICB0cmFuc2l0aW9uLWR1cmF0aW9uOiAy
NTBtczsKICAgICAgICB0cmFuc2l0aW9uLXRpbWluZy1mdW5jdGlvbjogZWFzZS1pbi1vdXQ7CiAg
ICAgICAgbGVmdDogMHB4OwogICAgICAgIHBvc2l0aW9uOiByZWxhdGl2ZTsKICAgICAgfQogICAg
PC9zdHlsZT4KICA8L2hlYWQ+CiAgPGJvZHk+CiAgICA8ZGl2IGlkPSJib3giIHN0eWxlPSJ3aWR0
aDogMTAwcHg7IGhlaWdodDogMTAwcHg7IGJhY2tncm91bmQ6IGdyZWVuOyI+PC9kaXY+CiAgICA8
c2NyaXB0PgogICAgICBsZXQgc3RhcnRUaW1lID0gbnVsbCwgbGFzdFRpbWUgPSBudWxsOwogICAg
ICBsZXQgY291bnRlciA9IDA7CiAgICAgIGNvbnN0IGJveCA9IGRvY3VtZW50LmdldEVsZW1lbnRC
eUlkKCJib3giKTsKCiAgICAgIHdpbmRvdy5vbnBvcHN0YXRlID0gZnVuY3Rpb24oZSkgewogICAg
ICAgIGNvbnNvbGUubG9nKGUuc3RhdGUpOwogICAgICAgIGNvdW50ZXIgPSBlLnN0YXRlID8gZS5z
dGF0ZS5jb3VudGVyIDogMDsKICAgICAgICBib3guc3R5bGUubGVmdCA9IGAke2NvdW50ZXIgKiAx
MH1weGA7CiAgICAgIH07CgogICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCJ0b3VjaHN0
YXJ0IiwgZSA9PiB7CiAgICAgICAgbGFzdFRpbWUgPSBzdGFydFRpbWUgPSBEYXRlLm5vdygpOwog
ICAgICB9LCB7IHBhc3NpdmU6IGZhbHNlIH0pOwoKICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0
ZW5lcigidG91Y2htb3ZlIiwgZSA9PiB7CiAgICAgICAgbGFzdFRpbWUgPSBEYXRlLm5vdygpOwog
ICAgICB9LCB7IHBhc3NpdmU6IGZhbHNlIH0pOwoKICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0
ZW5lcigidG91Y2hlbmQiLCBlID0+IHsKICAgICAgICBjb25zdCBlbmRUaW1lID0gRGF0ZS5ub3co
KTsKICAgICAgICBjb3VudGVyKys7CiAgICAgICAgaGlzdG9yeS5wdXNoU3RhdGUoe2NvdW50ZXI6
IGNvdW50ZXJ9LCAiIiwgYC90ZXN0Lmh0bWwvJHtjb3VudGVyfWApOyAgICAgCiAgICAgICAgYm94
LnN0eWxlLmxlZnQgPSBgJHtjb3VudGVyICogMTB9cHhgOwoKICAgICAgICBjb25zb2xlLmxvZyhl
bmRUaW1lIC0gc3RhcnRUaW1lKTsKICAgICAgICBjb25zb2xlLmxvZyhlbmRUaW1lIC0gbGFzdFRp
bWUpOwogICAgICAgIHN0YXJ0VGltZSA9IG51bGw7CglsYXN0VGltZSA9IG51bGw7CiAgICAgIH0s
IHsgcGFzc2l2ZTogZmFsc2UgfSk7CiAgICA8L3NjcmlwdD4KICA8L2JvZHk+CjwvaHRtbD4K
</data>

          </attachment>
      

    </bug>

</bugzilla>