");
page->mainFrame()->setHtml(content);
// this will select the first paragraph
QString script = "var range = document.createRange(); " \
"var node = document.getElementById(\"one\"); " \
"range.selectNode(node); " \
"getSelection().addRange(range);";
page->mainFrame()->evaluateJavaScript(script);
QCOMPARE(page->selectedText().trimmed(), QString::fromLatin1("The quick brown fox"));
// these actions must exist
QVERIFY(page->action(QWebPage::MoveToNextChar) != 0);
QVERIFY(page->action(QWebPage::MoveToPreviousChar) != 0);
QVERIFY(page->action(QWebPage::MoveToNextWord) != 0);
QVERIFY(page->action(QWebPage::MoveToPreviousWord) != 0);
QVERIFY(page->action(QWebPage::MoveToNextLine) != 0);
QVERIFY(page->action(QWebPage::MoveToPreviousLine) != 0);
QVERIFY(page->action(QWebPage::MoveToStartOfLine) != 0);
QVERIFY(page->action(QWebPage::MoveToEndOfLine) != 0);
QVERIFY(page->action(QWebPage::MoveToStartOfBlock) != 0);
QVERIFY(page->action(QWebPage::MoveToEndOfBlock) != 0);
QVERIFY(page->action(QWebPage::MoveToStartOfDocument) != 0);
QVERIFY(page->action(QWebPage::MoveToEndOfDocument) != 0);
// right now they are disabled because contentEditable is false
QCOMPARE(page->action(QWebPage::MoveToNextChar)->isEnabled(), false);
QCOMPARE(page->action(QWebPage::MoveToPreviousChar)->isEnabled(), false);
QCOMPARE(page->action(QWebPage::MoveToNextWord)->isEnabled(), false);
QCOMPARE(page->action(QWebPage::MoveToPreviousWord)->isEnabled(), false);
QCOMPARE(page->action(QWebPage::MoveToNextLine)->isEnabled(), false);
QCOMPARE(page->action(QWebPage::MoveToPreviousLine)->isEnabled(), false);
QCOMPARE(page->action(QWebPage::MoveToStartOfLine)->isEnabled(), false);
QCOMPARE(page->action(QWebPage::MoveToEndOfLine)->isEnabled(), false);
QCOMPARE(page->action(QWebPage::MoveToStartOfBlock)->isEnabled(), false);
QCOMPARE(page->action(QWebPage::MoveToEndOfBlock)->isEnabled(), false);
QCOMPARE(page->action(QWebPage::MoveToStartOfDocument)->isEnabled(), false);
QCOMPARE(page->action(QWebPage::MoveToEndOfDocument)->isEnabled(), false);
// make it editable before navigating the cursor
page->setContentEditable(true);
// here the actions are enabled after contentEditable is true
QCOMPARE(page->action(QWebPage::MoveToNextChar)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::MoveToPreviousChar)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::MoveToNextWord)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::MoveToPreviousWord)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::MoveToNextLine)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::MoveToPreviousLine)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::MoveToStartOfLine)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::MoveToEndOfLine)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::MoveToStartOfBlock)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::MoveToEndOfBlock)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::MoveToStartOfDocument)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::MoveToEndOfDocument)->isEnabled(), true);
// cursor will be before the word "jump"
page->triggerAction(QWebPage::MoveToNextChar);
QVERIFY(page->isSelectionCollapsed());
QCOMPARE(page->selectionStartOffset(), 0);
// cursor will be between 'j' and 'u' in the word "jump"
page->triggerAction(QWebPage::MoveToNextChar);
QVERIFY(page->isSelectionCollapsed());
QCOMPARE(page->selectionStartOffset(), 1);
// cursor will be between 'u' and 'm' in the word "jump"
page->triggerAction(QWebPage::MoveToNextChar);
QVERIFY(page->isSelectionCollapsed());
QCOMPARE(page->selectionStartOffset(), 2);
// cursor will be after the word "jump"
page->triggerAction(QWebPage::MoveToNextWord);
QVERIFY(page->isSelectionCollapsed());
QCOMPARE(page->selectionStartOffset(), 5);
// cursor will be after the word "lazy"
page->triggerAction(QWebPage::MoveToNextWord);
page->triggerAction(QWebPage::MoveToNextWord);
page->triggerAction(QWebPage::MoveToNextWord);
QVERIFY(page->isSelectionCollapsed());
QCOMPARE(page->selectionStartOffset(), 19);
// cursor will be between 'z' and 'y' in "lazy"
page->triggerAction(QWebPage::MoveToPreviousChar);
QVERIFY(page->isSelectionCollapsed());
QCOMPARE(page->selectionStartOffset(), 18);
// cursor will be between 'a' and 'z' in "lazy"
page->triggerAction(QWebPage::MoveToPreviousChar);
QVERIFY(page->isSelectionCollapsed());
QCOMPARE(page->selectionStartOffset(), 17);
// cursor will be before the word "lazy"
page->triggerAction(QWebPage::MoveToPreviousWord);
QVERIFY(page->isSelectionCollapsed());
QCOMPARE(page->selectionStartOffset(), 15);
// cursor will be before the word "quick"
page->triggerAction(QWebPage::MoveToPreviousWord);
page->triggerAction(QWebPage::MoveToPreviousWord);
page->triggerAction(QWebPage::MoveToPreviousWord);
page->triggerAction(QWebPage::MoveToPreviousWord);
page->triggerAction(QWebPage::MoveToPreviousWord);
page->triggerAction(QWebPage::MoveToPreviousWord);
QVERIFY(page->isSelectionCollapsed());
QCOMPARE(page->selectionStartOffset(), 4);
// cursor will be between 'p' and 's' in the word "jumps"
page->triggerAction(QWebPage::MoveToNextWord);
page->triggerAction(QWebPage::MoveToNextWord);
page->triggerAction(QWebPage::MoveToNextWord);
page->triggerAction(QWebPage::MoveToNextChar);
page->triggerAction(QWebPage::MoveToNextChar);
page->triggerAction(QWebPage::MoveToNextChar);
page->triggerAction(QWebPage::MoveToNextChar);
page->triggerAction(QWebPage::MoveToNextChar);
QVERIFY(page->isSelectionCollapsed());
QCOMPARE(page->selectionStartOffset(), 4);
// cursor will be before the word "jumps"
page->triggerAction(QWebPage::MoveToStartOfLine);
QVERIFY(page->isSelectionCollapsed());
QCOMPARE(page->selectionStartOffset(), 0);
// cursor will be after the word "dog"
page->triggerAction(QWebPage::MoveToEndOfLine);
QVERIFY(page->isSelectionCollapsed());
QCOMPARE(page->selectionStartOffset(), 23);
// cursor will be between 'w' and 'n' in "brown"
page->triggerAction(QWebPage::MoveToStartOfLine);
page->triggerAction(QWebPage::MoveToPreviousWord);
page->triggerAction(QWebPage::MoveToPreviousWord);
page->triggerAction(QWebPage::MoveToNextChar);
page->triggerAction(QWebPage::MoveToNextChar);
page->triggerAction(QWebPage::MoveToNextChar);
page->triggerAction(QWebPage::MoveToNextChar);
QVERIFY(page->isSelectionCollapsed());
QCOMPARE(page->selectionStartOffset(), 14);
// cursor will be after the word "fox"
page->triggerAction(QWebPage::MoveToEndOfLine);
QVERIFY(page->isSelectionCollapsed());
QCOMPARE(page->selectionStartOffset(), 19);
// cursor will be before the word "The"
page->triggerAction(QWebPage::MoveToStartOfDocument);
QVERIFY(page->isSelectionCollapsed());
QCOMPARE(page->selectionStartOffset(), 0);
// cursor will be after the word "you!"
page->triggerAction(QWebPage::MoveToEndOfDocument);
QVERIFY(page->isSelectionCollapsed());
QCOMPARE(page->selectionStartOffset(), 12);
// cursor will be before the word "be"
page->triggerAction(QWebPage::MoveToStartOfBlock);
QVERIFY(page->isSelectionCollapsed());
QCOMPARE(page->selectionStartOffset(), 0);
// cursor will be after the word "you!"
page->triggerAction(QWebPage::MoveToEndOfBlock);
QVERIFY(page->isSelectionCollapsed());
QCOMPARE(page->selectionStartOffset(), 12);
// try to move before the document start
page->triggerAction(QWebPage::MoveToStartOfDocument);
page->triggerAction(QWebPage::MoveToPreviousChar);
QVERIFY(page->isSelectionCollapsed());
QCOMPARE(page->selectionStartOffset(), 0);
page->triggerAction(QWebPage::MoveToStartOfDocument);
page->triggerAction(QWebPage::MoveToPreviousWord);
QVERIFY(page->isSelectionCollapsed());
QCOMPARE(page->selectionStartOffset(), 0);
// try to move past the document end
page->triggerAction(QWebPage::MoveToEndOfDocument);
page->triggerAction(QWebPage::MoveToNextChar);
QVERIFY(page->isSelectionCollapsed());
QCOMPARE(page->selectionStartOffset(), 12);
page->triggerAction(QWebPage::MoveToEndOfDocument);
page->triggerAction(QWebPage::MoveToNextWord);
QVERIFY(page->isSelectionCollapsed());
QCOMPARE(page->selectionStartOffset(), 12);
delete page;
}
void tst_QWebPage::textSelection()
{
CursorTrackedPage* page = new CursorTrackedPage;
QString content("The quick brown fox
" \
"
jumps over the lazy dog
" \
"
May the source be with you!
");
page->mainFrame()->setHtml(content);
// these actions must exist
QVERIFY(page->action(QWebPage::SelectAll) != 0);
QVERIFY(page->action(QWebPage::SelectNextChar) != 0);
QVERIFY(page->action(QWebPage::SelectPreviousChar) != 0);
QVERIFY(page->action(QWebPage::SelectNextWord) != 0);
QVERIFY(page->action(QWebPage::SelectPreviousWord) != 0);
QVERIFY(page->action(QWebPage::SelectNextLine) != 0);
QVERIFY(page->action(QWebPage::SelectPreviousLine) != 0);
QVERIFY(page->action(QWebPage::SelectStartOfLine) != 0);
QVERIFY(page->action(QWebPage::SelectEndOfLine) != 0);
QVERIFY(page->action(QWebPage::SelectStartOfBlock) != 0);
QVERIFY(page->action(QWebPage::SelectEndOfBlock) != 0);
QVERIFY(page->action(QWebPage::SelectStartOfDocument) != 0);
QVERIFY(page->action(QWebPage::SelectEndOfDocument) != 0);
// right now they are disabled because contentEditable is false and
// there isn't an existing selection to modify
QCOMPARE(page->action(QWebPage::SelectNextChar)->isEnabled(), false);
QCOMPARE(page->action(QWebPage::SelectPreviousChar)->isEnabled(), false);
QCOMPARE(page->action(QWebPage::SelectNextWord)->isEnabled(), false);
QCOMPARE(page->action(QWebPage::SelectPreviousWord)->isEnabled(), false);
QCOMPARE(page->action(QWebPage::SelectNextLine)->isEnabled(), false);
QCOMPARE(page->action(QWebPage::SelectPreviousLine)->isEnabled(), false);
QCOMPARE(page->action(QWebPage::SelectStartOfLine)->isEnabled(), false);
QCOMPARE(page->action(QWebPage::SelectEndOfLine)->isEnabled(), false);
QCOMPARE(page->action(QWebPage::SelectStartOfBlock)->isEnabled(), false);
QCOMPARE(page->action(QWebPage::SelectEndOfBlock)->isEnabled(), false);
QCOMPARE(page->action(QWebPage::SelectStartOfDocument)->isEnabled(), false);
QCOMPARE(page->action(QWebPage::SelectEndOfDocument)->isEnabled(), false);
// ..but SelectAll is awalys enabled
QCOMPARE(page->action(QWebPage::SelectAll)->isEnabled(), true);
// this will select the first paragraph
QString selectScript = "var range = document.createRange(); " \
"var node = document.getElementById(\"one\"); " \
"range.selectNode(node); " \
"getSelection().addRange(range);";
page->mainFrame()->evaluateJavaScript(selectScript);
QCOMPARE(page->selectedText().trimmed(), QString::fromLatin1("The quick brown fox"));
// here the actions are enabled after a selection has been created
QCOMPARE(page->action(QWebPage::SelectNextChar)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::SelectPreviousChar)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::SelectNextWord)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::SelectPreviousWord)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::SelectNextLine)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::SelectPreviousLine)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::SelectStartOfLine)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::SelectEndOfLine)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::SelectStartOfBlock)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::SelectEndOfBlock)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::SelectStartOfDocument)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::SelectEndOfDocument)->isEnabled(), true);
// make it editable before navigating the cursor
page->setContentEditable(true);
// cursor will be before the word "The", this makes sure there is a charet
page->triggerAction(QWebPage::MoveToStartOfDocument);
QVERIFY(page->isSelectionCollapsed());
QCOMPARE(page->selectionStartOffset(), 0);
// here the actions are enabled after contentEditable is true
QCOMPARE(page->action(QWebPage::SelectNextChar)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::SelectPreviousChar)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::SelectNextWord)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::SelectPreviousWord)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::SelectNextLine)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::SelectPreviousLine)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::SelectStartOfLine)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::SelectEndOfLine)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::SelectStartOfBlock)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::SelectEndOfBlock)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::SelectStartOfDocument)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::SelectEndOfDocument)->isEnabled(), true);
delete page;
}
void tst_QWebPage::textEditing()
{
CursorTrackedPage* page = new CursorTrackedPage;
QString content("The quick brown fox" \
"
jumps over the lazy dog
" \
"
May the source be with you!
");
page->mainFrame()->setHtml(content);
// these actions must exist
QVERIFY(page->action(QWebPage::Cut) != 0);
QVERIFY(page->action(QWebPage::Copy) != 0);
QVERIFY(page->action(QWebPage::Paste) != 0);
QVERIFY(page->action(QWebPage::DeleteStartOfWord) != 0);
QVERIFY(page->action(QWebPage::DeleteEndOfWord) != 0);
QVERIFY(page->action(QWebPage::SetTextDirectionDefault) != 0);
QVERIFY(page->action(QWebPage::SetTextDirectionLeftToRight) != 0);
QVERIFY(page->action(QWebPage::SetTextDirectionRightToLeft) != 0);
QVERIFY(page->action(QWebPage::ToggleBold) != 0);
QVERIFY(page->action(QWebPage::ToggleItalic) != 0);
QVERIFY(page->action(QWebPage::ToggleUnderline) != 0);
QVERIFY(page->action(QWebPage::InsertParagraphSeparator) != 0);
QVERIFY(page->action(QWebPage::InsertLineSeparator) != 0);
QVERIFY(page->action(QWebPage::PasteAndMatchStyle) != 0);
QVERIFY(page->action(QWebPage::RemoveFormat) != 0);
QVERIFY(page->action(QWebPage::ToggleStrikethrough) != 0);
QVERIFY(page->action(QWebPage::ToggleSubscript) != 0);
QVERIFY(page->action(QWebPage::ToggleSuperscript) != 0);
QVERIFY(page->action(QWebPage::InsertUnorderedList) != 0);
QVERIFY(page->action(QWebPage::InsertOrderedList) != 0);
QVERIFY(page->action(QWebPage::Indent) != 0);
QVERIFY(page->action(QWebPage::Outdent) != 0);
QVERIFY(page->action(QWebPage::AlignCenter) != 0);
QVERIFY(page->action(QWebPage::AlignJustified) != 0);
QVERIFY(page->action(QWebPage::AlignLeft) != 0);
QVERIFY(page->action(QWebPage::AlignRight) != 0);
// right now they are disabled because contentEditable is false
QCOMPARE(page->action(QWebPage::Cut)->isEnabled(), false);
QCOMPARE(page->action(QWebPage::Paste)->isEnabled(), false);
QCOMPARE(page->action(QWebPage::DeleteStartOfWord)->isEnabled(), false);
QCOMPARE(page->action(QWebPage::DeleteEndOfWord)->isEnabled(), false);
QCOMPARE(page->action(QWebPage::SetTextDirectionDefault)->isEnabled(), false);
QCOMPARE(page->action(QWebPage::SetTextDirectionLeftToRight)->isEnabled(), false);
QCOMPARE(page->action(QWebPage::SetTextDirectionRightToLeft)->isEnabled(), false);
QCOMPARE(page->action(QWebPage::ToggleBold)->isEnabled(), false);
QCOMPARE(page->action(QWebPage::ToggleItalic)->isEnabled(), false);
QCOMPARE(page->action(QWebPage::ToggleUnderline)->isEnabled(), false);
QCOMPARE(page->action(QWebPage::InsertParagraphSeparator)->isEnabled(), false);
QCOMPARE(page->action(QWebPage::InsertLineSeparator)->isEnabled(), false);
QCOMPARE(page->action(QWebPage::PasteAndMatchStyle)->isEnabled(), false);
QCOMPARE(page->action(QWebPage::RemoveFormat)->isEnabled(), false);
QCOMPARE(page->action(QWebPage::ToggleStrikethrough)->isEnabled(), false);
QCOMPARE(page->action(QWebPage::ToggleSubscript)->isEnabled(), false);
QCOMPARE(page->action(QWebPage::ToggleSuperscript)->isEnabled(), false);
QCOMPARE(page->action(QWebPage::InsertUnorderedList)->isEnabled(), false);
QCOMPARE(page->action(QWebPage::InsertOrderedList)->isEnabled(), false);
QCOMPARE(page->action(QWebPage::Indent)->isEnabled(), false);
QCOMPARE(page->action(QWebPage::Outdent)->isEnabled(), false);
QCOMPARE(page->action(QWebPage::AlignCenter)->isEnabled(), false);
QCOMPARE(page->action(QWebPage::AlignJustified)->isEnabled(), false);
QCOMPARE(page->action(QWebPage::AlignLeft)->isEnabled(), false);
QCOMPARE(page->action(QWebPage::AlignRight)->isEnabled(), false);
// Select everything
page->triggerAction(QWebPage::SelectAll);
// make sure it is enabled since there is a selection
QCOMPARE(page->action(QWebPage::Copy)->isEnabled(), true);
// make it editable before navigating the cursor
page->setContentEditable(true);
// clear the selection
page->triggerAction(QWebPage::MoveToStartOfDocument);
QVERIFY(page->isSelectionCollapsed());
QCOMPARE(page->selectionStartOffset(), 0);
// make sure it is disabled since there isn't a selection
QCOMPARE(page->action(QWebPage::Copy)->isEnabled(), false);
// here the actions are enabled after contentEditable is true
QCOMPARE(page->action(QWebPage::Paste)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::DeleteStartOfWord)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::DeleteEndOfWord)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::SetTextDirectionDefault)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::SetTextDirectionLeftToRight)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::SetTextDirectionRightToLeft)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::ToggleBold)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::ToggleItalic)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::ToggleUnderline)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::InsertParagraphSeparator)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::InsertLineSeparator)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::PasteAndMatchStyle)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::ToggleStrikethrough)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::ToggleSubscript)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::ToggleSuperscript)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::InsertUnorderedList)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::InsertOrderedList)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::Indent)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::Outdent)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::AlignCenter)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::AlignJustified)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::AlignLeft)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::AlignRight)->isEnabled(), true);
// make sure these are disabled since there isn't a selection
QCOMPARE(page->action(QWebPage::Cut)->isEnabled(), false);
QCOMPARE(page->action(QWebPage::RemoveFormat)->isEnabled(), false);
// make sure everything is selected
page->triggerAction(QWebPage::SelectAll);
// this is only true if there is an editable selection
QCOMPARE(page->action(QWebPage::Cut)->isEnabled(), true);
QCOMPARE(page->action(QWebPage::RemoveFormat)->isEnabled(), true);
delete page;
}
void tst_QWebPage::requestCache()
{
TestPage page;
QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
page.mainFrame()->setUrl(QString("data:text/html,Click me"));
QTRY_COMPARE(loadSpy.count(), 1);
QTRY_COMPARE(page.navigations.count(), 1);
page.mainFrame()->setUrl(QString("data:text/html,Click me2"));
QTRY_COMPARE(loadSpy.count(), 2);
QTRY_COMPARE(page.navigations.count(), 2);
page.triggerAction(QWebPage::Stop);
QVERIFY(page.history()->canGoBack());
page.triggerAction(QWebPage::Back);
QTRY_COMPARE(loadSpy.count(), 3);
QTRY_COMPARE(page.navigations.count(), 3);
QCOMPARE(page.navigations.at(0).request.attribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferNetwork).toInt(),
(int)QNetworkRequest::PreferNetwork);
QCOMPARE(page.navigations.at(1).request.attribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferNetwork).toInt(),
(int)QNetworkRequest::PreferNetwork);
QCOMPARE(page.navigations.at(2).request.attribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferNetwork).toInt(),
(int)QNetworkRequest::PreferCache);
}
void tst_QWebPage::backActionUpdate()
{
QWebView view;
QWebPage *page = view.page();
QAction *action = page->action(QWebPage::Back);
QVERIFY(!action->isEnabled());
QSignalSpy loadSpy(page, SIGNAL(loadFinished(bool)));
QUrl url = QUrl("qrc:///frametest/index.html");
page->mainFrame()->load(url);
QTRY_COMPARE(loadSpy.count(), 1);
QVERIFY(!action->isEnabled());
QTest::mouseClick(&view, Qt::LeftButton, 0, QPoint(10, 10));
QTRY_COMPARE(loadSpy.count(), 2);
QVERIFY(action->isEnabled());
}
void frameAtHelper(QWebPage* webPage, QWebFrame* webFrame, QPoint framePosition)
{
if (!webFrame)
return;
framePosition += QPoint(webFrame->pos());
QList children = webFrame->childFrames();
for (int i = 0; i < children.size(); ++i) {
if (children.at(i)->childFrames().size() > 0)
frameAtHelper(webPage, children.at(i), framePosition);
QRect frameRect(children.at(i)->pos() + framePosition, children.at(i)->geometry().size());
QVERIFY(children.at(i) == webPage->frameAt(frameRect.topLeft()));
}
}
void tst_QWebPage::frameAt()
{
QWebView webView;
QWebPage* webPage = webView.page();
QSignalSpy loadSpy(webPage, SIGNAL(loadFinished(bool)));
QUrl url = QUrl("qrc:///frametest/iframe.html");
webPage->mainFrame()->load(url);
QTRY_COMPARE(loadSpy.count(), 1);
frameAtHelper(webPage, webPage->mainFrame(), webPage->mainFrame()->pos());
}
void tst_QWebPage::inputMethods()
{
m_view->page()->mainFrame()->setHtml("" \
" " \
"" \
"");
m_view->page()->mainFrame()->setFocus();
QList inputs = m_view->page()->mainFrame()->documentElement().findAll("input");
QMouseEvent evpres(QEvent::MouseButtonPress, inputs.at(0).geometry().center(), Qt::LeftButton, Qt::NoButton, Qt::NoModifier);
m_view->page()->event(&evpres);
QMouseEvent evrel(QEvent::MouseButtonRelease, inputs.at(0).geometry().center(), Qt::LeftButton, Qt::NoButton, Qt::NoModifier);
m_view->page()->event(&evrel);
//ImMicroFocus
QVariant variant = m_view->page()->inputMethodQuery(Qt::ImMicroFocus);
QRect focusRect = variant.toRect();
QVERIFY(inputs.at(0).geometry().contains(variant.toRect().topLeft()));
//ImFont
variant = m_view->page()->inputMethodQuery(Qt::ImFont);
QFont font = variant.value();
QCOMPARE(QString("-webkit-serif"), font.family());
QList inputAttributes;
//Insert text.
{
QInputMethodEvent eventText("QtWebKit", inputAttributes);
QSignalSpy signalSpy(m_view->page(), SIGNAL(microFocusChanged()));
m_view->page()->event(&eventText);
QCOMPARE(signalSpy.count(), 0);
}
{
QInputMethodEvent eventText("", inputAttributes);
eventText.setCommitString(QString("QtWebKit"), 0, 0);
m_view->page()->event(&eventText);
}
#if QT_VERSION >= 0x040600
//ImMaximumTextLength
variant = m_view->page()->inputMethodQuery(Qt::ImMaximumTextLength);
QCOMPARE(20, variant.toInt());
//Set selection
inputAttributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, 3, 2, QVariant());
QInputMethodEvent eventSelection("",inputAttributes);
m_view->page()->event(&eventSelection);
//ImAnchorPosition
variant = m_view->page()->inputMethodQuery(Qt::ImAnchorPosition);
int anchorPosition = variant.toInt();
QCOMPARE(anchorPosition, 3);
//ImCursorPosition
variant = m_view->page()->inputMethodQuery(Qt::ImCursorPosition);
int cursorPosition = variant.toInt();
QCOMPARE(cursorPosition, 5);
//ImCurrentSelection
variant = m_view->page()->inputMethodQuery(Qt::ImCurrentSelection);
QString selectionValue = variant.value();
QCOMPARE(selectionValue, QString("eb"));
#endif
//ImSurroundingText
variant = m_view->page()->inputMethodQuery(Qt::ImSurroundingText);
QString value = variant.value();
QCOMPARE(value, QString("QtWebKit"));
#if QT_VERSION >= 0x040600
{
QList attributes;
// Clear the selection, so the next test does not clear any contents.
QInputMethodEvent::Attribute newSelection(QInputMethodEvent::Selection, 0, 0, QVariant());
attributes.append(newSelection);
QInputMethodEvent event("composition", attributes);
m_view->page()->event(&event);
}
// A ongoing composition should not change the surrounding text before it is committed.
variant = m_view->page()->inputMethodQuery(Qt::ImSurroundingText);
value = variant.value();
QCOMPARE(value, QString("QtWebKit"));
#endif
//ImhHiddenText
QMouseEvent evpresPassword(QEvent::MouseButtonPress, inputs.at(1).geometry().center(), Qt::LeftButton, Qt::NoButton, Qt::NoModifier);
m_view->page()->event(&evpresPassword);
QMouseEvent evrelPassword(QEvent::MouseButtonRelease, inputs.at(1).geometry().center(), Qt::LeftButton, Qt::NoButton, Qt::NoModifier);
m_view->page()->event(&evrelPassword);
QVERIFY(m_view->testAttribute(Qt::WA_InputMethodEnabled));
#if QT_VERSION >= 0x040600
QVERIFY(m_view->inputMethodHints() & Qt::ImhHiddenText);
m_view->page()->event(&evpres);
m_view->page()->event(&evrel);
QVERIFY(!(m_view->inputMethodHints() & Qt::ImhHiddenText));
#endif
}
// import a little DRT helper function to trigger the garbage collector
void QWEBKIT_EXPORT qt_drt_garbageCollector_collect();
void tst_QWebPage::protectBindingsRuntimeObjectsFromCollector()
{
QSignalSpy loadSpy(m_view, SIGNAL(loadFinished(bool)));
PluginPage* newPage = new PluginPage(m_view);
m_view->setPage(newPage);
m_view->settings()->setAttribute(QWebSettings::PluginsEnabled, true);
m_view->setHtml(QString(""));
QTRY_COMPARE(loadSpy.count(), 1);
newPage->mainFrame()->evaluateJavaScript("function testme(text) { var lineedit = document.getElementById('mylineedit'); lineedit.setText(text); lineedit.selectAll(); }");
newPage->mainFrame()->evaluateJavaScript("testme('foo')");
qt_drt_garbageCollector_collect();
// don't crash!
newPage->mainFrame()->evaluateJavaScript("testme('bar')");
}
void tst_QWebPage::localURLSchemes()
{
int i = QWebSecurityOrigin::localSchemes().size();
QWebSecurityOrigin::removeLocalScheme("file");
QTRY_COMPARE(QWebSecurityOrigin::localSchemes().size(), i);
QWebSecurityOrigin::addLocalScheme("file");
QTRY_COMPARE(QWebSecurityOrigin::localSchemes().size(), i);
QString myscheme = "myscheme";
QWebSecurityOrigin::addLocalScheme(myscheme);
QTRY_COMPARE(QWebSecurityOrigin::localSchemes().size(), i + 1);
QVERIFY(QWebSecurityOrigin::localSchemes().contains(myscheme));
QWebSecurityOrigin::removeLocalScheme(myscheme);
QTRY_COMPARE(QWebSecurityOrigin::localSchemes().size(), i);
QWebSecurityOrigin::removeLocalScheme(myscheme);
QTRY_COMPARE(QWebSecurityOrigin::localSchemes().size(), i);
}
static inline bool testFlag(QWebPage& webPage, QWebSettings::WebAttribute settingAttribute, const QString& jsObjectName, bool settingValue)
{
webPage.settings()->setAttribute(settingAttribute, settingValue);
return webPage.mainFrame()->evaluateJavaScript(QString("(window.%1 != undefined)").arg(jsObjectName)).toBool();
}
void tst_QWebPage::testOptionalJSObjects()
{
// Once a feature is enabled and the JS object is accessed turning off the setting will not turn off
// the visibility of the JS object any more. For this reason this test uses two QWebPage instances.
// Part of the test is to make sure that the QWebPage instances do not interfere with each other so turning on
// a feature for one instance will not turn it on for another.
QWebPage webPage1;
QWebPage webPage2;
webPage1.currentFrame()->setHtml(QString("test"), QUrl());
webPage2.currentFrame()->setHtml(QString("test"), QUrl());
QCOMPARE(testFlag(webPage1, QWebSettings::OfflineWebApplicationCacheEnabled, "applicationCache", false), false);
QCOMPARE(testFlag(webPage2, QWebSettings::OfflineWebApplicationCacheEnabled, "applicationCache", true), true);
QCOMPARE(testFlag(webPage1, QWebSettings::OfflineWebApplicationCacheEnabled, "applicationCache", false), false);
QCOMPARE(testFlag(webPage2, QWebSettings::OfflineWebApplicationCacheEnabled, "applicationCache", false), true);
QCOMPARE(testFlag(webPage1, QWebSettings::LocalStorageEnabled, "localStorage", false), false);
QCOMPARE(testFlag(webPage2, QWebSettings::LocalStorageEnabled, "localStorage", true), true);
QCOMPARE(testFlag(webPage1, QWebSettings::LocalStorageEnabled, "localStorage", false), false);
QCOMPARE(testFlag(webPage2, QWebSettings::LocalStorageEnabled, "localStorage", false), true);
QCOMPARE(testFlag(webPage1, QWebSettings::SessionStorageEnabled, "sessionStorage", false), false);
QCOMPARE(testFlag(webPage2, QWebSettings::SessionStorageEnabled, "sessionStorage", true), true);
QCOMPARE(testFlag(webPage1, QWebSettings::SessionStorageEnabled, "sessionStorage", false), false);
QCOMPARE(testFlag(webPage2, QWebSettings::SessionStorageEnabled, "sessionStorage", false), true);
}
void tst_QWebPage::testEnablePersistentStorage()
{
QWebPage webPage;
// By default all persistent options should be disabled
QCOMPARE(webPage.settings()->testAttribute(QWebSettings::LocalStorageEnabled), false);
QCOMPARE(webPage.settings()->testAttribute(QWebSettings::OfflineStorageDatabaseEnabled), false);
QCOMPARE(webPage.settings()->testAttribute(QWebSettings::OfflineWebApplicationCacheEnabled), false);
QVERIFY(webPage.settings()->iconDatabasePath().isEmpty());
QWebSettings::enablePersistentStorage();
// Give it some time to initialize - icon database needs it
QTest::qWait(1000);
QCOMPARE(webPage.settings()->testAttribute(QWebSettings::LocalStorageEnabled), true);
QCOMPARE(webPage.settings()->testAttribute(QWebSettings::OfflineStorageDatabaseEnabled), true);
QCOMPARE(webPage.settings()->testAttribute(QWebSettings::OfflineWebApplicationCacheEnabled), true);
QVERIFY(!webPage.settings()->offlineStoragePath().isEmpty());
QVERIFY(!webPage.settings()->offlineWebApplicationCachePath().isEmpty());
QVERIFY(!webPage.settings()->iconDatabasePath().isEmpty());
}
void tst_QWebPage::crashTests_LazyInitializationOfMainFrame()
{
{
QWebPage webPage;
}
{
QWebPage webPage;
webPage.selectedText();
}
{
QWebPage webPage;
webPage.triggerAction(QWebPage::Back, true);
}
{
QWebPage webPage;
QPoint pos(10,10);
webPage.updatePositionDependentActions(pos);
}
}
QTEST_MAIN(tst_QWebPage)
#include "tst_qwebpage.moc"