refactor: remove dynamic scoping from browser module

closes #4246
This commit is contained in:
Khushboo Mehta 2021-12-08 00:15:17 +01:00 committed by Sale Djenic
parent a9c968b984
commit 83d4aaa0e8
21 changed files with 675 additions and 534 deletions

View File

@ -22,115 +22,120 @@ import "../Chat/popups"
// Code based on https://code.qt.io/cgit/qt/qtwebengine.git/tree/examples/webengine/quicknanobrowser/BrowserWindow.qml?h=5.15
// Licensed under BSD
Rectangle {
id: browserWindow
property var globalStore
property Item currentWebView: tabs.currentIndex < tabs.count ? tabs.getTab(tabs.currentIndex).item : null
property Component browserDialogComponent: BrowserDialog {
onClosing: destroy()
}
property Component jsDialogComponent: JSDialogWindow {}
property bool currentTabConnected: false
property Component accessDialogComponent: BrowserConnectionModal {
currentTab: tabs.getTab(tabs.currentIndex) && tabs.getTab(tabs.currentIndex).item
x: appLayout.width - width - Style.current.halfPadding
y: browserWindow.y + browserHeader.height + Style.current.halfPadding
}
// TODO we'll need a new dialog at one point because this one is not using the same call, but it's good for now
property Component sendTransactionModalComponent: SignTransactionModal {
store: browserWindow.globalStore
}
property Component signMessageModalComponent: SignMessageModal {}
property MessageDialog sendingError: MessageDialog {
id: sendingError
//% "Error sending the transaction"
title: qsTrId("error-sending-the-transaction")
icon: StandardIcon.Critical
standardButtons: StandardButton.Ok
}
property MessageDialog signingError: MessageDialog {
id: signingError
//% "Error signing message"
title: qsTrId("error-signing-message")
icon: StandardIcon.Critical
standardButtons: StandardButton.Ok
}
property QtObject defaultProfile: WebEngineProfile {
storageName: "Profile"
offTheRecord: false
httpUserAgent: {
if (localAccountSensitiveSettings.compatibilityMode) {
// Google doesn't let you connect if the user agent is Chrome-ish and doesn't satisfy some sort of hidden requirement
return "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:81.0) Gecko/20100101 Firefox/81.0"
}
return ""
}
useForGlobalCertificateVerification: true
userScripts: [
WebEngineScript {
injectionPoint: WebEngineScript.DocumentCreation
sourceUrl: Qt.resolvedUrl("./helpers/provider.js")
worldId: WebEngineScript.MainWorld // TODO: check https://doc.qt.io/qt-5/qml-qtwebengine-webenginescript.html#worldId-prop
}
]
}
property QtObject otrProfile: WebEngineProfile {
offTheRecord: true
persistentCookiesPolicy: WebEngineProfile.NoPersistentCookies
httpUserAgent: defaultProfile.httpUserAgent
userScripts: [
WebEngineScript {
injectionPoint: WebEngineScript.DocumentCreation
sourceUrl: Qt.resolvedUrl("./helpers/provider.js")
worldId: WebEngineScript.MainWorld // TODO: check https://doc.qt.io/qt-5/qml-qtwebengine-webenginescript.html#worldId-prop
}
]
}
property var sendTransactionModal
function openUrlInNewTab(url) {
var tab = browserWindow.addNewTab()
tab.item.url = determineRealURL(url)
var tab = _internal.addNewTab()
tab.item.url = _internal.determineRealURL(url)
}
function addNewDownloadTab() {
tabs.createDownloadTab(tabs.count !== 0 ? currentWebView.profile : defaultProfile);
tabs.currentIndex = tabs.count - 1;
}
QtObject {
id: _internal
function addNewTab() {
var tab = tabs.createEmptyTab(tabs.count !== 0 ? currentWebView.profile : defaultProfile);
tabs.currentIndex = tabs.count - 1;
browserHeader.addressBar.forceActiveFocus();
browserHeader.addressBar.selectAll();
property Item currentWebView: tabs.currentIndex < tabs.count ? tabs.getTab(tabs.currentIndex).item : null
return tab;
}
property Component browserDialogComponent: BrowserDialog {
onClosing: destroy()
}
function onDownloadRequested(download) {
downloadBar.isVisible = true
download.accept();
DownloadsStore.addDownload(download)
}
property Component jsDialogComponent: JSDialogWindow {}
function determineRealURL(url) {
return Web3ProviderStore.determineRealURL(url)
}
property Component accessDialogComponent: BrowserConnectionModal {
currentTab: tabs.getTab(tabs.currentIndex) && tabs.getTab(tabs.currentIndex).item
parent: browserWindow
x: browserWindow.width - width - Style.current.halfPadding
y: browserWindow.y + browserHeader.height + Style.current.halfPadding
web3Response: function(message) {
provider.web3Response(message)
}
}
onCurrentWebViewChanged: {
findBar.reset();
browserHeader.addressBar.text = Web3ProviderStore.obtainAddress(currentWebView.url)
// TODO we'll need a new dialog at one point because this one is not using the same call, but it's good for now
property Component sendTransactionModalComponent: SignTransactionModal {
store: browserWindow.globalStore
}
property Component signMessageModalComponent: SignMessageModal {}
property MessageDialog sendingError: MessageDialog {
//% "Error sending the transaction"
title: qsTrId("error-sending-the-transaction")
icon: StandardIcon.Critical
standardButtons: StandardButton.Ok
}
property MessageDialog signingError: MessageDialog {
//% "Error signing message"
title: qsTrId("error-signing-message")
icon: StandardIcon.Critical
standardButtons: StandardButton.Ok
}
property QtObject defaultProfile: WebEngineProfile {
storageName: "Profile"
offTheRecord: false
httpUserAgent: {
if (localAccountSensitiveSettings.compatibilityMode) {
// Google doesn't let you connect if the user agent is Chrome-ish and doesn't satisfy some sort of hidden requirement
return "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:81.0) Gecko/20100101 Firefox/81.0"
}
return ""
}
useForGlobalCertificateVerification: true
userScripts: [
WebEngineScript {
injectionPoint: WebEngineScript.DocumentCreation
sourceUrl: Qt.resolvedUrl("./helpers/provider.js")
worldId: WebEngineScript.MainWorld // TODO: check https://doc.qt.io/qt-5/qml-qtwebengine-webenginescript.html#worldId-prop
}
]
}
property QtObject otrProfile: WebEngineProfile {
offTheRecord: true
persistentCookiesPolicy: WebEngineProfile.NoPersistentCookies
httpUserAgent: _internal.defaultProfile.httpUserAgent
userScripts: [
WebEngineScript {
injectionPoint: WebEngineScript.DocumentCreation
sourceUrl: Qt.resolvedUrl("./helpers/provider.js")
worldId: WebEngineScript.MainWorld // TODO: check https://doc.qt.io/qt-5/qml-qtwebengine-webenginescript.html#worldId-prop
}
]
}
function addNewDownloadTab() {
tabs.createDownloadTab(tabs.count !== 0 ? currentWebView.profile : defaultProfile);
tabs.currentIndex = tabs.count - 1;
}
function addNewTab() {
var tab = tabs.createEmptyTab(tabs.count !== 0 ? currentWebView.profile : defaultProfile);
tabs.currentIndex = tabs.count - 1;
browserHeader.addressBar.forceActiveFocus();
browserHeader.addressBar.selectAll();
return tab;
}
function onDownloadRequested(download) {
downloadBar.isVisible = true
download.accept();
DownloadsStore.addDownload(download)
}
function determineRealURL(url) {
return Web3ProviderStore.determineRealURL(url)
}
onCurrentWebViewChanged: {
findBar.reset();
browserHeader.addressBar.text = Web3ProviderStore.obtainAddress(currentWebView.url)
}
}
Layout.fillHeight: true
@ -139,10 +144,71 @@ Rectangle {
color: Style.current.inputBackground
border.width: 0
WebProviderObj { id: provider }
WebProviderObj {
id: provider
createAccessDialogComponent: function() {
return _internal.accessDialogComponent.createObject(browserWindow)
}
createSendTransactionModalComponent: function(request) {
return _internal.sendTransactionModalComponent.createObject(browserWindow, {
trxData: request.payload.params[0].data || "",
selectedAccount: {
name: WalletStore.dappBrowserAccount.name,
address: request.payload.params[0].from,
iconColor: WalletStore.dappBrowserAccount.color,
assets: WalletStore.dappBrowserAccount.assets
},
selectedRecipient: {
address: request.payload.params[0].to,
identicon: RootStore.generateIdenticon(request.payload.params[0].to),
name: RootStore.activeChannelName,
type: RecipientSelector.Type.Address
},
selectedAsset: {
name: "ETH",
symbol: "ETH",
address: Constants.zeroAddress
},
selectedFiatAmount: "42", // TODO calculate that
selectedAmount: RootStore.getWei2Eth(request.payload.params[0].value, 18)
})
}
createSignMessageModalComponent: function(request) {
return _internal.signMessageModalComponent.createObject(browserWindow, {
request,
selectedAccount: {
name: WalletStore.dappBrowserAccount.name,
iconColor: WalletStore.dappBrowserAccount.color
}
})
}
showSendingError: function(message) {
_internal.sendingError.text = e.message
return _internal.sendingError.open()
}
showSigningError: function(message) {
_internal.signingError.text = e.message
return _internal.signingError.open()
}
showToastMessage: function(result) {
// TODO: WIP under PR https://github.com/status-im/status-desktop/pull/4274
//% "Transaction pending..."
toastMessage.title = qsTrId("ens-transaction-pending")
toastMessage.source = Style.svg("loading")
toastMessage.iconColor = Style.current.primary
toastMessage.iconRotates = true
toastMessage.link = `${WalletStore.etherscanLink}/${result}`
toastMessage.open()
}
}
BrowserShortcutActions {
id: keyboardShortcutActions
currentWebView: _internal.currentWebView
findBarComponent: findBar
browserHeaderComponent: browserHeader
onAddNewDownloadTab: _internal.addNewDownloadTab()
onRemoveView: tabs.removeView(tabs.currentIndex)
}
WebChannel {
@ -155,20 +221,45 @@ Rectangle {
anchors.top: parent.top
anchors.topMargin: tabs.tabHeight + tabs.anchors.topMargin
z: 52
addNewTab: browserWindow.addNewTab
favoriteComponent: favoritesBar
currentFavorite: currentWebView && BookmarksStore.getCurrentFavorite(currentWebView.url)
currentFavorite: _internal.currentWebView && BookmarksStore.getCurrentFavorite(_internal.currentWebView.url)
dappBrowserAccName: WalletStore.dappBrowserAccount.name
dappBrowserAccIcon: WalletStore.dappBrowserAccount.color
settingMenu: settingsMenu
walletMenu: browserWalletMenu
currentUrl: _internal.currentWebView.url
isLoading: _internal.currentWebView.loading
canGoBack: _internal.currentWebView.canGoBack
canGoForward: _internal.currentWebView.canGoForward
currentTabConnected: RootStore.currentTabConnected
onOpenHistoryPopup: historyMenu.popup(xPos, yPos)
onGoBack: _internal.currentWebView.goBack()
onGoForward: _internal.currentWebView.goForward()
onReload: _internal.currentWebView.reload()
onStopLoading: _internal.currentWebView.stop()
onAddNewFavoritelClicked: {
addFavoriteModal.modifiyModal = browserHeader.currentFavorite
addFavoriteModal.toolbarMode = true
addFavoriteModal.x = xPos - 30
addFavoriteModal.y = browserHeader.y + browserHeader.height + 4
addFavoriteModal.ogUrl = browserHeader.currentFavorite ? browserHeader.currentFavorite.url : currentWebView.url
addFavoriteModal.ogName = browserHeader.currentFavorite ? browserHeader.currentFavorite.name : currentWebView.title
addFavoriteModal.ogUrl = browserHeader.currentFavorite ? browserHeader.currentFavorite.url : _internal.currentWebView.url
addFavoriteModal.ogName = browserHeader.currentFavorite ? browserHeader.currentFavorite.name : _internal.currentWebView.title
addFavoriteModal.open()
}
onLaunchInBrowser: {
// TODO: disable browsing local files? file://
if (localAccountSensitiveSettings.useBrowserEthereumExplorer !== Constants.browserEthereumExplorerNone && url.startsWith("0x")) {
_internal.currentWebView.url = RootStore.get0xFormedUrl(localAccountSensitiveSettings.useBrowserEthereumExplorer, url)
return
}
if (localAccountSensitiveSettings.shouldShowBrowserSearchEngine !== Constants.browserSearchEngineNone && !Utils.isURL(url) && !Utils.isURLWithOptionalProtocol(url)) {
_internal.currentWebView.url = RootStore.getFormedUrl(localAccountSensitiveSettings.shouldShowBrowserSearchEngine, url)
return
} else if (Utils.isURLWithOptionalProtocol(url)) {
url = "https://" + url
}
_internal.currentWebView.url = _internal.determineRealURL(url);
}
}
BrowserTabView {
@ -181,6 +272,18 @@ Rectangle {
anchors.right: parent.right
z: 50
tabComponent: webEngineView
currentWebEngineProfile: _internal.currentWebView.profile
determineRealURL: function(url) {
return _internal.determineRealURL(url)
}
onOpenNewTabTriggered: _internal.addNewTab()
Component.onCompleted: {
_internal.defaultProfile.downloadRequested.connect(_internal.onDownloadRequested);
_internal.otrProfile.downloadRequested.connect(_internal.onDownloadRequested);
var tab = createEmptyTab(_internal.defaultProfile);
// For Devs: Uncomment the next lien if you want to use the simpeldapp on first load
// tab.item.url = Web3ProviderStore.determineRealURL("https://simpledapp.eth");
}
}
ProgressBar {
@ -189,7 +292,7 @@ Rectangle {
from: 0
to: 100
visible: value != 0 && value != 100
value: (currentWebView && currentWebView.loadProgress < 100) ? currentWebView.loadProgress : 0
value: (_internal.currentWebView && _internal.currentWebView.loadProgress < 100) ? _internal.currentWebView.loadProgress : 0
anchors.bottom: parent.bottom
anchors.bottomMargin: Style.current.padding
anchors.right: parent.right
@ -205,7 +308,7 @@ Rectangle {
anchors.right: parent.right
anchors.bottom: parent.bottom
onNewViewRequested: function(request) {
var tab = tabs.createEmptyTab(currentWebView.profile);
var tab = tabs.createEmptyTab(_internal.currentWebView.profile);
tabs.currentIndex = tabs.count - 1;
request.openIn(tab.item);
}
@ -221,6 +324,12 @@ Rectangle {
openInNewTab: function (url) {
browserWindow.openUrlInNewTab(url)
}
onEditFavoriteTriggered: {
addFavoriteModal.modifiyModal = true
addFavoriteModal.ogUrl = favoriteMenu.currentFavorite ? favoriteMenu.currentFavorite.url : _internal.currentWebView.url
addFavoriteModal.ogName = favoriteMenu.currentFavorite ? favoriteMenu.currentFavorite.name : _internal.currentWebView.title
addFavoriteModal.open()
}
}
MessageDialog {
@ -260,12 +369,14 @@ Rectangle {
anchors.bottom: parent.bottom
z: 60
downloadsModel: DownloadsStore.downloadModel
downloadsMenu: downloadMenu
onOpenDownloadClicked: {
if (downloadComplete) {
return DownloadsStore.openFile(index)
}
DownloadsStore.openDirectory(index)
}
onAddNewDownloadTab: _internal.addNewDownloadTab()
}
FindBar {
@ -277,13 +388,13 @@ Rectangle {
onFindNext: {
if (text)
currentWebView && currentWebView.findText(text);
_internal.currentWebView && _internal.currentWebView.findText(text);
else if (!visible)
visible = true;
}
onFindPrevious: {
if (text)
currentWebView && currentWebView.findText(text, WebEngineView.FindBackward);
_internal.currentWebView && _internal.currentWebView.findText(text, WebEngineView.FindBackward);
else if (!visible)
visible = true;
}
@ -320,29 +431,182 @@ Rectangle {
id: downloadMenu
}
BrowserSettingsMenu {
id: settingsMenu
x: parent.width - width
y: browserHeader.y + (localAccountSensitiveSettings.shouldShowFavoritesBar ? browserHeader.height - 38 : browserHeader.height)
isIncognito: _internal.currentWebView && _internal.currentWebView.profile === _internal.otrProfile
onAddNewTab: _internal.addNewTab()
onGoIncognito: {
if (_internal.currentWebView) {
_internal.currentWebView.profile = checked ? _internal.otrProfile : _internal.defaultProfile;
}
}
onZoomIn: {
const newZoom = _internal.currentWebView.zoomFactor + 0.1
_internal.currentWebView.changeZoomFactor(newZoom)
}
onZoomOut: {
const newZoom = currentWebView.zoomFactor - 0.1
_internal.currentWebView.changeZoomFactor(newZoom)
}
onChangeZoomFactor: _internal.currentWebView.changeZoomFactor(1.0)
onLaunchFindBar: {
if (!findBar.visible) {
findBar.visible = true;
findBar.forceActiveFocus()
}
}
onToggleCompatibilityMode: {
for (let i = 0; i < tabs.count; ++i){
tabs.getTab(i).item.stop() // Stop all loading tabs
}
localAccountSensitiveSettings.compatibilityMode = checked;
for (let i = 0; i < tabs.count; ++i){
tabs.getTab(i).item.reload() // Reload them with new user agent
}
}
onLaunchBrowserSettings: {
Global.changeAppSectionBySectionType(Constants.appSection.profile)
// TODO: replace with shared store constant
// Profile/RootStore.browser_settings_id
profileLayoutContainer.changeProfileSection(10)
}
}
BrowserWalletMenu {
id: browserWalletMenu
y: browserHeader.height + browserHeader.anchors.topMargin
x: parent.width - width - Style.current.halfPadding
onSendTriggered: {
sendTransactionModal.selectedAccount = selectedAccount
sendTransactionModal.open()
}
onReload: {
for (let i = 0; i < tabs.count; ++i){
tabs.getTab(i).item.reload();
}
}
onDisconnect: {
Web3ProviderStore.web3ProviderInst.disconnect()
provider.postMessage(`{"type":"web3-disconnect-account"}`)
close()
}
}
Menu {
id: historyMenu
Instantiator {
model: _internal.currentWebView && _internal.currentWebView.navigationHistory.items
MenuItem {
text: model.title
onTriggered: _internal.currentWebView.goBackOrForward(model.offset)
checkable: !enabled
checked: !enabled
enabled: model.offset
}
onObjectAdded: function(index, object) {
historyMenu.insertItem(index, object)
}
onObjectRemoved: function(index, object) {
historyMenu.removeItem(object)
}
}
}
Component {
id: favoritesBar
FavoritesBar {
bookmarkModel: BookmarksStore.bookmarksModel
favoritesMenu: favoriteMenu
setAsCurrentWebUrl: function(url) {
_internal.currentWebView.url = _internal.determineRealURL(url)
}
addFavModal: function() {
addFavoriteModal.toolbarMode = true
addFavoriteModal.ogUrl = browserHeader.currentFavorite ? browserHeader.currentFavorite.url : _internal.currentWebView.url
addFavoriteModal.ogName = browserHeader.currentFavorite ? browserHeader.currentFavorite.name : _internal.currentWebView.title
addFavoriteModal.open()
}
}
}
Component {
id: webEngineView
BrowserWebEngineView {}
BrowserWebEngineView {
anchors.top: parent.top
anchors.topMargin: browserHeader.height
currentWebView: _internal.currentWebView
webChannel: channel
findBarComp: findBar
favMenu: favoriteMenu
addFavModal: addFavoriteModal
downloadsMenu: downloadMenu
determineRealURLFn: function(url) {
return _internal.determineRealURL(url)
}
onLinkHovered: function(hoveredUrl) {
if (hoveredUrl === "")
hideStatusText.start();
else {
statusText.text = hoveredUrl;
statusBubble.visible = true;
hideStatusText.stop();
}
}
onSetCurrentWebUrl: {
_internal.currentWebView.url = url
}
onWindowCloseRequested: tabs.removeView(tabs.indexOfView(webEngineView))
onNewViewRequested: function(request) {
if (!request.userInitiated) {
print("Warning: Blocked a popup window.");
} else if (request.destination === WebEngineView.NewViewInTab) {
var tab = tabs.createEmptyTab(_internal.currentWebView.profile);
tabs.currentIndex = tabs.count - 1;
request.openIn(tab.item);
} else if (request.destination === WebEngineView.NewViewInBackgroundTab) {
var backgroundTab = tabs.createEmptyTab(_internal.currentWebView.profile);
request.openIn(backgroundTab.item);
// Disabling popups temporarily since we need to set that webengineview settings / channel and other properties
/*} else if (request.destination === WebEngineView.NewViewInDialog) {
var dialog = browserDialogComponent.createObject();
dialog.currentWebView.profile = currentWebView.profile;
dialog.currentWebView.webChannel = channel;
request.openIn(dialog.currentWebView);*/
} else {
// Instead of opening a new window, we open a new tab
// TODO: remove "open in new window" from context menu
var tab = tabs.createEmptyTab(_internal.currentWebView.profile);
tabs.currentIndex = tabs.count - 1;
request.openIn(tab.item);
}
}
onCertificateError: function(error) {
error.defer();
sslDialog.enqueue(error);
}
onJavaScriptDialogRequested: function(request) {
request.accepted = true;
var dialog = _internal.jsDialogComponent.createObject(browserWindow, {"request": request});
dialog.open();
}
}
}
Connections {
target: currentWebView
target: _internal.currentWebView
onUrlChanged: {
browserHeader.addressBar.text = Web3ProviderStore.obtainAddress(currentWebView.url)
browserHeader.addressBar.text = Web3ProviderStore.obtainAddress(_internal.currentWebView.url)
}
}
Connections {
target: BookmarksStore.bookmarksModel
onModelChanged: {
browserHeader.currentFavorite = Qt.binding(function () {return BookmarksStore.getCurrentFavorite(currentWebView.url)})
browserHeader.currentFavorite = Qt.binding(function () {return BookmarksStore.getCurrentFavorite(_internal.currentWebView.url)})
}
}
}

View File

@ -5,13 +5,11 @@ import Qt.labs.settings 1.0
import QtQuick.Controls.Styles 1.0
import QtWebEngine 1.10
import utils 1.0
import shared.controls 1.0
import StatusQ.Controls 0.1 as StatusQControls
import StatusQ.Controls 0.1
import shared 1.0
import shared.panels 1.0
import shared.status 1.0
import shared.controls 1.0
import utils 1.0
import "../popups"
import "../controls"
@ -22,13 +20,29 @@ Rectangle {
property alias favoriteComponent: favoritesBarLoader.sourceComponent
property alias addressBar: addressBar
readonly property int innerMargin: 12
property var currentUrl
property bool isLoading: false
property bool canGoBack: false
property bool canGoForward: false
property var currentFavorite
property var addNewTab: function () {}
property bool currentTabConnected: false
property string dappBrowserAccName: ""
property string dappBrowserAccIcon: ""
property var settingMenu
property var walletMenu
signal addNewFavoritelClicked(var xPos)
signal launchInBrowser(var url)
signal openHistoryPopup(var xPos, var yPos)
signal goForward()
signal goBack()
signal reload()
signal stopLoading()
QtObject {
id: _internal
readonly property int innerMargin: 12
}
width: parent.width
height: barRow.height + (favoritesBarLoader.active ? favoritesBarLoader.height : 0)
@ -39,29 +53,9 @@ Rectangle {
id: barRow
width: parent.width
height: 45
spacing: browserHeader.innerMargin
spacing: _internal.innerMargin
Menu {
id: historyMenu
Instantiator {
model: currentWebView && currentWebView.navigationHistory.items
MenuItem {
text: model.title
onTriggered: currentWebView.goBackOrForward(model.offset)
checkable: !enabled
checked: !enabled
enabled: model.offset
}
onObjectAdded: function(index, object) {
historyMenu.insertItem(index, object)
}
onObjectRemoved: function(index, object) {
historyMenu.removeItem(object)
}
}
}
StatusQControls.StatusFlatRoundButton {
StatusFlatRoundButton {
id: backButton
Layout.preferredWidth: 32
Layout.preferredHeight: 32
@ -69,18 +63,18 @@ Rectangle {
icon.width: 20
icon.name: "left"
icon.disabledColor: Style.current.lightGrey
type: StatusQControls.StatusFlatRoundButton.Type.Tertiary
enabled: currentWebView && currentWebView.canGoBack
Layout.leftMargin: browserHeader.innerMargin
onClicked: currentWebView.goBack()
type: StatusFlatRoundButton.Type.Tertiary
enabled: canGoBack
Layout.leftMargin: _internal.innerMargin
onClicked: goBack()
onPressAndHold: {
if (currentWebView && (currentWebView.canGoBack || currentWebView.canGoForward)){
historyMenu.popup(backButton.x, backButton.y + backButton.height)
if (canGoBack || canGoForward) {
openHistoryPopup(backButton.x, backButton.y + backButton.height)
}
}
}
StatusQControls.StatusFlatRoundButton {
StatusFlatRoundButton {
id: forwardButton
Layout.preferredWidth: 32
Layout.preferredHeight: 32
@ -88,13 +82,13 @@ Rectangle {
icon.height: 20
icon.name: "right"
icon.disabledColor: Style.current.lightGrey
type: StatusQControls.StatusFlatRoundButton.Type.Tertiary
enabled: currentWebView && currentWebView.canGoForward
Layout.leftMargin: -browserHeader.innerMargin/2
onClicked: currentWebView.goForward()
type: StatusFlatRoundButton.Type.Tertiary
enabled: canGoForward
Layout.leftMargin: -_internal.innerMargin/2
onClicked: goForward()
onPressAndHold: {
if (currentWebView && (currentWebView.canGoBack || currentWebView.canGoForward)){
historyMenu.popup(forwardButton.x, forwardButton.y + forwardButton.height)
if (canGoBack || canGoForward) {
openHistoryPopup(backButton.x, backButton.y + backButton.height)
}
}
}
@ -123,81 +117,39 @@ Rectangle {
}
Keys.onPressed: {
// TODO: disable browsing local files? file://
if (event.key === Qt.Key_Enter || event.key === Qt.Key_Return) {
if (localAccountSensitiveSettings.useBrowserEthereumExplorer !== Constants.browserEthereumExplorerNone && text.startsWith("0x")) {
switch (localAccountSensitiveSettings.useBrowserEthereumExplorer) {
case Constants.browserEthereumExplorerEtherscan:
if (text.length > 42) {
currentWebView.url = "https://etherscan.io/tx/" + text; break;
} else {
currentWebView.url = "https://etherscan.io/address/" + text; break;
}
case Constants.browserEthereumExplorerEthplorer:
if (text.length > 42) {
currentWebView.url = "https://ethplorer.io/tx/" + text; break;
} else {
currentWebView.url = "https://ethplorer.io/address/" + text; break;
}
case Constants.browserEthereumExplorerBlockchair:
if (text.length > 42) {
currentWebView.url = "https://blockchair.com/ethereum/transaction/" + text; break;
} else {
currentWebView.url = "https://blockchair.com/ethereum/address/" + text; break;
}
}
return
}
if (localAccountSensitiveSettings.shouldShowBrowserSearchEngine !== Constants.browserSearchEngineNone && !Utils.isURL(text) && !Utils.isURLWithOptionalProtocol(text)) {
switch (localAccountSensitiveSettings.shouldShowBrowserSearchEngine) {
case Constants.browserSearchEngineGoogle: currentWebView.url = "https://www.google.com/search?q=" + text; break;
case Constants.browserSearchEngineYahoo: currentWebView.url = "https://search.yahoo.com/search?p=" + text; break;
case Constants.browserSearchEngineDuckDuckGo: currentWebView.url = "https://duckduckgo.com/?q=" + text; break;
}
return
} else if (Utils.isURLWithOptionalProtocol(text)) {
text = "https://" + text
}
currentWebView.url = determineRealURL(text);
launchInBrowser(text)
}
}
StatusQControls.StatusFlatRoundButton {
StatusFlatRoundButton {
id: addFavoriteBtn
width: 24
height: 24
anchors.verticalCenter: parent.verticalCenter
anchors.right: reloadBtn.left
anchors.rightMargin: Style.current.halfPadding
visible: !!currentWebView && !!currentWebView.url
visible: !!currentUrl
icon.source: !!browserHeader.currentFavorite ? Style.svg("browser/favoriteActive") : Style.svg("browser/favorite")
color: "transparent"
type: StatusQControls.StatusFlatRoundButton.Type.Tertiary
type: StatusFlatRoundButton.Type.Tertiary
onClicked: addNewFavoritelClicked(addFavoriteBtn.x)
}
StatusQControls.StatusFlatRoundButton {
StatusFlatRoundButton {
id: reloadBtn
width: 24
height: 24
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
anchors.rightMargin: Style.current.halfPadding
icon.name: currentWebView && currentWebView.loading ? "close-circle" : "refresh"
icon.name: isLoading ? "close-circle" : "refresh"
color: "transparent"
type: StatusQControls.StatusFlatRoundButton.Type.Tertiary
onClicked: currentWebView && currentWebView.loading ? currentWebView.stop() : currentWebView.reload()
type: StatusFlatRoundButton.Type.Tertiary
onClicked: isLoading ? stopLoading(): reload()
}
}
BrowserWalletMenu {
id: browserWalletMenu
y: browserHeader.height + browserHeader.anchors.topMargin
x: parent.width - width - Style.current.halfPadding
}
Loader {
active: true
sourceComponent: currentTabConnected ? connectedBtnComponent : notConnectedBtnCompoent
@ -205,19 +157,19 @@ Rectangle {
Component {
id: notConnectedBtnCompoent
StatusQControls.StatusFlatRoundButton {
StatusFlatRoundButton {
id: accountBtn
width: 24
height: 24
icon.width: 24
icon.height: 24
icon.name: "filled-account"
type: StatusQControls.StatusFlatRoundButton.Type.Tertiary
type: StatusFlatRoundButton.Type.Tertiary
onClicked: {
if (browserWalletMenu.opened) {
browserWalletMenu.close()
if (walletMenu.opened) {
walletMenu.close()
} else {
browserWalletMenu.open()
walletMenu.open()
}
}
}
@ -225,7 +177,7 @@ Rectangle {
Component {
id: connectedBtnComponent
StatusQControls.StatusFlatButton {
StatusFlatButton {
id: accountBtnConnected
icon.name: "wallet"
icon.width: 18
@ -233,36 +185,29 @@ Rectangle {
icon.color: dappBrowserAccIcon
text: dappBrowserAccName
onClicked: {
if (browserWalletMenu.opened) {
browserWalletMenu.close()
if (walletMenu.opened) {
walletMenu.close()
} else {
browserWalletMenu.open()
walletMenu.open()
}
}
}
}
BrowserSettingsMenu {
id: settingsMenu
addNewTab: browserHeader.addNewTab
x: parent.width - width
y: parent.height
}
StatusQControls.StatusFlatRoundButton {
StatusFlatRoundButton {
id: settingsMenuButton
Layout.preferredHeight: 32
Layout.preferredWidth: 32
icon.width: 24
icon.height: 24
icon.name: "more"
type: StatusQControls.StatusFlatRoundButton.Type.Tertiary
Layout.rightMargin: browserHeader.innerMargin
type: StatusFlatRoundButton.Type.Tertiary
Layout.rightMargin: _internal.innerMargin
onClicked: {
if (settingsMenu.opened) {
settingsMenu.close()
if (settingMenu.opened) {
settingMenu.close()
} else {
settingsMenu.open()
settingMenu.open()
}
}
}

View File

@ -1,5 +1,4 @@
import QtQuick 2.13
import QtQuick.Controls 2.13
import QtQuick.Controls 1.0 as QQC1
import "../controls/styles"
@ -7,8 +6,12 @@ import "../controls/styles"
QQC1.TabView {
id: tabs
property int tabHeight: 40
property var currentWebEngineProfile
property var tabComponent
property var determineRealURL: function(url) {}
readonly property int tabHeight: 40
signal openNewTabTriggered()
function createEmptyTab(profile, createAsStartPage) {
var tab = addTab("", tabComponent);
@ -55,28 +58,20 @@ QQC1.TabView {
return -1
}
function openNewTabClicked() {
openNewTabTriggered()
}
function removeView(index) {
if (tabs.count === 1) {
tabs.createEmptyTab(currentWebView.profile, true)
tabs.createEmptyTab(currentWebEngineProfile, true)
}
tabs.removeTab(index)
}
function openNewTabClicked() {
addNewTab()
}
function closeButtonClicked(index) {
removeView(index)
}
Component.onCompleted: {
defaultProfile.downloadRequested.connect(onDownloadRequested);
otrProfile.downloadRequested.connect(onDownloadRequested);
var tab = createEmptyTab(defaultProfile);
// For Devs: Uncomment the next lien if you want to use the simpeldapp on first load
// tab.item.url = Web3ProviderStore.determineRealURL("https://simpledapp.eth");
}
style: BrowserTabStyle {}
}

View File

@ -5,9 +5,6 @@ import utils 1.0
import StatusQ.Controls 0.1
import shared 1.0
import shared.status 1.0
import "../controls"
Rectangle {
@ -16,8 +13,10 @@ Rectangle {
property bool isVisible: false
property var downloadsModel
property var downloadsMenu
signal openDownloadClicked(bool downloadComplete, int index)
signal addNewDownloadTab()
visible: isVisible && !!listView.count
color: Style.current.background
@ -78,15 +77,15 @@ Rectangle {
openDownloadClicked(downloadComplete, index)
}
onOptionsButtonClicked: {
downloadMenu.index = index
downloadMenu.downloadComplete = Qt.binding(function() {return downloadElement.downloadComplete})
downloadMenu.x = listView.width + downloadElement.x + 50
downloadMenu.y = downloadBar.y - downloadMenu.height
downloadMenu.open()
downloadsMenu.index = index
downloadsMenu.downloadComplete = Qt.binding(function() {return downloadElement.downloadComplete})
downloadsMenu.parent = downloadElement
downloadsMenu.x = xVal + 20
downloadsMenu.y = -downloadsMenu.height
downloadsMenu.open()
}
Connections {
target: downloadMenu
target: downloadsMenu
onCancelClicked: {
isCanceled = true
}

View File

@ -1,20 +1,16 @@
import QtQuick 2.1
import QtQuick.Controls 1.0
import QtQuick.Controls.Styles 1.0
import QtWebEngine 1.9
import QtQuick.Layouts 1.0
import shared 1.0
import shared.status 1.0
import "../controls"
import utils 1.0
Rectangle {
import "../controls"
Rectangle {
id: downloadView
property alias downloadsModel: listView.model
property var downloadsMenu
signal openDownloadClicked(bool downloadComplete, int index)
color: Style.current.background
@ -56,15 +52,15 @@ Rectangle {
openDownloadClicked(downloadComplete, index)
}
onOptionsButtonClicked: {
downloadMenu.index = index
downloadMenu.downloadComplete = Qt.binding(function() {return downloadElement.downloadComplete})
downloadMenu.x = xVal + 80
downloadMenu.y = listView.y + downloadElement.y + downloadElement.height
downloadMenu.open()
downloadsMenu.index = index
downloadsMenu.downloadComplete = Qt.binding(function() {return downloadElement.downloadComplete})
downloadsMenu.parent = downloadElement
downloadsMenu.x = xVal
downloadsMenu.y = downloadView.y - downloadsMenu.height
downloadsMenu.open()
}
Connections {
target: downloadMenu
target: downloadsMenu
onCancelClicked: {
isCanceled = true
}

View File

@ -10,6 +10,10 @@ RowLayout {
property alias bookmarkModel: bookmarkList.model
property var favoritesMenu
property var setAsCurrentWebUrl: function(url){}
property var addFavModal: function(){}
spacing: 0
height: 38
@ -41,22 +45,19 @@ RowLayout {
}
if (mouse.button === Qt.RightButton) {
favoriteMenu.url = url
favoriteMenu.x = favoriteBtn.x + mouse.x
favoriteMenu.y = Qt.binding(function () {return mouse.y + favoriteMenu.height})
favoriteMenu.open()
favoritesMenu.url = url
favoritesMenu.x = favoriteBtn.x + mouse.x
favoritesMenu.y = Qt.binding(function () {return mouse.y + favoritesMenu.height})
favoritesMenu.open()
return
}
if (isAddBookmarkButton) {
addFavoriteModal.toolbarMode = true
addFavoriteModal.ogUrl = browserHeader.currentFavorite ? browserHeader.currentFavorite.url : currentWebView.url
addFavoriteModal.ogName = browserHeader.currentFavorite ? browserHeader.currentFavorite.name : currentWebView.title
addFavoriteModal.open()
addFavModal()
return
}
currentWebView.url = determineRealURL(url)
setAsCurrentWebUrl(url)
}
}
}

View File

@ -1,31 +1,37 @@
import QtQuick 2.13
import shared 1.0
import shared.status 1.0
import "../controls"
import utils 1.0
import "../controls"
GridView {
id: bookmarkGrid
property var determineRealURLFn: function(url){}
property var setAsCurrentWebUrl: function(url){}
property var favMenu
property var addFavModal
cellWidth: 100
cellHeight: 100
delegate: BookmarkButton {
id: bookmarkBtn
text: name
source: imageUrl
webUrl: determineRealURL(url)
webUrl: determineRealURLFn(url)
onClicked: {
if (!webUrl.toString()) {
addFavoriteModal.open()
addFavModal.open()
} else {
currentWebView.url = webUrl
setAsCurrentWebUrl(webUrl)
}
}
onRightClicked: {
favoriteMenu.url = url
favoriteMenu.x = bookmarkGrid.x + bookmarkBtn.x + mouse.x
favoriteMenu.y = Qt.binding(function () {return bookmarkGrid.y + mouse.y + favoriteMenu.height})
favoriteMenu.open()
favMenu.url = url
favMenu.x = bookmarkGrid.x + bookmarkBtn.x + mouse.x
favMenu.y = Qt.binding(function () {return bookmarkGrid.y + mouse.y + favMenu.height})
favMenu.open()
}
}
}

View File

@ -53,15 +53,12 @@ import QtQuick.Controls 2.13
import QtGraphicalEffects 1.13
import QtQuick.Layouts 1.0
import StatusQ.Controls 0.1
import shared.controls 1.0
import shared 1.0
import shared.panels 1.0
import utils 1.0
import StatusQ.Controls 0.1
Rectangle {
id: root

View File

@ -1,17 +1,14 @@
import QtQuick 2.13
import QtQuick.Controls 2.13
import QtQuick.Layouts 1.13
import QtGraphicalEffects 1.13
import utils 1.0
import shared.controls 1.0
import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1
import StatusQ.Controls.Validators 0.1
import shared 1.0
import shared.popups 1.0
import utils 1.0
import "../stores"
// TODO: replace with StatusModal

View File

@ -3,7 +3,6 @@ import QtQuick.Controls 2.13
import QtQuick.Layouts 1.13
import utils 1.0
import shared.controls 1.0
import shared.panels 1.0
import StatusQ.Controls 0.1
@ -14,13 +13,13 @@ import "../controls"
import "../stores"
StatusModal {
id: browserConnectionModal
property var currentTab
property var request: ({"hostname": "", "title": "", "permission": ""})
property string currentAddress: ""
property bool interactedWith: false
id: browserConnectionModal
property var web3Response: function(){}
width: 360
height: 480
@ -31,16 +30,14 @@ StatusModal {
function postMessage(isAllowed){
interactedWith = true
currentTabConnected = isAllowed
if(isAllowed){
Web3ProviderStore.addPermission(request.hostname, request.permission)
}
provider.web3Response(Web3ProviderStore.web3ProviderInst.postMessage("api-request", JSON.stringify(request)));
request.isAllowed = isAllowed;
RootStore.currentTabConnected = isAllowed
web3Response(Web3ProviderStore.web3ProviderInst.postMessage(JSON.stringify(request)))
}
onClosed: {
if(!interactedWith){
currentTabConnected = false
RootStore.currentTabConnected = false
postMessage(false);
}
}

View File

@ -1,18 +1,28 @@
import QtQuick 2.13
import QtQuick.Controls 2.3
import QtWebEngine 1.9
import utils 1.0
import shared 1.0
import shared.panels 1.0
import shared.status 1.0
import shared.popups 1.0
import "../../Chat/popups"
import utils 1.0
// TODO: replace with StatusPopupMenu
PopupMenu {
property var addNewTab: function () {}
id: browserSettingsMenu
property bool isIncognito: false
signal addNewTab()
signal goIncognito(bool checked)
signal zoomIn()
signal zoomOut()
signal changeZoomFactor()
signal launchFindBar()
signal toggleCompatibilityMode(bool checked)
signal launchBrowserSettings()
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent
@ -20,9 +30,7 @@ PopupMenu {
//% "New Tab"
text: qsTrId("new-tab")
shortcut: StandardKey.AddTab
onTriggered: {
addNewTab()
}
onTriggered: addNewTab()
}
Action {
@ -34,12 +42,8 @@ PopupMenu {
//% "Go Incognito"
qsTrId("go-incognito")
checkable: true
checked: currentWebView && currentWebView.profile === otrProfile
onToggled: function(checked) {
if (currentWebView) {
currentWebView.profile = checked ? otrProfile : defaultProfile;
}
}
checked: isIncognito
onToggled: goIncognito(checked)
}
Separator {}
@ -49,23 +53,19 @@ PopupMenu {
//% "Zoom In"
text: qsTrId("zoom-in")
shortcut: StandardKey.ZoomIn
onTriggered: {
const newZoom = currentWebView.zoomFactor + 0.1
currentWebView.changeZoomFactor(newZoom)
}
onTriggered: zoomIn()
}
Action {
//% "Zoom Out"
text: qsTrId("zoom-out")
shortcut: StandardKey.ZoomOut
onTriggered: {
const newZoom = currentWebView.zoomFactor - 0.1
currentWebView.changeZoomFactor(newZoom)
}
onTriggered: zoomOut()
}
Action {
shortcut: "Ctrl+0"
onTriggered: currentWebView.changeZoomFactor(1.0)
onTriggered: changeZoomFactor()
}
Separator {}
@ -74,12 +74,7 @@ PopupMenu {
//% "Find"
text: qsTrId("find")
shortcut: StandardKey.Find
onTriggered: {
if (!findBar.visible) {
findBar.visible = true;
findBar.forceActiveFocus()
}
}
onTriggered: launchFindBar()
}
Action {
@ -87,18 +82,7 @@ PopupMenu {
text: qsTrId("compatibility-mode")
checkable: true
checked: true
onToggled: {
for (let i = 0; i < tabs.count; ++i){
tabs.getTab(i).item.stop(); // Stop all loading tabs
}
localAccountSensitiveSettings.compatibilityMode = checked;
for (let i = 0; i < tabs.count; ++i){
tabs.getTab(i).item.reload(); // Reload them with new user agent
}
}
onToggled: toggleCompatibilityMode(checked)
}
Action {
@ -116,11 +100,6 @@ PopupMenu {
//% "Settings"
text: qsTrId("settings")
shortcut: "Ctrl+,"
onTriggered: {
Global.changeAppSectionBySectionType(Constants.appSection.profile)
// TODO: replace with shared store constant
// Profile/RootStore.browser_settings_id
profileLayoutContainer.changeProfileSection(10)
}
onTriggered: launchBrowserSettings()
}
}

View File

@ -3,11 +3,12 @@ import QtQuick.Controls 2.13
import QtQuick.Layouts 1.13
import QtGraphicalEffects 1.13
import utils 1.0
import shared.controls 1.0
import shared.panels 1.0
import StatusQ.Controls 0.1
import StatusQ.Core 0.1
import shared.controls 1.0
import utils 1.0
import "../../Wallet/views"
import "../stores"
@ -15,6 +16,11 @@ import "../stores"
// TODO: replace with StatusPopupMenu
Popup {
id: popup
signal sendTriggered(var selectedAccount)
signal disconnect()
signal reload()
modal: false
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
@ -26,7 +32,7 @@ Popup {
color: Style.current.background
radius: Style.current.radius
layer.enabled: true
layer.effect: DropShadow{
layer.effect: DropShadow {
width: bgPopup.width
height: bgPopup.height
x: bgPopup.x
@ -62,7 +68,7 @@ Popup {
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
StatusBaseText {
id: networkText
text: {
switch (RootStore.currentNetwork) {
@ -80,7 +86,7 @@ Popup {
anchors.leftMargin: Style.current.halfPadding
}
StyledText {
StatusBaseText {
id: disconectBtn
//% "Disconnect"
text: qsTrId("disconnect")
@ -92,11 +98,7 @@ Popup {
MouseArea {
cursorShape: Qt.PointingHandCursor
anchors.fill: parent
onClicked: {
Web3ProviderStore.web3ProviderInst.disconnect();
provider.postMessage("web3-disconnect-account", "{}");
popup.close();
}
onClicked: disconnect()
}
}
}
@ -131,10 +133,8 @@ Popup {
accountSelectorRow.currentAddress = selectedAccount.address
Web3ProviderStore.web3ProviderInst.dappsAddress = selectedAccount.address;
WalletStore.setDappBrowserAddress()
Web3ProviderStore.revokeAllPermissions();
for (let i = 0; i < tabs.count; ++i){
tabs.getTab(i).item.reload();
}
Web3ProviderStore.revokeAllPermissions()
reload()
}
}
@ -157,10 +157,7 @@ Popup {
anchors.top: parent.top
anchors.topMargin: Style.current.halfPadding
icon.name: "send"
onClicked: {
sendModal.selectedAccount = accountSelector.selectedAccount
sendModal.open()
}
onClicked: sendTriggered(accountSelector.selectedAccount)
}
}

View File

@ -1,13 +1,13 @@
import QtQuick 2.13
import QtQuick.Controls 2.3
import shared 1.0
import shared.panels 1.0
import shared.popups 1.0
import "../stores"
import utils 1.0
import "../stores"
// TODO: replace with StatusPopupMenu
PopupMenu {
id: downloadMenu

View File

@ -1,23 +1,23 @@
import QtQuick 2.13
import QtQuick.Controls 2.3
import QtWebEngine 1.9
import shared 1.0
import shared.panels 1.0
import shared.status 1.0
import shared.popups 1.0
import "../stores"
import utils 1.0
import "../../Chat/popups"
import "../stores"
// TODO: replace with StatusPopupMenu
PopupMenu {
id: favoritePopupMenu
property var openInNewTab: function () {}
property string url
property var currentFavorite: BookmarksStore.getCurrentFavorite(url)
id: root
signal editFavoriteTriggered()
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
Action {
@ -27,7 +27,7 @@ PopupMenu {
icon.width: 16
icon.height: 16
onTriggered: {
openInNewTab(root.url)
openInNewTab(favoritePopupMenu.url)
}
}
@ -39,12 +39,7 @@ PopupMenu {
icon.source: Style.svg("edit")
icon.width: 16
icon.height: 16
onTriggered: {
addFavoriteModal.modifiyModal = true
addFavoriteModal.ogUrl = root.currentFavorite ? root.currentFavorite.url : currentWebView.url
addFavoriteModal.ogName = root.currentFavorite ? root.currentFavorite.name : currentWebView.title
addFavoriteModal.open()
}
onTriggered: editFavoriteTriggered()
}
Action {
@ -55,7 +50,7 @@ PopupMenu {
icon.width: 16
icon.height: 16
onTriggered: {
BookmarksStore.deleteBookmark(root.url)
BookmarksStore.deleteBookmark(favoritePopupMenu.url)
}
}
}

View File

@ -239,9 +239,4 @@ StatusModal {
]
}
/*##^##
Designer {
D{i:0;autoSize:true;height:480;width:640}
}
##^##*/

View File

@ -5,7 +5,6 @@ import QtQuick 2.13
QtObject {
id: root
// Seems like this vould be a BookMarks Store which has everything related to bookmarks
property var bookmarksModel: bookmarkModule.model
function addBookmark(url, name)
@ -43,5 +42,4 @@ QtObject {
image: bookmarkModule.model.rowData(index, 'imageUrl')
}
}
// END >> Seems like this vould be a BookMarks Store which has everything related to bookmarks
}

View File

@ -2,6 +2,8 @@ pragma Singleton
import QtQuick 2.13
import utils 1.0
QtObject {
id: root
@ -9,6 +11,8 @@ QtObject {
property var currentNetwork: profileModel.network.current
property bool currentTabConnected: false
function getUrlFromUserInput(input) {
return utilsModel.urlFromUserInput(input)
}
@ -29,11 +33,38 @@ QtObject {
return utilsModel.generateIdenticon(pk)
}
function getEth2Hex(eth) {
return utilsModel.eth2Hex(eth)
function get0xFormedUrl(browserExplorer, url) {
var tempUrl = ""
switch (browserExplorer) {
case Constants.browserEthereumExplorerEtherscan:
if (url.length > 42) {
tempUrl = "https://etherscan.io/tx/" + url; break;
} else {
tempUrl = "https://etherscan.io/address/" + url; break;
}
case Constants.browserEthereumExplorerEthplorer:
if (url.length > 42) {
tempUrl = "https://ethplorer.io/tx/" + url; break;
} else {
tempUrl = "https://ethplorer.io/address/" + url; break;
}
case Constants.browserEthereumExplorerBlockchair:
if (url.length > 42) {
tempUrl = "https://blockchair.com/ethereum/transaction/" + url; break;
} else {
tempUrl = "https://blockchair.com/ethereum/address/" + url; break;
}
}
return tempUrl
}
function getGwei2Hex(gwei){
return utilsModel.gwei2Hex(gwei)
function getFormedUrl(shouldShowBrowserSearchEngine, url) {
var tempUrl = ""
switch (localAccountSensitiveSettings.shouldShowBrowserSearchEngine) {
case Constants.browserSearchEngineGoogle: tempUrl = "https://www.google.com/search?q=" + url; break;
case Constants.browserSearchEngineYahoo: tempUrl = "https://search.yahoo.com/search?p=" + url; break;
case Constants.browserSearchEngineDuckDuckGo: tempUrl = "https://duckduckgo.com/?q=" + url; break;
}
return tempUrl
}
}

View File

@ -50,8 +50,18 @@
import QtQuick 2.13
import QtQuick.Controls 2.14
import QtWebEngine 1.10
Item {
id: shortcutActions
property var currentWebView
property var findBarComponent
property var browserHeaderComponent
signal addNewDownloadTab()
signal removeView()
Action {
shortcut: "Ctrl+D"
onTriggered: {
@ -61,8 +71,8 @@ Item {
Action {
shortcut: "Ctrl+L"
onTriggered: {
browserHeader.addressBar.forceActiveFocus();
browserHeader.addressBar.selectAll();
browserHeaderComponent.addressBar.forceActiveFocus();
browserHeaderComponent.addressBar.selectAll();
}
}
Action {
@ -74,9 +84,7 @@ Item {
}
Action {
shortcut: "Ctrl+W"
onTriggered: {
tabs.removeView(tabs.currentIndex)
}
onTriggered: removeView()
}
Action {
shortcut: StandardKey.Close
@ -87,8 +95,8 @@ Item {
Action {
shortcut: "Escape"
onTriggered: {
if (findBar.visible)
findBar.visible = false;
if (findBarComponent.visible)
findBarComponent.visible = false;
}
}
Action {
@ -129,10 +137,10 @@ Item {
}
Action {
shortcut: StandardKey.FindNext
onTriggered: findBar.findNext()
onTriggered: findBarComponent.findNext()
}
Action {
shortcut: StandardKey.FindPrevious
onTriggered: findBar.findPrevious()
onTriggered: findBarComponent.findPrevious()
}
}

View File

@ -2,26 +2,25 @@ import QtQuick 2.13
import QtWebEngine 1.10
import shared.controls 1.0
import "../panels"
import "../stores"
import utils 1.0
import "../panels"
import "../stores"
WebEngineView {
id: webEngineView
anchors.top: parent.top
anchors.topMargin: browserHeader.height
property var currentWebView
property var findBarComp
property var favMenu
property var addFavModal
property var downloadsMenu
property var determineRealURLFn: function(url){}
signal setCurrentWebUrl(var url)
focus: true
webChannel: channel
onLinkHovered: function(hoveredUrl) {
if (hoveredUrl === "")
hideStatusText.start();
else {
statusText.text = hoveredUrl;
statusBubble.visible = true;
hideStatusText.stop();
}
}
function changeZoomFactor(newFactor) {
// FIXME there seems to be a bug in the WebEngine where the zoomFactor only update 1/2 times
@ -40,42 +39,6 @@ WebEngineView {
settings.pdfViewerEnabled: localAccountSensitiveSettings.pdfViewerEnabled
settings.focusOnNavigationEnabled: true
onCertificateError: function(error) {
error.defer();
sslDialog.enqueue(error);
}
onJavaScriptDialogRequested: function(request) {
request.accepted = true;
var dialog = jsDialogComponent.createObject(browserWindow, {"request": request});
dialog.open();
}
onNewViewRequested: function(request) {
if (!request.userInitiated) {
print("Warning: Blocked a popup window.");
} else if (request.destination === WebEngineView.NewViewInTab) {
var tab = tabs.createEmptyTab(currentWebView.profile);
tabs.currentIndex = tabs.count - 1;
request.openIn(tab.item);
} else if (request.destination === WebEngineView.NewViewInBackgroundTab) {
var backgroundTab = tabs.createEmptyTab(currentWebView.profile);
request.openIn(backgroundTab.item);
// Disabling popups temporarily since we need to set that webengineview settings / channel and other properties
/*} else if (request.destination === WebEngineView.NewViewInDialog) {
var dialog = browserDialogComponent.createObject();
dialog.currentWebView.profile = currentWebView.profile;
dialog.currentWebView.webChannel = channel;
request.openIn(dialog.currentWebView);*/
} else {
// Instead of opening a new window, we open a new tab
// TODO: remove "open in new window" from context menu
var tab = tabs.createEmptyTab(currentWebView.profile);
tabs.currentIndex = tabs.count - 1;
request.openIn(tab.item);
}
}
onQuotaRequested: function(request) {
if (request.requestedSize <= 5 * 1024 * 1024)
request.accept();
@ -110,23 +73,21 @@ WebEngineView {
reloadTimer.running = true;
}
onWindowCloseRequested: tabs.removeView(tabs.indexOfView(webEngineView))
onSelectClientCertificate: function(selection) {
selection.certificates[0].select();
}
onFindTextFinished: function(result) {
if (!findBar.visible)
findBar.visible = true;
if (!findBarComp.visible)
findBarComp.visible = true;
findBar.numberOfMatches = result.numberOfMatches;
findBar.activeMatch = result.activeMatch;
findBarComp.numberOfMatches = result.numberOfMatches;
findBarComp.activeMatch = result.activeMatch;
}
onLoadingChanged: function(loadRequest) {
if (loadRequest.status === WebEngineView.LoadStartedStatus)
findBar.reset();
findBarComp.reset();
}
onNavigationRequested: {
@ -144,6 +105,7 @@ WebEngineView {
sourceComponent: DownloadView {
id: downloadView
downloadsModel: DownloadsStore.downloadModel
downloadsMenu: webEngineView.downloadsMenu
onOpenDownloadClicked: {
if (downloadComplete) {
return DownloadsStore.openFile(index)
@ -181,6 +143,14 @@ WebEngineView {
width: (parent.width < 700) ? (Math.floor(parent.width/cellWidth)*cellWidth) : 700
height: parent.height - emptyPageImage.height - 20
model: BookmarksStore.bookmarksModel
favMenu: webEngineView.favMenu
addFavModal: webEngineView.addFavModal
determineRealURLFn: function(url) {
return webEngineView.determineRealURLFn(url)
}
setAsCurrentWebUrl: function(url) {
webEngineView.setCurrentWebUrl(url)
}
Component.onCompleted: {
// Add fav button at the end of the grid
var index = BookmarksStore.getBookmarkIndexByUrl(Constants.newBookmark)

View File

@ -1,5 +1,6 @@
import QtQuick 2.13
import QtWebChannel 1.13
import QtQuick.Dialogs 1.2
import utils 1.0
import shared.controls 1.0
@ -8,12 +9,17 @@ import "../stores"
QtObject {
id: provider
WebChannel.id: "backend"
property var createAccessDialogComponent: function(){}
property var createSendTransactionModalComponent: function(){}
property var createSignMessageModalComponent: function(){}
property var showSendingError: function(){}
property var showSigningError: function(){}
property var showToastMessage: function(){}
property int networkId: (Web3ProviderStore && Web3ProviderStore.networkId) || -1
signal web3Response(string data);
property int networkId: (Web3ProviderStore && Web3ProviderStore.networkId) || -1
function signValue(input){
if(Utils.isHex(input) && Utils.startsWith0x(input)){
return input
@ -21,7 +27,7 @@ QtObject {
return RootStore.getAscii2Hex(input)
}
function postMessage(requestType, data) {
function postMessage(data) {
var request;
try {
request = JSON.parse(data)
@ -34,62 +40,33 @@ QtObject {
if (ensAddr) {
request.hostname = ensAddr;
}
if (requestType === Constants.web3DisconnectAccount) {
browserWindow.currentTabConnected = true
web3Response(JSON.stringify({type: Constants.web3DisconnectAccount}));
} else if (requestType === Constants.api_request) {
if (request.type === Constants.api_request) {
if (!Web3ProviderStore.web3ProviderInst.hasPermission(request.hostname, request.permission)) {
browserWindow.currentTabConnected = false
var dialog = accessDialogComponent.createObject(browserWindow);
RootStore.currentTabConnected = false
var dialog = createAccessDialogComponent()
dialog.request = request;
dialog.open();
} else {
browserWindow.currentTabConnected = true
web3Response(Web3ProviderStore.web3ProviderInst.postMessage(requestType, JSON.stringify(request)));
RootStore.currentTabConnected = true
request.isAllowed = true;
web3Response(Web3ProviderStore.web3ProviderInst.postMessage(JSON.stringify(request)));
}
} else if (requestType === Constants.web3SendAsyncReadOnly &&
} else if (request.type === Constants.web3SendAsyncReadOnly &&
request.payload.method === "eth_sendTransaction") {
var acc = WalletStore.dappBrowserAccount
const value = RootStore.getWei2Eth(request.payload.params[0].value, 18);
const sendDialog = sendTransactionModalComponent.createObject(browserWindow, {
trxData: request.payload.params[0].data || "",
selectedAccount: {
name: acc.name,
address: request.payload.params[0].from,
iconColor: acc.iconColor,
assets: acc.assets
},
selectedRecipient: {
address: request.payload.params[0].to,
identicon: RootStore.generateIdenticon(request.payload.params[0].to),
name: RootStore.activeChannelName,
type: RecipientSelector.Type.Address
},
selectedAsset: {
name: "ETH",
symbol: "ETH",
address: Constants.zeroAddress
},
selectedFiatAmount: "42", // TODO calculate that
selectedAmount: value
});
const sendDialog = createSendTransactionModalComponent(request)
// TODO change sendTransaction function to the postMessage one
sendDialog.sendTransaction = function (selectedGasLimit, selectedGasPrice, selectedTipLimit, selectedOverallLimit, enteredPassword) {
let trx = request.payload.params[0]
// TODO: use bignumber instead of floats
trx.value = RootStore.getEth2Hex(parseFloat(value))
trx.gas = "0x" + parseInt(selectedGasLimit, 10).toString(16)
if (walletModel.transactionsView.isEIP1559Enabled) {
trx.maxPriorityFeePerGas = RootStore.getGwei2Hex(parseFloat(selectedTipLimit))
trx.maxFeePerGas = RootStore.getGwei2Hex(parseFloat(selectedOverallLimit))
} else {
trx.gasPrice = RootStore.getGwei2Hex(parseFloat(selectedGasPrice))
}
request.payload.selectedGasLimit = selectedGasLimit
request.payload.selectedGasPrice = selectedGasPrice
request.payload.selectedTipLimit = selectedTipLimit
request.payload.selectedOverallLimit = selectedOverallLimit
request.payload.password = enteredPassword
request.payload.params[0] = trx
request.payload.params[0].value = value
const response = Web3ProviderStore.web3ProviderInst.postMessage(requestType, JSON.stringify(request))
const response = Web3ProviderStore.web3ProviderInst.postMessage(JSON.stringify(request))
provider.web3Response(response)
let responseObj
@ -99,22 +76,14 @@ QtObject {
if (responseObj.error) {
throw new Error(responseObj.error)
}
//% "Transaction pending..."
toastMessage.title = qsTrId("ens-transaction-pending")
toastMessage.source = Style.svg("loading")
toastMessage.iconColor = Style.current.primary
toastMessage.iconRotates = true
toastMessage.link = `${WalletStore.etherscanLink}/${responseObj.result.result}`
toastMessage.open()
showToastMessage(responseObj.result.result)
} catch (e) {
if (Utils.isInvalidPasswordMessage(e.message)){
//% "Wrong password"
sendDialog.transactionSigner.validationError = qsTrId("wrong-password")
return
}
sendingError.text = e.message
return sendingError.open()
return showSendingError(e.message)
}
sendDialog.close()
@ -123,14 +92,8 @@ QtObject {
sendDialog.open();
WalletStore.getGasPrice()
} else if (requestType === Constants.web3SendAsyncReadOnly && ["eth_sign", "personal_sign", "eth_signTypedData", "eth_signTypedData_v3"].indexOf(request.payload.method) > -1) {
const signDialog = signMessageModalComponent.createObject(browserWindow, {
request,
selectedAccount: {
name: WalletStore.dappBrowserAccount.name,
iconColor: WalletStore.dappBrowserAccount.iconColor
}
});
} else if (request.type === Constants.web3SendAsyncReadOnly && ["eth_sign", "personal_sign", "eth_signTypedData", "eth_signTypedData_v3"].indexOf(request.payload.method) > -1) {
const signDialog = createSignMessageModalComponent(request)
signDialog.web3Response = web3Response
signDialog.signMessage = function (enteredPassword) {
signDialog.interactedWith = true;
@ -141,12 +104,12 @@ QtObject {
case Constants.eth_sign:
request.payload.params[1] = signValue(request.payload.params[1]);
}
const response = Web3ProviderStore.web3ProviderInst.postMessage(requestType, JSON.stringify(request));
const response = Web3ProviderStore.web3ProviderInst.postMessage(JSON.stringify(request));
provider.web3Response(response);
try {
let responseObj = JSON.parse(response)
if (responseObj.error) {
throw new Error(responseObj.error.message)
throw new Error(responseObj.error)
}
} catch (e) {
if (Utils.isInvalidPasswordMessage(e.message)){
@ -154,8 +117,7 @@ QtObject {
signDialog.transactionSigner.validationError = qsTrId("wrong-password")
return
}
signingError.text = e.message
return signingError.open()
return showSigningError(e.message)
}
signDialog.close()
signDialog.destroy()
@ -166,7 +128,9 @@ QtObject {
} else if (request.type === Constants.web3DisconnectAccount) {
web3Response(data);
} else {
web3Response(Web3ProviderStore.web3ProviderInst.postMessage(requestType, data));
web3Response(Web3ProviderStore.web3ProviderInst.postMessage(data));
}
}
WebChannel.id: "backend"
}

View File

@ -439,6 +439,7 @@ Item {
id: browserLayoutComponent
BrowserLayout {
globalStore: appMain.rootStore
sendTransactionModal: sendModal
}
}
@ -751,6 +752,7 @@ Item {
// this.sourceComponent = undefined // kill an opened instance
this.active = false
}
property var selectedAccount
sourceComponent: SendModal {
store: appMain.rootStore
onOpened: {
@ -760,6 +762,11 @@ Item {
sendModal.closed()
}
}
onLoaded: {
if(!!sendModal.selectedAccount) {
item.selectFromAccount.selectedAccount = sendModal.selectedAccount
}
}
}
Action {