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("© " + 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 © ${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.