2 * Copyright (C) 2010 Apple Inc. All rights reserved.
3 * Portions Copyright (c) 2010 Motorola Mobility, Inc. All rights reserved.
4 * Copyright (C) 2011 Igalia S.L.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
17 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
19 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
25 * THE POSSIBILITY OF SUCH DAMAGE.
31 #include "EditorState.h"
32 #include "NamedNodeMap.h"
33 #include "NotImplemented.h"
35 #include "WindowsKeyboardCodes.h"
36 #include <WebCore/EflKeyboardUtilities.h>
37 #include <WebCore/FocusController.h>
38 #include <WebCore/Frame.h>
39 #include <WebCore/FrameView.h>
40 #include <WebCore/KeyboardEvent.h>
41 #include <WebCore/Page.h>
42 #include <WebCore/PlatformKeyboardEvent.h>
43 #include <WebCore/RenderThemeEfl.h>
44 #include <WebCore/Settings.h>
47 #include "Arguments.h"
48 #include "GraphicsContext.h"
49 #include "WebCoreArgumentCoders.h"
52 #include "WebPageProxyMessages.h"
53 #include <WebCore/FrameView.h>
55 #if ENABLE(TIZEN_INPUT_TAG_EXTENSION)
56 #include <WebCore/HTMLInputElement.h>
57 #include <WebCore/HTMLNames.h>
60 #if ENABLE(TIZEN_MULTIPLE_SELECT)
61 #include "WebPopupMenu.h"
62 #include <WebCore/PopupMenuClient.h>
65 #if ENABLE(TIZEN_MOBILE_WEB_PRINT)
66 #include <WebCore/PlatformContextCairo.h>
69 #if ENABLE(TIZEN_CLIPBOARD) || ENABLE(TIZEN_PASTEBOARD)
70 #include <WebCore/ClipboardTizen.h>
73 #if ENABLE(TIZEN_PASTEBOARD)
74 #include <WebCore/Pasteboard.h>
77 #if ENABLE(TIZEN_WEBKIT2_REMOTE_WEB_INSPECTOR)
78 #include "WebInspectorServerEfl.h"
81 #if ENABLE(TIZEN_WEB_STORAGE)
82 #include <WebCore/GroupSettings.h>
83 #include <WebCore/PageGroup.h>
86 #if ENABLE(TIZEN_PLUGIN_SUSPEND_RESUME)
87 #include "PluginView.h"
90 #if ENABLE(TIZEN_PREFERENCE)
91 #include "WebPreferencesStore.h"
92 #include <WebCore/Settings.h>
95 #if ENABLE(TIZEN_WEBKIT2_FOCUS_RING)
96 #include <WebCore/HTMLFrameOwnerElement.h>
97 #include <WebCore/HTMLImageElement.h>
100 #if ENABLE(TIZEN_DEVICE_ORIENTATION)
101 #include "DeviceMotionClientTizen.h"
102 #include "DeviceOrientationClientTizen.h"
105 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION_ON_UI_SIDE)
106 #include "RenderLayer.h"
107 #include "WebGraphicsLayer.h"
108 #include <WebCore/RenderView.h>
111 #if ENABLE(TIZEN_ISF_PORT)
112 #include <WebCore/Text.h>
113 #include <WebCore/EditorClient.h>
116 #if ENABLE(TIZEN_INPUT_TAG_EXTENSION) || ENABLE(TIZEN_WEBKIT2_FORM_DATABASE)
117 #include "EditorClient.h"
120 #if ENABLE(TIZEN_DATALIST_ELEMENT)
121 #include "HTMLCollection.h"
122 #include "HTMLDataListElement.h"
123 #include "HTMLOptionElement.h"
126 #if ENABLE(TIZEN_STYLE_SCOPED)
127 #include <WebCore/RuntimeEnabledFeatures.h>
130 #if ENABLE(TIZEN_WEBKIT2_TEXT_SELECTION)
131 #include "htmlediting.h"
134 #if ENABLE(TIZEN_LINK_MAGNIFIER)
135 #include "LinkMagnifier.h"
138 #if ENABLE(TIZEN_SCREEN_READER)
139 #include "WebEventConversion.h"
142 #if ENABLE(TIZEN_CSP)
143 #include <WebCore/ContentSecurityPolicy.h>
146 #if ENABLE(TIZEN_OFFLINE_PAGE_SAVE)
147 #include "WebPageSerializerTizen.h"
149 #endif // #if OS(TIZEN)
151 using namespace WebCore;
155 void WebPage::platformInitialize()
157 #if ENABLE(TIZEN_DEVICE_ORIENTATION)
158 WebCore::provideDeviceMotionTo(m_page.get(), new DeviceMotionClientTizen);
159 WebCore::provideDeviceOrientationTo(m_page.get(), new DeviceOrientationClientTizen);
161 #if ENABLE(TIZEN_ISF_PORT)
162 m_isSettingComposition = false;
166 #if ENABLE(TIZEN_PREFERENCE)
167 void WebPage::platformPreferencesDidChange(const WebPreferencesStore& store)
169 Settings* settings = m_page->settings();
170 settings->setInteractiveFormValidationEnabled(store.getBoolValueForKey(WebPreferencesKey::interactiveFormValidationEnabledKey()));
171 settings->setUsesEncodingDetector(store.getBoolValueForKey(WebPreferencesKey::usesEncodingDetectorKey()));
172 #if ENABLE(TIZEN_LOAD_REMOTE_IMAGES)
173 settings->setLoadRemoteImages(store.getBoolValueForKey(WebPreferencesKey::loadRemoteImagesKey()));
175 #if ENABLE(TIZEN_ISF_PORT)
176 settings->setEnableDefaultKeypad(store.getBoolValueForKey(WebPreferencesKey::defaultKeypadEnabledKey()));
178 #if ENABLE(TIZEN_STYLE_SCOPED)
179 WebCore::RuntimeEnabledFeatures::setStyleScopedEnabled(store.getBoolValueForKey(WebPreferencesKey::styleScopedEnabledKey()));
181 #if ENABLE(TIZEN_WEB_AUDIO)
182 settings->setWebAudioEnabled(true);
186 void WebPage::platformPreferencesDidChange(const WebPreferencesStore&)
190 #endif // #if ENABLE(TIZEN_PREFERENCE)
192 static inline void scroll(Page* page, ScrollDirection direction, ScrollGranularity granularity)
194 page->focusController()->focusedOrMainFrame()->eventHandler()->scrollRecursively(direction, granularity);
197 bool WebPage::performDefaultBehaviorForKeyEvent(const WebKeyboardEvent& keyboardEvent)
203 bool WebPage::platformHasLocalDataForURL(const KURL&)
209 String WebPage::cachedResponseMIMETypeForURL(const KURL&)
215 bool WebPage::platformCanHandleRequest(const ResourceRequest&)
221 String WebPage::cachedSuggestedFilenameForURL(const KURL&)
227 PassRefPtr<SharedBuffer> WebPage::cachedResponseDataForURL(const KURL&)
233 const char* WebPage::interpretKeyEvent(const KeyboardEvent* event)
235 ASSERT(event->type() == eventNames().keydownEvent || event->type() == eventNames().keypressEvent);
237 if (event->type() == eventNames().keydownEvent)
238 return getKeyDownCommandName(event);
240 return getKeyPressCommandName(event);
243 void WebPage::setThemePath(const String& themePath)
245 WebCore::RenderThemeEfl* theme = static_cast<WebCore::RenderThemeEfl*>(m_page->theme());
246 theme->setThemePath(themePath);
249 static Frame* targetFrameForEditing(WebPage* page)
251 Frame* frame = page->corePage()->focusController()->focusedOrMainFrame();
255 Editor* editor = frame->editor();
256 if (!editor->canEdit())
259 if (editor->hasComposition()) {
260 // We should verify the parent node of this IME composition node are
261 // editable because JavaScript may delete a parent node of the composition
262 // node. In this case, WebKit crashes while deleting texts from the parent
263 // node, which doesn't exist any longer.
264 if (PassRefPtr<Range> range = editor->compositionRange()) {
265 Node* node = range->startContainer();
266 if (!node || !node->isContentEditable())
274 void WebPage::confirmComposition(const String& compositionString)
276 Frame* targetFrame = targetFrameForEditing(this);
280 targetFrame->editor()->confirmComposition(compositionString);
283 void WebPage::setComposition(const String& compositionString, const Vector<WebCore::CompositionUnderline>& underlines, uint64_t cursorPosition)
285 Frame* targetFrame = targetFrameForEditing(this);
289 #if ENABLE(TIZEN_ISF_PORT)
290 if (targetFrame->selection()->rootEditableElement()) {
291 HTMLTextFormControlElement* textFormControl = toTextFormControl(targetFrame->selection()->rootEditableElement()->shadowAncestorNode());
292 if (textFormControl && textFormControl->maxLength() >= 0) {
293 unsigned availableLength = textFormControl->maxLength() - textFormControl->value().length();
294 if (targetFrame->editor()->hasComposition())
295 availableLength += (targetFrame->editor()->compositionEnd() - targetFrame->editor()->compositionStart());
296 if (!availableLength)
299 if (availableLength < compositionString.length()) {
300 String newCompositionString = compositionString.substring(0, availableLength);
301 Vector<CompositionUnderline> newUnderlines;
302 size_t numUnderlines = underlines.size();
303 for (size_t index = 0; index < numUnderlines; ++index) {
304 if (underlines[index].startOffset < availableLength) {
305 newUnderlines.append(underlines[index]);
306 if (newUnderlines.last().endOffset > availableLength)
307 newUnderlines.last().endOffset = availableLength;
310 targetFrame->editor()->setComposition(newCompositionString, newUnderlines, cursorPosition, 0);
315 m_isSettingComposition = true;
318 targetFrame->editor()->setComposition(compositionString, underlines, cursorPosition, 0);
320 #if ENABLE(TIZEN_ISF_PORT)
321 m_isSettingComposition = false;
325 void WebPage::cancelComposition()
327 Frame* frame = m_page->focusController()->focusedOrMainFrame();
331 frame->editor()->cancelComposition();
336 #if ENABLE(TIZEN_WEBKIT2_TILED_BACKING_STORE)
337 IntSize WebPage::contentsSize() const
339 FrameView* frameView = m_page->mainFrame()->view();
341 return IntSize(0, 0);
343 return frameView->contentsSize();
347 void WebPage::scrollMainFrameBy(const IntSize& scrollOffset)
349 m_page->mainFrame()->view()->scrollBy(scrollOffset);
352 void WebPage::scrollMainFrameTo(const IntPoint& scrollPosition)
354 m_page->mainFrame()->view()->setScrollPosition(scrollPosition);
357 void WebPage::createSnapshot(const IntRect rect, float scaleFactor, ShareableBitmap::Handle& snapshotHandle)
359 FrameView* frameView = m_mainFrame->coreFrame()->view();
363 RefPtr<WebImage> snapshotImage = scaledSnapshotInViewCoordinates(rect, scaleFactor, ImageOptionsShareable);
364 if (!snapshotImage || !snapshotImage->bitmap())
367 snapshotImage->bitmap()->createHandle(snapshotHandle);
370 void WebPage::requestUpdateFormNavigation()
372 Frame* frame = m_page->focusController()->focusedOrMainFrame();
376 Document* document = frame->document();
380 Node* focusedNode = document->focusedNode();
382 Vector<RefPtr<Node> > focusableNodes;
383 document->getFocusableNodes(focusableNodes);
385 int formElementCount = 0;
386 int currentNodeIndex = -1;
387 const Vector<RefPtr<Node> >::iterator end = focusableNodes.end();
388 for (Vector<RefPtr<Node> >::iterator it = focusableNodes.begin(); it != end; ++it) {
389 AtomicString nodeName = (*it).get()->nodeName();
390 if (equalIgnoringCase(nodeName, "SELECT")
391 || (equalIgnoringCase(nodeName, "INPUT")
392 && !equalIgnoringCase((*it).get()->toInputElement()->type(), "CHECKBOX")
393 && !equalIgnoringCase((*it).get()->toInputElement()->type(), "RADIO")
394 && !equalIgnoringCase((*it).get()->toInputElement()->type(), "SUBMIT")
397 if ((*it).get() == focusedNode)
398 currentNodeIndex = formElementCount;
403 if (currentNodeIndex == -1)
406 send(Messages::WebPageProxy::UpdateFormNavigation(formElementCount, currentNodeIndex));
409 void WebPage::moveFocus(int newIndex)
411 Frame* frame = m_page->focusController()->focusedOrMainFrame();
415 Document* document = frame->document();
419 Vector<RefPtr<Node> > focusableNodes;
420 document->getFocusableNodes(focusableNodes);
423 const Vector<RefPtr<Node> >::iterator end = focusableNodes.end();
424 for (Vector<RefPtr<Node> >::iterator it = focusableNodes.begin(); it != end; ++it) {
425 AtomicString nodeName = (*it).get()->nodeName();
426 if (equalIgnoringCase(nodeName, "SELECT")) {
427 if (index == newIndex) {
428 (*it).get()->setFocus();
429 LayoutPoint position = LayoutPoint(0, 0);
430 PlatformMouseEvent event(flooredIntPoint(position), flooredIntPoint(position), LeftButton, PlatformEvent::MouseMoved, 1, false, false, false, false, 0);
431 (*it).get()->dispatchMouseEvent(event, "mousedown", 0, 0);
434 } else if (equalIgnoringCase(nodeName, "INPUT")
435 && !equalIgnoringCase((*it).get()->toInputElement()->type(), "CHECKBOX")
436 && !equalIgnoringCase((*it).get()->toInputElement()->type(), "RADIO")
438 if (index == newIndex) {
439 HTMLInputElement* elem = (*it).get()->toInputElement();
447 #if ENABLE(TIZEN_MOBILE_WEB_PRINT)
448 #define INCH_TO_MM 25.4
449 #define INCH_TO_POINTS 72.0
451 void WebPage::createPagesToPDF(const IntSize& surfaceSize, const IntSize& contentsSize, const String& fileName)
453 FrameView* frameView = m_mainFrame->coreFrame()->view();
457 RefPtr<WebImage> pageshotImage = WebImage::create(contentsSize, ImageOptionsShareable);
458 if (!pageshotImage->bitmap())
461 double pdfWidth = (double)surfaceSize.width() / INCH_TO_MM * INCH_TO_POINTS;
462 double pdfHeight = (double)surfaceSize.height() / INCH_TO_MM * INCH_TO_POINTS;
463 double scaleFactorPdf = 1.0;
464 if (contentsSize.width() > pdfWidth)
465 scaleFactorPdf = pdfWidth / (double)contentsSize.width();
467 OwnPtr<WebCore::GraphicsContext> graphicsContext = pageshotImage->bitmap()->createGraphicsContextForPdfSurface(fileName, pdfWidth, pdfHeight);
468 graphicsContext->scale(FloatSize(scaleFactorPdf, scaleFactorPdf));
470 frameView->updateLayoutAndStyleIfNeededRecursive();
472 int pageNumber = ((contentsSize.height() * scaleFactorPdf) / pdfHeight) + 1;
475 PaintBehavior oldBehavior = frameView->paintBehavior();
476 frameView->setPaintBehavior(oldBehavior | PaintBehaviorFlattenCompositingLayers);
477 for (int i = 0; i < pageNumber; i++) {
478 IntRect paintRect(0, (int)paintY, contentsSize.width(), (int)(pdfHeight / scaleFactorPdf));
480 frameView->paint(graphicsContext.get(), paintRect);
481 cairo_show_page(graphicsContext->platformContext()->cr());
482 graphicsContext->translate(0, -ceil(pdfHeight / scaleFactorPdf));
483 paintY += (pdfHeight / scaleFactorPdf);
485 frameView->setPaintBehavior(oldBehavior);
487 pageshotImage.release();
491 #if ENABLE(TIZEN_TEXT_CARET_HANDLING_WK2)
492 bool WebPage::setCaretPosition(const IntPoint& pos)
494 Frame* frame = m_page->focusController()->focusedOrMainFrame();
498 FrameSelection* controller = frame->selection();
502 FrameView* frameView = frame->view();
506 IntPoint point = m_page->mainFrame()->view()->windowToContents(pos);
507 HitTestResult result = m_page->mainFrame()->eventHandler()->hitTestResultAtPoint(point, /*allowShadowContent*/ true, /*ignoreClipping*/ true);
508 if (result.scrollbar())
511 Node* innerNode = result.innerNode();
513 if (!innerNode || !innerNode->renderer())
516 VisiblePosition visiblePos;
518 // we check if content is richly editable - because those input field behave other than plain text ones
519 // sometimes they may consists a node structure and they need special approach
520 if (innerNode->rendererIsRichlyEditable()) {
521 // point gets inner node local coordinates
522 point = flooredIntPoint(result.localPoint());
523 IntRect rect = innerNode->renderer()->absoluteBoundingBoxRect(true);
525 // it is not the best way to do this, but it is not as slow and it works - so maybe in the future someone
526 // will have a better idea how to solve it
527 // here we are getting innerNode from HitTestResult - unfortunately this is a kind of high level node
528 // in the code below I am trying to obtain low level node - #text - to get its coordinates and size
530 // all those getting nodes rects are needed to bypass WebCore's methods of positioning caret when user
531 // is clicking outside a node - and cheat WebCore telling it that actually we clicked into input field
532 // node, not outside of it
533 Node* deepInnerNode = innerNode->renderer()->positionForPoint(point).deepEquivalent().deprecatedNode();
535 if (!deepInnerNode || !deepInnerNode->renderer())
538 // so we get a base node rectange
539 IntRect deepNodeRect = deepInnerNode->renderer()->absoluteBoundingBoxRect(true);
541 // we modify our local point to adjust it to base node local coordinates
542 point.move(rect.x() - deepNodeRect.x(), rect.y() - deepNodeRect.y());
544 // if we are outside the rect we cheat, that we are just inside of it
547 else if (point.y() >= deepNodeRect.height())
548 point.setY(deepNodeRect.height() - 1);
550 // visible position created - caret ready to set
551 visiblePos = deepInnerNode->renderer()->positionForPoint(point);
552 if (visiblePos.isNull())
555 // for plain text input fields we can get only a caret bounding box
556 if (!controller->isCaret() || !controller->caretRenderer())
559 const Node* node = controller->start().deprecatedNode();
560 if (!node || !node->renderer())
563 IntRect rect = controller->caretRenderer()->absoluteBoundingBoxRect(true);
565 // The below wirtten code is not correct way to implement. Presntly the is no
566 // other working way. To be replaced by better logic
567 // here we also cheat input field that we actually are just inside of if
568 IntPoint focusedFramePoint = frame->view()->windowToContents(pos);
569 IntPoint oldFocusedFramePoint = focusedFramePoint;
571 const int boundariesWidth = 2;
572 if (focusedFramePoint.x() < rect.x())
573 focusedFramePoint.setX(rect.x());
574 else if (focusedFramePoint.x() > rect.maxX())
575 focusedFramePoint.setX(rect.maxX());
576 if (focusedFramePoint.y() < rect.y() + boundariesWidth)
577 focusedFramePoint.setY(rect.y() + boundariesWidth);
578 else if (focusedFramePoint.y() >= rect.maxY() - boundariesWidth)
579 focusedFramePoint.setY(rect.maxY() - boundariesWidth - 1);
581 int diffX = focusedFramePoint.x() - oldFocusedFramePoint.x();
582 int diffY = focusedFramePoint.y() - oldFocusedFramePoint.y();
583 point.setX((point.x())+diffX);
584 point.setY((point.y())+diffY);
586 // hit test with fake (adjusted) coordinates
587 IntPoint hitTestPoint = m_page->mainFrame()->view()->windowToContents(point);
588 HitTestResult newResult = m_page->mainFrame()->eventHandler()->hitTestResultAtPoint(hitTestPoint, /*allowShadowContent*/ true, /*ignoreClipping*/ true);
590 if (!newResult.isContentEditable())
593 Node* newInnerNode = newResult.innerNode();
595 if (!newInnerNode || !newInnerNode->renderer())
598 // visible position created
599 visiblePos = newInnerNode->renderer()->positionForPoint(newResult.localPoint());
600 if (visiblePos.isNull())
604 // create visible selection from visible position
605 VisibleSelection newSelection = VisibleSelection(visiblePos);
606 controller->setSelection(newSelection, CharacterGranularity);
607 // after setting selection caret blinking is suspended by default so we are unsuspedning it
608 controller->setCaretBlinkingSuspended(false);
613 void WebPage::getCaretPosition(IntRect& rect)
615 Frame* frame = m_page->focusController()->focusedOrMainFrame();
619 FrameSelection* controller = frame->selection();
623 Node* node = controller->start().deprecatedNode();
624 if (!node || !node->renderer() || !node->isContentEditable())
627 if (controller->isCaret()) {
628 FrameView* frameView = frame->view();
632 rect = frameView->contentsToWindow(controller->absoluteCaretBounds());
637 #if ENABLE(TIZEN_ISF_PORT)
638 void WebPage::didCancelComposition(Node* valueChangedNode)
640 if (m_isSettingComposition)
643 Frame* frame = m_page->focusController()->focusedOrMainFrame();
644 if (!frame || !valueChangedNode->containsIncludingShadowDOM(frame->editor()->compositionNode()))
647 frame->editor()->cancelComposition();
648 send(Messages::WebPageProxy::DidCancelComposition());
651 void WebPage::getCursorOffset(int& offset)
654 Frame* frame = m_page->focusController()->focusedOrMainFrame();
655 if (!frame || !frame->editor()->canEdit())
658 Position base = frame->selection()->base();
659 Node* baseNode = base.containerNode();
661 offset = baseNode->isTextNode() ? base.offsetInContainerNode() : 0;
664 void WebPage::getSurroundingTextAndCursorOffset(String& text, int& offset)
669 Frame* frame = m_page->focusController()->focusedOrMainFrame();
670 if (!frame || !frame->editor()->canEdit())
673 Position base = frame->selection()->base();
674 Node* baseNode = base.containerNode();
675 if (baseNode && baseNode->isTextNode()) {
676 text = baseNode->textContent();
677 offset = base.offsetInContainerNode();
681 void WebPage::getSelectionRect(bool isOnlyEditable, IntRect& rect)
685 Frame* frame = m_page->focusController()->focusedFrame();
686 if (!frame || !frame->view())
689 FrameSelection* selection = frame->selection();
690 Node* node = selection->start().deprecatedNode();
691 if (!node || !node->renderer() || (isOnlyEditable && !node->isContentEditable()))
694 if (selection->isCaret())
695 rect = frame->view()->contentsToWindow(selection->absoluteCaretBounds());
696 else if (selection->isRange())
697 rect = frame->view()->contentsToWindow(enclosingIntRect(selection->bounds()));
700 void WebPage::deleteSurroundingText(int offset, int count)
702 Frame* frame = m_page->focusController()->focusedOrMainFrame();
703 if (!frame || !frame->editor()->canEdit())
706 Position base(frame->selection()->base());
707 offset += base.offsetInContainerNode();
708 base.moveToOffset(offset);
709 Position extent(base);
710 extent.moveToOffset(offset + count);
711 VisibleSelection selection(base, extent);
712 if (!selection.isRange())
715 frame->selection()->setSelection(selection);
716 frame->editor()->deleteWithDirection(DirectionBackward, CharacterGranularity, false, true);
720 #if ENABLE(TIZEN_INPUT_TAG_EXTENSION) || ENABLE(TIZEN_WEBKIT2_FORM_DATABASE)
721 void WebPage::setFocusedInputElementValue(const String& inputValue)
723 Frame* frame = m_page->focusController()->focusedOrMainFrame();
724 if (!frame || !frame->document() || !frame->document()->focusedNode())
727 HTMLInputElement* inputElement = frame->document()->focusedNode()->toInputElement();
731 inputElement->toNode()->dispatchFocusEvent(0);
732 inputElement->setValue(inputValue, DispatchChangeEvent);
735 void WebPage::getFocusedInputElementValue(String& inputValue)
737 inputValue = String();
739 Frame* frame = m_page->focusController()->focusedOrMainFrame();
740 if (!frame || !frame->document() || !frame->document()->focusedNode())
743 HTMLInputElement* inputElement = frame->document()->focusedNode()->toInputElement();
747 inputValue = inputElement->value();
751 #if ENABLE(TIZEN_DATALIST_ELEMENT)
752 void WebPage::getFocusedInputElementDataList(Vector<String>& optionList)
754 Frame* frame = m_page->focusController()->focusedOrMainFrame();
755 if (!frame || !frame->document())
758 Node* node = frame->document()->focusedNode();
762 HTMLInputElement* input = node->toInputElement();
766 HTMLDataListElement* dataList = static_cast<HTMLDataListElement*>(input->list());
770 RefPtr<HTMLCollection> options = static_cast<HTMLDataListElement*>(dataList)->options();
771 for (unsigned i = 0; Node* node = options->item(i); i++) {
772 HTMLOptionElement* optionElement = static_cast<HTMLOptionElement*>(node);
773 String value = optionElement->value();
774 optionList.append(value);
779 #if ENABLE(TIZEN_WEBKIT2_FOCUS_RING)
780 static IntRect getNodeRect(Node* node, Node* focusableNode, bool isImage)
786 IntRect imageNodeRect = pixelSnappedIntRect(node->getRect());
787 if (!focusableNode->renderRect(&isReplaced).isEmpty() && imageNodeRect.contains(pixelSnappedIntRect(focusableNode->getRect()))) {
788 // If render rect of focusableNode is empty and rect of imageNode include rect of focusableNode,
789 // we have to get rect of focusableNode.
790 // for example - The rect of google logo image in www.google.com pc site's search result page is bigger than rect of focusableNode.
791 // for example - The rect of category menu image in www.gmarket.co.kr pc site is bigger than rect of focusableNode.
792 rect = pixelSnappedIntRect(focusableNode->getRect());
795 // otherwise we have to get rect of imageNode.
796 // for example - The render rect of images in www.pudelek.pl is empty.
797 // 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.
798 rect = imageNodeRect;
799 focusableNode = node;
802 // If focusedNode have multiple child nodes, we have to unite rect of child nodes.
803 // for example - links in www.google.com's search result page.
805 for (Node* childNode = focusableNode->firstChild(); childNode; childNode = childNode->traverseNextNode(focusableNode)) {
807 if (focusableNode->renderRect(&isReplaced).contains(childNode->getRect()))
808 tempRect.unite(pixelSnappedIntRect(childNode->getRect()));
811 // If tempRect is empty or rect of focusableNode include tempRect,
812 // we have to get rect of focusableNode.
813 // for example - list menu item in m.naver.com.
814 // otherwise we have to get rect of tempRect.
815 // getRect API do not return correct rect if the node is a container node,
816 // hence using absoluteBoundingBoxRect to get the correct bounding rect.
817 LayoutRect renderRect = focusableNode->renderer() ? focusableNode->renderer()->absoluteBoundingBoxRect() : focusableNode->getRect();
818 if (tempRect.isEmpty() || renderRect.contains(tempRect))
819 rect = pixelSnappedIntRect(renderRect);
824 // We have to get render rect from ancestor node if current rect is empty.
825 // for example - The rect of naver logo image in www.naver.com pc site is empty.
827 for (Node* loopNode = focusableNode; loopNode && rect.isEmpty(); loopNode = loopNode->parentNode()) {
828 RenderObject* renderer = loopNode->renderer();
829 if (renderer && renderer->isRoot())
832 rect = pixelSnappedIntRect(loopNode->renderRect(&isReplaced));
835 Frame* nodeFrame = focusableNode->document()->frame();
837 while (nodeFrame && (owner = nodeFrame->ownerElement())) {
838 rect.moveBy(owner->getRect().pixelSnappedLocation());
839 nodeFrame = owner->document()->frame();
842 // The y position of tab menu item in www.google.com is negative value,
843 // so we do not want to draw focus ring in that case.
844 if ((rect.maxX() < 0) || (rect.maxY() < 0))
851 #if ENABLE(TIZEN_WEBKIT2_HIT_TEST)
852 #if ENABLE(TIZEN_WEBKIT2_FOCUS_RING)
853 static IntRect getFocusedRect(HitTestResult hitTestResult, Page* page)
855 Node* node = hitTestResult.innerNode();
856 bool isFocusRingDrawable = false;
857 Node* focusableNode = node;
858 while (focusableNode) {
859 RenderObject* renderer = focusableNode->renderer();
860 if (renderer && renderer->isRoot())
863 if (focusableNode->isFocusable()) {
864 if (focusableNode->isLink()
865 || focusableNode->hasTagName(HTMLNames::inputTag)
866 || focusableNode->hasTagName(HTMLNames::selectTag)
867 || focusableNode->hasTagName(HTMLNames::buttonTag))
868 isFocusRingDrawable = true;
872 focusableNode = focusableNode->parentNode();
875 if (!isFocusRingDrawable) {
876 if (node->hasTagName(HTMLNames::imgTag))
877 return getNodeRect(node, node, !hitTestResult.absoluteImageURL().isEmpty());
882 return getNodeRect(node, focusableNode, !hitTestResult.absoluteImageURL().isEmpty());
886 void WebPage::hitTestResultAtPoint(const IntPoint& point, int hitTestMode, WebHitTestResult::Data& hitTestResultData)
888 Frame* frame = m_page->mainFrame();
889 FrameView* frameView = frame->view();
893 HitTestResult hitTestResult = frame->eventHandler()->hitTestResultAtPoint(frameView->windowToContents(point), false);
894 hitTestResultData.absoluteImageURL = hitTestResult.absoluteImageURL().string();
895 hitTestResultData.absoluteLinkURL = hitTestResult.absoluteLinkURL().string();
896 hitTestResultData.absoluteMediaURL = hitTestResult.absoluteMediaURL().string();
897 hitTestResultData.linkLabel = hitTestResult.textContent();
898 hitTestResultData.linkTitle = hitTestResult.titleDisplayString();
899 #if ENABLE(TIZEN_DRAG_SUPPORT)
900 hitTestResultData.isDragSupport = hitTestResult.isDragSupport();
903 int context = WebHitTestResult::HitTestResultContextDocument;
905 if (!hitTestResult.absoluteLinkURL().isEmpty())
906 context |= WebHitTestResult::HitTestResultContextLink;
907 if (!hitTestResult.absoluteImageURL().isEmpty())
908 context |= WebHitTestResult::HitTestResultContextImage;
909 if (!hitTestResult.absoluteMediaURL().isEmpty())
910 context |= WebHitTestResult::HitTestResultContextMedia;
911 if (hitTestResult.isSelected())
912 context |= WebHitTestResult::HitTestResultContextSelection;
913 if (hitTestResult.isContentEditable())
914 context |= WebHitTestResult::HitTestResultContextEditable;
915 if (hitTestResult.innerNonSharedNode() && hitTestResult.innerNonSharedNode()->isTextNode())
916 context |= WebHitTestResult::HitTestResultContextText;
918 hitTestResultData.context = context;
919 hitTestResultData.hitTestMode = hitTestMode;
921 #if ENABLE(TIZEN_WEBKIT2_FOCUS_RING)
922 hitTestResultData.focusedRect = getFocusedRect(hitTestResult, m_page.get());
923 if (hitTestResult.innerNode() && hitTestResult.innerNode()->renderer() && hitTestResult.innerNode()->renderer()->style()) {
924 hitTestResultData.focusedColor = hitTestResult.innerNode()->renderer()->style()->tapHighlightColor();
925 if (!hitTestResultData.focusedColor.hasAlpha())
926 hitTestResultData.focusedColor = Color(hitTestResultData.focusedColor.red(), hitTestResultData.focusedColor.green(), hitTestResultData.focusedColor.blue(), RenderStyle::initialTapHighlightColor().alpha());
930 if (hitTestResultData.hitTestMode & WebHitTestResult::HitTestModeNodeData) {
931 WebCore::Node* hitNode = hitTestResult.innerNonSharedNode();
933 hitTestResultData.nodeData.nodeValue = hitNode->nodeValue();
935 if ((hitTestResultData.context & WebHitTestResult::HitTestResultContextText) && hitNode->parentNode())
936 hitNode = hitNode->parentNode(); // if hittest inner node is Text node, fill tagName with parent node's info and fill attributeMap with parent node's attributes.
938 if (hitNode->isElementNode()) {
939 WebCore::Element* hitElement = static_cast<WebCore::Element*>(hitNode);
941 hitTestResultData.nodeData.tagName = hitElement->tagName();
945 WebCore::NamedNodeMap* namedNodeMap = hitNode->attributes();
947 for (size_t i = 0; i < namedNodeMap->length(); i++) {
948 const WebCore::Attribute* attribute = namedNodeMap->element()->attributeItem(i);
949 String key = attribute->name().toString();
950 String value = attribute->value();
951 hitTestResultData.nodeData.attributeMap.add(key, value);
957 if ((hitTestResultData.hitTestMode & WebHitTestResult::HitTestModeImageData) && (hitTestResultData.context & WebHitTestResult::HitTestResultContextImage)) {
958 WebCore::Image* hitImage = hitTestResult.image();
959 if (hitImage && hitImage->data() && hitImage->data()->data()) {
960 hitTestResultData.imageData.data.append(hitImage->data()->data(), hitImage->data()->size());
961 hitTestResultData.imageData.fileNameExtension = hitImage->filenameExtension();
967 #if ENABLE(TIZEN_WEB_STORAGE)
968 void WebPage::getStorageQuotaBytes(uint64_t callbackID)
970 uint32_t quota = m_page->group().groupSettings()->localStorageQuotaBytes();
971 send(Messages::WebPageProxy::DidGetWebStorageQuotaBytes(quota, callbackID));
974 void WebPage::setStorageQuotaBytes(uint32_t quota)
976 m_page->group().groupSettings()->setLocalStorageQuotaBytes(quota);
980 #if ENABLE(TIZEN_RECORDING_SURFACE_SET)
981 void WebPage::recordingSurfaceSetEnableSet(bool enable)
983 m_recordingSurfaceSetSettings = enable;
987 #if ENABLE(TIZEN_CLIPBOARD) || ENABLE(TIZEN_PASTEBOARD)
988 void WebPage::setClipboardDataForPaste(const String& data, const String& type)
990 #if ENABLE(TIZEN_PASTEBOARD)
991 // FIXME: Should move to EditorClient like Clipboard
992 Pasteboard::generalPasteboard()->setDataWithType(data, type);
994 Frame* mainFrame = m_page->mainFrame();
998 mainFrame->editor()->client()->setClipboardDataForPaste(data, type);
1003 void WebPage::suspendJavaScriptAndResources()
1005 Frame* mainFrame = m_page->mainFrame();
1009 for (Frame* frame = mainFrame; frame; frame = frame->tree()->traverseNext())
1010 frame->document()->suspendScheduledTasks(WebCore::ActiveDOMObject::PageWillBeSuspended);
1011 mainFrame->loader()->suspendAllLoaders();
1014 void WebPage::resumeJavaScriptAndResources()
1016 Frame* mainFrame = m_page->mainFrame();
1020 for (Frame* frame = mainFrame; frame; frame = frame->tree()->traverseNext())
1021 frame->document()->resumeScheduledTasks();
1022 mainFrame->loader()->resumeAllLoaders();
1025 #if ENABLE(TIZEN_SYNC_REQUEST_ANIMATION_FRAME)
1026 void WebPage::suspendAnimationController()
1028 if (!m_suspendedAnimationController) {
1029 Frame* mainFrame = m_page->mainFrame();
1033 for (Frame* frame = mainFrame; frame; frame = frame->tree()->traverseNext())
1034 frame->document()->suspendScriptedAnimationControllerCallbacks();
1036 m_suspendedAnimationController = true;
1040 void WebPage::resumeAnimationController()
1042 if (m_suspendedAnimationController) {
1043 Frame* mainFrame = m_page->mainFrame();
1047 for (Frame* frame = mainFrame; frame; frame = frame->tree()->traverseNext())
1048 frame->document()->resumeScriptedAnimationControllerCallbacks();
1050 m_suspendedAnimationController = false;
1055 #if ENABLE(TIZEN_WEBKIT2_REMOTE_WEB_INSPECTOR)
1056 void WebPage::startInspectorServer(uint32_t port, uint32_t& allocatedPort)
1058 bool ret = WebInspectorServerEfl::server()->startServer(port);
1060 allocatedPort = WebInspectorServerEfl::server()->getServerPort();
1065 void WebPage::stopInspectorServer(bool& result)
1067 result = WebInspectorServerEfl::server()->stopServer();
1071 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION_ON_UI_SIDE)
1072 void WebPage::scrollOverflowWithTrajectoryVector(const WebCore::FloatPoint& trajectoryVector)
1074 Frame* frame = m_page->focusController()->focusedOrMainFrame();
1077 frame->eventHandler()->scrollOverflow(trajectoryVector);
1081 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION)
1082 void WebPage::scrollOverflow(const WebCore::FloatPoint& delta, bool& scrolled)
1084 scrolled = m_page->focusController()->focusedOrMainFrame()->eventHandler()->scrollOverflow(delta);
1087 void WebPage::setPressedNodeAtPoint(const IntPoint& point, bool checkOverflowLayer, bool& pressed, uint32_t& id)
1089 RenderObject* renderer = 0;
1091 pressed = m_page->focusController()->focusedOrMainFrame()->eventHandler()->setMousePressNodeAtPoint(point, checkOverflowLayer, renderer);
1092 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION_ON_UI_SIDE)
1093 if (pressed && renderer)
1094 id = toWebGraphicsLayer(renderer->enclosingLayer()->layerForScrollingContents())->id();
1099 void WebPage::executeEditCommandWithArgument(const String& commandName, const String& argument)
1101 executeEditingCommand(commandName, argument);
1104 #if ENABLE(TIZEN_PLUGIN_SUSPEND_RESUME)
1105 void WebPage::suspendPlugin()
1107 for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
1108 FrameView* view = frame->view();
1112 const HashSet<RefPtr<Widget> >* children = view->children();
1115 HashSet<RefPtr<Widget> >::const_iterator end = children->end();
1116 for (HashSet<RefPtr<Widget> >::const_iterator it = children->begin(); it != end; ++it) {
1117 Widget* widget = (*it).get();
1118 if (widget->isPluginViewBase()) {
1119 PluginView* pluginView = static_cast<PluginView*>(widget);
1121 pluginView->suspendPlugin();
1127 void WebPage::resumePlugin()
1129 for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
1130 FrameView* view = frame->view();
1134 const HashSet<RefPtr<Widget> >* children = view->children();
1137 HashSet<RefPtr<Widget> >::const_iterator end = children->end();
1138 for (HashSet<RefPtr<Widget> >::const_iterator it = children->begin(); it != end; ++it) {
1139 Widget* widget = (*it).get();
1140 if (widget->isPluginViewBase()) {
1141 PluginView* pluginView = static_cast<PluginView*>(widget);
1143 pluginView->resumePlugin();
1150 #if ENABLE(TIZEN_WEBKIT2_GET_TEXT_STYLE_FOR_SELECTION)
1151 void WebPage::getTextStyleStateForSelection()
1153 Frame* frame = m_page->focusController()->focusedOrMainFrame();
1155 int underlineState = frame->editor()->selectionHasStyle(CSSPropertyWebkitTextDecorationsInEffect, "underline");
1156 int italicState = frame->editor()->selectionHasStyle(CSSPropertyFontStyle, "italic");
1157 int boldState = frame->editor()->selectionHasStyle(CSSPropertyFontWeight, "bold");
1159 send(Messages::WebPageProxy::DidGetTextStyleStateForSelection(underlineState, italicState, boldState));
1163 #if ENABLE(TIZEN_MULTIPLE_SELECT)
1164 void WebPage::didChangeSelectedIndexForActivePopupMenuMultiple(Vector<int32_t> newIndex)
1166 if (!m_activePopupMenu)
1169 m_activePopupMenu->client()->popupDidHide();
1171 size_t indexSize = newIndex.size();
1172 for (size_t i = 0; i < indexSize; i++)
1173 m_activePopupMenu->didChangeSelectedIndex(newIndex.at(i));
1178 #if ENABLE(TIZEN_OFFLINE_PAGE_SAVE)
1179 void WebPage::startOfflinePageSave(String subresourceFolderName)
1181 WebPageSerializerTizen::getSerializedPageContent(this, subresourceFolderName);
1185 #if ENABLE(TIZEN_WEBKIT2_TEXT_SELECTION)
1186 void WebPage::selectClosestWord(const IntPoint& point, bool isStartedTextSelectionFromOutside, bool& result)
1190 Frame* mainFrame = m_page->mainFrame();
1191 Frame* focusedFrame = m_page->focusController()->focusedOrMainFrame();
1193 HitTestResult hitTestResult = mainFrame->eventHandler()->hitTestResultAtPoint(m_page->mainFrame()->view()->windowToContents(point), false);
1195 Node* node = hitTestResult.innerNonSharedNode();
1199 Frame* newFocusFrame = node->document()->frame();
1200 if (focusedFrame != newFocusFrame) {
1201 m_page->focusController()->setFocusedFrame(newFocusFrame);
1202 focusedFrame = newFocusFrame;
1205 #if ENABLE(TIZEN_INPUT_TAG_EXTENSION)
1206 HTMLInputElement* inputElement = node->toInputElement();
1209 if (hitTestResult.isContentEditable()) {
1210 #if ENABLE(TIZEN_ISF_PORT)
1212 didCancelComposition(node);
1214 #if ENABLE(TIZEN_INPUT_TAG_EXTENSION)
1215 if (!inputElement || (inputElement
1216 && !inputElement->isDateField() && !inputElement->isDateTimeField() && !inputElement->isDateTimeLocalField()
1217 && !inputElement->isMonthField() && !inputElement->isTimeField() && !inputElement->isWeekField())) {
1218 result = setCaretPosition(point);
1222 result = setCaretPosition(point);
1227 #if ENABLE(TIZEN_INPUT_TAG_EXTENSION)
1228 if (!node->isTextNode() && !inputElement)
1230 if (!node->isTextNode())
1234 if (!isStartedTextSelectionFromOutside) {
1235 for (Node* node = hitTestResult.innerNonSharedNode(); node; node = node->parentNode()) {
1236 if (node->isFocusable()) {
1237 // Text selection shoud not be started when text of <button> tag is selected.
1238 if (node->hasTagName(HTMLNames::buttonTag))
1245 FrameSelection* frameSelection = focusedFrame->selection();
1247 VisiblePosition position = mainFrame->visiblePositionForPoint(point);
1248 VisibleSelection selection(position);
1250 // This changes just the 'start' and 'end' positions of the VisibleSelection
1251 selection.expandUsingGranularity(WordGranularity);
1253 FrameSelection::SetSelectionOptions options = FrameSelection::CloseTyping | FrameSelection::ClearTypingStyle | FrameSelection::DoNotSetFocus;
1254 frameSelection->setSelection(VisibleSelection(selection.start(), selection.end()), options);
1256 if (!frameSelection->isRange())
1259 // This changes just the 'start' and 'end' positions of the VisibleSelection
1260 // Find handlers positions
1261 IntRect leftRect, rightRect;
1262 getSelectionHandlers(leftRect, rightRect);
1263 if (leftRect.size().isZero() && rightRect.size().isZero()) {
1264 // Sometimes there is no selected text, but isNone() returns TRUE
1265 // in this case ewk_frame_selection_handlers_get() returns FALSE and handlers are invalid
1266 // Workaround - clear the selection.
1267 // Better solution would be to modify the ewk_frame_select_closest_word()
1268 // to not select anything in the first place (for example - don't call setSelection()
1269 // if there is nothing under the cursor).
1270 selectionClearAllSelection(m_page->mainFrame());
1277 void WebPage::setLeftSelection(const IntPoint& point, bool& result)
1281 Frame* focusedFrame = m_page->focusController()->focusedOrMainFrame();
1282 FrameSelection* frameSelection = focusedFrame->selection();
1283 if (!frameSelection->isRange())
1286 Node* selectionEndNode = frameSelection->end().deprecatedNode();
1287 if (!selectionEndNode || !selectionEndNode->renderer())
1290 FrameView* frameView = focusedFrame->view();
1294 IntPoint pos = frameView->windowToContents(point);
1295 IntRect leftRect, rightRect;
1296 getSelectionHandlers(leftRect, rightRect);
1297 if ((rightRect.y() + rightRect.height()) < pos.y())
1298 pos.setY(rightRect.y() + (rightRect.height()/2));
1300 if (selectionEndNode->rendererIsEditable() && !selectionEndNode->rendererIsRichlyEditable()) {
1301 const int boundariesWidth = 2;
1303 IntRect rect = frameSelection->caretRenderer()->absoluteBoundingBoxRect(true);
1304 // here we cheat input field that we actually are just inside of if
1305 if (pos.y() < rect.y() + boundariesWidth)
1306 pos.setY(rect.y() + boundariesWidth);
1307 else if (pos.y() >= rect.maxY() - boundariesWidth)
1308 pos.setY(rect.maxY() - boundariesWidth - 1);
1311 OwnPtr<VisiblePosition> position = adoptPtr(new VisiblePosition(focusedFrame->visiblePositionForPoint(pos)));
1312 Position extent = frameSelection->extent();
1314 Node* newSelectionStartNode = position->deepEquivalent().deprecatedNode();
1316 // both start and end nodes should be in the same area type: both should be editable or both should be not editable
1317 // Check if the new position is before the extent's position
1318 if (newSelectionStartNode
1319 && selectionEndNode->isContentEditable() == newSelectionStartNode->isContentEditable()
1320 && comparePositions(position->deepEquivalent(), extent) < 0) {
1321 // Change the 'base' and 'extent' positions to 'start' and 'end' positions.
1322 // We do it, because without this, the other modification of the selection
1323 // would destroy the 'start' and/or 'end' positions and set them to
1324 // the 'base'/'extent' positions accordingly
1325 VisibleSelection sel(frameSelection->start(), frameSelection->end());
1326 frameSelection->setSelection(sel);
1328 bool oldProhibitsScrolling = focusedFrame->view()->prohibitsScrolling();
1329 focusedFrame->view()->setProhibitsScrolling(true);
1331 frameSelection->setBase(*position);
1333 focusedFrame->view()->setProhibitsScrolling(oldProhibitsScrolling);
1334 // This forces webkit to show selection
1335 // m_coreFrame->invalidateSelection();
1342 void WebPage::setRightSelection(const IntPoint& point, bool& result)
1346 Frame* focusedFrame = m_page->focusController()->focusedOrMainFrame();
1347 FrameSelection* frameSelection = focusedFrame->selection();
1349 if (!frameSelection->isRange())
1352 Node* selectionStartNode = frameSelection->start().deprecatedNode();
1353 if (!selectionStartNode || !selectionStartNode->renderer())
1356 FrameView* frameView = focusedFrame->view();
1360 IntPoint pos = frameView->windowToContents(point);
1361 if (selectionStartNode->rendererIsEditable() && !selectionStartNode->rendererIsRichlyEditable()) {
1362 const int boundariesWidth = 2;
1364 IntRect rect = frameSelection->caretRenderer()->absoluteBoundingBoxRect(true);
1365 // here we cheat input field that we actually are just inside of if
1366 if (pos.y() < rect.y() + boundariesWidth)
1367 pos.setY(rect.y() + boundariesWidth);
1368 else if (pos.y() >= rect.maxY() - boundariesWidth)
1369 pos.setY(rect.maxY() - boundariesWidth - 1);
1372 OwnPtr<VisiblePosition> position = adoptPtr(new VisiblePosition(focusedFrame->visiblePositionForPoint(pos)));
1373 Position base = frameSelection->base();
1375 Node* newSelectionEndNode = position->deepEquivalent().deprecatedNode();
1377 // both start and end nodes should be in the same area type: both should be editable or both should be not editable
1378 // Check if the new position is after the base's position
1379 if (newSelectionEndNode
1380 && selectionStartNode->isContentEditable() == newSelectionEndNode->isContentEditable()
1381 && comparePositions(position->deepEquivalent(), base) > 0) {
1382 // Change the 'base' and 'extent' positions to 'start' and 'end' positions.
1383 // We do it, because without this, the other modifications of the selection
1384 // would destroy the 'start' and/or 'end' positions and set them to
1385 // the 'base'/'extent' positions accordingly
1387 VisibleSelection sel(frameSelection->start(), frameSelection->end());
1388 frameSelection->setSelection(sel);
1390 bool oldProhibitsScrolling = focusedFrame->view()->prohibitsScrolling();
1391 focusedFrame->view()->setProhibitsScrolling(true);
1393 frameSelection->setExtent(*position);
1395 focusedFrame->view()->setProhibitsScrolling(oldProhibitsScrolling);
1401 void WebPage::getSelectionHandlers(IntRect& leftRect, IntRect& rightRect)
1403 Frame* focusedFrame = m_page->focusController()->focusedOrMainFrame();
1404 if (!focusedFrame->selection()->isRange())
1407 // Is this check necessary? Leaving it for safety.
1408 RenderView* root = focusedFrame->contentRenderer();
1412 RefPtr<Range> selectedRange = focusedFrame->selection()->toNormalizedRange();
1414 Vector<IntRect> rects, tempRects;
1415 selectedRange->boundingBoxEx(tempRects, true);
1417 IntRect boundsRect = enclosingIntRect(focusedFrame->selection()->bounds());
1418 for (size_t i = 0; i < tempRects.size(); i++) {
1419 if (boundsRect.contains(tempRects[i]))
1420 rects.append(tempRects[i]);
1422 tempRects[i].intersect(boundsRect);
1423 if (!tempRects[i].isEmpty())
1424 rects.append(tempRects[i]);
1428 unsigned size = rects.size();
1430 leftRect = rects[0];
1431 rightRect = rects[size-1];
1433 // If selection rect size is greater than editor rect size because of round operation,
1434 // selection rect size should be changed to editor rect size.
1436 Element* selectionRoot = focusedFrame->selection()->rootEditableElement();
1437 if (selectionRoot) {
1438 IntRect editorRect = focusedFrame->view()->contentsToWindow(selectionRoot->getPixelSnappedRect());
1440 #if ENABLE(TIZEN_WEBKIT2_TEXT_SELECTION)
1441 if (m_editorState.editorRect != editorRect) {
1442 EditorState state = editorState();
1443 state.updateEditorRectOnly = true;
1444 send(Messages::WebPageProxy::EditorStateChanged(state));
1448 if (leftRect.maxY() > editorRect.maxY()) {
1449 leftRect.setY(editorRect.y());
1450 leftRect.setHeight(editorRect.height());
1453 if (rightRect.maxY() > editorRect.maxY()) {
1454 rightRect.setY(editorRect.y());
1455 rightRect.setHeight(editorRect.height());
1460 // prevent from selecting zero-length selection
1461 if (leftRect.x() == rightRect.x() + rightRect.width()
1462 && leftRect.y() == rightRect.y())
1465 FrameView* frameView = focusedFrame->view();
1469 leftRect = frameView->contentsToWindow(leftRect);
1470 rightRect = frameView->contentsToWindow(rightRect);
1474 void WebPage::getSelectionText(String& result)
1476 Frame* focusedFrame = m_page->focusController()->focusedOrMainFrame();
1477 result = focusedFrame->editor()->selectedText();
1480 void WebPage::selectionRangeClear(bool& result)
1484 Frame* focusedFrame = m_page->focusController()->focusedOrMainFrame();
1485 FrameSelection* frameSelection = focusedFrame->selection();
1486 if (frameSelection && frameSelection->isRange() && frameSelection->isContentEditable()) {
1487 VisiblePosition visiblePos(frameSelection->extent());
1488 if (visiblePos.isNull())
1490 VisibleSelection newSelection = VisibleSelection(visiblePos);
1491 frameSelection->setSelection(newSelection, CharacterGranularity);
1492 frameSelection->setCaretBlinkingSuspended(false);
1494 selectionClearAllSelection(m_page->mainFrame());
1499 void WebPage::selectionClearAllSelection(Frame* frame)
1504 FrameSelection* frameSelection = frame->selection();
1506 frameSelection->clear();
1511 if (frame->tree()->childCount() > 0) {
1512 if (frame->tree()->firstChild())
1513 selectionClearAllSelection(frame->tree()->firstChild());
1514 } else if (frame->tree()->nextSibling())
1515 selectionClearAllSelection(frame->tree()->nextSibling());
1518 void WebPage::scrollContentByCharacter(const IntPoint&, int direction, bool& result)
1522 Frame* focusedFrame = m_page->focusController()->focusedOrMainFrame();
1524 result = focusedFrame->selection()->modify(FrameSelection::AlterationMove, DirectionBackward, CharacterGranularity, UserTriggered);
1526 result = focusedFrame->selection()->modify(FrameSelection::AlterationMove, DirectionForward, CharacterGranularity, UserTriggered);
1530 #if ENABLE(TIZEN_LINK_MAGNIFIER)
1531 void WebPage::getLinkMagnifierRect(const IntPoint& position, const IntSize& size)
1533 send(Messages::WebPageProxy::DidGetLinkMagnifierRect(position, LinkMagnifier::rect(this, position, size)));
1537 #if ENABLE(TIZEN_SCREEN_READER)
1538 void WebPage::raiseTapEvent(const IntPoint& position, const IntPoint& globalPosition)
1540 Frame* frame = m_page->mainFrame();
1544 Vector<WebPlatformTouchPoint> touchPoints;
1545 touchPoints.append(WebPlatformTouchPoint(0, WebPlatformTouchPoint::TouchPressed, globalPosition, position));
1547 WebTouchEvent touchStartEvent(WebEvent::TouchStart, touchPoints, WebEvent::Modifiers(0), ecore_time_get());
1548 if (!frame->eventHandler()->handleTouchEvent(platform(touchStartEvent))) {
1549 WebGestureEvent gestureEvent(WebEvent::GestureSingleTap, position, globalPosition, WebEvent::Modifiers(0), ecore_time_get());
1550 frame->eventHandler()->handleGestureEvent(platform(gestureEvent));
1553 touchPoints.at(0).setState(WebPlatformTouchPoint::TouchReleased);
1554 WebTouchEvent touchEndEvent(WebEvent::TouchEnd, touchPoints, WebEvent::Modifiers(0), ecore_time_get());
1555 frame->eventHandler()->handleTouchEvent(platform(touchEndEvent));
1558 static void sendScreenReaderFocusRect(WebPage* page, Node* node)
1560 bool isImage = false;
1561 if (node->isElementNode()) {
1562 Element* element = static_cast<Element*>(node);
1563 isImage = !element->getAttribute(element->imageSourceAttributeName()).isEmpty();
1566 page->send(Messages::WebPageProxy::DidScreenReaderFocusRectChanged(getNodeRect(node, node, isImage)));
1569 void WebPage::moveScreenReaderFocus(bool forward, bool& result)
1571 if (!m_screenReader)
1572 m_screenReader = ScreenReader::create(this);
1574 if (!m_screenReader->moveFocus(forward)) {
1576 send(Messages::WebPageProxy::DidScreenReaderFocusRectChanged(IntRect()));
1580 sendScreenReaderFocusRect(this, m_screenReader->getFocusedNode());
1584 void WebPage::moveScreenReaderFocusByPoint(const IntPoint& point)
1586 if (!m_screenReader)
1587 m_screenReader = ScreenReader::create(this);
1589 if (!m_screenReader->moveFocus(point))
1592 sendScreenReaderFocusRect(this, m_screenReader->getFocusedNode());
1595 void WebPage::recalcScreenReaderFocusRect()
1597 if (!m_screenReader || !m_screenReader->getFocusedNode())
1600 sendScreenReaderFocusRect(this, m_screenReader->getFocusedNode());
1603 void WebPage::updateScreenReaderFocus(RenderObject* object)
1605 if (!m_screenReader)
1609 m_screenReader->clearFocus();
1610 else if (!m_screenReader->rendererWillBeDestroyed(object))
1613 send(Messages::WebPageProxy::DidScreenReaderFocusRectChanged(IntRect()));
1616 void WebPage::clearScreenReader()
1618 m_screenReader.clear();
1622 #if ENABLE(TIZEN_WEBKIT2_POPUP_INTERNAL)
1623 // FIXME: Currently with cached pages, hiding Popup list menu is not working correctly.
1624 // This patch is a fix allowing any popup list menu to get close for any page navigation.
1625 void WebPage::notifyTransitionToCommitted(bool forNewPage)
1627 if (m_activePopupMenu) {
1629 m_activePopupMenu->hide();
1634 #if ENABLE(TIZEN_CSP)
1635 void WebPage::setContentSecurityPolicy(const String& policy, uint32_t headerType)
1637 Frame* frame = m_page->focusController()->focusedOrMainFrame();
1641 Document* document = frame->document();
1645 document->contentSecurityPolicy()->didReceiveHeader(policy, static_cast<WebCore::ContentSecurityPolicy::HeaderType>(headerType));
1649 #if ENABLE(TIZEN_INDEXED_DATABASE)
1650 void WebPage::setIndexedDatabaseDirectory(const String& path)
1652 m_page->group().groupSettings()->setIndexedDBDatabasePath(path);
1656 #if ENABLE(TIZEN_WEB_STORAGE)
1657 void WebPage::setLocalStorageDirectory(const String& path)
1659 m_page->settings()->setLocalStorageDatabasePath(path);
1662 #endif // #if OS(TIZEN)
1664 } // namespace WebKit