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