#include "config.h"
#include "qwebframe.h"
#if USE(JSC)
#include "BridgeJSC.h"
#include "CallFrame.h"
#elif USE(V8)
#include "V8Binding.h"
#endif
#include "Document.h"
#include "DocumentLoader.h"
#include "DragData.h"
#include "Element.h"
#include "FocusController.h"
#include "Frame.h"
#include "FrameLoaderClientQt.h"
#include "FrameSelection.h"
#include "FrameTree.h"
#include "FrameView.h"
#if USE(JSC)
#include "GCController.h"
#elif USE(V8)
#include "V8GCController.h"
#endif
#include "GraphicsContext.h"
#include "HTMLMetaElement.h"
#include "HitTestResult.h"
#include "HTTPParsers.h"
#include "IconDatabase.h"
#include "InspectorController.h"
#if USE(JSC)
#include "JSDOMBinding.h"
#include "JSDOMWindowBase.h"
#include "JSLock.h"
#include "JSObject.h"
#elif USE(V8)
#include "V8DOMWrapper.h"
#include "V8DOMWindowShell.h"
#endif
#include "NetworkingContext.h"
#include "NodeList.h"
#include "Page.h"
#include "PlatformMouseEvent.h"
#include "PlatformWheelEvent.h"
#include "PrintContext.h"
#if USE(JSC)
#include "PutPropertySlot.h"
#endif
#include "RenderLayer.h"
#include "RenderTreeAsText.h"
#include "RenderView.h"
#include "ResourceRequest.h"
#include "ScriptController.h"
#include "ScriptSourceCode.h"
#include "ScriptValue.h"
#include "Scrollbar.h"
#include "Settings.h"
#include "SubstituteData.h"
#include "SVGSMILElement.h"
#include "TiledBackingStore.h"
#include "htmlediting.h"
#include "markup.h"
#if USE(JSC)
#include "qt_instance.h"
#include "qt_runtime.h"
#endif
#include "qwebelement.h"
#include "qwebframe_p.h"
#include "qwebpage.h"
#include "qwebpage_p.h"
#include "qwebsecurityorigin.h"
#include "qwebsecurityorigin_p.h"
#include "qwebscriptworld.h"
#include "qwebscriptworld_p.h"
#if USE(JSC)
#include "runtime_object.h"
#include "runtime_root.h"
#endif
#if USE(TEXTURE_MAPPER)
#include "texmap/TextureMapper.h"
#include "texmap/TextureMapperNode.h"
#endif
#include "wtf/HashMap.h"
#include <QMultiMap>
#include <qdebug.h>
#include <qevent.h>
#include <qfileinfo.h>
#include <qpainter.h>
#include <qprinter.h>
#include <qregion.h>
#include <qnetworkrequest.h>
using namespace WebCore;
QT_BEGIN_NAMESPACE
extern Q_GUI_EXPORT int qt_defaultDpi();
QT_END_NAMESPACE
bool QWEBKIT_EXPORT qtwebkit_webframe_scrollOverflow(QWebFrame* qFrame, int dx, int dy, const QPoint& pos)
{
WebCore::Frame* frame = QWebFramePrivate::core(qFrame);
if (!frame || !frame->document() || !frame->view() || !frame->eventHandler())
return false;
QPoint contentsPos = frame->view()->windowToContents(pos);
Node* node = frame->document()->elementFromPoint(contentsPos.x(), contentsPos.y());
if (!node)
return false;
RenderObject* renderer = node->renderer();
if (!renderer)
return false;
if (renderer->isListBox())
return false;
RenderLayer* renderLayer = renderer->enclosingLayer();
if (!renderLayer)
return false;
bool scrolledHorizontal = false;
bool scrolledVertical = false;
do {
if (dx > 0)
scrolledHorizontal = renderLayer->scroll(ScrollRight, ScrollByPixel, dx);
else if (dx < 0)
scrolledHorizontal = renderLayer->scroll(ScrollLeft, ScrollByPixel, qAbs(dx));
if (dy > 0)
scrolledVertical = renderLayer->scroll(ScrollDown, ScrollByPixel, dy);
else if (dy < 0)
scrolledVertical = renderLayer->scroll(ScrollUp, ScrollByPixel, qAbs(dy));
if (scrolledHorizontal || scrolledVertical)
return true;
renderLayer = renderLayer->parent();
} while (renderLayer);
return false;
}
void QWEBKIT_EXPORT qtwebkit_webframe_scrollRecursively(QWebFrame* qFrame, int dx, int dy, const QPoint& pos)
{
if (!qFrame)
return;
if (qtwebkit_webframe_scrollOverflow(qFrame, dx, dy, pos))
return;
bool scrollHorizontal = false;
bool scrollVertical = false;
do {
if (dx > 0) scrollHorizontal = qFrame->scrollBarValue(Qt::Horizontal) < qFrame->scrollBarMaximum(Qt::Horizontal);
else if (dx < 0) scrollHorizontal = qFrame->scrollBarValue(Qt::Horizontal) > qFrame->scrollBarMinimum(Qt::Horizontal);
if (dy > 0) scrollVertical = qFrame->scrollBarValue(Qt::Vertical) < qFrame->scrollBarMaximum(Qt::Vertical);
else if (dy < 0) scrollVertical = qFrame->scrollBarValue(Qt::Vertical) > qFrame->scrollBarMinimum(Qt::Vertical);
if (scrollHorizontal || scrollVertical) {
qFrame->scroll(dx, dy);
return;
}
qFrame = qFrame->parentFrame();
} while (qFrame);
}
static inline ResourceRequestCachePolicy cacheLoadControlToCachePolicy(uint cacheLoadControl)
{
switch (cacheLoadControl) {
case QNetworkRequest::AlwaysNetwork:
return WebCore::ReloadIgnoringCacheData;
case QNetworkRequest::PreferCache:
return WebCore::ReturnCacheDataElseLoad;
case QNetworkRequest::AlwaysCache:
return WebCore::ReturnCacheDataDontLoad;
default:
break;
}
return WebCore::UseProtocolCachePolicy;
}
QWebFrameData::QWebFrameData(WebCore::Page* parentPage, WebCore::Frame* parentFrame,
WebCore::HTMLFrameOwnerElement* ownerFrameElement,
const WTF::String& frameName)
: name(frameName)
, ownerElement(ownerFrameElement)
, page(parentPage)
, allowsScrolling(true)
, marginWidth(0)
, marginHeight(0)
{
frameLoaderClient = new FrameLoaderClientQt();
frame = Frame::create(page, ownerElement, frameLoaderClient);
frame->tree()->setName(name);
if (parentFrame)
parentFrame->tree()->appendChild(frame);
}
void QWebFramePrivate::init(QWebFrame *qframe, QWebFrameData *frameData)
{
q = qframe;
allowsScrolling = frameData->allowsScrolling;
marginWidth = frameData->marginWidth;
marginHeight = frameData->marginHeight;
frame = frameData->frame.get();
frameLoaderClient = frameData->frameLoaderClient;
frameLoaderClient->setFrame(qframe, frame);
frame->init();
}
void QWebFramePrivate::setPage(QWebPage* newPage)
{
if (page == newPage)
return;
if (q->parent() == qobject_cast<QObject*>(page))
q->setParent(newPage);
page = newPage;
emit q->pageChanged();
}
WebCore::Scrollbar* QWebFramePrivate::horizontalScrollBar() const
{
if (!frame->view())
return 0;
return frame->view()->horizontalScrollbar();
}
WebCore::Scrollbar* QWebFramePrivate::verticalScrollBar() const
{
if (!frame->view())
return 0;
return frame->view()->verticalScrollbar();
}
#if ENABLE(TILED_BACKING_STORE)
void QWebFramePrivate::renderFromTiledBackingStore(GraphicsContext* context, const QRegion& clip)
{
ASSERT(frame->tiledBackingStore());
if (!frame->view() || !frame->contentRenderer())
return;
QVector<QRect> vector = clip.rects();
if (vector.isEmpty())
return;
QPainter* painter = context->platformContext();
WebCore::FrameView* view = frame->view();
int scrollX = view->scrollX();
int scrollY = view->scrollY();
context->translate(-scrollX, -scrollY);
for (int i = 0; i < vector.size(); ++i) {
const QRect& clipRect = vector.at(i);
painter->save();
QRect rect = clipRect.translated(scrollX, scrollY);
painter->setClipRect(rect, Qt::IntersectClip);
frame->tiledBackingStore()->paint(context, rect);
painter->restore();
}
#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER)
renderCompositedLayers(context, IntRect(clip.boundingRect()));
renderFrameExtras(context, QFlags<QWebFrame::RenderLayer>(QWebFrame::ScrollBarLayer) | QWebFrame::PanIconLayer, clip);
#endif
}
#endif
#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER)
void QWebFramePrivate::renderCompositedLayers(GraphicsContext* context, const IntRect& clip)
{
if (!rootTextureMapperNode || !textureMapper)
return;
textureMapper->setGraphicsContext(context);
textureMapper->setImageInterpolationQuality(context->imageInterpolationQuality());
textureMapper->setTextDrawingMode(context->textDrawingMode());
textureMapper->setViewportSize(frame->view()->frameRect().size());
QPainter* painter = context->platformContext();
const QTransform transform = painter->worldTransform();
const TransformationMatrix matrix(
transform.m11(), transform.m12(), 0, transform.m13(),
transform.m21(), transform.m22(), 0, transform.m23(),
0, 0, 1, 0,
transform.m31(), transform.m32(), 0, transform.m33()
);
rootTextureMapperNode->setTransform(matrix);
rootTextureMapperNode->setOpacity(painter->opacity());
textureMapper->beginPainting();
textureMapper->beginClip(matrix, clip);
rootTextureMapperNode->paint();
textureMapper->endClip();
textureMapper->endPainting();
}
#endif
void QWebFramePrivate::renderRelativeCoords(GraphicsContext* context, QFlags<QWebFrame::RenderLayer> layers, const QRegion& clip)
{
if (!frame->view() || !frame->contentRenderer())
return;
QVector<QRect> vector = clip.rects();
if (vector.isEmpty())
return;
QPainter* painter = context->platformContext();
WebCore::FrameView* view = frame->view();
view->updateLayoutAndStyleIfNeededRecursive();
if (layers & QWebFrame::ContentsLayer) {
for (int i = 0; i < vector.size(); ++i) {
const QRect& clipRect = vector.at(i);
QRect rect = clipRect.intersected(view->frameRect());
context->save();
painter->setClipRect(clipRect, Qt::IntersectClip);
int x = view->x();
int y = view->y();
int scrollX = view->scrollX();
int scrollY = view->scrollY();
context->translate(x, y);
rect.translate(-x, -y);
context->translate(-scrollX, -scrollY);
rect.translate(scrollX, scrollY);
context->clip(view->visibleContentRect());
view->paintContents(context, rect);
context->restore();
}
#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER)
renderCompositedLayers(context, IntRect(clip.boundingRect()));
#endif
}
renderFrameExtras(context, layers, clip);
#if ENABLE(INSPECTOR)
if (frame->page()->inspectorController()->highlightedNode()) {
context->save();
frame->page()->inspectorController()->drawNodeHighlight(*context);
context->restore();
}
#endif
}
void QWebFramePrivate::renderFrameExtras(GraphicsContext* context, QFlags<QWebFrame::RenderLayer> layers, const QRegion& clip)
{
if (!(layers & (QWebFrame::PanIconLayer | QWebFrame::ScrollBarLayer)))
return;
QPainter* painter = context->platformContext();
WebCore::FrameView* view = frame->view();
QVector<QRect> vector = clip.rects();
for (int i = 0; i < vector.size(); ++i) {
const QRect& clipRect = vector.at(i);
QRect intersectedRect = clipRect.intersected(view->frameRect());
painter->save();
painter->setClipRect(clipRect, Qt::IntersectClip);
int x = view->x();
int y = view->y();
if (layers & QWebFrame::ScrollBarLayer
&& !view->scrollbarsSuppressed()
&& (view->horizontalScrollbar() || view->verticalScrollbar())) {
QRect rect = intersectedRect;
context->translate(x, y);
rect.translate(-x, -y);
view->paintScrollbars(context, rect);
context->translate(-x, -y);
}
#if ENABLE(PAN_SCROLLING)
if (layers & QWebFrame::PanIconLayer)
view->paintPanScrollIcon(context);
#endif
painter->restore();
}
}
void QWebFramePrivate::emitUrlChanged()
{
url = frame->document()->url();
emit q->urlChanged(url);
}
void QWebFramePrivate::_q_orientationChanged()
{
#if ENABLE(ORIENTATION_EVENTS) && ENABLE(DEVICE_ORIENTATION)
int orientation;
WebCore::Frame* frame = core(q);
switch (m_orientation.reading()->orientation()) {
case QtMobility::QOrientationReading::TopUp:
orientation = 0;
break;
case QtMobility::QOrientationReading::TopDown:
orientation = 180;
break;
case QtMobility::QOrientationReading::LeftUp:
orientation = -90;
break;
case QtMobility::QOrientationReading::RightUp:
orientation = 90;
break;
case QtMobility::QOrientationReading::FaceUp:
case QtMobility::QOrientationReading::FaceDown:
default:
return;
}
frame->sendOrientationChangeEvent(orientation);
#endif
}
QWebFrame::QWebFrame(QWebPage *parent, QWebFrameData *frameData)
: QObject(parent)
, d(new QWebFramePrivate)
{
d->page = parent;
d->init(this, frameData);
if (!frameData->url.isEmpty()) {
WebCore::ResourceRequest request(frameData->url, frameData->referrer);
d->frame->loader()->load(request, frameData->name, false);
}
#if ENABLE(ORIENTATION_EVENTS) && ENABLE(DEVICE_ORIENTATION)
connect(&d->m_orientation, SIGNAL(readingChanged()), this, SLOT(_q_orientationChanged()));
d->m_orientation.start();
#endif
}
QWebFrame::QWebFrame(QWebFrame *parent, QWebFrameData *frameData)
: QObject(parent)
, d(new QWebFramePrivate)
{
d->page = parent->d->page;
d->init(this, frameData);
#if ENABLE(ORIENTATION_EVENTS) && ENABLE(DEVICE_ORIENTATION)
connect(&d->m_orientation, SIGNAL(readingChanged()), this, SLOT(_q_orientationChanged()));
d->m_orientation.start();
#endif
}
QWebFrame::~QWebFrame()
{
if (d->frame && d->frame->loader() && d->frame->loader()->client())
static_cast<FrameLoaderClientQt*>(d->frame->loader()->client())->m_webFrame = 0;
delete d;
}
void QWebFrame::addToJavaScriptWindowObject(const QString &name, QObject *object)
{
addToJavaScriptWindowObject(name, object, QScriptEngine::QtOwnership);
}
void QWebFrame::addToJavaScriptWindowObject(const QString &name, QObject *object, QScriptEngine::ValueOwnership ownership)
{
if (!page()->settings()->testAttribute(QWebSettings::JavascriptEnabled))
return;
#if USE(JSC)
JSC::JSLock lock(JSC::SilenceAssertionsOnly);
JSDOMWindow* window = toJSDOMWindow(d->frame, mainThreadNormalWorld());
JSC::Bindings::RootObject* root;
if (ownership == QScriptEngine::QtOwnership)
root = d->frame->script()->cacheableBindingRootObject();
else
root = d->frame->script()->bindingRootObject();
if (!window) {
qDebug() << "Warning: couldn't get window object";
return;
}
if (!root) {
qDebug() << "Warning: couldn't get root object";
return;
}
JSC::ExecState* exec = window->globalExec();
JSC::JSObject* runtimeObject =
JSC::Bindings::QtInstance::getQtInstance(object, root, ownership)->createRuntimeObject(exec);
JSC::PutPropertySlot slot;
window->put(exec, JSC::Identifier(exec, reinterpret_cast_ptr<const UChar*>(name.constData()), name.length()), runtimeObject, slot);
#elif USE(V8)
QScriptEngine* engine = d->frame->script()->qtScriptEngine();
if (!engine)
return;
QScriptValue v = engine->newQObject(object, ownership);
engine->globalObject().property("window").setProperty(name, v);
#endif
}
QString QWebFrame::toHtml() const
{
if (!d->frame->document())
return QString();
return createMarkup(d->frame->document());
}
QString QWebFrame::toPlainText() const
{
if (d->frame->view() && d->frame->view()->layoutPending())
d->frame->view()->layout();
Element *documentElement = d->frame->document()->documentElement();
if (documentElement)
return documentElement->innerText();
return QString();
}
QString QWebFrame::renderTreeDump() const
{
if (d->frame->view() && d->frame->view()->layoutPending())
d->frame->view()->layout();
return externalRepresentation(d->frame);
}
QString QWebFrame::title() const
{
if (d->frame->document())
return d->frame->loader()->documentLoader()->title().string();
return QString();
}
QMultiMap<QString, QString> QWebFrame::metaData() const
{
if (!d->frame->document())
return QMap<QString, QString>();
QMultiMap<QString, QString> map;
Document* doc = d->frame->document();
RefPtr<NodeList> list = doc->getElementsByTagName("meta");
unsigned len = list->length();
for (unsigned i = 0; i < len; i++) {
HTMLMetaElement* meta = static_cast<HTMLMetaElement*>(list->item(i));
map.insert(meta->name(), meta->content());
}
return map;
}
static inline void clearCoreFrame(WebCore::Frame* frame)
{
frame->loader()->activeDocumentLoader()->writer()->begin();
frame->loader()->activeDocumentLoader()->writer()->end();
}
static inline bool isCoreFrameClear(WebCore::Frame* frame)
{
return frame->document()->url().isEmpty();
}
static inline QUrl ensureAbsoluteUrl(const QUrl &url)
{
if (!url.isValid() || !url.isRelative())
return url;
QUrl baseUrl = QUrl::fromLocalFile(QFileInfo(url.toLocalFile()).absoluteFilePath());
QString pathRemoved = url.toString(QUrl::RemovePath);
QUrl toResolve(pathRemoved);
return baseUrl.resolved(toResolve);
}
void QWebFrame::setUrl(const QUrl &url)
{
clearCoreFrame(d->frame);
const QUrl absolute = ensureAbsoluteUrl(url);
d->url = absolute;
load(absolute);
}
QUrl QWebFrame::url() const
{
return d->url;
}
QUrl QWebFrame::requestedUrl() const
{
return d->frameLoaderClient->lastRequestedUrl();
}
QUrl QWebFrame::baseUrl() const
{
if (isCoreFrameClear(d->frame))
return QUrl(d->url).resolved(QUrl());
return d->frame->document()->baseURL();
}
QIcon QWebFrame::icon() const
{
return QWebSettings::iconForUrl(d->frame->document()->url());
}
QString QWebFrame::frameName() const
{
return d->frame->tree()->uniqueName();
}
QWebPage *QWebFrame::page() const
{
return d->page;
}
void QWebFrame::load(const QUrl &url)
{
load(QNetworkRequest(url));
}
void QWebFrame::load(const QNetworkRequest &req,
QNetworkAccessManager::Operation operation,
const QByteArray &body)
{
if (d->parentFrame())
d->page->d->insideOpenCall = true;
QUrl url = ensureAbsoluteUrl(req.url());
WebCore::ResourceRequest request(url);
switch (operation) {
case QNetworkAccessManager::HeadOperation:
request.setHTTPMethod("HEAD");
break;
case QNetworkAccessManager::GetOperation:
request.setHTTPMethod("GET");
break;
case QNetworkAccessManager::PutOperation:
request.setHTTPMethod("PUT");
break;
case QNetworkAccessManager::PostOperation:
request.setHTTPMethod("POST");
break;
case QNetworkAccessManager::DeleteOperation:
request.setHTTPMethod("DELETE");
break;
case QNetworkAccessManager::CustomOperation:
request.setHTTPMethod(req.attribute(QNetworkRequest::CustomVerbAttribute).toByteArray().constData());
break;
case QNetworkAccessManager::UnknownOperation:
break;
}
QVariant cacheLoad = req.attribute(QNetworkRequest::CacheLoadControlAttribute);
if (cacheLoad.isValid()) {
bool ok;
uint cacheLoadValue = cacheLoad.toUInt(&ok);
if (ok)
request.setCachePolicy(cacheLoadControlToCachePolicy(cacheLoadValue));
}
QList<QByteArray> httpHeaders = req.rawHeaderList();
for (int i = 0; i < httpHeaders.size(); ++i) {
const QByteArray &headerName = httpHeaders.at(i);
request.addHTTPHeaderField(QString::fromLatin1(headerName), QString::fromLatin1(req.rawHeader(headerName)));
}
if (!body.isEmpty())
request.setHTTPBody(WebCore::FormData::create(body.constData(), body.size()));
d->frame->loader()->load(request, false);
if (d->parentFrame())
d->page->d->insideOpenCall = false;
}
void QWebFrame::setHtml(const QString &html, const QUrl &baseUrl)
{
KURL kurl(baseUrl);
WebCore::ResourceRequest request(kurl);
const QByteArray utf8 = html.toUtf8();
WTF::RefPtr<WebCore::SharedBuffer> data = WebCore::SharedBuffer::create(utf8.constData(), utf8.length());
WebCore::SubstituteData substituteData(data, WTF::String("text/html"), WTF::String("utf-8"), KURL());
d->frame->loader()->load(request, substituteData, false);
}
void QWebFrame::setContent(const QByteArray &data, const QString &mimeType, const QUrl &baseUrl)
{
KURL kurl(baseUrl);
WebCore::ResourceRequest request(kurl);
WTF::RefPtr<WebCore::SharedBuffer> buffer = WebCore::SharedBuffer::create(data.constData(), data.length());
QString actualMimeType;
WTF::String encoding;
if (mimeType.isEmpty())
actualMimeType = QLatin1String("text/html");
else {
actualMimeType = extractMIMETypeFromMediaType(mimeType);
encoding = extractCharsetFromMediaType(mimeType);
}
WebCore::SubstituteData substituteData(buffer, WTF::String(actualMimeType), encoding, KURL());
d->frame->loader()->load(request, substituteData, false);
}
QWebFrame *QWebFrame::parentFrame() const
{
return d->parentFrame();
}
QList<QWebFrame*> QWebFrame::childFrames() const
{
QList<QWebFrame*> rc;
if (d->frame) {
FrameTree *tree = d->frame->tree();
for (Frame *child = tree->firstChild(); child; child = child->tree()->nextSibling()) {
FrameLoader *loader = child->loader();
QWebFrame* webFrame = qobject_cast<QWebFrame*>(loader->networkingContext()->originatingObject());
if (webFrame)
rc.append(webFrame);
}
}
return rc;
}
Qt::ScrollBarPolicy QWebFrame::scrollBarPolicy(Qt::Orientation orientation) const
{
if (orientation == Qt::Horizontal)
return d->horizontalScrollBarPolicy;
return d->verticalScrollBarPolicy;
}
void QWebFrame::setScrollBarPolicy(Qt::Orientation orientation, Qt::ScrollBarPolicy policy)
{
Q_ASSERT((int)ScrollbarAuto == (int)Qt::ScrollBarAsNeeded);
Q_ASSERT((int)ScrollbarAlwaysOff == (int)Qt::ScrollBarAlwaysOff);
Q_ASSERT((int)ScrollbarAlwaysOn == (int)Qt::ScrollBarAlwaysOn);
if (orientation == Qt::Horizontal) {
d->horizontalScrollBarPolicy = policy;
if (d->frame->view()) {
d->frame->view()->setHorizontalScrollbarMode((ScrollbarMode)policy, policy != Qt::ScrollBarAsNeeded );
d->frame->view()->updateCanHaveScrollbars();
}
} else {
d->verticalScrollBarPolicy = policy;
if (d->frame->view()) {
d->frame->view()->setVerticalScrollbarMode((ScrollbarMode)policy, policy != Qt::ScrollBarAsNeeded );
d->frame->view()->updateCanHaveScrollbars();
}
}
}
void QWebFrame::setScrollBarValue(Qt::Orientation orientation, int value)
{
Scrollbar *sb;
sb = (orientation == Qt::Horizontal) ? d->horizontalScrollBar() : d->verticalScrollBar();
if (sb) {
if (value < 0)
value = 0;
else if (value > scrollBarMaximum(orientation))
value = scrollBarMaximum(orientation);
sb->scrollableArea()->scrollToOffsetWithoutAnimation(orientation == Qt::Horizontal ? HorizontalScrollbar : VerticalScrollbar, value);
}
}
int QWebFrame::scrollBarValue(Qt::Orientation orientation) const
{
Scrollbar *sb;
sb = (orientation == Qt::Horizontal) ? d->horizontalScrollBar() : d->verticalScrollBar();
if (sb)
return sb->value();
return 0;
}
int QWebFrame::scrollBarMaximum(Qt::Orientation orientation) const
{
Scrollbar *sb;
sb = (orientation == Qt::Horizontal) ? d->horizontalScrollBar() : d->verticalScrollBar();
if (sb)
return sb->maximum();
return 0;
}
int QWebFrame::scrollBarMinimum(Qt::Orientation orientation) const
{
Q_UNUSED(orientation)
return 0;
}
QRect QWebFrame::scrollBarGeometry(Qt::Orientation orientation) const
{
Scrollbar *sb;
sb = (orientation == Qt::Horizontal) ? d->horizontalScrollBar() : d->verticalScrollBar();
if (sb)
return sb->frameRect();
return QRect();
}
void QWebFrame::scroll(int dx, int dy)
{
if (!d->frame->view())
return;
d->frame->view()->scrollBy(IntSize(dx, dy));
}
QPoint QWebFrame::scrollPosition() const
{
if (!d->frame->view())
return QPoint(0, 0);
IntSize ofs = d->frame->view()->scrollOffset();
return QPoint(ofs.width(), ofs.height());
}
void QWebFrame::setScrollPosition(const QPoint &pos)
{
QPoint current = scrollPosition();
int dx = pos.x() - current.x();
int dy = pos.y() - current.y();
scroll(dx, dy);
}
void QWebFrame::scrollToAnchor(const QString& anchor)
{
FrameView *view = d->frame->view();
if (view)
view->scrollToAnchor(anchor);
}
void QWebFrame::render(QPainter* painter, RenderLayer layer, const QRegion& clip)
{
GraphicsContext context(painter);
if (context.paintingDisabled() && !context.updatingControlTints())
return;
if (!clip.isEmpty())
d->renderRelativeCoords(&context, layer, clip);
else if (d->frame->view())
d->renderRelativeCoords(&context, layer, QRegion(d->frame->view()->frameRect()));
}
void QWebFrame::render(QPainter* painter, const QRegion& clip)
{
GraphicsContext context(painter);
if (context.paintingDisabled() && !context.updatingControlTints())
return;
d->renderRelativeCoords(&context, AllLayers, clip);
}
void QWebFrame::render(QPainter* painter)
{
if (!d->frame->view())
return;
GraphicsContext context(painter);
if (context.paintingDisabled() && !context.updatingControlTints())
return;
d->renderRelativeCoords(&context, AllLayers, QRegion(d->frame->view()->frameRect()));
}
void QWebFrame::setTextSizeMultiplier(qreal factor)
{
page()->settings()->setAttribute(QWebSettings::ZoomTextOnly, true);
d->frame->setPageAndTextZoomFactors(1, factor);
}
qreal QWebFrame::textSizeMultiplier() const
{
return page()->settings()->testAttribute(QWebSettings::ZoomTextOnly) ? d->frame->textZoomFactor() : d->frame->pageZoomFactor();
}
void QWebFrame::setZoomFactor(qreal factor)
{
if (page()->settings()->testAttribute(QWebSettings::ZoomTextOnly))
d->frame->setTextZoomFactor(factor);
else
d->frame->setPageZoomFactor(factor);
}
qreal QWebFrame::zoomFactor() const
{
return page()->settings()->testAttribute(QWebSettings::ZoomTextOnly) ? d->frame->textZoomFactor() : d->frame->pageZoomFactor();
}
bool QWebFrame::hasFocus() const
{
WebCore::Frame* ff = d->frame->page()->focusController()->focusedFrame();
return ff && QWebFramePrivate::kit(ff) == this;
}
void QWebFrame::setFocus()
{
QWebFramePrivate::core(this)->page()->focusController()->setFocusedFrame(QWebFramePrivate::core(this));
}
QPoint QWebFrame::pos() const
{
if (!d->frame->view())
return QPoint();
return d->frame->view()->frameRect().location();
}
QRect QWebFrame::geometry() const
{
if (!d->frame->view())
return QRect();
return d->frame->view()->frameRect();
}
QSize QWebFrame::contentsSize() const
{
FrameView *view = d->frame->view();
if (!view)
return QSize();
return QSize(view->contentsWidth(), view->contentsHeight());
}
QWebElement QWebFrame::documentElement() const
{
WebCore::Document *doc = d->frame->document();
if (!doc)
return QWebElement();
return QWebElement(doc->documentElement());
}
QWebElementCollection QWebFrame::findAllElements(const QString &selectorQuery) const
{
return documentElement().findAll(selectorQuery);
}
QWebElement QWebFrame::findFirstElement(const QString &selectorQuery) const
{
return documentElement().findFirst(selectorQuery);
}
QWebHitTestResult QWebFrame::hitTestContent(const QPoint &pos) const
{
if (!d->frame->view() || !d->frame->contentRenderer())
return QWebHitTestResult();
HitTestResult result = d->frame->eventHandler()->hitTestResultAtPoint(d->frame->view()->windowToContents(pos), false, true);
if (result.scrollbar())
return QWebHitTestResult();
return QWebHitTestResult(new QWebHitTestResultPrivate(result));
}
bool QWebFrame::event(QEvent *e)
{
return QObject::event(e);
}
#ifndef QT_NO_PRINTER
void QWebFrame::print(QPrinter *printer) const
{
QPainter painter;
if (!painter.begin(printer))
return;
const qreal zoomFactorX = (qreal)printer->logicalDpiX() / qt_defaultDpi();
const qreal zoomFactorY = (qreal)printer->logicalDpiY() / qt_defaultDpi();
PrintContext printContext(d->frame);
float pageHeight = 0;
QRect qprinterRect = printer->pageRect();
IntRect pageRect(0, 0,
int(qprinterRect.width() / zoomFactorX),
int(qprinterRect.height() / zoomFactorY));
printContext.begin(pageRect.width());
printContext.computePageRects(pageRect, 0, 0, 1.0, pageHeight);
int docCopies;
int pageCopies;
if (printer->collateCopies()) {
docCopies = 1;
pageCopies = printer->numCopies();
} else {
docCopies = printer->numCopies();
pageCopies = 1;
}
int fromPage = printer->fromPage();
int toPage = printer->toPage();
bool ascending = true;
if (fromPage == 0 && toPage == 0) {
fromPage = 1;
toPage = printContext.pageCount();
}
fromPage = qMax(1, fromPage);
toPage = qMin(static_cast<int>(printContext.pageCount()), toPage);
if (toPage < fromPage) {
return;
}
if (printer->pageOrder() == QPrinter::LastPageFirst) {
int tmp = fromPage;
fromPage = toPage;
toPage = tmp;
ascending = false;
}
painter.scale(zoomFactorX, zoomFactorY);
GraphicsContext ctx(&painter);
for (int i = 0; i < docCopies; ++i) {
int page = fromPage;
while (true) {
for (int j = 0; j < pageCopies; ++j) {
if (printer->printerState() == QPrinter::Aborted
|| printer->printerState() == QPrinter::Error) {
printContext.end();
return;
}
printContext.spoolPage(ctx, page - 1, pageRect.width());
if (j < pageCopies - 1)
printer->newPage();
}
if (page == toPage)
break;
if (ascending)
++page;
else
--page;
printer->newPage();
}
if ( i < docCopies - 1)
printer->newPage();
}
printContext.end();
}
#endif // QT_NO_PRINTER
QVariant QWebFrame::evaluateJavaScript(const QString& scriptSource)
{
ScriptController *proxy = d->frame->script();
QVariant rc;
if (proxy) {
#if USE(JSC)
int distance = 0;
JSC::JSValue v = d->frame->script()->executeScript(ScriptSourceCode(scriptSource)).jsValue();
rc = JSC::Bindings::convertValueToQVariant(proxy->globalObject(mainThreadNormalWorld())->globalExec(), v, QMetaType::Void, &distance);
#elif USE(V8)
QScriptEngine* engine = d->frame->script()->qtScriptEngine();
if (!engine)
return rc;
rc = engine->evaluate(scriptSource).toVariant();
#endif
}
return rc;
}
QWebSecurityOrigin QWebFrame::securityOrigin() const
{
QWebFrame* that = const_cast<QWebFrame*>(this);
QWebSecurityOriginPrivate* priv = new QWebSecurityOriginPrivate(QWebFramePrivate::core(that)->document()->securityOrigin());
return QWebSecurityOrigin(priv);
}
WebCore::Frame* QWebFramePrivate::core(const QWebFrame* webFrame)
{
return webFrame->d->frame;
}
QWebFrame* QWebFramePrivate::kit(const WebCore::Frame* coreFrame)
{
return qobject_cast<QWebFrame*>(coreFrame->loader()->networkingContext()->originatingObject());
}
QWebHitTestResult::QWebHitTestResult(QWebHitTestResultPrivate *priv)
: d(priv)
{
}
QWebHitTestResultPrivate::QWebHitTestResultPrivate(const WebCore::HitTestResult &hitTest)
: isContentEditable(false)
, isContentSelected(false)
, isScrollBar(false)
{
if (!hitTest.innerNode())
return;
pos = hitTest.point();
WebCore::TextDirection dir;
title = hitTest.title(dir);
linkText = hitTest.textContent();
linkUrl = hitTest.absoluteLinkURL();
linkTitle = hitTest.titleDisplayString();
alternateText = hitTest.altDisplayString();
imageUrl = hitTest.absoluteImageURL();
innerNode = hitTest.innerNode();
innerNonSharedNode = hitTest.innerNonSharedNode();
boundingRect = innerNonSharedNode ? innerNonSharedNode->renderer()->absoluteBoundingBoxRect(true) : IntRect();
WebCore::Image *img = hitTest.image();
if (img) {
QPixmap *pix = img->nativeImageForCurrentFrame();
if (pix)
pixmap = *pix;
}
WebCore::Frame *wframe = hitTest.targetFrame();
if (wframe)
linkTargetFrame = QWebFramePrivate::kit(wframe);
linkElement = QWebElement(hitTest.URLElement());
isContentEditable = hitTest.isContentEditable();
isContentSelected = hitTest.isSelected();
isScrollBar = hitTest.scrollbar();
if (innerNonSharedNode && innerNonSharedNode->document()
&& innerNonSharedNode->document()->frame())
frame = QWebFramePrivate::kit(innerNonSharedNode->document()->frame());
enclosingBlock = QWebElement(WebCore::enclosingBlock(innerNode.get()));
}
QWebHitTestResult::QWebHitTestResult()
: d(0)
{
}
QWebHitTestResult::QWebHitTestResult(const QWebHitTestResult &other)
: d(0)
{
if (other.d)
d = new QWebHitTestResultPrivate(*other.d);
}
QWebHitTestResult &QWebHitTestResult::operator=(const QWebHitTestResult &other)
{
if (this != &other) {
if (other.d) {
if (!d)
d = new QWebHitTestResultPrivate;
*d = *other.d;
} else {
delete d;
d = 0;
}
}
return *this;
}
QWebHitTestResult::~QWebHitTestResult()
{
delete d;
}
bool QWebHitTestResult::isNull() const
{
return !d;
}
QPoint QWebHitTestResult::pos() const
{
if (!d)
return QPoint();
return d->pos;
}
QRect QWebHitTestResult::boundingRect() const
{
if (!d)
return QRect();
return d->boundingRect;
}
QWebElement QWebHitTestResult::enclosingBlockElement() const
{
if (!d)
return QWebElement();
return d->enclosingBlock;
}
QString QWebHitTestResult::title() const
{
if (!d)
return QString();
return d->title;
}
QString QWebHitTestResult::linkText() const
{
if (!d)
return QString();
return d->linkText;
}
QUrl QWebHitTestResult::linkUrl() const
{
if (!d)
return QUrl();
return d->linkUrl;
}
QUrl QWebHitTestResult::linkTitle() const
{
if (!d)
return QUrl();
return d->linkTitle;
}
QWebElement QWebHitTestResult::linkElement() const
{
if (!d)
return QWebElement();
return d->linkElement;
}
QWebFrame *QWebHitTestResult::linkTargetFrame() const
{
if (!d)
return 0;
return d->linkTargetFrame;
}
QString QWebHitTestResult::alternateText() const
{
if (!d)
return QString();
return d->alternateText;
}
QUrl QWebHitTestResult::imageUrl() const
{
if (!d)
return QUrl();
return d->imageUrl;
}
QPixmap QWebHitTestResult::pixmap() const
{
if (!d)
return QPixmap();
return d->pixmap;
}
bool QWebHitTestResult::isContentEditable() const
{
if (!d)
return false;
return d->isContentEditable;
}
bool QWebHitTestResult::isContentSelected() const
{
if (!d)
return false;
return d->isContentSelected;
}
QWebElement QWebHitTestResult::element() const
{
if (!d || !d->innerNonSharedNode || !d->innerNonSharedNode->isElementNode())
return QWebElement();
return QWebElement(static_cast<WebCore::Element*>(d->innerNonSharedNode.get()));
}
QWebFrame *QWebHitTestResult::frame() const
{
if (!d)
return 0;
return d->frame;
}
#include "moc_qwebframe.cpp"