1/*
2 * Copyright (C) 2006 Zack Rusin <zack@kde.org>
3 * Copyright (C) 2006, 2011 Apple Inc. All rights reserved.
4 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
5 * Copyright (C) 2008 Collabora Ltd. All rights reserved.
6 * Copyright (C) 2008 Holger Hans Peter Freyther
7 * Copyright (C) 2008 Kenneth Rohde Christiansen
8 * Copyright (C) 2009-2010 ProFUSION embedded systems
9 * Copyright (C) 2009-2010 Samsung Electronics
10 * Copyright (C) 2012 Intel Corporation
11 *
12 * All rights reserved.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
16 * are met:
17 * 1. Redistributions of source code must retain the above copyright
18 *    notice, this list of conditions and the following disclaimer.
19 * 2. Redistributions in binary form must reproduce the above copyright
20 *    notice, this list of conditions and the following disclaimer in the
21 *    documentation and/or other materials provided with the distribution.
22 *
23 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
24 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
27 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
31 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
35
36#include "config.h"
37#include "FrameLoaderClientEfl.h"
38
39#include "APICast.h"
40#include "DocumentLoader.h"
41#include "ErrorsEfl.h"
42#include "FormState.h"
43#include "FrameLoader.h"
44#include "FrameNetworkingContextEfl.h"
45#include "FrameTree.h"
46#include "FrameView.h"
47#include "HTMLFormElement.h"
48#include "HTTPStatusCodes.h"
49#include "MIMETypeRegistry.h"
50#include "NotImplemented.h"
51#include "Page.h"
52#include "PluginDatabase.h"
53#include "ProgressTracker.h"
54#include "RenderPart.h"
55#include "ResourceRequest.h"
56#include "ResourceResponse.h"
57#include "ScriptController.h"
58#include "Settings.h"
59#include "WebKitVersion.h"
60#include "ewk_frame_private.h"
61#include "ewk_private.h"
62#include "ewk_settings.h"
63#include "ewk_settings_private.h"
64#include "ewk_view_private.h"
65#include <Ecore_Evas.h>
66#include <wtf/text/CString.h>
67#include <wtf/text/StringConcatenate.h>
68
69namespace WebCore {
70
71FrameLoaderClientEfl::FrameLoaderClientEfl(Evas_Object* view)
72    : m_view(view)
73    , m_frame(0)
74    , m_userAgent("")
75    , m_customUserAgent("")
76    , m_pluginView(0)
77    , m_hasSentResponseToPlugin(false)
78{
79}
80
81static String composeUserAgent()
82{
83    return String(ewk_settings_default_user_agent_get());
84}
85
86void FrameLoaderClientEfl::setCustomUserAgent(const String& agent)
87{
88    m_customUserAgent = agent;
89}
90
91const String& FrameLoaderClientEfl::customUserAgent() const
92{
93    return m_customUserAgent;
94}
95
96String FrameLoaderClientEfl::userAgent(const KURL&)
97{
98    if (!m_customUserAgent.isEmpty())
99        return m_customUserAgent;
100
101    if (m_userAgent.isEmpty())
102        m_userAgent = composeUserAgent();
103    return m_userAgent;
104}
105
106void FrameLoaderClientEfl::callPolicyFunction(FramePolicyFunction function, PolicyAction action)
107{
108    Frame* f = EWKPrivate::coreFrame(m_frame);
109    ASSERT(f);
110    (f->loader()->policyChecker()->*function)(action);
111}
112
113WTF::PassRefPtr<DocumentLoader> FrameLoaderClientEfl::createDocumentLoader(const ResourceRequest& request, const SubstituteData& substituteData)
114{
115    RefPtr<DocumentLoader> loader = DocumentLoader::create(request, substituteData);
116    if (substituteData.isValid())
117        loader->setDeferMainResourceDataLoad(false);
118    return loader.release();
119}
120
121void FrameLoaderClientEfl::dispatchWillSubmitForm(FramePolicyFunction function, PassRefPtr<FormState>)
122{
123    // FIXME: This is surely too simple
124    ASSERT(function);
125    callPolicyFunction(function, PolicyUse);
126}
127
128void FrameLoaderClientEfl::committedLoad(DocumentLoader* loader, const char* data, int length)
129{
130    if (!m_pluginView) {
131        loader->commitData(data, length);
132
133        // Let the media document handle the rest of loading itself, cancel here.
134        Frame* coreFrame = loader->frame();
135        if (coreFrame && coreFrame->document()->isMediaDocument())
136            loader->cancelMainResourceLoad(pluginWillHandleLoadError(loader->response()));
137    }
138
139    // We re-check here as the plugin can have been created
140    if (m_pluginView) {
141        if (!m_hasSentResponseToPlugin) {
142            m_pluginView->didReceiveResponse(loader->response());
143            m_hasSentResponseToPlugin = true;
144        }
145        m_pluginView->didReceiveData(data, length);
146    }
147}
148
149void FrameLoaderClientEfl::dispatchDidReplaceStateWithinPage()
150{
151    notImplemented();
152}
153
154void FrameLoaderClientEfl::dispatchDidPushStateWithinPage()
155{
156    notImplemented();
157}
158
159void FrameLoaderClientEfl::dispatchDidPopStateWithinPage()
160{
161    notImplemented();
162}
163
164void FrameLoaderClientEfl::dispatchDidReceiveAuthenticationChallenge(DocumentLoader*, unsigned long /*identifier*/, const AuthenticationChallenge&)
165{
166    notImplemented();
167}
168
169void FrameLoaderClientEfl::dispatchDidCancelAuthenticationChallenge(DocumentLoader*, unsigned long /*identifier*/, const AuthenticationChallenge&)
170{
171    notImplemented();
172}
173
174void FrameLoaderClientEfl::dispatchWillSendRequest(DocumentLoader* loader, unsigned long identifier, ResourceRequest& coreRequest, const ResourceResponse& coreResponse)
175{
176    CString url = coreRequest.url().string().utf8();
177    CString firstParty = coreRequest.firstPartyForCookies().string().utf8();
178    CString httpMethod = coreRequest.httpMethod().utf8();
179    DBG("Resource url=%s, first_party=%s, http_method=%s", url.data(), firstParty.data(), httpMethod.data());
180
181    // We want to distinguish between a request for a document to be loaded into
182    // the main frame, a sub-frame, or the sub-objects in that document.
183    bool isMainFrameRequest = false;
184    if (loader) {
185            const FrameLoader* frameLoader = loader->frameLoader();
186            isMainFrameRequest = (loader == frameLoader->provisionalDocumentLoader() && frameLoader->isLoadingMainFrame());
187    }
188
189    Ewk_Frame_Resource_Request request = { 0, firstParty.data(), httpMethod.data(), identifier, m_frame, isMainFrameRequest };
190    Ewk_Frame_Resource_Request orig = request; /* Initialize const fields. */
191
192    orig.url = request.url = url.data();
193
194    Ewk_Frame_Resource_Response* redirectResponse;
195    Ewk_Frame_Resource_Response responseBuffer;
196    CString redirectUrl, mimeType;
197
198    if (coreResponse.isNull())
199        redirectResponse = 0;
200    else {
201        redirectUrl = coreResponse.url().string().utf8();
202        mimeType = coreResponse.mimeType().utf8();
203        responseBuffer.url = redirectUrl.data();
204        responseBuffer.status_code = coreResponse.httpStatusCode();
205        responseBuffer.identifier = identifier;
206        responseBuffer.mime_type = mimeType.data();
207        redirectResponse = &responseBuffer;
208    }
209
210    Ewk_Frame_Resource_Messages messages = { &request, redirectResponse };
211    ewk_frame_request_will_send(m_frame, &messages);
212    evas_object_smart_callback_call(m_view, "resource,request,willsend", &messages);
213
214    if (request.url != orig.url) {
215        coreRequest.setURL(KURL(KURL(), request.url));
216
217        // Calling client might have changed our url pointer.
218        // Free the new allocated string.
219        free(const_cast<char*>(request.url));
220    }
221}
222
223bool FrameLoaderClientEfl::shouldUseCredentialStorage(DocumentLoader*, unsigned long)
224{
225    notImplemented();
226    return false;
227}
228
229void FrameLoaderClientEfl::assignIdentifierToInitialRequest(unsigned long identifier, DocumentLoader* loader, const ResourceRequest& coreRequest)
230{
231    CString url = coreRequest.url().string().utf8();
232    CString firstParty = coreRequest.firstPartyForCookies().string().utf8();
233    CString httpMethod = coreRequest.httpMethod().utf8();
234    DBG("Resource url=%s, First party=%s, HTTP method=%s", url.data(), firstParty.data(), httpMethod.data());
235
236    bool isMainFrameRequest = false;
237    if (loader) {
238            const FrameLoader* frameLoader = loader->frameLoader();
239            isMainFrameRequest = (loader == frameLoader->provisionalDocumentLoader() && frameLoader->isLoadingMainFrame());
240    }
241
242    Ewk_Frame_Resource_Request request = { url.data(), firstParty.data(), httpMethod.data(), identifier, m_frame, isMainFrameRequest };
243    ewk_frame_request_assign_identifier(m_frame, &request);
244    evas_object_smart_callback_call(m_view, "resource,request,new", &request);
245}
246
247void FrameLoaderClientEfl::postProgressStartedNotification()
248{
249    ewk_frame_load_started(m_frame);
250    postProgressEstimateChangedNotification();
251}
252
253void FrameLoaderClientEfl::postProgressEstimateChangedNotification()
254{
255    ewk_frame_load_progress_changed(m_frame);
256}
257
258void FrameLoaderClientEfl::postProgressFinishedNotification()
259{
260    notImplemented();
261}
262
263void FrameLoaderClientEfl::frameLoaderDestroyed()
264{
265    if (m_frame)
266        ewk_frame_core_gone(m_frame);
267    m_frame = 0;
268
269    delete this;
270}
271
272void FrameLoaderClientEfl::dispatchDidReceiveResponse(DocumentLoader* loader, unsigned long identifier, const ResourceResponse& coreResponse)
273{
274    // Update our knowledge of request soup flags - some are only set
275    // after the request is done.
276    loader->request().setSoupMessageFlags(coreResponse.soupMessageFlags());
277
278    m_response = coreResponse;
279
280    CString mimeType = coreResponse.mimeType().utf8();
281    Ewk_Frame_Resource_Response response = { 0, coreResponse.httpStatusCode(), identifier, mimeType.data() };
282    CString url = coreResponse.url().string().utf8();
283    response.url = url.data();
284
285    ewk_frame_response_received(m_frame, &response);
286    evas_object_smart_callback_call(m_view, "resource,response,received", &response);
287}
288
289void FrameLoaderClientEfl::dispatchDecidePolicyForResponse(FramePolicyFunction function, const ResourceResponse& response, const ResourceRequest& resourceRequest)
290{
291    // we need to call directly here (currently callPolicyFunction does that!)
292    ASSERT(function);
293
294    if (resourceRequest.isNull()) {
295        callPolicyFunction(function, PolicyIgnore);
296        return;
297    }
298
299    // Ignore responses with an HTTP status code of 204 (No Content)
300    if (response.httpStatusCode() == HTTPNoContent) {
301        callPolicyFunction(function, PolicyIgnore);
302        return;
303    }
304
305    if (canShowMIMEType(response.mimeType()))
306        callPolicyFunction(function, PolicyUse);
307    else
308        callPolicyFunction(function, PolicyDownload);
309}
310
311void FrameLoaderClientEfl::dispatchDecidePolicyForNewWindowAction(FramePolicyFunction function, const NavigationAction&, const ResourceRequest& resourceRequest, PassRefPtr<FormState>, const String&)
312{
313    ASSERT(function);
314    ASSERT(m_frame);
315
316    if (resourceRequest.isNull()) {
317        callPolicyFunction(function, PolicyIgnore);
318        return;
319    }
320
321    // if not acceptNavigationRequest - look at Qt -> PolicyIgnore;
322    // FIXME: do proper check and only reset forms when on PolicyIgnore
323    Frame* f = EWKPrivate::coreFrame(m_frame);
324    f->loader()->resetMultipleFormSubmissionProtection();
325    callPolicyFunction(function, PolicyUse);
326}
327
328void FrameLoaderClientEfl::dispatchDecidePolicyForNavigationAction(FramePolicyFunction function, const NavigationAction& action, const ResourceRequest& resourceRequest, PassRefPtr<FormState>)
329{
330    ASSERT(function);
331    ASSERT(m_frame);
332
333    if (resourceRequest.isNull()) {
334        callPolicyFunction(function, PolicyIgnore);
335        return;
336    }
337
338    // if not acceptNavigationRequest - look at Qt -> PolicyIgnore;
339    // FIXME: do proper check and only reset forms when on PolicyIgnore
340    CString url = resourceRequest.url().string().utf8();
341    CString firstParty = resourceRequest.firstPartyForCookies().string().utf8();
342    CString httpMethod = resourceRequest.httpMethod().utf8();
343    Ewk_Frame_Resource_Request request = { url.data(), firstParty.data(), httpMethod.data(), 0, m_frame, false };
344    bool ret = ewk_view_navigation_policy_decision(m_view, &request, static_cast<Ewk_Navigation_Type>(action.type()));
345
346    PolicyAction policy;
347    if (!ret)
348        policy = PolicyIgnore;
349    else {
350        if (action.type() == NavigationTypeFormSubmitted || action.type() == NavigationTypeFormResubmitted) {
351            Frame* f = EWKPrivate::coreFrame(m_frame);
352            f->loader()->resetMultipleFormSubmissionProtection();
353        }
354        policy = PolicyUse;
355    }
356    callPolicyFunction(function, policy);
357}
358
359PassRefPtr<Widget> FrameLoaderClientEfl::createPlugin(const IntSize& pluginSize, HTMLPlugInElement* element, const KURL& url, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually)
360{
361    ASSERT(m_frame);
362    ASSERT(m_view);
363
364    return ewk_view_plugin_create(m_view, m_frame, pluginSize,
365                                  element, url, paramNames, paramValues,
366                                  mimeType, loadManually);
367}
368
369PassRefPtr<Frame> FrameLoaderClientEfl::createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement, const String& referrer, bool /*allowsScrolling*/, int /*marginWidth*/, int /*marginHeight*/)
370{
371    ASSERT(m_frame);
372    ASSERT(m_view);
373
374    return ewk_view_frame_create(m_view, m_frame, name, ownerElement, url, referrer);
375}
376
377void FrameLoaderClientEfl::redirectDataToPlugin(Widget* pluginWidget)
378{
379    m_pluginView = toPluginView(pluginWidget);
380    if (pluginWidget)
381        m_hasSentResponseToPlugin = false;
382}
383
384PassRefPtr<Widget> FrameLoaderClientEfl::createJavaAppletWidget(const IntSize&, HTMLAppletElement*, const KURL&,
385                                                                const Vector<String>& /*paramNames*/, const Vector<String>& /*paramValues*/)
386{
387    notImplemented();
388    return 0;
389}
390
391ObjectContentType FrameLoaderClientEfl::objectContentType(const KURL& url, const String& mimeType, bool shouldPreferPlugInsForImages)
392{
393    // FIXME: once plugin support is enabled, this method needs to correctly handle the 'shouldPreferPlugInsForImages' flag. See
394    // WebCore::FrameLoader::defaultObjectContentType() for an example.
395    UNUSED_PARAM(shouldPreferPlugInsForImages);
396
397    if (url.isEmpty() && mimeType.isEmpty())
398        return ObjectContentNone;
399
400    // We don't use MIMETypeRegistry::getMIMETypeForPath() because it returns "application/octet-stream" upon failure
401    String type = mimeType;
402    if (type.isEmpty())
403        type = MIMETypeRegistry::getMIMETypeForExtension(url.path().substring(url.path().reverseFind('.') + 1));
404
405    if (type.isEmpty())
406        return ObjectContentFrame;
407
408    if (MIMETypeRegistry::isSupportedImageMIMEType(type))
409        return ObjectContentImage;
410
411#if 0 // PluginDatabase is disabled until we have Plugin system done.
412    if (PluginDatabase::installedPlugins()->isMIMETypeRegistered(mimeType))
413        return ObjectContentNetscapePlugin;
414#endif
415
416    if (MIMETypeRegistry::isSupportedNonImageMIMEType(type))
417        return ObjectContentFrame;
418
419    if (url.protocol() == "about")
420        return ObjectContentFrame;
421
422    return ObjectContentNone;
423}
424
425String FrameLoaderClientEfl::overrideMediaType() const
426{
427    return String::fromUTF8(ewk_settings_css_media_type_get());
428}
429
430void FrameLoaderClientEfl::dispatchDidClearWindowObjectInWorld(DOMWrapperWorld* world)
431{
432    if (world != mainThreadNormalWorld())
433        return;
434
435    Frame* coreFrame = EWKPrivate::coreFrame(m_frame);
436    ASSERT(coreFrame);
437
438    Settings* settings = coreFrame->settings();
439    if (!settings || !settings->isScriptEnabled())
440        return;
441
442    Ewk_Window_Object_Cleared_Event event;
443    event.context = toGlobalRef(coreFrame->script()->globalObject(mainThreadNormalWorld())->globalExec());
444    event.windowObject = toRef(coreFrame->script()->globalObject(mainThreadNormalWorld()));
445    event.frame = m_frame;
446
447    evas_object_smart_callback_call(m_view, "window,object,cleared", &event);
448
449#if ENABLE(NETSCAPE_PLUGIN_API)
450    ewk_view_js_window_object_clear(m_view, m_frame);
451#endif
452}
453
454void FrameLoaderClientEfl::documentElementAvailable()
455{
456    return;
457}
458
459void FrameLoaderClientEfl::didPerformFirstNavigation() const
460{
461    ewk_frame_did_perform_first_navigation(m_frame);
462}
463
464void FrameLoaderClientEfl::registerForIconNotification(bool)
465{
466    notImplemented();
467}
468
469void FrameLoaderClientEfl::setMainFrameDocumentReady(bool)
470{
471    // this is only interesting once we provide an external API for the DOM
472}
473
474bool FrameLoaderClientEfl::hasWebView() const
475{
476    if (!m_view)
477        return false;
478
479    return true;
480}
481
482bool FrameLoaderClientEfl::hasFrameView() const
483{
484    notImplemented();
485    return true;
486}
487
488void FrameLoaderClientEfl::dispatchDidFinishLoad()
489{
490    ewk_frame_load_finished(m_frame, 0, 0, 0, 0, 0);
491}
492
493void FrameLoaderClientEfl::frameLoadCompleted()
494{
495    // Note: Can be called multiple times.
496}
497
498void FrameLoaderClientEfl::saveViewStateToItem(HistoryItem* item)
499{
500    ewk_frame_view_state_save(m_frame, item);
501}
502
503void FrameLoaderClientEfl::restoreViewState()
504{
505    ASSERT(m_frame);
506    ASSERT(m_view);
507
508    ewk_view_restore_state(m_view, m_frame);
509}
510
511void FrameLoaderClientEfl::updateGlobalHistoryRedirectLinks()
512{
513        WebCore::Frame* frame = EWKPrivate::coreFrame(m_frame);
514        if (!frame)
515            return;
516
517        WebCore::DocumentLoader* loader = frame->loader()->documentLoader();
518        if (!loader)
519            return;
520
521        if (!loader->clientRedirectSourceForHistory().isNull()) {
522            const CString& sourceURL = loader->clientRedirectSourceForHistory().utf8();
523            const CString& destinationURL = loader->clientRedirectDestinationForHistory().utf8();
524            Ewk_View_Redirection_Data data = { sourceURL.data(), destinationURL.data() };
525            evas_object_smart_callback_call(m_view, "perform,client,redirect", &data);
526        }
527
528        if (!loader->serverRedirectSourceForHistory().isNull()) {
529            const CString& sourceURL = loader->serverRedirectSourceForHistory().utf8();
530            const CString& destinationURL = loader->serverRedirectDestinationForHistory().utf8();
531            Ewk_View_Redirection_Data data = { sourceURL.data(), destinationURL.data() };
532            evas_object_smart_callback_call(m_view, "perform,server,redirect", &data);
533        }
534}
535
536bool FrameLoaderClientEfl::shouldGoToHistoryItem(HistoryItem* item) const
537{
538    // FIXME: This is a very simple implementation. More sophisticated
539    // implementation would delegate the decision to a PolicyDelegate.
540    // See mac implementation for example.
541    return item;
542}
543
544bool FrameLoaderClientEfl::shouldStopLoadingForHistoryItem(HistoryItem*) const
545{
546    return true;
547}
548
549void FrameLoaderClientEfl::didDisplayInsecureContent()
550{
551    ewk_frame_mixed_content_displayed_set(m_frame, true);
552}
553
554void FrameLoaderClientEfl::didRunInsecureContent(SecurityOrigin*, const KURL&)
555{
556    ewk_frame_mixed_content_run_set(m_frame, true);
557}
558
559void FrameLoaderClientEfl::didDetectXSS(const KURL& insecureURL, bool didBlockEntirePage)
560{
561    CString cs = insecureURL.string().utf8();
562    Ewk_Frame_Xss_Notification xssInfo = { cs.data(), didBlockEntirePage };
563
564    ewk_frame_xss_detected(m_frame, &xssInfo);
565}
566
567void FrameLoaderClientEfl::forceLayout()
568{
569    ewk_frame_force_layout(m_frame);
570}
571
572void FrameLoaderClientEfl::forceLayoutForNonHTML()
573{
574}
575
576void FrameLoaderClientEfl::setCopiesOnScroll()
577{
578    // apparently mac specific (Qt comment)
579}
580
581void FrameLoaderClientEfl::detachedFromParent2()
582{
583}
584
585void FrameLoaderClientEfl::detachedFromParent3()
586{
587}
588
589void FrameLoaderClientEfl::loadedFromCachedPage()
590{
591    notImplemented();
592}
593
594void FrameLoaderClientEfl::dispatchDidHandleOnloadEvents()
595{
596    ewk_view_onload_event(m_view, m_frame);
597}
598
599void FrameLoaderClientEfl::dispatchDidReceiveServerRedirectForProvisionalLoad()
600{
601    ewk_frame_redirect_provisional_load(m_frame);
602}
603
604void FrameLoaderClientEfl::dispatchDidCancelClientRedirect()
605{
606    ewk_frame_redirect_cancelled(m_frame);
607}
608
609void FrameLoaderClientEfl::dispatchWillPerformClientRedirect(const KURL& url, double, double)
610{
611    ewk_frame_redirect_requested(m_frame, url.string().utf8().data());
612}
613
614void FrameLoaderClientEfl::dispatchDidChangeLocationWithinPage()
615{
616    ewk_frame_uri_changed(m_frame);
617
618    if (!isLoadingMainFrame())
619        return;
620    ewk_view_uri_changed(m_view);
621}
622
623void FrameLoaderClientEfl::dispatchWillClose()
624{
625    notImplemented();
626}
627
628void FrameLoaderClientEfl::dispatchDidReceiveIcon()
629{
630    // IconController loads icons only for the main frame.
631    ASSERT(isLoadingMainFrame());
632
633    ewk_view_frame_main_icon_received(m_view);
634}
635
636void FrameLoaderClientEfl::dispatchDidStartProvisionalLoad()
637{
638    ewk_frame_load_provisional(m_frame);
639    if (isLoadingMainFrame())
640        ewk_view_load_provisional(m_view);
641}
642
643void FrameLoaderClientEfl::dispatchDidReceiveTitle(const StringWithDirection& title)
644{
645    Ewk_Text_With_Direction ewkTitle;
646    CString cs = title.string().utf8();
647    ewkTitle.string = cs.data();
648    ewkTitle.direction = (title.direction() == LTR) ? EWK_TEXT_DIRECTION_LEFT_TO_RIGHT : EWK_TEXT_DIRECTION_RIGHT_TO_LEFT;
649    ewk_frame_title_set(m_frame, &ewkTitle);
650
651    if (!isLoadingMainFrame())
652        return;
653    ewk_view_title_set(m_view, &ewkTitle);
654}
655
656void FrameLoaderClientEfl::dispatchDidChangeIcons(WebCore::IconType iconType)
657{
658    // Other touch types are apple-specific
659    ASSERT_UNUSED(iconType, iconType == WebCore::Favicon);
660    ewk_frame_icon_changed(m_frame);
661}
662
663void FrameLoaderClientEfl::dispatchDidCommitLoad()
664{
665    ewk_frame_uri_changed(m_frame);
666    ewk_frame_load_committed(m_frame);
667    if (!isLoadingMainFrame())
668        return;
669    ewk_view_title_set(m_view, 0);
670    ewk_view_uri_changed(m_view);
671}
672
673void FrameLoaderClientEfl::dispatchDidFinishDocumentLoad()
674{
675    ewk_frame_load_document_finished(m_frame);
676}
677
678void FrameLoaderClientEfl::dispatchDidLayout(LayoutMilestones milestones)
679{
680    if (milestones & DidFirstLayout)
681        ewk_frame_load_firstlayout_finished(m_frame);
682    if (milestones & DidFirstVisuallyNonEmptyLayout)
683        ewk_frame_load_firstlayout_nonempty_finished(m_frame);
684}
685
686void FrameLoaderClientEfl::dispatchShow()
687{
688    ewk_view_load_show(m_view);
689}
690
691void FrameLoaderClientEfl::cancelPolicyCheck()
692{
693    notImplemented();
694}
695
696void FrameLoaderClientEfl::willChangeTitle(DocumentLoader*)
697{
698    // no need for, dispatchDidReceiveTitle is the right callback
699}
700
701void FrameLoaderClientEfl::didChangeTitle(DocumentLoader*)
702{
703    // no need for, dispatchDidReceiveTitle is the right callback
704}
705
706bool FrameLoaderClientEfl::canHandleRequest(const ResourceRequest&) const
707{
708    notImplemented();
709    return true;
710}
711
712bool FrameLoaderClientEfl::canShowMIMETypeAsHTML(const String& /*MIMEType*/) const
713{
714    notImplemented();
715    return false;
716}
717
718bool FrameLoaderClientEfl::canShowMIMEType(const String& MIMEType) const
719{
720    if (MIMETypeRegistry::canShowMIMEType(MIMEType))
721        return true;
722
723#if 0 // PluginDatabase is disabled until we have Plugin system done.
724    if (PluginDatabase::installedPlugins()->isMIMETypeRegistered(MIMEType))
725        return true;
726#endif
727
728    return false;
729}
730
731bool FrameLoaderClientEfl::representationExistsForURLScheme(const String&) const
732{
733    return false;
734}
735
736String FrameLoaderClientEfl::generatedMIMETypeForURLScheme(const String&) const
737{
738    notImplemented();
739    return String();
740}
741
742void FrameLoaderClientEfl::finishedLoading(DocumentLoader*)
743{
744    if (!m_pluginView)
745        return;
746    m_pluginView->didFinishLoading();
747    m_pluginView = 0;
748    m_hasSentResponseToPlugin = false;
749}
750
751
752void FrameLoaderClientEfl::provisionalLoadStarted()
753{
754    notImplemented();
755}
756
757void FrameLoaderClientEfl::didFinishLoad()
758{
759    notImplemented();
760}
761
762void FrameLoaderClientEfl::prepareForDataSourceReplacement()
763{
764    notImplemented();
765}
766
767void FrameLoaderClientEfl::setTitle(const StringWithDirection&, const KURL&)
768{
769    // no need for, dispatchDidReceiveTitle is the right callback
770}
771
772void FrameLoaderClientEfl::dispatchDidReceiveContentLength(DocumentLoader*, unsigned long /*identifier*/, int /*dataLength*/)
773{
774    notImplemented();
775}
776
777void FrameLoaderClientEfl::dispatchDidFinishLoading(DocumentLoader*, unsigned long identifier)
778{
779    ewk_frame_load_resource_finished(m_frame, identifier);
780    evas_object_smart_callback_call(m_view, "load,resource,finished", &identifier);
781}
782
783void FrameLoaderClientEfl::dispatchDidFailLoading(DocumentLoader*, unsigned long identifier, const ResourceError& err)
784{
785    Ewk_Frame_Load_Error error;
786    CString errorDomain = err.domain().utf8();
787    CString errorDescription = err.localizedDescription().utf8();
788    CString failingUrl = err.failingURL().utf8();
789
790    DBG("ewkFrame=%p, resource=%ld, error=%s (%d, cancellation=%hhu) \"%s\", url=%s",
791        m_frame, identifier, errorDomain.data(), err.errorCode(), err.isCancellation(),
792        errorDescription.data(), failingUrl.data());
793
794    error.code = err.errorCode();
795    error.is_cancellation = err.isCancellation();
796    error.domain = errorDomain.data();
797    error.description = errorDescription.data();
798    error.failing_url = failingUrl.data();
799    error.resource_identifier = identifier;
800    error.frame = m_frame;
801
802    ewk_frame_load_resource_failed(m_frame, &error);
803    evas_object_smart_callback_call(m_view, "load,resource,failed", &error);
804}
805
806bool FrameLoaderClientEfl::dispatchDidLoadResourceFromMemoryCache(DocumentLoader*, const ResourceRequest&, const ResourceResponse&, int /*length*/)
807{
808    notImplemented();
809    return false;
810}
811
812void FrameLoaderClientEfl::dispatchDidLoadResourceByXMLHttpRequest(unsigned long, const String&)
813{
814    notImplemented();
815}
816
817void FrameLoaderClientEfl::dispatchDidFailProvisionalLoad(const ResourceError& err)
818{
819    Ewk_Frame_Load_Error error;
820    CString errorDomain = err.domain().utf8();
821    CString errorDescription = err.localizedDescription().utf8();
822    CString failingUrl = err.failingURL().utf8();
823
824    DBG("ewkFrame=%p, error=%s (%d, cancellation=%hhu) \"%s\", url=%s",
825        m_frame, errorDomain.data(), err.errorCode(), err.isCancellation(),
826        errorDescription.data(), failingUrl.data());
827
828    error.code = err.errorCode();
829    error.is_cancellation = err.isCancellation();
830    error.domain = errorDomain.data();
831    error.description = errorDescription.data();
832    error.failing_url = failingUrl.data();
833    error.resource_identifier = 0;
834    error.frame = m_frame;
835
836    ewk_frame_load_provisional_failed(m_frame, &error);
837    if (isLoadingMainFrame())
838        ewk_view_load_provisional_failed(m_view, &error);
839
840    dispatchDidFailLoad(err);
841}
842
843void FrameLoaderClientEfl::dispatchDidFailLoad(const ResourceError& err)
844{
845    ewk_frame_load_error(m_frame,
846                         err.domain().utf8().data(),
847                         err.errorCode(), err.isCancellation(),
848                         err.localizedDescription().utf8().data(),
849                         err.failingURL().utf8().data());
850
851    ewk_frame_load_finished(m_frame,
852                            err.domain().utf8().data(),
853                            err.errorCode(),
854                            err.isCancellation(),
855                            err.localizedDescription().utf8().data(),
856                            err.failingURL().utf8().data());
857}
858
859void FrameLoaderClientEfl::convertMainResourceLoadToDownload(DocumentLoader*, const ResourceRequest& request, const ResourceResponse&)
860{
861    if (!m_view)
862        return;
863
864    CString url = request.url().string().utf8();
865    Ewk_Download download;
866
867    download.url = url.data();
868    download.suggested_name = 0;
869    ewk_view_download_request(m_view, &download);
870}
871
872ResourceError FrameLoaderClientEfl::cancelledError(const ResourceRequest& request)
873{
874    return WebCore::cancelledError(request);
875}
876
877ResourceError FrameLoaderClientEfl::blockedError(const ResourceRequest& request)
878{
879    return WebCore::blockedError(request);
880}
881
882ResourceError FrameLoaderClientEfl::cannotShowURLError(const ResourceRequest& request)
883{
884    return WebCore::cannotShowURLError(request);
885}
886
887ResourceError FrameLoaderClientEfl::interruptedForPolicyChangeError(const ResourceRequest& request)
888{
889    return WebCore::interruptedForPolicyChangeError(request);
890}
891
892ResourceError FrameLoaderClientEfl::cannotShowMIMETypeError(const ResourceResponse& response)
893{
894    return WebCore::cannotShowMIMETypeError(response);
895}
896
897ResourceError FrameLoaderClientEfl::fileDoesNotExistError(const ResourceResponse& response)
898{
899    return WebCore::fileDoesNotExistError(response);
900}
901
902ResourceError FrameLoaderClientEfl::pluginWillHandleLoadError(const ResourceResponse& response)
903{
904    return WebCore::pluginWillHandleLoadError(response);
905}
906
907bool FrameLoaderClientEfl::shouldFallBack(const ResourceError& error)
908{
909    return !(error.isCancellation() || error.errorCode() == PolicyErrorFrameLoadInterruptedByPolicyChange || error.errorCode() == PluginErrorWillHandleLoad);
910}
911
912bool FrameLoaderClientEfl::canCachePage() const
913{
914    return true;
915}
916
917Frame* FrameLoaderClientEfl::dispatchCreatePage(const NavigationAction&)
918{
919    if (!m_view)
920        return 0;
921
922    Evas_Object* newView = ewk_view_window_create(m_view, EINA_FALSE, 0);
923    Evas_Object* mainFrame;
924    if (!newView)
925        mainFrame = m_frame;
926    else
927        mainFrame = ewk_view_frame_main_get(newView);
928
929    return EWKPrivate::coreFrame(mainFrame);
930}
931
932void FrameLoaderClientEfl::dispatchUnableToImplementPolicy(const ResourceError&)
933{
934    notImplemented();
935}
936
937void FrameLoaderClientEfl::setMainDocumentError(DocumentLoader*, const ResourceError& error)
938{
939    if (!m_pluginView)
940        return;
941    m_pluginView->didFail(error);
942    m_pluginView = 0;
943    m_hasSentResponseToPlugin = false;
944}
945
946void FrameLoaderClientEfl::startDownload(const ResourceRequest& request, const String& suggestedName)
947{
948    if (!m_view)
949        return;
950
951    CString url = request.url().string().utf8();
952    CString suggestedNameString = suggestedName.utf8();
953    Ewk_Download download;
954
955    download.url = url.data();
956    download.suggested_name = suggestedNameString.data();
957    ewk_view_download_request(m_view, &download);
958}
959
960void FrameLoaderClientEfl::updateGlobalHistory()
961{
962    WebCore::Frame* frame = EWKPrivate::coreFrame(m_frame);
963    if (!frame)
964        return;
965
966    WebCore::DocumentLoader* loader = frame->loader()->documentLoader();
967    if (!loader)
968        return;
969
970    const FrameLoader* frameLoader = loader->frameLoader();
971    const bool isMainFrameRequest = frameLoader && (loader == frameLoader->provisionalDocumentLoader()) && frameLoader->isLoadingMainFrame();
972    const CString& urlForHistory = loader->urlForHistory().string().utf8();
973    const CString& title = loader->title().string().utf8();
974    const CString& firstParty = loader->request().firstPartyForCookies().string().utf8();
975    const CString& clientRedirectSource = loader->clientRedirectSourceForHistory().utf8();
976    const CString& originalURL = loader->originalURL().string().utf8();
977    const CString& httpMethod = loader->request().httpMethod().utf8();
978    const CString& responseURL = loader->responseURL().string().utf8();
979    const CString& mimeType = loader->response().mimeType().utf8();
980
981    Ewk_Frame_Resource_Request request = { originalURL.data(), firstParty.data(), httpMethod.data(), 0, m_frame, isMainFrameRequest };
982    Ewk_Frame_Resource_Response response = { responseURL.data(), loader->response().httpStatusCode(), 0, mimeType.data() };
983    bool hasSubstituteData = loader->substituteData().isValid();
984
985    Ewk_View_Navigation_Data data = { urlForHistory.data(), title.data(), &request, &response, hasSubstituteData, clientRedirectSource.data() };
986
987    evas_object_smart_callback_call(m_view, "navigate,with,data", &data);
988}
989
990void FrameLoaderClientEfl::savePlatformDataToCachedFrame(CachedFrame*)
991{
992    notImplemented();
993}
994
995void FrameLoaderClientEfl::transitionToCommittedFromCachedFrame(CachedFrame*)
996{
997}
998
999void FrameLoaderClientEfl::transitionToCommittedForNewPage()
1000{
1001    ASSERT(m_frame);
1002    ASSERT(m_view);
1003
1004    ewk_frame_view_create_for_view(m_frame, m_view);
1005
1006    if (isLoadingMainFrame()) {
1007        ewk_view_frame_view_creation_notify(m_view);
1008        ewk_view_frame_main_cleared(m_view);
1009    }
1010}
1011
1012void FrameLoaderClientEfl::didSaveToPageCache()
1013{
1014}
1015
1016void FrameLoaderClientEfl::didRestoreFromPageCache()
1017{
1018}
1019
1020void FrameLoaderClientEfl::dispatchDidBecomeFrameset(bool)
1021{
1022}
1023
1024PassRefPtr<FrameNetworkingContext> FrameLoaderClientEfl::createNetworkingContext()
1025{
1026    return FrameNetworkingContextEfl::create(EWKPrivate::coreFrame(m_frame), m_frame);
1027}
1028
1029}
1030