Change: detect all kinds of manager in openManage
This commit is contained in:
parent
c2ac963232
commit
b66b015252
|
@ -1,6 +1,8 @@
|
|||
/* global download prefs openURL FIREFOX CHROME VIVALDI
|
||||
debounce URLS ignoreChromeError getTab
|
||||
styleManager msg navigatorUtil iconUtil workerUtil contentScripts sync */
|
||||
styleManager msg navigatorUtil iconUtil workerUtil contentScripts sync
|
||||
findExistTab createTab activateTab isTabReplaceable getActiveTab */
|
||||
|
||||
'use strict';
|
||||
|
||||
// eslint-disable-next-line no-var
|
||||
|
@ -412,12 +414,32 @@ function openEditor(params) {
|
|||
}
|
||||
|
||||
function openManage({options = false, search} = {}) {
|
||||
let url = 'manage.html';
|
||||
let url = chrome.runtime.getURL('manage.html');
|
||||
if (search) {
|
||||
url += `?search=${encodeURIComponent(search)}`;
|
||||
}
|
||||
if (options) {
|
||||
url += '#stylus-options';
|
||||
}
|
||||
return openURL({url, currentWindow: null});
|
||||
return findExistTab({
|
||||
url,
|
||||
currentWindow: null,
|
||||
ignoreHash: true,
|
||||
ignoreSearch: true
|
||||
})
|
||||
.then(tab => {
|
||||
if (tab) {
|
||||
return Promise.all([
|
||||
activateTab(tab),
|
||||
tab.url !== url && msg.sendTab(tab.id, {method: 'pushState', url})
|
||||
.catch(console.warn)
|
||||
]);
|
||||
}
|
||||
return getActiveTab().then(tab => {
|
||||
if (isTabReplaceable(tab, url)) {
|
||||
return activateTab(tab, {url});
|
||||
}
|
||||
return createTab({url});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -260,18 +260,6 @@ const APPLY = (() => {
|
|||
case 'updateCount':
|
||||
updateCount();
|
||||
break;
|
||||
|
||||
case 'trimHash':
|
||||
if (IS_OWN_PAGE) {
|
||||
// FIXME: currently we only do this in our own page. Is it safe to do
|
||||
// it on all pages?
|
||||
try {
|
||||
// history.replaceState(null, null, ' ');
|
||||
// eslint-disable-next-line no-undef
|
||||
router.updateHash('');
|
||||
} catch (err) {}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* exported getActiveTab onTabReady stringAsRegExp getTabRealURL openURL
|
||||
getStyleWithNoCode tryRegExp sessionStorageHash download deepEqual
|
||||
closeCurrentTab capitalize CHROME_HAS_BORDER_BUG */
|
||||
/* global promisify msg */
|
||||
/* global promisify */
|
||||
'use strict';
|
||||
|
||||
const CHROME = Boolean(chrome.app) && parseInt(navigator.userAgent.match(/Chrom\w+\/(?:\d+\.){2}(\d+)|$/)[1]);
|
||||
|
@ -195,21 +195,38 @@ function onTabReady(tabOrId) {
|
|||
});
|
||||
}
|
||||
|
||||
function urlToMatchPattern(url) {
|
||||
function urlToMatchPattern(url, ignoreSearch) {
|
||||
// https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Match_patterns
|
||||
if (!/^(http|https|ws|wss|ftp|data|file)$/.test(url.protocol)) {
|
||||
return undefined;
|
||||
}
|
||||
if (ignoreSearch) {
|
||||
return [
|
||||
`${url.protocol}//${url.hostname}/${url.pathname}`,
|
||||
`${url.protocol}//${url.hostname}/${url.pathname}?*`
|
||||
];
|
||||
}
|
||||
// FIXME: is %2f allowed in pathname and search?
|
||||
return `${url.protocol}//${url.hostname}/${url.pathname}${url.search}`;
|
||||
}
|
||||
|
||||
function findExistTab(url, currentWindow) {
|
||||
function findExistTab({url, currentWindow, ignoreHash = true, ignoreSearch = false}) {
|
||||
url = new URL(url);
|
||||
const normalizedUrl = url.href.split('#')[0];
|
||||
return queryTabs({url: urlToMatchPattern(url), currentWindow})
|
||||
return queryTabs({url: urlToMatchPattern(url, ignoreSearch), currentWindow})
|
||||
// FIXME: is tab.url always normalized?
|
||||
.then(tabs => tabs.find(tab => tab.url.split('#')[0] === normalizedUrl));
|
||||
.then(tabs => tabs.find(matchTab));
|
||||
|
||||
function matchTab(tab) {
|
||||
const tabUrl = new URL(tab.url);
|
||||
return tabUrl.protocol === url.protocol &&
|
||||
tabUrl.username === url.username &&
|
||||
tabUrl.password === url.password &&
|
||||
tabUrl.hostname === url.hostname &&
|
||||
tabUrl.port === url.port &&
|
||||
tabUrl.pathname === url.pathname &&
|
||||
(ignoreSearch || tabUrl.search === url.search) &&
|
||||
(ignoreHash || tabUrl.hash === url.hash);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -246,49 +263,49 @@ function openURL(options) {
|
|||
if (!url.includes('://')) {
|
||||
url = chrome.runtime.getURL(url);
|
||||
}
|
||||
return findExistTab(url, currentWindow)
|
||||
.then(tab => {
|
||||
if (!tab) {
|
||||
return getActiveTab().then(maybeReplace);
|
||||
}
|
||||
return findExistTab({url, currentWindow}).then(tab => {
|
||||
if (tab) {
|
||||
// update url if only hash is different?
|
||||
if (tab.url !== url && tab.url.split('#')[0] === url.split('#')[0]) {
|
||||
if (url.includes('#')) {
|
||||
return activateTab(tab, {url, index});
|
||||
} else {
|
||||
// we can't update URL directly since it refresh the page
|
||||
return Promise.all([
|
||||
activateTab(tab, {index}),
|
||||
msg.sendTab(tab.id, {method: 'trimHash'}).catch(console.warn)
|
||||
]);
|
||||
}
|
||||
// we can't update URL if !url.includes('#') since it refreshes the page
|
||||
if (tab.url !== url && tab.url.split('#')[0] === url.split('#')[0] &&
|
||||
url.includes('#')) {
|
||||
return activateTab(tab, {url, index});
|
||||
}
|
||||
return activateTab(tab, {index});
|
||||
});
|
||||
|
||||
// update current NTP or about:blank
|
||||
// except when 'url' is chrome:// or chrome-extension:// in incognito
|
||||
function maybeReplace(tab) {
|
||||
const chromeInIncognito = tab && tab.incognito && url.startsWith('chrome');
|
||||
const emptyTab = tab && URLS.emptyTab.includes(tab.url);
|
||||
if (emptyTab && !chromeInIncognito) {
|
||||
return activateTab(tab, {url, index}); // FIXME: should we move current empty tab?
|
||||
}
|
||||
if (newWindow) {
|
||||
return createWindow(Object.assign({url}, windowPosition));
|
||||
}
|
||||
const options = {url, index, active};
|
||||
// FF57+ supports openerTabId, but not in Android (indicated by the absence of chrome.windows)
|
||||
// FIXME: is it safe to assume that the current tab is the opener?
|
||||
if (tab && (!FIREFOX || FIREFOX >= 57 && chrome.windows) && !chromeInIncognito) {
|
||||
options.openerTabId = tab.id;
|
||||
}
|
||||
return createTab(options);
|
||||
}
|
||||
return getActiveTab().then(tab => {
|
||||
if (isTabReplaceable(tab, url)) {
|
||||
return activateTab(tab, {url, index});
|
||||
}
|
||||
const options = {url, index, active};
|
||||
// FF57+ supports openerTabId, but not in Android (indicated by the absence of chrome.windows)
|
||||
// FIXME: is it safe to assume that the current tab is the opener?
|
||||
if (tab && !tab.incognito && (!FIREFOX || FIREFOX >= 57 && chrome.windows)) {
|
||||
options.openerTabId = tab.id;
|
||||
}
|
||||
return createTab(options);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// replace empty tab (NTP or about:blank)
|
||||
// except when new URL is chrome:// or chrome-extension:// and the empty tab is
|
||||
// in incognito
|
||||
function isTabReplaceable(tab, newUrl) {
|
||||
if (!tab || !URLS.emptyTab.includes(tab.url)) {
|
||||
return false;
|
||||
}
|
||||
// FIXME: why?
|
||||
if (tab.incognito && newUrl.startsWith('chrome')) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function activateTab(tab, {url, index}) {
|
||||
function activateTab(tab, {url, index} = {}) {
|
||||
const options = {active: true};
|
||||
if (url) {
|
||||
options.url = url;
|
||||
|
@ -297,7 +314,8 @@ function activateTab(tab, {url, index}) {
|
|||
updateTab(tab.id, options),
|
||||
updateWindow(tab.windowId, {focused: true}),
|
||||
index != null && moveTabs(tab.id, {index})
|
||||
]);
|
||||
])
|
||||
.then(() => tab);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* global deepEqual */
|
||||
/* global deepEqual msg */
|
||||
/* exported router */
|
||||
'use strict';
|
||||
|
||||
|
@ -8,6 +8,12 @@ const router = (() => {
|
|||
document.addEventListener('DOMContentLoaded', () => update());
|
||||
window.addEventListener('popstate', () => update());
|
||||
window.addEventListener('hashchange', () => update());
|
||||
msg.on(e => {
|
||||
if (e.method === 'pushState' && e.url !== location.href) {
|
||||
history.pushState(history.state, null, e.url);
|
||||
update();
|
||||
}
|
||||
});
|
||||
return {watch, updateSearch, getSearch, updateHash};
|
||||
|
||||
function watch(options, callback) {
|
||||
|
|
|
@ -150,9 +150,9 @@
|
|||
<script src="js/promisify.js"></script>
|
||||
<script src="js/dom.js"></script>
|
||||
<script src="js/messaging.js"></script>
|
||||
<script src="js/router.js"></script>
|
||||
<script src="js/prefs.js"></script>
|
||||
<script src="js/msg.js"></script>
|
||||
<script src="js/router.js"></script>
|
||||
<script src="content/style-injector.js"></script>
|
||||
<script src="content/apply.js"></script>
|
||||
<script src="js/localization.js"></script>
|
||||
|
|
|
@ -12,9 +12,7 @@ const filtersSelector = {
|
|||
let initialized = false;
|
||||
|
||||
router.watch({search: ['search']}, ([search]) => {
|
||||
if (search != null) {
|
||||
$('#search').value = search;
|
||||
}
|
||||
$('#search').value = search || '';
|
||||
if (!initialized) {
|
||||
init();
|
||||
} else {
|
||||
|
|
Loading…
Reference in New Issue
Block a user