diff -r 000000000000 -r dd21522fd290 webengine/osswebengine/WebKit/s60/webview/WebFrame.cpp --- /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::childFrames() +{ + Frame* coreFrame = core(this); + if (!coreFrame) + return WTF::Vector(); + + WTF::Vector 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 objects = frame->document()->objects(); + for (Node* n = objects->firstItem(); n; n = objects->nextItem()) + notifyPluginOfScrolling(n->renderer()); + + PassRefPtr 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(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 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(view); + } + } + } + + PassRefPtr 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(view); + } + } + } + } + //no focused plugin. If only one plugin is present return that plugin + if(pluginCount == 1 && view) { + return static_cast(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 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::iterator end = ch.end(); + for (Vector::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 ch = childFrames(); + WebFrame* frm = 0; + + Vector::iterator end = ch.end(); + for (Vector::iterator itr = ch.begin(); itr != end; itr++) + imageCount+=(*itr)->imageCount(visibleOnly_); + + return imageCount; +} + +CArrayFixFlat* WebFrame::imageData(bool visibleOnly_) +{ + CArrayFixFlat* imageList = imagesInFrame(*this, visibleOnly_); + // + WTF::Vector ch = childFrames(); + WebFrame* frm = 0; + + Vector::iterator end = ch.end(); + for (Vector::iterator itr = ch.begin(); itr != end; itr++) { + CArrayFixFlat* childImageList = (*itr)->imageData(visibleOnly_); + for (int i = 0; i < childImageList->Count(); i++) + imageList->AppendL(childImageList->At(i)); + childImageList->Reset(); + delete childImageList; + } + + return imageList; +} + +CArrayFixFlat* WebFrame::findSubscribeTo() +{ + CArrayFixFlat* linkList = findSubscribeToInFrame(*this); + // + WTF::Vector ch = childFrames(); + WebFrame* frm = 0; + + Vector::iterator end = ch.end(); + for (Vector::iterator itr = ch.begin(); itr != end; itr++) { + CArrayFixFlat* 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(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(render_)->widget(); + if (widget) { + MWebCoreWidget* view = widget->getView(); + if(view && view->isObjectView()) + return static_cast(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 objects = frame->document()->objects(); + for (Node* n = objects->firstItem(); n; n = objects->nextItem()) { + view = widget(n); + if (view) { + ptr = static_cast(view); + ptr->makeVisible(visible); + } + } + PassRefPtr embeds = frame->document()->embeds(); + for (Node* n = embeds->firstItem(); n; n = embeds->nextItem()) { + view = widget(n); + if (view) { + ptr = static_cast(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