[simple-window editor] embed popup as iframe

This commit is contained in:
tophf 2020-11-23 23:22:41 +03:00
parent b59737a012
commit 8b58b22825
2 changed files with 110 additions and 3 deletions

View File

@ -29,6 +29,35 @@ body {
display: none !important;
}
/************ embedded popup for simple-window editor ************/
#popup-iframe {
max-height: 600px;
position: fixed;
right: 0;
top: 0;
z-index: 1001;
border: none;
background: #fff;
box-shadow: 0 0 30px #000;
}
#popup-iframe:not([data-loaded]) {
opacity: 0;
}
#popup-button {
position: fixed;
right: 7px;
top: 11px;
z-index: 1000;
cursor: pointer;
transition: filter .25s;
}
#popup-button:hover {
filter: drop-shadow(0 0 3px hsl(180, 70%, 50%));
}
body:not(.compact-layout) #popup-button {
right: 24px;
}
/************ checkbox & select************/
.options-column > div[class="option"] {
margin-bottom: 4px;

View File

@ -12,6 +12,7 @@
DirtyReporter
DocFuncMapper
FIREFOX
getEventKeyName
getOwnTab
initBeautifyButton
linter
@ -36,6 +37,7 @@ const editor = {
isUsercss: false,
previewDelay: 200, // Chrome devtools uses 200
};
let isSimpleWindow;
let isWindowed;
let headerHeight;
@ -372,11 +374,34 @@ function lazyInit() {
}
}
async function detectWindowedState() {
isWindowed =
isSimpleWindow =
(await browser.windows.getCurrent()).type === 'popup';
isWindowed = isSimpleWindow || (
prefs.get('openEditInWindow') &&
history.length === 1 &&
browser.windows.getAll().length > 1 &&
(await browser.tabs.query({currentWindow: true})).length === 1;
(await browser.windows.getAll()).length > 1 &&
(await browser.tabs.query({currentWindow: true})).length === 1
);
if (isSimpleWindow) {
await onDOMready();
initPopupButton();
}
}
function initPopupButton() {
const POPUP_HOTKEY = 'Shift-Ctrl-Alt-S';
const btn = $create('img', {
id: 'popup-button',
title: t('optionsCustomizePopup') + '\n' + POPUP_HOTKEY,
onclick: embedPopup,
});
const onIconsetChanged = (_, val) => {
const prefix = `images/icon/${val ? 'light/' : ''}`;
btn.srcset = `${prefix}16.png 1x,${prefix}32.png 2x`;
};
prefs.subscribe('iconset', onIconsetChanged, {now: true});
document.body.appendChild(btn);
window.on('keydown', e => getEventKeyName(e) === POPUP_HOTKEY && embedPopup());
CodeMirror.defaults.extraKeys[POPUP_HOTKEY] = 'openStylusPopup'; // adds to keymap help
}
async function onAttached(tabId, info) {
if (tabId !== ownTabId) {
@ -609,3 +634,56 @@ function isWindowMaximized() {
window.outerHeight < screen.availHeight + 10
);
}
function embedPopup() {
const ID = 'popup-iframe';
const SEL = '#' + ID;
if ($(SEL)) return;
const frame = $create('iframe', {
id: ID,
src: chrome.runtime.getManifest().browser_action.default_popup,
height: 600,
width: prefs.get('popupWidth'),
onload() {
frame.onload = null;
frame.focus();
const pw = frame.contentWindow;
pw.on('keydown', e => getEventKeyName(e) === 'Escape' && embedPopup._close());
pw.close = embedPopup._close;
if (pw.IntersectionObserver) {
let loaded;
new pw.IntersectionObserver(([e]) => {
const el = pw.document.scrollingElement;
const h = e.isIntersecting && !pw.scrollY ? el.offsetHeight : el.scrollHeight;
const hasSB = h > el.offsetHeight;
frame.height = h;
if (!hasSB !== !frame._scrollbarWidth) {
frame._scrollbarWidth = hasSB ? e.boundingClientRect.width - el.offsetWidth : 0;
frame.width = prefs.get('popupWidth') + frame._scrollbarWidth;
}
if (!loaded) {
loaded = true;
frame.dataset.loaded = '';
}
}).observe(pw.document.body.appendChild(
$create('div', {style: {height: '1px', marginTop: '-1px'}})
));
} else {
frame.dataset.loaded = '';
frame.height = pw.document.body.scrollHeight;
}
},
});
if (!embedPopup._close) {
embedPopup._close = () => {
$.remove(SEL);
window.off('mousedown', embedPopup._close);
};
prefs.subscribe('popupWidth', (_, w) => {
const el = $(SEL);
if (el) el.width = w + el._scrollbarWidth;
}, {now: true});
}
window.on('mousedown', embedPopup._close);
document.body.appendChild(frame);
}