diff options
author | Simon Hausmann <simon.hausmann@nokia.com> | 2009-06-15 09:06:43 (GMT) |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2009-06-15 09:31:31 (GMT) |
commit | c411f16870f112c3407c28c22b617f613a82cff4 (patch) | |
tree | 29a1bcd590c8b31af2aab445bfe8a978dc5bf582 /src/3rdparty/webkit/WebKit/qt/Api | |
parent | 3d77b56b32a0c53ec0bbfaa07236fedb900ff336 (diff) | |
download | Qt-c411f16870f112c3407c28c22b617f613a82cff4.zip Qt-c411f16870f112c3407c28c22b617f613a82cff4.tar.gz Qt-c411f16870f112c3407c28c22b617f613a82cff4.tar.bz2 |
Updated WebKit from /home/shausman/src/webkit/trunk to qtwebkit-4.6-snapshot-15062009 ( 65232bf00dc494ebfd978f998c88f58d18ecce1e )
Diffstat (limited to 'src/3rdparty/webkit/WebKit/qt/Api')
-rw-r--r-- | src/3rdparty/webkit/WebKit/qt/Api/headers.pri | 3 | ||||
-rw-r--r-- | src/3rdparty/webkit/WebKit/qt/Api/qwebdatabase.cpp | 20 | ||||
-rw-r--r-- | src/3rdparty/webkit/WebKit/qt/Api/qwebelement.cpp | 1603 | ||||
-rw-r--r-- | src/3rdparty/webkit/WebKit/qt/Api/qwebelement.h | 153 | ||||
-rw-r--r-- | src/3rdparty/webkit/WebKit/qt/Api/qwebframe.cpp | 284 | ||||
-rw-r--r-- | src/3rdparty/webkit/WebKit/qt/Api/qwebframe.h | 17 | ||||
-rw-r--r-- | src/3rdparty/webkit/WebKit/qt/Api/qwebframe_p.h | 10 | ||||
-rw-r--r-- | src/3rdparty/webkit/WebKit/qt/Api/qwebkitglobal.h | 22 | ||||
-rw-r--r-- | src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp | 177 | ||||
-rw-r--r-- | src/3rdparty/webkit/WebKit/qt/Api/qwebpage.h | 30 | ||||
-rw-r--r-- | src/3rdparty/webkit/WebKit/qt/Api/qwebpage_p.h | 5 | ||||
-rw-r--r-- | src/3rdparty/webkit/WebKit/qt/Api/qwebsecurityorigin.cpp | 23 | ||||
-rw-r--r-- | src/3rdparty/webkit/WebKit/qt/Api/qwebsettings.cpp | 96 | ||||
-rw-r--r-- | src/3rdparty/webkit/WebKit/qt/Api/qwebsettings.h | 8 | ||||
-rw-r--r-- | src/3rdparty/webkit/WebKit/qt/Api/qwebview.cpp | 121 | ||||
-rw-r--r-- | src/3rdparty/webkit/WebKit/qt/Api/qwebview.h | 9 |
16 files changed, 2488 insertions, 93 deletions
diff --git a/src/3rdparty/webkit/WebKit/qt/Api/headers.pri b/src/3rdparty/webkit/WebKit/qt/Api/headers.pri index 2b3c940..e4bb618 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/headers.pri +++ b/src/3rdparty/webkit/WebKit/qt/Api/headers.pri @@ -5,4 +5,5 @@ WEBKIT_API_HEADERS = $$PWD/qwebframe.h \ $$PWD/qwebsettings.h \ $$PWD/qwebhistoryinterface.h \ $$PWD/qwebdatabase.h \ - $$PWD/qwebsecurityorigin.h + $$PWD/qwebsecurityorigin.h \ + $$PWD/qwebelement.h diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebdatabase.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebdatabase.cpp index 489ab17..2db9cd0 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebdatabase.cpp +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebdatabase.cpp @@ -19,6 +19,7 @@ #include "config.h" #include "qwebdatabase.h" + #include "qwebdatabase_p.h" #include "qwebsecurityorigin.h" #include "qwebsecurityorigin_p.h" @@ -69,8 +70,12 @@ QString QWebDatabase::name() const */ QString QWebDatabase::displayName() const { +#if ENABLE(DATABASE) DatabaseDetails details = DatabaseTracker::tracker().detailsForNameAndOrigin(d->name, d->origin.get()); return details.displayName(); +#else + return QString(); +#endif } /*! @@ -78,8 +83,12 @@ QString QWebDatabase::displayName() const */ qint64 QWebDatabase::expectedSize() const { +#if ENABLE(DATABASE) DatabaseDetails details = DatabaseTracker::tracker().detailsForNameAndOrigin(d->name, d->origin.get()); return details.expectedUsage(); +#else + return 0; +#endif } /*! @@ -87,8 +96,12 @@ qint64 QWebDatabase::expectedSize() const */ qint64 QWebDatabase::size() const { +#if ENABLE(DATABASE) DatabaseDetails details = DatabaseTracker::tracker().detailsForNameAndOrigin(d->name, d->origin.get()); return details.currentUsage(); +#else + return 0; +#endif } /*! @@ -118,7 +131,11 @@ QWebDatabase::QWebDatabase(QWebDatabasePrivate* priv) */ QString QWebDatabase::fileName() const { +#if ENABLE(DATABASE) return DatabaseTracker::tracker().fullPathForDatabase(d->origin.get(), d->name, false); +#else + return QString(); +#endif } /*! @@ -137,7 +154,9 @@ QWebSecurityOrigin QWebDatabase::origin() const */ void QWebDatabase::removeDatabase(const QWebDatabase &db) { +#if ENABLE(DATABASE) DatabaseTracker::tracker().deleteDatabase(db.d->origin.get(), db.d->name); +#endif } /*! @@ -146,3 +165,4 @@ void QWebDatabase::removeDatabase(const QWebDatabase &db) QWebDatabase::~QWebDatabase() { } + diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebelement.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebelement.cpp new file mode 100644 index 0000000..ff0463b --- /dev/null +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebelement.cpp @@ -0,0 +1,1603 @@ +/* + Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "qwebelement.h" + +#include "CSSComputedStyleDeclaration.h" +#include "CSSMutableStyleDeclaration.h" +#include "CSSParser.h" +#include "CSSRuleList.h" +#include "CSSRule.h" +#include "CSSStyleRule.h" +#include "CString.h" +#include "Document.h" +#include "DocumentFragment.h" +#include "FrameView.h" +#include "HTMLElement.h" +#include "JSGlobalObject.h" +#include "JSHTMLElement.h" +#include "JSObject.h" +#include "NodeList.h" +#include "PropertyNameArray.h" +#include "ScriptFunctionCall.h" +#include "StaticNodeList.h" +#include "qt_runtime.h" +#include "qwebframe.h" +#include "qwebframe_p.h" +#include "runtime_root.h" +#include <wtf/Vector.h> + +using namespace WebCore; + +class QWebElementPrivate +{ +public: +}; + +/*! + \class QWebElement + \since 4.6 + \brief The QWebElement class provides convenience access to DOM elements in a QWebFrame. + \preliminary + + QWebElement is the main class to provide easy access to the document model. + The document model is represented by a tree-like structure of DOM elements. + The root of the tree is called the document element and can be accessed using QWebFrame::documentElement(). + + You can reach specific elements by using the findAll() and findFirst() functions, which + allow the use of CSS selectors to identify elements. + + \snippet webkitsnippets/webelement/main.cpp FindAll + + The first list contains all span elements in the document. The second list contains + only the span elements that are children of the paragraph that is classified + as "intro" paragraph. + + Alternatively you can manually traverse the document using firstChild() and nextSibling(): + + \snippet webkitsnippets/webelement/main.cpp Traversing with QWebElement + + The underlying content of QWebElement is explicitly shared. Creating a copy of a QWebElement + does not create a copy of the content, both instances point to the same underlying element. + + The element's attributes can be read using attribute() and changed using setAttribute(). + + The content of the child elements can be converted to plain text using toPlainText() and to + x(html) using toXml(), and it is possible to replace the content using setPlainText() and setXml(). + + Depending on the type of the underlying element there may be extra functionality available, not + covered through QWebElement's API. For example a HTML form element can be triggered to submit the + entire form. These list of these functions is available through functions() and they can be called + directly using callFunction(). +*/ + +/*! + Constructs a null web element. +*/ +QWebElement::QWebElement() + : d(0) + , m_element(0) +{ +} + +/*! + \internal +*/ +QWebElement::QWebElement(WebCore::Element* domElement) + : d(0) + , m_element(domElement) +{ + if (m_element) + m_element->ref(); +} + +/*! + \internal +*/ +QWebElement::QWebElement(WebCore::Node* node) + : d(0) + , m_element(0) +{ + if (node && node->isHTMLElement()) { + m_element = static_cast<HTMLElement*>(node); + m_element->ref(); + } +} + +/*! + Constructs a copy of \a other. +*/ +QWebElement::QWebElement(const QWebElement &other) + : d(0) + , m_element(other.m_element) +{ + if (m_element) + m_element->ref(); +} + +/*! + Assigns \a other to this element and returns a reference to this element. +*/ +QWebElement &QWebElement::operator=(const QWebElement &other) +{ + // ### handle "d" assignment + if (this != &other) { + Element *otherElement = other.m_element; + if (otherElement) + otherElement->ref(); + if (m_element) + m_element->deref(); + m_element = otherElement; + } + return *this; +} + +/*! + Destroys the element. The underlying DOM element is not destroyed. +*/ +QWebElement::~QWebElement() +{ + delete d; + if (m_element) + m_element->deref(); +} + +bool QWebElement::operator==(const QWebElement& o) const +{ + return m_element == o.m_element; +} + +bool QWebElement::operator!=(const QWebElement& o) const +{ + return m_element != o.m_element; +} + +/*! + Returns true if the element is a null element; false otherwise. +*/ +bool QWebElement::isNull() const +{ + return !m_element; +} + +/*! + Returns a new collection of elements that are children of this element + and that match the given CSS selector \a selectorQuery. + + The query is specified using \l{http://www.w3.org/TR/REC-CSS2/selector.html#q1}{standard CSS2 selectors}. +*/ +QList<QWebElement> QWebElement::findAll(const QString &selectorQuery) const +{ + QList<QWebElement> elements; + if (!m_element) + return elements; + + ExceptionCode exception = 0; // ### + RefPtr<NodeList> nodes = m_element->querySelectorAll(selectorQuery, exception); + if (!nodes) + return elements; + + for (int i = 0; i < nodes->length(); ++i) { + WebCore::Node* n = nodes->item(i); + elements.append(QWebElement(static_cast<Element*>(n))); + } + + return elements; +} + +/*! + Returns the first child element that matches the given CSS selector \a selectorQuery. + + This function is equivalent to calling findAll() and taking only the + first element in the returned collection of elements. However calling + this function is more efficient. +*/ +QWebElement QWebElement::findFirst(const QString &selectorQuery) const +{ + if (!m_element) + return QWebElement(); + ExceptionCode exception = 0; // ### + return QWebElement(m_element->querySelector(selectorQuery, exception).get()); +} + +/*! + Replaces the existing content of this element with \a text. + + This is equivalent to setting the HTML innerText property. +*/ +void QWebElement::setPlainText(const QString &text) +{ + if (!m_element || !m_element->isHTMLElement()) + return; + ExceptionCode exception = 0; + static_cast<HTMLElement*>(m_element)->setInnerText(text, exception); +} + +/*! + Returns the text between the start and the end tag of this + element. + + This is equivalent to reading the HTML innerText property. +*/ +QString QWebElement::toPlainText() const +{ + if (!m_element || !m_element->isHTMLElement()) + return QString(); + return static_cast<HTMLElement*>(m_element)->innerText(); +} + +/*! + Replaces the contents of this element as well as its own tag with \a markup. + The string may contain HTML or XML tags, which is parsed and formatted + before insertion into the document. + + \note This is currently only implemented for (X)HTML elements. +*/ +void QWebElement::setOuterXml(const QString &markup) +{ + if (!m_element || !m_element->isHTMLElement()) + return; + + ExceptionCode exception = 0; + + static_cast<HTMLElement*>(m_element)->setOuterHTML(markup, exception); +} + +/*! + Returns this element converted to XML, including the start and the end + tag of this element and its attributes. + + \note This is currently only implemented for (X)HTML elements. +*/ +QString QWebElement::toOuterXml() const +{ + if (!m_element || !m_element->isHTMLElement()) + return QString(); + + return static_cast<HTMLElement*>(m_element)->outerHTML(); +} + +/*! + Replaces the content of this element with \a markup. + The string may contain HTML or XML tags, which is parsed and formatted + before insertion into the document. + + \note This is currently only implemented for (X)HTML elements. +*/ +void QWebElement::setInnerXml(const QString &markup) +{ + if (!m_element || !m_element->isHTMLElement()) + return; + + ExceptionCode exception = 0; + + static_cast<HTMLElement*>(m_element)->setInnerHTML(markup, exception); +} + +/*! + Returns the XML between the start and the end tag of this + element. + + \note This is currently only implemented for (X)HTML elements. +*/ +QString QWebElement::toInnerXml() const +{ + if (!m_element || !m_element->isHTMLElement()) + return QString(); + + return static_cast<HTMLElement*>(m_element)->innerHTML(); +} + +/*! + Adds an attribute called \a name with the value \a value. If an attribute + with the same name exists, its value is replaced by \a value. +*/ +void QWebElement::setAttribute(const QString &name, const QString &value) +{ + if (!m_element) + return; + ExceptionCode exception = 0; + m_element->setAttribute(name, value, exception); +} + +/*! + Adds an attribute called \a name in the namespace described with \a namespaceUri + with the value \a value. If an attribute with the same name exists, its value is + replaced by \a value. +*/ +void QWebElement::setAttributeNS(const QString &namespaceUri, const QString &name, const QString &value) +{ + if (!m_element) + return; + WebCore::ExceptionCode exception = 0; + m_element->setAttributeNS(namespaceUri, name, value, exception); +} + +/*! + Returns the attributed called \a name. If the attribute does not exist \a defaultValue is + returned. +*/ +QString QWebElement::attribute(const QString &name, const QString &defaultValue) const +{ + if (!m_element) + return QString(); + if (m_element->hasAttribute(name)) + return m_element->getAttribute(name); + else + return defaultValue; +} + +/*! + Returns the attributed called \a name in the namespace described with \a namespaceUri. + If the attribute does not exist \a defaultValue is returned. +*/ +QString QWebElement::attributeNS(const QString &namespaceUri, const QString &name, const QString &defaultValue) const +{ + if (!m_element) + return QString(); + if (m_element->hasAttributeNS(namespaceUri, name)) + return m_element->getAttributeNS(namespaceUri, name); + else + return defaultValue; +} + +/*! + Returns true if this element has an attribute called \a name; otherwise returns false. +*/ +bool QWebElement::hasAttribute(const QString &name) const +{ + if (!m_element) + return false; + return m_element->hasAttribute(name); +} + +/*! + Returns true if this element has an attribute called \a name in the namespace described + with \a namespaceUri; otherwise returns false. +*/ +bool QWebElement::hasAttributeNS(const QString &namespaceUri, const QString &name) const +{ + if (!m_element) + return false; + return m_element->hasAttributeNS(namespaceUri, name); +} + +/*! + Removes the attribute called \a name from this element. +*/ +void QWebElement::removeAttribute(const QString &name) +{ + if (!m_element) + return; + ExceptionCode exception = 0; + m_element->removeAttribute(name, exception); +} + +/*! + Removes the attribute called \a name in the namespace described with \a namespaceUri + from this element. +*/ +void QWebElement::removeAttributeNS(const QString &namespaceUri, const QString &name) +{ + if (!m_element) + return; + WebCore::ExceptionCode exception = 0; + m_element->removeAttributeNS(namespaceUri, name, exception); +} + +/*! + Returns true if the element has any attributes defined; otherwise returns false; +*/ +bool QWebElement::hasAttributes() const +{ + if (!m_element) + return false; + return m_element->hasAttributes(); +} + +/*! + Returns the geometry of this element, relative to its containing frame. +*/ +QRect QWebElement::geometry() const +{ + if (!m_element) + return QRect(); + return m_element->getRect(); +} + +/*! + Returns the tag name of this element. +*/ +QString QWebElement::tagName() const +{ + if (!m_element) + return QString(); + return m_element->tagName(); +} + +/*! + Returns the namespace prefix of the element or an empty string if the element has no namespace prefix. +*/ +QString QWebElement::prefix() const +{ + if (!m_element) + return QString(); + return m_element->prefix(); +} + +/*! + If the element uses namespaces, this function returns the local name of the element; + otherwise it returns an empty string. +*/ +QString QWebElement::localName() const +{ + if (!m_element) + return QString(); + return m_element->localName(); +} + +/*! + Returns the namespace URI of this element or an empty string if the element has no namespace URI. +*/ +QString QWebElement::namespaceUri() const +{ + if (!m_element) + return QString(); + return m_element->namespaceURI(); +} + +/*! + Returns the parent element of this element or a null element if this element + is the root document element. +*/ +QWebElement QWebElement::parent() const +{ + if (m_element) + return QWebElement(m_element->parentElement()); + return QWebElement(); +} + +/*! + Returns the first child element of this element. + + \sa lastChild() previousSibling() nextSibling() +*/ +QWebElement QWebElement::firstChild() const +{ + if (!m_element) + return QWebElement(); + for (Node* child = m_element->firstChild(); child; child = child->nextSibling()) { + if (!child->isElementNode()) + continue; + Element* e = static_cast<Element*>(child); + return QWebElement(e); + } + return QWebElement(); +} + +/*! + Returns the last child element of this element. + + \sa firstChild() previousSibling() nextSibling() +*/ +QWebElement QWebElement::lastChild() const +{ + if (!m_element) + return QWebElement(); + for (Node* child = m_element->lastChild(); child; child = child->previousSibling()) { + if (!child->isElementNode()) + continue; + Element* e = static_cast<Element*>(child); + return QWebElement(e); + } + return QWebElement(); +} + +/*! + Returns the next sibling element of this element. + + \sa firstChild() previousSibling() lastChild() +*/ +QWebElement QWebElement::nextSibling() const +{ + if (!m_element) + return QWebElement(); + for (Node* sib = m_element->nextSibling(); sib; sib = sib->nextSibling()) { + if (!sib->isElementNode()) + continue; + Element* e = static_cast<Element*>(sib); + return QWebElement(e); + } + return QWebElement(); +} + +/*! + Returns the previous sibling element of this element. + + \sa firstChild() nextSibling() lastChild() +*/ +QWebElement QWebElement::previousSibling() const +{ + if (!m_element) + return QWebElement(); + for (Node* sib = m_element->previousSibling(); sib; sib = sib->previousSibling()) { + if (!sib->isElementNode()) + continue; + Element* e = static_cast<Element*>(sib); + return QWebElement(e); + } + return QWebElement(); +} + +/*! + Returns the document this element belongs to. +*/ +QWebElement QWebElement::document() const +{ + if (!m_element) + return QWebElement(); + Document* document = m_element->document(); + if (!document) + return QWebElement(); + return QWebElement(document->documentElement()); +} + +/*! + Returns the web frame this elements is a part of. If the element is + a null element null is returned. +*/ +QWebFrame *QWebElement::webFrame() const +{ + if (!m_element) + return 0; + + Document* document = m_element->document(); + if (!document) + return 0; + + Frame* frame = document->frame(); + if (!frame) + return 0; + return QWebFramePrivate::kit(frame); +} + +static bool setupScriptContext(WebCore::Element* element, JSC::JSValue& thisValue, ScriptState*& state, ScriptController*& scriptController) +{ + if (!element) + return false; + + Document* document = element->document(); + if (!document) + return false; + + Frame* frame = document->frame(); + if (!frame) + return false; + + scriptController = frame->script(); + if (!scriptController) + return false; + + state = scriptController->globalObject()->globalExec(); + if (!state) + return false; + + thisValue = toJS(state, element); + if (!thisValue) + return false; + + return true; +} + + +static bool setupScriptObject(WebCore::Element* element, ScriptObject& object, ScriptState*& state, ScriptController*& scriptController) +{ + if (!element) + return false; + + Document* document = element->document(); + if (!document) + return false; + + Frame* frame = document->frame(); + if (!frame) + return false; + + scriptController = frame->script(); + + state = scriptController->globalObject()->globalExec(); + + JSC::JSValue thisValue = toJS(state, element); + if (!thisValue) + return false; + + JSC::JSObject* thisObject = thisValue.toObject(state); + if (!thisObject) + return false; + + object = ScriptObject(thisObject); + return true; +} + +/*! + Executes the \a scriptSource with this element as the `this' object. + + \sa callFunction() +*/ +QVariant QWebElement::evaluateScript(const QString& scriptSource) +{ + if (scriptSource.isEmpty()) + return QVariant(); + + ScriptState* state = 0; + JSC::JSValue thisValue; + ScriptController* scriptController = 0; + + if (!setupScriptContext(m_element, thisValue, state, scriptController)) + return QVariant(); + + JSC::ScopeChain& scopeChain = state->dynamicGlobalObject()->globalScopeChain(); + JSC::UString script((const ushort*)scriptSource.data(), scriptSource.length()); + JSC::Completion completion = JSC::evaluate(state, scopeChain, JSC::makeSource(script), thisValue); + if ((completion.complType() != JSC::ReturnValue) && (completion.complType() != JSC::Normal)) + return QVariant(); + + JSC::JSValue result = completion.value(); + if (!result) + return QVariant(); + + int distance = 0; + return JSC::Bindings::convertValueToQVariant(state, result, QMetaType::Void, &distance); +} + +/*! + Calls the function with the given \a name and \a arguments. + + The underlying DOM element that QWebElement wraps may have dedicated functions depending + on its type. For example a form element can have the "submit" function, that would submit + the form to the destination specified in the HTML. + + \sa functions() +*/ +QVariant QWebElement::callFunction(const QString &name, const QVariantList &arguments) +{ + ScriptState* state = 0; + ScriptObject thisObject; + ScriptController* scriptController = 0; + + if (!setupScriptObject(m_element, thisObject, state, scriptController)) + return QVariant(); + + ScriptFunctionCall functionCall(state, thisObject, name); + + for (QVariantList::ConstIterator it = arguments.constBegin(), end = arguments.constEnd(); + it != end; ++it) + functionCall.appendArgument(JSC::Bindings::convertQVariantToValue(state, scriptController->bindingRootObject(), *it)); + + bool hadException = false; + ScriptValue result = functionCall.call(hadException); + if (hadException) + return QVariant(); + + int distance = 0; + return JSC::Bindings::convertValueToQVariant(state, result.jsValue(), QMetaType::Void, &distance); +} + +/*! + Returns a list of function names this element supports. + + The function names returned are the same functions that are callable from the DOM + element's JavaScript binding. + + \sa callFunction() +*/ +QStringList QWebElement::functions() const +{ + ScriptState* state = 0; + ScriptObject thisObject; + ScriptController* scriptController = 0; + + if (!setupScriptObject(m_element, thisObject, state, scriptController)) + return QStringList(); + + JSC::JSObject* object = thisObject.jsObject(); + if (!object) + return QStringList(); + + QStringList names; + + // Enumerate the contents of the object + JSC::PropertyNameArray properties(state); + object->getPropertyNames(state, properties); + for (JSC::PropertyNameArray::const_iterator it = properties.begin(); + it != properties.end(); ++it) { + + JSC::JSValue property = object->get(state, *it); + if (!property) + continue; + + JSC::JSObject* function = property.toObject(state); + if (!function) + continue; + + JSC::CallData callData; + JSC::CallType callType = function->getCallData(callData); + if (callType == JSC::CallTypeNone) + continue; + + JSC::UString ustring = (*it).ustring(); + names << QString::fromUtf16((const ushort*)ustring.rep()->data(),ustring.size()); + } + + if (state->hadException()) + state->clearException(); + + return names; +} + +/*! + Returns the value of the element's \a name property. + + If no such property exists, the returned variant is invalid. + + The return property has the same value as the corresponding property + in the element's JavaScript binding with the same name. + + Information about all available properties is provided through scriptProperties(). + + \sa setScriptableProperty(), scriptableProperties() +*/ +QVariant QWebElement::scriptableProperty(const QString &name) const +{ + ScriptState* state = 0; + ScriptObject thisObject; + ScriptController *scriptController = 0; + + if (!setupScriptObject(m_element, thisObject, state, scriptController)) + return QVariant(); + + String wcName(name); + JSC::JSValue property = thisObject.jsObject()->get(state, JSC::Identifier(state, wcName)); + + // ### + if (state->hadException()) + state->clearException(); + + int distance = 0; + return JSC::Bindings::convertValueToQVariant(state, property, QMetaType::Void, &distance); +} + +/*! + Sets the value of the element's \a name property to \a value. + + Information about all available properties is provided through scriptProperties(). + + Setting the property will affect the corresponding property + in the element's JavaScript binding with the same name. + + \sa scriptableProperty(), scriptableProperties() +*/ +void QWebElement::setScriptableProperty(const QString &name, const QVariant &value) +{ + ScriptState* state = 0; + ScriptObject thisObject; + ScriptController* scriptController = 0; + + if (!setupScriptObject(m_element, thisObject, state, scriptController)) + return; + + JSC::JSValue jsValue = JSC::Bindings::convertQVariantToValue(state, scriptController->bindingRootObject(), value); + if (!jsValue) + return; + + String wcName(name); + JSC::PutPropertySlot slot; + thisObject.jsObject()->put(state, JSC::Identifier(state, wcName), jsValue, slot); + if (state->hadException()) + state->clearException(); +} + +/*! + Returns a list of property names this element supports. + + The function names returned are the same properties that are accessible from the DOM + element's JavaScript binding. + + \sa setScriptableProperty(), scriptableProperty() +*/ +QStringList QWebElement::scriptableProperties() const +{ + if (!m_element) + return QStringList(); + + Document* document = m_element->document(); + if (!document) + return QStringList(); + + Frame* frame = document->frame(); + if (!frame) + return QStringList(); + + ScriptController* script = frame->script(); + JSC::ExecState* exec = script->globalObject()->globalExec(); + + JSC::JSValue thisValue = toJS(exec, m_element); + if (!thisValue) + return QStringList(); + + JSC::JSObject* object = thisValue.toObject(exec); + if (!object) + return QStringList(); + + QStringList names; + + // Enumerate the contents of the object + JSC::PropertyNameArray properties(exec); + object->getPropertyNames(exec, properties); + for (JSC::PropertyNameArray::const_iterator it = properties.begin(); + it != properties.end(); ++it) { + + JSC::JSValue property = object->get(exec, *it); + if (!property) + continue; + + JSC::JSObject* function = property.toObject(exec); + if (!function) + continue; + + JSC::CallData callData; + JSC::CallType callType = function->getCallData(callData); + if (callType != JSC::CallTypeNone) + continue; + + JSC::UString ustring = (*it).ustring(); + names << QString::fromUtf16((const ushort*)ustring.rep()->data(),ustring.size()); + } + + if (exec->hadException()) + exec->clearException(); + + return names; +} + +/*! + \enum QWebElement::ResolveRule + \since 4.6 + + This enum describes how QWebElement's styleProperty resolves the given + property name. + + \value IgnoreCascadingStyles Return the property value as it is defined + in the element, without respecting style inheritance and other CSS rules. + \value RespectCascadingStyles The property's value is determined using + the inheritance and importance rules defined in the document's stylesheet. +*/ + +/*! + \enum QWebElement::StylePriority + \since 4.6 + + This enum describes the priority newly set CSS properties should have when + set using QWebElement::setStyleProperty(). + + \value NormalStylePriority Define the property without important + priority even if "!important" is explicitly set in \a value. + \value DeclaredStylePriority Define the property respecting the + priority specified in \a value. + \value ImportantStylePriority Define the property to have + an important priority, this is equal to appending "!important" to the value. +*/ + +/*! + Returns the value of the style named \a name or an empty string if such one + does not exist. + + If \a rule is IgnoreCascadingStyles, the value defined inside the element + (inline in CSS terminology) is returned. + + if \a rule is RespectCascadingStyles, the actual style applied to the + element is returned. + + In CSS, the cascading part has to do with which CSS rule has priority and + is thus applied. Generally speaking, the last defined rule has priority, + thus an inline style rule has priority over an embedded block style rule, + which in return has priority over an external style rule. + + If the !important declaration is set on one of those, the declaration gets + highest priority, unless other declarations also use the !important + declaration, in which the last !important declaration takes predecence. +*/ +QString QWebElement::styleProperty(const QString &name, ResolveRule rule) const +{ + if (!m_element || !m_element->isStyledElement()) + return QString(); + + int propID = cssPropertyID(name); + + if (!propID) + return QString(); + + CSSStyleDeclaration* style = static_cast<StyledElement*>(m_element)->style(); + + if (rule == IgnoreCascadingStyles) + return style->getPropertyValue(propID); + + if (rule == RespectCascadingStyles) { + if (style->getPropertyPriority(propID)) + return style->getPropertyValue(propID); + + // We are going to resolve the style property by walking through the + // list of non-inline matched CSS rules for the element, looking for + // the highest priority definition. + + // Get an array of matched CSS rules for the given element sorted + // by importance and inheritance order. This include external CSS + // declarations, as well as embedded and inline style declarations. + + DOMWindow* domWindow = m_element->document()->frame()->domWindow(); + if (RefPtr<CSSRuleList> rules = domWindow->getMatchedCSSRules(m_element, "")) { + for (int i = rules->length(); i > 0; --i) { + CSSStyleRule* rule = static_cast<CSSStyleRule*>(rules->item(i - 1)); + + if (rule->style()->getPropertyPriority(propID)) + return rule->style()->getPropertyValue(propID); + + if (style->getPropertyValue(propID).isEmpty()) + style = rule->style(); + } + } + + return style->getPropertyValue(propID); + } + + return QString(); +} + +/*! + Sets the value of the style named \a name to \a value. + + Setting a value, doesn't necessarily mean that it will become the applied + value, due to the fact that the style property's value might have been set + earlier with priority in external or embedded style declarations. + + In order to ensure that the value will be applied, ImportantStylePriority + should be used as \a priority. + + Following the CSS syntax for property values, this is equal to appending + "!important" to the value. + + This syntax is supported when using DeclaredStylePriority as \a priority. + + Using NormalStylePriority as \a priority, the property will have normal + priority, and any "!important" declaration will be ignored. On the other + hand, using ImportantStylePriority sets the important priority even when + not explicit passed in \a value. + By using DeclaredStylePriority as \a priority the property will respect the + priority specified in \a value. +*/ +void QWebElement::setStyleProperty(const QString &name, const QString &value, StylePriority priority) +{ + if (!m_element || !m_element->isStyledElement()) + return; + + int propID = cssPropertyID(name); + CSSStyleDeclaration* style = static_cast<StyledElement*>(m_element)->style(); + if (!propID || !style) + return; + + ExceptionCode exception = 0; + + const QRegExp hasImportantTest(QLatin1String("!\\s*important")); + int index = value.indexOf(hasImportantTest); + + QString newValue = (index != -1) ? value.left(index - 1) : value; + + switch (priority) { + case NormalStylePriority: + style->setProperty(name, newValue, "", exception); + break; + case DeclaredStylePriority: + style->setProperty(name, newValue, (index != -1) ? "important" : "", exception); + break; + case ImportantStylePriority: + style->setProperty(name, newValue, "important", exception); + break; + default: + break; + } +} + +/*! + Returns the computed value for style named \a name or an empty string if the style has no such name. +*/ +QString QWebElement::computedStyleProperty(const QString &name) const +{ + if (!m_element || !m_element->isStyledElement()) + return QString(); + + int propID = cssPropertyID(name); + + RefPtr<CSSComputedStyleDeclaration> style = computedStyle(m_element); + if (!propID || !style) + return QString(); + + return style->getPropertyValue(propID); +} + +/*! + Returns the list of classes of this element. +*/ +QStringList QWebElement::classes() const +{ + if (!hasAttribute("class")) + return QStringList(); + + QStringList classes = attribute("class").simplified().split(' ', QString::SkipEmptyParts); +#if QT_VERSION >= 0x040500 + classes.removeDuplicates(); +#else + int n = classes.size(); + int j = 0; + QSet<QString> seen; + seen.reserve(n); + for (int i = 0; i < n; ++i) { + const QString& s = classes.at(i); + if (seen.contains(s)) + continue; + seen.insert(s); + if (j != i) + classes[j] = s; + ++j; + } + if (n != j) + classes.erase(classes.begin() + j, classes.end()); +#endif + return classes; +} + +/*! + Returns true if this element has a class called \a name; otherwise returns false. +*/ +bool QWebElement::hasClass(const QString &name) const +{ + QStringList list = classes(); + return list.contains(name); +} + +/*! + Adds the specified class \a name to the element. +*/ +void QWebElement::addClass(const QString &name) +{ + QStringList list = classes(); + if (!list.contains(name)) { + list.append(name); + QString value = list.join(" "); + setAttribute("class", value); + } +} + +/*! + Removes the specified class \a name from the element. +*/ +void QWebElement::removeClass(const QString &name) +{ + QStringList list = classes(); + if (list.contains(name)) { + list.removeAll(name); + QString value = list.join(" "); + setAttribute("class", value); + } +} + +/*! + Adds the specified class \a name if it is not present, + removes it if it is already present. +*/ +void QWebElement::toggleClass(const QString &name) +{ + QStringList list = classes(); + if (list.contains(name)) + list.removeAll(name); + else + list.append(name); + + QString value = list.join(" "); + setAttribute("class", value); +} + +/*! + Appends \a element as the element's last child. + + If \a element is the child of another element, it is re-parented + to this element. If \a element is a child of this element, then + its position in the list of children is changed. + + Calling this function on a null element does nothing. + + \sa prependInside(), prependOutside(), appendOutside() +*/ +void QWebElement::appendInside(const QWebElement &element) +{ + if (!m_element || element.isNull()) + return; + + ExceptionCode exception = 0; + m_element->appendChild(element.m_element, exception); +} + +/*! + Appends the result of parsing \a markup as the element's last child. + + Calling this function on a null element does nothing. + + \sa prependInside(), prependOutside(), appendOutside() +*/ +void QWebElement::appendInside(const QString &markup) +{ + if (!m_element) + return; + + if (!m_element->isHTMLElement()) + return; + + HTMLElement* htmlElement = static_cast<HTMLElement*>(m_element); + RefPtr<DocumentFragment> fragment = htmlElement->createContextualFragment(markup); + + ExceptionCode exception = 0; + m_element->appendChild(fragment, exception); +} + +/*! + Prepends \a element as the element's first child. + + If \a element is the child of another element, it is re-parented + to this element. If \a element is a child of this element, then + its position in the list of children is changed. + + Calling this function on a null element does nothing. + + \sa appendInside(), prependOutside(), appendOutside() +*/ +void QWebElement::prependInside(const QWebElement &element) +{ + if (!m_element || element.isNull()) + return; + + ExceptionCode exception = 0; + + if (m_element->hasChildNodes()) + m_element->insertBefore(element.m_element, m_element->firstChild(), exception); + else + m_element->appendChild(element.m_element, exception); +} + +/*! + Prepends the result of parsing \a markup as the element's first child. + + Calling this function on a null element does nothing. + + \sa appendInside(), prependOutside(), appendOutside() +*/ +void QWebElement::prependInside(const QString &markup) +{ + if (!m_element) + return; + + if (!m_element->isHTMLElement()) + return; + + HTMLElement* htmlElement = static_cast<HTMLElement*>(m_element); + RefPtr<DocumentFragment> fragment = htmlElement->createContextualFragment(markup); + + ExceptionCode exception = 0; + + if (m_element->hasChildNodes()) + m_element->insertBefore(fragment, m_element->firstChild(), exception); + else + m_element->appendChild(fragment, exception); +} + + +/*! + Inserts \a element before this element. + + If \a element is the child of another element, it is re-parented + to the parent of this element. + + Calling this function on a null element does nothing. + + \sa appendInside(), prependInside(), appendOutside() +*/ +void QWebElement::prependOutside(const QWebElement &element) +{ + if (!m_element || element.isNull()) + return; + + if (!m_element->parent()) + return; + + ExceptionCode exception = 0; + m_element->parent()->insertBefore(element.m_element, m_element, exception); +} + +/*! + Inserts the result of parsing \a markup before this element. + + Calling this function on a null element does nothing. + + \sa appendInside(), prependInside(), appendOutside() +*/ +void QWebElement::prependOutside(const QString &markup) +{ + if (!m_element) + return; + + if (!m_element->parent()) + return; + + if (!m_element->isHTMLElement()) + return; + + HTMLElement* htmlElement = static_cast<HTMLElement*>(m_element); + RefPtr<DocumentFragment> fragment = htmlElement->createContextualFragment(markup); + + ExceptionCode exception = 0; + m_element->parent()->insertBefore(fragment, m_element, exception); +} + +/*! + Inserts \a element after this element. + + If \a element is the child of another element, it is re-parented + to the parent of this element. + + Calling this function on a null element does nothing. + + \sa appendInside(), prependInside(), prependOutside() +*/ +void QWebElement::appendOutside(const QWebElement &element) +{ + if (!m_element || element.isNull()) + return; + + if (!m_element->parent()) + return; + + ExceptionCode exception = 0; + if (!m_element->nextSibling()) + m_element->parent()->appendChild(element.m_element, exception); + else + m_element->parent()->insertBefore(element.m_element, m_element->nextSibling(), exception); +} + +/*! + Inserts the result of parsing \a markup after this element. + + Calling this function on a null element does nothing. + + \sa appendInside(), prependInside(), prependOutside() +*/ +void QWebElement::appendOutside(const QString &markup) +{ + if (!m_element) + return; + + if (!m_element->parent()) + return; + + if (!m_element->isHTMLElement()) + return; + + HTMLElement* htmlElement = static_cast<HTMLElement*>(m_element); + RefPtr<DocumentFragment> fragment = htmlElement->createContextualFragment(markup); + + ExceptionCode exception = 0; + if (!m_element->nextSibling()) + m_element->parent()->appendChild(fragment, exception); + else + m_element->parent()->insertBefore(fragment, m_element->nextSibling(), exception); +} + +/*! + Returns a clone of this element. + + The clone may be inserted at any point in the document. + + \sa appendInside(), prependInside(), prependOutside(), appendOutside() +*/ +QWebElement QWebElement::clone() const +{ + if (!m_element) + return QWebElement(); + + return QWebElement(m_element->cloneElementWithChildren().get()); +} + +/*! + Removes this element from the document and returns a reference + to this. + + The element is still valid after removal, and can be inserted into + other parts of the document. + + \sa removeChildren(), removeFromDocument() +*/ +QWebElement &QWebElement::takeFromDocument() +{ + if (!m_element) + return *this; + + ExceptionCode exception = 0; + m_element->remove(exception); + + return *this; +} + +/*! + Removes this element from the document and makes this + a null element. + + \sa removeChildren(), takeFromDocument() +*/ +void QWebElement::removeFromDocument() +{ + if (!m_element) + return; + + ExceptionCode exception = 0; + m_element->remove(exception); + m_element->deref(); + m_element = 0; +} + +/*! + Removes all children from this element. + + \sa removeFromDocument(), takeFromDocument() +*/ +void QWebElement::removeChildren() +{ + if (!m_element) + return; + + m_element->removeAllChildren(); +} + +static RefPtr<Node> findInsertionPoint(PassRefPtr<Node> root) +{ + RefPtr<Node> node = root; + + // Go as far down the tree as possible. + while (node->hasChildNodes() && node->firstChild()->isElementNode()) + node = node->firstChild(); + + // TODO: Implement SVG support + if (node->isHTMLElement()) { + HTMLElement* element = static_cast<HTMLElement*>(node.get()); + + // The insert point could be a non-enclosable tag and it can thus + // never have children, so go one up. Get the parent element, and not + // note as a root note will always exist. + if (element->endTagRequirement() == TagStatusForbidden) + node = node->parentElement(); + } + + return node; +} + +/*! + Enclose the contents of this element in \a element as the child + of the deepest descendant element within the structure of the + first element provided. + + \sa encloseWith() +*/ +void QWebElement::encloseContentsWith(const QWebElement &element) +{ + if (!m_element || element.isNull()) + return; + + RefPtr<Node> insertionPoint = findInsertionPoint(element.m_element); + + if (!insertionPoint) + return; + + ExceptionCode exception = 0; + + // reparent children + for (RefPtr<Node> child = m_element->firstChild(); child;) { + RefPtr<Node> next = child->nextSibling(); + insertionPoint->appendChild(child, exception); + child = next; + } + + if (m_element->hasChildNodes()) + m_element->insertBefore(element.m_element, m_element->firstChild(), exception); + else + m_element->appendChild(element.m_element, exception); +} + +/*! + Enclose the contents of this element in the result of parsing + \a markup as the child of the deepest descendant element within + the structure of the first element provided. + + \sa encloseWith() +*/ +void QWebElement::encloseContentsWith(const QString &markup) +{ + if (!m_element) + return; + + if (!m_element->parent()) + return; + + if (!m_element->isHTMLElement()) + return; + + HTMLElement* htmlElement = static_cast<HTMLElement*>(m_element); + RefPtr<DocumentFragment> fragment = htmlElement->createContextualFragment(markup); + + if (!fragment || !fragment->firstChild()) + return; + + RefPtr<Node> insertionPoint = findInsertionPoint(fragment->firstChild()); + + if (!insertionPoint) + return; + + ExceptionCode exception = 0; + + // reparent children + for (RefPtr<Node> child = m_element->firstChild(); child;) { + RefPtr<Node> next = child->nextSibling(); + insertionPoint->appendChild(child, exception); + child = next; + } + + if (m_element->hasChildNodes()) + m_element->insertBefore(fragment, m_element->firstChild(), exception); + else + m_element->appendChild(fragment, exception); +} + +/*! + Enclose this element in \a element as the child of the deepest + descendant element within the structure of the first element + provided. + + \sa replace() +*/ +void QWebElement::encloseWith(const QWebElement &element) +{ + if (!m_element || element.isNull()) + return; + + RefPtr<Node> insertionPoint = findInsertionPoint(element.m_element); + + if (!insertionPoint) + return; + + // Keep reference to these two nodes before pulling out this element and + // wrapping it in the fragment. The reason for doing it in this order is + // that once the fragment has been added to the document it is empty, so + // we no longer have access to the nodes it contained. + Node* parentNode = m_element->parent(); + Node* siblingNode = m_element->nextSibling(); + + ExceptionCode exception = 0; + insertionPoint->appendChild(m_element, exception); + + if (!siblingNode) + parentNode->appendChild(element.m_element, exception); + else + parentNode->insertBefore(element.m_element, siblingNode, exception); +} + +/*! + Enclose this element in the result of parsing \a markup, + as the last child. + + \sa replace() +*/ +void QWebElement::encloseWith(const QString &markup) +{ + if (!m_element) + return; + + if (!m_element->parent()) + return; + + if (!m_element->isHTMLElement()) + return; + + HTMLElement* htmlElement = static_cast<HTMLElement*>(m_element); + RefPtr<DocumentFragment> fragment = htmlElement->createContextualFragment(markup); + + if (!fragment || !fragment->firstChild()) + return; + + RefPtr<Node> insertionPoint = findInsertionPoint(fragment->firstChild()); + + if (!insertionPoint) + return; + + // Keep reference to these two nodes before pulling out this element and + // wrapping it in the fragment. The reason for doing it in this order is + // that once the fragment has been added to the document it is empty, so + // we no longer have access to the nodes it contained. + Node* parentNode = m_element->parent(); + Node* siblingNode = m_element->nextSibling(); + + ExceptionCode exception = 0; + insertionPoint->appendChild(m_element, exception); + + if (!siblingNode) + parentNode->appendChild(fragment, exception); + else + parentNode->insertBefore(fragment, siblingNode, exception); +} + +/*! + Replaces this element with \a element. + + It is not possible to replace the <html>, <head>, or <body> + elements using this method. + + \sa encloseWith() +*/ +void QWebElement::replace(const QWebElement &element) +{ + if (!m_element || element.isNull()) + return; + + appendOutside(element); + takeFromDocument(); +} + +/*! + Replaces this element with the result of parsing \a markup. + + It is not possible to replace the <html>, <head>, or <body> + elements using this method. + + \sa encloseWith() +*/ +void QWebElement::replace(const QString &markup) +{ + if (!m_element) + return; + + appendOutside(markup); + takeFromDocument(); +} + +/*! + \fn inline bool QWebElement::operator==(const QWebElement& o) const; + + Returns true if this element points to the same underlying DOM object than \a o; otherwise returns false. +*/ + +/*! + \fn inline bool QWebElement::operator!=(const QWebElement& o) const; + + Returns true if this element points to a different underlying DOM object than \a o; otherwise returns false. +*/ diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebelement.h b/src/3rdparty/webkit/WebKit/qt/Api/qwebelement.h new file mode 100644 index 0000000..7e56d0f --- /dev/null +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebelement.h @@ -0,0 +1,153 @@ +/* + Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef QWEBELEMENT_H +#define QWEBELEMENT_H + +#include <QString> +#include <QRect> +#include <QVariant> +#include <QExplicitlySharedDataPointer> + +#include "qwebkitglobal.h" +namespace WebCore { + class Element; + class Node; +} + +class QWebFrame; +class QWebElementPrivate; + +class QWEBKIT_EXPORT QWebElement +{ +public: + QWebElement(); + QWebElement(const QWebElement &); + QWebElement &operator=(const QWebElement &); + ~QWebElement(); + + bool operator==(const QWebElement& o) const; + bool operator!=(const QWebElement& o) const; + + bool isNull() const; + + QList<QWebElement> findAll(const QString &selectorQuery) const; + QWebElement findFirst(const QString &selectorQuery) const; + + void setPlainText(const QString &text); + QString toPlainText() const; + + void setOuterXml(const QString &markup); + QString toOuterXml() const; + + void setInnerXml(const QString &markup); + QString toInnerXml() const; + + void setAttribute(const QString &name, const QString &value); + void setAttributeNS(const QString &namespaceUri, const QString &name, const QString &value); + QString attribute(const QString &name, const QString &defaultValue = QString()) const; + QString attributeNS(const QString &namespaceUri, const QString &name, const QString &defaultValue = QString()) const; + bool hasAttribute(const QString &name) const; + bool hasAttributeNS(const QString &namespaceUri, const QString &name) const; + void removeAttribute(const QString &name); + void removeAttributeNS(const QString &namespaceUri, const QString &name); + bool hasAttributes() const; + + QStringList classes() const; + bool hasClass(const QString &name) const; + void addClass(const QString &name); + void removeClass(const QString &name); + void toggleClass(const QString &name); + + QRect geometry() const; + + QString tagName() const; + QString prefix() const; + QString localName() const; + QString namespaceUri() const; + + QWebElement parent() const; + QWebElement firstChild() const; + QWebElement lastChild() const; + QWebElement nextSibling() const; + QWebElement previousSibling() const; + QWebElement document() const; + QWebFrame *webFrame() const; + + // TODO: Add QList<QWebElement> overloads + // docs need example snippet + void appendInside(const QString &markup); + void appendInside(const QWebElement &element); + + // docs need example snippet + void prependInside(const QString &markup); + void prependInside(const QWebElement &element); + + // docs need example snippet + void appendOutside(const QString &markup); + void appendOutside(const QWebElement &element); + + // docs need example snippet + void prependOutside(const QString &markup); + void prependOutside(const QWebElement &element); + + // docs need example snippet + void encloseContentsWith(const QWebElement &element); + void encloseContentsWith(const QString &markup); + void encloseWith(const QString &markup); + void encloseWith(const QWebElement &element); + + void replace(const QString &markup); + void replace(const QWebElement &element); + + QWebElement clone() const; + QWebElement &takeFromDocument(); + void removeFromDocument(); + void removeChildren(); + + QVariant evaluateScript(const QString& scriptSource); + + QVariant callFunction(const QString &functionName, const QVariantList &arguments = QVariantList()); + QStringList functions() const; + + QVariant scriptableProperty(const QString &name) const; + void setScriptableProperty(const QString &name, const QVariant &value); + QStringList scriptableProperties() const; + + enum ResolveRule { IgnoreCascadingStyles, RespectCascadingStyles }; + QString styleProperty(const QString &name, ResolveRule = IgnoreCascadingStyles) const; + + enum StylePriority { NormalStylePriority, DeclaredStylePriority, ImportantStylePriority }; + void setStyleProperty(const QString &name, const QString &value, StylePriority = DeclaredStylePriority); + + QString computedStyleProperty(const QString &name) const; + +private: + explicit QWebElement(WebCore::Element *domElement); + explicit QWebElement(WebCore::Node *node); + + friend class QWebFrame; + friend class QWebHitTestResult; + friend class QWebHitTestResultPrivate; + + QWebElementPrivate *d; + WebCore::Element *m_element; +}; + +#endif // QWEBELEMENT_H diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebframe.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebframe.cpp index e565476..db4bfec 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebframe.cpp +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebframe.cpp @@ -25,6 +25,7 @@ #include "qwebframe_p.h" #include "qwebsecurityorigin.h" #include "qwebsecurityorigin_p.h" +#include "qwebelement.h" #include "DocumentLoader.h" #include "FocusController.h" @@ -44,6 +45,7 @@ #include "SubstituteData.h" #include "markup.h" +#include "htmlediting.h" #include "RenderTreeAsText.h" #include "Element.h" #include "Document.h" @@ -95,6 +97,7 @@ QT_END_NAMESPACE void QWEBKIT_EXPORT qt_drt_setJavaScriptProfilingEnabled(QWebFrame* qframe, bool enabled) { +#if ENABLE(JAVASCRIPT_DEBUGGER) Frame* frame = QWebFramePrivate::core(qframe); InspectorController* controller = frame->page()->inspectorController(); if (!controller) @@ -103,6 +106,64 @@ void QWEBKIT_EXPORT qt_drt_setJavaScriptProfilingEnabled(QWebFrame* qframe, bool controller->enableProfiler(); else controller->disableProfiler(); +#endif +} + +// Pause a given CSS animation or transition on the target node at a specific time. +// If the animation or transition is already paused, it will update its pause time. +// This method is only intended to be used for testing the CSS animation and transition system. +bool QWEBKIT_EXPORT qt_drt_pauseAnimation(QWebFrame *qframe, const QString &animationName, double time, const QString &elementId) +{ + Frame* frame = QWebFramePrivate::core(qframe); + if (!frame) + return false; + + AnimationController* controller = frame->animation(); + if (!controller) + return false; + + Document* doc = frame->document(); + Q_ASSERT(doc); + + Node* coreNode = doc->getElementById(elementId); + if (!coreNode || !coreNode->renderer()) + return false; + + return controller->pauseAnimationAtTime(coreNode->renderer(), animationName, time); +} + +bool QWEBKIT_EXPORT qt_drt_pauseTransitionOfProperty(QWebFrame *qframe, const QString &propertyName, double time, const QString &elementId) +{ + Frame* frame = QWebFramePrivate::core(qframe); + if (!frame) + return false; + + AnimationController* controller = frame->animation(); + if (!controller) + return false; + + Document* doc = frame->document(); + Q_ASSERT(doc); + + Node* coreNode = doc->getElementById(elementId); + if (!coreNode || !coreNode->renderer()) + return false; + + return controller->pauseTransitionAtTime(coreNode->renderer(), propertyName, time); +} + +// Returns the total number of currently running animations (includes both CSS transitions and CSS animations). +int QWEBKIT_EXPORT qt_drt_numberOfActiveAnimations(QWebFrame *qframe) +{ + Frame* frame = QWebFramePrivate::core(qframe); + if (!frame) + return false; + + AnimationController* controller = frame->animation(); + if (!controller) + return false; + + return controller->numberOfActiveAnimations(); } void QWebFramePrivate::init(QWebFrame *qframe, WebCore::Page *webcorePage, QWebFrameData *frameData) @@ -144,6 +205,37 @@ WebCore::Scrollbar* QWebFramePrivate::verticalScrollBar() const return frame->view()->verticalScrollbar(); } +void QWebFramePrivate::renderPrivate(QPainter *painter, const QRegion &clip, bool contents) +{ + if (!frame->view() || !frame->contentRenderer()) + return; + + QVector<QRect> vector = clip.rects(); + if (vector.isEmpty()) + return; + + WebCore::FrameView* view = frame->view(); + view->layoutIfNeededRecursive(); + + GraphicsContext context(painter); + + if (!contents) + view->paint(&context, vector.first()); + else + view->paintContents(&context, vector.first()); + + for (int i = 1; i < vector.size(); ++i) { + const QRect& clipRect = vector.at(i); + painter->save(); + painter->setClipRect(clipRect, Qt::IntersectClip); + if (!contents) + view->paint(&context, clipRect); + else + view->paintContents(&context, clipRect); + painter->restore(); + } +} + /*! \class QWebFrame \since 4.4 @@ -192,7 +284,7 @@ QWebFrame::QWebFrame(QWebPage *parent, QWebFrameData *frameData) if (!frameData->url.isEmpty()) { WebCore::ResourceRequest request(frameData->url, frameData->referrer); - d->frame->loader()->load(request, frameData->name); + d->frame->loader()->load(request, frameData->name, false); } } @@ -260,15 +352,15 @@ void QWebFrame::addToJavaScriptWindowObject(const QString &name, QObject *object JSC::ExecState* exec = window->globalExec(); - JSC::JSObject*runtimeObject = - JSC::Bindings::Instance::createRuntimeObject(exec, JSC::Bindings::QtInstance::getQtInstance(object, root, ownership)); + JSC::JSObject* runtimeObject = + JSC::Bindings::QtInstance::getQtInstance(object, root, ownership)->createRuntimeObject(exec); JSC::PutPropertySlot slot; window->put(exec, JSC::Identifier(exec, (const UChar *) name.constData(), name.length()), runtimeObject, slot); } /*! - Returns the frame's content as HTML, enclosed in HTML and BODY tags. + Returns the frame's content, converted to HTML. \sa setHtml(), toPlainText() */ @@ -280,8 +372,7 @@ QString QWebFrame::toHtml() const } /*! - Returns the content of this frame converted to plain text, completely - stripped of all HTML formatting. + Returns the content of this frame converted to plain text. \sa toHtml() */ @@ -468,7 +559,7 @@ void QWebFrame::load(const QWebNetworkRequest &req) if (!postData.isEmpty()) request.setHTTPBody(WebCore::FormData::create(postData.constData(), postData.size())); - d->frame->loader()->load(request); + d->frame->loader()->load(request, false); if (d->parentFrame()) d->page->d->insideOpenCall = false; @@ -524,7 +615,7 @@ void QWebFrame::load(const QNetworkRequest &req, if (!body.isEmpty()) request.setHTTPBody(WebCore::FormData::create(body.constData(), body.size())); - d->frame->loader()->load(request); + d->frame->loader()->load(request, false); if (d->parentFrame()) d->page->d->insideOpenCall = false; @@ -551,7 +642,7 @@ void QWebFrame::setHtml(const QString &html, const QUrl &baseUrl) const QByteArray utf8 = html.toUtf8(); WTF::RefPtr<WebCore::SharedBuffer> data = WebCore::SharedBuffer::create(utf8.constData(), utf8.length()); WebCore::SubstituteData substituteData(data, WebCore::String("text/html"), WebCore::String("utf-8"), kurl); - d->frame->loader()->load(request, substituteData); + d->frame->loader()->load(request, substituteData, false); } /*! @@ -574,7 +665,7 @@ void QWebFrame::setContent(const QByteArray &data, const QString &mimeType, cons if (actualMimeType.isEmpty()) actualMimeType = QLatin1String("text/html"); WebCore::SubstituteData substituteData(buffer, WebCore::String(actualMimeType), WebCore::String(), kurl); - d->frame->loader()->load(request, substituteData); + d->frame->loader()->load(request, substituteData, false); } @@ -712,6 +803,21 @@ int QWebFrame::scrollBarMinimum(Qt::Orientation orientation) const } /*! + \since 4.6 + Returns the geometry for the scrollbar with orientation \a orientation. + + If the scrollbar does not exist an empty rect is returned. +*/ +QRect QWebFrame::scrollBarGeometry(Qt::Orientation orientation) const +{ + Scrollbar *sb; + sb = (orientation == Qt::Horizontal) ? d->horizontalScrollBar() : d->verticalScrollBar(); + if (sb) + return sb->frameRect(); + return QRect(); +} + +/*! \since 4.5 Scrolls the frame \a dx pixels to the right and \a dy pixels downward. Both \a dx and \a dy may be negative. @@ -757,25 +863,7 @@ void QWebFrame::setScrollPosition(const QPoint &pos) */ void QWebFrame::render(QPainter *painter, const QRegion &clip) { - if (!d->frame->view() || !d->frame->contentRenderer()) - return; - - d->frame->view()->layoutIfNeededRecursive(); - - GraphicsContext ctx(painter); - QVector<QRect> vector = clip.rects(); - WebCore::FrameView* view = d->frame->view(); - for (int i = 0; i < vector.size(); ++i) { - if (i > 0) { - painter->save(); - painter->setClipRect(vector.at(i), Qt::IntersectClip); - } - - view->paint(&ctx, vector.at(i)); - - if (i > 0) - painter->restore(); - } + d->renderPrivate(painter, clip); } /*! @@ -783,14 +871,19 @@ void QWebFrame::render(QPainter *painter, const QRegion &clip) */ void QWebFrame::render(QPainter *painter) { - if (!d->frame->view() || !d->frame->contentRenderer()) + if (!d->frame->view()) return; - d->frame->view()->layoutIfNeededRecursive(); + d->renderPrivate(painter, QRegion(d->frame->view()->frameRect())); +} - GraphicsContext ctx(painter); - WebCore::FrameView* view = d->frame->view(); - view->paint(&ctx, view->frameRect()); +/*! + \since 4.6 + Render the frame's \a contents into \a painter while clipping to \a contents. +*/ +void QWebFrame::renderContents(QPainter *painter, const QRegion &contents) +{ + d->renderPrivate(painter, contents, true); } /*! @@ -862,6 +955,8 @@ QRect QWebFrame::geometry() const /*! \property QWebFrame::contentsSize \brief the size of the contents in this frame + + \sa contentsSizeChanged() */ QSize QWebFrame::contentsSize() const { @@ -872,6 +967,47 @@ QSize QWebFrame::contentsSize() const } /*! + \since 4.6 + + Returns the document element of this frame. + + The document element provides access to the entire structured + content of the frame. +*/ +QWebElement QWebFrame::documentElement() const +{ + WebCore::Document *doc = d->frame->document(); + if (!doc) + return QWebElement(); + return QWebElement(doc->documentElement()); +} + +/*! + \since 4.6 + Returns a new collection of elements that are children of the frame's + document element and that match the given CSS selector \a selectorQuery. + + \sa QWebElement::findAll() +*/ +QList<QWebElement> QWebFrame::findAllElements(const QString &selectorQuery) const +{ + return documentElement().findAll(selectorQuery); +} + +/*! + \since 4.6 + Returns the first element in the frame's document that matches the + given CSS selector \a selectorQuery. Returns a null element if there is no + match. + + \sa QWebElement::findFirst() +*/ +QWebElement QWebFrame::findFirstElement(const QString &selectorQuery) const +{ + return documentElement().findFirst(selectorQuery); +} + +/*! Performs a hit test on the frame contents at the given position \a pos and returns the hit test result. */ QWebHitTestResult QWebFrame::hitTestContent(const QPoint &pos) const @@ -879,7 +1015,7 @@ 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), /*allowShadowContent*/ false); + HitTestResult result = d->frame->eventHandler()->hitTestResultAtPoint(d->frame->view()->windowToContents(pos), /*allowShadowContent*/ false, /*ignoreClipping*/ true); return QWebHitTestResult(new QWebHitTestResultPrivate(result)); } @@ -994,11 +1130,9 @@ QVariant QWebFrame::evaluateJavaScript(const QString& scriptSource) ScriptController *proxy = d->frame->script(); QVariant rc; if (proxy) { - JSC::JSValuePtr v = proxy->evaluate(ScriptSourceCode(scriptSource)).jsValue(); - if (v) { - int distance = 0; - rc = JSC::Bindings::convertValueToQVariant(proxy->globalObject()->globalExec(), v, QMetaType::Void, &distance); - } + JSC::JSValue v = proxy->evaluate(ScriptSourceCode(scriptSource)).jsValue(); + int distance = 0; + rc = JSC::Bindings::convertValueToQVariant(proxy->globalObject()->globalExec(), v, QMetaType::Void, &distance); } return rc; } @@ -1080,6 +1214,16 @@ QWebFrame* QWebFramePrivate::kit(WebCore::Frame* coreFrame) */ /*! + \fn void QWebFrame::contentsSizeChanged(const QSize &size) + \since 4.6 + + This signal is emitted when the frame's contents size changes + to \a size. + + \sa contentsSize() +*/ + +/*! \class QWebHitTestResult \since 4.4 \brief The QWebHitTestResult class provides information about the web @@ -1100,6 +1244,7 @@ QWebHitTestResult::QWebHitTestResult(QWebHitTestResultPrivate *priv) QWebHitTestResultPrivate::QWebHitTestResultPrivate(const WebCore::HitTestResult &hitTest) : isContentEditable(false) , isContentSelected(false) + , isScrollBar(false) { if (!hitTest.innerNode()) return; @@ -1111,6 +1256,7 @@ QWebHitTestResultPrivate::QWebHitTestResultPrivate(const WebCore::HitTestResult linkTitle = hitTest.titleDisplayString(); alternateText = hitTest.altDisplayString(); imageUrl = hitTest.absoluteImageURL(); + innerNode = hitTest.innerNode(); innerNonSharedNode = hitTest.innerNonSharedNode(); WebCore::Image *img = hitTest.image(); if (img) { @@ -1121,13 +1267,19 @@ QWebHitTestResultPrivate::QWebHitTestResultPrivate(const WebCore::HitTestResult WebCore::Frame *wframe = hitTest.targetFrame(); if (wframe) linkTargetFrame = QWebFramePrivate::kit(wframe); + Element* urlElement = hitTest.URLElement(); + if (urlElement) + linkTarget = urlElement->target(); 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())); } /*! @@ -1204,6 +1356,21 @@ QRect QWebHitTestResult::boundingRect() const } /*! + \since 4.6 + Returns the block element that encloses the element hit. + + A block element is an element that is rendered using the + CSS "block" style. This includes for example text + paragraphs. +*/ +QWebElement QWebHitTestResult::enclosingBlockElement() const +{ + if (!d) + return QWebElement(); + return d->enclosingBlock; +} + +/*! Returns the title of the nearest enclosing HTML element. */ QString QWebHitTestResult::title() const @@ -1244,7 +1411,22 @@ QUrl QWebHitTestResult::linkTitle() const } /*! + \since 4.6 + Returns the name of the target frame that will load the link if it is activated. + + \sa linkTargetFrame() +*/ +QString QWebHitTestResult::linkTarget() const +{ + if (!d) + return 0; + return d->linkTarget; +} + +/*! Returns the frame that will load the link if it is activated. + + \sa linkTarget() */ QWebFrame *QWebHitTestResult::linkTargetFrame() const { @@ -1305,6 +1487,18 @@ bool QWebHitTestResult::isContentSelected() const } /*! + \since 4.6 + Returns the underlying DOM element as QWebElement. +*/ +QWebElement QWebHitTestResult::element() const +{ + if (!d || !d->innerNonSharedNode || !d->innerNonSharedNode->isElementNode()) + return QWebElement(); + + return QWebElement(static_cast<WebCore::Element*>(d->innerNonSharedNode.get())); +} + +/*! Returns the frame the hit test was executed in. */ QWebFrame *QWebHitTestResult::frame() const @@ -1314,3 +1508,13 @@ QWebFrame *QWebHitTestResult::frame() const return d->frame; } +/*! + \since 4.6 + Returns true if the test includes a scrollbar. +*/ +bool QWebHitTestResult::isScrollBar() const +{ + if (!d) + return false; + return d->isScrollBar; +} diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebframe.h b/src/3rdparty/webkit/WebKit/qt/Api/qwebframe.h index 18ae697..ebc22fe 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebframe.h +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebframe.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) + Copyright (C) 2008,2009 Nokia Corporation and/or its subsidiary(-ies) Copyright (C) 2007 Staikos Computing Services Inc. This library is free software; you can redistribute it and/or @@ -49,6 +49,7 @@ class QWebPage; class QWebHitTestResult; class QWebHistoryItem; class QWebSecurityOrigin; +class QWebElement; namespace WebCore { class WidgetPrivate; @@ -71,12 +72,14 @@ public: QPoint pos() const; QRect boundingRect() const; + QWebElement enclosingBlockElement() const; QString title() const; QString linkText() const; QUrl linkUrl() const; QUrl linkTitle() const; QWebFrame *linkTargetFrame() const; + QString linkTarget() const; QString alternateText() const; // for img, area, input and applet @@ -86,8 +89,12 @@ public: bool isContentEditable() const; bool isContentSelected() const; + QWebElement element() const; + QWebFrame *frame() const; + bool isScrollBar() const; + private: QWebHitTestResult(QWebHitTestResultPrivate *priv); QWebHitTestResultPrivate *d; @@ -150,6 +157,7 @@ public: int scrollBarValue(Qt::Orientation orientation) const; int scrollBarMinimum(Qt::Orientation orientation) const; int scrollBarMaximum(Qt::Orientation orientation) const; + QRect scrollBarGeometry(Qt::Orientation orientation) const; void scroll(int, int); QPoint scrollPosition() const; @@ -157,6 +165,7 @@ public: void render(QPainter *painter, const QRegion &clip); void render(QPainter *painter); + void renderContents(QPainter *painter, const QRegion &contents); void setTextSizeMultiplier(qreal factor); qreal textSizeMultiplier() const; @@ -168,6 +177,10 @@ public: QRect geometry() const; QSize contentsSize() const; + QWebElement documentElement() const; + QList<QWebElement> findAllElements(const QString &selectorQuery) const; + QWebElement findFirstElement(const QString &selectorQuery) const; + QWebHitTestResult hitTestContent(const QPoint &pos) const; virtual bool event(QEvent *); @@ -191,6 +204,8 @@ Q_SIGNALS: void iconChanged(); + void contentsSizeChanged(const QSize &size); + private: friend class QWebPage; friend class QWebPagePrivate; diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebframe_p.h b/src/3rdparty/webkit/WebKit/qt/Api/qwebframe_p.h index 14f69cd..325e6e0 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebframe_p.h +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebframe_p.h @@ -27,6 +27,7 @@ #include "EventHandler.h" #include "KURL.h" #include "PlatformString.h" +#include "qwebelement.h" #include "wtf/RefPtr.h" #include "Frame.h" @@ -39,7 +40,6 @@ namespace WebCore } class QWebPage; - class QWebFrameData { public: @@ -81,6 +81,8 @@ public: static WebCore::Frame* core(QWebFrame*); static QWebFrame* kit(WebCore::Frame*); + void renderPrivate(QPainter *painter, const QRegion &clip, bool contents = false); + QWebFrame *q; WebCore::FrameLoaderClientQt *frameLoaderClient; WebCore::Frame *frame; @@ -94,22 +96,26 @@ public: class QWebHitTestResultPrivate { public: - QWebHitTestResultPrivate() : isContentEditable(false), isContentSelected(false) {} + QWebHitTestResultPrivate() : isContentEditable(false), isContentSelected(false), isScrollBar(false) {} QWebHitTestResultPrivate(const WebCore::HitTestResult &hitTest); QPoint pos; QRect boundingRect; + QWebElement enclosingBlock; QString title; QString linkText; QUrl linkUrl; QString linkTitle; QPointer<QWebFrame> linkTargetFrame; + QString linkTarget; QString alternateText; QUrl imageUrl; QPixmap pixmap; bool isContentEditable; bool isContentSelected; + bool isScrollBar; QPointer<QWebFrame> frame; + RefPtr<WebCore::Node> innerNode; RefPtr<WebCore::Node> innerNonSharedNode; }; diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebkitglobal.h b/src/3rdparty/webkit/WebKit/qt/Api/qwebkitglobal.h index 19d9218..0885bdc 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebkitglobal.h +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebkitglobal.h @@ -22,22 +22,14 @@ #include <QtCore/qglobal.h> -#if defined(Q_OS_WIN) -# if defined(QT_NODLL) -# undef QT_MAKEDLL -# undef QT_DLL -# elif defined(QT_MAKEDLL) /* create a Qt DLL library */ -# if defined(QT_DLL) -# undef QT_DLL -# endif -# if defined(BUILD_WEBKIT) -# define QWEBKIT_EXPORT Q_DECL_EXPORT -# else -# define QWEBKIT_EXPORT Q_DECL_IMPORT -# endif -# elif defined(QT_DLL) /* use a Qt DLL library */ -# define QWEBKIT_EXPORT Q_DECL_IMPORT +#if defined(QT_MAKEDLL) /* create a Qt DLL library */ +# if defined(BUILD_WEBKIT) +# define QWEBKIT_EXPORT Q_DECL_EXPORT +# else +# define QWEBKIT_EXPORT Q_DECL_IMPORT # endif +#elif defined(QT_DLL) /* use a Qt DLL library */ +# define QWEBKIT_EXPORT Q_DECL_IMPORT #endif #if !defined(QWEBKIT_EXPORT) diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp index 77add54..ee64cad 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp @@ -34,6 +34,7 @@ #include "FrameLoader.h" #include "FrameLoaderClientQt.h" #include "FrameView.h" +#include "FormState.h" #include "ChromeClientQt.h" #include "ContextMenu.h" #include "ContextMenuClientQt.h" @@ -60,9 +61,11 @@ #include "ProgressTracker.h" #include "RefPtr.h" #include "HashMap.h" +#include "HTMLFormElement.h" #include "HitTestResult.h" #include "WindowFeatures.h" #include "LocalizedStrings.h" +#include "Cache.h" #include "runtime/InitializeThreading.h" #include <QApplication> @@ -179,6 +182,21 @@ static const char* editorCommandWebActions[] = "SelectAll", // SelectAll + "PasteAndMatchStyle", // PasteAndMatchStyle + "RemoveFormat", // RemoveFormat + "Strikethrough", // ToggleStrikethrough, + "Subscript", // ToggleSubscript + "Superscript", // ToggleSuperscript + "InsertUnorderedList", // InsertUnorderedList + "InsertOrderedList", // InsertOrderedList + "Indent", // Indent + "Outdent", // Outdent, + + "AlignCenter", // AlignCenter, + "AlignJustified", // AlignJustified, + "AlignLeft", // AlignLeft, + "AlignRight", // AlignRight, + 0 // WebActionCount }; @@ -263,6 +281,7 @@ QWebPagePrivate::QWebPagePrivate(QWebPage *qq) insideOpenCall = false; forwardUnsupportedContent = false; editable = false; + useFixedLayout = false; linkPolicy = QWebPage::DontDelegateLinks; #ifndef QT_NO_CONTEXTMENU currentContextMenu = 0; @@ -426,6 +445,14 @@ void QWebPagePrivate::_q_webActionTriggered(bool checked) q->triggerAction(action, checked); } +#ifndef NDEBUG +void QWebPagePrivate::_q_cleanupLeakMessages() +{ + // Need this to make leak messages accurate. + cache()->setCapacities(0, 0, 0); +} +#endif + void QWebPagePrivate::updateAction(QWebPage::WebAction action) { QAction *a = actions[action]; @@ -535,6 +562,19 @@ void QWebPagePrivate::updateEditorActions() updateAction(QWebPage::ToggleUnderline); updateAction(QWebPage::InsertParagraphSeparator); updateAction(QWebPage::InsertLineSeparator); + updateAction(QWebPage::PasteAndMatchStyle); + updateAction(QWebPage::RemoveFormat); + updateAction(QWebPage::ToggleStrikethrough); + updateAction(QWebPage::ToggleSubscript); + updateAction(QWebPage::ToggleSuperscript); + updateAction(QWebPage::InsertUnorderedList); + updateAction(QWebPage::InsertOrderedList); + updateAction(QWebPage::Indent); + updateAction(QWebPage::Outdent); + updateAction(QWebPage::AlignCenter); + updateAction(QWebPage::AlignJustified); + updateAction(QWebPage::AlignLeft); + updateAction(QWebPage::AlignRight); } void QWebPagePrivate::timerEvent(QTimerEvent *ev) @@ -1026,9 +1066,9 @@ QVariant QWebPage::inputMethodQuery(Qt::InputMethodQuery property) const case Qt::ImCursorPosition: { Frame *frame = d->page->focusController()->focusedFrame(); if (frame) { - Selection selection = frame->selection()->selection(); + VisibleSelection selection = frame->selection()->selection(); if (selection.isCaret()) { - return QVariant(selection.start().offset()); + return QVariant(selection.start().deprecatedEditingOffset()); } } return QVariant(); @@ -1155,6 +1195,21 @@ QVariant QWebPage::inputMethodQuery(Qt::InputMethodQuery property) const \value InsertParagraphSeparator Insert a new paragraph. \value InsertLineSeparator Insert a new line. \value SelectAll Selects all content. + \value PasteAndMatchStyle Paste content from the clipboard with current style. + \value RemoveFormat Removes formatting and style. + \value ToggleStrikethrough Toggle the formatting between strikethrough and normal style. + \value ToggleSubscript Toggle the formatting between subscript and baseline. + \value ToggleSuperscript Toggle the formatting between supercript and baseline. + \value InsertUnorderedList Toggles the selection between an ordered list and a normal block. + \value InsertOrderedList Toggles the selection between an ordered list and a normal block. + \value Indent Increases the indentation of the currently selected format block by one increment. + \value Outdent Decreases the indentation of the currently selected format block by one increment. + \value AlignCenter Applies center alignment to content. + \value AlignJustified Applies full justification to content. + \value AlignLeft Applies left justification to content. + \value AlignRight Applies right justification to content. + + \omitvalue WebActionCount */ @@ -1230,6 +1285,9 @@ QWebPage::QWebPage(QObject *parent) setView(qobject_cast<QWidget *>(parent)); connect(this, SIGNAL(loadProgress(int)), this, SLOT(_q_onLoadProgressChanged(int))); +#ifndef NDEBUG + connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), this, SLOT(_q_cleanupLeakMessages())); +#endif } /*! @@ -1433,10 +1491,9 @@ void QWebPage::triggerAction(WebAction action, bool checked) case OpenLink: if (QWebFrame *targetFrame = d->hitTestResult.linkTargetFrame()) { WTF::RefPtr<WebCore::Frame> wcFrame = targetFrame->d->frame; - targetFrame->d->frame->loader()->loadFrameRequestWithFormAndValues(frameLoadRequest(d->hitTestResult.linkUrl(), wcFrame.get()), - /*lockHistory*/ false, /*event*/ 0, - /*HTMLFormElement*/ 0, /*formValues*/ - WTF::HashMap<String, String>()); + targetFrame->d->frame->loader()->loadFrameRequest(frameLoadRequest(d->hitTestResult.linkUrl(), wcFrame.get()), + /*lockHistory*/ false, /*lockBackForwardList*/ false, /*event*/ 0, + /*FormState*/ 0); break; } // fall through @@ -1536,11 +1593,61 @@ void QWebPage::setViewportSize(const QSize &size) const if (frame->d->frame && frame->d->frame->view()) { WebCore::FrameView* view = frame->d->frame->view(); view->setFrameRect(QRect(QPoint(0, 0), size)); - frame->d->frame->forceLayout(); + view->forceLayout(); view->adjustViewSize(); } } +QSize QWebPage::fixedLayoutSize() const +{ + if (d->mainFrame && d->mainFrame->d->frame->view()) + return d->mainFrame->d->frame->view()->fixedLayoutSize(); + + return d->fixedLayoutSize; +} + +/*! + \property QWebPage::fixedLayoutSize + \since 4.6 + \brief the size of the fixed layout + + The size affects the layout of the page in the viewport. If set to a fixed size of + 1024x768 for example then webkit will layout the page as if the viewport were that size + rather than something different. +*/ +void QWebPage::setFixedLayoutSize(const QSize &size) const +{ + d->fixedLayoutSize = size; + + QWebFrame *frame = mainFrame(); + if (frame->d->frame && frame->d->frame->view()) { + WebCore::FrameView* view = frame->d->frame->view(); + view->setFixedLayoutSize(size); + view->forceLayout(); + } +} + +bool QWebPage::useFixedLayout() const +{ + return d->useFixedLayout; +} + +/*! + \property QWebPage::useFixedLayout + \since 4.6 + \brief whether to use a fixed layout size +*/ +void QWebPage::setUseFixedLayout(bool useFixedLayout) +{ + d->useFixedLayout = useFixedLayout; + + QWebFrame *frame = mainFrame(); + if (frame->d->frame && frame->d->frame->view()) { + WebCore::FrameView* view = frame->d->frame->view(); + view->setUseFixedLayout(useFixedLayout); + view->forceLayout(); + } +} /*! \fn bool QWebPage::acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, QWebPage::NavigationType type) @@ -1568,7 +1675,7 @@ bool QWebPage::acceptNavigationRequest(QWebFrame *frame, const QWebNetworkReques return true; case DelegateExternalLinks: - if (WebCore::FrameLoader::shouldTreatSchemeAsLocal(request.url().scheme())) + if (WebCore::FrameLoader::shouldTreatURLSchemeAsLocal(request.url().scheme())) return true; emit linkClicked(request.url()); return false; @@ -1808,6 +1915,52 @@ QAction *QWebPage::action(WebAction action) const text = tr("Insert a new line"); break; + case PasteAndMatchStyle: + text = tr("Paste and Match Style"); + break; + case RemoveFormat: + text = tr("Remove formatting"); + break; + + case ToggleStrikethrough: + text = tr("Strikethrough"); + checkable = true; + break; + case ToggleSubscript: + text = tr("Subscript"); + checkable = true; + break; + case ToggleSuperscript: + text = tr("Superscript"); + checkable = true; + break; + case InsertUnorderedList: + text = tr("Insert Bulleted List"); + checkable = true; + break; + case InsertOrderedList: + text = tr("Insert Numbered List"); + checkable = true; + break; + case Indent: + text = tr("Indent"); + break; + case Outdent: + text = tr("Outdent"); + break; + case AlignCenter: + text = tr("Center"); + break; + case AlignJustified: + text = tr("Justify"); + break; + case AlignLeft: + text = tr("Align Left"); + break; + case AlignRight: + text = tr("Align Right"); + break; + case NoWebAction: return 0; } @@ -1986,12 +2139,10 @@ bool QWebPage::isContentEditable() const /*! \property QWebPage::forwardUnsupportedContent - \brief whether QWebPage should forward unsupported content - - If enabled, the unsupportedContent() signal is emitted with a network reply that - can be used to read the content. + \brief whether QWebPage should forward unsupported content through the + unsupportedContent signal - If disabled, the download of such content is aborted immediately. + If disabled the download of such content is aborted immediately. By default unsupported content is not forwarded. */ diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.h b/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.h index 7253cee..2152865 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.h +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.h @@ -52,10 +52,11 @@ namespace WebCore { class ChromeClientQt; class EditorClientQt; class FrameLoaderClientQt; - class FrameLoadRequest; class InspectorClientQt; class ResourceHandle; class HitTestResult; + + struct FrameLoadRequest; } class QWEBKIT_EXPORT QWebPage : public QObject @@ -65,6 +66,8 @@ class QWEBKIT_EXPORT QWebPage : public QObject Q_PROPERTY(bool modified READ isModified) Q_PROPERTY(QString selectedText READ selectedText) Q_PROPERTY(QSize viewportSize READ viewportSize WRITE setViewportSize) + Q_PROPERTY(QSize fixedLayoutSize READ fixedLayoutSize WRITE setFixedLayoutSize) + Q_PROPERTY(bool useFixedLayout READ useFixedLayout WRITE setUseFixedLayout) Q_PROPERTY(bool forwardUnsupportedContent READ forwardUnsupportedContent WRITE setForwardUnsupportedContent) Q_PROPERTY(LinkDelegationPolicy linkDelegationPolicy READ linkDelegationPolicy WRITE setLinkDelegationPolicy) Q_PROPERTY(QPalette palette READ palette WRITE setPalette) @@ -148,6 +151,22 @@ public: SelectAll, + PasteAndMatchStyle, + RemoveFormat, + + ToggleStrikethrough, + ToggleSubscript, + ToggleSuperscript, + InsertUnorderedList, + InsertOrderedList, + Indent, + Outdent, + + AlignCenter, + AlignJustified, + AlignLeft, + AlignRight, + WebActionCount }; @@ -215,6 +234,12 @@ public: QSize viewportSize() const; void setViewportSize(const QSize &size) const; + QSize fixedLayoutSize() const; + void setFixedLayoutSize(const QSize &size) const; + + bool useFixedLayout() const; + void setUseFixedLayout(bool useFixedLayout); + virtual bool event(QEvent*); bool focusNextPrevChild(bool next); @@ -317,6 +342,9 @@ protected: private: Q_PRIVATE_SLOT(d, void _q_onLoadProgressChanged(int)) Q_PRIVATE_SLOT(d, void _q_webActionTriggered(bool checked)) +#ifndef NDEBUG + Q_PRIVATE_SLOT(d, void _q_cleanupLeakMessages()) +#endif QWebPagePrivate *d; friend class QWebFrame; diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebpage_p.h b/src/3rdparty/webkit/WebKit/qt/Api/qwebpage_p.h index a1f33ab..a897bf1 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebpage_p.h +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebpage_p.h @@ -79,6 +79,9 @@ public: void _q_onLoadProgressChanged(int); void _q_webActionTriggered(bool checked); +#ifndef NDEBUG + void _q_cleanupLeakMessages(); +#endif void updateAction(QWebPage::WebAction action); void updateNavigationActions(); void updateEditorActions(); @@ -154,6 +157,7 @@ public: QWebPage::LinkDelegationPolicy linkPolicy; QSize viewportSize; + QSize fixedLayoutSize; QWebHistory history; QWebHitTestResult hitTestResult; #ifndef QT_NO_CONTEXTMENU @@ -162,6 +166,7 @@ public: QWebSettings *settings; QPalette palette; bool editable; + bool useFixedLayout; QAction *actions[QWebPage::WebActionCount]; diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebsecurityorigin.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebsecurityorigin.cpp index 5217362..da9278c 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebsecurityorigin.cpp +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebsecurityorigin.cpp @@ -101,7 +101,11 @@ int QWebSecurityOrigin::port() const */ qint64 QWebSecurityOrigin::databaseUsage() const { +#if ENABLE(DATABASE) return DatabaseTracker::tracker().usageForOrigin(d->origin.get()); +#else + return 0; +#endif } /*! @@ -109,7 +113,11 @@ qint64 QWebSecurityOrigin::databaseUsage() const */ qint64 QWebSecurityOrigin::databaseQuota() const { +#if ENABLE(DATABASE) return DatabaseTracker::tracker().quotaForOrigin(d->origin.get()); +#else + return 0; +#endif } /*! @@ -121,7 +129,9 @@ qint64 QWebSecurityOrigin::databaseQuota() const */ void QWebSecurityOrigin::setDatabaseQuota(qint64 quota) { +#if ENABLE(DATABASE) DatabaseTracker::tracker().setQuota(d->origin.get(), quota); +#endif } /*! @@ -144,14 +154,18 @@ QWebSecurityOrigin::QWebSecurityOrigin(QWebSecurityOriginPrivate* priv) */ QList<QWebSecurityOrigin> QWebSecurityOrigin::allOrigins() { + QList<QWebSecurityOrigin> webOrigins; + +#if ENABLE(DATABASE) Vector<RefPtr<SecurityOrigin> > coreOrigins; DatabaseTracker::tracker().origins(coreOrigins); - QList<QWebSecurityOrigin> webOrigins; for (unsigned i = 0; i < coreOrigins.size(); ++i) { QWebSecurityOriginPrivate* priv = new QWebSecurityOriginPrivate(coreOrigins[i].get()); webOrigins.append(priv); } +#endif + return webOrigins; } @@ -160,8 +174,11 @@ QList<QWebSecurityOrigin> QWebSecurityOrigin::allOrigins() */ QList<QWebDatabase> QWebSecurityOrigin::databases() const { - Vector<String> nameVector; QList<QWebDatabase> databases; + +#if ENABLE(DATABASE) + Vector<String> nameVector; + if (!DatabaseTracker::tracker().databaseNamesForOrigin(d->origin.get(), nameVector)) return databases; for (unsigned i = 0; i < nameVector.size(); ++i) { @@ -171,6 +188,8 @@ QList<QWebDatabase> QWebSecurityOrigin::databases() const QWebDatabase webDatabase(priv); databases.append(webDatabase); } +#endif + return databases; } diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebsettings.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebsettings.cpp index b516263..8192e68 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebsettings.cpp +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebsettings.cpp @@ -24,6 +24,8 @@ #include "qwebpage_p.h" #include "Cache.h" +#include "CrossOriginPreflightResultCache.h" +#include "FontCache.h" #include "Page.h" #include "PageCache.h" #include "Settings.h" @@ -52,6 +54,7 @@ public: QHash<int, int> fontSizes; QHash<int, bool> attributes; QUrl userStyleSheetLocation; + QString defaultTextEncoding; QString localStorageDatabasePath; QString offlineWebApplicationCachePath; qint64 offlineStorageDefaultQuota; @@ -161,6 +164,9 @@ void QWebSettingsPrivate::apply() QUrl location = !userStyleSheetLocation.isEmpty() ? userStyleSheetLocation : global->userStyleSheetLocation; settings->setUserStyleSheetLocation(WebCore::KURL(location)); + QString encoding = !defaultTextEncoding.isEmpty() ? defaultTextEncoding: global->defaultTextEncoding; + settings->setDefaultTextEncodingName(encoding); + QString localStoragePath = !localStorageDatabasePath.isEmpty() ? localStorageDatabasePath : global->localStorageDatabasePath; settings->setLocalStorageDatabasePath(localStoragePath); @@ -183,6 +189,10 @@ void QWebSettingsPrivate::apply() value = attributes.value(QWebSettings::LocalStorageDatabaseEnabled, global->attributes.value(QWebSettings::LocalStorageDatabaseEnabled)); settings->setLocalStorageEnabled(value); + + value = attributes.value(QWebSettings::AllowUniversalAccessFromFileUrls, + global->attributes.value(QWebSettings::AllowUniversalAccessFromFileUrls)); + settings->setAllowUniversalAccessFromFileURLs(value); } else { QList<QWebSettingsPrivate *> settings = *::allSettings(); for (int i = 0; i < settings.count(); ++i) @@ -213,25 +223,17 @@ QWebSettings *QWebSettings::globalSettings() Each QWebPage object has its own QWebSettings object, which configures the settings for that page. If a setting is not configured, then it is looked up in the global settings object, which can be accessed using - globalSettings(). + QWebSettings::globalSettings(). - QWebSettings allows configuration of browser properties, such as font sizes and - families, the location of a custom style sheet, and generic attributes like - JavaScript and plugins. Individual attributes are set using the setAttribute() - function. The \l{QWebSettings::WebAttribute}{WebAttribute} enum further describes - each attribute. + QWebSettings allows configuring font properties such as font size and font + family, the location of a custom stylesheet, and generic attributes like java + script, plugins, etc. The \l{QWebSettings::WebAttribute}{WebAttribute} + enum further describes this. - QWebSettings also configures global properties such as the Web page memory - cache and the Web page icon database, local database storage and offline + QWebSettings also configures global properties such as the web page memory + cache and the web page icon database, local database storage and offline applications storage. - \section1 Enabling Plugins - - Support for browser plugins can enabled by setting the - \l{QWebSettings::PluginsEnabled}{PluginsEnabled} attribute. For many applications, - this attribute is enabled for all pages by setting it on the - \l{globalSettings()}{global settings object}. - \section1 Web Application Support WebKit provides support for features specified in \l{HTML 5} that improve the @@ -318,6 +320,8 @@ QWebSettings *QWebSettings::globalSettings() web application cache feature is enabled or not. \value LocalStorageDatabaseEnabled Specifies whether support for the HTML 5 local storage feature is enabled or not. + \value AllowUniversalAccessFromFileUrls Specifies whether documents from file + Urls should be granted universal access (e.g., to HTTP and HTTPS documents). */ /*! @@ -346,6 +350,7 @@ QWebSettings::QWebSettings() d->attributes.insert(QWebSettings::OfflineStorageDatabaseEnabled, true); d->attributes.insert(QWebSettings::OfflineWebApplicationCacheEnabled, true); d->attributes.insert(QWebSettings::LocalStorageDatabaseEnabled, true); + d->attributes.insert(QWebSettings::AllowUniversalAccessFromFileUrls, true); d->offlineStorageDefaultQuota = 5 * 1024 * 1024; } @@ -432,6 +437,33 @@ QUrl QWebSettings::userStyleSheetUrl() const } /*! + \since 4.6 + Specifies the default text encoding system. + + The \a encoding, must be a string describing an encoding such as "utf-8", + "iso-8859-1", etc. If left empty a default value will be used. For a more + extensive list of encoding names see \l{QTextCodec} + + \sa defaultTextEncoding() +*/ +void QWebSettings::setDefaultTextEncoding(const QString &encoding) +{ + d->defaultTextEncoding = encoding; + d->apply(); +} + +/*! + \since 4.6 + Returns the default text encoding. + + \sa setDefaultTextEncoding() +*/ +QString QWebSettings::defaultTextEncoding() const +{ + return d->defaultTextEncoding; +} + +/*! Sets the path of the icon database to \a path. The icon database is used to store "favicons" associated with web sites. @@ -535,6 +567,40 @@ QPixmap QWebSettings::webGraphic(WebGraphic type) } /*! + Frees up as much memory as possible by cleaning all memory caches such + as page, object and font cache. + + \since 4.6 + */ +void QWebSettings::clearMemoryCaches() +{ + // Turn the cache on and off. Disabling the object cache will remove all + // resources from the cache. They may still live on if they are referenced + // by some Web page though. + if (!WebCore::cache()->disabled()) { + WebCore::cache()->setDisabled(true); + WebCore::cache()->setDisabled(false); + } + + int pageCapacity = WebCore::pageCache()->capacity(); + // Setting size to 0, makes all pages be released. + WebCore::pageCache()->setCapacity(0); + WebCore::pageCache()->releaseAutoreleasedPagesNow(); + WebCore::pageCache()->setCapacity(pageCapacity); + + // Invalidating the font cache and freeing all inactive font data. + WebCore::fontCache()->invalidate(); + +#if ENABLE(OFFLINE_WEB_APPLICATIONS) + // Empty the application cache. + WebCore::cacheStorage().empty(); +#endif + + // Empty the Cross-Origin Preflight cache + WebCore::CrossOriginPreflightResultCache::shared().empty(); +} + +/*! Sets the maximum number of pages to hold in the memory cache to \a pages. */ void QWebSettings::setMaximumPagesInCache(int pages) diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebsettings.h b/src/3rdparty/webkit/WebKit/qt/Api/qwebsettings.h index 3d0660b..da0c9f2 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebsettings.h +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebsettings.h @@ -63,7 +63,8 @@ public: PrintElementBackgrounds, OfflineStorageDatabaseEnabled, OfflineWebApplicationCacheEnabled, - LocalStorageDatabaseEnabled + LocalStorageDatabaseEnabled, + AllowUniversalAccessFromFileUrls }; enum WebGraphic { MissingImageGraphic, @@ -95,6 +96,9 @@ public: void setUserStyleSheetUrl(const QUrl &location); QUrl userStyleSheetUrl() const; + void setDefaultTextEncoding(const QString &encoding); + QString defaultTextEncoding() const; + static void setIconDatabasePath(const QString &location); static QString iconDatabasePath(); static void clearIconDatabase(); @@ -112,6 +116,8 @@ public: static void setOfflineStorageDefaultQuota(qint64 maximumSize); static qint64 offlineStorageDefaultQuota(); + static void clearMemoryCaches(); + inline QWebSettingsPrivate* handle() const { return d; } private: diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebview.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebview.cpp index 9753f4f..3c56b93 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebview.cpp +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebview.cpp @@ -27,6 +27,8 @@ #include "qevent.h" #include "qpainter.h" #include "qprinter.h" +#include "qdir.h" +#include "qfile.h" class QWebViewPrivate { @@ -34,6 +36,7 @@ public: QWebViewPrivate(QWebView *view) : view(view) , page(0) + , renderHints(QPainter::TextAntialiasing) #ifndef QT_NO_CURSOR , cursorSetByWebCore(false) , usesWebCoreCursor(true) @@ -43,6 +46,7 @@ public: QWebView *view; QWebPage *page; + QPainter::RenderHints renderHints; #ifndef QT_NO_CURSOR /* @@ -245,11 +249,79 @@ void QWebView::setPage(QWebPage *page) } /*! + Returns a valid URL from a user supplied \a string if one can be deducted. + In the case that is not possible, an invalid QUrl() is returned. + + \since 4.6 + + Most applications that can browse the web, allow the user to input a URL + in the form of a plain string. This string can be manually typed into + a location bar, obtained from the clipboard, or passed in via command + line arguments. + + When the string is not already a valid URL, a best guess is performed, + making various web related assumptions. + + In the case the string corresponds to a valid file path on the system, + a file:// URL is constructed, using QUrl::fromLocalFile(). + + If that is not the case, an attempt is made to turn the string into a + http:// or ftp:// URL. The latter in the case the string starts with + 'ftp'. The result is then passed through QUrl's tolerant parser, and + in the case or success, a valid QUrl is returned, or else a QUrl(). + + Examples + - webkit.org becomes http://webkit.org + - ftp.webkit.org becomes ftp://ftp.webkit.org + - localhost becomes http://localhost + - /home/user/test.html becomes file:///home/user/test.html (if exists) + + Tips when dealing with URLs and strings + - When creating a QString from a QByteArray or a char*, always use + QString::fromUtf8(). + - Do not use QUrl(string), nor QUrl::toString() anywhere where the URL might + be used, such as in the location bar, as those functions loose data. + Instead use QUrl::fromEncoded() and QUrl::toEncoded(), respectively. + + */ +QUrl QWebView::guessUrlFromString(const QString &string) +{ + QString trimmedString = string.trimmed(); + + // Check the most common case of a valid url with scheme and host first + QUrl url = QUrl::fromEncoded(trimmedString.toUtf8(), QUrl::TolerantMode); + if (url.isValid() && !url.scheme().isEmpty() && !url.host().isEmpty()) + return url; + + // Absolute files that exists + if (QDir::isAbsolutePath(trimmedString) && QFile::exists(trimmedString)) + return QUrl::fromLocalFile(trimmedString); + + // If the string is missing the scheme or the scheme is not valid prepend a scheme + QString scheme = url.scheme(); + if (scheme.isEmpty() || scheme.contains(QLatin1Char('.')) || scheme == QLatin1String("localhost")) { + // Do not do anything for strings such as "foo", only "foo.com" + int dotIndex = trimmedString.indexOf(QLatin1Char('.')); + if (dotIndex != -1 || trimmedString.startsWith(QLatin1String("localhost"))) { + const QString hostscheme = trimmedString.left(dotIndex).toLower(); + QByteArray scheme = (hostscheme == QLatin1String("ftp")) ? "ftp" : "http"; + trimmedString = QLatin1String(scheme) + QLatin1String("://") + trimmedString; + } + url = QUrl::fromEncoded(trimmedString.toUtf8(), QUrl::TolerantMode); + } + + if (url.isValid()) + return url; + + return QUrl(); +} + +/*! Loads the specified \a url and displays it. \note The view remains the same until enough data has arrived to display the new \a url. - \sa setUrl(), url(), urlChanged() + \sa setUrl(), url(), urlChanged(), guessUrlFromString() */ void QWebView::load(const QUrl &url) { @@ -533,6 +605,47 @@ qreal QWebView::textSizeMultiplier() const } /*! + \property QWebView::renderHints + \since 4.6 + \brief the default render hints for the view + + These hints are used to initialize QPainter before painting the web page. + + QPainter::TextAntialiasing is enabled by default. +*/ +QPainter::RenderHints QWebView::renderHints() const +{ + return d->renderHints; +} + +void QWebView::setRenderHints(QPainter::RenderHints hints) +{ + if (hints == d->renderHints) + return; + d->renderHints = hints; + update(); +} + +/*! + If \a enabled is true, the render hint \a hint is enabled; otherwise it + is disabled. + + \since 4.6 + \sa renderHints +*/ +void QWebView::setRenderHint(QPainter::RenderHint hint, bool enabled) +{ + QPainter::RenderHints oldHints = d->renderHints; + if (enabled) + d->renderHints |= hint; + else + d->renderHints &= ~hint; + if (oldHints != d->renderHints) + update(); +} + + +/*! Finds the next occurrence of the string, \a subString, in the page, using the given \a options. Returns true of \a subString was found and selects the match visually; otherwise returns false. @@ -680,6 +793,7 @@ void QWebView::paintEvent(QPaintEvent *ev) QWebFrame *frame = d->page->mainFrame(); QPainter p(this); + p.setRenderHints(d->renderHints); frame->render(&p, ev->region()); @@ -914,7 +1028,10 @@ void QWebView::changeEvent(QEvent *e) This signal is emitted whenever the icon of the page is loaded or changes. - \sa icon() + In order for icons to be loaded, you will need to set an icon database path + using QWebSettings::setIconDatabasePath(). + + \sa icon(), QWebSettings::setIconDatabasePath() */ /*! diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebview.h b/src/3rdparty/webkit/WebKit/qt/Api/qwebview.h index 1172f39..5c2c7a0 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebview.h +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebview.h @@ -25,6 +25,7 @@ #include "qwebpage.h" #include <QtGui/qwidget.h> #include <QtGui/qicon.h> +#include <QtGui/qpainter.h> #include <QtCore/qurl.h> #if QT_VERSION >= 0x040400 #include <QtNetwork/qnetworkaccessmanager.h> @@ -50,6 +51,8 @@ class QWEBKIT_EXPORT QWebView : public QWidget //Q_PROPERTY(Qt::TextInteractionFlags textInteractionFlags READ textInteractionFlags WRITE setTextInteractionFlags) Q_PROPERTY(qreal textSizeMultiplier READ textSizeMultiplier WRITE setTextSizeMultiplier DESIGNABLE false) Q_PROPERTY(qreal zoomFactor READ zoomFactor WRITE setZoomFactor) + Q_PROPERTY(QPainter::RenderHints renderHints READ renderHints WRITE setRenderHints) + Q_FLAGS(QPainter::RenderHints) public: explicit QWebView(QWidget *parent = 0); virtual ~QWebView(); @@ -57,6 +60,8 @@ public: QWebPage *page() const; void setPage(QWebPage *page); + static QUrl guessUrlFromString(const QString &string); + void load(const QUrl &url); #if QT_VERSION < 0x040400 && !defined(qdoc) void load(const QWebNetworkRequest &request); @@ -99,6 +104,10 @@ public: void setTextSizeMultiplier(qreal factor); qreal textSizeMultiplier() const; + QPainter::RenderHints renderHints() const; + void setRenderHints(QPainter::RenderHints hints); + void setRenderHint(QPainter::RenderHint hint, bool enabled); + bool findText(const QString &subString, QWebPage::FindFlags options = 0); virtual bool event(QEvent *); |