updating changelog for release
[profile/ivi/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 "NamedNodeMap.h"
32 #include "NotImplemented.h"
33 #include "WebEvent.h"
34 #include "WindowsKeyboardCodes.h"
35 #include <WebCore/EflKeyboardUtilities.h>
36 #include <WebCore/FocusController.h>
37 #include <WebCore/Frame.h>
38 #include <WebCore/FrameView.h>
39 #include <WebCore/KeyboardEvent.h>
40 #include <WebCore/Page.h>
41 #include <WebCore/PlatformKeyboardEvent.h>
42 #include <WebCore/RenderThemeEfl.h>
43 #include <WebCore/Settings.h>
44
45 #if OS(TIZEN)
46 #include "Arguments.h"
47 #include "GraphicsContext.h"
48 #include "WebCoreArgumentCoders.h"
49 #include "WebFrame.h"
50 #include "WebImage.h"
51 #include "WebPageProxyMessages.h"
52 #include <WebCore/FrameView.h>
53
54 #if ENABLE(TIZEN_INPUT_TAG_EXTENSION)
55 #include <WebCore/HTMLInputElement.h>
56 #include <WebCore/HTMLNames.h>
57 #endif
58
59 #if ENABLE(TIZEN_MULTIPLE_SELECT)
60 #include "WebPopupMenu.h"
61 #include <WebCore/PopupMenuClient.h>
62 #endif
63
64 #if ENABLE(TIZEN_MOBILE_WEB_PRINT)
65 #include <WebCore/PlatformContextCairo.h>
66 #endif
67
68 #if ENABLE(TIZEN_CLIPBOARD) || ENABLE(TIZEN_PASTEBOARD)
69 #include <WebCore/ClipboardEfl.h>
70 #endif
71
72 #if ENABLE(TIZEN_PASTEBOARD)
73 #include <WebCore/Pasteboard.h>
74 #endif
75
76 #if ENABLE(TIZEN_WEBKIT2_REMOTE_WEB_INSPECTOR)
77 #include "WebInspectorServerEfl.h"
78 #endif
79
80 #if ENABLE(TIZEN_WEB_STORAGE)
81 #include <WebCore/GroupSettings.h>
82 #include <WebCore/PageGroup.h>
83 #endif
84
85 #if ENABLE(TIZEN_PLUGIN_SUSPEND_RESUME)
86 #include "PluginView.h"
87 #endif
88
89 #if ENABLE(TIZEN_PREFERENCE)
90 #include "WebPreferencesStore.h"
91 #include <WebCore/Settings.h>
92 #endif
93
94 #if ENABLE(TIZEN_WEBKIT2_FOCUS_RING)
95 #include <WebCore/HTMLFrameOwnerElement.h>
96 #include <WebCore/HTMLImageElement.h>
97 #endif
98
99 #if ENABLE(TIZEN_DEVICE_ORIENTATION)
100 #include "DeviceMotionClientTizen.h"
101 #include "DeviceOrientationClientTizen.h"
102 #endif
103
104 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION_ON_UI_SIDE)
105 #include "RenderLayer.h"
106 #include "WebGraphicsLayer.h"
107 #include <WebCore/RenderView.h>
108 #endif
109
110 #if ENABLE(TIZEN_ISF_PORT)
111 #include "WebEditorClient.h"
112 #include <WebCore/Text.h>
113 #endif
114
115 #if ENABLE(TIZEN_DATALIST_ELEMENT)
116 #include "HTMLCollection.h"
117 #include "HTMLDataListElement.h"
118 #include "HTMLOptionElement.h"
119 #endif
120
121 #if ENABLE(TIZEN_STYLE_SCOPED)
122 #include <WebCore/RuntimeEnabledFeatures.h>
123 #endif
124
125 #if ENABLE(TIZEN_WEBKIT2_TEXT_SELECTION)
126 #include "htmlediting.h"
127 #endif
128 #endif // #if OS(TIZEN)
129
130 using namespace WebCore;
131
132 namespace WebKit {
133
134 void WebPage::platformInitialize()
135 {
136 #if ENABLE(TIZEN_DEVICE_ORIENTATION)
137     WebCore::provideDeviceMotionTo(m_page.get(), new DeviceMotionClientTizen);
138     WebCore::provideDeviceOrientationTo(m_page.get(), new DeviceOrientationClientTizen);
139 #endif
140 }
141
142 #if ENABLE(TIZEN_PREFERENCE)
143 void WebPage::platformPreferencesDidChange(const WebPreferencesStore& store)
144 {
145     Settings* settings = m_page->settings();
146     settings->setInteractiveFormValidationEnabled(store.getBoolValueForKey(WebPreferencesKey::interactiveFormValidationEnabledKey()));
147     settings->setViewWidth(store.getUInt32ValueForKey(WebPreferencesKey::viewWidthKey()));
148     settings->setViewHeight(store.getUInt32ValueForKey(WebPreferencesKey::viewHeightKey()));
149     settings->setUsesEncodingDetector(store.getBoolValueForKey(WebPreferencesKey::usesEncodingDetectorKey()));
150 #if ENABLE(TIZEN_LOAD_REMOTE_IMAGES)
151     settings->setLoadRemoteImages(store.getBoolValueForKey(WebPreferencesKey::loadRemoteImagesKey()));
152 #endif
153 #if ENABLE(TIZEN_ISF_PORT)
154     settings->setEnableDefaultKeypad(store.getBoolValueForKey(WebPreferencesKey::defaultKeypadEnabledKey()));
155 #endif
156 #if ENABLE(TIZEN_STYLE_SCOPED)
157     WebCore::RuntimeEnabledFeatures::setStyleScopedEnabled(store.getBoolValueForKey(WebPreferencesKey::styleScopedEnabledKey()));
158 #endif
159 #if ENABLE(TIZEN_WEB_AUDIO)
160     settings->setWebAudioEnabled(true);
161 #endif
162 }
163 #else
164 void WebPage::platformPreferencesDidChange(const WebPreferencesStore&)
165 {
166     notImplemented();
167 }
168 #endif // #if ENABLE(TIZEN_PREFERENCE)
169
170 static inline void scroll(Page* page, ScrollDirection direction, ScrollGranularity granularity)
171 {
172     page->focusController()->focusedOrMainFrame()->eventHandler()->scrollRecursively(direction, granularity);
173 }
174
175 bool WebPage::performDefaultBehaviorForKeyEvent(const WebKeyboardEvent& keyboardEvent)
176 {
177     notImplemented();
178     return false;
179 }
180
181 bool WebPage::platformHasLocalDataForURL(const KURL&)
182 {
183     notImplemented();
184     return false;
185 }
186
187 String WebPage::cachedResponseMIMETypeForURL(const KURL&)
188 {
189     notImplemented();
190     return String();
191 }
192
193 bool WebPage::platformCanHandleRequest(const ResourceRequest&)
194 {
195     notImplemented();
196     return true;
197 }
198
199 String WebPage::cachedSuggestedFilenameForURL(const KURL&)
200 {
201     notImplemented();
202     return String();
203 }
204
205 PassRefPtr<SharedBuffer> WebPage::cachedResponseDataForURL(const KURL&)
206 {
207     notImplemented();
208     return 0;
209 }
210
211 const char* WebPage::interpretKeyEvent(const KeyboardEvent* event)
212 {
213     ASSERT(event->type() == eventNames().keydownEvent || event->type() == eventNames().keypressEvent);
214
215     if (event->type() == eventNames().keydownEvent)
216         return getKeyDownCommandName(event);
217
218     return getKeyPressCommandName(event);
219 }
220
221 void WebPage::setThemePath(const String& themePath)
222 {
223     WebCore::RenderThemeEfl* theme = static_cast<WebCore::RenderThemeEfl*>(m_page->theme());
224     theme->setThemePath(themePath);
225 }
226
227 #if OS(TIZEN)
228
229 #if ENABLE(TIZEN_WEBKIT2_TILED_BACKING_STORE)
230 IntSize WebPage::contentsSize() const
231 {
232     FrameView* frameView = m_page->mainFrame()->view();
233     if (!frameView)
234         return IntSize(0, 0);
235
236     return frameView->contentsSize();
237 }
238 #endif
239
240 void WebPage::scrollMainFrameBy(const IntSize& scrollOffset)
241 {
242     m_page->mainFrame()->view()->scrollBy(scrollOffset);
243 }
244
245 void WebPage::scrollMainFrameTo(const IntPoint& scrollPosition)
246 {
247     m_page->mainFrame()->view()->setScrollPosition(scrollPosition);
248 }
249
250 void WebPage::createSnapshot(const IntRect rect, float scaleFactor, ShareableBitmap::Handle& snapshotHandle)
251 {
252     FrameView* frameView = m_mainFrame->coreFrame()->view();
253     if (!frameView)
254         return;
255
256     RefPtr<WebImage> snapshotImage = scaledSnapshotInViewCoordinates(rect, scaleFactor, ImageOptionsShareable);
257     if (!snapshotImage || !snapshotImage->bitmap())
258         return;
259
260     snapshotImage->bitmap()->createHandle(snapshotHandle);
261 }
262
263 void WebPage::requestUpdateFormNavigation()
264 {
265     Frame* frame = m_page->focusController()->focusedOrMainFrame();
266     if (!frame)
267         return;
268
269     Document* document = frame->document();
270     if (!document)
271         return;
272
273     Node* focusedNode = document->focusedNode();
274
275     Vector<RefPtr<Node> > focusableNodes;
276     document->getFocusableNodes(focusableNodes);
277
278     int formElementCount = 0;
279     int currentNodeIndex = -1;
280     const Vector<RefPtr<Node> >::iterator end = focusableNodes.end();
281     for (Vector<RefPtr<Node> >::iterator it = focusableNodes.begin(); it != end; ++it) {
282         AtomicString nodeName = (*it).get()->nodeName();
283         if (equalIgnoringCase(nodeName, "SELECT")
284             || (equalIgnoringCase(nodeName, "INPUT")
285                 && !equalIgnoringCase((*it).get()->toInputElement()->type(), "CHECKBOX")
286                 && !equalIgnoringCase((*it).get()->toInputElement()->type(), "RADIO")
287                 && !equalIgnoringCase((*it).get()->toInputElement()->type(), "SUBMIT")
288                 )
289             ) {
290             if ((*it).get() == focusedNode)
291                 currentNodeIndex = formElementCount;
292             formElementCount++;
293         }
294     }
295
296     if (currentNodeIndex == -1)
297         return;
298
299     send(Messages::WebPageProxy::UpdateFormNavigation(formElementCount, currentNodeIndex));
300 }
301
302 void WebPage::moveFocus(int newIndex)
303 {
304     Frame* frame = m_page->focusController()->focusedOrMainFrame();
305     if (!frame)
306         return;
307
308     Document* document = frame->document();
309     if (!document)
310         return;
311
312     Vector<RefPtr<Node> > focusableNodes;
313     document->getFocusableNodes(focusableNodes);
314
315     int index = 0;
316     const Vector<RefPtr<Node> >::iterator end = focusableNodes.end();
317     for (Vector<RefPtr<Node> >::iterator it = focusableNodes.begin(); it != end; ++it) {
318         AtomicString nodeName = (*it).get()->nodeName();
319         if (equalIgnoringCase(nodeName, "SELECT")) {
320             if (index == newIndex) {
321                 (*it).get()->setFocus();
322                 LayoutPoint position = LayoutPoint(0, 0);
323                 PlatformMouseEvent event(flooredIntPoint(position), flooredIntPoint(position), LeftButton, PlatformEvent::MouseMoved, 1, false, false, false, false, 0);
324                 (*it).get()->dispatchMouseEvent(event, "mousedown", 0, 0);
325             }
326             index++;
327         } else if (equalIgnoringCase(nodeName, "INPUT")
328             && !equalIgnoringCase((*it).get()->toInputElement()->type(), "CHECKBOX")
329             && !equalIgnoringCase((*it).get()->toInputElement()->type(), "RADIO")
330             ) {
331             if (index == newIndex) {
332                 HTMLInputElement* elem = (*it).get()->toInputElement();
333                 elem->focus();
334             }
335             index++;
336         }
337     }
338 }
339
340 #if ENABLE(TIZEN_MOBILE_WEB_PRINT)
341 #define INCH_TO_MM 25.4
342 #define INCH_TO_POINTS 72.0
343
344 void WebPage::createPagesToPDF(const IntSize& surfaceSize, const IntSize& contentsSize, const String& fileName)
345 {
346     FrameView* frameView = m_mainFrame->coreFrame()->view();
347     if (!frameView)
348         return;
349
350     RefPtr<WebImage> pageshotImage = WebImage::create(contentsSize, ImageOptionsShareable);
351     if (!pageshotImage->bitmap())
352         return;
353
354     double pdfWidth = (double)surfaceSize.width() / INCH_TO_MM * INCH_TO_POINTS;
355     double pdfHeight = (double)surfaceSize.height() / INCH_TO_MM * INCH_TO_POINTS;
356     double scaleFactorPdf = 1.0;
357     if (contentsSize.width() > pdfWidth)
358         scaleFactorPdf = pdfWidth / (double)contentsSize.width();
359
360     OwnPtr<WebCore::GraphicsContext> graphicsContext = pageshotImage->bitmap()->createGraphicsContextForPdfSurface(fileName, pdfWidth, pdfHeight);
361     graphicsContext->scale(FloatSize(scaleFactorPdf, scaleFactorPdf));
362
363     frameView->updateLayoutAndStyleIfNeededRecursive();
364
365     int pageNumber = ((contentsSize.height() * scaleFactorPdf) / pdfHeight) + 1;
366     float paintY = 0.0;
367
368     PaintBehavior oldBehavior = frameView->paintBehavior();
369     frameView->setPaintBehavior(oldBehavior | PaintBehaviorFlattenCompositingLayers);
370     for (int i = 0; i < pageNumber; i++) {
371         IntRect paintRect(0, (int)paintY, contentsSize.width(), (int)(pdfHeight / scaleFactorPdf));
372
373         frameView->paint(graphicsContext.get(), paintRect);
374         cairo_show_page(graphicsContext->platformContext()->cr());
375         graphicsContext->translate(0, -ceil(pdfHeight / scaleFactorPdf));
376         paintY += (pdfHeight / scaleFactorPdf);
377     }
378     frameView->setPaintBehavior(oldBehavior);
379
380     pageshotImage.release();
381 }
382 #endif
383
384 void WebPage::confirmComposition(const String& compositionString)
385 {
386     Frame* frame = m_page->focusController()->focusedOrMainFrame();
387     if (!frame || !frame->editor()->canEdit())
388         return;
389     frame->editor()->confirmComposition(compositionString);
390 #if ENABLE(TIZEN_ISF_PORT)
391     send(Messages::WebPageProxy::UpdateCursorPosition());
392 #endif
393 }
394
395 void WebPage::setComposition(const String& compositionString, const Vector<WebCore::CompositionUnderline>& underlines, uint64_t cursorPosition)
396 {
397     Frame* frame = m_page->focusController()->focusedOrMainFrame();
398     if (!frame || !frame->editor()->canEdit())
399         return;
400 #if ENABLE(TIZEN_ISF_PORT)
401     if (frame->selection()->rootEditableElement()) {
402         HTMLTextFormControlElement* textFormControl = toTextFormControl(frame->selection()->rootEditableElement()->shadowAncestorNode());
403         if (textFormControl && textFormControl->maxLength() >= 0) {
404             unsigned availableLength = textFormControl->maxLength() - textFormControl->value().length();
405             if (frame->editor()->hasComposition())
406                 availableLength += (frame->editor()->compositionEnd() - frame->editor()->compositionStart());
407             if (!availableLength)
408                 return;
409
410             if (availableLength < compositionString.length()) {
411                 String newCompositionString = compositionString.substring(0, availableLength);
412                 Vector<CompositionUnderline> newUnderlines;
413                 size_t numUnderlines = underlines.size();
414                 for (size_t index = 0; index < numUnderlines; ++index) {
415                     if (underlines[index].startOffset < availableLength) {
416                         newUnderlines.append(underlines[index]);
417                         if (newUnderlines.last().endOffset > availableLength)
418                             newUnderlines.last().endOffset = availableLength;
419                     }
420                 }
421                 frame->editor()->setComposition(newCompositionString, newUnderlines, cursorPosition, 0);
422                 return;
423             }
424         }
425     }
426 #endif
427     frame->editor()->setComposition(compositionString, underlines, cursorPosition, 0);
428 }
429
430 #if ENABLE(TIZEN_TEXT_CARET_HANDLING_WK2)
431 bool WebPage::setCaretPosition(const WebCore::IntPoint& pos)
432 {
433     Frame* frame = m_page->focusController()->focusedOrMainFrame();
434     if (!frame)
435         return false;
436
437     WebCore::FrameSelection* controller = frame->selection();
438     if (!controller)
439         return false;
440
441     FrameView* frameView = frame->view();
442     if (!frameView)
443         return false;
444
445     WebCore::IntPoint point = m_page->mainFrame()->view()->windowToContents(pos);
446     WebCore::HitTestResult result = m_page->mainFrame()->eventHandler()->hitTestResultAtPoint(point, /*allowShadowContent*/ true, /*ignoreClipping*/ true);
447     if (result.scrollbar())
448         return false;
449
450     WebCore::Node* innerNode = result.innerNode();
451
452     if (!innerNode || !innerNode->renderer())
453         return false;
454
455     WebCore::VisiblePosition visiblePos;
456
457     const int boundariesWidth = 2;
458
459     // we check if content is richly editable - because those input field behave other than plain text ones
460     // sometimes they may consists a node structure and they need special approach
461     if (innerNode->rendererIsRichlyEditable()) {
462         // point gets inner node local coordinates
463         point = flooredIntPoint(result.localPoint());
464         WebCore::IntRect rect = innerNode->renderer()->absoluteBoundingBoxRect(true);
465
466         // it is not the best way to do this, but it is not as slow and it works - so maybe in the future someone
467         // will have a better idea how to solve it
468         // here we are getting innerNode from HitTestResult - unfortunately this is a kind of high level node
469         // in the code below I am trying to obtain low level node - #text - to get its coordinates and size
470
471         // all those getting nodes rects are needed to bypass WebCore's methods of positioning caret when user
472         // is clicking outside a node - and cheat WebCore telling it that actually we clicked into input field
473         // node, not outside of it
474         WebCore::Node* deepInnerNode = innerNode->renderer()->positionForPoint(point).deepEquivalent().deprecatedNode();
475
476         if (!deepInnerNode || !deepInnerNode->renderer())
477             return false;
478
479         // so we get a base node rectange
480         WebCore::IntRect deepNodeRect = deepInnerNode->renderer()->absoluteBoundingBoxRect(true);
481
482         // we modify our local point to adjust it to base node local coordinates
483         point.move(rect.x() - deepNodeRect.x(), rect.y() - deepNodeRect.y());
484
485         // if we are outside the rect we cheat, that we are just inside of it
486         if (point.y() < 0)
487             point.setY(0);
488         else if (point.y() >= deepNodeRect.height())
489             point.setY(deepNodeRect.height() - 1);
490
491         // visible position created - caret ready to set
492         visiblePos = deepInnerNode->renderer()->positionForPoint(point);
493         if (visiblePos.isNull())
494             return false;
495     } else {
496         // for plain text input fields we can get only a caret bounding box
497         if (!controller->isCaret() || !controller->caretRenderer())
498             return false;
499
500         const WebCore::Node* node = controller->start().deprecatedNode();
501         if (!node || !node->renderer())
502             return false;
503
504         WebCore::IntRect rect = controller->caretRenderer()->absoluteBoundingBoxRect(true);
505
506 // FIXME: The below codes should be updated to apply the positon of focusedFrame.
507 #if 0
508         // here we also cheat input field that we actually are just inside of if
509         if (point.x() < rect.x())
510             point.setX(rect.x());
511         else if (point.x() > rect.maxX())
512             point.setX(rect.maxX());
513         if (point.y() < rect.y() + boundariesWidth)
514             point.setY(rect.y() + boundariesWidth);
515         else if (point.y() >= rect.maxY() - boundariesWidth)
516             point.setY(rect.maxY() - boundariesWidth - 1);
517 #endif
518
519         // hit test with fake (adjusted) coordinates
520         WebCore::IntPoint hitTestPoint = m_page->mainFrame()->view()->windowToContents(point);
521         WebCore::HitTestResult newResult = m_page->mainFrame()->eventHandler()->hitTestResultAtPoint(hitTestPoint, /*allowShadowContent*/ true, /*ignoreClipping*/ true);
522
523         if (!newResult.isContentEditable())
524             return false;
525
526         WebCore::Node* newInnerNode = newResult.innerNode();
527
528         if (!newInnerNode || !newInnerNode->renderer())
529             return false;
530
531         // visible position created
532         visiblePos = newInnerNode->renderer()->positionForPoint(newResult.localPoint());
533         if (visiblePos.isNull())
534             return false;
535     }
536
537     // create visible selection from visible position
538     WebCore::VisibleSelection newSelection = WebCore::VisibleSelection(visiblePos);
539     controller->setSelection(newSelection, WebCore::CharacterGranularity);
540     // after setting selection caret blinking is suspended by default so we are unsuspedning it
541     controller->setCaretBlinkingSuspended(false);
542
543     return true;
544 }
545
546 void WebPage::getCaretPosition(WebCore::IntRect& rect)
547 {
548     Frame* frame = m_page->focusController()->focusedOrMainFrame();
549     if (!frame)
550         return;
551
552     WebCore::FrameSelection* controller = frame->selection();
553     if (!controller)
554         return;
555
556     WebCore::Node* node = controller->start().deprecatedNode();
557     if (!node || !node->renderer() || !node->isContentEditable())
558         return;
559
560     if (controller->isCaret()) {
561         FrameView* frameView = frame->view();
562         if (!frameView)
563             return;
564
565         rect = frameView->contentsToWindow(controller->absoluteCaretBounds());
566     }
567 }
568 #endif
569
570 #if ENABLE(TIZEN_ISF_PORT)
571 void WebPage::getCursorOffsetPosition(int& offset)
572 {
573     offset = 0;
574     Frame* frame = m_page->focusController()->focusedOrMainFrame();
575     if (!frame || !frame->editor()->canEdit())
576         return;
577
578     Position base = frame->selection()->base();
579     Node* baseNode = base.containerNode();
580     if (baseNode)
581         offset = baseNode->isTextNode() ? base.offsetInContainerNode() : 0;
582 }
583
584 void WebPage::getContentOfPosition(String& content)
585 {
586     Frame* frame = m_page->focusController()->focusedOrMainFrame();
587     if (!frame || !frame->editor()->canEdit())
588         return;
589
590     Position base = frame->selection()->base();
591     Node* baseNode = base.containerNode();
592     if (baseNode && baseNode->isTextNode())
593         content = baseNode->textContent();
594     else
595         content = String();
596 }
597
598 void WebPage::deleteSurroundingPosition(bool& result)
599 {
600     Frame* frame = m_page->focusController()->focusedOrMainFrame();
601     if (!frame || !frame->editor()->canEdit())
602         return;
603
604     frame->editor()->deleteWithDirection(DirectionBackward, CharacterGranularity, false, true);
605 }
606
607 void WebPage::getSelectionRect(bool isOnlyEditable, IntRect& rect)
608 {
609     rect = IntRect();
610
611     Frame* frame = m_page->focusController()->focusedFrame();
612     if (!frame || !frame->view())
613         return;
614
615     FrameSelection* selection = frame->selection();
616     Node* node = selection->start().deprecatedNode();
617     if (!node || !node->renderer() || (isOnlyEditable && !node->isContentEditable()))
618         return;
619
620     if (selection->isCaret())
621         rect = frame->view()->contentsToWindow(selection->absoluteCaretBounds());
622     else if (selection->isRange())
623         rect = frame->view()->contentsToWindow(enclosingIntRect(selection->bounds()));
624 }
625 #endif
626
627 #if ENABLE(TIZEN_INPUT_TAG_EXTENSION)
628 void WebPage::setFocusedInputElementValue(const String& inputValue)
629 {
630     Frame* frame = m_page->focusController()->focusedOrMainFrame();
631     if (!frame || !frame->document() || !frame->document()->focusedNode())
632         return;
633
634     HTMLInputElement* inputElement = frame->document()->focusedNode()->toInputElement();
635     if (!inputElement)
636         return;
637
638     inputElement->toNode()->dispatchFocusEvent(0);
639     inputElement->setValue(inputValue, DispatchChangeEvent);
640 }
641
642 void  WebPage::getFocusedInputElementValue(String& inputValue)
643 {
644     inputValue = String();
645
646     Frame* frame = m_page->focusController()->focusedOrMainFrame();
647     if (!frame || !frame->document() || !frame->document()->focusedNode())
648         return;
649
650     HTMLInputElement* inputElement = frame->document()->focusedNode()->toInputElement();
651     if (!inputElement)
652         return;
653
654     inputValue = inputElement->value();
655 }
656 #endif
657
658 #if ENABLE(TIZEN_DATALIST_ELEMENT)
659 void WebPage::getFocusedInputElementDataList(Vector<String>& optionList)
660 {
661     Frame* frame = m_page->focusController()->focusedOrMainFrame();
662     if (!frame || !frame->document())
663         return;
664
665     Node* node = frame->document()->focusedNode();
666     if (!node)
667         return;
668
669     HTMLInputElement* input = node->toInputElement();
670     if (!input)
671         return;
672
673     HTMLDataListElement* dataList = static_cast<HTMLDataListElement*>(input->list());
674     if (!dataList)
675         return;
676
677     RefPtr<HTMLCollection> options = static_cast<HTMLDataListElement*>(dataList)->options();
678     for (unsigned i = 0; Node* node = options->item(i); i++) {
679         HTMLOptionElement* optionElement = static_cast<HTMLOptionElement*>(node);
680         String value = optionElement->value();
681         optionList.append(value);
682     }
683 }
684 #endif
685
686 #if ENABLE(TIZEN_WEBKIT2_HIT_TEST)
687 #if ENABLE(TIZEN_WEBKIT2_FOCUS_RING)
688 static IntRect getFocusedRect(HitTestResult hitTestResult, Page* page)
689 {
690     IntRect focusedRect = IntRect(0, 0, 0, 0);
691     Node* node = hitTestResult.innerNode();
692     bool isFocusRingDrawable = false;
693     Node* focusableNode = node;
694     while (focusableNode) {
695         RenderObject* renderer = focusableNode->renderer();
696         if (renderer && renderer->isRoot())
697             break;
698
699         if (focusableNode->isFocusable()) {
700             if (focusableNode->isLink()
701                 || focusableNode->hasTagName(HTMLNames::inputTag)
702                 || focusableNode->hasTagName(HTMLNames::selectTag)
703                 || focusableNode->hasTagName(HTMLNames::buttonTag))
704                 isFocusRingDrawable = true;
705             break;
706         }
707
708         focusableNode = focusableNode->parentNode();
709     }
710
711     if (!isFocusRingDrawable)
712         return focusedRect;
713
714     if (!hitTestResult.absoluteImageURL().isEmpty()) {
715         bool isReplaced;
716         IntRect imageNodeRect = pixelSnappedIntRect(node->getRect());
717         if (!focusableNode->renderRect(&isReplaced).isEmpty() && imageNodeRect.contains(pixelSnappedIntRect(focusableNode->getRect()))) {
718             // If render rect of focusableNode is empty and rect of imageNode include rect of focusableNode,
719             // we have to get rect of focusableNode.
720             // for example - The rect of google logo image in www.google.com pc site's search result page is bigger than rect of focusableNode.
721             // for example - The rect of category menu image in www.gmarket.co.kr pc site is bigger than rect of focusableNode.
722             focusedRect = pixelSnappedIntRect(focusableNode->getRect());
723         }
724         else {
725             // otherwise we have to get rect of imageNode.
726             // for example - The render rect of images in www.pudelek.pl is empty.
727             // 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.
728             focusedRect = imageNodeRect;
729             focusableNode = node;
730         }
731     } else {
732         // If focusedNode have multiple child nodes, we have to unite rect of child nodes.
733         // for example - links in www.google.com's search result page.
734         IntRect tempRect = IntRect(0, 0, 0, 0);
735         for (Node* childNode = focusableNode->firstChild(); childNode; childNode = childNode->traverseNextNode(focusableNode)) {
736             bool isReplaced;
737             if (focusableNode->renderRect(&isReplaced).contains(childNode->getRect()))
738                 tempRect.unite(pixelSnappedIntRect(childNode->getRect()));
739         }
740
741         // If tempRect is empty or rect of focusableNode include tempRect,
742         // we have to get rect of focusableNode.
743         // for example - list menu item in m.naver.com.
744         // otherwise we have to get rect of tempRect.
745         // getRect API do not return correct rect if the node is a container node,
746         // hence using absoluteBoundingBoxRect to get the correct bounding rect.
747         LayoutRect renderRect = focusableNode->renderer() ? focusableNode->renderer()->absoluteBoundingBoxRect() : focusableNode->getRect();
748         if (tempRect.isEmpty() || renderRect.contains(tempRect))
749             focusedRect = pixelSnappedIntRect(renderRect);
750         else
751             focusedRect = tempRect;
752     }
753
754     // We have to get render rect from ancestor node if current focusedRect is empty.
755     // for example - The rect of naver logo image in www.naver.com pc site is empty.
756     bool isReplaced;
757     for (Node* loopNode = focusableNode; loopNode && focusedRect.isEmpty(); loopNode = loopNode->parentNode()) {
758         RenderObject* renderer = loopNode->renderer();
759         if (renderer && renderer->isRoot())
760             break;
761
762         focusedRect = pixelSnappedIntRect(loopNode->renderRect(&isReplaced));
763     }
764
765     Frame* mainFrame = page->mainFrame();
766     Frame* nodeFrame = focusableNode->document()->frame();
767     Node* owner;
768     while (nodeFrame && nodeFrame != mainFrame) {
769         owner = nodeFrame->ownerElement();
770         if (!owner)
771             break;
772
773         focusedRect.setX(focusedRect.x() + owner->getRect().x());
774         focusedRect.setY(focusedRect.y() + owner->getRect().y());
775         nodeFrame = owner->document()->frame();
776     }
777
778     // The y position of tab menu item in www.google.com is negative value,
779     // so we do not want to draw focus ring in that case.
780     if ((focusedRect.x() < 0) || (focusedRect.y() < 0))
781         focusedRect = IntRect(0, 0, 0, 0);
782
783     return focusedRect;
784 }
785 #endif
786
787 void WebPage::hitTestResultAtPoint(const IntPoint& point, int hitTestMode, WebHitTestResult::Data& hitTestResultData)
788 {
789     Frame* frame = m_page->mainFrame();
790     FrameView* frameView = frame->view();
791     if (!frameView)
792         return;
793
794     HitTestResult hitTestResult = frame->eventHandler()->hitTestResultAtPoint(frameView->windowToContents(point), false);
795     hitTestResultData.absoluteImageURL = hitTestResult.absoluteImageURL().string();
796     hitTestResultData.absoluteLinkURL = hitTestResult.absoluteLinkURL().string();
797     hitTestResultData.absoluteMediaURL = hitTestResult.absoluteMediaURL().string();
798     hitTestResultData.linkLabel = hitTestResult.textContent();
799     hitTestResultData.linkTitle = hitTestResult.titleDisplayString();
800 #if ENABLE(TIZEN_DRAG_SUPPORT)
801     hitTestResultData.isDragSupport = hitTestResult.isDragSupport();
802 #endif
803
804     int context = WebHitTestResult::HitTestResultContextDocument;
805
806     if (!hitTestResult.absoluteLinkURL().isEmpty())
807         context |= WebHitTestResult::HitTestResultContextLink;
808     if (!hitTestResult.absoluteImageURL().isEmpty())
809         context |= WebHitTestResult::HitTestResultContextImage;
810     if (!hitTestResult.absoluteMediaURL().isEmpty())
811         context |= WebHitTestResult::HitTestResultContextMedia;
812     if (hitTestResult.isSelected())
813         context |= WebHitTestResult::HitTestResultContextSelection;
814     if (hitTestResult.isContentEditable())
815         context |= WebHitTestResult::HitTestResultContextEditable;
816     if (hitTestResult.innerNonSharedNode() && hitTestResult.innerNonSharedNode()->isTextNode())
817         context |= WebHitTestResult::HitTestResultContextText;
818
819     hitTestResultData.context = context;
820     hitTestResultData.hitTestMode = hitTestMode;
821
822 #if ENABLE(TIZEN_WEBKIT2_FOCUS_RING)
823     hitTestResultData.focusedRect = getFocusedRect(hitTestResult, m_page.get());
824     if (hitTestResult.innerNode() && hitTestResult.innerNode()->renderer() && hitTestResult.innerNode()->renderer()->style()) {
825         hitTestResultData.focusedColor = hitTestResult.innerNode()->renderer()->style()->tapHighlightColor();
826         if (!hitTestResultData.focusedColor.hasAlpha())
827             hitTestResultData.focusedColor = Color(hitTestResultData.focusedColor.red(), hitTestResultData.focusedColor.green(), hitTestResultData.focusedColor.blue(), RenderStyle::initialTapHighlightColor().alpha());
828     }
829 #endif
830
831     if (hitTestResultData.hitTestMode & WebHitTestResult::HitTestModeNodeData) {
832         WebCore::Node* hitNode = hitTestResult.innerNonSharedNode();
833         if (hitNode) {
834             hitTestResultData.nodeData.nodeValue = hitNode->nodeValue();
835
836             if ((hitTestResultData.context & WebHitTestResult::HitTestResultContextText) && hitNode->parentNode())
837                 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.
838
839             if (hitNode->isElementNode()) {
840                 WebCore::Element* hitElement = static_cast<WebCore::Element*>(hitNode);
841                 if (hitElement) {
842                     hitTestResultData.nodeData.tagName = hitElement->tagName();
843                 }
844             }
845
846             WebCore::NamedNodeMap* namedNodeMap = hitNode->attributes();
847             if (namedNodeMap) {
848                 for (size_t i = 0; i < namedNodeMap->length(); i++) {
849                     const WebCore::Attribute* attribute = namedNodeMap->element()->attributeItem(i);
850                     String key = attribute->name().toString();
851                     String value = attribute->value();
852                     hitTestResultData.nodeData.attributeMap.add(key, value);
853                 }
854             }
855         }
856     }
857
858     if ((hitTestResultData.hitTestMode & WebHitTestResult::HitTestModeImageData) && (hitTestResultData.context & WebHitTestResult::HitTestResultContextImage)) {
859         WebCore::Image* hitImage = hitTestResult.image();
860         if (hitImage && hitImage->data() && hitImage->data()->data()) {
861             hitTestResultData.imageData.data.append(hitImage->data()->data(), hitImage->data()->size());
862             hitTestResultData.imageData.fileNameExtension = hitImage->filenameExtension();
863         }
864     }
865 }
866 #endif
867
868 #if ENABLE(TIZEN_WEB_STORAGE)
869 void WebPage::getStorageQuotaBytes(uint64_t callbackID)
870 {
871     uint32_t quota = m_page->group().groupSettings()->localStorageQuotaBytes();
872     send(Messages::WebPageProxy::DidGetWebStorageQuotaBytes(quota, callbackID));
873 }
874
875 void WebPage::setStorageQuotaBytes(uint32_t quota)
876 {
877     m_page->group().groupSettings()->setLocalStorageQuotaBytes(quota);
878 }
879 #endif
880
881 #if ENABLE(TIZEN_RECORDING_SURFACE_SET)
882 void WebPage::recordingSurfaceSetEnableSet(bool enable)
883 {
884     m_recordingSurfaceSetSettings = enable;
885 }
886 #endif
887
888 #if ENABLE(TIZEN_CLIPBOARD) || ENABLE(TIZEN_PASTEBOARD)
889 void WebPage::setClipboardDataForPaste(const String& data, const String& type)
890 {
891 #if ENABLE(TIZEN_PASTEBOARD)
892     // FIXME: Should move to EditorClient like Clipboard
893     Pasteboard::generalPasteboard()->setDataWithType(data, type);
894 #else
895     Frame* mainFrame = m_page->mainFrame();
896     if (!mainFrame)
897         return;
898
899     mainFrame->editor()->client()->setClipboardDataForPaste(data, type);
900 #endif
901 }
902 #endif
903
904 void WebPage::suspendJavaScriptAndResources()
905 {
906     Frame* mainFrame = m_page->mainFrame();
907     if (!mainFrame)
908         return;
909
910     for (Frame* frame = mainFrame; frame; frame = frame->tree()->traverseNext())
911         frame->document()->suspendScheduledTasks(WebCore::ActiveDOMObject::PageWillBeSuspended);
912     mainFrame->loader()->suspendAllLoaders();
913 }
914
915 void WebPage::resumeJavaScriptAndResources()
916 {
917     Frame* mainFrame = m_page->mainFrame();
918     if (!mainFrame)
919         return;
920
921     for (Frame* frame = mainFrame; frame; frame = frame->tree()->traverseNext())
922         frame->document()->resumeScheduledTasks();
923     mainFrame->loader()->resumeAllLoaders();
924 }
925
926 #if ENABLE(TIZEN_SYNC_REQUEST_ANIMATION_FRAME)
927 void WebPage::suspendAnimationController()
928 {
929     if (!m_suspendedAnimationController) {
930         Frame* mainFrame = m_page->mainFrame();
931         if (!mainFrame)
932             return;
933
934         for (Frame* frame = mainFrame; frame; frame = frame->tree()->traverseNext())
935             frame->document()->suspendScriptedAnimationControllerCallbacks();
936
937         m_suspendedAnimationController = true;
938     }
939 }
940
941 void WebPage::resumeAnimationController()
942 {
943     if (m_suspendedAnimationController) {
944         Frame* mainFrame = m_page->mainFrame();
945         if (!mainFrame)
946             return;
947
948         for (Frame* frame = mainFrame; frame; frame = frame->tree()->traverseNext())
949             frame->document()->resumeScriptedAnimationControllerCallbacks();
950
951         m_suspendedAnimationController = false;
952     }
953 }
954 #endif
955
956 #if ENABLE(TIZEN_WEBKIT2_REMOTE_WEB_INSPECTOR)
957 void WebPage::startInspectorServer(uint32_t port,  uint32_t& allocatedPort)
958 {
959     bool ret = WebInspectorServerEfl::server()->startServer(port);
960     if (ret)
961         allocatedPort = WebInspectorServerEfl::server()->getServerPort();
962     else
963         allocatedPort = 0;
964 }
965
966 void WebPage::stopInspectorServer(bool& result)
967 {
968     result = WebInspectorServerEfl::server()->stopServer();
969 }
970 #endif
971
972 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION_ON_UI_SIDE)
973 void WebPage::scrollOverflowWithTrajectoryVector(const WebCore::FloatPoint& trajectoryVector)
974 {
975     Frame* frame = m_page->focusController()->focusedOrMainFrame();
976     if (!frame)
977         return;
978     frame->eventHandler()->scrollOverflow(trajectoryVector);
979 }
980 #endif
981
982 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION)
983 void WebPage::scrollOverflow(const WebCore::FloatPoint& delta, bool& scrolled)
984 {
985     scrolled = m_page->focusController()->focusedOrMainFrame()->eventHandler()->scrollOverflow(delta);
986 }
987
988 void WebPage::setPressedNodeAtPoint(const IntPoint& point, bool checkOverflowLayer, bool& pressed, uint32_t& id)
989 {
990     RenderObject* renderer = 0;
991     id = 0;
992     pressed = m_page->focusController()->focusedOrMainFrame()->eventHandler()->setMousePressNodeAtPoint(point, checkOverflowLayer, renderer);
993 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION_ON_UI_SIDE)
994     if (pressed && renderer)
995         id = toWebGraphicsLayer(renderer->enclosingLayer()->layerForScrollingContents())->id();
996 #endif
997 }
998 #endif
999
1000 void WebPage::executeEditCommandWithArgument(const String& commandName, const String& argument)
1001 {
1002     executeEditingCommand(commandName, argument);
1003 }
1004
1005 #if ENABLE(TIZEN_PLUGIN_SUSPEND_RESUME)
1006 void WebPage::suspendPlugin()
1007 {
1008     for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
1009         FrameView* view = frame->view();
1010         if (!view)
1011             continue;
1012
1013         const HashSet<RefPtr<Widget> >* children = view->children();
1014         ASSERT(children);
1015
1016         HashSet<RefPtr<Widget> >::const_iterator end = children->end();
1017         for (HashSet<RefPtr<Widget> >::const_iterator it = children->begin(); it != end; ++it) {
1018             Widget* widget = (*it).get();
1019             if (widget->isPluginViewBase()) {
1020                 PluginView* pluginView = static_cast<PluginView*>(widget);
1021                 if (pluginView)
1022                     pluginView->suspendPlugin();
1023             }
1024         }
1025     }
1026 }
1027
1028 void WebPage::resumePlugin()
1029 {
1030     for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
1031         FrameView* view = frame->view();
1032         if (!view)
1033             continue;
1034
1035         const HashSet<RefPtr<Widget> >* children = view->children();
1036         ASSERT(children);
1037
1038         HashSet<RefPtr<Widget> >::const_iterator end = children->end();
1039         for (HashSet<RefPtr<Widget> >::const_iterator it = children->begin(); it != end; ++it) {
1040             Widget* widget = (*it).get();
1041             if (widget->isPluginViewBase()) {
1042                 PluginView* pluginView = static_cast<PluginView*>(widget);
1043                 if (pluginView)
1044                     pluginView->resumePlugin();
1045             }
1046         }
1047     }
1048 }
1049 #endif
1050
1051 #if ENABLE(TIZEN_WEBKIT2_GET_TEXT_STYLE_FOR_SELECTION)
1052 void WebPage::getTextStyleStateForSelection()
1053 {
1054     Frame* frame = m_page->focusController()->focusedOrMainFrame();
1055
1056     int underlineState = frame->editor()->selectionHasStyle(CSSPropertyWebkitTextDecorationsInEffect, "underline");
1057     int italicState = frame->editor()->selectionHasStyle(CSSPropertyFontStyle, "italic");
1058     int boldState = frame->editor()->selectionHasStyle(CSSPropertyFontWeight, "bold");
1059
1060     send(Messages::WebPageProxy::DidGetTextStyleStateForSelection(underlineState, italicState, boldState));
1061 }
1062 #endif
1063
1064 #if ENABLE(TIZEN_MULTIPLE_SELECT)
1065 void WebPage::didChangeSelectedIndexForActivePopupMenuMultiple(Vector<int32_t> newIndex)
1066 {
1067     if (!m_activePopupMenu)
1068         return;
1069
1070     m_activePopupMenu->client()->popupDidHide();
1071
1072     size_t indexSize = newIndex.size();
1073     for (size_t i = 0; i < indexSize; i++)
1074         m_activePopupMenu->didChangeSelectedIndex(i);
1075
1076 #if !PLATFORM(EFL)
1077     m_activePopupMenu = 0;
1078 #endif
1079 }
1080 #endif
1081
1082 #if ENABLE(TIZEN_WEBKIT2_TEXT_SELECTION)
1083 void WebPage::selectClosestWord(const WebCore::IntPoint& point, bool isStartedTextSelectionFromOutside, bool& result)
1084 {
1085     result = false;
1086
1087     Frame* mainFrame = m_page->mainFrame();
1088     Frame* focusedFrame = m_page->focusController()->focusedOrMainFrame();
1089
1090     HitTestResult hitTestResult = mainFrame->eventHandler()->hitTestResultAtPoint(m_page->mainFrame()->view()->windowToContents(point), false);
1091
1092     if (hitTestResult.isContentEditable()) {
1093         result = setCaretPosition(point);
1094         return;
1095     }
1096
1097     if (hitTestResult.innerNonSharedNode() && hitTestResult.innerNonSharedNode()->isTextNode()) {
1098         if (!isStartedTextSelectionFromOutside) {
1099             for (Node* node = hitTestResult.innerNonSharedNode(); node; node = node->parentNode()) {
1100                 if (node->isFocusable()) {
1101                     // Text selection shoud not be started when text of <button> tag is selected.
1102                     if (node->hasTagName(HTMLNames::buttonTag))
1103                         return;
1104                     break;
1105                 }
1106             }
1107         }
1108
1109         WebCore::FrameSelection* frameSelection = focusedFrame->selection();
1110
1111         WebCore::VisiblePosition position = mainFrame->visiblePositionForPoint(point);
1112         WebCore::VisibleSelection selection(position);
1113
1114         // This changes just the 'start' and 'end' positions of the VisibleSelection
1115         selection.expandUsingGranularity(WebCore::WordGranularity);
1116
1117         frameSelection->setSelection(WebCore::VisibleSelection(selection.start(), selection.end()));
1118
1119         if (!frameSelection->isRange())
1120             return;
1121
1122         // This changes just the 'start' and 'end' positions of the VisibleSelection
1123         // Find handlers positions
1124         WebCore::IntRect leftRect, rightRect;
1125         getSelectionHandlers(leftRect, rightRect);
1126         if (leftRect.size().isZero() && rightRect.size().isZero()) {
1127             // Sometimes there is no selected text, but isNone() returns TRUE
1128             // in this case ewk_frame_selection_handlers_get() returns FALSE and handlers are invalid
1129             // Workaround - clear the selection.
1130             // Better solution would be to modify the ewk_frame_select_closest_word()
1131             // to not select anything in the first place (for example - don't call setSelection()
1132             // if there is nothing under the cursor).
1133             frameSelection->clear();
1134             return;
1135         }
1136
1137         result = true;
1138     }
1139 }
1140
1141 void WebPage::setLeftSelection(const WebCore::IntPoint& point, bool& result)
1142 {
1143     result = false;
1144
1145     Frame* focusedFrame = m_page->focusController()->focusedOrMainFrame();
1146     WebCore::FrameSelection* frameSelection = focusedFrame->selection();
1147     if (!frameSelection->isRange())
1148         return;
1149
1150     WebCore::Node* selectionEndNode = frameSelection->end().deprecatedNode();
1151     if (!selectionEndNode || !selectionEndNode->renderer())
1152         return;
1153
1154     FrameView* frameView = focusedFrame->view();
1155     if (!frameView)
1156         return;
1157
1158     WebCore::IntPoint pos = frameView->windowToContents(point);
1159     WebCore::IntRect leftRect, rightRect;
1160     getSelectionHandlers(leftRect, rightRect);
1161     if ((rightRect.y() + rightRect.height()) < pos.y())
1162         pos.setY(rightRect.y() + (rightRect.height()/2));
1163
1164     if (selectionEndNode->rendererIsEditable() && !selectionEndNode->rendererIsRichlyEditable()) {
1165         const int boundariesWidth = 2;
1166
1167         WebCore::IntRect rect = frameSelection->caretRenderer()->absoluteBoundingBoxRect(true);
1168         // here we cheat input field that we actually are just inside of if
1169         if (pos.y() < rect.y() + boundariesWidth)
1170             pos.setY(rect.y() + boundariesWidth);
1171         else if (pos.y() >= rect.maxY() - boundariesWidth)
1172             pos.setY(rect.maxY() - boundariesWidth - 1);
1173     }
1174
1175     OwnPtr<WebCore::VisiblePosition> position = adoptPtr(new WebCore::VisiblePosition(focusedFrame->visiblePositionForPoint(pos)));
1176     WebCore::Position extent = frameSelection->extent();
1177
1178     WebCore::Node* newSelectionStartNode = position->deepEquivalent().deprecatedNode();
1179
1180     // both start and end nodes should be in the same area type: both should be editable or both should be not editable
1181     // Check if the new position is before the extent's position
1182     if (newSelectionStartNode
1183         && selectionEndNode->isContentEditable() == newSelectionStartNode->isContentEditable()
1184         && WebCore::comparePositions(position->deepEquivalent(), extent) < 0) {
1185         // Change the 'base' and 'extent' positions to 'start' and 'end' positions.
1186         // We do it, because without this, the other modification of the selection
1187         // would destroy the 'start' and/or 'end' positions and set them to
1188         // the 'base'/'extent' positions accordingly
1189         WebCore::VisibleSelection sel(frameSelection->start(), frameSelection->end());
1190         frameSelection->setSelection(sel);
1191
1192         bool oldProhibitsScrolling = focusedFrame->view()->prohibitsScrolling();
1193         focusedFrame->view()->setProhibitsScrolling(true);
1194
1195         frameSelection->setBase(*position);
1196
1197         focusedFrame->view()->setProhibitsScrolling(oldProhibitsScrolling);
1198         // This forces webkit to show selection
1199         // m_coreFrame->invalidateSelection();
1200
1201         result = true;
1202     }
1203 }
1204
1205
1206 void WebPage::setRightSelection(const WebCore::IntPoint& point, bool& result)
1207 {
1208     result = false;
1209
1210     Frame* focusedFrame = m_page->focusController()->focusedOrMainFrame();
1211     WebCore::FrameSelection* frameSelection = focusedFrame->selection();
1212
1213     if (!frameSelection->isRange())
1214         return;
1215
1216     WebCore::Node* selectionStartNode = frameSelection->start().deprecatedNode();
1217     if (!selectionStartNode || !selectionStartNode->renderer())
1218         return;
1219
1220     FrameView* frameView = focusedFrame->view();
1221     if (!frameView)
1222         return;
1223
1224     WebCore::IntPoint pos = frameView->windowToContents(point);
1225     if (selectionStartNode->rendererIsEditable() && !selectionStartNode->rendererIsRichlyEditable()) {
1226         const int boundariesWidth = 2;
1227
1228         WebCore::IntRect rect = frameSelection->caretRenderer()->absoluteBoundingBoxRect(true);
1229         // here we cheat input field that we actually are just inside of if
1230         if (pos.y() < rect.y() + boundariesWidth)
1231             pos.setY(rect.y() + boundariesWidth);
1232         else if (pos.y() >= rect.maxY() - boundariesWidth)
1233             pos.setY(rect.maxY() - boundariesWidth - 1);
1234     }
1235
1236     OwnPtr<WebCore::VisiblePosition> position = adoptPtr(new WebCore::VisiblePosition(focusedFrame->visiblePositionForPoint(pos)));
1237     WebCore::Position base = frameSelection->base();
1238
1239     WebCore::Node* newSelectionEndNode = position->deepEquivalent().deprecatedNode();
1240
1241     // both start and end nodes should be in the same area type: both should be editable or both should be not editable
1242     // Check if the new position is after the base's position
1243     if (newSelectionEndNode
1244         && selectionStartNode->isContentEditable() == newSelectionEndNode->isContentEditable()
1245         && WebCore::comparePositions(position->deepEquivalent(), base) > 0) {
1246         // Change the 'base' and 'extent' positions to 'start' and 'end' positions.
1247         // We do it, because without this, the other modifications of the selection
1248         // would destroy the 'start' and/or 'end' positions and set them to
1249         // the 'base'/'extent' positions accordingly
1250
1251         WebCore::VisibleSelection sel(frameSelection->start(), frameSelection->end());
1252         frameSelection->setSelection(sel);
1253
1254         bool oldProhibitsScrolling = focusedFrame->view()->prohibitsScrolling();
1255         focusedFrame->view()->setProhibitsScrolling(true);
1256
1257         frameSelection->setExtent(*position);
1258
1259         focusedFrame->view()->setProhibitsScrolling(oldProhibitsScrolling);
1260
1261         result = true;
1262     }
1263 }
1264
1265 void WebPage::getSelectionHandlers(IntRect& leftRect, IntRect& rightRect)
1266 {
1267     Frame* focusedFrame = m_page->focusController()->focusedOrMainFrame();
1268     if (!focusedFrame->selection()->isRange())
1269         return;
1270
1271     // Is this check necessary? Leaving it for safety.
1272     WebCore::RenderView* root = focusedFrame->contentRenderer();
1273     if (!root)
1274         return;
1275
1276     RefPtr<WebCore::Range> selectedRange = focusedFrame->selection()->toNormalizedRange();
1277
1278     Vector<WebCore::IntRect> rects;
1279     selectedRange->textRects(rects, true);
1280
1281     unsigned size = rects.size();
1282     if (size > 0) {
1283         leftRect = rects[0];
1284         rightRect = rects[size-1];
1285         // prevent from selecting zero-length selection
1286         if (leftRect.x() == rightRect.x() + rightRect.width()
1287             && leftRect.y() == rightRect.y())
1288             return;
1289
1290         FrameView* frameView = focusedFrame->view();
1291         if (!frameView)
1292             return;
1293
1294         leftRect = frameView->contentsToWindow(leftRect);
1295         rightRect = frameView->contentsToWindow(rightRect);
1296      }
1297 }
1298
1299 void WebPage::getSelectionText(String& result)
1300 {
1301     Frame* focusedFrame = m_page->focusController()->focusedOrMainFrame();
1302     result = focusedFrame->editor()->selectedText();
1303 }
1304
1305 void WebPage::selectionRangeClear(bool& result)
1306 {
1307     result = false;
1308
1309     Frame* focusedFrame = m_page->focusController()->focusedOrMainFrame();
1310     WebCore::FrameSelection* frameSelection = focusedFrame->selection();
1311     if (!frameSelection)
1312         return;
1313
1314     if (frameSelection->isRange()) {
1315         if (frameSelection->isContentEditable()) {
1316             WebCore::VisiblePosition visiblePos(frameSelection->extent());
1317             if (visiblePos.isNull())
1318                 return;
1319             WebCore::VisibleSelection newSelection = WebCore::VisibleSelection(visiblePos);
1320             frameSelection->setSelection(newSelection, WebCore::CharacterGranularity);
1321             frameSelection->setCaretBlinkingSuspended(false);
1322         } else
1323             frameSelection->clear();
1324
1325         result = true;
1326     }
1327 }
1328 #endif
1329
1330 #endif // #if OS(TIZEN)
1331
1332 } // namespace WebKit