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 "NamedNodeMap.h"
32 #include "NotImplemented.h"
34 #include "WindowsKeyboardCodes.h"
35 #include <WebCore/EflKeyboardUtilities.h>
36 #include <WebCore/FocusController.h>
37 #include <WebCore/Frame.h>
38 #include <WebCore/FrameView.h>
39 #include <WebCore/KeyboardEvent.h>
40 #include <WebCore/Page.h>
41 #include <WebCore/PlatformKeyboardEvent.h>
42 #include <WebCore/RenderThemeEfl.h>
43 #include <WebCore/Settings.h>
46 #include "Arguments.h"
47 #include "GraphicsContext.h"
48 #include "WebCoreArgumentCoders.h"
51 #include "WebPageProxyMessages.h"
52 #include <WebCore/FrameView.h>
54 #if ENABLE(TIZEN_INPUT_TAG_EXTENSION)
55 #include <WebCore/HTMLInputElement.h>
56 #include <WebCore/HTMLNames.h>
59 #if ENABLE(TIZEN_MULTIPLE_SELECT)
60 #include "WebPopupMenu.h"
61 #include <WebCore/PopupMenuClient.h>
64 #if ENABLE(TIZEN_MOBILE_WEB_PRINT)
65 #include <WebCore/PlatformContextCairo.h>
68 #if ENABLE(TIZEN_CLIPBOARD) || ENABLE(TIZEN_PASTEBOARD)
69 #include <WebCore/ClipboardTizen.h>
72 #if ENABLE(TIZEN_PASTEBOARD)
73 #include <WebCore/Pasteboard.h>
76 #if ENABLE(TIZEN_WEBKIT2_REMOTE_WEB_INSPECTOR)
77 #include "WebInspectorServerEfl.h"
80 #if ENABLE(TIZEN_WEB_STORAGE)
81 #include <WebCore/GroupSettings.h>
82 #include <WebCore/PageGroup.h>
85 #if ENABLE(TIZEN_PLUGIN_SUSPEND_RESUME)
86 #include "PluginView.h"
89 #if ENABLE(TIZEN_PREFERENCE)
90 #include "WebPreferencesStore.h"
91 #include <WebCore/Settings.h>
94 #if ENABLE(TIZEN_WEBKIT2_FOCUS_RING)
95 #include <WebCore/HTMLFrameOwnerElement.h>
96 #include <WebCore/HTMLImageElement.h>
99 #if ENABLE(TIZEN_DEVICE_ORIENTATION)
100 #include "DeviceMotionClientTizen.h"
101 #include "DeviceOrientationClientTizen.h"
104 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION_ON_UI_SIDE)
105 #include "RenderLayer.h"
106 #include "WebGraphicsLayer.h"
107 #include <WebCore/RenderView.h>
110 #if ENABLE(TIZEN_ISF_PORT)
111 #include <WebCore/Text.h>
112 #include <WebCore/EditorClient.h>
115 #if ENABLE(TIZEN_INPUT_TAG_EXTENSION) || ENABLE(TIZEN_WEBKIT2_FORM_DATABASE)
116 #include "EditorClient.h"
119 #if ENABLE(TIZEN_DATALIST_ELEMENT)
120 #include "HTMLCollection.h"
121 #include "HTMLDataListElement.h"
122 #include "HTMLOptionElement.h"
125 #if ENABLE(TIZEN_STYLE_SCOPED)
126 #include <WebCore/RuntimeEnabledFeatures.h>
129 #if ENABLE(TIZEN_WEBKIT2_TEXT_SELECTION)
130 #include "htmlediting.h"
133 #if ENABLE(TIZEN_LINK_MAGNIFIER)
134 #include "LinkMagnifier.h"
137 #if ENABLE(TIZEN_SCREEN_READER)
138 #include "WebEventConversion.h"
141 #if ENABLE(TIZEN_CSP)
142 #include <WebCore/ContentSecurityPolicy.h>
145 #if ENABLE(TIZEN_OFFLINE_PAGE_SAVE)
146 #include "WebPageSerializerTizen.h"
148 #endif // #if OS(TIZEN)
150 using namespace WebCore;
154 void WebPage::platformInitialize()
156 #if ENABLE(TIZEN_DEVICE_ORIENTATION)
157 WebCore::provideDeviceMotionTo(m_page.get(), new DeviceMotionClientTizen);
158 WebCore::provideDeviceOrientationTo(m_page.get(), new DeviceOrientationClientTizen);
160 #if ENABLE(TIZEN_ISF_PORT)
161 m_isSettingComposition = false;
165 #if ENABLE(TIZEN_PREFERENCE)
166 void WebPage::platformPreferencesDidChange(const WebPreferencesStore& store)
168 Settings* settings = m_page->settings();
169 settings->setInteractiveFormValidationEnabled(store.getBoolValueForKey(WebPreferencesKey::interactiveFormValidationEnabledKey()));
170 settings->setViewWidth(store.getUInt32ValueForKey(WebPreferencesKey::viewWidthKey()));
171 settings->setViewHeight(store.getUInt32ValueForKey(WebPreferencesKey::viewHeightKey()));
172 settings->setUsesEncodingDetector(store.getBoolValueForKey(WebPreferencesKey::usesEncodingDetectorKey()));
173 #if ENABLE(TIZEN_LOAD_REMOTE_IMAGES)
174 settings->setLoadRemoteImages(store.getBoolValueForKey(WebPreferencesKey::loadRemoteImagesKey()));
176 #if ENABLE(TIZEN_ISF_PORT)
177 settings->setEnableDefaultKeypad(store.getBoolValueForKey(WebPreferencesKey::defaultKeypadEnabledKey()));
179 #if ENABLE(TIZEN_STYLE_SCOPED)
180 WebCore::RuntimeEnabledFeatures::setStyleScopedEnabled(store.getBoolValueForKey(WebPreferencesKey::styleScopedEnabledKey()));
182 #if ENABLE(TIZEN_WEB_AUDIO)
183 settings->setWebAudioEnabled(true);
187 void WebPage::platformPreferencesDidChange(const WebPreferencesStore&)
191 #endif // #if ENABLE(TIZEN_PREFERENCE)
193 static inline void scroll(Page* page, ScrollDirection direction, ScrollGranularity granularity)
195 page->focusController()->focusedOrMainFrame()->eventHandler()->scrollRecursively(direction, granularity);
198 bool WebPage::performDefaultBehaviorForKeyEvent(const WebKeyboardEvent& keyboardEvent)
204 bool WebPage::platformHasLocalDataForURL(const KURL&)
210 String WebPage::cachedResponseMIMETypeForURL(const KURL&)
216 bool WebPage::platformCanHandleRequest(const ResourceRequest&)
222 String WebPage::cachedSuggestedFilenameForURL(const KURL&)
228 PassRefPtr<SharedBuffer> WebPage::cachedResponseDataForURL(const KURL&)
234 const char* WebPage::interpretKeyEvent(const KeyboardEvent* event)
236 ASSERT(event->type() == eventNames().keydownEvent || event->type() == eventNames().keypressEvent);
238 if (event->type() == eventNames().keydownEvent)
239 return getKeyDownCommandName(event);
241 return getKeyPressCommandName(event);
244 void WebPage::setThemePath(const String& themePath)
246 WebCore::RenderThemeEfl* theme = static_cast<WebCore::RenderThemeEfl*>(m_page->theme());
247 theme->setThemePath(themePath);
252 #if ENABLE(TIZEN_WEBKIT2_TILED_BACKING_STORE)
253 IntSize WebPage::contentsSize() const
255 FrameView* frameView = m_page->mainFrame()->view();
257 return IntSize(0, 0);
259 return frameView->contentsSize();
263 void WebPage::scrollMainFrameBy(const IntSize& scrollOffset)
265 m_page->mainFrame()->view()->scrollBy(scrollOffset);
268 void WebPage::scrollMainFrameTo(const IntPoint& scrollPosition)
270 m_page->mainFrame()->view()->setScrollPosition(scrollPosition);
273 void WebPage::createSnapshot(const IntRect rect, float scaleFactor, ShareableBitmap::Handle& snapshotHandle)
275 FrameView* frameView = m_mainFrame->coreFrame()->view();
279 RefPtr<WebImage> snapshotImage = scaledSnapshotInViewCoordinates(rect, scaleFactor, ImageOptionsShareable);
280 if (!snapshotImage || !snapshotImage->bitmap())
283 snapshotImage->bitmap()->createHandle(snapshotHandle);
286 void WebPage::requestUpdateFormNavigation()
288 Frame* frame = m_page->focusController()->focusedOrMainFrame();
292 Document* document = frame->document();
296 Node* focusedNode = document->focusedNode();
298 Vector<RefPtr<Node> > focusableNodes;
299 document->getFocusableNodes(focusableNodes);
301 int formElementCount = 0;
302 int currentNodeIndex = -1;
303 const Vector<RefPtr<Node> >::iterator end = focusableNodes.end();
304 for (Vector<RefPtr<Node> >::iterator it = focusableNodes.begin(); it != end; ++it) {
305 AtomicString nodeName = (*it).get()->nodeName();
306 if (equalIgnoringCase(nodeName, "SELECT")
307 || (equalIgnoringCase(nodeName, "INPUT")
308 && !equalIgnoringCase((*it).get()->toInputElement()->type(), "CHECKBOX")
309 && !equalIgnoringCase((*it).get()->toInputElement()->type(), "RADIO")
310 && !equalIgnoringCase((*it).get()->toInputElement()->type(), "SUBMIT")
313 if ((*it).get() == focusedNode)
314 currentNodeIndex = formElementCount;
319 if (currentNodeIndex == -1)
322 send(Messages::WebPageProxy::UpdateFormNavigation(formElementCount, currentNodeIndex));
325 void WebPage::moveFocus(int newIndex)
327 Frame* frame = m_page->focusController()->focusedOrMainFrame();
331 Document* document = frame->document();
335 Vector<RefPtr<Node> > focusableNodes;
336 document->getFocusableNodes(focusableNodes);
339 const Vector<RefPtr<Node> >::iterator end = focusableNodes.end();
340 for (Vector<RefPtr<Node> >::iterator it = focusableNodes.begin(); it != end; ++it) {
341 AtomicString nodeName = (*it).get()->nodeName();
342 if (equalIgnoringCase(nodeName, "SELECT")) {
343 if (index == newIndex) {
344 (*it).get()->setFocus();
345 LayoutPoint position = LayoutPoint(0, 0);
346 PlatformMouseEvent event(flooredIntPoint(position), flooredIntPoint(position), LeftButton, PlatformEvent::MouseMoved, 1, false, false, false, false, 0);
347 (*it).get()->dispatchMouseEvent(event, "mousedown", 0, 0);
350 } else if (equalIgnoringCase(nodeName, "INPUT")
351 && !equalIgnoringCase((*it).get()->toInputElement()->type(), "CHECKBOX")
352 && !equalIgnoringCase((*it).get()->toInputElement()->type(), "RADIO")
354 if (index == newIndex) {
355 HTMLInputElement* elem = (*it).get()->toInputElement();
363 #if ENABLE(TIZEN_MOBILE_WEB_PRINT)
364 #define INCH_TO_MM 25.4
365 #define INCH_TO_POINTS 72.0
367 void WebPage::createPagesToPDF(const IntSize& surfaceSize, const IntSize& contentsSize, const String& fileName)
369 FrameView* frameView = m_mainFrame->coreFrame()->view();
373 RefPtr<WebImage> pageshotImage = WebImage::create(contentsSize, ImageOptionsShareable);
374 if (!pageshotImage->bitmap())
377 double pdfWidth = (double)surfaceSize.width() / INCH_TO_MM * INCH_TO_POINTS;
378 double pdfHeight = (double)surfaceSize.height() / INCH_TO_MM * INCH_TO_POINTS;
379 double scaleFactorPdf = 1.0;
380 if (contentsSize.width() > pdfWidth)
381 scaleFactorPdf = pdfWidth / (double)contentsSize.width();
383 OwnPtr<WebCore::GraphicsContext> graphicsContext = pageshotImage->bitmap()->createGraphicsContextForPdfSurface(fileName, pdfWidth, pdfHeight);
384 graphicsContext->scale(FloatSize(scaleFactorPdf, scaleFactorPdf));
386 frameView->updateLayoutAndStyleIfNeededRecursive();
388 int pageNumber = ((contentsSize.height() * scaleFactorPdf) / pdfHeight) + 1;
391 PaintBehavior oldBehavior = frameView->paintBehavior();
392 frameView->setPaintBehavior(oldBehavior | PaintBehaviorFlattenCompositingLayers);
393 for (int i = 0; i < pageNumber; i++) {
394 IntRect paintRect(0, (int)paintY, contentsSize.width(), (int)(pdfHeight / scaleFactorPdf));
396 frameView->paint(graphicsContext.get(), paintRect);
397 cairo_show_page(graphicsContext->platformContext()->cr());
398 graphicsContext->translate(0, -ceil(pdfHeight / scaleFactorPdf));
399 paintY += (pdfHeight / scaleFactorPdf);
401 frameView->setPaintBehavior(oldBehavior);
403 pageshotImage.release();
407 void WebPage::confirmComposition(const String& compositionString)
409 Frame* frame = m_page->focusController()->focusedOrMainFrame();
410 if (!frame || !frame->editor()->canEdit())
412 frame->editor()->confirmComposition(compositionString);
413 #if ENABLE(TIZEN_ISF_PORT)
414 updateCursorOffset();
418 void WebPage::setComposition(const String& compositionString, const Vector<WebCore::CompositionUnderline>& underlines, uint64_t cursorPosition)
420 Frame* frame = m_page->focusController()->focusedOrMainFrame();
421 if (!frame || !frame->editor()->canEdit())
423 #if ENABLE(TIZEN_ISF_PORT)
424 if (frame->selection()->rootEditableElement()) {
425 HTMLTextFormControlElement* textFormControl = toTextFormControl(frame->selection()->rootEditableElement()->shadowAncestorNode());
426 if (textFormControl && textFormControl->maxLength() >= 0) {
427 unsigned availableLength = textFormControl->maxLength() - textFormControl->value().length();
428 if (frame->editor()->hasComposition())
429 availableLength += (frame->editor()->compositionEnd() - frame->editor()->compositionStart());
430 if (!availableLength)
433 if (availableLength < compositionString.length()) {
434 String newCompositionString = compositionString.substring(0, availableLength);
435 Vector<CompositionUnderline> newUnderlines;
436 size_t numUnderlines = underlines.size();
437 for (size_t index = 0; index < numUnderlines; ++index) {
438 if (underlines[index].startOffset < availableLength) {
439 newUnderlines.append(underlines[index]);
440 if (newUnderlines.last().endOffset > availableLength)
441 newUnderlines.last().endOffset = availableLength;
444 frame->editor()->setComposition(newCompositionString, newUnderlines, cursorPosition, 0);
449 m_isSettingComposition = true;
451 frame->editor()->setComposition(compositionString, underlines, cursorPosition, 0);
452 #if ENABLE(TIZEN_ISF_PORT)
453 m_isSettingComposition = false;
454 updateCursorOffset();
458 #if ENABLE(TIZEN_TEXT_CARET_HANDLING_WK2)
459 bool WebPage::setCaretPosition(const WebCore::IntPoint& pos)
461 Frame* frame = m_page->focusController()->focusedOrMainFrame();
465 WebCore::FrameSelection* controller = frame->selection();
469 FrameView* frameView = frame->view();
473 WebCore::IntPoint point = m_page->mainFrame()->view()->windowToContents(pos);
474 WebCore::HitTestResult result = m_page->mainFrame()->eventHandler()->hitTestResultAtPoint(point, /*allowShadowContent*/ true, /*ignoreClipping*/ true);
475 if (result.scrollbar())
478 WebCore::Node* innerNode = result.innerNode();
480 if (!innerNode || !innerNode->renderer())
483 WebCore::VisiblePosition visiblePos;
485 // we check if content is richly editable - because those input field behave other than plain text ones
486 // sometimes they may consists a node structure and they need special approach
487 if (innerNode->rendererIsRichlyEditable()) {
488 // point gets inner node local coordinates
489 point = flooredIntPoint(result.localPoint());
490 WebCore::IntRect rect = innerNode->renderer()->absoluteBoundingBoxRect(true);
492 // it is not the best way to do this, but it is not as slow and it works - so maybe in the future someone
493 // will have a better idea how to solve it
494 // here we are getting innerNode from HitTestResult - unfortunately this is a kind of high level node
495 // in the code below I am trying to obtain low level node - #text - to get its coordinates and size
497 // all those getting nodes rects are needed to bypass WebCore's methods of positioning caret when user
498 // is clicking outside a node - and cheat WebCore telling it that actually we clicked into input field
499 // node, not outside of it
500 WebCore::Node* deepInnerNode = innerNode->renderer()->positionForPoint(point).deepEquivalent().deprecatedNode();
502 if (!deepInnerNode || !deepInnerNode->renderer())
505 // so we get a base node rectange
506 WebCore::IntRect deepNodeRect = deepInnerNode->renderer()->absoluteBoundingBoxRect(true);
508 // we modify our local point to adjust it to base node local coordinates
509 point.move(rect.x() - deepNodeRect.x(), rect.y() - deepNodeRect.y());
511 // if we are outside the rect we cheat, that we are just inside of it
514 else if (point.y() >= deepNodeRect.height())
515 point.setY(deepNodeRect.height() - 1);
517 // visible position created - caret ready to set
518 visiblePos = deepInnerNode->renderer()->positionForPoint(point);
519 if (visiblePos.isNull())
522 // for plain text input fields we can get only a caret bounding box
523 if (!controller->isCaret() || !controller->caretRenderer())
526 const WebCore::Node* node = controller->start().deprecatedNode();
527 if (!node || !node->renderer())
530 WebCore::IntRect rect = controller->caretRenderer()->absoluteBoundingBoxRect(true);
532 // FIXME: The below codes should be updated to apply the positon of focusedFrame.
534 // here we also cheat input field that we actually are just inside of if
535 if (point.x() < rect.x())
536 point.setX(rect.x());
537 else if (point.x() > rect.maxX())
538 point.setX(rect.maxX());
540 const int boundariesWidth = 2;
541 if (point.y() < rect.y() + boundariesWidth)
542 point.setY(rect.y() + boundariesWidth);
543 else if (point.y() >= rect.maxY() - boundariesWidth)
544 point.setY(rect.maxY() - boundariesWidth - 1);
547 // hit test with fake (adjusted) coordinates
548 WebCore::IntPoint hitTestPoint = m_page->mainFrame()->view()->windowToContents(point);
549 WebCore::HitTestResult newResult = m_page->mainFrame()->eventHandler()->hitTestResultAtPoint(hitTestPoint, /*allowShadowContent*/ true, /*ignoreClipping*/ true);
551 if (!newResult.isContentEditable())
554 WebCore::Node* newInnerNode = newResult.innerNode();
556 if (!newInnerNode || !newInnerNode->renderer())
559 // visible position created
560 visiblePos = newInnerNode->renderer()->positionForPoint(newResult.localPoint());
561 if (visiblePos.isNull())
565 // create visible selection from visible position
566 WebCore::VisibleSelection newSelection = WebCore::VisibleSelection(visiblePos);
567 controller->setSelection(newSelection, WebCore::CharacterGranularity);
568 // after setting selection caret blinking is suspended by default so we are unsuspedning it
569 controller->setCaretBlinkingSuspended(false);
574 void WebPage::getCaretPosition(WebCore::IntRect& rect)
576 Frame* frame = m_page->focusController()->focusedOrMainFrame();
580 WebCore::FrameSelection* controller = frame->selection();
584 WebCore::Node* node = controller->start().deprecatedNode();
585 if (!node || !node->renderer() || !node->isContentEditable())
588 if (controller->isCaret()) {
589 FrameView* frameView = frame->view();
593 rect = frameView->contentsToWindow(controller->absoluteCaretBounds());
598 #if ENABLE(TIZEN_ISF_PORT)
599 void WebPage::updateCursorOffset()
602 getCursorOffset(offset);
603 send(Messages::WebPageProxy::UpdateCursorOffset(offset));
606 void WebPage::didCancelComposition(Node* valueChangedNode)
608 if (m_isSettingComposition)
611 Frame* frame = m_page->focusController()->focusedOrMainFrame();
612 if (!frame || !valueChangedNode->containsIncludingShadowDOM(frame->editor()->compositionNode()))
615 frame->editor()->cancelComposition();
616 send(Messages::WebPageProxy::DidCancelComposition());
619 void WebPage::getCursorOffset(int& offset)
622 Frame* frame = m_page->focusController()->focusedOrMainFrame();
623 if (!frame || !frame->editor()->canEdit())
626 Position base = frame->selection()->base();
627 Node* baseNode = base.containerNode();
629 offset = baseNode->isTextNode() ? base.offsetInContainerNode() : 0;
632 void WebPage::getSurroundingTextAndCursorOffset(String& text, int& offset)
637 Frame* frame = m_page->focusController()->focusedOrMainFrame();
638 if (!frame || !frame->editor()->canEdit())
641 Position base = frame->selection()->base();
642 Node* baseNode = base.containerNode();
643 if (baseNode && baseNode->isTextNode()) {
644 text = baseNode->textContent();
645 offset = base.offsetInContainerNode();
649 void WebPage::getSelectionRect(bool isOnlyEditable, IntRect& rect)
653 Frame* frame = m_page->focusController()->focusedFrame();
654 if (!frame || !frame->view())
657 FrameSelection* selection = frame->selection();
658 Node* node = selection->start().deprecatedNode();
659 if (!node || !node->renderer() || (isOnlyEditable && !node->isContentEditable()))
662 if (selection->isCaret())
663 rect = frame->view()->contentsToWindow(selection->absoluteCaretBounds());
664 else if (selection->isRange())
665 rect = frame->view()->contentsToWindow(enclosingIntRect(selection->bounds()));
668 void WebPage::deleteSurroundingText(int offset, int count)
670 Frame* frame = m_page->focusController()->focusedOrMainFrame();
671 if (!frame || !frame->editor()->canEdit())
674 Position base(frame->selection()->base());
675 offset += base.offsetInContainerNode();
676 base.moveToOffset(offset);
677 Position extent(base);
678 extent.moveToOffset(offset + count);
679 VisibleSelection selection(base, extent);
680 if (!selection.isRange())
683 frame->selection()->setSelection(selection);
684 frame->editor()->deleteWithDirection(DirectionBackward, CharacterGranularity, false, true);
688 #if ENABLE(TIZEN_INPUT_TAG_EXTENSION) || ENABLE(TIZEN_WEBKIT2_FORM_DATABASE)
689 void WebPage::setFocusedInputElementValue(const String& inputValue)
691 Frame* frame = m_page->focusController()->focusedOrMainFrame();
692 if (!frame || !frame->document() || !frame->document()->focusedNode())
695 HTMLInputElement* inputElement = frame->document()->focusedNode()->toInputElement();
699 inputElement->toNode()->dispatchFocusEvent(0);
700 inputElement->setValue(inputValue, DispatchChangeEvent);
702 updateCursorOffset();
705 void WebPage::getFocusedInputElementValue(String& inputValue)
707 inputValue = String();
709 Frame* frame = m_page->focusController()->focusedOrMainFrame();
710 if (!frame || !frame->document() || !frame->document()->focusedNode())
713 HTMLInputElement* inputElement = frame->document()->focusedNode()->toInputElement();
717 inputValue = inputElement->value();
721 #if ENABLE(TIZEN_DATALIST_ELEMENT)
722 void WebPage::getFocusedInputElementDataList(Vector<String>& optionList)
724 Frame* frame = m_page->focusController()->focusedOrMainFrame();
725 if (!frame || !frame->document())
728 Node* node = frame->document()->focusedNode();
732 HTMLInputElement* input = node->toInputElement();
736 HTMLDataListElement* dataList = static_cast<HTMLDataListElement*>(input->list());
740 RefPtr<HTMLCollection> options = static_cast<HTMLDataListElement*>(dataList)->options();
741 for (unsigned i = 0; Node* node = options->item(i); i++) {
742 HTMLOptionElement* optionElement = static_cast<HTMLOptionElement*>(node);
743 String value = optionElement->value();
744 optionList.append(value);
749 #if ENABLE(TIZEN_WEBKIT2_FOCUS_RING)
750 static IntRect getNodeRect(Node* node, Node* focusableNode, bool isImage)
756 IntRect imageNodeRect = pixelSnappedIntRect(node->getRect());
757 if (!focusableNode->renderRect(&isReplaced).isEmpty() && imageNodeRect.contains(pixelSnappedIntRect(focusableNode->getRect()))) {
758 // If render rect of focusableNode is empty and rect of imageNode include rect of focusableNode,
759 // we have to get rect of focusableNode.
760 // for example - The rect of google logo image in www.google.com pc site's search result page is bigger than rect of focusableNode.
761 // for example - The rect of category menu image in www.gmarket.co.kr pc site is bigger than rect of focusableNode.
762 rect = pixelSnappedIntRect(focusableNode->getRect());
765 // otherwise we have to get rect of imageNode.
766 // for example - The render rect of images in www.pudelek.pl is empty.
767 // 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.
768 rect = imageNodeRect;
769 focusableNode = node;
772 // If focusedNode have multiple child nodes, we have to unite rect of child nodes.
773 // for example - links in www.google.com's search result page.
775 for (Node* childNode = focusableNode->firstChild(); childNode; childNode = childNode->traverseNextNode(focusableNode)) {
777 if (focusableNode->renderRect(&isReplaced).contains(childNode->getRect()))
778 tempRect.unite(pixelSnappedIntRect(childNode->getRect()));
781 // If tempRect is empty or rect of focusableNode include tempRect,
782 // we have to get rect of focusableNode.
783 // for example - list menu item in m.naver.com.
784 // otherwise we have to get rect of tempRect.
785 // getRect API do not return correct rect if the node is a container node,
786 // hence using absoluteBoundingBoxRect to get the correct bounding rect.
787 LayoutRect renderRect = focusableNode->renderer() ? focusableNode->renderer()->absoluteBoundingBoxRect() : focusableNode->getRect();
788 if (tempRect.isEmpty() || renderRect.contains(tempRect))
789 rect = pixelSnappedIntRect(renderRect);
794 // We have to get render rect from ancestor node if current rect is empty.
795 // for example - The rect of naver logo image in www.naver.com pc site is empty.
797 for (Node* loopNode = focusableNode; loopNode && rect.isEmpty(); loopNode = loopNode->parentNode()) {
798 RenderObject* renderer = loopNode->renderer();
799 if (renderer && renderer->isRoot())
802 rect = pixelSnappedIntRect(loopNode->renderRect(&isReplaced));
805 Frame* nodeFrame = focusableNode->document()->frame();
807 while (nodeFrame && (owner = nodeFrame->ownerElement())) {
808 rect.moveBy(owner->getRect().pixelSnappedLocation());
809 nodeFrame = owner->document()->frame();
812 // The y position of tab menu item in www.google.com is negative value,
813 // so we do not want to draw focus ring in that case.
814 if ((rect.maxX() < 0) || (rect.maxY() < 0))
821 #if ENABLE(TIZEN_WEBKIT2_HIT_TEST)
822 #if ENABLE(TIZEN_WEBKIT2_FOCUS_RING)
823 static IntRect getFocusedRect(HitTestResult hitTestResult, Page* page)
825 Node* node = hitTestResult.innerNode();
826 bool isFocusRingDrawable = false;
827 Node* focusableNode = node;
828 while (focusableNode) {
829 RenderObject* renderer = focusableNode->renderer();
830 if (renderer && renderer->isRoot())
833 if (focusableNode->isFocusable()) {
834 if (focusableNode->isLink()
835 || focusableNode->hasTagName(HTMLNames::inputTag)
836 || focusableNode->hasTagName(HTMLNames::selectTag)
837 || focusableNode->hasTagName(HTMLNames::buttonTag))
838 isFocusRingDrawable = true;
842 focusableNode = focusableNode->parentNode();
845 if (!isFocusRingDrawable)
848 return getNodeRect(node, focusableNode, !hitTestResult.absoluteImageURL().isEmpty());
852 void WebPage::hitTestResultAtPoint(const IntPoint& point, int hitTestMode, WebHitTestResult::Data& hitTestResultData)
854 Frame* frame = m_page->mainFrame();
855 FrameView* frameView = frame->view();
859 HitTestResult hitTestResult = frame->eventHandler()->hitTestResultAtPoint(frameView->windowToContents(point), false);
860 hitTestResultData.absoluteImageURL = hitTestResult.absoluteImageURL().string();
861 hitTestResultData.absoluteLinkURL = hitTestResult.absoluteLinkURL().string();
862 hitTestResultData.absoluteMediaURL = hitTestResult.absoluteMediaURL().string();
863 hitTestResultData.linkLabel = hitTestResult.textContent();
864 hitTestResultData.linkTitle = hitTestResult.titleDisplayString();
865 #if ENABLE(TIZEN_DRAG_SUPPORT)
866 hitTestResultData.isDragSupport = hitTestResult.isDragSupport();
869 int context = WebHitTestResult::HitTestResultContextDocument;
871 if (!hitTestResult.absoluteLinkURL().isEmpty())
872 context |= WebHitTestResult::HitTestResultContextLink;
873 if (!hitTestResult.absoluteImageURL().isEmpty())
874 context |= WebHitTestResult::HitTestResultContextImage;
875 if (!hitTestResult.absoluteMediaURL().isEmpty())
876 context |= WebHitTestResult::HitTestResultContextMedia;
877 if (hitTestResult.isSelected())
878 context |= WebHitTestResult::HitTestResultContextSelection;
879 if (hitTestResult.isContentEditable())
880 context |= WebHitTestResult::HitTestResultContextEditable;
881 if (hitTestResult.innerNonSharedNode() && hitTestResult.innerNonSharedNode()->isTextNode())
882 context |= WebHitTestResult::HitTestResultContextText;
884 hitTestResultData.context = context;
885 hitTestResultData.hitTestMode = hitTestMode;
887 #if ENABLE(TIZEN_WEBKIT2_FOCUS_RING)
888 hitTestResultData.focusedRect = getFocusedRect(hitTestResult, m_page.get());
889 if (hitTestResult.innerNode() && hitTestResult.innerNode()->renderer() && hitTestResult.innerNode()->renderer()->style()) {
890 hitTestResultData.focusedColor = hitTestResult.innerNode()->renderer()->style()->tapHighlightColor();
891 if (!hitTestResultData.focusedColor.hasAlpha())
892 hitTestResultData.focusedColor = Color(hitTestResultData.focusedColor.red(), hitTestResultData.focusedColor.green(), hitTestResultData.focusedColor.blue(), RenderStyle::initialTapHighlightColor().alpha());
896 if (hitTestResultData.hitTestMode & WebHitTestResult::HitTestModeNodeData) {
897 WebCore::Node* hitNode = hitTestResult.innerNonSharedNode();
899 hitTestResultData.nodeData.nodeValue = hitNode->nodeValue();
901 if ((hitTestResultData.context & WebHitTestResult::HitTestResultContextText) && hitNode->parentNode())
902 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.
904 if (hitNode->isElementNode()) {
905 WebCore::Element* hitElement = static_cast<WebCore::Element*>(hitNode);
907 hitTestResultData.nodeData.tagName = hitElement->tagName();
911 WebCore::NamedNodeMap* namedNodeMap = hitNode->attributes();
913 for (size_t i = 0; i < namedNodeMap->length(); i++) {
914 const WebCore::Attribute* attribute = namedNodeMap->element()->attributeItem(i);
915 String key = attribute->name().toString();
916 String value = attribute->value();
917 hitTestResultData.nodeData.attributeMap.add(key, value);
923 if ((hitTestResultData.hitTestMode & WebHitTestResult::HitTestModeImageData) && (hitTestResultData.context & WebHitTestResult::HitTestResultContextImage)) {
924 WebCore::Image* hitImage = hitTestResult.image();
925 if (hitImage && hitImage->data() && hitImage->data()->data()) {
926 hitTestResultData.imageData.data.append(hitImage->data()->data(), hitImage->data()->size());
927 hitTestResultData.imageData.fileNameExtension = hitImage->filenameExtension();
933 #if ENABLE(TIZEN_WEB_STORAGE)
934 void WebPage::getStorageQuotaBytes(uint64_t callbackID)
936 uint32_t quota = m_page->group().groupSettings()->localStorageQuotaBytes();
937 send(Messages::WebPageProxy::DidGetWebStorageQuotaBytes(quota, callbackID));
940 void WebPage::setStorageQuotaBytes(uint32_t quota)
942 m_page->group().groupSettings()->setLocalStorageQuotaBytes(quota);
946 #if ENABLE(TIZEN_RECORDING_SURFACE_SET)
947 void WebPage::recordingSurfaceSetEnableSet(bool enable)
949 m_recordingSurfaceSetSettings = enable;
953 #if ENABLE(TIZEN_CLIPBOARD) || ENABLE(TIZEN_PASTEBOARD)
954 void WebPage::setClipboardDataForPaste(const String& data, const String& type)
956 #if ENABLE(TIZEN_PASTEBOARD)
957 // FIXME: Should move to EditorClient like Clipboard
958 Pasteboard::generalPasteboard()->setDataWithType(data, type);
960 Frame* mainFrame = m_page->mainFrame();
964 mainFrame->editor()->client()->setClipboardDataForPaste(data, type);
969 void WebPage::suspendJavaScriptAndResources()
971 Frame* mainFrame = m_page->mainFrame();
975 for (Frame* frame = mainFrame; frame; frame = frame->tree()->traverseNext())
976 frame->document()->suspendScheduledTasks(WebCore::ActiveDOMObject::PageWillBeSuspended);
977 mainFrame->loader()->suspendAllLoaders();
980 void WebPage::resumeJavaScriptAndResources()
982 Frame* mainFrame = m_page->mainFrame();
986 for (Frame* frame = mainFrame; frame; frame = frame->tree()->traverseNext())
987 frame->document()->resumeScheduledTasks();
988 mainFrame->loader()->resumeAllLoaders();
991 #if ENABLE(TIZEN_SYNC_REQUEST_ANIMATION_FRAME)
992 void WebPage::suspendAnimationController()
994 if (!m_suspendedAnimationController) {
995 Frame* mainFrame = m_page->mainFrame();
999 for (Frame* frame = mainFrame; frame; frame = frame->tree()->traverseNext())
1000 frame->document()->suspendScriptedAnimationControllerCallbacks();
1002 m_suspendedAnimationController = true;
1006 void WebPage::resumeAnimationController()
1008 if (m_suspendedAnimationController) {
1009 Frame* mainFrame = m_page->mainFrame();
1013 for (Frame* frame = mainFrame; frame; frame = frame->tree()->traverseNext())
1014 frame->document()->resumeScriptedAnimationControllerCallbacks();
1016 m_suspendedAnimationController = false;
1021 #if ENABLE(TIZEN_WEBKIT2_REMOTE_WEB_INSPECTOR)
1022 void WebPage::startInspectorServer(uint32_t port, uint32_t& allocatedPort)
1024 bool ret = WebInspectorServerEfl::server()->startServer(port);
1026 allocatedPort = WebInspectorServerEfl::server()->getServerPort();
1031 void WebPage::stopInspectorServer(bool& result)
1033 result = WebInspectorServerEfl::server()->stopServer();
1037 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION_ON_UI_SIDE)
1038 void WebPage::scrollOverflowWithTrajectoryVector(const WebCore::FloatPoint& trajectoryVector)
1040 Frame* frame = m_page->focusController()->focusedOrMainFrame();
1043 frame->eventHandler()->scrollOverflow(trajectoryVector);
1047 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION)
1048 void WebPage::scrollOverflow(const WebCore::FloatPoint& delta, bool& scrolled)
1050 scrolled = m_page->focusController()->focusedOrMainFrame()->eventHandler()->scrollOverflow(delta);
1053 void WebPage::setPressedNodeAtPoint(const IntPoint& point, bool checkOverflowLayer, bool& pressed, uint32_t& id)
1055 RenderObject* renderer = 0;
1057 pressed = m_page->focusController()->focusedOrMainFrame()->eventHandler()->setMousePressNodeAtPoint(point, checkOverflowLayer, renderer);
1058 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION_ON_UI_SIDE)
1059 if (pressed && renderer)
1060 id = toWebGraphicsLayer(renderer->enclosingLayer()->layerForScrollingContents())->id();
1065 void WebPage::executeEditCommandWithArgument(const String& commandName, const String& argument)
1067 executeEditingCommand(commandName, argument);
1070 #if ENABLE(TIZEN_PLUGIN_SUSPEND_RESUME)
1071 void WebPage::suspendPlugin()
1073 for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
1074 FrameView* view = frame->view();
1078 const HashSet<RefPtr<Widget> >* children = view->children();
1081 HashSet<RefPtr<Widget> >::const_iterator end = children->end();
1082 for (HashSet<RefPtr<Widget> >::const_iterator it = children->begin(); it != end; ++it) {
1083 Widget* widget = (*it).get();
1084 if (widget->isPluginViewBase()) {
1085 PluginView* pluginView = static_cast<PluginView*>(widget);
1087 pluginView->suspendPlugin();
1093 void WebPage::resumePlugin()
1095 for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
1096 FrameView* view = frame->view();
1100 const HashSet<RefPtr<Widget> >* children = view->children();
1103 HashSet<RefPtr<Widget> >::const_iterator end = children->end();
1104 for (HashSet<RefPtr<Widget> >::const_iterator it = children->begin(); it != end; ++it) {
1105 Widget* widget = (*it).get();
1106 if (widget->isPluginViewBase()) {
1107 PluginView* pluginView = static_cast<PluginView*>(widget);
1109 pluginView->resumePlugin();
1116 #if ENABLE(TIZEN_WEBKIT2_GET_TEXT_STYLE_FOR_SELECTION)
1117 void WebPage::getTextStyleStateForSelection()
1119 Frame* frame = m_page->focusController()->focusedOrMainFrame();
1121 int underlineState = frame->editor()->selectionHasStyle(CSSPropertyWebkitTextDecorationsInEffect, "underline");
1122 int italicState = frame->editor()->selectionHasStyle(CSSPropertyFontStyle, "italic");
1123 int boldState = frame->editor()->selectionHasStyle(CSSPropertyFontWeight, "bold");
1125 send(Messages::WebPageProxy::DidGetTextStyleStateForSelection(underlineState, italicState, boldState));
1129 #if ENABLE(TIZEN_MULTIPLE_SELECT)
1130 void WebPage::didChangeSelectedIndexForActivePopupMenuMultiple(Vector<int32_t> newIndex)
1132 if (!m_activePopupMenu)
1135 m_activePopupMenu->client()->popupDidHide();
1137 size_t indexSize = newIndex.size();
1138 for (size_t i = 0; i < indexSize; i++)
1139 m_activePopupMenu->didChangeSelectedIndex(newIndex.at(i));
1144 #if ENABLE(TIZEN_OFFLINE_PAGE_SAVE)
1145 void WebPage::startOfflinePageSave(String subresourceFolderName)
1147 WebPageSerializerTizen::getSerializedPageContent(this, subresourceFolderName);
1151 #if ENABLE(TIZEN_WEBKIT2_TEXT_SELECTION)
1152 void WebPage::selectClosestWord(const IntPoint& point, bool isStartedTextSelectionFromOutside, bool& result)
1156 Frame* mainFrame = m_page->mainFrame();
1157 Frame* focusedFrame = m_page->focusController()->focusedOrMainFrame();
1159 HitTestResult hitTestResult = mainFrame->eventHandler()->hitTestResultAtPoint(m_page->mainFrame()->view()->windowToContents(point), false);
1161 Node* node = hitTestResult.innerNonSharedNode();
1165 Frame* newFocusFrame = node->document()->frame();
1166 if (focusedFrame != newFocusFrame) {
1167 m_page->focusController()->setFocusedFrame(newFocusFrame);
1168 focusedFrame = newFocusFrame;
1171 #if ENABLE(TIZEN_INPUT_TAG_EXTENSION)
1172 HTMLInputElement* inputElement = node->toInputElement();
1175 if (hitTestResult.isContentEditable()) {
1176 #if ENABLE(TIZEN_ISF_PORT)
1178 didCancelComposition(node);
1180 #if ENABLE(TIZEN_INPUT_TAG_EXTENSION)
1181 if (!inputElement || (inputElement
1182 && !inputElement->isDateField() && !inputElement->isDateTimeField() && !inputElement->isDateTimeLocalField()
1183 && !inputElement->isMonthField() && !inputElement->isTimeField() && !inputElement->isWeekField())) {
1184 result = setCaretPosition(point);
1188 result = setCaretPosition(point);
1193 #if ENABLE(TIZEN_INPUT_TAG_EXTENSION)
1194 if (!node->isTextNode() && !inputElement)
1196 if (!node->isTextNode())
1200 if (!isStartedTextSelectionFromOutside) {
1201 for (Node* node = hitTestResult.innerNonSharedNode(); node; node = node->parentNode()) {
1202 if (node->isFocusable()) {
1203 // Text selection shoud not be started when text of <button> tag is selected.
1204 if (node->hasTagName(HTMLNames::buttonTag))
1211 FrameSelection* frameSelection = focusedFrame->selection();
1213 VisiblePosition position = mainFrame->visiblePositionForPoint(point);
1214 VisibleSelection selection(position);
1216 // This changes just the 'start' and 'end' positions of the VisibleSelection
1217 selection.expandUsingGranularity(WordGranularity);
1219 FrameSelection::SetSelectionOptions options = FrameSelection::CloseTyping | FrameSelection::ClearTypingStyle | FrameSelection::DoNotSetFocus;
1220 frameSelection->setSelection(VisibleSelection(selection.start(), selection.end()), options);
1222 if (!frameSelection->isRange())
1225 // This changes just the 'start' and 'end' positions of the VisibleSelection
1226 // Find handlers positions
1227 IntRect leftRect, rightRect;
1228 getSelectionHandlers(leftRect, rightRect);
1229 if (leftRect.size().isZero() && rightRect.size().isZero()) {
1230 // Sometimes there is no selected text, but isNone() returns TRUE
1231 // in this case ewk_frame_selection_handlers_get() returns FALSE and handlers are invalid
1232 // Workaround - clear the selection.
1233 // Better solution would be to modify the ewk_frame_select_closest_word()
1234 // to not select anything in the first place (for example - don't call setSelection()
1235 // if there is nothing under the cursor).
1236 selectionClearAllSelection(m_page->mainFrame());
1243 void WebPage::setLeftSelection(const WebCore::IntPoint& point, bool& result)
1247 Frame* focusedFrame = m_page->focusController()->focusedOrMainFrame();
1248 WebCore::FrameSelection* frameSelection = focusedFrame->selection();
1249 if (!frameSelection->isRange())
1252 WebCore::Node* selectionEndNode = frameSelection->end().deprecatedNode();
1253 if (!selectionEndNode || !selectionEndNode->renderer())
1256 FrameView* frameView = focusedFrame->view();
1260 WebCore::IntPoint pos = frameView->windowToContents(point);
1261 WebCore::IntRect leftRect, rightRect;
1262 getSelectionHandlers(leftRect, rightRect);
1263 if ((rightRect.y() + rightRect.height()) < pos.y())
1264 pos.setY(rightRect.y() + (rightRect.height()/2));
1266 if (selectionEndNode->rendererIsEditable() && !selectionEndNode->rendererIsRichlyEditable()) {
1267 const int boundariesWidth = 2;
1269 WebCore::IntRect rect = frameSelection->caretRenderer()->absoluteBoundingBoxRect(true);
1270 // here we cheat input field that we actually are just inside of if
1271 if (pos.y() < rect.y() + boundariesWidth)
1272 pos.setY(rect.y() + boundariesWidth);
1273 else if (pos.y() >= rect.maxY() - boundariesWidth)
1274 pos.setY(rect.maxY() - boundariesWidth - 1);
1277 OwnPtr<WebCore::VisiblePosition> position = adoptPtr(new WebCore::VisiblePosition(focusedFrame->visiblePositionForPoint(pos)));
1278 WebCore::Position extent = frameSelection->extent();
1280 WebCore::Node* newSelectionStartNode = position->deepEquivalent().deprecatedNode();
1282 // both start and end nodes should be in the same area type: both should be editable or both should be not editable
1283 // Check if the new position is before the extent's position
1284 if (newSelectionStartNode
1285 && selectionEndNode->isContentEditable() == newSelectionStartNode->isContentEditable()
1286 && WebCore::comparePositions(position->deepEquivalent(), extent) < 0) {
1287 // Change the 'base' and 'extent' positions to 'start' and 'end' positions.
1288 // We do it, because without this, the other modification of the selection
1289 // would destroy the 'start' and/or 'end' positions and set them to
1290 // the 'base'/'extent' positions accordingly
1291 WebCore::VisibleSelection sel(frameSelection->start(), frameSelection->end());
1292 frameSelection->setSelection(sel);
1294 bool oldProhibitsScrolling = focusedFrame->view()->prohibitsScrolling();
1295 focusedFrame->view()->setProhibitsScrolling(true);
1297 frameSelection->setBase(*position);
1299 focusedFrame->view()->setProhibitsScrolling(oldProhibitsScrolling);
1300 // This forces webkit to show selection
1301 // m_coreFrame->invalidateSelection();
1308 void WebPage::setRightSelection(const WebCore::IntPoint& point, bool& result)
1312 Frame* focusedFrame = m_page->focusController()->focusedOrMainFrame();
1313 WebCore::FrameSelection* frameSelection = focusedFrame->selection();
1315 if (!frameSelection->isRange())
1318 WebCore::Node* selectionStartNode = frameSelection->start().deprecatedNode();
1319 if (!selectionStartNode || !selectionStartNode->renderer())
1322 FrameView* frameView = focusedFrame->view();
1326 WebCore::IntPoint pos = frameView->windowToContents(point);
1327 if (selectionStartNode->rendererIsEditable() && !selectionStartNode->rendererIsRichlyEditable()) {
1328 const int boundariesWidth = 2;
1330 WebCore::IntRect rect = frameSelection->caretRenderer()->absoluteBoundingBoxRect(true);
1331 // here we cheat input field that we actually are just inside of if
1332 if (pos.y() < rect.y() + boundariesWidth)
1333 pos.setY(rect.y() + boundariesWidth);
1334 else if (pos.y() >= rect.maxY() - boundariesWidth)
1335 pos.setY(rect.maxY() - boundariesWidth - 1);
1338 OwnPtr<WebCore::VisiblePosition> position = adoptPtr(new WebCore::VisiblePosition(focusedFrame->visiblePositionForPoint(pos)));
1339 WebCore::Position base = frameSelection->base();
1341 WebCore::Node* newSelectionEndNode = position->deepEquivalent().deprecatedNode();
1343 // both start and end nodes should be in the same area type: both should be editable or both should be not editable
1344 // Check if the new position is after the base's position
1345 if (newSelectionEndNode
1346 && selectionStartNode->isContentEditable() == newSelectionEndNode->isContentEditable()
1347 && WebCore::comparePositions(position->deepEquivalent(), base) > 0) {
1348 // Change the 'base' and 'extent' positions to 'start' and 'end' positions.
1349 // We do it, because without this, the other modifications of the selection
1350 // would destroy the 'start' and/or 'end' positions and set them to
1351 // the 'base'/'extent' positions accordingly
1353 WebCore::VisibleSelection sel(frameSelection->start(), frameSelection->end());
1354 frameSelection->setSelection(sel);
1356 bool oldProhibitsScrolling = focusedFrame->view()->prohibitsScrolling();
1357 focusedFrame->view()->setProhibitsScrolling(true);
1359 frameSelection->setExtent(*position);
1361 focusedFrame->view()->setProhibitsScrolling(oldProhibitsScrolling);
1367 void WebPage::getSelectionHandlers(IntRect& leftRect, IntRect& rightRect)
1369 Frame* focusedFrame = m_page->focusController()->focusedOrMainFrame();
1370 if (!focusedFrame->selection()->isRange())
1373 // Is this check necessary? Leaving it for safety.
1374 WebCore::RenderView* root = focusedFrame->contentRenderer();
1378 RefPtr<WebCore::Range> selectedRange = focusedFrame->selection()->toNormalizedRange();
1380 Vector<WebCore::IntRect> rects;
1381 selectedRange->textRects(rects, true);
1383 unsigned size = rects.size();
1385 leftRect = rects[0];
1386 rightRect = rects[size-1];
1388 // If selection rect size is greater than editor rect size because of round operation,
1389 // selection rect size should be changed to editor rect size.
1391 Element* selectionRoot = focusedFrame->selection()->rootEditableElement();
1392 if (selectionRoot) {
1393 WebCore::IntRect editorRect = focusedFrame->view()->contentsToWindow(selectionRoot->getPixelSnappedRect());
1395 if (leftRect.maxY() > editorRect.maxY()) {
1396 leftRect.setY(editorRect.y());
1397 leftRect.setHeight(editorRect.height());
1400 if (rightRect.maxY() > editorRect.maxY()) {
1401 rightRect.setY(editorRect.y());
1402 rightRect.setHeight(editorRect.height());
1407 // prevent from selecting zero-length selection
1408 if (leftRect.x() == rightRect.x() + rightRect.width()
1409 && leftRect.y() == rightRect.y())
1412 FrameView* frameView = focusedFrame->view();
1416 leftRect = frameView->contentsToWindow(leftRect);
1417 rightRect = frameView->contentsToWindow(rightRect);
1421 void WebPage::getSelectionText(String& result)
1423 Frame* focusedFrame = m_page->focusController()->focusedOrMainFrame();
1424 result = focusedFrame->editor()->selectedText();
1427 void WebPage::selectionRangeClear(bool& result)
1431 Frame* focusedFrame = m_page->focusController()->focusedOrMainFrame();
1432 WebCore::FrameSelection* frameSelection = focusedFrame->selection();
1433 if (frameSelection && frameSelection->isRange() && frameSelection->isContentEditable()) {
1434 WebCore::VisiblePosition visiblePos(frameSelection->extent());
1435 if (visiblePos.isNull())
1437 WebCore::VisibleSelection newSelection = WebCore::VisibleSelection(visiblePos);
1438 frameSelection->setSelection(newSelection, WebCore::CharacterGranularity);
1439 frameSelection->setCaretBlinkingSuspended(false);
1441 selectionClearAllSelection(m_page->mainFrame());
1446 void WebPage::selectionClearAllSelection(Frame* frame)
1451 WebCore::FrameSelection* frameSelection = frame->selection();
1453 frameSelection->clear();
1458 if (frame->tree()->childCount() > 0) {
1459 if (frame->tree()->firstChild())
1460 selectionClearAllSelection(frame->tree()->firstChild());
1461 } else if (frame->tree()->nextSibling())
1462 selectionClearAllSelection(frame->tree()->nextSibling());
1467 #if ENABLE(TIZEN_LINK_MAGNIFIER)
1468 void WebPage::getLinkMagnifierRect(const IntPoint& position, const IntSize& size)
1470 send(Messages::WebPageProxy::DidGetLinkMagnifierRect(position, LinkMagnifier::rect(this, position, size)));
1474 #if ENABLE(TIZEN_SCREEN_READER)
1475 void WebPage::raiseTapEvent(const IntPoint& position, const IntPoint& globalPosition)
1477 Frame* frame = m_page->mainFrame();
1481 Vector<WebPlatformTouchPoint> touchPoints;
1482 touchPoints.append(WebPlatformTouchPoint(0, WebPlatformTouchPoint::TouchPressed, globalPosition, position));
1484 WebTouchEvent touchStartEvent(WebEvent::TouchStart, touchPoints, WebEvent::Modifiers(0), ecore_time_get());
1485 if (!frame->eventHandler()->handleTouchEvent(platform(touchStartEvent))) {
1486 WebGestureEvent gestureEvent(WebEvent::GestureSingleTap, position, globalPosition, WebEvent::Modifiers(0), ecore_time_get());
1487 frame->eventHandler()->handleGestureEvent(platform(gestureEvent));
1490 touchPoints.at(0).setState(WebPlatformTouchPoint::TouchReleased);
1491 WebTouchEvent touchEndEvent(WebEvent::TouchEnd, touchPoints, WebEvent::Modifiers(0), ecore_time_get());
1492 frame->eventHandler()->handleTouchEvent(platform(touchEndEvent));
1495 static void sendScreenReaderFocusRect(WebPage* page, Node* node)
1497 bool isImage = false;
1498 if (node->isElementNode()) {
1499 Element* element = static_cast<Element*>(node);
1500 isImage = !element->getAttribute(element->imageSourceAttributeName()).isEmpty();
1503 page->send(Messages::WebPageProxy::DidScreenReaderFocusRectChanged(getNodeRect(node, node, isImage)));
1506 void WebPage::moveScreenReaderFocus(bool forward, bool& result)
1508 if (!m_screenReader)
1509 m_screenReader = ScreenReader::create(this);
1511 if (!m_screenReader->moveFocus(forward)) {
1513 send(Messages::WebPageProxy::DidScreenReaderFocusRectChanged(IntRect()));
1517 sendScreenReaderFocusRect(this, m_screenReader->getFocusedNode());
1521 void WebPage::moveScreenReaderFocusByPoint(const IntPoint& point)
1523 if (!m_screenReader)
1524 m_screenReader = ScreenReader::create(this);
1526 if (!m_screenReader->moveFocus(point))
1529 sendScreenReaderFocusRect(this, m_screenReader->getFocusedNode());
1532 void WebPage::recalcScreenReaderFocusRect()
1534 if (!m_screenReader || !m_screenReader->getFocusedNode())
1537 sendScreenReaderFocusRect(this, m_screenReader->getFocusedNode());
1540 void WebPage::updateScreenReaderFocus(Node* willRemoveNode)
1542 if (!m_screenReader)
1545 if (!willRemoveNode)
1546 m_screenReader->clearFocus();
1547 else if (!m_screenReader->nodeWillBeRemoved(willRemoveNode))
1550 send(Messages::WebPageProxy::DidScreenReaderFocusRectChanged(IntRect()));
1553 void WebPage::clearScreenReader()
1555 m_screenReader.clear();
1559 #if ENABLE(TIZEN_WEBKIT2_POPUP_INTERNAL)
1560 // FIXME: Currently with cached pages, hiding Popup list menu is not working correctly.
1561 // This patch is a fix allowing any popup list menu to get close for any page navigation.
1562 void WebPage::notifyTransitionToCommitted(bool forNewPage)
1564 if (m_activePopupMenu) {
1566 m_activePopupMenu->hide();
1571 #if ENABLE(TIZEN_CSP)
1572 void WebPage::setContentSecurityPolicy(const String& policy, uint32_t headerType)
1574 Frame* frame = m_page->focusController()->focusedOrMainFrame();
1578 Document* document = frame->document();
1582 document->contentSecurityPolicy()->didReceiveHeader(policy, static_cast<WebCore::ContentSecurityPolicy::HeaderType>(headerType));
1586 #if ENABLE(TIZEN_INDEXED_DATABASE)
1587 void WebPage::setIndexedDatabaseDirectory(const String& path)
1589 m_page->group().groupSettings()->setIndexedDBDatabasePath(path);
1593 #if ENABLE(TIZEN_WEB_STORAGE)
1594 void WebPage::setLocalStorageDirectory(const String& path)
1596 m_page->settings()->setLocalStorageDatabasePath(path);
1599 #endif // #if OS(TIZEN)
1601 } // namespace WebKit