PageSourceSearch

https://physicsmonster.org/javascript/setup_basic_monster.js

js physicsmonster.org collected 2026-10-02 01:07:08 UTC 14,627 bytes, 421 lines download raw bytes

1/* 
2
3Set up up footer, floating back-to-top button, border before each section.
4Set up the base for the navigation bar.
5*/
6
7//namespace of each topic should be added to this array by array_namespace_topic.push(array_topic).
8//Each member namespace should have a method called update(), which will be called by did_finish_loading() in load_content.js. And is also called by the compute_and_substitue_random_value() in setup_exercise_all.js.
9var array_namespace_topic = []; 
10
11// Any Class_Game that cannot be loaded due to canvas not yet available is added to this array.
12var array_game_simulation = []; 
13
14
15function setup_page_monster(){
16    /*
17    Called by load_content() -> did_finish_loading() in load_content.js
18    */
19    make_footer();
20    make_button_float_back_to_top();
21    make_border_before_section();
22    make_section_collapsible();
23    make_try_collapsible();
24    make_simulation_canvas_collapsible();
25    make_video_youtube_collapsible();
26
27    make_navigation_bar_base();
28
29    make_button_accessibility();
30
31}
32
33
34function make_border_before_section(){
35    function make_element_border(){
36        let element_border = document.createElement("div");
37        element_border.classList.add("container");
38
39        // Add another div inside with margin so the size of the border could be controled relative to the container class.
40        let element_border_inside = document.createElement("div");
41        element_border_inside.classList.add("class_border_custom");
42        element_border.appendChild(element_border_inside);
43
44        return element_border;
45    }
46
47    var element_body = document.querySelector("body");
48    var array_element_section = document.querySelectorAll(".class_section");
49    array_element_section.forEach((element_section, index) => {
50        if (index !== 0){
51            let element_border = make_element_border();
52
53            if (element_section.classList.contains("class_level_01")){
54                element_border.classList.add("class_level_01");                
55            }
56
57            if (element_section.classList.contains("class_level_02")){
58                element_border.classList.add("class_level_02");                
59            }
60
61            element_body.insertBefore(element_border, element_section);
62        }
63    });
64
65}
66
67function make_footer(){
68    /*
69    <footer class="container-fluid text-center">
70        <a href="#id_body" title="To Top">
71            <i class="material-icons">keyboard_arrow_up</i>
72        </a>
73    
74        <p>
75            <script>
76                document.write("&copy;  " + new Date().getFullYear() + " H K Wilfred Lee. All rights reserved.");
77            </script>
78        </p>
79        <br>
80    </footer>
81    */
82
83    let element_footer = document.createElement("footer");
84    element_footer.classList.add("text-center");
85    element_footer.classList.add("container-fluid");
86
87    element_footer.innerHTML = `
88        <a href="#id_body">
89            <i class="material-icons">keyboard_arrow_up</i>
90        </a>
91    
92        <p>
93            &copy; ${new Date().getFullYear()} H K Wilfred Lee. All rights reserved.
94        </p>
95        <br>
96    `;
97
98    let element_body = document.querySelector("body");
99    element_body.appendChild(element_footer);
100
101}
102
103function make_button_float_back_to_top(){
104    /* 
105    <a href="#id_body" class="fixed-bottom px-2" style="width: 40px;">
106        <span class="material-icons">keyboard_arrow_up</span>
107    </a> 
108     */
109 
110    var element_float_a = document.createElement("a");
111
112    element_float_a.setAttribute("href", "#id_body");
113
114    element_float_a.classList.add("fixed-bottom");
115    element_float_a.classList.add("px-2");
116
117    element_float_a.style.width = "40px";
118
119    element_float_a.innerHTML = `<span class="material-icons">keyboard_arrow_up</span>`;
120
121    var element_body = document.querySelector("body");
122    element_body.appendChild(element_float_a);
123
124}
125
126function make_button_accessibility(){
127    // <button type="button" class="btn btn-light" style="float: right;" onclick="toggle_accessibility()"><span class="material-icons">accessibility_new</span></button>
128
129    var element_button_accessibility = document.createElement("button");
130
131    element_button_accessibility.classList.add("btn");
132    element_button_accessibility.classList.add("btn-light");
133    element_button_accessibility.classList.add("m-1");
134
135
136    element_button_accessibility.style.float = "right";
137
138    element_button_accessibility.innerHTML = `<span class="material-icons">accessibility_new</span>`;
139
140
141    element_button_accessibility.setAttribute("type", "button");
142    element_button_accessibility.setAttribute("onclick", "toggle_accessibility()");
143
144    // var element_body = document.querySelector("body");
145    // element_body.appendChild(element_button_accessibility);
146
147    let element_jumbotron = document.querySelector(".jumbotron");
148    element_jumbotron.appendChild(element_button_accessibility);
149
150}
151
152
153
154function make_navigation_bar_base(){
155    /*
156    Make the base of the collapsible navigation bar with brand logo.
157    This function must be called before any modification to the navigation bar. 
158    */
159
160    let element_nav = document.createElement("nav");
161    element_nav.classList.add("navbar");
162    element_nav.classList.add("navbar-expand-md");
163    element_nav.classList.add("navbar-dark");
164
165    element_nav.innerHTML = `
166    <!-- Brand/logo -->
167    <a class="navbar-brand" href="http://physicsmonster.org/">
168        <i class="material-icons">home</i>
169    </a>
170    
171    <!-- Hamburger collapse icon -->
172    <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#collapsible_navbar">
173        <span class="navbar-toggler-icon"></span>
174    </button>
175    
176    
177    
178    <!-- justify-content-center used to center the navbar, this class is always added in the tag enclosing the ul list.  -->
179    <!-- Use justify-content-start or justify-content-end to align left or right. -->
180    <!-- https://www.w3schools.com/bootstrap4/bootstrap_flex.asp -->
181    <!-- For example, if the navbar is not collapsible, then this extra div below is not needed then justify-content-center should be added to the nav tag. -->
182    <!-- Alternatively put mx-auto in the ul tag also works. -->
183    <div class="collapse navbar-collapse justify-content-center" id="collapsible_navbar">
184        <ul class="navbar-nav">
185            <!-- Navigation items go here. -->
186
187    
188        </ul>
189    </div>    
190    `;
191
192    let element_jumbotron = document.querySelector(".jumbotron");
193    element_jumbotron.appendChild(element_nav);
194
195}
196
197
198
199function update_navigation_bar_section(a_boolean_include_first_section = true){
200    /*
201    Make the navigation bar item for the sections on the page.
202    a_boolean_include_first_section could be set to false to exclude the first section, which is used in the swc main page to skip the courses item since it is already included in the first dropdown item.
203    */
204
205    let element_body  = document.querySelector("body");
206
207    let string_html_ul = "";
208
209    var array_element_section = document.querySelectorAll(".class_section");
210    array_element_section.forEach((element_section, index) => {
211        if (a_boolean_include_first_section || index !== 0){   //Skip the case for Courses because there is already a link.
212            let element_section_title = element_section.querySelector(".class_section_title");
213
214            let string_navbar_word = element_section_title.getAttribute("data-name-short");
215            if (string_navbar_word=== null || string_navbar_word ===""){
216                string_navbar_word = element_section_title.textContent;
217            }
218
219
220            let string_class_level = "";
221            if (element_section.classList.contains("class_level_01")){
222                string_class_level += " class_level_01";                
223            }
224
225            if (element_section.classList.contains("class_level_02")){
226                string_class_level += " class_level_02";                
227            }
228
229            string_html_ul +=`
230            <li class="nav-item">
231                <a class="nav-link ${string_class_level}" href="#${element_section.id}">${string_navbar_word}</a>
232            </li>
233            `; 
234        }
235    });
236
237    element_ul = document.querySelector(".navbar-nav");
238    element_ul.innerHTML += string_html_ul;   //The navigation items of other sections are hand-coded in the html page.
239
240}
241
242
243function prevent_navigation_bar_expand(){
244    //Useful when too many items crowded the navigation bar, so it will always show as a hamburger icon.
245    document.querySelector("nav").classList.remove("navbar-expand-md");
246}
247
248
249function make_part_collapsible(class_part, class_part_title, class_part_to_hide, boolean_show_default){
250    /*
251    Automatically find all class_part and make it collapsible.
252    Clicking on the part title (class_part_title) will collapse the class_part_to_hide.   
253    For this to work there must be a structure of: 
254    class_part (must have id) > class_part_title > class_part_to_hide
255    The cursor is changed to a pointer (hand) when hovering over class_part_title.
256
257    E.g. class_part=".class_exercise", class_part_title=".class_exercise_title", class_part_to_hide=".class_exercise_solution"
258    boolean_show_default when set to true, class_part_to_hide is visible by default. 
259    */
260
261    let array_element_part = document.querySelectorAll(class_part);
262    array_element_part.forEach(element_part => {
263
264        let element_part_title = element_part.querySelector(class_part_title);
265        let array_element_part_to_hide = element_part.querySelectorAll(class_part_to_hide); //Allow more than one part to be hidden.
266
267        if (element_part_title!==null || array_element_part_to_hide!==null){
268
269            element_part_title.setAttribute("data-toggle", "collapse");
270            element_part_title.setAttribute("data-target", `#${element_part.id} > ${class_part_to_hide}`);
271            element_part_title.style.cursor = "pointer";    //The cursor is changed to a pointer (hand) when hovering over class_part_title.
272
273            array_element_part_to_hide.forEach(element_part_to_hide => {
274                element_part_to_hide.classList.add("collapse");
275                if (boolean_show_default){
276                    element_part_to_hide.classList.add("show");
277                }
278            });
279            
280
281        }
282
283    });
284}
285
286
287
288function make_section_collapsible(){
289    /*
290    So that clicking on the section title (class_section_title) will collapse the class_section_body.   
291    There must be a structure of class_section (must have id) >
291 class_section_title > class_section_body for this this work. 
292    */
293
294   make_part_collapsible(".class_section", ".class_section_title", ".class_section_body", true);
295
296}
297
298function make_try_collapsible(){
299    /*
300    So that clicking on the title Try It Yourself will collapse the class_try_body.   
301    There must be a structure of class_try_container (must have id) > class_try_title > class_try_body for this this work. 
302    */
303
304   make_part_collapsible(".class_try_container", ".class_try_title", ".class_try_body", true);
305
306}
307
308
309function make_simulation_canvas_collapsible(){
310    make_part_collapsible(".class_simulation_canvas", ".class_simulation_canvas_title", ".class_simulation_canvas_body", true);
311
312}
313
314
315function make_video_youtube_collapsible(){
316    make_part_collapsible(".class_video_youtube", ".class_video_youtube_title", ".class_video_youtube_body", true);
317
318}
319
320
321function toggle_accessibility(){
322
323    if (document.getElementById("id_body").classList.contains("accessible")) {
324
325        document.getElementById("id_body").classList.remove("accessible");
326
327        document.querySelectorAll(".btn").forEach(element => {
328            element.classList.remove("accessible")
329        });
330    
331        document.querySelectorAll(".border-dark").forEach(element => {
332            element.classList.add("border-primary"); element.classList.remove("border-dark")
333        });
334
335        document.querySelectorAll(".text-primary").forEach(element => {
336            element.classList.add("text-primary");
337            element.classList.remove("text-dark");
338        });
339
340        document.querySelectorAll("nav a").forEach(element => {
341            element.classList.remove("accessible")
342        });
343
344        // document.querySelectorAll(".card-text").forEach(element => {element.classList.add("text-primary")});
345    
346        // document.querySelectorAll(".jumbotron").forEach(element => {element.classList.remove("accessible")});
347        // document.querySelectorAll(".navbar").forEach(element => {element.classList.remove("accessible")});
348        
349
350
351    } else {
352        document.getElementById("id_body").classList.add("accessible");
353
354        document.querySelectorAll(".btn").forEach(element => {
355            element.classList.add("accessible")
356        });
357    
358        document.querySelectorAll(".border-primary").forEach(element => {
359            element.classList.remove("border-primary"); element.classList.add("border-dark")
360        });
361
362        document.querySelectorAll(".text-primary").forEach(element => {
363            element.classList.remove("text-primary");
364            element.classList.add("text-dark");
365        });
366
367        document.querySelectorAll("nav a").forEach(element => {
368            element.classList.add("accessible")
369        });
370    
371        // document.querySelectorAll(".jumbotron").forEach(element => {element.classList.add("accessible")});
372        // document.querySelectorAll(".navbar").forEach(element => {element.classList.add("accessible")});
373        
374    }
375    
376}
377
378
379/*
380
381Setup offscreen canvas for possible draw operations. 
382To use, need to write a custom file (e.g. namespace_mechanics.js) to customize the namespace_offscreen.draw() function.
383
384*/
385
386
387
388// var namespace_offscreen = {};
389
390// namespace_offscreen.setup_canvas = function() {
391//     let namespace = this;   //namespace = namespace_offscreen
392
393
394//     namespace.canvas = document.createElement("canvas");
395    
396//     namespace.canvas.tabIndex = 0;
397    
398//     namespace.canvas.width = 600;
399//     namespace.canvas.height = 400;
400
401//     namespace.context = namespace.canvas.getContext('2d');
402
403    
404//     //Holds all the functions that can draw on the canvas.
405//     //To draw, add a function to this array.
406//     namespace.array_function_draw = []; 
407
408// };
409
410// namespace_offscreen.draw = function(){
411//     //Called by load_content.js in did_finish_loading().
412//     namespace.array_function_draw.forEach(function_draw =>{
413//         function_draw();
414//     });
415
416// };
417
418
419// function add_function_draw_to_namespace_offscreen(a_function){
420//     namespace_offscreen.array_function_draw.push(a_function)
421// };

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.