diff options
author | Steve Block <steveblock@google.com> | 2011-05-13 06:44:40 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2011-05-13 06:44:40 -0700 |
commit | 08014c20784f3db5df3a89b73cce46037b77eb59 (patch) | |
tree | 47749210d31e19e6e2f64036fa8fae2ad693476f /WebKit/qt | |
parent | 860220379e56aeb66424861ad602b07ee22b4055 (diff) | |
parent | 4c3661f7918f8b3f139f824efb7855bedccb4c94 (diff) | |
download | external_webkit-08014c20784f3db5df3a89b73cce46037b77eb59.zip external_webkit-08014c20784f3db5df3a89b73cce46037b77eb59.tar.gz external_webkit-08014c20784f3db5df3a89b73cce46037b77eb59.tar.bz2 |
Merge changes Ide388898,Ic49f367c,I1158a808,Iacb6ca5d,I2100dd3a,I5c1abe54,Ib0ef9902,I31dbc523,I570314b3
* changes:
Merge WebKit at r75315: Update WebKit version
Merge WebKit at r75315: Add FrameLoaderClient PageCache stubs
Merge WebKit at r75315: Stub out AXObjectCache::remove()
Merge WebKit at r75315: Fix ImageBuffer
Merge WebKit at r75315: Fix PluginData::initPlugins()
Merge WebKit at r75315: Fix conflicts
Merge WebKit at r75315: Fix Makefiles
Merge WebKit at r75315: Move Android-specific WebCore files to Source
Merge WebKit at r75315: Initial merge by git.
Diffstat (limited to 'WebKit/qt')
21 files changed, 666 insertions, 145 deletions
diff --git a/WebKit/qt/Api/qwebkitplatformplugin.h b/WebKit/qt/Api/qwebkitplatformplugin.h index 2ceaac1..b8cc984 100644 --- a/WebKit/qt/Api/qwebkitplatformplugin.h +++ b/WebKit/qt/Api/qwebkitplatformplugin.h @@ -131,6 +131,8 @@ public: virtual QObject* createExtension(Extension extension) const = 0; }; +QT_BEGIN_NAMESPACE Q_DECLARE_INTERFACE(QWebKitPlatformPlugin, "com.nokia.Qt.WebKit.PlatformPlugin/1.6"); +QT_END_NAMESPACE #endif // QWEBKITPLATFORMPLUGIN_H diff --git a/WebKit/qt/Api/qwebpage.cpp b/WebKit/qt/Api/qwebpage.cpp index e82bd45..eab514b 100644 --- a/WebKit/qt/Api/qwebpage.cpp +++ b/WebKit/qt/Api/qwebpage.cpp @@ -418,6 +418,7 @@ static QWebPage::WebAction webActionForContextMenuAction(WebCore::ContextMenuAct case WebCore::ContextMenuItemTagBold: return QWebPage::ToggleBold; case WebCore::ContextMenuItemTagItalic: return QWebPage::ToggleItalic; case WebCore::ContextMenuItemTagUnderline: return QWebPage::ToggleUnderline; + case WebCore::ContextMenuItemTagSelectAll: return QWebPage::SelectAll; #if ENABLE(INSPECTOR) case WebCore::ContextMenuItemTagInspectElement: return QWebPage::InspectElement; #endif @@ -1095,10 +1096,15 @@ void QWebPagePrivate::inputMethodEvent(QInputMethodEvent *ev) setSelectionRange(node, start, start + ev->replacementLength()); // Commit regardless of whether commitString is empty, to get rid of selection. editor->confirmComposition(ev->commitString()); - } else if (!ev->commitString().isEmpty()) - editor->confirmComposition(ev->commitString()); - else if (!hasSelection && !ev->preeditString().isEmpty()) + } else if (!ev->commitString().isEmpty()) { + if (editor->hasComposition()) + editor->confirmComposition(ev->commitString()); + else + editor->insertText(ev->commitString(), 0); + } else if (!hasSelection && !ev->preeditString().isEmpty()) editor->setComposition(ev->preeditString(), underlines, 0, 0); + else if (ev->preeditString().isEmpty() && editor->hasComposition()) + editor->confirmComposition(String()); ev->accept(); } @@ -2624,12 +2630,27 @@ bool QWebPage::acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest & } /*! + \property QWebPage::hasSelection + \brief whether this page contains selected content or not. + + \sa selectionChanged() +*/ +bool QWebPage::hasSelection() const +{ + d->createMainFrame(); + WebCore::Frame* frame = d->page->focusController()->focusedOrMainFrame(); + if (frame) + return (frame->selection()->selection().selectionType() != VisibleSelection::NoSelection); + return false; +} + +/*! \property QWebPage::selectedText \brief the text currently selected By default, this property contains an empty string. - \sa selectionChanged() + \sa selectionChanged(), selectedHtml() */ QString QWebPage::selectedText() const { @@ -2640,6 +2661,21 @@ QString QWebPage::selectedText() const return frame->editor()->selectedText(); } +/*! + \since 4.8 + \property QWebPage::selectedHtml + \brief the HTML currently selected + + By default, this property contains an empty string. + + \sa selectionChanged(), selectedText() +*/ +QString QWebPage::selectedHtml() const +{ + d->createMainFrame(); + return d->page->focusController()->focusedOrMainFrame()->editor()->selectedRange()->toHTML(); +} + #ifndef QT_NO_ACTION /*! Returns a QAction for the specified WebAction \a action. @@ -2717,6 +2753,9 @@ QAction *QWebPage::action(WebAction action) const case Paste: text = contextMenuItemTagPaste(); break; + case SelectAll: + text = contextMenuItemTagSelectAll(); + break; #ifndef QT_NO_UNDOSTACK case Undo: { QAction *a = undoStack()->createUndoAction(d->q); @@ -2765,9 +2804,6 @@ QAction *QWebPage::action(WebAction action) const case MoveToEndOfDocument: text = tr("Move the cursor to the end of the document"); break; - case SelectAll: - text = tr("Select all"); - break; case SelectNextChar: text = tr("Select to the next character"); break; diff --git a/WebKit/qt/Api/qwebpage.h b/WebKit/qt/Api/qwebpage.h index 1e0b3b7..b66adb2 100644 --- a/WebKit/qt/Api/qwebpage.h +++ b/WebKit/qt/Api/qwebpage.h @@ -72,6 +72,8 @@ class QWEBKIT_EXPORT QWebPage : public QObject { Q_PROPERTY(bool modified READ isModified) Q_PROPERTY(QString selectedText READ selectedText) + Q_PROPERTY(QString selectedHtml READ selectedHtml) + Q_PROPERTY(bool hasSelection READ hasSelection) Q_PROPERTY(QSize viewportSize READ viewportSize WRITE setViewportSize) Q_PROPERTY(QSize preferredContentsSize READ preferredContentsSize WRITE setPreferredContentsSize) Q_PROPERTY(bool forwardUnsupportedContent READ forwardUnsupportedContent WRITE setForwardUnsupportedContent) @@ -268,7 +270,9 @@ public: quint64 totalBytes() const; quint64 bytesReceived() const; + bool hasSelection() const; QString selectedText() const; + QString selectedHtml() const; #ifndef QT_NO_ACTION QAction *action(WebAction action) const; diff --git a/WebKit/qt/Api/qwebview.cpp b/WebKit/qt/Api/qwebview.cpp index 31ee521..f4b23f3 100644 --- a/WebKit/qt/Api/qwebview.cpp +++ b/WebKit/qt/Api/qwebview.cpp @@ -572,12 +572,27 @@ QIcon QWebView::icon() const } /*! + \property QWebView::hasSelection + \brief whether this page contains selected content or not. + + By default, this property is false. + + \sa selectionChanged() +*/ +bool QWebView::hasSelection() const +{ + if (d->page) + return d->page->hasSelection(); + return false; +} + +/*! \property QWebView::selectedText \brief the text currently selected By default, this property contains an empty string. - \sa findText(), selectionChanged() + \sa findText(), selectionChanged(), selectedHtml() */ QString QWebView::selectedText() const { @@ -586,6 +601,22 @@ QString QWebView::selectedText() const return QString(); } +/*! + \since 4.8 + \property QWebView::selectedHtml + \brief the HTML currently selected + + By default, this property contains an empty string. + + \sa findText(), selectionChanged(), selectedText() +*/ +QString QWebView::selectedHtml() const +{ + if (d->page) + return d->page->selectedHtml(); + return QString(); +} + #ifndef QT_NO_ACTION /*! Returns a pointer to a QAction that encapsulates the specified web action \a action. diff --git a/WebKit/qt/Api/qwebview.h b/WebKit/qt/Api/qwebview.h index 1d651d5..8b28f62 100644 --- a/WebKit/qt/Api/qwebview.h +++ b/WebKit/qt/Api/qwebview.h @@ -44,6 +44,8 @@ class QWEBKIT_EXPORT QWebView : public QWidget { Q_PROPERTY(QUrl url READ url WRITE setUrl) Q_PROPERTY(QIcon icon READ icon) Q_PROPERTY(QString selectedText READ selectedText) + Q_PROPERTY(QString selectedHtml READ selectedHtml) + Q_PROPERTY(bool hasSelection READ hasSelection) Q_PROPERTY(bool modified READ isModified) //Q_PROPERTY(Qt::TextInteractionFlags textInteractionFlags READ textInteractionFlags WRITE setTextInteractionFlags) Q_PROPERTY(qreal textSizeMultiplier READ textSizeMultiplier WRITE setTextSizeMultiplier DESIGNABLE false) @@ -73,7 +75,9 @@ public: QUrl url() const; QIcon icon() const; + bool hasSelection() const; QString selectedText() const; + QString selectedHtml() const; #ifndef QT_NO_ACTION QAction* pageAction(QWebPage::WebAction action) const; diff --git a/WebKit/qt/ChangeLog b/WebKit/qt/ChangeLog index 7016d6c..d59d413 100644 --- a/WebKit/qt/ChangeLog +++ b/WebKit/qt/ChangeLog @@ -1,3 +1,271 @@ +2011-01-07 Adam Barth <abarth@webkit.org> + + Rubber-stamped by Eric Seidel. + + Move WebCore to Source + https://bugs.webkit.org/show_bug.cgi?id=52050 + + Update documentation to reference new location of WebCore. + + * docs/qtwebkit.qdoc: + +2011-01-07 Andreas Kling <kling@webkit.org> + + Reviewed by Adam Barth. + + [Qt] Add selectedHtml function to QWebView + https://bugs.webkit.org/show_bug.cgi?id=35028 + + Add QWebView::selectedHtml() and QWebPage::selectedHtml() + which return the current selection range's HTML representation. + + * Api/qwebpage.cpp: + (QWebPage::selectedHtml): + * Api/qwebpage.h: + * Api/qwebview.cpp: + (QWebView::selectedText): + (QWebView::selectedHtml): + * Api/qwebview.h: + * tests/qwebpage/tst_qwebpage.cpp: + (tst_QWebPage::cursorMovements): + (tst_QWebPage::textSelection): + (tst_QWebPage::crashTests_LazyInitializationOfMainFrame): + (tst_QWebPage::findText): + +2011-01-06 Robert Hogan <robert@webkit.org> + + Reviewed by Antonio Gomes. + + [Qt] Introduce QDRTNode for passing WebCore::Node across JS bridge + + This allows LayoutTestController to pass WebCore::Node back to + layout tests. + + Also amend nodesFromRect-links-and-text.html and + nodesFromRect-inner-documents.html so that they do not produce + platform-specific results. + + Unskip: + fast/dom/nodesFromRect-links-and-text.html + fast/dom/nodesFromRect-inner-documents.html + + https://bugs.webkit.org/show_bug.cgi?id=48957 + + * WebCoreSupport/DumpRenderTreeSupportQt.cpp: + (QDRTNode::QDRTNode): + (QDRTNode::~QDRTNode): + (DumpRenderTreeSupportQt::nodesFromRect): + * WebCoreSupport/DumpRenderTreeSupportQt.h: + +2011-01-04 Girish Ramakrishnan <girish@forwardbias.in> + + Reviewed by Simon Hausmann. + Acked by Aaron Kennedy <aaron.kennedy@nokia.com> + + [Qt] QML WebView does not transfer focus to underlying QGraphicsWebView + + QML WebView creates QGraphicsWebView as it's child. The WebView is not + setup as a focus proxy of the QGraphicsWebView. Thus, even though the + WebView gets focus, the QGraphicsWebView does not get focus. + In QML, focus proxies or "focus scopes" are created using FocusScope. + This change makes WebView a FocusScope and sets the focus on the + QGraphicsWebView. + + https://bugs.webkit.org/show_bug.cgi?id=51094 + + * declarative/qdeclarativewebview.cpp: + (QDeclarativeWebView::init): + +2011-01-05 Yi Shen <yi.4.shen@nokia.com> + + Reviewed by Andreas Kling. + + [Qt] Sync qwebkitplatformplugin.h in the plugin example + https://bugs.webkit.org/show_bug.cgi?id=51882 + + Make examples/platformplugin/qwebkitplatformplugin.h exactly the same + as the one in the Api folder. + + * examples/platformplugin/qwebkitplatformplugin.h: + +2011-01-04 Zhe Su <suzhe@chromium.org> + + Reviewed by Kenneth Russell. + + Fix test LayoutTests/fast/events/ime-composition-events-001.html. + + https://bugs.webkit.org/show_bug.cgi?id=51693 + + * Api/qwebpage.cpp: + (QWebPagePrivate::inputMethodEvent): Calls editor->insertText() to + insert the commit string when no composition text is available. + +2011-01-03 Yi Shen <yi.4.shen@nokia.com> + + Reviewed by Adam Barth. + + [Qt] Add SelectAll option to the context menu for the editor + https://bugs.webkit.org/show_bug.cgi?id=50049 + + Enable SelectAll for the Qt context menu. + + * Api/qwebpage.cpp: + (webActionForContextMenuAction): + (QWebPage::action): + * WebCoreSupport/WebPlatformStrategies.cpp: + (WebPlatformStrategies::contextMenuItemTagSelectAll): + * WebCoreSupport/WebPlatformStrategies.h: + +2011-01-03 Antonio Gomes <agomes@rim.com> + + Unreviewed crash fix. + + Follow up of r74891: potential crash fix (bogus assertion). + + * WebCoreSupport/EditorClientQt.cpp: + (WebCore::editorCommandForKeyDownEvent): + +2011-01-03 Noam Rosenthal <noam.rosenthal@nokia.com> + + Reviewed by Andreas Kling. + + [Qt] document.getElementById(...) doesn't return the right object in combination with QGraphicsWidget + https://bugs.webkit.org/show_bug.cgi?id=51464 + + Added a way to bind any QObject created as a plugin to JavaScript, + by adding a custom membe to WebCore::Widget. + Added a test to make sure plugins created as QGraphicsWidget are + accessible through JavaScript. + + * WebCoreSupport/FrameLoaderClientQt.cpp: + * tests/qwebpage/tst_qwebpage.cpp: + (PluginPage::createPlugin): + (tst_QWebPage::graphicsWidgetPlugin): + +2011-01-02 Antonio Gomes <agomes@rim.com> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Refactor EditorClientQt::handleKeyboardEvent + https://bugs.webkit.org/show_bug.cgi?id=51306 + + EditorClientQt::handleKeyboardEvent relies on QWebPagePrivate::editorActionForKeyEvent() + to handle all editor commands that have a QAction associted with it. + In practice, that covers most of editor commands (as one can see in editorCommandWebActions, + in qwebpage.cpp). However, there are some key down events that are associated to no QAction + or need special handling when features like spatial navigation or + caret browsing are enabled. Currently, these cases are being handled with confusing + and nested if/else switch's statements in EditorClientQt::handleKeyboardEvent(), + and the code is hardly readable. + + This patch introduces a mapping hash for those cases, simplifying much + the code. Basically, nested switches statements mixed with if/else's were + refactored, and early returns were added right after an event gets consumed + by the Editor. + + Since it is a refactor only patch, there is no funcionality change at + all, and then no new tests are being added. + + * WebCoreSupport/EditorClientQt.cpp: + (WebCore::interpretKeyEvent): + (WebCore::EditorClientQt::handleKeyboardEvent): + +2011-01-01 Adam Barth <abarth@webkit.org> + + Reviewed by Eric Seidel. + + Move JavaScriptCore to Source + https://bugs.webkit.org/show_bug.cgi?id=51604 + + * WebKit_pch.h: + * docs/qtwebkit.qdocconf: + - Point to JavaScriptCore in its new location. + +2010-12-29 Kent Hansen <kent.hansen@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Fix compilation with Qt in namespace + https://bugs.webkit.org/show_bug.cgi?id=51701 + + * Api/qwebkitplatformplugin.h: + * WebCoreSupport/InspectorServerQt.h: + * tests/hybridPixmap/widget.h: + +2010-12-23 Jan Erik Hanssen <jhanssen@sencha.com> + + Reviewed by Alexey Proskuryakov. + + [Qt] Composition text is not removed from the editor when composition is cancelled + https://bugs.webkit.org/show_bug.cgi?id=29391 + + Ensure that the composition text is cleared when an empty QInputMethodEvent + is received and the editor is in composition mode. + + * Api/qwebpage.cpp: + (QWebPagePrivate::inputMethodEvent): + +2010-12-23 Jan Erik Hanssen <jhanssen@sencha.com> + + Reviewed by Andreas Kling. + + [Qt] copy and paste greek symbols to Word, TextEdit results in ?'s being shown + https://bugs.webkit.org/show_bug.cgi?id=35635 + + Test that QClipboard contains the charset information and unicode data + after copying unicode text. + + * tests/qwebpage/tst_qwebpage.cpp: + (tst_QWebPage::macCopyUnicodeToClipboard): + +2010-12-22 Sam Weinig <sam@webkit.org> + + Reviewed by Darin Adler. + + WebKit2 needs to mirror the frame tree in the UIProcess + https://bugs.webkit.org/show_bug.cgi?id=51546 + + - Add client functions to notify that a frame has been added or + removed from the page cache. + + * WebCoreSupport/FrameLoaderClientQt.cpp: + (WebCore::FrameLoaderClientQt::didSaveToPageCache): + (WebCore::FrameLoaderClientQt::didRestoreFromPageCache): + * WebCoreSupport/FrameLoaderClientQt.h: + +2010-12-22 Ryosuke Niwa <rniwa@webkit.org> + + Reviewed by Eric Seidel. + + Editor.h doesn't need to include SelectionController.h + https://bugs.webkit.org/show_bug.cgi?id=51441 + + Renamed SelectionController::EDirection to SelectionDirection. + + * WebCoreSupport/EditorClientQt.cpp: + (WebCore::EditorClientQt::handleKeyboardEvent): + +2010-12-23 Dawit Alemayehu <adawit@kde.org> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Add a 'hasSelection' function to QWebView and QWebPage. + https://bugs.webkit.org/show_bug.cgi?id=48722 + + This is a convenience API that optimizes the case where checking for + the presence of selected content and accessing the selected content + are two separate actions in the client. See comment #12 in the above + bug report link for details. + + * Api/qwebpage.cpp: + (QWebPage::hasSelection): + * Api/qwebpage.h: + * Api/qwebview.cpp: + (QWebView::hasSelection): + * Api/qwebview.h: + * tests/qwebpage/tst_qwebpage.cpp: + (tst_QWebPage::textSelection): + 2010-12-20 Benjamin Poulain <benjamin.poulain@nokia.com> Reviewed by Andreas Kling. diff --git a/WebKit/qt/WebCoreSupport/DumpRenderTreeSupportQt.cpp b/WebKit/qt/WebCoreSupport/DumpRenderTreeSupportQt.cpp index 754b20a..e958751 100644 --- a/WebKit/qt/WebCoreSupport/DumpRenderTreeSupportQt.cpp +++ b/WebKit/qt/WebCoreSupport/DumpRenderTreeSupportQt.cpp @@ -82,6 +82,27 @@ using namespace WebCore; QMap<int, QWebScriptWorld*> m_worldMap; +QDRTNode::QDRTNode() + : m_node(0) +{ +} + +QDRTNode::QDRTNode(WebCore::Node* node) + : m_node(0) +{ + if (node) { + m_node = node; + m_node->ref(); + } +} + +QDRTNode::~QDRTNode() +{ + if (m_node) + m_node->deref(); +} + + DumpRenderTreeSupportQt::DumpRenderTreeSupportQt() { } @@ -854,7 +875,10 @@ QVariantList DumpRenderTreeSupportQt::nodesFromRect(const QWebElement& document, for (int i = 0; i < nodes->length(); i++) { QVariant v; // QWebElement will be null if the Node is not an HTML Element - v.setValue(QWebElement(nodes->item(i))); + if (nodes->item(i)->isHTMLElement()) + v.setValue(QWebElement(nodes->item(i))); + else + v.setValue(QDRTNode(nodes->item(i))); res << v; } return res; diff --git a/WebKit/qt/WebCoreSupport/DumpRenderTreeSupportQt.h b/WebKit/qt/WebCoreSupport/DumpRenderTreeSupportQt.h index e08d962..6917039 100644 --- a/WebKit/qt/WebCoreSupport/DumpRenderTreeSupportQt.h +++ b/WebKit/qt/WebCoreSupport/DumpRenderTreeSupportQt.h @@ -26,6 +26,26 @@ #include "qwebkitglobal.h" #include <QVariant> +namespace WebCore { +class Text; +class Node; +} + + +#if defined(WTF_USE_V8) && WTF_USE_V8 +namespace V8 { +namespace Bindings { +class QtDRTNodeRuntime; +} +} +#else +namespace JSC { +namespace Bindings { +class QtDRTNodeRuntime; +} +} +#endif + class QWebElement; class QWebFrame; class QWebPage; @@ -34,6 +54,28 @@ class QWebScriptWorld; extern QMap<int, QWebScriptWorld*> m_worldMap; +// Used to pass WebCore::Node's to layout tests using LayoutTestController +class QWEBKIT_EXPORT QDRTNode { +public: + QDRTNode(); + ~QDRTNode(); + +private: + explicit QDRTNode(WebCore::Node*); + + friend class DumpRenderTreeSupportQt; + +#if defined(WTF_USE_V8) && WTF_USE_V8 + friend class V8::Bindings::QtDRTNodeRuntime; +#else + friend class JSC::Bindings::QtDRTNodeRuntime; +#endif + + WebCore::Node* m_node; +}; + +Q_DECLARE_METATYPE(QDRTNode) + class QWEBKIT_EXPORT DumpRenderTreeSupportQt { public: diff --git a/WebKit/qt/WebCoreSupport/EditorClientQt.cpp b/WebKit/qt/WebCoreSupport/EditorClientQt.cpp index 3fbc83d..534e334 100644 --- a/WebKit/qt/WebCoreSupport/EditorClientQt.cpp +++ b/WebKit/qt/WebCoreSupport/EditorClientQt.cpp @@ -346,6 +346,60 @@ void EditorClientQt::toggleGrammarChecking() notImplemented(); } +static const unsigned CtrlKey = 1 << 0; +static const unsigned AltKey = 1 << 1; +static const unsigned ShiftKey = 1 << 2; + +struct KeyDownEntry { + unsigned virtualKey; + unsigned modifiers; + const char* editorCommand; +}; + +// Handle here key down events that are needed for spatial navigation and caret browsing, or +// are not handled by QWebPage. +static const KeyDownEntry keyDownEntries[] = { + // Ones that do not have an associated QAction: + { VK_DELETE, 0, "DeleteForward" }, + { VK_BACK, ShiftKey, "DeleteBackward" }, + { VK_BACK, 0, "DeleteBackward" }, + // Ones that need special handling for caret browsing: + { VK_PRIOR, 0, "MovePageUp" }, + { VK_PRIOR, ShiftKey, "MovePageUpAndModifySelection" }, + { VK_NEXT, 0, "MovePageDown" }, + { VK_NEXT, ShiftKey, "MovePageDownAndModifySelection" }, + // Ones that need special handling for spatial navigation: + { VK_LEFT, 0, "MoveLeft" }, + { VK_RIGHT, 0, "MoveRight" }, + { VK_UP, 0, "MoveUp" }, + { VK_DOWN, 0, "MoveDown" }, +}; + +const char* editorCommandForKeyDownEvent(const KeyboardEvent* event) +{ + if (event->type() != eventNames().keydownEvent) + return ""; + + static HashMap<int, const char*> keyDownCommandsMap; + if (keyDownCommandsMap.isEmpty()) { + + unsigned numEntries = sizeof(keyDownEntries) / sizeof((keyDownEntries)[0]); + for (unsigned i = 0; i < numEntries; i++) + keyDownCommandsMap.set(keyDownEntries[i].modifiers << 16 | keyDownEntries[i].virtualKey, keyDownEntries[i].editorCommand); + } + + unsigned modifiers = 0; + if (event->shiftKey()) + modifiers |= ShiftKey; + if (event->altKey()) + modifiers |= AltKey; + if (event->ctrlKey()) + modifiers |= CtrlKey; + + int mapKey = modifiers << 16 | event->keyCode(); + return mapKey ? keyDownCommandsMap.get(mapKey) : 0; +} + void EditorClientQt::handleKeyboardEvent(KeyboardEvent* event) { Frame* frame = m_page->d->page->focusController()->focusedOrMainFrame(); @@ -387,150 +441,85 @@ void EditorClientQt::handleKeyboardEvent(KeyboardEvent* event) return; m_page->triggerAction(action); - } else + event->setDefaultHandled(); + return; + } else { #endif // QT_NO_SHORTCUT - switch (kevent->windowsVirtualKeyCode()) { - case VK_BACK: - frame->editor()->deleteWithDirection(SelectionController::DirectionBackward, - CharacterGranularity, false, true); - break; - case VK_DELETE: - frame->editor()->deleteWithDirection(SelectionController::DirectionForward, - CharacterGranularity, false, true); - break; - case VK_LEFT: - if (kevent->shiftKey()) - frame->editor()->command("MoveLeftAndModifySelection").execute(); - else if (!frame->editor()->command("MoveLeft").execute()) - return; - break; - case VK_RIGHT: - if (kevent->shiftKey()) - frame->editor()->command("MoveRightAndModifySelection").execute(); - else if (!frame->editor()->command("MoveRight").execute()) - return; - break; - case VK_UP: - if (kevent->shiftKey()) - frame->editor()->command("MoveUpAndModifySelection").execute(); - else if (!frame->editor()->command("MoveUp").execute()) + String commandName = editorCommandForKeyDownEvent(event); + if (!commandName.isEmpty()) { + if (frame->editor()->command(commandName).execute()) // Event handled. + event->setDefaultHandled(); return; - break; - case VK_DOWN: - if (kevent->shiftKey()) - frame->editor()->command("MoveDownAndModifySelection").execute(); - else if (!frame->editor()->command("MoveDown").execute()) + } + + if (kevent->windowsVirtualKeyCode() == VK_TAB) { + // Do not handle TAB text insertion here. return; - break; - case VK_PRIOR: // PageUp - if (kevent->shiftKey()) - frame->editor()->command("MovePageUpAndModifySelection").execute(); - else - frame->editor()->command("MovePageUp").execute(); - break; - case VK_NEXT: // PageDown - if (kevent->shiftKey()) - frame->editor()->command("MovePageDownAndModifySelection").execute(); - else - frame->editor()->command("MovePageDown").execute(); - break; - case VK_TAB: - return; - default: - if (kevent->type() != PlatformKeyboardEvent::KeyDown && !kevent->ctrlKey() + } + + // Text insertion. + bool shouldInsertText = false; + if (kevent->type() != PlatformKeyboardEvent::KeyDown && !kevent->text().isEmpty()) { + + if (kevent->ctrlKey()) { + if (kevent->altKey()) + shouldInsertText = true; + } else { #ifndef Q_WS_MAC // We need to exclude checking for Alt because it is just a different Shift - && !kevent->altKey() + if (!kevent->altKey()) #endif - && !kevent->text().isEmpty()) { - frame->editor()->insertText(kevent->text(), event); - } else if (kevent->ctrlKey()) { - switch (kevent->windowsVirtualKeyCode()) { - case VK_A: - frame->editor()->command("SelectAll").execute(); - break; - case VK_B: - frame->editor()->command("ToggleBold").execute(); - break; - case VK_I: - frame->editor()->command("ToggleItalic").execute(); - break; - default: - // catch combination AltGr+key or Ctrl+Alt+key - if (kevent->type() != PlatformKeyboardEvent::KeyDown && kevent->altKey() && !kevent->text().isEmpty()) { - frame->editor()->insertText(kevent->text(), event); - break; - } - return; + shouldInsertText = true; + } - } else + } + + if (shouldInsertText) { + frame->editor()->insertText(kevent->text(), event); + event->setDefaultHandled(); return; + } } - } else { - if (m_page->handle()->page->settings()->caretBrowsingEnabled()) { - switch (kevent->windowsVirtualKeyCode()) { - case VK_LEFT: - if (kevent->shiftKey() && kevent->ctrlKey()) - frame->editor()->command("MoveWordBackwardAndModifySelection").execute(); - else if (kevent->shiftKey()) - frame->editor()->command("MoveLeftAndModifySelection").execute(); - else if (kevent->ctrlKey()) - frame->editor()->command("MoveWordBackward").execute(); - else - frame->editor()->command("MoveLeft").execute(); - break; - case VK_RIGHT: - if (kevent->shiftKey() && kevent->ctrlKey()) - frame->editor()->command("MoveWordForwardAndModifySelection").execute(); - else if (kevent->shiftKey()) - frame->editor()->command("MoveRightAndModifySelection").execute(); - else if (kevent->ctrlKey()) - frame->editor()->command("MoveWordForward").execute(); - else - frame->editor()->command("MoveRight").execute(); - break; - case VK_UP: - if (kevent->shiftKey()) - frame->editor()->command("MoveUpAndModifySelection").execute(); - else - frame->editor()->command("MoveUp").execute(); - break; - case VK_DOWN: - if (kevent->shiftKey()) - frame->editor()->command("MoveDownAndModifySelection").execute(); - else - frame->editor()->command("MoveDown").execute(); - break; - case VK_PRIOR: // PageUp - frame->editor()->command("MovePageUp").execute(); - break; - case VK_NEXT: // PageDown - frame->editor()->command("MovePageDown").execute(); - break; - case VK_HOME: - if (kevent->shiftKey()) - frame->editor()->command("MoveToBeginningOfLineAndModifySelection").execute(); - else - frame->editor()->command("MoveToBeginningOfLine").execute(); - break; - case VK_END: - if (kevent->shiftKey()) - frame->editor()->command("MoveToEndOfLineAndModifySelection").execute(); - else - frame->editor()->command("MoveToEndOfLine").execute(); - break; - default: - break; + + // Event not handled. + return; + } + + // Non editable content. + if (m_page->handle()->page->settings()->caretBrowsingEnabled()) { + switch (kevent->windowsVirtualKeyCode()) { + case VK_LEFT: + case VK_RIGHT: + case VK_UP: + case VK_DOWN: + case VK_HOME: + case VK_END: + { + QWebPage::WebAction action = QWebPagePrivate::editorActionForKeyEvent(kevent->qtEvent()); + ASSERT(action != QWebPage::NoWebAction); + m_page->triggerAction(action); + event->setDefaultHandled(); + return; + } + case VK_PRIOR: // PageUp + case VK_NEXT: // PageDown + { + String commandName = editorCommandForKeyDownEvent(event); + ASSERT(!commandName.isEmpty()); + frame->editor()->command(commandName).execute(); + event->setDefaultHandled(); + return; } } + } + #ifndef QT_NO_SHORTCUT - if (kevent->qtEvent() == QKeySequence::Copy) - m_page->triggerAction(QWebPage::Copy); - else -#endif // QT_NO_SHORTCUT - return; + if (kevent->qtEvent() == QKeySequence::Copy) { + m_page->triggerAction(QWebPage::Copy); + event->setDefaultHandled(); + return; } - event->setDefaultHandled(); +#endif // QT_NO_SHORTCUT } void EditorClientQt::handleInputMethodKeydown(KeyboardEvent*) diff --git a/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp b/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp index 849958f..e83d5ef 100644 --- a/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp +++ b/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp @@ -295,6 +295,14 @@ void FrameLoaderClientQt::transitionToCommittedForNewPage() m_frame->view()->setActualVisibleContentRect(IntRect(IntPoint::zero(), currentVisibleContentSize)); } +void FrameLoaderClientQt::didSaveToPageCache() +{ +} + +void FrameLoaderClientQt::didRestoreFromPageCache() +{ +} + void FrameLoaderClientQt::dispatchDidBecomeFrameset(bool) { } @@ -1437,7 +1445,12 @@ public: graphicsWidget->hide(); } private: - QtPluginGraphicsWidget(QGraphicsWidget* w = 0): Widget(0), graphicsWidget(w) {} + QtPluginGraphicsWidget(QGraphicsWidget* w = 0) + : Widget(0) + , graphicsWidget(w) + { + setBindingObject(graphicsWidget); + } QGraphicsWidget* graphicsWidget; }; diff --git a/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.h b/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.h index 275b0e8..3d93eaf 100644 --- a/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.h +++ b/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.h @@ -193,6 +193,9 @@ public: virtual void transitionToCommittedFromCachedFrame(WebCore::CachedFrame*); virtual void transitionToCommittedForNewPage(); + virtual void didSaveToPageCache(); + virtual void didRestoreFromPageCache(); + virtual void dispatchDidBecomeFrameset(bool); virtual bool canCachePage() const; diff --git a/WebKit/qt/WebCoreSupport/InspectorServerQt.h b/WebKit/qt/WebCoreSupport/InspectorServerQt.h index 74e8c2f..922b63e 100644 --- a/WebKit/qt/WebCoreSupport/InspectorServerQt.h +++ b/WebKit/qt/WebCoreSupport/InspectorServerQt.h @@ -27,8 +27,10 @@ #include <QString> #include <wtf/Forward.h> +QT_BEGIN_NAMESPACE class QTcpServer; class QTcpSocket; +QT_END_NAMESPACE class QWebPage; namespace WebCore { diff --git a/WebKit/qt/WebCoreSupport/WebPlatformStrategies.cpp b/WebKit/qt/WebCoreSupport/WebPlatformStrategies.cpp index 7cd255f..c67ec2f 100644 --- a/WebKit/qt/WebCoreSupport/WebPlatformStrategies.cpp +++ b/WebKit/qt/WebCoreSupport/WebPlatformStrategies.cpp @@ -290,6 +290,11 @@ String WebPlatformStrategies::contextMenuItemTagPaste() return QCoreApplication::translate("QWebPage", "Paste", "Paste context menu item"); } +String WebPlatformStrategies::contextMenuItemTagSelectAll() +{ + return QCoreApplication::translate("QWebPage", "Select All", "Select All context menu item"); +} + String WebPlatformStrategies::contextMenuItemTagNoGuessesFound() { return QCoreApplication::translate("QWebPage", "No Guesses Found", "No Guesses Found context menu item"); diff --git a/WebKit/qt/WebCoreSupport/WebPlatformStrategies.h b/WebKit/qt/WebCoreSupport/WebPlatformStrategies.h index ea366e0..5f72f46 100644 --- a/WebKit/qt/WebCoreSupport/WebPlatformStrategies.h +++ b/WebKit/qt/WebCoreSupport/WebPlatformStrategies.h @@ -74,6 +74,7 @@ private: virtual WTF::String contextMenuItemTagReload(); virtual WTF::String contextMenuItemTagCut(); virtual WTF::String contextMenuItemTagPaste(); + virtual WTF::String contextMenuItemTagSelectAll(); virtual WTF::String contextMenuItemTagNoGuessesFound(); virtual WTF::String contextMenuItemTagIgnoreSpelling(); virtual WTF::String contextMenuItemTagLearnSpelling(); diff --git a/WebKit/qt/WebKit_pch.h b/WebKit/qt/WebKit_pch.h index 1dd4d52..f9f0fc1 100644 --- a/WebKit/qt/WebKit_pch.h +++ b/WebKit/qt/WebKit_pch.h @@ -39,7 +39,7 @@ #include <windows.h> #endif -#include "../../JavaScriptCore/config.h" +#include "../../Source/JavaScriptCore/config.h" #include <math.h> #include <stdio.h> diff --git a/WebKit/qt/declarative/qdeclarativewebview.cpp b/WebKit/qt/declarative/qdeclarativewebview.cpp index 94f08bd..e26889e 100644 --- a/WebKit/qt/declarative/qdeclarativewebview.cpp +++ b/WebKit/qt/declarative/qdeclarativewebview.cpp @@ -253,10 +253,12 @@ void QDeclarativeWebView::init() setAcceptedMouseButtons(Qt::LeftButton); setFlag(QGraphicsItem::ItemHasNoContents, true); + setFlag(QGraphicsItem::ItemIsFocusScope, true); setClip(true); d->view = new GraphicsWebView(this); d->view->setResizesToContents(true); + d->view->setFocus(); QWebPage* wp = new QDeclarativeWebPage(this); setPage(wp); connect(d->view, SIGNAL(geometryChanged()), this, SLOT(updateDeclarativeWebViewSize())); diff --git a/WebKit/qt/docs/qtwebkit.qdoc b/WebKit/qt/docs/qtwebkit.qdoc index 0335d46..df22e65 100644 --- a/WebKit/qt/docs/qtwebkit.qdoc +++ b/WebKit/qt/docs/qtwebkit.qdoc @@ -51,7 +51,7 @@ building the module only in release mode for embedded platforms. Currently QtWebKit will always be compiled without debugging symbols when using gcc. Take a look at the last lines of - \c{src/3rdparty/webkit/WebCore/WebCore.pro} if you need to change this. + \c{src/3rdparty/webkit/Source/WebCore/WebCore.pro} if you need to change this. \note Web site icons, also known as "FavIcons", are currently not supported on Windows. We plan to address this in a future release. diff --git a/WebKit/qt/docs/qtwebkit.qdocconf b/WebKit/qt/docs/qtwebkit.qdocconf index 5f877c2..f1d198d 100644 --- a/WebKit/qt/docs/qtwebkit.qdocconf +++ b/WebKit/qt/docs/qtwebkit.qdocconf @@ -4,7 +4,7 @@ project = qtwebkit description = "Qt WebKit API Documentation" headerdirs = $SRCDIR/WebKit/qt/Api $SRCDIR/WebKit/qt/declarative -sourcedirs = $SRCDIR/WebKit/qt/Api $SRCDIR/WebKit/qt/docs $SRCDIR/JavaScriptCore/qt/api $SRCDIR/WebKit/qt/declarative +sourcedirs = $SRCDIR/WebKit/qt/Api $SRCDIR/WebKit/qt/docs $SRCDIR/Source/JavaScriptCore/qt/api $SRCDIR/WebKit/qt/declarative outputdir = $OUTPUT_DIR/doc/html outputformats = HTML sources.fileextensions = "*.cpp *.doc *.qdoc *.h" diff --git a/WebKit/qt/examples/platformplugin/qwebkitplatformplugin.h b/WebKit/qt/examples/platformplugin/qwebkitplatformplugin.h index f38a8fb..b8cc984 100644 --- a/WebKit/qt/examples/platformplugin/qwebkitplatformplugin.h +++ b/WebKit/qt/examples/platformplugin/qwebkitplatformplugin.h @@ -84,9 +84,13 @@ Q_SIGNALS: void notificationClicked(); }; -class QWebHapticFeedbackPlayer +class QWebHapticFeedbackPlayer: public QObject { + Q_OBJECT public: + QWebHapticFeedbackPlayer() {} + virtual ~QWebHapticFeedbackPlayer() {} + enum HapticStrength { None, Weak, Medium, Strong }; @@ -127,6 +131,8 @@ public: virtual QObject* createExtension(Extension extension) const = 0; }; +QT_BEGIN_NAMESPACE Q_DECLARE_INTERFACE(QWebKitPlatformPlugin, "com.nokia.Qt.WebKit.PlatformPlugin/1.6"); +QT_END_NAMESPACE #endif // QWEBKITPLATFORMPLUGIN_H diff --git a/WebKit/qt/tests/hybridPixmap/widget.h b/WebKit/qt/tests/hybridPixmap/widget.h index a49f8ba..2ac8a06 100644 --- a/WebKit/qt/tests/hybridPixmap/widget.h +++ b/WebKit/qt/tests/hybridPixmap/widget.h @@ -27,9 +27,11 @@ typedef QWebView WebView; +QT_BEGIN_NAMESPACE namespace Ui { class Widget; } +QT_END_NAMESPACE class Widget : public QWidget { Q_OBJECT diff --git a/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp b/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp index 4645a06..b71f665 100644 --- a/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp +++ b/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp @@ -21,6 +21,7 @@ #include "../util.h" #include "../WebCoreSupport/DumpRenderTreeSupportQt.h" +#include <QClipboard> #include <QDir> #include <QGraphicsWidget> #include <QLineEdit> @@ -90,6 +91,7 @@ private slots: void destroyPlugin(); void createViewlessPlugin_data(); void createViewlessPlugin(); + void graphicsWidgetPlugin(); void multiplePageGroupsAndLocalStorage(); void cursorMovements(); void textSelection(); @@ -129,6 +131,10 @@ private slots: void supportedContentType(); void infiniteLoopJS(); void networkAccessManagerOnDifferentThread(); + +#ifdef Q_OS_MAC + void macCopyUnicodeToClipboard(); +#endif private: QWebView* m_view; @@ -583,6 +589,8 @@ protected: result = new QPushButton(); else if (classid == "lineedit") result = new QLineEdit(); + else if (classid == "graphicswidget") + result = new QGraphicsWidget(); if (result) result->setObjectName(classid); calls.append(CallInfo(classid, url, paramNames, paramValues, result)); @@ -672,6 +680,54 @@ static void createPlugin(QWebView *view) } } +void tst_QWebPage::graphicsWidgetPlugin() +{ + m_view->settings()->setAttribute(QWebSettings::PluginsEnabled, true); + QGraphicsWebView webView; + + QSignalSpy loadSpy(&webView, SIGNAL(loadFinished(bool))); + + PluginPage* newPage = new PluginPage(&webView); + webView.setPage(newPage); + + // type has to be application/x-qt-plugin + webView.setHtml(QString("<html><body><object type='application/x-foobarbaz' classid='graphicswidget' id='mygraphicswidget'/></body></html>")); + QTRY_COMPARE(loadSpy.count(), 1); + QCOMPARE(newPage->calls.count(), 0); + + webView.setHtml(QString("<html><body><object type='application/x-qt-plugin' classid='graphicswidget' id='mygraphicswidget'/></body></html>")); + QTRY_COMPARE(loadSpy.count(), 2); + QCOMPARE(newPage->calls.count(), 1); + { + PluginPage::CallInfo ci = newPage->calls.takeFirst(); + QCOMPARE(ci.classid, QString::fromLatin1("graphicswidget")); + QCOMPARE(ci.url, QUrl()); + QCOMPARE(ci.paramNames.count(), 3); + QCOMPARE(ci.paramValues.count(), 3); + QCOMPARE(ci.paramNames.at(0), QString::fromLatin1("type")); + QCOMPARE(ci.paramValues.at(0), QString::fromLatin1("application/x-qt-plugin")); + QCOMPARE(ci.paramNames.at(1), QString::fromLatin1("classid")); + QCOMPARE(ci.paramValues.at(1), QString::fromLatin1("graphicswidget")); + QCOMPARE(ci.paramNames.at(2), QString::fromLatin1("id")); + QCOMPARE(ci.paramValues.at(2), QString::fromLatin1("mygraphicswidget")); + QVERIFY(ci.returnValue); + QVERIFY(ci.returnValue->inherits("QGraphicsWidget")); + } + // test JS bindings + QCOMPARE(newPage->mainFrame()->evaluateJavaScript("document.getElementById('mygraphicswidget').toString()").toString(), + QString::fromLatin1("[object HTMLObjectElement]")); + QCOMPARE(newPage->mainFrame()->evaluateJavaScript("mygraphicswidget.toString()").toString(), + QString::fromLatin1("[object HTMLObjectElement]")); + QCOMPARE(newPage->mainFrame()->evaluateJavaScript("typeof mygraphicswidget.objectName").toString(), + QString::fromLatin1("string")); + QCOMPARE(newPage->mainFrame()->evaluateJavaScript("mygraphicswidget.objectName").toString(), + QString::fromLatin1("graphicswidget")); + QCOMPARE(newPage->mainFrame()->evaluateJavaScript("typeof mygraphicswidget.geometryChanged").toString(), + QString::fromLatin1("function")); + QCOMPARE(newPage->mainFrame()->evaluateJavaScript("mygraphicswidget.geometryChanged.toString()").toString(), + QString::fromLatin1("function geometryChanged() {\n [native code]\n}")); +} + void tst_QWebPage::createPluginWithPluginsEnabled() { m_view->settings()->setAttribute(QWebSettings::PluginsEnabled, true); @@ -879,6 +935,7 @@ void tst_QWebPage::cursorMovements() "getSelection().addRange(range);"; page->mainFrame()->evaluateJavaScript(script); QCOMPARE(page->selectedText().trimmed(), QString::fromLatin1("The quick brown fox")); + QCOMPARE(page->selectedHtml().trimmed(), QString::fromLatin1("<span class=\"Apple-style-span\" style=\"border-collapse: separate; color: rgb(0, 0, 0); font-family: Times; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; font-size: medium; \"><p id=\"one\">The quick brown fox</p></span>")); // these actions must exist QVERIFY(page->action(QWebPage::MoveToNextChar) != 0); @@ -1099,6 +1156,9 @@ void tst_QWebPage::textSelection() // ..but SelectAll is awalys enabled QCOMPARE(page->action(QWebPage::SelectAll)->isEnabled(), true); + // Verify hasSelection returns false since there is no selection yet... + QCOMPARE(page->hasSelection(), false); + // this will select the first paragraph QString selectScript = "var range = document.createRange(); " \ "var node = document.getElementById(\"one\"); " \ @@ -1106,6 +1166,10 @@ void tst_QWebPage::textSelection() "getSelection().addRange(range);"; page->mainFrame()->evaluateJavaScript(selectScript); QCOMPARE(page->selectedText().trimmed(), QString::fromLatin1("The quick brown fox")); + QCOMPARE(page->selectedHtml().trimmed(), QString::fromLatin1("<span class=\"Apple-style-span\" style=\"border-collapse: separate; color: rgb(0, 0, 0); font-family: Times; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; font-size: medium; \"><p id=\"one\">The quick brown fox</p></span>")); + + // Make sure hasSelection returns true, since there is selected text now... + QCOMPARE(page->hasSelection(), true); // here the actions are enabled after a selection has been created QCOMPARE(page->action(QWebPage::SelectNextChar)->isEnabled(), true); @@ -2318,6 +2382,10 @@ void tst_QWebPage::crashTests_LazyInitializationOfMainFrame() } { QWebPage webPage; + webPage.selectedHtml(); + } + { + QWebPage webPage; webPage.triggerAction(QWebPage::Back, true); } { @@ -2512,14 +2580,18 @@ void tst_QWebPage::findText() m_view->setHtml(QString("<html><head></head><body><div>foo bar</div></body></html>")); m_page->triggerAction(QWebPage::SelectAll); QVERIFY(!m_page->selectedText().isEmpty()); + QVERIFY(!m_page->selectedHtml().isEmpty()); m_page->findText(""); QVERIFY(m_page->selectedText().isEmpty()); + QVERIFY(m_page->selectedHtml().isEmpty()); QStringList words = (QStringList() << "foo" << "bar"); foreach (QString subString, words) { m_page->findText(subString, QWebPage::FindWrapsAroundDocument); QCOMPARE(m_page->selectedText(), subString); + QCOMPARE(m_page->selectedHtml(), QString("<span class=\"Apple-style-span\" style=\"border-collapse: separate; color: rgb(0, 0, 0); font-family: Times; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; font-size: medium; \">%1</span>").arg(subString)); m_page->findText(""); QVERIFY(m_page->selectedText().isEmpty()); + QVERIFY(m_page->selectedHtml().isEmpty()); } } @@ -2638,5 +2710,20 @@ void tst_QWebPage::networkAccessManagerOnDifferentThread() QCOMPARE(m_page->mainFrame()->childFrames()[0]->url(), QUrl("qrc:///resources/frame_a.html")); } +#ifdef Q_OS_MAC +void tst_QWebPage::macCopyUnicodeToClipboard() +{ + QString unicodeText = QString::fromUtf8("αβγδεζηθικλμπ"); + m_page->mainFrame()->setHtml(QString("<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" /></head><body>%1</body></html>").arg(unicodeText)); + m_page->triggerAction(QWebPage::SelectAll); + m_page->triggerAction(QWebPage::Copy); + + QString clipboardData = QString::fromUtf8(QApplication::clipboard()->mimeData()->data(QLatin1String("text/html"))); + + QVERIFY(clipboardData.contains(QLatin1String("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />"))); + QVERIFY(clipboardData.contains(unicodeText)); +} +#endif + QTEST_MAIN(tst_QWebPage) #include "tst_qwebpage.moc" |