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