1
0
Fork 0
mirror of https://github.com/jellyfin/jellyfin-web synced 2025-03-30 19:56:21 +00:00
jellyfin-web/src/components/viewManager/viewManager.js

173 lines
4.6 KiB
JavaScript
Raw Normal View History

2020-08-02 17:44:03 +01:00
import viewContainer from 'viewContainer';
import focusManager from 'focusManager';
import queryString from 'queryString';
import layoutManager from 'layoutManager';
2020-08-02 17:44:03 +01:00
let currentView;
let dispatchPageEvents;
2020-08-02 17:44:03 +01:00
viewContainer.setOnBeforeChange(function (newView, isRestored, options) {
const lastView = currentView;
if (lastView) {
const beforeHideResult = dispatchViewEvent(lastView, null, 'viewbeforehide', true);
2020-08-02 17:44:03 +01:00
if (!beforeHideResult) {
// todo: cancel
}
2020-08-02 17:44:03 +01:00
}
2020-08-02 17:44:03 +01:00
const eventDetail = getViewEventDetail(newView, options, isRestored);
2020-08-02 17:44:03 +01:00
if (!newView.initComplete) {
newView.initComplete = true;
2020-08-02 17:44:03 +01:00
if (typeof options.controllerFactory === 'function') {
new options.controllerFactory(newView, eventDetail.detail.params);
} else if (options.controllerFactory && typeof options.controllerFactory.default === 'function') {
new options.controllerFactory.default(newView, eventDetail.detail.params);
}
2020-08-02 17:44:03 +01:00
if (!options.controllerFactory || dispatchPageEvents) {
dispatchViewEvent(newView, eventDetail, 'viewinit');
}
2020-08-02 17:44:03 +01:00
}
2020-08-02 17:44:03 +01:00
dispatchViewEvent(newView, eventDetail, 'viewbeforeshow');
});
2020-08-02 17:44:03 +01:00
function onViewChange(view, options, isRestore) {
const lastView = currentView;
if (lastView) {
dispatchViewEvent(lastView, null, 'viewhide');
}
2020-08-02 17:44:03 +01:00
currentView = view;
2020-08-02 17:44:03 +01:00
const eventDetail = getViewEventDetail(view, options, isRestore);
2020-08-02 17:44:03 +01:00
if (!isRestore) {
if (options.autoFocus !== false) {
focusManager.autoFocus(view);
}
2020-08-02 17:44:03 +01:00
} else if (!layoutManager.mobile) {
if (view.activeElement && document.body.contains(view.activeElement) && focusManager.isCurrentlyFocusable(view.activeElement)) {
focusManager.focus(view.activeElement);
} else {
focusManager.autoFocus(view);
}
2018-10-23 01:05:09 +03:00
}
2020-08-02 17:44:03 +01:00
view.dispatchEvent(new CustomEvent('viewshow', eventDetail));
2020-08-02 17:44:03 +01:00
if (dispatchPageEvents) {
view.dispatchEvent(new CustomEvent('pageshow', eventDetail));
}
}
2020-08-02 17:44:03 +01:00
function getProperties(view) {
const props = view.getAttribute('data-properties');
2020-08-02 17:44:03 +01:00
if (props) {
return props.split(',');
2018-10-23 01:05:09 +03:00
}
2020-08-02 17:44:03 +01:00
return [];
}
2020-08-02 17:44:03 +01:00
function dispatchViewEvent(view, eventInfo, eventName, isCancellable) {
if (!eventInfo) {
eventInfo = {
2018-10-23 01:05:09 +03:00
detail: {
type: view.getAttribute('data-type'),
2020-08-02 17:44:03 +01:00
properties: getProperties(view)
2018-10-23 01:05:09 +03:00
},
bubbles: true,
2020-08-02 17:44:03 +01:00
cancelable: isCancellable
};
2018-10-23 01:05:09 +03:00
}
2020-08-02 17:44:03 +01:00
eventInfo.cancelable = isCancellable || false;
const eventResult = view.dispatchEvent(new CustomEvent(eventName, eventInfo));
if (dispatchPageEvents) {
eventInfo.cancelable = false;
view.dispatchEvent(new CustomEvent(eventName.replace('view', 'page'), eventInfo));
2018-10-23 01:05:09 +03:00
}
2020-08-02 17:44:03 +01:00
return eventResult;
}
function getViewEventDetail(view, options, isRestore) {
const url = options.url;
const index = url.indexOf('?');
const params = index === -1 ? {} : queryString.parse(url.substring(index + 1));
return {
detail: {
type: view.getAttribute('data-type'),
properties: getProperties(view),
params: params,
isRestored: isRestore,
state: options.state,
// The route options
options: options.options || {}
},
bubbles: true,
cancelable: false
};
}
function resetCachedViews() {
// Reset all cached views whenever the skin changes
viewContainer.reset();
}
2020-08-02 17:44:03 +01:00
document.addEventListener('skinunload', resetCachedViews);
class ViewManager {
loadView(options) {
const lastView = currentView;
// Record the element that has focus
2018-10-23 01:05:09 +03:00
if (lastView) {
lastView.activeElement = document.activeElement;
2018-10-23 01:05:09 +03:00
}
if (options.cancel) {
return;
2018-10-23 01:05:09 +03:00
}
2019-04-02 00:01:33 +01:00
viewContainer.loadView(options).then(function (view) {
onViewChange(view, options);
});
2020-08-02 17:44:03 +01:00
}
2020-08-02 17:44:03 +01:00
tryRestoreView(options, onViewChanging) {
if (options.cancel) {
return Promise.reject({ cancelled: true });
}
// Record the element that has focus
if (currentView) {
currentView.activeElement = document.activeElement;
}
2019-04-02 00:01:33 +01:00
return viewContainer.tryRestoreView(options).then(function (view) {
onViewChanging();
onViewChange(view, options, true);
});
2020-08-02 17:44:03 +01:00
}
2020-08-02 17:44:03 +01:00
currentView() {
return currentView;
2020-08-02 17:44:03 +01:00
}
2020-08-02 17:44:03 +01:00
dispatchPageEvents(value) {
dispatchPageEvents = value;
2020-08-02 17:44:03 +01:00
}
}
2020-08-02 17:44:03 +01:00
export default new ViewManager();