upload webkit/tizen 2.0_beta source.
[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/KeyboardEvent.h>
39 #include <WebCore/Page.h>
40 #include <WebCore/PlatformKeyboardEvent.h>
41 #include <WebCore/Settings.h>
42
43 #if OS(TIZEN)
44 #include "Arguments.h"
45 #include "PlatformContextCairo.h"
46 #include "WebCoreArgumentCoders.h"
47 #include "WebFrame.h"
48 #include "WebImage.h"
49 #include "WebPageProxyMessages.h"
50 #include <WebCore/FrameView.h>
51
52 #if ENABLE(TIZEN_INPUT_TAG_EXTENSION)
53 #include <WebCore/HTMLInputElement.h>
54 #include <WebCore/HTMLNames.h>
55 #endif
56
57 #if ENABLE(TIZEN_MOBILE_WEB_PRINT)
58 #include <WebCore/PlatformContextCairo.h>
59 #endif
60
61 #if ENABLE(TIZEN_SUPPORT_RSS_LINK_PARSING)
62 #include "HTMLLinkElement.h"
63 #include <WebCore/html/HTMLAllCollection.h>
64 #include <efl/RssItemEfl.h>
65 #endif
66
67 #if ENABLE(TIZEN_WEBKIT_PASTEBOARD)
68 #include <WebCore/Pasteboard.h>
69 #endif
70
71 #if ENABLE(TIZEN_WEBKIT2_REMOTE_WEB_INSPECTOR)
72 #include "WebInspectorServerEfl.h"
73 #endif
74
75 #if ENABLE(TIZEN_WEB_STORAGE)
76 #include <WebCore/GroupSettings.h>
77 #include <WebCore/PageGroup.h>
78 #endif
79
80 #if ENABLE(TIZEN_NPAPI)
81 #include "PluginView.h"
82 #endif
83
84 #if ENABLE(TIZEN_PREFERENCE)
85 #include "WebPreferencesStore.h"
86 #include <WebCore/Settings.h>
87 #endif
88
89 #if ENABLE(TIZEN_WEBKIT2_FOCUS_RING)
90 #include <WebCore/HTMLFrameOwnerElement.h>
91 #include <WebCore/HTMLImageElement.h>
92 #endif
93
94 #if ENABLE(TIZEN_DEVICE_ORIENTATION)
95 #include "DeviceMotionClientEfl.h"
96 #include "DeviceOrientationClientEfl.h"
97 #endif
98
99 #if ENABLE(TIZEN_WEBKIT2_THEME_SET)
100 #include <WebCore/RenderThemeEfl.h>
101 #endif
102
103 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION_ON_UI_SIDE)
104 #include "RenderLayer.h"
105 #include "WebGraphicsLayer.h"
106 #endif
107 #endif // #if OS(TIZEN)
108
109 using namespace WebCore;
110
111 namespace WebKit {
112
113 void WebPage::platformInitialize()
114 {
115 #if ENABLE(TIZEN_DEVICE_ORIENTATION)
116     WebCore::provideDeviceMotionTo(m_page.get(), new DeviceMotionClientEfl);
117     WebCore::provideDeviceOrientationTo(m_page.get(), new DeviceOrientationClientEfl);
118 #endif
119 }
120
121 #if ENABLE(TIZEN_PREFERENCE)
122 void WebPage::platformPreferencesDidChange(const WebPreferencesStore& store)
123 {
124     Settings* settings = m_page->settings();
125     settings->setInteractiveFormValidationEnabled(store.getBoolValueForKey(WebPreferencesKey::interactiveFormValidationEnabledKey()));
126     settings->setViewWidth(store.getUInt32ValueForKey(WebPreferencesKey::viewWidthKey()));
127     settings->setViewHeight(store.getUInt32ValueForKey(WebPreferencesKey::viewHeightKey()));
128     settings->setUsesEncodingDetector(store.getBoolValueForKey(WebPreferencesKey::usesEncodingDetectorKey()));
129 #if ENABLE(TIZEN_LOAD_REMOTE_IMAGES)
130     settings->setLoadRemoteImages(store.getBoolValueForKey(WebPreferencesKey::loadRemoteImagesKey()));
131 #endif
132 #if ENABLE(TIZEN_ISF_PORT)
133     settings->setShowImeOnAutofocus(store.getBoolValueForKey(WebPreferencesKey::showImeOnAutofocusKey()));
134     settings->setEnableDefaultKeypad(store.getBoolValueForKey(WebPreferencesKey::defaultKeypadEnabledKey()));
135 #endif
136 #if ENABLE(TIZEN_WAC_DISABLE_GEOLOCATION)
137     settings->setGeolocationEnabled(store.getBoolValueForKey(WebPreferencesKey::geolocationEnabledKey()));
138 #endif
139 }
140 #else
141 void WebPage::platformPreferencesDidChange(const WebPreferencesStore&)
142 {
143     notImplemented();
144 }
145 #endif // #if ENABLE(TIZEN_PREFERENCE)
146
147 static inline void scroll(Page* page, ScrollDirection direction, ScrollGranularity granularity)
148 {
149     page->focusController()->focusedOrMainFrame()->eventHandler()->scrollRecursively(direction, granularity);
150 }
151
152 bool WebPage::performDefaultBehaviorForKeyEvent(const WebKeyboardEvent& keyboardEvent)
153 {
154     notImplemented();
155     return false;
156 }
157
158 bool WebPage::platformHasLocalDataForURL(const KURL&)
159 {
160     notImplemented();
161     return false;
162 }
163
164 String WebPage::cachedResponseMIMETypeForURL(const KURL&)
165 {
166     notImplemented();
167     return String();
168 }
169
170 bool WebPage::platformCanHandleRequest(const ResourceRequest&)
171 {
172     notImplemented();
173     return true;
174 }
175
176 String WebPage::cachedSuggestedFilenameForURL(const KURL&)
177 {
178     notImplemented();
179     return String();
180 }
181
182 PassRefPtr<SharedBuffer> WebPage::cachedResponseDataForURL(const KURL&)
183 {
184     notImplemented();
185     return 0;
186 }
187
188 const char* WebPage::interpretKeyEvent(const KeyboardEvent* event)
189 {
190     ASSERT(event->type() == eventNames().keydownEvent || event->type() == eventNames().keypressEvent);
191
192     if (event->type() == eventNames().keydownEvent)
193         return getKeyDownCommandName(event);
194
195     return getKeyPressCommandName(event);
196 }
197
198 #if OS(TIZEN)
199
200 #if ENABLE(TIZEN_WEBKIT2_TILED_BACKING_STORE)
201 IntSize WebPage::contentsSize() const
202 {
203     FrameView* frameView = m_page->mainFrame()->view();
204     if (!frameView)
205         return IntSize(0, 0);
206
207     return frameView->contentsSize();
208 }
209 #endif
210
211 void WebPage::scrollMainFrameBy(const IntSize& scrollOffset)
212 {
213     m_page->mainFrame()->view()->scrollBy(scrollOffset);
214 }
215
216 void WebPage::scrollMainFrameTo(const IntPoint& scrollPosition)
217 {
218     m_page->mainFrame()->view()->setScrollPosition(scrollPosition);
219 }
220
221 void WebPage::createSnapshot(const IntRect rect, float scaleFactor, ShareableBitmap::Handle& snapshotHandle)
222 {
223     FrameView* frameView = m_mainFrame->coreFrame()->view();
224     if (!frameView)
225         return;
226
227     RefPtr<WebImage> snapshotImage = scaledSnapshotInViewCoordinates(rect, scaleFactor, ImageOptionsShareable);
228     if (!snapshotImage || !snapshotImage->bitmap())
229         return;
230
231     snapshotImage->bitmap()->createHandle(snapshotHandle);
232 }
233
234 void WebPage::requestUpdateFormNavigation()
235 {
236     Frame* frame = m_page->focusController()->focusedOrMainFrame();
237     if (!frame)
238         return;
239
240     Document* document = frame->document();
241     if (!document)
242         return;
243
244     Node* focusedNode = document->focusedNode();
245
246     Vector<RefPtr<Node> > focusableNodes;
247     document->getFocusableNodes(focusableNodes);
248
249     int formElementCount = 0;
250     int currentNodeIndex = -1;
251     const Vector<RefPtr<Node> >::iterator end = focusableNodes.end();
252     for (Vector<RefPtr<Node> >::iterator it = focusableNodes.begin(); it != end; ++it) {
253         AtomicString nodeName = (*it).get()->nodeName();
254         if (equalIgnoringCase(nodeName, "SELECT")
255             || (equalIgnoringCase(nodeName, "INPUT")
256                 && !equalIgnoringCase((*it).get()->toInputElement()->type(), "CHECKBOX")
257                 && !equalIgnoringCase((*it).get()->toInputElement()->type(), "RADIO")
258                 && !equalIgnoringCase((*it).get()->toInputElement()->type(), "SUBMIT")
259                 )
260             ) {
261             if ((*it).get() == focusedNode)
262                 currentNodeIndex = formElementCount;
263             formElementCount++;
264         }
265     }
266
267     if (currentNodeIndex == -1)
268         return;
269
270     send(Messages::WebPageProxy::UpdateFormNavigation(formElementCount, currentNodeIndex));
271 }
272
273 void WebPage::moveFocus(int newIndex)
274 {
275     Frame* frame = m_page->focusController()->focusedOrMainFrame();
276     if (!frame)
277         return;
278
279     Document* document = frame->document();
280     if (!document)
281         return;
282
283     Vector<RefPtr<Node> > focusableNodes;
284     document->getFocusableNodes(focusableNodes);
285
286     int index = 0;
287     const Vector<RefPtr<Node> >::iterator end = focusableNodes.end();
288     for (Vector<RefPtr<Node> >::iterator it = focusableNodes.begin(); it != end; ++it) {
289         AtomicString nodeName = (*it).get()->nodeName();
290         if (equalIgnoringCase(nodeName, "SELECT")) {
291             if (index == newIndex) {
292                 (*it).get()->setFocus();
293                 LayoutPoint position = LayoutPoint(0, 0);
294                 PlatformMouseEvent event(flooredIntPoint(position), flooredIntPoint(position), LeftButton, PlatformEvent::MouseMoved, 1, false, false, false, false, 0);
295                 (*it).get()->dispatchMouseEvent(event, "mousedown", 0, 0);
296             }
297             index++;
298         } else if (equalIgnoringCase(nodeName, "INPUT")
299             && !equalIgnoringCase((*it).get()->toInputElement()->type(), "CHECKBOX")
300             && !equalIgnoringCase((*it).get()->toInputElement()->type(), "RADIO")
301             ) {
302             if (index == newIndex) {
303                 HTMLInputElement* elem = (*it).get()->toInputElement();
304                 elem->focus();
305             }
306             index++;
307         }
308     }
309 }
310
311 #if ENABLE(TIZEN_MOBILE_WEB_PRINT)
312 #define A4_WIDTH 210
313 #define A4_HEIGHT 297
314 #define INCH_TO_MM 25.4
315 #define INCH_TO_POINTS 72.0
316
317 void WebPage::createPagesToPDF(const IntSize& size, const String& fileName)
318 {
319     FrameView* frameView = m_mainFrame->coreFrame()->view();
320     if (!frameView)
321         return;
322
323     RefPtr<WebImage> pageshotImage = WebImage::create(size, ImageOptionsShareable);
324     if (!pageshotImage->bitmap())
325         return;
326
327     double pdfWidth = A4_WIDTH / INCH_TO_MM * INCH_TO_POINTS;
328     double pdfHeight = A4_HEIGHT / INCH_TO_MM * INCH_TO_POINTS;
329     double scaleFactorPdf = pdfWidth / (double)size.width();
330
331     OwnPtr<WebCore::GraphicsContext> graphicsContext = pageshotImage->bitmap()->createGraphicsContextForPdfSurface(fileName, pdfWidth, pdfHeight);
332     graphicsContext->scale(FloatSize(scaleFactorPdf, scaleFactorPdf));
333
334     frameView->updateLayoutAndStyleIfNeededRecursive();
335
336     int pageNumber = ((size.height() * scaleFactorPdf) / pdfHeight) + 1;
337     IntRect paintRect(0, 0, size.width(), size.height());
338
339     PaintBehavior oldBehavior = frameView->paintBehavior();
340     frameView->setPaintBehavior(oldBehavior | PaintBehaviorFlattenCompositingLayers);
341     for (int i = 0; i < pageNumber; i++) {
342         frameView->paint(graphicsContext.get(), paintRect);
343         cairo_show_page(graphicsContext->platformContext()->cr());
344         graphicsContext->translate(0, -ceil(pdfHeight / scaleFactorPdf));
345     }
346     frameView->setPaintBehavior(oldBehavior);
347
348     pageshotImage.release();
349 }
350 #endif
351
352 void WebPage::confirmComposition(const String& compositionString)
353 {
354     Frame* frame = m_page->focusController()->focusedOrMainFrame();
355     if (!frame || !frame->editor()->canEdit())
356         return;
357     frame->editor()->confirmComposition(compositionString);
358 }
359
360 void WebPage::setComposition(const String& compositionString, const Vector<WebCore::CompositionUnderline>& underlines, uint64_t cursorPosition)
361 {
362     Frame* frame = m_page->focusController()->focusedOrMainFrame();
363     if (!frame || !frame->editor()->canEdit())
364         return;
365     frame->editor()->setComposition(compositionString, underlines, cursorPosition, 0);
366 }
367
368 #if ENABLE(TIZEN_TEXT_CARET_HANDLING_WK2)
369 bool WebPage::setCaretPosition(const WebCore::IntPoint& pos)
370 {
371     Frame* frame = m_page->focusController()->focusedOrMainFrame();
372     if (!frame)
373         return false;
374
375     WebCore::FrameSelection* controller = frame->selection();
376     if (!controller)
377         return false;
378
379     FrameView* frameView = frame->view();
380     if (!frameView)
381         return false;
382
383     WebCore::IntPoint point = pos;
384     WebCore::HitTestResult result = frame->eventHandler()->hitTestResultAtPoint(frameView->windowToContents(point), /*allowShadowContent*/ true, /*ignoreClipping*/ true);
385     if (result.scrollbar())
386         return false;
387
388     WebCore::Node* innerNode = result.innerNode();
389
390     if (!innerNode || !innerNode->renderer())
391         return false;
392
393     WebCore::VisiblePosition visiblePos;
394
395     const int boundariesWidth = 2;
396
397     // we check if content is richly editable - because those input field behave other than plain text ones
398     // sometimes they may consists a node structure and they need special approach
399     if (innerNode->rendererIsRichlyEditable()) {
400         // point gets inner node local coordinates
401         point = flooredIntPoint(result.localPoint());
402         WebCore::IntRect rect = innerNode->renderer()->absoluteBoundingBoxRect(true);
403
404         // it is not the best way to do this, but it is not as slow and it works - so maybe in the future someone
405         // will have a better idea how to solve it
406         // here we are getting innerNode from HitTestResult - unfortunately this is a kind of high level node
407         // in the code below I am trying to obtain low level node - #text - to get its coordinates and size
408
409         // all those getting nodes rects are needed to bypass WebCore's methods of positioning caret when user
410         // is clicking outside a node - and cheat WebCore telling it that actually we clicked into input field
411         // node, not outside of it
412         WebCore::Node* deepInnerNode = innerNode->renderer()->positionForPoint(point).deepEquivalent().deprecatedNode();
413
414         if (!deepInnerNode || !deepInnerNode->renderer())
415             return false;
416
417         // so we get a base node rectange
418         WebCore::IntRect deepNodeRect = deepInnerNode->renderer()->absoluteBoundingBoxRect(true);
419
420         // we modify our local point to adjust it to base node local coordinates
421         point.move(rect.x() - deepNodeRect.x(), rect.y() - deepNodeRect.y());
422
423         // if we are outside the rect we cheat, that we are just inside of it
424         if (point.y() < 0)
425             point.setY(0);
426         else if (point.y() >= deepNodeRect.height())
427             point.setY(deepNodeRect.height() - 1);
428
429         // visible position created - caret ready to set
430         visiblePos = deepInnerNode->renderer()->positionForPoint(point);
431         if (visiblePos.isNull())
432             return false;
433     } else {
434         // for plain text input fields we can get only a caret bounding box
435         if (!controller->isCaret() || !controller->caretRenderer())
436             return false;
437
438         const WebCore::Node* node = controller->start().deprecatedNode();
439         if (!node || !node->renderer())
440             return false;
441
442         WebCore::IntRect rect = controller->caretRenderer()->absoluteBoundingBoxRect(true);
443
444         // here we also cheat input field that we actually are just inside of if
445         if (point.x() < rect.x())
446             point.setX(rect.x());
447         else if (point.x() > rect.maxX())
448             point.setX(rect.maxX());
449         if (point.y() < rect.y() + boundariesWidth)
450             point.setY(rect.y() + boundariesWidth);
451         else if (point.y() >= rect.maxY() - boundariesWidth)
452             point.setY(rect.maxY() - boundariesWidth - 1);
453
454         // hit test with fake (adjusted) coordinates
455         WebCore::HitTestResult newResult = frame->eventHandler()->hitTestResultAtPoint
456                 (point, /*allowShadowContent*/ true, /*ignoreClipping*/ true);
457
458         if (!newResult.isContentEditable())
459             return false;
460
461         WebCore::Node* newInnerNode = newResult.innerNode();
462
463         if (!newInnerNode || !newInnerNode->renderer())
464             return false;
465
466         // visible position created
467         visiblePos = newInnerNode->renderer()->positionForPoint(newResult.localPoint());
468         if (visiblePos.isNull())
469             return false;
470     }
471
472     // create visible selection from visible position
473     WebCore::VisibleSelection newSelection = WebCore::VisibleSelection(visiblePos);
474     controller->setSelection(newSelection, WebCore::CharacterGranularity);
475     // after setting selection caret blinking is suspended by default so we are unsuspedning it
476     controller->setCaretBlinkingSuspended(false);
477
478     return true;
479 }
480
481 void WebPage::getCaretPosition(WebCore::IntRect& rect)
482 {
483     Frame* frame = m_page->focusController()->focusedOrMainFrame();
484     if (!frame)
485         return;
486
487     WebCore::FrameSelection* controller = frame->selection();
488     if (!controller)
489         return;
490
491     WebCore::Node* node = controller->start().deprecatedNode();
492     if (!node || !node->renderer() || !node->isContentEditable())
493         return;
494
495     if (controller->isCaret()) {
496         FrameView* frameView = frame->view();
497         if (!frameView)
498             return;
499
500         rect = frameView->contentsToWindow(controller->absoluteCaretBounds());
501     }
502 }
503 #endif
504
505 #if ENABLE(TIZEN_ISF_PORT)
506 void WebPage::getCursorOffsetPosition(int& offset)
507 {
508     offset = 0;
509     Frame* frame = m_page->focusController()->focusedOrMainFrame();
510     if (!frame || !frame->editor()->canEdit())
511         return;
512
513     Position base = frame->selection()->base();
514     Node* baseNode = base.containerNode();
515     if (baseNode)
516         offset = baseNode->isTextNode() ? base.offsetInContainerNode() : 0;
517 }
518
519 void WebPage::getContentOfPosition(String& content)
520 {
521     Frame* frame = m_page->focusController()->focusedOrMainFrame();
522     if (!frame || !frame->editor()->canEdit())
523         return;
524
525     Position base = frame->selection()->base();
526     Node* baseNode = base.containerNode();
527     if (baseNode && baseNode->isTextNode())
528         content = baseNode->textContent();
529     else
530         content = String();
531 }
532
533 void WebPage::deleteSurroundingPosition(bool& result)
534 {
535     Frame* frame = m_page->focusController()->focusedOrMainFrame();
536     if (!frame || !frame->editor()->canEdit())
537         return;
538
539     frame->editor()->deleteWithDirection(DirectionBackward, CharacterGranularity, false, true);
540 }
541 #endif
542
543 #if ENABLE(TIZEN_INPUT_TAG_EXTENSION)
544 void WebPage::setFocusedInputElementValue(const String& inputValue)
545 {
546     Frame* frame = m_page->focusController()->focusedOrMainFrame();
547     if (frame
548         && frame->document()
549         && frame->document()->focusedNode()) {
550         Node* node = frame->document()->focusedNode();
551         if (node->nodeType() == Node::ELEMENT_NODE) {
552             if (node->hasTagName(HTMLNames::inputTag)) {
553                 static_cast<HTMLInputElement*>(node)->setValue(inputValue, DispatchChangeEvent);
554                 static_cast<HTMLInputElement*>(node)->blur(); //  unfocus input element after set the value
555             }
556         }
557     }
558 }
559
560 void  WebPage::getFocusedInputElementValue(String& inputValue)
561 {
562     inputValue = String();
563
564     Frame* frame = m_page->focusController()->focusedOrMainFrame();
565     if (frame
566         && frame->document()
567         && frame->document()->focusedNode()) {
568         Node* node = frame->document()->focusedNode();
569         if (node->nodeType() == WebCore::Node::ELEMENT_NODE)
570             if (node->hasTagName(WebCore::HTMLNames::inputTag))
571                 inputValue = (static_cast<WebCore::HTMLInputElement*>(node))->value();
572     }
573 }
574 #endif
575
576 #if ENABLE(TIZEN_READER)
577 void WebPage::checkPageForReader(uint64_t callbackID)
578 {
579 }
580 #endif
581
582 #if ENABLE(TIZEN_WEBKIT2_HIT_TEST)
583 #if ENABLE(TIZEN_WEBKIT2_FOCUS_RING)
584 static IntRect getFocusedRect(HitTestResult hitTestResult, Page* page)
585 {
586     IntRect focusedRect = IntRect(0, 0, 0, 0);
587     Node* node = hitTestResult.innerNode();
588     bool isFocusRingDrawable = false;
589     Node* focusableNode = node;
590     while (focusableNode) {
591         RenderObject* renderer = focusableNode->renderer();
592         if (renderer && renderer->isRoot())
593             break;
594
595         if (focusableNode->isFocusable()) {
596             if (focusableNode->isLink() || focusableNode->hasTagName(HTMLNames::inputTag))
597                 isFocusRingDrawable = true;
598             break;
599         }
600
601         focusableNode = focusableNode->parentNode();
602     }
603
604     if (!isFocusRingDrawable)
605         return focusedRect;
606
607     if (!hitTestResult.absoluteImageURL().isEmpty()) {
608         bool isReplaced;
609         IntRect imageNodeRect = pixelSnappedIntRect(node->getRect());
610         if (!focusableNode->renderRect(&isReplaced).isEmpty() && imageNodeRect.contains(pixelSnappedIntRect(focusableNode->getRect()))) {
611             // If render rect of focusableNode is empty and rect of imageNode include rect of focusableNode,
612             // we have to get rect of focusableNode.
613             // for example - The rect of google logo image in www.google.com pc site's search result page is bigger than rect of focusableNode.
614             // for example - The rect of category menu image in www.gmarket.co.kr pc site is bigger than rect of focusableNode.
615             focusedRect = pixelSnappedIntRect(focusableNode->getRect());
616         }
617         else {
618             // otherwise we have to get rect of imageNode.
619             // for example - The render rect of images in www.pudelek.pl is empty.
620             // 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.
621             focusedRect = imageNodeRect;
622             focusableNode = node;
623         }
624     } else {
625         // If focusedNode have multiple child nodes, we have to unite rect of child nodes.
626         // for example - links in www.google.com's search result page.
627         IntRect tempRect = IntRect(0, 0, 0, 0);
628         for (Node* childNode = focusableNode->firstChild(); childNode; childNode = childNode->traverseNextNode(focusableNode)) {
629             bool isReplaced;
630             if (focusableNode->renderRect(&isReplaced).contains(childNode->getRect()))
631                 tempRect.unite(pixelSnappedIntRect(childNode->getRect()));
632         }
633
634         // If tempRect is empty or rect of focusableNode include tempRect,
635         // we have to get rect of focusableNode.
636         // for example - list menu item in m.naver.com.
637         // otherwise we have to get rect of tempRect.
638         if (tempRect.isEmpty() || focusableNode->getRect().contains(tempRect))
639             focusedRect = pixelSnappedIntRect(focusableNode->getRect());
640         else
641             focusedRect = tempRect;
642     }
643
644     // We have to get render rect from ancestor node if current focusedRect is empty.
645     // for example - The rect of naver logo image in www.naver.com pc site is empty.
646     bool isReplaced;
647     for (Node* loopNode = focusableNode; loopNode && focusedRect.isEmpty(); loopNode = loopNode->parentNode()) {
648         RenderObject* renderer = loopNode->renderer();
649         if (renderer && renderer->isRoot())
650             break;
651
652         focusedRect = pixelSnappedIntRect(loopNode->renderRect(&isReplaced));
653     }
654
655     Frame* mainFrame = page->mainFrame();
656     Frame* nodeFrame = focusableNode->document()->frame();
657     Node* owner;
658     while (nodeFrame && nodeFrame != mainFrame) {
659         owner = nodeFrame->ownerElement();
660         if (!owner)
661             break;
662
663         focusedRect.setX(focusedRect.x() + owner->getRect().x());
664         focusedRect.setY(focusedRect.y() + owner->getRect().y());
665         nodeFrame = owner->document()->frame();
666     }
667
668     // The y position of tab menu item in www.google.com is negative value,
669     // so we do not want to draw focus ring in that case.
670     if ((focusedRect.x() < 0) || (focusedRect.y() < 0))
671         focusedRect = IntRect(0, 0, 0, 0);
672
673     return focusedRect;
674 }
675 #endif
676
677 void WebPage::hitTestResultAtPoint(const IntPoint& point, int hitTestMode, WebHitTestResult::Data& hitTestResultData)
678 {
679     Frame* frame = m_page->focusController()->focusedOrMainFrame();
680     FrameView* frameView = frame->view();
681     if (!frameView)
682         return;
683
684     HitTestResult hitTestResult = frame->eventHandler()->hitTestResultAtPoint(frameView->windowToContents(point), false);
685     hitTestResultData.absoluteImageURL = hitTestResult.absoluteImageURL().string();
686     hitTestResultData.absoluteLinkURL = hitTestResult.absoluteLinkURL().string();
687     hitTestResultData.absoluteMediaURL = hitTestResult.absoluteMediaURL().string();
688     hitTestResultData.linkLabel = hitTestResult.textContent();
689     hitTestResultData.linkTitle = hitTestResult.titleDisplayString();
690
691     int context = WebHitTestResult::HitTestResultContextDocument;
692
693     if (!hitTestResult.absoluteLinkURL().isEmpty())
694         context |= WebHitTestResult::HitTestResultContextLink;
695     if (!hitTestResult.absoluteImageURL().isEmpty())
696         context |= WebHitTestResult::HitTestResultContextImage;
697     if (!hitTestResult.absoluteMediaURL().isEmpty())
698         context |= WebHitTestResult::HitTestResultContextMedia;
699     if (hitTestResult.isSelected())
700         context |= WebHitTestResult::HitTestResultContextSelection;
701     if (hitTestResult.isContentEditable())
702         context |= WebHitTestResult::HitTestResultContextEditable;
703     if (hitTestResult.innerNonSharedNode() && hitTestResult.innerNonSharedNode()->isTextNode())
704         context |= WebHitTestResult::HitTestResultContextText;
705
706     hitTestResultData.context = context;
707     hitTestResultData.hitTestMode = hitTestMode;
708
709 #if ENABLE(TIZEN_WEBKIT2_FOCUS_RING)
710     hitTestResultData.focusedRect = getFocusedRect(hitTestResult, m_page.get());
711 #endif
712
713     if (hitTestResultData.hitTestMode & WebHitTestResult::HitTestModeNodeData) {
714         WebCore::Node* hitNode = hitTestResult.innerNonSharedNode();
715         if (hitNode) {
716             hitTestResultData.nodeData.nodeValue = hitNode->nodeValue();
717
718             if ((hitTestResultData.context & WebHitTestResult::HitTestResultContextText) && hitNode->parentNode())
719                 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.
720
721             if (hitNode->isElementNode()) {
722                 WebCore::Element* hitElement = static_cast<WebCore::Element*>(hitNode);
723                 if (hitElement) {
724                     hitTestResultData.nodeData.tagName = hitElement->tagName();
725                 }
726             }
727
728             WebCore::NamedNodeMap* namedNodeMap = hitNode->attributes();
729             if (namedNodeMap) {
730                 for (size_t i = 0; i < namedNodeMap->length(); i++) {
731                     WebCore::Attribute* attribute = namedNodeMap->element()->attributeItem(i);
732                     String key = attribute->name().toString();
733                     String value = attribute->value();
734                     hitTestResultData.nodeData.attributeMap.add(key, value);
735                 }
736             }
737         }
738
739 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION_ON_UI_SIDE)
740         hitTestResultData.nodeData.isScrollableNodeFocused = false;
741         hitTestResultData.nodeData.enclosingWebLayerID = 0;
742         WebCore::RenderObject* renderer = hitTestResult.innerNode() ? hitTestResult.innerNode()->renderer() : 0;
743         while (renderer) {
744             if (renderer->isBoxModelObject() && renderer->hasLayer() && toRenderBoxModelObject(renderer)->layer()->hasAcceleratedTouchScrolling()) {
745                 hitTestResultData.nodeData.isScrollableNodeFocused = true;
746                 WebCore::GraphicsLayer* scrollingContentsLayer = renderer->enclosingLayer()->layerForScrollingContents();
747                 hitTestResultData.nodeData.enclosingWebLayerID = scrollingContentsLayer ? toWebGraphicsLayer(scrollingContentsLayer)->id() : 0;
748
749                 frame->eventHandler()->setMousePressNode(hitTestResult.innerNode());
750                 break;
751             }
752             renderer = renderer->parent();
753         }
754 #endif
755     }
756
757     if ((hitTestResultData.hitTestMode & WebHitTestResult::HitTestModeImageData) && (hitTestResultData.context & WebHitTestResult::HitTestResultContextImage)) {
758         WebCore::Image* hitImage = hitTestResult.image();
759         if (hitImage && hitImage->data() && hitImage->data()->data()) {
760             hitTestResultData.imageData.dataReference = CoreIPC::DataReference(reinterpret_cast<const uint8_t*>(hitImage->data()->data()), hitImage->data()->size());
761             hitTestResultData.imageData.fileNameExtension = hitImage->filenameExtension();
762         }
763     }
764 }
765 #endif
766
767 #if ENABLE(TIZEN_SUPPORT_RSS_LINK_PARSING)
768 void WebPage::getRssItems(uint64_t callbackID)
769 {
770     if (!m_page->mainFrame())
771         return;
772     Document* document = m_page->mainFrame()->document();
773     if (!document)
774         return;
775     RefPtr<HTMLAllCollection>collection = document->all();
776
777     WTF::String Rss("application/rss+xml");
778     WTF::String Atom("application/atom+xml");
779     WTF::String Alternate("alternate");
780
781     Vector<RssItemEfl> rssItems;
782
783     for (Node* node = collection->firstItem(); node; node = collection->nextItem()) {
784         HTMLLinkElement* linkElement = static_cast<HTMLLinkElement*>(node);
785         if (linkElement->rel() == Alternate) {
786             RssItemEfl::LinkTypeEfl type;
787             if (linkElement->type() == Rss)
788                 type = RssItemEfl::LINK_TYPE_EFL_RSS;
789             else if (linkElement->type() == Atom)
790                 type = RssItemEfl::LINK_TYPE_EFL_ATOM;
791             else
792                 continue;
793
794             RssItemEfl rssItem(linkElement->href(), linkElement->title(), type);
795             rssItems.append(rssItem);
796         }
797     }
798     send(Messages::WebPageProxy::GetRssItemsCallback(rssItems, callbackID));
799
800     return;
801 }
802 #endif // #if ENABLE(TIZEN_SUPPORT_RSS_LINK_PARSING)
803
804 #if ENABLE(TIZEN_WEB_STORAGE)
805 void WebPage::getStorageQuotaBytes(uint64_t callbackID)
806 {
807     uint32_t quota = m_page->group().groupSettings()->localStorageQuotaBytes();
808     send(Messages::WebPageProxy::DidGetWebStorageQuotaBytes(quota, callbackID));
809 }
810
811 void WebPage::setStorageQuotaBytes(uint32_t quota)
812 {
813     m_page->group().groupSettings()->setLocalStorageQuotaBytes(quota);
814 }
815 #endif
816
817 #if ENABLE(TIZEN_WEBKIT2_THEME_SET)
818 void WebPage::setThemePath(const String& path)
819 {
820     Frame* mainFrame = m_page->mainFrame();
821     if (!mainFrame)
822         return;
823
824     WebCore::FrameView* view = mainFrame->view();
825     if (view) {
826         view->setEdjeTheme(path);
827         WebCore::RenderThemeEfl* theme = static_cast<RenderThemeEfl*>(m_page->theme());
828         theme->themeChanged();
829     }
830 }
831 #endif
832
833 #if ENABLE(TIZEN_RECORDING_SURFACE_SET)
834 void WebPage::recordingSurfaceSetEnableSet(bool enable)
835 {
836     m_recordingSurfaceSetSettings = enable;
837 }
838 #endif
839
840 #if ENABLE(TIZEN_WEBKIT_PASTEBOARD)
841 void WebPage::setDataToPasteboardWithType(const String& data, uint64_t type)
842 {
843     Pasteboard::generalPasteboard()->setDataWithType(data, static_cast<Pasteboard::PasteboardDataType>(type));
844 }
845 #endif
846
847 void WebPage::suspendJavaScriptAndResources()
848 {
849     Frame* mainFrame = m_page->mainFrame();
850     if (!mainFrame)
851         return;
852
853     for (Frame* frame = mainFrame; frame; frame = frame->tree()->traverseNext())
854         frame->document()->suspendScheduledTasks(WebCore::ActiveDOMObject::PageWillBeSuspended);
855     mainFrame->loader()->suspendAllLoaders();
856 }
857
858 void WebPage::resumeJavaScriptAndResources()
859 {
860     Frame* mainFrame = m_page->mainFrame();
861     if (!mainFrame)
862         return;
863
864     for (Frame* frame = mainFrame; frame; frame = frame->tree()->traverseNext())
865         frame->document()->resumeScheduledTasks();
866     mainFrame->loader()->resumeAllLoaders();
867 }
868
869 #if ENABLE(TIZEN_WEBKIT2_REMOTE_WEB_INSPECTOR)
870 void WebPage::startInspectorServer(uint32_t port,  uint32_t& allocatedPort)
871 {
872     bool ret = WebInspectorServerEfl::server()->startServer(port);
873     if (ret)
874         allocatedPort = WebInspectorServerEfl::server()->getServerPort();
875     else
876         allocatedPort = 0;
877 }
878
879 void WebPage::stopInspectorServer(bool& result)
880 {
881     result = WebInspectorServerEfl::server()->stopServer();
882 }
883 #endif
884
885 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION_ON_UI_SIDE)
886 void WebPage::scrollOverflowWithTrajectoryVector(const WebCore::FloatPoint& trajectoryVector)
887 {
888     Frame* frame = m_page->focusController()->focusedOrMainFrame();
889     if (!frame)
890         return;
891     frame->eventHandler()->scrollOverflow(trajectoryVector);
892 }
893 #endif
894
895 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL)
896 void WebPage::scrollOverflow(const WebCore::FloatPoint& delta, bool& scrolled)
897 {
898     scrolled = m_page->focusController()->focusedOrMainFrame()->eventHandler()->scrollOverflow(delta);
899 }
900
901 void WebPage::setPressedNodeAtPoint(const IntPoint& point, bool& pressed)
902 {
903     pressed = m_page->focusController()->focusedOrMainFrame()->eventHandler()->setMousePressNodeAtPoint(point);
904 }
905 #endif
906
907 void WebPage::executeEditCommandWithArgument(const String& commandName, const String& argument)
908 {
909     executeEditingCommand(commandName, argument);
910 }
911
912 #if ENABLE(TIZEN_FIX_PLUGIN_DOWNLOAD)
913 void WebPage::arePluginsEnabled(bool& enabled)
914 {
915     enabled = m_page->settings()->arePluginsEnabled();
916 }
917 #endif // ENABLE(TIZEN_FIX_PLUGIN_DOWNLOAD)
918
919 #if ENABLE(TIZEN_NPAPI)
920 void WebPage::suspendPlugin()
921 {
922     for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
923         FrameView* view = frame->view();
924         if (!view)
925             continue;
926
927         const HashSet<RefPtr<Widget> >* children = view->children();
928         ASSERT(children);
929
930         HashSet<RefPtr<Widget> >::const_iterator end = children->end();
931         for (HashSet<RefPtr<Widget> >::const_iterator it = children->begin(); it != end; ++it) {
932             Widget* widget = (*it).get();
933             if (widget->isPluginViewBase()) {
934                 PluginView* pluginView = static_cast<PluginView*>(widget);
935                 if (pluginView)
936                     pluginView->suspendPlugin();
937             }
938         }
939     }
940 }
941
942 void WebPage::resumePlugin()
943 {
944     for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
945         FrameView* view = frame->view();
946         if (!view)
947             continue;
948
949         const HashSet<RefPtr<Widget> >* children = view->children();
950         ASSERT(children);
951
952         HashSet<RefPtr<Widget> >::const_iterator end = children->end();
953         for (HashSet<RefPtr<Widget> >::const_iterator it = children->begin(); it != end; ++it) {
954             Widget* widget = (*it).get();
955             if (widget->isPluginViewBase()) {
956                 PluginView* pluginView = static_cast<PluginView*>(widget);
957                 if (pluginView)
958                     pluginView->resumePlugin();
959             }
960         }
961     }
962 }
963 #endif
964
965 #if ENABLE(TIZEN_WEBKIT2_GET_TEXT_STYLE_FOR_SELECTION)
966 void WebPage::getTextStyleStateForSelection()
967 {
968     Frame* frame = m_page->focusController()->focusedOrMainFrame();
969
970     int underlineState = frame->editor()->selectionHasStyle(CSSPropertyWebkitTextDecorationsInEffect, "underline");
971     int italicState = frame->editor()->selectionHasStyle(CSSPropertyFontStyle, "italic");
972     int boldState = frame->editor()->selectionHasStyle(CSSPropertyFontWeight, "bold");
973
974     send(Messages::WebPageProxy::DidGetTextStyleStateForSelection(underlineState, italicState, boldState));
975 }
976 #endif
977
978 #endif // #if OS(TIZEN)
979
980 } // namespace WebKit