Permalink
Browse files

Add a simple start page with a search box pointing at the active

search engine. It has been created by Fernando Lemos and has some
modifications of mine:
1. It now uses engines from the user's collection.
2. It is translatable now.
3. It uses our SVG icon so that it is fully resizable.

Changes behind the scenes:
- It uses the window.arora interface that we will expose to the
  JavaScript scope for our custom pages. One of the methods is
  translate(), which is a wrapper for tr() function.
  Drawback: translatable strings need to be predeclared using the
  QT_TR_NOOP macro.
- Another object that is exposed is the current engine object. It is
  available under the window.arora.currentEngine interface. All
  properties that are declared using the Q_PROPERTY macro will be
  available as JS properties.
  • Loading branch information...
Jakub Wieczorek
Jakub Wieczorek committed Jul 4, 2009
1 parent 541eabc commit 80189ce5aab34a8902a9b3c99184f2e6a6f35b69
@@ -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<QUrl>("url");
+ QTest::addColumn<bool>("windowExternal");
+ QTest::addColumn<bool>("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"
@@ -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);
}
View
@@ -1,6 +1,7 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file>128x128/arora.png</file>
+ <file>arora.svg</file>
<file>defaultbookmarks.xbel</file>
<file>fetchLinks.js</file>
<file>../../AUTHORS</file>
View
@@ -1,6 +1,8 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
- <file>notfound.html</file>
<file>dirlist.html</file>
+ <file>notfound.html</file>
+ <file>startpage.html</file>
+ <file>startpage.css</file>
</qresource>
</RCC>
View
@@ -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;
+}
View
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+<head>
+ <title></title>
+ <link rel="stylesheet" href="qrc:/startpage.css" type="text/css" />
+ <script type="text/javascript">
+ function update()
+ {
+ var searchEngine = window.arora.currentEngine;
+
+ document.title = window.arora.translate('Welcome to Arora!');
+ document.getElementById('headerTitle').innerHTML = window.arora.translate('Arora Start');
+ document.getElementById('searchButton').value = window.arora.translate('Search!');
+ document.getElementById('footer').innerHTML = window.arora.translate('Search results provided by') + ' '
+ + searchEngine.name + ' | ' + '<a href="http://arora-browser.org/">'
+ + window.arora.translate('About Arora') + '</a>';
+ document.getElementById('lineEdit').innerHTML = searchEngine.name;
+ }
+
+ function formSubmitted()
+ {
+ var string = lineEdit.value;
+
+ if (string.length == 0)
+ return;
+
+ var url = window.arora.searchUrl(string);
+ window.location.href = url;
+ }
+ </script>
+</head>
+<body onload="document.forms[0].lineEdit.select(); update();">
+ <div id="header">
+ <h1 id="headerTitle"></h1>
+ <img src="qrc:/arora.svg" />
+ </div>
+ <div id="search">
+ <form action="javascript:formSubmitted();">
+ <fieldset>
+ <input id="lineEdit" name="lineEdit" type="text" />
+ <input id="searchButton" type="submit" />
+ </fieldset>
+ </form>
+ </div>
+ <div id="footer"></div>
+</body>
+</html>
@@ -34,6 +34,8 @@ class OpenSearchEngine : public QObject
{
Q_OBJECT
+ Q_PROPERTY(QString name READ name)
+
signals:
void imageChanged();
void suggestions(const QStringList &suggestions);
View
@@ -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();
View
@@ -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()))
View
@@ -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*>("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<WebPageLinkedResource> 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<QWebFrame*>(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,
View
@@ -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

0 comments on commit 80189ce

Please sign in to comment.