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