-
Notifications
You must be signed in to change notification settings - Fork 204
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Sidebar on window resize #2899
Sidebar on window resize #2899
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,6 +16,16 @@ import { ToolbarController } from './toolbar'; | |
* @prop {number} height | ||
*/ | ||
|
||
/** | ||
* @typedef {Window|HTMLElement} WindowOrHTMLElement | ||
* @typedef {Parameters<WindowOrHTMLElement["addEventListener"]>} ArgAddEventListener | ||
* @typedef {{ | ||
* object: WindowOrHTMLElement, | ||
* eventType: ArgAddEventListener[0], | ||
* listener:ArgAddEventListener[1] | ||
* }} RegisteredListener | ||
*/ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This works, although I probably would have gone with some types that were a bit more generic and simpler. Perhaps something like: /**
* @typedef {{
* target: EventTarget,
* eventType: string,
* listener: (e: Event) => void,
* }} RegisteredListener
*/ I notice that we have similar code in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I simplified it. |
||
|
||
// Minimum width to which the frame can be resized. | ||
const MIN_RESIZE = 280; | ||
|
||
|
@@ -53,7 +63,11 @@ function createSidebarIframe(config) { | |
* as well as the adjacent controls. | ||
*/ | ||
export default class Sidebar extends Guest { | ||
constructor(element, config) { | ||
/** | ||
* @param {HTMLElement} element | ||
* @param {Record<string, any>} config | ||
esanzgar marked this conversation as resolved.
Show resolved
Hide resolved
|
||
*/ | ||
constructor(element, config, hideOnResize = true) { | ||
if (config.theme === 'clean' || config.externalContainerSelector) { | ||
delete config.pluginClasses.BucketBar; | ||
} | ||
|
@@ -87,6 +101,9 @@ export default class Sidebar extends Guest { | |
|
||
super(element, { ...defaultConfig, ...config }); | ||
|
||
/** @type {RegisteredListener[]} */ | ||
this.registeredListeners = []; | ||
|
||
this.externalFrame = externalFrame; | ||
this.frame = frame; | ||
(frame || externalFrame).appendChild(sidebarFrame); | ||
|
@@ -117,7 +134,7 @@ export default class Sidebar extends Guest { | |
} | ||
|
||
if (this.plugins.BucketBar) { | ||
this.plugins.BucketBar.element.addEventListener('click', () => | ||
this._registerEvent(this.plugins.BucketBar.element, 'click', () => | ||
this.show() | ||
); | ||
} | ||
|
@@ -141,6 +158,10 @@ export default class Sidebar extends Guest { | |
this.toolbarWidth = 0; | ||
} | ||
|
||
if (hideOnResize) { | ||
this._registerEvent(window, 'resize', () => this._onResize()); | ||
} | ||
|
||
this._gestureState = { | ||
// Initial position at the start of a drag/pan resize event (in pixels). | ||
initial: /** @type {number|null} */ (null), | ||
|
@@ -169,11 +190,29 @@ export default class Sidebar extends Guest { | |
} | ||
|
||
destroy() { | ||
this._unregisterEvents(); | ||
this._hammerManager?.destroy(); | ||
this.frame?.remove(); | ||
super.destroy(); | ||
} | ||
|
||
/** | ||
* @param {WindowOrHTMLElement} object | ||
* @param {ArgAddEventListener[0]} eventType | ||
* @param {ArgAddEventListener[1]} listener | ||
*/ | ||
_registerEvent(object, eventType, listener) { | ||
object.addEventListener(eventType, listener); | ||
this.registeredListeners.push({ object, eventType, listener }); | ||
} | ||
|
||
_unregisterEvents() { | ||
this.registeredListeners.forEach(({ object, eventType, listener }) => { | ||
object.removeEventListener(eventType, listener); | ||
}); | ||
this.registeredListeners = []; | ||
} | ||
|
||
_setupSidebarEvents() { | ||
annotationCounts(document.body, this.crossframe); | ||
sidebarTrigger(document.body, () => this.show()); | ||
|
@@ -215,11 +254,11 @@ export default class Sidebar extends Guest { | |
const toggleButton = this.toolbar.sidebarToggleButton; | ||
if (toggleButton) { | ||
// Prevent any default gestures on the handle. | ||
toggleButton.addEventListener('touchmove', e => e.preventDefault()); | ||
this._registerEvent(toggleButton, 'touchmove', e => e.preventDefault()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The toggle button is part of an element that is owned by the sidebar. Since the sidebar frame is already removed by There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You are correct. However, it is a good idea to always remove all the events that have been added as a defensive programming technique. An example of why this is important: the sidebar (and pdf-sidebar) had an events attached to the window. Even when this element was destroy there was a dangling listener that contained a link to the sidebar component. |
||
|
||
this._hammerManager = new Hammer.Manager(toggleButton) | ||
// eslint-disable-next-line no-restricted-properties | ||
.on('panstart panend panleft panright', this._onPan.bind(this)); | ||
this._hammerManager = new Hammer.Manager( | ||
toggleButton | ||
).on('panstart panend panleft panright', () => this._onPan()); | ||
this._hammerManager.add( | ||
new Hammer.Pan({ direction: Hammer.DIRECTION_HORIZONTAL }) | ||
); | ||
|
@@ -308,6 +347,15 @@ export default class Sidebar extends Guest { | |
this.publish('sidebarLayoutChanged', [layoutState]); | ||
} | ||
|
||
/** | ||
* Minimize the sidebar on window resize event | ||
*/ | ||
_onResize() { | ||
if (this.toolbar.sidebarOpen === true) { | ||
this.hide(); | ||
} | ||
} | ||
|
||
_onPan(event) { | ||
const frame = this.frame; | ||
if (!frame) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not immediately clear from looking at this code what
false
. I would suggest that all configuration options should go into the existingconfig
argument where we can give it a useful name and more easily add new options.A more significant issue though is that there is an existing issue with the PDF sidebar where it becomes "detached" when the window size is reduced below a certain size. I think this is the issue that you mentioned in the PR description?