EmbyCrackedClient/web/modules/viewmanager/viewmanager.js
2025-06-25 11:46:04 +08:00

1 line
No EOL
12 KiB
JavaScript

import layoutManager from"./../layoutmanager.js";import focusManager from"./../focusmanager.js";import pluginManager from"./../common/pluginmanager.js";import userSettings from"./../common/usersettings/usersettings.js";import events from"./../emby-apiclient/events.js";import appSettings from"./../common/appsettings.js";let mainAnimatedPages,pageContainerCount=3,ViewClasses=[],CurrentViewStack=[];function extractPath(urlOrPath){try{var pathname=new URL(urlOrPath).pathname;if(pathname)return pathname}catch(e){}return urlOrPath}function removeItemOnce(arr,value){value=arr.indexOf(value);return-1<value&&arr.splice(value,1),arr}function removeViewInfoFromCurrentViews(viewInfo){removeItemOnce(CurrentViewStack,viewInfo)}function findOldestViewToRemove(ignoreViewInfo){var candidates=[],views=CurrentViewStack;for(let i=0,length=views.length;i<length;i++){var viewInfo=views[i];"true"!==viewInfo.params.asDialog&&candidates.push(viewInfo)}if(candidates.length>=pageContainerCount)for(let i=0,length=candidates.length;i<length;i++){let viewInfo=candidates[i];if(viewInfo!==ignoreViewInfo)return viewInfo}return null}function disableRestoreOnCurrentViews(){var views=CurrentViewStack;for(let i=0,length=views.length;i<length;i++){var viewInfo=views[i];"true"!==viewInfo.params.asDialog&&(viewInfo=viewInfo.view)&&(viewInfo.allowRestore=!1)}}function getViewInfoByUrl(url){var views=CurrentViewStack;for(let i=0,length=views.length;i<length;i++){var viewInfo=views[i];if(viewInfo.url===url)return viewInfo}return null}function setControllerClass(view,options){if(options.controllerFactory)return Promise.resolve();let controllerUrl=view.getAttribute("data-controller");return controllerUrl?(controllerUrl.startsWith("__plugin/")&&(controllerUrl=controllerUrl.substring("__plugin/".length)),controllerUrl=pluginManager.getConfigurationResourceUrl(controllerUrl),require([controllerUrl]).then(function(deps){options.controllerFactory=deps[0]})):Promise.resolve()}function ensureWindowScrollOption(detail,view){let windowScroll=detail.windowScroll;return 3!==windowScroll||(windowScroll=detail.windowScroll=!view.classList.contains("scrollFrameY")&&!view.querySelector('.emby-scroller[data-bindheader="true"],.scrollFrameY[data-bindheader="true"]'))||(detail.adjustHeaderForEmbeddedScroll=!0),!0===windowScroll}function parseHtml(html,hasScript){hasScript&&(html=(html=html.replaceAll("\x3c!--<script","<script")).replaceAll("<\/script>--\x3e","<\/script>"));hasScript=document.createElement("div");return hasScript.innerHTML=html,hasScript.querySelector('.view,div[data-role="page"]')}function normalizeNewView(options,isPluginpage){let viewHtml=options.view;options.params?.asDialog&&(viewHtml=viewHtml.replace('data-bindheader="true"','data-bindheader="false"'));isPluginpage=!!isPluginpage&&viewHtml.includes("<script"),isPluginpage=parseHtml(viewHtml,isPluginpage);options.view=isPluginpage}function getViewHideEventInfo(previousViewInfo,newViewInfo){previousViewInfo=Object.assign({},previousViewInfo);return previousViewInfo.newViewInfo=newViewInfo,{detail:previousViewInfo,bubbles:!0,cancelable:!1}}function onBeforeChange(previousViewInfo,newViewInfo,isRestored,isBack){previousViewInfo&&dispatchViewEvent(previousViewInfo.view,getViewHideEventInfo(previousViewInfo,newViewInfo),"viewbeforehide");var newView=newViewInfo.view,isRestored=getViewEventDetail(newViewInfo,isRestored,isBack,previousViewInfo);let navMenuId=isRestored.detail.navMenuId;return navMenuId||"search"===isRestored.detail.params?.type&&(navMenuId="search"),navMenuId=navMenuId||(navMenuId=window.location.href.toString()).substring(navMenuId.indexOf("#!")+2),isRestored.detail.navMenuId=navMenuId,newViewInfo.controllerFactory&&!newView.controller&&(newView.controller=new newViewInfo.controllerFactory(newView,isRestored.detail.params)),newViewInfo.controller&&newView.controller&&(isBack=extractPath(newViewInfo.controller),newView.controller.name=isBack.replaceAll(".js","").replaceAll(".","").replaceAll("/","-"),newView.classList.add("view-"+newView.controller.name)),dispatchViewEvent(newView,isRestored,"viewbeforeshow"),newView.controller}function onViewChange(previousViewInfo,newViewInfo,isRestore,isBack){previousViewInfo&&dispatchViewEvent(previousViewInfo.view,getViewHideEventInfo(previousViewInfo,newViewInfo),"viewhide"),isRestore&&removeViewInfoFromCurrentViews(newViewInfo),CurrentViewStack.push(newViewInfo);let newView=newViewInfo.view;var controller;return"true"===previousViewInfo?.params.asDialog?(onNewViewDisplayed(newViewInfo,isRestore,isBack,previousViewInfo),Promise.resolve(newView)):(((controller=newView.controller)?controller.transitionPromise:null)||Promise.resolve()).then(function(){return onNewViewDisplayed(newViewInfo,isRestore,isBack,previousViewInfo),newView})}function autoFocusView(view,options){var controller=view.controller;return controller&&controller.autoFocus?controller.autoFocus(options):focusManager.autoFocus(view,options)}function onNewViewDisplayed(viewInfo,isRestore,isBack,previousViewInfo){removeSplash();var newView=viewInfo.view,isBack=getViewEventDetail(viewInfo,isRestore,isBack,previousViewInfo);"true"===previousViewInfo?.params.asDialog&&removeAndDestroy(previousViewInfo),isRestore?(previousViewInfo=viewInfo.activeElement)&&document.body.contains(previousViewInfo)&&focusManager.isCurrentlyFocusable(previousViewInfo)?focusManager.focus(previousViewInfo):autoFocusView(newView,{skipIfNotEnabled:!0}):!1!==viewInfo.autoFocus&&autoFocusView(newView,{skipIfNotEnabled:!0}),newView.dispatchEvent(new CustomEvent("viewshow",isBack)),newView.dispatchEvent(new CustomEvent("pageshow",isBack))}function dispatchViewEvent(view,eventInfo,eventName){var eventResult=view.dispatchEvent(new CustomEvent(eventName,eventInfo));return view.dispatchEvent(new CustomEvent(eventName.replace("view","page"),eventInfo)),eventResult}function getViewEventDetail(viewInfo,isRestore,isBack,previousViewInfo){var view=viewInfo.view;return viewInfo.isRestored=isRestore,viewInfo.isBack=isBack,viewInfo.previousViewInfo=previousViewInfo,null==viewInfo.title&&(viewInfo.title=view.getAttribute("data-title")||null),viewInfo.helpUrl||(viewInfo.helpUrl=view.getAttribute("data-helpurl")||null),ensureWindowScrollOption(viewInfo,view),{detail:viewInfo,bubbles:!0,cancelable:!1}}function triggerDestroy(viewInfo){viewInfo.activeElement=null;var viewInfo=viewInfo.view,controller=viewInfo.controller;controller?.destroy&&controller.destroy(),viewInfo.controller=null}function removeAndDestroy(viewInfoToRemove,newViewToReplaceWith){removeViewInfoFromCurrentViews(viewInfoToRemove);var viewToRemove=viewInfoToRemove.view;triggerDestroy(viewInfoToRemove),"true"!==viewInfoToRemove.params.asDialog&&(newViewToReplaceWith?mainAnimatedPages.replaceChild(newViewToReplaceWith,viewToRemove):viewToRemove.remove())}function ViewManager(){}function animateRemoveSplash(elem){elem.remove()}events.on(layoutManager,"modechange",disableRestoreOnCurrentViews),events.on(userSettings,"change",function(e,name){switch(name){case"language":case"datetimelocale":case"tvhome":disableRestoreOnCurrentViews()}}),events.on(appSettings,"change",function(e,name){"name"===name&&disableRestoreOnCurrentViews()});let splashRemoved;function removeSplash(){var splash;!splashRemoved&&(splashRemoved=!0,splash=document.querySelector(".app-splash-container")||document.querySelector(".app-splash"))&&animateRemoveSplash(splash)}function removeItemAll(arr,value){let i=0;for(;i<arr.length;)arr[i]===value?arr.splice(i,1):++i;return arr}ViewManager.prototype.loadView=function(options,signal){let previousViewInfo=this.currentViewInfo();previousViewInfo&&(previousViewInfo.activeElement=document.activeElement);var isPluginpage=options.isPluginPage;normalizeNewView(options,isPluginpage);let view=options.view,dependencies=view.getAttribute("data-require");var dependencyPromises=[];return(dependencies=dependencies?dependencies.split(","):[]).length&&dependencyPromises.push(require(dependencies)),isPluginpage&&(dependencyPromises.push(Emby.importModule("./legacy/dashboard.js")),dependencyPromises.push(require(["css!legacy/dashboard.css"]))),Promise.all(dependencyPromises).then(function(){var viewClassList=view.classList;return viewClassList.add("page"),viewClassList.add.apply(viewClassList,ViewClasses),ensureWindowScrollOption(options,view)&&viewClassList.add("page-windowScroll"),mainAnimatedPages=mainAnimatedPages||document.querySelector(".mainAnimatedPages"),options.params?.asDialog||((viewClassList=findOldestViewToRemove(previousViewInfo))?removeAndDestroy(viewClassList,view):mainAnimatedPages.appendChild(view)),setControllerClass(view,options).then(function(){let viewInfo=options;var controller=onBeforeChange(previousViewInfo,viewInfo,!1,options.isBack);if(previousViewInfo&&(controller&&controller.onBeginResume||options.params?.asDialog||previousViewInfo.view.classList.add("hide"),previousViewInfo.params.asDialog)&&!options.params?.asDialog){var views=CurrentViewStack;for(let i=0,length=views.length;i<length;i++){let viewInfo=views[i];viewInfo.params?.asDialog||viewInfo.view.classList.add("hide")}}return options.view=view,onViewChange(previousViewInfo,viewInfo,!1,options.isBack)})})},ViewManager.prototype.tryRestoreView=function(options,signal){var previousViewInfo=this.currentViewInfo(),url=(previousViewInfo&&(previousViewInfo.activeElement=document.activeElement),options.url),options=options.isBack,url=getViewInfoByUrl(url);if(url){var controller,view=url?.view;if(view&&!1!==view.allowRestore)return(controller=onBeforeChange(previousViewInfo,url,!0,options))&&controller.onBeginResume||previousViewInfo&&(view.classList.remove("hide"),url.params?.asDialog||previousViewInfo.view.classList.add("hide")),onViewChange(previousViewInfo,url,!0,options)}return Promise.reject()},ViewManager.prototype.canRestoreCurrentView=function(){return!1!==this.currentView()?.allowRestore},ViewManager.prototype.replaceCurrentUrl=function(url){var viewInfo=this.currentViewInfo();viewInfo&&(viewInfo.url=url)},ViewManager.prototype.onViewChange=onViewChange,ViewManager.prototype.currentView=function(){return this.currentViewInfo()?.view},ViewManager.prototype.currentViewController=function(){return this.currentView()?.controller},ViewManager.prototype.currentViewInfo=function(){var views=CurrentViewStack,length=views.length;return length?views[length-1]:null},ViewManager.prototype.addViewClass=function(classes){var args=arguments;for(let i=0,length=args.length;i<length;i++){var cls=args[i];ViewClasses.includes(cls)||ViewClasses.push(cls)}var views=CurrentViewStack;for(let i=0,length=views.length;i<length;i++){var viewInfo=views[i],view=viewInfo.view;"true"!==viewInfo.params.asDialog&&view&&(viewInfo=view.classList).add.apply(viewInfo,arguments)}},ViewManager.prototype.removeViewClass=function(classes){var args=arguments;for(let i=0,length=args.length;i<length;i++){var cls=args[i];removeItemAll(ViewClasses,cls)}var views=CurrentViewStack;for(let i=0,length=views.length;i<length;i++){var viewInfo=views[i];"true"!==viewInfo.params.asDialog&&(viewInfo=viewInfo.view)&&(viewInfo=viewInfo.classList).remove.apply(viewInfo,arguments)}},ViewManager.prototype.disableRestoreOnCurrentViews=disableRestoreOnCurrentViews,ViewManager.prototype.autoFocusCurrentView=function(options){var view=this.currentView();return view?autoFocusView(view,options):null},ViewManager.prototype.dispatchViewBeforeShow=function(viewInfo,isRestore,isBack,previousViewInfo){isRestore=getViewEventDetail(viewInfo,isRestore,isBack,previousViewInfo);dispatchViewEvent(viewInfo.view,isRestore,"viewbeforeshow")},ViewManager.prototype.dispatchViewBeforeHide=function(viewInfo,newViewInfo){dispatchViewEvent(viewInfo.view,getViewHideEventInfo(viewInfo,newViewInfo),"viewbeforehide")};export default new ViewManager;