f9ba8e82e02016c9f44c8ee540ce9fb032a519b1
[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 }
162
163 #if ENABLE(TIZEN_PREFERENCE)
164 void WebPage::platformPreferencesDidChange(const WebPreferencesStore& store)
165 {
166     Settings* settings = m_page->settings();
167     settings->setInteractiveFormValidationEnabled(store.getBoolValueForKey(WebPreferencesKey::interactiveFormValidationEnabledKey()));
168     settings->setUsesEncodingDetector(store.getBoolValueForKey(WebPreferencesKey::usesEncodingDetectorKey()));
169 #if ENABLE(TIZEN_LOAD_REMOTE_IMAGES)
170     settings->setLoadRemoteImages(store.getBoolValueForKey(WebPreferencesKey::loadRemoteImagesKey()));
171 #endif
172 #if ENABLE(TIZEN_ISF_PORT)
173     settings->setEnableDefaultKeypad(store.getBoolValueForKey(WebPreferencesKey::defaultKeypadEnabledKey()));
174 #endif
175 #if ENABLE(TIZEN_STYLE_SCOPED)
176     WebCore::RuntimeEnabledFeatures::setStyleScopedEnabled(store.getBoolValueForKey(WebPreferencesKey::styleScopedEnabledKey()));
177 #endif
178 #if ENABLE(TIZEN_WEB_AUDIO)
179     settings->setWebAudioEnabled(true);
180 #endif
181 }
182 #else
183 void WebPage::platformPreferencesDidChange(const WebPreferencesStore&)
184 {
185     notImplemented();
186 }
187 #endif // #if ENABLE(TIZEN_PREFERENCE)
188
189 static inline void scroll(Page* page, ScrollDirection direction, ScrollGranularity granularity)
190 {
191     page->focusController()->focusedOrMainFrame()->eventHandler()->scrollRecursively(direction, granularity);
192 }
193
194 bool WebPage::performDefaultBehaviorForKeyEvent(const WebKeyboardEvent& keyboardEvent)
195 {
196     notImplemented();
197     return false;
198 }
199
200 bool WebPage::platformHasLocalDataForURL(const KURL&)
201 {
202     notImplemented();
203     return false;
204 }
205
206 String WebPage::cachedResponseMIMETypeForURL(const KURL&)
207 {
208     notImplemented();
209     return String();
210 }
211
212 bool WebPage::platformCanHandleRequest(const ResourceRequest&)
213 {
214     notImplemented();
215     return true;
216 }
217
218 String WebPage::cachedSuggestedFilenameForURL(const KURL&)
219 {
220     notImplemented();
221     return String();
222 }
223
224 PassRefPtr<SharedBuffer> WebPage::cachedResponseDataForURL(const KURL&)
225 {
226     notImplemented();
227     return 0;
228 }
229
230 const char* WebPage::interpretKeyEvent(const KeyboardEvent* event)
231 {
232     ASSERT(event->type() == eventNames().keydownEvent || event->type() == eventNames().keypressEvent);
233
234     if (event->type() == eventNames().keydownEvent)
235         return getKeyDownCommandName(event);
236
237     return getKeyPressCommandName(event);
238 }
239
240 void WebPage::setThemePath(const String& themePath)
241 {
242     WebCore::RenderThemeEfl* theme = static_cast<WebCore::RenderThemeEfl*>(m_page->theme());
243     theme->setThemePath(themePath);
244 }
245
246 static Frame* targetFrameForEditing(WebPage* page)
247 {
248     Frame* frame = page->corePage()->focusController()->focusedOrMainFrame();
249     if (!frame)
250         return 0;
251
252     Editor* editor = frame->editor();
253     if (!editor->canEdit())
254         return 0;
255
256     if (editor->hasComposition()) {
257         // We should verify the parent node of this IME composition node are
258         // editable because JavaScript may delete a parent node of the composition
259         // node. In this case, WebKit crashes while deleting texts from the parent
260         // node, which doesn't exist any longer.
261         if (PassRefPtr<Range> range = editor->compositionRange()) {
262             Node* node = range->startContainer();
263             if (!node || !node->isContentEditable())
264                 return 0;
265         }
266     }
267
268     return frame;
269 }
270
271 void WebPage::confirmComposition(const String& compositionString)
272 {
273     Frame* targetFrame = targetFrameForEditing(this);
274     if (!targetFrame)
275         return;
276
277     targetFrame->editor()->confirmComposition(compositionString);
278 }
279
280 void WebPage::setComposition(const String& compositionString, const Vector<WebCore::CompositionUnderline>& underlines, uint64_t cursorPosition)
281 {
282     Frame* targetFrame = targetFrameForEditing(this);
283     if (!targetFrame)
284         return;
285
286 #if ENABLE(TIZEN_ISF_PORT)
287     if (targetFrame->selection()->rootEditableElement()) {
288         HTMLTextFormControlElement* textFormControl = toTextFormControl(targetFrame->selection()->rootEditableElement()->shadowAncestorNode());
289         if (textFormControl && textFormControl->maxLength() >= 0) {
290             unsigned availableLength = textFormControl->maxLength() - textFormControl->value().length();
291             if (targetFrame->editor()->hasComposition())
292                 availableLength += (targetFrame->editor()->compositionEnd() - targetFrame->editor()->compositionStart());
293             if (!availableLength)
294                 return;
295
296             if (availableLength < compositionString.length()) {
297                 String newCompositionString = compositionString.substring(0, availableLength);
298                 Vector<CompositionUnderline> newUnderlines;
299                 size_t numUnderlines = underlines.size();
300                 for (size_t index = 0; index < numUnderlines; ++index) {
301                     if (underlines[index].startOffset < availableLength) {
302                         newUnderlines.append(underlines[index]);
303                         if (newUnderlines.last().endOffset > availableLength)
304                             newUnderlines.last().endOffset = availableLength;
305                     }
306                 }
307                 targetFrame->editor()->setComposition(newCompositionString, newUnderlines, cursorPosition, 0);
308                 return;
309             }
310         }
311     }
312 #endif
313
314     targetFrame->editor()->setComposition(compositionString, underlines, cursorPosition, 0);
315 }
316
317 void WebPage::cancelComposition()
318 {
319     Frame* frame = m_page->focusController()->focusedOrMainFrame();
320     if (!frame)
321         return;
322
323     frame->editor()->cancelComposition();
324 }
325
326 #if OS(TIZEN)
327
328 #if ENABLE(TIZEN_WEBKIT2_TILED_BACKING_STORE)
329 IntSize WebPage::contentsSize() const
330 {
331     FrameView* frameView = m_page->mainFrame()->view();
332     if (!frameView)
333         return IntSize(0, 0);
334
335     return frameView->contentsSize();
336 }
337 #endif
338
339 void WebPage::scrollMainFrameBy(const IntSize& scrollOffset)
340 {
341     m_page->mainFrame()->view()->scrollBy(scrollOffset);
342 }
343
344 void WebPage::scrollMainFrameTo(const IntPoint& scrollPosition)
345 {
346     m_page->mainFrame()->view()->setScrollPosition(scrollPosition);
347 }
348
349 void WebPage::createSnapshot(const IntRect rect, float scaleFactor, ShareableBitmap::Handle& snapshotHandle)
350 {
351     FrameView* frameView = m_mainFrame->coreFrame()->view();
352     if (!frameView)
353         return;
354
355     RefPtr<WebImage> snapshotImage = scaledSnapshotInViewCoordinates(rect, scaleFactor, ImageOptionsShareable);
356     if (!snapshotImage || !snapshotImage->bitmap())
357         return;
358
359     snapshotImage->bitmap()->createHandle(snapshotHandle);
360 }
361
362 void WebPage::requestUpdateFormNavigation()
363 {
364     Frame* frame = m_page->focusController()->focusedOrMainFrame();
365     if (!frame)
366         return;
367
368     Document* document = frame->document();
369     if (!document)
370         return;
371
372     Node* focusedNode = document->focusedNode();
373
374     Vector<RefPtr<Node> > focusableNodes;
375     document->getFocusableNodes(focusableNodes);
376
377     int formElementCount = 0;
378     int currentNodeIndex = -1;
379     const Vector<RefPtr<Node> >::iterator end = focusableNodes.end();
380     for (Vector<RefPtr<Node> >::iterator it = focusableNodes.begin(); it != end; ++it) {
381         AtomicString nodeName = (*it).get()->nodeName();
382         if (equalIgnoringCase(nodeName, "SELECT")
383             || (equalIgnoringCase(nodeName, "INPUT")
384                 && !equalIgnoringCase((*it).get()->toInputElement()->type(), "CHECKBOX")
385                 && !equalIgnoringCase((*it).get()->toInputElement()->type(), "RADIO")
386                 && !equalIgnoringCase((*it).get()->toInputElement()->type(), "SUBMIT")
387                 )
388             ) {
389             if ((*it).get() == focusedNode)
390                 currentNodeIndex = formElementCount;
391             formElementCount++;
392         }
393     }
394
395     if (currentNodeIndex == -1)
396         return;
397
398     send(Messages::WebPageProxy::UpdateFormNavigation(formElementCount, currentNodeIndex));
399 }
400
401 void WebPage::moveFocus(int newIndex)
402 {
403     Frame* frame = m_page->focusController()->focusedOrMainFrame();
404     if (!frame)
405         return;
406
407     Document* document = frame->document();
408     if (!document)
409         return;
410
411     Vector<RefPtr<Node> > focusableNodes;
412     document->getFocusableNodes(focusableNodes);
413
414     int index = 0;
415     const Vector<RefPtr<Node> >::iterator end = focusableNodes.end();
416     for (Vector<RefPtr<Node> >::iterator it = focusableNodes.begin(); it != end; ++it) {
417         AtomicString nodeName = (*it).get()->nodeName();
418         if (equalIgnoringCase(nodeName, "SELECT")) {
419             if (index == newIndex) {
420                 (*it).get()->setFocus();
421                 LayoutPoint position = LayoutPoint(0, 0);
422                 PlatformMouseEvent event(flooredIntPoint(position), flooredIntPoint(position), LeftButton, PlatformEvent::MouseMoved, 1, false, false, false, false, 0);
423                 (*it).get()->dispatchMouseEvent(event, "mousedown", 0, 0);
424             }
425             index++;
426         } else if (equalIgnoringCase(nodeName, "INPUT")
427             && !equalIgnoringCase((*it).get()->toInputElement()->type(), "CHECKBOX")
428             && !equalIgnoringCase((*it).get()->toInputElement()->type(), "RADIO")
429             ) {
430             if (index == newIndex) {
431                 HTMLInputElement* elem = (*it).get()->toInputElement();
432                 elem->focus();
433             }
434             index++;
435         }
436     }
437 }
438
439 #if ENABLE(TIZEN_MOBILE_WEB_PRINT)
440 #define INCH_TO_MM 25.4
441 #define INCH_TO_POINTS 72.0
442
443 void WebPage::createPagesToPDF(const IntSize& surfaceSize, const IntSize& contentsSize, const String& fileName)
444 {
445     FrameView* frameView = m_mainFrame->coreFrame()->view();
446     if (!frameView)
447         return;
448
449     RefPtr<WebImage> pageshotImage = WebImage::create(contentsSize, ImageOptionsShareable);
450     if (!pageshotImage->bitmap())
451         return;
452
453     double pdfWidth = (double)surfaceSize.width() / INCH_TO_MM * INCH_TO_POINTS;
454     double pdfHeight = (double)surfaceSize.height() / INCH_TO_MM * INCH_TO_POINTS;
455     double scaleFactorPdf = 1.0;
456     if (contentsSize.width() > pdfWidth)
457         scaleFactorPdf = pdfWidth / (double)contentsSize.width();
458
459     OwnPtr<WebCore::GraphicsContext> graphicsContext = pageshotImage->bitmap()->createGraphicsContextForPdfSurface(fileName, pdfWidth, pdfHeight);
460     graphicsContext->scale(FloatSize(scaleFactorPdf, scaleFactorPdf));
461
462     frameView->updateLayoutAndStyleIfNeededRecursive();
463
464     int pageNumber = ((contentsSize.height() * scaleFactorPdf) / pdfHeight) + 1;
465     float paintY = 0.0;
466
467     PaintBehavior oldBehavior = frameView->paintBehavior();
468     frameView->setPaintBehavior(oldBehavior | PaintBehaviorFlattenCompositingLayers);
469     for (int i = 0; i < pageNumber; i++) {
470         IntRect paintRect(0, (int)paintY, contentsSize.width(), (int)(pdfHeight / scaleFactorPdf));
471
472         frameView->paint(graphicsContext.get(), paintRect);
473         cairo_show_page(graphicsContext->platformContext()->cr());
474         graphicsContext->translate(0, -ceil(pdfHeight / scaleFactorPdf));
475         paintY += (pdfHeight / scaleFactorPdf);
476     }
477     frameView->setPaintBehavior(oldBehavior);
478
479     pageshotImage.release();
480 }
481 #endif
482
483 #if ENABLE(TIZEN_TEXT_CARET_HANDLING_WK2)
484 bool WebPage::setCaretPosition(const IntPoint& pos)
485 {
486     Frame* frame = m_page->focusController()->focusedOrMainFrame();
487     if (!frame)
488         return false;
489
490     FrameSelection* controller = frame->selection();
491     if (!controller)
492         return false;
493
494     FrameView* frameView = frame->view();
495     if (!frameView)
496         return false;
497
498     IntPoint point = m_page->mainFrame()->view()->windowToContents(pos);
499     HitTestResult result = m_page->mainFrame()->eventHandler()->hitTestResultAtPoint(point, /*allowShadowContent*/ true, /*ignoreClipping*/ true);
500     if (result.scrollbar())
501         return false;
502
503     Node* innerNode = result.innerNode();
504
505     if (!innerNode || !innerNode->renderer())
506         return false;
507
508     VisiblePosition visiblePos;
509
510     // we check if content is richly editable - because those input field behave other than plain text ones
511     // sometimes they may consists a node structure and they need special approach
512     if (innerNode->rendererIsRichlyEditable()) {
513         // point gets inner node local coordinates
514         point = flooredIntPoint(result.localPoint());
515         IntRect rect = innerNode->renderer()->absoluteBoundingBoxRect(true);
516
517         // it is not the best way to do this, but it is not as slow and it works - so maybe in the future someone
518         // will have a better idea how to solve it
519         // here we are getting innerNode from HitTestResult - unfortunately this is a kind of high level node
520         // in the code below I am trying to obtain low level node - #text - to get its coordinates and size
521
522         // all those getting nodes rects are needed to bypass WebCore's methods of positioning caret when user
523         // is clicking outside a node - and cheat WebCore telling it that actually we clicked into input field
524         // node, not outside of it
525         Node* deepInnerNode = innerNode->renderer()->positionForPoint(point).deepEquivalent().deprecatedNode();
526
527         if (!deepInnerNode || !deepInnerNode->renderer())
528             return false;
529
530         // so we get a base node rectange
531         IntRect deepNodeRect = deepInnerNode->renderer()->absoluteBoundingBoxRect(true);
532
533         // we modify our local point to adjust it to base node local coordinates
534         point.move(rect.x() - deepNodeRect.x(), rect.y() - deepNodeRect.y());
535
536         // if we are outside the rect we cheat, that we are just inside of it
537         if (point.y() < 0)
538             point.setY(0);
539         else if (point.y() >= deepNodeRect.height())
540             point.setY(deepNodeRect.height() - 1);
541
542         // visible position created - caret ready to set
543         visiblePos = deepInnerNode->renderer()->positionForPoint(point);
544         if (visiblePos.isNull())
545             return false;
546     } else {
547         // for plain text input fields we can get only a caret bounding box
548         if (!controller->isCaret() || !controller->caretRenderer())
549             return false;
550
551         const Node* node = controller->start().deprecatedNode();
552         if (!node || !node->renderer())
553             return false;
554
555         IntRect rect = controller->caretRenderer()->absoluteBoundingBoxRect(true);
556
557         // The below wirtten code is not correct way to implement. Presntly the is no
558         // other working way. To be replaced by better logic
559         // here we also cheat input field that we actually are just inside of if
560         IntPoint focusedFramePoint = frame->view()->windowToContents(pos);
561         IntPoint oldFocusedFramePoint = focusedFramePoint;
562
563         const int boundariesWidth = 2;
564         if (focusedFramePoint.x() < rect.x())
565             focusedFramePoint.setX(rect.x());
566         else if (focusedFramePoint.x() > rect.maxX())
567             focusedFramePoint.setX(rect.maxX());
568         if (focusedFramePoint.y() < rect.y() + boundariesWidth)
569             focusedFramePoint.setY(rect.y() + boundariesWidth);
570         else if (focusedFramePoint.y() >= rect.maxY() - boundariesWidth)
571             focusedFramePoint.setY(rect.maxY() - boundariesWidth - 1);
572
573         int diffX = focusedFramePoint.x() - oldFocusedFramePoint.x();
574         int diffY = focusedFramePoint.y() - oldFocusedFramePoint.y();
575         point.setX((point.x())+diffX);
576         point.setY((point.y())+diffY);
577
578         // hit test with fake (adjusted) coordinates
579         IntPoint hitTestPoint = m_page->mainFrame()->view()->windowToContents(point);
580         HitTestResult newResult = m_page->mainFrame()->eventHandler()->hitTestResultAtPoint(hitTestPoint, /*allowShadowContent*/ true, /*ignoreClipping*/ true);
581
582         if (!newResult.isContentEditable())
583             return false;
584
585         Node* newInnerNode = newResult.innerNode();
586
587         if (!newInnerNode || !newInnerNode->renderer())
588             return false;
589
590         // visible position created
591         visiblePos = newInnerNode->renderer()->positionForPoint(newResult.localPoint());
592         if (visiblePos.isNull())
593             return false;
594     }
595
596     // create visible selection from visible position
597     VisibleSelection newSelection = VisibleSelection(visiblePos);
598     controller->setSelection(newSelection, CharacterGranularity);
599     // after setting selection caret blinking is suspended by default so we are unsuspedning it
600     controller->setCaretBlinkingSuspended(false);
601
602     return true;
603 }
604
605 void WebPage::getCaretPosition(IntRect& rect)
606 {
607     Frame* frame = m_page->focusController()->focusedOrMainFrame();
608     if (!frame)
609         return;
610
611     FrameSelection* controller = frame->selection();
612     if (!controller)
613         return;
614
615     Node* node = controller->start().deprecatedNode();
616     if (!node || !node->renderer() || !node->isContentEditable())
617         return;
618
619     if (controller->isCaret()) {
620         FrameView* frameView = frame->view();
621         if (!frameView)
622             return;
623
624         rect = frameView->contentsToWindow(controller->absoluteCaretBounds());
625     }
626 }
627 #endif
628
629 #if ENABLE(TIZEN_ISF_PORT)
630 void WebPage::didCancelComposition(Node* valueChangedNode)
631 {
632     Frame* frame = m_page->focusController()->focusedOrMainFrame();
633     if (!frame || frame->editor()->ignoreCompositionSelectionChange() || !valueChangedNode->containsIncludingShadowDOM(frame->editor()->compositionNode()))
634         return;
635
636     frame->editor()->cancelComposition();
637     send(Messages::WebPageProxy::DidCancelComposition());
638 }
639
640 void WebPage::getCursorOffset(int& offset)
641 {
642     offset = 0;
643     Frame* frame = m_page->focusController()->focusedOrMainFrame();
644     if (!frame || !frame->editor()->canEdit())
645         return;
646
647     Position base = frame->selection()->base();
648     Node* baseNode = base.containerNode();
649     if (baseNode)
650         offset = baseNode->isTextNode() ? base.offsetInContainerNode() : 0;
651 }
652
653 void WebPage::getSurroundingTextAndCursorOffset(String& text, int& offset)
654 {
655     text = String();
656     offset = 0;
657
658     Frame* frame = m_page->focusController()->focusedOrMainFrame();
659     if (!frame || !frame->editor()->canEdit())
660         return;
661
662     Position base = frame->selection()->base();
663     Node* baseNode = base.containerNode();
664     if (baseNode && baseNode->isTextNode()) {
665         text = baseNode->textContent();
666         offset = base.offsetInContainerNode();
667     }
668 }
669
670 void WebPage::getSelectionRect(bool isOnlyEditable, IntRect& rect)
671 {
672     rect = IntRect();
673
674     Frame* frame = m_page->focusController()->focusedFrame();
675     if (!frame || !frame->view())
676         return;
677
678     FrameSelection* selection = frame->selection();
679     Node* node = selection->start().deprecatedNode();
680     if (!node || !node->renderer() || (isOnlyEditable && !node->isContentEditable()))
681         return;
682
683     if (selection->isCaret())
684         rect = frame->view()->contentsToWindow(selection->absoluteCaretBounds());
685     else if (selection->isRange())
686         rect = frame->view()->contentsToWindow(enclosingIntRect(selection->bounds(false)));
687 }
688
689 void WebPage::deleteSurroundingText(int offset, int count)
690 {
691     Frame* frame = m_page->focusController()->focusedOrMainFrame();
692     if (!frame || !frame->editor()->canEdit())
693         return;
694
695     Position base(frame->selection()->base());
696     offset += base.offsetInContainerNode();
697     base.moveToOffset(offset);
698     Position extent(base);
699     extent.moveToOffset(offset + count);
700     VisibleSelection selection(base, extent);
701     if (!selection.isRange())
702         return;
703
704     frame->selection()->setSelection(selection);
705     frame->editor()->deleteWithDirection(DirectionBackward, CharacterGranularity, false, true);
706 }
707 #endif
708
709 #if ENABLE(TIZEN_INPUT_TAG_EXTENSION) || ENABLE(TIZEN_WEBKIT2_FORM_DATABASE)
710 void WebPage::setFocusedInputElementValue(const String& inputValue)
711 {
712     Frame* frame = m_page->focusController()->focusedOrMainFrame();
713     if (!frame || !frame->document() || !frame->document()->focusedNode())
714         return;
715
716     HTMLInputElement* inputElement = frame->document()->focusedNode()->toInputElement();
717     if (!inputElement)
718         return;
719
720     inputElement->toNode()->dispatchFocusEvent(0);
721     inputElement->setValue(inputValue, DispatchChangeEvent);
722 }
723
724 void  WebPage::getFocusedInputElementValue(String& inputValue)
725 {
726     inputValue = String();
727
728     Frame* frame = m_page->focusController()->focusedOrMainFrame();
729     if (!frame || !frame->document() || !frame->document()->focusedNode())
730         return;
731
732     HTMLInputElement* inputElement = frame->document()->focusedNode()->toInputElement();
733     if (!inputElement)
734         return;
735
736     inputValue = inputElement->value();
737 }
738 #endif
739
740 #if ENABLE(TIZEN_DATALIST_ELEMENT)
741 void WebPage::getFocusedInputElementDataList(Vector<String>& optionList)
742 {
743     Frame* frame = m_page->focusController()->focusedOrMainFrame();
744     if (!frame || !frame->document())
745         return;
746
747     Node* node = frame->document()->focusedNode();
748     if (!node)
749         return;
750
751     HTMLInputElement* input = node->toInputElement();
752     if (!input)
753         return;
754
755     HTMLDataListElement* dataList = static_cast<HTMLDataListElement*>(input->list());
756     if (!dataList)
757         return;
758
759     RefPtr<HTMLCollection> options = static_cast<HTMLDataListElement*>(dataList)->options();
760     for (unsigned i = 0; Node* node = options->item(i); i++) {
761         HTMLOptionElement* optionElement = static_cast<HTMLOptionElement*>(node);
762         String value = optionElement->value();
763         optionList.append(value);
764     }
765 }
766 #endif
767
768 #if ENABLE(TIZEN_WEBKIT2_FOCUS_RING)
769 static IntRect getNodeRect(Node* node, Node* focusableNode, bool isImage)
770 {
771     IntRect rect;
772
773     if (isImage) {
774         bool isReplaced;
775         IntRect imageNodeRect = pixelSnappedIntRect(node->getRect());
776         if (!focusableNode->renderRect(&isReplaced).isEmpty() && imageNodeRect.contains(pixelSnappedIntRect(focusableNode->getRect()))) {
777             // If render rect of focusableNode is empty and rect of imageNode include rect of focusableNode,
778             // we have to get rect of focusableNode.
779             // for example - The rect of google logo image in www.google.com pc site's search result page is bigger than rect of focusableNode.
780             // for example - The rect of category menu image in www.gmarket.co.kr pc site is bigger than rect of focusableNode.
781             rect = pixelSnappedIntRect(focusableNode->getRect());
782         }
783         else {
784             // otherwise we have to get rect of imageNode.
785             // for example - The render rect of images in www.pudelek.pl is empty.
786             // 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.
787             rect = imageNodeRect;
788             focusableNode = node;
789         }
790     } else {
791         // If focusedNode have multiple child nodes, we have to unite rect of child nodes.
792         // for example - links in www.google.com's search result page.
793         IntRect tempRect;
794         for (Node* childNode = focusableNode->firstChild(); childNode; childNode = childNode->traverseNextNode(focusableNode)) {
795             bool isReplaced;
796             if (focusableNode->renderRect(&isReplaced).contains(childNode->getRect()))
797                 tempRect.unite(pixelSnappedIntRect(childNode->getRect()));
798         }
799
800         // If tempRect is empty or rect of focusableNode include tempRect,
801         // we have to get rect of focusableNode.
802         // for example - list menu item in m.naver.com.
803         // otherwise we have to get rect of tempRect.
804         // getRect API do not return correct rect if the node is a container node,
805         // hence using absoluteBoundingBoxRect to get the correct bounding rect.
806         LayoutRect renderRect = focusableNode->renderer() ? focusableNode->renderer()->absoluteBoundingBoxRect() : focusableNode->getRect();
807         if (tempRect.isEmpty() || renderRect.contains(tempRect))
808             rect = pixelSnappedIntRect(renderRect);
809         else
810             rect = tempRect;
811     }
812
813     // We have to get render rect from ancestor node if current rect is empty.
814     // for example - The rect of naver logo image in www.naver.com pc site is empty.
815     bool isReplaced;
816     for (Node* loopNode = focusableNode; loopNode && rect.isEmpty(); loopNode = loopNode->parentNode()) {
817         RenderObject* renderer = loopNode->renderer();
818         if (renderer && renderer->isRoot())
819             break;
820
821         rect = pixelSnappedIntRect(loopNode->renderRect(&isReplaced));
822     }
823
824     Frame* nodeFrame = focusableNode->document()->frame();
825     Node* owner;
826     while (nodeFrame && (owner = nodeFrame->ownerElement())) {
827         rect.moveBy(owner->getRect().pixelSnappedLocation());
828         nodeFrame = owner->document()->frame();
829     }
830
831     // The y position of tab menu item in www.google.com is negative value,
832     // so we do not want to draw focus ring in that case.
833     if ((rect.maxX() < 0) || (rect.maxY() < 0))
834         rect = IntRect();
835
836     return rect;
837 }
838 #endif
839
840 #if ENABLE(TIZEN_WEBKIT2_HIT_TEST)
841 #if ENABLE(TIZEN_WEBKIT2_FOCUS_RING)
842 static IntRect getFocusedRect(HitTestResult hitTestResult, Page* page)
843 {
844     Node* node = hitTestResult.innerNode();
845     bool isFocusRingDrawable = false;
846     Node* focusableNode = node;
847     while (focusableNode) {
848         RenderObject* renderer = focusableNode->renderer();
849         if (renderer && renderer->isRoot())
850             break;
851
852         if (focusableNode->isFocusable()) {
853             if (focusableNode->isLink()
854                 || focusableNode->hasTagName(HTMLNames::inputTag)
855                 || focusableNode->hasTagName(HTMLNames::selectTag)
856                 || focusableNode->hasTagName(HTMLNames::buttonTag))
857                 isFocusRingDrawable = true;
858             break;
859         }
860
861         focusableNode = focusableNode->parentNode();
862     }
863
864     if (!isFocusRingDrawable) {
865         if (node->hasTagName(HTMLNames::imgTag))
866             return getNodeRect(node, node, !hitTestResult.absoluteImageURL().isEmpty());
867
868         return IntRect();
869     }
870
871     return getNodeRect(node, focusableNode, !hitTestResult.absoluteImageURL().isEmpty());
872 }
873 #endif
874
875 void WebPage::hitTestResultAtPoint(const IntPoint& point, int hitTestMode, WebHitTestResult::Data& hitTestResultData)
876 {
877     Frame* frame = m_page->mainFrame();
878     FrameView* frameView = frame->view();
879     if (!frameView)
880         return;
881
882     HitTestResult hitTestResult = frame->eventHandler()->hitTestResultAtPoint(frameView->windowToContents(point), false);
883     hitTestResultData.absoluteImageURL = hitTestResult.absoluteImageURL().string();
884     hitTestResultData.absoluteLinkURL = hitTestResult.absoluteLinkURL().string();
885     hitTestResultData.absoluteMediaURL = hitTestResult.absoluteMediaURL().string();
886     hitTestResultData.linkLabel = hitTestResult.textContent();
887     hitTestResultData.linkTitle = hitTestResult.titleDisplayString();
888 #if ENABLE(TIZEN_DRAG_SUPPORT)
889     hitTestResultData.isDragSupport = hitTestResult.isDragSupport();
890 #endif
891
892     int context = WebHitTestResult::HitTestResultContextDocument;
893
894     if (!hitTestResult.absoluteLinkURL().isEmpty())
895         context |= WebHitTestResult::HitTestResultContextLink;
896     if (!hitTestResult.absoluteImageURL().isEmpty())
897         context |= WebHitTestResult::HitTestResultContextImage;
898     if (!hitTestResult.absoluteMediaURL().isEmpty())
899         context |= WebHitTestResult::HitTestResultContextMedia;
900     if (hitTestResult.isSelected())
901         context |= WebHitTestResult::HitTestResultContextSelection;
902     if (hitTestResult.isContentEditable())
903         context |= WebHitTestResult::HitTestResultContextEditable;
904     if (hitTestResult.innerNonSharedNode() && hitTestResult.innerNonSharedNode()->isTextNode())
905         context |= WebHitTestResult::HitTestResultContextText;
906
907     hitTestResultData.context = context;
908     hitTestResultData.hitTestMode = hitTestMode;
909
910 #if ENABLE(TIZEN_WEBKIT2_FOCUS_RING)
911     hitTestResultData.focusedRect = getFocusedRect(hitTestResult, m_page.get());
912     if (hitTestResult.innerNode() && hitTestResult.innerNode()->renderer() && hitTestResult.innerNode()->renderer()->style()) {
913         hitTestResultData.focusedColor = hitTestResult.innerNode()->renderer()->style()->tapHighlightColor();
914         if (!hitTestResultData.focusedColor.hasAlpha())
915             hitTestResultData.focusedColor = Color(hitTestResultData.focusedColor.red(), hitTestResultData.focusedColor.green(), hitTestResultData.focusedColor.blue(), RenderStyle::initialTapHighlightColor().alpha());
916     }
917 #endif
918
919     if (hitTestResultData.hitTestMode & WebHitTestResult::HitTestModeNodeData) {
920         WebCore::Node* hitNode = hitTestResult.innerNonSharedNode();
921         if (hitNode) {
922             hitTestResultData.nodeData.nodeValue = hitNode->nodeValue();
923
924             if ((hitTestResultData.context & WebHitTestResult::HitTestResultContextText) && hitNode->parentNode())
925                 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.
926
927             if (hitNode->isElementNode()) {
928                 WebCore::Element* hitElement = static_cast<WebCore::Element*>(hitNode);
929                 if (hitElement) {
930                     hitTestResultData.nodeData.tagName = hitElement->tagName();
931                 }
932             }
933
934             WebCore::NamedNodeMap* namedNodeMap = hitNode->attributes();
935             if (namedNodeMap) {
936                 for (size_t i = 0; i < namedNodeMap->length(); i++) {
937                     const WebCore::Attribute* attribute = namedNodeMap->element()->attributeItem(i);
938                     String key = attribute->name().toString();
939                     String value = attribute->value();
940                     hitTestResultData.nodeData.attributeMap.add(key, value);
941                 }
942             }
943         }
944     }
945
946     if ((hitTestResultData.hitTestMode & WebHitTestResult::HitTestModeImageData) && (hitTestResultData.context & WebHitTestResult::HitTestResultContextImage)) {
947         WebCore::Image* hitImage = hitTestResult.image();
948         if (hitImage && hitImage->data() && hitImage->data()->data()) {
949             hitTestResultData.imageData.data.append(hitImage->data()->data(), hitImage->data()->size());
950             hitTestResultData.imageData.fileNameExtension = hitImage->filenameExtension();
951         }
952     }
953 }
954 #endif
955
956 #if ENABLE(TIZEN_WEB_STORAGE)
957 void WebPage::getStorageQuotaBytes(uint64_t callbackID)
958 {
959     uint32_t quota = m_page->group().groupSettings()->localStorageQuotaBytes();
960     send(Messages::WebPageProxy::DidGetWebStorageQuotaBytes(quota, callbackID));
961 }
962
963 void WebPage::setStorageQuotaBytes(uint32_t quota)
964 {
965     m_page->group().groupSettings()->setLocalStorageQuotaBytes(quota);
966 }
967 #endif
968
969 #if ENABLE(TIZEN_RECORDING_SURFACE_SET)
970 void WebPage::recordingSurfaceSetEnableSet(bool enable)
971 {
972     m_recordingSurfaceSetSettings = enable;
973 }
974 #endif
975
976 #if ENABLE(TIZEN_CLIPBOARD) || ENABLE(TIZEN_PASTEBOARD)
977 void WebPage::setClipboardDataForPaste(const String& data, const String& type)
978 {
979 #if ENABLE(TIZEN_PASTEBOARD)
980     // FIXME: Should move to EditorClient like Clipboard
981     Pasteboard::generalPasteboard()->setDataWithType(data, type);
982 #else
983     Frame* mainFrame = m_page->mainFrame();
984     if (!mainFrame)
985         return;
986
987     mainFrame->editor()->client()->setClipboardDataForPaste(data, type);
988 #endif
989 }
990 #endif
991
992 void WebPage::suspendJavaScriptAndResources()
993 {
994     Frame* mainFrame = m_page->mainFrame();
995     if (!mainFrame)
996         return;
997
998     for (Frame* frame = mainFrame; frame; frame = frame->tree()->traverseNext())
999         frame->document()->suspendScheduledTasks(WebCore::ActiveDOMObject::PageWillBeSuspended);
1000     mainFrame->loader()->suspendAllLoaders();
1001 }
1002
1003 void WebPage::resumeJavaScriptAndResources()
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()->resumeScheduledTasks();
1011     mainFrame->loader()->resumeAllLoaders();
1012 }
1013
1014 #if ENABLE(TIZEN_SYNC_REQUEST_ANIMATION_FRAME)
1015 void WebPage::suspendAnimationController()
1016 {
1017     if (!m_suspendedAnimationController) {
1018         Frame* mainFrame = m_page->mainFrame();
1019         if (!mainFrame)
1020             return;
1021
1022         for (Frame* frame = mainFrame; frame; frame = frame->tree()->traverseNext())
1023             frame->document()->suspendScriptedAnimationControllerCallbacks();
1024
1025         m_suspendedAnimationController = true;
1026     }
1027 }
1028
1029 void WebPage::resumeAnimationController()
1030 {
1031     if (m_suspendedAnimationController) {
1032         Frame* mainFrame = m_page->mainFrame();
1033         if (!mainFrame)
1034             return;
1035
1036         for (Frame* frame = mainFrame; frame; frame = frame->tree()->traverseNext())
1037             frame->document()->resumeScriptedAnimationControllerCallbacks();
1038
1039         m_suspendedAnimationController = false;
1040     }
1041 }
1042 #endif
1043
1044 #if ENABLE(TIZEN_WEBKIT2_REMOTE_WEB_INSPECTOR)
1045 void WebPage::startInspectorServer(uint32_t port,  uint32_t& allocatedPort)
1046 {
1047     bool ret = WebInspectorServerEfl::server()->startServer(port);
1048     if (ret)
1049         allocatedPort = WebInspectorServerEfl::server()->getServerPort();
1050     else
1051         allocatedPort = 0;
1052 }
1053
1054 void WebPage::stopInspectorServer(bool& result)
1055 {
1056     result = WebInspectorServerEfl::server()->stopServer();
1057 }
1058 #endif
1059
1060 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION_ON_UI_SIDE)
1061 void WebPage::scrollOverflowWithTrajectoryVector(const WebCore::FloatPoint& trajectoryVector)
1062 {
1063     Frame* frame = m_page->focusController()->focusedOrMainFrame();
1064     if (!frame)
1065         return;
1066     frame->eventHandler()->scrollOverflow(trajectoryVector);
1067 }
1068 #endif
1069
1070 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION)
1071 void WebPage::scrollOverflow(const WebCore::FloatPoint& delta, bool& scrolled)
1072 {
1073     scrolled = m_page->focusController()->focusedOrMainFrame()->eventHandler()->scrollOverflow(delta);
1074 }
1075
1076 void WebPage::setPressedNodeAtPoint(const IntPoint& point, bool checkOverflowLayer, bool& pressed, uint32_t& id)
1077 {
1078     RenderObject* renderer = 0;
1079     id = 0;
1080     pressed = m_page->mainFrame()->eventHandler()->setMousePressNodeAtPoint(point, checkOverflowLayer, renderer);
1081 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION_ON_UI_SIDE)
1082     if (pressed && renderer)
1083         id = toWebGraphicsLayer(renderer->enclosingLayer()->layerForScrollingContents())->id();
1084 #endif
1085 }
1086 #endif
1087
1088 void WebPage::executeEditCommandWithArgument(const String& commandName, const String& argument)
1089 {
1090     executeEditingCommand(commandName, argument);
1091 }
1092
1093 #if ENABLE(TIZEN_PLUGIN_SUSPEND_RESUME)
1094 void WebPage::suspendPlugin()
1095 {
1096     for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
1097         FrameView* view = frame->view();
1098         if (!view)
1099             continue;
1100
1101         const HashSet<RefPtr<Widget> >* children = view->children();
1102         ASSERT(children);
1103
1104         HashSet<RefPtr<Widget> >::const_iterator end = children->end();
1105         for (HashSet<RefPtr<Widget> >::const_iterator it = children->begin(); it != end; ++it) {
1106             Widget* widget = (*it).get();
1107             if (widget->isPluginViewBase()) {
1108                 PluginView* pluginView = static_cast<PluginView*>(widget);
1109                 if (pluginView)
1110                     pluginView->suspendPlugin();
1111             }
1112         }
1113     }
1114 }
1115
1116 void WebPage::resumePlugin()
1117 {
1118     for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
1119         FrameView* view = frame->view();
1120         if (!view)
1121             continue;
1122
1123         const HashSet<RefPtr<Widget> >* children = view->children();
1124         ASSERT(children);
1125
1126         HashSet<RefPtr<Widget> >::const_iterator end = children->end();
1127         for (HashSet<RefPtr<Widget> >::const_iterator it = children->begin(); it != end; ++it) {
1128             Widget* widget = (*it).get();
1129             if (widget->isPluginViewBase()) {
1130                 PluginView* pluginView = static_cast<PluginView*>(widget);
1131                 if (pluginView)
1132                     pluginView->resumePlugin();
1133             }
1134         }
1135     }
1136 }
1137 #endif
1138
1139 #if ENABLE(TIZEN_WEBKIT2_GET_TEXT_STYLE_FOR_SELECTION)
1140 void WebPage::getTextStyleStateForSelection()
1141 {
1142     Frame* frame = m_page->focusController()->focusedOrMainFrame();
1143
1144     int underlineState = frame->editor()->selectionHasStyle(CSSPropertyWebkitTextDecorationsInEffect, "underline");
1145     int italicState = frame->editor()->selectionHasStyle(CSSPropertyFontStyle, "italic");
1146     int boldState = frame->editor()->selectionHasStyle(CSSPropertyFontWeight, "bold");
1147
1148     send(Messages::WebPageProxy::DidGetTextStyleStateForSelection(underlineState, italicState, boldState));
1149 }
1150 #endif
1151
1152 #if ENABLE(TIZEN_MULTIPLE_SELECT)
1153 void WebPage::didChangeSelectedIndexForActivePopupMenuMultiple(Vector<int32_t> newIndex)
1154 {
1155     if (!m_activePopupMenu)
1156         return;
1157
1158     m_activePopupMenu->client()->popupDidHide();
1159
1160     size_t indexSize = newIndex.size();
1161     for (size_t i = 0; i < indexSize; i++)
1162         m_activePopupMenu->didChangeSelectedIndex(newIndex.at(i));
1163
1164 }
1165 #endif
1166
1167 #if ENABLE(TIZEN_OFFLINE_PAGE_SAVE)
1168 void WebPage::startOfflinePageSave(String subresourceFolderName)
1169 {
1170     WebPageSerializerTizen::getSerializedPageContent(this, subresourceFolderName);
1171 }
1172 #endif
1173
1174 #if ENABLE(TIZEN_WEBKIT2_TEXT_SELECTION)
1175 void WebPage::selectClosestWord(const IntPoint& point, bool isStartedTextSelectionFromOutside, bool& result)
1176 {
1177     result = false;
1178
1179     Frame* mainFrame = m_page->mainFrame();
1180     Frame* focusedFrame = m_page->focusController()->focusedOrMainFrame();
1181
1182     HitTestResult hitTestResult = mainFrame->eventHandler()->hitTestResultAtPoint(m_page->mainFrame()->view()->windowToContents(point), false);
1183
1184     Node* node = hitTestResult.innerNonSharedNode();
1185     if (!node)
1186         return;
1187
1188      Frame* newFocusFrame = node->document()->frame();
1189      if (focusedFrame != newFocusFrame) {
1190          m_page->focusController()->setFocusedFrame(newFocusFrame);
1191          focusedFrame = newFocusFrame;
1192      }
1193
1194 #if ENABLE(TIZEN_INPUT_TAG_EXTENSION)
1195     HTMLInputElement* inputElement = node->toInputElement();
1196 #endif
1197
1198     if (hitTestResult.isContentEditable()) {
1199 #if ENABLE(TIZEN_INPUT_TAG_EXTENSION)
1200         if (!inputElement || (inputElement
1201             && !inputElement->isDateField() && !inputElement->isDateTimeField() && !inputElement->isDateTimeLocalField()
1202             && !inputElement->isMonthField() && !inputElement->isTimeField() && !inputElement->isWeekField())) {
1203             result = setCaretPosition(point);
1204             return;
1205         }
1206 #else
1207         result = setCaretPosition(point);
1208         return;
1209 #endif
1210     }
1211
1212 #if ENABLE(TIZEN_INPUT_TAG_EXTENSION)
1213     if (!node->isTextNode() && !inputElement)
1214 #else
1215     if (!node->isTextNode())
1216 #endif
1217         return;
1218
1219     if (!isStartedTextSelectionFromOutside) {
1220         for (Node* node = hitTestResult.innerNonSharedNode(); node; node = node->parentNode()) {
1221             if (node->isFocusable()) {
1222                 // Text selection shoud not be started when text of <button> tag is selected.
1223                 if (node->hasTagName(HTMLNames::buttonTag))
1224                     return;
1225                 break;
1226             }
1227         }
1228     }
1229
1230     FrameSelection* frameSelection = focusedFrame->selection();
1231
1232     VisiblePosition position = mainFrame->visiblePositionForPoint(point);
1233     VisibleSelection selection(position);
1234
1235     // This changes just the 'start' and 'end' positions of the VisibleSelection
1236     selection.expandUsingGranularity(WordGranularity);
1237
1238     FrameSelection::SetSelectionOptions options = FrameSelection::CloseTyping | FrameSelection::ClearTypingStyle | FrameSelection::DoNotSetFocus;
1239     frameSelection->setSelection(VisibleSelection(selection.start(), selection.end()), options);
1240
1241     if (!frameSelection->isRange())
1242         return;
1243
1244     // This changes just the 'start' and 'end' positions of the VisibleSelection
1245     // Find handlers positions
1246     IntRect leftRect, rightRect;
1247     getSelectionHandlers(leftRect, rightRect);
1248     if (leftRect.size().isZero() && rightRect.size().isZero()) {
1249         // Sometimes there is no selected text, but isNone() returns TRUE
1250         // in this case ewk_frame_selection_handlers_get() returns FALSE and handlers are invalid
1251         // Workaround - clear the selection.
1252         // Better solution would be to modify the ewk_frame_select_closest_word()
1253         // to not select anything in the first place (for example - don't call setSelection()
1254         // if there is nothing under the cursor).
1255         selectionClearAllSelection(m_page->mainFrame());
1256         return;
1257     }
1258
1259     result = true;
1260 }
1261
1262 void WebPage::setLeftSelection(const IntPoint& point, bool& result)
1263 {
1264     result = false;
1265
1266     Frame* focusedFrame = m_page->focusController()->focusedOrMainFrame();
1267     FrameSelection* frameSelection = focusedFrame->selection();
1268     if (!frameSelection->isRange())
1269         return;
1270
1271     Node* selectionEndNode = frameSelection->end().deprecatedNode();
1272     if (!selectionEndNode || !selectionEndNode->renderer())
1273         return;
1274
1275     FrameView* frameView = focusedFrame->view();
1276     if (!frameView)
1277         return;
1278
1279     IntPoint pos = frameView->windowToContents(point);
1280     IntRect leftRect, rightRect;
1281     getSelectionHandlers(leftRect, rightRect);
1282     if ((rightRect.y() + rightRect.height()) < pos.y())
1283         pos.setY(rightRect.y() + (rightRect.height()/2));
1284
1285     if (selectionEndNode->rendererIsEditable() && !selectionEndNode->rendererIsRichlyEditable()) {
1286         const int boundariesWidth = 2;
1287
1288         IntRect rect = frameSelection->caretRenderer()->absoluteBoundingBoxRect(true);
1289         // here we cheat input field that we actually are just inside of if
1290         if (pos.y() < rect.y() + boundariesWidth)
1291             pos.setY(rect.y() + boundariesWidth);
1292         else if (pos.y() >= rect.maxY() - boundariesWidth)
1293             pos.setY(rect.maxY() - boundariesWidth - 1);
1294     }
1295
1296     OwnPtr<VisiblePosition> position = adoptPtr(new VisiblePosition(focusedFrame->visiblePositionForPoint(pos)));
1297     Position extent = frameSelection->extent();
1298
1299     Node* newSelectionStartNode = position->deepEquivalent().deprecatedNode();
1300
1301     // both start and end nodes should be in the same area type: both should be editable or both should be not editable
1302     // Check if the new position is before the extent's position
1303     if (newSelectionStartNode
1304         && selectionEndNode->isContentEditable() == newSelectionStartNode->isContentEditable()
1305         && comparePositions(position->deepEquivalent(), extent) < 0) {
1306         // Change the 'base' and 'extent' positions to 'start' and 'end' positions.
1307         // We do it, because without this, the other modification of the selection
1308         // would destroy the 'start' and/or 'end' positions and set them to
1309         // the 'base'/'extent' positions accordingly
1310         VisibleSelection sel(frameSelection->start(), frameSelection->end());
1311         frameSelection->setSelection(sel);
1312
1313         bool oldProhibitsScrolling = focusedFrame->view()->prohibitsScrolling();
1314         focusedFrame->view()->setProhibitsScrolling(true);
1315
1316         frameSelection->setBase(*position);
1317
1318         focusedFrame->view()->setProhibitsScrolling(oldProhibitsScrolling);
1319         // This forces webkit to show selection
1320         // m_coreFrame->invalidateSelection();
1321
1322         result = true;
1323     }
1324 }
1325
1326
1327 void WebPage::setRightSelection(const IntPoint& point, bool& result)
1328 {
1329     result = false;
1330
1331     Frame* focusedFrame = m_page->focusController()->focusedOrMainFrame();
1332     FrameSelection* frameSelection = focusedFrame->selection();
1333
1334     if (!frameSelection->isRange())
1335         return;
1336
1337     Node* selectionStartNode = frameSelection->start().deprecatedNode();
1338     if (!selectionStartNode || !selectionStartNode->renderer())
1339         return;
1340
1341     FrameView* frameView = focusedFrame->view();
1342     if (!frameView)
1343         return;
1344
1345     IntPoint pos = frameView->windowToContents(point);
1346     if (selectionStartNode->rendererIsEditable() && !selectionStartNode->rendererIsRichlyEditable()) {
1347         const int boundariesWidth = 2;
1348
1349         IntRect rect = frameSelection->caretRenderer()->absoluteBoundingBoxRect(true);
1350         // here we cheat input field that we actually are just inside of if
1351         if (pos.y() < rect.y() + boundariesWidth)
1352             pos.setY(rect.y() + boundariesWidth);
1353         else if (pos.y() >= rect.maxY() - boundariesWidth)
1354             pos.setY(rect.maxY() - boundariesWidth - 1);
1355     }
1356
1357     OwnPtr<VisiblePosition> position = adoptPtr(new VisiblePosition(focusedFrame->visiblePositionForPoint(pos)));
1358     Position base = frameSelection->base();
1359
1360     Node* newSelectionEndNode = position->deepEquivalent().deprecatedNode();
1361
1362     // both start and end nodes should be in the same area type: both should be editable or both should be not editable
1363     // Check if the new position is after the base's position
1364     if (newSelectionEndNode
1365         && selectionStartNode->isContentEditable() == newSelectionEndNode->isContentEditable()
1366         && comparePositions(position->deepEquivalent(), base) > 0) {
1367         // Change the 'base' and 'extent' positions to 'start' and 'end' positions.
1368         // We do it, because without this, the other modifications of the selection
1369         // would destroy the 'start' and/or 'end' positions and set them to
1370         // the 'base'/'extent' positions accordingly
1371
1372         VisibleSelection sel(frameSelection->start(), frameSelection->end());
1373         frameSelection->setSelection(sel);
1374
1375         bool oldProhibitsScrolling = focusedFrame->view()->prohibitsScrolling();
1376         focusedFrame->view()->setProhibitsScrolling(true);
1377
1378         frameSelection->setExtent(*position);
1379
1380         focusedFrame->view()->setProhibitsScrolling(oldProhibitsScrolling);
1381
1382         result = true;
1383     }
1384 }
1385
1386 void WebPage::getSelectionHandlers(IntRect& leftRect, IntRect& rightRect)
1387 {
1388     Frame* focusedFrame = m_page->focusController()->focusedOrMainFrame();
1389     if (!focusedFrame->selection()->isRange())
1390         return;
1391
1392     // Is this check necessary? Leaving it for safety.
1393     RenderView* root = focusedFrame->contentRenderer();
1394     if (!root)
1395         return;
1396
1397     RefPtr<Range> selectedRange = focusedFrame->selection()->toNormalizedRange();
1398
1399     Vector<IntRect> rects, tempRects;
1400     selectedRange->boundingBoxEx(tempRects, true);
1401
1402     IntRect boundsRect =  enclosingIntRect(focusedFrame->selection()->bounds());
1403     for (size_t i = 0; i < tempRects.size(); i++) {
1404         if (boundsRect.contains(tempRects[i]))
1405             rects.append(tempRects[i]);
1406         else {
1407             tempRects[i].intersect(boundsRect);
1408             if (!tempRects[i].isEmpty())
1409                 rects.append(tempRects[i]);
1410         }
1411     }
1412
1413     unsigned size = rects.size();
1414     if (size > 0) {
1415         leftRect = rects[0];
1416         rightRect = rects[size-1];
1417
1418         // If selection rect size is greater than editor rect size because of round operation,
1419         // selection rect size should be changed to editor rect size.
1420         if (size == 1) {
1421             Element* selectionRoot = focusedFrame->selection()->rootEditableElement();
1422             if (selectionRoot) {
1423                 IntRect editorRect = focusedFrame->view()->contentsToWindow(selectionRoot->getPixelSnappedRect());
1424
1425 #if ENABLE(TIZEN_WEBKIT2_TEXT_SELECTION)
1426                 if (m_editorState.editorRect != editorRect) {
1427                     EditorState state = editorState();
1428                     state.updateEditorRectOnly = true;
1429                     send(Messages::WebPageProxy::EditorStateChanged(state));
1430                 }
1431 #endif
1432
1433                 if (leftRect.maxY() > editorRect.maxY()) {
1434                     leftRect.setY(editorRect.y());
1435                     leftRect.setHeight(editorRect.height());
1436                 }
1437
1438                 if (rightRect.maxY() > editorRect.maxY()) {
1439                     rightRect.setY(editorRect.y());
1440                     rightRect.setHeight(editorRect.height());
1441                 }
1442             }
1443         }
1444
1445         // prevent from selecting zero-length selection
1446         if (leftRect.x() == rightRect.x() + rightRect.width()
1447             && leftRect.y() == rightRect.y())
1448             return;
1449
1450         FrameView* frameView = focusedFrame->view();
1451         if (!frameView)
1452             return;
1453
1454         leftRect = frameView->contentsToWindow(leftRect);
1455         rightRect = frameView->contentsToWindow(rightRect);
1456      }
1457 }
1458
1459 void WebPage::getSelectionText(String& result)
1460 {
1461     Frame* focusedFrame = m_page->focusController()->focusedOrMainFrame();
1462     result = focusedFrame->editor()->selectedText();
1463 }
1464
1465 void WebPage::selectionRangeClear(bool& result)
1466 {
1467     result = false;
1468
1469     Frame* focusedFrame = m_page->focusController()->focusedOrMainFrame();
1470     FrameSelection* frameSelection = focusedFrame->selection();
1471     if (frameSelection && frameSelection->isRange() && frameSelection->isContentEditable()) {
1472         VisiblePosition visiblePos(frameSelection->extent());
1473         if (visiblePos.isNull())
1474             return;
1475
1476         focusedFrame->editor()->setIgnoreCompositionSelectionChange(true);
1477         frameSelection->setSelection(VisibleSelection(visiblePos), CharacterGranularity);
1478         focusedFrame->editor()->setIgnoreCompositionSelectionChange(false);
1479
1480         frameSelection->setCaretBlinkingSuspended(false);
1481     } else
1482         selectionClearAllSelection(m_page->mainFrame());
1483
1484     result = true;
1485 }
1486
1487 void WebPage::selectionClearAllSelection(Frame* frame)
1488 {
1489     if (!frame)
1490         return;
1491
1492     FrameSelection* frameSelection = frame->selection();
1493     if (frameSelection)
1494         frameSelection->clear();
1495
1496     if (!frame->tree())
1497         return;
1498
1499     if (frame->tree()->childCount() > 0) {
1500         if (frame->tree()->firstChild())
1501             selectionClearAllSelection(frame->tree()->firstChild());
1502     } else if (frame->tree()->nextSibling())
1503         selectionClearAllSelection(frame->tree()->nextSibling());
1504 }
1505
1506 void WebPage::scrollContentByCharacter(const IntPoint&, int direction, bool& result)
1507 {
1508     result = false;
1509
1510     Frame* focusedFrame = m_page->focusController()->focusedOrMainFrame();
1511     if (direction)
1512         result = focusedFrame->selection()->modify(FrameSelection::AlterationMove, DirectionBackward, CharacterGranularity, UserTriggered);
1513     else
1514         result = focusedFrame->selection()->modify(FrameSelection::AlterationMove, DirectionForward, CharacterGranularity, UserTriggered);
1515 }
1516 #endif
1517
1518 #if ENABLE(TIZEN_LINK_MAGNIFIER)
1519 void WebPage::getLinkMagnifierRect(const IntPoint& position, const IntSize& size)
1520 {
1521     send(Messages::WebPageProxy::DidGetLinkMagnifierRect(position, LinkMagnifier::rect(this, position, size)));
1522 }
1523 #endif
1524
1525 #if ENABLE(TIZEN_SCREEN_READER)
1526 void WebPage::raiseTapEvent(const IntPoint& position, const IntPoint& globalPosition)
1527 {
1528     Frame* frame = m_page->mainFrame();
1529     if (!frame->view())
1530         return;
1531
1532     Vector<WebPlatformTouchPoint> touchPoints;
1533     touchPoints.append(WebPlatformTouchPoint(0, WebPlatformTouchPoint::TouchPressed, globalPosition, position));
1534
1535     WebTouchEvent touchStartEvent(WebEvent::TouchStart, touchPoints, WebEvent::Modifiers(0), ecore_time_get());
1536     if (!frame->eventHandler()->handleTouchEvent(platform(touchStartEvent))) {
1537         WebGestureEvent gestureEvent(WebEvent::GestureSingleTap, position, globalPosition, WebEvent::Modifiers(0), ecore_time_get());
1538         frame->eventHandler()->handleGestureEvent(platform(gestureEvent));
1539     }
1540
1541     touchPoints.at(0).setState(WebPlatformTouchPoint::TouchReleased);
1542     WebTouchEvent touchEndEvent(WebEvent::TouchEnd, touchPoints, WebEvent::Modifiers(0), ecore_time_get());
1543     frame->eventHandler()->handleTouchEvent(platform(touchEndEvent));
1544 }
1545
1546 static void sendScreenReaderFocusRect(WebPage* page, Node* node)
1547 {
1548     bool isImage = false;
1549     if (node->isElementNode()) {
1550         Element* element = static_cast<Element*>(node);
1551         isImage = !element->getAttribute(element->imageSourceAttributeName()).isEmpty();
1552     }
1553
1554     page->send(Messages::WebPageProxy::DidScreenReaderFocusRectChanged(getNodeRect(node, node, isImage)));
1555 }
1556
1557 void WebPage::moveScreenReaderFocus(bool forward, bool& result)
1558 {
1559     if (!m_screenReader)
1560         m_screenReader = ScreenReader::create(this);
1561
1562     if (!m_screenReader->moveFocus(forward)) {
1563         result = false;
1564         send(Messages::WebPageProxy::DidScreenReaderFocusRectChanged(IntRect()));
1565         return;
1566     } else {
1567         result = true;
1568         sendScreenReaderFocusRect(this, m_screenReader->getFocusedNode());
1569     }
1570 }
1571
1572 void WebPage::moveScreenReaderFocusByPoint(const IntPoint& point)
1573 {
1574     if (!m_screenReader)
1575         m_screenReader = ScreenReader::create(this);
1576
1577     if (!m_screenReader->moveFocus(point))
1578         return;
1579
1580     sendScreenReaderFocusRect(this, m_screenReader->getFocusedNode());
1581 }
1582
1583 void WebPage::recalcScreenReaderFocusRect()
1584 {
1585     if (!m_screenReader || !m_screenReader->getFocusedNode())
1586         return;
1587
1588     sendScreenReaderFocusRect(this, m_screenReader->getFocusedNode());
1589 }
1590
1591 void WebPage::updateScreenReaderFocus(RenderObject* object)
1592 {
1593     if (!m_screenReader)
1594         return;
1595
1596     if (!object)
1597         m_screenReader->clearFocus();
1598     else if (!m_screenReader->rendererWillBeDestroyed(object))
1599         return;
1600
1601     send(Messages::WebPageProxy::DidScreenReaderFocusRectChanged(IntRect()));
1602 }
1603
1604 void WebPage::clearScreenReader()
1605 {
1606     m_screenReader.clear();
1607 }
1608 #endif
1609
1610 #if ENABLE(TIZEN_WEBKIT2_POPUP_INTERNAL)
1611 // FIXME: Currently with cached pages, hiding Popup list menu is not working correctly.
1612 // This patch is a fix allowing any popup list menu to get close for any page navigation.
1613 void WebPage::notifyTransitionToCommitted(bool forNewPage)
1614 {
1615     if (m_activePopupMenu) {
1616         TIZEN_LOGI("");
1617         m_activePopupMenu->hide();
1618     }
1619 }
1620 #endif
1621
1622 #if ENABLE(TIZEN_CSP)
1623 void WebPage::setContentSecurityPolicy(const String& policy, uint32_t headerType)
1624 {
1625     Frame* frame = m_page->focusController()->focusedOrMainFrame();
1626     if (!frame)
1627         return;
1628
1629     Document* document = frame->document();
1630     if (!document)
1631         return;
1632
1633     document->contentSecurityPolicy()->didReceiveHeader(policy, static_cast<WebCore::ContentSecurityPolicy::HeaderType>(headerType));
1634 }
1635 #endif
1636
1637 #if ENABLE(TIZEN_INDEXED_DATABASE)
1638 void WebPage::setIndexedDatabaseDirectory(const String& path)
1639 {
1640     m_page->group().groupSettings()->setIndexedDBDatabasePath(path);
1641 }
1642 #endif
1643
1644 #if ENABLE(TIZEN_WEB_STORAGE)
1645 void WebPage::setLocalStorageDirectory(const String& path)
1646 {
1647     m_page->settings()->setLocalStorageDatabasePath(path);
1648 }
1649 #endif
1650 #endif // #if OS(TIZEN)
1651
1652 } // namespace WebKit