diff --git a/bin/browser.sh b/bin/browser.sh old mode 100755 new mode 100644 diff --git a/browser/menu.js b/browser/menu.js index c20845b..7553aa3 100644 --- a/browser/menu.js +++ b/browser/menu.js @@ -1,629 +1,629 @@ -/* 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 -} +/* 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 +} diff --git a/dist/iwmlib.js b/dist/iwmlib.js index 1482c31..ba986b3 100644 --- a/dist/iwmlib.js +++ b/dist/iwmlib.js @@ -3215,7 +3215,7 @@ throwVisibility = 44, throwDamping = 0.95, autoThrow = true, - onThrowFinished = null, + onThrowFinished = null } = {}) { this.movableX = movableX; this.movableY = movableY; @@ -3248,7 +3248,7 @@ t: t, dt: dt, dx: delta.x / number, - dy: delta.y / number, + dy: delta.y / number }; this.velocities.push(velocity); while (this.velocities.length > buffer) { @@ -3310,7 +3310,7 @@ if (nextLength > prevLength) { let factor = nextLength / prevLength; next = Points$1.multiplyScalar(next, 1 / factor); - console.log('Prevent acceleration', factor, this.velocity, next); + // console.log('Prevent acceleration', factor, this.velocity, next) } this.velocity = next; let d = Points$1.multiplyScalar(this.velocity, dt); @@ -3346,7 +3346,7 @@ let next = Points$1.multiplyScalar(velocity, this.throwDamping); return { x: this.movableX ? next.x : 0, - y: this.movableY ? next.y : 0, + y: this.movableY ? next.y : 0 } } @@ -3391,7 +3391,7 @@ scaleCloseBuffer = 0.05, maxRotation = Angle.degree2radian(5), minInteractionDistance = 0, - useLowPassFilter = false, + useLowPassFilter = false } = {}) { if (rotationDegrees != null && rotation != null) { throw new Error('Use rotationDegrees or rotation but not both') @@ -3406,7 +3406,7 @@ throwVisibility, throwDamping, autoThrow, - onThrowFinished, + onThrowFinished }); /** @@ -3481,7 +3481,7 @@ _callCloseCallbacks() { if (this.onClose) { - this.onClose.forEach((callback) => callback(this)); + this.onClose.forEach(callback => callback(this)); } } @@ -3501,6 +3501,9 @@ let delta = interaction.delta(); if (delta != null) { + /* uo: Is this the best place to add velocity? It works with scrollable text in card drawers but + has to be tested */ + this.addVelocity(delta); let rotate = delta.rotate; let zoom = delta.zoom; if (this.maxRotation != null) { @@ -3519,9 +3522,10 @@ zoomDelta *= ratio; zoom = 1 + zoomDelta; } - this.transform(delta, zoom, rotate, delta.about); - this.addVelocity(delta); // uo: reverted commit fa0256d782dd498c6d3e51321260ca375ca9f855 + /* uo: This is too late an dangerous. transform sometimes modifies delta + this.addVelocity(delta) // uo: reverted commit fa0256d782dd498c6d3e51321260ca375ca9f855 + */ if (zoom != 1) this.interactionAnchor = delta.about; } @@ -3632,11 +3636,11 @@ if (this.scale < this.minScale + this.scaleCloseThreshold - this.scaleCloseBuffer) { this.zoom(this.minScale, { animate: 0.2, - onComplete: this.close.bind(this), + onComplete: this.close.bind(this) }); } else if (this.scale < this.minScale + this.scaleCloseThreshold) { this.zoom(this.minScale + this.scaleCloseThreshold, { - animate: 0.4, + animate: 0.4 }); } } @@ -3658,12 +3662,12 @@ x: '+=' + d.x, y: '+=' + d.y, /* scale: scale, uo: not defined, why was this here? */ - onUpdate: (e) => { + onUpdate: e => { let p = this.position; let dx = p.x - startPos.x; let dy = p.x - startPos.y; this.onMoved(dx, dy); - }, + } }); } else { this._move(d); @@ -3692,7 +3696,7 @@ scale: scale, delay: delay, onComplete: onComplete, - onUpdate: this.onZoomed.bind(this), + onUpdate: this.onZoomed.bind(this) }); } else { this.scale = scale; @@ -3710,7 +3714,7 @@ transform(translate, zoom, rotate, anchor) { let delta = { x: this.movableX ? translate.x : 0, - y: this.movableY ? translate.y : 0, + y: this.movableY ? translate.y : 0 }; if (this.resizable) var vzoom = zoom; if (!this.translatable) delta = { x: 0, y: 0 }; @@ -3725,9 +3729,9 @@ rotate: 0, about: anchor, fast: false, - type: UPDATE, + type: UPDATE }); - this.onTransform.forEach(function (f) { + this.onTransform.forEach(function(f) { f(event); }); } @@ -3756,9 +3760,9 @@ translate: delta, scale: newScale, rotate: rotate, - about: anchor, + about: anchor }); - this.onTransform.forEach(function (f) { + this.onTransform.forEach(function(f) { f(event); }); } @@ -3824,7 +3828,7 @@ if (this.scale > this.maxScale) zoom = 1 - amount; if (zoom != 1) { this.transform({ x: 0, y: 0 }, zoom, 0, this.zoomAnchor); - requestAnimationFrame((dt) => { + requestAnimationFrame(dt => { this.animateZoomBounce(dt); }); return @@ -3881,9 +3885,9 @@ rotate: 0, about: null, fast: false, - type: START, + type: START }); - this.onTransform.forEach(function (f) { + this.onTransform.forEach(function(f) { f(event); }); } @@ -3899,13 +3903,13 @@ } onEnd(event, interaction) { - console.log('Scatter.onEnd', this.dragging); + //console.log('Scatter.onEnd', this.dragging) if (interaction.isFinished()) { this.endGesture(interaction); this.dragging = false; for (let key of interaction.ended.keys()) { if (interaction.isTap(key)) { - console.log('Scatter.isTap'); + //console.log('Scatter.isTap') let point = interaction.ended.get(key); this.onTap(event, interaction, point); } @@ -3917,9 +3921,9 @@ rotate: 0, about: null, fast: false, - type: END, + type: END }); - this.onTransform.forEach(function (f) { + this.onTransform.forEach(function(f) { f(event); }); } @@ -3933,7 +3937,7 @@ //onTap(event, interaction, point) {} onTap(event, interaction, point) { - console.log('AbstractScatter.onTap', this.tapDelegate, interaction); + //console.log('AbstractScatter.onTap', this.tapDelegate, interaction) if (this.tapDelegate) { Events.stop(event); this.tapDelegate.tap(event, 'scatter'); @@ -3947,9 +3951,9 @@ translate: delta, scale: this.scale, about: this.currentAbout, - type: null, + type: null }); - this.onTransform.forEach(function (f) { + this.onTransform.forEach(function(f) { f(event); }); } @@ -3961,9 +3965,9 @@ scale: this.scale, about: this.currentAbout, fast: false, - type: null, + type: null }); - this.onTransform.forEach(function (f) { + this.onTransform.forEach(function(f) { f(event); }); } @@ -3975,9 +3979,9 @@ translate: { x: dx, y: dy }, about: about, fast: true, - type: null, + type: null }); - this.onTransform.forEach(function (f) { + this.onTransform.forEach(function(f) { f(event); }); } @@ -3988,9 +3992,9 @@ let event = new ScatterEvent(this, { scale: this.scale, fast: false, - type: null, + type: null }); - this.onTransform.forEach(function (f) { + this.onTransform.forEach(function(f) { f(event); }); } @@ -4004,9 +4008,9 @@ scale: this.scale, about: about, fast: false, - type: null, + type: null }); - this.onTransform.forEach(function (f) { + this.onTransform.forEach(function(f) { f(event); }); } @@ -4038,7 +4042,7 @@ useCapture = true, capturePointerEvents = true, touchAction = 'none', - debugCanvas = null, + debugCanvas = null } = {} ) { this.onCapture = null; @@ -4050,7 +4054,7 @@ movement of scatter objects, the touchmove event has to be bound again. */ if (Capabilities.isSafari) { - document.addEventListener('touchmove', (event) => this.preventPinch(event), false); + document.addEventListener('touchmove', event => this.preventPinch(event), false); stopEvents = false; } else { stopEvents = true; @@ -4065,11 +4069,11 @@ this.delegate = new InteractionMapper$1(element, this, { useCapture, capturePointerEvents, - mouseWheelElement: window, + mouseWheelElement: window }); if (debugCanvas !== null) { - requestAnimationFrame((dt) => { + requestAnimationFrame(dt => { this.showTouches(dt, debugCanvas); }); } @@ -4091,7 +4095,7 @@ context.fill(); context.stroke(); } - requestAnimationFrame((dt) => { + requestAnimationFrame(dt => { this.showTouches(dt, canvas); }); } @@ -4233,7 +4237,7 @@ scaleCloseBuffer = 0.05, useLowPassFilter = false, maxRotation = Angle.degree2radian(15), - minInteractionDistance = 200, + minInteractionDistance = 200 } = {} ) { super({ @@ -4260,7 +4264,7 @@ onClose, useLowPassFilter, maxRotation, - minInteractionDistance, + minInteractionDistance }); if (container == null || width == null || height == null) { throw new Error('Invalid value: null') @@ -4288,7 +4292,7 @@ height: height, scale: startScale, rotation: this.startRotationDegrees, - transformOrigin: transformOrigin, + transformOrigin: transformOrigin }; this.tapNodes = new Map(); @@ -4310,15 +4314,15 @@ button.className = 'interactiveElement'; this.element.appendChild(button); - button.addEventListener('pointerdown', (e) => { + button.addEventListener('pointerdown', e => { this.startResize(e); }); - button.addEventListener('pointermove', (e) => { + button.addEventListener('pointermove', e => { this.resize(e); }); - button.addEventListener('pointerup', (e) => { + button.addEventListener('pointerup', e => { this.stopResize(e); }); this.resizeButton = button; @@ -4335,7 +4339,7 @@ scale: this.scale, x: this.x, y: this.y, - rotation: this.rotation, + rotation: this.rotation } } @@ -4386,7 +4390,7 @@ top: rect.top - stage.top, left: rect.left - stage.left, width: rect.width, - height: rect.height, + height: rect.height } } @@ -4427,7 +4431,7 @@ set scale(scale) { TweenLite.set(this.element, { scale: scale, - transformOrigin: this.transformOrigin, + transformOrigin: this.transformOrigin }); this._scale = scale; } @@ -4459,9 +4463,9 @@ hide() { TweenLite.to(this.element, 0.1, { display: 'none', - onComplete: (e) => { + onComplete: e => { this.element.parentNode.removeChild(this.element); - }, + } }); } @@ -4475,7 +4479,7 @@ x: p.x, y: p.y, rotation: rotationDegrees, - transformOrigin: this.transformOrigin, + transformOrigin: this.transformOrigin }); } @@ -4536,7 +4540,7 @@ let oldPostition = { x: this.element.getBoundingClientRect().left, - y: this.element.getBoundingClientRect().top, + y: this.element.getBoundingClientRect().top }; this.bringToFront(); @@ -4544,7 +4548,7 @@ let newPostition = { x: this.element.getBoundingClientRect().left, - y: this.element.getBoundingClientRect().top, + y: this.element.getBoundingClientRect().top }; let offset = Points$1.subtract(oldPostition, newPostition); @@ -4589,7 +4593,7 @@ ) TweenLite.to(this.element, 0, { width: this.element.offsetWidth + resizeW / this.scale, - height: this.element.offsetHeight + resizeH / this.scale, + height: this.element.offsetHeight + resizeH / this.scale }); this.oldX = e.clientX; @@ -4606,12 +4610,12 @@ let event = new CustomEvent('resizeEnded'); let oldPostition = { x: this.element.getBoundingClientRect().left, - y: this.element.getBoundingClientRect().top, + y: this.element.getBoundingClientRect().top }; this.element.style.transformOrigin = '50% 50%'; let newPostition = { x: this.element.getBoundingClientRect().left, - y: this.element.getBoundingClientRect().top, + y: this.element.getBoundingClientRect().top }; let offset = Points$1.subtract(oldPostition, newPostition); diff --git a/dist/iwmlib.pixi.js b/dist/iwmlib.pixi.js index 7cdf1fa..4e1ab39 100644 --- a/dist/iwmlib.pixi.js +++ b/dist/iwmlib.pixi.js @@ -6778,7 +6778,7 @@ throwVisibility = 44, throwDamping = 0.95, autoThrow = true, - onThrowFinished = null, + onThrowFinished = null } = {}) { this.movableX = movableX; this.movableY = movableY; @@ -6811,7 +6811,7 @@ t: t, dt: dt, dx: delta.x / number, - dy: delta.y / number, + dy: delta.y / number }; this.velocities.push(velocity); while (this.velocities.length > buffer) { @@ -6873,7 +6873,7 @@ if (nextLength > prevLength) { let factor = nextLength / prevLength; next = Points.multiplyScalar(next, 1 / factor); - console.log('Prevent acceleration', factor, this.velocity, next); + // console.log('Prevent acceleration', factor, this.velocity, next) } this.velocity = next; let d = Points.multiplyScalar(this.velocity, dt); @@ -6909,7 +6909,7 @@ let next = Points.multiplyScalar(velocity, this.throwDamping); return { x: this.movableX ? next.x : 0, - y: this.movableY ? next.y : 0, + y: this.movableY ? next.y : 0 } } @@ -6954,7 +6954,7 @@ scaleCloseBuffer = 0.05, maxRotation = Angle.degree2radian(5), minInteractionDistance = 0, - useLowPassFilter = false, + useLowPassFilter = false } = {}) { if (rotationDegrees != null && rotation != null) { throw new Error('Use rotationDegrees or rotation but not both') @@ -6969,7 +6969,7 @@ throwVisibility, throwDamping, autoThrow, - onThrowFinished, + onThrowFinished }); /** @@ -7044,7 +7044,7 @@ _callCloseCallbacks() { if (this.onClose) { - this.onClose.forEach((callback) => callback(this)); + this.onClose.forEach(callback => callback(this)); } } @@ -7064,6 +7064,9 @@ let delta = interaction.delta(); if (delta != null) { + /* uo: Is this the best place to add velocity? It works with scrollable text in card drawers but + has to be tested */ + this.addVelocity(delta); let rotate = delta.rotate; let zoom = delta.zoom; if (this.maxRotation != null) { @@ -7082,9 +7085,10 @@ zoomDelta *= ratio; zoom = 1 + zoomDelta; } - this.transform(delta, zoom, rotate, delta.about); - this.addVelocity(delta); // uo: reverted commit fa0256d782dd498c6d3e51321260ca375ca9f855 + /* uo: This is too late an dangerous. transform sometimes modifies delta + this.addVelocity(delta) // uo: reverted commit fa0256d782dd498c6d3e51321260ca375ca9f855 + */ if (zoom != 1) this.interactionAnchor = delta.about; } @@ -7195,11 +7199,11 @@ if (this.scale < this.minScale + this.scaleCloseThreshold - this.scaleCloseBuffer) { this.zoom(this.minScale, { animate: 0.2, - onComplete: this.close.bind(this), + onComplete: this.close.bind(this) }); } else if (this.scale < this.minScale + this.scaleCloseThreshold) { this.zoom(this.minScale + this.scaleCloseThreshold, { - animate: 0.4, + animate: 0.4 }); } } @@ -7221,12 +7225,12 @@ x: '+=' + d.x, y: '+=' + d.y, /* scale: scale, uo: not defined, why was this here? */ - onUpdate: (e) => { + onUpdate: e => { let p = this.position; let dx = p.x - startPos.x; let dy = p.x - startPos.y; this.onMoved(dx, dy); - }, + } }); } else { this._move(d); @@ -7255,7 +7259,7 @@ scale: scale, delay: delay, onComplete: onComplete, - onUpdate: this.onZoomed.bind(this), + onUpdate: this.onZoomed.bind(this) }); } else { this.scale = scale; @@ -7273,7 +7277,7 @@ transform(translate, zoom, rotate, anchor) { let delta = { x: this.movableX ? translate.x : 0, - y: this.movableY ? translate.y : 0, + y: this.movableY ? translate.y : 0 }; if (this.resizable) var vzoom = zoom; if (!this.translatable) delta = { x: 0, y: 0 }; @@ -7288,9 +7292,9 @@ rotate: 0, about: anchor, fast: false, - type: UPDATE, + type: UPDATE }); - this.onTransform.forEach(function (f) { + this.onTransform.forEach(function(f) { f(event); }); } @@ -7319,9 +7323,9 @@ translate: delta, scale: newScale, rotate: rotate, - about: anchor, + about: anchor }); - this.onTransform.forEach(function (f) { + this.onTransform.forEach(function(f) { f(event); }); } @@ -7387,7 +7391,7 @@ if (this.scale > this.maxScale) zoom = 1 - amount; if (zoom != 1) { this.transform({ x: 0, y: 0 }, zoom, 0, this.zoomAnchor); - requestAnimationFrame((dt) => { + requestAnimationFrame(dt => { this.animateZoomBounce(dt); }); return @@ -7444,9 +7448,9 @@ rotate: 0, about: null, fast: false, - type: START, + type: START }); - this.onTransform.forEach(function (f) { + this.onTransform.forEach(function(f) { f(event); }); } @@ -7462,13 +7466,13 @@ } onEnd(event, interaction) { - console.log('Scatter.onEnd', this.dragging); + //console.log('Scatter.onEnd', this.dragging) if (interaction.isFinished()) { this.endGesture(interaction); this.dragging = false; for (let key of interaction.ended.keys()) { if (interaction.isTap(key)) { - console.log('Scatter.isTap'); + //console.log('Scatter.isTap') let point = interaction.ended.get(key); this.onTap(event, interaction, point); } @@ -7480,9 +7484,9 @@ rotate: 0, about: null, fast: false, - type: END, + type: END }); - this.onTransform.forEach(function (f) { + this.onTransform.forEach(function(f) { f(event); }); } @@ -7496,7 +7500,7 @@ //onTap(event, interaction, point) {} onTap(event, interaction, point) { - console.log('AbstractScatter.onTap', this.tapDelegate, interaction); + //console.log('AbstractScatter.onTap', this.tapDelegate, interaction) if (this.tapDelegate) { Events$1.stop(event); this.tapDelegate.tap(event, 'scatter'); @@ -7510,9 +7514,9 @@ translate: delta, scale: this.scale, about: this.currentAbout, - type: null, + type: null }); - this.onTransform.forEach(function (f) { + this.onTransform.forEach(function(f) { f(event); }); } @@ -7524,9 +7528,9 @@ scale: this.scale, about: this.currentAbout, fast: false, - type: null, + type: null }); - this.onTransform.forEach(function (f) { + this.onTransform.forEach(function(f) { f(event); }); } @@ -7538,9 +7542,9 @@ translate: { x: dx, y: dy }, about: about, fast: true, - type: null, + type: null }); - this.onTransform.forEach(function (f) { + this.onTransform.forEach(function(f) { f(event); }); } @@ -7551,9 +7555,9 @@ let event = new ScatterEvent(this, { scale: this.scale, fast: false, - type: null, + type: null }); - this.onTransform.forEach(function (f) { + this.onTransform.forEach(function(f) { f(event); }); } @@ -7567,9 +7571,9 @@ scale: this.scale, about: about, fast: false, - type: null, + type: null }); - this.onTransform.forEach(function (f) { + this.onTransform.forEach(function(f) { f(event); }); } @@ -7616,7 +7620,7 @@ scaleCloseBuffer = 0.05, useLowPassFilter = false, maxRotation = Angle.degree2radian(15), - minInteractionDistance = 200, + minInteractionDistance = 200 } = {} ) { super({ @@ -7643,7 +7647,7 @@ onClose, useLowPassFilter, maxRotation, - minInteractionDistance, + minInteractionDistance }); if (container == null || width == null || height == null) { throw new Error('Invalid value: null') @@ -7671,7 +7675,7 @@ height: height, scale: startScale, rotation: this.startRotationDegrees, - transformOrigin: transformOrigin, + transformOrigin: transformOrigin }; this.tapNodes = new Map(); @@ -7693,15 +7697,15 @@ button.className = 'interactiveElement'; this.element.appendChild(button); - button.addEventListener('pointerdown', (e) => { + button.addEventListener('pointerdown', e => { this.startResize(e); }); - button.addEventListener('pointermove', (e) => { + button.addEventListener('pointermove', e => { this.resize(e); }); - button.addEventListener('pointerup', (e) => { + button.addEventListener('pointerup', e => { this.stopResize(e); }); this.resizeButton = button; @@ -7718,7 +7722,7 @@ scale: this.scale, x: this.x, y: this.y, - rotation: this.rotation, + rotation: this.rotation } } @@ -7769,7 +7773,7 @@ top: rect.top - stage.top, left: rect.left - stage.left, width: rect.width, - height: rect.height, + height: rect.height } } @@ -7810,7 +7814,7 @@ set scale(scale) { TweenLite.set(this.element, { scale: scale, - transformOrigin: this.transformOrigin, + transformOrigin: this.transformOrigin }); this._scale = scale; } @@ -7842,9 +7846,9 @@ hide() { TweenLite.to(this.element, 0.1, { display: 'none', - onComplete: (e) => { + onComplete: e => { this.element.parentNode.removeChild(this.element); - }, + } }); } @@ -7858,7 +7862,7 @@ x: p.x, y: p.y, rotation: rotationDegrees, - transformOrigin: this.transformOrigin, + transformOrigin: this.transformOrigin }); } @@ -7919,7 +7923,7 @@ let oldPostition = { x: this.element.getBoundingClientRect().left, - y: this.element.getBoundingClientRect().top, + y: this.element.getBoundingClientRect().top }; this.bringToFront(); @@ -7927,7 +7931,7 @@ let newPostition = { x: this.element.getBoundingClientRect().left, - y: this.element.getBoundingClientRect().top, + y: this.element.getBoundingClientRect().top }; let offset = Points.subtract(oldPostition, newPostition); @@ -7972,7 +7976,7 @@ ) TweenLite.to(this.element, 0, { width: this.element.offsetWidth + resizeW / this.scale, - height: this.element.offsetHeight + resizeH / this.scale, + height: this.element.offsetHeight + resizeH / this.scale }); this.oldX = e.clientX; @@ -7989,12 +7993,12 @@ let event = new CustomEvent('resizeEnded'); let oldPostition = { x: this.element.getBoundingClientRect().left, - y: this.element.getBoundingClientRect().top, + y: this.element.getBoundingClientRect().top }; this.element.style.transformOrigin = '50% 50%'; let newPostition = { x: this.element.getBoundingClientRect().left, - y: this.element.getBoundingClientRect().top, + y: this.element.getBoundingClientRect().top }; let offset = Points.subtract(oldPostition, newPostition); diff --git a/lib/_menu.js b/lib/_menu.js old mode 100755 new mode 100644 diff --git a/lib/scatter.js b/lib/scatter.js index c75a3d7..efaada1 100644 --- a/lib/scatter.js +++ b/lib/scatter.js @@ -95,7 +95,7 @@ class Throwable { throwVisibility = 44, throwDamping = 0.95, autoThrow = true, - onThrowFinished = null, + onThrowFinished = null } = {}) { this.movableX = movableX this.movableY = movableY @@ -128,7 +128,7 @@ class Throwable { t: t, dt: dt, dx: delta.x / number, - dy: delta.y / number, + dy: delta.y / number } this.velocities.push(velocity) while (this.velocities.length > buffer) { @@ -190,7 +190,7 @@ class Throwable { if (nextLength > prevLength) { let factor = nextLength / prevLength next = Points.multiplyScalar(next, 1 / factor) - console.log('Prevent acceleration', factor, this.velocity, next) + // console.log('Prevent acceleration', factor, this.velocity, next) } this.velocity = next let d = Points.multiplyScalar(this.velocity, dt) @@ -226,7 +226,7 @@ class Throwable { let next = Points.multiplyScalar(velocity, this.throwDamping) return { x: this.movableX ? next.x : 0, - y: this.movableY ? next.y : 0, + y: this.movableY ? next.y : 0 } } @@ -271,7 +271,7 @@ export class AbstractScatter extends Throwable { scaleCloseBuffer = 0.05, maxRotation = Angle.degree2radian(5), minInteractionDistance = 0, - useLowPassFilter = false, + useLowPassFilter = false } = {}) { if (rotationDegrees != null && rotation != null) { throw new Error('Use rotationDegrees or rotation but not both') @@ -286,7 +286,7 @@ export class AbstractScatter extends Throwable { throwVisibility, throwDamping, autoThrow, - onThrowFinished, + onThrowFinished }) /** @@ -361,7 +361,7 @@ export class AbstractScatter extends Throwable { _callCloseCallbacks() { if (this.onClose) { - this.onClose.forEach((callback) => callback(this)) + this.onClose.forEach(callback => callback(this)) } } @@ -381,6 +381,9 @@ export class AbstractScatter extends Throwable { let delta = interaction.delta() if (delta != null) { + /* uo: Is this the best place to add velocity? It works with scrollable text in card drawers but + has to be tested */ + this.addVelocity(delta) let rotate = delta.rotate let zoom = delta.zoom if (this.maxRotation != null) { @@ -399,9 +402,10 @@ export class AbstractScatter extends Throwable { zoomDelta *= ratio zoom = 1 + zoomDelta } - this.transform(delta, zoom, rotate, delta.about) + /* uo: This is too late an dangerous. transform sometimes modifies delta this.addVelocity(delta) // uo: reverted commit fa0256d782dd498c6d3e51321260ca375ca9f855 + */ if (zoom != 1) this.interactionAnchor = delta.about } @@ -512,11 +516,11 @@ export class AbstractScatter extends Throwable { if (this.scale < this.minScale + this.scaleCloseThreshold - this.scaleCloseBuffer) { this.zoom(this.minScale, { animate: 0.2, - onComplete: this.close.bind(this), + onComplete: this.close.bind(this) }) } else if (this.scale < this.minScale + this.scaleCloseThreshold) { this.zoom(this.minScale + this.scaleCloseThreshold, { - animate: 0.4, + animate: 0.4 }) } } @@ -538,12 +542,12 @@ export class AbstractScatter extends Throwable { x: '+=' + d.x, y: '+=' + d.y, /* scale: scale, uo: not defined, why was this here? */ - onUpdate: (e) => { + onUpdate: e => { let p = this.position let dx = p.x - startPos.x let dy = p.x - startPos.y this.onMoved(dx, dy) - }, + } }) } else { this._move(d) @@ -572,7 +576,7 @@ export class AbstractScatter extends Throwable { scale: scale, delay: delay, onComplete: onComplete, - onUpdate: this.onZoomed.bind(this), + onUpdate: this.onZoomed.bind(this) }) } else { this.scale = scale @@ -590,7 +594,7 @@ export class AbstractScatter extends Throwable { transform(translate, zoom, rotate, anchor) { let delta = { x: this.movableX ? translate.x : 0, - y: this.movableY ? translate.y : 0, + y: this.movableY ? translate.y : 0 } if (this.resizable) var vzoom = zoom if (!this.translatable) delta = { x: 0, y: 0 } @@ -605,9 +609,9 @@ export class AbstractScatter extends Throwable { rotate: 0, about: anchor, fast: false, - type: UPDATE, + type: UPDATE }) - this.onTransform.forEach(function (f) { + this.onTransform.forEach(function(f) { f(event) }) } @@ -636,9 +640,9 @@ export class AbstractScatter extends Throwable { translate: delta, scale: newScale, rotate: rotate, - about: anchor, + about: anchor }) - this.onTransform.forEach(function (f) { + this.onTransform.forEach(function(f) { f(event) }) } @@ -704,7 +708,7 @@ export class AbstractScatter extends Throwable { if (this.scale > this.maxScale) zoom = 1 - amount if (zoom != 1) { this.transform({ x: 0, y: 0 }, zoom, 0, this.zoomAnchor) - requestAnimationFrame((dt) => { + requestAnimationFrame(dt => { this.animateZoomBounce(dt) }) return @@ -761,9 +765,9 @@ export class AbstractScatter extends Throwable { rotate: 0, about: null, fast: false, - type: START, + type: START }) - this.onTransform.forEach(function (f) { + this.onTransform.forEach(function(f) { f(event) }) } @@ -779,13 +783,13 @@ export class AbstractScatter extends Throwable { } onEnd(event, interaction) { - console.log('Scatter.onEnd', this.dragging) + //console.log('Scatter.onEnd', this.dragging) if (interaction.isFinished()) { this.endGesture(interaction) this.dragging = false for (let key of interaction.ended.keys()) { if (interaction.isTap(key)) { - console.log('Scatter.isTap') + //console.log('Scatter.isTap') let point = interaction.ended.get(key) this.onTap(event, interaction, point) } @@ -797,9 +801,9 @@ export class AbstractScatter extends Throwable { rotate: 0, about: null, fast: false, - type: END, + type: END }) - this.onTransform.forEach(function (f) { + this.onTransform.forEach(function(f) { f(event) }) } @@ -813,7 +817,7 @@ export class AbstractScatter extends Throwable { //onTap(event, interaction, point) {} onTap(event, interaction, point) { - console.log('AbstractScatter.onTap', this.tapDelegate, interaction) + //console.log('AbstractScatter.onTap', this.tapDelegate, interaction) if (this.tapDelegate) { Events.stop(event) this.tapDelegate.tap(event, 'scatter') @@ -827,9 +831,9 @@ export class AbstractScatter extends Throwable { translate: delta, scale: this.scale, about: this.currentAbout, - type: null, + type: null }) - this.onTransform.forEach(function (f) { + this.onTransform.forEach(function(f) { f(event) }) } @@ -841,9 +845,9 @@ export class AbstractScatter extends Throwable { scale: this.scale, about: this.currentAbout, fast: false, - type: null, + type: null }) - this.onTransform.forEach(function (f) { + this.onTransform.forEach(function(f) { f(event) }) } @@ -855,9 +859,9 @@ export class AbstractScatter extends Throwable { translate: { x: dx, y: dy }, about: about, fast: true, - type: null, + type: null }) - this.onTransform.forEach(function (f) { + this.onTransform.forEach(function(f) { f(event) }) } @@ -868,9 +872,9 @@ export class AbstractScatter extends Throwable { let event = new ScatterEvent(this, { scale: this.scale, fast: false, - type: null, + type: null }) - this.onTransform.forEach(function (f) { + this.onTransform.forEach(function(f) { f(event) }) } @@ -884,9 +888,9 @@ export class AbstractScatter extends Throwable { scale: this.scale, about: about, fast: false, - type: null, + type: null }) - this.onTransform.forEach(function (f) { + this.onTransform.forEach(function(f) { f(event) }) } @@ -918,7 +922,7 @@ export class DOMScatterContainer { useCapture = true, capturePointerEvents = true, touchAction = 'none', - debugCanvas = null, + debugCanvas = null } = {} ) { this.onCapture = null @@ -930,7 +934,7 @@ export class DOMScatterContainer { movement of scatter objects, the touchmove event has to be bound again. */ if (Capabilities.isSafari) { - document.addEventListener('touchmove', (event) => this.preventPinch(event), false) + document.addEventListener('touchmove', event => this.preventPinch(event), false) stopEvents = false } else { stopEvents = true @@ -945,11 +949,11 @@ export class DOMScatterContainer { this.delegate = new InteractionMapper(element, this, { useCapture, capturePointerEvents, - mouseWheelElement: window, + mouseWheelElement: window }) if (debugCanvas !== null) { - requestAnimationFrame((dt) => { + requestAnimationFrame(dt => { this.showTouches(dt, debugCanvas) }) } @@ -971,7 +975,7 @@ export class DOMScatterContainer { context.fill() context.stroke() } - requestAnimationFrame((dt) => { + requestAnimationFrame(dt => { this.showTouches(dt, canvas) }) } @@ -1113,7 +1117,7 @@ export class DOMScatter extends AbstractScatter { scaleCloseBuffer = 0.05, useLowPassFilter = false, maxRotation = Angle.degree2radian(15), - minInteractionDistance = 200, + minInteractionDistance = 200 } = {} ) { super({ @@ -1140,7 +1144,7 @@ export class DOMScatter extends AbstractScatter { onClose, useLowPassFilter, maxRotation, - minInteractionDistance, + minInteractionDistance }) if (container == null || width == null || height == null) { throw new Error('Invalid value: null') @@ -1168,7 +1172,7 @@ export class DOMScatter extends AbstractScatter { height: height, scale: startScale, rotation: this.startRotationDegrees, - transformOrigin: transformOrigin, + transformOrigin: transformOrigin } this.tapNodes = new Map() @@ -1190,15 +1194,15 @@ export class DOMScatter extends AbstractScatter { button.className = 'interactiveElement' this.element.appendChild(button) - button.addEventListener('pointerdown', (e) => { + button.addEventListener('pointerdown', e => { this.startResize(e) }) - button.addEventListener('pointermove', (e) => { + button.addEventListener('pointermove', e => { this.resize(e) }) - button.addEventListener('pointerup', (e) => { + button.addEventListener('pointerup', e => { this.stopResize(e) }) this.resizeButton = button @@ -1215,7 +1219,7 @@ export class DOMScatter extends AbstractScatter { scale: this.scale, x: this.x, y: this.y, - rotation: this.rotation, + rotation: this.rotation } } @@ -1266,7 +1270,7 @@ export class DOMScatter extends AbstractScatter { top: rect.top - stage.top, left: rect.left - stage.left, width: rect.width, - height: rect.height, + height: rect.height } } @@ -1307,7 +1311,7 @@ export class DOMScatter extends AbstractScatter { set scale(scale) { TweenLite.set(this.element, { scale: scale, - transformOrigin: this.transformOrigin, + transformOrigin: this.transformOrigin }) this._scale = scale } @@ -1339,9 +1343,9 @@ export class DOMScatter extends AbstractScatter { hide() { TweenLite.to(this.element, 0.1, { display: 'none', - onComplete: (e) => { + onComplete: e => { this.element.parentNode.removeChild(this.element) - }, + } }) } @@ -1355,7 +1359,7 @@ export class DOMScatter extends AbstractScatter { x: p.x, y: p.y, rotation: rotationDegrees, - transformOrigin: this.transformOrigin, + transformOrigin: this.transformOrigin }) } @@ -1416,7 +1420,7 @@ export class DOMScatter extends AbstractScatter { let oldPostition = { x: this.element.getBoundingClientRect().left, - y: this.element.getBoundingClientRect().top, + y: this.element.getBoundingClientRect().top } this.bringToFront() @@ -1424,7 +1428,7 @@ export class DOMScatter extends AbstractScatter { let newPostition = { x: this.element.getBoundingClientRect().left, - y: this.element.getBoundingClientRect().top, + y: this.element.getBoundingClientRect().top } let offset = Points.subtract(oldPostition, newPostition) @@ -1469,7 +1473,7 @@ export class DOMScatter extends AbstractScatter { ) TweenLite.to(this.element, 0, { width: this.element.offsetWidth + resizeW / this.scale, - height: this.element.offsetHeight + resizeH / this.scale, + height: this.element.offsetHeight + resizeH / this.scale }) this.oldX = e.clientX @@ -1486,12 +1490,12 @@ export class DOMScatter extends AbstractScatter { let event = new CustomEvent('resizeEnded') let oldPostition = { x: this.element.getBoundingClientRect().left, - y: this.element.getBoundingClientRect().top, + y: this.element.getBoundingClientRect().top } this.element.style.transformOrigin = '50% 50%' let newPostition = { x: this.element.getBoundingClientRect().left, - y: this.element.getBoundingClientRect().top, + y: this.element.getBoundingClientRect().top } let offset = Points.subtract(oldPostition, newPostition) diff --git a/package.json b/package.json index 9bef0a1..220608a 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "test-eventlistener-hammerjs-destroy": "node ./test/tests/eventlistener/hammerjs-destroy.js", "test-eventlistener-interactionmapper": "node ./test/tests/eventlistener/interactionmapper.js", "test-eventlistener-interactionmapper-off": "node ./test/tests/eventlistener/interactionmapper-off.js", - "build": "rollup --config ./rollup.config.js", + "build": "rollup --config --bundleConfigAsCjs ./rollup.config.js", "watch": "rollup --watch --config ./rollup.config.js", "3rdparty": "gulp", "prettier": "gulp prettify",