diff --git a/autotests/webpage/tst_webpage.cpp b/autotests/webpage/tst_webpage.cpp index b53aae4e..bd4726f4 100644 --- a/autotests/webpage/tst_webpage.cpp +++ b/autotests/webpage/tst_webpage.cpp @@ -51,6 +51,8 @@ private slots: void createWindow(); void handleUnsupportedContent(); void linkedResources(); + void javaScriptObjects_data(); + void javaScriptObjects(); }; // Subclass that exposes the protected functions. @@ -337,6 +339,34 @@ void tst_WebPage::linkedResources() QCOMPARE(resources.at(3).href, QUrl("http://external.foo/search.xml")); } +void tst_WebPage::javaScriptObjects_data() +{ + QTest::addColumn("url"); + QTest::addColumn("windowExternal"); + QTest::addColumn("windowArora"); + + QTest::newRow("qrc:/notfound.html") << QUrl("qrc:/notfound.html") << true << false; + QTest::newRow("qrc:/startpage.html") << QUrl("qrc:/startpage.html") << true << true; +} + +void tst_WebPage::javaScriptObjects() +{ + QFETCH(QUrl, url); + QFETCH(bool, windowExternal); + QFETCH(bool, windowArora); + + SubWebPage page; + QSignalSpy spy(&page, SIGNAL(loadFinished(bool))); + page.mainFrame()->load(url); + QTRY_COMPARE(spy.count(), 1); + + QVariant windowExternalVariant = page.mainFrame()->evaluateJavaScript(QLatin1String("window.external")); + QVariant windowAroraVariant = page.mainFrame()->evaluateJavaScript(QLatin1String("window.arora")); + + QCOMPARE(windowExternal, !windowExternalVariant.isNull()); + QCOMPARE(windowArora, !windowAroraVariant.isNull()); +} + QTEST_MAIN(tst_WebPage) #include "tst_webpage.moc" diff --git a/src/browsermainwindow.cpp b/src/browsermainwindow.cpp index a2bb2a25..b7f45fdf 100644 --- a/src/browsermainwindow.cpp +++ b/src/browsermainwindow.cpp @@ -1328,7 +1328,7 @@ void BrowserMainWindow::goHome() { QSettings settings; settings.beginGroup(QLatin1String("MainWindow")); - QString home = settings.value(QLatin1String("home"), QLatin1String("http://www.arora-browser.org")).toString(); + QString home = settings.value(QLatin1String("home"), QLatin1String("about:home")).toString(); tabWidget()->loadString(home); } diff --git a/src/data/data.qrc b/src/data/data.qrc index 636eaf23..f4217216 100644 --- a/src/data/data.qrc +++ b/src/data/data.qrc @@ -1,6 +1,7 @@ 128x128/arora.png + arora.svg defaultbookmarks.xbel fetchLinks.js ../../AUTHORS diff --git a/src/htmls/htmls.qrc b/src/htmls/htmls.qrc index 045186e1..da555367 100644 --- a/src/htmls/htmls.qrc +++ b/src/htmls/htmls.qrc @@ -1,6 +1,8 @@ - notfound.html dirlist.html + notfound.html + startpage.html + startpage.css diff --git a/src/htmls/startpage.css b/src/htmls/startpage.css new file mode 100644 index 00000000..dc729ed5 --- /dev/null +++ b/src/htmls/startpage.css @@ -0,0 +1,74 @@ +* { + margin: 0; + padding: 0; + font-family: "DejaVu Sans"; +} + +body { + background: -webkit-gradient(linear, left top, left bottom, from(#ccc), to(#fff), color-stop(0.5, #fff)); + background-repeat: repeat-x; + margin-top: 200px; +} + +#header, #search, #footer { + width: 500px; + margin: 10px auto; +} + +#header, #search { + -webkit-border-radius: 0.8em; + padding: 25px; +} + +#header { + background: -webkit-gradient(linear, left top, left bottom, from(#228), to(#668), color-stop(0.9, #66a)); + height: 20px; +} + +#header h1 { + display: inline; + font-size: 1.7em; + color: #fff; + font-weight: bold; +} + +#header img { + display: inline; + float: right; + height: 150px; + margin-top: -80px; +} + +#search { + background: -webkit-gradient(linear, left top, right top, from(#cdf), to(#cdf), color-stop(0.5, #eff)); + height: 50px; + color: #000; + text-align: center; + padding-top: 40px !important; +} + +#search fieldset { + border: 0; +} + +#search input[type=text] { + width: 65%; +} + +#search input[type=submit] { + width: 25%; +} + +#footer { + text-align: center; + color: #999; +} + +#footer a { + color: #555; + text-decoration: none; +} + +#footer a:hover { + text-decoration: underline; +} \ No newline at end of file diff --git a/src/htmls/startpage.html b/src/htmls/startpage.html new file mode 100644 index 00000000..5373759c --- /dev/null +++ b/src/htmls/startpage.html @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/opensearch/opensearchengine.h b/src/opensearch/opensearchengine.h index 9d881992..788eeb08 100644 --- a/src/opensearch/opensearchengine.h +++ b/src/opensearch/opensearchengine.h @@ -34,6 +34,8 @@ class OpenSearchEngine : public QObject { Q_OBJECT + Q_PROPERTY(QString name READ name) + signals: void imageChanged(); void suggestions(const QStringList &suggestions); diff --git a/src/settings.cpp b/src/settings.cpp index 986dad82..abfd4ee3 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -135,7 +135,7 @@ void SettingsDialog::loadFromSettings() { QSettings settings; settings.beginGroup(QLatin1String("MainWindow")); - QString defaultHome = QLatin1String("http://www.arora-browser.org"); + QString defaultHome = QLatin1String("about:home"); homeLineEdit->setText(settings.value(QLatin1String("home"), defaultHome).toString()); startupBehavior->setCurrentIndex(settings.value(QLatin1String("startupBehavior"), 0).toInt()); settings.endGroup(); diff --git a/src/tabwidget.cpp b/src/tabwidget.cpp index ce708021..20ce7b0c 100644 --- a/src/tabwidget.cpp +++ b/src/tabwidget.cpp @@ -928,6 +928,10 @@ QUrl TabWidget::guessUrlFromString(const QString &string) { QUrl url = WebView::guessUrlFromString(string); + if (url.scheme() == QLatin1String("about") + && url.path() == QLatin1String("home")) + url = QUrl(QLatin1String("qrc:/startpage.html")); + // QUrl::isValid() is too much tolerant. // We actually want to check if the url conforms to the RFC, which QUrl::isValid() doesn't state. if (!url.scheme().isEmpty() && (!url.host().isEmpty() || !url.path().isEmpty())) diff --git a/src/webpage.cpp b/src/webpage.cpp index 16a068e0..6df4c127 100644 --- a/src/webpage.cpp +++ b/src/webpage.cpp @@ -24,6 +24,7 @@ #include "downloadmanager.h" #include "historymanager.h" #include "networkaccessmanager.h" +#include "opensearchengine.h" #include "opensearchmanager.h" #include "tabwidget.h" #include "toolbarsearch.h" @@ -54,10 +55,42 @@ void JavaScriptExternalObject::AddSearchProvider(const QString &url) ToolbarSearch::openSearchManager()->addEngine(QUrl(url)); } +Q_DECLARE_METATYPE(OpenSearchEngine*) +JavaScriptAroraObject::JavaScriptAroraObject(QObject *parent) + : QObject(parent) +{ + static const char *translations[] = { + QT_TR_NOOP("Welcome to Arora!"), + QT_TR_NOOP("Arora Start"), + QT_TR_NOOP("Search!"), + QT_TR_NOOP("Search results provided by"), + QT_TR_NOOP("About Arora") + }; + Q_UNUSED(translations); + + qRegisterMetaType("OpenSearchEngine*"); +} + +QString JavaScriptAroraObject::translate(const QString &string) +{ + return trUtf8(string.toUtf8().constData()); +} + +QObject *JavaScriptAroraObject::currentEngine() const +{ + return ToolbarSearch::openSearchManager()->currentEngine(); +} + +QString JavaScriptAroraObject::searchUrl(const QString &string) const +{ + return QString::fromUtf8(ToolbarSearch::openSearchManager()->currentEngine()->searchUrl(string).toEncoded()); +} + WebPage::WebPage(QObject *parent) : QWebPage(parent) , m_openTargetBlankLinksIn(TabWidget::NewWindow) - , m_javaScriptBinding(0) + , m_javaScriptExternalObject(0) + , m_javaScriptAroraObject(0) { setPluginFactory(webPluginFactory()); setNetworkAccessManager(BrowserApplication::networkAccessManager()); @@ -139,17 +172,25 @@ QList WebPage::linkedResources(const QString &relation) void WebPage::addExternalBinding(QWebFrame *frame) { - if (!m_javaScriptBinding) - m_javaScriptBinding = new JavaScriptExternalObject(this); + if (!m_javaScriptExternalObject) + m_javaScriptExternalObject = new JavaScriptExternalObject(this); if (frame == 0) { // called from QWebFrame::javaScriptWindowObjectCleared frame = qobject_cast(sender()); + + if (frame->url().scheme() == QLatin1String("qrc") + && frame->url().path() == QLatin1String("/startpage.html")) { + + if (!m_javaScriptAroraObject) + m_javaScriptAroraObject = new JavaScriptAroraObject(this); + + frame->addToJavaScriptWindowObject(QLatin1String("arora"), m_javaScriptAroraObject); + } } else { // called from QWebPage::frameCreated connect(frame, SIGNAL(javaScriptWindowObjectCleared()), this, SLOT(addExternalBinding())); } - frame->addToJavaScriptWindowObject(QLatin1String("external"), - m_javaScriptBinding); + frame->addToJavaScriptWindowObject(QLatin1String("external"), m_javaScriptExternalObject); } bool WebPage::acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, diff --git a/src/webpage.h b/src/webpage.h index 1a6d9e05..db2aaaf1 100644 --- a/src/webpage.h +++ b/src/webpage.h @@ -34,6 +34,7 @@ class WebPageLinkedResource QString title; }; +class OpenSearchEngine; class QNetworkReply; class WebPluginFactory; // See https://developer.mozilla.org/en/adding_search_engines_from_web_pages @@ -48,6 +49,21 @@ public slots: void AddSearchProvider(const QString &url); }; +class JavaScriptAroraObject : public QObject +{ + Q_OBJECT + + Q_PROPERTY(QObject* currentEngine READ currentEngine) + +public: + JavaScriptAroraObject(QObject *parent = 0); + +public slots: + QString translate(const QString &string); + QObject *currentEngine() const; + QString searchUrl(const QString &string) const; +}; + class WebPage : public QWebPage { Q_OBJECT @@ -76,7 +92,8 @@ protected slots: static WebPluginFactory *s_webPluginFactory; TabWidget::OpenUrlIn m_openTargetBlankLinksIn; QUrl m_requestedUrl; - JavaScriptExternalObject *m_javaScriptBinding; + JavaScriptExternalObject *m_javaScriptExternalObject; + JavaScriptAroraObject *m_javaScriptAroraObject; }; #endif // WEBPAGE_H