11// Core ProcPages content manager
2-
2+ // Written by Kevin Edzenga; 2024-2025
3+ //
4+
5+ /**
6+ * @fileoverview Core ProcPages content manager that handles page layout and content organization
7+ * @module ProcPage
8+ */
9+
10+ /**
11+ * @typedef {Object } MediaData
12+ * @property {boolean } isLoaded - Internal flag indicating if media is loaded
13+ * @property {('image'|'manualLoad'|'video'|'audio'|'youtube') } type - Type of media
14+ * @property {string } sectionName - Name of the section containing this media
15+ * @property {string } src - Source URL for the media
16+ * @property {string } [thumb] - Thumbnail URL for manual loading
17+ * @property {number } [width] - Width for manual loading
18+ * @property {number } [height] - Height for manual loading
19+ * @property {string|string[] } [style] - CSS class(es) to apply
20+ * @property {HTMLElement } [object] - Internal reference to DOM element
21+ * @property {string[] } [caption] - Caption text to display under media
22+ * @property {string } [alt] - Alt text for accessibility
23+ */
24+
25+ /**
26+ * @typedef {Object } SectionData
27+ * @property {boolean } isLoaded - Whether the section has been loaded
28+ * @property {boolean } isActive - Whether the section is currently active
29+ * @property {string } name - Display name of the section
30+ * @property {string } navGroup - Navigation group this section belongs to
31+ * @property {string } content - HTML content for the section
32+ * @property {MediaData[] } media - Array of media items in this section
33+ * @property {Object[] } ytPlayers - YouTube player instances
34+ * @property {HTMLElement } header - Section header DOM element
35+ * @property {HTMLElement[] } objects - DOM elements for this section
36+ * @property {HTMLElement[] } mediaObjects - Media DOM elements for this section
37+ */
38+
39+ /**
40+ * Class representing a ProcPage that manages page content and layout
41+ */
342
443export class ProcPage {
44+ /**
45+ * Create a ProcPage
46+ * @param {Object } contentObject - Configuration object for the page
47+ * @param {Object } [contentObject.metaData] - Metadata for the page
48+ * @param {boolean } [contentObject.visible=true] - Whether the page is visible
49+ * @param {string } [contentObject.id] - Unique identifier for the page
50+ * @param {string } [contentObject.idPrefix="pxlPage_"] - Prefix for auto-generated IDs
51+ * @param {string } [contentObject.page="Default"] - Page name
52+ * @param {string } [contentObject.name=""] - Display name
53+ * @param {string } [contentObject.header=""] - Page header content
54+ * @param {string } [contentObject.subHeader=""] - Page subheader content
55+ * @param {string } [contentObject.footer=""] - Page footer content
56+ * @param {string } [contentObject.pageStyles=""] - Additional page styles
57+ * @param {Object } [contentObject.styleOverrides={}] - Style override definitions
58+ * @param {number } [contentObject.initialSection=0] - Initial active section index
59+ * @param {string[] } [contentObject.activeNavButton=[]] - Initially active navigation buttons
60+ * @param {('single'|'triple'|'vertical') } [contentObject.layout='triple'] - Page layout type
61+ * @param {Object } [contentObject.sections] - Section definitions
62+ */
563 constructor ( contentObject ) {
664 this . metaData = contentObject . metaData || { } ;
765 this . visible = contentObject . hasOwnProperty ( 'visible' ) ? contentObject . visible : true ;
@@ -80,22 +138,39 @@ export class ProcPage {
80138 }
81139
82140 // -- -- --
83-
141+ /**
142+ * Get a copy of the default section data
143+ * @returns {SectionData } Default section data object
144+ */
84145 getDefaultData ( ) {
85146 return Object . assign ( { } , this . defaultSectionData ) ;
86147 }
148+
149+ /**
150+ * Get a copy of the default media data
151+ * @returns {MediaData } Default media data object
152+ */
87153 getDefaultMedia ( ) {
88154 return Object . assign ( { } , this . defaultMediaData ) ;
89155 }
90156
91157 // -- -- --
92158
159+ /**
160+ * Set page metadata
161+ * @param {Object } metaData - Metadata object to set
162+ */
93163 setMetaData ( metaData ) {
94164 this . metaData = metaData ;
95165 }
96166
97167 // -- -- --
98168
169+ /**
170+ * Add a new section to the page
171+ * @param {string } sectionName - Unique identifier for the section
172+ * @param {Object } sectionContent - Section content and configuration
173+ */
99174 addSection ( sectionName , sectionContent ) {
100175 this . sectionTitles . push ( sectionName ) ;
101176 if ( ! this . sectionData . hasOwnProperty ( sectionName ) ) {
@@ -104,7 +179,11 @@ export class ProcPage {
104179 sectionContent . sectionName = sectionContent . name || sectionName ;
105180 this . sectionData [ sectionName ] = sectionContent ;
106181 }
107-
182+
183+ /**
184+ * Remove a section from the page
185+ * @param {string } sectionName - Name of section to remove
186+ */
108187 removeSection ( sectionName ) {
109188 if ( ! this . sectionTitles . includes ( sectionName ) ) return ;
110189
@@ -116,17 +195,32 @@ export class ProcPage {
116195// -- Page Section Helpers - -- --
117196// -- -- -- -- -- -- -- -- -- -- -- --
118197
198+ /**
199+ * Get section data by name
200+ * @param {string } sectionName - Name of section to retrieve
201+ * @returns {SectionData } Section data object
202+ */
119203 getSection ( sectionName ) {
120204 return this . sectionData [ sectionName ] ;
121205 }
122206
207+ /**
208+ * Set content for a page's titled section
209+ * @param {string } sectionName - Name of section to update
210+ * @param {string } sectionContent - HTML content for the section
211+ */
123212 setContent ( sectionName , sectionContent ) {
124213 if ( ! this . sectionTitles . includes ( sectionName ) ) {
125214 this . addSection ( sectionName , sectionContent ) ;
126215 }
127216 this . sectionData [ sectionName ] . content = sectionContent ;
128217 }
129218
219+ /**
220+ * Set display name for a page's section
221+ * @param {string } sectionName - Name of section to update
222+ * @param {string } sectionTitle - Display name to set
223+ */
130224 setSectionName ( sectionName , sectionTitle ) {
131225 if ( ! this . sectionTitles . includes ( sectionName ) ) {
132226 this . addSection ( sectionName , { } ) ;
@@ -138,7 +232,11 @@ export class ProcPage {
138232// -- Media Helpers -- -- --
139233// -- -- -- -- -- -- -- -- -- --
140234
141- // Apply style to media objects if specified
235+ /**
236+ * Apply style to media objects if specified
237+ * @param {MediaData } mediaData - Media data containing style information
238+ * @param {HTMLElement } obj - DOM element to apply styles to
239+ */
142240 applyStyle ( mediaData , obj ) {
143241 if ( mediaData . hasOwnProperty ( 'style' ) ) {
144242 if ( typeof mediaData . style == 'string' && mediaData . style != '' ) {
@@ -158,7 +256,11 @@ export class ProcPage {
158256 }
159257
160258 // -- -- --
161-
259+ /**
260+ * Creates an image element from media data
261+ * @param {MediaData } mediaData - Media data containing image properties
262+ * @returns {HTMLImageElement } Created image element
263+ */
162264 buildImage ( mediaData ) {
163265 let img = document . createElement ( 'img' ) ;
164266 img . src = mediaData . src ;
@@ -174,6 +276,11 @@ export class ProcPage {
174276 return img ;
175277 }
176278
279+ /**
280+ * Creates a lazy-loading image container with placeholder
281+ * @param {MediaData|string } mediaData - Media data or image URL
282+ * @returns {HTMLDivElement } Container with placeholder and lazy-loaded image
283+ */
177284 buildManualLoad ( mediaData ) {
178285 if ( typeof mediaData == 'string' ) {
179286 let imgPath = mediaData ;
@@ -249,6 +356,12 @@ export class ProcPage {
249356 // -- -- --
250357
251358
359+ /**
360+ * Adds a video to a page section
361+ * @param {string } sectionName - Name of section to add video to
362+ * @param {MediaData|string } videoData - Video data or URL
363+ * @param {string } [altText=''] - Alternative text for accessibility
364+ */
252365 addVideo ( sectionName , videoData , altText = '' ) {
253366 if ( ! this . sectionTitles . includes ( sectionName ) ) {
254367 this . addSection ( sectionName , { } ) ;
@@ -271,6 +384,11 @@ export class ProcPage {
271384 this . sectionData [ sectionName ] . media . push ( videoData ) ;
272385 }
273386
387+ /**
388+ * Creates a video element from media data
389+ * @param {MediaData } mediaData - Media data containing video properties
390+ * @returns {HTMLVideoElement } Created video element
391+ */
274392 buildVideoEmbed ( mediaData ) {
275393 let vidSrc = mediaData . src ;
276394 let vidAlt = mediaData . alt ;
@@ -290,6 +408,15 @@ export class ProcPage {
290408
291409 // -- -- --
292410
411+ /**
412+ * Creates a YouTube embed from media data
413+ *
414+ * Check's if the Youtube API is loaded, if not, it falls back to a simple iframe embed.
415+ * <br>Without the Youtube API, iframe embeds reset their `.src` to stop the video when the page is changed.
416+ * @param {HTMLElement } parentObj - Parent element to attach player to
417+ * @param {MediaData } mediaData - Media data containing YouTube video ID
418+ * @returns {HTMLIFrameElement|HTMLDivElement } YouTube player element
419+ */
293420 buildYoutubeEmbed ( parentObj , mediaData ) {
294421 //let embedParent = document.createElement('div');
295422 //this.applyStyle( mediaData, embedParent );
@@ -354,6 +481,12 @@ export class ProcPage {
354481
355482 // -- -- --
356483
484+ /**
485+ * Creates appropriate media element based on media type
486+ * @param {HTMLElement } parentObj - Parent element to attach media to
487+ * @param {MediaData } mediaData - Media data for creating element
488+ * @returns {HTMLElement } Created media element
489+ */
357490 buildMedia ( parentObj , mediaData ) {
358491 let media = null ;
359492 switch ( mediaData . type ) {
@@ -396,7 +529,10 @@ export class ProcPage {
396529// -- Page Building -- -- --
397530// -- -- -- -- -- -- -- -- -- --
398531
399-
532+ /**
533+ * Creates the page layout structure
534+ * @returns {HTMLDivElement } Root page content element
535+ */
400536 buildPage ( ) {
401537
402538 let pageContent = document . createElement ( 'div' ) ;
@@ -572,6 +708,10 @@ export class ProcPage {
572708
573709 // -- -- --
574710
711+ /**
712+ * Creates the section navigation buttons
713+ * @param {HTMLElement } sectionNav - Container element for section navigation
714+ */
575715 buildSectionNav ( sectionNav ) {
576716
577717 let sectionTitles = [ ] ;
@@ -635,6 +775,10 @@ export class ProcPage {
635775
636776 // -- -- --
637777
778+ /**
779+ * Builds a section's content and media elements
780+ * @param {string } sectionName - Name of section to build
781+ */
638782 buildSection ( sectionName ) {
639783 if ( ! this . sectionData . hasOwnProperty ( sectionName ) ) {
640784 console . error ( "Section '" + sectionName + "' does not exist." ) ;
@@ -693,6 +837,10 @@ export class ProcPage {
693837
694838 }
695839
840+ /**
841+ * Activates a section and displays its content
842+ * @param {string|number } sectionName - Section name or index to activate
843+ */
696844 activateSection ( sectionName ) {
697845
698846 if ( Number . isInteger ( sectionName ) ) {
@@ -749,7 +897,10 @@ export class ProcPage {
749897 }
750898
751899
752-
900+ /**
901+ * Deactivates a section and hides its content
902+ * @param {string } sectionName - Name of section to deactivate
903+ */
753904 deactivateSection ( sectionName ) {
754905 this . sectionData [ sectionName ] . isActive = false ;
755906 this . sectionData [ sectionName ] . header . classList . remove ( 'procPagesNavActive' ) ;
@@ -791,6 +942,10 @@ export class ProcPage {
791942
792943 // -- -- --
793944
945+ /**
946+ * Stops all media playback in a section
947+ * @param {string } [sectionName=null] - Name of section to stop media in
948+ */
794949 stopSectionMedia ( sectionName = null ) {
795950 if ( sectionName == null ) {
796951 sectionName = this . prevSection ;
@@ -819,14 +974,22 @@ export class ProcPage {
819974
820975 // -- -- --
821976
822- // TODO - Implement Vertical Page Layout
977+ /**
978+ * Builds page layout for vertical mode
979+ * TODO - Implement Vertical Page Layout
980+ */
823981 buildVerticalPage ( ) {
824982 this . buildHorizontalPage ( ) ;
825983 }
826984
827985
828986 // -- -- --
829987
988+ /**
989+ * Builds content for single layout mode
990+ * @param {SectionData } sectionData - Section data to build
991+ * @param {HTMLElement } sectionContentParent - Parent element for section content
992+ */
830993 buildSinglePageSection ( sectionData , sectionContentParent ) {
831994 if ( sectionData . content != '' ) {
832995 let sectionContentDiv = document . createElement ( 'div' ) ;
@@ -838,6 +1001,13 @@ export class ProcPage {
8381001 }
8391002 }
8401003
1004+ /**
1005+ * Builds content for triple layout mode
1006+ * @param {SectionData } sectionData - Section data to build
1007+ * @param {HTMLElement } sectionContentParent - Parent element for section content
1008+ * @param {HTMLElement } sectionMediaParent - Parent element for section media
1009+ * @returns {{content: HTMLElement[], media: HTMLElement[]} } Created content and media elements
1010+ */
8411011 buildTriplePageSection ( sectionData , sectionContentParent , sectionMediaParent ) {
8421012 let ret = {
8431013 'content' : [ ] ,
@@ -900,12 +1070,22 @@ export class ProcPage {
9001070 // -- -- --
9011071
9021072
1073+ /**
1074+ * Applies page styles to an element
1075+ * @param {string } styleType - Style type to apply
1076+ * @param {HTMLElement } obj - Element to apply styles to
1077+ */
9031078 applyPageStyle ( styleType , obj ) {
9041079 if ( this . pageStyles . hasOwnProperty ( styleType ) && Array . isArray ( this . pageStyles [ styleType ] ) ) {
9051080 this . pageStyles [ styleType ] . forEach ( ( style ) => { style != '' && obj . classList . add ( style ) } ) ;
9061081 }
9071082 }
9081083
1084+ /**
1085+ * Checks if page has a specific style type
1086+ * @param {string } styleType - Style type to check for
1087+ * @returns {boolean } True if style type exists
1088+ */
9091089 hasPageStyle ( styleType ) {
9101090 return this . pageStyles . hasOwnProperty ( styleType ) ;
9111091 }
0 commit comments