From 09c35ed49bbbdc5b283f038e54db0fb3f53401bc Mon Sep 17 00:00:00 2001 From: arkpar Date: Tue, 20 Jan 2015 10:50:53 +0100 Subject: [PATCH 1/8] started web preview --- mix/qml/MainContent.qml | 18 +++- mix/qml/ProjectModel.qml | 10 +- mix/qml/StateList.qml | 6 +- mix/qml/WebPreview.qml | 211 ++++++++++++++++++++++++++----------- mix/qml/js/ProjectModel.js | 42 +++++--- 5 files changed, 199 insertions(+), 88 deletions(-) diff --git a/mix/qml/MainContent.qml b/mix/qml/MainContent.qml index 2b0b50ce5..42a780288 100644 --- a/mix/qml/MainContent.qml +++ b/mix/qml/MainContent.qml @@ -96,11 +96,19 @@ Rectangle { id: contentView width: parent.width - projectList.width height: parent.height - CodeEditorView { - height: parent.height - anchors.top: parent.top - width: parent.width - } + SplitView { + anchors.fill: parent + orientation: Qt.Vertical + CodeEditorView { + height: parent.height * 0.6 + anchors.top: parent.top + width: parent.width + } + WebPreview { + height: parent.height * 0.4 + width: parent.width + } + } } Rectangle { diff --git a/mix/qml/ProjectModel.qml b/mix/qml/ProjectModel.qml index 5337e2780..d1942a671 100644 --- a/mix/qml/ProjectModel.qml +++ b/mix/qml/ProjectModel.qml @@ -13,18 +13,21 @@ Item { id: projectModel signal projectClosed - signal projectLoaded + signal projectLoaded(var projectData) signal documentOpened(var document) signal documentRemoved(var documentId) signal documentUpdated(var documentId) //renamed + signal documentAdded(var documentId) signal projectSaving(var projectData) + signal projectSaved() + signal documentSaved(var documentId) - property bool isEmpty: (projectData === null) + property bool isEmpty: (projectPath === "") readonly property string projectFileName: ".mix" property bool haveUnsavedChanges: false property string projectPath: "" - property var projectData: null + property string projectTitle: "" property var listModel: projectListModel //interface @@ -41,6 +44,7 @@ Item { function openDocument(documentId) { ProjectModelCode.openDocument(documentId); } function renameDocument(documentId, newName) { ProjectModelCode.renameDocument(documentId, newName); } function removeDocument(documentId) { ProjectModelCode.removeDocument(documentId); } + function getDocument(documentId) { return ProjectModelCode.getDocument(documentId); } Connections { target: appContext diff --git a/mix/qml/StateList.qml b/mix/qml/StateList.qml index 519e533d5..4a53d46ef 100644 --- a/mix/qml/StateList.qml +++ b/mix/qml/StateList.qml @@ -21,9 +21,9 @@ Rectangle { stateListModel.clear(); } onProjectLoaded: { - if (!target.projectData.states) - target.projectData.states = []; - var items = target.projectData.states; + if (!projectData.states) + projectData.states = []; + var items = projectData.states; for(var i = 0; i < items.length; i++) { stateListModel.append(items[i]); stateList.push(items[i]) diff --git a/mix/qml/WebPreview.qml b/mix/qml/WebPreview.qml index 77e60ee66..fc2302540 100644 --- a/mix/qml/WebPreview.qml +++ b/mix/qml/WebPreview.qml @@ -3,79 +3,170 @@ import QtQuick.Window 2.0 import QtQuick.Layouts 1.0 import QtQuick.Controls 1.0 import QtQuick.Controls.Styles 1.1 +import QtWebKit 3.0 +import QtWebKit.experimental 1.0 +import org.ethereum.qml.ProjectModel 1.0 -Component { - Item { - signal editorTextChanged +Item { + id: webPreview - function setText(text) { - codeEditor.text = text; + function reload() { + + + + webView.reload(); + } + + function reloadOnSave() { + if (autoReloadOnSave.checked) + reload(); + } + + function updateDocument(documentId, action) { + for (var i = 0; i < pageListModel.count; i++) + if (pageListModel.get(i).documentId === i) + action(i); + } + + function changePage() { + if (pageCombo.currentIndex >=0 && pageCombo.currentIndex < pageListModel.count) { + webView.url = pageListModel.get(pageCombo.currentIndex).path; + reload(); + } else { + webView.loadHtml(""); } + } - function getText() { - return codeEditor.text; + Connections { + target: ProjectModel + onProjectSaved : reloadOnSave(); + onDocumentSaved: reloadOnSave(); + onDocumentAdded: { + console.log("added") + console.log(documentId) + var document = ProjectModel.getDocument(documentId) + if (document.isHtml) + pageListModel.append(document); + } + onDocumentRemoved: { + updateDocument(documentId, function(i) { pageListModel.remove(i) } ) + } + onDocumentUpdated: { + updateDocument(documentId, function(i) { pageListModel.set(i, ProjectModel.getDocument(documentId)) } ) } - anchors.fill: parent - id: contentView - width: parent.width - height: parent.height * 0.7 - Rectangle { - id: lineColumn - property int rowHeight: codeEditor.font.pixelSize + 3 - color: "#202020" - width: 50 - height: parent.height - Column { - y: -codeEditor.flickableItem.contentY + 4 - width: parent.width - Repeater { - model: Math.max(codeEditor.lineCount + 2, (lineColumn.height/lineColumn.rowHeight)) - delegate: Text { - id: text - color: codeEditor.textColor - font: codeEditor.font - width: lineColumn.width - 4 - horizontalAlignment: Text.AlignRight - verticalAlignment: Text.AlignVCenter - height: lineColumn.rowHeight - renderType: Text.NativeRendering - text: index + 1 - } - } + onProjectLoaded: { + for (var i = 0; i < target.listModel.count; i++) { + var document = target.listModel.get(i); + if (document.isHtml) { + pageListModel.append(document); + if (pageListModel.count === 1) //first page added + changePage(); } } + } - TextArea { - id: codeEditor - textColor: "#EEE8D5" - style: TextAreaStyle { - backgroundColor: "#002B36" - } + onProjectClosed: { + pageListModel.clear(); + } + } - anchors.left: lineColumn.right - anchors.right: parent.right - anchors.top: parent.top - anchors.bottom: parent.bottom - wrapMode: TextEdit.NoWrap - frameVisible: false - - height: parent.height - font.family: "Monospace" - font.pointSize: 12 - width: parent.width - - tabChangesFocus: false - Keys.onPressed: { - if (event.key === Qt.Key_Tab) { - codeEditor.insert(codeEditor.cursorPosition, "\t"); - event.accepted = true; - } + ListModel { + id: pageListModel + } + + ColumnLayout { + anchors.fill: parent + RowLayout { + Layout.fillWidth: true; + Text { + text: qsTr("Page"); + } + ComboBox { + id: pageCombo + model: pageListModel + textRole: "name" + currentIndex: -1 + onCurrentIndexChanged: changePage() + } + Button { + text: qsTr("Reload"); + onClicked: reload() } - onTextChanged: { - editorTextChanged(); + CheckBox { + id: autoReloadOnSave + checked: true + text: qsTr("Auto reload on save"); } + } + + ScrollView { + Layout.fillWidth: true; + Layout.fillHeight: true; + WebView { + id: webView + url: "http://google.com" + anchors.fill: parent + experimental.preferences.developerExtrasEnabled: true + experimental.itemSelector: itemSelector + } + } + } + Component { + id: itemSelector + MouseArea { + // To avoid conflicting with ListView.model when inside ListView context. + property QtObject selectorModel: model + anchors.fill: parent + onClicked: selectorModel.reject() + Rectangle { + clip: true + width: 200 + height: Math.min(listView.contentItem.height + listView.anchors.topMargin + listView.anchors.bottomMargin + , Math.max(selectorModel.elementRect.y, parent.height - selectorModel.elementRect.y - selectorModel.elementRect.height)) + x: (selectorModel.elementRect.x + 200 > parent.width) ? parent.width - 200 : selectorModel.elementRect.x + y: (selectorModel.elementRect.y + selectorModel.elementRect.height + height < parent.height ) ? selectorModel.elementRect.y + selectorModel.elementRect.height + : selectorModel.elementRect.y - height; + radius: 5 + color: "gainsboro" + opacity: 0.8 + ListView { + id: listView + anchors.fill: parent + anchors.margins: 10 + spacing: 5 + model: selectorModel.items + delegate: Rectangle { + color: model.selected ? "gold" : "silver" + height: 50 + width: parent.width + Text { + anchors.centerIn: parent + text: model.text + color: model.enabled ? "black" : "gainsboro" + } + MouseArea { + anchors.fill: parent + enabled: model.enabled + onClicked: selectorModel.accept(model.index) + } + } + section.property: "group" + section.delegate: Rectangle { + height: 30 + width: parent.width + color: "silver" + Text { + anchors.centerIn: parent + text: section + font.bold: true + } + } + } + } } + } + } diff --git a/mix/qml/js/ProjectModel.js b/mix/qml/js/ProjectModel.js index 836b75e13..5b5571cad 100644 --- a/mix/qml/js/ProjectModel.js +++ b/mix/qml/js/ProjectModel.js @@ -43,10 +43,14 @@ function closeProject() { function saveProject() { if (!isEmpty) { + var projectData = { files: [] }; + for (var i = 0; i < projectListModel.count; i++) + projectData.files.push(projectListModel.get(i).fileName) projectSaving(projectData); var json = JSON.stringify(projectData); var projectFile = projectPath + projectFileName; fileIo.writeFile(projectFile, json); + projectSaved(); } } @@ -55,11 +59,12 @@ function loadProject(path) { console.log("loading project at " + path); var projectFile = path + projectFileName; var json = fileIo.readFile(projectFile); - projectData = JSON.parse(json); + var projectData = JSON.parse(json); if (!projectData.title) { var parts = path.split("/"); projectData.title = parts[parts.length - 2]; } + projectTitle = projectData.title; projectPath = path; if (!projectData.files) projectData.files = []; @@ -68,32 +73,31 @@ function loadProject(path) { addFile(projectData.files[i]); } projectSettings.lastProjectPath = path; - projectLoaded(); + projectLoaded(projectData); } function addExistingFile() { addExistingFileDialog.open(); } -function addProjectFiles(files) { - for(var i = 0; i < files.length; i++) - addFile(files[i]); -} - function addFile(fileName) { var p = projectPath + fileName; - var extension = fileName.substring(fileName.length - 4, fileName.length); + var extension = fileName.substring(fileName.lastIndexOf("."), fileName.length); var isContract = extension === ".sol"; - var fileData = { + var isHtml = extension === ".html"; + var docData = { contract: false, path: p, + fileName: fileName, name: isContract ? "Contract" : fileName, documentId: fileName, - isText: isContract || extension === ".html" || extension === ".js", + isText: isContract || isHtml || extension === ".js", isContract: isContract, + isHtml: isHtml, }; - projectListModel.append(fileData); + projectListModel.append(docData); + return docData.documentId; } function findDocument(documentId) @@ -143,14 +147,12 @@ function doCreateProject(title, path) { function doAddExistingFiles(files) { for(var i = 0; i < files.length; i++) { var sourcePath = files[i]; - console.log(sourcePath); var sourceFileName = sourcePath.substring(sourcePath.lastIndexOf("/") + 1, sourcePath.length); - console.log(sourceFileName); var destPath = projectPath + sourceFileName; - console.log(destPath); if (sourcePath !== destPath) fileIo.copyFile(sourcePath, destPath); - addFile(sourceFileName); + var id = addFile(sourceFileName); + documentAdded(id) } } @@ -168,12 +170,17 @@ function renameDocument(documentId, newName) { } } +function getDocument(documentId) { + var i = findDocument(documentId); + return projectListModel.get(i); +} + function removeDocument(documentId) { var i = findDocument(documentId); var document = projectListModel.get(i); if (!document.isContract) { projectListModel.remove(i); - documentUpdated(documentId); + documentRemoved(documentId); } } @@ -189,7 +196,8 @@ function createAndAddFile(name, extension, content) { var fileName = generateFileName(name, extension); var filePath = projectPath + fileName; fileIo.writeFile(filePath, content); - addFile(fileName); + var id = addFile(fileName); + documentAdded(id); } function generateFileName(name, extension) { From 69210417ec3673e1e40474ecb6d3d468e655ad8d Mon Sep 17 00:00:00 2001 From: arkpar Date: Tue, 20 Jan 2015 17:41:53 +0100 Subject: [PATCH 2/8] web container --- mix/CMakeLists.txt | 18 ++++- mix/FileIo.cpp | 5 +- mix/MixApplication.cpp | 8 +++ mix/main.cpp | 3 + mix/noweb.qrc | 5 ++ mix/qml.qrc | 1 - mix/qml/WebPreview.qml | 125 ++++++++++++--------------------- mix/qml/WebPreviewStub.qml | 15 ++++ mix/qml/html/WebContainer.html | 28 ++++++++ mix/web.qrc | 6 ++ 10 files changed, 130 insertions(+), 84 deletions(-) create mode 100644 mix/noweb.qrc create mode 100644 mix/qml/WebPreviewStub.qml create mode 100644 mix/qml/html/WebContainer.html create mode 100644 mix/web.qrc diff --git a/mix/CMakeLists.txt b/mix/CMakeLists.txt index b916cd0fd..92638d5f4 100644 --- a/mix/CMakeLists.txt +++ b/mix/CMakeLists.txt @@ -12,12 +12,21 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON) aux_source_directory(. SRC_LIST) include_directories(..) +find_package (Qt5WebEngine) qt5_add_resources(UI_RESOURCES qml.qrc) file(GLOB HEADERS "*.h") set(EXECUTABLE mix) +if ("${Qt5WebEngine_VERSION_STRING}" VERSION_GREATER "5.3.0") + set (ETH_HAVE_WEBENGINE TRUE) + qt5_add_resources(UI_RESOURCES web.qrc) +else() + qt5_add_resources(UI_RESOURCES noweb.qrc) +endif() + + # eth_add_executable is defined in cmake/EthExecutableHelper.cmake eth_add_executable(${EXECUTABLE} ICON mix @@ -38,8 +47,13 @@ target_link_libraries(${EXECUTABLE} lll) target_link_libraries(${EXECUTABLE} solidity) target_link_libraries(${EXECUTABLE} evmcore) target_link_libraries(${EXECUTABLE} devcore) -target_link_libraries(${EXECUTABLE} web3jsonrpc) -target_link_libraries(${EXECUTABLE} jsqrc) + +if (${ETH_HAVE_WEBENGINE}) + add_definitions(-DETH_HAVE_WEBENGINE) + target_link_libraries(${EXECUTABLE} Qt5::WebEngine) + target_link_libraries(${EXECUTABLE} jsqrc) + target_link_libraries(${EXECUTABLE} web3jsonrpc) +endif() # eth_install_executable is defined in cmake/EthExecutableHelper.cmake eth_install_executable(${EXECUTABLE} diff --git a/mix/FileIo.cpp b/mix/FileIo.cpp index e5a3e5364..52fd57902 100644 --- a/mix/FileIo.cpp +++ b/mix/FileIo.cpp @@ -40,7 +40,10 @@ void FileIo::makeDir(QString const& _url) QString FileIo::readFile(QString const& _url) { QUrl url(_url); - QFile file(url.path()); + QString path(url.path()); + if (url.scheme() == "qrc") + path = ":" + path; + QFile file(path); if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { QTextStream stream(&file); diff --git a/mix/MixApplication.cpp b/mix/MixApplication.cpp index 3b5cfe85d..56ba4ee9f 100644 --- a/mix/MixApplication.cpp +++ b/mix/MixApplication.cpp @@ -21,6 +21,11 @@ #include #include + +#ifdef ETH_HAVE_WEBENGINE +#include +#endif + #include "MixApplication.h" #include "AppContext.h" @@ -31,6 +36,9 @@ using namespace dev::mix; MixApplication::MixApplication(int _argc, char* _argv[]): QApplication(_argc, _argv), m_engine(new QQmlApplicationEngine()), m_appContext(new AppContext(m_engine.get())) { +#ifdef ETH_HAVE_WEBENGINE + QtWebEngine::initialize(); +#endif QObject::connect(this, SIGNAL(lastWindowClosed()), context(), SLOT(quitApplication())); //use to kill ApplicationContext and other stuff m_appContext->load(); } diff --git a/mix/main.cpp b/mix/main.cpp index 4f2c901b4..69bb9df4a 100644 --- a/mix/main.cpp +++ b/mix/main.cpp @@ -27,6 +27,9 @@ using namespace dev::mix; int main(int _argc, char* _argv[]) { +#ifdef ETH_HAVE_WEBENGINE + Q_INIT_RESOURCE(js); +#endif try { MixApplication app(_argc, _argv); diff --git a/mix/noweb.qrc b/mix/noweb.qrc new file mode 100644 index 000000000..25ce95352 --- /dev/null +++ b/mix/noweb.qrc @@ -0,0 +1,5 @@ + + + qml/WebPreviewStub.qml + + diff --git a/mix/qml.qrc b/mix/qml.qrc index 169d1ebcb..06188bda6 100644 --- a/mix/qml.qrc +++ b/mix/qml.qrc @@ -39,7 +39,6 @@ qml/CodeEditor.qml qml/CodeEditorView.qml qml/js/ProjectModel.js - qml/WebPreview.qml qml/Ether.qml qml/EtherValue.qml qml/BigIntValue.qml diff --git a/mix/qml/WebPreview.qml b/mix/qml/WebPreview.qml index fc2302540..f79ce80de 100644 --- a/mix/qml/WebPreview.qml +++ b/mix/qml/WebPreview.qml @@ -3,18 +3,25 @@ import QtQuick.Window 2.0 import QtQuick.Layouts 1.0 import QtQuick.Controls 1.0 import QtQuick.Controls.Styles 1.1 -import QtWebKit 3.0 -import QtWebKit.experimental 1.0 -import org.ethereum.qml.ProjectModel 1.0 +import QtWebEngine 1.0 +import QtWebEngine.experimental 1.0 Item { id: webPreview + property string pendingPageUrl: "" + property bool initialized: false + + function setPreviewUrl(url) { + if (!initialized) + pendingPageUrl = url; + else { + pendingPageUrl = ""; + webView.runJavaScript("loadPage(\"" + url + "\")"); + } + } function reload() { - - - - webView.reload(); + webView.runJavaScript("reloadPage()"); } function reloadOnSave() { @@ -30,21 +37,28 @@ Item { function changePage() { if (pageCombo.currentIndex >=0 && pageCombo.currentIndex < pageListModel.count) { - webView.url = pageListModel.get(pageCombo.currentIndex).path; - reload(); + setPreviewUrl(pageListModel.get(pageCombo.currentIndex).path); } else { - webView.loadHtml(""); + setPreviewUrl(""); + } + } + Connections { + target: appContext + onAppLoaded: { + //We need to load the container using file scheme so that web security would allow loading local files in iframe + var containerPage = fileIo.readFile("qrc:///qml/html/WebContainer.html"); + webView.loadHtml(containerPage, "file:///") } } Connections { - target: ProjectModel + target: projectModel onProjectSaved : reloadOnSave(); onDocumentSaved: reloadOnSave(); onDocumentAdded: { console.log("added") console.log(documentId) - var document = ProjectModel.getDocument(documentId) + var document = projectModel.getDocument(documentId) if (document.isHtml) pageListModel.append(document); } @@ -52,7 +66,7 @@ Item { updateDocument(documentId, function(i) { pageListModel.remove(i) } ) } onDocumentUpdated: { - updateDocument(documentId, function(i) { pageListModel.set(i, ProjectModel.getDocument(documentId)) } ) + updateDocument(documentId, function(i) { pageListModel.set(i, projectModel.getDocument(documentId)) } ) } onProjectLoaded: { @@ -77,10 +91,12 @@ Item { ColumnLayout { anchors.fill: parent + RowLayout { + anchors.top: parent.top Layout.fillWidth: true; Text { - text: qsTr("Page"); + text: qsTr("Page") } ComboBox { id: pageCombo @@ -90,83 +106,32 @@ Item { onCurrentIndexChanged: changePage() } Button { - text: qsTr("Reload"); + text: qsTr("Reload") onClicked: reload() } CheckBox { id: autoReloadOnSave checked: true - text: qsTr("Auto reload on save"); + text: qsTr("Auto reload on save") } } - ScrollView { - Layout.fillWidth: true; - Layout.fillHeight: true; - WebView { - id: webView - url: "http://google.com" - anchors.fill: parent - experimental.preferences.developerExtrasEnabled: true - experimental.itemSelector: itemSelector + WebEngineView { + Layout.fillWidth: true + Layout.fillHeight: true + id: webView + experimental.settings.localContentCanAccessFileUrls: true + experimental.settings.localContentCanAccessRemoteUrls: true + onJavaScriptConsoleMessage: { + console.log(sourceID + ":" + lineNumber + ":" + message); } - } - } - - Component { - id: itemSelector - MouseArea { - // To avoid conflicting with ListView.model when inside ListView context. - property QtObject selectorModel: model - anchors.fill: parent - onClicked: selectorModel.reject() - Rectangle { - clip: true - width: 200 - height: Math.min(listView.contentItem.height + listView.anchors.topMargin + listView.anchors.bottomMargin - , Math.max(selectorModel.elementRect.y, parent.height - selectorModel.elementRect.y - selectorModel.elementRect.height)) - x: (selectorModel.elementRect.x + 200 > parent.width) ? parent.width - 200 : selectorModel.elementRect.x - y: (selectorModel.elementRect.y + selectorModel.elementRect.height + height < parent.height ) ? selectorModel.elementRect.y + selectorModel.elementRect.height - : selectorModel.elementRect.y - height; - radius: 5 - color: "gainsboro" - opacity: 0.8 - ListView { - id: listView - anchors.fill: parent - anchors.margins: 10 - spacing: 5 - model: selectorModel.items - delegate: Rectangle { - color: model.selected ? "gold" : "silver" - height: 50 - width: parent.width - Text { - anchors.centerIn: parent - text: model.text - color: model.enabled ? "black" : "gainsboro" - } - MouseArea { - anchors.fill: parent - enabled: model.enabled - onClicked: selectorModel.accept(model.index) - } - } - section.property: "group" - section.delegate: Rectangle { - height: 30 - width: parent.width - color: "silver" - Text { - anchors.centerIn: parent - text: section - font.bold: true - } - } + onLoadingChanged: { + if (!loading) { + initialized = true; + if (pendingPageUrl) + setPreviewUrl(pendingPageUrl); } } } - } - } diff --git a/mix/qml/WebPreviewStub.qml b/mix/qml/WebPreviewStub.qml new file mode 100644 index 000000000..d2d797ffc --- /dev/null +++ b/mix/qml/WebPreviewStub.qml @@ -0,0 +1,15 @@ +import QtQuick 2.0 +import QtQuick.Window 2.0 +import QtQuick.Layouts 1.0 +import QtQuick.Controls 1.0 +import QtQuick.Controls.Styles 1.1 + +Item { + id: webPreview + Text { + anchors.fill: parent + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + text: qsTr("Web preview is not supported in this build"); + } +} diff --git a/mix/qml/html/WebContainer.html b/mix/qml/html/WebContainer.html new file mode 100644 index 000000000..ad87d93c9 --- /dev/null +++ b/mix/qml/html/WebContainer.html @@ -0,0 +1,28 @@ + + + + + + + + + + + + + diff --git a/mix/web.qrc b/mix/web.qrc new file mode 100644 index 000000000..a50863a2c --- /dev/null +++ b/mix/web.qrc @@ -0,0 +1,6 @@ + + + qml/WebPreview.qml + qml/html/WebContainer.html + + From 8f17be74bc48439fb07e1c34cb299f9dbd1bf3eb Mon Sep 17 00:00:00 2001 From: arkpar Date: Wed, 21 Jan 2015 10:31:56 +0100 Subject: [PATCH 3/8] web socket fot ethereum.js api --- libjsqrc/ethereumjs/dist/ethereum.js | 4 +++- mix/qml/WebPreview.qml | 15 +++++++++++++++ mix/qml/html/WebContainer.html | 7 +++++++ mix/qml/js/ProjectModel.js | 1 - 4 files changed, 25 insertions(+), 2 deletions(-) diff --git a/libjsqrc/ethereumjs/dist/ethereum.js b/libjsqrc/ethereumjs/dist/ethereum.js index 1dbb42d89..fb9101aef 100644 --- a/libjsqrc/ethereumjs/dist/ethereum.js +++ b/libjsqrc/ethereumjs/dist/ethereum.js @@ -1465,8 +1465,10 @@ var WebSocketProvider = function(host) { /// Response for the call will be received by ws.onmessage /// @param payload is inner message object WebSocketProvider.prototype.send = function(payload) { + console.log("wsSend"); if (this.ready) { var data = JSON.stringify(payload); + console.log(payload); this.ws.send(data); } else { @@ -1511,4 +1513,4 @@ module.exports = web3; },{"./lib/autoprovider":2,"./lib/contract":3,"./lib/filter":4,"./lib/httprpc":5,"./lib/providermanager":6,"./lib/qt":7,"./lib/web3":8,"./lib/websocket":9}]},{},["web3"]) -//# sourceMappingURL=ethereum.js.map \ No newline at end of file +//# sourceMappingURL=ethereum.js.map diff --git a/mix/qml/WebPreview.qml b/mix/qml/WebPreview.qml index f79ce80de..80d0f7e43 100644 --- a/mix/qml/WebPreview.qml +++ b/mix/qml/WebPreview.qml @@ -4,6 +4,7 @@ import QtQuick.Layouts 1.0 import QtQuick.Controls 1.0 import QtQuick.Controls.Styles 1.1 import QtWebEngine 1.0 +import Qt.WebSockets 1.0 import QtWebEngine.experimental 1.0 Item { @@ -48,6 +49,7 @@ Item { //We need to load the container using file scheme so that web security would allow loading local files in iframe var containerPage = fileIo.readFile("qrc:///qml/html/WebContainer.html"); webView.loadHtml(containerPage, "file:///") + } } @@ -89,6 +91,18 @@ Item { id: pageListModel } + WebSocketServer { + id: socketServer + listen: true + name: "mix" + onClientConnected: + { + webSocket.onTextMessageReceived.connect(function(message) { + console.log("rpc: " + message); + }); + } + } + ColumnLayout { anchors.fill: parent @@ -128,6 +142,7 @@ Item { onLoadingChanged: { if (!loading) { initialized = true; + webView.runJavaScript("init(\"" + socketServer.url + "\")"); if (pendingPageUrl) setPreviewUrl(pendingPageUrl); } diff --git a/mix/qml/html/WebContainer.html b/mix/qml/html/WebContainer.html index ad87d93c9..2a81985bc 100644 --- a/mix/qml/html/WebContainer.html +++ b/mix/qml/html/WebContainer.html @@ -15,6 +15,13 @@ reloadPage = function() { var preview = document.getElementById('preview'); preview.contentWindow.location.reload(); }; + +init = function(url) { + web3 = require('web3'); + web3.setProvider(new web3.providers.WebSocketProvider(url)); + window.web3 = web3; +} +