提交 38c8026e 编写于 作者: H Hixie

Remove focus support from sky/engine/core/*.

tabindex, :focus, actual focus support, etc.
上级 4e6b873e
......@@ -414,9 +414,6 @@ sky_core_files = [
"loader/UniqueIdentifier.cpp",
"loader/UniqueIdentifier.h",
"page/ChromeClient.h",
"page/FocusController.cpp",
"page/FocusController.h",
"page/FocusType.h",
"page/Page.cpp",
"page/Page.h",
"painting/Canvas.cpp",
......
......@@ -69,7 +69,6 @@ struct NameToPseudoStruct {
// This table should be kept sorted.
const static NameToPseudoStruct pseudoTypeMap[] = {
{"active", CSSSelector::PseudoActive},
{"focus", CSSSelector::PseudoFocus},
{"host", CSSSelector::PseudoHost},
{"host(", CSSSelector::PseudoHost},
{"hover", CSSSelector::PseudoHover},
......
......@@ -101,7 +101,7 @@ namespace blink {
Tag, // Example: div
Id, // Example: #id
Class, // example: .class
PseudoClass, // Example: :focus
PseudoClass, // Example: :hover
PseudoElement, // Example: ::first-line
Exact, // Example: E[foo="bar"]
Set, // Example: E[foo]
......@@ -112,7 +112,6 @@ namespace blink {
PseudoNotParsed = 0,
PseudoUnknown,
PseudoHover,
PseudoFocus,
PseudoActive,
PseudoLang,
PseudoHost,
......
......@@ -124,9 +124,6 @@ inline bool ElementRuleCollector::ruleMatches(const RuleData& ruleData)
if (checker.matchedAttributeSelector())
m_style->setUnique();
if (checker.matchedFocusSelector())
m_style->setAffectedByFocus();
if (checker.matchedHoverSelector())
m_style->setAffectedByHover();
......
......@@ -32,25 +32,13 @@
#include "sky/engine/core/dom/Document.h"
#include "sky/engine/core/frame/LocalFrame.h"
#include "sky/engine/core/html/parser/HTMLParserIdioms.h"
#include "sky/engine/core/page/FocusController.h"
#include "sky/engine/core/rendering/style/RenderStyle.h"
namespace blink {
static bool matchesFocusPseudoClass(const Element& element)
{
if (!element.focused())
return false;
LocalFrame* frame = element.document().frame();
if (!frame)
return false;
return true;
}
SelectorChecker::SelectorChecker(const Element& element)
: m_element(element)
, m_matchedAttributeSelector(false)
, m_matchedFocusSelector(false)
, m_matchedHoverSelector(false)
, m_matchedActiveSelector(false)
{
......@@ -122,10 +110,6 @@ bool SelectorChecker::checkOne(const CSSSelector& selector)
bool SelectorChecker::checkPseudoClass(const CSSSelector& selector)
{
switch (selector.pseudoType()) {
case CSSSelector::PseudoFocus:
m_matchedFocusSelector = true;
return matchesFocusPseudoClass(m_element);
case CSSSelector::PseudoHover:
m_matchedHoverSelector = true;
return m_element.hovered();
......
......@@ -44,7 +44,6 @@ public:
bool match(const CSSSelector&);
bool matchedAttributeSelector() const { return m_matchedAttributeSelector; }
bool matchedFocusSelector() const { return m_matchedFocusSelector; }
bool matchedHoverSelector() const { return m_matchedHoverSelector; }
bool matchedActiveSelector() const { return m_matchedActiveSelector; }
......@@ -54,7 +53,6 @@ private:
const Element& m_element;
bool m_matchedAttributeSelector;
bool m_matchedFocusSelector;
bool m_matchedHoverSelector;
bool m_matchedActiveSelector;
};
......
......@@ -134,8 +134,6 @@ PassRefPtr<Node> ContainerNode::insertBefore(PassRefPtr<Node> newChild, Node* re
if (targets.isEmpty())
return newChild;
// Must check this again beacuse focus events might run synchronously when
// removing children.
checkAcceptChildHierarchy(*newChild, 0, exceptionState);
if (exceptionState.had_exception())
return nullptr;
......@@ -252,8 +250,6 @@ PassRefPtr<Node> ContainerNode::replaceChild(PassRefPtr<Node> newChild, PassRefP
if (exceptionState.had_exception())
return nullptr;
// Must check this again beacuse focus events might run synchronously when
// removing children.
checkAcceptChildHierarchy(*newChild, child.get(),exceptionState);
if (exceptionState.had_exception())
return nullptr;
......@@ -384,10 +380,6 @@ PassRefPtr<Node> ContainerNode::removeChild(PassRefPtr<Node> oldChild, Exception
RefPtr<Node> protect(this);
RefPtr<Node> child = oldChild;
document().removeFocusedElementOfSubtree(child.get());
// Events fired when blurring currently focused node might have moved this
// child into a different parent.
if (child->parentNode() != this) {
exceptionState.ThrowDOMException(NotFoundError, "The node to be removed is no longer a child of this node. Perhaps it was moved in a 'blur' event handler?");
return nullptr;
......@@ -450,12 +442,6 @@ void ContainerNode::removeChildren()
willRemoveChildren();
{
// Exclude this node when looking for removed focusedElement since only
// children will be removed.
// This must be later than willRemoveChildren, which might change focus
// state of a child.
document().removeFocusedElementOfSubtree(this, true);
// Removing a node from a selection can cause widget updates.
document().nodeChildrenWillBeRemoved(*this);
}
......@@ -512,8 +498,6 @@ PassRefPtr<Node> ContainerNode::appendChild(PassRefPtr<Node> newChild, Exception
if (targets.isEmpty())
return newChild;
// Must check this again beacuse focus events might run synchronously when
// removing children.
checkAcceptChildHierarchy(*newChild, 0, exceptionState);
if (exceptionState.had_exception())
return nullptr;
......@@ -771,36 +755,6 @@ LayoutRect ContainerNode::boundingBox() const
return enclosingLayoutRect(FloatRect(upperLeft, lowerRight.expandedTo(upperLeft) - upperLeft));
}
// This is used by FrameSelection to denote when the active-state of the page has changed
// independent of the focused element changing.
void ContainerNode::focusStateChanged()
{
// If we're just changing the window's active state and the focused node has no
// renderer we can just ignore the state change.
if (!renderer())
return;
if (styleChangeType() < SubtreeStyleChange) {
if (renderStyle()->affectedByFocus())
setNeedsStyleRecalc(LocalStyleChange);
}
}
void ContainerNode::setFocus(bool received)
{
if (focused() == received)
return;
Node::setFocus(received);
focusStateChanged();
if (renderer() || received)
return;
setNeedsStyleRecalc(LocalStyleChange);
}
void ContainerNode::setActive(bool down)
{
if (down == active())
......
......@@ -90,8 +90,6 @@ public:
virtual void attach(const AttachContext& = AttachContext()) override;
virtual void detach(const AttachContext& = AttachContext()) override;
virtual LayoutRect boundingBox() const override final;
virtual void setFocus(bool) override;
void focusStateChanged();
virtual void setActive(bool = true) override;
virtual void setHovered(bool = true) override;
......
......@@ -73,7 +73,6 @@
#include "sky/engine/core/inspector/InspectorCounters.h"
#include "sky/engine/core/loader/FrameLoaderClient.h"
#include "sky/engine/core/page/ChromeClient.h"
#include "sky/engine/core/page/FocusController.h"
#include "sky/engine/core/page/Page.h"
#include "sky/engine/core/painting/PaintingTasks.h"
#include "sky/engine/core/painting/Picture.h"
......@@ -256,7 +255,6 @@ void Document::dispose()
// We must make sure not to be retaining any of our children through
// these extra pointers or we will create a reference cycle.
m_focusedElement = nullptr;
m_hoverNode = nullptr;
m_activeHoverElement = nullptr;
m_userActionElements.documentDidRemoveLastRef();
......@@ -771,11 +769,6 @@ void Document::updateLayout()
frameView->layout();
}
void Document::setNeedsFocusedElementCheck()
{
setNeedsStyleRecalc(LocalStyleChange);
}
StyleResolver& Document::styleResolver() const
{
ASSERT(isActive());
......@@ -811,7 +804,6 @@ void Document::detach(const AttachContext& context)
m_scriptedAnimationController.clear();
m_hoverNode = nullptr;
m_focusedElement = nullptr;
m_activeHoverElement = nullptr;
m_renderView = 0;
......@@ -1046,19 +1038,6 @@ void Document::setActiveHoverElement(PassRefPtr<Element> newActiveElement)
m_activeHoverElement = newActiveElement;
}
void Document::removeFocusedElementOfSubtree(Node* node, bool amongChildrenOnly)
{
if (!m_focusedElement)
return;
// We can't be focused if we're not in the document.
if (!node->inDocument())
return;
bool contains = node->contains(m_focusedElement.get());
if (contains && (m_focusedElement != node || !amongChildrenOnly))
setFocusedElement(nullptr);
}
void Document::hoveredNodeDetached(Node* node)
{
if (!m_hoverNode)
......@@ -1087,11 +1066,6 @@ void Document::activeChainNodeDetached(Node* node)
m_activeHoverElement = activeNode && activeNode->isElementNode() ? toElement(activeNode) : 0;
}
bool Document::setFocusedElement(PassRefPtr<Element> prpNewFocusedElement, FocusType type)
{
return false;
}
void Document::updateRangesAfterChildrenChanged(ContainerNode* container)
{
if (!m_ranges.isEmpty()) {
......@@ -1454,24 +1428,6 @@ float Document::devicePixelRatio() const
return m_frame ? m_frame->devicePixelRatio() : 1.0;
}
Element* Document::activeElement() const
{
if (Element* element = treeScope().adjustedFocusedElement())
return element;
return nullptr;
}
bool Document::hasFocus() const
{
Page* page = this->page();
if (!page)
return false;
if (!page->focusController().isActive() || !page->focusController().isFocused())
return false;
Frame* focusedFrame = page->focusController().focusedFrame();
return focusedFrame && focusedFrame == frame();
}
Picture* Document::rootPicture() const
{
return m_picture.get();
......
......@@ -38,7 +38,6 @@
#include "sky/engine/core/dom/UserActionElementSet.h"
#include "sky/engine/core/inspector/ScriptCallStack.h"
#include "sky/engine/core/loader/DocumentLoadTiming.h"
#include "sky/engine/core/page/FocusType.h"
#include "sky/engine/platform/Length.h"
#include "sky/engine/platform/heap/Handle.h"
#include "sky/engine/platform/weborigin/KURL.h"
......@@ -126,10 +125,6 @@ public:
SelectorQueryCache& selectorQueryCache();
// Focus Management.
Element* activeElement() const;
bool hasFocus() const;
AbstractModule* module() const { return m_module; }
void setModule(AbstractModule* module) { m_module = module; }
......@@ -263,16 +258,12 @@ public:
TextLinkColors& textLinkColors() { return m_textLinkColors; }
bool setFocusedElement(PassRefPtr<Element>, FocusType = FocusTypeNone);
Element* focusedElement() const { return m_focusedElement.get(); }
UserActionElementSet& userActionElements() { return m_userActionElements; }
const UserActionElementSet& userActionElements() const { return m_userActionElements; }
void setNeedsFocusedElementCheck();
void setActiveHoverElement(PassRefPtr<Element>);
Element* activeHoverElement() const { return m_activeHoverElement.get(); }
void removeFocusedElementOfSubtree(Node*, bool amongChildrenOnly = false);
void hoveredNodeDetached(Node*);
void activeChainNodeDetached(Node*);
......@@ -493,7 +484,6 @@ private:
RefPtr<CSSStyleSheet> m_elemSheet;
RefPtr<Element> m_focusedElement;
RefPtr<Node> m_hoverNode;
RefPtr<Element> m_activeHoverElement;
UserActionElementSet m_userActionElements;
......
......@@ -51,7 +51,4 @@
Range caretRangeFromPoint([Default=Undefined] optional long x,
[Default=Undefined] optional long y);
// HTML 5
readonly attribute Element activeElement;
boolean hasFocus();
};
......@@ -62,7 +62,6 @@
#include "sky/engine/core/html/parser/HTMLParserIdioms.h"
#include "sky/engine/core/layout/LayoutCallback.h"
#include "sky/engine/core/page/ChromeClient.h"
#include "sky/engine/core/page/FocusController.h"
#include "sky/engine/core/page/Page.h"
#include "sky/engine/core/painting/Canvas.h"
#include "sky/engine/core/painting/PaintingCallback.h"
......@@ -108,38 +107,6 @@ inline ElementRareData& Element::ensureElementRareData()
return static_cast<ElementRareData&>(ensureRareData());
}
void Element::setTabIndex(int value)
{
setIntegralAttribute(HTMLNames::tabindexAttr, value);
}
short Element::tabIndex() const
{
if (supportsFocus())
return hasRareData() ? elementRareData()->tabIndex() : 0;
return -1;
}
bool Element::rendererIsFocusable() const
{
// FIXME: These asserts should be in Node::isFocusable, but there are some
// callsites like Document::setFocusedElement that would currently fail on
// them. See crbug.com/251163
if (!renderer()) {
// We can't just use needsStyleRecalc() because if the node is in a
// display:none tree it might say it needs style recalc but the whole
// document is actually up to date.
ASSERT(!document().childNeedsStyleRecalc());
}
// FIXME: Even if we are not visible, we might have a child that is visible.
// Hyatt wants to fix that some day with a "has visible content" flag or the like.
if (!renderer())
return false;
return true;
}
PassRefPtr<Node> Element::cloneNode(bool deep)
{
return deep ? cloneElementWithChildren() : cloneElementWithoutChildren();
......@@ -443,8 +410,6 @@ ALWAYS_INLINE void Element::setAttributeInternal(size_t index, const QualifiedNa
void Element::attributeChanged(const QualifiedName& name, const AtomicString& newValue, AttributeModificationReason reason)
{
parseAttribute(name, newValue);
bool testShouldInvalidateStyle = inActiveDocument() && styleChangeType() < SubtreeStyleChange;
if (isStyledElement() && name == HTMLNames::styleAttr) {
......@@ -889,26 +854,6 @@ void Element::formatForDebugger(char* buffer, unsigned length) const
}
#endif
void Element::parseAttribute(const QualifiedName& name, const AtomicString& value)
{
if (name == HTMLNames::tabindexAttr) {
int tabindex = 0;
if (value.isEmpty()) {
if (hasRareData())
elementRareData()->clearTabIndex();
if (treeScope().adjustedFocusedElement() == this) {
// We might want to call blur(), but it's dangerous to dispatch
// events here.
document().setNeedsFocusedElementCheck();
}
} else if (parseHTMLInteger(value, tabindex)) {
// Clamp tabindex to the range of 'short' to match Firefox's behavior.
tabindex = max(static_cast<int>(std::numeric_limits<short>::min()), std::min(tabindex, static_cast<int>(std::numeric_limits<short>::max())));
ensureElementRareData().setTabIndex(tabindex);
}
}
}
void Element::removeAttributeInternal(size_t index, SynchronizationOfLazyAttribute inSynchronizationOfLazyAttribute)
{
MutableAttributeCollection attributes = ensureUniqueElementData().attributes();
......@@ -963,75 +908,6 @@ Vector<RefPtr<Attr>> Element::getAttributes()
return attributes;
}
void Element::focus(bool restorePreviousSelection, FocusType type)
{
if (!inDocument())
return;
if (document().focusedElement() == this)
return;
if (!document().isActive())
return;
document().updateLayout();
if (!isFocusable())
return;
RefPtr<Node> protect(this);
if (!document().page()->focusController().setFocusedElement(this, document().frame(), type))
return;
// Setting the focused node above might have invalidated the layout due to scripts.
document().updateLayout();
if (!isFocusable())
return;
updateFocusAppearance(restorePreviousSelection);
}
void Element::updateFocusAppearance(bool /*restorePreviousSelection*/)
{
if (isRootEditableElement()) {
// Taking the ownership since setSelection() may release the last reference to |frame|.
RefPtr<LocalFrame> frame(document().frame());
if (!frame)
return;
}
}
void Element::blur()
{
if (treeScope().adjustedFocusedElement() == this) {
Document& doc = document();
if (doc.page())
doc.page()->focusController().setFocusedElement(0, doc.frame());
else
doc.setFocusedElement(nullptr);
}
}
bool Element::supportsFocus() const
{
// FIXME: supportsFocus() can be called when layout is not up to date.
// Logic that deals with the renderer should be moved to rendererIsFocusable().
// But supportsFocus must return true when the element is editable, or else
// it won't be focusable. Furthermore, supportsFocus cannot just return true
// always or else tabIndex() will change for all HTML elements.
if (hasRareData() && elementRareData()->hasTabIndex())
return true;
return hasEditableStyle() && parentNode() && !parentNode()->hasEditableStyle();
}
bool Element::isFocusable() const
{
return inDocument() && supportsFocus() && rendererIsFocusable();
}
bool Element::isKeyboardFocusable() const
{
return isFocusable() && tabIndex() >= 0;
}
RenderStyle* Element::computedStyle()
{
// FIXME: Find and use the renderer from the pseudo element instead of the actual element so that the 'length'
......@@ -1409,8 +1285,7 @@ bool Element::supportsStyleSharing() const
if (hasID() && affectedByIdSelector(idForStyleResolution()))
return false;
// :active and :hover elements always make a chain towards the document node
// and no siblings or cousins will have the same state. There's also only one
// :focus element per scope so we don't need to attempt to share.
// and no siblings or cousins will have the same state.
if (isUserActionElement())
return false;
return true;
......
......@@ -32,7 +32,6 @@
#include "sky/engine/core/dom/ContainerNode.h"
#include "sky/engine/core/dom/ElementData.h"
#include "sky/engine/core/dom/SpaceSplitString.h"
#include "sky/engine/core/page/FocusType.h"
#include "sky/engine/platform/heap/Handle.h"
namespace blink {
......@@ -170,8 +169,6 @@ public:
ModifiedByCloning
};
virtual void parseAttribute(const QualifiedName&, const AtomicString&);
// Only called by the parser immediately after element construction.
void parserSetAttributes(const Vector<Attribute>&);
......@@ -236,22 +233,6 @@ public:
virtual const AtomicString imageSourceURL() const;
void focus(bool restorePreviousSelection = true, FocusType = FocusTypeNone);
void updateFocusAppearance(bool restorePreviousSelection);
void blur();
// Whether this element can receive focus at all. Most elements are not
// focusable but some elements, such as form controls and links, are. Unlike
// rendererIsFocusable(), this method may be called when layout is not up to
// date, so it must not use the renderer to determine focusability.
virtual bool supportsFocus() const;
// Whether the node can actually be focused.
bool isFocusable() const;
bool isKeyboardFocusable() const;
void dispatchFocusEvent(Element* oldFocusedElement, FocusType);
void dispatchBlurEvent(Element* newFocusedElement);
void dispatchFocusInEvent(const AtomicString& eventType, Element* oldFocusedElement);
void dispatchFocusOutEvent(const AtomicString& eventType, Element* newFocusedElement);
bool matches(const String& selectors, ExceptionState&);
DOMTokenList& classList();
......@@ -272,9 +253,6 @@ public:
MutableStylePropertySet& ensureMutableInlineStyle();
void clearMutableInlineStyleIfEmpty();
void setTabIndex(int);
virtual short tabIndex() const override;
String contentEditable() const;
void setContentEditable(const String&, ExceptionState&);
......@@ -297,13 +275,6 @@ protected:
virtual void removedFrom(ContainerNode*) override;
virtual void childrenChanged(const ChildrenChange&) override;
// Subclasses may override this method to affect focusability. Unlike
// supportsFocus, this method must be called on an up-to-date layout, so it
// may use the renderer to reason about focusability. This method cannot be
// moved to RenderObject because some focusable nodes don't have renderers,
// e.g., HTMLOptionElement.
virtual bool rendererIsFocusable() const;
// classAttributeChanged() exists to share code between
// parseAttribute (called via setAttribute()) and
// svgAttributeChanged (called when element.className.baseValue is set)
......
......@@ -21,9 +21,6 @@ interface Element : ParentNode {
// TODO(abarth): Remove these when we implement more of the system.
[RaisesException] boolean matches(DOMString selectors);
void focus();
void blur();
attribute long tabIndex;
readonly attribute DOMTokenList classList;
ClientRect getBoundingClientRect();
......
......@@ -39,21 +39,6 @@ public:
return new ElementRareData(renderer);
}
short tabIndex() const { return m_tabindex; }
bool hasTabIndex() const { return m_hasTabIndex; }
void setTabIndex(short index)
{
m_tabindex = index;
m_hasTabIndex = true;
}
void clearTabIndex()
{
m_tabindex = 0;
m_hasTabIndex = false;
}
CSSStyleDeclaration& ensureInlineCSSStyleDeclaration(Element* ownerElement);
RenderStyle* computedStyle() const { return m_computedStyle.get(); }
......@@ -64,9 +49,6 @@ public:
void setClassList(PassOwnPtr<DOMTokenList> classList) { m_classList = classList; }
private:
unsigned m_tabindex : 16;
unsigned m_hasTabIndex : 1;
OwnPtr<DOMTokenList> m_classList;
OwnPtr<InlineCSSStyleDeclaration> m_cssomWrapper;
......@@ -77,8 +59,6 @@ private:
inline ElementRareData::ElementRareData(RenderObject* renderer)
: NodeRareData(renderer)
, m_tabindex(0)
, m_hasTabIndex(false)
{
m_isElementRareData = true;
}
......
......@@ -298,11 +298,6 @@ void Node::AcceptDartGCVisitor(DartGCVisitor& visitor) const
visitor.AddToSetForRoot(rootForGC(this), dart_wrapper());
}
short Node::tabIndex() const
{
return 0;
}
PassRefPtr<Node> Node::insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionState& exceptionState)
{
if (isContainerNode())
......@@ -416,9 +411,7 @@ bool Node::isContentRichlyEditable()
bool Node::hasEditableStyle(EditableLevel editableLevel, UserSelectAllTreatment treatment) const
{
// Ideally we'd call ASSERT(!needsStyleRecalc()) here, but
// ContainerNode::setFocus() calls setNeedsStyleRecalc(), so the assertion
// would fire in the middle of Document::setFocusedNode().
ASSERT(!needsStyleRecalc());
for (const Node* node = this; node; node = node->parentNode()) {
if (node->isElementNode() && node->renderer()) {
......@@ -1215,11 +1208,6 @@ void Node::removedLastRef()
}
#endif
void Node::setFocus(bool flag)
{
document().userActionElements().setFocused(this, flag);
}
void Node::setActive(bool flag)
{
document().userActionElements().setActive(this, flag);
......@@ -1248,12 +1236,6 @@ bool Node::isUserActionElementHovered() const
return document().userActionElements().isHovered(this);
}
bool Node::isUserActionElementFocused() const
{
ASSERT(isUserActionElement());
return document().userActionElements().isFocused(this);
}
unsigned Node::lengthOfContents() const
{
// This switch statement must be consistent with that of Range::processContentsBetweenOffsets.
......
......@@ -219,7 +219,6 @@ public:
bool active() const { return isUserActionElement() && isUserActionElementActive(); }
bool inActiveChain() const { return isUserActionElement() && isUserActionElementInActiveChain(); }
bool hovered() const { return isUserActionElement() && isUserActionElementHovered(); }
bool focused() const { return isUserActionElement() && isUserActionElementFocused(); }
bool needsAttach() const { return styleChangeType() == NeedsReattachStyleChange; }
bool needsStyleRecalc() const { return styleChangeType() != NoStyleChange; }
......@@ -240,12 +239,9 @@ public:
void markV8CollectableDuringMinorGC() { setFlag(true, V8CollectableDuringMinorGCFlag); }
void clearV8CollectableDuringMinorGC() { setFlag(false, V8CollectableDuringMinorGCFlag); }
virtual void setFocus(bool flag);
virtual void setActive(bool flag = true);
virtual void setHovered(bool flag = true);
virtual short tabIndex() const;
enum UserSelectAllTreatment {
UserSelectAllDoesNotAffectEditability,
UserSelectAllIsAlwaysNonEditable
......@@ -423,7 +419,7 @@ private:
// ex. When setting the href attribute on an <a>.
IsLinkFlag = 1 << 8,
// Changes based on :hover, :active and :focus state.
// Changes based on :hover and :active state.
IsUserActionElementFlag = 1 << 9,
// Tree state flags. These change when the element is added/removed
......@@ -503,7 +499,6 @@ private:
bool isUserActionElementActive() const;
bool isUserActionElementInActiveChain() const;
bool isUserActionElementHovered() const;
bool isUserActionElementFocused() const;
void traceStyleChange(StyleChangeType);
void traceStyleChangeIfNeeded(StyleChangeType);
......
......@@ -36,7 +36,6 @@
#include "sky/engine/core/dom/TreeScopeAdopter.h"
#include "sky/engine/core/frame/FrameView.h"
#include "sky/engine/core/frame/LocalFrame.h"
#include "sky/engine/core/page/FocusController.h"
#include "sky/engine/core/page/Page.h"
#include "sky/engine/core/rendering/HitTestResult.h"
#include "sky/engine/core/rendering/RenderView.h"
......@@ -180,11 +179,6 @@ void TreeScope::adoptIfNeeded(Node& node)
adopter.execute();
}
Element* TreeScope::adjustedFocusedElement() const
{
return 0;
}
unsigned short TreeScope::comparePosition(const TreeScope& otherScope) const
{
if (otherScope == this)
......
......@@ -47,7 +47,6 @@ class TreeScope {
public:
TreeScope* parentTreeScope() const { return m_parentTreeScope; }
Element* adjustedFocusedElement() const;
Element* getElementById(const AtomicString&) const;
void addElementById(const AtomicString& elementId, Element*);
void removeElementById(const AtomicString& elementId, Element*);
......
......@@ -40,11 +40,9 @@ class Element;
class UserActionElementSet final {
DISALLOW_ALLOCATION();
public:
bool isFocused(const Node* node) { return hasFlags(node, IsFocusedFlag); }
bool isActive(const Node* node) { return hasFlags(node, IsActiveFlag); }
bool isInActiveChain(const Node* node) { return hasFlags(node, InActiveChainFlag); }
bool isHovered(const Node* node) { return hasFlags(node, IsHoveredFlag); }
void setFocused(Node* node, bool enable) { setFlags(node, enable, IsFocusedFlag); }
void setActive(Node* node, bool enable) { setFlags(node, enable, IsActiveFlag); }
void setInActiveChain(Node* node, bool enable) { setFlags(node, enable, InActiveChainFlag); }
void setHovered(Node* node, bool enable) { setFlags(node, enable, IsHoveredFlag); }
......@@ -63,7 +61,6 @@ private:
IsActiveFlag = 1 ,
InActiveChainFlag = 1 << 1,
IsHoveredFlag = 1 << 2,
IsFocusedFlag = 1 << 3
};
void setFlags(Node* node, bool enable, unsigned flags) { enable ? setFlags(node, flags) : clearFlags(node, flags); }
......
......@@ -105,11 +105,6 @@ bool Event::isUIEvent() const
return false;
}
bool Event::isFocusEvent() const
{
return false;
}
bool Event::isKeyboardEvent() const
{
return false;
......
......@@ -106,7 +106,6 @@ public:
// These events are general classes of events.
virtual bool isUIEvent() const;
virtual bool isFocusEvent() const;
virtual bool isKeyboardEvent() const;
// Drag events are a subset of mouse events.
......
......@@ -2,8 +2,6 @@ namespace="EventType"
DOMActivate
DOMContentLoaded
DOMFocusIn
DOMFocusOut
abort
animationend
animationiteration
......@@ -11,7 +9,6 @@ animationstart
beforecopy
beforecut
beforepaste
blur
boundary
cached
cancel
......@@ -43,9 +40,6 @@ error
exit
fetch
finish
focus
focusin
focusout
gesturescrollend
gesturescrollstart
gesturescrollupdate
......
......@@ -35,7 +35,6 @@
#include "sky/engine/core/frame/Settings.h"
#include "sky/engine/core/loader/FrameLoaderClient.h"
#include "sky/engine/core/page/ChromeClient.h"
#include "sky/engine/core/page/FocusController.h"
#include "sky/engine/core/page/Page.h"
#include "sky/engine/core/rendering/RenderLayer.h"
#include "sky/engine/public/platform/WebLayer.h"
......
......@@ -34,7 +34,6 @@
#include "sky/engine/core/frame/Settings.h"
#include "sky/engine/core/loader/FrameLoaderClient.h"
#include "sky/engine/core/page/ChromeClient.h"
#include "sky/engine/core/page/FocusController.h"
#include "sky/engine/core/page/Page.h"
#include "sky/engine/core/rendering/RenderLayer.h"
#include "sky/engine/core/rendering/RenderView.h"
......@@ -551,8 +550,7 @@ IntRect FrameView::windowClipRect() const
bool FrameView::isActive() const
{
Page* page = frame().page();
return page && page->focusController().isActive();
return false;
}
void FrameView::setVisibleContentScaleFactor(float visibleContentScaleFactor)
......
/*
/*
* Copyright (C) 2006, 2007, 2008, 2010 Apple Inc. All rights reserved.
* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
*
......@@ -70,9 +70,6 @@
#include "sky/engine/wtf/MathExtras.h"
#include "sky/engine/wtf/text/WTFString.h"
// The focus logic in this file is just disconnected cables now.
// TODO(ianh): Remove the concept of focus.
using std::min;
using std::max;
......@@ -274,21 +271,6 @@ Tracing& LocalDOMWindow::tracing() const
return *m_tracing;
}
void LocalDOMWindow::focus()
{
if (!m_frame)
return;
FrameHost* host = m_frame->host();
if (!host)
return;
host->page().focus();
if (!m_frame)
return;
}
int LocalDOMWindow::outerHeight() const
{
if (!m_frame)
......
......@@ -99,8 +99,6 @@ public:
Location& location() const;
void setLocation(const String& location, SetLocationLocking = LockHistoryBasedOnGestureState);
void focus();
int outerHeight() const;
int outerWidth() const;
int innerHeight() const;
......
......@@ -41,7 +41,6 @@
#include "sky/engine/core/frame/LocalDOMWindow.h"
#include "sky/engine/core/frame/Settings.h"
#include "sky/engine/core/loader/FrameLoaderClient.h"
#include "sky/engine/core/page/FocusController.h"
#include "sky/engine/core/page/Page.h"
#include "sky/engine/core/rendering/HitTestResult.h"
#include "sky/engine/core/rendering/RenderLayer.h"
......@@ -164,12 +163,6 @@ void LocalFrame::willDetachFrameHost()
HashSet<FrameDestructionObserver*>::iterator stop = m_destructionObservers.end();
for (HashSet<FrameDestructionObserver*>::iterator it = m_destructionObservers.begin(); it != stop; ++it)
(*it)->willDetachFrameHost();
// FIXME: Page should take care of updating focus/scrolling instead of Frame.
// FIXME: It's unclear as to why this is called more than once, but it is,
// so page() could be null.
if (page() && page()->focusController().focusedFrame() == this)
page()->focusController().setFocusedFrame(nullptr);
}
void LocalFrame::detachFromFrameHost()
......
......@@ -32,8 +32,6 @@
readonly attribute Screen screen;
[Replaceable, PutForwards=href] readonly attribute Location location;
void focus();
[Replaceable] readonly attribute long outerHeight;
[Replaceable] readonly attribute long outerWidth;
[Replaceable] readonly attribute long innerHeight;
......
......@@ -90,7 +90,6 @@ void FrameLoader::clear()
{
m_frame->document()->cancelParsing();
m_frame->document()->prepareForDestruction();
m_frame->document()->removeFocusedElementOfSubtree(m_frame->document());
if (m_frame->view())
m_frame->view()->clear();
......
......@@ -24,7 +24,6 @@
#include "sky/engine/core/frame/ConsoleTypes.h"
#include "sky/engine/core/inspector/ConsoleAPITypes.h"
#include "sky/engine/core/page/FocusType.h"
#include "sky/engine/public/platform/WebScreenInfo.h"
#include "sky/engine/wtf/Forward.h"
......@@ -44,12 +43,6 @@ public:
virtual void setWindowRect(const FloatRect&) = 0;
virtual FloatRect windowRect() = 0;
virtual void focus() = 0;
virtual bool canTakeFocus(FocusType) = 0;
virtual void takeFocus(FocusType) = 0;
virtual void focusedNodeChanged(Node*) = 0;
virtual void focusedFrameChanged(LocalFrame*) = 0;
virtual bool shouldReportDetailedMessageForSource(const String& source) = 0;
virtual void addMessageToConsole(LocalFrame*, MessageSource, MessageLevel, const String& message, unsigned lineNumber, const String& sourceID, const String& stackTrace) = 0;
......
/*
* Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
* Copyright (C) 2008 Nuanti Ltd.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "sky/engine/core/page/FocusController.h"
#include <limits>
#include "gen/sky/core/EventTypeNames.h"
#include "sky/engine/core/dom/Document.h"
#include "sky/engine/core/dom/Element.h"
#include "sky/engine/core/dom/ElementTraversal.h"
#include "sky/engine/core/dom/NodeTraversal.h"
#include "sky/engine/core/dom/Range.h"
#include "sky/engine/core/editing/htmlediting.h"
#include "sky/engine/core/events/Event.h"
#include "sky/engine/core/frame/FrameView.h"
#include "sky/engine/core/frame/LocalDOMWindow.h"
#include "sky/engine/core/frame/LocalFrame.h"
#include "sky/engine/core/frame/Settings.h"
#include "sky/engine/core/page/ChromeClient.h"
#include "sky/engine/core/page/Page.h"
#include "sky/engine/core/rendering/HitTestResult.h"
#include "sky/engine/core/rendering/RenderLayer.h"
// This file is no longer needed now that nothing can be focused and
// events can't be targetted at nodes. Parts of it have been gutted,
// in fact, such that it no longer makes sense.
// TODO(ianh): We should remove it.
namespace blink {
// FIXME: Some of Node* return values and Node* arguments should be Element*.
FocusNavigationScope::FocusNavigationScope(TreeScope* treeScope)
: m_rootTreeScope(treeScope)
{
ASSERT(treeScope);
}
Node* FocusNavigationScope::rootNode() const
{
return &m_rootTreeScope->rootNode();
}
Element* FocusNavigationScope::owner() const
{
return 0;
}
FocusNavigationScope FocusNavigationScope::focusNavigationScopeOf(Node* node)
{
ASSERT(node);
Node* root = node;
for (Node* n = node; n; n = n->parentNode())
root = n;
// The result is not always a DocumentNode since
// a starting node is in an orphaned tree in composed shadow tree.
return FocusNavigationScope(&root->treeScope());
}
static inline bool isNonFocusableFocusScopeOwner(Node* node)
{
ASSERT(node);
return false;
}
static inline int adjustedTabIndex(Node* node)
{
ASSERT(node);
return isNonFocusableFocusScopeOwner(node) ? 0 : node->tabIndex();
}
static inline bool shouldVisit(Node* node)
{
ASSERT(node);
return (node->isElementNode() && toElement(node)->isKeyboardFocusable()) || isNonFocusableFocusScopeOwner(node);
}
FocusController::FocusController(Page* page)
: m_page(page)
, m_isActive(false)
, m_isFocused(false)
, m_isChangingFocusedFrame(false)
{
}
PassOwnPtr<FocusController> FocusController::create(Page* page)
{
return adoptPtr(new FocusController(page));
}
void FocusController::setFocusedFrame(PassRefPtr<LocalFrame> frame)
{
ASSERT(!frame || frame->page() == m_page);
if (m_focusedFrame == frame || m_isChangingFocusedFrame)
return;
m_isChangingFocusedFrame = true;
RefPtr<LocalFrame> oldFrame = m_focusedFrame.get();
RefPtr<LocalFrame> newFrame = frame.get();
m_focusedFrame = frame.get();
m_isChangingFocusedFrame = false;
m_page->focusedFrameChanged(newFrame.get());
}
void FocusController::focusDocumentView(PassRefPtr<LocalFrame> frame)
{
ASSERT(!frame || frame->page() == m_page);
if (m_focusedFrame == frame)
return;
setFocusedFrame(frame);
}
LocalFrame* FocusController::focusedOrMainFrame() const
{
// FIXME(sky): this method makes no sense.
return m_page->mainFrame();
}
void FocusController::setFocused(bool focused)
{
if (isFocused() == focused)
return;
m_isFocused = focused;
if (!m_focusedFrame)
setFocusedFrame(m_page->mainFrame());
}
Node* FocusController::findFocusableNodeDecendingDownIntoFrameDocument(FocusType type, Node* node)
{
return 0;
}
bool FocusController::setInitialFocus(FocusType type)
{
return advanceFocus(type, true);
}
bool FocusController::advanceFocus(FocusType type, bool initialFocus)
{
switch (type) {
case FocusTypeForward:
case FocusTypeBackward:
return advanceFocusInDocumentOrder(type, initialFocus);
case FocusTypeLeft:
case FocusTypeRight:
case FocusTypeUp:
case FocusTypeDown:
// FIXME(sky): Remove directional focus.
return false;
default:
ASSERT_NOT_REACHED();
}
return false;
}
bool FocusController::advanceFocusInDocumentOrder(FocusType type, bool initialFocus)
{
LocalFrame* frame = focusedOrMainFrame();
ASSERT(frame);
Document* document = frame->document();
Node* currentNode = document->focusedElement();
document->updateLayout();
RefPtr<Node> node = findFocusableNodeAcrossFocusScope(type, FocusNavigationScope::focusNavigationScopeOf(currentNode ? currentNode : document), currentNode);
if (!node) {
// We didn't find a node to focus, so we should try to pass focus to Chrome.
if (!initialFocus && m_page->canTakeFocus(type)) {
document->setFocusedElement(nullptr);
setFocusedFrame(nullptr);
m_page->takeFocus(type);
return true;
}
// Chrome doesn't want focus, so we should wrap focus.
node = findFocusableNodeRecursively(type, FocusNavigationScope::focusNavigationScopeOf(m_page->mainFrame()->document()), 0);
node = findFocusableNodeDecendingDownIntoFrameDocument(type, node.get());
if (!node)
return false;
}
ASSERT(node);
if (node == document->focusedElement())
// Focus wrapped around to the same node.
return true;
if (!node->isElementNode())
// FIXME: May need a way to focus a document here.
return false;
Element* element = toElement(node);
// FIXME: It would be nice to just be able to call setFocusedElement(node)
// here, but we can't do that because some elements (e.g. HTMLInputElement
// and HTMLTextAreaElement) do extra work in their focus() methods.
Document& newDocument = element->document();
if (&newDocument != document) {
// Focus is going away from this document, so clear the focused node.
document->setFocusedElement(nullptr);
}
setFocusedFrame(newDocument.frame());
element->focus(false, type);
return true;
}
Node* FocusController::findFocusableNodeAcrossFocusScope(FocusType type, FocusNavigationScope scope, Node* currentNode)
{
ASSERT(!currentNode);
Node* found;
if (currentNode && type == FocusTypeForward) {
found = nullptr;
} else {
found = findFocusableNodeRecursively(type, scope, currentNode);
}
// If there's no focusable node to advance to, move up the focus scopes until we find one.
while (!found) {
Node* owner = scope.owner();
if (!owner)
break;
scope = FocusNavigationScope::focusNavigationScopeOf(owner);
if (type == FocusTypeBackward) {
found = owner;
break;
}
found = findFocusableNodeRecursively(type, scope, owner);
}
found = findFocusableNodeDecendingDownIntoFrameDocument(type, found);
return found;
}
Node* FocusController::findFocusableNodeRecursively(FocusType type, FocusNavigationScope scope, Node* start)
{
return nullptr;
}
Node* FocusController::findFocusableNode(FocusType type, FocusNavigationScope scope, Node* node)
{
return type == FocusTypeForward ? nextFocusableNode(scope, node) : previousFocusableNode(scope, node);
}
Node* FocusController::findNodeWithExactTabIndex(Node* start, int tabIndex, FocusType type)
{
// Search is inclusive of start
for (Node* node = start; node; node = type == FocusTypeForward ? NodeTraversal::next(*node) : NodeTraversal::previous(*node)) {
if (shouldVisit(node) && adjustedTabIndex(node) == tabIndex)
return node;
}
return 0;
}
static Node* nextNodeWithGreaterTabIndex(Node* start, int tabIndex)
{
// Search is inclusive of start
int winningTabIndex = std::numeric_limits<short>::max() + 1;
Node* winner = 0;
for (Node* node = start; node; node = NodeTraversal::next(*node)) {
if (shouldVisit(node) && node->tabIndex() > tabIndex && node->tabIndex() < winningTabIndex) {
winner = node;
winningTabIndex = node->tabIndex();
}
}
return winner;
}
static Node* previousNodeWithLowerTabIndex(Node* start, int tabIndex)
{
// Search is inclusive of start
int winningTabIndex = 0;
Node* winner = 0;
for (Node* node = start; node; node = NodeTraversal::previous(*node)) {
int currentTabIndex = adjustedTabIndex(node);
if ((shouldVisit(node)) && currentTabIndex < tabIndex && currentTabIndex > winningTabIndex) {
winner = node;
winningTabIndex = currentTabIndex;
}
}
return winner;
}
Node* FocusController::nextFocusableNode(FocusNavigationScope scope, Node* start)
{
if (start) {
int tabIndex = adjustedTabIndex(start);
// If a node is excluded from the normal tabbing cycle, the next focusable node is determined by tree order
if (tabIndex < 0) {
for (Node* node = NodeTraversal::next(*start); node; node = NodeTraversal::next(*node)) {
if (shouldVisit(node) && adjustedTabIndex(node) >= 0)
return node;
}
}
// First try to find a node with the same tabindex as start that comes after start in the scope.
if (Node* winner = findNodeWithExactTabIndex(NodeTraversal::next(*start), tabIndex, FocusTypeForward))
return winner;
if (!tabIndex)
// We've reached the last node in the document with a tabindex of 0. This is the end of the tabbing order.
return 0;
}
// Look for the first node in the scope that:
// 1) has the lowest tabindex that is higher than start's tabindex (or 0, if start is null), and
// 2) comes first in the scope, if there's a tie.
if (Node* winner = nextNodeWithGreaterTabIndex(scope.rootNode(), start ? adjustedTabIndex(start) : 0))
return winner;
// There are no nodes with a tabindex greater than start's tabindex,
// so find the first node with a tabindex of 0.
return findNodeWithExactTabIndex(scope.rootNode(), 0, FocusTypeForward);
}
Node* FocusController::previousFocusableNode(FocusNavigationScope scope, Node* start)
{
Node* last = 0;
for (Node* node = scope.rootNode(); node; node = node->lastChild())
last = node;
ASSERT(last);
// First try to find the last node in the scope that comes before start and has the same tabindex as start.
// If start is null, find the last node in the scope with a tabindex of 0.
Node* startingNode;
int startingTabIndex;
if (start) {
startingNode = NodeTraversal::previous(*start);
startingTabIndex = adjustedTabIndex(start);
} else {
startingNode = last;
startingTabIndex = 0;
}
// However, if a node is excluded from the normal tabbing cycle, the previous focusable node is determined by tree order
if (startingTabIndex < 0) {
for (Node* node = startingNode; node; node = NodeTraversal::previous(*node)) {
if (shouldVisit(node) && adjustedTabIndex(node) >= 0)
return node;
}
}
if (Node* winner = findNodeWithExactTabIndex(startingNode, startingTabIndex, FocusTypeBackward))
return winner;
// There are no nodes before start with the same tabindex as start, so look for a node that:
// 1) has the highest non-zero tabindex (that is less than start's tabindex), and
// 2) comes last in the scope, if there's a tie.
startingTabIndex = (start && startingTabIndex) ? startingTabIndex : std::numeric_limits<short>::max();
return previousNodeWithLowerTabIndex(last, startingTabIndex);
}
static bool relinquishesEditingFocus(Node *node)
{
ASSERT(node);
ASSERT(node->hasEditableStyle());
return node->document().frame() && node->rootEditableElement();
}
bool FocusController::setFocusedElement(Element* element, PassRefPtr<LocalFrame> newFocusedFrame, FocusType type)
{
RefPtr<LocalFrame> oldFocusedFrame = focusedFrame();
RefPtr<Document> oldDocument = oldFocusedFrame ? oldFocusedFrame->document() : 0;
Element* oldFocusedElement = oldDocument ? oldDocument->focusedElement() : 0;
if (element && oldFocusedElement == element)
return true;
// FIXME: Might want to disable this check for caretBrowsing
if (oldFocusedElement && oldFocusedElement->isRootEditableElement() && !relinquishesEditingFocus(oldFocusedElement))
return false;
RefPtr<Document> newDocument = nullptr;
if (element)
newDocument = &element->document();
else if (newFocusedFrame)
newDocument = newFocusedFrame->document();
if (newDocument && oldDocument == newDocument && newDocument->focusedElement() == element)
return true;
if (oldDocument && oldDocument != newDocument)
oldDocument->setFocusedElement(nullptr);
if (newFocusedFrame && !newFocusedFrame->page()) {
setFocusedFrame(nullptr);
return false;
}
setFocusedFrame(newFocusedFrame);
// Setting the focused node can result in losing our last reft to node when JS event handlers fire.
RefPtr<Element> protect ALLOW_UNUSED = element;
if (newDocument) {
bool successfullyFocused = newDocument->setFocusedElement(element, type);
if (!successfullyFocused)
return false;
}
return true;
}
void FocusController::setActive(bool active)
{
if (m_isActive == active)
return;
m_isActive = active;
}
} // namespace blink
/*
* Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SKY_ENGINE_CORE_PAGE_FOCUSCONTROLLER_H_
#define SKY_ENGINE_CORE_PAGE_FOCUSCONTROLLER_H_
#include "sky/engine/core/page/FocusType.h"
#include "sky/engine/platform/geometry/LayoutRect.h"
#include "sky/engine/platform/heap/Handle.h"
#include "sky/engine/wtf/Forward.h"
#include "sky/engine/wtf/Noncopyable.h"
#include "sky/engine/wtf/RefPtr.h"
namespace blink {
struct FocusCandidate;
class Document;
class Element;
class LocalFrame;
class IntRect;
class KeyboardEvent;
class Node;
class Page;
class TreeScope;
class FocusNavigationScope {
STACK_ALLOCATED();
public:
Node* rootNode() const;
Element* owner() const;
static FocusNavigationScope focusNavigationScopeOf(Node*);
private:
explicit FocusNavigationScope(TreeScope*);
RawPtr<TreeScope> m_rootTreeScope;
};
class FocusController {
WTF_MAKE_NONCOPYABLE(FocusController); WTF_MAKE_FAST_ALLOCATED;
public:
static PassOwnPtr<FocusController> create(Page*);
void setFocusedFrame(PassRefPtr<LocalFrame>);
void focusDocumentView(PassRefPtr<LocalFrame>);
LocalFrame* focusedFrame() const { return m_focusedFrame.get(); }
LocalFrame* focusedOrMainFrame() const;
bool setInitialFocus(FocusType);
bool advanceFocus(FocusType type) { return advanceFocus(type, false); }
bool setFocusedElement(Element*, PassRefPtr<LocalFrame>, FocusType = FocusTypeNone);
void setActive(bool);
bool isActive() const { return m_isActive; }
void setFocused(bool);
bool isFocused() const { return m_isFocused; }
private:
explicit FocusController(Page*);
bool advanceFocus(FocusType, bool initialFocus);
bool advanceFocusInDocumentOrder(FocusType, bool initialFocus);
Node* findFocusableNodeAcrossFocusScope(FocusType, FocusNavigationScope startScope, Node* start);
Node* findFocusableNodeRecursively(FocusType, FocusNavigationScope, Node* start);
Node* findFocusableNodeDecendingDownIntoFrameDocument(FocusType, Node*);
// Searches through the given tree scope, starting from start node, for the next/previous selectable element that comes after/before start node.
// The order followed is as specified in section 17.11.1 of the HTML4 spec, which is elements with tab indexes
// first (from lowest to highest), and then elements without tab indexes (in document order).
//
// @param start The node from which to start searching. The node after this will be focused. May be null.
//
// @return The focus node that comes after/before start node.
//
// See http://www.w3.org/TR/html4/interact/forms.html#h-17.11.1
inline Node* findFocusableNode(FocusType, FocusNavigationScope, Node* start);
Node* nextFocusableNode(FocusNavigationScope, Node* start);
Node* previousFocusableNode(FocusNavigationScope, Node* start);
Node* findNodeWithExactTabIndex(Node* start, int tabIndex, FocusType);
Page* m_page;
RefPtr<LocalFrame> m_focusedFrame;
bool m_isActive;
bool m_isFocused;
bool m_isChangingFocusedFrame;
};
} // namespace blink
#endif // SKY_ENGINE_CORE_PAGE_FOCUSCONTROLLER_H_
/*
* Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SKY_ENGINE_CORE_PAGE_FOCUSTYPE_H_
#define SKY_ENGINE_CORE_PAGE_FOCUSTYPE_H_
namespace blink {
enum FocusType {
// Element::focus(), etc.
FocusTypeNone = 0,
// Sequential navigation with TAB, or Shift + TAB.
FocusTypeForward,
FocusTypeBackward,
// Spatial navigation.
FocusTypeUp,
FocusTypeDown,
FocusTypeLeft,
FocusTypeRight,
// Mouse press
FocusTypeMouse,
// Re-focus by a page focus
FocusTypePage
};
}
#endif // SKY_ENGINE_CORE_PAGE_FOCUSTYPE_H_
......@@ -30,7 +30,6 @@
#include "sky/engine/core/frame/LocalFrame.h"
#include "sky/engine/core/frame/Settings.h"
#include "sky/engine/core/page/ChromeClient.h"
#include "sky/engine/core/page/FocusController.h"
#include "sky/engine/core/rendering/RenderView.h"
#include "sky/engine/platform/geometry/FloatRect.h"
#include "sky/engine/public/platform/WebScreenInfo.h"
......@@ -58,7 +57,6 @@ float deviceScaleFactor(LocalFrame* frame)
Page::Page(PageClients& pageClients, ServiceProvider* services)
: SettingsDelegate(Settings::create())
, m_chromeClient(pageClients.chromeClient)
, m_focusController(FocusController::create(this))
, m_mainFrame(0)
, m_deviceScaleFactor(1)
#if ENABLE(ASSERT)
......@@ -210,31 +208,6 @@ FloatRect Page::windowRect() const
return m_chromeClient->windowRect();
}
void Page::focus() const
{
m_chromeClient->focus();
}
bool Page::canTakeFocus(FocusType type) const
{
return m_chromeClient->canTakeFocus(type);
}
void Page::takeFocus(FocusType type) const
{
m_chromeClient->takeFocus(type);
}
void Page::focusedNodeChanged(Node* node) const
{
m_chromeClient->focusedNodeChanged(node);
}
void Page::focusedFrameChanged(LocalFrame* frame) const
{
m_chromeClient->focusedFrameChanged(frame);
}
void Page::scheduleVisualUpdate()
{
m_chromeClient->scheduleVisualUpdate();
......
......@@ -25,7 +25,6 @@
#include "sky/engine/core/frame/LocalFrame.h"
#include "sky/engine/core/frame/SettingsDelegate.h"
#include "sky/engine/core/inspector/ConsoleAPITypes.h"
#include "sky/engine/core/page/FocusType.h"
#include "sky/engine/platform/HostWindow.h"
#include "sky/engine/platform/Supplementable.h"
#include "sky/engine/platform/geometry/LayoutRect.h"
......@@ -42,7 +41,6 @@ class ChromeClient;
class ClientRectList;
class Document;
class FloatRect;
class FocusController;
class Frame;
class FrameHost;
class IntRect;
......@@ -84,8 +82,6 @@ public:
void documentDetached(Document*);
FocusController& focusController() const { return *m_focusController; }
Settings& settings() const { return *m_settings; }
void unmarkAllTextMatches();
......@@ -118,14 +114,6 @@ public:
void setWindowRect(const FloatRect&) const;
FloatRect windowRect() const;
void focus() const;
bool canTakeFocus(FocusType) const;
void takeFocus(FocusType) const;
void focusedNodeChanged(Node*) const;
void focusedFrameChanged(LocalFrame*) const;
bool shouldReportDetailedMessageForSource(const String& source);
void addMessageToConsole(LocalFrame*, MessageSource, MessageLevel, const String& message, unsigned lineNumber, const String& sourceID, const String& stackTrace);
......@@ -140,7 +128,6 @@ private:
virtual void settingsChanged(SettingsDelegate::ChangeType) override;
ChromeClient* m_chromeClient;
const OwnPtr<FocusController> m_focusController;
// Typically, the main frame and Page should both be owned by the embedder,
// which must call Page::willBeDestroyed() prior to destroying Page. This
......
......@@ -27,7 +27,6 @@
#include "sky/engine/core/frame/LocalFrame.h"
#include "sky/engine/core/frame/Settings.h"
#include "sky/engine/core/html/parser/HTMLParserIdioms.h"
#include "sky/engine/core/page/FocusController.h"
#include "sky/engine/core/page/Page.h"
#include "sky/engine/core/rendering/PaintInfo.h"
#include "sky/engine/core/rendering/RenderView.h"
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册