Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Handle focusability for plugin elements which has browsing context
https://bugs.webkit.org/show_bug.cgi?id=259420

Reviewed by Ryosuke Niwa.

This patch aligns WebKit with Blink / Chromium.

Merge: https://chromium.googlesource.com/chromium/src.git/+/a2c82afad86cf4f85f91df76f858434b15fe6b13

If `object` or `embed` has HTML/SVG contents,
focus navigation within documents under these
elements should work. This has been working fine
for `iframe`'s.

The FocusController code checks for FrameOwnerElement,
which is parent of `iframe`, `object`, and `embed` if
it is isKeyboardFocusable() and has contentFrame().

HTMLPluginElement::isKeyboardFocsuable() didn't handle
the cases with HTML/SVG contents, only considered plugins.

* Source/WebCore/html/HTMLPlugInElement.cpp:
(HTMLPlugInElement::isKeyboardFocusable): As above for focusability
* Source/WebCore/html/HTMLFrameOwnerElement.h: Move 'isKeyboardFocusable' from private to protected
* LayoutTests/fast/dom/focus-navigation-in-plugin.html: Add Test Case
* LayoutTests/fast/dom/resources/plugin-focus-subframe.html: Add Test Case resource
* LayoutTests/fast/dom/focus-navigation-in-plugin-expected.txt: Add Test Case Expectation
* LayoutTests/platform/ios/TestExpectations: Added test to skip on iOS since it does not support 'keyDown'

Canonical link: https://commits.webkit.org/266286@main
  • Loading branch information
Ahmad-S792 authored and Ahmad Saleem committed Jul 25, 2023
1 parent 0ddbfa3 commit 61a5480
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 3 deletions.
4 changes: 4 additions & 0 deletions LayoutTests/fast/dom/focus-navigation-in-plugin-expected.txt
@@ -0,0 +1,4 @@


PASS Focus should navigate to <object>/<embed>

39 changes: 39 additions & 0 deletions LayoutTests/fast/dom/focus-navigation-in-plugin.html
@@ -0,0 +1,39 @@
<!DOCTYPE html>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<input id="outer-before">
<object data="resources/plugin-focus-subframe.html" type="text/html" id="obj"></object>
<embed src="resources/plugin-focus-subframe.html" type="text/html" id="emb"></embed>
<input id="outer-after">
<script>
function PressTab() {
eventSender.keyDown('\t');
}
function PressShiftTab() {
eventSender.keyDown('\t', ['shiftKey']);
}
function testFocusNavigation() {
test(() => {
var before = document.querySelector('#outer-before');
var after = document.querySelector('#outer-after');
before.focus();
// 'plugin-focus-subframe.html' has 2 focus areas.
var expected = ['outer-before', 'obj', 'obj', 'emb', 'emb', 'outer-after'];
var i;
for (i = 0; i < 5; ++i) {
assert_equals(document.activeElement.id, expected[i]);
PressTab();
}
assert_equals(document.activeElement, after, '#after');
expected.reverse();
for (i = 0; i < 5; ++i) {
assert_equals(document.activeElement.id, expected[i]);
PressShiftTab();
}
assert_equals(document.activeElement, before, '#before');
}, "Focus should navigate to <object>/<embed>");
}
if (window.testRunner) {
window.addEventListener('load', testFocusNavigation, false);
}
</script>
9 changes: 9 additions & 0 deletions LayoutTests/fast/dom/resources/plugin-focus-subframe.html
@@ -0,0 +1,9 @@
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<input placeholder="subframe-before">
<input placeholder="subframe-after">
</body>
</html>
1 change: 1 addition & 0 deletions LayoutTests/platform/ios/TestExpectations
Expand Up @@ -917,6 +917,7 @@ editing/selection/shrink-selection-after-shift-pagedown.html [ Skip ]
editing/spelling/spelling-changed-text.html
editing/undo/undo-deleteWord.html [ Skip ]
fast/dom/access-key-iframe.html [ Skip ]
fast/dom/focus-navigation-in-plugin.html [ Skip ]
fast/dom/fragment-activation-focuses-target.html [ Skip ]
fast/dom/hidden-iframe-no-focus.html [ Skip ]
fast/dom/horizontal-scrollbar-in-rtl.html [ Skip ]
Expand Down
4 changes: 2 additions & 2 deletions Source/WebCore/html/HTMLFrameOwnerElement.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2006-2023 Apple Inc. All rights reserved.
* Copyright (C) 2013 Google Inc. All rights reserved.
* Copyright (C) 2013-2016 Google Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
Expand Down Expand Up @@ -71,9 +71,9 @@ class HTMLFrameOwnerElement : public HTMLElement {
HTMLFrameOwnerElement(const QualifiedName& tagName, Document&, ConstructionType = CreateHTMLFrameOwnerElement);
void setSandboxFlags(SandboxFlags);
bool isProhibitedSelfReference(const URL&) const;
bool isKeyboardFocusable(KeyboardEvent*) const override;

private:
bool isKeyboardFocusable(KeyboardEvent*) const override;
bool isFrameOwnerElement() const final { return true; }

WeakPtr<Frame> m_contentFrame;
Expand Down
5 changes: 4 additions & 1 deletion Source/WebCore/html/HTMLPlugInElement.cpp
Expand Up @@ -3,6 +3,7 @@
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2000 Stefan Schimanski (1Stein@gmx.de)
* Copyright (C) 2004-2019 Apple Inc. All rights reserved.
* Copyright (C) 2016 Google Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
Expand Down Expand Up @@ -201,8 +202,10 @@ void HTMLPlugInElement::defaultEventHandler(Event& event)
HTMLFrameOwnerElement::defaultEventHandler(event);
}

bool HTMLPlugInElement::isKeyboardFocusable(KeyboardEvent*) const
bool HTMLPlugInElement::isKeyboardFocusable(KeyboardEvent* event) const
{
if (HTMLFrameOwnerElement::isKeyboardFocusable(event))
return true;
return false;
}

Expand Down

0 comments on commit 61a5480

Please sign in to comment.