630 lines
21 KiB
JavaScript
630 lines
21 KiB
JavaScript
|
/* globals require, process */
|
||
|
/*eslint no-console: ["error", { allow: ["log", "error"] }] */
|
||
|
|
||
|
const { Menu, app, shell, dialog } = require('electron')
|
||
|
const fs = require('fs')
|
||
|
const fse = require('fs-extra')
|
||
|
const os = require('os')
|
||
|
const path = require('path')
|
||
|
const { openProcessManager } = require('electron-process-manager')
|
||
|
const main = require('./main.js')
|
||
|
|
||
|
let { thumbnail } = require('./utils.js')
|
||
|
const loadTests = require('./test.js')
|
||
|
const i18n = new (require('./i18n.js'))()
|
||
|
|
||
|
function selectURL(url) {
|
||
|
url = url.replace(/\\/g, '/')
|
||
|
console.log('selectURL', url)
|
||
|
main.win.loadURL(url)
|
||
|
main.store.set('url', url)
|
||
|
}
|
||
|
|
||
|
function findItems(key, value) {
|
||
|
let items = []
|
||
|
|
||
|
for (let i = 0; i < menu.items.length; i++) {
|
||
|
for (let j = 0; j < menu.items[i].submenu.items.length; j++) {
|
||
|
let item = menu.items[i].submenu.items[j]
|
||
|
if (item[key] === value) {
|
||
|
items.push(item)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return items
|
||
|
}
|
||
|
|
||
|
function findItem(key, value) {
|
||
|
return findItems(key, value)[0]
|
||
|
}
|
||
|
|
||
|
function toggleBookmarks(bookmark) {
|
||
|
let items = findItems('class', 'bookmark')
|
||
|
|
||
|
for (let i = 0; i < items.length; i++) {
|
||
|
items[i].checked = false
|
||
|
}
|
||
|
|
||
|
bookmark.checked = true
|
||
|
}
|
||
|
|
||
|
function checkBookmark(url) {
|
||
|
let items = findItems('url', url)
|
||
|
if (items.length === 1) {
|
||
|
toggleBookmarks(items[0])
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function setHistoryStatus() {
|
||
|
const historyBack = findItem('id', 'history-back')
|
||
|
historyBack.enabled = main.win.webContents.canGoBack()
|
||
|
|
||
|
const historyForward = findItem('id', 'history-forward')
|
||
|
historyForward.enabled = main.win.webContents.canGoForward()
|
||
|
}
|
||
|
|
||
|
function showSelectDataFolderDialog(focusedWindow) {
|
||
|
dialog.showOpenDialog(
|
||
|
{
|
||
|
title: i18n.__('selectfolder.select.title'),
|
||
|
buttonLabel: i18n.__('selectfolder.select.buttonLabel'),
|
||
|
properties: ['openDirectory', 'createDirectory', 'noResolveAliases', 'treatPackageAsDirectory']
|
||
|
},
|
||
|
(filePaths) => {
|
||
|
if (filePaths && filePaths.length === 1) {
|
||
|
const varPath = path.join(__dirname, '../var')
|
||
|
|
||
|
// Check if the same folder was used
|
||
|
if (filePaths[0].startsWith(varPath)) {
|
||
|
const same = filePaths[0] === varPath
|
||
|
|
||
|
dialog.showMessageBox(
|
||
|
{
|
||
|
type: 'error',
|
||
|
icon: path.join(__dirname, '../assets/icons/png/512x512-empty.png'),
|
||
|
buttons: [i18n.__('selectfolder.samefolder.ok')],
|
||
|
defaultId: 0,
|
||
|
message: i18n.__('selectfolder.samefolder.message'),
|
||
|
detail: same
|
||
|
? i18n.__('selectfolder.samefolder.detail.same')
|
||
|
: i18n.__('selectfolder.samefolder.detail.within'),
|
||
|
cancelId: 0
|
||
|
},
|
||
|
(response) => {
|
||
|
showSelectDataFolderDialog(focusedWindow)
|
||
|
}
|
||
|
)
|
||
|
} else {
|
||
|
// Backup
|
||
|
if (fse.pathExistsSync(varPath)) {
|
||
|
const varPathBackup = findNextVarFolder()
|
||
|
// Rename old var folder or link
|
||
|
fse.renameSync(varPath, varPathBackup)
|
||
|
} else {
|
||
|
// BUG: Workaround because pathExistsSync return false on existing symbolic links with a missing target
|
||
|
fse.removeSync(varPath)
|
||
|
}
|
||
|
|
||
|
// Add new symlink
|
||
|
main.store.set('dataFolder', filePaths[0])
|
||
|
fs.symlinkSync(filePaths[0], varPath, 'dir')
|
||
|
|
||
|
dialog.showMessageBox(
|
||
|
{
|
||
|
type: 'info',
|
||
|
icon: path.join(__dirname, '../assets/icons/png/link.png'),
|
||
|
buttons: [i18n.__('selectfolder.info.ok')],
|
||
|
defaultId: 0,
|
||
|
message: i18n.__('selectfolder.info.message'),
|
||
|
detail: i18n.__('selectfolder.info.detail').replace(/\$\{0\}/, filePaths[0]),
|
||
|
cancelId: 0
|
||
|
},
|
||
|
(response) => {
|
||
|
if (focusedWindow) focusedWindow.reload()
|
||
|
}
|
||
|
)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
)
|
||
|
}
|
||
|
|
||
|
function findNextVarFolder() {
|
||
|
let exists = true
|
||
|
let counter = 0
|
||
|
|
||
|
while (exists) {
|
||
|
counter++
|
||
|
exists = fse.pathExistsSync(path.join(__dirname, `../var${counter}`))
|
||
|
}
|
||
|
|
||
|
return path.join(__dirname, `../var${counter}`)
|
||
|
}
|
||
|
|
||
|
function showFolderBrowser(focusedWindow) {
|
||
|
const varPath = path.join(__dirname, '../var')
|
||
|
const varPathExists = fse.pathExistsSync(varPath)
|
||
|
if (varPathExists) {
|
||
|
dialog.showMessageBox(
|
||
|
{
|
||
|
type: 'warning',
|
||
|
icon: path.join(__dirname, '../assets/icons/png/512x512-empty.png'),
|
||
|
buttons: [i18n.__('selectfolder.warning.next'), i18n.__('selectfolder.warning.cancel')],
|
||
|
defaultId: 1,
|
||
|
message: i18n.__('selectfolder.warning.message'),
|
||
|
detail: i18n.__('selectfolder.warning.detail'),
|
||
|
cancelId: 1
|
||
|
},
|
||
|
(response) => {
|
||
|
if (response === 0) {
|
||
|
showSelectDataFolderDialog(focusedWindow)
|
||
|
}
|
||
|
}
|
||
|
)
|
||
|
} else {
|
||
|
showSelectDataFolderDialog(focusedWindow)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const template = [
|
||
|
{
|
||
|
label: i18n.__('edit'),
|
||
|
submenu: [
|
||
|
{
|
||
|
role: 'undo',
|
||
|
label: i18n.__('undo')
|
||
|
},
|
||
|
{
|
||
|
role: 'redo',
|
||
|
label: i18n.__('redo')
|
||
|
},
|
||
|
{
|
||
|
type: 'separator'
|
||
|
},
|
||
|
{
|
||
|
role: 'cut',
|
||
|
label: i18n.__('cut')
|
||
|
},
|
||
|
{
|
||
|
role: 'copy',
|
||
|
label: i18n.__('copy')
|
||
|
},
|
||
|
{
|
||
|
role: 'paste',
|
||
|
label: i18n.__('paste')
|
||
|
},
|
||
|
{
|
||
|
role: 'pasteandmatchstyle',
|
||
|
label: i18n.__('pasteandmatchstyle')
|
||
|
},
|
||
|
{
|
||
|
role: 'delete',
|
||
|
label: i18n.__('delete')
|
||
|
},
|
||
|
{
|
||
|
role: 'selectall',
|
||
|
label: i18n.__('selectall')
|
||
|
}
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
label: i18n.__('view'),
|
||
|
submenu: [
|
||
|
{
|
||
|
label: i18n.__('reload'),
|
||
|
accelerator: 'CmdOrCtrl+R',
|
||
|
click(item, focusedWindow) {
|
||
|
if (focusedWindow) {
|
||
|
focusedWindow.webContents.setVisualZoomLevelLimits(1, 1)
|
||
|
focusedWindow.reload()
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
{
|
||
|
id: 'forcereload',
|
||
|
label: i18n.__('forcereload'),
|
||
|
accelerator: 'CmdOrCtrl+Shift+R',
|
||
|
click(item, focusedWindow) {
|
||
|
if (focusedWindow) {
|
||
|
focusedWindow.webContents.session.clearCache(() => console.log('Cache cleared'))
|
||
|
|
||
|
focusedWindow.webContents.setVisualZoomLevelLimits(1, 1)
|
||
|
focusedWindow.reload()
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
{
|
||
|
type: 'separator'
|
||
|
},
|
||
|
{
|
||
|
role: 'resetzoom',
|
||
|
label: i18n.__('resetzoom')
|
||
|
},
|
||
|
{
|
||
|
role: 'zoomin',
|
||
|
label: i18n.__('zoomin')
|
||
|
},
|
||
|
{
|
||
|
role: 'zoomout',
|
||
|
label: i18n.__('zoomout')
|
||
|
},
|
||
|
{
|
||
|
type: 'separator'
|
||
|
},
|
||
|
{
|
||
|
id: 'togglefullscreen',
|
||
|
label: i18n.__('togglefullscreen'),
|
||
|
accelerator: process.platform === 'darwin' ? 'Cmd+Ctrl+F' : 'F11',
|
||
|
click(item, focusedWindow) {
|
||
|
if (focusedWindow) {
|
||
|
focusedWindow.setFullScreen(!focusedWindow.isFullScreen())
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
{
|
||
|
type: 'separator'
|
||
|
},
|
||
|
{
|
||
|
label: i18n.__('multiuserbrowser'),
|
||
|
accelerator: 'CmdOrCtrl+M',
|
||
|
type: 'checkbox',
|
||
|
checked: true,
|
||
|
click(item, focusedWindow) {
|
||
|
if (focusedWindow) {
|
||
|
main.store.set('multiUserBrowser', item.checked)
|
||
|
global.multiUserMode = item.checked
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
{
|
||
|
label: i18n.__('minimalpad'),
|
||
|
accelerator: 'CmdOrCtrl+p',
|
||
|
type: 'checkbox',
|
||
|
checked: true,
|
||
|
click(item, focusedWindow) {
|
||
|
if (focusedWindow) {
|
||
|
main.store.set('minimalPad', item.checked)
|
||
|
global.useMinimalPad = item.checked
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
label: i18n.__('history'),
|
||
|
submenu: [
|
||
|
{
|
||
|
id: 'history-back',
|
||
|
label: i18n.__('back'),
|
||
|
accelerator: 'CmdOrCtrl+Left',
|
||
|
click(item, focusedWindow) {
|
||
|
main.win.webContents.goBack()
|
||
|
}
|
||
|
},
|
||
|
{
|
||
|
id: 'history-forward',
|
||
|
label: i18n.__('forward'),
|
||
|
accelerator: 'CmdOrCtrl+Right',
|
||
|
click(item, focusedWindow) {
|
||
|
main.win.webContents.goForward()
|
||
|
}
|
||
|
},
|
||
|
{
|
||
|
label: i18n.__('home'),
|
||
|
accelerator: 'CmdOrCtrl+Up',
|
||
|
click(item, focusedWindow) {
|
||
|
main.win.webContents.goToIndex(0)
|
||
|
}
|
||
|
},
|
||
|
{
|
||
|
type: 'separator'
|
||
|
},
|
||
|
{
|
||
|
label: i18n.__('recentlyvisited'),
|
||
|
enabled: false
|
||
|
}
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
label: i18n.__('bookmarks'),
|
||
|
submenu: [
|
||
|
{
|
||
|
label: i18n.__('localfilesystem'),
|
||
|
class: 'bookmark',
|
||
|
type: 'checkbox',
|
||
|
url: `file://${__dirname}/../index.html`,
|
||
|
accelerator: 'CmdOrCtrl+L',
|
||
|
click(item, focusedWindow) {
|
||
|
selectURL(item.url)
|
||
|
toggleBookmarks(item)
|
||
|
}
|
||
|
},
|
||
|
{
|
||
|
label: i18n.__('testframes'),
|
||
|
class: 'bookmark',
|
||
|
type: 'checkbox',
|
||
|
url: `file://${__dirname}/../index.html?test`,
|
||
|
accelerator: 'CmdOrCtrl+T',
|
||
|
click(item, focusedWindow) {
|
||
|
selectURL(item.url)
|
||
|
toggleBookmarks(item)
|
||
|
}
|
||
|
},
|
||
|
{
|
||
|
type: 'separator'
|
||
|
},
|
||
|
{
|
||
|
id: 'localhost',
|
||
|
label: 'https://localhost:8443',
|
||
|
class: 'bookmark',
|
||
|
type: 'checkbox',
|
||
|
enabled: false,
|
||
|
url: 'https://localhost:8443/index.html',
|
||
|
click(item, focusedWindow) {
|
||
|
selectURL(item.url)
|
||
|
toggleBookmarks(item)
|
||
|
}
|
||
|
},
|
||
|
{
|
||
|
id: 'localhost',
|
||
|
label: 'https://localhost:3000',
|
||
|
class: 'bookmark',
|
||
|
type: 'checkbox',
|
||
|
enabled: true,
|
||
|
url: 'https://localhost:3000/index.html',
|
||
|
click(item, focusedWindow) {
|
||
|
selectURL(item.url)
|
||
|
toggleBookmarks(item)
|
||
|
}
|
||
|
},
|
||
|
// {
|
||
|
// label: 'http://tornado.iwm-kmrc.de:8000',
|
||
|
// class: 'bookmark',
|
||
|
// type: 'checkbox',
|
||
|
// url: 'http://tornado.iwm-kmrc.de:8000/index.html',
|
||
|
// click(item, focusedWindow) {
|
||
|
// selectURL(item.url)
|
||
|
// toggleBookmarks(item)
|
||
|
// }
|
||
|
// },
|
||
|
{
|
||
|
label: 'http://rousseau.iwm-kmrc.de/index.html',
|
||
|
class: 'bookmark',
|
||
|
type: 'checkbox',
|
||
|
url: 'http://rousseau.iwm-kmrc.de/index.html',
|
||
|
click(item, focusedWindow) {
|
||
|
selectURL(item.url)
|
||
|
toggleBookmarks(item)
|
||
|
}
|
||
|
}
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
label: i18n.__('develop'),
|
||
|
submenu: [
|
||
|
{
|
||
|
id: 'toggledevelopertools',
|
||
|
label: i18n.__('toggledevelopertools'),
|
||
|
accelerator: process.platform === 'darwin' ? 'Alt+Command+I' : 'Ctrl+Shift+I',
|
||
|
click(item, focusedWindow) {
|
||
|
if (focusedWindow) focusedWindow.webContents.toggleDevTools()
|
||
|
}
|
||
|
},
|
||
|
{
|
||
|
label: i18n.__('openprocessmonitor'),
|
||
|
accelerator: process.platform === 'darwin' ? 'Alt+Command+P' : 'Ctrl+Shift+P',
|
||
|
click(item, focusedWindow) {
|
||
|
openProcessManager()
|
||
|
}
|
||
|
},
|
||
|
{
|
||
|
type: 'separator'
|
||
|
},
|
||
|
{
|
||
|
label: i18n.__('selectfolder'),
|
||
|
accelerator: process.platform === 'darwin' ? 'Alt+Command+D' : 'Ctrl+Shift+D',
|
||
|
click(item, focusedWindow) {
|
||
|
if (process.platform === 'win32') {
|
||
|
var exec = require('child_process').exec
|
||
|
exec('NET SESSION', function (err, so, se) {
|
||
|
const admin = se.length === 0 ? true : false
|
||
|
|
||
|
if (admin) {
|
||
|
showFolderBrowser(focusedWindow)
|
||
|
} else {
|
||
|
dialog.showMessageBox({
|
||
|
type: 'error',
|
||
|
icon: path.join(__dirname, '../assets/icons/png/512x512-empty.png'),
|
||
|
buttons: [i18n.__('selectfolder.noadmin.ok')],
|
||
|
message: i18n.__('selectfolder.noadmin.message'),
|
||
|
detail: i18n.__('selectfolder.noadmin.detail')
|
||
|
})
|
||
|
}
|
||
|
})
|
||
|
} else {
|
||
|
showFolderBrowser(focusedWindow)
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
{
|
||
|
type: 'separator'
|
||
|
},
|
||
|
{
|
||
|
id: 'startserver',
|
||
|
label: i18n.__('startserver'),
|
||
|
accelerator: process.platform === 'darwin' ? 'Alt+Command+S' : 'Ctrl+Shift+S',
|
||
|
click(item, focusedWindow) {
|
||
|
const { server } = require('../server/main.js')
|
||
|
server.start()
|
||
|
item.visible = false
|
||
|
findItem('id', 'stopserver').visible = true
|
||
|
findItem('id', 'localhost').enabled = true
|
||
|
}
|
||
|
},
|
||
|
{
|
||
|
id: 'stopserver',
|
||
|
label: i18n.__('stopserver'),
|
||
|
accelerator: process.platform === 'darwin' ? 'Alt+Command+S' : 'Ctrl+Shift+S',
|
||
|
visible: false,
|
||
|
click(item, focusedWindow) {
|
||
|
const { server } = require('../server/main.js')
|
||
|
server.stop()
|
||
|
item.visible = false
|
||
|
findItem('id', 'startserver').visible = true
|
||
|
findItem('id', 'localhost').enabled = false
|
||
|
}
|
||
|
},
|
||
|
{
|
||
|
type: 'separator'
|
||
|
},
|
||
|
{
|
||
|
label: i18n.__('runloadtests'),
|
||
|
accelerator: process.platform === 'darwin' ? 'Alt+Command+L' : 'Ctrl+Shift+L',
|
||
|
click(item, focusedWindow) {
|
||
|
loadTests(focusedWindow)
|
||
|
}
|
||
|
},
|
||
|
{
|
||
|
type: 'separator'
|
||
|
},
|
||
|
{
|
||
|
label: 'Aktualisiere Tüsch POIs',
|
||
|
click(item, focusedWindow) {
|
||
|
const UpdatePOI = require('../dev/tuesch/bin/menu/update-pois.js')
|
||
|
UpdatePOI.update('./dev/tuesch')
|
||
|
}
|
||
|
}
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
role: 'window',
|
||
|
label: i18n.__('window'),
|
||
|
submenu: [
|
||
|
{
|
||
|
role: 'close',
|
||
|
label: i18n.__('close')
|
||
|
},
|
||
|
{
|
||
|
role: 'minimize',
|
||
|
label: i18n.__('minimize')
|
||
|
},
|
||
|
{
|
||
|
role: 'zoom',
|
||
|
label: i18n.__('zoom')
|
||
|
},
|
||
|
{
|
||
|
type: 'separator'
|
||
|
},
|
||
|
{
|
||
|
role: 'front',
|
||
|
label: i18n.__('front')
|
||
|
},
|
||
|
{
|
||
|
type: 'separator'
|
||
|
},
|
||
|
{
|
||
|
label: i18n.__('screenshot'),
|
||
|
accelerator: 'CmdOrCtrl+S',
|
||
|
async click(item, focusedWindow) {
|
||
|
if (focusedWindow) {
|
||
|
await focusedWindow.webContents.capturePage().then((image) => {
|
||
|
let screenshotFile = path.join(os.tmpdir(), 'screenshot.png')
|
||
|
|
||
|
console.log('image captured', screenshotFile)
|
||
|
|
||
|
let url = focusedWindow.webContents.getURL()
|
||
|
if (url.startsWith('file://')) {
|
||
|
let normalized = path.normalize(url).replace('.html', '.png')
|
||
|
screenshotFile = normalized.replace('file:', '')
|
||
|
let thumbnailFile = screenshotFile.replace('index.png', 'thumbnail.png')
|
||
|
if (url.endsWith('index.html')) {
|
||
|
thumbnailFile = screenshotFile.replace('index.png', 'thumbnail.png')
|
||
|
} else {
|
||
|
let folderName = path.dirname(screenshotFile)
|
||
|
let baseName = path.basename(screenshotFile)
|
||
|
thumbnailFile = path.join(folderName, 'thumbnails', baseName)
|
||
|
}
|
||
|
fs.writeFile(thumbnailFile, thumbnail(image), (err) => {
|
||
|
if (err) {
|
||
|
throw err
|
||
|
} else {
|
||
|
console.log(`Thumbnail written to ${thumbnailFile}`)
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
fs.writeFile(screenshotFile, image.toPNG(), (err) => {
|
||
|
if (err) {
|
||
|
throw err
|
||
|
} else {
|
||
|
console.log(`Screenshot written to ${screenshotFile}`)
|
||
|
}
|
||
|
})
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
{
|
||
|
type: 'separator'
|
||
|
}
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
role: 'help',
|
||
|
label: i18n.__('help'),
|
||
|
submenu: [
|
||
|
{
|
||
|
label: i18n.__('iwm'),
|
||
|
click() {
|
||
|
shell.openExternal('https://www.iwm-tuebingen.de')
|
||
|
}
|
||
|
}
|
||
|
]
|
||
|
}
|
||
|
]
|
||
|
|
||
|
if (process.platform === 'darwin') {
|
||
|
const name = app.getName()
|
||
|
template.unshift({
|
||
|
label: name,
|
||
|
submenu: [
|
||
|
{
|
||
|
role: 'about',
|
||
|
label: i18n.__('about')
|
||
|
},
|
||
|
{
|
||
|
type: 'separator'
|
||
|
},
|
||
|
{
|
||
|
role: 'quit',
|
||
|
label: i18n.__('quit')
|
||
|
}
|
||
|
]
|
||
|
})
|
||
|
}
|
||
|
|
||
|
const menu = Menu.buildFromTemplate(template)
|
||
|
Menu.setApplicationMenu(menu)
|
||
|
|
||
|
checkBookmark(main.store.get('url'))
|
||
|
setHistoryStatus()
|
||
|
|
||
|
function focus() {
|
||
|
findItem('id', 'forcereload').enabled = true
|
||
|
findItem('id', 'togglefullscreen').enabled = true
|
||
|
findItem('id', 'toggledevelopertools').enabled = true
|
||
|
}
|
||
|
|
||
|
function blur() {
|
||
|
findItem('id', 'forcereload').enabled = false
|
||
|
findItem('id', 'togglefullscreen').enabled = false
|
||
|
findItem('id', 'toggledevelopertools').enabled = false
|
||
|
}
|
||
|
|
||
|
module.exports = {
|
||
|
menu,
|
||
|
setHistoryStatus,
|
||
|
focus,
|
||
|
blur
|
||
|
}
|