webengine/osswebengine/WebKit/s60/webview/WebFrame.cpp
changeset 0 dd21522fd290
child 8 7c90e6132015
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/webengine/osswebengine/WebKit/s60/webview/WebFrame.cpp	Mon Mar 30 12:54:55 2009 +0300
@@ -0,0 +1,617 @@
+/*
+* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:   Frame in webkit side
+*
+*/
+
+
+#include "config.h"
+#include "../../bidi.h"
+#include "WebFrame.h"
+#include "WebCoreWidget.h"
+#include "WebCoreFrameBridge.h"
+#include "WebFrameBridge.h"
+#include "WebFrameView.h"
+#include "WebView.h"
+#include "WebChromeClient.h"
+#include "WebFrameLoaderClient.h"
+
+#include "Page.h"
+#include "Frame.h"
+#include "FrameView.h"
+#include "FrameTree.h"
+#include "FrameLoader.h"
+#include "DocumentLoader.h"
+#include "SelectionController.h"
+#include "SubstituteData.h"
+#include "RenderWidget.h"
+
+#include "HTMLNames.h"
+#include "GraphicsContext.h"
+#include "HTMLFormElement.h"
+#include "ResourceRequest.h"
+#include "webkitlogger.h"
+#include "webutil.h"
+#include "PluginSkin.h"
+#include "kjs_proxy.h"
+#if PLATFORM(SYMBIAN)
+#include "oom.h"
+#endif
+
+using namespace WebCore;
+using namespace HTMLNames;
+
+WebFrame::WebFrame() :
+    m_view(0)
+   ,m_bridge(0)
+{
+}
+
+WebFrame::~WebFrame() 
+{
+    if (m_view)
+        m_view->deref();
+}
+
+void WebFrame::initWithWebFrameView(WebFrameView* view, WebView* topView, WebFrameBridge* bridge)
+{
+    if (m_view)
+        m_view->deref();
+    m_view = view;
+    if (m_view) {
+        m_view->ref();
+        m_view->setWebFrame(this);
+        m_view->setTopView(topView);
+    }
+    setBridge(bridge);
+}
+
+void WebFrame::loadRequest(const WebCore::ResourceRequest& request,const WebCore::String* windowType)
+{
+    FrameLoader* fl = frameLoader();
+    if (fl) {
+        if(windowType)
+            fl->load(request,*windowType);
+        else
+            fl->load(request);
+    }
+        
+ }
+
+void WebFrame::loadData(const WebCore::ResourceRequest& request, WebCore::SubstituteData& substituteData)
+{
+    if (FrameLoader* fl = frameLoader())
+        fl->load(request, substituteData);
+}
+
+void WebFrame::loadURL(const TDesC8& url, TInt cachemode, const String& referrer,const WebCore::String* windowType) 
+{
+#if PLATFORM(SYMBIAN)
+    OOM_PRE_CHECK(1024*1024, 0, "WebFrame::loadURL")
+#endif
+    ResourceRequestCachePolicy cachePolicy;
+    switch (cachemode) 
+    {
+    default:
+    case TBrCtlDefs::ECacheModeNormal: 
+        cachePolicy = UseProtocolCachePolicy;
+        break;
+    case TBrCtlDefs::ECacheModeNoCache:
+        cachePolicy = ReloadIgnoringCacheData;
+        break;
+    case TBrCtlDefs::ECacheModeHistory:
+        cachePolicy = ReturnCacheDataElseLoad;
+        break;
+    case TBrCtlDefs::ECacheModeOnlyCache:
+        cachePolicy = ReturnCacheDataDontLoad;
+        break;
+    }
+    ResourceRequest request = (KURL(url));
+    request.setMainLoad(true);
+    request.setCachePolicy(cachePolicy);
+    if(!referrer.isNull())
+        request.setHTTPReferrer(referrer);
+    request.setHTTPMethod("GET");
+    loadRequest(request,windowType);
+#if PLATFORM(SYMBIAN)
+    OOM_POST_CHECK_FAILED(return;)
+#endif    
+}
+
+// Called by the bridge to load into a sub-frmae
+void WebFrame::loadURL(const TPtrC8 url, const TPtrC referrer, WebFrame* childFrame)
+{
+    /* fixme tot: do we need to hook up with bf list?
+    HistoryItem* parentItem = core(this)->loader()->currentHistoryItem();
+    FrameLoadType loadType = _frameLoader()->loadType();
+    FrameLoadType childLoadType = FrameLoadTypeRedirectWithLockedHistory;
+
+    if (parentItem && parentItem->children().size() && 
+        (isBackForwardLoadType(loadType) 
+        || loadType == FrameLoadTypeReload 
+        || loadType == FrameLoadTypeReloadAllowingStaleData)) 
+    {
+        HistoryItem* childItem = parentItem->childItemWithName(childFrame->name());
+        if (childItem) {
+            childLoadType = loadType;
+
+            if (isBackForwardLoadType(loadType))
+                core(childFrame)->loader()->setProvisionalHistoryItem(childItem);
+            else
+                core(childFrame)->loader()->setCurrentHistoryItem(childItem);
+        }
+    }*/
+
+    // tot fixme: saved pages not implemented.
+    FrameLoadType childLoadType = frameLoader()->loadType();
+    childFrame->frameLoader()->load(url, referrer, childLoadType, String(), 0, 0);
+}
+
+void WebFrame::paintRect(WebCoreGraphicsContext& gc, const TRect& rect)
+{
+    WebCore::GraphicsContext ctx(&gc);
+    core(this)->paint(&ctx, enclosingIntRect(rect));
+}
+
+FrameLoader* WebFrame::frameLoader()
+{
+    Frame* frame = core(this);
+    return frame ? frame->loader() : 0;
+}
+
+bool WebFrame::isMainFrame() const
+{
+    Frame* coreFrame = core(this);
+    if (!coreFrame)
+        return false;
+    return coreFrame == coreFrame->page()->mainFrame();
+}
+
+// selection
+bool WebFrame::hasSelection()
+{
+    if (Frame* coreFrame = core(this)) {
+        return !coreFrame->selectionController()->isNone();
+    }
+    return false;
+}
+
+void WebFrame::clearSelection()
+{
+    Frame* coreFrame = core(this);
+    if (!coreFrame)
+        return;
+    coreFrame->selectionController()->clear();
+}
+
+WebFrame* WebFrame::findFrameWithSelection()
+{
+    Frame* coreFrame = core(this);
+    for (Frame* frame = coreFrame; frame; frame = frame->tree()->traverseNext(coreFrame))
+        if (kit(frame)->hasSelection())
+            return kit(frame);
+    
+    return 0;
+}
+
+void WebFrame::stopLoading()
+{
+    if (FrameLoader* fl = frameLoader())
+        fl->stopForUserCancel();
+}
+
+void WebFrame::reload()
+{
+    frameLoader()->reload();
+}
+
+WebFrame* WebFrame::findFrameNamed(const TPtr& name)
+{
+    Frame* coreFrame = core(this);
+    if (!coreFrame)
+        return 0;
+    return kit(coreFrame->tree()->find(name));
+}
+
+WebFrame* WebFrame::parentFrame()
+{
+    Frame* coreFrame = core(this);
+    if (!coreFrame) 
+        return 0;
+    return kit(coreFrame->tree()->parent());
+}
+
+bool WebFrame::isIframe() const
+{
+    Frame* coreFrame = core(this);
+    if (!coreFrame)
+        return false;
+    Frame* pf = coreFrame->tree()->parent();
+    if (pf)
+        return !pf->isFrameSet();
+    return false;
+}
+
+bool WebFrame::isFrameSet() const
+{
+    Frame* coreFrame = core(this);
+    if (!coreFrame)
+        return false;
+    return coreFrame->isFrameSet();
+}
+
+WTF::Vector<WebFrame*> WebFrame::childFrames()
+{
+    Frame* coreFrame = core(this);
+    if (!coreFrame)
+        return WTF::Vector<WebFrame*>();
+
+    WTF::Vector<WebFrame*> children;
+    children.reserveCapacity(coreFrame->tree()->childCount());
+    for (Frame* child = coreFrame->tree()->firstChild(); child; child = child->tree()->nextSibling())
+        children.append(kit(child));
+    return children;
+}
+
+void WebFrame::addChild(WebFrame* child)
+{
+    core(this)->tree()->appendChild(adoptRef(core(child)));
+    if (child->documentLoader())
+        child->documentLoader()->setOverrideEncoding(documentLoader()->overrideEncoding());
+
+    // update the view heirachy
+    m_view->addChild(child->frameView());
+}
+
+DocumentLoader* WebFrame::documentLoader()
+{
+    return frameLoader()->documentLoader();
+}
+
+void WebFrame::notifyPluginsOfScrolling()
+{
+    Frame* coreFrame = core(this);
+    for (Frame* frame = coreFrame; frame; frame = frame->tree()->traverseNext(coreFrame)) {
+        PassRefPtr<HTMLCollection> objects = frame->document()->objects();       
+        for (Node* n = objects->firstItem(); n; n = objects->nextItem()) 
+            notifyPluginOfScrolling(n->renderer());             
+
+        PassRefPtr<HTMLCollection> embeds = frame->document()->embeds();       
+        for (Node* n = embeds->firstItem(); n; n = embeds->nextItem()) 
+            notifyPluginOfScrolling(n->renderer()); 
+
+        }
+}
+
+void WebFrame::notifyPluginOfScrolling(RenderObject* renderer)
+{        
+    MWebCoreObjectWidget* view = widget(renderer);
+    //Don't repaint the plugin objects if Browser is in PageView mode
+    if (view) {
+        view->positionChanged();
+        TRect r = m_view->toDocCoords(static_cast<PluginSkin*>(view)->getPluginWinRect());
+        m_view->topView()->scheduleRepaint(r);
+    }
+}
+
+PluginSkin* WebFrame::focusedPlugin()
+{
+    int pluginCount = 0;
+    Frame* coreFrame = core(this);
+    MWebCoreObjectWidget* view = NULL;
+    MWebCoreObjectWidget* tmpView = NULL;
+
+    for (Frame* frame = coreFrame; frame; frame = frame->tree()->traverseNext(coreFrame)) {
+        PassRefPtr<HTMLCollection> objects = frame->document()->objects();     
+        for (Node* n = objects->firstItem(); n; n = objects->nextItem()) {
+            tmpView = widget(n); 
+            if (tmpView) {
+                pluginCount++;
+                view = tmpView;
+                if (view->isActive()) {
+                    return static_cast<PluginSkin*>(view);
+                }
+            }
+        }
+
+        PassRefPtr<HTMLCollection> embeds = frame->document()->embeds();       
+        for (Node* n = embeds->firstItem(); n; n = embeds->nextItem()) {
+            tmpView = widget(n);
+            if (tmpView) { 
+                pluginCount++;
+                view = tmpView;
+                if (view->isActive()) {
+                    return static_cast<PluginSkin*>(view);
+                }
+            }
+        }
+    }
+    //no focused plugin. If only one plugin is present return that plugin
+    if(pluginCount == 1 && view) {
+        return static_cast<PluginSkin*>(view);           
+    } //endof pluginCount = 1
+
+    return NULL;    
+}
+
+void WebFrame::setFrameView(WebFrameView* v) 
+{
+    if (m_view)
+        m_view->deref();
+    m_view = v;
+    if (m_view)
+        m_view->ref();
+}
+
+void WebFrame::setBridge(WebFrameBridge* b)
+{
+    if (m_bridge) 
+        m_bridge->deref();
+    m_bridge = b;
+    if (m_bridge) 
+        m_bridge->ref();
+}
+
+WebFrame* WebFrame::frameAtPoint(const TPoint& pt_)
+{
+    WTF::Vector<WebFrame*> ch = childFrames();
+    WebFrame* frm = 0;
+    // Check the children of the frame only if this frame also contains pt_
+    // If a child iframe is bigger than the parent, it should not be picked.
+    if (m_view->rectInGlobalCoords().Contains(pt_)) {
+        Vector<WebFrame*>::iterator end = ch.end();
+        for (Vector<WebFrame*>::iterator itr = ch.begin(); itr != end; itr++) {
+            WebFrame* f = (*itr);
+            if( (f = f->frameAtPoint(pt_ + m_view->toViewCoords(m_view->contentPos()))) != 0 )
+                {
+                // TODO: this only fixes www.aol.com login iframe issue,
+                // a better solution is to check the z-index for each frame.
+                // Anyway, overlapping iframes are not common.
+                frm = f;
+                }
+        }
+
+        if (frm)
+            return frm;
+
+
+        return this;
+    }
+    return 0;
+}
+
+int WebFrame::imageCount(bool visibleOnly_) 
+{   
+    int imageCount = imageCountInFrame(*this, visibleOnly_);
+    //
+    WTF::Vector<WebFrame*> ch = childFrames();
+    WebFrame* frm = 0;
+    
+    Vector<WebFrame*>::iterator end = ch.end();
+    for (Vector<WebFrame*>::iterator itr = ch.begin(); itr != end; itr++)
+        imageCount+=(*itr)->imageCount(visibleOnly_);
+        
+    return imageCount;
+}
+
+CArrayFixFlat<TBrCtlImageCarrier>* WebFrame::imageData(bool visibleOnly_) 
+{   
+    CArrayFixFlat<TBrCtlImageCarrier>* imageList = imagesInFrame(*this, visibleOnly_);
+    //
+    WTF::Vector<WebFrame*> ch = childFrames();
+    WebFrame* frm = 0;
+    
+    Vector<WebFrame*>::iterator end = ch.end();
+    for (Vector<WebFrame*>::iterator itr = ch.begin(); itr != end; itr++) {
+        CArrayFixFlat<TBrCtlImageCarrier>* childImageList = (*itr)->imageData(visibleOnly_);
+        for (int i = 0; i < childImageList->Count(); i++)
+            imageList->AppendL(childImageList->At(i));
+        childImageList->Reset();
+        delete childImageList;
+    }
+       
+    return imageList;
+}
+
+CArrayFixFlat<TBrCtlSubscribeTo>* WebFrame::findSubscribeTo() 
+{   
+    CArrayFixFlat<TBrCtlSubscribeTo>* linkList = findSubscribeToInFrame(*this);
+    //
+    WTF::Vector<WebFrame*> ch = childFrames();
+    WebFrame* frm = 0;
+    
+    Vector<WebFrame*>::iterator end = ch.end();
+    for (Vector<WebFrame*>::iterator itr = ch.begin(); itr != end; itr++) {
+        CArrayFixFlat<TBrCtlSubscribeTo>* childLinkList = (*itr)->findSubscribeTo();
+        for (int i = 0; i < childLinkList->Count(); i++)
+            linkList->AppendL(childLinkList->At(i));
+        childLinkList->Reset();
+        delete childLinkList;
+    }
+    return linkList;
+}
+
+DOMDocument* WebFrame::DOMDocument()
+{
+    return 0;
+}
+
+void WebFrame::scalingFactorChanged(int factor)
+{
+    bridge()->scalingFactorChanged(factor);
+}
+
+// helpers
+Frame* core(const WebFrame* frame)
+{
+    if (!frame)
+        return NULL;
+    
+    if (!frame->bridge())
+        return NULL;
+
+    return frame->bridge()->frame();
+}
+
+WebFrame* kit(Frame* frame)
+{
+    return frame ? ((WebFrameBridge *)frame->bridge())->webFrame(): NULL;
+}
+
+WebView *kit(Page* page)
+{
+    return page ? static_cast<WebChromeClient*>(page->chrome()->client())->webView() : 0;
+}
+
+WebFrame* mainFrame(WebFrame* frame) 
+{
+    if (!frame)
+        return 0;
+    if (frame->isMainFrame())
+        return frame;
+    
+    Frame* coreFrame = core(frame);
+    if (!coreFrame)
+        return 0;
+    return kit(coreFrame->page()->mainFrame());
+}
+
+CBrCtl* control(WebCore::Frame* frame) 
+{
+    return control(kit(frame));
+}
+
+CBrCtl* control(const WebFrame* webFrame)
+{
+    if (webFrame && webFrame->frameView())
+        return webFrame->frameView()->topView()->brCtl();
+    return NULL;
+}
+
+MWebCoreObjectWidget* widget(RenderObject* render_) 
+{   
+    if (!render_)
+        return NULL;
+        
+    if (render_->isWidget()) {
+        Widget* widget = static_cast<RenderWidget*>(render_)->widget();
+        if (widget) {
+            MWebCoreWidget* view = widget->getView();    
+            if(view && view->isObjectView())
+                return static_cast<MWebCoreObjectWidget*>(view);
+        }
+    }
+    return NULL;    
+}
+
+
+MWebCoreObjectWidget* widget(Node* node_) 
+{   
+    if (!node_)
+        return NULL;
+        
+    return widget(node_->renderer());
+}
+
+bool WebFrame::executeScript(const WebCore::String& script)
+{
+    bool result = false;
+    KJSProxy *proxy = core(this)->scriptProxy();
+    if (proxy) {
+        KJS::JSValue *v = proxy->evaluate(String(), 0, script);
+        if (v)
+            result = true;
+    }
+    return result;
+}
+
+void WebFrame::makeVisiblePlugins(TBool visible)
+{
+    MWebCoreObjectWidget* view = NULL;
+    int pluginCount = 0;
+    Frame* coreFrame = core(this);
+    PluginSkin* ptr = 0;
+    for (Frame* frame = coreFrame; frame; frame = frame->tree()->traverseNext(coreFrame)) {
+
+        PassRefPtr<HTMLCollection> objects = frame->document()->objects();     
+        for (Node* n = objects->firstItem(); n; n = objects->nextItem()) {
+            view = widget(n); 
+            if (view) {
+                ptr = static_cast<PluginSkin*>(view);
+                ptr->makeVisible(visible);
+            }
+        }
+        PassRefPtr<HTMLCollection> embeds = frame->document()->embeds();       
+        for (Node* n = embeds->firstItem(); n; n = embeds->nextItem()) {
+            view = widget(n);
+            if (view) {
+                ptr = static_cast<PluginSkin*>(view);
+                ptr->makeVisible(visible);
+            }
+        }
+    }
+}
+
+
+inline int xInRect(const IntRect& r, int x)
+{
+	return std::min(std::max(x, r.location().x()), r.location().x() + r.width());
+}
+
+inline int yInRect(const IntRect& r, int y)
+{
+	return std::min(std::max(y, r.location().y()), r.location().y() + r.height());
+}
+
+Node* WebFrame::getClosestAnchorElement(const TPoint& viewPt, TPoint& newPos)
+{
+    IntPoint pt = m_view->viewCoordsInFrameCoords(viewPt);
+    
+    Frame* coreFrame = core(this);
+
+	int dist = 99999999;
+	Node* result = 0;
+	//for (Node* n=links->firstItem(); n; n=links->nextItem()) {
+	for(Node* n = coreFrame->document(); n != 0; n = n->traverseNextNode()) {
+        if(n->isFocusable() || n->hasTagName(areaTag)) {
+			IntRect r = n->getRect();
+			if (r.contains(pt)) {
+				dist = 0;
+				result = n;
+				break;
+			}
+			
+			int x = xInRect(r, pt.x());
+			int y = yInRect(r, pt.y());
+			int d = (pt.x() - x) * (pt.x() - x) + (pt.y() - y) * (pt.y() - y);
+			if (dist > d) {
+				dist = d;
+				result = n;
+			}
+        }
+	}
+	
+    // check if we are close enough and calcualte with zoom factor. 
+    if (dist< (400/m_view->topView()->scalingFactor() * 100)) {
+        IntRect r = result->getRect();
+        r.inflate(-2);
+        TPoint docPos(xInRect(r, pt.x()), yInRect(r, pt.y()));
+        newPos = m_view->frameCoordsInViewCoords(docPos);
+        return result;        
+    }
+    
+    return 0;
+}
+
+// END OF FILE