@@ -19,37 +19,11 @@ class ViewportController extends Controller {
1919 className : 'Colors.view.ViewportController'
2020 }
2121
22- /**
23- * @summary Tracks the names of widgets currently open in separate windows.
24- * @member {String[]} connectedApps=[]
25- */
26- connectedApps = [ ]
2722 /**
2823 * @summary The ID for the `setInterval` used for real-time data updates.
2924 * @member {Number|null} intervalId
3025 */
3126 intervalId = null
32- /**
33- * @member {Boolean} #isReintegrating=false
34- * @private
35- */
36- #isReintegrating = false
37- /**
38- * @summary A private flag to track if a drag operation is in the process of moving a widget to a new window.
39- * @member {Boolean} #isWindowDragging=false
40- * @private
41- */
42- #isWindowDragging = false
43- /**
44- * @summary A map to get the original index of a widget in the dashboard's items array.
45- * @description This is used to correctly re-insert a widget when its popup window is closed.
46- * @member {Object} widgetIndexMap
47- */
48- widgetIndexMap = {
49- 'bar-chart' : 2 ,
50- 'pie-chart' : 1 ,
51- grid : 0
52- }
5327
5428 /**
5529 * @summary Factory method to open a widget in a new browser window or popup.
@@ -59,10 +33,11 @@ class ViewportController extends Controller {
5933 */
6034 async createBrowserWindow ( name ) {
6135 if ( this . getStateProvider ( ) . getData ( 'openWidgetsAsPopups' ) ) {
62- let widget = this . getReference ( name ) ,
63- rect = await this . component . getDomRect ( widget . vdom . id ) ; // using the vdom id to always get the top-level node
36+ let dashboard = this . getReference ( 'dashboard' ) ,
37+ widget = this . getReference ( name ) ,
38+ rect = await this . component . getDomRect ( widget . vdom . id ) ; // using the vdom id to always get the top-level node
6439
65- await this . # openWidgetInPopup( name , rect )
40+ await dashboard . openWidgetInPopup ( widget , rect )
6641 } else {
6742 let { config, windowConfigs} = Neo ,
6843 { environment} = config ,
@@ -89,75 +64,6 @@ class ViewportController extends Controller {
8964 super . destroy ( ...args )
9065 }
9166
92- /**
93- * @summary Handles the `connect` event fired by `Neo.currentWorker`.
94- * @description This is triggered when a new child application (a detached widget window) connects to the shared worker.
95- * It re-parents the widget component from the main app's component tree into the new child app's viewport.
96- * @param {Object } data The event data from the worker.
97- * @param {String } data.appName The name of the connecting application.
98- * @param {Number } data.windowId The ID of the new window.
99- */
100- async onAppConnect ( data ) {
101- if ( data . appName === 'ColorsWidget' ) {
102- let me = this ,
103- app = Neo . apps [ data . windowId ] ,
104- mainView = app . mainView ,
105- { windowId} = data ,
106- url = await Neo . Main . getByPath ( { path : 'document.URL' , windowId} ) ,
107- widgetName = new URL ( url ) . searchParams . get ( 'name' ) ,
108- widget = me . getReference ( widgetName ) ,
109- parent = widget . up ( 'panel' ) ;
110-
111- if ( ! me . #isWindowDragging) {
112- parent . hide ( )
113- }
114-
115- me . connectedApps . push ( widgetName ) ;
116-
117- me . getReference ( `detach-${ widgetName } -button` ) . disabled = true ;
118-
119- mainView . add ( widget , false , ! me . #isWindowDragging)
120- }
121- }
122-
123- /**
124- * @summary Handles the `disconnect` event fired by `Neo.currentWorker`.
125- * @description This is triggered when a child application window is closed. It moves the widget component
126- * back into its original position in the main application's dashboard.
127- * @param {Object } data The event data from the worker.
128- * @param {String } data.appName The name of the disconnecting application.
129- * @param {Number } data.windowId The ID of the closed window.
130- */
131- async onAppDisconnect ( data ) {
132- let me = this ;
133-
134- if ( me . #isWindowDragging || me . #isReintegrating) {
135- me . #isWindowDragging = false ;
136- return
137- }
138-
139- let { appName, windowId} = data ,
140- dashboard = me . getReference ( 'dashboard' ) ,
141- url = await Neo . Main . getByPath ( { path : 'document.URL' , windowId} ) ,
142- widgetName = new URL ( url ) . searchParams . get ( 'name' ) ,
143- widget = me . getReference ( widgetName ) ;
144-
145- // Closing a non-main app needs to move the widget back into its original position & re-enable the show button
146- if ( appName === 'ColorsWidget' ) {
147- let itemPanel = dashboard . items [ me . widgetIndexMap [ widgetName ] ] ,
148- bodyContainer = itemPanel . getReference ( 'bodyContainer' ) ;
149-
150- bodyContainer . add ( widget ) ;
151- itemPanel . show ( ) ;
152-
153- me . getReference ( `detach-${ widgetName } -button` ) . disabled = false
154- }
155- // Close popup windows when closing or reloading the main window
156- else if ( appName === 'Colors' ) {
157- Neo . Main . windowClose ( { names : me . connectedApps , windowId} )
158- }
159- }
160-
16167 /**
16268 * @summary Handles the change event from the 'Amount of Colors' slider.
16369 * @param {Object } data The event data.
@@ -190,22 +96,6 @@ class ViewportController extends Controller {
19096 this . setState ( 'openWidgetsAsPopups' , data . value )
19197 }
19298
193- /**
194- * @summary Lifecycle method, called after the controller's constructor.
195- * @description Sets up listeners for the shared worker's connect and disconnect events.
196- */
197- onConstructed ( ) {
198- super . onConstructed ( ) ;
199-
200- let me = this ;
201-
202- Neo . currentWorker . on ( {
203- connect : me . onAppConnect ,
204- disconnect : me . onAppDisconnect ,
205- scope : me
206- } )
207- }
208-
20999 /**
210100 * @summary Lifecycle method, called after the controller's component is constructed.
211101 * @description Triggers the initial data load for the widgets.
@@ -239,60 +129,6 @@ class ViewportController extends Controller {
239129 await this . createBrowserWindow ( 'pie-chart' )
240130 }
241131
242- /**
243- * @summary Handles the `dragBoundaryEntry` event from the `SortZone`.
244- * @description This is the core of the drag-to-re-dock feature. When a dragged window re-enters the main
245- * application's boundary, this method closes the popup window and re-inserts the widget component
246- * back into its original dashboard container, providing a seamless user experience.
247- * @param {Object } data The event data from the SortZone.
248- */
249- async onDragBoundaryEntry ( data ) {
250- let me = this ,
251- { windowId} = me ,
252- { sortZone} = data ,
253- widgetName = data . draggedItem . reference . replace ( '-panel' , '' ) ,
254- widget = me . getReference ( widgetName ) ;
255-
256- me . #isReintegrating = true ;
257-
258- sortZone . dragProxy . add ( widget , true ) ;
259-
260- await Neo . Main . windowClose ( { names : widgetName , windowId} ) ;
261-
262- me . #isReintegrating = false ;
263- me . #isWindowDragging = false ;
264-
265- sortZone . isWindowDragging = false ;
266- sortZone . dragProxy . style = { opacity : 1 } ;
267-
268- Neo . main . addon . DragDrop . setConfigs ( { isWindowDragging : false , windowId} )
269- }
270-
271- /**
272- * @summary Handles the `dragBoundaryExit` event from the `SortZone`.
273- * @description This is the core of the drag-to-popup feature. When a dragged component's proxy leaves
274- * the boundary of its container, this method orchestrates the creation of a new popup window
275- * and hands off the drag operation to the main thread's DragDrop addon to drag the OS-level window.
276- * @param {Object } data The event data from the SortZone.
277- */
278- async onDragBoundaryExit ( data ) {
279- let { draggedItem, proxyRect, sortZone} = data ,
280- widgetName = draggedItem . reference . replace ( '-panel' , '' ) ,
281- popupData ;
282-
283- this . #isWindowDragging = true ;
284-
285- // Prohibit the size reduction inside #openWidgetInPopup().
286- proxyRect . height += 50 ;
287-
288- popupData = await this . #openWidgetInPopup( widgetName , proxyRect ) ;
289-
290- sortZone . startWindowDrag ( {
291- dragData : data ,
292- ...popupData
293- } ) ;
294- }
295-
296132 /**
297133 * @summary Handles the click event to request Window Management permissions.
298134 * @description The Window Management API is a new browser feature that allows web apps to control
@@ -346,46 +182,6 @@ class ViewportController extends Controller {
346182 }
347183 }
348184
349- /**
350- * @summary Private helper method to open a widget in a new popup window.
351- * @description This method calculates the precise screen coordinates for the new window based on the main
352- * window's position and the drag proxy's last known rectangle. It then calls the main thread
353- * to open the new window with the correct URL and features.
354- * @param {String } name The reference name of the widget.
355- * @param {Object } rect The DOM rect of the drag proxy.
356- * @returns {Promise<Object> } A promise that resolves with the new window's properties.
357- * @private
358- */
359- async #openWidgetInPopup( name , rect ) {
360- let me = this ,
361- { windowId} = me ,
362- { config, windowConfigs} = Neo ,
363- { environment} = config ,
364- firstWindowId = Object . keys ( windowConfigs ) [ 0 ] ,
365- { basePath} = windowConfigs [ firstWindowId ] ,
366- url ;
367-
368- if ( environment !== 'development' ) {
369- basePath = `${ basePath + environment } /`
370- }
371-
372- url = `${ basePath } apps/colors/childapps/widget/index.html?name=${ name } ` ;
373-
374- let winData = await Neo . Main . getWindowData ( { windowId} ) ,
375- { height, width, x, y} = rect ,
376- popupHeight = height - 50 , // popup header in Chrome
377- popupLeft = x + winData . screenLeft ,
378- popupTop = y + ( winData . outerHeight - winData . innerHeight + winData . screenTop ) ;
379-
380- await Neo . Main . windowOpen ( {
381- url,
382- windowFeatures : `height=${ popupHeight } ,left=${ popupLeft } ,top=${ popupTop } ,width=${ width } ` ,
383- windowName : name
384- } ) ;
385-
386- return { popupHeight, popupLeft, popupTop, popupWidth : width , windowName : name }
387- }
388-
389185 /**
390186 * @summary Updates the chart components with new data.
391187 * @param {Object } data The data for the charts.
0 commit comments