Implemented scrolling of text when the magnifier is on
[framework/web/webkit-efl.git] / Source / WebKit2 / WebProcess / WebPage / efl / WebPageEfl.cpp
1 /*
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.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
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.
14  *
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.
26  */
27
28 #include "config.h"
29 #include "WebPage.h"
30
31 #include "EditorState.h"
32 #include "NamedNodeMap.h"
33 #include "NotImplemented.h"
34 #include "WebEvent.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>
45
46 #if OS(TIZEN)
47 #include "Arguments.h"
48 #include "GraphicsContext.h"
49 #include "WebCoreArgumentCoders.h"
50 #include "WebFrame.h"
51 #include "WebImage.h"
52 #include "WebPageProxyMessages.h"
53 #include <WebCore/FrameView.h>
54
55 #if ENABLE(TIZEN_INPUT_TAG_EXTENSION)
56 #include <WebCore/HTMLInputElement.h>
57 #include <WebCore/HTMLNames.h>
58 #endif
59
60 #if ENABLE(TIZEN_MULTIPLE_SELECT)
61 #include "WebPopupMenu.h"
62 #include <WebCore/PopupMenuClient.h>
63 #endif
64
65 #if ENABLE(TIZEN_MOBILE_WEB_PRINT)
66 #include <WebCore/PlatformContextCairo.h>
67 #endif
68
69 #if ENABLE(TIZEN_CLIPBOARD) || ENABLE(TIZEN_PASTEBOARD)
70 #include <WebCore/ClipboardTizen.h>
71 #endif
72
73 #if ENABLE(TIZEN_PASTEBOARD)
74 #include <WebCore/Pasteboard.h>
75 #endif
76
77 #if ENABLE(TIZEN_WEBKIT2_REMOTE_WEB_INSPECTOR)
78 #include "WebInspectorServerEfl.h"
79 #endif
80
81 #if ENABLE(TIZEN_WEB_STORAGE)
82 #include <WebCore/GroupSettings.h>
83 #include <WebCore/PageGroup.h>
84 #endif
85
86 #if ENABLE(TIZEN_PLUGIN_SUSPEND_RESUME)
87 #include "PluginView.h"
88 #endif
89
90 #if ENABLE(TIZEN_PREFERENCE)
91 #include "WebPreferencesStore.h"
92 #include <WebCore/Settings.h>
93 #endif
94
95 #if ENABLE(TIZEN_WEBKIT2_FOCUS_RING)
96 #include <WebCore/HTMLFrameOwnerElement.h>
97 #include <WebCore/HTMLImageElement.h>
98 #endif
99
100 #if ENABLE(TIZEN_DEVICE_ORIENTATION)
101 #include "DeviceMotionClientTizen.h"
102 #include "DeviceOrientationClientTizen.h"
103 #endif
104
105 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION_ON_UI_SIDE)
106 #include "RenderLayer.h"
107 #include "WebGraphicsLayer.h"
108 #include <WebCore/RenderView.h>
109 #endif
110
111 #if ENABLE(TIZEN_ISF_PORT)
112 #include <WebCore/Text.h>
113 #include <WebCore/EditorClient.h>
114 #endif
115
116 #if ENABLE(TIZEN_INPUT_TAG_EXTENSION) || ENABLE(TIZEN_WEBKIT2_FORM_DATABASE)
117 #include "EditorClient.h"
118 #endif
119
120 #if ENABLE(TIZEN_DATALIST_ELEMENT)
121 #include "HTMLCollection.h"
122 #include "HTMLDataListElement.h"
123 #include "HTMLOptionElement.h"
124 #endif
125
126 #if ENABLE(TIZEN_STYLE_SCOPED)
127 #include <WebCore/RuntimeEnabledFeatures.h>
128 #endif
129
130 #if ENABLE(TIZEN_WEBKIT2_TEXT_SELECTION)
131 #include "htmlediting.h"
132 #endif
133
134 #if ENABLE(TIZEN_LINK_MAGNIFIER)
135 #include "LinkMagnifier.h"
136 #endif
137
138 #if ENABLE(TIZEN_SCREEN_READER)
139 #include "WebEventConversion.h"
140 #endif
141
142 #if ENABLE(TIZEN_CSP)
143 #include <WebCore/ContentSecurityPolicy.h>
144 #endif
145
146 #if ENABLE(TIZEN_OFFLINE_PAGE_SAVE)
147 #include "WebPageSerializerTizen.h"
148 #endif
149 #endif // #if OS(TIZEN)
150
151 using namespace WebCore;
152
153 namespace WebKit {
154
155 void WebPage::platformInitialize()
156 {
157 #if ENABLE(TIZEN_DEVICE_ORIENTATION)
158     WebCore::provideDeviceMotionTo(m_page.get(), new DeviceMotionClientTizen);
159     WebCore::provideDeviceOrientationTo(m_page.get(), new DeviceOrientationClientTizen);
160 #endif
161 #if ENABLE(TIZEN_ISF_PORT)
162     m_isSettingComposition = false;
163 #endif
164 }
165
166 #if ENABLE(TIZEN_PREFERENCE)
167 void WebPage::platformPreferencesDidChange(const WebPreferencesStore& store)
168 {
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()));
174 #endif
175 #if ENABLE(TIZEN_ISF_PORT)
176     settings->setEnableDefaultKeypad(store.getBoolValueForKey(WebPreferencesKey::defaultKeypadEnabledKey()));
177 #endif
178 #if ENABLE(TIZEN_STYLE_SCOPED)
179     WebCore::RuntimeEnabledFeatures::setStyleScopedEnabled(store.getBoolValueForKey(WebPreferencesKey::styleScopedEnabledKey()));
180 #endif
181 #if ENABLE(TIZEN_WEB_AUDIO)
182     settings->setWebAudioEnabled(true);
183 #endif
184 }
185 #else
186 void WebPage::platformPreferencesDidChange(const WebPreferencesStore&)
187 {
188     notImplemented();
189 }
190 #endif // #if ENABLE(TIZEN_PREFERENCE)
191
192 static inline void scroll(Page* page, ScrollDirection direction, ScrollGranularity granularity)
193 {
194     page->focusController()->focusedOrMainFrame()->eventHandler()->scrollRecursively(direction, granularity);
195 }
196
197 bool WebPage::performDefaultBehaviorForKeyEvent(const WebKeyboardEvent& keyboardEvent)
198 {
199     notImplemented();
200     return false;
201 }
202
203 bool WebPage::platformHasLocalDataForURL(const KURL&)
204 {
205     notImplemented();
206     return false;
207 }
208
209 String WebPage::cachedResponseMIMETypeForURL(const KURL&)
210 {
211     notImplemented();
212     return String();
213 }
214
215 bool WebPage::platformCanHandleRequest(const ResourceRequest&)
216 {
217     notImplemented();
218     return true;
219 }
220
221 String WebPage::cachedSuggestedFilenameForURL(const KURL&)
222 {
223     notImplemented();
224     return String();
225 }
226
227 PassRefPtr<SharedBuffer> WebPage::cachedResponseDataForURL(const KURL&)
228 {
229     notImplemented();
230     return 0;
231 }
232
233 const char* WebPage::interpretKeyEvent(const KeyboardEvent* event)
234 {
235     ASSERT(event->type() == eventNames().keydownEvent || event->type() == eventNames().keypressEvent);
236
237     if (event->type() == eventNames().keydownEvent)
238         return getKeyDownCommandName(event);
239
240     return getKeyPressCommandName(event);
241 }
242
243 void WebPage::setThemePath(const String& themePath)
244 {
245     WebCore::RenderThemeEfl* theme = static_cast<WebCore::RenderThemeEfl*>(m_page->theme());
246     theme->setThemePath(themePath);
247 }
248
249 static Frame* targetFrameForEditing(WebPage* page)
250 {
251     Frame* frame = page->corePage()->focusController()->focusedOrMainFrame();
252     if (!frame)
253         return 0;
254
255     Editor* editor = frame->editor();
256     if (!editor->canEdit())
257         return 0;
258
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())
267                 return 0;
268         }
269     }
270
271     return frame;
272 }
273
274 void WebPage::confirmComposition(const String& compositionString)
275 {
276     Frame* targetFrame = targetFrameForEditing(this);
277     if (!targetFrame)
278         return;
279
280     targetFrame->editor()->confirmComposition(compositionString);
281 }
282
283 void WebPage::setComposition(const String& compositionString, const Vector<WebCore::CompositionUnderline>& underlines, uint64_t cursorPosition)
284 {
285     Frame* targetFrame = targetFrameForEditing(this);
286     if (!targetFrame)
287         return;
288
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)
297                 return;
298
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;
308                     }
309                 }
310                 targetFrame->editor()->setComposition(newCompositionString, newUnderlines, cursorPosition, 0);
311                 return;
312             }
313         }
314     }
315     m_isSettingComposition = true;
316 #endif
317
318     targetFrame->editor()->setComposition(compositionString, underlines, cursorPosition, 0);
319
320 #if ENABLE(TIZEN_ISF_PORT)
321     m_isSettingComposition = false;
322 #endif
323 }
324
325 void WebPage::cancelComposition()
326 {
327     Frame* frame = m_page->focusController()->focusedOrMainFrame();
328     if (!frame)
329         return;
330
331     frame->editor()->cancelComposition();
332 }
333
334 #if OS(TIZEN)
335
336 #if ENABLE(TIZEN_WEBKIT2_TILED_BACKING_STORE)
337 IntSize WebPage::contentsSize() const
338 {
339     FrameView* frameView = m_page->mainFrame()->view();
340     if (!frameView)
341         return IntSize(0, 0);
342
343     return frameView->contentsSize();
344 }
345 #endif
346
347 void WebPage::scrollMainFrameBy(const IntSize& scrollOffset)
348 {
349     m_page->mainFrame()->view()->scrollBy(scrollOffset);
350 }
351
352 void WebPage::scrollMainFrameTo(const IntPoint& scrollPosition)
353 {
354     m_page->mainFrame()->view()->setScrollPosition(scrollPosition);
355 }
356
357 void WebPage::createSnapshot(const IntRect rect, float scaleFactor, ShareableBitmap::Handle& snapshotHandle)
358 {
359     FrameView* frameView = m_mainFrame->coreFrame()->view();
360     if (!frameView)
361         return;
362
363     RefPtr<WebImage> snapshotImage = scaledSnapshotInViewCoordinates(rect, scaleFactor, ImageOptionsShareable);
364     if (!snapshotImage || !snapshotImage->bitmap())
365         return;
366
367     snapshotImage->bitmap()->createHandle(snapshotHandle);
368 }
369
370 void WebPage::requestUpdateFormNavigation()
371 {
372     Frame* frame = m_page->focusController()->focusedOrMainFrame();
373     if (!frame)
374         return;
375
376     Document* document = frame->document();
377     if (!document)
378         return;
379
380     Node* focusedNode = document->focusedNode();
381
382     Vector<RefPtr<Node> > focusableNodes;
383     document->getFocusableNodes(focusableNodes);
384
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")
395                 )
396             ) {
397             if ((*it).get() == focusedNode)
398                 currentNodeIndex = formElementCount;
399             formElementCount++;
400         }
401     }
402
403     if (currentNodeIndex == -1)
404         return;
405
406     send(Messages::WebPageProxy::UpdateFormNavigation(formElementCount, currentNodeIndex));
407 }
408
409 void WebPage::moveFocus(int newIndex)
410 {
411     Frame* frame = m_page->focusController()->focusedOrMainFrame();
412     if (!frame)
413         return;
414
415     Document* document = frame->document();
416     if (!document)
417         return;
418
419     Vector<RefPtr<Node> > focusableNodes;
420     document->getFocusableNodes(focusableNodes);
421
422     int index = 0;
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);
432             }
433             index++;
434         } else if (equalIgnoringCase(nodeName, "INPUT")
435             && !equalIgnoringCase((*it).get()->toInputElement()->type(), "CHECKBOX")
436             && !equalIgnoringCase((*it).get()->toInputElement()->type(), "RADIO")
437             ) {
438             if (index == newIndex) {
439                 HTMLInputElement* elem = (*it).get()->toInputElement();
440                 elem->focus();
441             }
442             index++;
443         }
444     }
445 }
446
447 #if ENABLE(TIZEN_MOBILE_WEB_PRINT)
448 #define INCH_TO_MM 25.4
449 #define INCH_TO_POINTS 72.0
450
451 void WebPage::createPagesToPDF(const IntSize& surfaceSize, const IntSize& contentsSize, const String& fileName)
452 {
453     FrameView* frameView = m_mainFrame->coreFrame()->view();
454     if (!frameView)
455         return;
456
457     RefPtr<WebImage> pageshotImage = WebImage::create(contentsSize, ImageOptionsShareable);
458     if (!pageshotImage->bitmap())
459         return;
460
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();
466
467     OwnPtr<WebCore::GraphicsContext> graphicsContext = pageshotImage->bitmap()->createGraphicsContextForPdfSurface(fileName, pdfWidth, pdfHeight);
468     graphicsContext->scale(FloatSize(scaleFactorPdf, scaleFactorPdf));
469
470     frameView->updateLayoutAndStyleIfNeededRecursive();
471
472     int pageNumber = ((contentsSize.height() * scaleFactorPdf) / pdfHeight) + 1;
473     float paintY = 0.0;
474
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));
479
480         frameView->paint(graphicsContext.get(), paintRect);
481         cairo_show_page(graphicsContext->platformContext()->cr());
482         graphicsContext->translate(0, -ceil(pdfHeight / scaleFactorPdf));
483         paintY += (pdfHeight / scaleFactorPdf);
484     }
485     frameView->setPaintBehavior(oldBehavior);
486
487     pageshotImage.release();
488 }
489 #endif
490
491 #if ENABLE(TIZEN_TEXT_CARET_HANDLING_WK2)
492 bool WebPage::setCaretPosition(const IntPoint& pos)
493 {
494     Frame* frame = m_page->focusController()->focusedOrMainFrame();
495     if (!frame)
496         return false;
497
498     FrameSelection* controller = frame->selection();
499     if (!controller)
500         return false;
501
502     FrameView* frameView = frame->view();
503     if (!frameView)
504         return false;
505
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())
509         return false;
510
511     Node* innerNode = result.innerNode();
512
513     if (!innerNode || !innerNode->renderer())
514         return false;
515
516     VisiblePosition visiblePos;
517
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);
524
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
529
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();
534
535         if (!deepInnerNode || !deepInnerNode->renderer())
536             return false;
537
538         // so we get a base node rectange
539         IntRect deepNodeRect = deepInnerNode->renderer()->absoluteBoundingBoxRect(true);
540
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());
543
544         // if we are outside the rect we cheat, that we are just inside of it
545         if (point.y() < 0)
546             point.setY(0);
547         else if (point.y() >= deepNodeRect.height())
548             point.setY(deepNodeRect.height() - 1);
549
550         // visible position created - caret ready to set
551         visiblePos = deepInnerNode->renderer()->positionForPoint(point);
552         if (visiblePos.isNull())
553             return false;
554     } else {
555         // for plain text input fields we can get only a caret bounding box
556         if (!controller->isCaret() || !controller->caretRenderer())
557             return false;
558
559         const Node* node = controller->start().deprecatedNode();
560         if (!node || !node->renderer())
561             return false;
562
563         IntRect rect = controller->caretRenderer()->absoluteBoundingBoxRect(true);
564
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;
570
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);
580
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);
585
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);
589
590         if (!newResult.isContentEditable())
591             return false;
592
593         Node* newInnerNode = newResult.innerNode();
594
595         if (!newInnerNode || !newInnerNode->renderer())
596             return false;
597
598         // visible position created
599         visiblePos = newInnerNode->renderer()->positionForPoint(newResult.localPoint());
600         if (visiblePos.isNull())
601             return false;
602     }
603
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);
609
610     return true;
611 }
612
613 void WebPage::getCaretPosition(IntRect& rect)
614 {
615     Frame* frame = m_page->focusController()->focusedOrMainFrame();
616     if (!frame)
617         return;
618
619     FrameSelection* controller = frame->selection();
620     if (!controller)
621         return;
622
623     Node* node = controller->start().deprecatedNode();
624     if (!node || !node->renderer() || !node->isContentEditable())
625         return;
626
627     if (controller->isCaret()) {
628         FrameView* frameView = frame->view();
629         if (!frameView)
630             return;
631
632         rect = frameView->contentsToWindow(controller->absoluteCaretBounds());
633     }
634 }
635 #endif
636
637 #if ENABLE(TIZEN_ISF_PORT)
638 void WebPage::didCancelComposition(Node* valueChangedNode)
639 {
640     if (m_isSettingComposition)
641         return;
642
643     Frame* frame = m_page->focusController()->focusedOrMainFrame();
644     if (!frame || !valueChangedNode->containsIncludingShadowDOM(frame->editor()->compositionNode()))
645         return;
646
647     frame->editor()->cancelComposition();
648     send(Messages::WebPageProxy::DidCancelComposition());
649 }
650
651 void WebPage::getCursorOffset(int& offset)
652 {
653     offset = 0;
654     Frame* frame = m_page->focusController()->focusedOrMainFrame();
655     if (!frame || !frame->editor()->canEdit())
656         return;
657
658     Position base = frame->selection()->base();
659     Node* baseNode = base.containerNode();
660     if (baseNode)
661         offset = baseNode->isTextNode() ? base.offsetInContainerNode() : 0;
662 }
663
664 void WebPage::getSurroundingTextAndCursorOffset(String& text, int& offset)
665 {
666     text = String();
667     offset = 0;
668
669     Frame* frame = m_page->focusController()->focusedOrMainFrame();
670     if (!frame || !frame->editor()->canEdit())
671         return;
672
673     Position base = frame->selection()->base();
674     Node* baseNode = base.containerNode();
675     if (baseNode && baseNode->isTextNode()) {
676         text = baseNode->textContent();
677         offset = base.offsetInContainerNode();
678     }
679 }
680
681 void WebPage::getSelectionRect(bool isOnlyEditable, IntRect& rect)
682 {
683     rect = IntRect();
684
685     Frame* frame = m_page->focusController()->focusedFrame();
686     if (!frame || !frame->view())
687         return;
688
689     FrameSelection* selection = frame->selection();
690     Node* node = selection->start().deprecatedNode();
691     if (!node || !node->renderer() || (isOnlyEditable && !node->isContentEditable()))
692         return;
693
694     if (selection->isCaret())
695         rect = frame->view()->contentsToWindow(selection->absoluteCaretBounds());
696     else if (selection->isRange())
697         rect = frame->view()->contentsToWindow(enclosingIntRect(selection->bounds()));
698 }
699
700 void WebPage::deleteSurroundingText(int offset, int count)
701 {
702     Frame* frame = m_page->focusController()->focusedOrMainFrame();
703     if (!frame || !frame->editor()->canEdit())
704         return;
705
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())
713         return;
714
715     frame->selection()->setSelection(selection);
716     frame->editor()->deleteWithDirection(DirectionBackward, CharacterGranularity, false, true);
717 }
718 #endif
719
720 #if ENABLE(TIZEN_INPUT_TAG_EXTENSION) || ENABLE(TIZEN_WEBKIT2_FORM_DATABASE)
721 void WebPage::setFocusedInputElementValue(const String& inputValue)
722 {
723     Frame* frame = m_page->focusController()->focusedOrMainFrame();
724     if (!frame || !frame->document() || !frame->document()->focusedNode())
725         return;
726
727     HTMLInputElement* inputElement = frame->document()->focusedNode()->toInputElement();
728     if (!inputElement)
729         return;
730
731     inputElement->toNode()->dispatchFocusEvent(0);
732     inputElement->setValue(inputValue, DispatchChangeEvent);
733 }
734
735 void  WebPage::getFocusedInputElementValue(String& inputValue)
736 {
737     inputValue = String();
738
739     Frame* frame = m_page->focusController()->focusedOrMainFrame();
740     if (!frame || !frame->document() || !frame->document()->focusedNode())
741         return;
742
743     HTMLInputElement* inputElement = frame->document()->focusedNode()->toInputElement();
744     if (!inputElement)
745         return;
746
747     inputValue = inputElement->value();
748 }
749 #endif
750
751 #if ENABLE(TIZEN_DATALIST_ELEMENT)
752 void WebPage::getFocusedInputElementDataList(Vector<String>& optionList)
753 {
754     Frame* frame = m_page->focusController()->focusedOrMainFrame();
755     if (!frame || !frame->document())
756         return;
757
758     Node* node = frame->document()->focusedNode();
759     if (!node)
760         return;
761
762     HTMLInputElement* input = node->toInputElement();
763     if (!input)
764         return;
765
766     HTMLDataListElement* dataList = static_cast<HTMLDataListElement*>(input->list());
767     if (!dataList)
768         return;
769
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);
775     }
776 }
777 #endif
778
779 #if ENABLE(TIZEN_WEBKIT2_FOCUS_RING)
780 static IntRect getNodeRect(Node* node, Node* focusableNode, bool isImage)
781 {
782     IntRect rect;
783
784     if (isImage) {
785         bool isReplaced;
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());
793         }
794         else {
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;
800         }
801     } else {
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.
804         IntRect tempRect;
805         for (Node* childNode = focusableNode->firstChild(); childNode; childNode = childNode->traverseNextNode(focusableNode)) {
806             bool isReplaced;
807             if (focusableNode->renderRect(&isReplaced).contains(childNode->getRect()))
808                 tempRect.unite(pixelSnappedIntRect(childNode->getRect()));
809         }
810
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);
820         else
821             rect = tempRect;
822     }
823
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.
826     bool isReplaced;
827     for (Node* loopNode = focusableNode; loopNode && rect.isEmpty(); loopNode = loopNode->parentNode()) {
828         RenderObject* renderer = loopNode->renderer();
829         if (renderer && renderer->isRoot())
830             break;
831
832         rect = pixelSnappedIntRect(loopNode->renderRect(&isReplaced));
833     }
834
835     Frame* nodeFrame = focusableNode->document()->frame();
836     Node* owner;
837     while (nodeFrame && (owner = nodeFrame->ownerElement())) {
838         rect.moveBy(owner->getRect().pixelSnappedLocation());
839         nodeFrame = owner->document()->frame();
840     }
841
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))
845         rect = IntRect();
846
847     return rect;
848 }
849 #endif
850
851 #if ENABLE(TIZEN_WEBKIT2_HIT_TEST)
852 #if ENABLE(TIZEN_WEBKIT2_FOCUS_RING)
853 static IntRect getFocusedRect(HitTestResult hitTestResult, Page* page)
854 {
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())
861             break;
862
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;
869             break;
870         }
871
872         focusableNode = focusableNode->parentNode();
873     }
874
875     if (!isFocusRingDrawable) {
876         if (node->hasTagName(HTMLNames::imgTag))
877             return getNodeRect(node, node, !hitTestResult.absoluteImageURL().isEmpty());
878
879         return IntRect();
880     }
881
882     return getNodeRect(node, focusableNode, !hitTestResult.absoluteImageURL().isEmpty());
883 }
884 #endif
885
886 void WebPage::hitTestResultAtPoint(const IntPoint& point, int hitTestMode, WebHitTestResult::Data& hitTestResultData)
887 {
888     Frame* frame = m_page->mainFrame();
889     FrameView* frameView = frame->view();
890     if (!frameView)
891         return;
892
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();
901 #endif
902
903     int context = WebHitTestResult::HitTestResultContextDocument;
904
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;
917
918     hitTestResultData.context = context;
919     hitTestResultData.hitTestMode = hitTestMode;
920
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());
927     }
928 #endif
929
930     if (hitTestResultData.hitTestMode & WebHitTestResult::HitTestModeNodeData) {
931         WebCore::Node* hitNode = hitTestResult.innerNonSharedNode();
932         if (hitNode) {
933             hitTestResultData.nodeData.nodeValue = hitNode->nodeValue();
934
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.
937
938             if (hitNode->isElementNode()) {
939                 WebCore::Element* hitElement = static_cast<WebCore::Element*>(hitNode);
940                 if (hitElement) {
941                     hitTestResultData.nodeData.tagName = hitElement->tagName();
942                 }
943             }
944
945             WebCore::NamedNodeMap* namedNodeMap = hitNode->attributes();
946             if (namedNodeMap) {
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);
952                 }
953             }
954         }
955     }
956
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();
962         }
963     }
964 }
965 #endif
966
967 #if ENABLE(TIZEN_WEB_STORAGE)
968 void WebPage::getStorageQuotaBytes(uint64_t callbackID)
969 {
970     uint32_t quota = m_page->group().groupSettings()->localStorageQuotaBytes();
971     send(Messages::WebPageProxy::DidGetWebStorageQuotaBytes(quota, callbackID));
972 }
973
974 void WebPage::setStorageQuotaBytes(uint32_t quota)
975 {
976     m_page->group().groupSettings()->setLocalStorageQuotaBytes(quota);
977 }
978 #endif
979
980 #if ENABLE(TIZEN_RECORDING_SURFACE_SET)
981 void WebPage::recordingSurfaceSetEnableSet(bool enable)
982 {
983     m_recordingSurfaceSetSettings = enable;
984 }
985 #endif
986
987 #if ENABLE(TIZEN_CLIPBOARD) || ENABLE(TIZEN_PASTEBOARD)
988 void WebPage::setClipboardDataForPaste(const String& data, const String& type)
989 {
990 #if ENABLE(TIZEN_PASTEBOARD)
991     // FIXME: Should move to EditorClient like Clipboard
992     Pasteboard::generalPasteboard()->setDataWithType(data, type);
993 #else
994     Frame* mainFrame = m_page->mainFrame();
995     if (!mainFrame)
996         return;
997
998     mainFrame->editor()->client()->setClipboardDataForPaste(data, type);
999 #endif
1000 }
1001 #endif
1002
1003 void WebPage::suspendJavaScriptAndResources()
1004 {
1005     Frame* mainFrame = m_page->mainFrame();
1006     if (!mainFrame)
1007         return;
1008
1009     for (Frame* frame = mainFrame; frame; frame = frame->tree()->traverseNext())
1010         frame->document()->suspendScheduledTasks(WebCore::ActiveDOMObject::PageWillBeSuspended);
1011     mainFrame->loader()->suspendAllLoaders();
1012 }
1013
1014 void WebPage::resumeJavaScriptAndResources()
1015 {
1016     Frame* mainFrame = m_page->mainFrame();
1017     if (!mainFrame)
1018         return;
1019
1020     for (Frame* frame = mainFrame; frame; frame = frame->tree()->traverseNext())
1021         frame->document()->resumeScheduledTasks();
1022     mainFrame->loader()->resumeAllLoaders();
1023 }
1024
1025 #if ENABLE(TIZEN_SYNC_REQUEST_ANIMATION_FRAME)
1026 void WebPage::suspendAnimationController()
1027 {
1028     if (!m_suspendedAnimationController) {
1029         Frame* mainFrame = m_page->mainFrame();
1030         if (!mainFrame)
1031             return;
1032
1033         for (Frame* frame = mainFrame; frame; frame = frame->tree()->traverseNext())
1034             frame->document()->suspendScriptedAnimationControllerCallbacks();
1035
1036         m_suspendedAnimationController = true;
1037     }
1038 }
1039
1040 void WebPage::resumeAnimationController()
1041 {
1042     if (m_suspendedAnimationController) {
1043         Frame* mainFrame = m_page->mainFrame();
1044         if (!mainFrame)
1045             return;
1046
1047         for (Frame* frame = mainFrame; frame; frame = frame->tree()->traverseNext())
1048             frame->document()->resumeScriptedAnimationControllerCallbacks();
1049
1050         m_suspendedAnimationController = false;
1051     }
1052 }
1053 #endif
1054
1055 #if ENABLE(TIZEN_WEBKIT2_REMOTE_WEB_INSPECTOR)
1056 void WebPage::startInspectorServer(uint32_t port,  uint32_t& allocatedPort)
1057 {
1058     bool ret = WebInspectorServerEfl::server()->startServer(port);
1059     if (ret)
1060         allocatedPort = WebInspectorServerEfl::server()->getServerPort();
1061     else
1062         allocatedPort = 0;
1063 }
1064
1065 void WebPage::stopInspectorServer(bool& result)
1066 {
1067     result = WebInspectorServerEfl::server()->stopServer();
1068 }
1069 #endif
1070
1071 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION_ON_UI_SIDE)
1072 void WebPage::scrollOverflowWithTrajectoryVector(const WebCore::FloatPoint& trajectoryVector)
1073 {
1074     Frame* frame = m_page->focusController()->focusedOrMainFrame();
1075     if (!frame)
1076         return;
1077     frame->eventHandler()->scrollOverflow(trajectoryVector);
1078 }
1079 #endif
1080
1081 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION)
1082 void WebPage::scrollOverflow(const WebCore::FloatPoint& delta, bool& scrolled)
1083 {
1084     scrolled = m_page->focusController()->focusedOrMainFrame()->eventHandler()->scrollOverflow(delta);
1085 }
1086
1087 void WebPage::setPressedNodeAtPoint(const IntPoint& point, bool checkOverflowLayer, bool& pressed, uint32_t& id)
1088 {
1089     RenderObject* renderer = 0;
1090     id = 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();
1095 #endif
1096 }
1097 #endif
1098
1099 void WebPage::executeEditCommandWithArgument(const String& commandName, const String& argument)
1100 {
1101     executeEditingCommand(commandName, argument);
1102 }
1103
1104 #if ENABLE(TIZEN_PLUGIN_SUSPEND_RESUME)
1105 void WebPage::suspendPlugin()
1106 {
1107     for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
1108         FrameView* view = frame->view();
1109         if (!view)
1110             continue;
1111
1112         const HashSet<RefPtr<Widget> >* children = view->children();
1113         ASSERT(children);
1114
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);
1120                 if (pluginView)
1121                     pluginView->suspendPlugin();
1122             }
1123         }
1124     }
1125 }
1126
1127 void WebPage::resumePlugin()
1128 {
1129     for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
1130         FrameView* view = frame->view();
1131         if (!view)
1132             continue;
1133
1134         const HashSet<RefPtr<Widget> >* children = view->children();
1135         ASSERT(children);
1136
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);
1142                 if (pluginView)
1143                     pluginView->resumePlugin();
1144             }
1145         }
1146     }
1147 }
1148 #endif
1149
1150 #if ENABLE(TIZEN_WEBKIT2_GET_TEXT_STYLE_FOR_SELECTION)
1151 void WebPage::getTextStyleStateForSelection()
1152 {
1153     Frame* frame = m_page->focusController()->focusedOrMainFrame();
1154
1155     int underlineState = frame->editor()->selectionHasStyle(CSSPropertyWebkitTextDecorationsInEffect, "underline");
1156     int italicState = frame->editor()->selectionHasStyle(CSSPropertyFontStyle, "italic");
1157     int boldState = frame->editor()->selectionHasStyle(CSSPropertyFontWeight, "bold");
1158
1159     send(Messages::WebPageProxy::DidGetTextStyleStateForSelection(underlineState, italicState, boldState));
1160 }
1161 #endif
1162
1163 #if ENABLE(TIZEN_MULTIPLE_SELECT)
1164 void WebPage::didChangeSelectedIndexForActivePopupMenuMultiple(Vector<int32_t> newIndex)
1165 {
1166     if (!m_activePopupMenu)
1167         return;
1168
1169     m_activePopupMenu->client()->popupDidHide();
1170
1171     size_t indexSize = newIndex.size();
1172     for (size_t i = 0; i < indexSize; i++)
1173         m_activePopupMenu->didChangeSelectedIndex(newIndex.at(i));
1174
1175 }
1176 #endif
1177
1178 #if ENABLE(TIZEN_OFFLINE_PAGE_SAVE)
1179 void WebPage::startOfflinePageSave(String subresourceFolderName)
1180 {
1181     WebPageSerializerTizen::getSerializedPageContent(this, subresourceFolderName);
1182 }
1183 #endif
1184
1185 #if ENABLE(TIZEN_WEBKIT2_TEXT_SELECTION)
1186 void WebPage::selectClosestWord(const IntPoint& point, bool isStartedTextSelectionFromOutside, bool& result)
1187 {
1188     result = false;
1189
1190     Frame* mainFrame = m_page->mainFrame();
1191     Frame* focusedFrame = m_page->focusController()->focusedOrMainFrame();
1192
1193     HitTestResult hitTestResult = mainFrame->eventHandler()->hitTestResultAtPoint(m_page->mainFrame()->view()->windowToContents(point), false);
1194
1195     Node* node = hitTestResult.innerNonSharedNode();
1196     if (!node)
1197         return;
1198
1199      Frame* newFocusFrame = node->document()->frame();
1200      if (focusedFrame != newFocusFrame) {
1201          m_page->focusController()->setFocusedFrame(newFocusFrame);
1202          focusedFrame = newFocusFrame;
1203      }
1204
1205 #if ENABLE(TIZEN_INPUT_TAG_EXTENSION)
1206     HTMLInputElement* inputElement = node->toInputElement();
1207 #endif
1208
1209     if (hitTestResult.isContentEditable()) {
1210 #if ENABLE(TIZEN_ISF_PORT)
1211         if (focusedFrame)
1212             didCancelComposition(node);
1213 #endif
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);
1219             return;
1220         }
1221 #else
1222         result = setCaretPosition(point);
1223         return;
1224 #endif
1225     }
1226
1227 #if ENABLE(TIZEN_INPUT_TAG_EXTENSION)
1228     if (!node->isTextNode() && !inputElement)
1229 #else
1230     if (!node->isTextNode())
1231 #endif
1232         return;
1233
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))
1239                     return;
1240                 break;
1241             }
1242         }
1243     }
1244
1245     FrameSelection* frameSelection = focusedFrame->selection();
1246
1247     VisiblePosition position = mainFrame->visiblePositionForPoint(point);
1248     VisibleSelection selection(position);
1249
1250     // This changes just the 'start' and 'end' positions of the VisibleSelection
1251     selection.expandUsingGranularity(WordGranularity);
1252
1253     FrameSelection::SetSelectionOptions options = FrameSelection::CloseTyping | FrameSelection::ClearTypingStyle | FrameSelection::DoNotSetFocus;
1254     frameSelection->setSelection(VisibleSelection(selection.start(), selection.end()), options);
1255
1256     if (!frameSelection->isRange())
1257         return;
1258
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());
1271         return;
1272     }
1273
1274     result = true;
1275 }
1276
1277 void WebPage::setLeftSelection(const IntPoint& point, bool& result)
1278 {
1279     result = false;
1280
1281     Frame* focusedFrame = m_page->focusController()->focusedOrMainFrame();
1282     FrameSelection* frameSelection = focusedFrame->selection();
1283     if (!frameSelection->isRange())
1284         return;
1285
1286     Node* selectionEndNode = frameSelection->end().deprecatedNode();
1287     if (!selectionEndNode || !selectionEndNode->renderer())
1288         return;
1289
1290     FrameView* frameView = focusedFrame->view();
1291     if (!frameView)
1292         return;
1293
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));
1299
1300     if (selectionEndNode->rendererIsEditable() && !selectionEndNode->rendererIsRichlyEditable()) {
1301         const int boundariesWidth = 2;
1302
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);
1309     }
1310
1311     OwnPtr<VisiblePosition> position = adoptPtr(new VisiblePosition(focusedFrame->visiblePositionForPoint(pos)));
1312     Position extent = frameSelection->extent();
1313
1314     Node* newSelectionStartNode = position->deepEquivalent().deprecatedNode();
1315
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);
1327
1328         bool oldProhibitsScrolling = focusedFrame->view()->prohibitsScrolling();
1329         focusedFrame->view()->setProhibitsScrolling(true);
1330
1331         frameSelection->setBase(*position);
1332
1333         focusedFrame->view()->setProhibitsScrolling(oldProhibitsScrolling);
1334         // This forces webkit to show selection
1335         // m_coreFrame->invalidateSelection();
1336
1337         result = true;
1338     }
1339 }
1340
1341
1342 void WebPage::setRightSelection(const IntPoint& point, bool& result)
1343 {
1344     result = false;
1345
1346     Frame* focusedFrame = m_page->focusController()->focusedOrMainFrame();
1347     FrameSelection* frameSelection = focusedFrame->selection();
1348
1349     if (!frameSelection->isRange())
1350         return;
1351
1352     Node* selectionStartNode = frameSelection->start().deprecatedNode();
1353     if (!selectionStartNode || !selectionStartNode->renderer())
1354         return;
1355
1356     FrameView* frameView = focusedFrame->view();
1357     if (!frameView)
1358         return;
1359
1360     IntPoint pos = frameView->windowToContents(point);
1361     if (selectionStartNode->rendererIsEditable() && !selectionStartNode->rendererIsRichlyEditable()) {
1362         const int boundariesWidth = 2;
1363
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);
1370     }
1371
1372     OwnPtr<VisiblePosition> position = adoptPtr(new VisiblePosition(focusedFrame->visiblePositionForPoint(pos)));
1373     Position base = frameSelection->base();
1374
1375     Node* newSelectionEndNode = position->deepEquivalent().deprecatedNode();
1376
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
1386
1387         VisibleSelection sel(frameSelection->start(), frameSelection->end());
1388         frameSelection->setSelection(sel);
1389
1390         bool oldProhibitsScrolling = focusedFrame->view()->prohibitsScrolling();
1391         focusedFrame->view()->setProhibitsScrolling(true);
1392
1393         frameSelection->setExtent(*position);
1394
1395         focusedFrame->view()->setProhibitsScrolling(oldProhibitsScrolling);
1396
1397         result = true;
1398     }
1399 }
1400
1401 void WebPage::getSelectionHandlers(IntRect& leftRect, IntRect& rightRect)
1402 {
1403     Frame* focusedFrame = m_page->focusController()->focusedOrMainFrame();
1404     if (!focusedFrame->selection()->isRange())
1405         return;
1406
1407     // Is this check necessary? Leaving it for safety.
1408     RenderView* root = focusedFrame->contentRenderer();
1409     if (!root)
1410         return;
1411
1412     RefPtr<Range> selectedRange = focusedFrame->selection()->toNormalizedRange();
1413
1414     Vector<IntRect> rects, tempRects;
1415     selectedRange->boundingBoxEx(tempRects, true);
1416
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]);
1421         else {
1422             tempRects[i].intersect(boundsRect);
1423             if (!tempRects[i].isEmpty())
1424                 rects.append(tempRects[i]);
1425         }
1426     }
1427
1428     unsigned size = rects.size();
1429     if (size > 0) {
1430         leftRect = rects[0];
1431         rightRect = rects[size-1];
1432
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.
1435         if (size == 1) {
1436             Element* selectionRoot = focusedFrame->selection()->rootEditableElement();
1437             if (selectionRoot) {
1438                 IntRect editorRect = focusedFrame->view()->contentsToWindow(selectionRoot->getPixelSnappedRect());
1439
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));
1445                 }
1446 #endif
1447
1448                 if (leftRect.maxY() > editorRect.maxY()) {
1449                     leftRect.setY(editorRect.y());
1450                     leftRect.setHeight(editorRect.height());
1451                 }
1452
1453                 if (rightRect.maxY() > editorRect.maxY()) {
1454                     rightRect.setY(editorRect.y());
1455                     rightRect.setHeight(editorRect.height());
1456                 }
1457             }
1458         }
1459
1460         // prevent from selecting zero-length selection
1461         if (leftRect.x() == rightRect.x() + rightRect.width()
1462             && leftRect.y() == rightRect.y())
1463             return;
1464
1465         FrameView* frameView = focusedFrame->view();
1466         if (!frameView)
1467             return;
1468
1469         leftRect = frameView->contentsToWindow(leftRect);
1470         rightRect = frameView->contentsToWindow(rightRect);
1471      }
1472 }
1473
1474 void WebPage::getSelectionText(String& result)
1475 {
1476     Frame* focusedFrame = m_page->focusController()->focusedOrMainFrame();
1477     result = focusedFrame->editor()->selectedText();
1478 }
1479
1480 void WebPage::selectionRangeClear(bool& result)
1481 {
1482     result = false;
1483
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())
1489             return;
1490         VisibleSelection newSelection = VisibleSelection(visiblePos);
1491         frameSelection->setSelection(newSelection, CharacterGranularity);
1492         frameSelection->setCaretBlinkingSuspended(false);
1493     } else
1494         selectionClearAllSelection(m_page->mainFrame());
1495
1496     result = true;
1497 }
1498
1499 void WebPage::selectionClearAllSelection(Frame* frame)
1500 {
1501     if (!frame)
1502         return;
1503
1504     FrameSelection* frameSelection = frame->selection();
1505     if (frameSelection)
1506         frameSelection->clear();
1507
1508     if (!frame->tree())
1509         return;
1510
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());
1516 }
1517
1518 void WebPage::scrollContentByCharacter(const IntPoint&, int direction, bool& result)
1519 {
1520     result = false;
1521
1522     Frame* focusedFrame = m_page->focusController()->focusedOrMainFrame();
1523     if (direction)
1524         result = focusedFrame->selection()->modify(FrameSelection::AlterationMove, DirectionBackward, CharacterGranularity, UserTriggered);
1525     else
1526         result = focusedFrame->selection()->modify(FrameSelection::AlterationMove, DirectionForward, CharacterGranularity, UserTriggered);
1527 }
1528 #endif
1529
1530 #if ENABLE(TIZEN_LINK_MAGNIFIER)
1531 void WebPage::getLinkMagnifierRect(const IntPoint& position, const IntSize& size)
1532 {
1533     send(Messages::WebPageProxy::DidGetLinkMagnifierRect(position, LinkMagnifier::rect(this, position, size)));
1534 }
1535 #endif
1536
1537 #if ENABLE(TIZEN_SCREEN_READER)
1538 void WebPage::raiseTapEvent(const IntPoint& position, const IntPoint& globalPosition)
1539 {
1540     Frame* frame = m_page->mainFrame();
1541     if (!frame->view())
1542         return;
1543
1544     Vector<WebPlatformTouchPoint> touchPoints;
1545     touchPoints.append(WebPlatformTouchPoint(0, WebPlatformTouchPoint::TouchPressed, globalPosition, position));
1546
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));
1551     }
1552
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));
1556 }
1557
1558 static void sendScreenReaderFocusRect(WebPage* page, Node* node)
1559 {
1560     bool isImage = false;
1561     if (node->isElementNode()) {
1562         Element* element = static_cast<Element*>(node);
1563         isImage = !element->getAttribute(element->imageSourceAttributeName()).isEmpty();
1564     }
1565
1566     page->send(Messages::WebPageProxy::DidScreenReaderFocusRectChanged(getNodeRect(node, node, isImage)));
1567 }
1568
1569 void WebPage::moveScreenReaderFocus(bool forward, bool& result)
1570 {
1571     if (!m_screenReader)
1572         m_screenReader = ScreenReader::create(this);
1573
1574     if (!m_screenReader->moveFocus(forward)) {
1575         result = false;
1576         send(Messages::WebPageProxy::DidScreenReaderFocusRectChanged(IntRect()));
1577         return;
1578     } else {
1579         result = true;
1580         sendScreenReaderFocusRect(this, m_screenReader->getFocusedNode());
1581     }
1582 }
1583
1584 void WebPage::moveScreenReaderFocusByPoint(const IntPoint& point)
1585 {
1586     if (!m_screenReader)
1587         m_screenReader = ScreenReader::create(this);
1588
1589     if (!m_screenReader->moveFocus(point))
1590         return;
1591
1592     sendScreenReaderFocusRect(this, m_screenReader->getFocusedNode());
1593 }
1594
1595 void WebPage::recalcScreenReaderFocusRect()
1596 {
1597     if (!m_screenReader || !m_screenReader->getFocusedNode())
1598         return;
1599
1600     sendScreenReaderFocusRect(this, m_screenReader->getFocusedNode());
1601 }
1602
1603 void WebPage::updateScreenReaderFocus(RenderObject* object)
1604 {
1605     if (!m_screenReader)
1606         return;
1607
1608     if (!object)
1609         m_screenReader->clearFocus();
1610     else if (!m_screenReader->rendererWillBeDestroyed(object))
1611         return;
1612
1613     send(Messages::WebPageProxy::DidScreenReaderFocusRectChanged(IntRect()));
1614 }
1615
1616 void WebPage::clearScreenReader()
1617 {
1618     m_screenReader.clear();
1619 }
1620 #endif
1621
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)
1626 {
1627     if (m_activePopupMenu) {
1628         TIZEN_LOGI("");
1629         m_activePopupMenu->hide();
1630     }
1631 }
1632 #endif
1633
1634 #if ENABLE(TIZEN_CSP)
1635 void WebPage::setContentSecurityPolicy(const String& policy, uint32_t headerType)
1636 {
1637     Frame* frame = m_page->focusController()->focusedOrMainFrame();
1638     if (!frame)
1639         return;
1640
1641     Document* document = frame->document();
1642     if (!document)
1643         return;
1644
1645     document->contentSecurityPolicy()->didReceiveHeader(policy, static_cast<WebCore::ContentSecurityPolicy::HeaderType>(headerType));
1646 }
1647 #endif
1648
1649 #if ENABLE(TIZEN_INDEXED_DATABASE)
1650 void WebPage::setIndexedDatabaseDirectory(const String& path)
1651 {
1652     m_page->group().groupSettings()->setIndexedDBDatabasePath(path);
1653 }
1654 #endif
1655
1656 #if ENABLE(TIZEN_WEB_STORAGE)
1657 void WebPage::setLocalStorageDirectory(const String& path)
1658 {
1659     m_page->settings()->setLocalStorageDatabasePath(path);
1660 }
1661 #endif
1662 #endif // #if OS(TIZEN)
1663
1664 } // namespace WebKit