#include "config.h"
#include "WebPage.h"
+#include "EditorState.h"
#include "NamedNodeMap.h"
#include "NotImplemented.h"
#include "WebEvent.h"
#endif
#if ENABLE(TIZEN_CLIPBOARD) || ENABLE(TIZEN_PASTEBOARD)
-#include <WebCore/ClipboardEfl.h>
+#include <WebCore/ClipboardTizen.h>
#endif
#if ENABLE(TIZEN_PASTEBOARD)
#include <WebCore/Pasteboard.h>
#endif
-#if ENABLE(TIZEN_WEBKIT2_REMOTE_WEB_INSPECTOR)
-#include "WebInspectorServerEfl.h"
+#if ENABLE(TIZEN_REMOTE_WEB_INSPECTOR)
+#include "WebInspectorServerTizen.h"
#endif
#if ENABLE(TIZEN_WEB_STORAGE)
#endif
#if ENABLE(TIZEN_ISF_PORT)
-#include "WebEditorClient.h"
#include <WebCore/Text.h>
+#include <WebCore/EditorClient.h>
+#endif
+
+#if ENABLE(TIZEN_INPUT_TAG_EXTENSION) || ENABLE(TIZEN_WEBKIT2_FORM_DATABASE)
+#include "EditorClient.h"
#endif
#if ENABLE(TIZEN_DATALIST_ELEMENT)
#if ENABLE(TIZEN_WEBKIT2_TEXT_SELECTION)
#include "htmlediting.h"
#endif
+
+#if ENABLE(TIZEN_LINK_MAGNIFIER)
+#include "LinkMagnifier.h"
+#endif
+
+#if ENABLE(TIZEN_SCREEN_READER)
+#include "WebEventConversion.h"
+#endif
+
+#if ENABLE(TIZEN_SCREEN_READER) || ENABLE(TIZEN_FOCUS_UI) || ENABLE(TIZEN_WEBKIT2_TEXT_SELECTION)
+#include <WebCore/HTMLAreaElement.h>
+#endif
+
+#if ENABLE(TIZEN_CSP)
+#include <WebCore/ContentSecurityPolicy.h>
+#endif
+
+#if ENABLE(TIZEN_OFFLINE_PAGE_SAVE)
+#include "WebPageSerializerTizen.h"
+#endif
+
+#if ENABLE(TIZEN_USE_SETTINGS_FONT)
+#include "fontconfig/fontconfig.h"
+#include <WebCore/FontCache.h>
+#endif
+
+#if ENABLE(TIZEN_WEBKIT2_TEXT_SELECTION)
+#include "visible_units.h"
+#endif
#endif // #if OS(TIZEN)
using namespace WebCore;
{
Settings* settings = m_page->settings();
settings->setInteractiveFormValidationEnabled(store.getBoolValueForKey(WebPreferencesKey::interactiveFormValidationEnabledKey()));
- settings->setViewWidth(store.getUInt32ValueForKey(WebPreferencesKey::viewWidthKey()));
- settings->setViewHeight(store.getUInt32ValueForKey(WebPreferencesKey::viewHeightKey()));
settings->setUsesEncodingDetector(store.getBoolValueForKey(WebPreferencesKey::usesEncodingDetectorKey()));
#if ENABLE(TIZEN_LOAD_REMOTE_IMAGES)
settings->setLoadRemoteImages(store.getBoolValueForKey(WebPreferencesKey::loadRemoteImagesKey()));
#endif
+#if ENABLE(TIZEN_LINK_EFFECT)
+ settings->setLinkEffectEnabled(store.getBoolValueForKey(WebPreferencesKey::linkEffectEnabledKey()));
+#endif
#if ENABLE(TIZEN_ISF_PORT)
settings->setEnableDefaultKeypad(store.getBoolValueForKey(WebPreferencesKey::defaultKeypadEnabledKey()));
#endif
theme->setThemePath(themePath);
}
+static Frame* targetFrameForEditing(WebPage* page)
+{
+ Frame* frame = page->corePage()->focusController()->focusedOrMainFrame();
+ if (!frame)
+ return 0;
+
+ Editor* editor = frame->editor();
+ if (!editor->canEdit())
+ return 0;
+
+ if (editor->hasComposition()) {
+ // We should verify the parent node of this IME composition node are
+ // editable because JavaScript may delete a parent node of the composition
+ // node. In this case, WebKit crashes while deleting texts from the parent
+ // node, which doesn't exist any longer.
+ if (PassRefPtr<Range> range = editor->compositionRange()) {
+ Node* node = range->startContainer();
+ if (!node || !node->isContentEditable())
+ return 0;
+ }
+ }
+
+ return frame;
+}
+
+void WebPage::confirmComposition(const String& compositionString)
+{
+ Frame* targetFrame = targetFrameForEditing(this);
+ if (!targetFrame)
+ return;
+
+#if ENABLE(TIZEN_ISF_PORT)
+ if (m_prepareKeyDownEvent) {
+ m_keyPressCommands.append(adoptPtr(new ConfirmCompositionKeyPressCommand(compositionString)));
+ return;
+ }
+#endif
+
+ targetFrame->editor()->confirmComposition(compositionString);
+
+#if ENABLE(TIZEN_ISF_PORT)
+ m_page->editorClient()->respondToChangedSelection(targetFrame);
+#endif
+}
+
+void WebPage::setComposition(const String& compositionString, const Vector<WebCore::CompositionUnderline>& underlines, uint64_t cursorPosition)
+{
+ Frame* targetFrame = targetFrameForEditing(this);
+ if (!targetFrame)
+ return;
+
+#if ENABLE(TIZEN_ISF_PORT)
+ if (!targetFrame->editor()->hasComposition() && compositionString.isEmpty())
+ return;
+
+ if (m_prepareKeyDownEvent) {
+ m_keyPressCommands.append(adoptPtr(new SetCompositionKeyPressCommand(compositionString, underlines, cursorPosition)));
+ return;
+ }
+
+ if (targetFrame->selection()->rootEditableElement()) {
+ HTMLTextFormControlElement* textFormControl = toTextFormControl(targetFrame->selection()->rootEditableElement()->shadowAncestorNode());
+ if (textFormControl && textFormControl->maxLength() >= 0) {
+ unsigned availableLength = textFormControl->maxLength() - textFormControl->value().length();
+ if (targetFrame->editor()->hasComposition())
+ availableLength += (targetFrame->editor()->compositionEnd() - targetFrame->editor()->compositionStart());
+ if (!availableLength)
+ return;
+
+ if (availableLength < compositionString.length()) {
+ String newCompositionString = compositionString.substring(0, availableLength);
+ Vector<CompositionUnderline> newUnderlines;
+ size_t numUnderlines = underlines.size();
+ for (size_t index = 0; index < numUnderlines; ++index) {
+ if (underlines[index].startOffset < availableLength) {
+ newUnderlines.append(underlines[index]);
+ if (newUnderlines.last().endOffset > availableLength)
+ newUnderlines.last().endOffset = availableLength;
+ }
+ }
+ targetFrame->editor()->setComposition(newCompositionString, newUnderlines, cursorPosition, 0);
+ return;
+ }
+ }
+ }
+#endif
+
+ targetFrame->editor()->setComposition(compositionString, underlines, cursorPosition, 0);
+
+#if ENABLE(TIZEN_ISF_PORT)
+ m_page->editorClient()->respondToChangedSelection(targetFrame);
+#endif
+}
+
+void WebPage::cancelComposition()
+{
+ Frame* frame = m_page->focusController()->focusedOrMainFrame();
+ if (!frame)
+ return;
+
+ frame->editor()->cancelComposition();
+}
+
#if OS(TIZEN)
#if ENABLE(TIZEN_WEBKIT2_TILED_BACKING_STORE)
}
#endif
-void WebPage::confirmComposition(const String& compositionString)
-{
- Frame* frame = m_page->focusController()->focusedOrMainFrame();
- if (!frame || !frame->editor()->canEdit())
- return;
- frame->editor()->confirmComposition(compositionString);
-#if ENABLE(TIZEN_ISF_PORT)
- send(Messages::WebPageProxy::UpdateCursorPosition());
-#endif
-}
-
-void WebPage::setComposition(const String& compositionString, const Vector<WebCore::CompositionUnderline>& underlines, uint64_t cursorPosition)
-{
- Frame* frame = m_page->focusController()->focusedOrMainFrame();
- if (!frame || !frame->editor()->canEdit())
- return;
-#if ENABLE(TIZEN_ISF_PORT)
- if (frame->selection()->rootEditableElement()) {
- HTMLTextFormControlElement* textFormControl = toTextFormControl(frame->selection()->rootEditableElement()->shadowAncestorNode());
- if (textFormControl && textFormControl->maxLength() >= 0) {
- unsigned availableLength = textFormControl->maxLength() - textFormControl->value().length();
- if (frame->editor()->hasComposition())
- availableLength += (frame->editor()->compositionEnd() - frame->editor()->compositionStart());
- if (!availableLength)
- return;
-
- if (availableLength < compositionString.length()) {
- String newCompositionString = compositionString.substring(0, availableLength);
- Vector<CompositionUnderline> newUnderlines;
- size_t numUnderlines = underlines.size();
- for (size_t index = 0; index < numUnderlines; ++index) {
- if (underlines[index].startOffset < availableLength) {
- newUnderlines.append(underlines[index]);
- if (newUnderlines.last().endOffset > availableLength)
- newUnderlines.last().endOffset = availableLength;
- }
- }
- frame->editor()->setComposition(newCompositionString, newUnderlines, cursorPosition, 0);
- return;
- }
- }
- }
-#endif
- frame->editor()->setComposition(compositionString, underlines, cursorPosition, 0);
-}
-
#if ENABLE(TIZEN_TEXT_CARET_HANDLING_WK2)
-bool WebPage::setCaretPosition(const WebCore::IntPoint& pos)
+bool WebPage::setCaretPosition(const IntPoint& pos)
{
Frame* frame = m_page->focusController()->focusedOrMainFrame();
if (!frame)
return false;
- WebCore::FrameSelection* controller = frame->selection();
+ FrameSelection* controller = frame->selection();
if (!controller)
return false;
if (!frameView)
return false;
- WebCore::IntPoint point = m_page->mainFrame()->view()->windowToContents(pos);
- WebCore::HitTestResult result = m_page->mainFrame()->eventHandler()->hitTestResultAtPoint(point, /*allowShadowContent*/ true, /*ignoreClipping*/ true);
+ IntPoint point = m_page->mainFrame()->view()->windowToContents(pos);
+ HitTestResult result = m_page->mainFrame()->eventHandler()->hitTestResultAtPoint(point, /*allowShadowContent*/ true, /*ignoreClipping*/ true);
if (result.scrollbar())
return false;
- WebCore::Node* innerNode = result.innerNode();
+ Node* innerNode = result.innerNode();
if (!innerNode || !innerNode->renderer())
return false;
- WebCore::VisiblePosition visiblePos;
-
- const int boundariesWidth = 2;
+ VisiblePosition visiblePos;
// we check if content is richly editable - because those input field behave other than plain text ones
// sometimes they may consists a node structure and they need special approach
if (innerNode->rendererIsRichlyEditable()) {
// point gets inner node local coordinates
point = flooredIntPoint(result.localPoint());
- WebCore::IntRect rect = innerNode->renderer()->absoluteBoundingBoxRect(true);
+ IntRect rect = innerNode->renderer()->absoluteBoundingBoxRect(true);
// it is not the best way to do this, but it is not as slow and it works - so maybe in the future someone
// will have a better idea how to solve it
// all those getting nodes rects are needed to bypass WebCore's methods of positioning caret when user
// is clicking outside a node - and cheat WebCore telling it that actually we clicked into input field
// node, not outside of it
- WebCore::Node* deepInnerNode = innerNode->renderer()->positionForPoint(point).deepEquivalent().deprecatedNode();
+ Node* deepInnerNode = innerNode->renderer()->positionForPoint(point).deepEquivalent().deprecatedNode();
if (!deepInnerNode || !deepInnerNode->renderer())
return false;
// so we get a base node rectange
- WebCore::IntRect deepNodeRect = deepInnerNode->renderer()->absoluteBoundingBoxRect(true);
+ IntRect deepNodeRect = deepInnerNode->renderer()->absoluteBoundingBoxRect(true);
// we modify our local point to adjust it to base node local coordinates
point.move(rect.x() - deepNodeRect.x(), rect.y() - deepNodeRect.y());
if (!controller->isCaret() || !controller->caretRenderer())
return false;
- const WebCore::Node* node = controller->start().deprecatedNode();
+ const Node* node = controller->start().deprecatedNode();
if (!node || !node->renderer())
return false;
- WebCore::IntRect rect = controller->caretRenderer()->absoluteBoundingBoxRect(true);
+ Element* currentRootEditableElement = node->rootEditableElement();
+ Element* newRootEditableElement = innerNode->rootEditableElement();
+ if (currentRootEditableElement != newRootEditableElement)
+ return false;
+
+ IntRect rect = controller->caretRenderer()->absoluteBoundingBoxRect(true);
-// FIXME: The below codes should be updated to apply the positon of focusedFrame.
-#if 0
+ // The below wirtten code is not correct way to implement. Presntly the is no
+ // other working way. To be replaced by better logic
// here we also cheat input field that we actually are just inside of if
- if (point.x() < rect.x())
- point.setX(rect.x());
- else if (point.x() > rect.maxX())
- point.setX(rect.maxX());
- if (point.y() < rect.y() + boundariesWidth)
- point.setY(rect.y() + boundariesWidth);
- else if (point.y() >= rect.maxY() - boundariesWidth)
- point.setY(rect.maxY() - boundariesWidth - 1);
-#endif
+ IntPoint focusedFramePoint = frame->view()->windowToContents(pos);
+ IntPoint oldFocusedFramePoint = focusedFramePoint;
+
+ const int boundariesWidth = 2;
+ if (focusedFramePoint.x() < rect.x())
+ focusedFramePoint.setX(rect.x());
+ else if (focusedFramePoint.x() > rect.maxX())
+ focusedFramePoint.setX(rect.maxX());
+ if (focusedFramePoint.y() < rect.y() + boundariesWidth)
+ focusedFramePoint.setY(rect.y() + boundariesWidth);
+ else if (focusedFramePoint.y() >= rect.maxY() - boundariesWidth)
+ focusedFramePoint.setY(rect.maxY() - boundariesWidth - 1);
+
+ int diffX = focusedFramePoint.x() - oldFocusedFramePoint.x();
+ int diffY = focusedFramePoint.y() - oldFocusedFramePoint.y();
+ point.setX((point.x())+diffX);
+ point.setY((point.y())+diffY);
// hit test with fake (adjusted) coordinates
- WebCore::IntPoint hitTestPoint = m_page->mainFrame()->view()->windowToContents(point);
- WebCore::HitTestResult newResult = m_page->mainFrame()->eventHandler()->hitTestResultAtPoint(hitTestPoint, /*allowShadowContent*/ true, /*ignoreClipping*/ true);
+ IntPoint hitTestPoint = m_page->mainFrame()->view()->windowToContents(point);
+ HitTestResult newResult = m_page->mainFrame()->eventHandler()->hitTestResultAtPoint(hitTestPoint, /*allowShadowContent*/ true, /*ignoreClipping*/ true);
if (!newResult.isContentEditable())
return false;
- WebCore::Node* newInnerNode = newResult.innerNode();
+ Node* newInnerNode = newResult.innerNode();
if (!newInnerNode || !newInnerNode->renderer())
return false;
}
// create visible selection from visible position
- WebCore::VisibleSelection newSelection = WebCore::VisibleSelection(visiblePos);
- controller->setSelection(newSelection, WebCore::CharacterGranularity);
+ VisibleSelection newSelection = VisibleSelection(visiblePos);
+ controller->setSelection(newSelection, CharacterGranularity);
// after setting selection caret blinking is suspended by default so we are unsuspedning it
controller->setCaretBlinkingSuspended(false);
return true;
}
-void WebPage::getCaretPosition(WebCore::IntRect& rect)
+void WebPage::getCaretPosition(IntRect& rect)
{
Frame* frame = m_page->focusController()->focusedOrMainFrame();
if (!frame)
return;
- WebCore::FrameSelection* controller = frame->selection();
+ FrameSelection* controller = frame->selection();
if (!controller)
return;
- WebCore::Node* node = controller->start().deprecatedNode();
+ Node* node = controller->start().deprecatedNode();
if (!node || !node->renderer() || !node->isContentEditable())
return;
#endif
#if ENABLE(TIZEN_ISF_PORT)
-void WebPage::getCursorOffsetPosition(int& offset)
+void WebPage::didCancelComposition(Node* valueChangedNode)
{
- offset = 0;
Frame* frame = m_page->focusController()->focusedOrMainFrame();
- if (!frame || !frame->editor()->canEdit())
+ if (!frame || frame->editor()->ignoreCompositionSelectionChange() || !valueChangedNode->containsIncludingShadowDOM(frame->editor()->compositionNode()))
return;
- Position base = frame->selection()->base();
- Node* baseNode = base.containerNode();
- if (baseNode)
- offset = baseNode->isTextNode() ? base.offsetInContainerNode() : 0;
+ frame->editor()->cancelComposition();
+ send(Messages::WebPageProxy::DidCancelComposition());
+}
+
+void WebPage::prepareKeyDownEvent()
+{
+ m_prepareKeyDownEvent = true;
+ m_keyPressCommands.clear();
}
-void WebPage::getContentOfPosition(String& content)
+void WebPage::swapKeyPressCommands(Vector<OwnPtr<KeyPressCommand> >& commands)
{
+ m_keyPressCommands.swap(commands);
+}
+
+void WebPage::getCursorOffset(int& offset)
+{
+ offset = 0;
Frame* frame = m_page->focusController()->focusedOrMainFrame();
if (!frame || !frame->editor()->canEdit())
return;
Position base = frame->selection()->base();
Node* baseNode = base.containerNode();
- if (baseNode && baseNode->isTextNode())
- content = baseNode->textContent();
- else
- content = String();
+ if (baseNode)
+ offset = baseNode->isTextNode() ? base.offsetInContainerNode() : 0;
}
-void WebPage::deleteSurroundingPosition(bool& result)
+void WebPage::getSurroundingTextAndCursorOffset(String& text, int& offset)
{
+ text = String();
+ offset = 0;
+
Frame* frame = m_page->focusController()->focusedOrMainFrame();
if (!frame || !frame->editor()->canEdit())
return;
- frame->editor()->deleteWithDirection(DirectionBackward, CharacterGranularity, false, true);
+ Position base = frame->selection()->base();
+ Node* baseNode = base.containerNode();
+ if (baseNode && baseNode->isTextNode()) {
+ text = baseNode->textContent();
+ offset = base.offsetInContainerNode();
+ }
}
void WebPage::getSelectionRect(bool isOnlyEditable, IntRect& rect)
if (selection->isCaret())
rect = frame->view()->contentsToWindow(selection->absoluteCaretBounds());
else if (selection->isRange())
- rect = frame->view()->contentsToWindow(enclosingIntRect(selection->bounds()));
+ rect = frame->view()->contentsToWindow(enclosingIntRect(selection->bounds(false)));
+}
+
+void WebPage::deleteSurroundingText(int offset, int count)
+{
+ Frame* frame = m_page->focusController()->focusedOrMainFrame();
+ if (!frame || !frame->editor()->canEdit())
+ return;
+
+ if (m_prepareKeyDownEvent) {
+ m_keyPressCommands.append(adoptPtr(new DeleteTextKeyPressCommand(offset, count)));
+ return;
+ }
+
+ Position base(frame->selection()->base());
+ offset += base.offsetInContainerNode();
+ base.moveToOffset(offset);
+ Position extent(base);
+ extent.moveToOffset(offset + count);
+ VisibleSelection selection(base, extent);
+ if (!selection.isRange())
+ return;
+
+ frame->selection()->setSelection(selection);
+ frame->editor()->deleteWithDirection(DirectionBackward, CharacterGranularity, false, true);
}
#endif
-#if ENABLE(TIZEN_INPUT_TAG_EXTENSION)
+#if ENABLE(TIZEN_INPUT_TAG_EXTENSION) || ENABLE(TIZEN_WEBKIT2_FORM_DATABASE)
void WebPage::setFocusedInputElementValue(const String& inputValue)
{
Frame* frame = m_page->focusController()->focusedOrMainFrame();
}
#endif
-#if ENABLE(TIZEN_WEBKIT2_HIT_TEST)
#if ENABLE(TIZEN_WEBKIT2_FOCUS_RING)
-static IntRect getFocusedRect(HitTestResult hitTestResult, Page* page)
+static IntRect getNodeRect(Node* node, Node* focusableNode, bool isImage)
{
- IntRect focusedRect = IntRect(0, 0, 0, 0);
- Node* node = hitTestResult.innerNode();
- bool isFocusRingDrawable = false;
- Node* focusableNode = node;
- while (focusableNode) {
- RenderObject* renderer = focusableNode->renderer();
- if (renderer && renderer->isRoot())
- break;
+ IntRect rect;
- if (focusableNode->isFocusable()) {
- if (focusableNode->isLink()
- || focusableNode->hasTagName(HTMLNames::inputTag)
- || focusableNode->hasTagName(HTMLNames::selectTag)
- || focusableNode->hasTagName(HTMLNames::buttonTag))
- isFocusRingDrawable = true;
- break;
- }
-
- focusableNode = focusableNode->parentNode();
- }
-
- if (!isFocusRingDrawable)
- return focusedRect;
-
- if (!hitTestResult.absoluteImageURL().isEmpty()) {
+ if (isImage) {
bool isReplaced;
IntRect imageNodeRect = pixelSnappedIntRect(node->getRect());
if (!focusableNode->renderRect(&isReplaced).isEmpty() && imageNodeRect.contains(pixelSnappedIntRect(focusableNode->getRect()))) {
// we have to get rect of focusableNode.
// for example - The rect of google logo image in www.google.com pc site's search result page is bigger than rect of focusableNode.
// for example - The rect of category menu image in www.gmarket.co.kr pc site is bigger than rect of focusableNode.
- focusedRect = pixelSnappedIntRect(focusableNode->getRect());
+ rect = pixelSnappedIntRect(focusableNode->getRect());
}
else {
// otherwise we have to get rect of imageNode.
// for example - The render rect of images in www.pudelek.pl is empty.
// for example - The rect of focusableNode of 'Test your browser GO' image in peacekeeper.futuremark.com is bigger than rect of 'Test your browser GO' image.
- focusedRect = imageNodeRect;
+ rect = imageNodeRect;
focusableNode = node;
}
} else {
// If focusedNode have multiple child nodes, we have to unite rect of child nodes.
// for example - links in www.google.com's search result page.
- IntRect tempRect = IntRect(0, 0, 0, 0);
+ IntRect tempRect;
for (Node* childNode = focusableNode->firstChild(); childNode; childNode = childNode->traverseNextNode(focusableNode)) {
bool isReplaced;
if (focusableNode->renderRect(&isReplaced).contains(childNode->getRect()))
// hence using absoluteBoundingBoxRect to get the correct bounding rect.
LayoutRect renderRect = focusableNode->renderer() ? focusableNode->renderer()->absoluteBoundingBoxRect() : focusableNode->getRect();
if (tempRect.isEmpty() || renderRect.contains(tempRect))
- focusedRect = pixelSnappedIntRect(renderRect);
+ rect = pixelSnappedIntRect(renderRect);
else
- focusedRect = tempRect;
+ rect = tempRect;
}
- // We have to get render rect from ancestor node if current focusedRect is empty.
+ // We have to get render rect from ancestor node if current rect is empty.
// for example - The rect of naver logo image in www.naver.com pc site is empty.
bool isReplaced;
- for (Node* loopNode = focusableNode; loopNode && focusedRect.isEmpty(); loopNode = loopNode->parentNode()) {
+ for (Node* loopNode = focusableNode; loopNode && rect.isEmpty(); loopNode = loopNode->parentNode()) {
RenderObject* renderer = loopNode->renderer();
if (renderer && renderer->isRoot())
break;
- focusedRect = pixelSnappedIntRect(loopNode->renderRect(&isReplaced));
+ rect = pixelSnappedIntRect(loopNode->renderRect(&isReplaced));
}
- Frame* mainFrame = page->mainFrame();
Frame* nodeFrame = focusableNode->document()->frame();
Node* owner;
- while (nodeFrame && nodeFrame != mainFrame) {
- owner = nodeFrame->ownerElement();
- if (!owner)
- break;
-
- focusedRect.setX(focusedRect.x() + owner->getRect().x());
- focusedRect.setY(focusedRect.y() + owner->getRect().y());
+ while (nodeFrame && (owner = nodeFrame->ownerElement())) {
+ rect.moveBy(owner->getRect().pixelSnappedLocation());
nodeFrame = owner->document()->frame();
}
// The y position of tab menu item in www.google.com is negative value,
// so we do not want to draw focus ring in that case.
- if ((focusedRect.x() < 0) || (focusedRect.y() < 0))
- focusedRect = IntRect(0, 0, 0, 0);
+ if ((rect.maxX() < 0) || (rect.maxY() < 0))
+ rect = IntRect();
- return focusedRect;
+ return rect;
}
#endif
+#if ENABLE(TIZEN_WEBKIT2_HIT_TEST)
+#if ENABLE(TIZEN_WEBKIT2_FOCUS_RING)
+#if ENABLE(TOUCH_ADJUSTMENT)
+static IntRect getFocusedRect(HitTestResult hitTestResult, Page* page, const IntSize& area)
+#else
+static IntRect getFocusedRect(HitTestResult hitTestResult, Page* page)
+#endif
+{
+ Node* node = hitTestResult.innerNode();
+#if ENABLE(TOUCH_ADJUSTMENT)
+ Node* adjustedNode = 0;
+ IntPoint adustedPoint;
+ Frame* mainFrame = page->mainFrame();
+ mainFrame->eventHandler()->bestClickableNodeForTouchPoint(hitTestResult.roundedPoint(), IntSize(area.width() / 2, area.height() / 2), adustedPoint, adjustedNode);
+
+ if (adjustedNode)
+ node = adjustedNode;
+#endif
+ if (!node)
+ return IntRect();
+
+ bool isFocusRingDrawable = false;
+ Node* focusableNode = node;
+ while (focusableNode) {
+ RenderObject* renderer = focusableNode->renderer();
+ if (renderer && renderer->isRoot())
+ break;
+
+ if (focusableNode->isFocusable()) {
+ if (focusableNode->isLink()
+ || focusableNode->hasTagName(HTMLNames::inputTag)
+ || focusableNode->hasTagName(HTMLNames::selectTag)
+ || focusableNode->hasTagName(HTMLNames::buttonTag))
+ isFocusRingDrawable = true;
+ break;
+ }
+
+ focusableNode = focusableNode->parentNode();
+ }
+
+ if (!isFocusRingDrawable) {
+ if (node->hasTagName(HTMLNames::imgTag))
+ return getNodeRect(node, node, !hitTestResult.absoluteImageURL().isEmpty());
+
+ return IntRect();
+ }
+
+ return getNodeRect(node, focusableNode, !hitTestResult.absoluteImageURL().isEmpty());
+}
+#endif
+
+#if ENABLE(TOUCH_ADJUSTMENT)
+void WebPage::hitTestResultAtPoint(const IntPoint& point, int hitTestMode, const IntSize& area, WebHitTestResult::Data& hitTestResultData)
+#else
void WebPage::hitTestResultAtPoint(const IntPoint& point, int hitTestMode, WebHitTestResult::Data& hitTestResultData)
+#endif
{
Frame* frame = m_page->mainFrame();
FrameView* frameView = frame->view();
hitTestResultData.absoluteMediaURL = hitTestResult.absoluteMediaURL().string();
hitTestResultData.linkLabel = hitTestResult.textContent();
hitTestResultData.linkTitle = hitTestResult.titleDisplayString();
+ hitTestResultData.isContentEditable = hitTestResult.isContentEditable();
#if ENABLE(TIZEN_DRAG_SUPPORT)
hitTestResultData.isDragSupport = hitTestResult.isDragSupport();
#endif
hitTestResultData.hitTestMode = hitTestMode;
#if ENABLE(TIZEN_WEBKIT2_FOCUS_RING)
+#if ENABLE(TOUCH_ADJUSTMENT)
+ hitTestResultData.focusedRect = getFocusedRect(hitTestResult, m_page.get(), area);
+#else
hitTestResultData.focusedRect = getFocusedRect(hitTestResult, m_page.get());
+#endif
if (hitTestResult.innerNode() && hitTestResult.innerNode()->renderer() && hitTestResult.innerNode()->renderer()->style()) {
hitTestResultData.focusedColor = hitTestResult.innerNode()->renderer()->style()->tapHighlightColor();
if (!hitTestResultData.focusedColor.hasAlpha())
}
#endif
-#if ENABLE(TIZEN_RECORDING_SURFACE_SET)
-void WebPage::recordingSurfaceSetEnableSet(bool enable)
-{
- m_recordingSurfaceSetSettings = enable;
-}
-#endif
-
#if ENABLE(TIZEN_CLIPBOARD) || ENABLE(TIZEN_PASTEBOARD)
void WebPage::setClipboardDataForPaste(const String& data, const String& type)
{
mainFrame->loader()->resumeAllLoaders();
}
+void WebPage::suspendAnimations()
+{
+ Frame* mainFrame = m_page->mainFrame();
+ if (!mainFrame)
+ return;
+
+ for (Frame* frame = mainFrame; frame; frame = frame->tree()->traverseNext())
+ frame->animation()->suspendAnimationsForDocument(frame->document());
+}
+
+void WebPage::resumeAnimations()
+{
+ Frame* mainFrame = m_page->mainFrame();
+ if (!mainFrame)
+ return;
+
+ for (Frame* frame = mainFrame; frame; frame = frame->tree()->traverseNext())
+ frame->animation()->resumeAnimationsForDocument(frame->document());
+}
+
#if ENABLE(TIZEN_SYNC_REQUEST_ANIMATION_FRAME)
void WebPage::suspendAnimationController()
{
}
#endif
-#if ENABLE(TIZEN_WEBKIT2_REMOTE_WEB_INSPECTOR)
+#if ENABLE(TIZEN_REMOTE_WEB_INSPECTOR)
void WebPage::startInspectorServer(uint32_t port, uint32_t& allocatedPort)
{
- bool ret = WebInspectorServerEfl::server()->startServer(port);
+ bool ret = WebInspectorServerTizen::server()->startServer(port);
if (ret)
- allocatedPort = WebInspectorServerEfl::server()->getServerPort();
+ allocatedPort = WebInspectorServerTizen::server()->getServerPort();
else
allocatedPort = 0;
}
void WebPage::stopInspectorServer(bool& result)
{
- result = WebInspectorServerEfl::server()->stopServer();
+ result = WebInspectorServerTizen::server()->stopServer();
}
#endif
{
RenderObject* renderer = 0;
id = 0;
- pressed = m_page->focusController()->focusedOrMainFrame()->eventHandler()->setMousePressNodeAtPoint(point, checkOverflowLayer, renderer);
+ pressed = m_page->mainFrame()->eventHandler()->setMousePressNodeAtPoint(point, checkOverflowLayer, renderer);
#if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION_ON_UI_SIDE)
if (pressed && renderer)
id = toWebGraphicsLayer(renderer->enclosingLayer()->layerForScrollingContents())->id();
}
#endif
-#if ENABLE(TIZEN_WEBKIT2_GET_TEXT_STYLE_FOR_SELECTION)
-void WebPage::getTextStyleStateForSelection()
-{
- Frame* frame = m_page->focusController()->focusedOrMainFrame();
-
- int underlineState = frame->editor()->selectionHasStyle(CSSPropertyWebkitTextDecorationsInEffect, "underline");
- int italicState = frame->editor()->selectionHasStyle(CSSPropertyFontStyle, "italic");
- int boldState = frame->editor()->selectionHasStyle(CSSPropertyFontWeight, "bold");
-
- send(Messages::WebPageProxy::DidGetTextStyleStateForSelection(underlineState, italicState, boldState));
-}
-#endif
-
#if ENABLE(TIZEN_MULTIPLE_SELECT)
void WebPage::didChangeSelectedIndexForActivePopupMenuMultiple(Vector<int32_t> newIndex)
{
size_t indexSize = newIndex.size();
for (size_t i = 0; i < indexSize; i++)
- m_activePopupMenu->didChangeSelectedIndex(i);
+ m_activePopupMenu->didChangeSelectedIndex(newIndex.at(i));
-#if !PLATFORM(EFL)
- m_activePopupMenu = 0;
+}
#endif
+
+#if ENABLE(TIZEN_OFFLINE_PAGE_SAVE)
+void WebPage::startOfflinePageSave(String subresourceFolderName)
+{
+ WebPageSerializerTizen::getSerializedPageContent(this, subresourceFolderName);
}
#endif
#if ENABLE(TIZEN_WEBKIT2_TEXT_SELECTION)
-void WebPage::selectClosestWord(const WebCore::IntPoint& point, bool isStartedTextSelectionFromOutside, bool& result)
+void WebPage::selectClosestWord(const IntPoint& point, bool& result)
{
result = false;
HitTestResult hitTestResult = mainFrame->eventHandler()->hitTestResultAtPoint(m_page->mainFrame()->view()->windowToContents(point), false);
+ Node* node = hitTestResult.innerNonSharedNode();
+ if (!node)
+ return;
+
+ Frame* newFocusFrame = node->document()->frame();
+ if (focusedFrame != newFocusFrame) {
+ m_page->focusController()->setFocusedFrame(newFocusFrame);
+ focusedFrame = newFocusFrame;
+ }
+
+ HTMLInputElement* inputElement = node->toInputElement();
+
if (hitTestResult.isContentEditable()) {
+#if ENABLE(TIZEN_INPUT_TAG_EXTENSION)
+ if (!inputElement || (inputElement
+ && !inputElement->isDateField() && !inputElement->isDateTimeField() && !inputElement->isDateTimeLocalField()
+ && !inputElement->isMonthField() && !inputElement->isTimeField() && !inputElement->isWeekField())) {
+ result = setCaretPosition(point);
+ return;
+ }
+#else
result = setCaretPosition(point);
return;
+#endif
}
- if (hitTestResult.innerNonSharedNode() && hitTestResult.innerNonSharedNode()->isTextNode()) {
- if (!isStartedTextSelectionFromOutside) {
- for (Node* node = hitTestResult.innerNonSharedNode(); node; node = node->parentNode()) {
- if (node->isFocusable()) {
- // Text selection shoud not be started when text of <button> tag is selected.
- if (node->hasTagName(HTMLNames::buttonTag))
- return;
- break;
- }
- }
- }
+#if ENABLE(TIZEN_INPUT_TAG_EXTENSION)
+ if (!node->isTextNode() && !inputElement)
+#else
+ if (!node->isTextNode())
+#endif
+ return;
+
+#if ENABLE(TIZEN_INPUT_TAG_EXTENSION)
+ if (inputElement
+ && (inputElement->isDateField() || inputElement->isDateTimeField() || inputElement->isDateTimeLocalField()
+ || inputElement->isMonthField() || inputElement->isTimeField() || inputElement->isWeekField())) {
+ if (inputElement->value().isEmpty())
+ return;
+ }
+#endif
- WebCore::FrameSelection* frameSelection = focusedFrame->selection();
+ for (Node* node = hitTestResult.innerNonSharedNode(); node; node = node->parentNode()) {
+ if (node->isFocusable()) {
+ // Text selection shoud not be started when text of <button> tag is selected.
+ if (node->hasTagName(HTMLNames::buttonTag))
+ return;
+
+ if (inputElement && inputElement->isTextButton())
+ return;
- WebCore::VisiblePosition position = mainFrame->visiblePositionForPoint(point);
- WebCore::VisibleSelection selection(position);
+ break;
+ }
+ }
- // This changes just the 'start' and 'end' positions of the VisibleSelection
- selection.expandUsingGranularity(WebCore::WordGranularity);
+ FrameSelection* frameSelection = focusedFrame->selection();
- frameSelection->setSelection(WebCore::VisibleSelection(selection.start(), selection.end()));
+ VisiblePosition position = mainFrame->visiblePositionForPoint(point);
+ VisibleSelection selection(position);
- if (!frameSelection->isRange())
- return;
+ // This changes just the 'start' and 'end' positions of the VisibleSelection
+ selection.expandUsingGranularity(WordGranularity);
- // This changes just the 'start' and 'end' positions of the VisibleSelection
- // Find handlers positions
- WebCore::IntRect leftRect, rightRect;
- getSelectionHandlers(leftRect, rightRect);
- if (leftRect.size().isZero() && rightRect.size().isZero()) {
- // Sometimes there is no selected text, but isNone() returns TRUE
- // in this case ewk_frame_selection_handlers_get() returns FALSE and handlers are invalid
- // Workaround - clear the selection.
- // Better solution would be to modify the ewk_frame_select_closest_word()
- // to not select anything in the first place (for example - don't call setSelection()
- // if there is nothing under the cursor).
- frameSelection->clear();
- return;
- }
+ FrameSelection::SetSelectionOptions options = FrameSelection::CloseTyping | FrameSelection::ClearTypingStyle | FrameSelection::DoNotSetFocus;
+ frameSelection->setSelection(VisibleSelection(selection.start(), selection.end()), options);
- result = true;
+ if (!frameSelection->isRange())
+ return;
+
+ // This changes just the 'start' and 'end' positions of the VisibleSelection
+ // Find handlers positions
+ IntRect leftRect, rightRect;
+ getSelectionHandlers(leftRect, rightRect);
+ if (leftRect.size().isZero() && rightRect.size().isZero()) {
+ // Sometimes there is no selected text, but isNone() returns TRUE
+ // in this case ewk_frame_selection_handlers_get() returns FALSE and handlers are invalid
+ // Workaround - clear the selection.
+ // Better solution would be to modify the ewk_frame_select_closest_word()
+ // to not select anything in the first place (for example - don't call setSelection()
+ // if there is nothing under the cursor).
+ selectionClearAllSelection(m_page->mainFrame());
+ return;
}
+
+ result = true;
}
-void WebPage::setLeftSelection(const WebCore::IntPoint& point, bool& result)
+void WebPage::setLeftSelection(const IntPoint& point, const int direction, int& result)
{
- result = false;
+ result = HandleMovingDirectionNone;
Frame* focusedFrame = m_page->focusController()->focusedOrMainFrame();
- WebCore::FrameSelection* frameSelection = focusedFrame->selection();
+ FrameSelection* frameSelection = focusedFrame->selection();
if (!frameSelection->isRange())
return;
- WebCore::Node* selectionEndNode = frameSelection->end().deprecatedNode();
+ Node* selectionEndNode = frameSelection->end().deprecatedNode();
if (!selectionEndNode || !selectionEndNode->renderer())
return;
if (!frameView)
return;
- WebCore::IntPoint pos = frameView->windowToContents(point);
- WebCore::IntRect leftRect, rightRect;
+ IntPoint pos = frameView->windowToContents(point);
+ IntRect leftRect, rightRect;
getSelectionHandlers(leftRect, rightRect);
- if ((rightRect.y() + rightRect.height()) < pos.y())
- pos.setY(rightRect.y() + (rightRect.height()/2));
if (selectionEndNode->rendererIsEditable() && !selectionEndNode->rendererIsRichlyEditable()) {
const int boundariesWidth = 2;
- WebCore::IntRect rect = frameSelection->caretRenderer()->absoluteBoundingBoxRect(true);
+ IntRect rect = frameSelection->caretRenderer()->absoluteBoundingBoxRect(true);
// here we cheat input field that we actually are just inside of if
if (pos.y() < rect.y() + boundariesWidth)
pos.setY(rect.y() + boundariesWidth);
pos.setY(rect.maxY() - boundariesWidth - 1);
}
- OwnPtr<WebCore::VisiblePosition> position = adoptPtr(new WebCore::VisiblePosition(focusedFrame->visiblePositionForPoint(pos)));
- WebCore::Position extent = frameSelection->extent();
+ OwnPtr<VisiblePosition> position = adoptPtr(new VisiblePosition(focusedFrame->visiblePositionForPoint(pos)));
+ Position base = frameSelection->base();
+ Position extent = frameSelection->extent();
- WebCore::Node* newSelectionStartNode = position->deepEquivalent().deprecatedNode();
+ Node* newSelectionStartNode = position->deepEquivalent().deprecatedNode();
// both start and end nodes should be in the same area type: both should be editable or both should be not editable
// Check if the new position is before the extent's position
if (newSelectionStartNode
- && selectionEndNode->isContentEditable() == newSelectionStartNode->isContentEditable()
- && WebCore::comparePositions(position->deepEquivalent(), extent) < 0) {
+ && selectionEndNode->isContentEditable() == newSelectionStartNode->isContentEditable()) {
// Change the 'base' and 'extent' positions to 'start' and 'end' positions.
// We do it, because without this, the other modification of the selection
// would destroy the 'start' and/or 'end' positions and set them to
// the 'base'/'extent' positions accordingly
- WebCore::VisibleSelection sel(frameSelection->start(), frameSelection->end());
+ VisibleSelection sel(frameSelection->start(), frameSelection->end());
frameSelection->setSelection(sel);
bool oldProhibitsScrolling = focusedFrame->view()->prohibitsScrolling();
focusedFrame->view()->setProhibitsScrolling(true);
- frameSelection->setBase(*position);
+ if (direction == HandleMovingDirectionNormal) {
+ if (comparePositions(position->deepEquivalent(), extent) < 0) {
+ frameSelection->setBase(*position);
+ result = HandleMovingDirectionNormal;
+ } else if (comparePositions(position->deepEquivalent(), extent) > 0) {
+ frameSelection->setExtent(*position);
+ frameSelection->setBase(extent);
+ result = HandleMovingDirectionReverse;
+ }
+ } else if (direction == HandleMovingDirectionReverse) {
+ if (comparePositions(position->deepEquivalent(), base) > 0) {
+ frameSelection->setExtent(*position);
+ result = HandleMovingDirectionReverse;
+ } else if (comparePositions(position->deepEquivalent(), base) < 0) {
+ frameSelection->setBase(*position);
+ frameSelection->setExtent(base);
+ result = HandleMovingDirectionNormal;
+ }
+ }
focusedFrame->view()->setProhibitsScrolling(oldProhibitsScrolling);
// This forces webkit to show selection
// m_coreFrame->invalidateSelection();
-
- result = true;
}
}
-
-void WebPage::setRightSelection(const WebCore::IntPoint& point, bool& result)
+void WebPage::setRightSelection(const IntPoint& point, const int direction, int& result)
{
- result = false;
+ result = HandleMovingDirectionNone;
Frame* focusedFrame = m_page->focusController()->focusedOrMainFrame();
- WebCore::FrameSelection* frameSelection = focusedFrame->selection();
+ FrameSelection* frameSelection = focusedFrame->selection();
if (!frameSelection->isRange())
return;
- WebCore::Node* selectionStartNode = frameSelection->start().deprecatedNode();
+ Node* selectionStartNode = frameSelection->start().deprecatedNode();
if (!selectionStartNode || !selectionStartNode->renderer())
return;
if (!frameView)
return;
- WebCore::IntPoint pos = frameView->windowToContents(point);
+ IntPoint pos = frameView->windowToContents(point);
if (selectionStartNode->rendererIsEditable() && !selectionStartNode->rendererIsRichlyEditable()) {
const int boundariesWidth = 2;
- WebCore::IntRect rect = frameSelection->caretRenderer()->absoluteBoundingBoxRect(true);
+ IntRect rect = frameSelection->caretRenderer()->absoluteBoundingBoxRect(true);
// here we cheat input field that we actually are just inside of if
if (pos.y() < rect.y() + boundariesWidth)
pos.setY(rect.y() + boundariesWidth);
pos.setY(rect.maxY() - boundariesWidth - 1);
}
- OwnPtr<WebCore::VisiblePosition> position = adoptPtr(new WebCore::VisiblePosition(focusedFrame->visiblePositionForPoint(pos)));
- WebCore::Position base = frameSelection->base();
+ OwnPtr<VisiblePosition> position = adoptPtr(new VisiblePosition(focusedFrame->visiblePositionForPoint(pos)));
+ Position base = frameSelection->base();
+ Position extent = frameSelection->extent();
- WebCore::Node* newSelectionEndNode = position->deepEquivalent().deprecatedNode();
+ Node* newSelectionEndNode = position->deepEquivalent().deprecatedNode();
// both start and end nodes should be in the same area type: both should be editable or both should be not editable
// Check if the new position is after the base's position
if (newSelectionEndNode
- && selectionStartNode->isContentEditable() == newSelectionEndNode->isContentEditable()
- && WebCore::comparePositions(position->deepEquivalent(), base) > 0) {
+ && selectionStartNode->isContentEditable() == newSelectionEndNode->isContentEditable()) {
// Change the 'base' and 'extent' positions to 'start' and 'end' positions.
// We do it, because without this, the other modifications of the selection
// would destroy the 'start' and/or 'end' positions and set them to
// the 'base'/'extent' positions accordingly
- WebCore::VisibleSelection sel(frameSelection->start(), frameSelection->end());
+ VisibleSelection sel(frameSelection->start(), frameSelection->end());
frameSelection->setSelection(sel);
bool oldProhibitsScrolling = focusedFrame->view()->prohibitsScrolling();
focusedFrame->view()->setProhibitsScrolling(true);
- frameSelection->setExtent(*position);
+ if (direction == HandleMovingDirectionNormal) {
+ if (comparePositions(position->deepEquivalent(), base) > 0) {
+ frameSelection->setExtent(*position);
+ result = HandleMovingDirectionNormal;
+ } else if (comparePositions(position->deepEquivalent(), base) < 0) {
+ frameSelection->setBase(*position);
+ frameSelection->setExtent(base);
+ result = HandleMovingDirectionReverse;
+ }
+ } else if (direction == HandleMovingDirectionReverse) {
+ if (comparePositions(position->deepEquivalent(), extent) < 0) {
+ frameSelection->setBase(*position);
+ result = HandleMovingDirectionReverse;
+ } else if (comparePositions(position->deepEquivalent(), extent) > 0) {
+ frameSelection->setExtent(*position);
+ frameSelection->setBase(extent);
+ result = HandleMovingDirectionNormal;
+ }
+ }
focusedFrame->view()->setProhibitsScrolling(oldProhibitsScrolling);
-
- result = true;
}
}
return;
// Is this check necessary? Leaving it for safety.
- WebCore::RenderView* root = focusedFrame->contentRenderer();
+ RenderView* root = focusedFrame->contentRenderer();
if (!root)
return;
- RefPtr<WebCore::Range> selectedRange = focusedFrame->selection()->toNormalizedRange();
+ RefPtr<Range> selectedRange = focusedFrame->selection()->toNormalizedRange();
- Vector<WebCore::IntRect> rects;
- selectedRange->textRects(rects, true);
+ Vector<IntRect> rects;
+ selectedRange->boundingBoxEx(rects, true);
unsigned size = rects.size();
if (size > 0) {
leftRect = rects[0];
rightRect = rects[size-1];
+
+ // If selection rect size is greater than editor rect size because of round operation,
+ // selection rect size should be changed to editor rect size.
+ if (size == 1) {
+ Element* rootEditableElement = focusedFrame->selection()->rootEditableElement();
+ if (rootEditableElement) {
+ IntRect editorRect = nodeRect(rootEditableElement);
+
+#if ENABLE(TIZEN_WEBKIT2_TEXT_SELECTION)
+ if (m_editorState.editorRect != editorRect) {
+ EditorState state = editorState();
+ state.updateEditorRectOnly = true;
+ setEditorState(state);
+ send(Messages::WebPageProxy::EditorStateChanged(state));
+ }
+#endif
+
+ if (leftRect.maxY() > editorRect.maxY()) {
+ leftRect.setY(editorRect.y());
+ leftRect.setHeight(editorRect.height());
+ }
+
+ if (rightRect.maxY() > editorRect.maxY()) {
+ rightRect.setY(editorRect.y());
+ rightRect.setHeight(editorRect.height());
+ }
+ }
+ }
+
// prevent from selecting zero-length selection
if (leftRect.x() == rightRect.x() + rightRect.width()
&& leftRect.y() == rightRect.y())
result = false;
Frame* focusedFrame = m_page->focusController()->focusedOrMainFrame();
- WebCore::FrameSelection* frameSelection = focusedFrame->selection();
+ FrameSelection* frameSelection = focusedFrame->selection();
+ if (frameSelection && frameSelection->isRange() && frameSelection->isContentEditable()) {
+ VisiblePosition visiblePos(frameSelection->extent());
+ if (visiblePos.isNull())
+ return;
+
+ focusedFrame->editor()->setIgnoreCompositionSelectionChange(true);
+ frameSelection->setSelection(VisibleSelection(visiblePos), CharacterGranularity);
+ focusedFrame->editor()->setIgnoreCompositionSelectionChange(false);
+
+ frameSelection->setCaretBlinkingSuspended(false);
+ } else
+ selectionClearAllSelection(m_page->mainFrame());
+
+ result = true;
+}
+
+void WebPage::selectionClearAllSelection(Frame* frame)
+{
+ if (!frame)
+ return;
+
+ FrameSelection* frameSelection = frame->selection();
+ if (frameSelection)
+ frameSelection->clear();
+
+ if (!frame->tree())
+ return;
+
+ if (frame->tree()->childCount() > 0) {
+ if (frame->tree()->firstChild())
+ selectionClearAllSelection(frame->tree()->firstChild());
+ } else if (frame->tree()->nextSibling())
+ selectionClearAllSelection(frame->tree()->nextSibling());
+}
+
+void WebPage::scrollContentByCharacter(const IntPoint&, int direction, bool& result)
+{
+ result = false;
+
+ Frame* focusedFrame = m_page->focusController()->focusedOrMainFrame();
+ if (!focusedFrame)
+ return;
+
+ FrameSelection* frameSelection = focusedFrame->selection();
if (!frameSelection)
return;
- if (frameSelection->isRange()) {
- if (frameSelection->isContentEditable()) {
- WebCore::VisiblePosition visiblePos(frameSelection->extent());
- if (visiblePos.isNull())
- return;
- WebCore::VisibleSelection newSelection = WebCore::VisibleSelection(visiblePos);
- frameSelection->setSelection(newSelection, WebCore::CharacterGranularity);
- frameSelection->setCaretBlinkingSuspended(false);
- } else
- frameSelection->clear();
+ VisiblePosition currentPosition = frameSelection->selection().visibleStart();
+ if (direction) {
+ if (isStartOfLine(currentPosition))
+ return;
+
+ focusedFrame->selection()->modify(FrameSelection::AlterationMove, DirectionBackward, CharacterGranularity, UserTriggered);
+ } else {
+ if (isEndOfLine(currentPosition))
+ return;
+
+ focusedFrame->selection()->modify(FrameSelection::AlterationMove, DirectionForward, CharacterGranularity, UserTriggered);
+ }
+}
+
+void WebPage::scrollContentByLine(const IntPoint&, int direction, bool& result)
+{
+ result = false;
+
+ Frame* focusedFrame = m_page->focusController()->focusedOrMainFrame();
+ if (!focusedFrame)
+ return;
+
+ FrameSelection* frameSelection = focusedFrame->selection();
+ if (!frameSelection)
+ return;
+
+ VisiblePosition currentPosition = frameSelection->selection().visibleStart();
+ if (direction) {
+ if (inSameLine(currentPosition, previousLinePosition(currentPosition, 0)))
+ return;
+
+ focusedFrame->selection()->modify(FrameSelection::AlterationMove, DirectionBackward, LineGranularity, UserTriggered);
+ } else {
+ if (inSameLine(currentPosition, nextLinePosition(currentPosition, 0)))
+ return;
+
+ focusedFrame->selection()->modify(FrameSelection::AlterationMove, DirectionForward, LineGranularity, UserTriggered);
+ }
+}
+#endif
+
+#if ENABLE(TIZEN_LINK_MAGNIFIER)
+void WebPage::getLinkMagnifierRect(const IntPoint& position, const IntSize& size)
+{
+ send(Messages::WebPageProxy::DidGetLinkMagnifierRect(position, LinkMagnifier::rect(this, position, size)));
+}
+#endif
+
+#if ENABLE(TIZEN_SCREEN_READER)
+static void sendScreenReaderFocusRect(WebPage* page, Node* node)
+{
+ bool isImage = false;
+ if (node->isElementNode()) {
+ Element* element = static_cast<Element*>(node);
+ isImage = !element->getAttribute(element->imageSourceAttributeName()).isEmpty();
+ }
+
+ page->send(Messages::WebPageProxy::DidScreenReaderFocusRectChanged(getNodeRect(node, node, isImage)));
+}
+
+void WebPage::moveScreenReaderFocus(bool forward, bool& result)
+{
+ if (!m_screenReader)
+ m_screenReader = ScreenReader::create(this);
+
+ if (!m_screenReader->moveFocus(forward)) {
+ result = false;
+ send(Messages::WebPageProxy::DidScreenReaderFocusRectChanged(IntRect()));
+ return;
+ } else {
+ result = true;
+ sendScreenReaderFocusRect(this, m_screenReader->getFocusedNode());
+ }
+}
+
+void WebPage::moveScreenReaderFocusByPoint(const IntPoint& point)
+{
+ if (!m_screenReader)
+ m_screenReader = ScreenReader::create(this);
+
+ if (!m_screenReader->moveFocus(point))
+ return;
+
+ sendScreenReaderFocusRect(this, m_screenReader->getFocusedNode());
+}
+
+void WebPage::clearScreenReaderFocus()
+{
+ if (!m_screenReader)
+ return;
+
+ m_screenReader->clearFocus();
+}
+
+void WebPage::raiseTapEvent(const IntPoint& position, const IntPoint& globalPosition, bool& result)
+{
+ result = false;
+
+#if ENABLE(GESTURE_EVENTS)
+ Frame* frame = m_page->mainFrame();
+ if (!frame->view())
+ return;
+
+ Vector<WebPlatformTouchPoint> touchPoints;
+ touchPoints.append(WebPlatformTouchPoint(0, WebPlatformTouchPoint::TouchPressed, globalPosition, position));
+
+ WebTouchEvent touchStartEvent(WebEvent::TouchStart, touchPoints, WebEvent::Modifiers(0), ecore_time_get());
+ bool handled = frame->eventHandler()->handleTouchEvent(platform(touchStartEvent));
+
+ touchPoints.at(0).setState(WebPlatformTouchPoint::TouchReleased);
+
+ WebTouchEvent touchEndEvent(WebEvent::TouchEnd, touchPoints, WebEvent::Modifiers(0), ecore_time_get());
+ handled |= frame->eventHandler()->handleTouchEvent(platform(touchEndEvent));
+ if (!handled) {
+ WebGestureEvent gestureEvent(WebEvent::GestureSingleTap, position, globalPosition, WebEvent::Modifiers(0), ecore_time_get());
+ frame->eventHandler()->handleGestureEvent(platform(gestureEvent));
result = true;
}
+#endif
+}
+
+void WebPage::adjustScreenReaderFocusedObjectValue(bool up)
+{
+ if (!m_screenReader || !m_screenReader->getFocusedNode() || !m_screenReader->getFocusedNode()->toInputElement())
+ return;
+
+ ExceptionCode ec;
+ if (up)
+ m_screenReader->getFocusedNode()->toInputElement()->stepUp(ec);
+ else
+ m_screenReader->getFocusedNode()->toInputElement()->stepDown(ec);
+}
+
+void WebPage::recalcScreenReaderFocusRect()
+{
+ if (!m_screenReader || !m_screenReader->getFocusedNode())
+ return;
+
+ sendScreenReaderFocusRect(this, m_screenReader->getFocusedNode());
+}
+
+void WebPage::updateScreenReaderFocus(RenderObject* object)
+{
+ if (!m_screenReader)
+ return;
+
+ if (!object)
+ m_screenReader->clearFocus();
+ else if (!m_screenReader->rendererWillBeDestroyed(object))
+ return;
+
+ send(Messages::WebPageProxy::DidScreenReaderFocusRectChanged(IntRect()));
+}
+
+void WebPage::clearScreenReader()
+{
+ m_screenReader.clear();
}
#endif
+#if ENABLE(TIZEN_SCREEN_READER) || ENABLE(TIZEN_FOCUS_UI) || ENABLE(TIZEN_WEBKIT2_TEXT_SELECTION)
+static LayoutRect rectToAbsoluteCoordinates(Frame* initialFrame, const LayoutRect& initialRect)
+{
+ LayoutRect rect = initialRect;
+ for (Frame* frame = initialFrame; frame; frame = frame->tree()->parent()) {
+ 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());
+ }
+ }
+ return rect;
+}
+
+IntRect WebPage::nodeRect(Node* node) const
+{
+ if (!node)
+ return IntRect();
+
+ LayoutRect rect;
+ if (node->hasTagName(HTMLNames::areaTag)) {
+ HTMLAreaElement* area = static_cast<HTMLAreaElement*>(node);
+ HTMLImageElement* image = area->imageElement();
+ if (!image || !image->renderer())
+ return IntRect();
+
+ rect = rectToAbsoluteCoordinates(area->document()->frame(), area->computeRect(area->imageElement()->renderer()));
+ } else if (node->renderer()) {
+ if (node->isDocumentNode())
+ rect = rectToAbsoluteCoordinates(static_cast<Document*>(node)->frame(), static_cast<Document*>(node)->frame()->view()->visibleContentRect());
+ else {
+ rect = node->getRect();
+ rect.intersect(node->renderer()->absoluteClippedOverflowRect());
+ rect = rectToAbsoluteCoordinates(node->document()->frame(), rect);
+
+ rect.move(node->renderer()->style()->borderLeftWidth(), node->renderer()->style()->borderTopWidth());
+ rect.setWidth(rect.width() - node->renderer()->style()->borderLeftWidth() - node->renderer()->style()->borderRightWidth());
+ rect.setHeight(rect.height() - node->renderer()->style()->borderTopWidth() - node->renderer()->style()->borderBottomWidth());
+ }
+ }
+
+ return pixelSnappedIntRect(rect);
+}
+#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.
+void WebPage::notifyTransitionToCommitted(bool forNewPage)
+{
+ if (m_activePopupMenu) {
+ TIZEN_LOGI("");
+ m_activePopupMenu->hide();
+ m_activePopupMenu = 0;
+ }
+}
+#endif
+
+#if ENABLE(TIZEN_CSP)
+void WebPage::setContentSecurityPolicy(const String& policy, uint32_t headerType)
+{
+ Frame* frame = m_page->focusController()->focusedOrMainFrame();
+ if (!frame)
+ return;
+
+ Document* document = frame->document();
+ if (!document)
+ return;
+
+ document->contentSecurityPolicy()->didReceiveHeader(policy, static_cast<WebCore::ContentSecurityPolicy::HeaderType>(headerType));
+}
+#endif
+
+#if ENABLE(TIZEN_INDEXED_DATABASE)
+void WebPage::setIndexedDatabaseDirectory(const String& path)
+{
+ m_page->group().groupSettings()->setIndexedDBDatabasePath(path);
+}
+#endif
+
+#if ENABLE(TIZEN_WEB_STORAGE)
+void WebPage::setLocalStorageDirectory(const String& path)
+{
+ m_page->settings()->setLocalStorageDatabasePath(path);
+}
+#endif
+
+#if ENABLE(TIZEN_USE_SETTINGS_FONT)
+void WebPage::useSettingsFont()
+{
+ if (!WebCore::fontCache()->isFontFamliyTizen())
+ return;
+
+ FcInitReinitialize();
+ WebCore::fontCache()->invalidate();
+
+ FrameView* frameView = m_mainFrame->coreFrame()->view();
+ if (!frameView)
+ return;
+
+ frameView->forceLayout();
+}
+#endif
+
+void WebPage::didChangeContents(const IntRect& rect)
+{
+ if (!m_page)
+ return;
+
+ Frame* frame = m_page->focusController()->focusedOrMainFrame();
+ if (!frame || !frame->view() || frame->view()->needsLayout())
+ return;
+
+#if ENABLE(TIZEN_ISF_PORT) || ENABLE(TIZEN_WEBKIT2_TEXT_SELECTION)
+ if (m_editorState.isContentEditable && rect.intersects(m_editorState.editorRect) && frame->selection()->rootEditableElement()) {
+ IntRect currentEditorRect = nodeRect(frame->selection()->rootEditableElement());
+ if (m_editorState.editorRect != currentEditorRect) {
+ m_editorState.editorRect = currentEditorRect;
+ m_editorState.updateEditorRectOnly = true;
+ send(Messages::WebPageProxy::EditorStateChanged(m_editorState));
+ }
+ }
+#endif
+}
#endif // #if OS(TIZEN)
} // namespace WebKit