Scale popup based on current page zoom factor

This commit is contained in:
toasted-nutbread 2019-12-23 17:12:09 -05:00
parent 22afab2f47
commit e740965d4f
5 changed files with 61 additions and 12 deletions

View File

@ -89,7 +89,11 @@ class DisplayFloat extends Display {
} }
} }
async initialize(options, popupInfo, url, childrenSupported) { setContentScale(scale) {
document.body.style.fontSize = `${scale}em`;
}
async initialize(options, popupInfo, url, childrenSupported, scale) {
await super.initialize(options); await super.initialize(options);
const {id, depth, parentFrameId} = popupInfo; const {id, depth, parentFrameId} = popupInfo;
@ -99,6 +103,8 @@ class DisplayFloat extends Display {
if (childrenSupported) { if (childrenSupported) {
popupNestedInitialize(id, depth, parentFrameId, url); popupNestedInitialize(id, depth, parentFrameId, url);
} }
this.setContentScale(scale);
} }
} }
@ -116,7 +122,8 @@ DisplayFloat._messageHandlers = new Map([
['setContent', (self, {type, details}) => self.setContent(type, details)], ['setContent', (self, {type, details}) => self.setContent(type, details)],
['clearAutoPlayTimer', (self) => self.clearAutoPlayTimer()], ['clearAutoPlayTimer', (self) => self.clearAutoPlayTimer()],
['setCustomCss', (self, {css}) => self.setCustomCss(css)], ['setCustomCss', (self, {css}) => self.setCustomCss(css)],
['initialize', (self, {options, popupInfo, url, childrenSupported}) => self.initialize(options, popupInfo, url, childrenSupported)] ['initialize', (self, {options, popupInfo, url, childrenSupported, scale}) => self.initialize(options, popupInfo, url, childrenSupported, scale)],
['setContentScale', (self, {scale}) => self.setContentScale(scale)]
]); ]);
DisplayFloat.instance = new DisplayFloat(); DisplayFloat.instance = new DisplayFloat();

View File

@ -34,6 +34,8 @@ class Frontend extends TextScanner {
url: popup.url url: popup.url
}; };
this._pageZoomFactor = 1.0;
this._contentScale = 1.0;
this._orphaned = true; this._orphaned = true;
this._lastShowPromise = Promise.resolve(); this._lastShowPromise = Promise.resolve();
} }
@ -41,11 +43,14 @@ class Frontend extends TextScanner {
async prepare() { async prepare() {
try { try {
await this.updateOptions(); await this.updateOptions();
const {zoomFactor} = await apiGetZoom();
this.onZoomChanged({newZoomFactor: zoomFactor});
window.addEventListener('resize', this.onResize.bind(this), false); window.addEventListener('resize', this.onResize.bind(this), false);
yomichan.on('orphaned', () => this.onOrphaned()); yomichan.on('orphaned', () => this.onOrphaned());
yomichan.on('optionsUpdate', () => this.updateOptions()); yomichan.on('optionsUpdate', () => this.updateOptions());
yomichan.on('zoomChanged', (e) => this.onZoomChanged(e));
chrome.runtime.onMessage.addListener(this.onRuntimeMessage.bind(this)); chrome.runtime.onMessage.addListener(this.onRuntimeMessage.bind(this));
} catch (e) { } catch (e) {
this.onError(e); this.onError(e);
@ -80,6 +85,11 @@ class Frontend extends TextScanner {
this._orphaned = true; this._orphaned = true;
} }
onZoomChanged({newZoomFactor}) {
this._pageZoomFactor = newZoomFactor;
this._updateContentScale();
}
getMouseEventListeners() { getMouseEventListeners() {
return [ return [
...super.getMouseEventListeners(), ...super.getMouseEventListeners(),
@ -90,6 +100,7 @@ class Frontend extends TextScanner {
async updateOptions() { async updateOptions() {
this.setOptions(await apiOptionsGet(this.getOptionsContext())); this.setOptions(await apiOptionsGet(this.getOptionsContext()));
await this.popup.setOptions(this.options); await this.popup.setOptions(this.options);
this._updateContentScale();
} }
async onSearchSource(textSource, cause) { async onSearchSource(textSource, cause) {
@ -183,6 +194,15 @@ class Frontend extends TextScanner {
); );
return this._lastShowPromise; return this._lastShowPromise;
} }
_updateContentScale() {
const contentScale = 1.0 / this._pageZoomFactor; // TODO : Use options
if (contentScale === this._contentScale) { return; }
this._contentScale = contentScale;
this.popup.setContentScale(this._contentScale);
this.onResize();
}
} }
Frontend._windowMessageHandlers = new Map([ Frontend._windowMessageHandlers = new Map([

View File

@ -41,7 +41,8 @@ class PopupProxyHost {
['containsPoint', ({id, x, y}) => this._onApiContainsPoint(id, x, y)], ['containsPoint', ({id, x, y}) => this._onApiContainsPoint(id, x, y)],
['showContent', ({id, elementRect, writingMode, type, details}) => this._onApiShowContent(id, elementRect, writingMode, type, details)], ['showContent', ({id, elementRect, writingMode, type, details}) => this._onApiShowContent(id, elementRect, writingMode, type, details)],
['setCustomCss', ({id, css}) => this._onApiSetCustomCss(id, css)], ['setCustomCss', ({id, css}) => this._onApiSetCustomCss(id, css)],
['clearAutoPlayTimer', ({id}) => this._onApiClearAutoPlayTimer(id)] ['clearAutoPlayTimer', ({id}) => this._onApiClearAutoPlayTimer(id)],
['setContentScale', ({id, scale}) => this._onApiSetContentScale(id, scale)]
])); ]));
} }
@ -97,6 +98,11 @@ class PopupProxyHost {
return popup.clearAutoPlayTimer(); return popup.clearAutoPlayTimer();
} }
async _onApiSetContentScale(id, scale) {
const popup = this._getPopup(id);
return popup.setContentScale(scale);
}
// Private functions // Private functions
_createPopupInternal(parentId, depth) { _createPopupInternal(parentId, depth) {

View File

@ -97,6 +97,11 @@ class PopupProxy {
this._invokeHostApi('clearAutoPlayTimer', {id: this._id}); this._invokeHostApi('clearAutoPlayTimer', {id: this._id});
} }
async setContentScale(scale) {
const id = await this._getPopupId();
this._invokeHostApi('setContentScale', {id, scale});
}
// Private // Private
_getPopupId() { _getPopupId() {

View File

@ -33,6 +33,7 @@ class Popup {
this._visibleOverride = null; this._visibleOverride = null;
this._options = null; this._options = null;
this._stylesheetInjectedViaApi = false; this._stylesheetInjectedViaApi = false;
this._contentScale = 1.0;
this._container = document.createElement('iframe'); this._container = document.createElement('iframe');
this._container.className = 'yomichan-float'; this._container.className = 'yomichan-float';
@ -120,6 +121,13 @@ class Popup {
} }
} }
setContentScale(scale) {
this._contentScale = scale;
if (this._isInjectedAndLoaded) {
this._invokeApi('setContentScale', {scale});
}
}
// Popup-only public functions // Popup-only public functions
setParent(parent) { setParent(parent) {
@ -225,7 +233,8 @@ class Popup {
parentFrameId parentFrameId
}, },
url: this.url, url: this.url,
childrenSupported: this._childrenSupported childrenSupported: this._childrenSupported,
scale: this._contentScale
}); });
resolve(); resolve();
}); });
@ -248,12 +257,14 @@ class Popup {
Popup._getPositionForVerticalText Popup._getPositionForVerticalText
); );
const scale = this._contentScale;
const [x, y, width, height, below] = getPosition( const [x, y, width, height, below] = getPosition(
elementRect, elementRect,
Math.max(containerRect.width, optionsGeneral.popupWidth), Math.max(containerRect.width, optionsGeneral.popupWidth * scale),
Math.max(containerRect.height, optionsGeneral.popupHeight), Math.max(containerRect.height, optionsGeneral.popupHeight * scale),
document.body.clientWidth, document.body.clientWidth,
window.innerHeight, window.innerHeight,
scale,
optionsGeneral, optionsGeneral,
writingMode writingMode
); );
@ -339,8 +350,8 @@ class Popup {
} }
} }
static _getPositionForHorizontalText(elementRect, width, height, maxWidth, maxHeight, optionsGeneral) { static _getPositionForHorizontalText(elementRect, width, height, maxWidth, maxHeight, offsetScale, optionsGeneral) {
let x = elementRect.left + optionsGeneral.popupHorizontalOffset; let x = elementRect.left + optionsGeneral.popupHorizontalOffset * offsetScale;
const overflowX = Math.max(x + width - maxWidth, 0); const overflowX = Math.max(x + width - maxWidth, 0);
if (overflowX > 0) { if (overflowX > 0) {
if (x >= overflowX) { if (x >= overflowX) {
@ -353,7 +364,7 @@ class Popup {
const preferBelow = (optionsGeneral.popupHorizontalTextPosition === 'below'); const preferBelow = (optionsGeneral.popupHorizontalTextPosition === 'below');
const verticalOffset = optionsGeneral.popupVerticalOffset; const verticalOffset = optionsGeneral.popupVerticalOffset * offsetScale;
const [y, h, below] = Popup._limitGeometry( const [y, h, below] = Popup._limitGeometry(
elementRect.top - verticalOffset, elementRect.top - verticalOffset,
elementRect.bottom + verticalOffset, elementRect.bottom + verticalOffset,
@ -365,10 +376,10 @@ class Popup {
return [x, y, width, h, below]; return [x, y, width, h, below];
} }
static _getPositionForVerticalText(elementRect, width, height, maxWidth, maxHeight, optionsGeneral, writingMode) { static _getPositionForVerticalText(elementRect, width, height, maxWidth, maxHeight, offsetScale, optionsGeneral, writingMode) {
const preferRight = Popup._isVerticalTextPopupOnRight(optionsGeneral.popupVerticalTextPosition, writingMode); const preferRight = Popup._isVerticalTextPopupOnRight(optionsGeneral.popupVerticalTextPosition, writingMode);
const horizontalOffset = optionsGeneral.popupHorizontalOffset2; const horizontalOffset = optionsGeneral.popupHorizontalOffset2 * offsetScale;
const verticalOffset = optionsGeneral.popupVerticalOffset2; const verticalOffset = optionsGeneral.popupVerticalOffset2 * offsetScale;
const [x, w] = Popup._limitGeometry( const [x, w] = Popup._limitGeometry(
elementRect.left - horizontalOffset, elementRect.left - horizontalOffset,