diff --git a/mix/qml/LogsPane.qml b/mix/qml/LogsPane.qml index 9d03b2af2..bef616f21 100644 --- a/mix/qml/LogsPane.qml +++ b/mix/qml/LogsPane.qml @@ -205,7 +205,7 @@ Rectangle headerVisible : false onDoubleClicked: { - var log = logsModel.get((logsTable.currentRow)); + var log = logsModel.get(logsTable.currentRow); if (log) appContext.toClipboard(log.type + "\t" + log.level + "\t" + log.date + "\t" + log.content); } diff --git a/mix/qml/WebPreview.qml b/mix/qml/WebPreview.qml index ba2975453..34dc7c698 100644 --- a/mix/qml/WebPreview.qml +++ b/mix/qml/WebPreview.qml @@ -219,6 +219,14 @@ Item { focus: true } + Rectangle + { + width: 1 + height: parent.height - 10 + color: WebPreviewStyle.general.separatorColor + anchors.verticalCenter: parent.verticalCenter + } + CheckBox { id: autoReloadOnSave checked: true @@ -231,15 +239,56 @@ Item { } focus: true } + + Rectangle + { + width: 1 + height: parent.height - 10 + color: WebPreviewStyle.general.separatorColor + anchors.verticalCenter: parent.verticalCenter + } + + Button + { + height: 28 + anchors.verticalCenter: parent.verticalCenter + action: expressionAction + iconSource: "qrc:/qml/img/console.png" + } + + Action { + id: expressionAction + tooltip: qsTr("Expressions") + onTriggered: + { + expressionPanel.visible = !expressionPanel.visible; + if (expressionPanel.visible) + { + webView.width = webView.parent.width - 350 + expressionInput.forceActiveFocus(); + } + else + webView.width = webView.parent.width + } + } } } Rectangle + { + Layout.preferredHeight: 1 + Layout.preferredWidth: parent.width + color: WebPreviewStyle.general.separatorColor + } + + SplitView { Layout.preferredWidth: parent.width Layout.fillHeight: true WebEngineView { - anchors.fill: parent + Layout.fillHeight: true + width: parent.width + Layout.preferredWidth: parent.width id: webView experimental.settings.localContentCanAccessRemoteUrls: true onJavaScriptConsoleMessage: { @@ -254,6 +303,123 @@ Item { } } } + + Column { + id: expressionPanel + width: 350 + Layout.preferredWidth: 350 + Layout.fillHeight: true + spacing: 0 + visible: false + function addExpression() + { + if (expressionInput.text === "") + return; + expressionInput.history.unshift(expressionInput.text); + expressionInput.index = -1; + webView.runJavaScript("executeJavaScript(\"" + expressionInput.text.replace(/"/g, '\\"') + "\")", function(result) { + resultTextArea.text = "> " + result + "\n\n" + resultTextArea.text; + expressionInput.text = ""; + }); + } + + Row + { + id: rowConsole + width: parent.width + Button + { + height: 22 + width: 22 + action: clearAction + iconSource: "qrc:/qml/img/broom.png" + } + + Action { + id: clearAction + enabled: resultTextArea.text !== "" + tooltip: qsTr("Clear") + onTriggered: { + resultTextArea.text = ""; + } + } + + DefaultTextField { + id: expressionInput + width: parent.width - 15 + height: 20 + font.family: WebPreviewStyle.general.fontName + font.italic: true + font.pointSize: Style.absoluteSize(-3) + anchors.verticalCenter: parent.verticalCenter + + property var history: [] + property int index: -1 + + function displayCache(incr) + { + index = index + incr; + if (history.length - 1 < index || index < 0) + { + if (incr === 1) + index = 0; + else + index = history.length - 1; + } + expressionInput.text = history[index]; + } + + Keys.onDownPressed: { + displayCache(1); + } + + Keys.onUpPressed: { + displayCache(-1); + } + + Keys.onEnterPressed: + { + expressionPanel.addExpression(); + } + + Keys.onReturnPressed: + { + expressionPanel.addExpression(); + } + + onFocusChanged: + { + if (!focus && text == "") + text = qsTr("Expression"); + if (focus && text === qsTr("Expression")) + text = ""; + } + + style: TextFieldStyle { + background: Rectangle { + color: "transparent" + } + } + } + } + + TextArea { + Layout.fillHeight: true + height: parent.height - rowConsole.height + readOnly: true + id: resultTextArea + width: expressionPanel.width + wrapMode: Text.Wrap + font.family: WebPreviewStyle.general.fontName + font.pointSize: Style.absoluteSize(-3) + backgroundVisible: true + style: TextAreaStyle { + backgroundColor: "#f0f0f0" + } + } + } } } } + + diff --git a/mix/qml/WebPreviewStyle.qml b/mix/qml/WebPreviewStyle.qml index 551f5a446..231bbe16c 100644 --- a/mix/qml/WebPreviewStyle.qml +++ b/mix/qml/WebPreviewStyle.qml @@ -10,5 +10,7 @@ QtObject { property QtObject general: QtObject { property string headerBackgroundColor: "#f0f0f0" + property string separatorColor: "#808080" + property string fontName: "sans serif" } } diff --git a/mix/qml/html/WebContainer.html b/mix/qml/html/WebContainer.html index e2f97fd86..3cddda377 100644 --- a/mix/qml/html/WebContainer.html +++ b/mix/qml/html/WebContainer.html @@ -17,7 +17,7 @@ reloadPage = function() { updateContracts = function(contracts) { if (window.web3) { - window.web3.reset(); + window.web3.reset(); window.contracts = {}; for (var c in contracts) { var contract = window.web3.eth.contract(contracts[c].address, contracts[c].interface); @@ -36,6 +36,12 @@ init = function(url) { web3.setProvider(new web3.providers.HttpSyncProvider(url)); }; +executeJavaScript = function(script) { + var preview = document.getElementById('preview'); + var obj = preview.contentWindow.eval(script); + return JSON.stringify(obj, null, 2); +} +