| Index: Source/core/page/FocusController.cpp
|
| diff --git a/Source/core/page/FocusController.cpp b/Source/core/page/FocusController.cpp
|
| index f9cb3d95a7062afb608644e7ab992efb0939656f..52af0c4a5a9d4639c67d3e32fc70e1bc6ff0106e 100644
|
| --- a/Source/core/page/FocusController.cpp
|
| +++ b/Source/core/page/FocusController.cpp
|
| @@ -1,6 +1,7 @@
|
| /*
|
| * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
|
| * Copyright (C) 2008 Nuanti Ltd.
|
| + * Copyright (C) 2013, 2014 Opera Software ASA. All rights reserved.
|
| *
|
| * Redistribution and use in source and binary forms, with or without
|
| * modification, are permitted provided that the following conditions
|
| @@ -57,6 +58,8 @@
|
| #include "core/page/SpatialNavigation.h"
|
| #include "core/rendering/HitTestResult.h"
|
| #include "core/rendering/RenderLayer.h"
|
| +#include "core/rendering/RenderObject.h"
|
| +#include "core/rendering/style/StyleNavigationValue.h"
|
| #include <limits>
|
|
|
| namespace blink {
|
| @@ -931,4 +934,75 @@ void FocusController::trace(Visitor* visitor)
|
| visitor->trace(m_focusedFrame);
|
| }
|
|
|
| +bool FocusController::handleCSSFocusNavigation(FocusType type)
|
| +{
|
| + ASSERT(focusedOrMainFrame());
|
| + if (!focusedOrMainFrame()->isLocalFrame())
|
| + return false;
|
| +
|
| + LocalFrame* currentFrame = toLocalFrame(focusedOrMainFrame());
|
| + Document* focusedDocument = currentFrame->document();
|
| + if (!focusedDocument)
|
| + return false;
|
| +
|
| + Element* focused = focusedDocument->focusedElement();
|
| + RenderObject* renderer = focused ? focused->renderer() : 0;
|
| + if (!renderer)
|
| + return false;
|
| +
|
| + StyleNavigationValue value;
|
| +
|
| + switch (type) {
|
| + case FocusTypeForward:
|
| + case FocusTypeBackward:
|
| + return false;
|
| + case FocusTypeUp:
|
| + value = renderer->style()->navUp();
|
| + break;
|
| + case FocusTypeDown:
|
| + value = renderer->style()->navDown();
|
| + break;
|
| + case FocusTypeLeft:
|
| + value = renderer->style()->navLeft();
|
| + break;
|
| + case FocusTypeRight:
|
| + value = renderer->style()->navRight();
|
| + break;
|
| + case FocusTypeNone:
|
| + default:
|
| + ASSERT_NOT_REACHED();
|
| + break;
|
| + }
|
| +
|
| + if (value.isAuto())
|
| + return false;
|
| +
|
| + // If we were in the autoscroll/panScroll mode we want to stop it.
|
| + currentFrame->eventHandler().stopAutoscroll();
|
| +
|
| + ENavigationTarget navigationTarget = value.navigationTarget();
|
| + Frame* targetFrame = 0;
|
| + if (navigationTarget == Current)
|
| + targetFrame = currentFrame;
|
| + else if (navigationTarget == Root)
|
| + targetFrame = currentFrame->tree().top();
|
| + else
|
| + targetFrame = currentFrame->tree().find(value.targetName());
|
| +
|
| + if (!targetFrame || !targetFrame->isLocalFrame())
|
| + return false;
|
| +
|
| + Element* targetElement = toLocalFrame(targetFrame)->document()->getElementById(value.id());
|
| +
|
| + if (!targetElement)
|
| + return false;
|
| +
|
| + // If it's the same as the current focused, it should be considered a valid navigation,
|
| + // but there is no need to change focus.
|
| + if (focused == targetElement)
|
| + return true;
|
| +
|
| + return setFocusedElement(targetElement, targetFrame);
|
| +}
|
| +
|
| } // namespace blink
|
|
|