[Qt][WK2] Pages / resources cannot be loaded from qrc files.
authormichael.bruning@digia.com <michael.bruning@digia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 24 Jan 2013 12:25:19 +0000 (12:25 +0000)
committermichael.bruning@digia.com <michael.bruning@digia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 24 Jan 2013 12:25:19 +0000 (12:25 +0000)
https://bugs.webkit.org/show_bug.cgi?id=107031

Reviewed by Jocelyn Turcotte.

Enables WebKit2 Qt applications to load files from the bundled
qrc files. This is achieved by adding a url scheme handler for
the "qrc" scheme using the application scheme handler and ignoring
all handlers for the qrc application scheme that the application might
set.

* UIProcess/API/qt/qquickurlschemedelegate.cpp:
(QQuickQrcSchemeDelegate::QQuickQrcSchemeDelegate):
(QQuickQrcSchemeDelegate::readResourceAndSend):
* UIProcess/API/qt/qquickurlschemedelegate_p.h:
(QQuickQrcSchemeDelegate):
* UIProcess/API/qt/qquickwebview.cpp:
(QQuickWebViewPrivate::initialize):
(QQuickWebViewExperimental::schemeDelegates_Append):
(QQuickWebViewExperimental::invokeApplicationSchemeHandler):
* UIProcess/API/qt/tests/qmltests/WebView/tst_applicationScheme.qml:
* UIProcess/API/qt/tests/qmltests/common/qrctest.html: Added.
* UIProcess/API/qt/tests/qmltests/resources.qrc:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@140676 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebKit2/ChangeLog
Source/WebKit2/UIProcess/API/qt/qquickurlschemedelegate.cpp
Source/WebKit2/UIProcess/API/qt/qquickurlschemedelegate_p.h
Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp
Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_applicationScheme.qml
Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/qrctest.html [new file with mode: 0644]
Source/WebKit2/UIProcess/API/qt/tests/qmltests/resources.qrc

index 97d23dc..58b0851 100644 (file)
@@ -1,3 +1,29 @@
+2013-01-24  Michael Brüning  <michael.bruning@digia.com>
+
+        [Qt][WK2] Pages / resources cannot be loaded from qrc files.
+        https://bugs.webkit.org/show_bug.cgi?id=107031
+
+        Reviewed by Jocelyn Turcotte.
+
+        Enables WebKit2 Qt applications to load files from the bundled
+        qrc files. This is achieved by adding a url scheme handler for
+        the "qrc" scheme using the application scheme handler and ignoring
+        all handlers for the qrc application scheme that the application might
+        set.
+
+        * UIProcess/API/qt/qquickurlschemedelegate.cpp:
+        (QQuickQrcSchemeDelegate::QQuickQrcSchemeDelegate):
+        (QQuickQrcSchemeDelegate::readResourceAndSend):
+        * UIProcess/API/qt/qquickurlschemedelegate_p.h:
+        (QQuickQrcSchemeDelegate):
+        * UIProcess/API/qt/qquickwebview.cpp:
+        (QQuickWebViewPrivate::initialize):
+        (QQuickWebViewExperimental::schemeDelegates_Append):
+        (QQuickWebViewExperimental::invokeApplicationSchemeHandler):
+        * UIProcess/API/qt/tests/qmltests/WebView/tst_applicationScheme.qml:
+        * UIProcess/API/qt/tests/qmltests/common/qrctest.html: Added.
+        * UIProcess/API/qt/tests/qmltests/resources.qrc:
+
 2013-01-24  Krzysztof Czech  <k.czech@samsung.com>
 
         [EFL][WK2] Expose accessibility hierarchy in WebKit2-EFL.
index e5d6304..a10c89d 100644 (file)
 #include "qquicknetworkreply_p.h"
 #include "qquicknetworkrequest_p.h"
 
+#include <QtCore/QFile>
+#include <QtCore/QFileInfo>
+#include <QtCore/QMimeDatabase>
+#include <QtCore/QUrl>
+
 QQuickUrlSchemeDelegate::QQuickUrlSchemeDelegate(QObject* parent)
     : QObject(parent)
     , m_request(new QQuickNetworkRequest(this))
@@ -51,4 +56,27 @@ QQuickNetworkReply* QQuickUrlSchemeDelegate::reply() const
     return m_reply;
 }
 
+QQuickQrcSchemeDelegate::QQuickQrcSchemeDelegate(const QUrl& url)
+    : QQuickUrlSchemeDelegate()
+    , m_fileName(QLatin1Char(':') + url.path())
+{
+}
+
+void QQuickQrcSchemeDelegate::readResourceAndSend()
+{
+    QFile file(m_fileName);
+    QFileInfo fileInfo(file);
+    if (fileInfo.isDir() || !file.open(QIODevice::ReadOnly | QIODevice::Unbuffered))
+        return;
+
+    QByteArray fileData(file.readAll());
+    QMimeDatabase mimeDb;
+    QMimeType mimeType = mimeDb.mimeTypeForFileNameAndData(m_fileName, fileData);
+    file.close();
+
+    reply()->setData(fileData);
+    reply()->setContentType(mimeType.name());
+    reply()->send();
+}
+
 #include "moc_qquickurlschemedelegate_p.cpp"
index 6ee6027..087cb29 100644 (file)
@@ -27,6 +27,7 @@
 
 class QQuickNetworkRequest;
 class QQuickNetworkReply;
+class QUrl;
 
 class QWEBKIT_EXPORT QQuickUrlSchemeDelegate : public QObject {
     Q_OBJECT
@@ -53,6 +54,16 @@ private:
 
 QML_DECLARE_TYPE(QQuickUrlSchemeDelegate)
 
+class QQuickQrcSchemeDelegate : public QQuickUrlSchemeDelegate {
+    Q_OBJECT
+public:
+    QQuickQrcSchemeDelegate(const QUrl& url);
+    void readResourceAndSend();
+
+private:
+    QString m_fileName;
+};
+
 #endif // qquickurlschemedelegate_p_h
 
 
index 2053079..9e9fe95 100644 (file)
@@ -328,6 +328,7 @@ void QQuickWebViewPrivate::initialize(WKContextRef contextRef, WKPageGroupRef pa
 
     pageClient.initialize(q_ptr, pageViewPrivate->eventHandler.data(), &undoController);
     webPageProxy->initializeWebPage();
+    webPageProxy->registerApplicationScheme(ASCIILiteral("qrc"));
 
     q_ptr->setAcceptedMouseButtons(Qt::MouseButtonMask);
     q_ptr->setAcceptHoverEvents(true);
@@ -1312,6 +1313,12 @@ QQuickUrlSchemeDelegate* QQuickWebViewExperimental::schemeDelegates_At(QQmlListP
 
 void QQuickWebViewExperimental::schemeDelegates_Append(QQmlListProperty<QQuickUrlSchemeDelegate>* property, QQuickUrlSchemeDelegate *scheme)
 {
+    if (!scheme->scheme().compare(QLatin1String("qrc"), Qt::CaseInsensitive)) {
+        qWarning("WARNING: The qrc scheme is reserved to be handled internally. The handler will be ignored.");
+        delete scheme;
+        return;
+    }
+
     QObject* schemeParent = property->object;
     scheme->setParent(schemeParent);
     QQuickWebViewExperimental* webViewExperimental = qobject_cast<QQuickWebViewExperimental*>(property->object->parent());
@@ -1349,6 +1356,15 @@ QQmlListProperty<QQuickUrlSchemeDelegate> QQuickWebViewExperimental::schemeDeleg
 void QQuickWebViewExperimental::invokeApplicationSchemeHandler(PassRefPtr<QtRefCountedNetworkRequestData> request)
 {
     RefPtr<QtRefCountedNetworkRequestData> req = request;
+    if (req->data().m_scheme.startsWith("qrc", false)) {
+        QQuickQrcSchemeDelegate qrcDelegate(QUrl(QString(req->data().m_urlString)));
+        qrcDelegate.request()->setNetworkRequestData(req);
+        qrcDelegate.reply()->setNetworkRequestData(req);
+        qrcDelegate.reply()->setWebViewExperimental(this);
+        qrcDelegate.readResourceAndSend();
+        return;
+    }
+
     const QObjectList children = schemeParent->children();
     for (int index = 0; index < children.count(); index++) {
         QQuickUrlSchemeDelegate* delegate = qobject_cast<QQuickUrlSchemeDelegate*>(children.at(index));
index 4fe0812..e561e1a 100644 (file)
@@ -113,5 +113,13 @@ TestWebView {
             verify(webView.waitForLoadSucceeded())
             compare(webView.title, "title with copyright ©")
         }
+
+        function test_qrcScheme() {
+            var testUrl = "qrc:///common/qrctest.html"
+            webView.url = testUrl
+            verify(webView.waitForLoadSucceeded())
+            compare(webView.title, "Loaded from qrc.")
+
+        }
     }
 }
diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/qrctest.html b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/qrctest.html
new file mode 100644 (file)
index 0000000..98f25fb
--- /dev/null
@@ -0,0 +1,6 @@
+<html>
+<head><title>Loaded from qrc.</title></head>
+<body>
+Hello. I was loaded from a qrc file. Amazing.
+</body>
+</html>
index 1696aaa..f251865 100644 (file)
@@ -1,5 +1,6 @@
 <RCC>
     <qresource prefix="/">
         <file>common/change-document-title.js</file>
+        <file>common/qrctest.html</file>
     </qresource>
 </RCC>