#include "htmlediting.h" // For firstPositionInOrBeforeNode
#include <limits>
+#if ENABLE(TIZEN_FOCUS_UI)
+#include "RenderLayer.h"
+#endif
+
namespace WebCore {
using namespace HTMLNames;
using namespace std;
+#if ENABLE(TIZEN_FOCUS_UI)
+HashSet<Node*> m_excludedCandidateSet;
+#endif
+
static inline ComposedShadowTreeWalker walkerFrom(const Node* node)
{
return ComposedShadowTreeWalker(node, ComposedShadowTreeWalker::DoNotCrossUpperBoundary);
}
}
+#if ENABLE(TIZEN_FOCUS_UI)
+static IntSize frameOffset(Frame* initialFrame)
+{
+ IntSize offset;
+ for (Frame* frame = initialFrame; frame; frame = frame->tree()->parent()) {
+ RenderBoxModelObject* renderer;
+ if (frame->ownerElement() && (renderer = frame->ownerElement()->renderBoxModelObject())) {
+ do {
+ offset.expand(renderer->offsetLeft(), renderer->offsetTop());
+ } while ((renderer = renderer->offsetParent()));
+ offset -= frame->view()->scrollOffset();
+ }
+ }
+ return offset;
+}
+
+static bool isTopmostNode(const FocusCandidate& candidate)
+{
+ Node* candidateNode = candidate.visibleNode;
+ if (candidateNode->isFrameOwnerElement())
+ return true;
+
+ Frame* frame = candidateNode->document()->frame();
+ EventHandler* eventHandler = frame->eventHandler();
+ IntSize offset(frameOffset(frame));
+
+ Node* childNode;
+ if (candidateNode->hasTagName(HTMLNames::aTag))
+ childNode = candidateNode->firstChild();
+ else
+ childNode = 0;
+
+ Region region(pixelSnappedIntRect(candidate.rect));
+
+ while (!region.isEmpty()) {
+ Vector<IntRect> rects = region.rects();
+ HitTestResult result = eventHandler->hitTestResultAtPoint(IntPoint(rects[0].x(), rects[0].y()) - offset, false);
+
+ Node* node = result.innerNode();
+ if (!node || !node->parentNode() || node->parentNode()->isDocumentNode() || candidateNode->contains(node))
+ return true;
+
+ if (node->hasTagName(HTMLNames::areaTag))
+ node = static_cast<HTMLAreaElement*>(node)->imageElement();
+
+ ASSERT(node && node->renderer() && node->renderer()->enclosingLayer());
+ IntRect layerRect(node->renderer()->enclosingLayer()->absoluteBoundingBox());
+ layerRect.move(frameOffset(node->document()->frame()));
+ if (!layerRect.intersects(rects[0]))
+ return true;
+
+ region.subtract(layerRect);
+
+ while (childNode && region.isEmpty()) {
+ if (childNode->renderer())
+ region.intersect(pixelSnappedIntRect(nodeRectInAbsoluteCoordinates(childNode)));
+ childNode = childNode->nextSibling();
+ }
+ }
+
+ return false;
+}
+
+static bool isSuitableCandidate(FocusDirection direction, const FocusCandidate& candidate, const FocusCandidate& closest)
+{
+ ASSERT(candidate.alignment != closest.alignment);
+ if (candidate.alignment == None)
+ return false;
+ if (closest.alignment == None)
+ return true;
+
+ long long candidateDistance = candidate.distance;
+ long long closestDistance = closest.distance;
+
+ if (candidate.alignment < closest.alignment) {
+ if (direction == FocusDirectionLeft || direction == FocusDirectionRight)
+ candidateDistance += candidate.rect.width().toInt();
+ else
+ candidateDistance += candidate.rect.height().toInt();
+ } else {
+ if (direction == FocusDirectionLeft || direction == FocusDirectionRight)
+ closestDistance += closest.rect.width().toInt();
+ else
+ closestDistance += closest.rect.height().toInt();
+ }
+
+ return candidateDistance < closestDistance;
+}
+#endif
+
static void updateFocusCandidateIfNeeded(FocusDirection direction, const FocusCandidate& current, FocusCandidate& candidate, FocusCandidate& closest)
{
ASSERT(candidate.visibleNode->isElementNode());
if (candidate.isOffscreenAfterScrolling && candidate.alignment < Full)
return;
+#if ENABLE(TIZEN_FOCUS_UI)
+ if (!isTopmostNode(candidate))
+ return;
+#endif
+
if (closest.isNull()) {
closest = candidate;
return;
return;
}
+#if ENABLE(TIZEN_FOCUS_UI)
+ if (isSuitableCandidate(direction, candidate, closest))
+ closest = candidate;
+#else
if (candidate.alignment > closest.alignment)
closest = candidate;
+#endif
}
void FocusController::findFocusCandidateInContainer(Node* container, const LayoutRect& startingRect, FocusDirection direction, KeyboardEvent* event, FocusCandidate& closest)
if (!node->isElementNode())
continue;
+#if ENABLE(TIZEN_FOCUS_UI)
+ if ((!node->isFocusable() && !node->isFrameOwnerElement() && !canScrollInDirection(node, direction)) || m_excludedCandidateSet.contains(node))
+#else
if (!node->isKeyboardFocusable(event) && !node->isFrameOwnerElement() && !canScrollInDirection(node, direction))
+#endif
continue;
FocusCandidate candidate = FocusCandidate(node, direction);
frameElement->contentFrame()->document()->updateLayoutIgnorePendingStylesheets();
if (!advanceFocusDirectionallyInContainer(frameElement->contentFrame()->document(), rect, direction, event)) {
// The new frame had nothing interesting, need to find another candidate.
+#if ENABLE(TIZEN_FOCUS_UI)
+ m_excludedCandidateSet.add(focusCandidate.visibleNode);
+ return advanceFocusDirectionallyInContainer(container, newStartingRect, direction, event);
+#else
return advanceFocusDirectionallyInContainer(container, nodeRectInAbsoluteCoordinates(focusCandidate.visibleNode, true), direction, event);
+#endif
}
return true;
}
return true;
}
+#if ENABLE(TIZEN_FOCUS_UI)
+ if (focusCandidate.isOffscreen) {
+ Node* container = focusCandidate.enclosingScrollableBox;
+ scrollInDirection(container, direction);
+ }
+#endif
+
// We found a new focus node, navigate to it.
Element* element = toElement(focusCandidate.focusableNode);
ASSERT(element);
static_cast<Document*>(container)->updateLayoutIgnorePendingStylesheets();
} while (!consumed && container);
+#if ENABLE(TIZEN_FOCUS_UI)
+ m_excludedCandidateSet.clear();
+#endif
return consumed;
}
visibleNode = node;
rect = nodeRectInAbsoluteCoordinates(node, true /* ignore border */);
}
+#if ENABLE(TIZEN_FOCUS_UI)
+ if (rect.isEmpty() || rect.maxX() < 0 || rect.maxY() < 0) {
+ visibleNode = 0;
+ return;
+ }
+#endif
focusableNode = node;
isOffscreen = hasOffscreenRect(visibleNode);
aStart = start(direction, a);
bStart = start(direction, b);
+#if !ENABLE(TIZEN_FOCUS_UI)
LayoutUnit aMiddle = middle(direction, a);
LayoutUnit bMiddle = middle(direction, b);
+#endif
aEnd = end(direction, a);
bEnd = end(direction, b);
// * * * * * *
// **************************** *****************************
+#if ENABLE(TIZEN_FOCUS_UI)
+ return (aStart <= bStart && aEnd >= bEnd) || (bStart <= aStart && bEnd >= aEnd);
+#else
return ((bMiddle >= aStart && bMiddle <= aEnd) // (1)
|| (aMiddle >= bStart && aMiddle <= bEnd) // (2)
|| (bStart == aStart) // (3)
|| (bEnd == aEnd)); // (4)
+#endif
}
// This method checks if |start| and |dest| have a partial intersection, either
{
LayoutRect rect = initialRect;
for (Frame* frame = initialFrame; frame; frame = frame->tree()->parent()) {
+#if ENABLE(TIZEN_FOCUS_UI)
+ RenderBoxModelObject* renderer;
+ if (frame->ownerElement() && (renderer = frame->ownerElement()->renderBoxModelObject())) {
+ do {
+ rect.move(renderer->offsetLeft(), renderer->offsetTop());
+ } while ((renderer = renderer->offsetParent()));
+ rect.move(-frame->view()->scrollOffset());
+ }
+#else
if (Element* element = static_cast<Element*>(frame->ownerElement())) {
do {
rect.move(element->offsetLeft(), element->offsetTop());
} while ((element = element->offsetParent()));
rect.move((-frame->view()->scrollOffset()));
}
+#endif
}
return rect;
}
if (node->isDocumentNode())
return frameRectInAbsoluteCoordinates(static_cast<Document*>(node)->frame());
+#if ENABLE(TIZEN_FOCUS_UI)
+ LayoutRect rect = node->getRect();
+ rect.intersect(node->renderer()->absoluteClippedOverflowRect());
+ rect = rectToAbsoluteCoordinates(node->document()->frame(), rect);
+#else
LayoutRect rect = rectToAbsoluteCoordinates(node->document()->frame(), node->getRect());
+#endif
// For authors that use border instead of outline in their CSS, we compensate by ignoring the border when calculating
// the rect of the focused element.
ADD_DEFINITIONS(-DSCREEN_READER_FOCUS_RING_IMAGE_PATH="${SCREEN_READER_FOCUS_RING_IMAGE_PATH}/screenReaderFocusRing.png")
INSTALL(FILES ${WEBKIT2_DIR}/UIProcess/API/efl/tizen/images/screenReaderFocusRing.png DESTINATION ${SCREEN_READER_FOCUS_RING_IMAGE_PATH})
ENDIF ()
+
+IF (ENABLE_TIZEN_FOCUS_UI)
+ SET(FOCUS_UI_FOCUS_RING_IMAGE_PATH ${CMAKE_INSTALL_PREFIX}/share/${WebKit2_LIBRARY_NAME}-${PROJECT_VERSION_MAJOR}/images)
+ ADD_DEFINITIONS(-DFOCUS_UI_FOCUS_RING_IMAGE_PATH="${FOCUS_UI_FOCUS_RING_IMAGE_PATH}/focusUIFocusRing.png")
+ INSTALL(FILES ${WEBKIT2_DIR}/UIProcess/API/efl/tizen/images/focusUIFocusRing.png DESTINATION ${FOCUS_UI_FOCUS_RING_IMAGE_PATH})
+ENDIF ()
if (!count)
return;
+#if ENABLE(TIZEN_FOCUS_UI)
+ if (type == EWK_TOUCH_START)
+ pageProxy->setSpatialNavigationEnabled(false);
+#endif
+
Eina_List* points = 0;
for (unsigned i = 0; i < count; ++i) {
Ewk_Touch_Point* point = new Ewk_Touch_Point;
focusRing->updateScrollAndScale(previousScrollPosition, previousScale);
#endif
}
+
+#if ENABLE(TIZEN_FOCUS_UI)
+void EwkViewImpl::pages(Vector<RefPtr<WebPageProxy> >& pages)
+{
+ pages.resize(pageViewMap.size());
+
+ PageViewMap::const_iterator::Keys it = pageViewMap.begin().keys();
+ PageViewMap::const_iterator::Keys end = pageViewMap.end().keys();
+ for (unsigned i = 0; it != end; ++it, ++i)
+ pages[i] = toImpl(*it);
+}
+#endif
#endif //#if OS(TIZEN)
#endif
void didChangeScrollAndScale(const WebCore::IntPoint&, float);
+
+#if ENABLE(TIZEN_FOCUS_UI)
+ static void pages(Vector<RefPtr<WebKit::WebPageProxy> >&);
+#endif
#endif // #if OS(TIZEN)
// FIXME: Make members private for encapsulation.
#endif
#if ENABLE(TIZEN_ISF_PORT)
- Ecore_X_Window rootWin = ecore_x_window_root_first_get();
- ecore_x_event_mask_set(rootWin, ECORE_X_EVENT_MASK_WINDOW_PROPERTY);
- Ecore_X_Atom xAtom = ecore_x_atom_get("X External Keyboard Exist");
- unsigned int connectedKeyboardNum = 0;
- bool isExternalKeyboardConnected = false;
-
- // get connected keyboard number
- if (ecore_x_window_prop_card32_get(rootWin, xAtom, &connectedKeyboardNum, 1)
- && connectedKeyboardNum)
- isExternalKeyboardConnected = true;
-
// We should treat both of ECORE_IMF_INPUT_PANEL_STATE_SHOW and ECORE_IMF_INPUT_PANEL_STATE_WILL_SHOW
// as IME is shown. ECORE_IMF_INPUT_PANEL_STATE_HIDE is ignored at here.
// input field zoom should not work with below conditions
// 3. imfContext is null(if adjustForExternalKeyboard is false)
// 4. input panel state is hidden(if adjustForExternalKeyboard is false)
if ((!(static_cast<PageClient*>(impl->pageClient.get()))->isViewFocused()
- || (adjustForExternalKeyboard && !isExternalKeyboardConnected)
+ || (adjustForExternalKeyboard && !InputMethodContextEfl::shouldUseExternalKeyboard())
|| (!adjustForExternalKeyboard && !impl->inputMethodContext())
|| (!adjustForExternalKeyboard && !impl->inputMethodContext()->isShow()))
#if ENABLE(TIZEN_WEBKIT2_CONTEXT_MENU_CLIPBOARD)
#if ENABLE(TIZEN_WEBKIT2_NOTIFY_SUSPEND_BY_REMOTE_WEB_INSPECTOR)
, m_contentSuspendedByInspector(false)
#endif
+#if ENABLE(TIZEN_FOCUS_UI)
+ , m_spatialNavigationEnabled(false)
+#endif
{
#ifndef NDEBUG
webPageProxyCounter.increment();
void recalcScreenReaderFocusRect();
void clearScreenReader();
- void didScreenReaderFocusRectChanged(const WebCore::IntRect&);
void didScreenReaderTextChanged(const String&);
#endif
+#if ENABLE(TIZEN_SCREEN_READER) || ENABLE(TIZEN_FOCUS_UI)
+ void didChangeFocusedRect(const WebCore::IntRect&);
+#endif
+
#if ENABLE(TIZEN_CSP)
void setContentSecurityPolicy(const String& policy, WebCore::ContentSecurityPolicy::HeaderType type);
#endif
void useSettingsFont();
#endif
+#if ENABLE(TIZEN_FOCUS_UI)
+ void setSpatialNavigationEnabled(bool);
+#endif
+
private:
WebPageProxy(PageClient*, PassRefPtr<WebProcessProxy>, WebPageGroup*, uint64_t pageID);
#if ENABLE(TIZEN_FILE_SYSTEM)
RefPtr<Messages::WebPageProxy::ExceededLocalFileSystemQuota::DelayedReply> m_exceededLocalFileSystemQuotaReply;
#endif
+
+#if ENABLE(TIZEN_FOCUS_UI)
+ bool m_spatialNavigationEnabled;
+#endif
};
} // namespace WebKit
#endif
#if ENABLE(TIZEN_SCREEN_READER)
- DidScreenReaderFocusRectChanged(WebCore::IntRect rect)
DidScreenReaderTextChanged(WTF::String text)
#endif
+#if ENABLE(TIZEN_SCREEN_READER) || ENABLE(TIZEN_FOCUS_UI)
+ DidChangeFocusedRect(WebCore::IntRect rect)
+#endif
+
#if ENABLE(TIZEN_INDEXED_DATABASE)
ExceededIndexedDatabaseQuota(uint64_t frameID, WTF::String originIdentifier, int64_t currentUsage) -> (bool returnValue) Delayed
#endif
#if ENABLE(TIZEN_ISF_PORT)
const unsigned InputMethodContextEfl::maxContextSize = 10;
+Ecore_X_Atom InputMethodContextEfl::s_externalKeyboardProperty = 0;
+bool InputMethodContextEfl::s_shouldUseExternalKeyboard = false;
+
+void InputMethodContextEfl::initializeExternalKeyboard()
+{
+ s_externalKeyboardProperty = ecore_x_atom_get("X External Keyboard Exist");
+ if (!s_externalKeyboardProperty)
+ return;
+
+ Ecore_X_Window rootWin = ecore_x_window_root_first_get();
+ ecore_x_event_mask_set(rootWin, ECORE_X_EVENT_MASK_WINDOW_PROPERTY);
+
+ ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROPERTY, windowPropertyChanged, 0);
+
+ unsigned int value;
+ if (ecore_x_window_prop_card32_get(rootWin, s_externalKeyboardProperty, &value, 1) <= 0)
+ return;
+
+ s_shouldUseExternalKeyboard = value;
+}
+
+Eina_Bool InputMethodContextEfl::windowPropertyChanged(void*, int, void* event)
+{
+ Ecore_X_Event_Window_Property* propertyEvent = static_cast<Ecore_X_Event_Window_Property*>(event);
+
+ if (propertyEvent->atom != s_externalKeyboardProperty)
+ return ECORE_CALLBACK_PASS_ON;
+
+ unsigned int value;
+ if (ecore_x_window_prop_card32_get(propertyEvent->win, s_externalKeyboardProperty, &value, 1) <= 0 || s_shouldUseExternalKeyboard == value)
+ return ECORE_CALLBACK_PASS_ON;
+
+ s_shouldUseExternalKeyboard = value;
+
+#if ENABLE(TIZEN_FOCUS_UI)
+ if (!s_shouldUseExternalKeyboard) {
+ Vector<RefPtr<WebPageProxy> > pages;
+ EwkViewImpl::pages(pages);
+
+ for (size_t i = 0; i < pages.size(); ++i)
+ pages[i]->setSpatialNavigationEnabled(false);
+ }
+#endif
+
+ return ECORE_CALLBACK_PASS_ON;
+}
#endif
InputMethodContextEfl::InputMethodContextEfl(EwkViewImpl* viewImpl, PassOwnPtr<Ecore_IMF_Context> context)
, m_fakeKeyEventTimer(this, &InputMethodContextEfl::fakeKeyEventTimerFired)
#endif
{
-#if !ENABLE(TIZEN_ISF_PORT)
+#if ENABLE(TIZEN_ISF_PORT)
+ if (!s_externalKeyboardProperty)
+ initializeExternalKeyboard();
+#else
ASSERT(context);
ecore_imf_context_event_callback_add(m_context.get(), ECORE_IMF_CALLBACK_PREEDIT_CHANGED, onIMFPreeditSequenceChanged, this);
ecore_imf_context_event_callback_add(m_context.get(), ECORE_IMF_CALLBACK_COMMIT, onIMFInputSequenceComplete, this);
void InputMethodContextEfl::handleKeyDownEvent(const Evas_Event_Key_Down* downEvent, bool* isFiltered)
{
+#if ENABLE(TIZEN_FOCUS_UI)
+ if (s_shouldUseExternalKeyboard)
+ m_viewImpl->page()->setSpatialNavigationEnabled(true);
+#endif
+
#if ENABLE(TIZEN_ISF_PORT)
if (!m_context)
return;
#include <wtf/OwnPtr.h>
#include <wtf/PassOwnPtr.h>
+#if ENABLE(TIZEN_ISF_PORT)
+#include <Ecore_X.h>
+#endif
+
class EwkViewImpl;
namespace WebKit {
void updateTextInputState();
#if ENABLE(TIZEN_ISF_PORT)
+ static bool shouldUseExternalKeyboard() { return s_shouldUseExternalKeyboard; }
+
bool isShow();
Ecore_IMF_Autocapital_Type autoCapitalType();
void onFocusIn();
static void onIMFPreeditSequenceChanged(void* data, Ecore_IMF_Context*, void* eventInfo);
#if ENABLE(TIZEN_ISF_PORT)
- void initializeIMFContext(Ecore_IMF_Context*, Ecore_IMF_Input_Panel_Layout, int, Ecore_IMF_Input_Panel_Return_Key_Type);
+ static void initializeExternalKeyboard();
+ static Eina_Bool windowPropertyChanged(void*, int, void*);
static void onIMFInputPanelStateChanged(void*, Ecore_IMF_Context*, int);
static void onIMFInputPanelGeometryChanged(void*, Ecore_IMF_Context*, int);
static Eina_Bool onIMFRetrieveSurrounding(void*, Ecore_IMF_Context*, char**, int*);
static void onIMFDeleteSurrounding(void*, Ecore_IMF_Context*, void*);
+ void initializeIMFContext(Ecore_IMF_Context*, Ecore_IMF_Input_Panel_Layout, int, Ecore_IMF_Input_Panel_Return_Key_Type);
+
PassOwnPtr<Ecore_IMF_Context> takeContext(uintptr_t);
void setIMFContext(const EditorState&);
void revertIMFContext();
#if ENABLE(TIZEN_ISF_PORT)
static const unsigned maxContextSize;
+ static Ecore_X_Atom s_externalKeyboardProperty;
+ static bool s_shouldUseExternalKeyboard;
+
Vector<std::pair<uintptr_t, OwnPtr<Ecore_IMF_Context> > > m_contextList;
uintptr_t m_contextID;
int m_state;
process()->send(Messages::WebPage::ClearScreenReader(), m_pageID);
}
-void WebPageProxy::didScreenReaderFocusRectChanged(const IntRect& rect)
+void WebPageProxy::didScreenReaderTextChanged(const String& text)
+{
+ ScreenReaderProxy::screenReader().setText(text);
+}
+#endif
+
+#if ENABLE(TIZEN_SCREEN_READER) || ENABLE(TIZEN_FOCUS_UI)
+void WebPageProxy::didChangeFocusedRect(const IntRect& rect)
{
#if ENABLE(TIZEN_WEBKIT2_FOCUS_RING)
FocusRing* focusRing = ewkViewGetFocusRing(viewWidget());
#else
UNUSED_PARAM(rect);
#endif
-}
-void WebPageProxy::didScreenReaderTextChanged(const String& text)
-{
- ScreenReaderProxy::screenReader().setText(text);
}
#endif
}
#endif
+#if ENABLE(TIZEN_FOCUS_UI)
+void WebPageProxy::setSpatialNavigationEnabled(bool enabled)
+{
+ if (m_spatialNavigationEnabled == enabled)
+ return;
+
+ m_spatialNavigationEnabled = enabled;
+
+ if (enabled)
+ static_cast<PageClientImpl*>(m_pageClient)->viewImpl()->focusRing->setImage(FOCUS_UI_FOCUS_RING_IMAGE_PATH, 4, 2);
+ else
+ static_cast<PageClientImpl*>(m_pageClient)->viewImpl()->focusRing->setImage(String(), 0, 0);
+
+ process()->send(Messages::WebPage::SetSpatialNavigationEnabled(enabled), m_pageID);
+}
+#endif
} // namespace WebKit
nodeRect.setY(nodeRect.y() / m_page->pageScaleFactor());
}
m_page->send(Messages::WebPageProxy::FocusedNodeChanged(nodeRect));
+
+#if ENABLE(TIZEN_FOCUS_UI)
+ if (m_page->corePage()->settings()->isSpatialNavigationEnabled())
+ m_page->didChangeFocusedRect(m_page->corePage()->focusController()->focusedOrMainFrame()->document()->focusedNode());
+#endif
#else
notImplemented();
#endif
void WebChromeClient::delegatedScrollRequested(const IntPoint& scrollOffset)
{
m_page->pageDidRequestScroll(scrollOffset);
+
+#if OS(TIZEN)
+ m_page->didChangeContents(m_page->bounds());
+#endif
}
#endif
WebCore::IntRect nodeRect(WebCore::Node*) const;
#endif
+#if ENABLE(TIZEN_SCREEN_READER) || ENABLE(TIZEN_FOCUS_UI)
+ void didChangeFocusedRect(WebCore::Node*);
+#endif
+
#if ENABLE(TIZEN_WEBKIT2_POPUP_INTERNAL)
void notifyTransitionToCommitted(bool);
#endif
void didChangeContents(const WebCore::IntRect&);
#endif
+#if ENABLE(TIZEN_FOCUS_UI)
+ void setSpatialNavigationEnabled(bool);
+#endif
+
private:
WebPage(uint64_t pageID, const WebPageCreationParameters&);
OwnPtr<ScreenReader> m_screenReader;
#endif
+#if ENABLE(TIZEN_SCREEN_READER) || ENABLE(TIZEN_FOCUS_UI)
+ WebCore::IntRect m_focusedRect;
+#endif
+
#if ENABLE(TIZEN_WEBKIT2_TEXT_SELECTION)
EditorState m_editorState;
#endif
#if ENABLE(TIZEN_USE_SETTINGS_FONT)
UseSettingsFont()
#endif
+
+#if ENABLE(TIZEN_FOCUS_UI)
+ SetSpatialNavigationEnabled(bool enabled)
+#endif
}
#endif
#if ENABLE(TIZEN_SCREEN_READER)
-static void sendScreenReaderFocusRect(WebPage* page, ScreenReader* screenReader)
-{
- Node* node = screenReader->getFocusedNode();
- IntRect rect;
-
- if (node) {
- bool isImage = false;
- if (node->isElementNode()) {
- Element* element = static_cast<Element*>(node);
- isImage = !element->getAttribute(element->imageSourceAttributeName()).isEmpty();
- }
- rect = getNodeRect(node, node, isImage);
- }
-
- screenReader->setFocusedRect(rect);
- page->send(Messages::WebPageProxy::DidScreenReaderFocusRectChanged(rect));
-}
-
void WebPage::moveScreenReaderFocus(bool forward, bool& result)
{
if (!m_screenReader)
m_screenReader = ScreenReader::create(this);
result = m_screenReader->moveFocus(forward);
- sendScreenReaderFocusRect(this, m_screenReader.get());
+ didChangeFocusedRect(m_screenReader->getFocusedNode());
}
void WebPage::moveScreenReaderFocusByPoint(const IntPoint& point)
if (!m_screenReader->moveFocus(point))
return;
- sendScreenReaderFocusRect(this, m_screenReader.get());
+ didChangeFocusedRect(m_screenReader->getFocusedNode());
}
void WebPage::clearScreenReaderFocus()
if (!m_screenReader || !m_screenReader->getFocusedNode())
return;
- sendScreenReaderFocusRect(this, m_screenReader.get());
+ didChangeFocusedRect(m_screenReader->getFocusedNode());
}
void WebPage::updateScreenReaderFocus(RenderObject* object)
else if (!m_screenReader->rendererWillBeDestroyed(object))
return;
- sendScreenReaderFocusRect(this, m_screenReader.get());
+ m_focusedRect = IntRect();
+ didChangeFocusedRect(m_screenReader->getFocusedNode());
}
void WebPage::clearScreenReader()
}
#endif
+#if ENABLE(TIZEN_SCREEN_READER) || ENABLE(TIZEN_FOCUS_UI)
+void WebPage::didChangeFocusedRect(WebCore::Node* node)
+{
+ m_focusedRect = nodeRect(node);
+ send(Messages::WebPageProxy::DidChangeFocusedRect(m_focusedRect));
+}
+#endif
+
#if ENABLE(TIZEN_WEBKIT2_POPUP_INTERNAL)
// FIXME: Currently with cached pages, hiding Popup list menu is not working correctly.
// This patch is a fix allowing any popup list menu to get close for any page navigation.
}
#endif
-#if ENABLE(TIZEN_SCREEN_READER)
- if (m_screenReader && rect.intersects(m_screenReader->focusedRect()))
- recalcScreenReaderFocusRect();
+#if ENABLE(TIZEN_SCREEN_READER) || ENABLE(TIZEN_FOCUS_UI)
+ if (rect.intersects(m_focusedRect)) {
+ if (m_screenReader)
+ didChangeFocusedRect(m_screenReader->getFocusedNode());
+ else if (m_page->settings()->isSpatialNavigationEnabled())
+ didChangeFocusedRect(frame->document()->focusedNode());
+ }
#endif
}
+
+#if ENABLE(TIZEN_FOCUS_UI)
+void WebPage::setSpatialNavigationEnabled(bool enabled)
+{
+ m_page->settings()->setSpatialNavigationEnabled(enabled);
+}
+#endif
#endif // #if OS(TIZEN)
} // namespace WebKit
void ScreenReader::clearFocus()
{
m_focusedObject = 0;
- m_focusedRect = IntRect();
m_hasFocus = false;
m_page->send(Messages::WebPageProxy::DidScreenReaderTextChanged(emptyString()));
}
bool rendererWillBeDestroyed(WebCore::RenderObject*);
void clearFocus();
- const WebCore::IntRect& focusedRect() const { return m_focusedRect; }
- void setFocusedRect(const WebCore::IntRect& rect) { m_focusedRect = rect; }
-
private:
ScreenReader(WebPage*);
WebPage* m_page;
WebCore::RenderObject* m_focusedObject;
- WebCore::IntRect m_focusedRect;
bool m_hasFocus;
bool m_isForward;
ADD_DEFINITIONS(-DHAVE_ACCESSIBILITY=1)
ENDIF()
+SET(ENABLE_TIZEN_FOCUS_UI 1)
+ADD_DEFINITIONS(-DENABLE_TIZEN_FOCUS_UI=1)
+
INCLUDE_IF_EXISTS(${CMAKE_CURRENT_SOURCE_DIR}/Source/cmake/OptionsExperimental.cmake)
MESSAGE("Finish to check Tizen dependencies")