},
adBlocker: true,
window: {
+ isCloseConfirm: true,
isCustomTitlebar: true,
isMaximized: false,
bounds: {
getBaseWindow = (width = 1100, height = 680, minWidth = 320, minHeight = 200, x, y, frame = false) => {
return new BrowserWindow({
- width, height, minWidth, minHeight, x, y, 'titleBarStyle': 'hidden', frame, fullscreenable: true,
+ width, height, minWidth, minHeight, x, y, titleBarStyle: 'hidden', frame, fullscreenable: true,
+ icon: `${__dirname}/static/app/icon.png`,
show: false,
- icon: path.join(app.getAppPath(), 'static', 'app', 'icon.png'),
webPreferences: {
nodeIntegration: true,
webviewTag: true,
setPermissionRequestHandler = (ses, isPrivate = false) => {
if (!isPrivate) {
ses.setPermissionRequestHandler((webContents, permission, callback) => {
- db.pageSettings.findOne({ origin: `${parse(webContents.getURL()).protocol}//${parse(webContents.getURL()).hostname}` }, (err, doc) => {
+ const url = parse(webContents.getURL());
+
+ db.pageSettings.findOne({ origin: `${url.protocol}//${url.hostname}` }, (err, doc) => {
if (doc != undefined) {
if (permission == 'media' && doc.media != undefined && doc.media > -1)
return callback(doc.media === 0);
if (permission == 'openExternal' && doc.openExternal != undefined && doc.openExternal > -1)
return callback(doc.openExternal === 0);
} else {
+ if (Notification.isSupported()) {
+ const notify = new Notification({
+ title: `${url.protocol}//${url.hostname} が権限を要求しています。`,
+ body: '詳細はここをクリックしてください。',
+ silent: true
+ });
+
+ notify.show();
+
+ notify.on('click', (e) => {
+ dialog.showMessageBox({
+ type: 'info',
+ title: '権限の要求',
+ message: `${url.protocol}//${url.hostname} が権限を要求しています。`,
+ detail: `要求内容: ${permission}`,
+ checkboxLabel: 'このサイトでは今後も同じ処理をする',
+ checkboxChecked: false,
+ noLink: true,
+ buttons: ['はい / Yes', 'いいえ / No'],
+ defaultId: 0,
+ cancelId: 1
+ }, (res, checked) => {
+ console.log(res, checked);
+ if (checked) {
+ if (permission == 'media')
+ db.pageSettings.update({ origin: `${url.protocol}//${url.hostname}` }, { origin: `${url.protocol}//${url.hostname}`, media: res }, { upsert: true });
+ if (permission == 'geolocation')
+ db.pageSettings.update({ origin: `${url.protocol}//${url.hostname}` }, { origin: `${url.protocol}//${url.hostname}`, geolocation: res }, { upsert: true });
+ if (permission == 'notifications')
+ db.pageSettings.update({ origin: `${url.protocol}//${url.hostname}` }, { origin: `${url.protocol}//${url.hostname}`, notifications: res }, { upsert: true });
+ if (permission == 'midiSysex')
+ db.pageSettings.update({ origin: `${url.protocol}//${url.hostname}` }, { origin: `${url.protocol}//${url.hostname}`, midiSysex: res }, { upsert: true });
+ if (permission == 'pointerLock')
+ db.pageSettings.update({ origin: `${url.protocol}//${url.hostname}` }, { origin: `${url.protocol}//${url.hostname}`, pointerLock: res }, { upsert: true });
+ if (permission == 'fullscreen')
+ db.pageSettings.update({ origin: `${url.protocol}//${url.hostname}` }, { origin: `${url.protocol}//${url.hostname}`, fullscreen: res }, { upsert: true });
+ if (permission == 'openExternal')
+ db.pageSettings.update({ origin: `${url.protocol}//${url.hostname}` }, { origin: `${url.protocol}//${url.hostname}`, openExternal: res }, { upsert: true });
+ }
+ return callback(res === 0);
+ });
+ });
+ notify.on('close', (e) => {
+ return callback(false);
+ });
+ } else {
+ dialog.showMessageBox({
+ type: 'info',
+ title: '権限の要求',
+ message: `${url.protocol}//${url.hostname} が権限を要求しています。`,
+ detail: `要求内容: ${permission}`,
+ checkboxLabel: 'このサイトでは今後も同じ処理をする',
+ checkboxChecked: false,
+ noLink: true,
+ buttons: ['はい / Yes', 'いいえ / No'],
+ defaultId: 0,
+ cancelId: 1
+ }, (res, checked) => {
+ if (checked) {
+ if (permission == 'media')
+ db.pageSettings.update({ origin: `${url.protocol}//${url.hostname}` }, { origin: `${url.protocol}//${url.hostname}`, media: res }, { upsert: true });
+ if (permission == 'geolocation')
+ db.pageSettings.update({ origin: `${url.protocol}//${url.hostname}` }, { origin: `${url.protocol}//${url.hostname}`, geolocation: res }, { upsert: true });
+ if (permission == 'notifications')
+ db.pageSettings.update({ origin: `${url.protocol}//${url.hostname}` }, { origin: `${url.protocol}//${url.hostname}`, notifications: res }, { upsert: true });
+ if (permission == 'midiSysex')
+ db.pageSettings.update({ origin: `${url.protocol}//${url.hostname}` }, { origin: `${url.protocol}//${url.hostname}`, midiSysex: res }, { upsert: true });
+ if (permission == 'pointerLock')
+ db.pageSettings.update({ origin: `${url.protocol}//${url.hostname}` }, { origin: `${url.protocol}//${url.hostname}`, pointerLock: res }, { upsert: true });
+ if (permission == 'fullscreen')
+ db.pageSettings.update({ origin: `${url.protocol}//${url.hostname}` }, { origin: `${url.protocol}//${url.hostname}`, fullscreen: res }, { upsert: true });
+ if (permission == 'openExternal')
+ db.pageSettings.update({ origin: `${url.protocol}//${url.hostname}` }, { origin: `${url.protocol}//${url.hostname}`, openExternal: res }, { upsert: true });
+ }
+ return callback(res === 0);
+ });
+ }
+ }
+ });
+ });
+ } else {
+ ses.setPermissionRequestHandler((webContents, permission, callback) => {
+ const url = parse(webContents.getURL());
+ if (Notification.isSupported()) {
+ const notify = new Notification({
+ title: `${url.protocol}//${url.hostname} が権限を要求しています。`,
+ body: '詳細はここをクリックしてください。(プライベート モード)',
+ silent: true
+ });
+
+ notify.show();
+
+ notify.on('click', (e) => {
dialog.showMessageBox({
type: 'info',
title: '権限の要求',
- message: `${parse(webContents.getURL()).protocol}//${parse(webContents.getURL()).hostname} が権限を要求しています。`,
+ message: `${url.protocol}//${url.hostname} が権限を要求しています。`,
detail: `要求内容: ${permission}`,
- checkboxLabel: 'このサイトでは今後も同じ処理をする',
- checkboxChecked: false,
noLink: true,
- buttons: ['Yes', 'No'],
+ buttons: ['はい / Yes', 'いいえ / No'],
defaultId: 0,
cancelId: 1
- }, (res, checked) => {
- console.log(res, checked);
- if (checked) {
- if (permission == 'media')
- db.pageSettings.update({ origin: `${parse(webContents.getURL()).protocol}//${parse(webContents.getURL()).hostname}` }, { origin: `${parse(webContents.getURL()).protocol}//${parse(webContents.getURL()).hostname}`, media: res }, { upsert: true });
- if (permission == 'geolocation')
- db.pageSettings.update({ origin: `${parse(webContents.getURL()).protocol}//${parse(webContents.getURL()).hostname}` }, { origin: `${parse(webContents.getURL()).protocol}//${parse(webContents.getURL()).hostname}`, geolocation: res }, { upsert: true });
- if (permission == 'notifications')
- db.pageSettings.update({ origin: `${parse(webContents.getURL()).protocol}//${parse(webContents.getURL()).hostname}` }, { origin: `${parse(webContents.getURL()).protocol}//${parse(webContents.getURL()).hostname}`, notifications: res }, { upsert: true });
- if (permission == 'midiSysex')
- db.pageSettings.update({ origin: `${parse(webContents.getURL()).protocol}//${parse(webContents.getURL()).hostname}` }, { origin: `${parse(webContents.getURL()).protocol}//${parse(webContents.getURL()).hostname}`, midiSysex: res }, { upsert: true });
- if (permission == 'pointerLock')
- db.pageSettings.update({ origin: `${parse(webContents.getURL()).protocol}//${parse(webContents.getURL()).hostname}` }, { origin: `${parse(webContents.getURL()).protocol}//${parse(webContents.getURL()).hostname}`, pointerLock: res }, { upsert: true });
- if (permission == 'fullscreen')
- db.pageSettings.update({ origin: `${parse(webContents.getURL()).protocol}//${parse(webContents.getURL()).hostname}` }, { origin: `${parse(webContents.getURL()).protocol}//${parse(webContents.getURL()).hostname}`, fullscreen: res }, { upsert: true });
- if (permission == 'openExternal')
- db.pageSettings.update({ origin: `${parse(webContents.getURL()).protocol}//${parse(webContents.getURL()).hostname}` }, { origin: `${parse(webContents.getURL()).protocol}//${parse(webContents.getURL()).hostname}`, openExternal: res }, { upsert: true });
- }
+ }, (res) => {
return callback(res === 0);
});
- }
- });
- });
- } else {
- ses.setPermissionRequestHandler((webContents, permission, callback) => {
- dialog.showMessageBox({
- type: 'info',
- title: '権限の要求',
- message: `${parse(webContents.getURL()).protocol}//${parse(webContents.getURL()).hostname} が権限を要求しています。`,
- detail: `要求内容: ${permission}`,
- noLink: true,
- buttons: ['Yes', 'No'],
- defaultId: 0,
- cancelId: 1
- }, (res) => {
- return callback(res === 0);
- });
+ });
+ notify.on('close', (e) => {
+ return callback(false);
+ });
+ } else {
+ dialog.showMessageBox({
+ type: 'info',
+ title: '権限の要求',
+ message: `${url.protocol}//${url.hostname} が権限を要求しています。`,
+ detail: `要求内容: ${permission}`,
+ noLink: true,
+ buttons: ['はい / Yes', 'いいえ / No'],
+ defaultId: 0,
+ cancelId: 1
+ }, (res) => {
+ return callback(res === 0);
+ });
+ }
});
}
}
});
config.clear();
+ db.pageSettings.remove({}, { multi: true });
+
db.historys.remove({}, { multi: true });
db.downloads.remove({}, { multi: true });
db.bookmarks.remove({}, { multi: true });
this.updateNavigationState(windowId, view);
});
view.webContents.on('did-fail-load', (e, code, description, url, isMainFrame, processId, routingId) => {
- if (view.isDestroyed()) return;
+ if (view.isDestroyed() || !isMainFrame) return;
- dialog.showMessageBox({message: `${code}: ${description}`});
+ dialog.showMessageBox({ message: `${code}: ${description}` });
});
view.webContents.on('did-start-navigation', (e) => {
view.webContents.on('before-input-event', (e, input) => {
if (view.isDestroyed()) return;
+ console.log((input.control || (platform.isDarwin && input.meta)) || input.alt)
+ window.webContents.setIgnoreMenuShortcuts(true);
- if (input.control || (platform.isDarwin && input.meta)) {
- console.log(input.control, input.alt, input.shift, input.key);
-
+ if (input.control) {
if (input.shift && input.key == 'I') {
e.preventDefault();
+ window.webContents.setIgnoreMenuShortcuts(true);
+ view.webContents.setIgnoreMenuShortcuts(true);
+
if (view.webContents.isDevToolsOpened()) {
view.webContents.devToolsWebContents.focus();
} else {
}
} else if (input.shift && input.key == 'R') {
e.preventDefault();
+ window.webContents.setIgnoreMenuShortcuts(true);
+ view.webContents.setIgnoreMenuShortcuts(true);
+
view.webContents.reloadIgnoringCache();
} else if (input.key == 'T') {
e.preventDefault();
- this.addView(windowId, config.get('homePage.defaultPage'), true)
+ window.webContents.setIgnoreMenuShortcuts(true);
+ // view.webContents.setIgnoreMenuShortcuts(true);
+
+ console.log('test');
+ this.addView(windowId, config.get('homePage.defaultPage'), true);
}
} else if (input.alt) {
if (input.key == 'ArrowLeft') {
e.preventDefault();
+ // window.webContents.setIgnoreMenuShortcuts(true);
+ view.webContents.setIgnoreMenuShortcuts(true);
+
if (view.webContents.canGoBack())
view.webContents.goBack();
} else if (input.key == 'ArrowRight') {
e.preventDefault();
+ // window.webContents.setIgnoreMenuShortcuts(true);
+ view.webContents.setIgnoreMenuShortcuts(true);
+
if (view.webContents.canGoForward())
view.webContents.goForward();
}
} else {
if (input.key == 'F11') {
e.preventDefault();
+ window.webContents.setIgnoreMenuShortcuts(true);
+ view.webContents.setIgnoreMenuShortcuts(true);
+
window.setFullScreen(!window.isFullScreen());
this.fixBounds(windowId, (floatingWindows.indexOf(windowId) != -1));
}
item.once('done', (e, state) => {
db.downloads.update({ id: str }, { $set: { name: item.getFilename(), url: item.getURL(), type: item.getMimeType(), size: item.getTotalBytes(), path: item.getSavePath(), status: state } });
+
+ if (!Notification.isSupported()) return;
+ const notify = new Notification({
+ title: 'ダウンロード完了',
+ body: `${item.getFilename()} のダウンロードが完了しました。`
+ });
+
+ notify.show();
});
});
import isURL from './Utils/isURL';
-const protocolStr = 'flast';
-const fileProtocolStr = `${protocolStr}-file`;
-
const { remote, ipcRenderer, shell } = window.require('electron');
const { app, systemPreferences, Menu, MenuItem, dialog } = remote;
+const pkg = window.require(`${app.getAppPath()}/package.json`);
+const protocolStr = 'flast';
+const fileProtocolStr = `${protocolStr}-file`;
+
const platform = window.require('electron-platform');
const { parse, format } = window.require('url');
const path = window.require('path');
<ToolbarButton isDarkModeOrPrivateMode={config.get('design.darkTheme') || String(this.props.windowId).startsWith('private')} src={this.isDarkModeOrPrivateMode.bind(this, LightHomeIcon, DarkHomeIcon)} size={24}
isShowing={config.get('design.homeButton')} isRight={false} isMarginLeft={false} isEnabled={true} title="ホームページに移動" onClick={() => { this.goHome(); }} />
<ToolbarTextBoxWrapper isDarkModeOrPrivateMode={config.get('design.darkTheme') || String(this.props.windowId).startsWith('private')} buttonCount={config.get('design.homeButton') ? 6 : 5}>
- <Tippy content={this.state.isTrusted ? (parse(this.state.barText).protocol == 'flast:' ? `保護された ${process.env.npm_package_name} ページを表示しています` : 'このサイトへの接続は保護されています') : 'このサイトへの接続は保護されていません'} theme={config.get('design.darkTheme') || String(this.props.windowId).startsWith('private') ? 'dark' : 'light'} placement="right" arrow={true}>
+ <Tippy content={this.state.isTrusted ? (parse(this.state.barText).protocol == 'flast:' ? `保護された ${pkg.name} ページを表示しています` : 'このサイトへの接続は保護されています') : 'このサイトへの接続は保護されていません'} theme={config.get('design.darkTheme') || String(this.props.windowId).startsWith('private') ? 'dark' : 'light'} placement="right" arrow={true}>
<ToolbarButton src={this.state.isTrusted ? this.isDarkModeOrPrivateMode.bind(this, LightSecureIcon, DarkSecureIcon) : this.isDarkModeOrPrivateMode.bind(this, LightInSecureIcon, DarkInSecureIcon)} size={12}
isShowing={true} isRight={false} isMarginLeft={true} isEnabled={true} title="このページの情報" />
</Tippy>
closeWindow = () => {
if (this.state.tabs.length > 1) {
- const dlg = dialog.showMessageBox(remote.getCurrentWindow(), {
- type: 'info',
- buttons: ['Yes', 'No'],
- title: 'アプリ終了確認',
- message: `${this.state.tabs.length}個のタブを閉じようとしています。`,
- detail: `${this.state.tabs.length}個のタブを閉じてアプリを終了しようとしています。\n複数のタブを閉じてアプリを終了してもよろしいでしょうか?`,
- defaultId: 0,
- cancelId: 1
- });
- if (dlg === 0) {
+ if (config.get('window.isCloseConfirm')) {
+ dialog.showMessageBox(remote.getCurrentWindow(), {
+ type: 'info',
+ title: 'アプリ終了確認',
+ message: `${this.state.tabs.length}個のタブを閉じようとしています。`,
+ detail: `${this.state.tabs.length}個のタブを閉じてアプリを終了しようとしています。\n複数のタブを閉じてアプリを終了してもよろしいでしょうか?`,
+ checkboxLabel: '今後は確認しない',
+ checkboxChecked: false,
+ noLink: true,
+ buttons: ['はい / Yes', 'いいえ / No'],
+ defaultId: 0,
+ cancelId: 1
+ }, (res, checked) => {
+ if (checked)
+ config.set('window.isCloseConfirm', false);
+ if (res === 0)
+ remote.getCurrentWindow().close();
+ });
+ } else {
remote.getCurrentWindow().close();
}
} else {